From 9b6568996817ce2803124cf70bd626e2e0708cb7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 25 Jan 2022 12:02:18 -0800 Subject: [PATCH 0001/1499] readme fixes (#180) --- src/OpenTelemetry.Contrib.PersistentStorage/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/README.md b/src/OpenTelemetry.Contrib.PersistentStorage/README.md index 1f8aa1e6ae..f1ded0e6c3 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/README.md +++ b/src/OpenTelemetry.Contrib.PersistentStorage/README.md @@ -32,6 +32,7 @@ Default is 2 minutes. Maintenance event performs following 3 tasks: 1. Removes `*.blob` files for which the retention period has expired. 2. Removes `*.tmp` files for which the write timeout period has expired. 3. Updates `*.lock` files to `*.blob` for which the lease period has expired. +4. Updates `directorySize`. `retentionPeriodInMilliseconds` : Retention period in milliseconds for the blob. Default is 2 days. @@ -43,7 +44,7 @@ blob. Default is 1 minute. `CreateBlob(byte[] buffer, int leasePeriodMilliseconds = 0)` method can be used to store data on disk in case of failures. The file stored will have `.blob` -extension. +extension. If acquiring lease, the file will have `.lock` extension. ```csharp IPersistentBlob blob = storage.CreateBlob(data); From 13ca8ec89ad224c38f45f1fc375dd5f078e16cdf Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 25 Jan 2022 13:49:52 -0800 Subject: [PATCH 0002/1499] Wording change to the PersistentStorage README (#183) * reyang/wording * update type names --- .../README.md | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/README.md b/src/OpenTelemetry.Contrib.PersistentStorage/README.md index f1ded0e6c3..e6484fd8fc 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/README.md +++ b/src/OpenTelemetry.Contrib.PersistentStorage/README.md @@ -1,7 +1,9 @@ -# Persistent Storage for OpenTelemetry Exporters +# Persistent Storage Interface and Implementation -This package enables OpenTelemetry exporters to store telemetry offline in case -of transient failures. The data can be read at later time for retries. +This package provides both the interface and implementation of persistent +storage. It is an experimental component which can be used by OpenTelemetry +Exporters to provide reliable data delivery. Eventually this component should +get splitted into the abstract interface and concrete implementations. ## Installation @@ -12,32 +14,28 @@ TODO ### Setup Storage ```csharp -var testDir = new DirectoryInfo(Path.Combine( - Environment.GetFolderPath( - Environment.SpecialFolder.LocalApplicationData) - , "test")); -using var storage = new LocalFileStorage(testDir.FullName); +using var storage = new FileStorage("test"); ``` Following is the complete list of configurable options that can be used to set up storage: -`path`: Sets file storage folder location where blobs are stored. +* `path`: Sets file storage folder location where blobs are stored. -`maxSizeInBytes` : Maximum allowed storage folder size. Default is 50 MB. +* `maxSizeInBytes`: Maximum allowed storage folder size. Default is 50 MB. -`maintenancePeriodInMilliseconds`: Maintenance event runs at specified interval. -Default is 2 minutes. Maintenance event performs following 3 tasks: +* `maintenancePeriodInMilliseconds`: Maintenance event runs at specified interval. +Default is 2 minutes. Maintenance event performs the following tasks: -1. Removes `*.blob` files for which the retention period has expired. -2. Removes `*.tmp` files for which the write timeout period has expired. -3. Updates `*.lock` files to `*.blob` for which the lease period has expired. -4. Updates `directorySize`. + * Removes `*.blob` files for which the retention period has expired. + * Removes `*.tmp` files for which the write timeout period has expired. + * Updates `*.lock` files to `*.blob` for which the lease period has expired. + * Updates `directorySize`. -`retentionPeriodInMilliseconds` : Retention period in milliseconds for the blob. +* `retentionPeriodInMilliseconds`: Retention period in milliseconds for the blob. Default is 2 days. -`writeTimeoutInMilliseconds`: Controls the timeout when writing a buffer to +* `writeTimeoutInMilliseconds`: Controls the timeout when writing a buffer to blob. Default is 1 minute. ### CreateBlob @@ -66,7 +64,7 @@ IPersistentBlob blob1 = storage.GetBlob(); // List all blobs. foreach (var blobItem in storage.GetBlobs()) { - Console.WriteLine(((LocalFileBlob)blobItem).FullPath); + Console.WriteLine(((FileBlob)blobItem).FullPath); } ``` @@ -98,14 +96,10 @@ byte[] data = blob2.Read(); blob2.Delete(); ``` -## Sample +## Example -```c# -var testDir = new DirectoryInfo(Path.Combine( - Environment.GetFolderPath( - Environment.SpecialFolder.LocalApplicationData) - , "test")); -using var storage = new LocalFileStorage(testDir.FullName); +```csharp +using var storage = new FileStorage("test"); var data = Encoding.UTF8.GetBytes("Hello, World!"); @@ -115,7 +109,7 @@ IPersistentBlob blob1 = storage.CreateBlob(data); // List all blobs. foreach (var blobItem in storage.GetBlobs()) { - Console.WriteLine(((LocalFileBlob)blobItem).FullPath); + Console.WriteLine(((FileBlob)blobItem).FullPath); } // Get blob. From be45af8350ca8711fe4bd24c2ed3e047bf56289c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 25 Jan 2022 18:18:36 -0800 Subject: [PATCH 0003/1499] Package rename [OpenTelemetry.Contrib.Extensions.PersistentStorage] (#181) --- ... package-Extensions.PersistentStorage.yml} | 6 ++-- CODEOWNERS | 4 +-- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 9 ++++++ .../FileBlob.cs | 2 +- .../FileStorage.cs | 2 +- .../IPersistentBlob.cs | 2 +- .../IPersistentStorage.cs | 2 +- ...ntrib.Extensions.PersistentStorage.csproj} | 2 +- .../PersistentStorageEventSource.cs | 2 +- .../PersistentStorageHelper.cs | 2 +- .../README.md | 0 .../CHANGELOG.md | 9 ------ .../FileBlobTests.cs | 2 +- .../FileStorageTests.cs | 2 +- ...Extensions.PersistentStorage.Tests.csproj} | 2 +- 17 files changed, 39 insertions(+), 39 deletions(-) rename .github/workflows/{package-PersistentStorage.yml => package-Extensions.PersistentStorage.yml} (82%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/AssemblyInfo.cs (93%) create mode 100644 src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/FileBlob.cs (98%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/FileStorage.cs (99%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/IPersistentBlob.cs (97%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/IPersistentStorage.cs (97%) rename src/{OpenTelemetry.Contrib.PersistentStorage/OpenTelemetry.Contrib.PersistentStorage.csproj => OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj} (80%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/PersistentStorageEventSource.cs (98%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/PersistentStorageHelper.cs (99%) rename src/{OpenTelemetry.Contrib.PersistentStorage => OpenTelemetry.Contrib.Extensions.PersistentStorage}/README.md (100%) delete mode 100644 src/OpenTelemetry.Contrib.PersistentStorage/CHANGELOG.md rename test/{OpenTelemetry.Contrib.PersistentStorage.Tests => OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests}/FileBlobTests.cs (98%) rename test/{OpenTelemetry.Contrib.PersistentStorage.Tests => OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests}/FileStorageTests.cs (98%) rename test/{OpenTelemetry.Contrib.PersistentStorage.Tests/OpenTelemetry.Contrib.PersistentStorage.Tests.csproj => OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj} (83%) diff --git a/.github/workflows/package-PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml similarity index 82% rename from .github/workflows/package-PersistentStorage.yml rename to .github/workflows/package-Extensions.PersistentStorage.yml index 0f808993cb..a28bd292de 100644 --- a/.github/workflows/package-PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.PersistentStorage +name: Pack OpenTelemetry.Contrib.Extensions.PersistentStorage on: workflow_dispatch: @@ -9,13 +9,13 @@ on: default: 'warning' push: tags: - - 'PersistentStorage-*' # trigger when we create a tag with prefix "PersistentStorage-" + - 'Extensions.PersistentStorage-*' # trigger when we create a tag with prefix "Extensions.PersistentStorage-" jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.PersistentStorage + PROJECT: OpenTelemetry.Contrib.Extensions.PersistentStorage strategy: matrix: diff --git a/CODEOWNERS b/CODEOWNERS index 094c4fdb39..e1ada4a181 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -13,7 +13,7 @@ src/OpenTelemetry.Contrib.Instrumentation.MassTransit/ @ope src/OpenTelemetry.Contrib.Instrumentation.Owin/ @open-telemetry/dotnet-contrib-approvers @codeblanch src/OpenTelemetry.Contrib.Instrumentation.Wcf/ @open-telemetry/dotnet-contrib-approvers @codeblanch src/OpenTelemetry.Contrib.Instrumentation.MySqlData/ @open-telemetry/dotnet-contrib-approvers @moonheart -src/OpenTelemetry.Contrib.PersistentStorage/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar +src/OpenTelemetry.Contrib.Extensions.PersistentStorage/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar src/OpenTelemetry.Contrib.Preview/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/ @open-telemetry/dotnet-contrib-approvers @SergeyKanzhelev @@ -25,5 +25,5 @@ test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/ @ope test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/ @open-telemetry/dotnet-contrib-approvers @moonheart -src/OpenTelemetry.Contrib.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar +src/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar test/OpenTelemetry.Contrib.Preview.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index b0d9ba4c45..11ea786c81 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -138,10 +138,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Previ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Preview.Tests", "test\OpenTelemetry.Contrib.Preview.Tests\OpenTelemetry.Contrib.Preview.Tests.csproj", "{D2C68560-C252-41A9-B742-2CEB7D760E0F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.PersistentStorage", "src\OpenTelemetry.Contrib.PersistentStorage\OpenTelemetry.Contrib.PersistentStorage.csproj", "{735E9121-93E0-4770-BF8F-45598EEC37FC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.PersistentStorage.Tests", "test\OpenTelemetry.Contrib.PersistentStorage.Tests\OpenTelemetry.Contrib.PersistentStorage.Tests.csproj", "{B4278414-48B8-45CF-B22F-A8BA614A6685}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj", "{4172D671-3AAC-443F-9EB0-A6608B154AF0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AzureMonitor", "src\OpenTelemetry.Contrib.Extensions.AzureMonitor\OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj", "{9C2D6D1A-8580-4527-B718-E206D0690635}" @@ -156,6 +152,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\o EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Owin.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Owin.Tests\OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj", "{D52558C8-B7BF-4F59-A0FA-9AA629E68012}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.PersistentStorage", "src\OpenTelemetry.Contrib.Extensions.PersistentStorage\OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj", "{433C59A3-D535-421E-BA7F-9BCE0D4A3D25}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj", "{72EBA81D-2933-417C-8F21-D4CFFD72F530}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -274,14 +274,6 @@ Global {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU - {735E9121-93E0-4770-BF8F-45598EEC37FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {735E9121-93E0-4770-BF8F-45598EEC37FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {735E9121-93E0-4770-BF8F-45598EEC37FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {735E9121-93E0-4770-BF8F-45598EEC37FC}.Release|Any CPU.Build.0 = Release|Any CPU - {B4278414-48B8-45CF-B22F-A8BA614A6685}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B4278414-48B8-45CF-B22F-A8BA614A6685}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B4278414-48B8-45CF-B22F-A8BA614A6685}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B4278414-48B8-45CF-B22F-A8BA614A6685}.Release|Any CPU.Build.0 = Release|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -306,6 +298,14 @@ Global {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Debug|Any CPU.Build.0 = Debug|Any CPU {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Release|Any CPU.ActiveCfg = Release|Any CPU {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Release|Any CPU.Build.0 = Release|Any CPU + {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Debug|Any CPU.Build.0 = Debug|Any CPU + {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Release|Any CPU.ActiveCfg = Release|Any CPU + {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Release|Any CPU.Build.0 = Release|Any CPU + {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -344,8 +344,6 @@ Global {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {B978939B-278C-43A3-AD12-32EA9BBD27D0} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D2C68560-C252-41A9-B742-2CEB7D760E0F} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {735E9121-93E0-4770-BF8F-45598EEC37FC} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {B4278414-48B8-45CF-B22F-A8BA614A6685} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {4172D671-3AAC-443F-9EB0-A6608B154AF0} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {9C2D6D1A-8580-4527-B718-E206D0690635} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2} = {2097345F-4DD3-477D-BC54-A922F9B2B402} @@ -353,6 +351,8 @@ Global {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} {D52558C8-B7BF-4F59-A0FA-9AA629E68012} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {433C59A3-D535-421E-BA7F-9BCE0D4A3D25} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {72EBA81D-2933-417C-8F21-D4CFFD72F530} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/AssemblyInfo.cs similarity index 93% rename from src/OpenTelemetry.Contrib.PersistentStorage/AssemblyInfo.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/AssemblyInfo.cs index 99837ba07e..e925a5a392 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.PersistentStorage.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md new file mode 100644 index 0000000000..4b104c7166 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog - OpenTelemetry.Contrib.Extensions.PersistentStorage + +## 1.0.0 [Unreleased] + +This is the first release for the `OpenTelemetry.Contrib.Extensions.PersistentStorage` +project. + +For more details, please refer to the +[README](README.md) diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileBlob.cs similarity index 98% rename from src/OpenTelemetry.Contrib.PersistentStorage/FileBlob.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileBlob.cs index 80d235ac5e..11181dfbb2 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileBlob.cs @@ -17,7 +17,7 @@ using System; using System.IO; -namespace OpenTelemetry.Contrib.PersistentStorage +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage { /// /// The allows to save a blob diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/FileStorage.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileStorage.cs similarity index 99% rename from src/OpenTelemetry.Contrib.PersistentStorage/FileStorage.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileStorage.cs index cbd832021f..087d5f270d 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/FileStorage.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileStorage.cs @@ -20,7 +20,7 @@ using System.Linq; using System.Timers; -namespace OpenTelemetry.Contrib.PersistentStorage +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage { /// /// Persistent file storage allows to save data diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/IPersistentBlob.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentBlob.cs similarity index 97% rename from src/OpenTelemetry.Contrib.PersistentStorage/IPersistentBlob.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentBlob.cs index 6123427a41..5e18345179 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/IPersistentBlob.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentBlob.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.PersistentStorage +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage { /// /// Represents a persistent blob. diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/IPersistentStorage.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentStorage.cs similarity index 97% rename from src/OpenTelemetry.Contrib.PersistentStorage/IPersistentStorage.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentStorage.cs index 4246ceac5a..40d12ec4f0 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/IPersistentStorage.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentStorage.cs @@ -16,7 +16,7 @@ using System.Collections.Generic; -namespace OpenTelemetry.Contrib.PersistentStorage +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage { /// /// Persistent storage API. diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/OpenTelemetry.Contrib.PersistentStorage.csproj b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj similarity index 80% rename from src/OpenTelemetry.Contrib.PersistentStorage/OpenTelemetry.Contrib.PersistentStorage.csproj rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj index b27b707617..aadf560c9d 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/OpenTelemetry.Contrib.PersistentStorage.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj @@ -3,7 +3,7 @@ netstandard2.0;net461 OpenTelemetry Persistent Storage - PersistentStorage- + Extensions.PersistentStorage- diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/PersistentStorageEventSource.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageEventSource.cs similarity index 98% rename from src/OpenTelemetry.Contrib.PersistentStorage/PersistentStorageEventSource.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageEventSource.cs index 9ba647b1c8..afe96c2cd1 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageEventSource.cs @@ -18,7 +18,7 @@ using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; -namespace OpenTelemetry.Contrib.PersistentStorage +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage { [EventSource(Name = EventSourceName)] internal sealed class PersistentStorageEventSource : EventSource diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageHelper.cs similarity index 99% rename from src/OpenTelemetry.Contrib.PersistentStorage/PersistentStorageHelper.cs rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageHelper.cs index b27b5cdff9..32c5a080ec 100644 --- a/src/OpenTelemetry.Contrib.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -24,7 +24,7 @@ using System.Text; using System.Threading; -namespace OpenTelemetry.Contrib.PersistentStorage +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage { internal static class PersistentStorageHelper { diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/README.md b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md similarity index 100% rename from src/OpenTelemetry.Contrib.PersistentStorage/README.md rename to src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md diff --git a/src/OpenTelemetry.Contrib.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Contrib.PersistentStorage/CHANGELOG.md deleted file mode 100644 index 3d552b4dbe..0000000000 --- a/src/OpenTelemetry.Contrib.PersistentStorage/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Changelog - OpenTelemetry.Contrib.PersistentStorage - -## 1.0.0 [Unreleased] - -This is the first release for the `OpenTelemetry.Contrib.PersistentStorage` -project. - -For more details, please refer to the -[README](README.md) diff --git a/test/OpenTelemetry.Contrib.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.PersistentStorage.Tests/FileBlobTests.cs rename to test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs index f7707af6b2..c1d809c276 100644 --- a/test/OpenTelemetry.Contrib.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs @@ -19,7 +19,7 @@ using System.Threading; using Xunit; -namespace OpenTelemetry.Contrib.PersistentStorage.Tests +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests { public class FileBlobTests { diff --git a/test/OpenTelemetry.Contrib.PersistentStorage.Tests/FileStorageTests.cs b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileStorageTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.PersistentStorage.Tests/FileStorageTests.cs rename to test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileStorageTests.cs index 64ec9231d2..923699233a 100644 --- a/test/OpenTelemetry.Contrib.PersistentStorage.Tests/FileStorageTests.cs +++ b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileStorageTests.cs @@ -21,7 +21,7 @@ using System.Threading; using Xunit; -namespace OpenTelemetry.Contrib.PersistentStorage.Tests +namespace OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests { public class FileStorageTests { diff --git a/test/OpenTelemetry.Contrib.PersistentStorage.Tests/OpenTelemetry.Contrib.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj similarity index 83% rename from test/OpenTelemetry.Contrib.PersistentStorage.Tests/OpenTelemetry.Contrib.PersistentStorage.Tests.csproj rename to test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj index 1ab5e638e3..cf14001b6c 100644 --- a/test/OpenTelemetry.Contrib.PersistentStorage.Tests/OpenTelemetry.Contrib.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj @@ -16,7 +16,7 @@ - + From 946c4d8aaffe62f4b199396293aa8e120cd46e3c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 27 Jan 2022 13:03:38 -0800 Subject: [PATCH 0004/1499] Update changelog [OpenTelemetry.Contrib.Extensions.PersistentStorage] (#185) * update changelog * fix --- .../CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md index 4b104c7166..f92fb41660 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog - OpenTelemetry.Contrib.Extensions.PersistentStorage -## 1.0.0 [Unreleased] +## 1.0.0-alpha1 This is the first release for the `OpenTelemetry.Contrib.Extensions.PersistentStorage` project. From 04678639385d6b7be79d63e9932c52ff3a6e3ca0 Mon Sep 17 00:00:00 2001 From: sailorgallifrey <76499312+sailorgallifrey@users.noreply.github.com> Date: Thu, 27 Jan 2022 15:08:38 -0600 Subject: [PATCH 0005/1499] Update CHANGELOG.md (#184) --- src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md index 301e586c56..32e5bc37db 100644 --- a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 1.0.0-beta1 * Update OTel SDK package version to 1.1.0 * Log exceptions when failing to export data to stackdriver From 9f9644bc879ab7775d5ff1bc49fc3d0da64a21bb Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 27 Jan 2022 17:10:43 -0800 Subject: [PATCH 0006/1499] Add release process clarification (#186) --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7ea0efcbb..8763eb107e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -129,6 +129,11 @@ Any Maintainer can merge the PR once it is **ready to merge**. Note, that some PR may not be merged immediately if repo is being in process of a major release and the new feature doesn't fit it. +### How to request for release of package + +Submit a PR with `CHANGELOG.md` file reflecting the version to be released. Also, +tag the maintainers of this repository who can release the package. + ## Style Guide This project includes a From 59a5020bd6dbbcabd2b9df959f31f8cb8d7cbd17 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 27 Jan 2022 17:25:24 -0800 Subject: [PATCH 0007/1499] Update release process (#187) --- build/RELEASING.md | 41 ++++++----------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/build/RELEASING.md b/build/RELEASING.md index 60003180d1..f0c46cc138 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -62,39 +62,10 @@ update the Changelog. This will trigger the building and packaging workflow for the project. -2. Navigate to the [**Actions**](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions) -tab on the repo and monitor the "Pack YOUR_PROJECT_NAME" workflow. The last -step in the workflow is to publish to MyGet. +2. Navigate to the +[**Actions**](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions) +tab on the repo and monitor the "Pack YOUR_PROJECT_NAME" workflow. The last step +in the workflow is to publish to Nuget.org. -3. Validate that the project has been published to MyGet with the latest -version that you had specified in step 1. - -4. Get the build artifact .zip from the workflow execution in step 2. -Extract the artifact to a local folder. This should contain the nuget -files and symbols. - -5. Download the latest [nuget.exe](https://www.nuget.org/downloads) into -the same folder as step 4. - -6. Publish the project to nuget.org - - ```powershell - .\nuget.exe setApiKey - ``` - - ```powershell - get-childitem -Recurse | where {$_.extension -eq ".nupkg"} | foreach - ($_) {.\nuget.exe push $_.fullname - -Source https://api.nuget.org/v3/index.json} - ``` - - It usually takes a while for the new version of the project to show up in nuget.org - -7. Validate that the new version of the project is successfully published to -nuget.org under OpenTelemetry owner. - -8. Delete the NUGET TOKEN set in step 6. - -9. Go to the [**Releases**](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/releases) -page on the repo. Create a new release with the tag from step 1. Include the -Changelog from your project to the release notes. +3. Validate that the new version (as specified in step1) of the project is +successfully published to nuget.org under OpenTelemetry owner. From ba777f4565606e7752795a4961a276e54131bf34 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 27 Jan 2022 18:44:13 -0800 Subject: [PATCH 0008/1499] Skip unstable test (#189) * skip unstable test * rmv console * fix spacing * skip +1 Co-authored-by: Cijo Thomas --- .../FileBlobTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs index c1d809c276..b7e9f6b797 100644 --- a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.IO; using System.Text; using System.Threading; @@ -123,7 +124,7 @@ public void FileBlobTests_Delete() Assert.False(testFile.Exists); } - [Fact] + [Fact(Skip = "Unstable")] public void FileBlobTests_DeleteFailsAfterLeaseIsExpired() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); @@ -151,7 +152,7 @@ public void FileBlobTests_DeleteFailsAfterLeaseIsExpired() testDirectory.Delete(true); } - [Fact] + [Fact(Skip = "Unstable")] public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); From 7fa52de0e20fbcd57a5e77105a6d5af6faecd7ed Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 27 Jan 2022 19:41:05 -0800 Subject: [PATCH 0009/1499] Remove netcore 2.1 from tests (#188) * Remove netcore 2.1 from tests * netcore21 from ci --- .github/workflows/pr_build.yml | 2 +- .../OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj | 2 +- .../OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj | 4 ++-- .../OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj | 2 +- ...enTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj | 2 +- ...y.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj | 2 +- ...Telemetry.Contrib.Instrumentation.MassTransit.Tests.csproj | 2 +- .../OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index ea1dc86f60..5e7f20e319 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [windows-latest,ubuntu-latest] - version: [net461,netcoreapp2.1,netcoreapp3.1,net5.0] + version: [net461,netcoreapp3.1,net5.0] exclude: - os: ubuntu-latest version: net461 diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj index ec2e74ee49..071cb1d186 100644 --- a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj @@ -1,7 +1,7 @@  Unit test project for Stackdriver Exporter for OpenTelemetry - netcoreapp2.1;netcoreapp3.1 + netcoreapp3.1 $(TargetFrameworks);net461 diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index 2c484d5002..77bc21337e 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for AWS X-Ray for OpenTelemetry - netcoreapp2.1;netcoreapp3.1 + netcoreapp3.1 $(TargetFrameworks);net452 @@ -25,7 +25,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 1ba6ad4081..749b9e88a7 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for AWS client instrumentation for OpenTelemetry - netcoreapp2.1;netcoreapp3.1 + netcoreapp3.1 $(TargetFrameworks);net452 diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj index 6f384a6538..12fa941744 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj @@ -2,7 +2,7 @@ Unit test project of OpenTelemetry instrumentation for AWS Lambda - netcoreapp2.1;netcoreapp3.1 + netcoreapp3.1 true diff --git a/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj index c3f9351d03..73c5b9a25d 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -1,7 +1,7 @@  Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - netcoreapp2.1;netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0 diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj index 917ccb2489..36f47b72db 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry MassTransit instrumentation - netcoreapp2.1;netcoreapp3.1 + netcoreapp3.1 $(TargetFrameworks);net461 true diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj index 9dd64f4a34..91cbff5095 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry WCF instrumentation - netcoreapp2.1;netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0 $(TargetFrameworks);net452 From 8f11553237076106f4926d42dcf8ee94f3343f6c Mon Sep 17 00:00:00 2001 From: sailorgallifrey <76499312+sailorgallifrey@users.noreply.github.com> Date: Fri, 28 Jan 2022 10:30:50 -0600 Subject: [PATCH 0010/1499] CODEOWNERS Prompt (#193) --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8763eb107e..c7760bdd07 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -198,3 +198,6 @@ to be placed in the `.github/workflows/` folder. value to "Foo.Bar-*" and [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml#L18) value to "OpenTelemetry.Contrib.Foo.Bar". + +* When contributing a new project you are expected to assign yourself to your +project in the [CODEOWNERS](./CODEOWNERS) file From e0395164378edb1086e70357a53226ac396cf4f0 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 28 Jan 2022 16:22:17 -0800 Subject: [PATCH 0011/1499] Fix nit (#199) --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index e1ada4a181..20b9e45a18 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -25,5 +25,5 @@ test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/ @ope test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/ @open-telemetry/dotnet-contrib-approvers @moonheart -src/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar +test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar test/OpenTelemetry.Contrib.Preview.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch From fa906bd2bc127ab5eeec5b63afd223694f9bb852 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 28 Jan 2022 16:25:18 -0800 Subject: [PATCH 0012/1499] update release version and readme (#198) Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 2 +- .../README.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md index f92fb41660..05bde1f36d 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog - OpenTelemetry.Contrib.Extensions.PersistentStorage -## 1.0.0-alpha1 +## 1.0.0-alpha2 This is the first release for the `OpenTelemetry.Contrib.Extensions.PersistentStorage` project. diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md index e6484fd8fc..ecc61eca22 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md +++ b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md @@ -7,7 +7,9 @@ get splitted into the abstract interface and concrete implementations. ## Installation -TODO +```shell +dotnet add package OpenTelemetry.Contrib.Extensions.PersistentStorage +``` ## Basic Usage From 667fc499ddd5b76a8374b7cdad2792eba29ca0ad Mon Sep 17 00:00:00 2001 From: Tamilanban Chinnaiyan <35332451+tamilaban@users.noreply.github.com> Date: Sat, 5 Feb 2022 23:28:01 +0530 Subject: [PATCH 0013/1499] WCF: action is assigned with null if operation name is not defined(#169) (#170) * action is assigned with null if operation name is not defined(#169) * adds unit test * Code review + changelog update. Co-authored-by: Mikel Blanchard --- .../CHANGELOG.md | 6 +++ .../TelemetryClientMessageInspector.cs | 12 ++++- .../TelemetryDispatchMessageInspector.cs | 12 ++++- .../TelemetryClientMessageInspectorTests.cs | 51 ++++++++++++++++--- ...etryDispatchMessageInspectorTests.netfx.cs | 42 ++++++++++++--- .../WCF/IServiceContract.cs | 3 ++ .../WCF/Service.netfx.cs | 9 ++++ .../WCF/ServiceClient.cs | 3 ++ 8 files changed, 118 insertions(+), 20 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md index 5b4f7fe271..4c3495aadf 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.0-rc5 + +* Fixed an `ArgumentNullException` setting `Activity`.`DisplayName` when + processing service requests with empty actions + ([#170](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/170)) + ## 1.0.0-rc4 * Removed `Propagator` property on `WcfInstrumentationOptions` diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index 5542d629c0..5cf7db607d 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -68,8 +68,16 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel) if (activity != null) { - string action = request.Headers.Action; - activity.DisplayName = action; + string action; + if (!string.IsNullOrEmpty(request.Headers.Action)) + { + action = request.Headers.Action; + activity.DisplayName = action; + } + else + { + action = string.Empty; + } Propagators.DefaultTextMapPropagator.Inject( new PropagationContext(activity.Context, Baggage.Current), diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index b1064030bb..b9d6b9768a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -66,8 +66,16 @@ public object AfterReceiveRequest(ref Message request, IClientChannel channel, I if (activity != null) { - string action = request.Headers.Action; - activity.DisplayName = action; + string action; + if (!string.IsNullOrEmpty(request.Headers.Action)) + { + action = request.Headers.Action; + activity.DisplayName = action; + } + else + { + action = string.Empty; + } if (activity.IsAllDataRequested) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs index a67775758c..202c097982 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs @@ -89,12 +89,23 @@ async void Listener() var ctx = await ctxTask.ConfigureAwait(false); + using StreamReader reader = new StreamReader(ctx.Request.InputStream); + + string request = reader.ReadToEnd(); + ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/xml; charset=utf-8"; using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream)) { - writer.Write(@"RSP: Hello Open Telemetry!"); + if (request.Contains("ExecuteWithEmptyActionName")) + { + writer.Write(@"RSP: Hello Open Telemetry!"); + } + else + { + writer.Write(@"RSP: Hello Open Telemetry!"); + } } ctx.Response.Close(); @@ -128,13 +139,15 @@ public void Dispose() [InlineData(true, false, true, true)] [InlineData(true, false, true, true, true)] [InlineData(true, false, true, true, true, true)] + [InlineData(true, false, true, true, true, true, true)] public async Task OutgoingRequestInstrumentationTest( bool instrument, bool filter = false, bool suppressDownstreamInstrumentation = true, bool includeVersion = false, bool enrich = false, - bool enrichmentException = false) + bool enrichmentException = false, + bool emptyOrNullAction = false) { #if NETFRAMEWORK const string OutgoingHttpOperationName = "OpenTelemetry.HttpWebRequest.HttpRequestOut"; @@ -190,11 +203,22 @@ public async Task OutgoingRequestInstrumentationTest( { client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - var response = await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + if (emptyOrNullAction) + { + await client.ExecuteWithEmptyActionNameAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } + else + { + await client.ExecuteAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } } finally { @@ -238,10 +262,21 @@ public async Task OutgoingRequestInstrumentationTest( Assert.Single(stoppedActivities); Activity activity = stoppedActivities[0]; + + if (emptyOrNullAction) + { + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.DisplayName); + Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + } + else + { + Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); + Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + } + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.OperationName); Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); - Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerNameTag).Value); Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerPortTag).Value); Assert.Equal("http", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index 9aa65c2cb4..a94a746b8b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -89,12 +89,14 @@ public void Dispose() [InlineData(true, false, true)] [InlineData(true, false, true, true)] [InlineData(true, false, true, true, true)] + [InlineData(true, false, true, true, true, true)] public async Task IncomingRequestInstrumentationTest( bool instrument, bool filter = false, bool includeVersion = false, bool enrich = false, - bool enrichmentExcecption = false) + bool enrichmentExcecption = false, + bool emptyOrNullAction = false) { List stoppedActivities = new List(); @@ -156,11 +158,22 @@ public async Task IncomingRequestInstrumentationTest( new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { - var response = await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + if (emptyOrNullAction) + { + await client.ExecuteWithEmptyActionNameAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } + else + { + await client.ExecuteAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } } finally { @@ -185,15 +198,28 @@ public async Task IncomingRequestInstrumentationTest( Assert.Single(stoppedActivities); Activity activity = stoppedActivities[0]; + + if (emptyOrNullAction) + { + Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.DisplayName); + Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + Assert.Equal("http://opentelemetry.io/Service/ExecuteWithEmptyActionNameResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); + } + else + { + Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); + Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + Assert.Equal("http://opentelemetry.io/Service/ExecuteResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); + } + Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); - Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); - Assert.Equal("http://opentelemetry.io/Service/ExecuteResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); + if (includeVersion) { Assert.Equal("Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 1901582b40..d4358f2b6d 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -24,5 +24,8 @@ public interface IServiceContract { [OperationContract] Task ExecuteAsync(ServiceRequest request); + + [OperationContract(Action = "")] + Task ExecuteWithEmptyActionNameAsync(ServiceRequest request); } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 05ec64df59..aa75e5e8bf 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -35,6 +35,15 @@ public Task ExecuteAsync(ServiceRequest request) Payload = $"RSP: {request.Payload}", }); } + + public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) + { + return Task.FromResult( + new ServiceResponse + { + Payload = $"RSP: {request.Payload}", + }); + } } } #endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index adf92082fc..98792bb3c1 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -29,5 +29,8 @@ public ServiceClient(Binding binding, EndpointAddress remoteAddress) public Task ExecuteAsync(ServiceRequest request) => this.Channel.ExecuteAsync(request); + + public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) + => this.Channel.ExecuteWithEmptyActionNameAsync(request); } } From 5f4fce1e8826cb82e40f5300bee6e5b16f862b2e Mon Sep 17 00:00:00 2001 From: Swetha Ravichandran Date: Mon, 14 Feb 2022 15:05:40 -0800 Subject: [PATCH 0014/1499] https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/201 - AWSEKSResourceDetector - Validate ClusterName/ContainerID independently before adding it to the resource (#205) - Validates ClusterName/ContainerID independently before adding it to the resource - Includes bug fix - IsEKSProcess should return non-null auth value to confirm if its running in EKS environment. - Handled exceptions separately with more error information - Added Unit Tests Co-authored-by: Prashant Srivastava <50466688+srprash@users.noreply.github.com> --- .../Resources/AWSEKSResourceDetector.cs | 111 ++++++++++-------- .../Resources/TestAWSEKSResourceDetector.cs | 31 +++++ 2 files changed, 96 insertions(+), 46 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index 87b5834361..2bc5850515 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -40,26 +40,15 @@ public class AWSEKSResourceDetector : IResourceDetector /// List of key-value pairs of resource attributes. public IEnumerable> Detect() { - List> resourceAttributes = null; - - try - { - var clusterName = this.GetEKSClusterName(AWSEKSCredentialPath); - var containerId = this.GetEKSContainerId(AWSEKSMetadataFilePath); - - if (clusterName == null && containerId == null) - { - return resourceAttributes; - } - - resourceAttributes = this.ExtractResourceAttributes(clusterName, containerId); - } - catch (Exception ex) + var credentials = this.GetEKSCredentials(AWSEKSCredentialPath); + if (credentials == null || !this.IsEKSProcess(credentials)) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEKSResourceDetector), ex); + return null; } - return resourceAttributes; + return this.ExtractResourceAttributes( + this.GetEKSClusterName(credentials), + this.GetEKSContainerId(AWSEKSMetadataFilePath)); } internal List> ExtractResourceAttributes(string clusterName, string containerId) @@ -68,46 +57,67 @@ internal List> ExtractResourceAttributes(string clu { new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), - new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName), - new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId), }; + if (!string.IsNullOrEmpty(clusterName)) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName)); + } + + if (!string.IsNullOrEmpty(containerId)) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); + } + return resourceAttributes; } internal string GetEKSCredentials(string path) { - StringBuilder stringBuilder = new StringBuilder(); - - using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + try { - while (!streamReader.EndOfStream) + StringBuilder stringBuilder = new StringBuilder(); + + using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) { - stringBuilder.Append(streamReader.ReadLine().Trim()); + while (!streamReader.EndOfStream) + { + stringBuilder.Append(streamReader.ReadLine().Trim()); + } } + + return "Bearer " + stringBuilder.ToString(); + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to load client token", ex); } - return "Bearer " + stringBuilder.ToString(); + return null; } internal string GetEKSContainerId(string path) { - string containerId = null; - - using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + try { - while (!streamReader.EndOfStream) + using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) { - var trimmedLine = streamReader.ReadLine().Trim(); - if (trimmedLine.Length > 64) + while (!streamReader.EndOfStream) { - containerId = trimmedLine.Substring(trimmedLine.Length - 64); - return containerId; + var trimmedLine = streamReader.ReadLine().Trim(); + if (trimmedLine.Length > 64) + { + return trimmedLine.Substring(trimmedLine.Length - 64); + } } } } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get Container Id", ex); + } - return containerId; + return null; } internal AWSEKSClusterInformationModel DeserializeResponse(string response) @@ -115,26 +125,35 @@ internal AWSEKSClusterInformationModel DeserializeResponse(string response) return ResourceDetectorUtils.DeserializeFromString(response); } - private string GetEKSClusterName(string path) + private string GetEKSClusterName(string credentials) { - var credentials = this.GetEKSCredentials(path); - - if (!this.IsEKSProcess(credentials)) + try { - return null; + var clusterInfo = this.GetEKSClusterInfo(credentials); + return this.DeserializeResponse(clusterInfo)?.Data?.ClusterName; + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get cluster information", ex); } - var clusterInfo = this.GetEKSClusterInfo(credentials); - var clusterInfoObject = this.DeserializeResponse(clusterInfo); - - return clusterInfoObject.Data?.ClusterName; + return null; } private bool IsEKSProcess(string credentials) { - var httpClientHandler = this.CreateHttpClientHandler(); - var awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; - return string.IsNullOrEmpty(awsAuth); + string awsAuth = null; + try + { + var httpClientHandler = this.CreateHttpClientHandler(); + awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get EKS information", ex); + } + + return !string.IsNullOrEmpty(awsAuth); } private string GetEKSClusterInfo(string credentials) diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index 961e654140..1273acabfc 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -44,12 +44,43 @@ public void TestExtractResourceAttributes() var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, containerId).ToDictionary(x => x.Key, x => x.Value); + Assert.Equal(4, resourceAttributes.Count); Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); Assert.Equal("Test cluster name", resourceAttributes[AWSSemanticConventions.AttributeK8SClusterName]); Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); } + [Fact] + public void TestExtractResourceAttributesWithEmptyClusterName() + { + var eksResourceDetector = new AWSEKSResourceDetector(); + var containerId = "Test container id"; + + var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(string.Empty, containerId).ToDictionary(x => x.Key, x => x.Value); + + // Validate the count of resourceAttributes -> Excluding cluster name, there will be only three resourceAttributes + Assert.Equal(3, resourceAttributes.Count); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); + } + + [Fact] + public void TestExtractResourceAttributesWithEmptyContainerId() + { + var eksResourceDetector = new AWSEKSResourceDetector(); + var clusterName = "Test cluster name"; + + var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, string.Empty).ToDictionary(x => x.Key, x => x.Value); + + // Validate the count of resourceAttributes -> Excluding container id, there will be only three resourceAttributes + Assert.Equal(3, resourceAttributes.Count); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test cluster name", resourceAttributes[AWSSemanticConventions.AttributeK8SClusterName]); + } + [Fact] public void TestGetEKSCredentials() { From 693e2617a7f5d9c147a727cf3d9daef248ec2a8c Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Thu, 3 Mar 2022 18:37:26 +0100 Subject: [PATCH 0015/1499] Runtime instrumentation (#207) --- .../package-Instrumentation.Runtime.yml | 49 ++++++ .github/workflows/pr_build.yml | 2 +- opentelemetry-dotnet-contrib.sln | 14 ++ .../AssemblyInfo.cs | 23 +++ .../MeterProviderBuilderExtensions.cs | 50 +++++++ ...try.Contrib.Instrumentation.Runtime.csproj | 14 ++ .../README.md | 88 +++++++++++ .../RuntimeMetrics.cs | 104 +++++++++++++ .../RuntimeMetricsOptions.cs | 100 +++++++++++++ ...ntrib.Instrumentation.Runtime.Tests.csproj | 26 ++++ .../RuntimeMetricsOptionsTests.cs | 140 ++++++++++++++++++ .../RuntimeMetricsTests.cs | 61 ++++++++ 12 files changed, 670 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/package-Instrumentation.Runtime.yml create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Contrib.Instrumentation.Runtime.csproj create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml new file mode 100644 index 0000000000..e5ff3f4966 --- /dev/null +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Contrib.Instrumentation.Runtime + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.Runtime-*' # trigger when we create a tag with prefix "Instrumentation.Runtime-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Contrib.Instrumentation.Runtime + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 5e7f20e319..ed3e8af464 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [windows-latest,ubuntu-latest] - version: [net461,netcoreapp3.1,net5.0] + version: [net461,netcoreapp3.1,net5.0,net6.0] exclude: - os: ubuntu-latest version: net461 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 11ea786c81..0d7d416698 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -156,6 +156,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exten EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj", "{72EBA81D-2933-417C-8F21-D4CFFD72F530}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Contrib.Instrumentation.Runtime", "src\OpenTelemetry.Contrib.Instrumentation.Runtime\OpenTelemetry.Contrib.Instrumentation.Runtime.csproj", "{F01E8C75-2791-4DBE-BD7A-5510871EBF56}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Contrib.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -306,6 +310,14 @@ Global {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Debug|Any CPU.Build.0 = Debug|Any CPU {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Release|Any CPU.ActiveCfg = Release|Any CPU {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Release|Any CPU.Build.0 = Release|Any CPU + {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Release|Any CPU.Build.0 = Release|Any CPU + {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -353,6 +365,8 @@ Global {D52558C8-B7BF-4F59-A0FA-9AA629E68012} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {433C59A3-D535-421E-BA7F-9BCE0D4A3D25} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {72EBA81D-2933-417C-8F21-D4CFFD72F530} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {F01E8C75-2791-4DBE-BD7A-5510871EBF56} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs new file mode 100644 index 0000000000..82ef8df4ab --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Runtime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Runtime.Tests")] +#endif diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..7bc2e24aef --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -0,0 +1,50 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Contrib.Instrumentation.Runtime; + +namespace OpenTelemetry.Metrics +{ + /// + /// Extension methods to simplify registering of dependency instrumentation. + /// + public static class MeterProviderBuilderExtensions + { + /// + /// Enables runtime instrumentation. + /// + /// being configured. + /// Runtime metrics options. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddRuntimeMetrics( + this MeterProviderBuilder builder, + Action configure = null) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + var options = new RuntimeMetricsOptions(); + configure?.Invoke(options); + + var instrumentation = new RuntimeMetrics(options); + builder.AddMeter(RuntimeMetrics.InstrumentationName); + return builder.AddInstrumentation(() => instrumentation); + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Contrib.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Contrib.Instrumentation.Runtime.csproj new file mode 100644 index 0000000000..c6b246f127 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Contrib.Instrumentation.Runtime.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0;net461;netcoreapp3.1;net6.0 + dotnet runtime instrumentation for OpenTelemetry .NET + $(PackageTags);OpenTelemetry;runtime + Instrumentation.Runtime- + + + + + + + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md new file mode 100644 index 0000000000..c80f7c713b --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md @@ -0,0 +1,88 @@ +# DotNet Runtime Instrumentation for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Runtime) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Contrib.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Runtime) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments [.NET Runtime](https://docs.microsoft.com/dotnet) and +collect telemetry about runtime behavior. + +## Steps to enable OpenTelemetry.Contrib.Instrumentation.Runtime + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Contrib.Instrumentation.Runtime`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Runtime) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Contrib.Instrumentation.Runtime +``` + +### Step 2: Enable Runtime Instrumentation at application startup + +Runtime instrumentation must be enabled at application startup. This is +typically done in the `ConfigureServices` of your `Startup` class. The example +below enables this instrumentation by using an extension method on +`IServiceCollection`. This extension method requires adding the package +[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md) +to the application. This ensures the instrumentation is disposed when the host +is shutdown. + +Additionally, this examples sets up the OpenTelemetry Prometheus exporter, which +requires adding the package +[`OpenTelemetry.Exporter.Prometheus`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus/README.md) +to the application. + +```csharp +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Metrics; + +public void ConfigureServices(IServiceCollection services) +{ + services.AddOpenTelemetryMetrics((builder) => builder + .AddRuntimeMetrics() + .AddPrometheusExporter() + ); +} +``` + +Or configure directly: + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeMetrics() + .Build(); +``` + +## Advanced configuration + +By default all available runtime metrics will be added. It's also possible to +specify only the required metrics: + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeMetrics(options => options + { + options.GcEnabled = true; + options.ThreadingEnabled = true; + options.MemoryEnabled = true; + }) + .Build(); +``` + +## Troubleshooting + +This component uses an +[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) +with the name "OpenTelemetry-Instrumentation-Runtime" for its internal +logging. Please refer to [SDK +troubleshooting](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry#troubleshooting) +for instructions on seeing these internal logs. + +## References + +* [Introduction to ASP.NET + Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core) +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs new file mode 100644 index 0000000000..0fe2926d08 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -0,0 +1,104 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Metrics; +using System.Reflection; +using System.Threading; + +namespace OpenTelemetry.Contrib.Instrumentation.Runtime +{ + /// + /// .NET runtime instrumentation. + /// + internal class RuntimeMetrics : IDisposable + { + internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name; + internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + + private readonly Meter meter; + + /// + /// Initializes a new instance of the class. + /// + /// The options to define the metrics. + public RuntimeMetrics(RuntimeMetricsOptions options) + { + this.meter = new Meter(InstrumentationName, InstrumentationVersion); + + if (options.IsGcEnabled) + { + this.meter.CreateObservableGauge($"{options.MetricPrefix}gc.heap", () => GC.GetTotalMemory(false), "B", "GC Heap Size"); + this.meter.CreateObservableGauge($"{options.MetricPrefix}gen_0-gc.count", () => GC.CollectionCount(0), description: "Gen 0 GC Count"); + this.meter.CreateObservableGauge($"{options.MetricPrefix}gen_1-gc.count", () => GC.CollectionCount(1), description: "Gen 1 GC Count"); + this.meter.CreateObservableGauge($"{options.MetricPrefix}gen_2-gc.count", () => GC.CollectionCount(2), description: "Gen 2 GC Count"); +#if NETCOREAPP3_1_OR_GREATER + this.meter.CreateObservableCounter($"{options.MetricPrefix}alloc.rate", () => GC.GetTotalAllocatedBytes(), "B", "Allocation Rate"); + this.meter.CreateObservableCounter($"{options.MetricPrefix}gc.fragmentation", GetFragmentation, description: "GC Fragmentation"); +#endif + +#if NET6_0_OR_GREATER + this.meter.CreateObservableCounter($"{options.MetricPrefix}gc.committed", () => (double)(GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000), "MB", description: "GC Committed Bytes"); +#endif + } + +#if NET6_0_OR_GREATER + if (options.IsJitEnabled) + { + this.meter.CreateObservableCounter($"{options.MetricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "B", description: "IL Bytes Jitted"); + this.meter.CreateObservableCounter($"{options.MetricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted"); + this.meter.CreateObservableGauge($"{options.MetricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().TotalMilliseconds, "ms", description: "Time spent in JIT"); + } +#endif + +#if NETCOREAPP3_1_OR_GREATER + if (options.IsThreadingEnabled) + { + this.meter.CreateObservableGauge($"{options.MetricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count"); + this.meter.CreateObservableCounter($"{options.MetricPrefix}threadpool.thread.count", () => ThreadPool.ThreadCount, description: "ThreadPool Thread Count"); + this.meter.CreateObservableGauge($"{options.MetricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count"); + this.meter.CreateObservableCounter($"{options.MetricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length"); + this.meter.CreateObservableCounter($"{options.MetricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers"); + } +#endif + + if (options.IsMemoryEnabled) + { + this.meter.CreateObservableGauge($"{options.MetricPrefix}memory.usage", () => (double)(Environment.WorkingSet / 1_000_000), "MB", "Working Set"); + } + + if (options.IsAssembliesEnabled) + { + this.meter.CreateObservableCounter($"{options.MetricPrefix}assembly.count", () => AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); + } + } + + /// + public void Dispose() + { + this.meter?.Dispose(); + } + +#if NETCOREAPP3_1_OR_GREATER + private static double GetFragmentation() + { + var gcInfo = GC.GetGCMemoryInfo(); + return gcInfo.HeapSizeBytes != 0 ? gcInfo.FragmentedBytes * 100d / gcInfo.HeapSizeBytes : 0; + } +#endif + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs new file mode 100644 index 0000000000..08f8576a97 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -0,0 +1,100 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Contrib.Instrumentation.Runtime +{ + /// + /// Options to define the runtime metrics. + /// + public class RuntimeMetricsOptions + { + /// + /// Gets a prefix used for the metric names. + /// + public string MetricPrefix { get; } = "process.runtime.dotnet."; + + /// + /// Gets or sets a value indicating whether garbage collection metrics should be collected. + /// + public bool? GcEnabled { get; set; } + +#if NET6_0_OR_GREATER + /// + /// Gets or sets a value indicating whether jitter metrics should be collected. + /// + public bool? JitEnabled { get; set; } +#endif + +#if NETCOREAPP3_1_OR_GREATER + /// + /// Gets or sets a value indicating whether threading metrics should be collected. + /// + public bool? ThreadingEnabled { get; set; } +#endif + + /// + /// Gets or sets a value indicating whether memory metrics should be collected. + /// + public bool? MemoryEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether assembly metrics should be collected. + /// + public bool? AssembliesEnabled { get; set; } + + /// + /// Gets a value indicating whether all metrics are enabled. + /// + internal bool IsAllEnabled => this.GcEnabled == null +#if NET6_0_OR_GREATER + && this.JitEnabled == null +#endif +#if NETCOREAPP3_1_OR_GREATER + && this.ThreadingEnabled == null +#endif + && this.MemoryEnabled == null + && this.AssembliesEnabled == null; + + /// + /// Gets a value indicating whether garbage collection metrics is enabled. + /// + internal bool IsGcEnabled => this.GcEnabled == true || this.IsAllEnabled; + +#if NET6_0_OR_GREATER + /// + /// Gets a value indicating whether jitter metrics is enabled. + /// + internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; +#endif + +#if NETCOREAPP3_1_OR_GREATER + /// + /// Gets a value indicating whether threading metrics is enabled. + /// + internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; +#endif + + /// + /// Gets a value indicating whether memory metrics is enabled. + /// + internal bool IsMemoryEnabled => this.MemoryEnabled == true || this.IsAllEnabled; + + /// + /// Gets a value indicating whether assembly metrics is enabled. + /// + internal bool IsAssembliesEnabled => this.AssembliesEnabled == true || this.IsAllEnabled; + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj new file mode 100644 index 0000000000..3b801c40fa --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp3.1;net6.0 + $(TargetFrameworks);net461 + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs new file mode 100644 index 0000000000..e8942649a7 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -0,0 +1,140 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Xunit; + +namespace OpenTelemetry.Contrib.Instrumentation.Runtime.Tests +{ + public class RuntimeMetricsOptionsTests + { + [Fact] + public void Enable_All_If_Nothing_Was_Defined() + { + var options = new RuntimeMetricsOptions(); + + Assert.True(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.True(options.IsJitEnabled); +#endif +#if NETCOREAPP3_1_OR_GREATER + Assert.True(options.IsThreadingEnabled); +#endif + Assert.True(options.IsMemoryEnabled); + Assert.True(options.IsAssembliesEnabled); + Assert.True(options.IsAllEnabled); + } + + [Fact] + public void Enable_Gc_Only() + { + var options = new RuntimeMetricsOptions { GcEnabled = true }; + + Assert.True(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); +#endif +#if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); +#endif + Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + +#if NET6_0_OR_GREATER + [Fact] + public void Enable_Jit_Only() + { + var options = new RuntimeMetricsOptions { JitEnabled = true }; + + Assert.False(options.IsGcEnabled); + Assert.True(options.IsJitEnabled); + Assert.False(options.IsThreadingEnabled); + Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } +#endif + +#if NETCOREAPP3_1_OR_GREATER + [Fact] + public void Enable_Threading_Only() + { + var options = new RuntimeMetricsOptions { ThreadingEnabled = true }; + + Assert.False(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); +#endif + Assert.True(options.IsThreadingEnabled); + Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } +#endif + + [Fact] + public void Enable_Memory_Only() + { + var options = new RuntimeMetricsOptions { MemoryEnabled = true }; + + Assert.False(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); +#endif +#if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); +#endif + Assert.True(options.IsMemoryEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + + [Fact] + public void Enable_Assemblies_Only() + { + var options = new RuntimeMetricsOptions { AssembliesEnabled = true }; + + Assert.False(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); +#endif +#if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); +#endif + Assert.False(options.IsMemoryEnabled); + Assert.True(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + + [Fact] + public void Enable_Multiple() + { + var options = new RuntimeMetricsOptions { GcEnabled = true, MemoryEnabled = true }; + + Assert.True(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); +#endif +#if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); +#endif + Assert.True(options.IsMemoryEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs new file mode 100644 index 0000000000..4da53cbb5e --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -0,0 +1,61 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using OpenTelemetry.Exporter; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Contrib.Instrumentation.Runtime.Tests +{ + public class RuntimeMetricsTests + { + private MeterProvider meterProvider = null; + + [Fact] + public async Task RequestMetricIsCaptured() + { + var metricItems = new List(); + var metricExporter = new InMemoryExporter(metricItems); + + var metricReader = new PeriodicExportingMetricReader(metricExporter, 500); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeMetrics(options => + { + options.GcEnabled = true; +#if NETCOREAPP3_1_OR_GREATER + options.ThreadingEnabled = true; +#endif + options.MemoryEnabled = true; +#if NET6_0_OR_GREATER + + options.JitEnabled = true; +#endif + options.AssembliesEnabled = true; + }) + .AddReader(metricReader) + .Build(); + + await Task.Delay(TimeSpan.FromSeconds(2)); + this.meterProvider.Dispose(); + + Assert.True(metricItems.Count > 1); + } + } +} From 46b9dffb03f402def42045c01cb8bbb7e042dde5 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 3 Mar 2022 09:50:48 -0800 Subject: [PATCH 0016/1499] Add Utkarsh as maintainer (#211) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 63af35a99f..4b8bade25a 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Maintainers * [Mikel Blanchard](https://github.com/CodeBlanch), CoStar Group * [Prashant Srivastava](https://github.com/srprash), AWS * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev), Google +* [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* From f9df5f29a8ec42b501049ce3b9dd6c3d5dccf2d6 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 3 Mar 2022 17:30:45 -0800 Subject: [PATCH 0017/1499] Minor improvements to Runtime metrics (#212) --- .../RuntimeMetrics.cs | 36 +++++++++---------- .../RuntimeMetricsOptions.cs | 5 --- ...ntrib.Instrumentation.Runtime.Tests.csproj | 4 +-- .../RuntimeMetricsTests.cs | 23 ++++++------ 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs index 0fe2926d08..2d3acd51e1 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -29,7 +29,7 @@ internal class RuntimeMetrics : IDisposable internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); internal static readonly string InstrumentationName = AssemblyName.Name; internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); - + private static string metricPrefix = "process.runtime.dotnet."; private readonly Meter meter; /// @@ -42,48 +42,48 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsGcEnabled) { - this.meter.CreateObservableGauge($"{options.MetricPrefix}gc.heap", () => GC.GetTotalMemory(false), "B", "GC Heap Size"); - this.meter.CreateObservableGauge($"{options.MetricPrefix}gen_0-gc.count", () => GC.CollectionCount(0), description: "Gen 0 GC Count"); - this.meter.CreateObservableGauge($"{options.MetricPrefix}gen_1-gc.count", () => GC.CollectionCount(1), description: "Gen 1 GC Count"); - this.meter.CreateObservableGauge($"{options.MetricPrefix}gen_2-gc.count", () => GC.CollectionCount(2), description: "Gen 2 GC Count"); + this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "B", "GC Heap Size"); + this.meter.CreateObservableGauge($"{metricPrefix}gen_0-gc.count", () => GC.CollectionCount(0), description: "Gen 0 GC Count"); + this.meter.CreateObservableGauge($"{metricPrefix}gen_1-gc.count", () => GC.CollectionCount(1), description: "Gen 1 GC Count"); + this.meter.CreateObservableGauge($"{metricPrefix}gen_2-gc.count", () => GC.CollectionCount(2), description: "Gen 2 GC Count"); #if NETCOREAPP3_1_OR_GREATER - this.meter.CreateObservableCounter($"{options.MetricPrefix}alloc.rate", () => GC.GetTotalAllocatedBytes(), "B", "Allocation Rate"); - this.meter.CreateObservableCounter($"{options.MetricPrefix}gc.fragmentation", GetFragmentation, description: "GC Fragmentation"); + this.meter.CreateObservableCounter($"{metricPrefix}alloc.rate", () => GC.GetTotalAllocatedBytes(), "B", "Allocation Rate"); + this.meter.CreateObservableCounter($"{metricPrefix}gc.fragmentation", GetFragmentation, description: "GC Fragmentation"); #endif #if NET6_0_OR_GREATER - this.meter.CreateObservableCounter($"{options.MetricPrefix}gc.committed", () => (double)(GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000), "MB", description: "GC Committed Bytes"); + this.meter.CreateObservableCounter($"{metricPrefix}gc.committed", () => (double)(GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000), "MB", description: "GC Committed Bytes"); #endif } #if NET6_0_OR_GREATER if (options.IsJitEnabled) { - this.meter.CreateObservableCounter($"{options.MetricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "B", description: "IL Bytes Jitted"); - this.meter.CreateObservableCounter($"{options.MetricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted"); - this.meter.CreateObservableGauge($"{options.MetricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().TotalMilliseconds, "ms", description: "Time spent in JIT"); + this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "B", description: "IL Bytes Jitted"); + this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted"); + this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().TotalMilliseconds, "ms", description: "Time spent in JIT"); } #endif #if NETCOREAPP3_1_OR_GREATER if (options.IsThreadingEnabled) { - this.meter.CreateObservableGauge($"{options.MetricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count"); - this.meter.CreateObservableCounter($"{options.MetricPrefix}threadpool.thread.count", () => ThreadPool.ThreadCount, description: "ThreadPool Thread Count"); - this.meter.CreateObservableGauge($"{options.MetricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count"); - this.meter.CreateObservableCounter($"{options.MetricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length"); - this.meter.CreateObservableCounter($"{options.MetricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers"); + this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count"); + this.meter.CreateObservableCounter($"{metricPrefix}threadpool.thread.count", () => ThreadPool.ThreadCount, description: "ThreadPool Thread Count"); + this.meter.CreateObservableGauge($"{metricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count"); + this.meter.CreateObservableCounter($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length"); + this.meter.CreateObservableCounter($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers"); } #endif if (options.IsMemoryEnabled) { - this.meter.CreateObservableGauge($"{options.MetricPrefix}memory.usage", () => (double)(Environment.WorkingSet / 1_000_000), "MB", "Working Set"); + this.meter.CreateObservableGauge($"{metricPrefix}memory.usage", () => (double)(Environment.WorkingSet / 1_000_000), "MB", "Working Set"); } if (options.IsAssembliesEnabled) { - this.meter.CreateObservableCounter($"{options.MetricPrefix}assembly.count", () => AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); + this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs index 08f8576a97..be87760660 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -21,11 +21,6 @@ namespace OpenTelemetry.Contrib.Instrumentation.Runtime /// public class RuntimeMetricsOptions { - /// - /// Gets a prefix used for the metric names. - /// - public string MetricPrefix { get; } = "process.runtime.dotnet."; - /// /// Gets or sets a value indicating whether garbage collection metrics should be collected. /// diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj index 3b801c40fa..523500f8ff 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj @@ -1,15 +1,13 @@ - netcoreapp3.1;net6.0 + netcoreapp3.1;net5.0;net6.0 $(TargetFrameworks);net461 - - diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 4da53cbb5e..fad59ac08a 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -25,17 +25,14 @@ namespace OpenTelemetry.Contrib.Instrumentation.Runtime.Tests { public class RuntimeMetricsTests { - private MeterProvider meterProvider = null; + private const int MaxTimeToAllowForFlush = 10000; + private const string MetricPrefix = "process.runtime.dotnet."; [Fact] - public async Task RequestMetricIsCaptured() + public void RuntimeMetricsAreCaptured() { - var metricItems = new List(); - var metricExporter = new InMemoryExporter(metricItems); - - var metricReader = new PeriodicExportingMetricReader(metricExporter, 500); - - this.meterProvider = Sdk.CreateMeterProviderBuilder() + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddRuntimeMetrics(options => { options.GcEnabled = true; @@ -49,13 +46,13 @@ public async Task RequestMetricIsCaptured() #endif options.AssembliesEnabled = true; }) - .AddReader(metricReader) + .AddInMemoryExporter(exportedItems) .Build(); - await Task.Delay(TimeSpan.FromSeconds(2)); - this.meterProvider.Dispose(); - - Assert.True(metricItems.Count > 1); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.True(exportedItems.Count > 1); + var metric1 = exportedItems[0]; + Assert.StartsWith(MetricPrefix, metric1.Name); } } } From 707a799e3ef1fb39cb98518d4bb11b14884a20bf Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 4 Mar 2022 10:47:44 -0800 Subject: [PATCH 0018/1499] Rename to remove contrib from instrumentation runtime project (#213) * Rename to remove contrib from instrumentation runtime project * visibility --- .github/workflows/package-Instrumentation.Runtime.yml | 4 ++-- opentelemetry-dotnet-contrib.sln | 6 ++++-- .../AssemblyInfo.cs | 4 ++-- ....csproj => OpenTelemetry.Instrumentation.Runtime.csproj} | 0 ...j => OpenTelemetry.Instrumentation.Runtime.Tests.csproj} | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) rename src/OpenTelemetry.Contrib.Instrumentation.Runtime/{OpenTelemetry.Contrib.Instrumentation.Runtime.csproj => OpenTelemetry.Instrumentation.Runtime.csproj} (100%) rename test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/{OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj => OpenTelemetry.Instrumentation.Runtime.Tests.csproj} (90%) diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index e5ff3f4966..66bc552ebf 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.Runtime +name: Pack OpenTelemetry.Instrumentation.Runtime on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.Runtime + PROJECT: OpenTelemetry.Instrumentation.Runtime strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 0d7d416698..f97d7582bb 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -10,6 +10,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{07AA0F83-22F6-4B8C-921D-029D3384CB17}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + CONTRIBUTING.md = CONTRIBUTING.md NuGet.config = NuGet.config opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj README.md = README.md @@ -37,6 +38,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml + .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\package-Preview.yml = .github\workflows\package-Preview.yml .github\workflows\pr_build.yml = .github\workflows\pr_build.yml @@ -156,9 +158,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exten EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj", "{72EBA81D-2933-417C-8F21-D4CFFD72F530}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Contrib.Instrumentation.Runtime", "src\OpenTelemetry.Contrib.Instrumentation.Runtime\OpenTelemetry.Contrib.Instrumentation.Runtime.csproj", "{F01E8C75-2791-4DBE-BD7A-5510871EBF56}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Contrib.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{F01E8C75-2791-4DBE-BD7A-5510871EBF56}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Contrib.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs index 82ef8df4ab..4b7b851acc 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Runtime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Runtime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Runtime.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Runtime.Tests")] #endif diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Contrib.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Contrib.Instrumentation.Runtime.csproj rename to src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj similarity index 90% rename from test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj rename to test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 523500f8ff..ff2ea386be 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1;net5.0;net6.0 @@ -18,7 +18,7 @@ - + From 94848f093641032404fc76105fe4d8788308ace8 Mon Sep 17 00:00:00 2001 From: Samuel Cochrane Date: Tue, 8 Mar 2022 19:17:18 +0000 Subject: [PATCH 0019/1499] Add QuartzNET instrumentation (#129) --- .../package-Instrumentation.Quartz.yml | 49 +++ CODEOWNERS | 4 +- opentelemetry-dotnet-contrib.sln | 40 +- .../CHANGELOG.md | 3 + .../QuartzDiagnosticListener.cs | 141 +++++++ .../QuartzInstrumentationEventSource.cs | 58 +++ .../Implementation/TagName.cs | 31 ++ ...penTelemetry.Instrumentation.Quartz.csproj | 14 + .../OperationName.cs | 40 ++ .../Properties/AssemblyInfo.cs | 22 + .../QuartzInstrumentationOptions.cs | 61 +++ .../QuartzJobInstrumentation.cs | 46 ++ .../README.md | 111 +++++ .../TraceProviderBuilderExtensions.cs | 51 +++ ...emetry.Instrumentation.Quartz.Tests.csproj | 26 ++ .../QuartzDiagnosticListenerTests.cs | 395 ++++++++++++++++++ .../TestJob.cs | 47 +++ .../TestJobExecutionExceptionJob.cs | 29 ++ 18 files changed, 1154 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/package-Instrumentation.Quartz.yml create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/README.md create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs create mode 100644 test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml new file mode 100644 index 0000000000..759dac8adf --- /dev/null +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Contrib.Instrumentation.Quartz + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.Quartz-*' # trigger when we create a tag with prefix "Instrumentation.Quartz-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Contrib.Instrumentation.Quartz + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS index 20b9e45a18..3d742ed04d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -14,6 +14,7 @@ src/OpenTelemetry.Contrib.Instrumentation.Owin/ @ope src/OpenTelemetry.Contrib.Instrumentation.Wcf/ @open-telemetry/dotnet-contrib-approvers @codeblanch src/OpenTelemetry.Contrib.Instrumentation.MySqlData/ @open-telemetry/dotnet-contrib-approvers @moonheart src/OpenTelemetry.Contrib.Extensions.PersistentStorage/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar +src/OpenTelemetry.Contrib.Instrumentation.Quartz/ @open-telemetry/dotnet-contrib-approvers @maldago src/OpenTelemetry.Contrib.Preview/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/ @open-telemetry/dotnet-contrib-approvers @SergeyKanzhelev @@ -25,5 +26,6 @@ test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/ @ope test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/ @open-telemetry/dotnet-contrib-approvers @moonheart -test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar +test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar +src/OpenTelemetry.Contrib.Instrumentation.Quartz.Tests/ @open-telemetry/dotnet-contrib-approvers @maldago test/OpenTelemetry.Contrib.Preview.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f97d7582bb..f09288625a 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -38,6 +38,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml + .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\package-Preview.yml = .github\workflows\package-Preview.yml @@ -52,7 +53,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.props = build\Common.props build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk - build\docfx.cmd = build\docfx.cmd build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset @@ -142,6 +142,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Previ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj", "{4172D671-3AAC-443F-9EB0-A6608B154AF0}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AzureMonitor", "src\OpenTelemetry.Contrib.Extensions.AzureMonitor\OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj", "{9C2D6D1A-8580-4527-B718-E206D0690635}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests\OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj", "{771651AA-010F-4FF6-9CB2-BAFFE5E04FC2}" @@ -268,18 +272,26 @@ Global {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.Build.0 = Debug|Any CPU {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.ActiveCfg = Release|Any CPU {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.Build.0 = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.Build.0 = Release|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.Build.0 = Release|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.Build.0 = Release|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -359,6 +371,8 @@ Global {B978939B-278C-43A3-AD12-32EA9BBD27D0} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D2C68560-C252-41A9-B742-2CEB7D760E0F} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {4172D671-3AAC-443F-9EB0-A6608B154AF0} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {9C2D6D1A-8580-4527-B718-E206D0690635} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {530255C1-D130-4B43-981D-911E54F7C787} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md new file mode 100644 index 0000000000..1512c42162 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +## Unreleased diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs new file mode 100644 index 0000000000..203eb1b18c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -0,0 +1,141 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Quartz.Implementation +{ + internal sealed class QuartzDiagnosticListener : ListenerHandler + { + internal static readonly AssemblyName AssemblyName = typeof(QuartzDiagnosticListener).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly Version Version = AssemblyName.Version; + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal readonly PropertyFetcher JobDetailsPropertyFetcher = new PropertyFetcher("JobDetail"); + + private readonly QuartzInstrumentationOptions options; + + public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions options) + : base(sourceName) + { + this.options = options ?? throw new ArgumentNullException(nameof(options)); + } + + public override void OnStartActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + if (!this.options.TracedOperations.Contains(activity.OperationName)) + { + QuartzInstrumentationEventSource.Log.OperationIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; + return; + } + + activity.DisplayName = this.GetDisplayName(activity); + + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); + + try + { + this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); + this.options.Enrich?.Invoke(activity, "OnStartActivity", jobDetails); + } + catch (Exception ex) + { + QuartzInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + public override void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + try + { + this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); + this.options.Enrich?.Invoke(activity, "OnStopActivity", jobDetails); + } + catch (Exception ex) + { + QuartzInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + public override void OnException(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + var exc = payload as Exception; + if (exc == null) + { + QuartzInstrumentationEventSource.Log.NullPayload(nameof(QuartzDiagnosticListener), nameof(this.OnStopActivity)); + return; + } + + if (this.options.RecordException) + { + activity.RecordException(exc); + } + + activity.SetStatus(Status.Error.WithDescription(exc.Message)); + + try + { + this.options.Enrich?.Invoke(activity, "OnException", exc); + } + catch (Exception ex) + { + QuartzInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + private string GetDisplayName(Activity activity) + { + return activity.OperationName switch + { + OperationName.Job.Execute => $"execute {this.GetTag(activity.Tags, TagName.JobName)}", + OperationName.Job.Veto => $"veto {this.GetTag(activity.Tags, TagName.JobName)}", + _ => activity.DisplayName, + }; + } + + private ActivityKind GetActivityKind(Activity activity) + { + return activity.OperationName switch + { + OperationName.Job.Execute => ActivityKind.Internal, + OperationName.Job.Veto => ActivityKind.Internal, + _ => activity.Kind, + }; + } + + private string GetTag(IEnumerable> tags, string tagName) + { + var tag = tags.SingleOrDefault(kv => kv.Key == tagName); + return tag.Value; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs new file mode 100644 index 0000000000..d808462aab --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -0,0 +1,58 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Quartz.Implementation +{ + /// + /// EventSource events emitted from the project. + /// + [EventSource(Name = "OpenTelemetry-Instrumentation-Quartz")] + internal class QuartzInstrumentationEventSource : EventSource + { + public static readonly QuartzInstrumentationEventSource Log = new QuartzInstrumentationEventSource(); + + [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(1, handlerName, eventName); + } + + [Event(2, Message = "Request is filtered out.", Level = EventLevel.Verbose)] + public void OperationIsFilteredOut(string eventName) + { + this.WriteEvent(2, eventName); + } + + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) + { + this.EnrichmentException(ex.ToInvariantString()); + } + } + + [Event(3, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(3, exception); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs new file mode 100644 index 0000000000..81134209bf --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Quartz.Implementation +{ + internal static class TagName + { + public const string DefaultListenerName = "Quartz"; + public const string SchedulerName = "scheduler.name"; + public const string SchedulerId = "scheduler.id"; + public const string FireInstanceId = "fire.instance.id"; + public const string TriggerGroup = "trigger.group"; + public const string TriggerName = "trigger.name"; + public const string JobType = "job.type"; + public const string JobGroup = "job.group"; + public const string JobName = "job.name"; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj new file mode 100644 index 0000000000..08d5120a59 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -0,0 +1,14 @@ + + + OpenTelemetry Quartz.NET Instrumentation + $(PackageTags);distributed-tracing + Instrumentation.Quartz- + true + net472;netstandard2.0 + OpenTelemetry.Instrumentation.Quartz + OpenTelemetry.Instrumentation.Quartz + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs new file mode 100644 index 0000000000..550c6d8c05 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Quartz +{ + /// + /// Quartz diagnostic source operation name constants. + /// + public static class OperationName + { + /// + /// Quartz Job category constants. + /// + public static class Job + { + /// + /// Quartz job execute diagnostic source operation name. + /// + public const string Execute = "Quartz.Job.Execute"; + + /// + /// Quartz job veto diagnostic source operation name. + /// + public const string Veto = "Quartz.Job.Veto"; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..67f6fcf60f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Quartz.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Quartz.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs new file mode 100644 index 0000000000..4c7e63981f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -0,0 +1,61 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenTelemetry.Instrumentation.Quartz +{ + /// + /// Options for . + /// + public class QuartzInstrumentationOptions + { + /// + /// Default traced operations. + /// + private static readonly IEnumerable DefaultTracedOperations = new[] + { + OperationName.Job.Execute, + OperationName.Job.Veto, + }; + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// string: the name of the event. + /// object: the raw object from which additional information can be extracted to enrich the activity. + /// The type of this object depends on the event, which is given by the above parameter. + /// + public Action Enrich { get; set; } + + /// + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. + /// + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. + /// + public bool RecordException { get; set; } + + /// + /// Gets or sets traced operations set. + /// + public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs new file mode 100644 index 0000000000..88c6983eed --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs @@ -0,0 +1,46 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.Quartz.Implementation; + +namespace OpenTelemetry.Instrumentation.Quartz +{ + internal class QuartzJobInstrumentation : IDisposable + { + internal const string QuartzDiagnosticListenerName = "Quartz"; + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + public QuartzJobInstrumentation() + : this(new QuartzInstrumentationOptions()) + { + } + + public QuartzJobInstrumentation(QuartzInstrumentationOptions options) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( + name => new QuartzDiagnosticListener(name, options), + listener => listener.Name == QuartzDiagnosticListenerName, + null); + this.diagnosticSourceSubscriber.Subscribe(); + } + + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md new file mode 100644 index 0000000000..d2841acb0b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -0,0 +1,111 @@ +# QuartzNET Instrumentation for OpenTelemetry .NET + +Automatically instruments the Quartz jobs from +[Quartz](https://www.nuget.org/packages/Quartz/). + +## Supported Frameworks + +QuartzNET Instrumentation is only supported when using +.NET Framework >= `net472` and netstandard >= `netstandard2.0`. +Quartz`net461` support for activity sources has been removed, +more information can be found +[here](https://www.quartz-scheduler.net/2021/04/07/quartznet-3-3-released/). + +## Installation + +```shell +dotnet add package OpenTelemetry.Extensions.Hosting +dotnet add package OpenTelemetry.Contrib.Instrumentation.Quartz +``` + +## Configuration + +ASP.NET Core instrumentation example: + +```csharp +// Add QuartzNET inside ConfigureServices +public void ConfigureServices(IServiceCollection services) +{ + services.AddQuartz(q => + { + // base quartz scheduler, job and trigger configuration + }); + + // ASP.NET Core hosting + services.AddQuartzServer(options => + { + // when shutting down we want jobs to complete gracefully + options.WaitForJobsToComplete = true; + }); +} + +// Add OpenTelemetry and Quartz instrumentation +services.AddOpenTelemetryTracing(x => +{ + x.AddQuartzInstrumentation(); + x.UseJaegerExporter(config => { + // Configure Jaeger + }); +}); +``` + +## Filter traced operations + +This option allows you to filter trace operations. + +For example you can trace only execute operations using this snippet: + +```csharp +// ... +using OpenTelemetry.Instrumentation.Quartz.Implementation; +// ... +x.AddQuartzInstrumentation( + opts => + opts.TracedOperations = new + HashSet(new[] { + OperationName.Job.Execute, +})); +``` + +For full operation list please see: [OperationName](../OpenTelemetry.Instrumentation.Quartz/Implementation/OperationName.cs). + +All operations are enabled by default. + +## Enrich + +This option allows one to enrich the activity with additional information +from the raw `JobDetail` object. The `Enrich` action is +called only when `activity.IsAllDataRequested` is `true`. It contains the +activity itself (which can be enriched), the name of the event, and the +actual raw object. + +For event names "OnStartActivity", "OnStopActivity", the actual object will be `IJobDetail`. + +For event name "OnException", the actual object will be the exception thrown + +The following code snippet shows how to add additional tags using `Enrich`. + +```csharp +// ... +using OpenTelemetry.Instrumentation.Quartz.Implementation; +using Quartz; +// ... +// Enable enriching an activity after it is created. +x.AddQuartzInstrumentation(opt => +{ + opt.Enrich = (activity, eventName, quartzJobDetails) => + { + // update activity + if (quartzJobDetails is IJobDetail jobDetail) + { + activity.SetTag("customProperty", jobDetail.JobDataMap["customProperty"]); + ... + } + }; +}) +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) +* [Quartz.NET Project](https://www.quartz-scheduler.net/) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs new file mode 100644 index 0000000000..6869be5a69 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -0,0 +1,51 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.Quartz; +using OpenTelemetry.Instrumentation.Quartz.Implementation; + +// ReSharper disable once CheckNamespace +namespace OpenTelemetry.Trace +{ + /// + /// Extension methods to simplify registering of dependency instrumentation. + /// + public static class TraceProviderBuilderExtensions + { + /// + /// Enables the Quartz.NET Job automatic data collection for Quartz.NET. + /// + /// being configured. + /// Quartz configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddQuartzInstrumentation( + this TracerProviderBuilder builder, + Action configureQuartzInstrumentationOptions = null) + { + var options = new QuartzInstrumentationOptions(); + configureQuartzInstrumentationOptions?.Invoke(options); + + builder.AddInstrumentation(() => new QuartzJobInstrumentation(options)); + builder.AddSource(QuartzDiagnosticListener.ActivitySourceName); + + builder.AddLegacySource(OperationName.Job.Execute); + builder.AddLegacySource(OperationName.Job.Veto); + + return builder; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj new file mode 100644 index 0000000000..aa2b6763b0 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -0,0 +1,26 @@ + + + + Unit test project for OpenTelemetry Quartz.NET instrumentation + net472;netcoreapp3.1 + true + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs new file mode 100644 index 0000000000..90c88e874e --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -0,0 +1,395 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Moq; +using OpenTelemetry.Trace; +using Quartz; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Quartz.Tests +{ + public class QuartzDiagnosticListenerTests + { + private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(125); + + public QuartzDiagnosticListenerTests() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + } + + [Fact] + public async Task Should_Create_Activity() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation() + .AddProcessor(activityProcessor.Object) + .Build(); + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + JobDataMap jobDataMap = new JobDataMap { { "A", "B" } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TestTimeout); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Contains("execute ", activity.DisplayName); + Assert.Equal("Quartz.Job.Execute", activity.OperationName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal("Scheduler", activity.Tags.SingleOrDefault(t => t.Key.Equals("scheduler.name")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("job.group")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("trigger.group")).Value); + } + + [Fact] + public async Task Should_Create_Activity_And_Enrich_When_Enrich() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + var jobDataMapPropertyFetcher = new PropertyFetcher("JobDataMap"); + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + q.Enrich = (a, s, payload) => + { + if (payload is IJobDetail jobDetail) + { + var dataMap = jobDetail.JobDataMap; + if (dataMap.ContainsKey("TestId")) + { + a.SetTag("test.id", dataMap["TestId"]); + } + } + }) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TestTimeout); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Equal("Quartz.Job.Execute", activity.OperationName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal("Scheduler", activity.Tags.SingleOrDefault(t => t.Key.Equals("scheduler.name")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("job.group")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("trigger.group")).Value); + Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); + } + + [Fact] + public async Task Should_Record_Exception_When_Record_Exception_Enabled() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + q.RecordException = true) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TimeSpan.FromSeconds(1)); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Equal("exception", activity.Events.First().Name); + Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); + Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); + } + + [Fact] + public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enrich() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + { + q.RecordException = true; + q.Enrich = (a, s, p) => + { + if (p is IJobDetail jobDetail) + { + var dataMap = jobDetail.JobDataMap; + if (dataMap.ContainsKey("TestId")) + { + a.SetTag("test.id", dataMap["TestId"]); + } + } + }; + }) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TimeSpan.FromSeconds(1)); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); + Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); + Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); + } + + [Fact] + public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + { + q.RecordException = true; + q.Enrich = (a, s, p) => + { + if (s.Equals("OnException")) + { + throw new Exception("Enrich Exception"); + } + }; + }) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TimeSpan.FromSeconds(1)); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Equal("exception", activity.Events.First().Name); + Assert.Equal("Quartz.JobExecutionException", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionType)).Value); + Assert.Equal("Catch me if you can!", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionMessage)).Value); + } + + [Fact] + public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + { + q.TracedOperations = new HashSet(); + }) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TestTimeout); + + await scheduler.Shutdown(true); + + // Assert + var activities = activityProcessor.Invocations.SelectMany(i => i.Arguments.OfType()) + .Where(a => a.IsAllDataRequested); + Assert.Empty(activities); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs new file mode 100644 index 0000000000..d5631d41e5 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Quartz; + +namespace OpenTelemetry.Instrumentation.Quartz.Tests +{ + public class TestJob : IJob + { + public Task Execute(IJobExecutionContext context) + { + try + { + List jobExecTimestamps = (List)context.Scheduler.Context.Get("DATESTAMPS"); + Barrier barrier = (Barrier)context.Scheduler.Context.Get("BARRIER"); + + jobExecTimestamps.Add(DateTime.UtcNow); + + barrier.SignalAndWait(TimeSpan.FromSeconds(125)); + return Task.CompletedTask; + } + catch (Exception e) + { + Console.Write(e); + } + + return Task.CompletedTask; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs new file mode 100644 index 0000000000..b46c3c9c7f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Threading.Tasks; +using Quartz; + +namespace OpenTelemetry.Instrumentation.Quartz.Tests +{ + public class TestJobExecutionExceptionJob : IJob + { + public Task Execute(IJobExecutionContext context) + { + throw new JobExecutionException("Catch me if you can!"); + } + } +} From 69cd737a8794b689d7424f24e4ab498004c26e56 Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Wed, 9 Mar 2022 18:38:04 +0100 Subject: [PATCH 0020/1499] Add cpu time (#214) --- .../RuntimeMetrics.cs | 6 +++ .../RuntimeMetricsOptions.cs | 11 ++++ .../RuntimeMetricsOptionsTests.cs | 25 +++++++++ .../RuntimeMetricsTests.cs | 51 ++++++++++++++++++- 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs index 2d3acd51e1..4510529aab 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -15,6 +15,7 @@ // using System; +using System.Diagnostics; using System.Diagnostics.Metrics; using System.Reflection; using System.Threading; @@ -81,6 +82,11 @@ public RuntimeMetrics(RuntimeMetricsOptions options) this.meter.CreateObservableGauge($"{metricPrefix}memory.usage", () => (double)(Environment.WorkingSet / 1_000_000), "MB", "Working Set"); } + if (options.IsProcessEnabled) + { + this.meter.CreateObservableCounter("process.cpu.time", () => Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds, "s", "Total processor time of this process"); + } + if (options.IsAssembliesEnabled) { this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs index be87760660..541a75b665 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -45,6 +45,11 @@ public class RuntimeMetricsOptions /// public bool? MemoryEnabled { get; set; } + /// + /// Gets or sets a value indicating whether process metrics should be collected. + /// + public bool? ProcessEnabled { get; set; } + /// /// Gets or sets a value indicating whether assembly metrics should be collected. /// @@ -61,6 +66,7 @@ public class RuntimeMetricsOptions && this.ThreadingEnabled == null #endif && this.MemoryEnabled == null + && this.ProcessEnabled == null && this.AssembliesEnabled == null; /// @@ -87,6 +93,11 @@ public class RuntimeMetricsOptions /// internal bool IsMemoryEnabled => this.MemoryEnabled == true || this.IsAllEnabled; + /// + /// Gets a value indicating whether process metrics is enabled. + /// + internal bool IsProcessEnabled => this.ProcessEnabled == true || this.IsAllEnabled; + /// /// Gets a value indicating whether assembly metrics is enabled. /// diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs index e8942649a7..6d729385af 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -33,6 +33,7 @@ public void Enable_All_If_Nothing_Was_Defined() Assert.True(options.IsThreadingEnabled); #endif Assert.True(options.IsMemoryEnabled); + Assert.True(options.IsProcessEnabled); Assert.True(options.IsAssembliesEnabled); Assert.True(options.IsAllEnabled); } @@ -50,6 +51,7 @@ public void Enable_Gc_Only() Assert.False(options.IsThreadingEnabled); #endif Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -64,6 +66,7 @@ public void Enable_Jit_Only() Assert.True(options.IsJitEnabled); Assert.False(options.IsThreadingEnabled); Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -81,6 +84,7 @@ public void Enable_Threading_Only() #endif Assert.True(options.IsThreadingEnabled); Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -99,6 +103,25 @@ public void Enable_Memory_Only() Assert.False(options.IsThreadingEnabled); #endif Assert.True(options.IsMemoryEnabled); + Assert.False(options.IsProcessEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + + [Fact] + public void Enable_Process_Only() + { + var options = new RuntimeMetricsOptions { ProcessEnabled = true }; + + Assert.False(options.IsGcEnabled); +#if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); +#endif +#if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); +#endif + Assert.False(options.IsMemoryEnabled); + Assert.True(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -116,6 +139,7 @@ public void Enable_Assemblies_Only() Assert.False(options.IsThreadingEnabled); #endif Assert.False(options.IsMemoryEnabled); + Assert.False(options.IsProcessEnabled); Assert.True(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -133,6 +157,7 @@ public void Enable_Multiple() Assert.False(options.IsThreadingEnabled); #endif Assert.True(options.IsMemoryEnabled); + Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index fad59ac08a..d7b5a2cc78 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -16,8 +16,6 @@ using System; using System.Collections.Generic; -using System.Threading.Tasks; -using OpenTelemetry.Exporter; using OpenTelemetry.Metrics; using Xunit; @@ -40,6 +38,7 @@ public void RuntimeMetricsAreCaptured() options.ThreadingEnabled = true; #endif options.MemoryEnabled = true; + options.ProcessEnabled = true; #if NET6_0_OR_GREATER options.JitEnabled = true; @@ -54,5 +53,53 @@ public void RuntimeMetricsAreCaptured() var metric1 = exportedItems[0]; Assert.StartsWith(MetricPrefix, metric1.Name); } + + [Fact] + public void CpuTimeMetricAreCaptured() + { + var exportedItems = new List(); + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeMetrics(options => + { + options.ProcessEnabled = true; + }) + .AddInMemoryExporter(exportedItems) + .Build(); + + // simple CPU spinning + var spinDuration = DateTime.UtcNow.AddMilliseconds(10); + while (DateTime.UtcNow < spinDuration) + { + } + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + Assert.True(exportedItems.Count > 0); + + var sumReceived = GetDoubleSum(exportedItems); + Assert.True(sumReceived > 0); + } + + private static double GetDoubleSum(List metrics) + { + double sum = 0; + foreach (var metric in metrics) + { + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumDouble(); + } + else + { + sum += metricPoint.GetGaugeLastValueDouble(); + } + } + } + + return sum; + } } } From 558d8685cf2f9cb0de297db6bff86af6cb33231e Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Wed, 9 Mar 2022 22:49:58 +0100 Subject: [PATCH 0021/1499] Provide cpu time with state tags (#217) --- .../RuntimeMetrics.cs | 13 ++++++++++++- .../RuntimeMetricsTests.cs | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs index 4510529aab..48c89cdb37 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -15,6 +15,7 @@ // using System; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Metrics; using System.Reflection; @@ -84,7 +85,7 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsProcessEnabled) { - this.meter.CreateObservableCounter("process.cpu.time", () => Process.GetCurrentProcess().TotalProcessorTime.TotalSeconds, "s", "Total processor time of this process"); + this.meter.CreateObservableCounter("process.cpu.time", this.GetProcessorTimes, "s", "Processor time of this process"); } if (options.IsAssembliesEnabled) @@ -106,5 +107,15 @@ private static double GetFragmentation() return gcInfo.HeapSizeBytes != 0 ? gcInfo.FragmentedBytes * 100d / gcInfo.HeapSizeBytes : 0; } #endif + + private IEnumerable> GetProcessorTimes() + { + var process = Process.GetCurrentProcess(); + return new[] + { + new Measurement(process.UserProcessorTime.TotalSeconds, new KeyValuePair("state", "user")), + new Measurement(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("state", "system")), + }; + } } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index d7b5a2cc78..70cefe430c 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -75,7 +75,9 @@ public void CpuTimeMetricAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count > 0); + Assert.Single(exportedItems); + var metric1 = exportedItems[0]; + Assert.Equal("process.cpu.time", metric1.Name); var sumReceived = GetDoubleSum(exportedItems); Assert.True(sumReceived > 0); From 674ab7646029eaa007aa0bcafaada7e01b76b093 Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Wed, 9 Mar 2022 23:07:16 +0100 Subject: [PATCH 0022/1499] Change unit to UCUM (#220) Co-authored-by: Cijo Thomas --- .../RuntimeMetrics.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs index 48c89cdb37..bc1467f7b6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -44,24 +44,24 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsGcEnabled) { - this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "B", "GC Heap Size"); + this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "By", "GC Heap Size"); this.meter.CreateObservableGauge($"{metricPrefix}gen_0-gc.count", () => GC.CollectionCount(0), description: "Gen 0 GC Count"); this.meter.CreateObservableGauge($"{metricPrefix}gen_1-gc.count", () => GC.CollectionCount(1), description: "Gen 1 GC Count"); this.meter.CreateObservableGauge($"{metricPrefix}gen_2-gc.count", () => GC.CollectionCount(2), description: "Gen 2 GC Count"); #if NETCOREAPP3_1_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}alloc.rate", () => GC.GetTotalAllocatedBytes(), "B", "Allocation Rate"); + this.meter.CreateObservableCounter($"{metricPrefix}alloc.rate", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate"); this.meter.CreateObservableCounter($"{metricPrefix}gc.fragmentation", GetFragmentation, description: "GC Fragmentation"); #endif #if NET6_0_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}gc.committed", () => (double)(GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000), "MB", description: "GC Committed Bytes"); + this.meter.CreateObservableCounter($"{metricPrefix}gc.committed", () => (double)(GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000), "Mi", description: "GC Committed Bytes"); #endif } #if NET6_0_OR_GREATER if (options.IsJitEnabled) { - this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "B", description: "IL Bytes Jitted"); + this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "By", description: "IL Bytes Jitted"); this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted"); this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().TotalMilliseconds, "ms", description: "Time spent in JIT"); } From d17007129ce4a3ec43290991c6f88bc9520d1e59 Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Thu, 10 Mar 2022 06:12:33 +0100 Subject: [PATCH 0023/1499] Move memory metric to process metrics (#219) * Move memory metric to process metrics * Fix whitespace --- .../RuntimeMetrics.cs | 7 ++--- .../RuntimeMetricsOptions.cs | 11 ------- .../RuntimeMetricsOptionsTests.cs | 29 ++----------------- .../RuntimeMetricsTests.cs | 29 +++++++++---------- 4 files changed, 17 insertions(+), 59 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs index bc1467f7b6..5c729e0288 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -78,14 +78,11 @@ public RuntimeMetrics(RuntimeMetricsOptions options) } #endif - if (options.IsMemoryEnabled) - { - this.meter.CreateObservableGauge($"{metricPrefix}memory.usage", () => (double)(Environment.WorkingSet / 1_000_000), "MB", "Working Set"); - } - if (options.IsProcessEnabled) { this.meter.CreateObservableCounter("process.cpu.time", this.GetProcessorTimes, "s", "Processor time of this process"); + this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use"); + this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory"); } if (options.IsAssembliesEnabled) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs index 541a75b665..730e4e2b98 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -40,11 +40,6 @@ public class RuntimeMetricsOptions public bool? ThreadingEnabled { get; set; } #endif - /// - /// Gets or sets a value indicating whether memory metrics should be collected. - /// - public bool? MemoryEnabled { get; set; } - /// /// Gets or sets a value indicating whether process metrics should be collected. /// @@ -65,7 +60,6 @@ public class RuntimeMetricsOptions #if NETCOREAPP3_1_OR_GREATER && this.ThreadingEnabled == null #endif - && this.MemoryEnabled == null && this.ProcessEnabled == null && this.AssembliesEnabled == null; @@ -88,11 +82,6 @@ public class RuntimeMetricsOptions internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; #endif - /// - /// Gets a value indicating whether memory metrics is enabled. - /// - internal bool IsMemoryEnabled => this.MemoryEnabled == true || this.IsAllEnabled; - /// /// Gets a value indicating whether process metrics is enabled. /// diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs index 6d729385af..c4eeda1777 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -32,7 +32,6 @@ public void Enable_All_If_Nothing_Was_Defined() #if NETCOREAPP3_1_OR_GREATER Assert.True(options.IsThreadingEnabled); #endif - Assert.True(options.IsMemoryEnabled); Assert.True(options.IsProcessEnabled); Assert.True(options.IsAssembliesEnabled); Assert.True(options.IsAllEnabled); @@ -50,7 +49,6 @@ public void Enable_Gc_Only() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.False(options.IsMemoryEnabled); Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); @@ -65,7 +63,6 @@ public void Enable_Jit_Only() Assert.False(options.IsGcEnabled); Assert.True(options.IsJitEnabled); Assert.False(options.IsThreadingEnabled); - Assert.False(options.IsMemoryEnabled); Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); @@ -83,31 +80,12 @@ public void Enable_Threading_Only() Assert.False(options.IsJitEnabled); #endif Assert.True(options.IsThreadingEnabled); - Assert.False(options.IsMemoryEnabled); Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } #endif - [Fact] - public void Enable_Memory_Only() - { - var options = new RuntimeMetricsOptions { MemoryEnabled = true }; - - Assert.False(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); -#endif -#if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); -#endif - Assert.True(options.IsMemoryEnabled); - Assert.False(options.IsProcessEnabled); - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } - [Fact] public void Enable_Process_Only() { @@ -120,7 +98,6 @@ public void Enable_Process_Only() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.False(options.IsMemoryEnabled); Assert.True(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); @@ -138,7 +115,6 @@ public void Enable_Assemblies_Only() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.False(options.IsMemoryEnabled); Assert.False(options.IsProcessEnabled); Assert.True(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); @@ -147,7 +123,7 @@ public void Enable_Assemblies_Only() [Fact] public void Enable_Multiple() { - var options = new RuntimeMetricsOptions { GcEnabled = true, MemoryEnabled = true }; + var options = new RuntimeMetricsOptions { GcEnabled = true, ProcessEnabled = true }; Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -156,8 +132,7 @@ public void Enable_Multiple() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.True(options.IsMemoryEnabled); - Assert.False(options.IsProcessEnabled); + Assert.True(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 70cefe430c..5caaeebeb1 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenTelemetry.Metrics; using Xunit; @@ -37,7 +38,6 @@ public void RuntimeMetricsAreCaptured() #if NETCOREAPP3_1_OR_GREATER options.ThreadingEnabled = true; #endif - options.MemoryEnabled = true; options.ProcessEnabled = true; #if NET6_0_OR_GREATER @@ -75,29 +75,26 @@ public void CpuTimeMetricAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Single(exportedItems); - var metric1 = exportedItems[0]; - Assert.Equal("process.cpu.time", metric1.Name); + Assert.Equal(3, exportedItems.Count); - var sumReceived = GetDoubleSum(exportedItems); + var cpuTimeMetric = exportedItems.First(i => i.Name == "process.cpu.time"); + var sumReceived = GetDoubleSum(cpuTimeMetric); Assert.True(sumReceived > 0); } - private static double GetDoubleSum(List metrics) + private static double GetDoubleSum(Metric metric) { double sum = 0; - foreach (var metric in metrics) + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumDouble(); + } + else { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumDouble(); - } - else - { - sum += metricPoint.GetGaugeLastValueDouble(); - } + sum += metricPoint.GetGaugeLastValueDouble(); } } From c651aa589f3270bc1c10e9263a8d6ce8ec6ac15b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=A3o=20Ribeiro?= Date: Thu, 10 Mar 2022 17:16:43 +0000 Subject: [PATCH 0024/1499] Include an option to hide dbstatement tag in ElasticSearch (#203) --- opentelemetry-dotnet-contrib.sln | 4 +- ...asticsearchClientInstrumentationOptions.cs | 6 ++ ...searchRequestPipelineDiagnosticListener.cs | 2 +- .../ElasticsearchClientTests.cs | 70 +++++++++++++++++++ 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f09288625a..9e7ed6e01b 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30204.135 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}" EndProject diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index 8ee329b412..625af65013 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -34,6 +34,12 @@ public class ElasticsearchClientInstrumentationOptions /// public bool ParseAndFormatRequest { get; set; } = false; + /// + /// Gets or sets a value indicating whether or not the OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient + /// should add the request information as db.statement attribute tag. Default value: True. + /// + public bool SetDbStatementForRequest { get; set; } = true; + /// /// Gets or sets an action to enrich an Activity. /// diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index b64fef286d..33accd4135 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -143,7 +143,7 @@ public override void OnStopActivity(Activity activity, object payload) } var debugInformation = this.debugInformationFetcher.Fetch(payload); - if (debugInformation != null) + if (debugInformation != null && this.options.SetDbStatementForRequest) { activity.SetTag(SemanticConventions.AttributeDbStatement, this.ParseAndFormatRequest(activity, debugInformation)); } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index b30ff65186..ab1ae1958e 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -797,5 +797,75 @@ public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecis Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnStart))); Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnEnd))); } + + [Fact] + public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); + + var parent = new Activity("parent").Start(); + + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation(o => o.SetDbStatementForRequest = false) + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) + { + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } + + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); + + var searchActivity = activities[0]; + + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + + [Fact] + public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDefaultValue() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); + + var parent = new Activity("parent").Start(); + + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) + { + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } + + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); + + var searchActivity = activities[0]; + + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.NotNull(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } } } From 51e335e0847b2679ae3081ac70fe2b38948b99d8 Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Thu, 10 Mar 2022 19:03:45 +0100 Subject: [PATCH 0025/1499] Add process.cpu.count (#218) * Add process.cpu.count * Change to gauge * Update tests * Add link to PR Co-authored-by: Cijo Thomas --- .../RuntimeMetrics.cs | 3 ++ .../RuntimeMetricsTests.cs | 32 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs index 5c729e0288..c5ea2421c5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs @@ -81,6 +81,9 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsProcessEnabled) { this.meter.CreateObservableCounter("process.cpu.time", this.GetProcessorTimes, "s", "Processor time of this process"); + + // Not yet official: https://github.com/open-telemetry/opentelemetry-specification/pull/2392 + this.meter.CreateObservableGauge("process.cpu.count", () => Environment.ProcessorCount, description: "The number of available logical CPUs"); this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use"); this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory"); } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 5caaeebeb1..009ddf196c 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -55,7 +55,7 @@ public void RuntimeMetricsAreCaptured() } [Fact] - public void CpuTimeMetricAreCaptured() + public void ProcessMetricsAreCaptured() { var exportedItems = new List(); @@ -75,11 +75,20 @@ public void CpuTimeMetricAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(3, exportedItems.Count); + Assert.Equal(4, exportedItems.Count); var cpuTimeMetric = exportedItems.First(i => i.Name == "process.cpu.time"); var sumReceived = GetDoubleSum(cpuTimeMetric); Assert.True(sumReceived > 0); + + var cpuCountMetric = exportedItems.First(i => i.Name == "process.cpu.count"); + Assert.Equal(Environment.ProcessorCount, (int)GetLongSum(cpuCountMetric)); + + var memoryMetric = exportedItems.First(i => i.Name == "process.memory.usage"); + Assert.True(GetLongSum(memoryMetric) > 0); + + var virtualMemoryMetric = exportedItems.First(i => i.Name == "process.memory.virtual"); + Assert.True(GetLongSum(virtualMemoryMetric) > 0); } private static double GetDoubleSum(Metric metric) @@ -100,5 +109,24 @@ private static double GetDoubleSum(Metric metric) return sum; } + + private static double GetLongSum(Metric metric) + { + double sum = 0; + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumLong(); + } + else + { + sum += metricPoint.GetGaugeLastValueLong(); + } + } + + return sum; + } } } From 53d946623d53c7ace3953dc8614408b180b2cada Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 10 Mar 2022 21:17:19 -0800 Subject: [PATCH 0026/1499] Add separate workflows for Windows and Linux (#224) * Add separate workflows for Windows and Linux * Update linux workflow --- .github/workflows/linux-ci.yml | 31 +++++++++++++++++++++++++++++++ .github/workflows/windows-ci.yml | 31 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 .github/workflows/linux-ci.yml create mode 100644 .github/workflows/windows-ci.yml diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml new file mode 100644 index 0000000000..f6d29654d2 --- /dev/null +++ b/.github/workflows/linux-ci.yml @@ -0,0 +1,31 @@ +name: Linux + +on: + push: + branches: [ main ] + paths-ignore: + - '**.md' + pull_request: + branches: [ main ] + paths-ignore: + - '**.md' + +jobs: + build-test: + runs-on: ubuntu-latest + + strategy: + matrix: + version: [netcoreapp3.1,net5.0,net6.0] + + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: dotnet build --configuration Release --no-restore + + - name: Test ${{ matrix.version }} + run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml new file mode 100644 index 0000000000..fbf928f758 --- /dev/null +++ b/.github/workflows/windows-ci.yml @@ -0,0 +1,31 @@ +name: Windows + +on: + push: + branches: [ main ] + paths-ignore: + - '**.md' + pull_request: + branches: [ main ] + paths-ignore: + - '**.md' + +jobs: + build-test: + runs-on: windows-latest + + strategy: + matrix: + version: [net461,netcoreapp3.1,net5.0,net6.0] + + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run: dotnet restore + + - name: Build + run: dotnet build --configuration Release --no-restore + + - name: Test ${{ matrix.version }} + run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" From 6ee39146f8c0d93aa99d3d7c6c4f261cc4e720b1 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 11 Mar 2022 06:35:47 -0800 Subject: [PATCH 0027/1499] Update workflows (#227) --- .github/workflows/dotnet-format.yml | 9 +++++++-- .github/workflows/markdownlint.yml | 4 ++++ .github/workflows/sanitycheck.yml | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index f9f2e38b5b..a546f81676 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -1,6 +1,11 @@ name: dotnet format on: + push: + branches: [ main ] + paths: + - '**.cs' + - '.editorconfig' pull_request: branches: [ main ] paths: @@ -15,10 +20,10 @@ jobs: - name: check out code uses: actions/checkout@v2 - - name: Setup .NET Core 3.1 + - name: Setup .NET Core 6.0 uses: actions/setup-dotnet@v1 with: - dotnet-version: 3.1.x + dotnet-version: 6.0.x - name: Install format tool run: dotnet tool install -g dotnet-format diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 77c8957b46..1e56c15478 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -1,6 +1,10 @@ name: markdownlint on: + push: + branches: [ main ] + paths: + - '**.md' pull_request: branches: [ main ] paths: diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 92fda06a6a..7de88aeb7f 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -1,6 +1,8 @@ name: sanitycheck on: + push: + branches: [ main ] pull_request: branches: [ main ] From 25b53893cc9bb3c70c352c0e4c0d6c8c6dbbd512 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 11 Mar 2022 06:37:14 -0800 Subject: [PATCH 0028/1499] Update build badge on main README (#226) --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4b8bade25a..60dc04e893 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@ # OpenTelemetry .NET Contrib [![Slack](https://img.shields.io/badge/slack-@cncf/otel/dotnet-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01N3BC2W7Q) -[![Build -Status](https://action-badges.now.sh/open-telemetry/opentelemetry-dotnet-contrib)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions) +[![Linux](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/linux-ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/linux-ci.yml) +[![Windows](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/windows-ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/windows-ci.yml) This repository contains set of components extending functionality of the OpenTelemetry SDK. Instrumentation libraries, exporters, and other components can find their home here. -Packages in this repository are prefixed with `OpenTelemetry.Contrib` to highlight -that they are different from the packages produced by the primary .NET SDK repository. +Packages in this repository are prefixed with `OpenTelemetry.Contrib` to +highlight that they are different from the packages produced by the primary .NET +SDK repository. ## Contributing From 55b5f51384419e5ed468002d1adebc87572dc38f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 11 Mar 2022 06:52:52 -0800 Subject: [PATCH 0029/1499] Update GitHub workflows (#225) Co-authored-by: Cijo Thomas --- opentelemetry-dotnet-contrib.sln | 45 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 9e7ed6e01b..ed8891f8b4 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -27,6 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml + .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml @@ -42,8 +43,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\package-Preview.yml = .github\workflows\package-Preview.yml - .github\workflows\pr_build.yml = .github\workflows\pr_build.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml + .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE-3FA8-4FE0-823A-FD365EAC78AF}" @@ -272,30 +273,30 @@ Global {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.Build.0 = Debug|Any CPU {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.ActiveCfg = Release|Any CPU {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.Build.0 = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.Build.0 = Release|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.Build.0 = Release|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.Build.0 = Release|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Release|Any CPU.Build.0 = Release|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.Build.0 = Release|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU {9C2D6D1A-8580-4527-B718-E206D0690635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9C2D6D1A-8580-4527-B718-E206D0690635}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C2D6D1A-8580-4527-B718-E206D0690635}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -371,8 +372,8 @@ Global {B978939B-278C-43A3-AD12-32EA9BBD27D0} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D2C68560-C252-41A9-B742-2CEB7D760E0F} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {4172D671-3AAC-443F-9EB0-A6608B154AF0} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {9C2D6D1A-8580-4527-B718-E206D0690635} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {530255C1-D130-4B43-981D-911E54F7C787} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} From 281e7536bd331bc74aa4877a88ec410f60339a3c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 11 Mar 2022 11:01:14 -0800 Subject: [PATCH 0030/1499] Delete old build workflow (#230) --- .github/workflows/pr_build.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .github/workflows/pr_build.yml diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml deleted file mode 100644 index ed3e8af464..0000000000 --- a/.github/workflows/pr_build.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: PR build and test - -on: - pull_request: - branches: [ main ] - paths-ignore: - - '**.md' - -jobs: - build-test: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - os: [windows-latest,ubuntu-latest] - version: [net461,netcoreapp3.1,net5.0,net6.0] - exclude: - - os: ubuntu-latest - version: net461 - - steps: - - uses: actions/checkout@v2 - - - name: Install dependencies - run: dotnet restore - - - name: Build - run: dotnet build --configuration Release --no-restore - - - name: Test - run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll \ No newline at end of file From 0d7542f09d1f5d0ab7bfb3ea3aa39584beaa9567 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 14 Mar 2022 15:12:17 -0700 Subject: [PATCH 0031/1499] Rename Quartz Instrumentation related files (#232) --- .github/workflows/package-Instrumentation.Quartz.yml | 4 ++-- CODEOWNERS | 4 ++-- src/OpenTelemetry.Instrumentation.Quartz/README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 759dac8adf..cbf69582a2 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.Quartz +name: Pack OpenTelemetry.Instrumentation.Quartz on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.Quartz + PROJECT: OpenTelemetry.Instrumentation.Quartz strategy: matrix: diff --git a/CODEOWNERS b/CODEOWNERS index 3d742ed04d..a69525d265 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -14,8 +14,8 @@ src/OpenTelemetry.Contrib.Instrumentation.Owin/ @ope src/OpenTelemetry.Contrib.Instrumentation.Wcf/ @open-telemetry/dotnet-contrib-approvers @codeblanch src/OpenTelemetry.Contrib.Instrumentation.MySqlData/ @open-telemetry/dotnet-contrib-approvers @moonheart src/OpenTelemetry.Contrib.Extensions.PersistentStorage/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar -src/OpenTelemetry.Contrib.Instrumentation.Quartz/ @open-telemetry/dotnet-contrib-approvers @maldago src/OpenTelemetry.Contrib.Preview/ @open-telemetry/dotnet-contrib-approvers @codeblanch +src/OpenTelemetry.Instrumentation.Quartz/ @open-telemetry/dotnet-contrib-approvers @maldago test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/ @open-telemetry/dotnet-contrib-approvers @SergeyKanzhelev test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/ @open-telemetry/dotnet-contrib-approvers @srprash @lupengamzn @@ -27,5 +27,5 @@ test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/ @ope test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/ @open-telemetry/dotnet-contrib-approvers @moonheart test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar -src/OpenTelemetry.Contrib.Instrumentation.Quartz.Tests/ @open-telemetry/dotnet-contrib-approvers @maldago test/OpenTelemetry.Contrib.Preview.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch +test/OpenTelemetry.Instrumentation.Quartz.Tests/ @open-telemetry/dotnet-contrib-approvers @maldago diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index d2841acb0b..0acc210865 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -15,7 +15,7 @@ more information can be found ```shell dotnet add package OpenTelemetry.Extensions.Hosting -dotnet add package OpenTelemetry.Contrib.Instrumentation.Quartz +dotnet add package OpenTelemetry.Instrumentation.Quartz ``` ## Configuration From 64c01d06d2cdb6af8ce2091fd87f6f9f325893c7 Mon Sep 17 00:00:00 2001 From: sailorgallifrey <76499312+sailorgallifrey@users.noreply.github.com> Date: Mon, 14 Mar 2022 20:29:50 -0500 Subject: [PATCH 0032/1499] Refactor code ownership to use the open-telemetry/assign-reviewers-action (#195) * Refactor code ownership to use the open-telemetry/assign-reviewers-action --- .github/code_owners.yml | 53 ++++++++++++++++++++++++++ .github/workflows/assign-reviewers.yml | 22 +++++++++++ CODEOWNERS | 26 ------------- CONTRIBUTING.md | 2 +- 4 files changed, 76 insertions(+), 27 deletions(-) create mode 100644 .github/code_owners.yml create mode 100644 .github/workflows/assign-reviewers.yml diff --git a/.github/code_owners.yml b/.github/code_owners.yml new file mode 100644 index 0000000000..3c94019ed1 --- /dev/null +++ b/.github/code_owners.yml @@ -0,0 +1,53 @@ +# .github/code_owners.yml + +# Each component identified by its path prefix has a list of users +components: + src/OpenTelemetry.Contrib.Exporter.Stackdriver/: + - SergeyKanzhelev + src/OpenTelemetry.Contrib.Extensions.AWSXRay/: + - srprash + - lupengamzn + src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/: + - ejsmith + src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/: + src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/: + - pcwiese + src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: + - alexvaluyskiy + src/OpenTelemetry.Contrib.Instrumentation.Owin/: + - codeblanch + src/OpenTelemetry.Contrib.Instrumentation.Wcf/: + - codeblanch + src/OpenTelemetry.Contrib.Instrumentation.MySqlData/: + - moonheart + src/OpenTelemetry.Contrib.Extensions.PersistentStorage/: + - vishweshbankwar + src/OpenTelemetry.Contrib.Preview/: + - codeblanch + src/OpenTelemetry.Instrumentation.Quartz/: + - maldago + + test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/: + - SergeyKanzhelev + test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: + - srprash + - lupengamzn + test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/: + - ejsmith + test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCoreTests/: + test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/: + - pcwiese + test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: + - alexvaluyskiy + test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/: + - codeblanch + test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/: + - codeblanch + test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/: + - moonheart + test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/: + - vishweshbankwar + test/OpenTelemetry.Contrib.Preview.Tests/: + - codeblanch + test/OpenTelemetry.Instrumentation.Quartz.Tests/: + - maldago diff --git a/.github/workflows/assign-reviewers.yml b/.github/workflows/assign-reviewers.yml new file mode 100644 index 0000000000..50c3266c5c --- /dev/null +++ b/.github/workflows/assign-reviewers.yml @@ -0,0 +1,22 @@ +name: 'Assign Reviewers' +on: + # pull_request_target is suggested for projects where pull requests will be + # made from forked repositories. If pull_request is used in these cases, + # the github token will not have sufficient permission to update the PR. + pull_request_target: + +jobs: + assign: + runs-on: ubuntu-latest + name: Assign Reviewers + steps: + - uses: open-telemetry/assign-reviewers-action@main + with: + # default: .github/code_owners.yml + config-file: .github/code_owners.yml + # default: ${{ github.token }} + repo-token: ${{ github.token }} + # default: true + assign-users: "true" + # default: true + request-user-reviews: "true" diff --git a/CODEOWNERS b/CODEOWNERS index a69525d265..3d68aa3d7f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -3,29 +3,3 @@ # For anything not explicitly taken by someone else: * @open-telemetry/dotnet-contrib-approvers - -src/OpenTelemetry.Contrib.Exporter.Stackdriver/ @open-telemetry/dotnet-contrib-approvers @SergeyKanzhelev -src/OpenTelemetry.Contrib.Extensions.AWSXRay/ @open-telemetry/dotnet-contrib-approvers @srprash @lupengamzn -src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ @open-telemetry/dotnet-contrib-approvers @ejsmith -src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/ @open-telemetry/dotnet-contrib-approvers -src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ @open-telemetry/dotnet-contrib-approvers @pcwiese -src/OpenTelemetry.Contrib.Instrumentation.MassTransit/ @open-telemetry/dotnet-contrib-approvers @alexvaluyskiy -src/OpenTelemetry.Contrib.Instrumentation.Owin/ @open-telemetry/dotnet-contrib-approvers @codeblanch -src/OpenTelemetry.Contrib.Instrumentation.Wcf/ @open-telemetry/dotnet-contrib-approvers @codeblanch -src/OpenTelemetry.Contrib.Instrumentation.MySqlData/ @open-telemetry/dotnet-contrib-approvers @moonheart -src/OpenTelemetry.Contrib.Extensions.PersistentStorage/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar -src/OpenTelemetry.Contrib.Preview/ @open-telemetry/dotnet-contrib-approvers @codeblanch -src/OpenTelemetry.Instrumentation.Quartz/ @open-telemetry/dotnet-contrib-approvers @maldago - -test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/ @open-telemetry/dotnet-contrib-approvers @SergeyKanzhelev -test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/ @open-telemetry/dotnet-contrib-approvers @srprash @lupengamzn -test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ @open-telemetry/dotnet-contrib-approvers @ejsmith -test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCoreTests/ @open-telemetry/dotnet-contrib-approvers -test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/ @open-telemetry/dotnet-contrib-approvers @pcwiese -test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/ @open-telemetry/dotnet-contrib-approvers @alexvaluyskiy -test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch -test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch -test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/ @open-telemetry/dotnet-contrib-approvers @moonheart -test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/ @open-telemetry/dotnet-contrib-approvers @vishweshbankwar -test/OpenTelemetry.Contrib.Preview.Tests/ @open-telemetry/dotnet-contrib-approvers @codeblanch -test/OpenTelemetry.Instrumentation.Quartz.Tests/ @open-telemetry/dotnet-contrib-approvers @maldago diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c7760bdd07..bc0942b186 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -200,4 +200,4 @@ to be placed in the `.github/workflows/` folder. value to "OpenTelemetry.Contrib.Foo.Bar". * When contributing a new project you are expected to assign yourself to your -project in the [CODEOWNERS](./CODEOWNERS) file +project in the [code_owners](./.github/code_owners.yml) file From 3ffc6dfe561d959964e44d1f16ef9ae434ad513a Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 14 Mar 2022 20:58:17 -0700 Subject: [PATCH 0033/1499] Update assign reviewers workflow (#234) * Update assign reviewers workflow to use `dyladan/component-owners@main` instead of `open-telemetry/assign-reviewers-action@main` --- .github/{code_owners.yml => component_owners.yml} | 2 +- .github/workflows/assign-reviewers.yml | 11 +---------- opentelemetry-dotnet-contrib.sln | 2 ++ 3 files changed, 4 insertions(+), 11 deletions(-) rename .github/{code_owners.yml => component_owners.yml} (96%) diff --git a/.github/code_owners.yml b/.github/component_owners.yml similarity index 96% rename from .github/code_owners.yml rename to .github/component_owners.yml index 3c94019ed1..c9b3d077fa 100644 --- a/.github/code_owners.yml +++ b/.github/component_owners.yml @@ -1,4 +1,4 @@ -# .github/code_owners.yml +# This file is used by .github/workflows/assign-reviewers.yml # Each component identified by its path prefix has a list of users components: diff --git a/.github/workflows/assign-reviewers.yml b/.github/workflows/assign-reviewers.yml index 50c3266c5c..a5110c7031 100644 --- a/.github/workflows/assign-reviewers.yml +++ b/.github/workflows/assign-reviewers.yml @@ -10,13 +10,4 @@ jobs: runs-on: ubuntu-latest name: Assign Reviewers steps: - - uses: open-telemetry/assign-reviewers-action@main - with: - # default: .github/code_owners.yml - config-file: .github/code_owners.yml - # default: ${{ github.token }} - repo-token: ${{ github.token }} - # default: true - assign-users: "true" - # default: true - request-user-reviews: "true" + - uses: dyladan/component-owners@main diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ed8891f8b4..56f9c9791d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -20,10 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A06 ProjectSection(SolutionItems) = preProject .github\codecov.yml = .github\codecov.yml CODEOWNERS = CODEOWNERS + .github\component_owners.yml = .github\component_owners.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" ProjectSection(SolutionItems) = preProject + .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml From 9c2ab967dc3558bd46d83eebff0fc90472e3cd8f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 14 Mar 2022 21:54:05 -0700 Subject: [PATCH 0034/1499] Update Quartz Instrumentation README (#233) --- .../README.md | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 0acc210865..9df515250a 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -1,21 +1,23 @@ # QuartzNET Instrumentation for OpenTelemetry .NET +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) + Automatically instruments the Quartz jobs from [Quartz](https://www.nuget.org/packages/Quartz/). ## Supported Frameworks -QuartzNET Instrumentation is only supported when using -.NET Framework >= `net472` and netstandard >= `netstandard2.0`. -Quartz`net461` support for activity sources has been removed, -more information can be found +QuartzNET Instrumentation is only supported when using .NET Framework >= +`net472` and netstandard >= `netstandard2.0`. Quartz`net461` support for +activity sources has been removed, more information can be found [here](https://www.quartz-scheduler.net/2021/04/07/quartznet-3-3-released/). ## Installation ```shell dotnet add package OpenTelemetry.Extensions.Hosting -dotnet add package OpenTelemetry.Instrumentation.Quartz +dotnet add package --prerelease OpenTelemetry.Instrumentation.Quartz ``` ## Configuration @@ -67,19 +69,20 @@ x.AddQuartzInstrumentation( })); ``` -For full operation list please see: [OperationName](../OpenTelemetry.Instrumentation.Quartz/Implementation/OperationName.cs). +For full operation list please see: +[OperationName](../OpenTelemetry.Instrumentation.Quartz/Implementation/OperationName.cs). All operations are enabled by default. ## Enrich -This option allows one to enrich the activity with additional information -from the raw `JobDetail` object. The `Enrich` action is -called only when `activity.IsAllDataRequested` is `true`. It contains the -activity itself (which can be enriched), the name of the event, and the -actual raw object. +This option allows one to enrich the activity with additional information from +the raw `JobDetail` object. The `Enrich` action is called only when +`activity.IsAllDataRequested` is `true`. It contains the activity itself (which +can be enriched), the name of the event, and the actual raw object. -For event names "OnStartActivity", "OnStopActivity", the actual object will be `IJobDetail`. +For event names "OnStartActivity", "OnStopActivity", the actual object will be +`IJobDetail`. For event name "OnException", the actual object will be the exception thrown From 349b33fbc23eeebbcb6f8d7b83e440ecd9351f45 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 15 Mar 2022 12:02:46 -0700 Subject: [PATCH 0035/1499] Remove EntityFramework Instrumentation entry from component_owners.yml (#235) --- .github/component_owners.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index c9b3d077fa..0b550e6ecf 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -9,7 +9,6 @@ components: - lupengamzn src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/: - ejsmith - src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/: src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/: - pcwiese src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: @@ -34,7 +33,6 @@ components: - lupengamzn test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/: - ejsmith - test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCoreTests/: test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/: - pcwiese test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: From 51128b0b4a4e19f3690dfdbb02cd26c9707640d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 16 Mar 2022 16:18:27 +0100 Subject: [PATCH 0036/1499] allow long lines for tables and code blocks (#238) --- .markdownlint.yaml | 7 +++++++ src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 .markdownlint.yaml diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000000..30672f8e7f --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,7 @@ +# Default state for all rules +default: true + +# allow long lines for tables and code blocks +MD013: + code_blocks: false + tables: false diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md index fa74a3cd4f..2f865516d5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md @@ -52,7 +52,6 @@ using var openTelemetry = Sdk.CreateTracerProviderBuilder() Add the `IClientMessageInspector` instrumentation via a behavior extension on the clients you want to instrument: - ```xml @@ -82,7 +81,6 @@ the clients you want to instrument: ``` - Example project available in [examples/wcf/client-netframework](../../examples/wcf/client-netframework/) @@ -109,7 +107,6 @@ To add the `IDispatchMessageInspector` instrumentation to select endpoints of a service, use the endpoint behavior extension on the service endpoints you want to instrument: - ```xml @@ -146,7 +143,6 @@ to instrument: ``` - Example project available in [examples/wcf/server-netframework](../../examples/wcf/server-netframework/) @@ -158,7 +154,6 @@ To add the `IDispatchMessageInspector` instrumentation for all endpoints of a service, use the service behavior extension on the services you want to instrument: - ```xml @@ -195,7 +190,6 @@ instrument: ``` - ## WCF Programmatic Configuration Server and/or Client (.NET Framework + .NET Core) From cd94736a3b3485026955f14fc509f735e136983e Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 16 Mar 2022 17:17:30 -0700 Subject: [PATCH 0037/1499] Remove contrib from Stackdriver (#223) * Remove contrib from Stackdriver --- .github/workflows/package-Exporter.Stackdriver.yml | 4 ++-- opentelemetry-dotnet-contrib.sln | 2 +- .../CHANGELOG.md | 8 ++++++++ ...r.csproj => OpenTelemetry.Exporter.Stackdriver.csproj} | 0 ...penTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) rename src/OpenTelemetry.Contrib.Exporter.Stackdriver/{OpenTelemetry.Contrib.Exporter.Stackdriver.csproj => OpenTelemetry.Exporter.Stackdriver.csproj} (100%) diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index 9910619572..b89615c73c 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Exporter.Stackdriver +name: Pack OpenTelemetry.Exporter.Stackdriver on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Exporter.Stackdriver + PROJECT: OpenTelemetry.Exporter.Stackdriver strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 56f9c9791d..3842e1231e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -75,7 +75,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-2 test\Directory.Build.targets = test\Directory.Build.targets EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver", "src\OpenTelemetry.Contrib.Exporter.Stackdriver\OpenTelemetry.Contrib.Exporter.Stackdriver.csproj", "{BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Contrib.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj", "{09525C6C-68B7-405E-B476-23E64D91C11B}" EndProject diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md index 32e5bc37db..d55109e9a5 100644 --- a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +* Going forward the NuGet package will be + [`OpenTelemetry.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver). + Older versions will remain at + [`OpenTelemetry.Contrib.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Exporter.Stackdriver). + [(#223)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/223) + ## 1.0.0-beta1 * Update OTel SDK package version to 1.1.0 diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/OpenTelemetry.Contrib.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/OpenTelemetry.Contrib.Exporter.Stackdriver.csproj rename to src/OpenTelemetry.Contrib.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj index 071cb1d186..16161b9f54 100644 --- a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj @@ -12,7 +12,7 @@ - + From a590a2d88748eb7152799a8fcadebc37cc233d1d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 16 Mar 2022 17:18:56 -0700 Subject: [PATCH 0038/1499] Update CONTRIBUTING.md (#239) * Update CONTRIBUTING.md --- CONTRIBUTING.md | 90 +++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc0942b186..1a9746fc6b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,20 +35,22 @@ 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 Core 3.1+ +* .NET 6.0+ + +Please note that individual project requirements might vary. ### Linux or MacOS * Visual Studio for Mac or Visual Studio Code Mono might be required by your IDE but is not required by this project. This is -because unit tests targeting .NET Framework (i.e: `net46`) are disabled outside -of Windows. +because unit tests targeting .NET Framework (`net452`, `net46`, `net461` etc.) +are disabled outside of Windows. ### Windows -* Visual Studio 2017+ or Visual Studio Code -* .NET Framework 4.6+ +* Visual Studio 2022+ or Visual Studio Code +* .NET Framework 4.6.1+ ## Pull Requests @@ -110,13 +112,17 @@ Open a pull request against the main `opentelemetry-dotnet-contrib` 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 CI is clear. +* 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. ### How to Get PRs Merged A PR is considered to be **ready to merge** when: * It has received approval from - [Approvers](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver). + [Approvers](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver) / [Maintainers](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer). * Major feedbacks are resolved. @@ -131,8 +137,8 @@ and the new feature doesn't fit it. ### How to request for release of package -Submit a PR with `CHANGELOG.md` file reflecting the version to be released. Also, -tag the maintainers of this repository who can release the package. +Submit a PR with `CHANGELOG.md` file reflecting the version to be released. +Also, tag the maintainers of this repository who can release the package. ## Style Guide @@ -148,36 +154,33 @@ build. Breaking the rules will result in a build failure. ## Contributing a new project -This repo is a great place to contribute a new instrumentation, exporter or -any kind of extension. Please refer to -[this page](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#extending-the-opentelemetry-net-sdk) -for help writing your component. -Although the projects within this repo share some -properties and configurations, they are built and released independently. +This repo is a great place to contribute a new instrumentation, exporter or any +kind of extension. Please refer to [this +page](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#extending-the-opentelemetry-net-sdk) +for help writing your component. Although the projects within this repo share +some properties and configurations, they are built and released independently. So if you are creating a new project within `/src` and corresponding test -project within `/test`, here are a few things you should do to ensure that -your project is automatically built and shipped through CI. - -* Based on what your project is, you may need to depend on the -[OpenTelemetry SDK](https://www.nuget.org/packages/OpenTelemetry) -or the -[OpenTelemetry API](https://www.nuget.org/packages/OpenTelemetry.Api) -Include the necessary package in your project. -You can choose the version that you want to depend on. +project within `/test`, here are a few things you should do to ensure that your +project is automatically built and shipped through CI. + +* Based on what your project is, you may need to depend on the [OpenTelemetry +SDK](https://www.nuget.org/packages/OpenTelemetry) or the [OpenTelemetry +API](https://www.nuget.org/packages/OpenTelemetry.Api) Include the necessary +package in your project. You can choose the version that you want to depend on. Usually it is a good idea to use the latest version. Example: ```xml - + ``` * The assembly and nuget versioning is managed through -[MinVer](https://github.com/adamralph/minver) for all the projects in the -repo. MinVer will assign the version to your project based on the tag prefix -specified by you. To ensure your project is versioned appropriately, specify -a `` property in your project file. If your project is named -as "OpenTelemetry.Contrib.Foo.Bar", the MinVerTagPrefix must be "Foo.Bar-". +[MinVer](https://github.com/adamralph/minver) for all the projects in the repo. +MinVer will assign the version to your project based on the tag prefix specified +by you. To ensure your project is versioned appropriately, specify a +`` property in your project file. If your project is named as +"OpenTelemetry.Contrib.Foo.Bar", the MinVerTagPrefix must be "Foo.Bar-". Example: ```xml @@ -186,18 +189,31 @@ Example: ``` -* To build and release your project as nuget, you must provide a GitHub -workflow to be triggered when a tag with prefix "Foo.Bar-" is pushed to the -main branch. The workflow file should be named as `package-Foo.Bar.yml` and -to be placed in the `.github/workflows/` folder. +* To build and release your project as nuget, you must provide a GitHub workflow +to be triggered when a tag with prefix "Foo.Bar-" is pushed to the main branch. +The workflow file should be named as `package-Foo.Bar.yml` and to be placed in +the `.github/workflows/` folder. - You can copy one of the - [existing workflow files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml) + You can copy one of the [existing workflow + files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml) and replace the [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml#L12) value to "Foo.Bar-*" and [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml#L18) value to "OpenTelemetry.Contrib.Foo.Bar". -* When contributing a new project you are expected to assign yourself to your -project in the [code_owners](./.github/code_owners.yml) file +* Add a README file for your project describing how to install and use your + package. Every project's README file needs to have a link to the Nuget + package. You can use the below snippet for reference: + + +``` +[![NuGet](https://img.shields.io/nuget/v/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) +[![NuGet](https://img.shields.io/nuget/dt/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) +``` + + +* When contributing a new project you are expected to assign either yourself or +someone else who would take ownership for the component you are contributing. +Please add the right onwer for your project in the +[component_owners](./.github/component_owners.yml) file. From 28dedcd4bbad9a7428dbca2c8b693be834c98e5a Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 16 Mar 2022 17:52:43 -0700 Subject: [PATCH 0039/1499] Update CHANGELOG for 1.0.0-beta.2 release (#240) --- src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md index d55109e9a5..e5160d147d 100644 --- a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.0.0-beta.2 + * Going forward the NuGet package will be [`OpenTelemetry.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver). Older versions will remain at From debf850563fb0082b13596cdcb6bafff65406ffb Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 16 Mar 2022 18:17:44 -0700 Subject: [PATCH 0040/1499] Rename StackDriver folder (#242) --- opentelemetry-dotnet-contrib.sln | 14 +++---- .../CHANGELOG.md | 42 +++++++++---------- .../Implementation/ActivityExtensions.cs | 0 .../Implementation/Constants.cs | 0 .../ExporterStackdriverEventSource.cs | 0 .../GoogleCloudResourceUtils.cs | 0 .../StackdriverStatsConfiguration.cs | 0 .../OpenTelemetry.Exporter.Stackdriver.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../README.md | 0 .../StackdriverTraceExporter.cs | 0 .../TracerProviderBuilderExtensions.cs | 0 .../Utils/CommonUtils.cs | 0 ....Contrib.Exporter.Stackdriver.Tests.csproj | 2 +- 14 files changed, 29 insertions(+), 29 deletions(-) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/CHANGELOG.md (97%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Implementation/ActivityExtensions.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Implementation/Constants.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Implementation/ExporterStackdriverEventSource.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Implementation/GoogleCloudResourceUtils.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Implementation/StackdriverStatsConfiguration.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/OpenTelemetry.Exporter.Stackdriver.csproj (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Properties/AssemblyInfo.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/README.md (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/StackdriverTraceExporter.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/TracerProviderBuilderExtensions.cs (100%) rename src/{OpenTelemetry.Contrib.Exporter.Stackdriver => OpenTelemetry.Exporter.Stackdriver}/Utils/CommonUtils.cs (100%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 3842e1231e..de91b2df61 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -75,8 +75,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-2 test\Directory.Build.targets = test\Directory.Build.targets EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Contrib.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj", "{09525C6C-68B7-405E-B476-23E64D91C11B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit", "src\OpenTelemetry.Contrib.Instrumentation.MassTransit\OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj", "{301BFB9F-6D73-4DEE-93D1-75F480816F63}" @@ -169,16 +167,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A}.Release|Any CPU.Build.0 = Release|Any CPU {09525C6C-68B7-405E-B476-23E64D91C11B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {09525C6C-68B7-405E-B476-23E64D91C11B}.Debug|Any CPU.Build.0 = Debug|Any CPU {09525C6C-68B7-405E-B476-23E64D91C11B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -335,6 +331,10 @@ Global {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Release|Any CPU.Build.0 = Release|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -343,7 +343,6 @@ Global {43CAFE52-F329-4431-87DA-7FEE1454D9A9} = {1A06E14B-DD2F-4536-9D2E-F708C0C43555} {0112BD4F-B7A6-4E43-AB23-B6E961E27A49} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {E0F52FDB-23D1-4927-BAB8-332655DD7A0B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {BAFDB2B7-A8D4-4725-81CB-F69A9C8A362A} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {09525C6C-68B7-405E-B476-23E64D91C11B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {301BFB9F-6D73-4DEE-93D1-75F480816F63} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {11839CC5-F02B-4812-969A-52CDF5FE9394} = {2097345F-4DD3-477D-BC54-A922F9B2B402} @@ -386,6 +385,7 @@ Global {72EBA81D-2933-417C-8F21-D4CFFD72F530} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {F01E8C75-2791-4DBE-BD7A-5510871EBF56} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md similarity index 97% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md rename to src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index e5160d147d..683a9c3cf5 100644 --- a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -1,21 +1,21 @@ -# Changelog - -## Unreleased - -## 1.0.0-beta.2 - -* Going forward the NuGet package will be - [`OpenTelemetry.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver). - Older versions will remain at - [`OpenTelemetry.Contrib.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Exporter.Stackdriver). - [(#223)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/223) - -## 1.0.0-beta1 - -* Update OTel SDK package version to 1.1.0 -* Log exceptions when failing to export data to stackdriver - -## Initial Release - -* Updated OTel SDK package version to 1.1.0-beta1 - ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) +# Changelog + +## Unreleased + +## 1.0.0-beta.2 + +* Going forward the NuGet package will be + [`OpenTelemetry.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver). + Older versions will remain at + [`OpenTelemetry.Contrib.Exporter.Stackdriver`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Exporter.Stackdriver). + [(#223)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/223) + +## 1.0.0-beta1 + +* Update OTel SDK package version to 1.1.0 +* Log exceptions when failing to export data to stackdriver + +## Initial Release + +* Updated OTel SDK package version to 1.1.0-beta1 + ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/ActivityExtensions.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/Constants.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj rename to src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Properties/AssemblyInfo.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/README.md rename to src/OpenTelemetry.Exporter.Stackdriver/README.md diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/StackdriverTraceExporter.cs rename to src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs diff --git a/src/OpenTelemetry.Contrib.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Exporter.Stackdriver/Utils/CommonUtils.cs rename to src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj index 16161b9f54..e96f112b44 100644 --- a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj @@ -12,7 +12,7 @@ - + From 8b456b42130d47c35fd35585afae57bb9ec00355 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 16 Mar 2022 21:36:05 -0700 Subject: [PATCH 0041/1499] Rename Stackdriver test folder (#243) --- opentelemetry-dotnet-contrib.sln | 14 +++++++------- .../StackdriverStatsConfigurationTests.cs | 0 ...metry.Contrib.Exporter.Stackdriver.Tests.csproj | 0 .../Shared/TestExporter.cs | 0 .../StackdriverExporterTests.cs | 0 .../TestActivityProcessor.cs | 0 .../xunit.runner.json | 0 7 files changed, 7 insertions(+), 7 deletions(-) rename test/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests => OpenTelemetry.Exporter.Stackdriver.Tests}/Implementation/StackdriverStatsConfigurationTests.cs (100%) rename test/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests => OpenTelemetry.Exporter.Stackdriver.Tests}/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj (100%) rename test/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests => OpenTelemetry.Exporter.Stackdriver.Tests}/Shared/TestExporter.cs (100%) rename test/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests => OpenTelemetry.Exporter.Stackdriver.Tests}/StackdriverExporterTests.cs (100%) rename test/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests => OpenTelemetry.Exporter.Stackdriver.Tests}/TestActivityProcessor.cs (100%) rename test/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests => OpenTelemetry.Exporter.Stackdriver.Tests}/xunit.runner.json (100%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index de91b2df61..a1d3302014 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -79,8 +79,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit", "src\OpenTelemetry.Contrib.Instrumentation.MassTransit\OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj", "{301BFB9F-6D73-4DEE-93D1-75F480816F63}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{11839CC5-F02B-4812-969A-52CDF5FE9394}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj", "{1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.csproj", "{5F10395B-DF38-438A-B5DB-5F6449184F67}" @@ -169,6 +167,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -183,10 +183,6 @@ Global {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Debug|Any CPU.Build.0 = Debug|Any CPU {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Release|Any CPU.ActiveCfg = Release|Any CPU {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Release|Any CPU.Build.0 = Release|Any CPU - {11839CC5-F02B-4812-969A-52CDF5FE9394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {11839CC5-F02B-4812-969A-52CDF5FE9394}.Debug|Any CPU.Build.0 = Debug|Any CPU - {11839CC5-F02B-4812-969A-52CDF5FE9394}.Release|Any CPU.ActiveCfg = Release|Any CPU - {11839CC5-F02B-4812-969A-52CDF5FE9394}.Release|Any CPU.Build.0 = Release|Any CPU {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Debug|Any CPU.Build.0 = Debug|Any CPU {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -335,6 +331,10 @@ Global {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.Build.0 = Release|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -345,7 +345,6 @@ Global {E0F52FDB-23D1-4927-BAB8-332655DD7A0B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {09525C6C-68B7-405E-B476-23E64D91C11B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {301BFB9F-6D73-4DEE-93D1-75F480816F63} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {11839CC5-F02B-4812-969A-52CDF5FE9394} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {5F10395B-DF38-438A-B5DB-5F6449184F67} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {BC839E07-108A-4184-B1F9-EF28A1E81088} = {2097345F-4DD3-477D-BC54-A922F9B2B402} @@ -386,6 +385,7 @@ Global {F01E8C75-2791-4DBE-BD7A-5510871EBF56} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj similarity index 100% rename from test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/Shared/TestExporter.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/Shared/TestExporter.cs rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/TestActivityProcessor.cs rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs diff --git a/test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/xunit.runner.json b/test/OpenTelemetry.Exporter.Stackdriver.Tests/xunit.runner.json similarity index 100% rename from test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/xunit.runner.json rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/xunit.runner.json From 954b81cb72ea1b715d4f54fcf860fd38471ae4b0 Mon Sep 17 00:00:00 2001 From: ievgen-platonov <72199261+ievgen-platonov@users.noreply.github.com> Date: Thu, 17 Mar 2022 19:04:01 +0200 Subject: [PATCH 0042/1499] #229: NullReferenceException in TelemetryDispatchMessageInspector.BeforeSendReply when operation is OneWay (#237) * Update TelemetryDispatchMessageInspector.cs #229: Check if reply is not null * #229: Added TelemetryDispatchMessageInspectorForOneWayOperationsTests * #229: Rename parameters * #229: Added new "1.0.0-rc6" version to CHANGELOG.md * #229: Fix text formatting * #229: Fix CHANGELOG formatting. Added extra asserts to the test * #229: Fix formatting * #229: Fix formatting in GHANGELOG.md Co-authored-by: iepl Co-authored-by: Ievgen Platonov <77076677+iepl@users.noreply.github.com> --- .../CHANGELOG.md | 6 + .../TelemetryDispatchMessageInspector.cs | 2 +- ...InspectorForOneWayOperationsTests.netfx.cs | 158 ++++++++++++++++++ .../Tools/ErrorHandler.netfx.cs | 48 ++++++ .../ErrorHandlerServiceBehavior.netfx.cs | 55 ++++++ .../WCF/IServiceContract.cs | 3 + .../WCF/Service.netfx.cs | 4 + .../WCF/ServiceClient.cs | 3 + 8 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md index 4c3495aadf..52eeb96fa7 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.0.0-rc6 + +* Fixed a `NullReferenceException` in + `TelemetryDispatchMessageInspector.BeforeSendReply` when operation is OneWay + ([#237](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/237)) + ## 1.0.0-rc5 * Fixed an `ArgumentNullException` setting `Activity`.`DisplayName` when diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index b9d6b9768a..7f03eafe66 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -131,7 +131,7 @@ public void BeforeSendReply(ref Message reply, object correlationState) { if (correlationState is Activity activity) { - if (activity.IsAllDataRequested) + if (activity.IsAllDataRequested && reply != null) { if (reply.IsFault) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs new file mode 100644 index 0000000000..69f7c7a9c0 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -0,0 +1,158 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if NETFRAMEWORK +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.ServiceModel; +using System.Threading; +using OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.Tools; +using OpenTelemetry.Trace; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +{ + [Collection("WCF")] + public class TelemetryDispatchMessageInspectorForOneWayOperationsTests : IDisposable + { + private readonly ITestOutputHelper output; + private readonly Uri serviceBaseUri; + private readonly ServiceHost serviceHost; + + private readonly EventWaitHandle thrownExceptionsHandle = new EventWaitHandle(false, EventResetMode.ManualReset); + private readonly List thrownExceptions = new List(); + + public TelemetryDispatchMessageInspectorForOneWayOperationsTests(ITestOutputHelper outputHelper) + { + this.output = outputHelper; + + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) + { + try + { + this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); + this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); + + var endpoint = this.serviceHost.AddServiceEndpoint( + typeof(IServiceContract), + new NetTcpBinding(), + "/Service"); + endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); + + this.serviceHost.Description.Behaviors.Add( + new ErrorHandlerServiceBehavior(this.thrownExceptionsHandle, ex => this.thrownExceptions.Add(ex))); + + this.serviceHost.Open(); + + break; + } + catch (Exception ex) + { + this.output.WriteLine(ex.ToString()); + if (this.serviceHost.State == CommunicationState.Faulted) + { + this.serviceHost.Abort(); + } + else + { + this.serviceHost.Close(); + } + + this.serviceHost = null; + retryCount--; + } + } + + if (this.serviceHost == null) + { + throw new InvalidOperationException("ServiceHost could not be started."); + } + } + + public void Dispose() + { + this.serviceHost?.Close(); + this.thrownExceptionsHandle?.Dispose(); + } + + [Fact] + public void IncomingRequestOneWayOperationInstrumentationTest() + { + List stoppedActivities = new List(); + + using ActivityListener activityListener = new ActivityListener + { + ShouldListenTo = activitySource => true, + ActivityStopped = activity => stoppedActivities.Add(activity), + }; + + ActivitySource.AddActivityListener(activityListener); + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddWcfInstrumentation() + .Build(); + + ServiceClient client = new ServiceClient( + new NetTcpBinding(), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + + try + { + client.ExecuteWithOneWay(new ServiceRequest()); + this.thrownExceptionsHandle.WaitOne(3000); + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); + + WcfInstrumentationActivitySource.Options = null; + } + + // Assert + Assert.Empty(this.thrownExceptions); + + Assert.NotEmpty(stoppedActivities); + Assert.Single(stoppedActivities); + + Activity activity = stoppedActivities[0]; + Assert.Equal("http://opentelemetry.io/Service/ExecuteWithOneWay", activity.DisplayName); + Assert.Equal("ExecuteWithOneWay", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + Assert.DoesNotContain(activity.TagObjects, t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag); + + Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); + Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); + Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); + Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); + Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); + Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); + Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); + } + } +} +#endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs new file mode 100644 index 0000000000..58961dbf62 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs @@ -0,0 +1,48 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if NETFRAMEWORK +using System; +using System.ServiceModel.Channels; +using System.ServiceModel.Dispatcher; +using System.Threading; + +namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.Tools +{ + internal class ErrorHandler : IErrorHandler + { + private readonly EventWaitHandle handle; + private readonly Action log; + + public ErrorHandler(EventWaitHandle handle, Action log) + { + this.handle = handle; + this.log = log; + } + + public bool HandleError(Exception error) + { + this.log(error); + this.handle.Set(); + + return true; + } + + public void ProvideFault(Exception error, MessageVersion version, ref Message fault) + { + } + } +} +#endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs new file mode 100644 index 0000000000..0dcccaf9a3 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -0,0 +1,55 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#if NETFRAMEWORK +using System; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Threading; + +namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.Tools +{ + internal class ErrorHandlerServiceBehavior : IServiceBehavior + { + private readonly EventWaitHandle handle; + private readonly Action action; + + public ErrorHandlerServiceBehavior(EventWaitHandle handle, Action action) + { + this.handle = handle; + this.action = action; + } + + public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) + { + } + + public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) + { + dispatcher.ErrorHandlers.Add(new ErrorHandler(this.handle, this.action)); + } + } + + public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + } + } +} +#endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index d4358f2b6d..49746d2178 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -27,5 +27,8 @@ public interface IServiceContract [OperationContract(Action = "")] Task ExecuteWithEmptyActionNameAsync(ServiceRequest request); + + [OperationContract(IsOneWay = true)] + void ExecuteWithOneWay(ServiceRequest request); } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index aa75e5e8bf..0f8aa6c9f5 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -44,6 +44,10 @@ public Task ExecuteWithEmptyActionNameAsync(ServiceRequest requ Payload = $"RSP: {request.Payload}", }); } + + public void ExecuteWithOneWay(ServiceRequest request) + { + } } } #endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index 98792bb3c1..a3af914511 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -32,5 +32,8 @@ public Task ExecuteAsync(ServiceRequest request) public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) => this.Channel.ExecuteWithEmptyActionNameAsync(request); + + public void ExecuteWithOneWay(ServiceRequest request) + => this.Channel.ExecuteWithOneWay(request); } } From 5b9dc459bdf4db567fdbc1b9383452a6546d4ea2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 11:30:57 -0700 Subject: [PATCH 0043/1499] Add common tags (#245) --- build/Common.prod.props | 1 + .../OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj | 2 +- .../OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/build/Common.prod.props b/build/Common.prod.props index fa47e5e8d7..91603cde24 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -14,6 +14,7 @@ $(Build_ArtifactStagingDirectory) true + Observability;OpenTelemetry;Monitoring;Telemetry diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj index 94874bc339..5824f7f151 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj @@ -3,7 +3,7 @@ netstandard2.0 AWS Lambda tracing wrapper for OpenTelemetry .NET - $(PackageTags);OpenTelemetry;AWS Lambda + $(PackageTags);AWS Lambda Instrumentation.AWSLambda- diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj index d7bf778ac8..bdba9cc4c3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj @@ -2,7 +2,7 @@ netstandard2.0 .NET gRPC Core based client and server interceptors for OpenTelemetry. - $(PackageTags);OpenTelemetry;gRPC Core;interceptors + $(PackageTags);gRPC Core;interceptors Instrumentation.GrpcCore- diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index c6b246f127..f48126e677 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -3,7 +3,7 @@ netstandard2.0;net461;netcoreapp3.1;net6.0 dotnet runtime instrumentation for OpenTelemetry .NET - $(PackageTags);OpenTelemetry;runtime + $(PackageTags);runtime Instrumentation.Runtime- From af709ae6dfd63f94410783c9f0dbe4b022344f22 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 17 Mar 2022 12:33:13 -0700 Subject: [PATCH 0044/1499] WCF: Update package/assembly name, namespace, and supported .NET Framework versions (#247) * Update WCF assembly name, namespace, and supported .NET Framework version. * CHANGELOG update. --- .../workflows/package-Instrumentation.Wcf.yml | 4 +-- .../Examples.Wcf.Client.Core.csproj | 2 +- examples/wcf/client-core/Program.cs | 2 +- examples/wcf/client-netframework/App.config | 2 +- .../Examples.Wcf.Client.NetFramework.csproj | 4 +-- examples/wcf/server-netframework/App.config | 2 +- .../Examples.Wcf.Server.NetFramework.csproj | 4 +-- .../wcf/shared/Examples.Wcf.Shared.csproj | 4 +-- opentelemetry-dotnet-contrib.sln | 4 +-- .../AssemblyInfo.cs | 4 +-- .../CHANGELOG.md | 25 ++++++++++++++++++- .../Implementation/ActionMetadata.cs | 2 +- .../WcfInstrumentationActivitySource.cs | 2 +- .../WcfInstrumentationConstants.cs | 2 +- .../WcfInstrumentationEventSource.cs | 2 +- ... OpenTelemetry.Instrumentation.Wcf.csproj} | 4 +-- .../README.md | 10 ++++---- .../TelemetryClientMessageInspector.cs | 4 +-- .../TelemetryContractBehaviorAttribute.cs | 2 +- .../TelemetryDispatchMessageInspector.cs | 4 +-- .../TelemetryEndpointBehavior.cs | 2 +- ...lemetryEndpointBehaviorExtensionElement.cs | 2 +- .../TelemetryServiceBehavior.cs | 2 +- ...elemetryServiceBehaviorExtensionElement.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../WcfEnrichEventNames.cs | 2 +- .../WcfInstrumentationOptions.cs | 2 +- ...elemetry.Instrumentation.Wcf.Tests.csproj} | 8 +++--- .../TelemetryClientMessageInspectorTests.cs | 6 ++--- ...InspectorForOneWayOperationsTests.netfx.cs | 4 +-- ...etryDispatchMessageInspectorTests.netfx.cs | 2 +- .../Tools/ErrorHandler.netfx.cs | 2 +- .../ErrorHandlerServiceBehavior.netfx.cs | 2 +- .../WCF/IServiceContract.cs | 2 +- .../WCF/Service.netfx.cs | 2 +- .../WCF/ServiceClient.cs | 2 +- .../WCF/ServiceRequest.cs | 2 +- .../WCF/ServiceResponse.cs | 2 +- 38 files changed, 80 insertions(+), 57 deletions(-) rename src/OpenTelemetry.Contrib.Instrumentation.Wcf/{OpenTelemetry.Contrib.Instrumentation.Wcf.csproj => OpenTelemetry.Instrumentation.Wcf.csproj} (84%) rename test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj => OpenTelemetry.Instrumentation.Wcf.Tests.csproj} (85%) diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index f9ae1528c9..7207b066a7 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.Wcf +name: Pack OpenTelemetry.Instrumentation.Wcf on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.Wcf + PROJECT: OpenTelemetry.Instrumentation.Wcf strategy: matrix: diff --git a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj b/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj index fedd23c29b..c2a1e9411f 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj @@ -15,7 +15,7 @@ - + diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 433ac6090c..7caf3e0d40 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -21,7 +21,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using OpenTelemetry; -using OpenTelemetry.Contrib.Instrumentation.Wcf; +using OpenTelemetry.Instrumentation.Wcf; using OpenTelemetry.Resources; using OpenTelemetry.Trace; diff --git a/examples/wcf/client-netframework/App.config b/examples/wcf/client-netframework/App.config index f1a84e2671..3eb6ad106e 100644 --- a/examples/wcf/client-netframework/App.config +++ b/examples/wcf/client-netframework/App.config @@ -3,7 +3,7 @@ - + diff --git a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj index 20050361d9..fa58a868eb 100644 --- a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj +++ b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj @@ -2,7 +2,7 @@ Exe - net46 + net462 false @@ -11,7 +11,7 @@ - + diff --git a/examples/wcf/server-netframework/App.config b/examples/wcf/server-netframework/App.config index aa7d7f0bdc..b79c6504be 100644 --- a/examples/wcf/server-netframework/App.config +++ b/examples/wcf/server-netframework/App.config @@ -3,7 +3,7 @@ - + diff --git a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj index 20050361d9..fa58a868eb 100644 --- a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj +++ b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj @@ -2,7 +2,7 @@ Exe - net46 + net462 false @@ -11,7 +11,7 @@ - + diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index 7eba215421..edcee4349e 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -1,10 +1,10 @@  - net452;netstandard2.0 + net462;netstandard2.0 - + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a1d3302014..e16faf5291 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -85,7 +85,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests.csproj", "{BC839E07-108A-4184-B1F9-EF28A1E81088}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Wcf", "src\OpenTelemetry.Contrib.Instrumentation.Wcf\OpenTelemetry.Contrib.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Contrib.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}" EndProject @@ -112,7 +112,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared", "src\OpenTelemetry.Contrib.Shared\OpenTelemetry.Contrib.Shared.csproj", "{F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Wcf.Tests\OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{58D1DE55-B0A5-4BC4-AB37-09B1C7B26752}" ProjectSection(SolutionItems) = preProject diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/AssemblyInfo.cs index 6160622a5f..237a194777 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Wcf.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Wcf.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Wcf.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Wcf.Tests")] #endif diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md index 52eeb96fa7..eb60e019dc 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md @@ -1,6 +1,29 @@ # Changelog -## 1.0.0-rc6 +## 1.0.0-rc.6 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.Wcf`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.Wcf`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Wcf) + [(#247)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/247) + + Migration: + + * In config files update fully qualified references to not use "Contrib" (eg + `type="OpenTelemetry.Contrib.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement, + OpenTelemetry.Contrib.Instrumentation.Wcf"` -> + `type="OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement, + OpenTelemetry.Instrumentation.Wcf"`) + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.Wcf` -> `using + OpenTelemetry.Instrumentation.Wcf`) + +* The minimum supported .NET Framework version is now .NET Framework 4.6.2. + Previous versions will be going out of support in [April + 2022](https://docs.microsoft.com/en-us/lifecycle/products/microsoft-net-framework) + [(#247)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/247) * Fixed a `NullReferenceException` in `TelemetryDispatchMessageInspector.BeforeSendReply` when operation is OneWay diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/ActionMetadata.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/ActionMetadata.cs index c5ddc9e46a..9060a90d64 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/ActionMetadata.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/ActionMetadata.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { internal sealed class ActionMetadata { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index 82b7e09713..34925e2202 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -19,7 +19,7 @@ using System.Diagnostics; using System.ServiceModel.Channels; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// WCF instrumentation. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs index 093e49adb8..f26ce58ea2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { internal static class WcfInstrumentationConstants { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index f3642a45e5..85bc49975f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -19,7 +19,7 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Implementation +namespace OpenTelemetry.Instrumentation.Wcf.Implementation { [EventSource(Name = "OpenTelemetry-Instrumentation-Wcf")] internal sealed class WcfInstrumentationEventSource : EventSource diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Contrib.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj similarity index 84% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Contrib.Instrumentation.Wcf.csproj rename to src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index e6bbfe326a..03238c9387 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Contrib.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -1,7 +1,7 @@  - net452;netstandard2.0 + net462;netstandard2.0 OpenTelemetry instrumentation for WCF $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- @@ -11,7 +11,7 @@ - + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md index 2f865516d5..47b2c0f7b9 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md @@ -1,13 +1,13 @@ # WCF Instrumentation for OpenTelemetry .NET -[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Instrumentation.Wcf.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Wcf/) +[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) Instruments WCF clients and/or services using implementations of `IClientMessageInspector` and `IDispatchMessageInspector` respectively. ## Installation -Add the OpenTelemetry.Contrib.Instrumentation.Wcf package via NuGet. +Add the OpenTelemetry.Instrumentation.Wcf package via NuGet. ## OpenTelemetry Configuration @@ -58,7 +58,7 @@ the clients you want to instrument: - + @@ -113,7 +113,7 @@ to instrument: - + @@ -160,7 +160,7 @@ instrument: - + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index 5cf7db607d..1529648e48 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -21,10 +21,10 @@ using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Contrib.Instrumentation.Wcf.Implementation; +using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// An implementation which adds telemetry to outgoing requests. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 1867f80a6f..6569cb5e51 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -19,7 +19,7 @@ using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { #if NETFRAMEWORK /// diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index 7f03eafe66..3d0c4ef9d0 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -22,10 +22,10 @@ using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Contrib.Instrumentation.Wcf.Implementation; +using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// An implementation which adds telemetry to incoming requests. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index 0f55b3cacf..d8f68af386 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -20,7 +20,7 @@ using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { #if NETFRAMEWORK /// diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs index bf41d4779a..6c30824287 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs @@ -18,7 +18,7 @@ using System; using System.ServiceModel.Configuration; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// A for registering on a service endpoint through configuration. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehavior.cs index a7e56dcb00..2971ef77c5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -18,7 +18,7 @@ using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { #if NETFRAMEWORK /// diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs index 515cdc2703..a40cd05df3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs @@ -18,7 +18,7 @@ using System; using System.ServiceModel.Configuration; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// A for registering on a service through configuration. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index 3a83f5b43c..a0f8026c85 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -15,7 +15,7 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.Wcf; +using OpenTelemetry.Instrumentation.Wcf; namespace OpenTelemetry.Trace { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfEnrichEventNames.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfEnrichEventNames.cs index a4a175ce8f..a7df0f66f9 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfEnrichEventNames.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfEnrichEventNames.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// Constants used for event names when enriching an activity. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfInstrumentationOptions.cs index 3e8a5510fb..2226695fbf 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfInstrumentationOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfInstrumentationOptions.cs @@ -18,7 +18,7 @@ using System.Diagnostics; using System.ServiceModel.Channels; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf { /// /// Options for WCF instrumentation. diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj similarity index 85% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj rename to test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 91cbff5095..61b42fafdb 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for OpenTelemetry WCF instrumentation netcoreapp3.1;net5.0 - $(TargetFrameworks);net452 + $(TargetFrameworks);net462 @@ -17,11 +17,11 @@ - + - + @@ -31,6 +31,6 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs index 202c097982..dd23c2ebd1 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs @@ -27,7 +27,7 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [Collection("WCF")] public class TelemetryClientMessageInspectorTests : IDisposable @@ -100,11 +100,11 @@ async void Listener() { if (request.Contains("ExecuteWithEmptyActionName")) { - writer.Write(@"RSP: Hello Open Telemetry!"); + writer.Write(@"RSP: Hello Open Telemetry!"); } else { - writer.Write(@"RSP: Hello Open Telemetry!"); + writer.Write(@"RSP: Hello Open Telemetry!"); } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index 69f7c7a9c0..1600995642 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -20,12 +20,12 @@ using System.Linq; using System.ServiceModel; using System.Threading; -using OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.Tools; +using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; using Xunit; using Xunit.Abstractions; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [Collection("WCF")] public class TelemetryDispatchMessageInspectorForOneWayOperationsTests : IDisposable diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index a94a746b8b..c3109f8231 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -25,7 +25,7 @@ using Xunit; using Xunit.Abstractions; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [Collection("WCF")] public class TelemetryDispatchMessageInspectorTests : IDisposable diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs index 58961dbf62..76a7fa3a7b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs @@ -19,7 +19,7 @@ using System.ServiceModel.Dispatcher; using System.Threading; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.Tools +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools { internal class ErrorHandler : IErrorHandler { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs index 0dcccaf9a3..ce08732e7b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -22,7 +22,7 @@ using System.ServiceModel.Dispatcher; using System.Threading; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests.Tools +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools { internal class ErrorHandlerServiceBehavior : IServiceBehavior { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 49746d2178..4cac874196 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -17,7 +17,7 @@ using System.ServiceModel; using System.Threading.Tasks; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [ServiceContract(Namespace = "http://opentelemetry.io/", Name = "Service", SessionMode = SessionMode.Allowed)] public interface IServiceContract diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 0f8aa6c9f5..44e3508935 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -17,7 +17,7 @@ using System.ServiceModel; using System.Threading.Tasks; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [ServiceBehavior( Namespace = "http://opentelemetry.io/", diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index a3af914511..09439bef39 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -18,7 +18,7 @@ using System.ServiceModel.Channels; using System.Threading.Tasks; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { public class ServiceClient : ClientBase, IServiceContract { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index 80259ee9b1..4b8e9f3ebc 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -16,7 +16,7 @@ using System.Runtime.Serialization; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [DataContract] public class ServiceRequest diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index fafe9bfba6..046a53fe03 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -16,7 +16,7 @@ using System.Runtime.Serialization; -namespace OpenTelemetry.Contrib.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests { [DataContract] public class ServiceResponse From dff05566736efc1bc1ecc264c2a82ef2c25501aa Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 13:30:48 -0700 Subject: [PATCH 0045/1499] Rename ElasticSearch instrumentation (#248) * Rename ElasticSearchInstrumentation --- .github/component_owners.yml | 4 ++-- .../package-Instrumentation.Elasticsearch.yml | 4 ++-- opentelemetry-dotnet-contrib.sln | 4 ++-- .../CHANGELOG.md | 14 ++++++++++++++ .../ElasticsearchClientInstrumentation.cs | 5 ++--- .../ElasticsearchClientInstrumentationOptions.cs | 4 ++-- .../ElasticsearchInstrumentationEventSource.cs | 2 +- ...asticsearchRequestPipelineDiagnosticListener.cs | 2 +- ...try.Instrumentation.ElasticsearchClient.csproj} | 0 .../Properties/AssemblyInfo.cs | 4 ++-- .../README.md | 2 +- .../TracerProviderBuilderExtensions.cs | 4 ++-- .../Customer.cs | 2 +- .../ElasticsearchClientTests.cs | 2 +- .../InMemoryConnectionWithDownstreamActivity.cs | 2 +- ...strumentation.ElasticsearchClient.Tests.csproj} | 2 +- 16 files changed, 35 insertions(+), 22 deletions(-) rename src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.csproj => OpenTelemetry.Instrumentation.ElasticsearchClient.csproj} (100%) rename test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests.csproj => OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj} (84%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 0b550e6ecf..ff827c72a0 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -7,7 +7,7 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn - src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/: + src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/: - pcwiese @@ -31,7 +31,7 @@ components: test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn - test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/: + test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/: - pcwiese diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 3e04c3ce48..3bf92513b3 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient +name: Pack OpenTelemetry.Instrumentation.ElasticsearchClient on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient + PROJECT: OpenTelemetry.Instrumentation.ElasticsearchClient strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e16faf5291..cc3f3c4e21 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -81,9 +81,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj", "{1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.csproj", "{5F10395B-DF38-438A-B5DB-5F6449184F67}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient\OpenTelemetry.Instrumentation.ElasticsearchClient.csproj", "{5F10395B-DF38-438A-B5DB-5F6449184F67}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests.csproj", "{BC839E07-108A-4184-B1F9-EF28A1E81088}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{BC839E07-108A-4184-B1F9-EF28A1E81088}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Contrib.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" EndProject diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/CHANGELOG.md index a6848b5cad..902b51c786 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,20 @@ ## Unreleased +## 1.0.0-beta.3 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.ElasticsearchClient`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient) + [(#248)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/248) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient` -> `using + OpenTelemetry.Instrumentation.ElasticsearchClient`) + ## 1.0.0-beta2 Released 2021-June-17 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs index af42fdcfa7..43a4e7fb2c 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs @@ -14,10 +14,9 @@ // limitations under the License. // using System; -using OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Implementation; -using OpenTelemetry.Instrumentation; +using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient +namespace OpenTelemetry.Instrumentation.ElasticsearchClient { /// /// Elasticsearch client instrumentation. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index 625af65013..406cee6131 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -17,7 +17,7 @@ using System; using System.Diagnostics; -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient +namespace OpenTelemetry.Instrumentation.ElasticsearchClient { /// /// Options for Elasticsearch client instrumentation. @@ -35,7 +35,7 @@ public class ElasticsearchClientInstrumentationOptions public bool ParseAndFormatRequest { get; set; } = false; /// - /// Gets or sets a value indicating whether or not the OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient + /// Gets or sets a value indicating whether or not the OpenTelemetry.Instrumentation.ElasticsearchClient /// should add the request information as db.statement attribute tag. Default value: True. /// public bool SetDbStatementForRequest { get; set; } = true; diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs index d2c4768633..6ac52ff137 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs @@ -18,7 +18,7 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Implementation +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation { /// /// EventSource events emitted from the project. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 33accd4135..5635344e8d 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -27,7 +27,7 @@ using OpenTelemetry.Instrumentation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Implementation +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation { internal class ElasticsearchRequestPipelineDiagnosticListener : ListenerHandler { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.csproj rename to src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs index 84a355764c..d5e496903e 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.ElasticsearchClient.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.ElasticsearchClient.Tests")] #endif diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md index bd060511dc..f8bfbaf7b9 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md @@ -5,7 +5,7 @@ Automatically instruments events emitted by the NEST/Elasticsearch.Net client li ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient +dotnet add package OpenTelemetry.Instrumentation.ElasticsearchClient ``` ## Configuration diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index 3e894633b2..250cc702ce 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -15,8 +15,8 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient; -using OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Implementation; +using OpenTelemetry.Instrumentation.ElasticsearchClient; +using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; namespace OpenTelemetry.Trace { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/Customer.cs b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/Customer.cs index 916126e42b..b1b0d0f882 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/Customer.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/Customer.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests { public class Customer { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index ab1ae1958e..ad0984b7d9 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -28,7 +28,7 @@ using Xunit; using Status = OpenTelemetry.Trace.Status; -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests { public class ElasticsearchClientTests { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs index 68bbb5fe4e..4db51f8943 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs @@ -19,7 +19,7 @@ using System.Threading.Tasks; using Elasticsearch.Net; -namespace OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests { public class InMemoryConnectionWithDownstreamActivity : InMemoryConnection { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj similarity index 84% rename from test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests.csproj rename to test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index c269f41508..ec8fb67e8b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -19,7 +19,7 @@ - + From 1123c93b59cf416564bdb2f983f2d411baec8bbf Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 17 Mar 2022 13:54:19 -0700 Subject: [PATCH 0046/1499] Update the folder structure for WCF instrumentation. (#249) --- examples/wcf/client-core/Examples.Wcf.Client.Core.csproj | 2 +- .../Examples.Wcf.Client.NetFramework.csproj | 2 +- .../Examples.Wcf.Server.NetFramework.csproj | 2 +- opentelemetry-dotnet-contrib.sln | 4 ++-- .../AssemblyInfo.cs | 0 .../CHANGELOG.md | 0 .../Implementation/ActionMetadata.cs | 0 .../Implementation/WcfInstrumentationActivitySource.cs | 0 .../Implementation/WcfInstrumentationConstants.cs | 0 .../Implementation/WcfInstrumentationEventSource.cs | 0 .../OpenTelemetry.Instrumentation.Wcf.csproj | 0 .../README.md | 0 .../TelemetryClientMessageInspector.cs | 0 .../TelemetryContractBehaviorAttribute.cs | 0 .../TelemetryDispatchMessageInspector.cs | 0 .../TelemetryEndpointBehavior.cs | 0 .../TelemetryEndpointBehaviorExtensionElement.cs | 0 .../TelemetryServiceBehavior.cs | 0 .../TelemetryServiceBehaviorExtensionElement.cs | 0 .../TracerProviderBuilderExtensions.cs | 0 .../WcfEnrichEventNames.cs | 0 .../WcfInstrumentationOptions.cs | 0 .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 2 +- .../TelemetryClientMessageInspectorTests.cs | 0 ...yDispatchMessageInspectorForOneWayOperationsTests.netfx.cs | 0 .../TelemetryDispatchMessageInspectorTests.netfx.cs | 0 .../Tools/ErrorHandler.netfx.cs | 0 .../Tools/ErrorHandlerServiceBehavior.netfx.cs | 0 .../WCF/IServiceContract.cs | 0 .../WCF/Service.netfx.cs | 0 .../WCF/ServiceClient.cs | 0 .../WCF/ServiceRequest.cs | 0 .../WCF/ServiceResponse.cs | 0 33 files changed, 6 insertions(+), 6 deletions(-) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/AssemblyInfo.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/CHANGELOG.md (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/Implementation/ActionMetadata.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/Implementation/WcfInstrumentationActivitySource.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/Implementation/WcfInstrumentationConstants.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/Implementation/WcfInstrumentationEventSource.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/OpenTelemetry.Instrumentation.Wcf.csproj (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/README.md (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryClientMessageInspector.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryContractBehaviorAttribute.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryDispatchMessageInspector.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryEndpointBehavior.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryEndpointBehaviorExtensionElement.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryServiceBehavior.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TelemetryServiceBehaviorExtensionElement.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/TracerProviderBuilderExtensions.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/WcfEnrichEventNames.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Wcf => OpenTelemetry.Instrumentation.Wcf}/WcfInstrumentationOptions.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/OpenTelemetry.Instrumentation.Wcf.Tests.csproj (91%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/TelemetryClientMessageInspectorTests.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/TelemetryDispatchMessageInspectorTests.netfx.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/Tools/ErrorHandler.netfx.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/Tools/ErrorHandlerServiceBehavior.netfx.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/WCF/IServiceContract.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/WCF/Service.netfx.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/WCF/ServiceClient.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/WCF/ServiceRequest.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.Wcf.Tests => OpenTelemetry.Instrumentation.Wcf.Tests}/WCF/ServiceResponse.cs (100%) diff --git a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj b/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj index c2a1e9411f..6be5e847bf 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj @@ -15,7 +15,7 @@ - + diff --git a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj index fa58a868eb..3ba74dd0fa 100644 --- a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj +++ b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj @@ -11,7 +11,7 @@ - + diff --git a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj index fa58a868eb..3ba74dd0fa 100644 --- a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj +++ b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj @@ -11,7 +11,7 @@ - + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index cc3f3c4e21..ebd3ed86d3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -85,7 +85,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{BC839E07-108A-4184-B1F9-EF28A1E81088}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Contrib.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}" EndProject @@ -112,7 +112,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared", "src\OpenTelemetry.Contrib.Shared\OpenTelemetry.Contrib.Shared.csproj", "{F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{58D1DE55-B0A5-4BC4-AB37-09B1C7B26752}" ProjectSection(SolutionItems) = preProject diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/CHANGELOG.md rename to src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/ActionMetadata.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/ActionMetadata.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj rename to src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/README.md rename to src/OpenTelemetry.Instrumentation.Wcf/README.md diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryClientMessageInspector.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehavior.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehavior.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfEnrichEventNames.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfEnrichEventNames.cs rename to src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Wcf/WcfInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj similarity index 91% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 61b42fafdb..076a025b57 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -31,6 +31,6 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs From ff979fbce1892d128f9cbb987f9679d82fdfcb2d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 16:30:42 -0700 Subject: [PATCH 0047/1499] Rename ElasticSearch folders (#250) * Rename ElasticSearch folders --- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../CHANGELOG.md | 0 .../ElasticsearchClientInstrumentation.cs | 0 ...asticsearchClientInstrumentationOptions.cs | 0 ...ElasticsearchInstrumentationEventSource.cs | 0 ...searchRequestPipelineDiagnosticListener.cs | 0 ...Instrumentation.ElasticsearchClient.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../README.md | 3 ++ .../TracerProviderBuilderExtensions.cs | 0 .../Customer.cs | 0 .../ElasticsearchClientTests.cs | 0 ...nMemoryConnectionWithDownstreamActivity.cs | 0 ...mentation.ElasticsearchClient.Tests.csproj | 2 +- 14 files changed, 18 insertions(+), 15 deletions(-) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/CHANGELOG.md (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/ElasticsearchClientInstrumentation.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/ElasticsearchClientInstrumentationOptions.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/Implementation/ElasticsearchInstrumentationEventSource.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/Properties/AssemblyInfo.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/README.md (68%) rename src/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient => OpenTelemetry.Instrumentation.ElasticsearchClient}/TracerProviderBuilderExtensions.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests => OpenTelemetry.Instrumentation.ElasticsearchClient.Tests}/Customer.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests => OpenTelemetry.Instrumentation.ElasticsearchClient.Tests}/ElasticsearchClientTests.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests => OpenTelemetry.Instrumentation.ElasticsearchClient.Tests}/InMemoryConnectionWithDownstreamActivity.cs (100%) rename test/{OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests => OpenTelemetry.Instrumentation.ElasticsearchClient.Tests}/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj (84%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ebd3ed86d3..ba794d4318 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -81,10 +81,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj", "{1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient\OpenTelemetry.Instrumentation.ElasticsearchClient.csproj", "{5F10395B-DF38-438A-B5DB-5F6449184F67}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{BC839E07-108A-4184-B1F9-EF28A1E81088}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}" @@ -169,6 +165,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stac EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Instrumentation.ElasticsearchClient\OpenTelemetry.Instrumentation.ElasticsearchClient.csproj", "{96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{970B604C-C57F-4767-A080-67976E69F76E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -187,14 +187,6 @@ Global {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Debug|Any CPU.Build.0 = Debug|Any CPU {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Release|Any CPU.ActiveCfg = Release|Any CPU {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Release|Any CPU.Build.0 = Release|Any CPU - {5F10395B-DF38-438A-B5DB-5F6449184F67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5F10395B-DF38-438A-B5DB-5F6449184F67}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5F10395B-DF38-438A-B5DB-5F6449184F67}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5F10395B-DF38-438A-B5DB-5F6449184F67}.Release|Any CPU.Build.0 = Release|Any CPU - {BC839E07-108A-4184-B1F9-EF28A1E81088}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC839E07-108A-4184-B1F9-EF28A1E81088}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC839E07-108A-4184-B1F9-EF28A1E81088}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC839E07-108A-4184-B1F9-EF28A1E81088}.Release|Any CPU.Build.0 = Release|Any CPU {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.Build.0 = Debug|Any CPU {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -335,6 +327,14 @@ Global {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.Build.0 = Release|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Release|Any CPU.Build.0 = Release|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -346,8 +346,6 @@ Global {09525C6C-68B7-405E-B476-23E64D91C11B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {301BFB9F-6D73-4DEE-93D1-75F480816F63} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {5F10395B-DF38-438A-B5DB-5F6449184F67} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {BC839E07-108A-4184-B1F9-EF28A1E81088} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {CAD5C27A-D359-4086-9C4F-02204C084A8E} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {73474960-8F91-4EE5-8E3E-F7E7ADA99238} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {21716C26-3B2A-4208-BDFB-8E58E2AF49EA} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} @@ -386,6 +384,8 @@ Global {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/CHANGELOG.md rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md similarity index 68% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index f8bfbaf7b9..b446359b08 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -1,5 +1,8 @@ # Elasticsearch Client Instrumentation for OpenTelemetry .NET +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) + Automatically instruments events emitted by the NEST/Elasticsearch.Net client library. ## Installation diff --git a/src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/Customer.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/Customer.cs rename to test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs rename to test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs rename to test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs diff --git a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj similarity index 84% rename from test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj rename to test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index ec8fb67e8b..22417858df 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -19,7 +19,7 @@ - + From 6664c00f19a3e00cbc7abe009ae151675c035fa8 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 16:47:21 -0700 Subject: [PATCH 0048/1499] Update CHANGELOG for Quartz Instrumentation (#251) * Update CHANGELOG for Quartz Instrumentation --- src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 1512c42162..e92e8f7d5c 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -1,3 +1,9 @@ # Changelog ## Unreleased + +## 1.0.0-alpha.1 + +* This is the first release of `OpenTelemetry.Instrumentation.Quartz` package. + +For more details, please refer to the [README](README.md). From f6fb30b18ed51e16a43fb9d15a1fa8147f722e2e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 17:46:56 -0700 Subject: [PATCH 0049/1499] Update component owners (#254) --- .github/component_owners.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index ff827c72a0..18bfb3a629 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -2,50 +2,50 @@ # Each component identified by its path prefix has a list of users components: - src/OpenTelemetry.Contrib.Exporter.Stackdriver/: - - SergeyKanzhelev src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn - src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - - ejsmith src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/: - pcwiese src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: - alexvaluyskiy src/OpenTelemetry.Contrib.Instrumentation.Owin/: - codeblanch - src/OpenTelemetry.Contrib.Instrumentation.Wcf/: - - codeblanch src/OpenTelemetry.Contrib.Instrumentation.MySqlData/: - moonheart src/OpenTelemetry.Contrib.Extensions.PersistentStorage/: - vishweshbankwar src/OpenTelemetry.Contrib.Preview/: - codeblanch + src/OpenTelemetry.Exporter.Stackdriver/: + - SergeyKanzhelev + src/OpenTelemetry.Instrumentation.ElasticsearchClient/: + - ejsmith src/OpenTelemetry.Instrumentation.Quartz/: - maldago + src/OpenTelemetry.Instrumentation.Wcf/: + - codeblanch - test/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests/: - - SergeyKanzhelev test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn - test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - - ejsmith test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/: - pcwiese test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: - alexvaluyskiy test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/: - codeblanch - test/OpenTelemetry.Contrib.Instrumentation.Wcf.Tests/: - - codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/: - moonheart test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/: - vishweshbankwar test/OpenTelemetry.Contrib.Preview.Tests/: - codeblanch + test/OpenTelemetry.Exporter.Stackdriver.Tests/: + - SergeyKanzhelev + test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: + - ejsmith test/OpenTelemetry.Instrumentation.Quartz.Tests/: - maldago + test/OpenTelemetry.Instrumentation.Wcf.Tests/: + - codeblanch From fa839e73370aee5b4a32de71d49c7d383bb8e0b1 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 18:27:22 -0700 Subject: [PATCH 0050/1499] Remove "Contrib" from AzureMonitor Extensions (#253) * Rename AzureMonitor Extensions * Add CHANGELOG --- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../ApplicationInsightsSampler.cs | 2 +- .../CHANGELOG.md | 3 ++ ...nTelemetry.Extensions.AzureMonitor.csproj} | 0 .../README.md | 2 +- .../ApplicationInsightsSamplerTests.cs | 2 +- ...etry.Extensions.AzureMonitor.Tests.csproj} | 2 +- 7 files changed, 21 insertions(+), 18 deletions(-) rename src/{OpenTelemetry.Contrib.Extensions.AzureMonitor => OpenTelemetry.Extensions.AzureMonitor}/ApplicationInsightsSampler.cs (98%) create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Extensions.AzureMonitor/OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj => OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj} (100%) rename src/{OpenTelemetry.Contrib.Extensions.AzureMonitor => OpenTelemetry.Extensions.AzureMonitor}/README.md (84%) rename test/{OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests => OpenTelemetry.Extensions.AzureMonitor.Tests}/ApplicationInsightsSamplerTests.cs (98%) rename test/{OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj => OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj} (81%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ba794d4318..f27c56c207 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -141,10 +141,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AzureMonitor", "src\OpenTelemetry.Contrib.Extensions.AzureMonitor\OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj", "{9C2D6D1A-8580-4527-B718-E206D0690635}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests\OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj", "{771651AA-010F-4FF6-9CB2-BAFFE5E04FC2}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Owin", "src\OpenTelemetry.Contrib.Instrumentation.Owin\OpenTelemetry.Contrib.Instrumentation.Owin.csproj", "{530255C1-D130-4B43-981D-911E54F7C787}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "owin", "owin", "{8D11A34C-D0EF-4DE1-8230-32168E67044D}" @@ -169,6 +165,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{970B604C-C57F-4767-A080-67976E69F76E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor", "src\OpenTelemetry.Extensions.AzureMonitor\OpenTelemetry.Extensions.AzureMonitor.csproj", "{426D8AE8-EC39-48EA-AC66-1BF84C4CE529}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -283,14 +283,6 @@ Global {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU - {9C2D6D1A-8580-4527-B718-E206D0690635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C2D6D1A-8580-4527-B718-E206D0690635}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9C2D6D1A-8580-4527-B718-E206D0690635}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9C2D6D1A-8580-4527-B718-E206D0690635}.Release|Any CPU.Build.0 = Release|Any CPU - {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2}.Release|Any CPU.Build.0 = Release|Any CPU {530255C1-D130-4B43-981D-911E54F7C787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {530255C1-D130-4B43-981D-911E54F7C787}.Debug|Any CPU.Build.0 = Debug|Any CPU {530255C1-D130-4B43-981D-911E54F7C787}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -335,6 +327,14 @@ Global {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.Build.0 = Debug|Any CPU {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.ActiveCfg = Release|Any CPU {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.Build.0 = Release|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.Build.0 = Debug|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.ActiveCfg = Release|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.Build.0 = Release|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -372,8 +372,6 @@ Global {4172D671-3AAC-443F-9EB0-A6608B154AF0} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {9C2D6D1A-8580-4527-B718-E206D0690635} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {771651AA-010F-4FF6-9CB2-BAFFE5E04FC2} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {530255C1-D130-4B43-981D-911E54F7C787} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} @@ -386,6 +384,8 @@ Global {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs similarity index 98% rename from src/OpenTelemetry.Contrib.Extensions.AzureMonitor/ApplicationInsightsSampler.cs rename to src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 33a03dc8db..2e9bdeedf9 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -17,7 +17,7 @@ using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Extensions.AzureMonitor +namespace OpenTelemetry.Extensions.AzureMonitor { /// /// Sample configurable for OpenTelemetry exporters for compatibility diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md new file mode 100644 index 0000000000..1512c42162 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +## Unreleased diff --git a/src/OpenTelemetry.Contrib.Extensions.AzureMonitor/OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Extensions.AzureMonitor/OpenTelemetry.Contrib.Extensions.AzureMonitor.csproj rename to src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj diff --git a/src/OpenTelemetry.Contrib.Extensions.AzureMonitor/README.md b/src/OpenTelemetry.Extensions.AzureMonitor/README.md similarity index 84% rename from src/OpenTelemetry.Contrib.Extensions.AzureMonitor/README.md rename to src/OpenTelemetry.Extensions.AzureMonitor/README.md index cedda76b62..2cef918157 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AzureMonitor/README.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/README.md @@ -7,7 +7,7 @@ implements the same hash algorithm when deciding to sample telemetry. ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Extensions.AzureMonitor +dotnet add package OpenTelemetry.Extensions.AzureMonitor ``` ## References diff --git a/test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs rename to test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs index afa36c32ec..4a08277dd4 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs @@ -20,7 +20,7 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests +namespace OpenTelemetry.Extensions.AzureMonitor.Tests { public class ApplicationInsightsSamplerTests { diff --git a/test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj similarity index 81% rename from test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj rename to test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index b4a6c0edba..3090d15741 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests/OpenTelemetry.Contrib.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -16,7 +16,7 @@ - + From 301cfc1e864bed2f39c525646614372bd316a3d4 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 17 Mar 2022 21:04:14 -0700 Subject: [PATCH 0051/1499] Remove "Contrib" from PersistentStorage Extension (#258) * Rename PersistentStorage Extension * Update CHANGELOG --- .github/component_owners.yml | 8 +++--- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../CHANGELOG.md | 9 ------ .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 22 +++++++++++++++ .../FileBlob.cs | 2 +- .../FileStorage.cs | 2 +- .../IPersistentBlob.cs | 2 +- .../IPersistentStorage.cs | 2 +- ...metry.Extensions.PersistentStorage.csproj} | 0 .../PersistentStorageEventSource.cs | 2 +- .../PersistentStorageHelper.cs | 2 +- .../README.md | 5 +++- .../FileBlobTests.cs | 2 +- .../FileStorageTests.cs | 2 +- ...Extensions.PersistentStorage.Tests.csproj} | 4 +-- 16 files changed, 55 insertions(+), 39 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/AssemblyInfo.cs (93%) create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/FileBlob.cs (98%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/FileStorage.cs (99%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/IPersistentBlob.cs (97%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/IPersistentStorage.cs (97%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj => OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj} (100%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/PersistentStorageEventSource.cs (98%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/PersistentStorageHelper.cs (99%) rename src/{OpenTelemetry.Contrib.Extensions.PersistentStorage => OpenTelemetry.Extensions.PersistentStorage}/README.md (89%) rename test/{OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests => OpenTelemetry.Extensions.PersistentStorage.Tests}/FileBlobTests.cs (98%) rename test/{OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests => OpenTelemetry.Extensions.PersistentStorage.Tests}/FileStorageTests.cs (98%) rename test/{OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj => OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj} (79%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 18bfb3a629..8985a8aab4 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -13,12 +13,12 @@ components: - codeblanch src/OpenTelemetry.Contrib.Instrumentation.MySqlData/: - moonheart - src/OpenTelemetry.Contrib.Extensions.PersistentStorage/: - - vishweshbankwar src/OpenTelemetry.Contrib.Preview/: - codeblanch src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev + src/OpenTelemetry.Extensions.PersistentStorage/: + - vishweshbankwar src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith src/OpenTelemetry.Instrumentation.Quartz/: @@ -37,12 +37,12 @@ components: - codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/: - moonheart - test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/: - - vishweshbankwar test/OpenTelemetry.Contrib.Preview.Tests/: - codeblanch test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev + test/OpenTelemetry.Extensions.PersistentStorage.Tests/: + - vishweshbankwar test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith test/OpenTelemetry.Instrumentation.Quartz.Tests/: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f27c56c207..64bc3c7a3d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -149,10 +149,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\o EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Owin.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Owin.Tests\OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj", "{D52558C8-B7BF-4F59-A0FA-9AA629E68012}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.PersistentStorage", "src\OpenTelemetry.Contrib.Extensions.PersistentStorage\OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj", "{433C59A3-D535-421E-BA7F-9BCE0D4A3D25}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests\OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj", "{72EBA81D-2933-417C-8F21-D4CFFD72F530}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Contrib.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{F01E8C75-2791-4DBE-BD7A-5510871EBF56}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" @@ -169,6 +165,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Az EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage", "src\OpenTelemetry.Extensions.PersistentStorage\OpenTelemetry.Extensions.PersistentStorage.csproj", "{C2B9190B-E2F6-4D40-B298-91521E383A50}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -295,14 +295,6 @@ Global {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Debug|Any CPU.Build.0 = Debug|Any CPU {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Release|Any CPU.ActiveCfg = Release|Any CPU {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Release|Any CPU.Build.0 = Release|Any CPU - {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Debug|Any CPU.Build.0 = Debug|Any CPU - {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Release|Any CPU.ActiveCfg = Release|Any CPU - {433C59A3-D535-421E-BA7F-9BCE0D4A3D25}.Release|Any CPU.Build.0 = Release|Any CPU - {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Debug|Any CPU.Build.0 = Debug|Any CPU - {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Release|Any CPU.ActiveCfg = Release|Any CPU - {72EBA81D-2933-417C-8F21-D4CFFD72F530}.Release|Any CPU.Build.0 = Release|Any CPU {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.Build.0 = Debug|Any CPU {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -335,6 +327,14 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.Build.0 = Release|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -376,8 +376,6 @@ Global {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} {D52558C8-B7BF-4F59-A0FA-9AA629E68012} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {433C59A3-D535-421E-BA7F-9BCE0D4A3D25} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {72EBA81D-2933-417C-8F21-D4CFFD72F530} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {F01E8C75-2791-4DBE-BD7A-5510871EBF56} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -386,6 +384,8 @@ Global {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md deleted file mode 100644 index 05bde1f36d..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Changelog - OpenTelemetry.Contrib.Extensions.PersistentStorage - -## 1.0.0-alpha2 - -This is the first release for the `OpenTelemetry.Contrib.Extensions.PersistentStorage` -project. - -For more details, please refer to the -[README](README.md) diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/AssemblyInfo.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs index e925a5a392..711d529c4d 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.PersistentStorage.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md new file mode 100644 index 0000000000..2ee6ef09c9 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md @@ -0,0 +1,22 @@ +# Changelog - OpenTelemetry.Extensions.PersistentStorage + +## 1.0.0-alpha.3 + +* Going forward the NuGet package will be + [`OpenTelemetry.Extensions.PersistentStorage`](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage). + Older versions will remain at + [`OpenTelemetry.Contrib.Extensions.PersistentStorage`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Extensions.PersistentStorage) + [(#258)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/258) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Extensions.PersistentStorage` -> `using + OpenTelemetry.Extensions.PersistentStorage`) + +## 1.0.0-alpha2 + +This is the first release for the +`OpenTelemetry.Contrib.Extensions.PersistentStorage` project. + +For more details, please refer to the [README](README.md) diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs similarity index 98% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileBlob.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs index 11181dfbb2..109788a412 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs @@ -17,7 +17,7 @@ using System; using System.IO; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage { /// /// The allows to save a blob diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileStorage.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileStorage.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs index 087d5f270d..2ad010fe07 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/FileStorage.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs @@ -20,7 +20,7 @@ using System.Linq; using System.Timers; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage { /// /// Persistent file storage allows to save data diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentBlob.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs index 5e18345179..7099d36bb0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage { /// /// Represents a persistent blob. diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentStorage.cs b/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentStorage.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs index 40d12ec4f0..3328bfdbda 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/IPersistentStorage.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs @@ -16,7 +16,7 @@ using System.Collections.Generic; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage { /// /// Persistent storage API. diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/OpenTelemetry.Contrib.Extensions.PersistentStorage.csproj rename to src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs similarity index 98% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageEventSource.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs index afe96c2cd1..ec90919986 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs @@ -18,7 +18,7 @@ using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage { [EventSource(Name = EventSourceName)] internal sealed class PersistentStorageEventSource : EventSource diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageHelper.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs index 32c5a080ec..e102645a6c 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -24,7 +24,7 @@ using System.Text; using System.Threading; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage { internal static class PersistentStorageHelper { diff --git a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md b/src/OpenTelemetry.Extensions.PersistentStorage/README.md similarity index 89% rename from src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md rename to src/OpenTelemetry.Extensions.PersistentStorage/README.md index ecc61eca22..98447c372a 100644 --- a/src/OpenTelemetry.Contrib.Extensions.PersistentStorage/README.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage/README.md @@ -1,5 +1,8 @@ # Persistent Storage Interface and Implementation +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) + This package provides both the interface and implementation of persistent storage. It is an experimental component which can be used by OpenTelemetry Exporters to provide reliable data delivery. Eventually this component should @@ -8,7 +11,7 @@ get splitted into the abstract interface and concrete implementations. ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Extensions.PersistentStorage +dotnet add package OpenTelemetry.Extensions.PersistentStorage ``` ## Basic Usage diff --git a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs rename to test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs index b7e9f6b797..bf9ee5c1bb 100644 --- a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs @@ -20,7 +20,7 @@ using System.Threading; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests +namespace OpenTelemetry.Extensions.PersistentStorage.Tests { public class FileBlobTests { diff --git a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileStorageTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileStorageTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileStorageTests.cs rename to test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileStorageTests.cs index 923699233a..b8fa77eadd 100644 --- a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/FileStorageTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileStorageTests.cs @@ -21,7 +21,7 @@ using System.Threading; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests +namespace OpenTelemetry.Extensions.PersistentStorage.Tests { public class FileStorageTests { diff --git a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj similarity index 79% rename from test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj rename to test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj index cf14001b6c..144388bfaa 100644 --- a/test/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests/OpenTelemetry.Contrib.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1;net5.0 @@ -16,7 +16,7 @@ - + From 595194da8526a550128894b19818f753e24d888c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 18 Mar 2022 13:37:39 -0700 Subject: [PATCH 0052/1499] Add release workflow for PersistentStorage (#260) --- .github/workflows/package-Extensions.PersistentStorage.yml | 4 ++-- opentelemetry-dotnet-contrib.sln | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index a28bd292de..b4e461e23f 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Extensions.PersistentStorage +name: Pack OpenTelemetry.Extensions.PersistentStorage on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Extensions.PersistentStorage + PROJECT: OpenTelemetry.Extensions.PersistentStorage strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 64bc3c7a3d..0e90f525de 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -33,6 +33,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml + .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml From 2fe7215516c46f7b70a263bf673fb46940d87773 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 18 Mar 2022 14:28:53 -0700 Subject: [PATCH 0053/1499] Rename Owin Instrumentation (#257) * Rename Owin Instrumentation --- .github/component_owners.yml | 8 +++--- .../package-Instrumentation.Owin.yml | 4 +-- examples/owin/Examples.Owin.csproj | 2 +- examples/owin/README.md | 2 +- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../CHANGELOG.md | 5 ---- .../AppBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 23 +++++++++++++++ .../Implementation/DiagnosticsMiddleware.cs | 2 +- .../OwinInstrumentationActivitySource.cs | 2 +- .../OwinInstrumentationEventSource.cs | 2 +- ...OpenTelemetry.Instrumentation.Owin.csproj} | 0 .../OwinEnrichEventType.cs | 2 +- .../OwinInstrumentationOptions.cs | 2 +- .../README.md | 9 +++--- .../TracerProviderBuilderExtensions.cs | 2 +- .../Controllers/TestController.cs | 2 +- .../DiagnosticsMiddlewareTests.cs | 2 +- ...lemetry.Instrumentation.Owin.Tests.csproj} | 2 +- 20 files changed, 61 insertions(+), 42 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Owin/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/AppBuilderExtensions.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/AssemblyInfo.cs (67%) create mode 100644 src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/Implementation/DiagnosticsMiddleware.cs (99%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/Implementation/OwinInstrumentationActivitySource.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/Implementation/OwinInstrumentationEventSource.cs (98%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin/OpenTelemetry.Contrib.Instrumentation.Owin.csproj => OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj} (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/OwinEnrichEventType.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/OwinInstrumentationOptions.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/README.md (87%) rename src/{OpenTelemetry.Contrib.Instrumentation.Owin => OpenTelemetry.Instrumentation.Owin}/TracerProviderBuilderExtensions.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.Owin.Tests => OpenTelemetry.Instrumentation.Owin.Tests}/Controllers/TestController.cs (92%) rename test/{OpenTelemetry.Contrib.Instrumentation.Owin.Tests => OpenTelemetry.Instrumentation.Owin.Tests}/DiagnosticsMiddlewareTests.cs (99%) rename test/{OpenTelemetry.Contrib.Instrumentation.Owin.Tests/OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj => OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj} (87%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 8985a8aab4..82e1dd54ad 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -9,8 +9,6 @@ components: - pcwiese src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: - alexvaluyskiy - src/OpenTelemetry.Contrib.Instrumentation.Owin/: - - codeblanch src/OpenTelemetry.Contrib.Instrumentation.MySqlData/: - moonheart src/OpenTelemetry.Contrib.Preview/: @@ -21,6 +19,8 @@ components: - vishweshbankwar src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith + src/OpenTelemetry.Instrumentation.Owin/: + - codeblanch src/OpenTelemetry.Instrumentation.Quartz/: - maldago src/OpenTelemetry.Instrumentation.Wcf/: @@ -33,8 +33,6 @@ components: - pcwiese test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: - alexvaluyskiy - test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/: - - codeblanch test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/: - moonheart test/OpenTelemetry.Contrib.Preview.Tests/: @@ -45,6 +43,8 @@ components: - vishweshbankwar test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith + test/OpenTelemetry.Instrumentation.Owin.Tests/: + - codeblanch test/OpenTelemetry.Instrumentation.Quartz.Tests/: - maldago test/OpenTelemetry.Instrumentation.Wcf.Tests/: diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index 5ae2534edb..006c9e2d4b 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.Owin +name: Pack OpenTelemetry.Instrumentation.Owin on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.Owin + PROJECT: OpenTelemetry.Instrumentation.Owin strategy: matrix: diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index 0fbabb0964..3e8294e89c 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -12,7 +12,7 @@ - + diff --git a/examples/owin/README.md b/examples/owin/README.md index db8d94a0c8..6b1abf7cc6 100644 --- a/examples/owin/README.md +++ b/examples/owin/README.md @@ -1,7 +1,7 @@ # OWIN Instrumentation for OpenTelemetry .NET - Example An example application that shows how to use -`OpenTelemetry.Contrib.Instrumentation.Owin` to capture telemetry from a +`OpenTelemetry.Instrumentation.Owin` to capture telemetry from a self-hosted WebAPI .NET Framework service. Span names are set to the route template resolved by WebAPI. diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 0e90f525de..6dd0475e97 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -142,14 +142,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Owin", "src\OpenTelemetry.Contrib.Instrumentation.Owin\OpenTelemetry.Contrib.Instrumentation.Owin.csproj", "{530255C1-D130-4B43-981D-911E54F7C787}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "owin", "owin", "{8D11A34C-D0EF-4DE1-8230-32168E67044D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\owin\Examples.Owin.csproj", "{6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.Owin.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Owin.Tests\OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj", "{D52558C8-B7BF-4F59-A0FA-9AA629E68012}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Contrib.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{F01E8C75-2791-4DBE-BD7A-5510871EBF56}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" @@ -170,6 +166,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Pe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin", "src\OpenTelemetry.Instrumentation.Owin\OpenTelemetry.Instrumentation.Owin.csproj", "{2815DA76-D855-43FD-A005-FAB289B5EFE8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin.Tests", "test\OpenTelemetry.Instrumentation.Owin.Tests\OpenTelemetry.Instrumentation.Owin.Tests.csproj", "{D7311F9A-BFC3-4470-9C49-39D826BA9996}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -284,18 +284,10 @@ Global {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU - {530255C1-D130-4B43-981D-911E54F7C787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {530255C1-D130-4B43-981D-911E54F7C787}.Debug|Any CPU.Build.0 = Debug|Any CPU - {530255C1-D130-4B43-981D-911E54F7C787}.Release|Any CPU.ActiveCfg = Release|Any CPU - {530255C1-D130-4B43-981D-911E54F7C787}.Release|Any CPU.Build.0 = Release|Any CPU {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.Build.0 = Debug|Any CPU {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.ActiveCfg = Release|Any CPU {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.Build.0 = Release|Any CPU - {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D52558C8-B7BF-4F59-A0FA-9AA629E68012}.Release|Any CPU.Build.0 = Release|Any CPU {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.Build.0 = Debug|Any CPU {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -336,6 +328,14 @@ Global {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.Build.0 = Release|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.Build.0 = Release|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -373,10 +373,8 @@ Global {4172D671-3AAC-443F-9EB0-A6608B154AF0} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {530255C1-D130-4B43-981D-911E54F7C787} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} - {D52558C8-B7BF-4F59-A0FA-9AA629E68012} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {F01E8C75-2791-4DBE-BD7A-5510871EBF56} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -387,6 +385,8 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.Owin/CHANGELOG.md deleted file mode 100644 index 134621e04d..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -## Unreleased - -* Initial release diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/AppBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/AppBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs index 902cfe3286..ff17e3fb1f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/AppBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs @@ -15,7 +15,7 @@ // using System.Diagnostics; -using OpenTelemetry.Contrib.Instrumentation.Owin; +using OpenTelemetry.Instrumentation.Owin; namespace Owin { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs similarity index 67% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs index f4836c41f8..7a9ba40bf0 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs @@ -18,7 +18,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.Owin.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Owin.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else [assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Owin.Tests")] #endif diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md new file mode 100644 index 0000000000..16122787c7 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +## Unreleased + +## 1.0.0-rc.2 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.Owin`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.Owin`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Owin) + [(#257)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/257) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.Owin` -> `using + OpenTelemetry.Instrumentation.Owin`) + +## 1.0.0-rc1 + +* This is the first release of `OpenTelemetry.Contrib.Instrumentation.Owin` package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs rename to src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 058500e658..b90d26cb43 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -23,7 +23,7 @@ using OpenTelemetry.Context.Propagation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin { /// /// Instruments incoming request with and notifies listeners with . diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs rename to src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index 60bfb6e358..11574f25f9 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -17,7 +17,7 @@ using System; using System.Diagnostics; -namespace OpenTelemetry.Contrib.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin { internal static class OwinInstrumentationActivitySource { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs similarity index 98% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs rename to src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index 021d137d90..ae9e5f97b0 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -19,7 +19,7 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Contrib.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin { /// /// EventSource events emitted from the project. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/OpenTelemetry.Contrib.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/OpenTelemetry.Contrib.Instrumentation.Owin.csproj rename to src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/OwinEnrichEventType.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/OwinEnrichEventType.cs rename to src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs index 9d5e3260c3..1ca4ea0c21 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/OwinEnrichEventType.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs @@ -16,7 +16,7 @@ using System.Diagnostics; -namespace OpenTelemetry.Contrib.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin { /// /// Describes the possible events fired when enriching an . diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/OwinInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index 0739e587fd..a127ee1ac0 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -19,7 +19,7 @@ using Microsoft.Owin; using OpenTelemetry.Context.Propagation; -namespace OpenTelemetry.Contrib.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin { /// /// Options for requests instrumentation. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md similarity index 87% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/README.md rename to src/OpenTelemetry.Instrumentation.Owin/README.md index c60f2c6135..80b82a750b 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -1,13 +1,14 @@ # OWIN Instrumentation for OpenTelemetry .NET -[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Instrumentation.Own.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Owin/) +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/glossary.md#instrumentation-library), which instruments [OWIN/Katana](https://github.com/aspnet/AspNetKatana/) and collects telemetry about incoming requests. -## Steps to enable OpenTelemetry.Contrib.Instrumentation.Owin +## Steps to enable OpenTelemetry.Instrumentation.Owin An example project is available in the [examples/owin](../../examples/owin/) folder. @@ -15,11 +16,11 @@ An example project is available in the ### Step 1: Install Package Add a reference to the -[`OpenTelemetry.Contrib.Instrumentation.Owin`](https://www.nuget.org/packages/opentelemetry.contrib.instrumentation.owin) +[`OpenTelemetry.Instrumentation.Owin`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) package. Also, add any other instrumentations & exporters you will need. ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.Owin +dotnet add package OpenTelemetry.Instrumentation.Owin ``` ### Step 2: Configure OWIN middleware diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.Owin/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index f34ecfa534..0e876540a1 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -15,7 +15,7 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.Owin; +using OpenTelemetry.Instrumentation.Owin; namespace OpenTelemetry.Trace { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/Controllers/TestController.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs similarity index 92% rename from test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/Controllers/TestController.cs rename to test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs index 661126c47d..2a7a870578 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/Controllers/TestController.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs @@ -17,7 +17,7 @@ using System; using System.Web.Http; -namespace OpenTelemetry.Contrib.Instrumentation.Owin.Tests.Controllers +namespace OpenTelemetry.Instrumentation.Owin.Tests.Controllers { public class TestController : ApiController { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs similarity index 99% rename from test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs rename to test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 858232aa5e..67e7a0bdf9 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -28,7 +28,7 @@ using Owin; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.Owin.Tests +namespace OpenTelemetry.Instrumentation.Owin.Tests { public class DiagnosticsMiddlewareTests : IDisposable { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj similarity index 87% rename from test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj rename to test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index 7b9472399a..c6936297f4 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Owin.Tests/OpenTelemetry.Contrib.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -21,7 +21,7 @@ - + From 76e5c4f2229961d3e69710255cdceb52f9d44353 Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Fri, 18 Mar 2022 22:42:05 +0100 Subject: [PATCH 0054/1499] Add initial release (#259) Co-authored-by: Utkarsh Umesan Pillai --- .../CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md new file mode 100644 index 0000000000..f8645188be --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## 0.1.0-alpha.1 + +* This is the first release of `OpenTelemetry.Instrumentation.Runtime` package. + +For more details, please refer to the [README](README.md). From bf420f880995ed8d75f83f38540e2189e2575a15 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 18 Mar 2022 14:59:54 -0700 Subject: [PATCH 0055/1499] Renam Runtime Instrumentation (#262) --- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../AssemblyInfo.cs | 0 .../CHANGELOG.md | 2 ++ .../MeterProviderBuilderExtensions.cs | 2 +- ...enTelemetry.Instrumentation.Runtime.csproj | 0 .../README.md | 10 +++---- .../RuntimeMetrics.cs | 2 +- .../RuntimeMetricsOptions.cs | 2 +- ...metry.Instrumentation.Runtime.Tests.csproj | 2 +- .../RuntimeMetricsOptionsTests.cs | 2 +- .../RuntimeMetricsTests.cs | 2 +- 11 files changed, 27 insertions(+), 25 deletions(-) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/AssemblyInfo.cs (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/CHANGELOG.md (91%) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/MeterProviderBuilderExtensions.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/OpenTelemetry.Instrumentation.Runtime.csproj (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/README.md (82%) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/RuntimeMetrics.cs (99%) rename src/{OpenTelemetry.Contrib.Instrumentation.Runtime => OpenTelemetry.Instrumentation.Runtime}/RuntimeMetricsOptions.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.Runtime.Tests => OpenTelemetry.Instrumentation.Runtime.Tests}/OpenTelemetry.Instrumentation.Runtime.Tests.csproj (88%) rename test/{OpenTelemetry.Contrib.Instrumentation.Runtime.Tests => OpenTelemetry.Instrumentation.Runtime.Tests}/RuntimeMetricsOptionsTests.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.Runtime.Tests => OpenTelemetry.Instrumentation.Runtime.Tests}/RuntimeMetricsTests.cs (98%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6dd0475e97..6484290660 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -146,10 +146,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "owin", "owin", "{8D11A34C-D EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\owin\Examples.Owin.csproj", "{6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Contrib.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{F01E8C75-2791-4DBE-BD7A-5510871EBF56}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Contrib.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" @@ -170,6 +166,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin.Tests", "test\OpenTelemetry.Instrumentation.Owin.Tests\OpenTelemetry.Instrumentation.Owin.Tests.csproj", "{D7311F9A-BFC3-4470-9C49-39D826BA9996}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{67BFE7DF-505D-427E-8019-40BFF19363E9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -288,14 +288,6 @@ Global {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.Build.0 = Debug|Any CPU {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.ActiveCfg = Release|Any CPU {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.Build.0 = Release|Any CPU - {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F01E8C75-2791-4DBE-BD7A-5510871EBF56}.Release|Any CPU.Build.0 = Release|Any CPU - {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA}.Release|Any CPU.Build.0 = Release|Any CPU {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -336,6 +328,14 @@ Global {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.Build.0 = Debug|Any CPU {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.ActiveCfg = Release|Any CPU {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.Build.0 = Release|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Release|Any CPU.Build.0 = Release|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -375,8 +375,6 @@ Global {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} - {F01E8C75-2791-4DBE-BD7A-5510871EBF56} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {FB907DF7-F3F3-4A07-885D-E5FECAE36BDA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -387,6 +385,8 @@ Global {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {67BFE7DF-505D-427E-8019-40BFF19363E9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md similarity index 91% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md rename to src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index f8645188be..23727004ed 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## Unreleased + ## 0.1.0-alpha.1 * This is the first release of `OpenTelemetry.Instrumentation.Runtime` package. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 7bc2e24aef..ec49496560 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -15,7 +15,7 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.Runtime; +using OpenTelemetry.Instrumentation.Runtime; namespace OpenTelemetry.Metrics { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj rename to src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md similarity index 82% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md rename to src/OpenTelemetry.Instrumentation.Runtime/README.md index c80f7c713b..bc26b361a3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -1,23 +1,23 @@ # DotNet Runtime Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Runtime) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Contrib.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Runtime) +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), which instruments [.NET Runtime](https://docs.microsoft.com/dotnet) and collect telemetry about runtime behavior. -## Steps to enable OpenTelemetry.Contrib.Instrumentation.Runtime +## Steps to enable OpenTelemetry.Instrumentation.Runtime ### Step 1: Install Package Add a reference to the -[`OpenTelemetry.Contrib.Instrumentation.Runtime`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.Runtime) +[`OpenTelemetry.Instrumentation.Runtime`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) package. Also, add any other instrumentations & exporters you will need. ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.Runtime +dotnet add package OpenTelemetry.Instrumentation.Runtime ``` ### Step 2: Enable Runtime Instrumentation at application startup diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs rename to src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index c5ea2421c5..e42dfc7a68 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -21,7 +21,7 @@ using System.Reflection; using System.Threading; -namespace OpenTelemetry.Contrib.Instrumentation.Runtime +namespace OpenTelemetry.Instrumentation.Runtime { /// /// .NET runtime instrumentation. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs similarity index 98% rename from src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs rename to src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs index 730e4e2b98..6553f07f72 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.Runtime +namespace OpenTelemetry.Instrumentation.Runtime { /// /// Options to define the runtime metrics. diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj similarity index 88% rename from test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj rename to test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index ff2ea386be..83e37f299a 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs rename to test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs index c4eeda1777..373cab8fe7 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -16,7 +16,7 @@ using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.Runtime.Tests +namespace OpenTelemetry.Instrumentation.Runtime.Tests { public class RuntimeMetricsOptionsTests { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs rename to test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 009ddf196c..a25ce5b875 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -20,7 +20,7 @@ using OpenTelemetry.Metrics; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.Runtime.Tests +namespace OpenTelemetry.Instrumentation.Runtime.Tests { public class RuntimeMetricsTests { From 38fd4525925b94be0e7889a6250bf6215771cf7e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 18 Mar 2022 15:28:35 -0700 Subject: [PATCH 0056/1499] Remove "Contrib" from Grpc instrumentation (#255) * Rename GRPC instrumentation --- .github/component_owners.yml | 8 +- .../package-Instrumentation.GrpcCore.yml | 4 +- .../Examples.GrpcCore.AspNetCore.csproj | 4 +- .../Examples.GrpcCore.AspNetCore/Startup.cs | 2 +- opentelemetry-dotnet-contrib.sln | 28 +- .../CHANGELOG.md | 9 - .../AssemblyInfo.cs | 2 +- .../AsyncStreamReaderProxy.cs | 194 +-- .../CHANGELOG.md | 32 + .../ClientStreamWriterProxy.cs | 216 ++-- .../ClientTracingInterceptor.cs | 720 +++++------ .../ClientTracingInterceptorOptions.cs | 84 +- .../Extensions.cs | 94 +- .../GrpcCoreInstrumentation.cs | 96 +- ...Telemetry.Instrumentation.GrpcCore.csproj} | 26 +- .../README.md | 5 +- .../RpcScope.cs | 462 +++---- .../SemanticConventions.cs | 80 +- .../ServerStreamWriterProxy.cs | 138 +-- .../ServerTracingInterceptor.cs | 452 +++---- .../ServerTracingInterceptorOptions.cs | 84 +- .../TracerProviderBuilderExtensions.cs | 86 +- .../FoobarService.cs | 568 ++++----- .../GrpcCoreClientInterceptorTests.cs | 1060 ++++++++--------- .../GrpcCoreServerInterceptorTests.cs | 362 +++--- .../InterceptorActivityListener.cs | 148 +-- ...try.Instrumentation.GrpcCore.Tests.csproj} | 50 +- .../proto/foobar.proto | 32 +- 28 files changed, 2536 insertions(+), 2510 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/AssemblyInfo.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/AsyncStreamReaderProxy.cs (95%) create mode 100644 src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/ClientStreamWriterProxy.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/ClientTracingInterceptor.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/ClientTracingInterceptorOptions.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/Extensions.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/GrpcCoreInstrumentation.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj => OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj} (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/README.md (79%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/RpcScope.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/SemanticConventions.cs (94%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/ServerStreamWriterProxy.cs (94%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/ServerTracingInterceptor.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/ServerTracingInterceptorOptions.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.GrpcCore => OpenTelemetry.Instrumentation.GrpcCore}/TracerProviderBuilderExtensions.cs (94%) rename test/{OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests => OpenTelemetry.Instrumentation.GrpcCore.Tests}/FoobarService.cs (96%) rename test/{OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests => OpenTelemetry.Instrumentation.GrpcCore.Tests}/GrpcCoreClientInterceptorTests.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests => OpenTelemetry.Instrumentation.GrpcCore.Tests}/GrpcCoreServerInterceptorTests.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests => OpenTelemetry.Instrumentation.GrpcCore.Tests}/InterceptorActivityListener.cs (95%) rename test/{OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests.csproj => OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj} (83%) rename test/{OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests => OpenTelemetry.Instrumentation.GrpcCore.Tests}/proto/foobar.proto (84%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 82e1dd54ad..328d63edb4 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -5,8 +5,6 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn - src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/: - - pcwiese src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: - alexvaluyskiy src/OpenTelemetry.Contrib.Instrumentation.MySqlData/: @@ -19,6 +17,8 @@ components: - vishweshbankwar src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith + src/OpenTelemetry.Instrumentation.GrpcCore/: + - pcwiese src/OpenTelemetry.Instrumentation.Owin/: - codeblanch src/OpenTelemetry.Instrumentation.Quartz/: @@ -29,8 +29,6 @@ components: test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn - test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/: - - pcwiese test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: - alexvaluyskiy test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/: @@ -43,6 +41,8 @@ components: - vishweshbankwar test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith + test/OpenTelemetry.Instrumentation.GrpcCore.Tests/: + - pcwiese test/OpenTelemetry.Instrumentation.Owin.Tests/: - codeblanch test/OpenTelemetry.Instrumentation.Quartz.Tests/: diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index d26b891d44..a75a5aaefb 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.GrpcCore +name: Pack OpenTelemetry.Instrumentation.GrpcCore on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.GrpcCore + PROJECT: OpenTelemetry.Instrumentation.GrpcCore strategy: matrix: diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 0bc531bbf2..8cc915727a 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -1,4 +1,4 @@ - + net5.0 @@ -17,7 +17,7 @@ - + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index ff5868b0ad..d9104d5bc3 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -23,7 +23,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using OpenTelemetry.Contrib.Instrumentation.GrpcCore; +using OpenTelemetry.Instrumentation.GrpcCore; using OpenTelemetry.Trace; namespace Examples.GrpcCore.AspNetCore diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6484290660..8a95008c47 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -118,10 +118,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcCore.AspNetCore", "examples\grpc.core\Examples.GrpcCore.AspNetCore\Examples.GrpcCore.AspNetCore.csproj", "{F1591DEE-79C0-4161-85C2-1477B261D274}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.GrpcCore", "src\OpenTelemetry.Contrib.Instrumentation.GrpcCore\OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj", "{ECBF7E54-3490-4B69-A376-17DC7BC75B0D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests", "test\OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests\OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests.csproj", "{22E101DD-D6D7-4554-9A98-8963230D6B2F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MySqlData", "src\OpenTelemetry.Contrib.Instrumentation.MySqlData\OpenTelemetry.Contrib.Instrumentation.MySqlData.csproj", "{7D6175C4-1E8C-43BD-878D-6241E9627A69}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests\OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests.csproj", "{9F837AD0-C410-4001-B002-55090DA584EA}" @@ -162,6 +158,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Pe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore", "src\OpenTelemetry.Instrumentation.GrpcCore\OpenTelemetry.Instrumentation.GrpcCore.csproj", "{D0B694E4-AAE4-492F-ACCB-3D913A874780}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore.Tests", "test\OpenTelemetry.Instrumentation.GrpcCore.Tests\OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj", "{32D24733-C807-4816-84C3-270CE790AFD4}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin", "src\OpenTelemetry.Instrumentation.Owin\OpenTelemetry.Instrumentation.Owin.csproj", "{2815DA76-D855-43FD-A005-FAB289B5EFE8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin.Tests", "test\OpenTelemetry.Instrumentation.Owin.Tests\OpenTelemetry.Instrumentation.Owin.Tests.csproj", "{D7311F9A-BFC3-4470-9C49-39D826BA9996}" @@ -236,14 +236,6 @@ Global {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.Build.0 = Debug|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.ActiveCfg = Release|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.Build.0 = Release|Any CPU - {ECBF7E54-3490-4B69-A376-17DC7BC75B0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ECBF7E54-3490-4B69-A376-17DC7BC75B0D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ECBF7E54-3490-4B69-A376-17DC7BC75B0D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ECBF7E54-3490-4B69-A376-17DC7BC75B0D}.Release|Any CPU.Build.0 = Release|Any CPU - {22E101DD-D6D7-4554-9A98-8963230D6B2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {22E101DD-D6D7-4554-9A98-8963230D6B2F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {22E101DD-D6D7-4554-9A98-8963230D6B2F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {22E101DD-D6D7-4554-9A98-8963230D6B2F}.Release|Any CPU.Build.0 = Release|Any CPU {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Debug|Any CPU.Build.0 = Debug|Any CPU {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -312,6 +304,14 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.Build.0 = Release|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.Build.0 = Release|Any CPU {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -361,8 +361,6 @@ Global {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} - {ECBF7E54-3490-4B69-A376-17DC7BC75B0D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {22E101DD-D6D7-4554-9A98-8963230D6B2F} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {7D6175C4-1E8C-43BD-878D-6241E9627A69} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {9F837AD0-C410-4001-B002-55090DA584EA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {87FE0ED4-56A5-4775-9F63-DD532F2200BD} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -381,6 +379,8 @@ Global {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/CHANGELOG.md deleted file mode 100644 index 60b95e6ce0..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# Changelog - -## Unreleased - -* Updated OTel SDK package version to 1.1.0-beta1 - ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) - -* Do NOT mutate incoming call headers, copy them before propagation - ([#143](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/143)) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs index 6d51fec554..3ad733d811 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.GrpcCore.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index 5e8a99bbd8..698cad42ee 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -1,97 +1,97 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using global::Grpc.Core; - - /// - /// A proxy stream reader with callbacks for interesting events. - /// - /// - /// Borrowed heavily from - /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingAsyncStreamReader.cs. - /// - /// The message type. - /// - internal class AsyncStreamReaderProxy : IAsyncStreamReader - { - /// - /// The reader. - /// - private readonly IAsyncStreamReader reader; - - /// - /// The on message action. - /// - private readonly Action onMessage; - - /// - /// The on stream end action. - /// - private readonly Action onStreamEnd; - - /// - /// The on exception action. - /// - private readonly Action onException; - - /// - /// Initializes a new instance of the class. - /// - /// The reader. - /// The on message action, if any. - /// The on stream end action, if any. - /// The on exception action, if any. - public AsyncStreamReaderProxy(IAsyncStreamReader reader, Action onMessage = null, Action onStreamEnd = null, Action onException = null) - { - this.reader = reader; - this.onMessage = onMessage; - this.onStreamEnd = onStreamEnd; - this.onException = onException; - } - - /// - public T Current => this.reader.Current; - - /// - public async Task MoveNext(CancellationToken cancellationToken) - { - try - { - var hasNext = await this.reader.MoveNext(cancellationToken).ConfigureAwait(false); - if (hasNext) - { - this.onMessage?.Invoke(this.Current); - } - else - { - this.onStreamEnd?.Invoke(); - } - - return hasNext; - } - catch (Exception ex) - { - this.onException?.Invoke(ex); - throw; - } - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Threading; + using System.Threading.Tasks; + using global::Grpc.Core; + + /// + /// A proxy stream reader with callbacks for interesting events. + /// + /// + /// Borrowed heavily from + /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingAsyncStreamReader.cs. + /// + /// The message type. + /// + internal class AsyncStreamReaderProxy : IAsyncStreamReader + { + /// + /// The reader. + /// + private readonly IAsyncStreamReader reader; + + /// + /// The on message action. + /// + private readonly Action onMessage; + + /// + /// The on stream end action. + /// + private readonly Action onStreamEnd; + + /// + /// The on exception action. + /// + private readonly Action onException; + + /// + /// Initializes a new instance of the class. + /// + /// The reader. + /// The on message action, if any. + /// The on stream end action, if any. + /// The on exception action, if any. + public AsyncStreamReaderProxy(IAsyncStreamReader reader, Action onMessage = null, Action onStreamEnd = null, Action onException = null) + { + this.reader = reader; + this.onMessage = onMessage; + this.onStreamEnd = onStreamEnd; + this.onException = onException; + } + + /// + public T Current => this.reader.Current; + + /// + public async Task MoveNext(CancellationToken cancellationToken) + { + try + { + var hasNext = await this.reader.MoveNext(cancellationToken).ConfigureAwait(false); + if (hasNext) + { + this.onMessage?.Invoke(this.Current); + } + else + { + this.onStreamEnd?.Invoke(); + } + + return hasNext; + } + catch (Exception ex) + { + this.onException?.Invoke(ex); + throw; + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md new file mode 100644 index 0000000000..6204360350 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -0,0 +1,32 @@ +# Changelog + +## Unreleased + +## 1.0.0-beta.4 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.GrpcCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.GrpcCore`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.GrpcCore) + [(#255)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/255) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.GrpcCore` -> `using + OpenTelemetry.Instrumentation.GrpcCore`) + +## 1.0.0-beta3 + +* Updated OTel SDK package version to 1.1.0-beta1 + ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) + +* Do NOT mutate incoming call headers, copy them before propagation + ([#143](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/143)) + +## 1.0.0-beta2 + +* This is the first release of `OpenTelemetry.Contrib.Instrumentation.GrpcCore` + package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index a0eca3341f..5aadc8e09f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -1,108 +1,108 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Threading.Tasks; - using global::Grpc.Core; - - /// - /// A proxy client stream writer. - /// - /// - /// Borrowed heavily from - /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingClientStreamWriter.cs. - /// - /// The message type. - /// - internal class ClientStreamWriterProxy : IClientStreamWriter - { - /// - /// The writer. - /// - private readonly IClientStreamWriter writer; - - /// - /// The on write action. - /// - private readonly Action onWrite; - - /// - /// The on complete action. - /// - private readonly Action onComplete; - - /// - /// The on exception action. - /// - private readonly Action onException; - - /// - /// Initializes a new instance of the class. - /// - /// The writer. - /// The on write action if any. - /// The on complete action, if any. - /// The on exception action, if any. - public ClientStreamWriterProxy(IClientStreamWriter writer, Action onWrite = null, Action onComplete = null, Action onException = null) - { - this.writer = writer; - this.onWrite = onWrite; - this.onComplete = onComplete; - this.onException = onException; - } - - /// - public WriteOptions WriteOptions - { - get => this.writer.WriteOptions; - set => this.writer.WriteOptions = value; - } - - /// - public async Task WriteAsync(T message) - { - this.onWrite?.Invoke(message); - - try - { - await this.writer.WriteAsync(message).ConfigureAwait(false); - } - catch (Exception e) - { - this.onException?.Invoke(e); - throw; - } - } - - /// - public async Task CompleteAsync() - { - this.onComplete?.Invoke(); - - try - { - await this.writer.CompleteAsync().ConfigureAwait(false); - } - catch (Exception e) - { - this.onException?.Invoke(e); - throw; - } - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Threading.Tasks; + using global::Grpc.Core; + + /// + /// A proxy client stream writer. + /// + /// + /// Borrowed heavily from + /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingClientStreamWriter.cs. + /// + /// The message type. + /// + internal class ClientStreamWriterProxy : IClientStreamWriter + { + /// + /// The writer. + /// + private readonly IClientStreamWriter writer; + + /// + /// The on write action. + /// + private readonly Action onWrite; + + /// + /// The on complete action. + /// + private readonly Action onComplete; + + /// + /// The on exception action. + /// + private readonly Action onException; + + /// + /// Initializes a new instance of the class. + /// + /// The writer. + /// The on write action if any. + /// The on complete action, if any. + /// The on exception action, if any. + public ClientStreamWriterProxy(IClientStreamWriter writer, Action onWrite = null, Action onComplete = null, Action onException = null) + { + this.writer = writer; + this.onWrite = onWrite; + this.onComplete = onComplete; + this.onException = onException; + } + + /// + public WriteOptions WriteOptions + { + get => this.writer.WriteOptions; + set => this.writer.WriteOptions = value; + } + + /// + public async Task WriteAsync(T message) + { + this.onWrite?.Invoke(message); + + try + { + await this.writer.WriteAsync(message).ConfigureAwait(false); + } + catch (Exception e) + { + this.onException?.Invoke(e); + throw; + } + } + + /// + public async Task CompleteAsync() + { + this.onComplete?.Invoke(); + + try + { + await this.writer.CompleteAsync().ConfigureAwait(false); + } + catch (Exception e) + { + this.onException?.Invoke(e); + throw; + } + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientTracingInterceptor.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 89a9dac2b9..5d2eec97db 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -1,360 +1,360 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using global::Grpc.Core; - using global::Grpc.Core.Interceptors; - using OpenTelemetry.Context.Propagation; - - /// - /// A client interceptor that starts and stops an Activity for each outbound RPC. - /// - /// - public class ClientTracingInterceptor : Interceptor - { - /// - /// The options. - /// - private readonly ClientTracingInterceptorOptions options; - - /// - /// Initializes a new instance of the class. - /// - /// The options. - public ClientTracingInterceptor(ClientTracingInterceptorOptions options) - { - this.options = options ?? throw new ArgumentNullException(nameof(options)); - } - - /// - public override TResponse BlockingUnaryCall( - TRequest request, - ClientInterceptorContext context, - BlockingUnaryCallContinuation continuation) - { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - rpcScope.RecordRequest(request); - var response = continuation(request, rpcScope.Context); - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - rpcScope?.Dispose(); - } - } - - /// - public override AsyncUnaryCall AsyncUnaryCall( - TRequest request, - ClientInterceptorContext context, - AsyncUnaryCallContinuation continuation) - { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - rpcScope.RecordRequest(request); - var responseContinuation = continuation(request, rpcScope.Context); - var responseAsync = responseContinuation.ResponseAsync.ContinueWith( - responseTask => - { - try - { - var response = responseTask.Result; - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (AggregateException ex) - { - rpcScope.CompleteWithException(ex.InnerException); - throw ex.InnerException; - } - }); - - return new AsyncUnaryCall( - responseAsync, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } - } - - /// - public override AsyncClientStreamingCall AsyncClientStreamingCall( - ClientInterceptorContext context, - AsyncClientStreamingCallContinuation continuation) - { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - var responseContinuation = continuation(rpcScope.Context); - var clientRequestStreamProxy = new ClientStreamWriterProxy( - responseContinuation.RequestStream, - rpcScope.RecordRequest, - onException: rpcScope.CompleteWithException); - - var responseAsync = responseContinuation.ResponseAsync.ContinueWith( - responseTask => - { - try - { - var response = responseTask.Result; - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (AggregateException ex) - { - rpcScope.CompleteWithException(ex.InnerException); - throw ex.InnerException; - } - }); - - return new AsyncClientStreamingCall( - clientRequestStreamProxy, - responseAsync, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } - } - - /// - public override AsyncServerStreamingCall AsyncServerStreamingCall( - TRequest request, - ClientInterceptorContext context, - AsyncServerStreamingCallContinuation continuation) - { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - rpcScope.RecordRequest(request); - var responseContinuation = continuation(request, rpcScope.Context); - - var responseStreamProxy = new AsyncStreamReaderProxy( - responseContinuation.ResponseStream, - rpcScope.RecordResponse, - rpcScope.Complete, - rpcScope.CompleteWithException); - - return new AsyncServerStreamingCall( - responseStreamProxy, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } - } - - /// - public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall( - ClientInterceptorContext context, - AsyncDuplexStreamingCallContinuation continuation) - { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - var responseContinuation = continuation(rpcScope.Context); - - var requestStreamProxy = new ClientStreamWriterProxy( - responseContinuation.RequestStream, - rpcScope.RecordRequest, - onException: rpcScope.CompleteWithException); - - var responseStreamProxy = new AsyncStreamReaderProxy( - responseContinuation.ResponseStream, - rpcScope.RecordResponse, - rpcScope.Complete, - rpcScope.CompleteWithException); - - return new AsyncDuplexStreamingCall( - requestStreamProxy, - responseStreamProxy, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } - } - - /// - /// A class to help track the lifetime of a client-side RPC. - /// - /// The type of the request. - /// The type of the response. - private sealed class ClientRpcScope : RpcScope - where TRequest : class - where TResponse : class - { - /// - /// The metadata setter action. - /// - private static readonly Action MetadataSetter = (metadata, key, value) => { metadata.Add(new Metadata.Entry(key, value)); }; - - /// - /// The context. - /// - private readonly ClientInterceptorContext context; - - /// - /// The parent activity. - /// - private readonly Activity parentActivity; - - /// - /// Initializes a new instance of the class. - /// - /// The context. - /// The options. - public ClientRpcScope(ClientInterceptorContext context, ClientTracingInterceptorOptions options) - : base(context.Method?.FullName, options.RecordMessageEvents) - { - this.context = context; - - // Capture the current activity. - this.parentActivity = Activity.Current; - - // Short-circuit if nobody is listening - if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) - { - return; - } - - // This if block is for unit testing only. - IEnumerable> customTags = null; - if (options.ActivityIdentifierValue != default) - { - customTags = new List> - { - new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), - }; - } - - // We want to start an activity but don't activate it. - // After calling StartActivity, Activity.Current will be the new Activity. - // This scope is created synchronously before the RPC invocation starts and so this new Activity will overwrite - // the callers current Activity which isn't what we want. We need to restore the original immediately after doing this. - // If this call happened after some kind of async context await then a restore wouldn't be necessary. - // gRPC Core just doesn't have the hooks to do this as far as I can tell. - var rpcActivity = GrpcCoreInstrumentation.ActivitySource.StartActivity( - this.FullServiceName, - ActivityKind.Client, - this.parentActivity == default ? default : this.parentActivity.Context, - tags: customTags); - - if (rpcActivity == null) - { - return; - } - - var callOptions = context.Options; - - // Do NOT mutate incoming call headers, make a new copy. - // Retry mechanisms that may sit above this interceptor rely on an original set of call headers. - var metadata = new Metadata(); - if (callOptions.Headers != null) - { - for (var i = 0; i < callOptions.Headers.Count; i++) - { - metadata.Add(callOptions.Headers[i]); - } - } - - // replace the CallOptions - callOptions = callOptions.WithHeaders(metadata); - - this.SetActivity(rpcActivity); - options.Propagator.Inject(new PropagationContext(rpcActivity.Context, Baggage.Current), callOptions.Headers, MetadataSetter); - this.context = new ClientInterceptorContext(context.Method, context.Host, callOptions); - } - - /// - /// Gets the context. - /// - public ClientInterceptorContext Context => this.context; - - /// - /// Restores the parent activity. - /// - public void RestoreParentActivity() - { - Activity.Current = this.parentActivity; - } - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using global::Grpc.Core; + using global::Grpc.Core.Interceptors; + using OpenTelemetry.Context.Propagation; + + /// + /// A client interceptor that starts and stops an Activity for each outbound RPC. + /// + /// + public class ClientTracingInterceptor : Interceptor + { + /// + /// The options. + /// + private readonly ClientTracingInterceptorOptions options; + + /// + /// Initializes a new instance of the class. + /// + /// The options. + public ClientTracingInterceptor(ClientTracingInterceptorOptions options) + { + this.options = options ?? throw new ArgumentNullException(nameof(options)); + } + + /// + public override TResponse BlockingUnaryCall( + TRequest request, + ClientInterceptorContext context, + BlockingUnaryCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + rpcScope.RecordRequest(request); + var response = continuation(request, rpcScope.Context); + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); + rpcScope?.Dispose(); + } + } + + /// + public override AsyncUnaryCall AsyncUnaryCall( + TRequest request, + ClientInterceptorContext context, + AsyncUnaryCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + rpcScope.RecordRequest(request); + var responseContinuation = continuation(request, rpcScope.Context); + var responseAsync = responseContinuation.ResponseAsync.ContinueWith( + responseTask => + { + try + { + var response = responseTask.Result; + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (AggregateException ex) + { + rpcScope.CompleteWithException(ex.InnerException); + throw ex.InnerException; + } + }); + + return new AsyncUnaryCall( + responseAsync, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); + } + } + + /// + public override AsyncClientStreamingCall AsyncClientStreamingCall( + ClientInterceptorContext context, + AsyncClientStreamingCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + var responseContinuation = continuation(rpcScope.Context); + var clientRequestStreamProxy = new ClientStreamWriterProxy( + responseContinuation.RequestStream, + rpcScope.RecordRequest, + onException: rpcScope.CompleteWithException); + + var responseAsync = responseContinuation.ResponseAsync.ContinueWith( + responseTask => + { + try + { + var response = responseTask.Result; + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (AggregateException ex) + { + rpcScope.CompleteWithException(ex.InnerException); + throw ex.InnerException; + } + }); + + return new AsyncClientStreamingCall( + clientRequestStreamProxy, + responseAsync, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); + } + } + + /// + public override AsyncServerStreamingCall AsyncServerStreamingCall( + TRequest request, + ClientInterceptorContext context, + AsyncServerStreamingCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + rpcScope.RecordRequest(request); + var responseContinuation = continuation(request, rpcScope.Context); + + var responseStreamProxy = new AsyncStreamReaderProxy( + responseContinuation.ResponseStream, + rpcScope.RecordResponse, + rpcScope.Complete, + rpcScope.CompleteWithException); + + return new AsyncServerStreamingCall( + responseStreamProxy, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); + } + } + + /// + public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall( + ClientInterceptorContext context, + AsyncDuplexStreamingCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + var responseContinuation = continuation(rpcScope.Context); + + var requestStreamProxy = new ClientStreamWriterProxy( + responseContinuation.RequestStream, + rpcScope.RecordRequest, + onException: rpcScope.CompleteWithException); + + var responseStreamProxy = new AsyncStreamReaderProxy( + responseContinuation.ResponseStream, + rpcScope.RecordResponse, + rpcScope.Complete, + rpcScope.CompleteWithException); + + return new AsyncDuplexStreamingCall( + requestStreamProxy, + responseStreamProxy, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); + } + } + + /// + /// A class to help track the lifetime of a client-side RPC. + /// + /// The type of the request. + /// The type of the response. + private sealed class ClientRpcScope : RpcScope + where TRequest : class + where TResponse : class + { + /// + /// The metadata setter action. + /// + private static readonly Action MetadataSetter = (metadata, key, value) => { metadata.Add(new Metadata.Entry(key, value)); }; + + /// + /// The context. + /// + private readonly ClientInterceptorContext context; + + /// + /// The parent activity. + /// + private readonly Activity parentActivity; + + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// The options. + public ClientRpcScope(ClientInterceptorContext context, ClientTracingInterceptorOptions options) + : base(context.Method?.FullName, options.RecordMessageEvents) + { + this.context = context; + + // Capture the current activity. + this.parentActivity = Activity.Current; + + // Short-circuit if nobody is listening + if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) + { + return; + } + + // This if block is for unit testing only. + IEnumerable> customTags = null; + if (options.ActivityIdentifierValue != default) + { + customTags = new List> + { + new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), + }; + } + + // We want to start an activity but don't activate it. + // After calling StartActivity, Activity.Current will be the new Activity. + // This scope is created synchronously before the RPC invocation starts and so this new Activity will overwrite + // the callers current Activity which isn't what we want. We need to restore the original immediately after doing this. + // If this call happened after some kind of async context await then a restore wouldn't be necessary. + // gRPC Core just doesn't have the hooks to do this as far as I can tell. + var rpcActivity = GrpcCoreInstrumentation.ActivitySource.StartActivity( + this.FullServiceName, + ActivityKind.Client, + this.parentActivity == default ? default : this.parentActivity.Context, + tags: customTags); + + if (rpcActivity == null) + { + return; + } + + var callOptions = context.Options; + + // Do NOT mutate incoming call headers, make a new copy. + // Retry mechanisms that may sit above this interceptor rely on an original set of call headers. + var metadata = new Metadata(); + if (callOptions.Headers != null) + { + for (var i = 0; i < callOptions.Headers.Count; i++) + { + metadata.Add(callOptions.Headers[i]); + } + } + + // replace the CallOptions + callOptions = callOptions.WithHeaders(metadata); + + this.SetActivity(rpcActivity); + options.Propagator.Inject(new PropagationContext(rpcActivity.Context, Baggage.Current), callOptions.Headers, MetadataSetter); + this.context = new ClientInterceptorContext(context.Method, context.Host, callOptions); + } + + /// + /// Gets the context. + /// + public ClientInterceptorContext Context => this.context; + + /// + /// Restores the parent activity. + /// + public void RestoreParentActivity() + { + Activity.Current = this.parentActivity; + } + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 95c3d28599..bd60b6691b 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -1,42 +1,42 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using OpenTelemetry.Context.Propagation; - - /// - /// Options for the ClientTracingInterceptor. - /// - public class ClientTracingInterceptorOptions - { - /// - /// Gets or sets a value indicating whether or not to record individual message events. - /// - public bool RecordMessageEvents { get; set; } = false; - - /// - /// Gets the propagator. - /// - public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; - - /// - /// Gets or sets a custom identfier used during unit testing. - /// - internal Guid ActivityIdentifierValue { get; set; } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using OpenTelemetry.Context.Propagation; + + /// + /// Options for the ClientTracingInterceptor. + /// + public class ClientTracingInterceptorOptions + { + /// + /// Gets or sets a value indicating whether or not to record individual message events. + /// + public bool RecordMessageEvents { get; set; } = false; + + /// + /// Gets the propagator. + /// + public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; + + /// + /// Gets or sets a custom identfier used during unit testing. + /// + internal Guid ActivityIdentifierValue { get; set; } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/Extensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/Extensions.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs index e6e953c549..9ee660121a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/Extensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs @@ -1,47 +1,47 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - - /// - /// Other useful extensions. - /// - internal static class Extensions - { - /// - /// Builds an Action comprised of two calls to Dispose with best effort execution for the second disposable. - /// - /// The first. - /// The second. - /// An Action. - internal static Action WithBestEffortDispose(this IDisposable first, IDisposable second) - { - return () => - { - try - { - first.Dispose(); - } - finally - { - second.Dispose(); - } - }; - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + + /// + /// Other useful extensions. + /// + internal static class Extensions + { + /// + /// Builds an Action comprised of two calls to Dispose with best effort execution for the second disposable. + /// + /// The first. + /// The second. + /// An Action. + internal static Action WithBestEffortDispose(this IDisposable first, IDisposable second) + { + return () => + { + try + { + first.Dispose(); + } + finally + { + second.Dispose(); + } + }; + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index fa3af86915..86ebffa3d3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -1,48 +1,48 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Diagnostics; - using System.Reflection; - - /// - /// Instrumentation class Grpc.Core. - /// - internal static class GrpcCoreInstrumentation - { - /// - /// The assembly name. - /// - internal static readonly AssemblyName AssemblyName = typeof(GrpcCoreInstrumentation).Assembly.GetName(); - - /// - /// The activity source name. - /// - internal static readonly string ActivitySourceName = AssemblyName.Name; - - /// - /// The version. - /// - internal static readonly Version Version = AssemblyName.Version; - - /// - /// The activity source. - /// - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Diagnostics; + using System.Reflection; + + /// + /// Instrumentation class Grpc.Core. + /// + internal static class GrpcCoreInstrumentation + { + /// + /// The assembly name. + /// + internal static readonly AssemblyName AssemblyName = typeof(GrpcCoreInstrumentation).Assembly.GetName(); + + /// + /// The activity source name. + /// + internal static readonly string ActivitySourceName = AssemblyName.Name; + + /// + /// The version. + /// + internal static readonly Version Version = AssemblyName.Version; + + /// + /// The activity source. + /// + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj rename to src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index bdba9cc4c3..3803cabb55 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/OpenTelemetry.Contrib.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -1,13 +1,13 @@ - - - netstandard2.0 - .NET gRPC Core based client and server interceptors for OpenTelemetry. - $(PackageTags);gRPC Core;interceptors - Instrumentation.GrpcCore- - - - - - - - + + + netstandard2.0 + .NET gRPC Core based client and server interceptors for OpenTelemetry. + $(PackageTags);gRPC Core;interceptors + Instrumentation.GrpcCore- + + + + + + + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md similarity index 79% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/README.md rename to src/OpenTelemetry.Instrumentation.GrpcCore/README.md index 401d517f65..5c629b815c 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -1,5 +1,8 @@ # gRPC Core-based Client and Server Interceptors for OpenTelemetry .NET +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) + Adds OpenTelemetry instrumentation for gRPC Core-based client and server calls. gRPC Core is the predecessor to ASP.NET Core gRPC. See @@ -15,7 +18,7 @@ semantic RPC specification -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Threading; - using global::Grpc.Core; - using Google.Protobuf; - using OpenTelemetry.Trace; - - /// - /// A class to help track the lifetime of an RPC. - /// - /// The type of the request. - /// The type of the response. - internal abstract class RpcScope : IDisposable - where TRequest : class - where TResponse : class - { - /// - /// The record message events flag. - /// - private readonly bool recordMessageEvents; - - /// - /// The RPC activity. - /// - private Activity activity; - - /// - /// The complete flag. - /// - private long complete = 0; - - /// - /// The request message counter. - /// - private int requestMessageCounter; - - /// - /// The response counter. - /// - private int responseMessageCounter; - - /// - /// Initializes a new instance of the class. - /// - /// Full name of the service. - /// if set to true [record message events]. - protected RpcScope(string fullServiceName, bool recordMessageEvents) - { - this.FullServiceName = fullServiceName?.TrimStart('/') ?? "unknownservice/unknownmethod"; - this.recordMessageEvents = recordMessageEvents; - } - - /// - /// Gets the full name of the service. - /// - protected string FullServiceName { get; } - - /// - /// Records a request message. - /// - /// The request. - public void RecordRequest(TRequest request) - { - this.requestMessageCounter++; - - if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) - { - return; - } - - this.AddMessageEvent(typeof(TRequest).Name, request as IMessage, request: true); - } - - /// - /// Records a response message. - /// - /// The response. - public void RecordResponse(TResponse response) - { - this.responseMessageCounter++; - - if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) - { - return; - } - - this.AddMessageEvent(typeof(TResponse).Name, response as IMessage, request: false); - } - - /// - /// Completes the RPC. - /// - public void Complete() - { - if (this.activity == null) - { - return; - } - - // The overall Span status should remain unset however the grpc status code attribute is required - this.StopActivity((int)Grpc.Core.StatusCode.OK); - } - - /// - /// Records a failed RPC. - /// - /// The exception. - public void CompleteWithException(Exception exception) - { - if (this.activity == null) - { - return; - } - - var grpcStatusCode = Grpc.Core.StatusCode.Unknown; - var description = exception.Message; - - if (exception is RpcException rpcException) - { - grpcStatusCode = rpcException.StatusCode; - description = rpcException.Message; - } - - this.StopActivity((int)grpcStatusCode, description); - } - - /// - public void Dispose() - { - if (this.activity == null) - { - return; - } - - // If not already completed this will mark the Activity as cancelled. - this.StopActivity((int)Grpc.Core.StatusCode.Cancelled); - } - - /// - /// Sets the activity for this RPC scope. Should only be called once. - /// - /// The activity. - protected void SetActivity(Activity activity) - { - this.activity = activity; - - if (this.activity == null || !this.activity.IsAllDataRequested) - { - return; - } - - // assign some reasonable defaults - var rpcService = this.FullServiceName; - var rpcMethod = this.FullServiceName; - - // split the full service name by the slash - var parts = this.FullServiceName.Split('/'); - if (parts.Length == 2) - { - rpcService = parts[0]; - rpcMethod = parts[1]; - } - - this.activity.SetTag(SemanticConventions.AttributeRpcSystem, "grpc"); - this.activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); - this.activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); - } - - /// - /// Stops the activity. - /// - /// The status code. - /// The description, if any. - private void StopActivity(int statusCode, string statusDescription = null) - { - if (Interlocked.CompareExchange(ref this.complete, 1, 0) == 0) - { - this.activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, statusCode); - if (statusDescription != null) - { - this.activity.SetStatus(OpenTelemetry.Trace.Status.Error.WithDescription(statusDescription)); - } - - this.activity.Stop(); - } - } - - /// - /// Adds a message event. - /// - /// Name of the event. - /// The message. - /// if true this is a request message. - private void AddMessageEvent(string eventName, IMessage message, bool request) - { - var messageSize = message.CalculateSize(); - - var attributes = new ActivityTagsCollection(new KeyValuePair[5] - { - new KeyValuePair("name", "message"), - new KeyValuePair(SemanticConventions.AttributeMessageType, request ? "SENT" : "RECEIVED"), - new KeyValuePair(SemanticConventions.AttributeMessageID, request ? this.requestMessageCounter : this.responseMessageCounter), - - // TODO how to get the real compressed or uncompressed sizes - new KeyValuePair(SemanticConventions.AttributeMessageCompressedSize, messageSize), - new KeyValuePair(SemanticConventions.AttributeMessageUncompressedSize, messageSize), - }); - - this.activity.AddEvent(new ActivityEvent(eventName, default, attributes)); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Threading; + using global::Grpc.Core; + using Google.Protobuf; + using OpenTelemetry.Trace; + + /// + /// A class to help track the lifetime of an RPC. + /// + /// The type of the request. + /// The type of the response. + internal abstract class RpcScope : IDisposable + where TRequest : class + where TResponse : class + { + /// + /// The record message events flag. + /// + private readonly bool recordMessageEvents; + + /// + /// The RPC activity. + /// + private Activity activity; + + /// + /// The complete flag. + /// + private long complete = 0; + + /// + /// The request message counter. + /// + private int requestMessageCounter; + + /// + /// The response counter. + /// + private int responseMessageCounter; + + /// + /// Initializes a new instance of the class. + /// + /// Full name of the service. + /// if set to true [record message events]. + protected RpcScope(string fullServiceName, bool recordMessageEvents) + { + this.FullServiceName = fullServiceName?.TrimStart('/') ?? "unknownservice/unknownmethod"; + this.recordMessageEvents = recordMessageEvents; + } + + /// + /// Gets the full name of the service. + /// + protected string FullServiceName { get; } + + /// + /// Records a request message. + /// + /// The request. + public void RecordRequest(TRequest request) + { + this.requestMessageCounter++; + + if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) + { + return; + } + + this.AddMessageEvent(typeof(TRequest).Name, request as IMessage, request: true); + } + + /// + /// Records a response message. + /// + /// The response. + public void RecordResponse(TResponse response) + { + this.responseMessageCounter++; + + if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) + { + return; + } + + this.AddMessageEvent(typeof(TResponse).Name, response as IMessage, request: false); + } + + /// + /// Completes the RPC. + /// + public void Complete() + { + if (this.activity == null) + { + return; + } + + // The overall Span status should remain unset however the grpc status code attribute is required + this.StopActivity((int)Grpc.Core.StatusCode.OK); + } + + /// + /// Records a failed RPC. + /// + /// The exception. + public void CompleteWithException(Exception exception) + { + if (this.activity == null) + { + return; + } + + var grpcStatusCode = Grpc.Core.StatusCode.Unknown; + var description = exception.Message; + + if (exception is RpcException rpcException) + { + grpcStatusCode = rpcException.StatusCode; + description = rpcException.Message; + } + + this.StopActivity((int)grpcStatusCode, description); + } + + /// + public void Dispose() + { + if (this.activity == null) + { + return; + } + + // If not already completed this will mark the Activity as cancelled. + this.StopActivity((int)Grpc.Core.StatusCode.Cancelled); + } + + /// + /// Sets the activity for this RPC scope. Should only be called once. + /// + /// The activity. + protected void SetActivity(Activity activity) + { + this.activity = activity; + + if (this.activity == null || !this.activity.IsAllDataRequested) + { + return; + } + + // assign some reasonable defaults + var rpcService = this.FullServiceName; + var rpcMethod = this.FullServiceName; + + // split the full service name by the slash + var parts = this.FullServiceName.Split('/'); + if (parts.Length == 2) + { + rpcService = parts[0]; + rpcMethod = parts[1]; + } + + this.activity.SetTag(SemanticConventions.AttributeRpcSystem, "grpc"); + this.activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); + this.activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + } + + /// + /// Stops the activity. + /// + /// The status code. + /// The description, if any. + private void StopActivity(int statusCode, string statusDescription = null) + { + if (Interlocked.CompareExchange(ref this.complete, 1, 0) == 0) + { + this.activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, statusCode); + if (statusDescription != null) + { + this.activity.SetStatus(OpenTelemetry.Trace.Status.Error.WithDescription(statusDescription)); + } + + this.activity.Stop(); + } + } + + /// + /// Adds a message event. + /// + /// Name of the event. + /// The message. + /// if true this is a request message. + private void AddMessageEvent(string eventName, IMessage message, bool request) + { + var messageSize = message.CalculateSize(); + + var attributes = new ActivityTagsCollection(new KeyValuePair[5] + { + new KeyValuePair("name", "message"), + new KeyValuePair(SemanticConventions.AttributeMessageType, request ? "SENT" : "RECEIVED"), + new KeyValuePair(SemanticConventions.AttributeMessageID, request ? this.requestMessageCounter : this.responseMessageCounter), + + // TODO how to get the real compressed or uncompressed sizes + new KeyValuePair(SemanticConventions.AttributeMessageCompressedSize, messageSize), + new KeyValuePair(SemanticConventions.AttributeMessageUncompressedSize, messageSize), + }); + + this.activity.AddEvent(new ActivityEvent(eventName, default, attributes)); + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/SemanticConventions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/SemanticConventions.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs index e8376c0202..3a023bf6cb 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/SemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs @@ -1,40 +1,40 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - /// - /// Semantic conventions. - /// - internal static class SemanticConventions - { -#pragma warning disable SA1600 // Elements should be documented - public const string AttributeRpcSystem = "rpc.system"; - public const string AttributeRpcService = "rpc.service"; - public const string AttributeRpcMethod = "rpc.method"; - public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; - public const string AttributeMessageType = "message.type"; - public const string AttributeMessageID = "message.id"; - public const string AttributeMessageCompressedSize = "message.compressed_size"; - public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; - public const string AttributeOtelStatusCode = "otel.status_code"; - public const string AttributeOtelStatusDescription = "otel.status_description"; - - // Used for unit testing only. - internal const string AttributeActivityIdentifier = "activityidentifier"; -#pragma warning restore SA1600 // Elements should be documented - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + /// + /// Semantic conventions. + /// + internal static class SemanticConventions + { +#pragma warning disable SA1600 // Elements should be documented + public const string AttributeRpcSystem = "rpc.system"; + public const string AttributeRpcService = "rpc.service"; + public const string AttributeRpcMethod = "rpc.method"; + public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; + public const string AttributeMessageType = "message.type"; + public const string AttributeMessageID = "message.id"; + public const string AttributeMessageCompressedSize = "message.compressed_size"; + public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; + public const string AttributeOtelStatusCode = "otel.status_code"; + public const string AttributeOtelStatusDescription = "otel.status_description"; + + // Used for unit testing only. + internal const string AttributeActivityIdentifier = "activityidentifier"; +#pragma warning restore SA1600 // Elements should be documented + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index 31d6182a9c..111e617f31 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -1,69 +1,69 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Threading.Tasks; - using global::Grpc.Core; - - /// - /// A proxy server stream writer. - /// - /// - /// Borrowed heavily from - /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingServerStreamWriter.cs. - /// - /// The message type. - /// - internal class ServerStreamWriterProxy : IServerStreamWriter - { - /// - /// The writer. - /// - private readonly IServerStreamWriter writer; - - /// - /// The on write action. - /// - private readonly Action onWrite; - - /// - /// Initializes a new instance of the class. - /// - /// The writer. - /// The on write action, if any. - public ServerStreamWriterProxy(IServerStreamWriter writer, Action onWrite = null) - { - this.writer = writer; - this.onWrite = onWrite; - } - - /// - public WriteOptions WriteOptions - { - get => this.writer.WriteOptions; - set => this.writer.WriteOptions = value; - } - - /// - public Task WriteAsync(T message) - { - this.onWrite?.Invoke(message); - return this.writer.WriteAsync(message); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Threading.Tasks; + using global::Grpc.Core; + + /// + /// A proxy server stream writer. + /// + /// + /// Borrowed heavily from + /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingServerStreamWriter.cs. + /// + /// The message type. + /// + internal class ServerStreamWriterProxy : IServerStreamWriter + { + /// + /// The writer. + /// + private readonly IServerStreamWriter writer; + + /// + /// The on write action. + /// + private readonly Action onWrite; + + /// + /// Initializes a new instance of the class. + /// + /// The writer. + /// The on write action, if any. + public ServerStreamWriterProxy(IServerStreamWriter writer, Action onWrite = null) + { + this.writer = writer; + this.onWrite = onWrite; + } + + /// + public WriteOptions WriteOptions + { + get => this.writer.WriteOptions; + set => this.writer.WriteOptions = value; + } + + /// + public Task WriteAsync(T message) + { + this.onWrite?.Invoke(message); + return this.writer.WriteAsync(message); + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerTracingInterceptor.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index 48ac2ad829..7d8045ae15 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -1,226 +1,226 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Threading.Tasks; - using global::Grpc.Core; - using global::Grpc.Core.Interceptors; - using OpenTelemetry.Context.Propagation; - - /// - /// A service interceptor that starts and stops an Activity for each inbound RPC. - /// - /// - public class ServerTracingInterceptor : Interceptor - { - /// - /// The options. - /// - private readonly ServerTracingInterceptorOptions options; - - /// - /// Initializes a new instance of the class. - /// - /// The options. - public ServerTracingInterceptor(ServerTracingInterceptorOptions options) - { - this.options = options ?? throw new ArgumentNullException(nameof(options)); - } - - /// - public override async Task UnaryServerHandler( - TRequest request, - ServerCallContext context, - UnaryServerMethod continuation) - { - using var rpcScope = new ServerRpcScope(context, this.options); - - try - { - rpcScope.RecordRequest(request); - var response = await continuation(request, context).ConfigureAwait(false); - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } - } - - /// - public override async Task ClientStreamingServerHandler( - IAsyncStreamReader requestStream, - ServerCallContext context, - ClientStreamingServerMethod continuation) - { - using var rpcScope = new ServerRpcScope(context, this.options); - - try - { - var requestStreamReaderProxy = new AsyncStreamReaderProxy( - requestStream, - rpcScope.RecordRequest); - - var response = await continuation(requestStreamReaderProxy, context).ConfigureAwait(false); - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } - } - - /// - public override async Task ServerStreamingServerHandler( - TRequest request, - IServerStreamWriter responseStream, - ServerCallContext context, - ServerStreamingServerMethod continuation) - { - using var rpcScope = new ServerRpcScope(context, this.options); - - try - { - rpcScope.RecordRequest(request); - - var responseStreamProxy = new ServerStreamWriterProxy( - responseStream, - rpcScope.RecordResponse); - - await continuation(request, responseStreamProxy, context).ConfigureAwait(false); - rpcScope.Complete(); - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } - } - - /// - public override async Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation) - { - using var rpcScope = new ServerRpcScope(context, this.options); - - try - { - var requestStreamReaderProxy = new AsyncStreamReaderProxy( - requestStream, - rpcScope.RecordRequest); - - var responseStreamProxy = new ServerStreamWriterProxy( - responseStream, - rpcScope.RecordResponse); - - await continuation(requestStreamReaderProxy, responseStreamProxy, context).ConfigureAwait(false); - rpcScope.Complete(); - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } - } - - /// - /// A class to help track the lifetime of a service-side RPC. - /// - /// The type of the request. - /// The type of the response. - private class ServerRpcScope : RpcScope - where TRequest : class - where TResponse : class - { - /// - /// The metadata setter action. - /// - private static readonly Func> MetadataGetter = (metadata, key) => - { - for (var i = 0; i < metadata.Count; i++) - { - var entry = metadata[i]; - if (entry.Key.Equals(key)) - { - return new string[1] { entry.Value }; - } - } - - return Enumerable.Empty(); - }; - - /// - /// Initializes a new instance of the class. - /// - /// The context. - /// The options. - public ServerRpcScope(ServerCallContext context, ServerTracingInterceptorOptions options) - : base(context.Method, options.RecordMessageEvents) - { - if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) - { - return; - } - - var currentContext = Activity.Current?.Context; - - // Extract the SpanContext, if any from the headers - var metadata = context.RequestHeaders; - if (metadata != null) - { - var propagationContext = options.Propagator.Extract(new PropagationContext(currentContext ?? default, Baggage.Current), metadata, MetadataGetter); - if (propagationContext.ActivityContext.IsValid()) - { - currentContext = propagationContext.ActivityContext; - } - - if (propagationContext.Baggage != default) - { - Baggage.Current = propagationContext.Baggage; - } - } - - // This if block is for unit testing only. - IEnumerable> customTags = null; - if (options.ActivityIdentifierValue != default) - { - customTags = new List> - { - new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), - }; - } - - var activity = GrpcCoreInstrumentation.ActivitySource.StartActivity( - this.FullServiceName, - ActivityKind.Server, - currentContext ?? default, - tags: customTags); - - this.SetActivity(activity); - } - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Threading.Tasks; + using global::Grpc.Core; + using global::Grpc.Core.Interceptors; + using OpenTelemetry.Context.Propagation; + + /// + /// A service interceptor that starts and stops an Activity for each inbound RPC. + /// + /// + public class ServerTracingInterceptor : Interceptor + { + /// + /// The options. + /// + private readonly ServerTracingInterceptorOptions options; + + /// + /// Initializes a new instance of the class. + /// + /// The options. + public ServerTracingInterceptor(ServerTracingInterceptorOptions options) + { + this.options = options ?? throw new ArgumentNullException(nameof(options)); + } + + /// + public override async Task UnaryServerHandler( + TRequest request, + ServerCallContext context, + UnaryServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); + + try + { + rpcScope.RecordRequest(request); + var response = await continuation(request, context).ConfigureAwait(false); + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (Exception e) + { + rpcScope.CompleteWithException(e); + throw; + } + } + + /// + public override async Task ClientStreamingServerHandler( + IAsyncStreamReader requestStream, + ServerCallContext context, + ClientStreamingServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); + + try + { + var requestStreamReaderProxy = new AsyncStreamReaderProxy( + requestStream, + rpcScope.RecordRequest); + + var response = await continuation(requestStreamReaderProxy, context).ConfigureAwait(false); + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (Exception e) + { + rpcScope.CompleteWithException(e); + throw; + } + } + + /// + public override async Task ServerStreamingServerHandler( + TRequest request, + IServerStreamWriter responseStream, + ServerCallContext context, + ServerStreamingServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); + + try + { + rpcScope.RecordRequest(request); + + var responseStreamProxy = new ServerStreamWriterProxy( + responseStream, + rpcScope.RecordResponse); + + await continuation(request, responseStreamProxy, context).ConfigureAwait(false); + rpcScope.Complete(); + } + catch (Exception e) + { + rpcScope.CompleteWithException(e); + throw; + } + } + + /// + public override async Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); + + try + { + var requestStreamReaderProxy = new AsyncStreamReaderProxy( + requestStream, + rpcScope.RecordRequest); + + var responseStreamProxy = new ServerStreamWriterProxy( + responseStream, + rpcScope.RecordResponse); + + await continuation(requestStreamReaderProxy, responseStreamProxy, context).ConfigureAwait(false); + rpcScope.Complete(); + } + catch (Exception e) + { + rpcScope.CompleteWithException(e); + throw; + } + } + + /// + /// A class to help track the lifetime of a service-side RPC. + /// + /// The type of the request. + /// The type of the response. + private class ServerRpcScope : RpcScope + where TRequest : class + where TResponse : class + { + /// + /// The metadata setter action. + /// + private static readonly Func> MetadataGetter = (metadata, key) => + { + for (var i = 0; i < metadata.Count; i++) + { + var entry = metadata[i]; + if (entry.Key.Equals(key)) + { + return new string[1] { entry.Value }; + } + } + + return Enumerable.Empty(); + }; + + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// The options. + public ServerRpcScope(ServerCallContext context, ServerTracingInterceptorOptions options) + : base(context.Method, options.RecordMessageEvents) + { + if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) + { + return; + } + + var currentContext = Activity.Current?.Context; + + // Extract the SpanContext, if any from the headers + var metadata = context.RequestHeaders; + if (metadata != null) + { + var propagationContext = options.Propagator.Extract(new PropagationContext(currentContext ?? default, Baggage.Current), metadata, MetadataGetter); + if (propagationContext.ActivityContext.IsValid()) + { + currentContext = propagationContext.ActivityContext; + } + + if (propagationContext.Baggage != default) + { + Baggage.Current = propagationContext.Baggage; + } + } + + // This if block is for unit testing only. + IEnumerable> customTags = null; + if (options.ActivityIdentifierValue != default) + { + customTags = new List> + { + new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), + }; + } + + var activity = GrpcCoreInstrumentation.ActivitySource.StartActivity( + this.FullServiceName, + ActivityKind.Server, + currentContext ?? default, + tags: customTags); + + this.SetActivity(activity); + } + } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index 8b45f1d637..59ec31dd29 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -1,42 +1,42 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore -{ - using System; - using OpenTelemetry.Context.Propagation; - - /// - /// Options for the ServerTracingInterceptor. - /// - public class ServerTracingInterceptorOptions - { - /// - /// Gets or sets a value indicating whether or not to record individual message events. - /// - public bool RecordMessageEvents { get; set; } = false; - - /// - /// Gets the propagator. - /// - public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; - - /// - /// Gets or sets a custom identfier used during unit testing. - /// - internal Guid ActivityIdentifierValue { get; set; } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.GrpcCore +{ + using System; + using OpenTelemetry.Context.Propagation; + + /// + /// Options for the ServerTracingInterceptor. + /// + public class ServerTracingInterceptorOptions + { + /// + /// Gets or sets a value indicating whether or not to record individual message events. + /// + public bool RecordMessageEvents { get; set; } = false; + + /// + /// Gets the propagator. + /// + public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; + + /// + /// Gets or sets a custom identfier used during unit testing. + /// + internal Guid ActivityIdentifierValue { get; set; } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs index 81cc8ea9f8..8debeee10f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs @@ -1,43 +1,43 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Trace -{ - using System; - using OpenTelemetry.Contrib.Instrumentation.GrpcCore; - - /// - /// OpenTelemetry builder extensions to simplify registration of Grpc.Core based interceptors. - /// - public static class TracerProviderBuilderExtensions - { - /// - /// Configures OpenTelemetry to listen for the Activities created by the client and server interceptors. - /// - /// The builder. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddGrpcCoreInstrumentation( - this TracerProviderBuilder builder) - { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - return builder.AddSource(GrpcCoreInstrumentation.ActivitySourceName); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Trace +{ + using System; + using OpenTelemetry.Instrumentation.GrpcCore; + + /// + /// OpenTelemetry builder extensions to simplify registration of Grpc.Core based interceptors. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Configures OpenTelemetry to listen for the Activities created by the client and server interceptors. + /// + /// The builder. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcCoreInstrumentation( + this TracerProviderBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + return builder.AddSource(GrpcCoreInstrumentation.ActivitySourceName); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs similarity index 96% rename from test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/FoobarService.cs rename to test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index c07fbe4745..6f5369dbba 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -1,284 +1,284 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; -using Google.Protobuf; -using Grpc.Core; -using Grpc.Core.Interceptors; - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore.Test -{ - /// - /// Test implementation of foobar. - /// - internal class FoobarService : Foobar.FoobarBase - { - /// - /// Default traceparent header value with the sampling bit on. - /// - internal static readonly string DefaultTraceparentWithSampling = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; - - /// - /// The default parent from a traceparent header. - /// - internal static readonly ActivityContext DefaultParentFromTraceparentHeader = ActivityContext.Parse(DefaultTraceparentWithSampling, null); - - /// - /// The default request message. - /// - internal static readonly FoobarRequest DefaultRequestMessage = new FoobarRequest { Message = "foo" }; - - /// - /// The default request message size. - /// - internal static readonly int DefaultRequestMessageSize = ((IMessage)DefaultRequestMessage).CalculateSize(); - - /// - /// The default response message. - /// - internal static readonly FoobarResponse DefaultResponseMessage = new FoobarResponse { Message = "bar" }; - - /// - /// The default request message size. - /// - internal static readonly int DefaultResponseMessageSize = ((IMessage)DefaultResponseMessage).CalculateSize(); - - /// - /// The request header fail with status code. - /// - internal static readonly string RequestHeaderFailWithStatusCode = "failurestatuscode"; - - /// - /// The request header error description. - /// - internal static readonly string RequestHeaderErrorDescription = "failuredescription"; - - /// - /// Starts the specified service. - /// - /// The server interceptor. - /// A tuple. - public static DisposableServer Start(Interceptor serverInterceptor = null) - { - // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 - var serviceDefinition = Foobar.BindService(new FoobarService()); - if (serverInterceptor != null) - { - serviceDefinition = serviceDefinition.Intercept(serverInterceptor); - } - - var server = new Server - { - Ports = { { "localhost", ServerPort.PickUnused, ServerCredentials.Insecure } }, - Services = { serviceDefinition }, - }; - - server.Start(); - var serverUriString = new Uri("dns:localhost:" + server.Ports.Single().BoundPort).ToString(); - - return new DisposableServer(server, serverUriString); - } - - /// - /// Builds the default RPC client. - /// - /// The target. - /// The client tracing interceptor, if any. - /// The additional metadata, if any. - /// - /// The gRPC client. - /// - public static Foobar.FoobarClient ConstructRpcClient( - string target, - ClientTracingInterceptor clientTracingInterceptor = null, - IEnumerable additionalMetadata = null) - { - var channel = new Channel(target, ChannelCredentials.Insecure); - var callInvoker = channel.CreateCallInvoker(); - - if (clientTracingInterceptor != null) - { - callInvoker = callInvoker.Intercept(clientTracingInterceptor); - } - - // The metadata injector comes first - if (additionalMetadata != null) - { - callInvoker = callInvoker.Intercept( - metadata => - { - foreach (var m in additionalMetadata) - { - metadata.Add(m); - } - - return metadata; - }); - } - - return new Foobar.FoobarClient(callInvoker); - } - - /// - /// Makes a unary asynchronous request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeUnaryAsyncRequest(Foobar.FoobarClient client, Metadata additionalMetadata) - { - using var call = client.UnaryAsync(DefaultRequestMessage, headers: additionalMetadata); - _ = await call.ResponseAsync.ConfigureAwait(false); - } - - /// - /// Makes a client streaming request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeClientStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) - { - using var call = client.ClientStreaming(headers: additionalMetadata); - await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); - await call.RequestStream.CompleteAsync().ConfigureAwait(false); - _ = await call.ResponseAsync.ConfigureAwait(false); - } - - /// - /// Makes a server streaming request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeServerStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) - { - using var call = client.ServerStreaming(DefaultRequestMessage, headers: additionalMetadata); - while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) - { - } - } - - /// - /// Makes a duplex streaming request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeDuplexStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) - { - using var call = client.DuplexStreaming(headers: additionalMetadata); - await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); - await call.RequestStream.CompleteAsync().ConfigureAwait(false); - - while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) - { - } - } - - /// - public override Task Unary(FoobarRequest request, ServerCallContext context) - { - this.CheckForFailure(context); - - return Task.FromResult(DefaultResponseMessage); - } - - /// - public override async Task ClientStreaming(IAsyncStreamReader requestStream, ServerCallContext context) - { - this.CheckForFailure(context); - - while (await requestStream.MoveNext().ConfigureAwait(false)) - { - } - - return DefaultResponseMessage; - } - - /// - public override async Task ServerStreaming(FoobarRequest request, IServerStreamWriter responseStream, ServerCallContext context) - { - this.CheckForFailure(context); - - await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); - } - - /// - public override async Task DuplexStreaming(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) - { - this.CheckForFailure(context); - - while (await requestStream.MoveNext().ConfigureAwait(false)) - { - } - - await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); - } - - /// - /// Throws if we see some by-convention request metadata. - /// - /// The context. - private void CheckForFailure(ServerCallContext context) - { - var failureStatusCodeString = context.RequestHeaders.GetValue(RequestHeaderFailWithStatusCode); - var failureDescription = context.RequestHeaders.GetValue(RequestHeaderErrorDescription); - if (failureStatusCodeString != null) - { - throw new RpcException(new Status((StatusCode)Enum.Parse(typeof(StatusCode), failureStatusCodeString), failureDescription ?? string.Empty)); - } - } - - /// - /// Wraps server shutdown with an IDisposable pattern. - /// - /// - public sealed class DisposableServer : IDisposable - { - /// - /// The server. - /// - private readonly Server server; - - /// - /// Initializes a new instance of the class. - /// - /// The server. - /// The URI string. - public DisposableServer(Server server, string uriString) - { - this.server = server; - this.UriString = uriString; - } - - /// - /// Gets the URI string. - /// - public string UriString { get; } - - /// - public void Dispose() - { - this.server.ShutdownAsync().Wait(); - } - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Google.Protobuf; +using Grpc.Core; +using Grpc.Core.Interceptors; + +namespace OpenTelemetry.Instrumentation.GrpcCore.Test +{ + /// + /// Test implementation of foobar. + /// + internal class FoobarService : Foobar.FoobarBase + { + /// + /// Default traceparent header value with the sampling bit on. + /// + internal static readonly string DefaultTraceparentWithSampling = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; + + /// + /// The default parent from a traceparent header. + /// + internal static readonly ActivityContext DefaultParentFromTraceparentHeader = ActivityContext.Parse(DefaultTraceparentWithSampling, null); + + /// + /// The default request message. + /// + internal static readonly FoobarRequest DefaultRequestMessage = new FoobarRequest { Message = "foo" }; + + /// + /// The default request message size. + /// + internal static readonly int DefaultRequestMessageSize = ((IMessage)DefaultRequestMessage).CalculateSize(); + + /// + /// The default response message. + /// + internal static readonly FoobarResponse DefaultResponseMessage = new FoobarResponse { Message = "bar" }; + + /// + /// The default request message size. + /// + internal static readonly int DefaultResponseMessageSize = ((IMessage)DefaultResponseMessage).CalculateSize(); + + /// + /// The request header fail with status code. + /// + internal static readonly string RequestHeaderFailWithStatusCode = "failurestatuscode"; + + /// + /// The request header error description. + /// + internal static readonly string RequestHeaderErrorDescription = "failuredescription"; + + /// + /// Starts the specified service. + /// + /// The server interceptor. + /// A tuple. + public static DisposableServer Start(Interceptor serverInterceptor = null) + { + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + var serviceDefinition = Foobar.BindService(new FoobarService()); + if (serverInterceptor != null) + { + serviceDefinition = serviceDefinition.Intercept(serverInterceptor); + } + + var server = new Server + { + Ports = { { "localhost", ServerPort.PickUnused, ServerCredentials.Insecure } }, + Services = { serviceDefinition }, + }; + + server.Start(); + var serverUriString = new Uri("dns:localhost:" + server.Ports.Single().BoundPort).ToString(); + + return new DisposableServer(server, serverUriString); + } + + /// + /// Builds the default RPC client. + /// + /// The target. + /// The client tracing interceptor, if any. + /// The additional metadata, if any. + /// + /// The gRPC client. + /// + public static Foobar.FoobarClient ConstructRpcClient( + string target, + ClientTracingInterceptor clientTracingInterceptor = null, + IEnumerable additionalMetadata = null) + { + var channel = new Channel(target, ChannelCredentials.Insecure); + var callInvoker = channel.CreateCallInvoker(); + + if (clientTracingInterceptor != null) + { + callInvoker = callInvoker.Intercept(clientTracingInterceptor); + } + + // The metadata injector comes first + if (additionalMetadata != null) + { + callInvoker = callInvoker.Intercept( + metadata => + { + foreach (var m in additionalMetadata) + { + metadata.Add(m); + } + + return metadata; + }); + } + + return new Foobar.FoobarClient(callInvoker); + } + + /// + /// Makes a unary asynchronous request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeUnaryAsyncRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.UnaryAsync(DefaultRequestMessage, headers: additionalMetadata); + _ = await call.ResponseAsync.ConfigureAwait(false); + } + + /// + /// Makes a client streaming request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeClientStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.ClientStreaming(headers: additionalMetadata); + await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); + await call.RequestStream.CompleteAsync().ConfigureAwait(false); + _ = await call.ResponseAsync.ConfigureAwait(false); + } + + /// + /// Makes a server streaming request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeServerStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.ServerStreaming(DefaultRequestMessage, headers: additionalMetadata); + while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) + { + } + } + + /// + /// Makes a duplex streaming request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeDuplexStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.DuplexStreaming(headers: additionalMetadata); + await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); + await call.RequestStream.CompleteAsync().ConfigureAwait(false); + + while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) + { + } + } + + /// + public override Task Unary(FoobarRequest request, ServerCallContext context) + { + this.CheckForFailure(context); + + return Task.FromResult(DefaultResponseMessage); + } + + /// + public override async Task ClientStreaming(IAsyncStreamReader requestStream, ServerCallContext context) + { + this.CheckForFailure(context); + + while (await requestStream.MoveNext().ConfigureAwait(false)) + { + } + + return DefaultResponseMessage; + } + + /// + public override async Task ServerStreaming(FoobarRequest request, IServerStreamWriter responseStream, ServerCallContext context) + { + this.CheckForFailure(context); + + await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); + } + + /// + public override async Task DuplexStreaming(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) + { + this.CheckForFailure(context); + + while (await requestStream.MoveNext().ConfigureAwait(false)) + { + } + + await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); + } + + /// + /// Throws if we see some by-convention request metadata. + /// + /// The context. + private void CheckForFailure(ServerCallContext context) + { + var failureStatusCodeString = context.RequestHeaders.GetValue(RequestHeaderFailWithStatusCode); + var failureDescription = context.RequestHeaders.GetValue(RequestHeaderErrorDescription); + if (failureStatusCodeString != null) + { + throw new RpcException(new Status((StatusCode)Enum.Parse(typeof(StatusCode), failureStatusCodeString), failureDescription ?? string.Empty)); + } + } + + /// + /// Wraps server shutdown with an IDisposable pattern. + /// + /// + public sealed class DisposableServer : IDisposable + { + /// + /// The server. + /// + private readonly Server server; + + /// + /// Initializes a new instance of the class. + /// + /// The server. + /// The URI string. + public DisposableServer(Server server, string uriString) + { + this.server = server; + this.UriString = uriString; + } + + /// + /// Gets the URI string. + /// + public string UriString { get; } + + /// + public void Dispose() + { + this.server.ShutdownAsync().Wait(); + } + } + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs rename to test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 06fc7d51a2..eedb99efad 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -1,530 +1,530 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; -using Grpc.Core; -using Grpc.Core.Interceptors; -using Moq; -using OpenTelemetry.Context.Propagation; -using Xunit; - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore.Test -{ - /// - /// Grpc Core client interceptor tests. - /// - public class GrpcCoreClientInterceptorTests - { - /// - /// A bogus server uri. - /// - private static readonly string BogusServerUri = "dns:i.dont.exist:77923"; - - /// - /// The default metadata func. - /// - private static readonly Func DefaultMetadataFunc = () => new Metadata { new Metadata.Entry("foo", "bar") }; - - /// - /// Validates a successful AsyncUnary call. - /// - /// A task. - [Fact] - public async Task AsyncUnarySuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } - - /// - /// Validates a failed AsyncUnary call because the endpoint isn't there. - /// - /// A task. - [Fact] - public async Task AsyncUnaryUnavailable() - { - await this.TestHandlerFailure( - FoobarService.MakeUnaryAsyncRequest, - StatusCode.Unavailable, - validateErrorDescription: false, - BogusServerUri).ConfigureAwait(false); - } - - /// - /// Validates a failed AsyncUnary call because the service returned an error. - /// - /// A task. - [Fact] - public async Task AsyncUnaryFail() - { - await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed AsyncUnary call because the client is disposed before completing the RPC. - /// - [Fact] - public void AsyncUnaryDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); - } - - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } - - /// - /// Validates a successful ClientStreaming call. - /// - /// A task. - [Fact] - public async Task ClientStreamingSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } - - /// - /// Validates a failed ClientStreaming call when the service is unavailable. - /// - /// A task. - [Fact] - public async Task ClientStreamingUnavailable() - { - await this.TestHandlerFailure( - FoobarService.MakeClientStreamingRequest, - StatusCode.Unavailable, - validateErrorDescription: false, - BogusServerUri).ConfigureAwait(false); - } - - /// - /// Validates a failed ClientStreaming call. - /// - /// A task. - [Fact] - public async Task ClientStreamingFail() - { - await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed ClientStreaming call because the client is disposed before completing the RPC. - /// - [Fact] - public void ClientStreamingDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.ClientStreaming(); - } - - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } - - /// - /// Validates a successful ServerStreaming call. - /// - /// A task. - [Fact] - public async Task ServerStreamingSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } - - /// - /// Validates a failed ServerStreaming call. - /// - /// A task. - [Fact] - public async Task ServerStreamingFail() - { - await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed ServerStreaming call because the client is disposed before completing the RPC. - /// - [Fact] - public void ServerStreamingDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.ServerStreaming(FoobarService.DefaultRequestMessage); - } - - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } - - /// - /// Validates a successful DuplexStreaming call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } - - /// - /// Validates a failed DuplexStreaming call when the service is unavailable. - /// - /// A task. - [Fact] - public async Task DuplexStreamingUnavailable() - { - await this.TestHandlerFailure( - FoobarService.MakeDuplexStreamingRequest, - StatusCode.Unavailable, - validateErrorDescription: false, - BogusServerUri).ConfigureAwait(false); - } - - /// - /// Validates a failed DuplexStreaming call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingFail() - { - await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed DuplexStreaming call because the client is disposed before completing the RPC. - /// - [Fact] - public void DuplexStreamingDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.DuplexStreaming(); - } - - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } - - /// - /// Validates that a downstream interceptor has access to the created Activity - /// and that the caller always sees the correct activity, not our created Activity. - /// - /// A Task. - [Fact] - public async Task DownstreamInterceptorActivityAccess() - { - using var server = FoobarService.Start(); - var channel = new Channel(server.UriString, ChannelCredentials.Insecure); - var callInvoker = channel.CreateCallInvoker(); - - // Activity has a parent - using var parentActivity = new Activity("foo"); - parentActivity.SetIdFormat(ActivityIdFormat.W3C); - parentActivity.Start(); - - // Order of interceptor invocation will be ClientTracingInterceptor -> MetadataInjector - callInvoker = callInvoker.Intercept( - metadata => - { - // This Func is called as part of an internal MetadataInjector interceptor created by gRPC Core. - Assert.True(Activity.Current.Source == GrpcCoreInstrumentation.ActivitySource); - Assert.Equal(parentActivity.Id, Activity.Current.ParentId); - - // Set a tag on the Activity and make sure we can see it afterwardsd - Activity.Current.SetTag("foo", "bar"); - return metadata; - }); - - var interceptorOptions = new ClientTracingInterceptorOptions { ActivityIdentifierValue = Guid.NewGuid() }; - callInvoker = callInvoker.Intercept(new ClientTracingInterceptor(interceptorOptions)); - var client = new Foobar.FoobarClient(callInvoker); - - static void ValidateNewTagOnActivity(InterceptorActivityListener listener) - { - var createdActivity = listener.Activity; - Assert.Contains(createdActivity.TagObjects, t => t.Key == "foo" && (string)t.Value == "bar"); - } - - // Check the blocking async call - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - Assert.Equal(parentActivity, Activity.Current); - var response = client.Unary(FoobarService.DefaultRequestMessage); - - Assert.Equal(parentActivity, Activity.Current); - - ValidateNewTagOnActivity(activityListener); - } - - // Check unary async - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - Assert.Equal(parentActivity, Activity.Current); - using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); - - Assert.Equal(parentActivity, Activity.Current); - - _ = await call.ResponseAsync.ConfigureAwait(false); - - Assert.Equal(parentActivity, Activity.Current); - - ValidateNewTagOnActivity(activityListener); - } - - // Check a streaming async call - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - Assert.Equal(parentActivity, Activity.Current); - using var call = client.DuplexStreaming(); - - Assert.Equal(parentActivity, Activity.Current); - - await call.RequestStream.WriteAsync(FoobarService.DefaultRequestMessage).ConfigureAwait(false); - - Assert.Equal(parentActivity, Activity.Current); - - await call.RequestStream.CompleteAsync().ConfigureAwait(false); - - Assert.Equal(parentActivity, Activity.Current); - - while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) - { - Assert.Equal(parentActivity, Activity.Current); - } - - Assert.Equal(parentActivity, Activity.Current); - - ValidateNewTagOnActivity(activityListener); - } - } - - /// - /// Validates the common activity tags. - /// - /// The activity. - /// The expected status code. - /// if set to true [recorded messages]. - internal static void ValidateCommonActivityTags( - Activity activity, - Grpc.Core.StatusCode expectedStatusCode = Grpc.Core.StatusCode.OK, - bool recordedMessages = false) - { - Assert.NotNull(activity); - Assert.NotNull(activity.Tags); - - // The activity was stopped - Assert.True(activity.Duration != default); - - // TagObjects contain non string values - // Tags contains only string values - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcSystem && (string)t.Value == "grpc"); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcService && (string)t.Value == "OpenTelemetry.Contrib.Instrumentation.GrpcCore.Test.Foobar"); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcMethod); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcGrpcStatusCode && (int)t.Value == (int)expectedStatusCode); - - // Cancelled is not an error. - if (expectedStatusCode != StatusCode.OK && expectedStatusCode != StatusCode.Cancelled) - { - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusCode && (string)t.Value == "ERROR"); - } - - if (recordedMessages) - { - // all methods accept a request and return a single response - Assert.NotNull(activity.Events); - var requestMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultRequestMessage.GetType().Name); - var responseMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultResponseMessage.GetType().Name); - - static void ValidateCommonEventAttributes(ActivityEvent activityEvent) - { - Assert.NotNull(activityEvent.Tags); - Assert.Contains(activityEvent.Tags, t => t.Key == "name" && (string)t.Value == "message"); - Assert.Contains(activityEvent.Tags, t => t.Key == SemanticConventions.AttributeMessageID && (int)t.Value == 1); - } - - Assert.NotEqual(default, requestMessage); - Assert.NotEqual(default, responseMessage); - - ValidateCommonEventAttributes(requestMessage); - Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "SENT"); - Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultRequestMessageSize); - - ValidateCommonEventAttributes(responseMessage); - Assert.Contains(responseMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "RECEIVED"); - Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultResponseMessageSize); - } - } - - /// - /// Tests basic handler success. - /// - /// The client request function. - /// The additional metadata, if any. - /// A Task. - private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) - { - var mockPropagator = new Mock(); - PropagationContext capturedPropagationContext = default; - Metadata capturedCarrier = null; - var propagatorCalled = 0; - var originalMetadataCount = additionalMetadata.Count; - - mockPropagator - .Setup( - x => x.Inject( - It.IsAny(), - It.IsAny(), - It.IsAny>())) - .Callback>( - (propagation, carrier, setter) => - { - propagatorCalled++; - capturedPropagationContext = propagation; - capturedCarrier = carrier; - - // Make sure the original metadata make it through - if (additionalMetadata != null) - { - Assert.Equal(capturedCarrier, additionalMetadata); - } - - // Call the actual setter to ensure it updates the carrier. - // It doesn't matter what we put in - setter(capturedCarrier, "bar", "baz"); - }); - - using var server = FoobarService.Start(); - var interceptorOptions = new ClientTracingInterceptorOptions - { - Propagator = mockPropagator.Object, - RecordMessageEvents = true, - ActivityIdentifierValue = Guid.NewGuid(), - }; - - // No Activity parent - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - - Assert.Equal(default, Activity.Current); - - var activity = activityListener.Activity; - - // Propagator was called exactly once - Assert.Equal(1, propagatorCalled); - - // The client tracing interceptor should create a copy of the original call headers before passing to the propagator. - // Retries that sit above this interceptor rely on the original call metadata. - // The propagator should not have mutated the original CallOption headers. - Assert.Equal(originalMetadataCount, additionalMetadata.Count); - - // There was no parent activity, so these will be default - Assert.Equal(default, capturedPropagationContext.ActivityContext.TraceId); - Assert.Equal(default, capturedPropagationContext.ActivityContext.SpanId); - - // Sanity check a valid metadata injection setter. - Assert.NotEmpty(capturedCarrier); - - ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(default, activity.ParentSpanId); - } - - propagatorCalled = 0; - capturedPropagationContext = default; - - // Activity has a parent - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - using var parentActivity = new Activity("foo"); - parentActivity.SetIdFormat(ActivityIdFormat.W3C); - parentActivity.Start(); - var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - - Assert.Equal(parentActivity, Activity.Current); - - // Propagator was called exactly once - Assert.Equal(1, propagatorCalled); - - // There was a parent activity, so these will have something in them. - Assert.NotEqual(default, capturedPropagationContext.ActivityContext.TraceId); - Assert.NotEqual(default, capturedPropagationContext.ActivityContext.SpanId); - - var activity = activityListener.Activity; - ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(parentActivity.Id, activity.ParentId); - } - } - - /// - /// Tests basic handler failure. Instructs the server to fail with resources exhausted and validates the created Activity. - /// - /// The client request function. - /// The status code to use for the failure. Defaults to ResourceExhausted. - /// if set to true [validate error description]. - /// An alternate server URI string. - /// - /// A Task. - /// - private async Task TestHandlerFailure( - Func clientRequestFunc, - StatusCode statusCode = StatusCode.ResourceExhausted, - bool validateErrorDescription = true, - string serverUriString = null) - { - using var server = FoobarService.Start(); - var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - var client = FoobarService.ConstructRpcClient( - serverUriString ?? server.UriString, - new ClientTracingInterceptor(clientInterceptorOptions), - new List - { - new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), - new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), - }); - - using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); - await Assert.ThrowsAsync(async () => await clientRequestFunc(client, null).ConfigureAwait(false)); - - var activity = activityListener.Activity; - ValidateCommonActivityTags(activity, statusCode, false); - - if (validateErrorDescription) - { - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusDescription && ((string)t.Value).Contains("fubar")); - } - } - - /// - /// Tests for Activity cancellation when the handler is disposed before completing the RPC. - /// - /// The client request action. - private void TestActivityIsCancelledWhenHandlerDisposed(Action clientRequestAction) - { - using var server = FoobarService.Start(); - var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); - var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(clientInterceptorOptions)); - clientRequestAction(client); - - var activity = activityListener.Activity; - ValidateCommonActivityTags(activity, StatusCode.Cancelled, false); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Interceptors; +using Moq; +using OpenTelemetry.Context.Propagation; +using Xunit; + +namespace OpenTelemetry.Instrumentation.GrpcCore.Test +{ + /// + /// Grpc Core client interceptor tests. + /// + public class GrpcCoreClientInterceptorTests + { + /// + /// A bogus server uri. + /// + private static readonly string BogusServerUri = "dns:i.dont.exist:77923"; + + /// + /// The default metadata func. + /// + private static readonly Func DefaultMetadataFunc = () => new Metadata { new Metadata.Entry("foo", "bar") }; + + /// + /// Validates a successful AsyncUnary call. + /// + /// A task. + [Fact] + public async Task AsyncUnarySuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } + + /// + /// Validates a failed AsyncUnary call because the endpoint isn't there. + /// + /// A task. + [Fact] + public async Task AsyncUnaryUnavailable() + { + await this.TestHandlerFailure( + FoobarService.MakeUnaryAsyncRequest, + StatusCode.Unavailable, + validateErrorDescription: false, + BogusServerUri).ConfigureAwait(false); + } + + /// + /// Validates a failed AsyncUnary call because the service returned an error. + /// + /// A task. + [Fact] + public async Task AsyncUnaryFail() + { + await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed AsyncUnary call because the client is disposed before completing the RPC. + /// + [Fact] + public void AsyncUnaryDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) + { + using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); + } + + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } + + /// + /// Validates a successful ClientStreaming call. + /// + /// A task. + [Fact] + public async Task ClientStreamingSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } + + /// + /// Validates a failed ClientStreaming call when the service is unavailable. + /// + /// A task. + [Fact] + public async Task ClientStreamingUnavailable() + { + await this.TestHandlerFailure( + FoobarService.MakeClientStreamingRequest, + StatusCode.Unavailable, + validateErrorDescription: false, + BogusServerUri).ConfigureAwait(false); + } + + /// + /// Validates a failed ClientStreaming call. + /// + /// A task. + [Fact] + public async Task ClientStreamingFail() + { + await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed ClientStreaming call because the client is disposed before completing the RPC. + /// + [Fact] + public void ClientStreamingDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) + { + using var call = client.ClientStreaming(); + } + + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } + + /// + /// Validates a successful ServerStreaming call. + /// + /// A task. + [Fact] + public async Task ServerStreamingSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } + + /// + /// Validates a failed ServerStreaming call. + /// + /// A task. + [Fact] + public async Task ServerStreamingFail() + { + await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed ServerStreaming call because the client is disposed before completing the RPC. + /// + [Fact] + public void ServerStreamingDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) + { + using var call = client.ServerStreaming(FoobarService.DefaultRequestMessage); + } + + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } + + /// + /// Validates a successful DuplexStreaming call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } + + /// + /// Validates a failed DuplexStreaming call when the service is unavailable. + /// + /// A task. + [Fact] + public async Task DuplexStreamingUnavailable() + { + await this.TestHandlerFailure( + FoobarService.MakeDuplexStreamingRequest, + StatusCode.Unavailable, + validateErrorDescription: false, + BogusServerUri).ConfigureAwait(false); + } + + /// + /// Validates a failed DuplexStreaming call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingFail() + { + await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed DuplexStreaming call because the client is disposed before completing the RPC. + /// + [Fact] + public void DuplexStreamingDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) + { + using var call = client.DuplexStreaming(); + } + + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } + + /// + /// Validates that a downstream interceptor has access to the created Activity + /// and that the caller always sees the correct activity, not our created Activity. + /// + /// A Task. + [Fact] + public async Task DownstreamInterceptorActivityAccess() + { + using var server = FoobarService.Start(); + var channel = new Channel(server.UriString, ChannelCredentials.Insecure); + var callInvoker = channel.CreateCallInvoker(); + + // Activity has a parent + using var parentActivity = new Activity("foo"); + parentActivity.SetIdFormat(ActivityIdFormat.W3C); + parentActivity.Start(); + + // Order of interceptor invocation will be ClientTracingInterceptor -> MetadataInjector + callInvoker = callInvoker.Intercept( + metadata => + { + // This Func is called as part of an internal MetadataInjector interceptor created by gRPC Core. + Assert.True(Activity.Current.Source == GrpcCoreInstrumentation.ActivitySource); + Assert.Equal(parentActivity.Id, Activity.Current.ParentId); + + // Set a tag on the Activity and make sure we can see it afterwardsd + Activity.Current.SetTag("foo", "bar"); + return metadata; + }); + + var interceptorOptions = new ClientTracingInterceptorOptions { ActivityIdentifierValue = Guid.NewGuid() }; + callInvoker = callInvoker.Intercept(new ClientTracingInterceptor(interceptorOptions)); + var client = new Foobar.FoobarClient(callInvoker); + + static void ValidateNewTagOnActivity(InterceptorActivityListener listener) + { + var createdActivity = listener.Activity; + Assert.Contains(createdActivity.TagObjects, t => t.Key == "foo" && (string)t.Value == "bar"); + } + + // Check the blocking async call + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + Assert.Equal(parentActivity, Activity.Current); + var response = client.Unary(FoobarService.DefaultRequestMessage); + + Assert.Equal(parentActivity, Activity.Current); + + ValidateNewTagOnActivity(activityListener); + } + + // Check unary async + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + Assert.Equal(parentActivity, Activity.Current); + using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); + + Assert.Equal(parentActivity, Activity.Current); + + _ = await call.ResponseAsync.ConfigureAwait(false); + + Assert.Equal(parentActivity, Activity.Current); + + ValidateNewTagOnActivity(activityListener); + } + + // Check a streaming async call + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + Assert.Equal(parentActivity, Activity.Current); + using var call = client.DuplexStreaming(); + + Assert.Equal(parentActivity, Activity.Current); + + await call.RequestStream.WriteAsync(FoobarService.DefaultRequestMessage).ConfigureAwait(false); + + Assert.Equal(parentActivity, Activity.Current); + + await call.RequestStream.CompleteAsync().ConfigureAwait(false); + + Assert.Equal(parentActivity, Activity.Current); + + while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) + { + Assert.Equal(parentActivity, Activity.Current); + } + + Assert.Equal(parentActivity, Activity.Current); + + ValidateNewTagOnActivity(activityListener); + } + } + + /// + /// Validates the common activity tags. + /// + /// The activity. + /// The expected status code. + /// if set to true [recorded messages]. + internal static void ValidateCommonActivityTags( + Activity activity, + Grpc.Core.StatusCode expectedStatusCode = Grpc.Core.StatusCode.OK, + bool recordedMessages = false) + { + Assert.NotNull(activity); + Assert.NotNull(activity.Tags); + + // The activity was stopped + Assert.True(activity.Duration != default); + + // TagObjects contain non string values + // Tags contains only string values + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcSystem && (string)t.Value == "grpc"); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcService && (string)t.Value == "OpenTelemetry.Instrumentation.GrpcCore.Test.Foobar"); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcMethod); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcGrpcStatusCode && (int)t.Value == (int)expectedStatusCode); + + // Cancelled is not an error. + if (expectedStatusCode != StatusCode.OK && expectedStatusCode != StatusCode.Cancelled) + { + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusCode && (string)t.Value == "ERROR"); + } + + if (recordedMessages) + { + // all methods accept a request and return a single response + Assert.NotNull(activity.Events); + var requestMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultRequestMessage.GetType().Name); + var responseMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultResponseMessage.GetType().Name); + + static void ValidateCommonEventAttributes(ActivityEvent activityEvent) + { + Assert.NotNull(activityEvent.Tags); + Assert.Contains(activityEvent.Tags, t => t.Key == "name" && (string)t.Value == "message"); + Assert.Contains(activityEvent.Tags, t => t.Key == SemanticConventions.AttributeMessageID && (int)t.Value == 1); + } + + Assert.NotEqual(default, requestMessage); + Assert.NotEqual(default, responseMessage); + + ValidateCommonEventAttributes(requestMessage); + Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "SENT"); + Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultRequestMessageSize); + + ValidateCommonEventAttributes(responseMessage); + Assert.Contains(responseMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "RECEIVED"); + Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultResponseMessageSize); + } + } + + /// + /// Tests basic handler success. + /// + /// The client request function. + /// The additional metadata, if any. + /// A Task. + private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) + { + var mockPropagator = new Mock(); + PropagationContext capturedPropagationContext = default; + Metadata capturedCarrier = null; + var propagatorCalled = 0; + var originalMetadataCount = additionalMetadata.Count; + + mockPropagator + .Setup( + x => x.Inject( + It.IsAny(), + It.IsAny(), + It.IsAny>())) + .Callback>( + (propagation, carrier, setter) => + { + propagatorCalled++; + capturedPropagationContext = propagation; + capturedCarrier = carrier; + + // Make sure the original metadata make it through + if (additionalMetadata != null) + { + Assert.Equal(capturedCarrier, additionalMetadata); + } + + // Call the actual setter to ensure it updates the carrier. + // It doesn't matter what we put in + setter(capturedCarrier, "bar", "baz"); + }); + + using var server = FoobarService.Start(); + var interceptorOptions = new ClientTracingInterceptorOptions + { + Propagator = mockPropagator.Object, + RecordMessageEvents = true, + ActivityIdentifierValue = Guid.NewGuid(), + }; + + // No Activity parent + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + + Assert.Equal(default, Activity.Current); + + var activity = activityListener.Activity; + + // Propagator was called exactly once + Assert.Equal(1, propagatorCalled); + + // The client tracing interceptor should create a copy of the original call headers before passing to the propagator. + // Retries that sit above this interceptor rely on the original call metadata. + // The propagator should not have mutated the original CallOption headers. + Assert.Equal(originalMetadataCount, additionalMetadata.Count); + + // There was no parent activity, so these will be default + Assert.Equal(default, capturedPropagationContext.ActivityContext.TraceId); + Assert.Equal(default, capturedPropagationContext.ActivityContext.SpanId); + + // Sanity check a valid metadata injection setter. + Assert.NotEmpty(capturedCarrier); + + ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(default, activity.ParentSpanId); + } + + propagatorCalled = 0; + capturedPropagationContext = default; + + // Activity has a parent + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + using var parentActivity = new Activity("foo"); + parentActivity.SetIdFormat(ActivityIdFormat.W3C); + parentActivity.Start(); + var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + + Assert.Equal(parentActivity, Activity.Current); + + // Propagator was called exactly once + Assert.Equal(1, propagatorCalled); + + // There was a parent activity, so these will have something in them. + Assert.NotEqual(default, capturedPropagationContext.ActivityContext.TraceId); + Assert.NotEqual(default, capturedPropagationContext.ActivityContext.SpanId); + + var activity = activityListener.Activity; + ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(parentActivity.Id, activity.ParentId); + } + } + + /// + /// Tests basic handler failure. Instructs the server to fail with resources exhausted and validates the created Activity. + /// + /// The client request function. + /// The status code to use for the failure. Defaults to ResourceExhausted. + /// if set to true [validate error description]. + /// An alternate server URI string. + /// + /// A Task. + /// + private async Task TestHandlerFailure( + Func clientRequestFunc, + StatusCode statusCode = StatusCode.ResourceExhausted, + bool validateErrorDescription = true, + string serverUriString = null) + { + using var server = FoobarService.Start(); + var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; + var client = FoobarService.ConstructRpcClient( + serverUriString ?? server.UriString, + new ClientTracingInterceptor(clientInterceptorOptions), + new List + { + new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), + new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), + }); + + using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); + await Assert.ThrowsAsync(async () => await clientRequestFunc(client, null).ConfigureAwait(false)); + + var activity = activityListener.Activity; + ValidateCommonActivityTags(activity, statusCode, false); + + if (validateErrorDescription) + { + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusDescription && ((string)t.Value).Contains("fubar")); + } + } + + /// + /// Tests for Activity cancellation when the handler is disposed before completing the RPC. + /// + /// The client request action. + private void TestActivityIsCancelledWhenHandlerDisposed(Action clientRequestAction) + { + using var server = FoobarService.Start(); + var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; + using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); + var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(clientInterceptorOptions)); + clientRequestAction(client); + + var activity = activityListener.Activity; + ValidateCommonActivityTags(activity, StatusCode.Cancelled, false); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs rename to test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 9434231ae3..730a9bf9eb 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -1,181 +1,181 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Grpc.Core; -using OpenTelemetry.Context.Propagation; -using Xunit; - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore.Test -{ - /// - /// Grpc Core server interceptor tests. - /// - public class GrpcCoreServerInterceptorTests - { - /// - /// Validates a successful UnaryServerHandler call. - /// - /// A task. - [Fact] - public async Task UnaryServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed UnaryServerHandler call. - /// - /// A task. - [Fact] - public async Task UnaryServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); - } - - /// - /// Validates a successful ClientStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ClientStreamingServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed ClientStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ClientStreamingServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a successful ServerStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ServerStreamingServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed ServerStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ServerStreamingServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a successful DuplexStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed DuplexStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); - } - - /// - /// A common method to test server interceptor handler success. - /// - /// The specific client request function. - /// The additional metadata, if any. - /// A Task. - private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) - { - // starts the server with the server interceptor - var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid() }; - using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); - - // No parent Activity, no context from header - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - var client = FoobarService.ConstructRpcClient(server.UriString); - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - - var activity = activityListener.Activity; - GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(default, activity.ParentSpanId); - } - - // No parent Activity, context from header - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - var client = FoobarService.ConstructRpcClient( - server.UriString, - additionalMetadata: new List - { - new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), - }); - - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - - var activity = activityListener.Activity; - GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); - } - } - - /// - /// A common method to test server interceptor handler failure. - /// - /// The specific client request function. - /// The additional metadata, if any. - /// A Task. - private async Task TestHandlerFailure(Func clientRequestFunc, Metadata additionalMetadata = null) - { - // starts the server with the server interceptor - var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); - - using var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue); - var client = FoobarService.ConstructRpcClient( - server.UriString, - additionalMetadata: new List - { - new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), - new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, StatusCode.ResourceExhausted.ToString()), - new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), - }); - - await Assert.ThrowsAsync(async () => await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false)); - - var activity = activityListener.Activity; - GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.ResourceExhausted, interceptorOptions.RecordMessageEvents); - Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Grpc.Core; +using OpenTelemetry.Context.Propagation; +using Xunit; + +namespace OpenTelemetry.Instrumentation.GrpcCore.Test +{ + /// + /// Grpc Core server interceptor tests. + /// + public class GrpcCoreServerInterceptorTests + { + /// + /// Validates a successful UnaryServerHandler call. + /// + /// A task. + [Fact] + public async Task UnaryServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed UnaryServerHandler call. + /// + /// A task. + [Fact] + public async Task UnaryServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + } + + /// + /// Validates a successful ClientStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ClientStreamingServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed ClientStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ClientStreamingServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a successful ServerStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ServerStreamingServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed ServerStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ServerStreamingServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a successful DuplexStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + } + + /// + /// Validates a failed DuplexStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + } + + /// + /// A common method to test server interceptor handler success. + /// + /// The specific client request function. + /// The additional metadata, if any. + /// A Task. + private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) + { + // starts the server with the server interceptor + var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid() }; + using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); + + // No parent Activity, no context from header + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + var client = FoobarService.ConstructRpcClient(server.UriString); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + + var activity = activityListener.Activity; + GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(default, activity.ParentSpanId); + } + + // No parent Activity, context from header + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + var client = FoobarService.ConstructRpcClient( + server.UriString, + additionalMetadata: new List + { + new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), + }); + + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + + var activity = activityListener.Activity; + GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); + } + } + + /// + /// A common method to test server interceptor handler failure. + /// + /// The specific client request function. + /// The additional metadata, if any. + /// A Task. + private async Task TestHandlerFailure(Func clientRequestFunc, Metadata additionalMetadata = null) + { + // starts the server with the server interceptor + var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; + using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); + + using var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue); + var client = FoobarService.ConstructRpcClient( + server.UriString, + additionalMetadata: new List + { + new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), + new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, StatusCode.ResourceExhausted.ToString()), + new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), + }); + + await Assert.ThrowsAsync(async () => await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false)); + + var activity = activityListener.Activity; + GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.ResourceExhausted, interceptorOptions.RecordMessageEvents); + Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs similarity index 95% rename from test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs rename to test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index ae3b3adb64..ec68ba6dfe 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -1,74 +1,74 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Diagnostics; -using System.Linq; - -namespace OpenTelemetry.Contrib.Instrumentation.GrpcCore.Test -{ - /// - /// This class listens for a single Activity created by the Grpc Core interceptors. - /// - internal sealed class InterceptorActivityListener : IDisposable - { - /// - /// The activity listener. - /// - private readonly ActivityListener activityListener; - - /// - /// Initializes a new instance of the class. - /// - /// The activity identifier. - public InterceptorActivityListener(Guid activityIdentifier) - { - this.activityListener = new ActivityListener - { - ShouldListenTo = source => source.Name == GrpcCoreInstrumentation.ActivitySourceName, - ActivityStarted = activity => - { - if (activity.TagObjects.Any(t => t.Key == SemanticConventions.AttributeActivityIdentifier && (Guid)t.Value == activityIdentifier)) - { - this.Activity = activity; - } - }, - Sample = this.Sample, - }; - - ActivitySource.AddActivityListener(this.activityListener); - Debug.Assert(GrpcCoreInstrumentation.ActivitySource.HasListeners(), "activity source has no listeners"); - } - - /// - /// Gets the started Activity. - /// - public Activity Activity { get; private set; } - - /// - public void Dispose() - { - this.activityListener.Dispose(); - } - - /// - /// Always sample. - /// - /// The options. - /// a result. - private ActivitySamplingResult Sample(ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Linq; + +namespace OpenTelemetry.Instrumentation.GrpcCore.Test +{ + /// + /// This class listens for a single Activity created by the Grpc Core interceptors. + /// + internal sealed class InterceptorActivityListener : IDisposable + { + /// + /// The activity listener. + /// + private readonly ActivityListener activityListener; + + /// + /// Initializes a new instance of the class. + /// + /// The activity identifier. + public InterceptorActivityListener(Guid activityIdentifier) + { + this.activityListener = new ActivityListener + { + ShouldListenTo = source => source.Name == GrpcCoreInstrumentation.ActivitySourceName, + ActivityStarted = activity => + { + if (activity.TagObjects.Any(t => t.Key == SemanticConventions.AttributeActivityIdentifier && (Guid)t.Value == activityIdentifier)) + { + this.Activity = activity; + } + }, + Sample = this.Sample, + }; + + ActivitySource.AddActivityListener(this.activityListener); + Debug.Assert(GrpcCoreInstrumentation.ActivitySource.HasListeners(), "activity source has no listeners"); + } + + /// + /// Gets the started Activity. + /// + public Activity Activity { get; private set; } + + /// + public void Dispose() + { + this.activityListener.Dispose(); + } + + /// + /// Always sample. + /// + /// The options. + /// a result. + private ActivitySamplingResult Sample(ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj similarity index 83% rename from test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests.csproj rename to test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 15ef60f0b7..6eec7d0f69 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -1,25 +1,25 @@ - - - - netcoreapp3.1 - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - + + + + netcoreapp3.1 + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/proto/foobar.proto b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto similarity index 84% rename from test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/proto/foobar.proto rename to test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto index c851747a0a..635c0383d9 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.GrpcCore.Tests/proto/foobar.proto +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto @@ -1,17 +1,17 @@ -syntax = "proto3"; -package OpenTelemetry.Contrib.Instrumentation.GrpcCore.Test; - -service Foobar { - rpc Unary (FoobarRequest) returns (FoobarResponse) {} - rpc ClientStreaming (stream FoobarRequest) returns (FoobarResponse) {} - rpc ServerStreaming (FoobarRequest) returns (stream FoobarResponse) {} - rpc DuplexStreaming (stream FoobarRequest) returns (stream FoobarResponse) {} -} - -message FoobarRequest { - string message = 1; -} - -message FoobarResponse { - string message = 1; +syntax = "proto3"; +package OpenTelemetry.Instrumentation.GrpcCore.Test; + +service Foobar { + rpc Unary (FoobarRequest) returns (FoobarResponse) {} + rpc ClientStreaming (stream FoobarRequest) returns (FoobarResponse) {} + rpc ServerStreaming (FoobarRequest) returns (stream FoobarResponse) {} + rpc DuplexStreaming (stream FoobarRequest) returns (stream FoobarResponse) {} +} + +message FoobarRequest { + string message = 1; +} + +message FoobarResponse { + string message = 1; } \ No newline at end of file From f507e57a0b11a1aa3955cca8a8c92ecc5b371c40 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 18 Mar 2022 15:43:23 -0700 Subject: [PATCH 0057/1499] Rename EntityFrameworkCoreInstrumentation (#261) * Rename EntityFrameworfCoreInstrumentation --- ...ge-Instrumentation.EntityFrameworkCore.yml | 4 +-- opentelemetry-dotnet-contrib.sln | 28 +++++++++--------- .../CHANGELOG.md | 3 -- .../README.md | 14 --------- .../CHANGELOG.md | 29 +++++++++++++++++++ .../EntityFrameworkInstrumentation.cs | 5 ++-- .../EntityFrameworkInstrumentationOptions.cs | 2 +- .../EntityFrameworkDiagnosticListener.cs | 2 +- ...tityFrameworkInstrumentationEventSource.cs | 2 +- ...nstrumentation.EntityFrameworkCore.csproj} | 0 .../Properties/AssemblyInfo.cs | 4 +-- .../README.md | 17 +++++++++++ .../TracerProviderBuilderExtensions.cs | 4 +-- .../EntityFrameworkDiagnosticListenerTests.cs | 4 +-- ...entation.EntityFrameworkCore.Tests.csproj} | 2 +- 15 files changed, 74 insertions(+), 46 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/CHANGELOG.md delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/README.md create mode 100644 src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore => OpenTelemetry.Instrumentation.EntityFrameworkCore}/EntityFrameworkInstrumentation.cs (88%) rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore => OpenTelemetry.Instrumentation.EntityFrameworkCore}/EntityFrameworkInstrumentationOptions.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore => OpenTelemetry.Instrumentation.EntityFrameworkCore}/Implementation/EntityFrameworkDiagnosticListener.cs (99%) rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore => OpenTelemetry.Instrumentation.EntityFrameworkCore}/Implementation/EntityFrameworkInstrumentationEventSource.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj => OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj} (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore => OpenTelemetry.Instrumentation.EntityFrameworkCore}/Properties/AssemblyInfo.cs (58%) create mode 100644 src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md rename src/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore => OpenTelemetry.Instrumentation.EntityFrameworkCore}/TracerProviderBuilderExtensions.cs (93%) rename test/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests => OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests}/EntityFrameworkDiagnosticListenerTests.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj => OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj} (86%) diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 2b61e7aa0e..a2439768a9 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore +name: Pack OpenTelemetry.Instrumentation.EntityFrameworkCore on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore + PROJECT: OpenTelemetry.Instrumentation.EntityFrameworkCore strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 8a95008c47..c5f4b47056 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -76,8 +76,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-2 test\Directory.Build.targets = test\Directory.Build.targets EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj", "{09525C6C-68B7-405E-B476-23E64D91C11B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit", "src\OpenTelemetry.Contrib.Instrumentation.MassTransit\OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj", "{301BFB9F-6D73-4DEE-93D1-75F480816F63}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj", "{1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}" @@ -132,8 +130,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Previ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Preview.Tests", "test\OpenTelemetry.Contrib.Preview.Tests\OpenTelemetry.Contrib.Preview.Tests.csproj", "{D2C68560-C252-41A9-B742-2CEB7D760E0F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj", "{4172D671-3AAC-443F-9EB0-A6608B154AF0}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" @@ -158,6 +154,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Pe EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Instrumentation.EntityFrameworkCore\OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj", "{D4468444-69EF-4BF3-B13F-61F4AB728813}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj", "{A1F7FA66-C83D-485D-90FE-71C4018971D4}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore", "src\OpenTelemetry.Instrumentation.GrpcCore\OpenTelemetry.Instrumentation.GrpcCore.csproj", "{D0B694E4-AAE4-492F-ACCB-3D913A874780}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore.Tests", "test\OpenTelemetry.Instrumentation.GrpcCore.Tests\OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj", "{32D24733-C807-4816-84C3-270CE790AFD4}" @@ -176,10 +176,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {09525C6C-68B7-405E-B476-23E64D91C11B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {09525C6C-68B7-405E-B476-23E64D91C11B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {09525C6C-68B7-405E-B476-23E64D91C11B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {09525C6C-68B7-405E-B476-23E64D91C11B}.Release|Any CPU.Build.0 = Release|Any CPU {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Debug|Any CPU.Build.0 = Debug|Any CPU {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -264,10 +260,6 @@ Global {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU - {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4172D671-3AAC-443F-9EB0-A6608B154AF0}.Release|Any CPU.Build.0 = Release|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -320,6 +312,14 @@ Global {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.Build.0 = Release|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.Build.0 = Release|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.Build.0 = Release|Any CPU {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -344,7 +344,6 @@ Global {43CAFE52-F329-4431-87DA-7FEE1454D9A9} = {1A06E14B-DD2F-4536-9D2E-F708C0C43555} {0112BD4F-B7A6-4E43-AB23-B6E961E27A49} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {E0F52FDB-23D1-4927-BAB8-332655DD7A0B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {09525C6C-68B7-405E-B476-23E64D91C11B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {301BFB9F-6D73-4DEE-93D1-75F480816F63} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {CAD5C27A-D359-4086-9C4F-02204C084A8E} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -368,7 +367,6 @@ Global {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {B978939B-278C-43A3-AD12-32EA9BBD27D0} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D2C68560-C252-41A9-B742-2CEB7D760E0F} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {4172D671-3AAC-443F-9EB0-A6608B154AF0} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} @@ -383,6 +381,8 @@ Global {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {A1F7FA66-C83D-485D-90FE-71C4018971D4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {67BFE7DF-505D-427E-8019-40BFF19363E9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/CHANGELOG.md deleted file mode 100644 index 1512c42162..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -# Changelog - -## Unreleased diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/README.md deleted file mode 100644 index bab115a539..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# EntityFrameworkCore Instrumentation for OpenTelemetry .NET - -Automatically instruments the outgoing database requests from -[Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore). - -## Installation - -```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore -``` - -## References - -* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md new file mode 100644 index 0000000000..4ddc0afbbc --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +## Unreleased + +## 1.0.0-beta.3 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.EntityFrameworkCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore) + [(#261)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/261) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore` -> `using + OpenTelemetry.Instrumentation.EntityFrameworkCore`) + +## 1.0.0-beta2 + +* EntityFrameworkCore instrumentation to depend on API and not SDK + ([#121](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/121)) + +## 0.6.0-beta + +* This is the first release of + `OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore` package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs similarity index 88% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 227d0240d1..47e976bcf2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -15,10 +15,9 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Implementation; -using OpenTelemetry.Instrumentation; +using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; -namespace OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore { internal class EntityFrameworkInstrumentation : IDisposable { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 90953cf4bf..ccf8f8576a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -17,7 +17,7 @@ using System.Data; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore { /// /// Options for . diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index a9aa18f82a..1523802031 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -20,7 +20,7 @@ using OpenTelemetry.Instrumentation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Implementation +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation { internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 6802f7617d..1868e7d8ad 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -19,7 +19,7 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Implementation +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation { [EventSource(Name = "OpenTelemetry-Instrumentation-EntityFrameworkCore")] internal class EntityFrameworkInstrumentationEventSource : EventSource diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs similarity index 58% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs index a788569ade..e13ce2b912 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests")] #endif diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md new file mode 100644 index 0000000000..00a9ef753b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -0,0 +1,17 @@ +# EntityFrameworkCore Instrumentation for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EntityFrameworkCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) + +Automatically instruments the outgoing database requests from +[Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore). + +## Installation + +```shell +dotnet add package OpenTelemetry.Instrumentation.EntityFrameworkCore +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 1d50a3f9d3..63777f7070 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -15,8 +15,8 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore; -using OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Implementation; +using OpenTelemetry.Instrumentation.EntityFrameworkCore; +using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; namespace OpenTelemetry.Trace { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs rename to test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 3d11b3280f..fc289e31f2 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -23,12 +23,12 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Moq; -using OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Implementation; +using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests { public class EntityFrameworkDiagnosticListenerTests : IDisposable { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj similarity index 86% rename from test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj rename to test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 73c5b9a25d..50250ee5a6 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -17,7 +17,7 @@ - + From 8dce73a147aa1fb5d2ada571505358aae480c469 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 21 Mar 2022 22:00:42 -0700 Subject: [PATCH 0058/1499] Remove "Contrib" from MySql instrumentation (#256) * Rename MySql Instrumentation --- .github/component_owners.yml | 8 +++--- .../package-Instrumentation.MySqlData.yml | 4 +-- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../CHANGELOG.md | 5 ---- .../AssemblyInfo.cs | 4 +-- .../CHANGELOG.md | 24 ++++++++++++++++ .../MySqlActivitySourceHelper.cs | 2 +- .../MySqlDataInstrumentation.cs | 2 +- .../MySqlDataInstrumentationEventSource.cs | 2 +- .../MySqlDataInstrumentationOptions.cs | 2 +- .../MySqlDataTraceCommand.cs | 2 +- ...elemetry.Instrumentation.MySqlData.csproj} | 0 .../README.md | 9 ++++-- .../TracerProviderBuilderExtensions.cs | 2 +- .../MySqlDataTests.cs | 3 +- ...ry.Instrumentation.MySqlData.Tests.csproj} | 4 +-- 16 files changed, 61 insertions(+), 40 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.MySqlData/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/AssemblyInfo.cs (59%) create mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/MySqlActivitySourceHelper.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/MySqlDataInstrumentation.cs (99%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/MySqlDataInstrumentationEventSource.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/MySqlDataInstrumentationOptions.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/MySqlDataTraceCommand.cs (94%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData/OpenTelemetry.Contrib.Instrumentation.MySqlData.csproj => OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj} (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/README.md (89%) rename src/{OpenTelemetry.Contrib.Instrumentation.MySqlData => OpenTelemetry.Instrumentation.MySqlData}/TracerProviderBuilderExtensions.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests => OpenTelemetry.Instrumentation.MySqlData.Tests}/MySqlDataTests.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests.csproj => OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj} (85%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 328d63edb4..d6e0dd4e1e 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -7,8 +7,6 @@ components: - lupengamzn src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: - alexvaluyskiy - src/OpenTelemetry.Contrib.Instrumentation.MySqlData/: - - moonheart src/OpenTelemetry.Contrib.Preview/: - codeblanch src/OpenTelemetry.Exporter.Stackdriver/: @@ -19,6 +17,8 @@ components: - ejsmith src/OpenTelemetry.Instrumentation.GrpcCore/: - pcwiese + src/OpenTelemetry.Instrumentation.MySqlData/: + - moonheart src/OpenTelemetry.Instrumentation.Owin/: - codeblanch src/OpenTelemetry.Instrumentation.Quartz/: @@ -31,8 +31,6 @@ components: - lupengamzn test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: - alexvaluyskiy - test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/: - - moonheart test/OpenTelemetry.Contrib.Preview.Tests/: - codeblanch test/OpenTelemetry.Exporter.Stackdriver.Tests/: @@ -43,6 +41,8 @@ components: - ejsmith test/OpenTelemetry.Instrumentation.GrpcCore.Tests/: - pcwiese + test/OpenTelemetry.Instrumentation.MySqlData.Tests/: + - moonheart test/OpenTelemetry.Instrumentation.Owin.Tests/: - codeblanch test/OpenTelemetry.Instrumentation.Quartz.Tests/: diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index a5667332a0..04f48133bc 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.MySqlData +name: Pack OpenTelemetry.Instrumentation.MySqlData on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.MySqlData + PROJECT: OpenTelemetry.Instrumentation.MySqlData strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index c5f4b47056..e75c0d6911 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -116,10 +116,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcCore.AspNetCore", "examples\grpc.core\Examples.GrpcCore.AspNetCore\Examples.GrpcCore.AspNetCore.csproj", "{F1591DEE-79C0-4161-85C2-1477B261D274}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MySqlData", "src\OpenTelemetry.Contrib.Instrumentation.MySqlData\OpenTelemetry.Contrib.Instrumentation.MySqlData.csproj", "{7D6175C4-1E8C-43BD-878D-6241E9627A69}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests\OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests.csproj", "{9F837AD0-C410-4001-B002-55090DA584EA}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda", "src\OpenTelemetry.Contrib.Instrumentation.AWSLambda\OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj", "{87FE0ED4-56A5-4775-9F63-DD532F2200BD}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj", "{08EDD935-8B4E-4CF5-8840-200DEBA8E110}" @@ -150,6 +146,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Az EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage", "src\OpenTelemetry.Extensions.PersistentStorage\OpenTelemetry.Extensions.PersistentStorage.csproj", "{C2B9190B-E2F6-4D40-B298-91521E383A50}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" @@ -232,14 +232,6 @@ Global {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.Build.0 = Debug|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.ActiveCfg = Release|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.Build.0 = Release|Any CPU - {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7D6175C4-1E8C-43BD-878D-6241E9627A69}.Release|Any CPU.Build.0 = Release|Any CPU - {9F837AD0-C410-4001-B002-55090DA584EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9F837AD0-C410-4001-B002-55090DA584EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9F837AD0-C410-4001-B002-55090DA584EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9F837AD0-C410-4001-B002-55090DA584EA}.Release|Any CPU.Build.0 = Release|Any CPU {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.Build.0 = Debug|Any CPU {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -296,6 +288,14 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.Build.0 = Release|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.Build.0 = Release|Any CPU {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.Build.0 = Debug|Any CPU {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -360,8 +360,6 @@ Global {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} - {7D6175C4-1E8C-43BD-878D-6241E9627A69} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {9F837AD0-C410-4001-B002-55090DA584EA} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {87FE0ED4-56A5-4775-9F63-DD532F2200BD} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {08EDD935-8B4E-4CF5-8840-200DEBA8E110} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} @@ -377,6 +375,8 @@ Global {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/CHANGELOG.md deleted file mode 100644 index 134621e04d..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -## Unreleased - -* Initial release diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs similarity index 59% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs index af3cf46e53..864cb0df01 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MySqlData.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MySqlData.Tests")] #endif diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md new file mode 100644 index 0000000000..789acbb35b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +## Unreleased + +## 1.0.0-beta.2 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.MySqlData`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.MySqlData`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.MySqlData) + [(#256)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/256) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.MySqlData` -> `using + OpenTelemetry.Instrumentation.MySqlData`) + +## 1.0.0-beta1 + +* This is the first release of `OpenTelemetry.Contrib.Instrumentation.MySqlData` + package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs index a11bdb9499..65adeb2296 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs @@ -20,7 +20,7 @@ using System.Reflection; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData { /// /// Helper class to hold common properties used by MySqlDataDiagnosticListener. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index 87935da79e..619dc72cd9 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -20,7 +20,7 @@ using MySql.Data.MySqlClient; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData { /// /// MySql.Data instrumentation. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs index 9332a60499..d56c6c29ab 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs @@ -16,7 +16,7 @@ using System.Diagnostics.Tracing; -namespace OpenTelemetry.Contrib.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData { /// /// EventSource events emitted from the project. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs index 3b5ef41653..891f7bcfd6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs @@ -22,7 +22,7 @@ using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData { /// /// Options for . diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataTraceCommand.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataTraceCommand.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs index fbce7faa39..0c876e3dbf 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/MySqlDataTraceCommand.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs @@ -16,7 +16,7 @@ using MySql.Data.MySqlClient; -namespace OpenTelemetry.Contrib.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData { /// /// Informations of current executing command. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/OpenTelemetry.Contrib.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/OpenTelemetry.Contrib.Instrumentation.MySqlData.csproj rename to src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md similarity index 89% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/README.md rename to src/OpenTelemetry.Instrumentation.MySqlData/README.md index 0c6c2cdcd4..7224b08334 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -1,20 +1,23 @@ # MySqlData Instrumentation for OpenTelemetry +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.MySqlData.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.MySqlData.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) + This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), which instruments [MySql.Data](https://www.nuget.org/packages/MySql.Data) and collects telemetry about database operations. -## Steps to enable OpenTelemetry.Contrib.Instrumentation.MySqlData +## Steps to enable OpenTelemetry.Instrumentation.MySqlData ### Step 1: Install Package Add a reference to the -[`OpenTelemetry.Contrib.Instrumentation.MySqlData`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) +[`OpenTelemetry.Instrumentation.MySqlData`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) package. Also, add any other instrumentations & exporters you will need. ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.MySqlData +dotnet add package OpenTelemetry.Instrumentation.MySqlData ``` ### Step 2: Enable MySqlData Instrumentation at application startup diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs index e158e26117..6a9f6283fa 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs @@ -15,7 +15,7 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.MySqlData; +using OpenTelemetry.Instrumentation.MySqlData; namespace OpenTelemetry.Trace { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/MySqlDataTests.cs rename to test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs index 283659195f..d3d920e730 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs @@ -15,7 +15,6 @@ // using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Moq; @@ -24,7 +23,7 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests +namespace OpenTelemetry.Instrumentation.MySqlData.Tests { public class MySqlDataTests { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj similarity index 85% rename from test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests.csproj rename to test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 24039e8ff2..2315824b39 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests/OpenTelemetry.Contrib.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -20,7 +20,7 @@ - + From 44955b61179113cdeaa9ee197030f1fd83f70bb6 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 24 Mar 2022 13:00:44 -0700 Subject: [PATCH 0059/1499] Remove "Contrib' from MassTransit Instrumentation (#252) * Rename MassTransit Instrumentation --- .github/component_owners.yml | 8 ++--- .../package-Instrumentation.MassTransit.yml | 4 +-- opentelemetry-dotnet-contrib.sln | 27 ++++++++++------- .../CHANGELOG.md | 15 ---------- .../AssemblyInfo.cs | 4 +-- .../CHANGELOG.md | 29 +++++++++++++++++++ .../Implementation/DisplayNameHelper.cs | 2 +- .../MassTransitDiagnosticListener.cs | 3 +- .../MassTransitInstrumentationEventSource.cs | 2 +- .../MassTransitSemanticConventions.cs | 2 +- .../Implementation/TagName.cs | 2 +- .../MassTransitInstrumentation.cs | 5 ++-- .../MassTransitInstrumentationOptions.cs | 3 +- ...emetry.Instrumentation.MassTransit.csproj} | 0 .../OperationName.cs | 2 +- .../README.md | 5 +++- .../TracerProviderBuilderExtensions.cs | 4 +-- .../MassTransitInstrumentationTests.cs | 10 +++---- ....Instrumentation.MassTransit.Tests.csproj} | 4 +-- .../TestConsumer.cs | 2 +- .../TestMessage.cs | 2 +- 21 files changed, 77 insertions(+), 58 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.MassTransit/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/AssemblyInfo.cs (59%) create mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/Implementation/DisplayNameHelper.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/Implementation/MassTransitDiagnosticListener.cs (98%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/Implementation/MassTransitInstrumentationEventSource.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/Implementation/MassTransitSemanticConventions.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/Implementation/TagName.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/MassTransitInstrumentation.cs (91%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/MassTransitInstrumentationOptions.cs (91%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit/OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj => OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj} (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/OperationName.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/README.md (81%) rename src/{OpenTelemetry.Contrib.Instrumentation.MassTransit => OpenTelemetry.Instrumentation.MassTransit}/TracerProviderBuilderExtensions.cs (94%) rename test/{OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests => OpenTelemetry.Instrumentation.MassTransit.Tests}/MassTransitInstrumentationTests.cs (96%) rename test/{OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj => OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj} (85%) rename test/{OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests => OpenTelemetry.Instrumentation.MassTransit.Tests}/TestConsumer.cs (93%) rename test/{OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests => OpenTelemetry.Instrumentation.MassTransit.Tests}/TestMessage.cs (92%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index d6e0dd4e1e..0dfa4f27b9 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -5,8 +5,6 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn - src/OpenTelemetry.Contrib.Instrumentation.MassTransit/: - - alexvaluyskiy src/OpenTelemetry.Contrib.Preview/: - codeblanch src/OpenTelemetry.Exporter.Stackdriver/: @@ -17,6 +15,8 @@ components: - ejsmith src/OpenTelemetry.Instrumentation.GrpcCore/: - pcwiese + src/OpenTelemetry.Instrumentation.MassTransit/: + - alexvaluyskiy src/OpenTelemetry.Instrumentation.MySqlData/: - moonheart src/OpenTelemetry.Instrumentation.Owin/: @@ -29,8 +29,6 @@ components: test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn - test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/: - - alexvaluyskiy test/OpenTelemetry.Contrib.Preview.Tests/: - codeblanch test/OpenTelemetry.Exporter.Stackdriver.Tests/: @@ -41,6 +39,8 @@ components: - ejsmith test/OpenTelemetry.Instrumentation.GrpcCore.Tests/: - pcwiese + test/OpenTelemetry.Instrumentation.MassTransit.Tests/: + - alexvaluyskiy test/OpenTelemetry.Instrumentation.MySqlData.Tests/: - moonheart test/OpenTelemetry.Instrumentation.Owin.Tests/: diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml index cd5e43e2d9..4ddb344263 100644 --- a/.github/workflows/package-Instrumentation.MassTransit.yml +++ b/.github/workflows/package-Instrumentation.MassTransit.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.MassTransit +name: Pack OpenTelemetry.Instrumentation.MassTransit on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.MassTransit + PROJECT: OpenTelemetry.Instrumentation.MassTransit strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e75c0d6911..acdcd2ba59 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31912.275 @@ -76,6 +75,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-2 test\Directory.Build.targets = test\Directory.Build.targets EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj", "{09525C6C-68B7-405E-B476-23E64D91C11B}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit", "src\OpenTelemetry.Contrib.Instrumentation.MassTransit\OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj", "{301BFB9F-6D73-4DEE-93D1-75F480816F63}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj", "{1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}" @@ -146,6 +147,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Az EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit", "src\OpenTelemetry.Instrumentation.MassTransit\OpenTelemetry.Instrumentation.MassTransit.csproj", "{D4120D09-93F6-4D5C-98C6-A98B459EA83D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Instrumentation.MassTransit.Tests\OpenTelemetry.Instrumentation.MassTransit.Tests.csproj", "{4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" @@ -176,14 +181,6 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Debug|Any CPU.Build.0 = Debug|Any CPU - {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Release|Any CPU.ActiveCfg = Release|Any CPU - {301BFB9F-6D73-4DEE-93D1-75F480816F63}.Release|Any CPU.Build.0 = Release|Any CPU - {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}.Release|Any CPU.Build.0 = Release|Any CPU {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.Build.0 = Debug|Any CPU {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -288,6 +285,14 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.Build.0 = Release|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.Build.0 = Release|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -344,8 +349,6 @@ Global {43CAFE52-F329-4431-87DA-7FEE1454D9A9} = {1A06E14B-DD2F-4536-9D2E-F708C0C43555} {0112BD4F-B7A6-4E43-AB23-B6E961E27A49} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {E0F52FDB-23D1-4927-BAB8-332655DD7A0B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {301BFB9F-6D73-4DEE-93D1-75F480816F63} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {CAD5C27A-D359-4086-9C4F-02204C084A8E} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {73474960-8F91-4EE5-8E3E-F7E7ADA99238} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {21716C26-3B2A-4208-BDFB-8E58E2AF49EA} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} @@ -375,6 +378,8 @@ Global {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D4120D09-93F6-4D5C-98C6-A98B459EA83D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/CHANGELOG.md deleted file mode 100644 index a6848b5cad..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/CHANGELOG.md +++ /dev/null @@ -1,15 +0,0 @@ -# Changelog - -## Unreleased - -## 1.0.0-beta2 - -Released 2021-June-17 - -* Updated OTel SDK package version to 1.1.0-beta4 - ([#136](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/136)) - -## Initial Release - -* Updated OTel SDK package version to 1.1.0-beta1 - ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs similarity index 59% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs index 80b3299ec6..73a6afa34c 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MassTransit.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MassTransit.Tests")] #endif diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md new file mode 100644 index 0000000000..ddcf4e95aa --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +## Unreleased + +## 1.0.0-beta.3 + +* Going forward the NuGet package will be + [`OpenTelemetry.Instrumentation.MassTransit`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit). + Older versions will remain at + [`OpenTelemetry.Contrib.Instrumentation.MassTransit`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.MassTransit) + [(#252)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/252) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Contrib.Instrumentation.MassTransit` -> `using + OpenTelemetry.Instrumentation.MassTransit`) + +## 1.0.0-beta2 + +Released 2021-June-17 + +* Updated OTel SDK package version to 1.1.0-beta4 + ([#136](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/136)) + +## Initial Release + +* Updated OTel SDK package version to 1.1.0-beta1 + ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs index 2a8f1fc55d..e657c67d95 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs @@ -16,7 +16,7 @@ using System.Collections.Concurrent; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation { internal static class DisplayNameHelper { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs similarity index 98% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs index 62380f8a84..fc9d694950 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs @@ -19,10 +19,9 @@ using System.Diagnostics; using System.Linq; using System.Reflection; -using OpenTelemetry.Instrumentation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation { internal class MassTransitDiagnosticListener : ListenerHandler { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs index ad3defb78e..e722c35f22 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs @@ -18,7 +18,7 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation { /// /// EventSource events emitted from the project. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs index 61340afccd..8045c7c1a2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation { internal class MassTransitSemanticConventions { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/TagName.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs index 7a1e4de30f..5e4e4d7065 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation { internal class TagName { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/MassTransitInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs similarity index 91% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/MassTransitInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs index 342f34c8fb..42f6e42009 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/MassTransitInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs @@ -15,10 +15,9 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation; -using OpenTelemetry.Instrumentation; +using OpenTelemetry.Instrumentation.MassTransit.Implementation; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit +namespace OpenTelemetry.Instrumentation.MassTransit { internal class MassTransitInstrumentation : IDisposable { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs similarity index 91% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs index cdd8a1bb77..95b72e7268 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs @@ -15,9 +15,8 @@ // using System.Collections.Generic; -using OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit +namespace OpenTelemetry.Instrumentation.MassTransit { /// /// Options for . diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj rename to src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/OperationName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/OperationName.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs index c2c7627a9b..df045bb7f2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit +namespace OpenTelemetry.Instrumentation.MassTransit { /// /// MassTransit diagnostic source operation name constants. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md similarity index 81% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/README.md rename to src/OpenTelemetry.Instrumentation.MassTransit/README.md index 8790167c38..f6067618dc 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -1,5 +1,8 @@ # MassTransit Instrumentation for OpenTelemetry .NET +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.MassTransit.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.MassTransit.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit) + Automatically instruments [DiagnosticSource](https://masstransit-project.com/advanced/monitoring/diagnostic-source.html) events emitted by [MassTransit](https://masstransit-project.com/) library. @@ -7,7 +10,7 @@ events emitted by [MassTransit](https://masstransit-project.com/) library. ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.MassTransit +dotnet add package OpenTelemetry.Instrumentation.MassTransit ``` ## Configuration diff --git a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs index 34cae8a7a7..824e493db2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs @@ -15,8 +15,8 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.MassTransit; -using OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation; +using OpenTelemetry.Instrumentation.MassTransit; +using OpenTelemetry.Instrumentation.MassTransit.Implementation; namespace OpenTelemetry.Trace { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs similarity index 96% rename from test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs rename to test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs index be09e27d93..4f6ec47d18 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs @@ -20,12 +20,12 @@ using System.Threading.Tasks; using MassTransit.Testing; using Moq; -using OpenTelemetry.Contrib.Instrumentation.MassTransit.Implementation; +using OpenTelemetry.Instrumentation.MassTransit.Implementation; using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests +namespace OpenTelemetry.Instrumentation.MassTransit.Tests { public class MassTransitInstrumentationTests { @@ -170,9 +170,9 @@ public async Task ShouldMapMassTransitTagsForConsumeMessageToOpenTelemetrySpecif Assert.NotNull(actualActivity); Assert.NotNull(expectedMessageContext); - Assert.Equal("OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.TestConsumer process", actualActivity.DisplayName); + Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer process", actualActivity.DisplayName); Assert.Equal(ActivityKind.Internal, actualActivity.Kind); - Assert.Equal("OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.TestConsumer", actualActivity.GetTagValue(MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType)?.ToString()); + Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer", actualActivity.GetTagValue(MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType)?.ToString()); Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); @@ -213,7 +213,7 @@ public async Task ShouldMapMassTransitTagsForHandleMessageToOpenTelemetrySpecifi Assert.NotNull(actualActivity); Assert.NotNull(expectedMessageContext); - Assert.Equal("TestMessage/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests process", actualActivity.DisplayName); + Assert.Equal("TestMessage/OpenTelemetry.Instrumentation.MassTransit.Tests process", actualActivity.DisplayName); Assert.Equal(ActivityKind.Internal, actualActivity.Kind); Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj similarity index 85% rename from test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj rename to test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj index 36f47b72db..3b8141c542 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry MassTransit instrumentation @@ -22,6 +22,6 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/TestConsumer.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs similarity index 93% rename from test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/TestConsumer.cs rename to test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs index 495eee6cdc..cf7b7d8749 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/TestConsumer.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs @@ -17,7 +17,7 @@ using System.Threading.Tasks; using MassTransit; -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests +namespace OpenTelemetry.Instrumentation.MassTransit.Tests { public class TestConsumer : IConsumer { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/TestMessage.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs similarity index 92% rename from test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/TestMessage.cs rename to test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs index 2b7d547913..f17628be69 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests/TestMessage.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests +namespace OpenTelemetry.Instrumentation.MassTransit.Tests { public class TestMessage { From 9e21d1a1f4ccf7c9af2102a1bec3fa88223c9b07 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 24 Mar 2022 15:15:10 -0700 Subject: [PATCH 0060/1499] Update .sln file (#264) --- opentelemetry-dotnet-contrib.sln | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index acdcd2ba59..dd17dbd7ee 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -75,12 +75,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-2 test\Directory.Build.targets = test\Directory.Build.targets EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore\OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore.csproj", "{09525C6C-68B7-405E-B476-23E64D91C11B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit", "src\OpenTelemetry.Contrib.Instrumentation.MassTransit\OpenTelemetry.Contrib.Instrumentation.MassTransit.csproj", "{301BFB9F-6D73-4DEE-93D1-75F480816F63}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests\OpenTelemetry.Contrib.Instrumentation.MassTransit.Tests.csproj", "{1F4B5983-EA2E-4DAC-8E02-20C0CDA9FA93}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}" @@ -301,14 +295,6 @@ Global {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.Build.0 = Release|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.Build.0 = Release|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.Build.0 = Release|Any CPU {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -325,6 +311,14 @@ Global {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.ActiveCfg = Release|Any CPU {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.Build.0 = Release|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.Build.0 = Release|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.Build.0 = Release|Any CPU {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -382,12 +376,12 @@ Global {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A1F7FA66-C83D-485D-90FE-71C4018971D4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {67BFE7DF-505D-427E-8019-40BFF19363E9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} From 8e5501d25ba459815402d109a8056c896eaf40d3 Mon Sep 17 00:00:00 2001 From: Peter Wiese Date: Thu, 24 Mar 2022 17:27:08 -0700 Subject: [PATCH 0061/1499] Swap out Grpc.Core for Grpc.Core.Api. (#265) The full Grpc.Core package reference is not necessary. --- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.GrpcCore.csproj | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 6204360350..dcb1e58a82 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Switched Grpc.Core package dependency to Grpc.Core.Api in the same range. + No functional change, just less exposure to unnecessary packages. + ## 1.0.0-beta.4 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 3803cabb55..c01b14e8cf 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -7,7 +7,7 @@ - + From e15d233a0a48b52462312708d9e36529c0c3d412 Mon Sep 17 00:00:00 2001 From: Peter Wiese Date: Fri, 25 Mar 2022 15:11:57 -0700 Subject: [PATCH 0062/1499] Release OpenTelemetry.Instrumentation.Grpc as 1.0.0-beta.5 (#268) --- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index dcb1e58a82..bf949234b4 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.0.0-beta.5 + * Switched Grpc.Core package dependency to Grpc.Core.Api in the same range. No functional change, just less exposure to unnecessary packages. From ee81f148fec79001c7053a0d516543e7f69c9213 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 29 Mar 2022 15:29:16 -0700 Subject: [PATCH 0063/1499] Rename OpenTelemetry.Contrib.Preview package to OpenTelemetry.Extensions (#266) * Rename Contrib Preview --- .github/component_owners.yml | 8 +++--- .github/workflows/package-Preview.yml | 8 +++--- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../CHANGELOG.md | 3 -- .../.publicApi/net461/PublicAPI.Shipped.txt | 0 .../.publicApi/net461/PublicAPI.Unshipped.txt | 0 .../.publicApi/net5.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net5.0/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../AssemblyInfo.cs | 0 src/OpenTelemetry.Extensions/CHANGELOG.md | 17 +++++++++++ .../ActivityEventAttachingLogProcessor.cs | 0 .../Internal/DefaultLogStateConverter.cs | 0 .../OpenTelemetryExtensionsEventSource.cs | 0 .../LogToActivityEventConversionOptions.cs | 0 .../Logs/OpenTelemetryLoggingExtensions.cs | 0 .../OpenTelemetry.Extensions.csproj} | 0 .../README.md | 3 +- ...ActivityEventAttachingLogProcessorTests.cs | 4 +-- .../OpenTelemetry.Extensions.Tests.csproj} | 2 +- 21 files changed, 44 insertions(+), 29 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Preview/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/.publicApi/net461/PublicAPI.Shipped.txt (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/.publicApi/net461/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/.publicApi/net5.0/PublicAPI.Shipped.txt (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/.publicApi/net5.0/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/.publicApi/netstandard2.0/PublicAPI.Shipped.txt (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/AssemblyInfo.cs (100%) create mode 100644 src/OpenTelemetry.Extensions/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/Internal/ActivityEventAttachingLogProcessor.cs (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/Internal/DefaultLogStateConverter.cs (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/Internal/OpenTelemetryExtensionsEventSource.cs (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/Logs/LogToActivityEventConversionOptions.cs (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/Logs/OpenTelemetryLoggingExtensions.cs (100%) rename src/{OpenTelemetry.Contrib.Preview/OpenTelemetry.Contrib.Preview.csproj => OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj} (100%) rename src/{OpenTelemetry.Contrib.Preview => OpenTelemetry.Extensions}/README.md (59%) rename test/{OpenTelemetry.Contrib.Preview.Tests => OpenTelemetry.Extensions.Tests}/ActivityEventAttachingLogProcessorTests.cs (97%) rename test/{OpenTelemetry.Contrib.Preview.Tests/OpenTelemetry.Contrib.Preview.Tests.csproj => OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj} (90%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 0dfa4f27b9..cce1ca18ff 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -5,10 +5,10 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn - src/OpenTelemetry.Contrib.Preview/: - - codeblanch src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev + src/OpenTelemetry.Extensions/: + - codeblanch src/OpenTelemetry.Extensions.PersistentStorage/: - vishweshbankwar src/OpenTelemetry.Instrumentation.ElasticsearchClient/: @@ -29,10 +29,10 @@ components: test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn - test/OpenTelemetry.Contrib.Preview.Tests/: - - codeblanch test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev + test/OpenTelemetry.Extensions.Tests/: + - codeblanch test/OpenTelemetry.Extensions.PersistentStorage.Tests/: - vishweshbankwar test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: diff --git a/.github/workflows/package-Preview.yml b/.github/workflows/package-Preview.yml index ff5c30eaa3..e91bf19097 100644 --- a/.github/workflows/package-Preview.yml +++ b/.github/workflows/package-Preview.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Preview +name: Pack OpenTelemetry.Extensions on: workflow_dispatch: @@ -9,13 +9,13 @@ on: default: 'warning' push: tags: - - 'Preview-*' # trigger when we create a tag with prefix "Preview-" + - 'Extensions-*' # trigger when we create a tag with prefix "Extensions-" jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Preview + PROJECT: OpenTelemetry.Extensions strategy: matrix: @@ -36,7 +36,7 @@ jobs: run: dotnet test test/${{env.PROJECT}}.Tests - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Contrib.Preview has a conditional net5.0 target which causes dotnet pack to break when -no-build is used (for some reason) + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions has a conditional net5.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts uses: actions/upload-artifact@v2 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index dd17dbd7ee..7edfd46ffb 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -117,10 +117,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Tests.Shared", "test\OpenTelemetry.Contrib.Tests.Shared\OpenTelemetry.Contrib.Tests.Shared.csproj", "{C33F2D9D-89A6-459C-9A51-79BA5A9EF194}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Preview", "src\OpenTelemetry.Contrib.Preview\OpenTelemetry.Contrib.Preview.csproj", "{B978939B-278C-43A3-AD12-32EA9BBD27D0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Preview.Tests", "test\OpenTelemetry.Contrib.Preview.Tests\OpenTelemetry.Contrib.Preview.Tests.csproj", "{D2C68560-C252-41A9-B742-2CEB7D760E0F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" @@ -169,6 +165,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", "src\OpenTelemetry.Extensions\OpenTelemetry.Extensions.csproj", "{42B3FB71-BB42-46E3-9CEC-56620CB76BD9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -235,14 +235,6 @@ Global {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B978939B-278C-43A3-AD12-32EA9BBD27D0}.Release|Any CPU.Build.0 = Release|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D2C68560-C252-41A9-B742-2CEB7D760E0F}.Release|Any CPU.Build.0 = Release|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -335,6 +327,14 @@ Global {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.Build.0 = Debug|Any CPU {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.ActiveCfg = Release|Any CPU {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.Build.0 = Release|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Release|Any CPU.Build.0 = Release|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -360,8 +360,6 @@ Global {87FE0ED4-56A5-4775-9F63-DD532F2200BD} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {08EDD935-8B4E-4CF5-8840-200DEBA8E110} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {B978939B-278C-43A3-AD12-32EA9BBD27D0} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {D2C68560-C252-41A9-B742-2CEB7D760E0F} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} @@ -386,6 +384,8 @@ Global {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {67BFE7DF-505D-427E-8019-40BFF19363E9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2117F4E3-6612-4E4D-A757-27271EEB7783} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Preview/CHANGELOG.md b/src/OpenTelemetry.Contrib.Preview/CHANGELOG.md deleted file mode 100644 index 1512c42162..0000000000 --- a/src/OpenTelemetry.Contrib.Preview/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -# Changelog - -## Unreleased diff --git a/src/OpenTelemetry.Contrib.Preview/.publicApi/net461/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/.publicApi/net461/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Contrib.Preview/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/.publicApi/net461/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Contrib.Preview/.publicApi/net5.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/.publicApi/net5.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Contrib.Preview/.publicApi/net5.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/.publicApi/net5.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Contrib.Preview/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Contrib.Preview/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Contrib.Preview/AssemblyInfo.cs b/src/OpenTelemetry.Extensions/AssemblyInfo.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/AssemblyInfo.cs rename to src/OpenTelemetry.Extensions/AssemblyInfo.cs diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md new file mode 100644 index 0000000000..048b8e45e8 --- /dev/null +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +## Unreleased + +## 1.0.0-beta.3 + +* Going forward the NuGet package will be + [`OpenTelemetry.Extensions`](https://www.nuget.org/packages/OpenTelemetry.Extensions). + Older versions will remain at + [`OpenTelemetry.Contrib.Preview`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Preview) + [(#266)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/266) + +## 1.0.0-beta2 + +* This is the first release of `OpenTelemetry.Contrib.Preview` package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Contrib.Preview/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/Internal/ActivityEventAttachingLogProcessor.cs rename to src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs diff --git a/src/OpenTelemetry.Contrib.Preview/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/Internal/DefaultLogStateConverter.cs rename to src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs diff --git a/src/OpenTelemetry.Contrib.Preview/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/Internal/OpenTelemetryExtensionsEventSource.cs rename to src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs diff --git a/src/OpenTelemetry.Contrib.Preview/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/Logs/LogToActivityEventConversionOptions.cs rename to src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs diff --git a/src/OpenTelemetry.Contrib.Preview/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/Logs/OpenTelemetryLoggingExtensions.cs rename to src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs diff --git a/src/OpenTelemetry.Contrib.Preview/OpenTelemetry.Contrib.Preview.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Preview/OpenTelemetry.Contrib.Preview.csproj rename to src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj diff --git a/src/OpenTelemetry.Contrib.Preview/README.md b/src/OpenTelemetry.Extensions/README.md similarity index 59% rename from src/OpenTelemetry.Contrib.Preview/README.md rename to src/OpenTelemetry.Extensions/README.md index 90857a6c7f..f48b095b49 100644 --- a/src/OpenTelemetry.Contrib.Preview/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -1,6 +1,7 @@ # OpenTelemetry .NET SDK preview features and extensions -[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Preview.svg)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Preview/) +[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions) Contains useful features and extensions to the OpenTelemetry .NET SDK that are not part of the official OpenTelemetry specification but might be added in the diff --git a/test/OpenTelemetry.Contrib.Preview.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Preview.Tests/ActivityEventAttachingLogProcessorTests.cs rename to test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 455590b28f..676b92c2ae 100644 --- a/test/OpenTelemetry.Contrib.Preview.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -22,7 +22,7 @@ using OpenTelemetry.Logs; using Xunit; -namespace OpenTelemetry.Contrib.Preview.Tests +namespace OpenTelemetry.Extensions.Tests { public sealed class ActivityEventAttachingLogProcessorTests : IDisposable { @@ -116,7 +116,7 @@ public void AttachLogsToActivityEventTest( Dictionary tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(tags); - Assert.Equal("OpenTelemetry.Contrib.Preview.Tests.ActivityEventAttachingLogProcessorTests", tags[nameof(LogRecord.CategoryName)]); + Assert.Equal("OpenTelemetry.Extensions.Tests.ActivityEventAttachingLogProcessorTests", tags[nameof(LogRecord.CategoryName)]); Assert.Equal(LogLevel.Information, tags[nameof(LogRecord.LogLevel)]); if (eventId != 0) diff --git a/test/OpenTelemetry.Contrib.Preview.Tests/OpenTelemetry.Contrib.Preview.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj similarity index 90% rename from test/OpenTelemetry.Contrib.Preview.Tests/OpenTelemetry.Contrib.Preview.Tests.csproj rename to test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index d765e6745e..c3e00b0481 100644 --- a/test/OpenTelemetry.Contrib.Preview.Tests/OpenTelemetry.Contrib.Preview.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -22,7 +22,7 @@ - + From f45edd73341c4ae35c417ffb98c23aabbc11081a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 31 Mar 2022 10:52:31 -0700 Subject: [PATCH 0064/1499] Update company in README. (#269) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 60dc04e893..0966cc38d9 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Maintainers * [Alan West](https://github.com/alanwest), New Relic * [Cijo Thomas](https://github.com/cijothomas), Microsoft -* [Mikel Blanchard](https://github.com/CodeBlanch), CoStar Group +* [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft * [Prashant Srivastava](https://github.com/srprash), AWS * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev), Google * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft From ccc0f42afeeacbbcefe1d48d34b461c61418fda2 Mon Sep 17 00:00:00 2001 From: fred2u Date: Tue, 12 Apr 2022 16:26:01 +0200 Subject: [PATCH 0065/1499] Add Hangfire instrumentation (#271) --- .github/component_owners.yml | 4 + opentelemetry-dotnet-contrib.sln | 14 +++ .../Implementation/HangfireInstrumentation.cs | 45 +++++++++ .../HangfireInstrumentationConstants.cs | 27 ++++++ ...ngfireInstrumentationJobFilterAttribute.cs | 69 ++++++++++++++ ...nTelemetry.Instrumentation.Hangfire.csproj | 13 +++ .../README.md | 62 ++++++++++++ .../TracerProviderBuilderExtensions.cs | 44 +++++++++ .../HangfireFixture.cs | 43 +++++++++ ...eInstrumentationJobFilterAttributeTests.cs | 94 +++++++++++++++++++ ...etry.Instrumentation.Hangfire.Tests.csproj | 24 +++++ .../TestJob.cs | 33 +++++++ 12 files changed, 472 insertions(+) create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/README.md create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs create mode 100644 test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs diff --git a/.github/component_owners.yml b/.github/component_owners.yml index cce1ca18ff..0686afaf8b 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -15,6 +15,8 @@ components: - ejsmith src/OpenTelemetry.Instrumentation.GrpcCore/: - pcwiese + src/OpenTelemetry.Instrumentation.Hangfire/: + - fred2u src/OpenTelemetry.Instrumentation.MassTransit/: - alexvaluyskiy src/OpenTelemetry.Instrumentation.MySqlData/: @@ -39,6 +41,8 @@ components: - ejsmith test/OpenTelemetry.Instrumentation.GrpcCore.Tests/: - pcwiese + test/OpenTelemetry.Instrumentation.Hangfire.Tests/: + - fred2u test/OpenTelemetry.Instrumentation.MassTransit.Tests/: - alexvaluyskiy test/OpenTelemetry.Instrumentation.MySqlData.Tests/: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7edfd46ffb..440e9f1c95 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -169,6 +169,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire", "src\OpenTelemetry.Instrumentation.Hangfire\OpenTelemetry.Instrumentation.Hangfire.csproj", "{BE5FFBBB-D73F-4071-92F4-F1694881604F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -335,6 +339,14 @@ Global {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.Build.0 = Debug|Any CPU {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.ActiveCfg = Release|Any CPU {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.Build.0 = Release|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.Build.0 = Release|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -386,6 +398,8 @@ Global {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {42B3FB71-BB42-46E3-9CEC-56620CB76BD9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2117F4E3-6612-4E4D-A757-27271EEB7783} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs new file mode 100644 index 0000000000..2adc37cd77 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -0,0 +1,45 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation +{ + using System; + using System.Diagnostics; + using System.Reflection; + + internal static class HangfireInstrumentation + { + /// + /// The assembly name. + /// + internal static readonly AssemblyName AssemblyName = typeof(HangfireInstrumentation).Assembly.GetName(); + + /// + /// The activity source name. + /// + internal static readonly string ActivitySourceName = AssemblyName.Name; + + /// + /// The version. + /// + internal static readonly Version Version = AssemblyName.Version; + + /// + /// The activity source. + /// + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs new file mode 100644 index 0000000000..956a0ca3d0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation +{ + internal static class HangfireInstrumentationConstants + { + public const string JobIdTag = "job.id"; + public const string JobCreatedAtTag = "job.createdat"; + + public const string ActivityName = "JOB"; + public const string ActivityKey = "opentelemetry_activity_key"; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs new file mode 100644 index 0000000000..d00b78fd4e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -0,0 +1,69 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation +{ + using System.Diagnostics; + using global::Hangfire.Common; + using global::Hangfire.Server; + + internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter + { + public void OnPerforming(PerformingContext performingContext) + { + // Short-circuit if nobody is listening + if (!HangfireInstrumentation.ActivitySource.HasListeners()) + { + return; + } + + var activity = HangfireInstrumentation.ActivitySource + .StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext: default); + + if (activity != null) + { + activity.DisplayName = $"JOB {performingContext.BackgroundJob.Job.Type.Name}.{performingContext.BackgroundJob.Job.Method.Name}"; + + if (activity.IsAllDataRequested) + { + activity.SetTag(HangfireInstrumentationConstants.JobIdTag, performingContext.BackgroundJob.Id); + activity.SetTag(HangfireInstrumentationConstants.JobCreatedAtTag, performingContext.BackgroundJob.CreatedAt.ToString("O")); + } + + performingContext.Items.Add(HangfireInstrumentationConstants.ActivityKey, activity); + } + } + + public void OnPerformed(PerformedContext performedContext) + { + // Short-circuit if nobody is listening + if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.ContainsKey(HangfireInstrumentationConstants.ActivityKey)) + { + return; + } + + if (performedContext.Items[HangfireInstrumentationConstants.ActivityKey] is Activity activity) + { + if (performedContext.Exception != null) + { + activity.SetStatus(ActivityStatusCode.Error, performedContext.Exception.Message); + } + + activity.Dispose(); + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj new file mode 100644 index 0000000000..85b5c8efad --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -0,0 +1,13 @@ + + + netstandard2.0 + OpenTelemetry Hangfire Instrumentation + $(PackageTags);Hangfire + Instrumentation.Hangfire- + false + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md new file mode 100644 index 0000000000..951a14054b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -0,0 +1,62 @@ +# Hangfire Instrumentation for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Hangfire.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Hangfire.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) + +This is an +[Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments +[Hangfire](https://www.nuget.org/packages/Hangfire/) +and collects telemetry about BackgroundJob. + +## Steps to enable OpenTelemetry.Instrumentation.Hangfire + +### Step 1: Install and configure Hangfire + +[Getting Started](https://docs.hangfire.io/en/latest/getting-started/index.html) + +### Step 2: Install Hangfire instrumentation Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.Hangfire`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.Hangfire --prerelease +``` + +### Step 3: Enable Hangfire Instrumentation at application startup + +Hangfire instrumentation must be enabled at application startup. + +The following example demonstrates adding Hangfire instrumentation to a +console application. This example also sets up the OpenTelemetry Console +exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +For an ASP.NET Core application, adding instrumentation is typically done in +the `ConfigureServices` of your `Startup` class. Refer to [example](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/examples/AspNetCore/Program.cs). + +For an ASP.NET application, adding instrumentation is typically done in the +`Global.asax.cs`. Refer to [example](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/examples/AspNet/Global.asax.cs). + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) +* [Hangfire Project](https://www.hangfire.io/) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..1565151c2a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Trace +{ + using System; + using OpenTelemetry.Instrumentation.Hangfire.Implementation; + + /// + /// Extension methods to simplify registering of Hangfire job instrumentation. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Adds Hangfire instrumentation to the tracer provider. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute()); + + return builder.AddSource(HangfireInstrumentation.ActivitySourceName); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs new file mode 100644 index 0000000000..acb9ac64e3 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Hangfire; +using Hangfire.MemoryStorage; +using Hangfire.Storage; + +namespace OpenTelemetry.Instrumentation.Hangfire.Tests +{ + public class HangfireFixture : IDisposable + { + public HangfireFixture() + { + GlobalConfiguration.Configuration + .UseMemoryStorage(); + this.Server = new BackgroundJobServer(); + this.MonitoringApi = JobStorage.Current.GetMonitoringApi(); + } + + public BackgroundJobServer Server { get; } + + public IMonitoringApi MonitoringApi { get; } + + public void Dispose() + { + this.Server.Dispose(); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs new file mode 100644 index 0000000000..1f2d4347e7 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -0,0 +1,94 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Hangfire; +using Hangfire.Storage.Monitoring; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Hangfire.Tests +{ + public class HangfireInstrumentationJobFilterAttributeTests : IClassFixture + { + private HangfireFixture hangfireFixture; + + public HangfireInstrumentationJobFilterAttributeTests(HangfireFixture hangfireFixture) + { + this.hangfireFixture = hangfireFixture; + } + + [Fact] + public async Task Should_Create_Activity() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + // Act + var jobId = BackgroundJob.Enqueue(x => x.Execute()); + await this.WaitJobProcessedAsync(jobId, 5); + + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains("JOB TestJob.Execute", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + } + + [Fact] + public async Task Should_Create_Activity_With_Status_Error_When_Job_Failed() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + // Act + var jobId = BackgroundJob.Enqueue(x => x.ThrowException()); + await this.WaitJobProcessedAsync(jobId, 5); + + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.NotNull(activity.StatusDescription); + } + + private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) + { + var timeout = DateTime.Now.AddSeconds(timeToWaitInSeconds); + string[] states = new[] { "Enqueued", "Processing" }; + JobDetailsDto jobDetails; + while (((jobDetails = this.hangfireFixture.MonitoringApi.JobDetails(jobId)) == null || jobDetails.History.All(h => states.Contains(h.StateName))) + && DateTime.Now < timeout) + { + await Task.Delay(500); + } + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj new file mode 100644 index 0000000000..552d1cd1d3 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -0,0 +1,24 @@ + + + Unit test project for OpenTelemetry Hangfire instrumentation + net472;netcoreapp3.1 + false + false + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs new file mode 100644 index 0000000000..df112c6754 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -0,0 +1,33 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Instrumentation.Hangfire.Tests +{ + public class TestJob + { + public void Execute() + { + return; + } + + public void ThrowException() + { + throw new Exception(); + } + } +} From af31ca7a2ecdd3318f8e02c1ed80081a68fd1220 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 13 Apr 2022 10:48:59 -0700 Subject: [PATCH 0066/1499] Adding a Geneva Exporter - Exports to local ETW or UDS (#273) --- .github/workflows/dotnet-core-cov.yml | 2 +- opentelemetry-dotnet-contrib.sln | 27 + .../AssemblyInfo.cs | 16 + .../CHANGELOG.md | 3 + .../ConnectionStringBuilder.cs | 212 +++++ .../EtwDataTransport.cs | 77 ++ .../ExporterEventSource.cs | 74 ++ .../GenevaBaseExporter.cs | 77 ++ .../GenevaExporterHelperExtensions.cs | 41 + .../GenevaExporterOptions.cs | 63 ++ .../GenevaLogExporter.cs | 450 ++++++++++ .../GenevaLoggingExtensions.cs | 32 + .../GenevaMetricExporter.cs | 489 +++++++++++ .../GenevaMetricExporterExtensions.cs | 21 + .../GenevaMetricExporterOptions.cs | 66 ++ .../GenevaTraceExporter.cs | 435 ++++++++++ .../IDataTransport.cs | 9 + .../IMetricDataTransport.cs | 18 + .../MessagePackSerializer.cs | 559 +++++++++++++ .../MetricEtwDataTransport.cs | 46 ++ .../MetricSerializer.cs | 312 +++++++ .../MetricUnixDataTransport.cs | 37 + .../OpenTelemetry.Exporter.Geneva.csproj | 22 + src/OpenTelemetry.Exporter.Geneva/README.md | 3 + .../ReentrantExportProcessor.cs | 36 + src/OpenTelemetry.Exporter.Geneva/Schema.cs | 87 ++ .../ServiceProviderExtensions.cs | 31 + .../UnixDomainSocketDataTransport.cs | 93 +++ .../UnixDomainSocketEndPoint.cs | 79 ++ .../Exporter/LogExporterBenchmarks.cs | 160 ++++ .../Exporter/MetricExporterBenchmarks.cs | 624 ++++++++++++++ .../Exporter/TraceExporterBenchmarks.cs | 110 +++ ...Telemetry.Exporter.Geneva.Benchmark.csproj | 21 + .../Program.cs | 9 + .../DummyServer.cs | 86 ++ ...penTelemetry.Exporter.Geneva.Stress.csproj | 18 + .../Program.cs | 187 +++++ .../ConnectionStringBuilderTests.cs | 228 ++++++ .../GenevaLogExporterTests.cs | 768 ++++++++++++++++++ .../GenevaMetricExporterOptionsTests.cs | 57 ++ .../GenevaMetricExporterTests.cs | 726 +++++++++++++++++ .../GenevaTraceExporterTests.cs | 515 ++++++++++++ .../MessagePackSerializerTests.cs | 388 +++++++++ .../MetricsContract.cs | 665 +++++++++++++++ ...nTelemetry.Exporter.Geneva.UnitTest.csproj | 40 + .../UnixDomainSocketDataTransportTests.cs | 195 +++++ .../UnixDomainSocketEndPointTests.cs | 68 ++ 47 files changed, 8281 insertions(+), 1 deletion(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md create mode 100644 src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj create mode 100644 src/OpenTelemetry.Exporter.Geneva/README.md create mode 100644 src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/Schema.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj create mode 100644 test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index d97be6a35a..cd37a3197f 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -31,7 +31,7 @@ jobs: run: dotnet build --configuration Release --no-restore - name: dotnet test - run: dotnet test --collect:"Code Coverage" --results-directory:"TestResults" --configuration Release --no-build -- RunConfiguration.DisableAppDomain=true + run: dotnet test --collect:"Code Coverage" --results-directory:"TestResults" --configuration Release --no-build --filter "Platform=Any|Platform=Windows" -- RunConfiguration.DisableAppDomain=true - name: Process code coverage run: .\build\process-codecoverage.ps1 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 440e9f1c95..069d9252dd 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -169,6 +169,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva", "src\OpenTelemetry.Exporter.Geneva\OpenTelemetry.Exporter.Geneva.csproj", "{1105C814-31DA-4214-BEA8-6DB5FC12C808}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Benchmark", "test\OpenTelemetry.Exporter.Geneva.Benchmark\OpenTelemetry.Exporter.Geneva.Benchmark.csproj", "{F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Stress", "test\OpenTelemetry.Exporter.Geneva.Stress\OpenTelemetry.Exporter.Geneva.Stress.csproj", "{F632DFB6-38AD-4356-8997-8CCC0492619C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.UnitTest", "test\OpenTelemetry.Exporter.Geneva.UnitTest\OpenTelemetry.Exporter.Geneva.UnitTest.csproj", "{A3EB4E60-256C-45EC-92EE-68FD035CAD11}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire", "src\OpenTelemetry.Instrumentation.Hangfire\OpenTelemetry.Instrumentation.Hangfire.csproj", "{BE5FFBBB-D73F-4071-92F4-F1694881604F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" @@ -339,6 +346,22 @@ Global {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.Build.0 = Debug|Any CPU {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.ActiveCfg = Release|Any CPU {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.Build.0 = Release|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.Build.0 = Release|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Release|Any CPU.Build.0 = Release|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Release|Any CPU.Build.0 = Release|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Release|Any CPU.Build.0 = Release|Any CPU {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.Build.0 = Debug|Any CPU {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -398,6 +421,10 @@ Global {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {42B3FB71-BB42-46E3-9CEC-56620CB76BD9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2117F4E3-6612-4E4D-A757-27271EEB7783} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {1105C814-31DA-4214-BEA8-6DB5FC12C808} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {F632DFB6-38AD-4356-8997-8CCC0492619C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A3EB4E60-256C-45EC-92EE-68FD035CAD11} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs new file mode 100644 index 0000000000..afc852f07f --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System; +using System.Runtime.CompilerServices; + +[assembly: CLSCompliant(false)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Benchmark" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.UnitTest" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Stress" + AssemblyInfo.PublicKey)] + +internal static class AssemblyInfo +{ +#if SIGNED + public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; +#else + public const string PublicKey = ""; +#endif +} diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md new file mode 100644 index 0000000000..1512c42162 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +## Unreleased diff --git a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs new file mode 100644 index 0000000000..116294e313 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace OpenTelemetry.Exporter.Geneva +{ + internal enum TransportProtocol + { + Etw, + Tcp, + Udp, + Unix, + Unspecified, + } + + internal class ConnectionStringBuilder + { + private readonly Dictionary _parts = new Dictionary(StringComparer.Ordinal); + + public ConnectionStringBuilder(string connectionString) + { + if (string.IsNullOrWhiteSpace(connectionString)) + { + throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); + } + + const char Semicolon = ';'; + const char EqualSign = '='; + foreach (var token in connectionString.Split(Semicolon)) + { + if (string.IsNullOrWhiteSpace(token)) + { + continue; + } + + var index = token.IndexOf(EqualSign); + if (index == -1 || index != token.LastIndexOf(EqualSign)) + { + continue; + } + + var pair = token.Trim().Split(EqualSign); + + var key = pair[0].Trim(); + var value = pair[1].Trim(); + if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) + { + throw new ArgumentException("Connection string cannot contain empty keys or values."); + } + + this._parts[key] = value; + } + + if (this._parts.Count == 0) + { + throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); + } + } + + public string EtwSession + { + get => this.ThrowIfNotExists(nameof(this.EtwSession)); + set => this._parts[nameof(this.EtwSession)] = value; + } + + public string Endpoint + { + get => this.ThrowIfNotExists(nameof(this.Endpoint)); + set => this._parts[nameof(this.Endpoint)] = value; + } + + public TransportProtocol Protocol + { + get + { + try + { + // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux + if (this._parts.ContainsKey(nameof(this.EtwSession))) + { + return TransportProtocol.Etw; + } + + if (!this._parts.ContainsKey(nameof(this.Endpoint))) + { + return TransportProtocol.Unspecified; + } + + var endpoint = new Uri(this.Endpoint); + if (Enum.TryParse(endpoint.Scheme, true, out TransportProtocol protocol)) + { + return protocol; + } + + throw new ArgumentException("Endpoint scheme is invalid."); + } + catch (UriFormatException ex) + { + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); + } + } + } + + public string ParseUnixDomainSocketPath() + { + try + { + var endpoint = new Uri(this.Endpoint); + return endpoint.AbsolutePath; + } + catch (UriFormatException ex) + { + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); + } + } + + public int TimeoutMilliseconds + { + get + { + if (!this._parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string value)) + { + return UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds; + } + + try + { + int timeout = int.Parse(value, CultureInfo.InvariantCulture); + if (timeout <= 0) + { + throw new ArgumentException( + $"{nameof(this.TimeoutMilliseconds)} should be greater than zero.", + nameof(this.TimeoutMilliseconds)); + } + + return timeout; + } + catch (ArgumentException) + { + throw; + } + catch (Exception ex) + { + throw new ArgumentException( + $"{nameof(this.TimeoutMilliseconds)} is malformed.", + nameof(this.TimeoutMilliseconds), + ex); + } + } + set => this._parts[nameof(this.TimeoutMilliseconds)] = value.ToString(CultureInfo.InvariantCulture); + } + + public string Host + { + get + { + try + { + var endpoint = new Uri(this.Endpoint); + return endpoint.Host; + } + catch (UriFormatException ex) + { + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); + } + } + } + + public int Port + { + get + { + try + { + var endpoint = new Uri(this.Endpoint); + if (endpoint.IsDefaultPort) + { + throw new ArgumentException($"Port should be explicitly set in {nameof(this.Endpoint)} value."); + } + + return endpoint.Port; + } + catch (UriFormatException ex) + { + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); + } + } + } + + public string Account + { + get => this.ThrowIfNotExists(nameof(this.Account)); + set => this._parts[nameof(this.Account)] = value; + } + + public string Namespace + { + get => this.ThrowIfNotExists(nameof(this.Namespace)); + set => this._parts[nameof(this.Namespace)] = value; + } + + private T ThrowIfNotExists(string name) + { + if (!this._parts.TryGetValue(name, out var value)) + { + throw new ArgumentException($"'{name}' value is missing in connection string."); + } + + return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs new file mode 100644 index 0000000000..f72c7f3aac --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs @@ -0,0 +1,77 @@ +using System; +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Exporter.Geneva +{ + [EventSource(Name = "OpenTelemetry")] + internal class EtwEventSource : EventSource + { + public EtwEventSource(string providerName) + : base(providerName, EventSourceSettings.EtwManifestEventFormat) + { + } + + public enum EtwEventId + { + TraceEvent = 100, + } + + [Event((int)EtwEventId.TraceEvent, Version = 1, Level = EventLevel.Informational)] + public void InformationalEvent() + { + } + + [NonEvent] + public unsafe void SendEvent(int eventId, byte[] data, int size) + { + EventData* dataDesc = stackalloc EventData[1]; + fixed (byte* ptr = data) + { + dataDesc[0].DataPointer = (IntPtr)ptr; + dataDesc[0].Size = (int)size; + this.WriteEventCore(eventId, 1, dataDesc); + } + } + } + + internal class EtwDataTransport : IDataTransport, IDisposable + { + public EtwDataTransport(string providerName) + { + this.m_eventSource = new EtwEventSource(providerName); + } + + public void Send(byte[] data, int size) + { + this.m_eventSource.SendEvent((int)EtwEventSource.EtwEventId.TraceEvent, data, size); + } + + public bool IsEnabled() + { + return this.m_eventSource.IsEnabled(); + } + + private EtwEventSource m_eventSource; + private bool m_disposed; + + public void Dispose() + { + this.Dispose(true); + } + + protected virtual void Dispose(bool disposing) + { + if (this.m_disposed) + { + return; + } + + if (disposing) + { + this.m_eventSource.Dispose(); + } + + this.m_disposed = true; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs new file mode 100644 index 0000000000..ef7d349c4b --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs @@ -0,0 +1,74 @@ +using System; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Threading; + +namespace OpenTelemetry.Exporter.Geneva +{ + [EventSource(Name = "OpenTelemetry-Exporter-Geneva")] + internal class ExporterEventSource : EventSource + { + public static readonly ExporterEventSource Log = new ExporterEventSource(); + private const int EVENT_ID_TRACE = 1; + private const int EVENT_ID_METRICS = 2; + private const int EVENT_ID_ERROR = 3; + + [NonEvent] + public void ExporterException(Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.FailedToSendSpanData(ToInvariantString(ex)); + } + } + + [Event(EVENT_ID_TRACE, Message = "Exporter failed to send SpanData. Data will not be sent. Exception: {0}", Level = EventLevel.Error)] + public void FailedToSendSpanData(string ex) + { + // https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing + // ETW has a size limit: The total event size is greater than 64K. This includes the ETW header plus the data or payload. + // TODO: Do not hit ETW size limit even for external library exception stack. But what is the ETW header size? + // Source code: https://referencesource.microsoft.com/#mscorlib/system/diagnostics/eventing/eventsource.cs,867 + // Why is size calculated like below in WriteEvent source code? + // descrs[0].Size = ((arg1.Length + 1) * 2); + // I'm assuming it calculates the size of string, then it should be: + // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). + this.WriteEvent(EVENT_ID_TRACE, ex); + } + + [Event(EVENT_ID_METRICS, Message = "Exporter failed to send MetricData. Data will not be sent. MetricNamespace = {0}, MetricName = {1}, Message: {2}", Level = EventLevel.Error)] + public void FailedToSendMetricData(string metricNamespace, string metricName, string message) + { + this.WriteEvent(EVENT_ID_METRICS, metricNamespace, metricName, message); + } + + [Event(EVENT_ID_ERROR, Message = "Exporter failed.", Level = EventLevel.Error)] + public void ExporterError(string message) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + // TODO: We should ensure that GenevaTraceExporter doesn't emit any message that could hit ETW size limit. + this.WriteEvent(EVENT_ID_ERROR, message); + } + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs new file mode 100644 index 0000000000..2e3033e634 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; + +namespace OpenTelemetry.Exporter.Geneva +{ + public abstract class GenevaBaseExporter : BaseExporter + where T : class + { + internal static readonly IReadOnlyDictionary V21_PART_A_MAPPING = new Dictionary + { + // Part A + [Schema.V21.PartA.IKey] = "env_iKey", + [Schema.V21.PartA.Name] = "env_name", + [Schema.V21.PartA.Ver] = "env_ver", + [Schema.V21.PartA.Time] = "env_time", + [Schema.V21.PartA.Cv] = "env_cv", + [Schema.V21.PartA.Epoch] = "env_epoch", + [Schema.V21.PartA.Flags] = "env_flags", + [Schema.V21.PartA.PopSample] = "env_popSample", + [Schema.V21.PartA.SeqNum] = "env_seqNum", + + // Part A Application extension + [Schema.V21.PartA.Extensions.App.Id] = "env_appId", + [Schema.V21.PartA.Extensions.App.Ver] = "env_appVer", + + // Part A Cloud extension + [Schema.V21.PartA.Extensions.Cloud.Environment] = "env_cloud_environment", + [Schema.V21.PartA.Extensions.Cloud.Location] = "env_cloud_location", + [Schema.V21.PartA.Extensions.Cloud.Name] = "env_cloud_name", + [Schema.V21.PartA.Extensions.Cloud.DeploymentUnit] = "env_cloud_deploymentUnit", + [Schema.V21.PartA.Extensions.Cloud.Role] = "env_cloud_role", + [Schema.V21.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", + [Schema.V21.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", + [Schema.V21.PartA.Extensions.Cloud.Ver] = "env_cloud_ver", + + // Part A Os extension + [Schema.V21.PartA.Extensions.Os.Name] = "env_os", + [Schema.V21.PartA.Extensions.Os.Ver] = "env_osVer", + }; + + internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = new Dictionary + { + // Part A + [Schema.V40.PartA.IKey] = "env_iKey", + [Schema.V40.PartA.Name] = "env_name", + [Schema.V40.PartA.Ver] = "env_ver", + [Schema.V40.PartA.Time] = "env_time", + + // Part A Application Extension + [Schema.V40.PartA.Extensions.App.Id] = "env_app_id", + [Schema.V40.PartA.Extensions.App.Ver] = "env_app_ver", + + // Part A Cloud Extension + [Schema.V40.PartA.Extensions.Cloud.Role] = "env_cloud_role", + [Schema.V40.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", + [Schema.V40.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", + + // Part A Os extension + [Schema.V40.PartA.Extensions.Os.Name] = "env_os_name", + [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", + }; + + internal static int AddPartAField(byte[] buffer, int cursor, string name, object value) + { + if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + } + + cursor = MessagePackSerializer.Serialize(buffer, cursor, value); + return cursor; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs new file mode 100644 index 0000000000..88d21c564c --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -0,0 +1,41 @@ +using System; +using System.Diagnostics; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Exporter.Geneva +{ + public static class GenevaExporterHelperExtensions + { + public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + return deferredTracerProviderBuilder.Configure((sp, builder) => + { + AddGenevaTraceExporter(builder, sp.GetOptions(), configure); + }); + } + + return AddGenevaTraceExporter(builder, new GenevaExporterOptions(), configure); + } + + private static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, GenevaExporterOptions options, Action configure) + { + configure?.Invoke(options); + var exporter = new GenevaTraceExporter(options); + if (exporter.IsUsingUnixDomainSocket) + { + return builder.AddProcessor(new BatchActivityExportProcessor(exporter)); + } + else + { + return builder.AddProcessor(new ReentrantExportProcessor(exporter)); + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs new file mode 100644 index 0000000000..b3bdb80781 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +namespace OpenTelemetry.Exporter.Geneva +{ + public class GenevaExporterOptions + { + private IReadOnlyDictionary _fields = new Dictionary(1) + { + [Schema.V40.PartA.Ver] = "4.0", + }; + + public string ConnectionString { get; set; } + + public IEnumerable CustomFields { get; set; } + + public IReadOnlyDictionary TableNameMappings { get; set; } + + public IReadOnlyDictionary PrepopulatedFields + { + get => this._fields; + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + var schemaVersion = "4.0"; + + if (value.ContainsKey(Schema.V40.PartA.Ver)) + { + schemaVersion = value[Schema.V40.PartA.Ver] as string; + } + + if (schemaVersion != "2.1" && schemaVersion != "4.0") + { + throw new ArgumentException("Unsupported schema version, only 2.1 and 4.0 are supported."); + } + + if (value.ContainsKey(Schema.V40.PartA.Name)) + { + throw new ArgumentException("Event name cannot be pre-populated."); + } + + if (value.ContainsKey(Schema.V40.PartA.Time)) + { + throw new ArgumentException("Event timestamp cannot be pre-populated."); + } + + var copy = new Dictionary(value.Count + 1) { [Schema.V40.PartA.Ver] = schemaVersion }; + foreach (var entry in value) + { + copy[entry.Key] = entry.Value; // shallow copy + } + + this._fields = copy; + } + } + + internal Func ConvertToJson = obj => "ERROR: GenevaExporterOptions.ConvertToJson not configured."; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs new file mode 100644 index 0000000000..886a852438 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -0,0 +1,450 @@ +#if NETSTANDARD2_0 || NET461 +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.Geneva +{ + public class GenevaLogExporter : GenevaBaseExporter + { + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + + private readonly IReadOnlyDictionary m_customFields; + private readonly string m_defaultEventName = "Log"; + private readonly IReadOnlyDictionary m_prepopulatedFields; + private readonly List m_prepopulatedFieldKeys; + private static readonly ThreadLocal m_buffer = new ThreadLocal(() => null); + private readonly byte[] m_bufferEpilogue; + private static readonly string[] logLevels = new string[7] + { + "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", + }; + + private readonly IDataTransport m_dataTransport; + private bool isDisposed; + private Func convertToJson; + + public GenevaLogExporter(GenevaExporterOptions options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (string.IsNullOrWhiteSpace(options.ConnectionString)) + { + throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); + } + + // TODO: Validate mappings for reserved tablenames etc. + if (options.TableNameMappings != null) + { + var tempTableMappings = new Dictionary(options.TableNameMappings.Count, StringComparer.Ordinal); + foreach (var kv in options.TableNameMappings) + { + if (Encoding.UTF8.GetByteCount(kv.Value) != kv.Value.Length) + { + throw new ArgumentException("The value: \"{tableName}\" provided for TableNameMappings option contains non-ASCII characters", kv.Value); + } + + if (kv.Key == "*") + { + this.m_defaultEventName = kv.Value; + } + else + { + tempTableMappings[kv.Key] = kv.Value; + } + } + + this.m_tableMappings = tempTableMappings; + } + + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Etw: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); + } + + this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); + break; + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Tcp: + throw new ArgumentException("TCP transport is not supported yet."); + case TransportProtocol.Udp: + throw new ArgumentException("UDP transport is not supported yet."); + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } + + this.convertToJson = options.ConvertToJson; + + if (options.PrepopulatedFields != null) + { + this.m_prepopulatedFieldKeys = new List(); + var tempPrepopulatedFields = new Dictionary(options.PrepopulatedFields.Count, StringComparer.Ordinal); + foreach (var kv in options.PrepopulatedFields) + { + tempPrepopulatedFields[kv.Key] = kv.Value; + this.m_prepopulatedFieldKeys.Add(kv.Key); + } + + this.m_prepopulatedFields = tempPrepopulatedFields; + } + + // TODO: Validate custom fields (reserved name? etc). + if (options.CustomFields != null) + { + var customFields = new Dictionary(StringComparer.Ordinal); + foreach (var name in options.CustomFields) + { + customFields[name] = true; + } + + this.m_customFields = customFields; + } + + var buffer = new byte[BUFFER_SIZE]; + var cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); + this.m_bufferEpilogue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + } + + private readonly IReadOnlyDictionary m_tableMappings; + + public override ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + foreach (var logRecord in batch) + { + try + { + var cursor = this.SerializeLogRecord(logRecord); + this.m_dataTransport.Send(m_buffer.Value, cursor - 0); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } + } + + return result; + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } + + if (disposing) + { + // DO NOT Dispose m_buffer as it is a static type + try + { + (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_prepopulatedFieldKeys.Clear(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); + } + } + + this.isDisposed = true; + base.Dispose(disposing); + } + + internal bool IsUsingUnixDomainSocket + { + get => this.m_dataTransport is UnixDomainSocketDataTransport; + } + + internal int SerializeLogRecord(LogRecord logRecord) + { + bool isUnstructuredLog = true; + IReadOnlyList> listKvp; + if (logRecord.State == null) + { + listKvp = logRecord.StateValues; + } + else + { + listKvp = logRecord.State as IReadOnlyList>; + } + + if (listKvp != null) + { + isUnstructuredLog = listKvp.Count == 1; + } + + var name = logRecord.CategoryName; + + // If user configured explicit TableName, use it. + if (this.m_tableMappings == null || !this.m_tableMappings.TryGetValue(name, out var eventName)) + { + eventName = this.m_defaultEventName; + } + + var buffer = m_buffer.Value; + if (buffer == null) + { + buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM + m_buffer.Value = buffer; + } + + /* Fluentd Forward Mode: + [ + "Log", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + // Structured log. + // 2 scenarios. + // 1. Structured logging with template + // eg: + // body + // "Hello from {food} {price}." + // part c + // food = onion + // price = 100 + // TODO: 2. Structured with strongly typed logging. + var timestamp = logRecord.Timestamp; + var cursor = 0; + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, timestamp); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration + ushort cntFields = 0; + var idxMapSizePatch = cursor - 2; + + if (this.m_prepopulatedFieldKeys != null) + { + for (int i = 0; i < this.m_prepopulatedFieldKeys.Count; i++) + { + var key = this.m_prepopulatedFieldKeys[i]; + var value = this.m_prepopulatedFields[key]; + switch (value) + { + case bool vb: + case byte vui8: + case sbyte vi8: + case short vi16: + case ushort vui16: + case int vi32: + case uint vui32: + case long vi64: + case ulong vui64: + case float vf: + case double vd: + case string vs: + break; + default: + value = this.convertToJson(value); + break; + } + + cursor = AddPartAField(buffer, cursor, key, value); + cntFields += 1; + } + } + + // Part A - core envelope + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + cntFields += 1; + + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Time, timestamp); + cntFields += 1; + + // Part A - dt extension + if (logRecord.TraceId != default) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_traceId"); + + // Note: ToHexString returns the pre-calculated hex representation without allocation + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.TraceId.ToHexString()); + cntFields += 1; + } + + if (logRecord.SpanId != default) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_spanId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.SpanId.ToHexString()); + cntFields += 1; + } + + // Part A - ex extension + if (logRecord.Exception != null) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_type"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.Exception.GetType().FullName); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_msg"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); + cntFields += 1; + } + + // Part B + var logLevel = logRecord.LogLevel; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityText"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logLevels[(int)logLevel]); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityNumber"); + cursor = MessagePackSerializer.SerializeUInt8(buffer, cursor, GetSeverityNumber(logLevel)); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + cntFields += 1; + + if (isUnstructuredLog) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? (listKvp != null ? Convert.ToString(listKvp[0].Value, CultureInfo.InvariantCulture) : Convert.ToString(logRecord.State, CultureInfo.InvariantCulture))); + cntFields += 1; + } + else + { + bool hasEnvProperties = false; + bool bodyPopulated = false; + for (int i = 0; i < listKvp.Count; i++) + { + var entry = listKvp[i]; + + // Iteration #1 - Get those fields which become dedicated column + // i.e all PartB fields and opt-in part c fields. + if (entry.Key == "{OriginalFormat}") + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); + cntFields += 1; + bodyPopulated = true; + continue; + } + else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + { + // TODO: the above null check can be optimized and avoided inside foreach. + if (entry.Value != null) + { + // Geneva doesn't support null. + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + cntFields += 1; + } + } + else + { + hasEnvProperties = true; + continue; + } + } + + if (!bodyPopulated && logRecord.FormattedMessage != null) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage); + cntFields += 1; + } + + if (hasEnvProperties) + { + // Iteration #2 - Get all "other" fields and collapse them into single field + // named "env_properties". + ushort envPropertiesCount = 0; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int idxMapSizeEnvPropertiesPatch = cursor - 2; + for (int i = 0; i < listKvp.Count; i++) + { + var entry = listKvp[i]; + if (entry.Key == "{OriginalFormat}" || this.m_customFields.ContainsKey(entry.Key)) + { + continue; + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + envPropertiesCount += 1; + } + } + + cntFields += 1; + MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); + } + } + + var eventId = logRecord.EventId; + if (eventId != default) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "eventId"); + cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, eventId.Id); + cntFields += 1; + } + + MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); + Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); + cursor += this.m_bufferEpilogue.Length; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static byte GetSeverityNumber(LogLevel logLevel) + { + // Maps the Ilogger LogLevel to OpenTelemetry logging level. + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#mapping-of-severitynumber + // TODO: for improving perf simply do ((int)loglevel * 4) + 1 + // or ((int)logLevel << 2) + 1 + switch (logLevel) + { + case LogLevel.Trace: + return 1; + case LogLevel.Debug: + return 5; + case LogLevel.Information: + return 9; + case LogLevel.Warning: + return 13; + case LogLevel.Error: + return 17; + case LogLevel.Critical: + return 21; + + // we reach default only for LogLevel.None + // but that is filtered out anyway. + // should we throw here then? + default: + return 1; + } + } + } +} +#endif diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs new file mode 100644 index 0000000000..f0c7ee945b --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -0,0 +1,32 @@ +#if NETSTANDARD2_0 || NET461 +using System; +using OpenTelemetry; +using OpenTelemetry.Exporter.Geneva; +using OpenTelemetry.Logs; + +namespace Microsoft.Extensions.Logging +{ + public static class GenevaLoggingExtensions + { + public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetryLoggerOptions options, Action configure) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + var genevaOptions = new GenevaExporterOptions(); + configure?.Invoke(genevaOptions); + var exporter = new GenevaLogExporter(genevaOptions); + if (exporter.IsUsingUnixDomainSocket) + { + return options.AddProcessor(new BatchLogRecordExportProcessor(exporter)); + } + else + { + return options.AddProcessor(new ReentrantExportProcessor(exporter)); + } + } + } +} +#endif diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs new file mode 100644 index 0000000000..09d8dc2243 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -0,0 +1,489 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.Geneva +{ + [AggregationTemporality(AggregationTemporality.Delta)] + public class GenevaMetricExporter : BaseExporter + { + private const int BufferSize = 65360; // the maximum ETW payload (inclusive) + + internal const int MaxDimensionNameSize = 256; + + internal const int MaxDimensionValueSize = 1024; + + private readonly ushort prepopulatedDimensionsCount; + + private readonly int fixedPayloadStartIndex; + + private readonly string monitoringAccount; + + private readonly string metricNamespace; + + private readonly IMetricDataTransport metricDataTransport; + + private readonly List serializedPrepopulatedDimensionsKeys; + + private readonly List serializedPrepopulatedDimensionsValues; + + private readonly byte[] bufferForNonHistogramMetrics = new byte[BufferSize]; + + private readonly byte[] bufferForHistogramMetrics = new byte[BufferSize]; + + private readonly int bufferIndexForNonHistogramMetrics; + + private readonly int bufferIndexForHistogramMetrics; + + private static readonly MetricData ulongZero = new MetricData { UInt64Value = 0 }; + + private bool isDisposed; + + public GenevaMetricExporter(GenevaMetricExporterOptions options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (string.IsNullOrWhiteSpace(options.ConnectionString)) + { + throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); + } + + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + this.monitoringAccount = connectionStringBuilder.Account; + this.metricNamespace = connectionStringBuilder.Namespace; + + if (options.PrepopulatedMetricDimensions != null) + { + this.prepopulatedDimensionsCount = (ushort)options.PrepopulatedMetricDimensions.Count; + this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(options.PrepopulatedMetricDimensions.Keys); + this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(options.PrepopulatedMetricDimensions.Values); + } + + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Tcp: + throw new ArgumentException("TCP transport is not supported yet."); + case TransportProtocol.Udp: + throw new ArgumentException("UDP transport is not supported yet."); + case TransportProtocol.Unspecified: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + this.metricDataTransport = new MetricEtwDataTransport(); + break; + } + else + { + throw new ArgumentException("Endpoint not specified"); + } + + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } + + this.bufferIndexForNonHistogramMetrics = this.InitializeBufferForNonHistogramMetrics(); + this.bufferIndexForHistogramMetrics = this.InitializeBufferForHistogramMetrics(); + + unsafe + { + this.fixedPayloadStartIndex = sizeof(BinaryHeader); + } + } + + public override ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + foreach (var metric in batch) + { + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + try + { + switch (metric.MetricType) + { + case MetricType.LongSum: + { + var ulongSum = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = ulongSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.LongGauge: + { + var ulongSum = Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { UInt64Value = ulongSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.DoubleSum: + { + var doubleSum = metricPoint.GetSumDouble(); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.DoubleGauge: + { + var doubleSum = metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.Histogram: + { + var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + var bodyLength = this.SerializeHistogramMetric( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count); + this.metricDataTransport.Send(MetricEventType.ExternallyAggregatedULongDistributionMetric, this.bufferForHistogramMetrics, bodyLength); + break; + } + } + } + catch (Exception ex) + { + ExporterEventSource.Log.FailedToSendMetricData(this.metricNamespace, metric.Name, ex.Message); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } + } + } + + return result; + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } + + if (disposing) + { + try + { + this.metricDataTransport?.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); + } + } + + this.isDisposed = true; + base.Dispose(disposing); + } + + internal unsafe ushort SerializeMetric( + MetricEventType eventType, + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + MetricData value) + { + ushort bodyLength; + try + { + var bufferIndex = this.bufferIndexForNonHistogramMetrics; + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, metricName); + + ushort dimensionsWritten = 0; + + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, tag.Key); + } + + dimensionsWritten += (ushort)tags.Count; + + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } + + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, dimensionValue); + } + + // The Autopilot container name is optional but still preserve the location with zero length if it is empty. + MetricSerializer.SerializeInt16(this.bufferForNonHistogramMetrics, ref bufferIndex, 0); + + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.bufferForNonHistogramMetrics) + { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)eventType; + ptr->BodyLength = bodyLength; + + var payloadPtr = (MetricPayload*)&bufferBytes[this.fixedPayloadStartIndex]; + payloadPtr->CountDimension = dimensionsWritten; + payloadPtr->ReservedWord = 0; + payloadPtr->ReservedDword = 0; + payloadPtr->TimestampUtc = (ulong)timestamp; + payloadPtr->Data = value; + } + } + finally + { + } + + return bodyLength; + } + + internal unsafe ushort SerializeHistogramMetric( + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + HistogramBuckets buckets, + MetricData sum, + uint count) + { + ushort bodyLength; + try + { + var bufferIndex = this.bufferIndexForHistogramMetrics; + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, metricName); + + ushort dimensionsWritten = 0; + + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, tag.Key); + } + + dimensionsWritten += (ushort)tags.Count; + + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } + + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, dimensionValue); + } + + // The Autopilot container name is optional but still preserve the location with zero length if it is empty. + MetricSerializer.SerializeInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); + + // Version + MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 0); + + // Meta-data + // Value-count pairs is associated with the constant value of 2 in the distribution_type enum. + MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 2); + + // Keep a position to record how many buckets are added + var itemsWrittenIndex = bufferIndex; + MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); + + // Bucket values + ushort bucketCount = 0; + double lastExplicitBound = default; + foreach (var bucket in buckets) + { + if (bucket.BucketCount > 0) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + lastExplicitBound = bucket.ExplicitBound; + } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + bucketCount++; + } + } + + // Write the number of items in distribution emitted and reset back to end. + MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref itemsWrittenIndex, bucketCount); + + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.bufferForHistogramMetrics) + { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric; + ptr->BodyLength = bodyLength; + + var payloadPtr = (ExternalPayload*)&bufferBytes[this.fixedPayloadStartIndex]; + payloadPtr[0].CountDimension = dimensionsWritten; + payloadPtr[0].ReservedWord = 0; + payloadPtr[0].Count = count; + payloadPtr[0].TimestampUtc = (ulong)timestamp; + payloadPtr[0].Sum = sum; + payloadPtr[0].Min = ulongZero; + payloadPtr[0].Max = ulongZero; + } + } + finally + { + } + + return bodyLength; + } + + private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) + { + var serializedKeys = new List(this.prepopulatedDimensionsCount); + foreach (var key in keys) + { + serializedKeys.Add(Encoding.UTF8.GetBytes(key)); + } + + return serializedKeys; + } + + private List SerializePrepopulatedDimensionsValues(IEnumerable values) + { + var serializedValues = new List(this.prepopulatedDimensionsCount); + foreach (var value in values) + { + var valueAsString = Convert.ToString(value, CultureInfo.InvariantCulture); + serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); + } + + return serializedValues; + } + + private unsafe int InitializeBufferForNonHistogramMetrics() + { + // The buffer format is as follows: + // -- BinaryHeader + // -- MetricPayload + // -- Variable length content + + // Leave enough space for the header and fixed payload + var bufferIndex = sizeof(BinaryHeader) + sizeof(MetricPayload); + + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.monitoringAccount); + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.metricNamespace); + + return bufferIndex; + } + + private unsafe int InitializeBufferForHistogramMetrics() + { + // The buffer format is as follows: + // -- BinaryHeader + // -- ExternalPayload + // -- Variable length content + + // Leave enough space for the header and fixed payload + var bufferIndex = sizeof(BinaryHeader) + sizeof(ExternalPayload); + + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.monitoringAccount); + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.metricNamespace); + + return bufferIndex; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs new file mode 100644 index 0000000000..dcf0df1bec --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -0,0 +1,21 @@ +using System; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.Geneva +{ + public static class GenevaMetricExporterExtensions + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] + public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure = null) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + + var options = new GenevaMetricExporterOptions(); + configure?.Invoke(options); + return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds)); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs new file mode 100644 index 0000000000..81a629d3b0 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace OpenTelemetry.Exporter.Geneva +{ + public class GenevaMetricExporterOptions + { + private IReadOnlyDictionary _prepopulatedMetricDimensions; + + /// + /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. + /// For e.g.: "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace". + /// + public string ConnectionString { get; set; } + + /// + /// Gets or sets the metric export interval in milliseconds. The default value is 20000. + /// + public int MetricExportIntervalMilliseconds { get; set; } = 20000; + + /// + /// Gets or sets the pre-populated dimensions for all the metrics exported by the exporter. + /// + public IReadOnlyDictionary PrepopulatedMetricDimensions + { + get + { + return this._prepopulatedMetricDimensions; + } + + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(value)); + } + + var copy = new Dictionary(value.Count); + + foreach (var entry in value) + { + if (entry.Key.Length > GenevaMetricExporter.MaxDimensionNameSize) + { + throw new ArgumentException($"The dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."); + } + + if (entry.Value == null) + { + throw new ArgumentNullException($"{nameof(this.PrepopulatedMetricDimensions)}[\"{entry.Key}\"]"); + } + + var dimensionValue = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > GenevaMetricExporter.MaxDimensionValueSize) + { + throw new ArgumentException($"Value provided for the dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."); + } + + copy[entry.Key] = entry.Value; // shallow copy + } + + this._prepopulatedMetricDimensions = copy; + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs new file mode 100644 index 0000000000..1eff7967a5 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -0,0 +1,435 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; + +namespace OpenTelemetry.Exporter.Geneva +{ + public class GenevaTraceExporter : GenevaBaseExporter + { + public GenevaTraceExporter(GenevaExporterOptions options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + if (string.IsNullOrWhiteSpace(options.ConnectionString)) + { + throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); + } + + var partAName = "Span"; + if (options.TableNameMappings != null + && options.TableNameMappings.TryGetValue("Span", out var customTableName)) + { + if (string.IsNullOrWhiteSpace(customTableName)) + { + throw new ArgumentException("TableName mapping for Span is invalid."); + } + + if (Encoding.UTF8.GetByteCount(customTableName) != customTableName.Length) + { + throw new ArgumentException("The \"{customTableName}\" provided for TableNameMappings option contains non-ASCII characters", customTableName); + } + + partAName = customTableName; + } + + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Etw: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); + } + + this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); + break; + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Tcp: + throw new ArgumentException("TCP transport is not supported yet."); + case TransportProtocol.Udp: + throw new ArgumentException("UDP transport is not supported yet."); + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } + + // TODO: Validate custom fields (reserved name? etc). + if (options.CustomFields != null) + { + var customFields = new Dictionary(StringComparer.Ordinal); + var dedicatedFields = new Dictionary(StringComparer.Ordinal); + + // Seed customFields with Span PartB + customFields["azureResourceProvider"] = true; + dedicatedFields["azureResourceProvider"] = true; + foreach (var name in CS40_PART_B_MAPPING.Values) + { + customFields[name] = true; + dedicatedFields[name] = true; + } + + foreach (var name in options.CustomFields) + { + customFields[name] = true; + dedicatedFields[name] = true; + } + + this.m_customFields = customFields; + + foreach (var name in CS40_PART_B_MAPPING.Keys) + { + dedicatedFields[name] = true; + } + + dedicatedFields["otel.status_code"] = true; + this.m_dedicatedFields = dedicatedFields; + } + + var buffer = new byte[BUFFER_SIZE]; + + var cursor = 0; + + /* Fluentd Forward Mode: + [ + "Span", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, partAName); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); + + // timestamp + cursor = MessagePackSerializer.WriteTimestamp96Header(buffer, cursor); + this.m_idxTimestampPatch = cursor; + cursor += 12; // reserve 12 bytes for the timestamp + + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration + this.m_idxMapSizePatch = cursor - 2; + + this.m_cntPrepopulatedFields = 0; + + // TODO: Do we support PartB as well? + // Part A - core envelope + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); + this.m_cntPrepopulatedFields += 1; + + foreach (var entry in options.PrepopulatedFields) + { + var value = entry.Value; + switch (value) + { + case bool vb: + case byte vui8: + case sbyte vi8: + case short vi16: + case ushort vui16: + case int vi32: + case uint vui32: + case long vi64: + case ulong vui64: + case float vf: + case double vd: + case string vs: + break; + default: + value = options.ConvertToJson(value); + break; + } + + cursor = AddPartAField(buffer, cursor, entry.Key, value); + this.m_cntPrepopulatedFields += 1; + } + + this.m_bufferPrologue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.m_bufferPrologue, 0, cursor - 0); + + cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); + + this.m_bufferEpilogue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + } + + public override ExportResult Export(in Batch batch) + { + // Note: The MessagePackSerializer takes way less time / memory than creating the activity itself. + // This makes the short-circuit check less useful. + // On the other side, running the serializer could help to catch error in the early phase of development lifecycle. + // + // if (!m_dataTransport.IsEnabled()) + // { + // return ExportResult.Success; + // } + + var result = ExportResult.Success; + foreach (var activity in batch) + { + try + { + var cursor = this.SerializeActivity(activity); + this.m_dataTransport.Send(this.m_buffer.Value, cursor - 0); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } + } + + return result; + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } + + if (disposing) + { + try + { + (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_buffer.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); + } + } + + this.isDisposed = true; + base.Dispose(disposing); + } + + internal bool IsUsingUnixDomainSocket + { + get => this.m_dataTransport is UnixDomainSocketDataTransport; + } + + internal int SerializeActivity(Activity activity) + { + var buffer = this.m_buffer.Value; + if (buffer == null) + { + buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM + Buffer.BlockCopy(this.m_bufferPrologue, 0, buffer, 0, this.m_bufferPrologue.Length); + this.m_buffer.Value = buffer; + } + + var cursor = this.m_bufferPrologue.Length; + var cntFields = this.m_cntPrepopulatedFields; + var dtBegin = activity.StartTimeUtc; + var tsBegin = dtBegin.Ticks; + var tsEnd = tsBegin + activity.Duration.Ticks; + var dtEnd = new DateTime(tsEnd); + + MessagePackSerializer.WriteTimestamp96(buffer, this.m_idxTimestampPatch, tsEnd); + + #region Part A - core envelope + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_time"); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, dtEnd); + cntFields += 1; + #endregion + + #region Part A - dt extension + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_traceId"); + + // Note: ToHexString returns the pre-calculated hex representation without allocation + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, activity.Context.TraceId.ToHexString()); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_spanId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, activity.Context.SpanId.ToHexString()); + cntFields += 1; + #endregion + + #region Part B Span - required fields + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, activity.DisplayName); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "kind"); + cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, (int)activity.Kind); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "startTime"); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, dtBegin); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "success"); + cursor = MessagePackSerializer.SerializeBool(buffer, cursor, true); + var idxSuccessPatch = cursor - 1; + cntFields += 1; + #endregion + + #region Part B Span optional fields and Part C fields + var strParentId = activity.ParentSpanId.ToHexString(); + + // Note: this should be blazing fast since Object.ReferenceEquals(strParentId, INVALID_SPAN_ID) == true + if (!string.Equals(strParentId, INVALID_SPAN_ID, StringComparison.Ordinal)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "parentId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, strParentId); + cntFields += 1; + } + + var links = activity.Links; + if (links.Any()) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "links"); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); // Note: always use Array16 for perf consideration + var idxLinkPatch = cursor - 2; + ushort cntLink = 0; + foreach (var link in links) + { + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, 2); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toTraceId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.TraceId.ToHexString()); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toSpanId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.SpanId.ToHexString()); + cntLink += 1; + } + + MessagePackSerializer.WriteUInt16(buffer, idxLinkPatch, cntLink); + cntFields += 1; + } + + // TODO: The current approach is to iterate twice over TagObjects so that all + // env_properties can be added the very end. This avoids speculating the size + // and preallocating a separate buffer for it. + // Alternates include static allocation and iterate once. + // The TODO: here is to measure perf and change to alternate, if required. + + // Iteration #1 - Get those fields which become dedicated column + // i.e all PartB fields and opt-in part c fields. + bool hasEnvProperties = false; + foreach (var entry in activity.TagObjects) + { + // TODO: check name collision + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); + } + else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) + { + if (string.Equals(entry.Value.ToString(), "ERROR", StringComparison.Ordinal)) + { + MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); + } + + continue; + } + else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + { + // TODO: the above null check can be optimized and avoided inside foreach. + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + } + else + { + hasEnvProperties = true; + continue; + } + + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + cntFields += 1; + } + + if (hasEnvProperties) + { + // Iteration #2 - Get all "other" fields and collapse them into single field + // named "env_properties". + ushort envPropertiesCount = 0; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int idxMapSizeEnvPropertiesPatch = cursor - 2; + + foreach (var entry in activity.TagObjects) + { + // TODO: check name collision + if (this.m_dedicatedFields.ContainsKey(entry.Key)) + { + continue; + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + envPropertiesCount += 1; + } + } + + cntFields += 1; + MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); + } + #endregion + + MessagePackSerializer.WriteUInt16(buffer, this.m_idxMapSizePatch, cntFields); + + Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); + cursor += this.m_bufferEpilogue.Length; + + return cursor; + } + + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + + private readonly ThreadLocal m_buffer = new ThreadLocal(() => null); + + private readonly byte[] m_bufferPrologue; + + private readonly byte[] m_bufferEpilogue; + + private readonly ushort m_cntPrepopulatedFields; + + private readonly int m_idxTimestampPatch; + + private readonly int m_idxMapSizePatch; + + private readonly IDataTransport m_dataTransport; + + private readonly IReadOnlyDictionary m_customFields; + + private readonly IReadOnlyDictionary m_dedicatedFields; + + private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); + + private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary + { + ["db.system"] = "dbSystem", + ["db.name"] = "dbName", + ["db.statement"] = "dbStatement", + + ["http.method"] = "httpMethod", + ["http.url"] = "httpUrl", + ["http.status_code"] = "httpStatusCode", + + ["messaging.system"] = "messagingSystem", + ["messaging.destination"] = "messagingDestination", + ["messaging.url"] = "messagingUrl", + + ["otel.status_description"] = "statusMessage", + }; + + private bool isDisposed; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs new file mode 100644 index 0000000000..2fb314b332 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs @@ -0,0 +1,9 @@ +namespace OpenTelemetry.Exporter.Geneva +{ + internal interface IDataTransport + { + bool IsEnabled(); + + void Send(byte[] data, int size); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs new file mode 100644 index 0000000000..09d84a21f8 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs @@ -0,0 +1,18 @@ +using System; + +namespace OpenTelemetry.Exporter.Geneva +{ + internal interface IMetricDataTransport : IDisposable + { + /// + /// Writes a standard metric event containing only a single value. + /// + /// Type of the event. + /// The byte array containing the serialized data. + /// Length of the payload (fixed + variable). + void Send( + MetricEventType eventType, + byte[] body, + int size); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs new file mode 100644 index 0000000000..6ab2bb6258 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs @@ -0,0 +1,559 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Text; + +namespace OpenTelemetry.Exporter.Geneva +{ + internal static class MessagePackSerializer + { + public const byte MIN_FIX_MAP = 0x80; + public const byte MIN_FIX_ARRAY = 0x90; + public const byte MIN_FIX_STR = 0xA0; + public const byte NIL = 0xC0; + public const byte FALSE = 0xC2; + public const byte TRUE = 0xC3; + public const byte BIN8 = 0xC4; + public const byte BIN16 = 0xC5; + public const byte BIN32 = 0xC6; + public const byte TIMESTAMP96 = 0xC7; + public const byte FLOAT32 = 0xCA; + public const byte FLOAT64 = 0xCB; + public const byte UINT8 = 0xCC; + public const byte UINT16 = 0xCD; + public const byte UINT32 = 0xCE; + public const byte UINT64 = 0xCF; + public const byte INT8 = 0xD0; + public const byte INT16 = 0xD1; + public const byte INT32 = 0xD2; + public const byte INT64 = 0xD3; + public const byte TIMESTAMP32 = 0xD6; + public const byte TIMESTAMP64 = 0xD7; + public const byte STR8 = 0xD9; + public const byte STR16 = 0xDA; + public const byte STR32 = 0xDB; + public const byte ARRAY16 = 0xDC; + public const byte ARRAY32 = 0xDD; + public const byte MAP16 = 0xDE; + public const byte MAP32 = 0xDF; + public const byte EXT_DATE_TIME = 0xFF; + + private const int LIMIT_MIN_FIX_NEGATIVE_INT = -32; + private const int LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES = 31; + private const int LIMIT_MAX_STR8_LENGTH_IN_BYTES = (1 << 8) - 1; // str8 stores 2^8 - 1 bytes + private const int LIMIT_MAX_FIX_MAP_COUNT = 15; + private const int LIMIT_MAX_FIX_ARRAY_LENGTH = 15; + private const int STRING_SIZE_LIMIT_CHAR_COUNT = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeNull(byte[] buffer, int cursor) + { + buffer[cursor++] = NIL; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeBool(byte[] buffer, int cursor, bool value) + { + buffer[cursor++] = value ? TRUE : FALSE; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt8(byte[] buffer, int cursor, sbyte value) + { + if (value >= 0) + { + return SerializeUInt8(buffer, cursor, unchecked((byte)value)); + } + + if (value < LIMIT_MIN_FIX_NEGATIVE_INT) + { + buffer[cursor++] = INT8; + } + + buffer[cursor++] = unchecked((byte)value); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt16(byte[] buffer, int cursor, short value) + { + if (value >= 0) + { + return SerializeUInt16(buffer, cursor, unchecked((ushort)value)); + } + + if (value >= sbyte.MinValue) + { + return SerializeInt8(buffer, cursor, unchecked((sbyte)value)); + } + + buffer[cursor++] = INT16; + return WriteInt16(buffer, cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt32(byte[] buffer, int cursor, int value) + { + if (value >= 0) + { + return SerializeUInt32(buffer, cursor, unchecked((uint)value)); + } + + if (value >= short.MinValue) + { + return SerializeInt16(buffer, cursor, unchecked((short)value)); + } + + buffer[cursor++] = INT32; + return WriteInt32(buffer, cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt64(byte[] buffer, int cursor, long value) + { + if (value >= 0) + { + return SerializeUInt64(buffer, cursor, unchecked((ulong)value)); + } + + if (value >= int.MinValue) + { + return SerializeInt32(buffer, cursor, unchecked((int)value)); + } + + buffer[cursor++] = INT64; + return WriteInt64(buffer, cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt8(byte[] buffer, int cursor, byte value) + { + if (value > 127) + { + buffer[cursor++] = UINT8; + } + + buffer[cursor++] = value; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt16(byte[] buffer, int cursor, ushort value) + { + if (value <= byte.MaxValue) + { + return SerializeUInt8(buffer, cursor, unchecked((byte)value)); + } + + buffer[cursor++] = UINT16; + return WriteUInt16(buffer, cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt32(byte[] buffer, int cursor, uint value) + { + if (value <= ushort.MaxValue) + { + return SerializeUInt16(buffer, cursor, unchecked((ushort)value)); + } + + buffer[cursor++] = UINT32; + return WriteUInt32(buffer, cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt64(byte[] buffer, int cursor, ulong value) + { + if (value <= uint.MaxValue) + { + return SerializeUInt32(buffer, cursor, unchecked((uint)value)); + } + + buffer[cursor++] = UINT64; + return WriteUInt64(buffer, cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteInt16(byte[] buffer, int cursor, short value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteInt32(byte[] buffer, int cursor, int value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteInt64(byte[] buffer, int cursor, long value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 56); + buffer[cursor++] = (byte)(value >> 48); + buffer[cursor++] = (byte)(value >> 40); + buffer[cursor++] = (byte)(value >> 32); + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUInt16(byte[] buffer, int cursor, ushort value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUInt32(byte[] buffer, int cursor, uint value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUInt64(byte[] buffer, int cursor, ulong value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 56); + buffer[cursor++] = (byte)(value >> 48); + buffer[cursor++] = (byte)(value >> 40); + buffer[cursor++] = (byte)(value >> 32); + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeFloat32(byte[] buffer, int cursor, float value) + { + buffer[cursor++] = FLOAT32; + return WriteInt32(buffer, cursor, Float32ToInt32(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe int Float32ToInt32(float value) + { + return *(int*)&value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeFloat64(byte[] buffer, int cursor, double value) + { + buffer[cursor++] = FLOAT64; + return WriteInt64(buffer, cursor, Float64ToInt64(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe long Float64ToInt64(double value) + { + return *(long*)&value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeAsciiString(byte[] buffer, int cursor, string value) + { + if (value == null) + { + return SerializeNull(buffer, cursor); + } + + int start = cursor; + var cch = value.Length; + int cb; + if (cch <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) + { + cursor += 1; + cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); + if (cb <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) + { + cursor += cb; + buffer[start] = unchecked((byte)(MIN_FIX_STR | cb)); + return cursor; + } + else + { + throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); + } + } + + if (cch <= LIMIT_MAX_STR8_LENGTH_IN_BYTES) + { + cursor += 2; + cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); + cursor += cb; + if (cb <= LIMIT_MAX_STR8_LENGTH_IN_BYTES) + { + buffer[start] = STR8; + buffer[start + 1] = unchecked((byte)cb); + return cursor; + } + else + { + throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); + } + } + + cursor += 3; + if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) + { + cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); + cursor += cb; + } + else + { + cb = Encoding.ASCII.GetBytes(value, 0, STRING_SIZE_LIMIT_CHAR_COUNT - 3, buffer, cursor); + cursor += cb; + cb += 3; + + // append "..." to indicate the string truncation + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + } + + buffer[start] = STR16; + buffer[start + 1] = unchecked((byte)(cb >> 8)); + buffer[start + 2] = unchecked((byte)cb); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUnicodeString(byte[] buffer, int cursor, string value) + { + if (value == null) + { + return SerializeNull(buffer, cursor); + } + + int start = cursor; + var cch = value.Length; + int cb; + cursor += 3; + if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) + { + cb = Encoding.UTF8.GetBytes(value, 0, cch, buffer, cursor); + cursor += cb; + } + else + { + cb = Encoding.UTF8.GetBytes(value, 0, STRING_SIZE_LIMIT_CHAR_COUNT - 3, buffer, cursor); + cursor += cb; + cb += 3; + + // append "..." to indicate the string truncation + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + } + + buffer[start] = STR16; + buffer[start + 1] = unchecked((byte)(cb >> 8)); + buffer[start + 2] = unchecked((byte)cb); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteArrayHeader(byte[] buffer, int cursor, int length) + { + if (length <= LIMIT_MAX_FIX_ARRAY_LENGTH) + { + buffer[cursor++] = unchecked((byte)(MIN_FIX_ARRAY | length)); + } + else if (length <= ushort.MaxValue) + { + buffer[cursor++] = ARRAY16; + cursor = WriteUInt16(buffer, cursor, unchecked((ushort)length)); + } + else + { + buffer[cursor++] = ARRAY32; + cursor = WriteUInt32(buffer, cursor, unchecked((uint)length)); + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeArray(byte[] buffer, int cursor, T[] array) + { + if (array == null) + { + return SerializeNull(buffer, cursor); + } + + cursor = WriteArrayHeader(buffer, cursor, array.Length); + for (int i = 0; i < array.Length; i++) + { + cursor = Serialize(buffer, cursor, array[i]); + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteMapHeader(byte[] buffer, int cursor, int count) + { + if (count <= LIMIT_MAX_FIX_MAP_COUNT) + { + buffer[cursor++] = unchecked((byte)(MIN_FIX_MAP | count)); + } + else if (count <= ushort.MaxValue) + { + buffer[cursor++] = MAP16; + cursor = WriteUInt16(buffer, cursor, unchecked((ushort)count)); + } + else + { + buffer[cursor++] = MAP32; + cursor = WriteUInt32(buffer, cursor, unchecked((uint)count)); + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeMap(byte[] buffer, int cursor, IDictionary map) + { + if (map == null) + { + return SerializeNull(buffer, cursor); + } + + cursor = WriteMapHeader(buffer, cursor, map.Count); + foreach (var entry in map) + { + cursor = SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = Serialize(buffer, cursor, entry.Value); + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteTimestamp96Header(byte[] buffer, int cursor) + { + buffer[cursor++] = TIMESTAMP96; + buffer[cursor++] = 12; + buffer[cursor++] = EXT_DATE_TIME; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteTimestamp96(byte[] buffer, int cursor, long ticks) + { + cursor = WriteUInt32(buffer, cursor, unchecked((uint)((ticks % TimeSpan.TicksPerSecond) * 100))); + cursor = WriteInt64(buffer, cursor, (ticks / TimeSpan.TicksPerSecond) - 62135596800L); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeTimestamp96(byte[] buffer, int cursor, long ticks) + { + cursor = WriteTimestamp96Header(buffer, cursor); + cursor = WriteTimestamp96(buffer, cursor, ticks); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUtcDateTime(byte[] buffer, int cursor, DateTime utc) + { + return SerializeTimestamp96(buffer, cursor, utc.Ticks); + } + + public static int Serialize(byte[] buffer, int cursor, object obj) + { + if (obj == null) + { + return SerializeNull(buffer, cursor); + } + + switch (obj) + { + case bool v: + return SerializeBool(buffer, cursor, v); + case byte v: + return SerializeUInt8(buffer, cursor, v); + case sbyte v: + return SerializeInt8(buffer, cursor, v); + case short v: + return SerializeInt16(buffer, cursor, v); + case ushort v: + return SerializeUInt16(buffer, cursor, v); + case int v: + return SerializeInt32(buffer, cursor, v); + case uint v: + return SerializeUInt32(buffer, cursor, v); + case long v: + return SerializeInt64(buffer, cursor, v); + case ulong v: + return SerializeUInt64(buffer, cursor, v); + case float v: + return SerializeFloat32(buffer, cursor, v); + case double v: + return SerializeFloat64(buffer, cursor, v); + case string v: + return SerializeUnicodeString(buffer, cursor, v); + case IDictionary v: + return SerializeMap(buffer, cursor, v); + case object[] v: + return SerializeArray(buffer, cursor, v); + case DateTime v: + return SerializeUtcDateTime(buffer, cursor, v.ToUniversalTime()); + default: + string repr = null; + + try + { + repr = Convert.ToString(obj, CultureInfo.InvariantCulture); + } + catch + { + repr = $"ERROR: type {obj.GetType().FullName} is not supported"; + } + + return SerializeUnicodeString(buffer, cursor, repr); + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs new file mode 100644 index 0000000000..2ba66e8e39 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Exporter.Geneva +{ + [EventSource(Name = "OpenTelemetryGenevaMetricExporter", Guid = "{edc24920-e004-40f6-a8e1-0e6e48f39d84}")] + internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport + { + private readonly int fixedPayloadEndIndex; + + public MetricEtwDataTransport() + { + unsafe + { + this.fixedPayloadEndIndex = sizeof(BinaryHeader); + } + } + + [NonEvent] + public unsafe void Send(MetricEventType eventType, byte[] data, int size) + { + var eventDataPtr = stackalloc EventData[1]; + fixed (byte* bufferPtr = data) + { + eventDataPtr[0].DataPointer = (IntPtr)bufferPtr + this.fixedPayloadEndIndex; + eventDataPtr[0].Size = size; + this.WriteEventCore((int)eventType, 1, eventDataPtr); + } + } + + [Event((int)MetricEventType.ULongMetric)] + private void ULongMetricEvent() + { + } + + [Event((int)MetricEventType.DoubleMetric)] + private void DoubleMetricEvent() + { + } + + [Event((int)MetricEventType.ExternallyAggregatedULongDistributionMetric)] + private void ExternallyAggregatedDoubleDistributionMetric() + { + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs new file mode 100644 index 0000000000..8beab0ea72 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs @@ -0,0 +1,312 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace OpenTelemetry.Exporter.Geneva +{ + internal static class MetricSerializer + { + /// + /// Writes the string to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeString(byte[] buffer, ref int bufferIndex, string value) + { + if (!string.IsNullOrEmpty(value)) + { + if (bufferIndex + value.Length + sizeof(short) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + +#if NETSTANDARD2_1 + Span bufferSpan = new Span(buffer); + bufferSpan = bufferSpan.Slice(bufferIndex); + Span stringSpan = bufferSpan.Slice(2); + var lengthWritten = (short)Encoding.UTF8.GetBytes(value, stringSpan); + MemoryMarshal.Write(bufferSpan, ref lengthWritten); + bufferIndex += sizeof(short) + lengthWritten; +#else + // Advanced the buffer to account for the length, we will write it back after encoding. + var currentIndex = bufferIndex; + bufferIndex += sizeof(short); + var lengthWritten = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, bufferIndex); + bufferIndex += lengthWritten; + + // Write the length now that it is known + SerializeInt16(buffer, ref currentIndex, (short)lengthWritten); +#endif + } + else + { + SerializeInt16(buffer, ref bufferIndex, 0); + } + } + + /// + /// Writes the encoded string to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The encoded value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeEncodedString(byte[] buffer, ref int bufferIndex, byte[] encodedValue) + { + if (bufferIndex + encodedValue.Length + sizeof(short) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + +#if NETSTANDARD2_1 + Span sourceSpan = new Span(encodedValue); + Span bufferSpan = new Span(buffer); + bufferSpan = bufferSpan.Slice(bufferIndex); + sourceSpan.CopyTo(bufferSpan.Slice(2)); + short encodedLength = (short)encodedValue.Length; + MemoryMarshal.Write(bufferSpan, ref encodedLength); + bufferIndex += sizeof(short) + encodedLength; +#else + SerializeInt16(buffer, ref bufferIndex, (short)encodedValue.Length); + Array.Copy(encodedValue, 0, buffer, bufferIndex, encodedValue.Length); + bufferIndex += encodedValue.Length; +#endif + } + + /// + /// Writes the byte to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeByte(byte[] buffer, ref int bufferIndex, byte value) + { + if (bufferIndex + sizeof(byte) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = value; + bufferIndex += sizeof(byte); + } + + /// + /// Writes the unsigned short to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt16(byte[] buffer, ref int bufferIndex, ushort value) + { + if (bufferIndex + sizeof(ushort) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + bufferIndex += sizeof(ushort); + } + + /// + /// Writes the short to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeInt16(byte[] buffer, ref int bufferIndex, short value) + { + if (bufferIndex + sizeof(short) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + bufferIndex += sizeof(short); + } + + /// + /// Writes the unsigned int to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt32(byte[] buffer, ref int bufferIndex, uint value) + { + if (bufferIndex + sizeof(uint) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + buffer[bufferIndex + 2] = (byte)(value >> 0x10); + buffer[bufferIndex + 3] = (byte)(value >> 0x18); + bufferIndex += sizeof(uint); + } + + /// + /// Writes the ulong to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt64(byte[] buffer, ref int bufferIndex, ulong value) + { + if (bufferIndex + sizeof(ulong) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + buffer[bufferIndex + 2] = (byte)(value >> 0x10); + buffer[bufferIndex + 3] = (byte)(value >> 0x18); + buffer[bufferIndex + 4] = (byte)(value >> 0x20); + buffer[bufferIndex + 5] = (byte)(value >> 0x28); + buffer[bufferIndex + 6] = (byte)(value >> 0x30); + buffer[bufferIndex + 7] = (byte)(value >> 0x38); + bufferIndex += sizeof(ulong); + } + } + + internal enum MetricEventType + { + ULongMetric = 50, + DoubleMetric = 55, + ExternallyAggregatedULongDistributionMetric = 56, + } + + /// + /// Represents the binary header for non-ETW transmitted metrics. + /// + [StructLayout(LayoutKind.Explicit)] + internal struct BinaryHeader + { + /// + /// The event ID that represents how it will be processed. + /// + [FieldOffset(0)] + public ushort EventId; + + /// + /// The length of the body following the header. + /// + [FieldOffset(2)] + public ushort BodyLength; + } + + /// + /// Represents the fixed payload of a standard metric. + /// + [StructLayout(LayoutKind.Explicit)] + internal struct MetricPayload + { + /// + /// The dimension count. + /// + [FieldOffset(0)] + public ushort CountDimension; + + /// + /// Reserved for alignment. + /// + [FieldOffset(2)] + public ushort ReservedWord; // for 8-byte aligned + + /// + /// Reserved for alignment. + /// + [FieldOffset(4)] + public uint ReservedDword; + + /// + /// The UTC timestamp of the metric. + /// + [FieldOffset(8)] + public ulong TimestampUtc; + + /// + /// The value of the metric. + /// + [FieldOffset(16)] + public MetricData Data; + } + + /// + /// Represents the fixed payload of an externally aggregated metric. + /// + [StructLayout(LayoutKind.Explicit)] + internal struct ExternalPayload + { + /// + /// The dimension count. + /// + [FieldOffset(0)] + public ushort CountDimension; + + /// + /// Reserved for alignment. + /// + [FieldOffset(2)] + public ushort ReservedWord; // for alignment + + /// + /// The number of samples produced in the period. + /// + [FieldOffset(4)] + public uint Count; + + /// + /// The UTC timestamp of the metric. + /// + [FieldOffset(8)] + public ulong TimestampUtc; + + /// + /// The sum of the samples produced in the period. + /// + [FieldOffset(16)] + public MetricData Sum; + + /// + /// The minimum value of the samples produced in the period. + /// + [FieldOffset(24)] + public MetricData Min; + + /// + /// The maximum value of the samples produced in the period. + /// + [FieldOffset(32)] + public MetricData Max; + } + + /// + /// Represents the value of a metric. + /// + [StructLayout(LayoutKind.Explicit)] + internal struct MetricData + { + /// + /// The value represented as an integer. + /// + [FieldOffset(0)] + public ulong UInt64Value; + + /// + /// The value represented as a double. + /// + [FieldOffset(0)] + public double DoubleValue; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs new file mode 100644 index 0000000000..b4fc3b8ca1 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs @@ -0,0 +1,37 @@ +namespace OpenTelemetry.Exporter.Geneva +{ + internal sealed class MetricUnixDataTransport : IMetricDataTransport + { + private readonly int fixedPayloadLength; + private readonly UnixDomainSocketDataTransport udsDataTransport; + private bool isDisposed; + + public MetricUnixDataTransport( + string unixDomainSocketPath, + int timeoutMilliseconds = UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds) + { + unsafe + { + this.fixedPayloadLength = sizeof(BinaryHeader); + } + + this.udsDataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath, timeoutMilliseconds); + } + + public void Send(MetricEventType eventType, byte[] body, int size) + { + this.udsDataTransport.Send(body, size + this.fixedPayloadLength); + } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + this.udsDataTransport?.Dispose(); + this.isDisposed = true; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj new file mode 100644 index 0000000000..4843382572 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -0,0 +1,22 @@ + + + + true + An OpenTelemetry .NET exporter that exports to local ETW or UDS + OpenTelemetry Authors + $(NoWarn),NU5104,CS1591,SA1123,SA1633,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 + netstandard2.0 + $(TargetFrameworks);net461 + + + + + + + + true + latest + AllEnabledByDefault + + + diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md new file mode 100644 index 0000000000..eb7729a83c --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -0,0 +1,3 @@ +# Geneva Exporters for OpenTelemetry .NET + +TBD diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs new file mode 100644 index 0000000000..d95406a1df --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs @@ -0,0 +1,36 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace OpenTelemetry.Exporter.Geneva +{ + // This export processor exports without synchronization. + // Once OpenTelemetry .NET officially support this, + // we can get rid of this class. + // This is currently only used in ETW export, where we know + // that the underlying system is safe under concurrent calls. + internal class ReentrantExportProcessor : BaseExportProcessor + where T : class + { + static ReentrantExportProcessor() + { + var flags = BindingFlags.Instance | BindingFlags.NonPublic; + var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); + var value = Expression.Parameter(typeof(T), null); + var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); + CreateBatch = lambda.Compile(); + } + + public ReentrantExportProcessor(BaseExporter exporter) + : base(exporter) + { + } + + protected override void OnExport(T data) + { + this.exporter.Export(CreateBatch(data)); + } + + private static readonly Func> CreateBatch; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Schema.cs new file mode 100644 index 0000000000..c641b8c32d --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Schema.cs @@ -0,0 +1,87 @@ +namespace OpenTelemetry.Exporter.Geneva +{ + internal static class Schema + { + internal static class V21 + { + internal static class PartA + { + internal const string IKey = ".iKey"; + internal const string Name = ".name"; + internal const string Ver = ".ver"; + internal const string Time = ".time"; + internal const string Cv = ".cv"; + internal const string Epoch = ".epoch"; + internal const string Flags = ".flags"; + internal const string PopSample = ".popSample"; + internal const string SeqNum = ".seqNum"; + + internal static class Extensions + { + internal static class App + { + internal const string Id = "app.id"; + internal const string Ver = "app.ver"; + } + + internal static class Cloud + { + internal const string Environment = "cloud.environment"; + internal const string Location = "cloud.location"; + internal const string Name = "cloud.name"; + internal const string DeploymentUnit = "cloud.deploymentUnit"; + internal const string Role = "cloud.role"; + internal const string RoleInstance = "cloud.roleInstance"; + internal const string RoleVer = "cloud.roleVer"; + internal const string Ver = "cloud.ver"; + } + + internal static class Os + { + internal const string Name = "os.name"; + internal const string Ver = "os.ver"; + } + } + } + } + + internal static class V40 + { + internal static class PartA + { + internal const string IKey = ".iKey"; + internal const string Name = ".name"; + internal const string Ver = ".ver"; + internal const string Time = ".time"; + + internal static class Extensions + { + internal static class App + { + internal const string Id = "app.id"; + internal const string Ver = "app.ver"; + } + + internal static class Cloud + { + internal const string Role = "cloud.role"; + internal const string RoleInstance = "cloud.roleInstance"; + internal const string RoleVer = "cloud.roleVer"; + } + + internal static class Os + { + internal const string Name = "os.name"; + internal const string Ver = "os.ver"; + } + + internal static class Dt + { + internal const string TraceId = "dt.traceId"; + internal const string SpanId = "dt.spanId"; + } + } + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs new file mode 100644 index 0000000000..47a2573c59 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs @@ -0,0 +1,31 @@ +#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER +using Microsoft.Extensions.Options; +#endif + +namespace System +{ + /// + /// Extension methods for OpenTelemetry dependency injection support. + /// + internal static class ServiceProviderExtensions + { + /// + /// Get options from the supplied . + /// + /// Options type. + /// . + /// Options instance. + public static T GetOptions(this IServiceProvider serviceProvider) + where T : class, new() + { +#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER + IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); + + // Note: options could be null if user never invoked services.AddOptions(). + return options?.Value ?? new T(); +#else + return new T(); +#endif + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs new file mode 100644 index 0000000000..280cd4e3bc --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs @@ -0,0 +1,93 @@ +using System; +using System.Net; +using System.Net.Sockets; + +namespace OpenTelemetry.Exporter.Geneva +{ + internal class UnixDomainSocketDataTransport : IDataTransport, IDisposable + { + public const int DefaultTimeoutMilliseconds = 15000; + private readonly EndPoint unixEndpoint; + private Socket socket; + private int timeoutMilliseconds; + + /// + /// Initializes a new instance of the class. + /// The class for transporting data over Unix domain socket. + /// + /// The path to connect a unix domain socket over. + /// + /// The time-out value, in milliseconds. + /// If you set the property with a value between 1 and 499, the value will be changed to 500. + /// The default value is 15,000 milliseconds. + /// + public UnixDomainSocketDataTransport( + string unixDomainSocketPath, + int timeoutMilliseconds = DefaultTimeoutMilliseconds) + { + this.unixEndpoint = new UnixDomainSocketEndPoint(unixDomainSocketPath); + this.timeoutMilliseconds = timeoutMilliseconds; + this.Connect(); + } + + public bool IsEnabled() + { + return true; + } + + public void Send(byte[] data, int size) + { + try + { + if (!this.socket.Connected) + { + // Socket connection is off! Server might have stopped. Trying to reconnect. + this.Reconnect(); + } + + this.socket.Send(data, size, SocketFlags.None); + } + catch (SocketException ex) + { + // SocketException from Socket.Send + ExporterEventSource.Log.ExporterException(ex); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); + } + } + + public void Dispose() + { + this.socket.Dispose(); + } + + private void Connect() + { + try + { + this.socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) + { + SendTimeout = this.timeoutMilliseconds, + }; + this.socket.Connect(this.unixEndpoint); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); + + // Re-throw the exception to + // 1. fail fast in Geneva exporter contructor, or + // 2. fail in the Reconnect attempt. + throw; + } + } + + private void Reconnect() + { + this.socket.Close(); + this.Connect(); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs new file mode 100644 index 0000000000..7b317b7206 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs @@ -0,0 +1,79 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; + +namespace OpenTelemetry.Exporter.Geneva +{ + internal class UnixDomainSocketEndPoint : EndPoint + { + // sockaddr_un.sun_path at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html, -1 for terminator + private const int MaximumNativePathLength = 92 - 1; + + // The first 2 bytes of the underlying buffer are reserved for the AddressFamily enumerated value. + // https://docs.microsoft.com/dotnet/api/system.net.socketaddress + private const int NativePathOffset = 2; + private readonly string path; + private readonly byte[] nativePath; + + public UnixDomainSocketEndPoint(string path) + { + this.path = path ?? throw new ArgumentNullException(nameof(path), "Path cannot be null."); + this.nativePath = Encoding.UTF8.GetBytes(path); + if (this.nativePath.Length == 0 || this.nativePath.Length > MaximumNativePathLength) + { + throw new ArgumentOutOfRangeException(nameof(this.nativePath), "Path is of an invalid length for use with domain sockets."); + } + } + + public override AddressFamily AddressFamily => AddressFamily.Unix; + + public override EndPoint Create(SocketAddress socketAddress) => new UnixDomainSocketEndPoint(socketAddress); + + private UnixDomainSocketEndPoint(SocketAddress socketAddress) + { + if (socketAddress == null) + { + throw new ArgumentNullException(nameof(socketAddress), "SocketAddress cannot be null."); + } + + if (socketAddress.Family != this.AddressFamily || + socketAddress.Size > NativePathOffset + MaximumNativePathLength) + { + throw new ArgumentOutOfRangeException( + nameof(socketAddress), + "The path of SocketAddress is of an invalid length for use with domain sockets."); + } + + if (socketAddress.Size > NativePathOffset) + { + this.nativePath = new byte[socketAddress.Size - NativePathOffset]; + for (int i = 0; i < this.nativePath.Length; ++i) + { + this.nativePath[i] = socketAddress[NativePathOffset + i]; + } + + this.path = Encoding.UTF8.GetString(this.nativePath); + } + else + { + this.path = string.Empty; + this.nativePath = Array.Empty(); + } + } + + public override SocketAddress Serialize() + { + var socketAddress = new SocketAddress(AddressFamily.Unix, NativePathOffset + this.nativePath.Length + 1); + for (int i = 0; i < this.nativePath.Length; ++i) + { + socketAddress[NativePathOffset + i] = this.nativePath[i]; + } + + socketAddress[NativePathOffset + this.nativePath.Length] = 0; // SocketAddress should be NULL terminated + return socketAddress; + } + + public override string ToString() => this.path; + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs new file mode 100644 index 0000000000..c1548a6db0 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; + +/* +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1415 (21H2) +AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores +.NET SDK=6.0.101 + [Host] : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT + DefaultJob : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT + + +``` +| Method | Mean | Error | StdDev | Gen 0 | Allocated | +|------------------------- |------------:|---------:|---------:|-------:|----------:| +| NoListener | 58.41 ns | 0.360 ns | 0.337 ns | 0.0076 | 64 B | +| OneProcessor | 189.79 ns | 0.391 ns | 0.347 ns | 0.0277 | 232 B | +| TwoProcessors | 195.50 ns | 0.438 ns | 0.388 ns | 0.0277 | 232 B | +| ThreeProcessors | 198.98 ns | 0.500 ns | 0.468 ns | 0.0277 | 232 B | +| LoggerWithGenevaExporter | 1,101.36 ns | 4.134 ns | 3.452 ns | 0.0305 | 256 B | +| SerializeLogRecord | 743.53 ns | 2.233 ns | 2.088 ns | 0.0029 | 24 B | +*/ + +namespace OpenTelemetry.Exporter.Geneva.Benchmark +{ + [MemoryDiagnoser] + public class LogExporterBenchmarks + { + private readonly LogRecord logRecord; + private readonly GenevaLogExporter exporter; + private readonly ILogger loggerWithNoListener; + private readonly ILogger loggerWithGenevaExporter; + private readonly ILogger loggerWithOneProcessor; + private readonly ILogger loggerWithTwoProcessors; + private readonly ILogger loggerWithThreeProcessors; + + public LogExporterBenchmarks() + { + this.logRecord = this.GenerateTestLogRecord(); + + this.exporter = new GenevaLogExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + this.loggerWithNoListener = this.CreateLogger(); + + this.loggerWithOneProcessor = this.CreateLogger(options => options + .AddProcessor(new DummyLogProcessor())); + + this.loggerWithTwoProcessors = this.CreateLogger(options => options + .AddProcessor(new DummyLogProcessor()) + .AddProcessor(new DummyLogProcessor())); + + this.loggerWithThreeProcessors = this.CreateLogger(options => options + .AddProcessor(new DummyLogProcessor()) + .AddProcessor(new DummyLogProcessor()) + .AddProcessor(new DummyLogProcessor())); + + this.loggerWithGenevaExporter = this.CreateLogger(options => + { + options.AddGenevaLogExporter(genevaOptions => + { + genevaOptions.ConnectionString = "EtwSession=OpenTelemetry"; + genevaOptions.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + }); + } + + [Benchmark] + public void NoListener() + { + this.loggerWithNoListener.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Benchmark] + public void OneProcessor() + { + this.loggerWithOneProcessor.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Benchmark] + public void TwoProcessors() + { + this.loggerWithTwoProcessors.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Benchmark] + public void ThreeProcessors() + { + this.loggerWithThreeProcessors.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Benchmark] + public void LoggerWithGenevaExporter() + { + this.loggerWithGenevaExporter.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Benchmark] + public void SerializeLogRecord() + { + this.exporter.SerializeLogRecord(this.logRecord); + } + + internal class DummyLogProcessor : BaseProcessor + { + } + + internal class DummyLogExporter : BaseExporter + { + public LogRecord LastRecord { get; set; } + + public override ExportResult Export(in Batch batch) + { + foreach (var record in batch) + { + this.LastRecord = record; + } + + return ExportResult.Success; + } + } + + internal ILogger CreateLogger(Action configure = null) + { + var loggerFactory = LoggerFactory.Create(builder => + { + if (configure != null) + { + builder.AddOpenTelemetry(configure); + } + }); + + return loggerFactory.CreateLogger(); + } + + internal LogRecord GenerateTestLogRecord() + { + var dummyLogExporter = new DummyLogExporter(); + var dummyLogger = this.CreateLogger(options => options + .AddProcessor(new SimpleLogRecordExportProcessor(dummyLogExporter))); + dummyLogger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return dummyLogExporter.LastRecord; + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs new file mode 100644 index 0000000000..ee5395a1a6 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -0,0 +1,624 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using System.Threading; +using BenchmarkDotNet.Attributes; +using OpenTelemetry.Metrics; + +/* +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK=6.0.102 + [Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT + DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT + +| Method | Mean | Error | StdDev | Allocated | +|--------------------------------------------------------- |----------:|---------:|---------:|----------:| +| InstrumentWithNoListener3Dimensions | 66.07 ns | 0.213 ns | 0.199 ns | - | +| InstrumentWithNoListener4Dimensions | 109.53 ns | 0.267 ns | 0.236 ns | - | +| InstrumentWithWithListener3Dimensions | 65.59 ns | 0.322 ns | 0.285 ns | - | +| InstrumentWithWithListener4Dimensions | 117.56 ns | 0.655 ns | 0.613 ns | - | +| InstrumentWithWithDummyReader3Dimensions | 182.75 ns | 0.787 ns | 0.698 ns | - | +| InstrumentWithWithDummyReader4Dimensions | 244.04 ns | 1.268 ns | 1.186 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 181.74 ns | 0.595 ns | 0.527 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 265.85 ns | 3.214 ns | 3.006 ns | - | +| SerializeCounterMetricItemWith3Dimensions | 166.33 ns | 0.470 ns | 0.439 ns | - | +| SerializeCounterMetricItemWith4Dimensions | 200.02 ns | 0.546 ns | 0.510 ns | - | +| ExportCounterMetricItemWith3Dimensions | 464.79 ns | 3.996 ns | 3.738 ns | - | +| ExportCounterMetricItemWith4Dimensions | 504.02 ns | 6.362 ns | 5.951 ns | - | +| SerializeHistogramMetricItemWith3Dimensions | 260.47 ns | 1.364 ns | 1.276 ns | - | +| SerializeHistogramMetricItemWith4Dimensions | 293.25 ns | 0.674 ns | 0.631 ns | - | +| ExportHistogramMetricItemWith3Dimensions | 585.69 ns | 5.137 ns | 4.805 ns | - | +| ExportHistogramMetricItemWith4Dimensions | 618.47 ns | 4.946 ns | 4.384 ns | - | +*/ + +namespace OpenTelemetry.Exporter.Geneva.Benchmark +{ + [MemoryDiagnoser] + public class MetricExporterBenchmarks + { + private Metric counterMetricWith3Dimensions; + private Metric counterMetricWith4Dimensions; + private MetricPoint counterMetricPointWith3Dimensions; + private MetricPoint counterMetricPointWith4Dimensions; + private MetricData counterMetricDataWith3Dimensions; + private MetricData counterMetricDataWith4Dimensions; + private Batch counterMetricBatchWith3Dimensions; + private Batch counterMetricBatchWith4Dimensions; + private Metric histogramMetricWith3Dimensions; + private Metric histogramMetricWith4Dimensions; + private MetricPoint histogramMetricPointWith3Dimensions; + private MetricPoint histogramMetricPointWith4Dimensions; + private MetricData histogramSumWith3Dimensions; + private MetricData histogramSumWith4Dimensions; + private uint histogramCountWith3Dimensions; + private uint histogramCountWith4Dimensions; + private Batch histogramMetricBatchWith3Dimensions; + private Batch histogramMetricBatchWith4Dimensions; + private Meter meterWithNoListener = new Meter("MeterWithNoListener", "0.0.1"); + private Meter meterWithListener = new Meter("MeterWithListener", "0.0.1"); + private Meter meterWithDummyReader = new Meter("MeterWithDummyReader", "0.0.1"); + private Meter meterWithGenevaMetricExporter = new Meter("MeterWithGenevaMetricExporter", "0.0.1"); + private Counter counterWithNoListener; + private Counter counterWithListener; + private Counter counterWithDummyReader; + private Counter counterWithGenevaMetricExporter; + private MeterListener listener; + private MeterProvider meterProviderWithDummyReader; + private MeterProvider meterProviderWithGenevaMetricExporter; + private MeterProvider meterProviderForCounterBatchWith3Dimensions; + private MeterProvider meterProviderForCounterBatchWith4Dimensions; + private MeterProvider meterProviderForHistogramBatchWith3Dimensions; + private MeterProvider meterProviderForHistogramBatchWith4Dimensions; + private GenevaMetricExporter exporter; + private ThreadLocal random = new ThreadLocal(() => new Random()); + + private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported + private static readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; + + [GlobalSetup] + public void Setup() + { + this.counterWithNoListener = this.meterWithNoListener.CreateCounter("counter"); + this.counterWithListener = this.meterWithListener.CreateCounter("counter"); + this.counterWithDummyReader = this.meterWithDummyReader.CreateCounter("counter"); + this.counterWithGenevaMetricExporter = this.meterWithGenevaMetricExporter.CreateCounter("counter"); + + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; + this.exporter = new GenevaMetricExporter(exporterOptions); + + this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); + this.counterMetricPointWith4Dimensions = this.GenerateCounterMetricItemWith4Dimensions(out this.counterMetricDataWith4Dimensions); + + this.counterMetricBatchWith3Dimensions = this.GenerateCounterBatchWith3Dimensions(); + this.counterMetricBatchWith4Dimensions = this.GenerateCounterBatchWith4Dimensions(); + + using var enumeratorForCounterBatchWith3Dimensions = this.counterMetricBatchWith3Dimensions.GetEnumerator(); + enumeratorForCounterBatchWith3Dimensions.MoveNext(); + this.counterMetricWith3Dimensions = enumeratorForCounterBatchWith3Dimensions.Current; + + using var enumeratorForCounterBatchWith4Dimensions = this.counterMetricBatchWith4Dimensions.GetEnumerator(); + enumeratorForCounterBatchWith4Dimensions.MoveNext(); + this.counterMetricWith4Dimensions = enumeratorForCounterBatchWith4Dimensions.Current; + + this.histogramMetricPointWith3Dimensions = this.GenerateHistogramMetricItemWith3Dimensions(out this.histogramSumWith3Dimensions, out this.histogramCountWith3Dimensions); + this.histogramMetricPointWith4Dimensions = this.GenerateHistogramMetricItemWith4Dimensions(out this.histogramSumWith4Dimensions, out this.histogramCountWith4Dimensions); + + this.histogramMetricBatchWith3Dimensions = this.GenerateHistogramBatchWith3Dimensions(); + this.histogramMetricBatchWith4Dimensions = this.GenerateHistogramBatchWith4Dimensions(); + + using var enumeratorForHistogramBatchWith3Dimensions = this.histogramMetricBatchWith3Dimensions.GetEnumerator(); + enumeratorForHistogramBatchWith3Dimensions.MoveNext(); + this.histogramMetricWith3Dimensions = enumeratorForHistogramBatchWith3Dimensions.Current; + + using var enumeratorForHistogramBatchWith4Dimensions = this.histogramMetricBatchWith4Dimensions.GetEnumerator(); + enumeratorForHistogramBatchWith4Dimensions.MoveNext(); + this.histogramMetricWith4Dimensions = enumeratorForHistogramBatchWith4Dimensions.Current; + + #region Setup MeterListener + this.listener = new MeterListener(); + this.listener.InstrumentPublished = (instrument, listener) => + { + if (instrument.Meter.Name == this.meterWithListener.Name) + { + listener.EnableMeasurementEvents(instrument); + } + }; + + this.listener.Start(); + #endregion + + this.meterProviderWithDummyReader = Sdk.CreateMeterProviderBuilder() + .AddMeter(this.meterWithDummyReader.Name) + .AddReader(new DummyReader(new DummyMetricExporter())) + .Build(); + + this.meterProviderWithGenevaMetricExporter = Sdk.CreateMeterProviderBuilder() + .AddMeter(this.meterWithGenevaMetricExporter.Name) + .AddGenevaMetricExporter(options => + { + options.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + }) + .Build(); + } + + private MetricPoint GenerateCounterMetricItemWith3Dimensions(out MetricData metricData) + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterMetricItemWith3Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWithThreeDimensions"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterMetricItemWith3Dimensions") + .AddReader(inMemoryReader) + .Build(); + + counter.Add( + 100, + new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); + + inMemoryReader.Collect(); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + metricData = new MetricData { UInt64Value = metricDataValue }; + + return metricPoint; + } + + private MetricPoint GenerateCounterMetricItemWith4Dimensions(out MetricData metricData) + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterMetricItemWith4Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWith4Dimensions"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterMetricItemWith4Dimensions") + .AddReader(inMemoryReader) + .Build(); + + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + counter.Add(100, tags); + + inMemoryReader.Collect(); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + metricData = new MetricData { UInt64Value = metricDataValue }; + + return metricPoint; + } + + private Batch GenerateCounterBatchWith3Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterBatchWith3Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWithThreeDimensions"); + + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) + { + Temporality = AggregationTemporality.Delta, + }; + + this.meterProviderForCounterBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterBatchWith3Dimensions") + .AddReader(batchGeneratorReader) + .Build(); + + counter.Add( + 100, + new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); + + this.meterProviderForCounterBatchWith3Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } + + private Batch GenerateCounterBatchWith4Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterBatchWith4Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWith4Dimensions"); + + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) + { + Temporality = AggregationTemporality.Delta, + }; + + this.meterProviderForCounterBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterBatchWith4Dimensions") + .AddReader(batchGeneratorReader) + .Build(); + + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + counter.Add(100, tags); + + this.meterProviderForCounterBatchWith4Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } + + private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData sum, out uint count) + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith3Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramMetricItemWith3Dimensions") + .AddReader(inMemoryReader) + .Build(); + + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); + } + + inMemoryReader.Collect(); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + + return metricPoint; + } + + private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData sum, out uint count) + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith4Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramMetricItemWith4Dimensions") + .AddReader(inMemoryReader) + .Build(); + + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tags); + } + + inMemoryReader.Collect(); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + + return metricPoint; + } + + private Batch GenerateHistogramBatchWith3Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramBatchWith3Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); + + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) + { + Temporality = AggregationTemporality.Delta, + }; + + this.meterProviderForHistogramBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramBatchWith3Dimensions") + .AddReader(batchGeneratorReader) + .Build(); + + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); + } + + this.meterProviderForHistogramBatchWith3Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } + + private Batch GenerateHistogramBatchWith4Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramBatchWith4Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); + + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) + { + Temporality = AggregationTemporality.Delta, + }; + + this.meterProviderForHistogramBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramBatchWith4Dimensions") + .AddReader(batchGeneratorReader) + .Build(); + + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tags); + } + + this.meterProviderForHistogramBatchWith4Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } + + [GlobalCleanup] + public void Cleanup() + { + this.meterWithNoListener?.Dispose(); + this.meterWithListener?.Dispose(); + this.meterWithDummyReader?.Dispose(); + this.meterWithGenevaMetricExporter?.Dispose(); + this.listener?.Dispose(); + this.meterProviderWithDummyReader?.Dispose(); + this.meterProviderWithGenevaMetricExporter?.Dispose(); + this.meterProviderForCounterBatchWith3Dimensions?.Dispose(); + this.meterProviderForCounterBatchWith4Dimensions?.Dispose(); + this.meterProviderForHistogramBatchWith3Dimensions?.Dispose(); + this.meterProviderForHistogramBatchWith4Dimensions?.Dispose(); + this.exporter?.Dispose(); + } + + [Benchmark] + public void InstrumentWithNoListener3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithNoListener?.Add(100, tag1, tag2, tag3); + } + + [Benchmark] + public void InstrumentWithNoListener4Dimensions() + { + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithNoListener?.Add(100, tags); + } + + [Benchmark] + public void InstrumentWithWithListener3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithListener?.Add(100, tag1, tag2, tag3); + } + + [Benchmark] + public void InstrumentWithWithListener4Dimensions() + { + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithListener?.Add(100, tags); + } + + [Benchmark] + public void InstrumentWithWithDummyReader3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithDummyReader?.Add(100, tag1, tag2, tag3); + } + + [Benchmark] + public void InstrumentWithWithDummyReader4Dimensions() + { + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithDummyReader?.Add(100, tags); + } + + [Benchmark] + public void InstrumentWithWithGenevaCounterMetricExporter3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithGenevaMetricExporter?.Add(100, tag1, tag2, tag3); + } + + [Benchmark] + public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() + { + var tags = new TagList + { + { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, + { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, + { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, + }; + + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithGenevaMetricExporter?.Add(100, tags); + } + + [Benchmark] + public void SerializeCounterMetricItemWith3Dimensions() + { + this.exporter.SerializeMetric( + MetricEventType.ULongMetric, + this.counterMetricWith3Dimensions.Name, + this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), + this.counterMetricPointWith3Dimensions.Tags, + this.counterMetricDataWith3Dimensions); + } + + [Benchmark] + public void SerializeCounterMetricItemWith4Dimensions() + { + this.exporter.SerializeMetric( + MetricEventType.ULongMetric, + this.counterMetricWith4Dimensions.Name, + this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), + this.counterMetricPointWith4Dimensions.Tags, + this.counterMetricDataWith4Dimensions); + } + + [Benchmark] + public void ExportCounterMetricItemWith3Dimensions() + { + this.exporter.Export(this.counterMetricBatchWith3Dimensions); + } + + [Benchmark] + public void ExportCounterMetricItemWith4Dimensions() + { + this.exporter.Export(this.counterMetricBatchWith4Dimensions); + } + + [Benchmark] + public void SerializeHistogramMetricItemWith3Dimensions() + { + this.exporter.SerializeHistogramMetric( + this.histogramMetricWith3Dimensions.Name, + this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), + this.histogramMetricPointWith3Dimensions.Tags, + this.histogramMetricPointWith3Dimensions.GetHistogramBuckets(), + this.histogramSumWith3Dimensions, + this.histogramCountWith3Dimensions); + } + + [Benchmark] + public void SerializeHistogramMetricItemWith4Dimensions() + { + this.exporter.SerializeHistogramMetric( + this.histogramMetricWith4Dimensions.Name, + this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), + this.histogramMetricPointWith4Dimensions.Tags, + this.histogramMetricPointWith4Dimensions.GetHistogramBuckets(), + this.histogramSumWith4Dimensions, + this.histogramCountWith4Dimensions); + } + + [Benchmark] + public void ExportHistogramMetricItemWith3Dimensions() + { + this.exporter.Export(this.histogramMetricBatchWith3Dimensions); + } + + [Benchmark] + public void ExportHistogramMetricItemWith4Dimensions() + { + this.exporter.Export(this.histogramMetricBatchWith4Dimensions); + } + + private class DummyReader : BaseExportingMetricReader + { + public DummyReader(BaseExporter exporter) + : base(exporter) + { + } + } + + private class DummyMetricExporter : BaseExporter + { + public override ExportResult Export(in Batch batch) + { + return ExportResult.Success; + } + } + + private class BatchGenerator : BaseExporter + { + public Batch Batch { get; set; } + + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; + } + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs new file mode 100644 index 0000000000..3c702182f5 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using BenchmarkDotNet.Attributes; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +/* +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1415 (21H2) +AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores +.NET SDK=6.0.101 + [Host] : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT + DefaultJob : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT + +| Method | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------- |----------:|---------:|---------:|-------:|----------:| +| CreateBoringActivity | 16.05 ns | 0.053 ns | 0.049 ns | - | - | +| CreateTediousActivity | 509.26 ns | 2.105 ns | 1.969 ns | 0.0486 | 408 B | +| CreateInterestingActivity | 959.87 ns | 6.014 ns | 5.625 ns | 0.0477 | 408 B | +| SerializeActivity | 506.55 ns | 3.862 ns | 3.612 ns | 0.0095 | 80 B | +*/ + +namespace OpenTelemetry.Exporter.Geneva.Benchmark +{ + [MemoryDiagnoser] + public class TraceExporterBenchmarks + { + private readonly Random r = new Random(); + private readonly Activity activity; + private readonly GenevaTraceExporter exporter; + private readonly ActivitySource sourceBoring = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.Boring"); + private readonly ActivitySource sourceTedious = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.Tedious"); + private readonly ActivitySource sourceInteresting = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.Interesting"); + + public TraceExporterBenchmarks() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + + ActivitySource.AddActivityListener(new ActivityListener + { + ActivityStarted = null, + ActivityStopped = null, + ShouldListenTo = (activitySource) => activitySource.Name == this.sourceTedious.Name, + Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded, + }); + + using (var tedious = this.sourceTedious.StartActivity("Benchmark")) + { + this.activity = tedious; + this.activity?.SetTag("tagString", "value"); + this.activity?.SetTag("tagInt", 100); + this.activity?.SetStatus(Status.Error); + } + + this.exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + CustomFields = new List { "azureResourceProvider", "clientRequestId" }, + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(this.sourceInteresting.Name) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + } + + [Benchmark] + public void CreateBoringActivity() + { + // this activity won't be created as there is no listener + using var activity = this.sourceBoring.StartActivity("Benchmark"); + } + + [Benchmark] + public void CreateTediousActivity() + { + // this activity will be created and feed into an ActivityListener that simply drops everything on the floor + using var activity = this.sourceTedious.StartActivity("Benchmark"); + } + + [Benchmark] + public void CreateInterestingActivity() + { + // this activity will be created and feed into the actual Geneva exporter + using var activity = this.sourceInteresting.StartActivity("Benchmark"); + } + + [Benchmark] + public void SerializeActivity() + { + this.exporter.SerializeActivity(this.activity); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj new file mode 100644 index 0000000000..521c7b3e2f --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -0,0 +1,21 @@ + + + + Exe + netcoreapp3.1;net5.0;net6.0 + $(TargetFrameworks);net461;net462;net47;net471;net472;net48 + $(NoWarn),SA1633,SA1201,SA1202,SA1204,SA1311,SA1123 + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs new file mode 100644 index 0000000000..5ec54db965 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs @@ -0,0 +1,9 @@ +using BenchmarkDotNet.Running; + +namespace OpenTelemetry.Exporter.Geneva.Benchmark +{ + internal class Program + { + private static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs new file mode 100644 index 0000000000..4af08fa4be --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -0,0 +1,86 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Geneva.Stress +{ + internal class DummyServer + { + private EndPoint endpoint; + private Socket serverSocket; + + public DummyServer(string path) + { + Console.WriteLine($"Server socket listening at path: {path}"); + + // Unix sockets must be unlink()ed before being reused again. + // Or there will be System.Net.Sockets.SocketException (98): SocketError.AddressAlreadyInUse + // https://github.com/dotnet/runtime/issues/23803 + // C# doesn't have the unlink() function in C + // Shutdown() and setting SocketOptions like ReuseAddress and Linger doesn't solve the problem as they do for TCP + // https://stackoverflow.com/questions/2821520/how-can-i-unbind-a-socket-in-c + File.Delete(path); + this.endpoint = new UnixDomainSocketEndPoint(path); + this.serverSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + } + + public void Start() + { + try + { + this.serverSocket.Bind(this.endpoint); + this.serverSocket.Listen(20); + + Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs args) => + { + Console.WriteLine("Program is terminating."); + this.serverSocket.Close(); + }; + + while (true) + { + Socket acceptSocket = this.serverSocket.Accept(); + Task.Run(() => + { + int threadId = Thread.CurrentThread.ManagedThreadId; + Console.WriteLine($"ThreadID {threadId}: Start reading from socket."); + int totalBytes = 0; + try + { + while (acceptSocket.Connected) + { + var receivedData = new byte[1024]; + int receivedDataSize = acceptSocket.Receive(receivedData); + totalBytes += receivedDataSize; + } + + acceptSocket.Shutdown(SocketShutdown.Both); + } + catch (Exception e) + { + Console.WriteLine($"acceptSocket exception: {e}"); + } + finally + { + Console.WriteLine($"ThreadID {threadId}: Closing socket"); + acceptSocket.Close(); + } + + Console.WriteLine($"ThreadID {threadId}: Socket received {totalBytes} bytes in total."); + }); + } + } + catch (Exception e) + { + Console.WriteLine($"Server socket exception: {e}"); + } + finally + { + this.serverSocket.Close(); + } + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj new file mode 100644 index 0000000000..41d0d5fb88 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -0,0 +1,18 @@ + + + + Exe + netcoreapp3.1;net5.0;net6.0 + $(TargetFrameworks);net461;net462;net47;net471;net472;net48 + $(NoWarn),SA1633,SA1308,SA1201 + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs new file mode 100644 index 0000000000..ee3e337ed3 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using CommandLine; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Exporter.Geneva.Stress +{ + internal class Program + { + private static volatile bool s_bContinue = true; + private static long s_nEvents = 0; + + private static ActivitySource source = new ActivitySource("OpenTelemetry.Exporter.Geneva.Stress"); + + private static int Main(string[] args) + { + return Parser.Default.ParseArguments(args) + .MapResult( + (WindowsOptions options) => EntryPoint(InitTraces, RunTraces), + (LinuxOptions options) => RunLinux(options), + (ServerOptions options) => RunServer(options), + (ExporterCreationOptions options) => RunExporterCreation(), + errs => 1); + + // return EntryPoint(InitMetrics, RunMetrics); + } + + [Verb("Windows", HelpText = "Run stress test on Windows.")] + private class WindowsOptions + { + } + + [Verb("Linux", HelpText = "Run stress test on Linux.")] + private class LinuxOptions + { + [Option('p', "path", Default = "/var/run/default_fluent.socket", HelpText = "Specify a path for Unix domain socket.")] + public string Path { get; set; } + } + + [Verb("server", HelpText = "Start a dummy server on Linux.")] + private class ServerOptions + { + [Option('p', "path", HelpText = "Specify a path for Unix domain socket.", Required = true)] + public string Path { get; set; } + } + + [Verb("ExporterCreation", HelpText = "Validate exporter dispose behavior")] + private class ExporterCreationOptions + { + } + + private static int RunExporterCreation() + { + var options = new GenevaExporterOptions() + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["ver"] = "4.0", + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; + + for (var i = 0; i < 300000; ++i) + { + using var dataTransport = new EtwDataTransport("OpenTelemetry"); + } + + return 0; + } + + private static int RunLinux(LinuxOptions options) + { + return EntryPoint(() => InitTracesOnLinux(options.Path), RunTraces); + } + + private static int RunServer(ServerOptions options) + { + var server = new DummyServer(options.Path); + server.Start(); + return 0; + } + + private static int EntryPoint(Action init, Action run) + { + init(); + + var statistics = new long[Environment.ProcessorCount]; + Parallel.Invoke( + () => + { + Console.WriteLine("Running, press to stop..."); + var watch = new Stopwatch(); + while (true) + { + if (Console.KeyAvailable) + { + var key = Console.ReadKey(true).Key; + switch (key) + { + case ConsoleKey.Escape: + s_bContinue = false; + return; + } + + continue; + } + + s_nEvents = statistics.Sum(); + watch.Restart(); + Thread.Sleep(200); + watch.Stop(); + var nEvents = statistics.Sum(); + var nEventPerSecond = (int)((nEvents - s_nEvents) / (watch.ElapsedMilliseconds / 1000.0)); + Console.Title = string.Format("Loops: {0:n0}, Loops/Second: {1:n0}", nEvents, nEventPerSecond); + } + }, + () => + { + Parallel.For(0, statistics.Length, (i) => + { + statistics[i] = 0; + while (s_bContinue) + { + run(); + statistics[i]++; + } + }); + }); + return 0; + } + + private static void InitTraces() + { + Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource("OpenTelemetry.Exporter.Geneva.Stress") + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void RunTraces() + { + using (var activity = source.StartActivity("Stress")) + { + activity?.SetTag("http.method", "GET"); + activity?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + activity?.SetTag("http.status_code", 200); + } + } + + private static void InitTracesOnLinux(string path) + { + Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource("OpenTelemetry.Exporter.Geneva.Stress") + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs new file mode 100644 index 0000000000..6e9f374a8c --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs @@ -0,0 +1,228 @@ +using System; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class ConnectionStringBuilderTests + { + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_constructor_Invalid_Input() + { + // null connection string + Assert.Throws(() => _ = new ConnectionStringBuilder(null)); + + // empty connection string + Assert.Throws(() => _ = new ConnectionStringBuilder(string.Empty)); + Assert.Throws(() => _ = new ConnectionStringBuilder(" ")); + + // empty key + Assert.Throws(() => _ = new ConnectionStringBuilder("=value")); + Assert.Throws(() => _ = new ConnectionStringBuilder("=value1;key2=value2")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key1=value1;=value2")); + + // empty value + Assert.Throws(() => _ = new ConnectionStringBuilder("key=")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key1=;key2=value2")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key1=value1;key2=")); + + // invalid format + Assert.Throws(() => _ = new ConnectionStringBuilder("key;value")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key==value")); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_constructor_Duplicated_Keys() + { + var builder = new ConnectionStringBuilder("Account=value1;Account=VALUE2"); + Assert.Equal("VALUE2", builder.Account); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_Protocol_No_Default_Value() + { + var builder = new ConnectionStringBuilder("key1=value1"); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + + builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); + Assert.Equal(TransportProtocol.Etw, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11013"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:11013"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=foo://localhost:11013"); + Assert.Throws(() => _ = builder.Protocol); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_EtwSession() + { + var builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); + Assert.Equal(TransportProtocol.Etw, builder.Protocol); + Assert.Equal("OpenTelemetry", builder.EtwSession); + Assert.Throws(() => _ = builder.Host); + Assert.Throws(() => _ = builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11013"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + Assert.Throws(() => _ = builder.EtwSession); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_Endpoint_UnixDomainSocketPath() + { + var builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); + Assert.Equal("unix:/var/run/default_fluent.socket", builder.Endpoint); + Assert.Equal(TransportProtocol.Unix, builder.Protocol); + Assert.Equal("/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("Endpoint=unix:///var/run/default_fluent.socket"); + Assert.Equal("unix:///var/run/default_fluent.socket", builder.Endpoint); + Assert.Equal(TransportProtocol.Unix, builder.Protocol); + Assert.Equal("/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("Endpoint=unix://:11111"); + Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); + Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_TimeoutMilliseconds() + { + var builder = new ConnectionStringBuilder("TimeoutMilliseconds=10000"); + Assert.Equal(10000, builder.TimeoutMilliseconds); + + builder.TimeoutMilliseconds = 6000; + Assert.Equal(6000, builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); + Assert.Equal(UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds, builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=0"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=-1"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=-2"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=10.5"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=abc"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_Endpoint_Udp() + { + var builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11111"); + Assert.Equal("udp://localhost:11111", builder.Endpoint); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Equal(11111, builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=Udp://localhost:11111"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=UDP://localhost:11111"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=udp://localhost"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Throws(() => _ = builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=udp://:11111"); + Assert.Throws(() => _ = builder.Protocol); + Assert.Throws(() => _ = builder.Host); + Assert.Throws(() => _ = builder.Port); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_Endpoint_Tcp() + { + var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333"); + Assert.Equal("tcp://localhost:33333", builder.Endpoint); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Equal(33333, builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=Tcp://localhost:11111"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=TCP://localhost:11111"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=tcp://localhost"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Throws(() => _ = builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=tpc://:11111"); + Assert.Throws(() => _ = builder.Protocol); + Assert.Throws(() => _ = builder.Host); + Assert.Throws(() => _ = builder.Port); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_EtwSession_Endpoint_Both_Set() + { + var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333;EtwSession=OpenTelemetry"); + Assert.Equal(TransportProtocol.Etw, builder.Protocol); + + Assert.Equal("OpenTelemetry", builder.EtwSession); + + Assert.Equal("tcp://localhost:33333", builder.Endpoint); + Assert.Equal("localhost", builder.Host); + Assert.Equal(33333, builder.Port); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_MonitoringAccount_No_Default_Value() + { + var builder = new ConnectionStringBuilder("key1=value1"); + Assert.Throws(() => _ = builder.Account); + + builder.Account = "TestAccount"; + Assert.Equal("TestAccount", builder.Account); + + builder = new ConnectionStringBuilder("Account=TestAccount"); + Assert.Equal("TestAccount", builder.Account); + } + + [Fact] + [Trait("Platform", "Any")] + public void ConnectionStringBuilder_Keywords_Are_Case_Sensitive() + { + var builder = new ConnectionStringBuilder("etwSession=OpenTelemetry"); + Assert.Throws(() => builder.EtwSession); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + + builder = new ConnectionStringBuilder("endpoint=tcp://localhost:33333"); + Assert.Throws(() => builder.Endpoint); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + Assert.Throws(() => builder.Host); + Assert.Throws(() => builder.Port); + + builder = new ConnectionStringBuilder("monitoringAccount=TestAccount"); + Assert.Throws(() => builder.Account); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs new file mode 100644 index 0000000000..b6f59ca6fc --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs @@ -0,0 +1,768 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class GenevaLogExporterTests + { + [Fact] + [Trait("Platform", "Any")] + public void BadArgs() + { + GenevaExporterOptions exporterOptions = null; + Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + } + + [Fact] + [Trait("Platform", "Any")] + public void SpecialChractersInTableNameMappings() + { + Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(new GenevaExporterOptions + { + TableNameMappings = new Dictionary { ["TestCategory"] = "\u0418" }, + }); + }); + + Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(new GenevaExporterOptions + { + TableNameMappings = new Dictionary { ["*"] = "\u0418" }, + }); + }); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + [Trait("Platform", "Any")] + public void InvalidConnectionString(string connectionString) + { + var exporterOptions = new GenevaExporterOptions() { ConnectionString = connectionString }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal($"{nameof(exporterOptions.ConnectionString)} is invalid.", exception.Message); + } + + [Fact] + [Trait("Platform", "Windows")] + public void IncompatibleConnectionStringOnWindows() + { + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); + } + + [Fact] + [Trait("Platform", "Linux")] + public void IncompatibleConnectionStringOnLinux() + { + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); + } + + [Theory] + [InlineData("categoryA", "TableA")] + [InlineData("categoryB", "TableB")] + [InlineData("categoryA", "TableA", "categoryB", "TableB")] + [InlineData("categoryA", "TableA", "*", "CatchAll")] + [InlineData(null)] + [Trait("Platform", "Any")] + public void TableNameMappingTest(params string[] category) + { + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + Dictionary mappingsDict = null; + try + { + var exporterOptions = new GenevaExporterOptions(); + if (category?.Length > 0) + { + mappingsDict = new Dictionary(); + for (int i = 0; i < category.Length; i = i + 2) + { + mappingsDict.Add(category[i], category[i + 1]); + } + + exporterOptions.TableNameMappings = mappingsDict; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + ILogger logger; + ThreadLocal m_buffer; + object fluentdData; + string actualTableName; + string defaultLogTable = "Log"; + if (mappingsDict != null) + { + foreach (var mapping in mappingsDict) + { + if (!mapping.Key.Equals("*")) + { + logger = loggerFactory.CreateLogger(mapping.Key); + logger.LogError("this does not matter"); + + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + Assert.Equal(mapping.Value, actualTableName); + logRecordList.Clear(); + } + else + { + defaultLogTable = mapping.Value; + } + } + + // test default table + logger = loggerFactory.CreateLogger("random category"); + logger.LogError("this does not matter"); + + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + Assert.Equal(defaultLogTable, actualTableName); + logRecordList.Clear(); + } + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + [Trait("Platform", "Any")] + public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) + { + // Dedicated test for the raw ILogger.Log method + // https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger.log + + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + }); + options.AddInMemoryExporter(logRecordList); + options.IncludeFormattedMessage = includeFormattedMessage; + }) + .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); + + // ACT + // This is treated as structured logging as the state can be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + new List>() + { + new KeyValuePair("Key1", "Value1"), + new KeyValuePair("Key2", "Value2"), + }, + null, + (state, ex) => "Formatted Message"); + + // VALIDATE + Assert.Single(logRecordList); + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var body = GetField(fluentdData, "body"); + string expectedBody = includeFormattedMessage ? "Formatted Message" : null; + Assert.Equal(expectedBody, body); + Assert.Equal("Value1", GetField(fluentdData, "Key1")); + Assert.Equal("Value2", GetField(fluentdData, "Key2")); + + // ARRANGE + logRecordList.Clear(); + + // ACT + // This is treated as Un-structured logging as the state cannot be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + state: "somestringasdata", + exception: null, + formatter: (state, ex) => "Formatted Message"); + + // VALIDATE + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + body = GetField(fluentdData, "body"); + expectedBody = includeFormattedMessage ? "Formatted Message" : "somestringasdata"; + Assert.Equal(expectedBody, body); + + // ARRANGE + logRecordList.Clear(); + + // ACT + // This is treated as Un-structured logging as the state cannot be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + state: "somestringasdata", + exception: null, + formatter: null); + + // VALIDATE + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + body = GetField(fluentdData, "body"); + + // Formatter is null, hence body is always the ToString() of the data + expectedBody = "somestringasdata"; + Assert.Equal(expectedBody, body); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Theory] + [InlineData(false, false, false)] + [InlineData(false, true, false)] + [InlineData(true, false, false)] + [InlineData(true, true, false)] + [InlineData(false, false, true)] + [InlineData(false, true, true)] + [InlineData(true, false, true)] + [InlineData(true, true, true)] + [Trait("Platform", "Any")] + public void SuccessfulSerialization(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) + { + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions + { + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + if (hasTableNameMapping) + { + exporterOptions.TableNameMappings = new Dictionary + { + { typeof(GenevaLogExporterTests).FullName, "CustomLogRecord" }, + { "*", "DefaultLogRecord" }, + }; + } + + if (hasCustomFields) + { + // The field "customField" of LogRecord.State should be present in the mapping as a separate key. Other fields of LogRecord.State which are not present + // in CustomFields should be added in the mapping under "env_properties" + exporterOptions.CustomFields = new string[] { "customField" }; + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + options.PrepopulatedFields = exporterOptions.PrepopulatedFields; + }); + options.AddInMemoryExporter(logRecordList); + options.ParseStateValues = parseStateValues; + }) + .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); + + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + + using var listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; + listener.Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; + ActivitySource.AddActivityListener(listener); + + using var source = new ActivitySource(sourceName); + + using (var activity = source.StartActivity("Activity")) + { + // Log inside an activity to set LogRecord.TraceId and LogRecord.SpanId + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); // structured logging + } + + // When the exporter options are configured with TableMappings only "customField" will be logged as a separate key in the mapping + // "property" will be logged under "env_properties" in the mapping + logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", null); + logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", null, "PropertyValue"); + logger.Log(LogLevel.Debug, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Information, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Warning, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Error, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Critical, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.LogInformation("Hello World!"); // unstructured logging + + logger.Log(LogLevel.Information, default, "Hello World!", null, null); // unstructured logging using a non-extension method call + + // logging custom state + // This is treated as structured logging as the state can be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + new List>() + { + new KeyValuePair("Key1", "Value1"), + new KeyValuePair("Key2", "Value2"), + }, + null, + (state, ex) => "Formatted Exception!"); + + logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {food} {price}.", "artichoke", 3.99); + + var loggerWithDefaultCategory = loggerFactory.CreateLogger("DefaultCategory"); + loggerWithDefaultCategory.LogInformation("Basic test"); + + // logRecordList should have two logRecord entries after the logger.LogInformation calls + Assert.Equal(14, logRecordList.Count); + + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + + foreach (var logRecord in logRecordList) + { + _ = exporter.SerializeLogRecord(logRecord); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + this.AssertFluentdForwardModeForLogRecord(exporterOptions, fluentdData, logRecord); + } + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + [Trait("Platform", "Windows")] + public void SuccessfulExportOnWindows() + { + var exporterOptions = new GenevaExporterOptions() + { + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + })); + + var logger = loggerFactory.CreateLogger(); + + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Fact] + [Trait("Platform", "Linux")] + public void SuccessfulExportOnLinux() + { + string path = GenerateTempFilePath(); + var logRecordList = new List(); + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + options.AddInMemoryExporter(logRecordList); + })); + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; + + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + using var exporter = new GenevaLogExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); + + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); + + int messagePackDataSize; + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + + private static string GenerateTempFilePath() + { + while (true) + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) + { + return path; + } + } + } + + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } + + private static object GetField(object fluentdData, string key) + { + /* Fluentd Forward Mode: + [ + "Log", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + + if (mapping.ContainsKey(key)) + { + return mapping[key]; + } + else + { + return null; + } + } + + private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporterOptions, object fluentdData, LogRecord logRecord) + { + /* Fluentd Forward Mode: + [ + "Log", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var timeStamp = (DateTime)(TimeStampAndMappings as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var timeFormat = (fluentdData as object[])[2] as Dictionary; + + var partAName = "Log"; + if (exporterOptions.TableNameMappings != null) + { + if (exporterOptions.TableNameMappings.ContainsKey(logRecord.CategoryName)) + { + partAName = exporterOptions.TableNameMappings[logRecord.CategoryName]; + } + else if (exporterOptions.TableNameMappings.ContainsKey("*")) + { + partAName = exporterOptions.TableNameMappings["*"]; + } + } + + Assert.Equal(partAName, signal); + + // Timestamp check + Assert.Equal(logRecord.Timestamp.Ticks, timeStamp.Ticks); + + // Part A core envelope fields + + var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; + + // Check if the user has configured a custom table mapping + Assert.Equal(partAName, mapping[nameKey]); + + // TODO: Update this when we support multiple Schema formats + var partAVer = "4.0"; + var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; + Assert.Equal(partAVer, mapping[verKey]); + + foreach (var item in exporterOptions.PrepopulatedFields) + { + var partAValue = item.Value as string; + var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; + Assert.Equal(partAValue, mapping[partAKey]); + } + + var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; + Assert.Equal(logRecord.Timestamp.Ticks, ((DateTime)mapping[timeKey]).Ticks); + + // Part A dt extensions + + if (logRecord.TraceId != default) + { + Assert.Equal(logRecord.TraceId.ToHexString(), mapping["env_dt_traceId"]); + } + + if (logRecord.SpanId != default) + { + Assert.Equal(logRecord.SpanId.ToHexString(), mapping["env_dt_spanId"]); + } + + if (logRecord.Exception != null) + { + Assert.Equal(logRecord.Exception.GetType().FullName, mapping["env_ex_type"]); + Assert.Equal(logRecord.Exception.Message, mapping["env_ex_msg"]); + } + + // Part B fields + Assert.Equal(logRecord.LogLevel.ToString(), mapping["severityText"]); + Assert.Equal((byte)(((int)logRecord.LogLevel * 4) + 1), mapping["severityNumber"]); + + Assert.Equal(logRecord.CategoryName, mapping["name"]); + + bool isUnstructuredLog = true; + IReadOnlyList> stateKeyValuePairList; + if (logRecord.State == null) + { + stateKeyValuePairList = logRecord.StateValues; + } + else + { + stateKeyValuePairList = logRecord.State as IReadOnlyList>; + } + + if (stateKeyValuePairList != null) + { + isUnstructuredLog = stateKeyValuePairList.Count == 1; + } + + if (isUnstructuredLog) + { + if (logRecord.State != null) + { + Assert.Equal(logRecord.State.ToString(), mapping["body"]); + } + else + { + Assert.Equal(stateKeyValuePairList[0].Value, mapping["body"]); + } + } + else + { + _ = mapping.TryGetValue("env_properties", out object envProprties); + var envPropertiesMapping = envProprties as IDictionary; + + foreach (var item in stateKeyValuePairList) + { + if (item.Key == "{OriginalFormat}") + { + Assert.Equal(item.Value.ToString(), mapping["body"]); + } + else if (exporterOptions.CustomFields == null || exporterOptions.CustomFields.Contains(item.Key)) + { + if (item.Value != null) + { + Assert.Equal(item.Value, mapping[item.Key]); + } + } + else + { + Assert.Equal(item.Value, envPropertiesMapping[item.Key]); + } + } + } + + if (logRecord.EventId != default) + { + Assert.Equal(logRecord.EventId.Id, int.Parse(mapping["eventId"].ToString())); + } + + // Epilouge + Assert.Equal("DateTime", timeFormat["TimeFormat"]); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs new file mode 100644 index 0000000000..e082213b6c --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class GenevaMetricExporterOptionsTests + { + [Fact] + public void InvalidPrepopulatedDimensions() + { + var exception = Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions { PrepopulatedMetricDimensions = null }; + }); + + Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions + { + PrepopulatedMetricDimensions = new Dictionary + { + ["DimensionKey"] = null, + }, + }; + }); + + var invalidDimensionNameException = Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions + { + PrepopulatedMetricDimensions = new Dictionary + { + [new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)] = "DimensionValue", + }, + }; + }); + + var expectedErrorMessage = $"The dimension: {new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."; + Assert.Equal(expectedErrorMessage, invalidDimensionNameException.Message); + + var invalidDimensionValueException = Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions + { + PrepopulatedMetricDimensions = new Dictionary + { + ["DimensionKey"] = new string('a', GenevaMetricExporter.MaxDimensionValueSize + 1), + }, + }; + }); + + expectedErrorMessage = $"Value provided for the dimension: DimensionKey exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."; + Assert.Equal(expectedErrorMessage, invalidDimensionValueException.Message); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs new file mode 100644 index 0000000000..5ce768c930 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs @@ -0,0 +1,726 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using Kaitai; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using Xunit; +using static OpenTelemetry.Exporter.Geneva.UnitTest.MetricsContract; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class GenevaMetricExporterTests + { + [Fact] + [Trait("Platform", "Any")] + public void NullExporterOptions() + { + GenevaMetricExporterOptions exporterOptions = null; + Assert.Throws(() => new GenevaMetricExporter(exporterOptions)); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + [Trait("Platform", "Any")] + public void InvalidConnectionString(string connectionString) + { + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = connectionString }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaMetricExporter(exporterOptions); + }); + Assert.Equal($"{nameof(exporterOptions.ConnectionString)} is invalid.", exception.Message); + } + + [Fact] + [Trait("Platform", "Any")] + public void ParseConnectionStringCorrectly() + { + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var exporter = new GenevaMetricExporter(exporterOptions); + var monitoringAccount = typeof(GenevaMetricExporter).GetField("monitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + var metricNamespace = typeof(GenevaMetricExporter).GetField("metricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + Assert.Equal("OTelMonitoringAccount", monitoringAccount); + Assert.Equal("OTelMetricNamespace", metricNamespace); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + [Trait("Platform", "Any")] + public void SuccessfulSerialization(bool testMaxLimits) + { + using var meter = new Meter("SuccessfulSerialization", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var histogram = meter.CreateHistogram("histogram"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerialization") + .AddReader(inMemoryReader) + .Build(); + + long longValue = 123; + double doubleValue = 123.45; + + if (testMaxLimits) + { + longValue = long.MaxValue; + doubleValue = double.MaxValue; + } + + longCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2")); + + doubleCounter.Add( + doubleValue, new("tag1", "value1"), new("tag2", "value2")); + + meter.CreateObservableCounter( + "observableLongCounter", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableCounter( + "observableDoubleCounter", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableGauge( + "observableLongGauge", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableGauge( + "observableDoubleGauge", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + if (testMaxLimits) + { + // only testing the max value allowed for sum + // max value allowed for count is uint.MaxValue. It's not feasible to test that + histogram.Record(longValue, new("tag1", "value1"), new("tag2", "value2")); + } + else + { + // Record the following values from Histogram: + // (-inf - 0] : 1 + // (0 - 5] : 0 + // (5 - 10] : 0 + // (10 - 25] : 0 + // (25 - 50] : 0 + // (50 - 75] : 0 + // (75 - 100] : 0 + // (100 - 250] : 2 + // (250 - 500] : 0 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for the given distribution: + // 0: 1 + // 250: 2 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogram.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + } + + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + exporterOptions.PrepopulatedMetricDimensions = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + + using var exporter = new GenevaMetricExporter(exporterOptions); + + inMemoryReader.Collect(); + + Assert.Equal(7, exportedItems.Count); + + // check serialization for longCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + + // check serialization for doubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + + // check serialization for histogram + this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + + // check serialization for observableLongCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + + // check serialization for observableDoubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + + // check serialization for observableLongGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + + // check serialization for observableDoubleGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + [Trait("Platform", "Any")] + public void SuccessfulSerializationWithViews() + { + using var meter = new Meter("SuccessfulSerializationWithViews", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var histogramWithCustomBounds = meter.CreateHistogram("histogramWithCustomBounds"); + var histogramWithNoBounds = meter.CreateHistogram("histogramWithNoBounds"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerializationWithViews") + .AddView("longCounter", "renamedLongCounter") + .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { "tag1" } }) + .AddView( + "histogramWithCustomBounds", + new ExplicitBucketHistogramConfiguration + { + Name = "renamedhistogramWithCustomBounds", + Description = "modifiedDescription", + Boundaries = new double[] { 500, 1000 }, + }) + .AddView(instrument => + { + if (instrument.Name == "histogramWithNoBounds") + { + return new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { } }; + } + + return null; + }) + .AddView("observableLongCounter", MetricStreamConfiguration.Drop) + .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { } }) + .AddView(instrument => + { + if (instrument.Name == "observableLongGauge") + { + return new MetricStreamConfiguration + { + Name = "renamedobservableLongGauge", + Description = "modifiedDescription", + TagKeys = new string[] { "tag1" }, + }; + } + + return null; + }) + .AddView(instrument => + { + if (instrument.Name == "observableDoubleGauge") + { + return MetricStreamConfiguration.Drop; + } + + return null; + }) + .AddReader(inMemoryReader) + .Build(); + + longCounter.Add( + 123, new("tag1", "value1"), new("tag2", "value2")); + + doubleCounter.Add( + 123.45, new("tag1", "value1"), new("tag2", "value2")); + + meter.CreateObservableCounter( + "observableLongCounter", + () => new List>() + { + new(123, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableCounter( + "observableDoubleCounter", + () => new List>() + { + new(123.45, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableGauge( + "observableLongGauge", + () => new List>() + { + new(123, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableGauge( + "observableDoubleGauge", + () => new List>() + { + new(123.45, new("tag1", "value1"), new("tag2", "value2")), + }); + + // Record the following values for histogramWithCustomBounds: + // (-inf - 500] : 3 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for histogramWithCustomBounds: + // 500: 3 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogramWithCustomBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + + // Record the following values for histogramWithNoBounds: + // (-inf - 500] : 3 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // Only `sum` and `count` are sent for histogramWithNoBounds + // No value-count pairs are sent for histogramWithNoBounds + + histogramWithNoBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + exporterOptions.PrepopulatedMetricDimensions = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + + using var exporter = new GenevaMetricExporter(exporterOptions); + + inMemoryReader.Collect(); + + Assert.Equal(6, exportedItems.Count); + + // observableLongCounter and observableDoubleGauge are dropped + Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); + + // check serialization for longCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + + // check serialization for doubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + + // check serialization for histogramWithCustomBounds + this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + + // check serialization for histogramWithNoBounds + this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + + // check serialization for observableDoubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + + // check serialization for observableLongGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + [Trait("Platform", "Linux")] + public void SuccessfulExportOnLinux() + { + string path = GenerateTempFilePath(); + var exportedItems = new List(); + + using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); + var counter = meter.CreateCounter("counter"); + + using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); + var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); + + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + Temporality = AggregationTemporality.Delta, + }; + + // Set up two different providers as only one Metric Processor is allowed. + // TODO: Simplify the setup when multiple Metric processors are allowed. + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulExportOnLinux") + .AddGenevaMetricExporter(options => + { + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + options.MetricExportIntervalMilliseconds = 5000; + }) + .Build(); + + using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("InMemoryExportOnLinux") + .AddReader(inMemoryReader) + .Build(); + + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 15000; + + // Create a test exporter to get byte data for validation of the data received via Socket. + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; + using var exporter = new GenevaMetricExporter(exporterOptions); + + // Emit a metric and grab a copy of internal buffer for validation. + counter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + inMemoryCounter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + // exportedItems list should have a single entry after the MetricReader.Collect call + inMemoryReader.Collect(); + + Assert.Single(exportedItems); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + + // Wait a little more than the ExportInterval for the exporter to export the data. + Task.Delay(5500).Wait(); + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + var fixedPayloadLength = (int)typeof(GenevaMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); + + // The whole payload is sent to the Unix Domain Socket + // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload + Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); + + var stream = new KaitaiStream(receivedData); + var data = new MetricsContract(stream); + + Assert.Equal(metric.Name, data.Body.MetricName.Value); + Assert.Equal("OTelMonitoringAccount", data.Body.MetricAccount.Value); + Assert.Equal("OTelMetricNamespace", data.Body.MetricNamespace.Value); + + var valueSection = data.Body.ValueSection as SingleUint64Value; + Assert.Equal(metricDataValue, valueSection.Value); + + Assert.Equal(2, data.Body.NumDimensions); + + int i = 0; + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); + i++; + } + + Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + + private static string GenerateTempFilePath() + { + while (true) + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) + { + return path; + } + } + } + + private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) + { + var metricType = metric.MetricType; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + MetricsContract data = null; + + // Check metric value, timestamp, eventId, and length of payload + if (metricType == MetricType.LongSum || metricType == MetricType.LongGauge) + { + var metricDataValue = metricType == MetricType.LongSum ? + Convert.ToUInt64(metricPoint.GetSumLong()) : + Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleUint64Value; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + { + var metricDataValue = metricType == MetricType.DoubleSum ? + metricPoint.GetSumDouble() : + metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleDoubleValue; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.Histogram) + { + var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + var bodyLength = exporter.SerializeHistogramMetric( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as ExtAggregatedUint64Value; + var valueCountPairs = data.Body.Histogram.Body as HistogramValueCountPairs; + + Assert.Equal(0, data.Body.Histogram.Version); + Assert.Equal(2, (int)data.Body.Histogram.Type); + + int listIterator = 0; + int bucketsWithPositiveCount = 0; + double lastExplicitBound = default; + foreach (var bucket in metricPoint.GetHistogramBuckets()) + { + if (bucket.BucketCount > 0) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + Assert.Equal(bucket.ExplicitBound, valueCountPairs.Columns[listIterator].Value); + lastExplicitBound = bucket.ExplicitBound; + } + else + { + Assert.Equal((ulong)lastExplicitBound + 1, valueCountPairs.Columns[listIterator].Value); + } + + Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); + + listIterator++; + bucketsWithPositiveCount++; + } + } + + Assert.Equal(bucketsWithPositiveCount, valueCountPairs.DistributionSize); + + Assert.Equal(count, valueSection.Count); + Assert.Equal(Convert.ToUInt64(metricPoint.GetHistogramSum()), valueSection.Sum); + Assert.Equal(0UL, valueSection.Min); + Assert.Equal(0UL, valueSection.Max); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + + // Check metric name, account, and namespace + var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); + Assert.Equal(metric.Name, data.Body.MetricName.Value); + Assert.Equal(connectionStringBuilder.Account, data.Body.MetricAccount.Value); + Assert.Equal(connectionStringBuilder.Namespace, data.Body.MetricNamespace.Value); + + var dimensionsCount = 0; + if (exporterOptions.PrepopulatedMetricDimensions != null) + { + foreach (var entry in exporterOptions.PrepopulatedMetricDimensions) + { + Assert.Contains(data.Body.DimensionsNames, dim => dim.Value == entry.Key); + Assert.Contains(data.Body.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); + } + + dimensionsCount += exporterOptions.PrepopulatedMetricDimensions.Count; + } + + // Check metric dimensions + int i = 0; + foreach (var item in exporterOptions.PrepopulatedMetricDimensions) + { + Assert.Equal(item.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(item.Value, data.Body.DimensionsValues[i].Value); + i++; + } + + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); + i++; + } + + dimensionsCount += metricPoint.Tags.Count; + + Assert.Equal(dimensionsCount, data.Body.NumDimensions); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs new file mode 100644 index 0000000000..286b04323e --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs @@ -0,0 +1,515 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class GenevaTraceExporterTests + { + public GenevaTraceExporterTests() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + } + + [Fact] + [Trait("Platform", "Any")] + public void GenevaTraceExporter_constructor_Invalid_Input() + { + // no connection string + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions()); + }); + + // null connection string + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = null, + }); + }); + } + + [Fact] + [Trait("Platform", "Windows")] + public void GenevaTraceExporter_constructor_Invalid_Input_Windows() + { + // no ETW session name + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "key=value", + }); + }); + + // empty ETW session name + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=", + }); + }); + } + + [Fact] + [Trait("Platform", "Any")] + public void GenevaTraceExporter_TableNameMappings_SpecialCharacters() + { + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + TableNameMappings = new Dictionary { ["Span"] = "\u0418" }, + }); + }); + } + + [Fact] + [Trait("Platform", "Windows")] + public void GenevaTraceExporter_Success() + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + + // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + + var source = new ActivitySource(sourceName); + using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) + { + parent?.SetTag("http.method", "GET"); + parent?.SetTag("http.url", "https://localhost/wiki/Rabbit"); + using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) + { + child?.SetTag("http.method", "GET"); + child?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + child?.SetTag("http.status_code", 404); + } + + parent?.SetTag("http.status_code", 200); + } + + var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); + using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) + { + } + + using (var activity = source.StartActivity("Bar")) + { + activity.SetStatus(Status.Error); + } + + using (var activity = source.StartActivity("Baz")) + { + activity.SetStatus(Status.Ok); + } + } + + [Theory] + [InlineData(false, false)] + [InlineData(false, true)] + [InlineData(true, false)] + [InlineData(true, true)] + [Trait("Platform", "Any")] + public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields) + { + string path = string.Empty; + Socket server = null; + try + { + int invocationCount = 0; + var exporterOptions = new GenevaExporterOptions + { + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GetRandomFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + if (hasTableNameMapping) + { + exporterOptions.TableNameMappings = new Dictionary { { "Span", "CustomActivity" } }; + } + + if (hasCustomFields) + { + // The tag "clientRequestId" should be present in the mapping as a separate key. Other tags which are not present + // in the m_dedicatedFields should be added in the mapping under "env_properties" + exporterOptions.CustomFields = new string[] { "clientRequestId" }; + } + + using var exporter = new GenevaTraceExporter(exporterOptions); + var dedicatedFields = typeof(GenevaTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as IReadOnlyDictionary; + var CS40_PART_B_MAPPING = typeof(GenevaTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; + var m_buffer = typeof(GenevaTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; + + // Add an ActivityListener to serialize the activity and assert that it was valid on ActivityStopped event + + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + + using var listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; + listener.Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; + listener.ActivityStopped = (activity) => + { + _ = exporter.SerializeActivity(activity); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields); + invocationCount++; + }; + ActivitySource.AddActivityListener(listener); + + using var source = new ActivitySource(sourceName); + using (var parentActivity = source.StartActivity("ParentActivity")) + { + var linkedtraceId1 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a1".AsSpan()); + var linkedSpanId1 = ActivitySpanId.CreateFromString("888915b6286b9c01".AsSpan()); + + var linkedtraceId2 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a2".AsSpan()); + var linkedSpanId2 = ActivitySpanId.CreateFromString("888915b6286b9c02".AsSpan()); + + var links = new[] + { + new ActivityLink(new ActivityContext( + linkedtraceId1, + linkedSpanId1, + ActivityTraceFlags.Recorded)), + new ActivityLink(new ActivityContext( + linkedtraceId2, + linkedSpanId2, + ActivityTraceFlags.Recorded)), + }; + + using (var activity = source.StartActivity("SayHello", ActivityKind.Internal, parentActivity.Context, null, links)) + { + activity?.SetTag("http.status_code", 500); // This should be added as httpStatusCode in the mapping + activity?.SetTag("azureResourceProvider", "Microsoft.AAD"); + activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); + activity?.SetTag("foo", 1); + activity?.SetTag("bar", 2); + activity?.SetStatus(Status.Error); + } + } + + Assert.Equal(2, invocationCount); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + [Trait("Platform", "Linux")] + public void GenevaTraceExporter_Linux_constructor_Missing() + { + string path = GetRandomFilePath(); + + // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address + try + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + }) + .Build(); + Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + } + catch (SocketException ex) + { + Assert.Contains("Cannot assign requested address", ex.Message); + } + + try + { + var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + }); + Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + } + catch (SocketException ex) + { + Assert.Contains("Cannot assign requested address", ex.Message); + } + } + + [Fact] + [Trait("Platform", "Linux")] + public void GenevaTraceExporter_Linux_Success() + { + string path = GetRandomFilePath(); + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + using Socket serverSocket = server.Accept(); + + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + // Emit trace and grab a copy of internal buffer for validation. + var source = new ActivitySource(sourceName); + int messagePackDataSize; + using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) + { + messagePackDataSize = exporter.SerializeActivity(activity); + } + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); + } + catch (Exception) + { + throw; + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + + private static string GetRandomFilePath() + { + while (true) + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) + { + return path; + } + } + } + + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } + + private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, IReadOnlyDictionary dedicatedFields) + { + /* Fluentd Forward Mode: + [ + "Span", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var timeStamp = (DateTime)(TimeStampAndMappings as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var timeFormat = (fluentdData as object[])[2] as Dictionary; + + var partAName = "Span"; + if (exporterOptions.TableNameMappings != null) + { + partAName = exporterOptions.TableNameMappings["Span"]; + } + + Assert.Equal(partAName, signal); + + // Timestamp check + var dtBegin = activity.StartTimeUtc; + var tsBegin = dtBegin.Ticks; + var tsEnd = tsBegin + activity.Duration.Ticks; + Assert.Equal(tsEnd, timeStamp.Ticks); + + // Part A core envelope fields + + var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; + + // Check if the user has configured a custom table mapping + Assert.Equal(partAName, mapping[nameKey]); + + // TODO: Update this when we support multiple Schema formats + var partAVer = "4.0"; + var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; + Assert.Equal(partAVer, mapping[verKey]); + + foreach (var item in exporterOptions.PrepopulatedFields) + { + var partAValue = item.Value as string; + var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; + Assert.Equal(partAValue, mapping[partAKey]); + } + + var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; + Assert.Equal(tsEnd, ((DateTime)mapping[timeKey]).Ticks); + + // Part A dt extensions + Assert.Equal(activity.TraceId.ToString(), mapping["env_dt_traceId"]); + Assert.Equal(activity.SpanId.ToString(), mapping["env_dt_spanId"]); + + // Part B Span - required fields + Assert.Equal(activity.DisplayName, mapping["name"]); + Assert.Equal((byte)activity.Kind, mapping["kind"]); + Assert.Equal(activity.StartTimeUtc, mapping["startTime"]); + + var activityStatusCode = activity.GetStatus().StatusCode; + Assert.Equal(activityStatusCode == StatusCode.Error ? false : true, mapping["success"]); + + // Part B Span optional fields and Part C fields + if (activity.ParentSpanId != default) + { + Assert.Equal(activity.ParentSpanId.ToHexString(), mapping["parentId"]); + } + + #region Assert Activity Links + if (activity.Links.Any()) + { + Assert.Contains(mapping, m => m.Key as string == "links"); + var mappingLinks = mapping["links"] as IEnumerable; + using IEnumerator activityLinksEnumerator = activity.Links.GetEnumerator(); + using IEnumerator mappingLinksEnumerator = mappingLinks.GetEnumerator(); + while (activityLinksEnumerator.MoveNext() && mappingLinksEnumerator.MoveNext()) + { + var activityLink = activityLinksEnumerator.Current; + var mappingLink = mappingLinksEnumerator.Current as Dictionary; + + Assert.Equal(activityLink.Context.TraceId.ToHexString(), mappingLink["toTraceId"]); + Assert.Equal(activityLink.Context.SpanId.ToHexString(), mappingLink["toSpanId"]); + } + + // Assert that mapping contains exactly the same number of ActivityLinks as present in the activity + // MoveNext() on both the enumerators should return false as we should have enumerated till the last element for both the Enumerables + Assert.Equal(activityLinksEnumerator.MoveNext(), mappingLinksEnumerator.MoveNext()); + } + else + { + Assert.DoesNotContain(mapping, m => m.Key as string == "links"); + } + #endregion + + #region Assert Activity Tags + _ = mapping.TryGetValue("env_properties", out object envProprties); + var envPropertiesMapping = envProprties as IDictionary; + foreach (var tag in activity.TagObjects) + { + if (CS40_PART_B_MAPPING.TryGetValue(tag.Key, out string replacementKey)) + { + Assert.Equal(tag.Value.ToString(), mapping[replacementKey].ToString()); + } + else if (string.Equals(tag.Key, "otel.status_code", StringComparison.Ordinal)) + { + // Status code check is already done when we check for "success" key in the mapping + continue; + } + else + { + // If CustomFields are proivded, dedicatedFields will be populated + if (exporterOptions.CustomFields == null || dedicatedFields.ContainsKey(tag.Key)) + { + Assert.Equal(tag.Value.ToString(), mapping[tag.Key].ToString()); + } + else + { + Assert.Equal(tag.Value.ToString(), envPropertiesMapping[tag.Key].ToString()); + } + } + } + #endregion + + // Epilouge + Assert.Equal("DateTime", timeFormat["TimeFormat"]); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs new file mode 100644 index 0000000000..7ee2f3f8a0 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs @@ -0,0 +1,388 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; +using Xunit.Sdk; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class MessagePackSerializerTests + { + private void AssertBytes(byte[] expected, byte[] actual, int length) + { + Assert.Equal(expected.Length, length); + for (int i = 0; i < length; i++) + { + byte expectedByte = expected[i]; + byte actualByte = actual[i]; + + Assert.True( + expectedByte == actualByte, + string.Format($"Expected: '{(byte)expectedByte}', Actual: '{(byte)actualByte}' at offset {i}.")); + } + } + + private void MessagePackSerializer_TestSerialization(object obj) + { + var buffer = new byte[64 * 1024]; + var length = MessagePackSerializer.Serialize(buffer, 0, obj); + this.AssertBytes(MessagePack.MessagePackSerializer.Serialize(obj), buffer, length); + } + + private void MessagePackSerializer_TestASCIIStringSerialization(string input) + { + var sizeLimit = (1 << 14) - 1; // // Max length of string allowed + var buffer = new byte[64 * 1024]; + var length = MessagePackSerializer.SerializeAsciiString(buffer, 0, input); + var deserializedString = MessagePack.MessagePackSerializer.Deserialize(buffer); + if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) + { + // We truncate the string using `.` in the last three characters which takes 3 bytes of memort + var byteCount = Encoding.ASCII.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata + + Assert.NotEqual(input, deserializedString); + + int i; + for (i = 0; i < sizeLimit - 3; i++) + { + Assert.Equal(input[i], deserializedString[i]); + } + + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + } + else + { + if (input != null) + { + var byteCount = Encoding.ASCII.GetByteCount(input); + if (input.Length <= 31) + { + Assert.Equal(0xA0 | byteCount, buffer[0]); + Assert.Equal(byteCount, length - 1); // First one byte is metadata + } + else if (input.Length <= 255) + { + Assert.Equal(0xD9, buffer[0]); + Assert.Equal(byteCount, buffer[1]); + Assert.Equal(byteCount, length - 2); // First two bytes are metadata + } + else if (input.Length <= sizeLimit) + { + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata + } + } + + Assert.Equal(input, deserializedString); + } + } + + private void MessagePackSerializer_TestUnicodeStringSerialization(string input) + { + var sizeLimit = (1 << 14) - 1; // // Max length of string allowed + var buffer = new byte[64 * 1024]; + var length = MessagePackSerializer.SerializeUnicodeString(buffer, 0, input); + + var deserializedString = MessagePack.MessagePackSerializer.Deserialize(buffer); + if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) + { + // We truncate the string using `.` in the last three characters which takes 3 bytes of memory + var byteCount = Encoding.UTF8.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata + + Assert.NotEqual(input, deserializedString); + + int i; + for (i = 0; i < sizeLimit - 3; i++) + { + Assert.Equal(input[i], deserializedString[i]); + } + + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + } + else + { + Assert.Equal(input, deserializedString); + + if (input != null) + { + var byteCount = Encoding.UTF8.GetByteCount(input); + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata + } + } + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_Null() + { + this.MessagePackSerializer_TestSerialization(null); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_Boolean() + { + this.MessagePackSerializer_TestSerialization(true); + this.MessagePackSerializer_TestSerialization(false); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_Int() + { + // 8 bits + for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization(value); + } + + this.MessagePackSerializer_TestSerialization(sbyte.MaxValue); + + // 16 bits + for (short value = short.MinValue; value < short.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization(value); + } + + this.MessagePackSerializer_TestSerialization(short.MaxValue); + + // 32 bits + this.MessagePackSerializer_TestSerialization(int.MinValue); + this.MessagePackSerializer_TestSerialization(int.MinValue + 1); + this.MessagePackSerializer_TestSerialization((int)short.MinValue - 1); + this.MessagePackSerializer_TestSerialization((int)short.MinValue); + this.MessagePackSerializer_TestSerialization((int)short.MinValue + 1); + this.MessagePackSerializer_TestSerialization((int)sbyte.MinValue - 1); + for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization((int)value); + } + + this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue); + this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((int)short.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((int)short.MaxValue); + this.MessagePackSerializer_TestSerialization((int)short.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(int.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(int.MaxValue); + + // 64 bits + this.MessagePackSerializer_TestSerialization(long.MinValue); + this.MessagePackSerializer_TestSerialization(long.MinValue + 1); + this.MessagePackSerializer_TestSerialization((long)int.MinValue - 1); + this.MessagePackSerializer_TestSerialization((long)int.MinValue); + this.MessagePackSerializer_TestSerialization((long)int.MinValue + 1); + this.MessagePackSerializer_TestSerialization((long)short.MinValue - 1); + this.MessagePackSerializer_TestSerialization((long)short.MinValue); + this.MessagePackSerializer_TestSerialization((long)short.MinValue + 1); + this.MessagePackSerializer_TestSerialization((long)sbyte.MinValue - 1); + for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization((long)value); + } + + this.MessagePackSerializer_TestSerialization((long)sbyte.MaxValue); + this.MessagePackSerializer_TestSerialization((long)sbyte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((long)short.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((long)short.MaxValue); + this.MessagePackSerializer_TestSerialization((long)short.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((long)int.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((long)int.MaxValue); + this.MessagePackSerializer_TestSerialization((long)int.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(long.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(long.MaxValue); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_UInt() + { + // 8 bits + for (byte value = byte.MinValue; value < byte.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization(value); + } + + this.MessagePackSerializer_TestSerialization(byte.MaxValue); + + // 16 bits + for (ushort value = ushort.MinValue; value < ushort.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization(value); + } + + this.MessagePackSerializer_TestSerialization(ushort.MaxValue); + + // 32 bits + this.MessagePackSerializer_TestSerialization(uint.MinValue); + this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue); + this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue); + this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(uint.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(uint.MaxValue); + + // 64 bits + this.MessagePackSerializer_TestSerialization(ulong.MinValue); + this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue); + this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue); + this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue); + this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(ulong.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(ulong.MaxValue); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_Float() + { + this.MessagePackSerializer_TestSerialization(0.0f); + this.MessagePackSerializer_TestSerialization(1.0f); + this.MessagePackSerializer_TestSerialization(-123.45f); + this.MessagePackSerializer_TestSerialization(float.MaxValue); + this.MessagePackSerializer_TestSerialization(float.MinValue); + this.MessagePackSerializer_TestSerialization(float.PositiveInfinity); + this.MessagePackSerializer_TestSerialization(float.NegativeInfinity); + + this.MessagePackSerializer_TestSerialization(0.0d); + this.MessagePackSerializer_TestSerialization(3.1415926d); + this.MessagePackSerializer_TestSerialization(-67.89f); + this.MessagePackSerializer_TestSerialization(double.MaxValue); + this.MessagePackSerializer_TestSerialization(double.MinValue); + this.MessagePackSerializer_TestSerialization(double.PositiveInfinity); + this.MessagePackSerializer_TestSerialization(double.NegativeInfinity); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_SerializeAsciiString() + { + this.MessagePackSerializer_TestASCIIStringSerialization(null); + this.MessagePackSerializer_TestASCIIStringSerialization(string.Empty); + this.MessagePackSerializer_TestASCIIStringSerialization("Hello world!"); + + // fixstr stores a byte array whose length is upto 31 bytes + this.MessagePackSerializer_TestASCIIStringSerialization("1234567890123456789012345678901"); + + // str 8 stores a byte array whose length is upto (2^8)-1 bytes + this.MessagePackSerializer_TestASCIIStringSerialization("12345678901234567890123456789012"); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('A', byte.MaxValue)); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('B', byte.MaxValue + 1)); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('Z', (1 << 14) - 1)); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('Z', 1 << 14)); + + // Unicode special characters + // SerializeAsciiString will encode non-ASCII characters with '?' + Assert.Throws(() => this.MessagePackSerializer_TestASCIIStringSerialization("\u0418")); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_SerializeUnicodeString() + { + this.MessagePackSerializer_TestUnicodeStringSerialization(null); + this.MessagePackSerializer_TestUnicodeStringSerialization(string.Empty); + this.MessagePackSerializer_TestUnicodeStringSerialization("Hello world!"); + + // fixstr stores a byte array whose length is upto 31 bytes + this.MessagePackSerializer_TestUnicodeStringSerialization("1234567890123456789012345678901"); + + // str 8 stores a byte array whose length is upto (2^8)-1 bytes + this.MessagePackSerializer_TestUnicodeStringSerialization("12345678901234567890123456789012"); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('A', byte.MaxValue)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('B', byte.MaxValue + 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('Z', (1 << 14) - 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('Z', 1 << 14)); + + // ill-formed UTF-8 sequence + // This is replaced by `U+FFFD REPLACEMENT CHARACTER` in the returned string instance constructed from the byte array + // TODO: Update this test case once the serializer starts to throw exception for ill-formed UTF-8 sequence. + Assert.Throws(() => this.MessagePackSerializer_TestUnicodeStringSerialization("\uD801\uD802")); + + // Unicode special characters + this.MessagePackSerializer_TestUnicodeStringSerialization("\u0418"); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 31)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 50)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', (1 << 8) - 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 1 << 10)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', (1 << 14) - 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 1 << 14)); + + // Unicode regular and special characters + this.MessagePackSerializer_TestUnicodeStringSerialization("\u0418TestString"); + this.MessagePackSerializer_TestUnicodeStringSerialization("TestString\u0418"); + this.MessagePackSerializer_TestUnicodeStringSerialization("Test\u0418String"); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_Array() + { + this.MessagePackSerializer_TestSerialization((object[])null); + this.MessagePackSerializer_TestSerialization(new object[0]); + + // This object array has a custom string which will be serialized as STR16 + var objectArrayWithString = new object[] + { + "foo", + 1, + 0.6180340f, + 3.14159265358979323846264d, + }; + + var buffer = new byte[64 * 1024]; + _ = MessagePackSerializer.Serialize(buffer, 0, objectArrayWithString); + var objectArrayWithStringDeserialized = MessagePack.MessagePackSerializer.Deserialize(buffer); + Assert.Equal(objectArrayWithString.Length, objectArrayWithStringDeserialized.Length); + Assert.Equal(objectArrayWithString[0], objectArrayWithStringDeserialized[0]); + Assert.Equal(objectArrayWithString[1], Convert.ToInt32(objectArrayWithStringDeserialized[1])); + Assert.Equal(objectArrayWithString[2], objectArrayWithStringDeserialized[2]); + Assert.Equal(objectArrayWithString[3], objectArrayWithStringDeserialized[3]); + } + + [Fact] + [Trait("Platform", "Any")] + public void MessagePackSerializer_Map() + { + this.MessagePackSerializer_TestSerialization((Dictionary)null); + this.MessagePackSerializer_TestSerialization(new Dictionary()); + + // This dictionary has custom strings which will be serialized as STR16 + var dictionaryWithStrings = new Dictionary + { + ["foo"] = 1, + ["bar"] = "baz", + ["golden ratio"] = 0.6180340f, + ["pi"] = 3.14159265358979323846264d, + }; + var buffer = new byte[64 * 1024]; + _ = MessagePackSerializer.Serialize(buffer, 0, dictionaryWithStrings); + var dictionaryWithStringsDeserialized = MessagePack.MessagePackSerializer.Deserialize>(buffer); + Assert.Equal(dictionaryWithStrings.Count, dictionaryWithStringsDeserialized.Count); + Assert.Equal(dictionaryWithStrings["foo"], Convert.ToInt32(dictionaryWithStringsDeserialized["foo"])); + Assert.Equal(dictionaryWithStrings["bar"], dictionaryWithStringsDeserialized["bar"]); + Assert.Equal(dictionaryWithStrings["golden ratio"], dictionaryWithStringsDeserialized["golden ratio"]); + Assert.Equal(dictionaryWithStrings["pi"], dictionaryWithStringsDeserialized["pi"]); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs new file mode 100644 index 0000000000..eb813cdde1 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs @@ -0,0 +1,665 @@ +// + +using System.Collections.Generic; +using Kaitai; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public partial class MetricsContract : KaitaiStruct + { + public static MetricsContract FromFile(string fileName) + { + return new MetricsContract(new KaitaiStream(fileName)); + } + + + public enum MetricEventType + { + Old = 0, + Uint64Metric = 50, + DoubleScaledToLongMetric = 51, + BatchMetric = 52, + ExternallyAggregatedUlongMetric = 53, + ExternallyAggregatedDoubleMetric = 54, + DoubleMetric = 55, + ExternallyAggregatedUlongDistributionMetric = 56, + ExternallyAggregatedDoubleDistributionMetric = 57, + ExternallyAggregatedDoubleScaledToLongDistributionMetric = 58, + } + + public enum DistributionType + { + Bucketed = 0, + MonBucketed = 1, + ValueCountPairs = 2, + } + public MetricsContract(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root ?? this; + this._read(); + } + private void _read() + { + this._eventId = this.m_io.ReadU2le(); + this._lenBody = this.m_io.ReadU2le(); + this.__raw_body = this.m_io.ReadBytes(this.LenBody); + var io___raw_body = new KaitaiStream(this.__raw_body); + this._body = new Userdata(this.EventId, io___raw_body, this, this.m_root); + } + + /// + /// This type represents "UserData" or "body" portion of Metrics message. + /// + public partial class Userdata : KaitaiStruct + { + public Userdata(ushort p_eventId, KaitaiStream p__io, MetricsContract p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._eventId = p_eventId; + this.f_eventType = false; + this._read(); + } + private void _read() + { + this._numDimensions = this.m_io.ReadU2le(); + this._padding = this.m_io.ReadBytes(2); + switch (this.EventType) + { + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric: + { + this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.DoubleMetric: + { + this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedUlongMetric: + { + this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric: + { + this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric: + { + this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.DoubleScaledToLongMetric: + { + this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.Uint64Metric: + { + this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleMetric: + { + this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.Old: + { + this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); + break; + } + } + this._metricAccount = new LenString(this.m_io, this, this.m_root); + this._metricNamespace = new LenString(this.m_io, this, this.m_root); + this._metricName = new LenString(this.m_io, this, this.m_root); + this._dimensionsNames = new List((int)this.NumDimensions); + for (var i = 0; i < this.NumDimensions; i++) + { + this._dimensionsNames.Add(new LenString(this.m_io, this, this.m_root)); + } + this._dimensionsValues = new List((int)this.NumDimensions); + for (var i = 0; i < this.NumDimensions; i++) + { + this._dimensionsValues.Add(new LenString(this.m_io, this, this.m_root)); + } + if (!this.M_Io.IsEof) + { + this._apContainer = new LenString(this.m_io, this, this.m_root); + } + if (((this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric)) && (!this.M_Io.IsEof)) + { + this._histogram = new Histogram(this.m_io, this, this.m_root); + } + } + private bool f_eventType; + private MetricEventType _eventType; + public MetricEventType EventType + { + get + { + if (this.f_eventType) + return this._eventType; + this._eventType = (MetricEventType)(MetricsContract.MetricEventType)this.EventId; + this.f_eventType = true; + return this._eventType; + } + } + private ushort _numDimensions; + private byte[] _padding; + private KaitaiStruct _valueSection; + private LenString _metricAccount; + private LenString _metricNamespace; + private LenString _metricName; + private List _dimensionsNames; + private List _dimensionsValues; + private LenString _apContainer; + private Histogram _histogram; + private ushort _eventId; + private MetricsContract m_root; + private MetricsContract m_parent; + + /// + /// Number of dimensions specified in this event. + /// + public ushort NumDimensions { get { return this._numDimensions; } } + public byte[] Padding { get { return this._padding; } } + + /// + /// Value section of the body, stores fixed numeric metric value(s), as per event type. + /// + public KaitaiStruct ValueSection { get { return this._valueSection; } } + + /// + /// Geneva Metrics account name to be used for this metric. + /// + public LenString MetricAccount { get { return this._metricAccount; } } + + /// + /// Geneva Metrics namespace name to be used for this metric. + /// + public LenString MetricNamespace { get { return this._metricNamespace; } } + + /// + /// Geneva Metrics metric name to be used. + /// + public LenString MetricName { get { return this._metricName; } } + + /// + /// Dimension names strings ("key" parts of key-value pairs). Must be sorted, + /// unless MetricsExtenion's option `enableDimensionSortingOnIngestion` is + /// enabled. + /// + public List DimensionsNames { get { return this._dimensionsNames; } } + + /// + /// Dimension values strings ("value" parts of key-value pairs). + /// + public List DimensionsValues { get { return this._dimensionsValues; } } + + /// + /// AutoPilot container string, required for correct AP PKI certificate loading + /// in AutoPilot containers environment. + /// + public LenString ApContainer { get { return this._apContainer; } } + public Histogram Histogram { get { return this._histogram; } } + + /// + /// Type of message, affects format of the body. + /// + public ushort EventId { get { return this._eventId; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract M_Parent { get { return this.m_parent; } } + } + + /// + /// Bucket with an explicitly-defined value coordinate `value`, claiming to + /// hold `count` hits. Normally used to represent non-linear (e.g. exponential) + /// histograms payloads. + /// + public partial class PairValueCount : KaitaiStruct + { + public static PairValueCount FromFile(string fileName) + { + return new PairValueCount(new KaitaiStream(fileName)); + } + + public PairValueCount(KaitaiStream p__io, MetricsContract.HistogramValueCountPairs p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._value = this.m_io.ReadU8le(); + this._count = this.m_io.ReadU4le(); + } + private ulong _value; + private uint _count; + private MetricsContract m_root; + private MetricsContract.HistogramValueCountPairs m_parent; + public ulong Value { get { return this._value; } } + public uint Count { get { return this._count; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.HistogramValueCountPairs M_Parent { get { return this.m_parent; } } + } + + /// + /// Payload of a histogram with linear distribution of buckets. Such histogram + /// is defined by the parameters specified in `min`, `bucket_size` and + /// `bucket_count`. It is modelled as a series of buckets. First (index 0) and + /// last (indexed `bucket_count - 1`) buckets are special and are supposed to + /// catch all "underflow" and "overflow" values. Buckets with indexes 1 up to + /// `bucket_count - 2` are regular buckets of size `bucket_size`. + /// + public partial class HistogramUint16Bucketed : KaitaiStruct + { + public static HistogramUint16Bucketed FromFile(string fileName) + { + return new HistogramUint16Bucketed(new KaitaiStream(fileName)); + } + + public HistogramUint16Bucketed(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._min = this.m_io.ReadU8le(); + this._bucketSize = this.m_io.ReadU4le(); + this._bucketCount = this.m_io.ReadU4le(); + this._distributionSize = this.m_io.ReadU2le(); + this._columns = new List((int)this.DistributionSize); + for (var i = 0; i < this.DistributionSize; i++) + { + this._columns.Add(new PairUint16(this.m_io, this, this.m_root)); + } + } + private ulong _min; + private uint _bucketSize; + private uint _bucketCount; + private ushort _distributionSize; + private List _columns; + private MetricsContract m_root; + private MetricsContract.Histogram m_parent; + public ulong Min { get { return this._min; } } + public uint BucketSize { get { return this._bucketSize; } } + public uint BucketCount { get { return this._bucketCount; } } + public ushort DistributionSize { get { return this._distributionSize; } } + public List Columns { get { return this._columns; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } + } + public partial class HistogramValueCountPairs : KaitaiStruct + { + public static HistogramValueCountPairs FromFile(string fileName) + { + return new HistogramValueCountPairs(new KaitaiStream(fileName)); + } + + public HistogramValueCountPairs(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._distributionSize = this.m_io.ReadU2le(); + this._columns = new List((int)this.DistributionSize); + for (var i = 0; i < this.DistributionSize; i++) + { + this._columns.Add(new PairValueCount(this.m_io, this, this.m_root)); + } + } + private ushort _distributionSize; + private List _columns; + private MetricsContract m_root; + private MetricsContract.Histogram m_parent; + public ushort DistributionSize { get { return this._distributionSize; } } + public List Columns { get { return this._columns; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } + } + public partial class Histogram : KaitaiStruct + { + public static Histogram FromFile(string fileName) + { + return new Histogram(new KaitaiStream(fileName)); + } + + public Histogram(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._version = this.m_io.ReadU1(); + this._type = (MetricsContract.DistributionType)this.m_io.ReadU1(); + switch (this.Type) + { + case MetricsContract.DistributionType.Bucketed: + { + this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); + break; + } + case MetricsContract.DistributionType.MonBucketed: + { + this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); + break; + } + case MetricsContract.DistributionType.ValueCountPairs: + { + this._body = new HistogramValueCountPairs(this.m_io, this, this.m_root); + break; + } + } + } + private byte _version; + private DistributionType _type; + private KaitaiStruct _body; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte Version { get { return this._version; } } + public DistributionType Type { get { return this._type; } } + public KaitaiStruct Body { get { return this._body; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + + /// + /// Bucket #index, claiming to hold exactly `count` hits. See notes in + /// `histogram_uint16_bucketed` for interpreting index. + /// + public partial class PairUint16 : KaitaiStruct + { + public static PairUint16 FromFile(string fileName) + { + return new PairUint16(new KaitaiStream(fileName)); + } + + public PairUint16(KaitaiStream p__io, MetricsContract.HistogramUint16Bucketed p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._index = this.m_io.ReadU2le(); + this._count = this.m_io.ReadU2le(); + } + private ushort _index; + private ushort _count; + private MetricsContract m_root; + private MetricsContract.HistogramUint16Bucketed m_parent; + public ushort Index { get { return this._index; } } + public ushort Count { get { return this._count; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.HistogramUint16Bucketed M_Parent { get { return this.m_parent; } } + } + public partial class SingleUint64Value : KaitaiStruct + { + public static SingleUint64Value FromFile(string fileName) + { + return new SingleUint64Value(new KaitaiStream(fileName)); + } + + public SingleUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._padding = this.m_io.ReadBytes(4); + this._timestamp = this.m_io.ReadU8le(); + this._value = this.m_io.ReadU8le(); + } + private byte[] _padding; + private ulong _timestamp; + private ulong _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte[] Padding { get { return this._padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + + /// + /// Metric value as 64-bit unsigned integer. + /// + public ulong Value { get { return this._value; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + public partial class ExtAggregatedDoubleValue : KaitaiStruct + { + public static ExtAggregatedDoubleValue FromFile(string fileName) + { + return new ExtAggregatedDoubleValue(new KaitaiStream(fileName)); + } + + public ExtAggregatedDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._count = this.m_io.ReadU4le(); + this._timestamp = this.m_io.ReadU8le(); + this._sum = this.m_io.ReadF8le(); + this._min = this.m_io.ReadF8le(); + this._max = this.m_io.ReadF8le(); + } + private uint _count; + private ulong _timestamp; + private double _sum; + private double _min; + private double _max; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + + /// + /// Count of events aggregated in this event. + /// + public uint Count { get { return this._count; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public double Sum { get { return this._sum; } } + + /// + /// Minimum of all metric values aggregated in this event. + /// + public double Min { get { return this._min; } } + + /// + /// Maximum of all metric values aggregated in this event. + /// + public double Max { get { return this._max; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + public partial class ExtAggregatedUint64Value : KaitaiStruct + { + public static ExtAggregatedUint64Value FromFile(string fileName) + { + return new ExtAggregatedUint64Value(new KaitaiStream(fileName)); + } + + public ExtAggregatedUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._count = this.m_io.ReadU4le(); + this._timestamp = this.m_io.ReadU8le(); + this._sum = this.m_io.ReadU8le(); + this._min = this.m_io.ReadU8le(); + this._max = this.m_io.ReadU8le(); + } + private uint _count; + private ulong _timestamp; + private ulong _sum; + private ulong _min; + private ulong _max; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + + /// + /// Count of events aggregated in this event. + /// + public uint Count { get { return this._count; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public ulong Sum { get { return this._sum; } } + + /// + /// Minimum of all metric values aggregated in this event. + /// + public ulong Min { get { return this._min; } } + + /// + /// Maximum of all metric values aggregated in this event. + /// + public ulong Max { get { return this._max; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + public partial class SingleDoubleValue : KaitaiStruct + { + public static SingleDoubleValue FromFile(string fileName) + { + return new SingleDoubleValue(new KaitaiStream(fileName)); + } + + public SingleDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._padding = this.m_io.ReadBytes(4); + this._timestamp = this.m_io.ReadU8le(); + this._value = this.m_io.ReadF8le(); + } + private byte[] _padding; + private ulong _timestamp; + private double _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte[] Padding { get { return this._padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + + /// + /// Metric value as double. + /// + public double Value { get { return this._value; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + + /// + /// A simple string, length-prefixed with a 2-byte integer. + /// + public partial class LenString : KaitaiStruct + { + public static LenString FromFile(string fileName) + { + return new LenString(new KaitaiStream(fileName)); + } + + public LenString(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._lenValue = this.m_io.ReadU2le(); + this._value = System.Text.Encoding.GetEncoding("UTF-8").GetString(this.m_io.ReadBytes(this.LenValue)); + } + private ushort _lenValue; + private string _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public ushort LenValue { get { return this._lenValue; } } + public string Value { get { return this._value; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + private ushort _eventId; + private ushort _lenBody; + private Userdata _body; + private MetricsContract m_root; + private KaitaiStruct m_parent; + private byte[] __raw_body; + + /// + /// Type of message, affects format of the body. + /// + public ushort EventId { get { return this._eventId; } } + + /// + /// Size of body in bytes. + /// + public ushort LenBody { get { return this._lenBody; } } + + /// + /// Body of Metrics binary protocol message. + /// + public Userdata Body { get { return this._body; } } + public MetricsContract M_Root { get { return this.m_root; } } + public KaitaiStruct M_Parent { get { return this.m_parent; } } + public byte[] M_RawBody { get { return this.__raw_body; } } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj b/test/OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj new file mode 100644 index 0000000000..372035fd34 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj @@ -0,0 +1,40 @@ + + + + Unit test project for Geneva Exporters for OpenTelemetry + false + netcoreapp3.1;net5.0;net6.0 + $(TargetFrameworks);net461;net462;net47;net471;net472;net48 + $(NoWarn),SA1633,SA1311,SA1312,SA1313,SA1123,SA1202 + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs new file mode 100644 index 0000000000..6a7cb34567 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs @@ -0,0 +1,195 @@ +using System; +using System.IO; +using System.Net.Sockets; +using System.Reflection; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class UnixDomainSocketDataTransportTests + { + [Fact] + [Trait("Platform", "Linux")] + public void UnixDomainSocketDataTransport_Success() + { + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + try + { + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + using Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + } + catch (Exception) + { + throw; + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + [Trait("Platform", "Linux")] + public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull() + { + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + var data = new byte[1024]; + var i = 0; + using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests + var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; + try + { + // Client + using Socket serverSocket = server.Accept(); + while (true) + { + Console.WriteLine($"Sending request #{i++}."); + socket.Send(data, data.Length, SocketFlags.None); + } + + // The server is not processing sent data (because of heavy load, etc.) + } + catch (Exception) + { + // At this point, the outgoing buffer for the socket must be full, + // because the last Send failed. + // Send again and assert the exception to confirm: + Assert.Throws(() => + { + Console.WriteLine($"Sending request #{i}."); + socket.Send(data, data.Length, SocketFlags.None); + }); + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + [Trait("Platform", "Linux")] + public void UnixDomainSocketDataTransport_ServerRestart() + { + Console.WriteLine("Test starts."); + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + try + { + var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + + // LingerOption lo = new LingerOption(false, 0); + // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + + Console.WriteLine("Successfully sent a message."); + + // Emulate server stops + serverSocket.Shutdown(SocketShutdown.Both); + serverSocket.Disconnect(false); + serverSocket.Dispose(); + server.Shutdown(SocketShutdown.Both); + server.Disconnect(false); + server.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + + Console.WriteLine("Destroyed server."); + + Console.WriteLine("Client will fail during Send, but shouldn't throw exception."); + dataTransport.Send(data, data.Length); + Console.WriteLine("Client will fail during reconnect, but shouldn't throw exception."); + dataTransport.Send(data, data.Length); + + using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server2.Bind(endpoint); + server2.Listen(1); + Console.WriteLine("Started a new server and listening."); + + var data2 = new byte[] { 34, 56, 78 }; + dataTransport.Send(data2, data2.Length); + Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); + + using Socket serverSocket2 = server2.Accept(); + Console.WriteLine("The new server is ready and accepting connections."); + var receivedData2 = new byte[5]; + serverSocket2.Receive(receivedData2); + Console.WriteLine("Server received a messge."); + Assert.Equal(data2[0], receivedData2[0]); + Assert.Equal(data2[1], receivedData2[1]); + Assert.Equal(data2[2], receivedData2[2]); + } + catch (Exception) + { + throw; + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + + private static string GetRandomFilePath() + { + while (true) + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) + { + return path; + } + } + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs new file mode 100644 index 0000000000..938eae9983 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs @@ -0,0 +1,68 @@ +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.UnitTest +{ + public class UnixDomainSocketEndPointTests + { + [Fact] + public void UnixDomainSocketEndPoint_constructor_InvalidArgument() + { + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(null)); + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(string.Empty)); + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(new string('a', 100))); + } + + [Fact] + public void UnixDomainSocketEndPoint_constructor_Success() + { + var endpoint = new UnixDomainSocketEndPoint("abc"); + Assert.Equal("abc", endpoint.ToString()); + } + + [Fact] + public void UnixDomainSocketEndPoint_Create_InvalidArgument() + { + var endpoint = new UnixDomainSocketEndPoint("abc"); + Assert.Throws(() => _ = endpoint.Create(null)); + Assert.Throws(() => _ = endpoint.Create(this.CreateSocketAddress(new string('a', 100)))); + } + + [Fact] + public void UnixDomainSocketEndPoint_Create_Success() + { + var endpoint = new UnixDomainSocketEndPoint("abc"); + + var sa = new SocketAddress(AddressFamily.Unix, 2); // SocketAddress size is 2 + Assert.Equal(string.Empty, endpoint.Create(sa).ToString()); + + Assert.Equal("\0", endpoint.Create(this.CreateSocketAddress(string.Empty)).ToString()); + Assert.Equal("test\0", endpoint.Create(this.CreateSocketAddress("test")).ToString()); + } + + [Fact] + public void UnixDomainSocketEndPoint_Serialize() + { + var path = "abc"; + var endpoint = new UnixDomainSocketEndPoint(path); + Assert.Equal(this.CreateSocketAddress(path), endpoint.Serialize()); + } + + private SocketAddress CreateSocketAddress(string path) + { + int NativePathOffset = 2; + var nativePath = Encoding.UTF8.GetBytes(path); + var sa = new SocketAddress(AddressFamily.Unix, NativePathOffset + nativePath.Length + 1); + for (int i = 0; i < nativePath.Length; ++i) + { + sa[NativePathOffset + i] = nativePath[i]; + } + + sa[NativePathOffset + nativePath.Length] = 0; + return sa; + } + } +} From 99967016d9cb3a6d76a95cae1c270f2bed5c6687 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 13 Apr 2022 13:41:07 -0700 Subject: [PATCH 0067/1499] Add @cijothomas @utpilla as Geneva owners (#279) --- .github/component_owners.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 0686afaf8b..8c722ca288 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -5,6 +5,9 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn + src/OpenTelemetry.Exporter.Geneva/: + - cijothomas + - utpilla src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev src/OpenTelemetry.Extensions/: @@ -31,6 +34,15 @@ components: test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn + test/OpenTelemetry.Exporter.Geneva.Benchmark/: + - cijothomas + - utpilla + test/OpenTelemetry.Exporter.Geneva.Stress/: + - cijothomas + - utpilla + test/OpenTelemetry.Exporter.Geneva.Tests/: + - cijothomas + - utpilla test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: From 355a8fb9a844a861a9ed9f2d3c15d389472ce960 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 13 Apr 2022 16:32:31 -0700 Subject: [PATCH 0068/1499] Rename `Geneva.UnitTests` to `Geneva.Tests` (#278) * Rename Geneva `UnitTests` project to `Tests` * Change UnitTest to Tests namespaces * Update AssemblyInfo.cs * oops * Add linux filter to tests * Update windows-ci.yml Co-authored-by: Cijo Thomas --- .github/workflows/linux-ci.yml | 2 +- .github/workflows/windows-ci.yml | 2 +- opentelemetry-dotnet-contrib.sln | 3 ++- src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs | 2 +- .../ConnectionStringBuilderTests.cs | 2 +- .../GenevaLogExporterTests.cs | 2 +- .../GenevaMetricExporterOptionsTests.cs | 2 +- .../GenevaMetricExporterTests.cs | 4 ++-- .../GenevaTraceExporterTests.cs | 2 +- .../MessagePackSerializerTests.cs | 2 +- .../MetricsContract.cs | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj} | 0 .../UnixDomainSocketDataTransportTests.cs | 2 +- .../UnixDomainSocketEndPointTests.cs | 2 +- 14 files changed, 15 insertions(+), 14 deletions(-) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/ConnectionStringBuilderTests.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/GenevaLogExporterTests.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/GenevaMetricExporterOptionsTests.cs (97%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/GenevaMetricExporterTests.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/GenevaTraceExporterTests.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/MessagePackSerializerTests.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/MetricsContract.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj => OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj} (100%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/UnixDomainSocketDataTransportTests.cs (99%) rename test/{OpenTelemetry.Exporter.Geneva.UnitTest => OpenTelemetry.Exporter.Geneva.Tests}/UnixDomainSocketEndPointTests.cs (98%) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index f6d29654d2..5e5daa8812 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -28,4 +28,4 @@ jobs: run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" + run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" --filter "Platform=Any|Platform=Linux" diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index fbf928f758..3007e19d44 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -28,4 +28,4 @@ jobs: run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" + run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" --filter "Platform=Any|Platform=Windows" diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 069d9252dd..ec5bb67c99 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -175,7 +175,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Gene EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Stress", "test\OpenTelemetry.Exporter.Geneva.Stress\OpenTelemetry.Exporter.Geneva.Stress.csproj", "{F632DFB6-38AD-4356-8997-8CCC0492619C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.UnitTest", "test\OpenTelemetry.Exporter.Geneva.UnitTest\OpenTelemetry.Exporter.Geneva.UnitTest.csproj", "{A3EB4E60-256C-45EC-92EE-68FD035CAD11}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Tests", "test\OpenTelemetry.Exporter.Geneva.Tests\OpenTelemetry.Exporter.Geneva.Tests.csproj", "{A3EB4E60-256C-45EC-92EE-68FD035CAD11}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire", "src\OpenTelemetry.Instrumentation.Hangfire\OpenTelemetry.Instrumentation.Hangfire.csproj", "{BE5FFBBB-D73F-4071-92F4-F1694881604F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs index afc852f07f..ba5df94718 100644 --- a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -3,7 +3,7 @@ [assembly: CLSCompliant(false)] [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Benchmark" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.UnitTest" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Stress" + AssemblyInfo.PublicKey)] internal static class AssemblyInfo diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 6e9f374a8c..7345131794 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -1,7 +1,7 @@ using System; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class ConnectionStringBuilderTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index b6f59ca6fc..d002226cda 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -12,7 +12,7 @@ using OpenTelemetry.Logs; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class GenevaLogExporterTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs similarity index 97% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index e082213b6c..9eeab63586 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class GenevaMetricExporterOptionsTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 5ce768c930..f481c27af6 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -12,9 +12,9 @@ using OpenTelemetry.Metrics; using OpenTelemetry.Trace; using Xunit; -using static OpenTelemetry.Exporter.Geneva.UnitTest.MetricsContract; +using static OpenTelemetry.Exporter.Geneva.Tests.MetricsContract; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class GenevaMetricExporterTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 286b04323e..3e71beca89 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -11,7 +11,7 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class GenevaTraceExporterTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 7ee2f3f8a0..691eef3e33 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -4,7 +4,7 @@ using Xunit; using Xunit.Sdk; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class MessagePackSerializerTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs index eb813cdde1..c03dda9252 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/MetricsContract.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Kaitai; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public partial class MetricsContract : KaitaiStruct { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj similarity index 100% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/OpenTelemetry.Exporter.Geneva.UnitTest.csproj rename to test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 6a7cb34567..e0b554c499 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -4,7 +4,7 @@ using System.Reflection; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class UnixDomainSocketDataTransportTests { diff --git a/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs similarity index 98% rename from test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs rename to test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index 938eae9983..65044bf9de 100644 --- a/test/OpenTelemetry.Exporter.Geneva.UnitTest/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -4,7 +4,7 @@ using System.Text; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.UnitTest +namespace OpenTelemetry.Exporter.Geneva.Tests { public class UnixDomainSocketEndPointTests { From c9ec9fe60a87e7ac8862193913d6f10974e3da1f Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 13 Apr 2022 16:40:39 -0700 Subject: [PATCH 0069/1499] Update `Microsoft.CodeAnalysis.NetAnalyzers` to `6.0.0` (#285) Co-authored-by: Cijo Thomas --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index 275cfee36c..6445d4015f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -22,7 +22,7 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [2.4.0,3.0) - [5.0.3] + [6.0.0] [16.7.1] [2.1.0,5.0) [1.0.0,2.0) From 9dd87ccd97902115fabe50570f3fc6b976a50bb3 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 13 Apr 2022 16:50:10 -0700 Subject: [PATCH 0070/1499] Added area owners of Geneva Exporter source and test files. (#280) --- .github/component_owners.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 8c722ca288..256d608bbe 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -7,7 +7,11 @@ components: - lupengamzn src/OpenTelemetry.Exporter.Geneva/: - cijothomas + - codeblanch + - mic-max + - reyang - utpilla + - Yun-Ting src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev src/OpenTelemetry.Extensions/: @@ -36,13 +40,25 @@ components: - lupengamzn test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas + - codeblanch + - mic-max + - reyang - utpilla + - Yun-Ting test/OpenTelemetry.Exporter.Geneva.Stress/: - cijothomas + - codeblanch + - mic-max + - reyang - utpilla + - Yun-Ting test/OpenTelemetry.Exporter.Geneva.Tests/: - cijothomas + - codeblanch + - mic-max + - reyang - utpilla + - Yun-Ting test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: From c04cb3ea58fe51b0548ebbbb69ef6168869ff1b9 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 13 Apr 2022 17:19:57 -0700 Subject: [PATCH 0071/1499] GitHub action update bot (#290) --- .github/dependabot.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..2ac5ee6784 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + labels: + - "infra" From 20f74a3f422247269d5abe82e0b7b342f1540ff7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Apr 2022 17:55:04 -0700 Subject: [PATCH 0072/1499] Bump codecov/codecov-action from 1.0.12 to 3.0.0 (#292) --- .github/workflows/dotnet-core-cov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index cd37a3197f..f184d4ee74 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -43,7 +43,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - uses: codecov/codecov-action@v1.0.12 + - uses: codecov/codecov-action@v3.0.0 with: file: TestResults/Cobertura.xml env_vars: OS From b3850ae67d675c59145169cc0a86e8ff77b36bae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Apr 2022 19:05:32 -0700 Subject: [PATCH 0073/1499] Bump actions/checkout from 2 to 3 (#291) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cijo Thomas --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dotnet-core-cov.yml | 2 +- .github/workflows/dotnet-format.yml | 2 +- .github/workflows/linux-ci.yml | 2 +- .github/workflows/markdownlint.yml | 2 +- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWSXRay.yml | 2 +- .github/workflows/package-Extensions.PersistentStorage.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.MassTransit.yml | 2 +- .github/workflows/package-Instrumentation.MySqlData.yml | 2 +- .github/workflows/package-Instrumentation.Owin.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-Instrumentation.Runtime.yml | 2 +- .github/workflows/package-Instrumentation.Wcf.yml | 2 +- .github/workflows/package-Preview.yml | 2 +- .github/workflows/sanitycheck.yml | 4 ++-- .github/workflows/windows-ci.yml | 2 +- 22 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1753aefeb2..307766987b 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,7 +33,7 @@ jobs: disk-root: "D:" - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index f184d4ee74..bd30ca8327 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -22,7 +22,7 @@ jobs: OS: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index a546f81676..e91b387281 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -18,7 +18,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup .NET Core 6.0 uses: actions/setup-dotnet@v1 diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index 5e5daa8812..a58189cfac 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -19,7 +19,7 @@ jobs: version: [netcoreapp3.1,net5.0,net6.0] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 1e56c15478..97f85f9e2b 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -16,7 +16,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: install markdownlint-cli run: sudo npm install -g markdownlint-cli diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index b89615c73c..26626d69d3 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index 819cd72272..3f29a910bb 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index b4e461e23f..1493d37798 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index 8a2135bad1..b1b02bd15d 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 7603aef45b..c5f62f4f40 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 3bf92513b3..b96c44e34f 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index a2439768a9..926d5662da 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index a75a5aaefb..9e3191a184 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml index 4ddb344263..8042afe655 100644 --- a/.github/workflows/package-Instrumentation.MassTransit.yml +++ b/.github/workflows/package-Instrumentation.MassTransit.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index 04f48133bc..7518790449 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index 006c9e2d4b..9ddf64bc71 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index cbf69582a2..0b37340890 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index 66bc552ebf..104339d36d 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 7207b066a7..3e9c243d1d 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Preview.yml b/.github/workflows/package-Preview.yml index e91bf19097..42b8ca89d9 100644 --- a/.github/workflows/package-Preview.yml +++ b/.github/workflows/package-Preview.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 7de88aeb7f..a52563198e 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -12,7 +12,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: install misspell run: | @@ -27,7 +27,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: detect non-ASCII encoding and trailing space run: python3 ./build/sanitycheck.py diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 3007e19d44..b95be5f955 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -19,7 +19,7 @@ jobs: version: [net461,netcoreapp3.1,net5.0,net6.0] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: dotnet restore From 3f965ae3c5c0cd96cbb7e891f1e3fe719f193722 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Apr 2022 22:54:24 -0700 Subject: [PATCH 0074/1499] Bump actions/upload-artifact from 2 to 3 (#293) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cijo Thomas --- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWSXRay.yml | 2 +- .github/workflows/package-Extensions.PersistentStorage.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.MassTransit.yml | 2 +- .github/workflows/package-Instrumentation.MySqlData.yml | 2 +- .github/workflows/package-Instrumentation.Owin.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-Instrumentation.Runtime.yml | 2 +- .github/workflows/package-Instrumentation.Wcf.yml | 2 +- .github/workflows/package-Preview.yml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index 26626d69d3..a4e9301cfb 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index 3f29a910bb..a2042cde0f 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index 1493d37798..8ba7e43c75 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index b1b02bd15d..f557dcad9a 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index c5f62f4f40..4db19aac33 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index b96c44e34f..3249ff4b5f 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 926d5662da..68fe869ee6 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index 9e3191a184..b7cc235525 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml index 8042afe655..d187edab4d 100644 --- a/.github/workflows/package-Instrumentation.MassTransit.yml +++ b/.github/workflows/package-Instrumentation.MassTransit.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index 7518790449..dc530c5d04 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index 9ddf64bc71..c7a0a77886 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 0b37340890..0cc104987b 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index 104339d36d..ed86a1a268 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 3e9c243d1d..8830ce48bf 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Preview.yml b/.github/workflows/package-Preview.yml index 42b8ca89d9..aae505cb0a 100644 --- a/.github/workflows/package-Preview.yml +++ b/.github/workflows/package-Preview.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions has a conditional net5.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' From 74bcaad986adaab3410275ed9516833d12e7672c Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 14 Apr 2022 07:15:59 -0700 Subject: [PATCH 0075/1499] GenevaExporter - LogSerialization Fixes (#295) --- .../GenevaLogExporter.cs | 118 ++++++++---------- .../GenevaLogExporterTests.cs | 82 ++++++++---- 2 files changed, 109 insertions(+), 91 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 886a852438..3fe8ed502e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -181,22 +181,19 @@ internal bool IsUsingUnixDomainSocket internal int SerializeLogRecord(LogRecord logRecord) { - bool isUnstructuredLog = true; IReadOnlyList> listKvp; if (logRecord.State == null) { + // When State is null, OTel SDK guarantees StateValues is populated + // TODO: Debug.Assert? listKvp = logRecord.StateValues; } else { + // Attempt to see if State could be ROL_KVP. listKvp = logRecord.State as IReadOnlyList>; } - if (listKvp != null) - { - isUnstructuredLog = listKvp.Count == 1; - } - var name = logRecord.CategoryName; // If user configured explicit TableName, use it. @@ -325,81 +322,72 @@ internal int SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); cntFields += 1; - if (isUnstructuredLog) + bool hasEnvProperties = false; + bool bodyPopulated = false; + for (int i = 0; i < listKvp?.Count; i++) + { + var entry = listKvp[i]; + + // Iteration #1 - Get those fields which become dedicated columns + // i.e all Part B fields and opt-in Part C fields. + if (entry.Key == "{OriginalFormat}") + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); + cntFields += 1; + bodyPopulated = true; + continue; + } + else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + { + // TODO: the above null check can be optimized and avoided inside foreach. + if (entry.Value != null) + { + // null is not supported. + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + cntFields += 1; + } + } + else + { + hasEnvProperties = true; + continue; + } + } + + if (!bodyPopulated && logRecord.FormattedMessage != null) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? (listKvp != null ? Convert.ToString(listKvp[0].Value, CultureInfo.InvariantCulture) : Convert.ToString(logRecord.State, CultureInfo.InvariantCulture))); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage); cntFields += 1; } - else + + if (hasEnvProperties) { - bool hasEnvProperties = false; - bool bodyPopulated = false; + // Iteration #2 - Get all "other" fields and collapse them into single field + // named "env_properties". + ushort envPropertiesCount = 0; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int idxMapSizeEnvPropertiesPatch = cursor - 2; for (int i = 0; i < listKvp.Count; i++) { var entry = listKvp[i]; - - // Iteration #1 - Get those fields which become dedicated column - // i.e all PartB fields and opt-in part c fields. - if (entry.Key == "{OriginalFormat}") + if (entry.Key == "{OriginalFormat}" || this.m_customFields.ContainsKey(entry.Key)) { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); - cntFields += 1; - bodyPopulated = true; continue; } - else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) - { - // TODO: the above null check can be optimized and avoided inside foreach. - if (entry.Value != null) - { - // Geneva doesn't support null. - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); - cntFields += 1; - } - } else { - hasEnvProperties = true; - continue; + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + envPropertiesCount += 1; } } - if (!bodyPopulated && logRecord.FormattedMessage != null) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage); - cntFields += 1; - } - - if (hasEnvProperties) - { - // Iteration #2 - Get all "other" fields and collapse them into single field - // named "env_properties". - ushort envPropertiesCount = 0; - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int idxMapSizeEnvPropertiesPatch = cursor - 2; - for (int i = 0; i < listKvp.Count; i++) - { - var entry = listKvp[i]; - if (entry.Key == "{OriginalFormat}" || this.m_customFields.ContainsKey(entry.Key)) - { - continue; - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); - envPropertiesCount += 1; - } - } - - cntFields += 1; - MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); - } + cntFields += 1; + MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); } var eventId = logRecord.EventId; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index d002226cda..b2d7d4482f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -261,8 +261,15 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) _ = exporter.SerializeLogRecord(logRecordList[0]); object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var body = GetField(fluentdData, "body"); - string expectedBody = includeFormattedMessage ? "Formatted Message" : null; - Assert.Equal(expectedBody, body); + if (includeFormattedMessage) + { + Assert.Equal("Formatted Message", body); + } + else + { + Assert.Null(body); + } + Assert.Equal("Value1", GetField(fluentdData, "Key1")); Assert.Equal("Value2", GetField(fluentdData, "Key2")); @@ -284,8 +291,14 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); - expectedBody = includeFormattedMessage ? "Formatted Message" : "somestringasdata"; - Assert.Equal(expectedBody, body); + if (includeFormattedMessage) + { + Assert.Equal("Formatted Message", body); + } + else + { + Assert.Null(body); + } // ARRANGE logRecordList.Clear(); @@ -306,9 +319,42 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); - // Formatter is null, hence body is always the ToString() of the data - expectedBody = "somestringasdata"; - Assert.Equal(expectedBody, body); + // Formatter is null, hence body is always null + Assert.Null(body); + + // ARRANGE + logRecordList.Clear(); + + // ACT + // This is treated as Structured logging as the state can be converted to IReadOnlyList> + logger.Log( + logLevel: LogLevel.Information, + eventId: default, + new List>() + { + new KeyValuePair("Key1", "Value1"), + }, + exception: null, + formatter: (state, ex) => "Example formatted message."); + + // VALIDATE + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + Assert.Equal("Value1", GetField(fluentdData, "Key1")); + + body = GetField(fluentdData, "body"); + + // Only populate body if FormattedMessage is enabled + if (includeFormattedMessage) + { + Assert.Equal("Example formatted message.", body); + } + else + { + Assert.Null(body); + } } finally { @@ -333,7 +379,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) [InlineData(true, false, true)] [InlineData(true, true, true)] [Trait("Platform", "Any")] - public void SuccessfulSerialization(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) + public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) { string path = string.Empty; Socket server = null; @@ -427,29 +473,13 @@ public void SuccessfulSerialization(bool hasTableNameMapping, bool hasCustomFiel logger.Log(LogLevel.Error, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); logger.Log(LogLevel.Critical, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); logger.LogInformation("Hello World!"); // unstructured logging - - logger.Log(LogLevel.Information, default, "Hello World!", null, null); // unstructured logging using a non-extension method call - - // logging custom state - // This is treated as structured logging as the state can be converted to IReadOnlyList> - logger.Log( - LogLevel.Information, - default, - new List>() - { - new KeyValuePair("Key1", "Value1"), - new KeyValuePair("Key2", "Value2"), - }, - null, - (state, ex) => "Formatted Exception!"); - logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {food} {price}.", "artichoke", 3.99); var loggerWithDefaultCategory = loggerFactory.CreateLogger("DefaultCategory"); loggerWithDefaultCategory.LogInformation("Basic test"); - // logRecordList should have two logRecord entries after the logger.LogInformation calls - Assert.Equal(14, logRecordList.Count); + // logRecordList should have 12 logRecord entries as there were 12 Log calls + Assert.Equal(12, logRecordList.Count); var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; From 6992c28ab5abbedae0bf9b78a1c2db55aece4ad9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Apr 2022 07:30:57 -0700 Subject: [PATCH 0076/1499] Bump actions/setup-dotnet from 1 to 2 (#294) Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 2. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v1...v2) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cijo Thomas --- .github/workflows/dotnet-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index e91b387281..472fc5f686 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Setup .NET Core 6.0 - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v2 with: dotnet-version: 6.0.x From 5f434959657f28598ee3d48fabf7f78232068781 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 14 Apr 2022 09:21:29 -0700 Subject: [PATCH 0077/1499] GenevaExporter - changelog fix (#298) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 1512c42162..132346cb0c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -1,3 +1,14 @@ # Changelog ## Unreleased + +LogExporter modified to stop calling `ToString()` +on `LogRecord.State` to obtain Log body. It now +obtains body from `LogRecord.FormattedMessage` +or special casing "{OriginalFormat}" only. +[295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) + +Fixed a bug which causes LogExporter to not +serialize if the `LogRecord.State` had a +single KeyValuePair. +[295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) From 10ba52cb40520dc84986e7572e05a94008bf567d Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 12:00:39 -0700 Subject: [PATCH 0078/1499] Geneva license comments (#302) --- .../AssemblyInfo.cs | 18 +++++++++++++++++- .../ConnectionStringBuilder.cs | 18 +++++++++++++++++- .../EtwDataTransport.cs | 18 +++++++++++++++++- .../ExporterEventSource.cs | 18 +++++++++++++++++- .../GenevaBaseExporter.cs | 18 +++++++++++++++++- .../GenevaExporterHelperExtensions.cs | 18 +++++++++++++++++- .../GenevaExporterOptions.cs | 18 +++++++++++++++++- .../GenevaLogExporter.cs | 18 +++++++++++++++++- .../GenevaLoggingExtensions.cs | 18 +++++++++++++++++- .../GenevaMetricExporter.cs | 18 +++++++++++++++++- .../GenevaMetricExporterExtensions.cs | 18 +++++++++++++++++- .../GenevaMetricExporterOptions.cs | 18 +++++++++++++++++- .../GenevaTraceExporter.cs | 18 +++++++++++++++++- .../IDataTransport.cs | 18 +++++++++++++++++- .../IMetricDataTransport.cs | 18 +++++++++++++++++- .../MessagePackSerializer.cs | 18 +++++++++++++++++- .../MetricEtwDataTransport.cs | 18 +++++++++++++++++- .../MetricSerializer.cs | 18 +++++++++++++++++- .../MetricUnixDataTransport.cs | 18 +++++++++++++++++- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../ReentrantExportProcessor.cs | 18 +++++++++++++++++- src/OpenTelemetry.Exporter.Geneva/Schema.cs | 18 +++++++++++++++++- .../ServiceProviderExtensions.cs | 18 +++++++++++++++++- .../UnixDomainSocketDataTransport.cs | 18 +++++++++++++++++- .../UnixDomainSocketEndPoint.cs | 18 +++++++++++++++++- .../Exporter/LogExporterBenchmarks.cs | 18 +++++++++++++++++- .../Exporter/MetricExporterBenchmarks.cs | 18 +++++++++++++++++- .../Exporter/TraceExporterBenchmarks.cs | 18 +++++++++++++++++- ...nTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../Program.cs | 18 +++++++++++++++++- .../DummyServer.cs | 18 +++++++++++++++++- ...OpenTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../Program.cs | 18 +++++++++++++++++- .../ConnectionStringBuilderTests.cs | 18 +++++++++++++++++- .../GenevaLogExporterTests.cs | 18 +++++++++++++++++- .../GenevaMetricExporterOptionsTests.cs | 18 +++++++++++++++++- .../GenevaMetricExporterTests.cs | 18 +++++++++++++++++- .../GenevaTraceExporterTests.cs | 18 +++++++++++++++++- .../MessagePackSerializerTests.cs | 18 +++++++++++++++++- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../UnixDomainSocketDataTransportTests.cs | 18 +++++++++++++++++- .../UnixDomainSocketEndPointTests.cs | 18 +++++++++++++++++- 42 files changed, 650 insertions(+), 42 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs index ba5df94718..96c1fb823d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] diff --git a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs index 116294e313..26a23943ea 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Globalization; diff --git a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs index f72c7f3aac..d5360dfc39 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Diagnostics.Tracing; namespace OpenTelemetry.Exporter.Geneva diff --git a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs index ef7d349c4b..880e02dbb1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Diagnostics.Tracing; using System.Globalization; using System.Threading; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 2e3033e634..f8c19bcc6d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -1,4 +1,20 @@ -using System.Collections.Generic; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; namespace OpenTelemetry.Exporter.Geneva { diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 88d21c564c..1868c009c9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Diagnostics; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index b3bdb80781..b9c791905d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; namespace OpenTelemetry.Exporter.Geneva diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 3fe8ed502e..03d54f4a66 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -1,4 +1,20 @@ -#if NETSTANDARD2_0 || NET461 +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETSTANDARD2_0 || NET461 using System; using System.Collections.Generic; using System.Globalization; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index f0c7ee945b..d6eaeee7aa 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -1,4 +1,20 @@ -#if NETSTANDARD2_0 || NET461 +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETSTANDARD2_0 || NET461 using System; using OpenTelemetry; using OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index 09d8dc2243..836e3b7bbf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.InteropServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index dcf0df1bec..69612ae9d5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using OpenTelemetry.Metrics; namespace OpenTelemetry.Exporter.Geneva diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs index 81a629d3b0..50a6e0f272 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Globalization; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 1eff7967a5..f6f7f19b01 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs index 2fb314b332..4ffc2d98fb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs @@ -1,4 +1,20 @@ -namespace OpenTelemetry.Exporter.Geneva +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Geneva { internal interface IDataTransport { diff --git a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs index 09d84a21f8..8db60e5728 100644 --- a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; namespace OpenTelemetry.Exporter.Geneva { diff --git a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs index 6ab2bb6258..4896bd5096 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs index 2ba66e8e39..a75450221b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Diagnostics.Tracing; namespace OpenTelemetry.Exporter.Geneva diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs index 8beab0ea72..70326352cf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs index b4fc3b8ca1..2dac515e4e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs @@ -1,4 +1,20 @@ -namespace OpenTelemetry.Exporter.Geneva +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Geneva { internal sealed class MetricUnixDataTransport : IMetricDataTransport { diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 4843382572..50d3b29ff1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -4,7 +4,7 @@ true An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors - $(NoWarn),NU5104,CS1591,SA1123,SA1633,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 + $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 netstandard2.0 $(TargetFrameworks);net461 diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs index d95406a1df..8022d3dd91 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Linq.Expressions; using System.Reflection; diff --git a/src/OpenTelemetry.Exporter.Geneva/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Schema.cs index c641b8c32d..29eec11d07 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Schema.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Schema.cs @@ -1,4 +1,20 @@ -namespace OpenTelemetry.Exporter.Geneva +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Geneva { internal static class Schema { diff --git a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs index 47a2573c59..7cb285b5b2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs @@ -1,4 +1,20 @@ -#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER using Microsoft.Extensions.Options; #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs index 280cd4e3bc..0ae3c1963d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Net; using System.Net.Sockets; diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs index 7b317b7206..2694087fec 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Net; using System.Net.Sockets; using System.Text; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index c1548a6db0..0f31cdcf51 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index ee5395a1a6..4f9a27d771 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Metrics; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index 3c702182f5..51e25443bc 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics; using BenchmarkDotNet.Attributes; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 521c7b3e2f..2555bf258c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -4,7 +4,7 @@ Exe netcoreapp3.1;net5.0;net6.0 $(TargetFrameworks);net461;net462;net47;net471;net472;net48 - $(NoWarn),SA1633,SA1201,SA1202,SA1204,SA1311,SA1123 + $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs index 5ec54db965..390541c617 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs @@ -1,4 +1,20 @@ -using BenchmarkDotNet.Running; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using BenchmarkDotNet.Running; namespace OpenTelemetry.Exporter.Geneva.Benchmark { diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index 4af08fa4be..156c711670 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.IO; using System.Net; using System.Net.Sockets; diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 41d0d5fb88..08747551f0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -4,7 +4,7 @@ Exe netcoreapp3.1;net5.0;net6.0 $(TargetFrameworks);net461;net462;net47;net471;net472;net48 - $(NoWarn),SA1633,SA1308,SA1201 + $(NoWarn),SA1308,SA1201 diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index ee3e337ed3..ac92bd010c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 7345131794..059f7d5933 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index b2d7d4482f..ad2fa404b3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index 9eeab63586..7b8d52de63 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index f481c27af6..d58e12b3a2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Globalization; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 3e71beca89..8474dc2b21 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 691eef3e33..955c0b167c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Collections.Generic; using System.Text; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 372035fd34..fdf3968094 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -5,7 +5,7 @@ false netcoreapp3.1;net5.0;net6.0 $(TargetFrameworks);net461;net462;net47;net471;net472;net48 - $(NoWarn),SA1633,SA1311,SA1312,SA1313,SA1123,SA1202 + $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index e0b554c499..de8f559f4d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.IO; using System.Net.Sockets; using System.Reflection; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index 65044bf9de..b0c2f677e3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -1,4 +1,20 @@ -using System; +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; using System.Net; using System.Net.Sockets; using System.Text; From e19fe140230bccbd92e209b78ac1268d914f3f0b Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 14:11:54 -0700 Subject: [PATCH 0079/1499] Use `EnableAnalysis` in Geneva Exporter (#305) --- .../OpenTelemetry.Exporter.Geneva.csproj | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 50d3b29ff1..c58f88f706 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -7,16 +7,11 @@ $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 netstandard2.0 $(TargetFrameworks);net461 + true - - true - latest - AllEnabledByDefault - - From d8b8e4fd6741e11e42f6d13ced11514e505e9de7 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 15:00:18 -0700 Subject: [PATCH 0080/1499] Add and enable `publicApi` analysis (#306) --- .../.publicApi/net461/PublicAPI.Shipped.txt | 38 +++++++++++++++++++ .../.publicApi/net461/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 38 +++++++++++++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../OpenTelemetry.Exporter.Geneva.csproj | 1 + 5 files changed, 77 insertions(+) create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..be1421894a --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Shipped.txt @@ -0,0 +1,38 @@ +Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void +OpenTelemetry.Exporter.Geneva.GenevaLogExporter +OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..be1421894a --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,38 @@ +Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void +OpenTelemetry.Exporter.Geneva.GenevaLogExporter +OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index c58f88f706..b33663ebbf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -7,6 +7,7 @@ $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 netstandard2.0 $(TargetFrameworks);net461 + true true From c13437407ab06ea5b3a7790a8070c633d9a4f8a4 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 16:12:33 -0700 Subject: [PATCH 0081/1499] Geneva Exporter to use `OpenTelemetry 1.2.0-rc5` (#308) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 +++++-- .../GenevaMetricExporter.cs | 1 - .../GenevaMetricExporterExtensions.cs | 3 ++- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 16 ++++++++-------- .../GenevaMetricExporterTests.cs | 6 +++--- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 132346cb0c..15558c1018 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,13 +2,16 @@ ## Unreleased -LogExporter modified to stop calling `ToString()` +* LogExporter modified to stop calling `ToString()` on `LogRecord.State` to obtain Log body. It now obtains body from `LogRecord.FormattedMessage` or special casing "{OriginalFormat}" only. [295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) -Fixed a bug which causes LogExporter to not +* Fixed a bug which causes LogExporter to not serialize if the `LogRecord.State` had a single KeyValuePair. [295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) + +* Update OTel SDK version to `1.2.0-rc5`. +[308](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/308) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index 836e3b7bbf..b45a257b8f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -23,7 +23,6 @@ namespace OpenTelemetry.Exporter.Geneva { - [AggregationTemporality(AggregationTemporality.Delta)] public class GenevaMetricExporter : BaseExporter { private const int BufferSize = 65360; // the maximum ETW payload (inclusive) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index 69612ae9d5..f117702320 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -31,7 +31,8 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui var options = new GenevaMetricExporterOptions(); configure?.Invoke(options); - return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds)); + return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) + { TemporalityPreference = MetricReaderTemporalityPreference.Delta }); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index b33663ebbf..0f95e77d92 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -12,7 +12,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 4f9a27d771..5e1f72534f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -167,7 +167,7 @@ private MetricPoint GenerateCounterMetricItemWith3Dimensions(out MetricData metr var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -201,7 +201,7 @@ private MetricPoint GenerateCounterMetricItemWith4Dimensions(out MetricData metr var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -239,7 +239,7 @@ private Batch GenerateCounterBatchWith3Dimensions() var batchGeneratorExporter = new BatchGenerator(); var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; this.meterProviderForCounterBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() @@ -265,7 +265,7 @@ private Batch GenerateCounterBatchWith4Dimensions() var batchGeneratorExporter = new BatchGenerator(); var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; this.meterProviderForCounterBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() @@ -295,7 +295,7 @@ private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData su var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -332,7 +332,7 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData su var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -373,7 +373,7 @@ private Batch GenerateHistogramBatchWith3Dimensions() var batchGeneratorExporter = new BatchGenerator(); var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; this.meterProviderForHistogramBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() @@ -402,7 +402,7 @@ private Batch GenerateHistogramBatchWith4Dimensions() var batchGeneratorExporter = new BatchGenerator(); var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; this.meterProviderForHistogramBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index d58e12b3a2..66b965863a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -112,7 +112,7 @@ public void SuccessfulSerialization(bool testMaxLimits) var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -275,7 +275,7 @@ public void SuccessfulSerializationWithViews() var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -479,7 +479,7 @@ public void SuccessfulExportOnLinux() using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - Temporality = AggregationTemporality.Delta, + TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; // Set up two different providers as only one Metric Processor is allowed. From 829c72920fc309bce880d52801fd26fcaa52a187 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 16:24:29 -0700 Subject: [PATCH 0082/1499] Create package-Exporter.Geneva.yml (#304) --- .github/workflows/package-Exporter.Geneva.yml | 49 +++++++++++++++++++ .../OpenTelemetry.Exporter.Geneva.csproj | 1 + 2 files changed, 50 insertions(+) create mode 100644 .github/workflows/package-Exporter.Geneva.yml diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml new file mode 100644 index 0000000000..c768599ac0 --- /dev/null +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Exporter.Geneva + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Exporter.Geneva-*' # trigger when we create a tag with prefix "Exporter.Geneva-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Exporter.Geneva + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 0f95e77d92..ed6f827edf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -7,6 +7,7 @@ $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 netstandard2.0 $(TargetFrameworks);net461 + Exporter.Geneva- true true From 7e4c140e959b80d71cae175cba1de7ed64875769 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 19:11:36 -0700 Subject: [PATCH 0083/1499] File scope namespaces for Geneva Exporter (#303) --- build/Common.props | 2 +- .../ConnectionStringBuilder.cs | 289 +++--- .../EtwDataTransport.cs | 105 ++- .../ExporterEventSource.cs | 107 ++- .../GenevaBaseExporter.cs | 121 ++- .../GenevaExporterHelperExtensions.cs | 51 +- .../GenevaExporterOptions.cs | 83 +- .../GenevaLogExporter.cs | 675 +++++++------ .../GenevaLoggingExtensions.cs | 35 +- .../GenevaMetricExporter.cs | 741 ++++++++------- .../GenevaMetricExporterExtensions.cs | 24 +- .../GenevaMetricExporterOptions.cs | 83 +- .../GenevaTraceExporter.cs | 655 +++++++------ .../IDataTransport.cs | 11 +- .../IMetricDataTransport.cs | 27 +- .../MessagePackSerializer.cs | 883 +++++++++--------- .../MetricEtwDataTransport.cs | 61 +- .../MetricSerializer.cs | 521 ++++++----- .../MetricUnixDataTransport.cs | 53 +- .../ReentrantExportProcessor.cs | 51 +- src/OpenTelemetry.Exporter.Geneva/Schema.cs | 129 ++- .../ServiceProviderExtensions.cs | 33 +- .../UnixDomainSocketDataTransport.cs | 141 ++- .../UnixDomainSocketEndPoint.cs | 105 ++- 24 files changed, 2481 insertions(+), 2505 deletions(-) diff --git a/build/Common.props b/build/Common.props index 6445d4015f..4689562849 100644 --- a/build/Common.props +++ b/build/Common.props @@ -1,6 +1,6 @@ - 9.0 + 10.0 true $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) $(MSBuildThisFileDirectory)debug.snk diff --git a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs index 26a23943ea..d9dcb140a4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs @@ -18,211 +18,210 @@ using System.Collections.Generic; using System.Globalization; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal enum TransportProtocol { - internal enum TransportProtocol - { - Etw, - Tcp, - Udp, - Unix, - Unspecified, - } + Etw, + Tcp, + Udp, + Unix, + Unspecified, +} + +internal class ConnectionStringBuilder +{ + private readonly Dictionary _parts = new Dictionary(StringComparer.Ordinal); - internal class ConnectionStringBuilder + public ConnectionStringBuilder(string connectionString) { - private readonly Dictionary _parts = new Dictionary(StringComparer.Ordinal); + if (string.IsNullOrWhiteSpace(connectionString)) + { + throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); + } - public ConnectionStringBuilder(string connectionString) + const char Semicolon = ';'; + const char EqualSign = '='; + foreach (var token in connectionString.Split(Semicolon)) { - if (string.IsNullOrWhiteSpace(connectionString)) + if (string.IsNullOrWhiteSpace(token)) + { + continue; + } + + var index = token.IndexOf(EqualSign); + if (index == -1 || index != token.LastIndexOf(EqualSign)) + { + continue; + } + + var pair = token.Trim().Split(EqualSign); + + var key = pair[0].Trim(); + var value = pair[1].Trim(); + if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) { - throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); + throw new ArgumentException("Connection string cannot contain empty keys or values."); } - const char Semicolon = ';'; - const char EqualSign = '='; - foreach (var token in connectionString.Split(Semicolon)) + this._parts[key] = value; + } + + if (this._parts.Count == 0) + { + throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); + } + } + + public string EtwSession + { + get => this.ThrowIfNotExists(nameof(this.EtwSession)); + set => this._parts[nameof(this.EtwSession)] = value; + } + + public string Endpoint + { + get => this.ThrowIfNotExists(nameof(this.Endpoint)); + set => this._parts[nameof(this.Endpoint)] = value; + } + + public TransportProtocol Protocol + { + get + { + try { - if (string.IsNullOrWhiteSpace(token)) + // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux + if (this._parts.ContainsKey(nameof(this.EtwSession))) { - continue; + return TransportProtocol.Etw; } - var index = token.IndexOf(EqualSign); - if (index == -1 || index != token.LastIndexOf(EqualSign)) + if (!this._parts.ContainsKey(nameof(this.Endpoint))) { - continue; + return TransportProtocol.Unspecified; } - var pair = token.Trim().Split(EqualSign); - - var key = pair[0].Trim(); - var value = pair[1].Trim(); - if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) + var endpoint = new Uri(this.Endpoint); + if (Enum.TryParse(endpoint.Scheme, true, out TransportProtocol protocol)) { - throw new ArgumentException("Connection string cannot contain empty keys or values."); + return protocol; } - this._parts[key] = value; + throw new ArgumentException("Endpoint scheme is invalid."); } - - if (this._parts.Count == 0) + catch (UriFormatException ex) { - throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); } } + } - public string EtwSession + public string ParseUnixDomainSocketPath() + { + try { - get => this.ThrowIfNotExists(nameof(this.EtwSession)); - set => this._parts[nameof(this.EtwSession)] = value; + var endpoint = new Uri(this.Endpoint); + return endpoint.AbsolutePath; } - - public string Endpoint + catch (UriFormatException ex) { - get => this.ThrowIfNotExists(nameof(this.Endpoint)); - set => this._parts[nameof(this.Endpoint)] = value; + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); } + } - public TransportProtocol Protocol + public int TimeoutMilliseconds + { + get { - get + if (!this._parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string value)) { - try - { - // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux - if (this._parts.ContainsKey(nameof(this.EtwSession))) - { - return TransportProtocol.Etw; - } - - if (!this._parts.ContainsKey(nameof(this.Endpoint))) - { - return TransportProtocol.Unspecified; - } - - var endpoint = new Uri(this.Endpoint); - if (Enum.TryParse(endpoint.Scheme, true, out TransportProtocol protocol)) - { - return protocol; - } - - throw new ArgumentException("Endpoint scheme is invalid."); - } - catch (UriFormatException ex) + return UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds; + } + + try + { + int timeout = int.Parse(value, CultureInfo.InvariantCulture); + if (timeout <= 0) { - throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); + throw new ArgumentException( + $"{nameof(this.TimeoutMilliseconds)} should be greater than zero.", + nameof(this.TimeoutMilliseconds)); } + + return timeout; + } + catch (ArgumentException) + { + throw; + } + catch (Exception ex) + { + throw new ArgumentException( + $"{nameof(this.TimeoutMilliseconds)} is malformed.", + nameof(this.TimeoutMilliseconds), + ex); } } + set => this._parts[nameof(this.TimeoutMilliseconds)] = value.ToString(CultureInfo.InvariantCulture); + } - public string ParseUnixDomainSocketPath() + public string Host + { + get { try { var endpoint = new Uri(this.Endpoint); - return endpoint.AbsolutePath; + return endpoint.Host; } catch (UriFormatException ex) { throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); } } + } - public int TimeoutMilliseconds + public int Port + { + get { - get + try { - if (!this._parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string value)) + var endpoint = new Uri(this.Endpoint); + if (endpoint.IsDefaultPort) { - return UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds; + throw new ArgumentException($"Port should be explicitly set in {nameof(this.Endpoint)} value."); } - try - { - int timeout = int.Parse(value, CultureInfo.InvariantCulture); - if (timeout <= 0) - { - throw new ArgumentException( - $"{nameof(this.TimeoutMilliseconds)} should be greater than zero.", - nameof(this.TimeoutMilliseconds)); - } - - return timeout; - } - catch (ArgumentException) - { - throw; - } - catch (Exception ex) - { - throw new ArgumentException( - $"{nameof(this.TimeoutMilliseconds)} is malformed.", - nameof(this.TimeoutMilliseconds), - ex); - } + return endpoint.Port; } - set => this._parts[nameof(this.TimeoutMilliseconds)] = value.ToString(CultureInfo.InvariantCulture); - } - - public string Host - { - get + catch (UriFormatException ex) { - try - { - var endpoint = new Uri(this.Endpoint); - return endpoint.Host; - } - catch (UriFormatException ex) - { - throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); - } + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); } } + } - public int Port - { - get - { - try - { - var endpoint = new Uri(this.Endpoint); - if (endpoint.IsDefaultPort) - { - throw new ArgumentException($"Port should be explicitly set in {nameof(this.Endpoint)} value."); - } - - return endpoint.Port; - } - catch (UriFormatException ex) - { - throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); - } - } - } + public string Account + { + get => this.ThrowIfNotExists(nameof(this.Account)); + set => this._parts[nameof(this.Account)] = value; + } - public string Account - { - get => this.ThrowIfNotExists(nameof(this.Account)); - set => this._parts[nameof(this.Account)] = value; - } + public string Namespace + { + get => this.ThrowIfNotExists(nameof(this.Namespace)); + set => this._parts[nameof(this.Namespace)] = value; + } - public string Namespace + private T ThrowIfNotExists(string name) + { + if (!this._parts.TryGetValue(name, out var value)) { - get => this.ThrowIfNotExists(nameof(this.Namespace)); - set => this._parts[nameof(this.Namespace)] = value; + throw new ArgumentException($"'{name}' value is missing in connection string."); } - private T ThrowIfNotExists(string name) - { - if (!this._parts.TryGetValue(name, out var value)) - { - throw new ArgumentException($"'{name}' value is missing in connection string."); - } - - return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); - } + return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs index d5360dfc39..dd2dda94cf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs @@ -17,77 +17,76 @@ using System; using System.Diagnostics.Tracing; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +[EventSource(Name = "OpenTelemetry")] +internal class EtwEventSource : EventSource { - [EventSource(Name = "OpenTelemetry")] - internal class EtwEventSource : EventSource + public EtwEventSource(string providerName) + : base(providerName, EventSourceSettings.EtwManifestEventFormat) { - public EtwEventSource(string providerName) - : base(providerName, EventSourceSettings.EtwManifestEventFormat) - { - } + } - public enum EtwEventId - { - TraceEvent = 100, - } + public enum EtwEventId + { + TraceEvent = 100, + } - [Event((int)EtwEventId.TraceEvent, Version = 1, Level = EventLevel.Informational)] - public void InformationalEvent() - { - } + [Event((int)EtwEventId.TraceEvent, Version = 1, Level = EventLevel.Informational)] + public void InformationalEvent() + { + } - [NonEvent] - public unsafe void SendEvent(int eventId, byte[] data, int size) + [NonEvent] + public unsafe void SendEvent(int eventId, byte[] data, int size) + { + EventData* dataDesc = stackalloc EventData[1]; + fixed (byte* ptr = data) { - EventData* dataDesc = stackalloc EventData[1]; - fixed (byte* ptr = data) - { - dataDesc[0].DataPointer = (IntPtr)ptr; - dataDesc[0].Size = (int)size; - this.WriteEventCore(eventId, 1, dataDesc); - } + dataDesc[0].DataPointer = (IntPtr)ptr; + dataDesc[0].Size = (int)size; + this.WriteEventCore(eventId, 1, dataDesc); } } +} - internal class EtwDataTransport : IDataTransport, IDisposable +internal class EtwDataTransport : IDataTransport, IDisposable +{ + public EtwDataTransport(string providerName) { - public EtwDataTransport(string providerName) - { - this.m_eventSource = new EtwEventSource(providerName); - } + this.m_eventSource = new EtwEventSource(providerName); + } - public void Send(byte[] data, int size) - { - this.m_eventSource.SendEvent((int)EtwEventSource.EtwEventId.TraceEvent, data, size); - } + public void Send(byte[] data, int size) + { + this.m_eventSource.SendEvent((int)EtwEventSource.EtwEventId.TraceEvent, data, size); + } - public bool IsEnabled() - { - return this.m_eventSource.IsEnabled(); - } + public bool IsEnabled() + { + return this.m_eventSource.IsEnabled(); + } + + private EtwEventSource m_eventSource; + private bool m_disposed; - private EtwEventSource m_eventSource; - private bool m_disposed; + public void Dispose() + { + this.Dispose(true); + } - public void Dispose() + protected virtual void Dispose(bool disposing) + { + if (this.m_disposed) { - this.Dispose(true); + return; } - protected virtual void Dispose(bool disposing) + if (disposing) { - if (this.m_disposed) - { - return; - } - - if (disposing) - { - this.m_eventSource.Dispose(); - } - - this.m_disposed = true; + this.m_eventSource.Dispose(); } + + this.m_disposed = true; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs index 880e02dbb1..a948859405 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs @@ -19,72 +19,71 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +[EventSource(Name = "OpenTelemetry-Exporter-Geneva")] +internal class ExporterEventSource : EventSource { - [EventSource(Name = "OpenTelemetry-Exporter-Geneva")] - internal class ExporterEventSource : EventSource - { - public static readonly ExporterEventSource Log = new ExporterEventSource(); - private const int EVENT_ID_TRACE = 1; - private const int EVENT_ID_METRICS = 2; - private const int EVENT_ID_ERROR = 3; + public static readonly ExporterEventSource Log = new ExporterEventSource(); + private const int EVENT_ID_TRACE = 1; + private const int EVENT_ID_METRICS = 2; + private const int EVENT_ID_ERROR = 3; - [NonEvent] - public void ExporterException(Exception ex) + [NonEvent] + public void ExporterException(Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.FailedToSendSpanData(ToInvariantString(ex)); - } + this.FailedToSendSpanData(ToInvariantString(ex)); } + } - [Event(EVENT_ID_TRACE, Message = "Exporter failed to send SpanData. Data will not be sent. Exception: {0}", Level = EventLevel.Error)] - public void FailedToSendSpanData(string ex) - { - // https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing - // ETW has a size limit: The total event size is greater than 64K. This includes the ETW header plus the data or payload. - // TODO: Do not hit ETW size limit even for external library exception stack. But what is the ETW header size? - // Source code: https://referencesource.microsoft.com/#mscorlib/system/diagnostics/eventing/eventsource.cs,867 - // Why is size calculated like below in WriteEvent source code? - // descrs[0].Size = ((arg1.Length + 1) * 2); - // I'm assuming it calculates the size of string, then it should be: - // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). - this.WriteEvent(EVENT_ID_TRACE, ex); - } + [Event(EVENT_ID_TRACE, Message = "Exporter failed to send SpanData. Data will not be sent. Exception: {0}", Level = EventLevel.Error)] + public void FailedToSendSpanData(string ex) + { + // https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing + // ETW has a size limit: The total event size is greater than 64K. This includes the ETW header plus the data or payload. + // TODO: Do not hit ETW size limit even for external library exception stack. But what is the ETW header size? + // Source code: https://referencesource.microsoft.com/#mscorlib/system/diagnostics/eventing/eventsource.cs,867 + // Why is size calculated like below in WriteEvent source code? + // descrs[0].Size = ((arg1.Length + 1) * 2); + // I'm assuming it calculates the size of string, then it should be: + // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). + this.WriteEvent(EVENT_ID_TRACE, ex); + } - [Event(EVENT_ID_METRICS, Message = "Exporter failed to send MetricData. Data will not be sent. MetricNamespace = {0}, MetricName = {1}, Message: {2}", Level = EventLevel.Error)] - public void FailedToSendMetricData(string metricNamespace, string metricName, string message) + [Event(EVENT_ID_METRICS, Message = "Exporter failed to send MetricData. Data will not be sent. MetricNamespace = {0}, MetricName = {1}, Message: {2}", Level = EventLevel.Error)] + public void FailedToSendMetricData(string metricNamespace, string metricName, string message) + { + this.WriteEvent(EVENT_ID_METRICS, metricNamespace, metricName, message); + } + + [Event(EVENT_ID_ERROR, Message = "Exporter failed.", Level = EventLevel.Error)] + public void ExporterError(string message) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.WriteEvent(EVENT_ID_METRICS, metricNamespace, metricName, message); + // TODO: We should ensure that GenevaTraceExporter doesn't emit any message that could hit ETW size limit. + this.WriteEvent(EVENT_ID_ERROR, message); } + } - [Event(EVENT_ID_ERROR, Message = "Exporter failed.", Level = EventLevel.Error)] - public void ExporterError(string message) + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - // TODO: We should ensure that GenevaTraceExporter doesn't emit any message that could hit ETW size limit. - this.WriteEvent(EVENT_ID_ERROR, message); - } + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index f8c19bcc6d..7132e31a62 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -16,78 +16,77 @@ using System.Collections.Generic; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public abstract class GenevaBaseExporter : BaseExporter +where T : class { - public abstract class GenevaBaseExporter : BaseExporter - where T : class + internal static readonly IReadOnlyDictionary V21_PART_A_MAPPING = new Dictionary { - internal static readonly IReadOnlyDictionary V21_PART_A_MAPPING = new Dictionary - { - // Part A - [Schema.V21.PartA.IKey] = "env_iKey", - [Schema.V21.PartA.Name] = "env_name", - [Schema.V21.PartA.Ver] = "env_ver", - [Schema.V21.PartA.Time] = "env_time", - [Schema.V21.PartA.Cv] = "env_cv", - [Schema.V21.PartA.Epoch] = "env_epoch", - [Schema.V21.PartA.Flags] = "env_flags", - [Schema.V21.PartA.PopSample] = "env_popSample", - [Schema.V21.PartA.SeqNum] = "env_seqNum", + // Part A + [Schema.V21.PartA.IKey] = "env_iKey", + [Schema.V21.PartA.Name] = "env_name", + [Schema.V21.PartA.Ver] = "env_ver", + [Schema.V21.PartA.Time] = "env_time", + [Schema.V21.PartA.Cv] = "env_cv", + [Schema.V21.PartA.Epoch] = "env_epoch", + [Schema.V21.PartA.Flags] = "env_flags", + [Schema.V21.PartA.PopSample] = "env_popSample", + [Schema.V21.PartA.SeqNum] = "env_seqNum", - // Part A Application extension - [Schema.V21.PartA.Extensions.App.Id] = "env_appId", - [Schema.V21.PartA.Extensions.App.Ver] = "env_appVer", + // Part A Application extension + [Schema.V21.PartA.Extensions.App.Id] = "env_appId", + [Schema.V21.PartA.Extensions.App.Ver] = "env_appVer", - // Part A Cloud extension - [Schema.V21.PartA.Extensions.Cloud.Environment] = "env_cloud_environment", - [Schema.V21.PartA.Extensions.Cloud.Location] = "env_cloud_location", - [Schema.V21.PartA.Extensions.Cloud.Name] = "env_cloud_name", - [Schema.V21.PartA.Extensions.Cloud.DeploymentUnit] = "env_cloud_deploymentUnit", - [Schema.V21.PartA.Extensions.Cloud.Role] = "env_cloud_role", - [Schema.V21.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", - [Schema.V21.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", - [Schema.V21.PartA.Extensions.Cloud.Ver] = "env_cloud_ver", + // Part A Cloud extension + [Schema.V21.PartA.Extensions.Cloud.Environment] = "env_cloud_environment", + [Schema.V21.PartA.Extensions.Cloud.Location] = "env_cloud_location", + [Schema.V21.PartA.Extensions.Cloud.Name] = "env_cloud_name", + [Schema.V21.PartA.Extensions.Cloud.DeploymentUnit] = "env_cloud_deploymentUnit", + [Schema.V21.PartA.Extensions.Cloud.Role] = "env_cloud_role", + [Schema.V21.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", + [Schema.V21.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", + [Schema.V21.PartA.Extensions.Cloud.Ver] = "env_cloud_ver", - // Part A Os extension - [Schema.V21.PartA.Extensions.Os.Name] = "env_os", - [Schema.V21.PartA.Extensions.Os.Ver] = "env_osVer", - }; + // Part A Os extension + [Schema.V21.PartA.Extensions.Os.Name] = "env_os", + [Schema.V21.PartA.Extensions.Os.Ver] = "env_osVer", + }; - internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = new Dictionary - { - // Part A - [Schema.V40.PartA.IKey] = "env_iKey", - [Schema.V40.PartA.Name] = "env_name", - [Schema.V40.PartA.Ver] = "env_ver", - [Schema.V40.PartA.Time] = "env_time", + internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = new Dictionary + { + // Part A + [Schema.V40.PartA.IKey] = "env_iKey", + [Schema.V40.PartA.Name] = "env_name", + [Schema.V40.PartA.Ver] = "env_ver", + [Schema.V40.PartA.Time] = "env_time", - // Part A Application Extension - [Schema.V40.PartA.Extensions.App.Id] = "env_app_id", - [Schema.V40.PartA.Extensions.App.Ver] = "env_app_ver", + // Part A Application Extension + [Schema.V40.PartA.Extensions.App.Id] = "env_app_id", + [Schema.V40.PartA.Extensions.App.Ver] = "env_app_ver", - // Part A Cloud Extension - [Schema.V40.PartA.Extensions.Cloud.Role] = "env_cloud_role", - [Schema.V40.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", - [Schema.V40.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", + // Part A Cloud Extension + [Schema.V40.PartA.Extensions.Cloud.Role] = "env_cloud_role", + [Schema.V40.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", + [Schema.V40.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", - // Part A Os extension - [Schema.V40.PartA.Extensions.Os.Name] = "env_os_name", - [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", - }; + // Part A Os extension + [Schema.V40.PartA.Extensions.Os.Name] = "env_os_name", + [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", + }; - internal static int AddPartAField(byte[] buffer, int cursor, string name, object value) + internal static int AddPartAField(byte[] buffer, int cursor, string name, object value) + { + if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) { - if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); - } - - cursor = MessagePackSerializer.Serialize(buffer, cursor, value); - return cursor; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); } + + cursor = MessagePackSerializer.Serialize(buffer, cursor, value); + return cursor; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 1868c009c9..3d4cdedbcb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -18,40 +18,39 @@ using System.Diagnostics; using OpenTelemetry.Trace; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public static class GenevaExporterHelperExtensions { - public static class GenevaExporterHelperExtensions + public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) { - public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) + if (builder == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + throw new ArgumentNullException(nameof(builder)); + } - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + return deferredTracerProviderBuilder.Configure((sp, builder) => { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddGenevaTraceExporter(builder, sp.GetOptions(), configure); - }); - } - - return AddGenevaTraceExporter(builder, new GenevaExporterOptions(), configure); + AddGenevaTraceExporter(builder, sp.GetOptions(), configure); + }); } - private static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, GenevaExporterOptions options, Action configure) + return AddGenevaTraceExporter(builder, new GenevaExporterOptions(), configure); + } + + private static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, GenevaExporterOptions options, Action configure) + { + configure?.Invoke(options); + var exporter = new GenevaTraceExporter(options); + if (exporter.IsUsingUnixDomainSocket) { - configure?.Invoke(options); - var exporter = new GenevaTraceExporter(options); - if (exporter.IsUsingUnixDomainSocket) - { - return builder.AddProcessor(new BatchActivityExportProcessor(exporter)); - } - else - { - return builder.AddProcessor(new ReentrantExportProcessor(exporter)); - } + return builder.AddProcessor(new BatchActivityExportProcessor(exporter)); + } + else + { + return builder.AddProcessor(new ReentrantExportProcessor(exporter)); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index b9c791905d..ebeee33921 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -17,63 +17,62 @@ using System; using System.Collections.Generic; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaExporterOptions { - public class GenevaExporterOptions + private IReadOnlyDictionary _fields = new Dictionary(1) { - private IReadOnlyDictionary _fields = new Dictionary(1) - { - [Schema.V40.PartA.Ver] = "4.0", - }; + [Schema.V40.PartA.Ver] = "4.0", + }; - public string ConnectionString { get; set; } + public string ConnectionString { get; set; } - public IEnumerable CustomFields { get; set; } + public IEnumerable CustomFields { get; set; } - public IReadOnlyDictionary TableNameMappings { get; set; } + public IReadOnlyDictionary TableNameMappings { get; set; } - public IReadOnlyDictionary PrepopulatedFields + public IReadOnlyDictionary PrepopulatedFields + { + get => this._fields; + set { - get => this._fields; - set + if (value == null) { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - var schemaVersion = "4.0"; + throw new ArgumentNullException(nameof(value)); + } - if (value.ContainsKey(Schema.V40.PartA.Ver)) - { - schemaVersion = value[Schema.V40.PartA.Ver] as string; - } + var schemaVersion = "4.0"; - if (schemaVersion != "2.1" && schemaVersion != "4.0") - { - throw new ArgumentException("Unsupported schema version, only 2.1 and 4.0 are supported."); - } + if (value.ContainsKey(Schema.V40.PartA.Ver)) + { + schemaVersion = value[Schema.V40.PartA.Ver] as string; + } - if (value.ContainsKey(Schema.V40.PartA.Name)) - { - throw new ArgumentException("Event name cannot be pre-populated."); - } + if (schemaVersion != "2.1" && schemaVersion != "4.0") + { + throw new ArgumentException("Unsupported schema version, only 2.1 and 4.0 are supported."); + } - if (value.ContainsKey(Schema.V40.PartA.Time)) - { - throw new ArgumentException("Event timestamp cannot be pre-populated."); - } + if (value.ContainsKey(Schema.V40.PartA.Name)) + { + throw new ArgumentException("Event name cannot be pre-populated."); + } - var copy = new Dictionary(value.Count + 1) { [Schema.V40.PartA.Ver] = schemaVersion }; - foreach (var entry in value) - { - copy[entry.Key] = entry.Value; // shallow copy - } + if (value.ContainsKey(Schema.V40.PartA.Time)) + { + throw new ArgumentException("Event timestamp cannot be pre-populated."); + } - this._fields = copy; + var copy = new Dictionary(value.Count + 1) { [Schema.V40.PartA.Ver] = schemaVersion }; + foreach (var entry in value) + { + copy[entry.Key] = entry.Value; // shallow copy } - } - internal Func ConvertToJson = obj => "ERROR: GenevaExporterOptions.ConvertToJson not configured."; + this._fields = copy; + } } + + internal Func ConvertToJson = obj => "ERROR: GenevaExporterOptions.ConvertToJson not configured."; } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 03d54f4a66..1123c7fdbc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -25,429 +25,428 @@ using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaLogExporter : GenevaBaseExporter { - public class GenevaLogExporter : GenevaBaseExporter + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + + private readonly IReadOnlyDictionary m_customFields; + private readonly string m_defaultEventName = "Log"; + private readonly IReadOnlyDictionary m_prepopulatedFields; + private readonly List m_prepopulatedFieldKeys; + private static readonly ThreadLocal m_buffer = new ThreadLocal(() => null); + private readonly byte[] m_bufferEpilogue; + private static readonly string[] logLevels = new string[7] { - private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - - private readonly IReadOnlyDictionary m_customFields; - private readonly string m_defaultEventName = "Log"; - private readonly IReadOnlyDictionary m_prepopulatedFields; - private readonly List m_prepopulatedFieldKeys; - private static readonly ThreadLocal m_buffer = new ThreadLocal(() => null); - private readonly byte[] m_bufferEpilogue; - private static readonly string[] logLevels = new string[7] - { - "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", - }; + "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", + }; - private readonly IDataTransport m_dataTransport; - private bool isDisposed; - private Func convertToJson; + private readonly IDataTransport m_dataTransport; + private bool isDisposed; + private Func convertToJson; - public GenevaLogExporter(GenevaExporterOptions options) + public GenevaLogExporter(GenevaExporterOptions options) + { + if (options == null) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + throw new ArgumentNullException(nameof(options)); + } - if (string.IsNullOrWhiteSpace(options.ConnectionString)) - { - throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); - } + if (string.IsNullOrWhiteSpace(options.ConnectionString)) + { + throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); + } - // TODO: Validate mappings for reserved tablenames etc. - if (options.TableNameMappings != null) + // TODO: Validate mappings for reserved tablenames etc. + if (options.TableNameMappings != null) + { + var tempTableMappings = new Dictionary(options.TableNameMappings.Count, StringComparer.Ordinal); + foreach (var kv in options.TableNameMappings) { - var tempTableMappings = new Dictionary(options.TableNameMappings.Count, StringComparer.Ordinal); - foreach (var kv in options.TableNameMappings) + if (Encoding.UTF8.GetByteCount(kv.Value) != kv.Value.Length) { - if (Encoding.UTF8.GetByteCount(kv.Value) != kv.Value.Length) - { - throw new ArgumentException("The value: \"{tableName}\" provided for TableNameMappings option contains non-ASCII characters", kv.Value); - } - - if (kv.Key == "*") - { - this.m_defaultEventName = kv.Value; - } - else - { - tempTableMappings[kv.Key] = kv.Value; - } + throw new ArgumentException("The value: \"{tableName}\" provided for TableNameMappings option contains non-ASCII characters", kv.Value); } - this.m_tableMappings = tempTableMappings; - } - - var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - switch (connectionStringBuilder.Protocol) - { - case TransportProtocol.Etw: - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); - } - - this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); - break; - case TransportProtocol.Unix: - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new ArgumentException("Unix domain socket should not be used on Windows."); - } - - var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); - break; - case TransportProtocol.Tcp: - throw new ArgumentException("TCP transport is not supported yet."); - case TransportProtocol.Udp: - throw new ArgumentException("UDP transport is not supported yet."); - default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); - } - - this.convertToJson = options.ConvertToJson; - - if (options.PrepopulatedFields != null) - { - this.m_prepopulatedFieldKeys = new List(); - var tempPrepopulatedFields = new Dictionary(options.PrepopulatedFields.Count, StringComparer.Ordinal); - foreach (var kv in options.PrepopulatedFields) + if (kv.Key == "*") { - tempPrepopulatedFields[kv.Key] = kv.Value; - this.m_prepopulatedFieldKeys.Add(kv.Key); + this.m_defaultEventName = kv.Value; } - - this.m_prepopulatedFields = tempPrepopulatedFields; - } - - // TODO: Validate custom fields (reserved name? etc). - if (options.CustomFields != null) - { - var customFields = new Dictionary(StringComparer.Ordinal); - foreach (var name in options.CustomFields) + else { - customFields[name] = true; + tempTableMappings[kv.Key] = kv.Value; } - - this.m_customFields = customFields; } - var buffer = new byte[BUFFER_SIZE]; - var cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); - this.m_bufferEpilogue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + this.m_tableMappings = tempTableMappings; } - private readonly IReadOnlyDictionary m_tableMappings; - - public override ExportResult Export(in Batch batch) + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + switch (connectionStringBuilder.Protocol) { - var result = ExportResult.Success; - foreach (var logRecord in batch) - { - try + case TransportProtocol.Etw: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var cursor = this.SerializeLogRecord(logRecord); - this.m_dataTransport.Send(m_buffer.Value, cursor - 0); + throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); } - catch (Exception ex) + + this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); + break; + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception - result = ExportResult.Failure; + throw new ArgumentException("Unix domain socket should not be used on Windows."); } - } - return result; + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Tcp: + throw new ArgumentException("TCP transport is not supported yet."); + case TransportProtocol.Udp: + throw new ArgumentException("UDP transport is not supported yet."); + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); } - protected override void Dispose(bool disposing) + this.convertToJson = options.ConvertToJson; + + if (options.PrepopulatedFields != null) { - if (this.isDisposed) + this.m_prepopulatedFieldKeys = new List(); + var tempPrepopulatedFields = new Dictionary(options.PrepopulatedFields.Count, StringComparer.Ordinal); + foreach (var kv in options.PrepopulatedFields) { - return; + tempPrepopulatedFields[kv.Key] = kv.Value; + this.m_prepopulatedFieldKeys.Add(kv.Key); } - if (disposing) + this.m_prepopulatedFields = tempPrepopulatedFields; + } + + // TODO: Validate custom fields (reserved name? etc). + if (options.CustomFields != null) + { + var customFields = new Dictionary(StringComparer.Ordinal); + foreach (var name in options.CustomFields) { - // DO NOT Dispose m_buffer as it is a static type - try - { - (this.m_dataTransport as IDisposable)?.Dispose(); - this.m_prepopulatedFieldKeys.Clear(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException(ex); - } + customFields[name] = true; } - this.isDisposed = true; - base.Dispose(disposing); + this.m_customFields = customFields; } - internal bool IsUsingUnixDomainSocket - { - get => this.m_dataTransport is UnixDomainSocketDataTransport; - } + var buffer = new byte[BUFFER_SIZE]; + var cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); + this.m_bufferEpilogue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + } + + private readonly IReadOnlyDictionary m_tableMappings; - internal int SerializeLogRecord(LogRecord logRecord) + public override ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + foreach (var logRecord in batch) { - IReadOnlyList> listKvp; - if (logRecord.State == null) + try { - // When State is null, OTel SDK guarantees StateValues is populated - // TODO: Debug.Assert? - listKvp = logRecord.StateValues; + var cursor = this.SerializeLogRecord(logRecord); + this.m_dataTransport.Send(m_buffer.Value, cursor - 0); } - else + catch (Exception ex) { - // Attempt to see if State could be ROL_KVP. - listKvp = logRecord.State as IReadOnlyList>; + ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; } + } - var name = logRecord.CategoryName; + return result; + } - // If user configured explicit TableName, use it. - if (this.m_tableMappings == null || !this.m_tableMappings.TryGetValue(name, out var eventName)) - { - eventName = this.m_defaultEventName; - } + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } - var buffer = m_buffer.Value; - if (buffer == null) + if (disposing) + { + // DO NOT Dispose m_buffer as it is a static type + try { - buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM - m_buffer.Value = buffer; + (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_prepopulatedFieldKeys.Clear(); } - - /* Fluentd Forward Mode: - [ - "Log", - [ - [ , { "env_ver": "4.0", ... } ] - ], - { "TimeFormat": "DateTime" } - ] - */ - - // Structured log. - // 2 scenarios. - // 1. Structured logging with template - // eg: - // body - // "Hello from {food} {price}." - // part c - // food = onion - // price = 100 - // TODO: 2. Structured with strongly typed logging. - var timestamp = logRecord.Timestamp; - var cursor = 0; - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); - cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, timestamp); - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration - ushort cntFields = 0; - var idxMapSizePatch = cursor - 2; - - if (this.m_prepopulatedFieldKeys != null) + catch (Exception ex) { - for (int i = 0; i < this.m_prepopulatedFieldKeys.Count; i++) - { - var key = this.m_prepopulatedFieldKeys[i]; - var value = this.m_prepopulatedFields[key]; - switch (value) - { - case bool vb: - case byte vui8: - case sbyte vi8: - case short vi16: - case ushort vui16: - case int vi32: - case uint vui32: - case long vi64: - case ulong vui64: - case float vf: - case double vd: - case string vs: - break; - default: - value = this.convertToJson(value); - break; - } - - cursor = AddPartAField(buffer, cursor, key, value); - cntFields += 1; - } + ExporterEventSource.Log.ExporterException(ex); } + } - // Part A - core envelope - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); - cntFields += 1; + this.isDisposed = true; + base.Dispose(disposing); + } - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Time, timestamp); - cntFields += 1; + internal bool IsUsingUnixDomainSocket + { + get => this.m_dataTransport is UnixDomainSocketDataTransport; + } - // Part A - dt extension - if (logRecord.TraceId != default) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_traceId"); + internal int SerializeLogRecord(LogRecord logRecord) + { + IReadOnlyList> listKvp; + if (logRecord.State == null) + { + // When State is null, OTel SDK guarantees StateValues is populated + // TODO: Debug.Assert? + listKvp = logRecord.StateValues; + } + else + { + // Attempt to see if State could be ROL_KVP. + listKvp = logRecord.State as IReadOnlyList>; + } - // Note: ToHexString returns the pre-calculated hex representation without allocation - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.TraceId.ToHexString()); - cntFields += 1; - } + var name = logRecord.CategoryName; - if (logRecord.SpanId != default) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_spanId"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.SpanId.ToHexString()); - cntFields += 1; - } + // If user configured explicit TableName, use it. + if (this.m_tableMappings == null || !this.m_tableMappings.TryGetValue(name, out var eventName)) + { + eventName = this.m_defaultEventName; + } - // Part A - ex extension - if (logRecord.Exception != null) + var buffer = m_buffer.Value; + if (buffer == null) + { + buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM + m_buffer.Value = buffer; + } + + /* Fluentd Forward Mode: + [ + "Log", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + // Structured log. + // 2 scenarios. + // 1. Structured logging with template + // eg: + // body + // "Hello from {food} {price}." + // part c + // food = onion + // price = 100 + // TODO: 2. Structured with strongly typed logging. + var timestamp = logRecord.Timestamp; + var cursor = 0; + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, timestamp); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration + ushort cntFields = 0; + var idxMapSizePatch = cursor - 2; + + if (this.m_prepopulatedFieldKeys != null) + { + for (int i = 0; i < this.m_prepopulatedFieldKeys.Count; i++) { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_type"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.Exception.GetType().FullName); - cntFields += 1; + var key = this.m_prepopulatedFieldKeys[i]; + var value = this.m_prepopulatedFields[key]; + switch (value) + { + case bool vb: + case byte vui8: + case sbyte vi8: + case short vi16: + case ushort vui16: + case int vi32: + case uint vui32: + case long vi64: + case ulong vui64: + case float vf: + case double vd: + case string vs: + break; + default: + value = this.convertToJson(value); + break; + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_msg"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); + cursor = AddPartAField(buffer, cursor, key, value); cntFields += 1; } + } + + // Part A - core envelope + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + cntFields += 1; - // Part B - var logLevel = logRecord.LogLevel; + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Time, timestamp); + cntFields += 1; - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityText"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logLevels[(int)logLevel]); + // Part A - dt extension + if (logRecord.TraceId != default) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_traceId"); + + // Note: ToHexString returns the pre-calculated hex representation without allocation + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.TraceId.ToHexString()); cntFields += 1; + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityNumber"); - cursor = MessagePackSerializer.SerializeUInt8(buffer, cursor, GetSeverityNumber(logLevel)); + if (logRecord.SpanId != default) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_spanId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.SpanId.ToHexString()); cntFields += 1; + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + // Part A - ex extension + if (logRecord.Exception != null) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_type"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.Exception.GetType().FullName); cntFields += 1; - bool hasEnvProperties = false; - bool bodyPopulated = false; - for (int i = 0; i < listKvp?.Count; i++) - { - var entry = listKvp[i]; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_msg"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); + cntFields += 1; + } - // Iteration #1 - Get those fields which become dedicated columns - // i.e all Part B fields and opt-in Part C fields. - if (entry.Key == "{OriginalFormat}") - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); - cntFields += 1; - bodyPopulated = true; - continue; - } - else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) - { - // TODO: the above null check can be optimized and avoided inside foreach. - if (entry.Value != null) - { - // null is not supported. - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); - cntFields += 1; - } - } - else - { - hasEnvProperties = true; - continue; - } - } + // Part B + var logLevel = logRecord.LogLevel; - if (!bodyPopulated && logRecord.FormattedMessage != null) + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityText"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logLevels[(int)logLevel]); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityNumber"); + cursor = MessagePackSerializer.SerializeUInt8(buffer, cursor, GetSeverityNumber(logLevel)); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + cntFields += 1; + + bool hasEnvProperties = false; + bool bodyPopulated = false; + for (int i = 0; i < listKvp?.Count; i++) + { + var entry = listKvp[i]; + + // Iteration #1 - Get those fields which become dedicated columns + // i.e all Part B fields and opt-in Part C fields. + if (entry.Key == "{OriginalFormat}") { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); cntFields += 1; + bodyPopulated = true; + continue; } - - if (hasEnvProperties) + else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) { - // Iteration #2 - Get all "other" fields and collapse them into single field - // named "env_properties". - ushort envPropertiesCount = 0; - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int idxMapSizeEnvPropertiesPatch = cursor - 2; - for (int i = 0; i < listKvp.Count; i++) + // TODO: the above null check can be optimized and avoided inside foreach. + if (entry.Value != null) { - var entry = listKvp[i]; - if (entry.Key == "{OriginalFormat}" || this.m_customFields.ContainsKey(entry.Key)) - { - continue; - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); - envPropertiesCount += 1; - } + // null is not supported. + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + cntFields += 1; } - - cntFields += 1; - MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); } - - var eventId = logRecord.EventId; - if (eventId != default) + else { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "eventId"); - cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, eventId.Id); - cntFields += 1; + hasEnvProperties = true; + continue; } + } - MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); - Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); - cursor += this.m_bufferEpilogue.Length; - return cursor; + if (!bodyPopulated && logRecord.FormattedMessage != null) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.FormattedMessage); + cntFields += 1; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static byte GetSeverityNumber(LogLevel logLevel) + if (hasEnvProperties) { - // Maps the Ilogger LogLevel to OpenTelemetry logging level. - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#mapping-of-severitynumber - // TODO: for improving perf simply do ((int)loglevel * 4) + 1 - // or ((int)logLevel << 2) + 1 - switch (logLevel) + // Iteration #2 - Get all "other" fields and collapse them into single field + // named "env_properties". + ushort envPropertiesCount = 0; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int idxMapSizeEnvPropertiesPatch = cursor - 2; + for (int i = 0; i < listKvp.Count; i++) { - case LogLevel.Trace: - return 1; - case LogLevel.Debug: - return 5; - case LogLevel.Information: - return 9; - case LogLevel.Warning: - return 13; - case LogLevel.Error: - return 17; - case LogLevel.Critical: - return 21; - - // we reach default only for LogLevel.None - // but that is filtered out anyway. - // should we throw here then? - default: - return 1; + var entry = listKvp[i]; + if (entry.Key == "{OriginalFormat}" || this.m_customFields.ContainsKey(entry.Key)) + { + continue; + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + envPropertiesCount += 1; + } } + + cntFields += 1; + MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); + } + + var eventId = logRecord.EventId; + if (eventId != default) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "eventId"); + cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, eventId.Id); + cntFields += 1; + } + + MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); + Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); + cursor += this.m_bufferEpilogue.Length; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static byte GetSeverityNumber(LogLevel logLevel) + { + // Maps the Ilogger LogLevel to OpenTelemetry logging level. + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#mapping-of-severitynumber + // TODO: for improving perf simply do ((int)loglevel * 4) + 1 + // or ((int)logLevel << 2) + 1 + switch (logLevel) + { + case LogLevel.Trace: + return 1; + case LogLevel.Debug: + return 5; + case LogLevel.Information: + return 9; + case LogLevel.Warning: + return 13; + case LogLevel.Error: + return 17; + case LogLevel.Critical: + return 21; + + // we reach default only for LogLevel.None + // but that is filtered out anyway. + // should we throw here then? + default: + return 1; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index d6eaeee7aa..4da2048708 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -20,28 +20,27 @@ using OpenTelemetry.Exporter.Geneva; using OpenTelemetry.Logs; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging; + +public static class GenevaLoggingExtensions { - public static class GenevaLoggingExtensions + public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetryLoggerOptions options, Action configure) { - public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetryLoggerOptions options, Action configure) + if (options == null) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + throw new ArgumentNullException(nameof(options)); + } - var genevaOptions = new GenevaExporterOptions(); - configure?.Invoke(genevaOptions); - var exporter = new GenevaLogExporter(genevaOptions); - if (exporter.IsUsingUnixDomainSocket) - { - return options.AddProcessor(new BatchLogRecordExportProcessor(exporter)); - } - else - { - return options.AddProcessor(new ReentrantExportProcessor(exporter)); - } + var genevaOptions = new GenevaExporterOptions(); + configure?.Invoke(genevaOptions); + var exporter = new GenevaLogExporter(genevaOptions); + if (exporter.IsUsingUnixDomainSocket) + { + return options.AddProcessor(new BatchLogRecordExportProcessor(exporter)); + } + else + { + return options.AddProcessor(new ReentrantExportProcessor(exporter)); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index b45a257b8f..7942cf412a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -21,484 +21,483 @@ using System.Text; using OpenTelemetry.Metrics; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaMetricExporter : BaseExporter { - public class GenevaMetricExporter : BaseExporter - { - private const int BufferSize = 65360; // the maximum ETW payload (inclusive) + private const int BufferSize = 65360; // the maximum ETW payload (inclusive) - internal const int MaxDimensionNameSize = 256; + internal const int MaxDimensionNameSize = 256; - internal const int MaxDimensionValueSize = 1024; + internal const int MaxDimensionValueSize = 1024; - private readonly ushort prepopulatedDimensionsCount; + private readonly ushort prepopulatedDimensionsCount; - private readonly int fixedPayloadStartIndex; + private readonly int fixedPayloadStartIndex; - private readonly string monitoringAccount; + private readonly string monitoringAccount; - private readonly string metricNamespace; + private readonly string metricNamespace; - private readonly IMetricDataTransport metricDataTransport; + private readonly IMetricDataTransport metricDataTransport; - private readonly List serializedPrepopulatedDimensionsKeys; + private readonly List serializedPrepopulatedDimensionsKeys; - private readonly List serializedPrepopulatedDimensionsValues; + private readonly List serializedPrepopulatedDimensionsValues; - private readonly byte[] bufferForNonHistogramMetrics = new byte[BufferSize]; + private readonly byte[] bufferForNonHistogramMetrics = new byte[BufferSize]; - private readonly byte[] bufferForHistogramMetrics = new byte[BufferSize]; + private readonly byte[] bufferForHistogramMetrics = new byte[BufferSize]; - private readonly int bufferIndexForNonHistogramMetrics; + private readonly int bufferIndexForNonHistogramMetrics; - private readonly int bufferIndexForHistogramMetrics; + private readonly int bufferIndexForHistogramMetrics; - private static readonly MetricData ulongZero = new MetricData { UInt64Value = 0 }; + private static readonly MetricData ulongZero = new MetricData { UInt64Value = 0 }; - private bool isDisposed; + private bool isDisposed; - public GenevaMetricExporter(GenevaMetricExporterOptions options) + public GenevaMetricExporter(GenevaMetricExporterOptions options) + { + if (options == null) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + throw new ArgumentNullException(nameof(options)); + } - if (string.IsNullOrWhiteSpace(options.ConnectionString)) - { - throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); - } + if (string.IsNullOrWhiteSpace(options.ConnectionString)) + { + throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); + } - var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - this.monitoringAccount = connectionStringBuilder.Account; - this.metricNamespace = connectionStringBuilder.Namespace; + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + this.monitoringAccount = connectionStringBuilder.Account; + this.metricNamespace = connectionStringBuilder.Namespace; - if (options.PrepopulatedMetricDimensions != null) - { - this.prepopulatedDimensionsCount = (ushort)options.PrepopulatedMetricDimensions.Count; - this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(options.PrepopulatedMetricDimensions.Keys); - this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(options.PrepopulatedMetricDimensions.Values); - } + if (options.PrepopulatedMetricDimensions != null) + { + this.prepopulatedDimensionsCount = (ushort)options.PrepopulatedMetricDimensions.Count; + this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(options.PrepopulatedMetricDimensions.Keys); + this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(options.PrepopulatedMetricDimensions.Values); + } - switch (connectionStringBuilder.Protocol) - { - case TransportProtocol.Unix: - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new ArgumentException("Unix domain socket should not be used on Windows."); - } + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } - var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Tcp: + throw new ArgumentException("TCP transport is not supported yet."); + case TransportProtocol.Udp: + throw new ArgumentException("UDP transport is not supported yet."); + case TransportProtocol.Unspecified: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + this.metricDataTransport = new MetricEtwDataTransport(); break; - case TransportProtocol.Tcp: - throw new ArgumentException("TCP transport is not supported yet."); - case TransportProtocol.Udp: - throw new ArgumentException("UDP transport is not supported yet."); - case TransportProtocol.Unspecified: - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - this.metricDataTransport = new MetricEtwDataTransport(); - break; - } - else - { - throw new ArgumentException("Endpoint not specified"); - } + } + else + { + throw new ArgumentException("Endpoint not specified"); + } - default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); - } + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } - this.bufferIndexForNonHistogramMetrics = this.InitializeBufferForNonHistogramMetrics(); - this.bufferIndexForHistogramMetrics = this.InitializeBufferForHistogramMetrics(); + this.bufferIndexForNonHistogramMetrics = this.InitializeBufferForNonHistogramMetrics(); + this.bufferIndexForHistogramMetrics = this.InitializeBufferForHistogramMetrics(); - unsafe - { - this.fixedPayloadStartIndex = sizeof(BinaryHeader); - } + unsafe + { + this.fixedPayloadStartIndex = sizeof(BinaryHeader); } + } - public override ExportResult Export(in Batch batch) + public override ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + foreach (var metric in batch) { - var result = ExportResult.Success; - foreach (var metric in batch) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + try { - try + switch (metric.MetricType) { - switch (metric.MetricType) - { - case MetricType.LongSum: - { - var ulongSum = Convert.ToUInt64(metricPoint.GetSumLong()); - var metricData = new MetricData { UInt64Value = ulongSum }; - var bodyLength = this.SerializeMetric( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp - metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); - break; - } - - case MetricType.LongGauge: - { - var ulongSum = Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); - var metricData = new MetricData { UInt64Value = ulongSum }; - var bodyLength = this.SerializeMetric( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); - break; - } - - case MetricType.DoubleSum: - { - var doubleSum = metricPoint.GetSumDouble(); - var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetric( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); - break; - } - - case MetricType.DoubleGauge: - { - var doubleSum = metricPoint.GetGaugeLastValueDouble(); - var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetric( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); - break; - } - - case MetricType.Histogram: - { - var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; - var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - var bodyLength = this.SerializeHistogramMetric( - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricPoint.GetHistogramBuckets(), - sum, - count); - this.metricDataTransport.Send(MetricEventType.ExternallyAggregatedULongDistributionMetric, this.bufferForHistogramMetrics, bodyLength); - break; - } - } - } - catch (Exception ex) - { - ExporterEventSource.Log.FailedToSendMetricData(this.metricNamespace, metric.Name, ex.Message); // TODO: preallocate exception or no exception - result = ExportResult.Failure; + case MetricType.LongSum: + { + var ulongSum = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = ulongSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.LongGauge: + { + var ulongSum = Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { UInt64Value = ulongSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.DoubleSum: + { + var doubleSum = metricPoint.GetSumDouble(); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.DoubleGauge: + { + var doubleSum = metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + + case MetricType.Histogram: + { + var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + var bodyLength = this.SerializeHistogramMetric( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count); + this.metricDataTransport.Send(MetricEventType.ExternallyAggregatedULongDistributionMetric, this.bufferForHistogramMetrics, bodyLength); + break; + } } } + catch (Exception ex) + { + ExporterEventSource.Log.FailedToSendMetricData(this.metricNamespace, metric.Name, ex.Message); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } } + } - return result; + return result; + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; } - protected override void Dispose(bool disposing) + if (disposing) { - if (this.isDisposed) + try { - return; + this.metricDataTransport?.Dispose(); } - - if (disposing) + catch (Exception ex) { - try - { - this.metricDataTransport?.Dispose(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException(ex); - } + ExporterEventSource.Log.ExporterException(ex); } - - this.isDisposed = true; - base.Dispose(disposing); } - internal unsafe ushort SerializeMetric( - MetricEventType eventType, - string metricName, - long timestamp, - in ReadOnlyTagCollection tags, - MetricData value) + this.isDisposed = true; + base.Dispose(disposing); + } + + internal unsafe ushort SerializeMetric( + MetricEventType eventType, + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + MetricData value) + { + ushort bodyLength; + try { - ushort bodyLength; - try - { - var bufferIndex = this.bufferIndexForNonHistogramMetrics; - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, metricName); + var bufferIndex = this.bufferIndexForNonHistogramMetrics; + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, metricName); - ushort dimensionsWritten = 0; + ushort dimensionsWritten = 0; - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } - if (this.prepopulatedDimensionsCount > 0) + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) { - dimensionsWritten += this.prepopulatedDimensionsCount; + // TODO: Data Validation } - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, tag.Key); + } - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, tag.Key); - } + dimensionsWritten += (ushort)tags.Count; - dimensionsWritten += (ushort)tags.Count; + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) { - MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + // TODO: Data Validation } - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, dimensionValue); - } + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, dimensionValue); + } - // The Autopilot container name is optional but still preserve the location with zero length if it is empty. - MetricSerializer.SerializeInt16(this.bufferForNonHistogramMetrics, ref bufferIndex, 0); + // The Autopilot container name is optional but still preserve the location with zero length if it is empty. + MetricSerializer.SerializeInt16(this.bufferForNonHistogramMetrics, ref bufferIndex, 0); - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.bufferForNonHistogramMetrics) - { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)eventType; - ptr->BodyLength = bodyLength; - - var payloadPtr = (MetricPayload*)&bufferBytes[this.fixedPayloadStartIndex]; - payloadPtr->CountDimension = dimensionsWritten; - payloadPtr->ReservedWord = 0; - payloadPtr->ReservedDword = 0; - payloadPtr->TimestampUtc = (ulong)timestamp; - payloadPtr->Data = value; - } - } - finally + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.bufferForNonHistogramMetrics) { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)eventType; + ptr->BodyLength = bodyLength; + + var payloadPtr = (MetricPayload*)&bufferBytes[this.fixedPayloadStartIndex]; + payloadPtr->CountDimension = dimensionsWritten; + payloadPtr->ReservedWord = 0; + payloadPtr->ReservedDword = 0; + payloadPtr->TimestampUtc = (ulong)timestamp; + payloadPtr->Data = value; } - - return bodyLength; + } + finally + { } - internal unsafe ushort SerializeHistogramMetric( - string metricName, - long timestamp, - in ReadOnlyTagCollection tags, - HistogramBuckets buckets, - MetricData sum, - uint count) + return bodyLength; + } + + internal unsafe ushort SerializeHistogramMetric( + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + HistogramBuckets buckets, + MetricData sum, + uint count) + { + ushort bodyLength; + try { - ushort bodyLength; - try - { - var bufferIndex = this.bufferIndexForHistogramMetrics; - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, metricName); + var bufferIndex = this.bufferIndexForHistogramMetrics; + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, metricName); - ushort dimensionsWritten = 0; + ushort dimensionsWritten = 0; - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } - if (this.prepopulatedDimensionsCount > 0) + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) { - dimensionsWritten += this.prepopulatedDimensionsCount; + // TODO: Data Validation } - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, tag.Key); + } - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, tag.Key); - } + dimensionsWritten += (ushort)tags.Count; - dimensionsWritten += (ushort)tags.Count; + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) { - MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + // TODO: Data Validation } - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, dimensionValue); - } + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, dimensionValue); + } - // The Autopilot container name is optional but still preserve the location with zero length if it is empty. - MetricSerializer.SerializeInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); + // The Autopilot container name is optional but still preserve the location with zero length if it is empty. + MetricSerializer.SerializeInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); - // Version - MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 0); + // Version + MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 0); - // Meta-data - // Value-count pairs is associated with the constant value of 2 in the distribution_type enum. - MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 2); + // Meta-data + // Value-count pairs is associated with the constant value of 2 in the distribution_type enum. + MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 2); - // Keep a position to record how many buckets are added - var itemsWrittenIndex = bufferIndex; - MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); + // Keep a position to record how many buckets are added + var itemsWrittenIndex = bufferIndex; + MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); - // Bucket values - ushort bucketCount = 0; - double lastExplicitBound = default; - foreach (var bucket in buckets) + // Bucket values + ushort bucketCount = 0; + double lastExplicitBound = default; + foreach (var bucket in buckets) + { + if (bucket.BucketCount > 0) { - if (bucket.BucketCount > 0) + if (bucket.ExplicitBound != double.PositiveInfinity) { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - lastExplicitBound = bucket.ExplicitBound; - } - else - { - // The bucket to catch the overflows is one greater than the last bound provided - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); - } - - MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); - bucketCount++; + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + lastExplicitBound = bucket.ExplicitBound; } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + bucketCount++; } + } - // Write the number of items in distribution emitted and reset back to end. - MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref itemsWrittenIndex, bucketCount); + // Write the number of items in distribution emitted and reset back to end. + MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref itemsWrittenIndex, bucketCount); - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.bufferForHistogramMetrics) - { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric; - ptr->BodyLength = bodyLength; - - var payloadPtr = (ExternalPayload*)&bufferBytes[this.fixedPayloadStartIndex]; - payloadPtr[0].CountDimension = dimensionsWritten; - payloadPtr[0].ReservedWord = 0; - payloadPtr[0].Count = count; - payloadPtr[0].TimestampUtc = (ulong)timestamp; - payloadPtr[0].Sum = sum; - payloadPtr[0].Min = ulongZero; - payloadPtr[0].Max = ulongZero; - } - } - finally + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.bufferForHistogramMetrics) { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric; + ptr->BodyLength = bodyLength; + + var payloadPtr = (ExternalPayload*)&bufferBytes[this.fixedPayloadStartIndex]; + payloadPtr[0].CountDimension = dimensionsWritten; + payloadPtr[0].ReservedWord = 0; + payloadPtr[0].Count = count; + payloadPtr[0].TimestampUtc = (ulong)timestamp; + payloadPtr[0].Sum = sum; + payloadPtr[0].Min = ulongZero; + payloadPtr[0].Max = ulongZero; } - - return bodyLength; } - - private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) + finally { - var serializedKeys = new List(this.prepopulatedDimensionsCount); - foreach (var key in keys) - { - serializedKeys.Add(Encoding.UTF8.GetBytes(key)); - } - - return serializedKeys; } - private List SerializePrepopulatedDimensionsValues(IEnumerable values) - { - var serializedValues = new List(this.prepopulatedDimensionsCount); - foreach (var value in values) - { - var valueAsString = Convert.ToString(value, CultureInfo.InvariantCulture); - serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); - } + return bodyLength; + } - return serializedValues; + private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) + { + var serializedKeys = new List(this.prepopulatedDimensionsCount); + foreach (var key in keys) + { + serializedKeys.Add(Encoding.UTF8.GetBytes(key)); } - private unsafe int InitializeBufferForNonHistogramMetrics() + return serializedKeys; + } + + private List SerializePrepopulatedDimensionsValues(IEnumerable values) + { + var serializedValues = new List(this.prepopulatedDimensionsCount); + foreach (var value in values) { - // The buffer format is as follows: - // -- BinaryHeader - // -- MetricPayload - // -- Variable length content + var valueAsString = Convert.ToString(value, CultureInfo.InvariantCulture); + serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); + } - // Leave enough space for the header and fixed payload - var bufferIndex = sizeof(BinaryHeader) + sizeof(MetricPayload); + return serializedValues; + } - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.monitoringAccount); - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.metricNamespace); + private unsafe int InitializeBufferForNonHistogramMetrics() + { + // The buffer format is as follows: + // -- BinaryHeader + // -- MetricPayload + // -- Variable length content - return bufferIndex; - } + // Leave enough space for the header and fixed payload + var bufferIndex = sizeof(BinaryHeader) + sizeof(MetricPayload); - private unsafe int InitializeBufferForHistogramMetrics() - { - // The buffer format is as follows: - // -- BinaryHeader - // -- ExternalPayload - // -- Variable length content + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.monitoringAccount); + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.metricNamespace); - // Leave enough space for the header and fixed payload - var bufferIndex = sizeof(BinaryHeader) + sizeof(ExternalPayload); + return bufferIndex; + } - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.monitoringAccount); - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.metricNamespace); + private unsafe int InitializeBufferForHistogramMetrics() + { + // The buffer format is as follows: + // -- BinaryHeader + // -- ExternalPayload + // -- Variable length content - return bufferIndex; - } + // Leave enough space for the header and fixed payload + var bufferIndex = sizeof(BinaryHeader) + sizeof(ExternalPayload); + + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.monitoringAccount); + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.metricNamespace); + + return bufferIndex; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index f117702320..c163849833 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -17,22 +17,20 @@ using System; using OpenTelemetry.Metrics; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public static class GenevaMetricExporterExtensions { - public static class GenevaMetricExporterExtensions + [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] + public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure = null) { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] - public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure = null) + if (builder == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } - - var options = new GenevaMetricExporterOptions(); - configure?.Invoke(options); - return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) - { TemporalityPreference = MetricReaderTemporalityPreference.Delta }); + throw new ArgumentNullException(nameof(builder)); } + + var options = new GenevaMetricExporterOptions(); + configure?.Invoke(options); + return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds)); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs index 50a6e0f272..9770e8fc00 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs @@ -18,65 +18,64 @@ using System.Collections.Generic; using System.Globalization; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaMetricExporterOptions { - public class GenevaMetricExporterOptions - { - private IReadOnlyDictionary _prepopulatedMetricDimensions; + private IReadOnlyDictionary _prepopulatedMetricDimensions; - /// - /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. - /// For e.g.: "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace". - /// - public string ConnectionString { get; set; } + /// + /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. + /// For e.g.: "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace". + /// + public string ConnectionString { get; set; } - /// - /// Gets or sets the metric export interval in milliseconds. The default value is 20000. - /// - public int MetricExportIntervalMilliseconds { get; set; } = 20000; + /// + /// Gets or sets the metric export interval in milliseconds. The default value is 20000. + /// + public int MetricExportIntervalMilliseconds { get; set; } = 20000; - /// - /// Gets or sets the pre-populated dimensions for all the metrics exported by the exporter. - /// - public IReadOnlyDictionary PrepopulatedMetricDimensions + /// + /// Gets or sets the pre-populated dimensions for all the metrics exported by the exporter. + /// + public IReadOnlyDictionary PrepopulatedMetricDimensions + { + get { - get + return this._prepopulatedMetricDimensions; + } + + set + { + if (value == null) { - return this._prepopulatedMetricDimensions; + throw new ArgumentNullException(nameof(value)); } - set + var copy = new Dictionary(value.Count); + + foreach (var entry in value) { - if (value == null) + if (entry.Key.Length > GenevaMetricExporter.MaxDimensionNameSize) { - throw new ArgumentNullException(nameof(value)); + throw new ArgumentException($"The dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."); } - var copy = new Dictionary(value.Count); - - foreach (var entry in value) + if (entry.Value == null) { - if (entry.Key.Length > GenevaMetricExporter.MaxDimensionNameSize) - { - throw new ArgumentException($"The dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."); - } - - if (entry.Value == null) - { - throw new ArgumentNullException($"{nameof(this.PrepopulatedMetricDimensions)}[\"{entry.Key}\"]"); - } - - var dimensionValue = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > GenevaMetricExporter.MaxDimensionValueSize) - { - throw new ArgumentException($"Value provided for the dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."); - } + throw new ArgumentNullException($"{nameof(this.PrepopulatedMetricDimensions)}[\"{entry.Key}\"]"); + } - copy[entry.Key] = entry.Value; // shallow copy + var dimensionValue = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > GenevaMetricExporter.MaxDimensionValueSize) + { + throw new ArgumentException($"Value provided for the dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."); } - this._prepopulatedMetricDimensions = copy; + copy[entry.Key] = entry.Value; // shallow copy } + + this._prepopulatedMetricDimensions = copy; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index f6f7f19b01..e2210f714a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -22,430 +22,429 @@ using System.Text; using System.Threading; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaTraceExporter : GenevaBaseExporter { - public class GenevaTraceExporter : GenevaBaseExporter + public GenevaTraceExporter(GenevaExporterOptions options) { - public GenevaTraceExporter(GenevaExporterOptions options) + if (options == null) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + throw new ArgumentNullException(nameof(options)); + } - if (string.IsNullOrWhiteSpace(options.ConnectionString)) - { - throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); - } + if (string.IsNullOrWhiteSpace(options.ConnectionString)) + { + throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); + } - var partAName = "Span"; - if (options.TableNameMappings != null - && options.TableNameMappings.TryGetValue("Span", out var customTableName)) + var partAName = "Span"; + if (options.TableNameMappings != null + && options.TableNameMappings.TryGetValue("Span", out var customTableName)) + { + if (string.IsNullOrWhiteSpace(customTableName)) { - if (string.IsNullOrWhiteSpace(customTableName)) - { - throw new ArgumentException("TableName mapping for Span is invalid."); - } - - if (Encoding.UTF8.GetByteCount(customTableName) != customTableName.Length) - { - throw new ArgumentException("The \"{customTableName}\" provided for TableNameMappings option contains non-ASCII characters", customTableName); - } - - partAName = customTableName; + throw new ArgumentException("TableName mapping for Span is invalid."); } - var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - switch (connectionStringBuilder.Protocol) + if (Encoding.UTF8.GetByteCount(customTableName) != customTableName.Length) { - case TransportProtocol.Etw: - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); - } - - this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); - break; - case TransportProtocol.Unix: - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new ArgumentException("Unix domain socket should not be used on Windows."); - } - - var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); - break; - case TransportProtocol.Tcp: - throw new ArgumentException("TCP transport is not supported yet."); - case TransportProtocol.Udp: - throw new ArgumentException("UDP transport is not supported yet."); - default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + throw new ArgumentException("The \"{customTableName}\" provided for TableNameMappings option contains non-ASCII characters", customTableName); } - // TODO: Validate custom fields (reserved name? etc). - if (options.CustomFields != null) - { - var customFields = new Dictionary(StringComparer.Ordinal); - var dedicatedFields = new Dictionary(StringComparer.Ordinal); + partAName = customTableName; + } - // Seed customFields with Span PartB - customFields["azureResourceProvider"] = true; - dedicatedFields["azureResourceProvider"] = true; - foreach (var name in CS40_PART_B_MAPPING.Values) + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Etw: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - customFields[name] = true; - dedicatedFields[name] = true; + throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); } - foreach (var name in options.CustomFields) + this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); + break; + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - customFields[name] = true; - dedicatedFields[name] = true; + throw new ArgumentException("Unix domain socket should not be used on Windows."); } - this.m_customFields = customFields; + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Tcp: + throw new ArgumentException("TCP transport is not supported yet."); + case TransportProtocol.Udp: + throw new ArgumentException("UDP transport is not supported yet."); + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } - foreach (var name in CS40_PART_B_MAPPING.Keys) - { - dedicatedFields[name] = true; - } + // TODO: Validate custom fields (reserved name? etc). + if (options.CustomFields != null) + { + var customFields = new Dictionary(StringComparer.Ordinal); + var dedicatedFields = new Dictionary(StringComparer.Ordinal); - dedicatedFields["otel.status_code"] = true; - this.m_dedicatedFields = dedicatedFields; + // Seed customFields with Span PartB + customFields["azureResourceProvider"] = true; + dedicatedFields["azureResourceProvider"] = true; + foreach (var name in CS40_PART_B_MAPPING.Values) + { + customFields[name] = true; + dedicatedFields[name] = true; } - var buffer = new byte[BUFFER_SIZE]; - - var cursor = 0; + foreach (var name in options.CustomFields) + { + customFields[name] = true; + dedicatedFields[name] = true; + } - /* Fluentd Forward Mode: - [ - "Span", - [ - [ , { "env_ver": "4.0", ... } ] - ], - { "TimeFormat": "DateTime" } - ] - */ - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, partAName); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); - - // timestamp - cursor = MessagePackSerializer.WriteTimestamp96Header(buffer, cursor); - this.m_idxTimestampPatch = cursor; - cursor += 12; // reserve 12 bytes for the timestamp - - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration - this.m_idxMapSizePatch = cursor - 2; - - this.m_cntPrepopulatedFields = 0; - - // TODO: Do we support PartB as well? - // Part A - core envelope - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); - this.m_cntPrepopulatedFields += 1; + this.m_customFields = customFields; - foreach (var entry in options.PrepopulatedFields) + foreach (var name in CS40_PART_B_MAPPING.Keys) { - var value = entry.Value; - switch (value) - { - case bool vb: - case byte vui8: - case sbyte vi8: - case short vi16: - case ushort vui16: - case int vi32: - case uint vui32: - case long vi64: - case ulong vui64: - case float vf: - case double vd: - case string vs: - break; - default: - value = options.ConvertToJson(value); - break; - } - - cursor = AddPartAField(buffer, cursor, entry.Key, value); - this.m_cntPrepopulatedFields += 1; + dedicatedFields[name] = true; } - this.m_bufferPrologue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.m_bufferPrologue, 0, cursor - 0); + dedicatedFields["otel.status_code"] = true; + this.m_dedicatedFields = dedicatedFields; + } - cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); + var buffer = new byte[BUFFER_SIZE]; - this.m_bufferEpilogue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); - } + var cursor = 0; - public override ExportResult Export(in Batch batch) + /* Fluentd Forward Mode: + [ + "Span", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, partAName); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); + + // timestamp + cursor = MessagePackSerializer.WriteTimestamp96Header(buffer, cursor); + this.m_idxTimestampPatch = cursor; + cursor += 12; // reserve 12 bytes for the timestamp + + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration + this.m_idxMapSizePatch = cursor - 2; + + this.m_cntPrepopulatedFields = 0; + + // TODO: Do we support PartB as well? + // Part A - core envelope + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); + this.m_cntPrepopulatedFields += 1; + + foreach (var entry in options.PrepopulatedFields) { - // Note: The MessagePackSerializer takes way less time / memory than creating the activity itself. - // This makes the short-circuit check less useful. - // On the other side, running the serializer could help to catch error in the early phase of development lifecycle. - // - // if (!m_dataTransport.IsEnabled()) - // { - // return ExportResult.Success; - // } - - var result = ExportResult.Success; - foreach (var activity in batch) + var value = entry.Value; + switch (value) { - try - { - var cursor = this.SerializeActivity(activity); - this.m_dataTransport.Send(this.m_buffer.Value, cursor - 0); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception - result = ExportResult.Failure; - } + case bool vb: + case byte vui8: + case sbyte vi8: + case short vi16: + case ushort vui16: + case int vi32: + case uint vui32: + case long vi64: + case ulong vui64: + case float vf: + case double vd: + case string vs: + break; + default: + value = options.ConvertToJson(value); + break; } - return result; + cursor = AddPartAField(buffer, cursor, entry.Key, value); + this.m_cntPrepopulatedFields += 1; } - protected override void Dispose(bool disposing) + this.m_bufferPrologue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.m_bufferPrologue, 0, cursor - 0); + + cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); + + this.m_bufferEpilogue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + } + + public override ExportResult Export(in Batch batch) + { + // Note: The MessagePackSerializer takes way less time / memory than creating the activity itself. + // This makes the short-circuit check less useful. + // On the other side, running the serializer could help to catch error in the early phase of development lifecycle. + // + // if (!m_dataTransport.IsEnabled()) + // { + // return ExportResult.Success; + // } + + var result = ExportResult.Success; + foreach (var activity in batch) { - if (this.isDisposed) + try { - return; + var cursor = this.SerializeActivity(activity); + this.m_dataTransport.Send(this.m_buffer.Value, cursor - 0); } - - if (disposing) + catch (Exception ex) { - try - { - (this.m_dataTransport as IDisposable)?.Dispose(); - this.m_buffer.Dispose(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException(ex); - } + ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; } - - this.isDisposed = true; - base.Dispose(disposing); } - internal bool IsUsingUnixDomainSocket + return result; + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) { - get => this.m_dataTransport is UnixDomainSocketDataTransport; + return; } - internal int SerializeActivity(Activity activity) + if (disposing) { - var buffer = this.m_buffer.Value; - if (buffer == null) + try { - buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM - Buffer.BlockCopy(this.m_bufferPrologue, 0, buffer, 0, this.m_bufferPrologue.Length); - this.m_buffer.Value = buffer; + (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_buffer.Dispose(); } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException(ex); + } + } - var cursor = this.m_bufferPrologue.Length; - var cntFields = this.m_cntPrepopulatedFields; - var dtBegin = activity.StartTimeUtc; - var tsBegin = dtBegin.Ticks; - var tsEnd = tsBegin + activity.Duration.Ticks; - var dtEnd = new DateTime(tsEnd); - - MessagePackSerializer.WriteTimestamp96(buffer, this.m_idxTimestampPatch, tsEnd); - - #region Part A - core envelope - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_time"); - cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, dtEnd); - cntFields += 1; - #endregion - - #region Part A - dt extension - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_traceId"); - - // Note: ToHexString returns the pre-calculated hex representation without allocation - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, activity.Context.TraceId.ToHexString()); - cntFields += 1; + this.isDisposed = true; + base.Dispose(disposing); + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_spanId"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, activity.Context.SpanId.ToHexString()); - cntFields += 1; - #endregion + internal bool IsUsingUnixDomainSocket + { + get => this.m_dataTransport is UnixDomainSocketDataTransport; + } - #region Part B Span - required fields - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, activity.DisplayName); - cntFields += 1; + internal int SerializeActivity(Activity activity) + { + var buffer = this.m_buffer.Value; + if (buffer == null) + { + buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM + Buffer.BlockCopy(this.m_bufferPrologue, 0, buffer, 0, this.m_bufferPrologue.Length); + this.m_buffer.Value = buffer; + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "kind"); - cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, (int)activity.Kind); + var cursor = this.m_bufferPrologue.Length; + var cntFields = this.m_cntPrepopulatedFields; + var dtBegin = activity.StartTimeUtc; + var tsBegin = dtBegin.Ticks; + var tsEnd = tsBegin + activity.Duration.Ticks; + var dtEnd = new DateTime(tsEnd); + + MessagePackSerializer.WriteTimestamp96(buffer, this.m_idxTimestampPatch, tsEnd); + + #region Part A - core envelope + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_time"); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, dtEnd); + cntFields += 1; + #endregion + + #region Part A - dt extension + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_traceId"); + + // Note: ToHexString returns the pre-calculated hex representation without allocation + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, activity.Context.TraceId.ToHexString()); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_dt_spanId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, activity.Context.SpanId.ToHexString()); + cntFields += 1; + #endregion + + #region Part B Span - required fields + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, activity.DisplayName); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "kind"); + cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, (int)activity.Kind); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "startTime"); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, dtBegin); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "success"); + cursor = MessagePackSerializer.SerializeBool(buffer, cursor, true); + var idxSuccessPatch = cursor - 1; + cntFields += 1; + #endregion + + #region Part B Span optional fields and Part C fields + var strParentId = activity.ParentSpanId.ToHexString(); + + // Note: this should be blazing fast since Object.ReferenceEquals(strParentId, INVALID_SPAN_ID) == true + if (!string.Equals(strParentId, INVALID_SPAN_ID, StringComparison.Ordinal)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "parentId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, strParentId); cntFields += 1; + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "startTime"); - cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, dtBegin); - cntFields += 1; + var links = activity.Links; + if (links.Any()) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "links"); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); // Note: always use Array16 for perf consideration + var idxLinkPatch = cursor - 2; + ushort cntLink = 0; + foreach (var link in links) + { + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, 2); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toTraceId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.TraceId.ToHexString()); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toSpanId"); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.SpanId.ToHexString()); + cntLink += 1; + } - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "success"); - cursor = MessagePackSerializer.SerializeBool(buffer, cursor, true); - var idxSuccessPatch = cursor - 1; + MessagePackSerializer.WriteUInt16(buffer, idxLinkPatch, cntLink); cntFields += 1; - #endregion + } - #region Part B Span optional fields and Part C fields - var strParentId = activity.ParentSpanId.ToHexString(); + // TODO: The current approach is to iterate twice over TagObjects so that all + // env_properties can be added the very end. This avoids speculating the size + // and preallocating a separate buffer for it. + // Alternates include static allocation and iterate once. + // The TODO: here is to measure perf and change to alternate, if required. - // Note: this should be blazing fast since Object.ReferenceEquals(strParentId, INVALID_SPAN_ID) == true - if (!string.Equals(strParentId, INVALID_SPAN_ID, StringComparison.Ordinal)) + // Iteration #1 - Get those fields which become dedicated column + // i.e all PartB fields and opt-in part c fields. + bool hasEnvProperties = false; + foreach (var entry in activity.TagObjects) + { + // TODO: check name collision + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "parentId"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, strParentId); - cntFields += 1; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); } - - var links = activity.Links; - if (links.Any()) + else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "links"); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); // Note: always use Array16 for perf consideration - var idxLinkPatch = cursor - 2; - ushort cntLink = 0; - foreach (var link in links) + if (string.Equals(entry.Value.ToString(), "ERROR", StringComparison.Ordinal)) { - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, 2); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toTraceId"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.TraceId.ToHexString()); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toSpanId"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.SpanId.ToHexString()); - cntLink += 1; + MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); } - MessagePackSerializer.WriteUInt16(buffer, idxLinkPatch, cntLink); - cntFields += 1; + continue; + } + else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + { + // TODO: the above null check can be optimized and avoided inside foreach. + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + } + else + { + hasEnvProperties = true; + continue; } - // TODO: The current approach is to iterate twice over TagObjects so that all - // env_properties can be added the very end. This avoids speculating the size - // and preallocating a separate buffer for it. - // Alternates include static allocation and iterate once. - // The TODO: here is to measure perf and change to alternate, if required. + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + cntFields += 1; + } + + if (hasEnvProperties) + { + // Iteration #2 - Get all "other" fields and collapse them into single field + // named "env_properties". + ushort envPropertiesCount = 0; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int idxMapSizeEnvPropertiesPatch = cursor - 2; - // Iteration #1 - Get those fields which become dedicated column - // i.e all PartB fields and opt-in part c fields. - bool hasEnvProperties = false; foreach (var entry in activity.TagObjects) { // TODO: check name collision - if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) + if (this.m_dedicatedFields.ContainsKey(entry.Key)) { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); - } - else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) - { - if (string.Equals(entry.Value.ToString(), "ERROR", StringComparison.Ordinal)) - { - MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); - } - continue; } - else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) - { - // TODO: the above null check can be optimized and avoided inside foreach. - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); - } else { - hasEnvProperties = true; - continue; + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); + envPropertiesCount += 1; } - - cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); - cntFields += 1; } - if (hasEnvProperties) - { - // Iteration #2 - Get all "other" fields and collapse them into single field - // named "env_properties". - ushort envPropertiesCount = 0; - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int idxMapSizeEnvPropertiesPatch = cursor - 2; - - foreach (var entry in activity.TagObjects) - { - // TODO: check name collision - if (this.m_dedicatedFields.ContainsKey(entry.Key)) - { - continue; - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); - envPropertiesCount += 1; - } - } - - cntFields += 1; - MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); - } - #endregion + cntFields += 1; + MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); + } + #endregion - MessagePackSerializer.WriteUInt16(buffer, this.m_idxMapSizePatch, cntFields); + MessagePackSerializer.WriteUInt16(buffer, this.m_idxMapSizePatch, cntFields); - Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); - cursor += this.m_bufferEpilogue.Length; + Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); + cursor += this.m_bufferEpilogue.Length; - return cursor; - } + return cursor; + } - private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - private readonly ThreadLocal m_buffer = new ThreadLocal(() => null); + private readonly ThreadLocal m_buffer = new ThreadLocal(() => null); - private readonly byte[] m_bufferPrologue; + private readonly byte[] m_bufferPrologue; - private readonly byte[] m_bufferEpilogue; + private readonly byte[] m_bufferEpilogue; - private readonly ushort m_cntPrepopulatedFields; + private readonly ushort m_cntPrepopulatedFields; - private readonly int m_idxTimestampPatch; + private readonly int m_idxTimestampPatch; - private readonly int m_idxMapSizePatch; + private readonly int m_idxMapSizePatch; - private readonly IDataTransport m_dataTransport; + private readonly IDataTransport m_dataTransport; - private readonly IReadOnlyDictionary m_customFields; + private readonly IReadOnlyDictionary m_customFields; - private readonly IReadOnlyDictionary m_dedicatedFields; + private readonly IReadOnlyDictionary m_dedicatedFields; - private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); + private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary - { - ["db.system"] = "dbSystem", - ["db.name"] = "dbName", - ["db.statement"] = "dbStatement", + private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary + { + ["db.system"] = "dbSystem", + ["db.name"] = "dbName", + ["db.statement"] = "dbStatement", - ["http.method"] = "httpMethod", - ["http.url"] = "httpUrl", - ["http.status_code"] = "httpStatusCode", + ["http.method"] = "httpMethod", + ["http.url"] = "httpUrl", + ["http.status_code"] = "httpStatusCode", - ["messaging.system"] = "messagingSystem", - ["messaging.destination"] = "messagingDestination", - ["messaging.url"] = "messagingUrl", + ["messaging.system"] = "messagingSystem", + ["messaging.destination"] = "messagingDestination", + ["messaging.url"] = "messagingUrl", - ["otel.status_description"] = "statusMessage", - }; + ["otel.status_description"] = "statusMessage", + }; - private bool isDisposed; - } + private bool isDisposed; } diff --git a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs index 4ffc2d98fb..a296312213 100644 --- a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs @@ -14,12 +14,11 @@ // limitations under the License. // -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal interface IDataTransport { - internal interface IDataTransport - { - bool IsEnabled(); + bool IsEnabled(); - void Send(byte[] data, int size); - } + void Send(byte[] data, int size); } diff --git a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs index 8db60e5728..622f168bf1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs @@ -16,19 +16,18 @@ using System; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal interface IMetricDataTransport : IDisposable { - internal interface IMetricDataTransport : IDisposable - { - /// - /// Writes a standard metric event containing only a single value. - /// - /// Type of the event. - /// The byte array containing the serialized data. - /// Length of the payload (fixed + variable). - void Send( - MetricEventType eventType, - byte[] body, - int size); - } + /// + /// Writes a standard metric event containing only a single value. + /// + /// Type of the event. + /// The byte array containing the serialized data. + /// Length of the payload (fixed + variable). + void Send( + MetricEventType eventType, + byte[] body, + int size); } diff --git a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs index 4896bd5096..396ae9d582 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs @@ -20,556 +20,555 @@ using System.Runtime.CompilerServices; using System.Text; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal static class MessagePackSerializer { - internal static class MessagePackSerializer + public const byte MIN_FIX_MAP = 0x80; + public const byte MIN_FIX_ARRAY = 0x90; + public const byte MIN_FIX_STR = 0xA0; + public const byte NIL = 0xC0; + public const byte FALSE = 0xC2; + public const byte TRUE = 0xC3; + public const byte BIN8 = 0xC4; + public const byte BIN16 = 0xC5; + public const byte BIN32 = 0xC6; + public const byte TIMESTAMP96 = 0xC7; + public const byte FLOAT32 = 0xCA; + public const byte FLOAT64 = 0xCB; + public const byte UINT8 = 0xCC; + public const byte UINT16 = 0xCD; + public const byte UINT32 = 0xCE; + public const byte UINT64 = 0xCF; + public const byte INT8 = 0xD0; + public const byte INT16 = 0xD1; + public const byte INT32 = 0xD2; + public const byte INT64 = 0xD3; + public const byte TIMESTAMP32 = 0xD6; + public const byte TIMESTAMP64 = 0xD7; + public const byte STR8 = 0xD9; + public const byte STR16 = 0xDA; + public const byte STR32 = 0xDB; + public const byte ARRAY16 = 0xDC; + public const byte ARRAY32 = 0xDD; + public const byte MAP16 = 0xDE; + public const byte MAP32 = 0xDF; + public const byte EXT_DATE_TIME = 0xFF; + + private const int LIMIT_MIN_FIX_NEGATIVE_INT = -32; + private const int LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES = 31; + private const int LIMIT_MAX_STR8_LENGTH_IN_BYTES = (1 << 8) - 1; // str8 stores 2^8 - 1 bytes + private const int LIMIT_MAX_FIX_MAP_COUNT = 15; + private const int LIMIT_MAX_FIX_ARRAY_LENGTH = 15; + private const int STRING_SIZE_LIMIT_CHAR_COUNT = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeNull(byte[] buffer, int cursor) { - public const byte MIN_FIX_MAP = 0x80; - public const byte MIN_FIX_ARRAY = 0x90; - public const byte MIN_FIX_STR = 0xA0; - public const byte NIL = 0xC0; - public const byte FALSE = 0xC2; - public const byte TRUE = 0xC3; - public const byte BIN8 = 0xC4; - public const byte BIN16 = 0xC5; - public const byte BIN32 = 0xC6; - public const byte TIMESTAMP96 = 0xC7; - public const byte FLOAT32 = 0xCA; - public const byte FLOAT64 = 0xCB; - public const byte UINT8 = 0xCC; - public const byte UINT16 = 0xCD; - public const byte UINT32 = 0xCE; - public const byte UINT64 = 0xCF; - public const byte INT8 = 0xD0; - public const byte INT16 = 0xD1; - public const byte INT32 = 0xD2; - public const byte INT64 = 0xD3; - public const byte TIMESTAMP32 = 0xD6; - public const byte TIMESTAMP64 = 0xD7; - public const byte STR8 = 0xD9; - public const byte STR16 = 0xDA; - public const byte STR32 = 0xDB; - public const byte ARRAY16 = 0xDC; - public const byte ARRAY32 = 0xDD; - public const byte MAP16 = 0xDE; - public const byte MAP32 = 0xDF; - public const byte EXT_DATE_TIME = 0xFF; - - private const int LIMIT_MIN_FIX_NEGATIVE_INT = -32; - private const int LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES = 31; - private const int LIMIT_MAX_STR8_LENGTH_IN_BYTES = (1 << 8) - 1; // str8 stores 2^8 - 1 bytes - private const int LIMIT_MAX_FIX_MAP_COUNT = 15; - private const int LIMIT_MAX_FIX_ARRAY_LENGTH = 15; - private const int STRING_SIZE_LIMIT_CHAR_COUNT = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeNull(byte[] buffer, int cursor) - { - buffer[cursor++] = NIL; - return cursor; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeBool(byte[] buffer, int cursor, bool value) - { - buffer[cursor++] = value ? TRUE : FALSE; - return cursor; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeInt8(byte[] buffer, int cursor, sbyte value) - { - if (value >= 0) - { - return SerializeUInt8(buffer, cursor, unchecked((byte)value)); - } - - if (value < LIMIT_MIN_FIX_NEGATIVE_INT) - { - buffer[cursor++] = INT8; - } + buffer[cursor++] = NIL; + return cursor; + } - buffer[cursor++] = unchecked((byte)value); - return cursor; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeBool(byte[] buffer, int cursor, bool value) + { + buffer[cursor++] = value ? TRUE : FALSE; + return cursor; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeInt16(byte[] buffer, int cursor, short value) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt8(byte[] buffer, int cursor, sbyte value) + { + if (value >= 0) { - if (value >= 0) - { - return SerializeUInt16(buffer, cursor, unchecked((ushort)value)); - } - - if (value >= sbyte.MinValue) - { - return SerializeInt8(buffer, cursor, unchecked((sbyte)value)); - } - - buffer[cursor++] = INT16; - return WriteInt16(buffer, cursor, value); + return SerializeUInt8(buffer, cursor, unchecked((byte)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeInt32(byte[] buffer, int cursor, int value) + if (value < LIMIT_MIN_FIX_NEGATIVE_INT) { - if (value >= 0) - { - return SerializeUInt32(buffer, cursor, unchecked((uint)value)); - } + buffer[cursor++] = INT8; + } - if (value >= short.MinValue) - { - return SerializeInt16(buffer, cursor, unchecked((short)value)); - } + buffer[cursor++] = unchecked((byte)value); + return cursor; + } - buffer[cursor++] = INT32; - return WriteInt32(buffer, cursor, value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt16(byte[] buffer, int cursor, short value) + { + if (value >= 0) + { + return SerializeUInt16(buffer, cursor, unchecked((ushort)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeInt64(byte[] buffer, int cursor, long value) + if (value >= sbyte.MinValue) { - if (value >= 0) - { - return SerializeUInt64(buffer, cursor, unchecked((ulong)value)); - } - - if (value >= int.MinValue) - { - return SerializeInt32(buffer, cursor, unchecked((int)value)); - } - - buffer[cursor++] = INT64; - return WriteInt64(buffer, cursor, value); + return SerializeInt8(buffer, cursor, unchecked((sbyte)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUInt8(byte[] buffer, int cursor, byte value) - { - if (value > 127) - { - buffer[cursor++] = UINT8; - } + buffer[cursor++] = INT16; + return WriteInt16(buffer, cursor, value); + } - buffer[cursor++] = value; - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt32(byte[] buffer, int cursor, int value) + { + if (value >= 0) + { + return SerializeUInt32(buffer, cursor, unchecked((uint)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUInt16(byte[] buffer, int cursor, ushort value) + if (value >= short.MinValue) { - if (value <= byte.MaxValue) - { - return SerializeUInt8(buffer, cursor, unchecked((byte)value)); - } - - buffer[cursor++] = UINT16; - return WriteUInt16(buffer, cursor, value); + return SerializeInt16(buffer, cursor, unchecked((short)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUInt32(byte[] buffer, int cursor, uint value) - { - if (value <= ushort.MaxValue) - { - return SerializeUInt16(buffer, cursor, unchecked((ushort)value)); - } + buffer[cursor++] = INT32; + return WriteInt32(buffer, cursor, value); + } - buffer[cursor++] = UINT32; - return WriteUInt32(buffer, cursor, value); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeInt64(byte[] buffer, int cursor, long value) + { + if (value >= 0) + { + return SerializeUInt64(buffer, cursor, unchecked((ulong)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUInt64(byte[] buffer, int cursor, ulong value) + if (value >= int.MinValue) { - if (value <= uint.MaxValue) - { - return SerializeUInt32(buffer, cursor, unchecked((uint)value)); - } - - buffer[cursor++] = UINT64; - return WriteUInt64(buffer, cursor, value); + return SerializeInt32(buffer, cursor, unchecked((int)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteInt16(byte[] buffer, int cursor, short value) - { - unchecked - { - buffer[cursor++] = (byte)(value >> 8); - buffer[cursor++] = (byte)value; - } + buffer[cursor++] = INT64; + return WriteInt64(buffer, cursor, value); + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt8(byte[] buffer, int cursor, byte value) + { + if (value > 127) + { + buffer[cursor++] = UINT8; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteInt32(byte[] buffer, int cursor, int value) - { - unchecked - { - buffer[cursor++] = (byte)(value >> 24); - buffer[cursor++] = (byte)(value >> 16); - buffer[cursor++] = (byte)(value >> 8); - buffer[cursor++] = (byte)value; - } + buffer[cursor++] = value; + return cursor; + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt16(byte[] buffer, int cursor, ushort value) + { + if (value <= byte.MaxValue) + { + return SerializeUInt8(buffer, cursor, unchecked((byte)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteInt64(byte[] buffer, int cursor, long value) - { - unchecked - { - buffer[cursor++] = (byte)(value >> 56); - buffer[cursor++] = (byte)(value >> 48); - buffer[cursor++] = (byte)(value >> 40); - buffer[cursor++] = (byte)(value >> 32); - buffer[cursor++] = (byte)(value >> 24); - buffer[cursor++] = (byte)(value >> 16); - buffer[cursor++] = (byte)(value >> 8); - buffer[cursor++] = (byte)value; - } + buffer[cursor++] = UINT16; + return WriteUInt16(buffer, cursor, value); + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt32(byte[] buffer, int cursor, uint value) + { + if (value <= ushort.MaxValue) + { + return SerializeUInt16(buffer, cursor, unchecked((ushort)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteUInt16(byte[] buffer, int cursor, ushort value) - { - unchecked - { - buffer[cursor++] = (byte)(value >> 8); - buffer[cursor++] = (byte)value; - } + buffer[cursor++] = UINT32; + return WriteUInt32(buffer, cursor, value); + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUInt64(byte[] buffer, int cursor, ulong value) + { + if (value <= uint.MaxValue) + { + return SerializeUInt32(buffer, cursor, unchecked((uint)value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteUInt32(byte[] buffer, int cursor, uint value) - { - unchecked - { - buffer[cursor++] = (byte)(value >> 24); - buffer[cursor++] = (byte)(value >> 16); - buffer[cursor++] = (byte)(value >> 8); - buffer[cursor++] = (byte)value; - } + buffer[cursor++] = UINT64; + return WriteUInt64(buffer, cursor, value); + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteInt16(byte[] buffer, int cursor, short value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteUInt64(byte[] buffer, int cursor, ulong value) - { - unchecked - { - buffer[cursor++] = (byte)(value >> 56); - buffer[cursor++] = (byte)(value >> 48); - buffer[cursor++] = (byte)(value >> 40); - buffer[cursor++] = (byte)(value >> 32); - buffer[cursor++] = (byte)(value >> 24); - buffer[cursor++] = (byte)(value >> 16); - buffer[cursor++] = (byte)(value >> 8); - buffer[cursor++] = (byte)value; - } + return cursor; + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteInt32(byte[] buffer, int cursor, int value) + { + unchecked + { + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeFloat32(byte[] buffer, int cursor, float value) + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteInt64(byte[] buffer, int cursor, long value) + { + unchecked { - buffer[cursor++] = FLOAT32; - return WriteInt32(buffer, cursor, Float32ToInt32(value)); + buffer[cursor++] = (byte)(value >> 56); + buffer[cursor++] = (byte)(value >> 48); + buffer[cursor++] = (byte)(value >> 40); + buffer[cursor++] = (byte)(value >> 32); + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe int Float32ToInt32(float value) + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUInt16(byte[] buffer, int cursor, ushort value) + { + unchecked { - return *(int*)&value; + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeFloat64(byte[] buffer, int cursor, double value) + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUInt32(byte[] buffer, int cursor, uint value) + { + unchecked { - buffer[cursor++] = FLOAT64; - return WriteInt64(buffer, cursor, Float64ToInt64(value)); + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe long Float64ToInt64(double value) + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteUInt64(byte[] buffer, int cursor, ulong value) + { + unchecked { - return *(long*)&value; + buffer[cursor++] = (byte)(value >> 56); + buffer[cursor++] = (byte)(value >> 48); + buffer[cursor++] = (byte)(value >> 40); + buffer[cursor++] = (byte)(value >> 32); + buffer[cursor++] = (byte)(value >> 24); + buffer[cursor++] = (byte)(value >> 16); + buffer[cursor++] = (byte)(value >> 8); + buffer[cursor++] = (byte)value; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeAsciiString(byte[] buffer, int cursor, string value) - { - if (value == null) - { - return SerializeNull(buffer, cursor); - } + return cursor; + } - int start = cursor; - var cch = value.Length; - int cb; - if (cch <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) - { - cursor += 1; - cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); - if (cb <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) - { - cursor += cb; - buffer[start] = unchecked((byte)(MIN_FIX_STR | cb)); - return cursor; - } - else - { - throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); - } - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeFloat32(byte[] buffer, int cursor, float value) + { + buffer[cursor++] = FLOAT32; + return WriteInt32(buffer, cursor, Float32ToInt32(value)); + } - if (cch <= LIMIT_MAX_STR8_LENGTH_IN_BYTES) - { - cursor += 2; - cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); - cursor += cb; - if (cb <= LIMIT_MAX_STR8_LENGTH_IN_BYTES) - { - buffer[start] = STR8; - buffer[start + 1] = unchecked((byte)cb); - return cursor; - } - else - { - throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); - } - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe int Float32ToInt32(float value) + { + return *(int*)&value; + } - cursor += 3; - if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) - { - cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); - cursor += cb; - } - else - { - cb = Encoding.ASCII.GetBytes(value, 0, STRING_SIZE_LIMIT_CHAR_COUNT - 3, buffer, cursor); - cursor += cb; - cb += 3; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeFloat64(byte[] buffer, int cursor, double value) + { + buffer[cursor++] = FLOAT64; + return WriteInt64(buffer, cursor, Float64ToInt64(value)); + } - // append "..." to indicate the string truncation - buffer[cursor++] = 0x2E; - buffer[cursor++] = 0x2E; - buffer[cursor++] = 0x2E; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe long Float64ToInt64(double value) + { + return *(long*)&value; + } - buffer[start] = STR16; - buffer[start + 1] = unchecked((byte)(cb >> 8)); - buffer[start + 2] = unchecked((byte)cb); - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeAsciiString(byte[] buffer, int cursor, string value) + { + if (value == null) + { + return SerializeNull(buffer, cursor); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUnicodeString(byte[] buffer, int cursor, string value) + int start = cursor; + var cch = value.Length; + int cb; + if (cch <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) { - if (value == null) + cursor += 1; + cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); + if (cb <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) { - return SerializeNull(buffer, cursor); - } - - int start = cursor; - var cch = value.Length; - int cb; - cursor += 3; - if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) - { - cb = Encoding.UTF8.GetBytes(value, 0, cch, buffer, cursor); cursor += cb; + buffer[start] = unchecked((byte)(MIN_FIX_STR | cb)); + return cursor; } else { - cb = Encoding.UTF8.GetBytes(value, 0, STRING_SIZE_LIMIT_CHAR_COUNT - 3, buffer, cursor); - cursor += cb; - cb += 3; - - // append "..." to indicate the string truncation - buffer[cursor++] = 0x2E; - buffer[cursor++] = 0x2E; - buffer[cursor++] = 0x2E; + throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); } - - buffer[start] = STR16; - buffer[start + 1] = unchecked((byte)(cb >> 8)); - buffer[start + 2] = unchecked((byte)cb); - return cursor; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteArrayHeader(byte[] buffer, int cursor, int length) + if (cch <= LIMIT_MAX_STR8_LENGTH_IN_BYTES) { - if (length <= LIMIT_MAX_FIX_ARRAY_LENGTH) + cursor += 2; + cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); + cursor += cb; + if (cb <= LIMIT_MAX_STR8_LENGTH_IN_BYTES) { - buffer[cursor++] = unchecked((byte)(MIN_FIX_ARRAY | length)); - } - else if (length <= ushort.MaxValue) - { - buffer[cursor++] = ARRAY16; - cursor = WriteUInt16(buffer, cursor, unchecked((ushort)length)); + buffer[start] = STR8; + buffer[start + 1] = unchecked((byte)cb); + return cursor; } else { - buffer[cursor++] = ARRAY32; - cursor = WriteUInt32(buffer, cursor, unchecked((uint)length)); + throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); } - - return cursor; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeArray(byte[] buffer, int cursor, T[] array) + cursor += 3; + if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) { - if (array == null) - { - return SerializeNull(buffer, cursor); - } + cb = Encoding.ASCII.GetBytes(value, 0, cch, buffer, cursor); + cursor += cb; + } + else + { + cb = Encoding.ASCII.GetBytes(value, 0, STRING_SIZE_LIMIT_CHAR_COUNT - 3, buffer, cursor); + cursor += cb; + cb += 3; + + // append "..." to indicate the string truncation + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + } - cursor = WriteArrayHeader(buffer, cursor, array.Length); - for (int i = 0; i < array.Length; i++) - { - cursor = Serialize(buffer, cursor, array[i]); - } + buffer[start] = STR16; + buffer[start + 1] = unchecked((byte)(cb >> 8)); + buffer[start + 2] = unchecked((byte)cb); + return cursor; + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUnicodeString(byte[] buffer, int cursor, string value) + { + if (value == null) + { + return SerializeNull(buffer, cursor); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteMapHeader(byte[] buffer, int cursor, int count) + int start = cursor; + var cch = value.Length; + int cb; + cursor += 3; + if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) { - if (count <= LIMIT_MAX_FIX_MAP_COUNT) - { - buffer[cursor++] = unchecked((byte)(MIN_FIX_MAP | count)); - } - else if (count <= ushort.MaxValue) - { - buffer[cursor++] = MAP16; - cursor = WriteUInt16(buffer, cursor, unchecked((ushort)count)); - } - else - { - buffer[cursor++] = MAP32; - cursor = WriteUInt32(buffer, cursor, unchecked((uint)count)); - } - - return cursor; + cb = Encoding.UTF8.GetBytes(value, 0, cch, buffer, cursor); + cursor += cb; } + else + { + cb = Encoding.UTF8.GetBytes(value, 0, STRING_SIZE_LIMIT_CHAR_COUNT - 3, buffer, cursor); + cursor += cb; + cb += 3; + + // append "..." to indicate the string truncation + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + } + + buffer[start] = STR16; + buffer[start + 1] = unchecked((byte)(cb >> 8)); + buffer[start + 2] = unchecked((byte)cb); + return cursor; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeMap(byte[] buffer, int cursor, IDictionary map) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteArrayHeader(byte[] buffer, int cursor, int length) + { + if (length <= LIMIT_MAX_FIX_ARRAY_LENGTH) { - if (map == null) - { - return SerializeNull(buffer, cursor); - } + buffer[cursor++] = unchecked((byte)(MIN_FIX_ARRAY | length)); + } + else if (length <= ushort.MaxValue) + { + buffer[cursor++] = ARRAY16; + cursor = WriteUInt16(buffer, cursor, unchecked((ushort)length)); + } + else + { + buffer[cursor++] = ARRAY32; + cursor = WriteUInt32(buffer, cursor, unchecked((uint)length)); + } - cursor = WriteMapHeader(buffer, cursor, map.Count); - foreach (var entry in map) - { - cursor = SerializeUnicodeString(buffer, cursor, entry.Key); - cursor = Serialize(buffer, cursor, entry.Value); - } + return cursor; + } - return cursor; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeArray(byte[] buffer, int cursor, T[] array) + { + if (array == null) + { + return SerializeNull(buffer, cursor); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteTimestamp96Header(byte[] buffer, int cursor) + cursor = WriteArrayHeader(buffer, cursor, array.Length); + for (int i = 0; i < array.Length; i++) + { + cursor = Serialize(buffer, cursor, array[i]); + } + + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteMapHeader(byte[] buffer, int cursor, int count) + { + if (count <= LIMIT_MAX_FIX_MAP_COUNT) + { + buffer[cursor++] = unchecked((byte)(MIN_FIX_MAP | count)); + } + else if (count <= ushort.MaxValue) + { + buffer[cursor++] = MAP16; + cursor = WriteUInt16(buffer, cursor, unchecked((ushort)count)); + } + else { - buffer[cursor++] = TIMESTAMP96; - buffer[cursor++] = 12; - buffer[cursor++] = EXT_DATE_TIME; - return cursor; + buffer[cursor++] = MAP32; + cursor = WriteUInt32(buffer, cursor, unchecked((uint)count)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteTimestamp96(byte[] buffer, int cursor, long ticks) + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeMap(byte[] buffer, int cursor, IDictionary map) + { + if (map == null) { - cursor = WriteUInt32(buffer, cursor, unchecked((uint)((ticks % TimeSpan.TicksPerSecond) * 100))); - cursor = WriteInt64(buffer, cursor, (ticks / TimeSpan.TicksPerSecond) - 62135596800L); - return cursor; + return SerializeNull(buffer, cursor); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeTimestamp96(byte[] buffer, int cursor, long ticks) + cursor = WriteMapHeader(buffer, cursor, map.Count); + foreach (var entry in map) { - cursor = WriteTimestamp96Header(buffer, cursor); - cursor = WriteTimestamp96(buffer, cursor, ticks); - return cursor; + cursor = SerializeUnicodeString(buffer, cursor, entry.Key); + cursor = Serialize(buffer, cursor, entry.Value); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUtcDateTime(byte[] buffer, int cursor, DateTime utc) + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteTimestamp96Header(byte[] buffer, int cursor) + { + buffer[cursor++] = TIMESTAMP96; + buffer[cursor++] = 12; + buffer[cursor++] = EXT_DATE_TIME; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteTimestamp96(byte[] buffer, int cursor, long ticks) + { + cursor = WriteUInt32(buffer, cursor, unchecked((uint)((ticks % TimeSpan.TicksPerSecond) * 100))); + cursor = WriteInt64(buffer, cursor, (ticks / TimeSpan.TicksPerSecond) - 62135596800L); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeTimestamp96(byte[] buffer, int cursor, long ticks) + { + cursor = WriteTimestamp96Header(buffer, cursor); + cursor = WriteTimestamp96(buffer, cursor, ticks); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUtcDateTime(byte[] buffer, int cursor, DateTime utc) + { + return SerializeTimestamp96(buffer, cursor, utc.Ticks); + } + + public static int Serialize(byte[] buffer, int cursor, object obj) + { + if (obj == null) { - return SerializeTimestamp96(buffer, cursor, utc.Ticks); + return SerializeNull(buffer, cursor); } - public static int Serialize(byte[] buffer, int cursor, object obj) + switch (obj) { - if (obj == null) - { - return SerializeNull(buffer, cursor); - } + case bool v: + return SerializeBool(buffer, cursor, v); + case byte v: + return SerializeUInt8(buffer, cursor, v); + case sbyte v: + return SerializeInt8(buffer, cursor, v); + case short v: + return SerializeInt16(buffer, cursor, v); + case ushort v: + return SerializeUInt16(buffer, cursor, v); + case int v: + return SerializeInt32(buffer, cursor, v); + case uint v: + return SerializeUInt32(buffer, cursor, v); + case long v: + return SerializeInt64(buffer, cursor, v); + case ulong v: + return SerializeUInt64(buffer, cursor, v); + case float v: + return SerializeFloat32(buffer, cursor, v); + case double v: + return SerializeFloat64(buffer, cursor, v); + case string v: + return SerializeUnicodeString(buffer, cursor, v); + case IDictionary v: + return SerializeMap(buffer, cursor, v); + case object[] v: + return SerializeArray(buffer, cursor, v); + case DateTime v: + return SerializeUtcDateTime(buffer, cursor, v.ToUniversalTime()); + default: + string repr = null; + + try + { + repr = Convert.ToString(obj, CultureInfo.InvariantCulture); + } + catch + { + repr = $"ERROR: type {obj.GetType().FullName} is not supported"; + } - switch (obj) - { - case bool v: - return SerializeBool(buffer, cursor, v); - case byte v: - return SerializeUInt8(buffer, cursor, v); - case sbyte v: - return SerializeInt8(buffer, cursor, v); - case short v: - return SerializeInt16(buffer, cursor, v); - case ushort v: - return SerializeUInt16(buffer, cursor, v); - case int v: - return SerializeInt32(buffer, cursor, v); - case uint v: - return SerializeUInt32(buffer, cursor, v); - case long v: - return SerializeInt64(buffer, cursor, v); - case ulong v: - return SerializeUInt64(buffer, cursor, v); - case float v: - return SerializeFloat32(buffer, cursor, v); - case double v: - return SerializeFloat64(buffer, cursor, v); - case string v: - return SerializeUnicodeString(buffer, cursor, v); - case IDictionary v: - return SerializeMap(buffer, cursor, v); - case object[] v: - return SerializeArray(buffer, cursor, v); - case DateTime v: - return SerializeUtcDateTime(buffer, cursor, v.ToUniversalTime()); - default: - string repr = null; - - try - { - repr = Convert.ToString(obj, CultureInfo.InvariantCulture); - } - catch - { - repr = $"ERROR: type {obj.GetType().FullName} is not supported"; - } - - return SerializeUnicodeString(buffer, cursor, repr); - } + return SerializeUnicodeString(buffer, cursor, repr); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs index a75450221b..59823c46f2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs @@ -17,46 +17,45 @@ using System; using System.Diagnostics.Tracing; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +[EventSource(Name = "OpenTelemetryGenevaMetricExporter", Guid = "{edc24920-e004-40f6-a8e1-0e6e48f39d84}")] +internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport { - [EventSource(Name = "OpenTelemetryGenevaMetricExporter", Guid = "{edc24920-e004-40f6-a8e1-0e6e48f39d84}")] - internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport - { - private readonly int fixedPayloadEndIndex; + private readonly int fixedPayloadEndIndex; - public MetricEtwDataTransport() + public MetricEtwDataTransport() + { + unsafe { - unsafe - { - this.fixedPayloadEndIndex = sizeof(BinaryHeader); - } + this.fixedPayloadEndIndex = sizeof(BinaryHeader); } + } - [NonEvent] - public unsafe void Send(MetricEventType eventType, byte[] data, int size) + [NonEvent] + public unsafe void Send(MetricEventType eventType, byte[] data, int size) + { + var eventDataPtr = stackalloc EventData[1]; + fixed (byte* bufferPtr = data) { - var eventDataPtr = stackalloc EventData[1]; - fixed (byte* bufferPtr = data) - { - eventDataPtr[0].DataPointer = (IntPtr)bufferPtr + this.fixedPayloadEndIndex; - eventDataPtr[0].Size = size; - this.WriteEventCore((int)eventType, 1, eventDataPtr); - } + eventDataPtr[0].DataPointer = (IntPtr)bufferPtr + this.fixedPayloadEndIndex; + eventDataPtr[0].Size = size; + this.WriteEventCore((int)eventType, 1, eventDataPtr); } + } - [Event((int)MetricEventType.ULongMetric)] - private void ULongMetricEvent() - { - } + [Event((int)MetricEventType.ULongMetric)] + private void ULongMetricEvent() + { + } - [Event((int)MetricEventType.DoubleMetric)] - private void DoubleMetricEvent() - { - } + [Event((int)MetricEventType.DoubleMetric)] + private void DoubleMetricEvent() + { + } - [Event((int)MetricEventType.ExternallyAggregatedULongDistributionMetric)] - private void ExternallyAggregatedDoubleDistributionMetric() - { - } + [Event((int)MetricEventType.ExternallyAggregatedULongDistributionMetric)] + private void ExternallyAggregatedDoubleDistributionMetric() + { } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs index 70326352cf..bc9ccf4bac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs @@ -19,310 +19,309 @@ using System.Runtime.InteropServices; using System.Text; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal static class MetricSerializer { - internal static class MetricSerializer + /// + /// Writes the string to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeString(byte[] buffer, ref int bufferIndex, string value) { - /// - /// Writes the string to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeString(byte[] buffer, ref int bufferIndex, string value) - { - if (!string.IsNullOrEmpty(value)) - { - if (bufferIndex + value.Length + sizeof(short) >= buffer.Length) - { - // TODO: What should we do when the data is invalid? - } - -#if NETSTANDARD2_1 - Span bufferSpan = new Span(buffer); - bufferSpan = bufferSpan.Slice(bufferIndex); - Span stringSpan = bufferSpan.Slice(2); - var lengthWritten = (short)Encoding.UTF8.GetBytes(value, stringSpan); - MemoryMarshal.Write(bufferSpan, ref lengthWritten); - bufferIndex += sizeof(short) + lengthWritten; -#else - // Advanced the buffer to account for the length, we will write it back after encoding. - var currentIndex = bufferIndex; - bufferIndex += sizeof(short); - var lengthWritten = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, bufferIndex); - bufferIndex += lengthWritten; - - // Write the length now that it is known - SerializeInt16(buffer, ref currentIndex, (short)lengthWritten); -#endif - } - else - { - SerializeInt16(buffer, ref bufferIndex, 0); - } - } - - /// - /// Writes the encoded string to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The encoded value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeEncodedString(byte[] buffer, ref int bufferIndex, byte[] encodedValue) + if (!string.IsNullOrEmpty(value)) { - if (bufferIndex + encodedValue.Length + sizeof(short) >= buffer.Length) + if (bufferIndex + value.Length + sizeof(short) >= buffer.Length) { // TODO: What should we do when the data is invalid? } #if NETSTANDARD2_1 - Span sourceSpan = new Span(encodedValue); Span bufferSpan = new Span(buffer); bufferSpan = bufferSpan.Slice(bufferIndex); - sourceSpan.CopyTo(bufferSpan.Slice(2)); - short encodedLength = (short)encodedValue.Length; - MemoryMarshal.Write(bufferSpan, ref encodedLength); - bufferIndex += sizeof(short) + encodedLength; + Span stringSpan = bufferSpan.Slice(2); + var lengthWritten = (short)Encoding.UTF8.GetBytes(value, stringSpan); + MemoryMarshal.Write(bufferSpan, ref lengthWritten); + bufferIndex += sizeof(short) + lengthWritten; #else - SerializeInt16(buffer, ref bufferIndex, (short)encodedValue.Length); - Array.Copy(encodedValue, 0, buffer, bufferIndex, encodedValue.Length); - bufferIndex += encodedValue.Length; + // Advanced the buffer to account for the length, we will write it back after encoding. + var currentIndex = bufferIndex; + bufferIndex += sizeof(short); + var lengthWritten = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, bufferIndex); + bufferIndex += lengthWritten; + + // Write the length now that it is known + SerializeInt16(buffer, ref currentIndex, (short)lengthWritten); #endif } - - /// - /// Writes the byte to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeByte(byte[] buffer, ref int bufferIndex, byte value) + else { - if (bufferIndex + sizeof(byte) >= buffer.Length) - { - // TODO: What should we do when the data is invalid? - } - - buffer[bufferIndex] = value; - bufferIndex += sizeof(byte); + SerializeInt16(buffer, ref bufferIndex, 0); } + } - /// - /// Writes the unsigned short to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeUInt16(byte[] buffer, ref int bufferIndex, ushort value) + /// + /// Writes the encoded string to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The encoded value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeEncodedString(byte[] buffer, ref int bufferIndex, byte[] encodedValue) + { + if (bufferIndex + encodedValue.Length + sizeof(short) >= buffer.Length) { - if (bufferIndex + sizeof(ushort) >= buffer.Length) - { - // TODO: What should we do when the data is invalid? - } - - buffer[bufferIndex] = (byte)value; - buffer[bufferIndex + 1] = (byte)(value >> 8); - bufferIndex += sizeof(ushort); + // TODO: What should we do when the data is invalid? } - /// - /// Writes the short to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeInt16(byte[] buffer, ref int bufferIndex, short value) - { - if (bufferIndex + sizeof(short) >= buffer.Length) - { - // TODO: What should we do when the data is invalid? - } - - buffer[bufferIndex] = (byte)value; - buffer[bufferIndex + 1] = (byte)(value >> 8); - bufferIndex += sizeof(short); - } +#if NETSTANDARD2_1 + Span sourceSpan = new Span(encodedValue); + Span bufferSpan = new Span(buffer); + bufferSpan = bufferSpan.Slice(bufferIndex); + sourceSpan.CopyTo(bufferSpan.Slice(2)); + short encodedLength = (short)encodedValue.Length; + MemoryMarshal.Write(bufferSpan, ref encodedLength); + bufferIndex += sizeof(short) + encodedLength; +#else + SerializeInt16(buffer, ref bufferIndex, (short)encodedValue.Length); + Array.Copy(encodedValue, 0, buffer, bufferIndex, encodedValue.Length); + bufferIndex += encodedValue.Length; +#endif + } - /// - /// Writes the unsigned int to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeUInt32(byte[] buffer, ref int bufferIndex, uint value) + /// + /// Writes the byte to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeByte(byte[] buffer, ref int bufferIndex, byte value) + { + if (bufferIndex + sizeof(byte) >= buffer.Length) { - if (bufferIndex + sizeof(uint) >= buffer.Length) - { - // TODO: What should we do when the data is invalid? - } - - buffer[bufferIndex] = (byte)value; - buffer[bufferIndex + 1] = (byte)(value >> 8); - buffer[bufferIndex + 2] = (byte)(value >> 0x10); - buffer[bufferIndex + 3] = (byte)(value >> 0x18); - bufferIndex += sizeof(uint); + // TODO: What should we do when the data is invalid? } - /// - /// Writes the ulong to buffer. - /// - /// The buffer. - /// Index of the buffer. - /// The value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeUInt64(byte[] buffer, ref int bufferIndex, ulong value) - { - if (bufferIndex + sizeof(ulong) >= buffer.Length) - { - // TODO: What should we do when the data is invalid? - } - - buffer[bufferIndex] = (byte)value; - buffer[bufferIndex + 1] = (byte)(value >> 8); - buffer[bufferIndex + 2] = (byte)(value >> 0x10); - buffer[bufferIndex + 3] = (byte)(value >> 0x18); - buffer[bufferIndex + 4] = (byte)(value >> 0x20); - buffer[bufferIndex + 5] = (byte)(value >> 0x28); - buffer[bufferIndex + 6] = (byte)(value >> 0x30); - buffer[bufferIndex + 7] = (byte)(value >> 0x38); - bufferIndex += sizeof(ulong); - } + buffer[bufferIndex] = value; + bufferIndex += sizeof(byte); } - internal enum MetricEventType + /// + /// Writes the unsigned short to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt16(byte[] buffer, ref int bufferIndex, ushort value) { - ULongMetric = 50, - DoubleMetric = 55, - ExternallyAggregatedULongDistributionMetric = 56, + if (bufferIndex + sizeof(ushort) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + bufferIndex += sizeof(ushort); } /// - /// Represents the binary header for non-ETW transmitted metrics. + /// Writes the short to buffer. /// - [StructLayout(LayoutKind.Explicit)] - internal struct BinaryHeader + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeInt16(byte[] buffer, ref int bufferIndex, short value) { - /// - /// The event ID that represents how it will be processed. - /// - [FieldOffset(0)] - public ushort EventId; - - /// - /// The length of the body following the header. - /// - [FieldOffset(2)] - public ushort BodyLength; + if (bufferIndex + sizeof(short) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + bufferIndex += sizeof(short); } /// - /// Represents the fixed payload of a standard metric. + /// Writes the unsigned int to buffer. /// - [StructLayout(LayoutKind.Explicit)] - internal struct MetricPayload + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt32(byte[] buffer, ref int bufferIndex, uint value) { - /// - /// The dimension count. - /// - [FieldOffset(0)] - public ushort CountDimension; - - /// - /// Reserved for alignment. - /// - [FieldOffset(2)] - public ushort ReservedWord; // for 8-byte aligned - - /// - /// Reserved for alignment. - /// - [FieldOffset(4)] - public uint ReservedDword; - - /// - /// The UTC timestamp of the metric. - /// - [FieldOffset(8)] - public ulong TimestampUtc; - - /// - /// The value of the metric. - /// - [FieldOffset(16)] - public MetricData Data; + if (bufferIndex + sizeof(uint) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + buffer[bufferIndex + 2] = (byte)(value >> 0x10); + buffer[bufferIndex + 3] = (byte)(value >> 0x18); + bufferIndex += sizeof(uint); } /// - /// Represents the fixed payload of an externally aggregated metric. + /// Writes the ulong to buffer. /// - [StructLayout(LayoutKind.Explicit)] - internal struct ExternalPayload + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt64(byte[] buffer, ref int bufferIndex, ulong value) { - /// - /// The dimension count. - /// - [FieldOffset(0)] - public ushort CountDimension; - - /// - /// Reserved for alignment. - /// - [FieldOffset(2)] - public ushort ReservedWord; // for alignment - - /// - /// The number of samples produced in the period. - /// - [FieldOffset(4)] - public uint Count; - - /// - /// The UTC timestamp of the metric. - /// - [FieldOffset(8)] - public ulong TimestampUtc; - - /// - /// The sum of the samples produced in the period. - /// - [FieldOffset(16)] - public MetricData Sum; - - /// - /// The minimum value of the samples produced in the period. - /// - [FieldOffset(24)] - public MetricData Min; - - /// - /// The maximum value of the samples produced in the period. - /// - [FieldOffset(32)] - public MetricData Max; + if (bufferIndex + sizeof(ulong) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + buffer[bufferIndex + 2] = (byte)(value >> 0x10); + buffer[bufferIndex + 3] = (byte)(value >> 0x18); + buffer[bufferIndex + 4] = (byte)(value >> 0x20); + buffer[bufferIndex + 5] = (byte)(value >> 0x28); + buffer[bufferIndex + 6] = (byte)(value >> 0x30); + buffer[bufferIndex + 7] = (byte)(value >> 0x38); + bufferIndex += sizeof(ulong); } +} + +internal enum MetricEventType +{ + ULongMetric = 50, + DoubleMetric = 55, + ExternallyAggregatedULongDistributionMetric = 56, +} +/// +/// Represents the binary header for non-ETW transmitted metrics. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct BinaryHeader +{ /// - /// Represents the value of a metric. + /// The event ID that represents how it will be processed. /// - [StructLayout(LayoutKind.Explicit)] - internal struct MetricData - { - /// - /// The value represented as an integer. - /// - [FieldOffset(0)] - public ulong UInt64Value; - - /// - /// The value represented as a double. - /// - [FieldOffset(0)] - public double DoubleValue; - } + [FieldOffset(0)] + public ushort EventId; + + /// + /// The length of the body following the header. + /// + [FieldOffset(2)] + public ushort BodyLength; +} + +/// +/// Represents the fixed payload of a standard metric. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct MetricPayload +{ + /// + /// The dimension count. + /// + [FieldOffset(0)] + public ushort CountDimension; + + /// + /// Reserved for alignment. + /// + [FieldOffset(2)] + public ushort ReservedWord; // for 8-byte aligned + + /// + /// Reserved for alignment. + /// + [FieldOffset(4)] + public uint ReservedDword; + + /// + /// The UTC timestamp of the metric. + /// + [FieldOffset(8)] + public ulong TimestampUtc; + + /// + /// The value of the metric. + /// + [FieldOffset(16)] + public MetricData Data; +} + +/// +/// Represents the fixed payload of an externally aggregated metric. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct ExternalPayload +{ + /// + /// The dimension count. + /// + [FieldOffset(0)] + public ushort CountDimension; + + /// + /// Reserved for alignment. + /// + [FieldOffset(2)] + public ushort ReservedWord; // for alignment + + /// + /// The number of samples produced in the period. + /// + [FieldOffset(4)] + public uint Count; + + /// + /// The UTC timestamp of the metric. + /// + [FieldOffset(8)] + public ulong TimestampUtc; + + /// + /// The sum of the samples produced in the period. + /// + [FieldOffset(16)] + public MetricData Sum; + + /// + /// The minimum value of the samples produced in the period. + /// + [FieldOffset(24)] + public MetricData Min; + + /// + /// The maximum value of the samples produced in the period. + /// + [FieldOffset(32)] + public MetricData Max; +} + +/// +/// Represents the value of a metric. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct MetricData +{ + /// + /// The value represented as an integer. + /// + [FieldOffset(0)] + public ulong UInt64Value; + + /// + /// The value represented as a double. + /// + [FieldOffset(0)] + public double DoubleValue; } diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs index 2dac515e4e..abd966485a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs @@ -14,40 +14,39 @@ // limitations under the License. // -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal sealed class MetricUnixDataTransport : IMetricDataTransport { - internal sealed class MetricUnixDataTransport : IMetricDataTransport - { - private readonly int fixedPayloadLength; - private readonly UnixDomainSocketDataTransport udsDataTransport; - private bool isDisposed; + private readonly int fixedPayloadLength; + private readonly UnixDomainSocketDataTransport udsDataTransport; + private bool isDisposed; - public MetricUnixDataTransport( - string unixDomainSocketPath, - int timeoutMilliseconds = UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds) + public MetricUnixDataTransport( + string unixDomainSocketPath, + int timeoutMilliseconds = UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds) + { + unsafe { - unsafe - { - this.fixedPayloadLength = sizeof(BinaryHeader); - } - - this.udsDataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath, timeoutMilliseconds); + this.fixedPayloadLength = sizeof(BinaryHeader); } - public void Send(MetricEventType eventType, byte[] body, int size) - { - this.udsDataTransport.Send(body, size + this.fixedPayloadLength); - } + this.udsDataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath, timeoutMilliseconds); + } - public void Dispose() - { - if (this.isDisposed) - { - return; - } + public void Send(MetricEventType eventType, byte[] body, int size) + { + this.udsDataTransport.Send(body, size + this.fixedPayloadLength); + } - this.udsDataTransport?.Dispose(); - this.isDisposed = true; + public void Dispose() + { + if (this.isDisposed) + { + return; } + + this.udsDataTransport?.Dispose(); + this.isDisposed = true; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs index 8022d3dd91..95b2163370 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs @@ -18,35 +18,34 @@ using System.Linq.Expressions; using System.Reflection; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +// This export processor exports without synchronization. +// Once OpenTelemetry .NET officially support this, +// we can get rid of this class. +// This is currently only used in ETW export, where we know +// that the underlying system is safe under concurrent calls. +internal class ReentrantExportProcessor : BaseExportProcessor + where T : class { - // This export processor exports without synchronization. - // Once OpenTelemetry .NET officially support this, - // we can get rid of this class. - // This is currently only used in ETW export, where we know - // that the underlying system is safe under concurrent calls. - internal class ReentrantExportProcessor : BaseExportProcessor - where T : class + static ReentrantExportProcessor() { - static ReentrantExportProcessor() - { - var flags = BindingFlags.Instance | BindingFlags.NonPublic; - var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); - var value = Expression.Parameter(typeof(T), null); - var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); - CreateBatch = lambda.Compile(); - } - - public ReentrantExportProcessor(BaseExporter exporter) - : base(exporter) - { - } + var flags = BindingFlags.Instance | BindingFlags.NonPublic; + var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); + var value = Expression.Parameter(typeof(T), null); + var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); + CreateBatch = lambda.Compile(); + } - protected override void OnExport(T data) - { - this.exporter.Export(CreateBatch(data)); - } + public ReentrantExportProcessor(BaseExporter exporter) + : base(exporter) + { + } - private static readonly Func> CreateBatch; + protected override void OnExport(T data) + { + this.exporter.Export(CreateBatch(data)); } + + private static readonly Func> CreateBatch; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Schema.cs index 29eec11d07..7217d6aa7f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Schema.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Schema.cs @@ -14,88 +14,87 @@ // limitations under the License. // -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal static class Schema { - internal static class Schema + internal static class V21 { - internal static class V21 + internal static class PartA { - internal static class PartA - { - internal const string IKey = ".iKey"; - internal const string Name = ".name"; - internal const string Ver = ".ver"; - internal const string Time = ".time"; - internal const string Cv = ".cv"; - internal const string Epoch = ".epoch"; - internal const string Flags = ".flags"; - internal const string PopSample = ".popSample"; - internal const string SeqNum = ".seqNum"; + internal const string IKey = ".iKey"; + internal const string Name = ".name"; + internal const string Ver = ".ver"; + internal const string Time = ".time"; + internal const string Cv = ".cv"; + internal const string Epoch = ".epoch"; + internal const string Flags = ".flags"; + internal const string PopSample = ".popSample"; + internal const string SeqNum = ".seqNum"; - internal static class Extensions + internal static class Extensions + { + internal static class App { - internal static class App - { - internal const string Id = "app.id"; - internal const string Ver = "app.ver"; - } + internal const string Id = "app.id"; + internal const string Ver = "app.ver"; + } - internal static class Cloud - { - internal const string Environment = "cloud.environment"; - internal const string Location = "cloud.location"; - internal const string Name = "cloud.name"; - internal const string DeploymentUnit = "cloud.deploymentUnit"; - internal const string Role = "cloud.role"; - internal const string RoleInstance = "cloud.roleInstance"; - internal const string RoleVer = "cloud.roleVer"; - internal const string Ver = "cloud.ver"; - } + internal static class Cloud + { + internal const string Environment = "cloud.environment"; + internal const string Location = "cloud.location"; + internal const string Name = "cloud.name"; + internal const string DeploymentUnit = "cloud.deploymentUnit"; + internal const string Role = "cloud.role"; + internal const string RoleInstance = "cloud.roleInstance"; + internal const string RoleVer = "cloud.roleVer"; + internal const string Ver = "cloud.ver"; + } - internal static class Os - { - internal const string Name = "os.name"; - internal const string Ver = "os.ver"; - } + internal static class Os + { + internal const string Name = "os.name"; + internal const string Ver = "os.ver"; } } } + } - internal static class V40 + internal static class V40 + { + internal static class PartA { - internal static class PartA - { - internal const string IKey = ".iKey"; - internal const string Name = ".name"; - internal const string Ver = ".ver"; - internal const string Time = ".time"; + internal const string IKey = ".iKey"; + internal const string Name = ".name"; + internal const string Ver = ".ver"; + internal const string Time = ".time"; - internal static class Extensions + internal static class Extensions + { + internal static class App { - internal static class App - { - internal const string Id = "app.id"; - internal const string Ver = "app.ver"; - } + internal const string Id = "app.id"; + internal const string Ver = "app.ver"; + } - internal static class Cloud - { - internal const string Role = "cloud.role"; - internal const string RoleInstance = "cloud.roleInstance"; - internal const string RoleVer = "cloud.roleVer"; - } + internal static class Cloud + { + internal const string Role = "cloud.role"; + internal const string RoleInstance = "cloud.roleInstance"; + internal const string RoleVer = "cloud.roleVer"; + } - internal static class Os - { - internal const string Name = "os.name"; - internal const string Ver = "os.ver"; - } + internal static class Os + { + internal const string Name = "os.name"; + internal const string Ver = "os.ver"; + } - internal static class Dt - { - internal const string TraceId = "dt.traceId"; - internal const string SpanId = "dt.spanId"; - } + internal static class Dt + { + internal const string TraceId = "dt.traceId"; + internal const string SpanId = "dt.spanId"; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs index 7cb285b5b2..65bad6b89b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs @@ -18,30 +18,29 @@ using Microsoft.Extensions.Options; #endif -namespace System +namespace System; + +/// +/// Extension methods for OpenTelemetry dependency injection support. +/// +internal static class ServiceProviderExtensions { /// - /// Extension methods for OpenTelemetry dependency injection support. + /// Get options from the supplied . /// - internal static class ServiceProviderExtensions + /// Options type. + /// . + /// Options instance. + public static T GetOptions(this IServiceProvider serviceProvider) + where T : class, new() { - /// - /// Get options from the supplied . - /// - /// Options type. - /// . - /// Options instance. - public static T GetOptions(this IServiceProvider serviceProvider) - where T : class, new() - { #if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER - IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); + IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); - // Note: options could be null if user never invoked services.AddOptions(). - return options?.Value ?? new T(); + // Note: options could be null if user never invoked services.AddOptions(). + return options?.Value ?? new T(); #else - return new T(); + return new T(); #endif - } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs index 0ae3c1963d..b0a06fa393 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs @@ -18,92 +18,91 @@ using System.Net; using System.Net.Sockets; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal class UnixDomainSocketDataTransport : IDataTransport, IDisposable { - internal class UnixDomainSocketDataTransport : IDataTransport, IDisposable - { - public const int DefaultTimeoutMilliseconds = 15000; - private readonly EndPoint unixEndpoint; - private Socket socket; - private int timeoutMilliseconds; + public const int DefaultTimeoutMilliseconds = 15000; + private readonly EndPoint unixEndpoint; + private Socket socket; + private int timeoutMilliseconds; - /// - /// Initializes a new instance of the class. - /// The class for transporting data over Unix domain socket. - /// - /// The path to connect a unix domain socket over. - /// - /// The time-out value, in milliseconds. - /// If you set the property with a value between 1 and 499, the value will be changed to 500. - /// The default value is 15,000 milliseconds. - /// - public UnixDomainSocketDataTransport( - string unixDomainSocketPath, - int timeoutMilliseconds = DefaultTimeoutMilliseconds) - { - this.unixEndpoint = new UnixDomainSocketEndPoint(unixDomainSocketPath); - this.timeoutMilliseconds = timeoutMilliseconds; - this.Connect(); - } + /// + /// Initializes a new instance of the class. + /// The class for transporting data over Unix domain socket. + /// + /// The path to connect a unix domain socket over. + /// + /// The time-out value, in milliseconds. + /// If you set the property with a value between 1 and 499, the value will be changed to 500. + /// The default value is 15,000 milliseconds. + /// + public UnixDomainSocketDataTransport( + string unixDomainSocketPath, + int timeoutMilliseconds = DefaultTimeoutMilliseconds) + { + this.unixEndpoint = new UnixDomainSocketEndPoint(unixDomainSocketPath); + this.timeoutMilliseconds = timeoutMilliseconds; + this.Connect(); + } - public bool IsEnabled() - { - return true; - } + public bool IsEnabled() + { + return true; + } - public void Send(byte[] data, int size) + public void Send(byte[] data, int size) + { + try { - try - { - if (!this.socket.Connected) - { - // Socket connection is off! Server might have stopped. Trying to reconnect. - this.Reconnect(); - } - - this.socket.Send(data, size, SocketFlags.None); - } - catch (SocketException ex) - { - // SocketException from Socket.Send - ExporterEventSource.Log.ExporterException(ex); - } - catch (Exception ex) + if (!this.socket.Connected) { - ExporterEventSource.Log.ExporterException(ex); + // Socket connection is off! Server might have stopped. Trying to reconnect. + this.Reconnect(); } - } - public void Dispose() + this.socket.Send(data, size, SocketFlags.None); + } + catch (SocketException ex) + { + // SocketException from Socket.Send + ExporterEventSource.Log.ExporterException(ex); + } + catch (Exception ex) { - this.socket.Dispose(); + ExporterEventSource.Log.ExporterException(ex); } + } - private void Connect() + public void Dispose() + { + this.socket.Dispose(); + } + + private void Connect() + { + try { - try + this.socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) { - this.socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) - { - SendTimeout = this.timeoutMilliseconds, - }; - this.socket.Connect(this.unixEndpoint); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException(ex); - - // Re-throw the exception to - // 1. fail fast in Geneva exporter contructor, or - // 2. fail in the Reconnect attempt. - throw; - } + SendTimeout = this.timeoutMilliseconds, + }; + this.socket.Connect(this.unixEndpoint); } - - private void Reconnect() + catch (Exception ex) { - this.socket.Close(); - this.Connect(); + ExporterEventSource.Log.ExporterException(ex); + + // Re-throw the exception to + // 1. fail fast in Geneva exporter contructor, or + // 2. fail in the Reconnect attempt. + throw; } } + + private void Reconnect() + { + this.socket.Close(); + this.Connect(); + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs index 2694087fec..4886b76677 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs @@ -19,77 +19,76 @@ using System.Net.Sockets; using System.Text; -namespace OpenTelemetry.Exporter.Geneva +namespace OpenTelemetry.Exporter.Geneva; + +internal class UnixDomainSocketEndPoint : EndPoint { - internal class UnixDomainSocketEndPoint : EndPoint - { - // sockaddr_un.sun_path at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html, -1 for terminator - private const int MaximumNativePathLength = 92 - 1; + // sockaddr_un.sun_path at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html, -1 for terminator + private const int MaximumNativePathLength = 92 - 1; - // The first 2 bytes of the underlying buffer are reserved for the AddressFamily enumerated value. - // https://docs.microsoft.com/dotnet/api/system.net.socketaddress - private const int NativePathOffset = 2; - private readonly string path; - private readonly byte[] nativePath; + // The first 2 bytes of the underlying buffer are reserved for the AddressFamily enumerated value. + // https://docs.microsoft.com/dotnet/api/system.net.socketaddress + private const int NativePathOffset = 2; + private readonly string path; + private readonly byte[] nativePath; - public UnixDomainSocketEndPoint(string path) + public UnixDomainSocketEndPoint(string path) + { + this.path = path ?? throw new ArgumentNullException(nameof(path), "Path cannot be null."); + this.nativePath = Encoding.UTF8.GetBytes(path); + if (this.nativePath.Length == 0 || this.nativePath.Length > MaximumNativePathLength) { - this.path = path ?? throw new ArgumentNullException(nameof(path), "Path cannot be null."); - this.nativePath = Encoding.UTF8.GetBytes(path); - if (this.nativePath.Length == 0 || this.nativePath.Length > MaximumNativePathLength) - { - throw new ArgumentOutOfRangeException(nameof(this.nativePath), "Path is of an invalid length for use with domain sockets."); - } + throw new ArgumentOutOfRangeException(nameof(this.nativePath), "Path is of an invalid length for use with domain sockets."); } + } - public override AddressFamily AddressFamily => AddressFamily.Unix; + public override AddressFamily AddressFamily => AddressFamily.Unix; - public override EndPoint Create(SocketAddress socketAddress) => new UnixDomainSocketEndPoint(socketAddress); + public override EndPoint Create(SocketAddress socketAddress) => new UnixDomainSocketEndPoint(socketAddress); - private UnixDomainSocketEndPoint(SocketAddress socketAddress) + private UnixDomainSocketEndPoint(SocketAddress socketAddress) + { + if (socketAddress == null) { - if (socketAddress == null) - { - throw new ArgumentNullException(nameof(socketAddress), "SocketAddress cannot be null."); - } - - if (socketAddress.Family != this.AddressFamily || - socketAddress.Size > NativePathOffset + MaximumNativePathLength) - { - throw new ArgumentOutOfRangeException( - nameof(socketAddress), - "The path of SocketAddress is of an invalid length for use with domain sockets."); - } - - if (socketAddress.Size > NativePathOffset) - { - this.nativePath = new byte[socketAddress.Size - NativePathOffset]; - for (int i = 0; i < this.nativePath.Length; ++i) - { - this.nativePath[i] = socketAddress[NativePathOffset + i]; - } + throw new ArgumentNullException(nameof(socketAddress), "SocketAddress cannot be null."); + } - this.path = Encoding.UTF8.GetString(this.nativePath); - } - else - { - this.path = string.Empty; - this.nativePath = Array.Empty(); - } + if (socketAddress.Family != this.AddressFamily || + socketAddress.Size > NativePathOffset + MaximumNativePathLength) + { + throw new ArgumentOutOfRangeException( + nameof(socketAddress), + "The path of SocketAddress is of an invalid length for use with domain sockets."); } - public override SocketAddress Serialize() + if (socketAddress.Size > NativePathOffset) { - var socketAddress = new SocketAddress(AddressFamily.Unix, NativePathOffset + this.nativePath.Length + 1); + this.nativePath = new byte[socketAddress.Size - NativePathOffset]; for (int i = 0; i < this.nativePath.Length; ++i) { - socketAddress[NativePathOffset + i] = this.nativePath[i]; + this.nativePath[i] = socketAddress[NativePathOffset + i]; } - socketAddress[NativePathOffset + this.nativePath.Length] = 0; // SocketAddress should be NULL terminated - return socketAddress; + this.path = Encoding.UTF8.GetString(this.nativePath); + } + else + { + this.path = string.Empty; + this.nativePath = Array.Empty(); + } + } + + public override SocketAddress Serialize() + { + var socketAddress = new SocketAddress(AddressFamily.Unix, NativePathOffset + this.nativePath.Length + 1); + for (int i = 0; i < this.nativePath.Length; ++i) + { + socketAddress[NativePathOffset + i] = this.nativePath[i]; } - public override string ToString() => this.path; + socketAddress[NativePathOffset + this.nativePath.Length] = 0; // SocketAddress should be NULL terminated + return socketAddress; } + + public override string ToString() => this.path; } From 5aa5544d458f3a7d6f83bf1737e55afa99f43f8d Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 14 Apr 2022 19:21:54 -0700 Subject: [PATCH 0084/1499] Cleanup versions and paths in csproj (#310) * use same xunit versions for geneva tests * use RepoRoot in csproj files instead of relative parents Co-authored-by: Cijo Thomas --- .../OpenTelemetry.Extensions.csproj | 2 +- .../OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj | 2 +- ...OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj | 2 +- ...lemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 8 ++++---- ...penTelemetry.Extensions.PersistentStorage.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index f3495982c1..652aa900a4 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -11,7 +11,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index 77bc21337e..f596591539 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 749b9e88a7..606c7d0ebf 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -21,7 +21,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj index 12fa941744..d0e6393e60 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 2555bf258c..c39a2dfb36 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -15,7 +15,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 08747551f0..ab98c9d102 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -12,7 +12,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index fdf3968094..f6271a99de 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -20,12 +20,12 @@ - - + + all runtime; build; native; contentfiles; analyzers - + @@ -34,7 +34,7 @@ - + diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj index 144388bfaa..a36fa8e080 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index aa2b6763b0..41ebffb234 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -21,6 +21,6 @@ - + From cb4a35455ed8b846cf0c73972802fa70b0eb30af Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 14 Apr 2022 22:40:09 -0700 Subject: [PATCH 0085/1499] Add release workflow for Extensions (#311) --- .../workflows/{package-Preview.yml => package-Extensions.yml} | 0 opentelemetry-dotnet-contrib.sln | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{package-Preview.yml => package-Extensions.yml} (100%) diff --git a/.github/workflows/package-Preview.yml b/.github/workflows/package-Extensions.yml similarity index 100% rename from .github/workflows/package-Preview.yml rename to .github/workflows/package-Extensions.yml diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ec5bb67c99..7983ccc0bf 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -33,6 +33,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml + .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml @@ -44,7 +45,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml - .github\workflows\package-Preview.yml = .github\workflows\package-Preview.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml EndProjectSection From faaa8b56eae0196754ec1162d4cc7a8253d45baa Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Fri, 15 Apr 2022 17:24:12 -0700 Subject: [PATCH 0086/1499] Update opentelemetry-dotnet-contrib.sln (#312) --- opentelemetry-dotnet-contrib.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7983ccc0bf..9546ca8ca5 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -30,6 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml + .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml From 716d2397b116be15e4dfdd5bd00f55d27951171d Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 18 Apr 2022 16:31:33 -0700 Subject: [PATCH 0087/1499] Remove unnecessary using statements + add rule (#313) * use same xunit versions for geneva tests * use RepoRoot in csproj files instead of relative parents * not needed usings Co-authored-by: Cijo Thomas --- .editorconfig | 1 + build/Common.props | 1 + .../TracerProviderBuilderExtensions.cs | 1 - .../ElasticsearchRequestPipelineDiagnosticListener.cs | 1 - .../Implementation/EntityFrameworkDiagnosticListener.cs | 1 - .../MySqlDataInstrumentationOptions.cs | 6 ------ .../OwinInstrumentationOptions.cs | 1 - src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs | 2 ++ .../TelemetryServiceBehavior.cs | 2 ++ 9 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.editorconfig b/.editorconfig index 780eab4f78..4f0400c633 100644 --- a/.editorconfig +++ b/.editorconfig @@ -64,6 +64,7 @@ dotnet_naming_symbols.constant_fields.required_modifiers = const # C# Coding Conventions # ############################### [*.cs] +dotnet_diagnostic.IDE0005.severity = warning # var preferences csharp_style_var_for_built_in_types = true:silent csharp_style_var_when_type_is_apparent = true:silent diff --git a/build/Common.props b/build/Common.props index 4689562849..410363d97f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -5,6 +5,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) $(MSBuildThisFileDirectory)debug.snk $(DefineConstants);SIGNED + true diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index 54edb3271d..935911460f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -15,7 +15,6 @@ // using System; -using System.Diagnostics; using OpenTelemetry.Contrib.Exporter.Stackdriver; namespace OpenTelemetry.Trace diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 5635344e8d..2d1bf5dc27 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -24,7 +24,6 @@ using System.Text; using System.Text.Json; using System.Text.RegularExpressions; -using OpenTelemetry.Instrumentation; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 1523802031..a66da55651 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -17,7 +17,6 @@ using System; using System.Data; using System.Diagnostics; -using OpenTelemetry.Instrumentation; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs index 891f7bcfd6..1ee9760218 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs @@ -14,12 +14,6 @@ // limitations under the License. // -using System; -using System.Collections.Concurrent; -using System.Data; -using System.Diagnostics; -using System.Text.RegularExpressions; - using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.MySqlData diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index a127ee1ac0..74e3df5f45 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -17,7 +17,6 @@ using System; using System.Diagnostics; using Microsoft.Owin; -using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Instrumentation.Owin { diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index e42dfc7a68..426ba225aa 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -19,7 +19,9 @@ using System.Diagnostics; using System.Diagnostics.Metrics; using System.Reflection; +#if NETCOREAPP3_1_OR_GREATER using System.Threading; +#endif namespace OpenTelemetry.Instrumentation.Runtime { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs index 2971ef77c5..d0f964917a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -14,9 +14,11 @@ // limitations under the License. // +#pragma warning disable IDE0005 // Using directive is unnecessary. using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation.Wcf { From e7b00646b99401df2a0d6126066568fcc49cec25 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Wed, 20 Apr 2022 09:49:27 -0700 Subject: [PATCH 0088/1499] Don't skip remaining tests in the CI even if one fails (#317) * Don't fail fast on CI * Don't fail fast on CI --- .github/workflows/linux-ci.yml | 1 + .github/workflows/windows-ci.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index a58189cfac..e369e8343f 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -15,6 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: version: [netcoreapp3.1,net5.0,net6.0] diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index b95be5f955..f5ee113db5 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -15,6 +15,7 @@ jobs: runs-on: windows-latest strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: version: [net461,netcoreapp3.1,net5.0,net6.0] From f84d4cf8df71d35a812fca16a546023595411894 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 20 Apr 2022 12:26:34 -0700 Subject: [PATCH 0089/1499] Geneva package workflow only run tests on windows (#318) --- .github/workflows/package-Exporter.Geneva.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index c768599ac0..03f1377489 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -33,7 +33,7 @@ jobs: run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests + run: dotnet test test/${{env.PROJECT}}.Tests --filter "Platform=Any|Platform=Windows" - name: dotnet pack ${{env.PROJECT}} run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build From 366acf55bf741296182fb3be46a314ba84ee8ab1 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 20 Apr 2022 12:39:52 -0700 Subject: [PATCH 0090/1499] Geneva Exporter Release v1.2.4 (#316) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 15558c1018..613163791a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 1.2.4 [2022-Apr-20] + +This is the first release of the `OpenTelemetry.Exporter.Geneva` +project. + * LogExporter modified to stop calling `ToString()` on `LogRecord.State` to obtain Log body. It now obtains body from `LogRecord.FormattedMessage` From 1fffa1e265019bf03a7d1361fe46c8c2fb88dbba Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 20 Apr 2022 13:38:15 -0700 Subject: [PATCH 0091/1499] Geneva Exporter - Update OTel SDK to 1.2.0 (#319) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 613163791a..ea125f79aa 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.2.0`. +[319](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/319) + ## 1.2.4 [2022-Apr-20] This is the first release of the `OpenTelemetry.Exporter.Geneva` diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index ed6f827edf..389ab89098 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + From 9e4c83668d7ec01f5edf10890c497152414c8637 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 20 Apr 2022 19:18:54 -0700 Subject: [PATCH 0092/1499] Geneva Exporter to use OTel 1.2.0 new release (#321) * use same xunit versions for geneva tests * use RepoRoot in csproj files instead of relative parents * changelog update Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index ea125f79aa..d074d7b155 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,13 +2,17 @@ ## Unreleased +## 1.2.5 [2022-Apr-20] + * Update OTel SDK version to `1.2.0`. [319](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/319) -## 1.2.4 [2022-Apr-20] +## 1.2.4 [2022-Apr-20] Broken This is the first release of the `OpenTelemetry.Exporter.Geneva` project. +Note: This release was broken due to using OpenTelemetry 1.2.0-rc5. +Therefore, it has been unlisted on NuGet. * LogExporter modified to stop calling `ToString()` on `LogRecord.State` to obtain Log body. It now From 5393454ca0c3898089388788c732b726f51563d9 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 20 Apr 2022 19:41:13 -0700 Subject: [PATCH 0093/1499] Add Guard exception throwing helper class (#307) --- .../AWSXRayIdGenerator.cs | 6 +- ...elemetry.Contrib.Extensions.AWSXRay.csproj | 4 + .../Resources/ResourceBuilderExtensions.cs | 7 +- .../TracerProviderBuilderExtensions.cs | 12 +- ...lemetry.Contrib.Instrumentation.AWS.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 6 +- ...y.Contrib.Instrumentation.AWSLambda.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 7 +- .../DiagnosticSourceListener.cs | 5 +- .../DiagnosticSourceSubscriber.cs | 5 +- .../OpenTelemetry.Contrib.Shared.csproj | 4 + .../ConnectionStringBuilder.cs | 6 +- .../GenevaExporterHelperExtensions.cs | 6 +- .../GenevaExporterOptions.cs | 6 +- .../GenevaLogExporter.cs | 12 +- .../GenevaLoggingExtensions.cs | 6 +- .../GenevaMetricExporter.cs | 12 +- .../GenevaMetricExporterExtensions.cs | 6 +- .../GenevaMetricExporterOptions.cs | 6 +- .../GenevaTraceExporter.cs | 12 +- .../OpenTelemetry.Exporter.Geneva.csproj | 4 + .../UnixDomainSocketEndPoint.cs | 10 +- .../OpenTelemetry.Exporter.Stackdriver.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 7 +- .../ApplicationInsightsSampler.cs | 7 +- ...enTelemetry.Extensions.AzureMonitor.csproj | 4 + .../FileStorage.cs | 6 +- ...emetry.Extensions.PersistentStorage.csproj | 4 + .../ActivityEventAttachingLogProcessor.cs | 5 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 6 +- .../OpenTelemetry.Extensions.csproj | 1 + ...Instrumentation.ElasticsearchClient.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 6 +- ...Instrumentation.EntityFrameworkCore.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 6 +- .../ClientTracingInterceptor.cs | 5 +- ...nTelemetry.Instrumentation.GrpcCore.csproj | 4 + .../ServerTracingInterceptor.cs | 5 +- .../TracerProviderBuilderExtensions.cs | 7 +- ...nTelemetry.Instrumentation.Hangfire.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 7 +- ...lemetry.Instrumentation.MassTransit.csproj | 4 + .../TracerProviderBuilderExtensions.cs | 6 +- ...Telemetry.Instrumentation.MySqlData.csproj | 1 + .../TracerProviderBuilderExtensions.cs | 6 +- .../OpenTelemetry.Instrumentation.Owin.csproj | 1 + .../TracerProviderBuilderExtensions.cs | 6 +- .../QuartzDiagnosticListener.cs | 5 +- ...penTelemetry.Instrumentation.Quartz.csproj | 4 + .../MeterProviderBuilderExtensions.cs | 6 +- ...enTelemetry.Instrumentation.Runtime.csproj | 3 + .../OpenTelemetry.Instrumentation.Wcf.csproj | 4 + .../TelemetryClientMessageInspector.cs | 5 +- .../TelemetryDispatchMessageInspector.cs | 5 +- .../TracerProviderBuilderExtensions.cs | 6 +- src/OpenTelemetry.Internal/Guard.cs | 201 ++++++++++++++++++ .../ConnectionStringBuilderTests.cs | 6 +- .../GenevaLogExporterTests.cs | 1 - .../GenevaMetricExporterTests.cs | 1 - .../Shared/TestExporter.cs | 5 +- 60 files changed, 369 insertions(+), 153 deletions(-) create mode 100644 src/OpenTelemetry.Internal/Guard.cs diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs index 5e05d14436..9cf3f53d12 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs @@ -19,6 +19,7 @@ using System.Globalization; using System.Linq; using System.Threading; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Contrib.Extensions.AWSXRay @@ -125,10 +126,7 @@ private static decimal ToUnixTimeSeconds(this DateTime date) /// The generated hex number. private static string GenerateHexNumber(int digits) { - if (digits < 0) - { - throw new ArgumentException("Length can't be a negative number.", "digits"); - } + Guard.ThrowIfOutOfRange(digits, min: 0); byte[] bytes = new byte[digits / 2]; NextBytes(bytes); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 7461b5616d..9e6e756ea4 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -17,4 +17,8 @@ + + + + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs index e224b595fe..9a1c722019 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ // limitations under the License. // -using System; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +using OpenTelemetry.Internal; namespace OpenTelemetry.Resources { @@ -32,10 +32,7 @@ public static class ResourceBuilderExtensions /// The instance of to chain the calls. public static ResourceBuilder AddDetector(this ResourceBuilder resourceBuilder, IResourceDetector resourceDetector) { - if (resourceDetector == null) - { - throw new ArgumentNullException(nameof(resourceDetector)); - } + Guard.ThrowIfNull(resourceDetector); var resourceAttributes = resourceDetector.Detect(); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs index e6075a1565..0adbb62772 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs @@ -14,8 +14,8 @@ // limitations under the License. // -using System; using OpenTelemetry.Contrib.Extensions.AWSXRay; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -31,10 +31,7 @@ public static class TracerProviderBuilderExtensions /// The instance of . public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder builder) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); AWSXRayIdGenerator.ReplaceTraceId(); return builder; @@ -49,10 +46,7 @@ public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder bu /// The instance of . public static TracerProviderBuilder AddXRayTraceIdWithSampler(this TracerProviderBuilder builder, Sampler sampler) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); AWSXRayIdGenerator.ReplaceTraceId(sampler); return builder; diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 21d8ba077a..45d4e245b8 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index 354d0e60fb..96408c758e 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -17,6 +17,7 @@ using System; using OpenTelemetry.Contrib.Instrumentation.AWS; using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -35,10 +36,7 @@ public static TracerProviderBuilder AddAWSInstrumentation( this TracerProviderBuilder builder, Action configure = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var awsClientOptions = new AWSClientInstrumentationOptions(); configure?.Invoke(awsClientOptions); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj index 5824f7f151..a4ed849310 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj @@ -13,4 +13,8 @@ + + + + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index 60d1005bb2..db2f232bf1 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -14,8 +14,8 @@ // limitations under the License. // -using System; using OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation; +using OpenTelemetry.Internal; using OpenTelemetry.Resources; namespace OpenTelemetry.Trace @@ -32,10 +32,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddAWSLambdaConfigurations(this TracerProviderBuilder builder) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); builder.AddSource(AWSLambdaUtils.ActivitySourceName); builder.SetResourceBuilder(ResourceBuilder diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs index 7bc18d38d5..f58e0fe7cc 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation { @@ -26,7 +27,9 @@ internal class DiagnosticSourceListener : IObserver public DiagnosticSourceListener(ListenerHandler handler) { - this.handler = handler ?? throw new ArgumentNullException(nameof(handler)); + Guard.ThrowIfNull(handler); + + this.handler = handler; } public void OnCompleted() diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs index 5177ef48f9..198f3815fc 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation { @@ -41,8 +42,10 @@ public DiagnosticSourceSubscriber( Func diagnosticSourceFilter, Func isEnabledFilter) { + Guard.ThrowIfNull(handlerFactory); + this.listenerSubscriptions = new List(); - this.handlerFactory = handlerFactory ?? throw new ArgumentNullException(nameof(handlerFactory)); + this.handlerFactory = handlerFactory; this.diagnosticSourceFilter = diagnosticSourceFilter; this.isEnabledFilter = isEnabledFilter; } diff --git a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj index f18e6bf7fd..232f379b5d 100644 --- a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj +++ b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs index d9dcb140a4..b09a6436bb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -35,10 +36,7 @@ internal class ConnectionStringBuilder public ConnectionStringBuilder(string connectionString) { - if (string.IsNullOrWhiteSpace(connectionString)) - { - throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); - } + Guard.ThrowIfNullOrWhitespace(connectionString); const char Semicolon = ';'; const char EqualSign = '='; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 3d4cdedbcb..97425268be 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -16,6 +16,7 @@ using System; using System.Diagnostics; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Exporter.Geneva; @@ -24,10 +25,7 @@ public static class GenevaExporterHelperExtensions { public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) { diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index ebeee33921..4ef5ad6621 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -37,10 +38,7 @@ public IReadOnlyDictionary PrepopulatedFields get => this._fields; set { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } + Guard.ThrowIfNull(value); var schemaVersion = "4.0"; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 1123c7fdbc..331ec1dda4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -23,6 +23,7 @@ using System.Text; using System.Threading; using Microsoft.Extensions.Logging; +using OpenTelemetry.Internal; using OpenTelemetry.Logs; namespace OpenTelemetry.Exporter.Geneva; @@ -48,15 +49,8 @@ public class GenevaLogExporter : GenevaBaseExporter public GenevaLogExporter(GenevaExporterOptions options) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (string.IsNullOrWhiteSpace(options.ConnectionString)) - { - throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); - } + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); // TODO: Validate mappings for reserved tablenames etc. if (options.TableNameMappings != null) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 4da2048708..e7ec6b9737 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -18,6 +18,7 @@ using System; using OpenTelemetry; using OpenTelemetry.Exporter.Geneva; +using OpenTelemetry.Internal; using OpenTelemetry.Logs; namespace Microsoft.Extensions.Logging; @@ -26,10 +27,7 @@ public static class GenevaLoggingExtensions { public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetryLoggerOptions options, Action configure) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } + Guard.ThrowIfNull(options); var genevaOptions = new GenevaExporterOptions(); configure?.Invoke(genevaOptions); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index 7942cf412a..dbac7b8ed7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -19,6 +19,7 @@ using System.Globalization; using System.Runtime.InteropServices; using System.Text; +using OpenTelemetry.Internal; using OpenTelemetry.Metrics; namespace OpenTelemetry.Exporter.Geneva; @@ -59,15 +60,8 @@ public class GenevaMetricExporter : BaseExporter public GenevaMetricExporter(GenevaMetricExporterOptions options) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (string.IsNullOrWhiteSpace(options.ConnectionString)) - { - throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); - } + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); this.monitoringAccount = connectionStringBuilder.Account; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index c163849833..2698798ef0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -15,6 +15,7 @@ // using System; +using OpenTelemetry.Internal; using OpenTelemetry.Metrics; namespace OpenTelemetry.Exporter.Geneva; @@ -24,10 +25,7 @@ public static class GenevaMetricExporterExtensions [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var options = new GenevaMetricExporterOptions(); configure?.Invoke(options); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs index 9770e8fc00..84261b27a5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -47,10 +48,7 @@ public IReadOnlyDictionary PrepopulatedMetricDimensions set { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } + Guard.ThrowIfNull(value); var copy = new Dictionary(value.Count); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index e2210f714a..1c776d79d8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -21,6 +21,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -28,15 +29,8 @@ public class GenevaTraceExporter : GenevaBaseExporter { public GenevaTraceExporter(GenevaExporterOptions options) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - if (string.IsNullOrWhiteSpace(options.ConnectionString)) - { - throw new ArgumentException($"{nameof(options.ConnectionString)} is invalid."); - } + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); var partAName = "Span"; if (options.TableNameMappings != null diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 389ab89098..11c0837589 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs index 4886b76677..480bb6cd02 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs @@ -18,6 +18,7 @@ using System.Net; using System.Net.Sockets; using System.Text; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -34,7 +35,9 @@ internal class UnixDomainSocketEndPoint : EndPoint public UnixDomainSocketEndPoint(string path) { - this.path = path ?? throw new ArgumentNullException(nameof(path), "Path cannot be null."); + Guard.ThrowIfNull(path); + + this.path = path; this.nativePath = Encoding.UTF8.GetBytes(path); if (this.nativePath.Length == 0 || this.nativePath.Length > MaximumNativePathLength) { @@ -48,10 +51,7 @@ public UnixDomainSocketEndPoint(string path) private UnixDomainSocketEndPoint(SocketAddress socketAddress) { - if (socketAddress == null) - { - throw new ArgumentNullException(nameof(socketAddress), "SocketAddress cannot be null."); - } + Guard.ThrowIfNull(socketAddress); if (socketAddress.Family != this.AddressFamily || socketAddress.Size > NativePathOffset + MaximumNativePathLength) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 5503bee6a9..f8feeb83fd 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index 935911460f..24d2fb3e52 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -14,8 +14,8 @@ // limitations under the License. // -using System; using OpenTelemetry.Contrib.Exporter.Stackdriver; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -34,10 +34,7 @@ public static TracerProviderBuilder UseStackdriverExporter( this TracerProviderBuilder builder, string projectId) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var activityExporter = new StackdriverTraceExporter(projectId); diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 2e9bdeedf9..89db6c8708 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -14,7 +14,7 @@ // limitations under the License. // using System; - +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Extensions.AzureMonitor @@ -34,10 +34,7 @@ public class ApplicationInsightsSampler : Sampler public ApplicationInsightsSampler(float samplingRatio) { // Ensure passed ratio is between 0 and 1, inclusive - if (samplingRatio < 0 || samplingRatio > 1) - { - throw new ArgumentOutOfRangeException(nameof(samplingRatio), "Ratio must be between 0 and 1, inclusive."); - } + Guard.ThrowIfOutOfRange((double)samplingRatio, min: 0.0, max: 1.0); this.samplingRatio = samplingRatio; this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 4e1cb0c7a9..356b1983c3 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -8,4 +8,8 @@ + + + + diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs index 2ad010fe07..f8a04d2beb 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs @@ -19,6 +19,7 @@ using System.IO; using System.Linq; using System.Timers; +using OpenTelemetry.Internal; namespace OpenTelemetry.Extensions.PersistentStorage { @@ -66,10 +67,7 @@ public FileStorage( long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) { - if (path == null) - { - throw new ArgumentNullException(nameof(path)); - } + Guard.ThrowIfNull(path); // TODO: Validate time period values this.directoryPath = PersistentStorageHelper.CreateSubdirectory(path); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj index aadf560c9d..82bcf03ccd 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj @@ -10,4 +10,8 @@ $(NoWarn),1591 + + + + diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index c9e1b936db..21a0cec1a3 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -17,6 +17,7 @@ #if NET461_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER using System; using System.Diagnostics; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Logs @@ -39,7 +40,9 @@ internal sealed class ActivityEventAttachingLogProcessor : BaseProcessor? configure = null) { - if (loggerOptions == null) - { - throw new ArgumentNullException(nameof(loggerOptions)); - } + Guard.ThrowIfNull(loggerOptions); var options = new LogToActivityEventConversionOptions(); configure?.Invoke(options); diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 652aa900a4..fd69c7b1e1 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -12,6 +12,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 1012202006..dc98d62fad 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index 250cc702ce..6fbd1b779a 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -17,6 +17,7 @@ using System; using OpenTelemetry.Instrumentation.ElasticsearchClient; using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -35,10 +36,7 @@ public static TracerProviderBuilder AddElasticsearchClientInstrumentation( this TracerProviderBuilder builder, Action configure = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var elasticsearchClientOptions = new ElasticsearchClientInstrumentationOptions(); configure?.Invoke(elasticsearchClientOptions); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index f860ce1448..358e34c17e 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 63777f7070..752130838a 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -17,6 +17,7 @@ using System; using OpenTelemetry.Instrumentation.EntityFrameworkCore; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -35,10 +36,7 @@ public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( this TracerProviderBuilder builder, Action configureOptions = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var options = new EntityFrameworkInstrumentationOptions(); configureOptions?.Invoke(options); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 5d2eec97db..f081401bed 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -22,6 +22,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore using global::Grpc.Core; using global::Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; + using OpenTelemetry.Internal; /// /// A client interceptor that starts and stops an Activity for each outbound RPC. @@ -40,7 +41,9 @@ public class ClientTracingInterceptor : Interceptor /// The options. public ClientTracingInterceptor(ClientTracingInterceptorOptions options) { - this.options = options ?? throw new ArgumentNullException(nameof(options)); + Guard.ThrowIfNull(options); + + this.options = options; } /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index c01b14e8cf..6133308c08 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index 7d8045ae15..c5ab46a8a1 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -24,6 +24,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore using global::Grpc.Core; using global::Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; + using OpenTelemetry.Internal; /// /// A service interceptor that starts and stops an Activity for each inbound RPC. @@ -42,7 +43,9 @@ public class ServerTracingInterceptor : Interceptor /// The options. public ServerTracingInterceptor(ServerTracingInterceptorOptions options) { - this.options = options ?? throw new ArgumentNullException(nameof(options)); + Guard.ThrowIfNull(options); + + this.options = options; } /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs index 8debeee10f..9e428a4793 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs @@ -16,8 +16,8 @@ namespace OpenTelemetry.Trace { - using System; using OpenTelemetry.Instrumentation.GrpcCore; + using OpenTelemetry.Internal; /// /// OpenTelemetry builder extensions to simplify registration of Grpc.Core based interceptors. @@ -32,10 +32,7 @@ public static class TracerProviderBuilderExtensions public static TracerProviderBuilder AddGrpcCoreInstrumentation( this TracerProviderBuilder builder) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); return builder.AddSource(GrpcCoreInstrumentation.ActivitySourceName); } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 85b5c8efad..31a68bafd1 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index 1565151c2a..d965a18ac8 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -16,8 +16,8 @@ namespace OpenTelemetry.Trace { - using System; using OpenTelemetry.Instrumentation.Hangfire.Implementation; + using OpenTelemetry.Internal; /// /// Extension methods to simplify registering of Hangfire job instrumentation. @@ -31,10 +31,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute()); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj index 75881f6083..fe595a0c0c 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj @@ -9,4 +9,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs index 824e493db2..4f7a81862a 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs @@ -17,6 +17,7 @@ using System; using OpenTelemetry.Instrumentation.MassTransit; using OpenTelemetry.Instrumentation.MassTransit.Implementation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -35,10 +36,7 @@ public static TracerProviderBuilder AddMassTransitInstrumentation( this TracerProviderBuilder builder, Action configureMassTransitInstrumentationOptions = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var options = new MassTransitInstrumentationOptions(); configureMassTransitInstrumentationOptions?.Invoke(options); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index 5c80254e3e..cbf676c0ae 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -19,6 +19,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs index 6a9f6283fa..d9a4b180b4 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs @@ -16,6 +16,7 @@ using System; using OpenTelemetry.Instrumentation.MySqlData; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -34,10 +35,7 @@ public static TracerProviderBuilder AddMySqlDataInstrumentation( this TracerProviderBuilder builder, Action configureMySqlDataInstrumentationOptions = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var sqlOptions = new MySqlDataInstrumentationOptions(); configureMySqlDataInstrumentationOptions?.Invoke(sqlOptions); diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 86e437fbde..df0c19fabc 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -11,6 +11,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index 0e876540a1..1100c47aa2 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -16,6 +16,7 @@ using System; using OpenTelemetry.Instrumentation.Owin; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -34,10 +35,7 @@ public static TracerProviderBuilder AddOwinInstrumentation( this TracerProviderBuilder builder, Action configureOwinInstrumentationOptions = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var owinOptions = new OwinInstrumentationOptions(); configureOwinInstrumentationOptions?.Invoke(owinOptions); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 203eb1b18c..c3006f0cff 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -19,6 +19,7 @@ using System.Diagnostics; using System.Linq; using System.Reflection; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Quartz.Implementation @@ -36,7 +37,9 @@ internal sealed class QuartzDiagnosticListener : ListenerHandler public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions options) : base(sourceName) { - this.options = options ?? throw new ArgumentNullException(nameof(options)); + Guard.ThrowIfNull(options); + + this.options = options; } public override void OnStartActivity(Activity activity, object payload) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 08d5120a59..b107cf3d4d 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index ec49496560..6aed9f8d3f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -16,6 +16,7 @@ using System; using OpenTelemetry.Instrumentation.Runtime; +using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics { @@ -34,10 +35,7 @@ public static MeterProviderBuilder AddRuntimeMetrics( this MeterProviderBuilder builder, Action configure = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); var options = new RuntimeMetricsOptions(); configure?.Invoke(options); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index f48126e677..2ee7f698b6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -11,4 +11,7 @@ + + + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 03238c9387..8df5c7f41e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index 1529648e48..b4ca2ec1ae 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -22,6 +22,7 @@ using System.ServiceModel.Dispatcher; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Wcf.Implementation; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Wcf @@ -35,7 +36,9 @@ public class TelemetryClientMessageInspector : IClientMessageInspector internal TelemetryClientMessageInspector(IDictionary actionMappings) { - this.actionMappings = actionMappings ?? throw new ArgumentNullException(nameof(actionMappings)); + Guard.ThrowIfNull(actionMappings); + + this.actionMappings = actionMappings; } /// diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index 3d0c4ef9d0..49adec2727 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -23,6 +23,7 @@ using System.ServiceModel.Dispatcher; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Wcf.Implementation; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Wcf @@ -36,7 +37,9 @@ public class TelemetryDispatchMessageInspector : IDispatchMessageInspector internal TelemetryDispatchMessageInspector(IDictionary actionMappings) { - this.actionMappings = actionMappings ?? throw new ArgumentNullException(nameof(actionMappings)); + Guard.ThrowIfNull(actionMappings); + + this.actionMappings = actionMappings; } /// diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index a0f8026c85..610935cfa1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -16,6 +16,7 @@ using System; using OpenTelemetry.Instrumentation.Wcf; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace { @@ -32,10 +33,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action configure = null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + Guard.ThrowIfNull(builder); if (WcfInstrumentationActivitySource.Options != null) { diff --git a/src/OpenTelemetry.Internal/Guard.cs b/src/OpenTelemetry.Internal/Guard.cs new file mode 100644 index 0000000000..0f67354d8f --- /dev/null +++ b/src/OpenTelemetry.Internal/Guard.cs @@ -0,0 +1,201 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Threading; + +#if !NETCOREAPP3_0_OR_GREATER +namespace System.Runtime.CompilerServices +{ + /// + /// Allows capturing of the expressions passed to a method. + /// + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] +#pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable SA1649 // File name should match first type name + internal sealed class CallerArgumentExpressionAttribute : Attribute +#pragma warning restore SA1649 // File name should match first type name +#pragma warning restore SA1402 // File may only contain a single type + { + /// + /// Initializes a new instance of the class. + /// + /// The name of the targeted parameter. + public CallerArgumentExpressionAttribute(string parameterName) + { + this.ParameterName = parameterName; + } + + /// + /// Gets the target parameter name of the CallerArgumentExpression. + /// + public string ParameterName { get; } + } +} +#endif + +#pragma warning disable SA1403 // File may only contain a single namespace +namespace OpenTelemetry.Internal +#pragma warning restore SA1403 // File may only contain a single namespace +{ + /// + /// Methods for guarding against exception throwing values. + /// + internal static class Guard + { + /// + /// Throw an exception if the value is null. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfNull(object value, [CallerArgumentExpression("value")] string paramName = null) + { + if (value is null) + { + throw new ArgumentNullException(paramName, "Must not be null"); + } + } + + /// + /// Throw an exception if the value is null or empty. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfNullOrEmpty(string value, [CallerArgumentExpression("value")] string paramName = null) + { + if (string.IsNullOrEmpty(value)) + { + throw new ArgumentException("Must not be null or empty", paramName); + } + } + + /// + /// Throw an exception if the value is null or whitespace. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfNullOrWhitespace(string value, [CallerArgumentExpression("value")] string paramName = null) + { + if (string.IsNullOrWhiteSpace(value)) + { + throw new ArgumentException("Must not be null or whitespace", paramName); + } + } + + /// + /// Throw an exception if the value is zero. + /// + /// The value to check. + /// The message to use in the thrown exception. + /// 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) + { + if (value == 0) + { + throw new ArgumentException(message, paramName); + } + } + + /// + /// Throw an exception if the value is not considered a valid timeout. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ThrowIfInvalidTimeout(int value, [CallerArgumentExpression("value")] string paramName = null) + { + ThrowIfOutOfRange(value, paramName, min: Timeout.Infinite, message: $"Must be non-negative or '{nameof(Timeout)}.{nameof(Timeout.Infinite)}'"); + } + + /// + /// Throw an exception if the value is not within the given range. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + /// The inclusive lower bound. + /// The inclusive upper bound. + /// The name of the lower bound. + /// The name of the upper bound. + /// 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) + { + Range(value, paramName, min, max, minName, maxName, message); + } + + /// + /// Throw an exception if the value is not within the given range. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + /// The inclusive lower bound. + /// The inclusive upper bound. + /// The name of the lower bound. + /// The name of the upper bound. + /// 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) + { + Range(value, paramName, min, max, minName, maxName, message); + } + + /// + /// Throw an exception if the value is not of the expected type. + /// + /// The value to check. + /// The parameter name to use in the thrown exception. + /// The type attempted to convert to. + /// The value casted to the specified type. + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ThrowIfNotOfType(object value, [CallerArgumentExpression("value")] string paramName = null) + { + if (value is not T result) + { + throw new InvalidCastException($"Cannot cast '{paramName}' from '{value.GetType().Name}' to '{typeof(T).Name}'"); + } + + return result; + } + + [DebuggerHidden] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void Range(T value, string paramName, T min, T max, string minName, string maxName, string message) + where T : IComparable + { + if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) + { + var minMessage = minName != null ? $": {minName}" : string.Empty; + var maxMessage = maxName != null ? $": {maxName}" : string.Empty; + var exMessage = message ?? $"Must be in the range: [{min}{minMessage}, {max}{maxMessage}]"; + throw new ArgumentOutOfRangeException(paramName, value, exMessage); + } + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 059f7d5933..5939e16d88 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -26,11 +26,11 @@ public class ConnectionStringBuilderTests public void ConnectionStringBuilder_constructor_Invalid_Input() { // null connection string - Assert.Throws(() => _ = new ConnectionStringBuilder(null)); + Assert.Throws(() => _ = new ConnectionStringBuilder(null)); // empty connection string - Assert.Throws(() => _ = new ConnectionStringBuilder(string.Empty)); - Assert.Throws(() => _ = new ConnectionStringBuilder(" ")); + Assert.Throws(() => _ = new ConnectionStringBuilder(string.Empty)); + Assert.Throws(() => _ = new ConnectionStringBuilder(" ")); // empty key Assert.Throws(() => _ = new ConnectionStringBuilder("=value")); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index ad2fa404b3..58cda5efd4 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -76,7 +76,6 @@ public void InvalidConnectionString(string connectionString) { using var exporter = new GenevaLogExporter(exporterOptions); }); - Assert.Equal($"{nameof(exporterOptions.ConnectionString)} is invalid.", exception.Message); } [Fact] diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 66b965863a..fd333bac83 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -54,7 +54,6 @@ public void InvalidConnectionString(string connectionString) { using var exporter = new GenevaMetricExporter(exporterOptions); }); - Assert.Equal($"{nameof(exporterOptions.ConnectionString)} is invalid.", exception.Message); } [Fact] diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs index 0c08e9a1e7..9a1ff52517 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs @@ -14,6 +14,7 @@ // limitations under the License. // using System; +using OpenTelemetry.Internal; namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.Shared { @@ -24,7 +25,9 @@ internal class TestExporter : BaseExporter public TestExporter(Action> processBatchAction) { - this.processBatchAction = processBatchAction ?? throw new ArgumentNullException(nameof(processBatchAction)); + Guard.ThrowIfNull(processBatchAction); + + this.processBatchAction = processBatchAction; } public override ExportResult Export(in Batch batch) From e07abb75b9902c0134f015f7be3614f4ca622d9b Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 20 Apr 2022 20:04:58 -0700 Subject: [PATCH 0094/1499] Update opentelemetry-icon-color.png (#320) --- build/opentelemetry-icon-color.png | Bin 47847 -> 2126 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/build/opentelemetry-icon-color.png b/build/opentelemetry-icon-color.png index c08946be7bcc61ed9fe00258d40d41d57aa06a63..93481dee87a22463d071a69d2df757651a6aa08e 100644 GIT binary patch literal 2126 zcmai!c~}y89L8aAL;+Vzi}EPCp2sU|JIoI82sf|9^%n2ciUe~r*K$38a?8rJQ|%B_ zLosN7NN{I@NoDri)UD;6sD$l?Fpl>>4ZibJN7^Zj%GBPid30L4!Ka|7w~U+u@k zZZ7UHI2-^F2o)6&R8>W)tE12ujE07$rq+Um+S)qUB}?`64GfkoTaH_?a`hTRBjdGZ z>(+1BxM|a7a|?@Y+qdtqw8Z1BtZZ#}?y`4sb|Dg7-Q3+hJiWYqd`bTP0Re%5A)#Sm zV|IO-nm>;X+1c)|G45vza+J@@}#U3JMEv6&15N zoYK4H6_xk64{GWj)z>#RK6~Eu;$?I5t5+>8Z{EIbZEb6B=kYo^-@Sj|#TN*=yL&$N z^?m9e82B>ybyzq$IW;8`&4|U4S*cVe6Gx?}!(b}=90)cZM*@d<1KytDI!{Ma)wU1} z3!L`aho3Sh>x6~db(|!T$RT+l;m1;1tX<8wdhJct{*->oajRF@Wm^Q+q;#b&W_NX9 z_UF0u`%{lQ28*LJ_HinjJJx*=z4T@ZJ4X6RjPmdkHiw>Q7<>5{e$FVGKI?pOf@9tC z6fk0<^5c!QM#51I8AiCEvS5~5E*P5YSP{%|D+RA!jIz13&@3}2AN|PzJK;Yvx3=Hx z+hL!@xp_3&q14Al>}Vi3zwtO~L(%5pgcM-n@1jziK>{5RCuRX-;i!Ju25>@pjbYm@ zDQ1vrnoUk7bMck9t1~h#sL>?cht(O6|JBAwDErEAN0)R*@?rxpyr%JK@I_Qr zY)Ct*0@lC}R&7{Z>}+HGrNH(2S=w8TqKzYx!Hv|6Y`NfE*K`3xUS|#0v@E^HECr3zlqR9gY zOegz+AGUN<)^%TO%k$Una9K?|8v#-y~|%>t0}gtp_`s7n&v@azL> z>S#`D-!rGoNy+=A=_+N>XG5%cEVh-o4~FAMo5F~#d?zQHe|neNSx{|&D*zFE&X|n+ zdDRxb9{g9+B_6k%Rz9WTK8*QsRBKz(T*NJ`R1w4ESU$O#sXe zx(-vD;KOkb5)W9NM{nx)=Ck&fG_wGnX^ybq`jv#b2aJ(2((D8o}nhBS%mYF3<~ z-2}##_F@UIuqOMPz;vS=3DOtWjV&fqi~5ORw&>tdJ8Ds=Uo(qQTf>Zxr5_iXX^m(v zCIDl%YG-yAQ-mWTUfdix*7I`1oB0)=fyLXAr zbWho=w8(bO3QkhPcl+JW3(jzVEGtruts18I zPa#QT%}_qRK*WlH#>G})QHgC z-f=Yz^~Q*qK4T%%2a& z^QGvYiY_CHB5eOK?Xq!nKrBDbySR19c3Q zmTRV6zLUMP;KJe7@LAfu$?g}W&`d_sv1#j;Z1f!~>i?mhm))3IEF9`@jgSSihQhsd zODg=FMb_re76jW(D$vXLweLXlFjUEGgn*ZQ3)A=IOXJTx-Hcz|a^-qRF^LkN7GAPB z;M}qeC)Ebl zg-7YZ8TV+_1d%Z_5q;;GMP_Rf%A07jNWU3<()f4A8%MMvulOj`%vUAi6-k& zXwTy3ty5NKx@Y)L@46PDfKEO&rcxVscij?EmA_x&tv=y*>lFy8B@ZKt$d$?F^i>pY zHO%_1+qExVI25V8ktW(Eu&nCTpXJ=QdRDOn_bww-4RO#49dl%8PIr>cGB^y&MB7pN zo+=BYbW)|z1u92wQGTmVWDOGNQ>E9MDt_#Np-m~Y>>}2kg8(i+0Inpwfx!LqyaT}Flc}J?w0N`U*vg=Ex~JUVks^B~pw*L3=Wnm_KVb`6HVBSmib_c-Qx zGdxd#=L$x+I*}rIHq6h}rUXA%5{`}sf`b@_=E3s;{5odT8`vAfV7s6soOBkTB`Ea*{d}Lv7~GHnHx(xx#o!SXTpqyZ zVsK{hLrTJH1e~re(8~82gTbq*aI`GMNk;&@$dC&26@bqHa1%zc(v^hUG59b>7E|+m zBte$^8Fcj`0B3{jJ($(o>{xnQuvcT4)pL}DLzdXeaHZ+$Y=e9s4DCmuy-dXFxg+3t zGxMwh&*Oo(OO&`u*D5p5iST@wdDf~jV=V@BZy09E^L)&g4Xh(q_Z*lbPi$ zl!ZTBftwXZb{I78h*CEii*@hct%v1{7qG6CRo_=bTtp) zy#ULGIc6rXx*>qq9HWXCqa@VE-~l@1RIqLGePl8CI9YP)ieUAp0A9I}u5Q9+$zWpD z=g`&PM2ZAb_?e;RC_InC&vfg!cJPd;Ej>Y(8#zLFKm)cSO@_*D@_3$9An20o0*Zfy zElWlLPOU(Jl7BUfqoBSB=y9j?I7x`rYa&59j#N5)uPU=5W1v5ic?R8!$G^uh&ra}+ zb!|8UuO(Jji-6~L=2;D%@k!C3^vLP(q{f44$Qsad>!bj`13a5U=~Dsz<+M|!6d9v9 zURikHX+#YQqsLwlk?+HI0{*orxZwz~x_%OXn^N#-0H2J(k5X|+0r(pXPBmY^1@L7U zoKk0~C|19U!CR>`)VLf4lexAs{OuH-n=Vf(2B`HoP0@{x6tORWw9ieTo2d)JF;&vw z{-)^S4{#I)!RkdSl-U3Pe*&wU*wD=!2jG}^dq#G8Rc4BK^}lrW8USyB+mBsBpH1P| zwG0FFJ1DbWgT(5UO96f*wK|pTDl-ATkgik5Pau)+!%c?uR?MU8Sw@ObAdr9c2qiyI zQ7EAR_o35ZN}t~Zo|O7LV3!eo14yq16HrVE;2hy76iopFHd6vxfB>zb@T^0h(++bK z;!nYRZ)QFylc6m9o=WA>0^&5($ME#oD-NFJFg$%OQW8qc2SYY+`2+dOfc$7`WVKjg zb-q5Z%Uu4l_AD9w;}Hr1eTPr=_fKF~R_o&QcRg{nQY!VcF8P{+PZ=Z2)h;E>!%w`8 z30CZ4Pr$D~mK?UQ4Dit|o}BeH+Q43uF9&XjS{QX&bh1YXC9ZE)*5J;eq=lugTOwR; zcgJ3XkB{S*hflHV%{5#VRr~ei`(|AQr%J#?Rx+;abVCO+fesx+f;v@1HGPZf9Vxs-*&w zzChWzSC{izG7QeW7d7eJ-=$VEvW|d2sq)YwAixAH{ zahZAYyVIW)X@@#C5g9sKjVM`yTaC&%V*}_2j%haGeZdg!+0GZ8&1_q#Df!~7)@y} zSYM&Q-VI0?vCae}0!2W=c$_=HnKOia(L&?|a?ioq@?d^F=*`P6a5*;)Nx^+EhVlAP z1NeX*Cn@$*wnNc;-Bc+PdKvIn87xuY9*e9&G4yUiNC7S~6UISArm+zUMY8m$qe>1? zB}G|5+z{a56x~ULy5K5av4or&glf)2C^$`GfcT*R#CREq%K|>$B;EYH(-?0H-|oiq zj|N%j>XTh|wZ2BqE{UVqUznH!{oJao!5={dIrGs>OK?444SHwsx7~g^n6C?%e^7FE z_-zS5E9TqE=u=;hT>xmD#w%$I_!~33Jz;_!Oo(U1j3>aY#5dHd|68^Ms6kgh?U?a* z=ybGWKUJ~5O=^NylpLo=c}o^2td}T~1bD>k^&_J>;GCsOMN=^lPiz`k z&iT~PJKcx4=)|%vx1-3!)>cN1(e|NM=X5~!Fb(t%XefeklsgLcL&^fQzfc{9i1rI7 zT{@#XgnelDa=R-Kyp?%L{7FB6qjL5X&+}46lM?}g?x4r>hl?bO43#uo8OrR>zB`>b z<(qYaE*b`EVZ@xi$Z5W49qhH6Z@SB!WCK8j3LrS0yF5Bc(*k-adAxVae7tBX{|bjfxMM}l^$DT)QoLK_(^L)Z|;|B>BlIj=7U2<=lvhrH=8t=j#y8EvbUMg6Iq5Jw!>8 zq9nbcNe=-I-GG~Piq}w!aJ&7Z0cBPlOhI4J zRoU7U)SIsAq)0$rSrk+S%p(x27ETEsOa*a-0Xb1_Jq?^DsAo^f>zsz;^{a-(AqL7jS3=$@Q6Vqk48NGh#E!eVj>*y z1AWIRXT9(b*5_x)1Zwob00@u-t z4#_Z}%rZ|X=tK(Y1)dA+qQ_y%n>qu^teQhPFQcon_fSwKs>WdifL>)*ZKFE5gIRTL z1lBW~U6gaJv2-rIbdVe6{64+9xD6DqG$jd#8-Q1zNx{j}V`9g6Plw1c317wtqLPBz zGN2HNU{FTD(F`cH7w7^5$_S!{f)1jfPB`&q>#N3?B^4X8$uAgg=202mrJ!tY0=h|_ z0i8fWnfO)(ashA>jtqbj%?dxyfQl)oECV{2fWES)uG)2K+RYewuOxG||I7Xnjrhsz z%}UBmE;IK&<;Ic0JCoq8VeIn?2n&FuE(X+|ZtE5X)R=(&P@|wlR3l8OgNjUW!cs{? zfgTKGPgf0QKr<*enhdB3S+$hW2ot)h9|NjQG~$`hAaWM8;7$V#O&%gB{!3_c^OKzr8a3W~hI!zxeH`?M@@enwzO- zC|RHRcJ|$#UG0CjN?Z}IwyUk)w*32P^ND14^b`ntT4$%9%WHJ8R_&|p&x)#5-E6*v z?0}v${W&6|^Ox>f;gpEqUp+T>%~SngeWr8NcAUM@F>j<6YRsoyiFx%;{fB(cX#W*= z^8G{i%f@u0%BajtYCJ$B^Ui;7r8DwM#BA2(5eCIo3Gn-UfSO;qNnhmfNZF_Jy3Z&fe9Q zc+^^IFrBg6`YbNPu{&W(VnJ=i^VSQ!Nz1aEc$&j=65pL}J^5ZnZz$U}G4GDctx?NE zD^l%fd@koVD=(;c!zw3a zt|TD{C)l# zTTh5)&#&?aJHyPQ&J$a=%D?r$F?Bjmy2@W|U=3sHAn@I*{K1ycb&aP|#avM3zvjO& zbvmY3<SHxP~zHAHMyBH7(e=`2*}y z#}!Hi{?jHX4fFzhP#ciY1-jbhND;WJl=?PW+u*OQGK*1W_S$kX*+P%w90!QH>9#JQ zo&eMihYT>@=0OPHPpUG5XqL)*9CeONY*>1x|E)@C*NqTC7MVF_N<<;pfAf97*<{9U zQR=QoidyssV4bOTFBu{Hv1ovlESiVCK7selVL);A(6Yvg1+4I#0b!JnA#7Yd%25FK zk=lkF>M}Y(_Os4uF9-!?toZmv7If>_o+EGK;V5!AQT+q|6^n(9fP7H zWSkjB?$Zr~!XvnWjFH<($z0in9kY@z-^ zj>5cw^O!>&O(;jIAN`M!TEd9yiYhaeMFWf+C&p0V0mZ3v0|Z{81TKvbISn2la4{wD zkg~8pCFjxWT~jPnXFd)J+;K`zt90~%ee<2JTS-_TiJ1lO1p5cQ9Q|b9e6O0zXx4hv zeb>Em%#&m1hrF6L)Bo$<7R7;2;8x&x$W(y*xw$h-XC z81?$v=CWjLeR1_)D|I-nj>STKWvs0)t`BLYE}#l>A%YahD8=LHo;=C-sgxMtf@Z`8 zbMk#$Wd_E^lT#vqx~c2%fw6ANZJ?6y0F=$C^qOhV->`%w6RX9rn`1yOlr&{1oE;bt zixow90m@Aa1`x*4FmE_i=)m8i1jbQ!w;jgV17pMKJZGrvL5x9})0|6gln`y6l+=jg zA>>NVr58X4RE?t9wtCU{`t7nJnptT9RkdRS#B88am<^RW38iF1a{WG{(Ue&I6g=&f8}LqWiai^d6`GhaP(5xSGq0Q(I}c+En6W};>;Q}< zGh?~T*d`duVa9GVV{>5a5HrSO# z^at=U^vMH0=pCSIF!ad-KK%iF5jBphZk)OWdc}oGH+yBdf#^fRw24m}e{FBqiTONA zm3t)Eev+m2!w0#ew+vZAloCz{-(0tN$d(ZrDAzI7T4T#3qWZE>UR|-6s($S}yX_~N z@6&Nme+aV4k*NLE_^bBO`7=*6ur4bC8y-h3iicD?_@afOuu7ldM~c`iM+$oJ`4 zs5USCF8tA)%F7;ty@Apb90h^Il2qjv6UgD75U#;B;N{p@YPC#w_YWpN#Wh}fjDX}`2cNXNj$QOz7JRz?+F9OGe8k)<-Y8`kTbn(&Cp75-|$sNP~K$5tYP> zhMFzk24k6?o5+)jH>0$iGPnM>om>FWo+iTwKNFwz$;1f}K^59y7@(3b`adH|iR!7nk$rig#APTk*G~ZQ)ik22GovdIIG-BZU z($!T)rcLig$(wB;5bX7$ba9ATN};EW(ryFCN2=Q&XFfo-<_{l)?5znWM@divM87&p z54S7Y7~7dg=u?9(F|?L?D~b)RGc;ZBhPj#mjc)c-!AXY}_Ydq3WK@Z+&9NHSx+&%6 zswrc^LJ9bQS--IRSCDzeF53q=tVWlM;<75qqVN+@^?EOZ)QAd#e=Eb)Va`!NTWu+I zpbSAX(NXG@^7S-hdueCjA>f`bN4XF1`q(RaO)RfG-ix{i%E^XJ&^5r`=rH|uismB@ zu{W}CoYJ})$xy<9!0DO*QvIcvJEQEP}Ncd{!E@Rrr4tHSI0j$N$4Hn%Hr|o z)O4g>*dIKN&KZ~?)6JO;<8 zskpv<9NE$Z%0db5Fv?WOpW2^QU0YJ3NFv({dIwP{qY_85f(=L&Nbm&k54glSmxaWw z6`Y4b#wX_f{%aM?BMU0v1)@r*s* z(_@ygzP2kg1aoirT#LvE~xghFr2fD`~W^P8gQCd4zbSerE5TYC30ovPwr_2@l-oG z{(QaT{-5nw%l5<07#?qb+vyvBVeNJybJb^#s1 zD6vIp*BN=g!N&$FWY`v)T+JT93f!U`DuZFyj3~ESp};M>naF@Gbv=fneU%7k6(I)% z2v*#zV-N&kvVPF1hp)#mQ^AKqhLC*%aXB4>Y$w_AKhXM#jM`@xv(EcwJ^2U+4i^w*>^P3jYg()*I9Hg$i->PIHRZ zm4zAmN6{WR$55+=x6w(Spp91&2a$4?+F3lPP6s8#K_p*b2+gF359wEM8eDCwIvue= z;vT>pJf}M|UQw7uE*oil+E!4%37q^ql1Wy?=IAO70idOqm3aycPnd4MrPXeZ@qcvUB{>fG@dzK4d+(1mGz5L-aV6{{m|AaM{5 z$V7-}hYj|$Q48d|fPQGeEGMlvl?Y?CpahJ~Z{-ocArR~&IN0PGQ51HQyaM*AQ6)8o z9_KjaqydO{)X>3$&!)|Z{8rL@Bv1flhrVU(7C_cUG>34y0876OQn#R%_KHF&avNZ0 z8p+a`kXC#`W(MM!gUCMFoXT&NAS7W28alBF_(~5E zcNry6Hb3RJ9>c`5GccP*dW6lXk)qL@^mVt^ZG?+~Kj*}ks_k~Q;9np02Z;(+iEs z?%A)Y2n_jE4g^DL8}Ex(mH!L%AD}Gvs<6D+^VCHSYA+w!=!;oCcqykGSW5R&+oNP@ z#5W=mmeuB|3UE}xF44_+4okUzfIV69j=C(6dNZJG`88v~Om-(X-g(t3f1&{Vbs&_L zcD0u@0HFjyXnK_6LW-|fzgRpPir6-UTQ8{Mun7s5D7WvLBvBDHQVsK11|Lt9>?r9P z1L4Z4gm2HyuAzq%MaEdE-xUR<30{I=o>992nlU&>V85>}0t%(jin_cBU59=y_%!x0l-Ome* zE#NgkdTo3#6+bp2 zq|Iw3jT>}u6M-I`z$qL~aprxog!jrwyqA0|LexW&phrzWK#kB_Nw2m-cpHRyLkV$% zDTWA6VGhBtqRAQ-6O+*)y1Z6mSoBMlTgbp2NK`=CmL*z>#R&g{4q|LnEtQ2|NXT}w z?qRYN;!Y*twUL~{LW&emry+VFq)C_#X@r7_yWyiHPRb!h5jJci5g(N8L|V)mMS5fn zT%coKY(j0sNhlnj?-R@Po**Rx_sxbS@*rD$eF~=d3$dlG%Hkv!q7K(EIr@jNc~71x zPAVq`7FIREO9Zq+X^+^9OWAkfAULUzQ80D^q_lRa%M;X^Z;Cgf?RSJIj3$H;SDQpM ziP}8n-{2vqX9L1xx*3NxJz(~Faya{_5xj9{+U`^NJ~R%u`&ZH=0pT*y@qqjJK2M2l zef{ka*ru(7@YM@g?uvvR(*E>@XwaP_oI+Q++xVxCbFjv{u*6AoC_Mh@YB**wXHAva zp+KF1&o#uI>w0Xv) zR7Jam{*rU#?#OaqL8u~cAl6O5W>t8aQ&{s2XA@NR7&))MbdvXF5zuj*Waip#Mu^;= z5cG$J`$6^Z`c`5hGqiaphGDyZ^?+tN9H`wyw8ik2+;d`WN2*r?LVK?yi%sexD>-pe z!&w{<@A#nx?*Lp)A@Q?j635{*5yz-zYynKpN7Y;|8ge(brawLVd@l6=FJ|ejCgdLe z6;!72qwn=@kbrWZyOHzb^b%WBh|53NFL3^*xN(^si8!VN?Os97&5o*)dN}*Boo<i?je*^0Zxs06>_s5pP zNxJ+v>D{O*_4A)3I+{buzrDTk_gJH*T)?|ZS&#tV3N99CCC}S64fw9E@6vCd;_Pto z>)Q`k>X#39SyvOdub-7`2@Ia8tv)0}EvuUx$h+)M;)QRcpTfcg@DKM4*IRUS7N^u- z^ARU)CKIodiRaov&$M3idg+QY87Y<(H#g=Nr#C$xlmY34IIC`|7AtldIs3kxZI$s1 z*pgrH(D=dMyG`GR&UTsopljo&m-j6s4(=e4{?#vI;kHBeox3!QHW}7$`R+dHQXah9 zF+2Uw2GjnRKng5hM)vsntb}P+7f-sBZ3VC3jpp0Vk4xW2SN;3b=D$D5|I&g-{UtdI z=b2pDh67D*SRKd%(zrDQY+@_f=_Z~(xn@6%_(qs zHo40s--KkLpY;vior*%~kRRb_q>5@e|pHA&hO5uZyp7f-3i((xI;iEF?!Gl=iH<^?pM%`^wT@O zL2k0SW&LhQ5LkcRSDJ$TV-rw%-}Z+&_gZ16!mPnRo8ml7FugBsr6fXQOzLCz-V@_r z&H%!Px1?QF@wq8V0$NTitJ8JLEenR-c=~RZR2r%Kdb|fsx0{q4h4pz5bn+(?NoAaF zt#yYo1v=N_Y2=*rWd|BZ?oxYb3_|?Tmy0AgB$H#}7?vxzJxr2gN#6Vv+S6vB=vRrO;&y{uo#Y!67UJZb}4D;dHA44#RNLMUhER zIGp(MbVd{UwisKE2jLjYO7o0c=o=}bad5vYDuMYANVf?@2|)LCxK+GJtq>=7z|*Tf zd}~mp6&8jd))w2>XKtB>hZO{?$Pj*K7+rn3{Hv^B78$_3-AKRu;j}@nW3hRwL>LQV z2NOc2A~B&;_w$+ecf4?GBs%(2!Iyb)I2OMnj4eAR87ibe;k+5}Rt#B<4IL?f{KZh` z!E`lt93DVi+FE3ZWsJ}p;-(D35`YIH{Xvj@#Si4h90Xl%NNaJfwT$Z&OraKj;Shc4 z^jwTeiTKrsU{Jg@{?%2B(qB&Km%#ML4~A?#eg6n@_%LVw{w+fXUsGPtID&RJvfPvUM?^ zY7l%1h^xYl#v88KbYY@2-5T~bJVAD=qy{$-UxjEiVKV;=sPES85)VlKbNnPsY=Ef4 z4~-)-a>E_wT$kXqBu24b!TW`falitniY1BH@w$gkOU%|mmD+?DZM>H0(dw^^E|cbS z^5%JqJ{B1t+#+yCu}|4R^i?0f*o^`coTno{G29$$^AkB4q{=u!A*_EE; znBqJJ`EA1fINudYNvLw^WvB#^+`5w~CVpI7;UAPnwv8`|SMmG{>E`k^07j&{0=J5D zH$J{U0X2|DrmOhvQdF_;gJ|_>DQ+-q14Iy58!E?wquxNW30Eu-%D~7?lMH- zq`puDwIl$miiwe~BweuV@mPA3+l7DIA4499)O}2F84RtcA%<^@gz0H)sktwp`UO$g z_xAgDJST&{h-(gG@bPduhHu&Q^QeuS5)a&N&K}%%KgrR$bRp`hg2M#R50y1Q$ieFh zuZU(1=US1A%_C_M{3h3SCQv95LE;|n9;i(rr--J*Deg^{GFk`m(kK_IUywk|ZeA&T z?t@Z^OoHGAA{2l35vT8qu7o1#$Eze3Vl?Cpuxf&VFu=SS;o267@VK|gGbBa~iDKZ| zHbT)*Rdw~knuLa9IjccS0`rN6anQX9Z(>7{2p<^GA$)kCna>RTZ_Iuv?mlIc--(t( z$Rh(;Untp)!h3}N!Rv0QXgt7s5_okCPjV=0iCHwoM_r%%(G^e;q~Mu1XrVR(86jvdV&1To#^9tf z#v$N`@Z!*K#k`@*eS)P6X%glQUIBD3AyUqwZ}_^xYfy+?49wFvfDI?ZiQ+E=>gXH7 zP<4k?7hayeLF|U#_rcvw%p1n(&_NEh7@$6YEWZ{XqjX$RgX<4u(|~2O7T4TJ)qs5( zFFzGzYeJMo%NdpzT!rP&5!uJ%K5|zTSl*uOEfnb?EeU-h+-+oURq*m^xE%X|?Cnv! zd>H7O2M_BSdnrbb%O?ek2{{w7GyQi9+w!50do5u^m;2Vq^ijz1ORiPux0&vTr=^!#?{%ih+jmECUrGD$eLzk7ISZjxhG zZ|4(86m(jKwu`Job3-1rK5`t-*8)Bph?3wphQqR>suJh)1j=qKyrQ{tL*L)er?1ra z2dI|MKJ=(mAsSbjq=^2T%&`qW6uhqgd0b-iPKD~=ud}7TTJL`O(*d09^CDjz;{JxImGuGVdaA##czAYM9K>IoZ5= zC~P5{Bv+wd>P3dxroJcM4bk>a;hO=kBDt>=(qm&BH9H>74mrPIyREPE`|q3j&UdeG z-FN)ktwUWmV)#w<0v7wXxzvS5S3h{GxkJXM(;PbnO1r{3vTmUfcKu zI_45hv0L+^e$O72unhLUHHP2!bpF#y&_r31*{Qf0svXk)ubX@0&vuQE)^dw~&b7TF zbNSu1@)zFC8=OM7ztm0wiIERb@RyEVke)ln^sM#o>E;iIo`q(_hT8fUCp%>fq*LdC z=UVcjeN?XB+&sXpMp8S&AYJx7`B%nY=OHg|_nlgHE~++qo~=k} zIlpYPxg9FeX9FxrVC601{uMXuk+XLBE1Z5gYK6SLtw=A`tYOiTaA=rAhUBgA$q=Pv zZ(NmktKm!ugpbXiW_(wA4JK<3&qKjd>BA-iP}yjl8Rx#a8Mi$&BjkqJzu*nwZTsh% z+b9+%wz-&uo7UgCvFBTY0xrZEj=(!Qd0B0K=a$^tA+tNQR|Dixs9=Yp<9-n^w0@7)pYwvO={=L`Y4Gl>ryVZ?g)O@ z-8}1%G+uz@5#%!aCi&N%^eRfiHSq+Y``%^W3u8{*ue})JE*%#;yN#TyvRn`u0ebdcBOvq*V=s$j;xak=UEm!ID5xWBG8V4*R_Ci* zX?d;pkJ#60Y|5~fl$a$EHLtUerX**2goov~^R8(QI}ROdNE!#_-265Ba*xkCsS)MY zHqX}aMR3nIR))pki_>n~rM$3Sb?F3r7zIgV4d#aBui5`&X!WUYFQa*q)8mIU2uJk#kJbgstQLP{@nc%h7YqK(U==f?_x?`q0VpxM z@-dTYX`J%TO9lrl{!R*6J1MQ$Oet9JcA3}iM8C?r7iv2<$=7D?cZctEAT^>@(sr!o zQwGy&VzJkTgzxawSGoWb)?6`pi(9k#bshQ!Lx#nYA ztbh-kcXeG5c5hDWCA}Q)=1|=vsn-$Oy;H+l%5L5r)O-xZo8lwn$7U}+XkcAy|0G4C zeMVBsu*#Idt`ir0Xx+a4Sni&moFnZE&@1w4urt(8pP%8kT}~4o?0yi?>S;B$0%ps& z?wV^ZY$=yT2}E>J`K=Q=jZT)U{7Goh4)fAUk}@+p$7{ZyvP&G-ZvNOnl06@9bm<5& zYkRKBrP-rHX9Y$7=-Gz)r=pw)?VJrUeJ7NrpKiBBugI$a&RRV8Cuc6S>1GHcZg2`a zf1$p$D6`5VAVe|lI>$XfstR6rHo^f4TbSQ^v*Y;5a<`VX-eaG2dSa9opt07`+P(Kj zzv8veMX!j=EJp}4e!g86aH7WjMR4>y_d+w74r|PFk7t|0S-s{%P$-MzZ2b1AcS2Z8#-=4l+bxkkG140FPR#GcD+7$V!qZ>X3U_^0C_2{h zC1jg(`vi_qiu)8_=0)(WosGBOU(pD8(PNYn<7hvfZ4FkXaYx(o=J-RudKHiymYLv4 zzRx)E#3?yn{;UaK$}WAc4YSH4{x@ImZe6#VUW@6%`r`9mc&7S+AO zP#TW#R!!t(Oqfz!Yac$P`0Gj$6gmZIYhrSh;o4|P7zqrgNs5zZb{L&5_iRaUD=}m1 z+?-z_*Sr%6G;iYbKQU5t^R=CCK*n!7-y4MzBR0Nuyx;Kg~M7{E;gLtS0io)7>gYC5iLsM3+_I~?stTBqugrn>dUDLee*Zjw4 zBN`uPj=Roy1L{bPy0rWE4g=##u3^K-FtKx<7# zz3y%E{mBw;U=l+V$9FmVJT__G1kEG(c5T6L^|bt&mJ>PW*KRm-qqlNcY|<_y`Z0S|A4p5{#^lL)wE1R9HWVM6daNHn@blrmW!bx46 z6xK094b^-rZtDTtwS3$7`kW!CCJb*mG{Wi4SOtD`a-#4>V?vGfi<%_p(?m7V$(2o@Th> zHmQ*Cf8z$BHeBn%ZF7TLe$7BdQ61BRmFAXemdXb9L+F7ECGi^Y9lDMYqv@gsxy$p$ zy^;-VmOz;FDYa&b|7} z>G9dXOheeTZxU!B6u~Q6wi=_N#A!L9fhiKmk1%KR%xK?0wLXVW{o5M?kJ>#oLYhTk?M73`S~$ zreH{Tsb|VvXl$-2fXlevV>#6)vLLh{gV_Scj zprRXa_&_B>4)+gh)bz!#y}KLo>Yq zi$2VqgwG8g!Gzgp@t$c#z+A)@-dmYNvXIc^#@%s3knW>S4zRVB~hhz8%Azygkrr~?IqJk(xeE*ts=J{(k{(axP z=TQH(N5yVGj3I#Sz;Eqx3nN9)kfX6??ef*(;(n1W5PF5% zaM=exJA$s}-rUxoel#aoFMG88sM*{5pgP4)AXv3|HW0hN zTEPnJski2}zwI9JslTIoDj-xN1I9Z-HG;zS2vdafy<42*CNeGtiA?5L1v-2I>B*^VdyS}^uLpG z;|gv%fN^iaigXiNSyoL*eKyKu-#+!#37UcPRcozoFUeE0AEkO}I5Z7-V!z)N`nJ<_ zl{CyheJm-z;JSOK-?+fXC4pl1PwdJ25Kws?cVs?f2j}3 zdL|t45pMANWp&%mI%6_u40+ov2*S%uTiYuh_8T-_dhNb%X5%x`rt5G5)H+PCFhjx2 zIP0b^KY97~zbd;{W%tAr+sljRgRgLZfWRGOu|>yx?T)%S!`r5zdyc%$4}YN3`#ww(#gn`NyzV3iFWBXK zh13Q482OD{eQ{_lHqO9>K7`ux&_nP(%tvm*MKI_iLF4(ZRc3}xI_9sH3g;|@8(=t) z%ZC0}*GgO8<6242W`}`>9LK@D3gk9NXr~&ld204}A)dMjPu-O7qcuav{LuT4C39pq z=_WmUUlwnr0cw0ip0Ox{L6K}BmS4Yob)a@whT_w}42hkcigQgt+4mnA4s~|ClX4)T z$VbV-7c#oXc18W@nb0SeKV0zbrDkf<5MV&Qq~e`CV)wynQdeNc&bm6&u%f1*mJD}& z->Q|5Q*I|_pBn?8tUmGzZaMBdI2Y1Z;P-7&ew}Hu@2~Fd3e$9q_E#4URWmr|Y|E%!E8Ql}P zFw32nm}cBK{PN`sudAM_z=6S8IyN|`FzcM~g`VyStC^r{&mK0GZBo0vd12lRcw@fd zX+<>5a>28*yr=A{v0uKrai-ri-ZTEa_Ue6)t>HMALXEE!Ff%nS#X0VRua~wmn#(*~N!ndgw_`mVT{ObR~ zW!h1A@%_Xbh1&kBE?`TFy@v_VziVVXQdoO#r6_*z4M_c!%HbPs1lWOu?OD66XI%5W zbnV8W2X#HS<{Z9x??!Rlf)meUwhu=9odh1*z>GfZ{=R#qcJlVR9b@J`7$wwR49sE~rTI@-Qxf7$FcF<8f%ti$F zRhm2&voxF|qy0L(jO&m+xX)3zdA|4CgV>bu;P!3+S_Og#5&QRTaNQ0s+BUM#LdLvu zJsiQ)_-2#`)lgwSaGhwsA=$K9z2?;!pJGROeT0NKESClW$hEu$?_@^t)En1std;$- zT1wit;d4hPlz}TchTBM@w7@DeC+=6prwNhUM%!;_JgiuDtFK~=Az!aKG22{LTRl!U z%Hohb5~yO4Hoyr{se=5?P?g8}FIpFi)k_a%iPyJT9vTKStXV9U8k};7@D9vf4<3xo ziGs!Fvj40ff4fqkBa06%ZQbrXPZ%az1VUlBO{`lXStMLS_( zY^JcEs?Wv8S_8h(dT;|4q$-M=xv%8*r=9{n8r|t_vQ`#sU;;kdd>fFLse4MRDxC3a z6;-0KxF8Clx+XHEG=;MTv2KMS}ASvzo*DMsSxVhME8@(64rGaB< z1Zb{YzFoHSN5zpr`me0#pE$f>4HUUBYXWI_A5sWn&wvS{s>8)d&PU0*A3PbdYr60O zR$~BP8@+%R#f~f!<}3#3lG_7^$6V_*!46}E?Q>;~qXut-RzmvU2oTQWyEcj{riP4z z>k8+@T<1Y(tO=_uX6?Ci=<|Fj{crUTMr;6yEW}M=5GJcb&}(&NADE_|ANzXN4?bKQ^*_>=14qr{ZJDyLf~y;!?sI@Vi@v-4G7_{ILWgpyjpIs3p2x z>;oH|Pd69}fpBMc%zxC?Qf0EaC&KIZCuIi2YW zH+z`kbURHM?!*oGLNLW6h?wBJ5nR3Rh3;Fl`A%@2p1W7qzkey|IyhynY&cvGg?tGl zpMp2n5n>SDuZGt20)RM`lNkv8q2}Oz;ZPU}vr~jGB-!WBW$y@OiEp=gqctBMb(qP4 zHNY-R989U$w~h1Wf;9LIe{X<$$u#Re+kV6SM+%Rp2dg9V zf94^%lE{#aPxx6?Xgmi5%fKYvHFh5Q;bV!n?2k|^h;h9>CTrKkKxxYmAM)prAvwM6 zum7g1&c_)*BH!IubRLWrF3{t5#nzNHf^9Nc|J=LDjNP9U4sf{00AaJb>%>BjX-k%` zzEWr@Q+n>R*hdw*+aW{8O$E-UJj{yOzZOIz%UDkSN2sb(5xo{K2C0H~^p&PRUpY(5?C$iO zdiC^{-)n~$s@>_iIt009!H(i6S};Gzdt=0dl`W6(Ub%Yy0%f)VW+8}HcirNC#4t2- zw~U&JGlW$QI86r8vrK8}6(D7cT9j+OANNQ4DY%L6YRphd|P1`P{9H6 zpc?N?$OHDxy*1}PFg)p>vCo3NjI4w|a25|yGv8PhdjMYBnkR&%ZS2xQ6H?0Y!FB3JHOmYB0ty6)-H%!lpTXn{aeH+Ww~#5?uIu z7V%*4_&$YJLU8InC_eoPOlmFNQ!Ro{ZAm9;(vBqelA3b_qY--&+1 zG{lwzVYry}v-X5&&2hNR>)8J=s4C9_{sq?CX(?y8-}VOIg2cJrgOD^-bZbgpf>b>t zTH$PrUDF3=JU)6>Y{g;4+nT-Z5R5nu{u7fQc%dX0dIY*0k0r0@xeyl!u_av9B-J0_ z{@1_!rj>g{Q+4?4<}TKZ$#?_usFxVPMGHKW~q&ZL-YVY8_IZ zGR7N1H9{_=HqusR?h!hzA01e|_RT1jkp*WaUe4Is7&}~M6&zt-oGQaf1MaOZeV%)L ze#Xgh->r}SJ|o@bEPgqtF_;7H|Bnl2n{qD>zjJdgTsfz~hK3W4I9F ztPU#{?zQ~zcu!p6l07z}`p5mdzDV4_mzNt{IcYvXzk_K%%W+l8hx>86OtZ>@jN^n$ zLhnuP4Sv(_Ab)fv*fI@#3zov0`L24{NjiUC7*!(jZLk?zJs+IZ1C0xoua=p?k*oFn zmG>~b>&=t%|K8B3@JsqCj;#(!Y0Wcm z_TGF}0?l&A_b!@7*N-OCz$~`;kuX6&)Gwbkm`5BTHf9 z=L|0cHGI?)vlg#P$+$h-`>RN~cvn`Lc#r6Oa-69_+V#~~ke;}_lL`KF>BGg#}xl5Ognm_V?9Ey_HZ6>Dny|5Zi$T_XyC{!?Xb{T-Kb}f zd)W2!$c^L_KVDhq(N^iVY0&)XYEy`D<4+8PfnD-kxo+FJ?CjQ{t&0lH96w%2)(x2+ zJax^{43PFLS6~lkQCtnDFPY~8`WcX$9_Hx%$WN4{H<=d~GA3(Z|B5b7OX|OeUY=(m zLx8PC4rr$I^G;Ex*|cE9DK-GzifJrsRm|GAr{YfNq~NKXVL+?n`k}!mjkX^|o*0OKPTWvbNGgXbpae2!F~%Ey=Ofbq0w5Tx5NMywlJYl8_!_eL-{2ljjmSM2-3+qc`}jgqK4#k=pv-7K-c1QN*M z`O9Ix>yR3MrG=gA9-Z3%sP0>i3*WSPk7sS6G7Bz`Rc$yIHbV*m5uTL%r{17h<;Ir& z9(C7~-}bNWGHp@S1a0ZOqPOBAPvEMM*I)Bo-?$LW!!M%YV=VJ>n z5m4_P)D~14lC{3dEIH!yu~Rj_{-{fUzXh8)6|C(-hrqthnC*)@DS zt91hI#x4f#xo6-e6zqpu_afyYW4NpDioCqxeTTWW2JdfltcNttXgDq{aARq0ZwGZ6 z)#R^e{$?-KVeG{LkBn;OiD6C${x~51Pk6xH$dZDqX^6(WPPg1I$ErEKOOLdRAxsh| zg9s}j3CkYkS;3R}nsug{hB8fdnzES&F8jl^!GwMK&h+W~JAcicd+s^UdCob{dCs$1DM>jXZ%crIdqi=2h)zT@mKdKfFgBop zD{kxyegFPPPU~EaNZa{XMWO#D9jrJzrR!N+sc8#XLqhoZpsr~|u12^*x&3g*l9)A9I?#dHlKGa4m zS_Xg|!S0K{C*$aCH@9_DwtoHI{X}Qo3#D5Wl?=X#4Zmluue>lCf|SY*v(RENy$c5_ zxZbm_jtbxMZ|3(2)?47p1BE-+7D(>~TyYnt2k)L;*B3f`&XqC=Ky zmA+u}0dRUd-kSgX{Psuj5Er`2Jt zo9t+<@gKZyV&_h*56EQ*O@O?JbwHDMiNCRM=YphArvqb>BAt>gA)z0GTP_b~QEX!w zk;p8@)cNb1uaG55H6N%*zgE-n5zJH@VW#?lDS{+fFYQWd9?hI+*=29m8Gr~ z>bUcl=}xndygvJb%*fA6fEAaiXAS&Z&oupq#fJSBdn+p_>9`VKi{b@g%DKc< zbsf}3uDnYN?vy-x0_rd^Ou1y)y?p2S+gvRpDeilc$l@DFnOf`OX6e{n(=RBoXK%*h zNE6M}jA%D6nD)AgEJvmucw%MSjIwE~u?N6QO?3Tl(cp?u>mMIF_rQ&77&q zj#-}!HI{+Wr-)|qMz@C)nEY4OW+_D-fL@0E05`}nca4WTW`%`XJ7Jd|_?W{da&9$< zZMpVXHalmrofABdMh1MpTdS$>bg$)_Eq{*&hXq|6CSWF19nN=5^&LaqdMK|ou052? z&8)KinySeTzzmVx>xU^&nh^g|&bZ*)3_mp$mtyPc2(oatTEtIM#P)dl=GD^NQBT90 zKg8}Th|wKr^IV!bunq*8$c!3BWWQLD@O67fgM!aijgJp*Xv0Vl3vmui?+OEJMkJn> z7dGc=EEt-- zu8NN}$9?q!x>>3Gcg`)5qF@6SH48%{A|vWw9iHCRD-%=s<(;^|-|4S)ptH!~!%wzljuntEr*Oc-T#me2bJp9T`Tyn5In$&H3v$dPkr88M)Hc8>F3Umjq?(1Na& z_Y5}=nqOvlhNA5#jf{Ysi8<3f9W5q>QG>ltPPXL7%qwf`#t>i_&t+jNEibw?b6)(A z@C~Yhcfl<&H-oK#eh3UaH38!rj(5YcY>ysF=Su*#HEW>d*gB2uZO(Cj0D;k;r?ixN zN_3s8A{I{v?oGRqlIDQKM#k`6d-taD7xsqB`R;;<&Rx_vRtZvJ&fXs!7E8&Lpg8l3yyEWw%XCWhe|!rdDvf2PPhRV5)YF|j097(3|EC> z^QF}IXIOVCQIsRL9S;mS<+jy3_V^AL;QFcQE4*`#w@k;z#kodALOA|3kHYx)O;exa z@une6i{|JvW0otgD4=ThNW6h=|z9fXAh$|dEmqbbFdSB`t*CF)_TV6L)>UG z3}S-I!TP64-X3n=cld4$^hG4Hr#Uu0<;CxQkzv-ka5rwt6S2X#nE)X}3m`0?1+ACt zBuCfM2aPoj8$uTMK*hEWMAs8SIx2VSnZwsU?)j?H=jq=9X(iDya;IUIsabbTYcq^H z!BXtO{1W*OOfdS(8d_m;u48f*+>JT54k}ijKHy3N@RX?z?^4rM5sRyM_e@#VvOoRw zLqDW^B&!!z5R}4mJyj{U4>jwBM|$Nc?o6_|(B1ihqIM;z5wn23Zj$ zJT*nYn)75-RzKw**)5{NgS1c^YQ^>9H1l~6N|#R!K_#anH3#l3V$_uxEf=~~<&EA~UMMAR5qxa2E_ z%#!v|8h!)6YT%9Nr+h32eG;#R6ibj27hI+3hc0Mx=>R&E>&sWK&$9MxhT`I}3*<0_ zS|Dc}01w#6Z-Z8X{6PdCDP|J3fx5clpZ1 zCexz*H4aa548j0ES$;aOIOVzY>W;~NdY3Ft@luMNN)SEy#%F2Y(lE?3*l9|K#9LW3 z6$Ej?KgagkR3`T7FCg-FqBaHuR_b}!<`AkXdACn3LP2LmO?aI``&v}Hb(_TtxZ-D)@* zKLYmV5WIUeKHjVQMdAJPl_-0MNkhfraxqH>)tRaf+oR?#HiJ~)JeIZ7> zo2sXC9CI;+gLUN|e5)~R{+0;F0Hi+ycQ48%W7P38X~1XQ32V8wV-V;3tem)koEt}h zq5xt${^C*7_zi<~%Nj>>f=<6~+R!2S9v5$lv!3sAal_OV|NLt$8=dek0Fdc)d_VwL zghk++1OQ;rQ62!+LFdaYznXW!?R`OhQOEuhpM9RGz>6@E8)sVm;o^%=D}$1I$ND8Z z!!Z}#XA}4NuKi!Pl{fD6{=aWuWYwkV6ABX4tIdl=a6PJ}Y zx6V2y`(1tK)^boJIZ}xs0+r`48}a~>boSBwK*)^A=x5#2s2dSWpSnORn|1&+@Kl}@{!Gz0}8yobOHlasxf zAFH?E@|^nAi`Ua~E`WJy>n!}ke+a=^P!_8(e^@)*`H4VZgLTRNroog8$QQR1lrCe6 zD^JfC;@jr9NDNbP9$2X%>A%C`*gckU6t@gW<`7&Y4gOjdxD@=^gHLXA8+-VBnp7wk zoF!bC9)QSXy){(Ya?SRVeS1#Crf*pd!Qeb_E_mWrODXL3IcnYXqOoYgKXVCZDEaah zzBC#QV?62dqf_r|Yq*|Wtd`2p`XKoh7g$Q+2sb$ca*koPcP4`=Gnp7h=|4T)T>98= z=NJ~vpLwn$)yhVdAG1vD`*s7;|Czx_kFa%*qgRF&n|Lv4%PgD)QZGZdf zWbZNGN1v;!nu6O$W3>*$VsOP?DCC*>n}t1?<^ID?P7gPV6&BGIX5DR)D*qB!hz2uh zt8F;Z9-9fPy6;|@*r{6;UGbg2-gM&ac63K0Wf+DQE0aofY+VSH`GBR39apgi7EoH31=TR*i%t>{rZgL@2Z zu;YxQLvuy;R{ox)+~A%ofL#B{fr?h=^+xluw_qvb$Y?OcZkh9TRC!!Kt+5`sDe28> z&-q?;!q9&peWfbYAn)s7#B_H?+#Sq|Ix{cdpLW00+1S_`U6pf~58DvjeaJm(OS_B+zd5&gJbFTGyM9_}qG)>?b!_V&Or=5|BVo!xGG8%Qpw`Xpe^iot@8)o!)- z^0G7Ic3B*(7~kFFgA*OChcz;2y04Iu_aZA;6=*8>_>Iy4wa-; zQ5CCtJ0Df(@`g*~2Lr&dvA6w*fr?6~LLfz{ea#TDN*?)S`bhUc*Wq%iQ`@{+ zIX$aWHdnv1{VoI`1ho0Ugp1`wL5Ft02?zU2%iagyummIE4#5G5e@fZPZ5d?iT8gv5 zHd+W7o?$$MJB0)B<#P$fu*T5feIbM|b^ zF60Iw?r9?@#YH*kA;5m{5k|;Wg3B3YdEX4OJC|p=DOm_Z+jK^nnuMdXgt*sO77Y*` z0`HZp{Ghn3`0Q3c`-07%Hl~Yqc?N&|UgnNSChgXck|vb(heZVrJNA3hmxcSIz<%FW z_cKYa?);6pJ)j})t`_0DZAAL0r;Xh#Dgze}O=L91Ig=`w0@=&kuYp_UY4o=)76gpT z(I{z43ks`=YP!ik-1U>9Ji&&uQ_!xbqf|&Z5J6do4q2AsJgC3N!HRtahTrzR26dbW zUT-i5Cf#l8>PUZfC=5$X$ za&Ku%o)4iic16GrXQ1?{ILLx0Cv*a*$vZS`XTU}%duu6l zetKVPR_-VbtihZ~OUqCh=Fq&zw!pTyVc7?Y-9PbQqMqB14lBQZe%-o~IxqEQhoE$= z#hI`74m8~>?7$R5PF~pdVyCeb#bLAg<+J`-r%+!$=0jU(sA~X3ptC0|Xiw{?SATYY zaLWhO=T5`1ART~NY5z|SYSM~r-lI$~-z~Os*-h(Ld|grXwMrQ7ay&L5|NXW>rRLr% zyxY6s{|PBHch>=rt-m*hQ(VR9^}*&@1CoZ^^ltoZ0iz;^Y0_^>onZ@Jzpc)5L}&Q& zepJQ?mb&Mi#84RTeyxmZES|u5^QwjOy#M4lZsuYgv-`uQfpitz+wb))Lnmmt zh{k*2q{Xgh%l9bZt6TTK&R)E1%X_6uwW*vZWH?8lSTdS)2^&g~^$S3b+LL&#e6zC< zW;cv2z@0(UITsG!E114xNA0VVGj8t+`1y95Z}DQwOZ{E3-8m3ABfwcI|98bs=sJm6 z%a2*17vpox4_D8$(|D`l^Uv~=`H2pxFJgWzk00|3GiX@>MbbA7*<-)?b+sR}Po9q+ zd1QW#yhDH?HzTCqm6f|*`?IddDr`L^8ZbAo-}u%-_nD4%Qc^2rEe(VFt-IDRw?X#2 zN@V_w>#=SdK1XVQNK{2YdF2)Cvo4&y^CxtFJ4j`2^O*?6^ypJdQs4G=i5(QrNid~b)rIXZ*kUJVHFh6-rV)# z`mFSdjmBT|&v(bXsn|8?pNG6~_l+(Es?WD*TzvlIel@Z>`sz_s8JPds*)}#`t#@`` z!sTps!|=|hNaN!1O2?sgZ%YLLG^1ZUiVjf;0?8a z6}<9|GJkb9-%|3SxJPF^&SRxMx|z@xR@-ClvadzIEBE-P3gaA`^Pyp(!A%9##*R+o ztew|Cvr3Ss1aN8fwD0XG-~8!w#1|HFWf$LBX5jR;ui#Aui>DodNr?#qYssDbb7MO- zdxvK?i+i*??ELojuFp!>(xutstZ`;hzcBL0|4DD6JbhbS{E8OJy}S5*7NuXaV5b$M zn=YJ#`O77dxlG!s`+jnYXTS0@aSI5XrIDSlNbR#Ykd9VFV9kcdAl#Pbu#19GMyDso z*vXx7^MDY274k}UnkrE|WN#}B`jKWu#mckt)Dbk}>Bqd02*p7Dc6SSYjO z8QB))wRUFksaf619tChEhuw{ll!gm#l_sZaj+|3|08c=8x2JaHK)lWdb=n3B!rrX- zWzHz%U%X{FpHll^l)o7lMrB}#BzuWX7}nddSS3#d3kSC7H@@$nN@|L`LhwCT^8Jy< zfD7Ym!|QM6!*eL7Jzs$`0(;>(+Tsn29t5rUzTnbS?J@F`N~w=eUVf#hvA705Zhs16 z$qV>MRhhlt9?tswnKFt!*p&kt9bNG4P(5Ht2dLjs zQs)Iuzg`L}C_3syptNeNN4?_~pR(QZ$}8JaQ7iE# z)`*o^bb1!Lqyup@7+;L7ZnWlbMF#f@q-cQ`;4n4>99TKikioe&QZe?`?NI)Q&l4FF zul-HoQ(#Yg@#Dy$txey@4d6~~L|6l=1i9CYEPtmcP$wGUVcnd(YEuO|g}vIQFk~wi z8RRDeBHBfayWNW-n2X9EB%Os@ym4jXT<(nE&p zozpgJDx#2()2Wy9v+->_1P3N&6?Z@})W-@IeBQ*$xR?;sdY2Cy!vT=59x8eTSNoJb zfMlLUMfMZls-(*tK@S9f8^(A{hw=r^h(<@|eTJGqI7{xG;IT11DO(aedlM8QG+|T<{u{{x+lIM9*&~5NIWsmZM!%JBsU+49y6Qc1SZtIVUZhTzm zT^pO)8+&Tvpa1LeUMD9?@n)m0Q*!S0K@?Al>})I|-jaITnfLyc%|F;)(%#43qzHE& zZV2!?Hdf*?mXN0H5^a#o_tT}=2*Sc`2b0LY{?Pwe)D8Gy%q60%sn{sPt1f+* z9;dZ8<_FBt4+S|Ph`9@rWKcX6aKmHf!@j{xh2M;{>Ey~q`IH!X6olWZr$%6p1RNKp z!^z6X1ku@${kCP``H1BkcqDuTdo99qfBaD54pIUSE&D?YThmNq?~+i&>`=V&dZ=a& zqTZf(AKw|w|5fxtN%3iqxT*mfmW{PIeT`9Zqp`5qB;2#;@)T(}O#lLuDu(&E&=Bkw8z)wyV5_B~P-gISf^!xV;4I zN=!`?2rM;NnLpn3&_7!~@Qn+z>tGN|Sw03oz{0++jjS!Gnh4qad$XnB8fuTW)DD~P zQMu4ldU^}O>UpXo>ekZ?@AtA)B{#@v+8WVYd98mcmo}WvsW=R~HHwgr{`wF5e%?&D z(;fFqih84yy!aX*8g1KEq$s^<#_8w(`VZ_!73N^x)U?C9e!U52QJa+cS5_Wc9X?$) z`I{>yq2VrhyFMbk$9ivDV6QBNm?M`)w7ZMo8Za?ev1Z#4+ZkKEz$Yevs1LYlW3$6+ z9JN)WJ+U!uXnCA*N#~Yv6^+MQ}-%9rS`887NJSjx(A&ILjJ<-#C<(zYg9?QpGUeq}z2(cLJtFeX` zfsa5$QfapTL;s)$SUiUva(=JB#+xuqYcB%MiQtgSM(l3(EPEtwfv*)m1I&=4$mZIJ zCGToMnKMs@%w*Q)&0(idNz4Z_V&dNF_yeO)$D!6nYQcuS+!Ue)RW2yen) zZD*VVJ8tXccKS}8odL^$Voy2DV--t{@LR3?i(XrLm>E>Q9 zR-w^D(0(BAfFkjbJnNA9h@!jC1fX9afj)H~fYE4uaV;iJl8?^ex zYPIRci5hO<6!ln?`nvz+dMv`)$X$BbBO#7YF5<4aS=}BwIcvuvwO5oQ z=isIx@zqg_;+%pk!`SB*#kbJz6tsKT1npL-@U_;G5sdlV66jO;+|ly-ud*J9*Ad*8 zw_4kr@%)s42Eyex-vYN$qa{`#02(nIEANu=nEy^}|DLh2|rHdedu-zZMgY4SbCN zVIjGC*en^)>;{#Q^}D#azt-Miu7{3tT32{)dt1{xlmvJduxOV@K2%Hm!7+h0QO3Wf zrxvpf-Wz}QKC%I5K|9_EE92=0kEN5Z*W~y&UFR%rJ|D2d`|Z!NPY^WyMjJsxVKtr% zt%f6@*)!vGOH^R?j=_2__-P2hSOYla`v(PW4lg+;1k#SRHP$F1)G-_h+^S z8aal+(P^H%QL8q(IsL2W59|8b9bhBsde(sKD3eNXi}Zo-!;*KAy!=hJVM}U5pAEYY zecxjo(Xp5cwlq8lR$|3Y-!H1>^(EA{ym*x4*@s-~As&!bD1f@@z>uG$cJgsbTvRaV zv&E6{`ZrNZePSSsedlW9_~)WB;;k$9@(&OkWzFbiV^S&ulPG0{D`0Nn)qy8u>5p zN}4+SK)rsbKybP)z8 z3j~lfAOG z_;3Y2r-Q6xj-1gviT#8`o1}RIcQIPSXc)zyA!sPJg?5yXvLu1(0YDbUOOhsgE?_zw zh1-<=0VFL^Wg0Xk8sgDt5K+%bgT5feyg6tPVVntGD~WFQ21ZC!(inga282`}(j-j| zo;4wZ;=adre!=uV2mT-==Lb2R@R~XX2KF*?Zwp{|O+F{#beCZKmth%?XZ98}cNN~i zONi1H=qCYJNd{#cD+Ip+3pBqG&A(=#84li_{o0;`E@@~LunI^}Cpviy>dOLs0)$26 z!BQEI)E;#2gYI3#-7iG>F#R)1)NXETD%uOEQ zq47+@q}gDxgfP9)VbWT#Sab+K466_;TtLRa4_SwK??UYE#^Aj#qwD7l2eg*(bFL%` z3LtYKMzefRlwzANGkT&x_FMq)-ZJ3PW;0U&fHN~$`UC(z9H}jd%pKS#mRY_yjk*XQ zj|SV(U?l?lwGnM7o`;a<-BF6f$^&)`B-U3pJ|D!4=Q7D2D37!TB%KHfiIm3H);1T2 z*Zu@~Ar*_(rZPqhyp`xp2TN&)_;ccDZl(Nk*8m2&ONjXgTxQv`nC9Y%RbdP+CQ{7k zUf{6ddEnXOpm@ZaQ~?1biN*u(1+*Cyx+i9M zc=jRPk45(iO!res_eaq^(IlY66II^uxF|(027IC<<0AfKA$()V`#V?*T!koMp&awv zwF~W?Mtdx#JvuU)2@VEnW-ZZ?(Y!!0iB%82rz4{w9iXB}+`b;hL!wTCfhUtgi1jKfh9>bvkw4xGabUp3RaW|>i330K;eE2NFSup z5^7k|!DMuZ82RcXF&CaGH_#@Yi?;bz@w5ETZ{I&J`z$wg0}iBX9Zkv4VK`-5Qic1> zjJ<7<3wEz(Mj8tf$t9C#f2&n~P?{8x|F(_4bBOI71+ATTJNSlR1Kv8TtW|w^7F;gr zMF$k_H4!o9Ms00suVzPN9~@qu>-c@j%%mGpLIHetNUg!Df?X*%!Z)Y<)ZA;NVRXvo z!oW|(#uq($|S2{KsXWFNVaft*A}E2)DRvt^3S0Ihr1y>44aD%U{{n5B?Ba0p;FXJ8h= z@h5ZX>KVTm2HxvE8_ns_NwJ&8OgoXHd65(QVQA5&K}|M2h;yQEi%^LA49TISRRp_y z$wj06NQcd++LKDP4}W=O-z#mn>oP(`{Qwlf7%mZ)X%1|^^TVJmZ{tpf92b*78*@ZG zKP#qd3IJgCkV~bxp{2h!>-D|Y8S{Db$fWb=g@lGc8LKSV^^&lmGj{YPth!UNRPJ42 zt?;~Viro(}oKMn+ju~FG(Ksnmx%5$o!;a#r-xIG7(dmFJ*D`rK^%0Te&<$FJsrIrPQh(mxwR<+e4!m!fsi@#-AZJtnPY>J&J(+Bb7Q_z0w z?~uKvHD%x=ZS(QbLORbC8a8>S$l(RP4_;I|GP!u#J{_c9ILA;W&9PGEf{E?-5QO3h z>JMP%&IH6HPlX?f^uf4E>=9Q5D<&A&z7u=^sVXO~ibLQ@bkm-}FC8(p?&3uW`P7`b zmKw-%yItFyxCM~WJ(m}8FSg`AGR1>n@l2&gqr>zS@ zdj^?8%}NiT4IaLv>HwU{eC_06NO+6=-NGyh_B$C4c-`QaG_3Co8L%z`#c8uF(|6N- z?PLxL_Ba_1^!LF_>8cxuEe*;LEIfzkCY-JS;L<{70+-+bMO?;Z2#k*`c8|qSX|dGr z#0AwMQP@X&&Pay!VP8O_NXNaHZuE+zQS3|Pfk@CH(}MH~G%38C$W`2_mpq+m^eNM* z01P`KIzrovyssx2l0@V>n#umq&jL|Moj~X?PfN;ts*`0Cavx$&X+aMV{a8*YFltY9 zh$4tyO!AGPjMU-ToqOp2Mw9NGVelv)#IzbTm>(=l18>3{rG(A%ITTbXO9PLr2{c9y zs|wC)!IO!e61^!5Ml^YL6Ce5yX8u!U{v&MPAZ5NIQZfNcN0}8>7${}F#0lCY8c>od zlfcwx%Z@w{-6UeF?h;o88+iEy4D9LdM}S`^RS{Y`5@#LGB+_cKxauBM1*CFxRir|o zt6I)Qs|dBvR2B1v4LH%3AX~UJ4SEN`-N6}M7Tut#O_b{ps zM^$?HcTnQ0U;|)cKOUJ~F{@%Wl6wtRk;Qxf-Kr|n6??Fhxf*0M;1Mv@FPQn~ddYA~ z5SxD=jerDZ@l%fS!dT<>M8pxs{7+|S6Jaj37QZ(eM9Y4wy567N$K)cwR4M8FQ>qvRXVlS>*Lb zh9|Tc#I#Am^x_&&gxfTT$3Zcmdj<Lx5|NSlWYxnb9nYTj{X^ao zN(BBT@+GFd6DJFNi?5wr(5UmcYhHdd~Nm2x$W0ml7fED;QOoEc5Pwc*WV}4 zse}v83L?YZ$2nFF*|1iZ^TgbLA#J+b3mFI&?lC!GMn44k`EmP+Z}+32N8du^n5)a{ z-Tipt!O-;0pMDC<+Y>rRSi=SqwH@Sz#C$n3aENUs^amB$2VN0jXK3Ns4WcurAooIn z;am}xi2mazUfGG&20fV&*F&s({7w2OkB?}ut-O8IGCfk081TP4jjE*);4G$8&ptyM z8#e98NXs|Bbi;Qw{DP3nDU_}XH;AGskPMwSX!|7`V?U#S7 zb%1mW1u5U(!RmR*hYqjonyjQlt1$tpc0KoaS45lN{+u+sqeCHCiBx2_%5X@U*Vo~&}Q=*=x^Vy+^(Wm-q~XL_>|M{ z(e-J1w%gyOtOmxskst&}jRx2GFt#41PonM<~u zdr}+p?OXElp6=3!{GadIA^&h!YP&fCH>Vc}$WMRz^ZZlpn6X0l#8)}LnhrkvJ$>1> z%+!HK(1Mq#T*m2icD&y4s_mPfkrf2t`Bi!0wg*2ot=(hV)Hd77c^eldpLQ|CX}_RH zDg8CwV&SS;{YAsAay`ROt?sgnM!d;AO%ITL#^=p%tfN*x8@krk)DrHPOD|&9SUQJI z4c%C~uyqyB%(VHGM*Haa0EpHC-8^LIiVYD%h6t7&Y<5pH{cW}9QpZ2jjn5YhE9(G1 zueJAgB8&ruLL7)9cR@xpV_P`*vBoR%%_9)ZrNp>}ep48@0uY(yo_qT{`F^?MwSmo% z;K=V>w{h)z=-;4NOtKZD)UO*wI+~ei&i{3!!!PWJ)~|V05r<5onhLG@ilQ~?O6;Zz zh2$a+&MyC3r;;HRzqBi8%=;Un-w<#*jIfNm8r@VVtvE@6uB*I#ppX&Aj{D*q zp#9)O_jDjgiK)zjUpET7WIV4}{!4_Z$&S9*%_D!AgdZh>j|TY`=-EigAMs03G<z7v4ZC=O5q(fX+syY!Un!KYg2#@oV??+udYLAzxGp^2|&aSC0X+S6ZT(f)H*M{0q!N*Kf^8CsA6 zlTw($vU>btO8d^S+C31Xcn*XxoczyyC)Ja5r~7Hg z?~Upsju>>AvpSZWzjA(ztz1F%4KI5UE_sVqKr%d(`Qq)HP&SMjAQ-iA^AL`iszGA& z(M9uuyL5;`qV9#>a$oyl^f`>4U-cxjZJ?3O*p#=?Amv~aQ+jQc_0_%ndhW96|JtZO)?WniYQ?^PET+eQqGQ6* ztt*_3k>@zvj!BRIU$b_OBLyEs-J5db_PwXW=rJ|Nf0xN=?zpEm3ZwA!!Gfzn=nxck z^|5}O@}{Z@{{y*j_#!7B|Ep&J9q?4lcI zUzJA_>q-d3g(dlw^q-XGQnrn6__$|BS7CI!6zJ42c$2L}R^jx$ZBG{s9hX4bIc)@Y zdQx;wvjcaAo}L|pZetH(X>FcD|Ibxpg{5~domAmNLfn~bUoHMS!;egmg_KXbEd9xd zat7&z)2p3$3D)UFo^*ZOZs}&~<%Bh#tNHg^kMaR)6#XJAnt zEW#qmKmEPPML{=TP^rr+xOw8matqS9 z7A|}L-Fm?gl$N);yz+nbNb713+hLS}Qs|s5FHE28?LX!aQ05X#Y%&fGVn!S8C6(0F zGoG}w`iL(y11MWHSV;?Z5?r~Q+T8QA<{|@NXSa>(zCk-w@_Id54m7c65(6VrAQ`QC ztl_GpA4QVOp)@Q!vb8^Nh`+@k`jH5LdHskI?gA3-kwTKixa6iH{#PzTbS&2;aQmu0 zNx5*L7`vCfkgip@7}`OXEG4oE6`8I+W8k^-hH?{E?NvVVg+XbC0YrZzYiGb-gp{D` zeo{TdQU|dwD(Yoj=p0Y~*|35%mC#bxu{IYWXizLGh)TLP=p_W;jlb7Yb6UMj+)A%8 z^Oq6rrz@}+=8AmNoL0w3Q>OFESJ|vzHBaGEX^`9sJ?^Fi1~0xuk}783s8}NRe8SwW zD9zK?q(T&iw#@ABslc#zRP3v4RbkRvH>pD67)XldT{YIP=h<{Z2>K77M zj~&DMDEJ{ocpdt$5?c>d;VOF&#GN;h7l^s+Lp=M^jUCen9d-lw61rmSNf6UR+WoUf z6ZJ0r7drr?v{kz&PWgeGn-WyI%rvd|WW|e&a1eb^eh{s}LTG$(?QFune)i-;m6IH) z?B2T#DW=6E_413A7g;E-VY7IXCH>{i1o75`z@EKWJaV3#oip#Ckn)pYdyT>v0fe{$ zvET!43HmH62yJgM_apdz9U4k1xJ(p}R=?~rQ{hhwhv^nvNJw*1^j8k0D_r=~!a7yD zg$d#cmu+2{3X&E!dJUs1NMN`;_g}igT}ca{yhf1`?oqlzn506Z8V!SBn54p@mvn_I zlDWw`pd^HNd=4Y5fe6=i78}Bc!fXlZgI~*tAYb<-)+D6F58F79d=X?IZc_8A0k6M` zy5}nK{1vJ%l_g(TN}BANd5i8-Njz?8<$INLkt)Ck?QFNqX?!Xi9**Oj1FUlCkTebO_|W zB-aC7Ms2jFD=>20!rxn3>kfZdew|X7e*N~)ZPJxFCDam`^V-UJ)1s9(%f5d>9blih zJLVKCmUW7?G=W-u?e5invnN@%RTgvj%`L5|w)d0F{Q5#eDDGG}p)`6H3xh}ki(eLy z$cqJOl&6eT53a{N6UkWS$cP}qVULr5t|BjV2BZy=XQYWmpwL}B$+Lot2q8k*#0!}e zwyso%!P?$GIce18n90iEBh#FzCBw5IjSVG9_myq*Ltvu`V7gA zH!^00*+XDXk}1>hpnosq4%U-A%dxD0uSx_JrQa(@ag(E?6z?$-eemtG*?edyk{JO# zMak&!yrH46k-)QiuwWq21OH*>^Ha#t5~Wxx-VoGoRl&f)FVDJ3u+>jS^uV4YJR+{{ zBF_qw(l+Oa1qIaQD6X}Nih4XFB0~mI=JtFik zhqz;qVQ95@^Ag4F9>`?H@_&lAP%5M!s!M?P!Pwqclbmn}dKXI$Dc)GAkPG&l65?t{itrHE9lDjwKcDOHmO)G_*7H%s6>yYhN|9L4 z2kUcr;bA0y@sSLsNk+6kO1PC#MWH=b-ZX9VFA|^JhGcFX6e|Iebq0B2oxX~?yX0_b zlV;_?c*Ih2q%{na3W2>y7curCrSP1LND;wfiC-W6d|XE46eW}_lQv6M-dJsOb;&vi zI?AmZp^`)#bC%#j2Bii9C3yez{>MlMjvCM^`=d0dLBqeUkDg&H`v)N6W5I5Hl(=}2~X!HDyRFb6X(&IW} zWEt*~EiYy6pz?A&$t6b$PmYyz4&rFge)^eoqK`(Qy``T^=CZw!BB~$GX}Wlg=Ay~d_2W|HRt*aX2Tll*`=|TS^Vye>V)sw?irT!zkkI|T?d`x)>5{@!q~Kz`<5;Cssp_iFtG{&5+O?O)g16fJ2e}NBOsnhbm zz~4ERrwZ-KA8#*XK|oZ1}r(Xd2@G?p>di)c9BLQ_;KQ z-=C`pHjv&C6=$`8UJI1pj4EH#BgZaYi|Z&qQMO}lbB*KiC-vS3U*CGi+{RulU|$-j zZGO5I`DFLIG52HY@`;Hx&AUI>Jo$o@;ZI|kW%&u$wm~XM&+F3SI+PGFnG_epWp~Qe zEAAezs$YNb^))SKLBA@NHLtx9?X*5lR$NVwm1KYfP&f0Q{(8U_H}_#cU{0fXpvm2N zSj1-=U zsoB|wPB^3@-vLjn7?Y+IKCyNH!^`mQDMuc%26;#?(!?Zd963?;roY|t{5VHtx z9$kroF>xDIRp2F<=OF}trSi!)+)I(`ykh(XfB*M#1xhwgnb(^7ql9fz3Bp4UhccUy z4Xed3YUTxSjh{U4!gIrbK)O|Kp_6IC;f`HnF&E-_9bI+5wJ64reoe_emNg&!MAtkt zQ!I~Eh9(OJ2~|a>S2Lr3sKYCoW6ufr(*vZUQFw;ppKd}1&n5O8;zcQWwv&}moL3I) z$oUd-bQv)dMnnrO-yc59bdIL&*8izGlO6eobVNC`BW)$$MJ-@Q?zZP7!UqS14Mz$! z-IT!AO|49aR21}7umEA&RE7(KDjl{T&zdky($z@`Y|iOq21D5c+J}D{MwgVm=sH#j z{jnSx(zF+C-q{?+G)65<@--b5DZPteZ}q(Hn!7i>vzI4{teKvE zA8137qp6a&B0u5}x1=~TTDTzRtE5SAo64u6>PAbZc^96c-8hu+ZW03{fdU$<1$RD4 zK6wc>mORu-Fr^@cES)9x_UUh$s@8nJ(5c0AZLi0(TW2qtu<8dR38%Ot<%BL;DtQwE zuWw<-M^^U9!7o#{O-mfYe1tXTVyu!kKqEwh`GY+fn!v=UF>f#Z-S#V}w`8M)tN+(_ zJhV7+DprXJRcm(C_A-l;+6dL2oxRA#;7@CQL<1T%=0O2*dLV^|ytGs2*q?c|YHqV# zaVtYcTqd*BM~+KzZd`MUnPVjU6r5eH9kT5Vh{aOxR)#nT5U^&XUdphnyqsSt#{-$& z>I3^Gb>)`_gPJ}C&^>T-pf!?Lu}Uq#w>yejnV}2z9e=U@!}+sgKmYf0>V=z!^O{P- z)T&#P3pO=~yUg*HRySX(8n)z2Sf?0Pxb$-7*lRor2-xy}{+nxW^Rzag;~y~_=Yw^v zuKH4G`*h#rde^QmG#I!su_KXcE3}(r{2=A#XRoZP8Sa`4g$2DlyutG6bTL0O5+P=6 zmK!!{ES}rC;J^N7c6Nwi2$M2zJNSKj_|Zi@x1ZGXZpvOBCfCNiqr9N9k0I0{a$@ao zA;&hb=uP)ht~axcc-(r05kb#=Z{#c(pEu^ZVe5+pbDI%nh=xUYa1f_q7I1-S$lT*6 z`ue6j5;HlXVFmq~(uavfKqgJfB9N54O8BrZE35!ZVp?GqQ^SbGQm=d#VrEmldBY_n z#WuN{pp{rJ8w4|2QglHs`mZo-+7fwK6tTqoe!{z)AD=1WO@qRwq|CRTXf-XnUGEsN z^#0V_%Wg%e(aIx=>VjSIp*3BzdvaG#{AF3WNZb@X2Nb=PVugy4_f4F&= z>SGZfNvpq}X-!~Wl045P8!P8W^wxS@=j9J-tai!Ii~kh@oNddbd!}>D9&iK77SFAo z{QdWDn^DQ{UJT@KpYrp!`NMC1I=|nCGRhzLUWlmz#S3*SIL$zg+me{hP+MWD#k9!_ zg*i3zliOdsM=7dy-k+bAFdAdt3*BMf#Qba^rdo7icM=;trYOmXc{eI2?$6I432mhW dc_$Y2XtZrnnLGW;LpJ%uah8+)bz9Hf{}1l5mbCx? From c31851a40f99f5cf9a3fa531b72f6c5788a6c998 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 21 Apr 2022 13:05:18 -0700 Subject: [PATCH 0095/1499] Geneva Exporter - Set metric exporter temporality to delta (#323) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 13 ++++++++++++- .../GenevaMetricExporterExtensions.cs | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index d074d7b155..02cb9fb9ad 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,7 +2,18 @@ ## Unreleased -## 1.2.5 [2022-Apr-20] +## 1.2.6 [2022-Apr-21] + +* Set GenevaMetricExporter temporality preference back to Delta. +[323](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/323) + +## 1.2.5 [2022-Apr-20] Broken + +Note: This release was broken due to the GenevaMetricExporter +using a TemporalityPreference of Cumulative instead of Delta, it has been +unlisted from NuGet. +[303](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/303) +is the PR that introduced this bug to GenevaMetricExporterExtensions.cs * Update OTel SDK version to `1.2.0`. [319](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/319) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index 2698798ef0..8cedae0682 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -29,6 +29,7 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui var options = new GenevaMetricExporterOptions(); configure?.Invoke(options); - return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds)); + return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) + { TemporalityPreference = MetricReaderTemporalityPreference.Delta }); } } From 0f22e37db4a599c86af726ee8699375d3eb8fe12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Apr 2022 22:17:27 -0700 Subject: [PATCH 0096/1499] Bump codecov/codecov-action from 3.0.0 to 3.1.0 (#324) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.0.0...v3.1.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dotnet-core-cov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index bd30ca8327..82a78f4a4a 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -43,7 +43,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - uses: codecov/codecov-action@v3.0.0 + - uses: codecov/codecov-action@v3.1.0 with: file: TestResults/Cobertura.xml env_vars: OS From d4f94cc9e8e8c1020806855f5e9e0a850020caac Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Fri, 22 Apr 2022 07:45:42 +0200 Subject: [PATCH 0097/1499] Auto flush activity processor implementation and tests (#296). (#297) --- .../.publicApi/net461/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net5.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + src/OpenTelemetry.Extensions/CHANGELOG.md | 3 + src/OpenTelemetry.Extensions/README.md | 26 +++- .../Trace/AutoFlushActivityProcessor.cs | 111 ++++++++++++++++++ .../TracerProviderBuilderExtensions.cs | 60 ++++++++++ .../Trace/AutoFlushActivityProcessorTests.cs | 82 +++++++++++++ 8 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs create mode 100644 src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs diff --git a/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt index c654303a3a..7104e3f8ec 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt @@ -6,4 +6,6 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> Sys OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt index c654303a3a..7104e3f8ec 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt @@ -6,4 +6,6 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> Sys OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index c654303a3a..7104e3f8ec 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,4 +6,6 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> Sys OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 048b8e45e8..acdf9bb081 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Implemented auto flush activity processor + ([#297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/297)) + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index f48b095b49..f58476e242 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -12,4 +12,28 @@ future. ### AttachLogsToActivityEvent Adds a log processor which will convert log messages into events and attach them -to the currently running Activity. +to the currently running `Activity`. + +## Traces + +### AutoFlushActivityProcessor + +Processor that flushes its containing `TracerProvider` if an ended `Activity` +matches a predicate. Note that this processor must be added *after* exporter +related `Activity` processors. + +Example of AutoFlushActivityProcessor usage: + +```cs +public static TracerProviderBuilder AddMyExporter(this TracerProviderBuilder builder, MyExporterOptions options) +{ + return builder + .AddProcessor(new BatchActivityExportProcessor( + new MyExporter(options), + options.BatchExportProcessorOptions.MaxQueueSize, + options.BatchExportProcessorOptions.ScheduledDelayMilliseconds, + options.BatchExportProcessorOptions.ExporterTimeoutMilliseconds, + options.BatchExportProcessorOptions.MaxExportBatchSize)) + .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000); +} +``` diff --git a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs new file mode 100644 index 0000000000..02fc015f74 --- /dev/null +++ b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs @@ -0,0 +1,111 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Threading; + +namespace OpenTelemetry.Trace +{ + /// + /// Activity processor that flushes its containing if an ended + /// Activity matches a predicate. + /// + /// + /// Add this processor *after* exporter related Activity processors. + /// + internal sealed class AutoFlushActivityProcessor : BaseProcessor + { + private readonly Func predicate; + private readonly int timeoutMilliseconds; + + private TracerProvider? tracerProvider; + private bool canForceFlush = true; + + /// + /// Initializes a new instance of the class. + /// + /// Predicate that should return true to initiate a flush. + /// Timeout (in milliseconds) to use for flushing. Specify + /// to wait indefinitely. + /// + /// + /// Thrown when the timeoutMilliseconds is smaller than -1. + /// + /// + /// It's assumed that the predicate is defined as a lambda expression which is executed quite fast and + /// doesn't contain more complex code. The predicate must not create new Activity instances, + /// otherwise the behavior is undefined. Any exception thrown by the predicate will be swallowed and logged. + /// In case of an exception the predicate is treated as false which means flush will not be applied. + /// + internal AutoFlushActivityProcessor(Func predicate, int timeoutMilliseconds) + { + this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate)); + if (timeoutMilliseconds < Timeout.Infinite) + { + throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds)); + } + + this.timeoutMilliseconds = timeoutMilliseconds; + } + + /// + public override void OnEnd(Activity data) + { + if (!this.canForceFlush) + { + return; + } + + if (this.tracerProvider == null && this.ParentProvider != null) + { + this.tracerProvider = this.ParentProvider as TracerProvider; + this.canForceFlush = this.tracerProvider != null; + if (!this.canForceFlush) + { + return; + } + } + else if (this.ParentProvider == null) + { + return; + } + + var shouldFlush = this.RunPredicate(data); + if (shouldFlush) + { + this.tracerProvider.ForceFlush(this.timeoutMilliseconds); + } + } + + private bool RunPredicate(Activity data) + { + var shouldFlush = false; + try + { + shouldFlush = this.predicate(data); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Flushing predicate threw an exception. Flush of {typeof(TracerProvider)} was skipped.", ex); + } + + return shouldFlush; + } + } +} diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..5ae2437f52 --- /dev/null +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -0,0 +1,60 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Threading; + +namespace OpenTelemetry.Trace +{ + /// + /// Extension methods to simplify registering of auto flush Activity processor. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Adds auto flush Activity processor. + /// + /// being configured. + /// Predicate that should return true to initiate a flush. + /// Timeout (in milliseconds) to use for flushing. Specify + /// to wait indefinitely. + /// + /// Thrown when the builder is null. + /// The instance of to chain the calls. + /// + /// Add this processor *after* exporter related Activity processors. + /// It's assumed that the predicate is defined as a lambda expression which is executed quite fast and + /// doesn't contain more complex code. The predicate must not create new Activity instances, + /// otherwise the behavior is undefined. Any exception thrown by the predicate will be swallowed and logged. + /// In case of an exception the predicate is treated as false which means flush will not be applied. + /// + public static TracerProviderBuilder AddAutoFlushActivityProcessor( + this TracerProviderBuilder builder, + Func predicate, + int timeoutMilliseconds = 10000) + { + if (builder == null) + { + throw new ArgumentNullException(nameof(builder)); + } + +#pragma warning disable CA2000 // Dispose objects before losing scope + return builder.AddProcessor(new AutoFlushActivityProcessor(predicate, timeoutMilliseconds)); +#pragma warning restore CA2000 // Dispose objects before losing scope + } + } +} diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs new file mode 100644 index 0000000000..fc4af7e797 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -0,0 +1,82 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using Moq; +using Moq.Protected; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Tests.Trace +{ + public class AutoFlushActivityProcessorTests + { + [Fact] + public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMatchingSpan_Flush() + { + var mockExporting = new Mock>(); + + using var provider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(mockExporting.Object) + .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000) + .AddSource("foo") + .Build(); + + using var source = new ActivitySource("foo"); + using var activity = source.StartActivity("name", ActivityKind.Server); + activity.Dispose(); + + mockExporting.Protected().Verify("OnForceFlush", Times.Once(), 5_000); + } + + [Fact] + public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNonMatchingSpan_DoesNothing() + { + var mockExporting = new Mock>(); + + using var provider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(mockExporting.Object) + .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer)) + .AddSource("foo") + .Build(); + + using var source = new ActivitySource("foo"); + using var activity = source.StartActivity("name", ActivityKind.Client); + activity.Dispose(); + + mockExporting.Protected().Verify("OnForceFlush", Times.Never(), It.IsAny()); + } + + [Fact] + public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() + { + var mockExporting = new Mock>(); + + using var provider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(mockExporting.Object) + .AddAutoFlushActivityProcessor(_ => throw new Exception("Predicate throws an exception.")) + .AddSource("foo") + .Build(); + + using var source = new ActivitySource("foo"); + using var activity = source.StartActivity("name", ActivityKind.Server); + activity.Dispose(); + + mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); + } + } +} From 9b526793768cd8b807becee8af9083797959cf67 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 25 Apr 2022 06:57:29 -0700 Subject: [PATCH 0098/1499] add nuget badges for OpenTelemetry.Exporter.Geneva (#327) --- src/OpenTelemetry.Exporter.Geneva/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index eb7729a83c..23ffb6bcf0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -1,3 +1,6 @@ # Geneva Exporters for OpenTelemetry .NET +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) + TBD From fd4968edc0a0aa9254eadfd42fa276c117c66641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Apr 2022 19:31:40 -0700 Subject: [PATCH 0099/1499] Bump github/codeql-action from 1 to 2 (#328) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 307766987b..db3592479e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -37,7 +37,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -48,7 +48,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -62,4 +62,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From 5732bf396347e2c9242782641f35c6b4119abf88 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 26 Apr 2022 18:27:56 -0700 Subject: [PATCH 0100/1499] Add issue/pr templates (#330) --- .../ISSUE_TEMPLATE/comp_exporter_geneva.md | 42 +++++++++++++++++++ .github/ISSUE_TEMPLATE/miscellaneous.md | 15 +++++++ .github/PULL_REQUEST_TEMPLATE.md | 10 +++++ 3 files changed, 67 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_geneva.md create mode 100644 .github/ISSUE_TEMPLATE/miscellaneous.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md b/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md new file mode 100644 index 0000000000..f54d5bfc4b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md @@ -0,0 +1,42 @@ +--- +name: OpenTelemetry.Exporter.Geneva +about: Issue with OpenTelemetry.Exporter.Geneva +labels: comp:exporter.geneva +--- + +# Issue with OpenTelemetry.Exporter.Geneva + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* [OpenTelemetry.Exporter.Geneva + 1.2.6](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva/1.2.6) + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/miscellaneous.md b/.github/ISSUE_TEMPLATE/miscellaneous.md new file mode 100644 index 0000000000..d48762effb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/miscellaneous.md @@ -0,0 +1,15 @@ +--- +name: Miscellaneous (anything else) +about: Issue that does not fit into other categories +--- + +# Issue that does not fit into other categories + +**What are you trying to achieve?** + +What do you expect to see? + +**Additional context.** + +Add any other context about the problem here. If you followed an existing +documentation, please share the link to it. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..b5fc738afc --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +Fixes #. + +## Changes + +Please provide a brief description of the changes here. + +For significant contributions please make sure you have completed the following items: + +* [ ] Appropriate `CHANGELOG.md` updated for non-trivial changes +* [ ] Design discussion issue # From 4bde914f087a2452ba3d35f0c89a463c16de5ed5 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 27 Apr 2022 19:08:11 -0700 Subject: [PATCH 0101/1499] Add more issue templates and update contributing.md (#331) * add more templates * update contributing.md doc --- .../comp_contrib_extensions_awsxray.md | 41 +++++++++++++++++++ .../comp_contrib_instrumentation_aws.md | 41 +++++++++++++++++++ .../comp_contrib_instrumentation_awslambda.md | 41 +++++++++++++++++++ .../comp_exporter_stackdriver.md | 41 +++++++++++++++++++ .github/ISSUE_TEMPLATE/comp_extensions.md | 41 +++++++++++++++++++ .../comp_extensions_azuremonitor.md | 41 +++++++++++++++++++ .../comp_extensions_persistentstorage.md | 41 +++++++++++++++++++ ...omp_instrumentation_elasticsearchclient.md | 41 +++++++++++++++++++ ...omp_instrumentation_entityframeworkcore.md | 41 +++++++++++++++++++ .../comp_instrumentation_grpccore.md | 41 +++++++++++++++++++ .../comp_instrumentation_hangfire.md | 41 +++++++++++++++++++ .../comp_instrumentation_masstransit.md | 41 +++++++++++++++++++ .../comp_instrumentation_mysqldata.md | 41 +++++++++++++++++++ .../comp_instrumentation_owin.md | 41 +++++++++++++++++++ .../comp_instrumentation_quartz.md | 41 +++++++++++++++++++ .../comp_instrumentation_runtime.md | 41 +++++++++++++++++++ .../comp_instrumentation_wcf.md | 41 +++++++++++++++++++ CONTRIBUTING.md | 10 ++++- 18 files changed, 705 insertions(+), 2 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md create mode 100644 .github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md create mode 100644 .github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md create mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md create mode 100644 .github/ISSUE_TEMPLATE/comp_extensions.md create mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md create mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_owin.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md b/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md new file mode 100644 index 0000000000..e1c5b43942 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Contrib.Extensions.AWSXRay +about: Issue with OpenTelemetry.Contrib.Extensions.AWSXRay +labels: comp:contrib.extensions.awsxray +--- + +# Issue with OpenTelemetry.Contrib.Extensions.AWSXRay + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md new file mode 100644 index 0000000000..af4c13a952 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Contrib.Instrumentation.AWS +about: Issue with OpenTelemetry.Contrib.Instrumentation.AWS +labels: comp:contrib.instrumentation.aws +--- + +# Issue with OpenTelemetry.Contrib.Instrumentation.AWS + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md new file mode 100644 index 0000000000..dcb46e3c44 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Contrib.Instrumentation.AWSLambda +about: Issue with OpenTelemetry.Contrib.Instrumentation.AWSLambda +labels: comp:contrib.instrumentation.awslambda +--- + +# Issue with OpenTelemetry.Contrib.Instrumentation.AWSLambda + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md b/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md new file mode 100644 index 0000000000..6afeebd9c6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Exporter.Stackdriver +about: Issue with OpenTelemetry.Exporter.Stackdriver +labels: comp:exporter.stackdriver +--- + +# Issue with OpenTelemetry.Exporter.Stackdriver + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_extensions.md b/.github/ISSUE_TEMPLATE/comp_extensions.md new file mode 100644 index 0000000000..89fb00ecf1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_extensions.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Extensions +about: Issue with OpenTelemetry.Extensions +labels: comp:extensions +--- + +# Issue with OpenTelemetry.Extensions + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md b/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md new file mode 100644 index 0000000000..50f63a6386 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Extensions.AzureMonitor +about: Issue with OpenTelemetry.Extensions.AzureMonitor +labels: comp:extensions.azuremonitor +--- + +# Issue with OpenTelemetry.Extensions.AzureMonitor + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md new file mode 100644 index 0000000000..4c069cd0bb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Extensions.PersistentStorage +about: Issue with OpenTelemetry.Extensions.PersistentStorage +labels: comp:extensions.persistentstorage +--- + +# Issue with OpenTelemetry.Extensions.PersistentStorage + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md new file mode 100644 index 0000000000..9d534eae7e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.ElasticsearchClient +about: Issue with OpenTelemetry.Instrumentation.ElasticsearchClient +labels: comp:instrumentation.elasticsearchclient +--- + +# Issue with OpenTelemetry.Instrumentation.ElasticsearchClient + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md new file mode 100644 index 0000000000..9113cb62a4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.EntityFrameworkCore +about: Issue with OpenTelemetry.Instrumentation.EntityFrameworkCore +labels: comp:instrumentation.entityframeworkcore +--- + +# Issue with OpenTelemetry.Instrumentation.EntityFrameworkCore + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md new file mode 100644 index 0000000000..467441e7b3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.GrpcCore +about: Issue with OpenTelemetry.Instrumentation.GrpcCore +labels: comp:instrumentation.grpccore +--- + +# Issue with OpenTelemetry.Instrumentation.GrpcCore + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md new file mode 100644 index 0000000000..745d1427c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Hangfire +about: Issue with OpenTelemetry.Instrumentation.Hangfire +labels: comp:instrumentation.hangfire +--- + +# Issue with OpenTelemetry.Instrumentation.Hangfire + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md new file mode 100644 index 0000000000..720b590fb8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.MassTransit +about: Issue with OpenTelemetry.Instrumentation.MassTransit +labels: comp:instrumentation.masstransit +--- + +# Issue with OpenTelemetry.Instrumentation.MassTransit + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md new file mode 100644 index 0000000000..cd0c9b600a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.MySqlData +about: Issue with OpenTelemetry.Instrumentation.MySqlData +labels: comp:instrumentation.mysqldata +--- + +# Issue with OpenTelemetry.Instrumentation.MySqlData + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md new file mode 100644 index 0000000000..9557899b12 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Owin +about: Issue with OpenTelemetry.Instrumentation.Owin +labels: comp:instrumentation.owin +--- + +# Issue with OpenTelemetry.Instrumentation.Owin + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md new file mode 100644 index 0000000000..d58aa6d1cc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Quartz +about: Issue with OpenTelemetry.Instrumentation.Quartz +labels: comp:instrumentation.quartz +--- + +# Issue with OpenTelemetry.Instrumentation.Quartz + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md new file mode 100644 index 0000000000..9c0edab241 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Runtime +about: Issue with OpenTelemetry.Instrumentation.Runtime +labels: comp:instrumentation.runtime +--- + +# Issue with OpenTelemetry.Instrumentation.Runtime + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md new file mode 100644 index 0000000000..baa913280c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Wcf +about: Issue with OpenTelemetry.Instrumentation.Wcf +labels: comp:instrumentation.wcf +--- + +# Issue with OpenTelemetry.Instrumentation.Wcf + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a9746fc6b..f47506eb8d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -171,7 +171,7 @@ Usually it is a good idea to use the latest version. Example: ```xml - + ``` @@ -202,6 +202,12 @@ the `.github/workflows/` folder. [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml#L18) value to "OpenTelemetry.Contrib.Foo.Bar". +* Add an issue template in your PR. You can follow the existing issue templates, + e.g. [comp_extensions](./.github/ISSUE_TEMPLATE/comp_extensions.md). The + maintainer will help to create a new ["comp:" + label](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/labels?q=comp%3A) + once the PR is merged. + * Add a README file for your project describing how to install and use your package. Every project's README file needs to have a link to the Nuget package. You can use the below snippet for reference: @@ -215,5 +221,5 @@ the `.github/workflows/` folder. * When contributing a new project you are expected to assign either yourself or someone else who would take ownership for the component you are contributing. -Please add the right onwer for your project in the +Please add the right owner for your project in the [component_owners](./.github/component_owners.yml) file. From d12619224040d065a9c3f69412f420295836f463 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 28 Apr 2022 21:02:13 -0700 Subject: [PATCH 0102/1499] fix nullable warnings in guard class (#332) Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Internal/Guard.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Internal/Guard.cs b/src/OpenTelemetry.Internal/Guard.cs index 0f67354d8f..aefa4cb7b2 100644 --- a/src/OpenTelemetry.Internal/Guard.cs +++ b/src/OpenTelemetry.Internal/Guard.cs @@ -49,6 +49,8 @@ public CallerArgumentExpressionAttribute(string parameterName) } #endif +#nullable enable + #pragma warning disable SA1403 // File may only contain a single namespace namespace OpenTelemetry.Internal #pragma warning restore SA1403 // File may only contain a single namespace @@ -65,7 +67,7 @@ internal static class Guard /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNull(object value, [CallerArgumentExpression("value")] string paramName = null) + public static void ThrowIfNull(object value, [CallerArgumentExpression("value")] string? paramName = null) { if (value is null) { @@ -80,7 +82,7 @@ public static void ThrowIfNull(object value, [CallerArgumentExpression("value")] /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNullOrEmpty(string value, [CallerArgumentExpression("value")] string paramName = null) + public static void ThrowIfNullOrEmpty(string value, [CallerArgumentExpression("value")] string? paramName = null) { if (string.IsNullOrEmpty(value)) { @@ -95,7 +97,7 @@ public static void ThrowIfNullOrEmpty(string value, [CallerArgumentExpression("v /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNullOrWhitespace(string value, [CallerArgumentExpression("value")] string paramName = null) + public static void ThrowIfNullOrWhitespace(string value, [CallerArgumentExpression("value")] string? paramName = null) { if (string.IsNullOrWhiteSpace(value)) { @@ -111,7 +113,7 @@ public static void ThrowIfNullOrWhitespace(string value, [CallerArgumentExpressi /// 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("value")] string? paramName = null) { if (value == 0) { @@ -126,7 +128,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("value")] string? paramName = null) { ThrowIfOutOfRange(value, paramName, min: Timeout.Infinite, message: $"Must be non-negative or '{nameof(Timeout)}.{nameof(Timeout.Infinite)}'"); } @@ -143,7 +145,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("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); } @@ -160,7 +162,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("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); } @@ -174,7 +176,7 @@ public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression("va /// The value casted to the specified type. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ThrowIfNotOfType(object value, [CallerArgumentExpression("value")] string paramName = null) + public static T ThrowIfNotOfType(object value, [CallerArgumentExpression("value")] string? paramName = null) { if (value is not T result) { @@ -186,7 +188,7 @@ public static T ThrowIfNotOfType(object value, [CallerArgumentExpression("val [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void Range(T value, string paramName, T min, T max, string minName, string maxName, string message) + private static void Range(T value, string? paramName, T min, T max, string? minName, string? maxName, string? message) where T : IComparable { if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) From b2460e215cb704454ea96e53ea8cdf545cfa7f3a Mon Sep 17 00:00:00 2001 From: xiang17 Date: Thu, 28 Apr 2022 21:08:21 -0700 Subject: [PATCH 0103/1499] Add OpenTelemetry.Instrumentation.Runtime component (#325) --- .github/component_owners.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 256d608bbe..2ce122bf2d 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -32,6 +32,9 @@ components: - codeblanch src/OpenTelemetry.Instrumentation.Quartz/: - maldago + src/OpenTelemetry.Instrumentation.Runtime/: + - twenzel + - xiang17 src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch @@ -79,5 +82,8 @@ components: - codeblanch test/OpenTelemetry.Instrumentation.Quartz.Tests/: - maldago + test/OpenTelemetry.Instrumentation.Runtime.Tests/: + - twenzel + - xiang17 test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch From 09cf306f43cfd5d55e0e07f5e3d2d00d59d621df Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Thu, 28 Apr 2022 21:55:29 -0700 Subject: [PATCH 0104/1499] tweak codecov.yml (#333) --- .github/codecov.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/codecov.yml b/.github/codecov.yml index cf7b065a15..df54634a71 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -5,6 +5,9 @@ coverage: precision: 2 round: down range: "70...100" + status: + project: off + patch: off parsers: gcov: @@ -20,6 +23,6 @@ comment: require_changes: no ignore: - - "test/**/*" # ignore test folder - - "**.md" # ignore md files + - "**.md" - "src/OpenTelemetry.Contrib.Shared" # copied from main OTel project and has code coverage there + - "test/**/*" From ba084736316ef5afb6398f95d637ac132b63c257 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 29 Apr 2022 13:38:40 -0700 Subject: [PATCH 0105/1499] Separate persistent storage api (#221) * spearate persistent storage api * indent * fix md error * remove contrib * add to sln * codeowners update * fix namespace * add api proj * change name to abstractions * reoslve PR comments * remove interfaces * remove contrib * fix comments * remove unnecessary usings * minor fix * resolve PR comments * resolve PR comment --- opentelemetry-dotnet-contrib.sln | 7 + .../CHANGELOG.md | 9 ++ ...ions.PersistentStorage.Abstractions.csproj | 13 ++ .../PersistentBlob.cs | 123 ++++++++++++++++ .../PersistentBlobProvider.cs | 133 ++++++++++++++++++ .../README.md | 10 ++ 6 files changed, 295 insertions(+) create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 9546ca8ca5..8e34330f7d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -182,6 +182,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Abstractions", "src\OpenTelemetry.Extensions.PersistentStorage.Abstractions\OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj", "{17E3936A-265A-4C9F-9DD5-4568F80E6D91}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -372,6 +374,10 @@ Global {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.Build.0 = Release|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -429,6 +435,7 @@ Global {A3EB4E60-256C-45EC-92EE-68FD035CAD11} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {17E3936A-265A-4C9F-9DD5-4568F80E6D91} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md new file mode 100644 index 0000000000..7f84dab7e5 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## Unreleased + +This is the first release for the `OpenTelemetry.Extensions.PersistentStorage.Abstractions` +project. + +For more details, please refer to the +[README](README.md) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj new file mode 100644 index 0000000000..7590f91c89 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.0;net462 + OpenTelemetry Persistent Storage Abstractions + Extensions.PersistentStorage.Abstractions- + + + + $(NoWarn),1591 + + + diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs new file mode 100644 index 0000000000..82467df7cf --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs @@ -0,0 +1,123 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions +{ + /// + /// Represents a persistent blob. + /// + public abstract class PersistentBlob + { + /// + /// Attempts to read the content from the blob. + /// + /// + /// The content to be read. + /// + /// + /// True if read was successful or else false. + /// + public bool TryRead(out byte[] buffer) + { + try + { + return this.OnTryRead(out buffer); + } + catch (Exception) + { + // TODO: log exception. + buffer = null; + return false; + } + } + + /// + /// Attempts to write the given content to the blob. + /// + /// + /// The content to be written. + /// + /// + /// The number of milliseconds to lease after the write operation finished. + /// + /// + /// True if the write operation succeeded or else false. + /// + public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) + { + try + { + return this.OnTryWrite(buffer, leasePeriodMilliseconds); + } + catch (Exception) + { + // TODO: log exception. + return false; + } + } + + /// + /// Attempts to acquire lease on the blob. + /// + /// + /// The number of milliseconds to lease. + /// + /// + /// true if lease is acquired or else false. + /// + public bool TryLease(int leasePeriodMilliseconds) + { + try + { + return this.OnTryLease(leasePeriodMilliseconds); + } + catch (Exception) + { + // TODO: log exception. + return false; + } + } + + /// + /// Attempts to delete the blob. + /// + /// + /// True if delete was successful else false. + /// + public bool TryDelete() + { + try + { + return this.OnTryDelete(); + } + catch (Exception) + { + // TODO: log exception. + return false; + } + } + + protected abstract bool OnTryRead(out byte[] buffer); + + protected abstract bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0); + + protected abstract bool OnTryLease(int leasePeriodMilliseconds); + + protected abstract bool OnTryDelete(); + } +} diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs new file mode 100644 index 0000000000..be35939d5b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -0,0 +1,133 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions +{ + /// + /// Represents persistent blob provider. + /// + public abstract class PersistentBlobProvider + { + /// + /// Attempts to create a new blob with the provided data and lease it. + /// + /// + /// The content to be written. + /// + /// + /// The number of milliseconds to lease after the blob is created. + /// + /// + /// Blob if it is created. + /// + /// + /// True if the blob was created or else false. + /// + public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out PersistentBlob blob) + { + try + { + return this.OnTryCreateBlob(buffer, leasePeriodMilliseconds, out blob); + } + catch (Exception) + { + // TODO: log exception. + blob = null; + return false; + } + } + + /// + /// Attempts to create a new blob with the provided data. + /// + /// + /// The content to be written. + /// + /// + /// Blob if it is created. + /// + /// + /// True if the blob was created or else false. + /// + public bool TryCreateBlob(byte[] buffer, out PersistentBlob blob) + { + try + { + return this.OnTryCreateBlob(buffer, out blob); + } + catch (Exception) + { + // TODO: log exception; + blob = null; + return false; + } + } + + /// + /// Attempts to get a single blob from storage. + /// + /// + /// Blob object if found. + /// + /// + /// True if blob is present or else false. + /// + public bool TryGetBlob(out PersistentBlob blob) + { + try + { + return this.OnTryGetBlob(out blob); + } + catch (Exception) + { + // TODO: log exception. + blob = null; + return false; + } + } + + /// + /// Reads a sequence of blobs from storage. + /// + /// + /// List of blobs if present in storage or else empty collection. + /// + public IEnumerable GetBlobs() + { + try + { + return this.OnGetBlobs() ?? Enumerable.Empty(); + } + catch (Exception) + { + // TODO: log exception + return Enumerable.Empty(); + } + } + + protected abstract IEnumerable OnGetBlobs(); + + protected abstract bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out PersistentBlob blob); + + protected abstract bool OnTryCreateBlob(byte[] buffer, out PersistentBlob blob); + + protected abstract bool OnTryGetBlob(out PersistentBlob blob); + } +} diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md new file mode 100644 index 0000000000..adbb4a187e --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md @@ -0,0 +1,10 @@ +# Persistent Storage Interface + +This package includes APIs which can be extended by exporter owners to implement +persistent storage. + +## Installation + +```shell +dotnet add package OpenTelemetry.Extensions.PersistentStorage.Abstractions +``` From 65a07cad4fe75a458435bd91877c8da1a0f7da95 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 2 May 2022 11:02:53 -0700 Subject: [PATCH 0106/1499] dotnet format CI skipped when no `.md` files modified (#336) --- .github/workflows/dotnet-format-md.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/dotnet-format-md.yml diff --git a/.github/workflows/dotnet-format-md.yml b/.github/workflows/dotnet-format-md.yml new file mode 100644 index 0000000000..45be5b05fb --- /dev/null +++ b/.github/workflows/dotnet-format-md.yml @@ -0,0 +1,21 @@ +# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks + +# Description: This workflow exists to unblock documentation-only PRs. + +# IMPORTANT: This workflow MUST use the same 'name' and 'matrix' as the non -md workflow. + +name: dotnet format + +on: + pull_request: + branches: [ main ] + paths: + - '**.md' + +jobs: + check-format: + runs-on: ubuntu-latest + + steps: + run: 'echo "No build required"' From 73415fcb03fe815868ca04b3ebd88370313d9c26 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 2 May 2022 11:09:20 -0700 Subject: [PATCH 0107/1499] Create windows-ci-md.yml (#339) Co-authored-by: Cijo Thomas --- .github/workflows/windows-ci-md.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/windows-ci-md.yml diff --git a/.github/workflows/windows-ci-md.yml b/.github/workflows/windows-ci-md.yml new file mode 100644 index 0000000000..dce6fa9c72 --- /dev/null +++ b/.github/workflows/windows-ci-md.yml @@ -0,0 +1,25 @@ +# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks + +# Description: This workflow exists to unblock documentation-only PRs. + +# IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow. + +name: Windows + +on: + pull_request: + branches: [ main ] + paths: + - '**.md' + +jobs: + build-test: + runs-on: ubuntu-latest + + strategy: + matrix: + version: [net461,netcoreapp3.1,net5.0,net6.0] + + steps: + - run: 'echo "No build required"' From 584654cb967bc8f6a65d9e9055f486ab7c2efe93 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 2 May 2022 11:38:21 -0700 Subject: [PATCH 0108/1499] Create linux-ci-md.yml (#338) Co-authored-by: Cijo Thomas --- .github/workflows/linux-ci-md.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/linux-ci-md.yml diff --git a/.github/workflows/linux-ci-md.yml b/.github/workflows/linux-ci-md.yml new file mode 100644 index 0000000000..b55ee6c7ed --- /dev/null +++ b/.github/workflows/linux-ci-md.yml @@ -0,0 +1,25 @@ +# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions +# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks + +# Description: This workflow exists to unblock documentation-only PRs. + +# IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow. + +name: Linux + +on: + pull_request: + branches: [ main ] + paths: + - '**.md' + +jobs: + build-test: + runs-on: ubuntu-latest + + strategy: + matrix: + version: [netcoreapp3.1,net5.0,net6.0] + + steps: + - run: 'echo "No build required"' From fe42963cf05aa65d1eb58b7b32f0857245f4e50a Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 2 May 2022 18:50:51 -0700 Subject: [PATCH 0109/1499] Editorial changes to the README.md (#340) --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0966cc38d9..eb87548c5a 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,17 @@ [![Linux](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/linux-ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/linux-ci.yml) [![Windows](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/windows-ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/windows-ci.yml) -This repository contains set of components extending functionality of the -OpenTelemetry SDK. Instrumentation libraries, exporters, and other components -can find their home here. - -Packages in this repository are prefixed with `OpenTelemetry.Contrib` to -highlight that they are different from the packages produced by the primary .NET -SDK repository. +This project is intended to provide helpful libraries and standalone +OpenTelemetry-based utilities that don't fit the express scope of the +[OpenTelemetry .NET](https://github.com/open-telemetry/opentelemetry-dotnet) or +[OpenTelemetry .NET Automatic +Instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation) +projects. ## Contributing For information on how to contribute, consult [the contributing -guidelines](./CONTRIBUTING.md) +guidelines](./CONTRIBUTING.md). ## Support From fc6a092372cb135b212d4a3c960e0f7c4d6fda66 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 6 May 2022 14:17:26 -0700 Subject: [PATCH 0110/1499] Enable public api check [OpenTelemetry.Extensions.PersistentStorage.Abstractions] (#337) * enable public api check * clscompliant false * resolve PR comments * add missing api dec * resolve PR comments * minor clean up Co-authored-by: Cijo Thomas --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 20 +++++++++++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 20 +++++++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 20 +++++++++++ .../AssemblyInfo.cs | 19 +++++++++++ .../NotNullWhenAttribute.cs | 33 +++++++++++++++++++ ...ions.PersistentStorage.Abstractions.csproj | 4 +++ .../PersistentBlob.cs | 13 ++++++-- .../PersistentBlobProvider.cs | 21 ++++++++---- 11 files changed, 145 insertions(+), 8 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..5fa88c4d7b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..5fa88c4d7b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..5fa88c4d7b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs new file mode 100644 index 0000000000..fb9851b200 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs @@ -0,0 +1,19 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +[assembly: CLSCompliant(false)] diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs new file mode 100644 index 0000000000..a84422c35b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs @@ -0,0 +1,33 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETSTANDARD2_0 || NET462 +namespace System.Diagnostics.CodeAnalysis +{ + [AttributeUsage(AttributeTargets.All)] + internal sealed class NotNullWhenAttribute : Attribute + { + /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => this.ReturnValue = returnValue; + + /// Gets a value indicating whether gets the return value condition. + public bool ReturnValue { get; } + } +} +#endif diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj index 7590f91c89..7c663ea313 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -2,12 +2,16 @@ netstandard2.0;net462 + $(TargetFrameworks);net6.0 OpenTelemetry Persistent Storage Abstractions Extensions.PersistentStorage.Abstractions- $(NoWarn),1591 + enable + true + true diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs index 82467df7cf..fd4f2d230c 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs @@ -15,6 +15,7 @@ // using System; +using System.Diagnostics.CodeAnalysis; namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions { @@ -32,8 +33,9 @@ public abstract class PersistentBlob /// /// True if read was successful or else false. /// - public bool TryRead(out byte[] buffer) + public bool TryRead([NotNullWhen(true)] out byte[]? buffer) { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryRead(out buffer); @@ -44,6 +46,7 @@ public bool TryRead(out byte[] buffer) buffer = null; return false; } +#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -60,6 +63,7 @@ public bool TryRead(out byte[] buffer) /// public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryWrite(buffer, leasePeriodMilliseconds); @@ -69,6 +73,7 @@ public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) // TODO: log exception. return false; } +#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -82,6 +87,7 @@ public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) /// public bool TryLease(int leasePeriodMilliseconds) { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryLease(leasePeriodMilliseconds); @@ -91,6 +97,7 @@ public bool TryLease(int leasePeriodMilliseconds) // TODO: log exception. return false; } +#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -101,6 +108,7 @@ public bool TryLease(int leasePeriodMilliseconds) /// public bool TryDelete() { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryDelete(); @@ -110,9 +118,10 @@ public bool TryDelete() // TODO: log exception. return false; } +#pragma warning restore CA1031 // Do not catch general exception types } - protected abstract bool OnTryRead(out byte[] buffer); + protected abstract bool OnTryRead([NotNullWhen(true)] out byte[]? buffer); protected abstract bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs index be35939d5b..431bf953e2 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions @@ -40,8 +41,9 @@ public abstract class PersistentBlobProvider /// /// True if the blob was created or else false. /// - public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out PersistentBlob blob) + public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob) { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryCreateBlob(buffer, leasePeriodMilliseconds, out blob); @@ -52,6 +54,7 @@ public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out Persis blob = null; return false; } +#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -66,8 +69,9 @@ public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out Persis /// /// True if the blob was created or else false. /// - public bool TryCreateBlob(byte[] buffer, out PersistentBlob blob) + public bool TryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob) { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryCreateBlob(buffer, out blob); @@ -78,6 +82,7 @@ public bool TryCreateBlob(byte[] buffer, out PersistentBlob blob) blob = null; return false; } +#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -89,8 +94,9 @@ public bool TryCreateBlob(byte[] buffer, out PersistentBlob blob) /// /// True if blob is present or else false. /// - public bool TryGetBlob(out PersistentBlob blob) + public bool TryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryGetBlob(out blob); @@ -101,6 +107,7 @@ public bool TryGetBlob(out PersistentBlob blob) blob = null; return false; } +#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -111,6 +118,7 @@ public bool TryGetBlob(out PersistentBlob blob) /// public IEnumerable GetBlobs() { +#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnGetBlobs() ?? Enumerable.Empty(); @@ -120,14 +128,15 @@ public IEnumerable GetBlobs() // TODO: log exception return Enumerable.Empty(); } +#pragma warning restore CA1031 // Do not catch general exception types } protected abstract IEnumerable OnGetBlobs(); - protected abstract bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out PersistentBlob blob); + protected abstract bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob); - protected abstract bool OnTryCreateBlob(byte[] buffer, out PersistentBlob blob); + protected abstract bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob); - protected abstract bool OnTryGetBlob(out PersistentBlob blob); + protected abstract bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob? blob); } } From bb01f8167b6a49d595f8bc055f5fc3f8552c1e6f Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Fri, 6 May 2022 19:24:18 -0700 Subject: [PATCH 0111/1499] Geneva Exporter - Throw on TableNameMappings `null` value (#322) --- .../CHANGELOG.md | 3 +++ .../GenevaExporterOptions.cs | 25 ++++++++++++++++++- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../GenevaLogExporterTests.cs | 20 +++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 02cb9fb9ad..83a089daac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Throw exception when `TableNameMappings` contains a `null` value. +[322](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/322) + ## 1.2.6 [2022-Apr-21] * Set GenevaMetricExporter temporality preference back to Delta. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 4ef5ad6621..63eba08012 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -27,11 +27,34 @@ public class GenevaExporterOptions [Schema.V40.PartA.Ver] = "4.0", }; + private IReadOnlyDictionary _tableNameMappings; + public string ConnectionString { get; set; } public IEnumerable CustomFields { get; set; } - public IReadOnlyDictionary TableNameMappings { get; set; } + public IReadOnlyDictionary TableNameMappings + { + get => this._tableNameMappings; + set + { + Guard.ThrowIfNull(value); + + var copy = new Dictionary(value.Count); + + foreach (var entry in value) + { + if (entry.Value is null) + { + throw new ArgumentNullException(entry.Key, $"{nameof(this.TableNameMappings)} must not contain null values."); + } + + copy[entry.Key] = entry.Value; + } + + this._tableNameMappings = copy; + } + } public IReadOnlyDictionary PrepopulatedFields { diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 11c0837589..097f916f46 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -1,4 +1,4 @@ - + true diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 58cda5efd4..276320ec9c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -62,6 +62,26 @@ public void SpecialChractersInTableNameMappings() TableNameMappings = new Dictionary { ["*"] = "\u0418" }, }); }); + + // Throw on null value - include key in exception message + var ex = Assert.Throws(() => + { + new GenevaExporterOptions + { + TableNameMappings = new Dictionary { ["TestCategory"] = null }, + }; + }); + Assert.Contains("TableNameMappings must not contain null values.", ex.Message); + Assert.Equal("TestCategory", ex.ParamName); + + // Throw when TableNameMappings is null + Assert.Throws(() => + { + new GenevaExporterOptions + { + TableNameMappings = null, + }; + }); } [Theory] From 5e0c058c64143c1f857599a6ad62d6c0e026871a Mon Sep 17 00:00:00 2001 From: Benjamin Evenson <2031163+benjiro@users.noreply.github.com> Date: Tue, 10 May 2022 00:09:36 +1000 Subject: [PATCH 0112/1499] Target OTel 1.2.0 for MassTransit, WCF, and EntityFrameworkCore (#347) --- .../CHANGELOG.md | 3 +++ ...y.Instrumentation.EntityFrameworkCore.csproj | 2 +- .../CHANGELOG.md | 3 +++ ...Telemetry.Instrumentation.MassTransit.csproj | 2 +- .../CHANGELOG.md | 5 +++++ .../OpenTelemetry.Instrumentation.Wcf.csproj | 2 +- .../EntityFrameworkDiagnosticListenerTests.cs | 1 - ...rumentation.EntityFrameworkCore.Tests.csproj | 17 ++++++++++++++--- ...try.Instrumentation.MassTransit.Tests.csproj | 2 +- ...enTelemetry.Instrumentation.Wcf.Tests.csproj | 6 +++--- 10 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 4ddc0afbbc..5c3885663a 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.2.0 + [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 358e34c17e..667f9e5435 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md index ddcf4e95aa..0dfc15b6ec 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.2.0 + [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj index fe595a0c0c..b546b34d47 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj @@ -7,7 +7,7 @@ true - + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index eb60e019dc..9b5516e1d8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +* Updated OTel SDK package version to 1.2.0 + [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) + ## 1.0.0-rc.6 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 8df5c7f41e..5bf42889b1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index fc289e31f2..fea2754b6e 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -24,7 +24,6 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Moq; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; -using OpenTelemetry.Internal; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 50250ee5a6..7ececc7d48 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -1,11 +1,22 @@  Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0;net6.0 + + + + + + + + + + + + - @@ -21,7 +32,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj index 3b8141c542..8c2b586ae3 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry MassTransit instrumentation - netcoreapp3.1 + netcoreapp3.1;net5.0;net6.0 $(TargetFrameworks);net461 true diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 076a025b57..25fac78dbc 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry WCF instrumentation - netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0;net6.0 $(TargetFrameworks);net462 @@ -26,8 +26,8 @@ - - + + From 25fac3c7a9cf991f5219897f95517aff564bf1ca Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 9 May 2022 16:12:42 -0700 Subject: [PATCH 0113/1499] exporter/geneva - Add README.md (#341) --- src/OpenTelemetry.Exporter.Geneva/README.md | 172 +++++++++++++++++++- 1 file changed, 170 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 23ffb6bcf0..48a96ff0eb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -1,6 +1,174 @@ -# Geneva Exporters for OpenTelemetry .NET +# Geneva Exporter for OpenTelemetry .NET [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) -TBD +The Geneva Exporter exports telemetry to +[Event Tracing for Windows (ETW)](https://docs.microsoft.com/windows/win32/etw/about-event-tracing) +or to a +[Unix Domain Socket (UDS)](https://en.wikipedia.org/wiki/Unix_domain_socket) +on the local machine. + +## Installation + +```shell +dotnet add package OpenTelemetry.Exporter.Geneva +``` + +## Configuration + +The three types of telemetry are handled separately in OpenTelemetry. +Therefore, each type of telemetry **must be** enabled separately. + +### Enable Logs + +Install the latest stable version of +[`Microsoft.Extensions.Logging`](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) + +```shell +dotnet add package OpenTelemetry.Exporter.Geneva +``` + +This snippet shows how to configure the Geneva Exporter for logs + +```csharp +using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder + .AddOpenTelemetry(openTelemetryLoggerOptions => + { + openTelemetryLoggerOptions.AddGenevaLogExporter(genevaExporterOptions => + { + genevaExporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + }); + })); +``` + +The above code must be in application startup. In case of ASP.NET Core +applications, this should be in `ConfigureServices` of `Startup` class. +For ASP.NET applications, this should be in `Global.aspx.cs`. + +Since OpenTelemetry .NET SDK is a +[LoggingProvider](https://docs.microsoft.com/dotnet/core/extensions/logging-providers), +use the built-in mechanism to apply [log +filtering](https://docs.microsoft.com/dotnet/core/extensions/logging?tabs=command-line#how-filtering-rules-are-applied). +This filtering lets you control the logs that are sent to each registered +provider, including the OpenTelemetry provider. `OpenTelemetry` is the +[alias](https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.provideraliasattribute) +for `OpenTelemetryLoggerProvider`, that may be used when configuring filtering +rules. + +**NOTE:** _Some application types (e.g. [ASP.NET +Core](https://docs.microsoft.com/aspnet/core/fundamentals/logging/#configure-logging-1)) +have default logging settings. Please review them to make sure +`OpenTelemetryLoggingProvider` is configured to receive logs of appropriate +levels and category. + +### Enable Traces + +This snippet shows how to configure the Geneva Exporter for traces + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource("DemoSource") + .AddGenevaTraceExporter(options => { + options.ConnectionString = "EtwSession=OpenTelemetry"; + }) + .Build(); +``` + +The above code must be in application startup. In case of ASP.NET Core +applications, this should be in `ConfigureServices` of `Startup` class. +For ASP.NET applications, this should be in `Global.aspx.cs`. + +### GenevaExporterOptions (for logs and traces) + +`GenevaExporterOptions` contains various options to configure the Geneva +Exporter. + +#### `ConnectionString` (required) + +On Linux the connection string has the format `Endpoint=unix:{UDS Path}`. + +On Windows the connection string has the format `EtwSession={ETW session}`. + +#### `CustomFields` (optional) + +A list of fields which should be stored as individual table columns. + +#### `PrepopulatedFields` (optional) + +This is a collection of fields that will be applied to all the logs and traces +sent through this exporter. + +#### `TableNameMappings` (optional) + +This defines the mapping for the table name used to store traces and logs. + +The default table name used for traces is `Span`. For changing the table name +for traces, add an entry with key as `Span`, and value as the custom table name. + +The default table name used for logs is `Log`. Mappings can be specified for +each +[category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) +of the log. For changing the default table name for logs, add an entry with key +as `*`, and value as the custom table name. + +### Enable Metrics + +**NOTE:** _Version 1.2.x of the Geneva Exporter (which adds Metrics support) +does not support .NET versions lower than .NET Framework 4.6.1._ + +This snippet shows how to configure the Geneva Exporter for metrics + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("TestMeter") + .AddGenevaMetricExporter(options => + { + options.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + }) + .Build(); +``` + +The above code must be in application startup. In case of ASP.NET Core +applications, this should be in `ConfigureServices` of `Startup` class. +For ASP.NET applications, this should be in `Global.aspx.cs`. + +### GenevaMetricExporterOptions (for metrics) + +`GenevaMetricExporterOptions` contains various options which are required to +configure the GenevaMetricExporter. + +#### `ConnectionString` (required for metrics) + +On Windows **DO NOT** provide an ETW session name for Metrics, only specify +Account and Namespace. For example: +`Account={MetricAccount};Namespace={MetricNamespace}`. + +On Linux provide an `Endpoint` in addition to the `Account` and `Namespace`. +For example: +`Endpoint=unix:{UDS Path};Account={MetricAccount};Namespace={MetricNamespace}`. + +#### `MetricExportIntervalMilliseconds` (optional) + +Set the exporter's periodic time interval to export metrics. The default value +is 20000 milliseconds. + +#### `PrepopulatedMetricDimensions` (optional) + +This is a collection of the dimensions that will be applied to _every_ metric +exported by the exporter. + +## Troubleshooting + +Before digging into a problem, check if you hit a known issue by looking at the +[CHANGELOG.md](./CHANGELOG.md) and [GitHub +issues](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues). + +Geneva Exporters uses an +[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) +with the name "OpenTelemetry-Exporter-Geneva" for its internal logging. Please +follow the [troubleshooting guide for OpenTelemetry +.NET](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry#troubleshooting) +for instructions on seeing logs from the geneva exporter, as well as other +OpenTelemetry components. From b99a67e9f843993746f4b2f047a99064395015da Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Tue, 10 May 2022 12:28:29 -0700 Subject: [PATCH 0114/1499] Update dotnet-format-md.yml (#344) Co-authored-by: Cijo Thomas --- .github/workflows/dotnet-format-md.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format-md.yml b/.github/workflows/dotnet-format-md.yml index 45be5b05fb..5453ddca94 100644 --- a/.github/workflows/dotnet-format-md.yml +++ b/.github/workflows/dotnet-format-md.yml @@ -18,4 +18,4 @@ jobs: runs-on: ubuntu-latest steps: - run: 'echo "No build required"' + - run: 'echo "No build required"' From 7d043e247a7fd0903c1c84bcea4190b688d7d960 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 11 May 2022 10:30:12 -0700 Subject: [PATCH 0115/1499] fix nits (#350) --- ...tensions_persistentstorage.abstractions.md | 41 +++++++++++++++++++ .../PersistentBlob.cs | 16 ++++---- .../PersistentBlobProvider.cs | 16 ++++---- 3 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md new file mode 100644 index 0000000000..7dd883b08a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Extensions.PersistentStorage.Abstractions +about: Issue with OpenTelemetry.Extensions.PersistentStorage.Abstractions +labels: comp:extensions.persistentstorage.abstractions +--- + +# Issue with OpenTelemetry.Extensions.PersistentStorage.Abstractions + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs index fd4f2d230c..92125f41ca 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs @@ -35,18 +35,18 @@ public abstract class PersistentBlob /// public bool TryRead([NotNullWhen(true)] out byte[]? buffer) { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryRead(out buffer); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception. buffer = null; return false; } -#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -63,17 +63,17 @@ public bool TryRead([NotNullWhen(true)] out byte[]? buffer) /// public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryWrite(buffer, leasePeriodMilliseconds); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception. return false; } -#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -87,17 +87,17 @@ public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) /// public bool TryLease(int leasePeriodMilliseconds) { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryLease(leasePeriodMilliseconds); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception. return false; } -#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -108,17 +108,17 @@ public bool TryLease(int leasePeriodMilliseconds) /// public bool TryDelete() { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryDelete(); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception. return false; } -#pragma warning restore CA1031 // Do not catch general exception types } protected abstract bool OnTryRead([NotNullWhen(true)] out byte[]? buffer); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs index 431bf953e2..224e3d47d7 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -43,18 +43,18 @@ public abstract class PersistentBlobProvider /// public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob) { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryCreateBlob(buffer, leasePeriodMilliseconds, out blob); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception. blob = null; return false; } -#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -71,18 +71,18 @@ public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWh /// public bool TryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob) { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryCreateBlob(buffer, out blob); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception; blob = null; return false; } -#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -96,18 +96,18 @@ public bool TryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? /// public bool TryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnTryGetBlob(out blob); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception. blob = null; return false; } -#pragma warning restore CA1031 // Do not catch general exception types } /// @@ -118,17 +118,17 @@ public bool TryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) /// public IEnumerable GetBlobs() { -#pragma warning disable CA1031 // Do not catch general exception types try { return this.OnGetBlobs() ?? Enumerable.Empty(); } +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types { // TODO: log exception return Enumerable.Empty(); } -#pragma warning restore CA1031 // Do not catch general exception types } protected abstract IEnumerable OnGetBlobs(); From 077363a5d824f311649ced5ddfe6877a9d9f896e Mon Sep 17 00:00:00 2001 From: fred2u Date: Wed, 11 May 2022 23:49:02 +0200 Subject: [PATCH 0116/1499] Target OTEL nuget package version 1.2.0 and add CHANGELOG.md (#353) --- .../CHANGELOG.md | 14 ++++++++++++++ .../OpenTelemetry.Instrumentation.Hangfire.csproj | 3 +-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md new file mode 100644 index 0000000000..e9f6c2776d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +## Unreleased + +## 1.2.0-beta1 + +* Updated OTel SDK package version to 1.2.0 + ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) + +## Initial Release + +* This is the first release of `OpenTelemetry.Instrumentation.Hangfire` package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 31a68bafd1..f1f983c7e0 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -8,9 +8,8 @@ - + - From 3883de8bf182a4c37472a4cc40f4bbd7056561fd Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 11 May 2022 16:02:42 -0700 Subject: [PATCH 0117/1499] GenevaTraceExporter bug fix to not export activities not sampled in (#352) --- .../CHANGELOG.md | 3 ++ .../GenevaExporterHelperExtensions.cs | 3 +- .../ReentrantActivityExportProcessor.cs | 40 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 83a089daac..816d10823f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,9 @@ * Throw exception when `TableNameMappings` contains a `null` value. [322](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/322) +* TraceExporter bug fix to not export non-recorded Activities. +[352](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/352) + ## 1.2.6 [2022-Apr-21] * Set GenevaMetricExporter temporality preference back to Delta. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 97425268be..5a14308ffe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -15,7 +15,6 @@ // using System; -using System.Diagnostics; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -48,7 +47,7 @@ private static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderB } else { - return builder.AddProcessor(new ReentrantExportProcessor(exporter)); + return builder.AddProcessor(new ReentrantActivityExportProcessor(exporter)); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs new file mode 100644 index 0000000000..81ca57cb3f --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Exporter.Geneva; + +// This export processor exports without synchronization. +// Once OpenTelemetry .NET officially support this, +// we can get rid of this class. +// This is currently only used in ETW export, where we know +// that the underlying system is safe under concurrent calls. +internal class ReentrantActivityExportProcessor : ReentrantExportProcessor +{ + public ReentrantActivityExportProcessor(BaseExporter exporter) + : base(exporter) + { + } + + protected override void OnExport(Activity data) + { + if (data.Recorded) + { + base.OnExport(data); + } + } +} From 055c156668db5bef6e89aa923411555e0c5cbe4d Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 11 May 2022 16:25:00 -0700 Subject: [PATCH 0118/1499] Minor readme file tweaks (#355) --- src/OpenTelemetry.Exporter.Geneva/README.md | 39 ++++++++++----------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 48a96ff0eb..24b0ca1626 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -29,7 +29,7 @@ Install the latest stable version of dotnet add package OpenTelemetry.Exporter.Geneva ``` -This snippet shows how to configure the Geneva Exporter for logs +This snippet shows how to configure the Geneva Exporter for Logs ```csharp using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder @@ -48,9 +48,9 @@ For ASP.NET applications, this should be in `Global.aspx.cs`. Since OpenTelemetry .NET SDK is a [LoggingProvider](https://docs.microsoft.com/dotnet/core/extensions/logging-providers), -use the built-in mechanism to apply [log +use the built-in mechanism to apply [Log filtering](https://docs.microsoft.com/dotnet/core/extensions/logging?tabs=command-line#how-filtering-rules-are-applied). -This filtering lets you control the logs that are sent to each registered +This filtering lets you control the Logs that are sent to each registered provider, including the OpenTelemetry provider. `OpenTelemetry` is the [alias](https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.provideraliasattribute) for `OpenTelemetryLoggerProvider`, that may be used when configuring filtering @@ -59,12 +59,12 @@ rules. **NOTE:** _Some application types (e.g. [ASP.NET Core](https://docs.microsoft.com/aspnet/core/fundamentals/logging/#configure-logging-1)) have default logging settings. Please review them to make sure -`OpenTelemetryLoggingProvider` is configured to receive logs of appropriate +`OpenTelemetryLoggingProvider` is configured to receive Logs of appropriate levels and category. ### Enable Traces -This snippet shows how to configure the Geneva Exporter for traces +This snippet shows how to configure the Geneva Exporter for Traces ```csharp using var tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -80,12 +80,12 @@ The above code must be in application startup. In case of ASP.NET Core applications, this should be in `ConfigureServices` of `Startup` class. For ASP.NET applications, this should be in `Global.aspx.cs`. -### GenevaExporterOptions (for logs and traces) +### GenevaExporterOptions (for Logs and Traces) `GenevaExporterOptions` contains various options to configure the Geneva Exporter. -#### `ConnectionString` (required) +#### `ConnectionString` (required for Logs and Traces) On Linux the connection string has the format `Endpoint=unix:{UDS Path}`. @@ -97,28 +97,25 @@ A list of fields which should be stored as individual table columns. #### `PrepopulatedFields` (optional) -This is a collection of fields that will be applied to all the logs and traces +This is a collection of fields that will be applied to all the Logs and Traces sent through this exporter. #### `TableNameMappings` (optional) -This defines the mapping for the table name used to store traces and logs. +This defines the mapping for the table name used to store Logs and Traces. -The default table name used for traces is `Span`. For changing the table name -for traces, add an entry with key as `Span`, and value as the custom table name. +The default table name used for Traces is `Span`. For changing the table name +for Traces, add an entry with key as `Span`, and value as the custom table name. -The default table name used for logs is `Log`. Mappings can be specified for +The default table name used for Logs is `Log`. Mappings can be specified for each [category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) -of the log. For changing the default table name for logs, add an entry with key +of the log. For changing the default table name for Logs, add an entry with key as `*`, and value as the custom table name. ### Enable Metrics -**NOTE:** _Version 1.2.x of the Geneva Exporter (which adds Metrics support) -does not support .NET versions lower than .NET Framework 4.6.1._ - -This snippet shows how to configure the Geneva Exporter for metrics +This snippet shows how to configure the Geneva Exporter for Metrics ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -134,12 +131,12 @@ The above code must be in application startup. In case of ASP.NET Core applications, this should be in `ConfigureServices` of `Startup` class. For ASP.NET applications, this should be in `Global.aspx.cs`. -### GenevaMetricExporterOptions (for metrics) +### GenevaMetricExporterOptions (for Metrics) `GenevaMetricExporterOptions` contains various options which are required to configure the GenevaMetricExporter. -#### `ConnectionString` (required for metrics) +#### `ConnectionString` (required for Metrics) On Windows **DO NOT** provide an ETW session name for Metrics, only specify Account and Namespace. For example: @@ -151,7 +148,7 @@ For example: #### `MetricExportIntervalMilliseconds` (optional) -Set the exporter's periodic time interval to export metrics. The default value +Set the exporter's periodic time interval to export Metrics. The default value is 20000 milliseconds. #### `PrepopulatedMetricDimensions` (optional) @@ -170,5 +167,5 @@ Geneva Exporters uses an with the name "OpenTelemetry-Exporter-Geneva" for its internal logging. Please follow the [troubleshooting guide for OpenTelemetry .NET](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry#troubleshooting) -for instructions on seeing logs from the geneva exporter, as well as other +for instructions on seeing Logs from the geneva exporter, as well as other OpenTelemetry components. From 560861664efee967572b03bbff42ae4bce751616 Mon Sep 17 00:00:00 2001 From: Swetha Ravichandran Date: Fri, 13 May 2022 04:07:08 +0530 Subject: [PATCH 0119/1499] Fix #197 - AWSEKSResourceDetector fails to detect resources due to exception "The SSL connection could not be established" (#208) * #197 - AWSEKSResourceDetector fails to detect resources due to exception "The SSL connection could not be established" Issue Description: With the current code, it requires an additional step of installing kubernetes self-signed certificate to the trusted store as .NET core expects them to the trsuted store to make a secure connection. Fix Provided: ServerCertificationValidationProvider - Safely loads the certificate to the trusted collection along with ServerSideValidation. This would avoid the unnecessary step of installing the certificate manually. Handler - Creates HttpClientHandler with client certificate. (cherry picked from commit 41e68d3c55ec3c61604a9c5ba07242747f5a17e9) * PR Review Comments (cherry picked from commit 0b5d9a9360c35e5db93f92e22fbea5f43b1adfd0) * Address PR comments (cherry picked from commit 4aa1c6213aabc78e60b841632ebc4db03cd4986c) * Remove unused import * Added Unit Tests * Removed unused directive * Added Trait for codecov build * Use temporary files to store test certificate * Fixed File Access Issue in Unit Test * Use TempFileName for Unit Tests * Added Debug logging for build test Fixed For loop tries * Revert "Added Debug logging for build test" This reverts commit b9823252f545324efc0031b0b654462085cb1f68. * Fixed tries logic in for loop Co-authored-by: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Co-authored-by: Igor Kiselev --- .../AWSXRayEventSource.cs | 6 + ...elemetry.Contrib.Extensions.AWSXRay.csproj | 4 +- .../Resources/AWSEKSResourceDetector.cs | 25 +-- .../Resources/Http/Handler.cs | 51 ++++++ .../ServerCertificateValidationProvider.cs | 161 ++++++++++++++++++ ...ry.Contrib.Extensions.AWSXRay.Tests.csproj | 4 + .../Resources/Http/CertificateUploader.cs | 84 +++++++++ .../Resources/Http/TestHandler.cs | 46 +++++ ...TestServerCertificateValidationProvider.cs | 62 +++++++ 9 files changed, 426 insertions(+), 17 deletions(-) create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs index 83e48a8931..945c09dc05 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs @@ -62,6 +62,12 @@ public void FailedToExtractResourceAttributes(string format, string exception) this.WriteEvent(3, format, exception); } + [Event(4, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] + public void FailedToValidateCertificate(string format, string error) + { + this.WriteEvent(4, format, error); + } + /// /// Returns a culture-independent string representation of the given object, /// appropriate for diagnostics tracing. diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 9e6e756ea4..108b059cf1 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -1,4 +1,4 @@ - + net452;netstandard2.0 OpenTelemetry extensions for AWS X-Ray. @@ -15,6 +15,8 @@ + + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index 2bc5850515..7be2e1ebd9 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -17,8 +17,8 @@ using System; using System.Collections.Generic; using System.Net.Http; -using System.Security.Cryptography.X509Certificates; using System.Text; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources @@ -41,13 +41,15 @@ public class AWSEKSResourceDetector : IResourceDetector public IEnumerable> Detect() { var credentials = this.GetEKSCredentials(AWSEKSCredentialPath); - if (credentials == null || !this.IsEKSProcess(credentials)) + var httpClientHandler = Handler.Create(AWSEKSCertificatePath); + + if (credentials == null || !this.IsEKSProcess(credentials, httpClientHandler)) { return null; } return this.ExtractResourceAttributes( - this.GetEKSClusterName(credentials), + this.GetEKSClusterName(credentials, httpClientHandler), this.GetEKSContainerId(AWSEKSMetadataFilePath)); } @@ -125,11 +127,11 @@ internal AWSEKSClusterInformationModel DeserializeResponse(string response) return ResourceDetectorUtils.DeserializeFromString(response); } - private string GetEKSClusterName(string credentials) + private string GetEKSClusterName(string credentials, HttpClientHandler httpClientHandler) { try { - var clusterInfo = this.GetEKSClusterInfo(credentials); + var clusterInfo = this.GetEKSClusterInfo(credentials, httpClientHandler); return this.DeserializeResponse(clusterInfo)?.Data?.ClusterName; } catch (Exception ex) @@ -140,12 +142,11 @@ private string GetEKSClusterName(string credentials) return null; } - private bool IsEKSProcess(string credentials) + private bool IsEKSProcess(string credentials, HttpClientHandler httpClientHandler) { string awsAuth = null; try { - var httpClientHandler = this.CreateHttpClientHandler(); awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; } catch (Exception ex) @@ -156,17 +157,9 @@ private bool IsEKSProcess(string credentials) return !string.IsNullOrEmpty(awsAuth); } - private string GetEKSClusterInfo(string credentials) + private string GetEKSClusterInfo(string credentials, HttpClientHandler httpClientHandler) { - var httpClientHandler = this.CreateHttpClientHandler(); return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; } - - private HttpClientHandler CreateHttpClientHandler() - { - var httpClientHandler = new HttpClientHandler(); - httpClientHandler.ClientCertificates.Add(new X509Certificate2(AWSEKSCertificatePath)); - return httpClientHandler; - } } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs new file mode 100644 index 0000000000..2b3326deb2 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs @@ -0,0 +1,51 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Net.Http; + +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http +{ + internal class Handler + { + public static HttpClientHandler Create(string certificateFile) + { + try + { + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateFile); + + if (!serverCertificateValidationProvider.IsCertificateLoaded) + { + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); + return null; + } + + var clientHandler = new HttpClientHandler(); + clientHandler.ServerCertificateCustomValidationCallback = + (sender, x509Certificate2, x509Chain, sslPolicyErrors) => + serverCertificateValidationProvider.ValidationCallback(null, x509Certificate2, x509Chain, sslPolicyErrors); + return clientHandler; + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex); + } + + return null; + } + } +} diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs new file mode 100644 index 0000000000..ce24067908 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs @@ -0,0 +1,161 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.IO; +using System.Linq; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; + +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http +{ + internal class ServerCertificateValidationProvider + { + private static readonly ServerCertificateValidationProvider InvalidProvider = + new ServerCertificateValidationProvider(null); + + private readonly X509Certificate2Collection trustedCertificates; + + private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates) + { + if (trustedCertificates == null) + { + this.trustedCertificates = null; + this.ValidationCallback = null; + this.IsCertificateLoaded = false; + return; + } + + this.trustedCertificates = trustedCertificates; + this.ValidationCallback = (sender, cert, chain, errors) => + this.ValidateCertificate(new X509Certificate2(cert), chain, errors); + this.IsCertificateLoaded = true; + } + + public bool IsCertificateLoaded { get; } + + public RemoteCertificateValidationCallback ValidationCallback { get; } + + public static ServerCertificateValidationProvider FromCertificateFile(string certificateFile) + { + if (!File.Exists(certificateFile)) + { + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); + return InvalidProvider; + } + + var trustedCertificates = new X509Certificate2Collection(); + if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile)) + { + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); + return InvalidProvider; + } + + return new ServerCertificateValidationProvider(trustedCertificates); + } + + private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName) + { + try + { + collection.Import(certFileName); + return true; + } + catch (Exception) + { + return false; + } + } + + private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPolicyErrors errors) + { + var isSslPolicyPassed = errors == SslPolicyErrors.None || + errors == SslPolicyErrors.RemoteCertificateChainErrors; + if (!isSslPolicyPassed) + { + if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) + { + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable"); + } + + if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors) + { + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch"); + } + } + + chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates); + chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; + + // building the chain to process basic validations e.g. signature, use, expiration, revocation + var isValidChain = chain.Build(cert); + + if (!isValidChain) + { + var chainErrors = string.Empty; + foreach (var element in chain.ChainElements) + { + foreach (var status in element.ChainElementStatus) + { + chainErrors += + $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}"; + } + } + + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}"); + } + + // check if at least one certificate in the chain is in our trust list + var isTrusted = this.HasCommonCertificate(chain, this.trustedCertificates); + if (!isTrusted) + { + var serverCertificates = string.Empty; + foreach (var element in chain.ChainElements) + { + serverCertificates += " " + element.Certificate.Subject; + } + + var trustCertificates = string.Empty; + foreach (var trustCertificate in this.trustedCertificates) + { + trustCertificates += " " + trustCertificate.Subject; + } + + AWSXRayEventSource.Log.FailedToValidateCertificate( + nameof(ServerCertificateValidationProvider), + $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}"); + } + + return isSslPolicyPassed && isValidChain && isTrusted; + } + + private bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection collection) + { + foreach (var chainElement in chain.ChainElements) + { + foreach (var certificate in collection) + { + if (Enumerable.SequenceEqual(chainElement.Certificate.GetPublicKey(), certificate.GetPublicKey())) + { + return true; + } + } + } + + return false; + } + } +} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index f596591539..274e57f917 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -30,6 +30,10 @@ + + + + diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs new file mode 100644 index 0000000000..152f6abc04 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs @@ -0,0 +1,84 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.IO; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Threading; + +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http +{ + internal class CertificateUploader : IDisposable + { + private const string CRTHEADER = "-----BEGIN CERTIFICATE-----\n"; + private const string CRTFOOTER = "\n-----END CERTIFICATE-----"; + private string filePath; + + public CertificateUploader() + { + this.filePath = Path.GetTempFileName(); + } + + public string FilePath + { + get { return this.filePath; } + set { this.filePath = value; } + } + + public void Create() + { + using var rsa = RSA.Create(); + var certRequest = new CertificateRequest("cn=test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + var subjectAlternativeNames = new SubjectAlternativeNameBuilder(); + subjectAlternativeNames.AddDnsName("test"); + certRequest.CertificateExtensions.Add(subjectAlternativeNames.Build()); + + // Create a temporary certificate and add validity for 1 day + var certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(1)); + + var exportData = certificate.Export(X509ContentType.Cert); + var crt = Convert.ToBase64String(exportData, Base64FormattingOptions.InsertLineBreaks); + + using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + { + using (StreamWriter sw = new StreamWriter(stream)) + { + sw.Write(CRTHEADER + crt + CRTFOOTER); + } + } + } + + public void Dispose() + { + for (int tries = 0; ; tries++) + { + try + { + File.Delete(this.filePath); + return; + } + catch (IOException) when (tries < 3) + { + // the file is unavailable because it is: still being written to or being processed by another thread + // sleep for sometime before deleting + Thread.Sleep(1000); + } + } + } + } +} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs new file mode 100644 index 0000000000..4d6b4703e3 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs @@ -0,0 +1,46 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; +using Xunit; + +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http +{ + [Trait("Platform", "Any")] + public class TestHandler + { + private const string INVALIDCRTNAME = "invalidcert"; + + [Fact] + public void TestValidHandler() + { + using (CertificateUploader certificateUploader = new CertificateUploader()) + { + certificateUploader.Create(); + + // Validates if the handler created. + Assert.NotNull(Handler.Create(certificateUploader.FilePath)); + } + } + + [Fact] + public void TestInValidHandler() + { + // Validates if the handler created if no certificate is loaded into the trusted collection + Assert.Null(Handler.Create(INVALIDCRTNAME)); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs new file mode 100644 index 0000000000..89355260b4 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs @@ -0,0 +1,62 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Security.Cryptography.X509Certificates; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; +using Xunit; + +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http +{ + [Trait("Platform", "Any")] + public class TestServerCertificateValidationProvider + { + private const string INVALIDCRTNAME = "invalidcert"; + + [Fact] + public void TestValidCertificate() + { + using (CertificateUploader certificateUploader = new CertificateUploader()) + { + certificateUploader.Create(); + + // Loads the certificate to the trusted collection from the file + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + + // Validates if the certificate loaded into the trusted collection. + Assert.True(serverCertificateValidationProvider.IsCertificateLoaded); + + var certificate = new X509Certificate2(certificateUploader.FilePath); + X509Chain chain = new X509Chain(); + chain.Build(certificate); + + // validates if certificate is valid + Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); + } + } + + [Fact] + public void TestInValidCertificate() + { + // Loads the certificate to the trusted collection from the file + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(INVALIDCRTNAME); + + // Validates if the certificate file loaded. + Assert.False(serverCertificateValidationProvider.IsCertificateLoaded); + } + } +} From 451e14fbac0e3b3f1dd400128dea9f895996392b Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 12 May 2022 17:05:22 -0700 Subject: [PATCH 0120/1499] Add support for the native Activity properties Status and StatusDescription (#359) * Add support for the native Activity properties `Status` and `StatusDescription` --- .../CHANGELOG.md | 29 +++++------ .../GenevaTraceExporter.cs | 41 +++++++++++++-- .../GenevaTraceExporterTests.cs | 50 +++++++++++++++++-- 3 files changed, 98 insertions(+), 22 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 816d10823f..95d9c0e3fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -8,6 +8,10 @@ * TraceExporter bug fix to not export non-recorded Activities. [352](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/352) +* Add support for the native `Activity` properties `Status` and +`StatusDescription`. +[359](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/359) + ## 1.2.6 [2022-Apr-21] * Set GenevaMetricExporter temporality preference back to Delta. @@ -15,9 +19,9 @@ ## 1.2.5 [2022-Apr-20] Broken -Note: This release was broken due to the GenevaMetricExporter -using a TemporalityPreference of Cumulative instead of Delta, it has been -unlisted from NuGet. +Note: This release was broken due to the GenevaMetricExporter using a +TemporalityPreference of Cumulative instead of Delta, it has been unlisted from +NuGet. [303](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/303) is the PR that introduced this bug to GenevaMetricExporterExtensions.cs @@ -26,20 +30,17 @@ is the PR that introduced this bug to GenevaMetricExporterExtensions.cs ## 1.2.4 [2022-Apr-20] Broken -This is the first release of the `OpenTelemetry.Exporter.Geneva` -project. -Note: This release was broken due to using OpenTelemetry 1.2.0-rc5. -Therefore, it has been unlisted on NuGet. +This is the first release of the `OpenTelemetry.Exporter.Geneva` project. Note: +This release was broken due to using OpenTelemetry 1.2.0-rc5. Therefore, it has +been unlisted on NuGet. -* LogExporter modified to stop calling `ToString()` -on `LogRecord.State` to obtain Log body. It now -obtains body from `LogRecord.FormattedMessage` -or special casing "{OriginalFormat}" only. +* LogExporter modified to stop calling `ToString()` on `LogRecord.State` to +obtain Log body. It now obtains body from `LogRecord.FormattedMessage` or +special casing "{OriginalFormat}" only. [295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) -* Fixed a bug which causes LogExporter to not -serialize if the `LogRecord.State` had a -single KeyValuePair. +* Fixed a bug which causes LogExporter to not serialize if the `LogRecord.State` +had a single KeyValuePair. [295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) * Update OTel SDK version to `1.2.0-rc5`. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 1c776d79d8..bbe5501481 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -106,6 +106,7 @@ public GenevaTraceExporter(GenevaExporterOptions options) } dedicatedFields["otel.status_code"] = true; + dedicatedFields["otel.status_description"] = true; this.m_dedicatedFields = dedicatedFields; } @@ -333,6 +334,9 @@ internal int SerializeActivity(Activity activity) // Iteration #1 - Get those fields which become dedicated column // i.e all PartB fields and opt-in part c fields. bool hasEnvProperties = false; + bool isStatusSuccess = true; + string statusDescription = string.Empty; + foreach (var entry in activity.TagObjects) { // TODO: check name collision @@ -344,11 +348,16 @@ internal int SerializeActivity(Activity activity) { if (string.Equals(entry.Value.ToString(), "ERROR", StringComparison.Ordinal)) { - MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); + isStatusSuccess = false; } continue; } + else if (string.Equals(entry.Key, "otel.status_description", StringComparison.Ordinal)) + { + statusDescription = entry.Value.ToString(); + continue; + } else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. @@ -391,6 +400,34 @@ internal int SerializeActivity(Activity activity) cntFields += 1; MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); } + + if (activity.Status != ActivityStatusCode.Unset) + { + if (activity.Status == ActivityStatusCode.Error) + { + MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); + } + + if (!string.IsNullOrEmpty(activity.StatusDescription)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "statusMessage"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, activity.StatusDescription); + cntFields += 1; + } + } + else + { + if (!isStatusSuccess) + { + MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); + if (!string.IsNullOrEmpty(statusDescription)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "statusMessage"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, statusDescription); + cntFields += 1; + } + } + } #endregion MessagePackSerializer.WriteUInt16(buffer, this.m_idxMapSizePatch, cntFields); @@ -436,8 +473,6 @@ internal int SerializeActivity(Activity activity) ["messaging.system"] = "messagingSystem", ["messaging.destination"] = "messagingDestination", ["messaging.url"] = "messagingUrl", - - ["otel.status_description"] = "statusMessage", }; private bool isDisposed; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 8474dc2b21..96d81a9d3e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -205,6 +205,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, // Set the ActivitySourceName to the unique value of the test method name to avoid interference with // the ActivitySource used by other unit tests. var sourceName = GetTestMethodName(); + Action> customChecksForActivity = null; using var listener = new ActivityListener(); listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; @@ -213,7 +214,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, { _ = exporter.SerializeActivity(activity); object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields); + this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields, customChecksForActivity); invocationCount++; }; ActivitySource.AddActivityListener(listener); @@ -246,11 +247,28 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); activity?.SetTag("foo", 1); activity?.SetTag("bar", 2); - activity?.SetStatus(Status.Error); + activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); } } - Assert.Equal(2, invocationCount); + using (var activity = source.StartActivity("TestActivityForSetStatusAPI")) + { + activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); + } + + // If the activity Status is set using both the OTel API and the .NET API, the `Status` and `StatusDescription` set by + // the .NET API is chosen + using (var activity = source.StartActivity("PreferStatusFromDotnetAPI")) + { + activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); + activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); + customChecksForActivity = mapping => + { + Assert.Equal("Error description from .NET API", mapping["statusMessage"]); + }; + } + + Assert.Equal(4, invocationCount); } finally { @@ -397,7 +415,7 @@ private static string GetTestMethodName([CallerMemberName] string callingMethodN return callingMethodName; } - private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, IReadOnlyDictionary dedicatedFields) + private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, IReadOnlyDictionary dedicatedFields, Action> customChecksForActivity) { /* Fluentd Forward Mode: [ @@ -461,7 +479,22 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO Assert.Equal(activity.StartTimeUtc, mapping["startTime"]); var activityStatusCode = activity.GetStatus().StatusCode; - Assert.Equal(activityStatusCode == StatusCode.Error ? false : true, mapping["success"]); + + if (activity.Status == ActivityStatusCode.Error) + { + Assert.False((bool)mapping["success"]); + Assert.Equal(activity.StatusDescription, mapping["statusMessage"]); + } + else if (activityStatusCode == StatusCode.Error) + { + Assert.False((bool)mapping["success"]); + var activityStatusDesc = activity.GetStatus().Description; + Assert.Equal(activityStatusDesc, mapping["statusMessage"]); + } + else + { + Assert.True((bool)mapping["success"]); + } // Part B Span optional fields and Part C fields if (activity.ParentSpanId != default) @@ -509,6 +542,11 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO // Status code check is already done when we check for "success" key in the mapping continue; } + else if (string.Equals(tag.Key, "otel.status_description", StringComparison.Ordinal)) + { + // Status description check is already done when we check for "statusMessage" key in the mapping + continue; + } else { // If CustomFields are proivded, dedicatedFields will be populated @@ -526,6 +564,8 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO // Epilouge Assert.Equal("DateTime", timeFormat["TimeFormat"]); + + customChecksForActivity?.Invoke(mapping); } } } From af8724a98159c4c75e58af249cd2ad466fef0ac7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 13 May 2022 13:24:27 -0700 Subject: [PATCH 0121/1499] Add eventsource - PersistentStorage.Abstractions (#354) --- ...ions.PersistentStorage.Abstractions.csproj | 1 + .../PersistentBlob.cs | 24 +++---- .../PersistentBlobProvider.cs | 24 +++---- ...ersistentStorageAbstractionsEventSource.cs | 64 +++++++++++++++++++ 4 files changed, 81 insertions(+), 32 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj index 7c663ea313..92d663befe 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -5,6 +5,7 @@ $(TargetFrameworks);net6.0 OpenTelemetry Persistent Storage Abstractions Extensions.PersistentStorage.Abstractions- + $(NoWarn),CA1031 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs index 92125f41ca..ab963bb185 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs @@ -39,11 +39,9 @@ public bool TryRead([NotNullWhen(true)] out byte[]? buffer) { return this.OnTryRead(out buffer); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception. + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to read the blob.", ex); buffer = null; return false; } @@ -67,11 +65,9 @@ public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) { return this.OnTryWrite(buffer, leasePeriodMilliseconds); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception. + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to write the blob", ex); return false; } } @@ -91,11 +87,9 @@ public bool TryLease(int leasePeriodMilliseconds) { return this.OnTryLease(leasePeriodMilliseconds); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception. + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to lease the blob", ex); return false; } } @@ -112,11 +106,9 @@ public bool TryDelete() { return this.OnTryDelete(); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception. + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to delete the blob", ex); return false; } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs index 224e3d47d7..486b250690 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -47,11 +47,9 @@ public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWh { return this.OnTryCreateBlob(buffer, leasePeriodMilliseconds, out blob); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception. + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to create and lease the blob", ex); blob = null; return false; } @@ -75,11 +73,9 @@ public bool TryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? { return this.OnTryCreateBlob(buffer, out blob); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception; + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to create the blob", ex); blob = null; return false; } @@ -100,11 +96,9 @@ public bool TryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) { return this.OnTryGetBlob(out blob); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception. + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get a single blob", ex); blob = null; return false; } @@ -122,11 +116,9 @@ public IEnumerable GetBlobs() { return this.OnGetBlobs() ?? Enumerable.Empty(); } -#pragma warning disable CA1031 // Do not catch general exception types - catch (Exception) -#pragma warning restore CA1031 // Do not catch general exception types + catch (Exception ex) { - // TODO: log exception + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get all the blobs", ex); return Enumerable.Empty(); } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs new file mode 100644 index 0000000000..717940aaa6 --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -0,0 +1,64 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Threading; + +namespace OpenTelemetry.Extensions.PersistentStorage +{ + [EventSource(Name = EventSourceName)] + internal sealed class PersistentStorageAbstractionsEventSource : EventSource + { + public static PersistentStorageAbstractionsEventSource Log = new PersistentStorageAbstractionsEventSource(); + private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage-Abstractions"; + + [NonEvent] + public void PersistentStorageAbstractionsException(string className, string message, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.PersistentStorageAbstractionsException(className, message, ToInvariantString(ex)); + } + } + + [Event(1, Message = "{0}: {1}: {2}", Level = EventLevel.Error)] + public void PersistentStorageAbstractionsException(string className, string message, string ex) + { + this.WriteEvent(1, className, message, ex); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + } +} From a95cf1d410506e0813208ca21bf5d0c635b23910 Mon Sep 17 00:00:00 2001 From: Benjamin Evenson <2031163+benjiro@users.noreply.github.com> Date: Sat, 14 May 2022 06:37:11 +1000 Subject: [PATCH 0122/1499] Upgrade Stackdriver support to OTel 1.2.0 (#357) --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 5 +++++ .../OpenTelemetry.Exporter.Stackdriver.csproj | 8 ++++---- ...penTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 683a9c3cf5..4ff1c37e1c 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Updated OTel SDK package version to 1.2.0 +* Updated minimum full framework support to net462 +* Update Google.Cloud.Monitoring.V3 2.1.0 -> 2.6.0 +* Update Google.Cloud.Monitoring.V3 2.0.0 -> 2.3.0 + ## 1.0.0-beta.2 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index f8feeb83fd..5ff84b77fb 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -1,14 +1,14 @@  - netstandard2.0;net461 + netstandard2.0;net462 Stackdriver .NET Exporter for OpenTelemetry. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- - - - + + + diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj index e96f112b44..c3e4f1bf49 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj @@ -1,8 +1,8 @@  Unit test project for Stackdriver Exporter for OpenTelemetry - netcoreapp3.1 - $(TargetFrameworks);net461 + netcoreapp3.1;net5.0;net6.0 + $(TargetFrameworks);net462 From 2b41bd6e3a5355154954218913597c995b02c21c Mon Sep 17 00:00:00 2001 From: Benjamin Evenson <2031163+benjiro@users.noreply.github.com> Date: Sat, 14 May 2022 09:59:22 +1000 Subject: [PATCH 0123/1499] Upgrade ElasticsearchClient support to Otel 1.2.0 (#358) --- .../CHANGELOG.md | 3 +++ ...enTelemetry.Instrumentation.ElasticsearchClient.csproj | 6 +++--- ...metry.Instrumentation.ElasticsearchClient.Tests.csproj | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 902b51c786..75ed5233f9 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.2.0 +* Update minimum full framework support to net462 + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index dc98d62fad..9d8f512ec9 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -1,14 +1,14 @@  - netstandard2.0;net461 + netstandard2.0;net462 Elasticsearch instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- true - - + + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 22417858df..8e230718e9 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,14 +1,14 @@  Unit test project for OpenTelemetry Elasticsearch client instrumentation - netcoreapp3.1 + netcoreapp3.1;net5.0;net6.0 true - - - + + + all runtime; build; native; contentfiles; analyzers From 002430cdb66a361f94997fc9af7611357f08f6e5 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 16 May 2022 14:18:26 -0700 Subject: [PATCH 0124/1499] Add release workflow - PersistentStorage.Abstractions (#360) * add release workflow --- .github/component_owners.yml | 2 + ...ensions.PersistentStorage.Abstractions.yml | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 .github/workflows/package-Extensions.PersistentStorage.Abstractions.yml diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 2ce122bf2d..6e96b7e85e 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -16,6 +16,8 @@ components: - SergeyKanzhelev src/OpenTelemetry.Extensions/: - codeblanch + src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/: + - vishweshbankwar src/OpenTelemetry.Extensions.PersistentStorage/: - vishweshbankwar src/OpenTelemetry.Instrumentation.ElasticsearchClient/: diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml new file mode 100644 index 0000000000..25c1592090 --- /dev/null +++ b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Extensions.PersistentStorage.Abstractions + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Extensions.PersistentStorage.Abstractions-*' # trigger when we create a tag with prefix "Extensions.PersistentStorage.Abstractions-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Extensions.PersistentStorage.Abstractions + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} From 0b96d6f0f6dcacf2ed11a3390d4f29f378cc9a69 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 16 May 2022 15:58:45 -0700 Subject: [PATCH 0125/1499] add workflow to sln (#361) --- opentelemetry-dotnet-contrib.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 8e34330f7d..aaf68749fd 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -34,6 +34,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml + .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml From 9a15e228e5634b70b21cd7e8b04a02f2278df707 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Wed, 18 May 2022 09:22:17 -0700 Subject: [PATCH 0126/1499] Extensions.AWSXRay Changelog update for v1.2.0 release (#364) * Extensions.AWSXRay Changelog update * Fix linting in markdown --- .../CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index ac59da2310..4c1b4b9c15 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog - OpenTelemetry.Contrib.Extensions.AWSXRay +## 1.2.0 [2022-May-18] + +* Enhancement - AWSEKSResourceDetector - Validate ClusterName/ContainerID + independently before adding it to the resource + ([#205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/205)) +* Fix - AWSEKSResourceDetector fails to detect resources due to exception + "The SSL connection could not be established" + ([#208](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/208)) + ## 1.1.0 [2021-Sept-20] * Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) From e70884174decf600cc9c0cdd376341d8c8ea9e3d Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Fri, 20 May 2022 15:49:25 -0500 Subject: [PATCH 0127/1499] Don't mark Elasticsearch 404's as error (#368) --- src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs | 5 +++++ .../CHANGELOG.md | 1 + 2 files changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs index 25771f11de..c057783c8a 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs @@ -34,6 +34,11 @@ public static Status ResolveSpanStatusForHttpStatusCode(int httpStatusCode) return Status.Unset; } + if (httpStatusCode == 404) + { + return Status.Unset; + } + return Status.Error; } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 75ed5233f9..3b86172fdc 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -4,6 +4,7 @@ * Updated OTel SDK package version to 1.2.0 * Update minimum full framework support to net462 +* Requests that get an HTTP status code of 404 are not marked as an error span status ## 1.0.0-beta.3 From a006cd6abfeca5a7ba68d3327992ebc71139166b Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Mon, 23 May 2022 19:08:23 +0200 Subject: [PATCH 0128/1499] Instana Exporter - Initial support (#362) --- .../ISSUE_TEMPLATE/comp_exporter_instana.md | 41 +++ .github/component_owners.yml | 4 + .../workflows/package-Exporter.Instana.yml | 49 +++ opentelemetry-dotnet-contrib.sln | 15 + .../IInstanaExporterHelper.cs | 28 ++ .../Implementation/ISpanSender.cs | 23 ++ .../Implementation/InstanaSpan.cs | 98 ++++++ .../Implementation/InstanaSpanFactory.cs | 39 +++ .../Implementation/InstanaSpanSerializer.cs | 281 ++++++++++++++++++ .../InstanaSpanTransformInfo.cs | 29 ++ .../Processors/ActivityProcessorBase.cs | 53 ++++ .../Processors/DefaultActivityProcessor.cs | 131 ++++++++ .../Processors/ErrorActivityProcessor.cs | 49 +++ .../Processors/EventsActivityProcessor.cs | 57 ++++ .../Processors/IActivityProcessor.cs | 27 ++ .../Processors/TagsActivityProcessor.cs | 59 ++++ .../Implementation/SpanSender.cs | 56 ++++ .../Implementation/Transport.cs | 161 ++++++++++ .../InstanaExporter.cs | 199 +++++++++++++ .../InstanaExporterConstants.cs | 48 +++ .../InstanaExporterHelper.cs | 35 +++ .../OpenTelemetry.Exporter.Instana.csproj | 30 ++ .../Properties/AssemblyInfo.cs | 34 +++ src/OpenTelemetry.Exporter.Instana/README.md | 42 +++ .../TracerProviderBuilderExtensions.cs | 43 +++ .../InstanaExporterTests.cs | 147 +++++++++ .../InstanaSpanFactoryTests.cs | 39 +++ .../InstanaSpanSerializerTests.cs | 105 +++++++ .../InstanaSpanTest.cs | 207 +++++++++++++ ...penTelemetry.Exporter.Instana.Tests.csproj | 21 ++ .../DefaultActivityProcessorTests.cs | 52 ++++ .../Processors/ErrorActivityProcessorTests.cs | 64 ++++ .../EventsActivityProcessorTests.cs | 64 ++++ .../Processors/TagsActivityProcessorTests.cs | 63 ++++ 34 files changed, 2393 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_instana.md create mode 100644 .github/workflows/package-Exporter.Instana.yml create mode 100644 src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj create mode 100644 src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Exporter.Instana/README.md create mode 100644 src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_instana.md b/.github/ISSUE_TEMPLATE/comp_exporter_instana.md new file mode 100644 index 0000000000..c03d1270c4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_exporter_instana.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Exporter.Instana +about: Issue with OpenTelemetry.Exporter.Instana +labels: comp:exporter.instana +--- + +# Issue with OpenTelemetry.Exporter.Instana + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 6e96b7e85e..144badb8c4 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -12,6 +12,8 @@ components: - reyang - utpilla - Yun-Ting + src/OpenTelemetry.Exporter.Instana/: + - zivaninstana src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev src/OpenTelemetry.Extensions/: @@ -64,6 +66,8 @@ components: - reyang - utpilla - Yun-Ting + test/OpenTelemetry.Exporter.Instana.Tests/: + - zivaninstana test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml new file mode 100644 index 0000000000..1fdac4e7ed --- /dev/null +++ b/.github/workflows/package-Exporter.Instana.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Exporter.Instana + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Exporter.Instana-*' # trigger when we create a tag with prefix "Exporter.Instana-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Exporter.Instana + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index aaf68749fd..e63236fb14 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -31,6 +31,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml + .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml @@ -185,6 +186,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Abstractions", "src\OpenTelemetry.Extensions.PersistentStorage.Abstractions\OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj", "{17E3936A-265A-4C9F-9DD5-4568F80E6D91}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana", "src\OpenTelemetry.Exporter.Instana\OpenTelemetry.Exporter.Instana.csproj", "{BD3C6377-6F8D-47D6-9710-1681ED4E6772}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana.Tests", "test\OpenTelemetry.Exporter.Instana.Tests\OpenTelemetry.Exporter.Instana.Tests.csproj", "{77E7DDB9-32CF-450E-B596-E893149D07DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -379,6 +384,14 @@ Global {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.Build.0 = Debug|Any CPU {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.ActiveCfg = Release|Any CPU {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.Build.0 = Release|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.Build.0 = Release|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -437,6 +450,8 @@ Global {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {17E3936A-265A-4C9F-9DD5-4568F80E6D91} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {BD3C6377-6F8D-47D6-9710-1681ED4E6772} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {77E7DDB9-32CF-450E-B596-E893149D07DD} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs new file mode 100644 index 0000000000..0ce045c869 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs @@ -0,0 +1,28 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Instana +{ + internal interface IInstanaExporterHelper + { + bool IsWindows(); + + Resource GetParentProviderResource(BaseExporter otelExporter); + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs new file mode 100644 index 0000000000..83d3ae906e --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal interface ISpanSender + { + void Enqueue(InstanaSpan instanaSpan); + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs new file mode 100644 index 0000000000..783c18e75e --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs @@ -0,0 +1,98 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal enum SpanKind + { +#pragma warning disable SA1602 // Enumeration items should be documented + ENTRY, +#pragma warning restore SA1602 // Enumeration items should be documented +#pragma warning disable SA1602 // Enumeration items should be documented + EXIT, +#pragma warning restore SA1602 // Enumeration items should be documented +#pragma warning disable SA1602 // Enumeration items should be documented + INTERMEDIATE, +#pragma warning restore SA1602 // Enumeration items should be documented +#pragma warning disable SA1602 // Enumeration items should be documented + NOT_SET, +#pragma warning restore SA1602 // Enumeration items should be documented + } + + internal class InstanaSpan + { + public InstanaSpanTransformInfo TransformInfo { get; set; } + + public string N { get; internal set; } + + public string T { get; internal set; } + + public string Lt { get; internal set; } + + public From F { get; internal set; } + + public string P { get; internal set; } + + public string S { get; internal set; } + + public SpanKind K { get; internal set; } + + public Data Data { get; internal set; } + + public long Ts { get; internal set; } + + public long D { get; internal set; } + + public bool Tp { get; internal set; } + + public int Ec { get; internal set; } + } + +#pragma warning disable SA1402 // File may only contain a single type + internal class From +#pragma warning restore SA1402 // File may only contain a single type + { + public string E { get; internal set; } + + public string H { get; internal set; } + } + +#pragma warning disable SA1402 // File may only contain a single type + internal class Data +#pragma warning restore SA1402 // File may only contain a single type + { +#pragma warning disable SA1300 // Element should begin with upper-case letter + public Dictionary data { get; internal set; } + +#pragma warning restore SA1300 // Element should begin with upper-case letter + public Dictionary Tags { get; internal set; } + + public List Events { get; internal set; } + } + +#pragma warning disable SA1402 // File may only contain a single type + internal class SpanEvent +#pragma warning restore SA1402 // File may only contain a single type + { + public string Name { get; internal set; } + + public long Ts { get; internal set; } + + public Dictionary Tags { get; internal set; } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs new file mode 100644 index 0000000000..35a4bee074 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs @@ -0,0 +1,39 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Collections.Generic; + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal class InstanaSpanFactory + { + internal static InstanaSpan CreateSpan() + { + InstanaSpan instanaSpan = new InstanaSpan + { + Data = new Data() + { + data = new Dictionary(), + Tags = new Dictionary(), + Events = new List(8), + }, + + TransformInfo = new InstanaSpanTransformInfo(), + }; + + return instanaSpan; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs new file mode 100644 index 0000000000..36e515b167 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -0,0 +1,281 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal class InstanaSpanSerializer + { +#pragma warning disable SA1310 // Field names should not contain underscore + private const string COMMA = ","; + private const string OPEN_BRACE = "{"; + private const string CLOSE_BRACE = "}"; + private const string QUOTE = "\""; + private const string COLON = ":"; + private const string QUOTE_COLON = QUOTE + COLON; + private const string QUOTE_COLON_QUOTE = QUOTE + COLON + QUOTE; + private const string QUOTE_COMMA_QUOTE = QUOTE + COMMA + QUOTE; +#pragma warning restore SA1310 // Field names should not contain underscore + private static readonly long UnixZeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks; + + internal IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan) + { + return instanaSpan.Data.Tags.GetEnumerator(); + } + + internal IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) + { + return instanaSpan.Data.Events.GetEnumerator(); + } + + internal async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await writer.WriteAsync(OPEN_BRACE); + await this.AppendProperty(instanaSpan.T, "t", writer); + await writer.WriteAsync(COMMA); + await this.AppendProperty(instanaSpan.S, "s", writer); + await writer.WriteAsync(COMMA); + + if (!string.IsNullOrEmpty(instanaSpan.P)) + { + await this.AppendProperty(instanaSpan.P, "p", writer); + await writer.WriteAsync(COMMA); + } + + if (!string.IsNullOrEmpty(instanaSpan.Lt)) + { + await this.AppendProperty(instanaSpan.Lt, "lt", writer); + await writer.WriteAsync(COMMA); + } + + if (instanaSpan.Tp) + { + await this.AppendProperty(true.ToString().ToLower(), "tp", writer); + await writer.WriteAsync(COMMA); + } + + if (instanaSpan.K != SpanKind.NOT_SET) + { + await this.AppendProperty((((int)instanaSpan.K) + 1).ToString(), "k", writer); + await writer.WriteAsync(COMMA); + } + + await this.AppendProperty(instanaSpan.N, "n", writer); + await writer.WriteAsync(COMMA); + await this.AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer); + await writer.WriteAsync(COMMA); + await this.AppendPropertyAsync(instanaSpan.D, "d", writer); + await writer.WriteAsync(COMMA); + await this.AppendObjectAsync(this.SerializeDataAsync, "data", instanaSpan, writer); + await writer.WriteAsync(COMMA); + await this.AppendObjectAsync(SerializeFromAsync, "f", instanaSpan, writer); + await writer.WriteAsync(COMMA); + await this.AppendPropertyAsync(instanaSpan.Ec, "ec", writer); + await writer.WriteAsync(CLOSE_BRACE); + } + + private static async Task SerializeFromAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await writer.WriteAsync("{\"e\":\""); + await writer.WriteAsync(instanaSpan.F.E); + await writer.WriteAsync("\"}"); + } + + private static long DateToUnixMillis(long timeStamp) + { + return (timeStamp - UnixZeroTime) / 10000; + } + + private static async Task SerializeTagsAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer); + } + + private static async Task SerializeTagsLogicAsync(Dictionary tags, StreamWriter writer) + { + await writer.WriteAsync(OPEN_BRACE); + using (var enumerator = tags.GetEnumerator()) + { + byte i = 0; + try + { + while (enumerator.MoveNext()) + { + if (i > 0) + { + await writer.WriteAsync(COMMA); + } + else + { + i = 1; + } + + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(enumerator.Current.Key); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(enumerator.Current.Value); + await writer.WriteAsync(QUOTE); + } + } + catch (InvalidOperationException) + { + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation + } + } + + await writer.WriteAsync(CLOSE_BRACE); + } + + private async Task AppendProperty(string value, string name, StreamWriter json) + { + await json.WriteAsync(QUOTE); + await json.WriteAsync(name); + await json.WriteAsync(QUOTE_COLON_QUOTE); + await json.WriteAsync(value); + await json.WriteAsync(QUOTE); + } + + private async Task AppendPropertyAsync(long value, string name, StreamWriter json) + { + await json.WriteAsync(QUOTE); + await json.WriteAsync(name); + await json.WriteAsync(QUOTE_COLON); + await json.WriteAsync(value.ToString()); + } + + private async Task AppendObjectAsync(Func valueFunction, string name, InstanaSpan instanaSpan, StreamWriter json) + { + await json.WriteAsync(QUOTE); + await json.WriteAsync(name); + await json.WriteAsync(QUOTE_COLON); + await valueFunction(instanaSpan, json); + } + + private async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await writer.WriteAsync(OPEN_BRACE); + using (var enumerator = instanaSpan.Data.data.GetEnumerator()) + { + byte i = 0; + try + { + while (enumerator.MoveNext()) + { + if (i > 0) + { + await writer.WriteAsync(COMMA); + } + else + { + i = 1; + } + + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(enumerator.Current.Key); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(enumerator.Current.Value.ToString()); + await writer.WriteAsync(QUOTE); + } + } + catch (InvalidOperationException) + { + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation + } + } + + if (instanaSpan.Data.Tags?.Count > 0) + { + await writer.WriteAsync(COMMA); + + // serialize tags + await this.AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer); + } + + if (instanaSpan.Data.Events?.Count > 0) + { + await writer.WriteAsync(COMMA); + + // serialize tags + await this.AppendObjectAsync(this.SerializeEventsAsync, InstanaExporterConstants.EVENTS_FIELD, instanaSpan, writer); + } + + await writer.WriteAsync(CLOSE_BRACE); + } + + private async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + using (var enumerator = instanaSpan.Data.Events.GetEnumerator()) + { + byte i = 0; + try + { + await writer.WriteAsync("["); + while (enumerator.MoveNext()) + { + if (i > 0) + { + await writer.WriteAsync(COMMA); + } + else + { + i = 1; + } + + await writer.WriteAsync(OPEN_BRACE); + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(enumerator.Current.Name); + await writer.WriteAsync(QUOTE_COMMA_QUOTE); + await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString()); + await writer.WriteAsync(QUOTE); + + if (enumerator.Current.Tags?.Count > 0) + { + await writer.WriteAsync(COMMA); + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD); + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(COLON); + await SerializeTagsLogicAsync(enumerator.Current.Tags, writer); + } + + await writer.WriteAsync(CLOSE_BRACE); + } + + await writer.WriteAsync("]"); + } + catch (InvalidOperationException) + { + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation + } + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs new file mode 100644 index 0000000000..659fc89ead --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal class InstanaSpanTransformInfo + { + public string StatusCode { get; internal set; } + + public string StatusDesc { get; internal set; } + + public bool HasExceptionEvent { get; internal set; } + + public bool IsEntrySpan { get; internal set; } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs new file mode 100644 index 0000000000..1e5ed9a84d --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -0,0 +1,53 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +{ + internal abstract class ActivityProcessorBase : IActivityProcessor + { + public IActivityProcessor NextProcessor { get; set; } + + public virtual async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + if (this.NextProcessor != null) + { + await this.NextProcessor.ProcessAsync(activity, instanaSpan); + } + } + + protected virtual void PreProcess(Activity activity, InstanaSpan instanaSpan) + { + if (instanaSpan.TransformInfo == null) + { + instanaSpan.TransformInfo = new InstanaSpanTransformInfo(); + } + + if (instanaSpan.Data == null) + { + instanaSpan.Data = new Data() + { + data = new Dictionary(), + Events = new List(8), + Tags = new Dictionary(), + }; + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs new file mode 100644 index 0000000000..7644b16912 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -0,0 +1,131 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +{ + internal class DefaultActivityProcessor : ActivityProcessorBase, IActivityProcessor + { + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + this.PreProcess(activity, instanaSpan); + + instanaSpan.N = InstanaExporterConstants.OTEL_SPAN_TYPE; + + string traceId = activity.TraceId.ToHexString(); + if (traceId.Length == 32) + { + instanaSpan.T = traceId.Substring(16); + instanaSpan.Lt = traceId; + } + else + { + instanaSpan.T = traceId; + } + + bool hasParent = false; + string parentSpanId = activity.ParentSpanId.ToHexString(); + if (!string.IsNullOrEmpty(parentSpanId) && GetLongFromHex(parentSpanId) != 0) + { + hasParent = true; + instanaSpan.P = parentSpanId; + } + + instanaSpan.S = activity.SpanId.ToHexString(); + instanaSpan.K = GetSpanKind(activity.Kind); + + instanaSpan.Ts = activity.StartTimeUtc.Ticks; + instanaSpan.D = activity.Duration.Ticks; + + SetKind(activity, instanaSpan); + + if (hasParent && instanaSpan.TransformInfo.IsEntrySpan) + { + // If an OTel entry span continues an ongoing trace (which is equivalent to the original span having a parent), it + // always uses the IDs from the traceparent header, thus we mark the span with span.tp accordingly. + instanaSpan.Tp = true; + } + + await base.ProcessAsync(activity, instanaSpan); + } + + private static SpanKind GetSpanKind(ActivityKind activityKind) + { + switch (activityKind) + { + case ActivityKind.Consumer: + case ActivityKind.Server: + return SpanKind.ENTRY; + case ActivityKind.Client: + case ActivityKind.Producer: + return SpanKind.EXIT; + case ActivityKind.Internal: + return SpanKind.INTERMEDIATE; + default: + return SpanKind.NOT_SET; + } + } + + private static long GetLongFromHex(string hexValue) + { + if (!string.IsNullOrEmpty(hexValue)) + { + try + { + string[] ids = hexValue.Split(','); + return Convert.ToInt64(ids[ids.Length - 1].Trim(), 16); + } + catch (Exception) + { + } + } + + return 0; + } + + private static void SetKind(Activity activity, InstanaSpan instanaSpan) + { + bool isEntrySpan = false; + switch (activity.Kind) + { + case ActivityKind.Server: + isEntrySpan = true; + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.SERVER_KIND; + break; + case ActivityKind.Client: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CLIENT_KIND; + break; + case ActivityKind.Producer: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.PRODUCER_KIND; + break; + case ActivityKind.Consumer: + isEntrySpan = true; + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CONSUMER_KIND; + break; + case ActivityKind.Internal: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.INTERNAL_KIND; + break; + default: + break; + } + + instanaSpan.TransformInfo.IsEntrySpan = isEntrySpan; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs new file mode 100644 index 0000000000..049fb6a395 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +{ + internal class ErrorActivityProcessor : ActivityProcessorBase, IActivityProcessor + { + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + this.PreProcess(activity, instanaSpan); + + if (activity.Status == ActivityStatusCode.Error) + { + instanaSpan.Ec = 1; + instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD] = activity.Status.ToString(); + if (!string.IsNullOrEmpty(activity.StatusDescription)) + { + instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD] = activity.StatusDescription; + } + } + else if (instanaSpan.TransformInfo.HasExceptionEvent) + { + instanaSpan.Ec = 1; + } + else + { + instanaSpan.Ec = 0; + } + + await base.ProcessAsync(activity, instanaSpan); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs new file mode 100644 index 0000000000..ec6016e3cc --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -0,0 +1,57 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +{ + internal class EventsActivityProcessor : ActivityProcessorBase, IActivityProcessor + { + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + this.PreProcess(activity, instanaSpan); + + foreach (var activityEvent in activity.Events) + { + if (activityEvent.Name == InstanaExporterConstants.EXCEPTION_FIELD) + { + instanaSpan.TransformInfo.HasExceptionEvent = true; + } + + var spanEvent = new SpanEvent + { + Name = activityEvent.Name, + Ts = activityEvent.Timestamp.Ticks, + Tags = new Dictionary(), + }; + + foreach (var eventTag in activityEvent.Tags) + { + if (eventTag.Value != null) + { + spanEvent.Tags[eventTag.Key] = eventTag.Value.ToString(); + } + } + + instanaSpan.Data.Events.Add(spanEvent); + } + + await base.ProcessAsync(activity, instanaSpan); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs new file mode 100644 index 0000000000..89b74a954c --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +{ + internal interface IActivityProcessor + { + IActivityProcessor NextProcessor { get; set; } + + Task ProcessAsync(System.Diagnostics.Activity activity, InstanaSpan instanaSpan); + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs new file mode 100644 index 0000000000..b35b7d3377 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -0,0 +1,59 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +{ + internal class TagsActivityProcessor : ActivityProcessorBase, IActivityProcessor + { + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + this.PreProcess(activity, instanaSpan); + + string statusCode = string.Empty; + string statusDesc = string.Empty; + Dictionary tags = new Dictionary(); + foreach (var tag in activity.Tags) + { + if (tag.Key == "otel.status_code") + { + statusCode = tag.Value as string; + continue; + } + + if (tag.Key == "otel.status_description") + { + statusDesc = tag.Value as string; + continue; + } + + if (tag.Value != null) + { + tags[tag.Key] = tag.Value.ToString(); + } + } + + instanaSpan.Data.Tags = tags; + instanaSpan.TransformInfo.StatusCode = statusCode; + instanaSpan.TransformInfo.StatusDesc = statusDesc; + + await base.ProcessAsync(activity, instanaSpan); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs new file mode 100644 index 0000000000..520a4f3952 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -0,0 +1,56 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Collections.Concurrent; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal class SpanSender : ISpanSender + { + private readonly Task queueSenderTask; + private readonly Transport transport = new Transport(); + private readonly ConcurrentQueue spansQueue = new ConcurrentQueue(); + + public SpanSender() + { + // create a task that will send a batch of spans every second at least + this.queueSenderTask = new Task(this.TaskSpanSender, TaskCreationOptions.LongRunning); + this.queueSenderTask.Start(); + } + + public void Enqueue(InstanaSpan instanaSpan) + { + this.spansQueue.Enqueue(instanaSpan); + } + + private async void TaskSpanSender() + { + // this will be an infinite loop + while (true) + { + // check if we can send spans + if (this.spansQueue.TryPeek(out InstanaSpan dummySpan)) + { + // actually send spans + await this.transport.SendSpansAsync(this.spansQueue); + } + + // rest for a while + await Task.Delay(1000); + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs new file mode 100644 index 0000000000..7ccc3992a4 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -0,0 +1,161 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; + +namespace OpenTelemetry.Exporter.Instana.Implementation +{ + internal class Transport + { + private static readonly InstanaSpanSerializer InstanaSpanSerializer = new InstanaSpanSerializer(); + private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); + + private static bool wasConfigured = false; + private static int backendTimeout = 0; + private static string configuredEndpoint = string.Empty; + private static string configuredAgentKey = string.Empty; + private static string bundleUrl = string.Empty; + private static InstanaHttpClient client = null; + + private readonly byte[] tracesBuffer = new byte[4096000]; + + static Transport() + { + Configure(); + } + + internal async Task SendSpansAsync(ConcurrentQueue spanQueue) + { + using (MemoryStream sendBuffer = new MemoryStream(this.tracesBuffer)) + { + using (StreamWriter writer = new StreamWriter(sendBuffer)) + { + await writer.WriteAsync("{\"spans\":["); + bool first = true; + while (spanQueue.TryDequeue(out InstanaSpan span) && sendBuffer.Position < 4070000) + { + if (!first) + { + await writer.WriteAsync(","); + } + + first = false; + await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer); + } + + await writer.WriteAsync("]}"); + + await writer.FlushAsync(); + long length = sendBuffer.Position; + sendBuffer.Position = 0; + + HttpContent content = new StreamContent(sendBuffer, (int)length); + content.Headers.ContentType = MEDIAHEADER; + content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); + + using (var httpMsg = new HttpRequestMessage() + { + Method = HttpMethod.Post, + RequestUri = new Uri(bundleUrl), + }) + { + httpMsg.Content = content; + var res = client.SendAsync(httpMsg).GetAwaiter().GetResult(); + } + } + } + } + + private static void Configure() + { + if (wasConfigured) + { + return; + } + + if (string.IsNullOrEmpty(configuredEndpoint)) + { + configuredEndpoint = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_URL); + } + + bundleUrl = configuredEndpoint + "/bundle"; + + if (string.IsNullOrEmpty(configuredAgentKey)) + { + configuredAgentKey = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_AGENT_KEY); + } + + if (backendTimeout == 0) + { + if (!int.TryParse(Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_TIMEOUT), out backendTimeout)) + { + backendTimeout = InstanaExporterConstants.BACKEND_DEFAULT_TIMEOUT; + } + } + + ConfigureBackendClient(); + wasConfigured = true; + } + + private static void ConfigureBackendClient() + { + if (client != null) + { + return; + } + + var configuredHandler = new HttpClientHandler(); + string proxy = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_PROXY); + if (Uri.TryCreate(proxy, UriKind.Absolute, out Uri proxyAddress)) + { + configuredHandler.Proxy = new WebProxy(proxyAddress, true); + configuredHandler.UseProxy = true; +#pragma warning disable SA1130 // Use lambda syntax + configuredHandler.ServerCertificateCustomValidationCallback = delegate { return true; }; +#pragma warning restore SA1130 // Use lambda syntax + } + + client = new InstanaHttpClient(backendTimeout, configuredHandler); + + client.DefaultRequestHeaders.Add("X-INSTANA-KEY", configuredAgentKey); + } + } + +#pragma warning disable SA1402 // File may only contain a single type + internal class InstanaHttpClient : HttpClient +#pragma warning restore SA1402 // File may only contain a single type + { + public InstanaHttpClient(int timeout) + : base() + { + this.Timeout = TimeSpan.FromMilliseconds(timeout); + this.DefaultRequestHeaders.Add("X-INSTANA-NOTRACE", "1"); + } + + public InstanaHttpClient(int timeout, HttpClientHandler handler) + : base(handler) + { + this.Timeout = TimeSpan.FromMilliseconds(timeout); + this.DefaultRequestHeaders.Add("X-INSTANA-NOTRACE", "1"); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs new file mode 100644 index 0000000000..06fbf85934 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -0,0 +1,199 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Instana +{ + internal class InstanaExporter : BaseExporter + { + private readonly IActivityProcessor activityProcessor; + private string name; + private ISpanSender spanSender = new SpanSender(); + private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); + private bool shutdownCalled = false; + + public InstanaExporter(string name = "InstanaExporter", IActivityProcessor activityProcessor = null) + { + this.name = name; + + if (activityProcessor != null) + { + this.activityProcessor = activityProcessor; + } + else + { + this.activityProcessor = new DefaultActivityProcessor + { + NextProcessor = new TagsActivityProcessor + { + NextProcessor = new EventsActivityProcessor + { + NextProcessor = new ErrorActivityProcessor(), + }, + }, + }; + } + } + + internal ISpanSender SpanSender + { + get { return this.spanSender; } + set { this.spanSender = value; } + } + + internal IInstanaExporterHelper InstanaExporterHelper + { + get { return this.instanaExporterHelper; } + set { this.instanaExporterHelper = value; } + } + + public override ExportResult Export(in Batch batch) + { + if (this.shutdownCalled) + { + return ExportResult.Failure; + } + + From from = null; + if (this.instanaExporterHelper.IsWindows()) + { + from = new From() { E = Process.GetCurrentProcess().Id.ToString() }; + } + + string serviceName = this.ExtractServiceName(ref from); + + foreach (var activity in batch) + { + if (activity == null) + { + continue; + } + + InstanaSpan span = this.ParseActivityAsync(activity, serviceName, from).Result; + this.spanSender.Enqueue(span); + } + + return ExportResult.Success; + } + + protected override bool OnShutdown(int timeoutMilliseconds) + { + if (!this.shutdownCalled) + { + this.shutdownCalled = true; + return true; + } + else + { + return false; + } + } + + protected override bool OnForceFlush(int timeoutMilliseconds) + { + return base.OnForceFlush(timeoutMilliseconds); + } + + private string ExtractServiceName(ref From from) + { + string serviceName = null; + string serviceId = null; + string processId = null; + string hostId = null; + var resource = this.instanaExporterHelper.GetParentProviderResource(this); + if (resource != Resource.Empty && resource.Attributes?.Count() > 0) + { + foreach (var resourceAttribute in resource.Attributes) + { + if (resourceAttribute.Key.Equals("service.name", StringComparison.OrdinalIgnoreCase) + && resourceAttribute.Value is string servName + && !string.IsNullOrEmpty(servName)) + { + serviceName = servName; + } + + if (from == null) + { + if (resourceAttribute.Key.Equals("service.instance.id", StringComparison.OrdinalIgnoreCase)) + { + serviceId = resourceAttribute.Value.ToString(); + } + else if (resourceAttribute.Key.Equals("process.pid", StringComparison.OrdinalIgnoreCase)) + { + processId = resourceAttribute.Value.ToString(); + } + else if (resourceAttribute.Key.Equals("host.id", StringComparison.OrdinalIgnoreCase)) + { + hostId = resourceAttribute.Value.ToString(); + } + } + } + } + + if (from == null) + { + from = new From(); + if (!string.IsNullOrEmpty(processId)) + { + from.E = processId; + } + else if (!string.IsNullOrEmpty(serviceId)) + { + from.E = serviceId; + } + + if (!string.IsNullOrEmpty(hostId)) + { + from.H = hostId; + } + } + + return serviceName; + } + + private async Task ParseActivityAsync(Activity activity, string serviceName = null, From from = null) + { + InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); + + await this.activityProcessor.ProcessAsync(activity, instanaSpan); + + if (!string.IsNullOrEmpty(serviceName)) + { + instanaSpan.Data.data[InstanaExporterConstants.SERVICE_FIELD] = serviceName; + } + + instanaSpan.Data.data[InstanaExporterConstants.OPERATION_FIELD] = activity.DisplayName; + if (!string.IsNullOrEmpty(activity.TraceStateString)) + { + instanaSpan.Data.data[InstanaExporterConstants.TRACE_STATE_FIELD] = activity.TraceStateString; + } + + if (from != null) + { + instanaSpan.F = from; + } + + return instanaSpan; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs new file mode 100644 index 0000000000..cecdf10035 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs @@ -0,0 +1,48 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Instana +{ + internal class InstanaExporterConstants + { +#pragma warning disable SA1310 // Field names should not contain underscore + internal const string OTEL_SPAN_TYPE = "otel"; + internal const string KIND_FIELD = "kind"; + internal const string SERVER_KIND = "server"; + internal const string CLIENT_KIND = "client"; + internal const string PRODUCER_KIND = "producer"; + internal const string CONSUMER_KIND = "consumer"; + internal const string INTERNAL_KIND = "internal"; + internal const string SERVICE_FIELD = "service"; + internal const string OPERATION_FIELD = "operation"; + internal const string TRACE_STATE_FIELD = "trace_state"; + internal const string ERROR_FIELD = "error"; + internal const string ERROR_DETAIL_FIELD = "error_detail"; + internal const string EXCEPTION_FIELD = "exception"; + internal const string TAGS_FIELD = "tags"; + internal const string EVENTS_FIELD = "events"; + internal const string EVENT_NAME_FIELD = "name"; + internal const string EVENT_TIMESTAMP_FIELD = "ts"; + + internal const string ENVVAR_INSTANA_ENDPOINT_URL = "INSTANA_ENDPOINT_URL"; + internal const string ENVVAR_INSTANA_AGENT_KEY = "INSTANA_AGENT_KEY"; + internal const string ENVVAR_INSTANA_TIMEOUT = "INSTANA_TIMEOUT"; + internal const int BACKEND_DEFAULT_TIMEOUT = 20000; + internal const string ENVVAR_INSTANA_EXTRA_HTTP_HEADERS = "INSTANA_EXTRA_HTTP_HEADERS"; + internal const string ENVVAR_INSTANA_ENDPOINT_PROXY = "INSTANA_ENDPOINT_PROXY"; +#pragma warning restore SA1310 // Field names should not contain underscore + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs new file mode 100644 index 0000000000..cd966785fa --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Instana +{ + internal class InstanaExporterHelper : IInstanaExporterHelper + { + public Resource GetParentProviderResource(BaseExporter otelExporter) + { + return otelExporter.ParentProvider.GetResource(); + } + + public bool IsWindows() + { + return Environment.OSVersion.Platform == PlatformID.Win32NT; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj new file mode 100644 index 0000000000..2e0d58a608 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -0,0 +1,30 @@ + + + + netstandard2.0;net461 + Instana Tracing APM + Instana .NET Exporter for OpenTelemetry + Exporter.Instana- + + + + 4 + + + + 4 + + + + 4 + + + + 4 + + + + + + + diff --git a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..e9509a2306 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Instana.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] + +#if SIGNED +internal static class AssemblyInfo +{ + public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898"; + public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; +} +#else +internal static class AssemblyInfo +{ + public const string PublicKey = ""; + public const string MoqPublicKey = ""; +} +#endif diff --git a/src/OpenTelemetry.Exporter.Instana/README.md b/src/OpenTelemetry.Exporter.Instana/README.md new file mode 100644 index 0000000000..379f6df1b8 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/README.md @@ -0,0 +1,42 @@ +# Instana Exporter for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Instana.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) + +The Instana Exporter exports telemetry to Instana backand. + +## Installation + +```shell +dotnet add package OpenTelemetry.Exporter.Instana +``` + +## Configuration + +The trace exporter is supported. + +To report to Instana backend correct agent key and backend URL must be configured. +These values can be configured by environment variables INSTANA_AGENT_KEY +and INSTANA_ENDPOINT_URL. +Optionally backend communication timeout can be configured by environment +variable INSTANA_TIMEOUT. + +### Enable Traces + +This snippet shows how to configure the Instana Exporter for Traces + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource("DemoSource") + .AddInstanaExporter() + .Build(); +``` + +The above code must be in application startup. In case of ASP.NET Core +applications, this should be in `ConfigureServices` of `Startup` class. +For ASP.NET applications, this should be in `Global.aspx.cs`. + +## Troubleshooting + +Before digging into a problem, check if you hit a known issue by looking at the [GitHub +issues](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues). diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..049a965c42 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Exporter.Instana +{ + /// + /// Todo. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Instana test provider builder extension. + /// + /// Test provider builder. + /// todo. + /// Test provider builder is null. + public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilder options) + { + if (options == null) + { + throw new ArgumentNullException(nameof(options)); + } + + return options.AddProcessor(new BatchActivityExportProcessor(new InstanaExporter())); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs new file mode 100644 index 0000000000..8763ad1155 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -0,0 +1,147 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using Moq; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests +{ + public class InstanaExporterTests + { + private readonly Mock instanaExporterHelperMock = new Mock(MockBehavior.Strict); + private readonly Mock activityProcessorMock = new Mock(MockBehavior.Strict); + private readonly Mock spanSenderMock = new Mock(MockBehavior.Strict); + private InstanaSpan instanaSpan = null; + private InstanaExporter instanaExporter = null; + + [Fact] + public void Export() + { + this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) + .Returns(() => Task.CompletedTask); + + this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); + this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) + .Returns(new Resource(new Dictionary() + { + { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, + { "process.pid", "processPid" }, { "host.id", "hostId" }, + })); + + this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); + + this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); + this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; + this.instanaExporter.SpanSender = this.spanSenderMock.Object; + + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + activity.TraceStateString = "TraceStateString"; + + Activity[] activities = new Activity[1] { activity }; + Batch batch = new Batch(activities, activities.Length); + var result = this.instanaExporter.Export(in batch); + + this.VerifyAllMocks(); + + Assert.Equal(ExportResult.Success, result); + Assert.NotNull(this.instanaSpan); + Assert.Equal("processPid", this.instanaSpan.F.E); + Assert.Equal("hostId", this.instanaSpan.F.H); + Assert.Equal("serviceName", this.instanaSpan.Data.data["service"]); + Assert.Equal("testOperationName", this.instanaSpan.Data.data["operation"]); + Assert.Equal("TraceStateString", this.instanaSpan.Data.data["trace_state"]); + } + + [Fact] + public void Export_ProcessPidDoesNotExistButServiceIdExists() + { + this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) + .Returns(() => Task.CompletedTask); + + this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); + this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) + .Returns(new Resource(new Dictionary() + { + { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, + { "host.id", "hostId" }, + })); + + this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); + + this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); + this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; + this.instanaExporter.SpanSender = this.spanSenderMock.Object; + + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + + Activity[] activities = new Activity[1] { activity }; + Batch batch = new Batch(activities, activities.Length); + var result = this.instanaExporter.Export(in batch); + + this.VerifyAllMocks(); + + Assert.Equal(ExportResult.Success, result); + Assert.NotNull(this.instanaSpan); + Assert.Equal("serviceInstanceId", this.instanaSpan.F.E); + Assert.Equal("hostId", this.instanaSpan.F.H); + Assert.Equal("serviceName", this.instanaSpan.Data.data["service"]); + Assert.Equal("testOperationName", this.instanaSpan.Data.data["operation"]); + } + + [Fact] + public void Export_ExporterIsShotDown() + { + this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); + this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; + this.instanaExporter.SpanSender = this.spanSenderMock.Object; + + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + + this.instanaExporter.Shutdown(); + + Activity[] activities = new Activity[1] { activity }; + Batch batch = new Batch(activities, activities.Length); + var result = this.instanaExporter.Export(in batch); + + this.VerifyAllMocks(); + + Assert.Equal(ExportResult.Failure, result); + Assert.Null(this.instanaSpan); + } + + private bool CloneSpan(InstanaSpan span) + { + this.instanaSpan = span; + return true; + } + + private void VerifyAllMocks() + { + this.instanaExporterHelperMock.VerifyAll(); + this.activityProcessorMock.VerifyAll(); + this.spanSenderMock.VerifyAll(); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs new file mode 100644 index 0000000000..82330c1d0c --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs @@ -0,0 +1,39 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Exporter.Instana.Implementation; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests +{ + public class InstanaSpanFactoryTests + { + private InstanaSpanFactory instanaSpanFactory = new InstanaSpanFactory(); + + [Fact] + public void CreateSpan() + { + OpenTelemetry.Exporter.Instana.Implementation.InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); + + Assert.NotNull(instanaSpan); + Assert.NotNull(instanaSpan.TransformInfo); + Assert.NotNull(instanaSpan.Data); + Assert.Empty(instanaSpan.Data.data); + Assert.Empty(instanaSpan.Data.Tags); + Assert.Empty(instanaSpan.Data.Events); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs new file mode 100644 index 0000000000..42a85a70ee --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -0,0 +1,105 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using OpenTelemetry.Exporter.Instana.Implementation; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests +{ + public class InstanaSpanSerializerTests + { + private InstanaSpanSerializer instanaSpanSerializer = new InstanaSpanSerializer(); + + [Fact] + public async Task SerializeToStreamWriterAsync() + { + InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); + instanaSpan.F = new OpenTelemetry.Exporter.Instana.Implementation.From() { E = "12345", H = "localhost" }; + instanaSpan.N = "otel"; + instanaSpan.T = "hexNumberT1234"; + instanaSpan.S = "hexNumberS1234"; + instanaSpan.P = "hexNumberP1234"; + instanaSpan.Ec = 1; + instanaSpan.D = 123456; + instanaSpan.Lt = "hexNumberLT1234567890123"; + instanaSpan.Tp = true; + instanaSpan.Data.Tags = new Dictionary(); + instanaSpan.Data.Tags["tag1Key"] = "tag1Vale"; + instanaSpan.Data.Tags["tag2Key"] = "tag2Vale"; + instanaSpan.Data.data = new Dictionary(); + instanaSpan.Data.data["data1Key"] = "data1Vale"; + instanaSpan.Data.data["data2Key"] = "data2Vale"; + instanaSpan.Data.Events = new List() + { + new OpenTelemetry.Exporter.Instana.Implementation.SpanEvent() + { + Name = "testEvent", Ts = 111111, + Tags = new Dictionary() { { "eventTagKey", "eventTagValue" } }, + }, + new Implementation.SpanEvent() + { + Name = "testEvent2", Ts = 222222, + Tags = new Dictionary() { { "eventTag2Key", "eventTag2Value" } }, + }, + }; + + InstanaSpanTest span; + using (MemoryStream sendBuffer = new MemoryStream(new byte[4096000])) + { + using (StreamWriter writer = new StreamWriter(sendBuffer)) + { + await this.instanaSpanSerializer.SerializeToStreamWriterAsync(instanaSpan, writer); + await writer.FlushAsync(); + long length = sendBuffer.Position; + sendBuffer.Position = 0; + sendBuffer.SetLength(length); + + Newtonsoft.Json.JsonSerializer serializer = null; + serializer = new Newtonsoft.Json.JsonSerializer(); + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + serializer.NullValueHandling = NullValueHandling.Ignore; + + TextReader textReader = new StreamReader(sendBuffer); + JsonReader reader = new JsonTextReader(textReader); + span = serializer.Deserialize(reader); + } + } + + Assert.NotNull(span); + Assert.Equal(instanaSpan.S, span.S); + Assert.Equal(instanaSpan.T, span.T); + Assert.Equal(instanaSpan.P, span.P); + Assert.Equal(instanaSpan.N, span.N); + Assert.Equal(instanaSpan.F.E, span.F.E); + Assert.Equal(instanaSpan.Ec, span.Ec); + Assert.Equal(instanaSpan.D, span.D); + Assert.Equal(instanaSpan.Lt, span.Lt); + Assert.Equal(instanaSpan.Data.Tags["tag1Key"], span.Data.Tags["tag1Key"]); + Assert.Equal(instanaSpan.Data.Tags["tag2Key"], span.Data.Tags["tag2Key"]); + Assert.Equal(instanaSpan.Data.data["data1Key"], span.Data.data["data1Key"]); + Assert.Equal(instanaSpan.Data.data["data2Key"], span.Data.data["data2Key"]); + Assert.Equal(instanaSpan.Data.Events[0].Name, span.Data.Events[0].Name); + Assert.Equal(instanaSpan.Data.Events[0].Tags["eventTagKey"], span.Data.Events[0].Tags["eventTagKey"]); + Assert.Equal(instanaSpan.Data.Events[1].Name, span.Data.Events[1].Name); + Assert.Equal(instanaSpan.Data.Events[1].Tags["eventTag2Key"], span.Data.Events[1].Tags["eventTag2Key"]); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs new file mode 100644 index 0000000000..a2fb74e22c --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -0,0 +1,207 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace OpenTelemetry.Exporter.Instana.Tests +{ + internal enum SpanKind + { +#pragma warning disable SA1602 // Enumeration items should be documented + ENTRY, +#pragma warning restore SA1602 // Enumeration items should be documented +#pragma warning disable SA1602 // Enumeration items should be documented + EXIT, +#pragma warning restore SA1602 // Enumeration items should be documented +#pragma warning disable SA1602 // Enumeration items should be documented + INTERMEDIATE, +#pragma warning restore SA1602 // Enumeration items should be documented +#pragma warning disable SA1602 // Enumeration items should be documented + NOT_SET, +#pragma warning restore SA1602 // Enumeration items should be documented + } + +#pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable SA1649 // File name should match first type name + internal class InstanaSpanTransformInfo +#pragma warning restore SA1649 // File name should match first type name +#pragma warning restore SA1402 // File may only contain a single type + { + public string StatusCode { get; internal set; } + + public string StatusDesc { get; internal set; } + + public bool HasExceptionEvent { get; internal set; } + + public bool IsEntrySpan { get; internal set; } + } + + internal class InstanaSpanTest + { + public InstanaSpanTransformInfo TransformInfo { get; set; } + + [JsonProperty] + public string N { get; internal set; } + + [JsonProperty] + public string T { get; internal set; } + + [JsonProperty] + public string Lt { get; internal set; } + + [JsonProperty] + public From F { get; internal set; } + + [JsonProperty] + public string P { get; internal set; } + + [JsonProperty] + public string S { get; internal set; } + + [JsonProperty] + public SpanKind K { get; internal set; } + + [JsonProperty] + public Data Data { get; internal set; } + + [JsonProperty] + public long Ts { get; internal set; } + + [JsonProperty] + public long D { get; internal set; } + + [JsonProperty] + public bool Tp { get; internal set; } + + [JsonProperty] + public int Ec { get; internal set; } + } + +#pragma warning disable SA1402 // File may only contain a single type + internal class From +#pragma warning restore SA1402 // File may only contain a single type + { + [JsonProperty] + public string E { get; internal set; } + + [JsonProperty] + public string H { get; internal set; } + } + + [JsonConverter(typeof(DataConverter))] +#pragma warning disable SA1402 // File may only contain a single type + internal class Data +#pragma warning restore SA1402 // File may only contain a single type + { + [JsonProperty] +#pragma warning disable SA1300 // Element should begin with upper-case letter + public Dictionary data { get; internal set; } +#pragma warning restore SA1300 // Element should begin with upper-case letter + + [JsonProperty] + public Dictionary Tags { get; internal set; } + + [JsonProperty] + public List Events { get; internal set; } + } + +#pragma warning disable SA1402 // File may only contain a single type + internal class SpanEvent +#pragma warning restore SA1402 // File may only contain a single type + { + [JsonProperty] + public string Name { get; internal set; } + + [JsonProperty] + public long Ts { get; internal set; } + + [JsonProperty] + public Dictionary Tags { get; internal set; } + } +} + +#pragma warning disable SA1402 // File may only contain a single type +public class DataConverter : JsonConverter +#pragma warning restore SA1402 // File may only contain a single type +{ + public override bool CanWrite => false; + + public override bool CanRead => true; + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(OpenTelemetry.Exporter.Instana.Tests.Data); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + { + return string.Empty; + } + else if (reader.TokenType == JsonToken.String) + { + return serializer.Deserialize(reader, objectType); + } + else + { + JObject obj = JObject.Load(reader); + var data = obj.Root; + if (data != null) + { + var newData = new OpenTelemetry.Exporter.Instana.Tests.Data(); + foreach (var field in data) + { + if (((Newtonsoft.Json.Linq.JProperty)field).Name == "tags" || + ((Newtonsoft.Json.Linq.JProperty)field).Name == "events") + { + continue; + } + + if (newData.data == null) + { + newData.data = new Dictionary(); + } + + newData.data[((Newtonsoft.Json.Linq.JProperty)field).Name] = ((Newtonsoft.Json.Linq.JProperty)field).Value.ToString(); + } + + var existingData = existingValue as OpenTelemetry.Exporter.Instana.Tests.Data ?? new OpenTelemetry.Exporter.Instana.Tests.Data(); + + // Populate the remaining standard properties + using (var subReader = data.CreateReader()) + { + serializer.Populate(subReader, existingData); + } + + newData.Events = existingData.Events; + newData.Tags = existingData.Tags; + + return newData; + } + + return null; + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotImplementedException(); + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj new file mode 100644 index 0000000000..0b17f09239 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp3.1 + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs new file mode 100644 index 0000000000..0cd6b4dba7 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs @@ -0,0 +1,52 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Threading.Tasks; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests.Processors +{ + public class DefaultActivityProcessorTests + { + private DefaultActivityProcessor defaultActivityProcessor = new DefaultActivityProcessor(); + + [Fact] + public async Task ProcessAsync() + { + Activity activity = new Activity("testOperationName"); + activity.Start(); + await Task.Delay(200); + activity.Stop(); + InstanaSpan instanaSpan = new InstanaSpan(); + await this.defaultActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.False(string.IsNullOrEmpty(instanaSpan.S)); + Assert.False(string.IsNullOrEmpty(instanaSpan.Lt)); + Assert.True(instanaSpan.D > 0); + Assert.True(instanaSpan.Ts > 0); + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.data); + Assert.Contains(instanaSpan.Data.data, filter: x => + { + return x.Key == "kind" + && x.Value.Equals("internal"); + }); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs new file mode 100644 index 0000000000..8b262b65b6 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -0,0 +1,64 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Threading.Tasks; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests.Processors +{ + public class ErrorActivityProcessorTests + { + private ErrorActivityProcessor errorActivityProcessor = new ErrorActivityProcessor(); + + [Fact] + public async Task Process_ErrorStatusCodeIsSet() + { + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + InstanaSpan instanaSpan = new InstanaSpan(); + await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.True(instanaSpan.Ec == 1); + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.data); + Assert.Equal("Error", instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD]); + Assert.Equal("TestErrorDesc", instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD]); + } + + [Fact] + public async Task Process_ExistsExceptionEvent() + { + Activity activity = new Activity("testOperationName"); + InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new OpenTelemetry.Exporter.Instana.Implementation.InstanaSpanTransformInfo() { HasExceptionEvent = true } }; + await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.True(instanaSpan.Ec == 1); + } + + [Fact] + public async Task Process_NoError() + { + Activity activity = new Activity("testOperationName"); + InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new OpenTelemetry.Exporter.Instana.Implementation.InstanaSpanTransformInfo() }; + await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.True(instanaSpan.Ec == 0); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs new file mode 100644 index 0000000000..a51ae08af6 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -0,0 +1,64 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading.Tasks; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests.Processors +{ + public class EventsActivityProcessorTests + { + private EventsActivityProcessor eventsActivityProcessor = new EventsActivityProcessor(); + + [Fact] + public async Task ProcessAsync() + { + var activityTagsCollection = new ActivityTagsCollection(); + activityTagsCollection.Add(new KeyValuePair("eventTagKey", "eventTagValue")); + var activityEvent = new ActivityEvent( + "testActivityEvent", + DateTimeOffset.MinValue, + activityTagsCollection); + + var activityTagsCollection2 = new ActivityTagsCollection(); + activityTagsCollection2.Add(new KeyValuePair("eventTagKey2", "eventTagValue2")); + var activityEvent2 = new ActivityEvent( + "testActivityEvent2", + DateTimeOffset.MaxValue, + activityTagsCollection2); + + Activity activity = new Activity("testOperationName"); + activity.AddEvent(activityEvent); + activity.AddEvent(activityEvent2); + InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new OpenTelemetry.Exporter.Instana.Implementation.InstanaSpanTransformInfo() }; + await this.eventsActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.True(instanaSpan.Ec == 0); + Assert.True(instanaSpan.Data.Events.Count == 2); + Assert.True(instanaSpan.Data.Events[0].Name == "testActivityEvent"); + Assert.True(instanaSpan.Data.Events[0].Ts > 0); + Assert.True(instanaSpan.Data.Events[0].Tags["eventTagKey"] == "eventTagValue"); + Assert.True(instanaSpan.Data.Events[1].Name == "testActivityEvent2"); + Assert.True(instanaSpan.Data.Events[1].Ts > 0); + Assert.True(instanaSpan.Data.Events[1].Tags["eventTagKey2"] == "eventTagValue2"); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs new file mode 100644 index 0000000000..4346fe3156 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs @@ -0,0 +1,63 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Threading.Tasks; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; +using Xunit; + +namespace OpenTelemetry.Exporter.Instana.Tests.Processors +{ + public class TagsActivityProcessorTests + { + private TagsActivityProcessor tagsActivityProcessor = new TagsActivityProcessor(); + + [Fact] + public async Task ProcessAsync_StatusTagsExist() + { + Activity activity = new Activity("testOperationName"); + activity.AddTag("otel.status_code", "testStatusCode"); + activity.AddTag("otel.status_description", "testStatusDescription"); + activity.AddTag("otel.testTag", "testTag"); + + InstanaSpan instanaSpan = new InstanaSpan(); + await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.Tags); + Assert.Contains(instanaSpan.Data.Tags, x => x.Key == "otel.testTag" && x.Value == "testTag"); + Assert.Equal("testStatusCode", instanaSpan.TransformInfo.StatusCode); + Assert.Equal("testStatusDescription", instanaSpan.TransformInfo.StatusDesc); + } + + [Fact] + public async Task ProcessAsync_StatusTagsDoNotExist() + { + Activity activity = new Activity("testOperationName"); + activity.AddTag("otel.testTag", "testTag"); + + InstanaSpan instanaSpan = new InstanaSpan(); + await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.Tags); + Assert.Contains(instanaSpan.Data.Tags, x => x.Key == "otel.testTag" && x.Value == "testTag"); + Assert.Equal(string.Empty, instanaSpan.TransformInfo.StatusCode); + Assert.Equal(string.Empty, instanaSpan.TransformInfo.StatusDesc); + } + } +} From 8d3510ac6b0a90e5fe8ac913dec3565d3fba85e2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 23 May 2022 14:07:45 -0700 Subject: [PATCH 0129/1499] Add StackExchangeRedis Instrumentation to contrib repo (#366) * Add StackExchangeRedis Instrumentation --- build/Common.props | 2 + opentelemetry-dotnet-contrib.sln | 16 +- .../OpenTelemetry.Contrib.Shared.csproj | 4 +- .../ServiceProviderExtensions.cs | 47 ++ .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 13 + .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 13 + .../AssemblyInfo.cs | 34 ++ .../CHANGELOG.md | 109 +++++ .../RedisProfilerEntryToActivityConverter.cs | 210 +++++++++ ....Instrumentation.StackExchangeRedis.csproj | 22 + .../README.md | 137 ++++++ .../StackExchangeRedisCallsInstrumentation.cs | 151 +++++++ ...xchangeRedisCallsInstrumentationOptions.cs | 48 ++ .../TracerProviderBuilderExtensions.cs | 90 ++++ .../OpenTelemetry.Contrib.Tests.Shared.csproj | 3 +- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 43 ++ .../Dockerfile | 17 + ...isProfilerEntryToActivityConverterTests.cs | 181 ++++++++ ...umentation.StackExchangeRedis.Tests.csproj | 31 ++ ...kExchangeRedisCallsInstrumentationTests.cs | 417 ++++++++++++++++++ .../docker-compose.yml | 20 + 23 files changed, 1604 insertions(+), 4 deletions(-) create mode 100644 src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs create mode 100644 test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile create mode 100644 test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml diff --git a/build/Common.props b/build/Common.props index 410363d97f..ee39b145cc 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,6 +31,8 @@ [3.3.2] [1.0.0,2.0) [1.2.0-beta.354,2.0) + [2.1.58,3.0) + [3.1.0,) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e63236fb14..5db4edc60d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -34,8 +34,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml - .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml + .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml @@ -190,6 +190,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Inst EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana.Tests", "test\OpenTelemetry.Exporter.Instana.Tests\OpenTelemetry.Exporter.Instana.Tests.csproj", "{77E7DDB9-32CF-450E-B596-E893149D07DD}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis", "src\OpenTelemetry.Instrumentation.StackExchangeRedis\OpenTelemetry.Instrumentation.StackExchangeRedis.csproj", "{14BAEC26-CCD1-44B5-94D7-F219057B0B4D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests", "test\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj", "{2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -392,6 +396,14 @@ Global {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.Build.0 = Debug|Any CPU {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.ActiveCfg = Release|Any CPU {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.Build.0 = Release|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Release|Any CPU.Build.0 = Release|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -452,6 +464,8 @@ Global {17E3936A-265A-4C9F-9DD5-4568F80E6D91} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {BD3C6377-6F8D-47D6-9710-1681ED4E6772} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {77E7DDB9-32CF-450E-B596-E893149D07DD} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj index 232f379b5d..5bfdb9cac6 100644 --- a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj +++ b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj @@ -5,9 +5,9 @@ - - + + diff --git a/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs b/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs new file mode 100644 index 0000000000..c92e3ba0b5 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER +using Microsoft.Extensions.Options; +#endif + +namespace System +{ + /// + /// Extension methods for OpenTelemetry dependency injection support. + /// + internal static class ServiceProviderExtensions + { + /// + /// Get options from the supplied . + /// + /// Options type. + /// . + /// Options instance. + public static T GetOptions(this IServiceProvider serviceProvider) + where T : class, new() + { +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER + IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); + + // Note: options could be null if user never invoked services.AddOptions(). + return options?.Value ?? new T(); +#else + return new T(); +#endif + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a1a71d36cb --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,13 @@ +OpenTelemetry.Instrumentation.MultiTypePropertyFetcher +OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.Fetch(object obj) -> T +OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.MultiTypePropertyFetcher(string propertyName) -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.get -> System.TimeSpan +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.StackExchangeRedisCallsInstrumentationOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, StackExchange.Redis.IConnectionMultiplexer connection = null, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a1a71d36cb --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,13 @@ +OpenTelemetry.Instrumentation.MultiTypePropertyFetcher +OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.Fetch(object obj) -> T +OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.MultiTypePropertyFetcher(string propertyName) -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.get -> System.TimeSpan +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.StackExchangeRedisCallsInstrumentationOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, StackExchange.Redis.IConnectionMultiplexer connection = null, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs new file mode 100644 index 0000000000..4ecd381011 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] + +#if SIGNED +internal static class AssemblyInfo +{ + public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; + public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; +} +#else +internal static class AssemblyInfo +{ + public const string PublicKey = ""; + public const string MoqPublicKey = ""; +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md new file mode 100644 index 0000000000..348502a14d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -0,0 +1,109 @@ +# Changelog + +## Unreleased + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +* Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is + .NET 4.6.2. + ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) + +* Bumped minimum required version of `Microsoft.Extensions.Options` to 3.1.0. + ([#2582](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3196)) + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +* Adds SetVerboseDatabaseStatements option to allow setting more detailed + database statement tag values. +* Adds Enrich option to allow enriching activities from the source profiled + command objects. +* Removes upper constraint for Microsoft.Extensions.Options dependency. + ([#2179](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2179)) + +## 1.0.0-rc7 + +Released 2021-Jul-12 + +## 1.0.0-rc6 + +Released 2021-Jun-25 + +* `AddRedisInstrumentation` extension will now resolve `IConnectionMultiplexer` + & `StackExchangeRedisCallsInstrumentationOptions` through DI when + OpenTelemetry.Extensions.Hosting is in use. + ([#2110](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2110)) + +## 1.0.0-rc5 + +Released 2021-Jun-09 + +## 1.0.0-rc4 + +Released 2021-Apr-23 + +* Activities are now created with the `db.system` attribute set for usage during + sampling. + ([#1984](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1984)) + +## 1.0.0-rc3 + +Released 2021-Mar-19 + +## 1.0.0-rc2 + +Released 2021-Jan-29 + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +## 0.8.0-beta.1 + +Released 2020-Nov-5 + +## 0.7.0-beta.1 + +Released 2020-Oct-16 + +* Span Status is populated as per new spec + ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) + +## 0.6.0-beta.1 + +Released 2020-Sep-15 + +## 0.5.0-beta.2 + +Released 2020-08-28 + +## 0.4.0-beta.2 + +Released 2020-07-24 + +* First beta release + +## 0.3.0-beta + +Released 2020-07-23 + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs new file mode 100644 index 0000000000..89731ffb42 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -0,0 +1,210 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net; +using System.Reflection; +using System.Reflection.Emit; +using OpenTelemetry.Trace; +using StackExchange.Redis.Profiling; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation +{ + internal static class RedisProfilerEntryToActivityConverter + { + private static readonly Lazy> MessageDataGetter = new(() => + { + var redisAssembly = typeof(IProfiledCommand).Assembly; + Type profiledCommandType = redisAssembly.GetType("StackExchange.Redis.Profiling.ProfiledCommand"); + Type messageType = redisAssembly.GetType("StackExchange.Redis.Message"); + Type scriptMessageType = redisAssembly.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage"); + + var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); + var scriptDelegate = CreateFieldGetter(scriptMessageType, "script", BindingFlags.NonPublic | BindingFlags.Instance); + var commandAndKeyFetcher = new PropertyFetcher("CommandAndKey"); + + if (messageDelegate == null) + { + return new Func(source => (null, null)); + } + + return new Func(source => + { + if (source == null) + { + return (null, null); + } + + var message = messageDelegate(source); + if (message == null) + { + return (null, null); + } + + string script = null; + if (message.GetType() == scriptMessageType) + { + script = scriptDelegate.Invoke(message); + } + + if (commandAndKeyFetcher.TryFetch(message, out var value)) + { + return (value, script); + } + + return (null, script); + }); + }); + + public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfiledCommand command, StackExchangeRedisCallsInstrumentationOptions options) + { + var name = command.Command; // Example: SET; + if (string.IsNullOrEmpty(name)) + { + name = StackExchangeRedisCallsInstrumentation.ActivityName; + } + + var activity = StackExchangeRedisCallsInstrumentation.ActivitySource.StartActivity( + name, + ActivityKind.Client, + parentActivity?.Context ?? default, + StackExchangeRedisCallsInstrumentation.CreationTags, + startTime: command.CommandCreated); + + if (activity == null) + { + return null; + } + + activity.SetEndTime(command.CommandCreated + command.ElapsedTime); + + if (activity.IsAllDataRequested == true) + { + // see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md + + // Timing example: + // command.CommandCreated; //2019-01-10 22:18:28Z + + // command.CreationToEnqueued; // 00:00:32.4571995 + // command.EnqueuedToSending; // 00:00:00.0352838 + // command.SentToResponse; // 00:00:00.0060586 + // command.ResponseToCompletion; // 00:00:00.0002601 + + // Total: + // command.ElapsedTime; // 00:00:32.4988020 + + activity.SetStatus(Status.Unset); + + activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName, command.Flags.ToString()); + + if (options.SetVerboseDatabaseStatements) + { + var (commandAndKey, script) = MessageDataGetter.Value.Invoke(command); + + if (!string.IsNullOrEmpty(commandAndKey) && !string.IsNullOrEmpty(script)) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, commandAndKey + " " + script); + } + else if (!string.IsNullOrEmpty(commandAndKey)) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, commandAndKey); + } + else if (command.Command != null) + { + // Example: "db.statement": SET; + activity.SetTag(SemanticConventions.AttributeDbStatement, command.Command); + } + } + else if (command.Command != null) + { + // Example: "db.statement": SET; + activity.SetTag(SemanticConventions.AttributeDbStatement, command.Command); + } + + if (command.EndPoint != null) + { + if (command.EndPoint is IPEndPoint ipEndPoint) + { + activity.SetTag(SemanticConventions.AttributeNetPeerIp, ipEndPoint.Address.ToString()); + activity.SetTag(SemanticConventions.AttributeNetPeerPort, ipEndPoint.Port); + } + else if (command.EndPoint is DnsEndPoint dnsEndPoint) + { + activity.SetTag(SemanticConventions.AttributeNetPeerName, dnsEndPoint.Host); + activity.SetTag(SemanticConventions.AttributeNetPeerPort, dnsEndPoint.Port); + } + else + { + activity.SetTag(SemanticConventions.AttributePeerService, command.EndPoint.ToString()); + } + } + + activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName, command.Db); + + // TODO: deal with the re-transmission + // command.RetransmissionOf; + // command.RetransmissionReason; + + var enqueued = command.CommandCreated.Add(command.CreationToEnqueued); + var send = enqueued.Add(command.EnqueuedToSending); + var response = send.Add(command.SentToResponse); + + activity.AddEvent(new ActivityEvent("Enqueued", enqueued)); + activity.AddEvent(new ActivityEvent("Sent", send)); + activity.AddEvent(new ActivityEvent("ResponseReceived", response)); + + options.Enrich?.Invoke(activity, command); + } + + activity.Stop(); + + return activity; + } + + public static void DrainSession(Activity parentActivity, IEnumerable sessionCommands, StackExchangeRedisCallsInstrumentationOptions options) + { + foreach (var command in sessionCommands) + { + ProfilerCommandToActivity(parentActivity, command, options); + } + } + + /// + /// Creates getter for a field defined in private or internal type + /// repesented with classType variable. + /// + private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) + { + FieldInfo field = classType.GetField(fieldName, flags); + if (field != null) + { + string methodName = classType.FullName + ".get_" + field.Name; + DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); + ILGenerator generator = getterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, classType); + generator.Emit(OpCodes.Ldfld, field); + generator.Emit(OpCodes.Ret); + + return (Func)getterMethod.CreateDelegate(typeof(Func)); + } + + return null; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj new file mode 100644 index 0000000000..572e03f7b8 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -0,0 +1,22 @@ + + + + netstandard2.0;net462 + StackExchange.Redis instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing;Redis;StackExchange.Redis + true + true + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md new file mode 100644 index 0000000000..5b109755fb --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -0,0 +1,137 @@ +# StackExchange.Redis Instrumentation for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.StackExchangeRedis.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.StackExchangeRedis.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) + +This is an +[Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments +[StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis/) +and collects traces about outgoing calls to Redis. + +**Note: This component is based on the OpenTelemetry semantic conventions for +[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +These conventions are +[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), +and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +Until a [stable +version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be breaking changes. You can track the progress from +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** + +## Steps to enable OpenTelemetry.Instrumentation.StackExchangeRedis + +## Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.StackExchangeRedis`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.StackExchangeRedis +``` + +## Step 2: Enable StackExchange.Redis Instrumentation at application startup + +StackExchange.Redis instrumentation must be enabled at application startup. +`AddRedisInstrumentation` method on `TracerProviderBuilder` must be called to +enable Redis instrumentation, passing the `IConnectionMultiplexer` instance used +to make Redis calls. Only those Redis calls made using the same instance of the +`IConnectionMultiplexer` will be instrumented. + +The following example demonstrates adding StackExchange.Redis instrumentation to +a console application. This example also sets up the OpenTelemetry Console +exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + // Connect to the server. + using var connection = ConnectionMultiplexer.Connect("localhost:6379"); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation(connection) + .AddConsoleExporter() + .Build(); + } +} +``` + +For an ASP.NET Core application, adding instrumentation is typically done in +the `ConfigureServices` of your `Startup` class. Refer to documentation for +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). + +For an ASP.NET application, adding instrumentation is typically done in the +`Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). + +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`StackExchangeRedisCallsInstrumentationOptions`. + +### FlushInterval + +StackExchange.Redis has its own internal profiler. OpenTelemetry converts each +profiled command from the internal profiler to an Activity for collection. By +default, this conversion process flushes profiled commands on a 10 second +interval. The `FlushInterval` option can be used to adjust this interval. + +The following example shows how to use `FlushInterval`. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation( + connection, + options => options.FlushInterval = TimeSpan.FromSeconds(5)) + .AddConsoleExporter() + .Build(); +``` + +### SetVerboseDatabaseStatements + +StackExchange.Redis by default does not give detailed database statements like +what key or script was used during an operation. The `SetVerboseDatabaseStatements` +option can be used to enable gathering this more detailed information. + +The following example shows how to use `SetVerboseDatabaseStatements`. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation( + connection, + options => options.SetVerboseDatabaseStatements = true) + .AddConsoleExporter() + .Build(); +``` + +## Enrich + +This option allows one to enrich the activity with additional information from the +raw `IProfiledCommand` object. The `Enrich` action is called only when +`activity.IsAllDataRequested` is `true`. It contains the activity itself (which can +be enriched), and the source profiled command object. + +The following code snippet shows how to add additional tags using `Enrich`. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation(opt => opt.Enrich = (activity, command) => + { + if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) + { + activity.SetTag("is_fast", true); + } + }) + .Build(); +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) +* [StackExchange.Redis Profiling](https://stackexchange.github.io/StackExchange.Redis/Profiling_v1.html) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs new file mode 100644 index 0000000000..8446fed165 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs @@ -0,0 +1,151 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; +using StackExchange.Redis; +using StackExchange.Redis.Profiling; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis +{ + /// + /// Redis calls instrumentation. + /// + internal class StackExchangeRedisCallsInstrumentation : IDisposable + { + internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; + internal const string RedisFlagsKeyName = "db.redis.flags"; + internal const string ActivitySourceName = "OpenTelemetry.StackExchange.Redis"; + internal const string ActivityName = ActivitySourceName + ".Execute"; + internal static readonly Version Version = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Version; + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly IEnumerable> CreationTags = new[] + { + new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), + }; + + internal readonly ConcurrentDictionary<(ActivityTraceId TraceId, ActivitySpanId SpanId), (Activity Activity, ProfilingSession Session)> Cache + = new(); + + private readonly StackExchangeRedisCallsInstrumentationOptions options; + private readonly EventWaitHandle stopHandle = new(false, EventResetMode.ManualReset); + private readonly Thread drainThread; + + private readonly ProfilingSession defaultSession = new(); + + /// + /// Initializes a new instance of the class. + /// + /// to instrument. + /// Configuration options for redis instrumentation. + public StackExchangeRedisCallsInstrumentation(IConnectionMultiplexer connection, StackExchangeRedisCallsInstrumentationOptions options) + { + Guard.ThrowIfNull(connection); + + this.options = options ?? new StackExchangeRedisCallsInstrumentationOptions(); + + this.drainThread = new Thread(this.DrainEntries) + { + Name = "OpenTelemetry.Redis", + }; + this.drainThread.Start(); + + connection.RegisterProfiler(this.GetProfilerSessionsFactory()); + } + + /// + /// Returns session for the Redis calls recording. + /// + /// Session associated with the current span context to record Redis calls. + public Func GetProfilerSessionsFactory() + { + return () => + { + if (this.stopHandle.WaitOne(0)) + { + return null; + } + + Activity parent = Activity.Current; + + // If no parent use the default session. + if (parent == null || parent.IdFormat != ActivityIdFormat.W3C) + { + return this.defaultSession; + } + + // Try to reuse a session for all activities created under the same TraceId+SpanId. + var cacheKey = (parent.TraceId, parent.SpanId); + if (!this.Cache.TryGetValue(cacheKey, out var session)) + { + session = (parent, new ProfilingSession()); + this.Cache.TryAdd(cacheKey, session); + } + + return session.Session; + }; + } + + /// + public void Dispose() + { + this.stopHandle.Set(); + this.drainThread.Join(); + + this.Flush(); + + this.stopHandle.Dispose(); + } + + internal void Flush() + { + RedisProfilerEntryToActivityConverter.DrainSession(null, this.defaultSession.FinishProfiling(), this.options); + + foreach (var entry in this.Cache) + { + var parent = entry.Value.Activity; + if (parent.Duration == TimeSpan.Zero) + { + // Activity is still running, don't drain. + continue; + } + + ProfilingSession session = entry.Value.Session; + RedisProfilerEntryToActivityConverter.DrainSession(parent, session.FinishProfiling(), this.options); + this.Cache.TryRemove((entry.Key.TraceId, entry.Key.SpanId), out _); + } + } + + private void DrainEntries(object state) + { + while (true) + { + if (this.stopHandle.WaitOne(this.options.FlushInterval)) + { + break; + } + + this.Flush(); + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs new file mode 100644 index 0000000000..e65c92a220 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs @@ -0,0 +1,48 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using OpenTelemetry.Trace; +using StackExchange.Redis.Profiling; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis +{ + /// + /// Options for StackExchange.Redis instrumentation. + /// + public class StackExchangeRedisCallsInstrumentationOptions + { + /// + /// Gets or sets the maximum time that should elapse between flushing the internal buffer of Redis profiling sessions and creating objects. Default value: 00:00:10. + /// + public TimeSpan FlushInterval { get; set; } = TimeSpan.FromSeconds(10); + + /// + /// Gets or sets a value indicating whether or not the should use reflection to get more detailed tag values. Default value: False. + /// + public bool SetVerboseDatabaseStatements { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the profiled redis command from which additional information can be extracted to enrich the activity. + /// + public Action Enrich { get; set; } + } +} diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..fc52b8751e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -0,0 +1,90 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.StackExchangeRedis; +using OpenTelemetry.Internal; +using StackExchange.Redis; + +namespace OpenTelemetry.Trace +{ + /// + /// Extension methods to simplify registering of dependency instrumentation. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// + /// Note: If an is not supplied + /// using the parameter it will be + /// resolved using the application . + /// + /// being configured. + /// Optional to instrument. + /// Optional callback to configure options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + IConnectionMultiplexer connection = null, + Action configure = null) + { + Guard.ThrowIfNull(builder); + + if (builder is not IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + if (connection == null) + { + throw new NotSupportedException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} must be supplied when dependency injection is unavailable - to enable dependency injection use the OpenTelemetry.Extensions.Hosting package"); + } + + return AddRedisInstrumentation(builder, connection, new StackExchangeRedisCallsInstrumentationOptions(), configure); + } + + return deferredTracerProviderBuilder.Configure((sp, builder) => + { + if (connection == null) + { + connection = (IConnectionMultiplexer)sp.GetService(typeof(IConnectionMultiplexer)); + if (connection == null) + { + throw new InvalidOperationException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} could not be resolved through application {nameof(IServiceProvider)}"); + } + } + + AddRedisInstrumentation( + builder, + connection, + sp.GetOptions(), + configure); + }); + } + + private static TracerProviderBuilder AddRedisInstrumentation( + TracerProviderBuilder builder, + IConnectionMultiplexer connection, + StackExchangeRedisCallsInstrumentationOptions options, + Action configure = null) + { + configure?.Invoke(options); + + return builder + .AddInstrumentation(() => new StackExchangeRedisCallsInstrumentation(connection, options)) + .AddSource(StackExchangeRedisCallsInstrumentation.ActivitySourceName); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj index 1224c29329..32de4e5218 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj +++ b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj @@ -6,7 +6,8 @@ - + + diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs new file mode 100644 index 0000000000..4b37f9ff03 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System; +using Xunit; + +namespace OpenTelemetry.Tests +{ + internal class SkipUnlessEnvVarFoundTheoryAttribute : TheoryAttribute + { + public SkipUnlessEnvVarFoundTheoryAttribute(string environmentVariable) + { + if (string.IsNullOrEmpty(GetEnvironmentVariable(environmentVariable))) + { + this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; + } + } + + public static string GetEnvironmentVariable(string environmentVariableName) + { + string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); + + if (string.IsNullOrEmpty(environmentVariableValue)) + { + environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine); + } + + return environmentVariableValue; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile new file mode 100644 index 0000000000..5f3f9f866c --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile @@ -0,0 +1,17 @@ +# Create a container for running the OpenTelemetry Redis integration tests. +# This should be run from the root of the repo: +# docker build --file test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile . + +ARG SDK_VERSION=6.0 +FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build +ARG PUBLISH_CONFIGURATION=Release +ARG PUBLISH_FRAMEWORK=net6.0 +WORKDIR /repo +COPY . ./ +WORKDIR "/repo/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" +RUN dotnet publish "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} + +FROM mcr.microsoft.com/dotnet/sdk:${SDK_VERSION} AS final +WORKDIR /test +COPY --from=build /drop . +ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.dll"] diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs new file mode 100644 index 0000000000..61c3d47668 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -0,0 +1,181 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using Moq; +using OpenTelemetry.Trace; +using StackExchange.Redis; +using StackExchange.Redis.Profiling; +using Xunit; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation +{ + [Collection("Redis")] + public class RedisProfilerEntryToActivityConverterTests : IDisposable + { + private readonly ConnectionMultiplexer connection; + private readonly IDisposable tracerProvider; + + public RedisProfilerEntryToActivityConverterTests() + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); + + this.connection = ConnectionMultiplexer.Connect(connectionOptions); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation(this.connection) + .Build(); + } + + public void Dispose() + { + this.tracerProvider.Dispose(); + this.connection.Dispose(); + GC.SuppressFinalize(this); + } + + [Fact] + public void ProfilerCommandToActivity_UsesCommandAsName() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.Command).Returns("SET"); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.Equal("SET", result.DisplayName); + } + + [Fact] + public void ProfilerCommandToActivity_UsesTimestampAsStartTime() + { + var now = DateTimeOffset.Now; + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(now.DateTime); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.Equal(now, result.StartTimeUtc); + } + + [Fact] + public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("redis", result.GetTagValue(SemanticConventions.AttributeDbSystem)); + } + + [Fact] + public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.Command).Returns("SET"); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbStatement)); + Assert.Equal("SET", result.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + + [Fact] + public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + var expectedFlags = CommandFlags.FireAndForget | + CommandFlags.NoRedirect; + profiledCommand.Setup(m => m.Flags).Returns(expectedFlags); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.NotNull(result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); + Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); + } + + [Fact] + public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() + { + long address = 1; + int port = 2; + + var activity = new Activity("redis-profiler"); + IPEndPoint ipLocalEndPoint = new IPEndPoint(address, port); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.EndPoint).Returns(ipLocalEndPoint); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); + Assert.Equal($"{address}.0.0.0", result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal(port, result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } + + [Fact] + public void ProfilerCommandToActivity_UsesDnsEndPointAsEndPoint() + { + var dnsEndPoint = new DnsEndPoint("https://opentelemetry.io/", 443); + + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.EndPoint).Returns(dnsEndPoint); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(dnsEndPoint.Host, result.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal(dnsEndPoint.Port, result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } + +#if !NETFRAMEWORK + [Fact] + public void ProfilerCommandToActivity_UsesOtherEndPointAsEndPoint() + { + var unixEndPoint = new UnixDomainSocketEndPoint("https://opentelemetry.io/"); + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.EndPoint).Returns(unixEndPoint); + + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributePeerService)); + Assert.Equal(unixEndPoint.ToString(), result.GetTagValue(SemanticConventions.AttributePeerService)); + } +#endif + } +} diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj new file mode 100644 index 0000000000..769b012dd3 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -0,0 +1,31 @@ + + + Unit test project for OpenTelemetry StackExchangeRedis instrumentation + + net6.0;netcoreapp3.1 + $(TargetFrameworks);net462 + $(TARGET_FRAMEWORK) + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs new file mode 100644 index 0000000000..99b317f098 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -0,0 +1,417 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System; +using System.Diagnostics; +using System.Net; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using StackExchange.Redis; +using StackExchange.Redis.Profiling; +using Xunit; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Tests +{ + [Collection("Redis")] + public class StackExchangeRedisCallsInstrumentationTests + { + /* + To run the integration tests, set the OTEL_REDISENDPOINT machine-level environment variable to a valid Redis endpoint. + + To use Docker... + 1) Run: docker run -d --name redis -p 6379:6379 redis + 2) Set OTEL_REDISENDPOINT as: localhost:6379 + */ + + private const string RedisEndPointEnvVarName = "OTEL_REDISENDPOINT"; + private static readonly string RedisEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(RedisEndPointEnvVarName); + + [Trait("CategoryName", "RedisIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] + [InlineData("value1")] + public void SuccessfulCommandTestWithKey(string value) + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = true, + }; + connectionOptions.EndPoints.Add(RedisEndPoint); + + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + var db = connection.GetDatabase(); + db.KeyDelete("key1"); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = true) + .Build()) + { + var prepared = LuaScript.Prepare("redis.call('set', @key, @value)"); + db.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 }); + + var redisValue = db.StringGet("key1"); + + Assert.False(redisValue.HasValue); + + bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + + Assert.True(set); + + redisValue = db.StringGet("key1"); + + Assert.True(redisValue.HasValue); + Assert.Equal(value, redisValue.ToString()); + } + + // Disposing SDK should flush the Redis profiling session immediately. + + Assert.Equal(11, activityProcessor.Invocations.Count); + + var scriptActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Equal("EVAL", scriptActivity.DisplayName); + Assert.Equal("EVAL redis.call('set', ARGV[1], ARGV[2])", scriptActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); + + VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], true); + VerifyActivityData((Activity)activityProcessor.Invocations[5].Arguments[0], true, connection.GetEndPoints()[0], true); + VerifyActivityData((Activity)activityProcessor.Invocations[7].Arguments[0], false, connection.GetEndPoints()[0], true); + VerifySamplingParameters(sampler.LatestSamplingParameters); + } + + [Trait("CategoryName", "RedisIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] + [InlineData("value1")] + public void SuccessfulCommandTest(string value) + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = true, + }; + connectionOptions.EndPoints.Add(RedisEndPoint); + + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = false) + .Build()) + { + var db = connection.GetDatabase(); + + bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + + Assert.True(set); + + var redisValue = db.StringGet("key1"); + + Assert.True(redisValue.HasValue); + Assert.Equal(value, redisValue.ToString()); + } + + // Disposing SDK should flush the Redis profiling session immediately. + + Assert.Equal(7, activityProcessor.Invocations.Count); + + VerifyActivityData((Activity)activityProcessor.Invocations[1].Arguments[0], true, connection.GetEndPoints()[0], false); + VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], false); + VerifySamplingParameters(sampler.LatestSamplingParameters); + } + + [Fact] + public async void ProfilerSessionUsesTheSameDefault() + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); + + var connection = ConnectionMultiplexer.Connect(connectionOptions); + + using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + var profilerFactory = instrumentation.GetProfilerSessionsFactory(); + var first = profilerFactory(); + var second = profilerFactory(); + ProfilingSession third = null; + await Task.Delay(1).ContinueWith((t) => { third = profilerFactory(); }); + Assert.Equal(first, second); + Assert.Equal(second, third); + } + + [Trait("CategoryName", "RedisIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] + [InlineData("value1")] + public void CanEnrichActivityFromCommand(string value) + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = true, + }; + connectionOptions.EndPoints.Add(RedisEndPoint); + + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(connection, c => c.Enrich = (activity, command) => + { + if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) + { + activity.AddTag("is_fast", true); + } + }) + .Build()) + { + var db = connection.GetDatabase(); + + bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + + Assert.True(set); + + var redisValue = db.StringGet("key1"); + + Assert.True(redisValue.HasValue); + Assert.Equal(value, redisValue.ToString()); + } + + // Disposing SDK should flush the Redis profiling session immediately. + + Assert.Equal(7, activityProcessor.Invocations.Count); + + var setActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Equal(true, setActivity.GetTagValue("is_fast")); + var getActivity = (Activity)activityProcessor.Invocations[3].Arguments[0]; + Assert.Equal(true, getActivity.GetTagValue("is_fast")); + } + + [Fact] + public void CheckCacheIsFlushedProperly() + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); + + var connection = ConnectionMultiplexer.Connect(connectionOptions); + + using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + var profilerFactory = instrumentation.GetProfilerSessionsFactory(); + + // start a root level activity + using Activity rootActivity = new Activity("Parent") + .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) + .Start(); + + Assert.NotNull(rootActivity.Id); + + // get an initial profiler from root activity + Activity.Current = rootActivity; + ProfilingSession profiler0 = profilerFactory(); + + // expect different result from synchronous child activity + ProfilingSession profiler1; + using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) + { + profiler1 = profilerFactory(); + Assert.NotSame(profiler0, profiler1); + } + + rootActivity.Stop(); + rootActivity.Dispose(); + + instrumentation.Flush(); + Assert.Empty(instrumentation.Cache); + } + + [Fact] + public async Task ProfilerSessionsHandleMultipleSpans() + { + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); + + var connection = ConnectionMultiplexer.Connect(connectionOptions); + + using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + var profilerFactory = instrumentation.GetProfilerSessionsFactory(); + + // start a root level activity + using Activity rootActivity = new Activity("Parent") + .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) + .Start(); + + Assert.NotNull(rootActivity.Id); + + // get an initial profiler from root activity + Activity.Current = rootActivity; + ProfilingSession profiler0 = profilerFactory(); + + // expect different result from synchronous child activity + ProfilingSession profiler1; + using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) + { + profiler1 = profilerFactory(); + Assert.NotSame(profiler0, profiler1); + } + + Activity.Current = rootActivity; + + // expect different result from asynchronous child activity + using (Activity.Current = new Activity("Child-Span-2").SetParentId(rootActivity.Id).Start()) + { + // lose async context on purpose + await Task.Delay(100).ConfigureAwait(false); + + ProfilingSession profiler2 = profilerFactory(); + Assert.NotSame(profiler0, profiler2); + Assert.NotSame(profiler1, profiler2); + } + + Activity.Current = rootActivity; + + // ensure same result back in root activity + ProfilingSession profiles3 = profilerFactory(); + Assert.Same(profiler0, profiles3); + } + + [Fact] + public void StackExchangeRedis_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddRedisInstrumentation(null)); + + var activityProcessor = new Mock>(); + Assert.Throws(() => + Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddRedisInstrumentation(null) + .Build()); + } + + [Fact] + public void StackExchangeRedis_DependencyInjection_Success() + { + bool connectionMultiplexerPickedFromDI = false; + bool optionsPickedFromDI = false; + + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost"); + + var services = new ServiceCollection(); + services.AddSingleton((sp) => + { + connectionMultiplexerPickedFromDI = true; + return ConnectionMultiplexer.Connect(connectionOptions); + }); + services.Configure(options => + { + optionsPickedFromDI = true; + }); + services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); + + using var serviceProvider = services.BuildServiceProvider(); + + var tracerProvider = serviceProvider.GetRequiredService(); + + Assert.True(connectionMultiplexerPickedFromDI); + Assert.True(optionsPickedFromDI); + } + + [Fact] + public void StackExchangeRedis_DependencyInjection_Failure() + { + var services = new ServiceCollection(); + + services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); + + using var serviceProvider = services.BuildServiceProvider(); + + Assert.Throws(() => serviceProvider.GetRequiredService()); + } + + private static void VerifyActivityData(Activity activity, bool isSet, EndPoint endPoint, bool setCommandKey = false) + { + if (isSet) + { + Assert.Equal("SETEX", activity.DisplayName); + if (setCommandKey) + { + Assert.Equal("SETEX key1", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + else + { + Assert.Equal("SETEX", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + } + else + { + Assert.Equal("GET", activity.DisplayName); + if (setCommandKey) + { + Assert.Equal("GET key1", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + else + { + Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + } + + Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal("redis", activity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal(0, activity.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName)); + + if (endPoint is IPEndPoint ipEndPoint) + { + Assert.Equal(ipEndPoint.Address.ToString(), activity.GetTagValue(SemanticConventions.AttributeNetPeerIp)); + Assert.Equal(ipEndPoint.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } + else if (endPoint is DnsEndPoint dnsEndPoint) + { + Assert.Equal(dnsEndPoint.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(dnsEndPoint.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } + else + { + Assert.Equal(endPoint.ToString(), activity.GetTagValue(SemanticConventions.AttributePeerService)); + } + } + + private static void VerifySamplingParameters(SamplingParameters samplingParameters) + { + Assert.NotNull(samplingParameters.Tags); + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeDbSystem + && (string)kvp.Value == "redis"); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml new file mode 100644 index 0000000000..7004e679c0 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml @@ -0,0 +1,20 @@ +# Start a redis container and then run OpenTelemetry redis integration tests. +# This should be run from the root of the repo: +# opentelemetry>docker-compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build +version: '3.7' + +services: + redis: + image: redis + ports: + - "6379:6379" + + tests: + build: + context: . + dockerfile: ./test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile + command: --TestCaseFilter:CategoryName=RedisIntegrationTests + environment: + - OTEL_REDISENDPOINT=redis:6379 + depends_on: + - redis From 0a03cfced7de0c3cc9da68df1aaaea5e5972f0b1 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 24 May 2022 05:08:35 -0700 Subject: [PATCH 0130/1499] Add workflow and issue template for RedisInstrumentation (#371) * Add workflow and issue template for RedisInstrumentation * Fix build --- ...comp_instrumentation_stackexchangeredis.md | 41 ++++++++++++++++ ...age-Instrumentation.StackExchangeRedis.yml | 49 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 1 + ....Instrumentation.StackExchangeRedis.csproj | 3 +- 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md create mode 100644 .github/workflows/package-Instrumentation.StackExchangeRedis.yml diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md new file mode 100644 index 0000000000..87f3f6bf7a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.StackExchangeRedis +about: Issue with OpenTelemetry.Instrumentation.StackExchangeRedis +labels: comp:instrumentation.stackexchangeredis +--- + +# Issue with OpenTelemetry.Instrumentation.StackExchangeRedis + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.2.0`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml new file mode 100644 index 0000000000..9c9b6f9b8c --- /dev/null +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Instrumentation.StackExchangeRedis + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.StackExchangeRedis-*' + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.StackExchangeRedis + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 5db4edc60d..7d772b65d8 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -47,6 +47,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml + .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 572e03f7b8..85121d6aa3 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -5,7 +5,8 @@ StackExchange.Redis instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;Redis;StackExchange.Redis true - true + Instrumentation.StackExchangeRedis- + true From 3603cbe63ccd69b290011b5632f65ce15e397188 Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Tue, 24 May 2022 16:26:19 +0200 Subject: [PATCH 0131/1499] Instana Exporter initial release (#372) --- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/OpenTelemetry.Exporter.Instana/CHANGELOG.md diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md new file mode 100644 index 0000000000..edc969a77d --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## Unreleased + +## 1.0.0 [2022-May-24] + +This is the first release of the `OpenTelemetry.Exporter.Instana` +project. From d72b4cd007b8b590e8997e09ab6a0e0925390ab5 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Tue, 24 May 2022 14:54:16 -0700 Subject: [PATCH 0132/1499] PassThru TableNameMappings using the logger category name. (#345) --- .../CHANGELOG.md | 3 + .../GenevaBaseExporter.cs | 16 +++ .../GenevaLogExporter.cs | 124 ++++++++++++++++-- .../MessagePackSerializer.cs | 17 +++ .../GenevaLogExporterTests.cs | 95 ++++++++++++++ 5 files changed, 243 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 95d9c0e3fe..098f363cdd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* PassThru TableNameMappings using the logger category name. +[345](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/345) + * Throw exception when `TableNameMappings` contains a `null` value. [322](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/322) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 7132e31a62..8cc50613a3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Collections.Generic; namespace OpenTelemetry.Exporter.Geneva; @@ -89,4 +90,19 @@ internal static int AddPartAField(byte[] buffer, int cursor, string name, object cursor = MessagePackSerializer.Serialize(buffer, cursor, value); return cursor; } + + internal static int AddPartAField(byte[] buffer, int cursor, string name, Span value) + { + if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + } + + cursor = MessagePackSerializer.SerializeSpan(buffer, cursor, value); + return cursor; + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 331ec1dda4..f700622aca 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -31,6 +31,7 @@ namespace OpenTelemetry.Exporter.Geneva; public class GenevaLogExporter : GenevaBaseExporter { private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + private const int MaxSanitizedEventNameLength = 50; private readonly IReadOnlyDictionary m_customFields; private readonly string m_defaultEventName = "Log"; @@ -44,6 +45,7 @@ public class GenevaLogExporter : GenevaBaseExporter }; private readonly IDataTransport m_dataTransport; + private readonly bool shouldPassThruTableMappings; private bool isDisposed; private Func convertToJson; @@ -65,7 +67,14 @@ public GenevaLogExporter(GenevaExporterOptions options) if (kv.Key == "*") { - this.m_defaultEventName = kv.Value; + if (kv.Value == "*") + { + this.shouldPassThruTableMappings = true; + } + else + { + this.m_defaultEventName = kv.Value; + } } else { @@ -204,14 +213,6 @@ internal int SerializeLogRecord(LogRecord logRecord) listKvp = logRecord.State as IReadOnlyList>; } - var name = logRecord.CategoryName; - - // If user configured explicit TableName, use it. - if (this.m_tableMappings == null || !this.m_tableMappings.TryGetValue(name, out var eventName)) - { - eventName = this.m_defaultEventName; - } - var buffer = m_buffer.Value; if (buffer == null) { @@ -242,7 +243,43 @@ internal int SerializeLogRecord(LogRecord logRecord) var timestamp = logRecord.Timestamp; var cursor = 0; cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); + + var categoryName = logRecord.CategoryName; + string eventName = null; + + Span sanitizedEventName = default; + + // If user configured explicit TableName, use it. + if (this.m_tableMappings != null && this.m_tableMappings.TryGetValue(categoryName, out eventName)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); + } + else if (!this.shouldPassThruTableMappings) + { + eventName = this.m_defaultEventName; + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); + } + else + { + int cursorStartIdx = cursor; + + if (categoryName.Length > 0) + { + cursor = SerializeSanitizedCategoryName(buffer, cursor, categoryName); + } + + if (cursor == cursorStartIdx) + { + // Serializing null as categoryName could not be sanitized into a valid string. + cursor = MessagePackSerializer.SerializeNull(buffer, cursor); + } + else + { + // Sanitized category name has been serialized. + sanitizedEventName = buffer.AsSpan().Slice(cursorStartIdx, cursor - cursorStartIdx); + } + } + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, timestamp); @@ -282,7 +319,15 @@ internal int SerializeLogRecord(LogRecord logRecord) } // Part A - core envelope - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + if (sanitizedEventName.Length != 0) + { + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, sanitizedEventName); + } + else + { + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + } + cntFields += 1; cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Time, timestamp); @@ -329,7 +374,7 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, categoryName); cntFields += 1; bool hasEnvProperties = false; @@ -443,5 +488,60 @@ private static byte GetSeverityNumber(LogLevel logLevel) return 1; } } + + // This method would map the logger category to a table name which only contains alphanumeric values with the following additions: + // Any character that is not allowed will be removed. + // If the resulting string is longer than 50 characters, only the first 50 characters will be taken. + // If the first character in the resulting string is a lower-case alphabet, it will be converted to the corresponding upper-case. + // If the resulting string still does not comply with Rule, the category name will not be serialized. + private static int SerializeSanitizedCategoryName(byte[] buffer, int cursor, string categoryName) + { + int cursorStartIdx = cursor; + + // Reserve 2 bytes for storing LIMIT_MAX_STR8_LENGTH_IN_BYTES and (byte)validNameLength - + // these 2 bytes will be back filled after iterating through categoryName. + cursor += 2; + int validNameLength = 0; + + // Special treatment for the first character. + var firstChar = categoryName[0]; + if (firstChar >= 'A' && firstChar <= 'Z') + { + buffer[cursor++] = (byte)firstChar; + ++validNameLength; + } + else if (firstChar >= 'a' && firstChar <= 'z') + { + // If the first character in the resulting string is a lower-case alphabet, + // it will be converted to the corresponding upper-case. + buffer[cursor++] = (byte)(firstChar - 32); + ++validNameLength; + } + else + { + // Not a valid name. + return cursor -= 2; + } + + for (int i = 1; i < categoryName.Length; ++i) + { + if (validNameLength == MaxSanitizedEventNameLength) + { + break; + } + + var cur = categoryName[i]; + if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) + { + buffer[cursor++] = (byte)cur; + ++validNameLength; + } + } + + // Backfilling MessagePack serialization protocol and valid category length to the startIdx of the categoryName byte array. + MessagePackSerializer.WriteStr8Header(buffer, cursorStartIdx, validNameLength); + + return cursor; + } } #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs index 396ae9d582..331ad0e36d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs @@ -306,6 +306,13 @@ private static unsafe long Float64ToInt64(double value) return *(long*)&value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteStr8Header(byte[] buffer, int nameStartIdx, int validNameLength) + { + buffer[nameStartIdx] = STR8; + buffer[nameStartIdx + 1] = unchecked((byte)validNameLength); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeAsciiString(byte[] buffer, int cursor, string value) { @@ -571,4 +578,14 @@ public static int Serialize(byte[] buffer, int cursor, object obj) return SerializeUnicodeString(buffer, cursor, repr); } } + + public static int SerializeSpan(byte[] buffer, int cursor, Span value) + { + for (int i = 0; i < value.Length; ++i) + { + buffer[cursor++] = value[i]; + } + + return cursor; + } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 276320ec9c..7edab1856f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -228,6 +228,101 @@ public void TableNameMappingTest(params string[] category) } } + [Fact] + [Trait("Platform", "Any")] + public void PassThruTableMappingsWhenTheRuleIsEnabled() + { + var userInitializedCategoryToTableNameMappings = new Dictionary + { + ["Company.Store"] = "Store", + ["Company.Orders"] = "Orders", + ["*"] = "*", + }; + + var expectedCategoryToTableNameList = new List> + { + // The category name must match "^[A-Z][a-zA-Z0-9]*$"; any character that is not allowed will be removed. + new KeyValuePair("Company.Customer", "CompanyCustomer"), + + new KeyValuePair("Company-%-Customer*Region$##", "CompanyCustomerRegion"), + + // If the first character in the resulting string is lower-case ALPHA, + // it will be converted to the corresponding upper-case. + new KeyValuePair("company.Calendar", "CompanyCalendar"), + + // After removing not allowed characters, + // if the resulting string is still an illegal event name, the data will get dropped on the floor. + new KeyValuePair("$&-.$~!!", null), + + new KeyValuePair("dlmwl3bvd84bxsx8wf700nx9rydrrhfewbxf82ceoo0h8rpla4", "Dlmwl3bvd84bxsx8wf700nx9rydrrhfewbxf82ceoo0h8rpla4"), + + // If the resulting string is longer than 50 characters, only the first 50 characters will be taken. + new KeyValuePair("Company.Customer.rsLiheLClHJasBOvM.XI4uW7iop6ghvwBzahfs", "CompanyCustomerrsLiheLClHJasBOvMXI4uW7iop6ghvwBzah"), + + // The data will be dropped on the floor as the exporter cannot deduce a valid table name. + new KeyValuePair("1.2", null), + }; + + var logRecordList = new List(); + var exporterOptions = new GenevaExporterOptions + { + TableNameMappings = userInitializedCategoryToTableNameMappings, + ConnectionString = "EtwSession=OpenTelemetry", + }; + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; + ThreadLocal m_buffer; + object fluentdData; + string actualTableName; + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + + // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. + foreach (var mapping in userInitializedCategoryToTableNameMappings) + { + if (mapping.Key != "*") + { + userInitializedTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); + userInitializedTableMappingsLogger.LogInformation("This information does not matter."); + Assert.Single(logRecordList); + + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + userInitializedCategoryToTableNameMappings.TryGetValue(mapping.Key, out var expectedTableNme); + Assert.Equal(expectedTableNme, actualTableName); + + logRecordList.Clear(); + } + } + + // Verify that when the "*" = "*" were enabled, the correct table names were being deduced following the set of rules. + foreach (var mapping in expectedCategoryToTableNameList) + { + passThruTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); + passThruTableMappingsLogger.LogInformation("This information does not matter."); + Assert.Single(logRecordList); + + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + string expectedTableName = string.Empty; + expectedTableName = mapping.Value; + Assert.Equal(expectedTableName, actualTableName); + + logRecordList.Clear(); + } + } + [Theory] [InlineData(true)] [InlineData(false)] From aaa9144fd61c11b16957e84516bd9d189bd0f072 Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Tue, 24 May 2022 17:22:38 -0500 Subject: [PATCH 0133/1499] Add MaxDbStatementLength option with default of 4096 (#370) --- .../CHANGELOG.md | 2 ++ ...lasticsearchClientInstrumentationOptions.cs | 5 +++++ ...csearchRequestPipelineDiagnosticListener.cs | 18 ++++++++---------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 3b86172fdc..2204bacfb7 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -5,6 +5,8 @@ * Updated OTel SDK package version to 1.2.0 * Update minimum full framework support to net462 * Requests that get an HTTP status code of 404 are not marked as an error span status +* Add MaxDbStatementLength option with default of 4096 +* Remove duplicated HTTP method and URL from db.statement attribute value ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index 406cee6131..e3d4abcac8 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -40,6 +40,11 @@ public class ElasticsearchClientInstrumentationOptions /// public bool SetDbStatementForRequest { get; set; } = true; + /// + /// Gets or sets a max length allowed for the db.statement attribute. Default value: 4096. + /// + public int MaxDbStatementLength { get; set; } = 4096; + /// /// Gets or sets an action to enrich an Activity. /// diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 2d1bf5dc27..4b055356bc 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -144,7 +144,13 @@ public override void OnStopActivity(Activity activity, object payload) var debugInformation = this.debugInformationFetcher.Fetch(payload); if (debugInformation != null && this.options.SetDbStatementForRequest) { - activity.SetTag(SemanticConventions.AttributeDbStatement, this.ParseAndFormatRequest(activity, debugInformation)); + var dbStatement = this.ParseAndFormatRequest(activity, debugInformation); + if (dbStatement.Length > this.options.MaxDbStatementLength) + { + dbStatement = dbStatement.Substring(0, 4096); + } + + activity.SetTag(SemanticConventions.AttributeDbStatement, dbStatement); } var originalException = this.originalExceptionFetcher.Fetch(payload); @@ -254,14 +260,6 @@ private string ParseAndFormatRequest(Activity activity, string debugInformation) return debugInformation; } - string method = activity.GetTagValue(AttributeDbMethod).ToString(); - string url = activity.GetTagValue(SemanticConventions.AttributeDbUrl).ToString(); - - if (method == "GET") - { - return $"GET {url}"; - } - var request = ParseRequest.Match(debugInformation); if (request.Success) { @@ -285,7 +283,7 @@ private string ParseAndFormatRequest(Activity activity, string debugInformation) body = Encoding.UTF8.GetString(stream.ToArray()); } - return $"{method} {url}\r\n{body}"; + return body; } return debugInformation; From 482ba4e68cb856349c3d341b62ae6fd280bd785a Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 24 May 2022 15:40:58 -0700 Subject: [PATCH 0134/1499] [Opentelemetry.Extensions.PersistentStorage] Update implementation to use Abstractions (#363) * Use abstractions --- .../CHANGELOG.md | 5 ++ .../FileBlob.cs | 34 ++++---- .../{FileStorage.cs => FileBlobProvider.cs} | 77 +++++++++++------- .../IPersistentBlob.cs | 74 ----------------- .../IPersistentStorage.cs | 65 --------------- ...emetry.Extensions.PersistentStorage.csproj | 4 +- ...orageTests.cs => FileBlobProviderTests.cs} | 68 +++++++++------- .../FileBlobTests.cs | 80 ++++++++++--------- ....Extensions.PersistentStorage.Tests.csproj | 4 +- 9 files changed, 159 insertions(+), 252 deletions(-) rename src/OpenTelemetry.Extensions.PersistentStorage/{FileStorage.cs => FileBlobProvider.cs} (79%) delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs rename test/OpenTelemetry.Extensions.PersistentStorage.Tests/{FileStorageTests.cs => FileBlobProviderTests.cs} (66%) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md index 2ee6ef09c9..9bc42576c0 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog - OpenTelemetry.Extensions.PersistentStorage +## Unreleased + +* [Update implementation to use + Opentelemetry.Extensions.PersistentStorage.Abstractions](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/363) + ## 1.0.0-alpha.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs index 109788a412..37ba893702 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs @@ -15,7 +15,9 @@ // using System; +using System.Diagnostics.CodeAnalysis; using System.IO; +using OpenTelemetry.Extensions.PersistentStorage.Abstractions; namespace OpenTelemetry.Extensions.PersistentStorage { @@ -23,7 +25,7 @@ namespace OpenTelemetry.Extensions.PersistentStorage /// The allows to save a blob /// in file storage. /// - public class FileBlob : IPersistentBlob + public class FileBlob : PersistentBlob { /// /// Initializes a new instance of the @@ -37,23 +39,23 @@ public FileBlob(string fullPath) public string FullPath { get; private set; } - /// - public byte[] Read() + protected override bool OnTryRead([NotNullWhen(true)] out byte[] buffer) { try { - return File.ReadAllBytes(this.FullPath); + buffer = File.ReadAllBytes(this.FullPath); } catch (Exception ex) { PersistentStorageEventSource.Log.Warning($"Reading a blob from file {this.FullPath} has failed.", ex); + buffer = null; + return false; } - return null; + return true; } - /// - public IPersistentBlob Write(byte[] buffer, int leasePeriodMilliseconds = 0) + protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) { string path = this.FullPath + ".tmp"; @@ -72,14 +74,13 @@ public IPersistentBlob Write(byte[] buffer, int leasePeriodMilliseconds = 0) catch (Exception ex) { PersistentStorageEventSource.Log.Warning($"Writing a blob to file {path} has failed.", ex); - return null; + return false; } - return this; + return true; } - /// - public IPersistentBlob Lease(int leasePeriodMilliseconds) + protected override bool OnTryLease(int leasePeriodMilliseconds) { var path = this.FullPath; var leaseTimestamp = DateTime.UtcNow + TimeSpan.FromMilliseconds(leasePeriodMilliseconds); @@ -97,15 +98,15 @@ public IPersistentBlob Lease(int leasePeriodMilliseconds) catch (Exception ex) { PersistentStorageEventSource.Log.Warning($"Acquiring a lease to file {this.FullPath} has failed.", ex); - return null; + return false; } this.FullPath = path; - return this; + + return true; } - /// - public void Delete() + protected override bool OnTryDelete() { try { @@ -114,7 +115,10 @@ public void Delete() catch (Exception ex) { PersistentStorageEventSource.Log.Warning($"Deletion of file blob {this.FullPath} has failed.", ex); + return false; } + + return true; } } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs similarity index 79% rename from src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs rename to src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs index f8a04d2beb..cb75baf48b 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileStorage.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,18 +16,20 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Timers; +using OpenTelemetry.Extensions.PersistentStorage.Abstractions; using OpenTelemetry.Internal; namespace OpenTelemetry.Extensions.PersistentStorage { /// - /// Persistent file storage allows to save data + /// Persistent file storage allows to save data /// as blobs in file storage. /// - public class FileStorage : IPersistentStorage, IDisposable + public class FileBlobProvider : PersistentBlobProvider, IDisposable { private readonly string directoryPath; private readonly long maxSizeInBytes; @@ -37,7 +39,7 @@ public class FileStorage : IPersistentStorage, IDisposable private bool disposedValue; /// - /// Initializes a new instance of the + /// Initializes a new instance of the /// class. /// /// @@ -60,7 +62,7 @@ public class FileStorage : IPersistentStorage, IDisposable /// Controls the timeout when writing a buffer to blob. /// Default is 1 minute. /// - public FileStorage( + public FileBlobProvider( string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, @@ -100,8 +102,7 @@ public void Dispose(bool disposing) } } - /// - public IEnumerable GetBlobs() + protected override IEnumerable OnGetBlobs() { var retentionDeadline = DateTime.UtcNow - TimeSpan.FromMilliseconds(this.retentionPeriodInMilliseconds); @@ -115,31 +116,25 @@ public IEnumerable GetBlobs() } } - /// - public IPersistentBlob GetBlob() + protected override bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob blob) { - return this.GetBlobs().FirstOrDefault(); + blob = this.CreateFileBlob(buffer, leasePeriodMilliseconds); + + return blob != null; } - /// - public IPersistentBlob CreateBlob(byte[] buffer, int leasePeriodMilliseconds = 0) + protected override bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob blob) { - if (!this.CheckStorageSize()) - { - return null; - } + blob = this.CreateFileBlob(buffer); - try - { - var blobFilePath = Path.Combine(this.directoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); - var blob = new FileBlob(blobFilePath); - return blob.Write(buffer, leasePeriodMilliseconds); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.Warning("CreateBlob has failed.", ex); - return null; - } + return blob != null; + } + + protected override bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob blob) + { + blob = this.OnGetBlobs().FirstOrDefault(); + + return blob != null; } private void OnMaintenanceEvent(object source, ElapsedEventArgs e) @@ -173,5 +168,33 @@ private bool CheckStorageSize() return true; } + + private PersistentBlob CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) + { + if (!this.CheckStorageSize()) + { + return null; + } + + try + { + var blobFilePath = Path.Combine(this.directoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); + var blob = new FileBlob(blobFilePath); + + if (blob.TryWrite(buffer, leasePeriodMilliseconds)) + { + return blob; + } + else + { + return null; + } + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.Warning("CreateBlob has failed.", ex); + return null; + } + } } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs deleted file mode 100644 index 7099d36bb0..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentBlob.cs +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Extensions.PersistentStorage -{ - /// - /// Represents a persistent blob. - /// - public interface IPersistentBlob - { - /// - /// Reads the content from the blob. - /// - /// - /// The content of the blob if the operation succeeded, otherwise null. - /// - /// - /// This function should never throw exception. - /// - byte[] Read(); - - /// - /// Writes the given content to the blob. - /// - /// - /// The content to be written. - /// - /// - /// The number of milliseconds to lease after the write operation finished. - /// - /// - /// The same blob if the operation succeeded, otherwise null. - /// - /// - /// This function should never throw exception. - /// - IPersistentBlob Write(byte[] buffer, int leasePeriodMilliseconds = 0); - - /// - /// Creates a lease on the blob. - /// - /// - /// The number of milliseconds to lease. - /// - /// - /// The same blob if the lease operation succeeded, otherwise null. - /// - /// - /// This function should never throw exception. - /// - IPersistentBlob Lease(int leasePeriodMilliseconds); - - /// - /// Attempts to delete the blob. - /// - /// - /// This function should never throw exception. - /// - void Delete(); - } -} diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs b/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs deleted file mode 100644 index 3328bfdbda..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage/IPersistentStorage.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; - -namespace OpenTelemetry.Extensions.PersistentStorage -{ - /// - /// Persistent storage API. - /// - public interface IPersistentStorage - { - /// - /// Reads a sequence of blobs from storage. - /// - /// - /// Sequence of blobs from storage. - /// - /// - /// This function should never throw exception. - /// - IEnumerable GetBlobs(); - - /// - /// Attempts to get a blob from storage. - /// - /// - /// A blob if there is an available one, or null if there is no blob available. - /// - /// - /// This function should never throw exception. - /// - IPersistentBlob GetBlob(); - - /// - /// Creates a new blob with the provided data. - /// - /// - /// The content to be written. - /// - /// - /// The number of milliseconds to lease after the blob is created. - /// - /// - /// The created blob. - /// - /// - /// This function should never throw exception. - /// - IPersistentBlob CreateBlob(byte[] buffer, int leasePeriodMilliseconds = 0); - } -} diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj index 82bcf03ccd..1e8444f62d 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net461 + netstandard2.0;net462 OpenTelemetry Persistent Storage Extensions.PersistentStorage- @@ -12,6 +12,8 @@ + + diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileStorageTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs similarity index 66% rename from test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileStorageTests.cs rename to test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs index b8fa77eadd..d2dab800ad 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileStorageTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,70 +16,71 @@ using System; using System.IO; -using System.Linq; using System.Text; using System.Threading; using Xunit; namespace OpenTelemetry.Extensions.PersistentStorage.Tests { - public class FileStorageTests + public class FileBlobProviderTests { [Fact] - public void FileStorage_E2E_Test() + public void FileBlobProvider_E2E_Test() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - using var storage = new FileStorage(testDirectory.FullName); + using var blobProvider = new FileBlobProvider(testDirectory.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); // Create blob. - IPersistentBlob blob1 = storage.CreateBlob(data); + Assert.True(blobProvider.TryCreateBlob(data, out var blob1)); // Get blob. - IPersistentBlob blob2 = storage.GetBlob(); + Assert.True(blobProvider.TryGetBlob(out var blob2)); - Assert.Single(storage.GetBlobs()); + Assert.Single(blobProvider.GetBlobs()); // Verify file name from both create blob and get blob are same. Assert.Equal(((FileBlob)blob1).FullPath, ((FileBlob)blob2).FullPath); // Validate if content in the blob is same as buffer data passed to create blob. - Assert.Equal(data, blob1.Read()); + Assert.True(blob1.TryRead(out var blobContent)); + Assert.Equal(data, blobContent); testDirectory.Delete(true); } [Fact] - public void FileStorage_CreateBlobReturnsNullIfStorageIsFull() + public void FileBlobProvider_CreateBlobReturnsNullIfblobProviderIsFull() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - using var storage = new FileStorage(testDirectory.FullName, 10000); + using var blobProvider = new FileBlobProvider(testDirectory.FullName, 10000); PersistentStorageHelper.UpdateDirectorySize(10000); var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.Null(storage.CreateBlob(data)); + Assert.False(blobProvider.TryCreateBlob(data, out var blob)); + Assert.Null(blob); testDirectory.Delete(true); } [Fact] - public void FileStorage_PathIsRequired() + public void FileBlobProvider_PathIsRequired() { - Assert.Throws(() => new FileStorage(null)); + Assert.Throws(() => new FileBlobProvider(null)); } [Fact] - public void FileStorage_TestRetentionPeriod() + public void FileBlobProvider_TestRetentionPeriod() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; int maintenancePeriodInMilliseconds = 3000; int retentionPeriodInMilliseconds = 2000; int writeTimeOutInMilliseconds = 1000; - using var storage = new FileStorage( + using var blobProvider = new FileBlobProvider( testDirectory.FullName, maxSizeInBytes, maintenancePeriodInMilliseconds, @@ -87,26 +88,27 @@ public void FileStorage_TestRetentionPeriod() writeTimeOutInMilliseconds); var data = Encoding.UTF8.GetBytes("Hello, World!"); - var blob1 = (FileBlob)storage.CreateBlob(data); + Assert.True(blobProvider.TryCreateBlob(data, out var blob)); // Wait for maintenance job to run + // TODO: reduce/eliminate sleep time Thread.Sleep(4000); // Blob will be deleted as retention period is 1 sec - Assert.False(File.Exists(blob1.FullPath)); + Assert.False(File.Exists(((FileBlob)blob).FullPath)); testDirectory.Delete(true); } [Fact] - public void FileStorage_TestWriteTimeoutPeriod() + public void FileBlobProvider_TestWriteTimeoutPeriod() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; int maintenancePeriodInMilliseconds = 3000; int retentionPeriodInMilliseconds = 2000; int writeTimeOutInMilliseconds = 1000; - using var storage = new FileStorage( + using var blobProvider = new FileBlobProvider( testDirectory.FullName, maxSizeInBytes, maintenancePeriodInMilliseconds, @@ -114,33 +116,35 @@ public void FileStorage_TestWriteTimeoutPeriod() writeTimeOutInMilliseconds); var data = Encoding.UTF8.GetBytes("Hello, World!"); - var blob2 = (FileBlob)storage.CreateBlob(data); + + Assert.True(blobProvider.TryCreateBlob(data, out var blob)); // Mock write - File.Move(blob2.FullPath, blob2.FullPath + ".tmp"); + File.Move(((FileBlob)blob).FullPath, ((FileBlob)blob).FullPath + ".tmp"); // validate file moved successfully - Assert.True(File.Exists(blob2.FullPath + ".tmp")); + Assert.True(File.Exists(((FileBlob)blob).FullPath + ".tmp")); // Wait for maintenance job to run + // TODO: reduce/eliminate sleep time Thread.Sleep(4000); // tmp file will be deleted as write timeout period is 1 sec - Assert.False(File.Exists(blob2.FullPath + ".tmp")); - Assert.False(File.Exists(blob2.FullPath)); + Assert.False(File.Exists(((FileBlob)blob).FullPath + ".tmp")); + Assert.False(File.Exists(((FileBlob)blob).FullPath)); testDirectory.Delete(true); } [Fact] - public void FileStorageTests_TestLeaseExpiration() + public void FileBlobProviderTests_TestLeaseExpiration() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; int maintenancePeriodInMilliseconds = 3000; int retentionPeriodInMilliseconds = 2000; int writeTimeOutInMilliseconds = 1000; - using var storage = new FileStorage( + using var blobProvider = new FileBlobProvider( testDirectory.FullName, maxSizeInBytes, maintenancePeriodInMilliseconds, @@ -148,14 +152,16 @@ public void FileStorageTests_TestLeaseExpiration() writeTimeOutInMilliseconds); var data = Encoding.UTF8.GetBytes("Hello, World!"); - var blob = (FileBlob)storage.CreateBlob(data); - var blobPath = blob.FullPath; - blob.Lease(1000); - var leasePath = blob.FullPath; + Assert.True(blobProvider.TryCreateBlob(data, out var blob)); + var blobPath = ((FileBlob)blob).FullPath; + + blob.TryLease(1000); + var leasePath = ((FileBlob)blob).FullPath; Assert.True(File.Exists(leasePath)); // Wait for maintenance job to run + // TODO: reduce/eliminate sleep time Thread.Sleep(4000); // File name will be change to .blob diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs index bf9ee5c1bb..4ca0c48337 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs @@ -14,10 +14,10 @@ // limitations under the License. // -using System; using System.IO; using System.Text; using System.Threading; +using OpenTelemetry.Extensions.PersistentStorage.Abstractions; using Xunit; namespace OpenTelemetry.Extensions.PersistentStorage.Tests @@ -28,16 +28,16 @@ public class FileBlobTests public void FileBlobTests_E2E_Test() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - IPersistentBlob blob = new FileBlob(testFile.FullName); + PersistentBlob blob = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); - IPersistentBlob blob1 = blob.Write(data); - var blobContent = blob.Read(); + blob.TryWrite(data); + blob.TryRead(out var blobContent); - Assert.Equal(testFile.FullName, ((FileBlob)blob1).FullPath); + Assert.Equal(testFile.FullName, ((FileBlob)blob).FullPath); Assert.Equal(data, blobContent); - blob1.Delete(); + Assert.True(blob.TryDelete()); Assert.False(testFile.Exists); } @@ -45,16 +45,16 @@ public void FileBlobTests_E2E_Test() public void FileBlobTests_Lease() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - IPersistentBlob blob = new FileBlob(testFile.FullName); + PersistentBlob blob = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); var leasePeriodMilliseconds = 1000; - IPersistentBlob blob1 = blob.Write(data); - IPersistentBlob leasedBlob = blob1.Lease(leasePeriodMilliseconds); + blob.TryWrite(data); + blob.TryLease(leasePeriodMilliseconds); - Assert.Contains(".lock", ((FileBlob)leasedBlob).FullPath); + Assert.Contains(".lock", ((FileBlob)blob).FullPath); - blob1.Delete(); + Assert.True(blob.TryDelete()); Assert.False(testFile.Exists); } @@ -62,14 +62,15 @@ public void FileBlobTests_Lease() public void FileBlobTests_LeaseAfterDelete() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - IPersistentBlob blob = new FileBlob(testFile.FullName); + PersistentBlob blob = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); - blob.Write(data); - blob.Delete(); - // Lease should return null - Assert.Null(blob.Lease(1000)); + Assert.True(blob.TryWrite(data)); + Assert.True(blob.TryDelete()); + + // Lease should return false + Assert.False(blob.TryLease(1000)); } [Fact] @@ -79,17 +80,18 @@ public void FileBlobTests_ReadFailsOnAlreadyLeasedFile() FileBlob blob1 = new FileBlob(testFile.FullName); FileBlob blob2 = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); - blob1.Write(data); - var leasePeriodMilliseconds = 10000; + + Assert.True(blob2.TryWrite(data)); // Leased by another thread/process/object - blob2.Lease(leasePeriodMilliseconds); + Assert.True(blob2.TryLease(10000)); // Read should fail as file is leased - Assert.Null(blob1.Read()); + Assert.False(blob1.TryRead(out var blob)); + Assert.Null(blob); // Clean up - blob2.Delete(); + Assert.True(blob2.TryDelete()); } [Fact] @@ -99,17 +101,17 @@ public void FileBlobTests_LeaseFailsOnAlreadyLeasedFileByOtherObject() FileBlob blob1 = new FileBlob(testFile.FullName); FileBlob blob2 = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); - blob1.Write(data); - var leasePeriodMilliseconds = 10000; + + Assert.True(blob1.TryWrite(data)); // Leased by another thread/process/object - blob2.Lease(leasePeriodMilliseconds); + Assert.True(blob2.TryLease(10000)); // Lease should fail as already leased - Assert.Null(blob1.Lease(10)); + Assert.False(blob1.TryLease(10)); // Clean up - blob2.Delete(); + Assert.True(blob2.TryDelete()); } [Fact] @@ -118,9 +120,12 @@ public void FileBlobTests_Delete() var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); FileBlob blob = new FileBlob(testFile.FullName); - blob.Delete(); + var data = Encoding.UTF8.GetBytes("Hello, World!"); + + Assert.True(blob.TryWrite(data)); // Assert + Assert.True(blob.TryDelete()); Assert.False(testFile.Exists); } @@ -130,24 +135,25 @@ public void FileBlobTests_DeleteFailsAfterLeaseIsExpired() var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); // set maintenance job interval to 2 secs - using var storage = new FileStorage(testDirectory.FullName, 10, 2); + using var storage = new FileBlobProvider(testDirectory.FullName, 10, 2); var data = Encoding.UTF8.GetBytes("Hello, World!"); - var blob = storage.CreateBlob(data); + Assert.True(storage.TryCreateBlob(data, out var blob)); var leasePeriodMilliseconds = 1; // lease for 1 ms - blob.Lease(leasePeriodMilliseconds); + blob.TryLease(leasePeriodMilliseconds); // Wait for lease to expire and maintenance job to run Thread.Sleep(5000); - blob.Delete(); + blob.TryDelete(); // Assert - Assert.NotNull(storage.GetBlob()); + Assert.True(storage.TryGetBlob(out var outputBlob)); + Assert.NotNull(outputBlob); testDirectory.Delete(true); } @@ -159,20 +165,20 @@ public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() FileBlob blob = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); - blob.Write(data); + Assert.True(blob.TryWrite(data)); var leasePeriodMilliseconds = 10000; - blob.Lease(leasePeriodMilliseconds); + Assert.True(blob.TryLease(leasePeriodMilliseconds)); var leaseTime = PersistentStorageHelper.GetDateTimeFromLeaseName(blob.FullPath); - Assert.NotNull(blob.Lease(10000)); + Assert.True(blob.TryLease(leasePeriodMilliseconds)); var newLeaseTime = PersistentStorageHelper.GetDateTimeFromLeaseName(blob.FullPath); Assert.NotEqual(leaseTime, newLeaseTime); - blob.Delete(); + Assert.True(blob.TryDelete()); } [Fact] @@ -181,7 +187,7 @@ public void FileBlobTests_FailedWrite() var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); FileBlob blob = new FileBlob(testFile.FullName); - Assert.Null(blob.Write(null)); + Assert.False(blob.TryWrite(null)); } } } diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj index a36fa8e080..d1a4d1abc1 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj @@ -1,8 +1,8 @@  - netcoreapp3.1;net5.0 - $(TargetFrameworks);net461 + netcoreapp3.1;net6.0 + $(TargetFrameworks);net462 false From 6bd6c221c4d37a78faf6aca27a8c372d26913334 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 24 May 2022 15:51:13 -0700 Subject: [PATCH 0135/1499] Mark MultiTypePropertyFetcher as internal (#373) --- .../MultiTypePropertyFetcher.cs | 2 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 --- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs index e88f28052c..e360055f57 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Instrumentation /// PropertyFetcher fetches a property from an object. /// /// The type of the property being fetched. - public class MultiTypePropertyFetcher + internal class MultiTypePropertyFetcher { private readonly string propertyName; private readonly ConcurrentDictionary innerFetcher = new ConcurrentDictionary(); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt index a1a71d36cb..ebca0c81e0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,6 +1,3 @@ -OpenTelemetry.Instrumentation.MultiTypePropertyFetcher -OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.Fetch(object obj) -> T -OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.MultiTypePropertyFetcher(string propertyName) -> void OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index a1a71d36cb..ebca0c81e0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,3 @@ -OpenTelemetry.Instrumentation.MultiTypePropertyFetcher -OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.Fetch(object obj) -> T -OpenTelemetry.Instrumentation.MultiTypePropertyFetcher.MultiTypePropertyFetcher(string propertyName) -> void OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void From 97642012d4744d7bab2b28850f02490d827a58dc Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 24 May 2022 16:24:07 -0700 Subject: [PATCH 0136/1499] Add public API anaylzer for ElasticSearch (#374) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 14 ++++++++++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 14 ++++++++++++++ ...etry.Instrumentation.ElasticsearchClient.csproj | 1 + 5 files changed, 29 insertions(+) create mode 100644 src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..079ec48823 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,14 @@ +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ElasticsearchClientInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.get -> int +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ParseAndFormatRequest.get -> bool +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ParseAndFormatRequest.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SetDbStatementForRequest.get -> bool +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SetDbStatementForRequest.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..079ec48823 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,14 @@ +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ElasticsearchClientInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.get -> int +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ParseAndFormatRequest.get -> bool +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ParseAndFormatRequest.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SetDbStatementForRequest.get -> bool +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SetDbStatementForRequest.set -> void +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 9d8f512ec9..a9b531ca62 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -5,6 +5,7 @@ $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- true + true From dcf0156af8697c0f4d95e4fdae8d3b4b778e4810 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 25 May 2022 18:48:35 -0700 Subject: [PATCH 0137/1499] Update sanity check and .editorconfig (#378) --- .editorconfig | 271 ++--- build/sanitycheck.py | 48 +- examples/Directory.Build.targets | 2 +- .../Controllers/WeatherForecastController.cs | 114 +-- .../EchoService.cs | 66 +- .../Examples.GrpcCore.AspNetCore.csproj | 46 +- .../Examples.GrpcCore.AspNetCore/Program.cs | 80 +- .../Examples.GrpcCore.AspNetCore/Startup.cs | 234 ++--- .../WeatherForecast.cs | 62 +- .../appsettings.json | 20 +- .../proto/echo.proto | 28 +- examples/grpc.core/README.md | 34 +- examples/owin/Controllers/TestController.cs | 2 +- examples/owin/Program.cs | 2 +- examples/wcf/client-core/Program.cs | 2 +- .../wcf/client-core/StatusServiceClient.cs | 2 +- examples/wcf/client-netframework/Program.cs | 2 +- .../StatusServiceClient.cs | 2 +- examples/wcf/server-netframework/Program.cs | 2 +- .../wcf/server-netframework/StatusService.cs | 2 +- examples/wcf/shared/IStatusServiceContract.cs | 2 +- examples/wcf/shared/StatusRequest.cs | 2 +- examples/wcf/shared/StatusResponse.cs | 2 +- opentelemetry-dotnet-contrib.sln | 948 +++++++++--------- src/Directory.Build.targets | 2 +- .../AWSXRayEventSource.cs | 2 +- .../AWSXRayIdGenerator.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 54 +- .../Resources/AWSEBSResourceDetector.cs | 2 +- .../Resources/AWSEC2ResourceDetector.cs | 2 +- .../Resources/AWSECSResourceDetector.cs | 2 +- .../Resources/AWSEKSResourceDetector.cs | 2 +- .../Resources/AWSLambdaResourceDetector.cs | 2 +- .../Resources/AWSSemanticConventions.cs | 2 +- .../Resources/Http/Handler.cs | 2 +- .../ServerCertificateValidationProvider.cs | 2 +- .../Resources/IResourceDetector.cs | 2 +- .../Resources/Models/AWSEBSMetadataModel.cs | 2 +- .../Models/AWSEC2IdentityDocumentModel.cs | 2 +- .../Models/AWSEKSClusterDataModel.cs | 2 +- .../Models/AWSEKSClusterInformationModel.cs | 2 +- .../Resources/ResourceBuilderExtensions.cs | 2 +- .../Resources/ResourceDetectorUtils.cs | 2 +- .../Trace/AWSXRayPropagator.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AWSClientInstrumentationOptions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../AWSClientsInstrumentation.cs | 2 +- .../Implementation/AWSSemanticConventions.cs | 2 +- .../AWSTracingPipelineCustomizer.cs | 2 +- .../AWSTracingPipelineHandler.cs | 2 +- .../Implementation/Utils.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../AWSLambdaResourceDetector.cs | 2 +- .../AWSLambdaSemanticConventions.cs | 2 +- .../Implementation/AWSLambdaUtils.cs | 2 +- .../Implementation/AWSLambdaWrapper.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../Api/ActivityHelperExtensions.cs | 2 +- .../Api/ExceptionExtensions.cs | 2 +- .../Api/IActivityEnumerator.cs | 2 +- .../Api/SemanticConventions.cs | 2 +- .../Api/SpanAttributeConstants.cs | 2 +- .../Api/SpanHelper.cs | 2 +- .../Api/StatusHelper.cs | 2 +- .../ActivityInstrumentationHelper.cs | 2 +- .../DiagnosticSourceListener.cs | 2 +- .../DiagnosticSourceSubscriber.cs | 2 +- .../InstrumentationEventSource.cs | 2 +- .../ListenerHandler.cs | 2 +- .../MultiTypePropertyFetcher.cs | 2 +- .../PropertyFetcher.cs | 2 +- .../ServiceProviderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../ConnectionStringBuilder.cs | 2 +- .../EtwDataTransport.cs | 2 +- .../ExporterEventSource.cs | 2 +- .../GenevaBaseExporter.cs | 2 +- .../GenevaExporterHelperExtensions.cs | 2 +- .../GenevaExporterOptions.cs | 2 +- .../GenevaLogExporter.cs | 2 +- .../GenevaLoggingExtensions.cs | 2 +- .../GenevaMetricExporter.cs | 2 +- .../GenevaMetricExporterExtensions.cs | 2 +- .../GenevaMetricExporterOptions.cs | 2 +- .../GenevaTraceExporter.cs | 2 +- .../IDataTransport.cs | 2 +- .../IMetricDataTransport.cs | 2 +- .../MessagePackSerializer.cs | 2 +- .../MetricEtwDataTransport.cs | 2 +- .../MetricSerializer.cs | 2 +- .../MetricUnixDataTransport.cs | 2 +- .../ReentrantActivityExportProcessor.cs | 2 +- .../ReentrantExportProcessor.cs | 2 +- src/OpenTelemetry.Exporter.Geneva/Schema.cs | 2 +- .../ServiceProviderExtensions.cs | 2 +- .../UnixDomainSocketDataTransport.cs | 2 +- .../UnixDomainSocketEndPoint.cs | 2 +- .../IInstanaExporterHelper.cs | 2 +- .../Implementation/ISpanSender.cs | 2 +- .../Implementation/InstanaSpan.cs | 2 +- .../Implementation/InstanaSpanFactory.cs | 2 +- .../Implementation/InstanaSpanSerializer.cs | 2 +- .../InstanaSpanTransformInfo.cs | 2 +- .../Processors/ActivityProcessorBase.cs | 2 +- .../Processors/DefaultActivityProcessor.cs | 2 +- .../Processors/ErrorActivityProcessor.cs | 2 +- .../Processors/EventsActivityProcessor.cs | 2 +- .../Processors/IActivityProcessor.cs | 2 +- .../Processors/TagsActivityProcessor.cs | 2 +- .../Implementation/SpanSender.cs | 2 +- .../Implementation/Transport.cs | 2 +- .../InstanaExporter.cs | 2 +- .../InstanaExporterConstants.cs | 2 +- .../InstanaExporterHelper.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../Implementation/ActivityExtensions.cs | 2 +- .../Implementation/Constants.cs | 2 +- .../ExporterStackdriverEventSource.cs | 2 +- .../GoogleCloudResourceUtils.cs | 2 +- .../StackdriverStatsConfiguration.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../StackdriverTraceExporter.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../Utils/CommonUtils.cs | 2 +- .../ApplicationInsightsSampler.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../NotNullWhenAttribute.cs | 2 +- .../PersistentBlob.cs | 2 +- .../PersistentBlobProvider.cs | 2 +- ...ersistentStorageAbstractionsEventSource.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../FileBlob.cs | 2 +- .../FileBlobProvider.cs | 2 +- .../PersistentStorageEventSource.cs | 2 +- .../PersistentStorageHelper.cs | 2 +- src/OpenTelemetry.Extensions/AssemblyInfo.cs | 2 +- .../ActivityEventAttachingLogProcessor.cs | 2 +- .../Internal/DefaultLogStateConverter.cs | 2 +- .../OpenTelemetryExtensionsEventSource.cs | 2 +- .../LogToActivityEventConversionOptions.cs | 2 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 2 +- .../Trace/AutoFlushActivityProcessor.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../ElasticsearchClientInstrumentation.cs | 2 +- ...asticsearchClientInstrumentationOptions.cs | 2 +- ...ElasticsearchInstrumentationEventSource.cs | 2 +- ...searchRequestPipelineDiagnosticListener.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../EntityFrameworkInstrumentation.cs | 2 +- .../EntityFrameworkInstrumentationOptions.cs | 2 +- .../EntityFrameworkDiagnosticListener.cs | 2 +- ...tityFrameworkInstrumentationEventSource.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../AsyncStreamReaderProxy.cs | 2 +- .../ClientStreamWriterProxy.cs | 2 +- .../ClientTracingInterceptor.cs | 2 +- .../ClientTracingInterceptorOptions.cs | 2 +- .../Extensions.cs | 2 +- .../GrpcCoreInstrumentation.cs | 2 +- .../RpcScope.cs | 2 +- .../SemanticConventions.cs | 2 +- .../ServerStreamWriterProxy.cs | 2 +- .../ServerTracingInterceptor.cs | 2 +- .../ServerTracingInterceptorOptions.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../Implementation/HangfireInstrumentation.cs | 2 +- .../HangfireInstrumentationConstants.cs | 2 +- ...ngfireInstrumentationJobFilterAttribute.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../Implementation/DisplayNameHelper.cs | 2 +- .../MassTransitDiagnosticListener.cs | 2 +- .../MassTransitInstrumentationEventSource.cs | 2 +- .../MassTransitSemanticConventions.cs | 2 +- .../Implementation/TagName.cs | 2 +- .../MassTransitInstrumentation.cs | 2 +- .../MassTransitInstrumentationOptions.cs | 2 +- .../OperationName.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../MySqlActivitySourceHelper.cs | 2 +- .../MySqlDataInstrumentation.cs | 2 +- .../MySqlDataInstrumentationEventSource.cs | 2 +- .../MySqlDataInstrumentationOptions.cs | 2 +- .../MySqlDataTraceCommand.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AppBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../Implementation/DiagnosticsMiddleware.cs | 2 +- .../OwinInstrumentationActivitySource.cs | 2 +- .../OwinInstrumentationEventSource.cs | 2 +- .../OwinEnrichEventType.cs | 2 +- .../OwinInstrumentationOptions.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../QuartzDiagnosticListener.cs | 2 +- .../QuartzInstrumentationEventSource.cs | 2 +- .../Implementation/TagName.cs | 2 +- .../OperationName.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../QuartzInstrumentationOptions.cs | 2 +- .../QuartzJobInstrumentation.cs | 2 +- .../README.md | 228 ++--- .../TraceProviderBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../MeterProviderBuilderExtensions.cs | 2 +- .../RuntimeMetrics.cs | 2 +- .../RuntimeMetricsOptions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../RedisProfilerEntryToActivityConverter.cs | 2 +- .../StackExchangeRedisCallsInstrumentation.cs | 2 +- ...xchangeRedisCallsInstrumentationOptions.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../Implementation/ActionMetadata.cs | 2 +- .../WcfInstrumentationActivitySource.cs | 2 +- .../WcfInstrumentationConstants.cs | 2 +- .../WcfInstrumentationEventSource.cs | 2 +- .../TelemetryClientMessageInspector.cs | 2 +- .../TelemetryContractBehaviorAttribute.cs | 2 +- .../TelemetryDispatchMessageInspector.cs | 2 +- .../TelemetryEndpointBehavior.cs | 2 +- ...lemetryEndpointBehaviorExtensionElement.cs | 2 +- .../TelemetryServiceBehavior.cs | 2 +- ...elemetryServiceBehaviorExtensionElement.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../WcfEnrichEventNames.cs | 2 +- .../WcfInstrumentationOptions.cs | 2 +- src/OpenTelemetry.Internal/Guard.cs | 2 +- test/Directory.Build.targets | 2 +- .../Resources/Http/CertificateUploader.cs | 2 +- .../Resources/Http/TestHandler.cs | 2 +- ...TestServerCertificateValidationProvider.cs | 2 +- .../Resources/SampleAWSEBSMetadataModel.cs | 2 +- .../SampleAWSEC2IdentityDocumentModel.cs | 2 +- .../Resources/TestAWSEBSResourceDetector.cs | 2 +- .../Resources/TestAWSEC2ResourceDetector.cs | 2 +- .../Resources/TestAWSECSResourceDetector.cs | 2 +- .../Resources/TestAWSEKSResourceDetector.cs | 2 +- .../TestAWSLambdaResourceDetector.cs | 2 +- .../TestResourceBuilderExtensions.cs | 2 +- .../TestAWSXRayIdGenerator.cs | 2 +- .../Trace/TestAWSXRayPropagator.cs | 2 +- .../TestAWSClientInstrumentation.cs | 2 +- .../Tools/CustomResponses.cs | 2 +- .../Tools/CustomWebResponse.cs | 2 +- .../Tools/HttpResponseMessageBody.cs | 2 +- .../Tools/MockHttpRequest.cs | 2 +- .../Tools/MockHttpRequestFactory.cs | 2 +- .../Tools/MockWebResponse.cs | 2 +- .../Tools/Utils.cs | 2 +- .../AWSLambdaWrapperTests.cs | 2 +- .../SampleHandlers.cs | 2 +- .../SampleLambdaContext.cs | 2 +- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 2 +- .../TestActivityExportProcessor.cs | 2 +- .../TestActivityProcessor.cs | 2 +- .../TestExporter.cs | 2 +- .../TestSampler.cs | 2 +- .../Exporter/LogExporterBenchmarks.cs | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 2 +- .../Exporter/TraceExporterBenchmarks.cs | 2 +- .../Program.cs | 2 +- .../DummyServer.cs | 2 +- .../Program.cs | 2 +- .../ConnectionStringBuilderTests.cs | 2 +- .../GenevaLogExporterTests.cs | 2 +- .../GenevaMetricExporterOptionsTests.cs | 2 +- .../GenevaMetricExporterTests.cs | 2 +- .../GenevaTraceExporterTests.cs | 2 +- .../MessagePackSerializerTests.cs | 2 +- .../UnixDomainSocketDataTransportTests.cs | 2 +- .../UnixDomainSocketEndPointTests.cs | 2 +- .../InstanaExporterTests.cs | 2 +- .../InstanaSpanFactoryTests.cs | 2 +- .../InstanaSpanSerializerTests.cs | 2 +- .../InstanaSpanTest.cs | 2 +- .../DefaultActivityProcessorTests.cs | 2 +- .../Processors/ErrorActivityProcessorTests.cs | 2 +- .../EventsActivityProcessorTests.cs | 2 +- .../Processors/TagsActivityProcessorTests.cs | 2 +- .../StackdriverStatsConfigurationTests.cs | 2 +- .../Shared/TestExporter.cs | 2 +- .../StackdriverExporterTests.cs | 2 +- .../TestActivityProcessor.cs | 2 +- .../ApplicationInsightsSamplerTests.cs | 2 +- .../FileBlobProviderTests.cs | 2 +- .../FileBlobTests.cs | 2 +- ...ActivityEventAttachingLogProcessorTests.cs | 2 +- .../Trace/AutoFlushActivityProcessorTests.cs | 2 +- .../Customer.cs | 2 +- .../ElasticsearchClientTests.cs | 2 +- ...nMemoryConnectionWithDownstreamActivity.cs | 2 +- .../EntityFrameworkDiagnosticListenerTests.cs | 2 +- .../FoobarService.cs | 2 +- .../GrpcCoreClientInterceptorTests.cs | 2 +- .../GrpcCoreServerInterceptorTests.cs | 2 +- .../InterceptorActivityListener.cs | 2 +- .../HangfireFixture.cs | 2 +- ...eInstrumentationJobFilterAttributeTests.cs | 2 +- .../TestJob.cs | 2 +- .../MassTransitInstrumentationTests.cs | 2 +- .../TestConsumer.cs | 2 +- .../TestMessage.cs | 2 +- .../MySqlDataTests.cs | 2 +- .../Controllers/TestController.cs | 2 +- .../DiagnosticsMiddlewareTests.cs | 2 +- .../QuartzDiagnosticListenerTests.cs | 2 +- .../TestJob.cs | 2 +- .../TestJobExecutionExceptionJob.cs | 2 +- .../RuntimeMetricsOptionsTests.cs | 2 +- .../RuntimeMetricsTests.cs | 2 +- ...isProfilerEntryToActivityConverterTests.cs | 2 +- ...kExchangeRedisCallsInstrumentationTests.cs | 2 +- .../TelemetryClientMessageInspectorTests.cs | 2 +- ...InspectorForOneWayOperationsTests.netfx.cs | 2 +- ...etryDispatchMessageInspectorTests.netfx.cs | 2 +- .../Tools/ErrorHandler.netfx.cs | 2 +- .../ErrorHandlerServiceBehavior.netfx.cs | 2 +- .../WCF/IServiceContract.cs | 2 +- .../WCF/Service.netfx.cs | 2 +- .../WCF/ServiceClient.cs | 2 +- .../WCF/ServiceRequest.cs | 2 +- .../WCF/ServiceResponse.cs | 2 +- 330 files changed, 1451 insertions(+), 1414 deletions(-) diff --git a/.editorconfig b/.editorconfig index 4f0400c633..800da16434 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,130 +1,149 @@ # To learn more about .editorconfig see https://aka.ms/editorconfigdocs -############################### -# Core EditorConfig Options # -############################### -# All files -[*] -indent_style = space -# Code files -[*.{cs,csx,vb,vbx}] -indent_size = 4 -insert_final_newline = true -trim_trailing_whitespace = true -charset = utf-8-bom -# maintain DOS/Windows style line endings in md files -[*.md] -end_of_line = crlf -############################### -# .NET Coding Conventions # -############################### -[*.{cs,vb}] -# Organize usings -dotnet_sort_system_directives_first = true -# this. preferences -dotnet_style_qualification_for_field = true:suggestion -dotnet_style_qualification_for_property = true:suggestion -dotnet_style_qualification_for_method = true:suggestion -dotnet_style_qualification_for_event = true:suggestion -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent -# 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 -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent -dotnet_style_readonly_field = true:suggestion -# Expression-level preferences -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent -dotnet_prefer_inferred_tuple_names = true:suggestion -dotnet_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 -############################### -# Naming Conventions # -############################### -# Style Definitions -dotnet_naming_style.pascal_case_style.capitalization = pascal_case -# Use PascalCase for constant fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.applicable_accessibilities = * -dotnet_naming_symbols.constant_fields.required_modifiers = const -############################### -# C# Coding Conventions # -############################### -[*.cs] +############################### +# Core EditorConfig Options # +############################### +# All files +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{cs,cshtml,htm,html,md,py,sln,xml}] +indent_size = 4 + +############################### +# .NET Coding Conventions # +############################### +# Directive order based on dotnet/runtime settings +# https://github.com/dotnet/runtime/blob/main/.editorconfig +[*.cs] +# New line preferences +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = flush_left + +# Modifier preferences +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# this. preferences +dotnet_style_qualification_for_field = true:suggestion +dotnet_style_qualification_for_property = true:suggestion +dotnet_style_qualification_for_method = true:suggestion +dotnet_style_qualification_for_event = true:suggestion + +# var preferences, language keywords vs BCL types preferences +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 + +# name all constant fields using PascalCase +dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_symbols.constant_fields.applicable_kinds = field +dotnet_naming_symbols.constant_fields.required_modifiers = const +dotnet_naming_symbols.constant_fields.applicable_accessibilities = * +dotnet_naming_style.pascal_case_style.capitalization = pascal_case + +# Code style defaults +dotnet_sort_system_directives_first = true +csharp_prefer_braces = true:silent +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true +csharp_prefer_simple_using_statement = true:suggestion +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 + +# Expression-level preferences +dotnet_style_object_initializer = true:suggestion +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_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 +csharp_prefer_simple_default_expression = true:suggestion + +# 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 + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion + +# Null checking preferences +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Other features +csharp_style_prefer_index_operator = false:none +csharp_style_prefer_range_operator = false:none +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_around_binary_operators = before_and_after +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +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 + +# Code analyzers +# CA1031: Do not catch general exception types +dotnet_diagnostic.CA1031.severity = none + +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = none + +# IDE0001: Simplify name +dotnet_diagnostic.IDE0001.severity = warning + +# IDE0002: Simplify member access +dotnet_diagnostic.IDE0002.severity = warning + +# IDE0005: Remove unnecessary import dotnet_diagnostic.IDE0005.severity = warning -# var preferences -csharp_style_var_for_built_in_types = true:silent -csharp_style_var_when_type_is_apparent = true:silent -csharp_style_var_elsewhere = true:silent -# 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 -# Pattern matching preferences -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -# Null-checking preferences -csharp_style_throw_expression = true:suggestion -csharp_style_conditional_delegate_call = true:suggestion -# Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion -# Expression-level preferences -csharp_prefer_braces = true:silent -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_pattern_local_over_anonymous_function = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -############################### -# C# Formatting Rules # -############################### -# New line preferences -csharp_new_line_before_open_brace = all -csharp_new_line_before_else = true -csharp_new_line_before_catch = true -csharp_new_line_before_finally = true -csharp_new_line_before_members_in_object_initializers = true -csharp_new_line_before_members_in_anonymous_types = true -csharp_new_line_between_query_expression_clauses = true -# Indentation preferences -csharp_indent_case_contents = true -csharp_indent_switch_labels = true -csharp_indent_labels = flush_left -# Space preferences -csharp_space_after_cast = false -csharp_space_after_keywords_in_control_flow_statements = true -csharp_space_between_method_call_parameter_list_parentheses = false -csharp_space_between_method_declaration_parameter_list_parentheses = false -csharp_space_between_parentheses = false -csharp_space_before_colon_in_inheritance_clause = true -csharp_space_after_colon_in_inheritance_clause = true -csharp_space_around_binary_operators = before_and_after -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false -csharp_space_between_method_call_name_and_opening_parenthesis = false -csharp_space_between_method_call_empty_parameter_list_parentheses = false -# Wrapping preferences -csharp_preserve_single_line_statements = true -csharp_preserve_single_line_blocks = true -############################### -# VB Coding Conventions # -############################### -[*.vb] -# Modifier preferences -visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion + [obj/**.cs] generated_code = true + +[*.csproj] +indent_size = 2 diff --git a/build/sanitycheck.py b/build/sanitycheck.py index 97c4e47454..901d364f46 100644 --- a/build/sanitycheck.py +++ b/build/sanitycheck.py @@ -8,7 +8,7 @@ CRLF = b'\r\n' LF = b'\n' -def sanitycheck(pattern, allow_utf8 = False): +def sanitycheck(pattern, allow_utf8 = False, allow_eol = (CRLF, LF), indent = 1): error_count = 0 for filename in glob.glob(pattern, recursive=True): @@ -26,6 +26,8 @@ def sanitycheck(pattern, allow_utf8 = False): for line in content.splitlines(True): if allow_utf8 and lineno == 1 and line.startswith(b'\xef\xbb\xbf'): line = line[3:] + if any(b == 7 for b in line): + error.append(' TAB found at Ln:{} {}'.format(lineno, line)) if any(b > 127 for b in line): error.append(' Non-ASCII character found at Ln:{} {}'.format(lineno, line)) if line[-2:] == CRLF: @@ -43,6 +45,18 @@ def sanitycheck(pattern, allow_utf8 = False): elif line[-1:] == CR: error.append(' CR found at Ln:{} {}'.format(lineno, line)) line = line[:-1] + if eol: + if eol not in allow_eol: + error.append(' Line ending {} not allowed at Ln:{}'.format(eol, lineno)) + break + if line.startswith(b' '): + spc_count = 0 + for c in line: + if c != 32: + break + spc_count += 1 + if not indent or spc_count % indent: + error.append(' {} SPC found at Ln:{} {}'.format(spc_count, lineno, line)) if line[-1:] == b' ' or line[-1:] == b'\t': error.append(' Trailing space found at Ln:{} {}'.format(lineno, line)) lineno += 1 @@ -58,19 +72,23 @@ def sanitycheck(pattern, allow_utf8 = False): return error_count retval = 0 -retval += sanitycheck('**/*.cmd') -retval += sanitycheck('**/*.config', allow_utf8 = True) -retval += sanitycheck('**/*.cs', allow_utf8 = True) -retval += sanitycheck('**/*.cshtml', allow_utf8 = True) -retval += sanitycheck('**/*.csproj', allow_utf8 = True) -retval += sanitycheck('**/*.htm') -retval += sanitycheck('**/*.html') -retval += sanitycheck('**/*.md') -retval += sanitycheck('**/*.proj') -retval += sanitycheck('**/*.props') -retval += sanitycheck('**/*.py') -retval += sanitycheck('**/*.ruleset', allow_utf8 = True) -retval += sanitycheck('**/*.sln', allow_utf8 = True) -retval += sanitycheck('**/*.xml') +retval += sanitycheck('.editorconfig', allow_eol = (LF,), indent = 0) +retval += sanitycheck('**/Dockerfile', allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.cmd', allow_eol = (CRLF,), indent = 2) +retval += sanitycheck('**/*.config', allow_utf8 = True, allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.cs', allow_utf8 = True, allow_eol = (LF,)) +retval += sanitycheck('**/*.cshtml', allow_utf8 = True, allow_eol = (LF,), indent = 4) +retval += sanitycheck('**/*.csproj', allow_utf8 = True, allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.htm', allow_eol = (LF,), indent = 4) +retval += sanitycheck('**/*.html', allow_eol = (LF,), indent = 4) +retval += sanitycheck('**/*.md', allow_eol = (LF,)) +retval += sanitycheck('**/*.proj', allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.props', allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.py', allow_eol = (LF,), indent = 4) +retval += sanitycheck('**/*.ruleset', allow_utf8 = True, allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.sln', allow_utf8 = True, allow_eol = (LF,), indent = 4) +retval += sanitycheck('**/*.targets', allow_eol = (LF,), indent = 2) +retval += sanitycheck('**/*.xml', allow_eol = (LF,), indent = 4) +retval += sanitycheck('**/*.yml', allow_eol = (LF,), indent = 2) sys.exit(retval) diff --git a/examples/Directory.Build.targets b/examples/Directory.Build.targets index da3eb65ef4..43fae9e60c 100644 --- a/examples/Directory.Build.targets +++ b/examples/Directory.Build.targets @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index ea61f4c545..7b9f689d90 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -1,57 +1,57 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; - -namespace Examples.GrpcCore.AspNetCore.Controllers -{ - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase - { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", - }; - - private readonly Echo.EchoClient echoClient; - - public WeatherForecastController(Echo.EchoClient echoClient) - { - this.echoClient = echoClient; - } - - [HttpGet] - public async Task> Get() - { - var echoCall = this.echoClient.EchoAsync(new EchoRequest { Message = "Hello" }); - var echoResponse = await echoCall.ResponseAsync.ConfigureAwait(false); - - var rng = new Random(); - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = rng.Next(-20, 55), - Summary = Summaries[rng.Next(Summaries.Length)], - }) - .ToArray(); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Examples.GrpcCore.AspNetCore.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", + }; + + private readonly Echo.EchoClient echoClient; + + public WeatherForecastController(Echo.EchoClient echoClient) + { + this.echoClient = echoClient; + } + + [HttpGet] + public async Task> Get() + { + var echoCall = this.echoClient.EchoAsync(new EchoRequest { Message = "Hello" }); + var echoResponse = await echoCall.ResponseAsync.ConfigureAwait(false); + + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)], + }) + .ToArray(); + } + } +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs index 6a36fdd4a5..688478c96f 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs @@ -1,33 +1,33 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Threading.Tasks; -using Grpc.Core; - -namespace Examples.GrpcCore.AspNetCore -{ - /// - /// Simple implementation of the echo service. - /// - internal class EchoService : Echo.EchoBase - { - /// - public override Task Echo(EchoRequest request, ServerCallContext context) - { - return Task.FromResult(new EchoResponse { Message = request.Message }); - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Threading.Tasks; +using Grpc.Core; + +namespace Examples.GrpcCore.AspNetCore +{ + /// + /// Simple implementation of the echo service. + /// + internal class EchoService : Echo.EchoBase + { + /// + public override Task Echo(EchoRequest request, ServerCallContext context) + { + return Task.FromResult(new EchoResponse { Message = request.Message }); + } + } +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 8cc915727a..a810d8abeb 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -1,23 +1,23 @@ - - - - net5.0 - - - - - - - - - - - - - - - - - - - + + + + net5.0 + + + + + + + + + + + + + + + + + + + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs index 7d8c817e9d..fc53b160af 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs @@ -1,40 +1,40 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; - -namespace Examples.GrpcCore.AspNetCore -{ - public class Program - { - internal const int Port = 5000; - internal const int GrpcServicePort = 5001; - - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } - - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseUrls($"http://+:{Port}"); - webBuilder.UseStartup(); - }); - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace Examples.GrpcCore.AspNetCore +{ + public class Program + { + internal const int Port = 5000; + internal const int GrpcServicePort = 5001; + + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseUrls($"http://+:{Port}"); + webBuilder.UseStartup(); + }); + } +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index d9104d5bc3..607462e16c 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -1,117 +1,117 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Threading; -using System.Threading.Tasks; -using Grpc.Core; -using Grpc.Core.Interceptors; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using OpenTelemetry.Instrumentation.GrpcCore; -using OpenTelemetry.Trace; - -namespace Examples.GrpcCore.AspNetCore -{ - public class Startup - { - public Startup(IConfiguration configuration) - { - this.Configuration = configuration; - } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddControllers(); - - // Wire in otel - services.AddOpenTelemetryTracing( - (builder) => builder - .AddAspNetCoreInstrumentation() - .AddGrpcCoreInstrumentation() - .AddConsoleExporter()); - - // We are running an in-process gRPC Core service. - services.AddHostedService(); - - // Add a singleton for the gRPC client to our local service. - services.AddSingleton(provider => - { - var channel = new Channel($"dns:localhost:{Program.GrpcServicePort}", ChannelCredentials.Insecure); - - var callInvoker = channel.CreateCallInvoker() - .Intercept(new ClientTracingInterceptor(new ClientTracingInterceptorOptions())); - - return new Echo.EchoClient(callInvoker); - }); - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseRouting(); - - app.UseAuthorization(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } - - /// - /// A hosted service wrapper for an in-process gRPC Core service. - /// This gRPC service is instrumented using the server interceptor. - /// - private sealed class EchoGrpcHostedService : BackgroundService - { - protected override Task ExecuteAsync(CancellationToken stoppingToken) - { - var serviceDefinition = Echo.BindService(new EchoService()) - .Intercept(new ServerTracingInterceptor(new ServerTracingInterceptorOptions())); - - var server = new Server - { - Ports = { new ServerPort("localhost", Program.GrpcServicePort, ServerCredentials.Insecure) }, - Services = { serviceDefinition }, - }; - - server.Start(); - - var tcs = new TaskCompletionSource(); - - var tokenRegistration = stoppingToken.Register( - async () => - { - await server.ShutdownAsync().ConfigureAwait(false); - tcs.SetResult(true); - }); - - return tcs.Task.ContinueWith(antecedent => tokenRegistration.Dispose()); - } - } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Interceptors; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Instrumentation.GrpcCore; +using OpenTelemetry.Trace; + +namespace Examples.GrpcCore.AspNetCore +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + this.Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); + + // Wire in otel + services.AddOpenTelemetryTracing( + (builder) => builder + .AddAspNetCoreInstrumentation() + .AddGrpcCoreInstrumentation() + .AddConsoleExporter()); + + // We are running an in-process gRPC Core service. + services.AddHostedService(); + + // Add a singleton for the gRPC client to our local service. + services.AddSingleton(provider => + { + var channel = new Channel($"dns:localhost:{Program.GrpcServicePort}", ChannelCredentials.Insecure); + + var callInvoker = channel.CreateCallInvoker() + .Intercept(new ClientTracingInterceptor(new ClientTracingInterceptorOptions())); + + return new Echo.EchoClient(callInvoker); + }); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + + /// + /// A hosted service wrapper for an in-process gRPC Core service. + /// This gRPC service is instrumented using the server interceptor. + /// + private sealed class EchoGrpcHostedService : BackgroundService + { + protected override Task ExecuteAsync(CancellationToken stoppingToken) + { + var serviceDefinition = Echo.BindService(new EchoService()) + .Intercept(new ServerTracingInterceptor(new ServerTracingInterceptorOptions())); + + var server = new Server + { + Ports = { new ServerPort("localhost", Program.GrpcServicePort, ServerCredentials.Insecure) }, + Services = { serviceDefinition }, + }; + + server.Start(); + + var tcs = new TaskCompletionSource(); + + var tokenRegistration = stoppingToken.Register( + async () => + { + await server.ShutdownAsync().ConfigureAwait(false); + tcs.SetResult(true); + }); + + return tcs.Task.ContinueWith(antecedent => tokenRegistration.Dispose()); + } + } + } +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index c3530e5867..0c2f9fd7eb 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -1,31 +1,31 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; - -namespace Examples.GrpcCore.AspNetCore -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); - - public string Summary { get; set; } - } -} +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace Examples.GrpcCore.AspNetCore +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); + + public string Summary { get; set; } + } +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.json b/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.json index 81ff877711..d9d9a9bff6 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.json +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.json @@ -1,10 +1,10 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" -} +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/proto/echo.proto b/examples/grpc.core/Examples.GrpcCore.AspNetCore/proto/echo.proto index 18ccfc81fe..ccfaece901 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/proto/echo.proto +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/proto/echo.proto @@ -1,14 +1,14 @@ -syntax = "proto3"; -package Examples.GrpcCore.AspNetCore; - -service Echo { - rpc Echo (EchoRequest) returns (EchoResponse) {} -} - -message EchoRequest { - string message = 1; -} - -message EchoResponse { - string message = 1; -} \ No newline at end of file +syntax = "proto3"; +package Examples.GrpcCore.AspNetCore; + +service Echo { + rpc Echo (EchoRequest) returns (EchoResponse) {} +} + +message EchoRequest { + string message = 1; +} + +message EchoResponse { + string message = 1; +} diff --git a/examples/grpc.core/README.md b/examples/grpc.core/README.md index 17795443ab..5e76477078 100644 --- a/examples/grpc.core/README.md +++ b/examples/grpc.core/README.md @@ -1,17 +1,17 @@ -# Grpc.Core Instrumentation for OpenTelemetry .NET - Examples - -Project structure: - -* Examples.GrpcCore.AspNetCore - - This is an all-in-one sample that shows how to use the client and server - interceptors. The main project is a vanilla webapi project created - using dotnet new ... - - When launched, the project will hit the - endpoint, make a call to a local in-process gRPC Core service running at - localhost:5001. - - The end result is 3 spans dumped via the console exporter. A server span for - the request to , a client span for the outbound - gRPC call and another server span for the gRPC Core server itself. +# Grpc.Core Instrumentation for OpenTelemetry .NET - Examples + +Project structure: + +* Examples.GrpcCore.AspNetCore + + This is an all-in-one sample that shows how to use the client and server + interceptors. The main project is a vanilla webapi project created + using dotnet new ... + + When launched, the project will hit the + endpoint, make a call to a local in-process gRPC Core service running at + localhost:5001. + + The end result is 3 spans dumped via the console exporter. A server span for + the request to , a client span for the outbound + gRPC call and another server span for the gRPC Core server itself. diff --git a/examples/owin/Controllers/TestController.cs b/examples/owin/Controllers/TestController.cs index 4b8e29eddc..ad469faf07 100644 --- a/examples/owin/Controllers/TestController.cs +++ b/examples/owin/Controllers/TestController.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/owin/Program.cs b/examples/owin/Program.cs index 9ee8b2ff03..a9bab679c5 100644 --- a/examples/owin/Program.cs +++ b/examples/owin/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 7caf3e0d40..c1b958d6c6 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/client-core/StatusServiceClient.cs b/examples/wcf/client-core/StatusServiceClient.cs index 6616063312..11a2e533f4 100644 --- a/examples/wcf/client-core/StatusServiceClient.cs +++ b/examples/wcf/client-core/StatusServiceClient.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index 73f66bc503..19882fef1a 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/client-netframework/StatusServiceClient.cs b/examples/wcf/client-netframework/StatusServiceClient.cs index a0fb5eeaed..5cfe67a273 100644 --- a/examples/wcf/client-netframework/StatusServiceClient.cs +++ b/examples/wcf/client-netframework/StatusServiceClient.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/server-netframework/Program.cs b/examples/wcf/server-netframework/Program.cs index dcaa43185c..c09b115db4 100644 --- a/examples/wcf/server-netframework/Program.cs +++ b/examples/wcf/server-netframework/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/server-netframework/StatusService.cs b/examples/wcf/server-netframework/StatusService.cs index d2fab77ffe..e2553b9020 100644 --- a/examples/wcf/server-netframework/StatusService.cs +++ b/examples/wcf/server-netframework/StatusService.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/shared/IStatusServiceContract.cs b/examples/wcf/shared/IStatusServiceContract.cs index 72e6a783cc..cf7c8a73ad 100644 --- a/examples/wcf/shared/IStatusServiceContract.cs +++ b/examples/wcf/shared/IStatusServiceContract.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/shared/StatusRequest.cs b/examples/wcf/shared/StatusRequest.cs index 450480946c..1061df0261 100644 --- a/examples/wcf/shared/StatusRequest.cs +++ b/examples/wcf/shared/StatusRequest.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/wcf/shared/StatusResponse.cs b/examples/wcf/shared/StatusResponse.cs index cdde1af310..b3d43b27c0 100644 --- a/examples/wcf/shared/StatusResponse.cs +++ b/examples/wcf/shared/StatusResponse.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7d772b65d8..4e2ca5ca08 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -1,474 +1,474 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31912.275 -MinimumVisualStudioVersion = 15.0.26124.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2097345F-4DD3-477D-BC54-A922F9B2B402}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{07AA0F83-22F6-4B8C-921D-029D3384CB17}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - CONTRIBUTING.md = CONTRIBUTING.md - NuGet.config = NuGet.config - opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj - README.md = README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A06E14B-DD2F-4536-9D2E-F708C0C43555}" - ProjectSection(SolutionItems) = preProject - .github\codecov.yml = .github\codecov.yml - CODEOWNERS = CODEOWNERS - .github\component_owners.yml = .github\component_owners.yml - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" - ProjectSection(SolutionItems) = preProject - .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml - .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml - .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml - .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml - .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml - .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml - .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml - .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml - .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml - .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml - .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml - .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml - .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml - .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml - .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml - .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml - .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml - .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml - .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml - .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml - .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml - .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml - .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml - .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml - .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml - .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml - .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE-3FA8-4FE0-823A-FD365EAC78AF}" - ProjectSection(SolutionItems) = preProject - 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 - build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png - build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset - build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset - build\sanitycheck.py = build\sanitycheck.py - build\stylecop.json = build\stylecop.json - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0112BD4F-B7A6-4E43-AB23-B6E961E27A49}" - ProjectSection(SolutionItems) = preProject - src\Directory.Build.props = src\Directory.Build.props - src\Directory.Build.targets = src\Directory.Build.targets - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-23D1-4927-BAB8-332655DD7A0B}" - ProjectSection(SolutionItems) = preProject - test\Directory.Build.props = test\Directory.Build.props - test\Directory.Build.targets = test\Directory.Build.targets - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wcf", "wcf", "{73474960-8F91-4EE5-8E3E-F7E7ADA99238}" - ProjectSection(SolutionItems) = preProject - examples\wcf\README.md = examples\wcf\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Shared", "examples\wcf\shared\Examples.Wcf.Shared.csproj", "{21716C26-3B2A-4208-BDFB-8E58E2AF49EA}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.Core", "examples\wcf\client-core\Examples.Wcf.Client.Core.csproj", "{3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.NetFramework", "examples\wcf\client-netframework\Examples.Wcf.Client.NetFramework.csproj", "{2A7867E5-0FD6-42F8-B594-19E897EDA54C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Server.NetFramework", "examples\wcf\server-netframework\Examples.Wcf.Server.NetFramework.csproj", "{E205AA70-36BD-461D-8B87-909ED1BCA721}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay", "src\OpenTelemetry.Contrib.Extensions.AWSXRay\OpenTelemetry.Contrib.Extensions.AWSXRay.csproj", "{D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay.Tests", "test\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj", "{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS", "src\OpenTelemetry.Contrib.Instrumentation.AWS\OpenTelemetry.Contrib.Instrumentation.AWS.csproj", "{970673DA-F308-4960-A58D-ECCEA44CEF6B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWS.Tests\OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj", "{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared", "src\OpenTelemetry.Contrib.Shared\OpenTelemetry.Contrib.Shared.csproj", "{F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{58D1DE55-B0A5-4BC4-AB37-09B1C7B26752}" - ProjectSection(SolutionItems) = preProject - examples\grpc.core\README.md = examples\grpc.core\README.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcCore.AspNetCore", "examples\grpc.core\Examples.GrpcCore.AspNetCore\Examples.GrpcCore.AspNetCore.csproj", "{F1591DEE-79C0-4161-85C2-1477B261D274}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda", "src\OpenTelemetry.Contrib.Instrumentation.AWSLambda\OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj", "{87FE0ED4-56A5-4775-9F63-DD532F2200BD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj", "{08EDD935-8B4E-4CF5-8840-200DEBA8E110}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Tests.Shared", "test\OpenTelemetry.Contrib.Tests.Shared\OpenTelemetry.Contrib.Tests.Shared.csproj", "{C33F2D9D-89A6-459C-9A51-79BA5A9EF194}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "owin", "owin", "{8D11A34C-D0EF-4DE1-8230-32168E67044D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\owin\Examples.Owin.csproj", "{6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Instrumentation.ElasticsearchClient\OpenTelemetry.Instrumentation.ElasticsearchClient.csproj", "{96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{970B604C-C57F-4767-A080-67976E69F76E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor", "src\OpenTelemetry.Extensions.AzureMonitor\OpenTelemetry.Extensions.AzureMonitor.csproj", "{426D8AE8-EC39-48EA-AC66-1BF84C4CE529}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit", "src\OpenTelemetry.Instrumentation.MassTransit\OpenTelemetry.Instrumentation.MassTransit.csproj", "{D4120D09-93F6-4D5C-98C6-A98B459EA83D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Instrumentation.MassTransit.Tests\OpenTelemetry.Instrumentation.MassTransit.Tests.csproj", "{4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage", "src\OpenTelemetry.Extensions.PersistentStorage\OpenTelemetry.Extensions.PersistentStorage.csproj", "{C2B9190B-E2F6-4D40-B298-91521E383A50}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Instrumentation.EntityFrameworkCore\OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj", "{D4468444-69EF-4BF3-B13F-61F4AB728813}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj", "{A1F7FA66-C83D-485D-90FE-71C4018971D4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore", "src\OpenTelemetry.Instrumentation.GrpcCore\OpenTelemetry.Instrumentation.GrpcCore.csproj", "{D0B694E4-AAE4-492F-ACCB-3D913A874780}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore.Tests", "test\OpenTelemetry.Instrumentation.GrpcCore.Tests\OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj", "{32D24733-C807-4816-84C3-270CE790AFD4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin", "src\OpenTelemetry.Instrumentation.Owin\OpenTelemetry.Instrumentation.Owin.csproj", "{2815DA76-D855-43FD-A005-FAB289B5EFE8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin.Tests", "test\OpenTelemetry.Instrumentation.Owin.Tests\OpenTelemetry.Instrumentation.Owin.Tests.csproj", "{D7311F9A-BFC3-4470-9C49-39D826BA9996}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{67BFE7DF-505D-427E-8019-40BFF19363E9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", "src\OpenTelemetry.Extensions\OpenTelemetry.Extensions.csproj", "{42B3FB71-BB42-46E3-9CEC-56620CB76BD9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva", "src\OpenTelemetry.Exporter.Geneva\OpenTelemetry.Exporter.Geneva.csproj", "{1105C814-31DA-4214-BEA8-6DB5FC12C808}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Benchmark", "test\OpenTelemetry.Exporter.Geneva.Benchmark\OpenTelemetry.Exporter.Geneva.Benchmark.csproj", "{F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Stress", "test\OpenTelemetry.Exporter.Geneva.Stress\OpenTelemetry.Exporter.Geneva.Stress.csproj", "{F632DFB6-38AD-4356-8997-8CCC0492619C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Tests", "test\OpenTelemetry.Exporter.Geneva.Tests\OpenTelemetry.Exporter.Geneva.Tests.csproj", "{A3EB4E60-256C-45EC-92EE-68FD035CAD11}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire", "src\OpenTelemetry.Instrumentation.Hangfire\OpenTelemetry.Instrumentation.Hangfire.csproj", "{BE5FFBBB-D73F-4071-92F4-F1694881604F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Abstractions", "src\OpenTelemetry.Extensions.PersistentStorage.Abstractions\OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj", "{17E3936A-265A-4C9F-9DD5-4568F80E6D91}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana", "src\OpenTelemetry.Exporter.Instana\OpenTelemetry.Exporter.Instana.csproj", "{BD3C6377-6F8D-47D6-9710-1681ED4E6772}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana.Tests", "test\OpenTelemetry.Exporter.Instana.Tests\OpenTelemetry.Exporter.Instana.Tests.csproj", "{77E7DDB9-32CF-450E-B596-E893149D07DD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis", "src\OpenTelemetry.Instrumentation.StackExchangeRedis\OpenTelemetry.Instrumentation.StackExchangeRedis.csproj", "{14BAEC26-CCD1-44B5-94D7-F219057B0B4D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests", "test\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj", "{2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Release|Any CPU.Build.0 = Release|Any CPU - {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Release|Any CPU.Build.0 = Release|Any CPU - {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Release|Any CPU.Build.0 = Release|Any CPU - {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Release|Any CPU.Build.0 = Release|Any CPU - {E205AA70-36BD-461D-8B87-909ED1BCA721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E205AA70-36BD-461D-8B87-909ED1BCA721}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E205AA70-36BD-461D-8B87-909ED1BCA721}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E205AA70-36BD-461D-8B87-909ED1BCA721}.Release|Any CPU.Build.0 = Release|Any CPU - {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Release|Any CPU.Build.0 = Release|Any CPU - {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Release|Any CPU.Build.0 = Release|Any CPU - {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Release|Any CPU.Build.0 = Release|Any CPU - {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.Build.0 = Release|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Release|Any CPU.Build.0 = Release|Any CPU - {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Release|Any CPU.Build.0 = Release|Any CPU - {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.Build.0 = Release|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.Build.0 = Release|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.Build.0 = Debug|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.ActiveCfg = Release|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.Build.0 = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.Build.0 = Release|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU - {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.Build.0 = Release|Any CPU - {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.Build.0 = Release|Any CPU - {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.Build.0 = Release|Any CPU - {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Release|Any CPU.Build.0 = Release|Any CPU - {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.Build.0 = Release|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.Build.0 = Debug|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.ActiveCfg = Release|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.Build.0 = Release|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.Build.0 = Release|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.Build.0 = Release|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.Build.0 = Release|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.Build.0 = Release|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.Build.0 = Release|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.Build.0 = Release|Any CPU - {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.Build.0 = Release|Any CPU - {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.Build.0 = Release|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.Build.0 = Release|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.Build.0 = Release|Any CPU - {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.Build.0 = Release|Any CPU - {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.Build.0 = Release|Any CPU - {67BFE7DF-505D-427E-8019-40BFF19363E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {67BFE7DF-505D-427E-8019-40BFF19363E9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {67BFE7DF-505D-427E-8019-40BFF19363E9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {67BFE7DF-505D-427E-8019-40BFF19363E9}.Release|Any CPU.Build.0 = Release|Any CPU - {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.Build.0 = Release|Any CPU - {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Release|Any CPU.Build.0 = Release|Any CPU - {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.Build.0 = Release|Any CPU - {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.Build.0 = Release|Any CPU - {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Release|Any CPU.Build.0 = Release|Any CPU - {F632DFB6-38AD-4356-8997-8CCC0492619C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F632DFB6-38AD-4356-8997-8CCC0492619C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F632DFB6-38AD-4356-8997-8CCC0492619C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F632DFB6-38AD-4356-8997-8CCC0492619C}.Release|Any CPU.Build.0 = Release|Any CPU - {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Release|Any CPU.Build.0 = Release|Any CPU - {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.Build.0 = Release|Any CPU - {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.Build.0 = Release|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.Build.0 = Release|Any CPU - {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.Build.0 = Release|Any CPU - {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.Build.0 = Release|Any CPU - {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Release|Any CPU.Build.0 = Release|Any CPU - {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {43CAFE52-F329-4431-87DA-7FEE1454D9A9} = {1A06E14B-DD2F-4536-9D2E-F708C0C43555} - {0112BD4F-B7A6-4E43-AB23-B6E961E27A49} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {E0F52FDB-23D1-4927-BAB8-332655DD7A0B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {CAD5C27A-D359-4086-9C4F-02204C084A8E} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {73474960-8F91-4EE5-8E3E-F7E7ADA99238} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} - {21716C26-3B2A-4208-BDFB-8E58E2AF49EA} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} - {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} - {2A7867E5-0FD6-42F8-B594-19E897EDA54C} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} - {E205AA70-36BD-461D-8B87-909ED1BCA721} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} - {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {970673DA-F308-4960-A58D-ECCEA44CEF6B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} - {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} - {87FE0ED4-56A5-4775-9F63-DD532F2200BD} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {08EDD935-8B4E-4CF5-8840-200DEBA8E110} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} - {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} - {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {D4120D09-93F6-4D5C-98C6-A98B459EA83D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {A1F7FA66-C83D-485D-90FE-71C4018971D4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {67BFE7DF-505D-427E-8019-40BFF19363E9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {42B3FB71-BB42-46E3-9CEC-56620CB76BD9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {2117F4E3-6612-4E4D-A757-27271EEB7783} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {1105C814-31DA-4214-BEA8-6DB5FC12C808} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {F632DFB6-38AD-4356-8997-8CCC0492619C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {A3EB4E60-256C-45EC-92EE-68FD035CAD11} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {17E3936A-265A-4C9F-9DD5-4568F80E6D91} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {BD3C6377-6F8D-47D6-9710-1681ED4E6772} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {77E7DDB9-32CF-450E-B596-E893149D07DD} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {14BAEC26-CCD1-44B5-94D7-F219057B0B4D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2097345F-4DD3-477D-BC54-A922F9B2B402}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{07AA0F83-22F6-4B8C-921D-029D3384CB17}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + CONTRIBUTING.md = CONTRIBUTING.md + NuGet.config = NuGet.config + opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj + README.md = README.md + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A06E14B-DD2F-4536-9D2E-F708C0C43555}" + ProjectSection(SolutionItems) = preProject + .github\codecov.yml = .github\codecov.yml + CODEOWNERS = CODEOWNERS + .github\component_owners.yml = .github\component_owners.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" + ProjectSection(SolutionItems) = preProject + .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml + .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml + .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml + .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml + .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml + .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml + .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml + .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml + .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml + .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml + .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml + .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml + .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml + .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml + .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml + .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml + .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml + .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml + .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml + .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml + .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml + .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml + .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml + .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml + .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml + .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml + .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE-3FA8-4FE0-823A-FD365EAC78AF}" + ProjectSection(SolutionItems) = preProject + 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 + build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png + build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset + build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset + build\sanitycheck.py = build\sanitycheck.py + build\stylecop.json = build\stylecop.json + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0112BD4F-B7A6-4E43-AB23-B6E961E27A49}" + ProjectSection(SolutionItems) = preProject + src\Directory.Build.props = src\Directory.Build.props + src\Directory.Build.targets = src\Directory.Build.targets + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E0F52FDB-23D1-4927-BAB8-332655DD7A0B}" + ProjectSection(SolutionItems) = preProject + test\Directory.Build.props = test\Directory.Build.props + test\Directory.Build.targets = test\Directory.Build.targets + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf", "src\OpenTelemetry.Instrumentation.Wcf\OpenTelemetry.Instrumentation.Wcf.csproj", "{CAD5C27A-D359-4086-9C4F-02204C084A8E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wcf", "wcf", "{73474960-8F91-4EE5-8E3E-F7E7ADA99238}" + ProjectSection(SolutionItems) = preProject + examples\wcf\README.md = examples\wcf\README.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Shared", "examples\wcf\shared\Examples.Wcf.Shared.csproj", "{21716C26-3B2A-4208-BDFB-8E58E2AF49EA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.Core", "examples\wcf\client-core\Examples.Wcf.Client.Core.csproj", "{3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.NetFramework", "examples\wcf\client-netframework\Examples.Wcf.Client.NetFramework.csproj", "{2A7867E5-0FD6-42F8-B594-19E897EDA54C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Server.NetFramework", "examples\wcf\server-netframework\Examples.Wcf.Server.NetFramework.csproj", "{E205AA70-36BD-461D-8B87-909ED1BCA721}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay", "src\OpenTelemetry.Contrib.Extensions.AWSXRay\OpenTelemetry.Contrib.Extensions.AWSXRay.csproj", "{D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay.Tests", "test\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj", "{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS", "src\OpenTelemetry.Contrib.Instrumentation.AWS\OpenTelemetry.Contrib.Instrumentation.AWS.csproj", "{970673DA-F308-4960-A58D-ECCEA44CEF6B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWS.Tests\OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj", "{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared", "src\OpenTelemetry.Contrib.Shared\OpenTelemetry.Contrib.Shared.csproj", "{F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{58D1DE55-B0A5-4BC4-AB37-09B1C7B26752}" + ProjectSection(SolutionItems) = preProject + examples\grpc.core\README.md = examples\grpc.core\README.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcCore.AspNetCore", "examples\grpc.core\Examples.GrpcCore.AspNetCore\Examples.GrpcCore.AspNetCore.csproj", "{F1591DEE-79C0-4161-85C2-1477B261D274}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda", "src\OpenTelemetry.Contrib.Instrumentation.AWSLambda\OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj", "{87FE0ED4-56A5-4775-9F63-DD532F2200BD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj", "{08EDD935-8B4E-4CF5-8840-200DEBA8E110}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Tests.Shared", "test\OpenTelemetry.Contrib.Tests.Shared\OpenTelemetry.Contrib.Tests.Shared.csproj", "{C33F2D9D-89A6-459C-9A51-79BA5A9EF194}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "owin", "owin", "{8D11A34C-D0EF-4DE1-8230-32168E67044D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\owin\Examples.Owin.csproj", "{6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Instrumentation.ElasticsearchClient\OpenTelemetry.Instrumentation.ElasticsearchClient.csproj", "{96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{970B604C-C57F-4767-A080-67976E69F76E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor", "src\OpenTelemetry.Extensions.AzureMonitor\OpenTelemetry.Extensions.AzureMonitor.csproj", "{426D8AE8-EC39-48EA-AC66-1BF84C4CE529}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit", "src\OpenTelemetry.Instrumentation.MassTransit\OpenTelemetry.Instrumentation.MassTransit.csproj", "{D4120D09-93F6-4D5C-98C6-A98B459EA83D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Instrumentation.MassTransit.Tests\OpenTelemetry.Instrumentation.MassTransit.Tests.csproj", "{4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage", "src\OpenTelemetry.Extensions.PersistentStorage\OpenTelemetry.Extensions.PersistentStorage.csproj", "{C2B9190B-E2F6-4D40-B298-91521E383A50}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Instrumentation.EntityFrameworkCore\OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj", "{D4468444-69EF-4BF3-B13F-61F4AB728813}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj", "{A1F7FA66-C83D-485D-90FE-71C4018971D4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore", "src\OpenTelemetry.Instrumentation.GrpcCore\OpenTelemetry.Instrumentation.GrpcCore.csproj", "{D0B694E4-AAE4-492F-ACCB-3D913A874780}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcCore.Tests", "test\OpenTelemetry.Instrumentation.GrpcCore.Tests\OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj", "{32D24733-C807-4816-84C3-270CE790AFD4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin", "src\OpenTelemetry.Instrumentation.Owin\OpenTelemetry.Instrumentation.Owin.csproj", "{2815DA76-D855-43FD-A005-FAB289B5EFE8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Owin.Tests", "test\OpenTelemetry.Instrumentation.Owin.Tests\OpenTelemetry.Instrumentation.Owin.Tests.csproj", "{D7311F9A-BFC3-4470-9C49-39D826BA9996}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime", "src\OpenTelemetry.Instrumentation.Runtime\OpenTelemetry.Instrumentation.Runtime.csproj", "{67BFE7DF-505D-427E-8019-40BFF19363E9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Runtime.Tests", "test\OpenTelemetry.Instrumentation.Runtime.Tests\OpenTelemetry.Instrumentation.Runtime.Tests.csproj", "{6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", "src\OpenTelemetry.Extensions\OpenTelemetry.Extensions.csproj", "{42B3FB71-BB42-46E3-9CEC-56620CB76BD9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva", "src\OpenTelemetry.Exporter.Geneva\OpenTelemetry.Exporter.Geneva.csproj", "{1105C814-31DA-4214-BEA8-6DB5FC12C808}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Benchmark", "test\OpenTelemetry.Exporter.Geneva.Benchmark\OpenTelemetry.Exporter.Geneva.Benchmark.csproj", "{F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Stress", "test\OpenTelemetry.Exporter.Geneva.Stress\OpenTelemetry.Exporter.Geneva.Stress.csproj", "{F632DFB6-38AD-4356-8997-8CCC0492619C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Tests", "test\OpenTelemetry.Exporter.Geneva.Tests\OpenTelemetry.Exporter.Geneva.Tests.csproj", "{A3EB4E60-256C-45EC-92EE-68FD035CAD11}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire", "src\OpenTelemetry.Instrumentation.Hangfire\OpenTelemetry.Instrumentation.Hangfire.csproj", "{BE5FFBBB-D73F-4071-92F4-F1694881604F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Abstractions", "src\OpenTelemetry.Extensions.PersistentStorage.Abstractions\OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj", "{17E3936A-265A-4C9F-9DD5-4568F80E6D91}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana", "src\OpenTelemetry.Exporter.Instana\OpenTelemetry.Exporter.Instana.csproj", "{BD3C6377-6F8D-47D6-9710-1681ED4E6772}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana.Tests", "test\OpenTelemetry.Exporter.Instana.Tests\OpenTelemetry.Exporter.Instana.Tests.csproj", "{77E7DDB9-32CF-450E-B596-E893149D07DD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis", "src\OpenTelemetry.Instrumentation.StackExchangeRedis\OpenTelemetry.Instrumentation.StackExchangeRedis.csproj", "{14BAEC26-CCD1-44B5-94D7-F219057B0B4D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests", "test\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj", "{2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAD5C27A-D359-4086-9C4F-02204C084A8E}.Release|Any CPU.Build.0 = Release|Any CPU + {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {21716C26-3B2A-4208-BDFB-8E58E2AF49EA}.Release|Any CPU.Build.0 = Release|Any CPU + {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}.Release|Any CPU.Build.0 = Release|Any CPU + {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A7867E5-0FD6-42F8-B594-19E897EDA54C}.Release|Any CPU.Build.0 = Release|Any CPU + {E205AA70-36BD-461D-8B87-909ED1BCA721}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E205AA70-36BD-461D-8B87-909ED1BCA721}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E205AA70-36BD-461D-8B87-909ED1BCA721}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E205AA70-36BD-461D-8B87-909ED1BCA721}.Release|Any CPU.Build.0 = Release|Any CPU + {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}.Release|Any CPU.Build.0 = Release|Any CPU + {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}.Release|Any CPU.Build.0 = Release|Any CPU + {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {970673DA-F308-4960-A58D-ECCEA44CEF6B}.Release|Any CPU.Build.0 = Release|Any CPU + {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.Build.0 = Release|Any CPU + {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Release|Any CPU.Build.0 = Release|Any CPU + {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Release|Any CPU.Build.0 = Release|Any CPU + {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.Build.0 = Release|Any CPU + {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.Build.0 = Release|Any CPU + {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.Build.0 = Release|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.Build.0 = Release|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}.Release|Any CPU.Build.0 = Release|Any CPU + {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423}.Release|Any CPU.Build.0 = Release|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}.Release|Any CPU.Build.0 = Release|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DABC11A-624E-4554-ACA4-D5B80146B9C6}.Release|Any CPU.Build.0 = Release|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}.Release|Any CPU.Build.0 = Release|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.Build.0 = Release|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.Build.0 = Debug|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.ActiveCfg = Release|Any CPU + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.Build.0 = Release|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.Build.0 = Release|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.Build.0 = Release|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.Build.0 = Release|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.Build.0 = Release|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.Build.0 = Release|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.Build.0 = Release|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.Build.0 = Release|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A1F7FA66-C83D-485D-90FE-71C4018971D4}.Release|Any CPU.Build.0 = Release|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0B694E4-AAE4-492F-ACCB-3D913A874780}.Release|Any CPU.Build.0 = Release|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32D24733-C807-4816-84C3-270CE790AFD4}.Release|Any CPU.Build.0 = Release|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2815DA76-D855-43FD-A005-FAB289B5EFE8}.Release|Any CPU.Build.0 = Release|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7311F9A-BFC3-4470-9C49-39D826BA9996}.Release|Any CPU.Build.0 = Release|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67BFE7DF-505D-427E-8019-40BFF19363E9}.Release|Any CPU.Build.0 = Release|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D}.Release|Any CPU.Build.0 = Release|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9}.Release|Any CPU.Build.0 = Release|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.Build.0 = Release|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.Build.0 = Release|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}.Release|Any CPU.Build.0 = Release|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F632DFB6-38AD-4356-8997-8CCC0492619C}.Release|Any CPU.Build.0 = Release|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A3EB4E60-256C-45EC-92EE-68FD035CAD11}.Release|Any CPU.Build.0 = Release|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE5FFBBB-D73F-4071-92F4-F1694881604F}.Release|Any CPU.Build.0 = Release|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.Build.0 = Release|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.Build.0 = Release|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.Build.0 = Release|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77E7DDB9-32CF-450E-B596-E893149D07DD}.Release|Any CPU.Build.0 = Release|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D}.Release|Any CPU.Build.0 = Release|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {43CAFE52-F329-4431-87DA-7FEE1454D9A9} = {1A06E14B-DD2F-4536-9D2E-F708C0C43555} + {0112BD4F-B7A6-4E43-AB23-B6E961E27A49} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {E0F52FDB-23D1-4927-BAB8-332655DD7A0B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {CAD5C27A-D359-4086-9C4F-02204C084A8E} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {73474960-8F91-4EE5-8E3E-F7E7ADA99238} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {21716C26-3B2A-4208-BDFB-8E58E2AF49EA} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} + {3AF5D7E4-CA7D-401B-9729-A6D8F63B023C} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} + {2A7867E5-0FD6-42F8-B594-19E897EDA54C} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} + {E205AA70-36BD-461D-8B87-909ED1BCA721} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} + {D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {970673DA-F308-4960-A58D-ECCEA44CEF6B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} + {87FE0ED4-56A5-4775-9F63-DD532F2200BD} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {08EDD935-8B4E-4CF5-8840-200DEBA8E110} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {6B3AA3F2-89A7-433F-918A-1E5E6AAF8423} = {8D11A34C-D0EF-4DE1-8230-32168E67044D} + {8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D4120D09-93F6-4D5C-98C6-A98B459EA83D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {A1F7FA66-C83D-485D-90FE-71C4018971D4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {32D24733-C807-4816-84C3-270CE790AFD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {2815DA76-D855-43FD-A005-FAB289B5EFE8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {D7311F9A-BFC3-4470-9C49-39D826BA9996} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {67BFE7DF-505D-427E-8019-40BFF19363E9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {42B3FB71-BB42-46E3-9CEC-56620CB76BD9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2117F4E3-6612-4E4D-A757-27271EEB7783} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {1105C814-31DA-4214-BEA8-6DB5FC12C808} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {F632DFB6-38AD-4356-8997-8CCC0492619C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A3EB4E60-256C-45EC-92EE-68FD035CAD11} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {17E3936A-265A-4C9F-9DD5-4568F80E6D91} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {BD3C6377-6F8D-47D6-9710-1681ED4E6772} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {77E7DDB9-32CF-450E-B596-E893149D07DD} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {14BAEC26-CCD1-44B5-94D7-F219057B0B4D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} + EndGlobalSection +EndGlobal diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index a582103dd0..986e063e61 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -15,4 +15,4 @@ - \ No newline at end of file + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs index 945c09dc05..67a9f7fefc 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs index 9cf3f53d12..4678254ea9 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs index 772898b5d6..d5ed93f820 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index 4c1b4b9c15..ad7c981332 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -1,27 +1,27 @@ -# Changelog - OpenTelemetry.Contrib.Extensions.AWSXRay - -## 1.2.0 [2022-May-18] - -* Enhancement - AWSEKSResourceDetector - Validate ClusterName/ContainerID - independently before adding it to the resource - ([#205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/205)) -* Fix - AWSEKSResourceDetector fails to detect resources due to exception - "The SSL connection could not be established" - ([#208](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/208)) - -## 1.1.0 [2021-Sept-20] - -* Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) -* Updated OTel SDK package version to 1.1.0 - ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) - -## 1.0.1 [2021-Feb-24] - -This is the first release for the `OpenTelemetry.Contrib.Extensions.AWSXRay` -project. The project targets v1.0.1 of the [OpenTelemetry -SDK](https://www.nuget.org/packages/OpenTelemetry/). - -The AWSXRay extensions include plugin to generate X-Ray format trace-ids and a -propagator to propagate the X-Ray trace header to downstream. For more details, -please refer to the -[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md) +# Changelog - OpenTelemetry.Contrib.Extensions.AWSXRay + +## 1.2.0 [2022-May-18] + +* Enhancement - AWSEKSResourceDetector - Validate ClusterName/ContainerID + independently before adding it to the resource + ([#205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/205)) +* Fix - AWSEKSResourceDetector fails to detect resources due to exception + "The SSL connection could not be established" + ([#208](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/208)) + +## 1.1.0 [2021-Sept-20] + +* Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) +* Updated OTel SDK package version to 1.1.0 + ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) + +## 1.0.1 [2021-Feb-24] + +This is the first release for the `OpenTelemetry.Contrib.Extensions.AWSXRay` +project. The project targets v1.0.1 of the [OpenTelemetry +SDK](https://www.nuget.org/packages/OpenTelemetry/). + +The AWSXRay extensions include plugin to generate X-Ray format trace-ids and a +propagator to propagate the X-Ray trace header to downstream. For more details, +please refer to the +[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs index c47dc26e26..a06dc4a5db 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs index 832bd3fda1..7a7e4f7b82 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index bd6808c365..3df4ad64a2 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index 7be2e1ebd9..32d151c504 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs index 6c9cb74530..9bef38cc0b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs index dbbced4c14..ab6ca6cbef 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs index 2b3326deb2..ddd66cdacc 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs index ce24067908..112f4a7929 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs index 56b763d582..6ffa64c130 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs index 5780a018b2..ae4ed8d5c6 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs index 8662829556..65f6559eb4 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs index cb6df66ce8..abaec62717 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs index cbd2dc55a5..db7bdd5833 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs index 9a1c722019..06f913f05e 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs index ad6a1594b7..9db25ef0d4 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs index a4cd229a3e..5864339d4e 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs index 0adbb62772..7690bb2f34 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs index 3d92002c36..3fb384be33 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs index 596aa11822..cc2b4852ad 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs index 09bdcfadc3..fcf0ca5fce 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index 5b25775af9..26665d3458 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index d4af217d8a..20da211edb 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 9950e6f618..f7b5862186 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs index cb662b2cf6..1104e4b66a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index 96408c758e..bb08c911d6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs index d8d876840f..27a1e79e48 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs index 9b74d78d87..f489ac6868 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs index 0eafb75567..4a174094cd 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 88f1029e31..1e859dcaee 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs index d13861c01d..cab174c835 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index db2f232bf1..7cd573a766 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs index 5a60a1900b..cdd5d92cd0 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs index 3de2891300..0254b0cc12 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs b/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs index 4b368e8ec6..b1fd73f3a7 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs b/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs index 450803f378..1871c60baf 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs b/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs index c1e1c3ca3b..7bff65e696 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs index c057783c8a..f3b8fadcd4 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs index 940746c720..4ca8fa2b2a 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs index 8a006394b6..4e527812f3 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs index f58e0fe7cc..812fc572ce 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs index 198f3815fc..ea98ab414a 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs index 277162d439..cb22138aa6 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs index ce159ee92e..66ae48e0ca 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs index e360055f57..7746d9d6ad 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs index 3bb1bb6347..933805d3ae 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs b/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs index c92e3ba0b5..daa1384d98 100644 --- a/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs index 96c1fb823d..67a0e79c89 100644 --- a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs index b09a6436bb..bba3ef97d4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs index dd2dda94cf..38e42a3e01 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs index a948859405..3a2e7e3dbd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 8cc50613a3..3dc7185074 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 5a14308ffe..09fb5c8942 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 63eba08012..e940366c25 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index f700622aca..60089b093e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index e7ec6b9737..e7331a66e7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index dbac7b8ed7..189d251c70 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index 8cedae0682..d086680135 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs index 84261b27a5..5d406e0f3c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index bbe5501481..9c976be084 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs index a296312213..200f04ac1b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs index 622f168bf1..112a05bf65 100644 --- a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs index 331ad0e36d..f92f79d0db 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs index 59823c46f2..cee3871f86 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs index bc9ccf4bac..fa1615c672 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs index abd966485a..c042db0a60 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs index 81ca57cb3f..80c1522186 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs index 95b2163370..0806440867 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Schema.cs index 7217d6aa7f..b5cf8429c4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Schema.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Schema.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs index 65bad6b89b..096eda95ac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs index b0a06fa393..78c024a1d5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs index 480bb6cd02..63e37360b7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs index 0ce045c869..2784c9deb6 100644 --- a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs +++ b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs index 83d3ae906e..61b6bff763 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs index 783c18e75e..81cda404e9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs index 35a4bee074..71b7ec5d40 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 36e515b167..68bc0b8715 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs index 659fc89ead..3579ba28d8 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs index 1e5ed9a84d..159fb97043 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs index 7644b16912..467002398e 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs index 049fb6a395..92ccf9b9c5 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs index ec6016e3cc..f8ddd63c20 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs index 89b74a954c..b935eefb57 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs index b35b7d3377..9707740a6e 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index 520a4f3952..5a9c5cbe4b 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index 7ccc3992a4..ec4749607d 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index 06fbf85934..6ff9e5254d 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs index cecdf10035..d2b1c417f8 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs index cd966785fa..3345bbfef7 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs index e9509a2306..fea138bbd7 100644 --- a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs index 049a965c42..62657261c0 100644 --- a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 025c956f65..f6e814d9d4 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs index fa011acc12..8a91ab9803 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs index 2d6d9d6d94..e2963b08ce 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs index 72b9aa6ae4..74fda378cd 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs index c247f83d76..0ffe6d0abc 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs index a95d903b3a..c2937a3676 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 512e8cd603..526337866f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index 24d2fb3e52..82169f9aad 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs index e81b4d5533..9d852ec2d0 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 89db6c8708..00bd29aa5d 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs index fb9851b200..11bfd5a202 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs index a84422c35b..77db7673bc 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs index ab963bb185..5cccfd07c4 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs index 486b250690..2eec7f7a8a 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs index 717940aaa6..b2ffb1cc23 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs index 711d529c4d..414feeffd5 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs index 37ba893702..d56c0bb2c9 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs index cb75baf48b..8e008501ec 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs index ec90919986..c4553e3934 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs index e102645a6c..9b0fc0eb2a 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/AssemblyInfo.cs b/src/OpenTelemetry.Extensions/AssemblyInfo.cs index fb9851b200..11bfd5a202 100644 --- a/src/OpenTelemetry.Extensions/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index 21a0cec1a3..2db1c1e820 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index 76d64d64f3..fc2687ef5c 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index 0815f0b2b0..ff7a5100f6 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index d2342ce410..93910b8a41 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index 43e1bb160f..ed9dd8748d 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs index 02fc015f74..ebe36c5b90 100644 --- a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs +++ b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index 5ae2437f52..c3ca61a1e7 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs index 43a4e7fb2c..3756e327b7 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index e3d4abcac8..d8cd284f8e 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs index 6ac52ff137..8e75df41a4 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 4b055356bc..86284d73fb 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs index d5e496903e..c9569e0a55 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index 6fbd1b779a..c809fc9f67 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 47e976bcf2..c82b49f19d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index ccf8f8576a..7c8accf017 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index a66da55651..44631fbd66 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 1868e7d8ad..310d152676 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs index e13ce2b912..e35b4a6565 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 752130838a..12d24832a3 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs index 3ad733d811..f40f68ad0a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index 698cad42ee..fdeb782a55 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index 5aadc8e09f..ae0e3b05bb 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index f081401bed..5bef4540ba 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index bd60b6691b..1eac18fe58 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs index 9ee660121a..0d31f0c8f3 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index 86ebffa3d3..f215aa9a0a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index 64c67705d5..1abdf00701 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs index 3a023bf6cb..be314c854a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index 111e617f31..b4a1bc1824 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index c5ab46a8a1..fbb26fb96e 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index 59ec31dd29..3713491397 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs index 9e428a4793..2b3e817438 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index 2adc37cd77..286a465858 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs index 956a0ca3d0..9d4ead7b5c 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index d00b78fd4e..60a8d8cf1c 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index d965a18ac8..3d6bdb225b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs index 73a6afa34c..2c45e8a3e5 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs index e657c67d95..6d5320f6b2 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs index fc9d694950..a7e6ec171f 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs index e722c35f22..8df2fe8abe 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs index 8045c7c1a2..ffa89d3bd6 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs index 5e4e4d7065..3cf2d93d06 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs index 42f6e42009..a61007c214 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs index 95b72e7268..5ffca9abe7 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs index df045bb7f2..5a04f5c95b 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs index 4f7a81862a..0992f3216f 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs index 864cb0df01..766e46cb93 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs index 65adeb2296..1aeea3b0af 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index 619dc72cd9..1c138173e4 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs index d56c6c29ab..8a0118bcd6 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs index 1ee9760218..bac2b8869a 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs index 0c876e3dbf..a1b6674529 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs index d9a4b180b4..41cce4a9a3 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs index ff17e3fb1f..21c3ac8a39 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs index 7a9ba40bf0..b1a23d9f66 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index b90d26cb43..e05bf9a801 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index 11574f25f9..4a34fce584 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index ae9e5f97b0..74e6a12815 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs index 1ca4ea0c21..bb6243cf6a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index 74e3df5f45..1e5e9806b3 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index 1100c47aa2..f7e9e5dd78 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index c3006f0cff..73e4785389 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs index d808462aab..1500324444 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs index 81134209bf..f0eb7f41d5 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs index 550c6d8c05..b5ebd2ab7f 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs index 67f6fcf60f..1dc6256128 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index 4c7e63981f..677b96dd64 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs index 88c6983eed..cae01b017f 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 9df515250a..6967b65841 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -1,114 +1,114 @@ -# QuartzNET Instrumentation for OpenTelemetry .NET - -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) - -Automatically instruments the Quartz jobs from -[Quartz](https://www.nuget.org/packages/Quartz/). - -## Supported Frameworks - -QuartzNET Instrumentation is only supported when using .NET Framework >= -`net472` and netstandard >= `netstandard2.0`. Quartz`net461` support for -activity sources has been removed, more information can be found -[here](https://www.quartz-scheduler.net/2021/04/07/quartznet-3-3-released/). - -## Installation - -```shell -dotnet add package OpenTelemetry.Extensions.Hosting -dotnet add package --prerelease OpenTelemetry.Instrumentation.Quartz -``` - -## Configuration - -ASP.NET Core instrumentation example: - -```csharp -// Add QuartzNET inside ConfigureServices -public void ConfigureServices(IServiceCollection services) -{ - services.AddQuartz(q => - { - // base quartz scheduler, job and trigger configuration - }); - - // ASP.NET Core hosting - services.AddQuartzServer(options => - { - // when shutting down we want jobs to complete gracefully - options.WaitForJobsToComplete = true; - }); -} - -// Add OpenTelemetry and Quartz instrumentation -services.AddOpenTelemetryTracing(x => -{ - x.AddQuartzInstrumentation(); - x.UseJaegerExporter(config => { - // Configure Jaeger - }); -}); -``` - -## Filter traced operations - -This option allows you to filter trace operations. - -For example you can trace only execute operations using this snippet: - -```csharp -// ... -using OpenTelemetry.Instrumentation.Quartz.Implementation; -// ... -x.AddQuartzInstrumentation( - opts => - opts.TracedOperations = new - HashSet(new[] { - OperationName.Job.Execute, -})); -``` - -For full operation list please see: -[OperationName](../OpenTelemetry.Instrumentation.Quartz/Implementation/OperationName.cs). - -All operations are enabled by default. - -## Enrich - -This option allows one to enrich the activity with additional information from -the raw `JobDetail` object. The `Enrich` action is called only when -`activity.IsAllDataRequested` is `true`. It contains the activity itself (which -can be enriched), the name of the event, and the actual raw object. - -For event names "OnStartActivity", "OnStopActivity", the actual object will be -`IJobDetail`. - -For event name "OnException", the actual object will be the exception thrown - -The following code snippet shows how to add additional tags using `Enrich`. - -```csharp -// ... -using OpenTelemetry.Instrumentation.Quartz.Implementation; -using Quartz; -// ... -// Enable enriching an activity after it is created. -x.AddQuartzInstrumentation(opt => -{ - opt.Enrich = (activity, eventName, quartzJobDetails) => - { - // update activity - if (quartzJobDetails is IJobDetail jobDetail) - { - activity.SetTag("customProperty", jobDetail.JobDataMap["customProperty"]); - ... - } - }; -}) -``` - -## References - -* [OpenTelemetry Project](https://opentelemetry.io/) -* [Quartz.NET Project](https://www.quartz-scheduler.net/) +# QuartzNET Instrumentation for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) + +Automatically instruments the Quartz jobs from +[Quartz](https://www.nuget.org/packages/Quartz/). + +## Supported Frameworks + +QuartzNET Instrumentation is only supported when using .NET Framework >= +`net472` and netstandard >= `netstandard2.0`. Quartz`net461` support for +activity sources has been removed, more information can be found +[here](https://www.quartz-scheduler.net/2021/04/07/quartznet-3-3-released/). + +## Installation + +```shell +dotnet add package OpenTelemetry.Extensions.Hosting +dotnet add package --prerelease OpenTelemetry.Instrumentation.Quartz +``` + +## Configuration + +ASP.NET Core instrumentation example: + +```csharp +// Add QuartzNET inside ConfigureServices +public void ConfigureServices(IServiceCollection services) +{ + services.AddQuartz(q => + { + // base quartz scheduler, job and trigger configuration + }); + + // ASP.NET Core hosting + services.AddQuartzServer(options => + { + // when shutting down we want jobs to complete gracefully + options.WaitForJobsToComplete = true; + }); +} + +// Add OpenTelemetry and Quartz instrumentation +services.AddOpenTelemetryTracing(x => +{ + x.AddQuartzInstrumentation(); + x.UseJaegerExporter(config => { + // Configure Jaeger + }); +}); +``` + +## Filter traced operations + +This option allows you to filter trace operations. + +For example you can trace only execute operations using this snippet: + +```csharp +// ... +using OpenTelemetry.Instrumentation.Quartz.Implementation; +// ... +x.AddQuartzInstrumentation( + opts => + opts.TracedOperations = new + HashSet(new[] { + OperationName.Job.Execute, +})); +``` + +For full operation list please see: +[OperationName](../OpenTelemetry.Instrumentation.Quartz/Implementation/OperationName.cs). + +All operations are enabled by default. + +## Enrich + +This option allows one to enrich the activity with additional information from +the raw `JobDetail` object. The `Enrich` action is called only when +`activity.IsAllDataRequested` is `true`. It contains the activity itself (which +can be enriched), the name of the event, and the actual raw object. + +For event names "OnStartActivity", "OnStopActivity", the actual object will be +`IJobDetail`. + +For event name "OnException", the actual object will be the exception thrown + +The following code snippet shows how to add additional tags using `Enrich`. + +```csharp +// ... +using OpenTelemetry.Instrumentation.Quartz.Implementation; +using Quartz; +// ... +// Enable enriching an activity after it is created. +x.AddQuartzInstrumentation(opt => +{ + opt.Enrich = (activity, eventName, quartzJobDetails) => + { + // update activity + if (quartzJobDetails is IJobDetail jobDetail) + { + activity.SetTag("customProperty", jobDetail.JobDataMap["customProperty"]); + ... + } + }; +}) +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) +* [Quartz.NET Project](https://www.quartz-scheduler.net/) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index 6869be5a69..f4e6b2127f 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs index 4b7b851acc..c1cb3f4670 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 6aed9f8d3f..a02f696fb5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 426ba225aa..955e8f929a 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs index 6553f07f72..03075c5e75 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs index 4ecd381011..b5227c02e1 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 89731ffb42..9fe12c6e56 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs index 8446fed165..6c5a1ed1ae 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs index e65c92a220..ee32c511f0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index fc52b8751e..e9aade2270 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs index 237a194777..dfba65b372 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs index 9060a90d64..39c32c9c71 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index 34925e2202..cd96f3bd5a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs index f26ce58ea2..bff21a0caf 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index 85bc49975f..bab42d7e92 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index b4ca2ec1ae..41d00e779a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 6569cb5e51..0c6bed3ee6 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index 49adec2727..151292ed6c 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index d8f68af386..06e4498282 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs index 6c30824287..c02c03f98d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs index d0f964917a..d616800688 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs index a40cd05df3..a1df56f16d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index 610935cfa1..2d99b44919 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs index a7df0f66f9..87044abdee 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs index 2226695fbf..cd2c65dc93 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/OpenTelemetry.Internal/Guard.cs b/src/OpenTelemetry.Internal/Guard.cs index aefa4cb7b2..1b6348cd83 100644 --- a/src/OpenTelemetry.Internal/Guard.cs +++ b/src/OpenTelemetry.Internal/Guard.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index da3eb65ef4..43fae9e60c 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,4 +1,4 @@ - \ No newline at end of file + diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs index 152f6abc04..a85613c4c5 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs index 4d6b4703e3..8bee2bb922 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs index 89355260b4..04759a94cd 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs index bb8aecb6e5..61e12837cc 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs index acc242cb9f..5d98b55ca9 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs index 010dcb1aea..4dfa908cbd 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs index bf56817396..dd717189e5 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs index 536fe03a39..4c0c5e8369 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index 1273acabfc..4da54abc8f 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs index 1691c170f5..b69a81f817 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs index ffda294b60..9107f2dec2 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs index 6fa549127e..01098c2be0 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs index ed58fd941b..2d44fb8761 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 762e7ffd9a..e4ec96ee6b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index 40c829ccb7..2e520372c6 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index c5113da663..d4349ade90 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index 102906a2b3..9897910117 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index d894abbe99..0e7314e618 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index fc01bf3d11..79bbeb9bc3 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 084a75386d..96092e2a12 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs index 39c5413601..d7dbde4f11 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 60d05a68d2..4971e4d761 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 6a0bbd63c5..30cb26ec45 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index 80f01e50b0..5152ac9f8c 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 4b37f9ff03..0b0ebe1f34 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs index d85cf7689c..64894b6cf1 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs index c4815ef5b2..0ec90b07b7 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs index d2a6603293..a4f4d94272 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs index 1d1a69e0d1..eff653f063 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 0f31cdcf51..42fa52b2b2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 5e1f72534f..425cfb815c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index 51e25443bc..9b44c6e4dd 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs index 390541c617..2616c540d0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index 156c711670..4521c6f4ed 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index ac92bd010c..e0d264e6a4 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 5939e16d88..c60b3a59ed 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 7edab1856f..9d591c2f0d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index 7b8d52de63..6d615b6dff 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index fd333bac83..1e3d77be64 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 96d81a9d3e..02d5b5bf73 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 955c0b167c..59b830e192 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index de8f559f4d..42f8f18ac7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index b0c2f677e3..30b1538f2d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index 8763ad1155..381f97765d 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs index 82330c1d0c..f92e1a7e26 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 42a85a70ee..98038c5786 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index a2fb74e22c..8bdcea7672 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs index 0cd6b4dba7..6b9dc76681 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs index 8b262b65b6..630c5e692e 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index a51ae08af6..f400cb79c2 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs index 4346fe3156..456eab64e1 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs index ccc0b0234b..d02cf1381a 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs index 9a1ff52517..7a946b399b 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 9e24f5aa1a..ff25a88d16 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index dd40a966ca..62ded2b6e3 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs index 4a08277dd4..e494573ba1 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs index d2dab800ad..0330807f44 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs index 4ca0c48337..8880998195 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 676b92c2ae..93b1687023 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index fc4af7e797..bf885f40cd 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs index b1b0d0f882..4ecc96d307 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index ad0984b7d9..fb272571b5 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs index 4db51f8943..b197b0ce3d 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index fea2754b6e..c549d17f3f 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 6f5369dbba..1d5d8599e6 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index eedb99efad..8becff7c7f 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 730a9bf9eb..86b0179094 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index ec68ba6dfe..2dcfc759e2 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs index acb9ac64e3..2f51f7f84b 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index 1f2d4347e7..6104f263e0 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs index df112c6754..6304f65151 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs index 4f6ec47d18..39e40e8664 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs index cf7b7d8749..5c1bbd8543 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs index f17628be69..aead15ec12 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs index d3d920e730..ba33da4b7d 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs index 2a7a870578..8e059108ed 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 67e7a0bdf9..5655aa9df0 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 90c88e874e..32ec6ddde2 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs index d5631d41e5..05f1fcffa1 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs index b46c3c9c7f..98546ea16e 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs index 373cab8fe7..78dca4b563 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index a25ce5b875..997a62f6d6 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index 61c3d47668..578e3f613c 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 99b317f098..46a29aa7b6 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs index dd23c2ebd1..55fabbfc42 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index 1600995642..127173852e 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index c3109f8231..a8e6b58a15 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs index 76a7fa3a7b..bc6f065e7b 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs index ce08732e7b..6332d79162 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 4cac874196..92abafbe02 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 44e3508935..d172ae8ec9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index 09439bef39..353cd624de 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index 4b8e9f3ebc..60da5eca97 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index 046a53fe03..e8856e2847 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); From 827eb256890889aeb72d0d641beb92ebd9819b94 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 25 May 2022 19:25:46 -0700 Subject: [PATCH 0138/1499] Allow serialization of Unicode characters for Exception type (#375) * Allow serialization of Unicode characters for Exception type --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ .../GenevaLogExporter.cs | 2 +- .../GenevaLogExporterTests.cs | 13 +++++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 098f363cdd..8d34b86063 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -15,6 +15,10 @@ `StatusDescription`. [359](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/359) +* Allow serialization of non-ASCII characters for +`LogRecord.Exception.GetType().FullName`. +[375](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/375) + ## 1.2.6 [2022-Apr-21] * Set GenevaMetricExporter temporality preference back to Delta. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 60089b093e..175421f70c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -354,7 +354,7 @@ internal int SerializeLogRecord(LogRecord logRecord) if (logRecord.Exception != null) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_type"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logRecord.Exception.GetType().FullName); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.GetType().FullName); cntFields += 1; cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_msg"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 9d591c2f0d..45a4833f4e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -605,11 +605,15 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin logger.LogInformation("Hello World!"); // unstructured logging logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {food} {price}.", "artichoke", 3.99); + // Exception with a non-ASCII character in its type name + logger.LogError(new CustomException\u0418(), "Hello from {food} {price}.", "artichoke", 3.99); + var loggerWithDefaultCategory = loggerFactory.CreateLogger("DefaultCategory"); loggerWithDefaultCategory.LogInformation("Basic test"); + loggerWithDefaultCategory.LogInformation("\u0418"); // Include non-ASCII characters in the message - // logRecordList should have 12 logRecord entries as there were 12 Log calls - Assert.Equal(12, logRecordList.Count); + // logRecordList should have 14 logRecord entries as there were 14 Log calls + Assert.Equal(14, logRecordList.Count); var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; @@ -924,5 +928,10 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter // Epilouge Assert.Equal("DateTime", timeFormat["TimeFormat"]); } + + // A custom exception class with non-ASCII character in the type name + private class CustomException\u0418 : Exception + { + } } } From 21f73d394a9877a58944dc11257a2792c4f13260 Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Fri, 27 May 2022 18:45:13 +0200 Subject: [PATCH 0139/1499] Instana exporter span duration fix (#376) --- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 7 ++++++- .../Implementation/InstanaSpanSerializer.cs | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index edc969a77d..d1cf2c90c2 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,7 +2,12 @@ ## Unreleased +## 1.0.1 [2022-May-25] + +* Instana span duration was not calculated correctly +[376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/376) + ## 1.0.0 [2022-May-24] -This is the first release of the `OpenTelemetry.Exporter.Instana` +* This is the first release of the `OpenTelemetry.Exporter.Instana` project. diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 68bc0b8715..91fc38ca92 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -82,7 +82,7 @@ internal async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, Stream await writer.WriteAsync(COMMA); await this.AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer); await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync(instanaSpan.D, "d", writer); + await this.AppendPropertyAsync((long)(instanaSpan.D / 10_000), "d", writer); await writer.WriteAsync(COMMA); await this.AppendObjectAsync(this.SerializeDataAsync, "data", instanaSpan, writer); await writer.WriteAsync(COMMA); From e737171a2467e09ef19b98d71d07e46a112d7500 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 27 May 2022 12:00:56 -0700 Subject: [PATCH 0140/1499] Update CHANGELOG for 1.3.0-beta.1 release (#381) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 8d34b86063..b8b6312636 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,7 +2,9 @@ ## Unreleased -* PassThru TableNameMappings using the logger category name. +## 1.3.0-beta.1 [2022-May-27] + +* Enable PassThru TableNameMappings using the logger category name. [345](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/345) * Throw exception when `TableNameMappings` contains a `null` value. From 9f56913878d9a2a92338f611f80e1be3dd9b6723 Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Thu, 2 Jun 2022 22:31:04 +0200 Subject: [PATCH 0141/1499] [Exporter.Instana] Check if env vars are defined (#385) * [Exporter.Instana] Check if env vars are defined * Update CHANGELOG.md * Wrong release version --- .../CHANGELOG.md | 5 +++++ .../Implementation/SpanSender.cs | 5 ++++- .../Implementation/Transport.cs | 21 ++++++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index d1cf2c90c2..78dcba1e6c 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 1.0.2 [2022-Jun-02] + +* Application is chrashing if environment variables are not defined +[385](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/385) + ## 1.0.1 [2022-May-25] * Instana span duration was not calculated correctly diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index 5a9c5cbe4b..ee1216b56d 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -33,7 +33,10 @@ public SpanSender() public void Enqueue(InstanaSpan instanaSpan) { - this.spansQueue.Enqueue(instanaSpan); + if (this.transport.IsAvailable) + { + this.spansQueue.Enqueue(instanaSpan); + } } private async void TaskSpanSender() diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index ec4749607d..a8f5176305 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -29,7 +29,7 @@ internal class Transport private static readonly InstanaSpanSerializer InstanaSpanSerializer = new InstanaSpanSerializer(); private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); - private static bool wasConfigured = false; + private static bool isConfigured = false; private static int backendTimeout = 0; private static string configuredEndpoint = string.Empty; private static string configuredAgentKey = string.Empty; @@ -43,6 +43,11 @@ static Transport() Configure(); } + internal bool IsAvailable + { + get { return isConfigured && client != null; } + } + internal async Task SendSpansAsync(ConcurrentQueue spanQueue) { using (MemoryStream sendBuffer = new MemoryStream(this.tracesBuffer)) @@ -87,7 +92,7 @@ internal async Task SendSpansAsync(ConcurrentQueue spanQueue) private static void Configure() { - if (wasConfigured) + if (isConfigured) { return; } @@ -97,6 +102,11 @@ private static void Configure() configuredEndpoint = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_URL); } + if (string.IsNullOrEmpty(configuredEndpoint)) + { + return; + } + bundleUrl = configuredEndpoint + "/bundle"; if (string.IsNullOrEmpty(configuredAgentKey)) @@ -104,6 +114,11 @@ private static void Configure() configuredAgentKey = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_AGENT_KEY); } + if (string.IsNullOrEmpty(configuredAgentKey)) + { + return; + } + if (backendTimeout == 0) { if (!int.TryParse(Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_TIMEOUT), out backendTimeout)) @@ -113,7 +128,7 @@ private static void Configure() } ConfigureBackendClient(); - wasConfigured = true; + isConfigured = true; } private static void ConfigureBackendClient() From 9461a1c3d3818ff5434099fbdb303b8c57b41852 Mon Sep 17 00:00:00 2001 From: fred2u Date: Fri, 3 Jun 2022 00:03:11 +0200 Subject: [PATCH 0142/1499] Update CHANGELOG for 1.0.0-beta.1 release (#387) Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index e9f6c2776d..619eb71eb3 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -## 1.2.0-beta1 +## 1.0.0-beta.1 * Updated OTel SDK package version to 1.2.0 ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) From 3f7f1ae70de72e474288fdb47843f62ffffe1516 Mon Sep 17 00:00:00 2001 From: fred2u Date: Fri, 3 Jun 2022 08:21:42 +0200 Subject: [PATCH 0143/1499] Add workflow for Hangfire instrumentation (#388) --- .../package-Instrumentation.Hangfire.yml | 49 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 1 + 2 files changed, 50 insertions(+) create mode 100644 .github/workflows/package-Instrumentation.Hangfire.yml diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml new file mode 100644 index 0000000000..31801c6e3e --- /dev/null +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Instrumentation.Hangfire + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.Hangfire-*' # trigger when we create a tag with prefix "Instrumentation.Hangfire-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.Hangfire + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 4e2ca5ca08..e12d5d925f 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -42,6 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml + .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml From 3571326e8a3148638824166a91b0e6f4b2549f42 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 3 Jun 2022 14:21:06 -0700 Subject: [PATCH 0144/1499] [Exporter.Geneva] Add support for ILogger scopes (#390) * Add support for ILogger scopes --- .../CHANGELOG.md | 3 ++ .../GenevaLogExporter.cs | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index b8b6312636..f4cbd6abbd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add support for exporting `ILogger` scopes. +[390](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/390) + ## 1.3.0-beta.1 [2022-May-27] * Enable PassThru TableNameMappings using the logger category name. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 175421f70c..a22c7eb013 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -418,6 +418,44 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; } + ushort scopeDepth = 0; + int indexArrayLength = 0; + logRecord.ForEachScope(ProcessScope, (object)null); + void ProcessScope(LogRecordScope scope, object state) + { + if (++scopeDepth == 1) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "scopes"); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); + indexArrayLength = cursor - 2; + } + + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int indexMapSizeScope = cursor - 2; + ushort keysCount = 0; + + foreach (KeyValuePair scopeItem in scope) + { + string key = "scope"; + if (!string.IsNullOrEmpty(scopeItem.Key)) + { + key = scopeItem.Key; + } + + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); + keysCount++; + } + + MessagePackSerializer.WriteUInt16(buffer, indexMapSizeScope, keysCount); + } + + if (scopeDepth > 0) + { + MessagePackSerializer.WriteUInt16(buffer, indexArrayLength, scopeDepth); + cntFields += 1; + } + if (hasEnvProperties) { // Iteration #2 - Get all "other" fields and collapse them into single field From 07d02a47f59fcc186fbd66c4be30d49329cf1447 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 3 Jun 2022 14:29:20 -0700 Subject: [PATCH 0145/1499] Update CHANGELOG for 1.3.0-beta.2 (#392) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f4cbd6abbd..da09c8fbf8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.3.0-beta.2 [2022-Jun-03] + * Add support for exporting `ILogger` scopes. [390](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/390) From 830caf1382ae35606e0a5913f07a8992dc279a7e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 6 Jun 2022 15:03:08 -0700 Subject: [PATCH 0146/1499] [Instrumentation.StackExchangeRedis] Add example for StackExchangeRedis instrumentation (#384) * Add examples for Redis instrumentation --- .../Examples.StackExchangeRedis.csproj | 18 ++++++ .../Examples.StackExchangeRedis/Program.cs | 58 +++++++++++++++++++ .../Examples.StackExchangeRedis/README.md | 5 ++ opentelemetry-dotnet-contrib.sln | 10 ++++ 4 files changed, 91 insertions(+) create mode 100644 examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj create mode 100644 examples/redis/Examples.StackExchangeRedis/Program.cs create mode 100644 examples/redis/Examples.StackExchangeRedis/README.md diff --git a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj new file mode 100644 index 0000000000..a71e757976 --- /dev/null +++ b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj @@ -0,0 +1,18 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + diff --git a/examples/redis/Examples.StackExchangeRedis/Program.cs b/examples/redis/Examples.StackExchangeRedis/Program.cs new file mode 100644 index 0000000000..1ab8a0de5d --- /dev/null +++ b/examples/redis/Examples.StackExchangeRedis/Program.cs @@ -0,0 +1,58 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using OpenTelemetry; +using OpenTelemetry.Trace; +using StackExchange.Redis; + +namespace GettingStartedPrometheusGrafana; + +public class Program +{ + public static ActivitySource RedisActivitySource = new("redis-test"); + + public static void Main() + { + // Prerequisite: + /* + * Setup redis service inside local docker. + * docker run --name opentelemetry-redis-test -d -p 6379:6379 redis + */ + + // connect to the redis server. The default port 6379 will be used. + var connection = ConnectionMultiplexer.Connect("localhost"); + + // Configure exporter to export traces to Zipkin + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddConsoleExporter() + .AddRedisInstrumentation(connection, options => + { + // changing flushinterval from 10s to 5s + options.FlushInterval = TimeSpan.FromSeconds(5); + }) + .AddSource(RedisActivitySource.Name) + .Build(); + + // select a database (by default, DB = 0) + var db = connection.GetDatabase(); + db.StringSet("key", "value " + DateTime.Now.ToLongDateString()); + Thread.Sleep(1000); + + // run a command, in this case a GET + var myVal = db.StringGet("key"); + } +} diff --git a/examples/redis/Examples.StackExchangeRedis/README.md b/examples/redis/Examples.StackExchangeRedis/README.md new file mode 100644 index 0000000000..dbf370a591 --- /dev/null +++ b/examples/redis/Examples.StackExchangeRedis/README.md @@ -0,0 +1,5 @@ +# StackExchangeRedis Instrumentation for OpenTelemetry .NET - Example + +An example application that shows how to use +`OpenTelemetry.Instrumentation.StackExchangeRedis` to capture traces of outgoing +calls to Redis. diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e12d5d925f..ae6a804c85 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -196,6 +196,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests", "test\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests\OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj", "{2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "redis", "redis", "{D8F9AEAC-6ACA-484E-81A5-9CEBEDBC3422}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.StackExchangeRedis", "examples\redis\Examples.StackExchangeRedis\Examples.StackExchangeRedis.csproj", "{DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -406,6 +410,10 @@ Global {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Debug|Any CPU.Build.0 = Debug|Any CPU {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.ActiveCfg = Release|Any CPU {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4}.Release|Any CPU.Build.0 = Release|Any CPU + {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -468,6 +476,8 @@ Global {77E7DDB9-32CF-450E-B596-E893149D07DD} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {14BAEC26-CCD1-44B5-94D7-F219057B0B4D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {D8F9AEAC-6ACA-484E-81A5-9CEBEDBC3422} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1} = {D8F9AEAC-6ACA-484E-81A5-9CEBEDBC3422} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From e3abb7ce4bd88b2878ef20d763d1d6cdcf0f4acb Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 6 Jun 2022 16:25:52 -0700 Subject: [PATCH 0147/1499] Update RedisInstrumentation (#396) * Update OTel API version to 1.3.0 * Update RedisInstrumeation example --- .../Examples.StackExchangeRedis/Program.cs | 3 -- .../Examples.StackExchangeRedis/README.md | 52 ++++++++++++++++++- .../CHANGELOG.md | 3 ++ ....Instrumentation.StackExchangeRedis.csproj | 4 +- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/examples/redis/Examples.StackExchangeRedis/Program.cs b/examples/redis/Examples.StackExchangeRedis/Program.cs index 1ab8a0de5d..9216209548 100644 --- a/examples/redis/Examples.StackExchangeRedis/Program.cs +++ b/examples/redis/Examples.StackExchangeRedis/Program.cs @@ -23,8 +23,6 @@ namespace GettingStartedPrometheusGrafana; public class Program { - public static ActivitySource RedisActivitySource = new("redis-test"); - public static void Main() { // Prerequisite: @@ -44,7 +42,6 @@ public static void Main() // changing flushinterval from 10s to 5s options.FlushInterval = TimeSpan.FromSeconds(5); }) - .AddSource(RedisActivitySource.Name) .Build(); // select a database (by default, DB = 0) diff --git a/examples/redis/Examples.StackExchangeRedis/README.md b/examples/redis/Examples.StackExchangeRedis/README.md index dbf370a591..dcc81d8007 100644 --- a/examples/redis/Examples.StackExchangeRedis/README.md +++ b/examples/redis/Examples.StackExchangeRedis/README.md @@ -2,4 +2,54 @@ An example application that shows how to use `OpenTelemetry.Instrumentation.StackExchangeRedis` to capture traces of outgoing -calls to Redis. +calls to Redis. You should see the following output on the Console when you run +this application (please look at the prerequisite for running the application in +[Program.cs](./Program.cs): + +```text +Activity.TraceId: f1a47baec558ebb97e57a6fb7d029a29 +Activity.SpanId: d0abf2503ad3d1b6 +Activity.TraceFlags: Recorded +Activity.ActivitySourceName: OpenTelemetry.StackExchange.Redis +Activity.DisplayName: SET +Activity.Kind: Client +Activity.StartTime: 2022-06-06T22:17:40.8927802Z +Activity.Duration: 00:00:00.0237767 +Activity.Tags: + db.system: redis + db.redis.flags: DemandMaster + db.statement: SET + net.peer.name: localhost + net.peer.port: 6379 + db.redis.database_index: 0 + StatusCode : UNSET +Activity.Events: + Enqueued [6/6/2022 10:17:40 PM +00:00] + Sent [6/6/2022 10:17:40 PM +00:00] + ResponseReceived [6/6/2022 10:17:40 PM +00:00] +Resource associated with Activity: + service.name: unknown_service:Examples.StackExchangeRedis + +Activity.TraceId: 0db37d796826693e23b17e3b082356a4 +Activity.SpanId: cd01d518b8b5cfa2 +Activity.TraceFlags: Recorded +Activity.ActivitySourceName: OpenTelemetry.StackExchange.Redis +Activity.DisplayName: GET +Activity.Kind: Client +Activity.StartTime: 2022-06-06T22:17:41.9223474Z +Activity.Duration: 00:00:00.0067062 +Activity.Tags: + db.system: redis + db.redis.flags: None + db.statement: GET + net.peer.name: localhost + net.peer.port: 6379 + db.redis.database_index: 0 + StatusCode : UNSET +Activity.Events: + Enqueued [6/6/2022 10:17:41 PM +00:00] + Sent [6/6/2022 10:17:41 PM +00:00] + ResponseReceived [6/6/2022 10:17:41 PM +00:00] +Resource associated with Activity: + service.name: unknown_service:Examples.StackExchangeRedis +``` diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 348502a14d..a4b1684e09 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel API package version to 1.3.0 + [#396](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/396) + ## 1.0.0-rc9.3 Released 2022-Apr-15 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 85121d6aa3..0c242324cf 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net462 @@ -15,7 +15,7 @@ - + From 480440a3e1f7f7413dff62dd613ed2dde8a71998 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 6 Jun 2022 16:50:28 -0700 Subject: [PATCH 0148/1499] [Exporter.Geneva] Add DI support for GenevaMetricExporter (#397) * Add DI support for GenevaMetricExporter --- .../CHANGELOG.md | 4 ++++ .../GenevaMetricExporterExtensions.cs | 21 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index da09c8fbf8..e614f2693c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Supports `OpenTelemetry.Extensions.Hosting` based configuration for +`GenevaMetricExporter`. +[397](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/397) + ## 1.3.0-beta.2 [2022-Jun-03] * Add support for exporting `ILogger` scopes. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs index d086680135..d2f37a5ee0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs @@ -22,12 +22,29 @@ namespace OpenTelemetry.Exporter.Geneva; public static class GenevaMetricExporterExtensions { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The objects should not be disposed.")] + /// + /// Adds to the . + /// + /// builder to use. + /// Exporter configuration options. + /// The instance of to chain the calls. public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure = null) { Guard.ThrowIfNull(builder); - var options = new GenevaMetricExporterOptions(); + if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + { + return deferredMeterProviderBuilder.Configure((sp, builder) => + { + AddGenevaMetricExporter(builder, sp.GetOptions(), configure); + }); + } + + return AddGenevaMetricExporter(builder, new GenevaMetricExporterOptions(), configure); + } + + private static MeterProviderBuilder AddGenevaMetricExporter(MeterProviderBuilder builder, GenevaMetricExporterOptions options, Action configure = null) + { configure?.Invoke(options); return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) { TemporalityPreference = MetricReaderTemporalityPreference.Delta }); From 6f51e048166b0bcc6919e7ccebc425fc5f2f5195 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 6 Jun 2022 17:25:19 -0700 Subject: [PATCH 0149/1499] [Instrumenation.StackExchangeRedis] Update CHANGELOG for RedisInstrumentation for 1.0.0-rc9.5 release (#398) * Update CHANGELOG for RedisInstrumentation for 1.0.0-rc9.5 release --- .../CHANGELOG.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index a4b1684e09..6c2995f73f 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,8 +2,20 @@ ## Unreleased -* Updated OTel API package version to 1.3.0 - [#396](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/396) +## 1.0.0-rc9.5 (source code moved to contrib repo) + +Released 2022-Jun-06 + +* From this version onwards, the source code for this package would be hosted in + the + [contrib](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.StackExchangeRedis) + repo. The source code for this package before this version was hosted on the + [main](https://github.com/open-telemetry/opentelemetry-dotnet/tree/core-1.3.0/src/OpenTelemetry.Instrumentation.StackExchangeRedis) + repo. + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 ## 1.0.0-rc9.3 From cff041066bad7e2fa93ba7edcce94a4ddf534873 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 6 Jun 2022 21:07:53 -0700 Subject: [PATCH 0150/1499] [Instrumentation.StackExchangeRedis] Add integration workflow (#399) --- .github/workflows/integration.yml | 24 ++++++++++++++++++++++++ build/docker-compose.net6.0.yml | 8 ++++++++ build/docker-compose.netcoreapp3.1.yml | 8 ++++++++ opentelemetry-dotnet-contrib.sln | 3 +++ 4 files changed, 43 insertions(+) create mode 100644 .github/workflows/integration.yml create mode 100644 build/docker-compose.net6.0.yml create mode 100644 build/docker-compose.netcoreapp3.1.yml diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 0000000000..b369d1131b --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,24 @@ +name: Integration Tests + +on: + push: + branches: [ main ] + paths-ignore: + - '**.md' + pull_request: + branches: [ main ] + paths-ignore: + - '**.md' + +jobs: + redis-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: [netcoreapp3.1,net6.0] + steps: + - uses: actions/checkout@v3 + + - name: Run redis docker-compose.integration + run: docker-compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build diff --git a/build/docker-compose.net6.0.yml b/build/docker-compose.net6.0.yml new file mode 100644 index 0000000000..c1a9529c51 --- /dev/null +++ b/build/docker-compose.net6.0.yml @@ -0,0 +1,8 @@ +version: '3.7' + +services: + tests: + build: + args: + PUBLISH_FRAMEWORK: net6.0 + SDK_VERSION: 6.0 diff --git a/build/docker-compose.netcoreapp3.1.yml b/build/docker-compose.netcoreapp3.1.yml new file mode 100644 index 0000000000..4d45fa1b3e --- /dev/null +++ b/build/docker-compose.netcoreapp3.1.yml @@ -0,0 +1,8 @@ +version: '3.7' + +services: + tests: + build: + args: + PUBLISH_FRAMEWORK: netcoreapp3.1 + SDK_VERSION: 3.1 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ae6a804c85..631728d407 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -28,6 +28,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml + .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml @@ -61,6 +62,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.props = build\Common.props build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk + build\docker-compose.net6.0.yml = build\docker-compose.net6.0.yml + build\docker-compose.netcoreapp3.1.yml = build\docker-compose.netcoreapp3.1.yml build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset From 04c64a93c4eb07f274da7db552c54b837abd042e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 8 Jun 2022 09:13:37 -0700 Subject: [PATCH 0151/1499] [Solution] Fix build CI (#402) --- .github/workflows/linux-ci.yml | 2 +- .github/workflows/windows-ci.yml | 2 +- .../Resources/Http/TestHandler.cs | 1 - ...TestServerCertificateValidationProvider.cs | 1 - .../ConnectionStringBuilderTests.cs | 11 - .../GenevaLogExporterTests.cs | 308 ++++++++++-------- .../GenevaMetricExporterTests.cs | 225 +++++++------ .../GenevaTraceExporterTests.cs | 297 ++++++++--------- .../MessagePackSerializerTests.cs | 9 - ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 15 +- .../UnixDomainSocketDataTransportTests.cs | 279 ++++++++-------- .../InstanaSpanSerializerTests.cs | 2 +- .../ElasticsearchClientTests.cs | 4 +- 13 files changed, 589 insertions(+), 567 deletions(-) diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index e369e8343f..b4d9e3b2a5 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -29,4 +29,4 @@ jobs: run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" --filter "Platform=Any|Platform=Linux" + run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index f5ee113db5..179577c9bc 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -29,4 +29,4 @@ jobs: run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" --filter "Platform=Any|Platform=Windows" + run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs index 8bee2bb922..559e8363c9 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs @@ -19,7 +19,6 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http { - [Trait("Platform", "Any")] public class TestHandler { private const string INVALIDCRTNAME = "invalidcert"; diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs index 04759a94cd..65d46676c5 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs @@ -20,7 +20,6 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http { - [Trait("Platform", "Any")] public class TestServerCertificateValidationProvider { private const string INVALIDCRTNAME = "invalidcert"; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index c60b3a59ed..9f579c0b8e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -22,7 +22,6 @@ namespace OpenTelemetry.Exporter.Geneva.Tests public class ConnectionStringBuilderTests { [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_constructor_Invalid_Input() { // null connection string @@ -48,7 +47,6 @@ public void ConnectionStringBuilder_constructor_Invalid_Input() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_constructor_Duplicated_Keys() { var builder = new ConnectionStringBuilder("Account=value1;Account=VALUE2"); @@ -56,7 +54,6 @@ public void ConnectionStringBuilder_constructor_Duplicated_Keys() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_Protocol_No_Default_Value() { var builder = new ConnectionStringBuilder("key1=value1"); @@ -76,7 +73,6 @@ public void ConnectionStringBuilder_Protocol_No_Default_Value() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_EtwSession() { var builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); @@ -91,7 +87,6 @@ public void ConnectionStringBuilder_EtwSession() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_Endpoint_UnixDomainSocketPath() { var builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); @@ -112,7 +107,6 @@ public void ConnectionStringBuilder_Endpoint_UnixDomainSocketPath() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_TimeoutMilliseconds() { var builder = new ConnectionStringBuilder("TimeoutMilliseconds=10000"); @@ -141,7 +135,6 @@ public void ConnectionStringBuilder_TimeoutMilliseconds() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_Endpoint_Udp() { var builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11111"); @@ -168,7 +161,6 @@ public void ConnectionStringBuilder_Endpoint_Udp() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_Endpoint_Tcp() { var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333"); @@ -195,7 +187,6 @@ public void ConnectionStringBuilder_Endpoint_Tcp() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_EtwSession_Endpoint_Both_Set() { var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333;EtwSession=OpenTelemetry"); @@ -209,7 +200,6 @@ public void ConnectionStringBuilder_EtwSession_Endpoint_Both_Set() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_MonitoringAccount_No_Default_Value() { var builder = new ConnectionStringBuilder("key1=value1"); @@ -223,7 +213,6 @@ public void ConnectionStringBuilder_MonitoringAccount_No_Default_Value() } [Fact] - [Trait("Platform", "Any")] public void ConnectionStringBuilder_Keywords_Are_Case_Sensitive() { var builder = new ConnectionStringBuilder("etwSession=OpenTelemetry"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 45a4833f4e..c665fe85d2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -33,7 +33,6 @@ namespace OpenTelemetry.Exporter.Geneva.Tests public class GenevaLogExporterTests { [Fact] - [Trait("Platform", "Any")] public void BadArgs() { GenevaExporterOptions exporterOptions = null; @@ -44,7 +43,6 @@ public void BadArgs() } [Fact] - [Trait("Platform", "Any")] public void SpecialChractersInTableNameMappings() { Assert.Throws(() => @@ -88,7 +86,6 @@ public void SpecialChractersInTableNameMappings() [InlineData(null)] [InlineData("")] [InlineData(" ")] - [Trait("Platform", "Any")] public void InvalidConnectionString(string connectionString) { var exporterOptions = new GenevaExporterOptions() { ConnectionString = connectionString }; @@ -99,27 +96,31 @@ public void InvalidConnectionString(string connectionString) } [Fact] - [Trait("Platform", "Windows")] - public void IncompatibleConnectionStringOnWindows() + public void IncompatibleConnectionString_Windows() { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; - var exception = Assert.Throws(() => + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - using var exporter = new GenevaLogExporter(exporterOptions); - }); - Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); + } } [Fact] - [Trait("Platform", "Linux")] - public void IncompatibleConnectionStringOnLinux() + public void IncompatibleConnectionString_Linux() { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; - var exception = Assert.Throws(() => + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - using var exporter = new GenevaLogExporter(exporterOptions); - }); - Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); + } } [Theory] @@ -128,7 +129,6 @@ public void IncompatibleConnectionStringOnLinux() [InlineData("categoryA", "TableA", "categoryB", "TableB")] [InlineData("categoryA", "TableA", "*", "CatchAll")] [InlineData(null)] - [Trait("Platform", "Any")] public void TableNameMappingTest(params string[] category) { // ARRANGE @@ -229,17 +229,20 @@ public void TableNameMappingTest(params string[] category) } [Fact] - [Trait("Platform", "Any")] public void PassThruTableMappingsWhenTheRuleIsEnabled() { - var userInitializedCategoryToTableNameMappings = new Dictionary + string path = string.Empty; + Socket server = null; + try { - ["Company.Store"] = "Store", - ["Company.Orders"] = "Orders", - ["*"] = "*", - }; + var userInitializedCategoryToTableNameMappings = new Dictionary + { + ["Company.Store"] = "Store", + ["Company.Orders"] = "Orders", + ["*"] = "*", + }; - var expectedCategoryToTableNameList = new List> + var expectedCategoryToTableNameList = new List> { // The category name must match "^[A-Z][a-zA-Z0-9]*$"; any character that is not allowed will be removed. new KeyValuePair("Company.Customer", "CompanyCustomer"), @@ -263,70 +266,94 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() new KeyValuePair("1.2", null), }; - var logRecordList = new List(); - var exporterOptions = new GenevaExporterOptions - { - TableNameMappings = userInitializedCategoryToTableNameMappings, - ConnectionString = "EtwSession=OpenTelemetry", - }; + var logRecordList = new List(); + var exporterOptions = new GenevaExporterOptions + { + TableNameMappings = userInitializedCategoryToTableNameMappings, + }; - using var loggerFactory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(options => - { - options.AddInMemoryExporter(logRecordList); - }) - .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); - ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; - ThreadLocal m_buffer; - object fluentdData; - string actualTableName; - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; + ThreadLocal m_buffer; + object fluentdData; + string actualTableName; + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. - foreach (var mapping in userInitializedCategoryToTableNameMappings) - { - if (mapping.Key != "*") + // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. + foreach (var mapping in userInitializedCategoryToTableNameMappings) { - userInitializedTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); - userInitializedTableMappingsLogger.LogInformation("This information does not matter."); + if (mapping.Key != "*") + { + userInitializedTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); + userInitializedTableMappingsLogger.LogInformation("This information does not matter."); + Assert.Single(logRecordList); + + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + userInitializedCategoryToTableNameMappings.TryGetValue(mapping.Key, out var expectedTableNme); + Assert.Equal(expectedTableNme, actualTableName); + + logRecordList.Clear(); + } + } + + // Verify that when the "*" = "*" were enabled, the correct table names were being deduced following the set of rules. + foreach (var mapping in expectedCategoryToTableNameList) + { + passThruTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); + passThruTableMappingsLogger.LogInformation("This information does not matter."); Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); actualTableName = (fluentdData as object[])[0] as string; - userInitializedCategoryToTableNameMappings.TryGetValue(mapping.Key, out var expectedTableNme); - Assert.Equal(expectedTableNme, actualTableName); + string expectedTableName = string.Empty; + expectedTableName = mapping.Value; + Assert.Equal(expectedTableName, actualTableName); logRecordList.Clear(); } } - - // Verify that when the "*" = "*" were enabled, the correct table names were being deduced following the set of rules. - foreach (var mapping in expectedCategoryToTableNameList) + finally { - passThruTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); - passThruTableMappingsLogger.LogInformation("This information does not matter."); - Assert.Single(logRecordList); - - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - actualTableName = (fluentdData as object[])[0] as string; - string expectedTableName = string.Empty; - expectedTableName = mapping.Value; - Assert.Equal(expectedTableName, actualTableName); - - logRecordList.Clear(); + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } } } [Theory] [InlineData(true)] [InlineData(false)] - [Trait("Platform", "Any")] public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) { // Dedicated test for the raw ILogger.Log method @@ -508,7 +535,6 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) [InlineData(false, true, true)] [InlineData(true, false, true)] [InlineData(true, true, true)] - [Trait("Platform", "Any")] public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) { string path = string.Empty; @@ -638,58 +664,26 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin } [Fact] - [Trait("Platform", "Windows")] - public void SuccessfulExportOnWindows() + public void SuccessfulExport_Windows() { - var exporterOptions = new GenevaExporterOptions() - { - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; - - using var loggerFactory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(options => + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - options.AddGenevaLogExporter(options => + var exporterOptions = new GenevaExporterOptions() { - options.ConnectionString = "EtwSession=OpenTelemetry"; - options.PrepopulatedFields = new Dictionary + PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", ["cloud.roleInstance"] = "CY1SCH030021417", ["cloud.roleVer"] = "9.0.15289.2", - }; - }); - })); - - var logger = loggerFactory.CreateLogger(); - - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - } - - [Fact] - [Trait("Platform", "Linux")] - public void SuccessfulExportOnLinux() - { - string path = GenerateTempFilePath(); - var logRecordList = new List(); - try - { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + }, + }; using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddGenevaLogExporter(options => { - options.ConnectionString = "Endpoint=unix:" + path; + options.ConnectionString = "EtwSession=OpenTelemetry"; options.PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", @@ -697,49 +691,85 @@ public void SuccessfulExportOnLinux() ["cloud.roleVer"] = "9.0.15289.2", }; }); - options.AddInMemoryExporter(logRecordList); })); - using var serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 10000; - // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - using var exporter = new GenevaLogExporter(new GenevaExporterOptions + var logger = loggerFactory.CreateLogger(); + + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + } + + [Fact] + public void SuccessfulExportOnLinux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + string path = GenerateTempFilePath(); + var logRecordList = new List(); + try { - ConnectionString = "Endpoint=unix:" + path, - PrepopulatedFields = new Dictionary + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }); + options.AddGenevaLogExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + options.AddInMemoryExporter(logRecordList); + })); + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; + + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + using var exporter = new GenevaLogExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); - // Emit a LogRecord and grab a copy of internal buffer for validation. - var logger = loggerFactory.CreateLogger(); + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - // logRecordList should have a singleLogRecord entry after the logger.LogInformation call - Assert.Single(logRecordList); + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); - int messagePackDataSize; - messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + int messagePackDataSize; + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); - // Validation - Assert.Equal(messagePackDataSize, receivedDataSize); - } - finally - { - try - { - File.Delete(path); + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); } - catch + finally { + try + { + File.Delete(path); + } + catch + { + } } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 1e3d77be64..746b413c00 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -35,7 +35,6 @@ namespace OpenTelemetry.Exporter.Geneva.Tests public class GenevaMetricExporterTests { [Fact] - [Trait("Platform", "Any")] public void NullExporterOptions() { GenevaMetricExporterOptions exporterOptions = null; @@ -46,7 +45,6 @@ public void NullExporterOptions() [InlineData(null)] [InlineData("")] [InlineData(" ")] - [Trait("Platform", "Any")] public void InvalidConnectionString(string connectionString) { var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = connectionString }; @@ -57,7 +55,6 @@ public void InvalidConnectionString(string connectionString) } [Fact] - [Trait("Platform", "Any")] public void ParseConnectionStringCorrectly() { string path = string.Empty; @@ -101,7 +98,6 @@ public void ParseConnectionStringCorrectly() [Theory] [InlineData(false)] [InlineData(true)] - [Trait("Platform", "Any")] public void SuccessfulSerialization(bool testMaxLimits) { using var meter = new Meter("SuccessfulSerialization", "0.0.1"); @@ -263,7 +259,6 @@ public void SuccessfulSerialization(bool testMaxLimits) } [Fact] - [Trait("Platform", "Any")] public void SuccessfulSerializationWithViews() { using var meter = new Meter("SuccessfulSerializationWithViews", "0.0.1"); @@ -457,126 +452,128 @@ public void SuccessfulSerializationWithViews() } [Fact] - [Trait("Platform", "Linux")] public void SuccessfulExportOnLinux() { - string path = GenerateTempFilePath(); - var exportedItems = new List(); - - using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); - var counter = meter.CreateCounter("counter"); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + string path = GenerateTempFilePath(); + var exportedItems = new List(); - using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); - var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); + using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); + var counter = meter.CreateCounter("counter"); - try - { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); + var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + try { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); - // Set up two different providers as only one Metric Processor is allowed. - // TODO: Simplify the setup when multiple Metric processors are allowed. - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulExportOnLinux") - .AddGenevaMetricExporter(options => + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - options.MetricExportIntervalMilliseconds = 5000; - }) - .Build(); - - using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("InMemoryExportOnLinux") - .AddReader(inMemoryReader) - .Build(); - - using var serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 15000; - - // Create a test exporter to get byte data for validation of the data received via Socket. - var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - using var exporter = new GenevaMetricExporter(exporterOptions); - - // Emit a metric and grab a copy of internal buffer for validation. - counter.Add( - 123, - new KeyValuePair("tag1", "value1"), - new KeyValuePair("tag2", "value2")); - - inMemoryCounter.Add( - 123, - new KeyValuePair("tag1", "value1"), - new KeyValuePair("tag2", "value2")); - - // exportedItems list should have a single entry after the MetricReader.Collect call - inMemoryReader.Collect(); - - Assert.Single(exportedItems); - - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); - var metricData = new MetricData { UInt64Value = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - - // Wait a little more than the ExportInterval for the exporter to export the data. - Task.Delay(5500).Wait(); - - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); - - var fixedPayloadLength = (int)typeof(GenevaMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); - - // The whole payload is sent to the Unix Domain Socket - // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload - Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); - - var stream = new KaitaiStream(receivedData); - var data = new MetricsContract(stream); - - Assert.Equal(metric.Name, data.Body.MetricName.Value); - Assert.Equal("OTelMonitoringAccount", data.Body.MetricAccount.Value); - Assert.Equal("OTelMetricNamespace", data.Body.MetricNamespace.Value); - - var valueSection = data.Body.ValueSection as SingleUint64Value; - Assert.Equal(metricDataValue, valueSection.Value); - - Assert.Equal(2, data.Body.NumDimensions); - - int i = 0; - foreach (var tag in metricPoint.Tags) - { - Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); - i++; - } + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + // Set up two different providers as only one Metric Processor is allowed. + // TODO: Simplify the setup when multiple Metric processors are allowed. + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulExportOnLinux") + .AddGenevaMetricExporter(options => + { + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + options.MetricExportIntervalMilliseconds = 5000; + }) + .Build(); + + using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("InMemoryExportOnLinux") + .AddReader(inMemoryReader) + .Build(); + + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 15000; + + // Create a test exporter to get byte data for validation of the data received via Socket. + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; + using var exporter = new GenevaMetricExporter(exporterOptions); + + // Emit a metric and grab a copy of internal buffer for validation. + counter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + inMemoryCounter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + // exportedItems list should have a single entry after the MetricReader.Collect call + inMemoryReader.Collect(); + + Assert.Single(exportedItems); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + + // Wait a little more than the ExportInterval for the exporter to export the data. + Task.Delay(5500).Wait(); + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + var fixedPayloadLength = (int)typeof(GenevaMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); + + // The whole payload is sent to the Unix Domain Socket + // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload + Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); + + var stream = new KaitaiStream(receivedData); + var data = new MetricsContract(stream); + + Assert.Equal(metric.Name, data.Body.MetricName.Value); + Assert.Equal("OTelMonitoringAccount", data.Body.MetricAccount.Value); + Assert.Equal("OTelMetricNamespace", data.Body.MetricNamespace.Value); + + var valueSection = data.Body.ValueSection as SingleUint64Value; + Assert.Equal(metricDataValue, valueSection.Value); + + Assert.Equal(2, data.Body.NumDimensions); + + int i = 0; + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); + i++; + } - Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - finally - { - try - { - File.Delete(path); + Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); } - catch + finally { + try + { + File.Delete(path); + } + catch + { + } } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 02d5b5bf73..5c49219c5b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -37,7 +37,6 @@ public GenevaTraceExporterTests() } [Fact] - [Trait("Platform", "Any")] public void GenevaTraceExporter_constructor_Invalid_Input() { // no connection string @@ -57,30 +56,31 @@ public void GenevaTraceExporter_constructor_Invalid_Input() } [Fact] - [Trait("Platform", "Windows")] public void GenevaTraceExporter_constructor_Invalid_Input_Windows() { - // no ETW session name - Assert.Throws(() => + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + // no ETW session name + Assert.Throws(() => { - ConnectionString = "key=value", + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "key=value", + }); }); - }); - // empty ETW session name - Assert.Throws(() => - { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + // empty ETW session name + Assert.Throws(() => { - ConnectionString = "EtwSession=", + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=", + }); }); - }); + } } [Fact] - [Trait("Platform", "Any")] public void GenevaTraceExporter_TableNameMappings_SpecialCharacters() { Assert.Throws(() => @@ -93,57 +93,59 @@ public void GenevaTraceExporter_TableNameMappings_SpecialCharacters() } [Fact] - [Trait("Platform", "Windows")] - public void GenevaTraceExporter_Success() + public void GenevaTraceExporter_Success_Windows() { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - - // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "EtwSession=OpenTelemetry"; - options.PrepopulatedFields = new Dictionary + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + + // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); - var source = new ActivitySource(sourceName); - using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) - { - parent?.SetTag("http.method", "GET"); - parent?.SetTag("http.url", "https://localhost/wiki/Rabbit"); - using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) + var source = new ActivitySource(sourceName); + using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) { - child?.SetTag("http.method", "GET"); - child?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); - child?.SetTag("http.status_code", 404); - } + parent?.SetTag("http.method", "GET"); + parent?.SetTag("http.url", "https://localhost/wiki/Rabbit"); + using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) + { + child?.SetTag("http.method", "GET"); + child?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + child?.SetTag("http.status_code", 404); + } - parent?.SetTag("http.status_code", 200); - } + parent?.SetTag("http.status_code", 200); + } - var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); - using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) - { - } + var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); + using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) + { + } - using (var activity = source.StartActivity("Bar")) - { - activity.SetStatus(Status.Error); - } + using (var activity = source.StartActivity("Bar")) + { + activity.SetStatus(Status.Error); + } - using (var activity = source.StartActivity("Baz")) - { - activity.SetStatus(Status.Ok); + using (var activity = source.StartActivity("Baz")) + { + activity.SetStatus(Status.Ok); + } } } @@ -152,7 +154,6 @@ public void GenevaTraceExporter_Success() [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] - [Trait("Platform", "Any")] public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields) { string path = string.Empty; @@ -284,116 +285,122 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, } [Fact] - [Trait("Platform", "Linux")] - public void GenevaTraceExporter_Linux_constructor_Missing() + public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() { - string path = GetRandomFilePath(); - - // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address - try - { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "Endpoint=unix:" + path; - }) - .Build(); - Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); - } - catch (SocketException ex) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - Assert.Contains("Cannot assign requested address", ex.Message); - } + string path = GetRandomFilePath(); - try - { - var exporter = new GenevaTraceExporter(new GenevaExporterOptions + // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address + try { - ConnectionString = "Endpoint=unix:" + path, - }); - Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); - } - catch (SocketException ex) - { - Assert.Contains("Cannot assign requested address", ex.Message); + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + }) + .Build(); + Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + } + catch (SocketException ex) + { + // There is no one to listent to the socket. + Assert.Contains("Cannot assign requested address", ex.Message); + } + + try + { + var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + }); + Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + } + catch (SocketException ex) + { + // There is no one to listent to the socket. + Assert.Contains("Cannot assign requested address", ex.Message); + } } } [Fact] - [Trait("Platform", "Linux")] - public void GenevaTraceExporter_Linux_Success() + public void GenevaTraceExporter_Success_Linux() { - string path = GetRandomFilePath(); - try + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + string path = GetRandomFilePath(); + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + using Socket serverSocket = server.Accept(); + + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - options.ConnectionString = "Endpoint=unix:" + path; - options.PrepopulatedFields = new Dictionary + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", ["cloud.roleInstance"] = "CY1SCH030021417", ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); - using Socket serverSocket = server.Accept(); + }, + }); - // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "Endpoint=unix:" + path, - PrepopulatedFields = new Dictionary + // Emit trace and grab a copy of internal buffer for validation. + var source = new ActivitySource(sourceName); + int messagePackDataSize; + using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }); - - // Emit trace and grab a copy of internal buffer for validation. - var source = new ActivitySource(sourceName); - int messagePackDataSize; - using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) - { - messagePackDataSize = exporter.SerializeActivity(activity); - } + messagePackDataSize = exporter.SerializeActivity(activity); + } - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); - // Validation - Assert.Equal(messagePackDataSize, receivedDataSize); - } - catch (Exception) - { - throw; - } - finally - { - try + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); + } + catch (Exception) { - File.Delete(path); + throw; } - catch + finally { + try + { + File.Delete(path); + } + catch + { + } } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 59b830e192..a4b8dfda30 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -141,14 +141,12 @@ private void MessagePackSerializer_TestUnicodeStringSerialization(string input) } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_Null() { this.MessagePackSerializer_TestSerialization(null); } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_Boolean() { this.MessagePackSerializer_TestSerialization(true); @@ -156,7 +154,6 @@ public void MessagePackSerializer_Boolean() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_Int() { // 8 bits @@ -223,7 +220,6 @@ public void MessagePackSerializer_Int() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_UInt() { // 8 bits @@ -269,7 +265,6 @@ public void MessagePackSerializer_UInt() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_Float() { this.MessagePackSerializer_TestSerialization(0.0f); @@ -290,7 +285,6 @@ public void MessagePackSerializer_Float() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_SerializeAsciiString() { this.MessagePackSerializer_TestASCIIStringSerialization(null); @@ -313,7 +307,6 @@ public void MessagePackSerializer_SerializeAsciiString() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_SerializeUnicodeString() { this.MessagePackSerializer_TestUnicodeStringSerialization(null); @@ -351,7 +344,6 @@ public void MessagePackSerializer_SerializeUnicodeString() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_Array() { this.MessagePackSerializer_TestSerialization((object[])null); @@ -377,7 +369,6 @@ public void MessagePackSerializer_Array() } [Fact] - [Trait("Platform", "Any")] public void MessagePackSerializer_Map() { this.MessagePackSerializer_TestSerialization((Dictionary)null); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index f6271a99de..9c4b4b3443 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -1,9 +1,9 @@ - + Unit test project for Geneva Exporters for OpenTelemetry false - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 $(TargetFrameworks);net461;net462;net47;net471;net472;net48 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 @@ -16,16 +16,19 @@ - + + + + + - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - runtime; build; native; contentfiles; analyzers - diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 42f8f18ac7..a180314a67 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -18,6 +18,7 @@ using System.IO; using System.Net.Sockets; using System.Reflection; +using System.Runtime.InteropServices; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests @@ -25,173 +26,179 @@ namespace OpenTelemetry.Exporter.Geneva.Tests public class UnixDomainSocketDataTransportTests { [Fact] - [Trait("Platform", "Linux")] - public void UnixDomainSocketDataTransport_Success() + public void UnixDomainSocketDataTransport_Success_Linux() { - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); - try - { - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - - // Client - using var dataTransport = new UnixDomainSocketDataTransport(path); - using Socket serverSocket = server.Accept(); - var data = new byte[] { 12, 34, 56 }; - dataTransport.Send(data, data.Length); - var receivedData = new byte[5]; - serverSocket.Receive(receivedData); - Assert.Equal(data[0], receivedData[0]); - Assert.Equal(data[1], receivedData[1]); - Assert.Equal(data[2], receivedData[2]); - } - catch (Exception) - { - throw; - } - finally + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); try { - File.Delete(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + using Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); } - catch + catch (Exception) { + throw; + } + finally + { + try + { + File.Delete(path); + } + catch + { + } } } } [Fact] - [Trait("Platform", "Linux")] - public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull() + public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() { - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - var data = new byte[1024]; - var i = 0; - using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests - var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; - try + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - // Client - using Socket serverSocket = server.Accept(); - while (true) + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + var data = new byte[1024]; + var i = 0; + using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests + var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; + try { - Console.WriteLine($"Sending request #{i++}."); - socket.Send(data, data.Length, SocketFlags.None); + // Client + using Socket serverSocket = server.Accept(); + while (true) + { + Console.WriteLine($"Sending request #{i++}."); + socket.Send(data, data.Length, SocketFlags.None); + } + + // The server is not processing sent data (because of heavy load, etc.) } - - // The server is not processing sent data (because of heavy load, etc.) - } - catch (Exception) - { - // At this point, the outgoing buffer for the socket must be full, - // because the last Send failed. - // Send again and assert the exception to confirm: - Assert.Throws(() => + catch (Exception) { - Console.WriteLine($"Sending request #{i}."); - socket.Send(data, data.Length, SocketFlags.None); - }); - } - finally - { - try - { - File.Delete(path); + // At this point, the outgoing buffer for the socket must be full, + // because the last Send failed. + // Send again and assert the exception to confirm: + Assert.Throws(() => + { + Console.WriteLine($"Sending request #{i}."); + socket.Send(data, data.Length, SocketFlags.None); + }); } - catch + finally { + try + { + File.Delete(path); + } + catch + { + } } } } [Fact] - [Trait("Platform", "Linux")] - public void UnixDomainSocketDataTransport_ServerRestart() + public void UnixDomainSocketDataTransport_ServerRestart_Linux() { - Console.WriteLine("Test starts."); - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); - try + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - - // LingerOption lo = new LingerOption(false, 0); - // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); - server.Bind(endpoint); - server.Listen(1); - - // Client - using var dataTransport = new UnixDomainSocketDataTransport(path); - Socket serverSocket = server.Accept(); - var data = new byte[] { 12, 34, 56 }; - dataTransport.Send(data, data.Length); - var receivedData = new byte[5]; - serverSocket.Receive(receivedData); - Assert.Equal(data[0], receivedData[0]); - Assert.Equal(data[1], receivedData[1]); - Assert.Equal(data[2], receivedData[2]); - - Console.WriteLine("Successfully sent a message."); - - // Emulate server stops - serverSocket.Shutdown(SocketShutdown.Both); - serverSocket.Disconnect(false); - serverSocket.Dispose(); - server.Shutdown(SocketShutdown.Both); - server.Disconnect(false); - server.Dispose(); + Console.WriteLine("Test starts."); + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); try { - File.Delete(path); + var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + + // LingerOption lo = new LingerOption(false, 0); + // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + + Console.WriteLine("Successfully sent a message."); + + // Emulate server stops + serverSocket.Shutdown(SocketShutdown.Both); + serverSocket.Disconnect(false); + serverSocket.Dispose(); + server.Shutdown(SocketShutdown.Both); + server.Disconnect(false); + server.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + + Console.WriteLine("Destroyed server."); + + Console.WriteLine("Client will fail during Send, but shouldn't throw exception."); + dataTransport.Send(data, data.Length); + Console.WriteLine("Client will fail during reconnect, but shouldn't throw exception."); + dataTransport.Send(data, data.Length); + + using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server2.Bind(endpoint); + server2.Listen(1); + Console.WriteLine("Started a new server and listening."); + + var data2 = new byte[] { 34, 56, 78 }; + dataTransport.Send(data2, data2.Length); + Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); + + using Socket serverSocket2 = server2.Accept(); + Console.WriteLine("The new server is ready and accepting connections."); + var receivedData2 = new byte[5]; + serverSocket2.Receive(receivedData2); + Console.WriteLine("Server received a messge."); + Assert.Equal(data2[0], receivedData2[0]); + Assert.Equal(data2[1], receivedData2[1]); + Assert.Equal(data2[2], receivedData2[2]); } - catch - { - } - - Console.WriteLine("Destroyed server."); - - Console.WriteLine("Client will fail during Send, but shouldn't throw exception."); - dataTransport.Send(data, data.Length); - Console.WriteLine("Client will fail during reconnect, but shouldn't throw exception."); - dataTransport.Send(data, data.Length); - - using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server2.Bind(endpoint); - server2.Listen(1); - Console.WriteLine("Started a new server and listening."); - - var data2 = new byte[] { 34, 56, 78 }; - dataTransport.Send(data2, data2.Length); - Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); - - using Socket serverSocket2 = server2.Accept(); - Console.WriteLine("The new server is ready and accepting connections."); - var receivedData2 = new byte[5]; - serverSocket2.Receive(receivedData2); - Console.WriteLine("Server received a messge."); - Assert.Equal(data2[0], receivedData2[0]); - Assert.Equal(data2[1], receivedData2[1]); - Assert.Equal(data2[2], receivedData2[2]); - } - catch (Exception) - { - throw; - } - finally - { - try + catch (Exception) { - File.Delete(path); + throw; } - catch + finally { + try + { + File.Delete(path); + } + catch + { + } } } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 98038c5786..3ccb37f44f 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -28,7 +28,7 @@ public class InstanaSpanSerializerTests { private InstanaSpanSerializer instanaSpanSerializer = new InstanaSpanSerializer(); - [Fact] + [Fact(Skip = "Borken unit test. https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/405")] public async Task SerializeToStreamWriterAsync() { InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index fb272571b5..b7fb288f8c 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -92,7 +92,7 @@ public async Task CanCaptureGetById() // Assert.Equal(expectedResource, searchActivity.GetResource()); } - [Fact] + [Fact(Skip = "Borken unit test. https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/406")] public async Task CanCaptureGetByIdNotFound() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); @@ -437,7 +437,7 @@ public async Task CanCaptureSearchCallWithDebugMode() // Assert.Equal(expectedResource, searchActivity.GetResource()); } - [Fact] + [Fact(Skip = "Borken unit test. https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/406")] public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); From fe43f8b12b1acae1ff61ea3e68d783acc052d0ed Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Wed, 8 Jun 2022 15:31:25 -0500 Subject: [PATCH 0152/1499] Fix elasticsearch tests (#407) --- .../ElasticsearchClientTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index b7fb288f8c..563f24edd5 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -142,7 +142,7 @@ public async Task CanCaptureGetByIdNotFound() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (404) low level call", debugInfo); - Assert.Equal(Status.Error, searchActivity.GetStatus()); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -485,8 +485,7 @@ public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); Assert.NotEmpty(debugInfo); Assert.Equal( - @"POST http://localhost:9200/customer/_search?pretty=true&error_trace=true&typed_keys=true -{ + @"{ ""query"": { ""bool"": { ""must"": [ From 342b516870513ad3ebbfbf02399759ca2d98c28d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 8 Jun 2022 14:33:08 -0700 Subject: [PATCH 0153/1499] Remove skip (#410) --- .../ElasticsearchClientTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 563f24edd5..4968c09c0d 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -92,7 +92,7 @@ public async Task CanCaptureGetById() // Assert.Equal(expectedResource, searchActivity.GetResource()); } - [Fact(Skip = "Borken unit test. https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/406")] + [Fact] public async Task CanCaptureGetByIdNotFound() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); @@ -437,7 +437,7 @@ public async Task CanCaptureSearchCallWithDebugMode() // Assert.Equal(expectedResource, searchActivity.GetResource()); } - [Fact(Skip = "Borken unit test. https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/406")] + [Fact] public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); From 1c1b816f4bf7be1ca3cede002ad7789f3f3a65ed Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 8 Jun 2022 15:21:48 -0700 Subject: [PATCH 0154/1499] Update OTel SDK package version to 1.3.0 (#411) * Update OTel SDK package version to 1.3.0 --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.Runtime.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 23727004ed..8228e83493 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.3.0 + ([#411](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/411)) + ## 0.1.0-alpha.1 * This is the first release of `OpenTelemetry.Instrumentation.Runtime` package. diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 2ee7f698b6..6cbe902371 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net461;netcoreapp3.1;net6.0 @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 83e37f299a..63f479b1d3 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1;net5.0;net6.0 @@ -8,7 +8,7 @@ - + all From b530a2fc140b09e7431f47923ae9231ef2311aef Mon Sep 17 00:00:00 2001 From: Swetha Ravichandran Date: Wed, 8 Jun 2022 16:06:11 -0700 Subject: [PATCH 0155/1499] #172 Resource detectors for Docker (#206) * #172 Resource detectors for Docker --- .../ISSUE_TEMPLATE/comp_extensions_docker.md | 41 ++++++ .github/component_owners.yml | 4 + .../workflows/package-Extensions.Docker.yml | 49 +++++++ opentelemetry-dotnet-contrib.sln | 14 ++ .../AssemblyInfo.cs | 23 +++ .../CHANGELOG.md | 12 ++ .../DockerExtensionsEventSource.cs | 63 +++++++++ .../OpenTelemetry.Extensions.Docker.csproj | 10 ++ src/OpenTelemetry.Extensions.Docker/README.md | 38 +++++ .../Resources/DockerResourceDetector.cs | 131 ++++++++++++++++++ .../Resources/DockerSemanticConventions.cs | 23 +++ .../Utils/EncodingUtils.cs | 37 +++++ ...enTelemetry.Extensions.Docker.Tests.csproj | 23 +++ .../Resources/DockerResourceDetectorTests.cs | 112 +++++++++++++++ .../Resources/TempFile.cs | 67 +++++++++ 15 files changed, 647 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_docker.md create mode 100644 .github/workflows/package-Extensions.Docker.yml create mode 100644 src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Extensions.Docker/CHANGELOG.md create mode 100644 src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs create mode 100644 src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj create mode 100644 src/OpenTelemetry.Extensions.Docker/README.md create mode 100644 src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs create mode 100644 src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs create mode 100644 src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs create mode 100644 test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj create mode 100644 test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs create mode 100644 test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_docker.md b/.github/ISSUE_TEMPLATE/comp_extensions_docker.md new file mode 100644 index 0000000000..0f6b510858 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_extensions_docker.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Extensions.Docker +about: Issue with OpenTelemetry.Extensions.Docker +labels: comp:extensions.docker +--- + +# Issue with OpenTelemetry.Extensions.Docker + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 144badb8c4..e42885e953 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -2,6 +2,8 @@ # Each component identified by its path prefix has a list of users components: + src/OpenTelemetry.Extensions.Docker/: + - swetharavichandrancisco src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn @@ -66,6 +68,8 @@ components: - reyang - utpilla - Yun-Ting + test/OpenTelemetry.Extensions.Docker.Tests/: + - swetharavichandrancisco test/OpenTelemetry.Exporter.Instana.Tests/: - zivaninstana test/OpenTelemetry.Exporter.Stackdriver.Tests/: diff --git a/.github/workflows/package-Extensions.Docker.yml b/.github/workflows/package-Extensions.Docker.yml new file mode 100644 index 0000000000..bb1bf1680f --- /dev/null +++ b/.github/workflows/package-Extensions.Docker.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Extensions.Docker + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Extensions.Docker-*' # trigger when we create a tag with prefix "Extensions.Docker-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Extensions.Docker + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 631728d407..969a91d702 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -177,6 +177,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Docker", "src\OpenTelemetry.Extensions.Docker\OpenTelemetry.Extensions.Docker.csproj", "{498A6808-C0DF-441F-A764-51A3BC4B8FC5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Docker.Tests", "test\OpenTelemetry.Extensions.Docker.Tests\OpenTelemetry.Extensions.Docker.Tests.csproj", "{FB41E19E-2682-4D07-BA59-FD5205AFA71E}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva", "src\OpenTelemetry.Exporter.Geneva\OpenTelemetry.Exporter.Geneva.csproj", "{1105C814-31DA-4214-BEA8-6DB5FC12C808}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Benchmark", "test\OpenTelemetry.Exporter.Geneva.Benchmark\OpenTelemetry.Exporter.Geneva.Benchmark.csproj", "{F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}" @@ -369,6 +373,14 @@ Global {2117F4E3-6612-4E4D-A757-27271EEB7783}.Debug|Any CPU.Build.0 = Debug|Any CPU {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.ActiveCfg = Release|Any CPU {2117F4E3-6612-4E4D-A757-27271EEB7783}.Release|Any CPU.Build.0 = Release|Any CPU + {498A6808-C0DF-441F-A764-51A3BC4B8FC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {498A6808-C0DF-441F-A764-51A3BC4B8FC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {498A6808-C0DF-441F-A764-51A3BC4B8FC5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {498A6808-C0DF-441F-A764-51A3BC4B8FC5}.Release|Any CPU.Build.0 = Release|Any CPU + {FB41E19E-2682-4D07-BA59-FD5205AFA71E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB41E19E-2682-4D07-BA59-FD5205AFA71E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB41E19E-2682-4D07-BA59-FD5205AFA71E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB41E19E-2682-4D07-BA59-FD5205AFA71E}.Release|Any CPU.Build.0 = Release|Any CPU {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Debug|Any CPU.Build.0 = Debug|Any CPU {1105C814-31DA-4214-BEA8-6DB5FC12C808}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -468,6 +480,8 @@ Global {6AE92AAD-CF08-4E60-98EF-A7F762DAAB4D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {42B3FB71-BB42-46E3-9CEC-56620CB76BD9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2117F4E3-6612-4E4D-A757-27271EEB7783} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {498A6808-C0DF-441F-A764-51A3BC4B8FC5} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {FB41E19E-2682-4D07-BA59-FD5205AFA71E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1105C814-31DA-4214-BEA8-6DB5FC12C808} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {F632DFB6-38AD-4356-8997-8CCC0492619C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} diff --git a/src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs new file mode 100644 index 0000000000..a6a0089eba --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Docker.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Docker.Tests")] +#endif diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md new file mode 100644 index 0000000000..7bb1594dee --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog - OpenTelemetry.Extensions.Docker + +This is the first release for the `OpenTelemetry.Extensions.Docker` project. +The release targets +[OpenTelemetry.Extensions.Docker](https://www.nuget.org/packages/OpenTelemetry.Extensions.Docker/). +The project targets 1.2.0 of the [OpenTelemetry +SDK](https://www.nuget.org/packages/OpenTelemetry/). + +The Docker extensions include plugin to extract resource detectors +from docker environment (container id). For more details, +please refer to the +[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Extensions.Docker/README.md) diff --git a/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs b/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs new file mode 100644 index 0000000000..ab522cea8b --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs @@ -0,0 +1,63 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Threading; + +namespace OpenTelemetry.Extensions.Docker +{ + [EventSource(Name = "OpenTelemetry-Extensions-Docker")] + internal class DockerExtensionsEventSource : EventSource + { + public static DockerExtensionsEventSource Log = new DockerExtensionsEventSource(); + + [NonEvent] + public void ExtractResourceAttributesException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) + { + this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); + } + } + + [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Error)] + public void FailedToExtractResourceAttributes(string format, string exception) + { + this.WriteEvent(1, format, exception); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + } +} diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj new file mode 100644 index 0000000000..d70c0d06c6 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj @@ -0,0 +1,10 @@ + + + ;net461;netstandard2.0 + OpenTelemetry Extensions - Container Resource Detector from Docker environment. + Extensions.Docker- + + + + + diff --git a/src/OpenTelemetry.Extensions.Docker/README.md b/src/OpenTelemetry.Extensions.Docker/README.md new file mode 100644 index 0000000000..63ed574581 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/README.md @@ -0,0 +1,38 @@ +# Docker Resource Detectors + +## Getting Started + +You need to install the +`OpenTelemetry.Extensions.Docker` to be able to use the +Docker Resource Detectors. It detects container.id from +Docker environment. + +```shell +dotnet add package OpenTelemetry.Extensions.Docker +``` + +## Usage + +You can configure Docker resource detector to +the `TracerProvider` with the following example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Extensions.Docker.Resources; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .SetResourceBuilder(ResourceBuilder + .CreateEmpty() + .AddDetector(new DockerResourceDetector())) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **DockerResourceDetector**: container id. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs new file mode 100644 index 0000000000..bb6ab6a13f --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs @@ -0,0 +1,131 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.IO; +using OpenTelemetry.Extensions.Docker.Utils; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Extensions.Docker.Resources +{ + /// + /// Resource detector for application running in Docker environment. + /// + public class DockerResourceDetector : IResourceDetector + { + private const string FILEPATH = "/proc/self/cgroup"; + + /// + /// Detects the resource attributes from Docker. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + return this.BuildResource(FILEPATH); + } + + /// + /// Builds the resource attributes from Container Id in file path. + /// + /// File path where container id exists. + /// Returns Resource with list of key-value pairs of container resource attributes if container id exists else empty resource. + internal Resource BuildResource(string path) + { + var containerId = this.ExtractContainerId(path); + + if (string.IsNullOrEmpty(containerId)) + { + return Resource.Empty; + } + else + { + return new Resource(new List>() { new KeyValuePair(DockerSemanticConventions.AttributeContainerID, containerId), }); + } + } + + /// + /// Extracts Container Id from path. + /// + /// cgroup path. + /// Container Id, Null if not found or exception being thrown. + private string ExtractContainerId(string path) + { + try + { + if (!File.Exists(path)) + { + return null; + } + + foreach (string line in File.ReadLines(path)) + { + string containerId = (!string.IsNullOrEmpty(line)) ? this.GetIdFromLine(line) : null; + if (!string.IsNullOrEmpty(containerId)) + { + return containerId; + } + } + } + catch (Exception ex) + { + DockerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(DockerResourceDetector)} : Failed to extract Container id from path", ex); + } + + return null; + } + + /// + /// Gets the Container Id from the line after removing the prefix and suffix. + /// + /// line read from cgroup file. + /// Container Id. + private string GetIdFromLine(string line) + { + // This cgroup output line should have the container id in it + int lastSlashIndex = line.LastIndexOf('/'); + if (lastSlashIndex < 0) + { + return null; + } + + string lastSection = line.Substring(lastSlashIndex + 1); + int startIndex = lastSection.LastIndexOf('-'); + int endIndex = lastSection.LastIndexOf('.'); + + string containerId = this.RemovePrefixAndSuffixIfneeded(lastSection, startIndex, endIndex); + + if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) + { + return null; + } + + return containerId; + } + + private string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) + { + startIndex = (startIndex == -1) ? 0 : startIndex + 1; + + if (endIndex == -1) + { + endIndex = input.Length; + } + + return input.Substring(startIndex, endIndex - startIndex); + } + } +} diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs new file mode 100644 index 0000000000..b41d7404af --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Extensions.Docker.Resources +{ + internal static class DockerSemanticConventions + { + public const string AttributeContainerID = "container.id"; + } +} diff --git a/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs b/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs new file mode 100644 index 0000000000..5963f7ecb2 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Linq; + +namespace OpenTelemetry.Extensions.Docker.Utils +{ + internal class EncodingUtils + { + /// + /// Checks if the string is valid hex. + /// + /// string. + /// true if valid else false. + public static bool IsValidHexString(IEnumerable hexString) + { + return hexString.Select(currentCharacter => + (currentCharacter >= '0' && currentCharacter <= '9') || + (currentCharacter >= 'a' && currentCharacter <= 'f') || + (currentCharacter >= 'A' && currentCharacter <= 'F')).All(isHexCharacter => isHexCharacter); + } + } +} diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj new file mode 100644 index 0000000000..5596e02af2 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -0,0 +1,23 @@ + + + + Unit test project for Docker Detector for OpenTelemetry + netcoreapp3.1 + $(TargetFrameworks);net461 + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs new file mode 100644 index 0000000000..bebb93d3e8 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs @@ -0,0 +1,112 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.IO; +using System.Linq; +using OpenTelemetry.Extensions.Docker.Resources; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Extensions.Docker.Tests +{ + public class DockerResourceDetectorTests + { + // Invalid cgroup line + private const string INVALIDCGROUPLINE = + "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz"; + + // cgroup line with prefix + private const string CGROUPLINEWITHPREFIX = + "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff"; + + // Expected Container Id with prefix removed + private const string CONTAINERIDWITHPREFIXREMOVED = "e2cc29debdf85dde404998aa128997a819ff"; + + // cgroup line with suffix + private const string CGROUPLINEWITHSUFFIX = + "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa"; + + // Expected Container Id with suffix removed + private const string CONTAINERIDWITHSUFFIXREMOVED = "ac679f8a8319c8cf7d38e1adf263bc08d23"; + + // cgroup line with prefix and suffix + private const string CGROUPLINEWITHPREFIXandSUFFIX = + "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff"; + + // Expected Container Id with both prefix and suffix removed + private const string CONTAINERIDWITHPREFIXANDSUFFIXREMOVED = "dc679f8a8319c8cf7d38e1adf263bc08d23"; + + // cgroup line with container Id + private const string CGROUPLINE = + "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; + + // Expected Container Id + private const string CONTAINERID = + "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; + + [Fact] + public void TestValidContainer() + { + var dockerResourceDetector = new DockerResourceDetector(); + + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(CGROUPLINEWITHPREFIX); + Assert.Equal(CONTAINERIDWITHPREFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + } + + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(CGROUPLINEWITHSUFFIX); + Assert.Equal(CONTAINERIDWITHSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + } + + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(CGROUPLINEWITHPREFIXandSUFFIX); + Assert.Equal(CONTAINERIDWITHPREFIXANDSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + } + + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(CGROUPLINE); + Assert.Equal(CONTAINERID, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + } + } + + [Fact] + public void TestInvalidContainer() + { + var dockerResourceDetector = new DockerResourceDetector(); + + // test invalid containerId (non-hex) + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(INVALIDCGROUPLINE); + Assert.Equal(dockerResourceDetector.BuildResource(tempFile.FilePath), Resource.Empty); + } + + // test invalid file + Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath()), Resource.Empty); + } + + private string GetContainerId(Resource resource) + { + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); + return resourceAttributes[DockerSemanticConventions.AttributeContainerID]?.ToString(); + } + } +} diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs new file mode 100644 index 0000000000..592c128152 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs @@ -0,0 +1,67 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.IO; +using System.Threading; + +namespace OpenTelemetry.Extensions.Docker.Tests +{ + internal class TempFile : IDisposable + { + private string filePath; + + public TempFile() + { + this.filePath = Path.GetTempFileName(); + } + + public string FilePath + { + get { return this.filePath; } + set { this.filePath = value; } + } + + public void Write(string data) + { + using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + { + using (StreamWriter sw = new StreamWriter(stream)) + { + sw.Write(data); + } + } + } + + public void Dispose() + { + for (int tries = 0; ; tries++) + { + try + { + File.Delete(this.filePath); + return; + } + catch (IOException) when (tries < 3) + { + // the file is unavailable because it is: still being written to or being processed by another thread + // sleep for sometime before deleting + Thread.Sleep(1000); + } + } + } + } +} From 1c00bf743acbbcc337891aaa7c6043a3e7062007 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 8 Jun 2022 16:43:23 -0700 Subject: [PATCH 0156/1499] Refactor eventsource [Extensions.PersistentStorage] (#382) * refactor eventsource --- .../FileBlob.cs | 8 +- .../FileBlobProvider.cs | 9 +- .../PersistentStorageEventSource.cs | 184 +++++++++++++----- .../PersistentStorageHelper.cs | 14 +- 4 files changed, 152 insertions(+), 63 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs index d56c0bb2c9..d82018c06a 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs @@ -47,7 +47,7 @@ protected override bool OnTryRead([NotNullWhen(true)] out byte[] buffer) } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning($"Reading a blob from file {this.FullPath} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotReadFileBlob(this.FullPath, ex); buffer = null; return false; } @@ -73,7 +73,7 @@ protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning($"Writing a blob to file {path} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotWriteFileBlob(path, ex); return false; } @@ -97,7 +97,7 @@ protected override bool OnTryLease(int leasePeriodMilliseconds) } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning($"Acquiring a lease to file {this.FullPath} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotLeaseFileBlob(this.FullPath, ex); return false; } @@ -114,7 +114,7 @@ protected override bool OnTryDelete() } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning($"Deletion of file blob {this.FullPath} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotDeleteFileBlob(this.FullPath, ex); return false; } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs index 8e008501ec..6f08c8d1b2 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs @@ -148,7 +148,7 @@ private void OnMaintenanceEvent(object source, ElapsedEventArgs e) } catch (Exception ex) { - PersistentStorageEventSource.Log.Error($"Error creating directory {this.directoryPath}", ex); + PersistentStorageEventSource.Log.PersistentStorageException(nameof(FileBlobProvider), $"Error creating directory {this.directoryPath}", ex); return; } @@ -161,8 +161,9 @@ private bool CheckStorageSize() if (size >= this.maxSizeInBytes) { // TODO: check accuracy of size reporting. - PersistentStorageEventSource.Log.Warning($"Persistent storage max capacity has been reached. Currently at {size / 1024} KB. " + - "Please consider increasing the value of storage max size in exporter config."); + PersistentStorageEventSource.Log.PersistentStorageWarning( + nameof(FileBlobProvider), + $"Persistent storage max capacity has been reached. Currently at {size / 1024} KiB. Please consider increasing the value of storage max size in exporter config."); return false; } @@ -192,7 +193,7 @@ private PersistentBlob CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning("CreateBlob has failed.", ex); + PersistentStorageEventSource.Log.CouldNotCreateFileBlob(ex); return null; } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs index c4553e3934..d8868d61f9 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs @@ -16,7 +16,8 @@ using System; using System.Diagnostics.Tracing; -using System.Runtime.CompilerServices; +using System.Globalization; +using System.Threading; namespace OpenTelemetry.Extensions.PersistentStorage { @@ -24,84 +25,171 @@ namespace OpenTelemetry.Extensions.PersistentStorage internal sealed class PersistentStorageEventSource : EventSource { public static PersistentStorageEventSource Log = new PersistentStorageEventSource(); - private const string EventSourceName = "OpenTelemetry-Contrib-PersistentStorage"; + private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage"; [NonEvent] - public void Critical(string message, object value = null) + public void CouldNotReadFileBlob(string filePath, Exception ex) { - this.Write(EventLevel.Critical, message, value); + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + this.CouldNotReadFileBlob(filePath, ToInvariantString(ex)); + } + } + + [NonEvent] + public void CouldNotWriteFileBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + this.CouldNotWriteFileBlob(filePath, ToInvariantString(ex)); + } } [NonEvent] - public void Error(string message, object value = null) + public void CouldNotLeaseFileBlob(string filePath, Exception ex) { - this.Write(EventLevel.Error, message, value); + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + this.CouldNotLeaseFileBlob(filePath, ToInvariantString(ex)); + } } [NonEvent] - public void Warning(string message, object value = null) + public void CouldNotDeleteFileBlob(string filePath, Exception ex) { - this.Write(EventLevel.Warning, message, value); + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + this.CouldNotDeleteFileBlob(filePath, ToInvariantString(ex)); + } } [NonEvent] - public void Informational(string message, object value = null) + public void CouldNotCreateFileBlob(Exception ex) { - this.Write(EventLevel.Informational, message, value); + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + this.CouldNotCreateFileBlob(ToInvariantString(ex)); + } + } + + [NonEvent] + public void CouldNotRemoveExpiredBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) + { + this.CouldNotRemoveExpiredBlob(filePath, ToInvariantString(ex)); + } + } + + [NonEvent] + public void CouldNotRemoveTimedOutTmpFile(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) + { + this.CouldNotRemoveTimedOutTmpFile(filePath, ToInvariantString(ex)); + } + } + + [NonEvent] + public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) + { + this.CouldNotRemoveExpiredLease(srcFilePath, destFilePath, ToInvariantString(ex)); + } } [NonEvent] - public void Verbose(string message, object value = null) + public void PersistentStorageException(string className, string message, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.PersistentStorageException(className, message, ToInvariantString(ex)); + } + } + + [Event(1, Message = "Could not read blob from file '{0}'", Level = EventLevel.Informational)] + public void CouldNotReadFileBlob(string filePath, string ex) { - this.Write(EventLevel.Verbose, message, value); + this.WriteEvent(1, filePath, ex); } - [Event(1, Message = "{0}", Level = EventLevel.Critical)] - public void WriteCritical(string message) => this.WriteEvent(1, message); + [Event(2, Message = "Could not write blob to file '{0}'", Level = EventLevel.Informational)] + public void CouldNotWriteFileBlob(string filePath, string ex) + { + this.WriteEvent(2, filePath, ex); + } - [Event(2, Message = "{0}", Level = EventLevel.Error)] - public void WriteError(string message) => this.WriteEvent(2, message); + [Event(3, Message = "Could not acquire a lease on file '{0}'", Level = EventLevel.Informational)] + public void CouldNotLeaseFileBlob(string filePath, string ex) + { + this.WriteEvent(3, filePath, ex); + } - [Event(3, Message = "{0}", Level = EventLevel.Warning)] - public void WriteWarning(string message) => this.WriteEvent(3, message); + [Event(4, Message = "Could not delete file '{0}'", Level = EventLevel.Informational)] + public void CouldNotDeleteFileBlob(string filePath, string ex) + { + this.WriteEvent(4, filePath, ex); + } - [Event(4, Message = "{0}", Level = EventLevel.Informational)] - public void WriteInformational(string message) => this.WriteEvent(4, message); + [Event(5, Message = "Could not create file blob", Level = EventLevel.Informational)] + public void CouldNotCreateFileBlob(string ex) + { + this.WriteEvent(5, ex); + } - [Event(5, Message = "{0}", Level = EventLevel.Verbose)] - public void WriteVerbose(string message) => this.WriteEvent(5, message); + [Event(6, Message = "Could not remove expired blob '{0}'", Level = EventLevel.Warning)] + public void CouldNotRemoveExpiredBlob(string filePath, string ex) + { + this.WriteEvent(6, filePath, ex); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static string GetMessage(object value) + [Event(7, Message = "Could not remove timed out file '{0}'", Level = EventLevel.Warning)] + public void CouldNotRemoveTimedOutTmpFile(string filePath, string ex) { - return value is Exception exception ? exception.ToString() : value.ToString(); + this.WriteEvent(7, filePath, ex); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void Write(EventLevel eventLevel, string message, object value) + [Event(8, Message = "Could not rename '{0}' to '{1}'", Level = EventLevel.Warning)] + public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, string ex) { - if (this.IsEnabled(eventLevel, (EventKeywords)(-1))) + this.WriteEvent(8, srcFilePath, destFilePath, ex); + } + + [Event(9, Message = "{0}: Error Message: {1}. Exception: {3}", Level = EventLevel.Error)] + public void PersistentStorageException(string className, string message, string ex) + { + this.WriteEvent(9, className, message, ex); + } + + [Event(10, Message = "{0}: Warning Message: {1}", Level = EventLevel.Warning)] + public void PersistentStorageWarning(string className, string message) + { + this.WriteEvent(10, className, message); + } + + [Event(11, Message = "{0}: Message: {1}", Level = EventLevel.Informational)] + public void PersistentStorageInformation(string className, string message) + { + this.WriteEvent(11, className, message); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally { - var logMessage = value == null ? message : $"{message} - {GetMessage(value)}"; - - switch (eventLevel) - { - case EventLevel.Critical: - this.WriteCritical(logMessage); - break; - case EventLevel.Error: - this.WriteError(logMessage); - break; - case EventLevel.Informational: - this.WriteInformational(logMessage); - break; - case EventLevel.Verbose: - this.WriteVerbose(logMessage); - break; - case EventLevel.Warning: - this.WriteWarning(logMessage); - break; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs index 9b0fc0eb2a..9c29be48ed 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -40,11 +40,11 @@ internal static void RemoveExpiredBlob(DateTime retentionDeadline, string filePa try { File.Delete(filePath); - PersistentStorageEventSource.Log.Warning("Removing blob as retention deadline expired"); + PersistentStorageEventSource.Log.PersistentStorageInformation(nameof(PersistentStorageHelper), "Removing blob as retention deadline expired"); } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning($"Deletion of file {filePath} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotRemoveExpiredBlob(filePath, ex); } } } @@ -67,7 +67,7 @@ internal static bool RemoveExpiredLease(DateTime leaseDeadline, string filePath) } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning("File rename of {filePath} to {newFilePath} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotRemoveExpiredLease(filePath, newFilePath, ex); } } } @@ -88,11 +88,11 @@ internal static bool RemoveTimedOutTmpFiles(DateTime timeoutDeadline, string fil { File.Delete(filePath); success = true; - PersistentStorageEventSource.Log.Warning("File write exceeded timeout. Dropping telemetry"); + PersistentStorageEventSource.Log.PersistentStorageInformation(nameof(PersistentStorageHelper), "File write exceeded timeout. Dropping telemetry"); } catch (Exception ex) { - PersistentStorageEventSource.Log.Warning($"Deletion of file {filePath} has failed.", ex); + PersistentStorageEventSource.Log.CouldNotRemoveTimedOutTmpFile(filePath, ex); } } } @@ -178,7 +178,7 @@ internal static string CreateSubdirectory(string path) } catch (Exception ex) { - PersistentStorageEventSource.Log.Error($"Error creating sub-directory {path}.", ex); + PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), $"Error creating sub-directory {path}", ex); } directorySize = CalculateFolderSize(subdirectoryPath); @@ -253,7 +253,7 @@ private static long CalculateFolderSize(string path) } catch (Exception ex) { - PersistentStorageEventSource.Log.Error("Error calculating folder size.", ex); + PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), "Error calculating folder size", ex); } return directorySize; From b902d5a66c1faec27bb14904ec94d39ee60c31e0 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 9 Jun 2022 13:41:58 -0700 Subject: [PATCH 0157/1499] Add AspNet.TelemetryHttpModule instrumentation (#413) * Add AspNet.TelemetryHttpModule instrumentation --- ...trumentation_AspNet.TelemetryHttpModule.md | 41 ++ .github/component_owners.yml | 8 +- ...rumentation.AspNet.TelemetryHttpModule.yml | 49 ++ opentelemetry-dotnet-contrib.sln | 15 + .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 16 + .../ActivityHelper.cs | 224 +++++++ .../AspNetTelemetryEventSource.cs | 122 ++++ .../AssemblyInfo.cs | 28 + .../CHANGELOG.md | 59 ++ ...entation.AspNet.TelemetryHttpModule.csproj | 26 + .../README.md | 136 +++++ .../TelemetryHttpModule.cs | 147 +++++ .../TelemetryHttpModuleOptions.cs | 67 +++ .../web.config.install.xdt | 48 ++ .../web.config.uninstall.xdt | 17 + .../ActivityHelperTest.cs | 546 ++++++++++++++++++ .../HttpContextHelper.cs | 103 ++++ ...on.AspNet.TelemetryHttpModule.Tests.csproj | 34 ++ .../WebConfigTransformTest.cs | 409 +++++++++++++ .../WebConfigWithLocationTagTransformTest.cs | 439 ++++++++++++++ 21 files changed, 2530 insertions(+), 4 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md create mode 100644 .github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.install.xdt create mode 100644 src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md new file mode 100644 index 0000000000..dc3d2f78c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule +about: Issue with OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule +labels: comp:instrumentation.AspNet.TelemetryHttpModule +--- + +# Issue with OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.2.0`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index e42885e953..187324cf2d 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -2,8 +2,6 @@ # Each component identified by its path prefix has a list of users components: - src/OpenTelemetry.Extensions.Docker/: - - swetharavichandrancisco src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn @@ -20,6 +18,8 @@ components: - SergeyKanzhelev src/OpenTelemetry.Extensions/: - codeblanch + src/OpenTelemetry.Extensions.Docker/: + - swetharavichandrancisco src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/: - vishweshbankwar src/OpenTelemetry.Extensions.PersistentStorage/: @@ -68,14 +68,14 @@ components: - reyang - utpilla - Yun-Ting - test/OpenTelemetry.Extensions.Docker.Tests/: - - swetharavichandrancisco test/OpenTelemetry.Exporter.Instana.Tests/: - zivaninstana test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: - codeblanch + test/OpenTelemetry.Extensions.Docker.Tests/: + - swetharavichandrancisco test/OpenTelemetry.Extensions.PersistentStorage.Tests/: - vishweshbankwar test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml new file mode 100644 index 0000000000..1b12b12187 --- /dev/null +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.AspNet.TelemetryHttpModule-*' + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 969a91d702..704cb4aaf0 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -38,6 +38,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml + .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml @@ -207,6 +208,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "redis", "redis", "{D8F9AEAC EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.StackExchangeRedis", "examples\redis\Examples.StackExchangeRedis\Examples.StackExchangeRedis.csproj", "{DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule", "src\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj", "{EC83D37A-3704-4515-8EE8-4D007CD9E0A8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests", "test\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj", "{969425CE-CB8F-462C-9126-597FC5B33E27}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -429,6 +434,14 @@ Global {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1}.Release|Any CPU.Build.0 = Release|Any CPU + {EC83D37A-3704-4515-8EE8-4D007CD9E0A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC83D37A-3704-4515-8EE8-4D007CD9E0A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC83D37A-3704-4515-8EE8-4D007CD9E0A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC83D37A-3704-4515-8EE8-4D007CD9E0A8}.Release|Any CPU.Build.0 = Release|Any CPU + {969425CE-CB8F-462C-9126-597FC5B33E27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {969425CE-CB8F-462C-9126-597FC5B33E27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {969425CE-CB8F-462C-9126-597FC5B33E27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {969425CE-CB8F-462C-9126-597FC5B33E27}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -495,6 +508,8 @@ Global {2AD0F8EB-B7C8-4E87-8090-25BE190A0BD4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D8F9AEAC-6ACA-484E-81A5-9CEBEDBC3422} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1} = {D8F9AEAC-6ACA-484E-81A5-9CEBEDBC3422} + {EC83D37A-3704-4515-8EE8-4D007CD9E0A8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {969425CE-CB8F-462C-9126-597FC5B33E27} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..367f7a1e6e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,16 @@ +const OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.AspNetActivityName = "Microsoft.AspNet.HttpReqIn" -> string +const OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry" -> string +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Dispose() -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Init(System.Web.HttpApplication context) -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.TelemetryHttpModule() -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnExceptionCallback.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnExceptionCallback.set -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStartedCallback.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStartedCallback.set -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStoppedCallback.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStoppedCallback.set -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.TextMapPropagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.TextMapPropagator.set -> void +static OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Options.get -> OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs new file mode 100644 index 0000000000..4a1e648ad0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -0,0 +1,224 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Web; +using OpenTelemetry.Context; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// Activity helper class. + /// + internal static class ActivityHelper + { + /// + /// Key to store the state in HttpContext. + /// + internal const string ContextKey = "__AspnetInstrumentationContext__"; + internal static readonly object StartedButNotSampledObj = new(); + + private const string BaggageSlotName = "otel.baggage"; + private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); + private static readonly ActivitySource AspNetSource = new( + TelemetryHttpModule.AspNetSourceName, + typeof(ActivityHelper).Assembly.GetName().Version.ToString()); + + /// + /// Try to get the started for the running . + /// + /// . + /// Started or if 1) start has not been called or 2) start was + /// called but sampling decided not to create an instance. + /// if start has been called. + public static bool HasStarted(HttpContext context, out Activity aspNetActivity) + { + Debug.Assert(context != null, "Context is null."); + + object itemValue = context.Items[ContextKey]; + if (itemValue is ContextHolder contextHolder) + { + aspNetActivity = contextHolder.Activity; + return true; + } + + aspNetActivity = null; + return itemValue == StartedButNotSampledObj; + } + + /// + /// Creates root (first level) activity that describes incoming request. + /// + /// . + /// . + /// Callback action. + /// New root activity. + public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action onRequestStartedCallback) + { + Debug.Assert(context != null, "Context is null."); + + PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); + + Activity activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext); + + if (activity != null) + { + if (textMapPropagator is not TraceContextPropagator) + { + Baggage.Current = propagationContext.Baggage; + + context.Items[ContextKey] = new ContextHolder { Activity = activity, Baggage = RuntimeContext.GetValue(BaggageSlotName) }; + } + else + { + context.Items[ContextKey] = new ContextHolder { Activity = activity }; + } + + try + { + onRequestStartedCallback?.Invoke(activity, context); + } + catch (Exception callbackEx) + { + AspNetTelemetryEventSource.Log.CallbackException(activity, "OnStarted", callbackEx); + } + + AspNetTelemetryEventSource.Log.ActivityStarted(activity); + } + else + { + context.Items[ContextKey] = StartedButNotSampledObj; + } + + return activity; + } + + /// + /// Stops the activity and notifies listeners about it. + /// + /// . + /// . + /// . + /// Callback action. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activity aspNetActivity, HttpContext context, Action onRequestStoppedCallback) + { + Debug.Assert(context != null, "Context is null."); + + if (aspNetActivity == null) + { + Debug.Assert(context.Items[ContextKey] == StartedButNotSampledObj, "Context item is not StartedButNotSampledObj."); + + // This is the case where a start was called but no activity was + // created due to a sampling decision. + context.Items[ContextKey] = null; + return; + } + + Debug.Assert(context.Items[ContextKey] is ContextHolder, "Context item is not an ContextHolder instance."); + + var currentActivity = Activity.Current; + + aspNetActivity.Stop(); + context.Items[ContextKey] = null; + + try + { + onRequestStoppedCallback?.Invoke(aspNetActivity, context); + } + catch (Exception callbackEx) + { + AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnStopped", callbackEx); + } + + AspNetTelemetryEventSource.Log.ActivityStopped(currentActivity); + + if (textMapPropagator is not TraceContextPropagator) + { + Baggage.Current = default; + } + + if (currentActivity != aspNetActivity) + { + Activity.Current = currentActivity; + } + } + + /// + /// Notifies listeners about an unhandled exception thrown on the . + /// + /// . + /// . + /// . + /// Callback action. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteActivityException(Activity aspNetActivity, HttpContext context, Exception exception, Action onExceptionCallback) + { + Debug.Assert(context != null, "Context is null."); + Debug.Assert(exception != null, "Exception is null."); + + if (aspNetActivity != null) + { + try + { + onExceptionCallback?.Invoke(aspNetActivity, context, exception); + } + catch (Exception callbackEx) + { + AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnException", callbackEx); + } + + AspNetTelemetryEventSource.Log.ActivityException(aspNetActivity, exception); + } + } + + /// + /// It's possible that a request is executed in both native threads and managed threads, + /// in such case Activity.Current will be lost during native thread and managed thread switch. + /// This method is intended to restore the current activity in order to correlate the child + /// activities with the root activity of the request. + /// + /// . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void RestoreContextIfNeeded(HttpContext context) + { + Debug.Assert(context != null, "Context is null."); + + if (context.Items[ContextKey] is ContextHolder contextHolder && Activity.Current != contextHolder.Activity) + { + Activity.Current = contextHolder.Activity; + if (contextHolder.Baggage != null) + { + RuntimeContext.SetValue(BaggageSlotName, contextHolder.Baggage); + } + + AspNetTelemetryEventSource.Log.ActivityRestored(contextHolder.Activity); + } + } + + internal class ContextHolder + { + public Activity Activity; + public object Baggage; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs new file mode 100644 index 0000000000..3fd4e239d0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs @@ -0,0 +1,122 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// ETW EventSource tracing class. + /// + [EventSource(Name = "OpenTelemetry-Instrumentation-AspNet-Telemetry", Guid = "1de158cc-f7ce-4293-bd19-2358c93c8186")] + internal sealed class AspNetTelemetryEventSource : EventSource + { + /// + /// Instance of the PlatformEventSource class. + /// + public static readonly AspNetTelemetryEventSource Log = new(); + + [NonEvent] + public void ActivityStarted(Activity activity) + { + if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) + { + this.ActivityStarted(activity?.Id); + } + } + + [NonEvent] + public void ActivityStopped(Activity activity) + { + if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) + { + this.ActivityStopped(activity?.Id); + } + } + + [NonEvent] + public void ActivityRestored(Activity activity) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) + { + this.ActivityRestored(activity?.Id); + } + } + + [NonEvent] + public void ActivityException(Activity activity, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.ActivityException(activity?.Id, ex.ToInvariantString()); + } + } + + [NonEvent] + public void CallbackException(Activity activity, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.CallbackException(activity?.Id, eventName, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Callback='{0}'", Level = EventLevel.Verbose)] + public void TraceCallback(string callback) + { + this.WriteEvent(1, callback); + } + + [Event(2, Message = "Activity started, Id='{0}'", Level = EventLevel.Verbose)] + public void ActivityStarted(string id) + { + this.WriteEvent(2, id); + } + + [Event(3, Message = "Activity stopped, Id='{0}'", Level = EventLevel.Verbose)] + public void ActivityStopped(string id) + { + this.WriteEvent(3, id); + } + + [Event(4, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)] + public void ActivityRestored(string id) + { + this.WriteEvent(4, id); + } + + [Event(5, Message = "Failed to invoke OnExecuteRequestStep, Error='{0}'", Level = EventLevel.Error)] + public void OnExecuteRequestStepInvocationError(string error) + { + this.WriteEvent(5, error); + } + + [Event(6, Message = "Activity exception, Id='{0}': {1}", Level = EventLevel.Error)] + public void ActivityException(string id, string ex) + { + this.WriteEvent(6, id, ex); + } + + [Event(7, Message = "Callback exception, Id='{0}', Name='{1}': {2}", Level = EventLevel.Error)] + public void CallbackException(string id, string eventName, string ex) + { + this.WriteEvent(7, id, eventName, ex); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs new file mode 100644 index 0000000000..5f10011c2f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs @@ -0,0 +1,28 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: ComVisible(false)] + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md new file mode 100644 index 0000000000..fbb62f7ebb --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -0,0 +1,59 @@ +# Changelog + +## Unreleased + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +* Removes .NET Framework 4.6.1. The minimum .NET Framework + version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +* Adopted the donation + [Microsoft.AspNet.TelemetryCorrelation](https://github.com/aspnet/Microsoft.AspNet.TelemetryCorrelation) + from [.NET Foundation](https://dotnetfoundation.org/) + ([#2223](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2223)) + +* Renamed the module, refactored existing code + ([#2224](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2224) + [#2225](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2225) + [#2226](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2226) + [#2229](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2229) + [#2231](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2231) + [#2235](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2235) + [#2238](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2238) + [#2240](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2240)) + +* Updated to use + [ActivitySource](https://docs.microsoft.com/dotnet/api/system.diagnostics.activitysource) + & OpenTelemetry.API + ([#2249](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2249) & + follow-ups (linked to #2249)) + +* TelemetryHttpModule will now restore Baggage on .NET 4.7.1+ runtimes when IIS + switches threads + ([#2314](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2314)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj new file mode 100644 index 0000000000..e1d245b557 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -0,0 +1,26 @@ + + + + net462 + A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. + $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md new file mode 100644 index 0000000000..c2d88b999b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -0,0 +1,136 @@ +# ASP.NET Telemetry HttpModule for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) + +The ASP.NET Telemetry HttpModule enables distributed tracing of incoming ASP.NET +requests using the OpenTelemetry API. + +## Usage + +### Step 1: Install NuGet package + +If you are using the traditional `packages.config` reference style, a +`web.config` transform should run automatically and configure the +`TelemetryHttpModule` for you. If you are using the more modern PackageReference +style, this may be needed to be done manually. For more information, see: +[Migrate from packages.config to +PackageReference](https://docs.microsoft.com/nuget/consume-packages/migrate-packages-config-to-package-reference). + +To configure your `web.config` manually, add this: + +```xml + + + + + +``` + +### Step 2: Register a listener + +`TelemetryHttpModule` registers an +[ActivitySource](https://docs.microsoft.com/dotnet/api/system.diagnostics.activitysource) +with the name `OpenTelemetry.Instrumentation.AspNet.Telemetry`. By default, .NET +`ActivitySource` will not generate any `Activity` objects unless there is a +registered listener. + +To register a listener automatically using OpenTelemetry, please use the +[OpenTelemetry.Instrumentation.AspNet](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet/) +NuGet package. + +To register a listener manually, use code such as the following: + +```csharp +using System.Diagnostics; +using System.Web; +using System.Web.Http; +using System.Web.Mvc; +using System.Web.Routing; +using OpenTelemetry.Instrumentation.AspNet; + +namespace Examples.AspNet +{ + public class WebApiApplication : HttpApplication + { + private ActivityListener aspNetActivityListener; + + protected void Application_Start() + { + this.aspNetActivityListener = new ActivityListener + { + ShouldListenTo = (activitySource) => + { + // Only listen to TelemetryHttpModule's ActivitySource. + return activitySource.Name == TelemetryHttpModule.AspNetSourceName; + }, + Sample = (ref ActivityCreationOptions options) => + { + // Sample everything created by TelemetryHttpModule's ActivitySource. + return ActivitySamplingResult.AllDataAndRecorded; + }, + }; + + ActivitySource.AddActivityListener(this.aspNetActivityListener); + + GlobalConfiguration.Configure(WebApiConfig.Register); + + AreaRegistration.RegisterAllAreas(); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + + protected void Application_End() + { + this.aspNetActivityListener?.Dispose(); + } + } +} +``` + +## Options + +`TelemetryHttpModule` provides a static options property +(`TelemetryHttpModule.Options`) which can be used to configure the +`TelemetryHttpModule` and listen to events it fires. + +### TextMapPropagator + +`TextMapPropagator` controls how trace context will be extracted from incoming +Http request messages. By default, [W3C Trace +Context](https://www.w3.org/TR/trace-context/) is enabled. + +The OpenTelemetry API ships with a handful of [standard +implementations](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Api/Context/Propagation) +which may be used, or you can write your own by deriving from the +`TextMapPropagator` class. + +To add support for +[Baggage](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/baggage/api.md) +propagation in addition to W3C Trace Context, use: + +```csharp +TelemetryHttpModuleOptions.TextMapPropagator = new CompositeTextMapPropagator( + new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + }); +``` + +Note: When using the `OpenTelemetry.Instrumentation.AspNet` +`TelemetryHttpModuleOptions.TextMapPropagator` is automatically initialized to +the SDK default propagator (`Propagators.DefaultTextMapPropagator`) which by +default supports W3C Trace Context & Baggage. + +### Events + +`OnRequestStartedCallback`, `OnRequestStoppedCallback`, & `OnExceptionCallback` +are provided on `TelemetryHttpModuleOptions` and will be fired by the +`TelemetryHttpModule` as requests are processed. + +A typical use case for these events is to add information (tags, events, and/or +links) to the created `Activity` based on the request, response, and/or +exception event being fired. diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs new file mode 100644 index 0000000000..395c5aec12 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -0,0 +1,147 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Reflection; +using System.Web; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// Http Module sets ambient state using Activity API from DiagnosticsSource package. + /// + public class TelemetryHttpModule : IHttpModule + { + /// + /// OpenTelemetry.Instrumentation.AspNet name. + /// + public const string AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry"; + + /// + /// for OpenTelemetry.Instrumentation.AspNet created objects. + /// + public const string AspNetActivityName = "Microsoft.AspNet.HttpReqIn"; + + // ServerVariable set only on rewritten HttpContext by URL Rewrite module. + private const string URLRewriteRewrittenRequest = "IIS_WasUrlRewritten"; + + // ServerVariable set on every request if URL module is registered in HttpModule pipeline. + private const string URLRewriteModuleVersion = "IIS_UrlRewriteModule"; + + private static readonly MethodInfo OnExecuteRequestStepMethodInfo = typeof(HttpApplication).GetMethod("OnExecuteRequestStep"); + + /// + /// Gets the applied to requests processed by the handler. + /// + public static TelemetryHttpModuleOptions Options { get; } = new TelemetryHttpModuleOptions(); + + /// + public void Dispose() + { + } + + /// + public void Init(HttpApplication context) + { + context.BeginRequest += this.Application_BeginRequest; + context.EndRequest += this.Application_EndRequest; + context.Error += this.Application_Error; + + if (HttpRuntime.UsingIntegratedPipeline && OnExecuteRequestStepMethodInfo != null) + { + // OnExecuteRequestStep is availabile starting with 4.7.1 + try + { + OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action)this.OnExecuteRequestStep }); + } + catch (Exception e) + { + AspNetTelemetryEventSource.Log.OnExecuteRequestStepInvocationError(e.Message); + } + } + } + + private void Application_BeginRequest(object sender, EventArgs e) + { + AspNetTelemetryEventSource.Log.TraceCallback("Application_BeginRequest"); + ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, ((HttpApplication)sender).Context, Options.OnRequestStartedCallback); + } + + private void OnExecuteRequestStep(HttpContextBase context, Action step) + { + // Called only on 4.7.1+ runtimes + + if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification) + { + ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context); + } + + step(); + } + + private void Application_EndRequest(object sender, EventArgs e) + { + AspNetTelemetryEventSource.Log.TraceCallback("Application_EndRequest"); + bool trackActivity = true; + + var context = ((HttpApplication)sender).Context; + + if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) + { + // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. + // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. + // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. + // When the child request completes, the parent request executes the end request notifications and completes itself. + // Do not create activity for parent request. Parent request has IIS_UrlRewriteModule ServerVariable with success response code. + // Child request contains an additional ServerVariable named - IIS_WasUrlRewritten. + // Track failed response activity: Different modules in the pipeline has ability to end the response. For example, authentication module could set HTTP 401 in OnBeginRequest and end the response. + if (context.Request.ServerVariables != null && context.Request.ServerVariables[URLRewriteRewrittenRequest] == null && context.Request.ServerVariables[URLRewriteModuleVersion] != null && context.Response.StatusCode == 200) + { + trackActivity = false; + } + else + { + // Activity has never been started + aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); + } + } + + if (trackActivity) + { + ActivityHelper.StopAspNetActivity(Options.TextMapPropagator, aspNetActivity, context, Options.OnRequestStoppedCallback); + } + } + + private void Application_Error(object sender, EventArgs e) + { + AspNetTelemetryEventSource.Log.TraceCallback("Application_Error"); + + var context = ((HttpApplication)sender).Context; + + var exception = context.Error; + if (exception != null) + { + if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) + { + aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); + } + + ActivityHelper.WriteActivityException(aspNetActivity, context, exception, Options.OnExceptionCallback); + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs new file mode 100644 index 0000000000..2d0e42efb0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs @@ -0,0 +1,67 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Web; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// Stores options for the . + /// + public class TelemetryHttpModuleOptions + { + private TextMapPropagator textMapPropagator = new TraceContextPropagator(); + + internal TelemetryHttpModuleOptions() + { + } + + /// + /// Gets or sets the to use to + /// extract from incoming requests. + /// + public TextMapPropagator TextMapPropagator + { + get => this.textMapPropagator; + set + { + Guard.ThrowIfNull(value); + + this.textMapPropagator = value; + } + } + + /// + /// Gets or sets a callback action to be fired when a request is started. + /// + public Action OnRequestStartedCallback { get; set; } + + /// + /// Gets or sets a callback action to be fired when a request is stopped. + /// + public Action OnRequestStoppedCallback { get; set; } + + /// + /// Gets or sets a callback action to be fired when an unhandled + /// exception is thrown processing a request. + /// + public Action OnExceptionCallback { get; set; } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.install.xdt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.install.xdt new file mode 100644 index 0000000000..6605354657 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.install.xdt @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt new file mode 100644 index 0000000000..5b76f2bc42 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/web.config.uninstall.xdt @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs new file mode 100644 index 0000000000..b8242fffa5 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -0,0 +1,546 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using OpenTelemetry.Context.Propagation; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class ActivityHelperTest : IDisposable + { + private const string TraceParentHeaderName = "traceparent"; + private const string TraceStateHeaderName = "tracestate"; + private const string BaggageHeaderName = "baggage"; + private const string BaggageInHeader = "TestKey1=123,TestKey2=456,TestKey1=789"; + private const string TestActivityName = "Activity.Test"; + private readonly TextMapPropagator noopTextMapPropagator = new NoopTextMapPropagator(); + private ActivityListener activitySourceListener; + + public void Dispose() + { + this.activitySourceListener?.Dispose(); + } + + [Fact] + public void Has_Started_Returns_Correctly() + { + var context = HttpContextHelper.GetFakeHttpContext(); + + bool result = ActivityHelper.HasStarted(context, out Activity aspNetActivity); + + Assert.False(result); + Assert.Null(aspNetActivity); + + context.Items[ActivityHelper.ContextKey] = ActivityHelper.StartedButNotSampledObj; + + result = ActivityHelper.HasStarted(context, out aspNetActivity); + + Assert.True(result); + Assert.Null(aspNetActivity); + + Activity activity = new Activity(TestActivityName); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = activity }; + + result = ActivityHelper.HasStarted(context, out aspNetActivity); + + Assert.True(result); + Assert.NotNull(aspNetActivity); + Assert.Equal(activity, aspNetActivity); + } + + [Fact] + public async Task Can_Restore_Activity() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + rootActivity.AddTag("k1", "v1"); + rootActivity.AddTag("k2", "v2"); + + Task testTask; + using (ExecutionContext.SuppressFlow()) + { + testTask = Task.Run(() => + { + Task.Yield(); + + Assert.Null(Activity.Current); + + ActivityHelper.RestoreContextIfNeeded(context); + + Assert.Same(Activity.Current, rootActivity); + }); + } + + await testTask.ConfigureAwait(false); + } + + [Fact(Skip = "Temporarily disable until stable.")] + public async Task Can_Restore_Baggage() + { + this.EnableListener(); + + var requestHeaders = new Dictionary + { + { BaggageHeaderName, BaggageInHeader }, + }; + + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); + + rootActivity.AddTag("k1", "v1"); + rootActivity.AddTag("k2", "v2"); + + Task testTask; + using (ExecutionContext.SuppressFlow()) + { + testTask = Task.Run(() => + { + Task.Yield(); + + Assert.Null(Activity.Current); + Assert.Equal(0, Baggage.Current.Count); + + ActivityHelper.RestoreContextIfNeeded(context); + + Assert.Same(Activity.Current, rootActivity); + Assert.Empty(rootActivity.Baggage); + + Assert.Equal(2, Baggage.Current.Count); + Assert.Equal("789", Baggage.Current.GetBaggage("TestKey1")); + Assert.Equal("456", Baggage.Current.GetBaggage("TestKey2")); + }); + } + + await testTask.ConfigureAwait(false); + } + + [Fact] + public void Can_Stop_Lost_Activity() + { + this.EnableListener(a => + { + Assert.NotNull(Activity.Current); + Assert.Equal(Activity.Current, a); + Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); + }); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + rootActivity.AddTag("k1", "v1"); + rootActivity.AddTag("k2", "v2"); + + Activity.Current = null; + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.Null(Activity.Current); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public void Do_Not_Restore_Activity_When_There_Is_No_Activity_In_Context() + { + this.EnableListener(); + ActivityHelper.RestoreContextIfNeeded(HttpContextHelper.GetFakeHttpContext()); + + Assert.Null(Activity.Current); + } + + [Fact] + public void Do_Not_Restore_Activity_When_It_Is_Not_Lost() + { + this.EnableListener(); + var root = new Activity("root").Start(); + + var context = HttpContextHelper.GetFakeHttpContext(); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = root }; + + ActivityHelper.RestoreContextIfNeeded(context); + + Assert.Equal(root, Activity.Current); + } + + [Fact] + public void Can_Stop_Activity_Without_AspNetListener_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + var rootActivity = new Activity(TestActivityName); + rootActivity.Start(); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; + Thread.Sleep(100); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.Null(rootActivity.Parent); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public void Can_Stop_Activity_With_AspNetListener_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + var rootActivity = new Activity(TestActivityName); + rootActivity.Start(); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; + Thread.Sleep(100); + this.EnableListener(); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.Null(rootActivity.Parent); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public void Can_Stop_Root_Activity_With_All_Children() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + var child = new Activity("child").Start(); + new Activity("grandchild").Start(); + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.True(child.Duration == TimeSpan.Zero); + Assert.Null(rootActivity.Parent); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public void Can_Stop_Root_While_Child_Is_Current() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + var child = new Activity("child").Start(); + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.True(child.Duration == TimeSpan.Zero); + Assert.NotNull(Activity.Current); + Assert.Equal(Activity.Current, child); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public async Task Can_Stop_Root_Activity_If_It_Is_Broken() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + new Activity("child").Start(); + + for (int i = 0; i < 2; i++) + { + await Task.Run(() => + { + // when we enter this method, Current is 'child' activity + Activity.Current.Stop(); + + // here Current is 'parent', but only in this execution context + }); + } + + // when we return back here, in the 'parent' execution context + // Current is still 'child' activity - changes in child context (inside Task.Run) + // do not affect 'parent' context in which Task.Run is called. + // But 'child' Activity is stopped, thus consequent calls to Stop will + // not update Current + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, root, context, null); + Assert.True(root.Duration != TimeSpan.Zero); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + Assert.Null(Activity.Current); + } + + [Fact] + public void Stop_Root_Activity_With_129_Nesting_Depth() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + for (int i = 0; i < 129; i++) + { + new Activity("child" + i).Start(); + } + + // can stop any activity regardless of the stack depth + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, root, context, null); + + Assert.True(root.Duration != TimeSpan.Zero); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + Assert.NotNull(Activity.Current); + } + + [Fact] + public void Should_Not_Create_RootActivity_If_AspNetListener_Not_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + Assert.Null(rootActivity); + Assert.Equal(ActivityHelper.StartedButNotSampledObj, context.Items[ActivityHelper.ContextKey]); + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public void Should_Not_Create_RootActivity_If_AspNetActivity_Not_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + this.EnableListener(onSample: (context) => ActivitySamplingResult.None); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + Assert.Null(rootActivity); + Assert.Equal(ActivityHelper.StartedButNotSampledObj, context.Items[ActivityHelper.ContextKey]); + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } + + [Fact] + public void Can_Create_RootActivity_From_W3C_Traceparent() + { + this.EnableListener(); + var requestHeaders = new Dictionary + { + { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-00" }, + }; + + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new TraceContextPropagator(), context, null); + + Assert.NotNull(rootActivity); + Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); + Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00", rootActivity.ParentId); + Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); + Assert.True(rootActivity.Recorded); // note: We're not using a parent-based sampler in this test so the recorded flag of traceparent is ignored. + + Assert.Null(rootActivity.TraceStateString); + Assert.Empty(rootActivity.Baggage); + + Assert.Equal(0, Baggage.Current.Count); + } + + [Fact] + public void Can_Create_RootActivityWithTraceState_From_W3C_TraceContext() + { + this.EnableListener(); + var requestHeaders = new Dictionary + { + { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01" }, + { TraceStateHeaderName, "ts1=v1,ts2=v2" }, + }; + + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new TraceContextPropagator(), context, null); + + Assert.NotNull(rootActivity); + Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); + Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01", rootActivity.ParentId); + Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); + Assert.True(rootActivity.Recorded); + + Assert.Equal("ts1=v1,ts2=v2", rootActivity.TraceStateString); + Assert.Empty(rootActivity.Baggage); + + Assert.Equal(0, Baggage.Current.Count); + } + + [Fact] + public void Can_Create_RootActivity_From_W3C_Traceparent_With_Baggage() + { + this.EnableListener(); + var requestHeaders = new Dictionary + { + { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-00" }, + { BaggageHeaderName, BaggageInHeader }, + }; + + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); + + Assert.NotNull(rootActivity); + Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); + Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00", rootActivity.ParentId); + Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); + Assert.True(rootActivity.Recorded); // note: We're not using a parent-based sampler in this test so the recorded flag of traceparent is ignored. + + Assert.Null(rootActivity.TraceStateString); + Assert.Empty(rootActivity.Baggage); + + Assert.Equal(2, Baggage.Current.Count); + Assert.Equal("789", Baggage.Current.GetBaggage("TestKey1")); + Assert.Equal("456", Baggage.Current.GetBaggage("TestKey2")); + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.Equal(0, Baggage.Current.Count); + } + + [Fact] + public void Can_Create_RootActivity_And_Start_Activity() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + Assert.NotNull(rootActivity); + Assert.True(!string.IsNullOrEmpty(rootActivity.Id)); + } + + [Fact] + public void Can_Create_RootActivity_And_Saved_In_HttContext() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + Assert.NotNull(rootActivity); + Assert.Same(rootActivity, ((ActivityHelper.ContextHolder)context.Items[ActivityHelper.ContextKey])?.Activity); + } + + [Fact] + public void Fire_Exception_Events() + { + int callbacksFired = 0; + + var context = HttpContextHelper.GetFakeHttpContext(); + + Activity activity = new Activity(TestActivityName); + + ActivityHelper.WriteActivityException(activity, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); + + ActivityHelper.WriteActivityException(null, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); + + // Callback should fire only for non-null activity + Assert.Equal(1, callbacksFired); + } + + private void EnableListener(Action onStarted = null, Action onStopped = null, Func onSample = null) + { + Debug.Assert(this.activitySourceListener == null, "Cannot attach multiple listeners in tests."); + + this.activitySourceListener = new ActivityListener + { + ShouldListenTo = (activitySource) => activitySource.Name == TelemetryHttpModule.AspNetSourceName, + ActivityStarted = (a) => onStarted?.Invoke(a), + ActivityStopped = (a) => onStopped?.Invoke(a), + Sample = (ref ActivityCreationOptions options) => + { + if (onSample != null) + { + return onSample(options.Parent); + } + + return ActivitySamplingResult.AllDataAndRecorded; + }, + }; + + ActivitySource.AddActivityListener(this.activitySourceListener); + } + + private class TestHttpRequest : HttpRequestBase + { + private readonly NameValueCollection headers = new(); + + public override NameValueCollection Headers => this.headers; + + public override UnvalidatedRequestValuesBase Unvalidated => new TestUnvalidatedRequestValues(this.headers); + } + + private class TestUnvalidatedRequestValues : UnvalidatedRequestValuesBase + { + public TestUnvalidatedRequestValues(NameValueCollection headers) + { + this.Headers = headers; + } + + public override NameValueCollection Headers { get; } + } + + private class TestHttpResponse : HttpResponseBase + { + } + + private class TestHttpServerUtility : HttpServerUtilityBase + { + private readonly HttpContextBase context; + + public TestHttpServerUtility(HttpContextBase context) + { + this.context = context; + } + + public override Exception GetLastError() + { + return this.context.Error; + } + } + + private class TestHttpContext : HttpContextBase + { + private readonly Hashtable items; + + public TestHttpContext(Exception error = null) + { + this.Server = new TestHttpServerUtility(this); + this.items = new Hashtable(); + this.Error = error; + } + + public override HttpRequestBase Request { get; } = new TestHttpRequest(); + + /// + public override IDictionary Items => this.items; + + public override Exception Error { get; } + + public override HttpServerUtilityBase Server { get; } + } + + private class NoopTextMapPropagator : TextMapPropagator + { + private static readonly PropagationContext DefaultPropagationContext = default; + + public override ISet Fields => null; + + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + { + return DefaultPropagationContext; + } + + public override void Inject(PropagationContext context, T carrier, Action setter) + { + } + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs new file mode 100644 index 0000000000..e9920ef16b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -0,0 +1,103 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Threading; +using System.Web; +using System.Web.Hosting; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + internal class HttpContextHelper + { + public static HttpContext GetFakeHttpContext(string page = "/page", string query = "", IDictionary headers = null) + { + Thread.GetDomain().SetData(".appPath", string.Empty); + Thread.GetDomain().SetData(".appVPath", string.Empty); + + var workerRequest = new SimpleWorkerRequestWithHeaders(page, query, new StringWriter(CultureInfo.InvariantCulture), headers); + var context = new HttpContext(workerRequest); + HttpContext.Current = context; + return context; + } + + public static HttpContextBase GetFakeHttpContextBase(string page = "/page", string query = "", IDictionary headers = null) + { + var context = GetFakeHttpContext(page, query, headers); + return new HttpContextWrapper(context); + } + + private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest + { + private readonly IDictionary headers; + + public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary headers) + : base(page, query, output) + { + if (headers != null) + { + this.headers = headers; + } + else + { + this.headers = new Dictionary(); + } + } + + public override string[][] GetUnknownRequestHeaders() + { + List result = new List(); + + foreach (var header in this.headers) + { + result.Add(new string[] { header.Key, header.Value }); + } + + var baseResult = base.GetUnknownRequestHeaders(); + if (baseResult != null) + { + result.AddRange(baseResult); + } + + return result.ToArray(); + } + + public override string GetUnknownRequestHeader(string name) + { + if (this.headers.ContainsKey(name)) + { + return this.headers[name]; + } + + return base.GetUnknownRequestHeader(name); + } + + public override string GetKnownRequestHeader(int index) + { + var name = GetKnownRequestHeaderName(index); + + if (this.headers.ContainsKey(name)) + { + return this.headers[name]; + } + + return base.GetKnownRequestHeader(index); + } + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj new file mode 100644 index 0000000000..0a4edd08a1 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -0,0 +1,34 @@ + + + Unit test project for ASP.NET HttpModule + + net462 + false + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + Resources\web.config.install.xdt + + + Resources\web.config.uninstall.xdt + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs new file mode 100644 index 0000000000..c0ddbe96b1 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs @@ -0,0 +1,409 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.IO; +using System.Xml.Linq; +using Microsoft.Web.XmlTransform; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class WebConfigTransformTest + { + private const string InstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.install.xdt"; + private const string UninstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.uninstall.xdt"; + + [Fact] + public void VerifyInstallationToBasicWebConfig() + { + const string OriginalWebConfigContent = @" + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyUpdateWithTypeRenamingWebConfig() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyUpdateNewerVersionWebConfig() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyUpdateWithIntegratedModeWebConfig() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyUninstallationWithBasicWebConfig() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + "; + + var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyUninstallWithIntegratedPrecondition() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + "; + + var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyUninstallationWithUserModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToWebConfigWithUserModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToEmptyWebConfig() + { + const string OriginalWebConfigContent = @""; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToWebConfigWithoutModules() + { + const string OriginalWebConfigContent = @""; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + private XDocument ApplyInstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } + + private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } + + private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) + { + Assert.True( + XNode.DeepEquals( + transformedWebConfig.FirstNode, + XDocument.Parse(expectedConfigContent).FirstNode)); + } + + private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) + { + XDocument result; + Stream stream = null; + try + { + stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); + var document = new XmlTransformableDocument(); + using var transformation = new XmlTransformation(stream, null); + stream = null; + document.LoadXml(originalConfiguration); + transformation.Apply(document); + result = XDocument.Parse(document.OuterXml); + } + finally + { + if (stream != null) + { + stream.Dispose(); + } + } + + return result; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs new file mode 100644 index 0000000000..e8415130ca --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -0,0 +1,439 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.IO; +using System.Xml.Linq; +using Microsoft.Web.XmlTransform; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class WebConfigWithLocationTagTransformTest + { + private const string InstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.install.xdt"; + + [Fact] + public void VerifyInstallationWhenNonGlobalLocationTagExists() + { + const string OriginalWebConfigContent = @" + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationWhenGlobalAndNonGlobalLocationTagExists() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToLocationTagWithDotPathAndExistingModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToLocationTagWithEmptyPathAndExistingModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToLocationTagWithDotPathWithNoModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToLocationTagWithEmptyPathWithNoModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToLocationTagWithDotPathWithGlobalModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + [Fact] + public void VerifyInstallationToLocationTagWithEmptyPathWithGlobalModules() + { + const string OriginalWebConfigContent = @" + + + + + + + + + + + + + + "; + + const string ExpectedWebConfigContent = @" + + + + + + + + + + + + + + + + + + "; + + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } + + private XDocument ApplyInstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } + + private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } + + private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) + { + Assert.True( + XNode.DeepEquals( + transformedWebConfig.FirstNode, + XDocument.Parse(expectedConfigContent).FirstNode)); + } + + private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) + { + XDocument result; + Stream stream = null; + try + { + stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); + var document = new XmlTransformableDocument(); + using var transformation = new XmlTransformation(stream, null); + stream = null; + document.LoadXml(originalConfiguration); + transformation.Apply(document); + result = XDocument.Parse(document.OuterXml); + } + finally + { + if (stream != null) + { + stream.Dispose(); + } + } + + return result; + } + } +} From 768d94bf9c1a05bc1f0ba5dfd70161310f8d3c78 Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Fri, 10 Jun 2022 17:55:06 +0200 Subject: [PATCH 0158/1499] [Instana Exporter] Unit test fix (#417) --- .../InstanaSpanSerializerTests.cs | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 3ccb37f44f..8b4a1c8ecf 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -28,28 +28,28 @@ public class InstanaSpanSerializerTests { private InstanaSpanSerializer instanaSpanSerializer = new InstanaSpanSerializer(); - [Fact(Skip = "Borken unit test. https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/405")] + [Fact] public async Task SerializeToStreamWriterAsync() { - InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); - instanaSpan.F = new OpenTelemetry.Exporter.Instana.Implementation.From() { E = "12345", H = "localhost" }; - instanaSpan.N = "otel"; - instanaSpan.T = "hexNumberT1234"; - instanaSpan.S = "hexNumberS1234"; - instanaSpan.P = "hexNumberP1234"; - instanaSpan.Ec = 1; - instanaSpan.D = 123456; - instanaSpan.Lt = "hexNumberLT1234567890123"; - instanaSpan.Tp = true; - instanaSpan.Data.Tags = new Dictionary(); - instanaSpan.Data.Tags["tag1Key"] = "tag1Vale"; - instanaSpan.Data.Tags["tag2Key"] = "tag2Vale"; - instanaSpan.Data.data = new Dictionary(); - instanaSpan.Data.data["data1Key"] = "data1Vale"; - instanaSpan.Data.data["data2Key"] = "data2Vale"; - instanaSpan.Data.Events = new List() + InstanaSpan instanaOtelSpan = InstanaSpanFactory.CreateSpan(); + instanaOtelSpan.F = new Implementation.From() { E = "12345", H = "localhost" }; + instanaOtelSpan.N = "otel"; + instanaOtelSpan.T = "hexNumberT1234"; + instanaOtelSpan.S = "hexNumberS1234"; + instanaOtelSpan.P = "hexNumberP1234"; + instanaOtelSpan.Ec = 1; + instanaOtelSpan.D = 123456; + instanaOtelSpan.Lt = "hexNumberLT1234567890123"; + instanaOtelSpan.Tp = true; + instanaOtelSpan.Data.Tags = new Dictionary(); + instanaOtelSpan.Data.Tags["tag1Key"] = "tag1Vale"; + instanaOtelSpan.Data.Tags["tag2Key"] = "tag2Vale"; + instanaOtelSpan.Data.data = new Dictionary(); + instanaOtelSpan.Data.data["data1Key"] = "data1Vale"; + instanaOtelSpan.Data.data["data2Key"] = "data2Vale"; + instanaOtelSpan.Data.Events = new List() { - new OpenTelemetry.Exporter.Instana.Implementation.SpanEvent() + new Implementation.SpanEvent() { Name = "testEvent", Ts = 111111, Tags = new Dictionary() { { "eventTagKey", "eventTagValue" } }, @@ -66,7 +66,7 @@ public async Task SerializeToStreamWriterAsync() { using (StreamWriter writer = new StreamWriter(sendBuffer)) { - await this.instanaSpanSerializer.SerializeToStreamWriterAsync(instanaSpan, writer); + await this.instanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); await writer.FlushAsync(); long length = sendBuffer.Position; sendBuffer.Position = 0; @@ -84,22 +84,22 @@ public async Task SerializeToStreamWriterAsync() } Assert.NotNull(span); - Assert.Equal(instanaSpan.S, span.S); - Assert.Equal(instanaSpan.T, span.T); - Assert.Equal(instanaSpan.P, span.P); - Assert.Equal(instanaSpan.N, span.N); - Assert.Equal(instanaSpan.F.E, span.F.E); - Assert.Equal(instanaSpan.Ec, span.Ec); - Assert.Equal(instanaSpan.D, span.D); - Assert.Equal(instanaSpan.Lt, span.Lt); - Assert.Equal(instanaSpan.Data.Tags["tag1Key"], span.Data.Tags["tag1Key"]); - Assert.Equal(instanaSpan.Data.Tags["tag2Key"], span.Data.Tags["tag2Key"]); - Assert.Equal(instanaSpan.Data.data["data1Key"], span.Data.data["data1Key"]); - Assert.Equal(instanaSpan.Data.data["data2Key"], span.Data.data["data2Key"]); - Assert.Equal(instanaSpan.Data.Events[0].Name, span.Data.Events[0].Name); - Assert.Equal(instanaSpan.Data.Events[0].Tags["eventTagKey"], span.Data.Events[0].Tags["eventTagKey"]); - Assert.Equal(instanaSpan.Data.Events[1].Name, span.Data.Events[1].Name); - Assert.Equal(instanaSpan.Data.Events[1].Tags["eventTag2Key"], span.Data.Events[1].Tags["eventTag2Key"]); + Assert.Equal(instanaOtelSpan.S, span.S); + Assert.Equal(instanaOtelSpan.T, span.T); + Assert.Equal(instanaOtelSpan.P, span.P); + Assert.Equal(instanaOtelSpan.N, span.N); + Assert.Equal(instanaOtelSpan.F.E, span.F.E); + Assert.Equal(instanaOtelSpan.Ec, span.Ec); + Assert.Equal(instanaOtelSpan.D / 10_000, span.D); + Assert.Equal(instanaOtelSpan.Lt, span.Lt); + Assert.Equal(instanaOtelSpan.Data.Tags["tag1Key"], span.Data.Tags["tag1Key"]); + Assert.Equal(instanaOtelSpan.Data.Tags["tag2Key"], span.Data.Tags["tag2Key"]); + Assert.Equal(instanaOtelSpan.Data.data["data1Key"], span.Data.data["data1Key"]); + Assert.Equal(instanaOtelSpan.Data.data["data2Key"], span.Data.data["data2Key"]); + Assert.Equal(instanaOtelSpan.Data.Events[0].Name, span.Data.Events[0].Name); + Assert.Equal(instanaOtelSpan.Data.Events[0].Tags["eventTagKey"], span.Data.Events[0].Tags["eventTagKey"]); + Assert.Equal(instanaOtelSpan.Data.Events[1].Name, span.Data.Events[1].Name); + Assert.Equal(instanaOtelSpan.Data.Events[1].Tags["eventTag2Key"], span.Data.Events[1].Tags["eventTag2Key"]); } } } From 5ac01faab5d5dac363313fdaac6798962a99d2df Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 10 Jun 2022 16:24:33 -0700 Subject: [PATCH 0159/1499] Fix some bugs in Runtime metrics (#409) * Update instrument types, value types and units and some renames --- .../CHANGELOG.md | 2 ++ .../RuntimeMetrics.cs | 31 ++++++++++--------- .../RuntimeMetricsTests.cs | 21 +------------ 3 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 8228e83493..3539aa3695 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -4,6 +4,8 @@ * Updated OTel SDK package version to 1.3.0 ([#411](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/411)) +* Fix some bugs in Runtime metrics + ([#409](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/409)) ## 0.1.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 955e8f929a..513dfc07d8 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -33,6 +33,7 @@ internal class RuntimeMetrics : IDisposable internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); internal static readonly string InstrumentationName = AssemblyName.Name; internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + private const long NanosecondsPerTick = 100; private static string metricPrefix = "process.runtime.dotnet."; private readonly Meter meter; @@ -46,17 +47,19 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsGcEnabled) { + // TODO: Almost all the ObservableGauge should be ObservableUpDownCounter (except for CPU utilization and fragmentation.ratio. + // Replace them once ObservableUpDownCounter is available. this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "By", "GC Heap Size"); this.meter.CreateObservableGauge($"{metricPrefix}gen_0-gc.count", () => GC.CollectionCount(0), description: "Gen 0 GC Count"); this.meter.CreateObservableGauge($"{metricPrefix}gen_1-gc.count", () => GC.CollectionCount(1), description: "Gen 1 GC Count"); this.meter.CreateObservableGauge($"{metricPrefix}gen_2-gc.count", () => GC.CollectionCount(2), description: "Gen 2 GC Count"); #if NETCOREAPP3_1_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}alloc.rate", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate"); - this.meter.CreateObservableCounter($"{metricPrefix}gc.fragmentation", GetFragmentation, description: "GC Fragmentation"); + this.meter.CreateObservableCounter($"{metricPrefix}gc.allocated.bytes", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate"); + this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.ratio", GetFragmentation, description: "GC Fragmentation"); #endif #if NET6_0_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}gc.committed", () => (double)(GC.GetGCMemoryInfo().TotalCommittedBytes / 1_000_000), "Mi", description: "GC Committed Bytes"); + this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GC.GetGCMemoryInfo().TotalCommittedBytes, "By", description: "GC Committed Bytes"); #endif } @@ -65,7 +68,7 @@ public RuntimeMetrics(RuntimeMetricsOptions options) { this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "By", description: "IL Bytes Jitted"); this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted"); - this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().TotalMilliseconds, "ms", description: "Time spent in JIT"); + this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, "ns", description: "Time spent in JIT"); } #endif @@ -73,26 +76,26 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsThreadingEnabled) { this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count"); - this.meter.CreateObservableCounter($"{metricPrefix}threadpool.thread.count", () => ThreadPool.ThreadCount, description: "ThreadPool Thread Count"); + this.meter.CreateObservableGauge($"{metricPrefix}threadpool.thread.count", () => (long)ThreadPool.ThreadCount, description: "ThreadPool Thread Count"); this.meter.CreateObservableGauge($"{metricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count"); - this.meter.CreateObservableCounter($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length"); - this.meter.CreateObservableCounter($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers"); + this.meter.CreateObservableGauge($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length"); + this.meter.CreateObservableGauge($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers"); } #endif if (options.IsProcessEnabled) { - this.meter.CreateObservableCounter("process.cpu.time", this.GetProcessorTimes, "s", "Processor time of this process"); + this.meter.CreateObservableCounter("process.cpu.time", this.GetProcessorTimes, "ns", "Processor time of this process"); // Not yet official: https://github.com/open-telemetry/opentelemetry-specification/pull/2392 - this.meter.CreateObservableGauge("process.cpu.count", () => Environment.ProcessorCount, description: "The number of available logical CPUs"); + this.meter.CreateObservableGauge("process.cpu.count", () => (long)Environment.ProcessorCount, description: "The number of available logical CPUs"); this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use"); this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory"); } if (options.IsAssembliesEnabled) { - this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); + this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); } } @@ -106,17 +109,17 @@ public void Dispose() private static double GetFragmentation() { var gcInfo = GC.GetGCMemoryInfo(); - return gcInfo.HeapSizeBytes != 0 ? gcInfo.FragmentedBytes * 100d / gcInfo.HeapSizeBytes : 0; + return gcInfo.HeapSizeBytes != 0 ? gcInfo.FragmentedBytes * 1.0d / gcInfo.HeapSizeBytes : 0; } #endif - private IEnumerable> GetProcessorTimes() + private IEnumerable> GetProcessorTimes() { var process = Process.GetCurrentProcess(); return new[] { - new Measurement(process.UserProcessorTime.TotalSeconds, new KeyValuePair("state", "user")), - new Measurement(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("state", "system")), + new Measurement(process.UserProcessorTime.Ticks * NanosecondsPerTick, new KeyValuePair("state", "user")), + new Measurement(process.PrivilegedProcessorTime.Ticks * NanosecondsPerTick, new KeyValuePair("state", "system")), }; } } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 997a62f6d6..618ca36614 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -78,7 +78,7 @@ public void ProcessMetricsAreCaptured() Assert.Equal(4, exportedItems.Count); var cpuTimeMetric = exportedItems.First(i => i.Name == "process.cpu.time"); - var sumReceived = GetDoubleSum(cpuTimeMetric); + var sumReceived = GetLongSum(cpuTimeMetric); Assert.True(sumReceived > 0); var cpuCountMetric = exportedItems.First(i => i.Name == "process.cpu.count"); @@ -91,25 +91,6 @@ public void ProcessMetricsAreCaptured() Assert.True(GetLongSum(virtualMemoryMetric) > 0); } - private static double GetDoubleSum(Metric metric) - { - double sum = 0; - - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) - { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumDouble(); - } - else - { - sum += metricPoint.GetGaugeLastValueDouble(); - } - } - - return sum; - } - private static double GetLongSum(Metric metric) { double sum = 0; From 667cf28685a18d518d7ec3f233d08ad8b74a13f4 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 10 Jun 2022 17:08:54 -0700 Subject: [PATCH 0160/1499] Add GC heap size and count in Runtime metrics (#412) * Add `gc.heapsize` and change `gc.count` to multi-dimensional metrics --- .../CHANGELOG.md | 2 + .../RuntimeMetrics.cs | 75 ++++++++++++------- .../RuntimeMetricsTests.cs | 21 +++++- 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 3539aa3695..895d745764 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -6,6 +6,8 @@ ([#411](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/411)) * Fix some bugs in Runtime metrics ([#409](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/409)) +* Add GC heap size and refactor GC count as multi-dimensional metrics in Runtime + metrics ([#412](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/412)) ## 0.1.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 513dfc07d8..ebae341a47 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -34,6 +34,8 @@ internal class RuntimeMetrics : IDisposable internal static readonly string InstrumentationName = AssemblyName.Name; internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); private const long NanosecondsPerTick = 100; + private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; + private static readonly int NumberOfGenerations = 3; private static string metricPrefix = "process.runtime.dotnet."; private readonly Meter meter; @@ -49,53 +51,53 @@ public RuntimeMetrics(RuntimeMetricsOptions options) { // TODO: Almost all the ObservableGauge should be ObservableUpDownCounter (except for CPU utilization and fragmentation.ratio. // Replace them once ObservableUpDownCounter is available. - this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "By", "GC Heap Size"); - this.meter.CreateObservableGauge($"{metricPrefix}gen_0-gc.count", () => GC.CollectionCount(0), description: "Gen 0 GC Count"); - this.meter.CreateObservableGauge($"{metricPrefix}gen_1-gc.count", () => GC.CollectionCount(1), description: "Gen 1 GC Count"); - this.meter.CreateObservableGauge($"{metricPrefix}gen_2-gc.count", () => GC.CollectionCount(2), description: "Gen 2 GC Count"); + this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "By", "GC Heap Size."); + this.meter.CreateObservableGauge($"{metricPrefix}gc.count", () => GetGarbageCollectionCounts(), description: "GC Count for all generations."); + #if NETCOREAPP3_1_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}gc.allocated.bytes", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate"); - this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.ratio", GetFragmentation, description: "GC Fragmentation"); + this.meter.CreateObservableCounter($"{metricPrefix}gc.allocated.bytes", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate."); + this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.ratio", GetFragmentation, description: "GC Fragmentation."); #endif #if NET6_0_OR_GREATER - this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GC.GetGCMemoryInfo().TotalCommittedBytes, "By", description: "GC Committed Bytes"); + this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GC.GetGCMemoryInfo().TotalCommittedBytes, "By", description: "GC Committed Bytes."); + this.meter.CreateObservableGauge($"{metricPrefix}gc.heapsize", () => GetGarbageCollectionHeapSizes(), "By", "Heap size for all generations."); #endif } #if NET6_0_OR_GREATER if (options.IsJitEnabled) { - this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "By", description: "IL Bytes Jitted"); - this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted"); - this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, "ns", description: "Time spent in JIT"); + this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "By", description: "IL Bytes Jitted."); + this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted."); + this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, "ns", description: "Time spent in JIT."); } #endif #if NETCOREAPP3_1_OR_GREATER if (options.IsThreadingEnabled) { - this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count"); - this.meter.CreateObservableGauge($"{metricPrefix}threadpool.thread.count", () => (long)ThreadPool.ThreadCount, description: "ThreadPool Thread Count"); - this.meter.CreateObservableGauge($"{metricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count"); - this.meter.CreateObservableGauge($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length"); - this.meter.CreateObservableGauge($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers"); + this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count."); + this.meter.CreateObservableGauge($"{metricPrefix}threadpool.thread.count", () => (long)ThreadPool.ThreadCount, description: "ThreadPool Thread Count."); + this.meter.CreateObservableGauge($"{metricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count."); + this.meter.CreateObservableGauge($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length."); + this.meter.CreateObservableGauge($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers."); } #endif if (options.IsProcessEnabled) { - this.meter.CreateObservableCounter("process.cpu.time", this.GetProcessorTimes, "ns", "Processor time of this process"); + this.meter.CreateObservableCounter("process.cpu.time", GetProcessorTimes, "s", "Processor time of this process."); // Not yet official: https://github.com/open-telemetry/opentelemetry-specification/pull/2392 - this.meter.CreateObservableGauge("process.cpu.count", () => (long)Environment.ProcessorCount, description: "The number of available logical CPUs"); - this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use"); - this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory"); + this.meter.CreateObservableGauge("process.cpu.count", () => (long)Environment.ProcessorCount, description: "The number of available logical CPUs."); + this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use."); + this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory."); } if (options.IsAssembliesEnabled) { - this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded"); + this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); } } @@ -105,6 +107,14 @@ public void Dispose() this.meter?.Dispose(); } + private static IEnumerable> GetGarbageCollectionCounts() + { + for (int i = 0; i < NumberOfGenerations; ++i) + { + yield return new(GC.CollectionCount(i), new KeyValuePair("gen", GenNames[i])); + } + } + #if NETCOREAPP3_1_OR_GREATER private static double GetFragmentation() { @@ -113,14 +123,27 @@ private static double GetFragmentation() } #endif - private IEnumerable> GetProcessorTimes() +#if NET6_0_OR_GREATER + private static IEnumerable> GetGarbageCollectionHeapSizes() { - var process = Process.GetCurrentProcess(); - return new[] + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) { - new Measurement(process.UserProcessorTime.Ticks * NanosecondsPerTick, new KeyValuePair("state", "user")), - new Measurement(process.PrivilegedProcessorTime.Ticks * NanosecondsPerTick, new KeyValuePair("state", "system")), - }; + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("gen", GenNames[i])); + } + + return measurements; + } +#endif + + private static IEnumerable> GetProcessorTimes() + { + var process = Process.GetCurrentProcess(); + yield return new(process.UserProcessorTime.TotalSeconds, new KeyValuePair("state", "user")); + yield return new(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("state", "system")); } } } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 618ca36614..997a62f6d6 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -78,7 +78,7 @@ public void ProcessMetricsAreCaptured() Assert.Equal(4, exportedItems.Count); var cpuTimeMetric = exportedItems.First(i => i.Name == "process.cpu.time"); - var sumReceived = GetLongSum(cpuTimeMetric); + var sumReceived = GetDoubleSum(cpuTimeMetric); Assert.True(sumReceived > 0); var cpuCountMetric = exportedItems.First(i => i.Name == "process.cpu.count"); @@ -91,6 +91,25 @@ public void ProcessMetricsAreCaptured() Assert.True(GetLongSum(virtualMemoryMetric) > 0); } + private static double GetDoubleSum(Metric metric) + { + double sum = 0; + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumDouble(); + } + else + { + sum += metricPoint.GetGaugeLastValueDouble(); + } + } + + return sum; + } + private static double GetLongSum(Metric metric) { double sum = 0; From 5cfb426e1818aefff0aa782f60b1214c59157503 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 10 Jun 2022 17:23:29 -0700 Subject: [PATCH 0161/1499] Make a release for OpenTelemetry.Instrumentation.Runtime with new version 0.2.0-alpha.1 (#420) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 895d745764..115f7b72f0 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.2.0-alpha.1 + * Updated OTel SDK package version to 1.3.0 ([#411](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/411)) * Fix some bugs in Runtime metrics From 645e089e493ce0f3148698c1a86f735e5f0c80dc Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 13 Jun 2022 08:31:28 -0700 Subject: [PATCH 0162/1499] [PersistentStorage.Extensions] Update Readme (#419) * draft * update readme * resolve PR comments --- .../README.md | 2 +- .../README.md | 77 ++++++++++--------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md index adbb4a187e..e96b83a75c 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md @@ -1,4 +1,4 @@ -# Persistent Storage Interface +# Persistent Storage Abstractions This package includes APIs which can be extended by exporter owners to implement persistent storage. diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/README.md b/src/OpenTelemetry.Extensions.PersistentStorage/README.md index 98447c372a..c8c2749ac3 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/README.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage/README.md @@ -1,12 +1,12 @@ -# Persistent Storage Interface and Implementation +# Persistent Storage file based implementation [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) -This package provides both the interface and implementation of persistent -storage. It is an experimental component which can be used by OpenTelemetry -Exporters to provide reliable data delivery. Eventually this component should -get splitted into the abstract interface and concrete implementations. +This package provides an implementation of +[persistent-storage-abstractions](../OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md#Persistent-Storage-Abstractions) +based on local file system. This component can be used by OpenTelemetry +exporters to improve the reliability of data delivery. ## Installation @@ -16,18 +16,18 @@ dotnet add package OpenTelemetry.Extensions.PersistentStorage ## Basic Usage -### Setup Storage +### Setup FileBlobProvider ```csharp -using var storage = new FileStorage("test"); +using var persistentBlobProvider = new FileBlobProvider("test"); ``` Following is the complete list of configurable options that can be used to set -up storage: +up FileBlobProvider: -* `path`: Sets file storage folder location where blobs are stored. +* `path`: Sets folder location where blobs are stored. -* `maxSizeInBytes`: Maximum allowed storage folder size. Default is 50 MB. +* `maxSizeInBytes`: Maximum allowed folder size. Default is 50 MB. * `maintenancePeriodInMilliseconds`: Maintenance event runs at specified interval. Default is 2 minutes. Maintenance event performs the following tasks: @@ -45,29 +45,31 @@ blob. Default is 1 minute. ### CreateBlob -`CreateBlob(byte[] buffer, int leasePeriodMilliseconds = 0)` method can be used +`TryCreateBlob(byte[] buffer, out PersistentBlob blob)` or `TryCreateBlob(byte[] +buffer, int leasePeriodMilliseconds = 0, out PersistentBlob blob)` can be used to store data on disk in case of failures. The file stored will have `.blob` extension. If acquiring lease, the file will have `.lock` extension. ```csharp -IPersistentBlob blob = storage.CreateBlob(data); +// Try create blob without acquiring lease +persistentBlobProvider.TryCreateBlob(data, out var blob); -// Create blob and acquire lease -IPersistentBlob blob = storage.CreateBlob(data, 10); +// Try create blob and acquire lease +persistentBlobProvider.TryCreateBlob(data, 1000, out var blob); ``` ### GetBlob and GetBlobs -`GetBlob` can be used to read single blob or `GetBlobs` can be used to get list +`TryGetBlob` can be used to read single blob or `GetBlobs` can be used to get list of all blobs stored on disk. The result will only include files with `.blob` extension. ```csharp // Get single blob from storage. -IPersistentBlob blob1 = storage.GetBlob(); +persistentBlobProvider.GetBlob(out var blob); // List all blobs. -foreach (var blobItem in storage.GetBlobs()) +foreach (var blobItem in persistentBlobProvider.GetBlobs()) { Console.WriteLine(((FileBlob)blobItem).FullPath); } @@ -75,64 +77,65 @@ foreach (var blobItem in storage.GetBlobs()) ### Lease -When reading data back from disk, `Lease(int leasePeriodMilliseconds)` method +When reading data back from disk, `TryLease(int leasePeriodMilliseconds)` method should be used first to acquire lease on blob. This prevents it to be read concurrently, until the lease period expires. Leasing a blob changes the file extension to `.lock`. ```csharp -IPersistentBlob blob2 = blob1.Lease(10); +blob.TryLease(1000); ``` ### Read -Once the lease is acquired on the blob, the data can be read using `Read` -method. +Once the lease is acquired on the blob, the data can be read using +`TryRead(out var data)` method. ```csharp -byte[] data = blob2.Read(); +blob.TryRead(out var data); ``` ### Delete -`Delete` method can be used to delete the blob. +`TryDelete` method can be used to delete the blob. ```csharp -blob2.Delete(); +blob.TryDelete(); ``` ## Example ```csharp -using var storage = new FileStorage("test"); +using var persistentBlobProvider = new FileBlobProvider("test"); var data = Encoding.UTF8.GetBytes("Hello, World!"); // Create blob. -IPersistentBlob blob1 = storage.CreateBlob(data); +persistentBlobProvider.TryCreateBlob(data, out var createdBlob); // List all blobs. -foreach (var blobItem in storage.GetBlobs()) +foreach (var blobItem in persistentBlobProvider.GetBlobs()) { Console.WriteLine(((FileBlob)blobItem).FullPath); } -// Get blob. -IPersistentBlob blob2 = storage.GetBlob(); - -if(blob2 != null) +// Get single blob. +if (persistentBlobProvider.TryGetBlob(out var blob)) { // Lease before reading - IPersistentBlob blob3 = blob2.Lease(10); - - // Check if the lease is acquired - if (blob3 != null) + if (blob.TryLease(1000)) { // Read - System.Text.Encoding.UTF8.GetString(blob3.Read()); + if (blob.TryRead(out var outputData)) + { + Console.WriteLine(Encoding.UTF8.GetString(outputData)); + } // Delete - blob3.Delete(); + if (blob.TryDelete()) + { + Console.WriteLine("Successfully deleted the blob"); + } } } ``` From 7ef196647e5536b628d503216e2d6c64149797fe Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 13 Jun 2022 09:04:51 -0700 Subject: [PATCH 0163/1499] Add AspNet instrumentation (#414) --- .../comp_instrumentation_AspNet.md | 41 ++ .../package-Instrumentation.AspNet.yml | 49 +++ opentelemetry-dotnet-contrib.sln | 15 + .../Api/SpanHelper.cs | 20 + ...entation.AspNet.TelemetryHttpModule.csproj | 2 + .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 12 + .../AspNetInstrumentation.cs | 44 +++ .../AspNetInstrumentationOptions.cs | 63 +++ .../AspNetMetrics.cs | 53 +++ .../AssemblyInfo.cs | 22 ++ .../CHANGELOG.md | 162 ++++++++ .../AspNetInstrumentationEventSource.cs | 67 ++++ .../Implementation/HttpInListener.cs | 197 ++++++++++ .../Implementation/HttpInMetricsListener.cs | 54 +++ .../MeterProviderBuilderExtensions.cs | 42 ++ ...penTelemetry.Instrumentation.AspNet.csproj | 28 ++ .../README.md | 167 ++++++++ .../TracerProviderBuilderExtensions.cs | 49 +++ .../EventSourceTestHelper.cs | 142 +++++++ .../InMemoryEventListener.cs | 36 ++ .../TestEventListener.cs | 98 +++++ .../BasicTests.cs | 32 ++ .../EventSourceTest.cs | 31 ++ .../HttpInListenerTests.cs | 370 ++++++++++++++++++ .../HttpInMetricsListenerTests.cs | 112 ++++++ ...emetry.Instrumentation.AspNet.Tests.csproj | 40 ++ 27 files changed, 1949 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md create mode 100644 .github/workflows/package-Instrumentation.AspNet.yml create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/README.md create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md new file mode 100644 index 0000000000..9f54a19034 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.AspNet +about: Issue with OpenTelemetry.Instrumentation.AspNet +labels: comp:instrumentation.AspNet +--- + +# Issue with OpenTelemetry.Instrumentation.AspNet + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.2.0`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml new file mode 100644 index 0000000000..00a61079fd --- /dev/null +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Instrumentation.AspNet + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.AspNet-*' + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.AspNet + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 704cb4aaf0..50cdefa021 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -39,6 +39,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml + .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml @@ -212,6 +213,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests", "test\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests\OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj", "{969425CE-CB8F-462C-9126-597FC5B33E27}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet", "src\OpenTelemetry.Instrumentation.AspNet\OpenTelemetry.Instrumentation.AspNet.csproj", "{582B70B5-0067-4D9A-ABF2-623F502BE9A9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.Tests", "test\OpenTelemetry.Instrumentation.AspNet.Tests\OpenTelemetry.Instrumentation.AspNet.Tests.csproj", "{F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -442,6 +447,14 @@ Global {969425CE-CB8F-462C-9126-597FC5B33E27}.Debug|Any CPU.Build.0 = Debug|Any CPU {969425CE-CB8F-462C-9126-597FC5B33E27}.Release|Any CPU.ActiveCfg = Release|Any CPU {969425CE-CB8F-462C-9126-597FC5B33E27}.Release|Any CPU.Build.0 = Release|Any CPU + {582B70B5-0067-4D9A-ABF2-623F502BE9A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {582B70B5-0067-4D9A-ABF2-623F502BE9A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {582B70B5-0067-4D9A-ABF2-623F502BE9A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {582B70B5-0067-4D9A-ABF2-623F502BE9A9}.Release|Any CPU.Build.0 = Release|Any CPU + {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -510,6 +523,8 @@ Global {DD471BEE-65B3-4D72-8A67-92F9C8E93CC1} = {D8F9AEAC-6ACA-484E-81A5-9CEBEDBC3422} {EC83D37A-3704-4515-8EE8-4D007CD9E0A8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {969425CE-CB8F-462C-9126-597FC5B33E27} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {582B70B5-0067-4D9A-ABF2-623F502BE9A9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs index f3b8fadcd4..fb342ae4d3 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using System.Diagnostics; + namespace OpenTelemetry.Trace { /// @@ -41,5 +43,23 @@ public static Status ResolveSpanStatusForHttpStatusCode(int httpStatusCode) return Status.Error; } + + /// + /// Helper method that populates span properties from http status code according + /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. + /// + /// The span kind. + /// Http status code. + /// Resolved span for the Http status code. + public static Status ResolveSpanStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) + { + var upperBound = kind == ActivityKind.Client ? 399 : 499; + if (httpStatusCode >= 100 && httpStatusCode <= upperBound) + { + return Status.Unset; + } + + return Status.Error; + } } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index e1d245b557..35ea9547d7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -4,6 +4,8 @@ net462 A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI + Instrumentation.AspNet.TelemetryHttpModule- + true diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a9ba7f916d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,12 @@ +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.AspNetInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs new file mode 100644 index 0000000000..2bd2a988be --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.AspNet.Implementation; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// Asp.Net Requests instrumentation. + /// + internal sealed class AspNetInstrumentation : IDisposable + { + private readonly HttpInListener httpInListener; + + /// + /// Initializes a new instance of the class. + /// + /// Configuration options for ASP.NET instrumentation. + public AspNetInstrumentation(AspNetInstrumentationOptions options) + { + this.httpInListener = new HttpInListener(options); + } + + /// + public void Dispose() + { + this.httpInListener?.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs new file mode 100644 index 0000000000..4209ce23e0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs @@ -0,0 +1,63 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Web; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// Options for ASP.NET instrumentation. + /// + public class AspNetInstrumentationOptions + { + /// + /// Gets or sets a filter callback function that determines on a per + /// request basis whether or not to collect telemetry. + /// + /// + /// The filter callback receives the for the + /// current request and should return a boolean. + /// + /// If filter returns the request is + /// collected. + /// If filter returns or throws an + /// exception the request is filtered out (NOT collected). + /// + /// + public Func Filter { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// string: the name of the event. + /// object: the raw object from which additional information can be extracted to enrich the activity. + /// The type of this object depends on the event, which is given by the above parameter. + /// + public Action Enrich { get; set; } + + /// + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. + /// + /// + /// See: . + /// + public bool RecordException { get; set; } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs new file mode 100644 index 0000000000..373fe8a553 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -0,0 +1,53 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Metrics; +using System.Reflection; +using OpenTelemetry.Instrumentation.AspNet.Implementation; + +namespace OpenTelemetry.Instrumentation.AspNet +{ + /// + /// Asp.Net Requests instrumentation. + /// + internal class AspNetMetrics : IDisposable + { + internal static readonly AssemblyName AssemblyName = typeof(HttpInMetricsListener).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name; + internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + + private readonly Meter meter; + + private readonly HttpInMetricsListener httpInMetricsListener; + + /// + /// Initializes a new instance of the class. + /// + public AspNetMetrics() + { + this.meter = new Meter(InstrumentationName, InstrumentationVersion); + this.httpInMetricsListener = new HttpInMetricsListener(this.meter); + } + + /// + public void Dispose() + { + this.meter?.Dispose(); + this.httpInMetricsListener?.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs new file mode 100644 index 0000000000..0f14529a44 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNet.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md new file mode 100644 index 0000000000..9f6c1880f3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -0,0 +1,162 @@ +# Changelog + +## Unreleased + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +* Removes .NET Framework 4.6.1. The minimum .NET Framework + version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +* Added ASP.NET metrics instrumentation to collect `http.server.duration`. + ([#2985](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2985)) + +* Fix: Http server span status is now unset for `400`-`499`. + ([#2904](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2904)) + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +* Removes .NET Framework 4.5.2, .NET 4.6 support. The minimum .NET Framework + version supported is .NET 4.6.1. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138)) + +* Replaced `http.path` tag on activity with `http.target`. + ([#2266](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2266)) + +* ASP.NET instrumentation now uses + [OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) + instead of + [Microsoft.AspNet.TelemetryCorrelation](https://www.nuget.org/packages/Microsoft.AspNet.TelemetryCorrelation/) + to listen for incoming http requests to the process. Please see the (Step 2: + Modify + Web.config)[https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNet#step-2-modify-webconfig] + README section for details on the new HttpModule definition required. + ([#2222](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2222)) + +* Added `RecordException` option. Specify `true` to have unhandled exception + details automatically captured on spans. + ([#2256](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2256)) + +## 1.0.0-rc7 + +Released 2021-Jul-12 + +## 1.0.0-rc6 + +Released 2021-Jun-25 + +## 1.0.0-rc5 + +Released 2021-Jun-09 + +## 1.0.0-rc4 + +Released 2021-Apr-23 + +* Sanitize `http.url` attribute. ([#1961](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1961)) + +## 1.0.0-rc3 + +Released 2021-Mar-19 + +* Leverages added AddLegacySource API from OpenTelemetry SDK to trigger Samplers + and ActivityProcessors. Samplers, ActivityProcessor.OnStart will now get the + Activity before any enrichment done by the instrumentation. + ([#1836](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1836)) +* Performance optimization by leveraging sampling decision and short circuiting + activity enrichment. + ([#1903](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1903)) + +## 1.0.0-rc2 + +Released 2021-Jan-29 + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +* AspNetInstrumentation sets ActivitySource to activities created outside + ActivitySource. + ([#1515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1515/)) + +## 0.8.0-beta.1 + +Released 2020-Nov-5 + +* Renamed TextMapPropagator to TraceContextPropagator, CompositePropagator to + CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and + changed from interface to abstract class. + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Propagators.DefaultTextMapPropagator will be used as the default Propagator. + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) +* Removed Propagator from Instrumentation Options. Instrumentation now always + respect the Propagator.DefaultTextMapPropagator. + ([#1448](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1448)) + +## 0.7.0-beta.1 + +Released 2020-Oct-16 + +* Instrumentation no longer store raw objects like `HttpRequest` in + Activity.CustomProperty. To enrich activity, use the Enrich action on the + instrumentation. + ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) +* Span Status is populated as per new spec + ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) + +## 0.6.0-beta.1 + +Released 2020-Sep-15 + +## 0.5.0-beta.2 + +Released 2020-08-28 + +* Added Filter public API on AspNetInstrumentationOptions to allow filtering of + instrumentation based on HttpContext. + +* Asp.Net Instrumentation automatically populates HttpRequest, HttpResponse in + Activity custom property + +* Changed the default propagation to support W3C Baggage + ([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048)) + * The default ITextFormat is now `CompositePropagator(TraceContextFormat, + BaggageFormat)`. Baggage sent via the [W3C + Baggage](https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md) + header will now be parsed and set on incoming Http spans. +* Renamed `ITextPropagator` to `IPropagator` + ([#1190](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1190)) + +## 0.4.0-beta.2 + +Released 2020-07-24 + +* First beta release + +## 0.3.0-beta + +Released 2020-07-23 + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs new file mode 100644 index 0000000000..58bd374d2a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs @@ -0,0 +1,67 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.AspNet.Implementation +{ + /// + /// EventSource events emitted from the project. + /// + [EventSource(Name = "OpenTelemetry-Instrumentation-AspNet")] + internal sealed class AspNetInstrumentationEventSource : EventSource + { + public static AspNetInstrumentationEventSource Log = new(); + + [NonEvent] + public void RequestFilterException(string operationName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.RequestFilterException(operationName, ex.ToInvariantString()); + } + } + + [NonEvent] + public void EnrichmentException(string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(eventName, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Request is filtered out and will not be collected. Operation='{0}'", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut(string operationName) + { + this.WriteEvent(1, operationName); + } + + [Event(2, Message = "Filter callback threw an exception. Request will not be collected. Operation='{0}': {1}", Level = EventLevel.Error)] + public void RequestFilterException(string operationName, string exception) + { + this.WriteEvent(2, operationName, exception); + } + + [Event(3, Message = "Enrich callback threw an exception. Event='{0}': {1}", Level = EventLevel.Error)] + public void EnrichmentException(string eventName, string exception) + { + this.WriteEvent(3, eventName, exception); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs new file mode 100644 index 0000000000..946de293eb --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -0,0 +1,197 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Web; +using System.Web.Routing; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AspNet.Implementation +{ + internal sealed class HttpInListener : IDisposable + { + private readonly PropertyFetcher routeFetcher = new("Route"); + private readonly PropertyFetcher routeTemplateFetcher = new("RouteTemplate"); + private readonly AspNetInstrumentationOptions options; + + public HttpInListener(AspNetInstrumentationOptions options) + { + Guard.ThrowIfNull(options); + + this.options = options; + + TelemetryHttpModule.Options.TextMapPropagator = Propagators.DefaultTextMapPropagator; + + TelemetryHttpModule.Options.OnRequestStartedCallback += this.OnStartActivity; + TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; + TelemetryHttpModule.Options.OnExceptionCallback += this.OnException; + } + + public void Dispose() + { + TelemetryHttpModule.Options.OnRequestStartedCallback -= this.OnStartActivity; + TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; + TelemetryHttpModule.Options.OnExceptionCallback -= this.OnException; + } + + /// + /// Gets the OpenTelemetry standard uri tag value for a span based on its request . + /// + /// . + /// Span uri value. + private static string GetUriTagValueFromRequestUri(Uri uri) + { + return string.IsNullOrEmpty(uri.UserInfo) ? uri.ToString() : string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); + } + + private void OnStartActivity(Activity activity, HttpContext context) + { + if (activity.IsAllDataRequested) + { + try + { + // todo: Ideally we would also check + // Sdk.SuppressInstrumentation here to prevent tagging a + // span that will not be collected but we can't do that + // without an SDK reference. Need the spec to come around on + // this. + + if (this.options.Filter?.Invoke(context) == false) + { + AspNetInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.RequestFilterException(activity.OperationName, ex); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + + var request = context.Request; + var requestValues = request.Unvalidated; + + // see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md + var path = requestValues.Path; + activity.DisplayName = path; + + if (request.Url.Port == 80 || request.Url.Port == 443) + { + activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host); + } + else + { + activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host + ":" + request.Url.Port); + } + + activity.SetTag(SemanticConventions.AttributeHttpMethod, request.HttpMethod); + activity.SetTag(SemanticConventions.AttributeHttpTarget, path); + activity.SetTag(SemanticConventions.AttributeHttpUserAgent, request.UserAgent); + activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Url)); + + try + { + this.options.Enrich?.Invoke(activity, "OnStartActivity", request); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException("OnStartActivity", ex); + } + } + } + + private void OnStopActivity(Activity activity, HttpContext context) + { + if (activity.IsAllDataRequested) + { + var response = context.Response; + + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + + if (activity.GetStatus().StatusCode == StatusCode.Unset) + { + activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(activity.Kind, response.StatusCode)); + } + + var routeData = context.Request.RequestContext.RouteData; + + string template = null; + if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) + { + // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. + + if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1) + { + var subRouteData = attributeRouting.GetValue(0); + + _ = this.routeFetcher.TryFetch(subRouteData, out var route); + _ = this.routeTemplateFetcher.TryFetch(route, out template); + } + } + else if (routeData.Route is Route route) + { + // MVC + WebAPI traditional routing & MVC attribute routing flow here. + template = route.Url; + } + + if (!string.IsNullOrEmpty(template)) + { + // Override the name that was previously set to the path part of URL. + activity.DisplayName = template; + activity.SetTag(SemanticConventions.AttributeHttpRoute, template); + } + + try + { + this.options.Enrich?.Invoke(activity, "OnStopActivity", response); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException("OnStopActivity", ex); + } + } + } + + private void OnException(Activity activity, HttpContext context, Exception exception) + { + if (activity.IsAllDataRequested) + { + if (this.options.RecordException) + { + activity.RecordException(exception); + } + + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + + try + { + this.options.Enrich?.Invoke(activity, "OnException", exception); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException("OnException", ex); + } + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs new file mode 100644 index 0000000000..ece456273c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -0,0 +1,54 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using System.Web; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AspNet.Implementation +{ + internal sealed class HttpInMetricsListener : IDisposable + { + private readonly Histogram httpServerDuration; + + public HttpInMetricsListener(Meter meter) + { + this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "measures the duration of the inbound HTTP request"); + TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; + } + + public void Dispose() + { + TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; + } + + private void OnStopActivity(Activity activity, HttpContext context) + { + // TODO: This is just a minimal set of attributes. See the spec for additional attributes: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server + var tags = new TagList + { + { SemanticConventions.AttributeHttpMethod, context.Request.HttpMethod }, + { SemanticConventions.AttributeHttpScheme, context.Request.Url.Scheme }, + { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode }, + }; + + this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..e92740546a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs @@ -0,0 +1,42 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Instrumentation.AspNet; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics +{ + /// + /// Extension methods to simplify registering of ASP.NET request instrumentation. + /// + public static class MeterProviderBuilderExtensions + { + /// + /// Enables the incoming requests automatic data collection for ASP.NET. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddAspNetInstrumentation( + this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + + var instrumentation = new AspNetMetrics(); + builder.AddMeter(AspNetMetrics.InstrumentationName); + return builder.AddInstrumentation(() => instrumentation); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj new file mode 100644 index 0000000000..ce047f848c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -0,0 +1,28 @@ + + + + net462 + ASP.NET instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI + true + Instrumentation.AspNet- + true + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md new file mode 100644 index 0000000000..3a2ed2c1b7 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -0,0 +1,167 @@ +# ASP.NET Instrumentation for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments [ASP.NET](https://docs.microsoft.com/aspnet/overview) and +collect metrics and traces about incoming web requests. + +**Note: This component is based on the OpenTelemetry semantic conventions for +[metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) +and +[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +These conventions are +[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), +and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +Until a [stable +version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be breaking changes. You can track the progress from +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** + +## Steps to enable OpenTelemetry.Instrumentation.AspNet + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.AspNet`](https://www.nuget.org/packages/opentelemetry.instrumentation.aspnet) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.AspNet +``` + +### Step 2: Modify Web.config + +`OpenTelemetry.Instrumentation.AspNet` requires adding an additional HttpModule +to your web server. This additional HttpModule is shipped as part of +[`OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) +which is implicitly brought by `OpenTelemetry.Instrumentation.AspNet`. The +following shows changes required to your `Web.config` when using IIS web server. + +```xml + + + + + +``` + +### Step 3: Enable ASP.NET Instrumentation at application startup + +ASP.NET instrumentation must be enabled at application startup. This is +typically done in the `Global.asax.cs` as shown below. This example also sets up +the OpenTelemetry Jaeger exporter, which requires adding the package +[`OpenTelemetry.Exporter.Jaeger`](../OpenTelemetry.Exporter.Jaeger/README.md) to +the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Trace; + +public class WebApiApplication : HttpApplication +{ + private TracerProvider tracerProvider; + protected void Application_Start() + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation() + .AddJaegerExporter() + .Build(); + } + protected void Application_End() + { + this.tracerProvider?.Dispose(); + } +} +``` + +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`AspNetInstrumentationOptions`, which allows configuring `Filter` as explained +below. + +### Filter + +This instrumentation by default collects all the incoming http requests. It +allows filtering of requests by using the `Filter` function in +`AspNetInstrumentationOptions`. This defines the condition for allowable +requests. The Filter receives the `HttpContext` of the incoming request, and +does not collect telemetry about the request if the Filter returns false or +throws exception. + +The following code snippet shows how to use `Filter` to only allow GET requests. + +```csharp +this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation( + (options) => options.Filter = + (httpContext) => + { + // only collect telemetry about HTTP GET requests + return httpContext.Request.HttpMethod.Equals("GET"); + }) + .Build(); +``` + +It is important to note that this `Filter` option is specific to this +instrumentation. OpenTelemetry has a concept of a +[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling), +and the `Filter` option does the filtering *before* the Sampler is invoked. + +### Enrich + +This option allows one to enrich the activity with additional information from +the raw `HttpRequest`, `HttpResponse` objects. The `Enrich` action is called +only when `activity.IsAllDataRequested` is `true`. It contains the activity +itself (which can be enriched), the name of the event, and the actual raw +object. For event name "OnStartActivity", the actual object will be +`HttpRequest`. For event name "OnStopActivity", the actual object will be +`HttpResponse` + +The following code snippet shows how to add additional tags using `Enrich`. + +```csharp +this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation((options) => options.Enrich + = (activity, eventName, rawObject) => + { + if (eventName.Equals("OnStartActivity")) + { + if (rawObject is HttpRequest httpRequest) + { + activity.SetTag("physicalPath", httpRequest.PhysicalPath); + } + } + else if (eventName.Equals("OnStopActivity")) + { + if (rawObject is HttpResponse httpResponse) + { + activity.SetTag("responseType", httpResponse.ContentType); + } + } + }) + .Build(); +``` + +[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the +general extensibility point to add additional properties to any activity. The +`Enrich` option is specific to this instrumentation, and is provided to get +access to `HttpRequest` and `HttpResponse`. + +### RecordException + +This instrumentation automatically sets Activity Status to Error if an unhandled +exception is thrown. Additionally, `RecordException` feature may be turned on, +to store the exception to the Activity itself as ActivityEvent. + +## References + +* [ASP.NET](https://dotnet.microsoft.com/apps/aspnet) +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..b58aeb83b8 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.AspNet; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace +{ + /// + /// Extension methods to simplify registering of ASP.NET request instrumentation. + /// + public static class TracerProviderBuilderExtensions + { + /// + /// Enables the incoming requests automatic data collection for ASP.NET. + /// + /// being configured. + /// ASP.NET Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetInstrumentation( + this TracerProviderBuilder builder, + Action configureAspNetInstrumentationOptions = null) + { + Guard.ThrowIfNull(builder); + + var aspnetOptions = new AspNetInstrumentationOptions(); + configureAspNetInstrumentationOptions?.Invoke(aspnetOptions); + + builder.AddInstrumentation(() => new AspNetInstrumentation(aspnetOptions)); + builder.AddSource(TelemetryHttpModule.AspNetSourceName); + + return builder; + } + } +} diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs new file mode 100644 index 0000000000..67afcbb57b --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -0,0 +1,142 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Linq; +using System.Reflection; + +namespace OpenTelemetry.Tests +{ + internal static class EventSourceTestHelper + { + public static void MethodsAreImplementedConsistentlyWithTheirAttributes(EventSource eventSource) + { + foreach (MethodInfo publicMethod in GetEventMethods(eventSource)) + { + VerifyMethodImplementation(eventSource, publicMethod); + } + } + + private static void VerifyMethodImplementation(EventSource eventSource, MethodInfo eventMethod) + { + using var listener = new TestEventListener(); + listener.EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All); + try + { + object[] eventArguments = GenerateEventArguments(eventMethod); + eventMethod.Invoke(eventSource, eventArguments); + + EventWrittenEventArgs actualEvent = null; + + actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); + + VerifyEventId(eventMethod, actualEvent); + VerifyEventLevel(eventMethod, actualEvent); + + if (eventMethod.Name != "ExporterErrorResult") + { + VerifyEventMessage(eventMethod, actualEvent, eventArguments); + } + } + catch (Exception e) + { + var name = eventMethod.DeclaringType.Name + "." + eventMethod.Name; + + throw new Exception("Method '" + name + "' is implemented incorrectly.", e); + } + finally + { + listener.ClearMessages(); + } + } + + private static object[] GenerateEventArguments(MethodInfo eventMethod) + { + ParameterInfo[] parameters = eventMethod.GetParameters(); + var arguments = new object[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + { + arguments[i] = GenerateArgument(parameters[i]); + } + + return arguments; + } + + private static object GenerateArgument(ParameterInfo parameter) + { + if (parameter.ParameterType == typeof(string)) + { + return "Test String"; + } + + if (parameter.ParameterType.IsValueType) + { + return Activator.CreateInstance(parameter.ParameterType); + } + + throw new NotSupportedException("Complex types are not supported"); + } + + private static void VerifyEventId(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) + { + int expectedEventId = GetEventAttribute(eventMethod).EventId; + AssertEqual(nameof(VerifyEventId), expectedEventId, actualEvent.EventId); + } + + private static void VerifyEventLevel(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) + { + EventLevel expectedLevel = GetEventAttribute(eventMethod).Level; + AssertEqual(nameof(VerifyEventLevel), expectedLevel, actualEvent.Level); + } + + 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()); + AssertEqual(nameof(VerifyEventMessage), expectedMessage, actualMessage); + } + + private static void AssertEqual(string methodName, T expected, T actual) + { + if (!expected.Equals(actual)) + { + var errorMessage = string.Format( + CultureInfo.InvariantCulture, + "{0} Failed: expected: '{1}' actual: '{2}'", + methodName, + expected, + actual); + throw new Exception(errorMessage); + } + } + + private static EventAttribute GetEventAttribute(MethodInfo eventMethod) + { + return (EventAttribute)eventMethod.GetCustomAttributes(typeof(EventAttribute), false).Single(); + } + + private static IEnumerable GetEventMethods(EventSource eventSource) + { + MethodInfo[] methods = eventSource.GetType().GetMethods(); + return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Any()); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs new file mode 100644 index 0000000000..dfaf067fe6 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Concurrent; +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Tests +{ + internal class InMemoryEventListener : EventListener + { + public ConcurrentQueue Events = new(); + + public InMemoryEventListener(EventSource eventSource, EventLevel minLevel = EventLevel.Verbose) + { + this.EnableEvents(eventSource, minLevel); + } + + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + this.Events.Enqueue(eventData); + } + } +} diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs new file mode 100644 index 0000000000..9c6ffc3e56 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs @@ -0,0 +1,98 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.Tracing; +using System.Threading; + +namespace OpenTelemetry.Tests +{ + /// + /// Event listener for testing event sources. + /// + internal class TestEventListener : EventListener + { + /// A queue of events that have been logged. + private readonly Queue events; + + /// + /// Lock for event writing tracking. + /// + private readonly AutoResetEvent eventWritten; + + /// + /// Initializes a new instance of the class. + /// + public TestEventListener() + { + this.events = new Queue(); + this.eventWritten = new AutoResetEvent(false); + this.OnOnEventWritten = e => + { + this.events.Enqueue(e); + this.eventWritten.Set(); + }; + } + + /// Gets or sets the handler for event source creation. + public Action OnOnEventSourceCreated { get; set; } + + /// Gets or sets the handler for event source writes. + public Action OnOnEventWritten { get; set; } + + /// Gets the events that have been written. + public IEnumerable Messages + { + get + { + if (this.events.Count == 0) + { + this.eventWritten.WaitOne(TimeSpan.FromSeconds(5)); + } + + while (this.events.Count != 0) + { + yield return this.events.Dequeue(); + } + } + } + + /// + /// Clears all event messages so that testing can assert expected counts. + /// + public void ClearMessages() + { + this.events.Clear(); + } + + /// Handler for event source writes. + /// The event data that was written. + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + this.OnOnEventWritten(eventData); + } + + /// Handler for event source creation. + /// The event source that was created. + protected override void OnEventSourceCreated(EventSource eventSource) + { + // Check for null because this method is called by the base class constror before we can initialize it + Action callback = this.OnOnEventSourceCreated; + callback?.Invoke(eventSource); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs new file mode 100644 index 0000000000..d3ded5f632 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs @@ -0,0 +1,32 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class BasicTests + { + [Fact] + public void AddAspNetInstrumentation_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddAspNetInstrumentation()); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs new file mode 100644 index 0000000000..521e857bba --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Instrumentation.AspNet.Implementation; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class EventSourceTest + { + [Fact] + public void EventSourceTest_AspNetInstrumentationEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(AspNetInstrumentationEventSource.Log); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs new file mode 100644 index 0000000000..bc1588d001 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -0,0 +1,370 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Web; +using System.Web.Routing; +using Moq; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.AspNet.Implementation; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class HttpInListenerTests + { + [Theory] + [InlineData("http://localhost/", "http://localhost/", 0, null)] + [InlineData("http://localhost/", "http://localhost/", 0, null, true)] + [InlineData("https://localhost/", "https://localhost/", 0, null)] + [InlineData("https://localhost/", "https://user:pass@localhost/", 0, null)] // Test URL sanitization + [InlineData("http://localhost:443/", "http://localhost:443/", 0, null)] // Test http over 443 + [InlineData("https://localhost:80/", "https://localhost:80/", 0, null)] // Test https over 80 + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL sanitization + [InlineData("http://localhost:80/Index", "http://localhost:80/Index", 1, "{controller}/{action}/{id}")] + [InlineData("https://localhost:443/about_attr_route/10", "https://localhost:443/about_attr_route/10", 2, "about_attr_route/{customerId}")] + [InlineData("http://localhost:1880/api/weatherforecast", "http://localhost:1880/api/weatherforecast", 3, "api/{controller}/{id}")] + [InlineData("https://localhost:1843/subroute/10", "https://localhost:1843/subroute/10", 4, "subroute/{customerId}")] + [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "/api/value")] // Request will be filtered + [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "{ThrowException}")] // Filter user code will throw an exception + [InlineData("http://localhost/", "http://localhost/", 0, null, false, null, true)] // Test RecordException option + public void AspNetRequestsAreCollectedSuccessfully( + string expectedUrl, + string url, + int routeType, + string routeTemplate, + bool setStatusToErrorInEnrich = false, + string filter = null, + bool recordException = false) + { + IDisposable tracerProvider = null; + RouteData routeData; + switch (routeType) + { + case 0: // WebForm, no route data. + routeData = new RouteData(); + break; + case 1: // Traditional MVC. + case 2: // Attribute routing MVC. + case 3: // Traditional WebAPI. + routeData = new RouteData() + { + Route = new Route(routeTemplate, null), + }; + break; + case 4: // Attribute routing WebAPI. + routeData = new RouteData(); + var value = new[] + { + new + { + Route = new + { + RouteTemplate = routeTemplate, + }, + }, + }; + routeData.Values.Add( + "MS_SubRoutes", + value); + break; + default: + throw new NotSupportedException(); + } + + var workerRequest = new Mock(); + workerRequest.Setup(wr => wr.GetKnownRequestHeader(It.IsAny())).Returns(i => + { + return i switch + { + 39 => "Test", // User-Agent + _ => null, + }; + }); + + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, url, string.Empty) + { + RequestContext = new RequestContext() + { + RouteData = routeData, + }, + }, + new HttpResponse(new StringWriter())); + + typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, workerRequest.Object); + + List exportedItems = new List(16); + + Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); + using (tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation((options) => + { + options.Filter = httpContext => + { + Assert.True(Activity.Current.IsAllDataRequested); + if (string.IsNullOrEmpty(filter)) + { + return true; + } + + if (filter == "{ThrowException}") + { + throw new InvalidOperationException(); + } + + return httpContext.Request.Path != filter; + }; + + options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? Status.Error : default); + + options.RecordException = recordException; + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); + + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + + if (filter == "{ThrowException}") + { + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); + } + + Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); + + if (recordException) + { + ActivityHelper.WriteActivityException(activity, HttpContext.Current, new InvalidOperationException(), TelemetryHttpModule.Options.OnExceptionCallback); + } + + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + } + + if (HttpContext.Current.Request.Path == filter || filter == "{ThrowException}") + { + Assert.Empty(exportedItems); + return; + } + + Assert.Single(exportedItems); + + Activity span = exportedItems[0]; + + Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); + Assert.NotEqual(TimeSpan.Zero, span.Duration); + + Assert.Equal(routeTemplate ?? HttpContext.Current.Request.Path, span.DisplayName); + Assert.Equal(ActivityKind.Server, span.Kind); + Assert.True(span.Duration != TimeSpan.Zero); + + Assert.Equal(200, span.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); + + var expectedUri = new Uri(expectedUrl); + var actualUrl = span.GetTagValue(SemanticConventions.AttributeHttpUrl); + + Assert.Equal(expectedUri.ToString(), actualUrl); + + // Url strips 80 or 443 if the scheme matches. + if ((expectedUri.Port == 80 && expectedUri.Scheme == "http") || (expectedUri.Port == 443 && expectedUri.Scheme == "https")) + { + Assert.DoesNotContain($":{expectedUri.Port}", actualUrl as string); + } + else + { + Assert.Contains($":{expectedUri.Port}", actualUrl as string); + } + + // Host includes port if it isn't 80 or 443. + if (expectedUri.Port is 80 or 443) + { + Assert.Equal( + expectedUri.Host, + span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); + } + else + { + Assert.Equal( + $"{expectedUri.Host}:{expectedUri.Port}", + span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); + } + + Assert.Equal(HttpContext.Current.Request.HttpMethod, span.GetTagValue(SemanticConventions.AttributeHttpMethod) as string); + Assert.Equal(HttpContext.Current.Request.Path, span.GetTagValue(SemanticConventions.AttributeHttpTarget) as string); + Assert.Equal(HttpContext.Current.Request.UserAgent, span.GetTagValue(SemanticConventions.AttributeHttpUserAgent) as string); + + if (recordException) + { + var status = span.GetStatus(); + Assert.Equal(Status.Error.StatusCode, status.StatusCode); + Assert.Equal("Operation is not valid due to the current state of the object.", status.Description); + } + else if (setStatusToErrorInEnrich) + { + // This validates that users can override the + // status in Enrich. + Assert.Equal(Status.Error, span.GetStatus()); + + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); + } + else + { + Assert.Equal(Status.Unset, span.GetStatus()); + + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); + } + } + + [Theory] + [InlineData(SamplingDecision.Drop)] + [InlineData(SamplingDecision.RecordOnly)] + [InlineData(SamplingDecision.RecordAndSample)] + public void ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision samplingDecision) + { + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, "http://localhost/", string.Empty) + { + RequestContext = new RequestContext() + { + RouteData = new RouteData(), + }, + }, + new HttpResponse(new StringWriter())); + + bool isPropagatorCalled = false; + var propagator = new Mock(); + propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) + .Returns(() => + { + isPropagatorCalled = true; + return default; + }); + + var activityProcessor = new Mock>(); + Sdk.SetDefaultTextMapPropagator(propagator.Object); + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new TestSampler(samplingDecision)) + .AddAspNetInstrumentation() + .AddProcessor(activityProcessor.Object).Build()) + { + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + } + + Assert.True(isPropagatorCalled); + } + + [Fact] + public void ExtractContextIrrespectiveOfTheFilterApplied() + { + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, "http://localhost/", string.Empty) + { + RequestContext = new RequestContext() + { + RouteData = new RouteData(), + }, + }, + new HttpResponse(new StringWriter())); + + bool isPropagatorCalled = false; + var propagator = new Mock(); + propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) + .Returns(() => + { + isPropagatorCalled = true; + return default; + }); + + bool isFilterCalled = false; + var activityProcessor = new Mock>(); + Sdk.SetDefaultTextMapPropagator(propagator.Object); + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation(options => + { + options.Filter = context => + { + isFilterCalled = true; + return false; + }; + }) + .AddProcessor(activityProcessor.Object).Build()) + { + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + } + + Assert.True(isFilterCalled); + Assert.True(isPropagatorCalled); + } + + private static Action GetEnrichmentAction(Status statusToBeSet) + { + void EnrichAction(Activity activity, string method, object obj) + { + Assert.True(activity.IsAllDataRequested); + switch (method) + { + case "OnStartActivity": + Assert.True(obj is HttpRequest); + break; + + case "OnStopActivity": + Assert.True(obj is HttpResponse); + if (statusToBeSet != default) + { + activity.SetStatus(statusToBeSet); + } + + break; + + default: + break; + } + } + + return EnrichAction; + } + + private class TestSampler : Sampler + { + private readonly SamplingDecision samplingDecision; + + public TestSampler(SamplingDecision samplingDecision) + { + this.samplingDecision = samplingDecision; + } + + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + return new SamplingResult(this.samplingDecision); + } + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs new file mode 100644 index 0000000000..b9fbbbeebe --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -0,0 +1,112 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.IO; +using System.Web; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests +{ + public class HttpInMetricsListenerTests + { + [Fact] + public void HttpDurationMetricIsEmitted() + { + string url = "http://localhost/api/value"; + double duration = 0; + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, url, string.Empty), + new HttpResponse(new StringWriter())); + + // This is to enable activity creation + // as it is created using activitysource inside TelemetryHttpModule + // TODO: This should not be needed once the dependency on activity is removed from metrics + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation(opts => opts.Enrich + = (activity, eventName, rawObject) => + { + if (eventName.Equals("OnStopActivity")) + { + duration = activity.Duration.TotalMilliseconds; + } + }) + .Build(); + + var exportedItems = new List(); + using var meterprovider = Sdk.CreateMeterProviderBuilder() + .AddAspNetInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + + meterprovider.ForceFlush(); + + var metricPoints = new List(); + foreach (var p in exportedItems[0].GetMetricPoints()) + { + metricPoints.Add(p); + } + + Assert.Single(metricPoints); + + var metricPoint = metricPoints[0]; + + var count = metricPoint.GetHistogramCount(); + var sum = metricPoint.GetHistogramSum(); + + Assert.Equal(MetricType.Histogram, exportedItems[0].MetricType); + Assert.Equal("http.server.duration", exportedItems[0].Name); + Assert.Equal(1L, count); + Assert.Equal(duration, sum); + + Assert.Equal(3, metricPoints[0].Tags.Count); + string httpMethod = null; + int httpStatusCode = 0; + string httpScheme = null; + + foreach (var tag in metricPoints[0].Tags) + { + if (tag.Key == SemanticConventions.AttributeHttpMethod) + { + httpMethod = (string)tag.Value; + continue; + } + + if (tag.Key == SemanticConventions.AttributeHttpStatusCode) + { + httpStatusCode = (int)tag.Value; + continue; + } + + if (tag.Key == SemanticConventions.AttributeHttpScheme) + { + httpScheme = (string)tag.Value; + continue; + } + } + + Assert.Equal("GET", httpMethod); + Assert.Equal(200, httpStatusCode); + Assert.Equal("http", httpScheme); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj new file mode 100644 index 0000000000..a3c8d11ff4 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -0,0 +1,40 @@ + + + Unit test project for OpenTelemetry ASP.NET instrumentation + + net462 + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + + + + + + + + + + + + From a2244668374150b1f95e364e83b44f9958c97313 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 13 Jun 2022 16:44:34 -0700 Subject: [PATCH 0164/1499] [Exporter.Geneva] Add unit test for scopes (#401) --- .../GenevaLogExporterTests.cs | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index c665fe85d2..eacb679eba 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -351,6 +351,117 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() } } + [Fact] + public void SerializeILoggerScopes() + { + string path = string.Empty; + Socket senderSocket = null; + Socket receiverSocket = null; + try + { + var exporterOptions = new GenevaExporterOptions(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + senderSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + senderSocket.Bind(endpoint); + senderSocket.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.IncludeScopes = true; + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + }); + })); + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + receiverSocket = senderSocket.Accept(); + receiverSocket.ReceiveTimeout = 10000; + } + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); + + using (logger.BeginScope("MyOuterScope")) + using (logger.BeginScope("MyInnerScope")) + using (logger.BeginScope("MyInnerInnerScope with {name} and {age} of custom", "John Doe", 35)) + using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) + { + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + byte[] serializedData; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + serializedData = m_buffer.Value; + } + else + { + // Read the data sent via socket. + serializedData = new byte[65360]; + _ = receiverSocket.Receive(serializedData); + } + + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var serializedScopes = mapping["scopes"] as object[]; + + Assert.Equal(4, serializedScopes.Length); + + // Test 1st scope + var scope = serializedScopes[0] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("scope", "MyOuterScope"), scope); + + // Test 2nd scope + scope = serializedScopes[1] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("scope", "MyInnerScope"), scope); + + // Test 3rd scope + scope = serializedScopes[2] as ICollection>; + Assert.Equal(3, scope.Count); + Assert.Contains(new KeyValuePair("name", "John Doe"), scope); + Assert.Contains(new KeyValuePair("age", (byte)35), scope); + Assert.Contains(new KeyValuePair("{OriginalFormat}", "MyInnerInnerScope with {name} and {age} of custom"), scope); + + // Test 4th scope + scope = serializedScopes[3] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("MyKey", "MyValue"), scope); + } + finally + { + senderSocket?.Dispose(); + receiverSocket?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + [Theory] [InlineData(true)] [InlineData(false)] From 240a3ad78b2d44d401469281cb394c3436102a71 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 15 Jun 2022 10:57:13 -0700 Subject: [PATCH 0165/1499] [Exporter.Geneva] Update OTel SDK version (#427) * Update OTel SDK version --- build/Common.props | 5 +++-- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 4 ++-- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.AspNet.Tests.csproj | 2 +- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/build/Common.props b/build/Common.props index ee39b145cc..55bfe93640 100644 --- a/build/Common.props +++ b/build/Common.props @@ -26,13 +26,14 @@ [6.0.0] [16.7.1] [2.1.0,5.0) + [3.1.0,) [1.0.0,2.0) [4.1.1] [3.3.2] [1.0.0,2.0) - [1.2.0-beta.354,2.0) + 1.3.0 [2.1.58,3.0) - [3.1.0,) + [1.2.0-beta.354,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index e614f2693c..f0512853e3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,6 +6,9 @@ `GenevaMetricExporter`. [397](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/397) +* Update OTel SDK version to `1.3.0`. +[427](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/427) + ## 1.3.0-beta.2 [2022-Jun-03] * Add support for exporting `ILogger` scopes. diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 097f916f46..4e0b95098a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index c39a2dfb36..a9af51a2a2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -1,4 +1,4 @@ - + Exe @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 9c4b4b3443..c3d76166fb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -33,7 +33,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index a3c8d11ff4..e3499a281e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -8,7 +8,7 @@ - + all From a6c4123acacb8f40086eacc2879b7edfa040535a Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 15 Jun 2022 16:14:49 -0700 Subject: [PATCH 0166/1499] add workflow to clear stale PRs (#428) --- .github/workflows/stale.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000..3793c1f0a2 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,21 @@ +# 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" +on: + schedule: + - cron: "12 3 * * *" # arbitrary time not to DDOS GitHub + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v5 + with: + stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' + 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-pr-close: 7 + days-before-issue-close: -1 From 3b3299f0dd23d77dda9f55d02943ce42eece2ddc Mon Sep 17 00:00:00 2001 From: chad122 Date: Fri, 17 Jun 2022 00:32:08 +0800 Subject: [PATCH 0167/1499] fix Elasticsearch MaxDbStatementLength option (#425) --- .../CHANGELOG.md | 1 + .../ElasticsearchRequestPipelineDiagnosticListener.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 2204bacfb7..a5885260dd 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -7,6 +7,7 @@ * Requests that get an HTTP status code of 404 are not marked as an error span status * Add MaxDbStatementLength option with default of 4096 * Remove duplicated HTTP method and URL from db.statement attribute value +* Fix faulty logic of MaxDbStatementLength option [(#425)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/425) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 86284d73fb..da05a4468f 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -145,9 +145,9 @@ public override void OnStopActivity(Activity activity, object payload) if (debugInformation != null && this.options.SetDbStatementForRequest) { var dbStatement = this.ParseAndFormatRequest(activity, debugInformation); - if (dbStatement.Length > this.options.MaxDbStatementLength) + if (this.options.MaxDbStatementLength > 0 && dbStatement.Length > this.options.MaxDbStatementLength) { - dbStatement = dbStatement.Substring(0, 4096); + dbStatement = dbStatement.Substring(0, this.options.MaxDbStatementLength); } activity.SetTag(SemanticConventions.AttributeDbStatement, dbStatement); From 08b52d5ce6d12727cb545f6388cdcf5804d36ac1 Mon Sep 17 00:00:00 2001 From: Nathaniel Ruiz Nowell Date: Thu, 16 Jun 2022 10:42:14 -0700 Subject: [PATCH 0168/1499] Use global Random instance instead of ThreadLocal (#380) Co-authored-by: srprash Co-authored-by: srprash Co-authored-by: Prashant Srivastava <50466688+srprash@users.noreply.github.com> --- .../AWSXRayIdGenerator.cs | 30 ++++++++----------- .../CHANGELOG.md | 6 ++++ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs index 4678254ea9..eba7c5b7b0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs @@ -18,7 +18,6 @@ using System.Diagnostics; using System.Globalization; using System.Linq; -using System.Threading; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -38,16 +37,7 @@ public static class AWSXRayIdGenerator private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly long UnixEpochMicroseconds = EpochStart.Ticks / TicksPerMicrosecond; private static readonly Random Global = new Random(); - private static readonly ThreadLocal Local = new ThreadLocal(() => - { - int seed; - lock (Global) - { - seed = Global.Next(); - } - - return new Random(seed); - }); + private static object randLock = new object(); internal static void ReplaceTraceId(Sampler sampler = null) { @@ -129,11 +119,17 @@ private static string GenerateHexNumber(int digits) Guard.ThrowIfOutOfRange(digits, min: 0); byte[] bytes = new byte[digits / 2]; - NextBytes(bytes); - string hexNumber = string.Concat(bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)).ToArray()); - if (digits % 2 != 0) + + string hexNumber; + + lock (randLock) { - hexNumber += Next(16).ToString("x", CultureInfo.InvariantCulture); + NextBytes(bytes); + hexNumber = string.Concat(bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)).ToArray()); + if (digits % 2 != 0) + { + hexNumber += Next(16).ToString("x", CultureInfo.InvariantCulture); + } } return hexNumber; @@ -145,7 +141,7 @@ private static string GenerateHexNumber(int digits) /// An array of bytes to contain random numbers. private static void NextBytes(byte[] buffer) { - Local.Value.NextBytes(buffer); + Global.NextBytes(buffer); } /// @@ -155,7 +151,7 @@ private static void NextBytes(byte[] buffer) /// A 32-bit signed integer that is greater than or equal to 0, and less than maxValue. private static int Next(int maxValue) { - return Local.Value.Next(maxValue); + return Global.Next(maxValue); } private static ActivitySamplingResult ComputeRootActivitySamplingResult( diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index ad7c981332..67369c91e6 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog - OpenTelemetry.Contrib.Extensions.AWSXRay +## 1.3.0 [TBD] + +* Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random + instance instead of recreating with ThreadLocal + ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) + ## 1.2.0 [2022-May-18] * Enhancement - AWSEKSResourceDetector - Validate ClusterName/ContainerID From 95535edcff8ffe4885ca11dea210aef67890cd6e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 10:38:21 -0700 Subject: [PATCH 0169/1499] [Exporter.Geneva] Update exception logging (#435) --- .../ExporterEventSource.cs | 55 +++++++++++-------- .../GenevaLogExporter.cs | 4 +- .../GenevaMetricExporter.cs | 4 +- .../GenevaTraceExporter.cs | 4 +- .../UnixDomainSocketDataTransport.cs | 6 +- 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs index 3a2e7e3dbd..7e827949c8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs @@ -25,46 +25,55 @@ namespace OpenTelemetry.Exporter.Geneva; internal class ExporterEventSource : EventSource { public static readonly ExporterEventSource Log = new ExporterEventSource(); - private const int EVENT_ID_TRACE = 1; - private const int EVENT_ID_METRICS = 2; - private const int EVENT_ID_ERROR = 3; + private const int EVENT_ID_TRACE = 1; // Failed to send Trace + private const int EVENT_ID_LOG = 2; // Failed to send Log + private const int EVENT_ID_METRIC = 3; // Failed to send Metric + private const int EVENT_ID_ERROR = 4; // Other common exporter exceptions - [NonEvent] - public void ExporterException(Exception ex) + [Event(EVENT_ID_TRACE, Message = "Exporter failed to send trace data. Exception: {0}", Level = EventLevel.Error)] + public void FailedToSendTraceData(Exception ex) { if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.FailedToSendSpanData(ToInvariantString(ex)); + // https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing + // ETW has a size limit: The total event size is greater than 64K. This includes the ETW header plus the data or payload. + // TODO: Do not hit ETW size limit even for external library exception stack. But what is the ETW header size? + // Source code: https://referencesource.microsoft.com/#mscorlib/system/diagnostics/eventing/eventsource.cs,867 + // Why is size calculated like below in WriteEvent source code? + // descrs[0].Size = ((arg1.Length + 1) * 2); + // I'm assuming it calculates the size of string, then it should be: + // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). + this.WriteEvent(EVENT_ID_TRACE, ToInvariantString(ex)); } } - [Event(EVENT_ID_TRACE, Message = "Exporter failed to send SpanData. Data will not be sent. Exception: {0}", Level = EventLevel.Error)] - public void FailedToSendSpanData(string ex) + [Event(EVENT_ID_LOG, Message = "Exporter failed to send log data. Exception: {0}", Level = EventLevel.Error)] + public void FailedToSendLogData(Exception ex) { - // https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing - // ETW has a size limit: The total event size is greater than 64K. This includes the ETW header plus the data or payload. - // TODO: Do not hit ETW size limit even for external library exception stack. But what is the ETW header size? - // Source code: https://referencesource.microsoft.com/#mscorlib/system/diagnostics/eventing/eventsource.cs,867 - // Why is size calculated like below in WriteEvent source code? - // descrs[0].Size = ((arg1.Length + 1) * 2); - // I'm assuming it calculates the size of string, then it should be: - // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). - this.WriteEvent(EVENT_ID_TRACE, ex); + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + // TODO: Do not hit ETW size limit even for external library exception stack. + this.WriteEvent(EVENT_ID_LOG, ToInvariantString(ex)); + } } - [Event(EVENT_ID_METRICS, Message = "Exporter failed to send MetricData. Data will not be sent. MetricNamespace = {0}, MetricName = {1}, Message: {2}", Level = EventLevel.Error)] - public void FailedToSendMetricData(string metricNamespace, string metricName, string message) + [Event(EVENT_ID_METRIC, Message = "Exporter failed to send metric data. Data will not be sent. MonitoringAccount = {0} MetricNamespace = {1}, MetricName = {2}, Message: {3}", Level = EventLevel.Error)] + public void FailedToSendMetricData(string monitoringAccount, string metricNamespace, string metricName, Exception ex) { - this.WriteEvent(EVENT_ID_METRICS, metricNamespace, metricName, message); + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + // TODO: Do not hit ETW size limit even for external library exception stack. + this.WriteEvent(EVENT_ID_METRIC, monitoringAccount, metricNamespace, metricName, ToInvariantString(ex)); + } } [Event(EVENT_ID_ERROR, Message = "Exporter failed.", Level = EventLevel.Error)] - public void ExporterError(string message) + public void ExporterException(string message, Exception ex) { if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - // TODO: We should ensure that GenevaTraceExporter doesn't emit any message that could hit ETW size limit. - this.WriteEvent(EVENT_ID_ERROR, message); + // TODO: Do not hit ETW size limit even for external library exception stack. + this.WriteEvent(EVENT_ID_ERROR, message, ToInvariantString(ex)); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index a22c7eb013..c7e89775dd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -160,7 +160,7 @@ public override ExportResult Export(in Batch batch) } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception + ExporterEventSource.Log.FailedToSendLogData(ex); // TODO: preallocate exception or no exception result = ExportResult.Failure; } } @@ -185,7 +185,7 @@ protected override void Dispose(bool disposing) } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); + ExporterEventSource.Log.ExporterException("GenevaLogExporter Dispose failed.", ex); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index 189d251c70..fde8fd5cfe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -198,7 +198,7 @@ public override ExportResult Export(in Batch batch) } catch (Exception ex) { - ExporterEventSource.Log.FailedToSendMetricData(this.metricNamespace, metric.Name, ex.Message); // TODO: preallocate exception or no exception + ExporterEventSource.Log.FailedToSendMetricData(this.monitoringAccount, this.metricNamespace, metric.Name, ex); // TODO: preallocate exception or no exception result = ExportResult.Failure; } } @@ -222,7 +222,7 @@ protected override void Dispose(bool disposing) } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); + ExporterEventSource.Log.ExporterException("GenevaMetricExporter Dispose failed.", ex); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 9c976be084..2e7b7932f4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -200,7 +200,7 @@ public override ExportResult Export(in Batch batch) } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); // TODO: preallocate exception or no exception + ExporterEventSource.Log.FailedToSendTraceData(ex); // TODO: preallocate exception or no exception result = ExportResult.Failure; } } @@ -224,7 +224,7 @@ protected override void Dispose(bool disposing) } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); + ExporterEventSource.Log.ExporterException("GenevaTraceExporter Dispose failed.", ex); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs index 78c024a1d5..44f0b9e158 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs @@ -66,11 +66,11 @@ public void Send(byte[] data, int size) catch (SocketException ex) { // SocketException from Socket.Send - ExporterEventSource.Log.ExporterException(ex); + ExporterEventSource.Log.ExporterException("UDS Send failed.", ex); } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); + ExporterEventSource.Log.ExporterException("UDS Send failed.", ex); } } @@ -91,7 +91,7 @@ private void Connect() } catch (Exception ex) { - ExporterEventSource.Log.ExporterException(ex); + ExporterEventSource.Log.ExporterException("UDS Connect failed.", ex); // Re-throw the exception to // 1. fail fast in Geneva exporter contructor, or From 383b0c42cace251fc23854f58a79ac8852ea2137 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 10:57:13 -0700 Subject: [PATCH 0170/1499] Remove unnecessary preprocessor directives (#434) --- src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index c7e89775dd..4d97cfa0ca 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if NETSTANDARD2_0 || NET461 using System; using System.Collections.Generic; using System.Globalization; @@ -582,4 +581,3 @@ private static int SerializeSanitizedCategoryName(byte[] buffer, int cursor, str return cursor; } } -#endif From 1624a215cae5ffaa218f50948b70a0c7f82cb2d3 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 11:45:36 -0700 Subject: [PATCH 0171/1499] [Instrumentation.AspNet] Add AspNet example (#436) * Add AspNet example --- examples/AspNet/App_Start/RouteConfig.cs | 36 +++ examples/AspNet/App_Start/WebApiConfig.cs | 40 ++++ examples/AspNet/Controllers/HomeController.cs | 37 +++ .../Controllers/WeatherForecastController.cs | 217 ++++++++++++++++++ examples/AspNet/Examples.AspNet.csproj | 132 +++++++++++ examples/AspNet/Global.asax | 1 + examples/AspNet/Global.asax.cs | 111 +++++++++ examples/AspNet/Models/WeatherForecast.cs | 31 +++ examples/AspNet/Properties/AssemblyInfo.cs | 50 ++++ .../SuppressInstrumentationHttpModule.cs | 58 +++++ examples/AspNet/Views/Home/About.cshtml | 7 + examples/AspNet/Views/Home/Index.cshtml | 31 +++ examples/AspNet/Views/Shared/_Layout.cshtml | 36 +++ examples/AspNet/Views/Web.config | 42 ++++ examples/AspNet/Views/_ViewStart.cshtml | 3 + examples/AspNet/Web.Debug.config | 30 +++ examples/AspNet/Web.Release.config | 31 +++ examples/AspNet/Web.config | 62 +++++ opentelemetry-dotnet-contrib.sln | 10 + 19 files changed, 965 insertions(+) create mode 100644 examples/AspNet/App_Start/RouteConfig.cs create mode 100644 examples/AspNet/App_Start/WebApiConfig.cs create mode 100644 examples/AspNet/Controllers/HomeController.cs create mode 100644 examples/AspNet/Controllers/WeatherForecastController.cs create mode 100644 examples/AspNet/Examples.AspNet.csproj create mode 100644 examples/AspNet/Global.asax create mode 100644 examples/AspNet/Global.asax.cs create mode 100644 examples/AspNet/Models/WeatherForecast.cs create mode 100644 examples/AspNet/Properties/AssemblyInfo.cs create mode 100644 examples/AspNet/SuppressInstrumentationHttpModule.cs create mode 100644 examples/AspNet/Views/Home/About.cshtml create mode 100644 examples/AspNet/Views/Home/Index.cshtml create mode 100644 examples/AspNet/Views/Shared/_Layout.cshtml create mode 100644 examples/AspNet/Views/Web.config create mode 100644 examples/AspNet/Views/_ViewStart.cshtml create mode 100644 examples/AspNet/Web.Debug.config create mode 100644 examples/AspNet/Web.Release.config create mode 100644 examples/AspNet/Web.config diff --git a/examples/AspNet/App_Start/RouteConfig.cs b/examples/AspNet/App_Start/RouteConfig.cs new file mode 100644 index 0000000000..e1c6ae4df1 --- /dev/null +++ b/examples/AspNet/App_Start/RouteConfig.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Web.Mvc; +using System.Web.Routing; + +namespace Examples.AspNet +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapMvcAttributeRoutes(); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }); + } + } +} diff --git a/examples/AspNet/App_Start/WebApiConfig.cs b/examples/AspNet/App_Start/WebApiConfig.cs new file mode 100644 index 0000000000..243637d65d --- /dev/null +++ b/examples/AspNet/App_Start/WebApiConfig.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Net.Http.Formatting; +using System.Web.Http; + +namespace Examples.AspNet +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Web API configuration and services + + // Web API routes + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional }); + + config.Formatters.Clear(); + config.Formatters.Add(new JsonMediaTypeFormatter()); + } + } +} diff --git a/examples/AspNet/Controllers/HomeController.cs b/examples/AspNet/Controllers/HomeController.cs new file mode 100644 index 0000000000..f238805897 --- /dev/null +++ b/examples/AspNet/Controllers/HomeController.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Web.Mvc; + +namespace Examples.AspNet.Controllers +{ + public class HomeController : Controller + { + // For testing traditional routing. Ex: https://localhost:XXXX/ + public ActionResult Index() + { + return this.View(); + } + + [Route("about_attr_route/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/about_attr_route + public ActionResult About(int? customerId) + { + this.ViewBag.Message = $"Your application description page for customer {customerId}."; + + return this.View(); + } + } +} diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000000..092bdf0710 --- /dev/null +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -0,0 +1,217 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Security.Cryptography; +using System.Threading.Tasks; +using System.Web.Http; +using Examples.AspNet.Models; +using OpenTelemetry; + +namespace Examples.AspNet.Controllers +{ + public class WeatherForecastController : ApiController + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", + }; + + [HttpGet] // For testing traditional routing. Ex: https://localhost:XXXX/api/weatherforecast + public async Task> Get() + { + // Build some dependency spans. + + await RequestGoogleHomPageViaHttpClient().ConfigureAwait(false); + + await this.RequestInvalidViaHttpClient().ConfigureAwait(false); + + await this.RequestValidThatReturnsFailedViaHttpClient().ConfigureAwait(false); + + await this.RequestValidThatSpawnsSubSpansViaHttpClient().ConfigureAwait(false); + + return GetWeatherForecast(); + } + + [Route("subroute/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/subroute/10 + [HttpGet] + public async Task> Get(int customerId) + { + if (customerId < 0) + { + throw new ArgumentException(); + } + + // Making http calls here to serve as an example of + // how dependency calls will be captured and treated + // automatically as child of incoming request. + + RequestGoogleHomPageViaHttpWebRequestLegacySync(); + + await RequestGoogleHomPageViaHttpWebRequestLegacyAsync().ConfigureAwait(false); + + RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult(); + + return GetWeatherForecast(); + } + + /// + /// For testing large async operation which causes IIS to jump threads and results in lost AsyncLocals. + /// + [Route("data")] + [HttpGet] + public async Task GetData() + { + Baggage.SetBaggage("key1", "value1"); + + using var rng = RandomNumberGenerator.Create(); + + var requestData = new byte[1024 * 1024 * 100]; + rng.GetBytes(requestData); + + using var client = new HttpClient(); + + using var request = new HttpRequestMessage(HttpMethod.Post, this.Url.Content("~/data")); + + request.Content = new ByteArrayContent(requestData); + + using var response = await client.SendAsync(request).ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + + var responseData = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + + return responseData.SequenceEqual(responseData) ? "match" : "mismatch"; + } + + [Route("data")] + [HttpPost] + public async Task PostData() + { + string value1 = Baggage.GetBaggage("key1"); + if (string.IsNullOrEmpty(value1)) + { + throw new InvalidOperationException("Key1 was not found on Baggage."); + } + + var stream = await this.Request.Content.ReadAsStreamAsync().ConfigureAwait(false); + + var result = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StreamContent(stream), + }; + + result.Content.Headers.ContentType = this.Request.Content.Headers.ContentType; + + return result; + } + + private static IEnumerable GetWeatherForecast() + { + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)], + }) + .ToArray(); + } + + // Test successful dependency collection via HttpClient. + private static async Task RequestGoogleHomPageViaHttpClient() + { + using var request = new HttpClient(); + + using var response = await request.GetAsync("http://www.google.com").ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + } + + // Test dependency collection via legacy HttpWebRequest sync. + private static void RequestGoogleHomPageViaHttpWebRequestLegacySync() + { + var request = WebRequest.Create("http://www.google.com/?sync"); + + using var response = request.GetResponse(); + } + + // Test dependency collection via legacy HttpWebRequest async. + private static async Task RequestGoogleHomPageViaHttpWebRequestLegacyAsync() + { + var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); + + using var response = await request.GetResponseAsync().ConfigureAwait(false); + } + + // Test dependency collection via legacy HttpWebRequest IAsyncResult. + private static void RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult() + { + var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); + + var asyncResult = request.BeginGetResponse(null, null); + + using var response = request.EndGetResponse(asyncResult); + } + + // Test exception dependency collection via HttpClient. + private async Task RequestInvalidViaHttpClient() + { + try + { + using var request = new HttpClient(); + + // This request is not available over SSL and will throw a handshake exception. + + using var response = await request.GetAsync(this.Url.Content("~/subroute/10").Replace("http", "https")).ConfigureAwait(false); + + Debug.Fail("Unreachable"); + } + catch + { + } + } + + // Test exception dependency collection via HttpClient. + private async Task RequestValidThatReturnsFailedViaHttpClient() + { + using var request = new HttpClient(); + + // This request will return a 500 error because customerId should be >= 0; + + using var response = await request.GetAsync(this.Url.Content("~/subroute/-1")).ConfigureAwait(false); + + Debug.Assert(response.StatusCode == HttpStatusCode.InternalServerError, "response.StatusCode is InternalServerError"); + } + + // Test successful dependency collection via HttpClient. + private async Task RequestValidThatSpawnsSubSpansViaHttpClient() + { + using var request = new HttpClient(); + + // This request will return successfully and cause a bunch of sub-spans; + + using var response = await request.GetAsync(this.Url.Content("~/subroute/10")).ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + } + } +} diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj new file mode 100644 index 0000000000..9dcd7be47c --- /dev/null +++ b/examples/AspNet/Examples.AspNet.csproj @@ -0,0 +1,132 @@ + + + + PackageReference + Debug + AnyCPU + + + 2.0 + {9A4E3A68-904B-4835-A3C8-F664B73098DB} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + OpenTelemetry.Exporter.AspNet + OpenTelemetry.Exporter.AspNet + v4.8 + true + + + + + + + + false + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + Global.asax + + + + + + + + + + + + + Web.config + + + Web.config + + + + + + + + + + + + + + + + + {582b70b5-0067-4d9a-abf2-623f502be9a9} + OpenTelemetry.Instrumentation.AspNet + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + $(BuildDependsOn) + SkipBuildWithoutVisualStudio + + + + + + True + True + 0 + / + http://localhost:56171/ + False + False + + + False + + + + + diff --git a/examples/AspNet/Global.asax b/examples/AspNet/Global.asax new file mode 100644 index 0000000000..e6d835ed40 --- /dev/null +++ b/examples/AspNet/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="Examples.AspNet.WebApiApplication" Language="C#" %> diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs new file mode 100644 index 0000000000..260dda7f92 --- /dev/null +++ b/examples/AspNet/Global.asax.cs @@ -0,0 +1,111 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Configuration; +using System.Web; +using System.Web.Http; +using System.Web.Mvc; +using System.Web.Routing; +using OpenTelemetry; +using OpenTelemetry.Exporter; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Examples.AspNet +{ +#pragma warning disable SA1649 // File name should match first type name + public class WebApiApplication : HttpApplication +#pragma warning restore SA1649 // File name should match first type name + { + private IDisposable tracerProvider; + private IDisposable meterProvider; + + protected void Application_Start() + { + var builder = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation() + .AddHttpClientInstrumentation(); + + switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant()) + { + case "jaeger": + builder.AddJaegerExporter(jaegerOptions => + { + jaegerOptions.AgentHost = ConfigurationManager.AppSettings["JaegerHost"]; + jaegerOptions.AgentPort = int.Parse(ConfigurationManager.AppSettings["JaegerPort"]); + }); + break; + case "zipkin": + builder.AddZipkinExporter(zipkinOptions => + { + zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]); + }); + break; + case "otlp": + builder.AddOtlpExporter(otlpOptions => + { + otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); + }); + break; + default: + builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug); + break; + } + + this.tracerProvider = builder.Build(); + + // Metrics + // Note: Tracerprovider is needed for metrics to work + // https://github.com/open-telemetry/opentelemetry-dotnet/issues/2994 + + var meterBuilder = Sdk.CreateMeterProviderBuilder() + .AddAspNetInstrumentation(); + + switch (ConfigurationManager.AppSettings["UseMetricsExporter"].ToLowerInvariant()) + { + case "otlp": + meterBuilder.AddOtlpExporter(otlpOptions => + { + otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); + }); + break; + case "prometheus": + meterBuilder.AddPrometheusExporter(); + break; + default: + meterBuilder.AddConsoleExporter((exporterOptions, metricReaderOptions) => + { + exporterOptions.Targets = ConsoleExporterOutputTargets.Debug; + }); + break; + } + + this.meterProvider = meterBuilder.Build(); + + GlobalConfiguration.Configure(WebApiConfig.Register); + + AreaRegistration.RegisterAllAreas(); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + + protected void Application_End() + { + this.tracerProvider?.Dispose(); + this.meterProvider?.Dispose(); + } + } +} diff --git a/examples/AspNet/Models/WeatherForecast.cs b/examples/AspNet/Models/WeatherForecast.cs new file mode 100644 index 0000000000..71e8983c6d --- /dev/null +++ b/examples/AspNet/Models/WeatherForecast.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace Examples.AspNet.Models +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); + + public string Summary { get; set; } + } +} diff --git a/examples/AspNet/Properties/AssemblyInfo.cs b/examples/AspNet/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..7dd41a41ac --- /dev/null +++ b/examples/AspNet/Properties/AssemblyInfo.cs @@ -0,0 +1,50 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Examples.AspNet")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Examples.AspNet")] +[assembly: AssemblyCopyright("Copyright @ 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9a4e3a68-904b-4835-a3c8-f664b73098db")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/AspNet/SuppressInstrumentationHttpModule.cs b/examples/AspNet/SuppressInstrumentationHttpModule.cs new file mode 100644 index 0000000000..fb83210918 --- /dev/null +++ b/examples/AspNet/SuppressInstrumentationHttpModule.cs @@ -0,0 +1,58 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Web; +using OpenTelemetry; + +namespace Examples.AspNet +{ + /// + /// A demo which will suppress ASP.NET + /// instrumentation if a request contains "suppress=true" on the query + /// string. Suppressed spans will not be processed/exported by the + /// OpenTelemetry SDK. + /// + public class SuppressInstrumentationHttpModule : IHttpModule + { + private IDisposable suppressionScope; + + public void Init(HttpApplication context) + { + context.BeginRequest += this.Application_BeginRequest; + context.EndRequest += this.Application_EndRequest; + } + + public void Dispose() + { + } + + private void Application_BeginRequest(object sender, EventArgs e) + { + var context = ((HttpApplication)sender).Context; + + if (context.Request.QueryString["suppress"] == "true") + { + this.suppressionScope = SuppressInstrumentationScope.Begin(); + } + } + + private void Application_EndRequest(object sender, EventArgs e) + { + this.suppressionScope?.Dispose(); + } + } +} diff --git a/examples/AspNet/Views/Home/About.cshtml b/examples/AspNet/Views/Home/About.cshtml new file mode 100644 index 0000000000..4b2d9e8440 --- /dev/null +++ b/examples/AspNet/Views/Home/About.cshtml @@ -0,0 +1,7 @@ +@{ + ViewBag.Title = "About"; +} +

@ViewBag.Title.

+

@ViewBag.Message

+ +

Use this area to provide additional information.

diff --git a/examples/AspNet/Views/Home/Index.cshtml b/examples/AspNet/Views/Home/Index.cshtml new file mode 100644 index 0000000000..b89b4453d3 --- /dev/null +++ b/examples/AspNet/Views/Home/Index.cshtml @@ -0,0 +1,31 @@ +@{ + ViewBag.Title = "Home Page"; +} + +
+

ASP.NET

+

ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

+

Learn more »

+
+ +
+
+

Getting started

+

+ ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that + enables a clean separation of concerns and gives you full control over markup + for enjoyable, agile development. +

+

Learn more »

+
+
+

Get more libraries

+

NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.

+

Learn more »

+
+
+

Web Hosting

+

You can easily find a web hosting company that offers the right mix of features and price for your applications.

+

Learn more »

+
+
diff --git a/examples/AspNet/Views/Shared/_Layout.cshtml b/examples/AspNet/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000000..160995d961 --- /dev/null +++ b/examples/AspNet/Views/Shared/_Layout.cshtml @@ -0,0 +1,36 @@ + + + + + + @ViewBag.Title - My ASP.NET Application + + + +
+ @RenderBody() +
+
+

© @DateTime.Now.Year - My ASP.NET Application

+
+
+ + @RenderSection("scripts", required: false) + + diff --git a/examples/AspNet/Views/Web.config b/examples/AspNet/Views/Web.config new file mode 100644 index 0000000000..6e67a6c67f --- /dev/null +++ b/examples/AspNet/Views/Web.config @@ -0,0 +1,42 @@ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/AspNet/Views/_ViewStart.cshtml b/examples/AspNet/Views/_ViewStart.cshtml new file mode 100644 index 0000000000..2de62418c0 --- /dev/null +++ b/examples/AspNet/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "~/Views/Shared/_Layout.cshtml"; +} diff --git a/examples/AspNet/Web.Debug.config b/examples/AspNet/Web.Debug.config new file mode 100644 index 0000000000..104f153f93 --- /dev/null +++ b/examples/AspNet/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/examples/AspNet/Web.Release.config b/examples/AspNet/Web.Release.config new file mode 100644 index 0000000000..63c58428af --- /dev/null +++ b/examples/AspNet/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config new file mode 100644 index 0000000000..bd4f12f8b1 --- /dev/null +++ b/examples/AspNet/Web.config @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 50cdefa021..537a8ee4bd 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -217,6 +217,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNet.Tests", "test\OpenTelemetry.Instrumentation.AspNet.Tests\OpenTelemetry.Instrumentation.AspNet.Tests.csproj", "{F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNet", "AspNet", "{2B6D0764-5E66-423A-9943-B3A72FF181EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.AspNet", "examples\AspNet\Examples.AspNet.csproj", "{9A4E3A68-904B-4835-A3C8-F664B73098DB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -455,6 +459,10 @@ Global {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Debug|Any CPU.Build.0 = Debug|Any CPU {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Release|Any CPU.ActiveCfg = Release|Any CPU {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72}.Release|Any CPU.Build.0 = Release|Any CPU + {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -525,6 +533,8 @@ Global {969425CE-CB8F-462C-9126-597FC5B33E27} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {582B70B5-0067-4D9A-ABF2-623F502BE9A9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {2B6D0764-5E66-423A-9943-B3A72FF181EA} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {9A4E3A68-904B-4835-A3C8-F664B73098DB} = {2B6D0764-5E66-423A-9943-B3A72FF181EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From 3ac93f80595b02e7c31d57a6caf44f8bfe249255 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 20 Jun 2022 14:33:37 -0700 Subject: [PATCH 0172/1499] target net462 on windows only (#440) --- ...nTelemetry.Extensions.PersistentStorage.Abstractions.csproj | 3 ++- .../OpenTelemetry.Extensions.PersistentStorage.csproj | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj index 92d663befe..9aaa8920c3 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net462 + netstandard2.0 + $(TargetFrameworks);net462 $(TargetFrameworks);net6.0 OpenTelemetry Persistent Storage Abstractions Extensions.PersistentStorage.Abstractions- diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj index 1e8444f62d..37990a64fb 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net462 + netstandard2.0 + $(TargetFrameworks);net462 OpenTelemetry Persistent Storage Extensions.PersistentStorage- From 18908b26688e0699e6bf9c31b3e5b17ac9b7c970 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 20 Jun 2022 14:56:42 -0700 Subject: [PATCH 0173/1499] update changelog (#438) --- .../CHANGELOG.md | 2 +- .../CHANGELOG.md | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md index 7f84dab7e5..a26937528c 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## ## 1.0.0-alpha.4 This is the first release for the `OpenTelemetry.Extensions.PersistentStorage.Abstractions` project. diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md index 9bc42576c0..73f825e00b 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md @@ -1,9 +1,10 @@ # Changelog - OpenTelemetry.Extensions.PersistentStorage -## Unreleased +## 1.0.0-alpha.4 -* [Update implementation to use - Opentelemetry.Extensions.PersistentStorage.Abstractions](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/363) +* Update implementation to use + Opentelemetry.Extensions.PersistentStorage.Abstractions. + [363](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/363) ## 1.0.0-alpha.3 From 4a23a7e3154ab9990a0624a665e229fef0a294ac Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 15:15:56 -0700 Subject: [PATCH 0174/1499] [Exporter.Geneva] Update target framework from net461 to net462 (#441) * Update target framework from net461 to net462 --- .../.publicApi/{net461 => net462}/PublicAPI.Shipped.txt | 0 .../.publicApi/{net461 => net462}/PublicAPI.Unshipped.txt | 0 src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs | 2 -- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 4 deletions(-) rename src/OpenTelemetry.Exporter.Geneva/.publicApi/{net461 => net462}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.Geneva/.publicApi/{net461 => net462}/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/.publicApi/net461/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f0512853e3..6c1fb9d175 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -9,6 +9,10 @@ * Update OTel SDK version to `1.3.0`. [427](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/427) +* Remove support for .NET Framework 4.6.1. The minimum .NET Framework version +supported now is .NET 4.6.2. +[441](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/441) + ## 1.3.0-beta.2 [2022-Jun-03] * Add support for exporting `ILogger` scopes. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index e7331a66e7..38f7c480da 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if NETSTANDARD2_0 || NET461 using System; using OpenTelemetry; using OpenTelemetry.Exporter.Geneva; @@ -42,4 +41,3 @@ public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetry } } } -#endif diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 4e0b95098a..99e3165823 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -6,7 +6,7 @@ OpenTelemetry Authors $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 netstandard2.0 - $(TargetFrameworks);net461 + $(TargetFrameworks);net462 Exporter.Geneva- true true diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index c3d76166fb..29cf056feb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -4,7 +4,7 @@ Unit test project for Geneva Exporters for OpenTelemetry false netcoreapp3.1;net6.0 - $(TargetFrameworks);net461;net462;net47;net471;net472;net48 + $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 From 3f3c68a56cc258b652119f7df791223ae6414031 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 16:41:00 -0700 Subject: [PATCH 0175/1499] Update PersistentStorage Abstractions workflow (#442) --- .../package-Extensions.PersistentStorage.Abstractions.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml index 25c1592090..82b0bf477b 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml @@ -27,14 +27,11 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - name: dotnet pack ${{env.PROJECT}} run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build From 07c0248a128d410a47374ba273745914d981cd58 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 17:15:22 -0700 Subject: [PATCH 0176/1499] [Instrumentation.AspNet] Update AspNetTelemetryHttpModule depdendency as a project reference (#443) * Update AspNetTelemetryHttpModule depdendency as a project reference --- .../OpenTelemetry.Instrumentation.AspNet.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index ce047f848c..03f775a3d7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -22,7 +22,7 @@ - + From fa8c9efc0a3730ba2372506d0dbf953e453e1415 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Jun 2022 17:30:21 -0700 Subject: [PATCH 0177/1499] [Exporter.Geneva] Fix ExportResult on Linux (#444) * Fix ExporterResult on Linux --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 +++++++ .../UnixDomainSocketDataTransport.cs | 10 +++------- .../UnixDomainSocketDataTransportTests.cs | 8 ++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 6c1fb9d175..6a6d7e957e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -13,6 +13,13 @@ supported now is .NET 4.6.2. [441](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/441) +* Fix the incorrect `ExportResult` issue on Linux: +[422](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/422) +by throwing any exception caught by `UnixDomainSocketDataTransport.Send` so that +`Export` methods cn catch it and correctly set `ExportResult` to +`ExportResult.Failure`. +[444](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/444) + ## 1.3.0-beta.2 [2022-Jun-03] * Add support for exporting `ILogger` scopes. diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs index 44f0b9e158..04628e7a49 100644 --- a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs @@ -63,14 +63,10 @@ public void Send(byte[] data, int size) this.socket.Send(data, size, SocketFlags.None); } - catch (SocketException ex) + catch (Exception) { - // SocketException from Socket.Send - ExporterEventSource.Log.ExporterException("UDS Send failed.", ex); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("UDS Send failed.", ex); + // Re-throw the exception so that Export method catches it and sets the ExportResult correctly. + throw; } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index a180314a67..021fb55140 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -163,10 +163,10 @@ public void UnixDomainSocketDataTransport_ServerRestart_Linux() Console.WriteLine("Destroyed server."); - Console.WriteLine("Client will fail during Send, but shouldn't throw exception."); - dataTransport.Send(data, data.Length); - Console.WriteLine("Client will fail during reconnect, but shouldn't throw exception."); - dataTransport.Send(data, data.Length); + Console.WriteLine("Client will fail during Send, and should throw an Exception"); + Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); + Console.WriteLine("Client will fail during Reconnect, and should throw an Exception"); + Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); server2.Bind(endpoint); From 986f65d91c724be7ace52c9565d1d2a570c261b4 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 21 Jun 2022 15:48:29 -0700 Subject: [PATCH 0178/1499] Update CHANGELOG for 1.0.0-rc9.5 release (#445) --- .../CHANGELOG.md | 16 ++++++++++++-- .../CHANGELOG.md | 22 +++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index fbb62f7ebb..ed4038c5fc 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,17 @@ ## Unreleased +## 1.0.0-rc9.5 (source code moved to contrib repo) + +Released 2022-Jun-21 + +* From this version onwards, the source code for this package would be hosted in + the + [contrib](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule) + repo. The source code for this package before this version was hosted on the + [main](https://github.com/open-telemetry/opentelemetry-dotnet/tree/core-1.3.0/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule) + repo. + ## 1.0.0-rc9.4 Released 2022-Jun-03 @@ -10,8 +21,9 @@ Released 2022-Jun-03 Released 2022-Apr-15 -* Removes .NET Framework 4.6.1. The minimum .NET Framework - version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) +* Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is + .NET 4.6.2. + ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) ## 1.0.0-rc9.2 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 9f6c1880f3..71a4bfa708 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,17 @@ ## Unreleased +## 1.0.0-rc9.5 (source code moved to contrib repo) + +Released 2022-Jun-21 + +* From this version onwards, the source code for this package would be hosted in + the + [contrib](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.AspNet) + repo. The source code for this package before this version was hosted on the + [main](https://github.com/open-telemetry/opentelemetry-dotnet/tree/core-1.3.0/src/OpenTelemetry.Instrumentation.AspNet) + repo. + ## 1.0.0-rc9.4 Released 2022-Jun-03 @@ -10,8 +21,9 @@ Released 2022-Jun-03 Released 2022-Apr-15 -* Removes .NET Framework 4.6.1. The minimum .NET Framework - version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) +* Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is + .NET 4.6.2. + ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) ## 1.0.0-rc9.2 @@ -40,7 +52,8 @@ Released 2022-Feb-02 Released 2021-Oct-08 * Removes .NET Framework 4.5.2, .NET 4.6 support. The minimum .NET Framework - version supported is .NET 4.6.1. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138)) + version supported is .NET 4.6.1. + ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138)) * Replaced `http.path` tag on activity with `http.target`. ([#2266](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2266)) @@ -75,7 +88,8 @@ Released 2021-Jun-09 Released 2021-Apr-23 -* Sanitize `http.url` attribute. ([#1961](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1961)) +* Sanitize `http.url` attribute. + ([#1961](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1961)) ## 1.0.0-rc3 From 70b1404f7f7a1201f1a2dfb3526578ce59356a33 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 22 Jun 2022 09:20:11 -0700 Subject: [PATCH 0179/1499] Update a few metrics to be in sync of doc updates for `gc.heap`, `gc.fragmentation.ratio`, `time.in.jit`, `process.cpu.count` and `assembly.count` (#430) --- .../CHANGELOG.md | 4 +++ .../RuntimeMetrics.cs | 29 ++++++++++--------- .../RuntimeMetricsTests.cs | 5 +--- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 115f7b72f0..c8d0e0c308 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Update a few metrics to be in sync of doc updates for `gc.heap`, + `gc.fragmentation.ratio`, `time.in.jit`, `process.cpu.count` and `assembly.count` + ([#430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/430)) + ## 0.2.0-alpha.1 * Updated OTel SDK package version to 1.3.0 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index ebae341a47..5f75c07c05 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -49,17 +49,16 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsGcEnabled) { - // TODO: Almost all the ObservableGauge should be ObservableUpDownCounter (except for CPU utilization and fragmentation.ratio. + // TODO: Almost all the ObservableGauge should be ObservableUpDownCounter (except for CPU utilization). // Replace them once ObservableUpDownCounter is available. - this.meter.CreateObservableGauge($"{metricPrefix}gc.heap", () => GC.GetTotalMemory(false), "By", "GC Heap Size."); this.meter.CreateObservableGauge($"{metricPrefix}gc.count", () => GetGarbageCollectionCounts(), description: "GC Count for all generations."); #if NETCOREAPP3_1_OR_GREATER this.meter.CreateObservableCounter($"{metricPrefix}gc.allocated.bytes", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate."); - this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.ratio", GetFragmentation, description: "GC Fragmentation."); #endif #if NET6_0_OR_GREATER + this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.size", GetFragmentationSizes, description: "GC fragmentation."); this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GC.GetGCMemoryInfo().TotalCommittedBytes, "By", description: "GC Committed Bytes."); this.meter.CreateObservableGauge($"{metricPrefix}gc.heapsize", () => GetGarbageCollectionHeapSizes(), "By", "Heap size for all generations."); #endif @@ -70,7 +69,7 @@ public RuntimeMetrics(RuntimeMetricsOptions options) { this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "By", description: "IL Bytes Jitted."); this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted."); - this.meter.CreateObservableGauge($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, "ns", description: "Time spent in JIT."); + this.meter.CreateObservableCounter($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, "ns", description: "Time spent in JIT."); } #endif @@ -88,16 +87,13 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsProcessEnabled) { this.meter.CreateObservableCounter("process.cpu.time", GetProcessorTimes, "s", "Processor time of this process."); - - // Not yet official: https://github.com/open-telemetry/opentelemetry-specification/pull/2392 - this.meter.CreateObservableGauge("process.cpu.count", () => (long)Environment.ProcessorCount, description: "The number of available logical CPUs."); this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use."); this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory."); } if (options.IsAssembliesEnabled) { - this.meter.CreateObservableCounter($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); + this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); } } @@ -115,15 +111,20 @@ private static IEnumerable> GetGarbageCollectionCounts() } } -#if NETCOREAPP3_1_OR_GREATER - private static double GetFragmentation() +#if NET6_0_OR_GREATER + private static IEnumerable> GetFragmentationSizes() { - var gcInfo = GC.GetGCMemoryInfo(); - return gcInfo.HeapSizeBytes != 0 ? gcInfo.FragmentedBytes * 1.0d / gcInfo.HeapSizeBytes : 0; + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) + { + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("gen", GenNames[i])); + } + + return measurements; } -#endif -#if NET6_0_OR_GREATER private static IEnumerable> GetGarbageCollectionHeapSizes() { var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 997a62f6d6..c57210aa64 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -75,15 +75,12 @@ public void ProcessMetricsAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.Equal(4, exportedItems.Count); + Assert.Equal(3, exportedItems.Count); var cpuTimeMetric = exportedItems.First(i => i.Name == "process.cpu.time"); var sumReceived = GetDoubleSum(cpuTimeMetric); Assert.True(sumReceived > 0); - var cpuCountMetric = exportedItems.First(i => i.Name == "process.cpu.count"); - Assert.Equal(Environment.ProcessorCount, (int)GetLongSum(cpuCountMetric)); - var memoryMetric = exportedItems.First(i => i.Name == "process.memory.usage"); Assert.True(GetLongSum(memoryMetric) > 0); From 351094bc8d5712c409d45ef790b0c756fd60207e Mon Sep 17 00:00:00 2001 From: Swetha Ravichandran Date: Wed, 22 Jun 2022 09:34:24 -0700 Subject: [PATCH 0180/1499] #172 Resource detectors for Docker (#432) --- .../OpenTelemetry.Extensions.Docker.csproj | 4 ++-- src/OpenTelemetry.Extensions.Docker/README.md | 2 +- .../OpenTelemetry.Extensions.Docker.Tests.csproj | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj index d70c0d06c6..4ae5ed2cb3 100644 --- a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj +++ b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj @@ -1,10 +1,10 @@ - ;net461;netstandard2.0 + ;net462;netstandard2.0 OpenTelemetry Extensions - Container Resource Detector from Docker environment. Extensions.Docker- - + diff --git a/src/OpenTelemetry.Extensions.Docker/README.md b/src/OpenTelemetry.Extensions.Docker/README.md index 63ed574581..1d8b0ed735 100644 --- a/src/OpenTelemetry.Extensions.Docker/README.md +++ b/src/OpenTelemetry.Extensions.Docker/README.md @@ -31,7 +31,7 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() The resource detectors will record the following metadata based on where your application is running: -- **DockerResourceDetector**: container id. +- **DockerResourceDetector**: container.id. ## References diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj index 5596e02af2..7e15fdc3b3 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -2,8 +2,8 @@ Unit test project for Docker Detector for OpenTelemetry - netcoreapp3.1 - $(TargetFrameworks);net461 + netcoreapp3.1;net6.0 + $(TargetFrameworks);net462 From 3fe27a2853b61a375e329f5552438264a9a4be8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jun 2022 09:49:08 -0700 Subject: [PATCH 0181/1499] Bump Newtonsoft.Json in /src/OpenTelemetry.Contrib.Extensions.AWSXRay (#448) Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 11.0.1 to 13.0.1. - [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases) - [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/11.0.1...13.0.1) --- updated-dependencies: - dependency-name: Newtonsoft.Json dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../OpenTelemetry.Contrib.Extensions.AWSXRay.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 108b059cf1..1064cc11a9 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -6,7 +6,7 @@ - + From b7fda495df9427540da4460ae8af1429cef5f84b Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 22 Jun 2022 10:41:23 -0700 Subject: [PATCH 0182/1499] fix nits (#450) * fix nits * fix nits * fix nits --- build/Common.nonprod.props | 1 + build/Common.props | 3 ++- examples/redis/Examples.StackExchangeRedis/Program.cs | 2 -- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 3dd5e62aa5..501b84b024 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -25,6 +25,7 @@ [5.0,6.0) [16.7.1,17.0) [4.14.5,5.0) + $(OpenTelemetryPkgVer) [2.4.3,3.0) [2.4.1,3.0) diff --git a/build/Common.props b/build/Common.props index 55bfe93640..cb3e4661a5 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,7 +31,8 @@ [4.1.1] [3.3.2] [1.0.0,2.0) - 1.3.0 + [1.3.0,2.0) + $(OpenTelemetryApiPkgVer) [2.1.58,3.0) [1.2.0-beta.354,2.0) diff --git a/examples/redis/Examples.StackExchangeRedis/Program.cs b/examples/redis/Examples.StackExchangeRedis/Program.cs index 9216209548..b36b680f5a 100644 --- a/examples/redis/Examples.StackExchangeRedis/Program.cs +++ b/examples/redis/Examples.StackExchangeRedis/Program.cs @@ -19,8 +19,6 @@ using OpenTelemetry.Trace; using StackExchange.Redis; -namespace GettingStartedPrometheusGrafana; - public class Program { public static void Main() diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 99e3165823..380115bd7e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 6cbe902371..8ffb54c1aa 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -8,7 +8,7 @@ - + From ff1033a34867bf11c4d01e77263f7c9b2d8724ef Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 22 Jun 2022 11:31:48 -0700 Subject: [PATCH 0183/1499] Add an example of the .NET Runtime Instrumentation (#449) --- examples/runtime-instrumentation/Program.cs | 36 +++++++++++++++++++ .../runtime-instrumentation.csproj | 12 +++++++ ...enTelemetry.Instrumentation.Runtime.csproj | 25 +++++++------ 3 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 examples/runtime-instrumentation/Program.cs create mode 100644 examples/runtime-instrumentation/runtime-instrumentation.csproj diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs new file mode 100644 index 0000000000..139c7bb37b --- /dev/null +++ b/examples/runtime-instrumentation/Program.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry; +using OpenTelemetry.Metrics; + +public class Program +{ + public static void Main() + { + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeMetrics() + .AddPrometheusExporter(options => + { + options.StartHttpListener = true; + options.ScrapeResponseCacheDurationMilliseconds = 0; + }) + .Build(); + + Console.WriteLine(".NET Runtime metrics are available at http://localhost:9464/metrics, press any key to exit..."); + Console.ReadKey(false); + } +} diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj new file mode 100644 index 0000000000..eb026e5dca --- /dev/null +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -0,0 +1,12 @@ + + + net6.0 + Exe + enable + enable + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 8ffb54c1aa..4fce0322ce 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -1,17 +1,16 @@ + + netstandard2.0;net462;netcoreapp3.1;net6.0 + dotnet runtime instrumentation for OpenTelemetry .NET + $(PackageTags);runtime + Instrumentation.Runtime- + - - netstandard2.0;net461;netcoreapp3.1;net6.0 - dotnet runtime instrumentation for OpenTelemetry .NET - $(PackageTags);runtime - Instrumentation.Runtime- - + + + - - - - - - - + + + From 8da864cf42ba16c74bcd701254461e4e00d18a44 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 22 Jun 2022 14:05:40 -0700 Subject: [PATCH 0184/1499] Remove Process related metrics from .NET Runtime metrics (#446) --- .../CHANGELOG.md | 2 + .../RuntimeMetrics.cs | 17 +---- .../RuntimeMetricsOptions.cs | 11 --- .../RuntimeMetricsOptionsTests.cs | 27 +------ .../RuntimeMetricsTests.cs | 75 ------------------- 5 files changed, 6 insertions(+), 126 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index c8d0e0c308..5ce8267e96 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -5,6 +5,8 @@ * Update a few metrics to be in sync of doc updates for `gc.heap`, `gc.fragmentation.ratio`, `time.in.jit`, `process.cpu.count` and `assembly.count` ([#430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/430)) +* Remove Process related metrics from .NET Runtime metrics + ([#446](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/446)) ## 0.2.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 5f75c07c05..816d4a3ff2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Diagnostics.Metrics; using System.Reflection; #if NETCOREAPP3_1_OR_GREATER @@ -33,7 +32,9 @@ internal class RuntimeMetrics : IDisposable internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); internal static readonly string InstrumentationName = AssemblyName.Name; internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); +#if NET6_0_OR_GREATER private const long NanosecondsPerTick = 100; +#endif private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; private static readonly int NumberOfGenerations = 3; private static string metricPrefix = "process.runtime.dotnet."; @@ -84,13 +85,6 @@ public RuntimeMetrics(RuntimeMetricsOptions options) } #endif - if (options.IsProcessEnabled) - { - this.meter.CreateObservableCounter("process.cpu.time", GetProcessorTimes, "s", "Processor time of this process."); - this.meter.CreateObservableGauge("process.memory.usage", () => Process.GetCurrentProcess().WorkingSet64, "By", "The amount of physical memory in use."); - this.meter.CreateObservableGauge("process.memory.virtual", () => Process.GetCurrentProcess().VirtualMemorySize64, "By", "The amount of committed virtual memory."); - } - if (options.IsAssembliesEnabled) { this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); @@ -139,12 +133,5 @@ private static IEnumerable> GetGarbageCollectionHeapSizes() return measurements; } #endif - - private static IEnumerable> GetProcessorTimes() - { - var process = Process.GetCurrentProcess(); - yield return new(process.UserProcessorTime.TotalSeconds, new KeyValuePair("state", "user")); - yield return new(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("state", "system")); - } } } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs index 03075c5e75..1c5c1b5f08 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -40,11 +40,6 @@ public class RuntimeMetricsOptions public bool? ThreadingEnabled { get; set; } #endif - /// - /// Gets or sets a value indicating whether process metrics should be collected. - /// - public bool? ProcessEnabled { get; set; } - /// /// Gets or sets a value indicating whether assembly metrics should be collected. /// @@ -60,7 +55,6 @@ public class RuntimeMetricsOptions #if NETCOREAPP3_1_OR_GREATER && this.ThreadingEnabled == null #endif - && this.ProcessEnabled == null && this.AssembliesEnabled == null; /// @@ -82,11 +76,6 @@ public class RuntimeMetricsOptions internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; #endif - /// - /// Gets a value indicating whether process metrics is enabled. - /// - internal bool IsProcessEnabled => this.ProcessEnabled == true || this.IsAllEnabled; - /// /// Gets a value indicating whether assembly metrics is enabled. /// diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs index 78dca4b563..98484160cf 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -32,7 +32,6 @@ public void Enable_All_If_Nothing_Was_Defined() #if NETCOREAPP3_1_OR_GREATER Assert.True(options.IsThreadingEnabled); #endif - Assert.True(options.IsProcessEnabled); Assert.True(options.IsAssembliesEnabled); Assert.True(options.IsAllEnabled); } @@ -49,7 +48,6 @@ public void Enable_Gc_Only() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -63,7 +61,6 @@ public void Enable_Jit_Only() Assert.False(options.IsGcEnabled); Assert.True(options.IsJitEnabled); Assert.False(options.IsThreadingEnabled); - Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -80,29 +77,11 @@ public void Enable_Threading_Only() Assert.False(options.IsJitEnabled); #endif Assert.True(options.IsThreadingEnabled); - Assert.False(options.IsProcessEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } #endif - [Fact] - public void Enable_Process_Only() - { - var options = new RuntimeMetricsOptions { ProcessEnabled = true }; - - Assert.False(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); -#endif -#if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); -#endif - Assert.True(options.IsProcessEnabled); - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } - [Fact] public void Enable_Assemblies_Only() { @@ -115,7 +94,6 @@ public void Enable_Assemblies_Only() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.False(options.IsProcessEnabled); Assert.True(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } @@ -123,7 +101,7 @@ public void Enable_Assemblies_Only() [Fact] public void Enable_Multiple() { - var options = new RuntimeMetricsOptions { GcEnabled = true, ProcessEnabled = true }; + var options = new RuntimeMetricsOptions { GcEnabled = true, AssembliesEnabled = true }; Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -132,8 +110,7 @@ public void Enable_Multiple() #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif - Assert.True(options.IsProcessEnabled); - Assert.False(options.IsAssembliesEnabled); + Assert.True(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); } } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index c57210aa64..6ac583cd6b 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -14,9 +14,7 @@ // limitations under the License. // -using System; using System.Collections.Generic; -using System.Linq; using OpenTelemetry.Metrics; using Xunit; @@ -38,7 +36,6 @@ public void RuntimeMetricsAreCaptured() #if NETCOREAPP3_1_OR_GREATER options.ThreadingEnabled = true; #endif - options.ProcessEnabled = true; #if NET6_0_OR_GREATER options.JitEnabled = true; @@ -53,77 +50,5 @@ public void RuntimeMetricsAreCaptured() var metric1 = exportedItems[0]; Assert.StartsWith(MetricPrefix, metric1.Name); } - - [Fact] - public void ProcessMetricsAreCaptured() - { - var exportedItems = new List(); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics(options => - { - options.ProcessEnabled = true; - }) - .AddInMemoryExporter(exportedItems) - .Build(); - - // simple CPU spinning - var spinDuration = DateTime.UtcNow.AddMilliseconds(10); - while (DateTime.UtcNow < spinDuration) - { - } - - meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - Assert.Equal(3, exportedItems.Count); - - var cpuTimeMetric = exportedItems.First(i => i.Name == "process.cpu.time"); - var sumReceived = GetDoubleSum(cpuTimeMetric); - Assert.True(sumReceived > 0); - - var memoryMetric = exportedItems.First(i => i.Name == "process.memory.usage"); - Assert.True(GetLongSum(memoryMetric) > 0); - - var virtualMemoryMetric = exportedItems.First(i => i.Name == "process.memory.virtual"); - Assert.True(GetLongSum(virtualMemoryMetric) > 0); - } - - private static double GetDoubleSum(Metric metric) - { - double sum = 0; - - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) - { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumDouble(); - } - else - { - sum += metricPoint.GetGaugeLastValueDouble(); - } - } - - return sum; - } - - private static double GetLongSum(Metric metric) - { - double sum = 0; - - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) - { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumLong(); - } - else - { - sum += metricPoint.GetGaugeLastValueLong(); - } - } - - return sum; - } } } From 1e067c7b579e348c970a20715d5ea0090a69be54 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 22 Jun 2022 15:47:23 -0700 Subject: [PATCH 0185/1499] Add badges to OpenTelemetry.Extensions.PersistentStorage.Abstractions (#451) --- .../README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md index e96b83a75c..7824d9e1e6 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md @@ -1,5 +1,8 @@ # Persistent Storage Abstractions +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) + This package includes APIs which can be extended by exporter owners to implement persistent storage. From d8d0e9326368a7acbadf613368f6b60a3f2e873f Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 22 Jun 2022 16:30:35 -0700 Subject: [PATCH 0186/1499] Dedupe IsPackable setting (#452) --- examples/AspNet/Examples.AspNet.csproj | 1 - examples/owin/Examples.Owin.csproj | 1 - examples/wcf/client-core/Examples.Wcf.Client.Core.csproj | 1 - .../client-netframework/Examples.Wcf.Client.NetFramework.csproj | 1 - .../server-netframework/Examples.Wcf.Server.NetFramework.csproj | 1 - .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 - .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 2 -- .../OpenTelemetry.Extensions.PersistentStorage.Tests.csproj | 1 - ...etry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj | 1 - .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 1 - 10 files changed, 11 deletions(-) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 9dcd7be47c..f13b2ffa57 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -22,7 +22,6 @@ - false true diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index 3e8294e89c..cdbe837143 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -3,7 +3,6 @@ Exe net461 - false diff --git a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj b/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj index 6be5e847bf..388c75e0d8 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj @@ -3,7 +3,6 @@ Exe netcoreapp3.1 - false diff --git a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj index 3ba74dd0fa..4a02ccb2cf 100644 --- a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj +++ b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj @@ -3,7 +3,6 @@ Exe net462 - false diff --git a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj index 3ba74dd0fa..4a02ccb2cf 100644 --- a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj +++ b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj @@ -3,7 +3,6 @@ Exe net462 - false diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 29cf056feb..2a4a44c287 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -2,7 +2,6 @@ Unit test project for Geneva Exporters for OpenTelemetry - false netcoreapp3.1;net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 3090d15741..434d5c9dfc 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -2,8 +2,6 @@ net5.0 - - false diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj index d1a4d1abc1..026fe3d98f 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj @@ -3,7 +3,6 @@ netcoreapp3.1;net6.0 $(TargetFrameworks);net462 - false diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index 0a4edd08a1..84c20ffb54 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -3,7 +3,6 @@ Unit test project for ASP.NET HttpModule net462 - false diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 552d1cd1d3..0ca6a79c0b 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -2,7 +2,6 @@ Unit test project for OpenTelemetry Hangfire instrumentation net472;netcoreapp3.1 - false false From 76f0b06cb8c9874bdf8cceec2d6ec76e9abde133 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 22 Jun 2022 18:07:45 -0700 Subject: [PATCH 0187/1499] Add `exception.count` in Runtime metrics (#431) --- .../CHANGELOG.md | 2 ++ .../RuntimeMetrics.cs | 9 +++++++++ .../RuntimeMetricsOptions.cs | 13 ++++++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 5ce8267e96..e6d2b4f7f1 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -7,6 +7,8 @@ ([#430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/430)) * Remove Process related metrics from .NET Runtime metrics ([#446](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/446)) +* Add `exception.count` in Runtime metrics + ([#431](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/431)) ## 0.2.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 816d4a3ff2..4579363a5b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -89,6 +89,15 @@ public RuntimeMetrics(RuntimeMetricsOptions options) { this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); } + + if (options.IsExceptionCountEnabled) + { + var exceptionCounter = this.meter.CreateCounter($"{metricPrefix}exception.count", description: "Number of exceptions thrown."); + AppDomain.CurrentDomain.FirstChanceException += (source, e) => + { + exceptionCounter.Add(1); + }; + } } /// diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs index 1c5c1b5f08..eb24d3a283 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -45,6 +45,11 @@ public class RuntimeMetricsOptions /// public bool? AssembliesEnabled { get; set; } + /// + /// Gets or sets a value indicating whether exception count metrics should be collected. + /// + public bool? ExceptionCountEnabled { get; set; } + /// /// Gets a value indicating whether all metrics are enabled. /// @@ -55,7 +60,8 @@ public class RuntimeMetricsOptions #if NETCOREAPP3_1_OR_GREATER && this.ThreadingEnabled == null #endif - && this.AssembliesEnabled == null; + && this.AssembliesEnabled == null + && this.ExceptionCountEnabled == null; /// /// Gets a value indicating whether garbage collection metrics is enabled. @@ -80,5 +86,10 @@ public class RuntimeMetricsOptions /// Gets a value indicating whether assembly metrics is enabled. /// internal bool IsAssembliesEnabled => this.AssembliesEnabled == true || this.IsAllEnabled; + + /// + /// Gets a value indicating whether exception count metrics is enabled. + /// + internal bool IsExceptionCountEnabled => this.ExceptionCountEnabled == true || this.IsAllEnabled; } } From 338d5b2d8a5ff90019a5ad0edc2a65ff8441554c Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Thu, 23 Jun 2022 17:25:06 -0700 Subject: [PATCH 0188/1499] Do not report 0 if GC info is not available yet (#453) --- examples/runtime-instrumentation/Program.cs | 1 + .../RuntimeMetrics.cs | 44 +++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index 139c7bb37b..7362fd2ee1 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -30,6 +30,7 @@ public static void Main() }) .Build(); + // GC.Collect(0); Console.WriteLine(".NET Runtime metrics are available at http://localhost:9464/metrics, press any key to exit..."); Console.ReadKey(false); } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 4579363a5b..cb433611b4 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -37,6 +37,7 @@ internal class RuntimeMetrics : IDisposable #endif private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; private static readonly int NumberOfGenerations = 3; + private static bool isGcInfoAvailable; private static string metricPrefix = "process.runtime.dotnet."; private readonly Meter meter; @@ -59,9 +60,9 @@ public RuntimeMetrics(RuntimeMetricsOptions options) #endif #if NET6_0_OR_GREATER - this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.size", GetFragmentationSizes, description: "GC fragmentation."); - this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GC.GetGCMemoryInfo().TotalCommittedBytes, "By", description: "GC Committed Bytes."); + this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GetGarbageCollectionCommittedBytes(), "By", description: "GC Committed Bytes."); this.meter.CreateObservableGauge($"{metricPrefix}gc.heapsize", () => GetGarbageCollectionHeapSizes(), "By", "Heap size for all generations."); + this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.size", GetFragmentationSizes, description: "GC fragmentation."); #endif } @@ -100,6 +101,24 @@ public RuntimeMetrics(RuntimeMetricsOptions options) } } + private static bool IsGcInfoAvailable + { + get + { + if (isGcInfoAvailable) + { + return true; + } + + if (GC.CollectionCount(0) > 0) + { + isGcInfoAvailable = true; + } + + return isGcInfoAvailable; + } + } + /// public void Dispose() { @@ -117,6 +136,11 @@ private static IEnumerable> GetGarbageCollectionCounts() #if NET6_0_OR_GREATER private static IEnumerable> GetFragmentationSizes() { + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; Measurement[] measurements = new Measurement[generationInfo.Length]; int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); @@ -128,10 +152,24 @@ private static IEnumerable> GetFragmentationSizes() return measurements; } + private static IEnumerable> GetGarbageCollectionCommittedBytes() + { + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + + return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; + } + private static IEnumerable> GetGarbageCollectionHeapSizes() { - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; Measurement[] measurements = new Measurement[generationInfo.Length]; int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); for (int i = 0; i < maxSupportedLength; ++i) From e2528920be9ead40f2fe9c0d4832b3a5ab25bf8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stef=C3=A1n=20J=C3=B6kull=20Sigur=C3=B0arson?= Date: Fri, 24 Jun 2022 04:12:55 +0000 Subject: [PATCH 0189/1499] Redis: Adding the ability to disable adding Events to Activities (#416) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 ++ .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 2 ++ .../CHANGELOG.md | 6 ++++++ .../RedisProfilerEntryToActivityConverter.cs | 9 ++++++--- .../StackExchangeRedisCallsInstrumentationOptions.cs | 5 +++++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt index ebca0c81e0..7d34433831 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt @@ -6,5 +6,7 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrume OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.set -> void OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.StackExchangeRedisCallsInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, StackExchange.Redis.IConnectionMultiplexer connection = null, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index ebca0c81e0..7d34433831 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,5 +6,7 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrume OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.set -> void OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.StackExchangeRedisCallsInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, StackExchange.Redis.IConnectionMultiplexer connection = null, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 6c2995f73f..f3a0adf69c 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Added the EnrichActivityWithTimingEvents option to + StackExchangeRedisCallsInstrumentationOptions to be able to disable adding + ActivityEvents (Enqueued, Sent, ResponseReceived) for Redis commands to + Activities since there is no way to clear these after they have been added. + This defaults to true to maintain current functionality. + ## 1.0.0-rc9.5 (source code moved to contrib repo) Released 2022-Jun-06 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 9fe12c6e56..2f553565fc 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -164,9 +164,12 @@ public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfi var send = enqueued.Add(command.EnqueuedToSending); var response = send.Add(command.SentToResponse); - activity.AddEvent(new ActivityEvent("Enqueued", enqueued)); - activity.AddEvent(new ActivityEvent("Sent", send)); - activity.AddEvent(new ActivityEvent("ResponseReceived", response)); + if (options.EnrichActivityWithTimingEvents) + { + activity.AddEvent(new ActivityEvent("Enqueued", enqueued)); + activity.AddEvent(new ActivityEvent("Sent", send)); + activity.AddEvent(new ActivityEvent("ResponseReceived", response)); + } options.Enrich?.Invoke(activity, command); } diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs index ee32c511f0..81b37b485d 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs @@ -44,5 +44,10 @@ public class StackExchangeRedisCallsInstrumentationOptions /// : the profiled redis command from which additional information can be extracted to enrich the activity. /// public Action Enrich { get; set; } + + /// + /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. + /// + public bool EnrichActivityWithTimingEvents { get; set; } = true; } } From 6e6690a9393c8e56973f81dd6be14dd6b403fec6 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 24 Jun 2022 16:45:19 -0700 Subject: [PATCH 0190/1499] Finalize GC instruments (#454) --- .../RuntimeMetrics.cs | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index cb433611b4..c0d7907160 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -51,18 +51,21 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsGcEnabled) { - // TODO: Almost all the ObservableGauge should be ObservableUpDownCounter (except for CPU utilization). - // Replace them once ObservableUpDownCounter is available. - this.meter.CreateObservableGauge($"{metricPrefix}gc.count", () => GetGarbageCollectionCounts(), description: "GC Count for all generations."); + this.meter.CreateObservableCounter($"{metricPrefix}gc.collections.count", () => GetGarbageCollectionCounts(), description: "Number of times garbage collection has occurred since process start."); #if NETCOREAPP3_1_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}gc.allocated.bytes", () => GC.GetTotalAllocatedBytes(), "By", "Allocation Rate."); + this.meter.CreateObservableCounter($"{metricPrefix}gc.allocations.size", () => GC.GetTotalAllocatedBytes(), unit: "By", description: "Count of the bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); #endif #if NET6_0_OR_GREATER - this.meter.CreateObservableGauge($"{metricPrefix}gc.committed", () => GetGarbageCollectionCommittedBytes(), "By", description: "GC Committed Bytes."); - this.meter.CreateObservableGauge($"{metricPrefix}gc.heapsize", () => GetGarbageCollectionHeapSizes(), "By", "Heap size for all generations."); - this.meter.CreateObservableGauge($"{metricPrefix}gc.fragmentation.size", GetFragmentationSizes, description: "GC fragmentation."); + // TODO: change to ObservableUpDownCounter + this.meter.CreateObservableGauge($"{metricPrefix}gc.committed_memory.size", () => GetGarbageCollectionCommittedBytes(), unit: "By", description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred."); + + // TODO: change to ObservableUpDownCounter + this.meter.CreateObservableGauge($"{metricPrefix}gc.heap.size", () => GetGarbageCollectionHeapSizes(), unit: "By", description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); + + // TODO: change to ObservableUpDownCounter + this.meter.CreateObservableGauge($"{metricPrefix}gc.heap.fragmentation.size", GetFragmentationSizes, unit: "By", description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); #endif } @@ -78,16 +81,26 @@ public RuntimeMetrics(RuntimeMetricsOptions options) #if NETCOREAPP3_1_OR_GREATER if (options.IsThreadingEnabled) { + // TODO: change to ObservableUpDownCounter this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count."); + + // TODO: change to ObservableUpDownCounter this.meter.CreateObservableGauge($"{metricPrefix}threadpool.thread.count", () => (long)ThreadPool.ThreadCount, description: "ThreadPool Thread Count."); + + // TODO: change to ObservableUpDownCounter this.meter.CreateObservableGauge($"{metricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count."); + + // TODO: change to ObservableUpDownCounter this.meter.CreateObservableGauge($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length."); + + // TODO: change to ObservableUpDownCounter this.meter.CreateObservableGauge($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers."); } #endif if (options.IsAssembliesEnabled) { + // TODO: change to ObservableUpDownCounter this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); } From 6c761b411eec4eb7868c291dc995f0e2bffa6f98 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 24 Jun 2022 17:50:08 -0700 Subject: [PATCH 0191/1499] adjust the semantic of gc count to make it exclusive (#457) --- .../RuntimeMetrics.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index c0d7907160..c94c7fe698 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -140,9 +140,15 @@ public void Dispose() private static IEnumerable> GetGarbageCollectionCounts() { - for (int i = 0; i < NumberOfGenerations; ++i) + long collectionsFromHigherGeneration = 0; + + for (int gen = NumberOfGenerations - 1; gen >= 0; --gen) { - yield return new(GC.CollectionCount(i), new KeyValuePair("gen", GenNames[i])); + long collectionsFromThisGeneration = GC.CollectionCount(gen); + + yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("gen", GenNames[gen])); + + collectionsFromHigherGeneration = collectionsFromThisGeneration; } } From cd35617a1883abc7bc56b3bbb254056730750b67 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 24 Jun 2022 18:03:10 -0700 Subject: [PATCH 0192/1499] Improve the runtime instrumentation naming and description (#455) --- .../RuntimeMetrics.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index c94c7fe698..fe08a26dd4 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -72,9 +72,9 @@ public RuntimeMetrics(RuntimeMetricsOptions options) #if NET6_0_OR_GREATER if (options.IsJitEnabled) { - this.meter.CreateObservableCounter($"{metricPrefix}il.bytes.jitted", () => System.Runtime.JitInfo.GetCompiledILBytes(), "By", description: "IL Bytes Jitted."); - this.meter.CreateObservableCounter($"{metricPrefix}methods.jitted.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "Number of Methods Jitted."); - this.meter.CreateObservableCounter($"{metricPrefix}time.in.jit", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, "ns", description: "Time spent in JIT."); + this.meter.CreateObservableCounter($"{metricPrefix}jit.il_compiled.size", () => System.Runtime.JitInfo.GetCompiledILBytes(), unit: "By", description: "Count of bytes of intermediate language that have been compiled since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); + this.meter.CreateObservableCounter($"{metricPrefix}jit.methods_compiled.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. The value will be zero under ahead-of-time (AOT) compilation mode."); + this.meter.CreateObservableCounter($"{metricPrefix}jit.compilation_time", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, unit: "ns", description: "The amount of time the JIT compiler has spent compiling methods since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); } #endif @@ -82,31 +82,31 @@ public RuntimeMetrics(RuntimeMetricsOptions options) if (options.IsThreadingEnabled) { // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock.contention.count", () => Monitor.LockContentionCount, description: "Monitor Lock Contention Count."); + this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock_contention.count", () => Monitor.LockContentionCount, description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()"); // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}threadpool.thread.count", () => (long)ThreadPool.ThreadCount, description: "ThreadPool Thread Count."); + this.meter.CreateObservableGauge($"{metricPrefix}thread_pool.threads.count", () => (long)ThreadPool.ThreadCount, description: "The number of thread pool threads that currently exist."); // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}threadpool.completed.items.count", () => ThreadPool.CompletedWorkItemCount, description: "ThreadPool Completed Work Item Count."); + this.meter.CreateObservableGauge($"{metricPrefix}thread_pool.completed_items.count", () => ThreadPool.CompletedWorkItemCount, description: "The number of work items that have been processed by the thread pool since the process start."); // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}threadpool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "ThreadPool Queue Length."); + this.meter.CreateObservableGauge($"{metricPrefix}thread_pool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "The number of work items that are currently queued to be processed by the thread pool."); // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}active.timer.count", () => Timer.ActiveCount, description: "Number of Active Timers."); + this.meter.CreateObservableGauge($"{metricPrefix}timer.count", () => Timer.ActiveCount, description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); } #endif if (options.IsAssembliesEnabled) { // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "Number of Assemblies Loaded."); + this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "The number of .NET assemblies that are currently loaded."); } if (options.IsExceptionCountEnabled) { - var exceptionCounter = this.meter.CreateCounter($"{metricPrefix}exception.count", description: "Number of exceptions thrown."); + var exceptionCounter = this.meter.CreateCounter($"{metricPrefix}exception.count", description: "Count of exceptions that have been thrown in managed code, since the observation started."); AppDomain.CurrentDomain.FirstChanceException += (source, e) => { exceptionCounter.Add(1); From cd1f5367067f4c65662578c1352fe47552109c11 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 24 Jun 2022 18:31:57 -0700 Subject: [PATCH 0193/1499] Release Runtime instrumentation version 1.0.0-beta.1 (#458) --- .../CHANGELOG.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index e6d2b4f7f1..3557ac6b8b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,13 +2,11 @@ ## Unreleased -* Update a few metrics to be in sync of doc updates for `gc.heap`, - `gc.fragmentation.ratio`, `time.in.jit`, `process.cpu.count` and `assembly.count` - ([#430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/430)) -* Remove Process related metrics from .NET Runtime metrics - ([#446](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/446)) -* Add `exception.count` in Runtime metrics - ([#431](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/431)) +## 1.0.0-beta.1 + +Major redesign of the runtime instrumentation. Renamed metrics to be more user-friendly +and better logical grouping. Removed the process related metrics which are not +.NET Runtime specific. ## 0.2.0-alpha.1 From a0f1286afff11b629521f7ba278af3b7f0e002be Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 24 Jun 2022 22:20:25 -0700 Subject: [PATCH 0194/1499] Cleanup few net461 targets (#459) * Cleanup few net461 targets * fix public api --- examples/owin/Examples.Owin.csproj | 4 ++-- .../ServiceProviderExtensions.cs | 4 ++-- .../.publicApi/{net461 => net462}/PublicAPI.Shipped.txt | 0 .../.publicApi/{net461 => net462}/PublicAPI.Unshipped.txt | 0 src/OpenTelemetry.Extensions/CHANGELOG.md | 2 ++ .../Internal/ActivityEventAttachingLogProcessor.cs | 2 +- .../Internal/DefaultLogStateConverter.cs | 2 +- .../Logs/LogToActivityEventConversionOptions.cs | 2 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 2 +- src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj | 4 ++-- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 4 ++-- 13 files changed, 17 insertions(+), 15 deletions(-) rename src/OpenTelemetry.Extensions/.publicApi/{net461 => net462}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Extensions/.publicApi/{net461 => net462}/PublicAPI.Unshipped.txt (100%) diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index cdbe837143..de45e39449 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -1,8 +1,8 @@ - + Exe - net461 + net462 diff --git a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs index 096eda95ac..9175001b9f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER using Microsoft.Extensions.Options; #endif @@ -34,7 +34,7 @@ internal static class ServiceProviderExtensions public static T GetOptions(this IServiceProvider serviceProvider) where T : class, new() { -#if NET461 || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); // Note: options could be null if user never invoked services.AddOptions(). diff --git a/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net461/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index acdf9bb081..fc12d03af0 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -4,6 +4,8 @@ * Implemented auto flush activity processor ([#297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/297)) +* Removes .NET Framework 4.6.1. The minimum .NET Framework version + supported is .NET 4.6.2. ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index 2db1c1e820..c0b559e907 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET461_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER using System; using System.Diagnostics; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index fc2687ef5c..fbd7b1080e 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET461_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index 93910b8a41..670083e543 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET461_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index ed9dd8748d..bc8fa1518b 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET461_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER using System; using System.Diagnostics; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index fd69c7b1e1..cf4f32e9e9 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -1,7 +1,7 @@ - + - net461;netstandard2.0 + net462;netstandard2.0 $(TargetFrameworks);net5.0 OpenTelemetry .NET SDK preview features and extensions Preview- diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index a9af51a2a2..b2b3918d5a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -3,7 +3,7 @@ Exe netcoreapp3.1;net5.0;net6.0 - $(TargetFrameworks);net461;net462;net47;net471;net472;net48 + $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index ab98c9d102..6823561c4b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -1,9 +1,9 @@ - + Exe netcoreapp3.1;net5.0;net6.0 - $(TargetFrameworks);net461;net462;net47;net471;net472;net48 + $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1308,SA1201 diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 63f479b1d3..d51bb93f8a 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,8 +1,8 @@ - netcoreapp3.1;net5.0;net6.0 - $(TargetFrameworks);net461 + netcoreapp3.1;net6.0 + $(TargetFrameworks);net462 From 27f3385070f02efc1513c599e811d9b80f8aa86e Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jun 2022 10:47:12 -0700 Subject: [PATCH 0195/1499] Refactor runtime instrumentation (#461) --- .../MeterProviderBuilderExtensions.cs | 2 +- .../RuntimeMetrics.cs | 248 ++++++++++-------- .../RuntimeMetricsOptions.cs | 122 ++++----- .../RuntimeMetricsOptionsTests.cs | 166 ++++++------ .../RuntimeMetricsTests.cs | 16 +- 5 files changed, 291 insertions(+), 263 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index a02f696fb5..cfefb6691c 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -41,7 +41,7 @@ public static MeterProviderBuilder AddRuntimeMetrics( configure?.Invoke(options); var instrumentation = new RuntimeMetrics(options); - builder.AddMeter(RuntimeMetrics.InstrumentationName); + builder.AddMeter(RuntimeMetrics.MeterInstance.Name); return builder.AddInstrumentation(() => instrumentation); } } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index fe08a26dd4..8d67ef7164 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -22,6 +22,10 @@ using System.Threading; #endif +#if NET6_0_OR_GREATER +using JitInfo = System.Runtime.JitInfo; +#endif + namespace OpenTelemetry.Instrumentation.Runtime { /// @@ -30,88 +34,168 @@ namespace OpenTelemetry.Instrumentation.Runtime internal class RuntimeMetrics : IDisposable { internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); - internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); + #if NET6_0_OR_GREATER private const long NanosecondsPerTick = 100; #endif + private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; private static readonly int NumberOfGenerations = 3; private static bool isGcInfoAvailable; private static string metricPrefix = "process.runtime.dotnet."; - private readonly Meter meter; - /// - /// Initializes a new instance of the class. - /// - /// The options to define the metrics. - public RuntimeMetrics(RuntimeMetricsOptions options) + static RuntimeMetrics() { - this.meter = new Meter(InstrumentationName, InstrumentationVersion); - - if (options.IsGcEnabled) - { - this.meter.CreateObservableCounter($"{metricPrefix}gc.collections.count", () => GetGarbageCollectionCounts(), description: "Number of times garbage collection has occurred since process start."); + MeterInstance.CreateObservableCounter( + $"{metricPrefix}gc.collections.count", + () => GetGarbageCollectionCounts(), + description: "Number of times garbage collection has occurred since process start."); #if NETCOREAPP3_1_OR_GREATER - this.meter.CreateObservableCounter($"{metricPrefix}gc.allocations.size", () => GC.GetTotalAllocatedBytes(), unit: "By", description: "Count of the bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); + MeterInstance.CreateObservableCounter( + $"{metricPrefix}gc.allocations.size", + () => GC.GetTotalAllocatedBytes(), + unit: "By", + description: "Count of the bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); #endif #if NET6_0_OR_GREATER - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}gc.committed_memory.size", () => GetGarbageCollectionCommittedBytes(), unit: "By", description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred."); - - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}gc.heap.size", () => GetGarbageCollectionHeapSizes(), unit: "By", description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); - - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}gc.heap.fragmentation.size", GetFragmentationSizes, unit: "By", description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}gc.committed_memory.size", + () => + { + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + + return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; + }, + unit: "By", + description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}gc.heap.size", + () => + { + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) + { + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("gen", GenNames[i])); + } + + return measurements; + }, + unit: "By", + description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}gc.heap.fragmentation.size", + () => + { + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) + { + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("gen", GenNames[i])); + } + + return measurements; + }, + unit: "By", + description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); #endif - } #if NET6_0_OR_GREATER - if (options.IsJitEnabled) - { - this.meter.CreateObservableCounter($"{metricPrefix}jit.il_compiled.size", () => System.Runtime.JitInfo.GetCompiledILBytes(), unit: "By", description: "Count of bytes of intermediate language that have been compiled since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); - this.meter.CreateObservableCounter($"{metricPrefix}jit.methods_compiled.count", () => System.Runtime.JitInfo.GetCompiledMethodCount(), description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. The value will be zero under ahead-of-time (AOT) compilation mode."); - this.meter.CreateObservableCounter($"{metricPrefix}jit.compilation_time", () => System.Runtime.JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, unit: "ns", description: "The amount of time the JIT compiler has spent compiling methods since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); - } + MeterInstance.CreateObservableCounter( + $"{metricPrefix}jit.il_compiled.size", + () => JitInfo.GetCompiledILBytes(), + unit: "By", + description: "Count of bytes of intermediate language that have been compiled since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); + + MeterInstance.CreateObservableCounter( + $"{metricPrefix}jit.methods_compiled.count", + () => JitInfo.GetCompiledMethodCount(), + description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. The value will be zero under ahead-of-time (AOT) compilation mode."); + + MeterInstance.CreateObservableCounter( + $"{metricPrefix}jit.compilation_time", + () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, + unit: "ns", + description: "The amount of time the JIT compiler has spent compiling methods since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); #endif #if NETCOREAPP3_1_OR_GREATER - if (options.IsThreadingEnabled) - { - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}monitor.lock_contention.count", () => Monitor.LockContentionCount, description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()"); - - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}thread_pool.threads.count", () => (long)ThreadPool.ThreadCount, description: "The number of thread pool threads that currently exist."); - - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}thread_pool.completed_items.count", () => ThreadPool.CompletedWorkItemCount, description: "The number of work items that have been processed by the thread pool since the process start."); + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}monitor.lock_contention.count", + () => Monitor.LockContentionCount, + description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()"); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}thread_pool.threads.count", + () => (long)ThreadPool.ThreadCount, + description: "The number of thread pool threads that currently exist."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}thread_pool.completed_items.count", + () => ThreadPool.CompletedWorkItemCount, + description: "The number of work items that have been processed by the thread pool since the process start."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}thread_pool.queue.length", + () => ThreadPool.PendingWorkItemCount, + description: "The number of work items that are currently queued to be processed by the thread pool."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}timer.count", + () => Timer.ActiveCount, + description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); +#endif - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}thread_pool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "The number of work items that are currently queued to be processed by the thread pool."); + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}assembly.count", + () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, + description: "The number of .NET assemblies that are currently loaded."); - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}timer.count", () => Timer.ActiveCount, description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); - } -#endif + var exceptionCounter = MeterInstance.CreateCounter( + $"{metricPrefix}exception.count", + description: "Count of exceptions that have been thrown in managed code, since the observation started."); - if (options.IsAssembliesEnabled) + AppDomain.CurrentDomain.FirstChanceException += (source, e) => { - // TODO: change to ObservableUpDownCounter - this.meter.CreateObservableGauge($"{metricPrefix}assembly.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "The number of .NET assemblies that are currently loaded."); - } + exceptionCounter.Add(1); + }; + } - if (options.IsExceptionCountEnabled) - { - var exceptionCounter = this.meter.CreateCounter($"{metricPrefix}exception.count", description: "Count of exceptions that have been thrown in managed code, since the observation started."); - AppDomain.CurrentDomain.FirstChanceException += (source, e) => - { - exceptionCounter.Add(1); - }; - } + /// + /// Initializes a new instance of the class. + /// + /// The options to define the metrics. + public RuntimeMetrics(RuntimeMetricsOptions options) + { } private static bool IsGcInfoAvailable @@ -135,7 +219,7 @@ private static bool IsGcInfoAvailable /// public void Dispose() { - this.meter?.Dispose(); + MeterInstance?.Dispose(); } private static IEnumerable> GetGarbageCollectionCounts() @@ -151,53 +235,5 @@ private static IEnumerable> GetGarbageCollectionCounts() collectionsFromHigherGeneration = collectionsFromThisGeneration; } } - -#if NET6_0_OR_GREATER - private static IEnumerable> GetFragmentationSizes() - { - if (!IsGcInfoAvailable) - { - return Array.Empty>(); - } - - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) - { - measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("gen", GenNames[i])); - } - - return measurements; - } - - private static IEnumerable> GetGarbageCollectionCommittedBytes() - { - if (!IsGcInfoAvailable) - { - return Array.Empty>(); - } - - return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; - } - - private static IEnumerable> GetGarbageCollectionHeapSizes() - { - if (!IsGcInfoAvailable) - { - return Array.Empty>(); - } - - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) - { - measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("gen", GenNames[i])); - } - - return measurements; - } -#endif } } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs index eb24d3a283..6212f76530 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs @@ -21,75 +21,77 @@ namespace OpenTelemetry.Instrumentation.Runtime /// public class RuntimeMetricsOptions { - /// - /// Gets or sets a value indicating whether garbage collection metrics should be collected. - /// - public bool? GcEnabled { get; set; } + /* + /// + /// Gets or sets a value indicating whether garbage collection metrics should be collected. + /// + public bool? GcEnabled { get; set; } -#if NET6_0_OR_GREATER - /// - /// Gets or sets a value indicating whether jitter metrics should be collected. - /// - public bool? JitEnabled { get; set; } -#endif + #if NET6_0_OR_GREATER + /// + /// Gets or sets a value indicating whether jitter metrics should be collected. + /// + public bool? JitEnabled { get; set; } + #endif -#if NETCOREAPP3_1_OR_GREATER - /// - /// Gets or sets a value indicating whether threading metrics should be collected. - /// - public bool? ThreadingEnabled { get; set; } -#endif + #if NETCOREAPP3_1_OR_GREATER + /// + /// Gets or sets a value indicating whether threading metrics should be collected. + /// + public bool? ThreadingEnabled { get; set; } + #endif - /// - /// Gets or sets a value indicating whether assembly metrics should be collected. - /// - public bool? AssembliesEnabled { get; set; } + /// + /// Gets or sets a value indicating whether assembly metrics should be collected. + /// + public bool? AssembliesEnabled { get; set; } - /// - /// Gets or sets a value indicating whether exception count metrics should be collected. - /// - public bool? ExceptionCountEnabled { get; set; } + /// + /// Gets or sets a value indicating whether exception count metrics should be collected. + /// + public bool? ExceptionCountEnabled { get; set; } - /// - /// Gets a value indicating whether all metrics are enabled. - /// - internal bool IsAllEnabled => this.GcEnabled == null -#if NET6_0_OR_GREATER - && this.JitEnabled == null -#endif -#if NETCOREAPP3_1_OR_GREATER - && this.ThreadingEnabled == null -#endif - && this.AssembliesEnabled == null - && this.ExceptionCountEnabled == null; + /// + /// Gets a value indicating whether all metrics are enabled. + /// + internal bool IsAllEnabled => this.GcEnabled == null + #if NET6_0_OR_GREATER + && this.JitEnabled == null + #endif + #if NETCOREAPP3_1_OR_GREATER + && this.ThreadingEnabled == null + #endif + && this.AssembliesEnabled == null + && this.ExceptionCountEnabled == null; - /// - /// Gets a value indicating whether garbage collection metrics is enabled. - /// - internal bool IsGcEnabled => this.GcEnabled == true || this.IsAllEnabled; + /// + /// Gets a value indicating whether garbage collection metrics is enabled. + /// + internal bool IsGcEnabled => this.GcEnabled == true || this.IsAllEnabled; -#if NET6_0_OR_GREATER - /// - /// Gets a value indicating whether jitter metrics is enabled. - /// - internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; -#endif + #if NET6_0_OR_GREATER + /// + /// Gets a value indicating whether jitter metrics is enabled. + /// + internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; + #endif -#if NETCOREAPP3_1_OR_GREATER - /// - /// Gets a value indicating whether threading metrics is enabled. - /// - internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; -#endif + #if NETCOREAPP3_1_OR_GREATER + /// + /// Gets a value indicating whether threading metrics is enabled. + /// + internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; + #endif - /// - /// Gets a value indicating whether assembly metrics is enabled. - /// - internal bool IsAssembliesEnabled => this.AssembliesEnabled == true || this.IsAllEnabled; + /// + /// Gets a value indicating whether assembly metrics is enabled. + /// + internal bool IsAssembliesEnabled => this.AssembliesEnabled == true || this.IsAllEnabled; - /// - /// Gets a value indicating whether exception count metrics is enabled. - /// - internal bool IsExceptionCountEnabled => this.ExceptionCountEnabled == true || this.IsAllEnabled; + /// + /// Gets a value indicating whether exception count metrics is enabled. + /// + internal bool IsExceptionCountEnabled => this.ExceptionCountEnabled == true || this.IsAllEnabled; + */ } } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs index 98484160cf..78100a3d28 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs @@ -20,98 +20,100 @@ namespace OpenTelemetry.Instrumentation.Runtime.Tests { public class RuntimeMetricsOptionsTests { - [Fact] - public void Enable_All_If_Nothing_Was_Defined() - { - var options = new RuntimeMetricsOptions(); + /* + [Fact] + public void Enable_All_If_Nothing_Was_Defined() + { + var options = new RuntimeMetricsOptions(); - Assert.True(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.True(options.IsJitEnabled); -#endif -#if NETCOREAPP3_1_OR_GREATER - Assert.True(options.IsThreadingEnabled); -#endif - Assert.True(options.IsAssembliesEnabled); - Assert.True(options.IsAllEnabled); - } + Assert.True(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.True(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.True(options.IsThreadingEnabled); + #endif + Assert.True(options.IsAssembliesEnabled); + Assert.True(options.IsAllEnabled); + } - [Fact] - public void Enable_Gc_Only() - { - var options = new RuntimeMetricsOptions { GcEnabled = true }; + [Fact] + public void Enable_Gc_Only() + { + var options = new RuntimeMetricsOptions { GcEnabled = true }; - Assert.True(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); -#endif -#if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); -#endif - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } + Assert.True(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); + #endif + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } -#if NET6_0_OR_GREATER - [Fact] - public void Enable_Jit_Only() - { - var options = new RuntimeMetricsOptions { JitEnabled = true }; + #if NET6_0_OR_GREATER + [Fact] + public void Enable_Jit_Only() + { + var options = new RuntimeMetricsOptions { JitEnabled = true }; - Assert.False(options.IsGcEnabled); - Assert.True(options.IsJitEnabled); - Assert.False(options.IsThreadingEnabled); - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } -#endif + Assert.False(options.IsGcEnabled); + Assert.True(options.IsJitEnabled); + Assert.False(options.IsThreadingEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + #endif -#if NETCOREAPP3_1_OR_GREATER - [Fact] - public void Enable_Threading_Only() - { - var options = new RuntimeMetricsOptions { ThreadingEnabled = true }; + #if NETCOREAPP3_1_OR_GREATER + [Fact] + public void Enable_Threading_Only() + { + var options = new RuntimeMetricsOptions { ThreadingEnabled = true }; - Assert.False(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); -#endif - Assert.True(options.IsThreadingEnabled); - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } -#endif + Assert.False(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + Assert.True(options.IsThreadingEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + #endif - [Fact] - public void Enable_Assemblies_Only() - { - var options = new RuntimeMetricsOptions { AssembliesEnabled = true }; + [Fact] + public void Enable_Assemblies_Only() + { + var options = new RuntimeMetricsOptions { AssembliesEnabled = true }; - Assert.False(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); -#endif -#if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); -#endif - Assert.True(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } + Assert.False(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); + #endif + Assert.True(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } - [Fact] - public void Enable_Multiple() - { - var options = new RuntimeMetricsOptions { GcEnabled = true, AssembliesEnabled = true }; + [Fact] + public void Enable_Multiple() + { + var options = new RuntimeMetricsOptions { GcEnabled = true, AssembliesEnabled = true }; - Assert.True(options.IsGcEnabled); -#if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); -#endif -#if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); -#endif - Assert.True(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } + Assert.True(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); + #endif + Assert.True(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + */ } } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 6ac583cd6b..0c38e4e473 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -30,25 +30,13 @@ public void RuntimeMetricsAreCaptured() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics(options => - { - options.GcEnabled = true; -#if NETCOREAPP3_1_OR_GREATER - options.ThreadingEnabled = true; -#endif -#if NET6_0_OR_GREATER - - options.JitEnabled = true; -#endif - options.AssembliesEnabled = true; - }) + .AddRuntimeMetrics() .AddInMemoryExporter(exportedItems) .Build(); meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.True(exportedItems.Count > 1); - var metric1 = exportedItems[0]; - Assert.StartsWith(MetricPrefix, metric1.Name); + Assert.StartsWith(MetricPrefix, exportedItems[0].Name); } } } From 2fd961a6d0e0c9ae742327dec4c69a9a1659e274 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jun 2022 11:11:24 -0700 Subject: [PATCH 0196/1499] refactor runtime instrumentation (#462) --- .../MeterProviderBuilderExtensions.cs | 4 ++-- ...icsOptions.cs => RuntimeInstrumentOptions.cs} | 4 ++-- .../RuntimeMetrics.cs | 10 ++-------- ...Tests.cs => RuntimeInstrumentOptionsTests.cs} | 16 ++++++++-------- 4 files changed, 14 insertions(+), 20 deletions(-) rename src/OpenTelemetry.Instrumentation.Runtime/{RuntimeMetricsOptions.cs => RuntimeInstrumentOptions.cs} (96%) rename test/OpenTelemetry.Instrumentation.Runtime.Tests/{RuntimeMetricsOptionsTests.cs => RuntimeInstrumentOptionsTests.cs} (84%) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index cfefb6691c..0eb659a992 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -33,11 +33,11 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddRuntimeMetrics( this MeterProviderBuilder builder, - Action configure = null) + Action configure = null) { Guard.ThrowIfNull(builder); - var options = new RuntimeMetricsOptions(); + var options = new RuntimeInstrumentOptions(); configure?.Invoke(options); var instrumentation = new RuntimeMetrics(options); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentOptions.cs similarity index 96% rename from src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs rename to src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentOptions.cs index 6212f76530..38455545f0 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,7 @@ namespace OpenTelemetry.Instrumentation.Runtime /// /// Options to define the runtime metrics. /// - public class RuntimeMetricsOptions + public class RuntimeInstrumentOptions { /* /// diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 8d67ef7164..505fb2f2f8 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -31,7 +31,7 @@ namespace OpenTelemetry.Instrumentation.Runtime /// /// .NET runtime instrumentation. /// - internal class RuntimeMetrics : IDisposable + internal class RuntimeMetrics { internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); @@ -194,7 +194,7 @@ static RuntimeMetrics() /// Initializes a new instance of the class. /// /// The options to define the metrics. - public RuntimeMetrics(RuntimeMetricsOptions options) + public RuntimeMetrics(RuntimeInstrumentOptions options) { } @@ -216,12 +216,6 @@ private static bool IsGcInfoAvailable } } - /// - public void Dispose() - { - MeterInstance?.Dispose(); - } - private static IEnumerable> GetGarbageCollectionCounts() { long collectionsFromHigherGeneration = 0; diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentOptionsTests.cs similarity index 84% rename from test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs rename to test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentOptionsTests.cs index 78100a3d28..1f83d3ef30 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentOptionsTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,13 +18,13 @@ namespace OpenTelemetry.Instrumentation.Runtime.Tests { - public class RuntimeMetricsOptionsTests + public class RuntimeInstrumentOptionsTests { /* [Fact] public void Enable_All_If_Nothing_Was_Defined() { - var options = new RuntimeMetricsOptions(); + var options = new RuntimeInstrumentOptions(); Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -40,7 +40,7 @@ public void Enable_All_If_Nothing_Was_Defined() [Fact] public void Enable_Gc_Only() { - var options = new RuntimeMetricsOptions { GcEnabled = true }; + var options = new RuntimeInstrumentOptions { GcEnabled = true }; Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -57,7 +57,7 @@ public void Enable_Gc_Only() [Fact] public void Enable_Jit_Only() { - var options = new RuntimeMetricsOptions { JitEnabled = true }; + var options = new RuntimeInstrumentOptions { JitEnabled = true }; Assert.False(options.IsGcEnabled); Assert.True(options.IsJitEnabled); @@ -71,7 +71,7 @@ public void Enable_Jit_Only() [Fact] public void Enable_Threading_Only() { - var options = new RuntimeMetricsOptions { ThreadingEnabled = true }; + var options = new RuntimeInstrumentOptions { ThreadingEnabled = true }; Assert.False(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -86,7 +86,7 @@ public void Enable_Threading_Only() [Fact] public void Enable_Assemblies_Only() { - var options = new RuntimeMetricsOptions { AssembliesEnabled = true }; + var options = new RuntimeInstrumentOptions { AssembliesEnabled = true }; Assert.False(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -102,7 +102,7 @@ public void Enable_Assemblies_Only() [Fact] public void Enable_Multiple() { - var options = new RuntimeMetricsOptions { GcEnabled = true, AssembliesEnabled = true }; + var options = new RuntimeInstrumentOptions { GcEnabled = true, AssembliesEnabled = true }; Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER From 69f98cb0ce78ac4619df5d6735a8848ad6cbde89 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jun 2022 11:36:02 -0700 Subject: [PATCH 0197/1499] update runtime instrumentation example (#463) --- examples/runtime-instrumentation/Program.cs | 14 +++++++++++++- .../RuntimeMetrics.cs | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index 7362fd2ee1..1abb96dbf8 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -30,7 +30,19 @@ public static void Main() }) .Build(); - // GC.Collect(0); + // Most of the process.runtime.dotnet.gc.* metrics are only available after the GC finished at least one collection. + GC.Collect(1); + + // The process.runtime.dotnet.exception.count metrics are only available after an exception has been thrown post OpenTelemetry.Instrumentation.Runtime initialization. + try + { + throw new Exception("Oops!"); + } + catch (Exception) + { + // swallow the exception + } + Console.WriteLine(".NET Runtime metrics are available at http://localhost:9464/metrics, press any key to exit..."); Console.ReadKey(false); } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 505fb2f2f8..30e1892205 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -182,7 +182,7 @@ static RuntimeMetrics() var exceptionCounter = MeterInstance.CreateCounter( $"{metricPrefix}exception.count", - description: "Count of exceptions that have been thrown in managed code, since the observation started."); + description: "Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization."); AppDomain.CurrentDomain.FirstChanceException += (source, e) => { From 92bbe8740c4bb4e2944c76c9b178e1a107212487 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 27 Jun 2022 13:50:02 -0700 Subject: [PATCH 0198/1499] fix workflow persistenstorage.extensions (#464) * fix workflow --- .../package-Extensions.PersistentStorage.Abstractions.yml | 2 +- .github/workflows/package-Extensions.PersistentStorage.yml | 2 +- .../OpenTelemetry.Extensions.PersistentStorage.csproj | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml index 82b0bf477b..93e14f8f57 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml @@ -33,7 +33,7 @@ jobs: run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions.PersistentStorage.Abstractions has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts uses: actions/upload-artifact@v3 diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index 8ba7e43c75..979f4f1675 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -36,7 +36,7 @@ jobs: run: dotnet test test/${{env.PROJECT}}.Tests - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions.PersistentStorage has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts uses: actions/upload-artifact@v3 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj index 37990a64fb..931b637b7a 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj @@ -3,6 +3,7 @@ netstandard2.0 $(TargetFrameworks);net462 + $(TargetFrameworks);net6.0 OpenTelemetry Persistent Storage Extensions.PersistentStorage- From aec4d531a327c968626e01b60d87d021b0b4075c Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jun 2022 14:45:14 -0700 Subject: [PATCH 0199/1499] clean up runtime instrumentation docs --- examples/runtime-instrumentation/Program.cs | 2 +- .../MeterProviderBuilderExtensions.cs | 2 +- .../README.md | 31 +++++-------------- .../RuntimeMetricsTests.cs | 2 +- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index 1abb96dbf8..b4bdd9fc56 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -22,7 +22,7 @@ public class Program public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() .AddPrometheusExporter(options => { options.StartHttpListener = true; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 0eb659a992..f207bb5bc6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -31,7 +31,7 @@ public static class MeterProviderBuilderExtensions /// being configured. /// Runtime metrics options. /// The instance of to chain the calls. - public static MeterProviderBuilder AddRuntimeMetrics( + public static MeterProviderBuilder AddRuntimeInstrumentation( this MeterProviderBuilder builder, Action configure = null) { diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index bc26b361a3..d401cf9d44 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -10,19 +10,19 @@ collect telemetry about runtime behavior. ## Steps to enable OpenTelemetry.Instrumentation.Runtime -### Step 1: Install Package +### Step 1: Install package Add a reference to the [`OpenTelemetry.Instrumentation.Runtime`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) -package. Also, add any other instrumentations & exporters you will need. +package. ```shell dotnet add package OpenTelemetry.Instrumentation.Runtime ``` -### Step 2: Enable Runtime Instrumentation at application startup +### Step 2: Enable runtime instrumentation -Runtime instrumentation must be enabled at application startup. This is +Runtime instrumentation should be enabled at application startup. This is typically done in the `ConfigureServices` of your `Startup` class. The example below enables this instrumentation by using an extension method on `IServiceCollection`. This extension method requires adding the package @@ -42,7 +42,7 @@ using OpenTelemetry.Metrics; public void ConfigureServices(IServiceCollection services) { services.AddOpenTelemetryMetrics((builder) => builder - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() .AddPrometheusExporter() ); } @@ -52,25 +52,12 @@ Or configure directly: ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() + .AddPrometheusExporter() .Build(); ``` -## Advanced configuration - -By default all available runtime metrics will be added. It's also possible to -specify only the required metrics: - -```csharp -using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics(options => options - { - options.GcEnabled = true; - options.ThreadingEnabled = true; - options.MemoryEnabled = true; - }) - .Build(); -``` +Refer to [Program.cs](../../examples/runtime-instrumentation/Program.cs) for a complete demo. ## Troubleshooting @@ -83,6 +70,4 @@ for instructions on seeing these internal logs. ## References -* [Introduction to ASP.NET - Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core) * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 0c38e4e473..6a9b73f107 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -30,7 +30,7 @@ public void RuntimeMetricsAreCaptured() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() .AddInMemoryExporter(exportedItems) .Build(); From 9fa0f79b7ec90999585c8cd501bfb9010c3c81dc Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jun 2022 15:04:37 -0700 Subject: [PATCH 0200/1499] Revert "clean up runtime instrumentation docs" (#465) This reverts commit aec4d531a327c968626e01b60d87d021b0b4075c. --- examples/runtime-instrumentation/Program.cs | 2 +- .../MeterProviderBuilderExtensions.cs | 2 +- .../README.md | 31 ++++++++++++++----- .../RuntimeMetricsTests.cs | 2 +- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index b4bdd9fc56..1abb96dbf8 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -22,7 +22,7 @@ public class Program public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() + .AddRuntimeMetrics() .AddPrometheusExporter(options => { options.StartHttpListener = true; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index f207bb5bc6..0eb659a992 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -31,7 +31,7 @@ public static class MeterProviderBuilderExtensions /// being configured. /// Runtime metrics options. /// The instance of to chain the calls. - public static MeterProviderBuilder AddRuntimeInstrumentation( + public static MeterProviderBuilder AddRuntimeMetrics( this MeterProviderBuilder builder, Action configure = null) { diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index d401cf9d44..bc26b361a3 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -10,19 +10,19 @@ collect telemetry about runtime behavior. ## Steps to enable OpenTelemetry.Instrumentation.Runtime -### Step 1: Install package +### Step 1: Install Package Add a reference to the [`OpenTelemetry.Instrumentation.Runtime`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) -package. +package. Also, add any other instrumentations & exporters you will need. ```shell dotnet add package OpenTelemetry.Instrumentation.Runtime ``` -### Step 2: Enable runtime instrumentation +### Step 2: Enable Runtime Instrumentation at application startup -Runtime instrumentation should be enabled at application startup. This is +Runtime instrumentation must be enabled at application startup. This is typically done in the `ConfigureServices` of your `Startup` class. The example below enables this instrumentation by using an extension method on `IServiceCollection`. This extension method requires adding the package @@ -42,7 +42,7 @@ using OpenTelemetry.Metrics; public void ConfigureServices(IServiceCollection services) { services.AddOpenTelemetryMetrics((builder) => builder - .AddRuntimeInstrumentation() + .AddRuntimeMetrics() .AddPrometheusExporter() ); } @@ -52,12 +52,25 @@ Or configure directly: ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() - .AddPrometheusExporter() + .AddRuntimeMetrics() .Build(); ``` -Refer to [Program.cs](../../examples/runtime-instrumentation/Program.cs) for a complete demo. +## Advanced configuration + +By default all available runtime metrics will be added. It's also possible to +specify only the required metrics: + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeMetrics(options => options + { + options.GcEnabled = true; + options.ThreadingEnabled = true; + options.MemoryEnabled = true; + }) + .Build(); +``` ## Troubleshooting @@ -70,4 +83,6 @@ for instructions on seeing these internal logs. ## References +* [Introduction to ASP.NET + Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core) * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 6a9b73f107..0c38e4e473 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -30,7 +30,7 @@ public void RuntimeMetricsAreCaptured() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() + .AddRuntimeMetrics() .AddInMemoryExporter(exportedItems) .Build(); From 73d733f393bed0869b1a6efcb30d7870d9a8baf1 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 27 Jun 2022 16:20:44 -0700 Subject: [PATCH 0201/1499] Clean up runtime instrumentation API/docs (#466) * clean up runtime instrumentation * rewrap --- examples/runtime-instrumentation/Program.cs | 2 +- .../MeterProviderBuilderExtensions.cs | 2 +- .../README.md | 32 ++++++------------- .../RuntimeMetricsTests.cs | 2 +- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index 1abb96dbf8..b4bdd9fc56 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -22,7 +22,7 @@ public class Program public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() .AddPrometheusExporter(options => { options.StartHttpListener = true; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 0eb659a992..f207bb5bc6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -31,7 +31,7 @@ public static class MeterProviderBuilderExtensions /// being configured. /// Runtime metrics options. /// The instance of to chain the calls. - public static MeterProviderBuilder AddRuntimeMetrics( + public static MeterProviderBuilder AddRuntimeInstrumentation( this MeterProviderBuilder builder, Action configure = null) { diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index bc26b361a3..6c14c887bc 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -10,19 +10,19 @@ collect telemetry about runtime behavior. ## Steps to enable OpenTelemetry.Instrumentation.Runtime -### Step 1: Install Package +### Step 1: Install package Add a reference to the [`OpenTelemetry.Instrumentation.Runtime`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) -package. Also, add any other instrumentations & exporters you will need. +package. ```shell dotnet add package OpenTelemetry.Instrumentation.Runtime ``` -### Step 2: Enable Runtime Instrumentation at application startup +### Step 2: Enable runtime instrumentation -Runtime instrumentation must be enabled at application startup. This is +Runtime instrumentation should be enabled at application startup. This is typically done in the `ConfigureServices` of your `Startup` class. The example below enables this instrumentation by using an extension method on `IServiceCollection`. This extension method requires adding the package @@ -42,7 +42,7 @@ using OpenTelemetry.Metrics; public void ConfigureServices(IServiceCollection services) { services.AddOpenTelemetryMetrics((builder) => builder - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() .AddPrometheusExporter() ); } @@ -52,25 +52,13 @@ Or configure directly: ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() + .AddPrometheusExporter() .Build(); ``` -## Advanced configuration - -By default all available runtime metrics will be added. It's also possible to -specify only the required metrics: - -```csharp -using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics(options => options - { - options.GcEnabled = true; - options.ThreadingEnabled = true; - options.MemoryEnabled = true; - }) - .Build(); -``` +Refer to [Program.cs](../../examples/runtime-instrumentation/Program.cs) for a +complete demo. ## Troubleshooting @@ -83,6 +71,4 @@ for instructions on seeing these internal logs. ## References -* [Introduction to ASP.NET - Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core) * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 0c38e4e473..6a9b73f107 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -30,7 +30,7 @@ public void RuntimeMetricsAreCaptured() { var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeMetrics() + .AddRuntimeInstrumentation() .AddInMemoryExporter(exportedItems) .Build(); From 00ac3601a6f85ed44840641a0d40c8f122732e79 Mon Sep 17 00:00:00 2001 From: chad122 Date: Tue, 28 Jun 2022 11:02:36 +0800 Subject: [PATCH 0202/1499] [Instrumentation.MySql] fix sql text incomplete (#424) * fix sql text incomplete --- .../CHANGELOG.md | 3 +++ .../MySqlDataInstrumentation.cs | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 789acbb35b..dca310dd3b 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix incomplete db.statement when the length>300 + [(#424)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/424) + ## 1.0.0-beta.2 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index 1c138173e4..ca7b2f1797 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -84,6 +84,9 @@ public override void TraceEvent(TraceEventCache eventCache, string source, Trace this.ErrorExecuteCommand(this.GetMySqlErrorException(args[2])); break; case MySqlTraceEventType.QueryNormalized: + // Should use QueryNormalized event when it exists. Because cmdText in QueryOpened event is incomplete when cmdText.length>300 + // args: [driverId, threadId, normalized_query] + this.OverwriteDbStatement(this.GetCommand(args[0], args[2])); break; default: MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(id, string.Format(format, args)); @@ -125,6 +128,28 @@ private void BeforeExecuteCommand(MySqlDataTraceCommand command) } } + private void OverwriteDbStatement(MySqlDataTraceCommand command) + { + var activity = Activity.Current; + if (activity == null) + { + return; + } + + if (activity.Source != MySqlActivitySourceHelper.ActivitySource) + { + return; + } + + if (activity.IsAllDataRequested) + { + if (this.options.SetDbStatement) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); + } + } + } + private void AfterExecuteCommand() { var activity = Activity.Current; From d12e2dbe6e741a3b7d267b13ac7d3956feb480c5 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 28 Jun 2022 16:01:27 -0700 Subject: [PATCH 0203/1499] Add stale workflow to the solution file (#469) --- opentelemetry-dotnet-contrib.sln | 1 + .../CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 537a8ee4bd..b1fcde4044 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -54,6 +54,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml + .github\workflows\stale.yml = .github\workflows\stale.yml .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml EndProjectSection EndProject diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md index a26937528c..d200eebf1c 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## ## 1.0.0-alpha.4 +## 1.0.0-alpha.4 This is the first release for the `OpenTelemetry.Extensions.PersistentStorage.Abstractions` project. From 270c33dc43a2ba9bb31dac08e97a52cdb6297c2c Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 29 Jun 2022 14:29:37 -0700 Subject: [PATCH 0204/1499] Use `bytes` instead of `By` in runtime instruments (#468) Co-authored-by: Cijo Thomas --- .../RuntimeMetrics.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 30e1892205..5fd7b42ccf 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -56,7 +56,7 @@ static RuntimeMetrics() MeterInstance.CreateObservableCounter( $"{metricPrefix}gc.allocations.size", () => GC.GetTotalAllocatedBytes(), - unit: "By", + unit: "bytes", description: "Count of the bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); #endif @@ -73,7 +73,7 @@ static RuntimeMetrics() return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; }, - unit: "By", + unit: "bytes", description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred."); // TODO: change to ObservableUpDownCounter @@ -96,7 +96,7 @@ static RuntimeMetrics() return measurements; }, - unit: "By", + unit: "bytes", description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); // TODO: change to ObservableUpDownCounter @@ -119,7 +119,7 @@ static RuntimeMetrics() return measurements; }, - unit: "By", + unit: "bytes", description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); #endif @@ -127,7 +127,7 @@ static RuntimeMetrics() MeterInstance.CreateObservableCounter( $"{metricPrefix}jit.il_compiled.size", () => JitInfo.GetCompiledILBytes(), - unit: "By", + unit: "bytes", description: "Count of bytes of intermediate language that have been compiled since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); MeterInstance.CreateObservableCounter( From be7f840eabca52a75cd4eb2362922e0c672d13d0 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 29 Jun 2022 14:51:30 -0700 Subject: [PATCH 0205/1499] Update the contributing doc to mention about adding date to CHANGELOG (#473) * Update the contributing doc to mention about adding date to CHANGELOG --- CONTRIBUTING.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f47506eb8d..e182294952 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -137,8 +137,11 @@ and the new feature doesn't fit it. ### How to request for release of package -Submit a PR with `CHANGELOG.md` file reflecting the version to be released. -Also, tag the maintainers of this repository who can release the package. +* Submit a PR with `CHANGELOG.md` file reflecting the version to be released +along with the date in the following format `[yyyy-MMM-dd`]`. For example: +"1.2.0-beta.2 [2022-May-15]". +* Tag the maintainers of this repository +(@open-telemetry/dotnet-contrib-maintainers) who can release the package. ## Style Guide From 023f6b2fde541b9db35689c201e468d7c7f2f28e Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 29 Jun 2022 18:00:32 -0700 Subject: [PATCH 0206/1499] Update instrument type for `monitor.lock_contention.count` and `thread_pool.completed_items.count` (#476) --- src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 5fd7b42ccf..7ba0064722 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -143,8 +143,7 @@ static RuntimeMetrics() #endif #if NETCOREAPP3_1_OR_GREATER - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableCounter( $"{metricPrefix}monitor.lock_contention.count", () => Monitor.LockContentionCount, description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()"); @@ -155,8 +154,7 @@ static RuntimeMetrics() () => (long)ThreadPool.ThreadCount, description: "The number of thread pool threads that currently exist."); - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableCounter( $"{metricPrefix}thread_pool.completed_items.count", () => ThreadPool.CompletedWorkItemCount, description: "The number of work items that have been processed by the thread pool since the process start."); From df02e6368eaeea94005c41f53db8369de20c314f Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 29 Jun 2022 19:18:21 -0700 Subject: [PATCH 0207/1499] Release Runtime instrumentation version 1.0.0-rc.1 (#477) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 3557ac6b8b..150e5ce4aa 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 1.0.0-rc.1 + +Major refactor of the runtime instrumentation. Renamed API signature and metrics. +Removed the options to turn off certain metrics. + ## 1.0.0-beta.1 Major redesign of the runtime instrumentation. Renamed metrics to be more user-friendly From 3404084a714f802fe0b1fbcba52033bde7f66a47 Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Wed, 29 Jun 2022 21:26:50 -0500 Subject: [PATCH 0208/1499] Release StackExchangeRedis 1.0.0-rc9.6 (#472) * Release StackExchangeRedis 1.0.0-rc9.6 --- .../CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index f3a0adf69c..dc45bd3b30 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog -## Unreleased +## 1.0.0-rc9.6 + +Released 2022-Jun-29 * Added the EnrichActivityWithTimingEvents option to StackExchangeRedisCallsInstrumentationOptions to be able to disable adding From 0edc79f847da4218eb2e4fe4c30826111240a091 Mon Sep 17 00:00:00 2001 From: chad122 Date: Thu, 30 Jun 2022 10:32:20 +0800 Subject: [PATCH 0209/1499] update CHANGELOG.md (#470) --- src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index dca310dd3b..69cd226ae4 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 1.0.0-beta.3 + * Fix incomplete db.statement when the length>300 [(#424)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/424) From c55fd8d963241a8bd5d94567dbb2f9773e8d1f6c Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Thu, 30 Jun 2022 07:14:17 +0200 Subject: [PATCH 0210/1499] Add db.system attribute to the AWS SDK instrumentation. (#418) * Added db.system attribute to the AWS SDK instrumentation (#415) * Aligned code formatting (#415) * - set dynamo db related tag in appropriate method (#415) Co-authored-by: Cijo Thomas Co-authored-by: Prashant Srivastava <50466688+srprash@users.noreply.github.com> --- .../Implementation/AWSSemanticConventions.cs | 2 + .../Implementation/AWSServiceHelper.cs | 54 +++++++++++++++++++ .../AWSTracingPipelineHandler.cs | 45 ++++------------ ...lemetry.Contrib.Instrumentation.AWS.csproj | 3 +- .../TestAWSClientInstrumentation.cs | 1 + 5 files changed, 70 insertions(+), 35 deletions(-) create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index 26665d3458..43090d2c85 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -28,5 +28,7 @@ internal static class AWSSemanticConventions public const string AttributeHttpStatusCode = "http.status_code"; public const string AttributeHttpResponseContentLength = "http.response_content_length"; + + public const string AttributeValueDynamoDb = "dynamodb"; } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs new file mode 100644 index 0000000000..d884b21003 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -0,0 +1,54 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using Amazon.Runtime; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +{ + internal class AWSServiceHelper + { + internal static IReadOnlyDictionary ServiceParameterMap = new Dictionary() + { + { DynamoDbService, "TableName" }, + { SQSService, "QueueUrl" }, + }; + + internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() + { + { "TableName", AWSSemanticConventions.AttributeAWSDynamoTableName }, + { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, + }; + + private const string DynamoDbService = "DynamoDBv2"; + private const string SQSService = "SQS"; + + internal static string GetAWSServiceName(IRequestContext requestContext) + => Utils.RemoveAmazonPrefixFromServiceName(requestContext.Request.ServiceName); + + internal static string GetAWSOperationName(IRequestContext requestContext) + { + string completeRequestName = requestContext.OriginalRequest.GetType().Name; + string suffix = "Request"; + var operationName = Utils.RemoveSuffix(completeRequestName, suffix); + return operationName; + } + + internal static bool IsDynamoDbService(string service) + => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index f7b5862186..e731aabff4 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -37,18 +37,6 @@ internal class AWSTracingPipelineHandler : PipelineHandler carrier[name] = value; }; - private static readonly Dictionary ServiceParameterMap = new Dictionary() - { - { "DynamoDBv2", "TableName" }, - { "SQS", "QueueUrl" }, - }; - - private static readonly Dictionary ParameterAttributeMap = new Dictionary() - { - { "TableName", AWSSemanticConventions.AttributeAWSDynamoTableName }, - { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, - }; - private static readonly ActivitySource AWSSDKActivitySource = new ActivitySource(ActivitySourceName); private readonly AWSClientInstrumentationOptions options; @@ -117,8 +105,8 @@ private Activity ProcessBeginRequest(IExecutionContext executionContext) Activity activity = null; var requestContext = executionContext.RequestContext; - var service = this.GetAWSServiceName(requestContext); - var operation = this.GetAWSOperationName(requestContext); + var service = AWSServiceHelper.GetAWSServiceName(requestContext); + var operation = AWSServiceHelper.GetAWSOperationName(requestContext); activity = AWSSDKActivitySource.StartActivity(service + "." + operation, ActivityKind.Client); @@ -192,37 +180,26 @@ private void ProcessException(Activity activity, Exception ex) } } - private string GetAWSServiceName(IRequestContext requestContext) - { - string serviceName = string.Empty; - serviceName = Utils.RemoveAmazonPrefixFromServiceName(requestContext.Request.ServiceName); - return serviceName; - } - - private string GetAWSOperationName(IRequestContext requestContext) - { - string operationName = string.Empty; - string completeRequestName = requestContext.OriginalRequest.GetType().Name; - string suffix = "Request"; - operationName = Utils.RemoveSuffix(completeRequestName, suffix); - return operationName; - } - private void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) { - AmazonWebServiceRequest request = requestContext.OriginalRequest; - - if (ServiceParameterMap.TryGetValue(service, out string parameter)) + if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out string parameter)) { + AmazonWebServiceRequest request = requestContext.OriginalRequest; + var property = request.GetType().GetProperty(parameter); if (property != null) { - if (ParameterAttributeMap.TryGetValue(parameter, out string attribute)) + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out string attribute)) { activity.SetTag(attribute, property.GetValue(request)); } } } + + if (AWSServiceHelper.IsDynamoDbService(service)) + { + activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); + } } private void AddStatusCodeToActivity(Activity activity, int status_code) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 45d4e245b8..01adf3f3f5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -1,4 +1,4 @@ - + net452;netstandard2.0 @@ -13,5 +13,6 @@ + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index e4ec96ee6b..b17a0567aa 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -179,6 +179,7 @@ private void ValidateDynamoActivityTags(Activity ddb_activity) Assert.Equal("Scan", Utils.GetTagValue(ddb_activity, "aws.operation")); Assert.Equal("us-east-1", Utils.GetTagValue(ddb_activity, "aws.region")); Assert.Equal("SampleProduct", Utils.GetTagValue(ddb_activity, "aws.table_name")); + Assert.Equal("dynamodb", Utils.GetTagValue(ddb_activity, "db.system")); } private void ValidateSqsActivityTags(Activity sqs_activity) From dafb2ef6d73eddbeb8e9601ca76f405b1449319d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 30 Jun 2022 14:13:33 -0700 Subject: [PATCH 0211/1499] Update CHANGELOG files to use a consistent date format (#479) --- CONTRIBUTING.md | 12 +++++++++-- .../CHANGELOG.md | 12 ++++++++--- .../CHANGELOG.md | 4 +++- .../CHANGELOG.md | 4 +++- .../CHANGELOG.md | 20 ++++++++++++++----- .../CHANGELOG.md | 12 ++++++++--- .../CHANGELOG.md | 2 ++ .../CHANGELOG.md | 2 ++ 8 files changed, 53 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e182294952..0a1e590110 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -138,8 +138,16 @@ and the new feature doesn't fit it. ### How to request for release of package * Submit a PR with `CHANGELOG.md` file reflecting the version to be released -along with the date in the following format `[yyyy-MMM-dd`]`. For example: -"1.2.0-beta.2 [2022-May-15]". +along with the date in the following format `yyyy-MMM-dd`. + +For example: + +```text +## 1.2.0-beta.2 + +Released 2022-Jun-21 +``` + * Tag the maintainers of this repository (@open-telemetry/dotnet-contrib-maintainers) who can release the package. diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index 67369c91e6..57cbf9f241 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -6,7 +6,9 @@ instance instead of recreating with ThreadLocal ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) -## 1.2.0 [2022-May-18] +## 1.2.0 + +Released 2022-May-18 * Enhancement - AWSEKSResourceDetector - Validate ClusterName/ContainerID independently before adding it to the resource @@ -15,13 +17,17 @@ "The SSL connection could not be established" ([#208](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/208)) -## 1.1.0 [2021-Sept-20] +## 1.1.0 + +Released 2021-Sept-20 * Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) * Updated OTel SDK package version to 1.1.0 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) -## 1.0.1 [2021-Feb-24] +## 1.0.1 + +Released 2021-Feb-24 This is the first release for the `OpenTelemetry.Contrib.Extensions.AWSXRay` project. The project targets v1.0.1 of the [OpenTelemetry diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md index ea1991daf8..0e903ec307 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog - OpenTelemetry.Contrib.Instrumentation.AWS -## 1.0.1 [2021-Feb-24] +## 1.0.1 + +Released 2021-Feb-24 This is the first release for the `OpenTelemetry.Contrib.Instrumentation.AWS` project. The release targets v1.0.1 of the diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md index df08983d54..8928f2bfc5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog - OpenTelemetry.Contrib.Instrumentation.AWSLambda -## 1.1.0-beta1 [2021-May-26] +## 1.1.0-beta1 + +Released 2021-May-26 This is the first release for the `OpenTelemetry.Contrib.Instrumentation.AWSLambda` project. The project targets v1.1.0-beta1 of the [OpenTelemetry diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 6a6d7e957e..66bf8e7480 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -20,12 +20,16 @@ by throwing any exception caught by `UnixDomainSocketDataTransport.Send` so that `ExportResult.Failure`. [444](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/444) -## 1.3.0-beta.2 [2022-Jun-03] +## 1.3.0-beta.2 + +Released 2022-Jun-03 * Add support for exporting `ILogger` scopes. [390](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/390) -## 1.3.0-beta.1 [2022-May-27] +## 1.3.0-beta.1 + +Released 2022-May-27 * Enable PassThru TableNameMappings using the logger category name. [345](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/345) @@ -44,12 +48,16 @@ by throwing any exception caught by `UnixDomainSocketDataTransport.Send` so that `LogRecord.Exception.GetType().FullName`. [375](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/375) -## 1.2.6 [2022-Apr-21] +## 1.2.6 + +Released 2022-Apr-21 * Set GenevaMetricExporter temporality preference back to Delta. [323](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/323) -## 1.2.5 [2022-Apr-20] Broken +## 1.2.5 Broken + +Released 2022-Apr-20 Note: This release was broken due to the GenevaMetricExporter using a TemporalityPreference of Cumulative instead of Delta, it has been unlisted from @@ -60,7 +68,9 @@ is the PR that introduced this bug to GenevaMetricExporterExtensions.cs * Update OTel SDK version to `1.2.0`. [319](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/319) -## 1.2.4 [2022-Apr-20] Broken +## 1.2.4 Broken + +Released 2022-Apr-20 This is the first release of the `OpenTelemetry.Exporter.Geneva` project. Note: This release was broken due to using OpenTelemetry 1.2.0-rc5. Therefore, it has diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 78dcba1e6c..4bb688b84f 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,17 +2,23 @@ ## Unreleased -## 1.0.2 [2022-Jun-02] +## 1.0.2 + +Released 2022-Jun-02 * Application is chrashing if environment variables are not defined [385](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/385) -## 1.0.1 [2022-May-25] +## 1.0.1 + +Released 2022-May-25 * Instana span duration was not calculated correctly [376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/376) -## 1.0.0 [2022-May-24] +## 1.0.0 + +Released 2022-May-24 * This is the first release of the `OpenTelemetry.Exporter.Instana` project. diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 69cd226ae4..4d88e85de9 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -4,6 +4,8 @@ ## 1.0.0-beta.3 +Released 2022-Jun-29 + * Fix incomplete db.statement when the length>300 [(#424)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/424) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 150e5ce4aa..6d326578d0 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -4,6 +4,8 @@ ## 1.0.0-rc.1 +Released 2022-Jun-29 + Major refactor of the runtime instrumentation. Renamed API signature and metrics. Removed the options to turn off certain metrics. From 5722bba06961a7069ee59583b0ced2e56a2164c2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 30 Jun 2022 14:59:40 -0700 Subject: [PATCH 0212/1499] Minor edit (#481) --- src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index 57cbf9f241..b3ffec18f8 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -19,7 +19,7 @@ Released 2022-May-18 ## 1.1.0 -Released 2021-Sept-20 +Released 2021-Sep-20 * Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) * Updated OTel SDK package version to 1.1.0 From 73a09901743396cb8644e48d6c7d49f5e8652665 Mon Sep 17 00:00:00 2001 From: yan xu <58940428+xyq175com@users.noreply.github.com> Date: Wed, 6 Jul 2022 10:55:47 +0800 Subject: [PATCH 0213/1499] Fix issue -propagation type is not case insensitive (#483) * Fix issue- #3149 --- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 3 +++ .../ServerTracingInterceptor.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index bf949234b4..7b162124b5 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Make the context propagation extraction case insensitive. + ([#483](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/483)) + ## 1.0.0-beta.5 * Switched Grpc.Core package dependency to Grpc.Core.Api in the same range. diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index fbb26fb96e..5dd4633306 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -166,7 +166,7 @@ private class ServerRpcScope : RpcScope Date: Tue, 5 Jul 2022 22:37:09 -0700 Subject: [PATCH 0214/1499] [Instrumentation.StackExchangeRedis] Update ActivitySource name (#485) --- examples/redis/Examples.StackExchangeRedis/README.md | 4 ++-- .../CHANGELOG.md | 5 +++++ .../StackExchangeRedisCallsInstrumentation.cs | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/redis/Examples.StackExchangeRedis/README.md b/examples/redis/Examples.StackExchangeRedis/README.md index dcc81d8007..ced8f7944b 100644 --- a/examples/redis/Examples.StackExchangeRedis/README.md +++ b/examples/redis/Examples.StackExchangeRedis/README.md @@ -10,7 +10,7 @@ this application (please look at the prerequisite for running the application in Activity.TraceId: f1a47baec558ebb97e57a6fb7d029a29 Activity.SpanId: d0abf2503ad3d1b6 Activity.TraceFlags: Recorded -Activity.ActivitySourceName: OpenTelemetry.StackExchange.Redis +Activity.ActivitySourceName: OpenTelemetry.Instrumentation.StackExchangeRedis Activity.DisplayName: SET Activity.Kind: Client Activity.StartTime: 2022-06-06T22:17:40.8927802Z @@ -33,7 +33,7 @@ Resource associated with Activity: Activity.TraceId: 0db37d796826693e23b17e3b082356a4 Activity.SpanId: cd01d518b8b5cfa2 Activity.TraceFlags: Recorded -Activity.ActivitySourceName: OpenTelemetry.StackExchange.Redis +Activity.ActivitySourceName: OpenTelemetry.Instrumentation.StackExchangeRedis Activity.DisplayName: GET Activity.Kind: Client Activity.StartTime: 2022-06-06T22:17:41.9223474Z diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index dc45bd3b30..756e4c9b70 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +* Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.StackExchangeRedis` +[#485](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/485) + ## 1.0.0-rc9.6 Released 2022-Jun-29 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs index 6c5a1ed1ae..dbc3b2efb9 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs @@ -34,8 +34,8 @@ internal class StackExchangeRedisCallsInstrumentation : IDisposable { internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; internal const string RedisFlagsKeyName = "db.redis.flags"; - internal const string ActivitySourceName = "OpenTelemetry.StackExchange.Redis"; - internal const string ActivityName = ActivitySourceName + ".Execute"; + internal static readonly string ActivitySourceName = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Name; + internal static readonly string ActivityName = ActivitySourceName + ".Execute"; internal static readonly Version Version = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Version; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); internal static readonly IEnumerable> CreationTags = new[] From d6d951c226dd5c32b080c689df08ca79b788c1d2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 6 Jul 2022 06:53:11 -0700 Subject: [PATCH 0215/1499] [Instrumentation.EntityFrameworkCore] Update EntityFrameworkCore ActivitySource name (#486) --- .../CHANGELOG.md | 4 ++++ .../Implementation/EntityFrameworkDiagnosticListener.cs | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 5c3885663a..27c99f63fb 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -5,6 +5,10 @@ * Updated OTel SDK package version to 1.2.0 [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) +* Update the `ActivitySource` name used to the assembly name: +`OpenTelemetry.Instrumentation.StackExchangeRedis` + [#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486) + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 44631fbd66..24968879b4 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -25,9 +25,6 @@ internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler { internal const string DiagnosticSourceName = "Microsoft.EntityFrameworkCore"; - internal const string ActivitySourceName = "OpenTelemetry.EntityFrameworkCore"; - internal const string ActivityName = ActivitySourceName + ".Execute"; - internal const string EntityFrameworkCoreCommandCreated = "Microsoft.EntityFrameworkCore.Database.Command.CommandCreated"; internal const string EntityFrameworkCoreCommandExecuting = "Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting"; internal const string EntityFrameworkCoreCommandExecuted = "Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted"; @@ -38,6 +35,9 @@ internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler internal const string AttributeDbName = "db.name"; internal const string AttributeDbStatement = "db.statement"; + internal static readonly string ActivitySourceName = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Name; + internal static readonly string ActivityName = ActivitySourceName + ".Execute"; + private static readonly Version Version = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Version; #pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before SqlClientActivitySource otherwise null ref exception is thrown. internal static readonly ActivitySource SqlClientActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); From 64a61b828173e89a4f794380ccce06e7eb39df46 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 6 Jul 2022 18:39:38 -0700 Subject: [PATCH 0216/1499] Exporter-Geneva - Refactor benchmarks for logging (#487) --- .../Exporter/Food.cs | 30 ++++ .../Exporter/LogExporterBenchmarks.cs | 166 +++++++----------- ...Telemetry.Exporter.Geneva.Benchmark.csproj | 2 +- 3 files changed, 91 insertions(+), 107 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs new file mode 100644 index 0000000000..8ce08e7269 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs @@ -0,0 +1,30 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Microsoft.Extensions.Logging; + +namespace OpenTelemetry.Exporter.Geneva.Benchmark +{ + public static partial class Food + { + [LoggerMessage( + EventId = 0, + Level = LogLevel.Information, + Message = "Hello from {food} {price}.")] + public static partial void SayHello( + ILogger logger, string food, double price); + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 42fa52b2b2..9cfa7dc146 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -21,22 +21,19 @@ using OpenTelemetry.Logs; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1415 (21H2) -AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores -.NET SDK=6.0.101 - [Host] : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT - DefaultJob : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT - - -``` -| Method | Mean | Error | StdDev | Gen 0 | Allocated | -|------------------------- |------------:|---------:|---------:|-------:|----------:| -| NoListener | 58.41 ns | 0.360 ns | 0.337 ns | 0.0076 | 64 B | -| OneProcessor | 189.79 ns | 0.391 ns | 0.347 ns | 0.0277 | 232 B | -| TwoProcessors | 195.50 ns | 0.438 ns | 0.388 ns | 0.0277 | 232 B | -| ThreeProcessors | 198.98 ns | 0.500 ns | 0.468 ns | 0.0277 | 232 B | -| LoggerWithGenevaExporter | 1,101.36 ns | 4.134 ns | 3.452 ns | 0.0305 | 256 B | -| SerializeLogRecord | 743.53 ns | 2.233 ns | 2.088 ns | 0.0029 | 24 B | +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1766 (21H2) +Intel Core i7-4790 CPU 3.60GHz (Haswell), 1 CPU, 8 logical and 4 physical cores +.NET SDK=6.0.301 + [Host] : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT + DefaultJob : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT + + +| Method | Mean | Error | StdDev | Median | Gen 0 | Allocated | +|-------------------------- |-----------:|---------:|---------:|-----------:|-------:|----------:| +| LoggerWithMessageTemplate | 1,219.6 ns | 24.41 ns | 64.30 ns | 1,200.5 ns | 0.0858 | 360 B | +| LoggerWithDirectLoggerAPI | 1,043.6 ns | 19.02 ns | 17.79 ns | 1,050.5 ns | 0.0954 | 400 B | +| LoggerWithSourceGenerator | 1,138.1 ns | 22.62 ns | 28.60 ns | 1,134.1 ns | 0.0763 | 320 B | +| SerializeLogRecord | 845.5 ns | 10.18 ns | 9.52 ns | 845.5 ns | 0.0305 | 128 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark @@ -44,18 +41,33 @@ namespace OpenTelemetry.Exporter.Geneva.Benchmark [MemoryDiagnoser] public class LogExporterBenchmarks { - private readonly LogRecord logRecord; + private readonly ILogger logger; + private readonly ILoggerFactory loggerFactory; private readonly GenevaLogExporter exporter; - private readonly ILogger loggerWithNoListener; - private readonly ILogger loggerWithGenevaExporter; - private readonly ILogger loggerWithOneProcessor; - private readonly ILogger loggerWithTwoProcessors; - private readonly ILogger loggerWithThreeProcessors; + private readonly LogRecord logRecord; public LogExporterBenchmarks() { - this.logRecord = this.GenerateTestLogRecord(); - + // for total cost of logging + msgpack serialization + this.loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddGenevaLogExporter(exporterOptions => + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + exporterOptions.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + })); + + this.logger = this.loggerFactory.CreateLogger("TestLogger"); + + // For msgpack serialization alone + this.logRecord = GenerateTestLogRecord(); this.exporter = new GenevaLogExporter(new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", @@ -66,64 +78,33 @@ public LogExporterBenchmarks() ["cloud.roleVer"] = "9.0.15289.2", }, }); - - this.loggerWithNoListener = this.CreateLogger(); - - this.loggerWithOneProcessor = this.CreateLogger(options => options - .AddProcessor(new DummyLogProcessor())); - - this.loggerWithTwoProcessors = this.CreateLogger(options => options - .AddProcessor(new DummyLogProcessor()) - .AddProcessor(new DummyLogProcessor())); - - this.loggerWithThreeProcessors = this.CreateLogger(options => options - .AddProcessor(new DummyLogProcessor()) - .AddProcessor(new DummyLogProcessor()) - .AddProcessor(new DummyLogProcessor())); - - this.loggerWithGenevaExporter = this.CreateLogger(options => - { - options.AddGenevaLogExporter(genevaOptions => - { - genevaOptions.ConnectionString = "EtwSession=OpenTelemetry"; - genevaOptions.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }); - }); - } - - [Benchmark] - public void NoListener() - { - this.loggerWithNoListener.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); } [Benchmark] - public void OneProcessor() + public void LoggerWithMessageTemplate() { - this.loggerWithOneProcessor.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + this.logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); } [Benchmark] - public void TwoProcessors() + public void LoggerWithDirectLoggerAPI() { - this.loggerWithTwoProcessors.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - } - - [Benchmark] - public void ThreeProcessors() - { - this.loggerWithThreeProcessors.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + this.logger.Log( + logLevel: LogLevel.Information, + eventId: default, + state: new List>() + { + new KeyValuePair("food", "artichoke"), + new KeyValuePair("price", 3.99), + }, + exception: null, + formatter: (state, ex) => "Example formatted message."); } [Benchmark] - public void LoggerWithGenevaExporter() + public void LoggerWithSourceGenerator() { - this.loggerWithGenevaExporter.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + Food.SayHello(this.logger, "artichoke", 3.99); } [Benchmark] @@ -132,45 +113,18 @@ public void SerializeLogRecord() this.exporter.SerializeLogRecord(this.logRecord); } - internal class DummyLogProcessor : BaseProcessor - { - } - - internal class DummyLogExporter : BaseExporter - { - public LogRecord LastRecord { get; set; } - - public override ExportResult Export(in Batch batch) - { - foreach (var record in batch) - { - this.LastRecord = record; - } - - return ExportResult.Success; - } - } - - internal ILogger CreateLogger(Action configure = null) + internal static LogRecord GenerateTestLogRecord() { - var loggerFactory = LoggerFactory.Create(builder => - { - if (configure != null) + var items = new List(1); + var factory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => { - builder.AddOpenTelemetry(configure); - } - }); + loggerOptions.AddInMemoryExporter(items); + })); - return loggerFactory.CreateLogger(); - } - - internal LogRecord GenerateTestLogRecord() - { - var dummyLogExporter = new DummyLogExporter(); - var dummyLogger = this.CreateLogger(options => options - .AddProcessor(new SimpleLogRecordExportProcessor(dummyLogExporter))); - dummyLogger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - return dummyLogExporter.LastRecord; + var logger = factory.CreateLogger("SerializationTest"); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return items[0]; } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index b2b3918d5a..e7919ee3ed 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -10,7 +10,7 @@ - + From 361d7047cf76d1ed5b43e56e5bf0bcedc463267c Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 6 Jul 2022 19:26:38 -0700 Subject: [PATCH 0217/1499] Exporter-Geneva add formatted message to benchmarks (#488) --- .../Exporter/LogExporterBenchmarks.cs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 9cfa7dc146..e6787bd568 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -28,12 +28,16 @@ DefaultJob : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT -| Method | Mean | Error | StdDev | Median | Gen 0 | Allocated | -|-------------------------- |-----------:|---------:|---------:|-----------:|-------:|----------:| -| LoggerWithMessageTemplate | 1,219.6 ns | 24.41 ns | 64.30 ns | 1,200.5 ns | 0.0858 | 360 B | -| LoggerWithDirectLoggerAPI | 1,043.6 ns | 19.02 ns | 17.79 ns | 1,050.5 ns | 0.0954 | 400 B | -| LoggerWithSourceGenerator | 1,138.1 ns | 22.62 ns | 28.60 ns | 1,134.1 ns | 0.0763 | 320 B | -| SerializeLogRecord | 845.5 ns | 10.18 ns | 9.52 ns | 845.5 ns | 0.0305 | 128 B | +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------- |------------------------ |-----------:|---------:|---------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 1,107.3 ns | 19.34 ns | 17.15 ns | 0.0858 | 360 B | +| LoggerWithDirectLoggerAPI | False | 1,027.4 ns | 8.92 ns | 7.91 ns | 0.1183 | 496 B | +| LoggerWithSourceGenerator | False | 1,081.5 ns | 4.53 ns | 4.24 ns | 0.0763 | 320 B | +| SerializeLogRecord | False | 825.1 ns | 6.88 ns | 5.74 ns | 0.0305 | 128 B | +| LoggerWithMessageTemplate | True | 1,123.3 ns | 2.24 ns | 1.87 ns | 0.0858 | 360 B | +| LoggerWithDirectLoggerAPI | True | 1,005.8 ns | 2.26 ns | 2.00 ns | 0.1183 | 496 B | +| LoggerWithSourceGenerator | True | 1,083.9 ns | 8.73 ns | 6.82 ns | 0.0763 | 320 B | +| SerializeLogRecord | True | 827.1 ns | 6.45 ns | 6.03 ns | 0.0305 | 128 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark @@ -46,6 +50,9 @@ public class LogExporterBenchmarks private readonly GenevaLogExporter exporter; private readonly LogRecord logRecord; + [Params(true, false)] + public bool IncludeFormattedMessage { get; set; } + public LogExporterBenchmarks() { // for total cost of logging + msgpack serialization @@ -62,6 +69,8 @@ public LogExporterBenchmarks() ["cloud.roleVer"] = "9.0.15289.2", }; }); + + loggerOptions.IncludeFormattedMessage = this.IncludeFormattedMessage; })); this.logger = this.loggerFactory.CreateLogger("TestLogger"); @@ -89,16 +98,18 @@ public void LoggerWithMessageTemplate() [Benchmark] public void LoggerWithDirectLoggerAPI() { + var food = "artichoke"; + var price = 3.99; this.logger.Log( logLevel: LogLevel.Information, eventId: default, state: new List>() { - new KeyValuePair("food", "artichoke"), - new KeyValuePair("price", 3.99), + new KeyValuePair("food", food), + new KeyValuePair("price", price), }, exception: null, - formatter: (state, ex) => "Example formatted message."); + formatter: (state, ex) => $"Hello from {food} {price}."); } [Benchmark] From 8afa0a5f19e0843704e81b88b800a245764f3e24 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Thu, 7 Jul 2022 06:23:52 -0700 Subject: [PATCH 0218/1499] [Instrumentation.Runtime] Add description for metrics in `README.md` (#475) --- .../README.md | 132 ++++++++++++++++++ .../RuntimeMetrics.cs | 22 +-- 2 files changed, 143 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 6c14c887bc..8d938fca71 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -60,6 +60,138 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder() Refer to [Program.cs](../../examples/runtime-instrumentation/Program.cs) for a complete demo. +## Metrics + +### GC related metrics + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------------------------------------------|-----------------------------------------------------------------------|-----------------|-------------------|------------|------------------|------------------| +| process.runtime.dotnet.**gc.collections.count** | Number of garbage collections that have occurred since process start. | `{collections}` | ObservableCounter | `Int64` | generation | gen0, gen1, gen2 | + +Note: Collecting a generation means collecting objects in that generation and all +its younger generations. However, each dimension for this metrics doesn't include +the collection counts for the lower generation. +e.g. count for gen1 is `GC.CollectionCount(1) - GC.CollectionCount(0)`. + +The API used to retrieve the value is: + +* [GC.CollectionCount](https://docs.microsoft.com/dotnet/api/system.gc.collectioncount): + The number of times garbage collection has occurred for the specified generation +of objects. + +#### Additional GC metrics only available when targeting .NET Core 3.1 or later + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------|------------|------------------|------------------| +| process.runtime.dotnet.**gc.allocations.size** | Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap. | `bytes` | ObservableCounter | `Int64` | | | + +The API used to retrieve the value is: + +* [GC.GetTotalAllocatedBytes](https://docs.microsoft.com/dotnet/api/system.gc.gettotalallocatedbytes): + Gets a count of the bytes allocated over the lifetime of the process. The returned +value does not include any native allocations. The value is an approximate count. + +#### Additional GC metrics only available when targeting .NET6 or later + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------|------------|------------------|----------------------------| +| process.runtime.dotnet.**gc.committed_memory.size** | The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred. | `bytes` | ObservableGauge | `Int64` | | | +| process.runtime.dotnet.**gc.heap.size** | The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred. | `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | +| process.runtime.dotnet.**gc.heap.fragmentation.size** | The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred. | `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | + +Note: `ObservableGauge` should be changed to `ObservableUpDownCounter` once available, +as `ObservableUpDownCounter` is the best fit of instrument type. The same applies +to all the `ObservableGauge` below. + +The APIs used to retrieve the values are: + +* [GCMemoryInfo.TotalCommittedBytes](https://docs.microsoft.com/dotnet/api/system.gcmemoryinfo.totalcommittedbytes): + Gets the total committed bytes of the managed heap. + +* [GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo): + Represents the size in bytes of a generation on exit of the GC reported in GCMemoryInfo. + +* [GCGenerationInfo.FragmentationAfterBytes Property](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo.fragmentationafterbytes) + Gets the fragmentation in bytes on exit from the reported collection. + +### JIT Compiler related metrics + +These metrics are only available when targeting .NET6 or later. + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|-------------------|------------|------------------|------------------| +| process.runtime.dotnet.**jit.il_compiled.size** | Count of bytes of intermediate language that have been compiled since the process start. | `bytes` | ObservableCounter | `Int64` | | | +| process.runtime.dotnet.**jit.methods_compiled.count** | The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. | `{methods}` | ObservableCounter | `Int64` | | | +| process.runtime.dotnet.**jit.compilation_time** | The amount of time the JIT compiler has spent compiling methods since the process start. | `ns` | ObservableCounter | `Int64` | | | + +The APIs used to retrieve the values are: + +* [JitInfo.GetCompiledILBytes](https://docs.microsoft.com/dotnet/api/system.runtime.jitinfo.getcompiledilbytes): + Gets the number of bytes of intermediate language that have been compiled. +The scope of this value is global. The same applies for other JIT related metrics. + +* [JitInfo.GetCompiledMethodCount](https://docs.microsoft.com/dotnet/api/system.runtime.jitinfo.getcompiledmethodcount): + Gets the number of methods that have been compiled. + +* [JitInfo.GetCompilationTime](https://docs.microsoft.com/dotnet/api/system.runtime.jitinfo.getcompilationtime): + Gets the amount of time the JIT Compiler has spent compiling methods. + +### Threading related metrics + +These metrics are only available when targeting .NET Core 3.1 or later. + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|--------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------|------------|------------------|------------------| +| process.runtime.dotnet.**monitor.lock_contention.count** | The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter(). | `{contended_acquisitions}` | ObservableCounter | `Int64` | | | +| process.runtime.dotnet.**thread_pool.threads.count** | The number of thread pool threads that currently exist. | `{threads}` | ObservableGauge | `Int32` | | | +| process.runtime.dotnet.**thread_pool.completed_items.count** | The number of work items that have been processed by the thread pool since the process start. | `{items}` | ObservableCounter | `Int64` | | | +| process.runtime.dotnet.**thread_pool.queue.length** | The number of work items that are currently queued to be processed by the thread pool. | `{items}` | ObservableGauge | `Int64` | | | +| process.runtime.dotnet.**timer.count** | The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled. | `{timers}` | ObservableGauge | `Int64` | | | + +The APIs used to retrieve the values are: + +* [Monitor.LockContentionCount](https://docs.microsoft.com/dotnet/api/system.threading.monitor.lockcontentioncount): + Gets the number of times there was contention when trying to take the monitor's + lock. +* [ThreadPool.ThreadCount](https://docs.microsoft.com/dotnet/api/system.threading.threadpool.threadcount): + Gets the number of thread pool threads that currently exist. +* [ThreadPool.CompletedWorkItemCount](https://docs.microsoft.com/dotnet/api/system.threading.threadpool.completedworkitemcount): + Gets the number of work items that have been processed so far. +* [ThreadPool.PendingWorkItemCount](https://docs.microsoft.com/dotnet/api/system.threading.threadpool.pendingworkitemcount): + Gets the number of work items that are currently queued to be processed. +* [Timer.ActiveCount](https://docs.microsoft.com/dotnet/api/system.threading.timer.activecount): + Gets the number of timers that are currently active. An active timer is registered + to tick at some point in the future, and has not yet been canceled. + +### Assemblies related metrics + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------------------------------------------|----------------------------------------------------------|----------------|-----------------|------------|------------------|------------------| +| process.runtime.dotnet.**assemblies.count** | The number of .NET assemblies that are currently loaded. | `{assemblies}` | ObservableGauge | `Int64` | | | + +The API used to retrieve the value is: + +* [AppDomain.GetAssemblies](https://docs.microsoft.com/dotnet/api/system.appdomain.getassemblies): + Gets the number of the assemblies that have been loaded into the execution context + of this application domain. + +### Exception counter metric + +| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-----------------|------------|------------------|------------------| +| process.runtime.dotnet.**exceptions.count** | Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization. | `{exceptions}` | Counter | `Int64` | | | + +Note: The value is tracked by incrementing a counter whenever an AppDomain.FirstChanceException +event occurs. The observation starts when the Runtime instrumentation library is +initialized, so the value will be unavailable until an exception has been +thrown after the initialization. + +Relevant API: + +* [AppDomain.FirstChanceException](https://docs.microsoft.com/dotnet/api/system.appdomain.firstchanceexception) + Occurs when an exception is thrown in managed code, before the runtime searches + the call stack for an exception handler in the application domain. + ## Troubleshooting This component uses an diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 7ba0064722..b13396d8b1 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -50,14 +50,14 @@ static RuntimeMetrics() MeterInstance.CreateObservableCounter( $"{metricPrefix}gc.collections.count", () => GetGarbageCollectionCounts(), - description: "Number of times garbage collection has occurred since process start."); + description: "Number of garbage collections that have occurred since process start."); #if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( $"{metricPrefix}gc.allocations.size", () => GC.GetTotalAllocatedBytes(), unit: "bytes", - description: "Count of the bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); + description: "Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); #endif #if NET6_0_OR_GREATER @@ -91,7 +91,7 @@ static RuntimeMetrics() int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); for (int i = 0; i < maxSupportedLength; ++i) { - measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("gen", GenNames[i])); + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); } return measurements; @@ -114,7 +114,7 @@ static RuntimeMetrics() int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); for (int i = 0; i < maxSupportedLength; ++i) { - measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("gen", GenNames[i])); + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); } return measurements; @@ -128,25 +128,25 @@ static RuntimeMetrics() $"{metricPrefix}jit.il_compiled.size", () => JitInfo.GetCompiledILBytes(), unit: "bytes", - description: "Count of bytes of intermediate language that have been compiled since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); + description: "Count of bytes of intermediate language that have been compiled since the process start."); MeterInstance.CreateObservableCounter( $"{metricPrefix}jit.methods_compiled.count", () => JitInfo.GetCompiledMethodCount(), - description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. The value will be zero under ahead-of-time (AOT) compilation mode."); + description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings."); MeterInstance.CreateObservableCounter( $"{metricPrefix}jit.compilation_time", () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, unit: "ns", - description: "The amount of time the JIT compiler has spent compiling methods since the process start. The value will be zero under ahead-of-time (AOT) compilation mode."); + description: "The amount of time the JIT compiler has spent compiling methods since the process start."); #endif #if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( $"{metricPrefix}monitor.lock_contention.count", () => Monitor.LockContentionCount, - description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()"); + description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( @@ -174,12 +174,12 @@ static RuntimeMetrics() // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}assembly.count", + $"{metricPrefix}assemblies.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "The number of .NET assemblies that are currently loaded."); var exceptionCounter = MeterInstance.CreateCounter( - $"{metricPrefix}exception.count", + $"{metricPrefix}exceptions.count", description: "Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization."); AppDomain.CurrentDomain.FirstChanceException += (source, e) => @@ -222,7 +222,7 @@ private static IEnumerable> GetGarbageCollectionCounts() { long collectionsFromThisGeneration = GC.CollectionCount(gen); - yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("gen", GenNames[gen])); + yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("generation", GenNames[gen])); collectionsFromHigherGeneration = collectionsFromThisGeneration; } From c2739170ab452aa7e75b24a46334263ebb55d7a8 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 7 Jul 2022 19:20:46 -0700 Subject: [PATCH 0219/1499] Instrumentation-Runtime minor tweaks to description (#490) --- opentelemetry-dotnet-contrib.sln | 7 +++++++ .../RuntimeMetrics.cs | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index b1fcde4044..265378a2f5 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -222,6 +222,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNet", "AspNet", "{2B6D07 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.AspNet", "examples\AspNet\Examples.AspNet.csproj", "{9A4E3A68-904B-4835-A3C8-F664B73098DB}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "runtime-instrumentation", "examples\runtime-instrumentation\runtime-instrumentation.csproj", "{9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -464,6 +466,10 @@ Global {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Debug|Any CPU.Build.0 = Debug|Any CPU {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Release|Any CPU.ActiveCfg = Release|Any CPU {9A4E3A68-904B-4835-A3C8-F664B73098DB}.Release|Any CPU.Build.0 = Release|Any CPU + {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -536,6 +542,7 @@ Global {F8629D9B-27C2-4B79-9EF7-DDE7E08CDD72} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2B6D0764-5E66-423A-9943-B3A72FF181EA} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {9A4E3A68-904B-4835-A3C8-F664B73098DB} = {2B6D0764-5E66-423A-9943-B3A72FF181EA} + {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index b13396d8b1..e5ee1dcd10 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -74,7 +74,7 @@ static RuntimeMetrics() return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; }, unit: "bytes", - description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred."); + description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( @@ -97,7 +97,7 @@ static RuntimeMetrics() return measurements; }, unit: "bytes", - description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); + description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( @@ -120,7 +120,7 @@ static RuntimeMetrics() return measurements; }, unit: "bytes", - description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred."); + description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); #endif #if NET6_0_OR_GREATER From c8af3e9d2e30e7e302944df315bd5deb73b06578 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 8 Jul 2022 13:08:03 -0700 Subject: [PATCH 0220/1499] Update CONTRIBUTING doc (#494) --- CONTRIBUTING.md | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a1e590110..7e811d5d60 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -191,27 +191,30 @@ Usually it is a good idea to use the latest version. Example: MinVer will assign the version to your project based on the tag prefix specified by you. To ensure your project is versioned appropriately, specify a `` property in your project file. If your project is named as -"OpenTelemetry.Contrib.Foo.Bar", the MinVerTagPrefix must be "Foo.Bar-". -Example: +"OpenTelemetry.Instrumentation.FooBar", the MinVerTagPrefix must be +"Instrumentation.FooBar-". Example: ```xml - Foo.Bar- + Instrumentation.FooBar- ``` * To build and release your project as nuget, you must provide a GitHub workflow -to be triggered when a tag with prefix "Foo.Bar-" is pushed to the main branch. -The workflow file should be named as `package-Foo.Bar.yml` and to be placed in -the `.github/workflows/` folder. +to be triggered when a tag with prefix "Instrumentation.FooBar-" is pushed to +the main branch. The workflow file should be named as +`package-Instrumentation.FooBar.yml` and to be placed in the +`.github/workflows/` folder. You can copy one of the [existing workflow - files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml) - and replace the - [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml#L12) - value to "Foo.Bar-*" and - [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Extensions.AWSXRay.yml#L18) - value to "OpenTelemetry.Contrib.Foo.Bar". + files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml) + and replace the workflow + [`name`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L1) + with "Pack OpenTelemetry.Instrumentation.FooBar", + [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L12) + with "Instrumentation.FooBar-*" and + [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L18) + with "OpenTelemetry.Instrumentation.FooBar". * Add an issue template in your PR. You can follow the existing issue templates, e.g. [comp_extensions](./.github/ISSUE_TEMPLATE/comp_extensions.md). The From 230895bc6fb6232626e5faf14485be29562d5d82 Mon Sep 17 00:00:00 2001 From: Sami Musallam Date: Mon, 11 Jul 2022 22:28:51 +0300 Subject: [PATCH 0221/1499] fix(remove-testExporter): replaced TestExporter with InMemoryExporter (#497) * fix(remove-testexporter): replaced TestExporter with InMemoryExporter --- ....Contrib.Exporter.Stackdriver.Tests.csproj | 1 + .../Shared/TestExporter.cs | 40 ------------------- .../StackdriverExporterTests.cs | 16 +++++--- 3 files changed, 12 insertions(+), 45 deletions(-) delete mode 100644 test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj index c3e4f1bf49..c07444cf5b 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj @@ -18,6 +18,7 @@ + all diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs deleted file mode 100644 index 7a946b399b..0000000000 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Shared/TestExporter.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -using System; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.Shared -{ - internal class TestExporter : BaseExporter - where T : class - { - private readonly Action> processBatchAction; - - public TestExporter(Action> processBatchAction) - { - Guard.ThrowIfNull(processBatchAction); - - this.processBatchAction = processBatchAction; - } - - public override ExportResult Export(in Batch batch) - { - this.processBatchAction(batch); - - return ExportResult.Success; - } - } -} diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index ff25a88d16..ab770e1c7c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -22,7 +22,7 @@ using Google.Cloud.Trace.V2; using Grpc.Core; using Moq; -using OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.Shared; +using OpenTelemetry.Exporter; using OpenTelemetry.Resources; using OpenTelemetry.Trace; @@ -94,6 +94,7 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() { Exception exception = null; ExportResult result = ExportResult.Success; + var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); var traceClientMock = new Mock(MockBehavior.Strict); @@ -102,9 +103,8 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() .Throws(new RpcException(Status.DefaultCancelled)) .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); - var testExporter = new TestExporter(RunTest); - var processor = new BatchActivityExportProcessor(testExporter); + var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); for (int i = 0; i < 10; i++) { @@ -114,6 +114,9 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() processor.Shutdown(); + var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); + RunTest(batch); + void RunTest(Batch batch) { exception = Record.Exception(() => @@ -132,6 +135,7 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() { Exception exception = null; ExportResult result = ExportResult.Failure; + var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); var traceClientMock = new Mock(MockBehavior.Strict); @@ -139,9 +143,8 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() x.BatchWriteSpans(It.IsAny(), It.IsAny())) .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); - var testExporter = new TestExporter(RunTest); - var processor = new BatchActivityExportProcessor(testExporter); + var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); for (int i = 0; i < 10; i++) { @@ -151,6 +154,9 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() processor.Shutdown(); + var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); + RunTest(batch); + void RunTest(Batch batch) { exception = Record.Exception(() => From 6e840903d639883be86381a3a557942ffb236cd9 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 11 Jul 2022 19:43:10 -0700 Subject: [PATCH 0222/1499] Remove TCP and UDP related options (#500) --- src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs | 4 ---- src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs | 4 ---- src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs | 4 ---- 3 files changed, 12 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 4d97cfa0ca..017fc22ef7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -104,10 +104,6 @@ public GenevaLogExporter(GenevaExporterOptions options) var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; - case TransportProtocol.Tcp: - throw new ArgumentException("TCP transport is not supported yet."); - case TransportProtocol.Udp: - throw new ArgumentException("UDP transport is not supported yet."); default: throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs index fde8fd5cfe..a809174c3a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs @@ -85,10 +85,6 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); break; - case TransportProtocol.Tcp: - throw new ArgumentException("TCP transport is not supported yet."); - case TransportProtocol.Udp: - throw new ArgumentException("UDP transport is not supported yet."); case TransportProtocol.Unspecified: if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 2e7b7932f4..72020ac2c5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -69,10 +69,6 @@ public GenevaTraceExporter(GenevaExporterOptions options) var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; - case TransportProtocol.Tcp: - throw new ArgumentException("TCP transport is not supported yet."); - case TransportProtocol.Udp: - throw new ArgumentException("UDP transport is not supported yet."); default: throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); } From f27d824b9ce798e74b06a43e7e92041684318690 Mon Sep 17 00:00:00 2001 From: Marcin Druzgala <100698932+marcindruzgala@users.noreply.github.com> Date: Tue, 12 Jul 2022 20:52:54 +0200 Subject: [PATCH 0223/1499] [Hangfire OTEL] create parent context if traceparent is available (#421) * create parent context if traceparent is available --- .../CHANGELOG.md | 2 + .../HangfireInstrumentationConstants.cs | 1 + ...ngfireInstrumentationJobFilterAttribute.cs | 50 ++++++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 619eb71eb3..b540497e1b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Added client side instrumentation for jobs ([#421](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/421)) + ## 1.0.0-beta.1 * Updated OTel SDK package version to 1.2.0 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs index 9d4ead7b5c..9b3c125566 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs @@ -23,5 +23,6 @@ internal static class HangfireInstrumentationConstants public const string ActivityName = "JOB"; public const string ActivityKey = "opentelemetry_activity_key"; + public const string ActivityContextKey = "opentelemetry_activity_context"; } } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 60a8d8cf1c..bc0b3baa24 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -16,11 +16,15 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Implementation { + using System.Collections.Generic; using System.Diagnostics; + using System.Linq; + using global::Hangfire.Client; using global::Hangfire.Common; using global::Hangfire.Server; + using OpenTelemetry.Context.Propagation; - internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter + internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter { public void OnPerforming(PerformingContext performingContext) { @@ -30,8 +34,17 @@ public void OnPerforming(PerformingContext performingContext) return; } + var activityContextData = performingContext.GetJobParameter>(HangfireInstrumentationConstants.ActivityContextKey); + ActivityContext parentContext = default; + if (activityContextData is not null) + { + var propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, activityContextData, ExtractActivityProperties); + parentContext = propagationContext.ActivityContext; + Baggage.Current = propagationContext.Baggage; + } + var activity = HangfireInstrumentation.ActivitySource - .StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext: default); + .StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext); if (activity != null) { @@ -65,5 +78,38 @@ public void OnPerformed(PerformedContext performedContext) activity.Dispose(); } } + + public void OnCreating(CreatingContext creatingContext) + { + // Short-circuit if nobody is listening + if (!HangfireInstrumentation.ActivitySource.HasListeners()) + { + return; + } + + ActivityContext contextToInject = default; + if (Activity.Current != null) + { + contextToInject = Activity.Current.Context; + } + + var activityContextData = new Dictionary(); + Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(contextToInject, Baggage.Current), activityContextData, InjectActivityProperties); + creatingContext.SetJobParameter(HangfireInstrumentationConstants.ActivityContextKey, activityContextData); + } + + public void OnCreated(CreatedContext filterContext) + { + } + + private static void InjectActivityProperties(IDictionary jobParams, string key, string value) + { + jobParams[key] = value; + } + + private static IEnumerable ExtractActivityProperties(Dictionary telemetryData, string key) + { + return telemetryData.ContainsKey(key) ? new[] { telemetryData[key] } : Enumerable.Empty(); + } } } From 9418c08abfa0b56423b2c748033a2c25d64d084b Mon Sep 17 00:00:00 2001 From: Hananiel Sarella Date: Tue, 12 Jul 2022 17:37:50 -0400 Subject: [PATCH 0224/1499] Create an EventCounter Listener that subscribes to all event counters (#365) * Create a EventCounter Listener that subscribes to all event counters --- .../comp_instrumentation_eventcounters.md | 41 ++++ .github/component_owners.yml | 5 +- .../package-Instrumentation.EventCounters.yml | 49 +++++ opentelemetry-dotnet-contrib.sln | 14 ++ .../CHANGELOG.md | 9 + .../EventCounterListener.cs | 190 +++++++++++++++++ .../EventCounterMetricsOptions.cs | 29 +++ ...EventCountersInstrumentationEventSource.cs | 47 ++++ .../MeterProviderBuilderExtensions.cs | 48 +++++ ...metry.Instrumentation.EventCounters.csproj | 16 ++ .../README.md | 70 ++++++ .../EventCounterListenerTests.cs | 200 ++++++++++++++++++ .../MeterProviderBuilderExtensionsTests.cs | 34 +++ ...Instrumentation.EventCounters.Tests.csproj | 23 ++ .../TestEventCounter.cs | 45 ++++ .../TestIncrementingEventCounter.cs | 40 ++++ .../TestIncrementingPollingCounter.cs | 37 ++++ .../TestPollingEventCounter.cs | 37 ++++ 18 files changed, 933 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md create mode 100644 .github/workflows/package-Instrumentation.EventCounters.yml create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/README.md create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md new file mode 100644 index 0000000000..27433bb4d4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.EventCounters +about: Issue with OpenTelemetry.Instrumentation.EventCounters +labels: comp:instrumentation.eventcounters +--- + +# Issue with OpenTelemetry.Instrumentation.EventCounters + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 187324cf2d..1a409788f5 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -43,7 +43,8 @@ components: - xiang17 src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch - + src/OpenTelemetry.Instrumentation.EventCounters/: + - hananiel test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn @@ -97,3 +98,5 @@ components: - xiang17 test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch + test/OpenTelemetry.Instrumentation.EventCounters.Tests/: + - hananiel diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml new file mode 100644 index 0000000000..6021ad00f7 --- /dev/null +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Instrumentation.EventCounters + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.EventCounters-*' # trigger when we create a tag with prefix "Instrumentation.EventCounters-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.EventCounters + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 265378a2f5..4fcf6ca13e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -224,6 +224,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.AspNet", "examples EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "runtime-instrumentation", "examples\runtime-instrumentation\runtime-instrumentation.csproj", "{9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EventCounters", "src\OpenTelemetry.Instrumentation.EventCounters\OpenTelemetry.Instrumentation.EventCounters.csproj", "{AE12EFB7-4B1A-46B8-B89A-0375252B10B1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EventCounters.Tests", "test\OpenTelemetry.Instrumentation.EventCounters.Tests\OpenTelemetry.Instrumentation.EventCounters.Tests.csproj", "{DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -470,6 +474,14 @@ Global {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Debug|Any CPU.Build.0 = Debug|Any CPU {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Release|Any CPU.ActiveCfg = Release|Any CPU {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}.Release|Any CPU.Build.0 = Release|Any CPU + {AE12EFB7-4B1A-46B8-B89A-0375252B10B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE12EFB7-4B1A-46B8-B89A-0375252B10B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE12EFB7-4B1A-46B8-B89A-0375252B10B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE12EFB7-4B1A-46B8-B89A-0375252B10B1}.Release|Any CPU.Build.0 = Release|Any CPU + {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -543,6 +555,8 @@ Global {2B6D0764-5E66-423A-9943-B3A72FF181EA} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {9A4E3A68-904B-4835-A3C8-F664B73098DB} = {2B6D0764-5E66-423A-9943-B3A72FF181EA} {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {AE12EFB7-4B1A-46B8-B89A-0375252B10B1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md new file mode 100644 index 0000000000..85f97c807a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## 0.1.0-alpha.1 + +Released 2022-Jul-12 + +* This is the first release of `OpenTelemetry.Instrumentation.EventCounters` package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs new file mode 100644 index 0000000000..597c6734f9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs @@ -0,0 +1,190 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using System.Diagnostics.Tracing; +using System.Reflection; + +namespace OpenTelemetry.Instrumentation.EventCounters +{ + internal class EventCounterListener : EventListener + { + internal static readonly AssemblyName AssemblyName = typeof(EventCounterListener).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name; + internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + + private readonly bool isInitialized = false; + private readonly Meter meter; + private readonly EventCounterMetricsOptions options; + private readonly ConcurrentDictionary metricInstruments = new(); + private readonly ConcurrentDictionary lastValue = new(); + private readonly ConcurrentBag eventSources = new(); + + public EventCounterListener(EventCounterMetricsOptions options) + { + this.meter = new Meter(InstrumentationName, InstrumentationVersion); + this.options = options ?? throw new ArgumentNullException(nameof(options)); + + this.isInitialized = true; + this.EnablePendingEventSources(); // Some OnEventSourceCreated may have fired before constructor, enable them + } + + private enum InstrumentType + { + ObservableGauge, + ObservableCounter, + } + + private Dictionary EnableEventArgs => new() { ["EventCounterIntervalSec"] = this.options.RefreshIntervalSecs.ToString(), }; + + protected override void OnEventSourceCreated(EventSource source) + { + // TODO: Add Configuration options to selectively subscribe to EventCounters + try + { + if (!this.isInitialized) + { + this.eventSources.Add(source); + } + else + { + this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); + } + } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.ErrorEventCounter(source.Name, ex.Message); + } + } + + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + if (!eventData.EventName.Equals("EventCounters") || !this.isInitialized) + { + return; + } + + try + { + if (eventData.Payload.Count > 0 && eventData.Payload[0] is IDictionary eventPayload) + { + this.ExtractAndPostMetric(eventData.EventSource.Name, eventPayload); + } + else + { + EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenAsEventPayloadNotParseable(eventData.EventSource.Name); + } + } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.ErrorEventCounter(eventData.EventName, ex.ToString()); + } + } + + private void ExtractAndPostMetric(string eventSourceName, IDictionary eventPayload) + { + try + { + bool calculateRate = false; + double actualValue = 0; + + string counterName = string.Empty; + string counterDisplayName = string.Empty; + InstrumentType instrumentType = InstrumentType.ObservableGauge; + + foreach (KeyValuePair payload in eventPayload) + { + var key = payload.Key; + if (key.Equals("Name", StringComparison.OrdinalIgnoreCase)) + { + counterName = payload.Value.ToString(); + } + else + if (key.Equals("DisplayName", StringComparison.OrdinalIgnoreCase)) + { + counterDisplayName = payload.Value.ToString(); + } + else if (key.Equals("Mean", StringComparison.OrdinalIgnoreCase)) + { + instrumentType = InstrumentType.ObservableGauge; + actualValue = Convert.ToDouble(payload.Value); + } + else if (key.Equals("Increment", StringComparison.OrdinalIgnoreCase)) + { + // Increment indicates we have to calculate rate. + instrumentType = InstrumentType.ObservableCounter; + calculateRate = true; + actualValue = Convert.ToDouble(payload.Value); + } + } + + this.RecordMetric(eventSourceName, counterName, counterDisplayName, instrumentType, actualValue, calculateRate); + } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.EventCountersInstrumentationWarning("ExtractMetric", ex.Message); + } + } + + private void RecordMetric(string eventSourceName, string counterName, string displayName, InstrumentType instrumentType, double value, bool calculateRate) + { + var metricKey = new MetricKey(eventSourceName, counterName); + var description = string.IsNullOrEmpty(displayName) ? counterName : displayName; + this.lastValue[metricKey] = calculateRate ? value / this.options.RefreshIntervalSecs : value; + switch (instrumentType) + { + case InstrumentType.ObservableCounter: + this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableCounter(counterName, () => this.ObserveDouble(metricKey), description: description)); + break; + + case InstrumentType.ObservableGauge: + this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableGauge(counterName, () => this.ObserveDouble(metricKey), description: description)); + break; + } + } + + private double ObserveDouble(MetricKey key) => this.lastValue[key]; + + private void EnablePendingEventSources() + { + foreach (var source in this.eventSources) + { + this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); + } + } + + private class MetricKey + { + public MetricKey(string eventSourceName, string counterName) + { + this.EventSourceName = eventSourceName; + this.CounterName = counterName; + } + + public string EventSourceName { get; private set; } + + public string CounterName { get; private set; } + + public override int GetHashCode() => (this.EventSourceName, this.CounterName).GetHashCode(); + + public override bool Equals(object obj) => + obj is MetricKey nextKey && this.EventSourceName == nextKey.EventSourceName && this.CounterName == nextKey.CounterName; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs new file mode 100644 index 0000000000..8163ca2faa --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.EventCounters +{ + /// + /// EventCounterMetrics Options. + /// + public class EventCounterMetricsOptions + { + /// + /// Gets or sets the subscription interval in seconds. + /// + public int RefreshIntervalSecs { get; set; } = 60; + } +} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs new file mode 100644 index 0000000000..ba75cb2da0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.EventCounters +{ + /// + /// EventSource events emitted from the project. + /// + [EventSource(Name = "OpenTelemetry-Instrumentation-EventCounters")] + internal class EventCountersInstrumentationEventSource : EventSource + { + public static readonly EventCountersInstrumentationEventSource Log = new(); + + [Event(1, Message = "Error occurred while processing eventCounter, EventCounter: {0}, Exception: {2}", Level = EventLevel.Error)] + public void ErrorEventCounter(string counterName, string exception) + { + this.WriteEvent(1, counterName, exception); + } + + [Event(2, Level = EventLevel.Warning, Message = @"Ignoring event written from EventSource: {0} as payload is not IDictionary to extract metrics.")] + public void IgnoreEventWrittenAsEventPayloadNotParseable(string eventSourceName) + { + this.WriteEvent(4, eventSourceName); + } + + [Event(3, Level = EventLevel.Warning, Message = @"EventCountersInstrumentation - {0} failed with exception: {1}.")] + public void EventCountersInstrumentationWarning(string stage, string exceptionMessage) + { + this.WriteEvent(8, stage, exceptionMessage); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..af114abb45 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -0,0 +1,48 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.EventCounters; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics +{ + /// + /// Extension methods to simplify registering of dependency instrumentation. + /// + public static class MeterProviderBuilderExtensions + { + /// + /// Enables EventCounter instrumentation. + /// + /// being configured. + /// Runtime metrics options. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddEventCounterMetrics( + this MeterProviderBuilder builder, + Action configure = null) + { + Guard.ThrowIfNull(builder); + + var options = new EventCounterMetricsOptions(); + configure?.Invoke(options); + + var instrumentation = new EventCounterListener(options); + builder.AddMeter(EventCounterListener.InstrumentationName); + return builder.AddInstrumentation(() => instrumentation); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj new file mode 100644 index 0000000000..571b39054d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -0,0 +1,16 @@ + + + netstandard2.0 + OpenTelemetry Metrics instrumentation for Dotnet EventCounters + $(PackageTags);metrics;eventcounters + Instrumentation.EventCounters- + enable + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md new file mode 100644 index 0000000000..7ddad17e82 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -0,0 +1,70 @@ +# Event counter instrumentation for OpenTelemetry + +This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which republishes EventCounters using Metrics Api. + +## Steps to enable OpenTelemetry.Instrumentation.EventCounters + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.EventCounters`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) +package. Also, add any other instrumentation & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.EventCounters +``` + +### Step 2: Enable EventCounters Instrumentation at application startup + +EventCounters instrumentation must be enabled at application startup. + +The following example demonstrates adding EventCounter events to a +console application. This example also sets up the OpenTelemetry Console +exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Console) +to the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Metrics; + +namespace DotnetMetrics; + +public class Program +{ + public static void Main(string[] args) + { + using var meterprovider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 5; + }) + .AddConsoleExporter() + .Build(); + } +} +``` + +Console Output: + +```console + +Export cpu-usage, CPU Usage, Meter: OpenTelemetry.Instrumentation.EventCounters/0.0.0.0 +(2022-07-12T16:40:37.2639447Z, 2022-07-12T16:40:42.2533747Z] DoubleGauge +Value: 0 + +Export working-set, Working Set, Meter: OpenTelemetry.Instrumentation.EventCounters/0.0.0.0 +(2022-07-12T16:40:37.2666398Z, 2022-07-12T16:40:42.2534452Z] DoubleGauge +Value: 38 + +Export gc-heap-size, GC Heap Size, Meter: OpenTelemetry.Instrumentation.EventCounters/0.0.0.0 +(2022-07-12T16:40:37.2667389Z, 2022-07-12T16:40:42.2534456Z] DoubleGauge +Value: 7 + + +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs new file mode 100644 index 0000000000..794337f970 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs @@ -0,0 +1,200 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Threading.Tasks; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests +{ + public class EventCounterListenerTests + { + private const int MaxTimeToAllowForFlush = 10000; + private MeterProvider meterProvider; + + [Fact] + public async Task SystemMetricsAreCaptured() + { + var metricItems = new List(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 1; + }) + .AddInMemoryExporter(metricItems) + .Build(); + + await Task.Delay(2000); + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + this.meterProvider.Dispose(); + + Assert.True(metricItems.Count > 1); + } + + [Fact(Skip = "Unstable")] + public async Task TestEventCounterMetricsAreCaptured() + { + const int refreshIntervalSeconds = 1; + var metricItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 1; + }) + .AddInMemoryExporter(metricItems) + .Build(); + var expected = new[] { 100.3F, 200.1F }; + TestEventCounter.Log.SampleCounter1(expected[0]); + TestEventCounter.Log.SampleCounter2(expected[1]); + + // Wait a little bit over the refresh interval seconds + await Task.Delay((refreshIntervalSeconds * 1000) + 300); + + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + this.meterProvider.Dispose(); + + var counter1 = metricItems.Find(m => m.Name == "mycountername1"); + var counter2 = metricItems.Find(m => m.Name == "mycountername2"); + Assert.NotNull(counter1); + Assert.NotNull(counter2); + Assert.Equal(MetricType.DoubleGauge, counter1.MetricType); // EventCounter CounterType is `Mean` + + Assert.Equal(expected[0], GetActualValue(counter1)); + Assert.Equal(expected[1], GetActualValue(counter2)); + } + + [Fact(Skip = "Unstable")] + public async Task TestIncrementingEventCounterMetricsAreCaptured() + { + const int refreshIntervalSeconds = 1; + var metricItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 1; + }) + .AddInMemoryExporter(metricItems) + .Build(); + + TestIncrementingEventCounter.Log.SampleCounter1(1); + TestIncrementingEventCounter.Log.SampleCounter1(1); + TestIncrementingEventCounter.Log.SampleCounter1(1); + + // Wait a little bit over the refresh interval seconds + await Task.Delay((refreshIntervalSeconds * 1000) + 300); + + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + this.meterProvider.Dispose(); + + var counter = metricItems.Find(m => m.Name == TestIncrementingEventCounter.CounterName); + Assert.NotNull(counter); + Assert.Equal(MetricType.DoubleSum, counter.MetricType); // EventCounter CounterType is `Sum` + Assert.Equal(3, GetActualValue(counter)); + } + + [Fact(Skip = "Unstable")] + public async Task TestPollingCounterMetricsAreCaptured() + { + var metricItems = new List(); + const int refreshIntervalSeconds = 1; + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = refreshIntervalSeconds; + }) + .AddInMemoryExporter(metricItems) + .Build(); + + int i = 0; + TestPollingEventCounter.CreateSingleton(() => ++i * 10); + + var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice + await Task.Delay(duration); + + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + this.meterProvider.Dispose(); + + var pollingCounter = metricItems.Find(m => m.Name == TestPollingEventCounter.CounterName); + Assert.NotNull(pollingCounter); + Assert.Equal(MetricType.DoubleGauge, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Mean` + + var expected = i * 10; // The last recorded `Mean` value + Assert.Equal(expected, GetActualValue(pollingCounter)); + } + + [Fact(Skip = "Unstable")] + public async Task TestIncrementingPollingCounterMetrics() + { + var metricItems = new List(); + const int refreshIntervalSeconds = 1; + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = refreshIntervalSeconds; + }) + .AddInMemoryExporter(metricItems) + .Build(); + + int i = 1; + + TestIncrementingPollingCounter.CreateSingleton(() => i++); + + var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice + await Task.Delay(duration); + + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + this.meterProvider.Dispose(); + + var pollingCounter = metricItems.Find(m => m.Name == TestIncrementingPollingCounter.CounterName); + Assert.NotNull(pollingCounter); + Assert.Equal(MetricType.DoubleSum, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Sum` + + Assert.Equal(1, GetActualValue(pollingCounter)); + } + + /// + /// Event Counters are always Sum or Mean and are always record with `float`. + /// + /// Metric to Aggregate. + /// The Aggregated value. + private static double GetActualValue(Metric metric) + { + double sum = 0; + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumDouble(); + } + else + { + sum += metricPoint.GetGaugeLastValueDouble(); + } + } + + return sum; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs new file mode 100644 index 0000000000..deb6e743b2 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests +{ + public class MeterProviderBuilderExtensionsTests + { + [Fact] + public void Throws_Exception_When_Builder_Is_Null() + { + MeterProviderBuilder builder = null; + + Func action = () => builder.AddEventCounterMetrics(); + Assert.Throws(action); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj new file mode 100644 index 0000000000..dbbd098409 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp3.1;net6.0 + true + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs new file mode 100644 index 0000000000..d359a81d1e --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs @@ -0,0 +1,45 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests +{ + [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestEventCounter")] + public sealed class TestEventCounter : EventSource + { + // define the singleton instance of the event source + public static TestEventCounter Log = new TestEventCounter(); + private EventCounter testCounter1; + private EventCounter testCounter2; + + private TestEventCounter() + { + this.testCounter1 = new EventCounter("mycountername1", this); + this.testCounter2 = new EventCounter("mycountername2", this); + } + + public void SampleCounter1(float counterValue) + { + this.testCounter1.WriteMetric(counterValue); + } + + public void SampleCounter2(float counterValue) + { + this.testCounter2.WriteMetric(counterValue); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs new file mode 100644 index 0000000000..f73ac8406a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests +{ + [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestIncrementingEventCounter")] + public sealed class TestIncrementingEventCounter : EventSource + { + public const string CounterName = "IncrementingEventCounter"; + + // define the singleton instance of the event source + public static TestIncrementingEventCounter Log = new(); + private IncrementingEventCounter incrementingEventCounter; + + private TestIncrementingEventCounter() + { + this.incrementingEventCounter = new IncrementingEventCounter(CounterName, this); + } + + public void SampleCounter1(float counterValue) + { + this.incrementingEventCounter.Increment(counterValue); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs new file mode 100644 index 0000000000..03f87bb2aa --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests +{ + [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingIncrementingEventCounter")] + public sealed class TestIncrementingPollingCounter : EventSource + { + public const string CounterName = "TestIncrementingPollingCounter"; + + private IncrementingPollingCounter incrementingPollingCounter; + + private TestIncrementingPollingCounter(Func provider) + { + this.incrementingPollingCounter = new IncrementingPollingCounter(CounterName, this, provider); + } + + // define the singleton instance of the event source + public static TestIncrementingPollingCounter CreateSingleton(Func provider) => new(provider); + } +} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs new file mode 100644 index 0000000000..85aefae11f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests +{ + [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingEventCounter")] + public sealed class TestPollingEventCounter : EventSource + { + public const string CounterName = "TestPollingCounter"; + + private PollingCounter pollingCounter; + + private TestPollingEventCounter(Func provider) + { + this.pollingCounter = new PollingCounter(CounterName, this, provider); + } + + // define the singleton instance of the event source + public static TestPollingEventCounter CreateSingleton(Func provider) => new(provider); + } +} From c5cb68f7ddc760716b682019b3702fe71addb772 Mon Sep 17 00:00:00 2001 From: fred2u Date: Thu, 14 Jul 2022 01:11:48 +0200 Subject: [PATCH 0225/1499] [Instrumentation.Hangfire] Update CHANGELOG for 1.0.0-beta.2 release (#503) * Update CHANGELOG for 1.0.0-beta.2 release --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 9 +++++++-- .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index b540497e1b..7763dd4a0b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,12 +2,17 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2022-Jul-14 + * Added client side instrumentation for jobs ([#421](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/421)) ## 1.0.0-beta.1 -* Updated OTel SDK package version to 1.2.0 - ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) +Released 2022-Jun-03 + +* Updated OTel SDK package version to 1.2.0 ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) ## Initial Release diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index f1f983c7e0..ed025af007 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 OpenTelemetry Hangfire Instrumentation From b971af1826e3ae90da92da9bfb77a5221fabd58c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 14 Jul 2022 18:21:58 -0700 Subject: [PATCH 0226/1499] Add component owner for AWS instrumentation (#506) --- .github/component_owners.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 1a409788f5..11a9f2e73c 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -5,6 +5,8 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - lupengamzn + src/OpenTelemetry.Contrib.Instrumentation.AWS/: + - srprash src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch @@ -46,8 +48,10 @@ components: src/OpenTelemetry.Instrumentation.EventCounters/: - hananiel test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - - srprash + - srprash - lupengamzn + test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/: + - srprash test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch From 2cb82a98e49aaed8931a0a75a627a4d26bdd37f3 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 18 Jul 2022 15:28:46 -0700 Subject: [PATCH 0227/1499] [Exporter.Stackdriver] Fix markdown (#512) * Fix markdown --- .../README.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 2b57c2dacd..911543af79 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -3,14 +3,14 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Stackdriver.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Stackdriver.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) -**NOTE: This exporter is not affiliated with or officially supported by Google.** +**NOTE: This exporter is not affiliated with or officially supported by +Google.** This sample assumes your code authenticates to Stackdriver APIs using [service account][gcp-auth] with credentials stored in environment variable GOOGLE_APPLICATION_CREDENTIALS. When you run on [GAE][GAE], [GKE][GKE] or locally with gcloud sdk installed - this is typically the case. There is also a -constructor for specifying path to the service account credential. See -[sample][stackdriver-sample] for details. +constructor for specifying path to the service account credential. 1. Add [Stackdriver Exporter package][OpenTelemetry-exporter-stackdriver-myget-url] reference. @@ -18,7 +18,6 @@ constructor for specifying path to the service account credential. See 3. Enable [Stackdriver Monitoring][stackdriver-monitoring-setup] API. 4. Instantiate a new instance of `StackdriverExporter` with your Google Cloud's ProjectId -5. See [sample][stackdriver-sample] for example use. ## Installation @@ -64,3 +63,13 @@ metricExporter.Start(); * [GAE](https://cloud.google.com/appengine/docs/flexible/dotnet/quickstart) * [GKE](https://codelabs.developers.google.com/codelabs/cloud-kubernetes-aspnetcore/index.html) * [gcp-auth](https://cloud.google.com/docs/authentication/getting-started) + +[stackdriver-trace-setup]: https://cloud.google.com/trace/docs/setup/ +[stackdriver-monitoring-setup]: + https://cloud.google.com/monitoring/api/enable-api +[GAE]: https://cloud.google.com/appengine/docs/flexible/dotnet/quickstart +[GKE]: + https://codelabs.developers.google.com/codelabs/cloud-kubernetes-aspnetcore/index.html +[gcp-auth]: https://cloud.google.com/docs/authentication/getting-started +[OpenTelemetry-exporter-stackdriver-myget-url]: + https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver From d8ab64abc20625dfbc41e5b881d4a7f00ff890d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 19 Jul 2022 00:43:52 +0200 Subject: [PATCH 0228/1499] Bump OpenTelemetry to 1.3.0 in MySqlData instrumentation (#508) * Bump OpenTelemetry to 1.3.0 in MySqlData instrumentation --- .../CHANGELOG.md | 3 +++ ...penTelemetry.Instrumentation.MySqlData.csproj | 16 ++++++++-------- ...emetry.Instrumentation.MySqlData.Tests.csproj | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 4d88e85de9..5cec97f129 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.3.0 + ([#508](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/508)) + ## 1.0.0-beta.3 Released 2022-Jun-29 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index cbf676c0ae..6dfbeedb42 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -8,17 +8,17 @@ - - + + - - - - - - + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 2315824b39..85df907250 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -16,7 +16,7 @@ - + From 25f3c43f27e0be7097a08671515e6be85671c375 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 18 Jul 2022 20:55:48 -0700 Subject: [PATCH 0229/1499] [Instrumentation.Runtime] Change API for GC Heap Size (#495) --- .../CHANGELOG.md | 3 + .../README.md | 5 ++ .../RuntimeMetrics.cs | 61 +++++++++++++------ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 6d326578d0..b4ebd994c6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Change API for GC Heap Size for .NET 6 where the API has a bug + ([#495](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/495)) + ## 1.0.0-rc.1 Released 2022-Jun-29 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 8d938fca71..8ecb0aa67f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -110,6 +110,11 @@ The APIs used to retrieve the values are: * [GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo): Represents the size in bytes of a generation on exit of the GC reported in GCMemoryInfo. + Note that this API on .NET 6 has a [bug](https://github.com/dotnet/runtime/pull/60309). + For .NET 6, heap size is retrieved with an internal method `GC.GetGenerationSize`, + which is how the [well-known EventCounters](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/available-counters) + retrieve the values. + See source code [here](https://github.com/dotnet/runtime/blob/b4dd16b4418de9b3af08ae85f0f3653e55dc420a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs#L110-L114). * [GCGenerationInfo.FragmentationAfterBytes Property](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo.fragmentationafterbytes) Gets the fragmentation in bytes on exit from the reported collection. diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index e5ee1dcd10..a43d572d6d 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -76,28 +76,51 @@ static RuntimeMetrics() unit: "bytes", description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{metricPrefix}gc.heap.size", - () => + // GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 + Func getGenerationSize = null; + bool isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; + if (isCodeRunningOnBuggyRuntimeVersion) + { + MethodInfo mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); + if (mi != null) { - if (!IsGcInfoAvailable) - { - return Array.Empty>(); - } + getGenerationSize = mi.CreateDelegate>(); + } + } - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) + // Either Environment.Version is not 6 or (it's 6 but internal API GC.GetGenerationSize is valid) + if (!isCodeRunningOnBuggyRuntimeVersion || getGenerationSize != null) + { + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}gc.heap.size", + () => { - measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); - } - - return measurements; - }, - unit: "bytes", - description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) + { + if (isCodeRunningOnBuggyRuntimeVersion) + { + measurements[i] = new((long)getGenerationSize(i), new KeyValuePair("generation", GenNames[i])); + } + else + { + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); + } + } + + return measurements; + }, + unit: "bytes", + description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + } // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( From db3c2a2e67cffdad7995c2e374d28502c1761d82 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 18 Jul 2022 21:10:54 -0700 Subject: [PATCH 0230/1499] [Exporter.Stackdriver] Remove contrib from Stackdriver files (#513) * Rename namespace * Rename the test project * Update CHANGELOG Co-authored-by: Cijo Thomas --- opentelemetry-dotnet-contrib.sln | 2 +- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 9 +++++++++ .../Implementation/ActivityExtensions.cs | 2 +- .../Implementation/Constants.cs | 2 +- .../Implementation/ExporterStackdriverEventSource.cs | 2 +- .../Implementation/GoogleCloudResourceUtils.cs | 2 +- .../Implementation/StackdriverStatsConfiguration.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../StackdriverTraceExporter.cs | 4 ++-- .../TracerProviderBuilderExtensions.cs | 2 +- .../Utils/CommonUtils.cs | 2 +- .../Implementation/StackdriverStatsConfigurationTests.cs | 4 ++-- ...j => OpenTelemetry.Exporter.Stackdriver.Tests.csproj} | 0 .../StackdriverExporterTests.cs | 3 +-- .../TestActivityProcessor.cs | 3 +-- 15 files changed, 24 insertions(+), 17 deletions(-) rename test/OpenTelemetry.Exporter.Stackdriver.Tests/{OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj => OpenTelemetry.Exporter.Stackdriver.Tests.csproj} (100%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 4fcf6ca13e..6380291c2b 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -138,7 +138,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Owin", "examples\o EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver", "src\OpenTelemetry.Exporter.Stackdriver\OpenTelemetry.Exporter.Stackdriver.csproj", "{8A25B43D-BBB2-40FF-B0EB-33AACCD15AD7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Stackdriver.Tests", "test\OpenTelemetry.Exporter.Stackdriver.Tests\OpenTelemetry.Exporter.Stackdriver.Tests.csproj", "{8DABC11A-624E-4554-ACA4-D5B80146B9C6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient", "src\OpenTelemetry.Instrumentation.ElasticsearchClient\OpenTelemetry.Instrumentation.ElasticsearchClient.csproj", "{96F5B85B-402B-4DFB-AF31-33D5A2EBE35B}" EndProject diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 4ff1c37e1c..21ca39e497 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -7,6 +7,15 @@ * Update Google.Cloud.Monitoring.V3 2.1.0 -> 2.6.0 * Update Google.Cloud.Monitoring.V3 2.0.0 -> 2.3.0 +* Rename the namespaces to remove the word `Contrib` from them: + 1. `OpenTelemetry.Contrib.Exporter.Stackdriver` -> + `OpenTelemetry.Exporter.Stackdriver` + 2. `OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation` -> + `OpenTelemetry.Exporter.Stackdriver.Implementation` + 3. `OpenTelemetry.Contrib.Exporter.Stackdriver.Utils` -> + `OpenTelemetry.Exporter.Stackdriver.Utils` + [(#513)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/513) + ## 1.0.0-beta.2 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index f6e814d9d4..5fbb64670a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -21,7 +21,7 @@ using Google.Protobuf.WellKnownTypes; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation { internal static class ActivityExtensions { diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs index 8a91ab9803..4259b34ade 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs @@ -16,7 +16,7 @@ using System; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation { internal class Constants { diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs index e2963b08ce..70d68a3d99 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs @@ -19,7 +19,7 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation { [EventSource(Name = "OpenTelemetry-Exporter-Stackdriver")] internal class ExporterStackdriverEventSource : EventSource diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs index 74fda378cd..864afffaac 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs @@ -18,7 +18,7 @@ using System.IO; using Google.Api; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation { /// /// Utility methods for working with Google Cloud Resources. diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs index 0ffe6d0abc..c424d84c81 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs @@ -18,7 +18,7 @@ using Google.Api; using Google.Apis.Auth.OAuth2; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation { /// /// Configuration for exporting stats into Stackdriver. diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs index c2937a3676..6c14f10f6f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Exporter.Stackdriver.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Stackdriver.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 526337866f..65e6587f3d 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -21,9 +21,9 @@ using Google.Api.Gax.Grpc; using Google.Cloud.Trace.V2; using Grpc.Core; -using OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation; +using OpenTelemetry.Exporter.Stackdriver.Implementation; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver +namespace OpenTelemetry.Exporter.Stackdriver { /// /// Exports a group of spans to Stackdriver. diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index 82169f9aad..974942ab3a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -using OpenTelemetry.Contrib.Exporter.Stackdriver; +using OpenTelemetry.Exporter.Stackdriver; using OpenTelemetry.Internal; namespace OpenTelemetry.Trace diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs index 9d852ec2d0..6478bfcef0 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs @@ -16,7 +16,7 @@ using System.Collections.Generic; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Utils +namespace OpenTelemetry.Exporter.Stackdriver.Utils { /// /// Common Utility Methods that are not metrics/trace specific. diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs index d02cf1381a..8089b4a71c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs @@ -15,10 +15,10 @@ // using System; -using OpenTelemetry.Contrib.Exporter.Stackdriver.Implementation; +using OpenTelemetry.Exporter.Stackdriver.Implementation; using Xunit; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Tests +namespace OpenTelemetry.Exporter.Stackdriver.Tests { public class StackdriverStatsConfigurationTests { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj similarity index 100% rename from test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Contrib.Exporter.Stackdriver.Tests.csproj rename to test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index ab770e1c7c..3a4f662207 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -22,14 +22,13 @@ using Google.Cloud.Trace.V2; using Grpc.Core; using Moq; -using OpenTelemetry.Exporter; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Xunit; using Status = Grpc.Core.Status; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Tests +namespace OpenTelemetry.Exporter.Stackdriver.Tests { public class StackdriverExporterTests { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index 62ded2b6e3..dc7e415768 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -16,9 +16,8 @@ using System; using System.Diagnostics; -using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Exporter.Stackdriver.Tests +namespace OpenTelemetry.Exporter.Stackdriver.Tests { public class TestActivityProcessor : BaseProcessor, IDisposable { From d9cc2811c384943dc7aa5004af7c89dd0ed6bebc Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 18 Jul 2022 21:31:23 -0700 Subject: [PATCH 0231/1499] [Instrumentation.Runtime] Remove `gc.heap.fragmentation.size` metrics due to buggy API on .NET 6 (#509) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Runtime/README.md | 3 +++ src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs | 3 +++ 3 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index b4ebd994c6..3aad6068f5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -4,6 +4,8 @@ * Change API for GC Heap Size for .NET 6 where the API has a bug ([#495](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/495)) +* Remove gc.heap.fragmentation.size metrics due to buggy API on .NET 6 + ([#509](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/509)) ## 1.0.0-rc.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 8ecb0aa67f..c56c41df6b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -103,6 +103,9 @@ Note: `ObservableGauge` should be changed to `ObservableUpDownCounter` once avai as `ObservableUpDownCounter` is the best fit of instrument type. The same applies to all the `ObservableGauge` below. +Note: `gc.heap.fragmentation.size` metrics is removed for .NET 6 because of a +[bug](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496). + The APIs used to retrieve the values are: * [GCMemoryInfo.TotalCommittedBytes](https://docs.microsoft.com/dotnet/api/system.gcmemoryinfo.totalcommittedbytes): diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index a43d572d6d..552e2b1b87 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -121,7 +121,10 @@ static RuntimeMetrics() unit: "bytes", description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); } +#endif +#if NET7_0_OR_GREATER + // TODO: Not valid until .NET 7 where the bug is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( $"{metricPrefix}gc.heap.fragmentation.size", From ff5e8c20efc248c380f167a93be97e86386e253b Mon Sep 17 00:00:00 2001 From: xiang17 Date: Tue, 19 Jul 2022 06:54:04 -0700 Subject: [PATCH 0232/1499] [Instrumentation.Runtime] Reformat by taking description column out of table (#492) --- .../README.md | 180 ++++++++++++++---- 1 file changed, 148 insertions(+), 32 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index c56c41df6b..74d2264fa8 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -64,26 +64,36 @@ complete demo. ### GC related metrics -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------------------------------------------------|-----------------------------------------------------------------------|-----------------|-------------------|------------|------------------|------------------| -| process.runtime.dotnet.**gc.collections.count** | Number of garbage collections that have occurred since process start. | `{collections}` | ObservableCounter | `Int64` | generation | gen0, gen1, gen2 | +#### process.runtime.dotnet.**gc.collections.count** + +Number of garbage collections that have occurred since process start. Note: Collecting a generation means collecting objects in that generation and all its younger generations. However, each dimension for this metrics doesn't include the collection counts for the lower generation. e.g. count for gen1 is `GC.CollectionCount(1) - GC.CollectionCount(0)`. +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-----------------|-------------------|------------|------------------|------------------| +| `{collections}` | ObservableCounter | `Int64` | generation | gen0, gen1, gen2 | + The API used to retrieve the value is: * [GC.CollectionCount](https://docs.microsoft.com/dotnet/api/system.gc.collectioncount): The number of times garbage collection has occurred for the specified generation of objects. -#### Additional GC metrics only available when targeting .NET Core 3.1 or later +#### process.runtime.dotnet.**gc.allocations.size** + +Count of bytes allocated on the managed GC heap since the process start. +.NET objects are allocated from this heap. Object allocations from unmanaged languages +such as C/C++ do not use this heap. -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-------------------|------------|------------------|------------------| -| process.runtime.dotnet.**gc.allocations.size** | Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap. | `bytes` | ObservableCounter | `Int64` | | | +Note: This metric is only available when targeting .NET Core 3.1 or later. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-------------------|------------|------------------|------------------| +| `bytes` | ObservableCounter | `Int64` | No Attributes | N/A | The API used to retrieve the value is: @@ -91,26 +101,47 @@ The API used to retrieve the value is: Gets a count of the bytes allocated over the lifetime of the process. The returned value does not include any native allocations. The value is an approximate count. -#### Additional GC metrics only available when targeting .NET6 or later +#### process.runtime.dotnet.**gc.committed_memory.size** -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------------|------------|------------------|----------------------------| -| process.runtime.dotnet.**gc.committed_memory.size** | The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until garbage collection has occurred. | `bytes` | ObservableGauge | `Int64` | | | -| process.runtime.dotnet.**gc.heap.size** | The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred. | `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | -| process.runtime.dotnet.**gc.heap.fragmentation.size** | The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until garbage collection has occurred. | `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | +The amount of committed virtual memory for the managed GC heap, as +observed during the latest garbage collection. Committed virtual memory may be +larger than the heap size because it includes both memory for storing existing +objects (the heap size) and some extra memory that is ready to handle newly +allocated objects in the future. The value will be unavailable until at least one +garbage collection has occurred. Note: `ObservableGauge` should be changed to `ObservableUpDownCounter` once available, as `ObservableUpDownCounter` is the best fit of instrument type. The same applies to all the `ObservableGauge` below. +Note: This metric is only available when targeting .NET6 or later. + Note: `gc.heap.fragmentation.size` metrics is removed for .NET 6 because of a [bug](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496). -The APIs used to retrieve the values are: +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-----------------|------------|------------------|------------------| +| `bytes` | ObservableGauge | `Int64` | No Attributes | N/A | + +The API used to retrieve the value is: * [GCMemoryInfo.TotalCommittedBytes](https://docs.microsoft.com/dotnet/api/system.gcmemoryinfo.totalcommittedbytes): Gets the total committed bytes of the managed heap. +#### process.runtime.dotnet.**gc.heap.size** + +The heap size (including fragmentation), as observed during the +latest garbage collection. The value will be unavailable until at least one +garbage collection has occurred. + +Note: This metric is only available when targeting .NET6 or later. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-----------------|------------|------------------|----------------------------| +| `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | + +The API used to retrieve the value is: + * [GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo): Represents the size in bytes of a generation on exit of the GC reported in GCMemoryInfo. Note that this API on .NET 6 has a [bug](https://github.com/dotnet/runtime/pull/60309). @@ -119,6 +150,19 @@ The APIs used to retrieve the values are: retrieve the values. See source code [here](https://github.com/dotnet/runtime/blob/b4dd16b4418de9b3af08ae85f0f3653e55dc420a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs#L110-L114). +#### process.runtime.dotnet.**gc.heap.fragmentation.size** + +The heap fragmentation, as observed during the latest garbage collection. +The value will be unavailable until at least one garbage collection has occurred. + +Note: This metric is only available when targeting .NET6 or later. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-----------------|------------|------------------|----------------------------| +| `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | + +The API used to retrieve the value is: + * [GCGenerationInfo.FragmentationAfterBytes Property](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo.fragmentationafterbytes) Gets the fragmentation in bytes on exit from the reported collection. @@ -126,11 +170,34 @@ The APIs used to retrieve the values are: These metrics are only available when targeting .NET6 or later. -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|-------------------|------------|------------------|------------------| -| process.runtime.dotnet.**jit.il_compiled.size** | Count of bytes of intermediate language that have been compiled since the process start. | `bytes` | ObservableCounter | `Int64` | | | -| process.runtime.dotnet.**jit.methods_compiled.count** | The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings. | `{methods}` | ObservableCounter | `Int64` | | | -| process.runtime.dotnet.**jit.compilation_time** | The amount of time the JIT compiler has spent compiling methods since the process start. | `ns` | ObservableCounter | `Int64` | | | +#### process.runtime.dotnet.**jit.il_compiled.size** + +Count of bytes of intermediate language that have been compiled since +the process start. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-------------------|------------|------------------|------------------| +| `bytes` | ObservableCounter | `Int64` | No Attributes | N/A | + +#### process.runtime.dotnet.**jit.methods_compiled.count** + +The number of times the JIT compiler compiled a method since the process +start. The JIT compiler may be invoked multiple times for the same method to compile +with different generic parameters, or because tiered compilation requested different +optimization settings. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------|-------------------|------------|------------------|------------------| +| `{methods}` | ObservableCounter | `Int64` | No Attributes | N/A | + +#### process.runtime.dotnet.**jit.compilation_time** + +The amount of time the JIT compiler has spent compiling methods since +the process start. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------|-------------------|------------|------------------|------------------| +| `ns` | ObservableCounter | `Int64` | No Attributes | N/A | The APIs used to retrieve the values are: @@ -148,13 +215,52 @@ The scope of this value is global. The same applies for other JIT related metric These metrics are only available when targeting .NET Core 3.1 or later. -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|--------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|-------------------|------------|------------------|------------------| -| process.runtime.dotnet.**monitor.lock_contention.count** | The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter(). | `{contended_acquisitions}` | ObservableCounter | `Int64` | | | -| process.runtime.dotnet.**thread_pool.threads.count** | The number of thread pool threads that currently exist. | `{threads}` | ObservableGauge | `Int32` | | | -| process.runtime.dotnet.**thread_pool.completed_items.count** | The number of work items that have been processed by the thread pool since the process start. | `{items}` | ObservableCounter | `Int64` | | | -| process.runtime.dotnet.**thread_pool.queue.length** | The number of work items that are currently queued to be processed by the thread pool. | `{items}` | ObservableGauge | `Int64` | | | -| process.runtime.dotnet.**timer.count** | The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled. | `{timers}` | ObservableGauge | `Int64` | | | +#### process.runtime.dotnet.**monitor.lock_contention.count** + +The number of times there was contention when trying to acquire a +monitor lock since the process start. Monitor locks are commonly acquired by using +the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter(). + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|----------------------------|-------------------|------------|------------------|------------------| +| `{contended_acquisitions}` | ObservableCounter | `Int64` | No Attributes | N/A | + +#### process.runtime.dotnet.**thread_pool.threads.count** + +The number of thread pool threads that currently exist. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------|-------------------|------------|------------------|------------------| +| `{threads}` | ObservableGauge | `Int32` | No Attributes | N/A | + +#### process.runtime.dotnet.**thread_pool.completed_items.count** + +The number of work items that have been processed by the thread pool +since the process start. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------|-------------------|------------|------------------|------------------| +| `{items}` | ObservableCounter | `Int64` | No Attributes | N/A | + +#### process.runtime.dotnet.**thread_pool.queue.length** + +The number of work items that are currently queued to be processed +by the thread pool. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------|-------------------|------------|------------------|------------------| +| `{items}` | ObservableGauge | `Int64` | No Attributes | N/A | + +#### process.runtime.dotnet.**timer.count** + +The number of timer instances that are currently active. Timers can +be created by many sources such as System.Threading.Timer, Task.Delay, or the +timeout in a CancellationSource. An active timer is registered to tick at some +point in the future and has not yet been canceled. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------|-------------------|------------|------------------|------------------| +| `{timers}` | ObservableGauge | `Int64` | No Attributes | N/A | The APIs used to retrieve the values are: @@ -173,9 +279,13 @@ The APIs used to retrieve the values are: ### Assemblies related metrics -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|---------------------------------------------|----------------------------------------------------------|----------------|-----------------|------------|------------------|------------------| -| process.runtime.dotnet.**assemblies.count** | The number of .NET assemblies that are currently loaded. | `{assemblies}` | ObservableGauge | `Int64` | | | +#### process.runtime.dotnet.**assemblies.count** + +The number of .NET assemblies that are currently loaded. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|----------------|-----------------|------------|------------------|------------------| +| `{assemblies}` | ObservableGauge | `Int64` | No Attributes | N/A | The API used to retrieve the value is: @@ -185,15 +295,21 @@ The API used to retrieve the value is: ### Exception counter metric -| Name | Description | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|---------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-----------------|------------|------------------|------------------| -| process.runtime.dotnet.**exceptions.count** | Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization. | `{exceptions}` | Counter | `Int64` | | | +#### process.runtime.dotnet.**exceptions.count** + +Count of exceptions that have been thrown in managed code, since the +observation started. The value will be unavailable until an exception has been +thrown after OpenTelemetry.Instrumentation.Runtime initialization. Note: The value is tracked by incrementing a counter whenever an AppDomain.FirstChanceException event occurs. The observation starts when the Runtime instrumentation library is initialized, so the value will be unavailable until an exception has been thrown after the initialization. +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|----------------|-----------------|------------|------------------|------------------| +| `{exceptions}` | Counter | `Int64` | No Attributes | N/A | + Relevant API: * [AppDomain.FirstChanceException](https://docs.microsoft.com/dotnet/api/system.appdomain.firstchanceexception) From c37fccf8f5ab5678628da79149231a50ebe12c13 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Tue, 19 Jul 2022 17:47:22 -0700 Subject: [PATCH 0233/1499] Release Runtime instrumentation version 1.0.0-rc.2 (#520) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 3aad6068f5..d3b2fec726 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.2 + +Released 2022-Jul-19 + * Change API for GC Heap Size for .NET 6 where the API has a bug ([#495](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/495)) * Remove gc.heap.fragmentation.size metrics due to buggy API on .NET 6 From 60ee91c73dd9e3a3ed8f164e09c14ba417921fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 20 Jul 2022 03:31:05 +0200 Subject: [PATCH 0234/1499] Unify coverlet.collector (3.1.2+) (#518) --- build/Common.nonprod.props | 1 + .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.EventCounters.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.MySqlData.Tests.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 501b84b024..5583ab29d2 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -21,6 +21,7 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [0.12.1,0.13) + [3.1.2,4.0.0) [2.3.1,3.0) [5.0,6.0) [16.7.1,17.0) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 2a4a44c287..71743f602e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -8,7 +8,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 434d5c9dfc..8a51781e5b 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index dbbd098409..e690787bfd 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 6eec7d0f69..13cd736850 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -4,7 +4,7 @@ netcoreapp3.1 - + diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 85df907250..fcfe43e961 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -7,7 +7,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index d51bb93f8a..a0bd58a833 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -6,7 +6,7 @@ - + From 2dbc66a021fbd601b59c4c805b46fc397ba1a9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 20 Jul 2022 16:33:48 +0200 Subject: [PATCH 0235/1499] Unify Moq (4.17.2+) (#516) --- build/Common.nonprod.props | 2 +- .../OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj | 2 +- .../OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj | 2 +- ...OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.MySqlData.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 5583ab29d2..e4c6818fc7 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -25,7 +25,7 @@ [2.3.1,3.0) [5.0,6.0) [16.7.1,17.0) - [4.14.5,5.0) + [4.17.2,5.0) $(OpenTelemetryPkgVer) [2.4.3,3.0) [2.4.1,3.0) diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index 274e57f917..c4f3634c9e 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -9,7 +9,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 606c7d0ebf..9bc689512e 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj index d0e6393e60..fb79832ea4 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj @@ -9,7 +9,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 0b17f09239..e09f2f25da 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -6,7 +6,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index fcfe43e961..81cb72fc80 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -6,7 +6,7 @@ - + From e8b5202948554d44b757812f8cac9ee09ae4937a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 20 Jul 2022 17:08:03 +0200 Subject: [PATCH 0236/1499] [Geneva.Exporter] remove obsolete comment from tests (#517) Co-authored-by: Utkarsh Umesan Pillai --- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 71743f602e..c7115ee052 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -13,7 +13,6 @@ all - From 337ce91bd558ff212758ba13e762fa7978d71c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 20 Jul 2022 21:10:54 +0200 Subject: [PATCH 0237/1499] [Instrumentation.StackExchangeRedis] Code cleanup (#521) --- .../Implementation/RedisProfilerEntryToActivityConverter.cs | 5 ++--- .../OpenTelemetry.Instrumentation.StackExchangeRedis.csproj | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- ...Telemetry.Instrumentation.StackExchangeRedis.Tests.csproj | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 2f553565fc..efb2f7db29 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -31,7 +31,6 @@ internal static class RedisProfilerEntryToActivityConverter { var redisAssembly = typeof(IProfiledCommand).Assembly; Type profiledCommandType = redisAssembly.GetType("StackExchange.Redis.Profiling.ProfiledCommand"); - Type messageType = redisAssembly.GetType("StackExchange.Redis.Message"); Type scriptMessageType = redisAssembly.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage"); var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); @@ -93,7 +92,7 @@ public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfi activity.SetEndTime(command.CommandCreated + command.ElapsedTime); - if (activity.IsAllDataRequested == true) + if (activity.IsAllDataRequested) { // see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md @@ -189,7 +188,7 @@ public static void DrainSession(Activity parentActivity, IEnumerable /// Creates getter for a field defined in private or internal type - /// repesented with classType variable. + /// represented with classType variable. /// private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) { diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 0c242324cf..06dc29e19c 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index e9aade2270..2d99482051 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -78,7 +78,7 @@ private static TracerProviderBuilder AddRedisInstrumentation( TracerProviderBuilder builder, IConnectionMultiplexer connection, StackExchangeRedisCallsInstrumentationOptions options, - Action configure = null) + Action configure) { configure?.Invoke(options); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 769b012dd3..7a994128d1 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry StackExchangeRedis instrumentation @@ -19,7 +19,7 @@ - + all From b4f4a7e9f3835aaa3b3a7800c96175bacca932bf Mon Sep 17 00:00:00 2001 From: fred2u Date: Wed, 20 Jul 2022 23:47:03 +0200 Subject: [PATCH 0238/1499] Updated OTel SDK package version to 1.3.0 (#522) * Updated OTel SDK package version to 1.3.0 --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 +++- .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 +- .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 5 ++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 7763dd4a0b..d5b01dd16d 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Updated OTel API package version to 1.3.0 ([#522](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/522)) + ## 1.0.0-beta.2 Released 2022-Jul-14 @@ -12,7 +14,7 @@ Released 2022-Jul-14 Released 2022-Jun-03 -* Updated OTel SDK package version to 1.2.0 ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) +* Updated OTel API package version to 1.2.0 ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) ## Initial Release diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index ed025af007..f12cc61c01 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 0ca6a79c0b..aa7a7f9b68 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry Hangfire instrumentation net472;netcoreapp3.1 @@ -8,8 +8,7 @@ - - + all From b9c9f4b6e714d14a28d25a744679e139b0fb2452 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 17:57:14 -0700 Subject: [PATCH 0239/1499] [Instrumentation.Runtime] Add `gc.heap.fragmentation.size` back for .NET 7 and later (#524) --- .../CHANGELOG.md | 3 ++ .../RuntimeMetrics.cs | 45 ++++++++++--------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index d3b2fec726..23c2377230 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add gc.heap.fragmentation.size back for .NET 7 and later + ([#524](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/524)) + ## 1.0.0-rc.2 Released 2022-Jul-19 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 552e2b1b87..c373950e5f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -121,32 +121,33 @@ static RuntimeMetrics() unit: "bytes", description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); } -#endif -#if NET7_0_OR_GREATER - // TODO: Not valid until .NET 7 where the bug is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{metricPrefix}gc.heap.fragmentation.size", - () => - { - if (!IsGcInfoAvailable) + // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 + if (Environment.Version.Major >= 7) + { + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{metricPrefix}gc.heap.fragmentation.size", + () => { - return Array.Empty>(); - } + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) - { - measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); - } + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) + { + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); + } - return measurements; - }, - unit: "bytes", - description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + return measurements; + }, + unit: "bytes", + description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + } #endif #if NET6_0_OR_GREATER From 6fcb78e9bf00c9b107c9924b197a39ae30ab9213 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 20 Jul 2022 21:48:48 -0700 Subject: [PATCH 0240/1499] [Instrumentation.Runtime] Amend `CHANGELOG.md` for 1.0.0-rc.2 (#523) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 23c2377230..2eea74a65b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -9,6 +9,9 @@ Released 2022-Jul-19 +* Refined some metrics names (assembly.count->assemblies.count, exception.count-> + exceptions.count, attribute name: gen->generation) and descriptions + ([#475](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/475)) * Change API for GC Heap Size for .NET 6 where the API has a bug ([#495](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/495)) * Remove gc.heap.fragmentation.size metrics due to buggy API on .NET 6 From 0a7b14d2a7e319cc43ee321a2f705ff85b84c050 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Thu, 21 Jul 2022 14:48:08 -0700 Subject: [PATCH 0241/1499] [Instrumentation.Runtime] Add unit tests (#510) --- .../RuntimeMetricsTests.cs | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 6a9b73f107..fb205860bd 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -14,7 +14,10 @@ // limitations under the License. // +using System; using System.Collections.Generic; +using System.Linq; +using System.Threading; using OpenTelemetry.Metrics; using Xunit; @@ -34,9 +37,156 @@ public void RuntimeMetricsAreCaptured() .AddInMemoryExporter(exportedItems) .Build(); + // The process.runtime.dotnet.exception.count metrics are only available after an exception has been thrown post OpenTelemetry.Instrumentation.Runtime initialization. + try + { + throw new Exception("Oops!"); + } + catch (Exception) + { + // swallow the exception + } + meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.True(exportedItems.Count > 1); Assert.StartsWith(MetricPrefix, exportedItems[0].Name); + + var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); + Assert.NotNull(assembliesCountMetric); + + var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.exceptions.count"); + Assert.True(GetValue(exceptionsCountMetric) >= 1); + } + + [Fact] + public void GcMetricsTest() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + GC.Collect(1); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); + Assert.NotNull(gcCountMetric); + +#if NETCOREAPP3_1_OR_GREATER + var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); + Assert.NotNull(gcAllocationSizeMetric); +#endif + +#if NET6_0_OR_GREATER + var gcCommittedMemorySizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); + Assert.NotNull(gcCommittedMemorySizeMetric); + + var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); + Assert.NotNull(gcHeapSizeMetric); + + if (Environment.Version.Major >= 7) + { + var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); + Assert.NotNull(gcHeapFragmentationSizeMetric); + } +#endif + } + +#if NET6_0_OR_GREATER + [Fact] + public void JitRelatedMetricsTest() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var jitCompiledSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); + Assert.NotNull(jitCompiledSizeMetric); + + var jitMethodsCompiledCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.methods_compiled.count"); + Assert.NotNull(jitMethodsCompiledCountMetric); + + var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); + Assert.NotNull(jitCompilationTimeMetric); + } +#endif + +#if NETCOREAPP3_1_OR_GREATER + [Fact] + public void ThreadingRelatedMetricsTest() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); + Assert.NotNull(lockContentionCountMetric); + + var threadCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); + Assert.NotNull(threadCountMetric); + + var completedItemsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); + Assert.NotNull(completedItemsCountMetric); + + var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); + Assert.NotNull(queueLengthMetric); + + List timers = new List(); + try + { + // Create 10 timers to bump timer.count metrics. + int timerCount = 10; + TimerCallback timerCallback = _ => { }; + for (int i = 0; i < timerCount; i++) + { + Timer timer = new Timer(timerCallback, null, 1000, 250); + timers.Add(timer); + } + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var timerCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.timer.count"); + Assert.True(GetValue(timerCountMetric) >= timerCount); + } + finally + { + for (int i = 0; i < timers.Count; i++) + { + timers[i].Dispose(); + } + } + } +#endif + + private static double GetValue(Metric metric) + { + Assert.NotNull(metric); + double sum = 0; + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) + { + sum += metricPoint.GetSumLong(); + } + else + { + sum += metricPoint.GetGaugeLastValueLong(); + break; + } + } + + return sum; } } } From 8ce78452442456a3bc44dc69237b60f6654e0b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 22 Jul 2022 19:31:54 +0200 Subject: [PATCH 0242/1499] [Instrumentation.StackExchangeRedis] mark drain thread as background (#528) --- .../CHANGELOG.md | 7 +++++-- .../StackExchangeRedisCallsInstrumentation.cs | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 756e4c9b70..8457256bb0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased -* Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.StackExchangeRedis` -[#485](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/485) +* Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.StackExchangeRedis`. +([#485](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/485)) +* Drain thread is marked as background. It allows to close the application + even if the instrumentation is not disposed. +([#528](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/528)) ## 1.0.0-rc9.6 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs index dbc3b2efb9..92eb51ec61 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs @@ -66,6 +66,7 @@ public StackExchangeRedisCallsInstrumentation(IConnectionMultiplexer connection, this.drainThread = new Thread(this.DrainEntries) { Name = "OpenTelemetry.Redis", + IsBackground = true, }; this.drainThread.Start(); From a707d57e242cc8795a972a920e026debbee5a2ad Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 25 Jul 2022 10:44:26 -0700 Subject: [PATCH 0243/1499] Update CHANGELOG for 1.0.0-beta.3 release (#529) --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 21ca39e497..e492e044af 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.3 + +Released 2022-Jul-22 + * Updated OTel SDK package version to 1.2.0 * Updated minimum full framework support to net462 * Update Google.Cloud.Monitoring.V3 2.1.0 -> 2.6.0 From b86db84ad40648dff77315dd77e5db73b94a9a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 25 Jul 2022 20:56:48 +0200 Subject: [PATCH 0244/1499] [Instrumentation.StackExchangeRedis] release 1.0.0-rc9.7 (#531) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 8457256bb0..22d6ab282a 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.7 + +Released 2022-Jul-25 + * Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.StackExchangeRedis`. ([#485](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/485)) * Drain thread is marked as background. It allows to close the application From 977bbf540226285ee4f9188d1453621e4cd909f6 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 25 Jul 2022 12:12:05 -0700 Subject: [PATCH 0245/1499] Release Runtime instrumentation version 1.0.0-rc.3 (#526) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 2eea74a65b..b5a4cd4760 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.3 + +Released 2022-Jul-21 + * Add gc.heap.fragmentation.size back for .NET 7 and later ([#524](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/524)) From ea8e2a1a34510cd0bb834254c2c8bf113f17a87f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 26 Jul 2022 13:10:05 -0700 Subject: [PATCH 0246/1499] [Instrumentation.Runtime] Update release date for 1.0.0-rc.3 (#532) * Update release date for 1.0.0-rc.3 --- .../CHANGELOG.md | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index b5a4cd4760..93c98d5ae5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -4,7 +4,7 @@ ## 1.0.0-rc.3 -Released 2022-Jul-21 +Released 2022-Jul-25 * Add gc.heap.fragmentation.size back for .NET 7 and later ([#524](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/524)) @@ -13,8 +13,9 @@ Released 2022-Jul-21 Released 2022-Jul-19 -* Refined some metrics names (assembly.count->assemblies.count, exception.count-> - exceptions.count, attribute name: gen->generation) and descriptions +* Refined some metrics names (assembly.count->assemblies.count, + exception.count-> exceptions.count, attribute name: gen->generation) and + descriptions ([#475](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/475)) * Change API for GC Heap Size for .NET 6 where the API has a bug ([#495](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/495)) @@ -25,14 +26,14 @@ Released 2022-Jul-19 Released 2022-Jun-29 -Major refactor of the runtime instrumentation. Renamed API signature and metrics. -Removed the options to turn off certain metrics. +Major refactor of the runtime instrumentation. Renamed API signature and +metrics. Removed the options to turn off certain metrics. ## 1.0.0-beta.1 -Major redesign of the runtime instrumentation. Renamed metrics to be more user-friendly -and better logical grouping. Removed the process related metrics which are not -.NET Runtime specific. +Major redesign of the runtime instrumentation. Renamed metrics to be more +user-friendly and better logical grouping. Removed the process related metrics +which are not .NET Runtime specific. ## 0.2.0-alpha.1 @@ -41,7 +42,8 @@ and better logical grouping. Removed the process related metrics which are not * Fix some bugs in Runtime metrics ([#409](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/409)) * Add GC heap size and refactor GC count as multi-dimensional metrics in Runtime - metrics ([#412](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/412)) + metrics + ([#412](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/412)) ## 0.1.0-alpha.1 From a55cbad858d9d3f578105aa01cbf90fd05deef76 Mon Sep 17 00:00:00 2001 From: yan xu <58940428+xyq175com@users.noreply.github.com> Date: Thu, 28 Jul 2022 08:39:07 +0800 Subject: [PATCH 0247/1499] [ExporterGeneva]Remove ConvertToJson option (#514) --- .../GenevaExporterOptions.cs | 24 ++++++++++++++++--- .../GenevaLogExporter.cs | 23 ------------------ .../GenevaTraceExporter.cs | 20 ---------------- .../GenevaTraceExporterTests.cs | 15 ++++++++++++ 4 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index e940366c25..c24f76a894 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -88,12 +88,30 @@ public IReadOnlyDictionary PrepopulatedFields var copy = new Dictionary(value.Count + 1) { [Schema.V40.PartA.Ver] = schemaVersion }; foreach (var entry in value) { - copy[entry.Key] = entry.Value; // shallow copy + var val = entry.Value; + switch (val) + { + case bool vb: + case byte vui8: + case sbyte vi8: + case short vi16: + case ushort vui16: + case int vi32: + case uint vui32: + case long vi64: + case ulong vui64: + case float vf: + case double vd: + case string vs: + break; + default: + throw new ArgumentException($"Type: {entry.Value.GetType()} is not supported. Only bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, and string are the supported types for PrepopulatedFields values."); + } + + copy[entry.Key] = val; // shallow copy } this._fields = copy; } } - - internal Func ConvertToJson = obj => "ERROR: GenevaExporterOptions.ConvertToJson not configured."; } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 017fc22ef7..5f7d4cdd5c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -46,7 +46,6 @@ public class GenevaLogExporter : GenevaBaseExporter private readonly IDataTransport m_dataTransport; private readonly bool shouldPassThruTableMappings; private bool isDisposed; - private Func convertToJson; public GenevaLogExporter(GenevaExporterOptions options) { @@ -108,8 +107,6 @@ public GenevaLogExporter(GenevaExporterOptions options) throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); } - this.convertToJson = options.ConvertToJson; - if (options.PrepopulatedFields != null) { this.m_prepopulatedFieldKeys = new List(); @@ -288,26 +285,6 @@ internal int SerializeLogRecord(LogRecord logRecord) { var key = this.m_prepopulatedFieldKeys[i]; var value = this.m_prepopulatedFields[key]; - switch (value) - { - case bool vb: - case byte vui8: - case sbyte vi8: - case short vi16: - case ushort vui16: - case int vi32: - case uint vui32: - case long vi64: - case ulong vui64: - case float vf: - case double vd: - case string vs: - break; - default: - value = this.convertToJson(value); - break; - } - cursor = AddPartAField(buffer, cursor, key, value); cntFields += 1; } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 72020ac2c5..4dfa3d828c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -142,26 +142,6 @@ public GenevaTraceExporter(GenevaExporterOptions options) foreach (var entry in options.PrepopulatedFields) { var value = entry.Value; - switch (value) - { - case bool vb: - case byte vui8: - case sbyte vi8: - case short vi16: - case ushort vui16: - case int vi32: - case uint vui32: - case long vi64: - case ulong vui64: - case float vf: - case double vd: - case string vs: - break; - default: - value = options.ConvertToJson(value); - break; - } - cursor = AddPartAField(buffer, cursor, entry.Key, value); this.m_cntPrepopulatedFields += 1; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 5c49219c5b..cf4b58bd6b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -53,6 +53,21 @@ public void GenevaTraceExporter_constructor_Invalid_Input() ConnectionString = null, }); }); + + // unsupported types(char) for PrepopulatedFields + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = (char)106, + }, + }); + }); } [Fact] From 551c960424344c70e2cbd3430620726889e6803b Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 27 Jul 2022 18:08:53 -0700 Subject: [PATCH 0248/1499] [Exporter.Geneva] Add data validation for MetricExportIntervalMilliseconds (#527) --- .../GenevaMetricExporterOptions.cs | 16 +++++++++++++- .../GenevaMetricExporterOptionsTests.cs | 22 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs index 5d406e0f3c..8009f98879 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs @@ -24,6 +24,7 @@ namespace OpenTelemetry.Exporter.Geneva; public class GenevaMetricExporterOptions { private IReadOnlyDictionary _prepopulatedMetricDimensions; + private int _metricExporterIntervalMilliseconds = 20000; /// /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. @@ -34,7 +35,20 @@ public class GenevaMetricExporterOptions /// /// Gets or sets the metric export interval in milliseconds. The default value is 20000. /// - public int MetricExportIntervalMilliseconds { get; set; } = 20000; + public int MetricExportIntervalMilliseconds + { + get + { + return this._metricExporterIntervalMilliseconds; + } + + set + { + Guard.ThrowIfOutOfRange(value, min: 1000); + + this._metricExporterIntervalMilliseconds = value; + } + } /// /// Gets or sets the pre-populated dimensions for all the metrics exported by the exporter. diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index 6d615b6dff..9b0fb22a50 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -69,5 +69,27 @@ [new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)] = "DimensionVal expectedErrorMessage = $"Value provided for the dimension: DimensionKey exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."; Assert.Equal(expectedErrorMessage, invalidDimensionValueException.Message); } + + [Fact] + public void MetricExportIntervalValidationTest() + { + Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions + { + MetricExportIntervalMilliseconds = 999, + }; + }); + + var exception = Record.Exception(() => + { + var exporterOptions = new GenevaMetricExporterOptions + { + MetricExportIntervalMilliseconds = 1000, + }; + }); + + Assert.Null(exception); + } } } From 08a1f4db50a35be356400697b0470c86a60f3a8d Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 27 Jul 2022 19:38:35 -0700 Subject: [PATCH 0249/1499] Fix bugs in the GenevaExporter PrepopulatedField handling (#537) --- .../GenevaExporterOptions.cs | 7 ++++++- .../GenevaTraceExporterTests.cs | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index c24f76a894..809f08d214 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -105,7 +105,12 @@ public IReadOnlyDictionary PrepopulatedFields case string vs: break; default: - throw new ArgumentException($"Type: {entry.Value.GetType()} is not supported. Only bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, and string are the supported types for PrepopulatedFields values."); + if (entry.Value == null) + { + throw new ArgumentNullException(entry.Key, $"{nameof(this.PrepopulatedFields)} must not contain null values."); + } + + throw new ArgumentException($"Type `{entry.Value.GetType()}` (key = `{entry.Key}`) is not allowed. Only bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, and string are supported."); } copy[entry.Key] = val; // shallow copy diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index cf4b58bd6b..7ebfa8b279 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -54,6 +54,19 @@ public void GenevaTraceExporter_constructor_Invalid_Input() }); }); + // null value in the PrepopulatedFields + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["cloud.roleVer"] = null, + }, + }); + }); + // unsupported types(char) for PrepopulatedFields Assert.Throws(() => { From c9f0532a3b0fbb99d108f40e49c29438e5d34825 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 27 Jul 2022 20:10:27 -0700 Subject: [PATCH 0250/1499] [Exporter.Geneva] Simplify exporter options for PrepopulatedFields (#538) --- .../GenevaExporterOptions.cs | 31 +++++++++---------- .../GenevaTraceExporterTests.cs | 26 ++++++++++++++++ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 809f08d214..9664117af3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -91,25 +91,22 @@ public IReadOnlyDictionary PrepopulatedFields var val = entry.Value; switch (val) { - case bool vb: - case byte vui8: - case sbyte vi8: - case short vi16: - case ushort vui16: - case int vi32: - case uint vui32: - case long vi64: - case ulong vui64: - case float vf: - case double vd: - case string vs: + case bool: + case byte: + case sbyte: + case short: + case ushort: + case int: + case uint: + case long: + case ulong: + case float: + case double: + case string: break; + case null: + throw new ArgumentNullException(entry.Key, $"{nameof(this.PrepopulatedFields)} must not contain null values."); default: - if (entry.Value == null) - { - throw new ArgumentNullException(entry.Key, $"{nameof(this.PrepopulatedFields)} must not contain null values."); - } - throw new ArgumentException($"Type `{entry.Value.GetType()}` (key = `{entry.Key}`) is not allowed. Only bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, and string are supported."); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 7ebfa8b279..ba3929e81e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -81,6 +81,32 @@ public void GenevaTraceExporter_constructor_Invalid_Input() }, }); }); + + // Supported types for PrepopulatedFields should not throw an exception + var exception = Record.Exception(() => + { + new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["bool"] = true, + ["byte"] = byte.MaxValue, + ["sbyte"] = sbyte.MaxValue, + ["short"] = short.MaxValue, + ["ushort"] = ushort.MaxValue, + ["int"] = int.MaxValue, + ["uint"] = uint.MaxValue, + ["long"] = long.MaxValue, + ["ulong"] = ulong.MaxValue, + ["float"] = float.MaxValue, + ["double"] = double.MaxValue, + ["string"] = string.Empty, + }, + }; + }); + + Assert.Null(exception); } [Fact] From d6dd670a29d55284173df25d6aff41373613f7cf Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 27 Jul 2022 21:01:06 -0700 Subject: [PATCH 0251/1499] Update CHANGELOG (#539) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 66bf8e7480..8d94ff5951 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -20,6 +20,17 @@ by throwing any exception caught by `UnixDomainSocketDataTransport.Send` so that `ExportResult.Failure`. [444](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/444) +* The option `PrepopulatedFields` of `GenevaExporterOptions` will only support +values of type: `bool`, `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, +`long`, `ulong`, `float`, `double`, and `string`. It will also not accept `null` +values. +[514](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/514) +[537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/537) + +* The option `MetricExportIntervalMilliseconds` of `GenevaMetricExporterOptions` +will not accept a value less than 1000. +[527](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/527) + ## 1.3.0-beta.2 Released 2022-Jun-03 From 47637aa4e3d9424cbd517c7c8bc512fa8e1bd081 Mon Sep 17 00:00:00 2001 From: Igor Kiselev Date: Thu, 28 Jul 2022 11:59:34 -0700 Subject: [PATCH 0252/1499] Changed owner for OpenTelemetry.Extensions.Docker (#540) --- .github/component_owners.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 11a9f2e73c..5ef6a939e6 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -21,7 +21,7 @@ components: src/OpenTelemetry.Extensions/: - codeblanch src/OpenTelemetry.Extensions.Docker/: - - swetharavichandrancisco + - iskiselev src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/: - vishweshbankwar src/OpenTelemetry.Extensions.PersistentStorage/: From 5b6b33b185296fbb888a717808039bc9e1ce4505 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 28 Jul 2022 15:30:07 -0700 Subject: [PATCH 0253/1499] [Instrumentation.AWSLambda] Add component owners for AWSLambda (#530) * Add component owners for AWSLambda --- .github/component_owners.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 5ef6a939e6..784f2b419e 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -7,6 +7,9 @@ components: - lupengamzn src/OpenTelemetry.Contrib.Instrumentation.AWS/: - srprash + src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/: + - rypdal + - Oberon00 src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch @@ -52,6 +55,9 @@ components: - lupengamzn test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/: - srprash + test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/: + - rypdal + - Oberon00 test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch From a0658279495309dc95679fe1a457b3bae22069c1 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 28 Jul 2022 15:52:23 -0700 Subject: [PATCH 0254/1499] [Exporter.Geneva] Remove scopes (#541) --- .../CHANGELOG.md | 4 + .../GenevaLogExporter.cs | 38 ------ .../GenevaLogExporterTests.cs | 111 ------------------ 3 files changed, 4 insertions(+), 149 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 8d94ff5951..b4c7ae7215 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -31,6 +31,10 @@ values. will not accept a value less than 1000. [527](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/527) +* Remove support for exporting `ILogger` scopes that was added in `1.3.0-beta.2` +version. +[541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/541) + ## 1.3.0-beta.2 Released 2022-Jun-03 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 5f7d4cdd5c..b074947b49 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -390,44 +390,6 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; } - ushort scopeDepth = 0; - int indexArrayLength = 0; - logRecord.ForEachScope(ProcessScope, (object)null); - void ProcessScope(LogRecordScope scope, object state) - { - if (++scopeDepth == 1) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "scopes"); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); - indexArrayLength = cursor - 2; - } - - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int indexMapSizeScope = cursor - 2; - ushort keysCount = 0; - - foreach (KeyValuePair scopeItem in scope) - { - string key = "scope"; - if (!string.IsNullOrEmpty(scopeItem.Key)) - { - key = scopeItem.Key; - } - - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); - keysCount++; - } - - MessagePackSerializer.WriteUInt16(buffer, indexMapSizeScope, keysCount); - } - - if (scopeDepth > 0) - { - MessagePackSerializer.WriteUInt16(buffer, indexArrayLength, scopeDepth); - cntFields += 1; - } - if (hasEnvProperties) { // Iteration #2 - Get all "other" fields and collapse them into single field diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index eacb679eba..c665fe85d2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -351,117 +351,6 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() } } - [Fact] - public void SerializeILoggerScopes() - { - string path = string.Empty; - Socket senderSocket = null; - Socket receiverSocket = null; - try - { - var exporterOptions = new GenevaExporterOptions(); - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - senderSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - senderSocket.Bind(endpoint); - senderSocket.Listen(1); - } - - using var loggerFactory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(options => - { - options.IncludeScopes = true; - options.AddGenevaLogExporter(options => - { - options.ConnectionString = exporterOptions.ConnectionString; - }); - })); - - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - receiverSocket = senderSocket.Accept(); - receiverSocket.ReceiveTimeout = 10000; - } - - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); - - // Emit a LogRecord and grab a copy of internal buffer for validation. - var logger = loggerFactory.CreateLogger(); - - using (logger.BeginScope("MyOuterScope")) - using (logger.BeginScope("MyInnerScope")) - using (logger.BeginScope("MyInnerInnerScope with {name} and {age} of custom", "John Doe", 35)) - using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) - { - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - } - - byte[] serializedData; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - serializedData = m_buffer.Value; - } - else - { - // Read the data sent via socket. - serializedData = new byte[65360]; - _ = receiverSocket.Receive(serializedData); - } - - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - var signal = (fluentdData as object[])[0] as string; - var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; - var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - var serializedScopes = mapping["scopes"] as object[]; - - Assert.Equal(4, serializedScopes.Length); - - // Test 1st scope - var scope = serializedScopes[0] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("scope", "MyOuterScope"), scope); - - // Test 2nd scope - scope = serializedScopes[1] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("scope", "MyInnerScope"), scope); - - // Test 3rd scope - scope = serializedScopes[2] as ICollection>; - Assert.Equal(3, scope.Count); - Assert.Contains(new KeyValuePair("name", "John Doe"), scope); - Assert.Contains(new KeyValuePair("age", (byte)35), scope); - Assert.Contains(new KeyValuePair("{OriginalFormat}", "MyInnerInnerScope with {name} and {age} of custom"), scope); - - // Test 4th scope - scope = serializedScopes[3] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("MyKey", "MyValue"), scope); - } - finally - { - senderSocket?.Dispose(); - receiverSocket?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } - } - } - [Theory] [InlineData(true)] [InlineData(false)] From 19f44ade6aa9cb104dac19b43500eb1a5888ee72 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 28 Jul 2022 16:01:51 -0700 Subject: [PATCH 0255/1499] Update CHANGELOG for 1.3.0 release (#542) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index b4c7ae7215..ced48e87cc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.3.0 + +Released 2022-Jul-28 + * Supports `OpenTelemetry.Extensions.Hosting` based configuration for `GenevaMetricExporter`. [397](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/397) From a69fbd06d226289ad5c773fcc2bafbdb8e0e24f1 Mon Sep 17 00:00:00 2001 From: Igor Kiselev Date: Thu, 28 Jul 2022 18:56:36 -0700 Subject: [PATCH 0256/1499] [Extensions.Docker] Update CHANGELOG for 1.0.0-beta.1 release (#543) --- .../CHANGELOG.md | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md index 7bb1594dee..638666430a 100644 --- a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md @@ -1,12 +1,13 @@ -# Changelog - OpenTelemetry.Extensions.Docker - -This is the first release for the `OpenTelemetry.Extensions.Docker` project. -The release targets -[OpenTelemetry.Extensions.Docker](https://www.nuget.org/packages/OpenTelemetry.Extensions.Docker/). -The project targets 1.2.0 of the [OpenTelemetry -SDK](https://www.nuget.org/packages/OpenTelemetry/). - -The Docker extensions include plugin to extract resource detectors -from docker environment (container id). For more details, -please refer to the -[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Extensions.Docker/README.md) +# Changelog + +## Unreleased + +## 1.0.0-beta.1 + +Released 2022-Jul-28 + +* Targets 1.3.0 of the OpenTelemetry-SDK, net6.0 build added. +[432](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/432) + +* Initial release of `OpenTelemetry.Extensions.Docker` project +[206](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/206) From 694512ade3ba7a840f6591964221f76ad6a2a09c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 29 Jul 2022 07:56:10 -0700 Subject: [PATCH 0257/1499] Update component owners file (#544) --- .github/component_owners.yml | 9 +++++---- opentelemetry-dotnet-contrib.sln | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 784f2b419e..969e074b50 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -1,6 +1,7 @@ # This file is used by .github/workflows/assign-reviewers.yml # Each component identified by its path prefix has a list of users +# Please add the entries in alphabetically sorted order components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash @@ -31,6 +32,8 @@ components: - vishweshbankwar src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith + src/OpenTelemetry.Instrumentation.EventCounters/: + - hananiel src/OpenTelemetry.Instrumentation.GrpcCore/: - pcwiese src/OpenTelemetry.Instrumentation.Hangfire/: @@ -48,8 +51,6 @@ components: - xiang17 src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch - src/OpenTelemetry.Instrumentation.EventCounters/: - - hananiel test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn @@ -91,6 +92,8 @@ components: - vishweshbankwar test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith + test/OpenTelemetry.Instrumentation.EventCounters.Tests/: + - hananiel test/OpenTelemetry.Instrumentation.GrpcCore.Tests/: - pcwiese test/OpenTelemetry.Instrumentation.Hangfire.Tests/: @@ -108,5 +111,3 @@ components: - xiang17 test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch - test/OpenTelemetry.Instrumentation.EventCounters.Tests/: - - hananiel diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6380291c2b..977168caf3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -35,6 +35,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml + .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml @@ -44,6 +45,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml + .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml From e09211469ec38ced7cfa97e331b0751a2b2beaa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 29 Jul 2022 20:14:33 +0200 Subject: [PATCH 0258/1499] Unify test packages (#548) --- build/Common.nonprod.props | 2 +- build/Common.props | 2 +- build/process-codecoverage.ps1 | 2 +- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 6 +++--- .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 4 ++-- ...lemetry.Instrumentation.ElasticsearchClient.Tests.csproj | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index e4c6818fc7..6b4934f225 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -24,7 +24,7 @@ [3.1.2,4.0.0) [2.3.1,3.0) [5.0,6.0) - [16.7.1,17.0) + [16.11.0,17.0) [4.17.2,5.0) $(OpenTelemetryPkgVer) [2.4.3,3.0) diff --git a/build/Common.props b/build/Common.props index cb3e4661a5..e7c6a6b2e7 100644 --- a/build/Common.props +++ b/build/Common.props @@ -24,7 +24,7 @@ --> [2.4.0,3.0) [6.0.0] - [16.7.1] + [16.11.0] [2.1.0,5.0) [3.1.0,) [1.0.0,2.0) diff --git a/build/process-codecoverage.ps1 b/build/process-codecoverage.ps1 index 3d29cbc98e..33e35e431e 100644 --- a/build/process-codecoverage.ps1 +++ b/build/process-codecoverage.ps1 @@ -2,7 +2,7 @@ Write-Host $env:USERPROFILE foreach ($file in $files) { - $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\16.7.1\build\netstandard1.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName + $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\16.11.0\build\netstandard1.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName Write-Host $command Invoke-Expression $command } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index e09f2f25da..a08c3fc4e3 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -5,10 +5,10 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 8a51781e5b..1298131090 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -5,12 +5,12 @@ - + - + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 8e230718e9..447f50b606 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -9,11 +9,11 @@ - + all runtime; build; native; contentfiles; analyzers - + From d891c91efe4aed65ae83cf07748cc7b52ed04093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 29 Jul 2022 20:29:00 +0200 Subject: [PATCH 0259/1499] File Scoped namespaces for Shared project (#547) Co-authored-by: Utkarsh Umesan Pillai --- .../Api/ActivityHelperExtensions.cs | 473 +++++++++--------- .../Api/EnumerationHelper.cs | 221 ++++---- .../Api/ExceptionExtensions.cs | 39 +- .../Api/IActivityEnumerator.cs | 23 +- .../Api/SemanticConventions.cs | 167 +++---- .../Api/SpanAttributeConstants.cs | 19 +- .../Api/SpanHelper.cs | 69 ++- .../Api/StatusHelper.cs | 71 ++- .../ActivityInstrumentationHelper.cs | 37 +- .../DiagnosticSourceListener.cs | 69 ++- .../DiagnosticSourceSubscriber.cs | 137 +++-- .../InstrumentationEventSource.cs | 47 +- .../ListenerHandler.cs | 103 ++-- .../MultiTypePropertyFetcher.cs | 139 +++-- .../PropertyFetcher.cs | 159 +++--- .../ServiceProviderExtensions.cs | 33 +- .../EventSourceTestHelper.cs | 169 ++++--- .../InMemoryEventListener.cs | 23 +- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 31 +- .../TestActivityExportProcessor.cs | 23 +- .../TestActivityProcessor.cs | 75 ++- .../TestEventListener.cs | 117 +++-- .../TestExporter.cs | 27 +- .../TestSampler.cs | 19 +- 24 files changed, 1133 insertions(+), 1157 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs index cdd5d92cd0..7fdcdefc14 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs @@ -20,313 +20,312 @@ using System.Runtime.CompilerServices; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods on Activity. +/// +internal static class ActivityHelperExtensions { /// - /// Extension methods on Activity. + /// 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. /// - internal static class ActivityHelperExtensions + /// Activity instance. + /// . + /// Status description. + /// if was found on the supplied Activity. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static bool TryGetStatus(this Activity activity, out StatusCode statusCode, out string statusDescription) { - /// - /// 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. - /// - /// Activity instance. - /// . - /// Status description. - /// if was found on the supplied Activity. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static bool TryGetStatus(this Activity activity, out StatusCode statusCode, out string statusDescription) + Debug.Assert(activity != null, "Activity should not be null"); + + ActivityStatusTagEnumerator state = default; + + ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); + + if (!state.StatusCode.HasValue) { - Debug.Assert(activity != null, "Activity should not be null"); + statusCode = default; + statusDescription = null; + return false; + } - ActivityStatusTagEnumerator state = default; + statusCode = state.StatusCode.Value; + statusDescription = state.StatusDescription; + return true; + } - ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); + /// + /// Gets the value of a specific tag on an . + /// + /// Activity instance. + /// Case-sensitive tag name to retrieve. + /// Tag value or null if a match was not found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static object GetTagValue(this Activity activity, string tagName) + { + Debug.Assert(activity != null, "Activity should not be null"); - if (!state.StatusCode.HasValue) - { - statusCode = default; - statusDescription = null; - return false; - } + ActivitySingleTagEnumerator state = new ActivitySingleTagEnumerator(tagName); - statusCode = state.StatusCode.Value; - statusDescription = state.StatusDescription; - return true; - } + ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); - /// - /// Gets the value of a specific tag on an . - /// - /// Activity instance. - /// Case-sensitive tag name to retrieve. - /// Tag value or null if a match was not found. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static object GetTagValue(this Activity activity, string tagName) - { - Debug.Assert(activity != null, "Activity should not be null"); + return state.Value; + } - ActivitySingleTagEnumerator state = new ActivitySingleTagEnumerator(tagName); + /// + /// Enumerates all the key/value pairs on an without performing an allocation. + /// + /// The struct implementation to use for the enumeration. + /// Activity instance. + /// Tag enumerator. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static void EnumerateTags(this Activity activity, ref T tagEnumerator) + where T : struct, IActivityEnumerator> + { + Debug.Assert(activity != null, "Activity should not be null"); - ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); + ActivityTagsEnumeratorFactory.Enumerate(activity, ref tagEnumerator); + } - return state.Value; - } + /// + /// Enumerates all the s on an without performing an allocation. + /// + /// The struct implementation to use for the enumeration. + /// Activity instance. + /// Link enumerator. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static void EnumerateLinks(this Activity activity, ref T linkEnumerator) + where T : struct, IActivityEnumerator + { + Debug.Assert(activity != null, "Activity should not be null"); - /// - /// Enumerates all the key/value pairs on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// Activity instance. - /// Tag enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateTags(this Activity activity, ref T tagEnumerator) - where T : struct, IActivityEnumerator> - { - Debug.Assert(activity != null, "Activity should not be null"); + ActivityLinksEnumeratorFactory.Enumerate(activity, ref linkEnumerator); + } - ActivityTagsEnumeratorFactory.Enumerate(activity, ref tagEnumerator); - } + /// + /// Enumerates all the key/value pairs on an without performing an allocation. + /// + /// The struct implementation to use for the enumeration. + /// ActivityLink instance. + /// Tag enumerator. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static void EnumerateTags(this ActivityLink activityLink, ref T tagEnumerator) + where T : struct, IActivityEnumerator> + { + ActivityTagsEnumeratorFactory.Enumerate(activityLink, ref tagEnumerator); + } - /// - /// Enumerates all the s on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// Activity instance. - /// Link enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateLinks(this Activity activity, ref T linkEnumerator) - where T : struct, IActivityEnumerator - { - Debug.Assert(activity != null, "Activity should not be null"); + /// + /// Enumerates all the s on an without performing an allocation. + /// + /// The struct implementation to use for the enumeration. + /// Activity instance. + /// Event enumerator. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static void EnumerateEvents(this Activity activity, ref T eventEnumerator) + where T : struct, IActivityEnumerator + { + Debug.Assert(activity != null, "Activity should not be null"); - ActivityLinksEnumeratorFactory.Enumerate(activity, ref linkEnumerator); - } + ActivityEventsEnumeratorFactory.Enumerate(activity, ref eventEnumerator); + } - /// - /// Enumerates all the key/value pairs on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// ActivityLink instance. - /// Tag enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateTags(this ActivityLink activityLink, ref T tagEnumerator) - where T : struct, IActivityEnumerator> - { - ActivityTagsEnumeratorFactory.Enumerate(activityLink, ref tagEnumerator); - } + /// + /// Enumerates all the key/value pairs on an without performing an allocation. + /// + /// The struct implementation to use for the enumeration. + /// ActivityEvent instance. + /// Tag enumerator. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] + public static void EnumerateTags(this ActivityEvent activityEvent, ref T tagEnumerator) + where T : struct, IActivityEnumerator> + { + ActivityTagsEnumeratorFactory.Enumerate(activityEvent, ref tagEnumerator); + } - /// - /// Enumerates all the s on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// Activity instance. - /// Event enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateEvents(this Activity activity, ref T eventEnumerator) - where T : struct, IActivityEnumerator - { - Debug.Assert(activity != null, "Activity should not be null"); + private struct ActivitySingleTagEnumerator : IActivityEnumerator> + { + public object Value; - ActivityEventsEnumeratorFactory.Enumerate(activity, ref eventEnumerator); - } + private readonly string tagName; - /// - /// Enumerates all the key/value pairs on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// ActivityEvent instance. - /// Tag enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateTags(this ActivityEvent activityEvent, ref T tagEnumerator) - where T : struct, IActivityEnumerator> + public ActivitySingleTagEnumerator(string tagName) { - ActivityTagsEnumeratorFactory.Enumerate(activityEvent, ref tagEnumerator); + this.tagName = tagName; + this.Value = null; } - private struct ActivitySingleTagEnumerator : IActivityEnumerator> + public bool ForEach(KeyValuePair item) { - public object Value; - - private readonly string tagName; - - public ActivitySingleTagEnumerator(string tagName) + if (item.Key == this.tagName) { - this.tagName = tagName; - this.Value = null; + this.Value = item.Value; + return false; } - public bool ForEach(KeyValuePair item) - { - if (item.Key == this.tagName) - { - this.Value = item.Value; - return false; - } - - return true; - } + return true; } + } - private struct ActivityStatusTagEnumerator : IActivityEnumerator> - { - public StatusCode? StatusCode; + private struct ActivityStatusTagEnumerator : IActivityEnumerator> + { + public StatusCode? StatusCode; - public string StatusDescription; + public string StatusDescription; - public bool ForEach(KeyValuePair item) + public bool ForEach(KeyValuePair item) + { + switch (item.Key) { - switch (item.Key) - { - case SpanAttributeConstants.StatusCodeKey: - this.StatusCode = StatusHelper.GetStatusCodeForTagValue(item.Value as string); - break; - case SpanAttributeConstants.StatusDescriptionKey: - this.StatusDescription = item.Value as string; - break; - } - - return !this.StatusCode.HasValue || this.StatusDescription == null; + case SpanAttributeConstants.StatusCodeKey: + this.StatusCode = StatusHelper.GetStatusCodeForTagValue(item.Value as string); + break; + case SpanAttributeConstants.StatusDescriptionKey: + this.StatusDescription = item.Value as string; + break; } - } - private static class ActivityTagsEnumeratorFactory - where TState : struct, IActivityEnumerator> - { - private static readonly object EmptyActivityTagObjects = typeof(Activity).GetField("s_emptyTagObjects", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); + return !this.StatusCode.HasValue || this.StatusDescription == null; + } + } - private static readonly object EmptyActivityEventTags = typeof(ActivityEvent).GetField("s_emptyTags", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); + private static class ActivityTagsEnumeratorFactory + where TState : struct, IActivityEnumerator> + { + private static readonly object EmptyActivityTagObjects = typeof(Activity).GetField("s_emptyTagObjects", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate - ActivityTagObjectsEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate( - typeof(Activity).GetField("_tags", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); + private static readonly object EmptyActivityEventTags = typeof(ActivityEvent).GetField("s_emptyTags", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate - ActivityTagsCollectionEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate(typeof(ActivityTagsCollection)); + private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate + ActivityTagObjectsEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate( + typeof(Activity).GetField("_tags", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - private static readonly DictionaryEnumerator.ForEachDelegate ForEachTagValueCallbackRef = ForEachTagValueCallback; + private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate + ActivityTagsCollectionEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate(typeof(ActivityTagsCollection)); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(Activity activity, ref TState state) - { - var tagObjects = activity.TagObjects; + private static readonly DictionaryEnumerator.ForEachDelegate ForEachTagValueCallbackRef = ForEachTagValueCallback; - if (ReferenceEquals(tagObjects, EmptyActivityTagObjects)) - { - return; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Enumerate(Activity activity, ref TState state) + { + var tagObjects = activity.TagObjects; - ActivityTagObjectsEnumerator( - tagObjects, - ref state, - ForEachTagValueCallbackRef); + if (ReferenceEquals(tagObjects, EmptyActivityTagObjects)) + { + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(ActivityLink activityLink, ref TState state) - { - var tags = activityLink.Tags; + ActivityTagObjectsEnumerator( + tagObjects, + ref state, + ForEachTagValueCallbackRef); + } - if (tags is null) - { - return; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Enumerate(ActivityLink activityLink, ref TState state) + { + var tags = activityLink.Tags; - ActivityTagsCollectionEnumerator( - tags, - ref state, - ForEachTagValueCallbackRef); + if (tags is null) + { + return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(ActivityEvent activityEvent, ref TState state) - { - var tags = activityEvent.Tags; + ActivityTagsCollectionEnumerator( + tags, + ref state, + ForEachTagValueCallbackRef); + } - if (ReferenceEquals(tags, EmptyActivityEventTags)) - { - return; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Enumerate(ActivityEvent activityEvent, ref TState state) + { + var tags = activityEvent.Tags; - ActivityTagsCollectionEnumerator( - tags, - ref state, - ForEachTagValueCallbackRef); + if (ReferenceEquals(tags, EmptyActivityEventTags)) + { + return; } - private static bool ForEachTagValueCallback(ref TState state, KeyValuePair item) - => state.ForEach(item); + ActivityTagsCollectionEnumerator( + tags, + ref state, + ForEachTagValueCallbackRef); } - private static class ActivityLinksEnumeratorFactory - where TState : struct, IActivityEnumerator - { - private static readonly object EmptyActivityLinks = typeof(Activity).GetField("s_emptyLinks", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); + private static bool ForEachTagValueCallback(ref TState state, KeyValuePair item) + => state.ForEach(item); + } - private static readonly ListEnumerator.AllocationFreeForEachDelegate - ActivityLinksEnumerator = ListEnumerator.BuildAllocationFreeForEachDelegate( - typeof(Activity).GetField("_links", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); + private static class ActivityLinksEnumeratorFactory + where TState : struct, IActivityEnumerator + { + private static readonly object EmptyActivityLinks = typeof(Activity).GetField("s_emptyLinks", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - private static readonly ListEnumerator.ForEachDelegate ForEachLinkCallbackRef = ForEachLinkCallback; + private static readonly ListEnumerator.AllocationFreeForEachDelegate + ActivityLinksEnumerator = ListEnumerator.BuildAllocationFreeForEachDelegate( + typeof(Activity).GetField("_links", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(Activity activity, ref TState state) - { - var activityLinks = activity.Links; + private static readonly ListEnumerator.ForEachDelegate ForEachLinkCallbackRef = ForEachLinkCallback; - if (ReferenceEquals(activityLinks, EmptyActivityLinks)) - { - return; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Enumerate(Activity activity, ref TState state) + { + var activityLinks = activity.Links; - ActivityLinksEnumerator( - activityLinks, - ref state, - ForEachLinkCallbackRef); + if (ReferenceEquals(activityLinks, EmptyActivityLinks)) + { + return; } - private static bool ForEachLinkCallback(ref TState state, ActivityLink item) - => state.ForEach(item); + ActivityLinksEnumerator( + activityLinks, + ref state, + ForEachLinkCallbackRef); } - private static class ActivityEventsEnumeratorFactory - where TState : struct, IActivityEnumerator - { - private static readonly object EmptyActivityEvents = typeof(Activity).GetField("s_emptyEvents", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); + private static bool ForEachLinkCallback(ref TState state, ActivityLink item) + => state.ForEach(item); + } - private static readonly ListEnumerator.AllocationFreeForEachDelegate - ActivityEventsEnumerator = ListEnumerator.BuildAllocationFreeForEachDelegate( - typeof(Activity).GetField("_events", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); + private static class ActivityEventsEnumeratorFactory + where TState : struct, IActivityEnumerator + { + private static readonly object EmptyActivityEvents = typeof(Activity).GetField("s_emptyEvents", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - private static readonly ListEnumerator.ForEachDelegate ForEachEventCallbackRef = ForEachEventCallback; + private static readonly ListEnumerator.AllocationFreeForEachDelegate + ActivityEventsEnumerator = ListEnumerator.BuildAllocationFreeForEachDelegate( + typeof(Activity).GetField("_events", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(Activity activity, ref TState state) - { - var activityEvents = activity.Events; + private static readonly ListEnumerator.ForEachDelegate ForEachEventCallbackRef = ForEachEventCallback; - if (ReferenceEquals(activityEvents, EmptyActivityEvents)) - { - return; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Enumerate(Activity activity, ref TState state) + { + var activityEvents = activity.Events; - ActivityEventsEnumerator( - activityEvents, - ref state, - ForEachEventCallbackRef); + if (ReferenceEquals(activityEvents, EmptyActivityEvents)) + { + return; } - private static bool ForEachEventCallback(ref TState state, ActivityEvent item) - => state.ForEach(item); + ActivityEventsEnumerator( + activityEvents, + ref state, + ForEachEventCallbackRef); } + + private static bool ForEachEventCallback(ref TState state, ActivityEvent item) + => state.ForEach(item); } } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs index 0c9abc43c9..dbae60c27d 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs @@ -20,161 +20,160 @@ using System.Reflection; using System.Reflection.Emit; -namespace OpenTelemetry.Internal +namespace OpenTelemetry.Internal; + +internal class DictionaryEnumerator : Enumerator +>, + KeyValuePair, + TState> + where TState : struct { - internal class DictionaryEnumerator : Enumerator - >, - KeyValuePair, - TState> - where TState : struct + protected DictionaryEnumerator() { - protected DictionaryEnumerator() - { - } } +} - internal class ListEnumerator : Enumerator - , - TValue, - TState> - where TState : struct +internal class ListEnumerator : Enumerator +, + TValue, + TState> + where TState : struct +{ + protected ListEnumerator() { - protected ListEnumerator() - { - } } +} - // A helper class for enumerating over IEnumerable without allocation if a struct enumerator is available. - internal class Enumerator - where TEnumerable : IEnumerable - where TState : struct - { - private static readonly MethodInfo GenericGetEnumeratorMethod = typeof(IEnumerable).GetMethod("GetEnumerator"); - private static readonly MethodInfo GeneircCurrentGetMethod = typeof(IEnumerator).GetProperty("Current").GetMethod; - private static readonly MethodInfo MoveNextMethod = typeof(IEnumerator).GetMethod("MoveNext"); - private static readonly MethodInfo DisposeMethod = typeof(IDisposable).GetMethod("Dispose"); +// A helper class for enumerating over IEnumerable without allocation if a struct enumerator is available. +internal class Enumerator + where TEnumerable : IEnumerable + where TState : struct +{ + private static readonly MethodInfo GenericGetEnumeratorMethod = typeof(IEnumerable).GetMethod("GetEnumerator"); + private static readonly MethodInfo GeneircCurrentGetMethod = typeof(IEnumerator).GetProperty("Current").GetMethod; + private static readonly MethodInfo MoveNextMethod = typeof(IEnumerator).GetMethod("MoveNext"); + private static readonly MethodInfo DisposeMethod = typeof(IDisposable).GetMethod("Dispose"); - public delegate void AllocationFreeForEachDelegate(TEnumerable instance, ref TState state, ForEachDelegate itemCallback); + public delegate void AllocationFreeForEachDelegate(TEnumerable instance, ref TState state, ForEachDelegate itemCallback); - public delegate bool ForEachDelegate(ref TState state, TItem item); + public delegate bool ForEachDelegate(ref TState state, TItem item); - protected Enumerator() - { - } + protected Enumerator() + { + } - /* We want to do this type of logic... - public static void AllocationFreeForEach(Dictionary dictionary, ref TState state, ForEachDelegate itemCallback) + /* We want to do this type of logic... + public static void AllocationFreeForEach(Dictionary dictionary, ref TState state, ForEachDelegate itemCallback) + { + using (Dictionary.Enumerator enumerator = dictionary.GetEnumerator()) { - using (Dictionary.Enumerator enumerator = dictionary.GetEnumerator()) + while (enumerator.MoveNext()) { - while (enumerator.MoveNext()) - { - if (!itemCallback(ref state, enumerator.Current)) - break; - } + if (!itemCallback(ref state, enumerator.Current)) + break; } } - ...because it takes advantage of the struct Enumerator on the built-in types which give an allocation-free way to enumerate. - */ - public static AllocationFreeForEachDelegate BuildAllocationFreeForEachDelegate(Type enumerableType) - { - var itemCallbackType = typeof(ForEachDelegate); + } + ...because it takes advantage of the struct Enumerator on the built-in types which give an allocation-free way to enumerate. + */ + public static AllocationFreeForEachDelegate BuildAllocationFreeForEachDelegate(Type enumerableType) + { + var itemCallbackType = typeof(ForEachDelegate); - var getEnumeratorMethod = ResolveGetEnumeratorMethodForType(enumerableType); - if (getEnumeratorMethod == null) - { - // Fallback to allocation mode and use IEnumerable.GetEnumerator. - // Primarily for Array.Empty and Enumerable.Empty case, but also for user types. - getEnumeratorMethod = GenericGetEnumeratorMethod; - } + var getEnumeratorMethod = ResolveGetEnumeratorMethodForType(enumerableType); + if (getEnumeratorMethod == null) + { + // Fallback to allocation mode and use IEnumerable.GetEnumerator. + // Primarily for Array.Empty and Enumerable.Empty case, but also for user types. + getEnumeratorMethod = GenericGetEnumeratorMethod; + } - var enumeratorType = getEnumeratorMethod.ReturnType; + var enumeratorType = getEnumeratorMethod.ReturnType; - var dynamicMethod = new DynamicMethod( - nameof(AllocationFreeForEachDelegate), - null, - new[] { typeof(TEnumerable), typeof(TState).MakeByRefType(), itemCallbackType }, - typeof(AllocationFreeForEachDelegate).Module, - skipVisibility: true); + var dynamicMethod = new DynamicMethod( + nameof(AllocationFreeForEachDelegate), + null, + new[] { typeof(TEnumerable), typeof(TState).MakeByRefType(), itemCallbackType }, + typeof(AllocationFreeForEachDelegate).Module, + skipVisibility: true); - var generator = dynamicMethod.GetILGenerator(); + var generator = dynamicMethod.GetILGenerator(); - generator.DeclareLocal(enumeratorType); + generator.DeclareLocal(enumeratorType); - var beginLoopLabel = generator.DefineLabel(); - var processCurrentLabel = generator.DefineLabel(); - var returnLabel = generator.DefineLabel(); - var breakLoopLabel = generator.DefineLabel(); + var beginLoopLabel = generator.DefineLabel(); + var processCurrentLabel = generator.DefineLabel(); + var returnLabel = generator.DefineLabel(); + var breakLoopLabel = generator.DefineLabel(); - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Callvirt, getEnumeratorMethod); - generator.Emit(OpCodes.Stloc_0); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Callvirt, getEnumeratorMethod); + generator.Emit(OpCodes.Stloc_0); - // try - generator.BeginExceptionBlock(); - { - generator.Emit(OpCodes.Br_S, beginLoopLabel); + // try + generator.BeginExceptionBlock(); + { + generator.Emit(OpCodes.Br_S, beginLoopLabel); - generator.MarkLabel(processCurrentLabel); + generator.MarkLabel(processCurrentLabel); - generator.Emit(OpCodes.Ldarg_2); - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Ldloca_S, 0); - generator.Emit(OpCodes.Constrained, enumeratorType); - generator.Emit(OpCodes.Callvirt, GeneircCurrentGetMethod); + generator.Emit(OpCodes.Ldarg_2); + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldloca_S, 0); + generator.Emit(OpCodes.Constrained, enumeratorType); + generator.Emit(OpCodes.Callvirt, GeneircCurrentGetMethod); - generator.Emit(OpCodes.Callvirt, itemCallbackType.GetMethod("Invoke")); + generator.Emit(OpCodes.Callvirt, itemCallbackType.GetMethod("Invoke")); - generator.Emit(OpCodes.Brtrue_S, beginLoopLabel); + generator.Emit(OpCodes.Brtrue_S, beginLoopLabel); - generator.Emit(OpCodes.Leave_S, returnLabel); + generator.Emit(OpCodes.Leave_S, returnLabel); - generator.MarkLabel(beginLoopLabel); + generator.MarkLabel(beginLoopLabel); - generator.Emit(OpCodes.Ldloca_S, 0); - generator.Emit(OpCodes.Constrained, enumeratorType); - generator.Emit(OpCodes.Callvirt, MoveNextMethod); + generator.Emit(OpCodes.Ldloca_S, 0); + generator.Emit(OpCodes.Constrained, enumeratorType); + generator.Emit(OpCodes.Callvirt, MoveNextMethod); - generator.Emit(OpCodes.Brtrue_S, processCurrentLabel); + generator.Emit(OpCodes.Brtrue_S, processCurrentLabel); - generator.MarkLabel(breakLoopLabel); + generator.MarkLabel(breakLoopLabel); - generator.Emit(OpCodes.Leave_S, returnLabel); - } + generator.Emit(OpCodes.Leave_S, returnLabel); + } - // finally - generator.BeginFinallyBlock(); + // finally + generator.BeginFinallyBlock(); + { + if (typeof(IDisposable).IsAssignableFrom(enumeratorType)) { - if (typeof(IDisposable).IsAssignableFrom(enumeratorType)) - { - generator.Emit(OpCodes.Ldloca_S, 0); - generator.Emit(OpCodes.Constrained, enumeratorType); - generator.Emit(OpCodes.Callvirt, DisposeMethod); - } + generator.Emit(OpCodes.Ldloca_S, 0); + generator.Emit(OpCodes.Constrained, enumeratorType); + generator.Emit(OpCodes.Callvirt, DisposeMethod); } + } - generator.EndExceptionBlock(); + generator.EndExceptionBlock(); - generator.MarkLabel(returnLabel); + generator.MarkLabel(returnLabel); - generator.Emit(OpCodes.Ret); + generator.Emit(OpCodes.Ret); - return (AllocationFreeForEachDelegate)dynamicMethod.CreateDelegate(typeof(AllocationFreeForEachDelegate)); - } + return (AllocationFreeForEachDelegate)dynamicMethod.CreateDelegate(typeof(AllocationFreeForEachDelegate)); + } - private static MethodInfo ResolveGetEnumeratorMethodForType(Type type) - { - var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + private static MethodInfo ResolveGetEnumeratorMethodForType(Type type) + { + var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - foreach (var method in methods) + foreach (var method in methods) + { + if (method.Name == "GetEnumerator" && !method.ReturnType.IsInterface) { - if (method.Name == "GetEnumerator" && !method.ReturnType.IsInterface) - { - return method; - } + return method; } - - return null; } + + return null; } } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs index 0254b0cc12..9fc3296917 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs @@ -18,29 +18,28 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Internal +namespace OpenTelemetry.Internal; + +internal static class ExceptionExtensions { - internal static class ExceptionExtensions + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + /// Exception to convert to string. + /// Exception as string with no culture. + public static string ToInvariantString(this Exception exception) { - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - /// Exception to convert to string. - /// Exception as string with no culture. - public static string ToInvariantString(this Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; + var originalUICulture = Thread.CurrentThread.CurrentUICulture; - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs b/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs index b1fd73f3a7..3a55f61399 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs @@ -16,19 +16,18 @@ using System.Diagnostics; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// An interface used to perform zero-allocation enumeration of elements. Implementation must be a struct. +/// +/// Enumerated item type. +internal interface IActivityEnumerator { /// - /// An interface used to perform zero-allocation enumeration of elements. Implementation must be a struct. + /// Called for each item while the enumeration is executing. /// - /// Enumerated item type. - internal interface IActivityEnumerator - { - /// - /// Called for each item while the enumeration is executing. - /// - /// Enumeration item. - /// to continue the enumeration of records or to stop (break) the enumeration. - bool ForEach(T item); - } + /// Enumeration item. + /// to continue the enumeration of records or to stop (break) the enumeration. + bool ForEach(T item); } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs b/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs index 1871c60baf..ab5aca7023 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs @@ -14,100 +14,99 @@ // limitations under the License. // -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// . +/// +internal static class SemanticConventions { - /// - /// Constants for semantic attribute names outlined by the OpenTelemetry specifications. - /// . - /// - internal static class SemanticConventions - { - // The set of constants matches the specification as of this commit. - // https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md + // The set of constants matches the specification as of this commit. + // https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - public const string AttributeNetTransport = "net.transport"; - public const string AttributeNetPeerIp = "net.peer.ip"; - public const string AttributeNetPeerPort = "net.peer.port"; - public const string AttributeNetPeerName = "net.peer.name"; - public const string AttributeNetHostIp = "net.host.ip"; - public const string AttributeNetHostPort = "net.host.port"; - public const string AttributeNetHostName = "net.host.name"; + public const string AttributeNetTransport = "net.transport"; + public const string AttributeNetPeerIp = "net.peer.ip"; + public const string AttributeNetPeerPort = "net.peer.port"; + public const string AttributeNetPeerName = "net.peer.name"; + public const string AttributeNetHostIp = "net.host.ip"; + public const string AttributeNetHostPort = "net.host.port"; + public const string AttributeNetHostName = "net.host.name"; - public const string AttributeEnduserId = "enduser.id"; - public const string AttributeEnduserRole = "enduser.role"; - public const string AttributeEnduserScope = "enduser.scope"; + public const string AttributeEnduserId = "enduser.id"; + public const string AttributeEnduserRole = "enduser.role"; + public const string AttributeEnduserScope = "enduser.scope"; - public const string AttributePeerService = "peer.service"; + public const string AttributePeerService = "peer.service"; - public const string AttributeHttpMethod = "http.method"; - public const string AttributeHttpUrl = "http.url"; - public const string AttributeHttpTarget = "http.target"; - public const string AttributeHttpHost = "http.host"; - public const string AttributeHttpScheme = "http.scheme"; - public const string AttributeHttpStatusCode = "http.status_code"; - public const string AttributeHttpStatusText = "http.status_text"; - public const string AttributeHttpFlavor = "http.flavor"; - public const string AttributeHttpServerName = "http.server_name"; - public const string AttributeHttpRoute = "http.route"; - public const string AttributeHttpClientIP = "http.client_ip"; - public const string AttributeHttpUserAgent = "http.user_agent"; - public const string AttributeHttpRequestContentLength = "http.request_content_length"; - public const string AttributeHttpRequestContentLengthUncompressed = "http.request_content_length_uncompressed"; - public const string AttributeHttpResponseContentLength = "http.response_content_length"; - public const string AttributeHttpResponseContentLengthUncompressed = "http.response_content_length_uncompressed"; + public const string AttributeHttpMethod = "http.method"; + public const string AttributeHttpUrl = "http.url"; + public const string AttributeHttpTarget = "http.target"; + public const string AttributeHttpHost = "http.host"; + public const string AttributeHttpScheme = "http.scheme"; + public const string AttributeHttpStatusCode = "http.status_code"; + public const string AttributeHttpStatusText = "http.status_text"; + public const string AttributeHttpFlavor = "http.flavor"; + public const string AttributeHttpServerName = "http.server_name"; + public const string AttributeHttpRoute = "http.route"; + public const string AttributeHttpClientIP = "http.client_ip"; + public const string AttributeHttpUserAgent = "http.user_agent"; + public const string AttributeHttpRequestContentLength = "http.request_content_length"; + public const string AttributeHttpRequestContentLengthUncompressed = "http.request_content_length_uncompressed"; + public const string AttributeHttpResponseContentLength = "http.response_content_length"; + public const string AttributeHttpResponseContentLengthUncompressed = "http.response_content_length_uncompressed"; - public const string AttributeDbSystem = "db.system"; - public const string AttributeDbConnectionString = "db.connection_string"; - public const string AttributeDbUser = "db.user"; - public const string AttributeDbMsSqlInstanceName = "db.mssql.instance_name"; - public const string AttributeDbJdbcDriverClassName = "db.jdbc.driver_classname"; - public const string AttributeDbName = "db.name"; - public const string AttributeDbStatement = "db.statement"; - public const string AttributeDbOperation = "db.operation"; - public const string AttributeDbInstance = "db.instance"; - public const string AttributeDbUrl = "db.url"; - public const string AttributeDbCassandraKeyspace = "db.cassandra.keyspace"; - public const string AttributeDbHBaseNamespace = "db.hbase.namespace"; - public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; - public const string AttributeDbMongoDbCollection = "db.mongodb.collection"; + public const string AttributeDbSystem = "db.system"; + public const string AttributeDbConnectionString = "db.connection_string"; + public const string AttributeDbUser = "db.user"; + public const string AttributeDbMsSqlInstanceName = "db.mssql.instance_name"; + public const string AttributeDbJdbcDriverClassName = "db.jdbc.driver_classname"; + public const string AttributeDbName = "db.name"; + public const string AttributeDbStatement = "db.statement"; + public const string AttributeDbOperation = "db.operation"; + public const string AttributeDbInstance = "db.instance"; + public const string AttributeDbUrl = "db.url"; + public const string AttributeDbCassandraKeyspace = "db.cassandra.keyspace"; + public const string AttributeDbHBaseNamespace = "db.hbase.namespace"; + public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; + public const string AttributeDbMongoDbCollection = "db.mongodb.collection"; - public const string AttributeRpcSystem = "rpc.system"; - public const string AttributeRpcService = "rpc.service"; - public const string AttributeRpcMethod = "rpc.method"; - public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; + public const string AttributeRpcSystem = "rpc.system"; + public const string AttributeRpcService = "rpc.service"; + public const string AttributeRpcMethod = "rpc.method"; + public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; - public const string AttributeMessageType = "message.type"; - public const string AttributeMessageId = "message.id"; - public const string AttributeMessageCompressedSize = "message.compressed_size"; - public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; + public const string AttributeMessageType = "message.type"; + public const string AttributeMessageId = "message.id"; + public const string AttributeMessageCompressedSize = "message.compressed_size"; + public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; - public const string AttributeFaasTrigger = "faas.trigger"; - public const string AttributeFaasExecution = "faas.execution"; - public const string AttributeFaasDocumentCollection = "faas.document.collection"; - public const string AttributeFaasDocumentOperation = "faas.document.operation"; - public const string AttributeFaasDocumentTime = "faas.document.time"; - public const string AttributeFaasDocumentName = "faas.document.name"; - public const string AttributeFaasTime = "faas.time"; - public const string AttributeFaasCron = "faas.cron"; + public const string AttributeFaasTrigger = "faas.trigger"; + public const string AttributeFaasExecution = "faas.execution"; + public const string AttributeFaasDocumentCollection = "faas.document.collection"; + public const string AttributeFaasDocumentOperation = "faas.document.operation"; + public const string AttributeFaasDocumentTime = "faas.document.time"; + public const string AttributeFaasDocumentName = "faas.document.name"; + public const string AttributeFaasTime = "faas.time"; + public const string AttributeFaasCron = "faas.cron"; - public const string AttributeMessagingSystem = "messaging.system"; - public const string AttributeMessagingDestination = "messaging.destination"; - public const string AttributeMessagingDestinationKind = "messaging.destination_kind"; - public const string AttributeMessagingTempDestination = "messaging.temp_destination"; - public const string AttributeMessagingProtocol = "messaging.protocol"; - public const string AttributeMessagingProtocolVersion = "messaging.protocol_version"; - public const string AttributeMessagingUrl = "messaging.url"; - public const string AttributeMessagingMessageId = "messaging.message_id"; - public const string AttributeMessagingConversationId = "messaging.conversation_id"; - public const string AttributeMessagingPayloadSize = "messaging.message_payload_size_bytes"; - public const string AttributeMessagingPayloadCompressedSize = "messaging.message_payload_compressed_size_bytes"; - public const string AttributeMessagingOperation = "messaging.operation"; + public const string AttributeMessagingSystem = "messaging.system"; + public const string AttributeMessagingDestination = "messaging.destination"; + public const string AttributeMessagingDestinationKind = "messaging.destination_kind"; + public const string AttributeMessagingTempDestination = "messaging.temp_destination"; + public const string AttributeMessagingProtocol = "messaging.protocol"; + public const string AttributeMessagingProtocolVersion = "messaging.protocol_version"; + public const string AttributeMessagingUrl = "messaging.url"; + public const string AttributeMessagingMessageId = "messaging.message_id"; + public const string AttributeMessagingConversationId = "messaging.conversation_id"; + public const string AttributeMessagingPayloadSize = "messaging.message_payload_size_bytes"; + public const string AttributeMessagingPayloadCompressedSize = "messaging.message_payload_compressed_size_bytes"; + public const string AttributeMessagingOperation = "messaging.operation"; - public const string AttributeExceptionEventName = "exception"; - public const string AttributeExceptionType = "exception.type"; - public const string AttributeExceptionMessage = "exception.message"; - public const string AttributeExceptionStacktrace = "exception.stacktrace"; + public const string AttributeExceptionEventName = "exception"; + public const string AttributeExceptionType = "exception.type"; + public const string AttributeExceptionMessage = "exception.message"; + public const string AttributeExceptionStacktrace = "exception.stacktrace"; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - } } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs b/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs index 7bff65e696..56d107fb80 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs @@ -14,18 +14,17 @@ // limitations under the License. // -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Defines well-known span attribute keys. +/// +internal static class SpanAttributeConstants { - /// - /// Defines well-known span attribute keys. - /// - internal static class SpanAttributeConstants - { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - public const string StatusCodeKey = "otel.status_code"; - public const string StatusDescriptionKey = "otel.status_description"; - public const string DatabaseStatementTypeKey = "db.statement_type"; + public const string StatusCodeKey = "otel.status_code"; + public const string StatusDescriptionKey = "otel.status_description"; + public const string DatabaseStatementTypeKey = "db.statement_type"; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member - } } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs index fb342ae4d3..f7bb9880ff 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs @@ -16,50 +16,49 @@ using System.Diagnostics; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// A collection of helper methods to be used when building spans. +/// +internal static class SpanHelper { /// - /// A collection of helper methods to be used when building spans. + /// Helper method that populates span properties from http status code according + /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. /// - internal static class SpanHelper + /// Http status code. + /// Resolved span for the Http status code. + public static Status ResolveSpanStatusForHttpStatusCode(int httpStatusCode) { - /// - /// Helper method that populates span properties from http status code according - /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. - /// - /// Http status code. - /// Resolved span for the Http status code. - public static Status ResolveSpanStatusForHttpStatusCode(int httpStatusCode) + if (httpStatusCode >= 100 && httpStatusCode <= 399) { - if (httpStatusCode >= 100 && httpStatusCode <= 399) - { - return Status.Unset; - } - - if (httpStatusCode == 404) - { - return Status.Unset; - } - - return Status.Error; + return Status.Unset; } - /// - /// Helper method that populates span properties from http status code according - /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. - /// - /// The span kind. - /// Http status code. - /// Resolved span for the Http status code. - public static Status ResolveSpanStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) + if (httpStatusCode == 404) { - var upperBound = kind == ActivityKind.Client ? 399 : 499; - if (httpStatusCode >= 100 && httpStatusCode <= upperBound) - { - return Status.Unset; - } + return Status.Unset; + } + + return Status.Error; + } - return Status.Error; + /// + /// Helper method that populates span properties from http status code according + /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. + /// + /// The span kind. + /// Http status code. + /// Resolved span for the Http status code. + public static Status ResolveSpanStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) + { + var upperBound = kind == ActivityKind.Client ? 399 : 499; + if (httpStatusCode >= 100 && httpStatusCode <= upperBound) + { + return Status.Unset; } + + return Status.Error; } } diff --git a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs index 4ca8fa2b2a..36db9d9e94 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs @@ -18,46 +18,45 @@ using System.Runtime.CompilerServices; using OpenTelemetry.Trace; -namespace OpenTelemetry.Internal +namespace OpenTelemetry.Internal; + +internal static class StatusHelper { - internal static class StatusHelper - { - public const string UnsetStatusCodeTagValue = "UNSET"; - public const string OkStatusCodeTagValue = "OK"; - public const string ErrorStatusCodeTagValue = "ERROR"; + public const string UnsetStatusCodeTagValue = "UNSET"; + public const string OkStatusCodeTagValue = "OK"; + public const string ErrorStatusCodeTagValue = "ERROR"; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string GetTagValueForStatusCode(StatusCode statusCode) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string GetTagValueForStatusCode(StatusCode statusCode) + { + return statusCode switch { - return statusCode 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. - */ - StatusCode.Unset => UnsetStatusCodeTagValue, - StatusCode.Error => ErrorStatusCodeTagValue, - StatusCode.Ok => OkStatusCodeTagValue, - _ => null, - }; - } + /* + * 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. + */ + StatusCode.Unset => UnsetStatusCodeTagValue, + StatusCode.Error => ErrorStatusCodeTagValue, + StatusCode.Ok => OkStatusCodeTagValue, + _ => null, + }; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static StatusCode? GetStatusCodeForTagValue(string statusCodeTagValue) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StatusCode? GetStatusCodeForTagValue(string statusCodeTagValue) + { + return statusCodeTagValue switch { - return statusCodeTagValue 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. - */ - string _ when UnsetStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Unset, - string _ when ErrorStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Error, - string _ when OkStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Ok, - _ => (StatusCode?)null, - }; - } + /* + * 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. + */ + string _ when UnsetStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Unset, + string _ when ErrorStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Error, + string _ when OkStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Ok, + _ => (StatusCode?)null, + }; } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs index 4e527812f3..1ba9636dfa 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs @@ -18,27 +18,26 @@ using System.Diagnostics; using System.Linq.Expressions; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +internal static class ActivityInstrumentationHelper { - internal static class ActivityInstrumentationHelper - { - internal static readonly Action SetKindProperty = CreateActivityKindSetter(); - internal static readonly Action SetActivitySourceProperty = CreateActivitySourceSetter(); + internal static readonly Action SetKindProperty = CreateActivityKindSetter(); + internal static readonly Action SetActivitySourceProperty = CreateActivitySourceSetter(); - private static Action CreateActivitySourceSetter() - { - ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance"); - ParameterExpression propertyValue = Expression.Parameter(typeof(ActivitySource), "propertyValue"); - var body = Expression.Assign(Expression.Property(instance, "Source"), propertyValue); - return Expression.Lambda>(body, instance, propertyValue).Compile(); - } + private static Action CreateActivitySourceSetter() + { + ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance"); + ParameterExpression propertyValue = Expression.Parameter(typeof(ActivitySource), "propertyValue"); + var body = Expression.Assign(Expression.Property(instance, "Source"), propertyValue); + return Expression.Lambda>(body, instance, propertyValue).Compile(); + } - private static Action CreateActivityKindSetter() - { - ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance"); - ParameterExpression propertyValue = Expression.Parameter(typeof(ActivityKind), "propertyValue"); - var body = Expression.Assign(Expression.Property(instance, "Kind"), propertyValue); - return Expression.Lambda>(body, instance, propertyValue).Compile(); - } + private static Action CreateActivityKindSetter() + { + ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance"); + ParameterExpression propertyValue = Expression.Parameter(typeof(ActivityKind), "propertyValue"); + var body = Expression.Assign(Expression.Property(instance, "Kind"), propertyValue); + return Expression.Lambda>(body, instance, propertyValue).Compile(); } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs index 812fc572ce..ef3a0c46be 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs @@ -19,57 +19,56 @@ using System.Diagnostics; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +internal class DiagnosticSourceListener : IObserver> { - internal class DiagnosticSourceListener : IObserver> + private readonly ListenerHandler handler; + + public DiagnosticSourceListener(ListenerHandler handler) { - private readonly ListenerHandler handler; + Guard.ThrowIfNull(handler); - public DiagnosticSourceListener(ListenerHandler handler) - { - Guard.ThrowIfNull(handler); + this.handler = handler; + } - this.handler = handler; - } + public void OnCompleted() + { + } - public void OnCompleted() - { - } + public void OnError(Exception error) + { + } - public void OnError(Exception error) + public void OnNext(KeyValuePair value) + { + if (!this.handler.SupportsNullActivity && Activity.Current == null) { + return; } - public void OnNext(KeyValuePair value) + try { - if (!this.handler.SupportsNullActivity && Activity.Current == null) + if (value.Key.EndsWith("Start", StringComparison.Ordinal)) { - return; + this.handler.OnStartActivity(Activity.Current, value.Value); } - - try + else if (value.Key.EndsWith("Stop", StringComparison.Ordinal)) { - if (value.Key.EndsWith("Start", StringComparison.Ordinal)) - { - this.handler.OnStartActivity(Activity.Current, value.Value); - } - else if (value.Key.EndsWith("Stop", StringComparison.Ordinal)) - { - this.handler.OnStopActivity(Activity.Current, value.Value); - } - else if (value.Key.EndsWith("Exception", StringComparison.Ordinal)) - { - this.handler.OnException(Activity.Current, value.Value); - } - else - { - this.handler.OnCustom(value.Key, Activity.Current, value.Value); - } + this.handler.OnStopActivity(Activity.Current, value.Value); } - catch (Exception ex) + else if (value.Key.EndsWith("Exception", StringComparison.Ordinal)) { - InstrumentationEventSource.Log.UnknownErrorProcessingEvent(this.handler?.SourceName, value.Key, ex); + this.handler.OnException(Activity.Current, value.Value); } + else + { + this.handler.OnCustom(value.Key, Activity.Current, value.Value); + } + } + catch (Exception ex) + { + InstrumentationEventSource.Log.UnknownErrorProcessingEvent(this.handler?.SourceName, value.Key, ex); } } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs index ea98ab414a..f0065c97ac 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs @@ -19,97 +19,96 @@ using System.Threading; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +internal class DiagnosticSourceSubscriber : IDisposable, IObserver { - internal class DiagnosticSourceSubscriber : IDisposable, IObserver - { - private readonly Func handlerFactory; - private readonly Func diagnosticSourceFilter; - private readonly Func isEnabledFilter; - private long disposed; - private IDisposable allSourcesSubscription; - private List listenerSubscriptions; + private readonly Func handlerFactory; + private readonly Func diagnosticSourceFilter; + private readonly Func isEnabledFilter; + private long disposed; + private IDisposable allSourcesSubscription; + private List listenerSubscriptions; - public DiagnosticSourceSubscriber( - ListenerHandler handler, - Func isEnabledFilter) - : this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter) - { - } + public DiagnosticSourceSubscriber( + ListenerHandler handler, + Func isEnabledFilter) + : this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter) + { + } - public DiagnosticSourceSubscriber( - Func handlerFactory, - Func diagnosticSourceFilter, - Func isEnabledFilter) - { - Guard.ThrowIfNull(handlerFactory); + public DiagnosticSourceSubscriber( + Func handlerFactory, + Func diagnosticSourceFilter, + Func isEnabledFilter) + { + Guard.ThrowIfNull(handlerFactory); - this.listenerSubscriptions = new List(); - this.handlerFactory = handlerFactory; - this.diagnosticSourceFilter = diagnosticSourceFilter; - this.isEnabledFilter = isEnabledFilter; - } + this.listenerSubscriptions = new List(); + this.handlerFactory = handlerFactory; + this.diagnosticSourceFilter = diagnosticSourceFilter; + this.isEnabledFilter = isEnabledFilter; + } - public void Subscribe() + public void Subscribe() + { + if (this.allSourcesSubscription == null) { - if (this.allSourcesSubscription == null) - { - this.allSourcesSubscription = DiagnosticListener.AllListeners.Subscribe(this); - } + this.allSourcesSubscription = DiagnosticListener.AllListeners.Subscribe(this); } + } - public void OnNext(DiagnosticListener value) + public void OnNext(DiagnosticListener value) + { + if ((Interlocked.Read(ref this.disposed) == 0) && + this.diagnosticSourceFilter(value)) { - if ((Interlocked.Read(ref this.disposed) == 0) && - this.diagnosticSourceFilter(value)) - { - var handler = this.handlerFactory(value.Name); - var listener = new DiagnosticSourceListener(handler); - var subscription = this.isEnabledFilter == null ? - value.Subscribe(listener) : - value.Subscribe(listener, this.isEnabledFilter); + var handler = this.handlerFactory(value.Name); + var listener = new DiagnosticSourceListener(handler); + var subscription = this.isEnabledFilter == null ? + value.Subscribe(listener) : + value.Subscribe(listener, this.isEnabledFilter); - lock (this.listenerSubscriptions) - { - this.listenerSubscriptions.Add(subscription); - } + lock (this.listenerSubscriptions) + { + this.listenerSubscriptions.Add(subscription); } } + } - public void OnCompleted() - { - } + public void OnCompleted() + { + } - public void OnError(Exception error) - { - } + public void OnError(Exception error) + { + } + + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } - /// - public void Dispose() + protected virtual void Dispose(bool disposing) + { + if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 1) { - this.Dispose(true); - GC.SuppressFinalize(this); + return; } - protected virtual void Dispose(bool disposing) + lock (this.listenerSubscriptions) { - if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 1) + foreach (var listenerSubscription in this.listenerSubscriptions) { - return; + listenerSubscription?.Dispose(); } - lock (this.listenerSubscriptions) - { - foreach (var listenerSubscription in this.listenerSubscriptions) - { - listenerSubscription?.Dispose(); - } - - this.listenerSubscriptions.Clear(); - } - - this.allSourcesSubscription?.Dispose(); - this.allSourcesSubscription = null; + this.listenerSubscriptions.Clear(); } + + this.allSourcesSubscription?.Dispose(); + this.allSourcesSubscription = null; } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs index cb22138aa6..53b684f707 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs @@ -18,35 +18,34 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation")] +internal class InstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation")] - internal class InstrumentationEventSource : EventSource - { - public static InstrumentationEventSource Log = new InstrumentationEventSource(); + public static InstrumentationEventSource Log = new InstrumentationEventSource(); - [Event(1, Message = "Current Activity is NULL in the '{0}' callback. Activity will not be recorded.", Level = EventLevel.Warning)] - public void NullActivity(string eventName) - { - this.WriteEvent(1, eventName); - } + [Event(1, Message = "Current Activity is NULL in the '{0}' callback. Activity will not be recorded.", Level = EventLevel.Warning)] + public void NullActivity(string eventName) + { + this.WriteEvent(1, eventName); + } - [NonEvent] - public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); - } + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); } + } - [Event(2, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] - public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) - { - this.WriteEvent(2, handlerName, eventName, ex); - } + [Event(2, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(2, handlerName, eventName, ex); } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs index 66ae48e0ca..e19a5ff7ab 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs @@ -15,67 +15,66 @@ // using System.Diagnostics; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +/// +/// ListenerHandler base class. +/// +internal abstract class ListenerHandler { /// - /// ListenerHandler base class. + /// Initializes a new instance of the class. /// - internal abstract class ListenerHandler + /// The name of the . + public ListenerHandler(string sourceName) { - /// - /// Initializes a new instance of the class. - /// - /// The name of the . - public ListenerHandler(string sourceName) - { - this.SourceName = sourceName; - } + this.SourceName = sourceName; + } - /// - /// Gets the name of the . - /// - public string SourceName { get; } + /// + /// Gets the name of the . + /// + public string SourceName { get; } - /// - /// Gets a value indicating whether the supports NULL . - /// - public virtual bool SupportsNullActivity { get; } + /// + /// Gets a value indicating whether the supports NULL . + /// + public virtual bool SupportsNullActivity { get; } - /// - /// Method called for an event with the suffix 'Start'. - /// - /// The to be started. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnStartActivity(Activity activity, object payload) - { - } + /// + /// Method called for an event with the suffix 'Start'. + /// + /// The to be started. + /// An object that represent the value being passed as a payload for the event. + public virtual void OnStartActivity(Activity activity, object payload) + { + } - /// - /// Method called for an event with the suffix 'Stop'. - /// - /// The to be stopped. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnStopActivity(Activity activity, object payload) - { - } + /// + /// Method called for an event with the suffix 'Stop'. + /// + /// The to be stopped. + /// An object that represent the value being passed as a payload for the event. + public virtual void OnStopActivity(Activity activity, object payload) + { + } - /// - /// Method called for an event with the suffix 'Exception'. - /// - /// The . - /// An object that represent the value being passed as a payload for the event. - public virtual void OnException(Activity activity, object payload) - { - } + /// + /// Method called for an event with the suffix 'Exception'. + /// + /// The . + /// An object that represent the value being passed as a payload for the event. + public virtual void OnException(Activity activity, object payload) + { + } - /// - /// Method called for an event which does not have 'Start', 'Stop' or 'Exception' as suffix. - /// - /// Custom name. - /// The to be processed. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnCustom(string name, Activity activity, object payload) - { - } + /// + /// Method called for an event which does not have 'Start', 'Stop' or 'Exception' as suffix. + /// + /// Custom name. + /// The to be processed. + /// An object that represent the value being passed as a payload for the event. + public virtual void OnCustom(string name, Activity activity, object payload) + { } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs index 7746d9d6ad..8ed27681e4 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs @@ -19,106 +19,105 @@ using System.Linq; using System.Reflection; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +/// +/// PropertyFetcher fetches a property from an object. +/// +/// The type of the property being fetched. +internal class MultiTypePropertyFetcher { + private readonly string propertyName; + private readonly ConcurrentDictionary innerFetcher = new ConcurrentDictionary(); + /// - /// PropertyFetcher fetches a property from an object. + /// Initializes a new instance of the class. /// - /// The type of the property being fetched. - internal class MultiTypePropertyFetcher + /// Property name to fetch. + public MultiTypePropertyFetcher(string propertyName) { - private readonly string propertyName; - private readonly ConcurrentDictionary innerFetcher = new ConcurrentDictionary(); + this.propertyName = propertyName; + } - /// - /// Initializes a new instance of the class. - /// - /// Property name to fetch. - public MultiTypePropertyFetcher(string propertyName) + /// + /// Fetch the property from the object. + /// + /// Object to be fetched. + /// Property fetched. + public T Fetch(object obj) + { + if (obj == null) { - this.propertyName = propertyName; + return default; } - /// - /// Fetch the property from the object. - /// - /// Object to be fetched. - /// Property fetched. - public T Fetch(object obj) + var type = obj.GetType().GetTypeInfo(); + PropertyFetch fetcher = null; + if (!this.innerFetcher.TryGetValue(type, out fetcher)) { - if (obj == null) + var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.InvariantCultureIgnoreCase)); + if (property == null) { - return default; + property = type.GetProperty(this.propertyName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } - var type = obj.GetType().GetTypeInfo(); - PropertyFetch fetcher = null; - if (!this.innerFetcher.TryGetValue(type, out fetcher)) - { - var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.InvariantCultureIgnoreCase)); - if (property == null) - { - property = type.GetProperty(this.propertyName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - } + fetcher = PropertyFetch.FetcherForProperty(property); - fetcher = PropertyFetch.FetcherForProperty(property); + this.innerFetcher.TryAdd(type, fetcher); + } - this.innerFetcher.TryAdd(type, fetcher); - } + if (fetcher == null) + { + return default; + } - if (fetcher == null) + return fetcher.Fetch(obj); + } + + // see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs + private class PropertyFetch + { + /// + /// Create a property fetcher from a .NET Reflection PropertyInfo class that + /// represents a property of a particular type. + /// + public static PropertyFetch FetcherForProperty(PropertyInfo propertyInfo) + { + if (propertyInfo == null || !typeof(T).IsAssignableFrom(propertyInfo.PropertyType)) { - return default; + // returns null on any fetch. + return new PropertyFetch(); } - return fetcher.Fetch(obj); + var typedPropertyFetcher = typeof(TypedPropertyFetch<,>); + var instantiatedTypedPropertyFetcher = typedPropertyFetcher.MakeGenericType( + typeof(T), propertyInfo.DeclaringType, propertyInfo.PropertyType); + return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, propertyInfo); } - // see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs - private class PropertyFetch + public virtual T Fetch(object obj) { - /// - /// Create a property fetcher from a .NET Reflection PropertyInfo class that - /// represents a property of a particular type. - /// - public static PropertyFetch FetcherForProperty(PropertyInfo propertyInfo) - { - if (propertyInfo == null || !typeof(T).IsAssignableFrom(propertyInfo.PropertyType)) - { - // returns null on any fetch. - return new PropertyFetch(); - } + return default; + } - var typedPropertyFetcher = typeof(TypedPropertyFetch<,>); - var instantiatedTypedPropertyFetcher = typedPropertyFetcher.MakeGenericType( - typeof(T), propertyInfo.DeclaringType, propertyInfo.PropertyType); - return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, propertyInfo); - } + private class TypedPropertyFetch : PropertyFetch + where TDeclaredProperty : T + { + private readonly Func propertyFetch; - public virtual T Fetch(object obj) + public TypedPropertyFetch(PropertyInfo property) { - return default; + this.propertyFetch = (Func)property.GetMethod.CreateDelegate(typeof(Func)); } - private class TypedPropertyFetch : PropertyFetch - where TDeclaredProperty : T + public override T Fetch(object obj) { - private readonly Func propertyFetch; - - public TypedPropertyFetch(PropertyInfo property) + if (obj is TDeclaredObject o) { - this.propertyFetch = (Func)property.GetMethod.CreateDelegate(typeof(Func)); + return this.propertyFetch(o); } - public override T Fetch(object obj) - { - if (obj is TDeclaredObject o) - { - return this.propertyFetch(o); - } - - return default; - } + return default; } } } diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs index 933805d3ae..15e3d099b6 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs @@ -18,118 +18,117 @@ using System.Linq; using System.Reflection; -namespace OpenTelemetry.Instrumentation +namespace OpenTelemetry.Instrumentation; + +/// +/// PropertyFetcher fetches a property from an object. +/// +/// The type of the property being fetched. +internal class PropertyFetcher { + private readonly string propertyName; + private PropertyFetch innerFetcher; + /// - /// PropertyFetcher fetches a property from an object. + /// Initializes a new instance of the class. /// - /// The type of the property being fetched. - internal class PropertyFetcher + /// Property name to fetch. + public PropertyFetcher(string propertyName) { - private readonly string propertyName; - private PropertyFetch innerFetcher; + this.propertyName = propertyName; + } - /// - /// Initializes a new instance of the class. - /// - /// Property name to fetch. - public PropertyFetcher(string propertyName) + /// + /// Fetch the property from the object. + /// + /// Object to be fetched. + /// Property fetched. + public T Fetch(object obj) + { + if (!this.TryFetch(obj, out T value)) { - this.propertyName = propertyName; + throw new ArgumentException("Supplied object was null or did not match the expected type.", nameof(obj)); } - /// - /// Fetch the property from the object. - /// - /// Object to be fetched. - /// Property fetched. - public T Fetch(object obj) + return value; + } + + /// + /// Try to fetch the property from the object. + /// + /// Object to be fetched. + /// Fetched value. + /// if the property was fetched. + public bool TryFetch(object obj, out T value) + { + if (obj == null) + { + value = default; + return false; + } + + if (this.innerFetcher == null) { - if (!this.TryFetch(obj, out T value)) + var type = obj.GetType().GetTypeInfo(); + var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.InvariantCultureIgnoreCase)); + if (property == null) { - throw new ArgumentException("Supplied object was null or did not match the expected type.", nameof(obj)); + property = type.GetProperty(this.propertyName); } - return value; + this.innerFetcher = PropertyFetch.FetcherForProperty(property); } + return this.innerFetcher.TryFetch(obj, out value); + } + + // see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs + private class PropertyFetch + { /// - /// Try to fetch the property from the object. + /// Create a property fetcher from a .NET Reflection PropertyInfo class that + /// represents a property of a particular type. /// - /// Object to be fetched. - /// Fetched value. - /// if the property was fetched. - public bool TryFetch(object obj, out T value) + public static PropertyFetch FetcherForProperty(PropertyInfo propertyInfo) { - if (obj == null) + if (propertyInfo == null || !typeof(T).IsAssignableFrom(propertyInfo.PropertyType)) { - value = default; - return false; + // returns null on any fetch. + return new PropertyFetch(); } - if (this.innerFetcher == null) - { - var type = obj.GetType().GetTypeInfo(); - var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.InvariantCultureIgnoreCase)); - if (property == null) - { - property = type.GetProperty(this.propertyName); - } - - this.innerFetcher = PropertyFetch.FetcherForProperty(property); - } - - return this.innerFetcher.TryFetch(obj, out value); + var typedPropertyFetcher = typeof(TypedPropertyFetch<,>); + var instantiatedTypedPropertyFetcher = typedPropertyFetcher.MakeGenericType( + typeof(T), propertyInfo.DeclaringType, propertyInfo.PropertyType); + return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, propertyInfo); } - // see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs - private class PropertyFetch + public virtual bool TryFetch(object obj, out T value) { - /// - /// Create a property fetcher from a .NET Reflection PropertyInfo class that - /// represents a property of a particular type. - /// - public static PropertyFetch FetcherForProperty(PropertyInfo propertyInfo) - { - if (propertyInfo == null || !typeof(T).IsAssignableFrom(propertyInfo.PropertyType)) - { - // returns null on any fetch. - return new PropertyFetch(); - } + value = default; + return false; + } - var typedPropertyFetcher = typeof(TypedPropertyFetch<,>); - var instantiatedTypedPropertyFetcher = typedPropertyFetcher.MakeGenericType( - typeof(T), propertyInfo.DeclaringType, propertyInfo.PropertyType); - return (PropertyFetch)Activator.CreateInstance(instantiatedTypedPropertyFetcher, propertyInfo); - } + private class TypedPropertyFetch : PropertyFetch + where TDeclaredProperty : T + { + private readonly Func propertyFetch; - public virtual bool TryFetch(object obj, out T value) + public TypedPropertyFetch(PropertyInfo property) { - value = default; - return false; + this.propertyFetch = (Func)property.GetMethod.CreateDelegate(typeof(Func)); } - private class TypedPropertyFetch : PropertyFetch - where TDeclaredProperty : T + public override bool TryFetch(object obj, out T value) { - private readonly Func propertyFetch; - - public TypedPropertyFetch(PropertyInfo property) + if (obj is TDeclaredObject o) { - this.propertyFetch = (Func)property.GetMethod.CreateDelegate(typeof(Func)); + value = this.propertyFetch(o); + return true; } - public override bool TryFetch(object obj, out T value) - { - if (obj is TDeclaredObject o) - { - value = this.propertyFetch(o); - return true; - } - - value = default; - return false; - } + value = default; + return false; } } } diff --git a/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs b/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs index daa1384d98..dbfc46ea62 100644 --- a/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs @@ -18,30 +18,29 @@ using Microsoft.Extensions.Options; #endif -namespace System +namespace System; + +/// +/// Extension methods for OpenTelemetry dependency injection support. +/// +internal static class ServiceProviderExtensions { /// - /// Extension methods for OpenTelemetry dependency injection support. + /// Get options from the supplied . /// - internal static class ServiceProviderExtensions + /// Options type. + /// . + /// Options instance. + public static T GetOptions(this IServiceProvider serviceProvider) + where T : class, new() { - /// - /// Get options from the supplied . - /// - /// Options type. - /// . - /// Options instance. - public static T GetOptions(this IServiceProvider serviceProvider) - where T : class, new() - { #if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER - IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); + IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); - // Note: options could be null if user never invoked services.AddOptions(). - return options?.Value ?? new T(); + // Note: options could be null if user never invoked services.AddOptions(). + return options?.Value ?? new T(); #else - return new T(); + return new T(); #endif - } } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs index 67afcbb57b..2c9f2f9578 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -21,122 +21,121 @@ using System.Linq; using System.Reflection; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal static class EventSourceTestHelper { - internal static class EventSourceTestHelper + public static void MethodsAreImplementedConsistentlyWithTheirAttributes(EventSource eventSource) { - public static void MethodsAreImplementedConsistentlyWithTheirAttributes(EventSource eventSource) + foreach (MethodInfo publicMethod in GetEventMethods(eventSource)) { - foreach (MethodInfo publicMethod in GetEventMethods(eventSource)) - { - VerifyMethodImplementation(eventSource, publicMethod); - } + VerifyMethodImplementation(eventSource, publicMethod); } + } - private static void VerifyMethodImplementation(EventSource eventSource, MethodInfo eventMethod) + private static void VerifyMethodImplementation(EventSource eventSource, MethodInfo eventMethod) + { + using var listener = new TestEventListener(); + listener.EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All); + try { - using var listener = new TestEventListener(); - listener.EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All); - try - { - object[] eventArguments = GenerateEventArguments(eventMethod); - eventMethod.Invoke(eventSource, eventArguments); + object[] eventArguments = GenerateEventArguments(eventMethod); + eventMethod.Invoke(eventSource, eventArguments); - EventWrittenEventArgs actualEvent = null; + EventWrittenEventArgs actualEvent = null; - actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); + actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); - VerifyEventId(eventMethod, actualEvent); - VerifyEventLevel(eventMethod, actualEvent); + VerifyEventId(eventMethod, actualEvent); + VerifyEventLevel(eventMethod, actualEvent); - if (eventMethod.Name != "ExporterErrorResult") - { - VerifyEventMessage(eventMethod, actualEvent, eventArguments); - } - } - catch (Exception e) - { - var name = eventMethod.DeclaringType.Name + "." + eventMethod.Name; - - throw new Exception("Method '" + name + "' is implemented incorrectly.", e); - } - finally + if (eventMethod.Name != "ExporterErrorResult") { - listener.ClearMessages(); + VerifyEventMessage(eventMethod, actualEvent, eventArguments); } } - - private static object[] GenerateEventArguments(MethodInfo eventMethod) + catch (Exception e) { - ParameterInfo[] parameters = eventMethod.GetParameters(); - var arguments = new object[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) - { - arguments[i] = GenerateArgument(parameters[i]); - } + var name = eventMethod.DeclaringType.Name + "." + eventMethod.Name; - return arguments; + throw new Exception("Method '" + name + "' is implemented incorrectly.", e); } - - private static object GenerateArgument(ParameterInfo parameter) + finally { - if (parameter.ParameterType == typeof(string)) - { - return "Test String"; - } - - if (parameter.ParameterType.IsValueType) - { - return Activator.CreateInstance(parameter.ParameterType); - } - - throw new NotSupportedException("Complex types are not supported"); + listener.ClearMessages(); } + } - private static void VerifyEventId(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) + private static object[] GenerateEventArguments(MethodInfo eventMethod) + { + ParameterInfo[] parameters = eventMethod.GetParameters(); + var arguments = new object[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) { - int expectedEventId = GetEventAttribute(eventMethod).EventId; - AssertEqual(nameof(VerifyEventId), expectedEventId, actualEvent.EventId); + arguments[i] = GenerateArgument(parameters[i]); } - private static void VerifyEventLevel(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) - { - EventLevel expectedLevel = GetEventAttribute(eventMethod).Level; - AssertEqual(nameof(VerifyEventLevel), expectedLevel, actualEvent.Level); - } + return arguments; + } - private static void VerifyEventMessage(MethodInfo eventMethod, EventWrittenEventArgs actualEvent, object[] eventArguments) + private static object GenerateArgument(ParameterInfo parameter) + { + if (parameter.ParameterType == typeof(string)) { - 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()); - AssertEqual(nameof(VerifyEventMessage), expectedMessage, actualMessage); + return "Test String"; } - private static void AssertEqual(string methodName, T expected, T actual) + if (parameter.ParameterType.IsValueType) { - if (!expected.Equals(actual)) - { - var errorMessage = string.Format( - CultureInfo.InvariantCulture, - "{0} Failed: expected: '{1}' actual: '{2}'", - methodName, - expected, - actual); - throw new Exception(errorMessage); - } + return Activator.CreateInstance(parameter.ParameterType); } - private static EventAttribute GetEventAttribute(MethodInfo eventMethod) - { - return (EventAttribute)eventMethod.GetCustomAttributes(typeof(EventAttribute), false).Single(); - } + throw new NotSupportedException("Complex types are not supported"); + } + + private static void VerifyEventId(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) + { + int expectedEventId = GetEventAttribute(eventMethod).EventId; + AssertEqual(nameof(VerifyEventId), expectedEventId, actualEvent.EventId); + } - private static IEnumerable GetEventMethods(EventSource eventSource) + private static void VerifyEventLevel(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) + { + EventLevel expectedLevel = GetEventAttribute(eventMethod).Level; + AssertEqual(nameof(VerifyEventLevel), expectedLevel, actualEvent.Level); + } + + 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()); + AssertEqual(nameof(VerifyEventMessage), expectedMessage, actualMessage); + } + + private static void AssertEqual(string methodName, T expected, T actual) + { + if (!expected.Equals(actual)) { - MethodInfo[] methods = eventSource.GetType().GetMethods(); - return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Any()); + var errorMessage = string.Format( + CultureInfo.InvariantCulture, + "{0} Failed: expected: '{1}' actual: '{2}'", + methodName, + expected, + actual); + throw new Exception(errorMessage); } } + + private static EventAttribute GetEventAttribute(MethodInfo eventMethod) + { + return (EventAttribute)eventMethod.GetCustomAttributes(typeof(EventAttribute), false).Single(); + } + + private static IEnumerable GetEventMethods(EventSource eventSource) + { + MethodInfo[] methods = eventSource.GetType().GetMethods(); + return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Any()); + } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs index dfaf067fe6..0799387e56 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs @@ -17,20 +17,19 @@ using System.Collections.Concurrent; using System.Diagnostics.Tracing; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal class InMemoryEventListener : EventListener { - internal class InMemoryEventListener : EventListener - { - public ConcurrentQueue Events = new(); + public ConcurrentQueue Events = new(); - public InMemoryEventListener(EventSource eventSource, EventLevel minLevel = EventLevel.Verbose) - { - this.EnableEvents(eventSource, minLevel); - } + public InMemoryEventListener(EventSource eventSource, EventLevel minLevel = EventLevel.Verbose) + { + this.EnableEvents(eventSource, minLevel); + } - protected override void OnEventWritten(EventWrittenEventArgs eventData) - { - this.Events.Enqueue(eventData); - } + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + this.Events.Enqueue(eventData); } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 0b0ebe1f34..34b96ceae4 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -16,28 +16,27 @@ using System; using Xunit; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal class SkipUnlessEnvVarFoundTheoryAttribute : TheoryAttribute { - internal class SkipUnlessEnvVarFoundTheoryAttribute : TheoryAttribute + public SkipUnlessEnvVarFoundTheoryAttribute(string environmentVariable) { - public SkipUnlessEnvVarFoundTheoryAttribute(string environmentVariable) + if (string.IsNullOrEmpty(GetEnvironmentVariable(environmentVariable))) { - if (string.IsNullOrEmpty(GetEnvironmentVariable(environmentVariable))) - { - this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; - } + this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; } + } - public static string GetEnvironmentVariable(string environmentVariableName) - { - string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); - - if (string.IsNullOrEmpty(environmentVariableValue)) - { - environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine); - } + public static string GetEnvironmentVariable(string environmentVariableName) + { + string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); - return environmentVariableValue; + if (string.IsNullOrEmpty(environmentVariableValue)) + { + environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine); } + + return environmentVariableValue; } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs index 64894b6cf1..129e806e3a 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs @@ -17,20 +17,19 @@ using System.Collections.Generic; using System.Diagnostics; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal class TestActivityExportProcessor : SimpleActivityExportProcessor { - internal class TestActivityExportProcessor : SimpleActivityExportProcessor - { - public List ExportedItems = new List(); + public List ExportedItems = new List(); - public TestActivityExportProcessor(BaseExporter exporter) - : base(exporter) - { - } + public TestActivityExportProcessor(BaseExporter exporter) + : base(exporter) + { + } - protected override void OnExport(Activity data) - { - this.ExportedItems.Add(data); - } + protected override void OnExport(Activity data) + { + this.ExportedItems.Add(data); } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs index 0ec90b07b7..dc127c38f8 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs @@ -17,54 +17,53 @@ using System; using System.Diagnostics; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal class TestActivityProcessor : BaseProcessor { - internal class TestActivityProcessor : BaseProcessor - { - public Action StartAction; - public Action EndAction; + public Action StartAction; + public Action EndAction; - public TestActivityProcessor() - { - } + public TestActivityProcessor() + { + } - public TestActivityProcessor(Action onStart, Action onEnd) - { - this.StartAction = onStart; - this.EndAction = onEnd; - } + public TestActivityProcessor(Action onStart, Action onEnd) + { + this.StartAction = onStart; + this.EndAction = onEnd; + } - public bool ShutdownCalled { get; private set; } = false; + public bool ShutdownCalled { get; private set; } = false; - public bool ForceFlushCalled { get; private set; } = false; + public bool ForceFlushCalled { get; private set; } = false; - public bool DisposedCalled { get; private set; } = false; + public bool DisposedCalled { get; private set; } = false; - public override void OnStart(Activity span) - { - this.StartAction?.Invoke(span); - } + public override void OnStart(Activity span) + { + this.StartAction?.Invoke(span); + } - public override void OnEnd(Activity span) - { - this.EndAction?.Invoke(span); - } + public override void OnEnd(Activity span) + { + this.EndAction?.Invoke(span); + } - protected override bool OnForceFlush(int timeoutMilliseconds) - { - this.ForceFlushCalled = true; - return true; - } + protected override bool OnForceFlush(int timeoutMilliseconds) + { + this.ForceFlushCalled = true; + return true; + } - protected override bool OnShutdown(int timeoutMilliseconds) - { - this.ShutdownCalled = true; - return true; - } + protected override bool OnShutdown(int timeoutMilliseconds) + { + this.ShutdownCalled = true; + return true; + } - protected override void Dispose(bool disposing) - { - this.DisposedCalled = true; - } + protected override void Dispose(bool disposing) + { + this.DisposedCalled = true; } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs index 9c6ffc3e56..7bd3d7fc36 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs @@ -19,80 +19,79 @@ using System.Diagnostics.Tracing; using System.Threading; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +/// +/// Event listener for testing event sources. +/// +internal class TestEventListener : EventListener { + /// A queue of events that have been logged. + private readonly Queue events; + /// - /// Event listener for testing event sources. + /// Lock for event writing tracking. /// - internal class TestEventListener : EventListener - { - /// A queue of events that have been logged. - private readonly Queue events; - - /// - /// Lock for event writing tracking. - /// - private readonly AutoResetEvent eventWritten; + private readonly AutoResetEvent eventWritten; - /// - /// Initializes a new instance of the class. - /// - public TestEventListener() + /// + /// Initializes a new instance of the class. + /// + public TestEventListener() + { + this.events = new Queue(); + this.eventWritten = new AutoResetEvent(false); + this.OnOnEventWritten = e => { - this.events = new Queue(); - this.eventWritten = new AutoResetEvent(false); - this.OnOnEventWritten = e => - { - this.events.Enqueue(e); - this.eventWritten.Set(); - }; - } + this.events.Enqueue(e); + this.eventWritten.Set(); + }; + } - /// Gets or sets the handler for event source creation. - public Action OnOnEventSourceCreated { get; set; } + /// Gets or sets the handler for event source creation. + public Action OnOnEventSourceCreated { get; set; } - /// Gets or sets the handler for event source writes. - public Action OnOnEventWritten { get; set; } + /// Gets or sets the handler for event source writes. + public Action OnOnEventWritten { get; set; } - /// Gets the events that have been written. - public IEnumerable Messages + /// Gets the events that have been written. + public IEnumerable Messages + { + get { - get + if (this.events.Count == 0) { - if (this.events.Count == 0) - { - this.eventWritten.WaitOne(TimeSpan.FromSeconds(5)); - } + this.eventWritten.WaitOne(TimeSpan.FromSeconds(5)); + } - while (this.events.Count != 0) - { - yield return this.events.Dequeue(); - } + while (this.events.Count != 0) + { + yield return this.events.Dequeue(); } } + } - /// - /// Clears all event messages so that testing can assert expected counts. - /// - public void ClearMessages() - { - this.events.Clear(); - } + /// + /// Clears all event messages so that testing can assert expected counts. + /// + public void ClearMessages() + { + this.events.Clear(); + } - /// Handler for event source writes. - /// The event data that was written. - protected override void OnEventWritten(EventWrittenEventArgs eventData) - { - this.OnOnEventWritten(eventData); - } + /// Handler for event source writes. + /// The event data that was written. + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + this.OnOnEventWritten(eventData); + } - /// Handler for event source creation. - /// The event source that was created. - protected override void OnEventSourceCreated(EventSource eventSource) - { - // Check for null because this method is called by the base class constror before we can initialize it - Action callback = this.OnOnEventSourceCreated; - callback?.Invoke(eventSource); - } + /// Handler for event source creation. + /// The event source that was created. + protected override void OnEventSourceCreated(EventSource eventSource) + { + // Check for null because this method is called by the base class constror before we can initialize it + Action callback = this.OnOnEventSourceCreated; + callback?.Invoke(eventSource); } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs index a4f4d94272..3f48da917e 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs @@ -16,23 +16,22 @@ using System; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal class TestExporter : BaseExporter + where T : class { - internal class TestExporter : BaseExporter - where T : class - { - private readonly Action> processBatchAction; + private readonly Action> processBatchAction; - public TestExporter(Action> processBatchAction) - { - this.processBatchAction = processBatchAction ?? throw new ArgumentNullException(nameof(processBatchAction)); - } + public TestExporter(Action> processBatchAction) + { + this.processBatchAction = processBatchAction ?? throw new ArgumentNullException(nameof(processBatchAction)); + } - public override ExportResult Export(in Batch batch) - { - this.processBatchAction(batch); + public override ExportResult Export(in Batch batch) + { + this.processBatchAction(batch); - return ExportResult.Success; - } + return ExportResult.Success; } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs index eff653f063..7ab20376a3 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs @@ -17,18 +17,17 @@ using System; using OpenTelemetry.Trace; -namespace OpenTelemetry.Tests +namespace OpenTelemetry.Tests; + +internal class TestSampler : Sampler { - internal class TestSampler : Sampler - { - public Func SamplingAction { get; set; } + public Func SamplingAction { get; set; } - public SamplingParameters LatestSamplingParameters { get; private set; } + public SamplingParameters LatestSamplingParameters { get; private set; } - public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) - { - this.LatestSamplingParameters = samplingParameters; - return this.SamplingAction?.Invoke(samplingParameters) ?? new SamplingResult(SamplingDecision.RecordAndSample); - } + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + this.LatestSamplingParameters = samplingParameters; + return this.SamplingAction?.Invoke(samplingParameters) ?? new SamplingResult(SamplingDecision.RecordAndSample); } } From e0fc5836c08f3b55d691d35f0931fa8f0d826755 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 29 Jul 2022 11:42:26 -0700 Subject: [PATCH 0260/1499] [Exporter.Geneva] Add support for ILogger scopes back (#545) * Add scopes --- .../CHANGELOG.md | 7 ++ .../GenevaLogExporter.cs | 38 ++++++ .../GenevaLogExporterTests.cs | 111 ++++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index ced48e87cc..daee2190bf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.4.0.beta.1 + +Released 2022-Jul-29 + +* Add support for exporting `ILogger` scopes. +[545](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/545) + ## 1.3.0 Released 2022-Jul-28 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index b074947b49..5f7d4cdd5c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -390,6 +390,44 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; } + ushort scopeDepth = 0; + int indexArrayLength = 0; + logRecord.ForEachScope(ProcessScope, (object)null); + void ProcessScope(LogRecordScope scope, object state) + { + if (++scopeDepth == 1) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "scopes"); + cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); + indexArrayLength = cursor - 2; + } + + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); + int indexMapSizeScope = cursor - 2; + ushort keysCount = 0; + + foreach (KeyValuePair scopeItem in scope) + { + string key = "scope"; + if (!string.IsNullOrEmpty(scopeItem.Key)) + { + key = scopeItem.Key; + } + + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); + keysCount++; + } + + MessagePackSerializer.WriteUInt16(buffer, indexMapSizeScope, keysCount); + } + + if (scopeDepth > 0) + { + MessagePackSerializer.WriteUInt16(buffer, indexArrayLength, scopeDepth); + cntFields += 1; + } + if (hasEnvProperties) { // Iteration #2 - Get all "other" fields and collapse them into single field diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index c665fe85d2..eacb679eba 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -351,6 +351,117 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() } } + [Fact] + public void SerializeILoggerScopes() + { + string path = string.Empty; + Socket senderSocket = null; + Socket receiverSocket = null; + try + { + var exporterOptions = new GenevaExporterOptions(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + senderSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + senderSocket.Bind(endpoint); + senderSocket.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.IncludeScopes = true; + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + }); + })); + + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + receiverSocket = senderSocket.Accept(); + receiverSocket.ReceiveTimeout = 10000; + } + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); + + using (logger.BeginScope("MyOuterScope")) + using (logger.BeginScope("MyInnerScope")) + using (logger.BeginScope("MyInnerInnerScope with {name} and {age} of custom", "John Doe", 35)) + using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) + { + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + byte[] serializedData; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + serializedData = m_buffer.Value; + } + else + { + // Read the data sent via socket. + serializedData = new byte[65360]; + _ = receiverSocket.Receive(serializedData); + } + + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var serializedScopes = mapping["scopes"] as object[]; + + Assert.Equal(4, serializedScopes.Length); + + // Test 1st scope + var scope = serializedScopes[0] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("scope", "MyOuterScope"), scope); + + // Test 2nd scope + scope = serializedScopes[1] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("scope", "MyInnerScope"), scope); + + // Test 3rd scope + scope = serializedScopes[2] as ICollection>; + Assert.Equal(3, scope.Count); + Assert.Contains(new KeyValuePair("name", "John Doe"), scope); + Assert.Contains(new KeyValuePair("age", (byte)35), scope); + Assert.Contains(new KeyValuePair("{OriginalFormat}", "MyInnerInnerScope with {name} and {age} of custom"), scope); + + // Test 4th scope + scope = serializedScopes[3] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("MyKey", "MyValue"), scope); + } + finally + { + senderSocket?.Dispose(); + receiverSocket?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + [Theory] [InlineData(true)] [InlineData(false)] From c062c5a36bc86b3353511f53b74dc1af821eeb01 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 29 Jul 2022 17:48:59 -0700 Subject: [PATCH 0261/1499] [Exporter.Geneva] Add test case for multithreading scenarios (#549) --- .../GenevaLogExporterTests.cs | 18 ++++++++++++++++++ .../GenevaTraceExporterTests.cs | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index eacb679eba..91d82c38c3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -24,6 +24,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; using Xunit; @@ -871,6 +872,23 @@ public void SuccessfulExportOnLinux() // Validation Assert.Equal(messagePackDataSize, receivedDataSize); + + logRecordList.Clear(); + + // Emit log on a different thread to test for multithreading scenarios + var thread = new Thread(() => + { + logger.LogInformation("Hello from another thread {food} {price}.", "artichoke", 3.99); + }); + thread.Start(); + thread.Join(); + + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); + + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + receivedDataSize = serverSocket.Receive(receivedData); + Assert.Equal(messagePackDataSize, receivedDataSize); } finally { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index ba3929e81e..a75d66c5f6 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -24,6 +24,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; using OpenTelemetry.Trace; using Xunit; @@ -414,6 +415,7 @@ public void GenevaTraceExporter_Success_Linux() }) .Build(); using Socket serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. var exporter = new GenevaTraceExporter(new GenevaExporterOptions @@ -429,7 +431,8 @@ public void GenevaTraceExporter_Success_Linux() // Emit trace and grab a copy of internal buffer for validation. var source = new ActivitySource(sourceName); - int messagePackDataSize; + int messagePackDataSize = 0; + using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) { messagePackDataSize = exporter.SerializeActivity(activity); @@ -441,6 +444,20 @@ public void GenevaTraceExporter_Success_Linux() // Validation Assert.Equal(messagePackDataSize, receivedDataSize); + + // Create activity on a different thread to test for multithreading scenarios + var thread = new Thread(() => + { + using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) + { + messagePackDataSize = exporter.SerializeActivity(activity); + } + }); + thread.Start(); + thread.Join(); + + receivedDataSize = serverSocket.Receive(receivedData); + Assert.Equal(messagePackDataSize, receivedDataSize); } catch (Exception) { From 355643cf5be993fe055d62b0f9121b46531a063c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 1 Aug 2022 23:11:52 +0200 Subject: [PATCH 0262/1499] File scoped namespace for StackExchangeRedis (#552) --- .../RedisProfilerEntryToActivityConverter.cs | 275 ++++---- .../StackExchangeRedisCallsInstrumentation.cs | 191 +++--- ...xchangeRedisCallsInstrumentationOptions.cs | 49 +- .../TracerProviderBuilderExtensions.cs | 103 ++- ...isProfilerEntryToActivityConverterTests.cs | 239 ++++--- ...kExchangeRedisCallsInstrumentationTests.cs | 595 +++++++++--------- 6 files changed, 723 insertions(+), 729 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index efb2f7db29..0cd0bdc319 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -23,190 +23,189 @@ using OpenTelemetry.Trace; using StackExchange.Redis.Profiling; -namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; + +internal static class RedisProfilerEntryToActivityConverter { - internal static class RedisProfilerEntryToActivityConverter + private static readonly Lazy> MessageDataGetter = new(() => { - private static readonly Lazy> MessageDataGetter = new(() => - { - var redisAssembly = typeof(IProfiledCommand).Assembly; - Type profiledCommandType = redisAssembly.GetType("StackExchange.Redis.Profiling.ProfiledCommand"); - Type scriptMessageType = redisAssembly.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage"); + var redisAssembly = typeof(IProfiledCommand).Assembly; + Type profiledCommandType = redisAssembly.GetType("StackExchange.Redis.Profiling.ProfiledCommand"); + Type scriptMessageType = redisAssembly.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage"); - var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); - var scriptDelegate = CreateFieldGetter(scriptMessageType, "script", BindingFlags.NonPublic | BindingFlags.Instance); - var commandAndKeyFetcher = new PropertyFetcher("CommandAndKey"); + var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); + var scriptDelegate = CreateFieldGetter(scriptMessageType, "script", BindingFlags.NonPublic | BindingFlags.Instance); + var commandAndKeyFetcher = new PropertyFetcher("CommandAndKey"); + + if (messageDelegate == null) + { + return new Func(source => (null, null)); + } - if (messageDelegate == null) + return new Func(source => + { + if (source == null) { - return new Func(source => (null, null)); + return (null, null); } - return new Func(source => + var message = messageDelegate(source); + if (message == null) { - if (source == null) - { - return (null, null); - } - - var message = messageDelegate(source); - if (message == null) - { - return (null, null); - } + return (null, null); + } - string script = null; - if (message.GetType() == scriptMessageType) - { - script = scriptDelegate.Invoke(message); - } + string script = null; + if (message.GetType() == scriptMessageType) + { + script = scriptDelegate.Invoke(message); + } - if (commandAndKeyFetcher.TryFetch(message, out var value)) - { - return (value, script); - } + if (commandAndKeyFetcher.TryFetch(message, out var value)) + { + return (value, script); + } - return (null, script); - }); + return (null, script); }); + }); - public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfiledCommand command, StackExchangeRedisCallsInstrumentationOptions options) + public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfiledCommand command, StackExchangeRedisCallsInstrumentationOptions options) + { + var name = command.Command; // Example: SET; + if (string.IsNullOrEmpty(name)) { - var name = command.Command; // Example: SET; - if (string.IsNullOrEmpty(name)) - { - name = StackExchangeRedisCallsInstrumentation.ActivityName; - } + name = StackExchangeRedisCallsInstrumentation.ActivityName; + } - var activity = StackExchangeRedisCallsInstrumentation.ActivitySource.StartActivity( - name, - ActivityKind.Client, - parentActivity?.Context ?? default, - StackExchangeRedisCallsInstrumentation.CreationTags, - startTime: command.CommandCreated); + var activity = StackExchangeRedisCallsInstrumentation.ActivitySource.StartActivity( + name, + ActivityKind.Client, + parentActivity?.Context ?? default, + StackExchangeRedisCallsInstrumentation.CreationTags, + startTime: command.CommandCreated); - if (activity == null) - { - return null; - } + if (activity == null) + { + return null; + } - activity.SetEndTime(command.CommandCreated + command.ElapsedTime); + activity.SetEndTime(command.CommandCreated + command.ElapsedTime); - if (activity.IsAllDataRequested) - { - // see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md + if (activity.IsAllDataRequested) + { + // see https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md - // Timing example: - // command.CommandCreated; //2019-01-10 22:18:28Z + // Timing example: + // command.CommandCreated; //2019-01-10 22:18:28Z - // command.CreationToEnqueued; // 00:00:32.4571995 - // command.EnqueuedToSending; // 00:00:00.0352838 - // command.SentToResponse; // 00:00:00.0060586 - // command.ResponseToCompletion; // 00:00:00.0002601 + // command.CreationToEnqueued; // 00:00:32.4571995 + // command.EnqueuedToSending; // 00:00:00.0352838 + // command.SentToResponse; // 00:00:00.0060586 + // command.ResponseToCompletion; // 00:00:00.0002601 - // Total: - // command.ElapsedTime; // 00:00:32.4988020 + // Total: + // command.ElapsedTime; // 00:00:32.4988020 - activity.SetStatus(Status.Unset); + activity.SetStatus(Status.Unset); - activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName, command.Flags.ToString()); + activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName, command.Flags.ToString()); - if (options.SetVerboseDatabaseStatements) + if (options.SetVerboseDatabaseStatements) + { + var (commandAndKey, script) = MessageDataGetter.Value.Invoke(command); + + if (!string.IsNullOrEmpty(commandAndKey) && !string.IsNullOrEmpty(script)) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, commandAndKey + " " + script); + } + else if (!string.IsNullOrEmpty(commandAndKey)) { - var (commandAndKey, script) = MessageDataGetter.Value.Invoke(command); - - if (!string.IsNullOrEmpty(commandAndKey) && !string.IsNullOrEmpty(script)) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, commandAndKey + " " + script); - } - else if (!string.IsNullOrEmpty(commandAndKey)) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, commandAndKey); - } - else if (command.Command != null) - { - // Example: "db.statement": SET; - activity.SetTag(SemanticConventions.AttributeDbStatement, command.Command); - } + activity.SetTag(SemanticConventions.AttributeDbStatement, commandAndKey); } else if (command.Command != null) { // Example: "db.statement": SET; activity.SetTag(SemanticConventions.AttributeDbStatement, command.Command); } + } + else if (command.Command != null) + { + // Example: "db.statement": SET; + activity.SetTag(SemanticConventions.AttributeDbStatement, command.Command); + } - if (command.EndPoint != null) + if (command.EndPoint != null) + { + if (command.EndPoint is IPEndPoint ipEndPoint) { - if (command.EndPoint is IPEndPoint ipEndPoint) - { - activity.SetTag(SemanticConventions.AttributeNetPeerIp, ipEndPoint.Address.ToString()); - activity.SetTag(SemanticConventions.AttributeNetPeerPort, ipEndPoint.Port); - } - else if (command.EndPoint is DnsEndPoint dnsEndPoint) - { - activity.SetTag(SemanticConventions.AttributeNetPeerName, dnsEndPoint.Host); - activity.SetTag(SemanticConventions.AttributeNetPeerPort, dnsEndPoint.Port); - } - else - { - activity.SetTag(SemanticConventions.AttributePeerService, command.EndPoint.ToString()); - } + activity.SetTag(SemanticConventions.AttributeNetPeerIp, ipEndPoint.Address.ToString()); + activity.SetTag(SemanticConventions.AttributeNetPeerPort, ipEndPoint.Port); } - - activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName, command.Db); - - // TODO: deal with the re-transmission - // command.RetransmissionOf; - // command.RetransmissionReason; - - var enqueued = command.CommandCreated.Add(command.CreationToEnqueued); - var send = enqueued.Add(command.EnqueuedToSending); - var response = send.Add(command.SentToResponse); - - if (options.EnrichActivityWithTimingEvents) + else if (command.EndPoint is DnsEndPoint dnsEndPoint) { - activity.AddEvent(new ActivityEvent("Enqueued", enqueued)); - activity.AddEvent(new ActivityEvent("Sent", send)); - activity.AddEvent(new ActivityEvent("ResponseReceived", response)); + activity.SetTag(SemanticConventions.AttributeNetPeerName, dnsEndPoint.Host); + activity.SetTag(SemanticConventions.AttributeNetPeerPort, dnsEndPoint.Port); + } + else + { + activity.SetTag(SemanticConventions.AttributePeerService, command.EndPoint.ToString()); } - - options.Enrich?.Invoke(activity, command); } - activity.Stop(); + activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName, command.Db); - return activity; - } + // TODO: deal with the re-transmission + // command.RetransmissionOf; + // command.RetransmissionReason; - public static void DrainSession(Activity parentActivity, IEnumerable sessionCommands, StackExchangeRedisCallsInstrumentationOptions options) - { - foreach (var command in sessionCommands) + var enqueued = command.CommandCreated.Add(command.CreationToEnqueued); + var send = enqueued.Add(command.EnqueuedToSending); + var response = send.Add(command.SentToResponse); + + if (options.EnrichActivityWithTimingEvents) { - ProfilerCommandToActivity(parentActivity, command, options); + activity.AddEvent(new ActivityEvent("Enqueued", enqueued)); + activity.AddEvent(new ActivityEvent("Sent", send)); + activity.AddEvent(new ActivityEvent("ResponseReceived", response)); } + + options.Enrich?.Invoke(activity, command); } - /// - /// Creates getter for a field defined in private or internal type - /// represented with classType variable. - /// - private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) + activity.Stop(); + + return activity; + } + + public static void DrainSession(Activity parentActivity, IEnumerable sessionCommands, StackExchangeRedisCallsInstrumentationOptions options) + { + foreach (var command in sessionCommands) { - FieldInfo field = classType.GetField(fieldName, flags); - if (field != null) - { - string methodName = classType.FullName + ".get_" + field.Name; - DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); - ILGenerator generator = getterMethod.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Castclass, classType); - generator.Emit(OpCodes.Ldfld, field); - generator.Emit(OpCodes.Ret); - - return (Func)getterMethod.CreateDelegate(typeof(Func)); - } + ProfilerCommandToActivity(parentActivity, command, options); + } + } - return null; + /// + /// Creates getter for a field defined in private or internal type + /// represented with classType variable. + /// + private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) + { + FieldInfo field = classType.GetField(fieldName, flags); + if (field != null) + { + string methodName = classType.FullName + ".get_" + field.Name; + DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); + ILGenerator generator = getterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, classType); + generator.Emit(OpCodes.Ldfld, field); + generator.Emit(OpCodes.Ret); + + return (Func)getterMethod.CreateDelegate(typeof(Func)); } + + return null; } } diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs index 92eb51ec61..8d451142cd 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs @@ -25,128 +25,127 @@ using StackExchange.Redis; using StackExchange.Redis.Profiling; -namespace OpenTelemetry.Instrumentation.StackExchangeRedis +namespace OpenTelemetry.Instrumentation.StackExchangeRedis; + +/// +/// Redis calls instrumentation. +/// +internal class StackExchangeRedisCallsInstrumentation : IDisposable { + internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; + internal const string RedisFlagsKeyName = "db.redis.flags"; + internal static readonly string ActivitySourceName = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Name; + internal static readonly string ActivityName = ActivitySourceName + ".Execute"; + internal static readonly Version Version = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Version; + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly IEnumerable> CreationTags = new[] + { + new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), + }; + + internal readonly ConcurrentDictionary<(ActivityTraceId TraceId, ActivitySpanId SpanId), (Activity Activity, ProfilingSession Session)> Cache + = new(); + + private readonly StackExchangeRedisCallsInstrumentationOptions options; + private readonly EventWaitHandle stopHandle = new(false, EventResetMode.ManualReset); + private readonly Thread drainThread; + + private readonly ProfilingSession defaultSession = new(); + /// - /// Redis calls instrumentation. + /// Initializes a new instance of the class. /// - internal class StackExchangeRedisCallsInstrumentation : IDisposable + /// to instrument. + /// Configuration options for redis instrumentation. + public StackExchangeRedisCallsInstrumentation(IConnectionMultiplexer connection, StackExchangeRedisCallsInstrumentationOptions options) { - internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; - internal const string RedisFlagsKeyName = "db.redis.flags"; - internal static readonly string ActivitySourceName = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Name; - internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - internal static readonly Version Version = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Version; - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); - internal static readonly IEnumerable> CreationTags = new[] - { - new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), - }; + Guard.ThrowIfNull(connection); - internal readonly ConcurrentDictionary<(ActivityTraceId TraceId, ActivitySpanId SpanId), (Activity Activity, ProfilingSession Session)> Cache - = new(); + this.options = options ?? new StackExchangeRedisCallsInstrumentationOptions(); - private readonly StackExchangeRedisCallsInstrumentationOptions options; - private readonly EventWaitHandle stopHandle = new(false, EventResetMode.ManualReset); - private readonly Thread drainThread; + this.drainThread = new Thread(this.DrainEntries) + { + Name = "OpenTelemetry.Redis", + IsBackground = true, + }; + this.drainThread.Start(); - private readonly ProfilingSession defaultSession = new(); + connection.RegisterProfiler(this.GetProfilerSessionsFactory()); + } - /// - /// Initializes a new instance of the class. - /// - /// to instrument. - /// Configuration options for redis instrumentation. - public StackExchangeRedisCallsInstrumentation(IConnectionMultiplexer connection, StackExchangeRedisCallsInstrumentationOptions options) + /// + /// Returns session for the Redis calls recording. + /// + /// Session associated with the current span context to record Redis calls. + public Func GetProfilerSessionsFactory() + { + return () => { - Guard.ThrowIfNull(connection); + if (this.stopHandle.WaitOne(0)) + { + return null; + } - this.options = options ?? new StackExchangeRedisCallsInstrumentationOptions(); + Activity parent = Activity.Current; - this.drainThread = new Thread(this.DrainEntries) + // If no parent use the default session. + if (parent == null || parent.IdFormat != ActivityIdFormat.W3C) { - Name = "OpenTelemetry.Redis", - IsBackground = true, - }; - this.drainThread.Start(); - - connection.RegisterProfiler(this.GetProfilerSessionsFactory()); - } + return this.defaultSession; + } - /// - /// Returns session for the Redis calls recording. - /// - /// Session associated with the current span context to record Redis calls. - public Func GetProfilerSessionsFactory() - { - return () => + // Try to reuse a session for all activities created under the same TraceId+SpanId. + var cacheKey = (parent.TraceId, parent.SpanId); + if (!this.Cache.TryGetValue(cacheKey, out var session)) { - if (this.stopHandle.WaitOne(0)) - { - return null; - } - - Activity parent = Activity.Current; - - // If no parent use the default session. - if (parent == null || parent.IdFormat != ActivityIdFormat.W3C) - { - return this.defaultSession; - } - - // Try to reuse a session for all activities created under the same TraceId+SpanId. - var cacheKey = (parent.TraceId, parent.SpanId); - if (!this.Cache.TryGetValue(cacheKey, out var session)) - { - session = (parent, new ProfilingSession()); - this.Cache.TryAdd(cacheKey, session); - } - - return session.Session; - }; - } + session = (parent, new ProfilingSession()); + this.Cache.TryAdd(cacheKey, session); + } - /// - public void Dispose() - { - this.stopHandle.Set(); - this.drainThread.Join(); + return session.Session; + }; + } - this.Flush(); + /// + public void Dispose() + { + this.stopHandle.Set(); + this.drainThread.Join(); - this.stopHandle.Dispose(); - } + this.Flush(); - internal void Flush() - { - RedisProfilerEntryToActivityConverter.DrainSession(null, this.defaultSession.FinishProfiling(), this.options); + this.stopHandle.Dispose(); + } - foreach (var entry in this.Cache) + internal void Flush() + { + RedisProfilerEntryToActivityConverter.DrainSession(null, this.defaultSession.FinishProfiling(), this.options); + + foreach (var entry in this.Cache) + { + var parent = entry.Value.Activity; + if (parent.Duration == TimeSpan.Zero) { - var parent = entry.Value.Activity; - if (parent.Duration == TimeSpan.Zero) - { - // Activity is still running, don't drain. - continue; - } - - ProfilingSession session = entry.Value.Session; - RedisProfilerEntryToActivityConverter.DrainSession(parent, session.FinishProfiling(), this.options); - this.Cache.TryRemove((entry.Key.TraceId, entry.Key.SpanId), out _); + // Activity is still running, don't drain. + continue; } + + ProfilingSession session = entry.Value.Session; + RedisProfilerEntryToActivityConverter.DrainSession(parent, session.FinishProfiling(), this.options); + this.Cache.TryRemove((entry.Key.TraceId, entry.Key.SpanId), out _); } + } - private void DrainEntries(object state) + private void DrainEntries(object state) + { + while (true) { - while (true) + if (this.stopHandle.WaitOne(this.options.FlushInterval)) { - if (this.stopHandle.WaitOne(this.options.FlushInterval)) - { - break; - } - - this.Flush(); + break; } + + this.Flush(); } } } diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs index 81b37b485d..4b9e7c99f3 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs @@ -19,35 +19,34 @@ using OpenTelemetry.Trace; using StackExchange.Redis.Profiling; -namespace OpenTelemetry.Instrumentation.StackExchangeRedis +namespace OpenTelemetry.Instrumentation.StackExchangeRedis; + +/// +/// Options for StackExchange.Redis instrumentation. +/// +public class StackExchangeRedisCallsInstrumentationOptions { /// - /// Options for StackExchange.Redis instrumentation. + /// Gets or sets the maximum time that should elapse between flushing the internal buffer of Redis profiling sessions and creating objects. Default value: 00:00:10. /// - public class StackExchangeRedisCallsInstrumentationOptions - { - /// - /// Gets or sets the maximum time that should elapse between flushing the internal buffer of Redis profiling sessions and creating objects. Default value: 00:00:10. - /// - public TimeSpan FlushInterval { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan FlushInterval { get; set; } = TimeSpan.FromSeconds(10); - /// - /// Gets or sets a value indicating whether or not the should use reflection to get more detailed tag values. Default value: False. - /// - public bool SetVerboseDatabaseStatements { get; set; } + /// + /// Gets or sets a value indicating whether or not the should use reflection to get more detailed tag values. Default value: False. + /// + public bool SetVerboseDatabaseStatements { get; set; } - /// - /// Gets or sets an action to enrich an Activity. - /// - /// - /// : the activity being enriched. - /// : the profiled redis command from which additional information can be extracted to enrich the activity. - /// - public Action Enrich { get; set; } + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the profiled redis command from which additional information can be extracted to enrich the activity. + /// + public Action Enrich { get; set; } - /// - /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. - /// - public bool EnrichActivityWithTimingEvents { get; set; } = true; - } + /// + /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. + /// + public bool EnrichActivityWithTimingEvents { get; set; } = true; } diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index 2d99482051..22c7e56494 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -19,72 +19,71 @@ using OpenTelemetry.Internal; using StackExchange.Redis; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables automatic data collection of outgoing requests to Redis. /// - public static class TracerProviderBuilderExtensions + /// + /// Note: If an is not supplied + /// using the parameter it will be + /// resolved using the application . + /// + /// being configured. + /// Optional to instrument. + /// Optional callback to configure options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + IConnectionMultiplexer connection = null, + Action configure = null) { - /// - /// Enables automatic data collection of outgoing requests to Redis. - /// - /// - /// Note: If an is not supplied - /// using the parameter it will be - /// resolved using the application . - /// - /// being configured. - /// Optional to instrument. - /// Optional callback to configure options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddRedisInstrumentation( - this TracerProviderBuilder builder, - IConnectionMultiplexer connection = null, - Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - if (builder is not IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + if (builder is not IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + if (connection == null) { - if (connection == null) - { - throw new NotSupportedException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} must be supplied when dependency injection is unavailable - to enable dependency injection use the OpenTelemetry.Extensions.Hosting package"); - } - - return AddRedisInstrumentation(builder, connection, new StackExchangeRedisCallsInstrumentationOptions(), configure); + throw new NotSupportedException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} must be supplied when dependency injection is unavailable - to enable dependency injection use the OpenTelemetry.Extensions.Hosting package"); } - return deferredTracerProviderBuilder.Configure((sp, builder) => + return AddRedisInstrumentation(builder, connection, new StackExchangeRedisCallsInstrumentationOptions(), configure); + } + + return deferredTracerProviderBuilder.Configure((sp, builder) => + { + if (connection == null) { + connection = (IConnectionMultiplexer)sp.GetService(typeof(IConnectionMultiplexer)); if (connection == null) { - connection = (IConnectionMultiplexer)sp.GetService(typeof(IConnectionMultiplexer)); - if (connection == null) - { - throw new InvalidOperationException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} could not be resolved through application {nameof(IServiceProvider)}"); - } + throw new InvalidOperationException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} could not be resolved through application {nameof(IServiceProvider)}"); } + } - AddRedisInstrumentation( - builder, - connection, - sp.GetOptions(), - configure); - }); - } + AddRedisInstrumentation( + builder, + connection, + sp.GetOptions(), + configure); + }); + } - private static TracerProviderBuilder AddRedisInstrumentation( - TracerProviderBuilder builder, - IConnectionMultiplexer connection, - StackExchangeRedisCallsInstrumentationOptions options, - Action configure) - { - configure?.Invoke(options); + private static TracerProviderBuilder AddRedisInstrumentation( + TracerProviderBuilder builder, + IConnectionMultiplexer connection, + StackExchangeRedisCallsInstrumentationOptions options, + Action configure) + { + configure?.Invoke(options); - return builder - .AddInstrumentation(() => new StackExchangeRedisCallsInstrumentation(connection, options)) - .AddSource(StackExchangeRedisCallsInstrumentation.ActivitySourceName); - } + return builder + .AddInstrumentation(() => new StackExchangeRedisCallsInstrumentation(connection, options)) + .AddSource(StackExchangeRedisCallsInstrumentation.ActivitySourceName); } } diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index 578e3f613c..f718265990 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -24,158 +24,157 @@ using StackExchange.Redis.Profiling; using Xunit; -namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; + +[Collection("Redis")] +public class RedisProfilerEntryToActivityConverterTests : IDisposable { - [Collection("Redis")] - public class RedisProfilerEntryToActivityConverterTests : IDisposable - { - private readonly ConnectionMultiplexer connection; - private readonly IDisposable tracerProvider; + private readonly ConnectionMultiplexer connection; + private readonly IDisposable tracerProvider; - public RedisProfilerEntryToActivityConverterTests() + public RedisProfilerEntryToActivityConverterTests() + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = false, - }; - connectionOptions.EndPoints.Add("localhost:6379"); + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); - this.connection = ConnectionMultiplexer.Connect(connectionOptions); + this.connection = ConnectionMultiplexer.Connect(connectionOptions); - this.tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddRedisInstrumentation(this.connection) - .Build(); - } + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation(this.connection) + .Build(); + } - public void Dispose() - { - this.tracerProvider.Dispose(); - this.connection.Dispose(); - GC.SuppressFinalize(this); - } + public void Dispose() + { + this.tracerProvider.Dispose(); + this.connection.Dispose(); + GC.SuppressFinalize(this); + } - [Fact] - public void ProfilerCommandToActivity_UsesCommandAsName() - { - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.Command).Returns("SET"); + [Fact] + public void ProfilerCommandToActivity_UsesCommandAsName() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.Command).Returns("SET"); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.Equal("SET", result.DisplayName); - } + Assert.Equal("SET", result.DisplayName); + } - [Fact] - public void ProfilerCommandToActivity_UsesTimestampAsStartTime() - { - var now = DateTimeOffset.Now; - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(now.DateTime); + [Fact] + public void ProfilerCommandToActivity_UsesTimestampAsStartTime() + { + var now = DateTimeOffset.Now; + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(now.DateTime); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.Equal(now, result.StartTimeUtc); - } + Assert.Equal(now, result.StartTimeUtc); + } - [Fact] - public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() - { - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + [Fact] + public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("redis", result.GetTagValue(SemanticConventions.AttributeDbSystem)); - } + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("redis", result.GetTagValue(SemanticConventions.AttributeDbSystem)); + } - [Fact] - public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() - { - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.Command).Returns("SET"); + [Fact] + public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.Command).Returns("SET"); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbStatement)); - Assert.Equal("SET", result.GetTagValue(SemanticConventions.AttributeDbStatement)); - } + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbStatement)); + Assert.Equal("SET", result.GetTagValue(SemanticConventions.AttributeDbStatement)); + } - [Fact] - public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() - { - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - var expectedFlags = CommandFlags.FireAndForget | - CommandFlags.NoRedirect; - profiledCommand.Setup(m => m.Flags).Returns(expectedFlags); + [Fact] + public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() + { + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + var expectedFlags = CommandFlags.FireAndForget | + CommandFlags.NoRedirect; + profiledCommand.Setup(m => m.Flags).Returns(expectedFlags); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); - Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); - } + Assert.NotNull(result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); + Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); + } - [Fact] - public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() - { - long address = 1; - int port = 2; + [Fact] + public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() + { + long address = 1; + int port = 2; - var activity = new Activity("redis-profiler"); - IPEndPoint ipLocalEndPoint = new IPEndPoint(address, port); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.EndPoint).Returns(ipLocalEndPoint); + var activity = new Activity("redis-profiler"); + IPEndPoint ipLocalEndPoint = new IPEndPoint(address, port); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.EndPoint).Returns(ipLocalEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); - Assert.Equal($"{address}.0.0.0", result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(port, result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - } + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); + Assert.Equal($"{address}.0.0.0", result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal(port, result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } - [Fact] - public void ProfilerCommandToActivity_UsesDnsEndPointAsEndPoint() - { - var dnsEndPoint = new DnsEndPoint("https://opentelemetry.io/", 443); + [Fact] + public void ProfilerCommandToActivity_UsesDnsEndPointAsEndPoint() + { + var dnsEndPoint = new DnsEndPoint("https://opentelemetry.io/", 443); - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.EndPoint).Returns(dnsEndPoint); + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.EndPoint).Returns(dnsEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(dnsEndPoint.Host, result.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(dnsEndPoint.Port, result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - } + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(dnsEndPoint.Host, result.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal(dnsEndPoint.Port, result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } #if !NETFRAMEWORK - [Fact] - public void ProfilerCommandToActivity_UsesOtherEndPointAsEndPoint() - { - var unixEndPoint = new UnixDomainSocketEndPoint("https://opentelemetry.io/"); - var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.EndPoint).Returns(unixEndPoint); + [Fact] + public void ProfilerCommandToActivity_UsesOtherEndPointAsEndPoint() + { + var unixEndPoint = new UnixDomainSocketEndPoint("https://opentelemetry.io/"); + var activity = new Activity("redis-profiler"); + var profiledCommand = new Mock(); + profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + profiledCommand.Setup(m => m.EndPoint).Returns(unixEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(SemanticConventions.AttributePeerService)); - Assert.Equal(unixEndPoint.ToString(), result.GetTagValue(SemanticConventions.AttributePeerService)); - } -#endif + Assert.NotNull(result.GetTagValue(SemanticConventions.AttributePeerService)); + Assert.Equal(unixEndPoint.ToString(), result.GetTagValue(SemanticConventions.AttributePeerService)); } +#endif } diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 46a29aa7b6..1066317736 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -25,393 +25,392 @@ using StackExchange.Redis.Profiling; using Xunit; -namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Tests +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Tests; + +[Collection("Redis")] +public class StackExchangeRedisCallsInstrumentationTests { - [Collection("Redis")] - public class StackExchangeRedisCallsInstrumentationTests - { - /* - To run the integration tests, set the OTEL_REDISENDPOINT machine-level environment variable to a valid Redis endpoint. + /* + To run the integration tests, set the OTEL_REDISENDPOINT machine-level environment variable to a valid Redis endpoint. - To use Docker... - 1) Run: docker run -d --name redis -p 6379:6379 redis - 2) Set OTEL_REDISENDPOINT as: localhost:6379 - */ + To use Docker... + 1) Run: docker run -d --name redis -p 6379:6379 redis + 2) Set OTEL_REDISENDPOINT as: localhost:6379 + */ - private const string RedisEndPointEnvVarName = "OTEL_REDISENDPOINT"; - private static readonly string RedisEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(RedisEndPointEnvVarName); + private const string RedisEndPointEnvVarName = "OTEL_REDISENDPOINT"; + private static readonly string RedisEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(RedisEndPointEnvVarName); - [Trait("CategoryName", "RedisIntegrationTests")] - [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] - [InlineData("value1")] - public void SuccessfulCommandTestWithKey(string value) + [Trait("CategoryName", "RedisIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] + [InlineData("value1")] + public void SuccessfulCommandTestWithKey(string value) + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = true, - }; - connectionOptions.EndPoints.Add(RedisEndPoint); - - using var connection = ConnectionMultiplexer.Connect(connectionOptions); - var db = connection.GetDatabase(); - db.KeyDelete("key1"); - - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = true) - .Build()) - { - var prepared = LuaScript.Prepare("redis.call('set', @key, @value)"); - db.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 }); + AbortOnConnectFail = true, + }; + connectionOptions.EndPoints.Add(RedisEndPoint); + + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + var db = connection.GetDatabase(); + db.KeyDelete("key1"); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = true) + .Build()) + { + var prepared = LuaScript.Prepare("redis.call('set', @key, @value)"); + db.ScriptEvaluate(prepared, new { key = (RedisKey)"mykey", value = 123 }); - var redisValue = db.StringGet("key1"); + var redisValue = db.StringGet("key1"); - Assert.False(redisValue.HasValue); + Assert.False(redisValue.HasValue); - bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); - Assert.True(set); + Assert.True(set); - redisValue = db.StringGet("key1"); + redisValue = db.StringGet("key1"); - Assert.True(redisValue.HasValue); - Assert.Equal(value, redisValue.ToString()); - } + Assert.True(redisValue.HasValue); + Assert.Equal(value, redisValue.ToString()); + } - // Disposing SDK should flush the Redis profiling session immediately. + // Disposing SDK should flush the Redis profiling session immediately. - Assert.Equal(11, activityProcessor.Invocations.Count); + Assert.Equal(11, activityProcessor.Invocations.Count); - var scriptActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - Assert.Equal("EVAL", scriptActivity.DisplayName); - Assert.Equal("EVAL redis.call('set', ARGV[1], ARGV[2])", scriptActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); + var scriptActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Equal("EVAL", scriptActivity.DisplayName); + Assert.Equal("EVAL redis.call('set', ARGV[1], ARGV[2])", scriptActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); - VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], true); - VerifyActivityData((Activity)activityProcessor.Invocations[5].Arguments[0], true, connection.GetEndPoints()[0], true); - VerifyActivityData((Activity)activityProcessor.Invocations[7].Arguments[0], false, connection.GetEndPoints()[0], true); - VerifySamplingParameters(sampler.LatestSamplingParameters); - } + VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], true); + VerifyActivityData((Activity)activityProcessor.Invocations[5].Arguments[0], true, connection.GetEndPoints()[0], true); + VerifyActivityData((Activity)activityProcessor.Invocations[7].Arguments[0], false, connection.GetEndPoints()[0], true); + VerifySamplingParameters(sampler.LatestSamplingParameters); + } - [Trait("CategoryName", "RedisIntegrationTests")] - [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] - [InlineData("value1")] - public void SuccessfulCommandTest(string value) + [Trait("CategoryName", "RedisIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] + [InlineData("value1")] + public void SuccessfulCommandTest(string value) + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = true, - }; - connectionOptions.EndPoints.Add(RedisEndPoint); - - using var connection = ConnectionMultiplexer.Connect(connectionOptions); - - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = false) - .Build()) - { - var db = connection.GetDatabase(); + AbortOnConnectFail = true, + }; + connectionOptions.EndPoints.Add(RedisEndPoint); + + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = false) + .Build()) + { + var db = connection.GetDatabase(); - bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); - Assert.True(set); + Assert.True(set); - var redisValue = db.StringGet("key1"); + var redisValue = db.StringGet("key1"); - Assert.True(redisValue.HasValue); - Assert.Equal(value, redisValue.ToString()); - } + Assert.True(redisValue.HasValue); + Assert.Equal(value, redisValue.ToString()); + } - // Disposing SDK should flush the Redis profiling session immediately. + // Disposing SDK should flush the Redis profiling session immediately. - Assert.Equal(7, activityProcessor.Invocations.Count); + Assert.Equal(7, activityProcessor.Invocations.Count); - VerifyActivityData((Activity)activityProcessor.Invocations[1].Arguments[0], true, connection.GetEndPoints()[0], false); - VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], false); - VerifySamplingParameters(sampler.LatestSamplingParameters); - } + VerifyActivityData((Activity)activityProcessor.Invocations[1].Arguments[0], true, connection.GetEndPoints()[0], false); + VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], false); + VerifySamplingParameters(sampler.LatestSamplingParameters); + } - [Fact] - public async void ProfilerSessionUsesTheSameDefault() + [Fact] + public async void ProfilerSessionUsesTheSameDefault() + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = false, - }; - connectionOptions.EndPoints.Add("localhost:6379"); - - var connection = ConnectionMultiplexer.Connect(connectionOptions); - - using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); - var profilerFactory = instrumentation.GetProfilerSessionsFactory(); - var first = profilerFactory(); - var second = profilerFactory(); - ProfilingSession third = null; - await Task.Delay(1).ContinueWith((t) => { third = profilerFactory(); }); - Assert.Equal(first, second); - Assert.Equal(second, third); - } + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); + + var connection = ConnectionMultiplexer.Connect(connectionOptions); + + using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + var profilerFactory = instrumentation.GetProfilerSessionsFactory(); + var first = profilerFactory(); + var second = profilerFactory(); + ProfilingSession third = null; + await Task.Delay(1).ContinueWith((t) => { third = profilerFactory(); }); + Assert.Equal(first, second); + Assert.Equal(second, third); + } - [Trait("CategoryName", "RedisIntegrationTests")] - [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] - [InlineData("value1")] - public void CanEnrichActivityFromCommand(string value) + [Trait("CategoryName", "RedisIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] + [InlineData("value1")] + public void CanEnrichActivityFromCommand(string value) + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = true, - }; - connectionOptions.EndPoints.Add(RedisEndPoint); - - using var connection = ConnectionMultiplexer.Connect(connectionOptions); - - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddRedisInstrumentation(connection, c => c.Enrich = (activity, command) => - { - if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) - { - activity.AddTag("is_fast", true); - } - }) - .Build()) - { - var db = connection.GetDatabase(); + AbortOnConnectFail = true, + }; + connectionOptions.EndPoints.Add(RedisEndPoint); + + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(connection, c => c.Enrich = (activity, command) => + { + if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) + { + activity.AddTag("is_fast", true); + } + }) + .Build()) + { + var db = connection.GetDatabase(); - bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); - Assert.True(set); + Assert.True(set); - var redisValue = db.StringGet("key1"); + var redisValue = db.StringGet("key1"); - Assert.True(redisValue.HasValue); - Assert.Equal(value, redisValue.ToString()); - } + Assert.True(redisValue.HasValue); + Assert.Equal(value, redisValue.ToString()); + } - // Disposing SDK should flush the Redis profiling session immediately. + // Disposing SDK should flush the Redis profiling session immediately. - Assert.Equal(7, activityProcessor.Invocations.Count); + Assert.Equal(7, activityProcessor.Invocations.Count); - var setActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - Assert.Equal(true, setActivity.GetTagValue("is_fast")); - var getActivity = (Activity)activityProcessor.Invocations[3].Arguments[0]; - Assert.Equal(true, getActivity.GetTagValue("is_fast")); - } + var setActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Equal(true, setActivity.GetTagValue("is_fast")); + var getActivity = (Activity)activityProcessor.Invocations[3].Arguments[0]; + Assert.Equal(true, getActivity.GetTagValue("is_fast")); + } - [Fact] - public void CheckCacheIsFlushedProperly() + [Fact] + public void CheckCacheIsFlushedProperly() + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = false, - }; - connectionOptions.EndPoints.Add("localhost:6379"); + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); - var connection = ConnectionMultiplexer.Connect(connectionOptions); + var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); - var profilerFactory = instrumentation.GetProfilerSessionsFactory(); + using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + var profilerFactory = instrumentation.GetProfilerSessionsFactory(); - // start a root level activity - using Activity rootActivity = new Activity("Parent") - .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) - .Start(); + // start a root level activity + using Activity rootActivity = new Activity("Parent") + .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) + .Start(); - Assert.NotNull(rootActivity.Id); + Assert.NotNull(rootActivity.Id); - // get an initial profiler from root activity - Activity.Current = rootActivity; - ProfilingSession profiler0 = profilerFactory(); + // get an initial profiler from root activity + Activity.Current = rootActivity; + ProfilingSession profiler0 = profilerFactory(); - // expect different result from synchronous child activity - ProfilingSession profiler1; - using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) - { - profiler1 = profilerFactory(); - Assert.NotSame(profiler0, profiler1); - } + // expect different result from synchronous child activity + ProfilingSession profiler1; + using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) + { + profiler1 = profilerFactory(); + Assert.NotSame(profiler0, profiler1); + } - rootActivity.Stop(); - rootActivity.Dispose(); + rootActivity.Stop(); + rootActivity.Dispose(); - instrumentation.Flush(); - Assert.Empty(instrumentation.Cache); - } + instrumentation.Flush(); + Assert.Empty(instrumentation.Cache); + } - [Fact] - public async Task ProfilerSessionsHandleMultipleSpans() + [Fact] + public async Task ProfilerSessionsHandleMultipleSpans() + { + var connectionOptions = new ConfigurationOptions { - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = false, - }; - connectionOptions.EndPoints.Add("localhost:6379"); + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost:6379"); - var connection = ConnectionMultiplexer.Connect(connectionOptions); + var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); - var profilerFactory = instrumentation.GetProfilerSessionsFactory(); + using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + var profilerFactory = instrumentation.GetProfilerSessionsFactory(); - // start a root level activity - using Activity rootActivity = new Activity("Parent") - .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) - .Start(); + // start a root level activity + using Activity rootActivity = new Activity("Parent") + .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) + .Start(); - Assert.NotNull(rootActivity.Id); + Assert.NotNull(rootActivity.Id); - // get an initial profiler from root activity - Activity.Current = rootActivity; - ProfilingSession profiler0 = profilerFactory(); + // get an initial profiler from root activity + Activity.Current = rootActivity; + ProfilingSession profiler0 = profilerFactory(); - // expect different result from synchronous child activity - ProfilingSession profiler1; - using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) - { - profiler1 = profilerFactory(); - Assert.NotSame(profiler0, profiler1); - } + // expect different result from synchronous child activity + ProfilingSession profiler1; + using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) + { + profiler1 = profilerFactory(); + Assert.NotSame(profiler0, profiler1); + } - Activity.Current = rootActivity; + Activity.Current = rootActivity; - // expect different result from asynchronous child activity - using (Activity.Current = new Activity("Child-Span-2").SetParentId(rootActivity.Id).Start()) - { - // lose async context on purpose - await Task.Delay(100).ConfigureAwait(false); + // expect different result from asynchronous child activity + using (Activity.Current = new Activity("Child-Span-2").SetParentId(rootActivity.Id).Start()) + { + // lose async context on purpose + await Task.Delay(100).ConfigureAwait(false); - ProfilingSession profiler2 = profilerFactory(); - Assert.NotSame(profiler0, profiler2); - Assert.NotSame(profiler1, profiler2); - } + ProfilingSession profiler2 = profilerFactory(); + Assert.NotSame(profiler0, profiler2); + Assert.NotSame(profiler1, profiler2); + } - Activity.Current = rootActivity; + Activity.Current = rootActivity; - // ensure same result back in root activity - ProfilingSession profiles3 = profilerFactory(); - Assert.Same(profiler0, profiles3); - } + // ensure same result back in root activity + ProfilingSession profiles3 = profilerFactory(); + Assert.Same(profiler0, profiles3); + } - [Fact] - public void StackExchangeRedis_BadArgs() - { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddRedisInstrumentation(null)); + [Fact] + public void StackExchangeRedis_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddRedisInstrumentation(null)); - var activityProcessor = new Mock>(); - Assert.Throws(() => + var activityProcessor = new Mock>(); + Assert.Throws(() => Sdk.CreateTracerProviderBuilder() .AddProcessor(activityProcessor.Object) .AddRedisInstrumentation(null) .Build()); - } + } - [Fact] - public void StackExchangeRedis_DependencyInjection_Success() - { - bool connectionMultiplexerPickedFromDI = false; - bool optionsPickedFromDI = false; + [Fact] + public void StackExchangeRedis_DependencyInjection_Success() + { + bool connectionMultiplexerPickedFromDI = false; + bool optionsPickedFromDI = false; - var connectionOptions = new ConfigurationOptions - { - AbortOnConnectFail = false, - }; - connectionOptions.EndPoints.Add("localhost"); + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost"); - var services = new ServiceCollection(); - services.AddSingleton((sp) => - { - connectionMultiplexerPickedFromDI = true; - return ConnectionMultiplexer.Connect(connectionOptions); - }); - services.Configure(options => - { - optionsPickedFromDI = true; - }); - services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); + var services = new ServiceCollection(); + services.AddSingleton((sp) => + { + connectionMultiplexerPickedFromDI = true; + return ConnectionMultiplexer.Connect(connectionOptions); + }); + services.Configure(options => + { + optionsPickedFromDI = true; + }); + services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); - using var serviceProvider = services.BuildServiceProvider(); + using var serviceProvider = services.BuildServiceProvider(); - var tracerProvider = serviceProvider.GetRequiredService(); + var tracerProvider = serviceProvider.GetRequiredService(); - Assert.True(connectionMultiplexerPickedFromDI); - Assert.True(optionsPickedFromDI); - } + Assert.True(connectionMultiplexerPickedFromDI); + Assert.True(optionsPickedFromDI); + } - [Fact] - public void StackExchangeRedis_DependencyInjection_Failure() - { - var services = new ServiceCollection(); + [Fact] + public void StackExchangeRedis_DependencyInjection_Failure() + { + var services = new ServiceCollection(); - services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); + services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); - using var serviceProvider = services.BuildServiceProvider(); + using var serviceProvider = services.BuildServiceProvider(); - Assert.Throws(() => serviceProvider.GetRequiredService()); - } + Assert.Throws(() => serviceProvider.GetRequiredService()); + } - private static void VerifyActivityData(Activity activity, bool isSet, EndPoint endPoint, bool setCommandKey = false) + private static void VerifyActivityData(Activity activity, bool isSet, EndPoint endPoint, bool setCommandKey = false) + { + if (isSet) { - if (isSet) + Assert.Equal("SETEX", activity.DisplayName); + if (setCommandKey) { - Assert.Equal("SETEX", activity.DisplayName); - if (setCommandKey) - { - Assert.Equal("SETEX key1", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } - else - { - Assert.Equal("SETEX", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } + Assert.Equal("SETEX key1", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); } else { - Assert.Equal("GET", activity.DisplayName); - if (setCommandKey) - { - Assert.Equal("GET key1", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } - else - { - Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } + Assert.Equal("SETEX", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); } - - Assert.Equal(Status.Unset, activity.GetStatus()); - Assert.Equal("redis", activity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal(0, activity.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName)); - - if (endPoint is IPEndPoint ipEndPoint) - { - Assert.Equal(ipEndPoint.Address.ToString(), activity.GetTagValue(SemanticConventions.AttributeNetPeerIp)); - Assert.Equal(ipEndPoint.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - } - else if (endPoint is DnsEndPoint dnsEndPoint) + } + else + { + Assert.Equal("GET", activity.DisplayName); + if (setCommandKey) { - Assert.Equal(dnsEndPoint.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(dnsEndPoint.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal("GET key1", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); } else { - Assert.Equal(endPoint.ToString(), activity.GetTagValue(SemanticConventions.AttributePeerService)); + Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeDbStatement)); } } - private static void VerifySamplingParameters(SamplingParameters samplingParameters) + Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal("redis", activity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal(0, activity.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName)); + + if (endPoint is IPEndPoint ipEndPoint) + { + Assert.Equal(ipEndPoint.Address.ToString(), activity.GetTagValue(SemanticConventions.AttributeNetPeerIp)); + Assert.Equal(ipEndPoint.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } + else if (endPoint is DnsEndPoint dnsEndPoint) { - Assert.NotNull(samplingParameters.Tags); - Assert.Contains( - samplingParameters.Tags, - kvp => kvp.Key == SemanticConventions.AttributeDbSystem - && (string)kvp.Value == "redis"); + Assert.Equal(dnsEndPoint.Host, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(dnsEndPoint.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); } + else + { + Assert.Equal(endPoint.ToString(), activity.GetTagValue(SemanticConventions.AttributePeerService)); + } + } + + private static void VerifySamplingParameters(SamplingParameters samplingParameters) + { + Assert.NotNull(samplingParameters.Tags); + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeDbSystem + && (string)kvp.Value == "redis"); } } From 43cbf52e4b628434f1bd547990d474ce8ca6edbe Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 1 Aug 2022 14:41:20 -0700 Subject: [PATCH 0263/1499] [Exporter.Geneva] Update CHANGELOG (#554) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index daee2190bf..d6ded992f5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,7 +2,11 @@ ## Unreleased -## 1.4.0.beta.1 +## 1.4.0-beta.1 + +Released 2022-Aug-01 + +## 1.3.1-alpha.0.5 (unlisted due to incorrect version) Released 2022-Jul-29 From 0a584e688f106c9c9cc03e7f98e70841fd35adb6 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 1 Aug 2022 17:34:02 -0700 Subject: [PATCH 0264/1499] [Instrumentation.Runtime] Enable CodeAnalysis for Runtime Instrumentation library (#555) --- src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs | 2 ++ .../OpenTelemetry.Instrumentation.Runtime.csproj | 1 + src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs index c1cb3f4670..fd9413b83e 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs @@ -14,8 +14,10 @@ // limitations under the License. // +using System; using System.Runtime.CompilerServices; +[assembly: CLSCompliant(false)] #if SIGNED [assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Runtime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 4fce0322ce..40ad2f80e7 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -4,6 +4,7 @@ dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- + true diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index c373950e5f..77be030ee7 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -39,9 +39,9 @@ internal class RuntimeMetrics #if NET6_0_OR_GREATER private const long NanosecondsPerTick = 100; #endif + private const int NumberOfGenerations = 3; private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; - private static readonly int NumberOfGenerations = 3; private static bool isGcInfoAvailable; private static string metricPrefix = "process.runtime.dotnet."; From f69c5ff02f85dcd99a1a1325e8c5ba4d80c5c782 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 1 Aug 2022 17:51:33 -0700 Subject: [PATCH 0265/1499] [Instrumentation.Runtime] Rename `RuntimeInstrumentOptions` to `RuntimeInstrumentationOptions` (#556) * Rename options object for Runtime Instrumentation --- .../CHANGELOG.md | 3 +++ .../MeterProviderBuilderExtensions.cs | 4 ++-- ...ons.cs => RuntimeInstrumentationOptions.cs} | 4 ++-- .../RuntimeMetrics.cs | 2 +- ...s => RuntimeInstrumentationOptionsTests.cs} | 18 ++++++++---------- 5 files changed, 16 insertions(+), 15 deletions(-) rename src/OpenTelemetry.Instrumentation.Runtime/{RuntimeInstrumentOptions.cs => RuntimeInstrumentationOptions.cs} (96%) rename test/OpenTelemetry.Instrumentation.Runtime.Tests/{RuntimeInstrumentOptionsTests.cs => RuntimeInstrumentationOptionsTests.cs} (83%) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 93c98d5ae5..878f819c97 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Rename `RuntimeInstrumentOptions` to `RuntimeInstrumentationOptions` + ([#556](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/556)) + ## 1.0.0-rc.3 Released 2022-Jul-25 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index f207bb5bc6..9963243e7a 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -33,11 +33,11 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddRuntimeInstrumentation( this MeterProviderBuilder builder, - Action configure = null) + Action configure = null) { Guard.ThrowIfNull(builder); - var options = new RuntimeInstrumentOptions(); + var options = new RuntimeInstrumentationOptions(); configure?.Invoke(options); var instrumentation = new RuntimeMetrics(options); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs similarity index 96% rename from src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentOptions.cs rename to src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs index 38455545f0..3809444a4a 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,7 @@ namespace OpenTelemetry.Instrumentation.Runtime /// /// Options to define the runtime metrics. /// - public class RuntimeInstrumentOptions + public class RuntimeInstrumentationOptions { /* /// diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 77be030ee7..0b046b7ebe 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -219,7 +219,7 @@ static RuntimeMetrics() /// Initializes a new instance of the class. /// /// The options to define the metrics. - public RuntimeMetrics(RuntimeInstrumentOptions options) + public RuntimeMetrics(RuntimeInstrumentationOptions options) { } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs similarity index 83% rename from test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentOptionsTests.cs rename to test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs index 1f83d3ef30..d419f0c921 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,17 +14,15 @@ // limitations under the License. // -using Xunit; - namespace OpenTelemetry.Instrumentation.Runtime.Tests { - public class RuntimeInstrumentOptionsTests + public class RuntimeInstrumentationOptionsTests { /* [Fact] public void Enable_All_If_Nothing_Was_Defined() { - var options = new RuntimeInstrumentOptions(); + var options = new RuntimeInstrumentationOptions(); Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -40,7 +38,7 @@ public void Enable_All_If_Nothing_Was_Defined() [Fact] public void Enable_Gc_Only() { - var options = new RuntimeInstrumentOptions { GcEnabled = true }; + var options = new RuntimeInstrumentationOptions { GcEnabled = true }; Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -57,7 +55,7 @@ public void Enable_Gc_Only() [Fact] public void Enable_Jit_Only() { - var options = new RuntimeInstrumentOptions { JitEnabled = true }; + var options = new RuntimeInstrumentationOptions { JitEnabled = true }; Assert.False(options.IsGcEnabled); Assert.True(options.IsJitEnabled); @@ -71,7 +69,7 @@ public void Enable_Jit_Only() [Fact] public void Enable_Threading_Only() { - var options = new RuntimeInstrumentOptions { ThreadingEnabled = true }; + var options = new RuntimeInstrumentationOptions { ThreadingEnabled = true }; Assert.False(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -86,7 +84,7 @@ public void Enable_Threading_Only() [Fact] public void Enable_Assemblies_Only() { - var options = new RuntimeInstrumentOptions { AssembliesEnabled = true }; + var options = new RuntimeInstrumentationOptions { AssembliesEnabled = true }; Assert.False(options.IsGcEnabled); #if NET6_0_OR_GREATER @@ -102,7 +100,7 @@ public void Enable_Assemblies_Only() [Fact] public void Enable_Multiple() { - var options = new RuntimeInstrumentOptions { GcEnabled = true, AssembliesEnabled = true }; + var options = new RuntimeInstrumentationOptions { GcEnabled = true, AssembliesEnabled = true }; Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER From bbb3faf6bdcb3f531738bb1063564e0c68d9de15 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Mon, 1 Aug 2022 18:39:24 -0700 Subject: [PATCH 0266/1499] [Instrumentation.Runtime] Enable CodeAnalysis.PublicApiAnalyzers (#557) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 ++++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 ++++ .../.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt | 0 .../.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt | 4 ++++ .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 0 .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 4 ++++ .../OpenTelemetry.Instrumentation.Runtime.csproj | 1 + 9 files changed, 17 insertions(+) create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4f1e7e604f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4f1e7e604f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4f1e7e604f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4f1e7e604f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 40ad2f80e7..dad52da362 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,6 +5,7 @@ $(PackageTags);runtime Instrumentation.Runtime- true + true From 3dbb571e248fef93bb73133de48d745aeff340de Mon Sep 17 00:00:00 2001 From: xiang17 Date: Tue, 2 Aug 2022 18:14:37 -0700 Subject: [PATCH 0267/1499] [Instrumentation.Runtime] Two internal refactors (#559) --- .../RuntimeMetrics.cs | 32 +++++++++---------- .../RuntimeMetricsTests.cs | 13 +++++++- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 0b046b7ebe..e0d24e7151 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -40,21 +40,21 @@ internal class RuntimeMetrics private const long NanosecondsPerTick = 100; #endif private const int NumberOfGenerations = 3; + private const string MetricPrefix = "process.runtime.dotnet."; private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; private static bool isGcInfoAvailable; - private static string metricPrefix = "process.runtime.dotnet."; static RuntimeMetrics() { MeterInstance.CreateObservableCounter( - $"{metricPrefix}gc.collections.count", + $"{MetricPrefix}gc.collections.count", () => GetGarbageCollectionCounts(), description: "Number of garbage collections that have occurred since process start."); #if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( - $"{metricPrefix}gc.allocations.size", + $"{MetricPrefix}gc.allocations.size", () => GC.GetTotalAllocatedBytes(), unit: "bytes", description: "Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); @@ -63,7 +63,7 @@ static RuntimeMetrics() #if NET6_0_OR_GREATER // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}gc.committed_memory.size", + $"{MetricPrefix}gc.committed_memory.size", () => { if (!IsGcInfoAvailable) @@ -93,7 +93,7 @@ static RuntimeMetrics() { // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}gc.heap.size", + $"{MetricPrefix}gc.heap.size", () => { if (!IsGcInfoAvailable) @@ -127,7 +127,7 @@ static RuntimeMetrics() { // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}gc.heap.fragmentation.size", + $"{MetricPrefix}gc.heap.fragmentation.size", () => { if (!IsGcInfoAvailable) @@ -152,18 +152,18 @@ static RuntimeMetrics() #if NET6_0_OR_GREATER MeterInstance.CreateObservableCounter( - $"{metricPrefix}jit.il_compiled.size", + $"{MetricPrefix}jit.il_compiled.size", () => JitInfo.GetCompiledILBytes(), unit: "bytes", description: "Count of bytes of intermediate language that have been compiled since the process start."); MeterInstance.CreateObservableCounter( - $"{metricPrefix}jit.methods_compiled.count", + $"{MetricPrefix}jit.methods_compiled.count", () => JitInfo.GetCompiledMethodCount(), description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings."); MeterInstance.CreateObservableCounter( - $"{metricPrefix}jit.compilation_time", + $"{MetricPrefix}jit.compilation_time", () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, unit: "ns", description: "The amount of time the JIT compiler has spent compiling methods since the process start."); @@ -171,42 +171,42 @@ static RuntimeMetrics() #if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( - $"{metricPrefix}monitor.lock_contention.count", + $"{MetricPrefix}monitor.lock_contention.count", () => Monitor.LockContentionCount, description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}thread_pool.threads.count", + $"{MetricPrefix}thread_pool.threads.count", () => (long)ThreadPool.ThreadCount, description: "The number of thread pool threads that currently exist."); MeterInstance.CreateObservableCounter( - $"{metricPrefix}thread_pool.completed_items.count", + $"{MetricPrefix}thread_pool.completed_items.count", () => ThreadPool.CompletedWorkItemCount, description: "The number of work items that have been processed by the thread pool since the process start."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}thread_pool.queue.length", + $"{MetricPrefix}thread_pool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "The number of work items that are currently queued to be processed by the thread pool."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}timer.count", + $"{MetricPrefix}timer.count", () => Timer.ActiveCount, description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); #endif // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{metricPrefix}assemblies.count", + $"{MetricPrefix}assemblies.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "The number of .NET assemblies that are currently loaded."); var exceptionCounter = MeterInstance.CreateCounter( - $"{metricPrefix}exceptions.count", + $"{MetricPrefix}exceptions.count", description: "Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization."); AppDomain.CurrentDomain.FirstChanceException += (source, e) => diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index fb205860bd..8b5ed3ab4a 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; @@ -127,6 +128,16 @@ public void ThreadingRelatedMetricsTest() .AddInMemoryExporter(exportedItems) .Build(); + // Bump the count for `thread_pool.completed_items.count` metric + int taskCount = 50; + List tasks = new List(); + for (int i = 0; i < taskCount; i++) + { + tasks.Add(Task.Run(() => { Console.Write("Hi"); })); + } + + Task.WaitAll(tasks.ToArray()); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); @@ -136,7 +147,7 @@ public void ThreadingRelatedMetricsTest() Assert.NotNull(threadCountMetric); var completedItemsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); - Assert.NotNull(completedItemsCountMetric); + Assert.True(GetValue(completedItemsCountMetric) >= taskCount); var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); Assert.NotNull(queueLengthMetric); From 5b47fd8c8c62e605bfa9f86e0496f26ef3ea1876 Mon Sep 17 00:00:00 2001 From: Tony Yin Date: Thu, 4 Aug 2022 03:29:51 +0800 Subject: [PATCH 0268/1499] [OpenTelemetry.Extensions] Use file scoped namespace #276 (#560) --- .../ActivityEventAttachingLogProcessor.cs | 121 ++++---- .../Internal/DefaultLogStateConverter.cs | 59 ++-- .../OpenTelemetryExtensionsEventSource.cs | 37 ++- .../LogToActivityEventConversionOptions.cs | 25 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 43 ++- .../Trace/AutoFlushActivityProcessor.cs | 131 +++++---- .../TracerProviderBuilderExtensions.cs | 59 ++-- ...ActivityEventAttachingLogProcessorTests.cs | 265 +++++++++--------- .../Trace/AutoFlushActivityProcessorTests.cs | 87 +++--- 9 files changed, 409 insertions(+), 418 deletions(-) diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index c0b559e907..af4831f7b3 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -20,94 +20,93 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Logs +namespace OpenTelemetry.Logs; + +internal sealed class ActivityEventAttachingLogProcessor : BaseProcessor { - internal sealed class ActivityEventAttachingLogProcessor : BaseProcessor + private static readonly Action ProcessScope = (LogRecordScope scope, State state) => { - private static readonly Action ProcessScope = (LogRecordScope scope, State state) => + try { - try - { - state.Processor.options.ScopeConverter?.Invoke(state.Tags, state.Depth++, scope); - } - catch (Exception ex) - { - OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing scope of type [{scope.GetType().FullName}]", ex); - } - }; + state.Processor.options.ScopeConverter?.Invoke(state.Tags, state.Depth++, scope); + } + catch (Exception ex) + { + OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing scope of type [{scope.GetType().FullName}]", ex); + } + }; - private readonly LogToActivityEventConversionOptions options; + private readonly LogToActivityEventConversionOptions options; - public ActivityEventAttachingLogProcessor(LogToActivityEventConversionOptions options) - { - Guard.ThrowIfNull(options); + public ActivityEventAttachingLogProcessor(LogToActivityEventConversionOptions options) + { + Guard.ThrowIfNull(options); - this.options = options; - } + this.options = options; + } - public override void OnEnd(LogRecord data) - { - Activity? activity = Activity.Current; + public override void OnEnd(LogRecord data) + { + Activity? activity = Activity.Current; - if (activity?.IsAllDataRequested == true) + if (activity?.IsAllDataRequested == true) + { + var tags = new ActivityTagsCollection { - var tags = new ActivityTagsCollection - { - { nameof(data.CategoryName), data.CategoryName }, - { nameof(data.LogLevel), data.LogLevel }, - }; + { nameof(data.CategoryName), data.CategoryName }, + { nameof(data.LogLevel), data.LogLevel }, + }; - if (data.EventId != 0) - { - tags[nameof(data.EventId)] = data.EventId; - } + if (data.EventId != 0) + { + tags[nameof(data.EventId)] = data.EventId; + } - var activityEvent = new ActivityEvent("log", data.Timestamp, tags); + var activityEvent = new ActivityEvent("log", data.Timestamp, tags); - data.ForEachScope(ProcessScope, new State(tags, this)); + data.ForEachScope(ProcessScope, new State(tags, this)); - if (data.StateValues != null) + if (data.StateValues != null) + { + try { - try - { - this.options.StateConverter?.Invoke(tags, data.StateValues); - } + this.options.StateConverter?.Invoke(tags, data.StateValues); + } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) + catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types - { - OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing state of type [{data.State.GetType().FullName}]", ex); - } - } - - if (!string.IsNullOrEmpty(data.FormattedMessage)) { - tags[nameof(data.FormattedMessage)] = data.FormattedMessage; + OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing state of type [{data.State.GetType().FullName}]", ex); } + } - activity.AddEvent(activityEvent); + if (!string.IsNullOrEmpty(data.FormattedMessage)) + { + tags[nameof(data.FormattedMessage)] = data.FormattedMessage; + } - if (data.Exception != null) - { - activity.RecordException(data.Exception); - } + activity.AddEvent(activityEvent); + + if (data.Exception != null) + { + activity.RecordException(data.Exception); } } + } - private class State + private class State + { + public State(ActivityTagsCollection tags, ActivityEventAttachingLogProcessor processor) { - public State(ActivityTagsCollection tags, ActivityEventAttachingLogProcessor processor) - { - this.Tags = tags; - this.Processor = processor; - } + this.Tags = tags; + this.Processor = processor; + } - public ActivityTagsCollection Tags { get; } + public ActivityTagsCollection Tags { get; } - public ActivityEventAttachingLogProcessor Processor { get; } + public ActivityEventAttachingLogProcessor Processor { get; } - public int Depth { get; set; } - } + public int Depth { get; set; } } } #endif diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index fbd7b1080e..2ae3b2f487 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -18,48 +18,47 @@ using System.Collections.Generic; using System.Diagnostics; -namespace OpenTelemetry.Logs +namespace OpenTelemetry.Logs; + +internal static class DefaultLogStateConverter { - internal static class DefaultLogStateConverter + public static void ConvertState(ActivityTagsCollection tags, IReadOnlyList> state) { - public static void ConvertState(ActivityTagsCollection tags, IReadOnlyList> state) + for (int i = 0; i < state.Count; i++) { - for (int i = 0; i < state.Count; i++) - { - KeyValuePair stateItem = state[i]; + KeyValuePair stateItem = state[i]; - object value = stateItem.Value; - if (value != null) + object value = stateItem.Value; + if (value != null) + { + if (string.IsNullOrEmpty(stateItem.Key)) { - if (string.IsNullOrEmpty(stateItem.Key)) - { - tags["state"] = value; - } - else - { - tags[$"state.{stateItem.Key}"] = value; - } + tags["state"] = value; + } + else + { + tags[$"state.{stateItem.Key}"] = value; } } } + } - public static void ConvertScope(ActivityTagsCollection tags, int depth, LogRecordScope scope) - { - string prefix = $"scope[{depth}]"; + public static void ConvertScope(ActivityTagsCollection tags, int depth, LogRecordScope scope) + { + string prefix = $"scope[{depth}]"; - foreach (KeyValuePair scopeItem in scope) + foreach (KeyValuePair scopeItem in scope) + { + object value = scopeItem.Value; + if (value != null) { - object value = scopeItem.Value; - if (value != null) + if (string.IsNullOrEmpty(scopeItem.Key)) + { + tags[prefix] = value; + } + else { - if (string.IsNullOrEmpty(scopeItem.Key)) - { - tags[prefix] = value; - } - else - { - tags[$"{prefix}.{scopeItem.Key}"] = value; - } + tags[$"{prefix}.{scopeItem.Key}"] = value; } } } diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index ff7a5100f6..596bd0ec71 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -18,29 +18,28 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry +namespace OpenTelemetry; + +/// +/// EventSource implementation for OpenTelemetry SDK extensions implementation. +/// +[EventSource(Name = "OpenTelemetry-Extensions")] +internal class OpenTelemetryExtensionsEventSource : EventSource { - /// - /// EventSource implementation for OpenTelemetry SDK extensions implementation. - /// - [EventSource(Name = "OpenTelemetry-Extensions")] - internal class OpenTelemetryExtensionsEventSource : EventSource - { - public static OpenTelemetryExtensionsEventSource Log = new OpenTelemetryExtensionsEventSource(); + public static OpenTelemetryExtensionsEventSource Log = new OpenTelemetryExtensionsEventSource(); - [NonEvent] - public void LogProcessorException(string @event, Exception ex) + [NonEvent] + public void LogProcessorException(string @event, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.LogProcessorException(@event, ex.ToInvariantString()); - } + this.LogProcessorException(@event, ex.ToInvariantString()); } + } - [Event(1, Message = "Unknown error in LogProcessor event '{0}': '{1}'.", Level = EventLevel.Error)] - public void LogProcessorException(string @event, string exception) - { - this.WriteEvent(1, @event, exception); - } + [Event(1, Message = "Unknown error in LogProcessor event '{0}': '{1}'.", Level = EventLevel.Error)] + public void LogProcessorException(string @event, string exception) + { + this.WriteEvent(1, @event, exception); } } diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index 670083e543..8783830309 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -19,22 +19,21 @@ using System.Collections.Generic; using System.Diagnostics; -namespace OpenTelemetry.Logs +namespace OpenTelemetry.Logs; + +/// +/// Stores options used to convert log messages into s. +/// +public class LogToActivityEventConversionOptions { /// - /// Stores options used to convert log messages into s. + /// Gets or sets the callback action used to convert log state into tags. /// - public class LogToActivityEventConversionOptions - { - /// - /// Gets or sets the callback action used to convert log state into tags. - /// - public Action>> StateConverter { get; set; } = DefaultLogStateConverter.ConvertState; + public Action>> StateConverter { get; set; } = DefaultLogStateConverter.ConvertState; - /// - /// Gets or sets the callback action used to convert log scopes into tags. - /// - public Action ScopeConverter { get; set; } = DefaultLogStateConverter.ConvertScope; - } + /// + /// Gets or sets the callback action used to convert log scopes into tags. + /// + public Action ScopeConverter { get; set; } = DefaultLogStateConverter.ConvertScope; } #endif diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index bc8fa1518b..7b87044461 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -20,35 +20,34 @@ using OpenTelemetry.Internal; using OpenTelemetry.Logs; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging; + +/// +/// Contains OpenTelemetry logging SDK extensions. +/// +public static class OpenTelemetryLoggingExtensions { /// - /// Contains OpenTelemetry logging SDK extensions. + /// Adds a processor to the OpenTelemetry which will convert log messages + /// into s attached to the active when the message is written. /// - public static class OpenTelemetryLoggingExtensions + /// options to use. + /// . + /// The instance of to chain the calls. + /// is null. + public static OpenTelemetryLoggerOptions AttachLogsToActivityEvent( + this OpenTelemetryLoggerOptions loggerOptions, + Action? configure = null) { - /// - /// Adds a processor to the OpenTelemetry which will convert log messages - /// into s attached to the active when the message is written. - /// - /// options to use. - /// . - /// The instance of to chain the calls. - /// is null. - public static OpenTelemetryLoggerOptions AttachLogsToActivityEvent( - this OpenTelemetryLoggerOptions loggerOptions, - Action? configure = null) - { - Guard.ThrowIfNull(loggerOptions); + Guard.ThrowIfNull(loggerOptions); - var options = new LogToActivityEventConversionOptions(); - configure?.Invoke(options); + var options = new LogToActivityEventConversionOptions(); + configure?.Invoke(options); #pragma warning disable CA2000 // Dispose objects before losing scope - return loggerOptions.AddProcessor(new ActivityEventAttachingLogProcessor(options)); + return loggerOptions.AddProcessor(new ActivityEventAttachingLogProcessor(options)); #pragma warning restore CA2000 // Dispose objects before losing scope - } } } #endif diff --git a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs index ebe36c5b90..bf10f6666d 100644 --- a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs +++ b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs @@ -18,94 +18,93 @@ using System.Diagnostics; using System.Threading; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Activity processor that flushes its containing if an ended +/// Activity matches a predicate. +/// +/// +/// Add this processor *after* exporter related Activity processors. +/// +internal sealed class AutoFlushActivityProcessor : BaseProcessor { + private readonly Func predicate; + private readonly int timeoutMilliseconds; + + private TracerProvider? tracerProvider; + private bool canForceFlush = true; + /// - /// Activity processor that flushes its containing if an ended - /// Activity matches a predicate. + /// Initializes a new instance of the class. /// + /// Predicate that should return true to initiate a flush. + /// Timeout (in milliseconds) to use for flushing. Specify + /// to wait indefinitely. + /// + /// + /// Thrown when the timeoutMilliseconds is smaller than -1. + /// /// - /// Add this processor *after* exporter related Activity processors. + /// It's assumed that the predicate is defined as a lambda expression which is executed quite fast and + /// doesn't contain more complex code. The predicate must not create new Activity instances, + /// otherwise the behavior is undefined. Any exception thrown by the predicate will be swallowed and logged. + /// In case of an exception the predicate is treated as false which means flush will not be applied. /// - internal sealed class AutoFlushActivityProcessor : BaseProcessor + internal AutoFlushActivityProcessor(Func predicate, int timeoutMilliseconds) { - private readonly Func predicate; - private readonly int timeoutMilliseconds; + this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate)); + if (timeoutMilliseconds < Timeout.Infinite) + { + throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds)); + } - private TracerProvider? tracerProvider; - private bool canForceFlush = true; + this.timeoutMilliseconds = timeoutMilliseconds; + } - /// - /// Initializes a new instance of the class. - /// - /// Predicate that should return true to initiate a flush. - /// Timeout (in milliseconds) to use for flushing. Specify - /// to wait indefinitely. - /// - /// - /// Thrown when the timeoutMilliseconds is smaller than -1. - /// - /// - /// It's assumed that the predicate is defined as a lambda expression which is executed quite fast and - /// doesn't contain more complex code. The predicate must not create new Activity instances, - /// otherwise the behavior is undefined. Any exception thrown by the predicate will be swallowed and logged. - /// In case of an exception the predicate is treated as false which means flush will not be applied. - /// - internal AutoFlushActivityProcessor(Func predicate, int timeoutMilliseconds) + /// + public override void OnEnd(Activity data) + { + if (!this.canForceFlush) { - this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate)); - if (timeoutMilliseconds < Timeout.Infinite) - { - throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds)); - } - - this.timeoutMilliseconds = timeoutMilliseconds; + return; } - /// - public override void OnEnd(Activity data) + if (this.tracerProvider == null && this.ParentProvider != null) { + this.tracerProvider = this.ParentProvider as TracerProvider; + this.canForceFlush = this.tracerProvider != null; if (!this.canForceFlush) { return; } + } + else if (this.ParentProvider == null) + { + return; + } - if (this.tracerProvider == null && this.ParentProvider != null) - { - this.tracerProvider = this.ParentProvider as TracerProvider; - this.canForceFlush = this.tracerProvider != null; - if (!this.canForceFlush) - { - return; - } - } - else if (this.ParentProvider == null) - { - return; - } - - var shouldFlush = this.RunPredicate(data); - if (shouldFlush) - { - this.tracerProvider.ForceFlush(this.timeoutMilliseconds); - } + var shouldFlush = this.RunPredicate(data); + if (shouldFlush) + { + this.tracerProvider.ForceFlush(this.timeoutMilliseconds); } + } - private bool RunPredicate(Activity data) + private bool RunPredicate(Activity data) + { + var shouldFlush = false; + try { - var shouldFlush = false; - try - { - shouldFlush = this.predicate(data); - } + shouldFlush = this.predicate(data); + } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) + catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types - { - OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Flushing predicate threw an exception. Flush of {typeof(TracerProvider)} was skipped.", ex); - } - - return shouldFlush; + { + OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Flushing predicate threw an exception. Flush of {typeof(TracerProvider)} was skipped.", ex); } + + return shouldFlush; } } diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index c3ca61a1e7..a21b3af4d8 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -18,43 +18,42 @@ using System.Diagnostics; using System.Threading; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of auto flush Activity processor. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of auto flush Activity processor. + /// Adds auto flush Activity processor. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// Predicate that should return true to initiate a flush. + /// Timeout (in milliseconds) to use for flushing. Specify + /// to wait indefinitely. + /// + /// Thrown when the builder is null. + /// The instance of to chain the calls. + /// + /// Add this processor *after* exporter related Activity processors. + /// It's assumed that the predicate is defined as a lambda expression which is executed quite fast and + /// doesn't contain more complex code. The predicate must not create new Activity instances, + /// otherwise the behavior is undefined. Any exception thrown by the predicate will be swallowed and logged. + /// In case of an exception the predicate is treated as false which means flush will not be applied. + /// + public static TracerProviderBuilder AddAutoFlushActivityProcessor( + this TracerProviderBuilder builder, + Func predicate, + int timeoutMilliseconds = 10000) { - /// - /// Adds auto flush Activity processor. - /// - /// being configured. - /// Predicate that should return true to initiate a flush. - /// Timeout (in milliseconds) to use for flushing. Specify - /// to wait indefinitely. - /// - /// Thrown when the builder is null. - /// The instance of to chain the calls. - /// - /// Add this processor *after* exporter related Activity processors. - /// It's assumed that the predicate is defined as a lambda expression which is executed quite fast and - /// doesn't contain more complex code. The predicate must not create new Activity instances, - /// otherwise the behavior is undefined. Any exception thrown by the predicate will be swallowed and logged. - /// In case of an exception the predicate is treated as false which means flush will not be applied. - /// - public static TracerProviderBuilder AddAutoFlushActivityProcessor( - this TracerProviderBuilder builder, - Func predicate, - int timeoutMilliseconds = 10000) + if (builder == null) { - if (builder == null) - { - throw new ArgumentNullException(nameof(builder)); - } + throw new ArgumentNullException(nameof(builder)); + } #pragma warning disable CA2000 // Dispose objects before losing scope - return builder.AddProcessor(new AutoFlushActivityProcessor(predicate, timeoutMilliseconds)); + return builder.AddProcessor(new AutoFlushActivityProcessor(predicate, timeoutMilliseconds)); #pragma warning restore CA2000 // Dispose objects before losing scope - } } } diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 93b1687023..25dbbb6f8e 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -22,169 +22,168 @@ using OpenTelemetry.Logs; using Xunit; -namespace OpenTelemetry.Extensions.Tests +namespace OpenTelemetry.Extensions.Tests; + +public sealed class ActivityEventAttachingLogProcessorTests : IDisposable { - public sealed class ActivityEventAttachingLogProcessorTests : IDisposable + private readonly ActivitySource activitySource = new ActivitySource("Test"); + private readonly ActivityListener activityListener = new ActivityListener + { + ShouldListenTo = source => true, + }; + + private readonly ILogger logger; + private readonly ILoggerFactory loggerFactory; + private OpenTelemetryLoggerOptions options; + private bool sampled; + + public ActivityEventAttachingLogProcessorTests() { - private readonly ActivitySource activitySource = new ActivitySource("Test"); - private readonly ActivityListener activityListener = new ActivityListener + this.activityListener.Sample = (ref ActivityCreationOptions options) => { - ShouldListenTo = source => true, + return this.sampled + ? ActivitySamplingResult.AllDataAndRecorded + : ActivitySamplingResult.PropagationData; }; - private readonly ILogger logger; - private readonly ILoggerFactory loggerFactory; - private OpenTelemetryLoggerOptions options; - private bool sampled; + ActivitySource.AddActivityListener(this.activityListener); - public ActivityEventAttachingLogProcessorTests() + this.loggerFactory = LoggerFactory.Create(builder => { - this.activityListener.Sample = (ref ActivityCreationOptions options) => + builder.AddOpenTelemetry(options => { - return this.sampled - ? ActivitySamplingResult.AllDataAndRecorded - : ActivitySamplingResult.PropagationData; - }; + this.options = options; + options.AttachLogsToActivityEvent(); + }); + builder.AddFilter(typeof(ActivityEventAttachingLogProcessorTests).FullName, LogLevel.Trace); + }); - ActivitySource.AddActivityListener(this.activityListener); + this.logger = this.loggerFactory.CreateLogger(); + } - this.loggerFactory = LoggerFactory.Create(builder => - { - builder.AddOpenTelemetry(options => - { - this.options = options; - options.AttachLogsToActivityEvent(); - }); - builder.AddFilter(typeof(ActivityEventAttachingLogProcessorTests).FullName, LogLevel.Trace); - }); + public void Dispose() + { + this.activitySource.Dispose(); + this.activityListener.Dispose(); + this.loggerFactory.Dispose(); + } - this.logger = this.loggerFactory.CreateLogger(); - } + [Theory] + [InlineData(true)] + [InlineData(false)] + [InlineData(true, 18, true, true, true)] + [InlineData(true, 0, false, false, true, true)] + public void AttachLogsToActivityEventTest( + bool sampled, + int eventId = 0, + bool includeFormattedMessage = false, + bool parseStateValues = false, + bool includeScopes = false, + bool recordException = false) + { + this.sampled = sampled; + this.options.IncludeFormattedMessage = includeFormattedMessage; + this.options.ParseStateValues = parseStateValues; + this.options.IncludeScopes = includeScopes; - public void Dispose() + Activity activity = this.activitySource.StartActivity("Test"); + + using IDisposable scope = this.logger.BeginScope("{NodeId}", 99); + + this.logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); + + Activity innerActivity = null; + if (recordException) { - this.activitySource.Dispose(); - this.activityListener.Dispose(); - this.loggerFactory.Dispose(); + innerActivity = this.activitySource.StartActivity("InnerTest"); + + using IDisposable innerScope = this.logger.BeginScope("{RequestId}", "1234"); + + this.logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); + + innerActivity.Dispose(); } - [Theory] - [InlineData(true)] - [InlineData(false)] - [InlineData(true, 18, true, true, true)] - [InlineData(true, 0, false, false, true, true)] - public void AttachLogsToActivityEventTest( - bool sampled, - int eventId = 0, - bool includeFormattedMessage = false, - bool parseStateValues = false, - bool includeScopes = false, - bool recordException = false) + activity.Dispose(); + + if (sampled) { - this.sampled = sampled; - this.options.IncludeFormattedMessage = includeFormattedMessage; - this.options.ParseStateValues = parseStateValues; - this.options.IncludeScopes = includeScopes; + ActivityEvent? logEvent = activity.Events.FirstOrDefault(); - Activity activity = this.activitySource.StartActivity("Test"); + Assert.NotNull(logEvent); + Assert.Equal("log", logEvent.Value.Name); - using IDisposable scope = this.logger.BeginScope("{NodeId}", 99); + Dictionary tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + Assert.NotNull(tags); - this.logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); + Assert.Equal("OpenTelemetry.Extensions.Tests.ActivityEventAttachingLogProcessorTests", tags[nameof(LogRecord.CategoryName)]); + Assert.Equal(LogLevel.Information, tags[nameof(LogRecord.LogLevel)]); - Activity innerActivity = null; - if (recordException) + if (eventId != 0) { - innerActivity = this.activitySource.StartActivity("InnerTest"); - - using IDisposable innerScope = this.logger.BeginScope("{RequestId}", "1234"); - - this.logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); + Assert.Equal((EventId)eventId, tags[nameof(LogRecord.EventId)]); + } + else + { + Assert.DoesNotContain(tags, kvp => kvp.Key == nameof(LogRecord.EventId)); + } - innerActivity.Dispose(); + if (includeFormattedMessage) + { + Assert.Equal("Hello OpenTelemetry 8!", tags[nameof(LogRecord.FormattedMessage)]); + } + else + { + Assert.DoesNotContain(tags, kvp => kvp.Key == nameof(LogRecord.FormattedMessage)); } - activity.Dispose(); + if (parseStateValues) + { + Assert.Equal(8, tags["state.UserId"]); + } + else + { + Assert.DoesNotContain(tags, kvp => kvp.Key == "state.UserId"); + } - if (sampled) + if (includeScopes) { - ActivityEvent? logEvent = activity.Events.FirstOrDefault(); - - Assert.NotNull(logEvent); - Assert.Equal("log", logEvent.Value.Name); - - Dictionary tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); - Assert.NotNull(tags); - - Assert.Equal("OpenTelemetry.Extensions.Tests.ActivityEventAttachingLogProcessorTests", tags[nameof(LogRecord.CategoryName)]); - Assert.Equal(LogLevel.Information, tags[nameof(LogRecord.LogLevel)]); - - if (eventId != 0) - { - Assert.Equal((EventId)eventId, tags[nameof(LogRecord.EventId)]); - } - else - { - Assert.DoesNotContain(tags, kvp => kvp.Key == nameof(LogRecord.EventId)); - } - - if (includeFormattedMessage) - { - Assert.Equal("Hello OpenTelemetry 8!", tags[nameof(LogRecord.FormattedMessage)]); - } - else - { - Assert.DoesNotContain(tags, kvp => kvp.Key == nameof(LogRecord.FormattedMessage)); - } - - if (parseStateValues) - { - Assert.Equal(8, tags["state.UserId"]); - } - else - { - Assert.DoesNotContain(tags, kvp => kvp.Key == "state.UserId"); - } - - if (includeScopes) - { - Assert.Equal(99, tags["scope[0].NodeId"]); - } - else - { - Assert.DoesNotContain(tags, kvp => kvp.Key == "scope[0].NodeId"); - } - - if (recordException) - { - ActivityEvent? exLogEvent = innerActivity.Events.FirstOrDefault(); - - Assert.NotNull(exLogEvent); - Assert.Equal("log", exLogEvent.Value.Name); - - Dictionary exLogTags = exLogEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); - Assert.NotNull(exLogTags); - - Assert.Equal(99, exLogTags["scope[0].NodeId"]); - Assert.Equal("1234", exLogTags["scope[1].RequestId"]); - - ActivityEvent? exEvent = innerActivity.Events.Skip(1).FirstOrDefault(); - - Assert.NotNull(exEvent); - Assert.Equal("exception", exEvent.Value.Name); - - Dictionary exTags = exEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); - Assert.NotNull(exTags); - - Assert.Equal("System.InvalidOperationException", exTags["exception.type"]); - Assert.Equal("Goodbye OpenTelemetry.", exTags["exception.message"]); - Assert.Contains(exTags, kvp => kvp.Key == "exception.stacktrace"); - } + Assert.Equal(99, tags["scope[0].NodeId"]); } else { - Assert.Empty(activity.Events); + Assert.DoesNotContain(tags, kvp => kvp.Key == "scope[0].NodeId"); + } + + if (recordException) + { + ActivityEvent? exLogEvent = innerActivity.Events.FirstOrDefault(); + + Assert.NotNull(exLogEvent); + Assert.Equal("log", exLogEvent.Value.Name); + + Dictionary exLogTags = exLogEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + Assert.NotNull(exLogTags); + + Assert.Equal(99, exLogTags["scope[0].NodeId"]); + Assert.Equal("1234", exLogTags["scope[1].RequestId"]); + + ActivityEvent? exEvent = innerActivity.Events.Skip(1).FirstOrDefault(); + + Assert.NotNull(exEvent); + Assert.Equal("exception", exEvent.Value.Name); + + Dictionary exTags = exEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + Assert.NotNull(exTags); + + Assert.Equal("System.InvalidOperationException", exTags["exception.type"]); + Assert.Equal("Goodbye OpenTelemetry.", exTags["exception.message"]); + Assert.Contains(exTags, kvp => kvp.Key == "exception.stacktrace"); } } + else + { + Assert.Empty(activity.Events); + } } } diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index bf885f40cd..e1c060fb87 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -21,62 +21,61 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Extensions.Tests.Trace +namespace OpenTelemetry.Extensions.Tests.Trace; + +public class AutoFlushActivityProcessorTests { - public class AutoFlushActivityProcessorTests + [Fact] + public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMatchingSpan_Flush() { - [Fact] - public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMatchingSpan_Flush() - { - var mockExporting = new Mock>(); + var mockExporting = new Mock>(); - using var provider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(mockExporting.Object) - .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000) - .AddSource("foo") - .Build(); + using var provider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(mockExporting.Object) + .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000) + .AddSource("foo") + .Build(); - using var source = new ActivitySource("foo"); - using var activity = source.StartActivity("name", ActivityKind.Server); - activity.Dispose(); + using var source = new ActivitySource("foo"); + using var activity = source.StartActivity("name", ActivityKind.Server); + activity.Dispose(); - mockExporting.Protected().Verify("OnForceFlush", Times.Once(), 5_000); - } + mockExporting.Protected().Verify("OnForceFlush", Times.Once(), 5_000); + } - [Fact] - public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNonMatchingSpan_DoesNothing() - { - var mockExporting = new Mock>(); + [Fact] + public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNonMatchingSpan_DoesNothing() + { + var mockExporting = new Mock>(); - using var provider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(mockExporting.Object) - .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer)) - .AddSource("foo") - .Build(); + using var provider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(mockExporting.Object) + .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer)) + .AddSource("foo") + .Build(); - using var source = new ActivitySource("foo"); - using var activity = source.StartActivity("name", ActivityKind.Client); - activity.Dispose(); + using var source = new ActivitySource("foo"); + using var activity = source.StartActivity("name", ActivityKind.Client); + activity.Dispose(); - mockExporting.Protected().Verify("OnForceFlush", Times.Never(), It.IsAny()); - } + mockExporting.Protected().Verify("OnForceFlush", Times.Never(), It.IsAny()); + } - [Fact] - public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() - { - var mockExporting = new Mock>(); + [Fact] + public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() + { + var mockExporting = new Mock>(); - using var provider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(mockExporting.Object) - .AddAutoFlushActivityProcessor(_ => throw new Exception("Predicate throws an exception.")) - .AddSource("foo") - .Build(); + using var provider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(mockExporting.Object) + .AddAutoFlushActivityProcessor(_ => throw new Exception("Predicate throws an exception.")) + .AddSource("foo") + .Build(); - using var source = new ActivitySource("foo"); - using var activity = source.StartActivity("name", ActivityKind.Server); - activity.Dispose(); + using var source = new ActivitySource("foo"); + using var activity = source.StartActivity("name", ActivityKind.Server); + activity.Dispose(); - mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); - } + mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); } } From 84338465981207a23a087cb00c3ac199a6eb432e Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 3 Aug 2022 17:40:17 -0700 Subject: [PATCH 0269/1499] [Instrumentation.Runtime] Release Runtime instrumentation version 1.0.0 (#553) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 4 ++++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 ---- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 4 ++++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 ---- .../.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt | 4 ++++ .../.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt | 4 ---- .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 4 ++++ .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 4 ---- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..4f1e7e604f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt index 4f1e7e604f..e69de29bb2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt index e69de29bb2..4f1e7e604f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt index 4f1e7e604f..e69de29bb2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt index e69de29bb2..4f1e7e604f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt index 4f1e7e604f..e69de29bb2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..4f1e7e604f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions +OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 4f1e7e604f..e69de29bb2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 878f819c97..d9cadc760e 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0 + +Released 2022-Aug-03 + * Rename `RuntimeInstrumentOptions` to `RuntimeInstrumentationOptions` ([#556](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/556)) From 6ee4ebabac096c90fa608b591225620bdbbb977e Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 3 Aug 2022 22:03:48 -0700 Subject: [PATCH 0270/1499] [Instrumentation.Runtime] Reword README.md (#558) --- .../README.md | 45 +++++-------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 74d2264fa8..c4647cf140 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -22,33 +22,8 @@ dotnet add package OpenTelemetry.Instrumentation.Runtime ### Step 2: Enable runtime instrumentation -Runtime instrumentation should be enabled at application startup. This is -typically done in the `ConfigureServices` of your `Startup` class. The example -below enables this instrumentation by using an extension method on -`IServiceCollection`. This extension method requires adding the package -[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md) -to the application. This ensures the instrumentation is disposed when the host -is shutdown. - -Additionally, this examples sets up the OpenTelemetry Prometheus exporter, which -requires adding the package -[`OpenTelemetry.Exporter.Prometheus`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus/README.md) -to the application. - -```csharp -using Microsoft.Extensions.DependencyInjection; -using OpenTelemetry.Metrics; - -public void ConfigureServices(IServiceCollection services) -{ - services.AddOpenTelemetryMetrics((builder) => builder - .AddRuntimeInstrumentation() - .AddPrometheusExporter() - ); -} -``` - -Or configure directly: +Runtime instrumentation should be enabled at application startup using the +`AddRuntimeInstrumentation` extension on `MeterProviderBuilder`: ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() @@ -60,6 +35,11 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder() Refer to [Program.cs](../../examples/runtime-instrumentation/Program.cs) for a complete demo. +Additionally, this examples sets up the OpenTelemetry Prometheus exporter, which +requires adding the package +[`OpenTelemetry.Exporter.Prometheus`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +to the application. + ## Metrics ### GC related metrics @@ -318,12 +298,11 @@ Relevant API: ## Troubleshooting -This component uses an -[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) -with the name "OpenTelemetry-Instrumentation-Runtime" for its internal -logging. Please refer to [SDK -troubleshooting](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry#troubleshooting) -for instructions on seeing these internal logs. +If a metric is missing, review the [list of metrics](#metrics) to see if the +metric is available in the .NET version you are running. + +Some GC related metrics are unavailable until at least one garbage collection +has occurred. ## References From 2c57ff08c0398bf408a97113ad598985d4ad9635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 4 Aug 2022 18:55:16 +0200 Subject: [PATCH 0271/1499] [WCF.Intrumentation] Filescoped namespace (#561) --- .../Implementation/ActionMetadata.cs | 11 +- .../WcfInstrumentationActivitySource.cs | 55 ++- .../WcfInstrumentationConstants.cs | 33 +- .../WcfInstrumentationEventSource.cs | 105 +++-- .../TelemetryClientMessageInspector.cs | 239 +++++----- .../TelemetryContractBehaviorAttribute.cs | 64 ++- .../TelemetryDispatchMessageInspector.cs | 196 ++++---- .../TelemetryEndpointBehavior.cs | 108 +++-- ...lemetryEndpointBehaviorExtensionElement.cs | 26 +- .../TelemetryServiceBehavior.cs | 49 +- ...elemetryServiceBehaviorExtensionElement.cs | 26 +- .../TracerProviderBuilderExtensions.cs | 41 +- .../WcfEnrichEventNames.cs | 43 +- .../WcfInstrumentationOptions.cs | 75 ++-- .../TelemetryClientMessageInspectorTests.cs | 417 +++++++++--------- ...InspectorForOneWayOperationsTests.netfx.cs | 193 ++++---- ...etryDispatchMessageInspectorTests.netfx.cs | 339 +++++++------- .../Tools/ErrorHandler.netfx.cs | 45 +- .../ErrorHandlerServiceBehavior.netfx.cs | 43 +- .../WCF/IServiceContract.cs | 21 +- .../WCF/Service.netfx.cs | 55 +-- .../WCF/ServiceClient.cs | 25 +- .../WCF/ServiceRequest.cs | 13 +- .../WCF/ServiceResponse.cs | 13 +- 24 files changed, 1110 insertions(+), 1125 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs index 39c32c9c71..e4bc90e78b 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs @@ -14,12 +14,11 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +internal sealed class ActionMetadata { - internal sealed class ActionMetadata - { - public string ContractName { get; set; } + public string ContractName { get; set; } - public string OperationName { get; set; } - } + public string OperationName { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index cd96f3bd5a..c90e363450 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -19,33 +19,32 @@ using System.Diagnostics; using System.ServiceModel.Channels; -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// WCF instrumentation. +/// +internal static class WcfInstrumentationActivitySource { - /// - /// WCF instrumentation. - /// - internal static class WcfInstrumentationActivitySource - { - public const string ActivitySourceName = "OpenTelemetry.WCF"; - public const string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; - public const string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; - - private static readonly Version Version = typeof(WcfInstrumentationActivitySource).Assembly.GetName().Version; - - public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); - - public static Func> MessageHeaderValuesGetter { get; } - = (request, name) => - { - var headerIndex = request.Headers.FindHeader(name, "https://www.w3.org/TR/trace-context/"); - return headerIndex < 0 - ? null - : new[] { request.Headers.GetHeader(headerIndex) }; - }; - - public static Action MessageHeaderValueSetter { get; } - = (request, name, value) => request.Headers.Add(MessageHeader.CreateHeader(name, "https://www.w3.org/TR/trace-context/", value, false)); - - public static WcfInstrumentationOptions Options { get; set; } - } + public const string ActivitySourceName = "OpenTelemetry.WCF"; + public const string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; + public const string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; + + private static readonly Version Version = typeof(WcfInstrumentationActivitySource).Assembly.GetName().Version; + + public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); + + public static Func> MessageHeaderValuesGetter { get; } + = (request, name) => + { + var headerIndex = request.Headers.FindHeader(name, "https://www.w3.org/TR/trace-context/"); + return headerIndex < 0 + ? null + : new[] { request.Headers.GetHeader(headerIndex) }; + }; + + public static Action MessageHeaderValueSetter { get; } + = (request, name, value) => request.Headers.Add(MessageHeader.CreateHeader(name, "https://www.w3.org/TR/trace-context/", value, false)); + + public static WcfInstrumentationOptions Options { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs index bff21a0caf..e3f934bb5e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs @@ -14,23 +14,22 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +internal static class WcfInstrumentationConstants { - internal static class WcfInstrumentationConstants - { - public const string RpcSystemTag = "rpc.system"; - public const string RpcServiceTag = "rpc.service"; - public const string RpcMethodTag = "rpc.method"; - public const string NetHostNameTag = "net.host.name"; - public const string NetHostPortTag = "net.host.port"; - public const string NetPeerNameTag = "net.peer.name"; - public const string NetPeerPortTag = "net.peer.port"; - public const string SoapMessageVersionTag = "soap.message_version"; - public const string SoapReplyActionTag = "soap.reply_action"; - public const string SoapViaTag = "soap.via"; - public const string WcfChannelSchemeTag = "wcf.channel.scheme"; - public const string WcfChannelPathTag = "wcf.channel.path"; + public const string RpcSystemTag = "rpc.system"; + public const string RpcServiceTag = "rpc.service"; + public const string RpcMethodTag = "rpc.method"; + public const string NetHostNameTag = "net.host.name"; + public const string NetHostPortTag = "net.host.port"; + public const string NetPeerNameTag = "net.peer.name"; + public const string NetPeerPortTag = "net.peer.port"; + public const string SoapMessageVersionTag = "soap.message_version"; + public const string SoapReplyActionTag = "soap.reply_action"; + public const string SoapViaTag = "soap.via"; + public const string WcfChannelSchemeTag = "wcf.channel.scheme"; + public const string WcfChannelPathTag = "wcf.channel.path"; - public const string WcfSystemValue = "wcf"; - } + public const string WcfSystemValue = "wcf"; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index bab42d7e92..fa73b497c1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -19,73 +19,72 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Instrumentation.Wcf.Implementation +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +[EventSource(Name = "OpenTelemetry-Instrumentation-Wcf")] +internal sealed class WcfInstrumentationEventSource : EventSource { - [EventSource(Name = "OpenTelemetry-Instrumentation-Wcf")] - internal sealed class WcfInstrumentationEventSource : EventSource - { - public static readonly WcfInstrumentationEventSource Log = new WcfInstrumentationEventSource(); + public static readonly WcfInstrumentationEventSource Log = new WcfInstrumentationEventSource(); - [NonEvent] - public void RequestFilterException(Exception ex) + [NonEvent] + public void RequestFilterException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.RequestFilterException(ToInvariantString(ex)); - } + this.RequestFilterException(ToInvariantString(ex)); } + } - [Event(EventIds.RequestIsFilteredOut, Message = "Request is filtered out.", Level = EventLevel.Verbose)] - public void RequestIsFilteredOut() - { - this.WriteEvent(EventIds.RequestIsFilteredOut); - } + [Event(EventIds.RequestIsFilteredOut, Message = "Request is filtered out.", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut() + { + this.WriteEvent(EventIds.RequestIsFilteredOut); + } - [Event(EventIds.RequestFilterException, Message = "InstrumentationFilter threw exception. Request will not be collected. Exception {0}.", Level = EventLevel.Error)] - public void RequestFilterException(string exception) - { - this.WriteEvent(EventIds.RequestFilterException, exception); - } + [Event(EventIds.RequestFilterException, Message = "InstrumentationFilter threw exception. Request will not be collected. Exception {0}.", Level = EventLevel.Error)] + public void RequestFilterException(string exception) + { + this.WriteEvent(EventIds.RequestFilterException, exception); + } - [NonEvent] - public void EnrichmentException(Exception exception) + [NonEvent] + public void EnrichmentException(Exception exception) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.EnrichmentException(ToInvariantString(exception)); - } + this.EnrichmentException(ToInvariantString(exception)); } + } - [Event(EventIds.EnrichmentException, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] - public void EnrichmentException(string exception) - { - this.WriteEvent(EventIds.EnrichmentException, exception); - } + [Event(EventIds.EnrichmentException, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(EventIds.EnrichmentException, exception); + } - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - private class EventIds + finally { - public const int RequestIsFilteredOut = 1; - public const int RequestFilterException = 2; - public const int EnrichmentException = 3; + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } + + private class EventIds + { + public const int RequestIsFilteredOut = 1; + public const int RequestFilterException = 2; + public const int EnrichmentException = 3; + } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index 41d00e779a..2830e78c91 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -25,163 +25,162 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// An implementation which adds telemetry to outgoing requests. +/// +public class TelemetryClientMessageInspector : IClientMessageInspector { - /// - /// An implementation which adds telemetry to outgoing requests. - /// - public class TelemetryClientMessageInspector : IClientMessageInspector - { - private readonly IDictionary actionMappings; + private readonly IDictionary actionMappings; - internal TelemetryClientMessageInspector(IDictionary actionMappings) - { - Guard.ThrowIfNull(actionMappings); + internal TelemetryClientMessageInspector(IDictionary actionMappings) + { + Guard.ThrowIfNull(actionMappings); - this.actionMappings = actionMappings; - } + this.actionMappings = actionMappings; + } - /// - public object BeforeSendRequest(ref Message request, IClientChannel channel) + /// + public object BeforeSendRequest(ref Message request, IClientChannel channel) + { + try { - try - { - if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.OutgoingRequestFilter?.Invoke(request) == false) - { - WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); - return new State - { - SuppressionScope = this.SuppressDownstreamInstrumentation(), - }; - } - } - catch (Exception ex) + if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.OutgoingRequestFilter?.Invoke(request) == false) { - WcfInstrumentationEventSource.Log.RequestFilterException(ex); + WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); return new State { SuppressionScope = this.SuppressDownstreamInstrumentation(), }; } + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.RequestFilterException(ex); + return new State + { + SuppressionScope = this.SuppressDownstreamInstrumentation(), + }; + } - Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( - WcfInstrumentationActivitySource.OutgoingRequestActivityName, - ActivityKind.Client); - IDisposable suppressionScope = this.SuppressDownstreamInstrumentation(); + Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + WcfInstrumentationActivitySource.OutgoingRequestActivityName, + ActivityKind.Client); + IDisposable suppressionScope = this.SuppressDownstreamInstrumentation(); - if (activity != null) + if (activity != null) + { + string action; + if (!string.IsNullOrEmpty(request.Headers.Action)) { - string action; - if (!string.IsNullOrEmpty(request.Headers.Action)) - { - action = request.Headers.Action; - activity.DisplayName = action; - } - else - { - action = string.Empty; - } + action = request.Headers.Action; + activity.DisplayName = action; + } + else + { + action = string.Empty; + } - Propagators.DefaultTextMapPropagator.Inject( - new PropagationContext(activity.Context, Baggage.Current), - request, - WcfInstrumentationActivitySource.MessageHeaderValueSetter); + Propagators.DefaultTextMapPropagator.Inject( + new PropagationContext(activity.Context, Baggage.Current), + request, + WcfInstrumentationActivitySource.MessageHeaderValueSetter); - if (activity.IsAllDataRequested) - { - activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); + if (activity.IsAllDataRequested) + { + activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); - if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) + if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) + { + actionMetadata = new ActionMetadata { - actionMetadata = new ActionMetadata - { - ContractName = null, - OperationName = action, - }; - } + ContractName = null, + OperationName = action, + }; + } - activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); - activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); + activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); + activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); - if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) - { - activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); - } + if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) + { + activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); + } - var remoteAddressUri = request.Headers.To ?? channel.RemoteAddress?.Uri; - if (remoteAddressUri != null) - { - activity.SetTag(WcfInstrumentationConstants.NetPeerNameTag, remoteAddressUri.Host); - activity.SetTag(WcfInstrumentationConstants.NetPeerPortTag, remoteAddressUri.Port); - activity.SetTag(WcfInstrumentationConstants.WcfChannelSchemeTag, remoteAddressUri.Scheme); - activity.SetTag(WcfInstrumentationConstants.WcfChannelPathTag, remoteAddressUri.LocalPath); - } + var remoteAddressUri = request.Headers.To ?? channel.RemoteAddress?.Uri; + if (remoteAddressUri != null) + { + activity.SetTag(WcfInstrumentationConstants.NetPeerNameTag, remoteAddressUri.Host); + activity.SetTag(WcfInstrumentationConstants.NetPeerPortTag, remoteAddressUri.Port); + activity.SetTag(WcfInstrumentationConstants.WcfChannelSchemeTag, remoteAddressUri.Scheme); + activity.SetTag(WcfInstrumentationConstants.WcfChannelPathTag, remoteAddressUri.LocalPath); + } - if (request.Properties.Via != null) - { - activity.SetTag(WcfInstrumentationConstants.SoapViaTag, request.Properties.Via.ToString()); - } + if (request.Properties.Via != null) + { + activity.SetTag(WcfInstrumentationConstants.SoapViaTag, request.Properties.Via.ToString()); + } - try - { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendRequest, request); - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.EnrichmentException(ex); - } + try + { + WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendRequest, request); + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.EnrichmentException(ex); } } - - return new State - { - SuppressionScope = suppressionScope, - Activity = activity, - }; } - /// - public void AfterReceiveReply(ref Message reply, object correlationState) + return new State { - State state = (State)correlationState; + SuppressionScope = suppressionScope, + Activity = activity, + }; + } + + /// + public void AfterReceiveReply(ref Message reply, object correlationState) + { + State state = (State)correlationState; - state.SuppressionScope?.Dispose(); + state.SuppressionScope?.Dispose(); - if (state.Activity is Activity activity) + if (state.Activity is Activity activity) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + if (reply.IsFault) { - if (reply.IsFault) - { - activity.SetStatus(Status.Error); - } - - activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); - try - { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveReply, reply); - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.EnrichmentException(ex); - } + activity.SetStatus(Status.Error); } - activity.Stop(); + activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); + try + { + WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveReply, reply); + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.EnrichmentException(ex); + } } - } - private IDisposable SuppressDownstreamInstrumentation() - { - return WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false - ? SuppressInstrumentationScope.Begin() - : null; + activity.Stop(); } + } - private class State - { - public IDisposable SuppressionScope; - public Activity Activity; - } + private IDisposable SuppressDownstreamInstrumentation() + { + return WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false + ? SuppressInstrumentationScope.Begin() + : null; + } + + private class State + { + public IDisposable SuppressionScope; + public Activity Activity; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 0c6bed3ee6..522dfc9ec3 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -19,47 +19,45 @@ using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -namespace OpenTelemetry.Instrumentation.Wcf -{ +namespace OpenTelemetry.Instrumentation.Wcf; #if NETFRAMEWORK - /// - /// An to add the - /// to service operations - /// and to client operations - /// programmatically. - /// +/// +/// An to add the +/// to service operations +/// and to client operations +/// programmatically. +/// #else - /// - /// An to add the - /// to client operations - /// programmatically. - /// +/// +/// An to add the +/// to client operations +/// programmatically. +/// #endif - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] - public sealed class TelemetryContractBehaviorAttribute : Attribute, IContractBehavior +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] +public sealed class TelemetryContractBehaviorAttribute : Attribute, IContractBehavior +{ + /// + public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { - /// - public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) - { - } + } - /// - public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) - { - TelemetryEndpointBehavior.ApplyClientBehaviorToClientRuntime(clientRuntime); - } + /// + public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) + { + TelemetryEndpointBehavior.ApplyClientBehaviorToClientRuntime(clientRuntime); + } - /// - public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) - { + /// + public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) + { #if NETFRAMEWORK - TelemetryEndpointBehavior.ApplyDispatchBehaviorToEndpoint(dispatchRuntime.EndpointDispatcher); + TelemetryEndpointBehavior.ApplyDispatchBehaviorToEndpoint(dispatchRuntime.EndpointDispatcher); #endif - } + } - /// - public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) - { - } + /// + public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) + { } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index 151292ed6c..26e109eaa9 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -26,140 +26,140 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// An implementation which adds telemetry to incoming requests. +/// +public class TelemetryDispatchMessageInspector : IDispatchMessageInspector { - /// - /// An implementation which adds telemetry to incoming requests. - /// - public class TelemetryDispatchMessageInspector : IDispatchMessageInspector + private readonly IDictionary actionMappings; + + internal TelemetryDispatchMessageInspector(IDictionary actionMappings) { - private readonly IDictionary actionMappings; + Guard.ThrowIfNull(actionMappings); - internal TelemetryDispatchMessageInspector(IDictionary actionMappings) - { - Guard.ThrowIfNull(actionMappings); + this.actionMappings = actionMappings; + } - this.actionMappings = actionMappings; + /// + public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) + { + try + { + if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.IncomingRequestFilter?.Invoke(request) == false) + { + WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); + return null; + } + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.RequestFilterException(ex); + return null; } - /// - public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) + var textMapPropagator = Propagators.DefaultTextMapPropagator; + var ctx = textMapPropagator.Extract(default, request, WcfInstrumentationActivitySource.MessageHeaderValuesGetter); + + Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + WcfInstrumentationActivitySource.IncomingRequestActivityName, + ActivityKind.Server, + ctx.ActivityContext); + + if (activity != null) { - try + string action; + if (!string.IsNullOrEmpty(request.Headers.Action)) { - if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.IncomingRequestFilter?.Invoke(request) == false) - { - WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); - return null; - } + action = request.Headers.Action; + activity.DisplayName = action; } - catch (Exception ex) + else { - WcfInstrumentationEventSource.Log.RequestFilterException(ex); - return null; + action = string.Empty; } - var textMapPropagator = Propagators.DefaultTextMapPropagator; - var ctx = textMapPropagator.Extract(default, request, WcfInstrumentationActivitySource.MessageHeaderValuesGetter); - - Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( - WcfInstrumentationActivitySource.IncomingRequestActivityName, - ActivityKind.Server, - ctx.ActivityContext); - - if (activity != null) + if (activity.IsAllDataRequested) { - string action; - if (!string.IsNullOrEmpty(request.Headers.Action)) - { - action = request.Headers.Action; - activity.DisplayName = action; - } - else - { - action = string.Empty; - } + activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); - if (activity.IsAllDataRequested) + if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) { - activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); - - if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) + actionMetadata = new ActionMetadata { - actionMetadata = new ActionMetadata - { - ContractName = null, - OperationName = action, - }; - } - - activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); - activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); + ContractName = null, + OperationName = action, + }; + } - if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) - { - activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); - } + activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); + activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); - var localAddressUri = channel.LocalAddress?.Uri; - if (localAddressUri != null) - { - activity.SetTag(WcfInstrumentationConstants.NetHostNameTag, localAddressUri.Host); - activity.SetTag(WcfInstrumentationConstants.NetHostPortTag, localAddressUri.Port); - activity.SetTag(WcfInstrumentationConstants.WcfChannelSchemeTag, localAddressUri.Scheme); - activity.SetTag(WcfInstrumentationConstants.WcfChannelPathTag, localAddressUri.LocalPath); - } + if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) + { + activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); + } - try - { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveRequest, request); - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.EnrichmentException(ex); - } + var localAddressUri = channel.LocalAddress?.Uri; + if (localAddressUri != null) + { + activity.SetTag(WcfInstrumentationConstants.NetHostNameTag, localAddressUri.Host); + activity.SetTag(WcfInstrumentationConstants.NetHostPortTag, localAddressUri.Port); + activity.SetTag(WcfInstrumentationConstants.WcfChannelSchemeTag, localAddressUri.Scheme); + activity.SetTag(WcfInstrumentationConstants.WcfChannelPathTag, localAddressUri.LocalPath); } - if (!(textMapPropagator is TraceContextPropagator)) + try { - Baggage.Current = ctx.Baggage; + WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveRequest, request); + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.EnrichmentException(ex); } } - return activity; + if (!(textMapPropagator is TraceContextPropagator)) + { + Baggage.Current = ctx.Baggage; + } } - /// - public void BeforeSendReply(ref Message reply, object correlationState) + return activity; + } + + /// + public void BeforeSendReply(ref Message reply, object correlationState) + { + if (correlationState is Activity activity) { - if (correlationState is Activity activity) + if (activity.IsAllDataRequested && reply != null) { - if (activity.IsAllDataRequested && reply != null) + if (reply.IsFault) { - if (reply.IsFault) - { - activity.SetStatus(Status.Error); - } - - activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); - try - { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendReply, reply); - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.EnrichmentException(ex); - } + activity.SetStatus(Status.Error); } - activity.Stop(); - - if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) + activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); + try + { + WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendReply, reply); + } + catch (Exception ex) { - Baggage.Current = default; + WcfInstrumentationEventSource.Log.EnrichmentException(ex); } } + + activity.Stop(); + + if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) + { + Baggage.Current = default; + } } } } + #endif diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index 06e4498282..73417ff793 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -20,78 +20,76 @@ using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -namespace OpenTelemetry.Instrumentation.Wcf -{ +namespace OpenTelemetry.Instrumentation.Wcf; #if NETFRAMEWORK - /// - /// An implementation which adds the to client endpoints and the - /// to service endpoints. - /// +/// +/// An implementation which adds the to client endpoints and the +/// to service endpoints. +/// #else - /// - /// An implementation which adds the to client endpoints. - /// +/// +/// An implementation which adds the to client endpoints. +/// #endif - public class TelemetryEndpointBehavior : IEndpointBehavior +public class TelemetryEndpointBehavior : IEndpointBehavior +{ + /// + public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { - /// - public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) - { - } + } - /// - public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) - { - ApplyClientBehaviorToClientRuntime(clientRuntime); - } + /// + public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) + { + ApplyClientBehaviorToClientRuntime(clientRuntime); + } - /// - public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) - { + /// + public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) + { #if NETFRAMEWORK - ApplyDispatchBehaviorToEndpoint(endpointDispatcher); + ApplyDispatchBehaviorToEndpoint(endpointDispatcher); #endif - } + } - /// - public void Validate(ServiceEndpoint endpoint) - { - } + /// + public void Validate(ServiceEndpoint endpoint) + { + } - internal static void ApplyClientBehaviorToClientRuntime(ClientRuntime clientRuntime) - { - var actionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + internal static void ApplyClientBehaviorToClientRuntime(ClientRuntime clientRuntime) + { + var actionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var clientOperation in clientRuntime.ClientOperations) + foreach (var clientOperation in clientRuntime.ClientOperations) + { + actionMappings[clientOperation.Action] = new ActionMetadata { - actionMappings[clientOperation.Action] = new ActionMetadata - { - ContractName = $"{clientRuntime.ContractNamespace}{clientRuntime.ContractName}", - OperationName = clientOperation.Name, - }; - } - - clientRuntime.ClientMessageInspectors.Add(new TelemetryClientMessageInspector(actionMappings)); + ContractName = $"{clientRuntime.ContractNamespace}{clientRuntime.ContractName}", + OperationName = clientOperation.Name, + }; } + clientRuntime.ClientMessageInspectors.Add(new TelemetryClientMessageInspector(actionMappings)); + } + #if NETFRAMEWORK - internal static void ApplyDispatchBehaviorToEndpoint(EndpointDispatcher endpointDispatcher) - { - var actionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); + internal static void ApplyDispatchBehaviorToEndpoint(EndpointDispatcher endpointDispatcher) + { + var actionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var dispatchOperation in endpointDispatcher.DispatchRuntime.Operations) + foreach (var dispatchOperation in endpointDispatcher.DispatchRuntime.Operations) + { + actionMappings[dispatchOperation.Action] = new ActionMetadata { - actionMappings[dispatchOperation.Action] = new ActionMetadata - { - ContractName = $"{endpointDispatcher.ContractNamespace}{endpointDispatcher.ContractName}", - OperationName = dispatchOperation.Name, - }; - } - - endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new TelemetryDispatchMessageInspector(actionMappings)); + ContractName = $"{endpointDispatcher.ContractNamespace}{endpointDispatcher.ContractName}", + OperationName = dispatchOperation.Name, + }; } -#endif + + endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new TelemetryDispatchMessageInspector(actionMappings)); } +#endif } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs index c02c03f98d..c2bd78c1a0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs @@ -18,21 +18,21 @@ using System; using System.ServiceModel.Configuration; -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// A for registering on a service endpoint through configuration. +/// +public class TelemetryEndpointBehaviorExtensionElement : BehaviorExtensionElement { - /// - /// A for registering on a service endpoint through configuration. - /// - public class TelemetryEndpointBehaviorExtensionElement : BehaviorExtensionElement - { - /// - public override Type BehaviorType => typeof(TelemetryEndpointBehavior); + /// + public override Type BehaviorType => typeof(TelemetryEndpointBehavior); - /// - protected override object CreateBehavior() - { - return new TelemetryEndpointBehavior(); - } + /// + protected override object CreateBehavior() + { + return new TelemetryEndpointBehavior(); } } + #endif diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs index d616800688..c9cb943025 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -14,43 +14,40 @@ // limitations under the License. // -#pragma warning disable IDE0005 // Using directive is unnecessary. +#if NETFRAMEWORK using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -#pragma warning restore IDE0005 // Using directive is unnecessary. -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// An implementation to add the +/// to service operations. +/// +public class TelemetryServiceBehavior : IServiceBehavior { -#if NETFRAMEWORK - /// - /// An implementation to add the - /// to service operations. - /// - public class TelemetryServiceBehavior : IServiceBehavior + /// + public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { - /// - public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) - { - } + } - /// - public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + /// + public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + foreach (var channelDispatcherBase in serviceHostBase.ChannelDispatchers) { - foreach (var channelDispatcherBase in serviceHostBase.ChannelDispatchers) + var channelDispatcher = (ChannelDispatcher)channelDispatcherBase; + foreach (var endpointDispatcher in channelDispatcher.Endpoints) { - var channelDispatcher = (ChannelDispatcher)channelDispatcherBase; - foreach (var endpointDispatcher in channelDispatcher.Endpoints) - { - TelemetryEndpointBehavior.ApplyDispatchBehaviorToEndpoint(endpointDispatcher); - } + TelemetryEndpointBehavior.ApplyDispatchBehaviorToEndpoint(endpointDispatcher); } } + } - /// - public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) - { - } + /// + public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { } -#endif } +#endif diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs index a1df56f16d..90fb6794af 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs @@ -18,21 +18,21 @@ using System; using System.ServiceModel.Configuration; -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// A for registering on a service through configuration. +/// +public class TelemetryServiceBehaviorExtensionElement : BehaviorExtensionElement { - /// - /// A for registering on a service through configuration. - /// - public class TelemetryServiceBehaviorExtensionElement : BehaviorExtensionElement - { - /// - public override Type BehaviorType => typeof(TelemetryServiceBehavior); + /// + public override Type BehaviorType => typeof(TelemetryServiceBehavior); - /// - protected override object CreateBehavior() - { - return new TelemetryServiceBehavior(); - } + /// + protected override object CreateBehavior() + { + return new TelemetryServiceBehavior(); } } + #endif diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index 2d99b44919..fbfad45d92 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -18,34 +18,33 @@ using OpenTelemetry.Instrumentation.Wcf; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables the outgoing requests automatic data collection for WCF. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// Wcf configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action configure = null) { - /// - /// Enables the outgoing requests automatic data collection for WCF. - /// - /// being configured. - /// Wcf configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - if (WcfInstrumentationActivitySource.Options != null) - { - throw new NotSupportedException("WCF instrumentation has already been registered and doesn't support multiple registrations."); - } + if (WcfInstrumentationActivitySource.Options != null) + { + throw new NotSupportedException("WCF instrumentation has already been registered and doesn't support multiple registrations."); + } - var options = new WcfInstrumentationOptions(); - configure?.Invoke(options); + var options = new WcfInstrumentationOptions(); + configure?.Invoke(options); - WcfInstrumentationActivitySource.Options = options; + WcfInstrumentationActivitySource.Options = options; - return builder.AddSource(WcfInstrumentationActivitySource.ActivitySourceName); - } + return builder.AddSource(WcfInstrumentationActivitySource.ActivitySourceName); } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs index 87044abdee..02b1dbe0e9 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs @@ -14,33 +14,32 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// Constants used for event names when enriching an activity. +/// +public static class WcfEnrichEventNames { +#if NETFRAMEWORK /// - /// Constants used for event names when enriching an activity. + /// WCF service activity, event happens before WCF service method is invoked. /// - public static class WcfEnrichEventNames - { -#if NETFRAMEWORK - /// - /// WCF service activity, event happens before WCF service method is invoked. - /// - public const string AfterReceiveRequest = "AfterReceiveRequest"; + public const string AfterReceiveRequest = "AfterReceiveRequest"; - /// - /// WCF service activity, event happens after the WCF service method is invoked but before the reply is sent back to the client. - /// - public const string BeforeSendReply = "BeforeSendReply"; + /// + /// WCF service activity, event happens after the WCF service method is invoked but before the reply is sent back to the client. + /// + public const string BeforeSendReply = "BeforeSendReply"; #endif - /// - /// WCF client activity, event happens before the request is sent across the wire. - /// - public const string BeforeSendRequest = "BeforeSendRequest"; + /// + /// WCF client activity, event happens before the request is sent across the wire. + /// + public const string BeforeSendRequest = "BeforeSendRequest"; - /// - /// WCF client activity, event happens after a reply from the WCF service is received. - /// - public const string AfterReceiveReply = "AfterReceiveReply"; - } + /// + /// WCF client activity, event happens after a reply from the WCF service is received. + /// + public const string AfterReceiveReply = "AfterReceiveReply"; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs index cd2c65dc93..83cca12ecd 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs @@ -18,49 +18,48 @@ using System.Diagnostics; using System.ServiceModel.Channels; -namespace OpenTelemetry.Instrumentation.Wcf +namespace OpenTelemetry.Instrumentation.Wcf; + +/// +/// Options for WCF instrumentation. +/// +public class WcfInstrumentationOptions { /// - /// Options for WCF instrumentation. + /// Gets or sets an action to enrich an Activity. /// - public class WcfInstrumentationOptions - { - /// - /// Gets or sets an action to enrich an Activity. - /// - /// - /// : the activity being enriched. - /// string: the name of the event. Will be one of the constants in . - /// - /// object: the raw from which additional information can be extracted to enrich the activity. - /// - /// - public Action Enrich { get; set; } + /// + /// : the activity being enriched. + /// string: the name of the event. Will be one of the constants in . + /// + /// object: the raw from which additional information can be extracted to enrich the activity. + /// + /// + public Action Enrich { get; set; } - /// - /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. - /// The Filter gets the Message, and should return a boolean. - /// If Filter returns true, the request is collected. - /// If Filter returns false or throw exception, the request is filtered out. - /// - public Func IncomingRequestFilter { get; set; } + /// + /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. + /// The Filter gets the Message, and should return a boolean. + /// If Filter returns true, the request is collected. + /// If Filter returns false or throw exception, the request is filtered out. + /// + public Func IncomingRequestFilter { get; set; } - /// - /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. - /// The Filter gets the Message, and should return a boolean. - /// If Filter returns true, the request is collected. - /// If Filter returns false or throw exception, the request is filtered out. - /// - public Func OutgoingRequestFilter { get; set; } + /// + /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. + /// The Filter gets the Message, and should return a boolean. + /// If Filter returns true, the request is collected. + /// If Filter returns false or throw exception, the request is filtered out. + /// + public Func OutgoingRequestFilter { get; set; } - /// - /// Gets or sets a value indicating whether down stream instrumentation (HttpClient) is suppressed (disabled). Default value: True. - /// - public bool SuppressDownstreamInstrumentation { get; set; } = true; + /// + /// Gets or sets a value indicating whether down stream instrumentation (HttpClient) is suppressed (disabled). Default value: True. + /// + public bool SuppressDownstreamInstrumentation { get; set; } = true; - /// - /// Gets or sets a value indicating whether or not the SOAP message version should be added as the tag. Default value: False. - /// - public bool SetSoapMessageVersion { get; set; } - } + /// + /// Gets or sets a value indicating whether or not the SOAP message version should be added as the tag. Default value: False. + /// + public bool SetSoapMessageVersion { get; set; } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs index 55fabbfc42..5e535f3f57 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs @@ -27,281 +27,280 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[Collection("WCF")] +public class TelemetryClientMessageInspectorTests : IDisposable { - [Collection("WCF")] - public class TelemetryClientMessageInspectorTests : IDisposable - { - private readonly Uri serviceBaseUri; - private readonly HttpListener listener; - private readonly EventWaitHandle initializationHandle; + private readonly Uri serviceBaseUri; + private readonly HttpListener listener; + private readonly EventWaitHandle initializationHandle; - public TelemetryClientMessageInspectorTests() + public TelemetryClientMessageInspectorTests() + { + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) { - Random random = new Random(); - var retryCount = 5; - while (retryCount > 0) + try { - try - { - this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); + this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); - this.listener = new HttpListener(); - this.listener.Prefixes.Add(this.serviceBaseUri.OriginalString); - this.listener.Start(); - break; - } - catch - { - this.listener.Stop(); - this.listener = null; - retryCount--; - } + this.listener = new HttpListener(); + this.listener.Prefixes.Add(this.serviceBaseUri.OriginalString); + this.listener.Start(); + break; } - - if (this.listener == null) + catch { - throw new InvalidOperationException("HttpListener could not be started."); + this.listener.Stop(); + this.listener = null; + retryCount--; } + } - this.initializationHandle = new EventWaitHandle(false, EventResetMode.ManualReset); - try - { - Listener(); + if (this.listener == null) + { + throw new InvalidOperationException("HttpListener could not be started."); + } - this.initializationHandle.WaitOne(); - } - finally - { - this.initializationHandle.Dispose(); - this.initializationHandle = null; - } + this.initializationHandle = new EventWaitHandle(false, EventResetMode.ManualReset); + try + { + Listener(); + + this.initializationHandle.WaitOne(); + } + finally + { + this.initializationHandle.Dispose(); + this.initializationHandle = null; + } - async void Listener() + async void Listener() + { + while (true) { - while (true) + try { - try - { - var ctxTask = this.listener.GetContextAsync(); + var ctxTask = this.listener.GetContextAsync(); - this.initializationHandle?.Set(); + this.initializationHandle?.Set(); - var ctx = await ctxTask.ConfigureAwait(false); + var ctx = await ctxTask.ConfigureAwait(false); - using StreamReader reader = new StreamReader(ctx.Request.InputStream); + using StreamReader reader = new StreamReader(ctx.Request.InputStream); - string request = reader.ReadToEnd(); + string request = reader.ReadToEnd(); - ctx.Response.StatusCode = 200; - ctx.Response.ContentType = "text/xml; charset=utf-8"; + ctx.Response.StatusCode = 200; + ctx.Response.ContentType = "text/xml; charset=utf-8"; - using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream)) + using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream)) + { + if (request.Contains("ExecuteWithEmptyActionName")) { - if (request.Contains("ExecuteWithEmptyActionName")) - { - writer.Write(@"RSP: Hello Open Telemetry!"); - } - else - { - writer.Write(@"RSP: Hello Open Telemetry!"); - } + writer.Write(@"RSP: Hello Open Telemetry!"); } - - ctx.Response.Close(); - } - catch (Exception ex) - { - if (ex is ObjectDisposedException - || (ex is HttpListenerException httpEx && httpEx.ErrorCode == 995)) + else { - // Listener was closed before we got into GetContextAsync or - // Listener was closed while we were in GetContextAsync. - break; + writer.Write(@"RSP: Hello Open Telemetry!"); } + } - throw; + ctx.Response.Close(); + } + catch (Exception ex) + { + if (ex is ObjectDisposedException + || (ex is HttpListenerException httpEx && httpEx.ErrorCode == 995)) + { + // Listener was closed before we got into GetContextAsync or + // Listener was closed while we were in GetContextAsync. + break; } + + throw; } } } + } - public void Dispose() - { - this.listener?.Stop(); - } + public void Dispose() + { + this.listener?.Stop(); + } - [Theory] - [InlineData(true, false)] - [InlineData(true, true)] - [InlineData(true, false, false)] - [InlineData(false)] - [InlineData(true, false, true, true)] - [InlineData(true, false, true, true, true)] - [InlineData(true, false, true, true, true, true)] - [InlineData(true, false, true, true, true, true, true)] - public async Task OutgoingRequestInstrumentationTest( - bool instrument, - bool filter = false, - bool suppressDownstreamInstrumentation = true, - bool includeVersion = false, - bool enrich = false, - bool enrichmentException = false, - bool emptyOrNullAction = false) - { + [Theory] + [InlineData(true, false)] + [InlineData(true, true)] + [InlineData(true, false, false)] + [InlineData(false)] + [InlineData(true, false, true, true)] + [InlineData(true, false, true, true, true)] + [InlineData(true, false, true, true, true, true)] + [InlineData(true, false, true, true, true, true, true)] + public async Task OutgoingRequestInstrumentationTest( + bool instrument, + bool filter = false, + bool suppressDownstreamInstrumentation = true, + bool includeVersion = false, + bool enrich = false, + bool enrichmentException = false, + bool emptyOrNullAction = false) + { #if NETFRAMEWORK - const string OutgoingHttpOperationName = "OpenTelemetry.HttpWebRequest.HttpRequestOut"; + const string OutgoingHttpOperationName = "OpenTelemetry.HttpWebRequest.HttpRequestOut"; #else - const string OutgoingHttpOperationName = "System.Net.Http.HttpRequestOut"; + const string OutgoingHttpOperationName = "System.Net.Http.HttpRequestOut"; #endif - List stoppedActivities = new List(); + List stoppedActivities = new List(); - var builder = Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(stoppedActivities); + var builder = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities); - if (instrument) - { - builder - .AddWcfInstrumentation(options => + if (instrument) + { + builder + .AddWcfInstrumentation(options => + { + if (enrich) { - if (enrich) + if (!enrichmentException) { - if (!enrichmentException) + options.Enrich = (activity, eventName, message) => { - options.Enrich = (activity, eventName, message) => + switch (eventName) { - switch (eventName) - { - case WcfEnrichEventNames.BeforeSendRequest: - activity.SetTag("client.beforesendrequest", WcfEnrichEventNames.BeforeSendRequest); - break; - case WcfEnrichEventNames.AfterReceiveReply: - activity.SetTag("client.afterreceivereply", WcfEnrichEventNames.AfterReceiveReply); - break; - } - }; - } - else - { - options.Enrich = (activity, eventName, message) => throw new Exception("Error while enriching activity"); - } + case WcfEnrichEventNames.BeforeSendRequest: + activity.SetTag("client.beforesendrequest", WcfEnrichEventNames.BeforeSendRequest); + break; + case WcfEnrichEventNames.AfterReceiveReply: + activity.SetTag("client.afterreceivereply", WcfEnrichEventNames.AfterReceiveReply); + break; + } + }; + } + else + { + options.Enrich = (activity, eventName, message) => throw new Exception("Error while enriching activity"); } + } - options.OutgoingRequestFilter = (Message m) => !filter; - options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; - options.SetSoapMessageVersion = includeVersion; - }) - .AddHttpClientInstrumentation(); // <- Added to test SuppressDownstreamInstrumentation. - } + options.OutgoingRequestFilter = (Message m) => !filter; + options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; + options.SetSoapMessageVersion = includeVersion; + }) + .AddHttpClientInstrumentation(); // <- Added to test SuppressDownstreamInstrumentation. + } - TracerProvider tracerProvider = builder.Build(); + TracerProvider tracerProvider = builder.Build(); - ServiceClient client = new ServiceClient( - new BasicHttpBinding(BasicHttpSecurityMode.None), - new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); - try - { - client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + ServiceClient client = new ServiceClient( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - if (emptyOrNullAction) - { - await client.ExecuteWithEmptyActionNameAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); - } - else - { - await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); - } + if (emptyOrNullAction) + { + await client.ExecuteWithEmptyActionNameAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); } - finally + else + { + await client.ExecuteAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } + } + finally + { + if (client.State == CommunicationState.Faulted) { - if (client.State == CommunicationState.Faulted) + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + + WcfInstrumentationActivitySource.Options = null; + } + + if (instrument) + { + if (!suppressDownstreamInstrumentation) + { + Assert.NotEmpty(stoppedActivities); + if (filter) { - client.Abort(); + Assert.Single(stoppedActivities); + Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); } else { - client.Close(); + Assert.Equal(2, stoppedActivities.Count); + Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); } - - tracerProvider.Shutdown(); - tracerProvider.Dispose(); - - WcfInstrumentationActivitySource.Options = null; } - - if (instrument) + else { - if (!suppressDownstreamInstrumentation) + if (!filter) { Assert.NotEmpty(stoppedActivities); - if (filter) + Assert.Single(stoppedActivities); + + Activity activity = stoppedActivities[0]; + + if (emptyOrNullAction) { - Assert.Single(stoppedActivities); - Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.DisplayName); + Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); } else { - Assert.Equal(2, stoppedActivities.Count); - Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); - Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); + Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); + Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); } - } - else - { - if (!filter) - { - Assert.NotEmpty(stoppedActivities); - Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; - - if (emptyOrNullAction) - { - Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.DisplayName); - Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); - } - else - { - Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); - Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); - } - - Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.OperationName); - Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); - Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); - Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerNameTag).Value); - Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerPortTag).Value); - Assert.Equal("http", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); - Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); - if (includeVersion) - { - Assert.Equal("Soap11 (http://schemas.xmlsoap.org/soap/envelope/) AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); - } - - if (enrich && !enrichmentException) - { - Assert.Equal(WcfEnrichEventNames.BeforeSendRequest, activity.TagObjects.Single(t => t.Key == "client.beforesendrequest").Value); - Assert.Equal(WcfEnrichEventNames.AfterReceiveReply, activity.TagObjects.Single(t => t.Key == "client.afterreceivereply").Value); - } + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.OperationName); + Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); + Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); + Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerNameTag).Value); + Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerPortTag).Value); + Assert.Equal("http", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); + Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); + if (includeVersion) + { + Assert.Equal("Soap11 (http://schemas.xmlsoap.org/soap/envelope/) AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); } - else + + if (enrich && !enrichmentException) { - Assert.Empty(stoppedActivities); + Assert.Equal(WcfEnrichEventNames.BeforeSendRequest, activity.TagObjects.Single(t => t.Key == "client.beforesendrequest").Value); + Assert.Equal(WcfEnrichEventNames.AfterReceiveReply, activity.TagObjects.Single(t => t.Key == "client.afterreceivereply").Value); } } + else + { + Assert.Empty(stoppedActivities); + } } - else - { - Assert.Empty(stoppedActivities); - } + } + else + { + Assert.Empty(stoppedActivities); } } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index 127173852e..8dd1ec1bb9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + #if NETFRAMEWORK using System; using System.Collections.Generic; @@ -25,134 +26,134 @@ using Xunit; using Xunit.Abstractions; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[Collection("WCF")] +public class TelemetryDispatchMessageInspectorForOneWayOperationsTests : IDisposable { - [Collection("WCF")] - public class TelemetryDispatchMessageInspectorForOneWayOperationsTests : IDisposable - { - private readonly ITestOutputHelper output; - private readonly Uri serviceBaseUri; - private readonly ServiceHost serviceHost; + private readonly ITestOutputHelper output; + private readonly Uri serviceBaseUri; + private readonly ServiceHost serviceHost; - private readonly EventWaitHandle thrownExceptionsHandle = new EventWaitHandle(false, EventResetMode.ManualReset); - private readonly List thrownExceptions = new List(); + private readonly EventWaitHandle thrownExceptionsHandle = new EventWaitHandle(false, EventResetMode.ManualReset); + private readonly List thrownExceptions = new List(); - public TelemetryDispatchMessageInspectorForOneWayOperationsTests(ITestOutputHelper outputHelper) - { - this.output = outputHelper; + public TelemetryDispatchMessageInspectorForOneWayOperationsTests(ITestOutputHelper outputHelper) + { + this.output = outputHelper; - Random random = new Random(); - var retryCount = 5; - while (retryCount > 0) + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) + { + try { - try - { - this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); - this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); + this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); + this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); - var endpoint = this.serviceHost.AddServiceEndpoint( - typeof(IServiceContract), - new NetTcpBinding(), - "/Service"); - endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); + var endpoint = this.serviceHost.AddServiceEndpoint( + typeof(IServiceContract), + new NetTcpBinding(), + "/Service"); + endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); - this.serviceHost.Description.Behaviors.Add( - new ErrorHandlerServiceBehavior(this.thrownExceptionsHandle, ex => this.thrownExceptions.Add(ex))); + this.serviceHost.Description.Behaviors.Add( + new ErrorHandlerServiceBehavior(this.thrownExceptionsHandle, ex => this.thrownExceptions.Add(ex))); - this.serviceHost.Open(); + this.serviceHost.Open(); - break; + break; + } + catch (Exception ex) + { + this.output.WriteLine(ex.ToString()); + if (this.serviceHost.State == CommunicationState.Faulted) + { + this.serviceHost.Abort(); } - catch (Exception ex) + else { - this.output.WriteLine(ex.ToString()); - if (this.serviceHost.State == CommunicationState.Faulted) - { - this.serviceHost.Abort(); - } - else - { - this.serviceHost.Close(); - } - - this.serviceHost = null; - retryCount--; + this.serviceHost.Close(); } - } - if (this.serviceHost == null) - { - throw new InvalidOperationException("ServiceHost could not be started."); + this.serviceHost = null; + retryCount--; } } - public void Dispose() + if (this.serviceHost == null) { - this.serviceHost?.Close(); - this.thrownExceptionsHandle?.Dispose(); + throw new InvalidOperationException("ServiceHost could not be started."); } + } - [Fact] - public void IncomingRequestOneWayOperationInstrumentationTest() - { - List stoppedActivities = new List(); + public void Dispose() + { + this.serviceHost?.Close(); + this.thrownExceptionsHandle?.Dispose(); + } - using ActivityListener activityListener = new ActivityListener - { - ShouldListenTo = activitySource => true, - ActivityStopped = activity => stoppedActivities.Add(activity), - }; + [Fact] + public void IncomingRequestOneWayOperationInstrumentationTest() + { + List stoppedActivities = new List(); - ActivitySource.AddActivityListener(activityListener); - TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddWcfInstrumentation() - .Build(); + using ActivityListener activityListener = new ActivityListener + { + ShouldListenTo = activitySource => true, + ActivityStopped = activity => stoppedActivities.Add(activity), + }; - ServiceClient client = new ServiceClient( - new NetTcpBinding(), - new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + ActivitySource.AddActivityListener(activityListener); + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddWcfInstrumentation() + .Build(); - try + ServiceClient client = new ServiceClient( + new NetTcpBinding(), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + + try + { + client.ExecuteWithOneWay(new ServiceRequest()); + this.thrownExceptionsHandle.WaitOne(3000); + } + finally + { + if (client.State == CommunicationState.Faulted) { - client.ExecuteWithOneWay(new ServiceRequest()); - this.thrownExceptionsHandle.WaitOne(3000); + client.Abort(); } - finally + else { - if (client.State == CommunicationState.Faulted) - { - client.Abort(); - } - else - { - client.Close(); - } + client.Close(); + } - tracerProvider?.Shutdown(); - tracerProvider?.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); - WcfInstrumentationActivitySource.Options = null; - } + WcfInstrumentationActivitySource.Options = null; + } - // Assert - Assert.Empty(this.thrownExceptions); + // Assert + Assert.Empty(this.thrownExceptions); - Assert.NotEmpty(stoppedActivities); - Assert.Single(stoppedActivities); + Assert.NotEmpty(stoppedActivities); + Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; - Assert.Equal("http://opentelemetry.io/Service/ExecuteWithOneWay", activity.DisplayName); - Assert.Equal("ExecuteWithOneWay", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); - Assert.DoesNotContain(activity.TagObjects, t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag); + Activity activity = stoppedActivities[0]; + Assert.Equal("http://opentelemetry.io/Service/ExecuteWithOneWay", activity.DisplayName); + Assert.Equal("ExecuteWithOneWay", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + Assert.DoesNotContain(activity.TagObjects, t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag); - Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); - Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); - Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); - Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); - Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); - Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); - } + Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); + Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); + Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); + Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); + Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); + Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); + Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); } } + #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index a8e6b58a15..c6776c9f82 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + #if NETFRAMEWORK using System; using System.Collections.Generic; @@ -25,217 +26,217 @@ using Xunit; using Xunit.Abstractions; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[Collection("WCF")] +public class TelemetryDispatchMessageInspectorTests : IDisposable { - [Collection("WCF")] - public class TelemetryDispatchMessageInspectorTests : IDisposable + private readonly ITestOutputHelper output; + private readonly Uri serviceBaseUri; + private readonly ServiceHost serviceHost; + + public TelemetryDispatchMessageInspectorTests(ITestOutputHelper outputHelper) { - private readonly ITestOutputHelper output; - private readonly Uri serviceBaseUri; - private readonly ServiceHost serviceHost; + this.output = outputHelper; - public TelemetryDispatchMessageInspectorTests(ITestOutputHelper outputHelper) + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) { - this.output = outputHelper; - - Random random = new Random(); - var retryCount = 5; - while (retryCount > 0) + try { - try + this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); + this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); + var endpoint = this.serviceHost.AddServiceEndpoint( + typeof(IServiceContract), + new NetTcpBinding(), + "/Service"); + endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); + this.serviceHost.Open(); + break; + } + catch (Exception ex) + { + this.output.WriteLine(ex.ToString()); + if (this.serviceHost.State == CommunicationState.Faulted) { - this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); - this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); - var endpoint = this.serviceHost.AddServiceEndpoint( - typeof(IServiceContract), - new NetTcpBinding(), - "/Service"); - endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); - this.serviceHost.Open(); - break; + this.serviceHost.Abort(); } - catch (Exception ex) + else { - this.output.WriteLine(ex.ToString()); - if (this.serviceHost.State == CommunicationState.Faulted) - { - this.serviceHost.Abort(); - } - else - { - this.serviceHost.Close(); - } - - this.serviceHost = null; - retryCount--; + this.serviceHost.Close(); } - } - if (this.serviceHost == null) - { - throw new InvalidOperationException("ServiceHost could not be started."); + this.serviceHost = null; + retryCount--; } } - public void Dispose() + if (this.serviceHost == null) { - this.serviceHost?.Close(); + throw new InvalidOperationException("ServiceHost could not be started."); } + } - [Theory] - [InlineData(true, false)] - [InlineData(true, true)] - [InlineData(false)] - [InlineData(true, false, true)] - [InlineData(true, false, true, true)] - [InlineData(true, false, true, true, true)] - [InlineData(true, false, true, true, true, true)] - public async Task IncomingRequestInstrumentationTest( - bool instrument, - bool filter = false, - bool includeVersion = false, - bool enrich = false, - bool enrichmentExcecption = false, - bool emptyOrNullAction = false) - { - List stoppedActivities = new List(); + public void Dispose() + { + this.serviceHost?.Close(); + } - using ActivityListener activityListener = new ActivityListener - { - ShouldListenTo = activitySource => true, - ActivityStopped = activity => stoppedActivities.Add(activity), - }; + [Theory] + [InlineData(true, false)] + [InlineData(true, true)] + [InlineData(false)] + [InlineData(true, false, true)] + [InlineData(true, false, true, true)] + [InlineData(true, false, true, true, true)] + [InlineData(true, false, true, true, true, true)] + public async Task IncomingRequestInstrumentationTest( + bool instrument, + bool filter = false, + bool includeVersion = false, + bool enrich = false, + bool enrichmentExcecption = false, + bool emptyOrNullAction = false) + { + List stoppedActivities = new List(); - ActivitySource.AddActivityListener(activityListener); + using ActivityListener activityListener = new ActivityListener + { + ShouldListenTo = activitySource => true, + ActivityStopped = activity => stoppedActivities.Add(activity), + }; - TracerProvider tracerProvider = null; - if (instrument) - { - tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddWcfInstrumentation(options => + ActivitySource.AddActivityListener(activityListener); + + TracerProvider tracerProvider = null; + if (instrument) + { + tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddWcfInstrumentation(options => + { + if (enrich) { - if (enrich) + if (!enrichmentExcecption) { - if (!enrichmentExcecption) + options.Enrich = (activity, eventName, message) => { - options.Enrich = (activity, eventName, message) => + switch (eventName) { - switch (eventName) - { - case WcfEnrichEventNames.AfterReceiveRequest: - activity.SetTag( - "server.afterreceiverequest", - WcfEnrichEventNames.AfterReceiveRequest); - break; - case WcfEnrichEventNames.BeforeSendReply: - activity.SetTag( - "server.beforesendreply", - WcfEnrichEventNames.BeforeSendReply); - break; - } - }; - } - else + case WcfEnrichEventNames.AfterReceiveRequest: + activity.SetTag( + "server.afterreceiverequest", + WcfEnrichEventNames.AfterReceiveRequest); + break; + case WcfEnrichEventNames.BeforeSendReply: + activity.SetTag( + "server.beforesendreply", + WcfEnrichEventNames.BeforeSendReply); + break; + } + }; + } + else + { + options.Enrich = (activity, eventName, message) => { - options.Enrich = (activity, eventName, message) => - { - throw new Exception("Failure whilst enriching activity"); - }; - } + throw new Exception("Failure whilst enriching activity"); + }; } + } - options.IncomingRequestFilter = (Message m) => - { - return !filter; - }; - options.SetSoapMessageVersion = includeVersion; - }) - .Build(); - } + options.IncomingRequestFilter = (Message m) => + { + return !filter; + }; + options.SetSoapMessageVersion = includeVersion; + }) + .Build(); + } - ServiceClient client = new ServiceClient( - new NetTcpBinding(), - new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); - try + ServiceClient client = new ServiceClient( + new NetTcpBinding(), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + if (emptyOrNullAction) { - if (emptyOrNullAction) - { - await client.ExecuteWithEmptyActionNameAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); - } - else - { - await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); - } + await client.ExecuteWithEmptyActionNameAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); } - finally + else { - if (client.State == CommunicationState.Faulted) - { - client.Abort(); - } - else - { - client.Close(); - } - - tracerProvider?.Shutdown(); - tracerProvider?.Dispose(); - - WcfInstrumentationActivitySource.Options = null; + await client.ExecuteAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); } - - if (instrument && !filter) + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else { - Assert.NotEmpty(stoppedActivities); - Assert.Single(stoppedActivities); + client.Close(); + } - Activity activity = stoppedActivities[0]; + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); - if (emptyOrNullAction) - { - Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.DisplayName); - Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); - Assert.Equal("http://opentelemetry.io/Service/ExecuteWithEmptyActionNameResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); - } - else - { - Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); - Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); - Assert.Equal("http://opentelemetry.io/Service/ExecuteResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); - } + WcfInstrumentationActivitySource.Options = null; + } - Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); - Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); - Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); - Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); - Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); - Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); + if (instrument && !filter) + { + Assert.NotEmpty(stoppedActivities); + Assert.Single(stoppedActivities); - if (includeVersion) - { - Assert.Equal("Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); - } + Activity activity = stoppedActivities[0]; - if (enrich && !enrichmentExcecption) - { - Assert.Equal(WcfEnrichEventNames.AfterReceiveRequest, activity.TagObjects.Single(t => t.Key == "server.afterreceiverequest").Value); - Assert.Equal(WcfEnrichEventNames.BeforeSendReply, activity.TagObjects.Single(t => t.Key == "server.beforesendreply").Value); - } + if (emptyOrNullAction) + { + Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.DisplayName); + Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + Assert.Equal("http://opentelemetry.io/Service/ExecuteWithEmptyActionNameResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); } else { - Assert.Empty(stoppedActivities); + Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); + Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + Assert.Equal("http://opentelemetry.io/Service/ExecuteResponse", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag).Value); + } + + Assert.Equal(WcfInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); + Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); + Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); + Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostNameTag).Value); + Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetHostPortTag).Value); + Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); + Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); + + if (includeVersion) + { + Assert.Equal("Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); + } + + if (enrich && !enrichmentExcecption) + { + Assert.Equal(WcfEnrichEventNames.AfterReceiveRequest, activity.TagObjects.Single(t => t.Key == "server.afterreceiverequest").Value); + Assert.Equal(WcfEnrichEventNames.BeforeSendReply, activity.TagObjects.Single(t => t.Key == "server.beforesendreply").Value); } } + else + { + Assert.Empty(stoppedActivities); + } } } + #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs index bc6f065e7b..afe5f9e201 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs @@ -13,36 +13,37 @@ // See the License for the specific language governing permissions and // limitations under the License. // + #if NETFRAMEWORK using System; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using System.Threading; -namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +internal class ErrorHandler : IErrorHandler { - internal class ErrorHandler : IErrorHandler + private readonly EventWaitHandle handle; + private readonly Action log; + + public ErrorHandler(EventWaitHandle handle, Action log) + { + this.handle = handle; + this.log = log; + } + + public bool HandleError(Exception error) + { + this.log(error); + this.handle.Set(); + + return true; + } + + public void ProvideFault(Exception error, MessageVersion version, ref Message fault) { - private readonly EventWaitHandle handle; - private readonly Action log; - - public ErrorHandler(EventWaitHandle handle, Action log) - { - this.handle = handle; - this.log = log; - } - - public bool HandleError(Exception error) - { - this.log(error); - this.handle.Set(); - - return true; - } - - public void ProvideFault(Exception error, MessageVersion version, ref Message fault) - { - } } } + #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs index 6332d79162..85af0db661 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + #if NETFRAMEWORK using System; using System.Collections.ObjectModel; @@ -22,34 +23,34 @@ using System.ServiceModel.Dispatcher; using System.Threading; -namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +internal class ErrorHandlerServiceBehavior : IServiceBehavior { - internal class ErrorHandlerServiceBehavior : IServiceBehavior - { - private readonly EventWaitHandle handle; - private readonly Action action; + private readonly EventWaitHandle handle; + private readonly Action action; - public ErrorHandlerServiceBehavior(EventWaitHandle handle, Action action) - { - this.handle = handle; - this.action = action; - } + public ErrorHandlerServiceBehavior(EventWaitHandle handle, Action action) + { + this.handle = handle; + this.action = action; + } - public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) - { - } + public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) + { + } - public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) { - foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) - { - dispatcher.ErrorHandlers.Add(new ErrorHandler(this.handle, this.action)); - } + dispatcher.ErrorHandlers.Add(new ErrorHandler(this.handle, this.action)); } + } - public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) - { - } + public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { } } + #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 92abafbe02..5dbee33438 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -17,18 +17,17 @@ using System.ServiceModel; using System.Threading.Tasks; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[ServiceContract(Namespace = "http://opentelemetry.io/", Name = "Service", SessionMode = SessionMode.Allowed)] +public interface IServiceContract { - [ServiceContract(Namespace = "http://opentelemetry.io/", Name = "Service", SessionMode = SessionMode.Allowed)] - public interface IServiceContract - { - [OperationContract] - Task ExecuteAsync(ServiceRequest request); + [OperationContract] + Task ExecuteAsync(ServiceRequest request); - [OperationContract(Action = "")] - Task ExecuteWithEmptyActionNameAsync(ServiceRequest request); + [OperationContract(Action = "")] + Task ExecuteWithEmptyActionNameAsync(ServiceRequest request); - [OperationContract(IsOneWay = true)] - void ExecuteWithOneWay(ServiceRequest request); - } + [OperationContract(IsOneWay = true)] + void ExecuteWithOneWay(ServiceRequest request); } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index d172ae8ec9..3cecbe1cb9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -13,41 +13,42 @@ // See the License for the specific language governing permissions and // limitations under the License. // + #if NETFRAMEWORK using System.ServiceModel; using System.Threading.Tasks; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[ServiceBehavior( + Namespace = "http://opentelemetry.io/", + ConcurrencyMode = ConcurrencyMode.Multiple, + InstanceContextMode = InstanceContextMode.Single, + UseSynchronizationContext = false, + Name = "Service")] +public class Service : IServiceContract { - [ServiceBehavior( - Namespace = "http://opentelemetry.io/", - ConcurrencyMode = ConcurrencyMode.Multiple, - InstanceContextMode = InstanceContextMode.Single, - UseSynchronizationContext = false, - Name = "Service")] - public class Service : IServiceContract + public Task ExecuteAsync(ServiceRequest request) { - public Task ExecuteAsync(ServiceRequest request) - { - return Task.FromResult( - new ServiceResponse - { - Payload = $"RSP: {request.Payload}", - }); - } + return Task.FromResult( + new ServiceResponse + { + Payload = $"RSP: {request.Payload}", + }); + } - public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) - { - return Task.FromResult( - new ServiceResponse - { - Payload = $"RSP: {request.Payload}", - }); - } + public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) + { + return Task.FromResult( + new ServiceResponse + { + Payload = $"RSP: {request.Payload}", + }); + } - public void ExecuteWithOneWay(ServiceRequest request) - { - } + public void ExecuteWithOneWay(ServiceRequest request) + { } } + #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index 353cd624de..7381b135fc 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -18,22 +18,21 @@ using System.ServiceModel.Channels; using System.Threading.Tasks; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +public class ServiceClient : ClientBase, IServiceContract { - public class ServiceClient : ClientBase, IServiceContract + public ServiceClient(Binding binding, EndpointAddress remoteAddress) + : base(binding, remoteAddress) { - public ServiceClient(Binding binding, EndpointAddress remoteAddress) - : base(binding, remoteAddress) - { - } + } - public Task ExecuteAsync(ServiceRequest request) - => this.Channel.ExecuteAsync(request); + public Task ExecuteAsync(ServiceRequest request) + => this.Channel.ExecuteAsync(request); - public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) - => this.Channel.ExecuteWithEmptyActionNameAsync(request); + public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) + => this.Channel.ExecuteWithEmptyActionNameAsync(request); - public void ExecuteWithOneWay(ServiceRequest request) - => this.Channel.ExecuteWithOneWay(request); - } + public void ExecuteWithOneWay(ServiceRequest request) + => this.Channel.ExecuteWithOneWay(request); } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index 60da5eca97..6e7ffcb3b6 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -16,12 +16,11 @@ using System.Runtime.Serialization; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[DataContract] +public class ServiceRequest { - [DataContract] - public class ServiceRequest - { - [DataMember] - public string Payload { get; set; } - } + [DataMember] + public string Payload { get; set; } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index e8856e2847..b076c64f7a 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -16,12 +16,11 @@ using System.Runtime.Serialization; -namespace OpenTelemetry.Instrumentation.Wcf.Tests +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[DataContract] +public class ServiceResponse { - [DataContract] - public class ServiceResponse - { - [DataMember] - public string Payload { get; set; } - } + [DataMember] + public string Payload { get; set; } } From ba73fd8b70c10c66cf9b0e89b5213cf1fbd7ff0c Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Fri, 5 Aug 2022 19:52:52 +0200 Subject: [PATCH 0272/1499] AWS Lambda wrapper enhancements: Trace methods enhancements and Activity creation behaviour changes. (#408) --- .../AWSLambdaInstrumentationOptions.cs | 29 ++ .../CHANGELOG.md | 17 ++ .../AWSLambdaSemanticConventions.cs | 1 + .../Implementation/AWSLambdaUtils.cs | 118 +++++++- .../Implementation/AWSLambdaWrapper.cs | 284 +++++++++--------- ...y.Contrib.Instrumentation.AWSLambda.csproj | 1 + .../TracerProviderBuilderExtensions.cs | 12 +- .../AWSLambdaWrapperTests.cs | 169 ++++++----- .../SampleHandlers.cs | 29 +- 9 files changed, 421 insertions(+), 239 deletions(-) create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs new file mode 100644 index 0000000000..2c3b101380 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda +{ + /// + /// AWS lambda instrumentation options. + /// + public class AWSLambdaInstrumentationOptions + { + /// + /// Gets or sets a value indicating whether AWS X-Ray context extraction should be disabled. + /// + public bool DisableAwsXRayContextExtraction { get; set; } + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md index 8928f2bfc5..61ade2e4b0 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog - OpenTelemetry.Contrib.Instrumentation.AWSLambda +## Unreleased + +* Added public option `AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction`. +* Extended public API of the `AWSLambdaWrapper`: added optional parent + context (`ActivityContext`) to all `Trace` methods. +* Enhanced parent extraction: if the parent context is not provided + then it can be extracted from the incoming request for certain types of the request. + If the parent is not extracted from the incoming request then it can be extracted + from the AWS X-Ray tracing header if AWS X-Ray context extraction + is not disabled (`DisableAwsXRayContextExtraction`). +* Changed behaviour of the `OnFunctionStart` method: Activity is created even + if the parent context is not defined. +* Breaking change: `AWSLambdaWrapper.Trace` overloads without `ILambdaContext` argument + have been completely removed. +* Added two new `AWSLambdaWrapper.Trace` overloads without generic input arguments. + ([#408](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/408)) + ## 1.1.0-beta1 Released 2021-May-26 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs index 4a174094cd..a3fcdb6977 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs @@ -28,5 +28,6 @@ internal static class AWSLambdaSemanticConventions public const string AttributeFaasID = "faas.id"; public const string AttributeFaasName = "faas.name"; public const string AttributeFaasVersion = "faas.version"; + public const string AttributeFaasTrigger = "faas.trigger"; } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 1e859dcaee..f387ec69a5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -17,7 +17,10 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; +using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.Core; +using OpenTelemetry.Context.Propagation; using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation @@ -45,7 +48,7 @@ internal static class AWSLambdaUtils return new string[0]; }; - internal static ActivityContext GetParentContext() + internal static ActivityContext GetXRayParentContext() { // Currently get trace header from Lambda runtime environment variable // https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime @@ -61,6 +64,22 @@ internal static ActivityContext GetParentContext() return activityContext; } + internal static ActivityContext ExtractParentContext(TInput input) + { + PropagationContext propagationContext = default; + switch (input) + { + case APIGatewayProxyRequest apiGatewayProxyRequest: + propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayProxyRequest, GetHeaderValues); + break; + case APIGatewayHttpApiV2ProxyRequest apiGatewayHttpApiV2ProxyRequest: + propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayHttpApiV2ProxyRequest, GetHeaderValues); + break; + } + + return propagationContext.ActivityContext; + } + internal static string GetCloudProvider() { return CloudProvider; @@ -73,12 +92,7 @@ internal static string GetAWSRegion() internal static string GetFunctionName(ILambdaContext context = null) { - if (context != null) - { - return context.FunctionName; - } - - return Environment.GetEnvironmentVariable(FunctionName); + return context?.FunctionName ?? Environment.GetEnvironmentVariable(FunctionName); } internal static string GetFunctionVersion() @@ -86,7 +100,45 @@ internal static string GetFunctionVersion() return Environment.GetEnvironmentVariable(FunctionVersion); } - internal static string GetAccountId(string functionArn) + internal static IEnumerable> GetFunctionTags(TInput input, ILambdaContext context) + { + var tags = new List> + { + new(AWSLambdaSemanticConventions.AttributeFaasTrigger, GetFaasTrigger(input)), + }; + + var functionName = GetFunctionName(context); + if (functionName != null) + { + tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasName, functionName)); + } + + if (context == null) + { + return tags; + } + + if (context.AwsRequestId != null) + { + tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasExecution, context.AwsRequestId)); + } + + var functionArn = context.InvokedFunctionArn; + if (functionArn != null) + { + tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasID, GetFaasId(functionArn))); + + var accountId = GetAccountId(functionArn); + if (accountId != null) + { + tags.Add(new(AWSLambdaSemanticConventions.AttributeCloudAccountID, accountId)); + } + } + + return tags; + } + + private static string GetAccountId(string functionArn) { // The fifth item of function arn: https://github.com/open-telemetry/opentelemetry-specification/blob/86aeab1e0a7e6c67be09c7f15ff25063ee6d2b5c/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers // Function arn format - arn:aws:lambda:::function: @@ -100,6 +152,33 @@ internal static string GetAccountId(string functionArn) return null; } + private static string GetFaasId(string functionArn) + { + var faasId = functionArn; + + // According to faas.id description https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers + // the 8th part of arn (function version or alias, see https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html) + // should not be included into faas.id + var items = functionArn.Split(':'); + if (items.Length >= 8) + { + faasId = string.Join(":", items.Take(7)); + } + + return faasId; + } + + private static string GetFaasTrigger(TInput input) + { + var trigger = "other"; + if (input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest) + { + trigger = "http"; + } + + return trigger; + } + private static ActivityContext ParseXRayTraceHeader(string rawHeader) { var xrayPropagator = new AWSXRayPropagator(); @@ -112,5 +191,28 @@ private static ActivityContext ParseXRayTraceHeader(string rawHeader) var propagationContext = xrayPropagator.Extract(default, carrier, Getter); return propagationContext.ActivityContext; } + + private static IEnumerable GetHeaderValues(APIGatewayProxyRequest request, string name) + { + if (request.MultiValueHeaders != null && + request.MultiValueHeaders.TryGetValue(name, out var values)) + { + return values; + } + + return null; + } + + private static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) + { + if (request.Headers != null && + request.Headers.TryGetValue(name, out var header)) + { + // Multiple values for the same header will be separated by a comma. + return header?.Split(','); + } + + return null; + } } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs index cab174c835..4ca66e3c7a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs @@ -27,63 +27,95 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation /// public class AWSLambdaWrapper { - private static readonly ActivitySource AWSLambdaActivitySource = new ActivitySource(AWSLambdaUtils.ActivitySourceName); + private static readonly ActivitySource AWSLambdaActivitySource = new(AWSLambdaUtils.ActivitySourceName); /// - /// Tracing wrapper for Lambda handler without Lambda context. + /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. /// - /// Input. - /// Output result. - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of input. - /// Instance of output result. - public static TResult Trace(TracerProvider tracerProvider, Func lambdaHandler, TInput input) - { - return Intercept(tracerProvider, () => lambdaHandler(input)); - } + internal static bool DisableAwsXRayContextExtraction { get; set; } /// - /// Tracing wrapper for Lambda handler without Lambda context. + /// Tracing wrapper for Lambda handler. /// /// Input. + /// Output result. /// TracerProvider passed in. /// Lambda handler function passed in. /// Instance of input. - public static void Trace(TracerProvider tracerProvider, Action lambdaHandler, TInput input) + /// Instance of lambda context. + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + /// Instance of output result. + public static TResult Trace( + TracerProvider tracerProvider, + Func lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) { - Intercept(tracerProvider, () => lambdaHandler(input)); + TResult result = default; + Action action = () => result = lambdaHandler(input, context); + TraceInternal(tracerProvider, action, input, context, parentContext); + return result; } /// - /// Tracing wrapper for async Lambda handler without Lambda context. + /// Tracing wrapper for Lambda handler. /// /// Input. /// TracerProvider passed in. /// Lambda handler function passed in. /// Instance of input. - /// Task. - public static async Task Trace(TracerProvider tracerProvider, Func lambdaHandler, TInput input) + /// Instance of lambda context. + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + public static void Trace( + TracerProvider tracerProvider, + Action lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) { - await Intercept(tracerProvider, () => lambdaHandler(input)); + Action action = () => lambdaHandler(input, context); + TraceInternal(tracerProvider, action, input, context, parentContext); } /// - /// Tracing wrapper for async Lambda handler without Lambda context. + /// Tracing wrapper for async Lambda handler. /// /// Input. - /// Output result. /// TracerProvider passed in. /// Lambda handler function passed in. /// Instance of input. - /// Task of result. - public static async Task Trace(TracerProvider tracerProvider, Func> lambdaHandler, TInput input) + /// Lambda context (optional, but strongly recommended). + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + /// Task. + public static Task Trace( + TracerProvider tracerProvider, + Func lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) { - return await Intercept(tracerProvider, () => lambdaHandler(input)); + Func action = async () => await lambdaHandler(input, context); + return TraceInternalAsync(tracerProvider, action, input, context, parentContext); } /// - /// Tracing wrapper for Lambda handler. + /// Tracing wrapper for async Lambda handler. /// /// Input. /// Output result. @@ -91,98 +123,123 @@ public static async Task Trace(TracerProvider tracerPr /// Lambda handler function passed in. /// Instance of input. /// Instance of lambda context. - /// Instance of output result. - public static TResult Trace(TracerProvider tracerProvider, Func lambdaHandler, TInput input, ILambdaContext context) + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + /// Task of result. + public static async Task Trace( + TracerProvider tracerProvider, + Func> lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) { - return Intercept(tracerProvider, () => lambdaHandler(input, context), context); + TResult result = default; + Func action = async () => result = await lambdaHandler(input, context); + await TraceInternalAsync(tracerProvider, action, input, context, parentContext); + return result; } /// /// Tracing wrapper for Lambda handler. /// - /// Input. /// TracerProvider passed in. /// Lambda handler function passed in. - /// Instance of input. /// Instance of lambda context. - public static void Trace(TracerProvider tracerProvider, Action lambdaHandler, TInput input, ILambdaContext context) + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + public static void Trace( + TracerProvider tracerProvider, + Action lambdaHandler, + ILambdaContext context, + ActivityContext parentContext = default) { - Intercept(tracerProvider, () => lambdaHandler(input, context), context); + Action action = () => lambdaHandler(context); + TraceInternal(tracerProvider, action, null, context, parentContext); } /// /// Tracing wrapper for async Lambda handler. /// - /// Input. /// TracerProvider passed in. /// Lambda handler function passed in. - /// Instance of input. /// Instance of lambda context. + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration. + /// /// Task. - public static async Task Trace(TracerProvider tracerProvider, Func lambdaHandler, TInput input, ILambdaContext context) - { - await Intercept(tracerProvider, () => lambdaHandler(input, context), context); - } - - /// - /// Tracing wrapper for async Lambda handler. - /// - /// Input. - /// Output result. - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of input. - /// Instance of lambda context. - /// Task of result. - public static async Task Trace(TracerProvider tracerProvider, Func> lambdaHandler, TInput input, ILambdaContext context) + public static Task Trace( + TracerProvider tracerProvider, + Func lambdaHandler, + ILambdaContext context, + ActivityContext parentContext = default) { - return await Intercept(tracerProvider, () => lambdaHandler(input, context), context); + Func action = async () => await lambdaHandler(context); + return TraceInternalAsync(tracerProvider, action, null, context, parentContext); } - private static TResult Intercept(TracerProvider tracerProvider, Func method, ILambdaContext context = null) + internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) { - var lambdaActivity = OnFunctionStart(context); - try + if (parentContext == default) { - return method(); + parentContext = AWSLambdaUtils.ExtractParentContext(input); + if (parentContext == default && !DisableAwsXRayContextExtraction) + { + parentContext = AWSLambdaUtils.GetXRayParentContext(); + } } - catch (Exception ex) - { - OnException(lambdaActivity, ex); - throw; - } - finally - { - OnFunctionStop(lambdaActivity, tracerProvider); - } + var tags = AWSLambdaUtils.GetFunctionTags(input, context); + var activityName = AWSLambdaUtils.GetFunctionName(context) ?? "AWS Lambda Invoke"; + var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, tags); + + return activity; } - private static void Intercept(TracerProvider tracerProvider, Action method, ILambdaContext context = null) + private static void OnFunctionStop(Activity activity, TracerProvider tracerProvider) { - var lambdaActivity = OnFunctionStart(context); - try + if (activity != null) { - method(); + activity.Stop(); } - catch (Exception ex) - { - OnException(lambdaActivity, ex); - throw; - } - finally + // force flush before function quit in case of Lambda freeze. + tracerProvider?.ForceFlush(); + } + + private static void OnException(Activity activity, Exception exception) + { + if (activity != null) { - OnFunctionStop(lambdaActivity, tracerProvider); + if (activity.IsAllDataRequested) + { + activity.RecordException(exception); + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + } } } - private static async Task Intercept(TracerProvider tracerProvider, Func> method, ILambdaContext context = null) + private static void TraceInternal( + TracerProvider tracerProvider, + Action handler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) { - var lambdaActivity = OnFunctionStart(context); + var lambdaActivity = OnFunctionStart(input, context, parentContext); try { - return await method(); + handler(); } catch (Exception ex) { @@ -196,12 +253,17 @@ private static async Task Intercept(TracerProvider tracerProvi } } - private static async Task Intercept(TracerProvider tracerProvider, Func method, ILambdaContext context = null) + private static async Task TraceInternalAsync( + TracerProvider tracerProvider, + Func handlerAsync, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) { - var lambdaActivity = OnFunctionStart(context); + var lambdaActivity = OnFunctionStart(input, context, parentContext); try { - await method(); + await handlerAsync(); } catch (Exception ex) { @@ -214,65 +276,5 @@ private static async Task Intercept(TracerProvider tracerProvider, Func me OnFunctionStop(lambdaActivity, tracerProvider); } } - - private static Activity OnFunctionStart(ILambdaContext context = null) - { - Activity activity = null; - - var parentContext = AWSLambdaUtils.GetParentContext(); - if (parentContext != default) - { - var activityName = AWSLambdaUtils.GetFunctionName(context); - activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext); - - if (activity != null && context != null) - { - if (activity.IsAllDataRequested) - { - if (context.AwsRequestId != null) - { - activity.SetTag(AWSLambdaSemanticConventions.AttributeFaasExecution, context.AwsRequestId); - } - - var functionArn = context.InvokedFunctionArn; - if (functionArn != null) - { - activity.SetTag(AWSLambdaSemanticConventions.AttributeFaasID, functionArn); - - var accountId = AWSLambdaUtils.GetAccountId(functionArn); - if (accountId != null) - { - activity.SetTag(AWSLambdaSemanticConventions.AttributeCloudAccountID, accountId); - } - } - } - } - } - - return activity; - } - - private static void OnFunctionStop(Activity activity, TracerProvider tracerProvider) - { - if (activity != null) - { - activity.Stop(); - } - - // force flush before function quit in case of Lambda freeze. - tracerProvider.ForceFlush(); - } - - private static void OnException(Activity activity, Exception exception) - { - if (activity != null) - { - if (activity.IsAllDataRequested) - { - activity.RecordException(exception); - activity.SetStatus(Status.Error.WithDescription(exception.Message)); - } - } - } } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj index a4ed849310..93b001d29b 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj @@ -8,6 +8,7 @@ + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index 7cd573a766..6a984a90e7 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using System; +using OpenTelemetry.Contrib.Instrumentation.AWSLambda; using OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -29,11 +31,19 @@ public static class TracerProviderBuilderExtensions /// Add AWS Lambda configurations. /// /// being configured. + /// AWS lambda instrumentation options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddAWSLambdaConfigurations(this TracerProviderBuilder builder) + public static TracerProviderBuilder AddAWSLambdaConfigurations( + this TracerProviderBuilder builder, + Action configure = null) { Guard.ThrowIfNull(builder); + var options = new AWSLambdaInstrumentationOptions(); + configure?.Invoke(options); + + AWSLambdaWrapper.DisableAwsXRayContextExtraction = options.DisableAwsXRayContextExtraction; + builder.AddSource(AWSLambdaUtils.ActivitySourceName); builder.SetResourceBuilder(ResourceBuilder .CreateEmpty() diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 4971e4d761..724806bac2 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -18,6 +18,7 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using Amazon.Lambda.Core; using Moq; using OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Resources; @@ -28,6 +29,10 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests { public class AWSLambdaWrapperTests { + private const string TraceId = "5759e988bd862e3fe1be46a994272793"; + private const string XRayParentId = "53995c3f42cd8ad8"; + private const string CustomParentId = "11195c3f42cd8222"; + private readonly SampleHandlers sampleHandlers; private readonly SampleLambdaContext sampleLambdaContext; @@ -35,14 +40,16 @@ public AWSLambdaWrapperTests() { this.sampleHandlers = new SampleHandlers(); this.sampleLambdaContext = new SampleLambdaContext(); - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1"); + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=1"); Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); } - [Fact] - public void TestLambdaHandler() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TraceSyncWithInputAndReturn(bool setCustomParent) { var processor = new Mock>(); @@ -51,7 +58,8 @@ public void TestLambdaHandler() .AddProcessor(processor.Object) .Build()) { - var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncReturn, "TestStream", this.sampleLambdaContext); + var parentContext = setCustomParent ? CreateParentContext() : default; + var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -60,12 +68,14 @@ public void TestLambdaHandler() Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } - [Fact] - public void TestLambdaHandlerNoReturn() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TraceSyncWithInputAndNoReturn(bool setCustomParent) { var processor = new Mock>(); @@ -74,7 +84,8 @@ public void TestLambdaHandlerNoReturn() .AddProcessor(processor.Object) .Build()) { - AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoReturn, "TestStream", this.sampleLambdaContext); + var parentContext = setCustomParent ? CreateParentContext() : default; + AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -83,12 +94,14 @@ public void TestLambdaHandlerNoReturn() Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } - [Fact] - public async Task TestLambdaHandlerAsync() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TraceSyncWithNoInputAndNoReturn(bool setCustomParent) { var processor = new Mock>(); @@ -97,7 +110,8 @@ public async Task TestLambdaHandlerAsync() .AddProcessor(processor.Object) .Build()) { - var result = await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncReturn, "TestStream", this.sampleLambdaContext); + var parentContext = setCustomParent ? CreateParentContext() : default; + AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoInputAndNoReturn, this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -106,12 +120,14 @@ public async Task TestLambdaHandlerAsync() Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } - [Fact] - public async Task TestLambdaHandlerAsyncNoReturn() + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) { var processor = new Mock>(); @@ -120,7 +136,8 @@ public async Task TestLambdaHandlerAsyncNoReturn() .AddProcessor(processor.Object) .Build()) { - await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncNoReturn, "TestStream", this.sampleLambdaContext); + var parentContext = setCustomParent ? CreateParentContext() : default; + var result = await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -129,12 +146,14 @@ public async Task TestLambdaHandlerAsyncNoReturn() Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } - [Fact] - public void TestLambdaHandlerNoContext() + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) { var processor = new Mock>(); @@ -143,7 +162,8 @@ public void TestLambdaHandlerNoContext() .AddProcessor(processor.Object) .Build()) { - var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncReturn, "TestStream"); + var parentContext = setCustomParent ? CreateParentContext() : default; + await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -152,11 +172,14 @@ public void TestLambdaHandlerNoContext() Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); } - [Fact] - public void TestLambdaHandlerNoContextNoReturn() + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task TraceAsyncWithNoInputAndNoReturn(bool setCustomParent) { var processor = new Mock>(); @@ -165,7 +188,8 @@ public void TestLambdaHandlerNoContextNoReturn() .AddProcessor(processor.Object) .Build()) { - AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoReturn, "TestStream"); + var parentContext = setCustomParent ? CreateParentContext() : default; + await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncNoInputAndNoReturn, this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -174,11 +198,14 @@ public void TestLambdaHandlerNoContextNoReturn() Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); } - [Fact] - public async Task TestLambdaHandlerAsyncNoContext() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TestLambdaHandlerException(bool setCustomParent) { var processor = new Mock>(); @@ -187,21 +214,32 @@ public async Task TestLambdaHandlerAsyncNoContext() .AddProcessor(processor.Object) .Build()) { - var result = await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncReturn, "TestStream"); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); + try + { + var parentContext = setCustomParent ? CreateParentContext() : default; + AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoReturnException, "TestException", this.sampleLambdaContext, parentContext); + } + catch + { + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); + } } // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose Assert.Equal(6, processor.Invocations.Count); var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); + this.AssertSpanException(activity); } [Fact] - public async Task TestLambdaHandlerAsyncNoContextNoReturn() + public void TestLambdaHandlerNotSampled() { + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0"); + var processor = new Mock>(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -209,76 +247,61 @@ public async Task TestLambdaHandlerAsyncNoContextNoReturn() .AddProcessor(processor.Object) .Build()) { - await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncNoReturn, "TestStream"); + var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + // SetParentProvider -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(4, processor.Invocations.Count); - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.True(activities.Length == 0); } [Fact] - public void TestLambdaHandlerException() + public void OnFunctionStart_NoParent_ActivityCreated() { - var processor = new Mock>(); + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", null); + Activity activity = null; using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) .Build()) { - try - { - AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoReturnException, "TestException", this.sampleLambdaContext); - } - catch - { - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); - - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity); - this.AssertSpanAttributes(activity); - this.AssertSpanException(activity); + Assert.NotNull(activity); } [Fact] - public void TestLambdaHandlerNotSampled() + public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_ActivityCreated() { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0"); - - var processor = new Mock>(); + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=0"); + Activity activity = null; using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) .Build()) { - var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncReturn, "TestStream", this.sampleLambdaContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); } - // SetParentProvider -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(4, processor.Invocations.Count); + Assert.NotNull(activity); + } - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.True(activities.Length == 0); + private static ActivityContext CreateParentContext() + { + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(CustomParentId.AsSpan()); + return new ActivityContext(traceId, parentId, ActivityTraceFlags.Recorded); } - private void AssertSpanProperties(Activity activity) + private void AssertSpanProperties(Activity activity, string parentId) { - Assert.Equal("5759e988bd862e3fe1be46a994272793", activity.TraceId.ToHexString()); - Assert.Equal("53995c3f42cd8ad8", activity.ParentSpanId.ToHexString()); + Assert.Equal(TraceId, activity.TraceId.ToHexString()); + Assert.Equal(parentId, activity.ParentSpanId.ToHexString()); Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); Assert.Equal(ActivityKind.Server, activity.Kind); Assert.Equal("testfunction", activity.DisplayName); @@ -297,6 +320,8 @@ private void AssertSpanAttributes(Activity activity) { Assert.Equal(this.sampleLambdaContext.AwsRequestId, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasExecution)); Assert.Equal(this.sampleLambdaContext.InvokedFunctionArn, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasID)); + Assert.Equal(this.sampleLambdaContext.FunctionName, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasName)); + Assert.Equal("other", activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasTrigger)); Assert.Equal("111111111111", activity.GetTagValue(AWSLambdaSemanticConventions.AttributeCloudAccountID)); } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 30cb26ec45..85e89c4a45 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -22,44 +22,39 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests { public class SampleHandlers { - public void SampleHandlerSyncNoReturn(string str, ILambdaContext context) + // Action + public void SampleHandlerSyncInputAndNoReturn(string str, ILambdaContext context) { } - public void SampleHandlerSyncNoReturn(string str) + // Action + public void SampleHandlerSyncNoInputAndNoReturn(ILambdaContext context) { } - public string SampleHandlerSyncReturn(string str, ILambdaContext context) + // Func + public string SampleHandlerSyncInputAndReturn(string str, ILambdaContext context) { return str; } - public string SampleHandlerSyncReturn(string str) - { - return str; - } - - public async Task SampleHandlerAsyncNoReturn(string str, ILambdaContext context) + // Func + public async Task SampleHandlerAsyncInputAndNoReturn(string str, ILambdaContext context) { await Task.Delay(10); } - public async Task SampleHandlerAsyncNoReturn(string str) - { - await Task.Delay(10); - } - - public async Task SampleHandlerAsyncReturn(string str, ILambdaContext context) + // Func> + public async Task SampleHandlerAsyncInputAndReturn(string str, ILambdaContext context) { await Task.Delay(10); return str; } - public async Task SampleHandlerAsyncReturn(string str) + // Func + public async Task SampleHandlerAsyncNoInputAndNoReturn(ILambdaContext context) { await Task.Delay(10); - return str; } public void SampleHandlerSyncNoReturnException(string str, ILambdaContext context) From aa2751d6ab520493180069b4282f72e4523c47f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 5 Aug 2022 21:44:51 +0200 Subject: [PATCH 0273/1499] [Instrumenation.Quartz] File scoped namespace (#564) --- .../QuartzDiagnosticListener.cs | 183 +++-- .../QuartzInstrumentationEventSource.cs | 57 +- .../Implementation/TagName.cs | 25 +- .../OperationName.cs | 29 +- .../QuartzInstrumentationOptions.cs | 65 +- .../QuartzJobInstrumentation.cs | 41 +- .../TraceProviderBuilderExtensions.cs | 41 +- .../QuartzDiagnosticListenerTests.cs | 697 +++++++++--------- .../TestJob.cs | 31 +- .../TestJobExecutionExceptionJob.cs | 11 +- 10 files changed, 585 insertions(+), 595 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 73e4785389..bb4bc853df 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -22,123 +22,122 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.Quartz.Implementation +namespace OpenTelemetry.Instrumentation.Quartz.Implementation; + +internal sealed class QuartzDiagnosticListener : ListenerHandler { - internal sealed class QuartzDiagnosticListener : ListenerHandler + internal static readonly AssemblyName AssemblyName = typeof(QuartzDiagnosticListener).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly Version Version = AssemblyName.Version; + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal readonly PropertyFetcher JobDetailsPropertyFetcher = new PropertyFetcher("JobDetail"); + + private readonly QuartzInstrumentationOptions options; + + public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions options) + : base(sourceName) { - internal static readonly AssemblyName AssemblyName = typeof(QuartzDiagnosticListener).Assembly.GetName(); - internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); - internal readonly PropertyFetcher JobDetailsPropertyFetcher = new PropertyFetcher("JobDetail"); + Guard.ThrowIfNull(options); - private readonly QuartzInstrumentationOptions options; + this.options = options; + } - public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions options) - : base(sourceName) + public override void OnStartActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) { - Guard.ThrowIfNull(options); + if (!this.options.TracedOperations.Contains(activity.OperationName)) + { + QuartzInstrumentationEventSource.Log.OperationIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; + return; + } - this.options = options; - } + activity.DisplayName = this.GetDisplayName(activity); - public override void OnStartActivity(Activity activity, object payload) - { - if (activity.IsAllDataRequested) + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); + + try { - if (!this.options.TracedOperations.Contains(activity.OperationName)) - { - QuartzInstrumentationEventSource.Log.OperationIsFilteredOut(activity.OperationName); - activity.IsAllDataRequested = false; - return; - } - - activity.DisplayName = this.GetDisplayName(activity); - - ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); - ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); - - try - { - this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); - this.options.Enrich?.Invoke(activity, "OnStartActivity", jobDetails); - } - catch (Exception ex) - { - QuartzInstrumentationEventSource.Log.EnrichmentException(ex); - } + this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); + this.options.Enrich?.Invoke(activity, "OnStartActivity", jobDetails); + } + catch (Exception ex) + { + QuartzInstrumentationEventSource.Log.EnrichmentException(ex); } } + } - public override void OnStopActivity(Activity activity, object payload) + public override void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + try { - try - { - this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); - this.options.Enrich?.Invoke(activity, "OnStopActivity", jobDetails); - } - catch (Exception ex) - { - QuartzInstrumentationEventSource.Log.EnrichmentException(ex); - } + this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); + this.options.Enrich?.Invoke(activity, "OnStopActivity", jobDetails); + } + catch (Exception ex) + { + QuartzInstrumentationEventSource.Log.EnrichmentException(ex); } } + } - public override void OnException(Activity activity, object payload) + public override void OnException(Activity activity, object payload) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + var exc = payload as Exception; + if (exc == null) { - var exc = payload as Exception; - if (exc == null) - { - QuartzInstrumentationEventSource.Log.NullPayload(nameof(QuartzDiagnosticListener), nameof(this.OnStopActivity)); - return; - } - - if (this.options.RecordException) - { - activity.RecordException(exc); - } - - activity.SetStatus(Status.Error.WithDescription(exc.Message)); - - try - { - this.options.Enrich?.Invoke(activity, "OnException", exc); - } - catch (Exception ex) - { - QuartzInstrumentationEventSource.Log.EnrichmentException(ex); - } + QuartzInstrumentationEventSource.Log.NullPayload(nameof(QuartzDiagnosticListener), nameof(this.OnStopActivity)); + return; } - } - private string GetDisplayName(Activity activity) - { - return activity.OperationName switch + if (this.options.RecordException) { - OperationName.Job.Execute => $"execute {this.GetTag(activity.Tags, TagName.JobName)}", - OperationName.Job.Veto => $"veto {this.GetTag(activity.Tags, TagName.JobName)}", - _ => activity.DisplayName, - }; - } + activity.RecordException(exc); + } - private ActivityKind GetActivityKind(Activity activity) - { - return activity.OperationName switch + activity.SetStatus(Status.Error.WithDescription(exc.Message)); + + try { - OperationName.Job.Execute => ActivityKind.Internal, - OperationName.Job.Veto => ActivityKind.Internal, - _ => activity.Kind, - }; + this.options.Enrich?.Invoke(activity, "OnException", exc); + } + catch (Exception ex) + { + QuartzInstrumentationEventSource.Log.EnrichmentException(ex); + } } + } - private string GetTag(IEnumerable> tags, string tagName) + private string GetDisplayName(Activity activity) + { + return activity.OperationName switch { - var tag = tags.SingleOrDefault(kv => kv.Key == tagName); - return tag.Value; - } + OperationName.Job.Execute => $"execute {this.GetTag(activity.Tags, TagName.JobName)}", + OperationName.Job.Veto => $"veto {this.GetTag(activity.Tags, TagName.JobName)}", + _ => activity.DisplayName, + }; + } + + private ActivityKind GetActivityKind(Activity activity) + { + return activity.OperationName switch + { + OperationName.Job.Execute => ActivityKind.Internal, + OperationName.Job.Veto => ActivityKind.Internal, + _ => activity.Kind, + }; + } + + private string GetTag(IEnumerable> tags, string tagName) + { + var tag = tags.SingleOrDefault(kv => kv.Key == tagName); + return tag.Value; } } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs index 1500324444..b3cc2ce6de 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -18,41 +18,40 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.Quartz.Implementation +namespace OpenTelemetry.Instrumentation.Quartz.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-Quartz")] +internal class QuartzInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-Quartz")] - internal class QuartzInstrumentationEventSource : EventSource - { - public static readonly QuartzInstrumentationEventSource Log = new QuartzInstrumentationEventSource(); + public static readonly QuartzInstrumentationEventSource Log = new QuartzInstrumentationEventSource(); - [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] - public void NullPayload(string handlerName, string eventName) - { - this.WriteEvent(1, handlerName, eventName); - } + [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(1, handlerName, eventName); + } - [Event(2, Message = "Request is filtered out.", Level = EventLevel.Verbose)] - public void OperationIsFilteredOut(string eventName) - { - this.WriteEvent(2, eventName); - } + [Event(2, Message = "Request is filtered out.", Level = EventLevel.Verbose)] + public void OperationIsFilteredOut(string eventName) + { + this.WriteEvent(2, eventName); + } - [NonEvent] - public void EnrichmentException(Exception ex) + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.EnrichmentException(ex.ToInvariantString()); - } + this.EnrichmentException(ex.ToInvariantString()); } + } - [Event(3, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] - public void EnrichmentException(string exception) - { - this.WriteEvent(3, exception); - } + [Event(3, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(3, exception); } } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs index f0eb7f41d5..f42440a46d 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs @@ -14,18 +14,17 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Quartz.Implementation +namespace OpenTelemetry.Instrumentation.Quartz.Implementation; + +internal static class TagName { - internal static class TagName - { - public const string DefaultListenerName = "Quartz"; - public const string SchedulerName = "scheduler.name"; - public const string SchedulerId = "scheduler.id"; - public const string FireInstanceId = "fire.instance.id"; - public const string TriggerGroup = "trigger.group"; - public const string TriggerName = "trigger.name"; - public const string JobType = "job.type"; - public const string JobGroup = "job.group"; - public const string JobName = "job.name"; - } + public const string DefaultListenerName = "Quartz"; + public const string SchedulerName = "scheduler.name"; + public const string SchedulerId = "scheduler.id"; + public const string FireInstanceId = "fire.instance.id"; + public const string TriggerGroup = "trigger.group"; + public const string TriggerName = "trigger.name"; + public const string JobType = "job.type"; + public const string JobGroup = "job.group"; + public const string JobName = "job.name"; } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs index b5ebd2ab7f..b173e14041 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs @@ -14,27 +14,26 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Quartz +namespace OpenTelemetry.Instrumentation.Quartz; + +/// +/// Quartz diagnostic source operation name constants. +/// +public static class OperationName { /// - /// Quartz diagnostic source operation name constants. + /// Quartz Job category constants. /// - public static class OperationName + public static class Job { /// - /// Quartz Job category constants. + /// Quartz job execute diagnostic source operation name. /// - public static class Job - { - /// - /// Quartz job execute diagnostic source operation name. - /// - public const string Execute = "Quartz.Job.Execute"; + public const string Execute = "Quartz.Job.Execute"; - /// - /// Quartz job veto diagnostic source operation name. - /// - public const string Veto = "Quartz.Job.Veto"; - } + /// + /// Quartz job veto diagnostic source operation name. + /// + public const string Veto = "Quartz.Job.Veto"; } } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index 677b96dd64..9f10410c0b 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -18,44 +18,43 @@ using System.Collections.Generic; using System.Diagnostics; -namespace OpenTelemetry.Instrumentation.Quartz +namespace OpenTelemetry.Instrumentation.Quartz; + +/// +/// Options for . +/// +public class QuartzInstrumentationOptions { /// - /// Options for . + /// Default traced operations. /// - public class QuartzInstrumentationOptions + private static readonly IEnumerable DefaultTracedOperations = new[] { - /// - /// Default traced operations. - /// - private static readonly IEnumerable DefaultTracedOperations = new[] - { - OperationName.Job.Execute, - OperationName.Job.Veto, - }; + OperationName.Job.Execute, + OperationName.Job.Veto, + }; - /// - /// Gets or sets an action to enrich an Activity. - /// - /// - /// : the activity being enriched. - /// string: the name of the event. - /// object: the raw object from which additional information can be extracted to enrich the activity. - /// The type of this object depends on the event, which is given by the above parameter. - /// - public Action Enrich { get; set; } + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// string: the name of the event. + /// object: the raw object from which additional information can be extracted to enrich the activity. + /// The type of this object depends on the event, which is given by the above parameter. + /// + public Action Enrich { get; set; } - /// - /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. - /// - /// - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. - /// - public bool RecordException { get; set; } + /// + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. + /// + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. + /// + public bool RecordException { get; set; } - /// - /// Gets or sets traced operations set. - /// - public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); - } + /// + /// Gets or sets traced operations set. + /// + public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs index cae01b017f..2ab0ca89d6 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs @@ -17,30 +17,29 @@ using System; using OpenTelemetry.Instrumentation.Quartz.Implementation; -namespace OpenTelemetry.Instrumentation.Quartz +namespace OpenTelemetry.Instrumentation.Quartz; + +internal class QuartzJobInstrumentation : IDisposable { - internal class QuartzJobInstrumentation : IDisposable - { - internal const string QuartzDiagnosticListenerName = "Quartz"; - private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + internal const string QuartzDiagnosticListenerName = "Quartz"; + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - public QuartzJobInstrumentation() - : this(new QuartzInstrumentationOptions()) - { - } + public QuartzJobInstrumentation() + : this(new QuartzInstrumentationOptions()) + { + } - public QuartzJobInstrumentation(QuartzInstrumentationOptions options) - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( - name => new QuartzDiagnosticListener(name, options), - listener => listener.Name == QuartzDiagnosticListenerName, - null); - this.diagnosticSourceSubscriber.Subscribe(); - } + public QuartzJobInstrumentation(QuartzInstrumentationOptions options) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( + name => new QuartzDiagnosticListener(name, options), + listener => listener.Name == QuartzDiagnosticListenerName, + null); + this.diagnosticSourceSubscriber.Subscribe(); + } - public void Dispose() - { - this.diagnosticSourceSubscriber?.Dispose(); - } + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index f4e6b2127f..61000e1980 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -19,33 +19,32 @@ using OpenTelemetry.Instrumentation.Quartz.Implementation; // ReSharper disable once CheckNamespace -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TraceProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables the Quartz.NET Job automatic data collection for Quartz.NET. /// - public static class TraceProviderBuilderExtensions + /// being configured. + /// Quartz configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddQuartzInstrumentation( + this TracerProviderBuilder builder, + Action configureQuartzInstrumentationOptions = null) { - /// - /// Enables the Quartz.NET Job automatic data collection for Quartz.NET. - /// - /// being configured. - /// Quartz configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddQuartzInstrumentation( - this TracerProviderBuilder builder, - Action configureQuartzInstrumentationOptions = null) - { - var options = new QuartzInstrumentationOptions(); - configureQuartzInstrumentationOptions?.Invoke(options); + var options = new QuartzInstrumentationOptions(); + configureQuartzInstrumentationOptions?.Invoke(options); - builder.AddInstrumentation(() => new QuartzJobInstrumentation(options)); - builder.AddSource(QuartzDiagnosticListener.ActivitySourceName); + builder.AddInstrumentation(() => new QuartzJobInstrumentation(options)); + builder.AddSource(QuartzDiagnosticListener.ActivitySourceName); - builder.AddLegacySource(OperationName.Job.Execute); - builder.AddLegacySource(OperationName.Job.Veto); + builder.AddLegacySource(OperationName.Job.Execute); + builder.AddLegacySource(OperationName.Job.Veto); - return builder; - } + return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 32ec6ddde2..56fd496a51 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -25,371 +25,370 @@ using Quartz; using Xunit; -namespace OpenTelemetry.Instrumentation.Quartz.Tests +namespace OpenTelemetry.Instrumentation.Quartz.Tests; + +public class QuartzDiagnosticListenerTests { - public class QuartzDiagnosticListenerTests + private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(125); + + public QuartzDiagnosticListenerTests() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + } + + [Fact] + public async Task Should_Create_Activity() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation() + .AddProcessor(activityProcessor.Object) + .Build(); + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + JobDataMap jobDataMap = new JobDataMap { { "A", "B" } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TestTimeout); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Contains("execute ", activity.DisplayName); + Assert.Equal("Quartz.Job.Execute", activity.OperationName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal("Scheduler", activity.Tags.SingleOrDefault(t => t.Key.Equals("scheduler.name")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("job.group")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("trigger.group")).Value); + } + + [Fact] + public async Task Should_Create_Activity_And_Enrich_When_Enrich() { - private static readonly TimeSpan TestTimeout = TimeSpan.FromSeconds(125); - - public QuartzDiagnosticListenerTests() - { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - } - - [Fact] - public async Task Should_Create_Activity() - { - // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); - - var activityProcessor = new Mock>(); - using var tel = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddQuartzInstrumentation() - .AddProcessor(activityProcessor.Object) - .Build(); - var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); - schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); - var scheduler = await schedulerConfig.BuildScheduler(); - - scheduler.Context.Put("BARRIER", barrier); - scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); - await scheduler.Start(); - - JobDataMap jobDataMap = new JobDataMap { { "A", "B" } }; - - var name = Guid.NewGuid().ToString(); - var job = JobBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .UsingJobData(jobDataMap) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .StartNow() - .Build(); - - // Act - await scheduler.ScheduleJob(job, trigger); - - barrier.SignalAndWait(TestTimeout); - - await scheduler.Shutdown(true); - - // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - Assert.Contains("execute ", activity.DisplayName); - Assert.Equal("Quartz.Job.Execute", activity.OperationName); - Assert.Equal(ActivityKind.Internal, activity.Kind); - Assert.Equal("Scheduler", activity.Tags.SingleOrDefault(t => t.Key.Equals("scheduler.name")).Value); - Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("job.group")).Value); - Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("trigger.group")).Value); - } - - [Fact] - public async Task Should_Create_Activity_And_Enrich_When_Enrich() - { - // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); - - var activityProcessor = new Mock>(); - - var jobDataMapPropertyFetcher = new PropertyFetcher("JobDataMap"); - using var tel = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddQuartzInstrumentation(q => - q.Enrich = (a, s, payload) => + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + var jobDataMapPropertyFetcher = new PropertyFetcher("JobDataMap"); + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + q.Enrich = (a, s, payload) => + { + if (payload is IJobDetail jobDetail) { - if (payload is IJobDetail jobDetail) + var dataMap = jobDetail.JobDataMap; + if (dataMap.ContainsKey("TestId")) { - var dataMap = jobDetail.JobDataMap; - if (dataMap.ContainsKey("TestId")) - { - a.SetTag("test.id", dataMap["TestId"]); - } + a.SetTag("test.id", dataMap["TestId"]); } - }) - .AddProcessor(activityProcessor.Object) - .Build(); - - var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); - schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); - var scheduler = await schedulerConfig.BuildScheduler(); - - scheduler.Context.Put("BARRIER", barrier); - scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); - await scheduler.Start(); - - var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; - - var name = Guid.NewGuid().ToString(); - var job = JobBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .UsingJobData(jobDataMap) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .StartNow() - .Build(); - - // Act - await scheduler.ScheduleJob(job, trigger); - - barrier.SignalAndWait(TestTimeout); - - await scheduler.Shutdown(true); - - // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - Assert.Equal("Quartz.Job.Execute", activity.OperationName); - Assert.Equal(ActivityKind.Internal, activity.Kind); - Assert.Equal("Scheduler", activity.Tags.SingleOrDefault(t => t.Key.Equals("scheduler.name")).Value); - Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("job.group")).Value); - Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("trigger.group")).Value); - Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); - } - - [Fact] - public async Task Should_Record_Exception_When_Record_Exception_Enabled() - { - // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); - - var activityProcessor = new Mock>(); - - using var tel = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddQuartzInstrumentation(q => - q.RecordException = true) - .AddProcessor(activityProcessor.Object) - .Build(); - - var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); - schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); - var scheduler = await schedulerConfig.BuildScheduler(); - - scheduler.Context.Put("BARRIER", barrier); - scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); - await scheduler.Start(); - - var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; - - var name = Guid.NewGuid().ToString(); - var job = JobBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .UsingJobData(jobDataMap) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .StartNow() - .Build(); - - // Act - await scheduler.ScheduleJob(job, trigger); - - barrier.SignalAndWait(TimeSpan.FromSeconds(1)); - - await scheduler.Shutdown(true); - - // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - Assert.Equal("exception", activity.Events.First().Name); - Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); - Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); - } - - [Fact] - public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enrich() - { - // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); - - var activityProcessor = new Mock>(); - - using var tel = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddQuartzInstrumentation(q => - { - q.RecordException = true; - q.Enrich = (a, s, p) => - { - if (p is IJobDetail jobDetail) - { - var dataMap = jobDetail.JobDataMap; - if (dataMap.ContainsKey("TestId")) - { - a.SetTag("test.id", dataMap["TestId"]); - } - } - }; + } }) - .AddProcessor(activityProcessor.Object) - .Build(); - - var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); - schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); - var scheduler = await schedulerConfig.BuildScheduler(); - - scheduler.Context.Put("BARRIER", barrier); - scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); - await scheduler.Start(); - - var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; - - var name = Guid.NewGuid().ToString(); - var job = JobBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .UsingJobData(jobDataMap) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .StartNow() - .Build(); - - // Act - await scheduler.ScheduleJob(job, trigger); - - barrier.SignalAndWait(TimeSpan.FromSeconds(1)); - - await scheduler.Shutdown(true); - - // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); - Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); - Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); - } - - [Fact] - public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() - { - // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); - - var activityProcessor = new Mock>(); - using var tel = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddQuartzInstrumentation(q => + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TestTimeout); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Equal("Quartz.Job.Execute", activity.OperationName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal("Scheduler", activity.Tags.SingleOrDefault(t => t.Key.Equals("scheduler.name")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("job.group")).Value); + Assert.Equal(SchedulerConstants.DefaultGroup, activity.Tags.SingleOrDefault(t => t.Key.Equals("trigger.group")).Value); + Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); + } + + [Fact] + public async Task Should_Record_Exception_When_Record_Exception_Enabled() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + q.RecordException = true) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TimeSpan.FromSeconds(1)); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Equal("exception", activity.Events.First().Name); + Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); + Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); + } + + [Fact] + public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enrich() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + { + q.RecordException = true; + q.Enrich = (a, s, p) => { - q.RecordException = true; - q.Enrich = (a, s, p) => + if (p is IJobDetail jobDetail) + { + var dataMap = jobDetail.JobDataMap; + if (dataMap.ContainsKey("TestId")) { - if (s.Equals("OnException")) - { - throw new Exception("Enrich Exception"); - } - }; - }) - .AddProcessor(activityProcessor.Object) - .Build(); - - var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); - schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); - var scheduler = await schedulerConfig.BuildScheduler(); - - scheduler.Context.Put("BARRIER", barrier); - scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); - await scheduler.Start(); - - var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; - - var name = Guid.NewGuid().ToString(); - var job = JobBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .UsingJobData(jobDataMap) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .StartNow() - .Build(); - - // Act - await scheduler.ScheduleJob(job, trigger); - - barrier.SignalAndWait(TimeSpan.FromSeconds(1)); - - await scheduler.Shutdown(true); - - // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - Assert.Equal("exception", activity.Events.First().Name); - Assert.Equal("Quartz.JobExecutionException", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionType)).Value); - Assert.Equal("Catch me if you can!", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionMessage)).Value); - } - - [Fact] - public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present() - { - // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); - - var activityProcessor = new Mock>(); - - using var tel = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddQuartzInstrumentation(q => - { - q.TracedOperations = new HashSet(); - }) - .AddProcessor(activityProcessor.Object) - .Build(); + a.SetTag("test.id", dataMap["TestId"]); + } + } + }; + }) + .AddProcessor(activityProcessor.Object) + .Build(); - var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); - schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); - var scheduler = await schedulerConfig.BuildScheduler(); + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); - scheduler.Context.Put("BARRIER", barrier); - scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); - await scheduler.Start(); + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); - var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; - var name = Guid.NewGuid().ToString(); - var job = JobBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .UsingJobData(jobDataMap) - .Build(); + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); - var trigger = TriggerBuilder.Create() - .WithIdentity(name, SchedulerConstants.DefaultGroup) - .StartNow() - .Build(); + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); - // Act - await scheduler.ScheduleJob(job, trigger); + // Act + await scheduler.ScheduleJob(job, trigger); - barrier.SignalAndWait(TestTimeout); + barrier.SignalAndWait(TimeSpan.FromSeconds(1)); - await scheduler.Shutdown(true); + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); + Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); + Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); + } - // Assert - var activities = activityProcessor.Invocations.SelectMany(i => i.Arguments.OfType()) - .Where(a => a.IsAllDataRequested); - Assert.Empty(activities); - } + [Fact] + public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + { + q.RecordException = true; + q.Enrich = (a, s, p) => + { + if (s.Equals("OnException")) + { + throw new Exception("Enrich Exception"); + } + }; + }) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TimeSpan.FromSeconds(1)); + + await scheduler.Shutdown(true); + + // Assert + Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Equal("exception", activity.Events.First().Name); + Assert.Equal("Quartz.JobExecutionException", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionType)).Value); + Assert.Equal("Catch me if you can!", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionMessage)).Value); + } + + [Fact] + public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present() + { + // Arrange + Barrier barrier = new Barrier(2); + List jobExecTimestamps = new List(); + + var activityProcessor = new Mock>(); + + using var tel = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddQuartzInstrumentation(q => + { + q.TracedOperations = new HashSet(); + }) + .AddProcessor(activityProcessor.Object) + .Build(); + + var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); + schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); + var scheduler = await schedulerConfig.BuildScheduler(); + + scheduler.Context.Put("BARRIER", barrier); + scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); + await scheduler.Start(); + + var testId = Guid.NewGuid().ToString(); + JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + + var name = Guid.NewGuid().ToString(); + var job = JobBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .UsingJobData(jobDataMap) + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity(name, SchedulerConstants.DefaultGroup) + .StartNow() + .Build(); + + // Act + await scheduler.ScheduleJob(job, trigger); + + barrier.SignalAndWait(TestTimeout); + + await scheduler.Shutdown(true); + + // Assert + var activities = activityProcessor.Invocations.SelectMany(i => i.Arguments.OfType()) + .Where(a => a.IsAllDataRequested); + Assert.Empty(activities); } } diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs index 05f1fcffa1..563ee5a834 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs @@ -20,28 +20,27 @@ using System.Threading.Tasks; using Quartz; -namespace OpenTelemetry.Instrumentation.Quartz.Tests +namespace OpenTelemetry.Instrumentation.Quartz.Tests; + +public class TestJob : IJob { - public class TestJob : IJob + public Task Execute(IJobExecutionContext context) { - public Task Execute(IJobExecutionContext context) + try { - try - { - List jobExecTimestamps = (List)context.Scheduler.Context.Get("DATESTAMPS"); - Barrier barrier = (Barrier)context.Scheduler.Context.Get("BARRIER"); - - jobExecTimestamps.Add(DateTime.UtcNow); + List jobExecTimestamps = (List)context.Scheduler.Context.Get("DATESTAMPS"); + Barrier barrier = (Barrier)context.Scheduler.Context.Get("BARRIER"); - barrier.SignalAndWait(TimeSpan.FromSeconds(125)); - return Task.CompletedTask; - } - catch (Exception e) - { - Console.Write(e); - } + jobExecTimestamps.Add(DateTime.UtcNow); + barrier.SignalAndWait(TimeSpan.FromSeconds(125)); return Task.CompletedTask; } + catch (Exception e) + { + Console.Write(e); + } + + return Task.CompletedTask; } } diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs index 98546ea16e..bfc2484519 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs @@ -17,13 +17,12 @@ using System.Threading.Tasks; using Quartz; -namespace OpenTelemetry.Instrumentation.Quartz.Tests +namespace OpenTelemetry.Instrumentation.Quartz.Tests; + +public class TestJobExecutionExceptionJob : IJob { - public class TestJobExecutionExceptionJob : IJob + public Task Execute(IJobExecutionContext context) { - public Task Execute(IJobExecutionContext context) - { - throw new JobExecutionException("Catch me if you can!"); - } + throw new JobExecutionException("Catch me if you can!"); } } From ca8d34227d9f58b7f85643c8995f79416dde0a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 9 Aug 2022 19:30:47 +0200 Subject: [PATCH 0274/1499] [Instrumenation.Owin] File scoped namespace (#567) --- .../AppBuilderExtensions.cs | 27 +- .../Implementation/DiagnosticsMiddleware.cs | 293 +++++++++--------- .../OwinInstrumentationActivitySource.cs | 17 +- .../OwinInstrumentationEventSource.cs | 111 ++++--- .../OwinEnrichEventType.cs | 25 +- .../OwinInstrumentationOptions.cs | 45 ++- .../TracerProviderBuilderExtensions.cs | 37 ++- .../Controllers/TestController.cs | 14 +- .../DiagnosticsMiddlewareTests.cs | 281 +++++++++-------- 9 files changed, 420 insertions(+), 430 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs index 21c3ac8a39..b0f0a095c5 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs @@ -17,19 +17,18 @@ using System.Diagnostics; using OpenTelemetry.Instrumentation.Owin; -namespace Owin +namespace Owin; + +/// +/// Provides extension methods for the class. +/// +public static class AppBuilderExtensions { - /// - /// Provides extension methods for the class. - /// - public static class AppBuilderExtensions - { - /// Adds a component to the OWIN pipeline for instrumenting - /// incoming request with and notifying listeners - /// with . - /// . - /// Supplied for chaining. - public static IAppBuilder UseOpenTelemetry(this IAppBuilder appBuilder) - => appBuilder.Use(); - } + /// Adds a component to the OWIN pipeline for instrumenting + /// incoming request with and notifying listeners + /// with . + /// . + /// Supplied for chaining. + public static IAppBuilder UseOpenTelemetry(this IAppBuilder appBuilder) + => appBuilder.Use(); } diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index e05bf9a801..1d0bd2ba8f 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -23,202 +23,201 @@ using OpenTelemetry.Context.Propagation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin; + +/// +/// Instruments incoming request with and notifies listeners with . +/// +internal sealed class DiagnosticsMiddleware : OwinMiddleware { + private const string ContextKey = "__OpenTelemetry.Context__"; + private static readonly Func> OwinRequestHeaderValuesGetter + = (request, name) => request.Headers.GetValues(name); + /// - /// Instruments incoming request with and notifies listeners with . + /// Initializes a new instance of the class. /// - internal sealed class DiagnosticsMiddleware : OwinMiddleware + /// An optional pointer to the next component. + public DiagnosticsMiddleware(OwinMiddleware next) + : base(next) + { + } + + /// + public override async Task Invoke(IOwinContext owinContext) { - private const string ContextKey = "__OpenTelemetry.Context__"; - private static readonly Func> OwinRequestHeaderValuesGetter - = (request, name) => request.Headers.GetValues(name); - - /// - /// Initializes a new instance of the class. - /// - /// An optional pointer to the next component. - public DiagnosticsMiddleware(OwinMiddleware next) - : base(next) + try { + BeginRequest(owinContext); + await this.Next.Invoke(owinContext).ConfigureAwait(false); + RequestEnd(owinContext, null); } - - /// - public override async Task Invoke(IOwinContext owinContext) + catch (Exception ex) { - try - { - BeginRequest(owinContext); - await this.Next.Invoke(owinContext).ConfigureAwait(false); - RequestEnd(owinContext, null); - } - catch (Exception ex) - { - RequestEnd(owinContext, ex); - throw; - } + RequestEnd(owinContext, ex); + throw; } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void BeginRequest(IOwinContext owinContext) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void BeginRequest(IOwinContext owinContext) + { + try { - try + if (OwinInstrumentationActivitySource.Options == null || OwinInstrumentationActivitySource.Options.Filter?.Invoke(owinContext) == false) { - if (OwinInstrumentationActivitySource.Options == null || OwinInstrumentationActivitySource.Options.Filter?.Invoke(owinContext) == false) - { - OwinInstrumentationEventSource.Log.RequestIsFilteredOut(); - return; - } + OwinInstrumentationEventSource.Log.RequestIsFilteredOut(); + return; } + } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) + catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types - { - OwinInstrumentationEventSource.Log.RequestFilterException(ex); - return; - } + { + OwinInstrumentationEventSource.Log.RequestFilterException(ex); + return; + } - var textMapPropagator = Propagators.DefaultTextMapPropagator; - var ctx = textMapPropagator.Extract(default, owinContext.Request, OwinRequestHeaderValuesGetter); + var textMapPropagator = Propagators.DefaultTextMapPropagator; + var ctx = textMapPropagator.Extract(default, owinContext.Request, OwinRequestHeaderValuesGetter); - Activity activity = OwinInstrumentationActivitySource.ActivitySource.StartActivity( - OwinInstrumentationActivitySource.IncomingRequestActivityName, - ActivityKind.Server, - ctx.ActivityContext); + Activity activity = OwinInstrumentationActivitySource.ActivitySource.StartActivity( + OwinInstrumentationActivitySource.IncomingRequestActivityName, + ActivityKind.Server, + ctx.ActivityContext); - if (activity != null) + if (activity != null) + { + var request = owinContext.Request; + + /* + * Note: Display name is intentionally set to a low cardinality + * value because OWIN does not expose any kind of + * route/template. See: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name + */ + activity.DisplayName = request.Method switch { - var request = owinContext.Request; - - /* - * Note: Display name is intentionally set to a low cardinality - * value because OWIN does not expose any kind of - * route/template. See: - * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name - */ - activity.DisplayName = request.Method switch + "GET" => "HTTP GET", + "POST" => "HTTP POST", + "PUT" => "HTTP PUT", + "DELETE" => "HTTP DELETE", + _ => $"HTTP {request.Method}", + }; + + if (activity.IsAllDataRequested) + { + if (request.Uri.Port == 80 || request.Uri.Port == 443) { - "GET" => "HTTP GET", - "POST" => "HTTP POST", - "PUT" => "HTTP PUT", - "DELETE" => "HTTP DELETE", - _ => $"HTTP {request.Method}", - }; - - if (activity.IsAllDataRequested) + activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host); + } + else { - if (request.Uri.Port == 80 || request.Uri.Port == 443) - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host + ":" + request.Uri.Port); - } + activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host + ":" + request.Uri.Port); + } - activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); - activity.SetTag(SemanticConventions.AttributeHttpTarget, request.Uri.AbsolutePath); - activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Uri)); + activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); + activity.SetTag(SemanticConventions.AttributeHttpTarget, request.Uri.AbsolutePath); + activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Uri)); - if (request.Headers.TryGetValue("User-Agent", out string[] userAgent) && userAgent.Length > 0) - { - activity.SetTag(SemanticConventions.AttributeHttpUserAgent, userAgent[0]); - } + if (request.Headers.TryGetValue("User-Agent", out string[] userAgent) && userAgent.Length > 0) + { + activity.SetTag(SemanticConventions.AttributeHttpUserAgent, userAgent[0]); + } - try - { - OwinInstrumentationActivitySource.Options.Enrich?.Invoke( - activity, - OwinEnrichEventType.BeginRequest, - owinContext, - null); - } + try + { + OwinInstrumentationActivitySource.Options.Enrich?.Invoke( + activity, + OwinEnrichEventType.BeginRequest, + owinContext, + null); + } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) + catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types - { - OwinInstrumentationEventSource.Log.EnrichmentException(ex); - } - } - - if (!(textMapPropagator is TraceContextPropagator)) { - Baggage.Current = ctx.Baggage; + OwinInstrumentationEventSource.Log.EnrichmentException(ex); } + } - owinContext.Environment[ContextKey] = activity; + if (!(textMapPropagator is TraceContextPropagator)) + { + Baggage.Current = ctx.Baggage; } + + owinContext.Environment[ContextKey] = activity; } + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void RequestEnd(IOwinContext owinContext, Exception exception) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void RequestEnd(IOwinContext owinContext, Exception exception) + { + if (owinContext.Environment.TryGetValue(ContextKey, out object context) + && context is Activity activity) { - if (owinContext.Environment.TryGetValue(ContextKey, out object context) - && context is Activity activity) + if (Activity.Current != activity) { - if (Activity.Current != activity) - { - Activity.Current = activity; - } + Activity.Current = activity; + } + + if (activity.IsAllDataRequested) + { + var response = owinContext.Response; - if (activity.IsAllDataRequested) + if (exception != null) { - var response = owinContext.Response; + activity.SetStatus(Status.Error); - if (exception != null) + if (OwinInstrumentationActivitySource.Options.RecordException) { - activity.SetStatus(Status.Error); - - if (OwinInstrumentationActivitySource.Options.RecordException) - { - activity.RecordException(exception); - } - } - else if (activity.GetStatus().StatusCode == StatusCode.Unset) - { - activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(response.StatusCode)); + activity.RecordException(exception); } + } + else if (activity.GetStatus().StatusCode == StatusCode.Unset) + { + activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(response.StatusCode)); + } - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); - try - { - OwinInstrumentationActivitySource.Options.Enrich?.Invoke( - activity, - OwinEnrichEventType.EndRequest, - owinContext, - exception); - } + try + { + OwinInstrumentationActivitySource.Options.Enrich?.Invoke( + activity, + OwinEnrichEventType.EndRequest, + owinContext, + exception); + } #pragma warning disable CA1031 // Do not catch general exception types - catch (Exception ex) + catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types - { - OwinInstrumentationEventSource.Log.EnrichmentException(ex); - } - } - - activity.Stop(); - - if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) { - Baggage.Current = default; + OwinInstrumentationEventSource.Log.EnrichmentException(ex); } } - } - /// - /// Gets the OpenTelemetry standard uri tag value for a span based on its request . - /// - /// . - /// Span uri value. - private static string GetUriTagValueFromRequestUri(Uri uri) - { - if (string.IsNullOrEmpty(uri.UserInfo)) + activity.Stop(); + + if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) { - return uri.ToString(); + Baggage.Current = default; } + } + } - return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); + /// + /// Gets the OpenTelemetry standard uri tag value for a span based on its request . + /// + /// . + /// Span uri value. + private static string GetUriTagValueFromRequestUri(Uri uri) + { + if (string.IsNullOrEmpty(uri.UserInfo)) + { + return uri.ToString(); } + + return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index 4a34fce584..d20d36b327 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -17,17 +17,16 @@ using System; using System.Diagnostics; -namespace OpenTelemetry.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin; + +internal static class OwinInstrumentationActivitySource { - internal static class OwinInstrumentationActivitySource - { - public const string ActivitySourceName = "OpenTelemetry.OWIN"; - public const string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; + public const string ActivitySourceName = "OpenTelemetry.OWIN"; + public const string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; - private static readonly Version Version = typeof(OwinInstrumentationActivitySource).Assembly.GetName().Version; + private static readonly Version Version = typeof(OwinInstrumentationActivitySource).Assembly.GetName().Version; - public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); + public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); - public static OwinInstrumentationOptions Options { get; set; } - } + public static OwinInstrumentationOptions Options { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index 74e6a12815..ddcd595f10 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -19,76 +19,75 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-Owin")] +internal sealed class OwinInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-Owin")] - internal sealed class OwinInstrumentationEventSource : EventSource - { - public static OwinInstrumentationEventSource Log { get; } = new OwinInstrumentationEventSource(); + public static OwinInstrumentationEventSource Log { get; } = new OwinInstrumentationEventSource(); - [NonEvent] - public void RequestFilterException(Exception ex) + [NonEvent] + public void RequestFilterException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.RequestFilterException(ToInvariantString(ex)); - } + this.RequestFilterException(ToInvariantString(ex)); } + } - [Event(EventIds.RequestIsFilteredOut, Message = "Request is filtered out.", Level = EventLevel.Verbose)] - public void RequestIsFilteredOut() - { - this.WriteEvent(EventIds.RequestIsFilteredOut); - } + [Event(EventIds.RequestIsFilteredOut, Message = "Request is filtered out.", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut() + { + this.WriteEvent(EventIds.RequestIsFilteredOut); + } - [Event(EventIds.RequestFilterException, Message = "InstrumentationFilter threw exception. Request will not be collected. Exception {0}.", Level = EventLevel.Error)] - public void RequestFilterException(string exception) - { - this.WriteEvent(EventIds.RequestFilterException, exception); - } + [Event(EventIds.RequestFilterException, Message = "InstrumentationFilter threw exception. Request will not be collected. Exception {0}.", Level = EventLevel.Error)] + public void RequestFilterException(string exception) + { + this.WriteEvent(EventIds.RequestFilterException, exception); + } - [NonEvent] - public void EnrichmentException(Exception exception) + [NonEvent] + public void EnrichmentException(Exception exception) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.EnrichmentException(ToInvariantString(exception)); - } + this.EnrichmentException(ToInvariantString(exception)); } + } - [Event(EventIds.EnrichmentException, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] - public void EnrichmentException(string exception) - { - this.WriteEvent(EventIds.EnrichmentException, exception); - } + [Event(EventIds.EnrichmentException, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(EventIds.EnrichmentException, exception); + } - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - private class EventIds + finally { - public const int RequestIsFilteredOut = 1; - public const int RequestFilterException = 2; - public const int EnrichmentException = 3; + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } + + private class EventIds + { + public const int RequestIsFilteredOut = 1; + public const int RequestFilterException = 2; + public const int EnrichmentException = 3; + } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs index bb6243cf6a..e2066bd396 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs @@ -16,21 +16,20 @@ using System.Diagnostics; -namespace OpenTelemetry.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin; + +/// +/// Describes the possible events fired when enriching an . +/// +public enum OwinEnrichEventType { /// - /// Describes the possible events fired when enriching an . + /// Begin request. /// - public enum OwinEnrichEventType - { - /// - /// Begin request. - /// - BeginRequest, + BeginRequest, - /// - /// End request. - /// - EndRequest, - } + /// + /// End request. + /// + EndRequest, } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index 1e5e9806b3..a8d7206376 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -18,32 +18,31 @@ using System.Diagnostics; using Microsoft.Owin; -namespace OpenTelemetry.Instrumentation.Owin +namespace OpenTelemetry.Instrumentation.Owin; + +/// +/// Options for requests instrumentation. +/// +public class OwinInstrumentationOptions { /// - /// Options for requests instrumentation. + /// Gets or sets a Filter function that determines whether or not to collect telemetry about requests on a per request basis. + /// The Filter gets the , and should return a boolean. + /// If Filter returns true, the request is collected. + /// If Filter returns false or throw exception, the request is filtered out. /// - public class OwinInstrumentationOptions - { - /// - /// Gets or sets a Filter function that determines whether or not to collect telemetry about requests on a per request basis. - /// The Filter gets the , and should return a boolean. - /// If Filter returns true, the request is collected. - /// If Filter returns false or throw exception, the request is filtered out. - /// - public Func Filter { get; set; } + public Func Filter { get; set; } - /// - /// Gets or sets an action to enrich the created by the instrumentation. - /// - public Action Enrich { get; set; } + /// + /// Gets or sets an action to enrich the created by the instrumentation. + /// + public Action Enrich { get; set; } - /// - /// Gets or sets a value indicating whether the exception will be recorded as or not. - /// - /// - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. - /// - public bool RecordException { get; set; } - } + /// + /// Gets or sets a value indicating whether the exception will be recorded as or not. + /// + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. + /// + public bool RecordException { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index f7e9e5dd78..c2b26c796e 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -18,31 +18,30 @@ using OpenTelemetry.Instrumentation.Owin; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of OWIN request instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of OWIN request instrumentation. + /// Enables the incoming requests automatic data collection for OWIN. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// OWIN Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddOwinInstrumentation( + this TracerProviderBuilder builder, + Action configureOwinInstrumentationOptions = null) { - /// - /// Enables the incoming requests automatic data collection for OWIN. - /// - /// being configured. - /// OWIN Request configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddOwinInstrumentation( - this TracerProviderBuilder builder, - Action configureOwinInstrumentationOptions = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var owinOptions = new OwinInstrumentationOptions(); - configureOwinInstrumentationOptions?.Invoke(owinOptions); + var owinOptions = new OwinInstrumentationOptions(); + configureOwinInstrumentationOptions?.Invoke(owinOptions); - OwinInstrumentationActivitySource.Options = owinOptions; + OwinInstrumentationActivitySource.Options = owinOptions; - return builder.AddSource(OwinInstrumentationActivitySource.ActivitySourceName); - } + return builder.AddSource(OwinInstrumentationActivitySource.ActivitySourceName); } } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs index 8e059108ed..0b9a044ef2 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs @@ -14,17 +14,15 @@ // limitations under the License. // -using System; using System.Web.Http; -namespace OpenTelemetry.Instrumentation.Owin.Tests.Controllers +namespace OpenTelemetry.Instrumentation.Owin.Tests.Controllers; + +public class TestController : ApiController { - public class TestController : ApiController + // GET api/test/{id} + public string Get(string id = null) { - // GET api/test/{id} - public string Get(string id = null) - { - return $"id:{id}"; - } + return $"id:{id}"; } } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 5655aa9df0..3f48ffe817 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -28,194 +28,189 @@ using Owin; using Xunit; -namespace OpenTelemetry.Instrumentation.Owin.Tests +namespace OpenTelemetry.Instrumentation.Owin.Tests; + +public class DiagnosticsMiddlewareTests : IDisposable { - public class DiagnosticsMiddlewareTests : IDisposable - { - private readonly Uri serviceBaseUri; - private readonly IDisposable listener; - private readonly EventWaitHandle requestCompleteHandle = new(false, EventResetMode.AutoReset); + private readonly Uri serviceBaseUri; + private readonly IDisposable listener; + private readonly EventWaitHandle requestCompleteHandle = new(false, EventResetMode.AutoReset); - public DiagnosticsMiddlewareTests() + public DiagnosticsMiddlewareTests() + { + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) { - Random random = new Random(); - var retryCount = 5; - while (retryCount > 0) + try { - try - { - this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); + this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); - this.listener = WebApp.Start( - this.serviceBaseUri.ToString(), - appBuilder => + this.listener = WebApp.Start( + this.serviceBaseUri.ToString(), + appBuilder => + { + appBuilder.Use((context, next) => { - appBuilder.Use((context, next) => + try { - try - { - return next(); - } - finally - { - this.requestCompleteHandle?.Set(); - } - }); + return next(); + } + finally + { + this.requestCompleteHandle?.Set(); + } + }); - appBuilder.UseOpenTelemetry(); + appBuilder.UseOpenTelemetry(); - appBuilder.Use((context, next) => + appBuilder.Use((context, next) => + { + if (context.Request.Path == new PathString("/exception")) { - if (context.Request.Path == new PathString("/exception")) - { - context.Response.StatusCode = 500; - throw new InvalidOperationException("Unhandled exception requested by caller."); - } + context.Response.StatusCode = 500; + throw new InvalidOperationException("Unhandled exception requested by caller."); + } - return next(); - }); + return next(); + }); - HttpConfiguration config = new HttpConfiguration(); - config.Routes.MapHttpRoute( - name: "DefaultApi", - routeTemplate: "api/{controller}/{id}", - defaults: new { id = RouteParameter.Optional }); + HttpConfiguration config = new HttpConfiguration(); + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional }); - appBuilder.UseWebApi(config); - }); - break; - } - catch - { - this.listener.Dispose(); - this.listener = null; - retryCount--; - } + appBuilder.UseWebApi(config); + }); + break; } - - if (this.listener == null) + catch { - throw new InvalidOperationException("HttpListener could not be started."); + this.listener.Dispose(); + this.listener = null; + retryCount--; } } - public void Dispose() + if (this.listener == null) { - this.listener?.Dispose(); - this.requestCompleteHandle?.Dispose(); + throw new InvalidOperationException("HttpListener could not be started."); } + } - [Theory] - [InlineData(true, false)] - [InlineData(true, true)] - [InlineData(false)] - [InlineData(true, false, true)] - [InlineData(true, false, true, true)] - [InlineData(true, false, false, false, true)] - [InlineData(true, false, false, false, true, true)] - public async Task OutgoingRequestInstrumentationTest( - bool instrument, - bool filter = false, - bool enrich = false, - bool enrichmentException = false, - bool generateRemoteException = false, - bool recordException = false) - { - List stoppedActivities = new List(); + public void Dispose() + { + this.listener?.Dispose(); + this.requestCompleteHandle?.Dispose(); + } - var builder = Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(stoppedActivities); + [Theory] + [InlineData(true, false)] + [InlineData(true, true)] + [InlineData(false)] + [InlineData(true, false, true)] + [InlineData(true, false, true, true)] + [InlineData(true, false, false, false, true)] + [InlineData(true, false, false, false, true, true)] + public async Task OutgoingRequestInstrumentationTest( + bool instrument, + bool filter = false, + bool enrich = false, + bool enrichmentException = false, + bool generateRemoteException = false, + bool recordException = false) + { + List stoppedActivities = new List(); - if (instrument) - { - builder - .AddOwinInstrumentation(options => + var builder = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities); + + if (instrument) + { + builder + .AddOwinInstrumentation(options => + { + if (enrich) { - if (enrich) + if (!enrichmentException) { - if (!enrichmentException) + options.Enrich = (activity, eventName, context, exception) => { - options.Enrich = (activity, eventName, context, exception) => + switch (eventName) { - switch (eventName) - { - case OwinEnrichEventType.BeginRequest: - activity.SetTag("client.beginrequest", nameof(OwinEnrichEventType.BeginRequest)); - break; - case OwinEnrichEventType.EndRequest: - activity.SetTag("client.endrequest", nameof(OwinEnrichEventType.EndRequest)); - break; - } - }; - } - else - { - options.Enrich = (activity, eventName, context, exception) => throw new Exception("Error while enriching activity"); - } + case OwinEnrichEventType.BeginRequest: + activity.SetTag("client.beginrequest", nameof(OwinEnrichEventType.BeginRequest)); + break; + case OwinEnrichEventType.EndRequest: + activity.SetTag("client.endrequest", nameof(OwinEnrichEventType.EndRequest)); + break; + } + }; + } + else + { + options.Enrich = (activity, eventName, context, exception) => throw new Exception("Error while enriching activity"); } + } - options.Filter = _ => !filter; - options.RecordException = recordException; - }); - } + options.Filter = _ => !filter; + options.RecordException = recordException; + }); + } - using TracerProvider tracerProvider = builder.Build(); + using TracerProvider tracerProvider = builder.Build(); - using HttpClient client = new HttpClient(); + using HttpClient client = new HttpClient(); - Uri requestUri = generateRemoteException - ? new Uri($"{this.serviceBaseUri}exception") - : new Uri($"{this.serviceBaseUri}api/test"); + Uri requestUri = generateRemoteException + ? new Uri($"{this.serviceBaseUri}exception") + : new Uri($"{this.serviceBaseUri}api/test"); - this.requestCompleteHandle.Reset(); + this.requestCompleteHandle.Reset(); - using var response = await client.GetAsync(requestUri).ConfigureAwait(false); + using var response = await client.GetAsync(requestUri).ConfigureAwait(false); - /* Note: This code will continue executing as soon as the response - is available but Owin could still be working. We need to wait until - Owin has finished to inspect the activity status. */ + /* Note: This code will continue executing as soon as the response + is available but Owin could still be working. We need to wait until + Owin has finished to inspect the activity status. */ - Assert.True(this.requestCompleteHandle.WaitOne(3000)); + Assert.True(this.requestCompleteHandle.WaitOne(3000)); - if (instrument) + if (instrument) + { + if (!filter) { - if (!filter) - { - Assert.NotEmpty(stoppedActivities); - Assert.Single(stoppedActivities); + Assert.NotEmpty(stoppedActivities); + Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; - Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); + Activity activity = stoppedActivities[0]; + Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); - Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); - Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); - Assert.Equal(requestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); - - Assert.Equal(generateRemoteException ? 500 : 200, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpStatusCode).Value); - if (generateRemoteException) - { - Assert.Equal(Status.Error, activity.GetStatus()); + Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); + Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); + Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); + Assert.Equal(requestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); - if (recordException) - { - Assert.Contains(activity.Events, ae => ae.Name == SemanticConventions.AttributeExceptionEventName); - } - } - else - { - Assert.Equal(Status.Unset, activity.GetStatus()); - } + Assert.Equal(generateRemoteException ? 500 : 200, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpStatusCode).Value); + if (generateRemoteException) + { + Assert.Equal(Status.Error, activity.GetStatus()); - if (enrich && !enrichmentException) + if (recordException) { - Assert.Equal(nameof(OwinEnrichEventType.BeginRequest), activity.TagObjects.Single(t => t.Key == "client.beginrequest").Value); - Assert.Equal(nameof(OwinEnrichEventType.EndRequest), activity.TagObjects.Single(t => t.Key == "client.endrequest").Value); + Assert.Contains(activity.Events, ae => ae.Name == SemanticConventions.AttributeExceptionEventName); } } else { - Assert.Empty(stoppedActivities); + Assert.Equal(Status.Unset, activity.GetStatus()); + } + + if (enrich && !enrichmentException) + { + Assert.Equal(nameof(OwinEnrichEventType.BeginRequest), activity.TagObjects.Single(t => t.Key == "client.beginrequest").Value); + Assert.Equal(nameof(OwinEnrichEventType.EndRequest), activity.TagObjects.Single(t => t.Key == "client.endrequest").Value); } } else @@ -223,5 +218,9 @@ Owin has finished to inspect the activity status. */ Assert.Empty(stoppedActivities); } } + else + { + Assert.Empty(stoppedActivities); + } } } From c4ab6734e66ffe0752b2646e2ffcc92eced4acd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 9 Aug 2022 20:02:55 +0200 Subject: [PATCH 0275/1499] [Instrumenation.MySqlData] File scoped namespace (#568) --- .../MySqlActivitySourceHelper.cs | 33 +- .../MySqlDataInstrumentation.cs | 345 +++++++++--------- .../MySqlDataInstrumentationEventSource.cs | 35 +- .../MySqlDataInstrumentationOptions.cs | 45 ++- .../MySqlDataTraceCommand.cs | 17 +- .../TracerProviderBuilderExtensions.cs | 39 +- .../MySqlDataTests.cs | 313 ++++++++-------- 7 files changed, 410 insertions(+), 417 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs index 1aeea3b0af..fdb1866307 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs @@ -20,27 +20,26 @@ using System.Reflection; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData; + +/// +/// Helper class to hold common properties used by MySqlDataDiagnosticListener. +/// +internal class MySqlActivitySourceHelper { - /// - /// Helper class to hold common properties used by MySqlDataDiagnosticListener. - /// - internal class MySqlActivitySourceHelper - { - public const string MysqlDatabaseSystemName = "mysql"; + public const string MysqlDatabaseSystemName = "mysql"; - public static readonly AssemblyName AssemblyName = typeof(MySqlActivitySourceHelper).Assembly.GetName(); - public static readonly string ActivitySourceName = AssemblyName.Name; - public static readonly string ActivityName = ActivitySourceName + ".Execute"; + public static readonly AssemblyName AssemblyName = typeof(MySqlActivitySourceHelper).Assembly.GetName(); + public static readonly string ActivitySourceName = AssemblyName.Name; + public static readonly string ActivityName = ActivitySourceName + ".Execute"; - public static readonly IEnumerable> CreationTags = new[] - { - new KeyValuePair(SemanticConventions.AttributeDbSystem, MysqlDatabaseSystemName), - }; + public static readonly IEnumerable> CreationTags = new[] + { + new KeyValuePair(SemanticConventions.AttributeDbSystem, MysqlDatabaseSystemName), + }; - private static readonly Version Version = typeof(MySqlActivitySourceHelper).Assembly.GetName().Version; + private static readonly Version Version = typeof(MySqlActivitySourceHelper).Assembly.GetName().Version; #pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before ActivitySource otherwise null ref exception is thrown. - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); #pragma warning restore SA1202 // Elements should be ordered by access - } } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index ca7b2f1797..ce8ae4a66d 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -20,231 +20,230 @@ using MySql.Data.MySqlClient; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData; + +/// +/// MySql.Data instrumentation. +/// +internal class MySqlDataInstrumentation : DefaultTraceListener { - /// - /// MySql.Data instrumentation. - /// - internal class MySqlDataInstrumentation : DefaultTraceListener - { - private readonly ConcurrentDictionary dbConn = new ConcurrentDictionary(); + private readonly ConcurrentDictionary dbConn = new ConcurrentDictionary(); + + private readonly MySqlDataInstrumentationOptions options; - private readonly MySqlDataInstrumentationOptions options; + public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null) + { + this.options = options ?? new MySqlDataInstrumentationOptions(); + MySqlTrace.Listeners.Clear(); + MySqlTrace.Listeners.Add(this); + MySqlTrace.Switch.Level = SourceLevels.Information; + MySqlTrace.QueryAnalysisEnabled = true; + } - public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null) + /// + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) + { + try { - this.options = options ?? new MySqlDataInstrumentationOptions(); - MySqlTrace.Listeners.Clear(); - MySqlTrace.Listeners.Add(this); - MySqlTrace.Switch.Level = SourceLevels.Information; - MySqlTrace.QueryAnalysisEnabled = true; + switch ((MySqlTraceEventType)id) + { + case MySqlTraceEventType.ConnectionOpened: + // args: [driverId, connStr, threadId] + var driverId = (long)args[0]; + var connStr = args[1].ToString(); + this.dbConn[driverId] = new MySqlConnectionStringBuilder(connStr); + break; + case MySqlTraceEventType.ConnectionClosed: + break; + case MySqlTraceEventType.QueryOpened: + // args: [driverId, threadId, cmdText] + this.BeforeExecuteCommand(this.GetCommand(args[0], args[2])); + break; + case MySqlTraceEventType.ResultOpened: + break; + case MySqlTraceEventType.ResultClosed: + break; + case MySqlTraceEventType.QueryClosed: + // args: [driverId] + this.AfterExecuteCommand(); + break; + case MySqlTraceEventType.StatementPrepared: + break; + case MySqlTraceEventType.StatementExecuted: + break; + case MySqlTraceEventType.StatementClosed: + break; + case MySqlTraceEventType.NonQuery: + break; + case MySqlTraceEventType.UsageAdvisorWarning: + break; + case MySqlTraceEventType.Warning: + break; + case MySqlTraceEventType.Error: + // args: [driverId, exNumber, exMessage] + this.ErrorExecuteCommand(this.GetMySqlErrorException(args[2])); + break; + case MySqlTraceEventType.QueryNormalized: + // Should use QueryNormalized event when it exists. Because cmdText in QueryOpened event is incomplete when cmdText.length>300 + // args: [driverId, threadId, normalized_query] + this.OverwriteDbStatement(this.GetCommand(args[0], args[2])); + break; + default: + MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(id, string.Format(format, args)); + break; + } + } + catch (Exception e) + { + MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(id, string.Format(format, args), e.ToString()); } + } - /// - public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) + private void BeforeExecuteCommand(MySqlDataTraceCommand command) + { + var activity = MySqlActivitySourceHelper.ActivitySource.StartActivity( + MySqlActivitySourceHelper.ActivityName, + ActivityKind.Client, + Activity.Current?.Context ?? default(ActivityContext), + MySqlActivitySourceHelper.CreationTags); + if (activity == null) { - try - { - switch ((MySqlTraceEventType)id) - { - case MySqlTraceEventType.ConnectionOpened: - // args: [driverId, connStr, threadId] - var driverId = (long)args[0]; - var connStr = args[1].ToString(); - this.dbConn[driverId] = new MySqlConnectionStringBuilder(connStr); - break; - case MySqlTraceEventType.ConnectionClosed: - break; - case MySqlTraceEventType.QueryOpened: - // args: [driverId, threadId, cmdText] - this.BeforeExecuteCommand(this.GetCommand(args[0], args[2])); - break; - case MySqlTraceEventType.ResultOpened: - break; - case MySqlTraceEventType.ResultClosed: - break; - case MySqlTraceEventType.QueryClosed: - // args: [driverId] - this.AfterExecuteCommand(); - break; - case MySqlTraceEventType.StatementPrepared: - break; - case MySqlTraceEventType.StatementExecuted: - break; - case MySqlTraceEventType.StatementClosed: - break; - case MySqlTraceEventType.NonQuery: - break; - case MySqlTraceEventType.UsageAdvisorWarning: - break; - case MySqlTraceEventType.Warning: - break; - case MySqlTraceEventType.Error: - // args: [driverId, exNumber, exMessage] - this.ErrorExecuteCommand(this.GetMySqlErrorException(args[2])); - break; - case MySqlTraceEventType.QueryNormalized: - // Should use QueryNormalized event when it exists. Because cmdText in QueryOpened event is incomplete when cmdText.length>300 - // args: [driverId, threadId, normalized_query] - this.OverwriteDbStatement(this.GetCommand(args[0], args[2])); - break; - default: - MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(id, string.Format(format, args)); - break; - } - } - catch (Exception e) - { - MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(id, string.Format(format, args), e.ToString()); - } + return; } - private void BeforeExecuteCommand(MySqlDataTraceCommand command) + if (activity.IsAllDataRequested) { - var activity = MySqlActivitySourceHelper.ActivitySource.StartActivity( - MySqlActivitySourceHelper.ActivityName, - ActivityKind.Client, - Activity.Current?.Context ?? default(ActivityContext), - MySqlActivitySourceHelper.CreationTags); - if (activity == null) + if (this.options.SetDbStatement) { - return; + activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); } - if (activity.IsAllDataRequested) + if (command.ConnectionStringBuilder != null) { - if (this.options.SetDbStatement) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); - } - - if (command.ConnectionStringBuilder != null) - { - activity.DisplayName = command.ConnectionStringBuilder.Database; - activity.SetTag(SemanticConventions.AttributeDbName, command.ConnectionStringBuilder.Database); + activity.DisplayName = command.ConnectionStringBuilder.Database; + activity.SetTag(SemanticConventions.AttributeDbName, command.ConnectionStringBuilder.Database); - this.AddConnectionLevelDetailsToActivity(command.ConnectionStringBuilder, activity); - } + this.AddConnectionLevelDetailsToActivity(command.ConnectionStringBuilder, activity); } } + } - private void OverwriteDbStatement(MySqlDataTraceCommand command) + private void OverwriteDbStatement(MySqlDataTraceCommand command) + { + var activity = Activity.Current; + if (activity == null) { - var activity = Activity.Current; - if (activity == null) - { - return; - } + return; + } - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } + if (activity.Source != MySqlActivitySourceHelper.ActivitySource) + { + return; + } - if (activity.IsAllDataRequested) + if (activity.IsAllDataRequested) + { + if (this.options.SetDbStatement) { - if (this.options.SetDbStatement) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); - } + activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); } } + } - private void AfterExecuteCommand() + private void AfterExecuteCommand() + { + var activity = Activity.Current; + if (activity == null) { - var activity = Activity.Current; - if (activity == null) - { - return; - } + return; + } - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } + if (activity.Source != MySqlActivitySourceHelper.ActivitySource) + { + return; + } - try - { - if (activity.IsAllDataRequested) - { - activity.SetStatus(Status.Unset); - } - } - finally + try + { + if (activity.IsAllDataRequested) { - activity.Stop(); + activity.SetStatus(Status.Unset); } } + finally + { + activity.Stop(); + } + } - private void ErrorExecuteCommand(Exception exception) + private void ErrorExecuteCommand(Exception exception) + { + var activity = Activity.Current; + if (activity == null) { - var activity = Activity.Current; - if (activity == null) - { - return; - } + return; + } - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } + if (activity.Source != MySqlActivitySourceHelper.ActivitySource) + { + return; + } - try + try + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + if (this.options.RecordException) { - activity.SetStatus(Status.Error.WithDescription(exception.Message)); - if (this.options.RecordException) - { - activity.RecordException(exception); - } + activity.RecordException(exception); } } - finally - { - activity.Stop(); - } } - - private MySqlDataTraceCommand GetCommand(object driverIdObj, object cmd) + finally { - var command = new MySqlDataTraceCommand(); - if (this.dbConn.TryGetValue((long)driverIdObj, out var database)) - { - command.ConnectionStringBuilder = database; - } - - command.SqlText = cmd == null ? string.Empty : cmd.ToString(); - return command; + activity.Stop(); } + } - private Exception GetMySqlErrorException(object errorMsg) + private MySqlDataTraceCommand GetCommand(object driverIdObj, object cmd) + { + var command = new MySqlDataTraceCommand(); + if (this.dbConn.TryGetValue((long)driverIdObj, out var database)) { - return new Exception($"{errorMsg}"); + command.ConnectionStringBuilder = database; } - private void AddConnectionLevelDetailsToActivity(MySqlConnectionStringBuilder dataSource, Activity sqlActivity) + command.SqlText = cmd == null ? string.Empty : cmd.ToString(); + return command; + } + + private Exception GetMySqlErrorException(object errorMsg) + { + return new Exception($"{errorMsg}"); + } + + private void AddConnectionLevelDetailsToActivity(MySqlConnectionStringBuilder dataSource, Activity sqlActivity) + { + if (!this.options.EnableConnectionLevelAttributes) + { + sqlActivity.SetTag(SemanticConventions.AttributePeerService, dataSource.Server); + } + else { - if (!this.options.EnableConnectionLevelAttributes) + var uriHostNameType = Uri.CheckHostName(dataSource.Server); + + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) { - sqlActivity.SetTag(SemanticConventions.AttributePeerService, dataSource.Server); + sqlActivity.SetTag(SemanticConventions.AttributeNetPeerIp, dataSource.Server); } else { - var uriHostNameType = Uri.CheckHostName(dataSource.Server); - - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - sqlActivity.SetTag(SemanticConventions.AttributeNetPeerIp, dataSource.Server); - } - else - { - sqlActivity.SetTag(SemanticConventions.AttributeNetPeerName, dataSource.Server); - } - - sqlActivity.SetTag(SemanticConventions.AttributeNetPeerPort, dataSource.Port); - sqlActivity.SetTag(SemanticConventions.AttributeDbUser, dataSource.UserID); + sqlActivity.SetTag(SemanticConventions.AttributeNetPeerName, dataSource.Server); } + + sqlActivity.SetTag(SemanticConventions.AttributeNetPeerPort, dataSource.Port); + sqlActivity.SetTag(SemanticConventions.AttributeDbUser, dataSource.UserID); } } } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs index 8a0118bcd6..99436a67d8 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs @@ -16,26 +16,25 @@ using System.Diagnostics.Tracing; -namespace OpenTelemetry.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-MySqlData")] +internal class MySqlDataInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-MySqlData")] - internal class MySqlDataInstrumentationEventSource : EventSource - { - public static readonly MySqlDataInstrumentationEventSource Log = new MySqlDataInstrumentationEventSource(); + public static readonly MySqlDataInstrumentationEventSource Log = new MySqlDataInstrumentationEventSource(); - [Event(1, Message = "Unknown MySqlTraceEventType: {0}, Message {1}", Level = EventLevel.Error)] - public void UnknownMySqlTraceEventType(int mysqlEventId, string message) - { - this.WriteEvent(1, mysqlEventId, message); - } + [Event(1, Message = "Unknown MySqlTraceEventType: {0}, Message {1}", Level = EventLevel.Error)] + public void UnknownMySqlTraceEventType(int mysqlEventId, string message) + { + this.WriteEvent(1, mysqlEventId, message); + } - [Event(2, Message = "Error accured while processing trace event, MySqlTraceEventType: {0}, Message {1}, Exception: {2}", Level = EventLevel.Error)] - public void ErrorTraceEvent(int mysqlEventId, string message, string exception) - { - this.WriteEvent(1, mysqlEventId, message, exception); - } + [Event(2, Message = "Error accured while processing trace event, MySqlTraceEventType: {0}, Message {1}, Exception: {2}", Level = EventLevel.Error)] + public void ErrorTraceEvent(int mysqlEventId, string message, string exception) + { + this.WriteEvent(1, mysqlEventId, message, exception); } } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs index bac2b8869a..fc1afcc288 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs @@ -16,32 +16,31 @@ using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData; + +/// +/// Options for . +/// +public class MySqlDataInstrumentationOptions { /// - /// Options for . + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. Default value: False. /// - public class MySqlDataInstrumentationOptions - { - /// - /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. Default value: False. - /// - /// - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. - /// - public bool RecordException { get; set; } + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. + /// + public bool RecordException { get; set; } - /// - /// Gets or sets a value indicating whether or not the should add the text as the tag. Default value: False. - /// - public bool SetDbStatement { get; set; } + /// + /// Gets or sets a value indicating whether or not the should add the text as the tag. Default value: False. + /// + public bool SetDbStatement { get; set; } - /// - /// Gets or sets a value indicating whether or not the should parse the DataSource on a SqlConnection into server name, instance name, and/or port connection-level attribute tags. Default value: False. - /// - /// - /// The default behavior is to set the MySqlConnection DataSource as the tag. If enabled, MySqlConnection DataSource will be parsed and the server name will be sent as the or tag, the instance name will be sent as the tag, and the port will be sent as the tag if it is not 1433 (the default port). - /// - public bool EnableConnectionLevelAttributes { get; set; } - } + /// + /// Gets or sets a value indicating whether or not the should parse the DataSource on a SqlConnection into server name, instance name, and/or port connection-level attribute tags. Default value: False. + /// + /// + /// The default behavior is to set the MySqlConnection DataSource as the tag. If enabled, MySqlConnection DataSource will be parsed and the server name will be sent as the or tag, the instance name will be sent as the tag, and the port will be sent as the tag if it is not 1433 (the default port). + /// + public bool EnableConnectionLevelAttributes { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs index a1b6674529..3d988581ed 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs @@ -16,15 +16,14 @@ using MySql.Data.MySqlClient; -namespace OpenTelemetry.Instrumentation.MySqlData +namespace OpenTelemetry.Instrumentation.MySqlData; + +/// +/// Information of current executing command. +/// +internal class MySqlDataTraceCommand { - /// - /// Informations of current executing command. - /// - internal class MySqlDataTraceCommand - { - public MySqlConnectionStringBuilder ConnectionStringBuilder { get; set; } + public MySqlConnectionStringBuilder ConnectionStringBuilder { get; set; } - public string SqlText { get; set; } - } + public string SqlText { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs index 41cce4a9a3..e14edba2ed 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs @@ -18,32 +18,31 @@ using OpenTelemetry.Instrumentation.MySqlData; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables SqlClient instrumentation. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// SqlClient configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddMySqlDataInstrumentation( + this TracerProviderBuilder builder, + Action configureMySqlDataInstrumentationOptions = null) { - /// - /// Enables SqlClient instrumentation. - /// - /// being configured. - /// SqlClient configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddMySqlDataInstrumentation( - this TracerProviderBuilder builder, - Action configureMySqlDataInstrumentationOptions = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var sqlOptions = new MySqlDataInstrumentationOptions(); - configureMySqlDataInstrumentationOptions?.Invoke(sqlOptions); + var sqlOptions = new MySqlDataInstrumentationOptions(); + configureMySqlDataInstrumentationOptions?.Invoke(sqlOptions); - builder.AddInstrumentation(() => new MySqlDataInstrumentation(sqlOptions)); - builder.AddSource(MySqlActivitySourceHelper.ActivitySourceName); + builder.AddInstrumentation(() => new MySqlDataInstrumentation(sqlOptions)); + builder.AddSource(MySqlActivitySourceHelper.ActivitySourceName); - return builder; - } + return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs index ba33da4b7d..3f4c105897 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs @@ -23,201 +23,200 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.MySqlData.Tests +namespace OpenTelemetry.Instrumentation.MySqlData.Tests; + +public class MySqlDataTests { - public class MySqlDataTests + private const string ConnStr = "database=mysql;server=127.0.0.1;user id=root;password=123456;port=3306;pooling=False"; + + [Theory] + [InlineData("select 1/1", true, true, true, false)] + [InlineData("select 1/1", true, true, false, false)] + [InlineData("selext 1/1", true, true, true, true)] + public void SuccessTraceEventTest( + string commandText, + bool setDbStatement = false, + bool recordException = false, + bool enableConnectionLevelAttributes = false, + bool isFailure = false) { - private const string ConnStr = "database=mysql;server=127.0.0.1;user id=root;password=123456;port=3306;pooling=False"; - - [Theory] - [InlineData("select 1/1", true, true, true, false)] - [InlineData("select 1/1", true, true, false, false)] - [InlineData("selext 1/1", true, true, true, true)] - public void SuccessTraceEventTest( - string commandText, - bool setDbStatement = false, - bool recordException = false, - bool enableConnectionLevelAttributes = false, - bool isFailure = false) - { - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddMySqlDataInstrumentation(options => - { - options.SetDbStatement = setDbStatement; - options.RecordException = recordException; - options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; - }) - .Build(); - - var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); - - this.ExecuteSuccessQuery(traceListener, commandText, isFailure); + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddMySqlDataInstrumentation(options => + { + options.SetDbStatement = setDbStatement; + options.RecordException = recordException; + options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; + }) + .Build(); - Assert.Equal(3, activityProcessor.Invocations.Count); + var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + this.ExecuteSuccessQuery(traceListener, commandText, isFailure); - VerifyActivityData(commandText, setDbStatement, recordException, enableConnectionLevelAttributes, isFailure, activity); - } + Assert.Equal(3, activityProcessor.Invocations.Count); - [Fact] - public void MySqlDataInstrumentationEventSource_test() - { - MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(15, "UnknownMySqlTraceEventType"); - MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(1, "ErrorTraceEvent", "ErrorTraceEvent exception"); - } + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - [Theory] - [InlineData(MySqlTraceEventType.ConnectionClosed)] - [InlineData(MySqlTraceEventType.ResultOpened)] - [InlineData(MySqlTraceEventType.ResultClosed)] - [InlineData(MySqlTraceEventType.StatementPrepared)] - [InlineData(MySqlTraceEventType.StatementExecuted)] - [InlineData(MySqlTraceEventType.StatementClosed)] - [InlineData(MySqlTraceEventType.NonQuery)] - [InlineData(MySqlTraceEventType.UsageAdvisorWarning)] - [InlineData(MySqlTraceEventType.Warning)] - [InlineData(MySqlTraceEventType.QueryNormalized)] - [InlineData((MySqlTraceEventType)0)] - public void UnknownMySqlTraceEventType(MySqlTraceEventType eventType) - { - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddMySqlDataInstrumentation() - .Build(); + VerifyActivityData(commandText, setDbStatement, recordException, enableConnectionLevelAttributes, isFailure, activity); + } - var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); + [Fact] + public void MySqlDataInstrumentationEventSource_test() + { + MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(15, "UnknownMySqlTraceEventType"); + MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(1, "ErrorTraceEvent", "ErrorTraceEvent exception"); + } - traceListener?.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - (int)eventType, - "{0}: Connection Opened: connection string = '{1}'", - 1L, - ConnStr, - 10); + [Theory] + [InlineData(MySqlTraceEventType.ConnectionClosed)] + [InlineData(MySqlTraceEventType.ResultOpened)] + [InlineData(MySqlTraceEventType.ResultClosed)] + [InlineData(MySqlTraceEventType.StatementPrepared)] + [InlineData(MySqlTraceEventType.StatementExecuted)] + [InlineData(MySqlTraceEventType.StatementClosed)] + [InlineData(MySqlTraceEventType.NonQuery)] + [InlineData(MySqlTraceEventType.UsageAdvisorWarning)] + [InlineData(MySqlTraceEventType.Warning)] + [InlineData(MySqlTraceEventType.QueryNormalized)] + [InlineData((MySqlTraceEventType)0)] + public void UnknownMySqlTraceEventType(MySqlTraceEventType eventType) + { + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddMySqlDataInstrumentation() + .Build(); + + var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); + + traceListener?.TraceEvent( + new TraceEventCache(), + "mysql", + TraceEventType.Information, + (int)eventType, + "{0}: Connection Opened: connection string = '{1}'", + 1L, + ConnStr, + 10); + + Assert.Equal(1, activityProcessor.Invocations.Count); + } - Assert.Equal(1, activityProcessor.Invocations.Count); + private static void VerifyActivityData( + string commandText, + bool setDbStatement, + bool recordException, + bool enableConnectionLevelAttributes, + bool isFailure, + Activity activity) + { + if (!isFailure) + { + Assert.Equal(Status.Unset, activity.GetStatus()); } - - private static void VerifyActivityData( - string commandText, - bool setDbStatement, - bool recordException, - bool enableConnectionLevelAttributes, - bool isFailure, - Activity activity) + else { - if (!isFailure) + var status = activity.GetStatus(); + Assert.Equal(Status.Error.StatusCode, status.StatusCode); + Assert.NotNull(status.Description); + + if (recordException) { - Assert.Equal(Status.Unset, activity.GetStatus()); + var events = activity.Events.ToList(); + Assert.Single(events); + + Assert.Equal(SemanticConventions.AttributeExceptionEventName, events[0].Name); } else { - var status = activity.GetStatus(); - Assert.Equal(Status.Error.StatusCode, status.StatusCode); - Assert.NotNull(status.Description); - - if (recordException) - { - var events = activity.Events.ToList(); - Assert.Single(events); - - Assert.Equal(SemanticConventions.AttributeExceptionEventName, events[0].Name); - } - else - { - Assert.Empty(activity.Events); - } + Assert.Empty(activity.Events); } + } - Assert.Equal("mysql", activity.GetTagValue(SemanticConventions.AttributeDbName)); + Assert.Equal("mysql", activity.GetTagValue(SemanticConventions.AttributeDbName)); - if (setDbStatement) - { - Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } - else - { - Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } + if (setDbStatement) + { + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + else + { + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } - var dataSource = new MySqlConnectionStringBuilder(ConnStr).Server; + var dataSource = new MySqlConnectionStringBuilder(ConnStr).Server; - if (!enableConnectionLevelAttributes) + if (!enableConnectionLevelAttributes) + { + Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributePeerService)); + } + else + { + var uriHostNameType = Uri.CheckHostName(dataSource); + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) { - Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributePeerService)); + Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributeNetPeerIp)); } else { - var uriHostNameType = Uri.CheckHostName(dataSource); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributeNetPeerIp)); - } - else - { - Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - } + Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); } } + } - private void ExecuteSuccessQuery(TraceListener listener, string query, bool isFailure) + private void ExecuteSuccessQuery(TraceListener listener, string query, bool isFailure) + { + // Connection opened + listener.TraceEvent( + new TraceEventCache(), + "mysql", + TraceEventType.Information, + 1, + "{0}: Connection Opened: connection string = '{1}'", + 1L, + ConnStr, + 10); + + // Query opened + listener.TraceEvent( + new TraceEventCache(), + "mysql", + TraceEventType.Information, + 3, + "{0}: Query Opened: {2}", + 1L, + 9, + query); + + if (isFailure) { - // Connection opened + // Query error listener.TraceEvent( new TraceEventCache(), "mysql", TraceEventType.Information, - 1, - "{0}: Connection Opened: connection string = '{1}'", + 13, + "{0}: Error encountered attempting to open result: Number={1}, Message={2}", 1L, - ConnStr, - 10); - - // Query opened + 1064, + "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'selext 1/1' at line 1"); + } + else + { + // Query closed listener.TraceEvent( new TraceEventCache(), "mysql", TraceEventType.Information, - 3, - "{0}: Query Opened: {2}", - 1L, - 9, - query); - - if (isFailure) - { - // Query error - listener.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - 13, - "{0}: Error encountered attempting to open result: Number={1}, Message={2}", - 1L, - 1064, - "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'selext 1/1' at line 1"); - } - else - { - // Query closed - listener.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - 6, - "{0}: Query Closed", - 1L); - } + 6, + "{0}: Query Closed", + 1L); } } } From d75708acdfa891f169776ebc22840441e02e1598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 9 Aug 2022 20:21:38 +0200 Subject: [PATCH 0276/1499] [Intrumentation.WCF] Bump OTel package to 1.3.0 (#569) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++-- .../OpenTelemetry.Instrumentation.Wcf.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 9b5516e1d8..84fd62f9ff 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OTel SDK package version to 1.2.0 - [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) +* Updated OTel SDK package version to 1.3.0 + ([#569](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/569)) ## 1.0.0-rc.6 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 5bf42889b1..33f4f07253 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -1,4 +1,4 @@ - + net462;netstandard2.0 @@ -8,7 +8,7 @@ - + From f9fcaaaecf717800d3c16624c97e163994eed996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 9 Aug 2022 22:51:37 +0200 Subject: [PATCH 0277/1499] [Instrumenation.WCF] Adjust activity source name (#570) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ .../Implementation/WcfInstrumentationActivitySource.cs | 10 ++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 84fd62f9ff..e1d70cecf1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -4,6 +4,9 @@ * Updated OTel SDK package version to 1.3.0 ([#569](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/569)) +* Changed activity source name from `OpenTelemetry.WCF` + to `OpenTelemetry.Instrumentation.Wcf` + ([#570](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/570)) ## 1.0.0-rc.6 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index c90e363450..ca92becf65 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Reflection; using System.ServiceModel.Channels; namespace OpenTelemetry.Instrumentation.Wcf; @@ -26,11 +27,12 @@ namespace OpenTelemetry.Instrumentation.Wcf; /// internal static class WcfInstrumentationActivitySource { - public const string ActivitySourceName = "OpenTelemetry.WCF"; - public const string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; - public const string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; + internal static readonly AssemblyName AssemblyName = typeof(WcfInstrumentationActivitySource).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; + internal static readonly string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; - private static readonly Version Version = typeof(WcfInstrumentationActivitySource).Assembly.GetName().Version; + private static readonly Version Version = AssemblyName.Version; public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); From b2b6c4b52e7b7fb68966e3b6c04b70982b563888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 Aug 2022 08:10:37 +0200 Subject: [PATCH 0278/1499] [Instrumenation.Hangfire] File scoped namespace (#574) --- .../Implementation/HangfireInstrumentation.cs | 47 +++--- .../HangfireInstrumentationConstants.cs | 17 +-- ...ngfireInstrumentationJobFilterAttribute.cs | 143 +++++++++--------- .../TracerProviderBuilderExtensions.cs | 33 ++-- .../HangfireFixture.cs | 29 ++-- ...eInstrumentationJobFilterAttributeTests.cs | 109 +++++++------ .../TestJob.cs | 19 ++- 7 files changed, 195 insertions(+), 202 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index 286a465858..0fc54b23f3 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -14,32 +14,31 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Hangfire.Implementation -{ - using System; - using System.Diagnostics; - using System.Reflection; +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; + +using System; +using System.Diagnostics; +using System.Reflection; - internal static class HangfireInstrumentation - { - /// - /// The assembly name. - /// - internal static readonly AssemblyName AssemblyName = typeof(HangfireInstrumentation).Assembly.GetName(); +internal static class HangfireInstrumentation +{ + /// + /// The assembly name. + /// + internal static readonly AssemblyName AssemblyName = typeof(HangfireInstrumentation).Assembly.GetName(); - /// - /// The activity source name. - /// - internal static readonly string ActivitySourceName = AssemblyName.Name; + /// + /// The activity source name. + /// + internal static readonly string ActivitySourceName = AssemblyName.Name; - /// - /// The version. - /// - internal static readonly Version Version = AssemblyName.Version; + /// + /// The version. + /// + internal static readonly Version Version = AssemblyName.Version; - /// - /// The activity source. - /// - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); - } + /// + /// The activity source. + /// + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs index 9b3c125566..9ef7f77858 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs @@ -14,15 +14,14 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Hangfire.Implementation +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; + +internal static class HangfireInstrumentationConstants { - internal static class HangfireInstrumentationConstants - { - public const string JobIdTag = "job.id"; - public const string JobCreatedAtTag = "job.createdat"; + public const string JobIdTag = "job.id"; + public const string JobCreatedAtTag = "job.createdat"; - public const string ActivityName = "JOB"; - public const string ActivityKey = "opentelemetry_activity_key"; - public const string ActivityContextKey = "opentelemetry_activity_context"; - } + public const string ActivityName = "JOB"; + public const string ActivityKey = "opentelemetry_activity_key"; + public const string ActivityContextKey = "opentelemetry_activity_context"; } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index bc0b3baa24..79cdb83fcd 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -14,102 +14,101 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Hangfire.Implementation +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using global::Hangfire.Client; +using global::Hangfire.Common; +using global::Hangfire.Server; +using OpenTelemetry.Context.Propagation; + +internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter { - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using global::Hangfire.Client; - using global::Hangfire.Common; - using global::Hangfire.Server; - using OpenTelemetry.Context.Propagation; - - internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter + public void OnPerforming(PerformingContext performingContext) { - public void OnPerforming(PerformingContext performingContext) + // Short-circuit if nobody is listening + if (!HangfireInstrumentation.ActivitySource.HasListeners()) { - // Short-circuit if nobody is listening - if (!HangfireInstrumentation.ActivitySource.HasListeners()) - { - return; - } - - var activityContextData = performingContext.GetJobParameter>(HangfireInstrumentationConstants.ActivityContextKey); - ActivityContext parentContext = default; - if (activityContextData is not null) - { - var propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, activityContextData, ExtractActivityProperties); - parentContext = propagationContext.ActivityContext; - Baggage.Current = propagationContext.Baggage; - } - - var activity = HangfireInstrumentation.ActivitySource - .StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext); - - if (activity != null) - { - activity.DisplayName = $"JOB {performingContext.BackgroundJob.Job.Type.Name}.{performingContext.BackgroundJob.Job.Method.Name}"; - - if (activity.IsAllDataRequested) - { - activity.SetTag(HangfireInstrumentationConstants.JobIdTag, performingContext.BackgroundJob.Id); - activity.SetTag(HangfireInstrumentationConstants.JobCreatedAtTag, performingContext.BackgroundJob.CreatedAt.ToString("O")); - } + return; + } - performingContext.Items.Add(HangfireInstrumentationConstants.ActivityKey, activity); - } + var activityContextData = performingContext.GetJobParameter>(HangfireInstrumentationConstants.ActivityContextKey); + ActivityContext parentContext = default; + if (activityContextData is not null) + { + var propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, activityContextData, ExtractActivityProperties); + parentContext = propagationContext.ActivityContext; + Baggage.Current = propagationContext.Baggage; } - public void OnPerformed(PerformedContext performedContext) + var activity = HangfireInstrumentation.ActivitySource + .StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext); + + if (activity != null) { - // Short-circuit if nobody is listening - if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.ContainsKey(HangfireInstrumentationConstants.ActivityKey)) - { - return; - } + activity.DisplayName = $"JOB {performingContext.BackgroundJob.Job.Type.Name}.{performingContext.BackgroundJob.Job.Method.Name}"; - if (performedContext.Items[HangfireInstrumentationConstants.ActivityKey] is Activity activity) + if (activity.IsAllDataRequested) { - if (performedContext.Exception != null) - { - activity.SetStatus(ActivityStatusCode.Error, performedContext.Exception.Message); - } - - activity.Dispose(); + activity.SetTag(HangfireInstrumentationConstants.JobIdTag, performingContext.BackgroundJob.Id); + activity.SetTag(HangfireInstrumentationConstants.JobCreatedAtTag, performingContext.BackgroundJob.CreatedAt.ToString("O")); } + + performingContext.Items.Add(HangfireInstrumentationConstants.ActivityKey, activity); } + } - public void OnCreating(CreatingContext creatingContext) + public void OnPerformed(PerformedContext performedContext) + { + // Short-circuit if nobody is listening + if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.ContainsKey(HangfireInstrumentationConstants.ActivityKey)) { - // Short-circuit if nobody is listening - if (!HangfireInstrumentation.ActivitySource.HasListeners()) - { - return; - } + return; + } - ActivityContext contextToInject = default; - if (Activity.Current != null) + if (performedContext.Items[HangfireInstrumentationConstants.ActivityKey] is Activity activity) + { + if (performedContext.Exception != null) { - contextToInject = Activity.Current.Context; + activity.SetStatus(ActivityStatusCode.Error, performedContext.Exception.Message); } - var activityContextData = new Dictionary(); - Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(contextToInject, Baggage.Current), activityContextData, InjectActivityProperties); - creatingContext.SetJobParameter(HangfireInstrumentationConstants.ActivityContextKey, activityContextData); + activity.Dispose(); } + } - public void OnCreated(CreatedContext filterContext) + public void OnCreating(CreatingContext creatingContext) + { + // Short-circuit if nobody is listening + if (!HangfireInstrumentation.ActivitySource.HasListeners()) { + return; } - private static void InjectActivityProperties(IDictionary jobParams, string key, string value) + ActivityContext contextToInject = default; + if (Activity.Current != null) { - jobParams[key] = value; + contextToInject = Activity.Current.Context; } - private static IEnumerable ExtractActivityProperties(Dictionary telemetryData, string key) - { - return telemetryData.ContainsKey(key) ? new[] { telemetryData[key] } : Enumerable.Empty(); - } + var activityContextData = new Dictionary(); + Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(contextToInject, Baggage.Current), activityContextData, InjectActivityProperties); + creatingContext.SetJobParameter(HangfireInstrumentationConstants.ActivityContextKey, activityContextData); + } + + public void OnCreated(CreatedContext filterContext) + { + } + + private static void InjectActivityProperties(IDictionary jobParams, string key, string value) + { + jobParams[key] = value; + } + + private static IEnumerable ExtractActivityProperties(Dictionary telemetryData, string key) + { + return telemetryData.ContainsKey(key) ? new[] { telemetryData[key] } : Enumerable.Empty(); } } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index 3d6bdb225b..514ced7c46 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -14,28 +14,27 @@ // limitations under the License. // -namespace OpenTelemetry.Trace -{ - using OpenTelemetry.Instrumentation.Hangfire.Implementation; - using OpenTelemetry.Internal; +namespace OpenTelemetry.Trace; + +using OpenTelemetry.Instrumentation.Hangfire.Implementation; +using OpenTelemetry.Internal; +/// +/// Extension methods to simplify registering of Hangfire job instrumentation. +/// +public static class TracerProviderBuilderExtensions +{ /// - /// Extension methods to simplify registering of Hangfire job instrumentation. + /// Adds Hangfire instrumentation to the tracer provider. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder) { - /// - /// Adds Hangfire instrumentation to the tracer provider. - /// - /// being configured. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute()); + Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute()); - return builder.AddSource(HangfireInstrumentation.ActivitySourceName); - } + return builder.AddSource(HangfireInstrumentation.ActivitySourceName); } } diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs index 2f51f7f84b..4c33bb8166 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -19,25 +19,24 @@ using Hangfire.MemoryStorage; using Hangfire.Storage; -namespace OpenTelemetry.Instrumentation.Hangfire.Tests +namespace OpenTelemetry.Instrumentation.Hangfire.Tests; + +public class HangfireFixture : IDisposable { - public class HangfireFixture : IDisposable + public HangfireFixture() { - public HangfireFixture() - { - GlobalConfiguration.Configuration - .UseMemoryStorage(); - this.Server = new BackgroundJobServer(); - this.MonitoringApi = JobStorage.Current.GetMonitoringApi(); - } + GlobalConfiguration.Configuration + .UseMemoryStorage(); + this.Server = new BackgroundJobServer(); + this.MonitoringApi = JobStorage.Current.GetMonitoringApi(); + } - public BackgroundJobServer Server { get; } + public BackgroundJobServer Server { get; } - public IMonitoringApi MonitoringApi { get; } + public IMonitoringApi MonitoringApi { get; } - public void Dispose() - { - this.Server.Dispose(); - } + public void Dispose() + { + this.Server.Dispose(); } } diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index 6104f263e0..66d67b5b48 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -24,71 +24,70 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.Hangfire.Tests +namespace OpenTelemetry.Instrumentation.Hangfire.Tests; + +public class HangfireInstrumentationJobFilterAttributeTests : IClassFixture { - public class HangfireInstrumentationJobFilterAttributeTests : IClassFixture - { - private HangfireFixture hangfireFixture; + private HangfireFixture hangfireFixture; - public HangfireInstrumentationJobFilterAttributeTests(HangfireFixture hangfireFixture) - { - this.hangfireFixture = hangfireFixture; - } + public HangfireInstrumentationJobFilterAttributeTests(HangfireFixture hangfireFixture) + { + this.hangfireFixture = hangfireFixture; + } - [Fact] - public async Task Should_Create_Activity() - { - // Arrange - var exportedItems = new List(); - using var tel = Sdk.CreateTracerProviderBuilder() - .AddHangfireInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); + [Fact] + public async Task Should_Create_Activity() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); - // Act - var jobId = BackgroundJob.Enqueue(x => x.Execute()); - await this.WaitJobProcessedAsync(jobId, 5); + // Act + var jobId = BackgroundJob.Enqueue(x => x.Execute()); + await this.WaitJobProcessedAsync(jobId, 5); - // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); - Assert.Contains("JOB TestJob.Execute", activity.DisplayName); - Assert.Equal(ActivityKind.Internal, activity.Kind); - } + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains("JOB TestJob.Execute", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + } - [Fact] - public async Task Should_Create_Activity_With_Status_Error_When_Job_Failed() - { - // Arrange - var exportedItems = new List(); - using var tel = Sdk.CreateTracerProviderBuilder() - .AddHangfireInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); + [Fact] + public async Task Should_Create_Activity_With_Status_Error_When_Job_Failed() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); - // Act - var jobId = BackgroundJob.Enqueue(x => x.ThrowException()); - await this.WaitJobProcessedAsync(jobId, 5); + // Act + var jobId = BackgroundJob.Enqueue(x => x.ThrowException()); + await this.WaitJobProcessedAsync(jobId, 5); - // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); - Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); - Assert.Equal(ActivityKind.Internal, activity.Kind); - Assert.Equal(ActivityStatusCode.Error, activity.Status); - Assert.NotNull(activity.StatusDescription); - } + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.NotNull(activity.StatusDescription); + } - private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) + private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) + { + var timeout = DateTime.Now.AddSeconds(timeToWaitInSeconds); + string[] states = new[] { "Enqueued", "Processing" }; + JobDetailsDto jobDetails; + while (((jobDetails = this.hangfireFixture.MonitoringApi.JobDetails(jobId)) == null || jobDetails.History.All(h => states.Contains(h.StateName))) + && DateTime.Now < timeout) { - var timeout = DateTime.Now.AddSeconds(timeToWaitInSeconds); - string[] states = new[] { "Enqueued", "Processing" }; - JobDetailsDto jobDetails; - while (((jobDetails = this.hangfireFixture.MonitoringApi.JobDetails(jobId)) == null || jobDetails.History.All(h => states.Contains(h.StateName))) - && DateTime.Now < timeout) - { - await Task.Delay(500); - } + await Task.Delay(500); } } } diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs index 6304f65151..604383d23d 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -16,18 +16,17 @@ using System; -namespace OpenTelemetry.Instrumentation.Hangfire.Tests +namespace OpenTelemetry.Instrumentation.Hangfire.Tests; + +public class TestJob { - public class TestJob + public void Execute() { - public void Execute() - { - return; - } + return; + } - public void ThrowException() - { - throw new Exception(); - } + public void ThrowException() + { + throw new Exception(); } } From c14c75dd47572c7c603c3fa7b123b7b76ea41d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 Aug 2022 08:23:48 +0200 Subject: [PATCH 0279/1499] [Instrumenation.OWIN] Adjust activity source name (#572) --- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 4 ++++ .../Implementation/OwinInstrumentationActivitySource.cs | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 16122787c7..eda06216f8 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Changed activity source name from `OpenTelemetry.OWIN` + to `OpenTelemetry.Instrumentation.Owin` + ([#572](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/572)) + ## 1.0.0-rc.2 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index d20d36b327..dcf20a8cb5 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -16,15 +16,17 @@ using System; using System.Diagnostics; +using System.Reflection; namespace OpenTelemetry.Instrumentation.Owin; internal static class OwinInstrumentationActivitySource { - public const string ActivitySourceName = "OpenTelemetry.OWIN"; - public const string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; + internal static readonly AssemblyName AssemblyName = typeof(OwinInstrumentationActivitySource).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; - private static readonly Version Version = typeof(OwinInstrumentationActivitySource).Assembly.GetName().Version; + private static readonly Version Version = AssemblyName.Version; public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); From b4c61fe190bcc70ac8ebdf40b687ad984711b9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 Aug 2022 18:16:06 +0200 Subject: [PATCH 0280/1499] [Instrumenation.MassTransit] File scoped namespace (#573) Co-authored-by: Utkarsh Umesan Pillai --- .../Implementation/DisplayNameHelper.cs | 39 +- .../MassTransitDiagnosticListener.cs | 241 ++++---- .../MassTransitInstrumentationEventSource.cs | 47 +- .../MassTransitSemanticConventions.cs | 13 +- .../Implementation/TagName.cs | 35 +- .../MassTransitInstrumentation.cs | 43 +- .../MassTransitInstrumentationOptions.cs | 35 +- .../OperationName.cs | 53 +- .../MassTransitInstrumentationTests.cs | 537 +++++++++--------- .../TestConsumer.cs | 11 +- .../TestMessage.cs | 9 +- 11 files changed, 526 insertions(+), 537 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs index 6d5320f6b2..c8f959d19b 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs @@ -16,33 +16,32 @@ using System.Collections.Concurrent; -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; + +internal static class DisplayNameHelper { - internal static class DisplayNameHelper - { - private static readonly ConcurrentDictionary SendOperationDisplayNameCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary ReceiveOperationDisplayNameCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary ConsumeOperationDisplayNameCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary HandleOperationDisplayNameCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary SendOperationDisplayNameCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary ReceiveOperationDisplayNameCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary ConsumeOperationDisplayNameCache = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary HandleOperationDisplayNameCache = new ConcurrentDictionary(); - public static string GetSendOperationDisplayName(string peerAddress) => - SendOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertSendOperationToDisplayName); + public static string GetSendOperationDisplayName(string peerAddress) => + SendOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertSendOperationToDisplayName); - public static string GetReceiveOperationDisplayName(string peerAddress) => - ReceiveOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertReceiveOperationToDisplayName); + public static string GetReceiveOperationDisplayName(string peerAddress) => + ReceiveOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertReceiveOperationToDisplayName); - public static string GetConsumeOperationDisplayName(string peerAddress) => - ConsumeOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertConsumeOperationToDisplayName); + public static string GetConsumeOperationDisplayName(string peerAddress) => + ConsumeOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertConsumeOperationToDisplayName); - public static string GetHandleOperationDisplayName(string peerAddress) => - HandleOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertHandleOperationToDisplayName); + public static string GetHandleOperationDisplayName(string peerAddress) => + HandleOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertHandleOperationToDisplayName); - private static string ConvertSendOperationToDisplayName(string peerAddress) => $"{peerAddress} send"; + private static string ConvertSendOperationToDisplayName(string peerAddress) => $"{peerAddress} send"; - private static string ConvertReceiveOperationToDisplayName(string peerAddress) => $"{peerAddress} consume"; + private static string ConvertReceiveOperationToDisplayName(string peerAddress) => $"{peerAddress} consume"; - private static string ConvertConsumeOperationToDisplayName(string consumerType) => $"{consumerType} process"; + private static string ConvertConsumeOperationToDisplayName(string consumerType) => $"{consumerType} process"; - private static string ConvertHandleOperationToDisplayName(string peerAddress) => $"{peerAddress} process"; - } + private static string ConvertHandleOperationToDisplayName(string peerAddress) => $"{peerAddress} process"; } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs index a7e6ec171f..0529db9631 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs @@ -21,166 +21,165 @@ using System.Reflection; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; + +internal class MassTransitDiagnosticListener : ListenerHandler { - internal class MassTransitDiagnosticListener : ListenerHandler + internal static readonly AssemblyName AssemblyName = typeof(MassTransitDiagnosticListener).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly Version Version = AssemblyName.Version; + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + + private readonly MassTransitInstrumentationOptions options; + + public MassTransitDiagnosticListener(string name, MassTransitInstrumentationOptions options) + : base(name) { - internal static readonly AssemblyName AssemblyName = typeof(MassTransitDiagnosticListener).Assembly.GetName(); - internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + this.options = options; + } - private readonly MassTransitInstrumentationOptions options; + public override void OnStartActivity(Activity activity, object payload) + { + // By this time, samplers have already run and + // activity.IsAllDataRequested populated accordingly. - public MassTransitDiagnosticListener(string name, MassTransitInstrumentationOptions options) - : base(name) + if (Sdk.SuppressInstrumentation) { - this.options = options; + return; } - public override void OnStartActivity(Activity activity, object payload) + if (activity.IsAllDataRequested) { - // By this time, samplers have already run and - // activity.IsAllDataRequested populated accordingly. - - if (Sdk.SuppressInstrumentation) + if (this.options.TracedOperations != null && !this.options.TracedOperations.Contains(activity.OperationName)) { + MassTransitInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; return; } - if (activity.IsAllDataRequested) - { - if (this.options.TracedOperations != null && !this.options.TracedOperations.Contains(activity.OperationName)) - { - MassTransitInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); - activity.IsAllDataRequested = false; - return; - } + activity.DisplayName = this.GetDisplayName(activity); - activity.DisplayName = this.GetDisplayName(activity); - - ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); - ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); - } + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); } + } - public override void OnStopActivity(Activity activity, object payload) + public override void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + try + { + this.TransformMassTransitTags(activity); + } + catch (Exception ex) { - try - { - this.TransformMassTransitTags(activity); - } - catch (Exception ex) - { - MassTransitInstrumentationEventSource.Log.EnrichmentException(ex); - } + MassTransitInstrumentationEventSource.Log.EnrichmentException(ex); } } + } - private string GetDisplayName(Activity activity) + private string GetDisplayName(Activity activity) + { + return activity.OperationName switch { - return activity.OperationName switch - { - OperationName.Transport.Send => DisplayNameHelper.GetSendOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), - OperationName.Transport.Receive => DisplayNameHelper.GetReceiveOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), - OperationName.Consumer.Consume => DisplayNameHelper.GetConsumeOperationDisplayName(this.GetTag(activity.Tags, TagName.ConsumerType)), - OperationName.Consumer.Handle => DisplayNameHelper.GetHandleOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), - _ => activity.DisplayName, - }; - } + OperationName.Transport.Send => DisplayNameHelper.GetSendOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), + OperationName.Transport.Receive => DisplayNameHelper.GetReceiveOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), + OperationName.Consumer.Consume => DisplayNameHelper.GetConsumeOperationDisplayName(this.GetTag(activity.Tags, TagName.ConsumerType)), + OperationName.Consumer.Handle => DisplayNameHelper.GetHandleOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), + _ => activity.DisplayName, + }; + } - private ActivityKind GetActivityKind(Activity activity) + private ActivityKind GetActivityKind(Activity activity) + { + return activity.OperationName switch { - return activity.OperationName switch - { - OperationName.Transport.Send => ActivityKind.Producer, - OperationName.Transport.Receive => ActivityKind.Consumer, - OperationName.Consumer.Consume => ActivityKind.Internal, - OperationName.Consumer.Handle => ActivityKind.Internal, - _ => activity.Kind, - }; - } + OperationName.Transport.Send => ActivityKind.Producer, + OperationName.Transport.Receive => ActivityKind.Consumer, + OperationName.Consumer.Consume => ActivityKind.Internal, + OperationName.Consumer.Handle => ActivityKind.Internal, + _ => activity.Kind, + }; + } - private void TransformMassTransitTags(Activity activity) + private void TransformMassTransitTags(Activity activity) + { + if (activity.OperationName == OperationName.Transport.Send) { - if (activity.OperationName == OperationName.Transport.Send) - { - this.ProcessHostInfo(activity); + this.ProcessHostInfo(activity); - this.RenameTag(activity, TagName.MessageId, SemanticConventions.AttributeMessagingMessageId); - this.RenameTag(activity, TagName.ConversationId, SemanticConventions.AttributeMessagingConversationId); - this.RenameTag(activity, TagName.InitiatorId, MassTransitSemanticConventions.AttributeMessagingMassTransitInitiatorId); - this.RenameTag(activity, TagName.CorrelationId, MassTransitSemanticConventions.AttributeMessagingMassTransitCorrelationId); + this.RenameTag(activity, TagName.MessageId, SemanticConventions.AttributeMessagingMessageId); + this.RenameTag(activity, TagName.ConversationId, SemanticConventions.AttributeMessagingConversationId); + this.RenameTag(activity, TagName.InitiatorId, MassTransitSemanticConventions.AttributeMessagingMassTransitInitiatorId); + this.RenameTag(activity, TagName.CorrelationId, MassTransitSemanticConventions.AttributeMessagingMassTransitCorrelationId); - activity.SetTag(TagName.SourceAddress, null); - } - else if (activity.OperationName == OperationName.Transport.Receive) - { - this.ProcessHostInfo(activity); + activity.SetTag(TagName.SourceAddress, null); + } + else if (activity.OperationName == OperationName.Transport.Receive) + { + this.ProcessHostInfo(activity); - this.RenameTag(activity, TagName.MessageId, SemanticConventions.AttributeMessagingMessageId); - this.RenameTag(activity, TagName.ConversationId, SemanticConventions.AttributeMessagingConversationId); - this.RenameTag(activity, TagName.InitiatorId, MassTransitSemanticConventions.AttributeMessagingMassTransitInitiatorId); - this.RenameTag(activity, TagName.CorrelationId, MassTransitSemanticConventions.AttributeMessagingMassTransitCorrelationId); + this.RenameTag(activity, TagName.MessageId, SemanticConventions.AttributeMessagingMessageId); + this.RenameTag(activity, TagName.ConversationId, SemanticConventions.AttributeMessagingConversationId); + this.RenameTag(activity, TagName.InitiatorId, MassTransitSemanticConventions.AttributeMessagingMassTransitInitiatorId); + this.RenameTag(activity, TagName.CorrelationId, MassTransitSemanticConventions.AttributeMessagingMassTransitCorrelationId); - activity.SetTag(TagName.MessageId, null); + activity.SetTag(TagName.MessageId, null); - activity.SetTag(TagName.MessageTypes, null); - activity.SetTag(TagName.SourceAddress, null); - activity.SetTag(TagName.SourceHostMachine, null); - } - else if (activity.OperationName == OperationName.Consumer.Consume) + activity.SetTag(TagName.MessageTypes, null); + activity.SetTag(TagName.SourceAddress, null); + activity.SetTag(TagName.SourceHostMachine, null); + } + else if (activity.OperationName == OperationName.Consumer.Consume) + { + this.RenameTag(activity, TagName.ConsumerType, MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType); + } + else if (activity.OperationName == OperationName.Consumer.Handle) + { + } + + activity.SetTag(TagName.SpanKind, null); + activity.SetTag(TagName.PeerService, null); + activity.SetTag(TagName.PeerAddress, null); + activity.SetTag(TagName.PeerHost, null); + } + + private void ProcessHostInfo(Activity activity) + { + if (Uri.TryCreate(activity.GetTagValue(TagName.DestinationAddress).ToString(), UriKind.Absolute, out var destinationAddress)) + { + activity.SetTag(SemanticConventions.AttributeMessagingSystem, destinationAddress.Scheme); + activity.SetTag(SemanticConventions.AttributeMessagingDestination, destinationAddress.LocalPath); + + var uriHostNameType = Uri.CheckHostName(destinationAddress.Host); + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) { - this.RenameTag(activity, TagName.ConsumerType, MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType); + activity.SetTag(SemanticConventions.AttributeNetPeerIp, destinationAddress.Host); } - else if (activity.OperationName == OperationName.Consumer.Handle) + else { + activity.SetTag(SemanticConventions.AttributeNetPeerName, destinationAddress.Host); } - activity.SetTag(TagName.SpanKind, null); - activity.SetTag(TagName.PeerService, null); - activity.SetTag(TagName.PeerAddress, null); - activity.SetTag(TagName.PeerHost, null); - } - - private void ProcessHostInfo(Activity activity) - { - if (Uri.TryCreate(activity.GetTagValue(TagName.DestinationAddress).ToString(), UriKind.Absolute, out var destinationAddress)) + if (destinationAddress.Port > 0) { - activity.SetTag(SemanticConventions.AttributeMessagingSystem, destinationAddress.Scheme); - activity.SetTag(SemanticConventions.AttributeMessagingDestination, destinationAddress.LocalPath); - - var uriHostNameType = Uri.CheckHostName(destinationAddress.Host); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - activity.SetTag(SemanticConventions.AttributeNetPeerIp, destinationAddress.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeNetPeerName, destinationAddress.Host); - } - - if (destinationAddress.Port > 0) - { - activity.SetTag(SemanticConventions.AttributeNetPeerPort, destinationAddress.Port); - } - - activity.SetTag(TagName.DestinationAddress, null); + activity.SetTag(SemanticConventions.AttributeNetPeerPort, destinationAddress.Port); } - } - private string GetTag(IEnumerable> tags, string tagName) - { - var tag = tags.SingleOrDefault(kv => kv.Key == tagName); - return tag.Value; + activity.SetTag(TagName.DestinationAddress, null); } + } - private void RenameTag(Activity activity, string oldTagName, string newTagName) - { - activity.SetTag(newTagName, activity.GetTagValue(oldTagName)); - activity.SetTag(oldTagName, null); - } + private string GetTag(IEnumerable> tags, string tagName) + { + var tag = tags.SingleOrDefault(kv => kv.Key == tagName); + return tag.Value; + } + + private void RenameTag(Activity activity, string oldTagName, string newTagName) + { + activity.SetTag(newTagName, activity.GetTagValue(oldTagName)); + activity.SetTag(oldTagName, null); } } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs index 8df2fe8abe..650b30d612 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs @@ -18,35 +18,34 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-MassTransit")] +internal class MassTransitInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-MassTransit")] - internal class MassTransitInstrumentationEventSource : EventSource - { - public static MassTransitInstrumentationEventSource Log = new MassTransitInstrumentationEventSource(); + public static MassTransitInstrumentationEventSource Log = new MassTransitInstrumentationEventSource(); - [Event(1, Message = "Request is filtered out.", Level = EventLevel.Verbose)] - public void RequestIsFilteredOut(string eventName) - { - this.WriteEvent(1, eventName); - } + [Event(1, Message = "Request is filtered out.", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut(string eventName) + { + this.WriteEvent(1, eventName); + } - [NonEvent] - public void EnrichmentException(Exception ex) + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.EnrichmentException(ex.ToInvariantString()); - } + this.EnrichmentException(ex.ToInvariantString()); } + } - [Event(2, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] - public void EnrichmentException(string exception) - { - this.WriteEvent(2, exception); - } + [Event(2, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(2, exception); } } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs index ffa89d3bd6..b943bb077f 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs @@ -14,12 +14,11 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; + +internal class MassTransitSemanticConventions { - internal class MassTransitSemanticConventions - { - public const string AttributeMessagingMassTransitInitiatorId = "messaging.masstransit.initiator_id"; - public const string AttributeMessagingMassTransitCorrelationId = "messaging.masstransit.correlation_id"; - public const string AttributeMessagingMassTransitConsumerType = "messaging.masstransit.consumer_type"; - } + public const string AttributeMessagingMassTransitInitiatorId = "messaging.masstransit.initiator_id"; + public const string AttributeMessagingMassTransitCorrelationId = "messaging.masstransit.correlation_id"; + public const string AttributeMessagingMassTransitConsumerType = "messaging.masstransit.consumer_type"; } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs index 3cf2d93d06..63d28c63e3 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs @@ -14,27 +14,26 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation +namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; + +internal class TagName { - internal class TagName - { - public const string SpanKind = "span.kind"; + public const string SpanKind = "span.kind"; - public const string PeerAddress = "peer.address"; - public const string PeerHost = "peer.host"; - public const string PeerService = "peer.service"; - public const string SourceHostMachine = "source-host-machine"; + public const string PeerAddress = "peer.address"; + public const string PeerHost = "peer.host"; + public const string PeerService = "peer.service"; + public const string SourceHostMachine = "source-host-machine"; - public const string MessageId = "message-id"; - public const string ConversationId = "conversation-id"; - public const string CorrelationId = "correlation-id"; - public const string InitiatorId = "initiator-id"; + public const string MessageId = "message-id"; + public const string ConversationId = "conversation-id"; + public const string CorrelationId = "correlation-id"; + public const string InitiatorId = "initiator-id"; - public const string ConsumerType = "consumer-type"; - public const string MessageTypes = "message-types"; + public const string ConsumerType = "consumer-type"; + public const string MessageTypes = "message-types"; - public const string DestinationAddress = "destination-address"; - public const string SourceAddress = "source-address"; - public const string InputAddress = "input-address"; - } + public const string DestinationAddress = "destination-address"; + public const string SourceAddress = "source-address"; + public const string InputAddress = "input-address"; } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs index a61007c214..5d674d51fd 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs @@ -17,31 +17,30 @@ using System; using OpenTelemetry.Instrumentation.MassTransit.Implementation; -namespace OpenTelemetry.Instrumentation.MassTransit +namespace OpenTelemetry.Instrumentation.MassTransit; + +internal class MassTransitInstrumentation : IDisposable { - internal class MassTransitInstrumentation : IDisposable - { - internal const string MassTransitDiagnosticListenerName = "MassTransit"; + internal const string MassTransitDiagnosticListenerName = "MassTransit"; - private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - /// - /// Initializes a new instance of the class. - /// - /// Instrumentation options. - public MassTransitInstrumentation(MassTransitInstrumentationOptions options) - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( - name => new MassTransitDiagnosticListener(name, options), - listener => listener.Name == MassTransitDiagnosticListenerName, - null); - this.diagnosticSourceSubscriber.Subscribe(); - } + /// + /// Initializes a new instance of the class. + /// + /// Instrumentation options. + public MassTransitInstrumentation(MassTransitInstrumentationOptions options) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( + name => new MassTransitDiagnosticListener(name, options), + listener => listener.Name == MassTransitDiagnosticListenerName, + null); + this.diagnosticSourceSubscriber.Subscribe(); + } - /// - public void Dispose() - { - this.diagnosticSourceSubscriber?.Dispose(); - } + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs index 5ffca9abe7..bf98c06d8a 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs @@ -16,27 +16,26 @@ using System.Collections.Generic; -namespace OpenTelemetry.Instrumentation.MassTransit +namespace OpenTelemetry.Instrumentation.MassTransit; + +/// +/// Options for . +/// +public class MassTransitInstrumentationOptions { /// - /// Options for . + /// Default traced operations. /// - public class MassTransitInstrumentationOptions + public static readonly IEnumerable DefaultTracedOperations = new string[] { - /// - /// Default traced operations. - /// - public static readonly IEnumerable DefaultTracedOperations = new string[] - { - OperationName.Transport.Send, - OperationName.Transport.Receive, - OperationName.Consumer.Consume, - OperationName.Consumer.Handle, - }; + OperationName.Transport.Send, + OperationName.Transport.Receive, + OperationName.Consumer.Consume, + OperationName.Consumer.Handle, + }; - /// - /// Gets or sets traced operations set. - /// - public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); - } + /// + /// Gets or sets traced operations set. + /// + public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs index 5a04f5c95b..92081d0696 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs @@ -14,43 +14,42 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.MassTransit +namespace OpenTelemetry.Instrumentation.MassTransit; + +/// +/// MassTransit diagnostic source operation name constants. +/// +public static class OperationName { /// - /// MassTransit diagnostic source operation name constants. + /// MassTransit Transport category constants. /// - public static class OperationName + public static class Transport { /// - /// MassTransit Transport category constants. + /// MassTransit send diagnostic source operation name. /// - public static class Transport - { - /// - /// MassTransit send diagnostic source operation name. - /// - public const string Send = "MassTransit.Transport.Send"; + public const string Send = "MassTransit.Transport.Send"; - /// - /// MassTransit receive diagnostic source operation name. - /// - public const string Receive = "MassTransit.Transport.Receive"; - } + /// + /// MassTransit receive diagnostic source operation name. + /// + public const string Receive = "MassTransit.Transport.Receive"; + } + /// + /// MassTransit Consumer category constants. + /// + public static class Consumer + { /// - /// MassTransit Consumer category constants. + /// MassTransit consume diagnostic source operation name. /// - public static class Consumer - { - /// - /// MassTransit consume diagnostic source operation name. - /// - public const string Consume = "MassTransit.Consumer.Consume"; + public const string Consume = "MassTransit.Consumer.Consume"; - /// - /// MassTransit handle diagnostic source operation name. - /// - public const string Handle = "MassTransit.Consumer.Handle"; - } + /// + /// MassTransit handle diagnostic source operation name. + /// + public const string Handle = "MassTransit.Consumer.Handle"; } } diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs index 39e40e8664..95feb345ac 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs @@ -25,340 +25,339 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.MassTransit.Tests +namespace OpenTelemetry.Instrumentation.MassTransit.Tests; + +public class MassTransitInstrumentationTests { - public class MassTransitInstrumentationTests + [Fact] + public async Task ShouldMapMassTransitTagsForPublishMessageToOpenTelemetrySpecification() { - [Fact] - public async Task ShouldMapMassTransitTagsForPublishMessageToOpenTelemetrySpecification() + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation() + .Build()) { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); + await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); + } + finally + { + await harness.Stop(); + } - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Transport.Send).LastOrDefault(); + var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; + var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Transport.Send).LastOrDefault(); - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); + Assert.NotNull(actualActivity); + Assert.NotNull(expectedMessageContext); - Assert.Equal("/input_queue send", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Producer, actualActivity.Kind); - Assert.Equal("loopback", actualActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)?.ToString()); + Assert.Equal("/input_queue send", actualActivity.DisplayName); + Assert.Equal(ActivityKind.Producer, actualActivity.Kind); + Assert.Equal("loopback", actualActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)?.ToString()); - Assert.Equal(expectedMessageContext.MessageId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingMessageId)?.ToString()); - Assert.Equal(expectedMessageContext.ConversationId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingConversationId)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.AbsolutePath, actualActivity.GetTagValue(SemanticConventions.AttributeMessagingDestination)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.Host, actualActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)?.ToString()); + Assert.Equal(expectedMessageContext.MessageId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingMessageId)?.ToString()); + Assert.Equal(expectedMessageContext.ConversationId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingConversationId)?.ToString()); + Assert.Equal(expectedMessageContext.DestinationAddress.AbsolutePath, actualActivity.GetTagValue(SemanticConventions.AttributeMessagingDestination)?.ToString()); + Assert.Equal(expectedMessageContext.DestinationAddress.Host, actualActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)?.ToString()); - Assert.Null(actualActivity.GetTagValue(TagName.MessageId)); - Assert.Null(actualActivity.GetTagValue(TagName.ConversationId)); - Assert.Null(actualActivity.GetTagValue(TagName.DestinationAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.MessageId)); + Assert.Null(actualActivity.GetTagValue(TagName.ConversationId)); + Assert.Null(actualActivity.GetTagValue(TagName.DestinationAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); + Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - Assert.Null(actualActivity.GetTagValue(TagName.SourceAddress)); - } + Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); + Assert.Null(actualActivity.GetTagValue(TagName.SourceAddress)); } + } - [Fact] - public async Task ShouldMapMassTransitTagsForReceiveMessageToOpenTelemetrySpecification() + [Fact] + public async Task ShouldMapMassTransitTagsForReceiveMessageToOpenTelemetrySpecification() + { + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation() + .Build()) { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); + await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); + } + finally + { + await harness.Stop(); + } - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Transport.Receive).LastOrDefault(); + var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; + var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Transport.Receive).LastOrDefault(); - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); + Assert.NotNull(actualActivity); + Assert.NotNull(expectedMessageContext); - Assert.Equal("/input_queue consume", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Consumer, actualActivity.Kind); - Assert.Equal("loopback", actualActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)?.ToString()); + Assert.Equal("/input_queue consume", actualActivity.DisplayName); + Assert.Equal(ActivityKind.Consumer, actualActivity.Kind); + Assert.Equal("loopback", actualActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)?.ToString()); - Assert.Equal(expectedMessageContext.MessageId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingMessageId)?.ToString()); - Assert.Equal(expectedMessageContext.ConversationId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingConversationId)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.AbsolutePath, actualActivity.GetTagValue(SemanticConventions.AttributeMessagingDestination)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.Host, actualActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)?.ToString()); + Assert.Equal(expectedMessageContext.MessageId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingMessageId)?.ToString()); + Assert.Equal(expectedMessageContext.ConversationId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingConversationId)?.ToString()); + Assert.Equal(expectedMessageContext.DestinationAddress.AbsolutePath, actualActivity.GetTagValue(SemanticConventions.AttributeMessagingDestination)?.ToString()); + Assert.Equal(expectedMessageContext.DestinationAddress.Host, actualActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)?.ToString()); - Assert.Null(actualActivity.GetTagValue(TagName.MessageId)); - Assert.Null(actualActivity.GetTagValue(TagName.ConversationId)); - Assert.Null(actualActivity.GetTagValue(TagName.DestinationAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.MessageId)); + Assert.Null(actualActivity.GetTagValue(TagName.ConversationId)); + Assert.Null(actualActivity.GetTagValue(TagName.DestinationAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); + Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - Assert.Null(actualActivity.GetTagValue(TagName.MessageTypes)); - Assert.Null(actualActivity.GetTagValue(TagName.SourceAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.SourceHostMachine)); - } + Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); + Assert.Null(actualActivity.GetTagValue(TagName.MessageTypes)); + Assert.Null(actualActivity.GetTagValue(TagName.SourceAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.SourceHostMachine)); } + } - [Fact] - public async Task ShouldMapMassTransitTagsForConsumeMessageToOpenTelemetrySpecification() + [Fact] + public async Task ShouldMapMassTransitTagsForConsumeMessageToOpenTelemetrySpecification() + { + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation() + .Build()) { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); + await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); + } + finally + { + await harness.Stop(); + } - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Consumer.Consume).LastOrDefault(); + var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; + var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Consumer.Consume).LastOrDefault(); - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); - Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer process", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Internal, actualActivity.Kind); - Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer", actualActivity.GetTagValue(MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType)?.ToString()); + Assert.NotNull(actualActivity); + Assert.NotNull(expectedMessageContext); + Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer process", actualActivity.DisplayName); + Assert.Equal(ActivityKind.Internal, actualActivity.Kind); + Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer", actualActivity.GetTagValue(MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType)?.ToString()); - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); + Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - } + Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); } + } - [Fact] - public async Task ShouldMapMassTransitTagsForHandleMessageToOpenTelemetrySpecification() + [Fact] + public async Task ShouldMapMassTransitTagsForHandleMessageToOpenTelemetrySpecification() + { + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation() + .Build()) { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); + await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); + } + finally + { + await harness.Stop(); + } - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Consumer.Handle).LastOrDefault(); + var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; + var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Consumer.Handle).LastOrDefault(); - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); - Assert.Equal("TestMessage/OpenTelemetry.Instrumentation.MassTransit.Tests process", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Internal, actualActivity.Kind); + Assert.NotNull(actualActivity); + Assert.NotNull(expectedMessageContext); + Assert.Equal("TestMessage/OpenTelemetry.Instrumentation.MassTransit.Tests process", actualActivity.DisplayName); + Assert.Equal(ActivityKind.Internal, actualActivity.Kind); - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); + Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - } + Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); + Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); } + } - [Theory] - [InlineData(OperationName.Consumer.Consume)] - [InlineData(OperationName.Consumer.Handle)] - [InlineData(OperationName.Transport.Send)] - [InlineData(OperationName.Transport.Receive)] - public async Task MassTransitInstrumentationTestOptions(string operationName) + [Theory] + [InlineData(OperationName.Consumer.Consume)] + [InlineData(OperationName.Consumer.Handle)] + [InlineData(OperationName.Transport.Send)] + [InlineData(OperationName.Transport.Receive)] + public async Task MassTransitInstrumentationTestOptions(string operationName) + { + using Activity activity = new Activity("Parent"); + activity.SetParentId( + ActivityTraceId.CreateRandom(), + ActivitySpanId.CreateRandom(), + ActivityTraceFlags.Recorded); + activity.Start(); + + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation(o => + o.TracedOperations = new HashSet(new[] { operationName })) + .Build()) { - using Activity activity = new Activity("Parent"); - activity.SetParentId( - ActivityTraceId.CreateRandom(), - ActivitySpanId.CreateRandom(), - ActivityTraceFlags.Recorded); - activity.Start(); - - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation(o => - o.TracedOperations = new HashSet(new[] { operationName })) - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try + await harness.InputQueueSendEndpoint.Send(new { - await harness.InputQueueSendEndpoint.Send(new - { - Text = "Hello, world!", - }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } + Text = "Hello, world!", + }); + + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); } + finally + { + await harness.Stop(); + } + } - Assert.Equal(8, activityProcessor.Invocations.Count); + Assert.Equal(8, activityProcessor.Invocations.Count); - var consumes = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, operationName); + var consumes = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, operationName); - Assert.Single(consumes); - } + Assert.Single(consumes); + } - [Fact] - public async Task ShouldMapMassTransitTagsWhenIntrumentationIsSuppressed() + [Fact] + public async Task ShouldMapMassTransitTagsWhenIntrumentationIsSuppressed() + { + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation() + .Build()) { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + using var scope = SuppressInstrumentationScope.Begin(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - using var scope = SuppressInstrumentationScope.Begin(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); + await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - Assert.NotNull(expectedMessageContext); + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); + } + finally + { + await harness.Stop(); } - // Since instrumentation is suppressed, activiy is not emitted - Assert.Equal(3, activityProcessor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose - - // Processor.OnStart and Processor.OnEnd are not called - Assert.DoesNotContain(activityProcessor.Invocations, invo => invo.Method.Name == nameof(activityProcessor.Object.OnStart)); - Assert.DoesNotContain(activityProcessor.Invocations, invo => invo.Method.Name == nameof(activityProcessor.Object.OnEnd)); + var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; + Assert.NotNull(expectedMessageContext); } - [Theory] - [InlineData(SamplingDecision.Drop, false)] - [InlineData(SamplingDecision.RecordOnly, true)] - [InlineData(SamplingDecision.RecordAndSample, true)] - public async Task ShouldMapMassTransitTagsWhenIntrumentationWhenSampled(SamplingDecision samplingDecision, bool isActivityExpected) + // Since instrumentation is suppressed, activiy is not emitted + Assert.Equal(3, activityProcessor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose + + // Processor.OnStart and Processor.OnEnd are not called + Assert.DoesNotContain(activityProcessor.Invocations, invo => invo.Method.Name == nameof(activityProcessor.Object.OnStart)); + Assert.DoesNotContain(activityProcessor.Invocations, invo => invo.Method.Name == nameof(activityProcessor.Object.OnEnd)); + } + + [Theory] + [InlineData(SamplingDecision.Drop, false)] + [InlineData(SamplingDecision.RecordOnly, true)] + [InlineData(SamplingDecision.RecordAndSample, true)] + public async Task ShouldMapMassTransitTagsWhenIntrumentationWhenSampled(SamplingDecision samplingDecision, bool isActivityExpected) + { + var activityProcessor = new Mock>(); + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) + .AddProcessor(activityProcessor.Object) + .AddMassTransitInstrumentation() + .Build()) { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) + var harness = new InMemoryTestHarness(); + var consumerHarness = harness.Consumer(); + var handlerHarness = harness.Handler(); + await harness.Start(); + try { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } + await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - Assert.NotNull(expectedMessageContext); + Assert.True(await harness.Consumed.SelectAsync().Any()); + Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); + Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); + } + finally + { + await harness.Stop(); } - Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invo => invo.Method.Name == nameof(activityProcessor.Object.OnStart))); - Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invo => invo.Method.Name == nameof(activityProcessor.Object.OnEnd))); + var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; + Assert.NotNull(expectedMessageContext); } - private IEnumerable GetActivitiesFromInvocationsByOperationName(IEnumerable invocations, string operationName) - { - return - invocations - .Where(i => - i.Arguments.OfType() - .Any(a => a.OperationName == operationName)) - .Where(i => i.Method.Name == "OnEnd") - .Select(i => i.Arguments.OfType().Single()); - } + Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invo => invo.Method.Name == nameof(activityProcessor.Object.OnStart))); + Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invo => invo.Method.Name == nameof(activityProcessor.Object.OnEnd))); + } + + private IEnumerable GetActivitiesFromInvocationsByOperationName(IEnumerable invocations, string operationName) + { + return + invocations + .Where(i => + i.Arguments.OfType() + .Any(a => a.OperationName == operationName)) + .Where(i => i.Method.Name == "OnEnd") + .Select(i => i.Arguments.OfType().Single()); } } diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs index 5c1bbd8543..9b6d834054 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs @@ -17,13 +17,12 @@ using System.Threading.Tasks; using MassTransit; -namespace OpenTelemetry.Instrumentation.MassTransit.Tests +namespace OpenTelemetry.Instrumentation.MassTransit.Tests; + +public class TestConsumer : IConsumer { - public class TestConsumer : IConsumer + public Task Consume(ConsumeContext context) { - public Task Consume(ConsumeContext context) - { - return Task.CompletedTask; - } + return Task.CompletedTask; } } diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs index aead15ec12..5c29747ed6 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs @@ -14,10 +14,9 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.MassTransit.Tests +namespace OpenTelemetry.Instrumentation.MassTransit.Tests; + +public class TestMessage { - public class TestMessage - { - public string Text; - } + public string Text; } From 485409ec18cdab482482fd532b28b5a304c6de20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 Aug 2022 19:37:25 +0200 Subject: [PATCH 0281/1499] [Instrumenation.GrpcCore] File scoped namespace (#575) --- .../AsyncStreamReaderProxy.cs | 127 ++- .../ClientStreamWriterProxy.cs | 145 ++-- .../ClientTracingInterceptor.cs | 605 +++++++------ .../ClientTracingInterceptorOptions.cs | 39 +- .../Extensions.cs | 45 +- .../GrpcCoreInstrumentation.cs | 49 +- .../RpcScope.cs | 347 ++++---- .../SemanticConventions.cs | 37 +- .../ServerStreamWriterProxy.cs | 87 +- .../ServerTracingInterceptor.cs | 335 ++++--- .../ServerTracingInterceptorOptions.cs | 39 +- .../TracerProviderBuilderExtensions.cs | 33 +- .../FoobarService.cs | 409 +++++---- .../GrpcCoreClientInterceptorTests.cs | 821 +++++++++--------- .../GrpcCoreServerInterceptorTests.cs | 255 +++--- .../InterceptorActivityListener.cs | 83 +- 16 files changed, 1720 insertions(+), 1736 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index fdeb782a55..cc4b603d14 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -14,84 +14,83 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using global::Grpc.Core; +using System; +using System.Threading; +using System.Threading.Tasks; +using global::Grpc.Core; + +namespace OpenTelemetry.Instrumentation.GrpcCore; +/// +/// A proxy stream reader with callbacks for interesting events. +/// +/// +/// Borrowed heavily from +/// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingAsyncStreamReader.cs. +/// +/// The message type. +/// +internal class AsyncStreamReaderProxy : IAsyncStreamReader +{ /// - /// A proxy stream reader with callbacks for interesting events. + /// The reader. /// - /// - /// Borrowed heavily from - /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingAsyncStreamReader.cs. - /// - /// The message type. - /// - internal class AsyncStreamReaderProxy : IAsyncStreamReader - { - /// - /// The reader. - /// - private readonly IAsyncStreamReader reader; + private readonly IAsyncStreamReader reader; - /// - /// The on message action. - /// - private readonly Action onMessage; + /// + /// The on message action. + /// + private readonly Action onMessage; - /// - /// The on stream end action. - /// - private readonly Action onStreamEnd; + /// + /// The on stream end action. + /// + private readonly Action onStreamEnd; - /// - /// The on exception action. - /// - private readonly Action onException; + /// + /// The on exception action. + /// + private readonly Action onException; - /// - /// Initializes a new instance of the class. - /// - /// The reader. - /// The on message action, if any. - /// The on stream end action, if any. - /// The on exception action, if any. - public AsyncStreamReaderProxy(IAsyncStreamReader reader, Action onMessage = null, Action onStreamEnd = null, Action onException = null) - { - this.reader = reader; - this.onMessage = onMessage; - this.onStreamEnd = onStreamEnd; - this.onException = onException; - } + /// + /// Initializes a new instance of the class. + /// + /// The reader. + /// The on message action, if any. + /// The on stream end action, if any. + /// The on exception action, if any. + public AsyncStreamReaderProxy(IAsyncStreamReader reader, Action onMessage = null, Action onStreamEnd = null, Action onException = null) + { + this.reader = reader; + this.onMessage = onMessage; + this.onStreamEnd = onStreamEnd; + this.onException = onException; + } - /// - public T Current => this.reader.Current; + /// + public T Current => this.reader.Current; - /// - public async Task MoveNext(CancellationToken cancellationToken) + /// + public async Task MoveNext(CancellationToken cancellationToken) + { + try { - try + var hasNext = await this.reader.MoveNext(cancellationToken).ConfigureAwait(false); + if (hasNext) { - var hasNext = await this.reader.MoveNext(cancellationToken).ConfigureAwait(false); - if (hasNext) - { - this.onMessage?.Invoke(this.Current); - } - else - { - this.onStreamEnd?.Invoke(); - } - - return hasNext; + this.onMessage?.Invoke(this.Current); } - catch (Exception ex) + else { - this.onException?.Invoke(ex); - throw; + this.onStreamEnd?.Invoke(); } + + return hasNext; + } + catch (Exception ex) + { + this.onException?.Invoke(ex); + throw; } } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index ae0e3b05bb..95fa3f69fb 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -14,95 +14,94 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore +using System; +using System.Threading.Tasks; +using global::Grpc.Core; + +namespace OpenTelemetry.Instrumentation.GrpcCore; + +/// +/// A proxy client stream writer. +/// +/// +/// Borrowed heavily from +/// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingClientStreamWriter.cs. +/// +/// The message type. +/// +internal class ClientStreamWriterProxy : IClientStreamWriter { - using System; - using System.Threading.Tasks; - using global::Grpc.Core; + /// + /// The writer. + /// + private readonly IClientStreamWriter writer; /// - /// A proxy client stream writer. + /// The on write action. /// - /// - /// Borrowed heavily from - /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingClientStreamWriter.cs. - /// - /// The message type. - /// - internal class ClientStreamWriterProxy : IClientStreamWriter - { - /// - /// The writer. - /// - private readonly IClientStreamWriter writer; + private readonly Action onWrite; - /// - /// The on write action. - /// - private readonly Action onWrite; + /// + /// The on complete action. + /// + private readonly Action onComplete; - /// - /// The on complete action. - /// - private readonly Action onComplete; + /// + /// The on exception action. + /// + private readonly Action onException; - /// - /// The on exception action. - /// - private readonly Action onException; + /// + /// Initializes a new instance of the class. + /// + /// The writer. + /// The on write action if any. + /// The on complete action, if any. + /// The on exception action, if any. + public ClientStreamWriterProxy(IClientStreamWriter writer, Action onWrite = null, Action onComplete = null, Action onException = null) + { + this.writer = writer; + this.onWrite = onWrite; + this.onComplete = onComplete; + this.onException = onException; + } - /// - /// Initializes a new instance of the class. - /// - /// The writer. - /// The on write action if any. - /// The on complete action, if any. - /// The on exception action, if any. - public ClientStreamWriterProxy(IClientStreamWriter writer, Action onWrite = null, Action onComplete = null, Action onException = null) + /// + public WriteOptions WriteOptions + { + get => this.writer.WriteOptions; + set => this.writer.WriteOptions = value; + } + + /// + public async Task WriteAsync(T message) + { + this.onWrite?.Invoke(message); + + try { - this.writer = writer; - this.onWrite = onWrite; - this.onComplete = onComplete; - this.onException = onException; + await this.writer.WriteAsync(message).ConfigureAwait(false); } - - /// - public WriteOptions WriteOptions + catch (Exception e) { - get => this.writer.WriteOptions; - set => this.writer.WriteOptions = value; + this.onException?.Invoke(e); + throw; } + } - /// - public async Task WriteAsync(T message) - { - this.onWrite?.Invoke(message); + /// + public async Task CompleteAsync() + { + this.onComplete?.Invoke(); - try - { - await this.writer.WriteAsync(message).ConfigureAwait(false); - } - catch (Exception e) - { - this.onException?.Invoke(e); - throw; - } + try + { + await this.writer.CompleteAsync().ConfigureAwait(false); } - - /// - public async Task CompleteAsync() + catch (Exception e) { - this.onComplete?.Invoke(); - - try - { - await this.writer.CompleteAsync().ConfigureAwait(false); - } - catch (Exception e) - { - this.onException?.Invoke(e); - throw; - } + this.onException?.Invoke(e); + throw; } } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 5bef4540ba..72716be951 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -14,350 +14,349 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore +using System; +using System.Collections.Generic; +using System.Diagnostics; +using global::Grpc.Core; +using global::Grpc.Core.Interceptors; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.GrpcCore; + +/// +/// A client interceptor that starts and stops an Activity for each outbound RPC. +/// +/// +public class ClientTracingInterceptor : Interceptor { - using System; - using System.Collections.Generic; - using System.Diagnostics; - using global::Grpc.Core; - using global::Grpc.Core.Interceptors; - using OpenTelemetry.Context.Propagation; - using OpenTelemetry.Internal; + /// + /// The options. + /// + private readonly ClientTracingInterceptorOptions options; /// - /// A client interceptor that starts and stops an Activity for each outbound RPC. + /// Initializes a new instance of the class. /// - /// - public class ClientTracingInterceptor : Interceptor + /// The options. + public ClientTracingInterceptor(ClientTracingInterceptorOptions options) { - /// - /// The options. - /// - private readonly ClientTracingInterceptorOptions options; + Guard.ThrowIfNull(options); - /// - /// Initializes a new instance of the class. - /// - /// The options. - public ClientTracingInterceptor(ClientTracingInterceptorOptions options) - { - Guard.ThrowIfNull(options); + this.options = options; + } - this.options = options; - } + /// + public override TResponse BlockingUnaryCall( + TRequest request, + ClientInterceptorContext context, + BlockingUnaryCallContinuation continuation) + { + ClientRpcScope rpcScope = null; - /// - public override TResponse BlockingUnaryCall( - TRequest request, - ClientInterceptorContext context, - BlockingUnaryCallContinuation continuation) + try { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - rpcScope.RecordRequest(request); - var response = continuation(request, rpcScope.Context); - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - rpcScope?.Dispose(); - } + rpcScope = new ClientRpcScope(context, this.options); + rpcScope.RecordRequest(request); + var response = continuation(request, rpcScope.Context); + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; } - - /// - public override AsyncUnaryCall AsyncUnaryCall( - TRequest request, - ClientInterceptorContext context, - AsyncUnaryCallContinuation continuation) + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally { - ClientRpcScope rpcScope = null; + rpcScope?.RestoreParentActivity(); + rpcScope?.Dispose(); + } + } - try - { - rpcScope = new ClientRpcScope(context, this.options); - rpcScope.RecordRequest(request); - var responseContinuation = continuation(request, rpcScope.Context); - var responseAsync = responseContinuation.ResponseAsync.ContinueWith( - responseTask => + /// + public override AsyncUnaryCall AsyncUnaryCall( + TRequest request, + ClientInterceptorContext context, + AsyncUnaryCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + rpcScope.RecordRequest(request); + var responseContinuation = continuation(request, rpcScope.Context); + var responseAsync = responseContinuation.ResponseAsync.ContinueWith( + responseTask => + { + try { - try - { - var response = responseTask.Result; - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (AggregateException ex) - { - rpcScope.CompleteWithException(ex.InnerException); - throw ex.InnerException; - } - }); - - return new AsyncUnaryCall( - responseAsync, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } + var response = responseTask.Result; + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (AggregateException ex) + { + rpcScope.CompleteWithException(ex.InnerException); + throw ex.InnerException; + } + }); + + return new AsyncUnaryCall( + responseAsync, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); } - - /// - public override AsyncClientStreamingCall AsyncClientStreamingCall( - ClientInterceptorContext context, - AsyncClientStreamingCallContinuation continuation) + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally { - ClientRpcScope rpcScope = null; + rpcScope?.RestoreParentActivity(); + } + } - try - { - rpcScope = new ClientRpcScope(context, this.options); - var responseContinuation = continuation(rpcScope.Context); - var clientRequestStreamProxy = new ClientStreamWriterProxy( - responseContinuation.RequestStream, - rpcScope.RecordRequest, - onException: rpcScope.CompleteWithException); - - var responseAsync = responseContinuation.ResponseAsync.ContinueWith( - responseTask => + /// + public override AsyncClientStreamingCall AsyncClientStreamingCall( + ClientInterceptorContext context, + AsyncClientStreamingCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + var responseContinuation = continuation(rpcScope.Context); + var clientRequestStreamProxy = new ClientStreamWriterProxy( + responseContinuation.RequestStream, + rpcScope.RecordRequest, + onException: rpcScope.CompleteWithException); + + var responseAsync = responseContinuation.ResponseAsync.ContinueWith( + responseTask => + { + try { - try - { - var response = responseTask.Result; - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (AggregateException ex) - { - rpcScope.CompleteWithException(ex.InnerException); - throw ex.InnerException; - } - }); - - return new AsyncClientStreamingCall( - clientRequestStreamProxy, - responseAsync, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } + var response = responseTask.Result; + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (AggregateException ex) + { + rpcScope.CompleteWithException(ex.InnerException); + throw ex.InnerException; + } + }); + + return new AsyncClientStreamingCall( + clientRequestStreamProxy, + responseAsync, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); } - - /// - public override AsyncServerStreamingCall AsyncServerStreamingCall( - TRequest request, - ClientInterceptorContext context, - AsyncServerStreamingCallContinuation continuation) + catch (Exception e) { - ClientRpcScope rpcScope = null; - - try - { - rpcScope = new ClientRpcScope(context, this.options); - rpcScope.RecordRequest(request); - var responseContinuation = continuation(request, rpcScope.Context); - - var responseStreamProxy = new AsyncStreamReaderProxy( - responseContinuation.ResponseStream, - rpcScope.RecordResponse, - rpcScope.Complete, - rpcScope.CompleteWithException); - - return new AsyncServerStreamingCall( - responseStreamProxy, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); } + } + + /// + public override AsyncServerStreamingCall AsyncServerStreamingCall( + TRequest request, + ClientInterceptorContext context, + AsyncServerStreamingCallContinuation continuation) + { + ClientRpcScope rpcScope = null; - /// - public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall( - ClientInterceptorContext context, - AsyncDuplexStreamingCallContinuation continuation) + try + { + rpcScope = new ClientRpcScope(context, this.options); + rpcScope.RecordRequest(request); + var responseContinuation = continuation(request, rpcScope.Context); + + var responseStreamProxy = new AsyncStreamReaderProxy( + responseContinuation.ResponseStream, + rpcScope.RecordResponse, + rpcScope.Complete, + rpcScope.CompleteWithException); + + return new AsyncServerStreamingCall( + responseStreamProxy, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally { - ClientRpcScope rpcScope = null; + rpcScope?.RestoreParentActivity(); + } + } - try - { - rpcScope = new ClientRpcScope(context, this.options); - var responseContinuation = continuation(rpcScope.Context); - - var requestStreamProxy = new ClientStreamWriterProxy( - responseContinuation.RequestStream, - rpcScope.RecordRequest, - onException: rpcScope.CompleteWithException); - - var responseStreamProxy = new AsyncStreamReaderProxy( - responseContinuation.ResponseStream, - rpcScope.RecordResponse, - rpcScope.Complete, - rpcScope.CompleteWithException); - - return new AsyncDuplexStreamingCall( - requestStreamProxy, - responseStreamProxy, - responseContinuation.ResponseHeadersAsync, - responseContinuation.GetStatus, - responseContinuation.GetTrailers, - responseContinuation.WithBestEffortDispose(rpcScope)); - } - catch (Exception e) - { - rpcScope?.CompleteWithException(e); - throw; - } - finally - { - rpcScope?.RestoreParentActivity(); - } + /// + public override AsyncDuplexStreamingCall AsyncDuplexStreamingCall( + ClientInterceptorContext context, + AsyncDuplexStreamingCallContinuation continuation) + { + ClientRpcScope rpcScope = null; + + try + { + rpcScope = new ClientRpcScope(context, this.options); + var responseContinuation = continuation(rpcScope.Context); + + var requestStreamProxy = new ClientStreamWriterProxy( + responseContinuation.RequestStream, + rpcScope.RecordRequest, + onException: rpcScope.CompleteWithException); + + var responseStreamProxy = new AsyncStreamReaderProxy( + responseContinuation.ResponseStream, + rpcScope.RecordResponse, + rpcScope.Complete, + rpcScope.CompleteWithException); + + return new AsyncDuplexStreamingCall( + requestStreamProxy, + responseStreamProxy, + responseContinuation.ResponseHeadersAsync, + responseContinuation.GetStatus, + responseContinuation.GetTrailers, + responseContinuation.WithBestEffortDispose(rpcScope)); + } + catch (Exception e) + { + rpcScope?.CompleteWithException(e); + throw; + } + finally + { + rpcScope?.RestoreParentActivity(); } + } + + /// + /// A class to help track the lifetime of a client-side RPC. + /// + /// The type of the request. + /// The type of the response. + private sealed class ClientRpcScope : RpcScope + where TRequest : class + where TResponse : class + { + /// + /// The metadata setter action. + /// + private static readonly Action MetadataSetter = (metadata, key, value) => { metadata.Add(new Metadata.Entry(key, value)); }; /// - /// A class to help track the lifetime of a client-side RPC. + /// The context. /// - /// The type of the request. - /// The type of the response. - private sealed class ClientRpcScope : RpcScope - where TRequest : class - where TResponse : class + private readonly ClientInterceptorContext context; + + /// + /// The parent activity. + /// + private readonly Activity parentActivity; + + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// The options. + public ClientRpcScope(ClientInterceptorContext context, ClientTracingInterceptorOptions options) + : base(context.Method?.FullName, options.RecordMessageEvents) { - /// - /// The metadata setter action. - /// - private static readonly Action MetadataSetter = (metadata, key, value) => { metadata.Add(new Metadata.Entry(key, value)); }; - - /// - /// The context. - /// - private readonly ClientInterceptorContext context; - - /// - /// The parent activity. - /// - private readonly Activity parentActivity; - - /// - /// Initializes a new instance of the class. - /// - /// The context. - /// The options. - public ClientRpcScope(ClientInterceptorContext context, ClientTracingInterceptorOptions options) - : base(context.Method?.FullName, options.RecordMessageEvents) - { - this.context = context; + this.context = context; - // Capture the current activity. - this.parentActivity = Activity.Current; + // Capture the current activity. + this.parentActivity = Activity.Current; - // Short-circuit if nobody is listening - if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) - { - return; - } + // Short-circuit if nobody is listening + if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) + { + return; + } - // This if block is for unit testing only. - IEnumerable> customTags = null; - if (options.ActivityIdentifierValue != default) + // This if block is for unit testing only. + IEnumerable> customTags = null; + if (options.ActivityIdentifierValue != default) + { + customTags = new List> { - customTags = new List> - { - new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), - }; - } + new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), + }; + } - // We want to start an activity but don't activate it. - // After calling StartActivity, Activity.Current will be the new Activity. - // This scope is created synchronously before the RPC invocation starts and so this new Activity will overwrite - // the callers current Activity which isn't what we want. We need to restore the original immediately after doing this. - // If this call happened after some kind of async context await then a restore wouldn't be necessary. - // gRPC Core just doesn't have the hooks to do this as far as I can tell. - var rpcActivity = GrpcCoreInstrumentation.ActivitySource.StartActivity( - this.FullServiceName, - ActivityKind.Client, - this.parentActivity == default ? default : this.parentActivity.Context, - tags: customTags); - - if (rpcActivity == null) - { - return; - } + // We want to start an activity but don't activate it. + // After calling StartActivity, Activity.Current will be the new Activity. + // This scope is created synchronously before the RPC invocation starts and so this new Activity will overwrite + // the callers current Activity which isn't what we want. We need to restore the original immediately after doing this. + // If this call happened after some kind of async context await then a restore wouldn't be necessary. + // gRPC Core just doesn't have the hooks to do this as far as I can tell. + var rpcActivity = GrpcCoreInstrumentation.ActivitySource.StartActivity( + this.FullServiceName, + ActivityKind.Client, + this.parentActivity == default ? default : this.parentActivity.Context, + tags: customTags); + + if (rpcActivity == null) + { + return; + } - var callOptions = context.Options; + var callOptions = context.Options; - // Do NOT mutate incoming call headers, make a new copy. - // Retry mechanisms that may sit above this interceptor rely on an original set of call headers. - var metadata = new Metadata(); - if (callOptions.Headers != null) + // Do NOT mutate incoming call headers, make a new copy. + // Retry mechanisms that may sit above this interceptor rely on an original set of call headers. + var metadata = new Metadata(); + if (callOptions.Headers != null) + { + for (var i = 0; i < callOptions.Headers.Count; i++) { - for (var i = 0; i < callOptions.Headers.Count; i++) - { - metadata.Add(callOptions.Headers[i]); - } + metadata.Add(callOptions.Headers[i]); } + } - // replace the CallOptions - callOptions = callOptions.WithHeaders(metadata); + // replace the CallOptions + callOptions = callOptions.WithHeaders(metadata); - this.SetActivity(rpcActivity); - options.Propagator.Inject(new PropagationContext(rpcActivity.Context, Baggage.Current), callOptions.Headers, MetadataSetter); - this.context = new ClientInterceptorContext(context.Method, context.Host, callOptions); - } + this.SetActivity(rpcActivity); + options.Propagator.Inject(new PropagationContext(rpcActivity.Context, Baggage.Current), callOptions.Headers, MetadataSetter); + this.context = new ClientInterceptorContext(context.Method, context.Host, callOptions); + } - /// - /// Gets the context. - /// - public ClientInterceptorContext Context => this.context; + /// + /// Gets the context. + /// + public ClientInterceptorContext Context => this.context; - /// - /// Restores the parent activity. - /// - public void RestoreParentActivity() - { - Activity.Current = this.parentActivity; - } + /// + /// Restores the parent activity. + /// + public void RestoreParentActivity() + { + Activity.Current = this.parentActivity; } } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 1eac18fe58..5e7898b58d 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -14,29 +14,28 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore -{ - using System; - using OpenTelemetry.Context.Propagation; +using System; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Instrumentation.GrpcCore; +/// +/// Options for the ClientTracingInterceptor. +/// +public class ClientTracingInterceptorOptions +{ /// - /// Options for the ClientTracingInterceptor. + /// Gets or sets a value indicating whether or not to record individual message events. /// - public class ClientTracingInterceptorOptions - { - /// - /// Gets or sets a value indicating whether or not to record individual message events. - /// - public bool RecordMessageEvents { get; set; } = false; + public bool RecordMessageEvents { get; set; } = false; - /// - /// Gets the propagator. - /// - public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; + /// + /// Gets the propagator. + /// + public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; - /// - /// Gets or sets a custom identfier used during unit testing. - /// - internal Guid ActivityIdentifierValue { get; set; } - } + /// + /// Gets or sets a custom identfier used during unit testing. + /// + internal Guid ActivityIdentifierValue { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs index 0d31f0c8f3..ff4ee15c88 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs @@ -14,34 +14,33 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore -{ - using System; +using System; + +namespace OpenTelemetry.Instrumentation.GrpcCore; +/// +/// Other useful extensions. +/// +internal static class Extensions +{ /// - /// Other useful extensions. + /// Builds an Action comprised of two calls to Dispose with best effort execution for the second disposable. /// - internal static class Extensions + /// The first. + /// The second. + /// An Action. + internal static Action WithBestEffortDispose(this IDisposable first, IDisposable second) { - /// - /// Builds an Action comprised of two calls to Dispose with best effort execution for the second disposable. - /// - /// The first. - /// The second. - /// An Action. - internal static Action WithBestEffortDispose(this IDisposable first, IDisposable second) + return () => { - return () => + try + { + first.Dispose(); + } + finally { - try - { - first.Dispose(); - } - finally - { - second.Dispose(); - } - }; - } + second.Dispose(); + } + }; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index f215aa9a0a..0c7a6a80c0 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -14,35 +14,34 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore -{ - using System; - using System.Diagnostics; - using System.Reflection; +using System; +using System.Diagnostics; +using System.Reflection; + +namespace OpenTelemetry.Instrumentation.GrpcCore; +/// +/// Instrumentation class Grpc.Core. +/// +internal static class GrpcCoreInstrumentation +{ /// - /// Instrumentation class Grpc.Core. + /// The assembly name. /// - internal static class GrpcCoreInstrumentation - { - /// - /// The assembly name. - /// - internal static readonly AssemblyName AssemblyName = typeof(GrpcCoreInstrumentation).Assembly.GetName(); + internal static readonly AssemblyName AssemblyName = typeof(GrpcCoreInstrumentation).Assembly.GetName(); - /// - /// The activity source name. - /// - internal static readonly string ActivitySourceName = AssemblyName.Name; + /// + /// The activity source name. + /// + internal static readonly string ActivitySourceName = AssemblyName.Name; - /// - /// The version. - /// - internal static readonly Version Version = AssemblyName.Version; + /// + /// The version. + /// + internal static readonly Version Version = AssemblyName.Version; - /// - /// The activity source. - /// - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); - } + /// + /// The activity source. + /// + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index 1abdf00701..e179a19454 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -14,218 +14,217 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; +using global::Grpc.Core; +using Google.Protobuf; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.GrpcCore; + +/// +/// A class to help track the lifetime of an RPC. +/// +/// The type of the request. +/// The type of the response. +internal abstract class RpcScope : IDisposable + where TRequest : class + where TResponse : class { - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Threading; - using global::Grpc.Core; - using Google.Protobuf; - using OpenTelemetry.Trace; + /// + /// The record message events flag. + /// + private readonly bool recordMessageEvents; /// - /// A class to help track the lifetime of an RPC. + /// The RPC activity. /// - /// The type of the request. - /// The type of the response. - internal abstract class RpcScope : IDisposable - where TRequest : class - where TResponse : class - { - /// - /// The record message events flag. - /// - private readonly bool recordMessageEvents; - - /// - /// The RPC activity. - /// - private Activity activity; - - /// - /// The complete flag. - /// - private long complete = 0; - - /// - /// The request message counter. - /// - private int requestMessageCounter; - - /// - /// The response counter. - /// - private int responseMessageCounter; - - /// - /// Initializes a new instance of the class. - /// - /// Full name of the service. - /// if set to true [record message events]. - protected RpcScope(string fullServiceName, bool recordMessageEvents) - { - this.FullServiceName = fullServiceName?.TrimStart('/') ?? "unknownservice/unknownmethod"; - this.recordMessageEvents = recordMessageEvents; - } + private Activity activity; - /// - /// Gets the full name of the service. - /// - protected string FullServiceName { get; } + /// + /// The complete flag. + /// + private long complete = 0; - /// - /// Records a request message. - /// - /// The request. - public void RecordRequest(TRequest request) - { - this.requestMessageCounter++; + /// + /// The request message counter. + /// + private int requestMessageCounter; - if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) - { - return; - } + /// + /// The response counter. + /// + private int responseMessageCounter; - this.AddMessageEvent(typeof(TRequest).Name, request as IMessage, request: true); - } + /// + /// Initializes a new instance of the class. + /// + /// Full name of the service. + /// if set to true [record message events]. + protected RpcScope(string fullServiceName, bool recordMessageEvents) + { + this.FullServiceName = fullServiceName?.TrimStart('/') ?? "unknownservice/unknownmethod"; + this.recordMessageEvents = recordMessageEvents; + } - /// - /// Records a response message. - /// - /// The response. - public void RecordResponse(TResponse response) - { - this.responseMessageCounter++; + /// + /// Gets the full name of the service. + /// + protected string FullServiceName { get; } - if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) - { - return; - } + /// + /// Records a request message. + /// + /// The request. + public void RecordRequest(TRequest request) + { + this.requestMessageCounter++; - this.AddMessageEvent(typeof(TResponse).Name, response as IMessage, request: false); + if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) + { + return; } - /// - /// Completes the RPC. - /// - public void Complete() - { - if (this.activity == null) - { - return; - } + this.AddMessageEvent(typeof(TRequest).Name, request as IMessage, request: true); + } - // The overall Span status should remain unset however the grpc status code attribute is required - this.StopActivity((int)Grpc.Core.StatusCode.OK); - } + /// + /// Records a response message. + /// + /// The response. + public void RecordResponse(TResponse response) + { + this.responseMessageCounter++; - /// - /// Records a failed RPC. - /// - /// The exception. - public void CompleteWithException(Exception exception) + if (this.activity == null || !this.activity.IsAllDataRequested || !this.recordMessageEvents) { - if (this.activity == null) - { - return; - } - - var grpcStatusCode = Grpc.Core.StatusCode.Unknown; - var description = exception.Message; + return; + } - if (exception is RpcException rpcException) - { - grpcStatusCode = rpcException.StatusCode; - description = rpcException.Message; - } + this.AddMessageEvent(typeof(TResponse).Name, response as IMessage, request: false); + } - this.StopActivity((int)grpcStatusCode, description); + /// + /// Completes the RPC. + /// + public void Complete() + { + if (this.activity == null) + { + return; } - /// - public void Dispose() + // The overall Span status should remain unset however the grpc status code attribute is required + this.StopActivity((int)Grpc.Core.StatusCode.OK); + } + + /// + /// Records a failed RPC. + /// + /// The exception. + public void CompleteWithException(Exception exception) + { + if (this.activity == null) { - if (this.activity == null) - { - return; - } + return; + } - // If not already completed this will mark the Activity as cancelled. - this.StopActivity((int)Grpc.Core.StatusCode.Cancelled); + var grpcStatusCode = Grpc.Core.StatusCode.Unknown; + var description = exception.Message; + + if (exception is RpcException rpcException) + { + grpcStatusCode = rpcException.StatusCode; + description = rpcException.Message; } - /// - /// Sets the activity for this RPC scope. Should only be called once. - /// - /// The activity. - protected void SetActivity(Activity activity) + this.StopActivity((int)grpcStatusCode, description); + } + + /// + public void Dispose() + { + if (this.activity == null) { - this.activity = activity; + return; + } - if (this.activity == null || !this.activity.IsAllDataRequested) - { - return; - } + // If not already completed this will mark the Activity as cancelled. + this.StopActivity((int)Grpc.Core.StatusCode.Cancelled); + } + + /// + /// Sets the activity for this RPC scope. Should only be called once. + /// + /// The activity. + protected void SetActivity(Activity activity) + { + this.activity = activity; - // assign some reasonable defaults - var rpcService = this.FullServiceName; - var rpcMethod = this.FullServiceName; + if (this.activity == null || !this.activity.IsAllDataRequested) + { + return; + } - // split the full service name by the slash - var parts = this.FullServiceName.Split('/'); - if (parts.Length == 2) - { - rpcService = parts[0]; - rpcMethod = parts[1]; - } + // assign some reasonable defaults + var rpcService = this.FullServiceName; + var rpcMethod = this.FullServiceName; - this.activity.SetTag(SemanticConventions.AttributeRpcSystem, "grpc"); - this.activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); - this.activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + // split the full service name by the slash + var parts = this.FullServiceName.Split('/'); + if (parts.Length == 2) + { + rpcService = parts[0]; + rpcMethod = parts[1]; } - /// - /// Stops the activity. - /// - /// The status code. - /// The description, if any. - private void StopActivity(int statusCode, string statusDescription = null) + this.activity.SetTag(SemanticConventions.AttributeRpcSystem, "grpc"); + this.activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); + this.activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + } + + /// + /// Stops the activity. + /// + /// The status code. + /// The description, if any. + private void StopActivity(int statusCode, string statusDescription = null) + { + if (Interlocked.CompareExchange(ref this.complete, 1, 0) == 0) { - if (Interlocked.CompareExchange(ref this.complete, 1, 0) == 0) + this.activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, statusCode); + if (statusDescription != null) { - this.activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, statusCode); - if (statusDescription != null) - { - this.activity.SetStatus(OpenTelemetry.Trace.Status.Error.WithDescription(statusDescription)); - } - - this.activity.Stop(); + this.activity.SetStatus(OpenTelemetry.Trace.Status.Error.WithDescription(statusDescription)); } + + this.activity.Stop(); } + } - /// - /// Adds a message event. - /// - /// Name of the event. - /// The message. - /// if true this is a request message. - private void AddMessageEvent(string eventName, IMessage message, bool request) - { - var messageSize = message.CalculateSize(); + /// + /// Adds a message event. + /// + /// Name of the event. + /// The message. + /// if true this is a request message. + private void AddMessageEvent(string eventName, IMessage message, bool request) + { + var messageSize = message.CalculateSize(); - var attributes = new ActivityTagsCollection(new KeyValuePair[5] - { - new KeyValuePair("name", "message"), - new KeyValuePair(SemanticConventions.AttributeMessageType, request ? "SENT" : "RECEIVED"), - new KeyValuePair(SemanticConventions.AttributeMessageID, request ? this.requestMessageCounter : this.responseMessageCounter), + var attributes = new ActivityTagsCollection(new KeyValuePair[5] + { + new KeyValuePair("name", "message"), + new KeyValuePair(SemanticConventions.AttributeMessageType, request ? "SENT" : "RECEIVED"), + new KeyValuePair(SemanticConventions.AttributeMessageID, request ? this.requestMessageCounter : this.responseMessageCounter), - // TODO how to get the real compressed or uncompressed sizes - new KeyValuePair(SemanticConventions.AttributeMessageCompressedSize, messageSize), - new KeyValuePair(SemanticConventions.AttributeMessageUncompressedSize, messageSize), - }); + // TODO how to get the real compressed or uncompressed sizes + new KeyValuePair(SemanticConventions.AttributeMessageCompressedSize, messageSize), + new KeyValuePair(SemanticConventions.AttributeMessageUncompressedSize, messageSize), + }); - this.activity.AddEvent(new ActivityEvent(eventName, default, attributes)); - } + this.activity.AddEvent(new ActivityEvent(eventName, default, attributes)); } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs index be314c854a..3746e3fb60 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs @@ -14,27 +14,26 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore +namespace OpenTelemetry.Instrumentation.GrpcCore; + +/// +/// Semantic conventions. +/// +internal static class SemanticConventions { - /// - /// Semantic conventions. - /// - internal static class SemanticConventions - { #pragma warning disable SA1600 // Elements should be documented - public const string AttributeRpcSystem = "rpc.system"; - public const string AttributeRpcService = "rpc.service"; - public const string AttributeRpcMethod = "rpc.method"; - public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; - public const string AttributeMessageType = "message.type"; - public const string AttributeMessageID = "message.id"; - public const string AttributeMessageCompressedSize = "message.compressed_size"; - public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; - public const string AttributeOtelStatusCode = "otel.status_code"; - public const string AttributeOtelStatusDescription = "otel.status_description"; + public const string AttributeRpcSystem = "rpc.system"; + public const string AttributeRpcService = "rpc.service"; + public const string AttributeRpcMethod = "rpc.method"; + public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; + public const string AttributeMessageType = "message.type"; + public const string AttributeMessageID = "message.id"; + public const string AttributeMessageCompressedSize = "message.compressed_size"; + public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; + public const string AttributeOtelStatusCode = "otel.status_code"; + public const string AttributeOtelStatusDescription = "otel.status_description"; - // Used for unit testing only. - internal const string AttributeActivityIdentifier = "activityidentifier"; + // Used for unit testing only. + internal const string AttributeActivityIdentifier = "activityidentifier"; #pragma warning restore SA1600 // Elements should be documented - } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index b4a1bc1824..8f9abc417c 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -14,56 +14,55 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore -{ - using System; - using System.Threading.Tasks; - using global::Grpc.Core; +using System; +using System.Threading.Tasks; +using global::Grpc.Core; + +namespace OpenTelemetry.Instrumentation.GrpcCore; +/// +/// A proxy server stream writer. +/// +/// +/// Borrowed heavily from +/// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingServerStreamWriter.cs. +/// +/// The message type. +/// +internal class ServerStreamWriterProxy : IServerStreamWriter +{ /// - /// A proxy server stream writer. + /// The writer. /// - /// - /// Borrowed heavily from - /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingServerStreamWriter.cs. - /// - /// The message type. - /// - internal class ServerStreamWriterProxy : IServerStreamWriter - { - /// - /// The writer. - /// - private readonly IServerStreamWriter writer; + private readonly IServerStreamWriter writer; - /// - /// The on write action. - /// - private readonly Action onWrite; + /// + /// The on write action. + /// + private readonly Action onWrite; - /// - /// Initializes a new instance of the class. - /// - /// The writer. - /// The on write action, if any. - public ServerStreamWriterProxy(IServerStreamWriter writer, Action onWrite = null) - { - this.writer = writer; - this.onWrite = onWrite; - } + /// + /// Initializes a new instance of the class. + /// + /// The writer. + /// The on write action, if any. + public ServerStreamWriterProxy(IServerStreamWriter writer, Action onWrite = null) + { + this.writer = writer; + this.onWrite = onWrite; + } - /// - public WriteOptions WriteOptions - { - get => this.writer.WriteOptions; - set => this.writer.WriteOptions = value; - } + /// + public WriteOptions WriteOptions + { + get => this.writer.WriteOptions; + set => this.writer.WriteOptions = value; + } - /// - public Task WriteAsync(T message) - { - this.onWrite?.Invoke(message); - return this.writer.WriteAsync(message); - } + /// + public Task WriteAsync(T message) + { + this.onWrite?.Invoke(message); + return this.writer.WriteAsync(message); } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index 5dd4633306..cf6ff03467 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -14,216 +14,215 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using global::Grpc.Core; +using global::Grpc.Core.Interceptors; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.GrpcCore; + +/// +/// A service interceptor that starts and stops an Activity for each inbound RPC. +/// +/// +public class ServerTracingInterceptor : Interceptor { - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Threading.Tasks; - using global::Grpc.Core; - using global::Grpc.Core.Interceptors; - using OpenTelemetry.Context.Propagation; - using OpenTelemetry.Internal; + /// + /// The options. + /// + private readonly ServerTracingInterceptorOptions options; /// - /// A service interceptor that starts and stops an Activity for each inbound RPC. + /// Initializes a new instance of the class. /// - /// - public class ServerTracingInterceptor : Interceptor + /// The options. + public ServerTracingInterceptor(ServerTracingInterceptorOptions options) { - /// - /// The options. - /// - private readonly ServerTracingInterceptorOptions options; + Guard.ThrowIfNull(options); - /// - /// Initializes a new instance of the class. - /// - /// The options. - public ServerTracingInterceptor(ServerTracingInterceptorOptions options) - { - Guard.ThrowIfNull(options); + this.options = options; + } - this.options = options; - } + /// + public override async Task UnaryServerHandler( + TRequest request, + ServerCallContext context, + UnaryServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); - /// - public override async Task UnaryServerHandler( - TRequest request, - ServerCallContext context, - UnaryServerMethod continuation) + try { - using var rpcScope = new ServerRpcScope(context, this.options); - - try - { - rpcScope.RecordRequest(request); - var response = await continuation(request, context).ConfigureAwait(false); - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } + rpcScope.RecordRequest(request); + var response = await continuation(request, context).ConfigureAwait(false); + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; } - - /// - public override async Task ClientStreamingServerHandler( - IAsyncStreamReader requestStream, - ServerCallContext context, - ClientStreamingServerMethod continuation) + catch (Exception e) { - using var rpcScope = new ServerRpcScope(context, this.options); - - try - { - var requestStreamReaderProxy = new AsyncStreamReaderProxy( - requestStream, - rpcScope.RecordRequest); - - var response = await continuation(requestStreamReaderProxy, context).ConfigureAwait(false); - rpcScope.RecordResponse(response); - rpcScope.Complete(); - return response; - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } + rpcScope.CompleteWithException(e); + throw; } + } + + /// + public override async Task ClientStreamingServerHandler( + IAsyncStreamReader requestStream, + ServerCallContext context, + ClientStreamingServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); - /// - public override async Task ServerStreamingServerHandler( - TRequest request, - IServerStreamWriter responseStream, - ServerCallContext context, - ServerStreamingServerMethod continuation) + try { - using var rpcScope = new ServerRpcScope(context, this.options); + var requestStreamReaderProxy = new AsyncStreamReaderProxy( + requestStream, + rpcScope.RecordRequest); + + var response = await continuation(requestStreamReaderProxy, context).ConfigureAwait(false); + rpcScope.RecordResponse(response); + rpcScope.Complete(); + return response; + } + catch (Exception e) + { + rpcScope.CompleteWithException(e); + throw; + } + } - try - { - rpcScope.RecordRequest(request); + /// + public override async Task ServerStreamingServerHandler( + TRequest request, + IServerStreamWriter responseStream, + ServerCallContext context, + ServerStreamingServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); - var responseStreamProxy = new ServerStreamWriterProxy( - responseStream, - rpcScope.RecordResponse); + try + { + rpcScope.RecordRequest(request); - await continuation(request, responseStreamProxy, context).ConfigureAwait(false); - rpcScope.Complete(); - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } - } + var responseStreamProxy = new ServerStreamWriterProxy( + responseStream, + rpcScope.RecordResponse); - /// - public override async Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation) + await continuation(request, responseStreamProxy, context).ConfigureAwait(false); + rpcScope.Complete(); + } + catch (Exception e) { - using var rpcScope = new ServerRpcScope(context, this.options); + rpcScope.CompleteWithException(e); + throw; + } + } - try - { - var requestStreamReaderProxy = new AsyncStreamReaderProxy( - requestStream, - rpcScope.RecordRequest); + /// + public override async Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation) + { + using var rpcScope = new ServerRpcScope(context, this.options); - var responseStreamProxy = new ServerStreamWriterProxy( - responseStream, - rpcScope.RecordResponse); + try + { + var requestStreamReaderProxy = new AsyncStreamReaderProxy( + requestStream, + rpcScope.RecordRequest); - await continuation(requestStreamReaderProxy, responseStreamProxy, context).ConfigureAwait(false); - rpcScope.Complete(); - } - catch (Exception e) - { - rpcScope.CompleteWithException(e); - throw; - } + var responseStreamProxy = new ServerStreamWriterProxy( + responseStream, + rpcScope.RecordResponse); + + await continuation(requestStreamReaderProxy, responseStreamProxy, context).ConfigureAwait(false); + rpcScope.Complete(); + } + catch (Exception e) + { + rpcScope.CompleteWithException(e); + throw; } + } + /// + /// A class to help track the lifetime of a service-side RPC. + /// + /// The type of the request. + /// The type of the response. + private class ServerRpcScope : RpcScope + where TRequest : class + where TResponse : class + { /// - /// A class to help track the lifetime of a service-side RPC. + /// The metadata setter action. /// - /// The type of the request. - /// The type of the response. - private class ServerRpcScope : RpcScope - where TRequest : class - where TResponse : class + private static readonly Func> MetadataGetter = (metadata, key) => { - /// - /// The metadata setter action. - /// - private static readonly Func> MetadataGetter = (metadata, key) => + for (var i = 0; i < metadata.Count; i++) { - for (var i = 0; i < metadata.Count; i++) + var entry = metadata[i]; + if (string.Equals(entry.Key, key, StringComparison.OrdinalIgnoreCase)) { - var entry = metadata[i]; - if (string.Equals(entry.Key, key, StringComparison.OrdinalIgnoreCase)) - { - return new string[1] { entry.Value }; - } + return new string[1] { entry.Value }; } + } - return Enumerable.Empty(); - }; + return Enumerable.Empty(); + }; - /// - /// Initializes a new instance of the class. - /// - /// The context. - /// The options. - public ServerRpcScope(ServerCallContext context, ServerTracingInterceptorOptions options) - : base(context.Method, options.RecordMessageEvents) + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// The options. + public ServerRpcScope(ServerCallContext context, ServerTracingInterceptorOptions options) + : base(context.Method, options.RecordMessageEvents) + { + if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) { - if (!GrpcCoreInstrumentation.ActivitySource.HasListeners()) - { - return; - } + return; + } - var currentContext = Activity.Current?.Context; + var currentContext = Activity.Current?.Context; - // Extract the SpanContext, if any from the headers - var metadata = context.RequestHeaders; - if (metadata != null) + // Extract the SpanContext, if any from the headers + var metadata = context.RequestHeaders; + if (metadata != null) + { + var propagationContext = options.Propagator.Extract(new PropagationContext(currentContext ?? default, Baggage.Current), metadata, MetadataGetter); + if (propagationContext.ActivityContext.IsValid()) { - var propagationContext = options.Propagator.Extract(new PropagationContext(currentContext ?? default, Baggage.Current), metadata, MetadataGetter); - if (propagationContext.ActivityContext.IsValid()) - { - currentContext = propagationContext.ActivityContext; - } - - if (propagationContext.Baggage != default) - { - Baggage.Current = propagationContext.Baggage; - } + currentContext = propagationContext.ActivityContext; } - // This if block is for unit testing only. - IEnumerable> customTags = null; - if (options.ActivityIdentifierValue != default) + if (propagationContext.Baggage != default) { - customTags = new List> - { - new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), - }; + Baggage.Current = propagationContext.Baggage; } + } - var activity = GrpcCoreInstrumentation.ActivitySource.StartActivity( - this.FullServiceName, - ActivityKind.Server, - currentContext ?? default, - tags: customTags); - - this.SetActivity(activity); + // This if block is for unit testing only. + IEnumerable> customTags = null; + if (options.ActivityIdentifierValue != default) + { + customTags = new List> + { + new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), + }; } + + var activity = GrpcCoreInstrumentation.ActivitySource.StartActivity( + this.FullServiceName, + ActivityKind.Server, + currentContext ?? default, + tags: customTags); + + this.SetActivity(activity); } } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index 3713491397..94fbea9967 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -14,29 +14,28 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.GrpcCore -{ - using System; - using OpenTelemetry.Context.Propagation; +using System; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Instrumentation.GrpcCore; +/// +/// Options for the ServerTracingInterceptor. +/// +public class ServerTracingInterceptorOptions +{ /// - /// Options for the ServerTracingInterceptor. + /// Gets or sets a value indicating whether or not to record individual message events. /// - public class ServerTracingInterceptorOptions - { - /// - /// Gets or sets a value indicating whether or not to record individual message events. - /// - public bool RecordMessageEvents { get; set; } = false; + public bool RecordMessageEvents { get; set; } = false; - /// - /// Gets the propagator. - /// - public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; + /// + /// Gets the propagator. + /// + public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; - /// - /// Gets or sets a custom identfier used during unit testing. - /// - internal Guid ActivityIdentifierValue { get; set; } - } + /// + /// Gets or sets a custom identfier used during unit testing. + /// + internal Guid ActivityIdentifierValue { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs index 2b3e817438..3ab16404c2 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs @@ -14,27 +14,26 @@ // limitations under the License. // -namespace OpenTelemetry.Trace -{ - using OpenTelemetry.Instrumentation.GrpcCore; - using OpenTelemetry.Internal; +using OpenTelemetry.Instrumentation.GrpcCore; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; +/// +/// OpenTelemetry builder extensions to simplify registration of Grpc.Core based interceptors. +/// +public static class TracerProviderBuilderExtensions +{ /// - /// OpenTelemetry builder extensions to simplify registration of Grpc.Core based interceptors. + /// Configures OpenTelemetry to listen for the Activities created by the client and server interceptors. /// - public static class TracerProviderBuilderExtensions + /// The builder. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcCoreInstrumentation( + this TracerProviderBuilder builder) { - /// - /// Configures OpenTelemetry to listen for the Activities created by the client and server interceptors. - /// - /// The builder. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddGrpcCoreInstrumentation( - this TracerProviderBuilder builder) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - return builder.AddSource(GrpcCoreInstrumentation.ActivitySourceName); - } + return builder.AddSource(GrpcCoreInstrumentation.ActivitySourceName); } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 1d5d8599e6..73f545680a 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -23,262 +23,261 @@ using Grpc.Core; using Grpc.Core.Interceptors; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test +namespace OpenTelemetry.Instrumentation.GrpcCore.Test; + +/// +/// Test implementation of foobar. +/// +internal class FoobarService : Foobar.FoobarBase { /// - /// Test implementation of foobar. + /// Default traceparent header value with the sampling bit on. /// - internal class FoobarService : Foobar.FoobarBase - { - /// - /// Default traceparent header value with the sampling bit on. - /// - internal static readonly string DefaultTraceparentWithSampling = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; + internal static readonly string DefaultTraceparentWithSampling = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; - /// - /// The default parent from a traceparent header. - /// - internal static readonly ActivityContext DefaultParentFromTraceparentHeader = ActivityContext.Parse(DefaultTraceparentWithSampling, null); + /// + /// The default parent from a traceparent header. + /// + internal static readonly ActivityContext DefaultParentFromTraceparentHeader = ActivityContext.Parse(DefaultTraceparentWithSampling, null); - /// - /// The default request message. - /// - internal static readonly FoobarRequest DefaultRequestMessage = new FoobarRequest { Message = "foo" }; + /// + /// The default request message. + /// + internal static readonly FoobarRequest DefaultRequestMessage = new FoobarRequest { Message = "foo" }; - /// - /// The default request message size. - /// - internal static readonly int DefaultRequestMessageSize = ((IMessage)DefaultRequestMessage).CalculateSize(); + /// + /// The default request message size. + /// + internal static readonly int DefaultRequestMessageSize = ((IMessage)DefaultRequestMessage).CalculateSize(); - /// - /// The default response message. - /// - internal static readonly FoobarResponse DefaultResponseMessage = new FoobarResponse { Message = "bar" }; + /// + /// The default response message. + /// + internal static readonly FoobarResponse DefaultResponseMessage = new FoobarResponse { Message = "bar" }; - /// - /// The default request message size. - /// - internal static readonly int DefaultResponseMessageSize = ((IMessage)DefaultResponseMessage).CalculateSize(); + /// + /// The default request message size. + /// + internal static readonly int DefaultResponseMessageSize = ((IMessage)DefaultResponseMessage).CalculateSize(); - /// - /// The request header fail with status code. - /// - internal static readonly string RequestHeaderFailWithStatusCode = "failurestatuscode"; + /// + /// The request header fail with status code. + /// + internal static readonly string RequestHeaderFailWithStatusCode = "failurestatuscode"; - /// - /// The request header error description. - /// - internal static readonly string RequestHeaderErrorDescription = "failuredescription"; + /// + /// The request header error description. + /// + internal static readonly string RequestHeaderErrorDescription = "failuredescription"; - /// - /// Starts the specified service. - /// - /// The server interceptor. - /// A tuple. - public static DisposableServer Start(Interceptor serverInterceptor = null) + /// + /// Starts the specified service. + /// + /// The server interceptor. + /// A tuple. + public static DisposableServer Start(Interceptor serverInterceptor = null) + { + // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 + var serviceDefinition = Foobar.BindService(new FoobarService()); + if (serverInterceptor != null) { - // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 - var serviceDefinition = Foobar.BindService(new FoobarService()); - if (serverInterceptor != null) - { - serviceDefinition = serviceDefinition.Intercept(serverInterceptor); - } - - var server = new Server - { - Ports = { { "localhost", ServerPort.PickUnused, ServerCredentials.Insecure } }, - Services = { serviceDefinition }, - }; - - server.Start(); - var serverUriString = new Uri("dns:localhost:" + server.Ports.Single().BoundPort).ToString(); - - return new DisposableServer(server, serverUriString); + serviceDefinition = serviceDefinition.Intercept(serverInterceptor); } - /// - /// Builds the default RPC client. - /// - /// The target. - /// The client tracing interceptor, if any. - /// The additional metadata, if any. - /// - /// The gRPC client. - /// - public static Foobar.FoobarClient ConstructRpcClient( - string target, - ClientTracingInterceptor clientTracingInterceptor = null, - IEnumerable additionalMetadata = null) + var server = new Server { - var channel = new Channel(target, ChannelCredentials.Insecure); - var callInvoker = channel.CreateCallInvoker(); - - if (clientTracingInterceptor != null) - { - callInvoker = callInvoker.Intercept(clientTracingInterceptor); - } - - // The metadata injector comes first - if (additionalMetadata != null) - { - callInvoker = callInvoker.Intercept( - metadata => - { - foreach (var m in additionalMetadata) - { - metadata.Add(m); - } + Ports = { { "localhost", ServerPort.PickUnused, ServerCredentials.Insecure } }, + Services = { serviceDefinition }, + }; - return metadata; - }); - } + server.Start(); + var serverUriString = new Uri("dns:localhost:" + server.Ports.Single().BoundPort).ToString(); - return new Foobar.FoobarClient(callInvoker); - } + return new DisposableServer(server, serverUriString); + } - /// - /// Makes a unary asynchronous request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeUnaryAsyncRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + /// + /// Builds the default RPC client. + /// + /// The target. + /// The client tracing interceptor, if any. + /// The additional metadata, if any. + /// + /// The gRPC client. + /// + public static Foobar.FoobarClient ConstructRpcClient( + string target, + ClientTracingInterceptor clientTracingInterceptor = null, + IEnumerable additionalMetadata = null) + { + var channel = new Channel(target, ChannelCredentials.Insecure); + var callInvoker = channel.CreateCallInvoker(); + + if (clientTracingInterceptor != null) { - using var call = client.UnaryAsync(DefaultRequestMessage, headers: additionalMetadata); - _ = await call.ResponseAsync.ConfigureAwait(false); + callInvoker = callInvoker.Intercept(clientTracingInterceptor); } - /// - /// Makes a client streaming request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeClientStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + // The metadata injector comes first + if (additionalMetadata != null) { - using var call = client.ClientStreaming(headers: additionalMetadata); - await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); - await call.RequestStream.CompleteAsync().ConfigureAwait(false); - _ = await call.ResponseAsync.ConfigureAwait(false); + callInvoker = callInvoker.Intercept( + metadata => + { + foreach (var m in additionalMetadata) + { + metadata.Add(m); + } + + return metadata; + }); } - /// - /// Makes a server streaming request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeServerStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + return new Foobar.FoobarClient(callInvoker); + } + + /// + /// Makes a unary asynchronous request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeUnaryAsyncRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.UnaryAsync(DefaultRequestMessage, headers: additionalMetadata); + _ = await call.ResponseAsync.ConfigureAwait(false); + } + + /// + /// Makes a client streaming request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeClientStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.ClientStreaming(headers: additionalMetadata); + await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); + await call.RequestStream.CompleteAsync().ConfigureAwait(false); + _ = await call.ResponseAsync.ConfigureAwait(false); + } + + /// + /// Makes a server streaming request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeServerStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.ServerStreaming(DefaultRequestMessage, headers: additionalMetadata); + while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) { - using var call = client.ServerStreaming(DefaultRequestMessage, headers: additionalMetadata); - while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) - { - } } + } - /// - /// Makes a duplex streaming request. - /// - /// The client. - /// The additional metadata. - /// A Task. - public static async Task MakeDuplexStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) - { - using var call = client.DuplexStreaming(headers: additionalMetadata); - await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); - await call.RequestStream.CompleteAsync().ConfigureAwait(false); + /// + /// Makes a duplex streaming request. + /// + /// The client. + /// The additional metadata. + /// A Task. + public static async Task MakeDuplexStreamingRequest(Foobar.FoobarClient client, Metadata additionalMetadata) + { + using var call = client.DuplexStreaming(headers: additionalMetadata); + await call.RequestStream.WriteAsync(DefaultRequestMessage).ConfigureAwait(false); + await call.RequestStream.CompleteAsync().ConfigureAwait(false); - while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) - { - } + while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) + { } + } - /// - public override Task Unary(FoobarRequest request, ServerCallContext context) - { - this.CheckForFailure(context); + /// + public override Task Unary(FoobarRequest request, ServerCallContext context) + { + this.CheckForFailure(context); - return Task.FromResult(DefaultResponseMessage); - } + return Task.FromResult(DefaultResponseMessage); + } - /// - public override async Task ClientStreaming(IAsyncStreamReader requestStream, ServerCallContext context) + /// + public override async Task ClientStreaming(IAsyncStreamReader requestStream, ServerCallContext context) + { + this.CheckForFailure(context); + + while (await requestStream.MoveNext().ConfigureAwait(false)) { - this.CheckForFailure(context); + } - while (await requestStream.MoveNext().ConfigureAwait(false)) - { - } + return DefaultResponseMessage; + } - return DefaultResponseMessage; - } + /// + public override async Task ServerStreaming(FoobarRequest request, IServerStreamWriter responseStream, ServerCallContext context) + { + this.CheckForFailure(context); - /// - public override async Task ServerStreaming(FoobarRequest request, IServerStreamWriter responseStream, ServerCallContext context) - { - this.CheckForFailure(context); + await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); + } - await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); - } + /// + public override async Task DuplexStreaming(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) + { + this.CheckForFailure(context); - /// - public override async Task DuplexStreaming(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context) + while (await requestStream.MoveNext().ConfigureAwait(false)) { - this.CheckForFailure(context); + } - while (await requestStream.MoveNext().ConfigureAwait(false)) - { - } + await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); + } - await responseStream.WriteAsync(DefaultResponseMessage).ConfigureAwait(false); + /// + /// Throws if we see some by-convention request metadata. + /// + /// The context. + private void CheckForFailure(ServerCallContext context) + { + var failureStatusCodeString = context.RequestHeaders.GetValue(RequestHeaderFailWithStatusCode); + var failureDescription = context.RequestHeaders.GetValue(RequestHeaderErrorDescription); + if (failureStatusCodeString != null) + { + throw new RpcException(new Status((StatusCode)Enum.Parse(typeof(StatusCode), failureStatusCodeString), failureDescription ?? string.Empty)); } + } + + /// + /// Wraps server shutdown with an IDisposable pattern. + /// + /// + public sealed class DisposableServer : IDisposable + { + /// + /// The server. + /// + private readonly Server server; /// - /// Throws if we see some by-convention request metadata. + /// Initializes a new instance of the class. /// - /// The context. - private void CheckForFailure(ServerCallContext context) + /// The server. + /// The URI string. + public DisposableServer(Server server, string uriString) { - var failureStatusCodeString = context.RequestHeaders.GetValue(RequestHeaderFailWithStatusCode); - var failureDescription = context.RequestHeaders.GetValue(RequestHeaderErrorDescription); - if (failureStatusCodeString != null) - { - throw new RpcException(new Status((StatusCode)Enum.Parse(typeof(StatusCode), failureStatusCodeString), failureDescription ?? string.Empty)); - } + this.server = server; + this.UriString = uriString; } /// - /// Wraps server shutdown with an IDisposable pattern. + /// Gets the URI string. /// - /// - public sealed class DisposableServer : IDisposable + public string UriString { get; } + + /// + public void Dispose() { - /// - /// The server. - /// - private readonly Server server; - - /// - /// Initializes a new instance of the class. - /// - /// The server. - /// The URI string. - public DisposableServer(Server server, string uriString) - { - this.server = server; - this.UriString = uriString; - } - - /// - /// Gets the URI string. - /// - public string UriString { get; } - - /// - public void Dispose() - { - this.server.ShutdownAsync().Wait(); - } + this.server.ShutdownAsync().Wait(); } } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 8becff7c7f..56b5fb8d40 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -25,506 +25,505 @@ using OpenTelemetry.Context.Propagation; using Xunit; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test +namespace OpenTelemetry.Instrumentation.GrpcCore.Test; + +/// +/// Grpc Core client interceptor tests. +/// +public class GrpcCoreClientInterceptorTests { /// - /// Grpc Core client interceptor tests. + /// A bogus server uri. + /// + private static readonly string BogusServerUri = "dns:i.dont.exist:77923"; + + /// + /// The default metadata func. + /// + private static readonly Func DefaultMetadataFunc = () => new Metadata { new Metadata.Entry("foo", "bar") }; + + /// + /// Validates a successful AsyncUnary call. /// - public class GrpcCoreClientInterceptorTests + /// A task. + [Fact] + public async Task AsyncUnarySuccess() { - /// - /// A bogus server uri. - /// - private static readonly string BogusServerUri = "dns:i.dont.exist:77923"; - - /// - /// The default metadata func. - /// - private static readonly Func DefaultMetadataFunc = () => new Metadata { new Metadata.Entry("foo", "bar") }; - - /// - /// Validates a successful AsyncUnary call. - /// - /// A task. - [Fact] - public async Task AsyncUnarySuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } + await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } - /// - /// Validates a failed AsyncUnary call because the endpoint isn't there. - /// - /// A task. - [Fact] - public async Task AsyncUnaryUnavailable() - { - await this.TestHandlerFailure( - FoobarService.MakeUnaryAsyncRequest, - StatusCode.Unavailable, - validateErrorDescription: false, - BogusServerUri).ConfigureAwait(false); - } + /// + /// Validates a failed AsyncUnary call because the endpoint isn't there. + /// + /// A task. + [Fact] + public async Task AsyncUnaryUnavailable() + { + await this.TestHandlerFailure( + FoobarService.MakeUnaryAsyncRequest, + StatusCode.Unavailable, + validateErrorDescription: false, + BogusServerUri).ConfigureAwait(false); + } + + /// + /// Validates a failed AsyncUnary call because the service returned an error. + /// + /// A task. + [Fact] + public async Task AsyncUnaryFail() + { + await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + } - /// - /// Validates a failed AsyncUnary call because the service returned an error. - /// - /// A task. - [Fact] - public async Task AsyncUnaryFail() + /// + /// Validates a failed AsyncUnary call because the client is disposed before completing the RPC. + /// + [Fact] + public void AsyncUnaryDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) { - await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); } - /// - /// Validates a failed AsyncUnary call because the client is disposed before completing the RPC. - /// - [Fact] - public void AsyncUnaryDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); - } + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } + /// + /// Validates a successful ClientStreaming call. + /// + /// A task. + [Fact] + public async Task ClientStreamingSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } - /// - /// Validates a successful ClientStreaming call. - /// - /// A task. - [Fact] - public async Task ClientStreamingSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } + /// + /// Validates a failed ClientStreaming call when the service is unavailable. + /// + /// A task. + [Fact] + public async Task ClientStreamingUnavailable() + { + await this.TestHandlerFailure( + FoobarService.MakeClientStreamingRequest, + StatusCode.Unavailable, + validateErrorDescription: false, + BogusServerUri).ConfigureAwait(false); + } - /// - /// Validates a failed ClientStreaming call when the service is unavailable. - /// - /// A task. - [Fact] - public async Task ClientStreamingUnavailable() - { - await this.TestHandlerFailure( - FoobarService.MakeClientStreamingRequest, - StatusCode.Unavailable, - validateErrorDescription: false, - BogusServerUri).ConfigureAwait(false); - } + /// + /// Validates a failed ClientStreaming call. + /// + /// A task. + [Fact] + public async Task ClientStreamingFail() + { + await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a failed ClientStreaming call. - /// - /// A task. - [Fact] - public async Task ClientStreamingFail() + /// + /// Validates a failed ClientStreaming call because the client is disposed before completing the RPC. + /// + [Fact] + public void ClientStreamingDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) { - await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + using var call = client.ClientStreaming(); } - /// - /// Validates a failed ClientStreaming call because the client is disposed before completing the RPC. - /// - [Fact] - public void ClientStreamingDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.ClientStreaming(); - } + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } + /// + /// Validates a successful ServerStreaming call. + /// + /// A task. + [Fact] + public async Task ServerStreamingSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } - /// - /// Validates a successful ServerStreaming call. - /// - /// A task. - [Fact] - public async Task ServerStreamingSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } + /// + /// Validates a failed ServerStreaming call. + /// + /// A task. + [Fact] + public async Task ServerStreamingFail() + { + await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a failed ServerStreaming call. - /// - /// A task. - [Fact] - public async Task ServerStreamingFail() + /// + /// Validates a failed ServerStreaming call because the client is disposed before completing the RPC. + /// + [Fact] + public void ServerStreamingDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) { - await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + using var call = client.ServerStreaming(FoobarService.DefaultRequestMessage); } - /// - /// Validates a failed ServerStreaming call because the client is disposed before completing the RPC. - /// - [Fact] - public void ServerStreamingDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) - { - using var call = client.ServerStreaming(FoobarService.DefaultRequestMessage); - } + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); - } + /// + /// Validates a successful DuplexStreaming call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + } - /// - /// Validates a successful DuplexStreaming call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); - } + /// + /// Validates a failed DuplexStreaming call when the service is unavailable. + /// + /// A task. + [Fact] + public async Task DuplexStreamingUnavailable() + { + await this.TestHandlerFailure( + FoobarService.MakeDuplexStreamingRequest, + StatusCode.Unavailable, + validateErrorDescription: false, + BogusServerUri).ConfigureAwait(false); + } - /// - /// Validates a failed DuplexStreaming call when the service is unavailable. - /// - /// A task. - [Fact] - public async Task DuplexStreamingUnavailable() - { - await this.TestHandlerFailure( - FoobarService.MakeDuplexStreamingRequest, - StatusCode.Unavailable, - validateErrorDescription: false, - BogusServerUri).ConfigureAwait(false); - } + /// + /// Validates a failed DuplexStreaming call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingFail() + { + await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a failed DuplexStreaming call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingFail() + /// + /// Validates a failed DuplexStreaming call because the client is disposed before completing the RPC. + /// + [Fact] + public void DuplexStreamingDisposed() + { + static void MakeRequest(Foobar.FoobarClient client) { - await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + using var call = client.DuplexStreaming(); } - /// - /// Validates a failed DuplexStreaming call because the client is disposed before completing the RPC. - /// - [Fact] - public void DuplexStreamingDisposed() - { - static void MakeRequest(Foobar.FoobarClient client) + this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + } + + /// + /// Validates that a downstream interceptor has access to the created Activity + /// and that the caller always sees the correct activity, not our created Activity. + /// + /// A Task. + [Fact] + public async Task DownstreamInterceptorActivityAccess() + { + using var server = FoobarService.Start(); + var channel = new Channel(server.UriString, ChannelCredentials.Insecure); + var callInvoker = channel.CreateCallInvoker(); + + // Activity has a parent + using var parentActivity = new Activity("foo"); + parentActivity.SetIdFormat(ActivityIdFormat.W3C); + parentActivity.Start(); + + // Order of interceptor invocation will be ClientTracingInterceptor -> MetadataInjector + callInvoker = callInvoker.Intercept( + metadata => { - using var call = client.DuplexStreaming(); - } + // This Func is called as part of an internal MetadataInjector interceptor created by gRPC Core. + Assert.True(Activity.Current.Source == GrpcCoreInstrumentation.ActivitySource); + Assert.Equal(parentActivity.Id, Activity.Current.ParentId); + + // Set a tag on the Activity and make sure we can see it afterwardsd + Activity.Current.SetTag("foo", "bar"); + return metadata; + }); + + var interceptorOptions = new ClientTracingInterceptorOptions { ActivityIdentifierValue = Guid.NewGuid() }; + callInvoker = callInvoker.Intercept(new ClientTracingInterceptor(interceptorOptions)); + var client = new Foobar.FoobarClient(callInvoker); - this.TestActivityIsCancelledWhenHandlerDisposed(MakeRequest); + static void ValidateNewTagOnActivity(InterceptorActivityListener listener) + { + var createdActivity = listener.Activity; + Assert.Contains(createdActivity.TagObjects, t => t.Key == "foo" && (string)t.Value == "bar"); } - /// - /// Validates that a downstream interceptor has access to the created Activity - /// and that the caller always sees the correct activity, not our created Activity. - /// - /// A Task. - [Fact] - public async Task DownstreamInterceptorActivityAccess() + // Check the blocking async call + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) { - using var server = FoobarService.Start(); - var channel = new Channel(server.UriString, ChannelCredentials.Insecure); - var callInvoker = channel.CreateCallInvoker(); + Assert.Equal(parentActivity, Activity.Current); + var response = client.Unary(FoobarService.DefaultRequestMessage); - // Activity has a parent - using var parentActivity = new Activity("foo"); - parentActivity.SetIdFormat(ActivityIdFormat.W3C); - parentActivity.Start(); + Assert.Equal(parentActivity, Activity.Current); - // Order of interceptor invocation will be ClientTracingInterceptor -> MetadataInjector - callInvoker = callInvoker.Intercept( - metadata => - { - // This Func is called as part of an internal MetadataInjector interceptor created by gRPC Core. - Assert.True(Activity.Current.Source == GrpcCoreInstrumentation.ActivitySource); - Assert.Equal(parentActivity.Id, Activity.Current.ParentId); + ValidateNewTagOnActivity(activityListener); + } - // Set a tag on the Activity and make sure we can see it afterwardsd - Activity.Current.SetTag("foo", "bar"); - return metadata; - }); + // Check unary async + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + Assert.Equal(parentActivity, Activity.Current); + using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); - var interceptorOptions = new ClientTracingInterceptorOptions { ActivityIdentifierValue = Guid.NewGuid() }; - callInvoker = callInvoker.Intercept(new ClientTracingInterceptor(interceptorOptions)); - var client = new Foobar.FoobarClient(callInvoker); + Assert.Equal(parentActivity, Activity.Current); - static void ValidateNewTagOnActivity(InterceptorActivityListener listener) - { - var createdActivity = listener.Activity; - Assert.Contains(createdActivity.TagObjects, t => t.Key == "foo" && (string)t.Value == "bar"); - } + _ = await call.ResponseAsync.ConfigureAwait(false); - // Check the blocking async call - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - Assert.Equal(parentActivity, Activity.Current); - var response = client.Unary(FoobarService.DefaultRequestMessage); + Assert.Equal(parentActivity, Activity.Current); - Assert.Equal(parentActivity, Activity.Current); + ValidateNewTagOnActivity(activityListener); + } - ValidateNewTagOnActivity(activityListener); - } + // Check a streaming async call + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + Assert.Equal(parentActivity, Activity.Current); + using var call = client.DuplexStreaming(); - // Check unary async - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - Assert.Equal(parentActivity, Activity.Current); - using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); + Assert.Equal(parentActivity, Activity.Current); - Assert.Equal(parentActivity, Activity.Current); + await call.RequestStream.WriteAsync(FoobarService.DefaultRequestMessage).ConfigureAwait(false); - _ = await call.ResponseAsync.ConfigureAwait(false); + Assert.Equal(parentActivity, Activity.Current); - Assert.Equal(parentActivity, Activity.Current); + await call.RequestStream.CompleteAsync().ConfigureAwait(false); - ValidateNewTagOnActivity(activityListener); - } + Assert.Equal(parentActivity, Activity.Current); - // Check a streaming async call - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) { Assert.Equal(parentActivity, Activity.Current); - using var call = client.DuplexStreaming(); - - Assert.Equal(parentActivity, Activity.Current); - - await call.RequestStream.WriteAsync(FoobarService.DefaultRequestMessage).ConfigureAwait(false); + } - Assert.Equal(parentActivity, Activity.Current); + Assert.Equal(parentActivity, Activity.Current); - await call.RequestStream.CompleteAsync().ConfigureAwait(false); + ValidateNewTagOnActivity(activityListener); + } + } - Assert.Equal(parentActivity, Activity.Current); + /// + /// Validates the common activity tags. + /// + /// The activity. + /// The expected status code. + /// if set to true [recorded messages]. + internal static void ValidateCommonActivityTags( + Activity activity, + Grpc.Core.StatusCode expectedStatusCode = Grpc.Core.StatusCode.OK, + bool recordedMessages = false) + { + Assert.NotNull(activity); + Assert.NotNull(activity.Tags); - while (await call.ResponseStream.MoveNext().ConfigureAwait(false)) - { - Assert.Equal(parentActivity, Activity.Current); - } + // The activity was stopped + Assert.True(activity.Duration != default); - Assert.Equal(parentActivity, Activity.Current); + // TagObjects contain non string values + // Tags contains only string values + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcSystem && (string)t.Value == "grpc"); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcService && (string)t.Value == "OpenTelemetry.Instrumentation.GrpcCore.Test.Foobar"); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcMethod); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcGrpcStatusCode && (int)t.Value == (int)expectedStatusCode); - ValidateNewTagOnActivity(activityListener); - } + // Cancelled is not an error. + if (expectedStatusCode != StatusCode.OK && expectedStatusCode != StatusCode.Cancelled) + { + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusCode && (string)t.Value == "ERROR"); } - /// - /// Validates the common activity tags. - /// - /// The activity. - /// The expected status code. - /// if set to true [recorded messages]. - internal static void ValidateCommonActivityTags( - Activity activity, - Grpc.Core.StatusCode expectedStatusCode = Grpc.Core.StatusCode.OK, - bool recordedMessages = false) + if (recordedMessages) { - Assert.NotNull(activity); - Assert.NotNull(activity.Tags); - - // The activity was stopped - Assert.True(activity.Duration != default); - - // TagObjects contain non string values - // Tags contains only string values - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcSystem && (string)t.Value == "grpc"); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcService && (string)t.Value == "OpenTelemetry.Instrumentation.GrpcCore.Test.Foobar"); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcMethod); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcGrpcStatusCode && (int)t.Value == (int)expectedStatusCode); + // all methods accept a request and return a single response + Assert.NotNull(activity.Events); + var requestMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultRequestMessage.GetType().Name); + var responseMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultResponseMessage.GetType().Name); - // Cancelled is not an error. - if (expectedStatusCode != StatusCode.OK && expectedStatusCode != StatusCode.Cancelled) + static void ValidateCommonEventAttributes(ActivityEvent activityEvent) { - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusCode && (string)t.Value == "ERROR"); + Assert.NotNull(activityEvent.Tags); + Assert.Contains(activityEvent.Tags, t => t.Key == "name" && (string)t.Value == "message"); + Assert.Contains(activityEvent.Tags, t => t.Key == SemanticConventions.AttributeMessageID && (int)t.Value == 1); } - if (recordedMessages) - { - // all methods accept a request and return a single response - Assert.NotNull(activity.Events); - var requestMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultRequestMessage.GetType().Name); - var responseMessage = activity.Events.FirstOrDefault(ae => ae.Name == FoobarService.DefaultResponseMessage.GetType().Name); - - static void ValidateCommonEventAttributes(ActivityEvent activityEvent) - { - Assert.NotNull(activityEvent.Tags); - Assert.Contains(activityEvent.Tags, t => t.Key == "name" && (string)t.Value == "message"); - Assert.Contains(activityEvent.Tags, t => t.Key == SemanticConventions.AttributeMessageID && (int)t.Value == 1); - } - - Assert.NotEqual(default, requestMessage); - Assert.NotEqual(default, responseMessage); + Assert.NotEqual(default, requestMessage); + Assert.NotEqual(default, responseMessage); - ValidateCommonEventAttributes(requestMessage); - Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "SENT"); - Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultRequestMessageSize); + ValidateCommonEventAttributes(requestMessage); + Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "SENT"); + Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultRequestMessageSize); - ValidateCommonEventAttributes(responseMessage); - Assert.Contains(responseMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "RECEIVED"); - Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultResponseMessageSize); - } + ValidateCommonEventAttributes(responseMessage); + Assert.Contains(responseMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageType && (string)t.Value == "RECEIVED"); + Assert.Contains(requestMessage.Tags, t => t.Key == SemanticConventions.AttributeMessageCompressedSize && (int)t.Value == FoobarService.DefaultResponseMessageSize); } + } - /// - /// Tests basic handler success. - /// - /// The client request function. - /// The additional metadata, if any. - /// A Task. - private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) - { - var mockPropagator = new Mock(); - PropagationContext capturedPropagationContext = default; - Metadata capturedCarrier = null; - var propagatorCalled = 0; - var originalMetadataCount = additionalMetadata.Count; - - mockPropagator - .Setup( - x => x.Inject( - It.IsAny(), - It.IsAny(), - It.IsAny>())) - .Callback>( - (propagation, carrier, setter) => - { - propagatorCalled++; - capturedPropagationContext = propagation; - capturedCarrier = carrier; - - // Make sure the original metadata make it through - if (additionalMetadata != null) - { - Assert.Equal(capturedCarrier, additionalMetadata); - } - - // Call the actual setter to ensure it updates the carrier. - // It doesn't matter what we put in - setter(capturedCarrier, "bar", "baz"); - }); - - using var server = FoobarService.Start(); - var interceptorOptions = new ClientTracingInterceptorOptions - { - Propagator = mockPropagator.Object, - RecordMessageEvents = true, - ActivityIdentifierValue = Guid.NewGuid(), - }; + /// + /// Tests basic handler success. + /// + /// The client request function. + /// The additional metadata, if any. + /// A Task. + private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) + { + var mockPropagator = new Mock(); + PropagationContext capturedPropagationContext = default; + Metadata capturedCarrier = null; + var propagatorCalled = 0; + var originalMetadataCount = additionalMetadata.Count; + + mockPropagator + .Setup( + x => x.Inject( + It.IsAny(), + It.IsAny(), + It.IsAny>())) + .Callback>( + (propagation, carrier, setter) => + { + propagatorCalled++; + capturedPropagationContext = propagation; + capturedCarrier = carrier; - // No Activity parent - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + // Make sure the original metadata make it through + if (additionalMetadata != null) + { + Assert.Equal(capturedCarrier, additionalMetadata); + } - Assert.Equal(default, Activity.Current); + // Call the actual setter to ensure it updates the carrier. + // It doesn't matter what we put in + setter(capturedCarrier, "bar", "baz"); + }); - var activity = activityListener.Activity; + using var server = FoobarService.Start(); + var interceptorOptions = new ClientTracingInterceptorOptions + { + Propagator = mockPropagator.Object, + RecordMessageEvents = true, + ActivityIdentifierValue = Guid.NewGuid(), + }; - // Propagator was called exactly once - Assert.Equal(1, propagatorCalled); + // No Activity parent + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - // The client tracing interceptor should create a copy of the original call headers before passing to the propagator. - // Retries that sit above this interceptor rely on the original call metadata. - // The propagator should not have mutated the original CallOption headers. - Assert.Equal(originalMetadataCount, additionalMetadata.Count); + Assert.Equal(default, Activity.Current); - // There was no parent activity, so these will be default - Assert.Equal(default, capturedPropagationContext.ActivityContext.TraceId); - Assert.Equal(default, capturedPropagationContext.ActivityContext.SpanId); + var activity = activityListener.Activity; - // Sanity check a valid metadata injection setter. - Assert.NotEmpty(capturedCarrier); + // Propagator was called exactly once + Assert.Equal(1, propagatorCalled); - ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(default, activity.ParentSpanId); - } + // The client tracing interceptor should create a copy of the original call headers before passing to the propagator. + // Retries that sit above this interceptor rely on the original call metadata. + // The propagator should not have mutated the original CallOption headers. + Assert.Equal(originalMetadataCount, additionalMetadata.Count); - propagatorCalled = 0; - capturedPropagationContext = default; + // There was no parent activity, so these will be default + Assert.Equal(default, capturedPropagationContext.ActivityContext.TraceId); + Assert.Equal(default, capturedPropagationContext.ActivityContext.SpanId); - // Activity has a parent - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - using var parentActivity = new Activity("foo"); - parentActivity.SetIdFormat(ActivityIdFormat.W3C); - parentActivity.Start(); - var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + // Sanity check a valid metadata injection setter. + Assert.NotEmpty(capturedCarrier); - Assert.Equal(parentActivity, Activity.Current); + ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(default, activity.ParentSpanId); + } - // Propagator was called exactly once - Assert.Equal(1, propagatorCalled); + propagatorCalled = 0; + capturedPropagationContext = default; - // There was a parent activity, so these will have something in them. - Assert.NotEqual(default, capturedPropagationContext.ActivityContext.TraceId); - Assert.NotEqual(default, capturedPropagationContext.ActivityContext.SpanId); + // Activity has a parent + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + using var parentActivity = new Activity("foo"); + parentActivity.SetIdFormat(ActivityIdFormat.W3C); + parentActivity.Start(); + var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(interceptorOptions)); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - var activity = activityListener.Activity; - ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(parentActivity.Id, activity.ParentId); - } - } + Assert.Equal(parentActivity, Activity.Current); - /// - /// Tests basic handler failure. Instructs the server to fail with resources exhausted and validates the created Activity. - /// - /// The client request function. - /// The status code to use for the failure. Defaults to ResourceExhausted. - /// if set to true [validate error description]. - /// An alternate server URI string. - /// - /// A Task. - /// - private async Task TestHandlerFailure( - Func clientRequestFunc, - StatusCode statusCode = StatusCode.ResourceExhausted, - bool validateErrorDescription = true, - string serverUriString = null) - { - using var server = FoobarService.Start(); - var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - var client = FoobarService.ConstructRpcClient( - serverUriString ?? server.UriString, - new ClientTracingInterceptor(clientInterceptorOptions), - new List - { - new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), - new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), - }); + // Propagator was called exactly once + Assert.Equal(1, propagatorCalled); - using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); - await Assert.ThrowsAsync(async () => await clientRequestFunc(client, null).ConfigureAwait(false)); + // There was a parent activity, so these will have something in them. + Assert.NotEqual(default, capturedPropagationContext.ActivityContext.TraceId); + Assert.NotEqual(default, capturedPropagationContext.ActivityContext.SpanId); var activity = activityListener.Activity; - ValidateCommonActivityTags(activity, statusCode, false); + ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(parentActivity.Id, activity.ParentId); + } + } - if (validateErrorDescription) + /// + /// Tests basic handler failure. Instructs the server to fail with resources exhausted and validates the created Activity. + /// + /// The client request function. + /// The status code to use for the failure. Defaults to ResourceExhausted. + /// if set to true [validate error description]. + /// An alternate server URI string. + /// + /// A Task. + /// + private async Task TestHandlerFailure( + Func clientRequestFunc, + StatusCode statusCode = StatusCode.ResourceExhausted, + bool validateErrorDescription = true, + string serverUriString = null) + { + using var server = FoobarService.Start(); + var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; + var client = FoobarService.ConstructRpcClient( + serverUriString ?? server.UriString, + new ClientTracingInterceptor(clientInterceptorOptions), + new List { - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusDescription && ((string)t.Value).Contains("fubar")); - } - } + new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), + new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), + }); - /// - /// Tests for Activity cancellation when the handler is disposed before completing the RPC. - /// - /// The client request action. - private void TestActivityIsCancelledWhenHandlerDisposed(Action clientRequestAction) - { - using var server = FoobarService.Start(); - var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); - var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(clientInterceptorOptions)); - clientRequestAction(client); + using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); + await Assert.ThrowsAsync(async () => await clientRequestFunc(client, null).ConfigureAwait(false)); - var activity = activityListener.Activity; - ValidateCommonActivityTags(activity, StatusCode.Cancelled, false); + var activity = activityListener.Activity; + ValidateCommonActivityTags(activity, statusCode, false); + + if (validateErrorDescription) + { + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeOtelStatusDescription && ((string)t.Value).Contains("fubar")); } } + + /// + /// Tests for Activity cancellation when the handler is disposed before completing the RPC. + /// + /// The client request action. + private void TestActivityIsCancelledWhenHandlerDisposed(Action clientRequestAction) + { + using var server = FoobarService.Start(); + var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; + using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); + var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(clientInterceptorOptions)); + clientRequestAction(client); + + var activity = activityListener.Activity; + ValidateCommonActivityTags(activity, StatusCode.Cancelled, false); + } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 86b0179094..947f6cc88b 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -21,161 +21,160 @@ using OpenTelemetry.Context.Propagation; using Xunit; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test +namespace OpenTelemetry.Instrumentation.GrpcCore.Test; + +/// +/// Grpc Core server interceptor tests. +/// +public class GrpcCoreServerInterceptorTests { /// - /// Grpc Core server interceptor tests. + /// Validates a successful UnaryServerHandler call. /// - public class GrpcCoreServerInterceptorTests + /// A task. + [Fact] + public async Task UnaryServerHandlerSuccess() { - /// - /// Validates a successful UnaryServerHandler call. - /// - /// A task. - [Fact] - public async Task UnaryServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); - } - - /// - /// Validates a failed UnaryServerHandler call. - /// - /// A task. - [Fact] - public async Task UnaryServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); - } + await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + } - /// - /// Validates a successful ClientStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ClientStreamingServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); - } + /// + /// Validates a failed UnaryServerHandler call. + /// + /// A task. + [Fact] + public async Task UnaryServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + } - /// - /// Validates a failed ClientStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ClientStreamingServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); - } + /// + /// Validates a successful ClientStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ClientStreamingServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a successful ServerStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ServerStreamingServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); - } + /// + /// Validates a failed ClientStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ClientStreamingServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a failed ServerStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task ServerStreamingServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); - } + /// + /// Validates a successful ServerStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ServerStreamingServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a successful DuplexStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingServerHandlerSuccess() - { - await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); - } + /// + /// Validates a failed ServerStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task ServerStreamingServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + } - /// - /// Validates a failed DuplexStreamingServerHandler call. - /// - /// A task. - [Fact] - public async Task DuplexStreamingServerHandlerFail() - { - await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); - } + /// + /// Validates a successful DuplexStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingServerHandlerSuccess() + { + await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + } - /// - /// A common method to test server interceptor handler success. - /// - /// The specific client request function. - /// The additional metadata, if any. - /// A Task. - private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) - { - // starts the server with the server interceptor - var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid() }; - using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); + /// + /// Validates a failed DuplexStreamingServerHandler call. + /// + /// A task. + [Fact] + public async Task DuplexStreamingServerHandlerFail() + { + await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + } - // No parent Activity, no context from header - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - var client = FoobarService.ConstructRpcClient(server.UriString); - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); + /// + /// A common method to test server interceptor handler success. + /// + /// The specific client request function. + /// The additional metadata, if any. + /// A Task. + private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) + { + // starts the server with the server interceptor + var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid() }; + using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); - var activity = activityListener.Activity; - GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(default, activity.ParentSpanId); - } + // No parent Activity, no context from header + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + { + var client = FoobarService.ConstructRpcClient(server.UriString); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - // No parent Activity, context from header - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) - { - var client = FoobarService.ConstructRpcClient( - server.UriString, - additionalMetadata: new List - { - new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), - }); - - await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); - - var activity = activityListener.Activity; - GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); - Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); - } + var activity = activityListener.Activity; + GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); + Assert.Equal(default, activity.ParentSpanId); } - /// - /// A common method to test server interceptor handler failure. - /// - /// The specific client request function. - /// The additional metadata, if any. - /// A Task. - private async Task TestHandlerFailure(Func clientRequestFunc, Metadata additionalMetadata = null) + // No parent Activity, context from header + using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) { - // starts the server with the server interceptor - var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); - - using var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue); var client = FoobarService.ConstructRpcClient( server.UriString, additionalMetadata: new List { new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), - new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, StatusCode.ResourceExhausted.ToString()), - new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), }); - await Assert.ThrowsAsync(async () => await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false)); + await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); var activity = activityListener.Activity; - GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.ResourceExhausted, interceptorOptions.RecordMessageEvents); + GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.OK, interceptorOptions.RecordMessageEvents); Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); } } + + /// + /// A common method to test server interceptor handler failure. + /// + /// The specific client request function. + /// The additional metadata, if any. + /// A Task. + private async Task TestHandlerFailure(Func clientRequestFunc, Metadata additionalMetadata = null) + { + // starts the server with the server interceptor + var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; + using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); + + using var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue); + var client = FoobarService.ConstructRpcClient( + server.UriString, + additionalMetadata: new List + { + new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), + new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, StatusCode.ResourceExhausted.ToString()), + new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), + }); + + await Assert.ThrowsAsync(async () => await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false)); + + var activity = activityListener.Activity; + GrpcCoreClientInterceptorTests.ValidateCommonActivityTags(activity, StatusCode.ResourceExhausted, interceptorOptions.RecordMessageEvents); + Assert.Equal(FoobarService.DefaultParentFromTraceparentHeader.SpanId, activity.ParentSpanId); + } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index 2dcfc759e2..662f013ec5 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -18,57 +18,56 @@ using System.Diagnostics; using System.Linq; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test +namespace OpenTelemetry.Instrumentation.GrpcCore.Test; + +/// +/// This class listens for a single Activity created by the Grpc Core interceptors. +/// +internal sealed class InterceptorActivityListener : IDisposable { /// - /// This class listens for a single Activity created by the Grpc Core interceptors. + /// The activity listener. /// - internal sealed class InterceptorActivityListener : IDisposable - { - /// - /// The activity listener. - /// - private readonly ActivityListener activityListener; + private readonly ActivityListener activityListener; - /// - /// Initializes a new instance of the class. - /// - /// The activity identifier. - public InterceptorActivityListener(Guid activityIdentifier) + /// + /// Initializes a new instance of the class. + /// + /// The activity identifier. + public InterceptorActivityListener(Guid activityIdentifier) + { + this.activityListener = new ActivityListener { - this.activityListener = new ActivityListener + ShouldListenTo = source => source.Name == GrpcCoreInstrumentation.ActivitySourceName, + ActivityStarted = activity => { - ShouldListenTo = source => source.Name == GrpcCoreInstrumentation.ActivitySourceName, - ActivityStarted = activity => + if (activity.TagObjects.Any(t => t.Key == SemanticConventions.AttributeActivityIdentifier && (Guid)t.Value == activityIdentifier)) { - if (activity.TagObjects.Any(t => t.Key == SemanticConventions.AttributeActivityIdentifier && (Guid)t.Value == activityIdentifier)) - { - this.Activity = activity; - } - }, - Sample = this.Sample, - }; - - ActivitySource.AddActivityListener(this.activityListener); - Debug.Assert(GrpcCoreInstrumentation.ActivitySource.HasListeners(), "activity source has no listeners"); - } + this.Activity = activity; + } + }, + Sample = this.Sample, + }; - /// - /// Gets the started Activity. - /// - public Activity Activity { get; private set; } + ActivitySource.AddActivityListener(this.activityListener); + Debug.Assert(GrpcCoreInstrumentation.ActivitySource.HasListeners(), "activity source has no listeners"); + } - /// - public void Dispose() - { - this.activityListener.Dispose(); - } + /// + /// Gets the started Activity. + /// + public Activity Activity { get; private set; } - /// - /// Always sample. - /// - /// The options. - /// a result. - private ActivitySamplingResult Sample(ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; + /// + public void Dispose() + { + this.activityListener.Dispose(); } + + /// + /// Always sample. + /// + /// The options. + /// a result. + private ActivitySamplingResult Sample(ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; } From c44a25b5fa4f9dacb805997724629916c969eccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 11 Aug 2022 17:50:05 +0200 Subject: [PATCH 0282/1499] [Instrumenation.EventCounters] File scoped namespace (#577) --- .../EventCounterListener.cs | 245 ++++++++------- .../EventCounterMetricsOptions.cs | 17 +- ...EventCountersInstrumentationEventSource.cs | 45 ++- .../MeterProviderBuilderExtensions.cs | 39 ++- .../EventCounterListenerTests.cs | 291 +++++++++--------- .../MeterProviderBuilderExtensionsTests.cs | 17 +- .../TestEventCounter.cs | 41 ++- .../TestIncrementingEventCounter.cs | 31 +- .../TestIncrementingPollingCounter.cs | 25 +- .../TestPollingEventCounter.cs | 25 +- 10 files changed, 383 insertions(+), 393 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs index 597c6734f9..b8ee562d94 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs @@ -21,170 +21,169 @@ using System.Diagnostics.Tracing; using System.Reflection; -namespace OpenTelemetry.Instrumentation.EventCounters +namespace OpenTelemetry.Instrumentation.EventCounters; + +internal class EventCounterListener : EventListener { - internal class EventCounterListener : EventListener + internal static readonly AssemblyName AssemblyName = typeof(EventCounterListener).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name; + internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + + private readonly bool isInitialized = false; + private readonly Meter meter; + private readonly EventCounterMetricsOptions options; + private readonly ConcurrentDictionary metricInstruments = new(); + private readonly ConcurrentDictionary lastValue = new(); + private readonly ConcurrentBag eventSources = new(); + + public EventCounterListener(EventCounterMetricsOptions options) { - internal static readonly AssemblyName AssemblyName = typeof(EventCounterListener).Assembly.GetName(); - internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); - - private readonly bool isInitialized = false; - private readonly Meter meter; - private readonly EventCounterMetricsOptions options; - private readonly ConcurrentDictionary metricInstruments = new(); - private readonly ConcurrentDictionary lastValue = new(); - private readonly ConcurrentBag eventSources = new(); - - public EventCounterListener(EventCounterMetricsOptions options) - { - this.meter = new Meter(InstrumentationName, InstrumentationVersion); - this.options = options ?? throw new ArgumentNullException(nameof(options)); + this.meter = new Meter(InstrumentationName, InstrumentationVersion); + this.options = options ?? throw new ArgumentNullException(nameof(options)); - this.isInitialized = true; - this.EnablePendingEventSources(); // Some OnEventSourceCreated may have fired before constructor, enable them - } + this.isInitialized = true; + this.EnablePendingEventSources(); // Some OnEventSourceCreated may have fired before constructor, enable them + } - private enum InstrumentType - { - ObservableGauge, - ObservableCounter, - } + private enum InstrumentType + { + ObservableGauge, + ObservableCounter, + } - private Dictionary EnableEventArgs => new() { ["EventCounterIntervalSec"] = this.options.RefreshIntervalSecs.ToString(), }; + private Dictionary EnableEventArgs => new() { ["EventCounterIntervalSec"] = this.options.RefreshIntervalSecs.ToString(), }; - protected override void OnEventSourceCreated(EventSource source) + protected override void OnEventSourceCreated(EventSource source) + { + // TODO: Add Configuration options to selectively subscribe to EventCounters + try { - // TODO: Add Configuration options to selectively subscribe to EventCounters - try + if (!this.isInitialized) { - if (!this.isInitialized) - { - this.eventSources.Add(source); - } - else - { - this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); - } + this.eventSources.Add(source); } - catch (Exception ex) + else { - EventCountersInstrumentationEventSource.Log.ErrorEventCounter(source.Name, ex.Message); + this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); } } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.ErrorEventCounter(source.Name, ex.Message); + } + } - protected override void OnEventWritten(EventWrittenEventArgs eventData) + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + if (!eventData.EventName.Equals("EventCounters") || !this.isInitialized) { - if (!eventData.EventName.Equals("EventCounters") || !this.isInitialized) - { - return; - } + return; + } - try + try + { + if (eventData.Payload.Count > 0 && eventData.Payload[0] is IDictionary eventPayload) { - if (eventData.Payload.Count > 0 && eventData.Payload[0] is IDictionary eventPayload) - { - this.ExtractAndPostMetric(eventData.EventSource.Name, eventPayload); - } - else - { - EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenAsEventPayloadNotParseable(eventData.EventSource.Name); - } + this.ExtractAndPostMetric(eventData.EventSource.Name, eventPayload); } - catch (Exception ex) + else { - EventCountersInstrumentationEventSource.Log.ErrorEventCounter(eventData.EventName, ex.ToString()); + EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenAsEventPayloadNotParseable(eventData.EventSource.Name); } } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.ErrorEventCounter(eventData.EventName, ex.ToString()); + } + } - private void ExtractAndPostMetric(string eventSourceName, IDictionary eventPayload) + private void ExtractAndPostMetric(string eventSourceName, IDictionary eventPayload) + { + try { - try - { - bool calculateRate = false; - double actualValue = 0; + bool calculateRate = false; + double actualValue = 0; - string counterName = string.Empty; - string counterDisplayName = string.Empty; - InstrumentType instrumentType = InstrumentType.ObservableGauge; + string counterName = string.Empty; + string counterDisplayName = string.Empty; + InstrumentType instrumentType = InstrumentType.ObservableGauge; - foreach (KeyValuePair payload in eventPayload) + foreach (KeyValuePair payload in eventPayload) + { + var key = payload.Key; + if (key.Equals("Name", StringComparison.OrdinalIgnoreCase)) { - var key = payload.Key; - if (key.Equals("Name", StringComparison.OrdinalIgnoreCase)) - { - counterName = payload.Value.ToString(); - } - else - if (key.Equals("DisplayName", StringComparison.OrdinalIgnoreCase)) - { - counterDisplayName = payload.Value.ToString(); - } - else if (key.Equals("Mean", StringComparison.OrdinalIgnoreCase)) - { - instrumentType = InstrumentType.ObservableGauge; - actualValue = Convert.ToDouble(payload.Value); - } - else if (key.Equals("Increment", StringComparison.OrdinalIgnoreCase)) - { - // Increment indicates we have to calculate rate. - instrumentType = InstrumentType.ObservableCounter; - calculateRate = true; - actualValue = Convert.ToDouble(payload.Value); - } + counterName = payload.Value.ToString(); + } + else + if (key.Equals("DisplayName", StringComparison.OrdinalIgnoreCase)) + { + counterDisplayName = payload.Value.ToString(); + } + else if (key.Equals("Mean", StringComparison.OrdinalIgnoreCase)) + { + instrumentType = InstrumentType.ObservableGauge; + actualValue = Convert.ToDouble(payload.Value); + } + else if (key.Equals("Increment", StringComparison.OrdinalIgnoreCase)) + { + // Increment indicates we have to calculate rate. + instrumentType = InstrumentType.ObservableCounter; + calculateRate = true; + actualValue = Convert.ToDouble(payload.Value); } - - this.RecordMetric(eventSourceName, counterName, counterDisplayName, instrumentType, actualValue, calculateRate); - } - catch (Exception ex) - { - EventCountersInstrumentationEventSource.Log.EventCountersInstrumentationWarning("ExtractMetric", ex.Message); } + + this.RecordMetric(eventSourceName, counterName, counterDisplayName, instrumentType, actualValue, calculateRate); + } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.EventCountersInstrumentationWarning("ExtractMetric", ex.Message); } + } - private void RecordMetric(string eventSourceName, string counterName, string displayName, InstrumentType instrumentType, double value, bool calculateRate) + private void RecordMetric(string eventSourceName, string counterName, string displayName, InstrumentType instrumentType, double value, bool calculateRate) + { + var metricKey = new MetricKey(eventSourceName, counterName); + var description = string.IsNullOrEmpty(displayName) ? counterName : displayName; + this.lastValue[metricKey] = calculateRate ? value / this.options.RefreshIntervalSecs : value; + switch (instrumentType) { - var metricKey = new MetricKey(eventSourceName, counterName); - var description = string.IsNullOrEmpty(displayName) ? counterName : displayName; - this.lastValue[metricKey] = calculateRate ? value / this.options.RefreshIntervalSecs : value; - switch (instrumentType) - { - case InstrumentType.ObservableCounter: - this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableCounter(counterName, () => this.ObserveDouble(metricKey), description: description)); - break; + case InstrumentType.ObservableCounter: + this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableCounter(counterName, () => this.ObserveDouble(metricKey), description: description)); + break; - case InstrumentType.ObservableGauge: - this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableGauge(counterName, () => this.ObserveDouble(metricKey), description: description)); - break; - } + case InstrumentType.ObservableGauge: + this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableGauge(counterName, () => this.ObserveDouble(metricKey), description: description)); + break; } + } - private double ObserveDouble(MetricKey key) => this.lastValue[key]; + private double ObserveDouble(MetricKey key) => this.lastValue[key]; - private void EnablePendingEventSources() + private void EnablePendingEventSources() + { + foreach (var source in this.eventSources) { - foreach (var source in this.eventSources) - { - this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); - } + this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); } + } - private class MetricKey + private class MetricKey + { + public MetricKey(string eventSourceName, string counterName) { - public MetricKey(string eventSourceName, string counterName) - { - this.EventSourceName = eventSourceName; - this.CounterName = counterName; - } + this.EventSourceName = eventSourceName; + this.CounterName = counterName; + } - public string EventSourceName { get; private set; } + public string EventSourceName { get; private set; } - public string CounterName { get; private set; } + public string CounterName { get; private set; } - public override int GetHashCode() => (this.EventSourceName, this.CounterName).GetHashCode(); + public override int GetHashCode() => (this.EventSourceName, this.CounterName).GetHashCode(); - public override bool Equals(object obj) => - obj is MetricKey nextKey && this.EventSourceName == nextKey.EventSourceName && this.CounterName == nextKey.CounterName; - } + public override bool Equals(object obj) => + obj is MetricKey nextKey && this.EventSourceName == nextKey.EventSourceName && this.CounterName == nextKey.CounterName; } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs index 8163ca2faa..0152da017e 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs @@ -14,16 +14,15 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.EventCounters +namespace OpenTelemetry.Instrumentation.EventCounters; + +/// +/// EventCounterMetrics Options. +/// +public class EventCounterMetricsOptions { /// - /// EventCounterMetrics Options. + /// Gets or sets the subscription interval in seconds. /// - public class EventCounterMetricsOptions - { - /// - /// Gets or sets the subscription interval in seconds. - /// - public int RefreshIntervalSecs { get; set; } = 60; - } + public int RefreshIntervalSecs { get; set; } = 60; } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs index ba75cb2da0..f3d0d431ce 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs @@ -16,32 +16,31 @@ using System.Diagnostics.Tracing; -namespace OpenTelemetry.Instrumentation.EventCounters +namespace OpenTelemetry.Instrumentation.EventCounters; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-EventCounters")] +internal class EventCountersInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-EventCounters")] - internal class EventCountersInstrumentationEventSource : EventSource - { - public static readonly EventCountersInstrumentationEventSource Log = new(); + public static readonly EventCountersInstrumentationEventSource Log = new(); - [Event(1, Message = "Error occurred while processing eventCounter, EventCounter: {0}, Exception: {2}", Level = EventLevel.Error)] - public void ErrorEventCounter(string counterName, string exception) - { - this.WriteEvent(1, counterName, exception); - } + [Event(1, Message = "Error occurred while processing eventCounter, EventCounter: {0}, Exception: {2}", Level = EventLevel.Error)] + public void ErrorEventCounter(string counterName, string exception) + { + this.WriteEvent(1, counterName, exception); + } - [Event(2, Level = EventLevel.Warning, Message = @"Ignoring event written from EventSource: {0} as payload is not IDictionary to extract metrics.")] - public void IgnoreEventWrittenAsEventPayloadNotParseable(string eventSourceName) - { - this.WriteEvent(4, eventSourceName); - } + [Event(2, Level = EventLevel.Warning, Message = @"Ignoring event written from EventSource: {0} as payload is not IDictionary to extract metrics.")] + public void IgnoreEventWrittenAsEventPayloadNotParseable(string eventSourceName) + { + this.WriteEvent(4, eventSourceName); + } - [Event(3, Level = EventLevel.Warning, Message = @"EventCountersInstrumentation - {0} failed with exception: {1}.")] - public void EventCountersInstrumentationWarning(string stage, string exceptionMessage) - { - this.WriteEvent(8, stage, exceptionMessage); - } + [Event(3, Level = EventLevel.Warning, Message = @"EventCountersInstrumentation - {0} failed with exception: {1}.")] + public void EventCountersInstrumentationWarning(string stage, string exceptionMessage) + { + this.WriteEvent(8, stage, exceptionMessage); } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index af114abb45..bb13a85281 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -18,31 +18,30 @@ using OpenTelemetry.Instrumentation.EventCounters; using OpenTelemetry.Internal; -namespace OpenTelemetry.Metrics +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class MeterProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables EventCounter instrumentation. /// - public static class MeterProviderBuilderExtensions + /// being configured. + /// Runtime metrics options. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddEventCounterMetrics( + this MeterProviderBuilder builder, + Action configure = null) { - /// - /// Enables EventCounter instrumentation. - /// - /// being configured. - /// Runtime metrics options. - /// The instance of to chain the calls. - public static MeterProviderBuilder AddEventCounterMetrics( - this MeterProviderBuilder builder, - Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var options = new EventCounterMetricsOptions(); - configure?.Invoke(options); + var options = new EventCounterMetricsOptions(); + configure?.Invoke(options); - var instrumentation = new EventCounterListener(options); - builder.AddMeter(EventCounterListener.InstrumentationName); - return builder.AddInstrumentation(() => instrumentation); - } + var instrumentation = new EventCounterListener(options); + builder.AddMeter(EventCounterListener.InstrumentationName); + return builder.AddInstrumentation(() => instrumentation); } } diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs index 794337f970..eab325222c 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs @@ -19,182 +19,181 @@ using OpenTelemetry.Metrics; using Xunit; -namespace OpenTelemetry.Instrumentation.EventCounters.Tests +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; + +public class EventCounterListenerTests { - public class EventCounterListenerTests + private const int MaxTimeToAllowForFlush = 10000; + private MeterProvider meterProvider; + + [Fact] + public async Task SystemMetricsAreCaptured() { - private const int MaxTimeToAllowForFlush = 10000; - private MeterProvider meterProvider; + var metricItems = new List(); - [Fact] - public async Task SystemMetricsAreCaptured() - { - var metricItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 1; + }) + .AddInMemoryExporter(metricItems) + .Build(); - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 1; - }) - .AddInMemoryExporter(metricItems) - .Build(); + await Task.Delay(2000); + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - await Task.Delay(2000); - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + this.meterProvider.Dispose(); - this.meterProvider.Dispose(); + Assert.True(metricItems.Count > 1); + } - Assert.True(metricItems.Count > 1); - } + [Fact(Skip = "Unstable")] + public async Task TestEventCounterMetricsAreCaptured() + { + const int refreshIntervalSeconds = 1; + var metricItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 1; + }) + .AddInMemoryExporter(metricItems) + .Build(); + var expected = new[] { 100.3F, 200.1F }; + TestEventCounter.Log.SampleCounter1(expected[0]); + TestEventCounter.Log.SampleCounter2(expected[1]); - [Fact(Skip = "Unstable")] - public async Task TestEventCounterMetricsAreCaptured() - { - const int refreshIntervalSeconds = 1; - var metricItems = new List(); - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 1; - }) - .AddInMemoryExporter(metricItems) - .Build(); - var expected = new[] { 100.3F, 200.1F }; - TestEventCounter.Log.SampleCounter1(expected[0]); - TestEventCounter.Log.SampleCounter2(expected[1]); - - // Wait a little bit over the refresh interval seconds - await Task.Delay((refreshIntervalSeconds * 1000) + 300); - - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - var counter1 = metricItems.Find(m => m.Name == "mycountername1"); - var counter2 = metricItems.Find(m => m.Name == "mycountername2"); - Assert.NotNull(counter1); - Assert.NotNull(counter2); - Assert.Equal(MetricType.DoubleGauge, counter1.MetricType); // EventCounter CounterType is `Mean` - - Assert.Equal(expected[0], GetActualValue(counter1)); - Assert.Equal(expected[1], GetActualValue(counter2)); - } + // Wait a little bit over the refresh interval seconds + await Task.Delay((refreshIntervalSeconds * 1000) + 300); - [Fact(Skip = "Unstable")] - public async Task TestIncrementingEventCounterMetricsAreCaptured() - { - const int refreshIntervalSeconds = 1; - var metricItems = new List(); - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 1; - }) - .AddInMemoryExporter(metricItems) - .Build(); - - TestIncrementingEventCounter.Log.SampleCounter1(1); - TestIncrementingEventCounter.Log.SampleCounter1(1); - TestIncrementingEventCounter.Log.SampleCounter1(1); - - // Wait a little bit over the refresh interval seconds - await Task.Delay((refreshIntervalSeconds * 1000) + 300); - - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - var counter = metricItems.Find(m => m.Name == TestIncrementingEventCounter.CounterName); - Assert.NotNull(counter); - Assert.Equal(MetricType.DoubleSum, counter.MetricType); // EventCounter CounterType is `Sum` - Assert.Equal(3, GetActualValue(counter)); - } + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - [Fact(Skip = "Unstable")] - public async Task TestPollingCounterMetricsAreCaptured() - { - var metricItems = new List(); - const int refreshIntervalSeconds = 1; + this.meterProvider.Dispose(); - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = refreshIntervalSeconds; - }) - .AddInMemoryExporter(metricItems) - .Build(); + var counter1 = metricItems.Find(m => m.Name == "mycountername1"); + var counter2 = metricItems.Find(m => m.Name == "mycountername2"); + Assert.NotNull(counter1); + Assert.NotNull(counter2); + Assert.Equal(MetricType.DoubleGauge, counter1.MetricType); // EventCounter CounterType is `Mean` + + Assert.Equal(expected[0], GetActualValue(counter1)); + Assert.Equal(expected[1], GetActualValue(counter2)); + } - int i = 0; - TestPollingEventCounter.CreateSingleton(() => ++i * 10); + [Fact(Skip = "Unstable")] + public async Task TestIncrementingEventCounterMetricsAreCaptured() + { + const int refreshIntervalSeconds = 1; + var metricItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = 1; + }) + .AddInMemoryExporter(metricItems) + .Build(); - var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice - await Task.Delay(duration); + TestIncrementingEventCounter.Log.SampleCounter1(1); + TestIncrementingEventCounter.Log.SampleCounter1(1); + TestIncrementingEventCounter.Log.SampleCounter1(1); - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + // Wait a little bit over the refresh interval seconds + await Task.Delay((refreshIntervalSeconds * 1000) + 300); - this.meterProvider.Dispose(); + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var pollingCounter = metricItems.Find(m => m.Name == TestPollingEventCounter.CounterName); - Assert.NotNull(pollingCounter); - Assert.Equal(MetricType.DoubleGauge, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Mean` + this.meterProvider.Dispose(); - var expected = i * 10; // The last recorded `Mean` value - Assert.Equal(expected, GetActualValue(pollingCounter)); - } + var counter = metricItems.Find(m => m.Name == TestIncrementingEventCounter.CounterName); + Assert.NotNull(counter); + Assert.Equal(MetricType.DoubleSum, counter.MetricType); // EventCounter CounterType is `Sum` + Assert.Equal(3, GetActualValue(counter)); + } - [Fact(Skip = "Unstable")] - public async Task TestIncrementingPollingCounterMetrics() - { - var metricItems = new List(); - const int refreshIntervalSeconds = 1; + [Fact(Skip = "Unstable")] + public async Task TestPollingCounterMetricsAreCaptured() + { + var metricItems = new List(); + const int refreshIntervalSeconds = 1; - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = refreshIntervalSeconds; - }) - .AddInMemoryExporter(metricItems) - .Build(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = refreshIntervalSeconds; + }) + .AddInMemoryExporter(metricItems) + .Build(); - int i = 1; + int i = 0; + TestPollingEventCounter.CreateSingleton(() => ++i * 10); - TestIncrementingPollingCounter.CreateSingleton(() => i++); + var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice + await Task.Delay(duration); - var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice - await Task.Delay(duration); + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + this.meterProvider.Dispose(); - this.meterProvider.Dispose(); + var pollingCounter = metricItems.Find(m => m.Name == TestPollingEventCounter.CounterName); + Assert.NotNull(pollingCounter); + Assert.Equal(MetricType.DoubleGauge, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Mean` - var pollingCounter = metricItems.Find(m => m.Name == TestIncrementingPollingCounter.CounterName); - Assert.NotNull(pollingCounter); - Assert.Equal(MetricType.DoubleSum, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Sum` + var expected = i * 10; // The last recorded `Mean` value + Assert.Equal(expected, GetActualValue(pollingCounter)); + } - Assert.Equal(1, GetActualValue(pollingCounter)); - } + [Fact(Skip = "Unstable")] + public async Task TestIncrementingPollingCounterMetrics() + { + var metricItems = new List(); + const int refreshIntervalSeconds = 1; + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCounterMetrics(options => + { + options.RefreshIntervalSecs = refreshIntervalSeconds; + }) + .AddInMemoryExporter(metricItems) + .Build(); + + int i = 1; + + TestIncrementingPollingCounter.CreateSingleton(() => i++); + + var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice + await Task.Delay(duration); - /// - /// Event Counters are always Sum or Mean and are always record with `float`. - /// - /// Metric to Aggregate. - /// The Aggregated value. - private static double GetActualValue(Metric metric) + this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + this.meterProvider.Dispose(); + + var pollingCounter = metricItems.Find(m => m.Name == TestIncrementingPollingCounter.CounterName); + Assert.NotNull(pollingCounter); + Assert.Equal(MetricType.DoubleSum, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Sum` + + Assert.Equal(1, GetActualValue(pollingCounter)); + } + + /// + /// Event Counters are always Sum or Mean and are always record with `float`. + /// + /// Metric to Aggregate. + /// The Aggregated value. + private static double GetActualValue(Metric metric) + { + double sum = 0; + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { - double sum = 0; - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + if (metric.MetricType.IsSum()) { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumDouble(); - } - else - { - sum += metricPoint.GetGaugeLastValueDouble(); - } + sum += metricPoint.GetSumDouble(); + } + else + { + sum += metricPoint.GetGaugeLastValueDouble(); } - - return sum; } + + return sum; } } diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs index deb6e743b2..22020300ed 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs @@ -18,17 +18,16 @@ using OpenTelemetry.Metrics; using Xunit; -namespace OpenTelemetry.Instrumentation.EventCounters.Tests +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; + +public class MeterProviderBuilderExtensionsTests { - public class MeterProviderBuilderExtensionsTests + [Fact] + public void Throws_Exception_When_Builder_Is_Null() { - [Fact] - public void Throws_Exception_When_Builder_Is_Null() - { - MeterProviderBuilder builder = null; + MeterProviderBuilder builder = null; - Func action = () => builder.AddEventCounterMetrics(); - Assert.Throws(action); - } + Func action = () => builder.AddEventCounterMetrics(); + Assert.Throws(action); } } diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs index d359a81d1e..eeaac2b030 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs @@ -16,30 +16,29 @@ using System.Diagnostics.Tracing; -namespace OpenTelemetry.Instrumentation.EventCounters.Tests +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; + +[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestEventCounter")] +public sealed class TestEventCounter : EventSource { - [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestEventCounter")] - public sealed class TestEventCounter : EventSource - { - // define the singleton instance of the event source - public static TestEventCounter Log = new TestEventCounter(); - private EventCounter testCounter1; - private EventCounter testCounter2; + // define the singleton instance of the event source + public static TestEventCounter Log = new TestEventCounter(); + private EventCounter testCounter1; + private EventCounter testCounter2; - private TestEventCounter() - { - this.testCounter1 = new EventCounter("mycountername1", this); - this.testCounter2 = new EventCounter("mycountername2", this); - } + private TestEventCounter() + { + this.testCounter1 = new EventCounter("mycountername1", this); + this.testCounter2 = new EventCounter("mycountername2", this); + } - public void SampleCounter1(float counterValue) - { - this.testCounter1.WriteMetric(counterValue); - } + public void SampleCounter1(float counterValue) + { + this.testCounter1.WriteMetric(counterValue); + } - public void SampleCounter2(float counterValue) - { - this.testCounter2.WriteMetric(counterValue); - } + public void SampleCounter2(float counterValue) + { + this.testCounter2.WriteMetric(counterValue); } } diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs index f73ac8406a..5cd33ba0bd 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs @@ -16,25 +16,24 @@ using System.Diagnostics.Tracing; -namespace OpenTelemetry.Instrumentation.EventCounters.Tests +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; + +[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestIncrementingEventCounter")] +public sealed class TestIncrementingEventCounter : EventSource { - [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestIncrementingEventCounter")] - public sealed class TestIncrementingEventCounter : EventSource - { - public const string CounterName = "IncrementingEventCounter"; + public const string CounterName = "IncrementingEventCounter"; - // define the singleton instance of the event source - public static TestIncrementingEventCounter Log = new(); - private IncrementingEventCounter incrementingEventCounter; + // define the singleton instance of the event source + public static TestIncrementingEventCounter Log = new(); + private IncrementingEventCounter incrementingEventCounter; - private TestIncrementingEventCounter() - { - this.incrementingEventCounter = new IncrementingEventCounter(CounterName, this); - } + private TestIncrementingEventCounter() + { + this.incrementingEventCounter = new IncrementingEventCounter(CounterName, this); + } - public void SampleCounter1(float counterValue) - { - this.incrementingEventCounter.Increment(counterValue); - } + public void SampleCounter1(float counterValue) + { + this.incrementingEventCounter.Increment(counterValue); } } diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs index 03f87bb2aa..a60077519e 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs @@ -17,21 +17,20 @@ using System; using System.Diagnostics.Tracing; -namespace OpenTelemetry.Instrumentation.EventCounters.Tests -{ - [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingIncrementingEventCounter")] - public sealed class TestIncrementingPollingCounter : EventSource - { - public const string CounterName = "TestIncrementingPollingCounter"; +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - private IncrementingPollingCounter incrementingPollingCounter; +[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingIncrementingEventCounter")] +public sealed class TestIncrementingPollingCounter : EventSource +{ + public const string CounterName = "TestIncrementingPollingCounter"; - private TestIncrementingPollingCounter(Func provider) - { - this.incrementingPollingCounter = new IncrementingPollingCounter(CounterName, this, provider); - } + private IncrementingPollingCounter incrementingPollingCounter; - // define the singleton instance of the event source - public static TestIncrementingPollingCounter CreateSingleton(Func provider) => new(provider); + private TestIncrementingPollingCounter(Func provider) + { + this.incrementingPollingCounter = new IncrementingPollingCounter(CounterName, this, provider); } + + // define the singleton instance of the event source + public static TestIncrementingPollingCounter CreateSingleton(Func provider) => new(provider); } diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs index 85aefae11f..12c9102e47 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs @@ -17,21 +17,20 @@ using System; using System.Diagnostics.Tracing; -namespace OpenTelemetry.Instrumentation.EventCounters.Tests -{ - [EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingEventCounter")] - public sealed class TestPollingEventCounter : EventSource - { - public const string CounterName = "TestPollingCounter"; +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - private PollingCounter pollingCounter; +[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingEventCounter")] +public sealed class TestPollingEventCounter : EventSource +{ + public const string CounterName = "TestPollingCounter"; - private TestPollingEventCounter(Func provider) - { - this.pollingCounter = new PollingCounter(CounterName, this, provider); - } + private PollingCounter pollingCounter; - // define the singleton instance of the event source - public static TestPollingEventCounter CreateSingleton(Func provider) => new(provider); + private TestPollingEventCounter(Func provider) + { + this.pollingCounter = new PollingCounter(CounterName, this, provider); } + + // define the singleton instance of the event source + public static TestPollingEventCounter CreateSingleton(Func provider) => new(provider); } From 1129085283a0948cc5a4e2a6c65f26b4b72131e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 11 Aug 2022 18:15:35 +0200 Subject: [PATCH 0283/1499] [Instrumenation.EntityFrameworkCore] File scoped namespace (#576) Co-authored-by: Cijo Thomas --- .../EntityFrameworkInstrumentation.cs | 31 +- .../EntityFrameworkInstrumentationOptions.cs | 25 +- .../EntityFrameworkDiagnosticListener.cs | 343 +++++++++--------- ...tityFrameworkInstrumentationEventSource.cs | 91 +++-- .../TracerProviderBuilderExtensions.cs | 39 +- .../EntityFrameworkDiagnosticListenerTests.cs | 215 ++++++----- 6 files changed, 369 insertions(+), 375 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index c82b49f19d..636762ab60 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -17,24 +17,23 @@ using System; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; -namespace OpenTelemetry.Instrumentation.EntityFrameworkCore +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; + +internal class EntityFrameworkInstrumentation : IDisposable { - internal class EntityFrameworkInstrumentation : IDisposable - { - private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions options = null) - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( - name => new EntityFrameworkDiagnosticListener(name, options), - listener => listener.Name == EntityFrameworkDiagnosticListener.DiagnosticSourceName, - null); - this.diagnosticSourceSubscriber.Subscribe(); - } + public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions options = null) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( + name => new EntityFrameworkDiagnosticListener(name, options), + listener => listener.Name == EntityFrameworkDiagnosticListener.DiagnosticSourceName, + null); + this.diagnosticSourceSubscriber.Subscribe(); + } - public void Dispose() - { - this.diagnosticSourceSubscriber?.Dispose(); - } + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 7c8accf017..f135754acd 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -17,21 +17,20 @@ using System.Data; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.EntityFrameworkCore +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; + +/// +/// Options for . +/// +public class EntityFrameworkInstrumentationOptions { /// - /// Options for . + /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default value: True. /// - public class EntityFrameworkInstrumentationOptions - { - /// - /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default value: True. - /// - public bool SetDbStatementForStoredProcedure { get; set; } = true; + public bool SetDbStatementForStoredProcedure { get; set; } = true; - /// - /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. - /// - public bool SetDbStatementForText { get; set; } = false; - } + /// + /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. + /// + public bool SetDbStatementForText { get; set; } = false; } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 24968879b4..300043c491 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -19,225 +19,224 @@ using System.Diagnostics; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; + +internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler { - internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler - { - internal const string DiagnosticSourceName = "Microsoft.EntityFrameworkCore"; + internal const string DiagnosticSourceName = "Microsoft.EntityFrameworkCore"; - internal const string EntityFrameworkCoreCommandCreated = "Microsoft.EntityFrameworkCore.Database.Command.CommandCreated"; - internal const string EntityFrameworkCoreCommandExecuting = "Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting"; - internal const string EntityFrameworkCoreCommandExecuted = "Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted"; - internal const string EntityFrameworkCoreCommandError = "Microsoft.EntityFrameworkCore.Database.Command.CommandError"; + internal const string EntityFrameworkCoreCommandCreated = "Microsoft.EntityFrameworkCore.Database.Command.CommandCreated"; + internal const string EntityFrameworkCoreCommandExecuting = "Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting"; + internal const string EntityFrameworkCoreCommandExecuted = "Microsoft.EntityFrameworkCore.Database.Command.CommandExecuted"; + internal const string EntityFrameworkCoreCommandError = "Microsoft.EntityFrameworkCore.Database.Command.CommandError"; - internal const string AttributePeerService = "peer.service"; - internal const string AttributeDbSystem = "db.system"; - internal const string AttributeDbName = "db.name"; - internal const string AttributeDbStatement = "db.statement"; + internal const string AttributePeerService = "peer.service"; + internal const string AttributeDbSystem = "db.system"; + internal const string AttributeDbName = "db.name"; + internal const string AttributeDbStatement = "db.statement"; - internal static readonly string ActivitySourceName = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Name; - internal static readonly string ActivityName = ActivitySourceName + ".Execute"; + internal static readonly string ActivitySourceName = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Name; + internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - private static readonly Version Version = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Version; + private static readonly Version Version = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Version; #pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before SqlClientActivitySource otherwise null ref exception is thrown. - internal static readonly ActivitySource SqlClientActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource SqlClientActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); #pragma warning restore SA1202 // Elements should be ordered by access - private readonly PropertyFetcher commandFetcher = new PropertyFetcher("Command"); - private readonly PropertyFetcher connectionFetcher = new PropertyFetcher("Connection"); - private readonly PropertyFetcher dbContextFetcher = new PropertyFetcher("Context"); - private readonly PropertyFetcher dbContextDatabaseFetcher = new PropertyFetcher("Database"); - private readonly PropertyFetcher providerNameFetcher = new PropertyFetcher("ProviderName"); - private readonly PropertyFetcher dataSourceFetcher = new PropertyFetcher("DataSource"); - private readonly PropertyFetcher databaseFetcher = new PropertyFetcher("Database"); - private readonly PropertyFetcher commandTypeFetcher = new PropertyFetcher("CommandType"); - private readonly PropertyFetcher commandTextFetcher = new PropertyFetcher("CommandText"); - private readonly PropertyFetcher exceptionFetcher = new PropertyFetcher("Exception"); - - private readonly EntityFrameworkInstrumentationOptions options; - - public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstrumentationOptions options) - : base(sourceName) - { - this.options = options ?? new EntityFrameworkInstrumentationOptions(); - } + private readonly PropertyFetcher commandFetcher = new PropertyFetcher("Command"); + private readonly PropertyFetcher connectionFetcher = new PropertyFetcher("Connection"); + private readonly PropertyFetcher dbContextFetcher = new PropertyFetcher("Context"); + private readonly PropertyFetcher dbContextDatabaseFetcher = new PropertyFetcher("Database"); + private readonly PropertyFetcher providerNameFetcher = new PropertyFetcher("ProviderName"); + private readonly PropertyFetcher dataSourceFetcher = new PropertyFetcher("DataSource"); + private readonly PropertyFetcher databaseFetcher = new PropertyFetcher("Database"); + private readonly PropertyFetcher commandTypeFetcher = new PropertyFetcher("CommandType"); + private readonly PropertyFetcher commandTextFetcher = new PropertyFetcher("CommandText"); + private readonly PropertyFetcher exceptionFetcher = new PropertyFetcher("Exception"); + + private readonly EntityFrameworkInstrumentationOptions options; + + public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstrumentationOptions options) + : base(sourceName) + { + this.options = options ?? new EntityFrameworkInstrumentationOptions(); + } - public override bool SupportsNullActivity => true; + public override bool SupportsNullActivity => true; - public override void OnCustom(string name, Activity activity, object payload) + public override void OnCustom(string name, Activity activity, object payload) + { + switch (name) { - switch (name) - { - case EntityFrameworkCoreCommandCreated: + case EntityFrameworkCoreCommandCreated: + { + activity = SqlClientActivitySource.StartActivity(ActivityName, ActivityKind.Client); + if (activity == null) { - activity = SqlClientActivitySource.StartActivity(ActivityName, ActivityKind.Client); - if (activity == null) - { - // There is no listener or it decided not to sample the current request. - return; - } + // There is no listener or it decided not to sample the current request. + return; + } - var command = this.commandFetcher.Fetch(payload); - if (command == null) - { - EntityFrameworkInstrumentationEventSource.Log.NullPayload(nameof(EntityFrameworkDiagnosticListener), name); - activity.Stop(); - return; - } + var command = this.commandFetcher.Fetch(payload); + if (command == null) + { + EntityFrameworkInstrumentationEventSource.Log.NullPayload(nameof(EntityFrameworkDiagnosticListener), name); + activity.Stop(); + return; + } - var connection = this.connectionFetcher.Fetch(command); - var database = (string)this.databaseFetcher.Fetch(connection); + var connection = this.connectionFetcher.Fetch(command); + var database = (string)this.databaseFetcher.Fetch(connection); - activity.DisplayName = database; + activity.DisplayName = database; - if (activity.IsAllDataRequested) - { - var dbContext = this.dbContextFetcher.Fetch(payload); - var dbContextDatabase = this.dbContextDatabaseFetcher.Fetch(dbContext); - var providerName = this.providerNameFetcher.Fetch(dbContextDatabase); + if (activity.IsAllDataRequested) + { + var dbContext = this.dbContextFetcher.Fetch(payload); + var dbContextDatabase = this.dbContextDatabaseFetcher.Fetch(dbContext); + var providerName = this.providerNameFetcher.Fetch(dbContextDatabase); - switch (providerName) - { - case "Microsoft.EntityFrameworkCore.SqlServer": - activity.AddTag(AttributeDbSystem, "mssql"); - break; - case "Microsoft.EntityFrameworkCore.Cosmos": - activity.AddTag(AttributeDbSystem, "cosmosdb"); - break; - case "Microsoft.EntityFrameworkCore.Sqlite": - activity.AddTag(AttributeDbSystem, "sqlite"); - break; - case "MySql.Data.EntityFrameworkCore": - case "Pomelo.EntityFrameworkCore.MySql": - activity.AddTag(AttributeDbSystem, "mysql"); - break; - case "Npgsql.EntityFrameworkCore.PostgreSQL": - activity.AddTag(AttributeDbSystem, "postgresql"); - break; - case "Oracle.EntityFrameworkCore": - activity.AddTag(AttributeDbSystem, "oracle"); - break; - default: - activity.AddTag(AttributeDbSystem, "other_sql"); - activity.AddTag("ef.provider", providerName); - break; - } + switch (providerName) + { + case "Microsoft.EntityFrameworkCore.SqlServer": + activity.AddTag(AttributeDbSystem, "mssql"); + break; + case "Microsoft.EntityFrameworkCore.Cosmos": + activity.AddTag(AttributeDbSystem, "cosmosdb"); + break; + case "Microsoft.EntityFrameworkCore.Sqlite": + activity.AddTag(AttributeDbSystem, "sqlite"); + break; + case "MySql.Data.EntityFrameworkCore": + case "Pomelo.EntityFrameworkCore.MySql": + activity.AddTag(AttributeDbSystem, "mysql"); + break; + case "Npgsql.EntityFrameworkCore.PostgreSQL": + activity.AddTag(AttributeDbSystem, "postgresql"); + break; + case "Oracle.EntityFrameworkCore": + activity.AddTag(AttributeDbSystem, "oracle"); + break; + default: + activity.AddTag(AttributeDbSystem, "other_sql"); + activity.AddTag("ef.provider", providerName); + break; + } - var dataSource = (string)this.dataSourceFetcher.Fetch(connection); + var dataSource = (string)this.dataSourceFetcher.Fetch(connection); - activity.AddTag(AttributeDbName, database); - if (!string.IsNullOrEmpty(dataSource)) - { - activity.AddTag(AttributePeerService, dataSource); - } + activity.AddTag(AttributeDbName, database); + if (!string.IsNullOrEmpty(dataSource)) + { + activity.AddTag(AttributePeerService, dataSource); } } + } - break; + break; - case EntityFrameworkCoreCommandExecuting: + case EntityFrameworkCoreCommandExecuting: + { + if (activity == null) { - if (activity == null) - { - EntityFrameworkInstrumentationEventSource.Log.NullActivity(name); - return; - } + EntityFrameworkInstrumentationEventSource.Log.NullActivity(name); + return; + } - if (activity.Source != SqlClientActivitySource) - { - return; - } + if (activity.Source != SqlClientActivitySource) + { + return; + } - if (activity.IsAllDataRequested) - { - var command = this.commandFetcher.Fetch(payload); + if (activity.IsAllDataRequested) + { + var command = this.commandFetcher.Fetch(payload); - if (this.commandTypeFetcher.Fetch(command) is CommandType commandType) + if (this.commandTypeFetcher.Fetch(command) is CommandType commandType) + { + var commandText = this.commandTextFetcher.Fetch(command); + switch (commandType) { - var commandText = this.commandTextFetcher.Fetch(command); - switch (commandType) - { - case CommandType.StoredProcedure: - activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.StoredProcedure)); - if (this.options.SetDbStatementForStoredProcedure) - { - activity.AddTag(AttributeDbStatement, commandText); - } - - break; - - case CommandType.Text: - activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.Text)); - if (this.options.SetDbStatementForText) - { - activity.AddTag(AttributeDbStatement, commandText); - } - - break; - - case CommandType.TableDirect: - activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.TableDirect)); - break; - } + case CommandType.StoredProcedure: + activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.StoredProcedure)); + if (this.options.SetDbStatementForStoredProcedure) + { + activity.AddTag(AttributeDbStatement, commandText); + } + + break; + + case CommandType.Text: + activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.Text)); + if (this.options.SetDbStatementForText) + { + activity.AddTag(AttributeDbStatement, commandText); + } + + break; + + case CommandType.TableDirect: + activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.TableDirect)); + break; } } } + } - break; + break; - case EntityFrameworkCoreCommandExecuted: + case EntityFrameworkCoreCommandExecuted: + { + if (activity == null) { - if (activity == null) - { - EntityFrameworkInstrumentationEventSource.Log.NullActivity(name); - return; - } - - if (activity.Source != SqlClientActivitySource) - { - return; - } + EntityFrameworkInstrumentationEventSource.Log.NullActivity(name); + return; + } - activity.Stop(); + if (activity.Source != SqlClientActivitySource) + { + return; } - break; + activity.Stop(); + } + + break; - case EntityFrameworkCoreCommandError: + case EntityFrameworkCoreCommandError: + { + if (activity == null) { - if (activity == null) - { - EntityFrameworkInstrumentationEventSource.Log.NullActivity(name); - return; - } + EntityFrameworkInstrumentationEventSource.Log.NullActivity(name); + return; + } - if (activity.Source != SqlClientActivitySource) - { - return; - } + if (activity.Source != SqlClientActivitySource) + { + return; + } - try + try + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + if (this.exceptionFetcher.Fetch(payload) is Exception exception) { - if (this.exceptionFetcher.Fetch(payload) is Exception exception) - { - activity.SetStatus(Status.Error.WithDescription(exception.Message)); - } - else - { - EntityFrameworkInstrumentationEventSource.Log.NullPayload(nameof(EntityFrameworkDiagnosticListener), name); - } + activity.SetStatus(Status.Error.WithDescription(exception.Message)); + } + else + { + EntityFrameworkInstrumentationEventSource.Log.NullPayload(nameof(EntityFrameworkDiagnosticListener), name); } } - finally - { - activity.Stop(); - } } + finally + { + activity.Stop(); + } + } - break; - } + break; } } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 310d152676..8bd40bdd08 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -19,63 +19,62 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; + +[EventSource(Name = "OpenTelemetry-Instrumentation-EntityFrameworkCore")] +internal class EntityFrameworkInstrumentationEventSource : EventSource { - [EventSource(Name = "OpenTelemetry-Instrumentation-EntityFrameworkCore")] - internal class EntityFrameworkInstrumentationEventSource : EventSource - { - public static EntityFrameworkInstrumentationEventSource Log = new EntityFrameworkInstrumentationEventSource(); + public static EntityFrameworkInstrumentationEventSource Log = new EntityFrameworkInstrumentationEventSource(); - [NonEvent] - public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.UnknownErrorProcessingEvent(handlerName, eventName, ToInvariantString(ex)); - } + this.UnknownErrorProcessingEvent(handlerName, eventName, ToInvariantString(ex)); } + } - [Event(1, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] - public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) - { - this.WriteEvent(1, handlerName, eventName, ex); - } + [Event(1, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(1, handlerName, eventName, ex); + } - [Event(2, Message = "Current Activity is NULL the '{0}' callback. Span will not be recorded.", Level = EventLevel.Warning)] - public void NullActivity(string eventName) - { - this.WriteEvent(2, eventName); - } + [Event(2, Message = "Current Activity is NULL the '{0}' callback. Span will not be recorded.", Level = EventLevel.Warning)] + public void NullActivity(string eventName) + { + this.WriteEvent(2, eventName); + } - [Event(3, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] - public void NullPayload(string handlerName, string eventName) - { - this.WriteEvent(3, handlerName, eventName); - } + [Event(3, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(3, handlerName, eventName); + } - [Event(4, Message = "Payload is invalid in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] - public void InvalidPayload(string handlerName, string eventName) + [Event(4, Message = "Payload is invalid in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void InvalidPayload(string handlerName, string eventName) + { + this.WriteEvent(4, handlerName, eventName); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try { - this.WriteEvent(4, handlerName, eventName); + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 12d24832a3..d0213ede8a 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -19,33 +19,32 @@ using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables Microsoft.EntityFrameworkCore instrumentation. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// EntityFrameworkCore configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( + this TracerProviderBuilder builder, + Action configureOptions = null) { - /// - /// Enables Microsoft.EntityFrameworkCore instrumentation. - /// - /// being configured. - /// EntityFrameworkCore configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( - this TracerProviderBuilder builder, - Action configureOptions = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var options = new EntityFrameworkInstrumentationOptions(); - configureOptions?.Invoke(options); + var options = new EntityFrameworkInstrumentationOptions(); + configureOptions?.Invoke(options); - builder.AddInstrumentation(() => new EntityFrameworkInstrumentation(options)); + builder.AddInstrumentation(() => new EntityFrameworkInstrumentation(options)); - builder.AddSource(EntityFrameworkDiagnosticListener.ActivitySourceName); + builder.AddSource(EntityFrameworkDiagnosticListener.ActivitySourceName); - return builder; - } + return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index c549d17f3f..61e4fb0c3e 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -27,154 +27,153 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests; + +public class EntityFrameworkDiagnosticListenerTests : IDisposable { - public class EntityFrameworkDiagnosticListenerTests : IDisposable + private readonly DbContextOptions contextOptions; + private readonly DbConnection connection; + + public EntityFrameworkDiagnosticListenerTests() { - private readonly DbContextOptions contextOptions; - private readonly DbConnection connection; + this.contextOptions = new DbContextOptionsBuilder() + .UseSqlite(CreateInMemoryDatabase()) + .Options; - public EntityFrameworkDiagnosticListenerTests() - { - this.contextOptions = new DbContextOptionsBuilder() - .UseSqlite(CreateInMemoryDatabase()) - .Options; + this.connection = RelationalOptionsExtension.Extract(this.contextOptions).Connection; - this.connection = RelationalOptionsExtension.Extract(this.contextOptions).Connection; + this.Seed(); + } - this.Seed(); - } + [Fact] + public void EntityFrameworkContextEventsInstrumentedTest() + { + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation().Build(); - [Fact] - public void EntityFrameworkContextEventsInstrumentedTest() + using (var context = new ItemsContext(this.contextOptions)) { - var activityProcessor = new Mock>(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddEntityFrameworkCoreInstrumentation().Build(); + var items = context.Set().OrderBy(e => e.Name).ToList(); - using (var context = new ItemsContext(this.contextOptions)) - { - var items = context.Set().OrderBy(e => e.Name).ToList(); + Assert.Equal(3, items.Count); + Assert.Equal("ItemOne", items[0].Name); + Assert.Equal("ItemThree", items[1].Name); + Assert.Equal("ItemTwo", items[2].Name); + } - Assert.Equal(3, items.Count); - Assert.Equal("ItemOne", items[0].Name); - Assert.Equal("ItemThree", items[1].Name); - Assert.Equal("ItemTwo", items[2].Name); - } + Assert.Equal(3, activityProcessor.Invocations.Count); - Assert.Equal(3, activityProcessor.Invocations.Count); + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + VerifyActivityData(activity); + } - VerifyActivityData(activity); - } + [Fact] + public void EntityFrameworkContextExceptionEventsInstrumentedTest() + { + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation() + .Build(); - [Fact] - public void EntityFrameworkContextExceptionEventsInstrumentedTest() + using (var context = new ItemsContext(this.contextOptions)) { - var activityProcessor = new Mock>(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddEntityFrameworkCoreInstrumentation() - .Build(); - - using (var context = new ItemsContext(this.contextOptions)) + try + { + context.Database.ExecuteSqlRaw("select * from no_table"); + } + catch { - try - { - context.Database.ExecuteSqlRaw("select * from no_table"); - } - catch - { - } } + } - Assert.Equal(3, activityProcessor.Invocations.Count); + Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - VerifyActivityData(activity, isError: true); - } + VerifyActivityData(activity, isError: true); + } - public void Dispose() => this.connection.Dispose(); + public void Dispose() => this.connection.Dispose(); - private static DbConnection CreateInMemoryDatabase() - { - var connection = new SqliteConnection("Filename=:memory:"); + private static DbConnection CreateInMemoryDatabase() + { + var connection = new SqliteConnection("Filename=:memory:"); - connection.Open(); + connection.Open(); - return connection; - } + return connection; + } - private static void VerifyActivityData(Activity activity, bool isError = false) - { - Assert.Equal("main", activity.DisplayName); - Assert.Equal(ActivityKind.Client, activity.Kind); - Assert.Equal("sqlite", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbSystem).Value); + private static void VerifyActivityData(Activity activity, bool isError = false) + { + Assert.Equal("main", activity.DisplayName); + Assert.Equal(ActivityKind.Client, activity.Kind); + Assert.Equal("sqlite", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbSystem).Value); - // TBD: SqlLite not setting the DataSource so it doesn't get set. - Assert.DoesNotContain(activity.Tags, t => t.Key == EntityFrameworkDiagnosticListener.AttributePeerService); + // TBD: SqlLite not setting the DataSource so it doesn't get set. + Assert.DoesNotContain(activity.Tags, t => t.Key == EntityFrameworkDiagnosticListener.AttributePeerService); - Assert.Equal("main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); - Assert.Equal(CommandType.Text.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SpanAttributeConstants.DatabaseStatementTypeKey).Value); + Assert.Equal("main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); + Assert.Equal(CommandType.Text.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SpanAttributeConstants.DatabaseStatementTypeKey).Value); - if (!isError) - { - Assert.Equal(Status.Unset, activity.GetStatus()); - } - else - { - Status status = activity.GetStatus(); - Assert.Equal(StatusCode.Error, status.StatusCode); - Assert.Equal("SQLite Error 1: 'no such table: no_table'.", status.Description); - Assert.Contains(activity.Tags, t => t.Key == SpanAttributeConstants.StatusDescriptionKey); - } + if (!isError) + { + Assert.Equal(Status.Unset, activity.GetStatus()); } - - private void Seed() + else { - using var context = new ItemsContext(this.contextOptions); + Status status = activity.GetStatus(); + Assert.Equal(StatusCode.Error, status.StatusCode); + Assert.Equal("SQLite Error 1: 'no such table: no_table'.", status.Description); + Assert.Contains(activity.Tags, t => t.Key == SpanAttributeConstants.StatusDescriptionKey); + } + } - context.Database.EnsureDeleted(); - context.Database.EnsureCreated(); + private void Seed() + { + using var context = new ItemsContext(this.contextOptions); - var one = new Item { Name = "ItemOne" }; + context.Database.EnsureDeleted(); + context.Database.EnsureCreated(); - var two = new Item { Name = "ItemTwo" }; + var one = new Item { Name = "ItemOne" }; - var three = new Item { Name = "ItemThree" }; + var two = new Item { Name = "ItemTwo" }; - context.AddRange(one, two, three); + var three = new Item { Name = "ItemThree" }; - context.SaveChanges(); - } + context.AddRange(one, two, three); - private class Item - { - public int Id { get; set; } + context.SaveChanges(); + } - public string Name { get; set; } - } + private class Item + { + public int Id { get; set; } + + public string Name { get; set; } + } - private class ItemsContext : DbContext + private class ItemsContext : DbContext + { + public ItemsContext(DbContextOptions options) + : base(options) { - public ItemsContext(DbContextOptions options) - : base(options) - { - } + } - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity( - b => - { - b.Property("Id"); - b.HasKey("Id"); - b.Property(e => e.Name); - }); - } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity( + b => + { + b.Property("Id"); + b.HasKey("Id"); + b.Property(e => e.Name); + }); } } } From 5bf1421dc4fe16209ea2e8f42d859ff868bcbbeb Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 11 Aug 2022 11:37:01 -0700 Subject: [PATCH 0284/1499] Throw when there is Invalid path / insufficient permissions to create subdirectory. (#578) --- .../CHANGELOG.md | 6 +++++ .../PersistentStorageHelper.cs | 22 ++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md index 73f825e00b..081f76a006 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog - OpenTelemetry.Extensions.PersistentStorage +## Unreleased + +* Invalid path or permissions issues will now result in `FileBlobProvider` + initialization failure by throwing exception. + ([#578](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/578)) + ## 1.0.0-alpha.4 * Update implementation to use diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs index 9c29be48ed..470a7d31ad 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -161,25 +161,17 @@ internal static string GetUniqueFileName(string extension) internal static string CreateSubdirectory(string path) { string subdirectoryPath = string.Empty; - - try - { - string baseDirectory = string.Empty; + string baseDirectory = string.Empty; #if !NETSTANDARD - baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + baseDirectory = AppDomain.CurrentDomain.BaseDirectory; #else - baseDirectory = AppContext.BaseDirectory; + baseDirectory = AppContext.BaseDirectory; #endif - string appIdentity = Environment.UserName + "@" + Path.Combine(baseDirectory, Process.GetCurrentProcess().ProcessName); - string subdirectoryName = GetSHA256Hash(appIdentity); - subdirectoryPath = Path.Combine(path, subdirectoryName); - Directory.CreateDirectory(subdirectoryPath); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), $"Error creating sub-directory {path}", ex); - } + string appIdentity = Environment.UserName + "@" + Path.Combine(baseDirectory, Process.GetCurrentProcess().ProcessName); + string subdirectoryName = GetSHA256Hash(appIdentity); + subdirectoryPath = Path.Combine(path, subdirectoryName); + Directory.CreateDirectory(subdirectoryPath); directorySize = CalculateFolderSize(subdirectoryPath); return subdirectoryPath; From 92b0eac89f9f8652a8d647c27a91a3b2f65ffd8e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 11 Aug 2022 14:38:13 -0700 Subject: [PATCH 0285/1499] Fix CHANGELOG (#571) Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index b3ffec18f8..2a694f0725 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog - OpenTelemetry.Contrib.Extensions.AWSXRay -## 1.3.0 [TBD] +## Unreleased * Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random instance instead of recreating with ThreadLocal From 097e25a4c748262867351c6c825d07588153683d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 11 Aug 2022 14:52:25 -0700 Subject: [PATCH 0286/1499] [Exporter.Geneva] Clean-up GenevaTraceExporter Benchmarks (#579) --- .../Exporter/LogExporterBenchmarks.cs | 1 - .../Exporter/TraceExporterBenchmarks.cs | 65 ++++++++----------- .../README.md | 11 ++++ 3 files changed, 39 insertions(+), 38 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index e6787bd568..b8bfae6677 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.Collections.Generic; using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index 9b44c6e4dd..c38d92e3e7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.Collections.Generic; using System.Diagnostics; using BenchmarkDotNet.Attributes; @@ -22,18 +21,16 @@ using OpenTelemetry.Trace; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1415 (21H2) -AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores -.NET SDK=6.0.101 - [Host] : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT - DefaultJob : .NET 5.0.12 (5.0.1221.52207), X64 RyuJIT +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK=7.0.100-preview.6.22352.1 + [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT -| Method | Mean | Error | StdDev | Gen 0 | Allocated | -|-------------------------- |----------:|---------:|---------:|-------:|----------:| -| CreateBoringActivity | 16.05 ns | 0.053 ns | 0.049 ns | - | - | -| CreateTediousActivity | 509.26 ns | 2.105 ns | 1.969 ns | 0.0486 | 408 B | -| CreateInterestingActivity | 959.87 ns | 6.014 ns | 5.625 ns | 0.0477 | 408 B | -| SerializeActivity | 506.55 ns | 3.862 ns | 3.612 ns | 0.0095 | 80 B | +| Method | Mean | Error | StdDev | Gen 0 | Allocated | +|------------------ |---------:|---------:|---------:|-------:|----------:| +| ExportActivity | 687.2 ns | 13.73 ns | 20.55 ns | 0.0648 | 408 B | +| SerializeActivity | 392.3 ns | 4.87 ns | 4.32 ns | 0.0062 | 40 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark @@ -41,12 +38,11 @@ namespace OpenTelemetry.Exporter.Geneva.Benchmark [MemoryDiagnoser] public class TraceExporterBenchmarks { - private readonly Random r = new Random(); private readonly Activity activity; private readonly GenevaTraceExporter exporter; - private readonly ActivitySource sourceBoring = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.Boring"); - private readonly ActivitySource sourceTedious = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.Tedious"); - private readonly ActivitySource sourceInteresting = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.Interesting"); + private readonly ActivitySource sourceTestData = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.TestData"); + private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); + private readonly TracerProvider tracerProvider; public TraceExporterBenchmarks() { @@ -56,11 +52,11 @@ public TraceExporterBenchmarks() { ActivityStarted = null, ActivityStopped = null, - ShouldListenTo = (activitySource) => activitySource.Name == this.sourceTedious.Name, + ShouldListenTo = (activitySource) => activitySource.Name == this.sourceTestData.Name, Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded, }); - using (var tedious = this.sourceTedious.StartActivity("Benchmark")) + using (var tedious = this.sourceTestData.StartActivity("Benchmark")) { this.activity = tedious; this.activity?.SetTag("tagString", "value"); @@ -71,7 +67,6 @@ public TraceExporterBenchmarks() this.exporter = new GenevaTraceExporter(new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", - CustomFields = new List { "azureResourceProvider", "clientRequestId" }, PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", @@ -80,9 +75,9 @@ public TraceExporterBenchmarks() }, }); - Sdk.CreateTracerProviderBuilder() + this.tracerProvider = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) - .AddSource(this.sourceInteresting.Name) + .AddSource(this.activitySource.Name) .AddGenevaTraceExporter(options => { options.ConnectionString = "EtwSession=OpenTelemetry"; @@ -97,24 +92,10 @@ public TraceExporterBenchmarks() } [Benchmark] - public void CreateBoringActivity() - { - // this activity won't be created as there is no listener - using var activity = this.sourceBoring.StartActivity("Benchmark"); - } - - [Benchmark] - public void CreateTediousActivity() - { - // this activity will be created and feed into an ActivityListener that simply drops everything on the floor - using var activity = this.sourceTedious.StartActivity("Benchmark"); - } - - [Benchmark] - public void CreateInterestingActivity() + public void ExportActivity() { // this activity will be created and feed into the actual Geneva exporter - using var activity = this.sourceInteresting.StartActivity("Benchmark"); + using var activity = this.activitySource.StartActivity("Benchmark"); } [Benchmark] @@ -122,5 +103,15 @@ public void SerializeActivity() { this.exporter.SerializeActivity(this.activity); } + + [GlobalCleanup] + public void Cleanup() + { + this.activity.Dispose(); + this.sourceTestData.Dispose(); + this.activitySource.Dispose(); + this.exporter.Dispose(); + this.tracerProvider.Dispose(); + } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md b/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md new file mode 100644 index 0000000000..34fdfc14e3 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md @@ -0,0 +1,11 @@ +# OpenTelemetry GenevaExporter Benchmarks + +Navigate to `./test/OpenTelemetry.Exporter.Geneva.Benchmark` directory and run +the following command: + +```sh +dotnet run -c Release -f net6.0 -- -m +`` + +Then choose the benchmark class that you want to run by entering the required +option number from the list of options shown on the Console window. From d9e91a7525cab01467d2e44661195c9ecb086e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 12 Aug 2022 19:05:42 +0200 Subject: [PATCH 0287/1499] [Instrumenation.AspNet] File scoped namespace (#581) --- .../ActivityHelper.cs | 315 ++++--- .../AspNetTelemetryEventSource.cs | 147 ++-- .../TelemetryHttpModule.cs | 179 ++-- .../TelemetryHttpModuleOptions.cs | 67 +- .../AspNetInstrumentation.cs | 35 +- .../AspNetInstrumentationOptions.cs | 73 +- .../AspNetMetrics.cs | 49 +- .../AspNetInstrumentationEventSource.cs | 69 +- .../Implementation/HttpInListener.cs | 257 +++--- .../Implementation/HttpInMetricsListener.cs | 47 +- .../MeterProviderBuilderExtensions.cs | 31 +- .../TracerProviderBuilderExtensions.cs | 39 +- .../ActivityHelperTest.cs | 791 +++++++++--------- .../HttpContextHelper.cs | 111 ++- .../WebConfigTransformTest.cs | 237 +++--- .../WebConfigWithLocationTagTransformTest.cs | 203 +++-- .../BasicTests.cs | 15 +- .../EventSourceTest.cs | 13 +- .../HttpInListenerTests.cs | 555 ++++++------ .../HttpInMetricsListenerTests.cs | 123 ++- 20 files changed, 1668 insertions(+), 1688 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index 4a1e648ad0..5c510f7c44 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -22,203 +22,202 @@ using OpenTelemetry.Context; using OpenTelemetry.Context.Propagation; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Activity helper class. +/// +internal static class ActivityHelper { /// - /// Activity helper class. + /// Key to store the state in HttpContext. /// - internal static class ActivityHelper - { - /// - /// Key to store the state in HttpContext. - /// - internal const string ContextKey = "__AspnetInstrumentationContext__"; - internal static readonly object StartedButNotSampledObj = new(); - - private const string BaggageSlotName = "otel.baggage"; - private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); - private static readonly ActivitySource AspNetSource = new( - TelemetryHttpModule.AspNetSourceName, - typeof(ActivityHelper).Assembly.GetName().Version.ToString()); - - /// - /// Try to get the started for the running . - /// - /// . - /// Started or if 1) start has not been called or 2) start was - /// called but sampling decided not to create an instance. - /// if start has been called. - public static bool HasStarted(HttpContext context, out Activity aspNetActivity) - { - Debug.Assert(context != null, "Context is null."); + internal const string ContextKey = "__AspnetInstrumentationContext__"; + internal static readonly object StartedButNotSampledObj = new(); - object itemValue = context.Items[ContextKey]; - if (itemValue is ContextHolder contextHolder) - { - aspNetActivity = contextHolder.Activity; - return true; - } + private const string BaggageSlotName = "otel.baggage"; + private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); + private static readonly ActivitySource AspNetSource = new( + TelemetryHttpModule.AspNetSourceName, + typeof(ActivityHelper).Assembly.GetName().Version.ToString()); - aspNetActivity = null; - return itemValue == StartedButNotSampledObj; - } + /// + /// Try to get the started for the running . + /// + /// . + /// Started or if 1) start has not been called or 2) start was + /// called but sampling decided not to create an instance. + /// if start has been called. + public static bool HasStarted(HttpContext context, out Activity aspNetActivity) + { + Debug.Assert(context != null, "Context is null."); - /// - /// Creates root (first level) activity that describes incoming request. - /// - /// . - /// . - /// Callback action. - /// New root activity. - public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action onRequestStartedCallback) + object itemValue = context.Items[ContextKey]; + if (itemValue is ContextHolder contextHolder) { - Debug.Assert(context != null, "Context is null."); + aspNetActivity = contextHolder.Activity; + return true; + } - PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); + aspNetActivity = null; + return itemValue == StartedButNotSampledObj; + } - Activity activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext); + /// + /// Creates root (first level) activity that describes incoming request. + /// + /// . + /// . + /// Callback action. + /// New root activity. + public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action onRequestStartedCallback) + { + Debug.Assert(context != null, "Context is null."); - if (activity != null) - { - if (textMapPropagator is not TraceContextPropagator) - { - Baggage.Current = propagationContext.Baggage; - - context.Items[ContextKey] = new ContextHolder { Activity = activity, Baggage = RuntimeContext.GetValue(BaggageSlotName) }; - } - else - { - context.Items[ContextKey] = new ContextHolder { Activity = activity }; - } - - try - { - onRequestStartedCallback?.Invoke(activity, context); - } - catch (Exception callbackEx) - { - AspNetTelemetryEventSource.Log.CallbackException(activity, "OnStarted", callbackEx); - } - - AspNetTelemetryEventSource.Log.ActivityStarted(activity); - } - else - { - context.Items[ContextKey] = StartedButNotSampledObj; - } + PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); - return activity; - } + Activity activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext); - /// - /// Stops the activity and notifies listeners about it. - /// - /// . - /// . - /// . - /// Callback action. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activity aspNetActivity, HttpContext context, Action onRequestStoppedCallback) + if (activity != null) { - Debug.Assert(context != null, "Context is null."); - - if (aspNetActivity == null) + if (textMapPropagator is not TraceContextPropagator) { - Debug.Assert(context.Items[ContextKey] == StartedButNotSampledObj, "Context item is not StartedButNotSampledObj."); + Baggage.Current = propagationContext.Baggage; - // This is the case where a start was called but no activity was - // created due to a sampling decision. - context.Items[ContextKey] = null; - return; + context.Items[ContextKey] = new ContextHolder { Activity = activity, Baggage = RuntimeContext.GetValue(BaggageSlotName) }; + } + else + { + context.Items[ContextKey] = new ContextHolder { Activity = activity }; } - - Debug.Assert(context.Items[ContextKey] is ContextHolder, "Context item is not an ContextHolder instance."); - - var currentActivity = Activity.Current; - - aspNetActivity.Stop(); - context.Items[ContextKey] = null; try { - onRequestStoppedCallback?.Invoke(aspNetActivity, context); + onRequestStartedCallback?.Invoke(activity, context); } catch (Exception callbackEx) { - AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnStopped", callbackEx); + AspNetTelemetryEventSource.Log.CallbackException(activity, "OnStarted", callbackEx); } - AspNetTelemetryEventSource.Log.ActivityStopped(currentActivity); + AspNetTelemetryEventSource.Log.ActivityStarted(activity); + } + else + { + context.Items[ContextKey] = StartedButNotSampledObj; + } - if (textMapPropagator is not TraceContextPropagator) - { - Baggage.Current = default; - } + return activity; + } - if (currentActivity != aspNetActivity) - { - Activity.Current = currentActivity; - } + /// + /// Stops the activity and notifies listeners about it. + /// + /// . + /// . + /// . + /// Callback action. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activity aspNetActivity, HttpContext context, Action onRequestStoppedCallback) + { + Debug.Assert(context != null, "Context is null."); + + if (aspNetActivity == null) + { + Debug.Assert(context.Items[ContextKey] == StartedButNotSampledObj, "Context item is not StartedButNotSampledObj."); + + // This is the case where a start was called but no activity was + // created due to a sampling decision. + context.Items[ContextKey] = null; + return; } - /// - /// Notifies listeners about an unhandled exception thrown on the . - /// - /// . - /// . - /// . - /// Callback action. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteActivityException(Activity aspNetActivity, HttpContext context, Exception exception, Action onExceptionCallback) + Debug.Assert(context.Items[ContextKey] is ContextHolder, "Context item is not an ContextHolder instance."); + + var currentActivity = Activity.Current; + + aspNetActivity.Stop(); + context.Items[ContextKey] = null; + + try + { + onRequestStoppedCallback?.Invoke(aspNetActivity, context); + } + catch (Exception callbackEx) { - Debug.Assert(context != null, "Context is null."); - Debug.Assert(exception != null, "Exception is null."); + AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnStopped", callbackEx); + } - if (aspNetActivity != null) - { - try - { - onExceptionCallback?.Invoke(aspNetActivity, context, exception); - } - catch (Exception callbackEx) - { - AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnException", callbackEx); - } - - AspNetTelemetryEventSource.Log.ActivityException(aspNetActivity, exception); - } + AspNetTelemetryEventSource.Log.ActivityStopped(currentActivity); + + if (textMapPropagator is not TraceContextPropagator) + { + Baggage.Current = default; } - /// - /// It's possible that a request is executed in both native threads and managed threads, - /// in such case Activity.Current will be lost during native thread and managed thread switch. - /// This method is intended to restore the current activity in order to correlate the child - /// activities with the root activity of the request. - /// - /// . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void RestoreContextIfNeeded(HttpContext context) + if (currentActivity != aspNetActivity) { - Debug.Assert(context != null, "Context is null."); + Activity.Current = currentActivity; + } + } - if (context.Items[ContextKey] is ContextHolder contextHolder && Activity.Current != contextHolder.Activity) - { - Activity.Current = contextHolder.Activity; - if (contextHolder.Baggage != null) - { - RuntimeContext.SetValue(BaggageSlotName, contextHolder.Baggage); - } + /// + /// Notifies listeners about an unhandled exception thrown on the . + /// + /// . + /// . + /// . + /// Callback action. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteActivityException(Activity aspNetActivity, HttpContext context, Exception exception, Action onExceptionCallback) + { + Debug.Assert(context != null, "Context is null."); + Debug.Assert(exception != null, "Exception is null."); - AspNetTelemetryEventSource.Log.ActivityRestored(contextHolder.Activity); + if (aspNetActivity != null) + { + try + { + onExceptionCallback?.Invoke(aspNetActivity, context, exception); + } + catch (Exception callbackEx) + { + AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnException", callbackEx); } + + AspNetTelemetryEventSource.Log.ActivityException(aspNetActivity, exception); } + } - internal class ContextHolder + /// + /// It's possible that a request is executed in both native threads and managed threads, + /// in such case Activity.Current will be lost during native thread and managed thread switch. + /// This method is intended to restore the current activity in order to correlate the child + /// activities with the root activity of the request. + /// + /// . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void RestoreContextIfNeeded(HttpContext context) + { + Debug.Assert(context != null, "Context is null."); + + if (context.Items[ContextKey] is ContextHolder contextHolder && Activity.Current != contextHolder.Activity) { - public Activity Activity; - public object Baggage; + Activity.Current = contextHolder.Activity; + if (contextHolder.Baggage != null) + { + RuntimeContext.SetValue(BaggageSlotName, contextHolder.Baggage); + } + + AspNetTelemetryEventSource.Log.ActivityRestored(contextHolder.Activity); } } + + internal class ContextHolder + { + public Activity Activity; + public object Baggage; + } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs index 3fd4e239d0..78f6cdb02c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs @@ -19,104 +19,103 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// ETW EventSource tracing class. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-AspNet-Telemetry", Guid = "1de158cc-f7ce-4293-bd19-2358c93c8186")] +internal sealed class AspNetTelemetryEventSource : EventSource { /// - /// ETW EventSource tracing class. + /// Instance of the PlatformEventSource class. /// - [EventSource(Name = "OpenTelemetry-Instrumentation-AspNet-Telemetry", Guid = "1de158cc-f7ce-4293-bd19-2358c93c8186")] - internal sealed class AspNetTelemetryEventSource : EventSource - { - /// - /// Instance of the PlatformEventSource class. - /// - public static readonly AspNetTelemetryEventSource Log = new(); + public static readonly AspNetTelemetryEventSource Log = new(); - [NonEvent] - public void ActivityStarted(Activity activity) + [NonEvent] + public void ActivityStarted(Activity activity) + { + if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) - { - this.ActivityStarted(activity?.Id); - } + this.ActivityStarted(activity?.Id); } + } - [NonEvent] - public void ActivityStopped(Activity activity) + [NonEvent] + public void ActivityStopped(Activity activity) + { + if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) - { - this.ActivityStopped(activity?.Id); - } + this.ActivityStopped(activity?.Id); } + } - [NonEvent] - public void ActivityRestored(Activity activity) + [NonEvent] + public void ActivityRestored(Activity activity) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) - { - this.ActivityRestored(activity?.Id); - } + this.ActivityRestored(activity?.Id); } + } - [NonEvent] - public void ActivityException(Activity activity, Exception ex) + [NonEvent] + public void ActivityException(Activity activity, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.ActivityException(activity?.Id, ex.ToInvariantString()); - } + this.ActivityException(activity?.Id, ex.ToInvariantString()); } + } - [NonEvent] - public void CallbackException(Activity activity, string eventName, Exception ex) + [NonEvent] + public void CallbackException(Activity activity, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.CallbackException(activity?.Id, eventName, ex.ToInvariantString()); - } + this.CallbackException(activity?.Id, eventName, ex.ToInvariantString()); } + } - [Event(1, Message = "Callback='{0}'", Level = EventLevel.Verbose)] - public void TraceCallback(string callback) - { - this.WriteEvent(1, callback); - } + [Event(1, Message = "Callback='{0}'", Level = EventLevel.Verbose)] + public void TraceCallback(string callback) + { + this.WriteEvent(1, callback); + } - [Event(2, Message = "Activity started, Id='{0}'", Level = EventLevel.Verbose)] - public void ActivityStarted(string id) - { - this.WriteEvent(2, id); - } + [Event(2, Message = "Activity started, Id='{0}'", Level = EventLevel.Verbose)] + public void ActivityStarted(string id) + { + this.WriteEvent(2, id); + } - [Event(3, Message = "Activity stopped, Id='{0}'", Level = EventLevel.Verbose)] - public void ActivityStopped(string id) - { - this.WriteEvent(3, id); - } + [Event(3, Message = "Activity stopped, Id='{0}'", Level = EventLevel.Verbose)] + public void ActivityStopped(string id) + { + this.WriteEvent(3, id); + } - [Event(4, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)] - public void ActivityRestored(string id) - { - this.WriteEvent(4, id); - } + [Event(4, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)] + public void ActivityRestored(string id) + { + this.WriteEvent(4, id); + } - [Event(5, Message = "Failed to invoke OnExecuteRequestStep, Error='{0}'", Level = EventLevel.Error)] - public void OnExecuteRequestStepInvocationError(string error) - { - this.WriteEvent(5, error); - } + [Event(5, Message = "Failed to invoke OnExecuteRequestStep, Error='{0}'", Level = EventLevel.Error)] + public void OnExecuteRequestStepInvocationError(string error) + { + this.WriteEvent(5, error); + } - [Event(6, Message = "Activity exception, Id='{0}': {1}", Level = EventLevel.Error)] - public void ActivityException(string id, string ex) - { - this.WriteEvent(6, id, ex); - } + [Event(6, Message = "Activity exception, Id='{0}': {1}", Level = EventLevel.Error)] + public void ActivityException(string id, string ex) + { + this.WriteEvent(6, id, ex); + } - [Event(7, Message = "Callback exception, Id='{0}', Name='{1}': {2}", Level = EventLevel.Error)] - public void CallbackException(string id, string eventName, string ex) - { - this.WriteEvent(7, id, eventName, ex); - } + [Event(7, Message = "Callback exception, Id='{0}', Name='{1}': {2}", Level = EventLevel.Error)] + public void CallbackException(string id, string eventName, string ex) + { + this.WriteEvent(7, id, eventName, ex); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index 395c5aec12..4df4fb4366 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -19,129 +19,128 @@ using System.Reflection; using System.Web; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Http Module sets ambient state using Activity API from DiagnosticsSource package. +/// +public class TelemetryHttpModule : IHttpModule { /// - /// Http Module sets ambient state using Activity API from DiagnosticsSource package. + /// OpenTelemetry.Instrumentation.AspNet name. /// - public class TelemetryHttpModule : IHttpModule - { - /// - /// OpenTelemetry.Instrumentation.AspNet name. - /// - public const string AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry"; + public const string AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry"; - /// - /// for OpenTelemetry.Instrumentation.AspNet created objects. - /// - public const string AspNetActivityName = "Microsoft.AspNet.HttpReqIn"; + /// + /// for OpenTelemetry.Instrumentation.AspNet created objects. + /// + public const string AspNetActivityName = "Microsoft.AspNet.HttpReqIn"; - // ServerVariable set only on rewritten HttpContext by URL Rewrite module. - private const string URLRewriteRewrittenRequest = "IIS_WasUrlRewritten"; + // ServerVariable set only on rewritten HttpContext by URL Rewrite module. + private const string URLRewriteRewrittenRequest = "IIS_WasUrlRewritten"; - // ServerVariable set on every request if URL module is registered in HttpModule pipeline. - private const string URLRewriteModuleVersion = "IIS_UrlRewriteModule"; + // ServerVariable set on every request if URL module is registered in HttpModule pipeline. + private const string URLRewriteModuleVersion = "IIS_UrlRewriteModule"; - private static readonly MethodInfo OnExecuteRequestStepMethodInfo = typeof(HttpApplication).GetMethod("OnExecuteRequestStep"); + private static readonly MethodInfo OnExecuteRequestStepMethodInfo = typeof(HttpApplication).GetMethod("OnExecuteRequestStep"); - /// - /// Gets the applied to requests processed by the handler. - /// - public static TelemetryHttpModuleOptions Options { get; } = new TelemetryHttpModuleOptions(); + /// + /// Gets the applied to requests processed by the handler. + /// + public static TelemetryHttpModuleOptions Options { get; } = new TelemetryHttpModuleOptions(); - /// - public void Dispose() - { - } + /// + public void Dispose() + { + } - /// - public void Init(HttpApplication context) - { - context.BeginRequest += this.Application_BeginRequest; - context.EndRequest += this.Application_EndRequest; - context.Error += this.Application_Error; + /// + public void Init(HttpApplication context) + { + context.BeginRequest += this.Application_BeginRequest; + context.EndRequest += this.Application_EndRequest; + context.Error += this.Application_Error; - if (HttpRuntime.UsingIntegratedPipeline && OnExecuteRequestStepMethodInfo != null) + if (HttpRuntime.UsingIntegratedPipeline && OnExecuteRequestStepMethodInfo != null) + { + // OnExecuteRequestStep is availabile starting with 4.7.1 + try + { + OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action)this.OnExecuteRequestStep }); + } + catch (Exception e) { - // OnExecuteRequestStep is availabile starting with 4.7.1 - try - { - OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action)this.OnExecuteRequestStep }); - } - catch (Exception e) - { - AspNetTelemetryEventSource.Log.OnExecuteRequestStepInvocationError(e.Message); - } + AspNetTelemetryEventSource.Log.OnExecuteRequestStepInvocationError(e.Message); } } + } - private void Application_BeginRequest(object sender, EventArgs e) + private void Application_BeginRequest(object sender, EventArgs e) + { + AspNetTelemetryEventSource.Log.TraceCallback("Application_BeginRequest"); + ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, ((HttpApplication)sender).Context, Options.OnRequestStartedCallback); + } + + private void OnExecuteRequestStep(HttpContextBase context, Action step) + { + // Called only on 4.7.1+ runtimes + + if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification) { - AspNetTelemetryEventSource.Log.TraceCallback("Application_BeginRequest"); - ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, ((HttpApplication)sender).Context, Options.OnRequestStartedCallback); + ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context); } - private void OnExecuteRequestStep(HttpContextBase context, Action step) - { - // Called only on 4.7.1+ runtimes + step(); + } - if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification) - { - ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context); - } + private void Application_EndRequest(object sender, EventArgs e) + { + AspNetTelemetryEventSource.Log.TraceCallback("Application_EndRequest"); + bool trackActivity = true; - step(); - } + var context = ((HttpApplication)sender).Context; - private void Application_EndRequest(object sender, EventArgs e) + if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) { - AspNetTelemetryEventSource.Log.TraceCallback("Application_EndRequest"); - bool trackActivity = true; - - var context = ((HttpApplication)sender).Context; - - if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) + // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. + // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. + // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. + // When the child request completes, the parent request executes the end request notifications and completes itself. + // Do not create activity for parent request. Parent request has IIS_UrlRewriteModule ServerVariable with success response code. + // Child request contains an additional ServerVariable named - IIS_WasUrlRewritten. + // Track failed response activity: Different modules in the pipeline has ability to end the response. For example, authentication module could set HTTP 401 in OnBeginRequest and end the response. + if (context.Request.ServerVariables != null && context.Request.ServerVariables[URLRewriteRewrittenRequest] == null && context.Request.ServerVariables[URLRewriteModuleVersion] != null && context.Response.StatusCode == 200) { - // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. - // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. - // The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete. - // When the child request completes, the parent request executes the end request notifications and completes itself. - // Do not create activity for parent request. Parent request has IIS_UrlRewriteModule ServerVariable with success response code. - // Child request contains an additional ServerVariable named - IIS_WasUrlRewritten. - // Track failed response activity: Different modules in the pipeline has ability to end the response. For example, authentication module could set HTTP 401 in OnBeginRequest and end the response. - if (context.Request.ServerVariables != null && context.Request.ServerVariables[URLRewriteRewrittenRequest] == null && context.Request.ServerVariables[URLRewriteModuleVersion] != null && context.Response.StatusCode == 200) - { - trackActivity = false; - } - else - { - // Activity has never been started - aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); - } + trackActivity = false; } - - if (trackActivity) + else { - ActivityHelper.StopAspNetActivity(Options.TextMapPropagator, aspNetActivity, context, Options.OnRequestStoppedCallback); + // Activity has never been started + aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); } } - private void Application_Error(object sender, EventArgs e) + if (trackActivity) { - AspNetTelemetryEventSource.Log.TraceCallback("Application_Error"); + ActivityHelper.StopAspNetActivity(Options.TextMapPropagator, aspNetActivity, context, Options.OnRequestStoppedCallback); + } + } - var context = ((HttpApplication)sender).Context; + private void Application_Error(object sender, EventArgs e) + { + AspNetTelemetryEventSource.Log.TraceCallback("Application_Error"); - var exception = context.Error; - if (exception != null) - { - if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) - { - aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); - } + var context = ((HttpApplication)sender).Context; - ActivityHelper.WriteActivityException(aspNetActivity, context, exception, Options.OnExceptionCallback); + var exception = context.Error; + if (exception != null) + { + if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) + { + aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); } + + ActivityHelper.WriteActivityException(aspNetActivity, context, exception, Options.OnExceptionCallback); } } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs index 2d0e42efb0..00be9abcae 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs @@ -20,48 +20,47 @@ using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Stores options for the . +/// +public class TelemetryHttpModuleOptions { + private TextMapPropagator textMapPropagator = new TraceContextPropagator(); + + internal TelemetryHttpModuleOptions() + { + } + /// - /// Stores options for the . + /// Gets or sets the to use to + /// extract from incoming requests. /// - public class TelemetryHttpModuleOptions + public TextMapPropagator TextMapPropagator { - private TextMapPropagator textMapPropagator = new TraceContextPropagator(); - - internal TelemetryHttpModuleOptions() - { - } - - /// - /// Gets or sets the to use to - /// extract from incoming requests. - /// - public TextMapPropagator TextMapPropagator + get => this.textMapPropagator; + set { - get => this.textMapPropagator; - set - { - Guard.ThrowIfNull(value); + Guard.ThrowIfNull(value); - this.textMapPropagator = value; - } + this.textMapPropagator = value; } + } - /// - /// Gets or sets a callback action to be fired when a request is started. - /// - public Action OnRequestStartedCallback { get; set; } + /// + /// Gets or sets a callback action to be fired when a request is started. + /// + public Action OnRequestStartedCallback { get; set; } - /// - /// Gets or sets a callback action to be fired when a request is stopped. - /// - public Action OnRequestStoppedCallback { get; set; } + /// + /// Gets or sets a callback action to be fired when a request is stopped. + /// + public Action OnRequestStoppedCallback { get; set; } - /// - /// Gets or sets a callback action to be fired when an unhandled - /// exception is thrown processing a request. - /// - public Action OnExceptionCallback { get; set; } - } + /// + /// Gets or sets a callback action to be fired when an unhandled + /// exception is thrown processing a request. + /// + public Action OnExceptionCallback { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs index 2bd2a988be..fd274fb947 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs @@ -17,28 +17,27 @@ using System; using OpenTelemetry.Instrumentation.AspNet.Implementation; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Asp.Net Requests instrumentation. +/// +internal sealed class AspNetInstrumentation : IDisposable { + private readonly HttpInListener httpInListener; + /// - /// Asp.Net Requests instrumentation. + /// Initializes a new instance of the class. /// - internal sealed class AspNetInstrumentation : IDisposable + /// Configuration options for ASP.NET instrumentation. + public AspNetInstrumentation(AspNetInstrumentationOptions options) { - private readonly HttpInListener httpInListener; - - /// - /// Initializes a new instance of the class. - /// - /// Configuration options for ASP.NET instrumentation. - public AspNetInstrumentation(AspNetInstrumentationOptions options) - { - this.httpInListener = new HttpInListener(options); - } + this.httpInListener = new HttpInListener(options); + } - /// - public void Dispose() - { - this.httpInListener?.Dispose(); - } + /// + public void Dispose() + { + this.httpInListener?.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs index 4209ce23e0..50ded07c2c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs @@ -18,46 +18,45 @@ using System.Diagnostics; using System.Web; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Options for ASP.NET instrumentation. +/// +public class AspNetInstrumentationOptions { /// - /// Options for ASP.NET instrumentation. + /// Gets or sets a filter callback function that determines on a per + /// request basis whether or not to collect telemetry. /// - public class AspNetInstrumentationOptions - { - /// - /// Gets or sets a filter callback function that determines on a per - /// request basis whether or not to collect telemetry. - /// - /// - /// The filter callback receives the for the - /// current request and should return a boolean. - /// - /// If filter returns the request is - /// collected. - /// If filter returns or throws an - /// exception the request is filtered out (NOT collected). - /// - /// - public Func Filter { get; set; } + /// + /// The filter callback receives the for the + /// current request and should return a boolean. + /// + /// If filter returns the request is + /// collected. + /// If filter returns or throws an + /// exception the request is filtered out (NOT collected). + /// + /// + public Func Filter { get; set; } - /// - /// Gets or sets an action to enrich an Activity. - /// - /// - /// : the activity being enriched. - /// string: the name of the event. - /// object: the raw object from which additional information can be extracted to enrich the activity. - /// The type of this object depends on the event, which is given by the above parameter. - /// - public Action Enrich { get; set; } + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// string: the name of the event. + /// object: the raw object from which additional information can be extracted to enrich the activity. + /// The type of this object depends on the event, which is given by the above parameter. + /// + public Action Enrich { get; set; } - /// - /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. - /// - /// - /// See: . - /// - public bool RecordException { get; set; } - } + /// + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. + /// + /// + /// See: . + /// + public bool RecordException { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs index 373fe8a553..53fa1720da 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -19,35 +19,34 @@ using System.Reflection; using OpenTelemetry.Instrumentation.AspNet.Implementation; -namespace OpenTelemetry.Instrumentation.AspNet +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Asp.Net Requests instrumentation. +/// +internal class AspNetMetrics : IDisposable { - /// - /// Asp.Net Requests instrumentation. - /// - internal class AspNetMetrics : IDisposable - { - internal static readonly AssemblyName AssemblyName = typeof(HttpInMetricsListener).Assembly.GetName(); - internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + internal static readonly AssemblyName AssemblyName = typeof(HttpInMetricsListener).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name; + internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); - private readonly Meter meter; + private readonly Meter meter; - private readonly HttpInMetricsListener httpInMetricsListener; + private readonly HttpInMetricsListener httpInMetricsListener; - /// - /// Initializes a new instance of the class. - /// - public AspNetMetrics() - { - this.meter = new Meter(InstrumentationName, InstrumentationVersion); - this.httpInMetricsListener = new HttpInMetricsListener(this.meter); - } + /// + /// Initializes a new instance of the class. + /// + public AspNetMetrics() + { + this.meter = new Meter(InstrumentationName, InstrumentationVersion); + this.httpInMetricsListener = new HttpInMetricsListener(this.meter); + } - /// - public void Dispose() - { - this.meter?.Dispose(); - this.httpInMetricsListener?.Dispose(); - } + /// + public void Dispose() + { + this.meter?.Dispose(); + this.httpInMetricsListener?.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs index 58bd374d2a..9d3d6ab35c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs @@ -18,50 +18,49 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.AspNet.Implementation +namespace OpenTelemetry.Instrumentation.AspNet.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-AspNet")] +internal sealed class AspNetInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-AspNet")] - internal sealed class AspNetInstrumentationEventSource : EventSource - { - public static AspNetInstrumentationEventSource Log = new(); + public static AspNetInstrumentationEventSource Log = new(); - [NonEvent] - public void RequestFilterException(string operationName, Exception ex) + [NonEvent] + public void RequestFilterException(string operationName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.RequestFilterException(operationName, ex.ToInvariantString()); - } + this.RequestFilterException(operationName, ex.ToInvariantString()); } + } - [NonEvent] - public void EnrichmentException(string eventName, Exception ex) + [NonEvent] + public void EnrichmentException(string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.EnrichmentException(eventName, ex.ToInvariantString()); - } + this.EnrichmentException(eventName, ex.ToInvariantString()); } + } - [Event(1, Message = "Request is filtered out and will not be collected. Operation='{0}'", Level = EventLevel.Verbose)] - public void RequestIsFilteredOut(string operationName) - { - this.WriteEvent(1, operationName); - } + [Event(1, Message = "Request is filtered out and will not be collected. Operation='{0}'", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut(string operationName) + { + this.WriteEvent(1, operationName); + } - [Event(2, Message = "Filter callback threw an exception. Request will not be collected. Operation='{0}': {1}", Level = EventLevel.Error)] - public void RequestFilterException(string operationName, string exception) - { - this.WriteEvent(2, operationName, exception); - } + [Event(2, Message = "Filter callback threw an exception. Request will not be collected. Operation='{0}': {1}", Level = EventLevel.Error)] + public void RequestFilterException(string operationName, string exception) + { + this.WriteEvent(2, operationName, exception); + } - [Event(3, Message = "Enrich callback threw an exception. Event='{0}': {1}", Level = EventLevel.Error)] - public void EnrichmentException(string eventName, string exception) - { - this.WriteEvent(3, eventName, exception); - } + [Event(3, Message = "Enrich callback threw an exception. Event='{0}': {1}", Level = EventLevel.Error)] + public void EnrichmentException(string eventName, string exception) + { + this.WriteEvent(3, eventName, exception); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index 946de293eb..716b9c0136 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -22,175 +22,174 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.AspNet.Implementation +namespace OpenTelemetry.Instrumentation.AspNet.Implementation; + +internal sealed class HttpInListener : IDisposable { - internal sealed class HttpInListener : IDisposable - { - private readonly PropertyFetcher routeFetcher = new("Route"); - private readonly PropertyFetcher routeTemplateFetcher = new("RouteTemplate"); - private readonly AspNetInstrumentationOptions options; + private readonly PropertyFetcher routeFetcher = new("Route"); + private readonly PropertyFetcher routeTemplateFetcher = new("RouteTemplate"); + private readonly AspNetInstrumentationOptions options; - public HttpInListener(AspNetInstrumentationOptions options) - { - Guard.ThrowIfNull(options); + public HttpInListener(AspNetInstrumentationOptions options) + { + Guard.ThrowIfNull(options); - this.options = options; + this.options = options; - TelemetryHttpModule.Options.TextMapPropagator = Propagators.DefaultTextMapPropagator; + TelemetryHttpModule.Options.TextMapPropagator = Propagators.DefaultTextMapPropagator; - TelemetryHttpModule.Options.OnRequestStartedCallback += this.OnStartActivity; - TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; - TelemetryHttpModule.Options.OnExceptionCallback += this.OnException; - } + TelemetryHttpModule.Options.OnRequestStartedCallback += this.OnStartActivity; + TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; + TelemetryHttpModule.Options.OnExceptionCallback += this.OnException; + } - public void Dispose() - { - TelemetryHttpModule.Options.OnRequestStartedCallback -= this.OnStartActivity; - TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; - TelemetryHttpModule.Options.OnExceptionCallback -= this.OnException; - } + public void Dispose() + { + TelemetryHttpModule.Options.OnRequestStartedCallback -= this.OnStartActivity; + TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; + TelemetryHttpModule.Options.OnExceptionCallback -= this.OnException; + } - /// - /// Gets the OpenTelemetry standard uri tag value for a span based on its request . - /// - /// . - /// Span uri value. - private static string GetUriTagValueFromRequestUri(Uri uri) - { - return string.IsNullOrEmpty(uri.UserInfo) ? uri.ToString() : string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); - } + /// + /// Gets the OpenTelemetry standard uri tag value for a span based on its request . + /// + /// . + /// Span uri value. + private static string GetUriTagValueFromRequestUri(Uri uri) + { + return string.IsNullOrEmpty(uri.UserInfo) ? uri.ToString() : string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); + } - private void OnStartActivity(Activity activity, HttpContext context) + private void OnStartActivity(Activity activity, HttpContext context) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + try { - try - { - // todo: Ideally we would also check - // Sdk.SuppressInstrumentation here to prevent tagging a - // span that will not be collected but we can't do that - // without an SDK reference. Need the spec to come around on - // this. - - if (this.options.Filter?.Invoke(context) == false) - { - AspNetInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); - activity.IsAllDataRequested = false; - activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; - return; - } - } - catch (Exception ex) + // todo: Ideally we would also check + // Sdk.SuppressInstrumentation here to prevent tagging a + // span that will not be collected but we can't do that + // without an SDK reference. Need the spec to come around on + // this. + + if (this.options.Filter?.Invoke(context) == false) { - AspNetInstrumentationEventSource.Log.RequestFilterException(activity.OperationName, ex); + AspNetInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); activity.IsAllDataRequested = false; activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; return; } + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.RequestFilterException(activity.OperationName, ex); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } - var request = context.Request; - var requestValues = request.Unvalidated; + var request = context.Request; + var requestValues = request.Unvalidated; - // see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md - var path = requestValues.Path; - activity.DisplayName = path; + // see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md + var path = requestValues.Path; + activity.DisplayName = path; - if (request.Url.Port == 80 || request.Url.Port == 443) - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host + ":" + request.Url.Port); - } + if (request.Url.Port == 80 || request.Url.Port == 443) + { + activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host); + } + else + { + activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host + ":" + request.Url.Port); + } - activity.SetTag(SemanticConventions.AttributeHttpMethod, request.HttpMethod); - activity.SetTag(SemanticConventions.AttributeHttpTarget, path); - activity.SetTag(SemanticConventions.AttributeHttpUserAgent, request.UserAgent); - activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Url)); + activity.SetTag(SemanticConventions.AttributeHttpMethod, request.HttpMethod); + activity.SetTag(SemanticConventions.AttributeHttpTarget, path); + activity.SetTag(SemanticConventions.AttributeHttpUserAgent, request.UserAgent); + activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Url)); - try - { - this.options.Enrich?.Invoke(activity, "OnStartActivity", request); - } - catch (Exception ex) - { - AspNetInstrumentationEventSource.Log.EnrichmentException("OnStartActivity", ex); - } + try + { + this.options.Enrich?.Invoke(activity, "OnStartActivity", request); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException("OnStartActivity", ex); } } + } - private void OnStopActivity(Activity activity, HttpContext context) + private void OnStopActivity(Activity activity, HttpContext context) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) - { - var response = context.Response; - - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + var response = context.Response; - if (activity.GetStatus().StatusCode == StatusCode.Unset) - { - activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(activity.Kind, response.StatusCode)); - } + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); - var routeData = context.Request.RequestContext.RouteData; + if (activity.GetStatus().StatusCode == StatusCode.Unset) + { + activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(activity.Kind, response.StatusCode)); + } - string template = null; - if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) - { - // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. + var routeData = context.Request.RequestContext.RouteData; - if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1) - { - var subRouteData = attributeRouting.GetValue(0); + string template = null; + if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) + { + // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. - _ = this.routeFetcher.TryFetch(subRouteData, out var route); - _ = this.routeTemplateFetcher.TryFetch(route, out template); - } - } - else if (routeData.Route is Route route) + if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1) { - // MVC + WebAPI traditional routing & MVC attribute routing flow here. - template = route.Url; - } + var subRouteData = attributeRouting.GetValue(0); - if (!string.IsNullOrEmpty(template)) - { - // Override the name that was previously set to the path part of URL. - activity.DisplayName = template; - activity.SetTag(SemanticConventions.AttributeHttpRoute, template); + _ = this.routeFetcher.TryFetch(subRouteData, out var route); + _ = this.routeTemplateFetcher.TryFetch(route, out template); } + } + else if (routeData.Route is Route route) + { + // MVC + WebAPI traditional routing & MVC attribute routing flow here. + template = route.Url; + } - try - { - this.options.Enrich?.Invoke(activity, "OnStopActivity", response); - } - catch (Exception ex) - { - AspNetInstrumentationEventSource.Log.EnrichmentException("OnStopActivity", ex); - } + if (!string.IsNullOrEmpty(template)) + { + // Override the name that was previously set to the path part of URL. + activity.DisplayName = template; + activity.SetTag(SemanticConventions.AttributeHttpRoute, template); + } + + try + { + this.options.Enrich?.Invoke(activity, "OnStopActivity", response); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException("OnStopActivity", ex); } } + } - private void OnException(Activity activity, HttpContext context, Exception exception) + private void OnException(Activity activity, HttpContext context, Exception exception) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) + if (this.options.RecordException) { - if (this.options.RecordException) - { - activity.RecordException(exception); - } + activity.RecordException(exception); + } - activity.SetStatus(Status.Error.WithDescription(exception.Message)); + activity.SetStatus(Status.Error.WithDescription(exception.Message)); - try - { - this.options.Enrich?.Invoke(activity, "OnException", exception); - } - catch (Exception ex) - { - AspNetInstrumentationEventSource.Log.EnrichmentException("OnException", ex); - } + try + { + this.options.Enrich?.Invoke(activity, "OnException", exception); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException("OnException", ex); } } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index ece456273c..aa88a78898 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -20,35 +20,34 @@ using System.Web; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.AspNet.Implementation +namespace OpenTelemetry.Instrumentation.AspNet.Implementation; + +internal sealed class HttpInMetricsListener : IDisposable { - internal sealed class HttpInMetricsListener : IDisposable - { - private readonly Histogram httpServerDuration; + private readonly Histogram httpServerDuration; - public HttpInMetricsListener(Meter meter) - { - this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "measures the duration of the inbound HTTP request"); - TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; - } + public HttpInMetricsListener(Meter meter) + { + this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "measures the duration of the inbound HTTP request"); + TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; + } - public void Dispose() - { - TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; - } + public void Dispose() + { + TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; + } - private void OnStopActivity(Activity activity, HttpContext context) + private void OnStopActivity(Activity activity, HttpContext context) + { + // TODO: This is just a minimal set of attributes. See the spec for additional attributes: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server + var tags = new TagList { - // TODO: This is just a minimal set of attributes. See the spec for additional attributes: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server - var tags = new TagList - { - { SemanticConventions.AttributeHttpMethod, context.Request.HttpMethod }, - { SemanticConventions.AttributeHttpScheme, context.Request.Url.Scheme }, - { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode }, - }; + { SemanticConventions.AttributeHttpMethod, context.Request.HttpMethod }, + { SemanticConventions.AttributeHttpScheme, context.Request.Url.Scheme }, + { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode }, + }; - this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags); - } + this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs index e92740546a..ee69839171 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs @@ -17,26 +17,25 @@ using OpenTelemetry.Instrumentation.AspNet; using OpenTelemetry.Internal; -namespace OpenTelemetry.Metrics +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of ASP.NET request instrumentation. +/// +public static class MeterProviderBuilderExtensions { /// - /// Extension methods to simplify registering of ASP.NET request instrumentation. + /// Enables the incoming requests automatic data collection for ASP.NET. /// - public static class MeterProviderBuilderExtensions + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddAspNetInstrumentation( + this MeterProviderBuilder builder) { - /// - /// Enables the incoming requests automatic data collection for ASP.NET. - /// - /// being configured. - /// The instance of to chain the calls. - public static MeterProviderBuilder AddAspNetInstrumentation( - this MeterProviderBuilder builder) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var instrumentation = new AspNetMetrics(); - builder.AddMeter(AspNetMetrics.InstrumentationName); - return builder.AddInstrumentation(() => instrumentation); - } + var instrumentation = new AspNetMetrics(); + builder.AddMeter(AspNetMetrics.InstrumentationName); + return builder.AddInstrumentation(() => instrumentation); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs index b58aeb83b8..e5cbbc5d2f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -18,32 +18,31 @@ using OpenTelemetry.Instrumentation.AspNet; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of ASP.NET request instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of ASP.NET request instrumentation. + /// Enables the incoming requests automatic data collection for ASP.NET. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// ASP.NET Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetInstrumentation( + this TracerProviderBuilder builder, + Action configureAspNetInstrumentationOptions = null) { - /// - /// Enables the incoming requests automatic data collection for ASP.NET. - /// - /// being configured. - /// ASP.NET Request configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddAspNetInstrumentation( - this TracerProviderBuilder builder, - Action configureAspNetInstrumentationOptions = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var aspnetOptions = new AspNetInstrumentationOptions(); - configureAspNetInstrumentationOptions?.Invoke(aspnetOptions); + var aspnetOptions = new AspNetInstrumentationOptions(); + configureAspNetInstrumentationOptions?.Invoke(aspnetOptions); - builder.AddInstrumentation(() => new AspNetInstrumentation(aspnetOptions)); - builder.AddSource(TelemetryHttpModule.AspNetSourceName); + builder.AddInstrumentation(() => new AspNetInstrumentation(aspnetOptions)); + builder.AddSource(TelemetryHttpModule.AspNetSourceName); - return builder; - } + return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index b8242fffa5..130614390c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -25,522 +25,521 @@ using OpenTelemetry.Context.Propagation; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class ActivityHelperTest : IDisposable { - public class ActivityHelperTest : IDisposable + private const string TraceParentHeaderName = "traceparent"; + private const string TraceStateHeaderName = "tracestate"; + private const string BaggageHeaderName = "baggage"; + private const string BaggageInHeader = "TestKey1=123,TestKey2=456,TestKey1=789"; + private const string TestActivityName = "Activity.Test"; + private readonly TextMapPropagator noopTextMapPropagator = new NoopTextMapPropagator(); + private ActivityListener activitySourceListener; + + public void Dispose() { - private const string TraceParentHeaderName = "traceparent"; - private const string TraceStateHeaderName = "tracestate"; - private const string BaggageHeaderName = "baggage"; - private const string BaggageInHeader = "TestKey1=123,TestKey2=456,TestKey1=789"; - private const string TestActivityName = "Activity.Test"; - private readonly TextMapPropagator noopTextMapPropagator = new NoopTextMapPropagator(); - private ActivityListener activitySourceListener; - - public void Dispose() - { - this.activitySourceListener?.Dispose(); - } + this.activitySourceListener?.Dispose(); + } - [Fact] - public void Has_Started_Returns_Correctly() - { - var context = HttpContextHelper.GetFakeHttpContext(); + [Fact] + public void Has_Started_Returns_Correctly() + { + var context = HttpContextHelper.GetFakeHttpContext(); - bool result = ActivityHelper.HasStarted(context, out Activity aspNetActivity); + bool result = ActivityHelper.HasStarted(context, out Activity aspNetActivity); - Assert.False(result); - Assert.Null(aspNetActivity); + Assert.False(result); + Assert.Null(aspNetActivity); - context.Items[ActivityHelper.ContextKey] = ActivityHelper.StartedButNotSampledObj; + context.Items[ActivityHelper.ContextKey] = ActivityHelper.StartedButNotSampledObj; - result = ActivityHelper.HasStarted(context, out aspNetActivity); + result = ActivityHelper.HasStarted(context, out aspNetActivity); - Assert.True(result); - Assert.Null(aspNetActivity); + Assert.True(result); + Assert.Null(aspNetActivity); - Activity activity = new Activity(TestActivityName); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = activity }; + Activity activity = new Activity(TestActivityName); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = activity }; - result = ActivityHelper.HasStarted(context, out aspNetActivity); + result = ActivityHelper.HasStarted(context, out aspNetActivity); - Assert.True(result); - Assert.NotNull(aspNetActivity); - Assert.Equal(activity, aspNetActivity); - } + Assert.True(result); + Assert.NotNull(aspNetActivity); + Assert.Equal(activity, aspNetActivity); + } - [Fact] - public async Task Can_Restore_Activity() + [Fact] + public async Task Can_Restore_Activity() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + rootActivity.AddTag("k1", "v1"); + rootActivity.AddTag("k2", "v2"); + + Task testTask; + using (ExecutionContext.SuppressFlow()) { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - rootActivity.AddTag("k1", "v1"); - rootActivity.AddTag("k2", "v2"); - - Task testTask; - using (ExecutionContext.SuppressFlow()) + testTask = Task.Run(() => { - testTask = Task.Run(() => - { - Task.Yield(); - - Assert.Null(Activity.Current); + Task.Yield(); - ActivityHelper.RestoreContextIfNeeded(context); + Assert.Null(Activity.Current); - Assert.Same(Activity.Current, rootActivity); - }); - } + ActivityHelper.RestoreContextIfNeeded(context); - await testTask.ConfigureAwait(false); + Assert.Same(Activity.Current, rootActivity); + }); } - [Fact(Skip = "Temporarily disable until stable.")] - public async Task Can_Restore_Baggage() - { - this.EnableListener(); + await testTask.ConfigureAwait(false); + } - var requestHeaders = new Dictionary - { - { BaggageHeaderName, BaggageInHeader }, - }; + [Fact(Skip = "Temporarily disable until stable.")] + public async Task Can_Restore_Baggage() + { + this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); + var requestHeaders = new Dictionary + { + { BaggageHeaderName, BaggageInHeader }, + }; - rootActivity.AddTag("k1", "v1"); - rootActivity.AddTag("k2", "v2"); + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); - Task testTask; - using (ExecutionContext.SuppressFlow()) - { - testTask = Task.Run(() => - { - Task.Yield(); + rootActivity.AddTag("k1", "v1"); + rootActivity.AddTag("k2", "v2"); - Assert.Null(Activity.Current); - Assert.Equal(0, Baggage.Current.Count); + Task testTask; + using (ExecutionContext.SuppressFlow()) + { + testTask = Task.Run(() => + { + Task.Yield(); - ActivityHelper.RestoreContextIfNeeded(context); + Assert.Null(Activity.Current); + Assert.Equal(0, Baggage.Current.Count); - Assert.Same(Activity.Current, rootActivity); - Assert.Empty(rootActivity.Baggage); + ActivityHelper.RestoreContextIfNeeded(context); - Assert.Equal(2, Baggage.Current.Count); - Assert.Equal("789", Baggage.Current.GetBaggage("TestKey1")); - Assert.Equal("456", Baggage.Current.GetBaggage("TestKey2")); - }); - } + Assert.Same(Activity.Current, rootActivity); + Assert.Empty(rootActivity.Baggage); - await testTask.ConfigureAwait(false); + Assert.Equal(2, Baggage.Current.Count); + Assert.Equal("789", Baggage.Current.GetBaggage("TestKey1")); + Assert.Equal("456", Baggage.Current.GetBaggage("TestKey2")); + }); } - [Fact] - public void Can_Stop_Lost_Activity() - { - this.EnableListener(a => - { - Assert.NotNull(Activity.Current); - Assert.Equal(Activity.Current, a); - Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); - }); - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - rootActivity.AddTag("k1", "v1"); - rootActivity.AddTag("k2", "v2"); + await testTask.ConfigureAwait(false); + } - Activity.Current = null; + [Fact] + public void Can_Stop_Lost_Activity() + { + this.EnableListener(a => + { + Assert.NotNull(Activity.Current); + Assert.Equal(Activity.Current, a); + Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); + }); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + rootActivity.AddTag("k1", "v1"); + rootActivity.AddTag("k2", "v2"); + + Activity.Current = null; + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.Null(Activity.Current); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - Assert.True(rootActivity.Duration != TimeSpan.Zero); - Assert.Null(Activity.Current); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public void Do_Not_Restore_Activity_When_There_Is_No_Activity_In_Context() + { + this.EnableListener(); + ActivityHelper.RestoreContextIfNeeded(HttpContextHelper.GetFakeHttpContext()); - [Fact] - public void Do_Not_Restore_Activity_When_There_Is_No_Activity_In_Context() - { - this.EnableListener(); - ActivityHelper.RestoreContextIfNeeded(HttpContextHelper.GetFakeHttpContext()); + Assert.Null(Activity.Current); + } - Assert.Null(Activity.Current); - } + [Fact] + public void Do_Not_Restore_Activity_When_It_Is_Not_Lost() + { + this.EnableListener(); + var root = new Activity("root").Start(); - [Fact] - public void Do_Not_Restore_Activity_When_It_Is_Not_Lost() - { - this.EnableListener(); - var root = new Activity("root").Start(); + var context = HttpContextHelper.GetFakeHttpContext(); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = root }; - var context = HttpContextHelper.GetFakeHttpContext(); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = root }; + ActivityHelper.RestoreContextIfNeeded(context); - ActivityHelper.RestoreContextIfNeeded(context); + Assert.Equal(root, Activity.Current); + } - Assert.Equal(root, Activity.Current); - } + [Fact] + public void Can_Stop_Activity_Without_AspNetListener_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + var rootActivity = new Activity(TestActivityName); + rootActivity.Start(); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; + Thread.Sleep(100); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.Null(rootActivity.Parent); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - [Fact] - public void Can_Stop_Activity_Without_AspNetListener_Enabled() - { - var context = HttpContextHelper.GetFakeHttpContext(); - var rootActivity = new Activity(TestActivityName); - rootActivity.Start(); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; - Thread.Sleep(100); - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - - Assert.True(rootActivity.Duration != TimeSpan.Zero); - Assert.Null(rootActivity.Parent); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public void Can_Stop_Activity_With_AspNetListener_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + var rootActivity = new Activity(TestActivityName); + rootActivity.Start(); + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; + Thread.Sleep(100); + this.EnableListener(); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.Null(rootActivity.Parent); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - [Fact] - public void Can_Stop_Activity_With_AspNetListener_Enabled() - { - var context = HttpContextHelper.GetFakeHttpContext(); - var rootActivity = new Activity(TestActivityName); - rootActivity.Start(); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; - Thread.Sleep(100); - this.EnableListener(); - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - - Assert.True(rootActivity.Duration != TimeSpan.Zero); - Assert.Null(rootActivity.Parent); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public void Can_Stop_Root_Activity_With_All_Children() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - [Fact] - public void Can_Stop_Root_Activity_With_All_Children() - { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + var child = new Activity("child").Start(); + new Activity("grandchild").Start(); - var child = new Activity("child").Start(); - new Activity("grandchild").Start(); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.True(rootActivity.Duration != TimeSpan.Zero); + Assert.True(child.Duration == TimeSpan.Zero); + Assert.Null(rootActivity.Parent); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - Assert.True(rootActivity.Duration != TimeSpan.Zero); - Assert.True(child.Duration == TimeSpan.Zero); - Assert.Null(rootActivity.Parent); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public void Can_Stop_Root_While_Child_Is_Current() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + var child = new Activity("child").Start(); - [Fact] - public void Can_Stop_Root_While_Child_Is_Current() - { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - var child = new Activity("child").Start(); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.True(child.Duration == TimeSpan.Zero); + Assert.NotNull(Activity.Current); + Assert.Equal(Activity.Current, child); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - Assert.True(child.Duration == TimeSpan.Zero); - Assert.NotNull(Activity.Current); - Assert.Equal(Activity.Current, child); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public async Task Can_Stop_Root_Activity_If_It_Is_Broken() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + new Activity("child").Start(); - [Fact] - public async Task Can_Stop_Root_Activity_If_It_Is_Broken() + for (int i = 0; i < 2; i++) { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - new Activity("child").Start(); - - for (int i = 0; i < 2; i++) + await Task.Run(() => { - await Task.Run(() => - { - // when we enter this method, Current is 'child' activity - Activity.Current.Stop(); - - // here Current is 'parent', but only in this execution context - }); - } - - // when we return back here, in the 'parent' execution context - // Current is still 'child' activity - changes in child context (inside Task.Run) - // do not affect 'parent' context in which Task.Run is called. - // But 'child' Activity is stopped, thus consequent calls to Stop will - // not update Current - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, root, context, null); - Assert.True(root.Duration != TimeSpan.Zero); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - Assert.Null(Activity.Current); - } + // when we enter this method, Current is 'child' activity + Activity.Current.Stop(); - [Fact] - public void Stop_Root_Activity_With_129_Nesting_Depth() - { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + // here Current is 'parent', but only in this execution context + }); + } - for (int i = 0; i < 129; i++) - { - new Activity("child" + i).Start(); - } + // when we return back here, in the 'parent' execution context + // Current is still 'child' activity - changes in child context (inside Task.Run) + // do not affect 'parent' context in which Task.Run is called. + // But 'child' Activity is stopped, thus consequent calls to Stop will + // not update Current + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, root, context, null); + Assert.True(root.Duration != TimeSpan.Zero); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + Assert.Null(Activity.Current); + } - // can stop any activity regardless of the stack depth - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, root, context, null); + [Fact] + public void Stop_Root_Activity_With_129_Nesting_Depth() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - Assert.True(root.Duration != TimeSpan.Zero); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - Assert.NotNull(Activity.Current); + for (int i = 0; i < 129; i++) + { + new Activity("child" + i).Start(); } - [Fact] - public void Should_Not_Create_RootActivity_If_AspNetListener_Not_Enabled() - { - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + // can stop any activity regardless of the stack depth + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, root, context, null); - Assert.Null(rootActivity); - Assert.Equal(ActivityHelper.StartedButNotSampledObj, context.Items[ActivityHelper.ContextKey]); + Assert.True(root.Duration != TimeSpan.Zero); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + Assert.NotNull(Activity.Current); + } - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public void Should_Not_Create_RootActivity_If_AspNetListener_Not_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - [Fact] - public void Should_Not_Create_RootActivity_If_AspNetActivity_Not_Enabled() - { - var context = HttpContextHelper.GetFakeHttpContext(); - this.EnableListener(onSample: (context) => ActivitySamplingResult.None); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + Assert.Null(rootActivity); + Assert.Equal(ActivityHelper.StartedButNotSampledObj, context.Items[ActivityHelper.ContextKey]); - Assert.Null(rootActivity); - Assert.Equal(ActivityHelper.StartedButNotSampledObj, context.Items[ActivityHelper.ContextKey]); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - Assert.Null(context.Items[ActivityHelper.ContextKey]); - } + [Fact] + public void Should_Not_Create_RootActivity_If_AspNetActivity_Not_Enabled() + { + var context = HttpContextHelper.GetFakeHttpContext(); + this.EnableListener(onSample: (context) => ActivitySamplingResult.None); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + + Assert.Null(rootActivity); + Assert.Equal(ActivityHelper.StartedButNotSampledObj, context.Items[ActivityHelper.ContextKey]); + + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + Assert.Null(context.Items[ActivityHelper.ContextKey]); + } - [Fact] - public void Can_Create_RootActivity_From_W3C_Traceparent() + [Fact] + public void Can_Create_RootActivity_From_W3C_Traceparent() + { + this.EnableListener(); + var requestHeaders = new Dictionary { - this.EnableListener(); - var requestHeaders = new Dictionary - { - { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-00" }, - }; + { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-00" }, + }; - var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new TraceContextPropagator(), context, null); + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new TraceContextPropagator(), context, null); - Assert.NotNull(rootActivity); - Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); - Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00", rootActivity.ParentId); - Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); - Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); - Assert.True(rootActivity.Recorded); // note: We're not using a parent-based sampler in this test so the recorded flag of traceparent is ignored. + Assert.NotNull(rootActivity); + Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); + Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00", rootActivity.ParentId); + Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); + Assert.True(rootActivity.Recorded); // note: We're not using a parent-based sampler in this test so the recorded flag of traceparent is ignored. - Assert.Null(rootActivity.TraceStateString); - Assert.Empty(rootActivity.Baggage); + Assert.Null(rootActivity.TraceStateString); + Assert.Empty(rootActivity.Baggage); - Assert.Equal(0, Baggage.Current.Count); - } + Assert.Equal(0, Baggage.Current.Count); + } - [Fact] - public void Can_Create_RootActivityWithTraceState_From_W3C_TraceContext() + [Fact] + public void Can_Create_RootActivityWithTraceState_From_W3C_TraceContext() + { + this.EnableListener(); + var requestHeaders = new Dictionary { - this.EnableListener(); - var requestHeaders = new Dictionary - { - { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01" }, - { TraceStateHeaderName, "ts1=v1,ts2=v2" }, - }; + { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01" }, + { TraceStateHeaderName, "ts1=v1,ts2=v2" }, + }; - var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new TraceContextPropagator(), context, null); + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new TraceContextPropagator(), context, null); - Assert.NotNull(rootActivity); - Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); - Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01", rootActivity.ParentId); - Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); - Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); - Assert.True(rootActivity.Recorded); + Assert.NotNull(rootActivity); + Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); + Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01", rootActivity.ParentId); + Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); + Assert.True(rootActivity.Recorded); - Assert.Equal("ts1=v1,ts2=v2", rootActivity.TraceStateString); - Assert.Empty(rootActivity.Baggage); + Assert.Equal("ts1=v1,ts2=v2", rootActivity.TraceStateString); + Assert.Empty(rootActivity.Baggage); - Assert.Equal(0, Baggage.Current.Count); - } + Assert.Equal(0, Baggage.Current.Count); + } - [Fact] - public void Can_Create_RootActivity_From_W3C_Traceparent_With_Baggage() + [Fact] + public void Can_Create_RootActivity_From_W3C_Traceparent_With_Baggage() + { + this.EnableListener(); + var requestHeaders = new Dictionary { - this.EnableListener(); - var requestHeaders = new Dictionary - { - { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-00" }, - { BaggageHeaderName, BaggageInHeader }, - }; + { TraceParentHeaderName, "00-0123456789abcdef0123456789abcdef-0123456789abcdef-00" }, + { BaggageHeaderName, BaggageInHeader }, + }; - var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); + var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); - Assert.NotNull(rootActivity); - Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); - Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00", rootActivity.ParentId); - Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); - Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); - Assert.True(rootActivity.Recorded); // note: We're not using a parent-based sampler in this test so the recorded flag of traceparent is ignored. + Assert.NotNull(rootActivity); + Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); + Assert.Equal("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00", rootActivity.ParentId); + Assert.Equal("0123456789abcdef0123456789abcdef", rootActivity.TraceId.ToHexString()); + Assert.Equal("0123456789abcdef", rootActivity.ParentSpanId.ToHexString()); + Assert.True(rootActivity.Recorded); // note: We're not using a parent-based sampler in this test so the recorded flag of traceparent is ignored. - Assert.Null(rootActivity.TraceStateString); - Assert.Empty(rootActivity.Baggage); + Assert.Null(rootActivity.TraceStateString); + Assert.Empty(rootActivity.Baggage); - Assert.Equal(2, Baggage.Current.Count); - Assert.Equal("789", Baggage.Current.GetBaggage("TestKey1")); - Assert.Equal("456", Baggage.Current.GetBaggage("TestKey2")); + Assert.Equal(2, Baggage.Current.Count); + Assert.Equal("789", Baggage.Current.GetBaggage("TestKey1")); + Assert.Equal("456", Baggage.Current.GetBaggage("TestKey2")); - ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); - Assert.Equal(0, Baggage.Current.Count); - } + Assert.Equal(0, Baggage.Current.Count); + } - [Fact] - public void Can_Create_RootActivity_And_Start_Activity() - { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + [Fact] + public void Can_Create_RootActivity_And_Start_Activity() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - Assert.NotNull(rootActivity); - Assert.True(!string.IsNullOrEmpty(rootActivity.Id)); - } + Assert.NotNull(rootActivity); + Assert.True(!string.IsNullOrEmpty(rootActivity.Id)); + } - [Fact] - public void Can_Create_RootActivity_And_Saved_In_HttContext() - { - this.EnableListener(); - var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + [Fact] + public void Can_Create_RootActivity_And_Saved_In_HttContext() + { + this.EnableListener(); + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); - Assert.NotNull(rootActivity); - Assert.Same(rootActivity, ((ActivityHelper.ContextHolder)context.Items[ActivityHelper.ContextKey])?.Activity); - } + Assert.NotNull(rootActivity); + Assert.Same(rootActivity, ((ActivityHelper.ContextHolder)context.Items[ActivityHelper.ContextKey])?.Activity); + } - [Fact] - public void Fire_Exception_Events() - { - int callbacksFired = 0; + [Fact] + public void Fire_Exception_Events() + { + int callbacksFired = 0; - var context = HttpContextHelper.GetFakeHttpContext(); + var context = HttpContextHelper.GetFakeHttpContext(); - Activity activity = new Activity(TestActivityName); + Activity activity = new Activity(TestActivityName); - ActivityHelper.WriteActivityException(activity, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); + ActivityHelper.WriteActivityException(activity, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); - ActivityHelper.WriteActivityException(null, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); + ActivityHelper.WriteActivityException(null, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); - // Callback should fire only for non-null activity - Assert.Equal(1, callbacksFired); - } + // Callback should fire only for non-null activity + Assert.Equal(1, callbacksFired); + } - private void EnableListener(Action onStarted = null, Action onStopped = null, Func onSample = null) - { - Debug.Assert(this.activitySourceListener == null, "Cannot attach multiple listeners in tests."); + private void EnableListener(Action onStarted = null, Action onStopped = null, Func onSample = null) + { + Debug.Assert(this.activitySourceListener == null, "Cannot attach multiple listeners in tests."); - this.activitySourceListener = new ActivityListener + this.activitySourceListener = new ActivityListener + { + ShouldListenTo = (activitySource) => activitySource.Name == TelemetryHttpModule.AspNetSourceName, + ActivityStarted = (a) => onStarted?.Invoke(a), + ActivityStopped = (a) => onStopped?.Invoke(a), + Sample = (ref ActivityCreationOptions options) => { - ShouldListenTo = (activitySource) => activitySource.Name == TelemetryHttpModule.AspNetSourceName, - ActivityStarted = (a) => onStarted?.Invoke(a), - ActivityStopped = (a) => onStopped?.Invoke(a), - Sample = (ref ActivityCreationOptions options) => + if (onSample != null) { - if (onSample != null) - { - return onSample(options.Parent); - } + return onSample(options.Parent); + } - return ActivitySamplingResult.AllDataAndRecorded; - }, - }; + return ActivitySamplingResult.AllDataAndRecorded; + }, + }; - ActivitySource.AddActivityListener(this.activitySourceListener); - } + ActivitySource.AddActivityListener(this.activitySourceListener); + } - private class TestHttpRequest : HttpRequestBase - { - private readonly NameValueCollection headers = new(); + private class TestHttpRequest : HttpRequestBase + { + private readonly NameValueCollection headers = new(); - public override NameValueCollection Headers => this.headers; + public override NameValueCollection Headers => this.headers; - public override UnvalidatedRequestValuesBase Unvalidated => new TestUnvalidatedRequestValues(this.headers); - } + public override UnvalidatedRequestValuesBase Unvalidated => new TestUnvalidatedRequestValues(this.headers); + } - private class TestUnvalidatedRequestValues : UnvalidatedRequestValuesBase + private class TestUnvalidatedRequestValues : UnvalidatedRequestValuesBase + { + public TestUnvalidatedRequestValues(NameValueCollection headers) { - public TestUnvalidatedRequestValues(NameValueCollection headers) - { - this.Headers = headers; - } - - public override NameValueCollection Headers { get; } + this.Headers = headers; } - private class TestHttpResponse : HttpResponseBase + public override NameValueCollection Headers { get; } + } + + private class TestHttpResponse : HttpResponseBase + { + } + + private class TestHttpServerUtility : HttpServerUtilityBase + { + private readonly HttpContextBase context; + + public TestHttpServerUtility(HttpContextBase context) { + this.context = context; } - private class TestHttpServerUtility : HttpServerUtilityBase + public override Exception GetLastError() { - private readonly HttpContextBase context; + return this.context.Error; + } + } - public TestHttpServerUtility(HttpContextBase context) - { - this.context = context; - } + private class TestHttpContext : HttpContextBase + { + private readonly Hashtable items; - public override Exception GetLastError() - { - return this.context.Error; - } + public TestHttpContext(Exception error = null) + { + this.Server = new TestHttpServerUtility(this); + this.items = new Hashtable(); + this.Error = error; } - private class TestHttpContext : HttpContextBase - { - private readonly Hashtable items; + public override HttpRequestBase Request { get; } = new TestHttpRequest(); - public TestHttpContext(Exception error = null) - { - this.Server = new TestHttpServerUtility(this); - this.items = new Hashtable(); - this.Error = error; - } + /// + public override IDictionary Items => this.items; - public override HttpRequestBase Request { get; } = new TestHttpRequest(); + public override Exception Error { get; } - /// - public override IDictionary Items => this.items; + public override HttpServerUtilityBase Server { get; } + } - public override Exception Error { get; } + private class NoopTextMapPropagator : TextMapPropagator + { + private static readonly PropagationContext DefaultPropagationContext = default; - public override HttpServerUtilityBase Server { get; } - } + public override ISet Fields => null; - private class NoopTextMapPropagator : TextMapPropagator + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) { - private static readonly PropagationContext DefaultPropagationContext = default; - - public override ISet Fields => null; - - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) - { - return DefaultPropagationContext; - } + return DefaultPropagationContext; + } - public override void Inject(PropagationContext context, T carrier, Action setter) - { - } + public override void Inject(PropagationContext context, T carrier, Action setter) + { } } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs index e9920ef16b..dd1864609b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -21,83 +21,82 @@ using System.Web; using System.Web.Hosting; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +internal class HttpContextHelper { - internal class HttpContextHelper + public static HttpContext GetFakeHttpContext(string page = "/page", string query = "", IDictionary headers = null) { - public static HttpContext GetFakeHttpContext(string page = "/page", string query = "", IDictionary headers = null) - { - Thread.GetDomain().SetData(".appPath", string.Empty); - Thread.GetDomain().SetData(".appVPath", string.Empty); + Thread.GetDomain().SetData(".appPath", string.Empty); + Thread.GetDomain().SetData(".appVPath", string.Empty); - var workerRequest = new SimpleWorkerRequestWithHeaders(page, query, new StringWriter(CultureInfo.InvariantCulture), headers); - var context = new HttpContext(workerRequest); - HttpContext.Current = context; - return context; - } + var workerRequest = new SimpleWorkerRequestWithHeaders(page, query, new StringWriter(CultureInfo.InvariantCulture), headers); + var context = new HttpContext(workerRequest); + HttpContext.Current = context; + return context; + } + + public static HttpContextBase GetFakeHttpContextBase(string page = "/page", string query = "", IDictionary headers = null) + { + var context = GetFakeHttpContext(page, query, headers); + return new HttpContextWrapper(context); + } - public static HttpContextBase GetFakeHttpContextBase(string page = "/page", string query = "", IDictionary headers = null) + private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest + { + private readonly IDictionary headers; + + public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary headers) + : base(page, query, output) { - var context = GetFakeHttpContext(page, query, headers); - return new HttpContextWrapper(context); + if (headers != null) + { + this.headers = headers; + } + else + { + this.headers = new Dictionary(); + } } - private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest + public override string[][] GetUnknownRequestHeaders() { - private readonly IDictionary headers; + List result = new List(); - public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary headers) - : base(page, query, output) + foreach (var header in this.headers) { - if (headers != null) - { - this.headers = headers; - } - else - { - this.headers = new Dictionary(); - } + result.Add(new string[] { header.Key, header.Value }); } - public override string[][] GetUnknownRequestHeaders() + var baseResult = base.GetUnknownRequestHeaders(); + if (baseResult != null) { - List result = new List(); - - foreach (var header in this.headers) - { - result.Add(new string[] { header.Key, header.Value }); - } - - var baseResult = base.GetUnknownRequestHeaders(); - if (baseResult != null) - { - result.AddRange(baseResult); - } - - return result.ToArray(); + result.AddRange(baseResult); } - public override string GetUnknownRequestHeader(string name) - { - if (this.headers.ContainsKey(name)) - { - return this.headers[name]; - } + return result.ToArray(); + } - return base.GetUnknownRequestHeader(name); + public override string GetUnknownRequestHeader(string name) + { + if (this.headers.ContainsKey(name)) + { + return this.headers[name]; } - public override string GetKnownRequestHeader(int index) - { - var name = GetKnownRequestHeaderName(index); + return base.GetUnknownRequestHeader(name); + } - if (this.headers.ContainsKey(name)) - { - return this.headers[name]; - } + public override string GetKnownRequestHeader(int index) + { + var name = GetKnownRequestHeaderName(index); - return base.GetKnownRequestHeader(index); + if (this.headers.ContainsKey(name)) + { + return this.headers[name]; } + + return base.GetKnownRequestHeader(index); } } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs index c0ddbe96b1..a232bb7bb4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs @@ -19,17 +19,17 @@ using Microsoft.Web.XmlTransform; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class WebConfigTransformTest { - public class WebConfigTransformTest - { - private const string InstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.install.xdt"; - private const string UninstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.uninstall.xdt"; + private const string InstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.install.xdt"; + private const string UninstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.uninstall.xdt"; - [Fact] - public void VerifyInstallationToBasicWebConfig() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToBasicWebConfig() + { + const string OriginalWebConfigContent = @" @@ -39,7 +39,7 @@ public void VerifyInstallationToBasicWebConfig() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -55,14 +55,14 @@ public void VerifyInstallationToBasicWebConfig() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyUpdateWithTypeRenamingWebConfig() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyUpdateWithTypeRenamingWebConfig() + { + const string OriginalWebConfigContent = @" @@ -76,7 +76,7 @@ public void VerifyUpdateWithTypeRenamingWebConfig() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -92,14 +92,14 @@ public void VerifyUpdateWithTypeRenamingWebConfig() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyUpdateNewerVersionWebConfig() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyUpdateNewerVersionWebConfig() + { + const string OriginalWebConfigContent = @" @@ -113,7 +113,7 @@ public void VerifyUpdateNewerVersionWebConfig() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -130,14 +130,14 @@ public void VerifyUpdateNewerVersionWebConfig() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyUpdateWithIntegratedModeWebConfig() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyUpdateWithIntegratedModeWebConfig() + { + const string OriginalWebConfigContent = @" @@ -152,7 +152,7 @@ public void VerifyUpdateWithIntegratedModeWebConfig() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -168,14 +168,14 @@ public void VerifyUpdateWithIntegratedModeWebConfig() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyUninstallationWithBasicWebConfig() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyUninstallationWithBasicWebConfig() + { + const string OriginalWebConfigContent = @" @@ -190,7 +190,7 @@ public void VerifyUninstallationWithBasicWebConfig() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -200,14 +200,14 @@ public void VerifyUninstallationWithBasicWebConfig() "; - var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyUninstallWithIntegratedPrecondition() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyUninstallWithIntegratedPrecondition() + { + const string OriginalWebConfigContent = @" @@ -222,7 +222,7 @@ public void VerifyUninstallWithIntegratedPrecondition() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -232,14 +232,14 @@ public void VerifyUninstallWithIntegratedPrecondition() "; - var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyUninstallationWithUserModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyUninstallationWithUserModules() + { + const string OriginalWebConfigContent = @" @@ -256,7 +256,7 @@ public void VerifyUninstallationWithUserModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -270,14 +270,14 @@ public void VerifyUninstallationWithUserModules() "; - var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyUninstallTransformation(OriginalWebConfigContent, UninstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToWebConfigWithUserModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToWebConfigWithUserModules() + { + const string OriginalWebConfigContent = @" @@ -291,7 +291,7 @@ public void VerifyInstallationToWebConfigWithUserModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -309,16 +309,16 @@ public void VerifyInstallationToWebConfigWithUserModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToEmptyWebConfig() - { - const string OriginalWebConfigContent = @""; + [Fact] + public void VerifyInstallationToEmptyWebConfig() + { + const string OriginalWebConfigContent = @""; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -334,16 +334,16 @@ public void VerifyInstallationToEmptyWebConfig() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToWebConfigWithoutModules() - { - const string OriginalWebConfigContent = @""; + [Fact] + public void VerifyInstallationToWebConfigWithoutModules() + { + const string OriginalWebConfigContent = @""; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -359,51 +359,50 @@ public void VerifyInstallationToWebConfigWithoutModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - private XDocument ApplyInstallTransformation(string originalConfiguration, string resourceName) - { - return this.ApplyTransformation(originalConfiguration, resourceName); - } + private XDocument ApplyInstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } - private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) - { - return this.ApplyTransformation(originalConfiguration, resourceName); - } + private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } + + private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) + { + Assert.True( + XNode.DeepEquals( + transformedWebConfig.FirstNode, + XDocument.Parse(expectedConfigContent).FirstNode)); + } - private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) + private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) + { + XDocument result; + Stream stream = null; + try { - Assert.True( - XNode.DeepEquals( - transformedWebConfig.FirstNode, - XDocument.Parse(expectedConfigContent).FirstNode)); + stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); + var document = new XmlTransformableDocument(); + using var transformation = new XmlTransformation(stream, null); + stream = null; + document.LoadXml(originalConfiguration); + transformation.Apply(document); + result = XDocument.Parse(document.OuterXml); } - - private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) + finally { - XDocument result; - Stream stream = null; - try + if (stream != null) { - stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); - var document = new XmlTransformableDocument(); - using var transformation = new XmlTransformation(stream, null); - stream = null; - document.LoadXml(originalConfiguration); - transformation.Apply(document); - result = XDocument.Parse(document.OuterXml); + stream.Dispose(); } - finally - { - if (stream != null) - { - stream.Dispose(); - } - } - - return result; } + + return result; } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs index e8415130ca..0e84dbb24b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -19,16 +19,16 @@ using Microsoft.Web.XmlTransform; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class WebConfigWithLocationTagTransformTest { - public class WebConfigWithLocationTagTransformTest - { - private const string InstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.install.xdt"; + private const string InstallConfigTransformationResourceName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.Resources.web.config.install.xdt"; - [Fact] - public void VerifyInstallationWhenNonGlobalLocationTagExists() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationWhenNonGlobalLocationTagExists() + { + const string OriginalWebConfigContent = @" @@ -39,7 +39,7 @@ public void VerifyInstallationWhenNonGlobalLocationTagExists() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -62,14 +62,14 @@ public void VerifyInstallationWhenNonGlobalLocationTagExists() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationWhenGlobalAndNonGlobalLocationTagExists() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationWhenGlobalAndNonGlobalLocationTagExists() + { + const string OriginalWebConfigContent = @" @@ -92,7 +92,7 @@ public void VerifyInstallationWhenGlobalAndNonGlobalLocationTagExists() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -121,14 +121,14 @@ public void VerifyInstallationWhenGlobalAndNonGlobalLocationTagExists() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToLocationTagWithDotPathAndExistingModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToLocationTagWithDotPathAndExistingModules() + { + const string OriginalWebConfigContent = @" @@ -146,7 +146,7 @@ public void VerifyInstallationToLocationTagWithDotPathAndExistingModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -168,14 +168,14 @@ public void VerifyInstallationToLocationTagWithDotPathAndExistingModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToLocationTagWithEmptyPathAndExistingModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToLocationTagWithEmptyPathAndExistingModules() + { + const string OriginalWebConfigContent = @" @@ -191,7 +191,7 @@ public void VerifyInstallationToLocationTagWithEmptyPathAndExistingModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -213,14 +213,14 @@ public void VerifyInstallationToLocationTagWithEmptyPathAndExistingModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToLocationTagWithDotPathWithNoModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToLocationTagWithDotPathWithNoModules() + { + const string OriginalWebConfigContent = @" @@ -234,7 +234,7 @@ public void VerifyInstallationToLocationTagWithDotPathWithNoModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -256,14 +256,14 @@ public void VerifyInstallationToLocationTagWithDotPathWithNoModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToLocationTagWithEmptyPathWithNoModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToLocationTagWithEmptyPathWithNoModules() + { + const string OriginalWebConfigContent = @" @@ -273,7 +273,7 @@ public void VerifyInstallationToLocationTagWithEmptyPathWithNoModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -295,14 +295,14 @@ public void VerifyInstallationToLocationTagWithEmptyPathWithNoModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToLocationTagWithDotPathWithGlobalModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToLocationTagWithDotPathWithGlobalModules() + { + const string OriginalWebConfigContent = @" @@ -322,7 +322,7 @@ public void VerifyInstallationToLocationTagWithDotPathWithGlobalModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -346,14 +346,14 @@ public void VerifyInstallationToLocationTagWithDotPathWithGlobalModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - [Fact] - public void VerifyInstallationToLocationTagWithEmptyPathWithGlobalModules() - { - const string OriginalWebConfigContent = @" + [Fact] + public void VerifyInstallationToLocationTagWithEmptyPathWithGlobalModules() + { + const string OriginalWebConfigContent = @" @@ -369,7 +369,7 @@ public void VerifyInstallationToLocationTagWithEmptyPathWithGlobalModules() "; - const string ExpectedWebConfigContent = @" + const string ExpectedWebConfigContent = @" @@ -389,51 +389,50 @@ public void VerifyInstallationToLocationTagWithEmptyPathWithGlobalModules() "; - var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); - this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); - } + var transformedWebConfig = this.ApplyInstallTransformation(OriginalWebConfigContent, InstallConfigTransformationResourceName); + this.VerifyTransformation(ExpectedWebConfigContent, transformedWebConfig); + } - private XDocument ApplyInstallTransformation(string originalConfiguration, string resourceName) - { - return this.ApplyTransformation(originalConfiguration, resourceName); - } + private XDocument ApplyInstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } - private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) - { - return this.ApplyTransformation(originalConfiguration, resourceName); - } + private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) + { + return this.ApplyTransformation(originalConfiguration, resourceName); + } + + private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) + { + Assert.True( + XNode.DeepEquals( + transformedWebConfig.FirstNode, + XDocument.Parse(expectedConfigContent).FirstNode)); + } - private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) + private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) + { + XDocument result; + Stream stream = null; + try { - Assert.True( - XNode.DeepEquals( - transformedWebConfig.FirstNode, - XDocument.Parse(expectedConfigContent).FirstNode)); + stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); + var document = new XmlTransformableDocument(); + using var transformation = new XmlTransformation(stream, null); + stream = null; + document.LoadXml(originalConfiguration); + transformation.Apply(document); + result = XDocument.Parse(document.OuterXml); } - - private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) + finally { - XDocument result; - Stream stream = null; - try - { - stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); - var document = new XmlTransformableDocument(); - using var transformation = new XmlTransformation(stream, null); - stream = null; - document.LoadXml(originalConfiguration); - transformation.Apply(document); - result = XDocument.Parse(document.OuterXml); - } - finally + if (stream != null) { - if (stream != null) - { - stream.Dispose(); - } + stream.Dispose(); } - - return result; } + + return result; } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs index d3ded5f632..431f52f995 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs @@ -18,15 +18,14 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class BasicTests { - public class BasicTests + [Fact] + public void AddAspNetInstrumentation_BadArgs() { - [Fact] - public void AddAspNetInstrumentation_BadArgs() - { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddAspNetInstrumentation()); - } + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddAspNetInstrumentation()); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs index 521e857bba..9c90b8ebee 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs @@ -18,14 +18,13 @@ using OpenTelemetry.Tests; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class EventSourceTest { - public class EventSourceTest + [Fact] + public void EventSourceTest_AspNetInstrumentationEventSource() { - [Fact] - public void EventSourceTest_AspNetInstrumentationEventSource() - { - EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(AspNetInstrumentationEventSource.Log); - } + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(AspNetInstrumentationEventSource.Log); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index bc1588d001..0e3bd5eef2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -29,342 +29,341 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class HttpInListenerTests { - public class HttpInListenerTests + [Theory] + [InlineData("http://localhost/", "http://localhost/", 0, null)] + [InlineData("http://localhost/", "http://localhost/", 0, null, true)] + [InlineData("https://localhost/", "https://localhost/", 0, null)] + [InlineData("https://localhost/", "https://user:pass@localhost/", 0, null)] // Test URL sanitization + [InlineData("http://localhost:443/", "http://localhost:443/", 0, null)] // Test http over 443 + [InlineData("https://localhost:80/", "https://localhost:80/", 0, null)] // Test https over 80 + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL sanitization + [InlineData("http://localhost:80/Index", "http://localhost:80/Index", 1, "{controller}/{action}/{id}")] + [InlineData("https://localhost:443/about_attr_route/10", "https://localhost:443/about_attr_route/10", 2, "about_attr_route/{customerId}")] + [InlineData("http://localhost:1880/api/weatherforecast", "http://localhost:1880/api/weatherforecast", 3, "api/{controller}/{id}")] + [InlineData("https://localhost:1843/subroute/10", "https://localhost:1843/subroute/10", 4, "subroute/{customerId}")] + [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "/api/value")] // Request will be filtered + [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "{ThrowException}")] // Filter user code will throw an exception + [InlineData("http://localhost/", "http://localhost/", 0, null, false, null, true)] // Test RecordException option + public void AspNetRequestsAreCollectedSuccessfully( + string expectedUrl, + string url, + int routeType, + string routeTemplate, + bool setStatusToErrorInEnrich = false, + string filter = null, + bool recordException = false) { - [Theory] - [InlineData("http://localhost/", "http://localhost/", 0, null)] - [InlineData("http://localhost/", "http://localhost/", 0, null, true)] - [InlineData("https://localhost/", "https://localhost/", 0, null)] - [InlineData("https://localhost/", "https://user:pass@localhost/", 0, null)] // Test URL sanitization - [InlineData("http://localhost:443/", "http://localhost:443/", 0, null)] // Test http over 443 - [InlineData("https://localhost:80/", "https://localhost:80/", 0, null)] // Test https over 80 - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL sanitization - [InlineData("http://localhost:80/Index", "http://localhost:80/Index", 1, "{controller}/{action}/{id}")] - [InlineData("https://localhost:443/about_attr_route/10", "https://localhost:443/about_attr_route/10", 2, "about_attr_route/{customerId}")] - [InlineData("http://localhost:1880/api/weatherforecast", "http://localhost:1880/api/weatherforecast", 3, "api/{controller}/{id}")] - [InlineData("https://localhost:1843/subroute/10", "https://localhost:1843/subroute/10", 4, "subroute/{customerId}")] - [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "/api/value")] // Request will be filtered - [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "{ThrowException}")] // Filter user code will throw an exception - [InlineData("http://localhost/", "http://localhost/", 0, null, false, null, true)] // Test RecordException option - public void AspNetRequestsAreCollectedSuccessfully( - string expectedUrl, - string url, - int routeType, - string routeTemplate, - bool setStatusToErrorInEnrich = false, - string filter = null, - bool recordException = false) + IDisposable tracerProvider = null; + RouteData routeData; + switch (routeType) { - IDisposable tracerProvider = null; - RouteData routeData; - switch (routeType) - { - case 0: // WebForm, no route data. - routeData = new RouteData(); - break; - case 1: // Traditional MVC. - case 2: // Attribute routing MVC. - case 3: // Traditional WebAPI. - routeData = new RouteData() - { - Route = new Route(routeTemplate, null), - }; - break; - case 4: // Attribute routing WebAPI. - routeData = new RouteData(); - var value = new[] - { - new - { - Route = new - { - RouteTemplate = routeTemplate, - }, - }, - }; - routeData.Values.Add( - "MS_SubRoutes", - value); - break; - default: - throw new NotSupportedException(); - } - - var workerRequest = new Mock(); - workerRequest.Setup(wr => wr.GetKnownRequestHeader(It.IsAny())).Returns(i => - { - return i switch + case 0: // WebForm, no route data. + routeData = new RouteData(); + break; + case 1: // Traditional MVC. + case 2: // Attribute routing MVC. + case 3: // Traditional WebAPI. + routeData = new RouteData() { - 39 => "Test", // User-Agent - _ => null, + Route = new Route(routeTemplate, null), }; - }); - - HttpContext.Current = new HttpContext( - new HttpRequest(string.Empty, url, string.Empty) + break; + case 4: // Attribute routing WebAPI. + routeData = new RouteData(); + var value = new[] { - RequestContext = new RequestContext() + new { - RouteData = routeData, - }, - }, - new HttpResponse(new StringWriter())); - - typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, workerRequest.Object); - - List exportedItems = new List(16); - - Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); - using (tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation((options) => - { - options.Filter = httpContext => - { - Assert.True(Activity.Current.IsAllDataRequested); - if (string.IsNullOrEmpty(filter)) - { - return true; - } - - if (filter == "{ThrowException}") + Route = new { - throw new InvalidOperationException(); - } - - return httpContext.Request.Path != filter; - }; - - options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? Status.Error : default); + RouteTemplate = routeTemplate, + }, + }, + }; + routeData.Values.Add( + "MS_SubRoutes", + value); + break; + default: + throw new NotSupportedException(); + } - options.RecordException = recordException; - }) - .AddInMemoryExporter(exportedItems) - .Build()) + var workerRequest = new Mock(); + workerRequest.Setup(wr => wr.GetKnownRequestHeader(It.IsAny())).Returns(i => + { + return i switch { - using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); - - var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + 39 => "Test", // User-Agent + _ => null, + }; + }); - if (filter == "{ThrowException}") + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, url, string.Empty) + { + RequestContext = new RequestContext() { - Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); - } + RouteData = routeData, + }, + }, + new HttpResponse(new StringWriter())); + + typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, workerRequest.Object); + + List exportedItems = new List(16); + + Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); + using (tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation((options) => + { + options.Filter = httpContext => + { + Assert.True(Activity.Current.IsAllDataRequested); + if (string.IsNullOrEmpty(filter)) + { + return true; + } + + if (filter == "{ThrowException}") + { + throw new InvalidOperationException(); + } + + return httpContext.Request.Path != filter; + }; + + options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? Status.Error : default); + + options.RecordException = recordException; + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); - Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); - if (recordException) - { - ActivityHelper.WriteActivityException(activity, HttpContext.Current, new InvalidOperationException(), TelemetryHttpModule.Options.OnExceptionCallback); - } - - ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + if (filter == "{ThrowException}") + { + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); } - if (HttpContext.Current.Request.Path == filter || filter == "{ThrowException}") + Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); + + if (recordException) { - Assert.Empty(exportedItems); - return; + ActivityHelper.WriteActivityException(activity, HttpContext.Current, new InvalidOperationException(), TelemetryHttpModule.Options.OnExceptionCallback); } - Assert.Single(exportedItems); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + } - Activity span = exportedItems[0]; + if (HttpContext.Current.Request.Path == filter || filter == "{ThrowException}") + { + Assert.Empty(exportedItems); + return; + } - Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); - Assert.NotEqual(TimeSpan.Zero, span.Duration); + Assert.Single(exportedItems); - Assert.Equal(routeTemplate ?? HttpContext.Current.Request.Path, span.DisplayName); - Assert.Equal(ActivityKind.Server, span.Kind); - Assert.True(span.Duration != TimeSpan.Zero); + Activity span = exportedItems[0]; - Assert.Equal(200, span.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); + Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); + Assert.NotEqual(TimeSpan.Zero, span.Duration); - var expectedUri = new Uri(expectedUrl); - var actualUrl = span.GetTagValue(SemanticConventions.AttributeHttpUrl); + Assert.Equal(routeTemplate ?? HttpContext.Current.Request.Path, span.DisplayName); + Assert.Equal(ActivityKind.Server, span.Kind); + Assert.True(span.Duration != TimeSpan.Zero); - Assert.Equal(expectedUri.ToString(), actualUrl); + Assert.Equal(200, span.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); - // Url strips 80 or 443 if the scheme matches. - if ((expectedUri.Port == 80 && expectedUri.Scheme == "http") || (expectedUri.Port == 443 && expectedUri.Scheme == "https")) - { - Assert.DoesNotContain($":{expectedUri.Port}", actualUrl as string); - } - else - { - Assert.Contains($":{expectedUri.Port}", actualUrl as string); - } + var expectedUri = new Uri(expectedUrl); + var actualUrl = span.GetTagValue(SemanticConventions.AttributeHttpUrl); - // Host includes port if it isn't 80 or 443. - if (expectedUri.Port is 80 or 443) - { - Assert.Equal( - expectedUri.Host, - span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); - } - else - { - Assert.Equal( - $"{expectedUri.Host}:{expectedUri.Port}", - span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); - } + Assert.Equal(expectedUri.ToString(), actualUrl); - Assert.Equal(HttpContext.Current.Request.HttpMethod, span.GetTagValue(SemanticConventions.AttributeHttpMethod) as string); - Assert.Equal(HttpContext.Current.Request.Path, span.GetTagValue(SemanticConventions.AttributeHttpTarget) as string); - Assert.Equal(HttpContext.Current.Request.UserAgent, span.GetTagValue(SemanticConventions.AttributeHttpUserAgent) as string); + // Url strips 80 or 443 if the scheme matches. + if ((expectedUri.Port == 80 && expectedUri.Scheme == "http") || (expectedUri.Port == 443 && expectedUri.Scheme == "https")) + { + Assert.DoesNotContain($":{expectedUri.Port}", actualUrl as string); + } + else + { + Assert.Contains($":{expectedUri.Port}", actualUrl as string); + } - if (recordException) - { - var status = span.GetStatus(); - Assert.Equal(Status.Error.StatusCode, status.StatusCode); - Assert.Equal("Operation is not valid due to the current state of the object.", status.Description); - } - else if (setStatusToErrorInEnrich) - { - // This validates that users can override the - // status in Enrich. - Assert.Equal(Status.Error, span.GetStatus()); + // Host includes port if it isn't 80 or 443. + if (expectedUri.Port is 80 or 443) + { + Assert.Equal( + expectedUri.Host, + span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); + } + else + { + Assert.Equal( + $"{expectedUri.Host}:{expectedUri.Port}", + span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); + } - // Instrumentation is not expected to set status description - // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode - Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); - } - else - { - Assert.Equal(Status.Unset, span.GetStatus()); + Assert.Equal(HttpContext.Current.Request.HttpMethod, span.GetTagValue(SemanticConventions.AttributeHttpMethod) as string); + Assert.Equal(HttpContext.Current.Request.Path, span.GetTagValue(SemanticConventions.AttributeHttpTarget) as string); + Assert.Equal(HttpContext.Current.Request.UserAgent, span.GetTagValue(SemanticConventions.AttributeHttpUserAgent) as string); - // Instrumentation is not expected to set status description - // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode - Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); - } + if (recordException) + { + var status = span.GetStatus(); + Assert.Equal(Status.Error.StatusCode, status.StatusCode); + Assert.Equal("Operation is not valid due to the current state of the object.", status.Description); } + else if (setStatusToErrorInEnrich) + { + // This validates that users can override the + // status in Enrich. + Assert.Equal(Status.Error, span.GetStatus()); - [Theory] - [InlineData(SamplingDecision.Drop)] - [InlineData(SamplingDecision.RecordOnly)] - [InlineData(SamplingDecision.RecordAndSample)] - public void ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision samplingDecision) + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); + } + else { - HttpContext.Current = new HttpContext( - new HttpRequest(string.Empty, "http://localhost/", string.Empty) + Assert.Equal(Status.Unset, span.GetStatus()); + + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); + } + } + + [Theory] + [InlineData(SamplingDecision.Drop)] + [InlineData(SamplingDecision.RecordOnly)] + [InlineData(SamplingDecision.RecordAndSample)] + public void ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision samplingDecision) + { + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, "http://localhost/", string.Empty) + { + RequestContext = new RequestContext() { - RequestContext = new RequestContext() - { - RouteData = new RouteData(), - }, + RouteData = new RouteData(), }, - new HttpResponse(new StringWriter())); + }, + new HttpResponse(new StringWriter())); - bool isPropagatorCalled = false; - var propagator = new Mock(); - propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) - .Returns(() => - { - isPropagatorCalled = true; - return default; - }); - - var activityProcessor = new Mock>(); - Sdk.SetDefaultTextMapPropagator(propagator.Object); - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new TestSampler(samplingDecision)) - .AddAspNetInstrumentation() - .AddProcessor(activityProcessor.Object).Build()) + bool isPropagatorCalled = false; + var propagator = new Mock(); + propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) + .Returns(() => { - var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); - ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); - } + isPropagatorCalled = true; + return default; + }); - Assert.True(isPropagatorCalled); + var activityProcessor = new Mock>(); + Sdk.SetDefaultTextMapPropagator(propagator.Object); + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new TestSampler(samplingDecision)) + .AddAspNetInstrumentation() + .AddProcessor(activityProcessor.Object).Build()) + { + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); } - [Fact] - public void ExtractContextIrrespectiveOfTheFilterApplied() - { - HttpContext.Current = new HttpContext( - new HttpRequest(string.Empty, "http://localhost/", string.Empty) + Assert.True(isPropagatorCalled); + } + + [Fact] + public void ExtractContextIrrespectiveOfTheFilterApplied() + { + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, "http://localhost/", string.Empty) + { + RequestContext = new RequestContext() { - RequestContext = new RequestContext() - { - RouteData = new RouteData(), - }, + RouteData = new RouteData(), }, - new HttpResponse(new StringWriter())); + }, + new HttpResponse(new StringWriter())); - bool isPropagatorCalled = false; - var propagator = new Mock(); - propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) - .Returns(() => - { - isPropagatorCalled = true; - return default; - }); - - bool isFilterCalled = false; - var activityProcessor = new Mock>(); - Sdk.SetDefaultTextMapPropagator(propagator.Object); - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation(options => - { - options.Filter = context => - { - isFilterCalled = true; - return false; - }; - }) - .AddProcessor(activityProcessor.Object).Build()) + bool isPropagatorCalled = false; + var propagator = new Mock(); + propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) + .Returns(() => { - var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); - ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); - } + isPropagatorCalled = true; + return default; + }); - Assert.True(isFilterCalled); - Assert.True(isPropagatorCalled); + bool isFilterCalled = false; + var activityProcessor = new Mock>(); + Sdk.SetDefaultTextMapPropagator(propagator.Object); + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation(options => + { + options.Filter = context => + { + isFilterCalled = true; + return false; + }; + }) + .AddProcessor(activityProcessor.Object).Build()) + { + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); } - private static Action GetEnrichmentAction(Status statusToBeSet) + Assert.True(isFilterCalled); + Assert.True(isPropagatorCalled); + } + + private static Action GetEnrichmentAction(Status statusToBeSet) + { + void EnrichAction(Activity activity, string method, object obj) { - void EnrichAction(Activity activity, string method, object obj) + Assert.True(activity.IsAllDataRequested); + switch (method) { - Assert.True(activity.IsAllDataRequested); - switch (method) - { - case "OnStartActivity": - Assert.True(obj is HttpRequest); - break; + case "OnStartActivity": + Assert.True(obj is HttpRequest); + break; - case "OnStopActivity": - Assert.True(obj is HttpResponse); - if (statusToBeSet != default) - { - activity.SetStatus(statusToBeSet); - } + case "OnStopActivity": + Assert.True(obj is HttpResponse); + if (statusToBeSet != default) + { + activity.SetStatus(statusToBeSet); + } - break; + break; - default: - break; - } + default: + break; } - - return EnrichAction; } - private class TestSampler : Sampler - { - private readonly SamplingDecision samplingDecision; + return EnrichAction; + } - public TestSampler(SamplingDecision samplingDecision) - { - this.samplingDecision = samplingDecision; - } + private class TestSampler : Sampler + { + private readonly SamplingDecision samplingDecision; - public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) - { - return new SamplingResult(this.samplingDecision); - } + public TestSampler(SamplingDecision samplingDecision) + { + this.samplingDecision = samplingDecision; + } + + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + return new SamplingResult(this.samplingDecision); } } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index b9fbbbeebe..f4d27ffd1b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -22,24 +22,24 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class HttpInMetricsListenerTests { - public class HttpInMetricsListenerTests + [Fact] + public void HttpDurationMetricIsEmitted() { - [Fact] - public void HttpDurationMetricIsEmitted() - { - string url = "http://localhost/api/value"; - double duration = 0; - HttpContext.Current = new HttpContext( - new HttpRequest(string.Empty, url, string.Empty), - new HttpResponse(new StringWriter())); - - // This is to enable activity creation - // as it is created using activitysource inside TelemetryHttpModule - // TODO: This should not be needed once the dependency on activity is removed from metrics - using var traceprovider = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation(opts => opts.Enrich + string url = "http://localhost/api/value"; + double duration = 0; + HttpContext.Current = new HttpContext( + new HttpRequest(string.Empty, url, string.Empty), + new HttpResponse(new StringWriter())); + + // This is to enable activity creation + // as it is created using activitysource inside TelemetryHttpModule + // TODO: This should not be needed once the dependency on activity is removed from metrics + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation(opts => opts.Enrich = (activity, eventName, rawObject) => { if (eventName.Equals("OnStopActivity")) @@ -47,66 +47,65 @@ public void HttpDurationMetricIsEmitted() duration = activity.Duration.TotalMilliseconds; } }) - .Build(); + .Build(); - var exportedItems = new List(); - using var meterprovider = Sdk.CreateMeterProviderBuilder() - .AddAspNetInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); + var exportedItems = new List(); + using var meterprovider = Sdk.CreateMeterProviderBuilder() + .AddAspNetInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); - var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); - ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); - meterprovider.ForceFlush(); + meterprovider.ForceFlush(); - var metricPoints = new List(); - foreach (var p in exportedItems[0].GetMetricPoints()) - { - metricPoints.Add(p); - } + var metricPoints = new List(); + foreach (var p in exportedItems[0].GetMetricPoints()) + { + metricPoints.Add(p); + } - Assert.Single(metricPoints); + Assert.Single(metricPoints); - var metricPoint = metricPoints[0]; + var metricPoint = metricPoints[0]; - var count = metricPoint.GetHistogramCount(); - var sum = metricPoint.GetHistogramSum(); + var count = metricPoint.GetHistogramCount(); + var sum = metricPoint.GetHistogramSum(); - Assert.Equal(MetricType.Histogram, exportedItems[0].MetricType); - Assert.Equal("http.server.duration", exportedItems[0].Name); - Assert.Equal(1L, count); - Assert.Equal(duration, sum); + Assert.Equal(MetricType.Histogram, exportedItems[0].MetricType); + Assert.Equal("http.server.duration", exportedItems[0].Name); + Assert.Equal(1L, count); + Assert.Equal(duration, sum); - Assert.Equal(3, metricPoints[0].Tags.Count); - string httpMethod = null; - int httpStatusCode = 0; - string httpScheme = null; + Assert.Equal(3, metricPoints[0].Tags.Count); + string httpMethod = null; + int httpStatusCode = 0; + string httpScheme = null; - foreach (var tag in metricPoints[0].Tags) + foreach (var tag in metricPoints[0].Tags) + { + if (tag.Key == SemanticConventions.AttributeHttpMethod) { - if (tag.Key == SemanticConventions.AttributeHttpMethod) - { - httpMethod = (string)tag.Value; - continue; - } - - if (tag.Key == SemanticConventions.AttributeHttpStatusCode) - { - httpStatusCode = (int)tag.Value; - continue; - } + httpMethod = (string)tag.Value; + continue; + } - if (tag.Key == SemanticConventions.AttributeHttpScheme) - { - httpScheme = (string)tag.Value; - continue; - } + if (tag.Key == SemanticConventions.AttributeHttpStatusCode) + { + httpStatusCode = (int)tag.Value; + continue; } - Assert.Equal("GET", httpMethod); - Assert.Equal(200, httpStatusCode); - Assert.Equal("http", httpScheme); + if (tag.Key == SemanticConventions.AttributeHttpScheme) + { + httpScheme = (string)tag.Value; + continue; + } } + + Assert.Equal("GET", httpMethod); + Assert.Equal(200, httpStatusCode); + Assert.Equal("http", httpScheme); } } From e005d8cb546c87cee5fba32cc3608ab6f0f6462b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 16 Aug 2022 20:58:29 +0200 Subject: [PATCH 0288/1499] [Extensions.PersistentStorage] File scoped namespace (#586) --- .../NotNullWhenAttribute.cs | 23 +- .../PersistentBlob.cs | 169 +++++---- .../PersistentBlobProvider.cs | 185 +++++----- ...ersistentStorageAbstractionsEventSource.cs | 63 ++-- .../FileBlob.cs | 149 ++++---- .../FileBlobProvider.cs | 269 +++++++------- .../PersistentStorageEventSource.cs | 259 +++++++------- .../PersistentStorageHelper.cs | 333 +++++++++--------- .../FileBlobProviderTests.cs | 295 ++++++++-------- .../FileBlobTests.cs | 243 +++++++------ 10 files changed, 989 insertions(+), 999 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs index 77db7673bc..c3c3ffad49 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs @@ -15,19 +15,18 @@ // #if NETSTANDARD2_0 || NET462 -namespace System.Diagnostics.CodeAnalysis +namespace System.Diagnostics.CodeAnalysis; + +[AttributeUsage(AttributeTargets.All)] +internal sealed class NotNullWhenAttribute : Attribute { - [AttributeUsage(AttributeTargets.All)] - internal sealed class NotNullWhenAttribute : Attribute - { - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => this.ReturnValue = returnValue; + /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => this.ReturnValue = returnValue; - /// Gets a value indicating whether gets the return value condition. - public bool ReturnValue { get; } - } + /// Gets a value indicating whether gets the return value condition. + public bool ReturnValue { get; } } #endif diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs index 5cccfd07c4..9f4d6c979b 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs @@ -17,108 +17,107 @@ using System; using System.Diagnostics.CodeAnalysis; -namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions +namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions; + +/// +/// Represents a persistent blob. +/// +public abstract class PersistentBlob { /// - /// Represents a persistent blob. + /// Attempts to read the content from the blob. /// - public abstract class PersistentBlob + /// + /// The content to be read. + /// + /// + /// True if read was successful or else false. + /// + public bool TryRead([NotNullWhen(true)] out byte[]? buffer) { - /// - /// Attempts to read the content from the blob. - /// - /// - /// The content to be read. - /// - /// - /// True if read was successful or else false. - /// - public bool TryRead([NotNullWhen(true)] out byte[]? buffer) + try + { + return this.OnTryRead(out buffer); + } + catch (Exception ex) { - try - { - return this.OnTryRead(out buffer); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to read the blob.", ex); - buffer = null; - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to read the blob.", ex); + buffer = null; + return false; } + } - /// - /// Attempts to write the given content to the blob. - /// - /// - /// The content to be written. - /// - /// - /// The number of milliseconds to lease after the write operation finished. - /// - /// - /// True if the write operation succeeded or else false. - /// - public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) + /// + /// Attempts to write the given content to the blob. + /// + /// + /// The content to be written. + /// + /// + /// The number of milliseconds to lease after the write operation finished. + /// + /// + /// True if the write operation succeeded or else false. + /// + public bool TryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) + { + try + { + return this.OnTryWrite(buffer, leasePeriodMilliseconds); + } + catch (Exception ex) { - try - { - return this.OnTryWrite(buffer, leasePeriodMilliseconds); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to write the blob", ex); - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to write the blob", ex); + return false; } + } - /// - /// Attempts to acquire lease on the blob. - /// - /// - /// The number of milliseconds to lease. - /// - /// - /// true if lease is acquired or else false. - /// - public bool TryLease(int leasePeriodMilliseconds) + /// + /// Attempts to acquire lease on the blob. + /// + /// + /// The number of milliseconds to lease. + /// + /// + /// true if lease is acquired or else false. + /// + public bool TryLease(int leasePeriodMilliseconds) + { + try + { + return this.OnTryLease(leasePeriodMilliseconds); + } + catch (Exception ex) { - try - { - return this.OnTryLease(leasePeriodMilliseconds); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to lease the blob", ex); - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to lease the blob", ex); + return false; } + } - /// - /// Attempts to delete the blob. - /// - /// - /// True if delete was successful else false. - /// - public bool TryDelete() + /// + /// Attempts to delete the blob. + /// + /// + /// True if delete was successful else false. + /// + public bool TryDelete() + { + try + { + return this.OnTryDelete(); + } + catch (Exception ex) { - try - { - return this.OnTryDelete(); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to delete the blob", ex); - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlob), "Failed to delete the blob", ex); + return false; } + } - protected abstract bool OnTryRead([NotNullWhen(true)] out byte[]? buffer); + protected abstract bool OnTryRead([NotNullWhen(true)] out byte[]? buffer); - protected abstract bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0); + protected abstract bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0); - protected abstract bool OnTryLease(int leasePeriodMilliseconds); + protected abstract bool OnTryLease(int leasePeriodMilliseconds); - protected abstract bool OnTryDelete(); - } + protected abstract bool OnTryDelete(); } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs index 2eec7f7a8a..82b5df58f9 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -19,116 +19,115 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions +namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions; + +/// +/// Represents persistent blob provider. +/// +public abstract class PersistentBlobProvider { /// - /// Represents persistent blob provider. + /// Attempts to create a new blob with the provided data and lease it. /// - public abstract class PersistentBlobProvider + /// + /// The content to be written. + /// + /// + /// The number of milliseconds to lease after the blob is created. + /// + /// + /// Blob if it is created. + /// + /// + /// True if the blob was created or else false. + /// + public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob) { - /// - /// Attempts to create a new blob with the provided data and lease it. - /// - /// - /// The content to be written. - /// - /// - /// The number of milliseconds to lease after the blob is created. - /// - /// - /// Blob if it is created. - /// - /// - /// True if the blob was created or else false. - /// - public bool TryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob) + try + { + return this.OnTryCreateBlob(buffer, leasePeriodMilliseconds, out blob); + } + catch (Exception ex) { - try - { - return this.OnTryCreateBlob(buffer, leasePeriodMilliseconds, out blob); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to create and lease the blob", ex); - blob = null; - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to create and lease the blob", ex); + blob = null; + return false; } + } - /// - /// Attempts to create a new blob with the provided data. - /// - /// - /// The content to be written. - /// - /// - /// Blob if it is created. - /// - /// - /// True if the blob was created or else false. - /// - public bool TryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob) + /// + /// Attempts to create a new blob with the provided data. + /// + /// + /// The content to be written. + /// + /// + /// Blob if it is created. + /// + /// + /// True if the blob was created or else false. + /// + public bool TryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob) + { + try + { + return this.OnTryCreateBlob(buffer, out blob); + } + catch (Exception ex) { - try - { - return this.OnTryCreateBlob(buffer, out blob); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to create the blob", ex); - blob = null; - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to create the blob", ex); + blob = null; + return false; } + } - /// - /// Attempts to get a single blob from storage. - /// - /// - /// Blob object if found. - /// - /// - /// True if blob is present or else false. - /// - public bool TryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) + /// + /// Attempts to get a single blob from storage. + /// + /// + /// Blob object if found. + /// + /// + /// True if blob is present or else false. + /// + public bool TryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) + { + try + { + return this.OnTryGetBlob(out blob); + } + catch (Exception ex) { - try - { - return this.OnTryGetBlob(out blob); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get a single blob", ex); - blob = null; - return false; - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get a single blob", ex); + blob = null; + return false; } + } - /// - /// Reads a sequence of blobs from storage. - /// - /// - /// List of blobs if present in storage or else empty collection. - /// - public IEnumerable GetBlobs() + /// + /// Reads a sequence of blobs from storage. + /// + /// + /// List of blobs if present in storage or else empty collection. + /// + public IEnumerable GetBlobs() + { + try + { + return this.OnGetBlobs() ?? Enumerable.Empty(); + } + catch (Exception ex) { - try - { - return this.OnGetBlobs() ?? Enumerable.Empty(); - } - catch (Exception ex) - { - PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get all the blobs", ex); - return Enumerable.Empty(); - } + PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get all the blobs", ex); + return Enumerable.Empty(); } + } - protected abstract IEnumerable OnGetBlobs(); + protected abstract IEnumerable OnGetBlobs(); - protected abstract bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob); + protected abstract bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob); - protected abstract bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob); + protected abstract bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob); - protected abstract bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob? blob); - } + protected abstract bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob? blob); } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs index b2ffb1cc23..2e15b8b8d5 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -19,46 +19,45 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage; + +[EventSource(Name = EventSourceName)] +internal sealed class PersistentStorageAbstractionsEventSource : EventSource { - [EventSource(Name = EventSourceName)] - internal sealed class PersistentStorageAbstractionsEventSource : EventSource - { - public static PersistentStorageAbstractionsEventSource Log = new PersistentStorageAbstractionsEventSource(); - private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage-Abstractions"; + public static PersistentStorageAbstractionsEventSource Log = new PersistentStorageAbstractionsEventSource(); + private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage-Abstractions"; - [NonEvent] - public void PersistentStorageAbstractionsException(string className, string message, Exception ex) + [NonEvent] + public void PersistentStorageAbstractionsException(string className, string message, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.PersistentStorageAbstractionsException(className, message, ToInvariantString(ex)); - } + this.PersistentStorageAbstractionsException(className, message, ToInvariantString(ex)); } + } - [Event(1, Message = "{0}: {1}: {2}", Level = EventLevel.Error)] - public void PersistentStorageAbstractionsException(string className, string message, string ex) + [Event(1, Message = "{0}: {1}: {2}", Level = EventLevel.Error)] + public void PersistentStorageAbstractionsException(string className, string message, string ex) + { + this.WriteEvent(1, className, message, ex); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try { - this.WriteEvent(1, className, message, ex); + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs index d82018c06a..742748bba8 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs @@ -19,106 +19,105 @@ using System.IO; using OpenTelemetry.Extensions.PersistentStorage.Abstractions; -namespace OpenTelemetry.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage; + +/// +/// The allows to save a blob +/// in file storage. +/// +public class FileBlob : PersistentBlob { /// - /// The allows to save a blob - /// in file storage. + /// Initializes a new instance of the + /// class. /// - public class FileBlob : PersistentBlob + /// Absolute file path of the blob. + public FileBlob(string fullPath) + { + this.FullPath = fullPath; + } + + public string FullPath { get; private set; } + + protected override bool OnTryRead([NotNullWhen(true)] out byte[] buffer) { - /// - /// Initializes a new instance of the - /// class. - /// - /// Absolute file path of the blob. - public FileBlob(string fullPath) + try { - this.FullPath = fullPath; + buffer = File.ReadAllBytes(this.FullPath); + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.CouldNotReadFileBlob(this.FullPath, ex); + buffer = null; + return false; } - public string FullPath { get; private set; } + return true; + } - protected override bool OnTryRead([NotNullWhen(true)] out byte[] buffer) + protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) + { + string path = this.FullPath + ".tmp"; + + try { - try - { - buffer = File.ReadAllBytes(this.FullPath); - } - catch (Exception ex) + PersistentStorageHelper.WriteAllBytes(path, buffer); + + if (leasePeriodMilliseconds > 0) { - PersistentStorageEventSource.Log.CouldNotReadFileBlob(this.FullPath, ex); - buffer = null; - return false; + var timestamp = DateTime.UtcNow + TimeSpan.FromMilliseconds(leasePeriodMilliseconds); + this.FullPath += $"@{timestamp:yyyy-MM-ddTHHmmss.fffffffZ}.lock"; } - return true; + File.Move(path, this.FullPath); } - - protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) + catch (Exception ex) { - string path = this.FullPath + ".tmp"; + PersistentStorageEventSource.Log.CouldNotWriteFileBlob(path, ex); + return false; + } - try - { - PersistentStorageHelper.WriteAllBytes(path, buffer); + return true; + } - if (leasePeriodMilliseconds > 0) - { - var timestamp = DateTime.UtcNow + TimeSpan.FromMilliseconds(leasePeriodMilliseconds); - this.FullPath += $"@{timestamp:yyyy-MM-ddTHHmmss.fffffffZ}.lock"; - } + protected override bool OnTryLease(int leasePeriodMilliseconds) + { + var path = this.FullPath; + var leaseTimestamp = DateTime.UtcNow + TimeSpan.FromMilliseconds(leasePeriodMilliseconds); + if (path.EndsWith(".lock", StringComparison.OrdinalIgnoreCase)) + { + path = path.Substring(0, path.LastIndexOf('@')); + } - File.Move(path, this.FullPath); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.CouldNotWriteFileBlob(path, ex); - return false; - } + path += $"@{leaseTimestamp:yyyy-MM-ddTHHmmss.fffffffZ}.lock"; - return true; + try + { + File.Move(this.FullPath, path); } - - protected override bool OnTryLease(int leasePeriodMilliseconds) + catch (Exception ex) { - var path = this.FullPath; - var leaseTimestamp = DateTime.UtcNow + TimeSpan.FromMilliseconds(leasePeriodMilliseconds); - if (path.EndsWith(".lock", StringComparison.OrdinalIgnoreCase)) - { - path = path.Substring(0, path.LastIndexOf('@')); - } - - path += $"@{leaseTimestamp:yyyy-MM-ddTHHmmss.fffffffZ}.lock"; + PersistentStorageEventSource.Log.CouldNotLeaseFileBlob(this.FullPath, ex); + return false; + } - try - { - File.Move(this.FullPath, path); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.CouldNotLeaseFileBlob(this.FullPath, ex); - return false; - } + this.FullPath = path; - this.FullPath = path; + return true; + } - return true; + protected override bool OnTryDelete() + { + try + { + PersistentStorageHelper.RemoveFile(this.FullPath); } - - protected override bool OnTryDelete() + catch (Exception ex) { - try - { - PersistentStorageHelper.RemoveFile(this.FullPath); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.CouldNotDeleteFileBlob(this.FullPath, ex); - return false; - } - - return true; + PersistentStorageEventSource.Log.CouldNotDeleteFileBlob(this.FullPath, ex); + return false; } + + return true; } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs index 6f08c8d1b2..9ffd6cf8e8 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs @@ -23,179 +23,178 @@ using OpenTelemetry.Extensions.PersistentStorage.Abstractions; using OpenTelemetry.Internal; -namespace OpenTelemetry.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage; + +/// +/// Persistent file storage allows to save data +/// as blobs in file storage. +/// +public class FileBlobProvider : PersistentBlobProvider, IDisposable { + private readonly string directoryPath; + private readonly long maxSizeInBytes; + private readonly long retentionPeriodInMilliseconds; + private readonly int writeTimeoutInMilliseconds; + private readonly Timer maintenanceTimer; + private bool disposedValue; + /// - /// Persistent file storage allows to save data - /// as blobs in file storage. + /// Initializes a new instance of the + /// class. /// - public class FileBlobProvider : PersistentBlobProvider, IDisposable + /// + /// Sets file storage folder location where blobs are stored. + /// + /// + /// Maximum allowed storage folder size. + /// Default is 50 MB. + /// + /// + /// Maintenance event runs at specified interval. + /// Removes expired leases and blobs that exceed retention period. + /// Default is 2 minutes. + /// + /// + /// Retention period in milliseconds for the blob. + /// Default is 2 days. + /// + /// + /// Controls the timeout when writing a buffer to blob. + /// Default is 1 minute. + /// + public FileBlobProvider( + string path, + long maxSizeInBytes = 52428800, + int maintenancePeriodInMilliseconds = 120000, + long retentionPeriodInMilliseconds = 172800000, + int writeTimeoutInMilliseconds = 60000) { - private readonly string directoryPath; - private readonly long maxSizeInBytes; - private readonly long retentionPeriodInMilliseconds; - private readonly int writeTimeoutInMilliseconds; - private readonly Timer maintenanceTimer; - private bool disposedValue; - - /// - /// Initializes a new instance of the - /// class. - /// - /// - /// Sets file storage folder location where blobs are stored. - /// - /// - /// Maximum allowed storage folder size. - /// Default is 50 MB. - /// - /// - /// Maintenance event runs at specified interval. - /// Removes expired leases and blobs that exceed retention period. - /// Default is 2 minutes. - /// - /// - /// Retention period in milliseconds for the blob. - /// Default is 2 days. - /// - /// - /// Controls the timeout when writing a buffer to blob. - /// Default is 1 minute. - /// - public FileBlobProvider( - string path, - long maxSizeInBytes = 52428800, - int maintenancePeriodInMilliseconds = 120000, - long retentionPeriodInMilliseconds = 172800000, - int writeTimeoutInMilliseconds = 60000) - { - Guard.ThrowIfNull(path); - - // TODO: Validate time period values - this.directoryPath = PersistentStorageHelper.CreateSubdirectory(path); - this.maxSizeInBytes = maxSizeInBytes; - this.retentionPeriodInMilliseconds = retentionPeriodInMilliseconds; - this.writeTimeoutInMilliseconds = writeTimeoutInMilliseconds; - - this.maintenanceTimer = new Timer(maintenancePeriodInMilliseconds); - this.maintenanceTimer.Elapsed += this.OnMaintenanceEvent; - this.maintenanceTimer.AutoReset = true; - this.maintenanceTimer.Enabled = true; - } + Guard.ThrowIfNull(path); + + // TODO: Validate time period values + this.directoryPath = PersistentStorageHelper.CreateSubdirectory(path); + this.maxSizeInBytes = maxSizeInBytes; + this.retentionPeriodInMilliseconds = retentionPeriodInMilliseconds; + this.writeTimeoutInMilliseconds = writeTimeoutInMilliseconds; + + this.maintenanceTimer = new Timer(maintenancePeriodInMilliseconds); + this.maintenanceTimer.Elapsed += this.OnMaintenanceEvent; + this.maintenanceTimer.AutoReset = true; + this.maintenanceTimer.Enabled = true; + } - public void Dispose() - { - this.Dispose(disposing: true); - GC.SuppressFinalize(this); - } + public void Dispose() + { + this.Dispose(disposing: true); + GC.SuppressFinalize(this); + } - public void Dispose(bool disposing) + public void Dispose(bool disposing) + { + if (!this.disposedValue) { - if (!this.disposedValue) + if (disposing) { - if (disposing) - { - this.maintenanceTimer.Dispose(); - } - - this.disposedValue = true; + this.maintenanceTimer.Dispose(); } + + this.disposedValue = true; } + } - protected override IEnumerable OnGetBlobs() - { - var retentionDeadline = DateTime.UtcNow - TimeSpan.FromMilliseconds(this.retentionPeriodInMilliseconds); + protected override IEnumerable OnGetBlobs() + { + var retentionDeadline = DateTime.UtcNow - TimeSpan.FromMilliseconds(this.retentionPeriodInMilliseconds); - foreach (var file in Directory.EnumerateFiles(this.directoryPath, "*.blob", SearchOption.TopDirectoryOnly).OrderByDescending(f => f)) + foreach (var file in Directory.EnumerateFiles(this.directoryPath, "*.blob", SearchOption.TopDirectoryOnly).OrderByDescending(f => f)) + { + DateTime fileDateTime = PersistentStorageHelper.GetDateTimeFromBlobName(file); + if (fileDateTime > retentionDeadline) { - DateTime fileDateTime = PersistentStorageHelper.GetDateTimeFromBlobName(file); - if (fileDateTime > retentionDeadline) - { - yield return new FileBlob(file); - } + yield return new FileBlob(file); } } + } - protected override bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob blob) - { - blob = this.CreateFileBlob(buffer, leasePeriodMilliseconds); + protected override bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob blob) + { + blob = this.CreateFileBlob(buffer, leasePeriodMilliseconds); - return blob != null; - } + return blob != null; + } - protected override bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob blob) - { - blob = this.CreateFileBlob(buffer); + protected override bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob blob) + { + blob = this.CreateFileBlob(buffer); - return blob != null; - } + return blob != null; + } - protected override bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob blob) - { - blob = this.OnGetBlobs().FirstOrDefault(); + protected override bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob blob) + { + blob = this.OnGetBlobs().FirstOrDefault(); - return blob != null; - } + return blob != null; + } - private void OnMaintenanceEvent(object source, ElapsedEventArgs e) + private void OnMaintenanceEvent(object source, ElapsedEventArgs e) + { + try { - try - { - if (!Directory.Exists(this.directoryPath)) - { - Directory.CreateDirectory(this.directoryPath); - } - } - catch (Exception ex) + if (!Directory.Exists(this.directoryPath)) { - PersistentStorageEventSource.Log.PersistentStorageException(nameof(FileBlobProvider), $"Error creating directory {this.directoryPath}", ex); - return; + Directory.CreateDirectory(this.directoryPath); } - - PersistentStorageHelper.RemoveExpiredBlobs(this.directoryPath, this.retentionPeriodInMilliseconds, this.writeTimeoutInMilliseconds); + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.PersistentStorageException(nameof(FileBlobProvider), $"Error creating directory {this.directoryPath}", ex); + return; } - private bool CheckStorageSize() + PersistentStorageHelper.RemoveExpiredBlobs(this.directoryPath, this.retentionPeriodInMilliseconds, this.writeTimeoutInMilliseconds); + } + + private bool CheckStorageSize() + { + var size = PersistentStorageHelper.GetDirectorySize(); + if (size >= this.maxSizeInBytes) { - var size = PersistentStorageHelper.GetDirectorySize(); - if (size >= this.maxSizeInBytes) - { - // TODO: check accuracy of size reporting. - PersistentStorageEventSource.Log.PersistentStorageWarning( - nameof(FileBlobProvider), - $"Persistent storage max capacity has been reached. Currently at {size / 1024} KiB. Please consider increasing the value of storage max size in exporter config."); - return false; - } + // TODO: check accuracy of size reporting. + PersistentStorageEventSource.Log.PersistentStorageWarning( + nameof(FileBlobProvider), + $"Persistent storage max capacity has been reached. Currently at {size / 1024} KiB. Please consider increasing the value of storage max size in exporter config."); + return false; + } - return true; + return true; + } + + private PersistentBlob CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) + { + if (!this.CheckStorageSize()) + { + return null; } - private PersistentBlob CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) + try { - if (!this.CheckStorageSize()) - { - return null; - } + var blobFilePath = Path.Combine(this.directoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); + var blob = new FileBlob(blobFilePath); - try + if (blob.TryWrite(buffer, leasePeriodMilliseconds)) { - var blobFilePath = Path.Combine(this.directoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); - var blob = new FileBlob(blobFilePath); - - if (blob.TryWrite(buffer, leasePeriodMilliseconds)) - { - return blob; - } - else - { - return null; - } + return blob; } - catch (Exception ex) + else { - PersistentStorageEventSource.Log.CouldNotCreateFileBlob(ex); return null; } } + catch (Exception ex) + { + PersistentStorageEventSource.Log.CouldNotCreateFileBlob(ex); + return null; + } } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs index d8868d61f9..c310eeadcd 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs @@ -19,178 +19,177 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage; + +[EventSource(Name = EventSourceName)] +internal sealed class PersistentStorageEventSource : EventSource { - [EventSource(Name = EventSourceName)] - internal sealed class PersistentStorageEventSource : EventSource - { - public static PersistentStorageEventSource Log = new PersistentStorageEventSource(); - private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage"; + public static PersistentStorageEventSource Log = new PersistentStorageEventSource(); + private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage"; - [NonEvent] - public void CouldNotReadFileBlob(string filePath, Exception ex) + [NonEvent] + public void CouldNotReadFileBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) - { - this.CouldNotReadFileBlob(filePath, ToInvariantString(ex)); - } + this.CouldNotReadFileBlob(filePath, ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotWriteFileBlob(string filePath, Exception ex) + [NonEvent] + public void CouldNotWriteFileBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) - { - this.CouldNotWriteFileBlob(filePath, ToInvariantString(ex)); - } + this.CouldNotWriteFileBlob(filePath, ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotLeaseFileBlob(string filePath, Exception ex) + [NonEvent] + public void CouldNotLeaseFileBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) - { - this.CouldNotLeaseFileBlob(filePath, ToInvariantString(ex)); - } + this.CouldNotLeaseFileBlob(filePath, ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotDeleteFileBlob(string filePath, Exception ex) + [NonEvent] + public void CouldNotDeleteFileBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) - { - this.CouldNotDeleteFileBlob(filePath, ToInvariantString(ex)); - } + this.CouldNotDeleteFileBlob(filePath, ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotCreateFileBlob(Exception ex) + [NonEvent] + public void CouldNotCreateFileBlob(Exception ex) + { + if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) - { - this.CouldNotCreateFileBlob(ToInvariantString(ex)); - } + this.CouldNotCreateFileBlob(ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotRemoveExpiredBlob(string filePath, Exception ex) + [NonEvent] + public void CouldNotRemoveExpiredBlob(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) - { - this.CouldNotRemoveExpiredBlob(filePath, ToInvariantString(ex)); - } + this.CouldNotRemoveExpiredBlob(filePath, ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotRemoveTimedOutTmpFile(string filePath, Exception ex) + [NonEvent] + public void CouldNotRemoveTimedOutTmpFile(string filePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) - { - this.CouldNotRemoveTimedOutTmpFile(filePath, ToInvariantString(ex)); - } + this.CouldNotRemoveTimedOutTmpFile(filePath, ToInvariantString(ex)); } + } - [NonEvent] - public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, Exception ex) + [NonEvent] + public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) - { - this.CouldNotRemoveExpiredLease(srcFilePath, destFilePath, ToInvariantString(ex)); - } + this.CouldNotRemoveExpiredLease(srcFilePath, destFilePath, ToInvariantString(ex)); } + } - [NonEvent] - public void PersistentStorageException(string className, string message, Exception ex) + [NonEvent] + public void PersistentStorageException(string className, string message, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.PersistentStorageException(className, message, ToInvariantString(ex)); - } + this.PersistentStorageException(className, message, ToInvariantString(ex)); } + } - [Event(1, Message = "Could not read blob from file '{0}'", Level = EventLevel.Informational)] - public void CouldNotReadFileBlob(string filePath, string ex) - { - this.WriteEvent(1, filePath, ex); - } + [Event(1, Message = "Could not read blob from file '{0}'", Level = EventLevel.Informational)] + public void CouldNotReadFileBlob(string filePath, string ex) + { + this.WriteEvent(1, filePath, ex); + } - [Event(2, Message = "Could not write blob to file '{0}'", Level = EventLevel.Informational)] - public void CouldNotWriteFileBlob(string filePath, string ex) - { - this.WriteEvent(2, filePath, ex); - } + [Event(2, Message = "Could not write blob to file '{0}'", Level = EventLevel.Informational)] + public void CouldNotWriteFileBlob(string filePath, string ex) + { + this.WriteEvent(2, filePath, ex); + } - [Event(3, Message = "Could not acquire a lease on file '{0}'", Level = EventLevel.Informational)] - public void CouldNotLeaseFileBlob(string filePath, string ex) - { - this.WriteEvent(3, filePath, ex); - } + [Event(3, Message = "Could not acquire a lease on file '{0}'", Level = EventLevel.Informational)] + public void CouldNotLeaseFileBlob(string filePath, string ex) + { + this.WriteEvent(3, filePath, ex); + } - [Event(4, Message = "Could not delete file '{0}'", Level = EventLevel.Informational)] - public void CouldNotDeleteFileBlob(string filePath, string ex) - { - this.WriteEvent(4, filePath, ex); - } + [Event(4, Message = "Could not delete file '{0}'", Level = EventLevel.Informational)] + public void CouldNotDeleteFileBlob(string filePath, string ex) + { + this.WriteEvent(4, filePath, ex); + } - [Event(5, Message = "Could not create file blob", Level = EventLevel.Informational)] - public void CouldNotCreateFileBlob(string ex) - { - this.WriteEvent(5, ex); - } + [Event(5, Message = "Could not create file blob", Level = EventLevel.Informational)] + public void CouldNotCreateFileBlob(string ex) + { + this.WriteEvent(5, ex); + } - [Event(6, Message = "Could not remove expired blob '{0}'", Level = EventLevel.Warning)] - public void CouldNotRemoveExpiredBlob(string filePath, string ex) - { - this.WriteEvent(6, filePath, ex); - } + [Event(6, Message = "Could not remove expired blob '{0}'", Level = EventLevel.Warning)] + public void CouldNotRemoveExpiredBlob(string filePath, string ex) + { + this.WriteEvent(6, filePath, ex); + } - [Event(7, Message = "Could not remove timed out file '{0}'", Level = EventLevel.Warning)] - public void CouldNotRemoveTimedOutTmpFile(string filePath, string ex) - { - this.WriteEvent(7, filePath, ex); - } + [Event(7, Message = "Could not remove timed out file '{0}'", Level = EventLevel.Warning)] + public void CouldNotRemoveTimedOutTmpFile(string filePath, string ex) + { + this.WriteEvent(7, filePath, ex); + } - [Event(8, Message = "Could not rename '{0}' to '{1}'", Level = EventLevel.Warning)] - public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, string ex) - { - this.WriteEvent(8, srcFilePath, destFilePath, ex); - } + [Event(8, Message = "Could not rename '{0}' to '{1}'", Level = EventLevel.Warning)] + public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, string ex) + { + this.WriteEvent(8, srcFilePath, destFilePath, ex); + } - [Event(9, Message = "{0}: Error Message: {1}. Exception: {3}", Level = EventLevel.Error)] - public void PersistentStorageException(string className, string message, string ex) - { - this.WriteEvent(9, className, message, ex); - } + [Event(9, Message = "{0}: Error Message: {1}. Exception: {3}", Level = EventLevel.Error)] + public void PersistentStorageException(string className, string message, string ex) + { + this.WriteEvent(9, className, message, ex); + } - [Event(10, Message = "{0}: Warning Message: {1}", Level = EventLevel.Warning)] - public void PersistentStorageWarning(string className, string message) - { - this.WriteEvent(10, className, message); - } + [Event(10, Message = "{0}: Warning Message: {1}", Level = EventLevel.Warning)] + public void PersistentStorageWarning(string className, string message) + { + this.WriteEvent(10, className, message); + } + + [Event(11, Message = "{0}: Message: {1}", Level = EventLevel.Informational)] + public void PersistentStorageInformation(string className, string message) + { + this.WriteEvent(11, className, message); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; - [Event(11, Message = "{0}: Message: {1}", Level = EventLevel.Informational)] - public void PersistentStorageInformation(string className, string message) + try { - this.WriteEvent(11, className, message); + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs index 470a7d31ad..f5baa87ab9 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -24,231 +24,230 @@ using System.Text; using System.Threading; -namespace OpenTelemetry.Extensions.PersistentStorage +namespace OpenTelemetry.Extensions.PersistentStorage; + +internal static class PersistentStorageHelper { - internal static class PersistentStorageHelper - { - private static long directorySize; + private static long directorySize; - internal static void RemoveExpiredBlob(DateTime retentionDeadline, string filePath) + internal static void RemoveExpiredBlob(DateTime retentionDeadline, string filePath) + { + if (filePath.EndsWith(".blob", StringComparison.OrdinalIgnoreCase)) { - if (filePath.EndsWith(".blob", StringComparison.OrdinalIgnoreCase)) + DateTime fileDateTime = GetDateTimeFromBlobName(filePath); + if (fileDateTime < retentionDeadline) { - DateTime fileDateTime = GetDateTimeFromBlobName(filePath); - if (fileDateTime < retentionDeadline) + try { - try - { - File.Delete(filePath); - PersistentStorageEventSource.Log.PersistentStorageInformation(nameof(PersistentStorageHelper), "Removing blob as retention deadline expired"); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.CouldNotRemoveExpiredBlob(filePath, ex); - } + File.Delete(filePath); + PersistentStorageEventSource.Log.PersistentStorageInformation(nameof(PersistentStorageHelper), "Removing blob as retention deadline expired"); + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.CouldNotRemoveExpiredBlob(filePath, ex); } } } + } - internal static bool RemoveExpiredLease(DateTime leaseDeadline, string filePath) - { - bool success = false; + internal static bool RemoveExpiredLease(DateTime leaseDeadline, string filePath) + { + bool success = false; - if (filePath.EndsWith(".lock", StringComparison.OrdinalIgnoreCase)) + if (filePath.EndsWith(".lock", StringComparison.OrdinalIgnoreCase)) + { + DateTime fileDateTime = GetDateTimeFromLeaseName(filePath); + if (fileDateTime < leaseDeadline) { - DateTime fileDateTime = GetDateTimeFromLeaseName(filePath); - if (fileDateTime < leaseDeadline) + var newFilePath = filePath.Substring(0, filePath.LastIndexOf('@')); + try { - var newFilePath = filePath.Substring(0, filePath.LastIndexOf('@')); - try - { - File.Move(filePath, newFilePath); - success = true; - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.CouldNotRemoveExpiredLease(filePath, newFilePath, ex); - } + File.Move(filePath, newFilePath); + success = true; + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.CouldNotRemoveExpiredLease(filePath, newFilePath, ex); } } - - return success; } - internal static bool RemoveTimedOutTmpFiles(DateTime timeoutDeadline, string filePath) - { - bool success = false; + return success; + } + + internal static bool RemoveTimedOutTmpFiles(DateTime timeoutDeadline, string filePath) + { + bool success = false; - if (filePath.EndsWith(".tmp", StringComparison.OrdinalIgnoreCase)) + if (filePath.EndsWith(".tmp", StringComparison.OrdinalIgnoreCase)) + { + DateTime fileDateTime = GetDateTimeFromBlobName(filePath); + if (fileDateTime < timeoutDeadline) { - DateTime fileDateTime = GetDateTimeFromBlobName(filePath); - if (fileDateTime < timeoutDeadline) + try { - try - { - File.Delete(filePath); - success = true; - PersistentStorageEventSource.Log.PersistentStorageInformation(nameof(PersistentStorageHelper), "File write exceeded timeout. Dropping telemetry"); - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.CouldNotRemoveTimedOutTmpFile(filePath, ex); - } + File.Delete(filePath); + success = true; + PersistentStorageEventSource.Log.PersistentStorageInformation(nameof(PersistentStorageHelper), "File write exceeded timeout. Dropping telemetry"); + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.CouldNotRemoveTimedOutTmpFile(filePath, ex); } } - - return success; } - internal static void RemoveExpiredBlobs(string directoryPath, long retentionPeriodInMilliseconds, long writeTimeoutInMilliseconds) - { - var currentUtcDateTime = DateTime.UtcNow; - - var leaseDeadline = currentUtcDateTime; - var retentionDeadline = currentUtcDateTime - TimeSpan.FromMilliseconds(retentionPeriodInMilliseconds); - var timeoutDeadline = currentUtcDateTime - TimeSpan.FromMilliseconds(writeTimeoutInMilliseconds); + return success; + } - foreach (var file in Directory.EnumerateFiles(directoryPath).OrderByDescending(filename => filename)) - { - var success = RemoveTimedOutTmpFiles(timeoutDeadline, file); + internal static void RemoveExpiredBlobs(string directoryPath, long retentionPeriodInMilliseconds, long writeTimeoutInMilliseconds) + { + var currentUtcDateTime = DateTime.UtcNow; - if (success) - { - continue; - } + var leaseDeadline = currentUtcDateTime; + var retentionDeadline = currentUtcDateTime - TimeSpan.FromMilliseconds(retentionPeriodInMilliseconds); + var timeoutDeadline = currentUtcDateTime - TimeSpan.FromMilliseconds(writeTimeoutInMilliseconds); - success = RemoveExpiredLease(leaseDeadline, file); + foreach (var file in Directory.EnumerateFiles(directoryPath).OrderByDescending(filename => filename)) + { + var success = RemoveTimedOutTmpFiles(timeoutDeadline, file); - if (!success) - { - RemoveExpiredBlob(retentionDeadline, file); - } + if (success) + { + continue; } - // It is faster to calculate the directory size, instead of removing length of expired files. - var size = CalculateFolderSize(directoryPath); - Interlocked.Exchange(ref directorySize, size); - } + success = RemoveExpiredLease(leaseDeadline, file); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static long GetDirectorySize() - { - return Interlocked.Read(ref directorySize); + if (!success) + { + RemoveExpiredBlob(retentionDeadline, file); + } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void WriteAllBytes(string path, byte[] buffer) - { - File.WriteAllBytes(path, buffer); - UpdateDirectorySize(buffer.Length); - } + // It is faster to calculate the directory size, instead of removing length of expired files. + var size = CalculateFolderSize(directoryPath); + Interlocked.Exchange(ref directorySize, size); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void RemoveFile(string fileName) - { - var fileInfo = new FileInfo(fileName); - var fileSize = fileInfo.Length; - fileInfo.Delete(); - UpdateDirectorySize(fileSize * -1); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static long GetDirectorySize() + { + return Interlocked.Read(ref directorySize); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static string GetUniqueFileName(string extension) - { - return string.Format(CultureInfo.InvariantCulture, $"{DateTime.UtcNow:yyyy-MM-ddTHHmmss.fffffffZ}-{Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)}{extension}"); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteAllBytes(string path, byte[] buffer) + { + File.WriteAllBytes(path, buffer); + UpdateDirectorySize(buffer.Length); + } - internal static string CreateSubdirectory(string path) - { - string subdirectoryPath = string.Empty; - string baseDirectory = string.Empty; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void RemoveFile(string fileName) + { + var fileInfo = new FileInfo(fileName); + var fileSize = fileInfo.Length; + fileInfo.Delete(); + UpdateDirectorySize(fileSize * -1); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static string GetUniqueFileName(string extension) + { + return string.Format(CultureInfo.InvariantCulture, $"{DateTime.UtcNow:yyyy-MM-ddTHHmmss.fffffffZ}-{Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture)}{extension}"); + } + + internal static string CreateSubdirectory(string path) + { + string subdirectoryPath = string.Empty; + string baseDirectory = string.Empty; #if !NETSTANDARD - baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + baseDirectory = AppDomain.CurrentDomain.BaseDirectory; #else - baseDirectory = AppContext.BaseDirectory; + baseDirectory = AppContext.BaseDirectory; #endif - string appIdentity = Environment.UserName + "@" + Path.Combine(baseDirectory, Process.GetCurrentProcess().ProcessName); - string subdirectoryName = GetSHA256Hash(appIdentity); - subdirectoryPath = Path.Combine(path, subdirectoryName); - Directory.CreateDirectory(subdirectoryPath); + string appIdentity = Environment.UserName + "@" + Path.Combine(baseDirectory, Process.GetCurrentProcess().ProcessName); + string subdirectoryName = GetSHA256Hash(appIdentity); + subdirectoryPath = Path.Combine(path, subdirectoryName); + Directory.CreateDirectory(subdirectoryPath); - directorySize = CalculateFolderSize(subdirectoryPath); - return subdirectoryPath; - } + directorySize = CalculateFolderSize(subdirectoryPath); + return subdirectoryPath; + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static long UpdateDirectorySize(long fileContentLength) - { - return Interlocked.Add(ref directorySize, fileContentLength); - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static long UpdateDirectorySize(long fileContentLength) + { + return Interlocked.Add(ref directorySize, fileContentLength); + } - internal static DateTime GetDateTimeFromBlobName(string filePath) - { - var fileName = Path.GetFileNameWithoutExtension(filePath); - var time = fileName.Substring(0, fileName.LastIndexOf('-')); + internal static DateTime GetDateTimeFromBlobName(string filePath) + { + var fileName = Path.GetFileNameWithoutExtension(filePath); + var time = fileName.Substring(0, fileName.LastIndexOf('-')); - // TODO:Handle possible parsing failure. - DateTime.TryParseExact(time, "yyyy-MM-ddTHHmmss.fffffffZ", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime); - return dateTime.ToUniversalTime(); - } + // TODO:Handle possible parsing failure. + DateTime.TryParseExact(time, "yyyy-MM-ddTHHmmss.fffffffZ", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime); + return dateTime.ToUniversalTime(); + } - internal static DateTime GetDateTimeFromLeaseName(string filePath) - { - var fileName = Path.GetFileNameWithoutExtension(filePath); - var startIndex = fileName.LastIndexOf('@') + 1; - var time = fileName.Substring(startIndex, fileName.Length - startIndex); - DateTime.TryParseExact(time, "yyyy-MM-ddTHHmmss.fffffffZ", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime); - return dateTime.ToUniversalTime(); - } + internal static DateTime GetDateTimeFromLeaseName(string filePath) + { + var fileName = Path.GetFileNameWithoutExtension(filePath); + var startIndex = fileName.LastIndexOf('@') + 1; + var time = fileName.Substring(startIndex, fileName.Length - startIndex); + DateTime.TryParseExact(time, "yyyy-MM-ddTHHmmss.fffffffZ", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime); + return dateTime.ToUniversalTime(); + } - internal static string GetSHA256Hash(string input) - { - var hashString = new StringBuilder(); + internal static string GetSHA256Hash(string input) + { + var hashString = new StringBuilder(); - byte[] inputBits = Encoding.Unicode.GetBytes(input); - using (var sha256 = SHA256.Create()) + byte[] inputBits = Encoding.Unicode.GetBytes(input); + using (var sha256 = SHA256.Create()) + { + byte[] hashBits = sha256.ComputeHash(inputBits); + foreach (byte b in hashBits) { - byte[] hashBits = sha256.ComputeHash(inputBits); - foreach (byte b in hashBits) - { - hashString.Append(b.ToString("x2", CultureInfo.InvariantCulture)); - } + hashString.Append(b.ToString("x2", CultureInfo.InvariantCulture)); } - - return hashString.ToString(); } - private static long CalculateFolderSize(string path) + return hashString.ToString(); + } + + private static long CalculateFolderSize(string path) + { + if (!Directory.Exists(path)) { - if (!Directory.Exists(path)) - { - return 0; - } + return 0; + } - long directorySize = 0; - try + long directorySize = 0; + try + { + foreach (string file in Directory.EnumerateFiles(path)) { - foreach (string file in Directory.EnumerateFiles(path)) - { - if (File.Exists(file)) - { - FileInfo fileInfo = new FileInfo(file); - directorySize += fileInfo.Length; - } - } - - foreach (string dir in Directory.GetDirectories(path)) + if (File.Exists(file)) { - directorySize += CalculateFolderSize(dir); + FileInfo fileInfo = new FileInfo(file); + directorySize += fileInfo.Length; } } - catch (Exception ex) + + foreach (string dir in Directory.GetDirectories(path)) { - PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), "Error calculating folder size", ex); + directorySize += CalculateFolderSize(dir); } - - return directorySize; } + catch (Exception ex) + { + PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), "Error calculating folder size", ex); + } + + return directorySize; } } diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs index 0330807f44..2e56912904 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs @@ -20,155 +20,154 @@ using System.Threading; using Xunit; -namespace OpenTelemetry.Extensions.PersistentStorage.Tests +namespace OpenTelemetry.Extensions.PersistentStorage.Tests; + +public class FileBlobProviderTests { - public class FileBlobProviderTests + [Fact] + public void FileBlobProvider_E2E_Test() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + using var blobProvider = new FileBlobProvider(testDirectory.FullName); + + var data = Encoding.UTF8.GetBytes("Hello, World!"); + + // Create blob. + Assert.True(blobProvider.TryCreateBlob(data, out var blob1)); + + // Get blob. + Assert.True(blobProvider.TryGetBlob(out var blob2)); + + Assert.Single(blobProvider.GetBlobs()); + + // Verify file name from both create blob and get blob are same. + Assert.Equal(((FileBlob)blob1).FullPath, ((FileBlob)blob2).FullPath); + + // Validate if content in the blob is same as buffer data passed to create blob. + Assert.True(blob1.TryRead(out var blobContent)); + Assert.Equal(data, blobContent); + + testDirectory.Delete(true); + } + + [Fact] + public void FileBlobProvider_CreateBlobReturnsNullIfblobProviderIsFull() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + using var blobProvider = new FileBlobProvider(testDirectory.FullName, 10000); + + PersistentStorageHelper.UpdateDirectorySize(10000); + + var data = Encoding.UTF8.GetBytes("Hello, World!"); + + Assert.False(blobProvider.TryCreateBlob(data, out var blob)); + Assert.Null(blob); + + testDirectory.Delete(true); + } + + [Fact] + public void FileBlobProvider_PathIsRequired() + { + Assert.Throws(() => new FileBlobProvider(null)); + } + + [Fact] + public void FileBlobProvider_TestRetentionPeriod() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + long maxSizeInBytes = 100000; + int maintenancePeriodInMilliseconds = 3000; + int retentionPeriodInMilliseconds = 2000; + int writeTimeOutInMilliseconds = 1000; + using var blobProvider = new FileBlobProvider( + testDirectory.FullName, + maxSizeInBytes, + maintenancePeriodInMilliseconds, + retentionPeriodInMilliseconds, + writeTimeOutInMilliseconds); + + var data = Encoding.UTF8.GetBytes("Hello, World!"); + Assert.True(blobProvider.TryCreateBlob(data, out var blob)); + + // Wait for maintenance job to run + // TODO: reduce/eliminate sleep time + Thread.Sleep(4000); + + // Blob will be deleted as retention period is 1 sec + Assert.False(File.Exists(((FileBlob)blob).FullPath)); + + testDirectory.Delete(true); + } + + [Fact] + public void FileBlobProvider_TestWriteTimeoutPeriod() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + long maxSizeInBytes = 100000; + int maintenancePeriodInMilliseconds = 3000; + int retentionPeriodInMilliseconds = 2000; + int writeTimeOutInMilliseconds = 1000; + using var blobProvider = new FileBlobProvider( + testDirectory.FullName, + maxSizeInBytes, + maintenancePeriodInMilliseconds, + retentionPeriodInMilliseconds, + writeTimeOutInMilliseconds); + + var data = Encoding.UTF8.GetBytes("Hello, World!"); + + Assert.True(blobProvider.TryCreateBlob(data, out var blob)); + + // Mock write + File.Move(((FileBlob)blob).FullPath, ((FileBlob)blob).FullPath + ".tmp"); + + // validate file moved successfully + Assert.True(File.Exists(((FileBlob)blob).FullPath + ".tmp")); + + // Wait for maintenance job to run + // TODO: reduce/eliminate sleep time + Thread.Sleep(4000); + + // tmp file will be deleted as write timeout period is 1 sec + Assert.False(File.Exists(((FileBlob)blob).FullPath + ".tmp")); + Assert.False(File.Exists(((FileBlob)blob).FullPath)); + + testDirectory.Delete(true); + } + + [Fact] + public void FileBlobProviderTests_TestLeaseExpiration() { - [Fact] - public void FileBlobProvider_E2E_Test() - { - var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - using var blobProvider = new FileBlobProvider(testDirectory.FullName); - - var data = Encoding.UTF8.GetBytes("Hello, World!"); - - // Create blob. - Assert.True(blobProvider.TryCreateBlob(data, out var blob1)); - - // Get blob. - Assert.True(blobProvider.TryGetBlob(out var blob2)); - - Assert.Single(blobProvider.GetBlobs()); - - // Verify file name from both create blob and get blob are same. - Assert.Equal(((FileBlob)blob1).FullPath, ((FileBlob)blob2).FullPath); - - // Validate if content in the blob is same as buffer data passed to create blob. - Assert.True(blob1.TryRead(out var blobContent)); - Assert.Equal(data, blobContent); - - testDirectory.Delete(true); - } - - [Fact] - public void FileBlobProvider_CreateBlobReturnsNullIfblobProviderIsFull() - { - var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - using var blobProvider = new FileBlobProvider(testDirectory.FullName, 10000); - - PersistentStorageHelper.UpdateDirectorySize(10000); - - var data = Encoding.UTF8.GetBytes("Hello, World!"); - - Assert.False(blobProvider.TryCreateBlob(data, out var blob)); - Assert.Null(blob); - - testDirectory.Delete(true); - } - - [Fact] - public void FileBlobProvider_PathIsRequired() - { - Assert.Throws(() => new FileBlobProvider(null)); - } - - [Fact] - public void FileBlobProvider_TestRetentionPeriod() - { - var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - long maxSizeInBytes = 100000; - int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 2000; - int writeTimeOutInMilliseconds = 1000; - using var blobProvider = new FileBlobProvider( - testDirectory.FullName, - maxSizeInBytes, - maintenancePeriodInMilliseconds, - retentionPeriodInMilliseconds, - writeTimeOutInMilliseconds); - - var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(blobProvider.TryCreateBlob(data, out var blob)); - - // Wait for maintenance job to run - // TODO: reduce/eliminate sleep time - Thread.Sleep(4000); - - // Blob will be deleted as retention period is 1 sec - Assert.False(File.Exists(((FileBlob)blob).FullPath)); - - testDirectory.Delete(true); - } - - [Fact] - public void FileBlobProvider_TestWriteTimeoutPeriod() - { - var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - long maxSizeInBytes = 100000; - int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 2000; - int writeTimeOutInMilliseconds = 1000; - using var blobProvider = new FileBlobProvider( - testDirectory.FullName, - maxSizeInBytes, - maintenancePeriodInMilliseconds, - retentionPeriodInMilliseconds, - writeTimeOutInMilliseconds); - - var data = Encoding.UTF8.GetBytes("Hello, World!"); - - Assert.True(blobProvider.TryCreateBlob(data, out var blob)); - - // Mock write - File.Move(((FileBlob)blob).FullPath, ((FileBlob)blob).FullPath + ".tmp"); - - // validate file moved successfully - Assert.True(File.Exists(((FileBlob)blob).FullPath + ".tmp")); - - // Wait for maintenance job to run - // TODO: reduce/eliminate sleep time - Thread.Sleep(4000); - - // tmp file will be deleted as write timeout period is 1 sec - Assert.False(File.Exists(((FileBlob)blob).FullPath + ".tmp")); - Assert.False(File.Exists(((FileBlob)blob).FullPath)); - - testDirectory.Delete(true); - } - - [Fact] - public void FileBlobProviderTests_TestLeaseExpiration() - { - var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - long maxSizeInBytes = 100000; - int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 2000; - int writeTimeOutInMilliseconds = 1000; - using var blobProvider = new FileBlobProvider( - testDirectory.FullName, - maxSizeInBytes, - maintenancePeriodInMilliseconds, - retentionPeriodInMilliseconds, - writeTimeOutInMilliseconds); - - var data = Encoding.UTF8.GetBytes("Hello, World!"); - - Assert.True(blobProvider.TryCreateBlob(data, out var blob)); - var blobPath = ((FileBlob)blob).FullPath; - - blob.TryLease(1000); - var leasePath = ((FileBlob)blob).FullPath; - Assert.True(File.Exists(leasePath)); - - // Wait for maintenance job to run - // TODO: reduce/eliminate sleep time - Thread.Sleep(4000); - - // File name will be change to .blob - Assert.True(File.Exists(blobPath)); - Assert.False(File.Exists(leasePath)); - - testDirectory.Delete(true); - } + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + long maxSizeInBytes = 100000; + int maintenancePeriodInMilliseconds = 3000; + int retentionPeriodInMilliseconds = 2000; + int writeTimeOutInMilliseconds = 1000; + using var blobProvider = new FileBlobProvider( + testDirectory.FullName, + maxSizeInBytes, + maintenancePeriodInMilliseconds, + retentionPeriodInMilliseconds, + writeTimeOutInMilliseconds); + + var data = Encoding.UTF8.GetBytes("Hello, World!"); + + Assert.True(blobProvider.TryCreateBlob(data, out var blob)); + var blobPath = ((FileBlob)blob).FullPath; + + blob.TryLease(1000); + var leasePath = ((FileBlob)blob).FullPath; + Assert.True(File.Exists(leasePath)); + + // Wait for maintenance job to run + // TODO: reduce/eliminate sleep time + Thread.Sleep(4000); + + // File name will be change to .blob + Assert.True(File.Exists(blobPath)); + Assert.False(File.Exists(leasePath)); + + testDirectory.Delete(true); } } diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs index 8880998195..3b752eab57 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs @@ -20,174 +20,173 @@ using OpenTelemetry.Extensions.PersistentStorage.Abstractions; using Xunit; -namespace OpenTelemetry.Extensions.PersistentStorage.Tests +namespace OpenTelemetry.Extensions.PersistentStorage.Tests; + +public class FileBlobTests { - public class FileBlobTests + [Fact] + public void FileBlobTests_E2E_Test() { - [Fact] - public void FileBlobTests_E2E_Test() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - PersistentBlob blob = new FileBlob(testFile.FullName); + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + PersistentBlob blob = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); - blob.TryWrite(data); - blob.TryRead(out var blobContent); + var data = Encoding.UTF8.GetBytes("Hello, World!"); + blob.TryWrite(data); + blob.TryRead(out var blobContent); - Assert.Equal(testFile.FullName, ((FileBlob)blob).FullPath); - Assert.Equal(data, blobContent); + Assert.Equal(testFile.FullName, ((FileBlob)blob).FullPath); + Assert.Equal(data, blobContent); - Assert.True(blob.TryDelete()); - Assert.False(testFile.Exists); - } + Assert.True(blob.TryDelete()); + Assert.False(testFile.Exists); + } - [Fact] - public void FileBlobTests_Lease() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - PersistentBlob blob = new FileBlob(testFile.FullName); + [Fact] + public void FileBlobTests_Lease() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + PersistentBlob blob = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); - var leasePeriodMilliseconds = 1000; - blob.TryWrite(data); - blob.TryLease(leasePeriodMilliseconds); + var data = Encoding.UTF8.GetBytes("Hello, World!"); + var leasePeriodMilliseconds = 1000; + blob.TryWrite(data); + blob.TryLease(leasePeriodMilliseconds); - Assert.Contains(".lock", ((FileBlob)blob).FullPath); + Assert.Contains(".lock", ((FileBlob)blob).FullPath); - Assert.True(blob.TryDelete()); - Assert.False(testFile.Exists); - } + Assert.True(blob.TryDelete()); + Assert.False(testFile.Exists); + } - [Fact] - public void FileBlobTests_LeaseAfterDelete() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - PersistentBlob blob = new FileBlob(testFile.FullName); + [Fact] + public void FileBlobTests_LeaseAfterDelete() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + PersistentBlob blob = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); + var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(blob.TryWrite(data)); - Assert.True(blob.TryDelete()); + Assert.True(blob.TryWrite(data)); + Assert.True(blob.TryDelete()); - // Lease should return false - Assert.False(blob.TryLease(1000)); - } + // Lease should return false + Assert.False(blob.TryLease(1000)); + } - [Fact] - public void FileBlobTests_ReadFailsOnAlreadyLeasedFile() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob1 = new FileBlob(testFile.FullName); - FileBlob blob2 = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); + [Fact] + public void FileBlobTests_ReadFailsOnAlreadyLeasedFile() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + FileBlob blob1 = new FileBlob(testFile.FullName); + FileBlob blob2 = new FileBlob(testFile.FullName); + var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(blob2.TryWrite(data)); + Assert.True(blob2.TryWrite(data)); - // Leased by another thread/process/object - Assert.True(blob2.TryLease(10000)); + // Leased by another thread/process/object + Assert.True(blob2.TryLease(10000)); - // Read should fail as file is leased - Assert.False(blob1.TryRead(out var blob)); - Assert.Null(blob); + // Read should fail as file is leased + Assert.False(blob1.TryRead(out var blob)); + Assert.Null(blob); - // Clean up - Assert.True(blob2.TryDelete()); - } + // Clean up + Assert.True(blob2.TryDelete()); + } - [Fact] - public void FileBlobTests_LeaseFailsOnAlreadyLeasedFileByOtherObject() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob1 = new FileBlob(testFile.FullName); - FileBlob blob2 = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); + [Fact] + public void FileBlobTests_LeaseFailsOnAlreadyLeasedFileByOtherObject() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + FileBlob blob1 = new FileBlob(testFile.FullName); + FileBlob blob2 = new FileBlob(testFile.FullName); + var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(blob1.TryWrite(data)); + Assert.True(blob1.TryWrite(data)); - // Leased by another thread/process/object - Assert.True(blob2.TryLease(10000)); + // Leased by another thread/process/object + Assert.True(blob2.TryLease(10000)); - // Lease should fail as already leased - Assert.False(blob1.TryLease(10)); + // Lease should fail as already leased + Assert.False(blob1.TryLease(10)); - // Clean up - Assert.True(blob2.TryDelete()); - } + // Clean up + Assert.True(blob2.TryDelete()); + } - [Fact] - public void FileBlobTests_Delete() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob = new FileBlob(testFile.FullName); + [Fact] + public void FileBlobTests_Delete() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + FileBlob blob = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); + var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(blob.TryWrite(data)); + Assert.True(blob.TryWrite(data)); - // Assert - Assert.True(blob.TryDelete()); - Assert.False(testFile.Exists); - } + // Assert + Assert.True(blob.TryDelete()); + Assert.False(testFile.Exists); + } - [Fact(Skip = "Unstable")] - public void FileBlobTests_DeleteFailsAfterLeaseIsExpired() - { - var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + [Fact(Skip = "Unstable")] + public void FileBlobTests_DeleteFailsAfterLeaseIsExpired() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - // set maintenance job interval to 2 secs - using var storage = new FileBlobProvider(testDirectory.FullName, 10, 2); + // set maintenance job interval to 2 secs + using var storage = new FileBlobProvider(testDirectory.FullName, 10, 2); - var data = Encoding.UTF8.GetBytes("Hello, World!"); + var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(storage.TryCreateBlob(data, out var blob)); + Assert.True(storage.TryCreateBlob(data, out var blob)); - var leasePeriodMilliseconds = 1; + var leasePeriodMilliseconds = 1; - // lease for 1 ms - blob.TryLease(leasePeriodMilliseconds); + // lease for 1 ms + blob.TryLease(leasePeriodMilliseconds); - // Wait for lease to expire and maintenance job to run - Thread.Sleep(5000); + // Wait for lease to expire and maintenance job to run + Thread.Sleep(5000); - blob.TryDelete(); + blob.TryDelete(); - // Assert - Assert.True(storage.TryGetBlob(out var outputBlob)); - Assert.NotNull(outputBlob); + // Assert + Assert.True(storage.TryGetBlob(out var outputBlob)); + Assert.NotNull(outputBlob); - testDirectory.Delete(true); - } + testDirectory.Delete(true); + } - [Fact(Skip = "Unstable")] - public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob = new FileBlob(testFile.FullName); - var data = Encoding.UTF8.GetBytes("Hello, World!"); + [Fact(Skip = "Unstable")] + public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + FileBlob blob = new FileBlob(testFile.FullName); + var data = Encoding.UTF8.GetBytes("Hello, World!"); - Assert.True(blob.TryWrite(data)); + Assert.True(blob.TryWrite(data)); - var leasePeriodMilliseconds = 10000; - Assert.True(blob.TryLease(leasePeriodMilliseconds)); + var leasePeriodMilliseconds = 10000; + Assert.True(blob.TryLease(leasePeriodMilliseconds)); - var leaseTime = PersistentStorageHelper.GetDateTimeFromLeaseName(blob.FullPath); + var leaseTime = PersistentStorageHelper.GetDateTimeFromLeaseName(blob.FullPath); - Assert.True(blob.TryLease(leasePeriodMilliseconds)); + Assert.True(blob.TryLease(leasePeriodMilliseconds)); - var newLeaseTime = PersistentStorageHelper.GetDateTimeFromLeaseName(blob.FullPath); + var newLeaseTime = PersistentStorageHelper.GetDateTimeFromLeaseName(blob.FullPath); - Assert.NotEqual(leaseTime, newLeaseTime); + Assert.NotEqual(leaseTime, newLeaseTime); - Assert.True(blob.TryDelete()); - } + Assert.True(blob.TryDelete()); + } - [Fact] - public void FileBlobTests_FailedWrite() - { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob = new FileBlob(testFile.FullName); + [Fact] + public void FileBlobTests_FailedWrite() + { + var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + FileBlob blob = new FileBlob(testFile.FullName); - Assert.False(blob.TryWrite(null)); - } + Assert.False(blob.TryWrite(null)); } } From a7ac68227779c5c0b17e6a70246c61f2529c9179 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 16 Aug 2022 22:17:11 +0200 Subject: [PATCH 0289/1499] [Instrumenation.Elasticsearch] File scoped namespace (#582) --- .../ElasticsearchClientInstrumentation.cs | 37 +- ...asticsearchClientInstrumentationOptions.cs | 63 +- ...ElasticsearchInstrumentationEventSource.cs | 47 +- ...searchRequestPipelineDiagnosticListener.cs | 385 +++-- .../TracerProviderBuilderExtensions.cs | 41 +- .../Customer.cs | 11 +- .../ElasticsearchClientTests.cs | 1257 ++++++++--------- ...nMemoryConnectionWithDownstreamActivity.cs | 21 +- 8 files changed, 927 insertions(+), 935 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs index 3756e327b7..42d4241f73 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs @@ -16,29 +16,28 @@ using System; using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; -namespace OpenTelemetry.Instrumentation.ElasticsearchClient +namespace OpenTelemetry.Instrumentation.ElasticsearchClient; + +/// +/// Elasticsearch client instrumentation. +/// +internal class ElasticsearchClientInstrumentation : IDisposable { + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + /// - /// Elasticsearch client instrumentation. + /// Initializes a new instance of the class. /// - internal class ElasticsearchClientInstrumentation : IDisposable + /// Configuration options for Elasticsearch client instrumentation. + public ElasticsearchClientInstrumentation(ElasticsearchClientInstrumentationOptions options) { - private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - - /// - /// Initializes a new instance of the class. - /// - /// Configuration options for Elasticsearch client instrumentation. - public ElasticsearchClientInstrumentation(ElasticsearchClientInstrumentationOptions options) - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new ElasticsearchRequestPipelineDiagnosticListener(options), null); - this.diagnosticSourceSubscriber.Subscribe(); - } + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new ElasticsearchRequestPipelineDiagnosticListener(options), null); + this.diagnosticSourceSubscriber.Subscribe(); + } - /// - public void Dispose() - { - this.diagnosticSourceSubscriber.Dispose(); - } + /// + public void Dispose() + { + this.diagnosticSourceSubscriber.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index d8cd284f8e..43d42bc6d0 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -17,43 +17,42 @@ using System; using System.Diagnostics; -namespace OpenTelemetry.Instrumentation.ElasticsearchClient +namespace OpenTelemetry.Instrumentation.ElasticsearchClient; + +/// +/// Options for Elasticsearch client instrumentation. +/// +public class ElasticsearchClientInstrumentationOptions { /// - /// Options for Elasticsearch client instrumentation. + /// Gets or sets a value indicating whether down stream instrumentation (HttpClient) is suppressed (disabled). /// - public class ElasticsearchClientInstrumentationOptions - { - /// - /// Gets or sets a value indicating whether down stream instrumentation (HttpClient) is suppressed (disabled). - /// - public bool SuppressDownstreamInstrumentation { get; set; } = true; + public bool SuppressDownstreamInstrumentation { get; set; } = true; - /// - /// Gets or sets a value indicating whether the JSON request body should be parsed out of the request debug information and formatted as indented JSON. - /// - public bool ParseAndFormatRequest { get; set; } = false; + /// + /// Gets or sets a value indicating whether the JSON request body should be parsed out of the request debug information and formatted as indented JSON. + /// + public bool ParseAndFormatRequest { get; set; } = false; - /// - /// Gets or sets a value indicating whether or not the OpenTelemetry.Instrumentation.ElasticsearchClient - /// should add the request information as db.statement attribute tag. Default value: True. - /// - public bool SetDbStatementForRequest { get; set; } = true; + /// + /// Gets or sets a value indicating whether or not the OpenTelemetry.Instrumentation.ElasticsearchClient + /// should add the request information as db.statement attribute tag. Default value: True. + /// + public bool SetDbStatementForRequest { get; set; } = true; - /// - /// Gets or sets a max length allowed for the db.statement attribute. Default value: 4096. - /// - public int MaxDbStatementLength { get; set; } = 4096; + /// + /// Gets or sets a max length allowed for the db.statement attribute. Default value: 4096. + /// + public int MaxDbStatementLength { get; set; } = 4096; - /// - /// Gets or sets an action to enrich an Activity. - /// - /// - /// : the activity being enriched. - /// string: the name of the event. - /// object: the raw object from which additional information can be extracted to enrich the activity. - /// The type of this object depends on the event, which is given by the above parameter. - /// - public Action Enrich { get; set; } - } + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// string: the name of the event. + /// object: the raw object from which additional information can be extracted to enrich the activity. + /// The type of this object depends on the event, which is given by the above parameter. + /// + public Action Enrich { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs index 8e75df41a4..ecbc51ad4a 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs @@ -18,35 +18,34 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-Elasticsearch")] +internal class ElasticsearchInstrumentationEventSource : EventSource { - /// - /// EventSource events emitted from the project. - /// - [EventSource(Name = "OpenTelemetry-Instrumentation-Elasticsearch")] - internal class ElasticsearchInstrumentationEventSource : EventSource - { - public static ElasticsearchInstrumentationEventSource Log = new ElasticsearchInstrumentationEventSource(); + public static ElasticsearchInstrumentationEventSource Log = new ElasticsearchInstrumentationEventSource(); - [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] - public void NullPayload(string handlerName, string eventName) - { - this.WriteEvent(1, handlerName, eventName); - } + [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(1, handlerName, eventName); + } - [NonEvent] - public void EnrichmentException(Exception ex) + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.EnrichmentException(ex.ToInvariantString()); - } + this.EnrichmentException(ex.ToInvariantString()); } + } - [Event(2, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] - public void EnrichmentException(string exception) - { - this.WriteEvent(2, exception); - } + [Event(2, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(2, exception); } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index da05a4468f..c2c8414ff2 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -26,267 +26,266 @@ using System.Text.RegularExpressions; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; + +internal class ElasticsearchRequestPipelineDiagnosticListener : ListenerHandler { - internal class ElasticsearchRequestPipelineDiagnosticListener : ListenerHandler + internal const string DatabaseSystemName = "elasticsearch"; + internal const string ExceptionCustomPropertyName = "OTel.Elasticsearch.Exception"; + internal const string AttributeDbMethod = "db.method"; + + internal static readonly AssemblyName AssemblyName = typeof(ElasticsearchRequestPipelineDiagnosticListener).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly Version Version = AssemblyName.Version; + internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + + private static readonly Regex ParseRequest = new Regex(@"\n# Request:\r?\n(\{.*)\n# Response", RegexOptions.Compiled | RegexOptions.Singleline); + private static readonly ConcurrentDictionary MethodNameCache = new ConcurrentDictionary(); + + private readonly ElasticsearchClientInstrumentationOptions options; + private readonly MultiTypePropertyFetcher uriFetcher = new MultiTypePropertyFetcher("Uri"); + private readonly MultiTypePropertyFetcher methodFetcher = new MultiTypePropertyFetcher("Method"); + private readonly MultiTypePropertyFetcher debugInformationFetcher = new MultiTypePropertyFetcher("DebugInformation"); + private readonly MultiTypePropertyFetcher httpStatusFetcher = new MultiTypePropertyFetcher("HttpStatusCode"); + private readonly MultiTypePropertyFetcher originalExceptionFetcher = new MultiTypePropertyFetcher("OriginalException"); + private readonly MultiTypePropertyFetcher failureReasonFetcher = new MultiTypePropertyFetcher("FailureReason"); + private readonly MultiTypePropertyFetcher responseBodyFetcher = new MultiTypePropertyFetcher("ResponseBodyInBytes"); + + public ElasticsearchRequestPipelineDiagnosticListener(ElasticsearchClientInstrumentationOptions options) + : base("Elasticsearch.Net.RequestPipeline") + { + this.options = options; + } + + public override void OnStartActivity(Activity activity, object payload) { - internal const string DatabaseSystemName = "elasticsearch"; - internal const string ExceptionCustomPropertyName = "OTel.Elasticsearch.Exception"; - internal const string AttributeDbMethod = "db.method"; - - internal static readonly AssemblyName AssemblyName = typeof(ElasticsearchRequestPipelineDiagnosticListener).Assembly.GetName(); - internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); - - private static readonly Regex ParseRequest = new Regex(@"\n# Request:\r?\n(\{.*)\n# Response", RegexOptions.Compiled | RegexOptions.Singleline); - private static readonly ConcurrentDictionary MethodNameCache = new ConcurrentDictionary(); - - private readonly ElasticsearchClientInstrumentationOptions options; - private readonly MultiTypePropertyFetcher uriFetcher = new MultiTypePropertyFetcher("Uri"); - private readonly MultiTypePropertyFetcher methodFetcher = new MultiTypePropertyFetcher("Method"); - private readonly MultiTypePropertyFetcher debugInformationFetcher = new MultiTypePropertyFetcher("DebugInformation"); - private readonly MultiTypePropertyFetcher httpStatusFetcher = new MultiTypePropertyFetcher("HttpStatusCode"); - private readonly MultiTypePropertyFetcher originalExceptionFetcher = new MultiTypePropertyFetcher("OriginalException"); - private readonly MultiTypePropertyFetcher failureReasonFetcher = new MultiTypePropertyFetcher("FailureReason"); - private readonly MultiTypePropertyFetcher responseBodyFetcher = new MultiTypePropertyFetcher("ResponseBodyInBytes"); - - public ElasticsearchRequestPipelineDiagnosticListener(ElasticsearchClientInstrumentationOptions options) - : base("Elasticsearch.Net.RequestPipeline") + // By this time, samplers have already run and + // activity.IsAllDataRequested populated accordingly. + + if (Sdk.SuppressInstrumentation) { - this.options = options; + return; } - public override void OnStartActivity(Activity activity, object payload) + if (activity.IsAllDataRequested) { - // By this time, samplers have already run and - // activity.IsAllDataRequested populated accordingly. + var uri = this.uriFetcher.Fetch(payload); - if (Sdk.SuppressInstrumentation) + if (uri == null) { + ElasticsearchInstrumentationEventSource.Log.NullPayload(nameof(ElasticsearchRequestPipelineDiagnosticListener), nameof(this.OnStartActivity)); return; } - if (activity.IsAllDataRequested) - { - var uri = this.uriFetcher.Fetch(payload); + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); - if (uri == null) - { - ElasticsearchInstrumentationEventSource.Log.NullPayload(nameof(ElasticsearchRequestPipelineDiagnosticListener), nameof(this.OnStartActivity)); - return; - } + var method = this.methodFetcher.Fetch(payload); - ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); - ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); + if (this.options.SuppressDownstreamInstrumentation) + { + SuppressInstrumentationScope.Enter(); + } - var method = this.methodFetcher.Fetch(payload); + var elasticIndex = this.GetElasticIndex(uri); + activity.DisplayName = this.GetDisplayName(activity, method, elasticIndex); + activity.SetTag(SemanticConventions.AttributeDbSystem, DatabaseSystemName); - if (this.options.SuppressDownstreamInstrumentation) - { - SuppressInstrumentationScope.Enter(); - } + if (elasticIndex != null) + { + activity.SetTag(SemanticConventions.AttributeDbName, elasticIndex); + } - var elasticIndex = this.GetElasticIndex(uri); - activity.DisplayName = this.GetDisplayName(activity, method, elasticIndex); - activity.SetTag(SemanticConventions.AttributeDbSystem, DatabaseSystemName); + var uriHostNameType = Uri.CheckHostName(uri.Host); + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + { + activity.SetTag(SemanticConventions.AttributeNetPeerIp, uri.Host); + } + else + { + activity.SetTag(SemanticConventions.AttributeNetPeerName, uri.Host); + } - if (elasticIndex != null) - { - activity.SetTag(SemanticConventions.AttributeDbName, elasticIndex); - } + if (uri.Port > 0) + { + activity.SetTag(SemanticConventions.AttributeNetPeerPort, uri.Port); + } - var uriHostNameType = Uri.CheckHostName(uri.Host); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - activity.SetTag(SemanticConventions.AttributeNetPeerIp, uri.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeNetPeerName, uri.Host); - } + if (method != null) + { + activity.SetTag(AttributeDbMethod, method.ToString()); + } - if (uri.Port > 0) - { - activity.SetTag(SemanticConventions.AttributeNetPeerPort, uri.Port); - } + activity.SetTag(SemanticConventions.AttributeDbUrl, uri.OriginalString); - if (method != null) - { - activity.SetTag(AttributeDbMethod, method.ToString()); - } + try + { + this.options.Enrich?.Invoke(activity, "OnStartActivity", payload); + } + catch (Exception ex) + { + ElasticsearchInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } - activity.SetTag(SemanticConventions.AttributeDbUrl, uri.OriginalString); + public override void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + var statusCode = this.httpStatusFetcher.Fetch(payload); + activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(statusCode.GetValueOrDefault())); - try - { - this.options.Enrich?.Invoke(activity, "OnStartActivity", payload); - } - catch (Exception ex) + if (statusCode.HasValue) + { + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, (int)statusCode); + } + + var debugInformation = this.debugInformationFetcher.Fetch(payload); + if (debugInformation != null && this.options.SetDbStatementForRequest) + { + var dbStatement = this.ParseAndFormatRequest(activity, debugInformation); + if (this.options.MaxDbStatementLength > 0 && dbStatement.Length > this.options.MaxDbStatementLength) { - ElasticsearchInstrumentationEventSource.Log.EnrichmentException(ex); + dbStatement = dbStatement.Substring(0, this.options.MaxDbStatementLength); } + + activity.SetTag(SemanticConventions.AttributeDbStatement, dbStatement); } - } - public override void OnStopActivity(Activity activity, object payload) - { - if (activity.IsAllDataRequested) + var originalException = this.originalExceptionFetcher.Fetch(payload); + if (originalException != null) { - var statusCode = this.httpStatusFetcher.Fetch(payload); - activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(statusCode.GetValueOrDefault())); + activity.SetCustomProperty(ExceptionCustomPropertyName, originalException); - if (statusCode.HasValue) + var failureReason = this.failureReasonFetcher.Fetch(originalException); + if (failureReason != null) { - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, (int)statusCode); + activity.SetStatus(Status.Error.WithDescription($"{failureReason} {originalException.Message}")); } - var debugInformation = this.debugInformationFetcher.Fetch(payload); - if (debugInformation != null && this.options.SetDbStatementForRequest) + var responseBody = this.responseBodyFetcher.Fetch(payload); + if (responseBody != null && responseBody.Length > 0) { - var dbStatement = this.ParseAndFormatRequest(activity, debugInformation); - if (this.options.MaxDbStatementLength > 0 && dbStatement.Length > this.options.MaxDbStatementLength) - { - dbStatement = dbStatement.Substring(0, this.options.MaxDbStatementLength); - } - - activity.SetTag(SemanticConventions.AttributeDbStatement, dbStatement); + var response = Encoding.UTF8.GetString(responseBody); + activity.SetStatus(Status.Error.WithDescription($"{failureReason} {originalException.Message}\r\n{response}")); } - var originalException = this.originalExceptionFetcher.Fetch(payload); - if (originalException != null) + if (originalException is HttpRequestException) { - activity.SetCustomProperty(ExceptionCustomPropertyName, originalException); - - var failureReason = this.failureReasonFetcher.Fetch(originalException); - if (failureReason != null) - { - activity.SetStatus(Status.Error.WithDescription($"{failureReason} {originalException.Message}")); - } - - var responseBody = this.responseBodyFetcher.Fetch(payload); - if (responseBody != null && responseBody.Length > 0) - { - var response = Encoding.UTF8.GetString(responseBody); - activity.SetStatus(Status.Error.WithDescription($"{failureReason} {originalException.Message}\r\n{response}")); - } - - if (originalException is HttpRequestException) + if (originalException.InnerException is SocketException exception) { - if (originalException.InnerException is SocketException exception) + switch (exception.SocketErrorCode) { - switch (exception.SocketErrorCode) - { - case SocketError.HostNotFound: - activity.SetStatus(Status.Error.WithDescription(originalException.Message)); - return; - } + case SocketError.HostNotFound: + activity.SetStatus(Status.Error.WithDescription(originalException.Message)); + return; } + } - if (originalException.InnerException != null) - { - activity.SetStatus(Status.Error.WithDescription(originalException.Message)); - } + if (originalException.InnerException != null) + { + activity.SetStatus(Status.Error.WithDescription(originalException.Message)); } } + } - try - { - this.options.Enrich?.Invoke(activity, "OnStopActivity", payload); - } - catch (Exception ex) - { - ElasticsearchInstrumentationEventSource.Log.EnrichmentException(ex); - } + try + { + this.options.Enrich?.Invoke(activity, "OnStopActivity", payload); + } + catch (Exception ex) + { + ElasticsearchInstrumentationEventSource.Log.EnrichmentException(ex); } } + } - private string GetDisplayName(Activity activity, object method, string elasticType = null) + private string GetDisplayName(Activity activity, object method, string elasticType = null) + { + switch (activity.OperationName) { - switch (activity.OperationName) - { - case "Ping": - return "Elasticsearch Ping"; - case "CallElasticsearch" when method != null: + case "Ping": + return "Elasticsearch Ping"; + case "CallElasticsearch" when method != null: + { + var methodName = MethodNameCache.GetOrAdd(method, $"Elasticsearch {method}"); + if (elasticType == null) { - var methodName = MethodNameCache.GetOrAdd(method, $"Elasticsearch {method}"); - if (elasticType == null) - { - return methodName; - } - - return $"{methodName} {elasticType}"; + return methodName; } - default: - return "Elasticsearch"; - } + return $"{methodName} {elasticType}"; + } + + default: + return "Elasticsearch"; } + } - private string GetElasticIndex(Uri uri) + private string GetElasticIndex(Uri uri) + { + // first segment is always / + if (uri.Segments.Length < 2) { - // first segment is always / - if (uri.Segments.Length < 2) - { - return null; - } + return null; + } - // operations starting with _ are not indices (_cat, _search, etc) - if (uri.Segments[1].StartsWith("_")) - { - return null; - } + // operations starting with _ are not indices (_cat, _search, etc) + if (uri.Segments[1].StartsWith("_")) + { + return null; + } - var elasticType = Uri.UnescapeDataString(uri.Segments[1]); + var elasticType = Uri.UnescapeDataString(uri.Segments[1]); - // multiple indices used, return null to avoid high cardinality - if (elasticType.Contains(',')) - { - return null; - } + // multiple indices used, return null to avoid high cardinality + if (elasticType.Contains(',')) + { + return null; + } - if (elasticType.EndsWith("/")) - { - elasticType = elasticType.Substring(0, elasticType.Length - 1); - } + if (elasticType.EndsWith("/")) + { + elasticType = elasticType.Substring(0, elasticType.Length - 1); + } - return elasticType; + return elasticType; + } + + private string ParseAndFormatRequest(Activity activity, string debugInformation) + { + if (!this.options.ParseAndFormatRequest) + { + return debugInformation; } - private string ParseAndFormatRequest(Activity activity, string debugInformation) + var request = ParseRequest.Match(debugInformation); + if (request.Success) { - if (!this.options.ParseAndFormatRequest) + string body = request.Groups[1]?.Value?.Trim(); + if (body == null) { return debugInformation; } - var request = ParseRequest.Match(debugInformation); - if (request.Success) + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(body)); + if (!JsonDocument.TryParseValue(ref reader, out var doc)) { - string body = request.Groups[1]?.Value?.Trim(); - if (body == null) - { - return debugInformation; - } - - var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(body)); - if (!JsonDocument.TryParseValue(ref reader, out var doc)) - { - return debugInformation; - } - - using (var stream = new MemoryStream()) - { - var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); - doc.WriteTo(writer); - writer.Flush(); - body = Encoding.UTF8.GetString(stream.ToArray()); - } + return debugInformation; + } - return body; + using (var stream = new MemoryStream()) + { + var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); + doc.WriteTo(writer); + writer.Flush(); + body = Encoding.UTF8.GetString(stream.ToArray()); } - return debugInformation; + return body; } + + return debugInformation; } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index c809fc9f67..6a14569a0b 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -19,33 +19,32 @@ using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables Elasticsearch client Instrumentation. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// Elasticsearch client configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddElasticsearchClientInstrumentation( + this TracerProviderBuilder builder, + Action configure = null) { - /// - /// Enables Elasticsearch client Instrumentation. - /// - /// being configured. - /// Elasticsearch client configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddElasticsearchClientInstrumentation( - this TracerProviderBuilder builder, - Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var elasticsearchClientOptions = new ElasticsearchClientInstrumentationOptions(); - configure?.Invoke(elasticsearchClientOptions); + var elasticsearchClientOptions = new ElasticsearchClientInstrumentationOptions(); + configure?.Invoke(elasticsearchClientOptions); - builder.AddInstrumentation(() => new ElasticsearchClientInstrumentation(elasticsearchClientOptions)); - builder.AddSource(ElasticsearchRequestPipelineDiagnosticListener.ActivitySourceName); - builder.AddLegacySource("CallElasticsearch"); + builder.AddInstrumentation(() => new ElasticsearchClientInstrumentation(elasticsearchClientOptions)); + builder.AddSource(ElasticsearchRequestPipelineDiagnosticListener.ActivitySourceName); + builder.AddLegacySource("CallElasticsearch"); - return builder; - } + return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs index 4ecc96d307..fa4ef971e2 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs @@ -14,12 +14,11 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; + +public class Customer { - public class Customer - { - public string Id { get; set; } + public string Id { get; set; } - public string Name { get; set; } - } + public string Name { get; set; } } diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 4968c09c0d..38e276e2a0 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -28,464 +28,464 @@ using Xunit; using Status = OpenTelemetry.Trace.Status; -namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; + +public class ElasticsearchClientTests { - public class ElasticsearchClientTests + public ElasticsearchClientTests() { - public ElasticsearchClientTests() - { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - } + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + } - [Fact] - public async Task CanCaptureGetById() + [Fact] + public async Task CanCaptureGetById() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); + + var parent = new Activity("parent").Start(); + + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var getResponse = await client.GetAsync("123"); + Assert.NotNull(getResponse); + Assert.True(getResponse.ApiCall.Success); + Assert.NotEmpty(getResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var getResponse = await client.GetAsync("123"); - Assert.NotNull(getResponse); - Assert.True(getResponse.ApiCall.Success); - Assert.NotEmpty(getResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Equal($"Elasticsearch GET customer", searchActivity.DisplayName); - var searchActivity = activities[0]; + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal($"Elasticsearch GET customer", searchActivity.DisplayName); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Successful (200) low level call", debugInfo); + [Fact] + public async Task CanCaptureGetByIdNotFound() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + var parent = new Activity("parent").Start(); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection(null, statusCode: 404)).DefaultIndex("customer")); - [Fact] - public async Task CanCaptureGetByIdNotFound() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var getResponse = await client.GetAsync("123"); + Assert.NotNull(getResponse); + Assert.True(getResponse.ApiCall.Success); + Assert.NotEmpty(getResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection(null, statusCode: 404)).DefaultIndex("customer")); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var getResponse = await client.GetAsync("123"); - Assert.NotNull(getResponse); - Assert.True(getResponse.ApiCall.Success); - Assert.NotEmpty(getResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Equal($"Elasticsearch GET customer", searchActivity.DisplayName); - var searchActivity = activities[0]; + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Successful (404) low level call", debugInfo); - Assert.Equal($"Elasticsearch GET customer", searchActivity.DisplayName); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Successful (404) low level call", debugInfo); + [Fact] + public async Task CanCaptureSearchCall() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + var parent = new Activity("parent").Start(); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - [Fact] - public async Task CanCaptureSearchCall() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); - - var parent = new Activity("parent").Start(); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + var searchActivity = activities[0]; - var searchActivity = activities[0]; + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); - Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Successful (200) low level call", debugInfo); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + [Fact] + public async Task CanRecordAndSampleSearchCall() + { + bool samplerCalled = false; - [Fact] - public async Task CanRecordAndSampleSearchCall() + var sampler = new TestSampler { - bool samplerCalled = false; - - var sampler = new TestSampler - { - SamplingAction = + SamplingAction = (samplingParameters) => { samplerCalled = true; return new SamplingResult(SamplingDecision.RecordAndSample); }, - }; + }; - using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); - int startCalled = 0; - int endCalled = 0; + int startCalled = 0; + int endCalled = 0; - testActivityProcessor.StartAction = - (a) => - { - Assert.True(samplerCalled); - Assert.False(Sdk.SuppressInstrumentation); - Assert.True(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true - startCalled++; - }; - - testActivityProcessor.EndAction = - (a) => - { - Assert.False(Sdk.SuppressInstrumentation); - Assert.True(a.IsAllDataRequested); // If Processor.OnEnd is called, activity's IsAllDataRequested is set to true - endCalled++; - }; - - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnectionWithDownstreamActivity()).DefaultIndex("customer").EnableDebugMode()); - - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(sampler) - .AddSource("Downstream") - .AddSource("NestedDownstream") - .AddElasticsearchClientInstrumentation((opt) => opt.SuppressDownstreamInstrumentation = false) - .AddProcessor(testActivityProcessor) - .Build()) + testActivityProcessor.StartAction = + (a) => { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + Assert.True(samplerCalled); + Assert.False(Sdk.SuppressInstrumentation); + Assert.True(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true + startCalled++; + }; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + testActivityProcessor.EndAction = + (a) => + { + Assert.False(Sdk.SuppressInstrumentation); + Assert.True(a.IsAllDataRequested); // If Processor.OnEnd is called, activity's IsAllDataRequested is set to true + endCalled++; + }; - Assert.Equal(3, startCalled); // Processor.OnStart is called since we added a legacy OperationName - Assert.Equal(3, endCalled); // Processor.OnEnd is called since we added a legacy OperationName - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnectionWithDownstreamActivity()).DefaultIndex("customer").EnableDebugMode()); - [Fact] - public async Task CanSupressDownstreamActivities() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(sampler) + .AddSource("Downstream") + .AddSource("NestedDownstream") + .AddElasticsearchClientInstrumentation((opt) => opt.SuppressDownstreamInstrumentation = false) + .AddProcessor(testActivityProcessor) + .Build()) { - bool samplerCalled = false; + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var sampler = new TestSampler - { - SamplingAction = + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } + + Assert.Equal(3, startCalled); // Processor.OnStart is called since we added a legacy OperationName + Assert.Equal(3, endCalled); // Processor.OnEnd is called since we added a legacy OperationName + } + + [Fact] + public async Task CanSupressDownstreamActivities() + { + bool samplerCalled = false; + + var sampler = new TestSampler + { + SamplingAction = (samplingParameters) => { samplerCalled = true; return new SamplingResult(SamplingDecision.RecordAndSample); }, - }; + }; - using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); - int startCalled = 0; - int endCalled = 0; + int startCalled = 0; + int endCalled = 0; - testActivityProcessor.StartAction = - (a) => - { - Assert.True(samplerCalled); - Assert.False(Sdk.SuppressInstrumentation); - Assert.True(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true - startCalled++; - }; - - testActivityProcessor.EndAction = - (a) => - { - Assert.False(Sdk.SuppressInstrumentation); - Assert.True(a.IsAllDataRequested); // If Processor.OnEnd is called, activity's IsAllDataRequested is set to true - endCalled++; - }; - - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnectionWithDownstreamActivity()).DefaultIndex("customer").EnableDebugMode()); - - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(sampler) - .AddSource("Downstream") - .AddSource("NestedDownstream") - .AddElasticsearchClientInstrumentation((opt) => opt.SuppressDownstreamInstrumentation = true) - .AddProcessor(testActivityProcessor) - .Build()) + testActivityProcessor.StartAction = + (a) => { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + Assert.True(samplerCalled); + Assert.False(Sdk.SuppressInstrumentation); + Assert.True(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true + startCalled++; + }; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + testActivityProcessor.EndAction = + (a) => + { + Assert.False(Sdk.SuppressInstrumentation); + Assert.True(a.IsAllDataRequested); // If Processor.OnEnd is called, activity's IsAllDataRequested is set to true + endCalled++; + }; - Assert.Equal(1, startCalled); // Processor.OnStart is called since we added a legacy OperationName - Assert.Equal(1, endCalled); // Processor.OnEnd is called since we added a legacy OperationName - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnectionWithDownstreamActivity()).DefaultIndex("customer").EnableDebugMode()); - [Fact] - public async Task CanDropSearchCall() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(sampler) + .AddSource("Downstream") + .AddSource("NestedDownstream") + .AddElasticsearchClientInstrumentation((opt) => opt.SuppressDownstreamInstrumentation = true) + .AddProcessor(testActivityProcessor) + .Build()) { - bool samplerCalled = false; + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var sampler = new TestSampler - { - SamplingAction = + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } + + Assert.Equal(1, startCalled); // Processor.OnStart is called since we added a legacy OperationName + Assert.Equal(1, endCalled); // Processor.OnEnd is called since we added a legacy OperationName + } + + [Fact] + public async Task CanDropSearchCall() + { + bool samplerCalled = false; + + var sampler = new TestSampler + { + SamplingAction = (samplingParameters) => { samplerCalled = true; return new SamplingResult(SamplingDecision.Drop); }, - }; + }; - using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); - int startCalled = 0; - int endCalled = 0; + int startCalled = 0; + int endCalled = 0; - testActivityProcessor.StartAction = - (a) => - { - Assert.True(samplerCalled); - Assert.False(Sdk.SuppressInstrumentation); - Assert.False(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true - startCalled++; - }; - - testActivityProcessor.EndAction = - (a) => - { - Assert.False(Sdk.SuppressInstrumentation); - Assert.False(a.IsAllDataRequested); // If Processor.OnEnd is called, activity's IsAllDataRequested is set to true - endCalled++; - }; - - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnectionWithDownstreamActivity()).DefaultIndex("customer").EnableDebugMode()); - - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(sampler) - .AddSource("Downstream") - .AddSource("NestedDownstream") - .AddElasticsearchClientInstrumentation((opt) => opt.SuppressDownstreamInstrumentation = false) - .AddProcessor(testActivityProcessor) - .Build()) + testActivityProcessor.StartAction = + (a) => { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + Assert.True(samplerCalled); + Assert.False(Sdk.SuppressInstrumentation); + Assert.False(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true + startCalled++; + }; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + testActivityProcessor.EndAction = + (a) => + { + Assert.False(Sdk.SuppressInstrumentation); + Assert.False(a.IsAllDataRequested); // If Processor.OnEnd is called, activity's IsAllDataRequested is set to true + endCalled++; + }; - Assert.Equal(0, startCalled); // Processor.OnStart is called since we added a legacy OperationName - Assert.Equal(0, endCalled); // Processor.OnEnd is called since we added a legacy OperationName - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnectionWithDownstreamActivity()).DefaultIndex("customer").EnableDebugMode()); - [Fact] - public async Task CanCaptureSearchCallWithDebugMode() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(sampler) + .AddSource("Downstream") + .AddSource("NestedDownstream") + .AddElasticsearchClientInstrumentation((opt) => opt.SuppressDownstreamInstrumentation = false) + .AddProcessor(testActivityProcessor) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer").EnableDebugMode()); + Assert.Equal(0, startCalled); // Processor.OnStart is called since we added a legacy OperationName + Assert.Equal(0, endCalled); // Processor.OnEnd is called since we added a legacy OperationName + } - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + [Fact] + public async Task CanCaptureSearchCallWithDebugMode() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + var parent = new Activity("parent").Start(); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer").EnableDebugMode()); - var searchActivity = activities[0]; + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) + { + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + var searchActivity = activities[0]; - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Successful (200) low level call", debugInfo); + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - [Fact] - public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() - { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Successful (200) low level call", debugInfo); - var parent = new Activity("parent").Start(); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer").EnableDebugMode()); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation(o => o.ParseAndFormatRequest = true) - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + [Fact] + public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + var parent = new Activity("parent").Start(); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer").EnableDebugMode()); - var searchActivity = activities[0]; + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation(o => o.ParseAndFormatRequest = true) + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) + { + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); + var searchActivity = activities[0]; - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Equal( - @"{ + Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); + + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Equal( + @"{ ""query"": { ""bool"": { ""must"": [ @@ -500,371 +500,370 @@ public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() } } }".Replace("\r\n", "\n"), - debugInfo.Replace("\r\n", "\n")); + debugInfo.Replace("\r\n", "\n")); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - [Fact] - public async Task CanCaptureSearchCallWithoutDebugMode() + [Fact] + public async Task CanCaptureSearchCallWithoutDebugMode() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); + + var parent = new Activity("parent").Start(); + + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation(o => o.ParseAndFormatRequest = true) + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation(o => o.ParseAndFormatRequest = true) - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); - var searchActivity = activities[0]; + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.DoesNotContain("123", debugInfo); - Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.DoesNotContain("123", debugInfo); + [Fact] + public async Task CanCaptureMultipleIndiceSearchCall() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + var parent = new Activity("parent").Start(); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer,order")); - [Fact] - public async Task CanCaptureMultipleIndiceSearchCall() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer,order")); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Equal($"Elasticsearch POST", searchActivity.DisplayName); - var searchActivity = activities[0]; + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal($"Elasticsearch POST", searchActivity.DisplayName); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Successful (200) low level call", debugInfo); + [Fact] + public async Task CanCaptureElasticsearchClientException() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + var parent = new Activity("parent").Start(); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var connection = new InMemoryConnection(Encoding.UTF8.GetBytes("{}"), statusCode: 500, exception: new ElasticsearchClientException("Boom")); + var client = new ElasticClient(new ConnectionSettings(connection).DefaultIndex("customer").EnableDebugMode()); - [Fact] - public async Task CanCaptureElasticsearchClientException() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.False(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.NotEmpty(failed); + } - var connection = new InMemoryConnection(Encoding.UTF8.GetBytes("{}"), statusCode: 500, exception: new ElasticsearchClientException("Boom")); - var client = new ElasticClient(new ConnectionSettings(connection).DefaultIndex("customer").EnableDebugMode()); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.False(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.NotEmpty(failed); - } + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); - var searchActivity = activities[0]; + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Unsuccessful (500) low level call", debugInfo); - Assert.Equal($"Elasticsearch POST customer", searchActivity.DisplayName); + var status = searchActivity.GetStatus(); + Assert.Equal(Status.Error.StatusCode, status.StatusCode); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal("customer", searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Unsuccessful (500) low level call", debugInfo); + [Fact] + public async Task CanCaptureCatRequest() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - var status = searchActivity.GetStatus(); - Assert.Equal(Status.Error.StatusCode, status.StatusCode); + var parent = new Activity("parent").Start(); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer").EnableDebugMode()); - [Fact] - public async Task CanCaptureCatRequest() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var getResponse = await client.Cat.IndicesAsync(); + Assert.NotNull(getResponse); + Assert.True(getResponse.ApiCall.Success); + Assert.NotEmpty(getResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer").EnableDebugMode()); + // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose + Assert.Equal(5, processor.Invocations.Count); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var getResponse = await client.Cat.IndicesAsync(); - Assert.NotNull(getResponse); - Assert.True(getResponse.ApiCall.Success); - Assert.NotEmpty(getResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); + Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); + Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); + Assert.NotEqual(default, searchActivity.Context.SpanId); - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Equal($"Elasticsearch GET", searchActivity.DisplayName); - var searchActivity = activities[0]; + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); - Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); - Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); - Assert.NotEqual(parent.SpanId, searchActivity.Context.SpanId); - Assert.NotEqual(default, searchActivity.Context.SpanId); + Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); + var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); + Assert.NotEmpty(debugInfo); + Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal($"Elasticsearch GET", searchActivity.DisplayName); + Assert.Equal(Status.Unset, searchActivity.GetStatus()); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Equal("localhost", searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - Assert.Equal(9200, searchActivity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + // Assert.Equal(expectedResource, searchActivity.GetResource()); + } - Assert.Equal("elasticsearch", searchActivity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbName)); - var debugInfo = (string)searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement); - Assert.NotEmpty(debugInfo); - Assert.Contains("Successful (200) low level call", debugInfo); + [Fact] + public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + var parent = new Activity("parent").Start(); - // Assert.Equal(expectedResource, searchActivity.GetResource()); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - [Fact] - public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + using var scope = SuppressInstrumentationScope.Begin(); + var getResponse = await client.GetAsync("123"); + Assert.NotNull(getResponse); + Assert.True(getResponse.ApiCall.Success); + Assert.NotEmpty(getResponse.ApiCall.AuditTrail); + + var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var parent = new Activity("parent").Start(); + // Since instrumentation is suppressed, activity is not emitted + Assert.Equal(3, processor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + // Processor.OnStart and Processor.OnEnd are not called + Assert.DoesNotContain(processor.Invocations, invo => invo.Method.Name == nameof(processor.Object.OnStart)); + Assert.DoesNotContain(processor.Invocations, invo => invo.Method.Name == nameof(processor.Object.OnEnd)); + } - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - using var scope = SuppressInstrumentationScope.Begin(); - var getResponse = await client.GetAsync("123"); - Assert.NotNull(getResponse); - Assert.True(getResponse.ApiCall.Success); - Assert.NotEmpty(getResponse.ApiCall.AuditTrail); - - var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + [Theory] + [InlineData(SamplingDecision.Drop, false)] + [InlineData(SamplingDecision.RecordOnly, true)] + [InlineData(SamplingDecision.RecordAndSample, true)] + public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecision, bool isActivityExpected) + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - // Since instrumentation is suppressed, activity is not emitted - Assert.Equal(3, processor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose + var parent = new Activity("parent").Start(); - // Processor.OnStart and Processor.OnEnd are not called - Assert.DoesNotContain(processor.Invocations, invo => invo.Method.Name == nameof(processor.Object.OnStart)); - Assert.DoesNotContain(processor.Invocations, invo => invo.Method.Name == nameof(processor.Object.OnEnd)); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - [Theory] - [InlineData(SamplingDecision.Drop, false)] - [InlineData(SamplingDecision.RecordOnly, true)] - [InlineData(SamplingDecision.RecordAndSample, true)] - public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecision, bool isActivityExpected) + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var getResponse = await client.GetAsync("123"); + Assert.NotNull(getResponse); + Assert.True(getResponse.ApiCall.Success); + Assert.NotEmpty(getResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnStart))); + Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnEnd))); + } - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var getResponse = await client.GetAsync("123"); - Assert.NotNull(getResponse); - Assert.True(getResponse.ApiCall.Success); - Assert.NotEmpty(getResponse.ApiCall.AuditTrail); + [Fact] + public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - var failed = getResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + var parent = new Activity("parent").Start(); - Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnStart))); - Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnEnd))); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - [Fact] - public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation(o => o.SetDbStatementForRequest = false) + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var parent = new Activity("parent").Start(); + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation(o => o.SetDbStatementForRequest = false) - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + var searchActivity = activities[0]; - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + [Fact] + public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDefaultValue() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var processor = new Mock>(); - var searchActivity = activities[0]; + var parent = new Activity("parent").Start(); - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } + var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - [Fact] - public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDefaultValue() + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation() + .SetResourceBuilder(expectedResource) + .AddProcessor(processor.Object) + .Build()) { - var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); - - var parent = new Activity("parent").Start(); - - var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); - - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddElasticsearchClientInstrumentation() - .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) - .Build()) - { - var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); - Assert.NotNull(searchResponse); - Assert.True(searchResponse.ApiCall.Success); - Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); - var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); - Assert.Empty(failed); - } + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.Single(activities); - var searchActivity = activities[0]; + var searchActivity = activities[0]; - var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); - Assert.NotNull(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } + var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + Assert.NotNull(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); } } diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs index b197b0ce3d..8e0b39ef99 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs @@ -19,19 +19,18 @@ using System.Threading.Tasks; using Elasticsearch.Net; -namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; + +public class InMemoryConnectionWithDownstreamActivity : InMemoryConnection { - public class InMemoryConnectionWithDownstreamActivity : InMemoryConnection - { - internal static readonly ActivitySource ActivitySource = new ActivitySource("Downstream"); - internal static readonly ActivitySource NestedActivitySource = new ActivitySource("NestedDownstream"); + internal static readonly ActivitySource ActivitySource = new ActivitySource("Downstream"); + internal static readonly ActivitySource NestedActivitySource = new ActivitySource("NestedDownstream"); - public override Task RequestAsync(RequestData requestData, CancellationToken cancellationToken) - { - using var a1 = ActivitySource.StartActivity("downstream"); - using var a2 = NestedActivitySource.StartActivity("nested-downstream"); + public override Task RequestAsync(RequestData requestData, CancellationToken cancellationToken) + { + using var a1 = ActivitySource.StartActivity("downstream"); + using var a2 = NestedActivitySource.StartActivity("nested-downstream"); - return base.RequestAsync(requestData, cancellationToken); - } + return base.RequestAsync(requestData, cancellationToken); } } From ba45b7f765a7d0a34a635c7bf1e91d566c98a4a8 Mon Sep 17 00:00:00 2001 From: Sami Musallam Date: Wed, 17 Aug 2022 00:42:12 +0300 Subject: [PATCH 0290/1499] [Instrumentation.AWSLambda] Updated AWSLambda ActivitySource Name (#534) --- .../CHANGELOG.md | 3 +++ .../Implementation/AWSLambdaUtils.cs | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md index 61ade2e4b0..ba2479e0a3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated the `ActivitySource` name to the assembly name: + `OpenTelemetry.Instrumentation.AWSLambda` + ([#534](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/534)) * Added public option `AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction`. * Extended public API of the `AWSLambdaWrapper`: added optional parent context (`ActivityContext`) to all `Trace` methods. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index f387ec69a5..9d84d9b78f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -30,7 +30,9 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation /// internal static class AWSLambdaUtils { - internal const string ActivitySourceName = "Amazon.AWS.AWSLambdaInstrumentation"; + internal static string ActivitySourceName = + typeof(AWSLambdaUtils).Assembly.GetName().Name.Replace(".Contrib", string.Empty); + private const string CloudProvider = "aws"; private const string AWSRegion = "AWS_REGION"; private const string AWSXRayLambdaTraceHeaderKey = "_X_AMZN_TRACE_ID"; From 2f535235834f06ac0aa13989c1fdfa6db68aa783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 17 Aug 2022 00:01:10 +0200 Subject: [PATCH 0291/1499] [Instrumenation.Runtime] File scoped namespace (#585) --- .../MeterProviderBuilderExtensions.cs | 39 +- .../RuntimeInstrumentationOptions.cs | 137 ++++--- .../RuntimeMetrics.cs | 351 +++++++++--------- .../RuntimeInstrumentationOptionsTests.cs | 175 +++++---- .../RuntimeMetricsTests.cs | 263 ++++++------- 5 files changed, 481 insertions(+), 484 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 9963243e7a..c6616295a1 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -18,31 +18,30 @@ using OpenTelemetry.Instrumentation.Runtime; using OpenTelemetry.Internal; -namespace OpenTelemetry.Metrics +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class MeterProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables runtime instrumentation. /// - public static class MeterProviderBuilderExtensions + /// being configured. + /// Runtime metrics options. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddRuntimeInstrumentation( + this MeterProviderBuilder builder, + Action configure = null) { - /// - /// Enables runtime instrumentation. - /// - /// being configured. - /// Runtime metrics options. - /// The instance of to chain the calls. - public static MeterProviderBuilder AddRuntimeInstrumentation( - this MeterProviderBuilder builder, - Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var options = new RuntimeInstrumentationOptions(); - configure?.Invoke(options); + var options = new RuntimeInstrumentationOptions(); + configure?.Invoke(options); - var instrumentation = new RuntimeMetrics(options); - builder.AddMeter(RuntimeMetrics.MeterInstance.Name); - return builder.AddInstrumentation(() => instrumentation); - } + var instrumentation = new RuntimeMetrics(options); + builder.AddMeter(RuntimeMetrics.MeterInstance.Name); + return builder.AddInstrumentation(() => instrumentation); } } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs index 3809444a4a..bb22d5243c 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs @@ -14,84 +14,83 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Runtime +namespace OpenTelemetry.Instrumentation.Runtime; + +/// +/// Options to define the runtime metrics. +/// +public class RuntimeInstrumentationOptions { - /// - /// Options to define the runtime metrics. - /// - public class RuntimeInstrumentationOptions - { - /* - /// - /// Gets or sets a value indicating whether garbage collection metrics should be collected. - /// - public bool? GcEnabled { get; set; } + /* + /// + /// Gets or sets a value indicating whether garbage collection metrics should be collected. + /// + public bool? GcEnabled { get; set; } - #if NET6_0_OR_GREATER - /// - /// Gets or sets a value indicating whether jitter metrics should be collected. - /// - public bool? JitEnabled { get; set; } - #endif + #if NET6_0_OR_GREATER + /// + /// Gets or sets a value indicating whether jitter metrics should be collected. + /// + public bool? JitEnabled { get; set; } + #endif - #if NETCOREAPP3_1_OR_GREATER - /// - /// Gets or sets a value indicating whether threading metrics should be collected. - /// - public bool? ThreadingEnabled { get; set; } - #endif + #if NETCOREAPP3_1_OR_GREATER + /// + /// Gets or sets a value indicating whether threading metrics should be collected. + /// + public bool? ThreadingEnabled { get; set; } + #endif - /// - /// Gets or sets a value indicating whether assembly metrics should be collected. - /// - public bool? AssembliesEnabled { get; set; } + /// + /// Gets or sets a value indicating whether assembly metrics should be collected. + /// + public bool? AssembliesEnabled { get; set; } - /// - /// Gets or sets a value indicating whether exception count metrics should be collected. - /// - public bool? ExceptionCountEnabled { get; set; } + /// + /// Gets or sets a value indicating whether exception count metrics should be collected. + /// + public bool? ExceptionCountEnabled { get; set; } - /// - /// Gets a value indicating whether all metrics are enabled. - /// - internal bool IsAllEnabled => this.GcEnabled == null - #if NET6_0_OR_GREATER - && this.JitEnabled == null - #endif - #if NETCOREAPP3_1_OR_GREATER - && this.ThreadingEnabled == null - #endif - && this.AssembliesEnabled == null - && this.ExceptionCountEnabled == null; + /// + /// Gets a value indicating whether all metrics are enabled. + /// + internal bool IsAllEnabled => this.GcEnabled == null + #if NET6_0_OR_GREATER + && this.JitEnabled == null + #endif + #if NETCOREAPP3_1_OR_GREATER + && this.ThreadingEnabled == null + #endif + && this.AssembliesEnabled == null + && this.ExceptionCountEnabled == null; - /// - /// Gets a value indicating whether garbage collection metrics is enabled. - /// - internal bool IsGcEnabled => this.GcEnabled == true || this.IsAllEnabled; + /// + /// Gets a value indicating whether garbage collection metrics is enabled. + /// + internal bool IsGcEnabled => this.GcEnabled == true || this.IsAllEnabled; - #if NET6_0_OR_GREATER - /// - /// Gets a value indicating whether jitter metrics is enabled. - /// - internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; - #endif + #if NET6_0_OR_GREATER + /// + /// Gets a value indicating whether jitter metrics is enabled. + /// + internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; + #endif - #if NETCOREAPP3_1_OR_GREATER - /// - /// Gets a value indicating whether threading metrics is enabled. - /// - internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; - #endif + #if NETCOREAPP3_1_OR_GREATER + /// + /// Gets a value indicating whether threading metrics is enabled. + /// + internal bool IsThreadingEnabled => this.ThreadingEnabled == true || this.IsAllEnabled; + #endif - /// - /// Gets a value indicating whether assembly metrics is enabled. - /// - internal bool IsAssembliesEnabled => this.AssembliesEnabled == true || this.IsAllEnabled; + /// + /// Gets a value indicating whether assembly metrics is enabled. + /// + internal bool IsAssembliesEnabled => this.AssembliesEnabled == true || this.IsAllEnabled; - /// - /// Gets a value indicating whether exception count metrics is enabled. - /// - internal bool IsExceptionCountEnabled => this.ExceptionCountEnabled == true || this.IsAllEnabled; - */ - } + /// + /// Gets a value indicating whether exception count metrics is enabled. + /// + internal bool IsExceptionCountEnabled => this.ExceptionCountEnabled == true || this.IsAllEnabled; + */ } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index e0d24e7151..26057cec91 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -26,44 +26,74 @@ using JitInfo = System.Runtime.JitInfo; #endif -namespace OpenTelemetry.Instrumentation.Runtime +namespace OpenTelemetry.Instrumentation.Runtime; + +/// +/// .NET runtime instrumentation. +/// +internal class RuntimeMetrics { - /// - /// .NET runtime instrumentation. - /// - internal class RuntimeMetrics - { - internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); - internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); + internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); + internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); #if NET6_0_OR_GREATER - private const long NanosecondsPerTick = 100; + private const long NanosecondsPerTick = 100; #endif - private const int NumberOfGenerations = 3; - private const string MetricPrefix = "process.runtime.dotnet."; + private const int NumberOfGenerations = 3; + private const string MetricPrefix = "process.runtime.dotnet."; - private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; - private static bool isGcInfoAvailable; + private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; + private static bool isGcInfoAvailable; - static RuntimeMetrics() - { - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}gc.collections.count", - () => GetGarbageCollectionCounts(), - description: "Number of garbage collections that have occurred since process start."); + static RuntimeMetrics() + { + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}gc.collections.count", + () => GetGarbageCollectionCounts(), + description: "Number of garbage collections that have occurred since process start."); #if NETCOREAPP3_1_OR_GREATER - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}gc.allocations.size", - () => GC.GetTotalAllocatedBytes(), - unit: "bytes", - description: "Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}gc.allocations.size", + () => GC.GetTotalAllocatedBytes(), + unit: "bytes", + description: "Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); #endif #if NET6_0_OR_GREATER + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{MetricPrefix}gc.committed_memory.size", + () => + { + if (!IsGcInfoAvailable) + { + return Array.Empty>(); + } + + return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; + }, + unit: "bytes", + description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); + + // GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 + Func getGenerationSize = null; + bool isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; + if (isCodeRunningOnBuggyRuntimeVersion) + { + MethodInfo mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); + if (mi != null) + { + getGenerationSize = mi.CreateDelegate>(); + } + } + + // Either Environment.Version is not 6 or (it's 6 but internal API GC.GetGenerationSize is valid) + if (!isCodeRunningOnBuggyRuntimeVersion || getGenerationSize != null) + { // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}gc.committed_memory.size", + $"{MetricPrefix}gc.heap.size", () => { if (!IsGcInfoAvailable) @@ -71,188 +101,157 @@ static RuntimeMetrics() return Array.Empty>(); } - return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; - }, - unit: "bytes", - description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); - - // GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 - Func getGenerationSize = null; - bool isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; - if (isCodeRunningOnBuggyRuntimeVersion) - { - MethodInfo mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); - if (mi != null) - { - getGenerationSize = mi.CreateDelegate>(); - } - } - - // Either Environment.Version is not 6 or (it's 6 but internal API GC.GetGenerationSize is valid) - if (!isCodeRunningOnBuggyRuntimeVersion || getGenerationSize != null) - { - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{MetricPrefix}gc.heap.size", - () => + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) { - if (!IsGcInfoAvailable) + if (isCodeRunningOnBuggyRuntimeVersion) { - return Array.Empty>(); + measurements[i] = new((long)getGenerationSize(i), new KeyValuePair("generation", GenNames[i])); } - - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) + else { - if (isCodeRunningOnBuggyRuntimeVersion) - { - measurements[i] = new((long)getGenerationSize(i), new KeyValuePair("generation", GenNames[i])); - } - else - { - measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); - } + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); } + } - return measurements; - }, - unit: "bytes", - description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); - } + return measurements; + }, + unit: "bytes", + description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + } - // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 - if (Environment.Version.Major >= 7) - { - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{MetricPrefix}gc.heap.fragmentation.size", - () => + // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 + if (Environment.Version.Major >= 7) + { + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{MetricPrefix}gc.heap.fragmentation.size", + () => + { + if (!IsGcInfoAvailable) { - if (!IsGcInfoAvailable) - { - return Array.Empty>(); - } + return Array.Empty>(); + } - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) - { - measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); - } + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + Measurement[] measurements = new Measurement[generationInfo.Length]; + int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (int i = 0; i < maxSupportedLength; ++i) + { + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); + } - return measurements; - }, - unit: "bytes", - description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); - } + return measurements; + }, + unit: "bytes", + description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + } #endif #if NET6_0_OR_GREATER - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}jit.il_compiled.size", - () => JitInfo.GetCompiledILBytes(), - unit: "bytes", - description: "Count of bytes of intermediate language that have been compiled since the process start."); - - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}jit.methods_compiled.count", - () => JitInfo.GetCompiledMethodCount(), - description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings."); - - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}jit.compilation_time", - () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, - unit: "ns", - description: "The amount of time the JIT compiler has spent compiling methods since the process start."); + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}jit.il_compiled.size", + () => JitInfo.GetCompiledILBytes(), + unit: "bytes", + description: "Count of bytes of intermediate language that have been compiled since the process start."); + + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}jit.methods_compiled.count", + () => JitInfo.GetCompiledMethodCount(), + description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings."); + + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}jit.compilation_time", + () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, + unit: "ns", + description: "The amount of time the JIT compiler has spent compiling methods since the process start."); #endif #if NETCOREAPP3_1_OR_GREATER - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}monitor.lock_contention.count", - () => Monitor.LockContentionCount, - description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()."); - - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{MetricPrefix}thread_pool.threads.count", - () => (long)ThreadPool.ThreadCount, - description: "The number of thread pool threads that currently exist."); - - MeterInstance.CreateObservableCounter( - $"{MetricPrefix}thread_pool.completed_items.count", - () => ThreadPool.CompletedWorkItemCount, - description: "The number of work items that have been processed by the thread pool since the process start."); - - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{MetricPrefix}thread_pool.queue.length", - () => ThreadPool.PendingWorkItemCount, - description: "The number of work items that are currently queued to be processed by the thread pool."); - - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{MetricPrefix}timer.count", - () => Timer.ActiveCount, - description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}monitor.lock_contention.count", + () => Monitor.LockContentionCount, + description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{MetricPrefix}thread_pool.threads.count", + () => (long)ThreadPool.ThreadCount, + description: "The number of thread pool threads that currently exist."); + + MeterInstance.CreateObservableCounter( + $"{MetricPrefix}thread_pool.completed_items.count", + () => ThreadPool.CompletedWorkItemCount, + description: "The number of work items that have been processed by the thread pool since the process start."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{MetricPrefix}thread_pool.queue.length", + () => ThreadPool.PendingWorkItemCount, + description: "The number of work items that are currently queued to be processed by the thread pool."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{MetricPrefix}timer.count", + () => Timer.ActiveCount, + description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); #endif - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( - $"{MetricPrefix}assemblies.count", - () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, - description: "The number of .NET assemblies that are currently loaded."); - - var exceptionCounter = MeterInstance.CreateCounter( - $"{MetricPrefix}exceptions.count", - description: "Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization."); + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + $"{MetricPrefix}assemblies.count", + () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, + description: "The number of .NET assemblies that are currently loaded."); - AppDomain.CurrentDomain.FirstChanceException += (source, e) => - { - exceptionCounter.Add(1); - }; - } + var exceptionCounter = MeterInstance.CreateCounter( + $"{MetricPrefix}exceptions.count", + description: "Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization."); - /// - /// Initializes a new instance of the class. - /// - /// The options to define the metrics. - public RuntimeMetrics(RuntimeInstrumentationOptions options) + AppDomain.CurrentDomain.FirstChanceException += (source, e) => { - } + exceptionCounter.Add(1); + }; + } - private static bool IsGcInfoAvailable + /// + /// Initializes a new instance of the class. + /// + /// The options to define the metrics. + public RuntimeMetrics(RuntimeInstrumentationOptions options) + { + } + + private static bool IsGcInfoAvailable + { + get { - get + if (isGcInfoAvailable) { - if (isGcInfoAvailable) - { - return true; - } - - if (GC.CollectionCount(0) > 0) - { - isGcInfoAvailable = true; - } + return true; + } - return isGcInfoAvailable; + if (GC.CollectionCount(0) > 0) + { + isGcInfoAvailable = true; } + + return isGcInfoAvailable; } + } - private static IEnumerable> GetGarbageCollectionCounts() - { - long collectionsFromHigherGeneration = 0; + private static IEnumerable> GetGarbageCollectionCounts() + { + long collectionsFromHigherGeneration = 0; - for (int gen = NumberOfGenerations - 1; gen >= 0; --gen) - { - long collectionsFromThisGeneration = GC.CollectionCount(gen); + for (int gen = NumberOfGenerations - 1; gen >= 0; --gen) + { + long collectionsFromThisGeneration = GC.CollectionCount(gen); - yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("generation", GenNames[gen])); + yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("generation", GenNames[gen])); - collectionsFromHigherGeneration = collectionsFromThisGeneration; - } + collectionsFromHigherGeneration = collectionsFromThisGeneration; } } } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs index d419f0c921..bd133de24e 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs @@ -14,104 +14,103 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.Runtime.Tests +namespace OpenTelemetry.Instrumentation.Runtime.Tests; + +public class RuntimeInstrumentationOptionsTests { - public class RuntimeInstrumentationOptionsTests - { - /* - [Fact] - public void Enable_All_If_Nothing_Was_Defined() - { - var options = new RuntimeInstrumentationOptions(); + /* + [Fact] + public void Enable_All_If_Nothing_Was_Defined() + { + var options = new RuntimeInstrumentationOptions(); - Assert.True(options.IsGcEnabled); - #if NET6_0_OR_GREATER - Assert.True(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER - Assert.True(options.IsThreadingEnabled); - #endif - Assert.True(options.IsAssembliesEnabled); - Assert.True(options.IsAllEnabled); - } + Assert.True(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.True(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.True(options.IsThreadingEnabled); + #endif + Assert.True(options.IsAssembliesEnabled); + Assert.True(options.IsAllEnabled); + } - [Fact] - public void Enable_Gc_Only() - { - var options = new RuntimeInstrumentationOptions { GcEnabled = true }; + [Fact] + public void Enable_Gc_Only() + { + var options = new RuntimeInstrumentationOptions { GcEnabled = true }; - Assert.True(options.IsGcEnabled); - #if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); - #endif - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } + Assert.True(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); + #endif + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } - #if NET6_0_OR_GREATER - [Fact] - public void Enable_Jit_Only() - { - var options = new RuntimeInstrumentationOptions { JitEnabled = true }; + #if NET6_0_OR_GREATER + [Fact] + public void Enable_Jit_Only() + { + var options = new RuntimeInstrumentationOptions { JitEnabled = true }; - Assert.False(options.IsGcEnabled); - Assert.True(options.IsJitEnabled); - Assert.False(options.IsThreadingEnabled); - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } - #endif + Assert.False(options.IsGcEnabled); + Assert.True(options.IsJitEnabled); + Assert.False(options.IsThreadingEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + #endif - #if NETCOREAPP3_1_OR_GREATER - [Fact] - public void Enable_Threading_Only() - { - var options = new RuntimeInstrumentationOptions { ThreadingEnabled = true }; + #if NETCOREAPP3_1_OR_GREATER + [Fact] + public void Enable_Threading_Only() + { + var options = new RuntimeInstrumentationOptions { ThreadingEnabled = true }; - Assert.False(options.IsGcEnabled); - #if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); - #endif - Assert.True(options.IsThreadingEnabled); - Assert.False(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } - #endif + Assert.False(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + Assert.True(options.IsThreadingEnabled); + Assert.False(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + #endif - [Fact] - public void Enable_Assemblies_Only() - { - var options = new RuntimeInstrumentationOptions { AssembliesEnabled = true }; + [Fact] + public void Enable_Assemblies_Only() + { + var options = new RuntimeInstrumentationOptions { AssembliesEnabled = true }; - Assert.False(options.IsGcEnabled); - #if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); - #endif - Assert.True(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } + Assert.False(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); + #endif + Assert.True(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } - [Fact] - public void Enable_Multiple() - { - var options = new RuntimeInstrumentationOptions { GcEnabled = true, AssembliesEnabled = true }; + [Fact] + public void Enable_Multiple() + { + var options = new RuntimeInstrumentationOptions { GcEnabled = true, AssembliesEnabled = true }; - Assert.True(options.IsGcEnabled); - #if NET6_0_OR_GREATER - Assert.False(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER - Assert.False(options.IsThreadingEnabled); - #endif - Assert.True(options.IsAssembliesEnabled); - Assert.False(options.IsAllEnabled); - } - */ - } + Assert.True(options.IsGcEnabled); + #if NET6_0_OR_GREATER + Assert.False(options.IsJitEnabled); + #endif + #if NETCOREAPP3_1_OR_GREATER + Assert.False(options.IsThreadingEnabled); + #endif + Assert.True(options.IsAssembliesEnabled); + Assert.False(options.IsAllEnabled); + } + */ } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 8b5ed3ab4a..750568c534 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -17,187 +17,188 @@ using System; using System.Collections.Generic; using System.Linq; +#if NETCOREAPP3_1_OR_GREATER using System.Threading; using System.Threading.Tasks; +#endif using OpenTelemetry.Metrics; using Xunit; -namespace OpenTelemetry.Instrumentation.Runtime.Tests +namespace OpenTelemetry.Instrumentation.Runtime.Tests; + +public class RuntimeMetricsTests { - public class RuntimeMetricsTests - { - private const int MaxTimeToAllowForFlush = 10000; - private const string MetricPrefix = "process.runtime.dotnet."; + private const int MaxTimeToAllowForFlush = 10000; + private const string MetricPrefix = "process.runtime.dotnet."; - [Fact] - public void RuntimeMetricsAreCaptured() + [Fact] + public void RuntimeMetricsAreCaptured() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + // The process.runtime.dotnet.exception.count metrics are only available after an exception has been thrown post OpenTelemetry.Instrumentation.Runtime initialization. + try { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); - - // The process.runtime.dotnet.exception.count metrics are only available after an exception has been thrown post OpenTelemetry.Instrumentation.Runtime initialization. - try - { - throw new Exception("Oops!"); - } - catch (Exception) - { - // swallow the exception - } + throw new Exception("Oops!"); + } + catch (Exception) + { + // swallow the exception + } - meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count > 1); - Assert.StartsWith(MetricPrefix, exportedItems[0].Name); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + Assert.True(exportedItems.Count > 1); + Assert.StartsWith(MetricPrefix, exportedItems[0].Name); - var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); - Assert.NotNull(assembliesCountMetric); + var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); + Assert.NotNull(assembliesCountMetric); - var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.exceptions.count"); - Assert.True(GetValue(exceptionsCountMetric) >= 1); - } + var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.exceptions.count"); + Assert.True(GetValue(exceptionsCountMetric) >= 1); + } - [Fact] - public void GcMetricsTest() - { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); + [Fact] + public void GcMetricsTest() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); - GC.Collect(1); + GC.Collect(1); - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); - Assert.NotNull(gcCountMetric); + var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); + Assert.NotNull(gcCountMetric); #if NETCOREAPP3_1_OR_GREATER - var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); - Assert.NotNull(gcAllocationSizeMetric); + var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); + Assert.NotNull(gcAllocationSizeMetric); #endif #if NET6_0_OR_GREATER - var gcCommittedMemorySizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); - Assert.NotNull(gcCommittedMemorySizeMetric); + var gcCommittedMemorySizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); + Assert.NotNull(gcCommittedMemorySizeMetric); - var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); - Assert.NotNull(gcHeapSizeMetric); + var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); + Assert.NotNull(gcHeapSizeMetric); - if (Environment.Version.Major >= 7) - { - var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); - Assert.NotNull(gcHeapFragmentationSizeMetric); - } -#endif + if (Environment.Version.Major >= 7) + { + var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); + Assert.NotNull(gcHeapFragmentationSizeMetric); } +#endif + } #if NET6_0_OR_GREATER - [Fact] - public void JitRelatedMetricsTest() - { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); + [Fact] + public void JitRelatedMetricsTest() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var jitCompiledSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); - Assert.NotNull(jitCompiledSizeMetric); + var jitCompiledSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); + Assert.NotNull(jitCompiledSizeMetric); - var jitMethodsCompiledCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.methods_compiled.count"); - Assert.NotNull(jitMethodsCompiledCountMetric); + var jitMethodsCompiledCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.methods_compiled.count"); + Assert.NotNull(jitMethodsCompiledCountMetric); - var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); - Assert.NotNull(jitCompilationTimeMetric); - } + var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); + Assert.NotNull(jitCompilationTimeMetric); + } #endif #if NETCOREAPP3_1_OR_GREATER - [Fact] - public void ThreadingRelatedMetricsTest() + [Fact] + public void ThreadingRelatedMetricsTest() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddRuntimeInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + // Bump the count for `thread_pool.completed_items.count` metric + int taskCount = 50; + List tasks = new List(); + for (int i = 0; i < taskCount; i++) { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddRuntimeInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); - - // Bump the count for `thread_pool.completed_items.count` metric - int taskCount = 50; - List tasks = new List(); - for (int i = 0; i < taskCount; i++) - { - tasks.Add(Task.Run(() => { Console.Write("Hi"); })); - } + tasks.Add(Task.Run(() => { Console.Write("Hi"); })); + } - Task.WaitAll(tasks.ToArray()); + Task.WaitAll(tasks.ToArray()); - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + meterProvider.ForceFlush(MaxTimeToAllowForFlush); - var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); - Assert.NotNull(lockContentionCountMetric); + var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); + Assert.NotNull(lockContentionCountMetric); - var threadCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); - Assert.NotNull(threadCountMetric); + var threadCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.threads.count"); + Assert.NotNull(threadCountMetric); - var completedItemsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); - Assert.True(GetValue(completedItemsCountMetric) >= taskCount); + var completedItemsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); + Assert.True(GetValue(completedItemsCountMetric) >= taskCount); - var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); - Assert.NotNull(queueLengthMetric); + var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); + Assert.NotNull(queueLengthMetric); - List timers = new List(); - try + List timers = new List(); + try + { + // Create 10 timers to bump timer.count metrics. + int timerCount = 10; + TimerCallback timerCallback = _ => { }; + for (int i = 0; i < timerCount; i++) { - // Create 10 timers to bump timer.count metrics. - int timerCount = 10; - TimerCallback timerCallback = _ => { }; - for (int i = 0; i < timerCount; i++) - { - Timer timer = new Timer(timerCallback, null, 1000, 250); - timers.Add(timer); - } - - meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - var timerCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.timer.count"); - Assert.True(GetValue(timerCountMetric) >= timerCount); + Timer timer = new Timer(timerCallback, null, 1000, 250); + timers.Add(timer); } - finally + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var timerCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.timer.count"); + Assert.True(GetValue(timerCountMetric) >= timerCount); + } + finally + { + for (int i = 0; i < timers.Count; i++) { - for (int i = 0; i < timers.Count; i++) - { - timers[i].Dispose(); - } + timers[i].Dispose(); } } + } #endif - private static double GetValue(Metric metric) - { - Assert.NotNull(metric); - double sum = 0; + private static double GetValue(Metric metric) + { + Assert.NotNull(metric); + double sum = 0; - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsSum()) { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumLong(); - } - else - { - sum += metricPoint.GetGaugeLastValueLong(); - break; - } + sum += metricPoint.GetSumLong(); + } + else + { + sum += metricPoint.GetGaugeLastValueLong(); + break; } - - return sum; } + + return sum; } } From 2cc804439fa021d4737defb852cdc018746b5e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 17 Aug 2022 23:55:48 +0200 Subject: [PATCH 0292/1499] [Exporter.Stackdriver] File scoped namespace (#589) --- .../Implementation/ActivityExtensions.cs | 213 +++++----- .../Implementation/Constants.cs | 63 ++- .../ExporterStackdriverEventSource.cs | 105 +++-- .../GoogleCloudResourceUtils.cs | 83 ++-- .../StackdriverStatsConfiguration.cs | 85 ++-- .../StackdriverTraceExporter.cs | 177 +++++---- .../TracerProviderBuilderExtensions.cs | 33 +- .../Utils/CommonUtils.cs | 41 +- .../StackdriverStatsConfigurationTests.cs | 73 ++-- .../StackdriverExporterTests.cs | 373 +++++++++--------- .../TestActivityProcessor.cs | 79 ++-- 11 files changed, 657 insertions(+), 668 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 5fbb64670a..aef78c1e37 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -21,137 +21,136 @@ using Google.Protobuf.WellKnownTypes; using OpenTelemetry.Trace; -namespace OpenTelemetry.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +internal static class ActivityExtensions { - internal static class ActivityExtensions + private static Dictionary labelsToReplace = new Dictionary + { + { "component", "/component" }, + { "http.method", "/http/method" }, + { "http.host", "/http/host" }, + { "http.status_code", "/http/status_code" }, + { "http.user_agent", "/http/user_agent" }, + { "http.target", "/http/target" }, + { "http.url", "/http/url" }, + { "http.route", "/http/route" }, + }; + + /// + /// Translating to Stackdriver's Span + /// According to specifications. + /// + /// Activity in OpenTelemetry format. + /// Google Cloud Platform Project Id. + /// . + public static Span ToSpan(this Activity activity, string projectId) { - private static Dictionary labelsToReplace = new Dictionary + var spanId = activity.Context.SpanId.ToHexString(); + + // Base span settings + var span = new Span { - { "component", "/component" }, - { "http.method", "/http/method" }, - { "http.host", "/http/host" }, - { "http.status_code", "/http/status_code" }, - { "http.user_agent", "/http/user_agent" }, - { "http.target", "/http/target" }, - { "http.url", "/http/url" }, - { "http.route", "/http/route" }, + SpanName = new SpanName(projectId, activity.Context.TraceId.ToHexString(), spanId), + SpanId = spanId, + DisplayName = new TruncatableString { Value = activity.DisplayName }, + StartTime = activity.StartTimeUtc.ToTimestamp(), + EndTime = activity.StartTimeUtc.Add(activity.Duration).ToTimestamp(), + ChildSpanCount = null, }; - - /// - /// Translating to Stackdriver's Span - /// According to specifications. - /// - /// Activity in OpenTelemetry format. - /// Google Cloud Platform Project Id. - /// . - public static Span ToSpan(this Activity activity, string projectId) + if (activity.ParentSpanId != null) { - var spanId = activity.Context.SpanId.ToHexString(); - - // Base span settings - var span = new Span + var parentSpanId = activity.ParentSpanId.ToHexString(); + if (!string.IsNullOrEmpty(parentSpanId)) { - SpanName = new SpanName(projectId, activity.Context.TraceId.ToHexString(), spanId), - SpanId = spanId, - DisplayName = new TruncatableString { Value = activity.DisplayName }, - StartTime = activity.StartTimeUtc.ToTimestamp(), - EndTime = activity.StartTimeUtc.Add(activity.Duration).ToTimestamp(), - ChildSpanCount = null, - }; - if (activity.ParentSpanId != null) - { - var parentSpanId = activity.ParentSpanId.ToHexString(); - if (!string.IsNullOrEmpty(parentSpanId)) - { - span.ParentSpanId = parentSpanId; - } + span.ParentSpanId = parentSpanId; } + } - // Span Links - if (activity.Links != null) + // Span Links + if (activity.Links != null) + { + span.Links = new Span.Types.Links { - span.Links = new Span.Types.Links - { - Link = { activity.Links.Select(l => l.ToLink()) }, - }; - } + Link = { activity.Links.Select(l => l.ToLink()) }, + }; + } - // Span Attributes - if (activity.Tags != null) + // Span Attributes + if (activity.Tags != null) + { + span.Attributes = new Span.Types.Attributes { - span.Attributes = new Span.Types.Attributes + AttributeMap = { - AttributeMap = - { - activity.Tags?.ToDictionary( - s => s.Key, - s => s.Value?.ToAttributeValue()), - }, - }; - } + activity.Tags?.ToDictionary( + s => s.Key, + s => s.Value?.ToAttributeValue()), + }, + }; + } - // StackDriver uses different labels that are used to categorize spans - // replace attribute keys with StackDriver version - foreach (var entry in labelsToReplace) + // StackDriver uses different labels that are used to categorize spans + // replace attribute keys with StackDriver version + foreach (var entry in labelsToReplace) + { + if (span.Attributes.AttributeMap.TryGetValue(entry.Key, out var attrValue)) { - if (span.Attributes.AttributeMap.TryGetValue(entry.Key, out var attrValue)) - { - span.Attributes.AttributeMap.Remove(entry.Key); - span.Attributes.AttributeMap.Add(entry.Value, attrValue); - } + span.Attributes.AttributeMap.Remove(entry.Key); + span.Attributes.AttributeMap.Add(entry.Value, attrValue); } - - return span; } - public static Span.Types.Link ToLink(this ActivityLink link) + return span; + } + + public static Span.Types.Link ToLink(this ActivityLink link) + { + var ret = new Span.Types.Link { - var ret = new Span.Types.Link - { - SpanId = link.Context.SpanId.ToHexString(), - TraceId = link.Context.TraceId.ToHexString(), - }; + SpanId = link.Context.SpanId.ToHexString(), + TraceId = link.Context.TraceId.ToHexString(), + }; - if (link.Tags != null) + if (link.Tags != null) + { + ret.Attributes = new Span.Types.Attributes { - ret.Attributes = new Span.Types.Attributes + AttributeMap = { - AttributeMap = - { - link.Tags.ToDictionary( - att => att.Key, - att => att.Value.ToAttributeValue()), - }, - }; - } - - return ret; + link.Tags.ToDictionary( + att => att.Key, + att => att.Value.ToAttributeValue()), + }, + }; } - public static AttributeValue ToAttributeValue(this object av) + return ret; + } + + public static AttributeValue ToAttributeValue(this object av) + { + switch (av) { - switch (av) - { - case string s: - return new AttributeValue() - { - StringValue = new TruncatableString() { Value = s }, - }; - case bool b: - return new AttributeValue() { BoolValue = b }; - case long l: - return new AttributeValue() { IntValue = l }; - case double d: - return new AttributeValue() - { - StringValue = new TruncatableString() { Value = d.ToString() }, - }; - default: - return new AttributeValue() - { - StringValue = new TruncatableString() { Value = av.ToString() }, - }; - } + case string s: + return new AttributeValue() + { + StringValue = new TruncatableString() { Value = s }, + }; + case bool b: + return new AttributeValue() { BoolValue = b }; + case long l: + return new AttributeValue() { IntValue = l }; + case double d: + return new AttributeValue() + { + StringValue = new TruncatableString() { Value = d.ToString() }, + }; + default: + return new AttributeValue() + { + StringValue = new TruncatableString() { Value = av.ToString() }, + }; } } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs index 4259b34ade..9f20621d53 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs @@ -16,39 +16,38 @@ using System; -namespace OpenTelemetry.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +internal class Constants { - internal class Constants + public static readonly string PackagVersionUndefined = "undefined"; + + public static readonly string LabelDescription = "OpenTelemetry string"; + public static readonly string OpenTelemetryTask = "OpenTelemetry_task"; + public static readonly string OpenTelemetryTaskDescription = "OpenTelemetry task identifier"; + + public static readonly string GcpGkeContainer = "k8s_container"; + public static readonly string GcpGceInstance = "gce_instance"; + public static readonly string AwsEc2Instance = "aws_ec2_instance"; + public static readonly string Global = "global"; + + public static readonly string ProjectIdLabelKey = "project_id"; + public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue(); + + public static readonly string GceGcpInstanceType = "cloud.google.com/gce/instance"; + public static readonly string GcpInstanceIdKey = "cloud.google.com/gce/instance_id"; + public static readonly string GcpAccountIdKey = "cloud.google.com/gce/project_id"; + public static readonly string GcpZoneKey = "cloud.google.com/gce/zone"; + + public static readonly string K8sContainerType = "k8s.io/container"; + public static readonly string K8sClusterNameKey = "k8s.io/cluster/name"; + public static readonly string K8sContainerNameKey = "k8s.io/container/name"; + public static readonly string K8sNamespaceNameKey = "k8s.io/namespace/name"; + public static readonly string K8sPodNameKey = "k8s.io/pod/name"; + + private static string GenerateDefaultTaskValue() { - public static readonly string PackagVersionUndefined = "undefined"; - - public static readonly string LabelDescription = "OpenTelemetry string"; - public static readonly string OpenTelemetryTask = "OpenTelemetry_task"; - public static readonly string OpenTelemetryTaskDescription = "OpenTelemetry task identifier"; - - public static readonly string GcpGkeContainer = "k8s_container"; - public static readonly string GcpGceInstance = "gce_instance"; - public static readonly string AwsEc2Instance = "aws_ec2_instance"; - public static readonly string Global = "global"; - - public static readonly string ProjectIdLabelKey = "project_id"; - public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue(); - - public static readonly string GceGcpInstanceType = "cloud.google.com/gce/instance"; - public static readonly string GcpInstanceIdKey = "cloud.google.com/gce/instance_id"; - public static readonly string GcpAccountIdKey = "cloud.google.com/gce/project_id"; - public static readonly string GcpZoneKey = "cloud.google.com/gce/zone"; - - public static readonly string K8sContainerType = "k8s.io/container"; - public static readonly string K8sClusterNameKey = "k8s.io/cluster/name"; - public static readonly string K8sContainerNameKey = "k8s.io/container/name"; - public static readonly string K8sNamespaceNameKey = "k8s.io/namespace/name"; - public static readonly string K8sPodNameKey = "k8s.io/pod/name"; - - private static string GenerateDefaultTaskValue() - { - // Something like '@' - return $"dotnet-{System.Diagnostics.Process.GetCurrentProcess().Id}@{Environment.MachineName}"; - } + // Something like '@' + return $"dotnet-{System.Diagnostics.Process.GetCurrentProcess().Id}@{Environment.MachineName}"; } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs index 70d68a3d99..c6c55009ec 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs @@ -19,75 +19,74 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +[EventSource(Name = "OpenTelemetry-Exporter-Stackdriver")] +internal class ExporterStackdriverEventSource : EventSource { - [EventSource(Name = "OpenTelemetry-Exporter-Stackdriver")] - internal class ExporterStackdriverEventSource : EventSource - { - public static readonly ExporterStackdriverEventSource Log = new ExporterStackdriverEventSource(); + public static readonly ExporterStackdriverEventSource Log = new ExporterStackdriverEventSource(); - [NonEvent] - public void UnknownProblemInWorkerThreadError(Exception ex) + [NonEvent] + public void UnknownProblemInWorkerThreadError(Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.UnknownProblemInWorkerThreadError(ToInvariantString(ex)); - } + this.UnknownProblemInWorkerThreadError(ToInvariantString(ex)); } + } - [Event(1, Message = "Stackdriver exporter encountered an unknown error and will shut down. Exception: {0}", Level = EventLevel.Error)] - public void UnknownProblemInWorkerThreadError(string ex) - { - this.WriteEvent(1, ex); - } + [Event(1, Message = "Stackdriver exporter encountered an unknown error and will shut down. Exception: {0}", Level = EventLevel.Error)] + public void UnknownProblemInWorkerThreadError(string ex) + { + this.WriteEvent(1, ex); + } - [NonEvent] - public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(Exception ex) + [NonEvent] + public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.UnknownProblemWhileCreatingStackdriverTimeSeriesError(ToInvariantString(ex)); - } + this.UnknownProblemWhileCreatingStackdriverTimeSeriesError(ToInvariantString(ex)); } + } - [Event(2, Message = "Stackdriver exporter failed to create time series. Time series will be lost. Exception: {0}", Level = EventLevel.Error)] - public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(string ex) - { - this.WriteEvent(2, ex); - } + [Event(2, Message = "Stackdriver exporter failed to create time series. Time series will be lost. Exception: {0}", Level = EventLevel.Error)] + public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(string ex) + { + this.WriteEvent(2, ex); + } - [NonEvent] - public void ExportMethodException(Exception ex) + [NonEvent] + public void ExportMethodException(Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.ExportMethodException(ToInvariantString(ex)); - } + this.ExportMethodException(ToInvariantString(ex)); } + } - [Event(3, Message = "Stackdriver exporter encountered an error while exporting. Exception: {0}", Level = EventLevel.Error)] - public void ExportMethodException(string ex) + [Event(3, Message = "Stackdriver exporter encountered an error while exporting. Exception: {0}", Level = EventLevel.Error)] + public void ExportMethodException(string ex) + { + this.WriteEvent(1, ex); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try { - this.WriteEvent(1, ex); + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs index 864afffaac..8f924ccf0e 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs @@ -18,58 +18,57 @@ using System.IO; using Google.Api; -namespace OpenTelemetry.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +/// +/// Utility methods for working with Google Cloud Resources. +/// +public static class GoogleCloudResourceUtils { /// - /// Utility methods for working with Google Cloud Resources. + /// Detects Google Cloud ProjectId based on the environment on which the code runs. + /// Supports GCE/GKE/GAE and projectId tied to service account + /// In case the code runs in a different environment, + /// the method returns null. /// - public static class GoogleCloudResourceUtils + /// Google Cloud Project ID. + public static string GetProjectId() { - /// - /// Detects Google Cloud ProjectId based on the environment on which the code runs. - /// Supports GCE/GKE/GAE and projectId tied to service account - /// In case the code runs in a different environment, - /// the method returns null. - /// - /// Google Cloud Project ID. - public static string GetProjectId() + // Try to detect projectId from the environment where the code is running + var instance = Google.Api.Gax.Platform.Instance(); + var projectId = instance?.ProjectId; + if (!string.IsNullOrEmpty(projectId)) { - // Try to detect projectId from the environment where the code is running - var instance = Google.Api.Gax.Platform.Instance(); - var projectId = instance?.ProjectId; - if (!string.IsNullOrEmpty(projectId)) - { - return projectId; - } - - // Try to detect projectId from service account credential if it exists - var serviceAccountFilePath = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); - if (!string.IsNullOrEmpty(serviceAccountFilePath) && File.Exists(serviceAccountFilePath)) - { - using var stream = new FileStream(serviceAccountFilePath, FileMode.Open, FileAccess.Read); - var credential = Google.Apis.Auth.OAuth2.ServiceAccountCredential.FromServiceAccountData(stream); - return credential.ProjectId; - } - - projectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID"); return projectId; } - /// - /// Determining the resource to which the metrics belong. - /// - /// The project id. - /// Stackdriver Monitored Resource. - public static MonitoredResource GetDefaultResource(string projectId) + // Try to detect projectId from service account credential if it exists + var serviceAccountFilePath = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); + if (!string.IsNullOrEmpty(serviceAccountFilePath) && File.Exists(serviceAccountFilePath)) { - var resource = new MonitoredResource(); - resource.Type = Constants.Global; - resource.Labels.Add(Constants.ProjectIdLabelKey, projectId); + using var stream = new FileStream(serviceAccountFilePath, FileMode.Open, FileAccess.Read); + var credential = Google.Apis.Auth.OAuth2.ServiceAccountCredential.FromServiceAccountData(stream); + return credential.ProjectId; + } - // TODO - zeltser - setting monitored resource labels for detected resource - // along with all the other metadata + projectId = Environment.GetEnvironmentVariable("GOOGLE_PROJECT_ID"); + return projectId; + } - return resource; - } + /// + /// Determining the resource to which the metrics belong. + /// + /// The project id. + /// Stackdriver Monitored Resource. + public static MonitoredResource GetDefaultResource(string projectId) + { + var resource = new MonitoredResource(); + resource.Type = Constants.Global; + resource.Labels.Add(Constants.ProjectIdLabelKey, projectId); + + // TODO - zeltser - setting monitored resource labels for detected resource + // along with all the other metadata + + return resource; } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs index c424d84c81..2ebe727993 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs @@ -18,60 +18,59 @@ using Google.Api; using Google.Apis.Auth.OAuth2; -namespace OpenTelemetry.Exporter.Stackdriver.Implementation +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +/// +/// Configuration for exporting stats into Stackdriver. +/// +public class StackdriverStatsConfiguration { + private static readonly TimeSpan DefaultInterval = TimeSpan.FromMinutes(1); + /// - /// Configuration for exporting stats into Stackdriver. + /// Gets default Stats Configuration for Stackdriver. /// - public class StackdriverStatsConfiguration + public static StackdriverStatsConfiguration Default { - private static readonly TimeSpan DefaultInterval = TimeSpan.FromMinutes(1); - - /// - /// Gets default Stats Configuration for Stackdriver. - /// - public static StackdriverStatsConfiguration Default + get { - get + var defaultConfig = new StackdriverStatsConfiguration { - var defaultConfig = new StackdriverStatsConfiguration - { - ExportInterval = DefaultInterval, - ProjectId = GoogleCloudResourceUtils.GetProjectId(), - MetricNamePrefix = string.Empty, - }; + ExportInterval = DefaultInterval, + ProjectId = GoogleCloudResourceUtils.GetProjectId(), + MetricNamePrefix = string.Empty, + }; - defaultConfig.MonitoredResource = GoogleCloudResourceUtils.GetDefaultResource(defaultConfig.ProjectId); - return defaultConfig; - } + defaultConfig.MonitoredResource = GoogleCloudResourceUtils.GetDefaultResource(defaultConfig.ProjectId); + return defaultConfig; } + } - /// - /// Gets or sets frequency of the export operation. - /// - public TimeSpan ExportInterval { get; set; } + /// + /// Gets or sets frequency of the export operation. + /// + public TimeSpan ExportInterval { get; set; } - /// - /// Gets or sets the prefix to append to every OpenTelemetry metric name in Stackdriver. - /// - public string MetricNamePrefix { get; set; } + /// + /// Gets or sets the prefix to append to every OpenTelemetry metric name in Stackdriver. + /// + public string MetricNamePrefix { get; set; } - /// - /// Gets or sets google Cloud Project Id. - /// - public string ProjectId { get; set; } + /// + /// Gets or sets google Cloud Project Id. + /// + public string ProjectId { get; set; } - /// - /// Gets or sets credential used to authenticate against Google Stackdriver Monitoring APIs. - /// - public GoogleCredential GoogleCredential { get; set; } + /// + /// Gets or sets credential used to authenticate against Google Stackdriver Monitoring APIs. + /// + public GoogleCredential GoogleCredential { get; set; } - /// - /// Gets or sets monitored Resource associated with metrics collection. - /// By default, the exporter detects the environment where the export is happening, - /// such as GKE/AWS/GCE. If the exporter is running on a different environment, - /// monitored resource will be identified as "general". - /// - public MonitoredResource MonitoredResource { get; set; } - } + /// + /// Gets or sets monitored Resource associated with metrics collection. + /// By default, the exporter detects the environment where the export is happening, + /// such as GKE/AWS/GCE. If the exporter is running on a different environment, + /// monitored resource will be identified as "general". + /// + public MonitoredResource MonitoredResource { get; set; } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 65e6587f3d..69df0cfd40 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -23,115 +23,114 @@ using Grpc.Core; using OpenTelemetry.Exporter.Stackdriver.Implementation; -namespace OpenTelemetry.Exporter.Stackdriver +namespace OpenTelemetry.Exporter.Stackdriver; + +/// +/// Exports a group of spans to Stackdriver. +/// +public class StackdriverTraceExporter : BaseExporter { - /// - /// Exports a group of spans to Stackdriver. - /// - public class StackdriverTraceExporter : BaseExporter - { - private static readonly string StackdriverExportVersion; - private static readonly string OpenTelemetryExporterVersion; + private static readonly string StackdriverExportVersion; + private static readonly string OpenTelemetryExporterVersion; - private readonly Google.Api.Gax.ResourceNames.ProjectName googleCloudProjectId; - private readonly TraceServiceSettings traceServiceSettings; - private readonly TraceServiceClient traceServiceClient; + private readonly Google.Api.Gax.ResourceNames.ProjectName googleCloudProjectId; + private readonly TraceServiceSettings traceServiceSettings; + private readonly TraceServiceClient traceServiceClient; - static StackdriverTraceExporter() + static StackdriverTraceExporter() + { + try { - try - { - var assemblyPackageVersion = typeof(StackdriverTraceExporter).GetTypeInfo().Assembly.GetCustomAttributes().First().InformationalVersion; - StackdriverExportVersion = assemblyPackageVersion; - } - catch (Exception) - { - StackdriverExportVersion = $"{Constants.PackagVersionUndefined}"; - } - - try - { - OpenTelemetryExporterVersion = Assembly.GetCallingAssembly().GetName().Version.ToString(); - } - catch (Exception) - { - OpenTelemetryExporterVersion = $"{Constants.PackagVersionUndefined}"; - } + var assemblyPackageVersion = typeof(StackdriverTraceExporter).GetTypeInfo().Assembly.GetCustomAttributes().First().InformationalVersion; + StackdriverExportVersion = assemblyPackageVersion; } - - /// - /// Initializes a new instance of the class. - /// - /// Project ID to send telemetry to. - public StackdriverTraceExporter(string projectId) + catch (Exception) { - this.googleCloudProjectId = new Google.Api.Gax.ResourceNames.ProjectName(projectId); - - // Set header mutation for every outgoing API call to Stackdriver so the BE knows - // which version of OC client is calling it as well as which version of the exporter - var callSettings = CallSettings.FromHeaderMutation(StackdriverCallHeaderAppender); - this.traceServiceSettings = new TraceServiceSettings { CallSettings = callSettings }; + StackdriverExportVersion = $"{Constants.PackagVersionUndefined}"; } - /// - /// Initializes a new instance of the class. - /// Only used internally for tests. - /// - /// Project ID to send telemetry to. - /// TraceServiceClient instance to use. - [ExcludeFromCodeCoverage] - internal StackdriverTraceExporter(string projectId, TraceServiceClient traceServiceClient) - : this(projectId) + try { - this.traceServiceClient = traceServiceClient; + OpenTelemetryExporterVersion = Assembly.GetCallingAssembly().GetName().Version.ToString(); } - - /// - public override ExportResult Export(in Batch batchActivity) + catch (Exception) { - TraceServiceClient traceWriter = this.traceServiceClient; - if (this.traceServiceClient == null) - { - traceWriter = new TraceServiceClientBuilder - { - Settings = this.traceServiceSettings, - }.Build(); - } + OpenTelemetryExporterVersion = $"{Constants.PackagVersionUndefined}"; + } + } - var batchSpansRequest = new BatchWriteSpansRequest - { - ProjectName = this.googleCloudProjectId, - }; + /// + /// Initializes a new instance of the class. + /// + /// Project ID to send telemetry to. + public StackdriverTraceExporter(string projectId) + { + this.googleCloudProjectId = new Google.Api.Gax.ResourceNames.ProjectName(projectId); - foreach (var activity in batchActivity) - { - batchSpansRequest.Spans.Add(activity.ToSpan(this.googleCloudProjectId.ProjectId)); - } + // Set header mutation for every outgoing API call to Stackdriver so the BE knows + // which version of OC client is calling it as well as which version of the exporter + var callSettings = CallSettings.FromHeaderMutation(StackdriverCallHeaderAppender); + this.traceServiceSettings = new TraceServiceSettings { CallSettings = callSettings }; + } - // avoid cancelling here: this is no return point: if we reached this point - // and cancellation is requested, it's better if we try to finish sending spans rather than drop it - try - { - traceWriter.BatchWriteSpans(batchSpansRequest); - } - catch (Exception ex) + /// + /// Initializes a new instance of the class. + /// Only used internally for tests. + /// + /// Project ID to send telemetry to. + /// TraceServiceClient instance to use. + [ExcludeFromCodeCoverage] + internal StackdriverTraceExporter(string projectId, TraceServiceClient traceServiceClient) + : this(projectId) + { + this.traceServiceClient = traceServiceClient; + } + + /// + public override ExportResult Export(in Batch batchActivity) + { + TraceServiceClient traceWriter = this.traceServiceClient; + if (this.traceServiceClient == null) + { + traceWriter = new TraceServiceClientBuilder { - ExporterStackdriverEventSource.Log.ExportMethodException(ex); + Settings = this.traceServiceSettings, + }.Build(); + } - return ExportResult.Failure; - } + var batchSpansRequest = new BatchWriteSpansRequest + { + ProjectName = this.googleCloudProjectId, + }; - return ExportResult.Success; + foreach (var activity in batchActivity) + { + batchSpansRequest.Spans.Add(activity.ToSpan(this.googleCloudProjectId.ProjectId)); } - /// - /// Appends OpenTelemetry headers for every outgoing request to Stackdriver Backend. - /// - /// The metadata that is sent with every outgoing http request. - private static void StackdriverCallHeaderAppender(Metadata metadata) + // avoid cancelling here: this is no return point: if we reached this point + // and cancellation is requested, it's better if we try to finish sending spans rather than drop it + try { - metadata.Add("AGENT_LABEL_KEY", "g.co/agent"); - metadata.Add("AGENT_LABEL_VALUE_STRING", $"{OpenTelemetryExporterVersion}; stackdriver-exporter {StackdriverExportVersion}"); + traceWriter.BatchWriteSpans(batchSpansRequest); } + catch (Exception ex) + { + ExporterStackdriverEventSource.Log.ExportMethodException(ex); + + return ExportResult.Failure; + } + + return ExportResult.Success; + } + + /// + /// Appends OpenTelemetry headers for every outgoing request to Stackdriver Backend. + /// + /// The metadata that is sent with every outgoing http request. + private static void StackdriverCallHeaderAppender(Metadata metadata) + { + metadata.Add("AGENT_LABEL_KEY", "g.co/agent"); + metadata.Add("AGENT_LABEL_VALUE_STRING", $"{OpenTelemetryExporterVersion}; stackdriver-exporter {StackdriverExportVersion}"); } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index 974942ab3a..6d08567660 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -17,28 +17,27 @@ using OpenTelemetry.Exporter.Stackdriver; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering a Stackdriver exporter. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering a Stackdriver exporter. + /// Registers a Stackdriver exporter that will receive instances. /// - public static class TracerProviderBuilderExtensions + /// builder to use. + /// Project ID to send telemetry to. + /// The instance of to chain the calls. + public static TracerProviderBuilder UseStackdriverExporter( + this TracerProviderBuilder builder, + string projectId) { - /// - /// Registers a Stackdriver exporter that will receive instances. - /// - /// builder to use. - /// Project ID to send telemetry to. - /// The instance of to chain the calls. - public static TracerProviderBuilder UseStackdriverExporter( - this TracerProviderBuilder builder, - string projectId) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var activityExporter = new StackdriverTraceExporter(projectId); + var activityExporter = new StackdriverTraceExporter(projectId); - return builder.AddProcessor(new BatchActivityExportProcessor(activityExporter)); - } + return builder.AddProcessor(new BatchActivityExportProcessor(activityExporter)); } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs index 6478bfcef0..3aac886d42 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs @@ -16,36 +16,35 @@ using System.Collections.Generic; -namespace OpenTelemetry.Exporter.Stackdriver.Utils +namespace OpenTelemetry.Exporter.Stackdriver.Utils; + +/// +/// Common Utility Methods that are not metrics/trace specific. +/// +public static class CommonUtils { /// - /// Common Utility Methods that are not metrics/trace specific. + /// Divide the source list into batches of lists of given size. /// - public static class CommonUtils + /// The type of the list. + /// The list. + /// Size of the batch. + /// . + public static IEnumerable> Partition(this IEnumerable source, int size) { - /// - /// Divide the source list into batches of lists of given size. - /// - /// The type of the list. - /// The list. - /// Size of the batch. - /// . - public static IEnumerable> Partition(this IEnumerable source, int size) + using var enumerator = source.GetEnumerator(); + while (enumerator.MoveNext()) { - using var enumerator = source.GetEnumerator(); - while (enumerator.MoveNext()) - { - yield return WalkPartition(enumerator, size - 1); - } + yield return WalkPartition(enumerator, size - 1); } + } - private static IEnumerable WalkPartition(IEnumerator source, int size) + private static IEnumerable WalkPartition(IEnumerator source, int size) + { + yield return source.Current; + for (var i = 0; i < size && source.MoveNext(); i++) { yield return source.Current; - for (var i = 0; i < size && source.MoveNext(); i++) - { - yield return source.Current; - } } } } diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs index 8089b4a71c..0d90e90a44 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs @@ -18,51 +18,50 @@ using OpenTelemetry.Exporter.Stackdriver.Implementation; using Xunit; -namespace OpenTelemetry.Exporter.Stackdriver.Tests +namespace OpenTelemetry.Exporter.Stackdriver.Tests; + +public class StackdriverStatsConfigurationTests { - public class StackdriverStatsConfigurationTests + public StackdriverStatsConfigurationTests() { - public StackdriverStatsConfigurationTests() - { - // Setting this for unit testing purposes, so we don't need credentials for real Google Cloud Account - Environment.SetEnvironmentVariable("GOOGLE_PROJECT_ID", "test", EnvironmentVariableTarget.Process); - } + // Setting this for unit testing purposes, so we don't need credentials for real Google Cloud Account + Environment.SetEnvironmentVariable("GOOGLE_PROJECT_ID", "test", EnvironmentVariableTarget.Process); + } - [Fact] - public void StatsConfiguration_ByDefault_MetricNamePrefixEmpty() - { - Assert.NotNull(StackdriverStatsConfiguration.Default); - Assert.Equal(GoogleCloudResourceUtils.GetProjectId(), StackdriverStatsConfiguration.Default.ProjectId); - Assert.Equal(string.Empty, StackdriverStatsConfiguration.Default.MetricNamePrefix); - } + [Fact] + public void StatsConfiguration_ByDefault_MetricNamePrefixEmpty() + { + Assert.NotNull(StackdriverStatsConfiguration.Default); + Assert.Equal(GoogleCloudResourceUtils.GetProjectId(), StackdriverStatsConfiguration.Default.ProjectId); + Assert.Equal(string.Empty, StackdriverStatsConfiguration.Default.MetricNamePrefix); + } - [Fact] - public void StatsConfiguration_ByDefault_ProjectIdIsGoogleCloudProjectId() - { - Assert.NotNull(StackdriverStatsConfiguration.Default); - Assert.Equal(GoogleCloudResourceUtils.GetProjectId(), StackdriverStatsConfiguration.Default.ProjectId); - } + [Fact] + public void StatsConfiguration_ByDefault_ProjectIdIsGoogleCloudProjectId() + { + Assert.NotNull(StackdriverStatsConfiguration.Default); + Assert.Equal(GoogleCloudResourceUtils.GetProjectId(), StackdriverStatsConfiguration.Default.ProjectId); + } - [Fact] - public void StatsConfiguration_ByDefault_ExportIntervalMinute() - { - Assert.Equal(TimeSpan.FromMinutes(1), StackdriverStatsConfiguration.Default.ExportInterval); - } + [Fact] + public void StatsConfiguration_ByDefault_ExportIntervalMinute() + { + Assert.Equal(TimeSpan.FromMinutes(1), StackdriverStatsConfiguration.Default.ExportInterval); + } - [Fact] - public void StatsConfiguration_ByDefault_MonitoredResourceIsGlobal() - { - Assert.NotNull(StackdriverStatsConfiguration.Default.MonitoredResource); + [Fact] + public void StatsConfiguration_ByDefault_MonitoredResourceIsGlobal() + { + Assert.NotNull(StackdriverStatsConfiguration.Default.MonitoredResource); - Assert.Equal(Constants.Global, StackdriverStatsConfiguration.Default.MonitoredResource.Type); + Assert.Equal(Constants.Global, StackdriverStatsConfiguration.Default.MonitoredResource.Type); - Assert.NotNull(StackdriverStatsConfiguration.Default.MonitoredResource.Labels); + Assert.NotNull(StackdriverStatsConfiguration.Default.MonitoredResource.Labels); - Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey("project_id")); - Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey(Constants.ProjectIdLabelKey)); - Assert.Equal( - StackdriverStatsConfiguration.Default.ProjectId, - StackdriverStatsConfiguration.Default.MonitoredResource.Labels[Constants.ProjectIdLabelKey]); - } + Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey("project_id")); + Assert.True(StackdriverStatsConfiguration.Default.MonitoredResource.Labels.ContainsKey(Constants.ProjectIdLabelKey)); + Assert.Equal( + StackdriverStatsConfiguration.Default.ProjectId, + StackdriverStatsConfiguration.Default.MonitoredResource.Labels[Constants.ProjectIdLabelKey]); } } diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 3a4f662207..57c9e58b79 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -28,234 +28,233 @@ using Xunit; using Status = Grpc.Core.Status; -namespace OpenTelemetry.Exporter.Stackdriver.Tests +namespace OpenTelemetry.Exporter.Stackdriver.Tests; + +public class StackdriverExporterTests { - public class StackdriverExporterTests + static StackdriverExporterTests() { - static StackdriverExporterTests() + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + Activity.ForceDefaultIdFormat = true; + + var listener = new ActivityListener { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - Activity.ForceDefaultIdFormat = true; + ShouldListenTo = _ => true, + Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllData, + }; - var listener = new ActivityListener - { - ShouldListenTo = _ => true, - Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllData, - }; + ActivitySource.AddActivityListener(listener); + } - ActivitySource.AddActivityListener(listener); - } + [Fact] + public void StackdriverExporter_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.UseStackdriverExporter(string.Empty)); + } - [Fact] - public void StackdriverExporter_BadArgs() - { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.UseStackdriverExporter(string.Empty)); - } + [Fact] + public void StackdriverExporter_CustomActivityProcessor() + { + const string ActivitySourceName = "stackdriver.test"; + Guid requestId = Guid.NewGuid(); + TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); - [Fact] - public void StackdriverExporter_CustomActivityProcessor() - { - const string ActivitySourceName = "stackdriver.test"; - Guid requestId = Guid.NewGuid(); - TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + bool startCalled = false; + bool endCalled = false; - bool startCalled = false; - bool endCalled = false; + testActivityProcessor.StartAction = + (a) => + { + startCalled = true; + }; - testActivityProcessor.StartAction = - (a) => - { - startCalled = true; - }; + testActivityProcessor.EndAction = + (a) => + { + endCalled = true; + }; - testActivityProcessor.EndAction = - (a) => - { - endCalled = true; - }; + var openTelemetrySdk = Sdk.CreateTracerProviderBuilder() + .AddSource(ActivitySourceName) + .AddProcessor(testActivityProcessor) + .UseStackdriverExporter("test").Build(); - var openTelemetrySdk = Sdk.CreateTracerProviderBuilder() - .AddSource(ActivitySourceName) - .AddProcessor(testActivityProcessor) - .UseStackdriverExporter("test").Build(); + var source = new ActivitySource(ActivitySourceName); + var activity = source.StartActivity("Test Activity"); + activity?.Stop(); - var source = new ActivitySource(ActivitySourceName); - var activity = source.StartActivity("Test Activity"); - activity?.Stop(); + Assert.True(startCalled); + Assert.True(endCalled); + } - Assert.True(startCalled); - Assert.True(endCalled); + [Fact] + public void StackdriverExporter_TraceClientThrows_ExportResultFailure() + { + Exception exception = null; + ExportResult result = ExportResult.Success; + var exportedItems = new List(); + const string ActivitySourceName = "stackdriver.test"; + var source = new ActivitySource(ActivitySourceName); + var traceClientMock = new Mock(MockBehavior.Strict); + traceClientMock.Setup(x => + x.BatchWriteSpans(It.IsAny(), It.IsAny())) + .Throws(new RpcException(Status.DefaultCancelled)) + .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); + var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); + + var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); + + for (int i = 0; i < 10; i++) + { + using Activity activity = source.StartActivity("Test Activity"); + processor.OnEnd(activity); } - [Fact] - public void StackdriverExporter_TraceClientThrows_ExportResultFailure() + processor.Shutdown(); + + var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); + RunTest(batch); + + void RunTest(Batch batch) { - Exception exception = null; - ExportResult result = ExportResult.Success; - var exportedItems = new List(); - const string ActivitySourceName = "stackdriver.test"; - var source = new ActivitySource(ActivitySourceName); - var traceClientMock = new Mock(MockBehavior.Strict); - traceClientMock.Setup(x => - x.BatchWriteSpans(It.IsAny(), It.IsAny())) - .Throws(new RpcException(Status.DefaultCancelled)) - .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); - var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); - - var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); - - for (int i = 0; i < 10; i++) + exception = Record.Exception(() => { - using Activity activity = source.StartActivity("Test Activity"); - processor.OnEnd(activity); - } + result = activityExporter.Export(batch); + }); + } - processor.Shutdown(); + Assert.Null(exception); + Assert.StrictEqual(ExportResult.Failure, result); + traceClientMock.VerifyAll(); + } - var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); - RunTest(batch); + [Fact] + public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() + { + Exception exception = null; + ExportResult result = ExportResult.Failure; + var exportedItems = new List(); + const string ActivitySourceName = "stackdriver.test"; + var source = new ActivitySource(ActivitySourceName); + var traceClientMock = new Mock(MockBehavior.Strict); + traceClientMock.Setup(x => + x.BatchWriteSpans(It.IsAny(), It.IsAny())) + .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); + var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); + + var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); + + for (int i = 0; i < 10; i++) + { + using Activity activity = source.StartActivity("Test Activity"); + processor.OnEnd(activity); + } - void RunTest(Batch batch) - { - exception = Record.Exception(() => - { - result = activityExporter.Export(batch); - }); - } + processor.Shutdown(); - Assert.Null(exception); - Assert.StrictEqual(ExportResult.Failure, result); - traceClientMock.VerifyAll(); - } + var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); + RunTest(batch); - [Fact] - public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() + void RunTest(Batch batch) { - Exception exception = null; - ExportResult result = ExportResult.Failure; - var exportedItems = new List(); - const string ActivitySourceName = "stackdriver.test"; - var source = new ActivitySource(ActivitySourceName); - var traceClientMock = new Mock(MockBehavior.Strict); - traceClientMock.Setup(x => - x.BatchWriteSpans(It.IsAny(), It.IsAny())) - .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); - var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); - - var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); - - for (int i = 0; i < 10; i++) + exception = Record.Exception(() => { - using Activity activity = source.StartActivity("Test Activity"); - processor.OnEnd(activity); - } + result = activityExporter.Export(batch); + }); + } + + Assert.Null(exception); + Assert.StrictEqual(ExportResult.Success, result); + traceClientMock.VerifyAll(); + } - processor.Shutdown(); + internal static Activity CreateTestActivity( + bool setAttributes = true, + Dictionary additionalAttributes = null, + bool addEvents = true, + bool addLinks = true, + Resource resource = null, + ActivityKind kind = ActivityKind.Client) + { + var startTimestamp = DateTime.UtcNow; + var endTimestamp = startTimestamp.AddSeconds(60); + var eventTimestamp = DateTime.UtcNow; + var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); - var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); - RunTest(batch); + var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); - void RunTest(Batch batch) + var attributes = new Dictionary + { + { "stringKey", "value" }, + { "longKey", 1L }, + { "longKey2", 1 }, + { "doubleKey", 1D }, + { "doubleKey2", 1F }, + { "boolKey", true }, + }; + if (additionalAttributes != null) + { + foreach (var attribute in additionalAttributes) { - exception = Record.Exception(() => - { - result = activityExporter.Export(batch); - }); + attributes.Add(attribute.Key, attribute.Value); } - - Assert.Null(exception); - Assert.StrictEqual(ExportResult.Success, result); - traceClientMock.VerifyAll(); } - internal static Activity CreateTestActivity( - bool setAttributes = true, - Dictionary additionalAttributes = null, - bool addEvents = true, - bool addLinks = true, - Resource resource = null, - ActivityKind kind = ActivityKind.Client) + var events = new List { - var startTimestamp = DateTime.UtcNow; - var endTimestamp = startTimestamp.AddSeconds(60); - var eventTimestamp = DateTime.UtcNow; - var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); + new ActivityEvent( + "Event1", + eventTimestamp, + new ActivityTagsCollection + { + { "key", "value" }, + }), + new ActivityEvent( + "Event2", + eventTimestamp, + new ActivityTagsCollection + { + { "key", "value" }, + }), + }; - var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); + var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); - var attributes = new Dictionary - { - { "stringKey", "value" }, - { "longKey", 1L }, - { "longKey2", 1 }, - { "doubleKey", 1D }, - { "doubleKey2", 1F }, - { "boolKey", true }, - }; - if (additionalAttributes != null) + var activitySource = new ActivitySource(nameof(CreateTestActivity)); + + var tags = setAttributes ? + attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())) + : null; + var links = addLinks ? + new[] { - foreach (var attribute in additionalAttributes) - { - attributes.Add(attribute.Key, attribute.Value); - } + new ActivityLink(new ActivityContext( + traceId, + linkedSpanId, + ActivityTraceFlags.Recorded)), } + : null; - var events = new List - { - new ActivityEvent( - "Event1", - eventTimestamp, - new ActivityTagsCollection - { - { "key", "value" }, - }), - new ActivityEvent( - "Event2", - eventTimestamp, - new ActivityTagsCollection - { - { "key", "value" }, - }), - }; + var activity = activitySource.StartActivity( + "Name", + kind, + parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), + tags, + links, + startTime: startTimestamp); - var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); - - var activitySource = new ActivitySource(nameof(CreateTestActivity)); - - var tags = setAttributes ? - attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())) - : null; - var links = addLinks ? - new[] - { - new ActivityLink(new ActivityContext( - traceId, - linkedSpanId, - ActivityTraceFlags.Recorded)), - } - : null; - - var activity = activitySource.StartActivity( - "Name", - kind, - parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), - tags, - links, - startTime: startTimestamp); - - if (addEvents) + if (addEvents) + { + foreach (var evnt in events) { - foreach (var evnt in events) - { - activity.AddEvent(evnt); - } + activity.AddEvent(evnt); } + } - activity.SetEndTime(endTimestamp); - activity.Stop(); + activity.SetEndTime(endTimestamp); + activity.Stop(); - return activity; - } + return activity; } } diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index dc7e415768..816c34a496 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -17,56 +17,55 @@ using System; using System.Diagnostics; -namespace OpenTelemetry.Exporter.Stackdriver.Tests +namespace OpenTelemetry.Exporter.Stackdriver.Tests; + +public class TestActivityProcessor : BaseProcessor, IDisposable { - public class TestActivityProcessor : BaseProcessor, IDisposable - { - public Action StartAction; - public Action EndAction; + public Action StartAction; + public Action EndAction; - public TestActivityProcessor() - { - } + public TestActivityProcessor() + { + } - public TestActivityProcessor(Action onStart, Action onEnd) - { - this.StartAction = onStart; - this.EndAction = onEnd; - } + public TestActivityProcessor(Action onStart, Action onEnd) + { + this.StartAction = onStart; + this.EndAction = onEnd; + } - public bool ShutdownCalled { get; private set; } = false; + public bool ShutdownCalled { get; private set; } = false; - public bool ForceFlushCalled { get; private set; } = false; + public bool ForceFlushCalled { get; private set; } = false; - public bool DisposedCalled { get; private set; } = false; + public bool DisposedCalled { get; private set; } = false; - public override void OnStart(Activity activity) - { - this.StartAction?.Invoke(activity); - } + public override void OnStart(Activity activity) + { + this.StartAction?.Invoke(activity); + } - public override void OnEnd(Activity activity) - { - this.EndAction?.Invoke(activity); - } + public override void OnEnd(Activity activity) + { + this.EndAction?.Invoke(activity); + } - protected override bool OnShutdown(int timeoutMilliseconds) - { - this.ShutdownCalled = true; - base.OnShutdown(timeoutMilliseconds); - return true; - } + protected override bool OnShutdown(int timeoutMilliseconds) + { + this.ShutdownCalled = true; + base.OnShutdown(timeoutMilliseconds); + return true; + } - protected override bool OnForceFlush(int timeoutMilliseconds) - { - this.ForceFlushCalled = true; - return base.OnForceFlush(timeoutMilliseconds); - } + protected override bool OnForceFlush(int timeoutMilliseconds) + { + this.ForceFlushCalled = true; + return base.OnForceFlush(timeoutMilliseconds); + } - protected override void Dispose(bool disposing) - { - this.DisposedCalled = true; - base.Dispose(disposing); - } + protected override void Dispose(bool disposing) + { + this.DisposedCalled = true; + base.Dispose(disposing); } } From 02945f347464334df668726483fee628e9126048 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Thu, 18 Aug 2022 09:02:22 -0700 Subject: [PATCH 0293/1499] nit: rewording (#592) --- src/OpenTelemetry.Instrumentation.Runtime/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index c4647cf140..4987f4ac91 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -1,4 +1,4 @@ -# DotNet Runtime Instrumentation for OpenTelemetry .NET +# Runtime Instrumentation for OpenTelemetry .NET [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) From 377602476d9ab693ab7f021e17398812e64cb8c3 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 18 Aug 2022 13:27:34 -0700 Subject: [PATCH 0294/1499] add exception remarks (#591) --- .../FileBlobProvider.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs index 9ffd6cf8e8..c8abc11b7e 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs @@ -62,6 +62,27 @@ public class FileBlobProvider : PersistentBlobProvider, IDisposable /// Controls the timeout when writing a buffer to blob. /// Default is 1 minute. /// + /// + /// path is null. + /// + /// + /// invalid path. + /// + /// + /// path exceeds system defined maximum length. + /// + /// + /// insufficient priviledges for provided path. + /// + /// + /// path contains a colon character (:) that is not part of a drive label ("C:\"). + /// + /// + /// path contains invalid characters. + /// + /// + /// path is either file or network name is not known. + /// public FileBlobProvider( string path, long maxSizeInBytes = 52428800, From 8d91837a537b2e522f4b868cc174e5c00c440ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 19 Aug 2022 21:03:45 +0200 Subject: [PATCH 0295/1499] [Extensions.Docker] File scoped namespace (#587) Co-authored-by: Utkarsh Umesan Pillai --- .../DockerExtensionsEventSource.cs | 61 ++++--- .../Resources/DockerResourceDetector.cs | 159 +++++++++--------- .../Resources/DockerSemanticConventions.cs | 9 +- .../Utils/EncodingUtils.cs | 27 ++- .../Resources/DockerResourceDetectorTests.cs | 135 ++++++++------- 5 files changed, 193 insertions(+), 198 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs b/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs index ab522cea8b..0478b5bdb6 100644 --- a/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs @@ -19,45 +19,44 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Extensions.Docker +namespace OpenTelemetry.Extensions.Docker; + +[EventSource(Name = "OpenTelemetry-Extensions-Docker")] +internal class DockerExtensionsEventSource : EventSource { - [EventSource(Name = "OpenTelemetry-Extensions-Docker")] - internal class DockerExtensionsEventSource : EventSource - { - public static DockerExtensionsEventSource Log = new DockerExtensionsEventSource(); + public static DockerExtensionsEventSource Log = new DockerExtensionsEventSource(); - [NonEvent] - public void ExtractResourceAttributesException(string format, Exception ex) + [NonEvent] + public void ExtractResourceAttributesException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); - } + this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); } + } - [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Error)] - public void FailedToExtractResourceAttributes(string format, string exception) + [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Error)] + public void FailedToExtractResourceAttributes(string format, string exception) + { + this.WriteEvent(1, format, exception); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try { - this.WriteEvent(1, format, exception); + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs index bb6ab6a13f..fb6d25f452 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs @@ -20,112 +20,111 @@ using OpenTelemetry.Extensions.Docker.Utils; using OpenTelemetry.Resources; -namespace OpenTelemetry.Extensions.Docker.Resources +namespace OpenTelemetry.Extensions.Docker.Resources; + +/// +/// Resource detector for application running in Docker environment. +/// +public class DockerResourceDetector : IResourceDetector { + private const string FILEPATH = "/proc/self/cgroup"; + + /// + /// Detects the resource attributes from Docker. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + return this.BuildResource(FILEPATH); + } + /// - /// Resource detector for application running in Docker environment. + /// Builds the resource attributes from Container Id in file path. /// - public class DockerResourceDetector : IResourceDetector + /// File path where container id exists. + /// Returns Resource with list of key-value pairs of container resource attributes if container id exists else empty resource. + internal Resource BuildResource(string path) { - private const string FILEPATH = "/proc/self/cgroup"; + var containerId = this.ExtractContainerId(path); - /// - /// Detects the resource attributes from Docker. - /// - /// Resource with key-value pairs of resource attributes. - public Resource Detect() + if (string.IsNullOrEmpty(containerId)) { - return this.BuildResource(FILEPATH); + return Resource.Empty; } - - /// - /// Builds the resource attributes from Container Id in file path. - /// - /// File path where container id exists. - /// Returns Resource with list of key-value pairs of container resource attributes if container id exists else empty resource. - internal Resource BuildResource(string path) + else { - var containerId = this.ExtractContainerId(path); - - if (string.IsNullOrEmpty(containerId)) - { - return Resource.Empty; - } - else - { - return new Resource(new List>() { new KeyValuePair(DockerSemanticConventions.AttributeContainerID, containerId), }); - } + return new Resource(new List>() { new KeyValuePair(DockerSemanticConventions.AttributeContainerID, containerId), }); } + } - /// - /// Extracts Container Id from path. - /// - /// cgroup path. - /// Container Id, Null if not found or exception being thrown. - private string ExtractContainerId(string path) + /// + /// Extracts Container Id from path. + /// + /// cgroup path. + /// Container Id, Null if not found or exception being thrown. + private string ExtractContainerId(string path) + { + try { - try + if (!File.Exists(path)) { - if (!File.Exists(path)) - { - return null; - } + return null; + } - foreach (string line in File.ReadLines(path)) + foreach (string line in File.ReadLines(path)) + { + string containerId = (!string.IsNullOrEmpty(line)) ? this.GetIdFromLine(line) : null; + if (!string.IsNullOrEmpty(containerId)) { - string containerId = (!string.IsNullOrEmpty(line)) ? this.GetIdFromLine(line) : null; - if (!string.IsNullOrEmpty(containerId)) - { - return containerId; - } + return containerId; } } - catch (Exception ex) - { - DockerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(DockerResourceDetector)} : Failed to extract Container id from path", ex); - } - - return null; } - - /// - /// Gets the Container Id from the line after removing the prefix and suffix. - /// - /// line read from cgroup file. - /// Container Id. - private string GetIdFromLine(string line) + catch (Exception ex) { - // This cgroup output line should have the container id in it - int lastSlashIndex = line.LastIndexOf('/'); - if (lastSlashIndex < 0) - { - return null; - } + DockerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(DockerResourceDetector)} : Failed to extract Container id from path", ex); + } - string lastSection = line.Substring(lastSlashIndex + 1); - int startIndex = lastSection.LastIndexOf('-'); - int endIndex = lastSection.LastIndexOf('.'); + return null; + } - string containerId = this.RemovePrefixAndSuffixIfneeded(lastSection, startIndex, endIndex); + /// + /// Gets the Container Id from the line after removing the prefix and suffix. + /// + /// line read from cgroup file. + /// Container Id. + private string GetIdFromLine(string line) + { + // This cgroup output line should have the container id in it + int lastSlashIndex = line.LastIndexOf('/'); + if (lastSlashIndex < 0) + { + return null; + } - if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) - { - return null; - } + string lastSection = line.Substring(lastSlashIndex + 1); + int startIndex = lastSection.LastIndexOf('-'); + int endIndex = lastSection.LastIndexOf('.'); - return containerId; - } + string containerId = this.RemovePrefixAndSuffixIfneeded(lastSection, startIndex, endIndex); - private string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) + if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) { - startIndex = (startIndex == -1) ? 0 : startIndex + 1; + return null; + } - if (endIndex == -1) - { - endIndex = input.Length; - } + return containerId; + } + + private string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) + { + startIndex = (startIndex == -1) ? 0 : startIndex + 1; - return input.Substring(startIndex, endIndex - startIndex); + if (endIndex == -1) + { + endIndex = input.Length; } + + return input.Substring(startIndex, endIndex - startIndex); } } diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs index b41d7404af..0b554a79d0 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs @@ -14,10 +14,9 @@ // limitations under the License. // -namespace OpenTelemetry.Extensions.Docker.Resources +namespace OpenTelemetry.Extensions.Docker.Resources; + +internal static class DockerSemanticConventions { - internal static class DockerSemanticConventions - { - public const string AttributeContainerID = "container.id"; - } + public const string AttributeContainerID = "container.id"; } diff --git a/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs b/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs index 5963f7ecb2..28bd35bc38 100644 --- a/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs +++ b/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs @@ -17,21 +17,20 @@ using System.Collections.Generic; using System.Linq; -namespace OpenTelemetry.Extensions.Docker.Utils +namespace OpenTelemetry.Extensions.Docker.Utils; + +internal class EncodingUtils { - internal class EncodingUtils + /// + /// Checks if the string is valid hex. + /// + /// string. + /// true if valid else false. + public static bool IsValidHexString(IEnumerable hexString) { - /// - /// Checks if the string is valid hex. - /// - /// string. - /// true if valid else false. - public static bool IsValidHexString(IEnumerable hexString) - { - return hexString.Select(currentCharacter => - (currentCharacter >= '0' && currentCharacter <= '9') || - (currentCharacter >= 'a' && currentCharacter <= 'f') || - (currentCharacter >= 'A' && currentCharacter <= 'F')).All(isHexCharacter => isHexCharacter); - } + return hexString.Select(currentCharacter => + (currentCharacter >= '0' && currentCharacter <= '9') || + (currentCharacter >= 'a' && currentCharacter <= 'f') || + (currentCharacter >= 'A' && currentCharacter <= 'F')).All(isHexCharacter => isHexCharacter); } } diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs index bebb93d3e8..004410766e 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs +++ b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs @@ -20,93 +20,92 @@ using OpenTelemetry.Resources; using Xunit; -namespace OpenTelemetry.Extensions.Docker.Tests +namespace OpenTelemetry.Extensions.Docker.Tests; + +public class DockerResourceDetectorTests { - public class DockerResourceDetectorTests - { - // Invalid cgroup line - private const string INVALIDCGROUPLINE = - "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz"; + // Invalid cgroup line + private const string INVALIDCGROUPLINE = + "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz"; - // cgroup line with prefix - private const string CGROUPLINEWITHPREFIX = - "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff"; + // cgroup line with prefix + private const string CGROUPLINEWITHPREFIX = + "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff"; - // Expected Container Id with prefix removed - private const string CONTAINERIDWITHPREFIXREMOVED = "e2cc29debdf85dde404998aa128997a819ff"; + // Expected Container Id with prefix removed + private const string CONTAINERIDWITHPREFIXREMOVED = "e2cc29debdf85dde404998aa128997a819ff"; - // cgroup line with suffix - private const string CGROUPLINEWITHSUFFIX = - "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa"; + // cgroup line with suffix + private const string CGROUPLINEWITHSUFFIX = + "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa"; - // Expected Container Id with suffix removed - private const string CONTAINERIDWITHSUFFIXREMOVED = "ac679f8a8319c8cf7d38e1adf263bc08d23"; + // Expected Container Id with suffix removed + private const string CONTAINERIDWITHSUFFIXREMOVED = "ac679f8a8319c8cf7d38e1adf263bc08d23"; - // cgroup line with prefix and suffix - private const string CGROUPLINEWITHPREFIXandSUFFIX = - "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff"; + // cgroup line with prefix and suffix + private const string CGROUPLINEWITHPREFIXandSUFFIX = + "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff"; - // Expected Container Id with both prefix and suffix removed - private const string CONTAINERIDWITHPREFIXANDSUFFIXREMOVED = "dc679f8a8319c8cf7d38e1adf263bc08d23"; + // Expected Container Id with both prefix and suffix removed + private const string CONTAINERIDWITHPREFIXANDSUFFIXREMOVED = "dc679f8a8319c8cf7d38e1adf263bc08d23"; - // cgroup line with container Id - private const string CGROUPLINE = - "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; + // cgroup line with container Id + private const string CGROUPLINE = + "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; - // Expected Container Id - private const string CONTAINERID = - "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; + // Expected Container Id + private const string CONTAINERID = + "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; + + [Fact] + public void TestValidContainer() + { + var dockerResourceDetector = new DockerResourceDetector(); - [Fact] - public void TestValidContainer() + using (TempFile tempFile = new TempFile()) { - var dockerResourceDetector = new DockerResourceDetector(); - - using (TempFile tempFile = new TempFile()) - { - tempFile.Write(CGROUPLINEWITHPREFIX); - Assert.Equal(CONTAINERIDWITHPREFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); - } - - using (TempFile tempFile = new TempFile()) - { - tempFile.Write(CGROUPLINEWITHSUFFIX); - Assert.Equal(CONTAINERIDWITHSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); - } - - using (TempFile tempFile = new TempFile()) - { - tempFile.Write(CGROUPLINEWITHPREFIXandSUFFIX); - Assert.Equal(CONTAINERIDWITHPREFIXANDSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); - } - - using (TempFile tempFile = new TempFile()) - { - tempFile.Write(CGROUPLINE); - Assert.Equal(CONTAINERID, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); - } + tempFile.Write(CGROUPLINEWITHPREFIX); + Assert.Equal(CONTAINERIDWITHPREFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); } - [Fact] - public void TestInvalidContainer() + using (TempFile tempFile = new TempFile()) { - var dockerResourceDetector = new DockerResourceDetector(); + tempFile.Write(CGROUPLINEWITHSUFFIX); + Assert.Equal(CONTAINERIDWITHSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + } - // test invalid containerId (non-hex) - using (TempFile tempFile = new TempFile()) - { - tempFile.Write(INVALIDCGROUPLINE); - Assert.Equal(dockerResourceDetector.BuildResource(tempFile.FilePath), Resource.Empty); - } + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(CGROUPLINEWITHPREFIXandSUFFIX); + Assert.Equal(CONTAINERIDWITHPREFIXANDSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + } - // test invalid file - Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath()), Resource.Empty); + using (TempFile tempFile = new TempFile()) + { + tempFile.Write(CGROUPLINE); + Assert.Equal(CONTAINERID, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); } + } + + [Fact] + public void TestInvalidContainer() + { + var dockerResourceDetector = new DockerResourceDetector(); - private string GetContainerId(Resource resource) + // test invalid containerId (non-hex) + using (TempFile tempFile = new TempFile()) { - var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - return resourceAttributes[DockerSemanticConventions.AttributeContainerID]?.ToString(); + tempFile.Write(INVALIDCGROUPLINE); + Assert.Equal(dockerResourceDetector.BuildResource(tempFile.FilePath), Resource.Empty); } + + // test invalid file + Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath()), Resource.Empty); + } + + private string GetContainerId(Resource resource) + { + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); + return resourceAttributes[DockerSemanticConventions.AttributeContainerID]?.ToString(); } } From 3e2029ab9ae6c9c755178ecc1a53f9f5f480e32a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Sat, 20 Aug 2022 01:22:10 +0200 Subject: [PATCH 0296/1499] [Extensions.AzureMonitor] File scoped namespace (#588) --- .../ApplicationInsightsSampler.cs | 93 ++++++++------- .../ApplicationInsightsSamplerTests.cs | 109 +++++++++--------- 2 files changed, 100 insertions(+), 102 deletions(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 00bd29aa5d..26049fc6a9 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -17,64 +17,63 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Extensions.AzureMonitor +namespace OpenTelemetry.Extensions.AzureMonitor; + +/// +/// Sample configurable for OpenTelemetry exporters for compatibility +/// with Application Insight SDKs. +/// +public class ApplicationInsightsSampler : Sampler { + private readonly float samplingRatio; + /// - /// Sample configurable for OpenTelemetry exporters for compatibility - /// with Application Insight SDKs. + /// Initializes a new instance of the class. /// - public class ApplicationInsightsSampler : Sampler + /// Ratio of telemetry that should be sampled. + public ApplicationInsightsSampler(float samplingRatio) { - private readonly float samplingRatio; + // Ensure passed ratio is between 0 and 1, inclusive + Guard.ThrowIfOutOfRange((double)samplingRatio, min: 0.0, max: 1.0); - /// - /// Initializes a new instance of the class. - /// - /// Ratio of telemetry that should be sampled. - public ApplicationInsightsSampler(float samplingRatio) - { - // Ensure passed ratio is between 0 and 1, inclusive - Guard.ThrowIfOutOfRange((double)samplingRatio, min: 0.0, max: 1.0); + this.samplingRatio = samplingRatio; + this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; + } - this.samplingRatio = samplingRatio; - this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; - } + /// + /// Computational method using the DJB2 Hash algorithm to decide whether to sample + /// a given telemetry item, based on its Trace Id. + /// + /// Parameters of telemetry item used to make sampling decision. + /// Returns whether or not we should sample telemetry in the form of a class. + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToLowerInvariant()); + return new SamplingResult(sampleScore < this.samplingRatio); + } - /// - /// Computational method using the DJB2 Hash algorithm to decide whether to sample - /// a given telemetry item, based on its Trace Id. - /// - /// Parameters of telemetry item used to make sampling decision. - /// Returns whether or not we should sample telemetry in the form of a class. - public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + private static double DJB2SampleScore(string traceIdHex) + { + // Calculate DJB2 hash code from hex-converted TraceId + int hash = 5381; + + for (int i = 0; i < traceIdHex.Length; i++) { - double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToLowerInvariant()); - return new SamplingResult(sampleScore < this.samplingRatio); + hash = ((hash << 5) + hash) + (int)traceIdHex[i]; } - private static double DJB2SampleScore(string traceIdHex) + // Take the absolute value of the hash + if (hash == int.MinValue) { - // Calculate DJB2 hash code from hex-converted TraceId - int hash = 5381; - - for (int i = 0; i < traceIdHex.Length; i++) - { - hash = ((hash << 5) + hash) + (int)traceIdHex[i]; - } - - // Take the absolute value of the hash - if (hash == int.MinValue) - { - hash = int.MaxValue; - } - else - { - hash = Math.Abs(hash); - } - - // Divide by MaxValue for value between 0 and 1 for sampling score - double samplingScore = (double)hash / int.MaxValue; - return samplingScore; + hash = int.MaxValue; + } + else + { + hash = Math.Abs(hash); } + + // Divide by MaxValue for value between 0 and 1 for sampling score + double samplingScore = (double)hash / int.MaxValue; + return samplingScore; } } diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs index e494573ba1..74caecd2cf 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs @@ -20,74 +20,73 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Extensions.AzureMonitor.Tests +namespace OpenTelemetry.Extensions.AzureMonitor.Tests; + +public class ApplicationInsightsSamplerTests { - public class ApplicationInsightsSamplerTests + [Fact] + public void VerifyHashAlgorithmCorrectness() { - [Fact] - public void VerifyHashAlgorithmCorrectness() + byte[] testBytes = new byte[] + { + 0x8F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + byte[] testBytes2 = new byte[] { - byte[] testBytes = new byte[] - { - 0x8F, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0, 0, 0, 0, 0, 0, 0, 0, - }; - byte[] testBytes2 = new byte[] - { - 0x0F, 0x1F, 0x2F, 0x3F, - 0x4F, 0x5F, 0x6F, 0x7F, - 0x8F, 0x9F, 0xAF, 0xBF, - 0xCF, 0xDF, 0xEF, 0xFF, - }; - ActivityTraceId testId = ActivityTraceId.CreateFromBytes(testBytes); - ActivityTraceId testId2 = ActivityTraceId.CreateFromBytes(testBytes2); + 0x0F, 0x1F, 0x2F, 0x3F, + 0x4F, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xBF, + 0xCF, 0xDF, 0xEF, 0xFF, + }; + ActivityTraceId testId = ActivityTraceId.CreateFromBytes(testBytes); + ActivityTraceId testId2 = ActivityTraceId.CreateFromBytes(testBytes2); - ActivityContext parentContext = default(ActivityContext); - SamplingParameters testParams = new SamplingParameters(parentContext, testId, "TestActivity", ActivityKind.Internal); - SamplingParameters testParams2 = new SamplingParameters(parentContext, testId2, "TestActivity", ActivityKind.Internal); + ActivityContext parentContext = default(ActivityContext); + SamplingParameters testParams = new SamplingParameters(parentContext, testId, "TestActivity", ActivityKind.Internal); + SamplingParameters testParams2 = new SamplingParameters(parentContext, testId2, "TestActivity", ActivityKind.Internal); - var zeroSampler = new ApplicationInsightsSampler(0); - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1); + var zeroSampler = new ApplicationInsightsSampler(0); + ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1); - // 0.86 is below the sample score for testId1, but strict enough to drop testId2 - ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(0.86f); + // 0.86 is below the sample score for testId1, but strict enough to drop testId2 + ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(0.86f); - Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams).Decision); - Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams2).Decision); + Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams).Decision); + Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams2).Decision); - Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams).Decision); - Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams2).Decision); + Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams).Decision); + Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams2).Decision); - Assert.Equal(SamplingDecision.Drop, ratioSampler.ShouldSample(testParams).Decision); - Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); - } + Assert.Equal(SamplingDecision.Drop, ratioSampler.ShouldSample(testParams).Decision); + Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); + } - [Fact] - public void ApplicationInsightsSamplerGoodArgs() - { - ApplicationInsightsSampler pointFiveSampler = new ApplicationInsightsSampler(0.5f); - Assert.NotNull(pointFiveSampler); + [Fact] + public void ApplicationInsightsSamplerGoodArgs() + { + ApplicationInsightsSampler pointFiveSampler = new ApplicationInsightsSampler(0.5f); + Assert.NotNull(pointFiveSampler); - ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(0f); - Assert.NotNull(zeroSampler); + ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(0f); + Assert.NotNull(zeroSampler); - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1f); - Assert.NotNull(oneSampler); - } + ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1f); + Assert.NotNull(oneSampler); + } - [Fact] - public void ApplicationInsightsSamplerBadArgs() - { - Assert.Throws(() => new ApplicationInsightsSampler(-2f)); - Assert.Throws(() => new ApplicationInsightsSampler(2f)); - } + [Fact] + public void ApplicationInsightsSamplerBadArgs() + { + Assert.Throws(() => new ApplicationInsightsSampler(-2f)); + Assert.Throws(() => new ApplicationInsightsSampler(2f)); + } - [Fact] - public void GetDescriptionMatchesSpec() - { - var expectedDescription = "ApplicationInsightsSampler{0.5}"; - Assert.Equal(expectedDescription, new ApplicationInsightsSampler(0.5f).Description); - } + [Fact] + public void GetDescriptionMatchesSpec() + { + var expectedDescription = "ApplicationInsightsSampler{0.5}"; + Assert.Equal(expectedDescription, new ApplicationInsightsSampler(0.5f).Description); } } From 2c3d15d40af2c6fc65105d980c743e3699b30ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Sat, 20 Aug 2022 02:28:47 +0200 Subject: [PATCH 0297/1499] nit: fir name for action in dotnet format workflow (#594) --- .github/workflows/dotnet-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 472fc5f686..156989f90f 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -20,7 +20,7 @@ jobs: - name: check out code uses: actions/checkout@v3 - - name: Setup .NET Core 6.0 + - name: Setup .NET 6.0 uses: actions/setup-dotnet@v2 with: dotnet-version: 6.0.x From b645248eb193c0f26aa01a19c0b068c4a91f62b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 22 Aug 2022 20:13:31 +0200 Subject: [PATCH 0298/1499] [Exporter.Instana] File scoped namespace (#597) --- .../IInstanaExporterHelper.cs | 11 +- .../Implementation/ISpanSender.cs | 9 +- .../Implementation/InstanaSpan.cs | 81 ++-- .../Implementation/InstanaSpanFactory.cs | 27 +- .../Implementation/InstanaSpanSerializer.cs | 401 +++++++++--------- .../InstanaSpanTransformInfo.cs | 15 +- .../Processors/ActivityProcessorBase.cs | 43 +- .../Processors/DefaultActivityProcessor.cs | 175 ++++---- .../Processors/ErrorActivityProcessor.cs | 43 +- .../Processors/EventsActivityProcessor.cs | 47 +- .../Processors/IActivityProcessor.cs | 11 +- .../Processors/TagsActivityProcessor.cs | 57 ++- .../Implementation/SpanSender.cs | 55 ++- .../Implementation/Transport.cs | 215 +++++----- .../InstanaExporter.cs | 249 ++++++----- .../InstanaExporterConstants.cs | 53 ++- .../InstanaExporterHelper.cs | 19 +- .../TracerProviderBuilderExtensions.cs | 31 +- .../InstanaExporterTests.cs | 235 +++++----- .../InstanaSpanFactoryTests.cs | 29 +- .../InstanaSpanSerializerTests.cs | 131 +++--- .../InstanaSpanTest.cs | 149 ++++--- .../DefaultActivityProcessorTests.cs | 47 +- .../Processors/ErrorActivityProcessorTests.cs | 67 ++- .../EventsActivityProcessorTests.cs | 65 ++- .../Processors/TagsActivityProcessorTests.cs | 73 ++-- 26 files changed, 1156 insertions(+), 1182 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs index 2784c9deb6..e2045e1932 100644 --- a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs +++ b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs @@ -17,12 +17,11 @@ using System.Diagnostics; using OpenTelemetry.Resources; -namespace OpenTelemetry.Exporter.Instana +namespace OpenTelemetry.Exporter.Instana; + +internal interface IInstanaExporterHelper { - internal interface IInstanaExporterHelper - { - bool IsWindows(); + bool IsWindows(); - Resource GetParentProviderResource(BaseExporter otelExporter); - } + Resource GetParentProviderResource(BaseExporter otelExporter); } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs index 61b6bff763..3cc30898d1 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs @@ -14,10 +14,9 @@ // limitations under the License. // -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal interface ISpanSender { - internal interface ISpanSender - { - void Enqueue(InstanaSpan instanaSpan); - } + void Enqueue(InstanaSpan instanaSpan); } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs index 81cda404e9..4bee9a0549 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs @@ -16,83 +16,82 @@ using System.Collections.Generic; -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal enum SpanKind { - internal enum SpanKind - { #pragma warning disable SA1602 // Enumeration items should be documented - ENTRY, + ENTRY, #pragma warning restore SA1602 // Enumeration items should be documented #pragma warning disable SA1602 // Enumeration items should be documented - EXIT, + EXIT, #pragma warning restore SA1602 // Enumeration items should be documented #pragma warning disable SA1602 // Enumeration items should be documented - INTERMEDIATE, + INTERMEDIATE, #pragma warning restore SA1602 // Enumeration items should be documented #pragma warning disable SA1602 // Enumeration items should be documented - NOT_SET, + NOT_SET, #pragma warning restore SA1602 // Enumeration items should be documented - } +} - internal class InstanaSpan - { - public InstanaSpanTransformInfo TransformInfo { get; set; } +internal class InstanaSpan +{ + public InstanaSpanTransformInfo TransformInfo { get; set; } - public string N { get; internal set; } + public string N { get; internal set; } - public string T { get; internal set; } + public string T { get; internal set; } - public string Lt { get; internal set; } + public string Lt { get; internal set; } - public From F { get; internal set; } + public From F { get; internal set; } - public string P { get; internal set; } + public string P { get; internal set; } - public string S { get; internal set; } + public string S { get; internal set; } - public SpanKind K { get; internal set; } + public SpanKind K { get; internal set; } - public Data Data { get; internal set; } + public Data Data { get; internal set; } - public long Ts { get; internal set; } + public long Ts { get; internal set; } - public long D { get; internal set; } + public long D { get; internal set; } - public bool Tp { get; internal set; } + public bool Tp { get; internal set; } - public int Ec { get; internal set; } - } + public int Ec { get; internal set; } +} #pragma warning disable SA1402 // File may only contain a single type - internal class From +internal class From #pragma warning restore SA1402 // File may only contain a single type - { - public string E { get; internal set; } +{ + public string E { get; internal set; } - public string H { get; internal set; } - } + public string H { get; internal set; } +} #pragma warning disable SA1402 // File may only contain a single type - internal class Data +internal class Data #pragma warning restore SA1402 // File may only contain a single type - { +{ #pragma warning disable SA1300 // Element should begin with upper-case letter - public Dictionary data { get; internal set; } + public Dictionary data { get; internal set; } #pragma warning restore SA1300 // Element should begin with upper-case letter - public Dictionary Tags { get; internal set; } + public Dictionary Tags { get; internal set; } - public List Events { get; internal set; } - } + public List Events { get; internal set; } +} #pragma warning disable SA1402 // File may only contain a single type - internal class SpanEvent +internal class SpanEvent #pragma warning restore SA1402 // File may only contain a single type - { - public string Name { get; internal set; } +{ + public string Name { get; internal set; } - public long Ts { get; internal set; } + public long Ts { get; internal set; } - public Dictionary Tags { get; internal set; } - } + public Dictionary Tags { get; internal set; } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs index 71b7ec5d40..5f9c1b70ff 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs @@ -15,25 +15,24 @@ // using System.Collections.Generic; -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal class InstanaSpanFactory { - internal class InstanaSpanFactory + internal static InstanaSpan CreateSpan() { - internal static InstanaSpan CreateSpan() + InstanaSpan instanaSpan = new InstanaSpan { - InstanaSpan instanaSpan = new InstanaSpan + Data = new Data() { - Data = new Data() - { - data = new Dictionary(), - Tags = new Dictionary(), - Events = new List(8), - }, + data = new Dictionary(), + Tags = new Dictionary(), + Events = new List(8), + }, - TransformInfo = new InstanaSpanTransformInfo(), - }; + TransformInfo = new InstanaSpanTransformInfo(), + }; - return instanaSpan; - } + return instanaSpan; } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 91fc38ca92..55ca75cb51 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -20,261 +20,260 @@ using System.IO; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal class InstanaSpanSerializer { - internal class InstanaSpanSerializer - { #pragma warning disable SA1310 // Field names should not contain underscore - private const string COMMA = ","; - private const string OPEN_BRACE = "{"; - private const string CLOSE_BRACE = "}"; - private const string QUOTE = "\""; - private const string COLON = ":"; - private const string QUOTE_COLON = QUOTE + COLON; - private const string QUOTE_COLON_QUOTE = QUOTE + COLON + QUOTE; - private const string QUOTE_COMMA_QUOTE = QUOTE + COMMA + QUOTE; + private const string COMMA = ","; + private const string OPEN_BRACE = "{"; + private const string CLOSE_BRACE = "}"; + private const string QUOTE = "\""; + private const string COLON = ":"; + private const string QUOTE_COLON = QUOTE + COLON; + private const string QUOTE_COLON_QUOTE = QUOTE + COLON + QUOTE; + private const string QUOTE_COMMA_QUOTE = QUOTE + COMMA + QUOTE; #pragma warning restore SA1310 // Field names should not contain underscore - private static readonly long UnixZeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks; - - internal IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan) - { - return instanaSpan.Data.Tags.GetEnumerator(); - } - - internal IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) - { - return instanaSpan.Data.Events.GetEnumerator(); - } + private static readonly long UnixZeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks; - internal async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) - { - await writer.WriteAsync(OPEN_BRACE); - await this.AppendProperty(instanaSpan.T, "t", writer); - await writer.WriteAsync(COMMA); - await this.AppendProperty(instanaSpan.S, "s", writer); - await writer.WriteAsync(COMMA); - - if (!string.IsNullOrEmpty(instanaSpan.P)) - { - await this.AppendProperty(instanaSpan.P, "p", writer); - await writer.WriteAsync(COMMA); - } - - if (!string.IsNullOrEmpty(instanaSpan.Lt)) - { - await this.AppendProperty(instanaSpan.Lt, "lt", writer); - await writer.WriteAsync(COMMA); - } + internal IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan) + { + return instanaSpan.Data.Tags.GetEnumerator(); + } - if (instanaSpan.Tp) - { - await this.AppendProperty(true.ToString().ToLower(), "tp", writer); - await writer.WriteAsync(COMMA); - } + internal IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) + { + return instanaSpan.Data.Events.GetEnumerator(); + } - if (instanaSpan.K != SpanKind.NOT_SET) - { - await this.AppendProperty((((int)instanaSpan.K) + 1).ToString(), "k", writer); - await writer.WriteAsync(COMMA); - } + internal async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await writer.WriteAsync(OPEN_BRACE); + await this.AppendProperty(instanaSpan.T, "t", writer); + await writer.WriteAsync(COMMA); + await this.AppendProperty(instanaSpan.S, "s", writer); + await writer.WriteAsync(COMMA); - await this.AppendProperty(instanaSpan.N, "n", writer); - await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer); - await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync((long)(instanaSpan.D / 10_000), "d", writer); - await writer.WriteAsync(COMMA); - await this.AppendObjectAsync(this.SerializeDataAsync, "data", instanaSpan, writer); - await writer.WriteAsync(COMMA); - await this.AppendObjectAsync(SerializeFromAsync, "f", instanaSpan, writer); + if (!string.IsNullOrEmpty(instanaSpan.P)) + { + await this.AppendProperty(instanaSpan.P, "p", writer); await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync(instanaSpan.Ec, "ec", writer); - await writer.WriteAsync(CLOSE_BRACE); } - private static async Task SerializeFromAsync(InstanaSpan instanaSpan, StreamWriter writer) + if (!string.IsNullOrEmpty(instanaSpan.Lt)) { - await writer.WriteAsync("{\"e\":\""); - await writer.WriteAsync(instanaSpan.F.E); - await writer.WriteAsync("\"}"); + await this.AppendProperty(instanaSpan.Lt, "lt", writer); + await writer.WriteAsync(COMMA); } - private static long DateToUnixMillis(long timeStamp) + if (instanaSpan.Tp) { - return (timeStamp - UnixZeroTime) / 10000; + await this.AppendProperty(true.ToString().ToLower(), "tp", writer); + await writer.WriteAsync(COMMA); } - private static async Task SerializeTagsAsync(InstanaSpan instanaSpan, StreamWriter writer) + if (instanaSpan.K != SpanKind.NOT_SET) { - await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer); + await this.AppendProperty((((int)instanaSpan.K) + 1).ToString(), "k", writer); + await writer.WriteAsync(COMMA); } - private static async Task SerializeTagsLogicAsync(Dictionary tags, StreamWriter writer) + await this.AppendProperty(instanaSpan.N, "n", writer); + await writer.WriteAsync(COMMA); + await this.AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer); + await writer.WriteAsync(COMMA); + await this.AppendPropertyAsync((long)(instanaSpan.D / 10_000), "d", writer); + await writer.WriteAsync(COMMA); + await this.AppendObjectAsync(this.SerializeDataAsync, "data", instanaSpan, writer); + await writer.WriteAsync(COMMA); + await this.AppendObjectAsync(SerializeFromAsync, "f", instanaSpan, writer); + await writer.WriteAsync(COMMA); + await this.AppendPropertyAsync(instanaSpan.Ec, "ec", writer); + await writer.WriteAsync(CLOSE_BRACE); + } + + private static async Task SerializeFromAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await writer.WriteAsync("{\"e\":\""); + await writer.WriteAsync(instanaSpan.F.E); + await writer.WriteAsync("\"}"); + } + + private static long DateToUnixMillis(long timeStamp) + { + return (timeStamp - UnixZeroTime) / 10000; + } + + private static async Task SerializeTagsAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer); + } + + private static async Task SerializeTagsLogicAsync(Dictionary tags, StreamWriter writer) + { + await writer.WriteAsync(OPEN_BRACE); + using (var enumerator = tags.GetEnumerator()) { - await writer.WriteAsync(OPEN_BRACE); - using (var enumerator = tags.GetEnumerator()) + byte i = 0; + try { - byte i = 0; - try + while (enumerator.MoveNext()) { - while (enumerator.MoveNext()) + if (i > 0) { - if (i > 0) - { - await writer.WriteAsync(COMMA); - } - else - { - i = 1; - } - - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(enumerator.Current.Key); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(enumerator.Current.Value); - await writer.WriteAsync(QUOTE); + await writer.WriteAsync(COMMA); } - } - catch (InvalidOperationException) - { - // if the collection gets modified while serializing, we might get a collision. - // There is no good way of preventing this and continuing normally except locking - // which needs investigation + else + { + i = 1; + } + + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(enumerator.Current.Key); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(enumerator.Current.Value); + await writer.WriteAsync(QUOTE); } } - - await writer.WriteAsync(CLOSE_BRACE); + catch (InvalidOperationException) + { + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation + } } - private async Task AppendProperty(string value, string name, StreamWriter json) - { - await json.WriteAsync(QUOTE); - await json.WriteAsync(name); - await json.WriteAsync(QUOTE_COLON_QUOTE); - await json.WriteAsync(value); - await json.WriteAsync(QUOTE); - } + await writer.WriteAsync(CLOSE_BRACE); + } - private async Task AppendPropertyAsync(long value, string name, StreamWriter json) - { - await json.WriteAsync(QUOTE); - await json.WriteAsync(name); - await json.WriteAsync(QUOTE_COLON); - await json.WriteAsync(value.ToString()); - } + private async Task AppendProperty(string value, string name, StreamWriter json) + { + await json.WriteAsync(QUOTE); + await json.WriteAsync(name); + await json.WriteAsync(QUOTE_COLON_QUOTE); + await json.WriteAsync(value); + await json.WriteAsync(QUOTE); + } - private async Task AppendObjectAsync(Func valueFunction, string name, InstanaSpan instanaSpan, StreamWriter json) - { - await json.WriteAsync(QUOTE); - await json.WriteAsync(name); - await json.WriteAsync(QUOTE_COLON); - await valueFunction(instanaSpan, json); - } + private async Task AppendPropertyAsync(long value, string name, StreamWriter json) + { + await json.WriteAsync(QUOTE); + await json.WriteAsync(name); + await json.WriteAsync(QUOTE_COLON); + await json.WriteAsync(value.ToString()); + } + + private async Task AppendObjectAsync(Func valueFunction, string name, InstanaSpan instanaSpan, StreamWriter json) + { + await json.WriteAsync(QUOTE); + await json.WriteAsync(name); + await json.WriteAsync(QUOTE_COLON); + await valueFunction(instanaSpan, json); + } - private async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writer) + private async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + await writer.WriteAsync(OPEN_BRACE); + using (var enumerator = instanaSpan.Data.data.GetEnumerator()) { - await writer.WriteAsync(OPEN_BRACE); - using (var enumerator = instanaSpan.Data.data.GetEnumerator()) + byte i = 0; + try { - byte i = 0; - try + while (enumerator.MoveNext()) { - while (enumerator.MoveNext()) + if (i > 0) { - if (i > 0) - { - await writer.WriteAsync(COMMA); - } - else - { - i = 1; - } - - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(enumerator.Current.Key); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(enumerator.Current.Value.ToString()); - await writer.WriteAsync(QUOTE); + await writer.WriteAsync(COMMA); } - } - catch (InvalidOperationException) - { - // if the collection gets modified while serializing, we might get a collision. - // There is no good way of preventing this and continuing normally except locking - // which needs investigation + else + { + i = 1; + } + + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(enumerator.Current.Key); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(enumerator.Current.Value.ToString()); + await writer.WriteAsync(QUOTE); } } - - if (instanaSpan.Data.Tags?.Count > 0) + catch (InvalidOperationException) { - await writer.WriteAsync(COMMA); - - // serialize tags - await this.AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer); + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation } + } - if (instanaSpan.Data.Events?.Count > 0) - { - await writer.WriteAsync(COMMA); + if (instanaSpan.Data.Tags?.Count > 0) + { + await writer.WriteAsync(COMMA); - // serialize tags - await this.AppendObjectAsync(this.SerializeEventsAsync, InstanaExporterConstants.EVENTS_FIELD, instanaSpan, writer); - } + // serialize tags + await this.AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer); + } + + if (instanaSpan.Data.Events?.Count > 0) + { + await writer.WriteAsync(COMMA); - await writer.WriteAsync(CLOSE_BRACE); + // serialize tags + await this.AppendObjectAsync(this.SerializeEventsAsync, InstanaExporterConstants.EVENTS_FIELD, instanaSpan, writer); } - private async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer) + await writer.WriteAsync(CLOSE_BRACE); + } + + private async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer) + { + using (var enumerator = instanaSpan.Data.Events.GetEnumerator()) { - using (var enumerator = instanaSpan.Data.Events.GetEnumerator()) + byte i = 0; + try { - byte i = 0; - try + await writer.WriteAsync("["); + while (enumerator.MoveNext()) { - await writer.WriteAsync("["); - while (enumerator.MoveNext()) + if (i > 0) + { + await writer.WriteAsync(COMMA); + } + else + { + i = 1; + } + + await writer.WriteAsync(OPEN_BRACE); + await writer.WriteAsync(QUOTE); + await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(enumerator.Current.Name); + await writer.WriteAsync(QUOTE_COMMA_QUOTE); + await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD); + await writer.WriteAsync(QUOTE_COLON_QUOTE); + await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString()); + await writer.WriteAsync(QUOTE); + + if (enumerator.Current.Tags?.Count > 0) { - if (i > 0) - { - await writer.WriteAsync(COMMA); - } - else - { - i = 1; - } - - await writer.WriteAsync(OPEN_BRACE); + await writer.WriteAsync(COMMA); await writer.WriteAsync(QUOTE); - await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(enumerator.Current.Name); - await writer.WriteAsync(QUOTE_COMMA_QUOTE); - await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString()); + await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD); await writer.WriteAsync(QUOTE); - - if (enumerator.Current.Tags?.Count > 0) - { - await writer.WriteAsync(COMMA); - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD); - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(COLON); - await SerializeTagsLogicAsync(enumerator.Current.Tags, writer); - } - - await writer.WriteAsync(CLOSE_BRACE); + await writer.WriteAsync(COLON); + await SerializeTagsLogicAsync(enumerator.Current.Tags, writer); } - await writer.WriteAsync("]"); - } - catch (InvalidOperationException) - { - // if the collection gets modified while serializing, we might get a collision. - // There is no good way of preventing this and continuing normally except locking - // which needs investigation + await writer.WriteAsync(CLOSE_BRACE); } + + await writer.WriteAsync("]"); + } + catch (InvalidOperationException) + { + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs index 3579ba28d8..6ca12066cd 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs @@ -14,16 +14,15 @@ // limitations under the License. // -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal class InstanaSpanTransformInfo { - internal class InstanaSpanTransformInfo - { - public string StatusCode { get; internal set; } + public string StatusCode { get; internal set; } - public string StatusDesc { get; internal set; } + public string StatusDesc { get; internal set; } - public bool HasExceptionEvent { get; internal set; } + public bool HasExceptionEvent { get; internal set; } - public bool IsEntrySpan { get; internal set; } - } + public bool IsEntrySpan { get; internal set; } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs index 159fb97043..237df5d77c 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -18,36 +18,35 @@ using System.Diagnostics; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; + +internal abstract class ActivityProcessorBase : IActivityProcessor { - internal abstract class ActivityProcessorBase : IActivityProcessor - { - public IActivityProcessor NextProcessor { get; set; } + public IActivityProcessor NextProcessor { get; set; } - public virtual async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + public virtual async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + if (this.NextProcessor != null) { - if (this.NextProcessor != null) - { - await this.NextProcessor.ProcessAsync(activity, instanaSpan); - } + await this.NextProcessor.ProcessAsync(activity, instanaSpan); } + } - protected virtual void PreProcess(Activity activity, InstanaSpan instanaSpan) + protected virtual void PreProcess(Activity activity, InstanaSpan instanaSpan) + { + if (instanaSpan.TransformInfo == null) { - if (instanaSpan.TransformInfo == null) - { - instanaSpan.TransformInfo = new InstanaSpanTransformInfo(); - } + instanaSpan.TransformInfo = new InstanaSpanTransformInfo(); + } - if (instanaSpan.Data == null) + if (instanaSpan.Data == null) + { + instanaSpan.Data = new Data() { - instanaSpan.Data = new Data() - { - data = new Dictionary(), - Events = new List(8), - Tags = new Dictionary(), - }; - } + data = new Dictionary(), + Events = new List(8), + Tags = new Dictionary(), + }; } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs index 467002398e..f4d5a70345 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -18,114 +18,113 @@ using System.Diagnostics; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; + +internal class DefaultActivityProcessor : ActivityProcessorBase, IActivityProcessor { - internal class DefaultActivityProcessor : ActivityProcessorBase, IActivityProcessor + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { - public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) - { - this.PreProcess(activity, instanaSpan); + this.PreProcess(activity, instanaSpan); - instanaSpan.N = InstanaExporterConstants.OTEL_SPAN_TYPE; + instanaSpan.N = InstanaExporterConstants.OTEL_SPAN_TYPE; - string traceId = activity.TraceId.ToHexString(); - if (traceId.Length == 32) - { - instanaSpan.T = traceId.Substring(16); - instanaSpan.Lt = traceId; - } - else - { - instanaSpan.T = traceId; - } - - bool hasParent = false; - string parentSpanId = activity.ParentSpanId.ToHexString(); - if (!string.IsNullOrEmpty(parentSpanId) && GetLongFromHex(parentSpanId) != 0) - { - hasParent = true; - instanaSpan.P = parentSpanId; - } + string traceId = activity.TraceId.ToHexString(); + if (traceId.Length == 32) + { + instanaSpan.T = traceId.Substring(16); + instanaSpan.Lt = traceId; + } + else + { + instanaSpan.T = traceId; + } - instanaSpan.S = activity.SpanId.ToHexString(); - instanaSpan.K = GetSpanKind(activity.Kind); + bool hasParent = false; + string parentSpanId = activity.ParentSpanId.ToHexString(); + if (!string.IsNullOrEmpty(parentSpanId) && GetLongFromHex(parentSpanId) != 0) + { + hasParent = true; + instanaSpan.P = parentSpanId; + } - instanaSpan.Ts = activity.StartTimeUtc.Ticks; - instanaSpan.D = activity.Duration.Ticks; + instanaSpan.S = activity.SpanId.ToHexString(); + instanaSpan.K = GetSpanKind(activity.Kind); - SetKind(activity, instanaSpan); + instanaSpan.Ts = activity.StartTimeUtc.Ticks; + instanaSpan.D = activity.Duration.Ticks; - if (hasParent && instanaSpan.TransformInfo.IsEntrySpan) - { - // If an OTel entry span continues an ongoing trace (which is equivalent to the original span having a parent), it - // always uses the IDs from the traceparent header, thus we mark the span with span.tp accordingly. - instanaSpan.Tp = true; - } + SetKind(activity, instanaSpan); - await base.ProcessAsync(activity, instanaSpan); + if (hasParent && instanaSpan.TransformInfo.IsEntrySpan) + { + // If an OTel entry span continues an ongoing trace (which is equivalent to the original span having a parent), it + // always uses the IDs from the traceparent header, thus we mark the span with span.tp accordingly. + instanaSpan.Tp = true; } - private static SpanKind GetSpanKind(ActivityKind activityKind) + await base.ProcessAsync(activity, instanaSpan); + } + + private static SpanKind GetSpanKind(ActivityKind activityKind) + { + switch (activityKind) { - switch (activityKind) - { - case ActivityKind.Consumer: - case ActivityKind.Server: - return SpanKind.ENTRY; - case ActivityKind.Client: - case ActivityKind.Producer: - return SpanKind.EXIT; - case ActivityKind.Internal: - return SpanKind.INTERMEDIATE; - default: - return SpanKind.NOT_SET; - } + case ActivityKind.Consumer: + case ActivityKind.Server: + return SpanKind.ENTRY; + case ActivityKind.Client: + case ActivityKind.Producer: + return SpanKind.EXIT; + case ActivityKind.Internal: + return SpanKind.INTERMEDIATE; + default: + return SpanKind.NOT_SET; } + } - private static long GetLongFromHex(string hexValue) + private static long GetLongFromHex(string hexValue) + { + if (!string.IsNullOrEmpty(hexValue)) { - if (!string.IsNullOrEmpty(hexValue)) + try { - try - { - string[] ids = hexValue.Split(','); - return Convert.ToInt64(ids[ids.Length - 1].Trim(), 16); - } - catch (Exception) - { - } + string[] ids = hexValue.Split(','); + return Convert.ToInt64(ids[ids.Length - 1].Trim(), 16); } - - return 0; - } - - private static void SetKind(Activity activity, InstanaSpan instanaSpan) - { - bool isEntrySpan = false; - switch (activity.Kind) + catch (Exception) { - case ActivityKind.Server: - isEntrySpan = true; - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.SERVER_KIND; - break; - case ActivityKind.Client: - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CLIENT_KIND; - break; - case ActivityKind.Producer: - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.PRODUCER_KIND; - break; - case ActivityKind.Consumer: - isEntrySpan = true; - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CONSUMER_KIND; - break; - case ActivityKind.Internal: - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.INTERNAL_KIND; - break; - default: - break; } + } + + return 0; + } - instanaSpan.TransformInfo.IsEntrySpan = isEntrySpan; + private static void SetKind(Activity activity, InstanaSpan instanaSpan) + { + bool isEntrySpan = false; + switch (activity.Kind) + { + case ActivityKind.Server: + isEntrySpan = true; + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.SERVER_KIND; + break; + case ActivityKind.Client: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CLIENT_KIND; + break; + case ActivityKind.Producer: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.PRODUCER_KIND; + break; + case ActivityKind.Consumer: + isEntrySpan = true; + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CONSUMER_KIND; + break; + case ActivityKind.Internal: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.INTERNAL_KIND; + break; + default: + break; } + + instanaSpan.TransformInfo.IsEntrySpan = isEntrySpan; } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs index 92ccf9b9c5..5c04e91584 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs @@ -17,33 +17,32 @@ using System.Diagnostics; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; + +internal class ErrorActivityProcessor : ActivityProcessorBase, IActivityProcessor { - internal class ErrorActivityProcessor : ActivityProcessorBase, IActivityProcessor + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { - public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) - { - this.PreProcess(activity, instanaSpan); + this.PreProcess(activity, instanaSpan); - if (activity.Status == ActivityStatusCode.Error) - { - instanaSpan.Ec = 1; - instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD] = activity.Status.ToString(); - if (!string.IsNullOrEmpty(activity.StatusDescription)) - { - instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD] = activity.StatusDescription; - } - } - else if (instanaSpan.TransformInfo.HasExceptionEvent) - { - instanaSpan.Ec = 1; - } - else + if (activity.Status == ActivityStatusCode.Error) + { + instanaSpan.Ec = 1; + instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD] = activity.Status.ToString(); + if (!string.IsNullOrEmpty(activity.StatusDescription)) { - instanaSpan.Ec = 0; + instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD] = activity.StatusDescription; } - - await base.ProcessAsync(activity, instanaSpan); } + else if (instanaSpan.TransformInfo.HasExceptionEvent) + { + instanaSpan.Ec = 1; + } + else + { + instanaSpan.Ec = 0; + } + + await base.ProcessAsync(activity, instanaSpan); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs index f8ddd63c20..d0e7bb7edb 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -18,40 +18,39 @@ using System.Diagnostics; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; + +internal class EventsActivityProcessor : ActivityProcessorBase, IActivityProcessor { - internal class EventsActivityProcessor : ActivityProcessorBase, IActivityProcessor + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { - public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) - { - this.PreProcess(activity, instanaSpan); + this.PreProcess(activity, instanaSpan); - foreach (var activityEvent in activity.Events) + foreach (var activityEvent in activity.Events) + { + if (activityEvent.Name == InstanaExporterConstants.EXCEPTION_FIELD) { - if (activityEvent.Name == InstanaExporterConstants.EXCEPTION_FIELD) - { - instanaSpan.TransformInfo.HasExceptionEvent = true; - } + instanaSpan.TransformInfo.HasExceptionEvent = true; + } - var spanEvent = new SpanEvent - { - Name = activityEvent.Name, - Ts = activityEvent.Timestamp.Ticks, - Tags = new Dictionary(), - }; + var spanEvent = new SpanEvent + { + Name = activityEvent.Name, + Ts = activityEvent.Timestamp.Ticks, + Tags = new Dictionary(), + }; - foreach (var eventTag in activityEvent.Tags) + foreach (var eventTag in activityEvent.Tags) + { + if (eventTag.Value != null) { - if (eventTag.Value != null) - { - spanEvent.Tags[eventTag.Key] = eventTag.Value.ToString(); - } + spanEvent.Tags[eventTag.Key] = eventTag.Value.ToString(); } - - instanaSpan.Data.Events.Add(spanEvent); } - await base.ProcessAsync(activity, instanaSpan); + instanaSpan.Data.Events.Add(spanEvent); } + + await base.ProcessAsync(activity, instanaSpan); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs index b935eefb57..81052f6da6 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs @@ -16,12 +16,11 @@ using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; + +internal interface IActivityProcessor { - internal interface IActivityProcessor - { - IActivityProcessor NextProcessor { get; set; } + IActivityProcessor NextProcessor { get; set; } - Task ProcessAsync(System.Diagnostics.Activity activity, InstanaSpan instanaSpan); - } + Task ProcessAsync(System.Diagnostics.Activity activity, InstanaSpan instanaSpan); } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs index 9707740a6e..1f868bdb30 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -18,42 +18,41 @@ using System.Diagnostics; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation.Processors +namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; + +internal class TagsActivityProcessor : ActivityProcessorBase, IActivityProcessor { - internal class TagsActivityProcessor : ActivityProcessorBase, IActivityProcessor + public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { - public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) - { - this.PreProcess(activity, instanaSpan); + this.PreProcess(activity, instanaSpan); - string statusCode = string.Empty; - string statusDesc = string.Empty; - Dictionary tags = new Dictionary(); - foreach (var tag in activity.Tags) + string statusCode = string.Empty; + string statusDesc = string.Empty; + Dictionary tags = new Dictionary(); + foreach (var tag in activity.Tags) + { + if (tag.Key == "otel.status_code") { - if (tag.Key == "otel.status_code") - { - statusCode = tag.Value as string; - continue; - } - - if (tag.Key == "otel.status_description") - { - statusDesc = tag.Value as string; - continue; - } - - if (tag.Value != null) - { - tags[tag.Key] = tag.Value.ToString(); - } + statusCode = tag.Value as string; + continue; } - instanaSpan.Data.Tags = tags; - instanaSpan.TransformInfo.StatusCode = statusCode; - instanaSpan.TransformInfo.StatusDesc = statusDesc; + if (tag.Key == "otel.status_description") + { + statusDesc = tag.Value as string; + continue; + } - await base.ProcessAsync(activity, instanaSpan); + if (tag.Value != null) + { + tags[tag.Key] = tag.Value.ToString(); + } } + + instanaSpan.Data.Tags = tags; + instanaSpan.TransformInfo.StatusCode = statusCode; + instanaSpan.TransformInfo.StatusDesc = statusDesc; + + await base.ProcessAsync(activity, instanaSpan); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index ee1216b56d..81596ecc3f 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -16,44 +16,43 @@ using System.Collections.Concurrent; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal class SpanSender : ISpanSender { - internal class SpanSender : ISpanSender + private readonly Task queueSenderTask; + private readonly Transport transport = new Transport(); + private readonly ConcurrentQueue spansQueue = new ConcurrentQueue(); + + public SpanSender() { - private readonly Task queueSenderTask; - private readonly Transport transport = new Transport(); - private readonly ConcurrentQueue spansQueue = new ConcurrentQueue(); + // create a task that will send a batch of spans every second at least + this.queueSenderTask = new Task(this.TaskSpanSender, TaskCreationOptions.LongRunning); + this.queueSenderTask.Start(); + } - public SpanSender() + public void Enqueue(InstanaSpan instanaSpan) + { + if (this.transport.IsAvailable) { - // create a task that will send a batch of spans every second at least - this.queueSenderTask = new Task(this.TaskSpanSender, TaskCreationOptions.LongRunning); - this.queueSenderTask.Start(); + this.spansQueue.Enqueue(instanaSpan); } + } - public void Enqueue(InstanaSpan instanaSpan) + private async void TaskSpanSender() + { + // this will be an infinite loop + while (true) { - if (this.transport.IsAvailable) + // check if we can send spans + if (this.spansQueue.TryPeek(out InstanaSpan dummySpan)) { - this.spansQueue.Enqueue(instanaSpan); + // actually send spans + await this.transport.SendSpansAsync(this.spansQueue); } - } - private async void TaskSpanSender() - { - // this will be an infinite loop - while (true) - { - // check if we can send spans - if (this.spansQueue.TryPeek(out InstanaSpan dummySpan)) - { - // actually send spans - await this.transport.SendSpansAsync(this.spansQueue); - } - - // rest for a while - await Task.Delay(1000); - } + // rest for a while + await Task.Delay(1000); } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index a8f5176305..49e4fd4bd9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -22,155 +22,154 @@ using System.Net.Http.Headers; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Instana.Implementation +namespace OpenTelemetry.Exporter.Instana.Implementation; + +internal class Transport { - internal class Transport - { - private static readonly InstanaSpanSerializer InstanaSpanSerializer = new InstanaSpanSerializer(); - private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); + private static readonly InstanaSpanSerializer InstanaSpanSerializer = new InstanaSpanSerializer(); + private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); - private static bool isConfigured = false; - private static int backendTimeout = 0; - private static string configuredEndpoint = string.Empty; - private static string configuredAgentKey = string.Empty; - private static string bundleUrl = string.Empty; - private static InstanaHttpClient client = null; + private static bool isConfigured = false; + private static int backendTimeout = 0; + private static string configuredEndpoint = string.Empty; + private static string configuredAgentKey = string.Empty; + private static string bundleUrl = string.Empty; + private static InstanaHttpClient client = null; - private readonly byte[] tracesBuffer = new byte[4096000]; + private readonly byte[] tracesBuffer = new byte[4096000]; - static Transport() - { - Configure(); - } + static Transport() + { + Configure(); + } - internal bool IsAvailable - { - get { return isConfigured && client != null; } - } + internal bool IsAvailable + { + get { return isConfigured && client != null; } + } - internal async Task SendSpansAsync(ConcurrentQueue spanQueue) + internal async Task SendSpansAsync(ConcurrentQueue spanQueue) + { + using (MemoryStream sendBuffer = new MemoryStream(this.tracesBuffer)) { - using (MemoryStream sendBuffer = new MemoryStream(this.tracesBuffer)) + using (StreamWriter writer = new StreamWriter(sendBuffer)) { - using (StreamWriter writer = new StreamWriter(sendBuffer)) + await writer.WriteAsync("{\"spans\":["); + bool first = true; + while (spanQueue.TryDequeue(out InstanaSpan span) && sendBuffer.Position < 4070000) { - await writer.WriteAsync("{\"spans\":["); - bool first = true; - while (spanQueue.TryDequeue(out InstanaSpan span) && sendBuffer.Position < 4070000) + if (!first) { - if (!first) - { - await writer.WriteAsync(","); - } - - first = false; - await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer); + await writer.WriteAsync(","); } - await writer.WriteAsync("]}"); + first = false; + await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer); + } - await writer.FlushAsync(); - long length = sendBuffer.Position; - sendBuffer.Position = 0; + await writer.WriteAsync("]}"); - HttpContent content = new StreamContent(sendBuffer, (int)length); - content.Headers.ContentType = MEDIAHEADER; - content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); + await writer.FlushAsync(); + long length = sendBuffer.Position; + sendBuffer.Position = 0; - using (var httpMsg = new HttpRequestMessage() - { - Method = HttpMethod.Post, - RequestUri = new Uri(bundleUrl), - }) - { - httpMsg.Content = content; - var res = client.SendAsync(httpMsg).GetAwaiter().GetResult(); - } + HttpContent content = new StreamContent(sendBuffer, (int)length); + content.Headers.ContentType = MEDIAHEADER; + content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); + + using (var httpMsg = new HttpRequestMessage() + { + Method = HttpMethod.Post, + RequestUri = new Uri(bundleUrl), + }) + { + httpMsg.Content = content; + var res = client.SendAsync(httpMsg).GetAwaiter().GetResult(); } } } + } - private static void Configure() + private static void Configure() + { + if (isConfigured) { - if (isConfigured) - { - return; - } + return; + } - if (string.IsNullOrEmpty(configuredEndpoint)) - { - configuredEndpoint = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_URL); - } + if (string.IsNullOrEmpty(configuredEndpoint)) + { + configuredEndpoint = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_URL); + } - if (string.IsNullOrEmpty(configuredEndpoint)) - { - return; - } + if (string.IsNullOrEmpty(configuredEndpoint)) + { + return; + } - bundleUrl = configuredEndpoint + "/bundle"; + bundleUrl = configuredEndpoint + "/bundle"; - if (string.IsNullOrEmpty(configuredAgentKey)) - { - configuredAgentKey = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_AGENT_KEY); - } + if (string.IsNullOrEmpty(configuredAgentKey)) + { + configuredAgentKey = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_AGENT_KEY); + } - if (string.IsNullOrEmpty(configuredAgentKey)) - { - return; - } + if (string.IsNullOrEmpty(configuredAgentKey)) + { + return; + } - if (backendTimeout == 0) + if (backendTimeout == 0) + { + if (!int.TryParse(Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_TIMEOUT), out backendTimeout)) { - if (!int.TryParse(Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_TIMEOUT), out backendTimeout)) - { - backendTimeout = InstanaExporterConstants.BACKEND_DEFAULT_TIMEOUT; - } + backendTimeout = InstanaExporterConstants.BACKEND_DEFAULT_TIMEOUT; } - - ConfigureBackendClient(); - isConfigured = true; } - private static void ConfigureBackendClient() + ConfigureBackendClient(); + isConfigured = true; + } + + private static void ConfigureBackendClient() + { + if (client != null) { - if (client != null) - { - return; - } + return; + } - var configuredHandler = new HttpClientHandler(); - string proxy = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_PROXY); - if (Uri.TryCreate(proxy, UriKind.Absolute, out Uri proxyAddress)) - { - configuredHandler.Proxy = new WebProxy(proxyAddress, true); - configuredHandler.UseProxy = true; + var configuredHandler = new HttpClientHandler(); + string proxy = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_PROXY); + if (Uri.TryCreate(proxy, UriKind.Absolute, out Uri proxyAddress)) + { + configuredHandler.Proxy = new WebProxy(proxyAddress, true); + configuredHandler.UseProxy = true; #pragma warning disable SA1130 // Use lambda syntax - configuredHandler.ServerCertificateCustomValidationCallback = delegate { return true; }; + configuredHandler.ServerCertificateCustomValidationCallback = delegate { return true; }; #pragma warning restore SA1130 // Use lambda syntax - } + } - client = new InstanaHttpClient(backendTimeout, configuredHandler); + client = new InstanaHttpClient(backendTimeout, configuredHandler); - client.DefaultRequestHeaders.Add("X-INSTANA-KEY", configuredAgentKey); - } + client.DefaultRequestHeaders.Add("X-INSTANA-KEY", configuredAgentKey); } +} #pragma warning disable SA1402 // File may only contain a single type - internal class InstanaHttpClient : HttpClient +internal class InstanaHttpClient : HttpClient #pragma warning restore SA1402 // File may only contain a single type +{ + public InstanaHttpClient(int timeout) + : base() { - public InstanaHttpClient(int timeout) - : base() - { - this.Timeout = TimeSpan.FromMilliseconds(timeout); - this.DefaultRequestHeaders.Add("X-INSTANA-NOTRACE", "1"); - } + this.Timeout = TimeSpan.FromMilliseconds(timeout); + this.DefaultRequestHeaders.Add("X-INSTANA-NOTRACE", "1"); + } - public InstanaHttpClient(int timeout, HttpClientHandler handler) - : base(handler) - { - this.Timeout = TimeSpan.FromMilliseconds(timeout); - this.DefaultRequestHeaders.Add("X-INSTANA-NOTRACE", "1"); - } + public InstanaHttpClient(int timeout, HttpClientHandler handler) + : base(handler) + { + this.Timeout = TimeSpan.FromMilliseconds(timeout); + this.DefaultRequestHeaders.Add("X-INSTANA-NOTRACE", "1"); } } diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index 6ff9e5254d..b9d5c44ac0 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -22,178 +22,177 @@ using OpenTelemetry.Exporter.Instana.Implementation.Processors; using OpenTelemetry.Resources; -namespace OpenTelemetry.Exporter.Instana +namespace OpenTelemetry.Exporter.Instana; + +internal class InstanaExporter : BaseExporter { - internal class InstanaExporter : BaseExporter + private readonly IActivityProcessor activityProcessor; + private string name; + private ISpanSender spanSender = new SpanSender(); + private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); + private bool shutdownCalled = false; + + public InstanaExporter(string name = "InstanaExporter", IActivityProcessor activityProcessor = null) { - private readonly IActivityProcessor activityProcessor; - private string name; - private ISpanSender spanSender = new SpanSender(); - private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); - private bool shutdownCalled = false; + this.name = name; - public InstanaExporter(string name = "InstanaExporter", IActivityProcessor activityProcessor = null) + if (activityProcessor != null) { - this.name = name; - - if (activityProcessor != null) - { - this.activityProcessor = activityProcessor; - } - else + this.activityProcessor = activityProcessor; + } + else + { + this.activityProcessor = new DefaultActivityProcessor { - this.activityProcessor = new DefaultActivityProcessor + NextProcessor = new TagsActivityProcessor { - NextProcessor = new TagsActivityProcessor + NextProcessor = new EventsActivityProcessor { - NextProcessor = new EventsActivityProcessor - { - NextProcessor = new ErrorActivityProcessor(), - }, + NextProcessor = new ErrorActivityProcessor(), }, - }; - } + }, + }; } + } - internal ISpanSender SpanSender - { - get { return this.spanSender; } - set { this.spanSender = value; } - } + internal ISpanSender SpanSender + { + get { return this.spanSender; } + set { this.spanSender = value; } + } - internal IInstanaExporterHelper InstanaExporterHelper + internal IInstanaExporterHelper InstanaExporterHelper + { + get { return this.instanaExporterHelper; } + set { this.instanaExporterHelper = value; } + } + + public override ExportResult Export(in Batch batch) + { + if (this.shutdownCalled) { - get { return this.instanaExporterHelper; } - set { this.instanaExporterHelper = value; } + return ExportResult.Failure; } - public override ExportResult Export(in Batch batch) + From from = null; + if (this.instanaExporterHelper.IsWindows()) { - if (this.shutdownCalled) - { - return ExportResult.Failure; - } - - From from = null; - if (this.instanaExporterHelper.IsWindows()) - { - from = new From() { E = Process.GetCurrentProcess().Id.ToString() }; - } + from = new From() { E = Process.GetCurrentProcess().Id.ToString() }; + } - string serviceName = this.ExtractServiceName(ref from); + string serviceName = this.ExtractServiceName(ref from); - foreach (var activity in batch) + foreach (var activity in batch) + { + if (activity == null) { - if (activity == null) - { - continue; - } - - InstanaSpan span = this.ParseActivityAsync(activity, serviceName, from).Result; - this.spanSender.Enqueue(span); + continue; } - return ExportResult.Success; + InstanaSpan span = this.ParseActivityAsync(activity, serviceName, from).Result; + this.spanSender.Enqueue(span); } - protected override bool OnShutdown(int timeoutMilliseconds) + return ExportResult.Success; + } + + protected override bool OnShutdown(int timeoutMilliseconds) + { + if (!this.shutdownCalled) { - if (!this.shutdownCalled) - { - this.shutdownCalled = true; - return true; - } - else - { - return false; - } + this.shutdownCalled = true; + return true; } - - protected override bool OnForceFlush(int timeoutMilliseconds) + else { - return base.OnForceFlush(timeoutMilliseconds); + return false; } + } + + protected override bool OnForceFlush(int timeoutMilliseconds) + { + return base.OnForceFlush(timeoutMilliseconds); + } - private string ExtractServiceName(ref From from) + private string ExtractServiceName(ref From from) + { + string serviceName = null; + string serviceId = null; + string processId = null; + string hostId = null; + var resource = this.instanaExporterHelper.GetParentProviderResource(this); + if (resource != Resource.Empty && resource.Attributes?.Count() > 0) { - string serviceName = null; - string serviceId = null; - string processId = null; - string hostId = null; - var resource = this.instanaExporterHelper.GetParentProviderResource(this); - if (resource != Resource.Empty && resource.Attributes?.Count() > 0) + foreach (var resourceAttribute in resource.Attributes) { - foreach (var resourceAttribute in resource.Attributes) + if (resourceAttribute.Key.Equals("service.name", StringComparison.OrdinalIgnoreCase) + && resourceAttribute.Value is string servName + && !string.IsNullOrEmpty(servName)) + { + serviceName = servName; + } + + if (from == null) { - if (resourceAttribute.Key.Equals("service.name", StringComparison.OrdinalIgnoreCase) - && resourceAttribute.Value is string servName - && !string.IsNullOrEmpty(servName)) + if (resourceAttribute.Key.Equals("service.instance.id", StringComparison.OrdinalIgnoreCase)) { - serviceName = servName; + serviceId = resourceAttribute.Value.ToString(); } - - if (from == null) + else if (resourceAttribute.Key.Equals("process.pid", StringComparison.OrdinalIgnoreCase)) { - if (resourceAttribute.Key.Equals("service.instance.id", StringComparison.OrdinalIgnoreCase)) - { - serviceId = resourceAttribute.Value.ToString(); - } - else if (resourceAttribute.Key.Equals("process.pid", StringComparison.OrdinalIgnoreCase)) - { - processId = resourceAttribute.Value.ToString(); - } - else if (resourceAttribute.Key.Equals("host.id", StringComparison.OrdinalIgnoreCase)) - { - hostId = resourceAttribute.Value.ToString(); - } + processId = resourceAttribute.Value.ToString(); + } + else if (resourceAttribute.Key.Equals("host.id", StringComparison.OrdinalIgnoreCase)) + { + hostId = resourceAttribute.Value.ToString(); } } } - - if (from == null) - { - from = new From(); - if (!string.IsNullOrEmpty(processId)) - { - from.E = processId; - } - else if (!string.IsNullOrEmpty(serviceId)) - { - from.E = serviceId; - } - - if (!string.IsNullOrEmpty(hostId)) - { - from.H = hostId; - } - } - - return serviceName; } - private async Task ParseActivityAsync(Activity activity, string serviceName = null, From from = null) + if (from == null) { - InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); - - await this.activityProcessor.ProcessAsync(activity, instanaSpan); - - if (!string.IsNullOrEmpty(serviceName)) + from = new From(); + if (!string.IsNullOrEmpty(processId)) { - instanaSpan.Data.data[InstanaExporterConstants.SERVICE_FIELD] = serviceName; + from.E = processId; } - - instanaSpan.Data.data[InstanaExporterConstants.OPERATION_FIELD] = activity.DisplayName; - if (!string.IsNullOrEmpty(activity.TraceStateString)) + else if (!string.IsNullOrEmpty(serviceId)) { - instanaSpan.Data.data[InstanaExporterConstants.TRACE_STATE_FIELD] = activity.TraceStateString; + from.E = serviceId; } - if (from != null) + if (!string.IsNullOrEmpty(hostId)) { - instanaSpan.F = from; + from.H = hostId; } + } + + return serviceName; + } + + private async Task ParseActivityAsync(Activity activity, string serviceName = null, From from = null) + { + InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); - return instanaSpan; + await this.activityProcessor.ProcessAsync(activity, instanaSpan); + + if (!string.IsNullOrEmpty(serviceName)) + { + instanaSpan.Data.data[InstanaExporterConstants.SERVICE_FIELD] = serviceName; + } + + instanaSpan.Data.data[InstanaExporterConstants.OPERATION_FIELD] = activity.DisplayName; + if (!string.IsNullOrEmpty(activity.TraceStateString)) + { + instanaSpan.Data.data[InstanaExporterConstants.TRACE_STATE_FIELD] = activity.TraceStateString; } + + if (from != null) + { + instanaSpan.F = from; + } + + return instanaSpan; } } diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs index d2b1c417f8..a427353318 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs @@ -14,35 +14,34 @@ // limitations under the License. // -namespace OpenTelemetry.Exporter.Instana +namespace OpenTelemetry.Exporter.Instana; + +internal class InstanaExporterConstants { - internal class InstanaExporterConstants - { #pragma warning disable SA1310 // Field names should not contain underscore - internal const string OTEL_SPAN_TYPE = "otel"; - internal const string KIND_FIELD = "kind"; - internal const string SERVER_KIND = "server"; - internal const string CLIENT_KIND = "client"; - internal const string PRODUCER_KIND = "producer"; - internal const string CONSUMER_KIND = "consumer"; - internal const string INTERNAL_KIND = "internal"; - internal const string SERVICE_FIELD = "service"; - internal const string OPERATION_FIELD = "operation"; - internal const string TRACE_STATE_FIELD = "trace_state"; - internal const string ERROR_FIELD = "error"; - internal const string ERROR_DETAIL_FIELD = "error_detail"; - internal const string EXCEPTION_FIELD = "exception"; - internal const string TAGS_FIELD = "tags"; - internal const string EVENTS_FIELD = "events"; - internal const string EVENT_NAME_FIELD = "name"; - internal const string EVENT_TIMESTAMP_FIELD = "ts"; + internal const string OTEL_SPAN_TYPE = "otel"; + internal const string KIND_FIELD = "kind"; + internal const string SERVER_KIND = "server"; + internal const string CLIENT_KIND = "client"; + internal const string PRODUCER_KIND = "producer"; + internal const string CONSUMER_KIND = "consumer"; + internal const string INTERNAL_KIND = "internal"; + internal const string SERVICE_FIELD = "service"; + internal const string OPERATION_FIELD = "operation"; + internal const string TRACE_STATE_FIELD = "trace_state"; + internal const string ERROR_FIELD = "error"; + internal const string ERROR_DETAIL_FIELD = "error_detail"; + internal const string EXCEPTION_FIELD = "exception"; + internal const string TAGS_FIELD = "tags"; + internal const string EVENTS_FIELD = "events"; + internal const string EVENT_NAME_FIELD = "name"; + internal const string EVENT_TIMESTAMP_FIELD = "ts"; - internal const string ENVVAR_INSTANA_ENDPOINT_URL = "INSTANA_ENDPOINT_URL"; - internal const string ENVVAR_INSTANA_AGENT_KEY = "INSTANA_AGENT_KEY"; - internal const string ENVVAR_INSTANA_TIMEOUT = "INSTANA_TIMEOUT"; - internal const int BACKEND_DEFAULT_TIMEOUT = 20000; - internal const string ENVVAR_INSTANA_EXTRA_HTTP_HEADERS = "INSTANA_EXTRA_HTTP_HEADERS"; - internal const string ENVVAR_INSTANA_ENDPOINT_PROXY = "INSTANA_ENDPOINT_PROXY"; + internal const string ENVVAR_INSTANA_ENDPOINT_URL = "INSTANA_ENDPOINT_URL"; + internal const string ENVVAR_INSTANA_AGENT_KEY = "INSTANA_AGENT_KEY"; + internal const string ENVVAR_INSTANA_TIMEOUT = "INSTANA_TIMEOUT"; + internal const int BACKEND_DEFAULT_TIMEOUT = 20000; + internal const string ENVVAR_INSTANA_EXTRA_HTTP_HEADERS = "INSTANA_EXTRA_HTTP_HEADERS"; + internal const string ENVVAR_INSTANA_ENDPOINT_PROXY = "INSTANA_ENDPOINT_PROXY"; #pragma warning restore SA1310 // Field names should not contain underscore - } } diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs index 3345bbfef7..bdfe5de79a 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs @@ -18,18 +18,17 @@ using System.Diagnostics; using OpenTelemetry.Resources; -namespace OpenTelemetry.Exporter.Instana +namespace OpenTelemetry.Exporter.Instana; + +internal class InstanaExporterHelper : IInstanaExporterHelper { - internal class InstanaExporterHelper : IInstanaExporterHelper + public Resource GetParentProviderResource(BaseExporter otelExporter) { - public Resource GetParentProviderResource(BaseExporter otelExporter) - { - return otelExporter.ParentProvider.GetResource(); - } + return otelExporter.ParentProvider.GetResource(); + } - public bool IsWindows() - { - return Environment.OSVersion.Platform == PlatformID.Win32NT; - } + public bool IsWindows() + { + return Environment.OSVersion.Platform == PlatformID.Win32NT; } } diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs index 62657261c0..a830904a4a 100644 --- a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -17,27 +17,26 @@ using System; using OpenTelemetry.Trace; -namespace OpenTelemetry.Exporter.Instana +namespace OpenTelemetry.Exporter.Instana; + +/// +/// Todo. +/// +public static class TracerProviderBuilderExtensions { /// - /// Todo. + /// Instana test provider builder extension. /// - public static class TracerProviderBuilderExtensions + /// Test provider builder. + /// todo. + /// Test provider builder is null. + public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilder options) { - /// - /// Instana test provider builder extension. - /// - /// Test provider builder. - /// todo. - /// Test provider builder is null. - public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilder options) + if (options == null) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - - return options.AddProcessor(new BatchActivityExportProcessor(new InstanaExporter())); + throw new ArgumentNullException(nameof(options)); } + + return options.AddProcessor(new BatchActivityExportProcessor(new InstanaExporter())); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index 381f97765d..07a5c5c053 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -23,125 +23,124 @@ using OpenTelemetry.Resources; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests +namespace OpenTelemetry.Exporter.Instana.Tests; + +public class InstanaExporterTests { - public class InstanaExporterTests + private readonly Mock instanaExporterHelperMock = new Mock(MockBehavior.Strict); + private readonly Mock activityProcessorMock = new Mock(MockBehavior.Strict); + private readonly Mock spanSenderMock = new Mock(MockBehavior.Strict); + private InstanaSpan instanaSpan = null; + private InstanaExporter instanaExporter = null; + + [Fact] + public void Export() + { + this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) + .Returns(() => Task.CompletedTask); + + this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); + this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) + .Returns(new Resource(new Dictionary() + { + { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, + { "process.pid", "processPid" }, { "host.id", "hostId" }, + })); + + this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); + + this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); + this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; + this.instanaExporter.SpanSender = this.spanSenderMock.Object; + + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + activity.TraceStateString = "TraceStateString"; + + Activity[] activities = new Activity[1] { activity }; + Batch batch = new Batch(activities, activities.Length); + var result = this.instanaExporter.Export(in batch); + + this.VerifyAllMocks(); + + Assert.Equal(ExportResult.Success, result); + Assert.NotNull(this.instanaSpan); + Assert.Equal("processPid", this.instanaSpan.F.E); + Assert.Equal("hostId", this.instanaSpan.F.H); + Assert.Equal("serviceName", this.instanaSpan.Data.data["service"]); + Assert.Equal("testOperationName", this.instanaSpan.Data.data["operation"]); + Assert.Equal("TraceStateString", this.instanaSpan.Data.data["trace_state"]); + } + + [Fact] + public void Export_ProcessPidDoesNotExistButServiceIdExists() + { + this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) + .Returns(() => Task.CompletedTask); + + this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); + this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) + .Returns(new Resource(new Dictionary() + { + { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, + { "host.id", "hostId" }, + })); + + this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); + + this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); + this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; + this.instanaExporter.SpanSender = this.spanSenderMock.Object; + + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + + Activity[] activities = new Activity[1] { activity }; + Batch batch = new Batch(activities, activities.Length); + var result = this.instanaExporter.Export(in batch); + + this.VerifyAllMocks(); + + Assert.Equal(ExportResult.Success, result); + Assert.NotNull(this.instanaSpan); + Assert.Equal("serviceInstanceId", this.instanaSpan.F.E); + Assert.Equal("hostId", this.instanaSpan.F.H); + Assert.Equal("serviceName", this.instanaSpan.Data.data["service"]); + Assert.Equal("testOperationName", this.instanaSpan.Data.data["operation"]); + } + + [Fact] + public void Export_ExporterIsShotDown() + { + this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); + this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; + this.instanaExporter.SpanSender = this.spanSenderMock.Object; + + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + + this.instanaExporter.Shutdown(); + + Activity[] activities = new Activity[1] { activity }; + Batch batch = new Batch(activities, activities.Length); + var result = this.instanaExporter.Export(in batch); + + this.VerifyAllMocks(); + + Assert.Equal(ExportResult.Failure, result); + Assert.Null(this.instanaSpan); + } + + private bool CloneSpan(InstanaSpan span) + { + this.instanaSpan = span; + return true; + } + + private void VerifyAllMocks() { - private readonly Mock instanaExporterHelperMock = new Mock(MockBehavior.Strict); - private readonly Mock activityProcessorMock = new Mock(MockBehavior.Strict); - private readonly Mock spanSenderMock = new Mock(MockBehavior.Strict); - private InstanaSpan instanaSpan = null; - private InstanaExporter instanaExporter = null; - - [Fact] - public void Export() - { - this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) - .Returns(() => Task.CompletedTask); - - this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); - this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) - .Returns(new Resource(new Dictionary() - { - { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, - { "process.pid", "processPid" }, { "host.id", "hostId" }, - })); - - this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); - - this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); - this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; - this.instanaExporter.SpanSender = this.spanSenderMock.Object; - - Activity activity = new Activity("testOperationName"); - activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); - activity.TraceStateString = "TraceStateString"; - - Activity[] activities = new Activity[1] { activity }; - Batch batch = new Batch(activities, activities.Length); - var result = this.instanaExporter.Export(in batch); - - this.VerifyAllMocks(); - - Assert.Equal(ExportResult.Success, result); - Assert.NotNull(this.instanaSpan); - Assert.Equal("processPid", this.instanaSpan.F.E); - Assert.Equal("hostId", this.instanaSpan.F.H); - Assert.Equal("serviceName", this.instanaSpan.Data.data["service"]); - Assert.Equal("testOperationName", this.instanaSpan.Data.data["operation"]); - Assert.Equal("TraceStateString", this.instanaSpan.Data.data["trace_state"]); - } - - [Fact] - public void Export_ProcessPidDoesNotExistButServiceIdExists() - { - this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) - .Returns(() => Task.CompletedTask); - - this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); - this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) - .Returns(new Resource(new Dictionary() - { - { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, - { "host.id", "hostId" }, - })); - - this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); - - this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); - this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; - this.instanaExporter.SpanSender = this.spanSenderMock.Object; - - Activity activity = new Activity("testOperationName"); - activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); - - Activity[] activities = new Activity[1] { activity }; - Batch batch = new Batch(activities, activities.Length); - var result = this.instanaExporter.Export(in batch); - - this.VerifyAllMocks(); - - Assert.Equal(ExportResult.Success, result); - Assert.NotNull(this.instanaSpan); - Assert.Equal("serviceInstanceId", this.instanaSpan.F.E); - Assert.Equal("hostId", this.instanaSpan.F.H); - Assert.Equal("serviceName", this.instanaSpan.Data.data["service"]); - Assert.Equal("testOperationName", this.instanaSpan.Data.data["operation"]); - } - - [Fact] - public void Export_ExporterIsShotDown() - { - this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); - this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; - this.instanaExporter.SpanSender = this.spanSenderMock.Object; - - Activity activity = new Activity("testOperationName"); - activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); - - this.instanaExporter.Shutdown(); - - Activity[] activities = new Activity[1] { activity }; - Batch batch = new Batch(activities, activities.Length); - var result = this.instanaExporter.Export(in batch); - - this.VerifyAllMocks(); - - Assert.Equal(ExportResult.Failure, result); - Assert.Null(this.instanaSpan); - } - - private bool CloneSpan(InstanaSpan span) - { - this.instanaSpan = span; - return true; - } - - private void VerifyAllMocks() - { - this.instanaExporterHelperMock.VerifyAll(); - this.activityProcessorMock.VerifyAll(); - this.spanSenderMock.VerifyAll(); - } + this.instanaExporterHelperMock.VerifyAll(); + this.activityProcessorMock.VerifyAll(); + this.spanSenderMock.VerifyAll(); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs index f92e1a7e26..fc49bf5ad5 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs @@ -17,23 +17,22 @@ using OpenTelemetry.Exporter.Instana.Implementation; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests +namespace OpenTelemetry.Exporter.Instana.Tests; + +public class InstanaSpanFactoryTests { - public class InstanaSpanFactoryTests - { - private InstanaSpanFactory instanaSpanFactory = new InstanaSpanFactory(); + private InstanaSpanFactory instanaSpanFactory = new InstanaSpanFactory(); - [Fact] - public void CreateSpan() - { - OpenTelemetry.Exporter.Instana.Implementation.InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); + [Fact] + public void CreateSpan() + { + InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); - Assert.NotNull(instanaSpan); - Assert.NotNull(instanaSpan.TransformInfo); - Assert.NotNull(instanaSpan.Data); - Assert.Empty(instanaSpan.Data.data); - Assert.Empty(instanaSpan.Data.Tags); - Assert.Empty(instanaSpan.Data.Events); - } + Assert.NotNull(instanaSpan); + Assert.NotNull(instanaSpan.TransformInfo); + Assert.NotNull(instanaSpan.Data); + Assert.Empty(instanaSpan.Data.data); + Assert.Empty(instanaSpan.Data.Tags); + Assert.Empty(instanaSpan.Data.Events); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 8b4a1c8ecf..0dcdf4eb2a 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -22,84 +22,83 @@ using OpenTelemetry.Exporter.Instana.Implementation; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests +namespace OpenTelemetry.Exporter.Instana.Tests; + +public class InstanaSpanSerializerTests { - public class InstanaSpanSerializerTests - { - private InstanaSpanSerializer instanaSpanSerializer = new InstanaSpanSerializer(); + private InstanaSpanSerializer instanaSpanSerializer = new InstanaSpanSerializer(); - [Fact] - public async Task SerializeToStreamWriterAsync() + [Fact] + public async Task SerializeToStreamWriterAsync() + { + InstanaSpan instanaOtelSpan = InstanaSpanFactory.CreateSpan(); + instanaOtelSpan.F = new Implementation.From() { E = "12345", H = "localhost" }; + instanaOtelSpan.N = "otel"; + instanaOtelSpan.T = "hexNumberT1234"; + instanaOtelSpan.S = "hexNumberS1234"; + instanaOtelSpan.P = "hexNumberP1234"; + instanaOtelSpan.Ec = 1; + instanaOtelSpan.D = 123456; + instanaOtelSpan.Lt = "hexNumberLT1234567890123"; + instanaOtelSpan.Tp = true; + instanaOtelSpan.Data.Tags = new Dictionary(); + instanaOtelSpan.Data.Tags["tag1Key"] = "tag1Vale"; + instanaOtelSpan.Data.Tags["tag2Key"] = "tag2Vale"; + instanaOtelSpan.Data.data = new Dictionary(); + instanaOtelSpan.Data.data["data1Key"] = "data1Vale"; + instanaOtelSpan.Data.data["data2Key"] = "data2Vale"; + instanaOtelSpan.Data.Events = new List() { - InstanaSpan instanaOtelSpan = InstanaSpanFactory.CreateSpan(); - instanaOtelSpan.F = new Implementation.From() { E = "12345", H = "localhost" }; - instanaOtelSpan.N = "otel"; - instanaOtelSpan.T = "hexNumberT1234"; - instanaOtelSpan.S = "hexNumberS1234"; - instanaOtelSpan.P = "hexNumberP1234"; - instanaOtelSpan.Ec = 1; - instanaOtelSpan.D = 123456; - instanaOtelSpan.Lt = "hexNumberLT1234567890123"; - instanaOtelSpan.Tp = true; - instanaOtelSpan.Data.Tags = new Dictionary(); - instanaOtelSpan.Data.Tags["tag1Key"] = "tag1Vale"; - instanaOtelSpan.Data.Tags["tag2Key"] = "tag2Vale"; - instanaOtelSpan.Data.data = new Dictionary(); - instanaOtelSpan.Data.data["data1Key"] = "data1Vale"; - instanaOtelSpan.Data.data["data2Key"] = "data2Vale"; - instanaOtelSpan.Data.Events = new List() - { - new Implementation.SpanEvent() + new Implementation.SpanEvent() { Name = "testEvent", Ts = 111111, Tags = new Dictionary() { { "eventTagKey", "eventTagValue" } }, }, - new Implementation.SpanEvent() - { - Name = "testEvent2", Ts = 222222, - Tags = new Dictionary() { { "eventTag2Key", "eventTag2Value" } }, - }, - }; + new Implementation.SpanEvent() + { + Name = "testEvent2", Ts = 222222, + Tags = new Dictionary() { { "eventTag2Key", "eventTag2Value" } }, + }, + }; - InstanaSpanTest span; - using (MemoryStream sendBuffer = new MemoryStream(new byte[4096000])) + InstanaSpanTest span; + using (MemoryStream sendBuffer = new MemoryStream(new byte[4096000])) + { + using (StreamWriter writer = new StreamWriter(sendBuffer)) { - using (StreamWriter writer = new StreamWriter(sendBuffer)) - { - await this.instanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); - await writer.FlushAsync(); - long length = sendBuffer.Position; - sendBuffer.Position = 0; - sendBuffer.SetLength(length); + await this.instanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); + await writer.FlushAsync(); + long length = sendBuffer.Position; + sendBuffer.Position = 0; + sendBuffer.SetLength(length); - Newtonsoft.Json.JsonSerializer serializer = null; - serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.Converters.Add(new JavaScriptDateTimeConverter()); - serializer.NullValueHandling = NullValueHandling.Ignore; + Newtonsoft.Json.JsonSerializer serializer = null; + serializer = new Newtonsoft.Json.JsonSerializer(); + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + serializer.NullValueHandling = NullValueHandling.Ignore; - TextReader textReader = new StreamReader(sendBuffer); - JsonReader reader = new JsonTextReader(textReader); - span = serializer.Deserialize(reader); - } + TextReader textReader = new StreamReader(sendBuffer); + JsonReader reader = new JsonTextReader(textReader); + span = serializer.Deserialize(reader); } - - Assert.NotNull(span); - Assert.Equal(instanaOtelSpan.S, span.S); - Assert.Equal(instanaOtelSpan.T, span.T); - Assert.Equal(instanaOtelSpan.P, span.P); - Assert.Equal(instanaOtelSpan.N, span.N); - Assert.Equal(instanaOtelSpan.F.E, span.F.E); - Assert.Equal(instanaOtelSpan.Ec, span.Ec); - Assert.Equal(instanaOtelSpan.D / 10_000, span.D); - Assert.Equal(instanaOtelSpan.Lt, span.Lt); - Assert.Equal(instanaOtelSpan.Data.Tags["tag1Key"], span.Data.Tags["tag1Key"]); - Assert.Equal(instanaOtelSpan.Data.Tags["tag2Key"], span.Data.Tags["tag2Key"]); - Assert.Equal(instanaOtelSpan.Data.data["data1Key"], span.Data.data["data1Key"]); - Assert.Equal(instanaOtelSpan.Data.data["data2Key"], span.Data.data["data2Key"]); - Assert.Equal(instanaOtelSpan.Data.Events[0].Name, span.Data.Events[0].Name); - Assert.Equal(instanaOtelSpan.Data.Events[0].Tags["eventTagKey"], span.Data.Events[0].Tags["eventTagKey"]); - Assert.Equal(instanaOtelSpan.Data.Events[1].Name, span.Data.Events[1].Name); - Assert.Equal(instanaOtelSpan.Data.Events[1].Tags["eventTag2Key"], span.Data.Events[1].Tags["eventTag2Key"]); } + + Assert.NotNull(span); + Assert.Equal(instanaOtelSpan.S, span.S); + Assert.Equal(instanaOtelSpan.T, span.T); + Assert.Equal(instanaOtelSpan.P, span.P); + Assert.Equal(instanaOtelSpan.N, span.N); + Assert.Equal(instanaOtelSpan.F.E, span.F.E); + Assert.Equal(instanaOtelSpan.Ec, span.Ec); + Assert.Equal(instanaOtelSpan.D / 10_000, span.D); + Assert.Equal(instanaOtelSpan.Lt, span.Lt); + Assert.Equal(instanaOtelSpan.Data.Tags["tag1Key"], span.Data.Tags["tag1Key"]); + Assert.Equal(instanaOtelSpan.Data.Tags["tag2Key"], span.Data.Tags["tag2Key"]); + Assert.Equal(instanaOtelSpan.Data.data["data1Key"], span.Data.data["data1Key"]); + Assert.Equal(instanaOtelSpan.Data.data["data2Key"], span.Data.data["data2Key"]); + Assert.Equal(instanaOtelSpan.Data.Events[0].Name, span.Data.Events[0].Name); + Assert.Equal(instanaOtelSpan.Data.Events[0].Tags["eventTagKey"], span.Data.Events[0].Tags["eventTagKey"]); + Assert.Equal(instanaOtelSpan.Data.Events[1].Name, span.Data.Events[1].Name); + Assert.Equal(instanaOtelSpan.Data.Events[1].Tags["eventTag2Key"], span.Data.Events[1].Tags["eventTag2Key"]); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index 8bdcea7672..a72c9cf878 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -19,121 +19,120 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace OpenTelemetry.Exporter.Instana.Tests +namespace OpenTelemetry.Exporter.Instana.Tests; + +internal enum SpanKind { - internal enum SpanKind - { #pragma warning disable SA1602 // Enumeration items should be documented - ENTRY, + ENTRY, #pragma warning restore SA1602 // Enumeration items should be documented #pragma warning disable SA1602 // Enumeration items should be documented - EXIT, + EXIT, #pragma warning restore SA1602 // Enumeration items should be documented #pragma warning disable SA1602 // Enumeration items should be documented - INTERMEDIATE, + INTERMEDIATE, #pragma warning restore SA1602 // Enumeration items should be documented #pragma warning disable SA1602 // Enumeration items should be documented - NOT_SET, + NOT_SET, #pragma warning restore SA1602 // Enumeration items should be documented - } +} #pragma warning disable SA1402 // File may only contain a single type #pragma warning disable SA1649 // File name should match first type name - internal class InstanaSpanTransformInfo +internal class InstanaSpanTransformInfo #pragma warning restore SA1649 // File name should match first type name #pragma warning restore SA1402 // File may only contain a single type - { - public string StatusCode { get; internal set; } +{ + public string StatusCode { get; internal set; } - public string StatusDesc { get; internal set; } + public string StatusDesc { get; internal set; } - public bool HasExceptionEvent { get; internal set; } + public bool HasExceptionEvent { get; internal set; } - public bool IsEntrySpan { get; internal set; } - } + public bool IsEntrySpan { get; internal set; } +} - internal class InstanaSpanTest - { - public InstanaSpanTransformInfo TransformInfo { get; set; } +internal class InstanaSpanTest +{ + public InstanaSpanTransformInfo TransformInfo { get; set; } - [JsonProperty] - public string N { get; internal set; } + [JsonProperty] + public string N { get; internal set; } - [JsonProperty] - public string T { get; internal set; } + [JsonProperty] + public string T { get; internal set; } - [JsonProperty] - public string Lt { get; internal set; } + [JsonProperty] + public string Lt { get; internal set; } - [JsonProperty] - public From F { get; internal set; } + [JsonProperty] + public From F { get; internal set; } - [JsonProperty] - public string P { get; internal set; } + [JsonProperty] + public string P { get; internal set; } - [JsonProperty] - public string S { get; internal set; } + [JsonProperty] + public string S { get; internal set; } - [JsonProperty] - public SpanKind K { get; internal set; } + [JsonProperty] + public SpanKind K { get; internal set; } - [JsonProperty] - public Data Data { get; internal set; } + [JsonProperty] + public Data Data { get; internal set; } - [JsonProperty] - public long Ts { get; internal set; } + [JsonProperty] + public long Ts { get; internal set; } - [JsonProperty] - public long D { get; internal set; } + [JsonProperty] + public long D { get; internal set; } - [JsonProperty] - public bool Tp { get; internal set; } + [JsonProperty] + public bool Tp { get; internal set; } - [JsonProperty] - public int Ec { get; internal set; } - } + [JsonProperty] + public int Ec { get; internal set; } +} #pragma warning disable SA1402 // File may only contain a single type - internal class From +internal class From #pragma warning restore SA1402 // File may only contain a single type - { - [JsonProperty] - public string E { get; internal set; } +{ + [JsonProperty] + public string E { get; internal set; } - [JsonProperty] - public string H { get; internal set; } - } + [JsonProperty] + public string H { get; internal set; } +} - [JsonConverter(typeof(DataConverter))] +[JsonConverter(typeof(DataConverter))] #pragma warning disable SA1402 // File may only contain a single type - internal class Data +internal class Data #pragma warning restore SA1402 // File may only contain a single type - { - [JsonProperty] +{ + [JsonProperty] #pragma warning disable SA1300 // Element should begin with upper-case letter - public Dictionary data { get; internal set; } + public Dictionary data { get; internal set; } #pragma warning restore SA1300 // Element should begin with upper-case letter - [JsonProperty] - public Dictionary Tags { get; internal set; } + [JsonProperty] + public Dictionary Tags { get; internal set; } - [JsonProperty] - public List Events { get; internal set; } - } + [JsonProperty] + public List Events { get; internal set; } +} #pragma warning disable SA1402 // File may only contain a single type - internal class SpanEvent +internal class SpanEvent #pragma warning restore SA1402 // File may only contain a single type - { - [JsonProperty] - public string Name { get; internal set; } +{ + [JsonProperty] + public string Name { get; internal set; } - [JsonProperty] - public long Ts { get; internal set; } + [JsonProperty] + public long Ts { get; internal set; } - [JsonProperty] - public Dictionary Tags { get; internal set; } - } + [JsonProperty] + public Dictionary Tags { get; internal set; } } #pragma warning disable SA1402 // File may only contain a single type @@ -146,7 +145,7 @@ public class DataConverter : JsonConverter public override bool CanConvert(Type objectType) { - return objectType == typeof(OpenTelemetry.Exporter.Instana.Tests.Data); + return objectType == typeof(Data); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) @@ -165,11 +164,11 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist var data = obj.Root; if (data != null) { - var newData = new OpenTelemetry.Exporter.Instana.Tests.Data(); + var newData = new Data(); foreach (var field in data) { - if (((Newtonsoft.Json.Linq.JProperty)field).Name == "tags" || - ((Newtonsoft.Json.Linq.JProperty)field).Name == "events") + if (((JProperty)field).Name == "tags" || + ((JProperty)field).Name == "events") { continue; } @@ -179,10 +178,10 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist newData.data = new Dictionary(); } - newData.data[((Newtonsoft.Json.Linq.JProperty)field).Name] = ((Newtonsoft.Json.Linq.JProperty)field).Value.ToString(); + newData.data[((JProperty)field).Name] = ((JProperty)field).Value.ToString(); } - var existingData = existingValue as OpenTelemetry.Exporter.Instana.Tests.Data ?? new OpenTelemetry.Exporter.Instana.Tests.Data(); + var existingData = existingValue as Data ?? new Data(); // Populate the remaining standard properties using (var subReader = data.CreateReader()) diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs index 6b9dc76681..5318918f64 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs @@ -20,33 +20,32 @@ using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests.Processors +namespace OpenTelemetry.Exporter.Instana.Tests.Processors; + +public class DefaultActivityProcessorTests { - public class DefaultActivityProcessorTests + private DefaultActivityProcessor defaultActivityProcessor = new DefaultActivityProcessor(); + + [Fact] + public async Task ProcessAsync() { - private DefaultActivityProcessor defaultActivityProcessor = new DefaultActivityProcessor(); + Activity activity = new Activity("testOperationName"); + activity.Start(); + await Task.Delay(200); + activity.Stop(); + InstanaSpan instanaSpan = new InstanaSpan(); + await this.defaultActivityProcessor.ProcessAsync(activity, instanaSpan); - [Fact] - public async Task ProcessAsync() + Assert.False(string.IsNullOrEmpty(instanaSpan.S)); + Assert.False(string.IsNullOrEmpty(instanaSpan.Lt)); + Assert.True(instanaSpan.D > 0); + Assert.True(instanaSpan.Ts > 0); + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.data); + Assert.Contains(instanaSpan.Data.data, filter: x => { - Activity activity = new Activity("testOperationName"); - activity.Start(); - await Task.Delay(200); - activity.Stop(); - InstanaSpan instanaSpan = new InstanaSpan(); - await this.defaultActivityProcessor.ProcessAsync(activity, instanaSpan); - - Assert.False(string.IsNullOrEmpty(instanaSpan.S)); - Assert.False(string.IsNullOrEmpty(instanaSpan.Lt)); - Assert.True(instanaSpan.D > 0); - Assert.True(instanaSpan.Ts > 0); - Assert.NotNull(instanaSpan.Data); - Assert.NotNull(instanaSpan.Data.data); - Assert.Contains(instanaSpan.Data.data, filter: x => - { - return x.Key == "kind" - && x.Value.Equals("internal"); - }); - } + return x.Key == "kind" + && x.Value.Equals("internal"); + }); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs index 630c5e692e..c09aca7a2f 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -20,45 +20,44 @@ using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests.Processors -{ - public class ErrorActivityProcessorTests - { - private ErrorActivityProcessor errorActivityProcessor = new ErrorActivityProcessor(); +namespace OpenTelemetry.Exporter.Instana.Tests.Processors; - [Fact] - public async Task Process_ErrorStatusCodeIsSet() - { - Activity activity = new Activity("testOperationName"); - activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); - InstanaSpan instanaSpan = new InstanaSpan(); - await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); +public class ErrorActivityProcessorTests +{ + private ErrorActivityProcessor errorActivityProcessor = new ErrorActivityProcessor(); - Assert.True(instanaSpan.Ec == 1); - Assert.NotNull(instanaSpan.Data); - Assert.NotNull(instanaSpan.Data.data); - Assert.Equal("Error", instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD]); - Assert.Equal("TestErrorDesc", instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD]); - } + [Fact] + public async Task Process_ErrorStatusCodeIsSet() + { + Activity activity = new Activity("testOperationName"); + activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); + InstanaSpan instanaSpan = new InstanaSpan(); + await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.True(instanaSpan.Ec == 1); + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.data); + Assert.Equal("Error", instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD]); + Assert.Equal("TestErrorDesc", instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD]); + } - [Fact] - public async Task Process_ExistsExceptionEvent() - { - Activity activity = new Activity("testOperationName"); - InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new OpenTelemetry.Exporter.Instana.Implementation.InstanaSpanTransformInfo() { HasExceptionEvent = true } }; - await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); + [Fact] + public async Task Process_ExistsExceptionEvent() + { + Activity activity = new Activity("testOperationName"); + InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() { HasExceptionEvent = true } }; + await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); - Assert.True(instanaSpan.Ec == 1); - } + Assert.True(instanaSpan.Ec == 1); + } - [Fact] - public async Task Process_NoError() - { - Activity activity = new Activity("testOperationName"); - InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new OpenTelemetry.Exporter.Instana.Implementation.InstanaSpanTransformInfo() }; - await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); + [Fact] + public async Task Process_NoError() + { + Activity activity = new Activity("testOperationName"); + InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; + await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); - Assert.True(instanaSpan.Ec == 0); - } + Assert.True(instanaSpan.Ec == 0); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index f400cb79c2..ba761a9e35 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -22,43 +22,42 @@ using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests.Processors +namespace OpenTelemetry.Exporter.Instana.Tests.Processors; + +public class EventsActivityProcessorTests { - public class EventsActivityProcessorTests - { - private EventsActivityProcessor eventsActivityProcessor = new EventsActivityProcessor(); + private EventsActivityProcessor eventsActivityProcessor = new EventsActivityProcessor(); - [Fact] - public async Task ProcessAsync() - { - var activityTagsCollection = new ActivityTagsCollection(); - activityTagsCollection.Add(new KeyValuePair("eventTagKey", "eventTagValue")); - var activityEvent = new ActivityEvent( - "testActivityEvent", - DateTimeOffset.MinValue, - activityTagsCollection); + [Fact] + public async Task ProcessAsync() + { + var activityTagsCollection = new ActivityTagsCollection(); + activityTagsCollection.Add(new KeyValuePair("eventTagKey", "eventTagValue")); + var activityEvent = new ActivityEvent( + "testActivityEvent", + DateTimeOffset.MinValue, + activityTagsCollection); - var activityTagsCollection2 = new ActivityTagsCollection(); - activityTagsCollection2.Add(new KeyValuePair("eventTagKey2", "eventTagValue2")); - var activityEvent2 = new ActivityEvent( - "testActivityEvent2", - DateTimeOffset.MaxValue, - activityTagsCollection2); + var activityTagsCollection2 = new ActivityTagsCollection(); + activityTagsCollection2.Add(new KeyValuePair("eventTagKey2", "eventTagValue2")); + var activityEvent2 = new ActivityEvent( + "testActivityEvent2", + DateTimeOffset.MaxValue, + activityTagsCollection2); - Activity activity = new Activity("testOperationName"); - activity.AddEvent(activityEvent); - activity.AddEvent(activityEvent2); - InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new OpenTelemetry.Exporter.Instana.Implementation.InstanaSpanTransformInfo() }; - await this.eventsActivityProcessor.ProcessAsync(activity, instanaSpan); + Activity activity = new Activity("testOperationName"); + activity.AddEvent(activityEvent); + activity.AddEvent(activityEvent2); + InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; + await this.eventsActivityProcessor.ProcessAsync(activity, instanaSpan); - Assert.True(instanaSpan.Ec == 0); - Assert.True(instanaSpan.Data.Events.Count == 2); - Assert.True(instanaSpan.Data.Events[0].Name == "testActivityEvent"); - Assert.True(instanaSpan.Data.Events[0].Ts > 0); - Assert.True(instanaSpan.Data.Events[0].Tags["eventTagKey"] == "eventTagValue"); - Assert.True(instanaSpan.Data.Events[1].Name == "testActivityEvent2"); - Assert.True(instanaSpan.Data.Events[1].Ts > 0); - Assert.True(instanaSpan.Data.Events[1].Tags["eventTagKey2"] == "eventTagValue2"); - } + Assert.True(instanaSpan.Ec == 0); + Assert.True(instanaSpan.Data.Events.Count == 2); + Assert.True(instanaSpan.Data.Events[0].Name == "testActivityEvent"); + Assert.True(instanaSpan.Data.Events[0].Ts > 0); + Assert.True(instanaSpan.Data.Events[0].Tags["eventTagKey"] == "eventTagValue"); + Assert.True(instanaSpan.Data.Events[1].Name == "testActivityEvent2"); + Assert.True(instanaSpan.Data.Events[1].Ts > 0); + Assert.True(instanaSpan.Data.Events[1].Tags["eventTagKey2"] == "eventTagValue2"); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs index 456eab64e1..c07c4f12ef 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs @@ -20,44 +20,43 @@ using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; -namespace OpenTelemetry.Exporter.Instana.Tests.Processors +namespace OpenTelemetry.Exporter.Instana.Tests.Processors; + +public class TagsActivityProcessorTests { - public class TagsActivityProcessorTests + private TagsActivityProcessor tagsActivityProcessor = new TagsActivityProcessor(); + + [Fact] + public async Task ProcessAsync_StatusTagsExist() { - private TagsActivityProcessor tagsActivityProcessor = new TagsActivityProcessor(); - - [Fact] - public async Task ProcessAsync_StatusTagsExist() - { - Activity activity = new Activity("testOperationName"); - activity.AddTag("otel.status_code", "testStatusCode"); - activity.AddTag("otel.status_description", "testStatusDescription"); - activity.AddTag("otel.testTag", "testTag"); - - InstanaSpan instanaSpan = new InstanaSpan(); - await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); - - Assert.NotNull(instanaSpan.Data); - Assert.NotNull(instanaSpan.Data.Tags); - Assert.Contains(instanaSpan.Data.Tags, x => x.Key == "otel.testTag" && x.Value == "testTag"); - Assert.Equal("testStatusCode", instanaSpan.TransformInfo.StatusCode); - Assert.Equal("testStatusDescription", instanaSpan.TransformInfo.StatusDesc); - } - - [Fact] - public async Task ProcessAsync_StatusTagsDoNotExist() - { - Activity activity = new Activity("testOperationName"); - activity.AddTag("otel.testTag", "testTag"); - - InstanaSpan instanaSpan = new InstanaSpan(); - await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); - - Assert.NotNull(instanaSpan.Data); - Assert.NotNull(instanaSpan.Data.Tags); - Assert.Contains(instanaSpan.Data.Tags, x => x.Key == "otel.testTag" && x.Value == "testTag"); - Assert.Equal(string.Empty, instanaSpan.TransformInfo.StatusCode); - Assert.Equal(string.Empty, instanaSpan.TransformInfo.StatusDesc); - } + Activity activity = new Activity("testOperationName"); + activity.AddTag("otel.status_code", "testStatusCode"); + activity.AddTag("otel.status_description", "testStatusDescription"); + activity.AddTag("otel.testTag", "testTag"); + + InstanaSpan instanaSpan = new InstanaSpan(); + await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.Tags); + Assert.Contains(instanaSpan.Data.Tags, x => x.Key == "otel.testTag" && x.Value == "testTag"); + Assert.Equal("testStatusCode", instanaSpan.TransformInfo.StatusCode); + Assert.Equal("testStatusDescription", instanaSpan.TransformInfo.StatusDesc); + } + + [Fact] + public async Task ProcessAsync_StatusTagsDoNotExist() + { + Activity activity = new Activity("testOperationName"); + activity.AddTag("otel.testTag", "testTag"); + + InstanaSpan instanaSpan = new InstanaSpan(); + await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); + + Assert.NotNull(instanaSpan.Data); + Assert.NotNull(instanaSpan.Data.Tags); + Assert.Contains(instanaSpan.Data.Tags, x => x.Key == "otel.testTag" && x.Value == "testTag"); + Assert.Equal(string.Empty, instanaSpan.TransformInfo.StatusCode); + Assert.Equal(string.Empty, instanaSpan.TransformInfo.StatusDesc); } } From 7386a192f994fc8d2366c18442d665f1248e98f6 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 22 Aug 2022 11:30:50 -0700 Subject: [PATCH 0299/1499] changelog for beta.1 release (#598) --- .../CHANGELOG.md | 2 ++ src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md index d200eebf1c..1905836144 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## 1.0.0-beta.1 + ## 1.0.0-alpha.4 This is the first release for the `OpenTelemetry.Extensions.PersistentStorage.Abstractions` diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md index 081f76a006..fe44762587 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog - OpenTelemetry.Extensions.PersistentStorage -## Unreleased +## 1.0.0-beta.1 * Invalid path or permissions issues will now result in `FileBlobProvider` initialization failure by throwing exception. From 1bc197e9fa19ebb9ed3177e4cf76a5ec14a076d4 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 22 Aug 2022 14:49:10 -0700 Subject: [PATCH 0300/1499] Remove unnecessary filters (#599) --- .github/workflows/dotnet-core-cov.yml | 2 +- .github/workflows/package-Exporter.Geneva.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 82a78f4a4a..fa3dc4d49f 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -31,7 +31,7 @@ jobs: run: dotnet build --configuration Release --no-restore - name: dotnet test - run: dotnet test --collect:"Code Coverage" --results-directory:"TestResults" --configuration Release --no-build --filter "Platform=Any|Platform=Windows" -- RunConfiguration.DisableAppDomain=true + run: dotnet test --collect:"Code Coverage" --results-directory:"TestResults" --configuration Release --no-build -- RunConfiguration.DisableAppDomain=true - name: Process code coverage run: .\build\process-codecoverage.ps1 diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index 03f1377489..c768599ac0 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -33,7 +33,7 @@ jobs: run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests --filter "Platform=Any|Platform=Windows" + run: dotnet test test/${{env.PROJECT}}.Tests - name: dotnet pack ${{env.PROJECT}} run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build From 553fcb233d2d9d57ca67cce48837a941d7da27eb Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 22 Aug 2022 19:52:10 -0700 Subject: [PATCH 0301/1499] Cleanup workflows (#600) --- .github/workflows/dotnet-format-md.yml | 5 +- .../package-Exporter.Geneva.yml | 0 .../package-Exporter.Instana.yml | 0 .../package-Exporter.Stackdriver.yml | 0 .../package-Extensions.AWSXRay.yml | 0 .../package-Extensions.Docker.yml | 0 ...ensions.PersistentStorage.Abstractions.yml | 0 .../package-Extensions.PersistentStorage.yml | 0 .../package-Extensions.yml | 0 .../package-Instrumentation.AWS.yml | 0 .../package-Instrumentation.AWSLambda.yml | 0 ...rumentation.AspNet.TelemetryHttpModule.yml | 0 .../package-Instrumentation.AspNet.yml | 0 .../package-Instrumentation.Elasticsearch.yml | 0 ...ge-Instrumentation.EntityFrameworkCore.yml | 0 .../package-Instrumentation.EventCounters.yml | 96 +++++++++---------- .../package-Instrumentation.GrpcCore.yml | 0 .../package-Instrumentation.Hangfire.yml | 0 .../package-Instrumentation.MassTransit.yml | 0 .../package-Instrumentation.MySqlData.yml | 0 .../package-Instrumentation.Owin.yml | 0 .../package-Instrumentation.Quartz.yml | 0 .../package-Instrumentation.Runtime.yml | 0 ...age-Instrumentation.StackExchangeRedis.yml | 0 .../package-Instrumentation.Wcf.yml | 0 CONTRIBUTING.md | 15 +-- opentelemetry-dotnet-contrib.sln | 56 ++++++----- 27 files changed, 91 insertions(+), 81 deletions(-) rename .github/workflows/{ => publish-packages}/package-Exporter.Geneva.yml (100%) rename .github/workflows/{ => publish-packages}/package-Exporter.Instana.yml (100%) rename .github/workflows/{ => publish-packages}/package-Exporter.Stackdriver.yml (100%) rename .github/workflows/{ => publish-packages}/package-Extensions.AWSXRay.yml (100%) rename .github/workflows/{ => publish-packages}/package-Extensions.Docker.yml (100%) rename .github/workflows/{ => publish-packages}/package-Extensions.PersistentStorage.Abstractions.yml (100%) rename .github/workflows/{ => publish-packages}/package-Extensions.PersistentStorage.yml (100%) rename .github/workflows/{ => publish-packages}/package-Extensions.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.AWS.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.AWSLambda.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.AspNet.TelemetryHttpModule.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.AspNet.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.Elasticsearch.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.EntityFrameworkCore.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.EventCounters.yml (96%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.GrpcCore.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.Hangfire.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.MassTransit.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.MySqlData.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.Owin.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.Quartz.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.Runtime.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.StackExchangeRedis.yml (100%) rename .github/workflows/{ => publish-packages}/package-Instrumentation.Wcf.yml (100%) diff --git a/.github/workflows/dotnet-format-md.yml b/.github/workflows/dotnet-format-md.yml index 5453ddca94..be810e6c82 100644 --- a/.github/workflows/dotnet-format-md.yml +++ b/.github/workflows/dotnet-format-md.yml @@ -10,8 +10,9 @@ name: dotnet format on: pull_request: branches: [ main ] - paths: - - '**.md' + paths-ignore: + - '**.cs' + - '.editorconfig' jobs: check-format: diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/publish-packages/package-Exporter.Geneva.yml similarity index 100% rename from .github/workflows/package-Exporter.Geneva.yml rename to .github/workflows/publish-packages/package-Exporter.Geneva.yml diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/publish-packages/package-Exporter.Instana.yml similarity index 100% rename from .github/workflows/package-Exporter.Instana.yml rename to .github/workflows/publish-packages/package-Exporter.Instana.yml diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/publish-packages/package-Exporter.Stackdriver.yml similarity index 100% rename from .github/workflows/package-Exporter.Stackdriver.yml rename to .github/workflows/publish-packages/package-Exporter.Stackdriver.yml diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/publish-packages/package-Extensions.AWSXRay.yml similarity index 100% rename from .github/workflows/package-Extensions.AWSXRay.yml rename to .github/workflows/publish-packages/package-Extensions.AWSXRay.yml diff --git a/.github/workflows/package-Extensions.Docker.yml b/.github/workflows/publish-packages/package-Extensions.Docker.yml similarity index 100% rename from .github/workflows/package-Extensions.Docker.yml rename to .github/workflows/publish-packages/package-Extensions.Docker.yml diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/publish-packages/package-Extensions.PersistentStorage.Abstractions.yml similarity index 100% rename from .github/workflows/package-Extensions.PersistentStorage.Abstractions.yml rename to .github/workflows/publish-packages/package-Extensions.PersistentStorage.Abstractions.yml diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/publish-packages/package-Extensions.PersistentStorage.yml similarity index 100% rename from .github/workflows/package-Extensions.PersistentStorage.yml rename to .github/workflows/publish-packages/package-Extensions.PersistentStorage.yml diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/publish-packages/package-Extensions.yml similarity index 100% rename from .github/workflows/package-Extensions.yml rename to .github/workflows/publish-packages/package-Extensions.yml diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/publish-packages/package-Instrumentation.AWS.yml similarity index 100% rename from .github/workflows/package-Instrumentation.AWS.yml rename to .github/workflows/publish-packages/package-Instrumentation.AWS.yml diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/publish-packages/package-Instrumentation.AWSLambda.yml similarity index 100% rename from .github/workflows/package-Instrumentation.AWSLambda.yml rename to .github/workflows/publish-packages/package-Instrumentation.AWSLambda.yml diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/publish-packages/package-Instrumentation.AspNet.TelemetryHttpModule.yml similarity index 100% rename from .github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml rename to .github/workflows/publish-packages/package-Instrumentation.AspNet.TelemetryHttpModule.yml diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml similarity index 100% rename from .github/workflows/package-Instrumentation.AspNet.yml rename to .github/workflows/publish-packages/package-Instrumentation.AspNet.yml diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/publish-packages/package-Instrumentation.Elasticsearch.yml similarity index 100% rename from .github/workflows/package-Instrumentation.Elasticsearch.yml rename to .github/workflows/publish-packages/package-Instrumentation.Elasticsearch.yml diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/publish-packages/package-Instrumentation.EntityFrameworkCore.yml similarity index 100% rename from .github/workflows/package-Instrumentation.EntityFrameworkCore.yml rename to .github/workflows/publish-packages/package-Instrumentation.EntityFrameworkCore.yml diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/publish-packages/package-Instrumentation.EventCounters.yml similarity index 96% rename from .github/workflows/package-Instrumentation.EventCounters.yml rename to .github/workflows/publish-packages/package-Instrumentation.EventCounters.yml index 6021ad00f7..adfa40a8c3 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/publish-packages/package-Instrumentation.EventCounters.yml @@ -1,49 +1,49 @@ -name: Pack OpenTelemetry.Instrumentation.EventCounters - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'Instrumentation.EventCounters-*' # trigger when we create a tag with prefix "Instrumentation.EventCounters-" - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - env: - PROJECT: OpenTelemetry.Instrumentation.EventCounters - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # fetching all - - - name: Install dependencies - run: dotnet restore - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | +name: Pack OpenTelemetry.Instrumentation.EventCounters + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.EventCounters-*' # trigger when we create a tag with prefix "Instrumentation.EventCounters-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.EventCounters + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/publish-packages/package-Instrumentation.GrpcCore.yml similarity index 100% rename from .github/workflows/package-Instrumentation.GrpcCore.yml rename to .github/workflows/publish-packages/package-Instrumentation.GrpcCore.yml diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/publish-packages/package-Instrumentation.Hangfire.yml similarity index 100% rename from .github/workflows/package-Instrumentation.Hangfire.yml rename to .github/workflows/publish-packages/package-Instrumentation.Hangfire.yml diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/publish-packages/package-Instrumentation.MassTransit.yml similarity index 100% rename from .github/workflows/package-Instrumentation.MassTransit.yml rename to .github/workflows/publish-packages/package-Instrumentation.MassTransit.yml diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/publish-packages/package-Instrumentation.MySqlData.yml similarity index 100% rename from .github/workflows/package-Instrumentation.MySqlData.yml rename to .github/workflows/publish-packages/package-Instrumentation.MySqlData.yml diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/publish-packages/package-Instrumentation.Owin.yml similarity index 100% rename from .github/workflows/package-Instrumentation.Owin.yml rename to .github/workflows/publish-packages/package-Instrumentation.Owin.yml diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/publish-packages/package-Instrumentation.Quartz.yml similarity index 100% rename from .github/workflows/package-Instrumentation.Quartz.yml rename to .github/workflows/publish-packages/package-Instrumentation.Quartz.yml diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/publish-packages/package-Instrumentation.Runtime.yml similarity index 100% rename from .github/workflows/package-Instrumentation.Runtime.yml rename to .github/workflows/publish-packages/package-Instrumentation.Runtime.yml diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/publish-packages/package-Instrumentation.StackExchangeRedis.yml similarity index 100% rename from .github/workflows/package-Instrumentation.StackExchangeRedis.yml rename to .github/workflows/publish-packages/package-Instrumentation.StackExchangeRedis.yml diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/publish-packages/package-Instrumentation.Wcf.yml similarity index 100% rename from .github/workflows/package-Instrumentation.Wcf.yml rename to .github/workflows/publish-packages/package-Instrumentation.Wcf.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7e811d5d60..1c478652d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -121,10 +121,11 @@ Open a pull request against the main `opentelemetry-dotnet-contrib` repo. A PR is considered to be **ready to merge** when: -* It has received approval from +* It has received an approval either from one of the [Approvers](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver) / - [Maintainers](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer). + [Maintainers](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer) + or the respective component owner. * Major feedbacks are resolved. * It has been open for review for at least one working day. This gives people reasonable time to review. @@ -204,16 +205,16 @@ by you. To ensure your project is versioned appropriately, specify a to be triggered when a tag with prefix "Instrumentation.FooBar-" is pushed to the main branch. The workflow file should be named as `package-Instrumentation.FooBar.yml` and to be placed in the -`.github/workflows/` folder. +`.github/workflows/publish-packages/` folder. You can copy one of the [existing workflow - files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml) + files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml) and replace the workflow - [`name`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L1) + [`name`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml#L1) with "Pack OpenTelemetry.Instrumentation.FooBar", - [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L12) + [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml#L12) with "Instrumentation.FooBar-*" and - [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L18) + [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml#L18) with "OpenTelemetry.Instrumentation.FooBar". * Add an issue template in your PR. You can follow the existing issue templates, diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 977168caf3..2b6f4719f3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -27,36 +27,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml + .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\integration.yml = .github\workflows\integration.yml + .github\workflows\linux-ci-md.yml = .github\workflows\linux-ci-md.yml .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml - .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml - .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml - .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml - .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml - .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml - .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml - .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml - .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml - .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml - .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml - .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml - .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml - .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml - .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml - .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml - .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml - .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml - .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml - .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml - .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml - .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml - .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml - .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml - .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml + .github\workflows\windows-ci-md.yml = .github\workflows\windows-ci-md.yml .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml EndProjectSection EndProject @@ -230,6 +209,34 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EventCounters.Tests", "test\OpenTelemetry.Instrumentation.EventCounters.Tests\OpenTelemetry.Instrumentation.EventCounters.Tests.csproj", "{DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "publish-packages", "publish-packages", "{312FD546-F83E-4BD5-9BAE-FF90C7343D24}" + ProjectSection(SolutionItems) = preProject + .github\workflows\publish-packages\package-Exporter.Geneva.yml = .github\workflows\publish-packages\package-Exporter.Geneva.yml + .github\workflows\publish-packages\package-Exporter.Instana.yml = .github\workflows\publish-packages\package-Exporter.Instana.yml + .github\workflows\publish-packages\package-Exporter.Stackdriver.yml = .github\workflows\publish-packages\package-Exporter.Stackdriver.yml + .github\workflows\publish-packages\package-Extensions.AWSXRay.yml = .github\workflows\publish-packages\package-Extensions.AWSXRay.yml + .github\workflows\publish-packages\package-Extensions.Docker.yml = .github\workflows\publish-packages\package-Extensions.Docker.yml + .github\workflows\publish-packages\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\publish-packages\package-Extensions.PersistentStorage.Abstractions.yml + .github\workflows\publish-packages\package-Extensions.PersistentStorage.yml = .github\workflows\publish-packages\package-Extensions.PersistentStorage.yml + .github\workflows\publish-packages\package-Extensions.yml = .github\workflows\publish-packages\package-Extensions.yml + .github\workflows\publish-packages\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\publish-packages\package-Instrumentation.AspNet.TelemetryHttpModule.yml + .github\workflows\publish-packages\package-Instrumentation.AspNet.yml = .github\workflows\publish-packages\package-Instrumentation.AspNet.yml + .github\workflows\publish-packages\package-Instrumentation.AWS.yml = .github\workflows\publish-packages\package-Instrumentation.AWS.yml + .github\workflows\publish-packages\package-Instrumentation.AWSLambda.yml = .github\workflows\publish-packages\package-Instrumentation.AWSLambda.yml + .github\workflows\publish-packages\package-Instrumentation.Elasticsearch.yml = .github\workflows\publish-packages\package-Instrumentation.Elasticsearch.yml + .github\workflows\publish-packages\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\publish-packages\package-Instrumentation.EntityFrameworkCore.yml + .github\workflows\publish-packages\package-Instrumentation.EventCounters.yml = .github\workflows\publish-packages\package-Instrumentation.EventCounters.yml + .github\workflows\publish-packages\package-Instrumentation.GrpcCore.yml = .github\workflows\publish-packages\package-Instrumentation.GrpcCore.yml + .github\workflows\publish-packages\package-Instrumentation.Hangfire.yml = .github\workflows\publish-packages\package-Instrumentation.Hangfire.yml + .github\workflows\publish-packages\package-Instrumentation.MassTransit.yml = .github\workflows\publish-packages\package-Instrumentation.MassTransit.yml + .github\workflows\publish-packages\package-Instrumentation.MySqlData.yml = .github\workflows\publish-packages\package-Instrumentation.MySqlData.yml + .github\workflows\publish-packages\package-Instrumentation.Owin.yml = .github\workflows\publish-packages\package-Instrumentation.Owin.yml + .github\workflows\publish-packages\package-Instrumentation.Quartz.yml = .github\workflows\publish-packages\package-Instrumentation.Quartz.yml + .github\workflows\publish-packages\package-Instrumentation.Runtime.yml = .github\workflows\publish-packages\package-Instrumentation.Runtime.yml + .github\workflows\publish-packages\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\publish-packages\package-Instrumentation.StackExchangeRedis.yml + .github\workflows\publish-packages\package-Instrumentation.Wcf.yml = .github\workflows\publish-packages\package-Instrumentation.Wcf.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -559,6 +566,7 @@ Global {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {AE12EFB7-4B1A-46B8-B89A-0375252B10B1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {312FD546-F83E-4BD5-9BAE-FF90C7343D24} = {43CAFE52-F329-4431-87DA-7FEE1454D9A9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From 6f9a83836e17ed7d208bf140f68515d25f5ee0ef Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 23 Aug 2022 11:20:04 -0700 Subject: [PATCH 0302/1499] Simplify GenevaTraceExporter benchmarks (#601) --- .../Exporter/TraceExporterBenchmarks.cs | 77 +++++++++++-------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index c38d92e3e7..f305ae24a9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -27,10 +27,11 @@ [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT -| Method | Mean | Error | StdDev | Gen 0 | Allocated | -|------------------ |---------:|---------:|---------:|-------:|----------:| -| ExportActivity | 687.2 ns | 13.73 ns | 20.55 ns | 0.0648 | 408 B | -| SerializeActivity | 392.3 ns | 4.87 ns | 4.32 ns | 0.0062 | 40 B | + +| Method | Mean | Error | StdDev | Gen 0 | Allocated | +|------------------ |---------:|--------:|--------:|-------:|----------:| +| ExportActivity | 422.0 ns | 8.41 ns | 8.64 ns | 0.0062 | 40 B | +| SerializeActivity | 387.4 ns | 7.22 ns | 7.09 ns | 0.0062 | 40 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark @@ -39,26 +40,29 @@ namespace OpenTelemetry.Exporter.Geneva.Benchmark public class TraceExporterBenchmarks { private readonly Activity activity; + private readonly Batch batch; private readonly GenevaTraceExporter exporter; - private readonly ActivitySource sourceTestData = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark.TestData"); private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); - private readonly TracerProvider tracerProvider; public TraceExporterBenchmarks() { Activity.DefaultIdFormat = ActivityIdFormat.W3C; - ActivitySource.AddActivityListener(new ActivityListener + this.batch = this.CreateBatch(); + + using var activityListener = new ActivityListener { ActivityStarted = null, ActivityStopped = null, - ShouldListenTo = (activitySource) => activitySource.Name == this.sourceTestData.Name, + ShouldListenTo = (activitySource) => activitySource.Name == this.activitySource.Name, Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded, - }); + }; + + ActivitySource.AddActivityListener(activityListener); - using (var tedious = this.sourceTestData.StartActivity("Benchmark")) + using (var testActivity = this.activitySource.StartActivity("Benchmark")) { - this.activity = tedious; + this.activity = testActivity; this.activity?.SetTag("tagString", "value"); this.activity?.SetTag("tagInt", 100); this.activity?.SetStatus(Status.Error); @@ -74,28 +78,12 @@ public TraceExporterBenchmarks() ["cloud.roleVer"] = "9.0.15289.2", }, }); - - this.tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(this.activitySource.Name) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "EtwSession=OpenTelemetry"; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); } [Benchmark] public void ExportActivity() { - // this activity will be created and feed into the actual Geneva exporter - using var activity = this.activitySource.StartActivity("Benchmark"); + this.exporter.Export(this.batch); } [Benchmark] @@ -108,10 +96,39 @@ public void SerializeActivity() public void Cleanup() { this.activity.Dispose(); - this.sourceTestData.Dispose(); this.activitySource.Dispose(); + this.batch.Dispose(); this.exporter.Dispose(); - this.tracerProvider.Dispose(); + } + + private Batch CreateBatch() + { + using var batchGeneratorExporter = new BatchGeneratorExporter(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(this.activitySource.Name) + .AddProcessor(new SimpleActivityExportProcessor(batchGeneratorExporter)) + .Build(); + + using (var activity = this.activitySource.StartActivity("Benchmark")) + { + activity.SetTag("tagString", "value"); + activity.SetTag("tagInt", 100); + activity.SetStatus(Status.Error); + } + + return batchGeneratorExporter.Batch; + } + + private class BatchGeneratorExporter : BaseExporter + { + public Batch Batch { get; set; } + + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; + } } } } From a26776f0748e03a33838b1e45e8aa2f3a8e963ac Mon Sep 17 00:00:00 2001 From: Dawid Szmigielski Date: Tue, 23 Aug 2022 22:29:28 +0200 Subject: [PATCH 0303/1499] WCF instrumentation release (#603) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index e1d70cecf1..b590c3e280 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.7 + +Released 2022-Aug-23 + * Updated OTel SDK package version to 1.3.0 ([#569](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/569)) * Changed activity source name from `OpenTelemetry.WCF` @@ -10,6 +14,8 @@ ## 1.0.0-rc.6 +Released 2022-Mar-17 + * Going forward the NuGet package will be [`OpenTelemetry.Instrumentation.Wcf`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf). Older versions will remain at @@ -39,17 +45,23 @@ ## 1.0.0-rc5 +Released 2022-Feb-05 + * Fixed an `ArgumentNullException` setting `Activity`.`DisplayName` when processing service requests with empty actions ([#170](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/170)) ## 1.0.0-rc4 +Released 2021-Oct-22 + * Removed `Propagator` property on `WcfInstrumentationOptions` ([#163](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/163)) ## 1.0.0-rc3 +Released 2021-Sep-13 + * Added `TelemetryServiceBehavior`. **Breaking change** (config update required): Renamed `TelemetryBehaviourExtensionElement` -> `TelemetryEndpointBehaviorExtensionElement` @@ -61,6 +73,8 @@ ## 1.0.0-rc2 +Released 2021-Jun-16 + * Updated OTel SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) From eb66a2ad636dc0e9017c8016c2cfcd025a792193 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 23 Aug 2022 14:04:36 -0700 Subject: [PATCH 0304/1499] Move workflows back to .github/workflows/ (#604) --- .../package-Exporter.Geneva.yml | 0 .../package-Exporter.Instana.yml | 0 .../package-Exporter.Stackdriver.yml | 0 .../package-Extensions.AWSXRay.yml | 0 .../package-Extensions.Docker.yml | 0 ...ensions.PersistentStorage.Abstractions.yml | 0 .../package-Extensions.PersistentStorage.yml | 0 .../package-Extensions.yml | 0 .../package-Instrumentation.AWS.yml | 0 .../package-Instrumentation.AWSLambda.yml | 0 ...rumentation.AspNet.TelemetryHttpModule.yml | 0 .../package-Instrumentation.AspNet.yml | 0 .../package-Instrumentation.Elasticsearch.yml | 0 ...ge-Instrumentation.EntityFrameworkCore.yml | 0 .../package-Instrumentation.EventCounters.yml | 0 .../package-Instrumentation.GrpcCore.yml | 0 .../package-Instrumentation.Hangfire.yml | 0 .../package-Instrumentation.MassTransit.yml | 0 .../package-Instrumentation.MySqlData.yml | 0 .../package-Instrumentation.Owin.yml | 0 .../package-Instrumentation.Quartz.yml | 0 .../package-Instrumentation.Runtime.yml | 0 ...age-Instrumentation.StackExchangeRedis.yml | 0 .../package-Instrumentation.Wcf.yml | 0 opentelemetry-dotnet-contrib.sln | 53 +++++++++---------- 25 files changed, 24 insertions(+), 29 deletions(-) rename .github/workflows/{publish-packages => }/package-Exporter.Geneva.yml (100%) rename .github/workflows/{publish-packages => }/package-Exporter.Instana.yml (100%) rename .github/workflows/{publish-packages => }/package-Exporter.Stackdriver.yml (100%) rename .github/workflows/{publish-packages => }/package-Extensions.AWSXRay.yml (100%) rename .github/workflows/{publish-packages => }/package-Extensions.Docker.yml (100%) rename .github/workflows/{publish-packages => }/package-Extensions.PersistentStorage.Abstractions.yml (100%) rename .github/workflows/{publish-packages => }/package-Extensions.PersistentStorage.yml (100%) rename .github/workflows/{publish-packages => }/package-Extensions.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.AWS.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.AWSLambda.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.AspNet.TelemetryHttpModule.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.AspNet.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.Elasticsearch.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.EntityFrameworkCore.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.EventCounters.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.GrpcCore.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.Hangfire.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.MassTransit.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.MySqlData.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.Owin.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.Quartz.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.Runtime.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.StackExchangeRedis.yml (100%) rename .github/workflows/{publish-packages => }/package-Instrumentation.Wcf.yml (100%) diff --git a/.github/workflows/publish-packages/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml similarity index 100% rename from .github/workflows/publish-packages/package-Exporter.Geneva.yml rename to .github/workflows/package-Exporter.Geneva.yml diff --git a/.github/workflows/publish-packages/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml similarity index 100% rename from .github/workflows/publish-packages/package-Exporter.Instana.yml rename to .github/workflows/package-Exporter.Instana.yml diff --git a/.github/workflows/publish-packages/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml similarity index 100% rename from .github/workflows/publish-packages/package-Exporter.Stackdriver.yml rename to .github/workflows/package-Exporter.Stackdriver.yml diff --git a/.github/workflows/publish-packages/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml similarity index 100% rename from .github/workflows/publish-packages/package-Extensions.AWSXRay.yml rename to .github/workflows/package-Extensions.AWSXRay.yml diff --git a/.github/workflows/publish-packages/package-Extensions.Docker.yml b/.github/workflows/package-Extensions.Docker.yml similarity index 100% rename from .github/workflows/publish-packages/package-Extensions.Docker.yml rename to .github/workflows/package-Extensions.Docker.yml diff --git a/.github/workflows/publish-packages/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml similarity index 100% rename from .github/workflows/publish-packages/package-Extensions.PersistentStorage.Abstractions.yml rename to .github/workflows/package-Extensions.PersistentStorage.Abstractions.yml diff --git a/.github/workflows/publish-packages/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml similarity index 100% rename from .github/workflows/publish-packages/package-Extensions.PersistentStorage.yml rename to .github/workflows/package-Extensions.PersistentStorage.yml diff --git a/.github/workflows/publish-packages/package-Extensions.yml b/.github/workflows/package-Extensions.yml similarity index 100% rename from .github/workflows/publish-packages/package-Extensions.yml rename to .github/workflows/package-Extensions.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.AWS.yml rename to .github/workflows/package-Instrumentation.AWS.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.AWSLambda.yml rename to .github/workflows/package-Instrumentation.AWSLambda.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.AspNet.TelemetryHttpModule.yml rename to .github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.AspNet.yml rename to .github/workflows/package-Instrumentation.AspNet.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.Elasticsearch.yml rename to .github/workflows/package-Instrumentation.Elasticsearch.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.EntityFrameworkCore.yml rename to .github/workflows/package-Instrumentation.EntityFrameworkCore.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.EventCounters.yml rename to .github/workflows/package-Instrumentation.EventCounters.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.GrpcCore.yml rename to .github/workflows/package-Instrumentation.GrpcCore.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.Hangfire.yml rename to .github/workflows/package-Instrumentation.Hangfire.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.MassTransit.yml rename to .github/workflows/package-Instrumentation.MassTransit.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.MySqlData.yml rename to .github/workflows/package-Instrumentation.MySqlData.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.Owin.yml rename to .github/workflows/package-Instrumentation.Owin.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.Quartz.yml rename to .github/workflows/package-Instrumentation.Quartz.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.Runtime.yml rename to .github/workflows/package-Instrumentation.Runtime.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.StackExchangeRedis.yml rename to .github/workflows/package-Instrumentation.StackExchangeRedis.yml diff --git a/.github/workflows/publish-packages/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml similarity index 100% rename from .github/workflows/publish-packages/package-Instrumentation.Wcf.yml rename to .github/workflows/package-Instrumentation.Wcf.yml diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 2b6f4719f3..15e63c98a1 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -33,6 +33,30 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\linux-ci-md.yml = .github\workflows\linux-ci-md.yml .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml + .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml + .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml + .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml + .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml + .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml + .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml + .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml + .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml + .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml + .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml + .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml + .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml + .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml + .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml + .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml + .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml + .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml + .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml + .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml + .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml + .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml + .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml + .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml + .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml .github\workflows\windows-ci-md.yml = .github\workflows\windows-ci-md.yml @@ -209,34 +233,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EventCounters.Tests", "test\OpenTelemetry.Instrumentation.EventCounters.Tests\OpenTelemetry.Instrumentation.EventCounters.Tests.csproj", "{DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "publish-packages", "publish-packages", "{312FD546-F83E-4BD5-9BAE-FF90C7343D24}" - ProjectSection(SolutionItems) = preProject - .github\workflows\publish-packages\package-Exporter.Geneva.yml = .github\workflows\publish-packages\package-Exporter.Geneva.yml - .github\workflows\publish-packages\package-Exporter.Instana.yml = .github\workflows\publish-packages\package-Exporter.Instana.yml - .github\workflows\publish-packages\package-Exporter.Stackdriver.yml = .github\workflows\publish-packages\package-Exporter.Stackdriver.yml - .github\workflows\publish-packages\package-Extensions.AWSXRay.yml = .github\workflows\publish-packages\package-Extensions.AWSXRay.yml - .github\workflows\publish-packages\package-Extensions.Docker.yml = .github\workflows\publish-packages\package-Extensions.Docker.yml - .github\workflows\publish-packages\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\publish-packages\package-Extensions.PersistentStorage.Abstractions.yml - .github\workflows\publish-packages\package-Extensions.PersistentStorage.yml = .github\workflows\publish-packages\package-Extensions.PersistentStorage.yml - .github\workflows\publish-packages\package-Extensions.yml = .github\workflows\publish-packages\package-Extensions.yml - .github\workflows\publish-packages\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\publish-packages\package-Instrumentation.AspNet.TelemetryHttpModule.yml - .github\workflows\publish-packages\package-Instrumentation.AspNet.yml = .github\workflows\publish-packages\package-Instrumentation.AspNet.yml - .github\workflows\publish-packages\package-Instrumentation.AWS.yml = .github\workflows\publish-packages\package-Instrumentation.AWS.yml - .github\workflows\publish-packages\package-Instrumentation.AWSLambda.yml = .github\workflows\publish-packages\package-Instrumentation.AWSLambda.yml - .github\workflows\publish-packages\package-Instrumentation.Elasticsearch.yml = .github\workflows\publish-packages\package-Instrumentation.Elasticsearch.yml - .github\workflows\publish-packages\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\publish-packages\package-Instrumentation.EntityFrameworkCore.yml - .github\workflows\publish-packages\package-Instrumentation.EventCounters.yml = .github\workflows\publish-packages\package-Instrumentation.EventCounters.yml - .github\workflows\publish-packages\package-Instrumentation.GrpcCore.yml = .github\workflows\publish-packages\package-Instrumentation.GrpcCore.yml - .github\workflows\publish-packages\package-Instrumentation.Hangfire.yml = .github\workflows\publish-packages\package-Instrumentation.Hangfire.yml - .github\workflows\publish-packages\package-Instrumentation.MassTransit.yml = .github\workflows\publish-packages\package-Instrumentation.MassTransit.yml - .github\workflows\publish-packages\package-Instrumentation.MySqlData.yml = .github\workflows\publish-packages\package-Instrumentation.MySqlData.yml - .github\workflows\publish-packages\package-Instrumentation.Owin.yml = .github\workflows\publish-packages\package-Instrumentation.Owin.yml - .github\workflows\publish-packages\package-Instrumentation.Quartz.yml = .github\workflows\publish-packages\package-Instrumentation.Quartz.yml - .github\workflows\publish-packages\package-Instrumentation.Runtime.yml = .github\workflows\publish-packages\package-Instrumentation.Runtime.yml - .github\workflows\publish-packages\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\publish-packages\package-Instrumentation.StackExchangeRedis.yml - .github\workflows\publish-packages\package-Instrumentation.Wcf.yml = .github\workflows\publish-packages\package-Instrumentation.Wcf.yml - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -566,7 +562,6 @@ Global {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {AE12EFB7-4B1A-46B8-B89A-0375252B10B1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {312FD546-F83E-4BD5-9BAE-FF90C7343D24} = {43CAFE52-F329-4431-87DA-7FEE1454D9A9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From 781202d3c7b48aabf111dbc13bab31e77bafedec Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Tue, 23 Aug 2022 14:20:37 -0700 Subject: [PATCH 0305/1499] nit: updated package reference to use the variable from common.props (#602) --- .../OpenTelemetry.Extensions.Tests.csproj | 3 +-- .../OpenTelemetry.Instrumentation.EventCounters.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Owin.Tests.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index c3e00b0481..f561400b96 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry .NET SDK preview features and extensions @@ -17,7 +17,6 @@ - diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index e690787bfd..674b5abe6e 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -8,7 +8,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index aa7a7f9b68..36dc2b09eb 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -8,7 +8,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index c6936297f4..53896ddd2b 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry OWIN instrumentation @@ -17,7 +17,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index a0bd58a833..65615a0ce0 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -8,7 +8,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 25fac78dbc..1d26ebe0bc 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry WCF instrumentation @@ -27,7 +27,7 @@ - + From dc952171f259b14e4f4827ce5395a41479d6a1e7 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 23 Aug 2022 16:16:55 -0700 Subject: [PATCH 0306/1499] Update GenevaLogExporter Benchmarks (#605) --- .../Exporter/LogExporterBenchmarks.cs | 106 ++++++++++++++---- 1 file changed, 84 insertions(+), 22 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index b8bfae6677..b839bd5f14 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -15,28 +15,48 @@ // using System.Collections.Generic; +using System.Diagnostics; using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19044.1766 (21H2) -Intel Core i7-4790 CPU 3.60GHz (Haswell), 1 CPU, 8 logical and 4 physical cores -.NET SDK=6.0.301 - [Host] : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT - DefaultJob : .NET 6.0.6 (6.0.622.26707), X64 RyuJIT - - -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | -|-------------------------- |------------------------ |-----------:|---------:|---------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 1,107.3 ns | 19.34 ns | 17.15 ns | 0.0858 | 360 B | -| LoggerWithDirectLoggerAPI | False | 1,027.4 ns | 8.92 ns | 7.91 ns | 0.1183 | 496 B | -| LoggerWithSourceGenerator | False | 1,081.5 ns | 4.53 ns | 4.24 ns | 0.0763 | 320 B | -| SerializeLogRecord | False | 825.1 ns | 6.88 ns | 5.74 ns | 0.0305 | 128 B | -| LoggerWithMessageTemplate | True | 1,123.3 ns | 2.24 ns | 1.87 ns | 0.0858 | 360 B | -| LoggerWithDirectLoggerAPI | True | 1,005.8 ns | 2.26 ns | 2.00 ns | 0.1183 | 496 B | -| LoggerWithSourceGenerator | True | 1,083.9 ns | 8.73 ns | 6.82 ns | 0.0763 | 320 B | -| SerializeLogRecord | True | 827.1 ns | 6.45 ns | 6.03 ns | 0.0305 | 128 B | +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK=7.0.100-preview.6.22352.1 + [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + +Without Scopes + +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------- |------------------------ |---------:|---------:|---------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 979.5 ns | 11.46 ns | 10.72 ns | 0.0401 | 256 B | +| LoggerWithDirectLoggerAPI | False | 887.9 ns | 17.24 ns | 16.13 ns | 0.0620 | 392 B | +| LoggerWithSourceGenerator | False | 965.8 ns | 16.84 ns | 15.75 ns | 0.0343 | 216 B | +| SerializeLogRecord | False | 696.5 ns | 13.94 ns | 14.92 ns | 0.0038 | 24 B | +| Export | False | 744.9 ns | 12.91 ns | 12.08 ns | 0.0038 | 24 B | +| LoggerWithMessageTemplate | True | 978.6 ns | 18.95 ns | 19.46 ns | 0.0401 | 256 B | +| LoggerWithDirectLoggerAPI | True | 878.3 ns | 11.43 ns | 10.69 ns | 0.0620 | 392 B | +| LoggerWithSourceGenerator | True | 942.8 ns | 14.55 ns | 13.61 ns | 0.0343 | 216 B | +| SerializeLogRecord | True | 707.3 ns | 9.01 ns | 8.42 ns | 0.0038 | 24 B | +| Export | True | 752.0 ns | 8.97 ns | 7.49 ns | 0.0038 | 24 B | + + +With Scopes (https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/545) + +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Median | Gen 0 | Allocated | +|-------------------------- |------------------------ |-----------:|---------:|---------:|-----------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 1,042.8 ns | 19.34 ns | 54.55 ns | 1,022.1 ns | 0.0572 | 360 B | +| LoggerWithDirectLoggerAPI | False | 953.4 ns | 13.90 ns | 13.00 ns | 950.4 ns | 0.0782 | 496 B | +| LoggerWithSourceGenerator | False | 962.1 ns | 18.93 ns | 17.71 ns | 957.6 ns | 0.0496 | 320 B | +| SerializeLogRecord | False | 722.8 ns | 6.26 ns | 5.23 ns | 722.9 ns | 0.0200 | 128 B | +| Export | False | 789.2 ns | 15.11 ns | 14.14 ns | 787.3 ns | 0.0200 | 128 B | +| LoggerWithMessageTemplate | True | 986.8 ns | 12.56 ns | 11.13 ns | 983.4 ns | 0.0572 | 360 B | +| LoggerWithDirectLoggerAPI | True | 932.1 ns | 18.25 ns | 20.29 ns | 924.7 ns | 0.0782 | 496 B | +| LoggerWithSourceGenerator | True | 980.0 ns | 15.56 ns | 14.55 ns | 979.6 ns | 0.0496 | 320 B | +| SerializeLogRecord | True | 737.5 ns | 13.46 ns | 12.59 ns | 738.8 ns | 0.0200 | 128 B | +| Export | True | 772.2 ns | 14.02 ns | 13.11 ns | 774.8 ns | 0.0200 | 128 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark @@ -48,13 +68,14 @@ public class LogExporterBenchmarks private readonly ILoggerFactory loggerFactory; private readonly GenevaLogExporter exporter; private readonly LogRecord logRecord; + private readonly Batch batch; [Params(true, false)] public bool IncludeFormattedMessage { get; set; } public LogExporterBenchmarks() { - // for total cost of logging + msgpack serialization + // for total cost of logging + msgpack serialization + export this.loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(loggerOptions => { @@ -74,8 +95,9 @@ public LogExporterBenchmarks() this.logger = this.loggerFactory.CreateLogger("TestLogger"); - // For msgpack serialization alone + // For msgpack serialization + export this.logRecord = GenerateTestLogRecord(); + this.batch = GenerateTestLogRecordBatch(); this.exporter = new GenevaLogExporter(new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", @@ -123,18 +145,58 @@ public void SerializeLogRecord() this.exporter.SerializeLogRecord(this.logRecord); } - internal static LogRecord GenerateTestLogRecord() + [Benchmark] + public void Export() + { + this.exporter.Export(this.batch); + } + + [GlobalCleanup] + public void Cleanup() + { + this.loggerFactory.Dispose(); + this.batch.Dispose(); + this.exporter.Dispose(); + } + + private static LogRecord GenerateTestLogRecord() { var items = new List(1); - var factory = LoggerFactory.Create(builder => builder + using var factory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(loggerOptions => { loggerOptions.AddInMemoryExporter(items); })); - var logger = factory.CreateLogger("SerializationTest"); + var logger = factory.CreateLogger("TestLogger"); logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); return items[0]; } + + private static Batch GenerateTestLogRecordBatch() + { + var items = new List(1); + using var batchGeneratorExporter = new BatchGeneratorExporter(); + using var factory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(batchGeneratorExporter)); + })); + + var logger = factory.CreateLogger("TestLogger"); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return batchGeneratorExporter.Batch; + } + + private class BatchGeneratorExporter : BaseExporter + { + public Batch Batch { get; set; } + + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; + } + } } } From 426f1a6816be90d12cc8c1d6bcb3e8e2b176c771 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Tue, 23 Aug 2022 16:30:21 -0700 Subject: [PATCH 0307/1499] [Instrumentation.Process] Create src/test project files. (#596) --- .../comp_instrumentation_process.md | 41 ++++++++++++++++ .github/component_owners.yml | 2 + .../package-Instrumentation.Process.yml | 49 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 14 ++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 4 ++ .../AssemblyInfo.cs | 25 ++++++++++ .../MeterProviderBuilderExtensions.cs | 47 ++++++++++++++++++ ...enTelemetry.Instrumentation.Process.csproj | 19 +++++++ .../ProcessInstrumentationOptions.cs | 24 +++++++++ .../ProcessMetrics.cs | 38 ++++++++++++++ .../README.md | 48 ++++++++++++++++++ ...metry.Instrumentation.Process.Tests.csproj | 24 +++++++++ .../ProcessMetricsTests.cs | 21 ++++++++ 14 files changed, 356 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_process.md create mode 100644 .github/workflows/package-Instrumentation.Process.yml create mode 100644 src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj create mode 100644 src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs create mode 100644 src/OpenTelemetry.Instrumentation.Process/README.md create mode 100644 test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md new file mode 100644 index 0000000000..c91853c544 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Process +about: Issue with OpenTelemetry.Instrumentation.Process +labels: comp:instrumentation.process +--- + +# Issue with OpenTelemetry.Instrumentation.Process + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Process version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 969e074b50..d8973e3081 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -44,6 +44,8 @@ components: - moonheart src/OpenTelemetry.Instrumentation.Owin/: - codeblanch + src/OpenTelemetry.Instrumentation.Process/: + - Yun-Ting src/OpenTelemetry.Instrumentation.Quartz/: - maldago src/OpenTelemetry.Instrumentation.Runtime/: diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml new file mode 100644 index 0000000000..3b4d609a0b --- /dev/null +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Instrumentation.Process + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.Process-*' # trigger when we create a tag with prefix "Instrumentation.Process-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.Process + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 15e63c98a1..ec6c76ee44 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -233,6 +233,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EventCounters.Tests", "test\OpenTelemetry.Instrumentation.EventCounters.Tests\OpenTelemetry.Instrumentation.EventCounters.Tests.csproj", "{DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Process", "src\OpenTelemetry.Instrumentation.Process\OpenTelemetry.Instrumentation.Process.csproj", "{F811262D-D78A-4C4A-8A31-FFC458164BF2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Process.Tests", "test\OpenTelemetry.Instrumentation.Process.Tests\OpenTelemetry.Instrumentation.Process.Tests.csproj", "{61421ACF-5F90-491B-AFB3-14EF12CCA255}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -487,6 +491,14 @@ Global {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Debug|Any CPU.Build.0 = Debug|Any CPU {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Release|Any CPU.ActiveCfg = Release|Any CPU {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896}.Release|Any CPU.Build.0 = Release|Any CPU + {F811262D-D78A-4C4A-8A31-FFC458164BF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F811262D-D78A-4C4A-8A31-FFC458164BF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F811262D-D78A-4C4A-8A31-FFC458164BF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F811262D-D78A-4C4A-8A31-FFC458164BF2}.Release|Any CPU.Build.0 = Release|Any CPU + {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -562,6 +574,8 @@ Global {9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {AE12EFB7-4B1A-46B8-B89A-0375252B10B1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {F811262D-D78A-4C4A-8A31-FFC458164BF2} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {61421ACF-5F90-491B-AFB3-14EF12CCA255} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..0247a31728 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions +OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions.ProcessInstrumentationOptions() -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs new file mode 100644 index 0000000000..dfc38d71b6 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Runtime.CompilerServices; + +[assembly: CLSCompliant(false)] +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Process.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Process.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..516945ebd1 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Instrumentation.Process; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class MeterProviderBuilderExtensions +{ + /// + /// Enables runtime instrumentation. + /// + /// being configured. + /// Runtime metrics options. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddProcessInstrumentation( + this MeterProviderBuilder builder, + Action configure = null) + { + Guard.ThrowIfNull(builder); + + var options = new ProcessInstrumentationOptions(); + configure?.Invoke(options); + + var instrumentation = new ProcessMetrics(options); + builder.AddMeter(ProcessMetrics.MeterInstance.Name); + return builder.AddInstrumentation(() => instrumentation); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj new file mode 100644 index 0000000000..f4d3822b0c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -0,0 +1,19 @@ + + + netstandard2.0 + dotnet process instrumentation for OpenTelemetry .NET + $(PackageTags);process + Instrumentation.Process- + true + true + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs new file mode 100644 index 0000000000..bc5b7ddef8 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs @@ -0,0 +1,24 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Process; + +/// +/// Options to define the process metrics. +/// +public class ProcessInstrumentationOptions +{ +} diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs new file mode 100644 index 0000000000..930279d669 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; +using System.Reflection; + +namespace OpenTelemetry.Instrumentation.Process; + +internal class ProcessMetrics +{ + internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); + internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); + + static ProcessMetrics() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The options to define the metrics. + public ProcessMetrics(ProcessInstrumentationOptions options) + { + } +} diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md new file mode 100644 index 0000000000..a0fc4b1faa --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -0,0 +1,48 @@ +# Process Instrumentation for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Process.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Process.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments [.NET](https://docs.microsoft.com/dotnet) and +collect telemetry about process behavior. + +## Steps to enable OpenTelemetry.Instrumentation.Process + +### Step 1: Install package + +Add a reference to +[`OpenTelemetry.Instrumentation.Process`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) +package. + +```shell +dotnet add package OpenTelemetry.Instrumentation.Process +``` + +Add a reference to +[`OpenTelemetry.Exporter.Prometheus.HttpListener`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.HttpListener) +package. + +```shell +dotnet add package --prerelease OpenTelemetry.Exporter.Prometheus.HttpListener +``` + +### Step 2: Enable Process instrumentation + +Process instrumentation should be enabled at application startup using the +`AddProcessInstrumentation` extension on `MeterProviderBuilder`: + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddPrometheusHttpListener( + options => options.UriPrefixes = new string[] { "http://localhost:9464/" }) + .Build(); +``` + +## Metrics + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj new file mode 100644 index 0000000000..031dce0c55 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -0,0 +1,24 @@ + + + + netcoreapp3.1;net6.0 + $(TargetFrameworks);net462 + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs new file mode 100644 index 0000000000..701679c659 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -0,0 +1,21 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Instrumentation.Process.Tests; + +public class ProcessMetricsTests +{ +} From 58cfd202ffad0079e3d829c7ada023aa17e2187d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 23 Aug 2022 17:07:00 -0700 Subject: [PATCH 0308/1499] Update CONTRIBUTING doc (#606) --- CONTRIBUTING.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c478652d4..40821dff41 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -205,16 +205,16 @@ by you. To ensure your project is versioned appropriately, specify a to be triggered when a tag with prefix "Instrumentation.FooBar-" is pushed to the main branch. The workflow file should be named as `package-Instrumentation.FooBar.yml` and to be placed in the -`.github/workflows/publish-packages/` folder. +`.github/workflows/` folder. You can copy one of the [existing workflow - files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml) + files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml) and replace the workflow - [`name`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml#L1) + [`name`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L1) with "Pack OpenTelemetry.Instrumentation.FooBar", - [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml#L12) + [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L12) with "Instrumentation.FooBar-*" and - [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/publish-packages/package-Instrumentation.AspNet.yml#L18) + [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L18) with "OpenTelemetry.Instrumentation.FooBar". * Add an issue template in your PR. You can follow the existing issue templates, From 54f22bb22607aa32f65c1349f605ae393381d5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 25 Aug 2022 17:53:49 +0200 Subject: [PATCH 0309/1499] File scoped namespace for examples and leftovers (#609) --- .../Controllers/WeatherForecastController.cs | 51 +- .../EchoService.cs | 19 +- .../Examples.GrpcCore.AspNetCore/Program.cs | 33 +- .../Examples.GrpcCore.AspNetCore/Startup.cs | 129 +- .../WeatherForecast.cs | 15 +- examples/owin/Controllers/TestController.cs | 14 +- examples/owin/Program.cs | 81 +- .../Examples.StackExchangeRedis/Program.cs | 3 +- examples/wcf/client-core/Program.cs | 97 +- .../wcf/client-core/StatusServiceClient.cs | 43 +- examples/wcf/client-netframework/Program.cs | 79 +- .../StatusServiceClient.cs | 35 +- examples/wcf/server-netframework/Program.cs | 29 +- .../wcf/server-netframework/StatusService.cs | 31 +- examples/wcf/shared/IStatusServiceContract.cs | 13 +- examples/wcf/shared/StatusRequest.cs | 13 +- examples/wcf/shared/StatusResponse.cs | 13 +- .../Exporter/Food.cs | 19 +- .../Exporter/LogExporterBenchmarks.cs | 222 ++- .../Exporter/MetricExporterBenchmarks.cs | 867 +++++---- .../Exporter/TraceExporterBenchmarks.cs | 154 +- .../Program.cs | 9 +- .../DummyServer.cs | 125 +- .../Program.cs | 227 ++- .../ConnectionStringBuilderTests.cs | 419 +++-- .../GenevaLogExporterTests.cs | 1548 ++++++++--------- .../GenevaMetricExporterOptionsTests.cs | 105 +- .../GenevaMetricExporterTests.cs | 1160 ++++++------ .../GenevaTraceExporterTests.cs | 954 +++++----- .../MessagePackSerializerTests.cs | 625 ++++--- .../MetricsContract.cs | 1163 +++++++------ .../UnixDomainSocketDataTransportTests.cs | 307 ++-- .../UnixDomainSocketEndPointTests.cs | 97 +- .../Resources/TempFile.cs | 63 +- 34 files changed, 4361 insertions(+), 4401 deletions(-) diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index 7b9f689d90..69ceb10bcb 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -20,38 +20,37 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -namespace Examples.GrpcCore.AspNetCore.Controllers +namespace Examples.GrpcCore.AspNetCore.Controllers; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase { - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase + private static readonly string[] Summaries = new[] { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", - }; + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", + }; - private readonly Echo.EchoClient echoClient; + private readonly Echo.EchoClient echoClient; - public WeatherForecastController(Echo.EchoClient echoClient) - { - this.echoClient = echoClient; - } + public WeatherForecastController(Echo.EchoClient echoClient) + { + this.echoClient = echoClient; + } - [HttpGet] - public async Task> Get() - { - var echoCall = this.echoClient.EchoAsync(new EchoRequest { Message = "Hello" }); - var echoResponse = await echoCall.ResponseAsync.ConfigureAwait(false); + [HttpGet] + public async Task> Get() + { + var echoCall = this.echoClient.EchoAsync(new EchoRequest { Message = "Hello" }); + var echoResponse = await echoCall.ResponseAsync.ConfigureAwait(false); - var rng = new Random(); - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = rng.Next(-20, 55), - Summary = Summaries[rng.Next(Summaries.Length)], - }) + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)], + }) .ToArray(); - } } } diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs index 688478c96f..46c9269931 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs @@ -17,17 +17,16 @@ using System.Threading.Tasks; using Grpc.Core; -namespace Examples.GrpcCore.AspNetCore +namespace Examples.GrpcCore.AspNetCore; + +/// +/// Simple implementation of the echo service. +/// +internal class EchoService : Echo.EchoBase { - /// - /// Simple implementation of the echo service. - /// - internal class EchoService : Echo.EchoBase + /// + public override Task Echo(EchoRequest request, ServerCallContext context) { - /// - public override Task Echo(EchoRequest request, ServerCallContext context) - { - return Task.FromResult(new EchoResponse { Message = request.Message }); - } + return Task.FromResult(new EchoResponse { Message = request.Message }); } } diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs index fc53b160af..f9b834c954 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs @@ -17,24 +17,23 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; -namespace Examples.GrpcCore.AspNetCore -{ - public class Program - { - internal const int Port = 5000; - internal const int GrpcServicePort = 5001; +namespace Examples.GrpcCore.AspNetCore; - public static void Main(string[] args) - { - CreateHostBuilder(args).Build().Run(); - } +public class Program +{ + internal const int Port = 5000; + internal const int GrpcServicePort = 5001; - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseUrls($"http://+:{Port}"); - webBuilder.UseStartup(); - }); + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseUrls($"http://+:{Port}"); + webBuilder.UseStartup(); + }); } diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index 607462e16c..374ec30c48 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -26,92 +26,91 @@ using OpenTelemetry.Instrumentation.GrpcCore; using OpenTelemetry.Trace; -namespace Examples.GrpcCore.AspNetCore +namespace Examples.GrpcCore.AspNetCore; + +public class Startup { - public class Startup + public Startup(IConfiguration configuration) { - public Startup(IConfiguration configuration) - { - this.Configuration = configuration; - } + this.Configuration = configuration; + } - public IConfiguration Configuration { get; } + public IConfiguration Configuration { get; } - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddControllers(); + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); - // Wire in otel - services.AddOpenTelemetryTracing( - (builder) => builder - .AddAspNetCoreInstrumentation() - .AddGrpcCoreInstrumentation() - .AddConsoleExporter()); + // Wire in otel + services.AddOpenTelemetryTracing( + (builder) => builder + .AddAspNetCoreInstrumentation() + .AddGrpcCoreInstrumentation() + .AddConsoleExporter()); - // We are running an in-process gRPC Core service. - services.AddHostedService(); + // We are running an in-process gRPC Core service. + services.AddHostedService(); - // Add a singleton for the gRPC client to our local service. - services.AddSingleton(provider => - { - var channel = new Channel($"dns:localhost:{Program.GrpcServicePort}", ChannelCredentials.Insecure); + // Add a singleton for the gRPC client to our local service. + services.AddSingleton(provider => + { + var channel = new Channel($"dns:localhost:{Program.GrpcServicePort}", ChannelCredentials.Insecure); - var callInvoker = channel.CreateCallInvoker() - .Intercept(new ClientTracingInterceptor(new ClientTracingInterceptorOptions())); + var callInvoker = channel.CreateCallInvoker() + .Intercept(new ClientTracingInterceptor(new ClientTracingInterceptorOptions())); - return new Echo.EchoClient(callInvoker); - }); - } + return new Echo.EchoClient(callInvoker); + }); + } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } + app.UseDeveloperExceptionPage(); + } - app.UseRouting(); + app.UseRouting(); - app.UseAuthorization(); + app.UseAuthorization(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } - /// - /// A hosted service wrapper for an in-process gRPC Core service. - /// This gRPC service is instrumented using the server interceptor. - /// - private sealed class EchoGrpcHostedService : BackgroundService + /// + /// A hosted service wrapper for an in-process gRPC Core service. + /// This gRPC service is instrumented using the server interceptor. + /// + private sealed class EchoGrpcHostedService : BackgroundService + { + protected override Task ExecuteAsync(CancellationToken stoppingToken) { - protected override Task ExecuteAsync(CancellationToken stoppingToken) - { - var serviceDefinition = Echo.BindService(new EchoService()) - .Intercept(new ServerTracingInterceptor(new ServerTracingInterceptorOptions())); + var serviceDefinition = Echo.BindService(new EchoService()) + .Intercept(new ServerTracingInterceptor(new ServerTracingInterceptorOptions())); - var server = new Server - { - Ports = { new ServerPort("localhost", Program.GrpcServicePort, ServerCredentials.Insecure) }, - Services = { serviceDefinition }, - }; + var server = new Server + { + Ports = { new ServerPort("localhost", Program.GrpcServicePort, ServerCredentials.Insecure) }, + Services = { serviceDefinition }, + }; - server.Start(); + server.Start(); - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); - var tokenRegistration = stoppingToken.Register( - async () => - { - await server.ShutdownAsync().ConfigureAwait(false); - tcs.SetResult(true); - }); + var tokenRegistration = stoppingToken.Register( + async () => + { + await server.ShutdownAsync().ConfigureAwait(false); + tcs.SetResult(true); + }); - return tcs.Task.ContinueWith(antecedent => tokenRegistration.Dispose()); - } + return tcs.Task.ContinueWith(antecedent => tokenRegistration.Dispose()); } } } diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index 0c2f9fd7eb..f840e9cfce 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -16,16 +16,15 @@ using System; -namespace Examples.GrpcCore.AspNetCore +namespace Examples.GrpcCore.AspNetCore; + +public class WeatherForecast { - public class WeatherForecast - { - public DateTime Date { get; set; } + public DateTime Date { get; set; } - public int TemperatureC { get; set; } + public int TemperatureC { get; set; } - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); + public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); - public string Summary { get; set; } - } + public string Summary { get; set; } } diff --git a/examples/owin/Controllers/TestController.cs b/examples/owin/Controllers/TestController.cs index ad469faf07..c47aa92312 100644 --- a/examples/owin/Controllers/TestController.cs +++ b/examples/owin/Controllers/TestController.cs @@ -14,17 +14,15 @@ // limitations under the License. // -using System; using System.Web.Http; -namespace Examples.Owin.Controllers +namespace Examples.Owin.Controllers; + +public class TestController : ApiController { - public class TestController : ApiController + // GET api/test/{id} + public string Get(string id = null) { - // GET api/test/{id} - public string Get(string id = null) - { - return $"id:{id}"; - } + return $"id:{id}"; } } diff --git a/examples/owin/Program.cs b/examples/owin/Program.cs index a9bab679c5..2267c5399c 100644 --- a/examples/owin/Program.cs +++ b/examples/owin/Program.cs @@ -26,60 +26,59 @@ using OpenTelemetry.Trace; using Owin; -namespace Examples.Owin +namespace Examples.Owin; + +internal static class Program { - internal static class Program + public static void Main() { - public static void Main() - { - using var host = WebApp.Start( - "http://localhost:9000", - appBuilder => - { - // Add OpenTelemetry early in the pipeline to start timing - // the request as soon as possible. - appBuilder.UseOpenTelemetry(); + using var host = WebApp.Start( + "http://localhost:9000", + appBuilder => + { + // Add OpenTelemetry early in the pipeline to start timing + // the request as soon as possible. + appBuilder.UseOpenTelemetry(); - HttpConfiguration config = new HttpConfiguration(); + HttpConfiguration config = new HttpConfiguration(); - config.MessageHandlers.Add(new ActivityDisplayNameRouteEnrichingHandler()); + config.MessageHandlers.Add(new ActivityDisplayNameRouteEnrichingHandler()); - config.Routes.MapHttpRoute( - name: "DefaultApi", - routeTemplate: "api/{controller}/{id}", - defaults: new { id = RouteParameter.Optional }); + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional }); - appBuilder.UseWebApi(config); - }); + appBuilder.UseWebApi(config); + }); - using var openTelemetry = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Owin-Example")) - .AddOwinInstrumentation() - .AddConsoleExporter() - .Build(); + using var openTelemetry = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Owin-Example")) + .AddOwinInstrumentation() + .AddConsoleExporter() + .Build(); - Console.WriteLine("Service listening. Press enter to exit."); - Console.ReadLine(); - } + Console.WriteLine("Service listening. Press enter to exit."); + Console.ReadLine(); + } - private class ActivityDisplayNameRouteEnrichingHandler : DelegatingHandler + private class ActivityDisplayNameRouteEnrichingHandler : DelegatingHandler + { + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + try { - try - { - return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); - } - finally + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + } + finally + { + var activity = Activity.Current; + if (activity != null) { - var activity = Activity.Current; - if (activity != null) + var routeData = request.GetRouteData(); + if (routeData != null) { - var routeData = request.GetRouteData(); - if (routeData != null) - { - activity.DisplayName = routeData.Route.RouteTemplate; - } + activity.DisplayName = routeData.Route.RouteTemplate; } } } diff --git a/examples/redis/Examples.StackExchangeRedis/Program.cs b/examples/redis/Examples.StackExchangeRedis/Program.cs index b36b680f5a..e395b698b5 100644 --- a/examples/redis/Examples.StackExchangeRedis/Program.cs +++ b/examples/redis/Examples.StackExchangeRedis/Program.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System.Diagnostics; using OpenTelemetry; using OpenTelemetry.Trace; using StackExchange.Redis; @@ -37,7 +36,7 @@ public static void Main() .AddConsoleExporter() .AddRedisInstrumentation(connection, options => { - // changing flushinterval from 10s to 5s + // changing flush interval from 10s to 5s options.FlushInterval = TimeSpan.FromSeconds(5); }) .Build(); diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index c1b958d6c6..96504c1f0c 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -25,70 +25,69 @@ using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace Examples.Wcf.Client +namespace Examples.Wcf.Client; + +internal static class Program { - internal static class Program + public static async Task Main() { - public static async Task Main() - { - IConfigurationRoot config = new ConfigurationBuilder() - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json") - .Build(); + IConfigurationRoot config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); - using var openTelemetry = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Wcf-Client-Core")) - .AddWcfInstrumentation() - .AddZipkinExporter() - .Build(); + using var openTelemetry = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Wcf-Client-Core")) + .AddWcfInstrumentation() + .AddZipkinExporter() + .Build(); - await CallService( - new BasicHttpBinding(BasicHttpSecurityMode.None), - new EndpointAddress(config.GetSection("Service").GetValue("HttpAddress"))).ConfigureAwait(false); - await CallService( - new NetTcpBinding(SecurityMode.None), - new EndpointAddress(config.GetSection("Service").GetValue("TcpAddress"))).ConfigureAwait(false); + await CallService( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(config.GetSection("Service").GetValue("HttpAddress"))).ConfigureAwait(false); + await CallService( + new NetTcpBinding(SecurityMode.None), + new EndpointAddress(config.GetSection("Service").GetValue("TcpAddress"))).ConfigureAwait(false); - Console.WriteLine("Press enter to exit."); - Console.ReadLine(); - } + Console.WriteLine("Press enter to exit."); + Console.ReadLine(); + } - private static async Task CallService(Binding binding, EndpointAddress remoteAddress) + private static async Task CallService(Binding binding, EndpointAddress remoteAddress) + { + // Note: Best practice is to re-use your client/channel instances. + // This code is not meant to illustrate best practices, only the + // instrumentation. + StatusServiceClient client = new StatusServiceClient(binding, remoteAddress); + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + try { - // Note: Best practice is to re-use your client/channel instances. - // This code is not meant to illustrate best practices, only the - // instrumentation. - StatusServiceClient client = new StatusServiceClient(binding, remoteAddress); - client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - try - { - await client.OpenAsync().ConfigureAwait(false); + await client.OpenAsync().ConfigureAwait(false); - var response = await client.PingAsync( - new StatusRequest - { - Status = Guid.NewGuid().ToString("N"), - }).ConfigureAwait(false); + var response = await client.PingAsync( + new StatusRequest + { + Status = Guid.NewGuid().ToString("N"), + }).ConfigureAwait(false); - Console.WriteLine($"Server returned: {response?.ServerTime}"); - } - finally + Console.WriteLine($"Server returned: {response?.ServerTime}"); + } + finally + { + try { - try + if (client.State == CommunicationState.Faulted) { - if (client.State == CommunicationState.Faulted) - { - client.Abort(); - } - else - { - await client.CloseAsync().ConfigureAwait(false); - } + client.Abort(); } - catch + else { + await client.CloseAsync().ConfigureAwait(false); } } + catch + { + } } } } diff --git a/examples/wcf/client-core/StatusServiceClient.cs b/examples/wcf/client-core/StatusServiceClient.cs index 11a2e533f4..ac8e4a2301 100644 --- a/examples/wcf/client-core/StatusServiceClient.cs +++ b/examples/wcf/client-core/StatusServiceClient.cs @@ -18,33 +18,32 @@ using System.ServiceModel.Channels; using System.Threading.Tasks; -namespace Examples.Wcf.Client +namespace Examples.Wcf.Client; + +public class StatusServiceClient : ClientBase, IStatusServiceContract { - public class StatusServiceClient : ClientBase, IStatusServiceContract + public StatusServiceClient(string name) + : base(name) { - public StatusServiceClient(string name) - : base(name) - { - } + } - public StatusServiceClient(Binding binding, EndpointAddress remoteAddress) - : base(binding, remoteAddress) - { - } + public StatusServiceClient(Binding binding, EndpointAddress remoteAddress) + : base(binding, remoteAddress) + { + } - public Task PingAsync(StatusRequest request) - => this.Channel.PingAsync(request); + public Task PingAsync(StatusRequest request) + => this.Channel.PingAsync(request); - public Task OpenAsync() - { - ICommunicationObject communicationObject = this; - return Task.Factory.FromAsync(communicationObject.BeginOpen, communicationObject.EndOpen, null); - } + public Task OpenAsync() + { + ICommunicationObject communicationObject = this; + return Task.Factory.FromAsync(communicationObject.BeginOpen, communicationObject.EndOpen, null); + } - public Task CloseAsync() - { - ICommunicationObject communicationObject = this; - return Task.Factory.FromAsync(communicationObject.BeginClose, communicationObject.EndClose, null); - } + public Task CloseAsync() + { + ICommunicationObject communicationObject = this; + return Task.Factory.FromAsync(communicationObject.BeginClose, communicationObject.EndClose, null); } } diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index 19882fef1a..dddbedcf1e 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -21,60 +21,59 @@ using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace Examples.Wcf.Client +namespace Examples.Wcf.Client; + +internal static class Program { - internal static class Program + public static async Task Main() { - public static async Task Main() - { - using var openTelemetry = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Wcf-Client")) - .AddWcfInstrumentation() - .AddZipkinExporter() - .Build(); + using var openTelemetry = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Wcf-Client")) + .AddWcfInstrumentation() + .AddZipkinExporter() + .Build(); - await CallService("StatusService_Http").ConfigureAwait(false); - await CallService("StatusService_Tcp").ConfigureAwait(false); + await CallService("StatusService_Http").ConfigureAwait(false); + await CallService("StatusService_Tcp").ConfigureAwait(false); - Console.WriteLine("Press enter to exit."); - Console.ReadLine(); - } + Console.WriteLine("Press enter to exit."); + Console.ReadLine(); + } - private static async Task CallService(string name) + private static async Task CallService(string name) + { + // Note: Best practice is to re-use your client/channel instances. + // This code is not meant to illustrate best practices, only the + // instrumentation. + StatusServiceClient client = new StatusServiceClient(name); + try { - // Note: Best practice is to re-use your client/channel instances. - // This code is not meant to illustrate best practices, only the - // instrumentation. - StatusServiceClient client = new StatusServiceClient(name); - try - { - await client.OpenAsync().ConfigureAwait(false); + await client.OpenAsync().ConfigureAwait(false); - var response = await client.PingAsync( - new StatusRequest - { - Status = Guid.NewGuid().ToString("N"), - }).ConfigureAwait(false); + var response = await client.PingAsync( + new StatusRequest + { + Status = Guid.NewGuid().ToString("N"), + }).ConfigureAwait(false); - Console.WriteLine($"Server returned: {response?.ServerTime}"); - } - finally + Console.WriteLine($"Server returned: {response?.ServerTime}"); + } + finally + { + try { - try + if (client.State == CommunicationState.Faulted) { - if (client.State == CommunicationState.Faulted) - { - client.Abort(); - } - else - { - await client.CloseAsync().ConfigureAwait(false); - } + client.Abort(); } - catch + else { + await client.CloseAsync().ConfigureAwait(false); } } + catch + { + } } } } diff --git a/examples/wcf/client-netframework/StatusServiceClient.cs b/examples/wcf/client-netframework/StatusServiceClient.cs index 5cfe67a273..b7c28e21e5 100644 --- a/examples/wcf/client-netframework/StatusServiceClient.cs +++ b/examples/wcf/client-netframework/StatusServiceClient.cs @@ -17,28 +17,27 @@ using System.ServiceModel; using System.Threading.Tasks; -namespace Examples.Wcf.Client +namespace Examples.Wcf.Client; + +public class StatusServiceClient : ClientBase, IStatusServiceContract { - public class StatusServiceClient : ClientBase, IStatusServiceContract + public StatusServiceClient(string name) + : base(name) { - public StatusServiceClient(string name) - : base(name) - { - } + } - public Task PingAsync(StatusRequest request) - => this.Channel.PingAsync(request); + public Task PingAsync(StatusRequest request) + => this.Channel.PingAsync(request); - public Task OpenAsync() - { - ICommunicationObject communicationObject = this; - return Task.Factory.FromAsync(communicationObject.BeginOpen, communicationObject.EndOpen, null); - } + public Task OpenAsync() + { + ICommunicationObject communicationObject = this; + return Task.Factory.FromAsync(communicationObject.BeginOpen, communicationObject.EndOpen, null); + } - public Task CloseAsync() - { - ICommunicationObject communicationObject = this; - return Task.Factory.FromAsync(communicationObject.BeginClose, communicationObject.EndClose, null); - } + public Task CloseAsync() + { + ICommunicationObject communicationObject = this; + return Task.Factory.FromAsync(communicationObject.BeginClose, communicationObject.EndClose, null); } } diff --git a/examples/wcf/server-netframework/Program.cs b/examples/wcf/server-netframework/Program.cs index c09b115db4..a2a230b5fd 100644 --- a/examples/wcf/server-netframework/Program.cs +++ b/examples/wcf/server-netframework/Program.cs @@ -20,25 +20,24 @@ using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace Examples.Wcf.Server +namespace Examples.Wcf.Server; + +internal static class Program { - internal static class Program + public static void Main() { - public static void Main() - { - using var openTelemetry = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Wcf-Server")) - .AddWcfInstrumentation() - .AddZipkinExporter() - .Build(); + using var openTelemetry = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Wcf-Server")) + .AddWcfInstrumentation() + .AddZipkinExporter() + .Build(); - ServiceHost serviceHost = new ServiceHost(typeof(StatusService)); - serviceHost.Open(); + ServiceHost serviceHost = new ServiceHost(typeof(StatusService)); + serviceHost.Open(); - Console.WriteLine("Service listening. Press enter to exit."); - Console.ReadLine(); + Console.WriteLine("Service listening. Press enter to exit."); + Console.ReadLine(); - serviceHost.Close(); - } + serviceHost.Close(); } } diff --git a/examples/wcf/server-netframework/StatusService.cs b/examples/wcf/server-netframework/StatusService.cs index e2553b9020..e173d122a3 100644 --- a/examples/wcf/server-netframework/StatusService.cs +++ b/examples/wcf/server-netframework/StatusService.cs @@ -18,23 +18,22 @@ using System.ServiceModel; using System.Threading.Tasks; -namespace Examples.Wcf.Server +namespace Examples.Wcf.Server; + +[ServiceBehavior( + Namespace = "http://opentelemetry.io/", + ConcurrencyMode = ConcurrencyMode.Multiple, + InstanceContextMode = InstanceContextMode.Single, + UseSynchronizationContext = false, + Name = "StatusService")] +public class StatusService : IStatusServiceContract { - [ServiceBehavior( - Namespace = "http://opentelemetry.io/", - ConcurrencyMode = ConcurrencyMode.Multiple, - InstanceContextMode = InstanceContextMode.Single, - UseSynchronizationContext = false, - Name = "StatusService")] - public class StatusService : IStatusServiceContract + public Task PingAsync(StatusRequest request) { - public Task PingAsync(StatusRequest request) - { - return Task.FromResult( - new StatusResponse - { - ServerTime = DateTimeOffset.UtcNow, - }); - } + return Task.FromResult( + new StatusResponse + { + ServerTime = DateTimeOffset.UtcNow, + }); } } diff --git a/examples/wcf/shared/IStatusServiceContract.cs b/examples/wcf/shared/IStatusServiceContract.cs index cf7c8a73ad..0c620e9472 100644 --- a/examples/wcf/shared/IStatusServiceContract.cs +++ b/examples/wcf/shared/IStatusServiceContract.cs @@ -17,12 +17,11 @@ using System.ServiceModel; using System.Threading.Tasks; -namespace Examples.Wcf +namespace Examples.Wcf; + +[ServiceContract(Namespace = "http://opentelemetry.io/", Name = "StatusService", SessionMode = SessionMode.Allowed)] +public interface IStatusServiceContract { - [ServiceContract(Namespace = "http://opentelemetry.io/", Name = "StatusService", SessionMode = SessionMode.Allowed)] - public interface IStatusServiceContract - { - [OperationContract] - Task PingAsync(StatusRequest request); - } + [OperationContract] + Task PingAsync(StatusRequest request); } diff --git a/examples/wcf/shared/StatusRequest.cs b/examples/wcf/shared/StatusRequest.cs index 1061df0261..701b1f3bee 100644 --- a/examples/wcf/shared/StatusRequest.cs +++ b/examples/wcf/shared/StatusRequest.cs @@ -16,12 +16,11 @@ using System.Runtime.Serialization; -namespace Examples.Wcf +namespace Examples.Wcf; + +[DataContract] +public class StatusRequest { - [DataContract] - public class StatusRequest - { - [DataMember] - public string Status { get; set; } - } + [DataMember] + public string Status { get; set; } } diff --git a/examples/wcf/shared/StatusResponse.cs b/examples/wcf/shared/StatusResponse.cs index b3d43b27c0..1207917842 100644 --- a/examples/wcf/shared/StatusResponse.cs +++ b/examples/wcf/shared/StatusResponse.cs @@ -17,12 +17,11 @@ using System; using System.Runtime.Serialization; -namespace Examples.Wcf +namespace Examples.Wcf; + +[DataContract] +public class StatusResponse { - [DataContract] - public class StatusResponse - { - [DataMember] - public DateTimeOffset ServerTime { get; set; } - } + [DataMember] + public DateTimeOffset ServerTime { get; set; } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs index 8ce08e7269..5c553eb788 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs @@ -16,15 +16,14 @@ using Microsoft.Extensions.Logging; -namespace OpenTelemetry.Exporter.Geneva.Benchmark +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +public static partial class Food { - public static partial class Food - { - [LoggerMessage( - EventId = 0, - Level = LogLevel.Information, - Message = "Hello from {food} {price}.")] - public static partial void SayHello( - ILogger logger, string food, double price); - } + [LoggerMessage( + EventId = 0, + Level = LogLevel.Information, + Message = "Hello from {food} {price}.")] + public static partial void SayHello( + ILogger logger, string food, double price); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index b839bd5f14..876d10f014 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -15,7 +15,6 @@ // using System.Collections.Generic; -using System.Diagnostics; using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; @@ -59,69 +58,69 @@ With Scopes (https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull | Export | True | 772.2 ns | 14.02 ns | 13.11 ns | 774.8 ns | 0.0200 | 128 B | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +[MemoryDiagnoser] +public class LogExporterBenchmarks { - [MemoryDiagnoser] - public class LogExporterBenchmarks - { - private readonly ILogger logger; - private readonly ILoggerFactory loggerFactory; - private readonly GenevaLogExporter exporter; - private readonly LogRecord logRecord; - private readonly Batch batch; + private readonly ILogger logger; + private readonly ILoggerFactory loggerFactory; + private readonly GenevaLogExporter exporter; + private readonly LogRecord logRecord; + private readonly Batch batch; - [Params(true, false)] - public bool IncludeFormattedMessage { get; set; } + [Params(true, false)] + public bool IncludeFormattedMessage { get; set; } - public LogExporterBenchmarks() - { - // for total cost of logging + msgpack serialization + export - this.loggerFactory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(loggerOptions => - { - loggerOptions.AddGenevaLogExporter(exporterOptions => - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - exporterOptions.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }); - - loggerOptions.IncludeFormattedMessage = this.IncludeFormattedMessage; - })); - - this.logger = this.loggerFactory.CreateLogger("TestLogger"); - - // For msgpack serialization + export - this.logRecord = GenerateTestLogRecord(); - this.batch = GenerateTestLogRecordBatch(); - this.exporter = new GenevaLogExporter(new GenevaExporterOptions + public LogExporterBenchmarks() + { + // for total cost of logging + msgpack serialization + export + this.loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary + loggerOptions.AddGenevaLogExporter(exporterOptions => { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }); - } + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + exporterOptions.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); - [Benchmark] - public void LoggerWithMessageTemplate() - { - this.logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - } + loggerOptions.IncludeFormattedMessage = this.IncludeFormattedMessage; + })); + + this.logger = this.loggerFactory.CreateLogger("TestLogger"); - [Benchmark] - public void LoggerWithDirectLoggerAPI() + // For msgpack serialization + export + this.logRecord = GenerateTestLogRecord(); + this.batch = GenerateTestLogRecordBatch(); + this.exporter = new GenevaLogExporter(new GenevaExporterOptions { - var food = "artichoke"; - var price = 3.99; - this.logger.Log( + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + } + + [Benchmark] + public void LoggerWithMessageTemplate() + { + this.logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + + [Benchmark] + public void LoggerWithDirectLoggerAPI() + { + var food = "artichoke"; + var price = 3.99; + this.logger.Log( logLevel: LogLevel.Information, eventId: default, state: new List>() @@ -131,72 +130,71 @@ public void LoggerWithDirectLoggerAPI() }, exception: null, formatter: (state, ex) => $"Hello from {food} {price}."); - } + } - [Benchmark] - public void LoggerWithSourceGenerator() - { - Food.SayHello(this.logger, "artichoke", 3.99); - } + [Benchmark] + public void LoggerWithSourceGenerator() + { + Food.SayHello(this.logger, "artichoke", 3.99); + } - [Benchmark] - public void SerializeLogRecord() - { - this.exporter.SerializeLogRecord(this.logRecord); - } + [Benchmark] + public void SerializeLogRecord() + { + this.exporter.SerializeLogRecord(this.logRecord); + } - [Benchmark] - public void Export() - { - this.exporter.Export(this.batch); - } + [Benchmark] + public void Export() + { + this.exporter.Export(this.batch); + } - [GlobalCleanup] - public void Cleanup() - { - this.loggerFactory.Dispose(); - this.batch.Dispose(); - this.exporter.Dispose(); - } + [GlobalCleanup] + public void Cleanup() + { + this.loggerFactory.Dispose(); + this.batch.Dispose(); + this.exporter.Dispose(); + } - private static LogRecord GenerateTestLogRecord() - { - var items = new List(1); - using var factory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(loggerOptions => - { - loggerOptions.AddInMemoryExporter(items); - })); + private static LogRecord GenerateTestLogRecord() + { + var items = new List(1); + using var factory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddInMemoryExporter(items); + })); - var logger = factory.CreateLogger("TestLogger"); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - return items[0]; - } + var logger = factory.CreateLogger("TestLogger"); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return items[0]; + } - private static Batch GenerateTestLogRecordBatch() - { - var items = new List(1); - using var batchGeneratorExporter = new BatchGeneratorExporter(); - using var factory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(loggerOptions => - { - loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(batchGeneratorExporter)); - })); + private static Batch GenerateTestLogRecordBatch() + { + var items = new List(1); + using var batchGeneratorExporter = new BatchGeneratorExporter(); + using var factory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(batchGeneratorExporter)); + })); - var logger = factory.CreateLogger("TestLogger"); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - return batchGeneratorExporter.Batch; - } + var logger = factory.CreateLogger("TestLogger"); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return batchGeneratorExporter.Batch; + } - private class BatchGeneratorExporter : BaseExporter - { - public Batch Batch { get; set; } + private class BatchGeneratorExporter : BaseExporter + { + public Batch Batch { get; set; } - public override ExportResult Export(in Batch batch) - { - this.Batch = batch; - return ExportResult.Success; - } + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 425cfb815c..0bb882d50b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -49,167 +49,167 @@ | ExportHistogramMetricItemWith4Dimensions | 618.47 ns | 4.946 ns | 4.384 ns | - | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +[MemoryDiagnoser] +public class MetricExporterBenchmarks { - [MemoryDiagnoser] - public class MetricExporterBenchmarks + private Metric counterMetricWith3Dimensions; + private Metric counterMetricWith4Dimensions; + private MetricPoint counterMetricPointWith3Dimensions; + private MetricPoint counterMetricPointWith4Dimensions; + private MetricData counterMetricDataWith3Dimensions; + private MetricData counterMetricDataWith4Dimensions; + private Batch counterMetricBatchWith3Dimensions; + private Batch counterMetricBatchWith4Dimensions; + private Metric histogramMetricWith3Dimensions; + private Metric histogramMetricWith4Dimensions; + private MetricPoint histogramMetricPointWith3Dimensions; + private MetricPoint histogramMetricPointWith4Dimensions; + private MetricData histogramSumWith3Dimensions; + private MetricData histogramSumWith4Dimensions; + private uint histogramCountWith3Dimensions; + private uint histogramCountWith4Dimensions; + private Batch histogramMetricBatchWith3Dimensions; + private Batch histogramMetricBatchWith4Dimensions; + private Meter meterWithNoListener = new Meter("MeterWithNoListener", "0.0.1"); + private Meter meterWithListener = new Meter("MeterWithListener", "0.0.1"); + private Meter meterWithDummyReader = new Meter("MeterWithDummyReader", "0.0.1"); + private Meter meterWithGenevaMetricExporter = new Meter("MeterWithGenevaMetricExporter", "0.0.1"); + private Counter counterWithNoListener; + private Counter counterWithListener; + private Counter counterWithDummyReader; + private Counter counterWithGenevaMetricExporter; + private MeterListener listener; + private MeterProvider meterProviderWithDummyReader; + private MeterProvider meterProviderWithGenevaMetricExporter; + private MeterProvider meterProviderForCounterBatchWith3Dimensions; + private MeterProvider meterProviderForCounterBatchWith4Dimensions; + private MeterProvider meterProviderForHistogramBatchWith3Dimensions; + private MeterProvider meterProviderForHistogramBatchWith4Dimensions; + private GenevaMetricExporter exporter; + private ThreadLocal random = new ThreadLocal(() => new Random()); + + private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported + private static readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; + + [GlobalSetup] + public void Setup() { - private Metric counterMetricWith3Dimensions; - private Metric counterMetricWith4Dimensions; - private MetricPoint counterMetricPointWith3Dimensions; - private MetricPoint counterMetricPointWith4Dimensions; - private MetricData counterMetricDataWith3Dimensions; - private MetricData counterMetricDataWith4Dimensions; - private Batch counterMetricBatchWith3Dimensions; - private Batch counterMetricBatchWith4Dimensions; - private Metric histogramMetricWith3Dimensions; - private Metric histogramMetricWith4Dimensions; - private MetricPoint histogramMetricPointWith3Dimensions; - private MetricPoint histogramMetricPointWith4Dimensions; - private MetricData histogramSumWith3Dimensions; - private MetricData histogramSumWith4Dimensions; - private uint histogramCountWith3Dimensions; - private uint histogramCountWith4Dimensions; - private Batch histogramMetricBatchWith3Dimensions; - private Batch histogramMetricBatchWith4Dimensions; - private Meter meterWithNoListener = new Meter("MeterWithNoListener", "0.0.1"); - private Meter meterWithListener = new Meter("MeterWithListener", "0.0.1"); - private Meter meterWithDummyReader = new Meter("MeterWithDummyReader", "0.0.1"); - private Meter meterWithGenevaMetricExporter = new Meter("MeterWithGenevaMetricExporter", "0.0.1"); - private Counter counterWithNoListener; - private Counter counterWithListener; - private Counter counterWithDummyReader; - private Counter counterWithGenevaMetricExporter; - private MeterListener listener; - private MeterProvider meterProviderWithDummyReader; - private MeterProvider meterProviderWithGenevaMetricExporter; - private MeterProvider meterProviderForCounterBatchWith3Dimensions; - private MeterProvider meterProviderForCounterBatchWith4Dimensions; - private MeterProvider meterProviderForHistogramBatchWith3Dimensions; - private MeterProvider meterProviderForHistogramBatchWith4Dimensions; - private GenevaMetricExporter exporter; - private ThreadLocal random = new ThreadLocal(() => new Random()); - - private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported - private static readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; - - [GlobalSetup] - public void Setup() - { - this.counterWithNoListener = this.meterWithNoListener.CreateCounter("counter"); - this.counterWithListener = this.meterWithListener.CreateCounter("counter"); - this.counterWithDummyReader = this.meterWithDummyReader.CreateCounter("counter"); - this.counterWithGenevaMetricExporter = this.meterWithGenevaMetricExporter.CreateCounter("counter"); + this.counterWithNoListener = this.meterWithNoListener.CreateCounter("counter"); + this.counterWithListener = this.meterWithListener.CreateCounter("counter"); + this.counterWithDummyReader = this.meterWithDummyReader.CreateCounter("counter"); + this.counterWithGenevaMetricExporter = this.meterWithGenevaMetricExporter.CreateCounter("counter"); - var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - this.exporter = new GenevaMetricExporter(exporterOptions); + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; + this.exporter = new GenevaMetricExporter(exporterOptions); - this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); - this.counterMetricPointWith4Dimensions = this.GenerateCounterMetricItemWith4Dimensions(out this.counterMetricDataWith4Dimensions); + this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); + this.counterMetricPointWith4Dimensions = this.GenerateCounterMetricItemWith4Dimensions(out this.counterMetricDataWith4Dimensions); - this.counterMetricBatchWith3Dimensions = this.GenerateCounterBatchWith3Dimensions(); - this.counterMetricBatchWith4Dimensions = this.GenerateCounterBatchWith4Dimensions(); + this.counterMetricBatchWith3Dimensions = this.GenerateCounterBatchWith3Dimensions(); + this.counterMetricBatchWith4Dimensions = this.GenerateCounterBatchWith4Dimensions(); - using var enumeratorForCounterBatchWith3Dimensions = this.counterMetricBatchWith3Dimensions.GetEnumerator(); - enumeratorForCounterBatchWith3Dimensions.MoveNext(); - this.counterMetricWith3Dimensions = enumeratorForCounterBatchWith3Dimensions.Current; + using var enumeratorForCounterBatchWith3Dimensions = this.counterMetricBatchWith3Dimensions.GetEnumerator(); + enumeratorForCounterBatchWith3Dimensions.MoveNext(); + this.counterMetricWith3Dimensions = enumeratorForCounterBatchWith3Dimensions.Current; - using var enumeratorForCounterBatchWith4Dimensions = this.counterMetricBatchWith4Dimensions.GetEnumerator(); - enumeratorForCounterBatchWith4Dimensions.MoveNext(); - this.counterMetricWith4Dimensions = enumeratorForCounterBatchWith4Dimensions.Current; + using var enumeratorForCounterBatchWith4Dimensions = this.counterMetricBatchWith4Dimensions.GetEnumerator(); + enumeratorForCounterBatchWith4Dimensions.MoveNext(); + this.counterMetricWith4Dimensions = enumeratorForCounterBatchWith4Dimensions.Current; - this.histogramMetricPointWith3Dimensions = this.GenerateHistogramMetricItemWith3Dimensions(out this.histogramSumWith3Dimensions, out this.histogramCountWith3Dimensions); - this.histogramMetricPointWith4Dimensions = this.GenerateHistogramMetricItemWith4Dimensions(out this.histogramSumWith4Dimensions, out this.histogramCountWith4Dimensions); + this.histogramMetricPointWith3Dimensions = this.GenerateHistogramMetricItemWith3Dimensions(out this.histogramSumWith3Dimensions, out this.histogramCountWith3Dimensions); + this.histogramMetricPointWith4Dimensions = this.GenerateHistogramMetricItemWith4Dimensions(out this.histogramSumWith4Dimensions, out this.histogramCountWith4Dimensions); - this.histogramMetricBatchWith3Dimensions = this.GenerateHistogramBatchWith3Dimensions(); - this.histogramMetricBatchWith4Dimensions = this.GenerateHistogramBatchWith4Dimensions(); + this.histogramMetricBatchWith3Dimensions = this.GenerateHistogramBatchWith3Dimensions(); + this.histogramMetricBatchWith4Dimensions = this.GenerateHistogramBatchWith4Dimensions(); - using var enumeratorForHistogramBatchWith3Dimensions = this.histogramMetricBatchWith3Dimensions.GetEnumerator(); - enumeratorForHistogramBatchWith3Dimensions.MoveNext(); - this.histogramMetricWith3Dimensions = enumeratorForHistogramBatchWith3Dimensions.Current; + using var enumeratorForHistogramBatchWith3Dimensions = this.histogramMetricBatchWith3Dimensions.GetEnumerator(); + enumeratorForHistogramBatchWith3Dimensions.MoveNext(); + this.histogramMetricWith3Dimensions = enumeratorForHistogramBatchWith3Dimensions.Current; - using var enumeratorForHistogramBatchWith4Dimensions = this.histogramMetricBatchWith4Dimensions.GetEnumerator(); - enumeratorForHistogramBatchWith4Dimensions.MoveNext(); - this.histogramMetricWith4Dimensions = enumeratorForHistogramBatchWith4Dimensions.Current; + using var enumeratorForHistogramBatchWith4Dimensions = this.histogramMetricBatchWith4Dimensions.GetEnumerator(); + enumeratorForHistogramBatchWith4Dimensions.MoveNext(); + this.histogramMetricWith4Dimensions = enumeratorForHistogramBatchWith4Dimensions.Current; - #region Setup MeterListener - this.listener = new MeterListener(); - this.listener.InstrumentPublished = (instrument, listener) => + #region Setup MeterListener + this.listener = new MeterListener(); + this.listener.InstrumentPublished = (instrument, listener) => + { + if (instrument.Meter.Name == this.meterWithListener.Name) { - if (instrument.Meter.Name == this.meterWithListener.Name) - { - listener.EnableMeasurementEvents(instrument); - } - }; + listener.EnableMeasurementEvents(instrument); + } + }; - this.listener.Start(); - #endregion + this.listener.Start(); + #endregion - this.meterProviderWithDummyReader = Sdk.CreateMeterProviderBuilder() + this.meterProviderWithDummyReader = Sdk.CreateMeterProviderBuilder() .AddMeter(this.meterWithDummyReader.Name) .AddReader(new DummyReader(new DummyMetricExporter())) .Build(); - this.meterProviderWithGenevaMetricExporter = Sdk.CreateMeterProviderBuilder() + this.meterProviderWithGenevaMetricExporter = Sdk.CreateMeterProviderBuilder() .AddMeter(this.meterWithGenevaMetricExporter.Name) .AddGenevaMetricExporter(options => { options.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; }) .Build(); - } + } + + private MetricPoint GenerateCounterMetricItemWith3Dimensions(out MetricData metricData) + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterMetricItemWith3Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWithThreeDimensions"); - private MetricPoint GenerateCounterMetricItemWith3Dimensions(out MetricData metricData) + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - using var meterWithInMemoryExporter = new Meter("GenerateCounterMetricItemWith3Dimensions", "0.0.1"); - var counter = meterWithInMemoryExporter.CreateCounter("CounterWithThreeDimensions"); + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateCounterMetricItemWith3Dimensions") - .AddReader(inMemoryReader) - .Build(); - - counter.Add( - 100, - new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), - new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), - new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); - - inMemoryReader.Collect(); - - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); - metricData = new MetricData { UInt64Value = metricDataValue }; - - return metricPoint; - } + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterMetricItemWith3Dimensions") + .AddReader(inMemoryReader) + .Build(); - private MetricPoint GenerateCounterMetricItemWith4Dimensions(out MetricData metricData) - { - using var meterWithInMemoryExporter = new Meter("GenerateCounterMetricItemWith4Dimensions", "0.0.1"); - var counter = meterWithInMemoryExporter.CreateCounter("CounterWith4Dimensions"); + counter.Add( + 100, + new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + inMemoryReader.Collect(); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + metricData = new MetricData { UInt64Value = metricDataValue }; + + return metricPoint; + } + + private MetricPoint GenerateCounterMetricItemWith4Dimensions(out MetricData metricData) + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterMetricItemWith4Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWith4Dimensions"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateCounterMetricItemWith4Dimensions") - .AddReader(inMemoryReader) - .Build(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterMetricItemWith4Dimensions") + .AddReader(inMemoryReader) + .Build(); - var tags = new TagList + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -217,63 +217,63 @@ private MetricPoint GenerateCounterMetricItemWith4Dimensions(out MetricData metr { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - counter.Add(100, tags); + counter.Add(100, tags); - inMemoryReader.Collect(); + inMemoryReader.Collect(); - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); - metricData = new MetricData { UInt64Value = metricDataValue }; + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + metricData = new MetricData { UInt64Value = metricDataValue }; - return metricPoint; - } + return metricPoint; + } - private Batch GenerateCounterBatchWith3Dimensions() + private Batch GenerateCounterBatchWith3Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterBatchWith3Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWithThreeDimensions"); + + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - using var meterWithInMemoryExporter = new Meter("GenerateCounterBatchWith3Dimensions", "0.0.1"); - var counter = meterWithInMemoryExporter.CreateCounter("CounterWithThreeDimensions"); + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - var batchGeneratorExporter = new BatchGenerator(); - var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; - - this.meterProviderForCounterBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateCounterBatchWith3Dimensions") - .AddReader(batchGeneratorReader) - .Build(); - - counter.Add( - 100, - new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), - new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), - new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); - - this.meterProviderForCounterBatchWith3Dimensions.ForceFlush(); - return batchGeneratorExporter.Batch; - } + this.meterProviderForCounterBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterBatchWith3Dimensions") + .AddReader(batchGeneratorReader) + .Build(); - private Batch GenerateCounterBatchWith4Dimensions() - { - using var meterWithInMemoryExporter = new Meter("GenerateCounterBatchWith4Dimensions", "0.0.1"); - var counter = meterWithInMemoryExporter.CreateCounter("CounterWith4Dimensions"); + counter.Add( + 100, + new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); - var batchGeneratorExporter = new BatchGenerator(); - var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + this.meterProviderForCounterBatchWith3Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } + + private Batch GenerateCounterBatchWith4Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateCounterBatchWith4Dimensions", "0.0.1"); + var counter = meterWithInMemoryExporter.CreateCounter("CounterWith4Dimensions"); - this.meterProviderForCounterBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateCounterBatchWith4Dimensions") - .AddReader(batchGeneratorReader) - .Build(); + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - var tags = new TagList + this.meterProviderForCounterBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateCounterBatchWith4Dimensions") + .AddReader(batchGeneratorReader) + .Build(); + + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -281,66 +281,66 @@ private Batch GenerateCounterBatchWith4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - counter.Add(100, tags); + counter.Add(100, tags); - this.meterProviderForCounterBatchWith4Dimensions.ForceFlush(); - return batchGeneratorExporter.Batch; - } + this.meterProviderForCounterBatchWith4Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } + + private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData sum, out uint count) + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith3Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); - private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData sum, out uint count) + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith3Dimensions", "0.0.1"); - var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramMetricItemWith3Dimensions") + .AddReader(inMemoryReader) + .Build(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateHistogramMetricItemWith3Dimensions") - .AddReader(inMemoryReader) - .Build(); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); + } - for (int i = 0; i < 1000; i++) - { - histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); - } + inMemoryReader.Collect(); - inMemoryReader.Collect(); + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; - count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + return metricPoint; + } - return metricPoint; - } + private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData sum, out uint count) + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith4Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); - private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData sum, out uint count) + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith4Dimensions", "0.0.1"); - var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); - - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateHistogramMetricItemWith4Dimensions") - .AddReader(inMemoryReader) - .Build(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramMetricItemWith4Dimensions") + .AddReader(inMemoryReader) + .Build(); - var tags = new TagList + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -348,69 +348,69 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData su { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - for (int i = 0; i < 1000; i++) - { - histogram.Record(randomForHistogram.Next(1, 1000), tags); - } + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tags); + } - inMemoryReader.Collect(); + inMemoryReader.Collect(); - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; - count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - return metricPoint; - } + return metricPoint; + } + + private Batch GenerateHistogramBatchWith3Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramBatchWith3Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); - private Batch GenerateHistogramBatchWith3Dimensions() + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - using var meterWithInMemoryExporter = new Meter("GenerateHistogramBatchWith3Dimensions", "0.0.1"); - var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - var batchGeneratorExporter = new BatchGenerator(); - var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + this.meterProviderForHistogramBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramBatchWith3Dimensions") + .AddReader(batchGeneratorReader) + .Build(); - this.meterProviderForHistogramBatchWith3Dimensions = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateHistogramBatchWith3Dimensions") - .AddReader(batchGeneratorReader) - .Build(); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + for (int i = 0; i < 1000; i++) + { + histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); + } - for (int i = 0; i < 1000; i++) - { - histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); - } + this.meterProviderForHistogramBatchWith3Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } - this.meterProviderForHistogramBatchWith3Dimensions.ForceFlush(); - return batchGeneratorExporter.Batch; - } + private Batch GenerateHistogramBatchWith4Dimensions() + { + using var meterWithInMemoryExporter = new Meter("GenerateHistogramBatchWith4Dimensions", "0.0.1"); + var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); - private Batch GenerateHistogramBatchWith4Dimensions() + var batchGeneratorExporter = new BatchGenerator(); + var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) { - using var meterWithInMemoryExporter = new Meter("GenerateHistogramBatchWith4Dimensions", "0.0.1"); - var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); - - var batchGeneratorExporter = new BatchGenerator(); - var batchGeneratorReader = new BaseExportingMetricReader(batchGeneratorExporter) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - this.meterProviderForHistogramBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() - .AddMeter("GenerateHistogramBatchWith4Dimensions") - .AddReader(batchGeneratorReader) - .Build(); + this.meterProviderForHistogramBatchWith4Dimensions = Sdk.CreateMeterProviderBuilder() + .AddMeter("GenerateHistogramBatchWith4Dimensions") + .AddReader(batchGeneratorReader) + .Build(); - var tags = new TagList + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -418,45 +418,45 @@ private Batch GenerateHistogramBatchWith4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - for (int i = 0; i < 1000; i++) - { - histogram.Record(randomForHistogram.Next(1, 1000), tags); - } - - this.meterProviderForHistogramBatchWith4Dimensions.ForceFlush(); - return batchGeneratorExporter.Batch; - } - - [GlobalCleanup] - public void Cleanup() + for (int i = 0; i < 1000; i++) { - this.meterWithNoListener?.Dispose(); - this.meterWithListener?.Dispose(); - this.meterWithDummyReader?.Dispose(); - this.meterWithGenevaMetricExporter?.Dispose(); - this.listener?.Dispose(); - this.meterProviderWithDummyReader?.Dispose(); - this.meterProviderWithGenevaMetricExporter?.Dispose(); - this.meterProviderForCounterBatchWith3Dimensions?.Dispose(); - this.meterProviderForCounterBatchWith4Dimensions?.Dispose(); - this.meterProviderForHistogramBatchWith3Dimensions?.Dispose(); - this.meterProviderForHistogramBatchWith4Dimensions?.Dispose(); - this.exporter?.Dispose(); + histogram.Record(randomForHistogram.Next(1, 1000), tags); } - [Benchmark] - public void InstrumentWithNoListener3Dimensions() - { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - this.counterWithNoListener?.Add(100, tag1, tag2, tag3); - } + this.meterProviderForHistogramBatchWith4Dimensions.ForceFlush(); + return batchGeneratorExporter.Batch; + } - [Benchmark] - public void InstrumentWithNoListener4Dimensions() - { - var tags = new TagList + [GlobalCleanup] + public void Cleanup() + { + this.meterWithNoListener?.Dispose(); + this.meterWithListener?.Dispose(); + this.meterWithDummyReader?.Dispose(); + this.meterWithGenevaMetricExporter?.Dispose(); + this.listener?.Dispose(); + this.meterProviderWithDummyReader?.Dispose(); + this.meterProviderWithGenevaMetricExporter?.Dispose(); + this.meterProviderForCounterBatchWith3Dimensions?.Dispose(); + this.meterProviderForCounterBatchWith4Dimensions?.Dispose(); + this.meterProviderForHistogramBatchWith3Dimensions?.Dispose(); + this.meterProviderForHistogramBatchWith4Dimensions?.Dispose(); + this.exporter?.Dispose(); + } + + [Benchmark] + public void InstrumentWithNoListener3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithNoListener?.Add(100, tag1, tag2, tag3); + } + + [Benchmark] + public void InstrumentWithNoListener4Dimensions() + { + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -464,23 +464,23 @@ public void InstrumentWithNoListener4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - // 2 * 5 * 10 * 10 = 1000 time series max. - this.counterWithNoListener?.Add(100, tags); - } + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithNoListener?.Add(100, tags); + } - [Benchmark] - public void InstrumentWithWithListener3Dimensions() - { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - this.counterWithListener?.Add(100, tag1, tag2, tag3); - } + [Benchmark] + public void InstrumentWithWithListener3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithListener?.Add(100, tag1, tag2, tag3); + } - [Benchmark] - public void InstrumentWithWithListener4Dimensions() - { - var tags = new TagList + [Benchmark] + public void InstrumentWithWithListener4Dimensions() + { + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -488,23 +488,23 @@ public void InstrumentWithWithListener4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - // 2 * 5 * 10 * 10 = 1000 time series max. - this.counterWithListener?.Add(100, tags); - } + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithListener?.Add(100, tags); + } - [Benchmark] - public void InstrumentWithWithDummyReader3Dimensions() - { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - this.counterWithDummyReader?.Add(100, tag1, tag2, tag3); - } + [Benchmark] + public void InstrumentWithWithDummyReader3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithDummyReader?.Add(100, tag1, tag2, tag3); + } - [Benchmark] - public void InstrumentWithWithDummyReader4Dimensions() - { - var tags = new TagList + [Benchmark] + public void InstrumentWithWithDummyReader4Dimensions() + { + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -512,23 +512,23 @@ public void InstrumentWithWithDummyReader4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - // 2 * 5 * 10 * 10 = 1000 time series max. - this.counterWithDummyReader?.Add(100, tags); - } + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithDummyReader?.Add(100, tags); + } - [Benchmark] - public void InstrumentWithWithGenevaCounterMetricExporter3Dimensions() - { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - this.counterWithGenevaMetricExporter?.Add(100, tag1, tag2, tag3); - } + [Benchmark] + public void InstrumentWithWithGenevaCounterMetricExporter3Dimensions() + { + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + this.counterWithGenevaMetricExporter?.Add(100, tag1, tag2, tag3); + } - [Benchmark] - public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() - { - var tags = new TagList + [Benchmark] + public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() + { + var tags = new TagList { { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, @@ -536,105 +536,104 @@ public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - // 2 * 5 * 10 * 10 = 1000 time series max. - this.counterWithGenevaMetricExporter?.Add(100, tags); - } + // 2 * 5 * 10 * 10 = 1000 time series max. + this.counterWithGenevaMetricExporter?.Add(100, tags); + } - [Benchmark] - public void SerializeCounterMetricItemWith3Dimensions() - { - this.exporter.SerializeMetric( - MetricEventType.ULongMetric, - this.counterMetricWith3Dimensions.Name, - this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), - this.counterMetricPointWith3Dimensions.Tags, - this.counterMetricDataWith3Dimensions); - } + [Benchmark] + public void SerializeCounterMetricItemWith3Dimensions() + { + this.exporter.SerializeMetric( + MetricEventType.ULongMetric, + this.counterMetricWith3Dimensions.Name, + this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), + this.counterMetricPointWith3Dimensions.Tags, + this.counterMetricDataWith3Dimensions); + } - [Benchmark] - public void SerializeCounterMetricItemWith4Dimensions() - { - this.exporter.SerializeMetric( - MetricEventType.ULongMetric, - this.counterMetricWith4Dimensions.Name, - this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), - this.counterMetricPointWith4Dimensions.Tags, - this.counterMetricDataWith4Dimensions); - } + [Benchmark] + public void SerializeCounterMetricItemWith4Dimensions() + { + this.exporter.SerializeMetric( + MetricEventType.ULongMetric, + this.counterMetricWith4Dimensions.Name, + this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), + this.counterMetricPointWith4Dimensions.Tags, + this.counterMetricDataWith4Dimensions); + } - [Benchmark] - public void ExportCounterMetricItemWith3Dimensions() - { - this.exporter.Export(this.counterMetricBatchWith3Dimensions); - } + [Benchmark] + public void ExportCounterMetricItemWith3Dimensions() + { + this.exporter.Export(this.counterMetricBatchWith3Dimensions); + } - [Benchmark] - public void ExportCounterMetricItemWith4Dimensions() - { - this.exporter.Export(this.counterMetricBatchWith4Dimensions); - } + [Benchmark] + public void ExportCounterMetricItemWith4Dimensions() + { + this.exporter.Export(this.counterMetricBatchWith4Dimensions); + } - [Benchmark] - public void SerializeHistogramMetricItemWith3Dimensions() - { - this.exporter.SerializeHistogramMetric( - this.histogramMetricWith3Dimensions.Name, - this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), - this.histogramMetricPointWith3Dimensions.Tags, - this.histogramMetricPointWith3Dimensions.GetHistogramBuckets(), - this.histogramSumWith3Dimensions, - this.histogramCountWith3Dimensions); - } + [Benchmark] + public void SerializeHistogramMetricItemWith3Dimensions() + { + this.exporter.SerializeHistogramMetric( + this.histogramMetricWith3Dimensions.Name, + this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), + this.histogramMetricPointWith3Dimensions.Tags, + this.histogramMetricPointWith3Dimensions.GetHistogramBuckets(), + this.histogramSumWith3Dimensions, + this.histogramCountWith3Dimensions); + } - [Benchmark] - public void SerializeHistogramMetricItemWith4Dimensions() - { - this.exporter.SerializeHistogramMetric( - this.histogramMetricWith4Dimensions.Name, - this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), - this.histogramMetricPointWith4Dimensions.Tags, - this.histogramMetricPointWith4Dimensions.GetHistogramBuckets(), - this.histogramSumWith4Dimensions, - this.histogramCountWith4Dimensions); - } + [Benchmark] + public void SerializeHistogramMetricItemWith4Dimensions() + { + this.exporter.SerializeHistogramMetric( + this.histogramMetricWith4Dimensions.Name, + this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), + this.histogramMetricPointWith4Dimensions.Tags, + this.histogramMetricPointWith4Dimensions.GetHistogramBuckets(), + this.histogramSumWith4Dimensions, + this.histogramCountWith4Dimensions); + } - [Benchmark] - public void ExportHistogramMetricItemWith3Dimensions() - { - this.exporter.Export(this.histogramMetricBatchWith3Dimensions); - } + [Benchmark] + public void ExportHistogramMetricItemWith3Dimensions() + { + this.exporter.Export(this.histogramMetricBatchWith3Dimensions); + } - [Benchmark] - public void ExportHistogramMetricItemWith4Dimensions() - { - this.exporter.Export(this.histogramMetricBatchWith4Dimensions); - } + [Benchmark] + public void ExportHistogramMetricItemWith4Dimensions() + { + this.exporter.Export(this.histogramMetricBatchWith4Dimensions); + } - private class DummyReader : BaseExportingMetricReader + private class DummyReader : BaseExportingMetricReader + { + public DummyReader(BaseExporter exporter) + : base(exporter) { - public DummyReader(BaseExporter exporter) - : base(exporter) - { - } } + } - private class DummyMetricExporter : BaseExporter + private class DummyMetricExporter : BaseExporter + { + public override ExportResult Export(in Batch batch) { - public override ExportResult Export(in Batch batch) - { - return ExportResult.Success; - } + return ExportResult.Success; } + } - private class BatchGenerator : BaseExporter - { - public Batch Batch { get; set; } + private class BatchGenerator : BaseExporter + { + public Batch Batch { get; set; } - public override ExportResult Export(in Batch batch) - { - this.Batch = batch; - return ExportResult.Success; - } + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index f305ae24a9..3460304ff1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -17,7 +17,6 @@ using System.Collections.Generic; using System.Diagnostics; using BenchmarkDotNet.Attributes; -using OpenTelemetry.Metrics; using OpenTelemetry.Trace; /* @@ -34,101 +33,100 @@ | SerializeActivity | 387.4 ns | 7.22 ns | 7.09 ns | 0.0062 | 40 B | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +[MemoryDiagnoser] +public class TraceExporterBenchmarks { - [MemoryDiagnoser] - public class TraceExporterBenchmarks + private readonly Activity activity; + private readonly Batch batch; + private readonly GenevaTraceExporter exporter; + private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); + + public TraceExporterBenchmarks() { - private readonly Activity activity; - private readonly Batch batch; - private readonly GenevaTraceExporter exporter; - private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); + Activity.DefaultIdFormat = ActivityIdFormat.W3C; - public TraceExporterBenchmarks() - { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; + this.batch = this.CreateBatch(); - this.batch = this.CreateBatch(); + using var activityListener = new ActivityListener + { + ActivityStarted = null, + ActivityStopped = null, + ShouldListenTo = (activitySource) => activitySource.Name == this.activitySource.Name, + Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded, + }; - using var activityListener = new ActivityListener - { - ActivityStarted = null, - ActivityStopped = null, - ShouldListenTo = (activitySource) => activitySource.Name == this.activitySource.Name, - Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded, - }; + ActivitySource.AddActivityListener(activityListener); - ActivitySource.AddActivityListener(activityListener); + using (var testActivity = this.activitySource.StartActivity("Benchmark")) + { + this.activity = testActivity; + this.activity?.SetTag("tagString", "value"); + this.activity?.SetTag("tagInt", 100); + this.activity?.SetStatus(Status.Error); + } - using (var testActivity = this.activitySource.StartActivity("Benchmark")) + this.exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary { - this.activity = testActivity; - this.activity?.SetTag("tagString", "value"); - this.activity?.SetTag("tagInt", 100); - this.activity?.SetStatus(Status.Error); - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + } - this.exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }); - } + [Benchmark] + public void ExportActivity() + { + this.exporter.Export(this.batch); + } - [Benchmark] - public void ExportActivity() - { - this.exporter.Export(this.batch); - } + [Benchmark] + public void SerializeActivity() + { + this.exporter.SerializeActivity(this.activity); + } - [Benchmark] - public void SerializeActivity() - { - this.exporter.SerializeActivity(this.activity); - } + [GlobalCleanup] + public void Cleanup() + { + this.activity.Dispose(); + this.activitySource.Dispose(); + this.batch.Dispose(); + this.exporter.Dispose(); + } - [GlobalCleanup] - public void Cleanup() + private Batch CreateBatch() + { + using var batchGeneratorExporter = new BatchGeneratorExporter(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(this.activitySource.Name) + .AddProcessor(new SimpleActivityExportProcessor(batchGeneratorExporter)) + .Build(); + + using (var activity = this.activitySource.StartActivity("Benchmark")) { - this.activity.Dispose(); - this.activitySource.Dispose(); - this.batch.Dispose(); - this.exporter.Dispose(); + activity.SetTag("tagString", "value"); + activity.SetTag("tagInt", 100); + activity.SetStatus(Status.Error); } - private Batch CreateBatch() - { - using var batchGeneratorExporter = new BatchGeneratorExporter(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(this.activitySource.Name) - .AddProcessor(new SimpleActivityExportProcessor(batchGeneratorExporter)) - .Build(); - - using (var activity = this.activitySource.StartActivity("Benchmark")) - { - activity.SetTag("tagString", "value"); - activity.SetTag("tagInt", 100); - activity.SetStatus(Status.Error); - } + return batchGeneratorExporter.Batch; + } - return batchGeneratorExporter.Batch; - } + private class BatchGeneratorExporter : BaseExporter + { + public Batch Batch { get; set; } - private class BatchGeneratorExporter : BaseExporter + public override ExportResult Export(in Batch batch) { - public Batch Batch { get; set; } - - public override ExportResult Export(in Batch batch) - { - this.Batch = batch; - return ExportResult.Success; - } + this.Batch = batch; + return ExportResult.Success; } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs index 2616c540d0..ac7b7f625e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs @@ -16,10 +16,9 @@ using BenchmarkDotNet.Running; -namespace OpenTelemetry.Exporter.Geneva.Benchmark +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +internal class Program { - internal class Program - { - private static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); - } + private static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index 4521c6f4ed..1757f49f2e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -21,82 +21,81 @@ using System.Threading; using System.Threading.Tasks; -namespace OpenTelemetry.Exporter.Geneva.Stress +namespace OpenTelemetry.Exporter.Geneva.Stress; + +internal class DummyServer { - internal class DummyServer - { - private EndPoint endpoint; - private Socket serverSocket; + private EndPoint endpoint; + private Socket serverSocket; - public DummyServer(string path) - { - Console.WriteLine($"Server socket listening at path: {path}"); + public DummyServer(string path) + { + Console.WriteLine($"Server socket listening at path: {path}"); - // Unix sockets must be unlink()ed before being reused again. - // Or there will be System.Net.Sockets.SocketException (98): SocketError.AddressAlreadyInUse - // https://github.com/dotnet/runtime/issues/23803 - // C# doesn't have the unlink() function in C - // Shutdown() and setting SocketOptions like ReuseAddress and Linger doesn't solve the problem as they do for TCP - // https://stackoverflow.com/questions/2821520/how-can-i-unbind-a-socket-in-c - File.Delete(path); - this.endpoint = new UnixDomainSocketEndPoint(path); - this.serverSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - } + // Unix sockets must be unlink()ed before being reused again. + // Or there will be System.Net.Sockets.SocketException (98): SocketError.AddressAlreadyInUse + // https://github.com/dotnet/runtime/issues/23803 + // C# doesn't have the unlink() function in C + // Shutdown() and setting SocketOptions like ReuseAddress and Linger doesn't solve the problem as they do for TCP + // https://stackoverflow.com/questions/2821520/how-can-i-unbind-a-socket-in-c + File.Delete(path); + this.endpoint = new UnixDomainSocketEndPoint(path); + this.serverSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + } - public void Start() + public void Start() + { + try { - try - { - this.serverSocket.Bind(this.endpoint); - this.serverSocket.Listen(20); + this.serverSocket.Bind(this.endpoint); + this.serverSocket.Listen(20); - Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs args) => - { - Console.WriteLine("Program is terminating."); - this.serverSocket.Close(); - }; + Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs args) => + { + Console.WriteLine("Program is terminating."); + this.serverSocket.Close(); + }; - while (true) + while (true) + { + Socket acceptSocket = this.serverSocket.Accept(); + Task.Run(() => { - Socket acceptSocket = this.serverSocket.Accept(); - Task.Run(() => + int threadId = Thread.CurrentThread.ManagedThreadId; + Console.WriteLine($"ThreadID {threadId}: Start reading from socket."); + int totalBytes = 0; + try { - int threadId = Thread.CurrentThread.ManagedThreadId; - Console.WriteLine($"ThreadID {threadId}: Start reading from socket."); - int totalBytes = 0; - try - { - while (acceptSocket.Connected) - { - var receivedData = new byte[1024]; - int receivedDataSize = acceptSocket.Receive(receivedData); - totalBytes += receivedDataSize; - } - - acceptSocket.Shutdown(SocketShutdown.Both); - } - catch (Exception e) + while (acceptSocket.Connected) { - Console.WriteLine($"acceptSocket exception: {e}"); - } - finally - { - Console.WriteLine($"ThreadID {threadId}: Closing socket"); - acceptSocket.Close(); + var receivedData = new byte[1024]; + int receivedDataSize = acceptSocket.Receive(receivedData); + totalBytes += receivedDataSize; } - Console.WriteLine($"ThreadID {threadId}: Socket received {totalBytes} bytes in total."); - }); - } - } - catch (Exception e) - { - Console.WriteLine($"Server socket exception: {e}"); - } - finally - { - this.serverSocket.Close(); + acceptSocket.Shutdown(SocketShutdown.Both); + } + catch (Exception e) + { + Console.WriteLine($"acceptSocket exception: {e}"); + } + finally + { + Console.WriteLine($"ThreadID {threadId}: Closing socket"); + acceptSocket.Close(); + } + + Console.WriteLine($"ThreadID {threadId}: Socket received {totalBytes} bytes in total."); + }); } } + catch (Exception e) + { + Console.WriteLine($"Server socket exception: {e}"); + } + finally + { + this.serverSocket.Close(); + } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index e0d264e6a4..b1b8275038 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -24,93 +24,93 @@ using CommandLine; using OpenTelemetry.Trace; -namespace OpenTelemetry.Exporter.Geneva.Stress +namespace OpenTelemetry.Exporter.Geneva.Stress; + +internal class Program { - internal class Program - { - private static volatile bool s_bContinue = true; - private static long s_nEvents = 0; + private static volatile bool s_bContinue = true; + private static long s_nEvents = 0; - private static ActivitySource source = new ActivitySource("OpenTelemetry.Exporter.Geneva.Stress"); + private static ActivitySource source = new ActivitySource("OpenTelemetry.Exporter.Geneva.Stress"); - private static int Main(string[] args) - { - return Parser.Default.ParseArguments(args) - .MapResult( - (WindowsOptions options) => EntryPoint(InitTraces, RunTraces), - (LinuxOptions options) => RunLinux(options), - (ServerOptions options) => RunServer(options), - (ExporterCreationOptions options) => RunExporterCreation(), - errs => 1); - - // return EntryPoint(InitMetrics, RunMetrics); - } + private static int Main(string[] args) + { + return Parser.Default.ParseArguments(args) + .MapResult( + (WindowsOptions options) => EntryPoint(InitTraces, RunTraces), + (LinuxOptions options) => RunLinux(options), + (ServerOptions options) => RunServer(options), + (ExporterCreationOptions options) => RunExporterCreation(), + errs => 1); + + // return EntryPoint(InitMetrics, RunMetrics); + } - [Verb("Windows", HelpText = "Run stress test on Windows.")] - private class WindowsOptions - { - } + [Verb("Windows", HelpText = "Run stress test on Windows.")] + private class WindowsOptions + { + } - [Verb("Linux", HelpText = "Run stress test on Linux.")] - private class LinuxOptions - { - [Option('p', "path", Default = "/var/run/default_fluent.socket", HelpText = "Specify a path for Unix domain socket.")] - public string Path { get; set; } - } + [Verb("Linux", HelpText = "Run stress test on Linux.")] + private class LinuxOptions + { + [Option('p', "path", Default = "/var/run/default_fluent.socket", HelpText = "Specify a path for Unix domain socket.")] + public string Path { get; set; } + } - [Verb("server", HelpText = "Start a dummy server on Linux.")] - private class ServerOptions - { - [Option('p', "path", HelpText = "Specify a path for Unix domain socket.", Required = true)] - public string Path { get; set; } - } + [Verb("server", HelpText = "Start a dummy server on Linux.")] + private class ServerOptions + { + [Option('p', "path", HelpText = "Specify a path for Unix domain socket.", Required = true)] + public string Path { get; set; } + } - [Verb("ExporterCreation", HelpText = "Validate exporter dispose behavior")] - private class ExporterCreationOptions - { - } + [Verb("ExporterCreation", HelpText = "Validate exporter dispose behavior")] + private class ExporterCreationOptions + { + } - private static int RunExporterCreation() + private static int RunExporterCreation() + { + var options = new GenevaExporterOptions() { - var options = new GenevaExporterOptions() - { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary - { - ["ver"] = "4.0", - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; - - for (var i = 0; i < 300000; ++i) + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary { - using var dataTransport = new EtwDataTransport("OpenTelemetry"); - } - - return 0; - } + ["ver"] = "4.0", + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; - private static int RunLinux(LinuxOptions options) + for (var i = 0; i < 300000; ++i) { - return EntryPoint(() => InitTracesOnLinux(options.Path), RunTraces); + using var dataTransport = new EtwDataTransport("OpenTelemetry"); } - private static int RunServer(ServerOptions options) - { - var server = new DummyServer(options.Path); - server.Start(); - return 0; - } + return 0; + } - private static int EntryPoint(Action init, Action run) - { - init(); + private static int RunLinux(LinuxOptions options) + { + return EntryPoint(() => InitTracesOnLinux(options.Path), RunTraces); + } + + private static int RunServer(ServerOptions options) + { + var server = new DummyServer(options.Path); + server.Start(); + return 0; + } - var statistics = new long[Environment.ProcessorCount]; - Parallel.Invoke( - () => + private static int EntryPoint(Action init, Action run) + { + init(); + + var statistics = new long[Environment.ProcessorCount]; + Parallel.Invoke( + () => { Console.WriteLine("Running, press to stop..."); var watch = new Stopwatch(); @@ -138,7 +138,7 @@ private static int EntryPoint(Action init, Action run) Console.Title = string.Format("Loops: {0:n0}, Loops/Second: {1:n0}", nEvents, nEventPerSecond); } }, - () => + () => { Parallel.For(0, statistics.Length, (i) => { @@ -150,54 +150,53 @@ private static int EntryPoint(Action init, Action run) } }); }); - return 0; - } + return 0; + } - private static void InitTraces() - { - Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource("OpenTelemetry.Exporter.Geneva.Stress") - .AddGenevaTraceExporter(options => + private static void InitTraces() + { + Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource("OpenTelemetry.Exporter.Geneva.Stress") + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary { - options.ConnectionString = "EtwSession=OpenTelemetry"; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void RunTraces() + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void RunTraces() + { + using (var activity = source.StartActivity("Stress")) { - using (var activity = source.StartActivity("Stress")) - { - activity?.SetTag("http.method", "GET"); - activity?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); - activity?.SetTag("http.status_code", 200); - } + activity?.SetTag("http.method", "GET"); + activity?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + activity?.SetTag("http.status_code", 200); } + } - private static void InitTracesOnLinux(string path) - { - Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource("OpenTelemetry.Exporter.Geneva.Stress") - .AddGenevaTraceExporter(options => + private static void InitTracesOnLinux(string path) + { + Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource("OpenTelemetry.Exporter.Geneva.Stress") + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary { - options.ConnectionString = "Endpoint=unix:" + path; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 9f579c0b8e..35473e893e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -17,217 +17,216 @@ using System; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class ConnectionStringBuilderTests { - public class ConnectionStringBuilderTests + [Fact] + public void ConnectionStringBuilder_constructor_Invalid_Input() + { + // null connection string + Assert.Throws(() => _ = new ConnectionStringBuilder(null)); + + // empty connection string + Assert.Throws(() => _ = new ConnectionStringBuilder(string.Empty)); + Assert.Throws(() => _ = new ConnectionStringBuilder(" ")); + + // empty key + Assert.Throws(() => _ = new ConnectionStringBuilder("=value")); + Assert.Throws(() => _ = new ConnectionStringBuilder("=value1;key2=value2")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key1=value1;=value2")); + + // empty value + Assert.Throws(() => _ = new ConnectionStringBuilder("key=")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key1=;key2=value2")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key1=value1;key2=")); + + // invalid format + Assert.Throws(() => _ = new ConnectionStringBuilder("key;value")); + Assert.Throws(() => _ = new ConnectionStringBuilder("key==value")); + } + + [Fact] + public void ConnectionStringBuilder_constructor_Duplicated_Keys() + { + var builder = new ConnectionStringBuilder("Account=value1;Account=VALUE2"); + Assert.Equal("VALUE2", builder.Account); + } + + [Fact] + public void ConnectionStringBuilder_Protocol_No_Default_Value() + { + var builder = new ConnectionStringBuilder("key1=value1"); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + + builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); + Assert.Equal(TransportProtocol.Etw, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11013"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:11013"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=foo://localhost:11013"); + Assert.Throws(() => _ = builder.Protocol); + } + + [Fact] + public void ConnectionStringBuilder_EtwSession() + { + var builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); + Assert.Equal(TransportProtocol.Etw, builder.Protocol); + Assert.Equal("OpenTelemetry", builder.EtwSession); + Assert.Throws(() => _ = builder.Host); + Assert.Throws(() => _ = builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11013"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + Assert.Throws(() => _ = builder.EtwSession); + } + + [Fact] + public void ConnectionStringBuilder_Endpoint_UnixDomainSocketPath() + { + var builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); + Assert.Equal("unix:/var/run/default_fluent.socket", builder.Endpoint); + Assert.Equal(TransportProtocol.Unix, builder.Protocol); + Assert.Equal("/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("Endpoint=unix:///var/run/default_fluent.socket"); + Assert.Equal("unix:///var/run/default_fluent.socket", builder.Endpoint); + Assert.Equal(TransportProtocol.Unix, builder.Protocol); + Assert.Equal("/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("Endpoint=unix://:11111"); + Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); + Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); + } + + [Fact] + public void ConnectionStringBuilder_TimeoutMilliseconds() + { + var builder = new ConnectionStringBuilder("TimeoutMilliseconds=10000"); + Assert.Equal(10000, builder.TimeoutMilliseconds); + + builder.TimeoutMilliseconds = 6000; + Assert.Equal(6000, builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); + Assert.Equal(UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds, builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=0"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=-1"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=-2"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=10.5"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + + builder = new ConnectionStringBuilder("TimeoutMilliseconds=abc"); + Assert.Throws(() => _ = builder.TimeoutMilliseconds); + } + + [Fact] + public void ConnectionStringBuilder_Endpoint_Udp() + { + var builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11111"); + Assert.Equal("udp://localhost:11111", builder.Endpoint); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Equal(11111, builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=Udp://localhost:11111"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=UDP://localhost:11111"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=udp://localhost"); + Assert.Equal(TransportProtocol.Udp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Throws(() => _ = builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=udp://:11111"); + Assert.Throws(() => _ = builder.Protocol); + Assert.Throws(() => _ = builder.Host); + Assert.Throws(() => _ = builder.Port); + } + + [Fact] + public void ConnectionStringBuilder_Endpoint_Tcp() + { + var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333"); + Assert.Equal("tcp://localhost:33333", builder.Endpoint); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Equal(33333, builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=Tcp://localhost:11111"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=TCP://localhost:11111"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + + builder = new ConnectionStringBuilder("Endpoint=tcp://localhost"); + Assert.Equal(TransportProtocol.Tcp, builder.Protocol); + Assert.Equal("localhost", builder.Host); + Assert.Throws(() => _ = builder.Port); + + builder = new ConnectionStringBuilder("Endpoint=tpc://:11111"); + Assert.Throws(() => _ = builder.Protocol); + Assert.Throws(() => _ = builder.Host); + Assert.Throws(() => _ = builder.Port); + } + + [Fact] + public void ConnectionStringBuilder_EtwSession_Endpoint_Both_Set() + { + var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333;EtwSession=OpenTelemetry"); + Assert.Equal(TransportProtocol.Etw, builder.Protocol); + + Assert.Equal("OpenTelemetry", builder.EtwSession); + + Assert.Equal("tcp://localhost:33333", builder.Endpoint); + Assert.Equal("localhost", builder.Host); + Assert.Equal(33333, builder.Port); + } + + [Fact] + public void ConnectionStringBuilder_MonitoringAccount_No_Default_Value() + { + var builder = new ConnectionStringBuilder("key1=value1"); + Assert.Throws(() => _ = builder.Account); + + builder.Account = "TestAccount"; + Assert.Equal("TestAccount", builder.Account); + + builder = new ConnectionStringBuilder("Account=TestAccount"); + Assert.Equal("TestAccount", builder.Account); + } + + [Fact] + public void ConnectionStringBuilder_Keywords_Are_Case_Sensitive() { - [Fact] - public void ConnectionStringBuilder_constructor_Invalid_Input() - { - // null connection string - Assert.Throws(() => _ = new ConnectionStringBuilder(null)); - - // empty connection string - Assert.Throws(() => _ = new ConnectionStringBuilder(string.Empty)); - Assert.Throws(() => _ = new ConnectionStringBuilder(" ")); - - // empty key - Assert.Throws(() => _ = new ConnectionStringBuilder("=value")); - Assert.Throws(() => _ = new ConnectionStringBuilder("=value1;key2=value2")); - Assert.Throws(() => _ = new ConnectionStringBuilder("key1=value1;=value2")); - - // empty value - Assert.Throws(() => _ = new ConnectionStringBuilder("key=")); - Assert.Throws(() => _ = new ConnectionStringBuilder("key1=;key2=value2")); - Assert.Throws(() => _ = new ConnectionStringBuilder("key1=value1;key2=")); - - // invalid format - Assert.Throws(() => _ = new ConnectionStringBuilder("key;value")); - Assert.Throws(() => _ = new ConnectionStringBuilder("key==value")); - } - - [Fact] - public void ConnectionStringBuilder_constructor_Duplicated_Keys() - { - var builder = new ConnectionStringBuilder("Account=value1;Account=VALUE2"); - Assert.Equal("VALUE2", builder.Account); - } - - [Fact] - public void ConnectionStringBuilder_Protocol_No_Default_Value() - { - var builder = new ConnectionStringBuilder("key1=value1"); - Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); - - builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); - Assert.Equal(TransportProtocol.Etw, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11013"); - Assert.Equal(TransportProtocol.Udp, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:11013"); - Assert.Equal(TransportProtocol.Tcp, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=foo://localhost:11013"); - Assert.Throws(() => _ = builder.Protocol); - } - - [Fact] - public void ConnectionStringBuilder_EtwSession() - { - var builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); - Assert.Equal(TransportProtocol.Etw, builder.Protocol); - Assert.Equal("OpenTelemetry", builder.EtwSession); - Assert.Throws(() => _ = builder.Host); - Assert.Throws(() => _ = builder.Port); - - builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11013"); - Assert.Equal(TransportProtocol.Udp, builder.Protocol); - Assert.Throws(() => _ = builder.EtwSession); - } - - [Fact] - public void ConnectionStringBuilder_Endpoint_UnixDomainSocketPath() - { - var builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); - Assert.Equal("unix:/var/run/default_fluent.socket", builder.Endpoint); - Assert.Equal(TransportProtocol.Unix, builder.Protocol); - Assert.Equal("/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); - - builder = new ConnectionStringBuilder("Endpoint=unix:///var/run/default_fluent.socket"); - Assert.Equal("unix:///var/run/default_fluent.socket", builder.Endpoint); - Assert.Equal(TransportProtocol.Unix, builder.Protocol); - Assert.Equal("/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); - - builder = new ConnectionStringBuilder("Endpoint=unix://:11111"); - Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); - - builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); - Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); - } - - [Fact] - public void ConnectionStringBuilder_TimeoutMilliseconds() - { - var builder = new ConnectionStringBuilder("TimeoutMilliseconds=10000"); - Assert.Equal(10000, builder.TimeoutMilliseconds); - - builder.TimeoutMilliseconds = 6000; - Assert.Equal(6000, builder.TimeoutMilliseconds); - - builder = new ConnectionStringBuilder("Endpoint=unix:/var/run/default_fluent.socket"); - Assert.Equal(UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds, builder.TimeoutMilliseconds); - - builder = new ConnectionStringBuilder("TimeoutMilliseconds=0"); - Assert.Throws(() => _ = builder.TimeoutMilliseconds); - - builder = new ConnectionStringBuilder("TimeoutMilliseconds=-1"); - Assert.Throws(() => _ = builder.TimeoutMilliseconds); - - builder = new ConnectionStringBuilder("TimeoutMilliseconds=-2"); - Assert.Throws(() => _ = builder.TimeoutMilliseconds); - - builder = new ConnectionStringBuilder("TimeoutMilliseconds=10.5"); - Assert.Throws(() => _ = builder.TimeoutMilliseconds); - - builder = new ConnectionStringBuilder("TimeoutMilliseconds=abc"); - Assert.Throws(() => _ = builder.TimeoutMilliseconds); - } - - [Fact] - public void ConnectionStringBuilder_Endpoint_Udp() - { - var builder = new ConnectionStringBuilder("Endpoint=udp://localhost:11111"); - Assert.Equal("udp://localhost:11111", builder.Endpoint); - Assert.Equal(TransportProtocol.Udp, builder.Protocol); - Assert.Equal("localhost", builder.Host); - Assert.Equal(11111, builder.Port); - - builder = new ConnectionStringBuilder("Endpoint=Udp://localhost:11111"); - Assert.Equal(TransportProtocol.Udp, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=UDP://localhost:11111"); - Assert.Equal(TransportProtocol.Udp, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=udp://localhost"); - Assert.Equal(TransportProtocol.Udp, builder.Protocol); - Assert.Equal("localhost", builder.Host); - Assert.Throws(() => _ = builder.Port); - - builder = new ConnectionStringBuilder("Endpoint=udp://:11111"); - Assert.Throws(() => _ = builder.Protocol); - Assert.Throws(() => _ = builder.Host); - Assert.Throws(() => _ = builder.Port); - } - - [Fact] - public void ConnectionStringBuilder_Endpoint_Tcp() - { - var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333"); - Assert.Equal("tcp://localhost:33333", builder.Endpoint); - Assert.Equal(TransportProtocol.Tcp, builder.Protocol); - Assert.Equal("localhost", builder.Host); - Assert.Equal(33333, builder.Port); - - builder = new ConnectionStringBuilder("Endpoint=Tcp://localhost:11111"); - Assert.Equal(TransportProtocol.Tcp, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=TCP://localhost:11111"); - Assert.Equal(TransportProtocol.Tcp, builder.Protocol); - - builder = new ConnectionStringBuilder("Endpoint=tcp://localhost"); - Assert.Equal(TransportProtocol.Tcp, builder.Protocol); - Assert.Equal("localhost", builder.Host); - Assert.Throws(() => _ = builder.Port); - - builder = new ConnectionStringBuilder("Endpoint=tpc://:11111"); - Assert.Throws(() => _ = builder.Protocol); - Assert.Throws(() => _ = builder.Host); - Assert.Throws(() => _ = builder.Port); - } - - [Fact] - public void ConnectionStringBuilder_EtwSession_Endpoint_Both_Set() - { - var builder = new ConnectionStringBuilder("Endpoint=tcp://localhost:33333;EtwSession=OpenTelemetry"); - Assert.Equal(TransportProtocol.Etw, builder.Protocol); - - Assert.Equal("OpenTelemetry", builder.EtwSession); - - Assert.Equal("tcp://localhost:33333", builder.Endpoint); - Assert.Equal("localhost", builder.Host); - Assert.Equal(33333, builder.Port); - } - - [Fact] - public void ConnectionStringBuilder_MonitoringAccount_No_Default_Value() - { - var builder = new ConnectionStringBuilder("key1=value1"); - Assert.Throws(() => _ = builder.Account); - - builder.Account = "TestAccount"; - Assert.Equal("TestAccount", builder.Account); - - builder = new ConnectionStringBuilder("Account=TestAccount"); - Assert.Equal("TestAccount", builder.Account); - } - - [Fact] - public void ConnectionStringBuilder_Keywords_Are_Case_Sensitive() - { - var builder = new ConnectionStringBuilder("etwSession=OpenTelemetry"); - Assert.Throws(() => builder.EtwSession); - Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); - - builder = new ConnectionStringBuilder("endpoint=tcp://localhost:33333"); - Assert.Throws(() => builder.Endpoint); - Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); - Assert.Throws(() => builder.Host); - Assert.Throws(() => builder.Port); - - builder = new ConnectionStringBuilder("monitoringAccount=TestAccount"); - Assert.Throws(() => builder.Account); - Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); - } + var builder = new ConnectionStringBuilder("etwSession=OpenTelemetry"); + Assert.Throws(() => builder.EtwSession); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + + builder = new ConnectionStringBuilder("endpoint=tcp://localhost:33333"); + Assert.Throws(() => builder.Endpoint); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); + Assert.Throws(() => builder.Host); + Assert.Throws(() => builder.Port); + + builder = new ConnectionStringBuilder("monitoringAccount=TestAccount"); + Assert.Throws(() => builder.Account); + Assert.Equal(TransportProtocol.Unspecified, builder.Protocol); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 91d82c38c3..0f1168c856 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -24,226 +24,225 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class GenevaLogExporterTests { - public class GenevaLogExporterTests + [Fact] + public void BadArgs() + { + GenevaExporterOptions exporterOptions = null; + Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + } + + [Fact] + public void SpecialCharactersInTableNameMappings() { - [Fact] - public void BadArgs() + Assert.Throws(() => { - GenevaExporterOptions exporterOptions = null; - Assert.Throws(() => + using var exporter = new GenevaLogExporter(new GenevaExporterOptions { - using var exporter = new GenevaLogExporter(exporterOptions); + TableNameMappings = new Dictionary { ["TestCategory"] = "\u0418" }, }); - } + }); - [Fact] - public void SpecialChractersInTableNameMappings() + Assert.Throws(() => { - Assert.Throws(() => + using var exporter = new GenevaLogExporter(new GenevaExporterOptions { - using var exporter = new GenevaLogExporter(new GenevaExporterOptions - { - TableNameMappings = new Dictionary { ["TestCategory"] = "\u0418" }, - }); + TableNameMappings = new Dictionary { ["*"] = "\u0418" }, }); + }); - Assert.Throws(() => + // Throw on null value - include key in exception message + var ex = Assert.Throws(() => + { + new GenevaExporterOptions { - using var exporter = new GenevaLogExporter(new GenevaExporterOptions - { - TableNameMappings = new Dictionary { ["*"] = "\u0418" }, - }); - }); + TableNameMappings = new Dictionary { ["TestCategory"] = null }, + }; + }); + Assert.Contains("TableNameMappings must not contain null values.", ex.Message); + Assert.Equal("TestCategory", ex.ParamName); - // Throw on null value - include key in exception message - var ex = Assert.Throws(() => + // Throw when TableNameMappings is null + Assert.Throws(() => + { + new GenevaExporterOptions { - new GenevaExporterOptions - { - TableNameMappings = new Dictionary { ["TestCategory"] = null }, - }; - }); - Assert.Contains("TableNameMappings must not contain null values.", ex.Message); - Assert.Equal("TestCategory", ex.ParamName); + TableNameMappings = null, + }; + }); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void InvalidConnectionString(string connectionString) + { + var exporterOptions = new GenevaExporterOptions() { ConnectionString = connectionString }; + var exception = Assert.Throws(() => + { + using var exporter = new GenevaLogExporter(exporterOptions); + }); + } - // Throw when TableNameMappings is null - Assert.Throws(() => + [Fact] + public void IncompatibleConnectionString_Windows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; + var exception = Assert.Throws(() => { - new GenevaExporterOptions - { - TableNameMappings = null, - }; + using var exporter = new GenevaLogExporter(exporterOptions); }); + Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); } + } - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public void InvalidConnectionString(string connectionString) + [Fact] + public void IncompatibleConnectionString_Linux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = connectionString }; + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; var exception = Assert.Throws(() => { using var exporter = new GenevaLogExporter(exporterOptions); }); + Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); } + } - [Fact] - public void IncompatibleConnectionString_Windows() + [Theory] + [InlineData("categoryA", "TableA")] + [InlineData("categoryB", "TableB")] + [InlineData("categoryA", "TableA", "categoryB", "TableB")] + [InlineData("categoryA", "TableA", "*", "CatchAll")] + [InlineData(null)] + public void TableNameMappingTest(params string[] category) + { + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + Dictionary mappingsDict = null; + try { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + var exporterOptions = new GenevaExporterOptions(); + if (category?.Length > 0) { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; - var exception = Assert.Throws(() => + mappingsDict = new Dictionary(); + for (int i = 0; i < category.Length; i = i + 2) { - using var exporter = new GenevaLogExporter(exporterOptions); - }); - Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); + mappingsDict.Add(category[i], category[i + 1]); + } + + exporterOptions.TableNameMappings = mappingsDict; } - } - [Fact] - public void IncompatibleConnectionString_Linux() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; - var exception = Assert.Throws(() => - { - using var exporter = new GenevaLogExporter(exporterOptions); - }); - Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; } - } - - [Theory] - [InlineData("categoryA", "TableA")] - [InlineData("categoryB", "TableB")] - [InlineData("categoryA", "TableA", "categoryB", "TableB")] - [InlineData("categoryA", "TableA", "*", "CatchAll")] - [InlineData(null)] - public void TableNameMappingTest(params string[] category) - { - // ARRANGE - string path = string.Empty; - Socket server = null; - var logRecordList = new List(); - Dictionary mappingsDict = null; - try + else { - var exporterOptions = new GenevaExporterOptions(); - if (category?.Length > 0) - { - mappingsDict = new Dictionary(); - for (int i = 0; i < category.Length; i = i + 2) - { - mappingsDict.Add(category[i], category[i + 1]); - } - - exporterOptions.TableNameMappings = mappingsDict; - } - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - using var loggerFactory = LoggerFactory.Create(builder => builder + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddInMemoryExporter(logRecordList); }) .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); - ILogger logger; - ThreadLocal m_buffer; - object fluentdData; - string actualTableName; - string defaultLogTable = "Log"; - if (mappingsDict != null) + ILogger logger; + ThreadLocal m_buffer; + object fluentdData; + string actualTableName; + string defaultLogTable = "Log"; + if (mappingsDict != null) + { + foreach (var mapping in mappingsDict) { - foreach (var mapping in mappingsDict) + if (!mapping.Key.Equals("*")) { - if (!mapping.Key.Equals("*")) - { - logger = loggerFactory.CreateLogger(mapping.Key); - logger.LogError("this does not matter"); - - Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - actualTableName = (fluentdData as object[])[0] as string; - Assert.Equal(mapping.Value, actualTableName); - logRecordList.Clear(); - } - else - { - defaultLogTable = mapping.Value; - } + logger = loggerFactory.CreateLogger(mapping.Key); + logger.LogError("this does not matter"); + + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + Assert.Equal(mapping.Value, actualTableName); + logRecordList.Clear(); } + else + { + defaultLogTable = mapping.Value; + } + } - // test default table - logger = loggerFactory.CreateLogger("random category"); - logger.LogError("this does not matter"); + // test default table + logger = loggerFactory.CreateLogger("random category"); + logger.LogError("this does not matter"); - Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - actualTableName = (fluentdData as object[])[0] as string; - Assert.Equal(defaultLogTable, actualTableName); - logRecordList.Clear(); - } + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + Assert.Equal(defaultLogTable, actualTableName); + logRecordList.Clear(); } - finally + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } } } + } - [Fact] - public void PassThruTableMappingsWhenTheRuleIsEnabled() + [Fact] + public void PassThruTableMappingsWhenTheRuleIsEnabled() + { + string path = string.Empty; + Socket server = null; + try { - string path = string.Empty; - Socket server = null; - try + var userInitializedCategoryToTableNameMappings = new Dictionary { - var userInitializedCategoryToTableNameMappings = new Dictionary - { - ["Company.Store"] = "Store", - ["Company.Orders"] = "Orders", - ["*"] = "*", - }; + ["Company.Store"] = "Store", + ["Company.Orders"] = "Orders", + ["*"] = "*", + }; - var expectedCategoryToTableNameList = new List> + var expectedCategoryToTableNameList = new List> { // The category name must match "^[A-Z][a-zA-Z0-9]*$"; any character that is not allowed will be removed. new KeyValuePair("Company.Customer", "CompanyCustomer"), @@ -267,116 +266,116 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() new KeyValuePair("1.2", null), }; - var logRecordList = new List(); - var exporterOptions = new GenevaExporterOptions - { - TableNameMappings = userInitializedCategoryToTableNameMappings, - }; + var logRecordList = new List(); + var exporterOptions = new GenevaExporterOptions + { + TableNameMappings = userInitializedCategoryToTableNameMappings, + }; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - using var loggerFactory = LoggerFactory.Create(builder => builder + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddInMemoryExporter(logRecordList); }) .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); - - ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; - ThreadLocal m_buffer; - object fluentdData; - string actualTableName; - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); - // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. - foreach (var mapping in userInitializedCategoryToTableNameMappings) - { - if (mapping.Key != "*") - { - userInitializedTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); - userInitializedTableMappingsLogger.LogInformation("This information does not matter."); - Assert.Single(logRecordList); + ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; + ThreadLocal m_buffer; + object fluentdData; + string actualTableName; + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - actualTableName = (fluentdData as object[])[0] as string; - userInitializedCategoryToTableNameMappings.TryGetValue(mapping.Key, out var expectedTableNme); - Assert.Equal(expectedTableNme, actualTableName); - - logRecordList.Clear(); - } - } - - // Verify that when the "*" = "*" were enabled, the correct table names were being deduced following the set of rules. - foreach (var mapping in expectedCategoryToTableNameList) + // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. + foreach (var mapping in userInitializedCategoryToTableNameMappings) + { + if (mapping.Key != "*") { - passThruTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); - passThruTableMappingsLogger.LogInformation("This information does not matter."); + userInitializedTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); + userInitializedTableMappingsLogger.LogInformation("This information does not matter."); Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); actualTableName = (fluentdData as object[])[0] as string; - string expectedTableName = string.Empty; - expectedTableName = mapping.Value; - Assert.Equal(expectedTableName, actualTableName); + userInitializedCategoryToTableNameMappings.TryGetValue(mapping.Key, out var expectedTableNme); + Assert.Equal(expectedTableNme, actualTableName); logRecordList.Clear(); } } - finally + + // Verify that when the "*" = "*" were enabled, the correct table names were being deduced following the set of rules. + foreach (var mapping in expectedCategoryToTableNameList) { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } + passThruTableMappingsLogger = loggerFactory.CreateLogger(mapping.Key); + passThruTableMappingsLogger.LogInformation("This information does not matter."); + Assert.Single(logRecordList); + + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + actualTableName = (fluentdData as object[])[0] as string; + string expectedTableName = string.Empty; + expectedTableName = mapping.Value; + Assert.Equal(expectedTableName, actualTableName); + + logRecordList.Clear(); } } - - [Fact] - public void SerializeILoggerScopes() + finally { - string path = string.Empty; - Socket senderSocket = null; - Socket receiverSocket = null; + server?.Dispose(); try { - var exporterOptions = new GenevaExporterOptions(); + File.Delete(path); + } + catch + { + } + } + } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - senderSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - senderSocket.Bind(endpoint); - senderSocket.Listen(1); - } + [Fact] + public void SerializeILoggerScopes() + { + string path = string.Empty; + Socket senderSocket = null; + Socket receiverSocket = null; + try + { + var exporterOptions = new GenevaExporterOptions(); - using var loggerFactory = LoggerFactory.Create(builder => builder + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + senderSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + senderSocket.Bind(endpoint); + senderSocket.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.IncludeScopes = true; @@ -386,114 +385,114 @@ public void SerializeILoggerScopes() }); })); - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - receiverSocket = senderSocket.Accept(); - receiverSocket.ReceiveTimeout = 10000; - } + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + receiverSocket = senderSocket.Accept(); + receiverSocket.ReceiveTimeout = 10000; + } - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); - // Emit a LogRecord and grab a copy of internal buffer for validation. - var logger = loggerFactory.CreateLogger(); + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); - using (logger.BeginScope("MyOuterScope")) - using (logger.BeginScope("MyInnerScope")) - using (logger.BeginScope("MyInnerInnerScope with {name} and {age} of custom", "John Doe", 35)) - using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) - { - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - } + using (logger.BeginScope("MyOuterScope")) + using (logger.BeginScope("MyInnerScope")) + using (logger.BeginScope("MyInnerInnerScope with {name} and {age} of custom", "John Doe", 35)) + using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) + { + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } - byte[] serializedData; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - serializedData = m_buffer.Value; - } - else - { - // Read the data sent via socket. - serializedData = new byte[65360]; - _ = receiverSocket.Receive(serializedData); - } + byte[] serializedData; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + serializedData = m_buffer.Value; + } + else + { + // Read the data sent via socket. + serializedData = new byte[65360]; + _ = receiverSocket.Receive(serializedData); + } - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - var signal = (fluentdData as object[])[0] as string; - var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; - var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - var serializedScopes = mapping["scopes"] as object[]; - - Assert.Equal(4, serializedScopes.Length); - - // Test 1st scope - var scope = serializedScopes[0] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("scope", "MyOuterScope"), scope); - - // Test 2nd scope - scope = serializedScopes[1] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("scope", "MyInnerScope"), scope); - - // Test 3rd scope - scope = serializedScopes[2] as ICollection>; - Assert.Equal(3, scope.Count); - Assert.Contains(new KeyValuePair("name", "John Doe"), scope); - Assert.Contains(new KeyValuePair("age", (byte)35), scope); - Assert.Contains(new KeyValuePair("{OriginalFormat}", "MyInnerInnerScope with {name} and {age} of custom"), scope); - - // Test 4th scope - scope = serializedScopes[3] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("MyKey", "MyValue"), scope); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var serializedScopes = mapping["scopes"] as object[]; + + Assert.Equal(4, serializedScopes.Length); + + // Test 1st scope + var scope = serializedScopes[0] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("scope", "MyOuterScope"), scope); + + // Test 2nd scope + scope = serializedScopes[1] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("scope", "MyInnerScope"), scope); + + // Test 3rd scope + scope = serializedScopes[2] as ICollection>; + Assert.Equal(3, scope.Count); + Assert.Contains(new KeyValuePair("name", "John Doe"), scope); + Assert.Contains(new KeyValuePair("age", (byte)35), scope); + Assert.Contains(new KeyValuePair("{OriginalFormat}", "MyInnerInnerScope with {name} and {age} of custom"), scope); + + // Test 4th scope + scope = serializedScopes[3] as ICollection>; + Assert.Single(scope); + Assert.Contains(new KeyValuePair("MyKey", "MyValue"), scope); + } + finally + { + senderSocket?.Dispose(); + receiverSocket?.Dispose(); + try + { + File.Delete(path); } - finally + catch { - senderSocket?.Dispose(); - receiverSocket?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } } } + } - [Theory] - [InlineData(true)] - [InlineData(false)] - public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) + [Theory] + [InlineData(true)] + [InlineData(false)] + public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) + { + // Dedicated test for the raw ILogger.Log method + // https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger.log + + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try { - // Dedicated test for the raw ILogger.Log method - // https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger.log + var exporterOptions = new GenevaExporterOptions(); - // ARRANGE - string path = string.Empty; - Socket server = null; - var logRecordList = new List(); - try + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var exporterOptions = new GenevaExporterOptions(); - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - using var loggerFactory = LoggerFactory.Create(builder => builder + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddGenevaLogExporter(options => @@ -503,198 +502,198 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) options.AddInMemoryExporter(logRecordList); options.IncludeFormattedMessage = includeFormattedMessage; }) - .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels - - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); - - // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter - var logger = loggerFactory.CreateLogger(); - - // ACT - // This is treated as structured logging as the state can be converted to IReadOnlyList> - logger.Log( - LogLevel.Information, - default, - new List>() - { - new KeyValuePair("Key1", "Value1"), - new KeyValuePair("Key2", "Value2"), - }, - null, - (state, ex) => "Formatted Message"); - - // VALIDATE - Assert.Single(logRecordList); - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - var body = GetField(fluentdData, "body"); - if (includeFormattedMessage) - { - Assert.Equal("Formatted Message", body); - } - else - { - Assert.Null(body); - } - - Assert.Equal("Value1", GetField(fluentdData, "Key1")); - Assert.Equal("Value2", GetField(fluentdData, "Key2")); - - // ARRANGE - logRecordList.Clear(); - - // ACT - // This is treated as Un-structured logging as the state cannot be converted to IReadOnlyList> - logger.Log( - LogLevel.Information, - default, - state: "somestringasdata", - exception: null, - formatter: (state, ex) => "Formatted Message"); - - // VALIDATE - Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - body = GetField(fluentdData, "body"); - if (includeFormattedMessage) - { - Assert.Equal("Formatted Message", body); - } - else - { - Assert.Null(body); - } - - // ARRANGE - logRecordList.Clear(); + .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels - // ACT - // This is treated as Un-structured logging as the state cannot be converted to IReadOnlyList> - logger.Log( - LogLevel.Information, - default, - state: "somestringasdata", - exception: null, - formatter: null); + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); - // VALIDATE - Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - body = GetField(fluentdData, "body"); + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); - // Formatter is null, hence body is always null + // ACT + // This is treated as structured logging as the state can be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + new List>() + { + new KeyValuePair("Key1", "Value1"), + new KeyValuePair("Key2", "Value2"), + }, + null, + (state, ex) => "Formatted Message"); + + // VALIDATE + Assert.Single(logRecordList); + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var body = GetField(fluentdData, "body"); + if (includeFormattedMessage) + { + Assert.Equal("Formatted Message", body); + } + else + { Assert.Null(body); + } - // ARRANGE - logRecordList.Clear(); - - // ACT - // This is treated as Structured logging as the state can be converted to IReadOnlyList> - logger.Log( - logLevel: LogLevel.Information, - eventId: default, - new List>() - { - new KeyValuePair("Key1", "Value1"), - }, - exception: null, - formatter: (state, ex) => "Example formatted message."); + Assert.Equal("Value1", GetField(fluentdData, "Key1")); + Assert.Equal("Value2", GetField(fluentdData, "Key2")); - // VALIDATE - Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - Assert.Equal("Value1", GetField(fluentdData, "Key1")); + // ARRANGE + logRecordList.Clear(); + + // ACT + // This is treated as Un-structured logging as the state cannot be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + state: "somestringasdata", + exception: null, + formatter: (state, ex) => "Formatted Message"); + + // VALIDATE + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + body = GetField(fluentdData, "body"); + if (includeFormattedMessage) + { + Assert.Equal("Formatted Message", body); + } + else + { + Assert.Null(body); + } - body = GetField(fluentdData, "body"); + // ARRANGE + logRecordList.Clear(); + + // ACT + // This is treated as Un-structured logging as the state cannot be converted to IReadOnlyList> + logger.Log( + LogLevel.Information, + default, + state: "somestringasdata", + exception: null, + formatter: null); + + // VALIDATE + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + body = GetField(fluentdData, "body"); + + // Formatter is null, hence body is always null + Assert.Null(body); - // Only populate body if FormattedMessage is enabled - if (includeFormattedMessage) - { - Assert.Equal("Example formatted message.", body); - } - else + // ARRANGE + logRecordList.Clear(); + + // ACT + // This is treated as Structured logging as the state can be converted to IReadOnlyList> + logger.Log( + logLevel: LogLevel.Information, + eventId: default, + new List>() { - Assert.Null(body); - } + new KeyValuePair("Key1", "Value1"), + }, + exception: null, + formatter: (state, ex) => "Example formatted message."); + + // VALIDATE + Assert.Single(logRecordList); + m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + Assert.Equal("Value1", GetField(fluentdData, "Key1")); + + body = GetField(fluentdData, "body"); + + // Only populate body if FormattedMessage is enabled + if (includeFormattedMessage) + { + Assert.Equal("Example formatted message.", body); } - finally + else { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } + Assert.Null(body); } } - - [Theory] - [InlineData(false, false, false)] - [InlineData(false, true, false)] - [InlineData(true, false, false)] - [InlineData(true, true, false)] - [InlineData(false, false, true)] - [InlineData(false, true, true)] - [InlineData(true, false, true)] - [InlineData(true, true, true)] - public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) + finally { - string path = string.Empty; - Socket server = null; - var logRecordList = new List(); + server?.Dispose(); try { - var exporterOptions = new GenevaExporterOptions - { - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; + File.Delete(path); + } + catch + { + } + } + } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else + [Theory] + [InlineData(false, false, false)] + [InlineData(false, true, false)] + [InlineData(true, false, false)] + [InlineData(true, true, false)] + [InlineData(false, false, true)] + [InlineData(false, true, true)] + [InlineData(true, false, true)] + [InlineData(true, true, true)] + public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) + { + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions + { + PrepopulatedFields = new Dictionary { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; - if (hasTableNameMapping) - { - exporterOptions.TableNameMappings = new Dictionary - { - { typeof(GenevaLogExporterTests).FullName, "CustomLogRecord" }, - { "*", "DefaultLogRecord" }, - }; - } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - if (hasCustomFields) + if (hasTableNameMapping) + { + exporterOptions.TableNameMappings = new Dictionary { - // The field "customField" of LogRecord.State should be present in the mapping as a separate key. Other fields of LogRecord.State which are not present - // in CustomFields should be added in the mapping under "env_properties" - exporterOptions.CustomFields = new string[] { "customField" }; - } + { typeof(GenevaLogExporterTests).FullName, "CustomLogRecord" }, + { "*", "DefaultLogRecord" }, + }; + } - using var loggerFactory = LoggerFactory.Create(builder => builder + if (hasCustomFields) + { + // The field "customField" of LogRecord.State should be present in the mapping as a separate key. Other fields of LogRecord.State which are not present + // in CustomFields should be added in the mapping under "env_properties" + exporterOptions.CustomFields = new string[] { "customField" }; + } + + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddGenevaLogExporter(options => @@ -707,90 +706,90 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin }) .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels - // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); - // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter - var logger = loggerFactory.CreateLogger(); + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); - using var listener = new ActivityListener(); - listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; - listener.Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; - ActivitySource.AddActivityListener(listener); + using var listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; + listener.Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; + ActivitySource.AddActivityListener(listener); - using var source = new ActivitySource(sourceName); + using var source = new ActivitySource(sourceName); - using (var activity = source.StartActivity("Activity")) - { - // Log inside an activity to set LogRecord.TraceId and LogRecord.SpanId - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); // structured logging - } + using (var activity = source.StartActivity("Activity")) + { + // Log inside an activity to set LogRecord.TraceId and LogRecord.SpanId + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); // structured logging + } - // When the exporter options are configured with TableMappings only "customField" will be logged as a separate key in the mapping - // "property" will be logged under "env_properties" in the mapping - logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", null); - logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", null, "PropertyValue"); - logger.Log(LogLevel.Debug, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Information, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Warning, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Error, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Critical, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.LogInformation("Hello World!"); // unstructured logging - logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {food} {price}.", "artichoke", 3.99); - - // Exception with a non-ASCII character in its type name - logger.LogError(new CustomException\u0418(), "Hello from {food} {price}.", "artichoke", 3.99); - - var loggerWithDefaultCategory = loggerFactory.CreateLogger("DefaultCategory"); - loggerWithDefaultCategory.LogInformation("Basic test"); - loggerWithDefaultCategory.LogInformation("\u0418"); // Include non-ASCII characters in the message - - // logRecordList should have 14 logRecord entries as there were 14 Log calls - Assert.Equal(14, logRecordList.Count); + // When the exporter options are configured with TableMappings only "customField" will be logged as a separate key in the mapping + // "property" will be logged under "env_properties" in the mapping + logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", null); + logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", null, "PropertyValue"); + logger.Log(LogLevel.Debug, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Information, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Warning, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Error, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Critical, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.LogInformation("Hello World!"); // unstructured logging + logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {food} {price}.", "artichoke", 3.99); - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + // Exception with a non-ASCII character in its type name + logger.LogError(new CustomException\u0418(), "Hello from {food} {price}.", "artichoke", 3.99); - foreach (var logRecord in logRecordList) - { - _ = exporter.SerializeLogRecord(logRecord); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - this.AssertFluentdForwardModeForLogRecord(exporterOptions, fluentdData, logRecord); - } + var loggerWithDefaultCategory = loggerFactory.CreateLogger("DefaultCategory"); + loggerWithDefaultCategory.LogInformation("Basic test"); + loggerWithDefaultCategory.LogInformation("\u0418"); // Include non-ASCII characters in the message + + // logRecordList should have 14 logRecord entries as there were 14 Log calls + Assert.Equal(14, logRecordList.Count); + + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + + foreach (var logRecord in logRecordList) + { + _ = exporter.SerializeLogRecord(logRecord); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + this.AssertFluentdForwardModeForLogRecord(exporterOptions, fluentdData, logRecord); } - finally + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } } } + } - [Fact] - public void SuccessfulExport_Windows() + [Fact] + public void SuccessfulExport_Windows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + var exporterOptions = new GenevaExporterOptions() { - var exporterOptions = new GenevaExporterOptions() + PrepopulatedFields = new Dictionary { - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; - using var loggerFactory = LoggerFactory.Create(builder => builder + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddGenevaLogExporter(options => @@ -805,27 +804,27 @@ public void SuccessfulExport_Windows() }); })); - var logger = loggerFactory.CreateLogger(); + var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - } + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); } + } - [Fact] - public void SuccessfulExportOnLinux() + [Fact] + public void SuccessfulExportOnLinux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GenerateTempFilePath(); + var logRecordList = new List(); + try { - string path = GenerateTempFilePath(); - var logRecordList = new List(); - try - { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); - using var loggerFactory = LoggerFactory.Create(builder => builder + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddGenevaLogExporter(options => @@ -840,257 +839,256 @@ public void SuccessfulExportOnLinux() }); options.AddInMemoryExporter(logRecordList); })); - using var serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 10000; + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; - // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - using var exporter = new GenevaLogExporter(new GenevaExporterOptions + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + using var exporter = new GenevaLogExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary { - ConnectionString = "Endpoint=unix:" + path, - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }); + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); - // Emit a LogRecord and grab a copy of internal buffer for validation. - var logger = loggerFactory.CreateLogger(); + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); - // logRecordList should have a singleLogRecord entry after the logger.LogInformation call - Assert.Single(logRecordList); + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); - int messagePackDataSize; - messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + int messagePackDataSize; + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); - // Validation - Assert.Equal(messagePackDataSize, receivedDataSize); + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); - logRecordList.Clear(); + logRecordList.Clear(); - // Emit log on a different thread to test for multithreading scenarios - var thread = new Thread(() => - { - logger.LogInformation("Hello from another thread {food} {price}.", "artichoke", 3.99); - }); - thread.Start(); - thread.Join(); + // Emit log on a different thread to test for multithreading scenarios + var thread = new Thread(() => + { + logger.LogInformation("Hello from another thread {food} {price}.", "artichoke", 3.99); + }); + thread.Start(); + thread.Join(); - // logRecordList should have a singleLogRecord entry after the logger.LogInformation call - Assert.Single(logRecordList); + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); - messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); - receivedDataSize = serverSocket.Receive(receivedData); - Assert.Equal(messagePackDataSize, receivedDataSize); + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + receivedDataSize = serverSocket.Receive(receivedData); + Assert.Equal(messagePackDataSize, receivedDataSize); + } + finally + { + try + { + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } + } - private static string GenerateTempFilePath() + private static string GenerateTempFilePath() + { + while (true) { - while (true) + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (!File.Exists(path)) - { - return path; - } + return path; } } + } - private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") - { - return callingMethodName; - } + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } - private static object GetField(object fluentdData, string key) - { - /* Fluentd Forward Mode: + private static object GetField(object fluentdData, string key) + { + /* Fluentd Forward Mode: + [ + "Log", [ - "Log", - [ - [ , { "env_ver": "4.0", ... } ] - ], - { "TimeFormat": "DateTime" } - ] - */ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ - var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; - var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + + if (mapping.ContainsKey(key)) + { + return mapping[key]; + } + else + { + return null; + } + } - if (mapping.ContainsKey(key)) + private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporterOptions, object fluentdData, LogRecord logRecord) + { + /* Fluentd Forward Mode: + [ + "Log", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var timeStamp = (DateTime)(TimeStampAndMappings as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var timeFormat = (fluentdData as object[])[2] as Dictionary; + + var partAName = "Log"; + if (exporterOptions.TableNameMappings != null) + { + if (exporterOptions.TableNameMappings.ContainsKey(logRecord.CategoryName)) { - return mapping[key]; + partAName = exporterOptions.TableNameMappings[logRecord.CategoryName]; } - else + else if (exporterOptions.TableNameMappings.ContainsKey("*")) { - return null; + partAName = exporterOptions.TableNameMappings["*"]; } } - private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporterOptions, object fluentdData, LogRecord logRecord) - { - /* Fluentd Forward Mode: - [ - "Log", - [ - [ , { "env_ver": "4.0", ... } ] - ], - { "TimeFormat": "DateTime" } - ] - */ - - var signal = (fluentdData as object[])[0] as string; - var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; - var timeStamp = (DateTime)(TimeStampAndMappings as object[])[0]; - var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - var timeFormat = (fluentdData as object[])[2] as Dictionary; + Assert.Equal(partAName, signal); - var partAName = "Log"; - if (exporterOptions.TableNameMappings != null) - { - if (exporterOptions.TableNameMappings.ContainsKey(logRecord.CategoryName)) - { - partAName = exporterOptions.TableNameMappings[logRecord.CategoryName]; - } - else if (exporterOptions.TableNameMappings.ContainsKey("*")) - { - partAName = exporterOptions.TableNameMappings["*"]; - } - } + // Timestamp check + Assert.Equal(logRecord.Timestamp.Ticks, timeStamp.Ticks); - Assert.Equal(partAName, signal); + // Part A core envelope fields - // Timestamp check - Assert.Equal(logRecord.Timestamp.Ticks, timeStamp.Ticks); + var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; - // Part A core envelope fields + // Check if the user has configured a custom table mapping + Assert.Equal(partAName, mapping[nameKey]); - var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; + // TODO: Update this when we support multiple Schema formats + var partAVer = "4.0"; + var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; + Assert.Equal(partAVer, mapping[verKey]); - // Check if the user has configured a custom table mapping - Assert.Equal(partAName, mapping[nameKey]); + foreach (var item in exporterOptions.PrepopulatedFields) + { + var partAValue = item.Value as string; + var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; + Assert.Equal(partAValue, mapping[partAKey]); + } - // TODO: Update this when we support multiple Schema formats - var partAVer = "4.0"; - var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; - Assert.Equal(partAVer, mapping[verKey]); + var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; + Assert.Equal(logRecord.Timestamp.Ticks, ((DateTime)mapping[timeKey]).Ticks); - foreach (var item in exporterOptions.PrepopulatedFields) - { - var partAValue = item.Value as string; - var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; - Assert.Equal(partAValue, mapping[partAKey]); - } + // Part A dt extensions - var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; - Assert.Equal(logRecord.Timestamp.Ticks, ((DateTime)mapping[timeKey]).Ticks); + if (logRecord.TraceId != default) + { + Assert.Equal(logRecord.TraceId.ToHexString(), mapping["env_dt_traceId"]); + } - // Part A dt extensions + if (logRecord.SpanId != default) + { + Assert.Equal(logRecord.SpanId.ToHexString(), mapping["env_dt_spanId"]); + } - if (logRecord.TraceId != default) - { - Assert.Equal(logRecord.TraceId.ToHexString(), mapping["env_dt_traceId"]); - } + if (logRecord.Exception != null) + { + Assert.Equal(logRecord.Exception.GetType().FullName, mapping["env_ex_type"]); + Assert.Equal(logRecord.Exception.Message, mapping["env_ex_msg"]); + } - if (logRecord.SpanId != default) - { - Assert.Equal(logRecord.SpanId.ToHexString(), mapping["env_dt_spanId"]); - } + // Part B fields + Assert.Equal(logRecord.LogLevel.ToString(), mapping["severityText"]); + Assert.Equal((byte)(((int)logRecord.LogLevel * 4) + 1), mapping["severityNumber"]); - if (logRecord.Exception != null) - { - Assert.Equal(logRecord.Exception.GetType().FullName, mapping["env_ex_type"]); - Assert.Equal(logRecord.Exception.Message, mapping["env_ex_msg"]); - } + Assert.Equal(logRecord.CategoryName, mapping["name"]); - // Part B fields - Assert.Equal(logRecord.LogLevel.ToString(), mapping["severityText"]); - Assert.Equal((byte)(((int)logRecord.LogLevel * 4) + 1), mapping["severityNumber"]); + bool isUnstructuredLog = true; + IReadOnlyList> stateKeyValuePairList; + if (logRecord.State == null) + { + stateKeyValuePairList = logRecord.StateValues; + } + else + { + stateKeyValuePairList = logRecord.State as IReadOnlyList>; + } - Assert.Equal(logRecord.CategoryName, mapping["name"]); + if (stateKeyValuePairList != null) + { + isUnstructuredLog = stateKeyValuePairList.Count == 1; + } - bool isUnstructuredLog = true; - IReadOnlyList> stateKeyValuePairList; - if (logRecord.State == null) + if (isUnstructuredLog) + { + if (logRecord.State != null) { - stateKeyValuePairList = logRecord.StateValues; + Assert.Equal(logRecord.State.ToString(), mapping["body"]); } else { - stateKeyValuePairList = logRecord.State as IReadOnlyList>; - } - - if (stateKeyValuePairList != null) - { - isUnstructuredLog = stateKeyValuePairList.Count == 1; + Assert.Equal(stateKeyValuePairList[0].Value, mapping["body"]); } + } + else + { + _ = mapping.TryGetValue("env_properties", out object envProprties); + var envPropertiesMapping = envProprties as IDictionary; - if (isUnstructuredLog) + foreach (var item in stateKeyValuePairList) { - if (logRecord.State != null) + if (item.Key == "{OriginalFormat}") { - Assert.Equal(logRecord.State.ToString(), mapping["body"]); + Assert.Equal(item.Value.ToString(), mapping["body"]); } - else - { - Assert.Equal(stateKeyValuePairList[0].Value, mapping["body"]); - } - } - else - { - _ = mapping.TryGetValue("env_properties", out object envProprties); - var envPropertiesMapping = envProprties as IDictionary; - - foreach (var item in stateKeyValuePairList) + else if (exporterOptions.CustomFields == null || exporterOptions.CustomFields.Contains(item.Key)) { - if (item.Key == "{OriginalFormat}") - { - Assert.Equal(item.Value.ToString(), mapping["body"]); - } - else if (exporterOptions.CustomFields == null || exporterOptions.CustomFields.Contains(item.Key)) - { - if (item.Value != null) - { - Assert.Equal(item.Value, mapping[item.Key]); - } - } - else + if (item.Value != null) { - Assert.Equal(item.Value, envPropertiesMapping[item.Key]); + Assert.Equal(item.Value, mapping[item.Key]); } } + else + { + Assert.Equal(item.Value, envPropertiesMapping[item.Key]); + } } - - if (logRecord.EventId != default) - { - Assert.Equal(logRecord.EventId.Id, int.Parse(mapping["eventId"].ToString())); - } - - // Epilouge - Assert.Equal("DateTime", timeFormat["TimeFormat"]); } - // A custom exception class with non-ASCII character in the type name - private class CustomException\u0418 : Exception + if (logRecord.EventId != default) { + Assert.Equal(logRecord.EventId.Id, int.Parse(mapping["eventId"].ToString())); } + + // Epilouge + Assert.Equal("DateTime", timeFormat["TimeFormat"]); + } + + // A custom exception class with non-ASCII character in the type name + private class CustomException\u0418 : Exception + { } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index 9b0fb22a50..737e27bc1d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -18,78 +18,77 @@ using System.Collections.Generic; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class GenevaMetricExporterOptionsTests { - public class GenevaMetricExporterOptionsTests + [Fact] + public void InvalidPrepopulatedDimensions() { - [Fact] - public void InvalidPrepopulatedDimensions() + var exception = Assert.Throws(() => { - var exception = Assert.Throws(() => - { - var exporterOptions = new GenevaMetricExporterOptions { PrepopulatedMetricDimensions = null }; - }); + var exporterOptions = new GenevaMetricExporterOptions { PrepopulatedMetricDimensions = null }; + }); - Assert.Throws(() => + Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions { - var exporterOptions = new GenevaMetricExporterOptions + PrepopulatedMetricDimensions = new Dictionary { - PrepopulatedMetricDimensions = new Dictionary - { - ["DimensionKey"] = null, - }, - }; - }); + ["DimensionKey"] = null, + }, + }; + }); - var invalidDimensionNameException = Assert.Throws(() => + var invalidDimensionNameException = Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions { - var exporterOptions = new GenevaMetricExporterOptions + PrepopulatedMetricDimensions = new Dictionary { - PrepopulatedMetricDimensions = new Dictionary - { - [new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)] = "DimensionValue", - }, - }; - }); + [new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)] = "DimensionValue", + }, + }; + }); - var expectedErrorMessage = $"The dimension: {new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."; - Assert.Equal(expectedErrorMessage, invalidDimensionNameException.Message); + var expectedErrorMessage = $"The dimension: {new string('a', GenevaMetricExporter.MaxDimensionNameSize + 1)} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."; + Assert.Equal(expectedErrorMessage, invalidDimensionNameException.Message); - var invalidDimensionValueException = Assert.Throws(() => + var invalidDimensionValueException = Assert.Throws(() => + { + var exporterOptions = new GenevaMetricExporterOptions { - var exporterOptions = new GenevaMetricExporterOptions + PrepopulatedMetricDimensions = new Dictionary { - PrepopulatedMetricDimensions = new Dictionary - { - ["DimensionKey"] = new string('a', GenevaMetricExporter.MaxDimensionValueSize + 1), - }, - }; - }); + ["DimensionKey"] = new string('a', GenevaMetricExporter.MaxDimensionValueSize + 1), + }, + }; + }); - expectedErrorMessage = $"Value provided for the dimension: DimensionKey exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."; - Assert.Equal(expectedErrorMessage, invalidDimensionValueException.Message); - } + expectedErrorMessage = $"Value provided for the dimension: DimensionKey exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."; + Assert.Equal(expectedErrorMessage, invalidDimensionValueException.Message); + } - [Fact] - public void MetricExportIntervalValidationTest() + [Fact] + public void MetricExportIntervalValidationTest() + { + Assert.Throws(() => { - Assert.Throws(() => + var exporterOptions = new GenevaMetricExporterOptions { - var exporterOptions = new GenevaMetricExporterOptions - { - MetricExportIntervalMilliseconds = 999, - }; - }); + MetricExportIntervalMilliseconds = 999, + }; + }); - var exception = Record.Exception(() => + var exception = Record.Exception(() => + { + var exporterOptions = new GenevaMetricExporterOptions { - var exporterOptions = new GenevaMetricExporterOptions - { - MetricExportIntervalMilliseconds = 1000, - }; - }); + MetricExportIntervalMilliseconds = 1000, + }; + }); - Assert.Null(exception); - } + Assert.Null(exception); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 746b413c00..1ace1bbd8b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -26,584 +26,500 @@ using System.Threading.Tasks; using Kaitai; using OpenTelemetry.Metrics; -using OpenTelemetry.Trace; using Xunit; using static OpenTelemetry.Exporter.Geneva.Tests.MetricsContract; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class GenevaMetricExporterTests { - public class GenevaMetricExporterTests + [Fact] + public void NullExporterOptions() { - [Fact] - public void NullExporterOptions() + GenevaMetricExporterOptions exporterOptions = null; + Assert.Throws(() => new GenevaMetricExporter(exporterOptions)); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public void InvalidConnectionString(string connectionString) + { + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = connectionString }; + var exception = Assert.Throws(() => { - GenevaMetricExporterOptions exporterOptions = null; - Assert.Throws(() => new GenevaMetricExporter(exporterOptions)); - } + using var exporter = new GenevaMetricExporter(exporterOptions); + }); + } - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - public void InvalidConnectionString(string connectionString) + [Fact] + public void ParseConnectionStringCorrectly() + { + string path = string.Empty; + Socket server = null; + try { - var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = connectionString }; - var exception = Assert.Throws(() => + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - using var exporter = new GenevaMetricExporter(exporterOptions); - }); - } + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - [Fact] - public void ParseConnectionStringCorrectly() + using var exporter = new GenevaMetricExporter(exporterOptions); + var monitoringAccount = typeof(GenevaMetricExporter).GetField("monitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + var metricNamespace = typeof(GenevaMetricExporter).GetField("metricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + Assert.Equal("OTelMonitoringAccount", monitoringAccount); + Assert.Equal("OTelMetricNamespace", metricNamespace); + } + finally { - string path = string.Empty; - Socket server = null; + server?.Dispose(); try { - var exporterOptions = new GenevaMetricExporterOptions(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } - - using var exporter = new GenevaMetricExporter(exporterOptions); - var monitoringAccount = typeof(GenevaMetricExporter).GetField("monitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; - var metricNamespace = typeof(GenevaMetricExporter).GetField("metricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; - Assert.Equal("OTelMonitoringAccount", monitoringAccount); - Assert.Equal("OTelMetricNamespace", metricNamespace); + File.Delete(path); } - finally + catch { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } } } + } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void SuccessfulSerialization(bool testMaxLimits) + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SuccessfulSerialization(bool testMaxLimits) + { + using var meter = new Meter("SuccessfulSerialization", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var histogram = meter.CreateHistogram("histogram"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - using var meter = new Meter("SuccessfulSerialization", "0.0.1"); - var longCounter = meter.CreateCounter("longCounter"); - var doubleCounter = meter.CreateCounter("doubleCounter"); - var histogram = meter.CreateHistogram("histogram"); - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulSerialization") - .AddReader(inMemoryReader) - .Build(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerialization") + .AddReader(inMemoryReader) + .Build(); - long longValue = 123; - double doubleValue = 123.45; + long longValue = 123; + double doubleValue = 123.45; - if (testMaxLimits) - { - longValue = long.MaxValue; - doubleValue = double.MaxValue; - } + if (testMaxLimits) + { + longValue = long.MaxValue; + doubleValue = double.MaxValue; + } - longCounter.Add( - longValue, new("tag1", "value1"), new("tag2", "value2")); + longCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2")); - doubleCounter.Add( - doubleValue, new("tag1", "value1"), new("tag2", "value2")); + doubleCounter.Add( + doubleValue, new("tag1", "value1"), new("tag2", "value2")); - meter.CreateObservableCounter( - "observableLongCounter", - () => new List>() - { - new(longValue, new("tag1", "value1"), new("tag2", "value2")), - }); + meter.CreateObservableCounter( + "observableLongCounter", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2")), + }); - meter.CreateObservableCounter( - "observableDoubleCounter", - () => new List>() - { - new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), - }); + meter.CreateObservableCounter( + "observableDoubleCounter", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), + }); - meter.CreateObservableGauge( - "observableLongGauge", - () => new List>() - { - new(longValue, new("tag1", "value1"), new("tag2", "value2")), - }); + meter.CreateObservableGauge( + "observableLongGauge", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2")), + }); - meter.CreateObservableGauge( - "observableDoubleGauge", - () => new List>() - { - new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), - }); + meter.CreateObservableGauge( + "observableDoubleGauge", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + if (testMaxLimits) + { + // only testing the max value allowed for sum + // max value allowed for count is uint.MaxValue. It's not feasible to test that + histogram.Record(longValue, new("tag1", "value1"), new("tag2", "value2")); + } + else + { + // Record the following values from Histogram: + // (-inf - 0] : 1 + // (0 - 5] : 0 + // (5 - 10] : 0 + // (10 - 25] : 0 + // (25 - 50] : 0 + // (50 - 75] : 0 + // (75 - 100] : 0 + // (100 - 250] : 2 + // (250 - 500] : 0 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for the given distribution: + // 0: 1 + // 250: 2 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogram.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + } - if (testMaxLimits) + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - // only testing the max value allowed for sum - // max value allowed for count is uint.MaxValue. It's not feasible to test that - histogram.Record(longValue, new("tag1", "value1"), new("tag2", "value2")); + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; } else { - // Record the following values from Histogram: - // (-inf - 0] : 1 - // (0 - 5] : 0 - // (5 - 10] : 0 - // (10 - 25] : 0 - // (25 - 50] : 0 - // (50 - 75] : 0 - // (75 - 100] : 0 - // (100 - 250] : 2 - // (250 - 500] : 0 - // (500 - 1000] : 1 - // (1000 - +inf) : 1 - // - // The corresponding value-count pairs to be sent for the given distribution: - // 0: 1 - // 250: 2 - // 1000: 1 - // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) - - histogram.Record(-1, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); } - string path = string.Empty; - Socket server = null; - try + exporterOptions.PrepopulatedMetricDimensions = new Dictionary { - var exporterOptions = new GenevaMetricExporterOptions(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } - - exporterOptions.PrepopulatedMetricDimensions = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; - using var exporter = new GenevaMetricExporter(exporterOptions); + using var exporter = new GenevaMetricExporter(exporterOptions); - inMemoryReader.Collect(); + inMemoryReader.Collect(); - Assert.Equal(7, exportedItems.Count); + Assert.Equal(7, exportedItems.Count); - // check serialization for longCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + // check serialization for longCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); - // check serialization for doubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + // check serialization for doubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - // check serialization for histogram - this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + // check serialization for histogram + this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - // check serialization for observableLongCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + // check serialization for observableLongCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - // check serialization for observableDoubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + // check serialization for observableDoubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - // check serialization for observableLongGauge - this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + // check serialization for observableLongGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); - // check serialization for observableDoubleGauge - this.CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + // check serialization for observableDoubleGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); } - finally + catch { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } } } + } - [Fact] - public void SuccessfulSerializationWithViews() + [Fact] + public void SuccessfulSerializationWithViews() + { + using var meter = new Meter("SuccessfulSerializationWithViews", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var histogramWithCustomBounds = meter.CreateHistogram("histogramWithCustomBounds"); + var histogramWithNoBounds = meter.CreateHistogram("histogramWithNoBounds"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - using var meter = new Meter("SuccessfulSerializationWithViews", "0.0.1"); - var longCounter = meter.CreateCounter("longCounter"); - var doubleCounter = meter.CreateCounter("doubleCounter"); - var histogramWithCustomBounds = meter.CreateHistogram("histogramWithCustomBounds"); - var histogramWithNoBounds = meter.CreateHistogram("histogramWithNoBounds"); - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulSerializationWithViews") - .AddView("longCounter", "renamedLongCounter") - .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { "tag1" } }) - .AddView( - "histogramWithCustomBounds", - new ExplicitBucketHistogramConfiguration - { - Name = "renamedhistogramWithCustomBounds", - Description = "modifiedDescription", - Boundaries = new double[] { 500, 1000 }, - }) - .AddView(instrument => + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerializationWithViews") + .AddView("longCounter", "renamedLongCounter") + .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { "tag1" } }) + .AddView( + "histogramWithCustomBounds", + new ExplicitBucketHistogramConfiguration { - if (instrument.Name == "histogramWithNoBounds") - { - return new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { } }; - } - - return null; + Name = "renamedhistogramWithCustomBounds", + Description = "modifiedDescription", + Boundaries = new double[] { 500, 1000 }, }) - .AddView("observableLongCounter", MetricStreamConfiguration.Drop) - .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { } }) - .AddView(instrument => + .AddView(instrument => + { + if (instrument.Name == "histogramWithNoBounds") { - if (instrument.Name == "observableLongGauge") - { - return new MetricStreamConfiguration - { - Name = "renamedobservableLongGauge", - Description = "modifiedDescription", - TagKeys = new string[] { "tag1" }, - }; - } + return new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { } }; + } - return null; - }) - .AddView(instrument => + return null; + }) + .AddView("observableLongCounter", MetricStreamConfiguration.Drop) + .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { } }) + .AddView(instrument => + { + if (instrument.Name == "observableLongGauge") { - if (instrument.Name == "observableDoubleGauge") + return new MetricStreamConfiguration { - return MetricStreamConfiguration.Drop; - } - - return null; - }) - .AddReader(inMemoryReader) - .Build(); - - longCounter.Add( - 123, new("tag1", "value1"), new("tag2", "value2")); - - doubleCounter.Add( - 123.45, new("tag1", "value1"), new("tag2", "value2")); + Name = "renamedobservableLongGauge", + Description = "modifiedDescription", + TagKeys = new string[] { "tag1" }, + }; + } - meter.CreateObservableCounter( - "observableLongCounter", - () => new List>() + return null; + }) + .AddView(instrument => + { + if (instrument.Name == "observableDoubleGauge") { - new(123, new("tag1", "value1"), new("tag2", "value2")), - }); + return MetricStreamConfiguration.Drop; + } - meter.CreateObservableCounter( - "observableDoubleCounter", - () => new List>() - { - new(123.45, new("tag1", "value1"), new("tag2", "value2")), - }); + return null; + }) + .AddReader(inMemoryReader) + .Build(); - meter.CreateObservableGauge( - "observableLongGauge", - () => new List>() - { - new(123, new("tag1", "value1"), new("tag2", "value2")), - }); + longCounter.Add( + 123, new("tag1", "value1"), new("tag2", "value2")); - meter.CreateObservableGauge( - "observableDoubleGauge", - () => new List>() - { - new(123.45, new("tag1", "value1"), new("tag2", "value2")), - }); + doubleCounter.Add( + 123.45, new("tag1", "value1"), new("tag2", "value2")); - // Record the following values for histogramWithCustomBounds: - // (-inf - 500] : 3 - // (500 - 1000] : 1 - // (1000 - +inf) : 1 - // - // The corresponding value-count pairs to be sent for histogramWithCustomBounds: - // 500: 3 - // 1000: 1 - // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + meter.CreateObservableCounter( + "observableLongCounter", + () => new List>() + { + new(123, new("tag1", "value1"), new("tag2", "value2")), + }); - histogramWithCustomBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + meter.CreateObservableCounter( + "observableDoubleCounter", + () => new List>() + { + new(123.45, new("tag1", "value1"), new("tag2", "value2")), + }); - // Record the following values for histogramWithNoBounds: - // (-inf - 500] : 3 - // (500 - 1000] : 1 - // (1000 - +inf) : 1 - // - // Only `sum` and `count` are sent for histogramWithNoBounds - // No value-count pairs are sent for histogramWithNoBounds + meter.CreateObservableGauge( + "observableLongGauge", + () => new List>() + { + new(123, new("tag1", "value1"), new("tag2", "value2")), + }); - histogramWithNoBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + meter.CreateObservableGauge( + "observableDoubleGauge", + () => new List>() + { + new(123.45, new("tag1", "value1"), new("tag2", "value2")), + }); - string path = string.Empty; - Socket server = null; - try + // Record the following values for histogramWithCustomBounds: + // (-inf - 500] : 3 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for histogramWithCustomBounds: + // 500: 3 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogramWithCustomBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + + // Record the following values for histogramWithNoBounds: + // (-inf - 500] : 3 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // Only `sum` and `count` are sent for histogramWithNoBounds + // No value-count pairs are sent for histogramWithNoBounds + + histogramWithNoBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var exporterOptions = new GenevaMetricExporterOptions(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - exporterOptions.PrepopulatedMetricDimensions = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; + exporterOptions.PrepopulatedMetricDimensions = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; - using var exporter = new GenevaMetricExporter(exporterOptions); + using var exporter = new GenevaMetricExporter(exporterOptions); - inMemoryReader.Collect(); + inMemoryReader.Collect(); - Assert.Equal(6, exportedItems.Count); + Assert.Equal(6, exportedItems.Count); - // observableLongCounter and observableDoubleGauge are dropped - Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); + // observableLongCounter and observableDoubleGauge are dropped + Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); - // check serialization for longCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + // check serialization for longCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); - // check serialization for doubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + // check serialization for doubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - // check serialization for histogramWithCustomBounds - this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + // check serialization for histogramWithCustomBounds + this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - // check serialization for histogramWithNoBounds - this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + // check serialization for histogramWithNoBounds + this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - // check serialization for observableDoubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + // check serialization for observableDoubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - // check serialization for observableLongGauge - this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + // check serialization for observableLongGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); } - finally + catch { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } } } + } - [Fact] - public void SuccessfulExportOnLinux() + [Fact] + public void SuccessfulExportOnLinux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - string path = GenerateTempFilePath(); - var exportedItems = new List(); + string path = GenerateTempFilePath(); + var exportedItems = new List(); - using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); - var counter = meter.CreateCounter("counter"); + using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); + var counter = meter.CreateCounter("counter"); - using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); - var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); + using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); + var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); - try + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + // Set up two different providers as only one Metric Processor is allowed. + // TODO: Simplify the setup when multiple Metric processors are allowed. + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulExportOnLinux") + .AddGenevaMetricExporter(options => { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + options.MetricExportIntervalMilliseconds = 5000; + }) + .Build(); - // Set up two different providers as only one Metric Processor is allowed. - // TODO: Simplify the setup when multiple Metric processors are allowed. - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulExportOnLinux") - .AddGenevaMetricExporter(options => - { - options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - options.MetricExportIntervalMilliseconds = 5000; - }) - .Build(); - - using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("InMemoryExportOnLinux") - .AddReader(inMemoryReader) - .Build(); - - using var serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 15000; - - // Create a test exporter to get byte data for validation of the data received via Socket. - var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - using var exporter = new GenevaMetricExporter(exporterOptions); - - // Emit a metric and grab a copy of internal buffer for validation. - counter.Add( - 123, - new KeyValuePair("tag1", "value1"), - new KeyValuePair("tag2", "value2")); - - inMemoryCounter.Add( - 123, - new KeyValuePair("tag1", "value1"), - new KeyValuePair("tag2", "value2")); - - // exportedItems list should have a single entry after the MetricReader.Collect call - inMemoryReader.Collect(); - - Assert.Single(exportedItems); - - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); - var metricData = new MetricData { UInt64Value = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - - // Wait a little more than the ExportInterval for the exporter to export the data. - Task.Delay(5500).Wait(); - - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); - - var fixedPayloadLength = (int)typeof(GenevaMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); - - // The whole payload is sent to the Unix Domain Socket - // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload - Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); - - var stream = new KaitaiStream(receivedData); - var data = new MetricsContract(stream); - - Assert.Equal(metric.Name, data.Body.MetricName.Value); - Assert.Equal("OTelMonitoringAccount", data.Body.MetricAccount.Value); - Assert.Equal("OTelMetricNamespace", data.Body.MetricNamespace.Value); - - var valueSection = data.Body.ValueSection as SingleUint64Value; - Assert.Equal(metricDataValue, valueSection.Value); - - Assert.Equal(2, data.Body.NumDimensions); - - int i = 0; - foreach (var tag in metricPoint.Tags) - { - Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); - i++; - } + using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("InMemoryExportOnLinux") + .AddReader(inMemoryReader) + .Build(); - Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - finally - { - try - { - File.Delete(path); - } - catch - { - } - } - } - } + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 15000; - private static string GenerateTempFilePath() - { - while (true) - { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (!File.Exists(path)) - { - return path; - } - } - } + // Create a test exporter to get byte data for validation of the data received via Socket. + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; + using var exporter = new GenevaMetricExporter(exporterOptions); - private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) - { - var metricType = metric.MetricType; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - MetricsContract data = null; - - // Check metric value, timestamp, eventId, and length of payload - if (metricType == MetricType.LongSum || metricType == MetricType.LongGauge) - { - var metricDataValue = metricType == MetricType.LongSum ? - Convert.ToUInt64(metricPoint.GetSumLong()) : - Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); + // Emit a metric and grab a copy of internal buffer for validation. + counter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + inMemoryCounter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + // exportedItems list should have a single entry after the MetricReader.Collect call + inMemoryReader.Collect(); + + Assert.Single(exportedItems); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; var bodyLength = exporter.SerializeMetric( MetricEventType.ULongMetric, @@ -611,128 +527,210 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); + + // Wait a little more than the ExportInterval for the exporter to export the data. + Task.Delay(5500).Wait(); + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + var fixedPayloadLength = (int)typeof(GenevaMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); + + // The whole payload is sent to the Unix Domain Socket + // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload + Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); + + var stream = new KaitaiStream(receivedData); + var data = new MetricsContract(stream); + + Assert.Equal(metric.Name, data.Body.MetricName.Value); + Assert.Equal("OTelMonitoringAccount", data.Body.MetricAccount.Value); + Assert.Equal("OTelMetricNamespace", data.Body.MetricNamespace.Value); + var valueSection = data.Body.ValueSection as SingleUint64Value; Assert.Equal(metricDataValue, valueSection.Value); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + + Assert.Equal(2, data.Body.NumDimensions); + + int i = 0; + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); + i++; + } + Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); Assert.Equal(bodyLength, data.LenBody); } - else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + finally { - var metricDataValue = metricType == MetricType.DoubleSum ? - metricPoint.GetSumDouble() : - metricPoint.GetGaugeLastValueDouble(); - var metricData = new MetricData { DoubleValue = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as SingleDoubleValue; - Assert.Equal(metricDataValue, valueSection.Value); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); + try + { + File.Delete(path); + } + catch + { + } + } + } + } + + private static string GenerateTempFilePath() + { + while (true) + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) + { + return path; } - else if (metricType == MetricType.Histogram) + } + } + + private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) + { + var metricType = metric.MetricType; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + MetricsContract data = null; + + // Check metric value, timestamp, eventId, and length of payload + if (metricType == MetricType.LongSum || metricType == MetricType.LongGauge) + { + var metricDataValue = metricType == MetricType.LongSum ? + Convert.ToUInt64(metricPoint.GetSumLong()) : + Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleUint64Value; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + { + var metricDataValue = metricType == MetricType.DoubleSum ? + metricPoint.GetSumDouble() : + metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleDoubleValue; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.Histogram) + { + var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + var bodyLength = exporter.SerializeHistogramMetric( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as ExtAggregatedUint64Value; + var valueCountPairs = data.Body.Histogram.Body as HistogramValueCountPairs; + + Assert.Equal(0, data.Body.Histogram.Version); + Assert.Equal(2, (int)data.Body.Histogram.Type); + + int listIterator = 0; + int bucketsWithPositiveCount = 0; + double lastExplicitBound = default; + foreach (var bucket in metricPoint.GetHistogramBuckets()) { - var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; - var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - var bodyLength = exporter.SerializeHistogramMetric( - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricPoint.GetHistogramBuckets(), - sum, - count); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as ExtAggregatedUint64Value; - var valueCountPairs = data.Body.Histogram.Body as HistogramValueCountPairs; - - Assert.Equal(0, data.Body.Histogram.Version); - Assert.Equal(2, (int)data.Body.Histogram.Type); - - int listIterator = 0; - int bucketsWithPositiveCount = 0; - double lastExplicitBound = default; - foreach (var bucket in metricPoint.GetHistogramBuckets()) + if (bucket.BucketCount > 0) { - if (bucket.BucketCount > 0) + if (bucket.ExplicitBound != double.PositiveInfinity) { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - Assert.Equal(bucket.ExplicitBound, valueCountPairs.Columns[listIterator].Value); - lastExplicitBound = bucket.ExplicitBound; - } - else - { - Assert.Equal((ulong)lastExplicitBound + 1, valueCountPairs.Columns[listIterator].Value); - } - - Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); - - listIterator++; - bucketsWithPositiveCount++; + Assert.Equal(bucket.ExplicitBound, valueCountPairs.Columns[listIterator].Value); + lastExplicitBound = bucket.ExplicitBound; + } + else + { + Assert.Equal((ulong)lastExplicitBound + 1, valueCountPairs.Columns[listIterator].Value); } - } - Assert.Equal(bucketsWithPositiveCount, valueCountPairs.DistributionSize); + Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); - Assert.Equal(count, valueSection.Count); - Assert.Equal(Convert.ToUInt64(metricPoint.GetHistogramSum()), valueSection.Sum); - Assert.Equal(0UL, valueSection.Min); - Assert.Equal(0UL, valueSection.Max); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); + listIterator++; + bucketsWithPositiveCount++; + } } - // Check metric name, account, and namespace - var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); - Assert.Equal(metric.Name, data.Body.MetricName.Value); - Assert.Equal(connectionStringBuilder.Account, data.Body.MetricAccount.Value); - Assert.Equal(connectionStringBuilder.Namespace, data.Body.MetricNamespace.Value); + Assert.Equal(bucketsWithPositiveCount, valueCountPairs.DistributionSize); - var dimensionsCount = 0; - if (exporterOptions.PrepopulatedMetricDimensions != null) - { - foreach (var entry in exporterOptions.PrepopulatedMetricDimensions) - { - Assert.Contains(data.Body.DimensionsNames, dim => dim.Value == entry.Key); - Assert.Contains(data.Body.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); - } + Assert.Equal(count, valueSection.Count); + Assert.Equal(Convert.ToUInt64(metricPoint.GetHistogramSum()), valueSection.Sum); + Assert.Equal(0UL, valueSection.Min); + Assert.Equal(0UL, valueSection.Max); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } - dimensionsCount += exporterOptions.PrepopulatedMetricDimensions.Count; - } + // Check metric name, account, and namespace + var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); + Assert.Equal(metric.Name, data.Body.MetricName.Value); + Assert.Equal(connectionStringBuilder.Account, data.Body.MetricAccount.Value); + Assert.Equal(connectionStringBuilder.Namespace, data.Body.MetricNamespace.Value); - // Check metric dimensions - int i = 0; - foreach (var item in exporterOptions.PrepopulatedMetricDimensions) + var dimensionsCount = 0; + if (exporterOptions.PrepopulatedMetricDimensions != null) + { + foreach (var entry in exporterOptions.PrepopulatedMetricDimensions) { - Assert.Equal(item.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(item.Value, data.Body.DimensionsValues[i].Value); - i++; + Assert.Contains(data.Body.DimensionsNames, dim => dim.Value == entry.Key); + Assert.Contains(data.Body.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); } - foreach (var tag in metricPoint.Tags) - { - Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); - i++; - } + dimensionsCount += exporterOptions.PrepopulatedMetricDimensions.Count; + } - dimensionsCount += metricPoint.Tags.Count; + // Check metric dimensions + int i = 0; + foreach (var item in exporterOptions.PrepopulatedMetricDimensions) + { + Assert.Equal(item.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(item.Value, data.Body.DimensionsValues[i].Value); + i++; + } - Assert.Equal(dimensionsCount, data.Body.NumDimensions); + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); + Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); + i++; } + + dimensionsCount += metricPoint.Tags.Count; + + Assert.Equal(dimensionsCount, data.Body.NumDimensions); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index a75d66c5f6..0db23b09b7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -24,268 +24,267 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -using System.Threading.Tasks; using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class GenevaTraceExporterTests { - public class GenevaTraceExporterTests + public GenevaTraceExporterTests() { - public GenevaTraceExporterTests() + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + } + + [Fact] + public void GenevaTraceExporter_constructor_Invalid_Input() + { + // no connection string + Assert.Throws(() => { - Activity.DefaultIdFormat = ActivityIdFormat.W3C; - } + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions()); + }); - [Fact] - public void GenevaTraceExporter_constructor_Invalid_Input() + // null connection string + Assert.Throws(() => { - // no connection string - Assert.Throws(() => + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions()); + ConnectionString = null, }); + }); - // null connection string - Assert.Throws(() => - { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = null, - }); - }); - - // null value in the PrepopulatedFields - Assert.Throws(() => + // null value in the PrepopulatedFields + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary - { - ["cloud.roleVer"] = null, - }, - }); + ["cloud.roleVer"] = null, + }, }); + }); - // unsupported types(char) for PrepopulatedFields - Assert.Throws(() => + // unsupported types(char) for PrepopulatedFields + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = (char)106, - }, - }); + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = (char)106, + }, }); + }); - // Supported types for PrepopulatedFields should not throw an exception - var exception = Record.Exception(() => + // Supported types for PrepopulatedFields should not throw an exception + var exception = Record.Exception(() => + { + new GenevaExporterOptions { - new GenevaExporterOptions - { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary - { - ["bool"] = true, - ["byte"] = byte.MaxValue, - ["sbyte"] = sbyte.MaxValue, - ["short"] = short.MaxValue, - ["ushort"] = ushort.MaxValue, - ["int"] = int.MaxValue, - ["uint"] = uint.MaxValue, - ["long"] = long.MaxValue, - ["ulong"] = ulong.MaxValue, - ["float"] = float.MaxValue, - ["double"] = double.MaxValue, - ["string"] = string.Empty, - }, - }; - }); - - Assert.Null(exception); - } + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["bool"] = true, + ["byte"] = byte.MaxValue, + ["sbyte"] = sbyte.MaxValue, + ["short"] = short.MaxValue, + ["ushort"] = ushort.MaxValue, + ["int"] = int.MaxValue, + ["uint"] = uint.MaxValue, + ["long"] = long.MaxValue, + ["ulong"] = ulong.MaxValue, + ["float"] = float.MaxValue, + ["double"] = double.MaxValue, + ["string"] = string.Empty, + }, + }; + }); + + Assert.Null(exception); + } - [Fact] - public void GenevaTraceExporter_constructor_Invalid_Input_Windows() + [Fact] + public void GenevaTraceExporter_constructor_Invalid_Input_Windows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // no ETW session name + Assert.Throws(() => { - // no ETW session name - Assert.Throws(() => - { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "key=value", - }); - }); - - // empty ETW session name - Assert.Throws(() => + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "EtwSession=", - }); + ConnectionString = "key=value", }); - } - } + }); - [Fact] - public void GenevaTraceExporter_TableNameMappings_SpecialCharacters() - { + // empty ETW session name Assert.Throws(() => { using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - TableNameMappings = new Dictionary { ["Span"] = "\u0418" }, + ConnectionString = "EtwSession=", }); }); } + } - [Fact] - public void GenevaTraceExporter_Success_Windows() + [Fact] + public void GenevaTraceExporter_TableNameMappings_SpecialCharacters() + { + Assert.Throws(() => { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); + TableNameMappings = new Dictionary { ["Span"] = "\u0418" }, + }); + }); + } - // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => + [Fact] + public void GenevaTraceExporter_Success_Windows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + + // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary { - options.ConnectionString = "EtwSession=OpenTelemetry"; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); - var source = new ActivitySource(sourceName); - using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) + var source = new ActivitySource(sourceName); + using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) + { + parent?.SetTag("http.method", "GET"); + parent?.SetTag("http.url", "https://localhost/wiki/Rabbit"); + using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) { - parent?.SetTag("http.method", "GET"); - parent?.SetTag("http.url", "https://localhost/wiki/Rabbit"); - using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) - { - child?.SetTag("http.method", "GET"); - child?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); - child?.SetTag("http.status_code", 404); - } - - parent?.SetTag("http.status_code", 200); + child?.SetTag("http.method", "GET"); + child?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + child?.SetTag("http.status_code", 404); } - var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); - using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) - { - } + parent?.SetTag("http.status_code", 200); + } - using (var activity = source.StartActivity("Bar")) - { - activity.SetStatus(Status.Error); - } + var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); + using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) + { + } - using (var activity = source.StartActivity("Baz")) - { - activity.SetStatus(Status.Ok); - } + using (var activity = source.StartActivity("Bar")) + { + activity.SetStatus(Status.Error); + } + + using (var activity = source.StartActivity("Baz")) + { + activity.SetStatus(Status.Ok); } } + } - [Theory] - [InlineData(false, false)] - [InlineData(false, true)] - [InlineData(true, false)] - [InlineData(true, true)] - public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields) + [Theory] + [InlineData(false, false)] + [InlineData(false, true)] + [InlineData(true, false)] + [InlineData(true, true)] + public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields) + { + string path = string.Empty; + Socket server = null; + try { - string path = string.Empty; - Socket server = null; - try + int invocationCount = 0; + var exporterOptions = new GenevaExporterOptions { - int invocationCount = 0; - var exporterOptions = new GenevaExporterOptions - { - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + PrepopulatedFields = new Dictionary { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; - } - else - { - path = GetRandomFilePath(); - exporterOptions.ConnectionString = "Endpoint=unix:" + path; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } - - if (hasTableNameMapping) - { - exporterOptions.TableNameMappings = new Dictionary { { "Span", "CustomActivity" } }; - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GetRandomFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } - if (hasCustomFields) - { - // The tag "clientRequestId" should be present in the mapping as a separate key. Other tags which are not present - // in the m_dedicatedFields should be added in the mapping under "env_properties" - exporterOptions.CustomFields = new string[] { "clientRequestId" }; - } + if (hasTableNameMapping) + { + exporterOptions.TableNameMappings = new Dictionary { { "Span", "CustomActivity" } }; + } - using var exporter = new GenevaTraceExporter(exporterOptions); - var dedicatedFields = typeof(GenevaTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as IReadOnlyDictionary; - var CS40_PART_B_MAPPING = typeof(GenevaTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; - var m_buffer = typeof(GenevaTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; + if (hasCustomFields) + { + // The tag "clientRequestId" should be present in the mapping as a separate key. Other tags which are not present + // in the m_dedicatedFields should be added in the mapping under "env_properties" + exporterOptions.CustomFields = new string[] { "clientRequestId" }; + } - // Add an ActivityListener to serialize the activity and assert that it was valid on ActivityStopped event + using var exporter = new GenevaTraceExporter(exporterOptions); + var dedicatedFields = typeof(GenevaTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as IReadOnlyDictionary; + var CS40_PART_B_MAPPING = typeof(GenevaTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; + var m_buffer = typeof(GenevaTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - Action> customChecksForActivity = null; + // Add an ActivityListener to serialize the activity and assert that it was valid on ActivityStopped event - using var listener = new ActivityListener(); - listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; - listener.Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; - listener.ActivityStopped = (activity) => - { - _ = exporter.SerializeActivity(activity); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); - this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields, customChecksForActivity); - invocationCount++; - }; - ActivitySource.AddActivityListener(listener); + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + Action> customChecksForActivity = null; - using var source = new ActivitySource(sourceName); - using (var parentActivity = source.StartActivity("ParentActivity")) - { - var linkedtraceId1 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a1".AsSpan()); - var linkedSpanId1 = ActivitySpanId.CreateFromString("888915b6286b9c01".AsSpan()); + using var listener = new ActivityListener(); + listener.ShouldListenTo = (activitySource) => activitySource.Name == sourceName; + listener.Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded; + listener.ActivityStopped = (activity) => + { + _ = exporter.SerializeActivity(activity); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields, customChecksForActivity); + invocationCount++; + }; + ActivitySource.AddActivityListener(listener); + + using var source = new ActivitySource(sourceName); + using (var parentActivity = source.StartActivity("ParentActivity")) + { + var linkedtraceId1 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a1".AsSpan()); + var linkedSpanId1 = ActivitySpanId.CreateFromString("888915b6286b9c01".AsSpan()); - var linkedtraceId2 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a2".AsSpan()); - var linkedSpanId2 = ActivitySpanId.CreateFromString("888915b6286b9c02".AsSpan()); + var linkedtraceId2 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a2".AsSpan()); + var linkedSpanId2 = ActivitySpanId.CreateFromString("888915b6286b9c02".AsSpan()); - var links = new[] - { + var links = new[] + { new ActivityLink(new ActivityContext( linkedtraceId1, linkedSpanId1, @@ -294,356 +293,355 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, linkedtraceId2, linkedSpanId2, ActivityTraceFlags.Recorded)), - }; - - using (var activity = source.StartActivity("SayHello", ActivityKind.Internal, parentActivity.Context, null, links)) - { - activity?.SetTag("http.status_code", 500); // This should be added as httpStatusCode in the mapping - activity?.SetTag("azureResourceProvider", "Microsoft.AAD"); - activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); - activity?.SetTag("foo", 1); - activity?.SetTag("bar", 2); - activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); - } - } - - using (var activity = source.StartActivity("TestActivityForSetStatusAPI")) - { - activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); - } + }; - // If the activity Status is set using both the OTel API and the .NET API, the `Status` and `StatusDescription` set by - // the .NET API is chosen - using (var activity = source.StartActivity("PreferStatusFromDotnetAPI")) + using (var activity = source.StartActivity("SayHello", ActivityKind.Internal, parentActivity.Context, null, links)) { + activity?.SetTag("http.status_code", 500); // This should be added as httpStatusCode in the mapping + activity?.SetTag("azureResourceProvider", "Microsoft.AAD"); + activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); + activity?.SetTag("foo", 1); + activity?.SetTag("bar", 2); activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); - activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); - customChecksForActivity = mapping => - { - Assert.Equal("Error description from .NET API", mapping["statusMessage"]); - }; } + } - Assert.Equal(4, invocationCount); + using (var activity = source.StartActivity("TestActivityForSetStatusAPI")) + { + activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); } - finally + + // If the activity Status is set using both the OTel API and the .NET API, the `Status` and `StatusDescription` set by + // the .NET API is chosen + using (var activity = source.StartActivity("PreferStatusFromDotnetAPI")) { - server?.Dispose(); - try - { - File.Delete(path); - } - catch + activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); + activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); + customChecksForActivity = mapping => { - } + Assert.Equal("Error description from .NET API", mapping["statusMessage"]); + }; } - } - [Fact] - public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() + Assert.Equal(4, invocationCount); + } + finally { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + server?.Dispose(); + try { - string path = GetRandomFilePath(); + File.Delete(path); + } + catch + { + } + } + } - // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address - try - { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "Endpoint=unix:" + path; - }) - .Build(); - Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); - } - catch (SocketException ex) - { - // There is no one to listent to the socket. - Assert.Contains("Cannot assign requested address", ex.Message); - } + [Fact] + public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + string path = GetRandomFilePath(); - try - { - var exporter = new GenevaTraceExporter(new GenevaExporterOptions + // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address + try + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => { - ConnectionString = "Endpoint=unix:" + path, - }); - Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); - } - catch (SocketException ex) + options.ConnectionString = "Endpoint=unix:" + path; + }) + .Build(); + Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + } + catch (SocketException ex) + { + // There is no one to listent to the socket. + Assert.Contains("Cannot assign requested address", ex.Message); + } + + try + { + var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - // There is no one to listent to the socket. - Assert.Contains("Cannot assign requested address", ex.Message); - } + ConnectionString = "Endpoint=unix:" + path, + }); + Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + } + catch (SocketException ex) + { + // There is no one to listent to the socket. + Assert.Contains("Cannot assign requested address", ex.Message); } } + } - [Fact] - public void GenevaTraceExporter_Success_Linux() + [Fact] + public void GenevaTraceExporter_Success_Linux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GetRandomFilePath(); + try { - string path = GetRandomFilePath(); - try - { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "Endpoint=unix:" + path; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); - using Socket serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 10000; - - // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - var exporter = new GenevaTraceExporter(new GenevaExporterOptions + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => { - ConnectionString = "Endpoint=unix:" + path, - PrepopulatedFields = new Dictionary + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", ["cloud.roleInstance"] = "CY1SCH030021417", ["cloud.roleVer"] = "9.0.15289.2", - }, - }); - - // Emit trace and grab a copy of internal buffer for validation. - var source = new ActivitySource(sourceName); - int messagePackDataSize = 0; + }; + }) + .Build(); + using Socket serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; - using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + var exporter = new GenevaTraceExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary { - messagePackDataSize = exporter.SerializeActivity(activity); - } - - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); - // Validation - Assert.Equal(messagePackDataSize, receivedDataSize); + // Emit trace and grab a copy of internal buffer for validation. + var source = new ActivitySource(sourceName); + int messagePackDataSize = 0; - // Create activity on a different thread to test for multithreading scenarios - var thread = new Thread(() => - { - using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) - { - messagePackDataSize = exporter.SerializeActivity(activity); - } - }); - thread.Start(); - thread.Join(); - - receivedDataSize = serverSocket.Receive(receivedData); - Assert.Equal(messagePackDataSize, receivedDataSize); - } - catch (Exception) + using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) { - throw; + messagePackDataSize = exporter.SerializeActivity(activity); } - finally + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); + + // Create activity on a different thread to test for multithreading scenarios + var thread = new Thread(() => { - try - { - File.Delete(path); - } - catch + using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) { + messagePackDataSize = exporter.SerializeActivity(activity); } + }); + thread.Start(); + thread.Join(); + + receivedDataSize = serverSocket.Receive(receivedData); + Assert.Equal(messagePackDataSize, receivedDataSize); + } + catch (Exception) + { + throw; + } + finally + { + try + { + File.Delete(path); + } + catch + { } } } + } - private static string GetRandomFilePath() + private static string GetRandomFilePath() + { + while (true) { - while (true) + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (!File.Exists(path)) - { - return path; - } + return path; } } + } - private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } + + private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, IReadOnlyDictionary dedicatedFields, Action> customChecksForActivity) + { + /* Fluentd Forward Mode: + [ + "Span", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var timeStamp = (DateTime)(TimeStampAndMappings as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var timeFormat = (fluentdData as object[])[2] as Dictionary; + + var partAName = "Span"; + if (exporterOptions.TableNameMappings != null) { - return callingMethodName; + partAName = exporterOptions.TableNameMappings["Span"]; } - private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, IReadOnlyDictionary dedicatedFields, Action> customChecksForActivity) - { - /* Fluentd Forward Mode: - [ - "Span", - [ - [ , { "env_ver": "4.0", ... } ] - ], - { "TimeFormat": "DateTime" } - ] - */ - - var signal = (fluentdData as object[])[0] as string; - var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; - var timeStamp = (DateTime)(TimeStampAndMappings as object[])[0]; - var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - var timeFormat = (fluentdData as object[])[2] as Dictionary; - - var partAName = "Span"; - if (exporterOptions.TableNameMappings != null) - { - partAName = exporterOptions.TableNameMappings["Span"]; - } + Assert.Equal(partAName, signal); - Assert.Equal(partAName, signal); + // Timestamp check + var dtBegin = activity.StartTimeUtc; + var tsBegin = dtBegin.Ticks; + var tsEnd = tsBegin + activity.Duration.Ticks; + Assert.Equal(tsEnd, timeStamp.Ticks); - // Timestamp check - var dtBegin = activity.StartTimeUtc; - var tsBegin = dtBegin.Ticks; - var tsEnd = tsBegin + activity.Duration.Ticks; - Assert.Equal(tsEnd, timeStamp.Ticks); + // Part A core envelope fields - // Part A core envelope fields + var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; - var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; + // Check if the user has configured a custom table mapping + Assert.Equal(partAName, mapping[nameKey]); - // Check if the user has configured a custom table mapping - Assert.Equal(partAName, mapping[nameKey]); + // TODO: Update this when we support multiple Schema formats + var partAVer = "4.0"; + var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; + Assert.Equal(partAVer, mapping[verKey]); - // TODO: Update this when we support multiple Schema formats - var partAVer = "4.0"; - var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; - Assert.Equal(partAVer, mapping[verKey]); + foreach (var item in exporterOptions.PrepopulatedFields) + { + var partAValue = item.Value as string; + var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; + Assert.Equal(partAValue, mapping[partAKey]); + } - foreach (var item in exporterOptions.PrepopulatedFields) - { - var partAValue = item.Value as string; - var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; - Assert.Equal(partAValue, mapping[partAKey]); - } + var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; + Assert.Equal(tsEnd, ((DateTime)mapping[timeKey]).Ticks); + + // Part A dt extensions + Assert.Equal(activity.TraceId.ToString(), mapping["env_dt_traceId"]); + Assert.Equal(activity.SpanId.ToString(), mapping["env_dt_spanId"]); - var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; - Assert.Equal(tsEnd, ((DateTime)mapping[timeKey]).Ticks); + // Part B Span - required fields + Assert.Equal(activity.DisplayName, mapping["name"]); + Assert.Equal((byte)activity.Kind, mapping["kind"]); + Assert.Equal(activity.StartTimeUtc, mapping["startTime"]); - // Part A dt extensions - Assert.Equal(activity.TraceId.ToString(), mapping["env_dt_traceId"]); - Assert.Equal(activity.SpanId.ToString(), mapping["env_dt_spanId"]); + var activityStatusCode = activity.GetStatus().StatusCode; - // Part B Span - required fields - Assert.Equal(activity.DisplayName, mapping["name"]); - Assert.Equal((byte)activity.Kind, mapping["kind"]); - Assert.Equal(activity.StartTimeUtc, mapping["startTime"]); + if (activity.Status == ActivityStatusCode.Error) + { + Assert.False((bool)mapping["success"]); + Assert.Equal(activity.StatusDescription, mapping["statusMessage"]); + } + else if (activityStatusCode == StatusCode.Error) + { + Assert.False((bool)mapping["success"]); + var activityStatusDesc = activity.GetStatus().Description; + Assert.Equal(activityStatusDesc, mapping["statusMessage"]); + } + else + { + Assert.True((bool)mapping["success"]); + } - var activityStatusCode = activity.GetStatus().StatusCode; + // Part B Span optional fields and Part C fields + if (activity.ParentSpanId != default) + { + Assert.Equal(activity.ParentSpanId.ToHexString(), mapping["parentId"]); + } - if (activity.Status == ActivityStatusCode.Error) - { - Assert.False((bool)mapping["success"]); - Assert.Equal(activity.StatusDescription, mapping["statusMessage"]); - } - else if (activityStatusCode == StatusCode.Error) - { - Assert.False((bool)mapping["success"]); - var activityStatusDesc = activity.GetStatus().Description; - Assert.Equal(activityStatusDesc, mapping["statusMessage"]); - } - else + #region Assert Activity Links + if (activity.Links.Any()) + { + Assert.Contains(mapping, m => m.Key as string == "links"); + var mappingLinks = mapping["links"] as IEnumerable; + using IEnumerator activityLinksEnumerator = activity.Links.GetEnumerator(); + using IEnumerator mappingLinksEnumerator = mappingLinks.GetEnumerator(); + while (activityLinksEnumerator.MoveNext() && mappingLinksEnumerator.MoveNext()) { - Assert.True((bool)mapping["success"]); + var activityLink = activityLinksEnumerator.Current; + var mappingLink = mappingLinksEnumerator.Current as Dictionary; + + Assert.Equal(activityLink.Context.TraceId.ToHexString(), mappingLink["toTraceId"]); + Assert.Equal(activityLink.Context.SpanId.ToHexString(), mappingLink["toSpanId"]); } - // Part B Span optional fields and Part C fields - if (activity.ParentSpanId != default) + // Assert that mapping contains exactly the same number of ActivityLinks as present in the activity + // MoveNext() on both the enumerators should return false as we should have enumerated till the last element for both the Enumerables + Assert.Equal(activityLinksEnumerator.MoveNext(), mappingLinksEnumerator.MoveNext()); + } + else + { + Assert.DoesNotContain(mapping, m => m.Key as string == "links"); + } + #endregion + + #region Assert Activity Tags + _ = mapping.TryGetValue("env_properties", out object envProprties); + var envPropertiesMapping = envProprties as IDictionary; + foreach (var tag in activity.TagObjects) + { + if (CS40_PART_B_MAPPING.TryGetValue(tag.Key, out string replacementKey)) { - Assert.Equal(activity.ParentSpanId.ToHexString(), mapping["parentId"]); + Assert.Equal(tag.Value.ToString(), mapping[replacementKey].ToString()); } - - #region Assert Activity Links - if (activity.Links.Any()) + else if (string.Equals(tag.Key, "otel.status_code", StringComparison.Ordinal)) { - Assert.Contains(mapping, m => m.Key as string == "links"); - var mappingLinks = mapping["links"] as IEnumerable; - using IEnumerator activityLinksEnumerator = activity.Links.GetEnumerator(); - using IEnumerator mappingLinksEnumerator = mappingLinks.GetEnumerator(); - while (activityLinksEnumerator.MoveNext() && mappingLinksEnumerator.MoveNext()) - { - var activityLink = activityLinksEnumerator.Current; - var mappingLink = mappingLinksEnumerator.Current as Dictionary; - - Assert.Equal(activityLink.Context.TraceId.ToHexString(), mappingLink["toTraceId"]); - Assert.Equal(activityLink.Context.SpanId.ToHexString(), mappingLink["toSpanId"]); - } - - // Assert that mapping contains exactly the same number of ActivityLinks as present in the activity - // MoveNext() on both the enumerators should return false as we should have enumerated till the last element for both the Enumerables - Assert.Equal(activityLinksEnumerator.MoveNext(), mappingLinksEnumerator.MoveNext()); + // Status code check is already done when we check for "success" key in the mapping + continue; } - else + else if (string.Equals(tag.Key, "otel.status_description", StringComparison.Ordinal)) { - Assert.DoesNotContain(mapping, m => m.Key as string == "links"); + // Status description check is already done when we check for "statusMessage" key in the mapping + continue; } - #endregion - - #region Assert Activity Tags - _ = mapping.TryGetValue("env_properties", out object envProprties); - var envPropertiesMapping = envProprties as IDictionary; - foreach (var tag in activity.TagObjects) + else { - if (CS40_PART_B_MAPPING.TryGetValue(tag.Key, out string replacementKey)) + // If CustomFields are proivded, dedicatedFields will be populated + if (exporterOptions.CustomFields == null || dedicatedFields.ContainsKey(tag.Key)) { - Assert.Equal(tag.Value.ToString(), mapping[replacementKey].ToString()); - } - else if (string.Equals(tag.Key, "otel.status_code", StringComparison.Ordinal)) - { - // Status code check is already done when we check for "success" key in the mapping - continue; - } - else if (string.Equals(tag.Key, "otel.status_description", StringComparison.Ordinal)) - { - // Status description check is already done when we check for "statusMessage" key in the mapping - continue; + Assert.Equal(tag.Value.ToString(), mapping[tag.Key].ToString()); } else { - // If CustomFields are proivded, dedicatedFields will be populated - if (exporterOptions.CustomFields == null || dedicatedFields.ContainsKey(tag.Key)) - { - Assert.Equal(tag.Value.ToString(), mapping[tag.Key].ToString()); - } - else - { - Assert.Equal(tag.Value.ToString(), envPropertiesMapping[tag.Key].ToString()); - } + Assert.Equal(tag.Value.ToString(), envPropertiesMapping[tag.Key].ToString()); } } - #endregion + } + #endregion - // Epilouge - Assert.Equal("DateTime", timeFormat["TimeFormat"]); + // Epilouge + Assert.Equal("DateTime", timeFormat["TimeFormat"]); - customChecksForActivity?.Invoke(mapping); - } + customChecksForActivity?.Invoke(mapping); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index a4b8dfda30..bb6e9ba212 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -20,376 +20,375 @@ using Xunit; using Xunit.Sdk; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class MessagePackSerializerTests { - public class MessagePackSerializerTests + private void AssertBytes(byte[] expected, byte[] actual, int length) { - private void AssertBytes(byte[] expected, byte[] actual, int length) + Assert.Equal(expected.Length, length); + for (int i = 0; i < length; i++) { - Assert.Equal(expected.Length, length); - for (int i = 0; i < length; i++) - { - byte expectedByte = expected[i]; - byte actualByte = actual[i]; + byte expectedByte = expected[i]; + byte actualByte = actual[i]; - Assert.True( - expectedByte == actualByte, - string.Format($"Expected: '{(byte)expectedByte}', Actual: '{(byte)actualByte}' at offset {i}.")); - } + Assert.True( + expectedByte == actualByte, + string.Format($"Expected: '{(byte)expectedByte}', Actual: '{(byte)actualByte}' at offset {i}.")); } + } - private void MessagePackSerializer_TestSerialization(object obj) - { - var buffer = new byte[64 * 1024]; - var length = MessagePackSerializer.Serialize(buffer, 0, obj); - this.AssertBytes(MessagePack.MessagePackSerializer.Serialize(obj), buffer, length); - } + private void MessagePackSerializer_TestSerialization(object obj) + { + var buffer = new byte[64 * 1024]; + var length = MessagePackSerializer.Serialize(buffer, 0, obj); + this.AssertBytes(MessagePack.MessagePackSerializer.Serialize(obj), buffer, length); + } - private void MessagePackSerializer_TestASCIIStringSerialization(string input) + private void MessagePackSerializer_TestASCIIStringSerialization(string input) + { + var sizeLimit = (1 << 14) - 1; // // Max length of string allowed + var buffer = new byte[64 * 1024]; + var length = MessagePackSerializer.SerializeAsciiString(buffer, 0, input); + var deserializedString = MessagePack.MessagePackSerializer.Deserialize(buffer); + if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) { - var sizeLimit = (1 << 14) - 1; // // Max length of string allowed - var buffer = new byte[64 * 1024]; - var length = MessagePackSerializer.SerializeAsciiString(buffer, 0, input); - var deserializedString = MessagePack.MessagePackSerializer.Deserialize(buffer); - if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) - { - // We truncate the string using `.` in the last three characters which takes 3 bytes of memort - var byteCount = Encoding.ASCII.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; - Assert.Equal(0xDA, buffer[0]); - Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); - Assert.Equal(byteCount, length - 3); // First three bytes are metadata - - Assert.NotEqual(input, deserializedString); + // We truncate the string using `.` in the last three characters which takes 3 bytes of memort + var byteCount = Encoding.ASCII.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata - int i; - for (i = 0; i < sizeLimit - 3; i++) - { - Assert.Equal(input[i], deserializedString[i]); - } + Assert.NotEqual(input, deserializedString); - Assert.Equal('.', deserializedString[i++]); - Assert.Equal('.', deserializedString[i++]); - Assert.Equal('.', deserializedString[i++]); - } - else + int i; + for (i = 0; i < sizeLimit - 3; i++) { - if (input != null) - { - var byteCount = Encoding.ASCII.GetByteCount(input); - if (input.Length <= 31) - { - Assert.Equal(0xA0 | byteCount, buffer[0]); - Assert.Equal(byteCount, length - 1); // First one byte is metadata - } - else if (input.Length <= 255) - { - Assert.Equal(0xD9, buffer[0]); - Assert.Equal(byteCount, buffer[1]); - Assert.Equal(byteCount, length - 2); // First two bytes are metadata - } - else if (input.Length <= sizeLimit) - { - Assert.Equal(0xDA, buffer[0]); - Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); - Assert.Equal(byteCount, length - 3); // First three bytes are metadata - } - } - - Assert.Equal(input, deserializedString); + Assert.Equal(input[i], deserializedString[i]); } - } - private void MessagePackSerializer_TestUnicodeStringSerialization(string input) + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + } + else { - var sizeLimit = (1 << 14) - 1; // // Max length of string allowed - var buffer = new byte[64 * 1024]; - var length = MessagePackSerializer.SerializeUnicodeString(buffer, 0, input); - - var deserializedString = MessagePack.MessagePackSerializer.Deserialize(buffer); - if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) + if (input != null) { - // We truncate the string using `.` in the last three characters which takes 3 bytes of memory - var byteCount = Encoding.UTF8.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; - Assert.Equal(0xDA, buffer[0]); - Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); - Assert.Equal(byteCount, length - 3); // First three bytes are metadata - - Assert.NotEqual(input, deserializedString); - - int i; - for (i = 0; i < sizeLimit - 3; i++) + var byteCount = Encoding.ASCII.GetByteCount(input); + if (input.Length <= 31) { - Assert.Equal(input[i], deserializedString[i]); + Assert.Equal(0xA0 | byteCount, buffer[0]); + Assert.Equal(byteCount, length - 1); // First one byte is metadata } - - Assert.Equal('.', deserializedString[i++]); - Assert.Equal('.', deserializedString[i++]); - Assert.Equal('.', deserializedString[i++]); - } - else - { - Assert.Equal(input, deserializedString); - - if (input != null) + else if (input.Length <= 255) + { + Assert.Equal(0xD9, buffer[0]); + Assert.Equal(byteCount, buffer[1]); + Assert.Equal(byteCount, length - 2); // First two bytes are metadata + } + else if (input.Length <= sizeLimit) { - var byteCount = Encoding.UTF8.GetByteCount(input); Assert.Equal(0xDA, buffer[0]); Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); Assert.Equal(byteCount, length - 3); // First three bytes are metadata } } - } - [Fact] - public void MessagePackSerializer_Null() - { - this.MessagePackSerializer_TestSerialization(null); + Assert.Equal(input, deserializedString); } + } - [Fact] - public void MessagePackSerializer_Boolean() - { - this.MessagePackSerializer_TestSerialization(true); - this.MessagePackSerializer_TestSerialization(false); - } + private void MessagePackSerializer_TestUnicodeStringSerialization(string input) + { + var sizeLimit = (1 << 14) - 1; // // Max length of string allowed + var buffer = new byte[64 * 1024]; + var length = MessagePackSerializer.SerializeUnicodeString(buffer, 0, input); - [Fact] - public void MessagePackSerializer_Int() + var deserializedString = MessagePack.MessagePackSerializer.Deserialize(buffer); + if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) { - // 8 bits - for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) - { - this.MessagePackSerializer_TestSerialization(value); - } + // We truncate the string using `.` in the last three characters which takes 3 bytes of memory + var byteCount = Encoding.UTF8.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata - this.MessagePackSerializer_TestSerialization(sbyte.MaxValue); + Assert.NotEqual(input, deserializedString); - // 16 bits - for (short value = short.MinValue; value < short.MaxValue; value++) + int i; + for (i = 0; i < sizeLimit - 3; i++) { - this.MessagePackSerializer_TestSerialization(value); + Assert.Equal(input[i], deserializedString[i]); } - this.MessagePackSerializer_TestSerialization(short.MaxValue); + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + Assert.Equal('.', deserializedString[i++]); + } + else + { + Assert.Equal(input, deserializedString); - // 32 bits - this.MessagePackSerializer_TestSerialization(int.MinValue); - this.MessagePackSerializer_TestSerialization(int.MinValue + 1); - this.MessagePackSerializer_TestSerialization((int)short.MinValue - 1); - this.MessagePackSerializer_TestSerialization((int)short.MinValue); - this.MessagePackSerializer_TestSerialization((int)short.MinValue + 1); - this.MessagePackSerializer_TestSerialization((int)sbyte.MinValue - 1); - for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + if (input != null) { - this.MessagePackSerializer_TestSerialization((int)value); + var byteCount = Encoding.UTF8.GetByteCount(input); + Assert.Equal(0xDA, buffer[0]); + Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); + Assert.Equal(byteCount, length - 3); // First three bytes are metadata } + } + } - this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue); - this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((int)short.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((int)short.MaxValue); - this.MessagePackSerializer_TestSerialization((int)short.MaxValue + 1); - this.MessagePackSerializer_TestSerialization(int.MaxValue - 1); - this.MessagePackSerializer_TestSerialization(int.MaxValue); - - // 64 bits - this.MessagePackSerializer_TestSerialization(long.MinValue); - this.MessagePackSerializer_TestSerialization(long.MinValue + 1); - this.MessagePackSerializer_TestSerialization((long)int.MinValue - 1); - this.MessagePackSerializer_TestSerialization((long)int.MinValue); - this.MessagePackSerializer_TestSerialization((long)int.MinValue + 1); - this.MessagePackSerializer_TestSerialization((long)short.MinValue - 1); - this.MessagePackSerializer_TestSerialization((long)short.MinValue); - this.MessagePackSerializer_TestSerialization((long)short.MinValue + 1); - this.MessagePackSerializer_TestSerialization((long)sbyte.MinValue - 1); - for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) - { - this.MessagePackSerializer_TestSerialization((long)value); - } + [Fact] + public void MessagePackSerializer_Null() + { + this.MessagePackSerializer_TestSerialization(null); + } - this.MessagePackSerializer_TestSerialization((long)sbyte.MaxValue); - this.MessagePackSerializer_TestSerialization((long)sbyte.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((long)short.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((long)short.MaxValue); - this.MessagePackSerializer_TestSerialization((long)short.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((long)int.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((long)int.MaxValue); - this.MessagePackSerializer_TestSerialization((long)int.MaxValue + 1); - this.MessagePackSerializer_TestSerialization(long.MaxValue - 1); - this.MessagePackSerializer_TestSerialization(long.MaxValue); - } + [Fact] + public void MessagePackSerializer_Boolean() + { + this.MessagePackSerializer_TestSerialization(true); + this.MessagePackSerializer_TestSerialization(false); + } - [Fact] - public void MessagePackSerializer_UInt() + [Fact] + public void MessagePackSerializer_Int() + { + // 8 bits + for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) { - // 8 bits - for (byte value = byte.MinValue; value < byte.MaxValue; value++) - { - this.MessagePackSerializer_TestSerialization(value); - } - - this.MessagePackSerializer_TestSerialization(byte.MaxValue); + this.MessagePackSerializer_TestSerialization(value); + } - // 16 bits - for (ushort value = ushort.MinValue; value < ushort.MaxValue; value++) - { - this.MessagePackSerializer_TestSerialization(value); - } + this.MessagePackSerializer_TestSerialization(sbyte.MaxValue); - this.MessagePackSerializer_TestSerialization(ushort.MaxValue); - - // 32 bits - this.MessagePackSerializer_TestSerialization(uint.MinValue); - this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue); - this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue); - this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue + 1); - this.MessagePackSerializer_TestSerialization(uint.MaxValue - 1); - this.MessagePackSerializer_TestSerialization(uint.MaxValue); - - // 64 bits - this.MessagePackSerializer_TestSerialization(ulong.MinValue); - this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue); - this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue); - this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue - 1); - this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue); - this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue + 1); - this.MessagePackSerializer_TestSerialization(ulong.MaxValue - 1); - this.MessagePackSerializer_TestSerialization(ulong.MaxValue); + // 16 bits + for (short value = short.MinValue; value < short.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization(value); } - [Fact] - public void MessagePackSerializer_Float() + this.MessagePackSerializer_TestSerialization(short.MaxValue); + + // 32 bits + this.MessagePackSerializer_TestSerialization(int.MinValue); + this.MessagePackSerializer_TestSerialization(int.MinValue + 1); + this.MessagePackSerializer_TestSerialization((int)short.MinValue - 1); + this.MessagePackSerializer_TestSerialization((int)short.MinValue); + this.MessagePackSerializer_TestSerialization((int)short.MinValue + 1); + this.MessagePackSerializer_TestSerialization((int)sbyte.MinValue - 1); + for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) { - this.MessagePackSerializer_TestSerialization(0.0f); - this.MessagePackSerializer_TestSerialization(1.0f); - this.MessagePackSerializer_TestSerialization(-123.45f); - this.MessagePackSerializer_TestSerialization(float.MaxValue); - this.MessagePackSerializer_TestSerialization(float.MinValue); - this.MessagePackSerializer_TestSerialization(float.PositiveInfinity); - this.MessagePackSerializer_TestSerialization(float.NegativeInfinity); - - this.MessagePackSerializer_TestSerialization(0.0d); - this.MessagePackSerializer_TestSerialization(3.1415926d); - this.MessagePackSerializer_TestSerialization(-67.89f); - this.MessagePackSerializer_TestSerialization(double.MaxValue); - this.MessagePackSerializer_TestSerialization(double.MinValue); - this.MessagePackSerializer_TestSerialization(double.PositiveInfinity); - this.MessagePackSerializer_TestSerialization(double.NegativeInfinity); + this.MessagePackSerializer_TestSerialization((int)value); } - [Fact] - public void MessagePackSerializer_SerializeAsciiString() + this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue); + this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((int)short.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((int)short.MaxValue); + this.MessagePackSerializer_TestSerialization((int)short.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(int.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(int.MaxValue); + + // 64 bits + this.MessagePackSerializer_TestSerialization(long.MinValue); + this.MessagePackSerializer_TestSerialization(long.MinValue + 1); + this.MessagePackSerializer_TestSerialization((long)int.MinValue - 1); + this.MessagePackSerializer_TestSerialization((long)int.MinValue); + this.MessagePackSerializer_TestSerialization((long)int.MinValue + 1); + this.MessagePackSerializer_TestSerialization((long)short.MinValue - 1); + this.MessagePackSerializer_TestSerialization((long)short.MinValue); + this.MessagePackSerializer_TestSerialization((long)short.MinValue + 1); + this.MessagePackSerializer_TestSerialization((long)sbyte.MinValue - 1); + for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) { - this.MessagePackSerializer_TestASCIIStringSerialization(null); - this.MessagePackSerializer_TestASCIIStringSerialization(string.Empty); - this.MessagePackSerializer_TestASCIIStringSerialization("Hello world!"); - - // fixstr stores a byte array whose length is upto 31 bytes - this.MessagePackSerializer_TestASCIIStringSerialization("1234567890123456789012345678901"); - - // str 8 stores a byte array whose length is upto (2^8)-1 bytes - this.MessagePackSerializer_TestASCIIStringSerialization("12345678901234567890123456789012"); - this.MessagePackSerializer_TestASCIIStringSerialization(new string('A', byte.MaxValue)); - this.MessagePackSerializer_TestASCIIStringSerialization(new string('B', byte.MaxValue + 1)); - this.MessagePackSerializer_TestASCIIStringSerialization(new string('Z', (1 << 14) - 1)); - this.MessagePackSerializer_TestASCIIStringSerialization(new string('Z', 1 << 14)); - - // Unicode special characters - // SerializeAsciiString will encode non-ASCII characters with '?' - Assert.Throws(() => this.MessagePackSerializer_TestASCIIStringSerialization("\u0418")); + this.MessagePackSerializer_TestSerialization((long)value); } - [Fact] - public void MessagePackSerializer_SerializeUnicodeString() + this.MessagePackSerializer_TestSerialization((long)sbyte.MaxValue); + this.MessagePackSerializer_TestSerialization((long)sbyte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((long)short.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((long)short.MaxValue); + this.MessagePackSerializer_TestSerialization((long)short.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((long)int.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((long)int.MaxValue); + this.MessagePackSerializer_TestSerialization((long)int.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(long.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(long.MaxValue); + } + + [Fact] + public void MessagePackSerializer_UInt() + { + // 8 bits + for (byte value = byte.MinValue; value < byte.MaxValue; value++) { - this.MessagePackSerializer_TestUnicodeStringSerialization(null); - this.MessagePackSerializer_TestUnicodeStringSerialization(string.Empty); - this.MessagePackSerializer_TestUnicodeStringSerialization("Hello world!"); - - // fixstr stores a byte array whose length is upto 31 bytes - this.MessagePackSerializer_TestUnicodeStringSerialization("1234567890123456789012345678901"); - - // str 8 stores a byte array whose length is upto (2^8)-1 bytes - this.MessagePackSerializer_TestUnicodeStringSerialization("12345678901234567890123456789012"); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('A', byte.MaxValue)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('B', byte.MaxValue + 1)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('Z', (1 << 14) - 1)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('Z', 1 << 14)); - - // ill-formed UTF-8 sequence - // This is replaced by `U+FFFD REPLACEMENT CHARACTER` in the returned string instance constructed from the byte array - // TODO: Update this test case once the serializer starts to throw exception for ill-formed UTF-8 sequence. - Assert.Throws(() => this.MessagePackSerializer_TestUnicodeStringSerialization("\uD801\uD802")); - - // Unicode special characters - this.MessagePackSerializer_TestUnicodeStringSerialization("\u0418"); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 31)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 50)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', (1 << 8) - 1)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 1 << 10)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', (1 << 14) - 1)); - this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 1 << 14)); - - // Unicode regular and special characters - this.MessagePackSerializer_TestUnicodeStringSerialization("\u0418TestString"); - this.MessagePackSerializer_TestUnicodeStringSerialization("TestString\u0418"); - this.MessagePackSerializer_TestUnicodeStringSerialization("Test\u0418String"); + this.MessagePackSerializer_TestSerialization(value); } - [Fact] - public void MessagePackSerializer_Array() - { - this.MessagePackSerializer_TestSerialization((object[])null); - this.MessagePackSerializer_TestSerialization(new object[0]); + this.MessagePackSerializer_TestSerialization(byte.MaxValue); - // This object array has a custom string which will be serialized as STR16 - var objectArrayWithString = new object[] - { - "foo", - 1, - 0.6180340f, - 3.14159265358979323846264d, - }; - - var buffer = new byte[64 * 1024]; - _ = MessagePackSerializer.Serialize(buffer, 0, objectArrayWithString); - var objectArrayWithStringDeserialized = MessagePack.MessagePackSerializer.Deserialize(buffer); - Assert.Equal(objectArrayWithString.Length, objectArrayWithStringDeserialized.Length); - Assert.Equal(objectArrayWithString[0], objectArrayWithStringDeserialized[0]); - Assert.Equal(objectArrayWithString[1], Convert.ToInt32(objectArrayWithStringDeserialized[1])); - Assert.Equal(objectArrayWithString[2], objectArrayWithStringDeserialized[2]); - Assert.Equal(objectArrayWithString[3], objectArrayWithStringDeserialized[3]); + // 16 bits + for (ushort value = ushort.MinValue; value < ushort.MaxValue; value++) + { + this.MessagePackSerializer_TestSerialization(value); } - [Fact] - public void MessagePackSerializer_Map() + this.MessagePackSerializer_TestSerialization(ushort.MaxValue); + + // 32 bits + this.MessagePackSerializer_TestSerialization(uint.MinValue); + this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue); + this.MessagePackSerializer_TestSerialization((uint)byte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue); + this.MessagePackSerializer_TestSerialization((uint)ushort.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(uint.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(uint.MaxValue); + + // 64 bits + this.MessagePackSerializer_TestSerialization(ulong.MinValue); + this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue); + this.MessagePackSerializer_TestSerialization((ulong)byte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue); + this.MessagePackSerializer_TestSerialization((ulong)ushort.MaxValue + 1); + this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue - 1); + this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue); + this.MessagePackSerializer_TestSerialization((ulong)uint.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(ulong.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(ulong.MaxValue); + } + + [Fact] + public void MessagePackSerializer_Float() + { + this.MessagePackSerializer_TestSerialization(0.0f); + this.MessagePackSerializer_TestSerialization(1.0f); + this.MessagePackSerializer_TestSerialization(-123.45f); + this.MessagePackSerializer_TestSerialization(float.MaxValue); + this.MessagePackSerializer_TestSerialization(float.MinValue); + this.MessagePackSerializer_TestSerialization(float.PositiveInfinity); + this.MessagePackSerializer_TestSerialization(float.NegativeInfinity); + + this.MessagePackSerializer_TestSerialization(0.0d); + this.MessagePackSerializer_TestSerialization(3.1415926d); + this.MessagePackSerializer_TestSerialization(-67.89f); + this.MessagePackSerializer_TestSerialization(double.MaxValue); + this.MessagePackSerializer_TestSerialization(double.MinValue); + this.MessagePackSerializer_TestSerialization(double.PositiveInfinity); + this.MessagePackSerializer_TestSerialization(double.NegativeInfinity); + } + + [Fact] + public void MessagePackSerializer_SerializeAsciiString() + { + this.MessagePackSerializer_TestASCIIStringSerialization(null); + this.MessagePackSerializer_TestASCIIStringSerialization(string.Empty); + this.MessagePackSerializer_TestASCIIStringSerialization("Hello world!"); + + // fixstr stores a byte array whose length is upto 31 bytes + this.MessagePackSerializer_TestASCIIStringSerialization("1234567890123456789012345678901"); + + // str 8 stores a byte array whose length is upto (2^8)-1 bytes + this.MessagePackSerializer_TestASCIIStringSerialization("12345678901234567890123456789012"); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('A', byte.MaxValue)); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('B', byte.MaxValue + 1)); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('Z', (1 << 14) - 1)); + this.MessagePackSerializer_TestASCIIStringSerialization(new string('Z', 1 << 14)); + + // Unicode special characters + // SerializeAsciiString will encode non-ASCII characters with '?' + Assert.Throws(() => this.MessagePackSerializer_TestASCIIStringSerialization("\u0418")); + } + + [Fact] + public void MessagePackSerializer_SerializeUnicodeString() + { + this.MessagePackSerializer_TestUnicodeStringSerialization(null); + this.MessagePackSerializer_TestUnicodeStringSerialization(string.Empty); + this.MessagePackSerializer_TestUnicodeStringSerialization("Hello world!"); + + // fixstr stores a byte array whose length is upto 31 bytes + this.MessagePackSerializer_TestUnicodeStringSerialization("1234567890123456789012345678901"); + + // str 8 stores a byte array whose length is upto (2^8)-1 bytes + this.MessagePackSerializer_TestUnicodeStringSerialization("12345678901234567890123456789012"); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('A', byte.MaxValue)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('B', byte.MaxValue + 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('Z', (1 << 14) - 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('Z', 1 << 14)); + + // ill-formed UTF-8 sequence + // This is replaced by `U+FFFD REPLACEMENT CHARACTER` in the returned string instance constructed from the byte array + // TODO: Update this test case once the serializer starts to throw exception for ill-formed UTF-8 sequence. + Assert.Throws(() => this.MessagePackSerializer_TestUnicodeStringSerialization("\uD801\uD802")); + + // Unicode special characters + this.MessagePackSerializer_TestUnicodeStringSerialization("\u0418"); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 31)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 50)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', (1 << 8) - 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 1 << 10)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', (1 << 14) - 1)); + this.MessagePackSerializer_TestUnicodeStringSerialization(new string('\u0418', 1 << 14)); + + // Unicode regular and special characters + this.MessagePackSerializer_TestUnicodeStringSerialization("\u0418TestString"); + this.MessagePackSerializer_TestUnicodeStringSerialization("TestString\u0418"); + this.MessagePackSerializer_TestUnicodeStringSerialization("Test\u0418String"); + } + + [Fact] + public void MessagePackSerializer_Array() + { + this.MessagePackSerializer_TestSerialization((object[])null); + this.MessagePackSerializer_TestSerialization(new object[0]); + + // This object array has a custom string which will be serialized as STR16 + var objectArrayWithString = new object[] { - this.MessagePackSerializer_TestSerialization((Dictionary)null); - this.MessagePackSerializer_TestSerialization(new Dictionary()); + "foo", + 1, + 0.6180340f, + 3.14159265358979323846264d, + }; + + var buffer = new byte[64 * 1024]; + _ = MessagePackSerializer.Serialize(buffer, 0, objectArrayWithString); + var objectArrayWithStringDeserialized = MessagePack.MessagePackSerializer.Deserialize(buffer); + Assert.Equal(objectArrayWithString.Length, objectArrayWithStringDeserialized.Length); + Assert.Equal(objectArrayWithString[0], objectArrayWithStringDeserialized[0]); + Assert.Equal(objectArrayWithString[1], Convert.ToInt32(objectArrayWithStringDeserialized[1])); + Assert.Equal(objectArrayWithString[2], objectArrayWithStringDeserialized[2]); + Assert.Equal(objectArrayWithString[3], objectArrayWithStringDeserialized[3]); + } - // This dictionary has custom strings which will be serialized as STR16 - var dictionaryWithStrings = new Dictionary - { - ["foo"] = 1, - ["bar"] = "baz", - ["golden ratio"] = 0.6180340f, - ["pi"] = 3.14159265358979323846264d, - }; - var buffer = new byte[64 * 1024]; - _ = MessagePackSerializer.Serialize(buffer, 0, dictionaryWithStrings); - var dictionaryWithStringsDeserialized = MessagePack.MessagePackSerializer.Deserialize>(buffer); - Assert.Equal(dictionaryWithStrings.Count, dictionaryWithStringsDeserialized.Count); - Assert.Equal(dictionaryWithStrings["foo"], Convert.ToInt32(dictionaryWithStringsDeserialized["foo"])); - Assert.Equal(dictionaryWithStrings["bar"], dictionaryWithStringsDeserialized["bar"]); - Assert.Equal(dictionaryWithStrings["golden ratio"], dictionaryWithStringsDeserialized["golden ratio"]); - Assert.Equal(dictionaryWithStrings["pi"], dictionaryWithStringsDeserialized["pi"]); - } + [Fact] + public void MessagePackSerializer_Map() + { + this.MessagePackSerializer_TestSerialization((Dictionary)null); + this.MessagePackSerializer_TestSerialization(new Dictionary()); + + // This dictionary has custom strings which will be serialized as STR16 + var dictionaryWithStrings = new Dictionary + { + ["foo"] = 1, + ["bar"] = "baz", + ["golden ratio"] = 0.6180340f, + ["pi"] = 3.14159265358979323846264d, + }; + var buffer = new byte[64 * 1024]; + _ = MessagePackSerializer.Serialize(buffer, 0, dictionaryWithStrings); + var dictionaryWithStringsDeserialized = MessagePack.MessagePackSerializer.Deserialize>(buffer); + Assert.Equal(dictionaryWithStrings.Count, dictionaryWithStringsDeserialized.Count); + Assert.Equal(dictionaryWithStrings["foo"], Convert.ToInt32(dictionaryWithStringsDeserialized["foo"])); + Assert.Equal(dictionaryWithStrings["bar"], dictionaryWithStringsDeserialized["bar"]); + Assert.Equal(dictionaryWithStrings["golden ratio"], dictionaryWithStringsDeserialized["golden ratio"]); + Assert.Equal(dictionaryWithStrings["pi"], dictionaryWithStringsDeserialized["pi"]); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs index c03dda9252..d14dcbf93f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs @@ -1,665 +1,664 @@ -// +// using System.Collections.Generic; using Kaitai; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public partial class MetricsContract : KaitaiStruct { - public partial class MetricsContract : KaitaiStruct + public static MetricsContract FromFile(string fileName) { - public static MetricsContract FromFile(string fileName) - { - return new MetricsContract(new KaitaiStream(fileName)); - } + return new MetricsContract(new KaitaiStream(fileName)); + } - public enum MetricEventType - { - Old = 0, - Uint64Metric = 50, - DoubleScaledToLongMetric = 51, - BatchMetric = 52, - ExternallyAggregatedUlongMetric = 53, - ExternallyAggregatedDoubleMetric = 54, - DoubleMetric = 55, - ExternallyAggregatedUlongDistributionMetric = 56, - ExternallyAggregatedDoubleDistributionMetric = 57, - ExternallyAggregatedDoubleScaledToLongDistributionMetric = 58, - } + public enum MetricEventType + { + Old = 0, + Uint64Metric = 50, + DoubleScaledToLongMetric = 51, + BatchMetric = 52, + ExternallyAggregatedUlongMetric = 53, + ExternallyAggregatedDoubleMetric = 54, + DoubleMetric = 55, + ExternallyAggregatedUlongDistributionMetric = 56, + ExternallyAggregatedDoubleDistributionMetric = 57, + ExternallyAggregatedDoubleScaledToLongDistributionMetric = 58, + } - public enum DistributionType - { - Bucketed = 0, - MonBucketed = 1, - ValueCountPairs = 2, - } - public MetricsContract(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) + public enum DistributionType + { + Bucketed = 0, + MonBucketed = 1, + ValueCountPairs = 2, + } + public MetricsContract(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root ?? this; + this._read(); + } + private void _read() + { + this._eventId = this.m_io.ReadU2le(); + this._lenBody = this.m_io.ReadU2le(); + this.__raw_body = this.m_io.ReadBytes(this.LenBody); + var io___raw_body = new KaitaiStream(this.__raw_body); + this._body = new Userdata(this.EventId, io___raw_body, this, this.m_root); + } + + /// + /// This type represents "UserData" or "body" portion of Metrics message. + /// + public partial class Userdata : KaitaiStruct + { + public Userdata(ushort p_eventId, KaitaiStream p__io, MetricsContract p__parent = null, MetricsContract p__root = null) : base(p__io) { this.m_parent = p__parent; - this.m_root = p__root ?? this; + this.m_root = p__root; + this._eventId = p_eventId; + this.f_eventType = false; this._read(); } private void _read() { - this._eventId = this.m_io.ReadU2le(); - this._lenBody = this.m_io.ReadU2le(); - this.__raw_body = this.m_io.ReadBytes(this.LenBody); - var io___raw_body = new KaitaiStream(this.__raw_body); - this._body = new Userdata(this.EventId, io___raw_body, this, this.m_root); - } - - /// - /// This type represents "UserData" or "body" portion of Metrics message. - /// - public partial class Userdata : KaitaiStruct - { - public Userdata(ushort p_eventId, KaitaiStream p__io, MetricsContract p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._eventId = p_eventId; - this.f_eventType = false; - this._read(); - } - private void _read() + this._numDimensions = this.m_io.ReadU2le(); + this._padding = this.m_io.ReadBytes(2); + switch (this.EventType) { - this._numDimensions = this.m_io.ReadU2le(); - this._padding = this.m_io.ReadBytes(2); - switch (this.EventType) + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric: { - case MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric: - { - this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.DoubleMetric: - { - this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedUlongMetric: - { - this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric: - { - this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric: - { - this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.DoubleScaledToLongMetric: - { - this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.Uint64Metric: - { - this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedDoubleMetric: - { - this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.Old: - { - this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); - break; - } + this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); + break; } - this._metricAccount = new LenString(this.m_io, this, this.m_root); - this._metricNamespace = new LenString(this.m_io, this, this.m_root); - this._metricName = new LenString(this.m_io, this, this.m_root); - this._dimensionsNames = new List((int)this.NumDimensions); - for (var i = 0; i < this.NumDimensions; i++) + case MetricsContract.MetricEventType.DoubleMetric: { - this._dimensionsNames.Add(new LenString(this.m_io, this, this.m_root)); + this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); + break; } - this._dimensionsValues = new List((int)this.NumDimensions); - for (var i = 0; i < this.NumDimensions; i++) + case MetricsContract.MetricEventType.ExternallyAggregatedUlongMetric: { - this._dimensionsValues.Add(new LenString(this.m_io, this, this.m_root)); + this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); + break; } - if (!this.M_Io.IsEof) + case MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric: { - this._apContainer = new LenString(this.m_io, this, this.m_root); + this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); + break; } - if (((this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric)) && (!this.M_Io.IsEof)) + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric: { - this._histogram = new Histogram(this.m_io, this, this.m_root); + this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); + break; } - } - private bool f_eventType; - private MetricEventType _eventType; - public MetricEventType EventType - { - get + case MetricsContract.MetricEventType.DoubleScaledToLongMetric: { - if (this.f_eventType) - return this._eventType; - this._eventType = (MetricEventType)(MetricsContract.MetricEventType)this.EventId; - this.f_eventType = true; - return this._eventType; + this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.Uint64Metric: + { + this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleMetric: + { + this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); + break; + } + case MetricsContract.MetricEventType.Old: + { + this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); + break; } } - private ushort _numDimensions; - private byte[] _padding; - private KaitaiStruct _valueSection; - private LenString _metricAccount; - private LenString _metricNamespace; - private LenString _metricName; - private List _dimensionsNames; - private List _dimensionsValues; - private LenString _apContainer; - private Histogram _histogram; - private ushort _eventId; - private MetricsContract m_root; - private MetricsContract m_parent; - - /// - /// Number of dimensions specified in this event. - /// - public ushort NumDimensions { get { return this._numDimensions; } } - public byte[] Padding { get { return this._padding; } } - - /// - /// Value section of the body, stores fixed numeric metric value(s), as per event type. - /// - public KaitaiStruct ValueSection { get { return this._valueSection; } } - - /// - /// Geneva Metrics account name to be used for this metric. - /// - public LenString MetricAccount { get { return this._metricAccount; } } - - /// - /// Geneva Metrics namespace name to be used for this metric. - /// - public LenString MetricNamespace { get { return this._metricNamespace; } } - - /// - /// Geneva Metrics metric name to be used. - /// - public LenString MetricName { get { return this._metricName; } } - - /// - /// Dimension names strings ("key" parts of key-value pairs). Must be sorted, - /// unless MetricsExtenion's option `enableDimensionSortingOnIngestion` is - /// enabled. - /// - public List DimensionsNames { get { return this._dimensionsNames; } } - - /// - /// Dimension values strings ("value" parts of key-value pairs). - /// - public List DimensionsValues { get { return this._dimensionsValues; } } - - /// - /// AutoPilot container string, required for correct AP PKI certificate loading - /// in AutoPilot containers environment. - /// - public LenString ApContainer { get { return this._apContainer; } } - public Histogram Histogram { get { return this._histogram; } } - - /// - /// Type of message, affects format of the body. - /// - public ushort EventId { get { return this._eventId; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract M_Parent { get { return this.m_parent; } } - } - - /// - /// Bucket with an explicitly-defined value coordinate `value`, claiming to - /// hold `count` hits. Normally used to represent non-linear (e.g. exponential) - /// histograms payloads. - /// - public partial class PairValueCount : KaitaiStruct - { - public static PairValueCount FromFile(string fileName) + this._metricAccount = new LenString(this.m_io, this, this.m_root); + this._metricNamespace = new LenString(this.m_io, this, this.m_root); + this._metricName = new LenString(this.m_io, this, this.m_root); + this._dimensionsNames = new List((int)this.NumDimensions); + for (var i = 0; i < this.NumDimensions; i++) { - return new PairValueCount(new KaitaiStream(fileName)); + this._dimensionsNames.Add(new LenString(this.m_io, this, this.m_root)); } - - public PairValueCount(KaitaiStream p__io, MetricsContract.HistogramValueCountPairs p__parent = null, MetricsContract p__root = null) - : base(p__io) + this._dimensionsValues = new List((int)this.NumDimensions); + for (var i = 0; i < this.NumDimensions; i++) + { + this._dimensionsValues.Add(new LenString(this.m_io, this, this.m_root)); + } + if (!this.M_Io.IsEof) + { + this._apContainer = new LenString(this.m_io, this, this.m_root); + } + if (((this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric)) && (!this.M_Io.IsEof)) { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); + this._histogram = new Histogram(this.m_io, this, this.m_root); } - private void _read() + } + private bool f_eventType; + private MetricEventType _eventType; + public MetricEventType EventType + { + get { - this._value = this.m_io.ReadU8le(); - this._count = this.m_io.ReadU4le(); + if (this.f_eventType) + return this._eventType; + this._eventType = (MetricEventType)(MetricsContract.MetricEventType)this.EventId; + this.f_eventType = true; + return this._eventType; } - private ulong _value; - private uint _count; - private MetricsContract m_root; - private MetricsContract.HistogramValueCountPairs m_parent; - public ulong Value { get { return this._value; } } - public uint Count { get { return this._count; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.HistogramValueCountPairs M_Parent { get { return this.m_parent; } } } + private ushort _numDimensions; + private byte[] _padding; + private KaitaiStruct _valueSection; + private LenString _metricAccount; + private LenString _metricNamespace; + private LenString _metricName; + private List _dimensionsNames; + private List _dimensionsValues; + private LenString _apContainer; + private Histogram _histogram; + private ushort _eventId; + private MetricsContract m_root; + private MetricsContract m_parent; /// - /// Payload of a histogram with linear distribution of buckets. Such histogram - /// is defined by the parameters specified in `min`, `bucket_size` and - /// `bucket_count`. It is modelled as a series of buckets. First (index 0) and - /// last (indexed `bucket_count - 1`) buckets are special and are supposed to - /// catch all "underflow" and "overflow" values. Buckets with indexes 1 up to - /// `bucket_count - 2` are regular buckets of size `bucket_size`. + /// Number of dimensions specified in this event. /// - public partial class HistogramUint16Bucketed : KaitaiStruct + public ushort NumDimensions { get { return this._numDimensions; } } + public byte[] Padding { get { return this._padding; } } + + /// + /// Value section of the body, stores fixed numeric metric value(s), as per event type. + /// + public KaitaiStruct ValueSection { get { return this._valueSection; } } + + /// + /// Geneva Metrics account name to be used for this metric. + /// + public LenString MetricAccount { get { return this._metricAccount; } } + + /// + /// Geneva Metrics namespace name to be used for this metric. + /// + public LenString MetricNamespace { get { return this._metricNamespace; } } + + /// + /// Geneva Metrics metric name to be used. + /// + public LenString MetricName { get { return this._metricName; } } + + /// + /// Dimension names strings ("key" parts of key-value pairs). Must be sorted, + /// unless MetricsExtenion's option `enableDimensionSortingOnIngestion` is + /// enabled. + /// + public List DimensionsNames { get { return this._dimensionsNames; } } + + /// + /// Dimension values strings ("value" parts of key-value pairs). + /// + public List DimensionsValues { get { return this._dimensionsValues; } } + + /// + /// AutoPilot container string, required for correct AP PKI certificate loading + /// in AutoPilot containers environment. + /// + public LenString ApContainer { get { return this._apContainer; } } + public Histogram Histogram { get { return this._histogram; } } + + /// + /// Type of message, affects format of the body. + /// + public ushort EventId { get { return this._eventId; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract M_Parent { get { return this.m_parent; } } + } + + /// + /// Bucket with an explicitly-defined value coordinate `value`, claiming to + /// hold `count` hits. Normally used to represent non-linear (e.g. exponential) + /// histograms payloads. + /// + public partial class PairValueCount : KaitaiStruct + { + public static PairValueCount FromFile(string fileName) + { + return new PairValueCount(new KaitaiStream(fileName)); + } + + public PairValueCount(KaitaiStream p__io, MetricsContract.HistogramValueCountPairs p__parent = null, MetricsContract p__root = null) + : base(p__io) { - public static HistogramUint16Bucketed FromFile(string fileName) + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._value = this.m_io.ReadU8le(); + this._count = this.m_io.ReadU4le(); + } + private ulong _value; + private uint _count; + private MetricsContract m_root; + private MetricsContract.HistogramValueCountPairs m_parent; + public ulong Value { get { return this._value; } } + public uint Count { get { return this._count; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.HistogramValueCountPairs M_Parent { get { return this.m_parent; } } + } + + /// + /// Payload of a histogram with linear distribution of buckets. Such histogram + /// is defined by the parameters specified in `min`, `bucket_size` and + /// `bucket_count`. It is modelled as a series of buckets. First (index 0) and + /// last (indexed `bucket_count - 1`) buckets are special and are supposed to + /// catch all "underflow" and "overflow" values. Buckets with indexes 1 up to + /// `bucket_count - 2` are regular buckets of size `bucket_size`. + /// + public partial class HistogramUint16Bucketed : KaitaiStruct + { + public static HistogramUint16Bucketed FromFile(string fileName) + { + return new HistogramUint16Bucketed(new KaitaiStream(fileName)); + } + + public HistogramUint16Bucketed(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._min = this.m_io.ReadU8le(); + this._bucketSize = this.m_io.ReadU4le(); + this._bucketCount = this.m_io.ReadU4le(); + this._distributionSize = this.m_io.ReadU2le(); + this._columns = new List((int)this.DistributionSize); + for (var i = 0; i < this.DistributionSize; i++) { - return new HistogramUint16Bucketed(new KaitaiStream(fileName)); + this._columns.Add(new PairUint16(this.m_io, this, this.m_root)); } + } + private ulong _min; + private uint _bucketSize; + private uint _bucketCount; + private ushort _distributionSize; + private List _columns; + private MetricsContract m_root; + private MetricsContract.Histogram m_parent; + public ulong Min { get { return this._min; } } + public uint BucketSize { get { return this._bucketSize; } } + public uint BucketCount { get { return this._bucketCount; } } + public ushort DistributionSize { get { return this._distributionSize; } } + public List Columns { get { return this._columns; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } + } + public partial class HistogramValueCountPairs : KaitaiStruct + { + public static HistogramValueCountPairs FromFile(string fileName) + { + return new HistogramValueCountPairs(new KaitaiStream(fileName)); + } - public HistogramUint16Bucketed(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) - : base(p__io) + public HistogramValueCountPairs(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._distributionSize = this.m_io.ReadU2le(); + this._columns = new List((int)this.DistributionSize); + for (var i = 0; i < this.DistributionSize; i++) { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); + this._columns.Add(new PairValueCount(this.m_io, this, this.m_root)); } - private void _read() + } + private ushort _distributionSize; + private List _columns; + private MetricsContract m_root; + private MetricsContract.Histogram m_parent; + public ushort DistributionSize { get { return this._distributionSize; } } + public List Columns { get { return this._columns; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } + } + public partial class Histogram : KaitaiStruct + { + public static Histogram FromFile(string fileName) + { + return new Histogram(new KaitaiStream(fileName)); + } + + public Histogram(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._version = this.m_io.ReadU1(); + this._type = (MetricsContract.DistributionType)this.m_io.ReadU1(); + switch (this.Type) { - this._min = this.m_io.ReadU8le(); - this._bucketSize = this.m_io.ReadU4le(); - this._bucketCount = this.m_io.ReadU4le(); - this._distributionSize = this.m_io.ReadU2le(); - this._columns = new List((int)this.DistributionSize); - for (var i = 0; i < this.DistributionSize; i++) + case MetricsContract.DistributionType.Bucketed: { - this._columns.Add(new PairUint16(this.m_io, this, this.m_root)); + this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); + break; } - } - private ulong _min; - private uint _bucketSize; - private uint _bucketCount; - private ushort _distributionSize; - private List _columns; - private MetricsContract m_root; - private MetricsContract.Histogram m_parent; - public ulong Min { get { return this._min; } } - public uint BucketSize { get { return this._bucketSize; } } - public uint BucketCount { get { return this._bucketCount; } } - public ushort DistributionSize { get { return this._distributionSize; } } - public List Columns { get { return this._columns; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } - } - public partial class HistogramValueCountPairs : KaitaiStruct - { - public static HistogramValueCountPairs FromFile(string fileName) - { - return new HistogramValueCountPairs(new KaitaiStream(fileName)); - } - - public HistogramValueCountPairs(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._distributionSize = this.m_io.ReadU2le(); - this._columns = new List((int)this.DistributionSize); - for (var i = 0; i < this.DistributionSize; i++) + case MetricsContract.DistributionType.MonBucketed: { - this._columns.Add(new PairValueCount(this.m_io, this, this.m_root)); + this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); + break; } - } - private ushort _distributionSize; - private List _columns; - private MetricsContract m_root; - private MetricsContract.Histogram m_parent; - public ushort DistributionSize { get { return this._distributionSize; } } - public List Columns { get { return this._columns; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } - } - public partial class Histogram : KaitaiStruct - { - public static Histogram FromFile(string fileName) - { - return new Histogram(new KaitaiStream(fileName)); - } - - public Histogram(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._version = this.m_io.ReadU1(); - this._type = (MetricsContract.DistributionType)this.m_io.ReadU1(); - switch (this.Type) + case MetricsContract.DistributionType.ValueCountPairs: { - case MetricsContract.DistributionType.Bucketed: - { - this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); - break; - } - case MetricsContract.DistributionType.MonBucketed: - { - this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); - break; - } - case MetricsContract.DistributionType.ValueCountPairs: - { - this._body = new HistogramValueCountPairs(this.m_io, this, this.m_root); - break; - } + this._body = new HistogramValueCountPairs(this.m_io, this, this.m_root); + break; } } - private byte _version; - private DistributionType _type; - private KaitaiStruct _body; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public byte Version { get { return this._version; } } - public DistributionType Type { get { return this._type; } } - public KaitaiStruct Body { get { return this._body; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + private byte _version; + private DistributionType _type; + private KaitaiStruct _body; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte Version { get { return this._version; } } + public DistributionType Type { get { return this._type; } } + public KaitaiStruct Body { get { return this._body; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + + /// + /// Bucket #index, claiming to hold exactly `count` hits. See notes in + /// `histogram_uint16_bucketed` for interpreting index. + /// + public partial class PairUint16 : KaitaiStruct + { + public static PairUint16 FromFile(string fileName) + { + return new PairUint16(new KaitaiStream(fileName)); } + public PairUint16(KaitaiStream p__io, MetricsContract.HistogramUint16Bucketed p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._index = this.m_io.ReadU2le(); + this._count = this.m_io.ReadU2le(); + } + private ushort _index; + private ushort _count; + private MetricsContract m_root; + private MetricsContract.HistogramUint16Bucketed m_parent; + public ushort Index { get { return this._index; } } + public ushort Count { get { return this._count; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.HistogramUint16Bucketed M_Parent { get { return this.m_parent; } } + } + public partial class SingleUint64Value : KaitaiStruct + { + public static SingleUint64Value FromFile(string fileName) + { + return new SingleUint64Value(new KaitaiStream(fileName)); + } + + public SingleUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._padding = this.m_io.ReadBytes(4); + this._timestamp = this.m_io.ReadU8le(); + this._value = this.m_io.ReadU8le(); + } + private byte[] _padding; + private ulong _timestamp; + private ulong _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte[] Padding { get { return this._padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + /// - /// Bucket #index, claiming to hold exactly `count` hits. See notes in - /// `histogram_uint16_bucketed` for interpreting index. + /// Metric value as 64-bit unsigned integer. /// - public partial class PairUint16 : KaitaiStruct + public ulong Value { get { return this._value; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + public partial class ExtAggregatedDoubleValue : KaitaiStruct + { + public static ExtAggregatedDoubleValue FromFile(string fileName) { - public static PairUint16 FromFile(string fileName) - { - return new PairUint16(new KaitaiStream(fileName)); - } + return new ExtAggregatedDoubleValue(new KaitaiStream(fileName)); + } - public PairUint16(KaitaiStream p__io, MetricsContract.HistogramUint16Bucketed p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._index = this.m_io.ReadU2le(); - this._count = this.m_io.ReadU2le(); - } - private ushort _index; - private ushort _count; - private MetricsContract m_root; - private MetricsContract.HistogramUint16Bucketed m_parent; - public ushort Index { get { return this._index; } } - public ushort Count { get { return this._count; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.HistogramUint16Bucketed M_Parent { get { return this.m_parent; } } - } - public partial class SingleUint64Value : KaitaiStruct - { - public static SingleUint64Value FromFile(string fileName) - { - return new SingleUint64Value(new KaitaiStream(fileName)); - } + public ExtAggregatedDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._count = this.m_io.ReadU4le(); + this._timestamp = this.m_io.ReadU8le(); + this._sum = this.m_io.ReadF8le(); + this._min = this.m_io.ReadF8le(); + this._max = this.m_io.ReadF8le(); + } + private uint _count; + private ulong _timestamp; + private double _sum; + private double _min; + private double _max; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; - public SingleUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._padding = this.m_io.ReadBytes(4); - this._timestamp = this.m_io.ReadU8le(); - this._value = this.m_io.ReadU8le(); - } - private byte[] _padding; - private ulong _timestamp; - private ulong _value; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public byte[] Padding { get { return this._padding; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Metric value as 64-bit unsigned integer. - /// - public ulong Value { get { return this._value; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - public partial class ExtAggregatedDoubleValue : KaitaiStruct - { - public static ExtAggregatedDoubleValue FromFile(string fileName) - { - return new ExtAggregatedDoubleValue(new KaitaiStream(fileName)); - } + /// + /// Count of events aggregated in this event. + /// + public uint Count { get { return this._count; } } - public ExtAggregatedDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._count = this.m_io.ReadU4le(); - this._timestamp = this.m_io.ReadU8le(); - this._sum = this.m_io.ReadF8le(); - this._min = this.m_io.ReadF8le(); - this._max = this.m_io.ReadF8le(); - } - private uint _count; - private ulong _timestamp; - private double _sum; - private double _min; - private double _max; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - - /// - /// Count of events aggregated in this event. - /// - public uint Count { get { return this._count; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Sum of all metric values aggregated in this event. - /// - public double Sum { get { return this._sum; } } - - /// - /// Minimum of all metric values aggregated in this event. - /// - public double Min { get { return this._min; } } - - /// - /// Maximum of all metric values aggregated in this event. - /// - public double Max { get { return this._max; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - public partial class ExtAggregatedUint64Value : KaitaiStruct - { - public static ExtAggregatedUint64Value FromFile(string fileName) - { - return new ExtAggregatedUint64Value(new KaitaiStream(fileName)); - } + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } - public ExtAggregatedUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._count = this.m_io.ReadU4le(); - this._timestamp = this.m_io.ReadU8le(); - this._sum = this.m_io.ReadU8le(); - this._min = this.m_io.ReadU8le(); - this._max = this.m_io.ReadU8le(); - } - private uint _count; - private ulong _timestamp; - private ulong _sum; - private ulong _min; - private ulong _max; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - - /// - /// Count of events aggregated in this event. - /// - public uint Count { get { return this._count; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Sum of all metric values aggregated in this event. - /// - public ulong Sum { get { return this._sum; } } - - /// - /// Minimum of all metric values aggregated in this event. - /// - public ulong Min { get { return this._min; } } - - /// - /// Maximum of all metric values aggregated in this event. - /// - public ulong Max { get { return this._max; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - public partial class SingleDoubleValue : KaitaiStruct - { - public static SingleDoubleValue FromFile(string fileName) - { - return new SingleDoubleValue(new KaitaiStream(fileName)); - } + /// + /// Sum of all metric values aggregated in this event. + /// + public double Sum { get { return this._sum; } } - public SingleDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._padding = this.m_io.ReadBytes(4); - this._timestamp = this.m_io.ReadU8le(); - this._value = this.m_io.ReadF8le(); - } - private byte[] _padding; - private ulong _timestamp; - private double _value; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public byte[] Padding { get { return this._padding; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Metric value as double. - /// - public double Value { get { return this._value; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } + /// + /// Minimum of all metric values aggregated in this event. + /// + public double Min { get { return this._min; } } /// - /// A simple string, length-prefixed with a 2-byte integer. + /// Maximum of all metric values aggregated in this event. /// - public partial class LenString : KaitaiStruct + public double Max { get { return this._max; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + public partial class ExtAggregatedUint64Value : KaitaiStruct + { + public static ExtAggregatedUint64Value FromFile(string fileName) { - public static LenString FromFile(string fileName) - { - return new LenString(new KaitaiStream(fileName)); - } + return new ExtAggregatedUint64Value(new KaitaiStream(fileName)); + } - public LenString(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._lenValue = this.m_io.ReadU2le(); - this._value = System.Text.Encoding.GetEncoding("UTF-8").GetString(this.m_io.ReadBytes(this.LenValue)); - } - private ushort _lenValue; - private string _value; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public ushort LenValue { get { return this._lenValue; } } - public string Value { get { return this._value; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + public ExtAggregatedUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); } - private ushort _eventId; - private ushort _lenBody; - private Userdata _body; + private void _read() + { + this._count = this.m_io.ReadU4le(); + this._timestamp = this.m_io.ReadU8le(); + this._sum = this.m_io.ReadU8le(); + this._min = this.m_io.ReadU8le(); + this._max = this.m_io.ReadU8le(); + } + private uint _count; + private ulong _timestamp; + private ulong _sum; + private ulong _min; + private ulong _max; private MetricsContract m_root; - private KaitaiStruct m_parent; - private byte[] __raw_body; + private MetricsContract.Userdata m_parent; /// - /// Type of message, affects format of the body. + /// Count of events aggregated in this event. /// - public ushort EventId { get { return this._eventId; } } + public uint Count { get { return this._count; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public ulong Sum { get { return this._sum; } } /// - /// Size of body in bytes. + /// Minimum of all metric values aggregated in this event. /// - public ushort LenBody { get { return this._lenBody; } } + public ulong Min { get { return this._min; } } /// - /// Body of Metrics binary protocol message. + /// Maximum of all metric values aggregated in this event. /// - public Userdata Body { get { return this._body; } } + public ulong Max { get { return this._max; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + public partial class SingleDoubleValue : KaitaiStruct + { + public static SingleDoubleValue FromFile(string fileName) + { + return new SingleDoubleValue(new KaitaiStream(fileName)); + } + + public SingleDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._padding = this.m_io.ReadBytes(4); + this._timestamp = this.m_io.ReadU8le(); + this._value = this.m_io.ReadF8le(); + } + private byte[] _padding; + private ulong _timestamp; + private double _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte[] Padding { get { return this._padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return this._timestamp; } } + + /// + /// Metric value as double. + /// + public double Value { get { return this._value; } } + public MetricsContract M_Root { get { return this.m_root; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } + } + + /// + /// A simple string, length-prefixed with a 2-byte integer. + /// + public partial class LenString : KaitaiStruct + { + public static LenString FromFile(string fileName) + { + return new LenString(new KaitaiStream(fileName)); + } + + public LenString(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) + : base(p__io) + { + this.m_parent = p__parent; + this.m_root = p__root; + this._read(); + } + private void _read() + { + this._lenValue = this.m_io.ReadU2le(); + this._value = System.Text.Encoding.GetEncoding("UTF-8").GetString(this.m_io.ReadBytes(this.LenValue)); + } + private ushort _lenValue; + private string _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public ushort LenValue { get { return this._lenValue; } } + public string Value { get { return this._value; } } public MetricsContract M_Root { get { return this.m_root; } } - public KaitaiStruct M_Parent { get { return this.m_parent; } } - public byte[] M_RawBody { get { return this.__raw_body; } } + public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } } + private ushort _eventId; + private ushort _lenBody; + private Userdata _body; + private MetricsContract m_root; + private KaitaiStruct m_parent; + private byte[] __raw_body; + + /// + /// Type of message, affects format of the body. + /// + public ushort EventId { get { return this._eventId; } } + + /// + /// Size of body in bytes. + /// + public ushort LenBody { get { return this._lenBody; } } + + /// + /// Body of Metrics binary protocol message. + /// + public Userdata Body { get { return this._body; } } + public MetricsContract M_Root { get { return this.m_root; } } + public KaitaiStruct M_Parent { get { return this.m_parent; } } + public byte[] M_RawBody { get { return this.__raw_body; } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 021fb55140..03f9f297c2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -21,197 +21,196 @@ using System.Runtime.InteropServices; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class UnixDomainSocketDataTransportTests { - public class UnixDomainSocketDataTransportTests + [Fact] + public void UnixDomainSocketDataTransport_Success_Linux() { - [Fact] - public void UnixDomainSocketDataTransport_Success_Linux() + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + try + { + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + using Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + } + catch (Exception) + { + throw; + } + finally { - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); try { - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - - // Client - using var dataTransport = new UnixDomainSocketDataTransport(path); - using Socket serverSocket = server.Accept(); - var data = new byte[] { 12, 34, 56 }; - dataTransport.Send(data, data.Length); - var receivedData = new byte[5]; - serverSocket.Receive(receivedData); - Assert.Equal(data[0], receivedData[0]); - Assert.Equal(data[1], receivedData[1]); - Assert.Equal(data[2], receivedData[2]); - } - catch (Exception) - { - throw; + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } + } - [Fact] - public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() + [Fact] + public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + var data = new byte[1024]; + var i = 0; + using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests + var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; + try { - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - var data = new byte[1024]; - var i = 0; - using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests - var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; - try + // Client + using Socket serverSocket = server.Accept(); + while (true) { - // Client - using Socket serverSocket = server.Accept(); - while (true) - { - Console.WriteLine($"Sending request #{i++}."); - socket.Send(data, data.Length, SocketFlags.None); - } - - // The server is not processing sent data (because of heavy load, etc.) + Console.WriteLine($"Sending request #{i++}."); + socket.Send(data, data.Length, SocketFlags.None); } - catch (Exception) + + // The server is not processing sent data (because of heavy load, etc.) + } + catch (Exception) + { + // At this point, the outgoing buffer for the socket must be full, + // because the last Send failed. + // Send again and assert the exception to confirm: + Assert.Throws(() => + { + Console.WriteLine($"Sending request #{i}."); + socket.Send(data, data.Length, SocketFlags.None); + }); + } + finally + { + try { - // At this point, the outgoing buffer for the socket must be full, - // because the last Send failed. - // Send again and assert the exception to confirm: - Assert.Throws(() => - { - Console.WriteLine($"Sending request #{i}."); - socket.Send(data, data.Length, SocketFlags.None); - }); + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } + } - [Fact] - public void UnixDomainSocketDataTransport_ServerRestart_Linux() + [Fact] + public void UnixDomainSocketDataTransport_ServerRestart_Linux() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + Console.WriteLine("Test starts."); + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + try { - Console.WriteLine("Test starts."); - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); + var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + + // LingerOption lo = new LingerOption(false, 0); + // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + + Console.WriteLine("Successfully sent a message."); + + // Emulate server stops + serverSocket.Shutdown(SocketShutdown.Both); + serverSocket.Disconnect(false); + serverSocket.Dispose(); + server.Shutdown(SocketShutdown.Both); + server.Disconnect(false); + server.Dispose(); try { - var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - - // LingerOption lo = new LingerOption(false, 0); - // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); - server.Bind(endpoint); - server.Listen(1); - - // Client - using var dataTransport = new UnixDomainSocketDataTransport(path); - Socket serverSocket = server.Accept(); - var data = new byte[] { 12, 34, 56 }; - dataTransport.Send(data, data.Length); - var receivedData = new byte[5]; - serverSocket.Receive(receivedData); - Assert.Equal(data[0], receivedData[0]); - Assert.Equal(data[1], receivedData[1]); - Assert.Equal(data[2], receivedData[2]); - - Console.WriteLine("Successfully sent a message."); - - // Emulate server stops - serverSocket.Shutdown(SocketShutdown.Both); - serverSocket.Disconnect(false); - serverSocket.Dispose(); - server.Shutdown(SocketShutdown.Both); - server.Disconnect(false); - server.Dispose(); - try - { - File.Delete(path); - } - catch - { - } - - Console.WriteLine("Destroyed server."); - - Console.WriteLine("Client will fail during Send, and should throw an Exception"); - Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); - Console.WriteLine("Client will fail during Reconnect, and should throw an Exception"); - Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); - - using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server2.Bind(endpoint); - server2.Listen(1); - Console.WriteLine("Started a new server and listening."); - - var data2 = new byte[] { 34, 56, 78 }; - dataTransport.Send(data2, data2.Length); - Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); - - using Socket serverSocket2 = server2.Accept(); - Console.WriteLine("The new server is ready and accepting connections."); - var receivedData2 = new byte[5]; - serverSocket2.Receive(receivedData2); - Console.WriteLine("Server received a messge."); - Assert.Equal(data2[0], receivedData2[0]); - Assert.Equal(data2[1], receivedData2[1]); - Assert.Equal(data2[2], receivedData2[2]); + File.Delete(path); } - catch (Exception) + catch { - throw; } - finally + + Console.WriteLine("Destroyed server."); + + Console.WriteLine("Client will fail during Send, and should throw an Exception"); + Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); + Console.WriteLine("Client will fail during Reconnect, and should throw an Exception"); + Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); + + using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server2.Bind(endpoint); + server2.Listen(1); + Console.WriteLine("Started a new server and listening."); + + var data2 = new byte[] { 34, 56, 78 }; + dataTransport.Send(data2, data2.Length); + Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); + + using Socket serverSocket2 = server2.Accept(); + Console.WriteLine("The new server is ready and accepting connections."); + var receivedData2 = new byte[5]; + serverSocket2.Receive(receivedData2); + Console.WriteLine("Server received a messge."); + Assert.Equal(data2[0], receivedData2[0]); + Assert.Equal(data2[1], receivedData2[1]); + Assert.Equal(data2[2], receivedData2[2]); + } + catch (Exception) + { + throw; + } + finally + { + try + { + File.Delete(path); + } + catch { - try - { - File.Delete(path); - } - catch - { - } } } } + } - private static string GetRandomFilePath() + private static string GetRandomFilePath() + { + while (true) { - while (true) + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - if (!File.Exists(path)) - { - return path; - } + return path; } } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index 30b1538f2d..fe023e36b9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -20,65 +20,64 @@ using System.Text; using Xunit; -namespace OpenTelemetry.Exporter.Geneva.Tests +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class UnixDomainSocketEndPointTests { - public class UnixDomainSocketEndPointTests + [Fact] + public void UnixDomainSocketEndPoint_constructor_InvalidArgument() { - [Fact] - public void UnixDomainSocketEndPoint_constructor_InvalidArgument() - { - Assert.Throws(() => _ = new UnixDomainSocketEndPoint(null)); - Assert.Throws(() => _ = new UnixDomainSocketEndPoint(string.Empty)); - Assert.Throws(() => _ = new UnixDomainSocketEndPoint(new string('a', 100))); - } + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(null)); + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(string.Empty)); + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(new string('a', 100))); + } - [Fact] - public void UnixDomainSocketEndPoint_constructor_Success() - { - var endpoint = new UnixDomainSocketEndPoint("abc"); - Assert.Equal("abc", endpoint.ToString()); - } + [Fact] + public void UnixDomainSocketEndPoint_constructor_Success() + { + var endpoint = new UnixDomainSocketEndPoint("abc"); + Assert.Equal("abc", endpoint.ToString()); + } - [Fact] - public void UnixDomainSocketEndPoint_Create_InvalidArgument() - { - var endpoint = new UnixDomainSocketEndPoint("abc"); - Assert.Throws(() => _ = endpoint.Create(null)); - Assert.Throws(() => _ = endpoint.Create(this.CreateSocketAddress(new string('a', 100)))); - } + [Fact] + public void UnixDomainSocketEndPoint_Create_InvalidArgument() + { + var endpoint = new UnixDomainSocketEndPoint("abc"); + Assert.Throws(() => _ = endpoint.Create(null)); + Assert.Throws(() => _ = endpoint.Create(this.CreateSocketAddress(new string('a', 100)))); + } - [Fact] - public void UnixDomainSocketEndPoint_Create_Success() - { - var endpoint = new UnixDomainSocketEndPoint("abc"); + [Fact] + public void UnixDomainSocketEndPoint_Create_Success() + { + var endpoint = new UnixDomainSocketEndPoint("abc"); - var sa = new SocketAddress(AddressFamily.Unix, 2); // SocketAddress size is 2 - Assert.Equal(string.Empty, endpoint.Create(sa).ToString()); + var sa = new SocketAddress(AddressFamily.Unix, 2); // SocketAddress size is 2 + Assert.Equal(string.Empty, endpoint.Create(sa).ToString()); - Assert.Equal("\0", endpoint.Create(this.CreateSocketAddress(string.Empty)).ToString()); - Assert.Equal("test\0", endpoint.Create(this.CreateSocketAddress("test")).ToString()); - } + Assert.Equal("\0", endpoint.Create(this.CreateSocketAddress(string.Empty)).ToString()); + Assert.Equal("test\0", endpoint.Create(this.CreateSocketAddress("test")).ToString()); + } - [Fact] - public void UnixDomainSocketEndPoint_Serialize() - { - var path = "abc"; - var endpoint = new UnixDomainSocketEndPoint(path); - Assert.Equal(this.CreateSocketAddress(path), endpoint.Serialize()); - } + [Fact] + public void UnixDomainSocketEndPoint_Serialize() + { + var path = "abc"; + var endpoint = new UnixDomainSocketEndPoint(path); + Assert.Equal(this.CreateSocketAddress(path), endpoint.Serialize()); + } - private SocketAddress CreateSocketAddress(string path) + private SocketAddress CreateSocketAddress(string path) + { + int NativePathOffset = 2; + var nativePath = Encoding.UTF8.GetBytes(path); + var sa = new SocketAddress(AddressFamily.Unix, NativePathOffset + nativePath.Length + 1); + for (int i = 0; i < nativePath.Length; ++i) { - int NativePathOffset = 2; - var nativePath = Encoding.UTF8.GetBytes(path); - var sa = new SocketAddress(AddressFamily.Unix, NativePathOffset + nativePath.Length + 1); - for (int i = 0; i < nativePath.Length; ++i) - { - sa[NativePathOffset + i] = nativePath[i]; - } - - sa[NativePathOffset + nativePath.Length] = 0; - return sa; + sa[NativePathOffset + i] = nativePath[i]; } + + sa[NativePathOffset + nativePath.Length] = 0; + return sa; } } diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs index 592c128152..61bb38d80f 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs +++ b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs @@ -18,49 +18,48 @@ using System.IO; using System.Threading; -namespace OpenTelemetry.Extensions.Docker.Tests +namespace OpenTelemetry.Extensions.Docker.Tests; + +internal class TempFile : IDisposable { - internal class TempFile : IDisposable - { - private string filePath; + private string filePath; - public TempFile() - { - this.filePath = Path.GetTempFileName(); - } + public TempFile() + { + this.filePath = Path.GetTempFileName(); + } - public string FilePath - { - get { return this.filePath; } - set { this.filePath = value; } - } + public string FilePath + { + get { return this.filePath; } + set { this.filePath = value; } + } - public void Write(string data) + public void Write(string data) + { + using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) { - using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + using (StreamWriter sw = new StreamWriter(stream)) { - using (StreamWriter sw = new StreamWriter(stream)) - { - sw.Write(data); - } + sw.Write(data); } } + } - public void Dispose() + public void Dispose() + { + for (int tries = 0; ; tries++) { - for (int tries = 0; ; tries++) + try + { + File.Delete(this.filePath); + return; + } + catch (IOException) when (tries < 3) { - try - { - File.Delete(this.filePath); - return; - } - catch (IOException) when (tries < 3) - { - // the file is unavailable because it is: still being written to or being processed by another thread - // sleep for sometime before deleting - Thread.Sleep(1000); - } + // the file is unavailable because it is: still being written to or being processed by another thread + // sleep for sometime before deleting + Thread.Sleep(1000); } } } From 1eccf86ad967e36d2e26730006b97bbb86ef6847 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 26 Aug 2022 09:52:37 -0700 Subject: [PATCH 0310/1499] [Instrumentation.Process] Added memory related metrics. (#595) --- .../ProcessMetrics.cs | 23 ++++++++++++++++++ .../ProcessMetricsTests.cs | 24 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 930279d669..563ff11452 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -16,6 +16,7 @@ using System.Diagnostics.Metrics; using System.Reflection; +using Diagnostics = System.Diagnostics; namespace OpenTelemetry.Instrumentation.Process; @@ -23,9 +24,31 @@ internal class ProcessMetrics { internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); + private static readonly Diagnostics.Process CurrentProcess = Diagnostics.Process.GetCurrentProcess(); static ProcessMetrics() { + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + "process.memory.usage", + () => + { + CurrentProcess.Refresh(); + return CurrentProcess.WorkingSet64; + }, + unit: "By", + description: "The amount of physical memory in use."); + + // TODO: change to ObservableUpDownCounter + MeterInstance.CreateObservableGauge( + "process.memory.virtual", + () => + { + CurrentProcess.Refresh(); + return CurrentProcess.VirtualMemorySize64; + }, + unit: "By", + description: "The amount of committed virtual memory."); } /// diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 701679c659..e227506a81 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -14,8 +14,32 @@ // limitations under the License. // +using System.Collections.Generic; +using System.Linq; +using OpenTelemetry.Metrics; +using Xunit; + namespace OpenTelemetry.Instrumentation.Process.Tests; public class ProcessMetricsTests { + private const int MaxTimeToAllowForFlush = 10000; + + [Fact] + public void ProcessMetricsAreCaptured() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + Assert.True(exportedItems.Count == 2); + var physicalMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.usage"); + Assert.NotNull(physicalMemoryMetric); + var virtualMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.virtual"); + Assert.NotNull(virtualMemoryMetric); + } } From 1e8a13e1b30ad262c04b882b7ba684b643da30f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 29 Aug 2022 20:19:45 +0200 Subject: [PATCH 0311/1499] Instrumentation.AWSLambda: Rename to remove .Contrib & minor cleanups. (#593) * Instrumentation.AWSLambda: Rename to remove .Contrib. * Also move public class AWSLambdaWrapper out of implementation namespace, add version to ActivitySource. --- .../comp_contrib_instrumentation_awslambda.md | 8 +++--- .github/component_owners.yml | 12 ++++---- .../package-Instrumentation.AWSLambda.yml | 6 ++-- opentelemetry-dotnet-contrib.sln | 28 +++++++++---------- .../AWSLambdaInstrumentationOptions.cs | 2 +- .../AWSLambdaWrapper.cs | 15 ++++++++-- .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 9 ++++-- .../AWSLambdaResourceDetector.cs | 2 +- .../AWSLambdaSemanticConventions.cs | 2 +- .../Implementation/AWSLambdaUtils.cs | 5 +--- ...elemetry.Instrumentation.AWSLambda.csproj} | 0 .../README.md | 2 +- .../TracerProviderBuilderExtensions.cs | 8 +++--- .../AWSLambdaWrapperTests.cs | 8 ++++-- ...ry.Instrumentation.AWSLambda.Tests.csproj} | 2 +- .../SampleHandlers.cs | 2 +- .../SampleLambdaContext.cs | 2 +- 18 files changed, 65 insertions(+), 50 deletions(-) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/AWSLambdaInstrumentationOptions.cs (94%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation => OpenTelemetry.Instrumentation.AWSLambda}/AWSLambdaWrapper.cs (94%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/AssemblyInfo.cs (63%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/CHANGELOG.md (72%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/Implementation/AWSLambdaResourceDetector.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/Implementation/AWSLambdaSemanticConventions.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/Implementation/AWSLambdaUtils.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj => OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj} (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/README.md (98%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWSLambda => OpenTelemetry.Instrumentation.AWSLambda}/TracerProviderBuilderExtensions.cs (90%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests => OpenTelemetry.Instrumentation.AWSLambda.Tests}/AWSLambdaWrapperTests.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj => OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj} (86%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests => OpenTelemetry.Instrumentation.AWSLambda.Tests}/SampleHandlers.cs (96%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests => OpenTelemetry.Instrumentation.AWSLambda.Tests}/SampleLambdaContext.cs (95%) diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md index dcb46e3c44..66089c059e 100644 --- a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md +++ b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md @@ -1,10 +1,10 @@ --- -name: OpenTelemetry.Contrib.Instrumentation.AWSLambda -about: Issue with OpenTelemetry.Contrib.Instrumentation.AWSLambda -labels: comp:contrib.instrumentation.awslambda +name: OpenTelemetry.Instrumentation.AWSLambda +about: Issue with OpenTelemetry.Instrumentation.AWSLambda +labels: comp:instrumentation.awslambda --- -# Issue with OpenTelemetry.Contrib.Instrumentation.AWSLambda +# Issue with OpenTelemetry.Instrumentation.AWSLambda List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are diff --git a/.github/component_owners.yml b/.github/component_owners.yml index d8973e3081..b3eec10176 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -8,9 +8,6 @@ components: - lupengamzn src/OpenTelemetry.Contrib.Instrumentation.AWS/: - srprash - src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/: - - rypdal - - Oberon00 src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch @@ -30,6 +27,9 @@ components: - vishweshbankwar src/OpenTelemetry.Extensions.PersistentStorage/: - vishweshbankwar + src/OpenTelemetry.Instrumentation.AWSLambda/: + - rypdal + - Oberon00 src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith src/OpenTelemetry.Instrumentation.EventCounters/: @@ -58,9 +58,6 @@ components: - lupengamzn test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/: - srprash - test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/: - - rypdal - - Oberon00 test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch @@ -92,6 +89,9 @@ components: - swetharavichandrancisco test/OpenTelemetry.Extensions.PersistentStorage.Tests/: - vishweshbankwar + test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: + - rypdal + - Oberon00 test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith test/OpenTelemetry.Instrumentation.EventCounters.Tests/: diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 4db19aac33..a7c179e364 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.AWSLambda +name: Pack OpenTelemetry.Instrumentation.AWSLambda on: workflow_dispatch: @@ -15,7 +15,7 @@ jobs: build-test-pack: runs-on: ${{ matrix.os }} env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.AWSLambda + PROJECT: OpenTelemetry.Instrumentation.AWSLambda strategy: matrix: @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ec6c76ee44..abb856fd7e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -127,10 +127,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcCore.AspNetCore", "examples\grpc.core\Examples.GrpcCore.AspNetCore\Examples.GrpcCore.AspNetCore.csproj", "{F1591DEE-79C0-4161-85C2-1477B261D274}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda", "src\OpenTelemetry.Contrib.Instrumentation.AWSLambda\OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj", "{87FE0ED4-56A5-4775-9F63-DD532F2200BD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests\OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj", "{08EDD935-8B4E-4CF5-8840-200DEBA8E110}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Tests.Shared", "test\OpenTelemetry.Contrib.Tests.Shared\OpenTelemetry.Contrib.Tests.Shared.csproj", "{C33F2D9D-89A6-459C-9A51-79BA5A9EF194}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" @@ -237,6 +233,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Process.Tests", "test\OpenTelemetry.Instrumentation.Process.Tests\OpenTelemetry.Instrumentation.Process.Tests.csproj", "{61421ACF-5F90-491B-AFB3-14EF12CCA255}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AWSLambda.Tests", "test\OpenTelemetry.Instrumentation.AWSLambda.Tests\OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj", "{0F18B7C8-B192-4236-9578-7AD02BFC7128}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AWSLambda", "src\OpenTelemetry.Instrumentation.AWSLambda\OpenTelemetry.Instrumentation.AWSLambda.csproj", "{B40B975E-78B2-4712-8B4D-BADA67DF0C0A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -291,14 +291,6 @@ Global {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.Build.0 = Debug|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.ActiveCfg = Release|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.Build.0 = Release|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {87FE0ED4-56A5-4775-9F63-DD532F2200BD}.Release|Any CPU.Build.0 = Release|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Debug|Any CPU.Build.0 = Debug|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.ActiveCfg = Release|Any CPU - {08EDD935-8B4E-4CF5-8840-200DEBA8E110}.Release|Any CPU.Build.0 = Release|Any CPU {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -499,6 +491,14 @@ Global {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Debug|Any CPU.Build.0 = Debug|Any CPU {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Release|Any CPU.ActiveCfg = Release|Any CPU {61421ACF-5F90-491B-AFB3-14EF12CCA255}.Release|Any CPU.Build.0 = Release|Any CPU + {0F18B7C8-B192-4236-9578-7AD02BFC7128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F18B7C8-B192-4236-9578-7AD02BFC7128}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F18B7C8-B192-4236-9578-7AD02BFC7128}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F18B7C8-B192-4236-9578-7AD02BFC7128}.Release|Any CPU.Build.0 = Release|Any CPU + {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -521,8 +521,6 @@ Global {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} - {87FE0ED4-56A5-4775-9F63-DD532F2200BD} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {08EDD935-8B4E-4CF5-8840-200DEBA8E110} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} @@ -576,6 +574,8 @@ Global {DDA355A3-4D75-4F45-9A5E-E93C3EFB9896} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {F811262D-D78A-4C4A-8A31-FFC458164BF2} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {61421ACF-5F90-491B-AFB3-14EF12CCA255} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {0F18B7C8-B192-4236-9578-7AD02BFC7128} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {B40B975E-78B2-4712-8B4D-BADA67DF0C0A} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs index 2c3b101380..dff492f750 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda +namespace OpenTelemetry.Instrumentation.AWSLambda { /// /// AWS lambda instrumentation options. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 4ca66e3c7a..7d34561c5e 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -16,18 +16,27 @@ using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; using System.Threading.Tasks; using Amazon.Lambda.Core; +using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda { /// /// Wrapper class for AWS Lambda handlers. /// - public class AWSLambdaWrapper + public static class AWSLambdaWrapper { - private static readonly ActivitySource AWSLambdaActivitySource = new(AWSLambdaUtils.ActivitySourceName); + private static readonly AssemblyName AssemblyName = typeof(AWSLambdaWrapper).Assembly.GetName(); + + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Initialization order.")] + internal static readonly string ActivitySourceName = AssemblyName.Name; + + private static readonly Version Version = AssemblyName.Version; + private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, Version.ToString()); /// /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs similarity index 63% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs index 27a1e79e48..573a6e313a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs @@ -16,4 +16,4 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AWSLambda.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md similarity index 72% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md rename to src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index ba2479e0a3..7af903a7bb 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -1,7 +1,12 @@ -# Changelog - OpenTelemetry.Contrib.Instrumentation.AWSLambda +# Changelog - OpenTelemetry.Instrumentation.AWSLambda ## Unreleased +* Breaking change: Rename package to OpenTelemetry.Instrumentation.AWSLambda + (remove ".Contrib") ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) +* Breaking change: Move public class AWSLambdaWrapper out of Implementation subnamespace + ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) +* Add version to ActivitySource ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) * Updated the `ActivitySource` name to the assembly name: `OpenTelemetry.Instrumentation.AWSLambda` ([#534](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/534)) @@ -30,4 +35,4 @@ SDK](https://www.nuget.org/packages/OpenTelemetry/). The AWSLambda library includes extension and tracing APIs to configure resource detector and generate incoming AWS Lambda OTel span. For more details, please refer to the -[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/README.md) +[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AWSLambda-1.1.0-beta1/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/README.md) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs index f489ac6868..1c08ddf592 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs @@ -16,7 +16,7 @@ using System.Collections.Generic; -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation { internal static class AWSLambdaResourceDetector { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs index a3fcdb6977..0674a9986f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation { /// /// Semantic conventions for AWS Lambda. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 9d84d9b78f..d796910781 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -23,16 +23,13 @@ using OpenTelemetry.Context.Propagation; using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation { /// /// Class for getting AWS Lambda related attributes. /// internal static class AWSLambdaUtils { - internal static string ActivitySourceName = - typeof(AWSLambdaUtils).Assembly.GetName().Name.Replace(".Contrib", string.Empty); - private const string CloudProvider = "aws"; private const string AWSRegion = "AWS_REGION"; private const string AWSXRayLambdaTraceHeaderKey = "_X_AMZN_TRACE_ID"; diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/OpenTelemetry.Contrib.Instrumentation.AWSLambda.csproj rename to src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md similarity index 98% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/README.md rename to src/OpenTelemetry.Instrumentation.AWSLambda/README.md index d8e7d04437..28adbb4bb6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -5,7 +5,7 @@ This repo contains SDK to instrument Lambda handler to create incoming span. ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.AWSLambda +dotnet add package OpenTelemetry.Instrumentation.AWSLambda ``` ## Configuration diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs similarity index 90% rename from src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index 6a984a90e7..36f6b9eb8a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -15,12 +15,12 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.AWSLambda; -using OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation; +using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Resources; +using OpenTelemetry.Trace; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Instrumentation.AWSLambda { /// /// Extension class for TracerProviderBuilder. @@ -44,7 +44,7 @@ public static TracerProviderBuilder AddAWSLambdaConfigurations( AWSLambdaWrapper.DisableAwsXRayContextExtraction = options.DisableAwsXRayContextExtraction; - builder.AddSource(AWSLambdaUtils.ActivitySourceName); + builder.AddSource(AWSLambdaWrapper.ActivitySourceName); builder.SetResourceBuilder(ResourceBuilder .CreateEmpty() .AddService(AWSLambdaUtils.GetFunctionName(), null, null, false) diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs rename to test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 724806bac2..1ad6b06310 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -20,12 +20,12 @@ using System.Threading.Tasks; using Amazon.Lambda.Core; using Moq; -using OpenTelemetry.Contrib.Instrumentation.AWSLambda.Implementation; +using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests { public class AWSLambdaWrapperTests { @@ -305,6 +305,10 @@ private void AssertSpanProperties(Activity activity, string parentId) Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); Assert.Equal(ActivityKind.Server, activity.Kind); Assert.Equal("testfunction", activity.DisplayName); + Assert.Equal("OpenTelemetry.Instrumentation.AWSLambda", activity.Source.Name); + + // Version should consist of four decimals separated by dots. + Assert.Matches(@"^\d+(\.\d+){3}$", activity.Source.Version); } private void AssertResourceAttributes(Resource resource) diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj similarity index 86% rename from test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj rename to test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index fb79832ea4..4b5203ccdf 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs similarity index 96% rename from test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs rename to test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 85e89c4a45..456c43aa62 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -18,7 +18,7 @@ using System.Threading.Tasks; using Amazon.Lambda.Core; -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests { public class SampleHandlers { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs similarity index 95% rename from test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs rename to test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index 5152ac9f8c..5d452b675a 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -17,7 +17,7 @@ using System; using Amazon.Lambda.Core; -namespace OpenTelemetry.Contrib.Instrumentation.AWSLambda.Tests +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests { public class SampleLambdaContext : ILambdaContext { From 371f0a0f8ef516c591172feaafc07f5bc3c3e68f Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 29 Aug 2022 16:00:36 -0700 Subject: [PATCH 0312/1499] Add Component Owners for OpenTelemetry.Extensions.AzureMonitor (#614) --- .github/component_owners.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index b3eec10176..57fe851901 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -21,6 +21,9 @@ components: - SergeyKanzhelev src/OpenTelemetry.Extensions/: - codeblanch + src/OpenTelemetry.Extensions.AzureMonitor/: + - rajkumar-rangaraj + - vishweshbankwar src/OpenTelemetry.Extensions.Docker/: - iskiselev src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/: From 2dcc721429779658f4b63ee140aad6361924fd79 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 31 Aug 2022 01:11:38 -0400 Subject: [PATCH 0313/1499] [Exporter.Geneva] Add dedicated test for Exception and EventId serialization (#615) --- .../GenevaLogExporterTests.cs | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 0f1168c856..3ec27e5ebf 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -902,6 +902,155 @@ public void SuccessfulExportOnLinux() } } + [Fact] + public void SerializationTestForException() + { + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + }); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); + + // ACT + // This is treated as structured logging as the state can be converted to IReadOnlyList> + logger.Log( + logLevel: LogLevel.Information, + eventId: default, + state: null, + exception: new Exception("Exception Message"), + formatter: null); + + // VALIDATE + Assert.Single(logRecordList); + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var exceptionType = GetField(fluentdData, "env_ex_type"); + var exceptionMessage = GetField(fluentdData, "env_ex_msg"); + Assert.Equal("System.Exception", exceptionType); + Assert.Equal("Exception Message", exceptionMessage); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + public void SerializationTestForEventId() + { + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + }); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new GenevaLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); + + // ACT + // This is treated as structured logging as the state can be converted to IReadOnlyList> + logger.Log( + logLevel: LogLevel.Information, + eventId: new EventId(1, "logger-event-name"), + state: null, + exception: null, + formatter: null); + + // VALIDATE + Assert.Single(logRecordList); + var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var eventId = GetField(fluentdData, "eventId"); + Assert.Equal((byte)1, eventId); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + private static string GenerateTempFilePath() { while (true) From 68630e9aa99c08c1620683a85228bb88f841e626 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 1 Sep 2022 10:57:44 -0400 Subject: [PATCH 0314/1499] Remove net5.0 from everywhere (#617) --- .github/workflows/linux-ci-md.yml | 2 +- .github/workflows/linux-ci.yml | 2 +- .github/workflows/package-Extensions.yml | 4 ++-- .github/workflows/windows-ci-md.yml | 2 +- .github/workflows/windows-ci.yml | 2 +- build/Common.props | 2 +- .../Examples.GrpcCore.AspNetCore.csproj | 2 +- .../OpenTelemetry.Extensions.AzureMonitor.csproj | 2 +- .../.publicApi/{net5.0 => net6.0}/PublicAPI.Shipped.txt | 0 .../.publicApi/{net5.0 => net6.0}/PublicAPI.Unshipped.txt | 0 src/OpenTelemetry.Extensions/CHANGELOG.md | 5 +++++ .../Internal/ActivityEventAttachingLogProcessor.cs | 2 +- .../Internal/DefaultLogStateConverter.cs | 2 +- .../Logs/LogToActivityEventConversionOptions.cs | 2 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 2 +- .../OpenTelemetry.Extensions.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.Tests.csproj | 2 +- ...lemetry.Instrumentation.ElasticsearchClient.Tests.csproj | 2 +- ...lemetry.Instrumentation.EntityFrameworkCore.Tests.csproj | 6 +----- .../OpenTelemetry.Instrumentation.MassTransit.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 2 +- 25 files changed, 28 insertions(+), 27 deletions(-) rename src/OpenTelemetry.Extensions/.publicApi/{net5.0 => net6.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Extensions/.publicApi/{net5.0 => net6.0}/PublicAPI.Unshipped.txt (100%) diff --git a/.github/workflows/linux-ci-md.yml b/.github/workflows/linux-ci-md.yml index b55ee6c7ed..cec69098ec 100644 --- a/.github/workflows/linux-ci-md.yml +++ b/.github/workflows/linux-ci-md.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - version: [netcoreapp3.1,net5.0,net6.0] + version: [netcoreapp3.1,net6.0] steps: - run: 'echo "No build required"' diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml index b4d9e3b2a5..4bf4d64b68 100644 --- a/.github/workflows/linux-ci.yml +++ b/.github/workflows/linux-ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - version: [netcoreapp3.1,net5.0,net6.0] + version: [netcoreapp3.1,net6.0] steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index aae505cb0a..3b03d4bc32 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -36,7 +36,7 @@ jobs: run: dotnet test test/${{env.PROJECT}}.Tests - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions has a conditional net5.0 target which causes dotnet pack to break when -no-build is used (for some reason) + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts uses: actions/upload-artifact@v3 @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/windows-ci-md.yml b/.github/workflows/windows-ci-md.yml index dce6fa9c72..02c643050a 100644 --- a/.github/workflows/windows-ci-md.yml +++ b/.github/workflows/windows-ci-md.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - version: [net461,netcoreapp3.1,net5.0,net6.0] + version: [net461,netcoreapp3.1,net6.0] steps: - run: 'echo "No build required"' diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 179577c9bc..0582256d9c 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - version: [net461,netcoreapp3.1,net5.0,net6.0] + version: [net461,netcoreapp3.1,net6.0] steps: - uses: actions/checkout@v3 diff --git a/build/Common.props b/build/Common.props index e7c6a6b2e7..ebba96dab9 100644 --- a/build/Common.props +++ b/build/Common.props @@ -37,7 +37,7 @@ [1.2.0-beta.354,2.0) - + $(NoWarn);nullable diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index a810d8abeb..375fd7eb0d 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 356b1983c3..53941035d0 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -1,7 +1,7 @@  - net461;net5.0 + net461;net6.0 diff --git a/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net5.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index fc12d03af0..b71c68bdca 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -7,6 +7,11 @@ * Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is .NET 4.6.2. + * Removes net5.0 target as .NET 5.0 is going out + of support. The package keeps netstandard2.0 target, so it + can still be used with .NET5.0 apps. + ([#617](https://github.com/open-telemetry/opentelemetry-dotnet/pull/617)) + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index af4831f7b3..e8924fc6cc 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System; using System.Diagnostics; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index 2ae3b2f487..f109cecd31 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index 8783830309..bf550b195b 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index 7b87044461..621157871d 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET5_0_OR_GREATER +#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System; using System.Diagnostics; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index cf4f32e9e9..2595e97bb1 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -2,7 +2,7 @@ net462;netstandard2.0 - $(TargetFrameworks);net5.0 + $(TargetFrameworks);net6.0 OpenTelemetry .NET SDK preview features and extensions Preview- enable diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index e7919ee3ed..ca229c6b57 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 6823561c4b..36d6642f07 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1308,SA1201 diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index c07444cf5b..b641dccca8 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -1,7 +1,7 @@  Unit test project for Stackdriver Exporter for OpenTelemetry - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 1298131090..cf6eece6bf 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index f561400b96..1fbff07a38 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry .NET SDK preview features and extensions - net5.0 + net6.0 diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 447f50b606..bbd79698a7 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,7 +1,7 @@  Unit test project for OpenTelemetry Elasticsearch client instrumentation - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 true diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 7ececc7d48..3d88601ed2 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -1,17 +1,13 @@  Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 - - - - diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj index 8c2b586ae3..c012240945 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry MassTransit instrumentation - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 $(TargetFrameworks);net461 true diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 1d26ebe0bc..ba9a0c04e8 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry WCF instrumentation - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 $(TargetFrameworks);net462 From e7bc1b0b705d39b1ea9ba508484650bc7ba81f56 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 1 Sep 2022 12:34:07 -0700 Subject: [PATCH 0315/1499] Remove unnecessary directives (#619) --- .../Internal/ActivityEventAttachingLogProcessor.cs | 2 -- .../Internal/DefaultLogStateConverter.cs | 2 -- .../Logs/LogToActivityEventConversionOptions.cs | 2 -- .../Logs/OpenTelemetryLoggingExtensions.cs | 2 -- 4 files changed, 8 deletions(-) diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index e8924fc6cc..618c0749d1 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System; using System.Diagnostics; using OpenTelemetry.Internal; @@ -109,4 +108,3 @@ public State(ActivityTagsCollection tags, ActivityEventAttachingLogProcessor pro public int Depth { get; set; } } } -#endif diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index f109cecd31..9b6e697a85 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System.Collections.Generic; using System.Diagnostics; @@ -64,4 +63,3 @@ public static void ConvertScope(ActivityTagsCollection tags, int depth, LogRecor } } } -#endif diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index bf550b195b..a31058fe1f 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System; using System.Collections.Generic; using System.Diagnostics; @@ -36,4 +35,3 @@ public class LogToActivityEventConversionOptions /// public Action ScopeConverter { get; set; } = DefaultLogStateConverter.ConvertScope; } -#endif diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index 621157871d..3adf9de5c1 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -#if NET462_OR_GREATER || NETSTANDARD2_0 || NET6_0_OR_GREATER using System; using System.Diagnostics; using OpenTelemetry.Internal; @@ -50,4 +49,3 @@ public static OpenTelemetryLoggerOptions AttachLogsToActivityEvent( #pragma warning restore CA2000 // Dispose objects before losing scope } } -#endif From 071a1d97a8841d3939d529d28c8996dc9743441e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Fri, 2 Sep 2022 16:49:36 +0200 Subject: [PATCH 0316/1499] [Instrumentation.AwsLambda] Rename Trace to TraceAsync where appropriate (#608) --- .../AWSLambdaWrapper.cs | 50 +++++++++---------- .../AWSLambdaWrapperTests.cs | 6 +-- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 7d34561c5e..ed222d95cd 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -98,65 +98,61 @@ public static void Trace( } /// - /// Tracing wrapper for async Lambda handler. + /// Tracing wrapper for Lambda handler. /// - /// Input. /// TracerProvider passed in. /// Lambda handler function passed in. - /// Instance of input. - /// Lambda context (optional, but strongly recommended). + /// Instance of lambda context. /// /// The optional parent context is used for Activity object creation. /// If no parent context provided, incoming request is used to extract one. /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one /// unless X-Ray propagation is disabled in the configuration for this wrapper. /// - /// Task. - public static Task Trace( + public static void Trace( TracerProvider tracerProvider, - Func lambdaHandler, - TInput input, + Action lambdaHandler, ILambdaContext context, ActivityContext parentContext = default) { - Func action = async () => await lambdaHandler(input, context); - return TraceInternalAsync(tracerProvider, action, input, context, parentContext); + Action action = () => lambdaHandler(context); + TraceInternal(tracerProvider, action, null, context, parentContext); } /// /// Tracing wrapper for async Lambda handler. /// /// Input. - /// Output result. /// TracerProvider passed in. /// Lambda handler function passed in. /// Instance of input. - /// Instance of lambda context. + /// Lambda context (optional, but strongly recommended). /// /// The optional parent context is used for Activity object creation. /// If no parent context provided, incoming request is used to extract one. /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one /// unless X-Ray propagation is disabled in the configuration for this wrapper. /// - /// Task of result. - public static async Task Trace( + /// Task. + public static Task TraceAsync( TracerProvider tracerProvider, - Func> lambdaHandler, + Func lambdaHandler, TInput input, ILambdaContext context, ActivityContext parentContext = default) { - TResult result = default; - Func action = async () => result = await lambdaHandler(input, context); - await TraceInternalAsync(tracerProvider, action, input, context, parentContext); - return result; + Func action = async () => await lambdaHandler(input, context); + return TraceInternalAsync(tracerProvider, action, input, context, parentContext); } /// - /// Tracing wrapper for Lambda handler. + /// Tracing wrapper for async Lambda handler. /// + /// Input. + /// Output result. /// TracerProvider passed in. /// Lambda handler function passed in. + /// Instance of input. /// Instance of lambda context. /// /// The optional parent context is used for Activity object creation. @@ -164,14 +160,18 @@ public static async Task Trace( /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one /// unless X-Ray propagation is disabled in the configuration for this wrapper. /// - public static void Trace( + /// Task of result. + public static async Task TraceAsync( TracerProvider tracerProvider, - Action lambdaHandler, + Func> lambdaHandler, + TInput input, ILambdaContext context, ActivityContext parentContext = default) { - Action action = () => lambdaHandler(context); - TraceInternal(tracerProvider, action, null, context, parentContext); + TResult result = default; + Func action = async () => result = await lambdaHandler(input, context); + await TraceInternalAsync(tracerProvider, action, input, context, parentContext); + return result; } /// @@ -187,7 +187,7 @@ public static void Trace( /// unless X-Ray propagation is disabled in the configuration. /// /// Task. - public static Task Trace( + public static Task TraceAsync( TracerProvider tracerProvider, Func lambdaHandler, ILambdaContext context, diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 1ad6b06310..3e3d9d633a 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -137,7 +137,7 @@ public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) .Build()) { var parentContext = setCustomParent ? CreateParentContext() : default; - var result = await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); + var result = await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -163,7 +163,7 @@ public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) .Build()) { var parentContext = setCustomParent ? CreateParentContext() : default; - await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); + await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } @@ -189,7 +189,7 @@ public async Task TraceAsyncWithNoInputAndNoReturn(bool setCustomParent) .Build()) { var parentContext = setCustomParent ? CreateParentContext() : default; - await AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerAsyncNoInputAndNoReturn, this.sampleLambdaContext, parentContext); + await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncNoInputAndNoReturn, this.sampleLambdaContext, parentContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } From bf01da1b248c2ce77f9709da119cbdf439dc1ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Tue, 6 Sep 2022 19:28:03 +0200 Subject: [PATCH 0317/1499] [Instrumentation.AwsLambda] Enable public API check. (#607) --- .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 13 +++++++++++++ .../AWSLambdaWrapper.cs | 4 ++++ .../OpenTelemetry.Instrumentation.AWSLambda.csproj | 1 + 4 files changed, 18 insertions(+) create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e4c64baf9c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,13 @@ +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.AWSLambdaInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction.get -> bool +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction.set -> void +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper +OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Action lambdaHandler, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> TResult +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Action lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func> lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task +static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index ed222d95cd..84c5c7a0d8 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -43,6 +43,8 @@ public static class AWSLambdaWrapper /// internal static bool DisableAwsXRayContextExtraction { get; set; } +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters + /// /// Tracing wrapper for Lambda handler. /// @@ -197,6 +199,8 @@ public static Task TraceAsync( return TraceInternalAsync(tracerProvider, action, null, context, parentContext); } +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters + internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) { if (parentContext == default) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 93b001d29b..239fb3e9f1 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -5,6 +5,7 @@ AWS Lambda tracing wrapper for OpenTelemetry .NET $(PackageTags);AWS Lambda Instrumentation.AWSLambda- + true From 0adee5aeccf67cecc4064af3f0037cfc864131bb Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Tue, 6 Sep 2022 19:51:35 +0200 Subject: [PATCH 0318/1499] Fix null tags. (#566) * Fix null tags. --- .../Implementation/ActivityExtensions.cs | 6 ++++-- .../StackdriverTraceExporter.cs | 6 +++++- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 2 +- .../StackdriverExporterTests.cs | 7 ++++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index aef78c1e37..66cc89a6f0 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -120,7 +120,7 @@ public static Span.Types.Link ToLink(this ActivityLink link) { link.Tags.ToDictionary( att => att.Key, - att => att.Value.ToAttributeValue()), + att => att.Value?.ToAttributeValue()), }, }; } @@ -128,7 +128,7 @@ public static Span.Types.Link ToLink(this ActivityLink link) return ret; } - public static AttributeValue ToAttributeValue(this object av) + public static AttributeValue ToAttributeValue(this object? av) { switch (av) { @@ -146,6 +146,8 @@ public static AttributeValue ToAttributeValue(this object av) { StringValue = new TruncatableString() { Value = d.ToString() }, }; + case null: + return new AttributeValue(); default: return new AttributeValue() { diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 69df0cfd40..222c5c12f0 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -105,7 +105,11 @@ public override ExportResult Export(in Batch batchActivity) foreach (var activity in batchActivity) { - batchSpansRequest.Spans.Add(activity.ToSpan(this.googleCloudProjectId.ProjectId)); + // It should never happen that the time has no correct kind, only if OpenTelemetry is used incorrectly. + if (activity.StartTimeUtc.Kind == DateTimeKind.Utc) + { + batchSpansRequest.Spans.Add(activity.ToSpan(this.googleCloudProjectId.ProjectId)); + } } // avoid cancelling here: this is no return point: if we reached this point diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index b641dccca8..75e8545346 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for Stackdriver Exporter for OpenTelemetry netcoreapp3.1;net6.0 diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 57c9e58b79..509d831452 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -107,7 +107,7 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() for (int i = 0; i < 10; i++) { - using Activity activity = source.StartActivity("Test Activity"); + using Activity activity = CreateTestActivity(); processor.OnEnd(activity); } @@ -147,7 +147,7 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() for (int i = 0; i < 10; i++) { - using Activity activity = source.StartActivity("Test Activity"); + using Activity activity = CreateTestActivity(); processor.OnEnd(activity); } @@ -192,6 +192,7 @@ internal static Activity CreateTestActivity( { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, + { "nullKey", null }, }; if (additionalAttributes != null) { @@ -224,7 +225,7 @@ internal static Activity CreateTestActivity( var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = setAttributes ? - attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())) + attributes.Where(x => x.Value != null).Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())) : null; var links = addLinks ? new[] From bc947a00c3f859cc436f050e81172fc1f8bc09d7 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 6 Sep 2022 16:04:43 -0400 Subject: [PATCH 0319/1499] Move inactive maintainers to emeritus (#618) --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eb87548c5a..78e89ea64c 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,17 @@ Maintainers * [Alan West](https://github.com/alanwest), New Relic * [Cijo Thomas](https://github.com/cijothomas), Microsoft * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft -* [Prashant Srivastava](https://github.com/srprash), AWS -* [Sergey Kanzhelev](https://github.com/SergeyKanzhelev), Google * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* +[Emeritus +Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): + +* [Prashant Srivastava](https://github.com/srprash), AWS +* [Sergey Kanzhelev](https://github.com/SergeyKanzhelev), Google + Even though, anybody can contribute, there are benefits of being a member of our community. See to the [community membership document](https://github.com/open-telemetry/community/blob/master/community-membership.md) From 1b808fd9bbeb8f6adaa210905f3476742d1e35e6 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Wed, 7 Sep 2022 16:02:42 -0700 Subject: [PATCH 0320/1499] OpenTelemetry.Extensions.AzureMonitor - Add sampleRate attribute to SamplingResult. (#623) --- .../ApplicationInsightsSampler.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 26049fc6a9..199da579de 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -14,6 +14,7 @@ // limitations under the License. // using System; +using System.Collections.Generic; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -25,6 +26,8 @@ namespace OpenTelemetry.Extensions.AzureMonitor; /// public class ApplicationInsightsSampler : Sampler { + private static readonly SamplingResult DropSamplingResult = new(false); + private readonly SamplingResult recordAndSampleSamplingResult; private readonly float samplingRatio; /// @@ -38,6 +41,13 @@ public ApplicationInsightsSampler(float samplingRatio) this.samplingRatio = samplingRatio; this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; + var sampleRate = (int)Math.Round(samplingRatio * 100); + this.recordAndSampleSamplingResult = new SamplingResult( + SamplingDecision.RecordAndSample, + new Dictionary + { + { "sampleRate", sampleRate }, + }); } /// @@ -48,8 +58,26 @@ public ApplicationInsightsSampler(float samplingRatio) /// Returns whether or not we should sample telemetry in the form of a class. public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { + if (this.samplingRatio == 0) + { + return DropSamplingResult; + } + + if (this.samplingRatio == 1) + { + return this.recordAndSampleSamplingResult; + } + double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToLowerInvariant()); - return new SamplingResult(sampleScore < this.samplingRatio); + + if (sampleScore < this.samplingRatio) + { + return this.recordAndSampleSamplingResult; + } + else + { + return DropSamplingResult; + } } private static double DJB2SampleScore(string traceIdHex) From e53ae411762c7dba10bf7f6f0df9fe19353e6228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Thu, 8 Sep 2022 20:05:53 +0200 Subject: [PATCH 0321/1499] Instrumentation.AwsLambda: Remove input-less Trace overloads. (#622) * Instrumentation.AwsLambda: Remove input-less Trace overloads. --- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 - .../AWSLambdaWrapper.cs | 45 ---------------- .../CHANGELOG.md | 2 - .../AWSLambdaWrapperTests.cs | 52 ------------------- .../SampleHandlers.cs | 13 +---- 5 files changed, 1 insertion(+), 113 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e4c64baf9c..78ca482d91 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -4,10 +4,8 @@ OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableA OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction.set -> void OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions -static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Action lambdaHandler, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> TResult static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Action lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void -static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func> lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 84c5c7a0d8..17fa2de592 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -99,28 +99,6 @@ public static void Trace( TraceInternal(tracerProvider, action, input, context, parentContext); } - /// - /// Tracing wrapper for Lambda handler. - /// - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of lambda context. - /// - /// The optional parent context is used for Activity object creation. - /// If no parent context provided, incoming request is used to extract one. - /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one - /// unless X-Ray propagation is disabled in the configuration for this wrapper. - /// - public static void Trace( - TracerProvider tracerProvider, - Action lambdaHandler, - ILambdaContext context, - ActivityContext parentContext = default) - { - Action action = () => lambdaHandler(context); - TraceInternal(tracerProvider, action, null, context, parentContext); - } - /// /// Tracing wrapper for async Lambda handler. /// @@ -176,29 +154,6 @@ public static async Task TraceAsync( return result; } - /// - /// Tracing wrapper for async Lambda handler. - /// - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of lambda context. - /// - /// The optional parent context is used for Activity object creation. - /// If no parent context provided, incoming request is used to extract one. - /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one - /// unless X-Ray propagation is disabled in the configuration. - /// - /// Task. - public static Task TraceAsync( - TracerProvider tracerProvider, - Func lambdaHandler, - ILambdaContext context, - ActivityContext parentContext = default) - { - Func action = async () => await lambdaHandler(context); - return TraceInternalAsync(tracerProvider, action, null, context, parentContext); - } - #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 7af903a7bb..876cf57b24 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -22,8 +22,6 @@ if the parent context is not defined. * Breaking change: `AWSLambdaWrapper.Trace` overloads without `ILambdaContext` argument have been completely removed. -* Added two new `AWSLambdaWrapper.Trace` overloads without generic input arguments. - ([#408](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/408)) ## 1.1.0-beta1 diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 3e3d9d633a..b29f315d82 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -98,32 +98,6 @@ public void TraceSyncWithInputAndNoReturn(bool setCustomParent) this.AssertSpanAttributes(activity); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void TraceSyncWithNoInputAndNoReturn(bool setCustomParent) - { - var processor = new Mock>(); - - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) - { - var parentContext = setCustomParent ? CreateParentContext() : default; - AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoInputAndNoReturn, this.sampleLambdaContext, parentContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } - - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); - - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - } - [Theory] [InlineData(false)] [InlineData(true)] @@ -176,32 +150,6 @@ public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) this.AssertSpanAttributes(activity); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task TraceAsyncWithNoInputAndNoReturn(bool setCustomParent) - { - var processor = new Mock>(); - - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) - { - var parentContext = setCustomParent ? CreateParentContext() : default; - await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncNoInputAndNoReturn, this.sampleLambdaContext, parentContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } - - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); - - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - } - [Theory] [InlineData(false)] [InlineData(true)] diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 456c43aa62..958c3e97a6 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -20,18 +20,13 @@ namespace OpenTelemetry.Instrumentation.AWSLambda.Tests { - public class SampleHandlers + internal class SampleHandlers { // Action public void SampleHandlerSyncInputAndNoReturn(string str, ILambdaContext context) { } - // Action - public void SampleHandlerSyncNoInputAndNoReturn(ILambdaContext context) - { - } - // Func public string SampleHandlerSyncInputAndReturn(string str, ILambdaContext context) { @@ -51,12 +46,6 @@ public async Task SampleHandlerAsyncInputAndReturn(string str, ILambdaCo return str; } - // Func - public async Task SampleHandlerAsyncNoInputAndNoReturn(ILambdaContext context) - { - await Task.Delay(10); - } - public void SampleHandlerSyncNoReturnException(string str, ILambdaContext context) { throw new Exception(str); From 82514f87f10c339131d94da3bd75d96698e41eee Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 9 Sep 2022 14:14:13 -0700 Subject: [PATCH 0322/1499] simply the code (#627) --- .../RuntimeMetrics.cs | 31 +++++++++---------- .../RuntimeMetricsTests.cs | 2 -- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 26057cec91..ac7d89da01 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -40,7 +40,6 @@ internal class RuntimeMetrics private const long NanosecondsPerTick = 100; #endif private const int NumberOfGenerations = 3; - private const string MetricPrefix = "process.runtime.dotnet."; private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; private static bool isGcInfoAvailable; @@ -48,13 +47,13 @@ internal class RuntimeMetrics static RuntimeMetrics() { MeterInstance.CreateObservableCounter( - $"{MetricPrefix}gc.collections.count", + "process.runtime.dotnet.gc.collections.count", () => GetGarbageCollectionCounts(), description: "Number of garbage collections that have occurred since process start."); #if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( - $"{MetricPrefix}gc.allocations.size", + "process.runtime.dotnet.gc.allocations.size", () => GC.GetTotalAllocatedBytes(), unit: "bytes", description: "Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); @@ -63,7 +62,7 @@ static RuntimeMetrics() #if NET6_0_OR_GREATER // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}gc.committed_memory.size", + "process.runtime.dotnet.gc.committed_memory.size", () => { if (!IsGcInfoAvailable) @@ -93,7 +92,7 @@ static RuntimeMetrics() { // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}gc.heap.size", + "process.runtime.dotnet.gc.heap.size", () => { if (!IsGcInfoAvailable) @@ -127,7 +126,7 @@ static RuntimeMetrics() { // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}gc.heap.fragmentation.size", + "process.runtime.dotnet.gc.heap.fragmentation.size", () => { if (!IsGcInfoAvailable) @@ -152,18 +151,18 @@ static RuntimeMetrics() #if NET6_0_OR_GREATER MeterInstance.CreateObservableCounter( - $"{MetricPrefix}jit.il_compiled.size", + "process.runtime.dotnet.jit.il_compiled.size", () => JitInfo.GetCompiledILBytes(), unit: "bytes", description: "Count of bytes of intermediate language that have been compiled since the process start."); MeterInstance.CreateObservableCounter( - $"{MetricPrefix}jit.methods_compiled.count", + "process.runtime.dotnet.jit.methods_compiled.count", () => JitInfo.GetCompiledMethodCount(), description: "The number of times the JIT compiler compiled a method since the process start. The JIT compiler may be invoked multiple times for the same method to compile with different generic parameters, or because tiered compilation requested different optimization settings."); MeterInstance.CreateObservableCounter( - $"{MetricPrefix}jit.compilation_time", + "process.runtime.dotnet.jit.compilation_time", () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, unit: "ns", description: "The amount of time the JIT compiler has spent compiling methods since the process start."); @@ -171,42 +170,42 @@ static RuntimeMetrics() #if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( - $"{MetricPrefix}monitor.lock_contention.count", + "process.runtime.dotnet.monitor.lock_contention.count", () => Monitor.LockContentionCount, description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}thread_pool.threads.count", + "process.runtime.dotnet.thread_pool.threads.count", () => (long)ThreadPool.ThreadCount, description: "The number of thread pool threads that currently exist."); MeterInstance.CreateObservableCounter( - $"{MetricPrefix}thread_pool.completed_items.count", + "process.runtime.dotnet.thread_pool.completed_items.count", () => ThreadPool.CompletedWorkItemCount, description: "The number of work items that have been processed by the thread pool since the process start."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}thread_pool.queue.length", + "process.runtime.dotnet.thread_pool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "The number of work items that are currently queued to be processed by the thread pool."); // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}timer.count", + "process.runtime.dotnet.timer.count", () => Timer.ActiveCount, description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); #endif // TODO: change to ObservableUpDownCounter MeterInstance.CreateObservableGauge( - $"{MetricPrefix}assemblies.count", + "process.runtime.dotnet.assemblies.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "The number of .NET assemblies that are currently loaded."); var exceptionCounter = MeterInstance.CreateCounter( - $"{MetricPrefix}exceptions.count", + "process.runtime.dotnet.exceptions.count", description: "Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization."); AppDomain.CurrentDomain.FirstChanceException += (source, e) => diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 750568c534..56640da0ca 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -29,7 +29,6 @@ namespace OpenTelemetry.Instrumentation.Runtime.Tests; public class RuntimeMetricsTests { private const int MaxTimeToAllowForFlush = 10000; - private const string MetricPrefix = "process.runtime.dotnet."; [Fact] public void RuntimeMetricsAreCaptured() @@ -52,7 +51,6 @@ public void RuntimeMetricsAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.True(exportedItems.Count > 1); - Assert.StartsWith(MetricPrefix, exportedItems[0].Name); var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); Assert.NotNull(assembliesCountMetric); From de6091fb786a734e1120188c3badf8140a87ed4f Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Fri, 9 Sep 2022 14:23:09 -0700 Subject: [PATCH 0323/1499] changelog (#628) --- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 1512c42162..9ca238ac4a 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -1,3 +1,8 @@ # Changelog -## Unreleased +## 1.0.0-beta.1 + +Released 2022-Sept-12 + +* Add "sampleRate" to `SamplingResult`. + ([#623](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/623)) From 5905dd826f51a67965f03740012e23ee1b7e3ca3 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 12 Sep 2022 12:21:25 -0700 Subject: [PATCH 0324/1499] [Extensions.AzureMonitor] Add package release workflow for OpenTelemetry.Extensions.AzureMonitor (#629) --- .../package-Extensions.AzureMonitor.yml | 49 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 1 + 2 files changed, 50 insertions(+) create mode 100644 .github/workflows/package-Extensions.AzureMonitor.yml diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml new file mode 100644 index 0000000000..8a6b44849b --- /dev/null +++ b/.github/workflows/package-Extensions.AzureMonitor.yml @@ -0,0 +1,49 @@ +name: Pack OpenTelemetry.Extensions.AzureMonitor + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Extensions.AzureMonitor-*' # trigger when we create a tag with prefix "Extensions.AzureMonitor-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Extensions.AzureMonitor + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - name: Install dependencies + run: dotnet restore + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions.AzureMonitor has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index abb856fd7e..fd5b53819f 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -37,6 +37,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml + .github\workflows\package-Extensions.AzureMonitor.yml = .github\workflows\package-Extensions.AzureMonitor.yml .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml From 32adb50b157a10a95ff9dd6ff415f2d2663b2116 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 12 Sep 2022 16:21:43 -0700 Subject: [PATCH 0325/1499] Update MinVer config (#630) --- .../OpenTelemetry.Extensions.AzureMonitor.csproj | 3 ++- src/OpenTelemetry.Extensions.AzureMonitor/README.md | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 53941035d0..7e59b7c26a 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -1,7 +1,8 @@ - + net461;net6.0 + Extensions.AzureMonitor- diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/README.md b/src/OpenTelemetry.Extensions.AzureMonitor/README.md index 2cef918157..a6c676cf4e 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/README.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/README.md @@ -1,5 +1,8 @@ # Application Insights Sampler for OpenTelemetry .NET +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AzureMonitor.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.AzureMonitor.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) + The ```Application Insights Sampler``` should be utilized when compatibility with Application Insights SDKs is desired, as it implements the same hash algorithm when deciding to sample telemetry. From 9f14538a111a6a6bb92f246dae77ef0a7b26caad Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 12 Sep 2022 16:36:34 -0700 Subject: [PATCH 0326/1499] Update OTel SDK version to 1.3.1 (#631) --- build/Common.props | 2 +- .../Examples.StackExchangeRedis.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/Common.props b/build/Common.props index ebba96dab9..505c5d2725 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,7 +31,7 @@ [4.1.1] [3.3.2] [1.0.0,2.0) - [1.3.0,2.0) + [1.3.1,2.0) $(OpenTelemetryApiPkgVer) [2.1.58,3.0) [1.2.0-beta.354,2.0) diff --git a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj index a71e757976..b4770eaf60 100644 --- a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj +++ b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj @@ -8,7 +8,7 @@ - + From f20bbfaa39da5ce776b363e539dac44c0317e2b0 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 12 Sep 2022 17:00:08 -0700 Subject: [PATCH 0327/1499] Update README for projects missing the number of downloads (#632) --- .../README.md | 1 + src/OpenTelemetry.Instrumentation.Wcf/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index c2d88b999b..1b3bbe8af1 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -1,6 +1,7 @@ # ASP.NET Telemetry HttpModule for OpenTelemetry [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) The ASP.NET Telemetry HttpModule enables distributed tracing of incoming ASP.NET requests using the OpenTelemetry API. diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 47b2c0f7b9..8f1cf1b389 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -1,6 +1,7 @@ # WCF Instrumentation for OpenTelemetry .NET [![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) +[![nuget](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Wcf.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) Instruments WCF clients and/or services using implementations of `IClientMessageInspector` and `IDispatchMessageInspector` respectively. From 713c4e1517802841271b23463e81e68bd56d9b08 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 12 Sep 2022 17:29:43 -0700 Subject: [PATCH 0328/1499] Replaced TargetFrameworks from net461 and net6.0 to netstandard2.0 (#633) --- .../ApplicationInsightsSampler.cs | 2 +- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 7 +++++++ .../OpenTelemetry.Extensions.AzureMonitor.csproj | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 199da579de..8945c5721d 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -41,7 +41,7 @@ public ApplicationInsightsSampler(float samplingRatio) this.samplingRatio = samplingRatio; this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; - var sampleRate = (int)Math.Round(samplingRatio * 100); + var sampleRate = (float)Math.Round(samplingRatio * 100); this.recordAndSampleSamplingResult = new SamplingResult( SamplingDecision.RecordAndSample, new Dictionary diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 9ca238ac4a..29c22491fa 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.0.0-beta.2 + +Released 2022-Sept-12 + +* Replaced TargetFrameworks from `net461` and `net6.0` to `netstandard2.0`. +* Changed `sampleRate` attribute type to `float`. + ## 1.0.0-beta.1 Released 2022-Sept-12 diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 7e59b7c26a..18d1eeca8a 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -1,7 +1,9 @@ - net461;net6.0 + netstandard2.0 + $(TargetFrameworks);net462 + $(TargetFrameworks);net6.0 Extensions.AzureMonitor- From e65cbbff428f176980f06cd2454c457fbdbf8955 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 12 Sep 2022 17:41:52 -0700 Subject: [PATCH 0329/1499] Add PR link to changelog (#634) --- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 29c22491fa..11e3ef4a0e 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -5,7 +5,9 @@ Released 2022-Sept-12 * Replaced TargetFrameworks from `net461` and `net6.0` to `netstandard2.0`. + ([#633](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/633)) * Changed `sampleRate` attribute type to `float`. + ([#633](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/633)) ## 1.0.0-beta.1 From 13a8dd4dc8d696de508f8da56d2f9cc2d0154ec0 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 12 Sep 2022 22:14:17 -0700 Subject: [PATCH 0330/1499] Add 462 TargetFramework to changelog. (#635) --- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 11e3ef4a0e..6afa9efb18 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -4,7 +4,8 @@ Released 2022-Sept-12 -* Replaced TargetFrameworks from `net461` and `net6.0` to `netstandard2.0`. +* Replaced TargetFrameworks from `net461` and `net6.0` to `netstandard2.0` and + `net462`. ([#633](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/633)) * Changed `sampleRate` attribute type to `float`. ([#633](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/633)) From 6a27f680bbe143c9b266358f279ab28b4e026673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 13 Sep 2022 16:32:16 +0200 Subject: [PATCH 0331/1499] Changelog for update to 1.3.1 OTel SDK release (#636) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 12 +++++++++--- .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ 7 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index d6ded992f5..22111fd53a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + ## 1.4.0-beta.1 Released 2022-Aug-01 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index d5b01dd16d..2706a6ae7f 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -1,20 +1,26 @@ # Changelog +* Update OTel SDK version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + ## Unreleased -* Updated OTel API package version to 1.3.0 ([#522](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/522)) +* Updated OTel API package version to 1.3.0 + ([#522](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/522)) ## 1.0.0-beta.2 Released 2022-Jul-14 -* Added client side instrumentation for jobs ([#421](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/421)) +* Added client side instrumentation for jobs + ([#421](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/421)) ## 1.0.0-beta.1 Released 2022-Jun-03 -* Updated OTel API package version to 1.2.0 ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) +* Updated OTel API package version to 1.2.0 + ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) ## Initial Release diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 5cec97f129..cc18433fbb 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OTel SDK package version to 1.3.0 - ([#508](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/508)) +* Update OTel SDK version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md new file mode 100644 index 0000000000..1512c42162 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +## Unreleased diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index d9cadc760e..75a61a000a 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + ## 1.0.0 Released 2022-Aug-03 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 22d6ab282a..be4af01947 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + ## 1.0.0-rc9.7 Released 2022-Jul-25 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index b590c3e280..cc6fc94fce 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + ## 1.0.0-rc.7 Released 2022-Aug-23 From 2a092cb1029a149e99b0315cd0c573827e96373f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Wed, 14 Sep 2022 00:02:20 +0200 Subject: [PATCH 0332/1499] [Instrumentation.AWSLambda] Request release of 1.1.0-beta2, reword CHANGELOG (#590) --- .../CHANGELOG.md | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 876cf57b24..b8623e83f8 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,26 +2,33 @@ ## Unreleased -* Breaking change: Rename package to OpenTelemetry.Instrumentation.AWSLambda - (remove ".Contrib") ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) -* Breaking change: Move public class AWSLambdaWrapper out of Implementation subnamespace +## 1.1.0-beta2 + +Release PR: [#590](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/590) + +This is the first release with the new package name `OpenTelemetry.Instrumentation.AWSLambda`. + +* BREAKING (API, behavior): Rename package to `OpenTelemetry.Instrumentation.AWSLambda` + (remove `.Contrib`) ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)). + This also affects the `ActivitySource` name (superseding [#534](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/534)). +* BREAKING (API): Move public class `AWSLambdaWrapper` out of `Implementation` subnamespace ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) -* Add version to ActivitySource ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) -* Updated the `ActivitySource` name to the assembly name: - `OpenTelemetry.Instrumentation.AWSLambda` - ([#534](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/534)) -* Added public option `AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction`. -* Extended public API of the `AWSLambdaWrapper`: added optional parent - context (`ActivityContext`) to all `Trace` methods. -* Enhanced parent extraction: if the parent context is not provided - then it can be extracted from the incoming request for certain types of the request. - If the parent is not extracted from the incoming request then it can be extracted - from the AWS X-Ray tracing header if AWS X-Ray context extraction - is not disabled (`DisableAwsXRayContextExtraction`). -* Changed behaviour of the `OnFunctionStart` method: Activity is created even - if the parent context is not defined. -* Breaking change: `AWSLambdaWrapper.Trace` overloads without `ILambdaContext` argument - have been completely removed. +* BREAKING (API): Rename overloads of `AWSLambdaWrapper.Trace` that take an async + handler to `TraceAsync`, to emphasize that they (usually) need to be awaited. + ([#608](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/608)) +* Rewrite of parent context handling and related changes + ([#408](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/408)): + * BREAKING (API): Remove `AWSLambdaWrapper.Trace`/`TraceAsync` overloads + without `ILambdaContext` parameter. + * BREAKING (behavior): Add automatic parent extraction from HTTP triggers + (API Gateway Proxy events), using the configured global textmap propagator. + * BREAKING (behavior): An activity is now also created if no parent context + could be extracted (previously this package would only create activities if + a valid parent span context could be extracted with X-Ray). + * Add optional parent context (`ActivityContext`) to `AWSLambdaWrapper.Trace`/`TraceAsync`. + * Add `AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction` + initialization option. +* Add version to `ActivitySource` ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) ## 1.1.0-beta1 From d0f1ea14c59113da1b60fdaf5369a39c15594bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 14 Sep 2022 01:32:35 +0200 Subject: [PATCH 0333/1499] [Instrumentation.MassTransit] Bump OTel, .NET frameworks, cleanup (#637) * [Instrumentation.MassTransit] Bump OTel SDK to 1.3.1 * [Instrumentation.MassTransit] Drop support for .NET Framework 4.6.1 as it is deprecated. --- .../CHANGELOG.md | 7 +++++-- ...penTelemetry.Instrumentation.MassTransit.csproj | 6 +++--- .../MassTransitInstrumentationTests.cs | 14 +++++++------- ...emetry.Instrumentation.MassTransit.Tests.csproj | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md index 0dfc15b6ec..5905af4a18 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased -* Updated OTel SDK package version to 1.2.0 - [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) +* Update OTel SDK version to `1.3.1`. + ([#637](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/637)) +* Remove .NET Framework 4.6.1. The minimum .NET Framework version supported is + .NET Framework 4.6.2 (by .NET Standard 2.0). + ([#637](https://github.com/open-telemetry/opentelemetry-dotnet/issues/637)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj index b546b34d47..430f2c5628 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj @@ -1,13 +1,13 @@ - + - netstandard2.0;net461 + netstandard2.0 OpenTelemetry instrumentation for MassTransit $(PackageTags);distributed-tracing;MassTransit Instrumentation.MassTransit- true - + diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs index 95feb345ac..542f643697 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs @@ -274,7 +274,7 @@ await harness.InputQueueSendEndpoint.Send(new } [Fact] - public async Task ShouldMapMassTransitTagsWhenIntrumentationIsSuppressed() + public async Task ShouldMapMassTransitTagsWhenInstrumentationIsSuppressed() { var activityProcessor = new Mock>(); using (Sdk.CreateTracerProviderBuilder() @@ -304,19 +304,19 @@ public async Task ShouldMapMassTransitTagsWhenIntrumentationIsSuppressed() Assert.NotNull(expectedMessageContext); } - // Since instrumentation is suppressed, activiy is not emitted + // Since instrumentation is suppressed, activity is not emitted Assert.Equal(3, activityProcessor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose // Processor.OnStart and Processor.OnEnd are not called - Assert.DoesNotContain(activityProcessor.Invocations, invo => invo.Method.Name == nameof(activityProcessor.Object.OnStart)); - Assert.DoesNotContain(activityProcessor.Invocations, invo => invo.Method.Name == nameof(activityProcessor.Object.OnEnd)); + Assert.DoesNotContain(activityProcessor.Invocations, invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnStart)); + Assert.DoesNotContain(activityProcessor.Invocations, invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnEnd)); } [Theory] [InlineData(SamplingDecision.Drop, false)] [InlineData(SamplingDecision.RecordOnly, true)] [InlineData(SamplingDecision.RecordAndSample, true)] - public async Task ShouldMapMassTransitTagsWhenIntrumentationWhenSampled(SamplingDecision samplingDecision, bool isActivityExpected) + public async Task ShouldMapMassTransitTagsWhenInstrumentationWhenSampled(SamplingDecision samplingDecision, bool isActivityExpected) { var activityProcessor = new Mock>(); using (Sdk.CreateTracerProviderBuilder() @@ -346,8 +346,8 @@ public async Task ShouldMapMassTransitTagsWhenIntrumentationWhenSampled(Sampling Assert.NotNull(expectedMessageContext); } - Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invo => invo.Method.Name == nameof(activityProcessor.Object.OnStart))); - Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invo => invo.Method.Name == nameof(activityProcessor.Object.OnEnd))); + Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnStart))); + Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnEnd))); } private IEnumerable GetActivitiesFromInvocationsByOperationName(IEnumerable invocations, string operationName) diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj index c012240945..157667046f 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj @@ -1,9 +1,9 @@ - + Unit test project for OpenTelemetry MassTransit instrumentation netcoreapp3.1;net6.0 - $(TargetFrameworks);net461 + $(TargetFrameworks);net462 true From 700785548b98f3c84e3d094a8a4e3cceb421dc51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 14 Sep 2022 06:55:44 +0200 Subject: [PATCH 0334/1499] Bump to 1.3.1 -fix changelog (#638) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 9 +++------ src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 2 +- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 2 +- .../CHANGELOG.md | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 2706a6ae7f..f1f0af7179 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -1,12 +1,9 @@ # Changelog -* Update OTel SDK version to `1.3.1`. - ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) - ## Unreleased -* Updated OTel API package version to 1.3.0 - ([#522](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/522)) +* Update OTel API version to `1.3.1`. + ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) ## 1.0.0-beta.2 @@ -19,7 +16,7 @@ Released 2022-Jul-14 Released 2022-Jun-03 -* Updated OTel API package version to 1.2.0 +* Updated OTel API package version to `1.2.0` ([#353](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/353)) ## Initial Release diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index cc18433fbb..e4f9db9cbc 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* Update OTel SDK version to `1.3.1`. +* Update OTel API version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 75a61a000a..a67c0ffee6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* Update OTel SDK version to `1.3.1`. +* Update OTel API version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) ## 1.0.0 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index be4af01947..71c9d2b7ab 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* Update OTel SDK version to `1.3.1`. +* Update OTel API version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) ## 1.0.0-rc9.7 From 62a20d10c9cdf152d2c42015be3d39e028a68e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Wed, 14 Sep 2022 22:49:13 +0200 Subject: [PATCH 0335/1499] Instrumentation.AwsLambda: Fix versioning scheme. (#639) --- src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index b8623e83f8..db388af70c 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,15 +2,17 @@ ## Unreleased -## 1.1.0-beta2 +## 1.1.0-beta.2 Release PR: [#590](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/590) +& [#639](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/639). This is the first release with the new package name `OpenTelemetry.Instrumentation.AWSLambda`. * BREAKING (API, behavior): Rename package to `OpenTelemetry.Instrumentation.AWSLambda` (remove `.Contrib`) ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)). This also affects the `ActivitySource` name (superseding [#534](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/534)). +* Pre-release version numbering scheme changed from `.betaN` to `beta.N` ([#639](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/639)) * BREAKING (API): Move public class `AWSLambdaWrapper` out of `Implementation` subnamespace ([#593](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/593)) * BREAKING (API): Rename overloads of `AWSLambdaWrapper.Trace` that take an async From a83fa0856be7b2bfa2998e5847787ab1733f2af3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Sep 2022 17:47:25 -0700 Subject: [PATCH 0336/1499] Remove unused Activity reflection code (#641) --- .../Api/ActivityHelperExtensions.cs | 233 +----------------- 1 file changed, 5 insertions(+), 228 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs index 7fdcdefc14..7e49b4d713 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs @@ -27,37 +27,6 @@ namespace OpenTelemetry.Trace; /// internal static class ActivityHelperExtensions { - /// - /// 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. - /// - /// Activity instance. - /// . - /// Status description. - /// if was found on the supplied Activity. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static bool TryGetStatus(this Activity activity, out StatusCode statusCode, out string statusDescription) - { - Debug.Assert(activity != null, "Activity should not be null"); - - ActivityStatusTagEnumerator state = default; - - ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); - - if (!state.StatusCode.HasValue) - { - statusCode = default; - statusDescription = null; - return false; - } - - statusCode = state.StatusCode.Value; - statusDescription = state.StatusDescription; - return true; - } - /// /// Gets the value of a specific tag on an . /// @@ -70,6 +39,11 @@ public static object GetTagValue(this Activity activity, string tagName) { Debug.Assert(activity != null, "Activity should not be null"); + // TODO: Update to use + // https://docs.microsoft.com/dotnet/api/system.diagnostics.activity.enumeratetagobjects?view=net-7.0 + // instead of reflection. See: + // https://github.com/open-telemetry/opentelemetry-dotnet/blob/928d77056c1d353d8ba72ad3b4b565398117b352/src/OpenTelemetry.Api/Internal/ActivityHelperExtensions.cs#L85-L98 + ActivitySingleTagEnumerator state = new ActivitySingleTagEnumerator(tagName); ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); @@ -77,82 +51,6 @@ public static object GetTagValue(this Activity activity, string tagName) return state.Value; } - /// - /// Enumerates all the key/value pairs on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// Activity instance. - /// Tag enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateTags(this Activity activity, ref T tagEnumerator) - where T : struct, IActivityEnumerator> - { - Debug.Assert(activity != null, "Activity should not be null"); - - ActivityTagsEnumeratorFactory.Enumerate(activity, ref tagEnumerator); - } - - /// - /// Enumerates all the s on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// Activity instance. - /// Link enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateLinks(this Activity activity, ref T linkEnumerator) - where T : struct, IActivityEnumerator - { - Debug.Assert(activity != null, "Activity should not be null"); - - ActivityLinksEnumeratorFactory.Enumerate(activity, ref linkEnumerator); - } - - /// - /// Enumerates all the key/value pairs on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// ActivityLink instance. - /// Tag enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateTags(this ActivityLink activityLink, ref T tagEnumerator) - where T : struct, IActivityEnumerator> - { - ActivityTagsEnumeratorFactory.Enumerate(activityLink, ref tagEnumerator); - } - - /// - /// Enumerates all the s on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// Activity instance. - /// Event enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateEvents(this Activity activity, ref T eventEnumerator) - where T : struct, IActivityEnumerator - { - Debug.Assert(activity != null, "Activity should not be null"); - - ActivityEventsEnumeratorFactory.Enumerate(activity, ref eventEnumerator); - } - - /// - /// Enumerates all the key/value pairs on an without performing an allocation. - /// - /// The struct implementation to use for the enumeration. - /// ActivityEvent instance. - /// Tag enumerator. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static void EnumerateTags(this ActivityEvent activityEvent, ref T tagEnumerator) - where T : struct, IActivityEnumerator> - { - ActivityTagsEnumeratorFactory.Enumerate(activityEvent, ref tagEnumerator); - } - private struct ActivitySingleTagEnumerator : IActivityEnumerator> { public object Value; @@ -177,42 +75,15 @@ public bool ForEach(KeyValuePair item) } } - private struct ActivityStatusTagEnumerator : IActivityEnumerator> - { - public StatusCode? StatusCode; - - public string StatusDescription; - - public bool ForEach(KeyValuePair item) - { - switch (item.Key) - { - case SpanAttributeConstants.StatusCodeKey: - this.StatusCode = StatusHelper.GetStatusCodeForTagValue(item.Value as string); - break; - case SpanAttributeConstants.StatusDescriptionKey: - this.StatusDescription = item.Value as string; - break; - } - - return !this.StatusCode.HasValue || this.StatusDescription == null; - } - } - private static class ActivityTagsEnumeratorFactory where TState : struct, IActivityEnumerator> { private static readonly object EmptyActivityTagObjects = typeof(Activity).GetField("s_emptyTagObjects", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - private static readonly object EmptyActivityEventTags = typeof(ActivityEvent).GetField("s_emptyTags", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate ActivityTagObjectsEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate( typeof(Activity).GetField("_tags", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate - ActivityTagsCollectionEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate(typeof(ActivityTagsCollection)); - private static readonly DictionaryEnumerator.ForEachDelegate ForEachTagValueCallbackRef = ForEachTagValueCallback; [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -231,101 +102,7 @@ public static void Enumerate(Activity activity, ref TState state) ForEachTagValueCallbackRef); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(ActivityLink activityLink, ref TState state) - { - var tags = activityLink.Tags; - - if (tags is null) - { - return; - } - - ActivityTagsCollectionEnumerator( - tags, - ref state, - ForEachTagValueCallbackRef); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(ActivityEvent activityEvent, ref TState state) - { - var tags = activityEvent.Tags; - - if (ReferenceEquals(tags, EmptyActivityEventTags)) - { - return; - } - - ActivityTagsCollectionEnumerator( - tags, - ref state, - ForEachTagValueCallbackRef); - } - private static bool ForEachTagValueCallback(ref TState state, KeyValuePair item) => state.ForEach(item); } - - private static class ActivityLinksEnumeratorFactory - where TState : struct, IActivityEnumerator - { - private static readonly object EmptyActivityLinks = typeof(Activity).GetField("s_emptyLinks", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - - private static readonly ListEnumerator.AllocationFreeForEachDelegate - ActivityLinksEnumerator = ListEnumerator.BuildAllocationFreeForEachDelegate( - typeof(Activity).GetField("_links", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - - private static readonly ListEnumerator.ForEachDelegate ForEachLinkCallbackRef = ForEachLinkCallback; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(Activity activity, ref TState state) - { - var activityLinks = activity.Links; - - if (ReferenceEquals(activityLinks, EmptyActivityLinks)) - { - return; - } - - ActivityLinksEnumerator( - activityLinks, - ref state, - ForEachLinkCallbackRef); - } - - private static bool ForEachLinkCallback(ref TState state, ActivityLink item) - => state.ForEach(item); - } - - private static class ActivityEventsEnumeratorFactory - where TState : struct, IActivityEnumerator - { - private static readonly object EmptyActivityEvents = typeof(Activity).GetField("s_emptyEvents", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - - private static readonly ListEnumerator.AllocationFreeForEachDelegate - ActivityEventsEnumerator = ListEnumerator.BuildAllocationFreeForEachDelegate( - typeof(Activity).GetField("_events", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - - private static readonly ListEnumerator.ForEachDelegate ForEachEventCallbackRef = ForEachEventCallback; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(Activity activity, ref TState state) - { - var activityEvents = activity.Events; - - if (ReferenceEquals(activityEvents, EmptyActivityEvents)) - { - return; - } - - ActivityEventsEnumerator( - activityEvents, - ref state, - ForEachEventCallbackRef); - } - - private static bool ForEachEventCallback(ref TState state, ActivityEvent item) - => state.ForEach(item); - } } From 80efab006a74d6edf25789cfa5a4ccc615094474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 15 Sep 2022 22:51:00 +0200 Subject: [PATCH 0337/1499] [Instrumentation.MassTransit] PublicApi verification (#642) --- .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 14 ++++++++++++++ ...penTelemetry.Instrumentation.MassTransit.csproj | 1 + 3 files changed, 15 insertions(+) create mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7eb6a114de --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,14 @@ +const OpenTelemetry.Instrumentation.MassTransit.OperationName.Consumer.Consume = "MassTransit.Consumer.Consume" -> string +const OpenTelemetry.Instrumentation.MassTransit.OperationName.Consumer.Handle = "MassTransit.Consumer.Handle" -> string +const OpenTelemetry.Instrumentation.MassTransit.OperationName.Transport.Receive = "MassTransit.Transport.Receive" -> string +const OpenTelemetry.Instrumentation.MassTransit.OperationName.Transport.Send = "MassTransit.Transport.Send" -> string +OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions +OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.MassTransitInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet +OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.TracedOperations.set -> void +OpenTelemetry.Instrumentation.MassTransit.OperationName +OpenTelemetry.Instrumentation.MassTransit.OperationName.Consumer +OpenTelemetry.Instrumentation.MassTransit.OperationName.Transport +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMassTransitInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureMassTransitInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static readonly OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.DefaultTracedOperations -> System.Collections.Generic.IEnumerable diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj index 430f2c5628..b9bc4618d7 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj @@ -5,6 +5,7 @@ $(PackageTags);distributed-tracing;MassTransit Instrumentation.MassTransit- true + true From 172bdc0c29f252bdbcb8d264389f1e1463fbccd1 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Thu, 15 Sep 2022 14:35:30 -0700 Subject: [PATCH 0338/1499] documentation (#643) --- .../ApplicationInsightsSampler.cs | 5 ++++- src/OpenTelemetry.Extensions.AzureMonitor/README.md | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 8945c5721d..04198a1078 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -33,7 +33,10 @@ public class ApplicationInsightsSampler : Sampler /// /// Initializes a new instance of the class. /// - /// Ratio of telemetry that should be sampled. + /// + /// Ratio of telemetry that should be sampled. + /// For example; Specifying 0.4F means 40% of traces are sampled and 60% are dropped. + /// public ApplicationInsightsSampler(float samplingRatio) { // Ensure passed ratio is between 0 and 1, inclusive diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/README.md b/src/OpenTelemetry.Extensions.AzureMonitor/README.md index a6c676cf4e..240aa20b5c 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/README.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/README.md @@ -13,6 +13,18 @@ implements the same hash algorithm when deciding to sample telemetry. dotnet add package OpenTelemetry.Extensions.AzureMonitor ``` +## Usage + +You can configure the `ApplicationInsightsSampler` with the following example. +In this example the `samplingRatio` has been set to `0.4F`. +This means 40% of traces are sampled and the remaining 60% will be dropped. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new ApplicationInsightsSampler(0.4F)) + .Build(); +``` + ## References * [OpenTelemetry Project](https://opentelemetry.io/) From 64d9773119f5501d947bea9422267c61aac3109c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Sat, 17 Sep 2022 01:53:58 +0200 Subject: [PATCH 0339/1499] AWS projects Filescope namespace (#644) --- .../AWSXRayEventSource.cs | 103 ++-- .../AWSXRayIdGenerator.cs | 257 +++++----- .../Resources/AWSEBSResourceDetector.cs | 95 ++-- .../Resources/AWSEC2ResourceDetector.cs | 127 +++-- .../Resources/AWSECSResourceDetector.cs | 105 +++-- .../Resources/AWSEKSResourceDetector.cs | 203 ++++---- .../Resources/AWSLambdaResourceDetector.cs | 91 ++-- .../Resources/AWSSemanticConventions.cs | 43 +- .../Resources/Http/Handler.cs | 43 +- .../ServerCertificateValidationProvider.cs | 191 ++++---- .../Resources/IResourceDetector.cs | 21 +- .../Resources/Models/AWSEBSMetadataModel.cs | 19 +- .../Models/AWSEC2IdentityDocumentModel.cs | 17 +- .../Models/AWSEKSClusterDataModel.cs | 11 +- .../Models/AWSEKSClusterInformationModel.cs | 9 +- .../Resources/ResourceBuilderExtensions.cs | 37 +- .../Resources/ResourceDetectorUtils.cs | 65 ++- .../Trace/AWSXRayPropagator.cs | 439 +++++++++--------- .../TracerProviderBuilderExtensions.cs | 53 ++- .../AWSClientInstrumentationOptions.cs | 17 +- .../AWSClientsInstrumentation.cs | 11 +- .../Implementation/AWSSemanticConventions.cs | 25 +- .../Implementation/AWSServiceHelper.cs | 59 ++- .../AWSTracingPipelineCustomizer.cs | 37 +- .../AWSTracingPipelineHandler.cs | 291 ++++++------ .../Implementation/Utils.cs | 83 ++-- .../TracerProviderBuilderExtensions.cs | 39 +- .../AWSLambdaInstrumentationOptions.cs | 17 +- .../AWSLambdaWrapper.cs | 373 ++++++++------- .../AWSLambdaResourceDetector.cs | 31 +- .../AWSLambdaSemanticConventions.cs | 29 +- .../Implementation/AWSLambdaUtils.cs | 281 ++++++----- .../TracerProviderBuilderExtensions.cs | 49 +- .../TracerProviderBuilderExtensions.cs | 47 +- .../Resources/Http/CertificateUploader.cs | 87 ++-- .../Resources/Http/TestHandler.cs | 35 +- ...TestServerCertificateValidationProvider.cs | 57 ++- .../Resources/SampleAWSEBSMetadataModel.cs | 15 +- .../SampleAWSEC2IdentityDocumentModel.cs | 19 +- .../Resources/TestAWSEBSResourceDetector.cs | 67 ++- .../Resources/TestAWSEC2ResourceDetector.cs | 75 ++- .../Resources/TestAWSECSResourceDetector.cs | 93 ++-- .../Resources/TestAWSEKSResourceDetector.cs | 175 ++++--- .../TestAWSLambdaResourceDetector.cs | 37 +- .../TestResourceBuilderExtensions.cs | 47 +- .../TestAWSXRayIdGenerator.cs | 137 +++--- .../Trace/TestAWSXRayPropagator.cs | 321 +++++++------ .../TestAWSClientInstrumentation.cs | 241 +++++----- .../Tools/CustomResponses.cs | 161 +++---- .../Tools/CustomWebResponse.cs | 145 +++--- .../Tools/HttpResponseMessageBody.cs | 97 ++-- .../Tools/MockHttpRequest.cs | 346 +++++++------- .../Tools/MockHttpRequestFactory.cs | 59 +-- .../Tools/MockWebResponse.cs | 253 +++++----- .../Tools/Utils.cs | 77 ++- .../AWSLambdaWrapperTests.cs | 413 ++++++++-------- .../SampleHandlers.cs | 51 +- .../SampleLambdaContext.cs | 29 +- 58 files changed, 3155 insertions(+), 3200 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs index 67a9f7fefc..c42b4eac89 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs @@ -19,72 +19,71 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay +namespace OpenTelemetry.Contrib.Extensions.AWSXRay; + +[EventSource(Name = "OpenTelemetry-AWS-XRay")] +internal class AWSXRayEventSource : EventSource { - [EventSource(Name = "OpenTelemetry-AWS-XRay")] - internal class AWSXRayEventSource : EventSource - { - public static AWSXRayEventSource Log = new AWSXRayEventSource(); + public static AWSXRayEventSource Log = new AWSXRayEventSource(); - [NonEvent] - public void ActivityContextExtractException(string format, Exception ex) + [NonEvent] + public void ActivityContextExtractException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) - { - this.FailedToExtractActivityContext(format, ToInvariantString(ex)); - } + this.FailedToExtractActivityContext(format, ToInvariantString(ex)); } + } - [NonEvent] - public void ResourceAttributesExtractException(string format, Exception ex) + [NonEvent] + public void ResourceAttributesExtractException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) { - if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) - { - this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); - } + this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); } + } - [Event(1, Message = "Failed to extract activity context in format: '{0}', context: '{1}'.", Level = EventLevel.Warning)] - public void FailedToExtractActivityContext(string format, string exception) - { - this.WriteEvent(1, format, exception); - } + [Event(1, Message = "Failed to extract activity context in format: '{0}', context: '{1}'.", Level = EventLevel.Warning)] + public void FailedToExtractActivityContext(string format, string exception) + { + this.WriteEvent(1, format, exception); + } - [Event(2, Message = "Failed to inject activity context in format: '{0}', context: '{1}'.", Level = EventLevel.Warning)] - public void FailedToInjectActivityContext(string format, string error) - { - this.WriteEvent(2, format, error); - } + [Event(2, Message = "Failed to inject activity context in format: '{0}', context: '{1}'.", Level = EventLevel.Warning)] + public void FailedToInjectActivityContext(string format, string error) + { + this.WriteEvent(2, format, error); + } - [Event(3, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] - public void FailedToExtractResourceAttributes(string format, string exception) - { - this.WriteEvent(3, format, exception); - } + [Event(3, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] + public void FailedToExtractResourceAttributes(string format, string exception) + { + this.WriteEvent(3, format, exception); + } + + [Event(4, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] + public void FailedToValidateCertificate(string format, string error) + { + this.WriteEvent(4, format, error); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; - [Event(4, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] - public void FailedToValidateCertificate(string format, string error) + try { - this.WriteEvent(4, format, error); + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) + finally { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs index eba7c5b7b0..a84843e169 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs @@ -21,174 +21,173 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay +namespace OpenTelemetry.Contrib.Extensions.AWSXRay; + +/// +/// Generate AWS X-Ray compatible trace id and replace the trace id of root activity. +/// See https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids. +/// +public static class AWSXRayIdGenerator { - /// - /// Generate AWS X-Ray compatible trace id and replace the trace id of root activity. - /// See https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids. - /// - public static class AWSXRayIdGenerator - { - private const int RandomNumberHexDigits = 24; + private const int RandomNumberHexDigits = 24; - private const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000; - private const long MicrosecondPerSecond = TimeSpan.TicksPerSecond / TicksPerMicrosecond; + private const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000; + private const long MicrosecondPerSecond = TimeSpan.TicksPerSecond / TicksPerMicrosecond; - private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - private static readonly long UnixEpochMicroseconds = EpochStart.Ticks / TicksPerMicrosecond; - private static readonly Random Global = new Random(); - private static object randLock = new object(); + private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private static readonly long UnixEpochMicroseconds = EpochStart.Ticks / TicksPerMicrosecond; + private static readonly Random Global = new Random(); + private static object randLock = new object(); - internal static void ReplaceTraceId(Sampler sampler = null) + internal static void ReplaceTraceId(Sampler sampler = null) + { + var awsXRayActivityListener = new ActivityListener { - var awsXRayActivityListener = new ActivityListener + ActivityStarted = (activity) => { - ActivityStarted = (activity) => + if (string.IsNullOrEmpty(activity.ParentId)) { - if (string.IsNullOrEmpty(activity.ParentId)) - { - var awsXRayTraceId = GenerateAWSXRayCompatiableTraceId(); + var awsXRayTraceId = GenerateAWSXRayCompatiableTraceId(); - // TODO: Apply API to directly modify trace id once .NET runtime publicizes it. - activity.SetParentId(awsXRayTraceId, default, activity.ActivityTraceFlags); + // TODO: Apply API to directly modify trace id once .NET runtime publicizes it. + activity.SetParentId(awsXRayTraceId, default, activity.ActivityTraceFlags); - // When not using instrumented library and creating root activity using ActivitySource.StartActivity(), - // need to update the sampling decision as sampler may be trace id dependent. - if (sampler != null) - { - UpdateSamplingDecision(activity, sampler); - } + // When not using instrumented library and creating root activity using ActivitySource.StartActivity(), + // need to update the sampling decision as sampler may be trace id dependent. + if (sampler != null) + { + UpdateSamplingDecision(activity, sampler); } - }, + } + }, - ShouldListenTo = (_) => true, - }; + ShouldListenTo = (_) => true, + }; - ActivitySource.AddActivityListener(awsXRayActivityListener); - } + ActivitySource.AddActivityListener(awsXRayActivityListener); + } - internal static ActivityTraceId GenerateAWSXRayCompatiableTraceId() - { - var epoch = (int)DateTime.UtcNow.ToUnixTimeSeconds(); // first 8 digit as time stamp + internal static ActivityTraceId GenerateAWSXRayCompatiableTraceId() + { + var epoch = (int)DateTime.UtcNow.ToUnixTimeSeconds(); // first 8 digit as time stamp - var randomNumber = GenerateHexNumber(RandomNumberHexDigits); // remaining 24 random digit + var randomNumber = GenerateHexNumber(RandomNumberHexDigits); // remaining 24 random digit - var newTraceId = string.Concat(epoch.ToString("x", CultureInfo.InvariantCulture), randomNumber); + var newTraceId = string.Concat(epoch.ToString("x", CultureInfo.InvariantCulture), randomNumber); - return ActivityTraceId.CreateFromString(newTraceId.AsSpan()); - } + return ActivityTraceId.CreateFromString(newTraceId.AsSpan()); + } - internal static void UpdateSamplingDecision(Activity activity, Sampler sampler) + internal static void UpdateSamplingDecision(Activity activity, Sampler sampler) + { + if (!(sampler is AlwaysOnSampler) && !(sampler is AlwaysOffSampler)) { - if (!(sampler is AlwaysOnSampler) && !(sampler is AlwaysOffSampler)) - { - ActivitySamplingResult result = !Sdk.SuppressInstrumentation ? ComputeRootActivitySamplingResult(activity, sampler) : ActivitySamplingResult.None; + ActivitySamplingResult result = !Sdk.SuppressInstrumentation ? ComputeRootActivitySamplingResult(activity, sampler) : ActivitySamplingResult.None; - activity.ActivityTraceFlags = ActivityTraceFlags.None; + activity.ActivityTraceFlags = ActivityTraceFlags.None; - // Following the same behavior when .NET runtime sets the trace flag for a newly created root activity. - // See: https://github.com/dotnet/runtime/blob/master/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs#L1022-L1027 - activity.IsAllDataRequested = result == ActivitySamplingResult.AllData || result == ActivitySamplingResult.AllDataAndRecorded; + // Following the same behavior when .NET runtime sets the trace flag for a newly created root activity. + // See: https://github.com/dotnet/runtime/blob/master/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs#L1022-L1027 + activity.IsAllDataRequested = result == ActivitySamplingResult.AllData || result == ActivitySamplingResult.AllDataAndRecorded; - if (result == ActivitySamplingResult.AllDataAndRecorded) - { - activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; - } + if (result == ActivitySamplingResult.AllDataAndRecorded) + { + activity.ActivityTraceFlags |= ActivityTraceFlags.Recorded; } } + } - /// - /// Convert a given time to Unix time which is the number of seconds since 1st January 1970, 00:00:00 UTC. - /// - /// .Net representation of time. - /// The number of seconds elapsed since 1970-01-01 00:00:00 UTC. The value is expressed in whole and fractional seconds with resolution of microsecond. - private static decimal ToUnixTimeSeconds(this DateTime date) - { - long microseconds = date.Ticks / TicksPerMicrosecond; - long microsecondsSinceEpoch = microseconds - UnixEpochMicroseconds; - return (decimal)microsecondsSinceEpoch / MicrosecondPerSecond; - } + /// + /// Convert a given time to Unix time which is the number of seconds since 1st January 1970, 00:00:00 UTC. + /// + /// .Net representation of time. + /// The number of seconds elapsed since 1970-01-01 00:00:00 UTC. The value is expressed in whole and fractional seconds with resolution of microsecond. + private static decimal ToUnixTimeSeconds(this DateTime date) + { + long microseconds = date.Ticks / TicksPerMicrosecond; + long microsecondsSinceEpoch = microseconds - UnixEpochMicroseconds; + return (decimal)microsecondsSinceEpoch / MicrosecondPerSecond; + } - /// - /// Generate a random 24-digit hex number. - /// - /// Digits of the hex number. - /// The generated hex number. - private static string GenerateHexNumber(int digits) - { - Guard.ThrowIfOutOfRange(digits, min: 0); + /// + /// Generate a random 24-digit hex number. + /// + /// Digits of the hex number. + /// The generated hex number. + private static string GenerateHexNumber(int digits) + { + Guard.ThrowIfOutOfRange(digits, min: 0); - byte[] bytes = new byte[digits / 2]; + byte[] bytes = new byte[digits / 2]; - string hexNumber; + string hexNumber; - lock (randLock) + lock (randLock) + { + NextBytes(bytes); + hexNumber = string.Concat(bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)).ToArray()); + if (digits % 2 != 0) { - NextBytes(bytes); - hexNumber = string.Concat(bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)).ToArray()); - if (digits % 2 != 0) - { - hexNumber += Next(16).ToString("x", CultureInfo.InvariantCulture); - } + hexNumber += Next(16).ToString("x", CultureInfo.InvariantCulture); } - - return hexNumber; } - /// - /// Fills the elements of a specified array of bytes with random numbers. - /// - /// An array of bytes to contain random numbers. - private static void NextBytes(byte[] buffer) - { - Global.NextBytes(buffer); - } + return hexNumber; + } - /// - /// Returns a non-negative random integer that is less than the specified maximum. - /// - /// Max value of the random integer. - /// A 32-bit signed integer that is greater than or equal to 0, and less than maxValue. - private static int Next(int maxValue) - { - return Global.Next(maxValue); - } + /// + /// Fills the elements of a specified array of bytes with random numbers. + /// + /// An array of bytes to contain random numbers. + private static void NextBytes(byte[] buffer) + { + Global.NextBytes(buffer); + } - private static ActivitySamplingResult ComputeRootActivitySamplingResult( - Activity activity, - Sampler sampler) + /// + /// Returns a non-negative random integer that is less than the specified maximum. + /// + /// Max value of the random integer. + /// A 32-bit signed integer that is greater than or equal to 0, and less than maxValue. + private static int Next(int maxValue) + { + return Global.Next(maxValue); + } + + private static ActivitySamplingResult ComputeRootActivitySamplingResult( + Activity activity, + Sampler sampler) + { + // Parent context is default for root activity + var samplingParameters = new SamplingParameters( + default, + activity.TraceId, + activity.DisplayName, + activity.Kind, + activity.TagObjects, + activity.Links); + + var shouldSample = sampler.ShouldSample(samplingParameters); + + var activitySamplingResult = shouldSample.Decision switch { - // Parent context is default for root activity - var samplingParameters = new SamplingParameters( - default, - activity.TraceId, - activity.DisplayName, - activity.Kind, - activity.TagObjects, - activity.Links); - - var shouldSample = sampler.ShouldSample(samplingParameters); - - var activitySamplingResult = shouldSample.Decision switch - { - SamplingDecision.RecordAndSample => ActivitySamplingResult.AllDataAndRecorded, - SamplingDecision.RecordOnly => ActivitySamplingResult.AllData, - _ => ActivitySamplingResult.PropagationData, - }; + SamplingDecision.RecordAndSample => ActivitySamplingResult.AllDataAndRecorded, + SamplingDecision.RecordOnly => ActivitySamplingResult.AllData, + _ => ActivitySamplingResult.PropagationData, + }; - if (activitySamplingResult != ActivitySamplingResult.PropagationData) + if (activitySamplingResult != ActivitySamplingResult.PropagationData) + { + // Update sampling attributes as we need to update the sampling decision + foreach (var att in shouldSample.Attributes) { - // Update sampling attributes as we need to update the sampling decision - foreach (var att in shouldSample.Attributes) - { - activity.SetTag(att.Key, att.Value); - } - - return activitySamplingResult; + activity.SetTag(att.Key, att.Value); } - // Return PropagationData for root activity in this case. - return ActivitySamplingResult.PropagationData; + return activitySamplingResult; } + + // Return PropagationData for root activity in this case. + return ActivitySamplingResult.PropagationData; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs index a06dc4a5db..0b3ffe119a 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs @@ -21,70 +21,69 @@ #endif using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Resource detector for application running in AWS ElasticBeanstalk environment. +/// +public class AWSEBSResourceDetector : IResourceDetector { + private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; + private const string AWSEBSMetadataLinuxFilePath = "/var/elasticbeanstalk/xray/environment.conf"; + /// - /// Resource detector for application running in AWS ElasticBeanstalk environment. + /// Detector the required and optional resource attributes from AWS ElasticBeanstalk. /// - public class AWSEBSResourceDetector : IResourceDetector + /// List of key-value pairs of resource attributes. + public IEnumerable> Detect() { - private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; - private const string AWSEBSMetadataLinuxFilePath = "/var/elasticbeanstalk/xray/environment.conf"; + List> resourceAttributes = null; - /// - /// Detector the required and optional resource attributes from AWS ElasticBeanstalk. - /// - /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + try { - List> resourceAttributes = null; - - try - { - string filePath = null; + string filePath = null; #if NETSTANDARD - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - filePath = AWSEBSMetadataWindowsFilePath; - } - else - { - filePath = AWSEBSMetadataLinuxFilePath; - } -#else + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { filePath = AWSEBSMetadataWindowsFilePath; -#endif - - var metadata = this.GetEBSMetadata(filePath); - - resourceAttributes = this.ExtractResourceAttributes(metadata); } - catch (Exception ex) + else { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSResourceDetector), ex); + filePath = AWSEBSMetadataLinuxFilePath; } +#else + filePath = AWSEBSMetadataWindowsFilePath; +#endif - return resourceAttributes; - } + var metadata = this.GetEBSMetadata(filePath); - internal List> ExtractResourceAttributes(AWSEBSMetadataModel metadata) + resourceAttributes = this.ExtractResourceAttributes(metadata); + } + catch (Exception ex) { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceNamespace, metadata.EnvironmentName), - new KeyValuePair(AWSSemanticConventions.AttributeServiceInstanceID, metadata.DeploymentId), - new KeyValuePair(AWSSemanticConventions.AttributeServiceVersion, metadata.VersionLabel), - }; - - return resourceAttributes; + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSResourceDetector), ex); } - internal AWSEBSMetadataModel GetEBSMetadata(string filePath) + return resourceAttributes; + } + + internal List> ExtractResourceAttributes(AWSEBSMetadataModel metadata) + { + var resourceAttributes = new List>() { - return ResourceDetectorUtils.DeserializeFromFile(filePath); - } + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), + new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), + new KeyValuePair(AWSSemanticConventions.AttributeServiceNamespace, metadata.EnvironmentName), + new KeyValuePair(AWSSemanticConventions.AttributeServiceInstanceID, metadata.DeploymentId), + new KeyValuePair(AWSSemanticConventions.AttributeServiceVersion, metadata.VersionLabel), + }; + + return resourceAttributes; + } + + internal AWSEBSMetadataModel GetEBSMetadata(string filePath) + { + return ResourceDetectorUtils.DeserializeFromFile(filePath); } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs index 7a7e4f7b82..6c6acf5ae0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs @@ -18,86 +18,85 @@ using System.Collections.Generic; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Resource detector for application running on AWS EC2 instance. +/// +public class AWSEC2ResourceDetector : IResourceDetector { + private const string AWSEC2MetadataTokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"; + private const string AWSEC2MetadataTokenHeader = "X-aws-ec2-metadata-token"; + private const string AWSEC2MetadataTokenUrl = "http://169.254.169.254/latest/api/token"; + private const string AWSEC2HostNameUrl = "http://169.254.169.254/latest/meta-data/hostname"; + private const string AWSEC2IdentityDocumentUrl = "http://169.254.169.254/latest/dynamic/instance-identity/document"; + /// - /// Resource detector for application running on AWS EC2 instance. + /// Detector the required and optional resource attributes from AWS EC2. /// - public class AWSEC2ResourceDetector : IResourceDetector + /// List of key-value pairs of resource attributes. + public IEnumerable> Detect() { - private const string AWSEC2MetadataTokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"; - private const string AWSEC2MetadataTokenHeader = "X-aws-ec2-metadata-token"; - private const string AWSEC2MetadataTokenUrl = "http://169.254.169.254/latest/api/token"; - private const string AWSEC2HostNameUrl = "http://169.254.169.254/latest/meta-data/hostname"; - private const string AWSEC2IdentityDocumentUrl = "http://169.254.169.254/latest/dynamic/instance-identity/document"; + List> resourceAttributes = null; - /// - /// Detector the required and optional resource attributes from AWS EC2. - /// - /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + try { - List> resourceAttributes = null; - - try - { - var token = this.GetAWSEC2Token(); - var identity = this.GetAWSEC2Identity(token); - var hostName = this.GetAWSEC2HostName(token); - - resourceAttributes = this.ExtractResourceAttributes(identity, hostName); - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2ResourceDetector), ex); - } + var token = this.GetAWSEC2Token(); + var identity = this.GetAWSEC2Identity(token); + var hostName = this.GetAWSEC2HostName(token); - return resourceAttributes; + resourceAttributes = this.ExtractResourceAttributes(identity, hostName); } - - internal List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel identity, string hostName) + catch (Exception ex) { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, identity.AccountId), - new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity.AvailabilityZone), - new KeyValuePair(AWSSemanticConventions.AttributeHostID, identity.InstanceId), - new KeyValuePair(AWSSemanticConventions.AttributeHostType, identity.InstanceType), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, identity.Region), - new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), - }; - - return resourceAttributes; + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2ResourceDetector), ex); } - internal AWSEC2IdentityDocumentModel DeserializeResponse(string response) - { - return ResourceDetectorUtils.DeserializeFromString(response); - } + return resourceAttributes; + } - private string GetAWSEC2Token() + internal List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel identity, string hostName) + { + var resourceAttributes = new List>() { - return ResourceDetectorUtils.SendOutRequest(AWSEC2MetadataTokenUrl, "PUT", new KeyValuePair(AWSEC2MetadataTokenTTLHeader, "60")).Result; - } + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, identity.AccountId), + new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity.AvailabilityZone), + new KeyValuePair(AWSSemanticConventions.AttributeHostID, identity.InstanceId), + new KeyValuePair(AWSSemanticConventions.AttributeHostType, identity.InstanceType), + new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, identity.Region), + new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), + }; - private AWSEC2IdentityDocumentModel GetAWSEC2Identity(string token) - { - var identity = this.GetIdentityResponse(token); - var identityDocument = this.DeserializeResponse(identity); + return resourceAttributes; + } - return identityDocument; - } + internal AWSEC2IdentityDocumentModel DeserializeResponse(string response) + { + return ResourceDetectorUtils.DeserializeFromString(response); + } - private string GetIdentityResponse(string token) - { - return ResourceDetectorUtils.SendOutRequest(AWSEC2IdentityDocumentUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; - } + private string GetAWSEC2Token() + { + return ResourceDetectorUtils.SendOutRequest(AWSEC2MetadataTokenUrl, "PUT", new KeyValuePair(AWSEC2MetadataTokenTTLHeader, "60")).Result; + } - private string GetAWSEC2HostName(string token) - { - return ResourceDetectorUtils.SendOutRequest(AWSEC2HostNameUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; - } + private AWSEC2IdentityDocumentModel GetAWSEC2Identity(string token) + { + var identity = this.GetIdentityResponse(token); + var identityDocument = this.DeserializeResponse(identity); + + return identityDocument; + } + + private string GetIdentityResponse(string token) + { + return ResourceDetectorUtils.SendOutRequest(AWSEC2IdentityDocumentUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; + } + + private string GetAWSEC2HostName(string token) + { + return ResourceDetectorUtils.SendOutRequest(AWSEC2HostNameUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index 3df4ad64a2..fc25011d7d 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -17,79 +17,78 @@ using System; using System.Collections.Generic; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Resource detector for application running in AWS ECS. +/// +public class AWSECSResourceDetector : IResourceDetector { + private const string AWSECSMetadataPath = "/proc/self/cgroup"; + private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; + private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; + /// - /// Resource detector for application running in AWS ECS. + /// Detector the required and optional resource attributes from AWS ECS. /// - public class AWSECSResourceDetector : IResourceDetector + /// List of key-value pairs of resource attributes. + public IEnumerable> Detect() { - private const string AWSECSMetadataPath = "/proc/self/cgroup"; - private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; - private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; + List> resourceAttributes = null; - /// - /// Detector the required and optional resource attributes from AWS ECS. - /// - /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + if (!this.IsECSProcess()) { - List> resourceAttributes = null; - - if (!this.IsECSProcess()) - { - return resourceAttributes; - } - - try - { - var containerId = this.GetECSContainerId(AWSECSMetadataPath); - - resourceAttributes = this.ExtractResourceAttributes(containerId); - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); - } - return resourceAttributes; } - internal List> ExtractResourceAttributes(string containerId) + try { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), - new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId), - }; + var containerId = this.GetECSContainerId(AWSECSMetadataPath); - return resourceAttributes; + resourceAttributes = this.ExtractResourceAttributes(containerId); + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); } - internal string GetECSContainerId(string path) + return resourceAttributes; + } + + internal List> ExtractResourceAttributes(string containerId) + { + var resourceAttributes = new List>() { - string containerId = null; + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), + new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId), + }; + + return resourceAttributes; + } + + internal string GetECSContainerId(string path) + { + string containerId = null; - using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + { + while (!streamReader.EndOfStream) { - while (!streamReader.EndOfStream) + var trimmedLine = streamReader.ReadLine().Trim(); + if (trimmedLine.Length > 64) { - var trimmedLine = streamReader.ReadLine().Trim(); - if (trimmedLine.Length > 64) - { - containerId = trimmedLine.Substring(trimmedLine.Length - 64); - return containerId; - } + containerId = trimmedLine.Substring(trimmedLine.Length - 64); + return containerId; } } - - return containerId; } - internal bool IsECSProcess() - { - return Environment.GetEnvironmentVariable(AWSECSMetadataURLKey) != null || Environment.GetEnvironmentVariable(AWSECSMetadataURLV4Key) != null; - } + return containerId; + } + + internal bool IsECSProcess() + { + return Environment.GetEnvironmentVariable(AWSECSMetadataURLKey) != null || Environment.GetEnvironmentVariable(AWSECSMetadataURLV4Key) != null; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index 32d151c504..a58fd0ee60 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -21,145 +21,144 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Resource detector for application running in AWS EKS. +/// +public class AWSEKSResourceDetector : IResourceDetector { + private const string AWSEKSCertificatePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; + private const string AWSEKSCredentialPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"; + private const string AWSEKSMetadataFilePath = "/proc/self/cgroup"; + private const string AWSClusterInfoUrl = "https://kubernetes.default.svc/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info"; + private const string AWSAuthUrl = "https://kubernetes.default.svc/api/v1/namespaces/kube-system/configmaps/aws-auth"; + /// - /// Resource detector for application running in AWS EKS. + /// Detector the required and optional resource attributes from AWS EKS. /// - public class AWSEKSResourceDetector : IResourceDetector + /// List of key-value pairs of resource attributes. + public IEnumerable> Detect() { - private const string AWSEKSCertificatePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; - private const string AWSEKSCredentialPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"; - private const string AWSEKSMetadataFilePath = "/proc/self/cgroup"; - private const string AWSClusterInfoUrl = "https://kubernetes.default.svc/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info"; - private const string AWSAuthUrl = "https://kubernetes.default.svc/api/v1/namespaces/kube-system/configmaps/aws-auth"; - - /// - /// Detector the required and optional resource attributes from AWS EKS. - /// - /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() - { - var credentials = this.GetEKSCredentials(AWSEKSCredentialPath); - var httpClientHandler = Handler.Create(AWSEKSCertificatePath); + var credentials = this.GetEKSCredentials(AWSEKSCredentialPath); + var httpClientHandler = Handler.Create(AWSEKSCertificatePath); - if (credentials == null || !this.IsEKSProcess(credentials, httpClientHandler)) - { - return null; - } - - return this.ExtractResourceAttributes( - this.GetEKSClusterName(credentials, httpClientHandler), - this.GetEKSContainerId(AWSEKSMetadataFilePath)); + if (credentials == null || !this.IsEKSProcess(credentials, httpClientHandler)) + { + return null; } - internal List> ExtractResourceAttributes(string clusterName, string containerId) - { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), - }; + return this.ExtractResourceAttributes( + this.GetEKSClusterName(credentials, httpClientHandler), + this.GetEKSContainerId(AWSEKSMetadataFilePath)); + } - if (!string.IsNullOrEmpty(clusterName)) - { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName)); - } + internal List> ExtractResourceAttributes(string clusterName, string containerId) + { + var resourceAttributes = new List>() + { + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), + }; - if (!string.IsNullOrEmpty(containerId)) - { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); - } + if (!string.IsNullOrEmpty(clusterName)) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName)); + } - return resourceAttributes; + if (!string.IsNullOrEmpty(containerId)) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); } - internal string GetEKSCredentials(string path) + return resourceAttributes; + } + + internal string GetEKSCredentials(string path) + { + try { - try - { - StringBuilder stringBuilder = new StringBuilder(); + StringBuilder stringBuilder = new StringBuilder(); - using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + { + while (!streamReader.EndOfStream) { - while (!streamReader.EndOfStream) - { - stringBuilder.Append(streamReader.ReadLine().Trim()); - } + stringBuilder.Append(streamReader.ReadLine().Trim()); } - - return "Bearer " + stringBuilder.ToString(); - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to load client token", ex); } - return null; + return "Bearer " + stringBuilder.ToString(); + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to load client token", ex); } - internal string GetEKSContainerId(string path) + return null; + } + + internal string GetEKSContainerId(string path) + { + try { - try + using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) { - using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + while (!streamReader.EndOfStream) { - while (!streamReader.EndOfStream) + var trimmedLine = streamReader.ReadLine().Trim(); + if (trimmedLine.Length > 64) { - var trimmedLine = streamReader.ReadLine().Trim(); - if (trimmedLine.Length > 64) - { - return trimmedLine.Substring(trimmedLine.Length - 64); - } + return trimmedLine.Substring(trimmedLine.Length - 64); } } } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get Container Id", ex); - } - - return null; } - - internal AWSEKSClusterInformationModel DeserializeResponse(string response) + catch (Exception ex) { - return ResourceDetectorUtils.DeserializeFromString(response); + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get Container Id", ex); } - private string GetEKSClusterName(string credentials, HttpClientHandler httpClientHandler) - { - try - { - var clusterInfo = this.GetEKSClusterInfo(credentials, httpClientHandler); - return this.DeserializeResponse(clusterInfo)?.Data?.ClusterName; - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get cluster information", ex); - } + return null; + } - return null; - } + internal AWSEKSClusterInformationModel DeserializeResponse(string response) + { + return ResourceDetectorUtils.DeserializeFromString(response); + } - private bool IsEKSProcess(string credentials, HttpClientHandler httpClientHandler) + private string GetEKSClusterName(string credentials, HttpClientHandler httpClientHandler) + { + try { - string awsAuth = null; - try - { - awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get EKS information", ex); - } - - return !string.IsNullOrEmpty(awsAuth); + var clusterInfo = this.GetEKSClusterInfo(credentials, httpClientHandler); + return this.DeserializeResponse(clusterInfo)?.Data?.ClusterName; + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get cluster information", ex); } - private string GetEKSClusterInfo(string credentials, HttpClientHandler httpClientHandler) + return null; + } + + private bool IsEKSProcess(string credentials, HttpClientHandler httpClientHandler) + { + string awsAuth = null; + try + { + awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; + } + catch (Exception ex) { - return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get EKS information", ex); } + + return !string.IsNullOrEmpty(awsAuth); + } + + private string GetEKSClusterInfo(string credentials, HttpClientHandler httpClientHandler) + { + return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs index 9bef38cc0b..9fd80e3552 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs @@ -17,64 +17,63 @@ using System; using System.Collections.Generic; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Resource detector for application running in AWS Lambda. +/// +public class AWSLambdaResourceDetector : IResourceDetector { + private const string AWSLambdaRegion = "AWS_REGION"; + private const string AWSLambdaFunctionName = "AWS_LAMBDA_FUNCTION_NAME"; + private const string AWSLambdaFunctionVersion = "AWS_LAMBDA_FUNCTION_VERSION"; + /// - /// Resource detector for application running in AWS Lambda. + /// Detector the required and optional resource attributes from AWS Lambda. /// - public class AWSLambdaResourceDetector : IResourceDetector + /// List of key-value pairs of resource attributes. + public IEnumerable> Detect() { - private const string AWSLambdaRegion = "AWS_REGION"; - private const string AWSLambdaFunctionName = "AWS_LAMBDA_FUNCTION_NAME"; - private const string AWSLambdaFunctionVersion = "AWS_LAMBDA_FUNCTION_VERSION"; + List> resourceAttributes = null; - /// - /// Detector the required and optional resource attributes from AWS Lambda. - /// - /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + try { - List> resourceAttributes = null; - - try - { - resourceAttributes = this.ExtractResourceAttributes(); - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSLambdaResourceDetector), ex); - } - - return resourceAttributes; + resourceAttributes = this.ExtractResourceAttributes(); } - - internal List> ExtractResourceAttributes() + catch (Exception ex) { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), - }; - - return resourceAttributes; + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSLambdaResourceDetector), ex); } - private static string GetAWSRegion() - { - return Environment.GetEnvironmentVariable(AWSLambdaRegion); - } + return resourceAttributes; + } - private static string GetFunctionName() + internal List> ExtractResourceAttributes() + { + var resourceAttributes = new List>() { - return Environment.GetEnvironmentVariable(AWSLambdaFunctionName); - } + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), + new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), + new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), + }; - private static string GetFunctionVersion() - { - return Environment.GetEnvironmentVariable(AWSLambdaFunctionVersion); - } + return resourceAttributes; + } + + private static string GetAWSRegion() + { + return Environment.GetEnvironmentVariable(AWSLambdaRegion); + } + + private static string GetFunctionName() + { + return Environment.GetEnvironmentVariable(AWSLambdaFunctionName); + } + + private static string GetFunctionVersion() + { + return Environment.GetEnvironmentVariable(AWSLambdaFunctionVersion); } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs index ab6ca6cbef..5291bcf77b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs @@ -14,32 +14,31 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +internal static class AWSSemanticConventions { - internal static class AWSSemanticConventions - { - public const string AttributeCloudAccountID = "cloud.account.id"; - public const string AttributeCloudAvailableZone = "cloud.availability_zone"; - public const string AttributeCloudPlatform = "cloud.platform"; - public const string AttributeCloudProvider = "cloud.provider"; - public const string AttributeCloudRegion = "cloud.region"; + public const string AttributeCloudAccountID = "cloud.account.id"; + public const string AttributeCloudAvailableZone = "cloud.availability_zone"; + public const string AttributeCloudPlatform = "cloud.platform"; + public const string AttributeCloudProvider = "cloud.provider"; + public const string AttributeCloudRegion = "cloud.region"; - public const string AttributeContainerID = "container.id"; + public const string AttributeContainerID = "container.id"; - public const string AttributeFaasExecution = "faas.execution"; - public const string AttributeFaasID = "faas.id"; - public const string AttributeFaasName = "faas.name"; - public const string AttributeFaasVersion = "faas.version"; + public const string AttributeFaasExecution = "faas.execution"; + public const string AttributeFaasID = "faas.id"; + public const string AttributeFaasName = "faas.name"; + public const string AttributeFaasVersion = "faas.version"; - public const string AttributeHostID = "host.id"; - public const string AttributeHostType = "host.type"; - public const string AttributeHostName = "host.name"; + public const string AttributeHostID = "host.id"; + public const string AttributeHostType = "host.type"; + public const string AttributeHostName = "host.name"; - public const string AttributeK8SClusterName = "k8s.cluster.name"; + public const string AttributeK8SClusterName = "k8s.cluster.name"; - public const string AttributeServiceName = "service.name"; - public const string AttributeServiceNamespace = "service.namespace"; - public const string AttributeServiceInstanceID = "service.instance.id"; - public const string AttributeServiceVersion = "service.version"; - } + public const string AttributeServiceName = "service.name"; + public const string AttributeServiceNamespace = "service.namespace"; + public const string AttributeServiceInstanceID = "service.instance.id"; + public const string AttributeServiceVersion = "service.version"; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs index ddd66cdacc..f3ef7ae450 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs @@ -17,35 +17,34 @@ using System; using System.Net.Http; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; + +internal class Handler { - internal class Handler + public static HttpClientHandler Create(string certificateFile) { - public static HttpClientHandler Create(string certificateFile) + try { - try - { - ServerCertificateValidationProvider serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateFile); + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateFile); - if (!serverCertificateValidationProvider.IsCertificateLoaded) - { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); - return null; - } - - var clientHandler = new HttpClientHandler(); - clientHandler.ServerCertificateCustomValidationCallback = - (sender, x509Certificate2, x509Chain, sslPolicyErrors) => - serverCertificateValidationProvider.ValidationCallback(null, x509Certificate2, x509Chain, sslPolicyErrors); - return clientHandler; - } - catch (Exception ex) + if (!serverCertificateValidationProvider.IsCertificateLoaded) { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex); + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); + return null; } - return null; + var clientHandler = new HttpClientHandler(); + clientHandler.ServerCertificateCustomValidationCallback = + (sender, x509Certificate2, x509Chain, sslPolicyErrors) => + serverCertificateValidationProvider.ValidationCallback(null, x509Certificate2, x509Chain, sslPolicyErrors); + return clientHandler; } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex); + } + + return null; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs index 112f4a7929..e37f710894 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs @@ -20,142 +20,141 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; + +internal class ServerCertificateValidationProvider { - internal class ServerCertificateValidationProvider - { - private static readonly ServerCertificateValidationProvider InvalidProvider = - new ServerCertificateValidationProvider(null); + private static readonly ServerCertificateValidationProvider InvalidProvider = + new ServerCertificateValidationProvider(null); - private readonly X509Certificate2Collection trustedCertificates; + private readonly X509Certificate2Collection trustedCertificates; - private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates) + private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates) + { + if (trustedCertificates == null) { - if (trustedCertificates == null) - { - this.trustedCertificates = null; - this.ValidationCallback = null; - this.IsCertificateLoaded = false; - return; - } - - this.trustedCertificates = trustedCertificates; - this.ValidationCallback = (sender, cert, chain, errors) => - this.ValidateCertificate(new X509Certificate2(cert), chain, errors); - this.IsCertificateLoaded = true; + this.trustedCertificates = null; + this.ValidationCallback = null; + this.IsCertificateLoaded = false; + return; } - public bool IsCertificateLoaded { get; } + this.trustedCertificates = trustedCertificates; + this.ValidationCallback = (sender, cert, chain, errors) => + this.ValidateCertificate(new X509Certificate2(cert), chain, errors); + this.IsCertificateLoaded = true; + } - public RemoteCertificateValidationCallback ValidationCallback { get; } + public bool IsCertificateLoaded { get; } - public static ServerCertificateValidationProvider FromCertificateFile(string certificateFile) + public RemoteCertificateValidationCallback ValidationCallback { get; } + + public static ServerCertificateValidationProvider FromCertificateFile(string certificateFile) + { + if (!File.Exists(certificateFile)) { - if (!File.Exists(certificateFile)) - { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); - return InvalidProvider; - } + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); + return InvalidProvider; + } - var trustedCertificates = new X509Certificate2Collection(); - if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile)) - { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); - return InvalidProvider; - } + var trustedCertificates = new X509Certificate2Collection(); + if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile)) + { + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); + return InvalidProvider; + } - return new ServerCertificateValidationProvider(trustedCertificates); + return new ServerCertificateValidationProvider(trustedCertificates); + } + + private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName) + { + try + { + collection.Import(certFileName); + return true; + } + catch (Exception) + { + return false; } + } - private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName) + private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPolicyErrors errors) + { + var isSslPolicyPassed = errors == SslPolicyErrors.None || + errors == SslPolicyErrors.RemoteCertificateChainErrors; + if (!isSslPolicyPassed) { - try + if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) { - collection.Import(certFileName); - return true; + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable"); } - catch (Exception) + + if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors) { - return false; + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch"); } } - private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPolicyErrors errors) + chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates); + chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; + + // building the chain to process basic validations e.g. signature, use, expiration, revocation + var isValidChain = chain.Build(cert); + + if (!isValidChain) { - var isSslPolicyPassed = errors == SslPolicyErrors.None || - errors == SslPolicyErrors.RemoteCertificateChainErrors; - if (!isSslPolicyPassed) + var chainErrors = string.Empty; + foreach (var element in chain.ChainElements) { - if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) - { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable"); - } - - if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors) + foreach (var status in element.ChainElementStatus) { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch"); + chainErrors += + $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}"; } } - chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates); - chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; - - // building the chain to process basic validations e.g. signature, use, expiration, revocation - var isValidChain = chain.Build(cert); + AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}"); + } - if (!isValidChain) + // check if at least one certificate in the chain is in our trust list + var isTrusted = this.HasCommonCertificate(chain, this.trustedCertificates); + if (!isTrusted) + { + var serverCertificates = string.Empty; + foreach (var element in chain.ChainElements) { - var chainErrors = string.Empty; - foreach (var element in chain.ChainElements) - { - foreach (var status in element.ChainElementStatus) - { - chainErrors += - $"\nCertificate [{element.Certificate.Subject}] Status [{status.Status}]: {status.StatusInformation}"; - } - } - - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}"); + serverCertificates += " " + element.Certificate.Subject; } - // check if at least one certificate in the chain is in our trust list - var isTrusted = this.HasCommonCertificate(chain, this.trustedCertificates); - if (!isTrusted) + var trustCertificates = string.Empty; + foreach (var trustCertificate in this.trustedCertificates) { - var serverCertificates = string.Empty; - foreach (var element in chain.ChainElements) - { - serverCertificates += " " + element.Certificate.Subject; - } - - var trustCertificates = string.Empty; - foreach (var trustCertificate in this.trustedCertificates) - { - trustCertificates += " " + trustCertificate.Subject; - } - - AWSXRayEventSource.Log.FailedToValidateCertificate( - nameof(ServerCertificateValidationProvider), - $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}"); + trustCertificates += " " + trustCertificate.Subject; } - return isSslPolicyPassed && isValidChain && isTrusted; + AWSXRayEventSource.Log.FailedToValidateCertificate( + nameof(ServerCertificateValidationProvider), + $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}"); } - private bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection collection) + return isSslPolicyPassed && isValidChain && isTrusted; + } + + private bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection collection) + { + foreach (var chainElement in chain.ChainElements) { - foreach (var chainElement in chain.ChainElements) + foreach (var certificate in collection) { - foreach (var certificate in collection) + if (Enumerable.SequenceEqual(chainElement.Certificate.GetPublicKey(), certificate.GetPublicKey())) { - if (Enumerable.SequenceEqual(chainElement.Certificate.GetPublicKey(), certificate.GetPublicKey())) - { - return true; - } + return true; } } - - return false; } + + return false; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs index 6ffa64c130..ef262b706b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs @@ -16,18 +16,17 @@ using System.Collections.Generic; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Resource detector interface. +/// Mocking https://github.com/open-telemetry/opentelemetry-dotnet/blob/6b7f2dd77cf9d37260a853fcc95f7b77e296065d/src/OpenTelemetry/Resources/IResourceDetector.cs. +/// +public interface IResourceDetector { /// - /// Resource detector interface. - /// Mocking https://github.com/open-telemetry/opentelemetry-dotnet/blob/6b7f2dd77cf9d37260a853fcc95f7b77e296065d/src/OpenTelemetry/Resources/IResourceDetector.cs. + /// Called to get key-value pairs of attribute from detector. /// - public interface IResourceDetector - { - /// - /// Called to get key-value pairs of attribute from detector. - /// - /// List of key-value pairs of resource attributes. - IEnumerable> Detect(); - } + /// List of key-value pairs of resource attributes. + IEnumerable> Detect(); } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs index ae4ed8d5c6..f3acf9d8a0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs @@ -16,17 +16,16 @@ using Newtonsoft.Json; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; + +internal class AWSEBSMetadataModel { - internal class AWSEBSMetadataModel - { - [JsonProperty(PropertyName = "deployment_id")] - public string DeploymentId { get; set; } + [JsonProperty(PropertyName = "deployment_id")] + public string DeploymentId { get; set; } - [JsonProperty(PropertyName = "environment_name")] - public string EnvironmentName { get; set; } + [JsonProperty(PropertyName = "environment_name")] + public string EnvironmentName { get; set; } - [JsonProperty(PropertyName = "version_label")] - public string VersionLabel { get; set; } - } + [JsonProperty(PropertyName = "version_label")] + public string VersionLabel { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs index 65f6559eb4..9a9ea20d63 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs @@ -14,18 +14,17 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; + +internal class AWSEC2IdentityDocumentModel { - internal class AWSEC2IdentityDocumentModel - { - public string AccountId { get; set; } + public string AccountId { get; set; } - public string AvailabilityZone { get; set; } + public string AvailabilityZone { get; set; } - public string Region { get; set; } + public string Region { get; set; } - public string InstanceId { get; set; } + public string InstanceId { get; set; } - public string InstanceType { get; set; } - } + public string InstanceType { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs index abaec62717..e81fbfd050 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs @@ -16,11 +16,10 @@ using Newtonsoft.Json; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; + +internal class AWSEKSClusterDataModel { - internal class AWSEKSClusterDataModel - { - [JsonProperty(PropertyName = "cluster.name")] - public string ClusterName { get; set; } - } + [JsonProperty(PropertyName = "cluster.name")] + public string ClusterName { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs index db7bdd5833..78eed916ba 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs @@ -14,10 +14,9 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; + +internal class AWSEKSClusterInformationModel { - internal class AWSEKSClusterInformationModel - { - public AWSEKSClusterDataModel Data { get; set; } - } + public AWSEKSClusterDataModel Data { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs index 06f913f05e..0aa64e40a2 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs @@ -17,31 +17,30 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using OpenTelemetry.Internal; -namespace OpenTelemetry.Resources +namespace OpenTelemetry.Resources; + +/// +/// Extension class for ResourceBuilder. +/// +public static class ResourceBuilderExtensions { /// - /// Extension class for ResourceBuilder. + /// Add resource detector to ResourceBuilder. /// - public static class ResourceBuilderExtensions + /// being configured. + /// being added. + /// The instance of to chain the calls. + public static ResourceBuilder AddDetector(this ResourceBuilder resourceBuilder, IResourceDetector resourceDetector) { - /// - /// Add resource detector to ResourceBuilder. - /// - /// being configured. - /// being added. - /// The instance of to chain the calls. - public static ResourceBuilder AddDetector(this ResourceBuilder resourceBuilder, IResourceDetector resourceDetector) - { - Guard.ThrowIfNull(resourceDetector); - - var resourceAttributes = resourceDetector.Detect(); + Guard.ThrowIfNull(resourceDetector); - if (resourceAttributes != null) - { - resourceBuilder.AddAttributes(resourceAttributes); - } + var resourceAttributes = resourceDetector.Detect(); - return resourceBuilder; + if (resourceAttributes != null) + { + resourceBuilder.AddAttributes(resourceAttributes); } + + return resourceBuilder; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs index 9db25ef0d4..b0a525424c 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs @@ -22,49 +22,48 @@ using System.Threading.Tasks; using Newtonsoft.Json; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; + +/// +/// Class for resource detector utils. +/// +public class ResourceDetectorUtils { - /// - /// Class for resource detector utils. - /// - public class ResourceDetectorUtils + internal static async Task SendOutRequest(string url, string method, KeyValuePair header, HttpClientHandler handler = null) { - internal static async Task SendOutRequest(string url, string method, KeyValuePair header, HttpClientHandler handler = null) + using (var httpRequestMessage = new HttpRequestMessage()) { - using (var httpRequestMessage = new HttpRequestMessage()) - { - httpRequestMessage.RequestUri = new Uri(url); - httpRequestMessage.Method = new HttpMethod(method); - httpRequestMessage.Headers.Add(header.Key, header.Value); - - var httpClient = handler == null ? new HttpClient() : new HttpClient(handler); - using (var response = await httpClient.SendAsync(httpRequestMessage)) - { - response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); - } - } - } + httpRequestMessage.RequestUri = new Uri(url); + httpRequestMessage.Method = new HttpMethod(method); + httpRequestMessage.Headers.Add(header.Key, header.Value); - internal static T DeserializeFromFile(string filePath) - { - using (var streamReader = GetStreamReader(filePath)) + var httpClient = handler == null ? new HttpClient() : new HttpClient(handler); + using (var response = await httpClient.SendAsync(httpRequestMessage)) { - JsonSerializer serializer = new JsonSerializer(); - return (T)serializer.Deserialize(streamReader, typeof(T)); + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync(); } } + } - internal static T DeserializeFromString(string json) + internal static T DeserializeFromFile(string filePath) + { + using (var streamReader = GetStreamReader(filePath)) { - return JsonConvert.DeserializeObject(json); + JsonSerializer serializer = new JsonSerializer(); + return (T)serializer.Deserialize(streamReader, typeof(T)); } + } - internal static StreamReader GetStreamReader(string filePath) - { - var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - var streamReader = new StreamReader(fileStream, Encoding.UTF8); - return streamReader; - } + internal static T DeserializeFromString(string json) + { + return JsonConvert.DeserializeObject(json); + } + + internal static StreamReader GetStreamReader(string filePath) + { + var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var streamReader = new StreamReader(fileStream, Encoding.UTF8); + return streamReader; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs index 5864339d4e..5e899960cd 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs @@ -23,293 +23,292 @@ using System.Text; using OpenTelemetry.Context.Propagation; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Trace +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; + +/// +/// Propagator for AWS X-Ray. See https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader. +/// +public class AWSXRayPropagator : TextMapPropagator { - /// - /// Propagator for AWS X-Ray. See https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader. - /// - public class AWSXRayPropagator : TextMapPropagator + private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; + private const char KeyValueDelimiter = '='; + private const char TraceHeaderDelimiter = ';'; + + private const string RootKey = "Root"; + private const string Version = "1"; + private const int RandomNumberHexDigits = 24; + private const int EpochHexDigits = 8; + private const int TotalLength = 35; + private const char TraceIdDelimiter = '-'; + private const int TraceIdDelimiterFirstIndex = 1; + private const int TraceIdDelimiterSecondIndex = 10; + + private const string ParentKey = "Parent"; + private const int ParentIdHexDigits = 16; + + private const string SampledKey = "Sampled"; + private const char SampledValue = '1'; + private const char NotSampledValue = '0'; + + /// + public override ISet Fields => new HashSet() { AWSXRayTraceHeaderKey }; + + /// + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) { - private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; - private const char KeyValueDelimiter = '='; - private const char TraceHeaderDelimiter = ';'; - - private const string RootKey = "Root"; - private const string Version = "1"; - private const int RandomNumberHexDigits = 24; - private const int EpochHexDigits = 8; - private const int TotalLength = 35; - private const char TraceIdDelimiter = '-'; - private const int TraceIdDelimiterFirstIndex = 1; - private const int TraceIdDelimiterSecondIndex = 10; - - private const string ParentKey = "Parent"; - private const int ParentIdHexDigits = 16; - - private const string SampledKey = "Sampled"; - private const char SampledValue = '1'; - private const char NotSampledValue = '0'; - - /// - public override ISet Fields => new HashSet() { AWSXRayTraceHeaderKey }; - - /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + if (context.ActivityContext.IsValid()) { - if (context.ActivityContext.IsValid()) - { - return context; - } + return context; + } - if (carrier == null) + if (carrier == null) + { + AWSXRayEventSource.Log.FailedToExtractActivityContext(nameof(AWSXRayPropagator), "null carrier"); + return context; + } + + if (getter == null) + { + AWSXRayEventSource.Log.FailedToExtractActivityContext(nameof(AWSXRayPropagator), "null getter"); + return context; + } + + try + { + var parentTraceHeader = getter(carrier, AWSXRayTraceHeaderKey); + + if (parentTraceHeader == null || parentTraceHeader.Count() != 1) { - AWSXRayEventSource.Log.FailedToExtractActivityContext(nameof(AWSXRayPropagator), "null carrier"); return context; } - if (getter == null) + var parentHeader = parentTraceHeader.First(); + + if (!TryParseXRayTraceHeader(parentHeader, out var newActivityContext)) { - AWSXRayEventSource.Log.FailedToExtractActivityContext(nameof(AWSXRayPropagator), "null getter"); return context; } - try - { - var parentTraceHeader = getter(carrier, AWSXRayTraceHeaderKey); - - if (parentTraceHeader == null || parentTraceHeader.Count() != 1) - { - return context; - } - - var parentHeader = parentTraceHeader.First(); + return new PropagationContext(newActivityContext, context.Baggage); + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ActivityContextExtractException(nameof(AWSXRayPropagator), ex); + } - if (!TryParseXRayTraceHeader(parentHeader, out var newActivityContext)) - { - return context; - } + return context; + } - return new PropagationContext(newActivityContext, context.Baggage); - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ActivityContextExtractException(nameof(AWSXRayPropagator), ex); - } + /// + public override void Inject(PropagationContext context, T carrier, Action setter) + { + if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default) + { + AWSXRayEventSource.Log.FailedToInjectActivityContext(nameof(AWSXRayPropagator), "Invalid context"); + return; + } - return context; + if (carrier == null) + { + AWSXRayEventSource.Log.FailedToInjectActivityContext(nameof(AWSXRayPropagator), "null carrier"); + return; } - /// - public override void Inject(PropagationContext context, T carrier, Action setter) + if (setter == null) { - if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default) - { - AWSXRayEventSource.Log.FailedToInjectActivityContext(nameof(AWSXRayPropagator), "Invalid context"); - return; - } + AWSXRayEventSource.Log.FailedToInjectActivityContext(nameof(AWSXRayPropagator), "null setter"); + return; + } - if (carrier == null) - { - AWSXRayEventSource.Log.FailedToInjectActivityContext(nameof(AWSXRayPropagator), "null carrier"); - return; - } + var sb = new StringBuilder(); + sb.Append(RootKey); + sb.Append(KeyValueDelimiter); + sb.Append(ToXRayTraceIdFormat(context.ActivityContext.TraceId.ToHexString())); + sb.Append(TraceHeaderDelimiter); + sb.Append(ParentKey); + sb.Append(KeyValueDelimiter); + sb.Append(context.ActivityContext.SpanId.ToHexString()); + sb.Append(TraceHeaderDelimiter); + sb.Append(SampledKey); + sb.Append(KeyValueDelimiter); + sb.Append((context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0 ? SampledValue : NotSampledValue); + + setter(carrier, AWSXRayTraceHeaderKey, sb.ToString()); + } - if (setter == null) - { - AWSXRayEventSource.Log.FailedToInjectActivityContext(nameof(AWSXRayPropagator), "null setter"); - return; - } + internal static bool TryParseXRayTraceHeader(string rawHeader, out ActivityContext activityContext) + { + // from https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader + // rawHeader format: Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1 - var sb = new StringBuilder(); - sb.Append(RootKey); - sb.Append(KeyValueDelimiter); - sb.Append(ToXRayTraceIdFormat(context.ActivityContext.TraceId.ToHexString())); - sb.Append(TraceHeaderDelimiter); - sb.Append(ParentKey); - sb.Append(KeyValueDelimiter); - sb.Append(context.ActivityContext.SpanId.ToHexString()); - sb.Append(TraceHeaderDelimiter); - sb.Append(SampledKey); - sb.Append(KeyValueDelimiter); - sb.Append((context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0 ? SampledValue : NotSampledValue); - - setter(carrier, AWSXRayTraceHeaderKey, sb.ToString()); - } + activityContext = default; + ReadOnlySpan traceId = default; + ReadOnlySpan parentId = default; + char traceOptions = default; - internal static bool TryParseXRayTraceHeader(string rawHeader, out ActivityContext activityContext) + if (string.IsNullOrEmpty(rawHeader)) { - // from https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader - // rawHeader format: Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1 + return false; + } - activityContext = default; - ReadOnlySpan traceId = default; - ReadOnlySpan parentId = default; - char traceOptions = default; + ReadOnlySpan header = rawHeader.AsSpan(); + while (header.Length > 0) + { + int delimiterIndex = header.IndexOf(TraceHeaderDelimiter); + ReadOnlySpan part; + if (delimiterIndex >= 0) + { + part = header.Slice(0, delimiterIndex); + header = header.Slice(delimiterIndex + 1); + } + else + { + part = header.Slice(0); + header = header.Slice(header.Length); + } - if (string.IsNullOrEmpty(rawHeader)) + ReadOnlySpan trimmedPart = part.Trim(); + int equalsIndex = trimmedPart.IndexOf(KeyValueDelimiter); + if (equalsIndex < 0) { return false; } - ReadOnlySpan header = rawHeader.AsSpan(); - while (header.Length > 0) + ReadOnlySpan value = trimmedPart.Slice(equalsIndex + 1); + if (trimmedPart.StartsWith(RootKey.AsSpan())) { - int delimiterIndex = header.IndexOf(TraceHeaderDelimiter); - ReadOnlySpan part; - if (delimiterIndex >= 0) - { - part = header.Slice(0, delimiterIndex); - header = header.Slice(delimiterIndex + 1); - } - else - { - part = header.Slice(0); - header = header.Slice(header.Length); - } - - ReadOnlySpan trimmedPart = part.Trim(); - int equalsIndex = trimmedPart.IndexOf(KeyValueDelimiter); - if (equalsIndex < 0) + if (!TryParseOTFormatTraceId(value, out var otFormatTraceId)) { return false; } - ReadOnlySpan value = trimmedPart.Slice(equalsIndex + 1); - if (trimmedPart.StartsWith(RootKey.AsSpan())) + traceId = otFormatTraceId; + } + else if (trimmedPart.StartsWith(ParentKey.AsSpan())) + { + if (!IsParentIdValid(value)) { - if (!TryParseOTFormatTraceId(value, out var otFormatTraceId)) - { - return false; - } - - traceId = otFormatTraceId; + return false; } - else if (trimmedPart.StartsWith(ParentKey.AsSpan())) - { - if (!IsParentIdValid(value)) - { - return false; - } - parentId = value; - } - else if (trimmedPart.StartsWith(SampledKey.AsSpan())) + parentId = value; + } + else if (trimmedPart.StartsWith(SampledKey.AsSpan())) + { + if (!TryParseSampleDecision(value, out var sampleDecision)) { - if (!TryParseSampleDecision(value, out var sampleDecision)) - { - return false; - } - - traceOptions = sampleDecision; + return false; } - } - if (traceId == default || parentId == default || traceOptions == default) - { - return false; + traceOptions = sampleDecision; } - - var activityTraceId = ActivityTraceId.CreateFromString(traceId); - var activityParentId = ActivitySpanId.CreateFromString(parentId); - var activityTraceOptions = traceOptions == SampledValue ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None; - - activityContext = new ActivityContext(activityTraceId, activityParentId, activityTraceOptions, isRemote: true); - - return true; } - internal static bool TryParseOTFormatTraceId(ReadOnlySpan traceId, out ReadOnlySpan otFormatTraceId) + if (traceId == default || parentId == default || traceOptions == default) { - otFormatTraceId = default; - - if (traceId.IsEmpty || traceId.IsWhiteSpace()) - { - return false; - } + return false; + } - if (traceId.Length != TotalLength) - { - return false; - } + var activityTraceId = ActivityTraceId.CreateFromString(traceId); + var activityParentId = ActivitySpanId.CreateFromString(parentId); + var activityTraceOptions = traceOptions == SampledValue ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None; - if (!traceId.StartsWith(Version.AsSpan())) - { - return false; - } + activityContext = new ActivityContext(activityTraceId, activityParentId, activityTraceOptions, isRemote: true); - if (traceId[TraceIdDelimiterFirstIndex] != TraceIdDelimiter || traceId[TraceIdDelimiterSecondIndex] != TraceIdDelimiter) - { - return false; - } + return true; + } - var timestamp = traceId.Slice(TraceIdDelimiterFirstIndex + 1, EpochHexDigits); - var randomNumber = traceId.Slice(TraceIdDelimiterSecondIndex + 1); - if (timestamp.Length != EpochHexDigits || randomNumber.Length != RandomNumberHexDigits) - { - return false; - } + internal static bool TryParseOTFormatTraceId(ReadOnlySpan traceId, out ReadOnlySpan otFormatTraceId) + { + otFormatTraceId = default; - var timestampString = timestamp.ToString(); - var randomNumberString = randomNumber.ToString(); - if (!int.TryParse(timestampString, NumberStyles.HexNumber, null, out _)) - { - return false; - } + if (traceId.IsEmpty || traceId.IsWhiteSpace()) + { + return false; + } - if (!BigInteger.TryParse(randomNumberString, NumberStyles.HexNumber, null, out _)) - { - return false; - } + if (traceId.Length != TotalLength) + { + return false; + } - otFormatTraceId = (timestampString + randomNumberString).AsSpan(); + if (!traceId.StartsWith(Version.AsSpan())) + { + return false; + } - return true; + if (traceId[TraceIdDelimiterFirstIndex] != TraceIdDelimiter || traceId[TraceIdDelimiterSecondIndex] != TraceIdDelimiter) + { + return false; } - internal static bool IsParentIdValid(ReadOnlySpan parentId) + var timestamp = traceId.Slice(TraceIdDelimiterFirstIndex + 1, EpochHexDigits); + var randomNumber = traceId.Slice(TraceIdDelimiterSecondIndex + 1); + if (timestamp.Length != EpochHexDigits || randomNumber.Length != RandomNumberHexDigits) { - if (parentId.IsEmpty || parentId.IsWhiteSpace()) - { - return false; - } + return false; + } - return parentId.Length == ParentIdHexDigits && long.TryParse(parentId.ToString(), NumberStyles.HexNumber, null, out _); + var timestampString = timestamp.ToString(); + var randomNumberString = randomNumber.ToString(); + if (!int.TryParse(timestampString, NumberStyles.HexNumber, null, out _)) + { + return false; } - internal static bool TryParseSampleDecision(ReadOnlySpan sampleDecision, out char result) + if (!BigInteger.TryParse(randomNumberString, NumberStyles.HexNumber, null, out _)) { - result = default; + return false; + } - if (sampleDecision.IsEmpty || sampleDecision.IsWhiteSpace()) - { - return false; - } + otFormatTraceId = (timestampString + randomNumberString).AsSpan(); - if (!char.TryParse(sampleDecision.ToString(), out var tempChar)) - { - return false; - } + return true; + } - if (tempChar != SampledValue && tempChar != NotSampledValue) - { - return false; - } + internal static bool IsParentIdValid(ReadOnlySpan parentId) + { + if (parentId.IsEmpty || parentId.IsWhiteSpace()) + { + return false; + } - result = tempChar; + return parentId.Length == ParentIdHexDigits && long.TryParse(parentId.ToString(), NumberStyles.HexNumber, null, out _); + } + + internal static bool TryParseSampleDecision(ReadOnlySpan sampleDecision, out char result) + { + result = default; - return true; + if (sampleDecision.IsEmpty || sampleDecision.IsWhiteSpace()) + { + return false; } - internal static string ToXRayTraceIdFormat(string traceId) + if (!char.TryParse(sampleDecision.ToString(), out var tempChar)) { - var sb = new StringBuilder(); - sb.Append(Version); - sb.Append(TraceIdDelimiter); - sb.Append(traceId.Substring(0, EpochHexDigits)); - sb.Append(TraceIdDelimiter); - sb.Append(traceId.Substring(EpochHexDigits)); - - return sb.ToString(); + return false; } + + if (tempChar != SampledValue && tempChar != NotSampledValue) + { + return false; + } + + result = tempChar; + + return true; + } + + internal static string ToXRayTraceIdFormat(string traceId) + { + var sb = new StringBuilder(); + sb.Append(Version); + sb.Append(TraceIdDelimiter); + sb.Append(traceId.Substring(0, EpochHexDigits)); + sb.Append(TraceIdDelimiter); + sb.Append(traceId.Substring(EpochHexDigits)); + + return sb.ToString(); } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs index 7690bb2f34..7257b70fb0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs @@ -17,39 +17,38 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension method to generate AWS X-Ray compatible trace id and replace the trace id of root activity. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension method to generate AWS X-Ray compatible trace id and replace the trace id of root activity. + /// Replace the trace id of root activity. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// The instance of . + public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder builder) { - /// - /// Replace the trace id of root activity. - /// - /// being configured. - /// The instance of . - public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder builder) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - AWSXRayIdGenerator.ReplaceTraceId(); - return builder; - } + AWSXRayIdGenerator.ReplaceTraceId(); + return builder; + } - /// - /// 1. Replace the trace id of root activity. - /// 2. Update the sampling decision for root activity when it's created through ActivitySource.StartActivity(). - /// - /// being configured. - /// being used. - /// The instance of . - public static TracerProviderBuilder AddXRayTraceIdWithSampler(this TracerProviderBuilder builder, Sampler sampler) - { - Guard.ThrowIfNull(builder); + /// + /// 1. Replace the trace id of root activity. + /// 2. Update the sampling decision for root activity when it's created through ActivitySource.StartActivity(). + /// + /// being configured. + /// being used. + /// The instance of . + public static TracerProviderBuilder AddXRayTraceIdWithSampler(this TracerProviderBuilder builder, Sampler sampler) + { + Guard.ThrowIfNull(builder); - AWSXRayIdGenerator.ReplaceTraceId(sampler); - return builder; - } + AWSXRayIdGenerator.ReplaceTraceId(sampler); + return builder; } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs index 3fb384be33..b2cc6eda64 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs @@ -14,16 +14,15 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.AWS +namespace OpenTelemetry.Contrib.Instrumentation.AWS; + +/// +/// Options for AWS client instrumentation. +/// +public class AWSClientInstrumentationOptions { /// - /// Options for AWS client instrumentation. + /// Gets or sets a value indicating whether downstream Http instrumentation is suppressed. /// - public class AWSClientInstrumentationOptions - { - /// - /// Gets or sets a value indicating whether downstream Http instrumentation is suppressed. - /// - public bool SuppressDownstreamInstrumentation { get; set; } = true; - } + public bool SuppressDownstreamInstrumentation { get; set; } = true; } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs index fcf0ca5fce..24de661b95 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs @@ -16,13 +16,12 @@ using Amazon.Runtime.Internal; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal class AWSClientsInstrumentation { - internal class AWSClientsInstrumentation + public AWSClientsInstrumentation(AWSClientInstrumentationOptions options) { - public AWSClientsInstrumentation(AWSClientInstrumentationOptions options) - { - RuntimePipelineCustomizerRegistry.Instance.Register(new AWSTracingPipelineCustomizer(options)); - } + RuntimePipelineCustomizerRegistry.Instance.Register(new AWSTracingPipelineCustomizer(options)); } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index 43090d2c85..b61cff81e5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -14,21 +14,20 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal static class AWSSemanticConventions { - internal static class AWSSemanticConventions - { - public const string AttributeAWSServiceName = "aws.service"; - public const string AttributeAWSOperationName = "aws.operation"; - public const string AttributeAWSRegion = "aws.region"; - public const string AttributeAWSRequestId = "aws.requestId"; + public const string AttributeAWSServiceName = "aws.service"; + public const string AttributeAWSOperationName = "aws.operation"; + public const string AttributeAWSRegion = "aws.region"; + public const string AttributeAWSRequestId = "aws.requestId"; - public const string AttributeAWSDynamoTableName = "aws.table_name"; - public const string AttributeAWSSQSQueueUrl = "aws.queue_url"; + public const string AttributeAWSDynamoTableName = "aws.table_name"; + public const string AttributeAWSSQSQueueUrl = "aws.queue_url"; - public const string AttributeHttpStatusCode = "http.status_code"; - public const string AttributeHttpResponseContentLength = "http.response_content_length"; + public const string AttributeHttpStatusCode = "http.status_code"; + public const string AttributeHttpResponseContentLength = "http.response_content_length"; - public const string AttributeValueDynamoDb = "dynamodb"; - } + public const string AttributeValueDynamoDb = "dynamodb"; } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index d884b21003..b36964b4ea 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -18,37 +18,36 @@ using System.Collections.Generic; using Amazon.Runtime; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal class AWSServiceHelper { - internal class AWSServiceHelper + internal static IReadOnlyDictionary ServiceParameterMap = new Dictionary() + { + { DynamoDbService, "TableName" }, + { SQSService, "QueueUrl" }, + }; + + internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() + { + { "TableName", AWSSemanticConventions.AttributeAWSDynamoTableName }, + { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, + }; + + private const string DynamoDbService = "DynamoDBv2"; + private const string SQSService = "SQS"; + + internal static string GetAWSServiceName(IRequestContext requestContext) + => Utils.RemoveAmazonPrefixFromServiceName(requestContext.Request.ServiceName); + + internal static string GetAWSOperationName(IRequestContext requestContext) { - internal static IReadOnlyDictionary ServiceParameterMap = new Dictionary() - { - { DynamoDbService, "TableName" }, - { SQSService, "QueueUrl" }, - }; - - internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() - { - { "TableName", AWSSemanticConventions.AttributeAWSDynamoTableName }, - { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, - }; - - private const string DynamoDbService = "DynamoDBv2"; - private const string SQSService = "SQS"; - - internal static string GetAWSServiceName(IRequestContext requestContext) - => Utils.RemoveAmazonPrefixFromServiceName(requestContext.Request.ServiceName); - - internal static string GetAWSOperationName(IRequestContext requestContext) - { - string completeRequestName = requestContext.OriginalRequest.GetType().Name; - string suffix = "Request"; - var operationName = Utils.RemoveSuffix(completeRequestName, suffix); - return operationName; - } - - internal static bool IsDynamoDbService(string service) - => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); + string completeRequestName = requestContext.OriginalRequest.GetType().Name; + string suffix = "Request"; + var operationName = Utils.RemoveSuffix(completeRequestName, suffix); + return operationName; } + + internal static bool IsDynamoDbService(string service) + => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index 20da211edb..2f93d2e23f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -18,33 +18,32 @@ using Amazon.Runtime; using Amazon.Runtime.Internal; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer { - internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer + private readonly AWSClientInstrumentationOptions options; + + public AWSTracingPipelineCustomizer(AWSClientInstrumentationOptions options) { - private readonly AWSClientInstrumentationOptions options; + this.options = options; + } - public AWSTracingPipelineCustomizer(AWSClientInstrumentationOptions options) + public string UniqueName + { + get { - this.options = options; + return "AWS Tracing Registration Customization"; } + } - public string UniqueName + public void Customize(Type serviceClientType, RuntimePipeline pipeline) + { + if (serviceClientType.BaseType != typeof(AmazonServiceClient)) { - get - { - return "AWS Tracing Registration Customization"; - } + return; } - public void Customize(Type serviceClientType, RuntimePipeline pipeline) - { - if (serviceClientType.BaseType != typeof(AmazonServiceClient)) - { - return; - } - - pipeline.AddHandlerAfter(new AWSTracingPipelineHandler(this.options)); - } + pipeline.AddHandlerAfter(new AWSTracingPipelineHandler(this.options)); } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index e731aabff4..bbce612cf6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -25,216 +25,215 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal class AWSTracingPipelineHandler : PipelineHandler { - internal class AWSTracingPipelineHandler : PipelineHandler + internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; + + private static readonly AWSXRayPropagator AwsPropagator = new AWSXRayPropagator(); + private static readonly Action, string, string> Setter = (carrier, name, value) => { - internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; + carrier[name] = value; + }; - private static readonly AWSXRayPropagator AwsPropagator = new AWSXRayPropagator(); - private static readonly Action, string, string> Setter = (carrier, name, value) => - { - carrier[name] = value; - }; + private static readonly ActivitySource AWSSDKActivitySource = new ActivitySource(ActivitySourceName); - private static readonly ActivitySource AWSSDKActivitySource = new ActivitySource(ActivitySourceName); + private readonly AWSClientInstrumentationOptions options; - private readonly AWSClientInstrumentationOptions options; + public AWSTracingPipelineHandler(AWSClientInstrumentationOptions options) + { + this.options = options; + } - public AWSTracingPipelineHandler(AWSClientInstrumentationOptions options) + public override void InvokeSync(IExecutionContext executionContext) + { + var activity = this.ProcessBeginRequest(executionContext); + try { - this.options = options; + base.InvokeSync(executionContext); } - - public override void InvokeSync(IExecutionContext executionContext) + catch (Exception ex) { - var activity = this.ProcessBeginRequest(executionContext); - try + if (activity != null) { - base.InvokeSync(executionContext); + this.ProcessException(activity, ex); } - catch (Exception ex) - { - if (activity != null) - { - this.ProcessException(activity, ex); - } - throw; - } - finally + throw; + } + finally + { + if (activity != null) { - if (activity != null) - { - this.ProcessEndRequest(executionContext, activity); - } + this.ProcessEndRequest(executionContext, activity); } } + } - public override async Task InvokeAsync(IExecutionContext executionContext) - { - T ret = null; + public override async Task InvokeAsync(IExecutionContext executionContext) + { + T ret = null; - var activity = this.ProcessBeginRequest(executionContext); - try + var activity = this.ProcessBeginRequest(executionContext); + try + { + ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); + } + catch (Exception ex) + { + if (activity != null) { - ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); + this.ProcessException(activity, ex); } - catch (Exception ex) - { - if (activity != null) - { - this.ProcessException(activity, ex); - } - throw; - } - finally + throw; + } + finally + { + if (activity != null) { - if (activity != null) - { - this.ProcessEndRequest(executionContext, activity); - } + this.ProcessEndRequest(executionContext, activity); } - - return ret; } - private Activity ProcessBeginRequest(IExecutionContext executionContext) - { - Activity activity = null; + return ret; + } - var requestContext = executionContext.RequestContext; - var service = AWSServiceHelper.GetAWSServiceName(requestContext); - var operation = AWSServiceHelper.GetAWSOperationName(requestContext); + private Activity ProcessBeginRequest(IExecutionContext executionContext) + { + Activity activity = null; - activity = AWSSDKActivitySource.StartActivity(service + "." + operation, ActivityKind.Client); + var requestContext = executionContext.RequestContext; + var service = AWSServiceHelper.GetAWSServiceName(requestContext); + var operation = AWSServiceHelper.GetAWSOperationName(requestContext); - if (activity == null) - { - return null; - } + activity = AWSSDKActivitySource.StartActivity(service + "." + operation, ActivityKind.Client); - if (this.options.SuppressDownstreamInstrumentation) + if (activity == null) + { + return null; + } + + if (this.options.SuppressDownstreamInstrumentation) + { + SuppressInstrumentationScope.Enter(); + } + + if (activity.IsAllDataRequested) + { + activity.SetTag(AWSSemanticConventions.AttributeAWSServiceName, service); + activity.SetTag(AWSSemanticConventions.AttributeAWSOperationName, operation); + var client = executionContext.RequestContext.ClientConfig; + if (client != null) { - SuppressInstrumentationScope.Enter(); + var region = client.RegionEndpoint?.SystemName; + activity.SetTag(AWSSemanticConventions.AttributeAWSRegion, region ?? AWSSDKUtils.DetermineRegion(client.ServiceURL)); } - if (activity.IsAllDataRequested) - { - activity.SetTag(AWSSemanticConventions.AttributeAWSServiceName, service); - activity.SetTag(AWSSemanticConventions.AttributeAWSOperationName, operation); - var client = executionContext.RequestContext.ClientConfig; - if (client != null) - { - var region = client.RegionEndpoint?.SystemName; - activity.SetTag(AWSSemanticConventions.AttributeAWSRegion, region ?? AWSSDKUtils.DetermineRegion(client.ServiceURL)); - } + this.AddRequestSpecificInformation(activity, requestContext, service); + } - this.AddRequestSpecificInformation(activity, requestContext, service); - } + AwsPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), requestContext.Request.Headers, Setter); - AwsPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), requestContext.Request.Headers, Setter); + return activity; + } - return activity; - } + private void ProcessEndRequest(IExecutionContext executionContext, Activity activity) + { + var responseContext = executionContext.ResponseContext; + var requestContext = executionContext.RequestContext; - private void ProcessEndRequest(IExecutionContext executionContext, Activity activity) + if (activity.IsAllDataRequested) { - var responseContext = executionContext.ResponseContext; - var requestContext = executionContext.RequestContext; - - if (activity.IsAllDataRequested) + if (Utils.GetTagValue(activity, AWSSemanticConventions.AttributeAWSRequestId) == null) { - if (Utils.GetTagValue(activity, AWSSemanticConventions.AttributeAWSRequestId) == null) - { - activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, this.FetchRequestId(requestContext, responseContext)); - } + activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, this.FetchRequestId(requestContext, responseContext)); + } - var httpResponse = responseContext.HttpResponse; - if (httpResponse != null) - { - int statusCode = (int)httpResponse.StatusCode; + var httpResponse = responseContext.HttpResponse; + if (httpResponse != null) + { + int statusCode = (int)httpResponse.StatusCode; - this.AddStatusCodeToActivity(activity, statusCode); - activity.SetTag(AWSSemanticConventions.AttributeHttpResponseContentLength, httpResponse.ContentLength); - } + this.AddStatusCodeToActivity(activity, statusCode); + activity.SetTag(AWSSemanticConventions.AttributeHttpResponseContentLength, httpResponse.ContentLength); } - - activity.Stop(); } - private void ProcessException(Activity activity, Exception ex) + activity.Stop(); + } + + private void ProcessException(Activity activity, Exception ex) + { + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) - { - activity.RecordException(ex); + activity.RecordException(ex); - activity.SetStatus(Status.Error.WithDescription(ex.Message)); + activity.SetStatus(Status.Error.WithDescription(ex.Message)); - if (ex is AmazonServiceException amazonServiceException) - { - this.AddStatusCodeToActivity(activity, (int)amazonServiceException.StatusCode); - activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, amazonServiceException.RequestId); - } + if (ex is AmazonServiceException amazonServiceException) + { + this.AddStatusCodeToActivity(activity, (int)amazonServiceException.StatusCode); + activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, amazonServiceException.RequestId); } } + } - private void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) + private void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) + { + if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out string parameter)) { - if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out string parameter)) - { - AmazonWebServiceRequest request = requestContext.OriginalRequest; + AmazonWebServiceRequest request = requestContext.OriginalRequest; - var property = request.GetType().GetProperty(parameter); - if (property != null) + var property = request.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out string attribute)) { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out string attribute)) - { - activity.SetTag(attribute, property.GetValue(request)); - } + activity.SetTag(attribute, property.GetValue(request)); } } - - if (AWSServiceHelper.IsDynamoDbService(service)) - { - activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); - } } - private void AddStatusCodeToActivity(Activity activity, int status_code) + if (AWSServiceHelper.IsDynamoDbService(service)) { - activity.SetTag(AWSSemanticConventions.AttributeHttpStatusCode, status_code); + activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); } + } - private string FetchRequestId(IRequestContext requestContext, IResponseContext responseContext) + private void AddStatusCodeToActivity(Activity activity, int status_code) + { + activity.SetTag(AWSSemanticConventions.AttributeHttpStatusCode, status_code); + } + + private string FetchRequestId(IRequestContext requestContext, IResponseContext responseContext) + { + string request_id = string.Empty; + var response = responseContext.Response; + if (response != null) { - string request_id = string.Empty; - var response = responseContext.Response; - if (response != null) + request_id = response.ResponseMetadata.RequestId; + } + else + { + var request_headers = requestContext.Request.Headers; + if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amzn-RequestId", out string req_id)) { - request_id = response.ResponseMetadata.RequestId; + request_id = req_id; } - else - { - var request_headers = requestContext.Request.Headers; - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amzn-RequestId", out string req_id)) - { - request_id = req_id; - } - - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amz-request-id", out req_id)) - { - request_id = req_id; - } - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amz-id-2", out req_id)) - { - request_id = req_id; - } + if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amz-request-id", out req_id)) + { + request_id = req_id; } - return request_id; + if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amz-id-2", out req_id)) + { + request_id = req_id; + } } + + return request_id; } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs index 1104e4b66a..6eec23f4fb 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs @@ -17,64 +17,63 @@ using System.Collections.Generic; using System.Diagnostics; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal class Utils { - internal class Utils + internal static object GetTagValue(Activity activity, string tagName) { - internal static object GetTagValue(Activity activity, string tagName) + foreach (KeyValuePair tag in activity.TagObjects) { - foreach (KeyValuePair tag in activity.TagObjects) + if (tag.Key.Equals(tagName)) { - if (tag.Key.Equals(tagName)) - { - return tag.Value; - } + return tag.Value; } + } + + return null; + } - return null; + internal static string RemoveSuffix(string originalString, string suffix) + { + if (string.IsNullOrEmpty(originalString)) + { + return string.Empty; } - internal static string RemoveSuffix(string originalString, string suffix) + if (originalString.EndsWith(suffix)) { - if (string.IsNullOrEmpty(originalString)) - { - return string.Empty; - } + return originalString.Substring(0, originalString.Length - suffix.Length); + } - if (originalString.EndsWith(suffix)) - { - return originalString.Substring(0, originalString.Length - suffix.Length); - } + return originalString; + } - return originalString; - } + /// + /// Removes amazon prefix from service name. There are two type of service name. + /// Amazon.DynamoDbV2 + /// AmazonS3 + /// . + /// + /// Name of the service. + /// String after removing Amazon prefix. + internal static string RemoveAmazonPrefixFromServiceName(string serviceName) + { + return RemovePrefix(RemovePrefix(serviceName, "Amazon"), "."); + } - /// - /// Removes amazon prefix from service name. There are two type of service name. - /// Amazon.DynamoDbV2 - /// AmazonS3 - /// . - /// - /// Name of the service. - /// String after removing Amazon prefix. - internal static string RemoveAmazonPrefixFromServiceName(string serviceName) + private static string RemovePrefix(string originalString, string prefix) + { + if (string.IsNullOrEmpty(originalString)) { - return RemovePrefix(RemovePrefix(serviceName, "Amazon"), "."); + return string.Empty; } - private static string RemovePrefix(string originalString, string prefix) + if (originalString.StartsWith(prefix)) { - if (string.IsNullOrEmpty(originalString)) - { - return string.Empty; - } - - if (originalString.StartsWith(prefix)) - { - return originalString.Substring(prefix.Length); - } - - return originalString; + return originalString.Substring(prefix.Length); } + + return originalString; } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index bb08c911d6..80c0d0efed 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -19,31 +19,30 @@ using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables AWS Instrumentation. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// AWS client configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAWSInstrumentation( + this TracerProviderBuilder builder, + Action configure = null) { - /// - /// Enables AWS Instrumentation. - /// - /// being configured. - /// AWS client configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddAWSInstrumentation( - this TracerProviderBuilder builder, - Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var awsClientOptions = new AWSClientInstrumentationOptions(); - configure?.Invoke(awsClientOptions); + var awsClientOptions = new AWSClientInstrumentationOptions(); + configure?.Invoke(awsClientOptions); - new AWSClientsInstrumentation(awsClientOptions); - builder.AddSource("Amazon.AWS.AWSClientInstrumentation"); - return builder; - } + new AWSClientsInstrumentation(awsClientOptions); + builder.AddSource("Amazon.AWS.AWSClientInstrumentation"); + return builder; } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs index dff492f750..1fc086521c 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs @@ -14,16 +14,15 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.AWSLambda +namespace OpenTelemetry.Instrumentation.AWSLambda; + +/// +/// AWS lambda instrumentation options. +/// +public class AWSLambdaInstrumentationOptions { /// - /// AWS lambda instrumentation options. + /// Gets or sets a value indicating whether AWS X-Ray context extraction should be disabled. /// - public class AWSLambdaInstrumentationOptions - { - /// - /// Gets or sets a value indicating whether AWS X-Ray context extraction should be disabled. - /// - public bool DisableAwsXRayContextExtraction { get; set; } - } + public bool DisableAwsXRayContextExtraction { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 17fa2de592..c2995f5231 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -23,226 +23,225 @@ using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.AWSLambda +namespace OpenTelemetry.Instrumentation.AWSLambda; + +/// +/// Wrapper class for AWS Lambda handlers. +/// +public static class AWSLambdaWrapper { - /// - /// Wrapper class for AWS Lambda handlers. - /// - public static class AWSLambdaWrapper - { - private static readonly AssemblyName AssemblyName = typeof(AWSLambdaWrapper).Assembly.GetName(); + private static readonly AssemblyName AssemblyName = typeof(AWSLambdaWrapper).Assembly.GetName(); - [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Initialization order.")] - internal static readonly string ActivitySourceName = AssemblyName.Name; + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Initialization order.")] + internal static readonly string ActivitySourceName = AssemblyName.Name; - private static readonly Version Version = AssemblyName.Version; - private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, Version.ToString()); + private static readonly Version Version = AssemblyName.Version; + private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, Version.ToString()); - /// - /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. - /// - internal static bool DisableAwsXRayContextExtraction { get; set; } + /// + /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. + /// + internal static bool DisableAwsXRayContextExtraction { get; set; } #pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters - /// - /// Tracing wrapper for Lambda handler. - /// - /// Input. - /// Output result. - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of input. - /// Instance of lambda context. - /// - /// The optional parent context is used for Activity object creation. - /// If no parent context provided, incoming request is used to extract one. - /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one - /// unless X-Ray propagation is disabled in the configuration for this wrapper. - /// - /// Instance of output result. - public static TResult Trace( - TracerProvider tracerProvider, - Func lambdaHandler, - TInput input, - ILambdaContext context, - ActivityContext parentContext = default) - { - TResult result = default; - Action action = () => result = lambdaHandler(input, context); - TraceInternal(tracerProvider, action, input, context, parentContext); - return result; - } + /// + /// Tracing wrapper for Lambda handler. + /// + /// Input. + /// Output result. + /// TracerProvider passed in. + /// Lambda handler function passed in. + /// Instance of input. + /// Instance of lambda context. + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + /// Instance of output result. + public static TResult Trace( + TracerProvider tracerProvider, + Func lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) + { + TResult result = default; + Action action = () => result = lambdaHandler(input, context); + TraceInternal(tracerProvider, action, input, context, parentContext); + return result; + } - /// - /// Tracing wrapper for Lambda handler. - /// - /// Input. - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of input. - /// Instance of lambda context. - /// - /// The optional parent context is used for Activity object creation. - /// If no parent context provided, incoming request is used to extract one. - /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one - /// unless X-Ray propagation is disabled in the configuration for this wrapper. - /// - public static void Trace( - TracerProvider tracerProvider, - Action lambdaHandler, - TInput input, - ILambdaContext context, - ActivityContext parentContext = default) - { - Action action = () => lambdaHandler(input, context); - TraceInternal(tracerProvider, action, input, context, parentContext); - } + /// + /// Tracing wrapper for Lambda handler. + /// + /// Input. + /// TracerProvider passed in. + /// Lambda handler function passed in. + /// Instance of input. + /// Instance of lambda context. + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + public static void Trace( + TracerProvider tracerProvider, + Action lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) + { + Action action = () => lambdaHandler(input, context); + TraceInternal(tracerProvider, action, input, context, parentContext); + } - /// - /// Tracing wrapper for async Lambda handler. - /// - /// Input. - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of input. - /// Lambda context (optional, but strongly recommended). - /// - /// The optional parent context is used for Activity object creation. - /// If no parent context provided, incoming request is used to extract one. - /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one - /// unless X-Ray propagation is disabled in the configuration for this wrapper. - /// - /// Task. - public static Task TraceAsync( - TracerProvider tracerProvider, - Func lambdaHandler, - TInput input, - ILambdaContext context, - ActivityContext parentContext = default) - { - Func action = async () => await lambdaHandler(input, context); - return TraceInternalAsync(tracerProvider, action, input, context, parentContext); - } + /// + /// Tracing wrapper for async Lambda handler. + /// + /// Input. + /// TracerProvider passed in. + /// Lambda handler function passed in. + /// Instance of input. + /// Lambda context (optional, but strongly recommended). + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + /// Task. + public static Task TraceAsync( + TracerProvider tracerProvider, + Func lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) + { + Func action = async () => await lambdaHandler(input, context); + return TraceInternalAsync(tracerProvider, action, input, context, parentContext); + } - /// - /// Tracing wrapper for async Lambda handler. - /// - /// Input. - /// Output result. - /// TracerProvider passed in. - /// Lambda handler function passed in. - /// Instance of input. - /// Instance of lambda context. - /// - /// The optional parent context is used for Activity object creation. - /// If no parent context provided, incoming request is used to extract one. - /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one - /// unless X-Ray propagation is disabled in the configuration for this wrapper. - /// - /// Task of result. - public static async Task TraceAsync( - TracerProvider tracerProvider, - Func> lambdaHandler, - TInput input, - ILambdaContext context, - ActivityContext parentContext = default) - { - TResult result = default; - Func action = async () => result = await lambdaHandler(input, context); - await TraceInternalAsync(tracerProvider, action, input, context, parentContext); - return result; - } + /// + /// Tracing wrapper for async Lambda handler. + /// + /// Input. + /// Output result. + /// TracerProvider passed in. + /// Lambda handler function passed in. + /// Instance of input. + /// Instance of lambda context. + /// + /// The optional parent context is used for Activity object creation. + /// If no parent context provided, incoming request is used to extract one. + /// If parent is not extracted from incoming request then X-Ray propagation is used to extract one + /// unless X-Ray propagation is disabled in the configuration for this wrapper. + /// + /// Task of result. + public static async Task TraceAsync( + TracerProvider tracerProvider, + Func> lambdaHandler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) + { + TResult result = default; + Func action = async () => result = await lambdaHandler(input, context); + await TraceInternalAsync(tracerProvider, action, input, context, parentContext); + return result; + } #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters - internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) + internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) + { + if (parentContext == default) { - if (parentContext == default) + parentContext = AWSLambdaUtils.ExtractParentContext(input); + if (parentContext == default && !DisableAwsXRayContextExtraction) { - parentContext = AWSLambdaUtils.ExtractParentContext(input); - if (parentContext == default && !DisableAwsXRayContextExtraction) - { - parentContext = AWSLambdaUtils.GetXRayParentContext(); - } + parentContext = AWSLambdaUtils.GetXRayParentContext(); } + } - var tags = AWSLambdaUtils.GetFunctionTags(input, context); - var activityName = AWSLambdaUtils.GetFunctionName(context) ?? "AWS Lambda Invoke"; - var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, tags); + var tags = AWSLambdaUtils.GetFunctionTags(input, context); + var activityName = AWSLambdaUtils.GetFunctionName(context) ?? "AWS Lambda Invoke"; + var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, tags); - return activity; - } + return activity; + } - private static void OnFunctionStop(Activity activity, TracerProvider tracerProvider) + private static void OnFunctionStop(Activity activity, TracerProvider tracerProvider) + { + if (activity != null) { - if (activity != null) - { - activity.Stop(); - } - - // force flush before function quit in case of Lambda freeze. - tracerProvider?.ForceFlush(); + activity.Stop(); } - private static void OnException(Activity activity, Exception exception) + // force flush before function quit in case of Lambda freeze. + tracerProvider?.ForceFlush(); + } + + private static void OnException(Activity activity, Exception exception) + { + if (activity != null) { - if (activity != null) + if (activity.IsAllDataRequested) { - if (activity.IsAllDataRequested) - { - activity.RecordException(exception); - activity.SetStatus(Status.Error.WithDescription(exception.Message)); - } + activity.RecordException(exception); + activity.SetStatus(Status.Error.WithDescription(exception.Message)); } } + } - private static void TraceInternal( - TracerProvider tracerProvider, - Action handler, - TInput input, - ILambdaContext context, - ActivityContext parentContext = default) + private static void TraceInternal( + TracerProvider tracerProvider, + Action handler, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) + { + var lambdaActivity = OnFunctionStart(input, context, parentContext); + try { - var lambdaActivity = OnFunctionStart(input, context, parentContext); - try - { - handler(); - } - catch (Exception ex) - { - OnException(lambdaActivity, ex); + handler(); + } + catch (Exception ex) + { + OnException(lambdaActivity, ex); - throw; - } - finally - { - OnFunctionStop(lambdaActivity, tracerProvider); - } + throw; + } + finally + { + OnFunctionStop(lambdaActivity, tracerProvider); } + } - private static async Task TraceInternalAsync( - TracerProvider tracerProvider, - Func handlerAsync, - TInput input, - ILambdaContext context, - ActivityContext parentContext = default) + private static async Task TraceInternalAsync( + TracerProvider tracerProvider, + Func handlerAsync, + TInput input, + ILambdaContext context, + ActivityContext parentContext = default) + { + var lambdaActivity = OnFunctionStart(input, context, parentContext); + try { - var lambdaActivity = OnFunctionStart(input, context, parentContext); - try - { - await handlerAsync(); - } - catch (Exception ex) - { - OnException(lambdaActivity, ex); + await handlerAsync(); + } + catch (Exception ex) + { + OnException(lambdaActivity, ex); - throw; - } - finally - { - OnFunctionStop(lambdaActivity, tracerProvider); - } + throw; + } + finally + { + OnFunctionStop(lambdaActivity, tracerProvider); } } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs index 1c08ddf592..34a3cf144c 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs @@ -16,25 +16,24 @@ using System.Collections.Generic; -namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; + +internal static class AWSLambdaResourceDetector { - internal static class AWSLambdaResourceDetector + /// + /// Detect the resource attributes for AWS Lambda. + /// + /// List of resource attributes pairs. + internal static IEnumerable> Detect() { - /// - /// Detect the resource attributes for AWS Lambda. - /// - /// List of resource attributes pairs. - internal static IEnumerable> Detect() + var resourceAttributes = new List>() { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSLambdaSemanticConventions.AttributeCloudProvider, AWSLambdaUtils.GetCloudProvider()), - new KeyValuePair(AWSLambdaSemanticConventions.AttributeCloudRegion, AWSLambdaUtils.GetAWSRegion()), - new KeyValuePair(AWSLambdaSemanticConventions.AttributeFaasName, AWSLambdaUtils.GetFunctionName()), - new KeyValuePair(AWSLambdaSemanticConventions.AttributeFaasVersion, AWSLambdaUtils.GetFunctionVersion()), - }; + new KeyValuePair(AWSLambdaSemanticConventions.AttributeCloudProvider, AWSLambdaUtils.GetCloudProvider()), + new KeyValuePair(AWSLambdaSemanticConventions.AttributeCloudRegion, AWSLambdaUtils.GetAWSRegion()), + new KeyValuePair(AWSLambdaSemanticConventions.AttributeFaasName, AWSLambdaUtils.GetFunctionName()), + new KeyValuePair(AWSLambdaSemanticConventions.AttributeFaasVersion, AWSLambdaUtils.GetFunctionVersion()), + }; - return resourceAttributes; - } + return resourceAttributes; } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs index 0674a9986f..a5bb50bcef 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs @@ -14,20 +14,19 @@ // limitations under the License. // -namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; + +/// +/// Semantic conventions for AWS Lambda. +/// +internal static class AWSLambdaSemanticConventions { - /// - /// Semantic conventions for AWS Lambda. - /// - internal static class AWSLambdaSemanticConventions - { - public const string AttributeCloudAccountID = "cloud.account.id"; - public const string AttributeCloudProvider = "cloud.provider"; - public const string AttributeCloudRegion = "cloud.region"; - public const string AttributeFaasExecution = "faas.execution"; - public const string AttributeFaasID = "faas.id"; - public const string AttributeFaasName = "faas.name"; - public const string AttributeFaasVersion = "faas.version"; - public const string AttributeFaasTrigger = "faas.trigger"; - } + public const string AttributeCloudAccountID = "cloud.account.id"; + public const string AttributeCloudProvider = "cloud.provider"; + public const string AttributeCloudRegion = "cloud.region"; + public const string AttributeFaasExecution = "faas.execution"; + public const string AttributeFaasID = "faas.id"; + public const string AttributeFaasName = "faas.name"; + public const string AttributeFaasVersion = "faas.version"; + public const string AttributeFaasTrigger = "faas.trigger"; } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index d796910781..c2ae886f0d 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -23,195 +23,194 @@ using OpenTelemetry.Context.Propagation; using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; -namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; + +/// +/// Class for getting AWS Lambda related attributes. +/// +internal static class AWSLambdaUtils { - /// - /// Class for getting AWS Lambda related attributes. - /// - internal static class AWSLambdaUtils + private const string CloudProvider = "aws"; + private const string AWSRegion = "AWS_REGION"; + private const string AWSXRayLambdaTraceHeaderKey = "_X_AMZN_TRACE_ID"; + private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; + private const string FunctionName = "AWS_LAMBDA_FUNCTION_NAME"; + private const string FunctionVersion = "AWS_LAMBDA_FUNCTION_VERSION"; + + private static readonly Func, string, IEnumerable> Getter = (headers, name) => { - private const string CloudProvider = "aws"; - private const string AWSRegion = "AWS_REGION"; - private const string AWSXRayLambdaTraceHeaderKey = "_X_AMZN_TRACE_ID"; - private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; - private const string FunctionName = "AWS_LAMBDA_FUNCTION_NAME"; - private const string FunctionVersion = "AWS_LAMBDA_FUNCTION_VERSION"; - - private static readonly Func, string, IEnumerable> Getter = (headers, name) => + if (headers.TryGetValue(name, out var value)) { - if (headers.TryGetValue(name, out var value)) - { - return new[] { value }; - } + return new[] { value }; + } - return new string[0]; - }; + return new string[0]; + }; - internal static ActivityContext GetXRayParentContext() + internal static ActivityContext GetXRayParentContext() + { + // Currently get trace header from Lambda runtime environment variable + // https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime + // TODO: Add steps to extract trace header from http header + + var tracerHeaderValue = Environment.GetEnvironmentVariable(AWSXRayLambdaTraceHeaderKey); + if (tracerHeaderValue == null) { - // Currently get trace header from Lambda runtime environment variable - // https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime - // TODO: Add steps to extract trace header from http header + return default; + } - var tracerHeaderValue = Environment.GetEnvironmentVariable(AWSXRayLambdaTraceHeaderKey); - if (tracerHeaderValue == null) - { - return default; - } + var activityContext = ParseXRayTraceHeader(tracerHeaderValue); + return activityContext; + } - var activityContext = ParseXRayTraceHeader(tracerHeaderValue); - return activityContext; + internal static ActivityContext ExtractParentContext(TInput input) + { + PropagationContext propagationContext = default; + switch (input) + { + case APIGatewayProxyRequest apiGatewayProxyRequest: + propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayProxyRequest, GetHeaderValues); + break; + case APIGatewayHttpApiV2ProxyRequest apiGatewayHttpApiV2ProxyRequest: + propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayHttpApiV2ProxyRequest, GetHeaderValues); + break; } - internal static ActivityContext ExtractParentContext(TInput input) - { - PropagationContext propagationContext = default; - switch (input) - { - case APIGatewayProxyRequest apiGatewayProxyRequest: - propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayProxyRequest, GetHeaderValues); - break; - case APIGatewayHttpApiV2ProxyRequest apiGatewayHttpApiV2ProxyRequest: - propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayHttpApiV2ProxyRequest, GetHeaderValues); - break; - } + return propagationContext.ActivityContext; + } - return propagationContext.ActivityContext; - } + internal static string GetCloudProvider() + { + return CloudProvider; + } - internal static string GetCloudProvider() + internal static string GetAWSRegion() + { + return Environment.GetEnvironmentVariable(AWSRegion); + } + + internal static string GetFunctionName(ILambdaContext context = null) + { + return context?.FunctionName ?? Environment.GetEnvironmentVariable(FunctionName); + } + + internal static string GetFunctionVersion() + { + return Environment.GetEnvironmentVariable(FunctionVersion); + } + + internal static IEnumerable> GetFunctionTags(TInput input, ILambdaContext context) + { + var tags = new List> { - return CloudProvider; - } + new(AWSLambdaSemanticConventions.AttributeFaasTrigger, GetFaasTrigger(input)), + }; - internal static string GetAWSRegion() + var functionName = GetFunctionName(context); + if (functionName != null) { - return Environment.GetEnvironmentVariable(AWSRegion); + tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasName, functionName)); } - internal static string GetFunctionName(ILambdaContext context = null) + if (context == null) { - return context?.FunctionName ?? Environment.GetEnvironmentVariable(FunctionName); + return tags; } - internal static string GetFunctionVersion() + if (context.AwsRequestId != null) { - return Environment.GetEnvironmentVariable(FunctionVersion); + tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasExecution, context.AwsRequestId)); } - internal static IEnumerable> GetFunctionTags(TInput input, ILambdaContext context) + var functionArn = context.InvokedFunctionArn; + if (functionArn != null) { - var tags = new List> - { - new(AWSLambdaSemanticConventions.AttributeFaasTrigger, GetFaasTrigger(input)), - }; - - var functionName = GetFunctionName(context); - if (functionName != null) - { - tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasName, functionName)); - } + tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasID, GetFaasId(functionArn))); - if (context == null) + var accountId = GetAccountId(functionArn); + if (accountId != null) { - return tags; + tags.Add(new(AWSLambdaSemanticConventions.AttributeCloudAccountID, accountId)); } + } - if (context.AwsRequestId != null) - { - tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasExecution, context.AwsRequestId)); - } - - var functionArn = context.InvokedFunctionArn; - if (functionArn != null) - { - tags.Add(new(AWSLambdaSemanticConventions.AttributeFaasID, GetFaasId(functionArn))); - - var accountId = GetAccountId(functionArn); - if (accountId != null) - { - tags.Add(new(AWSLambdaSemanticConventions.AttributeCloudAccountID, accountId)); - } - } + return tags; + } - return tags; - } + private static string GetAccountId(string functionArn) + { + // The fifth item of function arn: https://github.com/open-telemetry/opentelemetry-specification/blob/86aeab1e0a7e6c67be09c7f15ff25063ee6d2b5c/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers + // Function arn format - arn:aws:lambda:::function: - private static string GetAccountId(string functionArn) + var items = functionArn.Split(':'); + if (items.Length >= 5) { - // The fifth item of function arn: https://github.com/open-telemetry/opentelemetry-specification/blob/86aeab1e0a7e6c67be09c7f15ff25063ee6d2b5c/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers - // Function arn format - arn:aws:lambda:::function: + return items[4]; + } - var items = functionArn.Split(':'); - if (items.Length >= 5) - { - return items[4]; - } + return null; + } - return null; - } + private static string GetFaasId(string functionArn) + { + var faasId = functionArn; - private static string GetFaasId(string functionArn) + // According to faas.id description https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers + // the 8th part of arn (function version or alias, see https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html) + // should not be included into faas.id + var items = functionArn.Split(':'); + if (items.Length >= 8) { - var faasId = functionArn; + faasId = string.Join(":", items.Take(7)); + } - // According to faas.id description https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers - // the 8th part of arn (function version or alias, see https://docs.aws.amazon.com/lambda/latest/dg/lambda-api-permissions-ref.html) - // should not be included into faas.id - var items = functionArn.Split(':'); - if (items.Length >= 8) - { - faasId = string.Join(":", items.Take(7)); - } + return faasId; + } - return faasId; + private static string GetFaasTrigger(TInput input) + { + var trigger = "other"; + if (input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest) + { + trigger = "http"; } - private static string GetFaasTrigger(TInput input) - { - var trigger = "other"; - if (input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest) - { - trigger = "http"; - } + return trigger; + } - return trigger; - } + private static ActivityContext ParseXRayTraceHeader(string rawHeader) + { + var xrayPropagator = new AWSXRayPropagator(); - private static ActivityContext ParseXRayTraceHeader(string rawHeader) + var carrier = new Dictionary() { - var xrayPropagator = new AWSXRayPropagator(); - - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, rawHeader }, - }; + { AWSXRayTraceHeaderKey, rawHeader }, + }; - var propagationContext = xrayPropagator.Extract(default, carrier, Getter); - return propagationContext.ActivityContext; - } + var propagationContext = xrayPropagator.Extract(default, carrier, Getter); + return propagationContext.ActivityContext; + } - private static IEnumerable GetHeaderValues(APIGatewayProxyRequest request, string name) + private static IEnumerable GetHeaderValues(APIGatewayProxyRequest request, string name) + { + if (request.MultiValueHeaders != null && + request.MultiValueHeaders.TryGetValue(name, out var values)) { - if (request.MultiValueHeaders != null && - request.MultiValueHeaders.TryGetValue(name, out var values)) - { - return values; - } - - return null; + return values; } - private static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) - { - if (request.Headers != null && - request.Headers.TryGetValue(name, out var header)) - { - // Multiple values for the same header will be separated by a comma. - return header?.Split(','); - } + return null; + } - return null; + private static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) + { + if (request.Headers != null && + request.Headers.TryGetValue(name, out var header)) + { + // Multiple values for the same header will be separated by a comma. + return header?.Split(','); } + + return null; } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index 36f6b9eb8a..e6c523bd31 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -20,38 +20,37 @@ using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.AWSLambda +namespace OpenTelemetry.Instrumentation.AWSLambda; + +/// +/// Extension class for TracerProviderBuilder. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension class for TracerProviderBuilder. + /// Add AWS Lambda configurations. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// AWS lambda instrumentation options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAWSLambdaConfigurations( + this TracerProviderBuilder builder, + Action configure = null) { - /// - /// Add AWS Lambda configurations. - /// - /// being configured. - /// AWS lambda instrumentation options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddAWSLambdaConfigurations( - this TracerProviderBuilder builder, - Action configure = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var options = new AWSLambdaInstrumentationOptions(); - configure?.Invoke(options); + var options = new AWSLambdaInstrumentationOptions(); + configure?.Invoke(options); - AWSLambdaWrapper.DisableAwsXRayContextExtraction = options.DisableAwsXRayContextExtraction; + AWSLambdaWrapper.DisableAwsXRayContextExtraction = options.DisableAwsXRayContextExtraction; - builder.AddSource(AWSLambdaWrapper.ActivitySourceName); - builder.SetResourceBuilder(ResourceBuilder - .CreateEmpty() - .AddService(AWSLambdaUtils.GetFunctionName(), null, null, false) - .AddTelemetrySdk() - .AddAttributes(AWSLambdaResourceDetector.Detect())); + builder.AddSource(AWSLambdaWrapper.ActivitySourceName); + builder.SetResourceBuilder(ResourceBuilder + .CreateEmpty() + .AddService(AWSLambdaUtils.GetFunctionName(), null, null, false) + .AddTelemetrySdk() + .AddAttributes(AWSLambdaResourceDetector.Detect())); - return builder; - } + return builder; } } diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs index 0992f3216f..bc808da460 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs @@ -19,37 +19,36 @@ using OpenTelemetry.Instrumentation.MassTransit.Implementation; using OpenTelemetry.Internal; -namespace OpenTelemetry.Trace +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions { /// - /// Extension methods to simplify registering of dependency instrumentation. + /// Enables the outgoing requests automatic data collection for MassTransit. /// - public static class TracerProviderBuilderExtensions + /// being configured. + /// MassTransit configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddMassTransitInstrumentation( + this TracerProviderBuilder builder, + Action configureMassTransitInstrumentationOptions = null) { - /// - /// Enables the outgoing requests automatic data collection for MassTransit. - /// - /// being configured. - /// MassTransit configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddMassTransitInstrumentation( - this TracerProviderBuilder builder, - Action configureMassTransitInstrumentationOptions = null) - { - Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(builder); - var options = new MassTransitInstrumentationOptions(); - configureMassTransitInstrumentationOptions?.Invoke(options); + var options = new MassTransitInstrumentationOptions(); + configureMassTransitInstrumentationOptions?.Invoke(options); - builder.AddInstrumentation(() => new MassTransitInstrumentation(options)); - builder.AddSource(MassTransitDiagnosticListener.ActivitySourceName); + builder.AddInstrumentation(() => new MassTransitInstrumentation(options)); + builder.AddSource(MassTransitDiagnosticListener.ActivitySourceName); - builder.AddLegacySource(OperationName.Consumer.Consume); - builder.AddLegacySource(OperationName.Consumer.Handle); - builder.AddLegacySource(OperationName.Transport.Send); - builder.AddLegacySource(OperationName.Transport.Receive); + builder.AddLegacySource(OperationName.Consumer.Consume); + builder.AddLegacySource(OperationName.Consumer.Handle); + builder.AddLegacySource(OperationName.Transport.Send); + builder.AddLegacySource(OperationName.Transport.Receive); - return builder; - } + return builder; } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs index a85613c4c5..5b9c310500 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs @@ -20,64 +20,63 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http; + +internal class CertificateUploader : IDisposable { - internal class CertificateUploader : IDisposable - { - private const string CRTHEADER = "-----BEGIN CERTIFICATE-----\n"; - private const string CRTFOOTER = "\n-----END CERTIFICATE-----"; - private string filePath; + private const string CRTHEADER = "-----BEGIN CERTIFICATE-----\n"; + private const string CRTFOOTER = "\n-----END CERTIFICATE-----"; + private string filePath; - public CertificateUploader() - { - this.filePath = Path.GetTempFileName(); - } + public CertificateUploader() + { + this.filePath = Path.GetTempFileName(); + } - public string FilePath - { - get { return this.filePath; } - set { this.filePath = value; } - } + public string FilePath + { + get { return this.filePath; } + set { this.filePath = value; } + } - public void Create() - { - using var rsa = RSA.Create(); - var certRequest = new CertificateRequest("cn=test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + public void Create() + { + using var rsa = RSA.Create(); + var certRequest = new CertificateRequest("cn=test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - var subjectAlternativeNames = new SubjectAlternativeNameBuilder(); - subjectAlternativeNames.AddDnsName("test"); - certRequest.CertificateExtensions.Add(subjectAlternativeNames.Build()); + var subjectAlternativeNames = new SubjectAlternativeNameBuilder(); + subjectAlternativeNames.AddDnsName("test"); + certRequest.CertificateExtensions.Add(subjectAlternativeNames.Build()); - // Create a temporary certificate and add validity for 1 day - var certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(1)); + // Create a temporary certificate and add validity for 1 day + var certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddDays(1)); - var exportData = certificate.Export(X509ContentType.Cert); - var crt = Convert.ToBase64String(exportData, Base64FormattingOptions.InsertLineBreaks); + var exportData = certificate.Export(X509ContentType.Cert); + var crt = Convert.ToBase64String(exportData, Base64FormattingOptions.InsertLineBreaks); - using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + { + using (StreamWriter sw = new StreamWriter(stream)) { - using (StreamWriter sw = new StreamWriter(stream)) - { - sw.Write(CRTHEADER + crt + CRTFOOTER); - } + sw.Write(CRTHEADER + crt + CRTFOOTER); } } + } - public void Dispose() + public void Dispose() + { + for (int tries = 0; ; tries++) { - for (int tries = 0; ; tries++) + try + { + File.Delete(this.filePath); + return; + } + catch (IOException) when (tries < 3) { - try - { - File.Delete(this.filePath); - return; - } - catch (IOException) when (tries < 3) - { - // the file is unavailable because it is: still being written to or being processed by another thread - // sleep for sometime before deleting - Thread.Sleep(1000); - } + // the file is unavailable because it is: still being written to or being processed by another thread + // sleep for sometime before deleting + Thread.Sleep(1000); } } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs index 559e8363c9..cbac46d149 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs @@ -17,29 +17,28 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http; + +public class TestHandler { - public class TestHandler - { - private const string INVALIDCRTNAME = "invalidcert"; + private const string INVALIDCRTNAME = "invalidcert"; - [Fact] - public void TestValidHandler() + [Fact] + public void TestValidHandler() + { + using (CertificateUploader certificateUploader = new CertificateUploader()) { - using (CertificateUploader certificateUploader = new CertificateUploader()) - { - certificateUploader.Create(); + certificateUploader.Create(); - // Validates if the handler created. - Assert.NotNull(Handler.Create(certificateUploader.FilePath)); - } + // Validates if the handler created. + Assert.NotNull(Handler.Create(certificateUploader.FilePath)); } + } - [Fact] - public void TestInValidHandler() - { - // Validates if the handler created if no certificate is loaded into the trusted collection - Assert.Null(Handler.Create(INVALIDCRTNAME)); - } + [Fact] + public void TestInValidHandler() + { + // Validates if the handler created if no certificate is loaded into the trusted collection + Assert.Null(Handler.Create(INVALIDCRTNAME)); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs index 65d46676c5..6e1d910cbd 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs @@ -18,44 +18,43 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http; + +public class TestServerCertificateValidationProvider { - public class TestServerCertificateValidationProvider - { - private const string INVALIDCRTNAME = "invalidcert"; + private const string INVALIDCRTNAME = "invalidcert"; - [Fact] - public void TestValidCertificate() + [Fact] + public void TestValidCertificate() + { + using (CertificateUploader certificateUploader = new CertificateUploader()) { - using (CertificateUploader certificateUploader = new CertificateUploader()) - { - certificateUploader.Create(); + certificateUploader.Create(); - // Loads the certificate to the trusted collection from the file - ServerCertificateValidationProvider serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + // Loads the certificate to the trusted collection from the file + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); - // Validates if the certificate loaded into the trusted collection. - Assert.True(serverCertificateValidationProvider.IsCertificateLoaded); + // Validates if the certificate loaded into the trusted collection. + Assert.True(serverCertificateValidationProvider.IsCertificateLoaded); - var certificate = new X509Certificate2(certificateUploader.FilePath); - X509Chain chain = new X509Chain(); - chain.Build(certificate); + var certificate = new X509Certificate2(certificateUploader.FilePath); + X509Chain chain = new X509Chain(); + chain.Build(certificate); - // validates if certificate is valid - Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); - } + // validates if certificate is valid + Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); } + } - [Fact] - public void TestInValidCertificate() - { - // Loads the certificate to the trusted collection from the file - ServerCertificateValidationProvider serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(INVALIDCRTNAME); + [Fact] + public void TestInValidCertificate() + { + // Loads the certificate to the trusted collection from the file + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(INVALIDCRTNAME); - // Validates if the certificate file loaded. - Assert.False(serverCertificateValidationProvider.IsCertificateLoaded); - } + // Validates if the certificate file loaded. + Assert.False(serverCertificateValidationProvider.IsCertificateLoaded); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs index 61e12837cc..5b473225cd 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs @@ -16,15 +16,14 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +internal class SampleAWSEBSMetadataModel : AWSEBSMetadataModel { - internal class SampleAWSEBSMetadataModel : AWSEBSMetadataModel + public SampleAWSEBSMetadataModel() { - public SampleAWSEBSMetadataModel() - { - this.EnvironmentName = "Test environment name"; - this.DeploymentId = "Test ID"; - this.VersionLabel = "Test version label"; - } + this.EnvironmentName = "Test environment name"; + this.DeploymentId = "Test ID"; + this.VersionLabel = "Test version label"; } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs index 5d98b55ca9..45a068bf86 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs @@ -16,17 +16,16 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +internal class SampleAWSEC2IdentityDocumentModel : AWSEC2IdentityDocumentModel { - internal class SampleAWSEC2IdentityDocumentModel : AWSEC2IdentityDocumentModel + public SampleAWSEC2IdentityDocumentModel() { - public SampleAWSEC2IdentityDocumentModel() - { - this.AccountId = "Test account id"; - this.AvailabilityZone = "Test availability zone"; - this.Region = "Test aws region"; - this.InstanceId = "Test instance id"; - this.InstanceType = "Test instance type"; - } + this.AccountId = "Test account id"; + this.AvailabilityZone = "Test availability zone"; + this.Region = "Test aws region"; + this.InstanceId = "Test instance id"; + this.InstanceType = "Test instance type"; } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs index 4dfa908cbd..5aad80cc3b 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs @@ -19,46 +19,45 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +public class TestAWSEBSResourceDetector { - public class TestAWSEBSResourceDetector - { - private const string AWSEBSMetadataFilePath = "Resources/SampleMetadataFiles/environment.conf"; + private const string AWSEBSMetadataFilePath = "Resources/SampleMetadataFiles/environment.conf"; - [Fact] - public void TestDetect() - { - IEnumerable> resourceAttributes; - var ebsResourceDetector = new AWSEBSResourceDetector(); - resourceAttributes = ebsResourceDetector.Detect(); - Assert.Null(resourceAttributes); // will be null as it's not in ebs environment - } + [Fact] + public void TestDetect() + { + IEnumerable> resourceAttributes; + var ebsResourceDetector = new AWSEBSResourceDetector(); + resourceAttributes = ebsResourceDetector.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in ebs environment + } - [Fact] - public void TestExtractResourceAttributes() - { - var ebsResourceDetector = new AWSEBSResourceDetector(); - var sampleModel = new SampleAWSEBSMetadataModel(); + [Fact] + public void TestExtractResourceAttributes() + { + var ebsResourceDetector = new AWSEBSResourceDetector(); + var sampleModel = new SampleAWSEBSMetadataModel(); - var resourceAttributes = ebsResourceDetector.ExtractResourceAttributes(sampleModel).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = ebsResourceDetector.ExtractResourceAttributes(sampleModel).ToDictionary(x => x.Key, x => x.Value); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_elastic_beanstalk", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("aws_elastic_beanstalk", resourceAttributes[AWSSemanticConventions.AttributeServiceName]); - Assert.Equal("Test environment name", resourceAttributes[AWSSemanticConventions.AttributeServiceNamespace]); - Assert.Equal("Test ID", resourceAttributes[AWSSemanticConventions.AttributeServiceInstanceID]); - Assert.Equal("Test version label", resourceAttributes[AWSSemanticConventions.AttributeServiceVersion]); - } + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_elastic_beanstalk", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("aws_elastic_beanstalk", resourceAttributes[AWSSemanticConventions.AttributeServiceName]); + Assert.Equal("Test environment name", resourceAttributes[AWSSemanticConventions.AttributeServiceNamespace]); + Assert.Equal("Test ID", resourceAttributes[AWSSemanticConventions.AttributeServiceInstanceID]); + Assert.Equal("Test version label", resourceAttributes[AWSSemanticConventions.AttributeServiceVersion]); + } - [Fact] - public void TestGetEBSMetadata() - { - var ebsResourceDetector = new AWSEBSResourceDetector(); - var ebsMetadata = ebsResourceDetector.GetEBSMetadata(AWSEBSMetadataFilePath); + [Fact] + public void TestGetEBSMetadata() + { + var ebsResourceDetector = new AWSEBSResourceDetector(); + var ebsMetadata = ebsResourceDetector.GetEBSMetadata(AWSEBSMetadataFilePath); - Assert.Equal("1234567890", ebsMetadata.DeploymentId); - Assert.Equal("Test AWS Elastic Beanstalk Environment Name", ebsMetadata.EnvironmentName); - Assert.Equal("Test Version", ebsMetadata.VersionLabel); - } + Assert.Equal("1234567890", ebsMetadata.DeploymentId); + Assert.Equal("Test AWS Elastic Beanstalk Environment Name", ebsMetadata.EnvironmentName); + Assert.Equal("Test Version", ebsMetadata.VersionLabel); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs index dd717189e5..424ee1bb32 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs @@ -19,51 +19,50 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +public class TestAWSEC2ResourceDetector { - public class TestAWSEC2ResourceDetector + [Fact] + public void TestDetect() { - [Fact] - public void TestDetect() - { - IEnumerable> resourceAttributes; - var ec2ResourceDetector = new AWSEC2ResourceDetector(); - resourceAttributes = ec2ResourceDetector.Detect(); - Assert.Null(resourceAttributes); // will be null as it's not in ec2 environment - } + IEnumerable> resourceAttributes; + var ec2ResourceDetector = new AWSEC2ResourceDetector(); + resourceAttributes = ec2ResourceDetector.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in ec2 environment + } - [Fact] - public void TestExtractResourceAttributes() - { - var ec2ResourceDetector = new AWSEC2ResourceDetector(); - var sampleEC2IdentityDocumentModel = new SampleAWSEC2IdentityDocumentModel(); - var hostName = "Test host name"; - var resourceAttributes = ec2ResourceDetector.ExtractResourceAttributes(sampleEC2IdentityDocumentModel, hostName).ToDictionary(x => x.Key, x => x.Value); + [Fact] + public void TestExtractResourceAttributes() + { + var ec2ResourceDetector = new AWSEC2ResourceDetector(); + var sampleEC2IdentityDocumentModel = new SampleAWSEC2IdentityDocumentModel(); + var hostName = "Test host name"; + var resourceAttributes = ec2ResourceDetector.ExtractResourceAttributes(sampleEC2IdentityDocumentModel, hostName).ToDictionary(x => x.Key, x => x.Value); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_ec2", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("Test account id", resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID]); - Assert.Equal("Test availability zone", resourceAttributes[AWSSemanticConventions.AttributeCloudAvailableZone]); - Assert.Equal("Test instance id", resourceAttributes[AWSSemanticConventions.AttributeHostID]); - Assert.Equal("Test instance type", resourceAttributes[AWSSemanticConventions.AttributeHostType]); - Assert.Equal("Test aws region", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); - Assert.Equal("Test host name", resourceAttributes[AWSSemanticConventions.AttributeHostName]); - } + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_ec2", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test account id", resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID]); + Assert.Equal("Test availability zone", resourceAttributes[AWSSemanticConventions.AttributeCloudAvailableZone]); + Assert.Equal("Test instance id", resourceAttributes[AWSSemanticConventions.AttributeHostID]); + Assert.Equal("Test instance type", resourceAttributes[AWSSemanticConventions.AttributeHostType]); + Assert.Equal("Test aws region", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); + Assert.Equal("Test host name", resourceAttributes[AWSSemanticConventions.AttributeHostName]); + } - [Fact] - public void TestDeserializeResponse() - { - var ec2IdentityDocument = "{\"accountId\": \"123456789012\", \"architecture\": \"x86_64\", \"availabilityZone\": \"us-east-1a\", \"billingProducts\": null, \"devpayProductCodes\": null, \"marketplaceProductCodes\": null, \"imageId\": \"ami-12345678901234567\", \"instanceId\": \"i-12345678901234567\", \"instanceType\": \"t2.micro\", \"kernelId\": null, \"pendingTime\": \"2021-08-11T22:41:54Z\", \"privateIp\": \"123.456.789.123\", \"ramdiskId\": null, \"region\": \"us-east-1\", \"version\": \"2021-08-11\"}"; + [Fact] + public void TestDeserializeResponse() + { + var ec2IdentityDocument = "{\"accountId\": \"123456789012\", \"architecture\": \"x86_64\", \"availabilityZone\": \"us-east-1a\", \"billingProducts\": null, \"devpayProductCodes\": null, \"marketplaceProductCodes\": null, \"imageId\": \"ami-12345678901234567\", \"instanceId\": \"i-12345678901234567\", \"instanceType\": \"t2.micro\", \"kernelId\": null, \"pendingTime\": \"2021-08-11T22:41:54Z\", \"privateIp\": \"123.456.789.123\", \"ramdiskId\": null, \"region\": \"us-east-1\", \"version\": \"2021-08-11\"}"; - var ec2ResourceDetector = new AWSEC2ResourceDetector(); + var ec2ResourceDetector = new AWSEC2ResourceDetector(); - var ec2IdentityDocumentModel = ec2ResourceDetector.DeserializeResponse(ec2IdentityDocument); + var ec2IdentityDocumentModel = ec2ResourceDetector.DeserializeResponse(ec2IdentityDocument); - Assert.Equal("123456789012", ec2IdentityDocumentModel.AccountId); - Assert.Equal("us-east-1a", ec2IdentityDocumentModel.AvailabilityZone); - Assert.Equal("i-12345678901234567", ec2IdentityDocumentModel.InstanceId); - Assert.Equal("t2.micro", ec2IdentityDocumentModel.InstanceType); - Assert.Equal("us-east-1", ec2IdentityDocumentModel.Region); - } + Assert.Equal("123456789012", ec2IdentityDocumentModel.AccountId); + Assert.Equal("us-east-1a", ec2IdentityDocumentModel.AvailabilityZone); + Assert.Equal("i-12345678901234567", ec2IdentityDocumentModel.InstanceId); + Assert.Equal("t2.micro", ec2IdentityDocumentModel.InstanceType); + Assert.Equal("us-east-1", ec2IdentityDocumentModel.Region); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs index 4c0c5e8369..3f6739960f 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs @@ -20,64 +20,63 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +public class TestAWSECSResourceDetector { - public class TestAWSECSResourceDetector - { - private const string AWSECSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; - private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; - private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; + private const string AWSECSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; + private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; + private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; - [Fact] - public void TestDetect() - { - IEnumerable> resourceAttributes; - var ecsResourceDetector = new AWSECSResourceDetector(); - resourceAttributes = ecsResourceDetector.Detect(); - Assert.Null(resourceAttributes); // will be null as it's not in ecs environment - } + [Fact] + public void TestDetect() + { + IEnumerable> resourceAttributes; + var ecsResourceDetector = new AWSECSResourceDetector(); + resourceAttributes = ecsResourceDetector.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in ecs environment + } - [Fact] - public void TestExtractResourceAttributes() - { - var ecsResourceDetector = new AWSECSResourceDetector(); - var containerId = "Test container id"; + [Fact] + public void TestExtractResourceAttributes() + { + var ecsResourceDetector = new AWSECSResourceDetector(); + var containerId = "Test container id"; - var resourceAttributes = ecsResourceDetector.ExtractResourceAttributes(containerId).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = ecsResourceDetector.ExtractResourceAttributes(containerId).ToDictionary(x => x.Key, x => x.Value); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_ecs", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); - } + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_ecs", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); + } - [Fact] - public void TestGetECSContainerId() - { - var ecsResourceDetector = new AWSECSResourceDetector(); - var ecsContainerId = ecsResourceDetector.GetECSContainerId(AWSECSMetadataFilePath); + [Fact] + public void TestGetECSContainerId() + { + var ecsResourceDetector = new AWSECSResourceDetector(); + var ecsContainerId = ecsResourceDetector.GetECSContainerId(AWSECSMetadataFilePath); - Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", ecsContainerId); - } + Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", ecsContainerId); + } - [Fact] - public void TestIsECSProcess() - { - Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, "TestECSURIKey"); - Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, "TestECSURIV4Key"); + [Fact] + public void TestIsECSProcess() + { + Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, "TestECSURIKey"); + Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, "TestECSURIV4Key"); - var ecsResourceDetector = new AWSECSResourceDetector(); - var isEcsProcess = ecsResourceDetector.IsECSProcess(); + var ecsResourceDetector = new AWSECSResourceDetector(); + var isEcsProcess = ecsResourceDetector.IsECSProcess(); - Assert.True(isEcsProcess); - } + Assert.True(isEcsProcess); + } - [Fact] - public void TestIsNotECSProcess() - { - var ecsResourceDetector = new AWSECSResourceDetector(); - var isEcsProcess = ecsResourceDetector.IsECSProcess(); + [Fact] + public void TestIsNotECSProcess() + { + var ecsResourceDetector = new AWSECSResourceDetector(); + var isEcsProcess = ecsResourceDetector.IsECSProcess(); - Assert.False(isEcsProcess); - } + Assert.False(isEcsProcess); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index 4da54abc8f..99c6b14717 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -19,95 +19,94 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +public class TestAWSEKSResourceDetector { - public class TestAWSEKSResourceDetector + private const string AWSEKSCredentialsPath = "Resources/SampleMetadataFiles/testekstoken"; + private const string AWSEKSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; + + [Fact] + public void TestDetect() + { + IEnumerable> resourceAttributes; + var eksResourceDetector = new AWSEKSResourceDetector(); + resourceAttributes = eksResourceDetector.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in eks environment + } + + [Fact] + public void TestExtractResourceAttributes() + { + var eksResourceDetector = new AWSEKSResourceDetector(); + var clusterName = "Test cluster name"; + var containerId = "Test container id"; + + var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, containerId).ToDictionary(x => x.Key, x => x.Value); + + Assert.Equal(4, resourceAttributes.Count); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test cluster name", resourceAttributes[AWSSemanticConventions.AttributeK8SClusterName]); + Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); + } + + [Fact] + public void TestExtractResourceAttributesWithEmptyClusterName() + { + var eksResourceDetector = new AWSEKSResourceDetector(); + var containerId = "Test container id"; + + var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(string.Empty, containerId).ToDictionary(x => x.Key, x => x.Value); + + // Validate the count of resourceAttributes -> Excluding cluster name, there will be only three resourceAttributes + Assert.Equal(3, resourceAttributes.Count); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); + } + + [Fact] + public void TestExtractResourceAttributesWithEmptyContainerId() { - private const string AWSEKSCredentialsPath = "Resources/SampleMetadataFiles/testekstoken"; - private const string AWSEKSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; - - [Fact] - public void TestDetect() - { - IEnumerable> resourceAttributes; - var eksResourceDetector = new AWSEKSResourceDetector(); - resourceAttributes = eksResourceDetector.Detect(); - Assert.Null(resourceAttributes); // will be null as it's not in eks environment - } - - [Fact] - public void TestExtractResourceAttributes() - { - var eksResourceDetector = new AWSEKSResourceDetector(); - var clusterName = "Test cluster name"; - var containerId = "Test container id"; - - var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, containerId).ToDictionary(x => x.Key, x => x.Value); - - Assert.Equal(4, resourceAttributes.Count); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("Test cluster name", resourceAttributes[AWSSemanticConventions.AttributeK8SClusterName]); - Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); - } - - [Fact] - public void TestExtractResourceAttributesWithEmptyClusterName() - { - var eksResourceDetector = new AWSEKSResourceDetector(); - var containerId = "Test container id"; - - var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(string.Empty, containerId).ToDictionary(x => x.Key, x => x.Value); - - // Validate the count of resourceAttributes -> Excluding cluster name, there will be only three resourceAttributes - Assert.Equal(3, resourceAttributes.Count); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); - } - - [Fact] - public void TestExtractResourceAttributesWithEmptyContainerId() - { - var eksResourceDetector = new AWSEKSResourceDetector(); - var clusterName = "Test cluster name"; - - var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, string.Empty).ToDictionary(x => x.Key, x => x.Value); - - // Validate the count of resourceAttributes -> Excluding container id, there will be only three resourceAttributes - Assert.Equal(3, resourceAttributes.Count); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("Test cluster name", resourceAttributes[AWSSemanticConventions.AttributeK8SClusterName]); - } - - [Fact] - public void TestGetEKSCredentials() - { - var eksResourceDetector = new AWSEKSResourceDetector(); - var eksCredentials = eksResourceDetector.GetEKSCredentials(AWSEKSCredentialsPath); - - Assert.Equal("Bearer Test AWS EKS Token", eksCredentials); - } - - [Fact] - public void TestGetEKSContainerId() - { - var eksResourceDetector = new AWSEKSResourceDetector(); - var eksContainerId = eksResourceDetector.GetEKSContainerId(AWSEKSMetadataFilePath); - - Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", eksContainerId); - } - - [Fact] - public void TestDeserializeResponse() - { - var awsEKSClusterInformation = "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": {\"name\": \"cluster-info\", \"namespace\": \"amazon-cloudwatch\", \"selfLink\": \"/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info\", \"uid\": \"0734438c-48f4-45c3-b06d-b6f16f7f0e1e\", \"resourceVersion\": \"25911\", \"creationTimestamp\": \"2021-07-23T18:41:56Z\", \"annotations\": {\"kubectl.kubernetes.io/last-applied-configuration\": \"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"cluster.name\\\":\\\"Test\\\",\\\"logs.region\\\":\\\"us-west-2\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"cluster-info\\\",\\\"namespace\\\":\\\"amazon-cloudwatch\\\"}}\\n\"}}, \"data\": {\"cluster.name\": \"Test\", \"logs.region\": \"us-west-2\"}}"; - - var eksResourceDetector = new AWSEKSResourceDetector(); - var eksClusterInformation = eksResourceDetector.DeserializeResponse(awsEKSClusterInformation); - - Assert.Equal("Test", eksClusterInformation.Data.ClusterName); - } + var eksResourceDetector = new AWSEKSResourceDetector(); + var clusterName = "Test cluster name"; + + var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, string.Empty).ToDictionary(x => x.Key, x => x.Value); + + // Validate the count of resourceAttributes -> Excluding container id, there will be only three resourceAttributes + Assert.Equal(3, resourceAttributes.Count); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_eks", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("Test cluster name", resourceAttributes[AWSSemanticConventions.AttributeK8SClusterName]); + } + + [Fact] + public void TestGetEKSCredentials() + { + var eksResourceDetector = new AWSEKSResourceDetector(); + var eksCredentials = eksResourceDetector.GetEKSCredentials(AWSEKSCredentialsPath); + + Assert.Equal("Bearer Test AWS EKS Token", eksCredentials); + } + + [Fact] + public void TestGetEKSContainerId() + { + var eksResourceDetector = new AWSEKSResourceDetector(); + var eksContainerId = eksResourceDetector.GetEKSContainerId(AWSEKSMetadataFilePath); + + Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", eksContainerId); + } + + [Fact] + public void TestDeserializeResponse() + { + var awsEKSClusterInformation = "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": {\"name\": \"cluster-info\", \"namespace\": \"amazon-cloudwatch\", \"selfLink\": \"/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info\", \"uid\": \"0734438c-48f4-45c3-b06d-b6f16f7f0e1e\", \"resourceVersion\": \"25911\", \"creationTimestamp\": \"2021-07-23T18:41:56Z\", \"annotations\": {\"kubectl.kubernetes.io/last-applied-configuration\": \"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"cluster.name\\\":\\\"Test\\\",\\\"logs.region\\\":\\\"us-west-2\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"cluster-info\\\",\\\"namespace\\\":\\\"amazon-cloudwatch\\\"}}\\n\"}}, \"data\": {\"cluster.name\": \"Test\", \"logs.region\": \"us-west-2\"}}"; + + var eksResourceDetector = new AWSEKSResourceDetector(); + var eksClusterInformation = eksResourceDetector.DeserializeResponse(awsEKSClusterInformation); + + Assert.Equal("Test", eksClusterInformation.Data.ClusterName); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs index b69a81f817..78a8c3fdd6 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs @@ -19,29 +19,28 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +public class TestAWSLambdaResourceDetector { - public class TestAWSLambdaResourceDetector + [Fact] + public void TestDetect() { - [Fact] - public void TestDetect() - { - Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); + Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); - var lambdaResourceDetector = new AWSLambdaResourceDetector(); - var resourceAttributes = lambdaResourceDetector.Detect().ToDictionary(x => x.Key, x => x.Value); + var lambdaResourceDetector = new AWSLambdaResourceDetector(); + var resourceAttributes = lambdaResourceDetector.Detect().ToDictionary(x => x.Key, x => x.Value); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("us-east-1", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); - Assert.Equal("testfunction", resourceAttributes[AWSSemanticConventions.AttributeFaasName]); - Assert.Equal("latest", resourceAttributes[AWSSemanticConventions.AttributeFaasVersion]); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("us-east-1", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); + Assert.Equal("testfunction", resourceAttributes[AWSSemanticConventions.AttributeFaasName]); + Assert.Equal("latest", resourceAttributes[AWSSemanticConventions.AttributeFaasVersion]); - Environment.SetEnvironmentVariable("AWS_REGION", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", null); - } + Environment.SetEnvironmentVariable("AWS_REGION", null); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", null); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", null); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs index 9107f2dec2..7ce8115975 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs @@ -21,35 +21,34 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; + +public class TestResourceBuilderExtensions { - public class TestResourceBuilderExtensions + [Fact] + public void TestAddDetector() { - [Fact] - public void TestAddDetector() - { - Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); + Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder - .CreateDefault() - .AddDetector(new AWSLambdaResourceDetector())) // use lambda resource detector here as it doesn't require sending identical http request to aws endpoint - .Build(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder + .CreateDefault() + .AddDetector(new AWSLambdaResourceDetector())) // use lambda resource detector here as it doesn't require sending identical http request to aws endpoint + .Build(); - var resource = tracerProvider.GetResource(); - var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); + var resource = tracerProvider.GetResource(); + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("us-east-1", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); - Assert.Equal("testfunction", resourceAttributes[AWSSemanticConventions.AttributeFaasName]); - Assert.Equal("latest", resourceAttributes[AWSSemanticConventions.AttributeFaasVersion]); + Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); + Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("us-east-1", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); + Assert.Equal("testfunction", resourceAttributes[AWSSemanticConventions.AttributeFaasName]); + Assert.Equal("latest", resourceAttributes[AWSSemanticConventions.AttributeFaasVersion]); - Environment.SetEnvironmentVariable("AWS_REGION", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", null); - } + Environment.SetEnvironmentVariable("AWS_REGION", null); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", null); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", null); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs index 01098c2be0..d781ce40d6 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs @@ -19,99 +19,98 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests; + +public class TestAWSXRayIdGenerator { - public class TestAWSXRayIdGenerator + [Fact] + public void TestGenerateTraceIdForRootNode() { - [Fact] - public void TestGenerateTraceIdForRootNode() - { - var activity = new Activity("Test"); - var originalTraceId = activity.TraceId; - var originalParentSpanId = activity.ParentSpanId; - var originalTraceFlag = activity.ActivityTraceFlags; + var activity = new Activity("Test"); + var originalTraceId = activity.TraceId; + var originalParentSpanId = activity.ParentSpanId; + var originalTraceFlag = activity.ActivityTraceFlags; - using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) - { - activity.Start(); + using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) + { + activity.Start(); - Assert.NotEqual(originalTraceId, activity.TraceId); - Assert.NotEqual(originalParentSpanId, activity.ParentSpanId); - Assert.Equal("0000000000000000", activity.ParentSpanId.ToHexString()); - Assert.Equal(originalTraceFlag, activity.ActivityTraceFlags); - } + Assert.NotEqual(originalTraceId, activity.TraceId); + Assert.NotEqual(originalParentSpanId, activity.ParentSpanId); + Assert.Equal("0000000000000000", activity.ParentSpanId.ToHexString()); + Assert.Equal(originalTraceFlag, activity.ActivityTraceFlags); } + } - [Fact] - public void TestGenerateTraceIdForNonRootNode() - { - var activity = new Activity("Test"); - var traceId = ActivityTraceId.CreateFromString("12345678901234567890123456789012".AsSpan()); - var parentId = ActivitySpanId.CreateFromString("1234567890123456".AsSpan()); - activity.SetParentId(traceId, parentId, ActivityTraceFlags.Recorded); + [Fact] + public void TestGenerateTraceIdForNonRootNode() + { + var activity = new Activity("Test"); + var traceId = ActivityTraceId.CreateFromString("12345678901234567890123456789012".AsSpan()); + var parentId = ActivitySpanId.CreateFromString("1234567890123456".AsSpan()); + activity.SetParentId(traceId, parentId, ActivityTraceFlags.Recorded); - using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) - { - activity.Start(); + using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) + { + activity.Start(); - Assert.Equal("12345678901234567890123456789012", activity.TraceId.ToHexString()); - Assert.Equal("1234567890123456", activity.ParentSpanId.ToHexString()); - Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); - } + Assert.Equal("12345678901234567890123456789012", activity.TraceId.ToHexString()); + Assert.Equal("1234567890123456", activity.ParentSpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); } + } - [Fact] - public void TestGenerateTraceIdForNonRootNodeNotSampled() - { - var activity = new Activity("Test"); - var traceId = ActivityTraceId.CreateFromString("12345678901234567890123456789012".AsSpan()); - var parentId = ActivitySpanId.CreateFromString("1234567890123456".AsSpan()); - activity.SetParentId(traceId, parentId, ActivityTraceFlags.None); + [Fact] + public void TestGenerateTraceIdForNonRootNodeNotSampled() + { + var activity = new Activity("Test"); + var traceId = ActivityTraceId.CreateFromString("12345678901234567890123456789012".AsSpan()); + var parentId = ActivitySpanId.CreateFromString("1234567890123456".AsSpan()); + activity.SetParentId(traceId, parentId, ActivityTraceFlags.None); - using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) - { - activity.Start(); + using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) + { + activity.Start(); - Assert.Equal("12345678901234567890123456789012", activity.TraceId.ToHexString()); - Assert.Equal("1234567890123456", activity.ParentSpanId.ToHexString()); - Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); - } + Assert.Equal("12345678901234567890123456789012", activity.TraceId.ToHexString()); + Assert.Equal("1234567890123456", activity.ParentSpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); } + } - [Fact] - public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSamplerOn() + [Fact] + public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSamplerOn() + { + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceIdWithSampler(new TraceIdRatioBasedSampler(1.0)) + .AddSource("TestTraceIdBasedSamplerOn") + .SetSampler(new TraceIdRatioBasedSampler(1.0)) + .Build()) { - using (Sdk.CreateTracerProviderBuilder() - .AddXRayTraceIdWithSampler(new TraceIdRatioBasedSampler(1.0)) - .AddSource("TestTraceIdBasedSamplerOn") - .SetSampler(new TraceIdRatioBasedSampler(1.0)) - .Build()) + using (var activitySource = new ActivitySource("TestTraceIdBasedSamplerOn")) { - using (var activitySource = new ActivitySource("TestTraceIdBasedSamplerOn")) + using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) { - using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) - { - Assert.True(activity.ActivityTraceFlags == ActivityTraceFlags.Recorded); - } + Assert.True(activity.ActivityTraceFlags == ActivityTraceFlags.Recorded); } } } + } - [Fact] - public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSamplerOff() + [Fact] + public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSamplerOff() + { + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceIdWithSampler(new TraceIdRatioBasedSampler(0.0)) + .AddSource("TestTraceIdBasedSamplerOff") + .SetSampler(new TraceIdRatioBasedSampler(0.0)) + .Build()) { - using (Sdk.CreateTracerProviderBuilder() - .AddXRayTraceIdWithSampler(new TraceIdRatioBasedSampler(0.0)) - .AddSource("TestTraceIdBasedSamplerOff") - .SetSampler(new TraceIdRatioBasedSampler(0.0)) - .Build()) + using (var activitySource = new ActivitySource("TestTraceIdBasedSamplerOff")) { - using (var activitySource = new ActivitySource("TestTraceIdBasedSamplerOff")) + using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) { - using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) - { - Assert.True(activity.ActivityTraceFlags == ActivityTraceFlags.None); - } + Assert.True(activity.ActivityTraceFlags == ActivityTraceFlags.None); } } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs index 2d44fb8761..a3d4f8f80e 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs @@ -21,206 +21,205 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests +namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests; + +public class TestAWSXRayPropagator { - public class TestAWSXRayPropagator - { - private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; - private const string TraceId = "5759e988bd862e3fe1be46a994272793"; - private const string ParentId = "53995c3f42cd8ad8"; + private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; + private const string TraceId = "5759e988bd862e3fe1be46a994272793"; + private const string ParentId = "53995c3f42cd8ad8"; - private static readonly string[] Empty = new string[0]; - private static readonly Func, string, IEnumerable> Getter = (headers, name) => + private static readonly string[] Empty = new string[0]; + private static readonly Func, string, IEnumerable> Getter = (headers, name) => + { + if (headers.TryGetValue(name, out var value)) { - if (headers.TryGetValue(name, out var value)) - { - return new[] { value }; - } + return new[] { value }; + } - return Empty; - }; + return Empty; + }; - private static readonly Action, string, string> Setter = (carrier, name, value) => - { - carrier[name] = value; - }; + private static readonly Action, string, string> Setter = (carrier, name, value) => + { + carrier[name] = value; + }; - private readonly AWSXRayPropagator awsXRayPropagator = new AWSXRayPropagator(); + private readonly AWSXRayPropagator awsXRayPropagator = new AWSXRayPropagator(); - [Fact] - public void TestInjectTraceHeader() - { - var carrier = new Dictionary(); - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); - var traceFlags = ActivityTraceFlags.Recorded; - var activityContext = new ActivityContext(traceId, parentId, traceFlags); - this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter); - - Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey)); - Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1", carrier[AWSXRayTraceHeaderKey]); - } + [Fact] + public void TestInjectTraceHeader() + { + var carrier = new Dictionary(); + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.Recorded; + var activityContext = new ActivityContext(traceId, parentId, traceFlags); + this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter); + + Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey)); + Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1", carrier[AWSXRayTraceHeaderKey]); + } - [Fact] - public void TestInjectTraceHeaderNotSampled() - { - var carrier = new Dictionary(); - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); - var traceFlags = ActivityTraceFlags.None; - var activityContext = new ActivityContext(traceId, parentId, traceFlags); - this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter); - - Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey)); - Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0", carrier[AWSXRayTraceHeaderKey]); - } + [Fact] + public void TestInjectTraceHeaderNotSampled() + { + var carrier = new Dictionary(); + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.None; + var activityContext = new ActivityContext(traceId, parentId, traceFlags); + this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter); + + Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey)); + Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0", carrier[AWSXRayTraceHeaderKey]); + } - [Fact] - public void TestExtractTraceHeader() + [Fact] + public void TestExtractTraceHeader() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1" }, - }; - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); - var traceFlags = ActivityTraceFlags.Recorded; - var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); - - Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1" }, + }; + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.Recorded; + var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); - [Fact] - public void TestExtractTraceHeaderNotSampled() + Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); + } + + [Fact] + public void TestExtractTraceHeaderNotSampled() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0" }, - }; - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); - var traceFlags = ActivityTraceFlags.None; - var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); - - Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0" }, + }; + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.None; + var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); + + Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderDifferentOrder() + [Fact] + public void TestExtractTraceHeaderDifferentOrder() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Sampled=1;Parent=53995c3f42cd8ad8;Root=1-5759e988-bd862e3fe1be46a994272793" }, - }; - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); - var traceFlags = ActivityTraceFlags.Recorded; - var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); - - Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + { AWSXRayTraceHeaderKey, "Sampled=1;Parent=53995c3f42cd8ad8;Root=1-5759e988-bd862e3fe1be46a994272793" }, + }; + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.Recorded; + var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); + + Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithEmptyValue() + [Fact] + public void TestExtractTraceHeaderWithEmptyValue() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, string.Empty }, - }; + { AWSXRayTraceHeaderKey, string.Empty }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithoutParentId() + [Fact] + public void TestExtractTraceHeaderWithoutParentId() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Sampled=1" }, - }; + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Sampled=1" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithoutSampleDecision() + [Fact] + public void TestExtractTraceHeaderWithoutSampleDecision() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8" }, - }; + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithInvalidTraceId() + [Fact] + public void TestExtractTraceHeaderWithInvalidTraceId() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=15759e988bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1" }, - }; + { AWSXRayTraceHeaderKey, "Root=15759e988bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithInvalidParentId() + [Fact] + public void TestExtractTraceHeaderWithInvalidParentId() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=123;Sampled=1" }, - }; + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=123;Sampled=1" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithInvalidSampleDecision() + [Fact] + public void TestExtractTraceHeaderWithInvalidSampleDecision() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=" }, - }; + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithInvalidSampleDecisionValue() + [Fact] + public void TestExtractTraceHeaderWithInvalidSampleDecisionValue() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=3" }, - }; + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=3" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithInvalidSampleDecisionLength() + [Fact] + public void TestExtractTraceHeaderWithInvalidSampleDecisionLength() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=123" }, - }; + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=123" }, + }; - Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + Assert.Equal(default, this.awsXRayPropagator.Extract(default, carrier, Getter)); + } - [Fact] - public void TestExtractTraceHeaderWithAdditionalField() + [Fact] + public void TestExtractTraceHeaderWithAdditionalField() + { + var carrier = new Dictionary() { - var carrier = new Dictionary() - { - { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1;Foo=Bar" }, - }; - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); - var traceFlags = ActivityTraceFlags.Recorded; - var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); - - Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); - } + { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1;Foo=Bar" }, + }; + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.Recorded; + var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); + + Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter)); } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index b17a0567aa..014d1fdae1 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -28,167 +28,166 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +public class TestAWSClientInstrumentation { - public class TestAWSClientInstrumentation + [Fact] + public void TestDDBScanSuccessful() { - [Fact] - public void TestDDBScanSuccessful() - { - var processor = new Mock>(); + var processor = new Mock>(); - var parent = new Activity("parent").Start(); + var parent = new Activity("parent").Start(); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddXRayTraceId() - .AddAWSInstrumentation() - .AddProcessor(processor.Object) - .Build()) - { - var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; - CustomResponses.SetResponse(ddb, null, requestId, true); - var scan_request = new ScanRequest(); + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddXRayTraceId() + .AddAWSInstrumentation() + .AddProcessor(processor.Object) + .Build()) + { + var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + CustomResponses.SetResponse(ddb, null, requestId, true); + var scan_request = new ScanRequest(); - scan_request.TableName = "SampleProduct"; - scan_request.AttributesToGet = new List() { "Id", "Name" }; + scan_request.TableName = "SampleProduct"; + scan_request.AttributesToGet = new List() { "Id", "Name" }; #if NET452 - ddb.Scan(scan_request); + ddb.Scan(scan_request); #else - ddb.ScanAsync(scan_request).Wait(); + ddb.ScanAsync(scan_request).Wait(); #endif - var count = processor.Invocations.Count; + var count = processor.Invocations.Count; - Assert.Equal(3, count); + Assert.Equal(3, count); - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateDynamoActivityTags(awssdk_activity); + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateDynamoActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - } + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); } + } - [Fact] + [Fact] #if NET452 - public void TestDDBScanUnsuccessful() + public void TestDDBScanUnsuccessful() #else - public async Task TestDDBScanUnsuccessful() + public async Task TestDDBScanUnsuccessful() #endif - { - var processor = new Mock>(); + { + var processor = new Mock>(); - var parent = new Activity("parent").Start(); + var parent = new Activity("parent").Start(); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddXRayTraceId() - .AddAWSInstrumentation() - .AddProcessor(processor.Object) - .Build()) + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddXRayTraceId() + .AddAWSInstrumentation() + .AddProcessor(processor.Object) + .Build()) + { + var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + AmazonServiceException amazonServiceException = new AmazonServiceException(); + amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; + amazonServiceException.RequestId = requestId; + CustomResponses.SetResponse(ddb, (request) => { throw amazonServiceException; }); + var scan_request = new ScanRequest(); + + scan_request.TableName = "SampleProduct"; + scan_request.AttributesToGet = new List() { "Id", "Name" }; + + try { - var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; - AmazonServiceException amazonServiceException = new AmazonServiceException(); - amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; - amazonServiceException.RequestId = requestId; - CustomResponses.SetResponse(ddb, (request) => { throw amazonServiceException; }); - var scan_request = new ScanRequest(); - - scan_request.TableName = "SampleProduct"; - scan_request.AttributesToGet = new List() { "Id", "Name" }; - - try - { #if NET452 - ddb.Scan(scan_request); + ddb.Scan(scan_request); #else - await ddb.ScanAsync(scan_request); + await ddb.ScanAsync(scan_request); #endif - } - catch (AmazonServiceException) - { - var count = processor.Invocations.Count; - Assert.Equal(3, count); + } + catch (AmazonServiceException) + { + var count = processor.Invocations.Count; + Assert.Equal(3, count); - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateDynamoActivityTags(awssdk_activity); + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateDynamoActivityTags(awssdk_activity); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - Assert.Equal(Status.Error.WithDescription("Exception of type 'Amazon.Runtime.AmazonServiceException' was thrown."), awssdk_activity.GetStatus()); - Assert.Equal("exception", awssdk_activity.Events.First().Name); - } + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); + Assert.Equal(Status.Error.WithDescription("Exception of type 'Amazon.Runtime.AmazonServiceException' was thrown."), awssdk_activity.GetStatus()); + Assert.Equal("exception", awssdk_activity.Events.First().Name); } } + } - [Fact] - public void TestSQSSendMessageSuccessful() - { - var processor = new Mock>(); + [Fact] + public void TestSQSSendMessageSuccessful() + { + var processor = new Mock>(); - var parent = new Activity("parent").Start(); + var parent = new Activity("parent").Start(); - using (Sdk.CreateTracerProviderBuilder() - .AddXRayTraceId() - .SetSampler(new AlwaysOnSampler()) - .AddAWSInstrumentation() - .AddProcessor(processor.Object) - .Build()) - { - var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; - string dummyResponse = "\n" + - "SomeDummyResponse"; - CustomResponses.SetResponse(sqs, dummyResponse, requestId, true); - var send_msg_req = new SendMessageRequest(); - send_msg_req.QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue"; - send_msg_req.MessageBody = "Hello from OT"; + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddProcessor(processor.Object) + .Build()) + { + var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + string dummyResponse = "\n" + + "SomeDummyResponse"; + CustomResponses.SetResponse(sqs, dummyResponse, requestId, true); + var send_msg_req = new SendMessageRequest(); + send_msg_req.QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue"; + send_msg_req.MessageBody = "Hello from OT"; #if NET452 - sqs.SendMessage(send_msg_req); + sqs.SendMessage(send_msg_req); #else - sqs.SendMessageAsync(send_msg_req).Wait(); + sqs.SendMessageAsync(send_msg_req).Wait(); #endif - var count = processor.Invocations.Count; - Assert.Equal(3, count); - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + var count = processor.Invocations.Count; + Assert.Equal(3, count); + Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateSqsActivityTags(awssdk_activity); + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateSqsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - } + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); } + } - private void ValidateAWSActivity(Activity aws_activity, Activity parent) - { - Assert.Equal(parent.SpanId, aws_activity.ParentSpanId); - Assert.Equal(ActivityKind.Client, aws_activity.Kind); - } + private void ValidateAWSActivity(Activity aws_activity, Activity parent) + { + Assert.Equal(parent.SpanId, aws_activity.ParentSpanId); + Assert.Equal(ActivityKind.Client, aws_activity.Kind); + } - private void ValidateDynamoActivityTags(Activity ddb_activity) - { - Assert.Equal("DynamoDBv2.Scan", ddb_activity.DisplayName); - Assert.Equal("DynamoDBv2", Utils.GetTagValue(ddb_activity, "aws.service")); - Assert.Equal("Scan", Utils.GetTagValue(ddb_activity, "aws.operation")); - Assert.Equal("us-east-1", Utils.GetTagValue(ddb_activity, "aws.region")); - Assert.Equal("SampleProduct", Utils.GetTagValue(ddb_activity, "aws.table_name")); - Assert.Equal("dynamodb", Utils.GetTagValue(ddb_activity, "db.system")); - } + private void ValidateDynamoActivityTags(Activity ddb_activity) + { + Assert.Equal("DynamoDBv2.Scan", ddb_activity.DisplayName); + Assert.Equal("DynamoDBv2", Utils.GetTagValue(ddb_activity, "aws.service")); + Assert.Equal("Scan", Utils.GetTagValue(ddb_activity, "aws.operation")); + Assert.Equal("us-east-1", Utils.GetTagValue(ddb_activity, "aws.region")); + Assert.Equal("SampleProduct", Utils.GetTagValue(ddb_activity, "aws.table_name")); + Assert.Equal("dynamodb", Utils.GetTagValue(ddb_activity, "db.system")); + } - private void ValidateSqsActivityTags(Activity sqs_activity) - { - Assert.Equal("SQS.SendMessage", sqs_activity.DisplayName); - Assert.Equal("SQS", Utils.GetTagValue(sqs_activity, "aws.service")); - Assert.Equal("SendMessage", Utils.GetTagValue(sqs_activity, "aws.operation")); - Assert.Equal("us-east-1", Utils.GetTagValue(sqs_activity, "aws.region")); - Assert.Equal("https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue", Utils.GetTagValue(sqs_activity, "aws.queue_url")); - } + private void ValidateSqsActivityTags(Activity sqs_activity) + { + Assert.Equal("SQS.SendMessage", sqs_activity.DisplayName); + Assert.Equal("SQS", Utils.GetTagValue(sqs_activity, "aws.service")); + Assert.Equal("SendMessage", Utils.GetTagValue(sqs_activity, "aws.operation")); + Assert.Equal("us-east-1", Utils.GetTagValue(sqs_activity, "aws.region")); + Assert.Equal("https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue", Utils.GetTagValue(sqs_activity, "aws.queue_url")); } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index 2e520372c6..31c9f6837d 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -16,109 +16,114 @@ using System; using System.Collections.Generic; +#if NET452 using System.IO; +#endif using System.Net; +#if !NET452 using System.Net.Http; +#endif using Amazon.Runtime; using Amazon.Runtime.Internal; +#if NET452 using Amazon.Runtime.Internal.Transform; +#endif using Amazon.Util; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +internal static class CustomResponses { - internal static class CustomResponses - { #if NET452 - public static void SetResponse( - AmazonServiceClient client, string content, string requestId, bool isOK) - { - var response = Create(content, requestId, isOK); - SetResponse(client, response); - } + public static void SetResponse( + AmazonServiceClient client, string content, string requestId, bool isOK) + { + var response = Create(content, requestId, isOK); + SetResponse(client, response); + } - public static void SetResponse( - AmazonServiceClient client, - Func responseCreator) - { - var pipeline = client - .GetType() - .GetProperty("RuntimePipeline", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) - .GetValue(client, null) - as RuntimePipeline; + public static void SetResponse( + AmazonServiceClient client, + Func responseCreator) + { + var pipeline = client + .GetType() + .GetProperty("RuntimePipeline", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) + .GetValue(client, null) + as RuntimePipeline; + + var requestFactory = new MockHttpRequestFactory(); + requestFactory.ResponseCreator = responseCreator; + var httpHandler = new HttpHandler(requestFactory, client); + pipeline.ReplaceHandler>(httpHandler); + } - var requestFactory = new MockHttpRequestFactory(); - requestFactory.ResponseCreator = responseCreator; - var httpHandler = new HttpHandler(requestFactory, client); - pipeline.ReplaceHandler>(httpHandler); - } + private static Func Create( + string content, string requestId, bool isOK) + { + var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; - private static Func Create( - string content, string requestId, bool isOK) + return (request) => { - var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; + Dictionary headers = new Dictionary(StringComparer.Ordinal); + if (!string.IsNullOrEmpty(requestId)) + { + headers.Add(HeaderKeys.RequestIdHeader, requestId); + } + + var response = MockWebResponse.Create(status, headers, content); - return (request) => + if (isOK) { - Dictionary headers = new Dictionary(StringComparer.Ordinal); - if (!string.IsNullOrEmpty(requestId)) - { - headers.Add(HeaderKeys.RequestIdHeader, requestId); - } - - var response = MockWebResponse.Create(status, headers, content); - - if (isOK) - { - return response; - } - - throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); - }; - } + return response; + } + + throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); + }; + } #else - public static void SetResponse(AmazonServiceClient client, string content, string requestId, bool isOK) - { - var response = Create(content, requestId, isOK); - SetResponse(client, response); - } + public static void SetResponse(AmazonServiceClient client, string content, string requestId, bool isOK) + { + var response = Create(content, requestId, isOK); + SetResponse(client, response); + } - public static void SetResponse(AmazonServiceClient client, Func responseCreator) - { - var pipeline = client + public static void SetResponse(AmazonServiceClient client, Func responseCreator) + { + var pipeline = client .GetType() .GetProperty("RuntimePipeline", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) .GetValue(client, null) - as RuntimePipeline; + as RuntimePipeline; - var requestFactory = new MockHttpRequestFactory(); - requestFactory.ResponseCreator = responseCreator; - var httpHandler = new HttpHandler(requestFactory, client); - pipeline.ReplaceHandler>(httpHandler); - } + var requestFactory = new MockHttpRequestFactory(); + requestFactory.ResponseCreator = responseCreator; + var httpHandler = new HttpHandler(requestFactory, client); + pipeline.ReplaceHandler>(httpHandler); + } + + private static Func Create( + string content, string requestId, bool isOK) + { + var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; - private static Func Create( - string content, string requestId, bool isOK) + return (request) => { - var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; + Dictionary headers = new Dictionary(StringComparer.Ordinal); + if (!string.IsNullOrEmpty(requestId)) + { + headers.Add(HeaderKeys.RequestIdHeader, requestId); + } - return (request) => + var response = MockWebResponse.Create(status, headers, content); + + if (isOK) { - Dictionary headers = new Dictionary(StringComparer.Ordinal); - if (!string.IsNullOrEmpty(requestId)) - { - headers.Add(HeaderKeys.RequestIdHeader, requestId); - } - - var response = MockWebResponse.Create(status, headers, content); - - if (isOK) - { - return response; - } - - throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); - }; - } -#endif + return response; + } + + throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); + }; } +#endif } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index d4349ade90..9a19394d84 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -22,107 +22,106 @@ using System.Net.Http.Headers; using Amazon.Runtime.Internal.Transform; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +internal class CustomWebResponse : IWebResponseData { - internal class CustomWebResponse : IWebResponseData + private HttpResponseMessageBody response; + private string[] headerNames; + private Dictionary headers; + private HashSet headerNamesSet; + + public CustomWebResponse(HttpResponseMessage response) + : this(response, null, false) { - private HttpResponseMessageBody response; - private string[] headerNames; - private Dictionary headers; - private HashSet headerNamesSet; + } - public CustomWebResponse(HttpResponseMessage response) - : this(response, null, false) - { - } + public CustomWebResponse(HttpResponseMessage responseMsg, HttpClient httpClient, bool disposeClient) + { + this.response = new HttpResponseMessageBody(responseMsg, httpClient, disposeClient); - public CustomWebResponse(HttpResponseMessage responseMsg, HttpClient httpClient, bool disposeClient) - { - this.response = new HttpResponseMessageBody(responseMsg, httpClient, disposeClient); + this.StatusCode = responseMsg.StatusCode; + this.IsSuccessStatusCode = responseMsg.IsSuccessStatusCode; + this.ContentLength = responseMsg.Content.Headers.ContentLength ?? 0; + this.CopyHeaderValues(responseMsg); + } - this.StatusCode = responseMsg.StatusCode; - this.IsSuccessStatusCode = responseMsg.IsSuccessStatusCode; - this.ContentLength = responseMsg.Content.Headers.ContentLength ?? 0; - this.CopyHeaderValues(responseMsg); - } + public HttpStatusCode StatusCode { get; private set; } - public HttpStatusCode StatusCode { get; private set; } + public bool IsSuccessStatusCode { get; private set; } - public bool IsSuccessStatusCode { get; private set; } + public string ContentType { get; private set; } - public string ContentType { get; private set; } + public long ContentLength { get; private set; } - public long ContentLength { get; private set; } + public IHttpResponseBody ResponseBody + { + get { return this.response; } + } - public IHttpResponseBody ResponseBody - { - get { return this.response; } - } + public static IWebResponseData GenerateWebResponse(HttpResponseMessage response) + { + return new CustomWebResponse(response); + } - public static IWebResponseData GenerateWebResponse(HttpResponseMessage response) + public string GetHeaderValue(string headerName) + { + string headerValue; + if (this.headers.TryGetValue(headerName, out headerValue)) { - return new CustomWebResponse(response); + return headerValue; } - public string GetHeaderValue(string headerName) - { - string headerValue; - if (this.headers.TryGetValue(headerName, out headerValue)) - { - return headerValue; - } + return string.Empty; + } - return string.Empty; - } + public bool IsHeaderPresent(string headerName) + { + return this.headerNamesSet.Contains(headerName); + } - public bool IsHeaderPresent(string headerName) - { - return this.headerNamesSet.Contains(headerName); - } + public string[] GetHeaderNames() + { + return this.headerNames; + } + + private void CopyHeaderValues(HttpResponseMessage response) + { + List headerNames = new List(); + this.headers = new Dictionary(10, StringComparer.OrdinalIgnoreCase); - public string[] GetHeaderNames() + foreach (KeyValuePair> kvp in response.Headers) { - return this.headerNames; + headerNames.Add(kvp.Key); + var headerValue = this.GetFirstHeaderValue(response.Headers, kvp.Key); + this.headers.Add(kvp.Key, headerValue); } - private void CopyHeaderValues(HttpResponseMessage response) + if (response.Content != null) { - List headerNames = new List(); - this.headers = new Dictionary(10, StringComparer.OrdinalIgnoreCase); - - foreach (KeyValuePair> kvp in response.Headers) - { - headerNames.Add(kvp.Key); - var headerValue = this.GetFirstHeaderValue(response.Headers, kvp.Key); - this.headers.Add(kvp.Key, headerValue); - } - - if (response.Content != null) + foreach (var kvp in response.Content.Headers) { - foreach (var kvp in response.Content.Headers) + if (!headerNames.Contains(kvp.Key)) { - if (!headerNames.Contains(kvp.Key)) - { - headerNames.Add(kvp.Key); - var headerValue = this.GetFirstHeaderValue(response.Content.Headers, kvp.Key); - this.headers.Add(kvp.Key, headerValue); - } + headerNames.Add(kvp.Key); + var headerValue = this.GetFirstHeaderValue(response.Content.Headers, kvp.Key); + this.headers.Add(kvp.Key, headerValue); } } - - this.headerNames = headerNames.ToArray(); - this.headerNamesSet = new HashSet(this.headerNames, StringComparer.OrdinalIgnoreCase); } - private string GetFirstHeaderValue(HttpHeaders headers, string key) - { - IEnumerable headerValues = null; - if (headers.TryGetValues(key, out headerValues)) - { - return headerValues.FirstOrDefault(); - } + this.headerNames = headerNames.ToArray(); + this.headerNamesSet = new HashSet(this.headerNames, StringComparer.OrdinalIgnoreCase); + } - return string.Empty; + private string GetFirstHeaderValue(HttpHeaders headers, string key) + { + IEnumerable headerValues = null; + if (headers.TryGetValues(key, out headerValues)) + { + return headerValues.FirstOrDefault(); } + + return string.Empty; } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index 9897910117..d5b8ee4857 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -20,76 +20,75 @@ using System.Threading.Tasks; using Amazon.Runtime.Internal.Transform; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +internal class HttpResponseMessageBody : IHttpResponseBody { - internal class HttpResponseMessageBody : IHttpResponseBody + private HttpClient httpClient; + private HttpResponseMessage response; + private bool disposeClient = false; + private bool disposed = false; + + public HttpResponseMessageBody(HttpResponseMessage response, HttpClient httpClient, bool disposeClient) { - private HttpClient httpClient; - private HttpResponseMessage response; - private bool disposeClient = false; - private bool disposed = false; + this.httpClient = httpClient; + this.response = response; + this.disposeClient = disposeClient; + } - public HttpResponseMessageBody(HttpResponseMessage response, HttpClient httpClient, bool disposeClient) + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + Stream IHttpResponseBody.OpenResponse() + { + if (this.disposed) { - this.httpClient = httpClient; - this.response = response; - this.disposeClient = disposeClient; + throw new ObjectDisposedException("HttpWebResponseBody"); } - public void Dispose() + return this.response.Content.ReadAsStreamAsync().Result; + } + + Task IHttpResponseBody.OpenResponseAsync() + { + if (this.disposed) { - this.Dispose(true); - GC.SuppressFinalize(this); + throw new ObjectDisposedException("HttpWebResponseBody"); } - Stream IHttpResponseBody.OpenResponse() + if (this.response.Content != null) { - if (this.disposed) - { - throw new ObjectDisposedException("HttpWebResponseBody"); - } - - return this.response.Content.ReadAsStreamAsync().Result; + return this.response.Content.ReadAsStreamAsync(); } - - Task IHttpResponseBody.OpenResponseAsync() + else { - if (this.disposed) - { - throw new ObjectDisposedException("HttpWebResponseBody"); - } + return null; + } + } - if (this.response.Content != null) - { - return this.response.Content.ReadAsStreamAsync(); - } - else - { - return null; - } + protected virtual void Dispose(bool disposing) + { + if (this.disposed) + { + return; } - protected virtual void Dispose(bool disposing) + if (disposing) { - if (this.disposed) + if (this.response != null) { - return; + this.response.Dispose(); } - if (disposing) + if (this.httpClient != null && this.disposeClient) { - if (this.response != null) - { - this.response.Dispose(); - } - - if (this.httpClient != null && this.disposeClient) - { - this.httpClient.Dispose(); - } - - this.disposed = true; + this.httpClient.Dispose(); } + + this.disposed = true; } } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index 0e7314e618..5aefb6fc6e 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -19,250 +19,250 @@ using System.IO; using System.Linq; using System.Net; +#if !NET452 using System.Net.Http; +#endif using System.Threading; using System.Threading.Tasks; using Amazon.Runtime; using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Transform; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests -{ +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; #if NET452 - internal class MockHttpRequest : IHttpRequest +internal class MockHttpRequest : IHttpRequest +{ + private Stream requestStream = null; + + public MockHttpRequest(Uri requestUri, Action action, Func responseCreator = null) { - private Stream requestStream = null; + this.RequestUri = requestUri; + this.GetResponseAction = action; + this.ResponseCreator = responseCreator ?? this.CreateResponse; + } - public MockHttpRequest(Uri requestUri, Action action, Func responseCreator = null) - { - this.RequestUri = requestUri; - this.GetResponseAction = action; - this.ResponseCreator = responseCreator ?? this.CreateResponse; - } + public bool IsDisposed { get; set; } - public bool IsDisposed { get; set; } + public bool IsAborted { get; set; } - public bool IsAborted { get; set; } + public bool IsConfigureRequestCalled { get; set; } - public bool IsConfigureRequestCalled { get; set; } + public bool IsSetRequestHeadersCalled { get; set; } - public bool IsSetRequestHeadersCalled { get; set; } + public bool IsGetRequestContentCalled { get; set; } - public bool IsGetRequestContentCalled { get; set; } + public string Method { get; set; } - public string Method { get; set; } + public Uri RequestUri { get; set; } - public Uri RequestUri { get; set; } + public Action GetResponseAction { get; set; } - public Action GetResponseAction { get; set; } + public Func ResponseCreator { get; set; } - public Func ResponseCreator { get; set; } + public void ConfigureRequest(IRequestContext requestContext) + { + this.IsConfigureRequestCalled = true; + } - public void ConfigureRequest(IRequestContext requestContext) - { - this.IsConfigureRequestCalled = true; - } + public void SetRequestHeaders(IDictionary headers) + { + this.IsSetRequestHeadersCalled = true; + } - public void SetRequestHeaders(IDictionary headers) - { - this.IsSetRequestHeadersCalled = true; - } + public Stream GetRequestContent() + { + this.IsGetRequestContentCalled = true; + this.requestStream = new MemoryStream(); + return this.requestStream; + } - public Stream GetRequestContent() + public Amazon.Runtime.Internal.Transform.IWebResponseData GetResponse() + { + if (this.GetResponseAction != null) { - this.IsGetRequestContentCalled = true; - this.requestStream = new MemoryStream(); - return this.requestStream; + this.GetResponseAction(); } - public Amazon.Runtime.Internal.Transform.IWebResponseData GetResponse() - { - if (this.GetResponseAction != null) - { - this.GetResponseAction(); - } + var response = this.ResponseCreator(this); + return new HttpWebRequestResponseData(response); + } - var response = this.ResponseCreator(this); - return new HttpWebRequestResponseData(response); - } + public void WriteToRequestBody( + Stream requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) + { + } - public void WriteToRequestBody( - Stream requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) - { - } + public void WriteToRequestBody(Stream requestContent, byte[] content, IDictionary contentHeaders) + { + } - public void WriteToRequestBody(Stream requestContent, byte[] content, IDictionary contentHeaders) - { - } + public void Abort() + { + this.IsAborted = true; + } - public void Abort() - { - this.IsAborted = true; - } + public Task GetRequestContentAsync() + { + return Task.FromResult(new MemoryStream()); + } - public Task GetRequestContentAsync() - { - return Task.FromResult(new MemoryStream()); - } + public Task GetResponseAsync(System.Threading.CancellationToken cancellationToken) + { + this.GetResponseAction?.Invoke(); - public Task GetResponseAsync(System.Threading.CancellationToken cancellationToken) - { - this.GetResponseAction?.Invoke(); + var response = this.ResponseCreator(this); + return Task.FromResult(new HttpWebRequestResponseData(response)); + } - var response = this.ResponseCreator(this); - return Task.FromResult(new HttpWebRequestResponseData(response)); - } + public void Dispose() + { + this.IsDisposed = true; + } - public void Dispose() - { - this.IsDisposed = true; - } + public Stream SetupProgressListeners(Stream originalStream, long progressUpdateInterval, object sender, EventHandler callback) + { + return originalStream; + } - public Stream SetupProgressListeners(Stream originalStream, long progressUpdateInterval, object sender, EventHandler callback) - { - return originalStream; - } + Task IHttpRequest.GetRequestContentAsync(CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } - Task IHttpRequest.GetRequestContentAsync(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } + Task IHttpRequest.WriteToRequestBodyAsync(Stream requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) + { + throw new NotImplementedException(); + } - Task IHttpRequest.WriteToRequestBodyAsync(Stream requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) - { - throw new NotImplementedException(); - } + Task IHttpRequest.WriteToRequestBodyAsync(Stream requestContent, byte[] requestData, IDictionary headers, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + private HttpWebResponse CreateResponse(MockHttpRequest request) + { + var resourceName = request.RequestUri.Host.Split('.').Last(); + var response = MockWebResponse.CreateFromResource(resourceName); - Task IHttpRequest.WriteToRequestBodyAsync(Stream requestContent, byte[] requestData, IDictionary headers, CancellationToken cancellationToken) + if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) { - throw new NotImplementedException(); + return response; } - - private HttpWebResponse CreateResponse(MockHttpRequest request) + else { - var resourceName = request.RequestUri.Host.Split('.').Last(); - var response = MockWebResponse.CreateFromResource(resourceName); - - if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) - { - return response; - } - else - { - throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); - } + throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); } } +} #else - internal class MockHttpRequest : IHttpRequest +internal class MockHttpRequest : IHttpRequest +{ + public MockHttpRequest(Uri requestUri, Action action, Func responseCreator = null) { - public MockHttpRequest(Uri requestUri, Action action, Func responseCreator = null) - { - this.RequestUri = requestUri; - this.GetResponseAction = action; - this.ResponseCreator = responseCreator ?? this.CreateResponse; - } + this.RequestUri = requestUri; + this.GetResponseAction = action; + this.ResponseCreator = responseCreator ?? this.CreateResponse; + } - public bool IsDisposed { get; set; } + public bool IsDisposed { get; set; } - public bool IsAborted { get; set; } + public bool IsAborted { get; set; } - public bool IsConfigureRequestCalled { get; set; } + public bool IsConfigureRequestCalled { get; set; } - public bool IsSetRequestHeadersCalled { get; set; } + public bool IsSetRequestHeadersCalled { get; set; } - public bool IsGetRequestContentCalled { get; set; } + public bool IsGetRequestContentCalled { get; set; } - public string Method { get; set; } + public string Method { get; set; } - public Uri RequestUri { get; set; } + public Uri RequestUri { get; set; } - public Action GetResponseAction { get; set; } + public Action GetResponseAction { get; set; } - public Func ResponseCreator { get; set; } + public Func ResponseCreator { get; set; } - public void Abort() - { - this.IsAborted = true; - } + public void Abort() + { + this.IsAborted = true; + } - public void ConfigureRequest(IRequestContext requestContext) - { - this.IsConfigureRequestCalled = true; - } + public void ConfigureRequest(IRequestContext requestContext) + { + this.IsConfigureRequestCalled = true; + } - public void Dispose() - { - this.IsDisposed = true; - } + public void Dispose() + { + this.IsDisposed = true; + } - public HttpContent GetRequestContent() + public HttpContent GetRequestContent() + { + this.IsGetRequestContentCalled = true; + try { - this.IsGetRequestContentCalled = true; - try - { - return new HttpRequestMessage().Content; - } - catch (AggregateException e) - { - throw e.InnerException; - } + return new HttpRequestMessage().Content; } - - public Task GetRequestContentAsync() + catch (AggregateException e) { - return Task.FromResult(new HttpRequestMessage().Content); + throw e.InnerException; } + } - public IWebResponseData GetResponse() - { - this.GetResponseAction?.Invoke(); + public Task GetRequestContentAsync() + { + return Task.FromResult(new HttpRequestMessage().Content); + } - var response = this.ResponseCreator(this); - return CustomWebResponse.GenerateWebResponse(response); - } + public IWebResponseData GetResponse() + { + this.GetResponseAction?.Invoke(); - public Task GetResponseAsync(CancellationToken cancellationToken) - { - this.GetResponseAction?.Invoke(); - var response = this.ResponseCreator(this); - return Task.FromResult(CustomWebResponse.GenerateWebResponse(response)); - } + var response = this.ResponseCreator(this); + return CustomWebResponse.GenerateWebResponse(response); + } - public void SetRequestHeaders(IDictionary headers) - { - this.IsSetRequestHeadersCalled = true; - } + public Task GetResponseAsync(CancellationToken cancellationToken) + { + this.GetResponseAction?.Invoke(); + var response = this.ResponseCreator(this); + return Task.FromResult(CustomWebResponse.GenerateWebResponse(response)); + } - public Stream SetupProgressListeners(Stream originalStream, long progressUpdateInterval, object sender, EventHandler callback) - { - return originalStream; - } + public void SetRequestHeaders(IDictionary headers) + { + this.IsSetRequestHeadersCalled = true; + } - public void WriteToRequestBody(HttpContent requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) - { - } + public Stream SetupProgressListeners(Stream originalStream, long progressUpdateInterval, object sender, EventHandler callback) + { + return originalStream; + } + + public void WriteToRequestBody(HttpContent requestContent, Stream contentStream, IDictionary contentHeaders, IRequestContext requestContext) + { + } + + public void WriteToRequestBody(HttpContent requestContent, byte[] content, IDictionary contentHeaders) + { + } + + private HttpResponseMessage CreateResponse(MockHttpRequest request) + { + // Extract the last segment of the URI, this is the custom URI + // sent by the unit tests. + var resourceName = request.RequestUri.Host.Split('.').Last(); + var response = MockWebResponse.CreateFromResource(resourceName); - public void WriteToRequestBody(HttpContent requestContent, byte[] content, IDictionary contentHeaders) + if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) { + return response; } - - private HttpResponseMessage CreateResponse(MockHttpRequest request) + else { - // Extract the last segment of the URI, this is the custom URI - // sent by the unit tests. - var resourceName = request.RequestUri.Host.Split('.').Last(); - var response = MockWebResponse.CreateFromResource(resourceName); - - if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) - { - return response; - } - else - { - throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); - } + throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); } } -#endif } +#endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index 79bbeb9bc3..69584cc84f 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -15,50 +15,51 @@ // using System; +#if NET452 using System.IO; using System.Net; +#else using System.Net.Http; +#endif using Amazon.Runtime; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests -{ +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; #if NET452 - internal class MockHttpRequestFactory : IHttpRequestFactory - { - public Action GetResponseAction { get; set; } +internal class MockHttpRequestFactory : IHttpRequestFactory +{ + public Action GetResponseAction { get; set; } - public Func ResponseCreator { get; set; } + public Func ResponseCreator { get; set; } - public MockHttpRequest LastCreatedRequest { get; private set; } + public MockHttpRequest LastCreatedRequest { get; private set; } - public IHttpRequest CreateHttpRequest(Uri requestUri) - { - this.LastCreatedRequest = new MockHttpRequest(requestUri, this.GetResponseAction, this.ResponseCreator); - return this.LastCreatedRequest; - } + public IHttpRequest CreateHttpRequest(Uri requestUri) + { + this.LastCreatedRequest = new MockHttpRequest(requestUri, this.GetResponseAction, this.ResponseCreator); + return this.LastCreatedRequest; + } - public void Dispose() - { - } + public void Dispose() + { } +} #else - internal class MockHttpRequestFactory : IHttpRequestFactory - { - public Action GetResponseAction { get; set; } +internal class MockHttpRequestFactory : IHttpRequestFactory +{ + public Action GetResponseAction { get; set; } - public MockHttpRequest LastCreatedRequest { get; private set; } + public MockHttpRequest LastCreatedRequest { get; private set; } - public Func ResponseCreator { get; set; } + public Func ResponseCreator { get; set; } - public IHttpRequest CreateHttpRequest(Uri requestUri) - { - this.LastCreatedRequest = new MockHttpRequest(requestUri, this.GetResponseAction, this.ResponseCreator); - return this.LastCreatedRequest; - } + public IHttpRequest CreateHttpRequest(Uri requestUri) + { + this.LastCreatedRequest = new MockHttpRequest(requestUri, this.GetResponseAction, this.ResponseCreator); + return this.LastCreatedRequest; + } - public void Dispose() - { - } + public void Dispose() + { } -#endif } +#endif diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 96092e2a12..46e41168f8 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -16,171 +16,174 @@ using System; using System.Collections.Generic; +#if NET452 using System.IO; +#endif using System.Linq; using System.Net; +#if !NET452 using System.Net.Http; +#endif using System.Reflection; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +internal class MockWebResponse { - internal class MockWebResponse - { #if NET452 - public static HttpWebResponse CreateFromResource(string resourceName) - { - var rawResponse = Utils.GetResourceText(resourceName); - var response = ParseRawReponse(rawResponse); - var statusCode = ParseStatusCode(response.StatusLine); - return Create(statusCode, response.Headers, response.Body); - } + public static HttpWebResponse CreateFromResource(string resourceName) + { + var rawResponse = Utils.GetResourceText(resourceName); + var response = ParseRawReponse(rawResponse); + var statusCode = ParseStatusCode(response.StatusLine); + return Create(statusCode, response.Headers, response.Body); + } - public static HttpWebResponse Create(HttpStatusCode statusCode, IDictionary headers, string body = null) - { - var type = typeof(HttpWebResponse); - var assembly = Assembly.GetAssembly(type); - var obj = assembly.CreateInstance("System.Net.HttpWebResponse"); + public static HttpWebResponse Create(HttpStatusCode statusCode, IDictionary headers, string body = null) + { + var type = typeof(HttpWebResponse); + var assembly = Assembly.GetAssembly(type); + var obj = assembly.CreateInstance("System.Net.HttpWebResponse"); - var webHeaders = new WebHeaderCollection(); - if (headers != null) + var webHeaders = new WebHeaderCollection(); + if (headers != null) + { + foreach (var header in headers) { - foreach (var header in headers) - { - webHeaders.Add(header.Key, header.Value); - } + webHeaders.Add(header.Key, header.Value); } - - Stream responseBodyStream = null; - body = body ?? string.Empty; - responseBodyStream = Utils.CreateStreamFromString(body); - - var statusFieldInfo = type.GetField( - "m_StatusCode", - BindingFlags.NonPublic | BindingFlags.Instance); - var headersFieldInfo = type.GetField( - "m_HttpResponseHeaders", - BindingFlags.NonPublic | BindingFlags.Instance); - var streamFieldInfo = type.GetField( - "m_ConnectStream", - BindingFlags.NonPublic | BindingFlags.Instance); - var contentLengthFieldInfo = type.GetField( - "m_ContentLength", - BindingFlags.NonPublic | BindingFlags.Instance); - - statusFieldInfo.SetValue(obj, statusCode); - headersFieldInfo.SetValue(obj, webHeaders); - streamFieldInfo.SetValue(obj, responseBodyStream); - contentLengthFieldInfo.SetValue(obj, responseBodyStream.Length); - - return obj as HttpWebResponse; } + Stream responseBodyStream = null; + body = body ?? string.Empty; + responseBodyStream = Utils.CreateStreamFromString(body); + + var statusFieldInfo = type.GetField( + "m_StatusCode", + BindingFlags.NonPublic | BindingFlags.Instance); + var headersFieldInfo = type.GetField( + "m_HttpResponseHeaders", + BindingFlags.NonPublic | BindingFlags.Instance); + var streamFieldInfo = type.GetField( + "m_ConnectStream", + BindingFlags.NonPublic | BindingFlags.Instance); + var contentLengthFieldInfo = type.GetField( + "m_ContentLength", + BindingFlags.NonPublic | BindingFlags.Instance); + + statusFieldInfo.SetValue(obj, statusCode); + headersFieldInfo.SetValue(obj, webHeaders); + streamFieldInfo.SetValue(obj, responseBodyStream); + contentLengthFieldInfo.SetValue(obj, responseBodyStream.Length); + + return obj as HttpWebResponse; + } + #else - public static HttpResponseMessage CreateFromResource(string resourceName) - { - var rawResponse = Utils.GetResourceText(resourceName); + public static HttpResponseMessage CreateFromResource(string resourceName) + { + var rawResponse = Utils.GetResourceText(resourceName); - var response = ParseRawReponse(rawResponse); - var statusCode = ParseStatusCode(response.StatusLine); + var response = ParseRawReponse(rawResponse); + var statusCode = ParseStatusCode(response.StatusLine); - return Create(statusCode, response.Headers, response.Body); - } + return Create(statusCode, response.Headers, response.Body); + } - public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary headers, string body = null) - { - var type = typeof(HttpResponseMessage); - var assembly = Assembly.GetAssembly(type); - var obj = assembly.CreateInstance("System.Net.Http.HttpResponseMessage"); + public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary headers, string body = null) + { + var type = typeof(HttpResponseMessage); + var assembly = Assembly.GetAssembly(type); + var obj = assembly.CreateInstance("System.Net.Http.HttpResponseMessage"); - HttpResponseMessage httpResponseMessage = obj as HttpResponseMessage; - var webHeaders = new WebHeaderCollection(); - if (headers != null) + HttpResponseMessage httpResponseMessage = obj as HttpResponseMessage; + var webHeaders = new WebHeaderCollection(); + if (headers != null) + { + foreach (var header in headers) { - foreach (var header in headers) - { - webHeaders.Add(header.Key, header.Value); - httpResponseMessage.Headers.Add(header.Key, header.Value); - } + webHeaders.Add(header.Key, header.Value); + httpResponseMessage.Headers.Add(header.Key, header.Value); } - - httpResponseMessage.StatusCode = statusCode; - string dummyJson = "{\"key1\":\"value1\"}"; - httpResponseMessage.Content = new StringContent(body ?? dummyJson); // Content should be in Json format else we get exception from downstream unmarshalling - return httpResponseMessage; } + httpResponseMessage.StatusCode = statusCode; + string dummyJson = "{\"key1\":\"value1\"}"; + httpResponseMessage.Content = new StringContent(body ?? dummyJson); // Content should be in Json format else we get exception from downstream unmarshalling + return httpResponseMessage; + } + #endif - public static HttpResponse ParseRawReponse(string rawResponse) - { - var response = new HttpResponse(); - response.StatusLine = rawResponse; + public static HttpResponse ParseRawReponse(string rawResponse) + { + var response = new HttpResponse(); + response.StatusLine = rawResponse; - var responseLines = rawResponse.Split('\n'); + var responseLines = rawResponse.Split('\n'); - if (responseLines.Count() == 0) - { - throw new ArgumentException( - "The resource does not contain a valid HTTP response.", - "resourceName"); - } + if (responseLines.Count() == 0) + { + throw new ArgumentException( + "The resource does not contain a valid HTTP response.", + "resourceName"); + } - response.StatusLine = responseLines[0]; - var currentLine = responseLines[0]; - var statusCode = ParseStatusCode(currentLine); + response.StatusLine = responseLines[0]; + var currentLine = responseLines[0]; + var statusCode = ParseStatusCode(currentLine); - var lineIndex = 0; - if (responseLines.Count() > 1) + var lineIndex = 0; + if (responseLines.Count() > 1) + { + for (lineIndex = 1; lineIndex < responseLines.Count(); lineIndex++) { - for (lineIndex = 1; lineIndex < responseLines.Count(); lineIndex++) + currentLine = responseLines[lineIndex]; + if (currentLine.Trim() == string.Empty) { - currentLine = responseLines[lineIndex]; - if (currentLine.Trim() == string.Empty) - { - currentLine = responseLines[lineIndex - 1]; - break; - } - - var index = currentLine.IndexOf(":"); - if (index != -1) - { - var headerKey = currentLine.Substring(0, index); - var headerValue = currentLine.Substring(index + 1); - response.Headers.Add(headerKey.Trim(), headerValue.Trim()); - } + currentLine = responseLines[lineIndex - 1]; + break; } - } - var startOfBody = rawResponse.IndexOf(currentLine) + currentLine.Length; - response.Body = rawResponse.Substring(startOfBody).Trim(); - return response; + var index = currentLine.IndexOf(":"); + if (index != -1) + { + var headerKey = currentLine.Substring(0, index); + var headerValue = currentLine.Substring(index + 1); + response.Headers.Add(headerKey.Trim(), headerValue.Trim()); + } + } } - private static HttpStatusCode ParseStatusCode(string statusLine) + var startOfBody = rawResponse.IndexOf(currentLine) + currentLine.Length; + response.Body = rawResponse.Substring(startOfBody).Trim(); + return response; + } + + private static HttpStatusCode ParseStatusCode(string statusLine) + { + var statusCode = string.Empty; + try { - var statusCode = string.Empty; - try - { - statusCode = statusLine.Split(' ')[1]; - return (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), statusCode); - } - catch (Exception exception) - { - throw new ArgumentException("Invalid HTTP status line.", exception); - } + statusCode = statusLine.Split(' ')[1]; + return (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), statusCode); + } + catch (Exception exception) + { + throw new ArgumentException("Invalid HTTP status line.", exception); } + } - public class HttpResponse + public class HttpResponse + { + public HttpResponse() { - public HttpResponse() - { - this.Headers = new Dictionary(); - } + this.Headers = new Dictionary(); + } - public string StatusLine { get; set; } + public string StatusLine { get; set; } - public IDictionary Headers { get; private set; } + public IDictionary Headers { get; private set; } - public string Body { get; set; } - } + public string Body { get; set; } } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs index d7dbde4f11..635f5efabf 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -21,57 +21,56 @@ using System.Linq; using System.Reflection; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +internal static class Utils { - internal static class Utils + public static Stream CreateStreamFromString(string s) { - public static Stream CreateStreamFromString(string s) - { - MemoryStream stream = new MemoryStream(); - StreamWriter writer = new StreamWriter(stream); - writer.Write(s); - writer.Flush(); - stream.Position = 0; - return stream; - } + MemoryStream stream = new MemoryStream(); + StreamWriter writer = new StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } - public static Stream GetResourceStream(string resourceName) - { - Assembly assembly = typeof(Utils).Assembly; - var resource = FindResourceName(resourceName); - Stream stream = assembly.GetManifestResourceStream(resource); - return stream; - } + public static Stream GetResourceStream(string resourceName) + { + Assembly assembly = typeof(Utils).Assembly; + var resource = FindResourceName(resourceName); + Stream stream = assembly.GetManifestResourceStream(resource); + return stream; + } - public static string GetResourceText(string resourceName) + public static string GetResourceText(string resourceName) + { + using (StreamReader reader = new StreamReader(GetResourceStream(resourceName))) { - using (StreamReader reader = new StreamReader(GetResourceStream(resourceName))) - { - return reader.ReadToEnd(); - } + return reader.ReadToEnd(); } + } - public static string FindResourceName(string partialName) - { - return FindResourceName(s => s.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) >= 0).SingleOrDefault(); - } + public static string FindResourceName(string partialName) + { + return FindResourceName(s => s.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) >= 0).SingleOrDefault(); + } - public static IEnumerable FindResourceName(Predicate match) + public static IEnumerable FindResourceName(Predicate match) + { + Assembly assembly = typeof(Utils).Assembly; + var allResources = assembly.GetManifestResourceNames(); + foreach (var resource in allResources) { - Assembly assembly = typeof(Utils).Assembly; - var allResources = assembly.GetManifestResourceNames(); - foreach (var resource in allResources) + if (match(resource)) { - if (match(resource)) - { - yield return resource; - } + yield return resource; } } + } - public static object GetTagValue(Activity activity, string tagName) - { - return OpenTelemetry.Contrib.Instrumentation.AWS.Implementation.Utils.GetTagValue(activity, tagName); - } + public static object GetTagValue(Activity activity, string tagName) + { + return Implementation.Utils.GetTagValue(activity, tagName); } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index b29f315d82..9d4ace50ce 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -25,262 +25,261 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.AWSLambda.Tests +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; + +public class AWSLambdaWrapperTests { - public class AWSLambdaWrapperTests + private const string TraceId = "5759e988bd862e3fe1be46a994272793"; + private const string XRayParentId = "53995c3f42cd8ad8"; + private const string CustomParentId = "11195c3f42cd8222"; + + private readonly SampleHandlers sampleHandlers; + private readonly SampleLambdaContext sampleLambdaContext; + + public AWSLambdaWrapperTests() { - private const string TraceId = "5759e988bd862e3fe1be46a994272793"; - private const string XRayParentId = "53995c3f42cd8ad8"; - private const string CustomParentId = "11195c3f42cd8222"; + this.sampleHandlers = new SampleHandlers(); + this.sampleLambdaContext = new SampleLambdaContext(); + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=1"); + Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); + Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); + } - private readonly SampleHandlers sampleHandlers; - private readonly SampleLambdaContext sampleLambdaContext; + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TraceSyncWithInputAndReturn(bool setCustomParent) + { + var processor = new Mock>(); - public AWSLambdaWrapperTests() + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .AddProcessor(processor.Object) + .Build()) { - this.sampleHandlers = new SampleHandlers(); - this.sampleLambdaContext = new SampleLambdaContext(); - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=1"); - Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); + var parentContext = setCustomParent ? CreateParentContext() : default; + var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void TraceSyncWithInputAndReturn(bool setCustomParent) - { - var processor = new Mock>(); - - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) - { - var parentContext = setCustomParent ? CreateParentContext() : default; - var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } + // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(6, processor.Invocations.Count); - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + var activity = (Activity)processor.Invocations[1].Arguments[0]; + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); + } - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TraceSyncWithInputAndNoReturn(bool setCustomParent) + { + var processor = new Mock>(); - [Theory] - [InlineData(false)] - [InlineData(true)] - public void TraceSyncWithInputAndNoReturn(bool setCustomParent) + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .AddProcessor(processor.Object) + .Build()) { - var processor = new Mock>(); + var parentContext = setCustomParent ? CreateParentContext() : default; + AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); + } - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) - { - var parentContext = setCustomParent ? CreateParentContext() : default; - AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } + // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(6, processor.Invocations.Count); - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + var activity = (Activity)processor.Invocations[1].Arguments[0]; + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); + } - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - } + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) + { + var processor = new Mock>(); - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .AddProcessor(processor.Object) + .Build()) { - var processor = new Mock>(); + var parentContext = setCustomParent ? CreateParentContext() : default; + var result = await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); + } - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) - { - var parentContext = setCustomParent ? CreateParentContext() : default; - var result = await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } + // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(6, processor.Invocations.Count); - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + var activity = (Activity)processor.Invocations[1].Arguments[0]; + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); + } - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - } + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) + { + var processor = new Mock>(); - [Theory] - [InlineData(false)] - [InlineData(true)] - public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .AddProcessor(processor.Object) + .Build()) { - var processor = new Mock>(); + var parentContext = setCustomParent ? CreateParentContext() : default; + await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); + } - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) - { - var parentContext = setCustomParent ? CreateParentContext() : default; - await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } + // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(6, processor.Invocations.Count); - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + var activity = (Activity)processor.Invocations[1].Arguments[0]; + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); + } - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void TestLambdaHandlerException(bool setCustomParent) + { + var processor = new Mock>(); - [Theory] - [InlineData(false)] - [InlineData(true)] - public void TestLambdaHandlerException(bool setCustomParent) + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .AddProcessor(processor.Object) + .Build()) { - var processor = new Mock>(); - - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) + try { - try - { - var parentContext = setCustomParent ? CreateParentContext() : default; - AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoReturnException, "TestException", this.sampleLambdaContext, parentContext); - } - catch - { - var resource = tracerProvider.GetResource(); - this.AssertResourceAttributes(resource); - } + var parentContext = setCustomParent ? CreateParentContext() : default; + AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncNoReturnException, "TestException", this.sampleLambdaContext, parentContext); } - - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); - - var activity = (Activity)processor.Invocations[1].Arguments[0]; - this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); - this.AssertSpanAttributes(activity); - this.AssertSpanException(activity); - } - - [Fact] - public void TestLambdaHandlerNotSampled() - { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0"); - - var processor = new Mock>(); - - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) - .Build()) + catch { - var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); var resource = tracerProvider.GetResource(); this.AssertResourceAttributes(resource); } + } - // SetParentProvider -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(4, processor.Invocations.Count); + // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(6, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.True(activities.Length == 0); - } + var activity = (Activity)processor.Invocations[1].Arguments[0]; + this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); + this.AssertSpanAttributes(activity); + this.AssertSpanException(activity); + } - [Fact] - public void OnFunctionStart_NoParent_ActivityCreated() - { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", null); + [Fact] + public void TestLambdaHandlerNotSampled() + { + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0"); - Activity activity = null; - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations() - .Build()) - { - activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); - } + var processor = new Mock>(); - Assert.NotNull(activity); + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .AddProcessor(processor.Object) + .Build()) + { + var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); + var resource = tracerProvider.GetResource(); + this.AssertResourceAttributes(resource); } - [Fact] - public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_ActivityCreated() - { - Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=0"); - Activity activity = null; + // SetParentProvider -> OnForceFlush -> OnShutdown -> Dispose + Assert.Equal(4, processor.Invocations.Count); - using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) - .Build()) - { - activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); - } + var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); + Assert.True(activities.Length == 0); + } - Assert.NotNull(activity); - } + [Fact] + public void OnFunctionStart_NoParent_ActivityCreated() + { + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", null); - private static ActivityContext CreateParentContext() + Activity activity = null; + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations() + .Build()) { - var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); - var parentId = ActivitySpanId.CreateFromString(CustomParentId.AsSpan()); - return new ActivityContext(traceId, parentId, ActivityTraceFlags.Recorded); + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); } - private void AssertSpanProperties(Activity activity, string parentId) - { - Assert.Equal(TraceId, activity.TraceId.ToHexString()); - Assert.Equal(parentId, activity.ParentSpanId.ToHexString()); - Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); - Assert.Equal(ActivityKind.Server, activity.Kind); - Assert.Equal("testfunction", activity.DisplayName); - Assert.Equal("OpenTelemetry.Instrumentation.AWSLambda", activity.Source.Name); - - // Version should consist of four decimals separated by dots. - Assert.Matches(@"^\d+(\.\d+){3}$", activity.Source.Version); - } + Assert.NotNull(activity); + } - private void AssertResourceAttributes(Resource resource) - { - var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - Assert.Equal("aws", resourceAttributes[AWSLambdaSemanticConventions.AttributeCloudProvider]); - Assert.Equal("us-east-1", resourceAttributes[AWSLambdaSemanticConventions.AttributeCloudRegion]); - Assert.Equal("testfunction", resourceAttributes[AWSLambdaSemanticConventions.AttributeFaasName]); - Assert.Equal("latest", resourceAttributes[AWSLambdaSemanticConventions.AttributeFaasVersion]); - } + [Fact] + public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_ActivityCreated() + { + Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=0"); + Activity activity = null; - private void AssertSpanAttributes(Activity activity) + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) + .Build()) { - Assert.Equal(this.sampleLambdaContext.AwsRequestId, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasExecution)); - Assert.Equal(this.sampleLambdaContext.InvokedFunctionArn, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasID)); - Assert.Equal(this.sampleLambdaContext.FunctionName, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasName)); - Assert.Equal("other", activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasTrigger)); - Assert.Equal("111111111111", activity.GetTagValue(AWSLambdaSemanticConventions.AttributeCloudAccountID)); + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); } - private void AssertSpanException(Activity activity) - { - Assert.Equal("ERROR", activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); - Assert.NotNull(activity.GetTagValue(SpanAttributeConstants.StatusDescriptionKey)); - } + Assert.NotNull(activity); + } + + private static ActivityContext CreateParentContext() + { + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(CustomParentId.AsSpan()); + return new ActivityContext(traceId, parentId, ActivityTraceFlags.Recorded); + } + + private void AssertSpanProperties(Activity activity, string parentId) + { + Assert.Equal(TraceId, activity.TraceId.ToHexString()); + Assert.Equal(parentId, activity.ParentSpanId.ToHexString()); + Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); + Assert.Equal(ActivityKind.Server, activity.Kind); + Assert.Equal("testfunction", activity.DisplayName); + Assert.Equal("OpenTelemetry.Instrumentation.AWSLambda", activity.Source.Name); + + // Version should consist of four decimals separated by dots. + Assert.Matches(@"^\d+(\.\d+){3}$", activity.Source.Version); + } + + private void AssertResourceAttributes(Resource resource) + { + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); + Assert.Equal("aws", resourceAttributes[AWSLambdaSemanticConventions.AttributeCloudProvider]); + Assert.Equal("us-east-1", resourceAttributes[AWSLambdaSemanticConventions.AttributeCloudRegion]); + Assert.Equal("testfunction", resourceAttributes[AWSLambdaSemanticConventions.AttributeFaasName]); + Assert.Equal("latest", resourceAttributes[AWSLambdaSemanticConventions.AttributeFaasVersion]); + } + + private void AssertSpanAttributes(Activity activity) + { + Assert.Equal(this.sampleLambdaContext.AwsRequestId, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasExecution)); + Assert.Equal(this.sampleLambdaContext.InvokedFunctionArn, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasID)); + Assert.Equal(this.sampleLambdaContext.FunctionName, activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasName)); + Assert.Equal("other", activity.GetTagValue(AWSLambdaSemanticConventions.AttributeFaasTrigger)); + Assert.Equal("111111111111", activity.GetTagValue(AWSLambdaSemanticConventions.AttributeCloudAccountID)); + } + + private void AssertSpanException(Activity activity) + { + Assert.Equal("ERROR", activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); + Assert.NotNull(activity.GetTagValue(SpanAttributeConstants.StatusDescriptionKey)); } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 958c3e97a6..ca9e32ad40 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -18,37 +18,36 @@ using System.Threading.Tasks; using Amazon.Lambda.Core; -namespace OpenTelemetry.Instrumentation.AWSLambda.Tests +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; + +internal class SampleHandlers { - internal class SampleHandlers + // Action + public void SampleHandlerSyncInputAndNoReturn(string str, ILambdaContext context) { - // Action - public void SampleHandlerSyncInputAndNoReturn(string str, ILambdaContext context) - { - } + } - // Func - public string SampleHandlerSyncInputAndReturn(string str, ILambdaContext context) - { - return str; - } + // Func + public string SampleHandlerSyncInputAndReturn(string str, ILambdaContext context) + { + return str; + } - // Func - public async Task SampleHandlerAsyncInputAndNoReturn(string str, ILambdaContext context) - { - await Task.Delay(10); - } + // Func + public async Task SampleHandlerAsyncInputAndNoReturn(string str, ILambdaContext context) + { + await Task.Delay(10); + } - // Func> - public async Task SampleHandlerAsyncInputAndReturn(string str, ILambdaContext context) - { - await Task.Delay(10); - return str; - } + // Func> + public async Task SampleHandlerAsyncInputAndReturn(string str, ILambdaContext context) + { + await Task.Delay(10); + return str; + } - public void SampleHandlerSyncNoReturnException(string str, ILambdaContext context) - { - throw new Exception(str); - } + public void SampleHandlerSyncNoReturnException(string str, ILambdaContext context) + { + throw new Exception(str); } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index 5d452b675a..bc36ca20d8 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -17,30 +17,29 @@ using System; using Amazon.Lambda.Core; -namespace OpenTelemetry.Instrumentation.AWSLambda.Tests +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; + +public class SampleLambdaContext : ILambdaContext { - public class SampleLambdaContext : ILambdaContext - { - public string AwsRequestId { get; } = "testrequestid"; + public string AwsRequestId { get; } = "testrequestid"; - public IClientContext ClientContext { get; } = null; + public IClientContext ClientContext { get; } = null; - public string FunctionName { get; } = "testfunction"; + public string FunctionName { get; } = "testfunction"; - public string FunctionVersion { get; } = "latest"; + public string FunctionVersion { get; } = "latest"; - public ICognitoIdentity Identity { get; } = null; + public ICognitoIdentity Identity { get; } = null; - public string InvokedFunctionArn { get; } = "arn:aws:lambda:us-east-1:111111111111:function:testfunction"; + public string InvokedFunctionArn { get; } = "arn:aws:lambda:us-east-1:111111111111:function:testfunction"; - public ILambdaLogger Logger { get; } = null; + public ILambdaLogger Logger { get; } = null; - public string LogGroupName { get; } = null; + public string LogGroupName { get; } = null; - public string LogStreamName { get; } = null; + public string LogStreamName { get; } = null; - public int MemoryLimitInMB { get; } = 0; + public int MemoryLimitInMB { get; } = 0; - public TimeSpan RemainingTime { get; } = default; - } + public TimeSpan RemainingTime { get; } = default; } From f43518312ed9a3fbc5cc09831479721c79f4c39c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 16 Sep 2022 18:49:49 -0700 Subject: [PATCH 0340/1499] [Exporter.Geneva] Move TableNameMappings checks to GenevaExporterOptions class (#646) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 ++++++- .../GenevaExporterOptions.cs | 10 ++++++++-- .../GenevaLogExporter.cs | 6 ------ .../GenevaTraceExporter.cs | 11 ----------- .../GenevaLogExporterTests.cs | 5 ++--- 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 22111fd53a..472bf8169d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -3,7 +3,12 @@ ## Unreleased * Update OTel SDK version to `1.3.1`. - ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + [#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631) + +* The option `TableNameMappings` of `GenevaExporterOptions` will not support + string values that are null, empty, or consist only of white-space characters. + It will also not support string values that contain non-ASCII characters. + [646](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/646) ## 1.4.0-beta.1 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 9664117af3..437569fa4d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Text; using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -44,9 +45,14 @@ public IReadOnlyDictionary TableNameMappings foreach (var entry in value) { - if (entry.Value is null) + if (string.IsNullOrWhiteSpace(entry.Value)) { - throw new ArgumentNullException(entry.Key, $"{nameof(this.TableNameMappings)} must not contain null values."); + throw new ArgumentException($"A string-typed value provided for {nameof(this.TableNameMappings)} must not be null, empty, or consist only of white-space characters."); + } + + if (Encoding.UTF8.GetByteCount(entry.Value) != entry.Value.Length) + { + throw new ArgumentException($"A string-typed value provided for {nameof(this.TableNameMappings)} must not contain non-ASCII characters.", entry.Value); } copy[entry.Key] = entry.Value; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 5f7d4cdd5c..f6f17a0011 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -19,7 +19,6 @@ using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Text; using System.Threading; using Microsoft.Extensions.Logging; using OpenTelemetry.Internal; @@ -58,11 +57,6 @@ public GenevaLogExporter(GenevaExporterOptions options) var tempTableMappings = new Dictionary(options.TableNameMappings.Count, StringComparer.Ordinal); foreach (var kv in options.TableNameMappings) { - if (Encoding.UTF8.GetByteCount(kv.Value) != kv.Value.Length) - { - throw new ArgumentException("The value: \"{tableName}\" provided for TableNameMappings option contains non-ASCII characters", kv.Value); - } - if (kv.Key == "*") { if (kv.Value == "*") diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 4dfa3d828c..5ae7849df1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -19,7 +19,6 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; -using System.Text; using System.Threading; using OpenTelemetry.Internal; @@ -36,16 +35,6 @@ public GenevaTraceExporter(GenevaExporterOptions options) if (options.TableNameMappings != null && options.TableNameMappings.TryGetValue("Span", out var customTableName)) { - if (string.IsNullOrWhiteSpace(customTableName)) - { - throw new ArgumentException("TableName mapping for Span is invalid."); - } - - if (Encoding.UTF8.GetByteCount(customTableName) != customTableName.Length) - { - throw new ArgumentException("The \"{customTableName}\" provided for TableNameMappings option contains non-ASCII characters", customTableName); - } - partAName = customTableName; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 3ec27e5ebf..d86edadca5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -62,15 +62,14 @@ public void SpecialCharactersInTableNameMappings() }); // Throw on null value - include key in exception message - var ex = Assert.Throws(() => + var ex = Assert.Throws(() => { new GenevaExporterOptions { TableNameMappings = new Dictionary { ["TestCategory"] = null }, }; }); - Assert.Contains("TableNameMappings must not contain null values.", ex.Message); - Assert.Equal("TestCategory", ex.ParamName); + Assert.Contains("A string-typed value provided for TableNameMappings must not be null, empty, or consist only of white-space characters.", ex.Message); // Throw when TableNameMappings is null Assert.Throws(() => From 6d7c0d3fb5dbec2dd7fe5bd66b49d23e881e70cd Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 19 Sep 2022 07:28:36 -0700 Subject: [PATCH 0341/1499] Reorganize GenevaExporter directory (#647) --- .../{ => Internal}/ConnectionStringBuilder.cs | 0 .../{ => Internal}/ExporterEventSource.cs | 0 .../{ => Internal}/ReentrantActivityExportProcessor.cs | 0 .../{ => Internal}/ReentrantExportProcessor.cs | 0 src/OpenTelemetry.Exporter.Geneva/{ => Internal}/Schema.cs | 0 .../{ => Internal}/ServiceProviderExtensions.cs | 0 .../{ => Metrics}/GenevaMetricExporter.cs | 0 .../{ => Metrics}/GenevaMetricExporterExtensions.cs | 0 .../{ => Metrics}/GenevaMetricExporterOptions.cs | 0 .../{ => Metrics}/MetricSerializer.cs | 0 .../{ => Metrics/Transport}/IMetricDataTransport.cs | 0 .../{ => Metrics/Transport}/MetricEtwDataTransport.cs | 0 .../{ => Metrics/Transport}/MetricUnixDataTransport.cs | 0 .../{ => MsgPackExporter/Logs}/GenevaLogExporter.cs | 0 .../{ => MsgPackExporter/Logs}/GenevaLoggingExtensions.cs | 0 .../{ => MsgPackExporter}/MessagePackSerializer.cs | 0 .../Traces}/GenevaExporterHelperExtensions.cs | 0 .../{ => MsgPackExporter/Traces}/GenevaTraceExporter.cs | 0 .../{ => MsgPackExporter/Transport}/EtwDataTransport.cs | 0 .../{ => MsgPackExporter/Transport}/IDataTransport.cs | 0 .../Transport}/UnixDomainSocketDataTransport.cs | 0 .../{ => MsgPackExporter/Transport}/UnixDomainSocketEndPoint.cs | 0 22 files changed, 0 insertions(+), 0 deletions(-) rename src/OpenTelemetry.Exporter.Geneva/{ => Internal}/ConnectionStringBuilder.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Internal}/ExporterEventSource.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Internal}/ReentrantActivityExportProcessor.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Internal}/ReentrantExportProcessor.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Internal}/Schema.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Internal}/ServiceProviderExtensions.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics}/GenevaMetricExporter.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics}/GenevaMetricExporterExtensions.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics}/GenevaMetricExporterOptions.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics}/MetricSerializer.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics/Transport}/IMetricDataTransport.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics/Transport}/MetricEtwDataTransport.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => Metrics/Transport}/MetricUnixDataTransport.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Logs}/GenevaLogExporter.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Logs}/GenevaLoggingExtensions.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter}/MessagePackSerializer.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Traces}/GenevaExporterHelperExtensions.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Traces}/GenevaTraceExporter.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Transport}/EtwDataTransport.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Transport}/IDataTransport.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Transport}/UnixDomainSocketDataTransport.cs (100%) rename src/OpenTelemetry.Exporter.Geneva/{ => MsgPackExporter/Transport}/UnixDomainSocketEndPoint.cs (100%) diff --git a/src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/ConnectionStringBuilder.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/ExporterEventSource.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/ReentrantActivityExportProcessor.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/ReentrantExportProcessor.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/Schema.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ServiceProviderExtensions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/ServiceProviderExtensions.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/ServiceProviderExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterExtensions.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaMetricExporterOptions.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/MetricSerializer.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/IMetricDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/MetricEtwDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/MetricUnixDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLoggingExtensions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLoggingExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/MessagePackSerializer.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaExporterHelperExtensions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaExporterHelperExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaTraceExporter.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaTraceExporter.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/EtwDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/IDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/UnixDomainSocketEndPoint.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs From 5344b7b39cb09c424ae71c4eae7417ec59b0b5d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 16:44:11 -0700 Subject: [PATCH 0342/1499] Bump codecov/codecov-action from 3.1.0 to 3.1.1 (#650) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dotnet-core-cov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index fa3dc4d49f..928be44569 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -43,7 +43,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - uses: codecov/codecov-action@v3.1.0 + - uses: codecov/codecov-action@v3.1.1 with: file: TestResults/Cobertura.xml env_vars: OS From c0e856a1fb3c0e9a87b23e36e5617fca9380036a Mon Sep 17 00:00:00 2001 From: Jamie Marconi Date: Mon, 19 Sep 2022 17:48:41 -0700 Subject: [PATCH 0343/1499] Update OpenTelemetry.Instrumentation.Owin to depend on at least Owin 4.2.2 (#648) --- build/Common.props | 2 +- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index 505c5d2725..5bad5db7f0 100644 --- a/build/Common.props +++ b/build/Common.props @@ -28,7 +28,7 @@ [2.1.0,5.0) [3.1.0,) [1.0.0,2.0) - [4.1.1] + [4.2.2,5.0) [3.3.2] [1.0.0,2.0) [1.3.1,2.0) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index eda06216f8..a6d28def9a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -5,6 +5,9 @@ * Changed activity source name from `OpenTelemetry.OWIN` to `OpenTelemetry.Instrumentation.Owin` ([#572](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/572)) +* Changed to depend on at least Owin 4.2.2 to resolve a + [denial of service vulnerability](https://github.com/advisories/GHSA-3rq8-h3gj-r5c6). + ([#648](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/648)) ## 1.0.0-rc.2 From 5aed1985a4c37fdae7a9e3bffeecaca0f422df70 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 20 Sep 2022 11:51:44 -0700 Subject: [PATCH 0344/1499] Updated Owin CHANGELOG for release. (#652) --- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index a6d28def9a..1acd35dc85 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.3 + +Released 2022-Sep-20 + * Changed activity source name from `OpenTelemetry.OWIN` to `OpenTelemetry.Instrumentation.Owin` ([#572](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/572)) From 9b19d9acbe25d8ac604258fef33105c8d2abdc58 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 20 Sep 2022 13:24:35 -0700 Subject: [PATCH 0345/1499] [Owin] Bump target .NET Framework and OTel SDK version (#653) * Bump Owin target framework and OTel SDK version. * Updated CHANGELOG. * Update net framework version in CI. --- .github/workflows/windows-ci.yml | 2 +- build/Common.props | 1 + src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 2 ++ .../OpenTelemetry.Instrumentation.Owin.csproj | 6 +++--- .../OpenTelemetry.Instrumentation.Owin.Tests.csproj | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/windows-ci.yml index 0582256d9c..541d0b6414 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/windows-ci.yml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - version: [net461,netcoreapp3.1,net6.0] + version: [net462,netcoreapp3.1,net6.0] steps: - uses: actions/checkout@v3 diff --git a/build/Common.props b/build/Common.props index 5bad5db7f0..84eed10c51 100644 --- a/build/Common.props +++ b/build/Common.props @@ -6,6 +6,7 @@ $(MSBuildThisFileDirectory)debug.snk $(DefineConstants);SIGNED true + net462 diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 1acd35dc85..2655c8897d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -12,6 +12,8 @@ Released 2022-Sep-20 * Changed to depend on at least Owin 4.2.2 to resolve a [denial of service vulnerability](https://github.com/advisories/GHSA-3rq8-h3gj-r5c6). ([#648](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/648)) +* Updated project to target `net462` and OTel 1.3.1 SDK + ([#653](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/653)) ## 1.0.0-rc.2 diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index df0c19fabc..f2d861129d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -1,6 +1,6 @@  - net461 + $(NetFrameworkMinimumSupportedVersion) OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- @@ -11,11 +11,11 @@ - + - + diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index 53896ddd2b..9187f57329 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry OWIN instrumentation - net461 + $(NetFrameworkMinimumSupportedVersion) From 27bac99fcef070247371534c4b54a4717a25c56c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Sep 2022 17:01:58 -0700 Subject: [PATCH 0346/1499] Bump actions/stale from 5 to 6 (#655) Bumps [actions/stale](https://github.com/actions/stale) from 5 to 6. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .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 3793c1f0a2..39e8be83df 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v5 + - uses: actions/stale@v6 with: stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' From 58cf8d7e13f16b73fb54998fb54f3450e2b5fd5e Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 22 Sep 2022 20:36:13 -0700 Subject: [PATCH 0347/1499] [ASP.NET] Migrate to native Activity Status and Status Desc (#651) --- .../CHANGELOG.md | 3 ++ .../Implementation/HttpInListener.cs | 6 +-- ...penTelemetry.Instrumentation.AspNet.csproj | 1 - .../SpanHelper.cs | 43 +++++++++++++++++++ .../HttpInListenerTests.cs | 18 ++++---- ...emetry.Instrumentation.AspNet.Tests.csproj | 1 - 6 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 71a4bfa708..76782773cf 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Migrate to native Activity `Status` and `StatusDesciption`. + ([#651](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/651)) + ## 1.0.0-rc9.5 (source code moved to contrib repo) Released 2022-Jun-21 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index 716b9c0136..a8c1ddb9a4 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -128,9 +128,9 @@ private void OnStopActivity(Activity activity, HttpContext context) activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); - if (activity.GetStatus().StatusCode == StatusCode.Unset) + if (activity.Status == ActivityStatusCode.Unset) { - activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(activity.Kind, response.StatusCode)); + activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); } var routeData = context.Request.RequestContext.RouteData; @@ -181,7 +181,7 @@ private void OnException(Activity activity, HttpContext context, Exception excep activity.RecordException(exception); } - activity.SetStatus(Status.Error.WithDescription(exception.Message)); + activity.SetStatus(ActivityStatusCode.Error, exception.Message); try { diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 03f775a3d7..060706d0c6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -14,7 +14,6 @@ - diff --git a/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs new file mode 100644 index 0000000000..14e6bc4e2c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// A collection of helper methods to be used when building spans. +/// +internal static class SpanHelper +{ + /// + /// Helper method that populates Activity Status from http status code according + /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. + /// + /// The span kind. + /// Http status code. + /// Resolved span for the Http status code. + public static ActivityStatusCode ResolveActivityStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) + { + var upperBound = kind == ActivityKind.Client ? 399 : 499; + if (httpStatusCode >= 100 && httpStatusCode <= upperBound) + { + return ActivityStatusCode.Unset; + } + + return ActivityStatusCode.Error; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 0e3bd5eef2..70d477c627 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -137,7 +137,7 @@ public void AspNetRequestsAreCollectedSuccessfully( return httpContext.Request.Path != filter; }; - options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? Status.Error : default); + options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? ActivityStatusCode.Error : default); options.RecordException = recordException; }) @@ -217,27 +217,27 @@ public void AspNetRequestsAreCollectedSuccessfully( if (recordException) { - var status = span.GetStatus(); - Assert.Equal(Status.Error.StatusCode, status.StatusCode); - Assert.Equal("Operation is not valid due to the current state of the object.", status.Description); + var status = span.Status; + Assert.Equal(ActivityStatusCode.Error, span.Status); + Assert.Equal("Operation is not valid due to the current state of the object.", span.StatusDescription); } else if (setStatusToErrorInEnrich) { // This validates that users can override the // status in Enrich. - Assert.Equal(Status.Error, span.GetStatus()); + Assert.Equal(ActivityStatusCode.Error, span.Status); // Instrumentation is not expected to set status description // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode - Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); + Assert.True(string.IsNullOrEmpty(span.StatusDescription)); } else { - Assert.Equal(Status.Unset, span.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, span.Status); // Instrumentation is not expected to set status description // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode - Assert.True(string.IsNullOrEmpty(span.GetStatus().Description)); + Assert.True(string.IsNullOrEmpty(span.StatusDescription)); } } @@ -324,7 +324,7 @@ public void ExtractContextIrrespectiveOfTheFilterApplied() Assert.True(isPropagatorCalled); } - private static Action GetEnrichmentAction(Status statusToBeSet) + private static Action GetEnrichmentAction(ActivityStatusCode statusToBeSet) { void EnrichAction(Activity activity, string method, object obj) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index e3499a281e..50803ac337 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -27,7 +27,6 @@ - From c1e7d8c457d03375dd429799794ea15cc918ee10 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 26 Sep 2022 15:58:39 -0700 Subject: [PATCH 0348/1499] Update package versions (#657) --- build/Common.nonprod.props | 4 ++-- build/Common.props | 12 ++++++------ .../InstanaSpanTest.cs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 6b4934f225..5eafbc09ab 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -23,12 +23,12 @@ [0.12.1,0.13) [3.1.2,4.0.0) [2.3.1,3.0) - [5.0,6.0) + [5.0.0,7.0) [16.11.0,17.0) [4.17.2,5.0) $(OpenTelemetryPkgVer) [2.4.3,3.0) - [2.4.1,3.0) + [2.4.2,3.0) diff --git a/build/Common.props b/build/Common.props index 84eed10c51..2e4d94d967 100644 --- a/build/Common.props +++ b/build/Common.props @@ -23,19 +23,19 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [2.4.0,3.0) + [4.2.0,5.0) [6.0.0] - [16.11.0] + [17.3.2] [2.1.0,5.0) [3.1.0,) - [1.0.0,2.0) + [1.0.3,2.0) [4.2.2,5.0) - [3.3.2] - [1.0.0,2.0) + [3.3.3] + [1.1.1,2.0) [1.3.1,2.0) $(OpenTelemetryApiPkgVer) [2.1.58,3.0) - [1.2.0-beta.354,2.0) + [1.2.0-beta.435,2.0) diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index a72c9cf878..7f8a4d6b06 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -136,7 +136,7 @@ internal class SpanEvent } #pragma warning disable SA1402 // File may only contain a single type -public class DataConverter : JsonConverter +internal class DataConverter : JsonConverter #pragma warning restore SA1402 // File may only contain a single type { public override bool CanWrite => false; From 2179d356279dc773756f4e8392ceea901c5653b5 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 26 Sep 2022 16:07:59 -0700 Subject: [PATCH 0349/1499] Update CHANGELOG for Exporter.Stackdriver (#658) --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index e492e044af..ec1f06889a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix the issue of incorrect handling of null attributes. + ([#566](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/566)) + ## 1.0.0-beta.3 Released 2022-Jul-22 From 20338a998bfd7610369900c60ac4c84d2da0ebd3 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 26 Sep 2022 16:22:54 -0700 Subject: [PATCH 0350/1499] [Exporter.Geneva] Optimize GenevaLogExporter (#659) --- .../MsgPackExporter/Logs/GenevaLogExporter.cs | 3 +- .../Exporter/LogExporterBenchmarks.cs | 44 +++++++++---------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs index f6f17a0011..476836005a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs @@ -296,7 +296,8 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Time, timestamp); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_time"); + cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, timestamp); // LogRecord.Timestamp should already be converted to UTC format in the SDK cntFields += 1; // Part A - dt extension diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 876d10f014..b18385afc5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -30,32 +30,32 @@ Without Scopes | Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | |-------------------------- |------------------------ |---------:|---------:|---------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 979.5 ns | 11.46 ns | 10.72 ns | 0.0401 | 256 B | -| LoggerWithDirectLoggerAPI | False | 887.9 ns | 17.24 ns | 16.13 ns | 0.0620 | 392 B | -| LoggerWithSourceGenerator | False | 965.8 ns | 16.84 ns | 15.75 ns | 0.0343 | 216 B | -| SerializeLogRecord | False | 696.5 ns | 13.94 ns | 14.92 ns | 0.0038 | 24 B | -| Export | False | 744.9 ns | 12.91 ns | 12.08 ns | 0.0038 | 24 B | -| LoggerWithMessageTemplate | True | 978.6 ns | 18.95 ns | 19.46 ns | 0.0401 | 256 B | -| LoggerWithDirectLoggerAPI | True | 878.3 ns | 11.43 ns | 10.69 ns | 0.0620 | 392 B | -| LoggerWithSourceGenerator | True | 942.8 ns | 14.55 ns | 13.61 ns | 0.0343 | 216 B | -| SerializeLogRecord | True | 707.3 ns | 9.01 ns | 8.42 ns | 0.0038 | 24 B | -| Export | True | 752.0 ns | 8.97 ns | 7.49 ns | 0.0038 | 24 B | +| LoggerWithMessageTemplate | False | 823.3 ns | 2.20 ns | 1.84 ns | 0.0362 | 232 B | +| LoggerWithDirectLoggerAPI | False | 749.2 ns | 5.49 ns | 4.87 ns | 0.0582 | 368 B | +| LoggerWithSourceGenerator | False | 798.4 ns | 2.72 ns | 2.41 ns | 0.0305 | 192 B | +| SerializeLogRecord | False | 596.3 ns | 10.69 ns | 10.00 ns | - | - | +| Export | False | 655.1 ns | 12.75 ns | 15.18 ns | - | - | +| LoggerWithMessageTemplate | True | 817.8 ns | 3.04 ns | 2.85 ns | 0.0362 | 232 B | +| LoggerWithDirectLoggerAPI | True | 750.5 ns | 4.73 ns | 4.43 ns | 0.0582 | 368 B | +| LoggerWithSourceGenerator | True | 782.3 ns | 9.26 ns | 8.67 ns | 0.0305 | 192 B | +| SerializeLogRecord | True | 580.3 ns | 3.39 ns | 3.17 ns | - | - | +| Export | True | 640.1 ns | 4.26 ns | 3.98 ns | - | - | With Scopes (https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/545) -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Median | Gen 0 | Allocated | -|-------------------------- |------------------------ |-----------:|---------:|---------:|-----------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 1,042.8 ns | 19.34 ns | 54.55 ns | 1,022.1 ns | 0.0572 | 360 B | -| LoggerWithDirectLoggerAPI | False | 953.4 ns | 13.90 ns | 13.00 ns | 950.4 ns | 0.0782 | 496 B | -| LoggerWithSourceGenerator | False | 962.1 ns | 18.93 ns | 17.71 ns | 957.6 ns | 0.0496 | 320 B | -| SerializeLogRecord | False | 722.8 ns | 6.26 ns | 5.23 ns | 722.9 ns | 0.0200 | 128 B | -| Export | False | 789.2 ns | 15.11 ns | 14.14 ns | 787.3 ns | 0.0200 | 128 B | -| LoggerWithMessageTemplate | True | 986.8 ns | 12.56 ns | 11.13 ns | 983.4 ns | 0.0572 | 360 B | -| LoggerWithDirectLoggerAPI | True | 932.1 ns | 18.25 ns | 20.29 ns | 924.7 ns | 0.0782 | 496 B | -| LoggerWithSourceGenerator | True | 980.0 ns | 15.56 ns | 14.55 ns | 979.6 ns | 0.0496 | 320 B | -| SerializeLogRecord | True | 737.5 ns | 13.46 ns | 12.59 ns | 738.8 ns | 0.0200 | 128 B | -| Export | True | 772.2 ns | 14.02 ns | 13.11 ns | 774.8 ns | 0.0200 | 128 B | +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------- |------------------------ |---------:|---------:|---------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 872.5 ns | 5.37 ns | 4.48 ns | 0.0534 | 336 B | +| LoggerWithDirectLoggerAPI | False | 808.6 ns | 12.32 ns | 10.92 ns | 0.0744 | 472 B | +| LoggerWithSourceGenerator | False | 828.1 ns | 4.06 ns | 3.80 ns | 0.0467 | 296 B | +| SerializeLogRecord | False | 607.4 ns | 1.69 ns | 1.50 ns | 0.0162 | 104 B | +| Export | False | 658.8 ns | 2.20 ns | 2.05 ns | 0.0162 | 104 B | +| LoggerWithMessageTemplate | True | 845.7 ns | 3.77 ns | 3.52 ns | 0.0534 | 336 B | +| LoggerWithDirectLoggerAPI | True | 803.4 ns | 5.37 ns | 5.02 ns | 0.0744 | 472 B | +| LoggerWithSourceGenerator | True | 836.9 ns | 7.04 ns | 6.24 ns | 0.0467 | 296 B | +| SerializeLogRecord | True | 605.5 ns | 3.30 ns | 3.09 ns | 0.0162 | 104 B | +| Export | True | 664.1 ns | 2.01 ns | 1.88 ns | 0.0162 | 104 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; From 7f8df02a38f9937ae6a5d1fad7b9ad34c2345bc1 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 26 Sep 2022 18:29:11 -0700 Subject: [PATCH 0351/1499] [Exporter.Geneva] Refactor GenevaExporter (#649) --- .../GenevaExporterHelperExtensions.cs | 0 .../GenevaLogExporter.cs | 73 +++++++++++++++++++ .../Logs => }/GenevaLoggingExtensions.cs | 0 .../GenevaTraceExporter.cs | 73 +++++++++++++++++++ ...vaLogExporter.cs => MsgPackLogExporter.cs} | 64 +++++++--------- ...aceExporter.cs => MsgPackTraceExporter.cs} | 60 +++++++-------- .../Exporter/LogExporterBenchmarks.cs | 58 +++++++-------- .../Exporter/TraceExporterBenchmarks.cs | 15 ++-- .../GenevaLogExporterTests.cs | 36 ++++----- .../GenevaTraceExporterTests.cs | 10 +-- 10 files changed, 260 insertions(+), 129 deletions(-) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter/Traces => }/GenevaExporterHelperExtensions.cs (100%) create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter/Logs => }/GenevaLoggingExtensions.cs (100%) create mode 100644 src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs rename src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/{Logs/GenevaLogExporter.cs => MsgPackLogExporter.cs} (94%) rename src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/{Traces/GenevaTraceExporter.cs => MsgPackTraceExporter.cs} (94%) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaExporterHelperExtensions.cs rename to src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs new file mode 100644 index 0000000000..b23bd32b10 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -0,0 +1,73 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Internal; +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaLogExporter : GenevaBaseExporter +{ + internal bool IsUsingUnixDomainSocket; + + private bool isDisposed; + + private delegate ExportResult ExportLogRecordFunc(in Batch batch); + + private readonly ExportLogRecordFunc exportLogRecord; + + private readonly IDisposable exporter; + + public GenevaLogExporter(GenevaExporterOptions options) + { + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); + + var msgPackExporter = new MsgPackLogExporter(options); + this.IsUsingUnixDomainSocket = msgPackExporter.IsUsingUnixDomainSocket; + this.exportLogRecord = (in Batch batch) => msgPackExporter.Export(in batch); + this.exporter = msgPackExporter; + } + + public override ExportResult Export(in Batch batch) + { + return this.exportLogRecord(batch); + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } + + if (disposing) + { + try + { + this.exporter.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("GenevaLogExporter Dispose failed.", ex); + } + } + + this.isDisposed = true; + base.Dispose(disposing); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLoggingExtensions.cs rename to src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs new file mode 100644 index 0000000000..9c37b6db84 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -0,0 +1,73 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.Geneva; + +public class GenevaTraceExporter : GenevaBaseExporter +{ + internal readonly bool IsUsingUnixDomainSocket; + + private bool isDisposed; + + private delegate ExportResult ExportActivityFunc(in Batch batch); + + private readonly ExportActivityFunc exportActivity; + + private readonly IDisposable exporter; + + public GenevaTraceExporter(GenevaExporterOptions options) + { + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); + + var msgPackExporter = new MsgPackTraceExporter(options); + this.IsUsingUnixDomainSocket = msgPackExporter.IsUsingUnixDomainSocket; + this.exportActivity = (in Batch batch) => msgPackExporter.Export(in batch); + this.exporter = msgPackExporter; + } + + public override ExportResult Export(in Batch batch) + { + return this.exportActivity(batch); + } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } + + if (disposing) + { + try + { + this.exporter.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("GenevaTraceExporter Dispose failed.", ex); + } + } + + this.isDisposed = true; + base.Dispose(disposing); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs similarity index 94% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 476836005a..d437ff6c15 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Logs/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,12 +21,11 @@ using System.Runtime.InteropServices; using System.Threading; using Microsoft.Extensions.Logging; -using OpenTelemetry.Internal; using OpenTelemetry.Logs; namespace OpenTelemetry.Exporter.Geneva; -public class GenevaLogExporter : GenevaBaseExporter +internal sealed class MsgPackLogExporter : IDisposable { private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) private const int MaxSanitizedEventNameLength = 50; @@ -46,11 +45,8 @@ public class GenevaLogExporter : GenevaBaseExporter private readonly bool shouldPassThruTableMappings; private bool isDisposed; - public GenevaLogExporter(GenevaExporterOptions options) + public MsgPackLogExporter(GenevaExporterOptions options) { - Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); - // TODO: Validate mappings for reserved tablenames etc. if (options.TableNameMappings != null) { @@ -134,7 +130,7 @@ public GenevaLogExporter(GenevaExporterOptions options) private readonly IReadOnlyDictionary m_tableMappings; - public override ExportResult Export(in Batch batch) + public ExportResult Export(in Batch batch) { var result = ExportResult.Success; foreach (var logRecord in batch) @@ -154,31 +150,6 @@ public override ExportResult Export(in Batch batch) return result; } - protected override void Dispose(bool disposing) - { - if (this.isDisposed) - { - return; - } - - if (disposing) - { - // DO NOT Dispose m_buffer as it is a static type - try - { - (this.m_dataTransport as IDisposable)?.Dispose(); - this.m_prepopulatedFieldKeys.Clear(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("GenevaLogExporter Dispose failed.", ex); - } - } - - this.isDisposed = true; - base.Dispose(disposing); - } - internal bool IsUsingUnixDomainSocket { get => this.m_dataTransport is UnixDomainSocketDataTransport; @@ -279,7 +250,7 @@ internal int SerializeLogRecord(LogRecord logRecord) { var key = this.m_prepopulatedFieldKeys[i]; var value = this.m_prepopulatedFields[key]; - cursor = AddPartAField(buffer, cursor, key, value); + cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, key, value); cntFields += 1; } } @@ -287,11 +258,11 @@ internal int SerializeLogRecord(LogRecord logRecord) // Part A - core envelope if (sanitizedEventName.Length != 0) { - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, sanitizedEventName); + cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, Schema.V40.PartA.Name, sanitizedEventName); } else { - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); } cntFields += 1; @@ -548,4 +519,25 @@ private static int SerializeSanitizedCategoryName(byte[] buffer, int cursor, str return cursor; } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + // DO NOT Dispose m_buffer as it is a static type + try + { + (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_prepopulatedFieldKeys.Clear(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("MsgPackLogExporter Dispose failed.", ex); + } + + this.isDisposed = true; + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs similarity index 94% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaTraceExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 5ae7849df1..677fea7d4f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Traces/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,17 +20,13 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading; -using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; -public class GenevaTraceExporter : GenevaBaseExporter +internal sealed class MsgPackTraceExporter : IDisposable { - public GenevaTraceExporter(GenevaExporterOptions options) + public MsgPackTraceExporter(GenevaExporterOptions options) { - Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); - var partAName = "Span"; if (options.TableNameMappings != null && options.TableNameMappings.TryGetValue("Span", out var customTableName)) @@ -125,13 +121,13 @@ public GenevaTraceExporter(GenevaExporterOptions options) // TODO: Do we support PartB as well? // Part A - core envelope - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); + cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); this.m_cntPrepopulatedFields += 1; foreach (var entry in options.PrepopulatedFields) { var value = entry.Value; - cursor = AddPartAField(buffer, cursor, entry.Key, value); + cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, entry.Key, value); this.m_cntPrepopulatedFields += 1; } @@ -144,7 +140,7 @@ public GenevaTraceExporter(GenevaExporterOptions options) Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); } - public override ExportResult Export(in Batch batch) + public ExportResult Export(in Batch batch) { // Note: The MessagePackSerializer takes way less time / memory than creating the activity itself. // This makes the short-circuit check less useful. @@ -173,30 +169,6 @@ public override ExportResult Export(in Batch batch) return result; } - protected override void Dispose(bool disposing) - { - if (this.isDisposed) - { - return; - } - - if (disposing) - { - try - { - (this.m_dataTransport as IDisposable)?.Dispose(); - this.m_buffer.Dispose(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("GenevaTraceExporter Dispose failed.", ex); - } - } - - this.isDisposed = true; - base.Dispose(disposing); - } - internal bool IsUsingUnixDomainSocket { get => this.m_dataTransport is UnixDomainSocketDataTransport; @@ -403,6 +375,26 @@ internal int SerializeActivity(Activity activity) return cursor; } + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + try + { + (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_buffer.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("MsgPackTraceExporter Dispose failed.", ex); + } + + this.isDisposed = true; + } + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) private readonly ThreadLocal m_buffer = new ThreadLocal(() => null); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index b18385afc5..4c6c4bc122 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -20,42 +20,42 @@ using OpenTelemetry.Logs; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621 Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores .NET SDK=7.0.100-preview.6.22352.1 - [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT - DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT + DefaultJob : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT Without Scopes -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | -|-------------------------- |------------------------ |---------:|---------:|---------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 823.3 ns | 2.20 ns | 1.84 ns | 0.0362 | 232 B | -| LoggerWithDirectLoggerAPI | False | 749.2 ns | 5.49 ns | 4.87 ns | 0.0582 | 368 B | -| LoggerWithSourceGenerator | False | 798.4 ns | 2.72 ns | 2.41 ns | 0.0305 | 192 B | -| SerializeLogRecord | False | 596.3 ns | 10.69 ns | 10.00 ns | - | - | -| Export | False | 655.1 ns | 12.75 ns | 15.18 ns | - | - | -| LoggerWithMessageTemplate | True | 817.8 ns | 3.04 ns | 2.85 ns | 0.0362 | 232 B | -| LoggerWithDirectLoggerAPI | True | 750.5 ns | 4.73 ns | 4.43 ns | 0.0582 | 368 B | -| LoggerWithSourceGenerator | True | 782.3 ns | 9.26 ns | 8.67 ns | 0.0305 | 192 B | -| SerializeLogRecord | True | 580.3 ns | 3.39 ns | 3.17 ns | - | - | -| Export | True | 640.1 ns | 4.26 ns | 3.98 ns | - | - | +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------- |------------------------ |-----------:|--------:|--------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 1,273.1 ns | 6.09 ns | 5.39 ns | 0.0362 | 232 B | +| LoggerWithDirectLoggerAPI | False | 1,213.0 ns | 9.71 ns | 8.61 ns | 0.0572 | 368 B | +| LoggerWithSourceGenerator | False | 1,243.5 ns | 6.13 ns | 5.44 ns | 0.0305 | 192 B | +| SerializeLogRecord | False | 587.7 ns | 2.71 ns | 2.54 ns | - | - | +| Export | False | 955.0 ns | 5.46 ns | 5.11 ns | - | - | +| LoggerWithMessageTemplate | True | 1,261.1 ns | 6.59 ns | 5.84 ns | 0.0362 | 232 B | +| LoggerWithDirectLoggerAPI | True | 1,214.4 ns | 4.56 ns | 4.27 ns | 0.0572 | 368 B | +| LoggerWithSourceGenerator | True | 1,229.6 ns | 6.84 ns | 6.40 ns | 0.0305 | 192 B | +| SerializeLogRecord | True | 581.6 ns | 2.38 ns | 2.11 ns | - | - | +| Export | True | 958.4 ns | 3.02 ns | 2.52 ns | - | - | With Scopes (https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/545) -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | -|-------------------------- |------------------------ |---------:|---------:|---------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 872.5 ns | 5.37 ns | 4.48 ns | 0.0534 | 336 B | -| LoggerWithDirectLoggerAPI | False | 808.6 ns | 12.32 ns | 10.92 ns | 0.0744 | 472 B | -| LoggerWithSourceGenerator | False | 828.1 ns | 4.06 ns | 3.80 ns | 0.0467 | 296 B | -| SerializeLogRecord | False | 607.4 ns | 1.69 ns | 1.50 ns | 0.0162 | 104 B | -| Export | False | 658.8 ns | 2.20 ns | 2.05 ns | 0.0162 | 104 B | -| LoggerWithMessageTemplate | True | 845.7 ns | 3.77 ns | 3.52 ns | 0.0534 | 336 B | -| LoggerWithDirectLoggerAPI | True | 803.4 ns | 5.37 ns | 5.02 ns | 0.0744 | 472 B | -| LoggerWithSourceGenerator | True | 836.9 ns | 7.04 ns | 6.24 ns | 0.0467 | 296 B | -| SerializeLogRecord | True | 605.5 ns | 3.30 ns | 3.09 ns | 0.0162 | 104 B | -| Export | True | 664.1 ns | 2.01 ns | 1.88 ns | 0.0162 | 104 B | +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | +|-------------------------- |------------------------ |-----------:|--------:|--------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 1,280.8 ns | 7.45 ns | 6.61 ns | 0.0534 | 336 B | +| LoggerWithDirectLoggerAPI | False | 1,261.5 ns | 6.38 ns | 5.96 ns | 0.0744 | 472 B | +| LoggerWithSourceGenerator | False | 1,309.3 ns | 4.83 ns | 4.52 ns | 0.0458 | 296 B | +| SerializeLogRecord | False | 611.3 ns | 4.63 ns | 4.11 ns | 0.0162 | 104 B | +| Export | False | 1,012.2 ns | 7.56 ns | 7.07 ns | 0.0153 | 104 B | +| LoggerWithMessageTemplate | True | 1,278.3 ns | 6.63 ns | 5.88 ns | 0.0534 | 336 B | +| LoggerWithDirectLoggerAPI | True | 1,263.8 ns | 8.26 ns | 7.73 ns | 0.0744 | 472 B | +| LoggerWithSourceGenerator | True | 1,273.4 ns | 5.57 ns | 5.21 ns | 0.0458 | 296 B | +| SerializeLogRecord | True | 604.3 ns | 2.83 ns | 2.65 ns | 0.0162 | 104 B | +| Export | True | 1,003.6 ns | 9.29 ns | 8.69 ns | 0.0153 | 104 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; @@ -65,7 +65,7 @@ public class LogExporterBenchmarks { private readonly ILogger logger; private readonly ILoggerFactory loggerFactory; - private readonly GenevaLogExporter exporter; + private readonly MsgPackLogExporter exporter; private readonly LogRecord logRecord; private readonly Batch batch; @@ -97,7 +97,7 @@ public LogExporterBenchmarks() // For msgpack serialization + export this.logRecord = GenerateTestLogRecord(); this.batch = GenerateTestLogRecordBatch(); - this.exporter = new GenevaLogExporter(new GenevaExporterOptions + this.exporter = new MsgPackLogExporter(new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", PrepopulatedFields = new Dictionary diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index 3460304ff1..3956343f72 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -14,23 +14,24 @@ // limitations under the License. // +using System; using System.Collections.Generic; using System.Diagnostics; using BenchmarkDotNet.Attributes; using OpenTelemetry.Trace; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621 Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores .NET SDK=7.0.100-preview.6.22352.1 - [Host] : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT - DefaultJob : .NET 6.0.8 (6.0.822.36306), X64 RyuJIT + [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT + DefaultJob : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT | Method | Mean | Error | StdDev | Gen 0 | Allocated | |------------------ |---------:|--------:|--------:|-------:|----------:| -| ExportActivity | 422.0 ns | 8.41 ns | 8.64 ns | 0.0062 | 40 B | -| SerializeActivity | 387.4 ns | 7.22 ns | 7.09 ns | 0.0062 | 40 B | +| ExportActivity | 719.9 ns | 5.83 ns | 5.45 ns | 0.0057 | 40 B | +| SerializeActivity | 361.7 ns | 1.09 ns | 0.97 ns | 0.0062 | 40 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; @@ -40,7 +41,7 @@ public class TraceExporterBenchmarks { private readonly Activity activity; private readonly Batch batch; - private readonly GenevaTraceExporter exporter; + private readonly MsgPackTraceExporter exporter; private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); public TraceExporterBenchmarks() @@ -67,7 +68,7 @@ public TraceExporterBenchmarks() this.activity?.SetStatus(Status.Error); } - this.exporter = new GenevaTraceExporter(new GenevaExporterOptions + this.exporter = new MsgPackTraceExporter(new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", PrepopulatedFields = new Dictionary diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index d86edadca5..383c359519 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -171,7 +171,7 @@ public void TableNameMappingTest(params string[] category) .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + using var exporter = new MsgPackLogExporter(exporterOptions); ILogger logger; ThreadLocal m_buffer; @@ -188,7 +188,7 @@ public void TableNameMappingTest(params string[] category) logger.LogError("this does not matter"); Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); actualTableName = (fluentdData as object[])[0] as string; @@ -206,7 +206,7 @@ public void TableNameMappingTest(params string[] category) logger.LogError("this does not matter"); Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); actualTableName = (fluentdData as object[])[0] as string; @@ -293,13 +293,13 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + using var exporter = new MsgPackLogExporter(exporterOptions); ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; ThreadLocal m_buffer; object fluentdData; string actualTableName; - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. foreach (var mapping in userInitializedCategoryToTableNameMappings) @@ -407,7 +407,7 @@ public void SerializeILoggerScopes() byte[] serializedData; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; serializedData = m_buffer.Value; } else @@ -504,7 +504,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + using var exporter = new MsgPackLogExporter(exporterOptions); // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter var logger = loggerFactory.CreateLogger(); @@ -524,7 +524,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var body = GetField(fluentdData, "body"); @@ -554,7 +554,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); @@ -581,7 +581,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); @@ -606,7 +606,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); Assert.Equal("Value1", GetField(fluentdData, "Key1")); @@ -706,7 +706,7 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + using var exporter = new MsgPackLogExporter(exporterOptions); // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter var logger = loggerFactory.CreateLogger(); @@ -751,7 +751,7 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin // logRecordList should have 14 logRecord entries as there were 14 Log calls Assert.Equal(14, logRecordList.Count); - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; foreach (var logRecord in logRecordList) { @@ -842,7 +842,7 @@ public void SuccessfulExportOnLinux() serverSocket.ReceiveTimeout = 10000; // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - using var exporter = new GenevaLogExporter(new GenevaExporterOptions + using var exporter = new MsgPackLogExporter(new GenevaExporterOptions { ConnectionString = "Endpoint=unix:" + path, PrepopulatedFields = new Dictionary @@ -938,7 +938,7 @@ public void SerializationTestForException() .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + using var exporter = new MsgPackLogExporter(exporterOptions); // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter var logger = loggerFactory.CreateLogger(); @@ -954,7 +954,7 @@ public void SerializationTestForException() // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var exceptionType = GetField(fluentdData, "env_ex_type"); @@ -1012,7 +1012,7 @@ public void SerializationTestForEventId() .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. - using var exporter = new GenevaLogExporter(exporterOptions); + using var exporter = new MsgPackLogExporter(exporterOptions); // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter var logger = loggerFactory.CreateLogger(); @@ -1028,7 +1028,7 @@ public void SerializationTestForEventId() // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(GenevaLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 0db23b09b7..34ae3c7c61 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -250,10 +250,10 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, exporterOptions.CustomFields = new string[] { "clientRequestId" }; } - using var exporter = new GenevaTraceExporter(exporterOptions); - var dedicatedFields = typeof(GenevaTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as IReadOnlyDictionary; - var CS40_PART_B_MAPPING = typeof(GenevaTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; - var m_buffer = typeof(GenevaTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; + using var exporter = new MsgPackTraceExporter(exporterOptions); + var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as IReadOnlyDictionary; + var CS40_PART_B_MAPPING = typeof(MsgPackTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; + var m_buffer = typeof(MsgPackTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; // Add an ActivityListener to serialize the activity and assert that it was valid on ActivityStopped event @@ -417,7 +417,7 @@ public void GenevaTraceExporter_Success_Linux() serverSocket.ReceiveTimeout = 10000; // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - var exporter = new GenevaTraceExporter(new GenevaExporterOptions + var exporter = new MsgPackTraceExporter(new GenevaExporterOptions { ConnectionString = "Endpoint=unix:" + path, PrepopulatedFields = new Dictionary From 22c9beab388aa12a94a9254883fae3429eef15de Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 27 Sep 2022 13:14:21 -0700 Subject: [PATCH 0352/1499] update changelog for release (#661) --- src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 76782773cf..ca186294be 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.6 + +Released 2022-Sep-28 + * Migrate to native Activity `Status` and `StatusDesciption`. ([#651](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/651)) From 79d74989d662602b8b9086658d8ef54fb45aba74 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 27 Sep 2022 13:32:53 -0700 Subject: [PATCH 0353/1499] [Exporter.Geneva] Minor refactoring for MsgPackExporter (#660) --- .../GenevaBaseExporter.cs | 86 ------------------- .../MsgPackExporter/MsgPackExporter.cs | 75 ++++++++++++++++ .../MsgPackExporter/MsgPackLogExporter.cs | 8 +- .../MsgPackExporter/MsgPackTraceExporter.cs | 6 +- .../GenevaLogExporterTests.cs | 8 +- .../GenevaTraceExporterTests.cs | 8 +- 6 files changed, 90 insertions(+), 101 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 3dc7185074..d38c76267a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -14,95 +14,9 @@ // limitations under the License. // -using System; -using System.Collections.Generic; - namespace OpenTelemetry.Exporter.Geneva; public abstract class GenevaBaseExporter : BaseExporter where T : class { - internal static readonly IReadOnlyDictionary V21_PART_A_MAPPING = new Dictionary - { - // Part A - [Schema.V21.PartA.IKey] = "env_iKey", - [Schema.V21.PartA.Name] = "env_name", - [Schema.V21.PartA.Ver] = "env_ver", - [Schema.V21.PartA.Time] = "env_time", - [Schema.V21.PartA.Cv] = "env_cv", - [Schema.V21.PartA.Epoch] = "env_epoch", - [Schema.V21.PartA.Flags] = "env_flags", - [Schema.V21.PartA.PopSample] = "env_popSample", - [Schema.V21.PartA.SeqNum] = "env_seqNum", - - // Part A Application extension - [Schema.V21.PartA.Extensions.App.Id] = "env_appId", - [Schema.V21.PartA.Extensions.App.Ver] = "env_appVer", - - // Part A Cloud extension - [Schema.V21.PartA.Extensions.Cloud.Environment] = "env_cloud_environment", - [Schema.V21.PartA.Extensions.Cloud.Location] = "env_cloud_location", - [Schema.V21.PartA.Extensions.Cloud.Name] = "env_cloud_name", - [Schema.V21.PartA.Extensions.Cloud.DeploymentUnit] = "env_cloud_deploymentUnit", - [Schema.V21.PartA.Extensions.Cloud.Role] = "env_cloud_role", - [Schema.V21.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", - [Schema.V21.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", - [Schema.V21.PartA.Extensions.Cloud.Ver] = "env_cloud_ver", - - // Part A Os extension - [Schema.V21.PartA.Extensions.Os.Name] = "env_os", - [Schema.V21.PartA.Extensions.Os.Ver] = "env_osVer", - }; - - internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = new Dictionary - { - // Part A - [Schema.V40.PartA.IKey] = "env_iKey", - [Schema.V40.PartA.Name] = "env_name", - [Schema.V40.PartA.Ver] = "env_ver", - [Schema.V40.PartA.Time] = "env_time", - - // Part A Application Extension - [Schema.V40.PartA.Extensions.App.Id] = "env_app_id", - [Schema.V40.PartA.Extensions.App.Ver] = "env_app_ver", - - // Part A Cloud Extension - [Schema.V40.PartA.Extensions.Cloud.Role] = "env_cloud_role", - [Schema.V40.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", - [Schema.V40.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", - - // Part A Os extension - [Schema.V40.PartA.Extensions.Os.Name] = "env_os_name", - [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", - }; - - internal static int AddPartAField(byte[] buffer, int cursor, string name, object value) - { - if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); - } - - cursor = MessagePackSerializer.Serialize(buffer, cursor, value); - return cursor; - } - - internal static int AddPartAField(byte[] buffer, int cursor, string name, Span value) - { - if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); - } - - cursor = MessagePackSerializer.SerializeSpan(buffer, cursor, value); - return cursor; - } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs new file mode 100644 index 0000000000..f543b01689 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs @@ -0,0 +1,75 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; + +namespace OpenTelemetry.Exporter.Geneva; + +internal abstract class MsgPackExporter +{ + internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = new Dictionary + { + // Part A + [Schema.V40.PartA.IKey] = "env_iKey", + [Schema.V40.PartA.Name] = "env_name", + [Schema.V40.PartA.Ver] = "env_ver", + [Schema.V40.PartA.Time] = "env_time", + + // Part A Application Extension + [Schema.V40.PartA.Extensions.App.Id] = "env_app_id", + [Schema.V40.PartA.Extensions.App.Ver] = "env_app_ver", + + // Part A Cloud Extension + [Schema.V40.PartA.Extensions.Cloud.Role] = "env_cloud_role", + [Schema.V40.PartA.Extensions.Cloud.RoleInstance] = "env_cloud_roleInstance", + [Schema.V40.PartA.Extensions.Cloud.RoleVer] = "env_cloud_roleVer", + + // Part A Os extension + [Schema.V40.PartA.Extensions.Os.Name] = "env_os_name", + [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", + }; + + protected static int AddPartAField(byte[] buffer, int cursor, string name, object value) + { + if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + } + + cursor = MessagePackSerializer.Serialize(buffer, cursor, value); + return cursor; + } + + protected static int AddPartAField(byte[] buffer, int cursor, string name, Span value) + { + if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); + } + else + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); + } + + cursor = MessagePackSerializer.SerializeSpan(buffer, cursor, value); + return cursor; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index d437ff6c15..aa60cb88b4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Exporter.Geneva; -internal sealed class MsgPackLogExporter : IDisposable +internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable { private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) private const int MaxSanitizedEventNameLength = 50; @@ -250,7 +250,7 @@ internal int SerializeLogRecord(LogRecord logRecord) { var key = this.m_prepopulatedFieldKeys[i]; var value = this.m_prepopulatedFields[key]; - cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, key, value); + cursor = AddPartAField(buffer, cursor, key, value); cntFields += 1; } } @@ -258,11 +258,11 @@ internal int SerializeLogRecord(LogRecord logRecord) // Part A - core envelope if (sanitizedEventName.Length != 0) { - cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, Schema.V40.PartA.Name, sanitizedEventName); + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, sanitizedEventName); } else { - cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); } cntFields += 1; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 677fea7d4f..bdced95e7d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Exporter.Geneva; -internal sealed class MsgPackTraceExporter : IDisposable +internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable { public MsgPackTraceExporter(GenevaExporterOptions options) { @@ -121,13 +121,13 @@ public MsgPackTraceExporter(GenevaExporterOptions options) // TODO: Do we support PartB as well? // Part A - core envelope - cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); this.m_cntPrepopulatedFields += 1; foreach (var entry in options.PrepopulatedFields) { var value = entry.Value; - cursor = GenevaBaseExporter.AddPartAField(buffer, cursor, entry.Key, value); + cursor = AddPartAField(buffer, cursor, entry.Key, value); this.m_cntPrepopulatedFields += 1; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 383c359519..1014c7b2da 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1130,24 +1130,24 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter // Part A core envelope fields - var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; + var nameKey = MsgPackExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; // Check if the user has configured a custom table mapping Assert.Equal(partAName, mapping[nameKey]); // TODO: Update this when we support multiple Schema formats var partAVer = "4.0"; - var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; + var verKey = MsgPackExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; Assert.Equal(partAVer, mapping[verKey]); foreach (var item in exporterOptions.PrepopulatedFields) { var partAValue = item.Value as string; - var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; + var partAKey = MsgPackExporter.V40_PART_A_MAPPING[item.Key]; Assert.Equal(partAValue, mapping[partAKey]); } - var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; + var timeKey = MsgPackExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; Assert.Equal(logRecord.Timestamp.Ticks, ((DateTime)mapping[timeKey]).Ticks); // Part A dt extensions diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 34ae3c7c61..1f8cab0c1a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -526,24 +526,24 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO // Part A core envelope fields - var nameKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; + var nameKey = MsgPackExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Name]; // Check if the user has configured a custom table mapping Assert.Equal(partAName, mapping[nameKey]); // TODO: Update this when we support multiple Schema formats var partAVer = "4.0"; - var verKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; + var verKey = MsgPackExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Ver]; Assert.Equal(partAVer, mapping[verKey]); foreach (var item in exporterOptions.PrepopulatedFields) { var partAValue = item.Value as string; - var partAKey = GenevaBaseExporter.V40_PART_A_MAPPING[item.Key]; + var partAKey = MsgPackExporter.V40_PART_A_MAPPING[item.Key]; Assert.Equal(partAValue, mapping[partAKey]); } - var timeKey = GenevaBaseExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; + var timeKey = MsgPackExporter.V40_PART_A_MAPPING[Schema.V40.PartA.Time]; Assert.Equal(tsEnd, ((DateTime)mapping[timeKey]).Ticks); // Part A dt extensions From 00a1de9f6f7a2ad268daccfeb79c5d52184e472b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 28 Sep 2022 16:27:57 -0700 Subject: [PATCH 0354/1499] [TelemetryHttpModule] Update `OpenTelemetry.Api` reference and changelog (#665) --- .../CHANGELOG.md | 7 +++++++ ...metry.Instrumentation.AspNet.TelemetryHttpModule.csproj | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index ed4038c5fc..bd3006b278 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.0.0-rc9.6 + +Released 2022-Sep-28 + +* Update `OpenTelemetry.Api` to `1.3.1`. +([#665](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/665)) + ## 1.0.0-rc9.5 (source code moved to contrib repo) Released 2022-Jun-21 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 35ea9547d7..060ca62f03 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -23,6 +23,6 @@ - + From 0f8bdd97c6291bc8e6761eefacb1c9cea8e52577 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 28 Sep 2022 17:16:19 -0700 Subject: [PATCH 0355/1499] [Extensions.PersistentStorage] Stabilize tests (#666) --- .../FileBlobProviderTests.cs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs index 2e56912904..23be0a0f54 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs @@ -78,7 +78,7 @@ public void FileBlobProvider_TestRetentionPeriod() var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 2000; + int retentionPeriodInMilliseconds = 1000; int writeTimeOutInMilliseconds = 1000; using var blobProvider = new FileBlobProvider( testDirectory.FullName, @@ -90,9 +90,10 @@ public void FileBlobProvider_TestRetentionPeriod() var data = Encoding.UTF8.GetBytes("Hello, World!"); Assert.True(blobProvider.TryCreateBlob(data, out var blob)); - // Wait for maintenance job to run - // TODO: reduce/eliminate sleep time - Thread.Sleep(4000); + // Wait for rentention deadline to expire + Thread.Sleep(2000); + var retentionDeadline = DateTime.UtcNow - TimeSpan.FromMilliseconds(retentionPeriodInMilliseconds); + PersistentStorageHelper.RemoveExpiredBlob(retentionDeadline, ((FileBlob)blob).FullPath); // Blob will be deleted as retention period is 1 sec Assert.False(File.Exists(((FileBlob)blob).FullPath)); @@ -125,9 +126,10 @@ public void FileBlobProvider_TestWriteTimeoutPeriod() // validate file moved successfully Assert.True(File.Exists(((FileBlob)blob).FullPath + ".tmp")); - // Wait for maintenance job to run - // TODO: reduce/eliminate sleep time - Thread.Sleep(4000); + // wait for timeout period + Thread.Sleep(2000); + var timeoutDeadline = DateTime.UtcNow - TimeSpan.FromMilliseconds(writeTimeOutInMilliseconds); + PersistentStorageHelper.RemoveTimedOutTmpFiles(timeoutDeadline, ((FileBlob)blob).FullPath + ".tmp"); // tmp file will be deleted as write timeout period is 1 sec Assert.False(File.Exists(((FileBlob)blob).FullPath + ".tmp")); @@ -160,9 +162,9 @@ public void FileBlobProviderTests_TestLeaseExpiration() var leasePath = ((FileBlob)blob).FullPath; Assert.True(File.Exists(leasePath)); - // Wait for maintenance job to run - // TODO: reduce/eliminate sleep time - Thread.Sleep(4000); + // Wait for lease to expire + Thread.Sleep(2000); + PersistentStorageHelper.RemoveExpiredLease(DateTime.UtcNow, leasePath); // File name will be change to .blob Assert.True(File.Exists(blobPath)); From 215bc921a233200e2acfafc3420e1b763b4ea385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 29 Sep 2022 22:35:04 +0200 Subject: [PATCH 0356/1499] [Instrumentation.AspNet] use prop variables in project files (#668) --- ...elemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.AspNet.csproj | 2 +- ...ry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.AspNet.Tests.csproj | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 060ca62f03..64ed2d64c2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -1,7 +1,7 @@ - net462 + $(NetFrameworkMinimumSupportedVersion) A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI Instrumentation.AspNet.TelemetryHttpModule- @@ -23,6 +23,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 060706d0c6..ea25e6d359 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -1,7 +1,7 @@ - net462 + $(NetFrameworkMinimumSupportedVersion) ASP.NET instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index 84c20ffb54..2fbd767b8b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for ASP.NET HttpModule - net462 + $(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 50803ac337..1809ae8dbf 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry ASP.NET instrumentation - net462 + $(NetFrameworkMinimumSupportedVersion) From 73a093cd4a8430f2f5cd6f596c9bd531a5011d18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Sep 2022 14:58:18 -0700 Subject: [PATCH 0357/1499] Bump actions/setup-dotnet from 2 to 3.0.0 (#671) Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3.0.0. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3.0.0) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dotnet-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 156989f90f..86e1c7c0d1 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v2 + uses: actions/setup-dotnet@v3.0.0 with: dotnet-version: 6.0.x From 59dbc5d2675ea71e7ab617fed627b1f4b4cc8114 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 30 Sep 2022 16:02:59 -0700 Subject: [PATCH 0358/1499] [Exporter.Geneva] Update BenchmarkDotNet version (#670) --- build/Common.nonprod.props | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 5eafbc09ab..026bf333a4 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -20,7 +20,7 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [0.12.1,0.13) + [0.13.2,0.14) [3.1.2,4.0.0) [2.3.1,3.0) [5.0.0,7.0) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index ca229c6b57..57236f7a96 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -8,7 +8,7 @@ - + From 566f103b1112edd1b6c18f52412dd77712819e76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Oct 2022 17:09:25 -0700 Subject: [PATCH 0359/1499] Bump actions/setup-dotnet from 3.0.0 to 3.0.1 (#676) Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v3.0.0...v3.0.1) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dotnet-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 86e1c7c0d1..ba4d12353f 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v3.0.0 + uses: actions/setup-dotnet@v3.0.1 with: dotnet-version: 6.0.x From 462512fc1c3864748c15e029266c6bba8333083e Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Wed, 5 Oct 2022 18:19:19 +0200 Subject: [PATCH 0360/1499] [Instrumentation.AWSLambda] Issue/aws lambda http server semantic conventions attributes (#626) --- .../AWSLambdaWrapper.cs | 64 +++-- .../CHANGELOG.md | 3 + .../Implementation/AWSLambdaHttpUtils.cs | 136 +++++++++ .../Implementation/AWSLambdaUtils.cs | 60 ++-- .../Implementation/CommonExtensions.cs | 57 ++++ ...Telemetry.Instrumentation.AWSLambda.csproj | 1 + .../Implementation/AWSLambdaHttpUtilsTests.cs | 269 ++++++++++++++++++ .../Implementation/CommonExtensionsTests.cs | 49 ++++ 8 files changed, 580 insertions(+), 59 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index c2995f5231..9359fc17b5 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -17,6 +17,7 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Reflection; using System.Threading.Tasks; using Amazon.Lambda.Core; @@ -68,10 +69,7 @@ public static TResult Trace( ILambdaContext context, ActivityContext parentContext = default) { - TResult result = default; - Action action = () => result = lambdaHandler(input, context); - TraceInternal(tracerProvider, action, input, context, parentContext); - return result; + return TraceInternal(tracerProvider, lambdaHandler, input, context, parentContext); } /// @@ -95,8 +93,12 @@ public static void Trace( ILambdaContext context, ActivityContext parentContext = default) { - Action action = () => lambdaHandler(input, context); - TraceInternal(tracerProvider, action, input, context, parentContext); + Func func = (input, context) => + { + lambdaHandler(input, context); + return null; + }; + TraceInternal(tracerProvider, func, input, context, parentContext); } /// @@ -121,8 +123,12 @@ public static Task TraceAsync( ILambdaContext context, ActivityContext parentContext = default) { - Func action = async () => await lambdaHandler(input, context); - return TraceInternalAsync(tracerProvider, action, input, context, parentContext); + Func> func = async (input, context) => + { + await lambdaHandler(input, context); + return null; + }; + return TraceInternalAsync(tracerProvider, func, input, context, parentContext); } /// @@ -141,17 +147,14 @@ public static Task TraceAsync( /// unless X-Ray propagation is disabled in the configuration for this wrapper. /// /// Task of result. - public static async Task TraceAsync( + public static Task TraceAsync( TracerProvider tracerProvider, Func> lambdaHandler, TInput input, ILambdaContext context, ActivityContext parentContext = default) { - TResult result = default; - Func action = async () => result = await lambdaHandler(input, context); - await TraceInternalAsync(tracerProvider, action, input, context, parentContext); - return result; + return TraceInternalAsync(tracerProvider, lambdaHandler, input, context, parentContext); } #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters @@ -167,9 +170,12 @@ internal static Activity OnFunctionStart(TInput input, ILambdaContext co } } - var tags = AWSLambdaUtils.GetFunctionTags(input, context); + var functionTags = AWSLambdaUtils.GetFunctionTags(input, context); + var httpTags = AWSLambdaHttpUtils.GetHttpTags(input); + + // We assume that functionTags and httpTags have no intersection. var activityName = AWSLambdaUtils.GetFunctionName(context) ?? "AWS Lambda Invoke"; - var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, tags); + var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, functionTags.Concat(httpTags)); return activity; } @@ -197,51 +203,55 @@ private static void OnException(Activity activity, Exception exception) } } - private static void TraceInternal( + private static TResult TraceInternal( TracerProvider tracerProvider, - Action handler, + Func handler, TInput input, ILambdaContext context, ActivityContext parentContext = default) { - var lambdaActivity = OnFunctionStart(input, context, parentContext); + var activity = OnFunctionStart(input, context, parentContext); try { - handler(); + var result = handler(input, context); + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, result); + return result; } catch (Exception ex) { - OnException(lambdaActivity, ex); + OnException(activity, ex); throw; } finally { - OnFunctionStop(lambdaActivity, tracerProvider); + OnFunctionStop(activity, tracerProvider); } } - private static async Task TraceInternalAsync( + private static async Task TraceInternalAsync( TracerProvider tracerProvider, - Func handlerAsync, + Func> handlerAsync, TInput input, ILambdaContext context, ActivityContext parentContext = default) { - var lambdaActivity = OnFunctionStart(input, context, parentContext); + var activity = OnFunctionStart(input, context, parentContext); try { - await handlerAsync(); + var result = await handlerAsync(input, context); + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, result); + return result; } catch (Exception ex) { - OnException(lambdaActivity, ex); + OnException(activity, ex); throw; } finally { - OnFunctionStop(lambdaActivity, tracerProvider); + OnFunctionStop(activity, tracerProvider); } } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index db388af70c..729760a2cf 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add HTTP server span attributes for API Gateway triggers + ([#626](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/626)) + ## 1.1.0-beta.2 Release PR: [#590](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/590) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs new file mode 100644 index 0000000000..25adefc903 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -0,0 +1,136 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Web; +using Amazon.Lambda.APIGatewayEvents; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +{ + internal class AWSLambdaHttpUtils + { + // x-forwarded-... headers are described here https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html + private const string HeaderXForwardedProto = "x-forwarded-proto"; + private const string HeaderHost = "host"; + + internal static IEnumerable> GetHttpTags(TInput input) + { + var tags = new List>(); + + string httpScheme = null; + string httpTarget = null; + string httpMethod = null; + string hostName = null; + int? hostPort = null; + + switch (input) + { + case APIGatewayProxyRequest request: + httpScheme = AWSLambdaUtils.GetHeaderValues(request, HeaderXForwardedProto)?.LastOrDefault(); + httpTarget = string.Concat(request.RequestContext?.Path ?? string.Empty, GetQueryString(request)); + httpMethod = request.HttpMethod; + var hostHeader = AWSLambdaUtils.GetHeaderValues(request, HeaderHost)?.LastOrDefault(); + (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeader); + break; + case APIGatewayHttpApiV2ProxyRequest requestV2: + httpScheme = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderXForwardedProto)?.LastOrDefault(); + httpTarget = string.Concat(requestV2.RawPath ?? string.Empty, GetQueryString(requestV2)); + httpMethod = requestV2.RequestContext?.Http?.Method; + var hostHeaderV2 = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderHost)?.LastOrDefault(); + (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeaderV2); + break; + } + + tags.AddTagIfNotNull(SemanticConventions.AttributeHttpScheme, httpScheme); + tags.AddTagIfNotNull(SemanticConventions.AttributeHttpTarget, httpTarget); + tags.AddTagIfNotNull(SemanticConventions.AttributeHttpMethod, httpMethod); + tags.AddTagIfNotNull(SemanticConventions.AttributeNetHostName, hostName); + tags.AddTagIfNotNull(SemanticConventions.AttributeNetHostPort, hostPort); + + return tags; + } + + internal static void SetHttpTagsFromResult(Activity activity, object result) + { + switch (result) + { + case APIGatewayProxyResponse response: + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + break; + case APIGatewayHttpApiV2ProxyResponse responseV2: + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, responseV2.StatusCode); + break; + } + } + + internal static string GetQueryString(APIGatewayProxyRequest request) + { + if (request.MultiValueQueryStringParameters == null) + { + return string.Empty; + } + + var queryString = new StringBuilder(); + var separator = '?'; + foreach (var parameterKvp in request.MultiValueQueryStringParameters) + { + // Multiple values for the same parameter will be added to query + // as ampersand separated: name=value1&name=value2 + foreach (var value in parameterKvp.Value) + { + queryString.Append(separator) + .Append(HttpUtility.UrlEncode(parameterKvp.Key)) + .Append("=") + .Append(HttpUtility.UrlEncode(value)); + separator = '&'; + } + } + + return queryString.ToString(); + } + + internal static string GetQueryString(APIGatewayHttpApiV2ProxyRequest request) => + string.IsNullOrEmpty(request.RawQueryString) ? string.Empty : "?" + request.RawQueryString; + + internal static (string Host, int? Port) GetHostAndPort(string httpScheme, string hostHeader) + { + if (hostHeader == null) + { + return (null, null); + } + + var hostAndPort = hostHeader.Split(new char[] { ':' }, 2); + if (hostAndPort.Length > 1) + { + var host = hostAndPort[0]; + return int.TryParse(hostAndPort[1], out var port) + ? (host, port) + : (host, null); + } + else + { + return (hostAndPort[0], GetDefaultPort(httpScheme)); + } + } + + private static int? GetDefaultPort(string httpScheme) => + httpScheme == "https" ? 443 : httpScheme == "http" ? 80 : null; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index c2ae886f0d..75d0ba2a63 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -137,6 +137,30 @@ internal static IEnumerable> GetFunctionTags GetHeaderValues(APIGatewayProxyRequest request, string name) + { + var multiValueHeader = request.MultiValueHeaders?.GetValueByKeyIgnoringCase(name); + if (multiValueHeader != null) + { + return multiValueHeader; + } + + var headerValue = request.Headers?.GetValueByKeyIgnoringCase(name); + + return headerValue != null ? new[] { headerValue } : null; + } + + internal static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) + { + var headerValue = GetHeaderValue(request, name); + + // Multiple values for the same header will be separated by a comma. + return headerValue?.Split(','); + } + + private static string GetHeaderValue(APIGatewayHttpApiV2ProxyRequest request, string name) => + request.Headers?.GetValueByKeyIgnoringCase(name); + private static string GetAccountId(string functionArn) { // The fifth item of function arn: https://github.com/open-telemetry/opentelemetry-specification/blob/86aeab1e0a7e6c67be09c7f15ff25063ee6d2b5c/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers @@ -167,16 +191,11 @@ private static string GetFaasId(string functionArn) return faasId; } - private static string GetFaasTrigger(TInput input) - { - var trigger = "other"; - if (input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest) - { - trigger = "http"; - } + private static string GetFaasTrigger(TInput input) => + IsHttpRequest(input) ? "http" : "other"; - return trigger; - } + private static bool IsHttpRequest(TInput input) => + input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest; private static ActivityContext ParseXRayTraceHeader(string rawHeader) { @@ -190,27 +209,4 @@ private static ActivityContext ParseXRayTraceHeader(string rawHeader) var propagationContext = xrayPropagator.Extract(default, carrier, Getter); return propagationContext.ActivityContext; } - - private static IEnumerable GetHeaderValues(APIGatewayProxyRequest request, string name) - { - if (request.MultiValueHeaders != null && - request.MultiValueHeaders.TryGetValue(name, out var values)) - { - return values; - } - - return null; - } - - private static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) - { - if (request.Headers != null && - request.Headers.TryGetValue(name, out var header)) - { - // Multiple values for the same header will be separated by a comma. - return header?.Split(','); - } - - return null; - } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs new file mode 100644 index 0000000000..d82ebfad5e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs @@ -0,0 +1,57 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; + +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +{ + internal static class CommonExtensions + { + internal static void AddTagIfNotNull(this List> tags, string tagName, object tagValue) + { + if (tagValue != null) + { + tags.Add(new(tagName, tagValue)); + } + } + + internal static T GetValueByKeyIgnoringCase(this IDictionary dict, string key) + { + // TODO: there may be opportunities for performance improvements of this method. + + // We had to introduce case-insensitive headers search as can't fully rely on + // AWS documentation stating that expected headers are lower-case. AWS test + // console offers JSON example with camel case header names. + // See X-Forwarded-Proto or X-Forwarded-Port for example. + + if (dict == null) + { + return default; + } + + foreach (var kvp in dict) + { + if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) + { + return kvp.Value; + } + } + + return default; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 239fb3e9f1..4afae25088 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -17,6 +17,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs new file mode 100644 index 0000000000..a5ecf93424 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -0,0 +1,269 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Amazon.Lambda.APIGatewayEvents; +using Moq; +using OpenTelemetry.Instrumentation.AWSLambda.Implementation; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation +{ + public class AWSLambdaHttpUtilsTests + { + [Fact] + public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() + { + var request = new APIGatewayProxyRequest + { + MultiValueHeaders = new Dictionary> + { + { "X-Forwarded-Proto", new List { "https" } }, + { "Host", new List { "localhost:1234" } }, + }, + HttpMethod = "GET", + MultiValueQueryStringParameters = new Dictionary> + { + { "q1", new[] { "value1" } }, + }, + RequestContext = new APIGatewayProxyRequest.ProxyRequestContext + { + Path = "/path/test", + }, + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.scheme", "https" }, + { "http.target", "/path/test?q1=value1" }, + { "net.host.name", "localhost" }, + { "net.host.port", 1234 }, + { "http.method", "GET" }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void GetHttpTags_APIGatewayProxyRequestWithMultiValueHeader_UsesLastValue() + { + var request = new APIGatewayProxyRequest + { + MultiValueHeaders = new Dictionary> + { + { "X-Forwarded-Proto", new List { "https", "http" } }, + { "Host", new List { "localhost:1234", "myhost:432" } }, + }, + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.target", string.Empty }, + { "http.scheme", "http" }, + { "net.host.name", "myhost" }, + { "net.host.port", 432 }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void GetHttpTags_APIGatewayHttpApiV2ProxyRequest_ReturnsCorrectTags() + { + var request = new APIGatewayHttpApiV2ProxyRequest + { + Headers = new Dictionary + { + { "X-Forwarded-Proto", "https" }, + { "Host", "localhost:1234" }, + }, + RawPath = "/path/test", + RawQueryString = "q1=value1", + RequestContext = new APIGatewayHttpApiV2ProxyRequest.ProxyRequestContext + { + Http = new APIGatewayHttpApiV2ProxyRequest.HttpDescription + { + Method = "GET", + }, + }, + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.scheme", "https" }, + { "http.target", "/path/test?q1=value1" }, + { "net.host.name", "localhost" }, + { "net.host.port", 1234 }, + { "http.method", "GET" }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void GetHttpTags_APIGatewayHttpApiV2ProxyRequestWithMultiValueHeader_UsesLastValue() + { + var request = new APIGatewayHttpApiV2ProxyRequest + { + Headers = new Dictionary + { + { "X-Forwarded-Proto", "https,http" }, + { "Host", "localhost:1234,myhost:432" }, + }, + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.target", string.Empty }, + { "http.scheme", "http" }, + { "net.host.name", "myhost" }, + { "net.host.port", 432 }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void SetHttpTagsFromResult_APIGatewayProxyResponse_SetsCorrectTags() + { + var response = new APIGatewayProxyResponse + { + StatusCode = 200, + }; + var activityProcessor = new Mock>(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddSource("TestActivitySource") + .Build(); + + using var testActivitySource = new ActivitySource("TestActivitySource"); + using var activity = testActivitySource.StartActivity("TestActivity"); + + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); + + var expectedTags = new Dictionary + { + { "http.status_code", 200 }, + }; + AssertTags(expectedTags, activity.TagObjects); + } + + [Fact] + public void SetHttpTagsFromResult_APIGatewayHttpApiV2ProxyResponse_SetsCorrectTags() + { + var response = new APIGatewayHttpApiV2ProxyResponse + { + StatusCode = 200, + }; + var activityProcessor = new Mock>(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddSource("TestActivitySource") + .Build(); + + using var testActivitySource = new ActivitySource("TestActivitySource"); + using var activity = testActivitySource.StartActivity("TestActivity"); + + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); + + var expectedTags = new Dictionary + { + { "http.status_code", 200 }, + }; + AssertTags(expectedTags, activity.TagObjects); + } + + [Theory] + [InlineData(null, null, null, null)] + [InlineData("", "", "", null)] + [InlineData(null, "localhost:4321", "localhost", 4321)] + [InlineData(null, "localhost:1a", "localhost", null)] + [InlineData(null, "localhost", "localhost", null)] + [InlineData("http", "localhost", "localhost", 80)] + [InlineData("https", "localhost", "localhost", 443)] + public void GetHostAndPort_HostHeader_ReturnsCorrectHostAndPort(string httpSchema, string hostHeader, string expectedHost, int? expectedPort) + { + (var host, var port) = AWSLambdaHttpUtils.GetHostAndPort(httpSchema, hostHeader); + + Assert.Equal(expectedHost, host); + Assert.Equal(expectedPort, port); + } + + [Theory] + [InlineData(null, "")] + [InlineData(new string[] { }, "")] + [InlineData(new[] { "value1" }, "?name=value1")] + [InlineData(new[] { "value$a" }, "?name=value%24a")] + [InlineData(new[] { "value 1" }, "?name=value+1")] + [InlineData(new[] { "value1", "value2" }, "?name=value1&name=value2")] + public void GetQueryString_APIGatewayProxyRequest_CorrectQueryString(IList values, string expectedQueryString) + { + var request = new APIGatewayProxyRequest(); + if (values != null) + { + request.MultiValueQueryStringParameters = new Dictionary> + { + { "name", values }, + }; + } + + var queryString = AWSLambdaHttpUtils.GetQueryString(request); + + Assert.Equal(expectedQueryString, queryString); + } + + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("name=value1", "?name=value1")] + [InlineData("sdckj9_+", "?sdckj9_+")] + public void GetQueryString_APIGatewayHttpApiV2ProxyRequest_CorrectQueryString(string rawQueryString, string expectedQueryString) + { + var request = new APIGatewayHttpApiV2ProxyRequest + { + RawQueryString = rawQueryString, + }; + + var queryString = AWSLambdaHttpUtils.GetQueryString(request); + + Assert.Equal(expectedQueryString, queryString); + } + + private static void AssertTags(IReadOnlyDictionary expectedTags, IEnumerable> actualTags) + where TActualValue : class + { + Assert.NotNull(actualTags); + Assert.Equal(expectedTags.Count, actualTags.Count()); + foreach (var tag in expectedTags) + { + Assert.Contains(new KeyValuePair(tag.Key, tag.Value as TActualValue), actualTags); + } + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs new file mode 100644 index 0000000000..7cecb57cb5 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Linq; +using OpenTelemetry.Instrumentation.AWSLambda.Implementation; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation +{ + public class CommonExtensionsTests + { + [Theory] + [InlineData("test")] + [InlineData(443)] + [InlineData(null)] + public void AddTagIfNotNull_Tag_CorrectTagsList(object tag) + { + var tags = new List>(); + + tags.AddTagIfNotNull("tagName", tag); + + if (tag != null) + { + Assert.Single(tags); + var actualTag = tags.First(); + Assert.Equal("tagName", actualTag.Key); + Assert.Equal(tag, actualTag.Value); + } + else + { + Assert.Empty(tags); + } + } + } +} From 46bad33f9f1ddbd1a6ff62b1257115e47da83821 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 7 Oct 2022 17:25:47 -0400 Subject: [PATCH 0361/1499] Exporter.Geneva - Refactor unit test (#616) --- .vscode/settings.json | 5 + .../LogSerializationTests.cs | 149 ++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..5c19a07622 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "fluentdData" + ] +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs new file mode 100644 index 0000000000..69cbf74d4a --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -0,0 +1,149 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Sockets; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class LogSerializationTests +{ + /* + Run from the current directory: + dotnet test -f net6.0 --filter FullyQualifiedName~LogSerializationTests -l "console;verbosity=detailed" + */ + private readonly ITestOutputHelper output; + + public LogSerializationTests(ITestOutputHelper output) + { + this.output = output; + } + + [Fact] + public void SerializationTestForException() + { + var exceptionMessage = "Exception Message"; + var exportedFields = GetExportedFieldsAfterLogging(logger => logger.Log( + logLevel: LogLevel.Information, + eventId: default, + state: null, + exception: new Exception(exceptionMessage), + formatter: null)); + + PrintFields(this.output, exportedFields); + var actualExceptionMessage = exportedFields["env_ex_msg"]; + Assert.Equal(exceptionMessage, actualExceptionMessage); + } + + private static void PrintFields(ITestOutputHelper output, Dictionary fields) + { + foreach (var field in fields) + { + output.WriteLine($"{field.Key}:{field.Value}"); + } + } + + private static Dictionary GetExportedFieldsAfterLogging(Action doLog) + { + Socket server = null; + string path = string.Empty; + try + { + var logRecordList = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter(typeof(GenevaLogExporterTests).FullName, LogLevel.Trace)); // Enable all LogLevels + + var logger = loggerFactory.CreateLogger(); + doLog(logger); + + Assert.Single(logRecordList); + var exporterOptions = new GenevaExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var exporter = new MsgPackLogExporter(exporterOptions); + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + + return GetFields(fluentdData); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + private static string GenerateTempFilePath() + { + while (true) + { + string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + if (!File.Exists(path)) + { + return path; + } + } + } + + private static Dictionary GetFields(object fluentdData) + { + /* Fluentd Forward Mode: + [ + "Log", + [ + [ , { "env_ver": "4.0", ... } ] + ], + { "TimeFormat": "DateTime" } + ] + */ + + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + return mapping; + } +} From b9e3d880b5e538e9925b9520e94bbb4349467d27 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 10 Oct 2022 13:58:57 -0700 Subject: [PATCH 0362/1499] [Instrumentation.Process] Implement threadSafe Refresh() (#664) --- .../MeterProviderBuilderExtensions.cs | 2 +- .../ProcessMetrics.cs | 48 ++++++++++++------- .../ProcessMetricsTests.cs | 47 ++++++++++++++++++ 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index 516945ebd1..223808b4a4 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -41,7 +41,7 @@ public static MeterProviderBuilder AddProcessInstrumentation( configure?.Invoke(options); var instrumentation = new ProcessMetrics(options); - builder.AddMeter(ProcessMetrics.MeterInstance.Name); + builder.AddMeter(instrumentation.MeterInstance.Name); return builder.AddInstrumentation(() => instrumentation); } } diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 563ff11452..f4e1c74283 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -20,42 +20,56 @@ namespace OpenTelemetry.Instrumentation.Process; -internal class ProcessMetrics +internal sealed class ProcessMetrics { internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); - internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); - private static readonly Diagnostics.Process CurrentProcess = Diagnostics.Process.GetCurrentProcess(); + internal readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); - static ProcessMetrics() + private readonly Diagnostics.Process currentProcess = Diagnostics.Process.GetCurrentProcess(); + private double? memoryUsage; + private double? virtualMemoryUsage; + + public ProcessMetrics(ProcessInstrumentationOptions options) { // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + this.MeterInstance.CreateObservableGauge( "process.memory.usage", () => { - CurrentProcess.Refresh(); - return CurrentProcess.WorkingSet64; + if (!this.memoryUsage.HasValue) + { + this.Snapshot(); + } + + var value = this.memoryUsage.Value; + this.memoryUsage = null; + return value; }, unit: "By", - description: "The amount of physical memory in use."); + description: "The amount of physical memory allocated for this process."); // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + this.MeterInstance.CreateObservableGauge( "process.memory.virtual", () => { - CurrentProcess.Refresh(); - return CurrentProcess.VirtualMemorySize64; + if (!this.virtualMemoryUsage.HasValue) + { + this.Snapshot(); + } + + var value = this.virtualMemoryUsage.Value; + this.virtualMemoryUsage = null; + return value; }, unit: "By", - description: "The amount of committed virtual memory."); + description: "The amount of virtual memory allocated for this process that cannot be shared with other processes."); } - /// - /// Initializes a new instance of the class. - /// - /// The options to define the metrics. - public ProcessMetrics(ProcessInstrumentationOptions options) + private void Snapshot() { + this.currentProcess.Refresh(); + this.memoryUsage = this.currentProcess.WorkingSet64; + this.virtualMemoryUsage = this.currentProcess.PrivateMemorySize64; } } diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index e227506a81..7adc9fa789 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -15,6 +15,7 @@ // using System.Collections.Generic; +using System.Diagnostics.Metrics; using System.Linq; using OpenTelemetry.Metrics; using Xunit; @@ -42,4 +43,50 @@ public void ProcessMetricsAreCaptured() var virtualMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetric); } + + [Fact] + public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName() + { + var exportedItemsA = new List(); + var exportedItemsB = new List(); + + using var meterProviderA = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItemsA) + .Build(); + + using var meterProviderB = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItemsB) + .Build(); + + meterProviderA.ForceFlush(MaxTimeToAllowForFlush); + meterProviderB.ForceFlush(MaxTimeToAllowForFlush); + + var metricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); + var metricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); + + Assert.True(GetValue(metricA) > 0); + Assert.True(GetValue(metricB) > 0); + } + + private static double GetValue(Metric metric) + { + Assert.NotNull(metric); + double sum = 0; + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + if (metric.MetricType.IsGauge()) + { + sum += metricPoint.GetGaugeLastValueDouble(); + } + else if (metric.MetricType.IsDouble()) + { + sum += metricPoint.GetSumDouble(); + } + } + + return sum; + } } From cbed25e801fb6aa7a60ecc73b16f4c9cfc044f92 Mon Sep 17 00:00:00 2001 From: Toni Wenzel Date: Tue, 11 Oct 2022 22:25:41 +0200 Subject: [PATCH 0363/1499] [Instrumentation.Process] Add CPU metrics (#678) --- .../ProcessMetrics.cs | 28 +++++++++++++ .../ProcessMetricsTests.cs | 41 ++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index f4e1c74283..30c9b2a7d8 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; using Diagnostics = System.Diagnostics; @@ -28,6 +29,8 @@ internal sealed class ProcessMetrics private readonly Diagnostics.Process currentProcess = Diagnostics.Process.GetCurrentProcess(); private double? memoryUsage; private double? virtualMemoryUsage; + private double? userProcessorTime; + private double? privilegedProcessorTime; public ProcessMetrics(ProcessInstrumentationOptions options) { @@ -64,6 +67,29 @@ public ProcessMetrics(ProcessInstrumentationOptions options) }, unit: "By", description: "The amount of virtual memory allocated for this process that cannot be shared with other processes."); + + this.MeterInstance.CreateObservableCounter( + "process.cpu.time", + () => + { + if (!this.userProcessorTime.HasValue || !this.privilegedProcessorTime.HasValue) + { + this.Snapshot(); + } + + var userProcessorTimeValue = this.userProcessorTime.Value; + var privilegedProcessorTimeValue = this.privilegedProcessorTime.Value; + this.userProcessorTime = null; + this.privilegedProcessorTime = null; + + return new[] + { + new Measurement(userProcessorTimeValue, new KeyValuePair("state", "user")), + new Measurement(privilegedProcessorTimeValue, new KeyValuePair("state", "system")), + }; + }, + unit: "s", + description: "Total CPU seconds broken down by different states."); } private void Snapshot() @@ -71,5 +97,7 @@ private void Snapshot() this.currentProcess.Refresh(); this.memoryUsage = this.currentProcess.WorkingSet64; this.virtualMemoryUsage = this.currentProcess.PrivateMemorySize64; + this.userProcessorTime = this.currentProcess.UserProcessorTime.TotalSeconds; + this.privilegedProcessorTime = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; } } diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 7adc9fa789..82631a34ab 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -37,11 +37,50 @@ public void ProcessMetricsAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count == 2); + Assert.True(exportedItems.Count == 3); var physicalMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetric); var virtualMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetric); + var cpuTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.time"); + Assert.NotNull(cpuTimeMetric); + } + + [Fact] + public void CpuTimeMetricsAreCaptured() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var cpuTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.time"); + Assert.NotNull(cpuTimeMetric); + + var userTimeCaptured = false; + var systemTimeCaptured = false; + + var points = cpuTimeMetric.GetMetricPoints().GetEnumerator(); + while (points.MoveNext() && (!userTimeCaptured || !systemTimeCaptured)) + { + foreach (var tag in points.Current.Tags) + { + if (tag.Key == "state" && tag.Value.ToString() == "user") + { + userTimeCaptured = true; + } + else if (tag.Key == "state" && tag.Value.ToString() == "system") + { + systemTimeCaptured = true; + } + } + } + + Assert.True(userTimeCaptured); + Assert.True(systemTimeCaptured); } [Fact] From 35160280aacd1bf0156842d9497963aa681afaf4 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 12 Oct 2022 21:22:47 -0400 Subject: [PATCH 0364/1499] Fix incorrect readme content (#689) --- src/OpenTelemetry.Instrumentation.Runtime/README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 4987f4ac91..f2b465b82e 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -96,9 +96,6 @@ to all the `ObservableGauge` below. Note: This metric is only available when targeting .NET6 or later. -Note: `gc.heap.fragmentation.size` metrics is removed for .NET 6 because of a -[bug](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496). - | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-----------------|------------|------------------|------------------| | `bytes` | ObservableGauge | `Int64` | No Attributes | N/A | @@ -135,7 +132,7 @@ The API used to retrieve the value is: The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred. -Note: This metric is only available when targeting .NET6 or later. +Note: This metric is only available when targeting .NET 7 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-----------------|------------|------------------|----------------------------| From 7fb378deb11143891b4b944a4e5497b376c2899a Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 12 Oct 2022 20:02:18 -0700 Subject: [PATCH 0365/1499] Fix github workflow (#690) Co-authored-by: Cijo Thomas --- .github/workflows/windows-ci-md.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows-ci-md.yml b/.github/workflows/windows-ci-md.yml index 02c643050a..2e2bfd561a 100644 --- a/.github/workflows/windows-ci-md.yml +++ b/.github/workflows/windows-ci-md.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - version: [net461,netcoreapp3.1,net6.0] + version: [net462,netcoreapp3.1,net6.0] steps: - run: 'echo "No build required"' From a0aa56c26c5cfcc39fc6973a45d64601e766aa83 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 13 Oct 2022 15:09:58 -0700 Subject: [PATCH 0366/1499] [Instrumentation.EventCounters] Stabilize and Enable Testing (#620) --- .github/component_owners.yml | 2 + .../CHANGELOG.md | 6 + .../EventCounterListener.cs | 189 -------------- .../EventCounterMetricsOptions.cs | 28 --- ...EventCountersInstrumentationEventSource.cs | 30 ++- .../EventCountersInstrumentationOptions.cs | 59 +++++ .../EventCountersMetrics.cs | 137 +++++++++++ .../MeterProviderBuilderExtensions.cs | 10 +- .../README.md | 80 +++--- .../EventCounterListenerTests.cs | 199 --------------- .../EventCountersMetricsTests.cs | 232 ++++++++++++++++++ .../MeterProviderBuilderExtensionsTests.cs | 33 --- .../TestEventCounter.cs | 44 ---- .../TestIncrementingEventCounter.cs | 39 --- .../TestIncrementingPollingCounter.cs | 36 --- .../TestPollingEventCounter.cs | 36 --- 16 files changed, 501 insertions(+), 659 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs delete mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs delete mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs delete mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs delete mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs delete mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs delete mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs delete mode 100644 test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 57fe851901..8bec8de3df 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -37,6 +37,7 @@ components: - ejsmith src/OpenTelemetry.Instrumentation.EventCounters/: - hananiel + - mic-max src/OpenTelemetry.Instrumentation.GrpcCore/: - pcwiese src/OpenTelemetry.Instrumentation.Hangfire/: @@ -99,6 +100,7 @@ components: - ejsmith test/OpenTelemetry.Instrumentation.EventCounters.Tests/: - hananiel + - mic-max test/OpenTelemetry.Instrumentation.GrpcCore.Tests/: - pcwiese test/OpenTelemetry.Instrumentation.Hangfire.Tests/: diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 85f97c807a..165812f4e6 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +* Simplified implementation. EventSources must be explicitly configured to be + listened to now. + ([#620](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/620)) + ## 0.1.0-alpha.1 Released 2022-Jul-12 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs deleted file mode 100644 index b8ee562d94..0000000000 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterListener.cs +++ /dev/null @@ -1,189 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics.Metrics; -using System.Diagnostics.Tracing; -using System.Reflection; - -namespace OpenTelemetry.Instrumentation.EventCounters; - -internal class EventCounterListener : EventListener -{ - internal static readonly AssemblyName AssemblyName = typeof(EventCounterListener).Assembly.GetName(); - internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); - - private readonly bool isInitialized = false; - private readonly Meter meter; - private readonly EventCounterMetricsOptions options; - private readonly ConcurrentDictionary metricInstruments = new(); - private readonly ConcurrentDictionary lastValue = new(); - private readonly ConcurrentBag eventSources = new(); - - public EventCounterListener(EventCounterMetricsOptions options) - { - this.meter = new Meter(InstrumentationName, InstrumentationVersion); - this.options = options ?? throw new ArgumentNullException(nameof(options)); - - this.isInitialized = true; - this.EnablePendingEventSources(); // Some OnEventSourceCreated may have fired before constructor, enable them - } - - private enum InstrumentType - { - ObservableGauge, - ObservableCounter, - } - - private Dictionary EnableEventArgs => new() { ["EventCounterIntervalSec"] = this.options.RefreshIntervalSecs.ToString(), }; - - protected override void OnEventSourceCreated(EventSource source) - { - // TODO: Add Configuration options to selectively subscribe to EventCounters - try - { - if (!this.isInitialized) - { - this.eventSources.Add(source); - } - else - { - this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); - } - } - catch (Exception ex) - { - EventCountersInstrumentationEventSource.Log.ErrorEventCounter(source.Name, ex.Message); - } - } - - protected override void OnEventWritten(EventWrittenEventArgs eventData) - { - if (!eventData.EventName.Equals("EventCounters") || !this.isInitialized) - { - return; - } - - try - { - if (eventData.Payload.Count > 0 && eventData.Payload[0] is IDictionary eventPayload) - { - this.ExtractAndPostMetric(eventData.EventSource.Name, eventPayload); - } - else - { - EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenAsEventPayloadNotParseable(eventData.EventSource.Name); - } - } - catch (Exception ex) - { - EventCountersInstrumentationEventSource.Log.ErrorEventCounter(eventData.EventName, ex.ToString()); - } - } - - private void ExtractAndPostMetric(string eventSourceName, IDictionary eventPayload) - { - try - { - bool calculateRate = false; - double actualValue = 0; - - string counterName = string.Empty; - string counterDisplayName = string.Empty; - InstrumentType instrumentType = InstrumentType.ObservableGauge; - - foreach (KeyValuePair payload in eventPayload) - { - var key = payload.Key; - if (key.Equals("Name", StringComparison.OrdinalIgnoreCase)) - { - counterName = payload.Value.ToString(); - } - else - if (key.Equals("DisplayName", StringComparison.OrdinalIgnoreCase)) - { - counterDisplayName = payload.Value.ToString(); - } - else if (key.Equals("Mean", StringComparison.OrdinalIgnoreCase)) - { - instrumentType = InstrumentType.ObservableGauge; - actualValue = Convert.ToDouble(payload.Value); - } - else if (key.Equals("Increment", StringComparison.OrdinalIgnoreCase)) - { - // Increment indicates we have to calculate rate. - instrumentType = InstrumentType.ObservableCounter; - calculateRate = true; - actualValue = Convert.ToDouble(payload.Value); - } - } - - this.RecordMetric(eventSourceName, counterName, counterDisplayName, instrumentType, actualValue, calculateRate); - } - catch (Exception ex) - { - EventCountersInstrumentationEventSource.Log.EventCountersInstrumentationWarning("ExtractMetric", ex.Message); - } - } - - private void RecordMetric(string eventSourceName, string counterName, string displayName, InstrumentType instrumentType, double value, bool calculateRate) - { - var metricKey = new MetricKey(eventSourceName, counterName); - var description = string.IsNullOrEmpty(displayName) ? counterName : displayName; - this.lastValue[metricKey] = calculateRate ? value / this.options.RefreshIntervalSecs : value; - switch (instrumentType) - { - case InstrumentType.ObservableCounter: - this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableCounter(counterName, () => this.ObserveDouble(metricKey), description: description)); - break; - - case InstrumentType.ObservableGauge: - this.metricInstruments.TryAdd(metricKey, this.meter.CreateObservableGauge(counterName, () => this.ObserveDouble(metricKey), description: description)); - break; - } - } - - private double ObserveDouble(MetricKey key) => this.lastValue[key]; - - private void EnablePendingEventSources() - { - foreach (var source in this.eventSources) - { - this.EnableEvents(source, EventLevel.Verbose, EventKeywords.All, this.EnableEventArgs); - } - } - - private class MetricKey - { - public MetricKey(string eventSourceName, string counterName) - { - this.EventSourceName = eventSourceName; - this.CounterName = counterName; - } - - public string EventSourceName { get; private set; } - - public string CounterName { get; private set; } - - public override int GetHashCode() => (this.EventSourceName, this.CounterName).GetHashCode(); - - public override bool Equals(object obj) => - obj is MetricKey nextKey && this.EventSourceName == nextKey.EventSourceName && this.CounterName == nextKey.CounterName; - } -} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs deleted file mode 100644 index 0152da017e..0000000000 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCounterMetricsOptions.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Instrumentation.EventCounters; - -/// -/// EventCounterMetrics Options. -/// -public class EventCounterMetricsOptions -{ - /// - /// Gets or sets the subscription interval in seconds. - /// - public int RefreshIntervalSecs { get; set; } = 60; -} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs index f3d0d431ce..071f963352 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs @@ -22,25 +22,37 @@ namespace OpenTelemetry.Instrumentation.EventCounters; /// EventSource events emitted from the project. /// [EventSource(Name = "OpenTelemetry-Instrumentation-EventCounters")] -internal class EventCountersInstrumentationEventSource : EventSource +internal sealed class EventCountersInstrumentationEventSource : EventSource { public static readonly EventCountersInstrumentationEventSource Log = new(); - [Event(1, Message = "Error occurred while processing eventCounter, EventCounter: {0}, Exception: {2}", Level = EventLevel.Error)] - public void ErrorEventCounter(string counterName, string exception) + [Event(1, Level = EventLevel.Warning, Message = "Error while writing event from source: {0} - {1}.")] + internal void ErrorWhileWritingEvent(string eventSourceName, string exceptionMessage) { - this.WriteEvent(1, counterName, exception); + this.WriteEvent(1, eventSourceName, exceptionMessage); } - [Event(2, Level = EventLevel.Warning, Message = @"Ignoring event written from EventSource: {0} as payload is not IDictionary to extract metrics.")] - public void IgnoreEventWrittenAsEventPayloadNotParseable(string eventSourceName) + [Event(2, Level = EventLevel.Warning, Message = "Event data payload not parseable from source: {0}.")] + internal void IgnoreEventWrittenEventArgsPayloadNotParseable(string eventSourceName) + { + this.WriteEvent(2, eventSourceName); + } + + [Event(3, Level = EventLevel.Warning, Message = "Event data has no name from source: {0}.")] + internal void IgnoreEventWrittenEventArgsWithoutName(string eventSourceName) + { + this.WriteEvent(3, eventSourceName); + } + + [Event(4, Level = EventLevel.Warning, Message = "Event data payload problem with values of Mean, Increment from source: {0}.")] + internal void IgnoreMeanIncrementConflict(string eventSourceName) { this.WriteEvent(4, eventSourceName); } - [Event(3, Level = EventLevel.Warning, Message = @"EventCountersInstrumentation - {0} failed with exception: {1}.")] - public void EventCountersInstrumentationWarning(string stage, string exceptionMessage) + [Event(5, Level = EventLevel.Warning, Message = "Event data has name other than 'EventCounters' from source: {0}.")] + internal void IgnoreNonEventCountersName(string eventSourceName) { - this.WriteEvent(8, stage, exceptionMessage); + this.WriteEvent(5, eventSourceName); } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs new file mode 100644 index 0000000000..87e1a93e75 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs @@ -0,0 +1,59 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenTelemetry.Instrumentation.EventCounters; + +/// +/// EventCounterListener Options. +/// +public class EventCountersInstrumentationOptions +{ + private readonly HashSet eventSourceNames = new(); + + /// + /// Gets or sets the subscription interval in seconds for reading values + /// from the configured EventCounters. + /// + public int RefreshIntervalSecs { get; set; } = 1; + + /// + /// Listens to EventCounters from the given EventSource name. + /// + /// The EventSource names to listen to. + public void AddEventSources(params string[] names) + { + if (names.Contains("System.Runtime")) + { + throw new NotSupportedException("Use the `OpenTelemetry.Instrumentation.Runtime` or `OpenTelemetry.Instrumentation.Process` instrumentations."); + } + + this.eventSourceNames.UnionWith(names); + } + + /// + /// Returns whether or not an EventSource should be enabled on the EventListener. + /// + /// The EventSource name. + /// true when an EventSource with the name should be enabled. + internal bool ShouldListenToSource(string eventSourceName) + { + return this.eventSourceNames.Contains(eventSourceName); + } +} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs new file mode 100644 index 0000000000..e01ce8b968 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -0,0 +1,137 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics.Metrics; +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Instrumentation.EventCounters; + +/// +/// .NET EventCounters Instrumentation. +/// +internal sealed class EventCountersMetrics : EventListener +{ + internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, typeof(EventCountersMetrics).Assembly.GetName().Version.ToString()); + + private readonly EventCountersInstrumentationOptions options; + private readonly ConcurrentQueue preInitEventSources = new(); + private readonly ConcurrentDictionary<(string, string), Instrument> instruments = new(); + private readonly ConcurrentDictionary<(string, string), double> values = new(); + + /// + /// Initializes a new instance of the class. + /// + /// The options to define the metrics. + public EventCountersMetrics(EventCountersInstrumentationOptions options) + { + this.options = options; + + while (this.preInitEventSources.TryDequeue(out EventSource eventSource)) + { + if (this.options.ShouldListenToSource(eventSource.Name)) + { + this.EnableEvents(eventSource, EventLevel.LogAlways, EventKeywords.None, GetEnableEventsArguments(this.options)); + } + } + } + + /// + protected override void OnEventSourceCreated(EventSource source) + { + if (this.options == null) + { + this.preInitEventSources.Enqueue(source); + } + else if (this.options.ShouldListenToSource(source.Name)) + { + this.EnableEvents(source, EventLevel.LogAlways, EventKeywords.None, GetEnableEventsArguments(this.options)); + } + } + + /// + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + if (this.options == null) + { + return; + } + + var eventSourceName = eventData.EventSource.Name; + + if (eventData.EventName != "EventCounters") + { + EventCountersInstrumentationEventSource.Log.IgnoreNonEventCountersName(eventSourceName); + return; + } + + if (eventData.Payload == null || eventData.Payload.Count == 0 || eventData.Payload[0] is not IDictionary payload) + { + EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenEventArgsPayloadNotParseable(eventSourceName); + return; + } + + var hasName = payload.TryGetValue("Name", out var nameObj); + + if (!hasName) + { + EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenEventArgsWithoutName(eventSourceName); + return; + } + + var name = nameObj.ToString(); + + var hasMean = payload.TryGetValue("Mean", out var mean); + var hasIncrement = payload.TryGetValue("Increment", out var increment); + + if (!(hasIncrement ^ hasMean)) + { + EventCountersInstrumentationEventSource.Log.IgnoreMeanIncrementConflict(eventSourceName); + return; + } + + var value = Convert.ToDouble(hasMean ? mean : increment); + this.UpdateInstrumentWithEvent(hasMean, eventSourceName, name, value); + } + + private static Dictionary GetEnableEventsArguments(EventCountersInstrumentationOptions options) => + new() { { "EventCounterIntervalSec", options.RefreshIntervalSecs.ToString() } }; + + private void UpdateInstrumentWithEvent(bool isGauge, string eventSourceName, string name, double value) + { + try + { + ValueTuple metricKey = new(eventSourceName, name); + _ = this.values.AddOrUpdate(metricKey, value, isGauge ? (_, _) => value : (_, existing) => existing + value); + + var instrumentName = $"EventCounters.{eventSourceName}.{name}"; + + if (!this.instruments.ContainsKey(metricKey)) + { + Instrument instrument = isGauge + ? MeterInstance.CreateObservableGauge(instrumentName, () => this.values[metricKey]) + : MeterInstance.CreateObservableCounter(instrumentName, () => this.values[metricKey]); + _ = this.instruments.TryAdd(metricKey, instrument); + } + } + catch (Exception ex) + { + EventCountersInstrumentationEventSource.Log.ErrorWhileWritingEvent(eventSourceName, ex.Message); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index bb13a85281..daf35c18ef 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -31,17 +31,17 @@ public static class MeterProviderBuilderExtensions /// being configured. /// Runtime metrics options. /// The instance of to chain the calls. - public static MeterProviderBuilder AddEventCounterMetrics( + public static MeterProviderBuilder AddEventCountersInstrumentation( this MeterProviderBuilder builder, - Action configure = null) + Action configure = null) { Guard.ThrowIfNull(builder); - var options = new EventCounterMetricsOptions(); + var options = new EventCountersInstrumentationOptions(); configure?.Invoke(options); - var instrumentation = new EventCounterListener(options); - builder.AddMeter(EventCounterListener.InstrumentationName); + var instrumentation = new EventCountersMetrics(options); + builder.AddMeter(EventCountersMetrics.MeterInstance.Name); return builder.AddInstrumentation(() => instrumentation); } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index 7ddad17e82..059f79cc32 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -1,7 +1,11 @@ -# Event counter instrumentation for OpenTelemetry +# Event Counters Instrumentation for OpenTelemetry .NET -This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), -which republishes EventCounters using Metrics Api. +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EventCounters.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) + +This is an +[Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) +, which **republishes EventCounters using Metrics Api.** ## Steps to enable OpenTelemetry.Instrumentation.EventCounters @@ -9,62 +13,56 @@ which republishes EventCounters using Metrics Api. Add a reference to the [`OpenTelemetry.Instrumentation.EventCounters`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) -package. Also, add any other instrumentation & exporters you will need. +package. ```shell dotnet add package OpenTelemetry.Instrumentation.EventCounters ``` -### Step 2: Enable EventCounters Instrumentation at application startup - -EventCounters instrumentation must be enabled at application startup. +### Step 2: Enable EventCounters Instrumentation -The following example demonstrates adding EventCounter events to a -console application. This example also sets up the OpenTelemetry Console -exporter, which requires adding the package -[`OpenTelemetry.Exporter.Console`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Console) -to the application. +EventCounters instrumentation should be enabled at application startup using the +`AddEventCountersInstrumentation` extension on the `MeterProviderBuilder`: ```csharp -using OpenTelemetry; -using OpenTelemetry.Metrics; - -namespace DotnetMetrics; - -public class Program -{ - public static void Main(string[] args) - { - using var meterprovider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 5; - }) - .AddConsoleExporter() - .Build(); - } +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => { + options.RefreshIntervalSecs = 1; + options.Sources.Add("MyEventSourceName"); + }) + .AddPrometheusExporter() + .Build(); } ``` -Console Output: - -```console +Additionally, this examples sets up the OpenTelemetry Prometheus exporter, which +requires adding the package +[`OpenTelemetry.Exporter.Prometheus`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +to the application. -Export cpu-usage, CPU Usage, Meter: OpenTelemetry.Instrumentation.EventCounters/0.0.0.0 -(2022-07-12T16:40:37.2639447Z, 2022-07-12T16:40:42.2533747Z] DoubleGauge -Value: 0 +### Step 3: Create EventCounters -Export working-set, Working Set, Meter: OpenTelemetry.Instrumentation.EventCounters/0.0.0.0 -(2022-07-12T16:40:37.2666398Z, 2022-07-12T16:40:42.2534452Z] DoubleGauge -Value: 38 +Learn about +[EventCounters in .NET](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/event-counters) +. -Export gc-heap-size, GC Heap Size, Meter: OpenTelemetry.Instrumentation.EventCounters/0.0.0.0 -(2022-07-12T16:40:37.2667389Z, 2022-07-12T16:40:42.2534456Z] DoubleGauge -Value: 7 +```csharp +EventSource eventSource = new("MyEventSource"); +EventCounter eventCounter = new("MyEventCounterName", eventSource); +eventCounter.WriteMetric(0); +eventCounter.WriteMetric(1000); +PollingCounter pollingCounter = new("MyPollingCounterName", eventSource, () => new Random().NextDouble()); ``` +## Notes + +The metrics will only be available after `EventCounterIntervalSec` seconds. +Before that nothing will be exported, if anything is present at the Prometheus +metrics endpoint it is from a prior execution. This is more evident when using +longer polling intervals. + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs deleted file mode 100644 index eab325222c..0000000000 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCounterListenerTests.cs +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; -using System.Threading.Tasks; -using OpenTelemetry.Metrics; -using Xunit; - -namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - -public class EventCounterListenerTests -{ - private const int MaxTimeToAllowForFlush = 10000; - private MeterProvider meterProvider; - - [Fact] - public async Task SystemMetricsAreCaptured() - { - var metricItems = new List(); - - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 1; - }) - .AddInMemoryExporter(metricItems) - .Build(); - - await Task.Delay(2000); - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - Assert.True(metricItems.Count > 1); - } - - [Fact(Skip = "Unstable")] - public async Task TestEventCounterMetricsAreCaptured() - { - const int refreshIntervalSeconds = 1; - var metricItems = new List(); - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 1; - }) - .AddInMemoryExporter(metricItems) - .Build(); - var expected = new[] { 100.3F, 200.1F }; - TestEventCounter.Log.SampleCounter1(expected[0]); - TestEventCounter.Log.SampleCounter2(expected[1]); - - // Wait a little bit over the refresh interval seconds - await Task.Delay((refreshIntervalSeconds * 1000) + 300); - - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - var counter1 = metricItems.Find(m => m.Name == "mycountername1"); - var counter2 = metricItems.Find(m => m.Name == "mycountername2"); - Assert.NotNull(counter1); - Assert.NotNull(counter2); - Assert.Equal(MetricType.DoubleGauge, counter1.MetricType); // EventCounter CounterType is `Mean` - - Assert.Equal(expected[0], GetActualValue(counter1)); - Assert.Equal(expected[1], GetActualValue(counter2)); - } - - [Fact(Skip = "Unstable")] - public async Task TestIncrementingEventCounterMetricsAreCaptured() - { - const int refreshIntervalSeconds = 1; - var metricItems = new List(); - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = 1; - }) - .AddInMemoryExporter(metricItems) - .Build(); - - TestIncrementingEventCounter.Log.SampleCounter1(1); - TestIncrementingEventCounter.Log.SampleCounter1(1); - TestIncrementingEventCounter.Log.SampleCounter1(1); - - // Wait a little bit over the refresh interval seconds - await Task.Delay((refreshIntervalSeconds * 1000) + 300); - - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - var counter = metricItems.Find(m => m.Name == TestIncrementingEventCounter.CounterName); - Assert.NotNull(counter); - Assert.Equal(MetricType.DoubleSum, counter.MetricType); // EventCounter CounterType is `Sum` - Assert.Equal(3, GetActualValue(counter)); - } - - [Fact(Skip = "Unstable")] - public async Task TestPollingCounterMetricsAreCaptured() - { - var metricItems = new List(); - const int refreshIntervalSeconds = 1; - - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = refreshIntervalSeconds; - }) - .AddInMemoryExporter(metricItems) - .Build(); - - int i = 0; - TestPollingEventCounter.CreateSingleton(() => ++i * 10); - - var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice - await Task.Delay(duration); - - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - var pollingCounter = metricItems.Find(m => m.Name == TestPollingEventCounter.CounterName); - Assert.NotNull(pollingCounter); - Assert.Equal(MetricType.DoubleGauge, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Mean` - - var expected = i * 10; // The last recorded `Mean` value - Assert.Equal(expected, GetActualValue(pollingCounter)); - } - - [Fact(Skip = "Unstable")] - public async Task TestIncrementingPollingCounterMetrics() - { - var metricItems = new List(); - const int refreshIntervalSeconds = 1; - - this.meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCounterMetrics(options => - { - options.RefreshIntervalSecs = refreshIntervalSeconds; - }) - .AddInMemoryExporter(metricItems) - .Build(); - - int i = 1; - - TestIncrementingPollingCounter.CreateSingleton(() => i++); - - var duration = (refreshIntervalSeconds * 2 * 1000) + 300; // Wait for two refresh intervals to call the valueProvider twice - await Task.Delay(duration); - - this.meterProvider.ForceFlush(MaxTimeToAllowForFlush); - - this.meterProvider.Dispose(); - - var pollingCounter = metricItems.Find(m => m.Name == TestIncrementingPollingCounter.CounterName); - Assert.NotNull(pollingCounter); - Assert.Equal(MetricType.DoubleSum, pollingCounter.MetricType); // Polling Counter is EventCounter CounterType of `Sum` - - Assert.Equal(1, GetActualValue(pollingCounter)); - } - - /// - /// Event Counters are always Sum or Mean and are always record with `float`. - /// - /// Metric to Aggregate. - /// The Aggregated value. - private static double GetActualValue(Metric metric) - { - double sum = 0; - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) - { - if (metric.MetricType.IsSum()) - { - sum += metricPoint.GetSumDouble(); - } - else - { - sum += metricPoint.GetGaugeLastValueDouble(); - } - } - - return sum; - } -} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs new file mode 100644 index 0000000000..748e849ed5 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -0,0 +1,232 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.Tracing; +using System.Threading.Tasks; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Instrumentation.EventCounters.Tests; + +public class EventCountersMetricsTests +{ + private const int Delay = 1200; + + [Fact(Skip = "Other tests metrics are being exported here")] + public async Task NoMetricsByDefault() + { + // Arrange + List metricItems = new(); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation() + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + await Task.Delay(Delay); + meterProvider.ForceFlush(); + + // Assert + Assert.Empty(metricItems); + } + + [Fact] + public async Task EventCounter() + { + // Arrange + List metricItems = new(); + EventSource source = new("a"); + EventCounter counter = new("c", source); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + counter.WriteMetric(1997.0202); + await Task.Delay(Delay); + meterProvider.ForceFlush(); + + // Assert + var metric = metricItems.Find(x => x.Name == "EventCounters.a.c"); + Assert.NotNull(metric); + Assert.Equal(MetricType.DoubleGauge, metric.MetricType); + Assert.Equal(1997.0202, GetActualValue(metric)); + } + + [Fact] + public async Task IncrementingEventCounter() + { + // Arrange + List metricItems = new(); + EventSource source = new("b"); + IncrementingEventCounter incCounter = new("inc-c", source); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + incCounter.Increment(1); + incCounter.Increment(1); + incCounter.Increment(1); + await Task.Delay(Delay); + meterProvider.ForceFlush(); + + // Assert + var metric = metricItems.Find(x => x.Name == "EventCounters.b.inc-c"); + Assert.NotNull(metric); + Assert.Equal(MetricType.DoubleSum, metric.MetricType); + Assert.Equal(3, GetActualValue(metric)); + } + + [Fact] + public async Task PollingCounter() + { + // Arrange + int i = 0; + List metricItems = new(); + EventSource source = new("c"); + PollingCounter pollCounter = new("poll-c", source, () => ++i * 10); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + await Task.Delay(Delay * 2); + meterProvider.ForceFlush(); + + // Assert + var metric = metricItems.Find(x => x.Name == "EventCounters.c.poll-c"); + Assert.NotNull(metric); + Assert.Equal(MetricType.DoubleGauge, metric.MetricType); + Assert.Equal(20, GetActualValue(metric)); + } + + [Fact] + public async Task IncrementingPollingCounter() + { + // Arrange + int i = 1; + List metricItems = new(); + EventSource source = new("d"); + IncrementingPollingCounter incPollCounter = new("inc-poll-c", source, () => i++); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + await Task.Delay(Delay * 2); + meterProvider.ForceFlush(); + + // Assert + var metric = metricItems.Find(x => x.Name == "EventCounters.d.inc-poll-c"); + Assert.NotNull(metric); + Assert.Equal(MetricType.DoubleSum, metric.MetricType); + Assert.Equal(2, GetActualValue(metric)); + } + + [Fact] + public async Task EventCounterSameNameUsesNewestCreated() + { + // Arrange + List metricItems = new(); + EventSource source = new("a"); + EventCounter counter = new("c", source); + EventCounter counter2 = new("c", source); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + counter2.WriteMetric(1980.1208); + counter.WriteMetric(1997.0202); + await Task.Delay(Delay); + meterProvider.ForceFlush(); + + // Assert + var metric = metricItems.Find(x => x.Name == "EventCounters.a.c"); + Assert.NotNull(metric); + Assert.Equal(MetricType.DoubleGauge, metric.MetricType); + + // Since `counter2` was created after `counter` it is exported + Assert.Equal(1980.1208, GetActualValue(metric)); + } + + [Fact] + public void ThrowExceptionWhenBuilderIsNull() + { + MeterProviderBuilder builder = null; + Assert.Throws(() => builder.AddEventCountersInstrumentation()); + } + + [Fact] + public void ThrowExceptionForUnsupportedEventSources() + { + var ex = Assert.Throws(() => + { + Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources("System.Runtime"); + }); + }); + + Assert.Equal("Use the `OpenTelemetry.Instrumentation.Runtime` or `OpenTelemetry.Instrumentation.Process` instrumentations.", ex.Message); + } + + // polling and eventcounter with same instrument name? + + private static double GetActualValue(Metric metric) + { + double sum = 0; + + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + sum += metric.MetricType.IsSum() + ? metricPoint.GetSumDouble() + : metricPoint.GetGaugeLastValueDouble(); + } + + return sum; + } +} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs deleted file mode 100644 index 22020300ed..0000000000 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/MeterProviderBuilderExtensionsTests.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using OpenTelemetry.Metrics; -using Xunit; - -namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - -public class MeterProviderBuilderExtensionsTests -{ - [Fact] - public void Throws_Exception_When_Builder_Is_Null() - { - MeterProviderBuilder builder = null; - - Func action = () => builder.AddEventCounterMetrics(); - Assert.Throws(action); - } -} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs deleted file mode 100644 index eeaac2b030..0000000000 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestEventCounter.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics.Tracing; - -namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - -[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestEventCounter")] -public sealed class TestEventCounter : EventSource -{ - // define the singleton instance of the event source - public static TestEventCounter Log = new TestEventCounter(); - private EventCounter testCounter1; - private EventCounter testCounter2; - - private TestEventCounter() - { - this.testCounter1 = new EventCounter("mycountername1", this); - this.testCounter2 = new EventCounter("mycountername2", this); - } - - public void SampleCounter1(float counterValue) - { - this.testCounter1.WriteMetric(counterValue); - } - - public void SampleCounter2(float counterValue) - { - this.testCounter2.WriteMetric(counterValue); - } -} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs deleted file mode 100644 index 5cd33ba0bd..0000000000 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingEventCounter.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics.Tracing; - -namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - -[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestIncrementingEventCounter")] -public sealed class TestIncrementingEventCounter : EventSource -{ - public const string CounterName = "IncrementingEventCounter"; - - // define the singleton instance of the event source - public static TestIncrementingEventCounter Log = new(); - private IncrementingEventCounter incrementingEventCounter; - - private TestIncrementingEventCounter() - { - this.incrementingEventCounter = new IncrementingEventCounter(CounterName, this); - } - - public void SampleCounter1(float counterValue) - { - this.incrementingEventCounter.Increment(counterValue); - } -} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs deleted file mode 100644 index a60077519e..0000000000 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestIncrementingPollingCounter.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Diagnostics.Tracing; - -namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - -[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingIncrementingEventCounter")] -public sealed class TestIncrementingPollingCounter : EventSource -{ - public const string CounterName = "TestIncrementingPollingCounter"; - - private IncrementingPollingCounter incrementingPollingCounter; - - private TestIncrementingPollingCounter(Func provider) - { - this.incrementingPollingCounter = new IncrementingPollingCounter(CounterName, this, provider); - } - - // define the singleton instance of the event source - public static TestIncrementingPollingCounter CreateSingleton(Func provider) => new(provider); -} diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs deleted file mode 100644 index 12c9102e47..0000000000 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/TestPollingEventCounter.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Diagnostics.Tracing; - -namespace OpenTelemetry.Instrumentation.EventCounters.Tests; - -[EventSource(Name = "OpenTelemetry.Instrumentation.EventCounters.Tests.TestPollingEventCounter")] -public sealed class TestPollingEventCounter : EventSource -{ - public const string CounterName = "TestPollingCounter"; - - private PollingCounter pollingCounter; - - private TestPollingEventCounter(Func provider) - { - this.pollingCounter = new PollingCounter(CounterName, this, provider); - } - - // define the singleton instance of the event source - public static TestPollingEventCounter CreateSingleton(Func provider) => new(provider); -} From d015eb3087c660f26cb36f421dbc749678277cbe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Oct 2022 17:20:56 -0700 Subject: [PATCH 0367/1499] Bump actions/setup-dotnet from 3.0.1 to 3.0.2 (#695) Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v3.0.1...v3.0.2) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dotnet-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index ba4d12353f..fc56e1dadd 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v3.0.1 + uses: actions/setup-dotnet@v3.0.2 with: dotnet-version: 6.0.x From fc969be46ef2a2ea10bd845d995743151377dd9b Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 14 Oct 2022 15:38:48 -0400 Subject: [PATCH 0368/1499] Switch to new Prometheus exporter in runtime example: (#697) --- examples/runtime-instrumentation/Program.cs | 6 +----- .../runtime-instrumentation/runtime-instrumentation.csproj | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index b4bdd9fc56..9131aa652c 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -23,11 +23,7 @@ public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddRuntimeInstrumentation() - .AddPrometheusExporter(options => - { - options.StartHttpListener = true; - options.ScrapeResponseCacheDurationMilliseconds = 0; - }) + .AddPrometheusHttpListener() .Build(); // Most of the process.runtime.dotnet.gc.* metrics are only available after the GC finished at least one collection. diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index eb026e5dca..3531e02f48 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + From eeca089f3c21e92de05a2ade0089b61f5f3b86c0 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 14 Oct 2022 13:56:33 -0700 Subject: [PATCH 0369/1499] [Instrumentation.Process] Added 2 instruments: CPU Utilization and threads (#687) --- .../ProcessMetrics.cs | 106 ++++++++++++++---- .../ProcessMetricsTests.cs | 44 +++++++- 2 files changed, 127 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 30c9b2a7d8..cd4e743149 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; @@ -27,25 +28,36 @@ internal sealed class ProcessMetrics internal readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); private readonly Diagnostics.Process currentProcess = Diagnostics.Process.GetCurrentProcess(); - private double? memoryUsage; - private double? virtualMemoryUsage; - private double? userProcessorTime; - private double? privilegedProcessorTime; + private double? memoryUsageBytes; + private double? virtualMemoryUsageBytes; + private double? userProcessorTimeSeconds; + private double? privilegedProcessorTimeSeconds; + private int? numberOfThreads; + private IEnumerable> cpuUtilization; + + // vars for calculating CPU utilization + private DateTime lastCollectionTimeUtc; + private double lastCollectedUserProcessorTime; + private double lastCollectedPrivilegedProcessorTime; public ProcessMetrics(ProcessInstrumentationOptions options) { + this.lastCollectionTimeUtc = DateTime.UtcNow; + this.lastCollectedUserProcessorTime = this.currentProcess.UserProcessorTime.TotalSeconds; + this.lastCollectedPrivilegedProcessorTime = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; + // TODO: change to ObservableUpDownCounter this.MeterInstance.CreateObservableGauge( "process.memory.usage", () => { - if (!this.memoryUsage.HasValue) + if (!this.memoryUsageBytes.HasValue) { this.Snapshot(); } - var value = this.memoryUsage.Value; - this.memoryUsage = null; + var value = this.memoryUsageBytes.Value; + this.memoryUsageBytes = null; return value; }, unit: "By", @@ -56,13 +68,13 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.memory.virtual", () => { - if (!this.virtualMemoryUsage.HasValue) + if (!this.virtualMemoryUsageBytes.HasValue) { this.Snapshot(); } - var value = this.virtualMemoryUsage.Value; - this.virtualMemoryUsage = null; + var value = this.virtualMemoryUsageBytes.Value; + this.virtualMemoryUsageBytes = null; return value; }, unit: "By", @@ -72,32 +84,84 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.cpu.time", () => { - if (!this.userProcessorTime.HasValue || !this.privilegedProcessorTime.HasValue) + if (!this.userProcessorTimeSeconds.HasValue || !this.privilegedProcessorTimeSeconds.HasValue) { this.Snapshot(); } - var userProcessorTimeValue = this.userProcessorTime.Value; - var privilegedProcessorTimeValue = this.privilegedProcessorTime.Value; - this.userProcessorTime = null; - this.privilegedProcessorTime = null; + var userProcessorTimeSecondsValue = this.userProcessorTimeSeconds.Value; + var privilegedProcessorTimeSecondsValue = this.privilegedProcessorTimeSeconds.Value; + this.userProcessorTimeSeconds = null; + this.privilegedProcessorTimeSeconds = null; return new[] { - new Measurement(userProcessorTimeValue, new KeyValuePair("state", "user")), - new Measurement(privilegedProcessorTimeValue, new KeyValuePair("state", "system")), + new Measurement(userProcessorTimeSecondsValue, new KeyValuePair("state", "user")), + new Measurement(privilegedProcessorTimeSecondsValue, new KeyValuePair("state", "system")), }; }, unit: "s", description: "Total CPU seconds broken down by different states."); + + this.MeterInstance.CreateObservableGauge( + "process.cpu.utilization", + () => + { + if (this.cpuUtilization == null) + { + this.Snapshot(); + } + + var value = this.cpuUtilization; + this.cpuUtilization = null; + return value; + }, + unit: "1", + description: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process."); + + // TODO: change to ObservableUpDownCounter + this.MeterInstance.CreateObservableGauge( + "process.threads", + () => + { + if (!this.numberOfThreads.HasValue) + { + this.Snapshot(); + } + + var value = this.numberOfThreads.Value; + this.numberOfThreads = null; + return value; + }, + unit: "{threads}", + description: "Process threads count."); } private void Snapshot() { this.currentProcess.Refresh(); - this.memoryUsage = this.currentProcess.WorkingSet64; - this.virtualMemoryUsage = this.currentProcess.PrivateMemorySize64; - this.userProcessorTime = this.currentProcess.UserProcessorTime.TotalSeconds; - this.privilegedProcessorTime = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; + this.memoryUsageBytes = this.currentProcess.WorkingSet64; + this.virtualMemoryUsageBytes = this.currentProcess.PrivateMemorySize64; + this.userProcessorTimeSeconds = this.currentProcess.UserProcessorTime.TotalSeconds; + this.privilegedProcessorTimeSeconds = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; + this.cpuUtilization = this.GetCpuUtilization(); + this.numberOfThreads = this.currentProcess.Threads.Count; + } + + private IEnumerable> GetCpuUtilization() + { + var elapsedTimeForAllCpus = (DateTime.UtcNow - this.lastCollectionTimeUtc).TotalSeconds * Environment.ProcessorCount; + var userProcessorUtilization = (this.userProcessorTimeSeconds - this.lastCollectedUserProcessorTime) / elapsedTimeForAllCpus; + var privilegedProcessorUtilization = (this.privilegedProcessorTimeSeconds - this.lastCollectedPrivilegedProcessorTime) / elapsedTimeForAllCpus; + + this.lastCollectionTimeUtc = DateTime.UtcNow; + this.lastCollectedUserProcessorTime = this.currentProcess.UserProcessorTime.TotalSeconds; + this.lastCollectedPrivilegedProcessorTime = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; + + return new[] + { + new Measurement(Math.Min(userProcessorUtilization.Value, 1D), new KeyValuePair("state", "user")), + new Measurement(Math.Min(privilegedProcessorUtilization.Value, 1D), new KeyValuePair("state", "system")), + }; } } diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 82631a34ab..c269f58aa8 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -15,7 +15,6 @@ // using System.Collections.Generic; -using System.Diagnostics.Metrics; using System.Linq; using OpenTelemetry.Metrics; using Xunit; @@ -37,13 +36,17 @@ public void ProcessMetricsAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count == 3); + Assert.True(exportedItems.Count == 5); var physicalMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetric); var virtualMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetric); var cpuTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.time"); Assert.NotNull(cpuTimeMetric); + var cpuUtilizationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.utilization"); + Assert.NotNull(cpuUtilizationMetric); + var threadMetric = exportedItems.FirstOrDefault(i => i.Name == "process.threads"); + Assert.NotNull(cpuTimeMetric); } [Fact] @@ -83,6 +86,43 @@ public void CpuTimeMetricsAreCaptured() Assert.True(systemTimeCaptured); } + [Fact] + public void CpuUtilizationMetricsAreCaptured() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + meterProvider.ForceFlush(MaxTimeToAllowForFlush); + + var cpuUtilizationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.utilization"); + Assert.NotNull(cpuUtilizationMetric); + + var userCpuUtilizationCaptured = false; + var systemCpuUtilizationCaptured = false; + + var iter = cpuUtilizationMetric.GetMetricPoints().GetEnumerator(); + while (iter.MoveNext() && (!userCpuUtilizationCaptured || !systemCpuUtilizationCaptured)) + { + foreach (var tag in iter.Current.Tags) + { + if (tag.Key == "state" && tag.Value.ToString() == "user") + { + userCpuUtilizationCaptured = true; + } + else if (tag.Key == "state" && tag.Value.ToString() == "system") + { + systemCpuUtilizationCaptured = true; + } + } + } + + Assert.True(userCpuUtilizationCaptured); + Assert.True(systemCpuUtilizationCaptured); + } + [Fact] public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName() { From 427758d8df14c3287391ba85d43dc7a06537010f Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 14 Oct 2022 13:59:20 -0700 Subject: [PATCH 0370/1499] initial (#698) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 6 +++++- src/OpenTelemetry.Instrumentation.Process/README.md | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 1512c42162..29f719d4ae 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -1,3 +1,7 @@ # Changelog -## Unreleased +## 0.1.0-alpha.1 + +* This is the first release of `OpenTelemetry.Instrumentation.Process` package. + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index a0fc4b1faa..234d58625c 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -36,8 +36,7 @@ Process instrumentation should be enabled at application startup using the ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddProcessInstrumentation() - .AddPrometheusHttpListener( - options => options.UriPrefixes = new string[] { "http://localhost:9464/" }) + .AddPrometheusHttpListener() .Build(); ``` From 841e6e5e2db270e691580bbd8c44f8633a03bb25 Mon Sep 17 00:00:00 2001 From: moonheart Date: Sat, 15 Oct 2022 05:33:19 +0800 Subject: [PATCH 0371/1499] [Instrumentation.MysqlData] Compatibility with `Mysql.Data` 8.0.31. (#692) --- src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 3 +++ .../MySqlDataInstrumentation.cs | 9 ++++++++- src/OpenTelemetry.Instrumentation.MySqlData/README.md | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index e4f9db9cbc..f9fb061c2e 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -4,6 +4,9 @@ * Update OTel API version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) +* Compatibility with `Mysql.Data` 8.0.31 or later, Users must set `Logging=true` + in their connection string manually. + ([#692](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/692)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index ce8ae4a66d..be4a296afe 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Concurrent; using System.Diagnostics; +using System.Reflection; using MySql.Data.MySqlClient; using OpenTelemetry.Trace; @@ -37,7 +38,13 @@ public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null) MySqlTrace.Listeners.Clear(); MySqlTrace.Listeners.Add(this); MySqlTrace.Switch.Level = SourceLevels.Information; - MySqlTrace.QueryAnalysisEnabled = true; + + // Mysql.Data removed `MySql.Data.MySqlClient.MySqlTrace.QueryAnalysisEnabled` since 8.0.31 so we need to set this using reflection. + var queryAnalysisEnabled = typeof(MySqlTrace).GetProperty("QueryAnalysisEnabled", BindingFlags.Public | BindingFlags.Static); + if (queryAnalysisEnabled != null) + { + queryAnalysisEnabled.SetValue(null, true); + } } /// diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index 7224b08334..ea6cb7deee 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -52,6 +52,10 @@ the `ConfigureServices` of your `Startup` class. Refer to documentation for For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md). +Note, If you are using `Mysql.Data` 8.0.31 or later, please add +option `Logging=true` in your connection string to enable tracing. +See issue #691 for details. + ## Advanced configuration This instrumentation can be configured to change the default behavior by using From 7cc659a33c5799a1b8c37755db72fdb1c7b8611f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 14 Oct 2022 14:55:20 -0700 Subject: [PATCH 0372/1499] Minor updates (#699) --- opentelemetry-dotnet-contrib.sln | 1 + src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index fd5b53819f..f1c9c7a209 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -54,6 +54,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml + .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 29f719d4ae..03cb29b20e 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.1.0-alpha.1 +Released 2022-Oct-14 + * This is the first release of `OpenTelemetry.Instrumentation.Process` package. For more details, please refer to the [README](README.md). From 8542bc8458e46d60e51c40b3d70478c7b8629239 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 17 Oct 2022 14:44:24 -0700 Subject: [PATCH 0373/1499] [Exporter.Geneva] Update GenevaMetricExporter to export Histogram Min Max (#704) * Update GenevaMetricExporter to export Histogram Min Max --- .../CHANGELOG.md | 8 +- .../Metrics/GenevaMetricExporter.cs | 20 ++++- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 79 +++++++++++++------ .../GenevaMetricExporterTests.cs | 45 +++++++++-- 5 files changed, 113 insertions(+), 41 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 472bf8169d..8b2f0cfdd0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,14 +2,16 @@ ## Unreleased -* Update OTel SDK version to `1.3.1`. - [#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631) - * The option `TableNameMappings` of `GenevaExporterOptions` will not support string values that are null, empty, or consist only of white-space characters. It will also not support string values that contain non-ASCII characters. [646](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/646) +* Update OTel SDK version to `1.4.0-beta.2`. Add support for exporting Histogram + Min and Max. If the histogram does not contain min and max, the exporter + exports both the values as zero. + [#704](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/704) + ## 1.4.0-beta.1 Released 2022-Aug-01 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index a809174c3a..56eee227d3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -180,13 +180,23 @@ public override ExportResult Export(in Batch batch) { var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + MetricData min = ulongZero; + MetricData max = ulongZero; + if (metricPoint.HasMinMax()) + { + min = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMin()) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMax()) }; + } + var bodyLength = this.SerializeHistogramMetric( metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricPoint.GetHistogramBuckets(), sum, - count); + count, + min, + max); this.metricDataTransport.Send(MetricEventType.ExternallyAggregatedULongDistributionMetric, this.bufferForHistogramMetrics, bodyLength); break; } @@ -317,7 +327,9 @@ internal unsafe ushort SerializeHistogramMetric( in ReadOnlyTagCollection tags, HistogramBuckets buckets, MetricData sum, - uint count) + uint count, + MetricData min, + MetricData max) { ushort bodyLength; try @@ -425,8 +437,8 @@ internal unsafe ushort SerializeHistogramMetric( payloadPtr[0].Count = count; payloadPtr[0].TimestampUtc = (ulong)timestamp; payloadPtr[0].Sum = sum; - payloadPtr[0].Min = ulongZero; - payloadPtr[0].Max = ulongZero; + payloadPtr[0].Min = min; + payloadPtr[0].Max = max; } } finally diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 380115bd7e..4f7f6b7b96 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 0bb882d50b..037bca4755 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -23,30 +23,31 @@ using OpenTelemetry.Metrics; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000 +BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.674) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=6.0.102 - [Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT - DefaultJob : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT +.NET SDK=7.0.100-preview.6.22352.1 + [Host] : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2 + DefaultJob : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2 + | Method | Mean | Error | StdDev | Allocated | |--------------------------------------------------------- |----------:|---------:|---------:|----------:| -| InstrumentWithNoListener3Dimensions | 66.07 ns | 0.213 ns | 0.199 ns | - | -| InstrumentWithNoListener4Dimensions | 109.53 ns | 0.267 ns | 0.236 ns | - | -| InstrumentWithWithListener3Dimensions | 65.59 ns | 0.322 ns | 0.285 ns | - | -| InstrumentWithWithListener4Dimensions | 117.56 ns | 0.655 ns | 0.613 ns | - | -| InstrumentWithWithDummyReader3Dimensions | 182.75 ns | 0.787 ns | 0.698 ns | - | -| InstrumentWithWithDummyReader4Dimensions | 244.04 ns | 1.268 ns | 1.186 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 181.74 ns | 0.595 ns | 0.527 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 265.85 ns | 3.214 ns | 3.006 ns | - | -| SerializeCounterMetricItemWith3Dimensions | 166.33 ns | 0.470 ns | 0.439 ns | - | -| SerializeCounterMetricItemWith4Dimensions | 200.02 ns | 0.546 ns | 0.510 ns | - | -| ExportCounterMetricItemWith3Dimensions | 464.79 ns | 3.996 ns | 3.738 ns | - | -| ExportCounterMetricItemWith4Dimensions | 504.02 ns | 6.362 ns | 5.951 ns | - | -| SerializeHistogramMetricItemWith3Dimensions | 260.47 ns | 1.364 ns | 1.276 ns | - | -| SerializeHistogramMetricItemWith4Dimensions | 293.25 ns | 0.674 ns | 0.631 ns | - | -| ExportHistogramMetricItemWith3Dimensions | 585.69 ns | 5.137 ns | 4.805 ns | - | -| ExportHistogramMetricItemWith4Dimensions | 618.47 ns | 4.946 ns | 4.384 ns | - | +| InstrumentWithNoListener3Dimensions | 67.73 ns | 0.232 ns | 0.217 ns | - | +| InstrumentWithNoListener4Dimensions | 109.41 ns | 0.593 ns | 0.526 ns | - | +| InstrumentWithWithListener3Dimensions | 70.75 ns | 0.336 ns | 0.314 ns | - | +| InstrumentWithWithListener4Dimensions | 111.69 ns | 0.455 ns | 0.403 ns | - | +| InstrumentWithWithDummyReader3Dimensions | 187.26 ns | 1.206 ns | 1.128 ns | - | +| InstrumentWithWithDummyReader4Dimensions | 254.82 ns | 0.931 ns | 0.777 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 177.80 ns | 1.325 ns | 1.239 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 255.63 ns | 4.011 ns | 3.752 ns | - | +| SerializeCounterMetricItemWith3Dimensions | 176.72 ns | 0.858 ns | 0.803 ns | - | +| SerializeCounterMetricItemWith4Dimensions | 211.00 ns | 1.069 ns | 1.000 ns | - | +| ExportCounterMetricItemWith3Dimensions | 448.24 ns | 3.487 ns | 3.091 ns | - | +| ExportCounterMetricItemWith4Dimensions | 489.01 ns | 4.478 ns | 3.739 ns | - | +| SerializeHistogramMetricItemWith3Dimensions | 303.49 ns | 5.922 ns | 7.050 ns | - | +| SerializeHistogramMetricItemWith4Dimensions | 330.51 ns | 3.240 ns | 3.030 ns | - | +| ExportHistogramMetricItemWith3Dimensions | 610.94 ns | 3.551 ns | 2.965 ns | - | +| ExportHistogramMetricItemWith4Dimensions | 632.27 ns | 1.829 ns | 1.528 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; @@ -68,6 +69,10 @@ public class MetricExporterBenchmarks private MetricPoint histogramMetricPointWith4Dimensions; private MetricData histogramSumWith3Dimensions; private MetricData histogramSumWith4Dimensions; + private MetricData histogramMinWith3Dimensions; + private MetricData histogramMinWith4Dimensions; + private MetricData histogramMaxWith3Dimensions; + private MetricData histogramMaxWith4Dimensions; private uint histogramCountWith3Dimensions; private uint histogramCountWith4Dimensions; private Batch histogramMetricBatchWith3Dimensions; @@ -118,8 +123,8 @@ public void Setup() enumeratorForCounterBatchWith4Dimensions.MoveNext(); this.counterMetricWith4Dimensions = enumeratorForCounterBatchWith4Dimensions.Current; - this.histogramMetricPointWith3Dimensions = this.GenerateHistogramMetricItemWith3Dimensions(out this.histogramSumWith3Dimensions, out this.histogramCountWith3Dimensions); - this.histogramMetricPointWith4Dimensions = this.GenerateHistogramMetricItemWith4Dimensions(out this.histogramSumWith4Dimensions, out this.histogramCountWith4Dimensions); + this.histogramMetricPointWith3Dimensions = this.GenerateHistogramMetricItemWith3Dimensions(out this.histogramSumWith3Dimensions, out this.histogramCountWith3Dimensions, out this.histogramMinWith3Dimensions, out this.histogramMaxWith3Dimensions); + this.histogramMetricPointWith4Dimensions = this.GenerateHistogramMetricItemWith4Dimensions(out this.histogramSumWith4Dimensions, out this.histogramCountWith4Dimensions, out this.histogramMinWith4Dimensions, out this.histogramMaxWith4Dimensions); this.histogramMetricBatchWith3Dimensions = this.GenerateHistogramBatchWith3Dimensions(); this.histogramMetricBatchWith4Dimensions = this.GenerateHistogramBatchWith4Dimensions(); @@ -287,7 +292,7 @@ private Batch GenerateCounterBatchWith4Dimensions() return batchGeneratorExporter.Batch; } - private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData sum, out uint count) + private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData sum, out uint count, out MetricData min, out MetricData max) { using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith3Dimensions", "0.0.1"); var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); @@ -321,10 +326,19 @@ private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData su sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + min = new MetricData { UInt64Value = 0 }; + max = new MetricData { UInt64Value = 0 }; + + if (metricPoint.HasMinMax()) + { + min = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMin()) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMax()) }; + } + return metricPoint; } - private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData sum, out uint count) + private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData sum, out uint count, out MetricData min, out MetricData max) { using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith4Dimensions", "0.0.1"); var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); @@ -362,6 +376,15 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData su sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + min = new MetricData { UInt64Value = 0 }; + max = new MetricData { UInt64Value = 0 }; + + if (metricPoint.HasMinMax()) + { + min = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMin()) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMax()) }; + } + return metricPoint; } @@ -583,7 +606,9 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramMetricPointWith3Dimensions.Tags, this.histogramMetricPointWith3Dimensions.GetHistogramBuckets(), this.histogramSumWith3Dimensions, - this.histogramCountWith3Dimensions); + this.histogramCountWith3Dimensions, + this.histogramMinWith3Dimensions, + this.histogramMaxWith3Dimensions); } [Benchmark] @@ -595,7 +620,9 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramMetricPointWith4Dimensions.Tags, this.histogramMetricPointWith4Dimensions.GetHistogramBuckets(), this.histogramSumWith4Dimensions, - this.histogramCountWith4Dimensions); + this.histogramCountWith4Dimensions, + this.histogramMinWith4Dimensions, + this.histogramMaxWith4Dimensions); } [Benchmark] diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 1ace1bbd8b..28f881e557 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -184,7 +184,7 @@ public void SuccessfulSerialization(bool testMaxLimits) // 1000: 1 // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) - histogram.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(0, new("tag1", "value1"), new("tag2", "value2")); histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogram.Record(750, new("tag1", "value1"), new("tag2", "value2")); @@ -265,6 +265,7 @@ public void SuccessfulSerializationWithViews() var doubleCounter = meter.CreateCounter("doubleCounter"); var histogramWithCustomBounds = meter.CreateHistogram("histogramWithCustomBounds"); var histogramWithNoBounds = meter.CreateHistogram("histogramWithNoBounds"); + var histogramWithNoMinMax = meter.CreateHistogram("histogramWithNoMinMax"); var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { @@ -292,6 +293,12 @@ public void SuccessfulSerializationWithViews() return null; }) + .AddView( + "histogramWithNoMinMax", + new HistogramConfiguration + { + RecordMinMax = false, + }) .AddView("observableLongCounter", MetricStreamConfiguration.Drop) .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { } }) .AddView(instrument => @@ -364,7 +371,7 @@ public void SuccessfulSerializationWithViews() // 1000: 1 // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) - histogramWithCustomBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(0, new("tag1", "value1"), new("tag2", "value2")); histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); @@ -378,12 +385,18 @@ public void SuccessfulSerializationWithViews() // Only `sum` and `count` are sent for histogramWithNoBounds // No value-count pairs are sent for histogramWithNoBounds - histogramWithNoBounds.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(0, new("tag1", "value1"), new("tag2", "value2")); histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogramWithNoBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); histogramWithNoBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + string path = string.Empty; Socket server = null; try @@ -414,7 +427,7 @@ public void SuccessfulSerializationWithViews() inMemoryReader.Collect(); - Assert.Equal(6, exportedItems.Count); + Assert.Equal(7, exportedItems.Count); // observableLongCounter and observableDoubleGauge are dropped Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); @@ -644,13 +657,31 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE { var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + + ulong minValue = 0; + ulong maxValue = 0; + var min = new MetricData { UInt64Value = 0 }; + var max = new MetricData { UInt64Value = 0 }; + + if (metricPoint.HasMinMax()) + { + minValue = Convert.ToUInt64(metricPoint.GetHistogramMin()); + maxValue = Convert.ToUInt64(metricPoint.GetHistogramMax()); + + min = new MetricData { UInt64Value = minValue }; + max = new MetricData { UInt64Value = maxValue }; + } + var bodyLength = exporter.SerializeHistogramMetric( metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricPoint.GetHistogramBuckets(), sum, - count); + count, + min, + max); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); data = new MetricsContract(stream); @@ -688,8 +719,8 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE Assert.Equal(count, valueSection.Count); Assert.Equal(Convert.ToUInt64(metricPoint.GetHistogramSum()), valueSection.Sum); - Assert.Equal(0UL, valueSection.Min); - Assert.Equal(0UL, valueSection.Max); + Assert.Equal(minValue, valueSection.Min); + Assert.Equal(maxValue, valueSection.Max); Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); Assert.Equal((ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric, data.EventId); Assert.Equal(bodyLength, data.LenBody); From 9bf327d5fb51a3145e5195ea3e19fe30ff4f458c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 17 Oct 2022 14:53:33 -0700 Subject: [PATCH 0374/1499] [Exporter.Geneva] Update GenevaExporter CHANGELOG for 1.4.0-beta.2 release (#706) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 8b2f0cfdd0..45bc04f69c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-beta.2 + +Released 2022-Oct-17 + * The option `TableNameMappings` of `GenevaExporterOptions` will not support string values that are null, empty, or consist only of white-space characters. It will also not support string values that contain non-ASCII characters. From 1ffa9546c2325a2108793d06b90506e4557e39e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 18 Oct 2022 00:12:56 +0200 Subject: [PATCH 0375/1499] [Instrumentation.MySqlData] Release 1.0.0-beta.4 (#700) Co-authored-by: Utkarsh Umesan Pillai --- src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index f9fb061c2e..881231b6f7 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2022-Oct-17 + * Update OTel API version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) * Compatibility with `Mysql.Data` 8.0.31 or later, Users must set `Logging=true` From cc9daf1d052849407f128b4c602d99134b26630b Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 17 Oct 2022 15:36:43 -0700 Subject: [PATCH 0376/1499] [Instrumentation.EventCounters] Release 1.0.0-alpha.1 (#705) --- src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 165812f4e6..bfe9583479 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.1 + +Released 2022-Oct-17 + * Simplified implementation. EventSources must be explicitly configured to be listened to now. ([#620](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/620)) From 926386e68c9066e8032853e8309abdf4088d8dca Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 17 Oct 2022 16:57:09 -0700 Subject: [PATCH 0377/1499] [Instrumentation.Process] Update doc and example for 0.1.0-alpha.1. (#702) --- examples/process-instrumentation/Program.cs | 32 ++++++++ .../process-instrumentation.csproj | 12 +++ opentelemetry-dotnet-contrib.sln | 8 ++ .../README.md | 81 ++++++++++++++++++- 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 examples/process-instrumentation/Program.cs create mode 100644 examples/process-instrumentation/process-instrumentation.csproj diff --git a/examples/process-instrumentation/Program.cs b/examples/process-instrumentation/Program.cs new file mode 100644 index 0000000000..789a591454 --- /dev/null +++ b/examples/process-instrumentation/Program.cs @@ -0,0 +1,32 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry; +using OpenTelemetry.Metrics; + +public class Program +{ + public static void Main() + { + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddPrometheusHttpListener() + .Build(); + + Console.WriteLine(".NET Process metrics are available at http://localhost:9464/metrics, press any key to exit..."); + Console.ReadKey(false); + } +} diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj new file mode 100644 index 0000000000..3ac8e20efd --- /dev/null +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -0,0 +1,12 @@ + + + Exe + net6.0 + enable + enable + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f1c9c7a209..321f30a763 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution CONTRIBUTING.md = CONTRIBUTING.md NuGet.config = NuGet.config opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj + examples\process-instrumentation\process-instrumentation.csproj = examples\process-instrumentation\process-instrumentation.csproj README.md = README.md EndProjectSection EndProject @@ -239,6 +240,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AWSLambda", "src\OpenTelemetry.Instrumentation.AWSLambda\OpenTelemetry.Instrumentation.AWSLambda.csproj", "{B40B975E-78B2-4712-8B4D-BADA67DF0C0A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "process-instrumentation", "examples\process-instrumentation\process-instrumentation.csproj", "{C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -501,6 +504,10 @@ Global {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Debug|Any CPU.Build.0 = Debug|Any CPU {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Release|Any CPU.ActiveCfg = Release|Any CPU {B40B975E-78B2-4712-8B4D-BADA67DF0C0A}.Release|Any CPU.Build.0 = Release|Any CPU + {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -578,6 +585,7 @@ Global {61421ACF-5F90-491B-AFB3-14EF12CCA255} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {0F18B7C8-B192-4236-9578-7AD02BFC7128} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {B40B975E-78B2-4712-8B4D-BADA67DF0C0A} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 234d58625c..7ad6d59a1f 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -17,7 +17,7 @@ Add a reference to package. ```shell -dotnet add package OpenTelemetry.Instrumentation.Process +dotnet add package --prerelease OpenTelemetry.Instrumentation.Process ``` Add a reference to @@ -40,8 +40,87 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder() .Build(); ``` +Refer to [Program.cs](../../examples/process-instrumentation/Program.cs) for a +complete demo. + ## Metrics +### process.memory.usage + +The amount of physical memory allocated for this process. + +| Units | Instrument Type | Value Type | +|-------|-------------------|------------| +| `By` | ObservableGauge | `Double` | + +The API used to retrieve the value is: + +* [Process.WorkingSet64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.workingset64): +Gets the amount of physical memory, in bytes, +allocated for the associated process. + +### process.memory.virtual + +The amount of virtual memory allocated for this process +that cannot be shared with other processes. + +| Units | Instrument Type | Value Type | +|-------|-------------------|------------| +| `By` | ObservableGauge | `Double` | + +The API used to retrieve the value is: + +* [Process.WorkingSet64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privatememorysize64): +Gets the amount of private memory, in bytes, +allocated for the associated process. + +### process.cpu.time + +Total CPU seconds broken down by states. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------|-------------------|------------|------------------|------------------| +| `s` | ObservableCounter | `Double` | state | user, system | + +The APIs used to retrieve the values are: + +* [Process.UserProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.userprocessortime): +Gets the user processor time for this process. + +* [Process.PrivilegedProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privilegedprocessortime): +Gets the privileged processor time for this process. + +### process.cpu.utilization + +Difference in process.cpu.time since the last measurement, +divided by the elapsed time and number of CPUs available to the process. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------|-------------------|------------|------------------|------------------| +| `1` | ObservableCounter | `Double` | state | user, system | + +The APIs used to retrieve the values are: + +* [Process.UserProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.userprocessortime): +Gets the user processor time for this process. + +* [Process.PrivilegedProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privilegedprocessortime): +Gets the privileged processor time for this process. + +### process.threads + +Process threads count. + +| Units | Instrument Type | Value Type | +|-----------------|-------------------|------------| +| `{threads}` | ObservableGauge | `Int32` | + +The API used to retrieve the value is: + +* [Process.Threads](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.threads): +Gets the set of threads that are running +in the associated process. + ## References * [OpenTelemetry Project](https://opentelemetry.io/) From 018e1240327ebd7c75dac8546221bd8d6e63a6c8 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Wed, 19 Oct 2022 01:28:27 +0200 Subject: [PATCH 0378/1499] [Instrumentation.EventCounters] Avoid race condition and performance trap in EventCountersMetrics (#703) --- .../EventCountersMetrics.cs | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index e01ce8b968..f4c92ad5c2 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -30,7 +30,7 @@ internal sealed class EventCountersMetrics : EventListener internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, typeof(EventCountersMetrics).Assembly.GetName().Version.ToString()); private readonly EventCountersInstrumentationOptions options; - private readonly ConcurrentQueue preInitEventSources = new(); + private readonly List preInitEventSources = new(); private readonly ConcurrentDictionary<(string, string), Instrument> instruments = new(); private readonly ConcurrentDictionary<(string, string), double> values = new(); @@ -40,27 +40,35 @@ internal sealed class EventCountersMetrics : EventListener /// The options to define the metrics. public EventCountersMetrics(EventCountersInstrumentationOptions options) { - this.options = options; - - while (this.preInitEventSources.TryDequeue(out EventSource eventSource)) + lock (this.preInitEventSources) { - if (this.options.ShouldListenToSource(eventSource.Name)) + this.options = options; + + foreach (EventSource eventSource in this.preInitEventSources) { - this.EnableEvents(eventSource, EventLevel.LogAlways, EventKeywords.None, GetEnableEventsArguments(this.options)); + if (this.options.ShouldListenToSource(eventSource.Name)) + { + this.EnableEvents(eventSource); + } } + + this.preInitEventSources.Clear(); } } /// - protected override void OnEventSourceCreated(EventSource source) + protected override void OnEventSourceCreated(EventSource eventSource) { - if (this.options == null) + lock (this.preInitEventSources) { - this.preInitEventSources.Enqueue(source); - } - else if (this.options.ShouldListenToSource(source.Name)) - { - this.EnableEvents(source, EventLevel.LogAlways, EventKeywords.None, GetEnableEventsArguments(this.options)); + if (this.options == null) + { + this.preInitEventSources.Add(eventSource); + } + else if (this.options.ShouldListenToSource(eventSource.Name)) + { + this.EnableEvents(eventSource); + } } } @@ -112,6 +120,11 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) private static Dictionary GetEnableEventsArguments(EventCountersInstrumentationOptions options) => new() { { "EventCounterIntervalSec", options.RefreshIntervalSecs.ToString() } }; + private void EnableEvents(EventSource eventSource) + { + this.EnableEvents(eventSource, EventLevel.Critical, EventKeywords.None, GetEnableEventsArguments(this.options)); + } + private void UpdateInstrumentWithEvent(bool isGauge, string eventSourceName, string name, double value) { try From 855cc61aff85ef79d20677fc77cdcf92acea2a71 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 18 Oct 2022 21:28:19 -0400 Subject: [PATCH 0379/1499] [Instrumentation.EventCounters] Few Fixes to EventCounter instrumentation doc (#708) --- .../CHANGELOG.md | 2 ++ .../EventCountersInstrumentationEventSource.cs | 4 ++-- .../EventCountersInstrumentationOptions.cs | 2 +- .../EventCountersMetrics.cs | 2 +- .../MeterProviderBuilderExtensions.cs | 2 +- ...nTelemetry.Instrumentation.EventCounters.csproj | 2 +- .../README.md | 14 ++++++-------- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index bfe9583479..f3f36b2d94 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OpenTelemetry.Api to 1.3.1. + ## 1.0.0-alpha.1 Released 2022-Oct-17 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs index 071f963352..a05b4e8d11 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs @@ -32,8 +32,8 @@ internal void ErrorWhileWritingEvent(string eventSourceName, string exceptionMes this.WriteEvent(1, eventSourceName, exceptionMessage); } - [Event(2, Level = EventLevel.Warning, Message = "Event data payload not parseable from source: {0}.")] - internal void IgnoreEventWrittenEventArgsPayloadNotParseable(string eventSourceName) + [Event(2, Level = EventLevel.Warning, Message = "Event data payload not parsable from source: {0}.")] + internal void IgnoreEventWrittenEventArgsPayloadNotParsable(string eventSourceName) { this.WriteEvent(2, eventSourceName); } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs index 87e1a93e75..d373e03fb8 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs @@ -21,7 +21,7 @@ namespace OpenTelemetry.Instrumentation.EventCounters; /// -/// EventCounterListener Options. +/// EventCounters Instrumentation Options. /// public class EventCountersInstrumentationOptions { diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index f4c92ad5c2..c236463144 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -90,7 +90,7 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) if (eventData.Payload == null || eventData.Payload.Count == 0 || eventData.Payload[0] is not IDictionary payload) { - EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenEventArgsPayloadNotParseable(eventSourceName); + EventCountersInstrumentationEventSource.Log.IgnoreEventWrittenEventArgsPayloadNotParsable(eventSourceName); return; } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index daf35c18ef..8dedcb5ef5 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -29,7 +29,7 @@ public static class MeterProviderBuilderExtensions /// Enables EventCounter instrumentation. /// /// being configured. - /// Runtime metrics options. + /// EventCounters instrumentation options. /// The instance of to chain the calls. public static MeterProviderBuilder AddEventCountersInstrumentation( this MeterProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 571b39054d..3ab16929ad 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -7,7 +7,7 @@ enable - + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index 059f79cc32..88939ad647 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -16,7 +16,7 @@ Add a reference to the package. ```shell -dotnet add package OpenTelemetry.Instrumentation.EventCounters +dotnet add package OpenTelemetry.Instrumentation.EventCounters --prerelease ``` ### Step 2: Enable EventCounters Instrumentation @@ -28,23 +28,21 @@ EventCounters instrumentation should be enabled at application startup using the using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.RefreshIntervalSecs = 1; - options.Sources.Add("MyEventSourceName"); + options.AddEventSources("MyEventSource"); }) - .AddPrometheusExporter() + .AddPrometheusHttpListener() .Build(); -} ``` -Additionally, this examples sets up the OpenTelemetry Prometheus exporter, which +Additionally, the above snippet sets up the OpenTelemetry Prometheus exporter, which requires adding the package [`OpenTelemetry.Exporter.Prometheus`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) to the application. ### Step 3: Create EventCounters -Learn about -[EventCounters in .NET](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/event-counters) -. +Learn about [EventCounters in +.NET](https://docs.microsoft.com/en-us/dotnet/core/diagnostics/event-counters) . ```csharp EventSource eventSource = new("MyEventSource"); From 0318b95a45c32f37e1f73805f9cd1272d0ce928c Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 18 Oct 2022 21:11:17 -0700 Subject: [PATCH 0380/1499] minor improvements on the EventCounters instrumentation library doc (#710) --- .../README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index 88939ad647..bbfc44a413 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -1,11 +1,13 @@ -# Event Counters Instrumentation for OpenTelemetry .NET +# EventCounters Instrumentation for OpenTelemetry .NET [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EventCounters.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) -This is an -[Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) -, which **republishes EventCounters using Metrics Api.** +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) +, which republishes +[EventCounters](https://learn.microsoft.com/dotnet/core/diagnostics/event-counters) +using OpenTelemetry Metrics API. ## Steps to enable OpenTelemetry.Instrumentation.EventCounters From 70930c95d6e09b19fadaac274dacef2cfc0a0695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 19 Oct 2022 06:58:49 +0200 Subject: [PATCH 0381/1499] Disable MyGet nuget source (#711) --- NuGet.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NuGet.config b/NuGet.config index 1f022d500c..51a4cc1590 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,7 +3,8 @@ - + From be99330cce6d40c86174492b8a6bc688036c1c3b Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 19 Oct 2022 15:24:31 -0400 Subject: [PATCH 0382/1499] Ignore event counter test (#714) --- .../EventCountersMetricsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 748e849ed5..cf76ea1055 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -132,7 +132,7 @@ public async Task PollingCounter() Assert.Equal(20, GetActualValue(metric)); } - [Fact] + [Fact(Skip = "Unstable")] public async Task IncrementingPollingCounter() { // Arrange @@ -160,7 +160,7 @@ public async Task IncrementingPollingCounter() Assert.Equal(2, GetActualValue(metric)); } - [Fact] + [Fact(Skip = "Unstable")] public async Task EventCounterSameNameUsesNewestCreated() { // Arrange From f12e16ec667fd083d6df704320b710f3d4a74567 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 19 Oct 2022 12:31:04 -0700 Subject: [PATCH 0383/1499] Add Piotr as Approver (#709) Co-authored-by: Cijo Thomas --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 78e89ea64c..20f73f6fc0 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ expected to directly contribute to every component. Approvers ([@open-telemetry/dotnet-contrib-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers)): -* This list is currently empty. +* [Piotr Kiełkowicz](https://github.com/Kielek), Splunk *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).* From d4045b8546455f25e0e8d0156daa07e1d514d373 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 19 Oct 2022 15:37:25 -0400 Subject: [PATCH 0384/1499] d (#715) --- .github/workflows/integration-md.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/integration-md.yml diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml new file mode 100644 index 0000000000..36c72b382e --- /dev/null +++ b/.github/workflows/integration-md.yml @@ -0,0 +1,22 @@ +name: Integration Tests + +on: + push: + branches: [ main ] + paths-ignore: + - '**.md' + pull_request: + branches: [ main ] + paths-ignore: + - '**.md' + +jobs: + redis-test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: [netcoreapp3.1,net6.0] + steps: + - run: 'echo "No build required"' + From 00cbcae0fbe059e995c94cebe741f694f9a3c814 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 19 Oct 2022 18:07:36 -0400 Subject: [PATCH 0385/1499] Refactor props file to have latest version of core pkgs (#712) * Refactor props file to have latest version of core pkgs * revert undesired --- build/Common.nonprod.props | 2 +- build/Common.props | 3 +-- examples/AspNet/Examples.AspNet.csproj | 10 +++++----- src/OpenTelemetry.Extensions.Docker/CHANGELOG.md | 2 ++ .../OpenTelemetry.Extensions.Docker.csproj | 2 +- ...y.Instrumentation.AspNet.TelemetryHttpModule.csproj | 2 +- .../OpenTelemetry.Instrumentation.EventCounters.csproj | 2 +- .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 +- .../OpenTelemetry.Instrumentation.MassTransit.csproj | 2 +- .../OpenTelemetry.Instrumentation.MySqlData.csproj | 2 +- .../OpenTelemetry.Instrumentation.Owin.csproj | 2 +- .../OpenTelemetry.Instrumentation.Process.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- ...Telemetry.Instrumentation.StackExchangeRedis.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.csproj | 2 +- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 2 +- ...penTelemetry.Instrumentation.MySqlData.Tests.csproj | 2 +- 17 files changed, 22 insertions(+), 21 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 026bf333a4..a7bbb51661 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -26,7 +26,7 @@ [5.0.0,7.0) [16.11.0,17.0) [4.17.2,5.0) - $(OpenTelemetryPkgVer) + $(OpenTelemetryCoreLatestVersion) [2.4.3,3.0) [2.4.2,3.0) diff --git a/build/Common.props b/build/Common.props index 2e4d94d967..e50a2cf7bb 100644 --- a/build/Common.props +++ b/build/Common.props @@ -32,8 +32,7 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.3.1,2.0) - $(OpenTelemetryApiPkgVer) + [1.3.1,2.0) [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index f13b2ffa57..e3f43cf21f 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -79,12 +79,12 @@ - + - - - - + + + + diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md index 638666430a..a352c0ca85 100644 --- a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Updates to 1.3.1 of OpenTelemetry SDK. + ## 1.0.0-beta.1 Released 2022-Jul-28 diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj index 4ae5ed2cb3..3eb8b7868a 100644 --- a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj +++ b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj @@ -5,6 +5,6 @@ Extensions.Docker- - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 64ed2d64c2..da7cfcfe8f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -23,6 +23,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 3ab16929ad..886f83bec0 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -7,7 +7,7 @@ enable - + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index f12cc61c01..33a91b03ee 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj index b9bc4618d7..d1a65cfa05 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj @@ -8,7 +8,7 @@ true - + diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index 6dfbeedb42..322698ecec 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index f2d861129d..65ebc2363d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index f4d3822b0c..cdf19e7ebd 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index dad52da362..73fb0a8ab2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 06dc29e19c..be106c8cf2 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 33f4f07253..dacec3f16e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 75e8545346..6ff4659473 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -18,7 +18,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 81cb72fc80..13742dc9fa 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -16,7 +16,7 @@ - + From 72724549ff498ea7177efbb4079526a2745e6dfe Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 19 Oct 2022 19:15:30 -0400 Subject: [PATCH 0386/1499] [Exporter.Geneva] LogExporter to serialize Exception Stack (#672) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 5 ++ .../netstandard2.0/PublicAPI.Unshipped.txt | 5 ++ .../ExceptionStackExportMode.cs | 25 ++++++ .../GenevaExporterOptions.cs | 2 + .../MsgPackExporter/MsgPackLogExporter.cs | 59 +++++++++++--- .../GenevaLogExporterTests.cs | 7 ++ .../LogSerializationTests.cs | 81 ++++++++++++++++--- 7 files changed, 161 insertions(+), 23 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2..62efb0fa1b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..62efb0fa1b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs new file mode 100644 index 0000000000..6cad7899a6 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.Geneva; + +public enum ExceptionStackExportMode +{ + Drop, + ExportAsString, + + // ExportAsArrayOfStacks - future if stacks can be exported in more structured way +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 437569fa4d..eee0865e0f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -34,6 +34,8 @@ public class GenevaExporterOptions public IEnumerable CustomFields { get; set; } + public ExceptionStackExportMode ExceptionStackExportMode { get; set; } + public IReadOnlyDictionary TableNameMappings { get => this._tableNameMappings; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index aa60cb88b4..70e2f8cd24 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -31,6 +31,9 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private const int MaxSanitizedEventNameLength = 50; private readonly IReadOnlyDictionary m_customFields; + + private readonly ExceptionStackExportMode m_exportExceptionStack; + private readonly string m_defaultEventName = "Log"; private readonly IReadOnlyDictionary m_prepopulatedFields; private readonly List m_prepopulatedFieldKeys; @@ -47,6 +50,8 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable public MsgPackLogExporter(GenevaExporterOptions options) { + this.m_exportExceptionStack = options.ExceptionStackExportMode; + // TODO: Validate mappings for reserved tablenames etc. if (options.TableNameMappings != null) { @@ -288,18 +293,6 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; } - // Part A - ex extension - if (logRecord.Exception != null) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_type"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.GetType().FullName); - cntFields += 1; - - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_msg"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); - cntFields += 1; - } - // Part B var logLevel = logRecord.LogLevel; @@ -429,6 +422,33 @@ void ProcessScope(LogRecordScope scope, object state) cntFields += 1; } + // Part A - ex extension + if (logRecord.Exception != null) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_type"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.GetType().FullName); + cntFields += 1; + + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_msg"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); + cntFields += 1; + + if (this.m_exportExceptionStack == ExceptionStackExportMode.ExportAsString) + { + // The current approach relies on the existing trim + // capabilities which trims string in excess of STRING_SIZE_LIMIT_CHAR_COUNT + // TODO: Revisit this: + // 1. Trim it off based on how much more bytes are available + // before running out of limit instead of STRING_SIZE_LIMIT_CHAR_COUNT. + // 2. Trim smarter, by trimming the middle of stack, an + // keep top and bottom. + var exceptionStack = ToInvariantString(logRecord.Exception); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_stack"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, exceptionStack); + cntFields += 1; + } + } + MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); cursor += this.m_bufferEpilogue.Length; @@ -520,6 +540,21 @@ private static int SerializeSanitizedCategoryName(byte[] buffer, int cursor, str return cursor; } + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + public void Dispose() { if (this.isDisposed) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 1014c7b2da..908884fe39 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -42,6 +42,13 @@ public void BadArgs() }); } + [Fact] + public void ExportExceptionStackDefaultIsDrop() + { + GenevaExporterOptions exporterOptions = new GenevaExporterOptions(); + Assert.Equal(ExceptionStackExportMode.Drop, exporterOptions.ExceptionStackExportMode); + } + [Fact] public void SpecialCharactersInTableNameMappings() { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index 69cbf74d4a..b1f6057210 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -45,16 +45,57 @@ public LogSerializationTests(ITestOutputHelper output) public void SerializationTestForException() { var exceptionMessage = "Exception Message"; - var exportedFields = GetExportedFieldsAfterLogging(logger => logger.Log( - logLevel: LogLevel.Information, - eventId: default, - state: null, - exception: new Exception(exceptionMessage), - formatter: null)); - - PrintFields(this.output, exportedFields); + var exStack = "Exception StackTrace"; + var ex = new MyException(exceptionMessage, exStack); + var exportedFields = GetExportedFieldsAfterLogging( + logger => + { + logger.Log( + logLevel: LogLevel.Information, + eventId: default, + state: null, + exception: ex, + formatter: null); + }, + (genevaOptions) => + genevaOptions.ExceptionStackExportMode = ExceptionStackExportMode.ExportAsString); + var actualExceptionMessage = exportedFields["env_ex_msg"]; Assert.Equal(exceptionMessage, actualExceptionMessage); + + var actualExceptionType = exportedFields["env_ex_type"]; + Assert.Equal(typeof(MyException).FullName, actualExceptionType); + + var actualExceptionStack = exportedFields["env_ex_stack"]; + Assert.Equal(exStack, actualExceptionStack); + } + + [Fact] + public void SerializationTestForExceptionTrim() + { + var exceptionMessage = "Exception Message"; + var exStack = new string('e', 16383 + 1); + var ex = new MyException(exceptionMessage, exStack); + var exportedFields = GetExportedFieldsAfterLogging( + logger => logger.LogError(ex, "Error occurred. {field1} {field2}", "value1", "value2"), + (genevaOptions) => genevaOptions.ExceptionStackExportMode = ExceptionStackExportMode.ExportAsString); + + var actualExceptionMessage = exportedFields["env_ex_msg"]; + Assert.Equal(exceptionMessage, actualExceptionMessage); + + var actualExceptionType = exportedFields["env_ex_type"]; + Assert.Equal(typeof(MyException).FullName, actualExceptionType); + + var actualExceptionStack = exportedFields["env_ex_stack"]; + Assert.EndsWith("...", (string)actualExceptionStack); + + var actualValue = exportedFields["field1"]; + Assert.Equal("value1", actualValue); + + actualValue = exportedFields["field2"]; + Assert.Equal("value2", actualValue); + + // PrintFields(this.output, exportedFields); } private static void PrintFields(ITestOutputHelper output, Dictionary fields) @@ -65,7 +106,7 @@ private static void PrintFields(ITestOutputHelper output, Dictionary GetExportedFieldsAfterLogging(Action doLog) + private static Dictionary GetExportedFieldsAfterLogging(Action doLog, Action configureGeneva = null) { Socket server = null; string path = string.Empty; @@ -77,9 +118,9 @@ private static Dictionary GetExportedFieldsAfterLogging(Action(); + var logger = loggerFactory.CreateLogger(); doLog(logger); Assert.Single(logRecordList); @@ -98,6 +139,8 @@ private static Dictionary GetExportedFieldsAfterLogging(Action; _ = exporter.SerializeLogRecord(logRecordList[0]); @@ -146,4 +189,20 @@ private static Dictionary GetFields(object fluentdData) var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; return mapping; } + + private class MyException : Exception + { + private string stackTrace; + + public MyException(string message, string stackTrace) + : base(message) + { + this.stackTrace = stackTrace; + } + + public override string ToString() + { + return this.stackTrace; + } + } } From 3a9e2484767ea46082c7e9cdcbc473f14a6795da Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 20 Oct 2022 15:10:02 -0700 Subject: [PATCH 0387/1499] [Exporter.Geneva] Add support for UpDownCounter and ObservableUpDownCounter (#685) * Add support for UpDownCounter --- .../CHANGELOG.md | 3 + .../Metrics/GenevaMetricExporter.cs | 18 +++++ ...Telemetry.Exporter.Geneva.Benchmark.csproj | 3 +- ...penTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../GenevaMetricExporterTests.cs | 67 +++++++++++++++++-- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 4 +- 6 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 45bc04f69c..b82f35ee58 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add support for exporting `UpDownCounter` and `ObservableUpDownCounter`. + [#685](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/685) + ## 1.4.0-beta.2 Released 2022-Oct-17 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 56eee227d3..068f8388c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -148,7 +148,25 @@ public override ExportResult Export(in Batch batch) break; } + // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` + case MetricType.LongSumNonMonotonic: + { + // potential for minor precision loss implicitly going from long->double + // see: https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions + var doubleSum = Convert.ToDouble(metricPoint.GetSumLong()); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + case MetricType.DoubleSum: + case MetricType.DoubleSumNonMonotonic: { var doubleSum = metricPoint.GetSumDouble(); var metricData = new MetricData { DoubleValue = doubleSum }; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 57236f7a96..5112523ae7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 @@ -11,7 +11,6 @@ - diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 36d6642f07..0ef8e9d09d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1308,SA1201 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 28f881e557..37c351e1dd 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -102,6 +102,8 @@ public void SuccessfulSerialization(bool testMaxLimits) using var meter = new Meter("SuccessfulSerialization", "0.0.1"); var longCounter = meter.CreateCounter("longCounter"); var doubleCounter = meter.CreateCounter("doubleCounter"); + var longUpDownCounter = meter.CreateUpDownCounter("longUpDownCounter"); + var doubleUpDownCounter = meter.CreateUpDownCounter("doubleUpDownCounter"); var histogram = meter.CreateHistogram("histogram"); var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) @@ -129,6 +131,12 @@ public void SuccessfulSerialization(bool testMaxLimits) doubleCounter.Add( doubleValue, new("tag1", "value1"), new("tag2", "value2")); + longUpDownCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2")); + + doubleUpDownCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2")); + meter.CreateObservableCounter( "observableLongCounter", () => new List>() @@ -157,6 +165,20 @@ public void SuccessfulSerialization(bool testMaxLimits) new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), }); + meter.CreateObservableUpDownCounter( + "observableUpDownLongCounter", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableUpDownCounter( + "observableUpDownDoubleCounter", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), + }); + if (testMaxLimits) { // only testing the max value allowed for sum @@ -221,7 +243,7 @@ public void SuccessfulSerialization(bool testMaxLimits) inMemoryReader.Collect(); - Assert.Equal(7, exportedItems.Count); + Assert.Equal(11, exportedItems.Count); // check serialization for longCounter this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); @@ -229,20 +251,32 @@ public void SuccessfulSerialization(bool testMaxLimits) // check serialization for doubleCounter this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - // check serialization for histogram + // check serialization for longUpDownCounter this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - // check serialization for observableLongCounter + // check serialization for doubleUpDownCounter this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - // check serialization for observableDoubleCounter + // check serialization for histogram this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - // check serialization for observableLongGauge + // check serialization for observableLongCounter this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); - // check serialization for observableDoubleGauge + // check serialization for observableDoubleCounter this.CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + + // check serialization for observableLongGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[7], exporter, exporterOptions); + + // check serialization for observableDoubleGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[8], exporter, exporterOptions); + + // check serialization for observableUpDownLongCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[9], exporter, exporterOptions); + + // check serialization for observableUpDownDoubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[10], exporter, exporterOptions); } finally { @@ -653,6 +687,27 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); Assert.Equal(bodyLength, data.LenBody); } + else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) + { + var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? + Convert.ToDouble(metricPoint.GetSumLong()) : + Convert.ToDouble(metricPoint.GetSumDouble()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleDoubleValue; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } else if (metricType == MetricType.Histogram) { var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index c7115ee052..ddbb67ecd0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for Geneva Exporters for OpenTelemetry - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 @@ -31,7 +31,7 @@ - + From 46179b7fed184d0404df8caab481f9aeeee4fb3e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 20 Oct 2022 15:55:12 -0700 Subject: [PATCH 0388/1499] [Exporter.Geneva] Export LongGauge as a double metric (#721) --- .../CHANGELOG.md | 4 +++ .../Metrics/GenevaMetricExporter.cs | 13 ++++++---- .../GenevaMetricExporterTests.cs | 25 ++++++++++++++++--- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index b82f35ee58..f4f153efa0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,10 @@ * Add support for exporting `UpDownCounter` and `ObservableUpDownCounter`. [#685](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/685) +* Export `MetricType.LongGauge` as a double metric as it might return negative + values. + [#721](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/721) + ## 1.4.0-beta.2 Released 2022-Oct-17 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 068f8388c2..c02b5f6080 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -134,17 +134,20 @@ public override ExportResult Export(in Batch batch) break; } + // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` case MetricType.LongGauge: { - var ulongSum = Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); - var metricData = new MetricData { UInt64Value = ulongSum }; + // potential for minor precision loss implicitly going from long->double + // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions + var doubleSum = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { DoubleValue = doubleSum }; var bodyLength = this.SerializeMetric( - MetricEventType.ULongMetric, + MetricEventType.DoubleMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData); - this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); break; } @@ -152,7 +155,7 @@ public override ExportResult Export(in Batch batch) case MetricType.LongSumNonMonotonic: { // potential for minor precision loss implicitly going from long->double - // see: https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions + // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions var doubleSum = Convert.ToDouble(metricPoint.GetSumLong()); var metricData = new MetricData { DoubleValue = doubleSum }; var bodyLength = this.SerializeMetric( diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 37c351e1dd..4e5f841e6d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -645,11 +645,9 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE MetricsContract data = null; // Check metric value, timestamp, eventId, and length of payload - if (metricType == MetricType.LongSum || metricType == MetricType.LongGauge) + if (metricType == MetricType.LongSum) { - var metricDataValue = metricType == MetricType.LongSum ? - Convert.ToUInt64(metricPoint.GetSumLong()) : - Convert.ToUInt64(metricPoint.GetGaugeLastValueLong()); + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; var bodyLength = exporter.SerializeMetric( MetricEventType.ULongMetric, @@ -666,6 +664,25 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); Assert.Equal(bodyLength, data.LenBody); } + else if (metricType == MetricType.LongGauge) + { + var metricDataValue = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleDoubleValue; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) { var metricDataValue = metricType == MetricType.DoubleSum ? From 1757bcfb2798c817453bc7dba73fec79cbc968d2 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 20 Oct 2022 19:39:48 -0400 Subject: [PATCH 0389/1499] [Exporter.Geneva] - Change default metric exporter interval to 60sec (#722) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 6 ++++++ .../Metrics/GenevaMetricExporterOptions.cs | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f4f153efa0..107f917ad9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -9,6 +9,12 @@ values. [#721](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/721) +* Add support for exporting exception stack. + [#672](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/672) + +* Change the default MetricExportInterval from 20 seconds to 60 seconds. + [#722](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/722) + ## 1.4.0-beta.2 Released 2022-Oct-17 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index 8009f98879..6488e894f8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Exporter.Geneva; public class GenevaMetricExporterOptions { private IReadOnlyDictionary _prepopulatedMetricDimensions; - private int _metricExporterIntervalMilliseconds = 20000; + private int _metricExporterIntervalMilliseconds = 60000; /// /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. @@ -33,7 +33,7 @@ public class GenevaMetricExporterOptions public string ConnectionString { get; set; } /// - /// Gets or sets the metric export interval in milliseconds. The default value is 20000. + /// Gets or sets the metric export interval in milliseconds. The default value is 60000. /// public int MetricExportIntervalMilliseconds { From ee5c8d63d98a46c6a1930122d4acc8a2cd44bd92 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 20 Oct 2022 16:45:29 -0700 Subject: [PATCH 0390/1499] Update CHANGELOG for 1.4.0-beta.3 release (#723) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 107f917ad9..ce5397f31f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-beta.3 + +Released 2022-Oct-20 + * Add support for exporting `UpDownCounter` and `ObservableUpDownCounter`. [#685](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/685) From d21d3cada7b6fc4be03b5f44b35889c476f9a123 Mon Sep 17 00:00:00 2001 From: Vitor Pinto <104011363+vitor-pinto-maersk@users.noreply.github.com> Date: Fri, 21 Oct 2022 18:01:59 +0100 Subject: [PATCH 0391/1499] [Instrumentation.Hangfire] Add option to record exceptions (#719) --- .../CHANGELOG.md | 3 ++ .../HangfireInstrumentationOptions.cs | 31 +++++++++++ ...ngfireInstrumentationJobFilterAttribute.cs | 20 +++++++- .../TracerProviderBuilderExtensions.cs | 11 +++- ...eInstrumentationJobFilterAttributeTests.cs | 51 ++++++++++++++++++- 5 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index f1f0af7179..8536e0e104 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add support to optionally record exceptions + ([#719](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/719)) + * Update OTel API version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs new file mode 100644 index 0000000000..94d14f569d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Trace; + +/// +/// Options for hangfire jobs instrumentation. +/// +public class HangfireInstrumentationOptions +{ + /// + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. + /// + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. + /// + public bool RecordException { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 79cdb83fcd..97e871309b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -23,9 +23,17 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; using global::Hangfire.Common; using global::Hangfire.Server; using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Trace; internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter { + private readonly HangfireInstrumentationOptions options; + + public HangfireInstrumentationJobFilterAttribute(HangfireInstrumentationOptions options) + { + this.options = options; + } + public void OnPerforming(PerformingContext performingContext) { // Short-circuit if nobody is listening @@ -72,7 +80,7 @@ public void OnPerformed(PerformedContext performedContext) { if (performedContext.Exception != null) { - activity.SetStatus(ActivityStatusCode.Error, performedContext.Exception.Message); + this.SetStatusAndRecordException(activity, performedContext.Exception); } activity.Dispose(); @@ -111,4 +119,14 @@ private static IEnumerable ExtractActivityProperties(Dictionary(); } + + private void SetStatusAndRecordException(Activity activity, System.Exception exception) + { + activity.SetStatus(ActivityStatusCode.Error, exception.Message); + + if (this.options.RecordException) + { + activity.RecordException(exception); + } + } } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index 514ced7c46..e1d3a9d2e7 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -16,6 +16,7 @@ namespace OpenTelemetry.Trace; +using System; using OpenTelemetry.Instrumentation.Hangfire.Implementation; using OpenTelemetry.Internal; @@ -28,12 +29,18 @@ public static class TracerProviderBuilderExtensions /// Adds Hangfire instrumentation to the tracer provider. /// /// being configured. + /// Callback action for configuring . /// The instance of to chain the calls. - public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder) + public static TracerProviderBuilder AddHangfireInstrumentation( + this TracerProviderBuilder builder, + Action configureHangfireInstrumentationOptions = null) { Guard.ThrowIfNull(builder); - Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute()); + var options = new HangfireInstrumentationOptions(); + configureHangfireInstrumentationOptions?.Invoke(options); + + Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute(options)); return builder.AddSource(HangfireInstrumentation.ActivitySourceName); } diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index 66d67b5b48..3c8920c64c 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -76,7 +76,56 @@ public async Task Should_Create_Activity_With_Status_Error_When_Job_Failed() Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); Assert.Equal(ActivityKind.Internal, activity.Kind); Assert.Equal(ActivityStatusCode.Error, activity.Status); - Assert.NotNull(activity.StatusDescription); + Assert.Contains("An exception occurred during performance of the job.", activity.StatusDescription); + Assert.Empty(activity.Events); + } + + [Fact] + public async Task Should_Create_Activity_With_Exception_Event_When_Job_Failed_And_Record_Exception_Is_True() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => options.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + // Act + var jobId = BackgroundJob.Enqueue(x => x.ThrowException()); + await this.WaitJobProcessedAsync(jobId, 5); + + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Contains("An exception occurred during performance of the job.", activity.StatusDescription); + Assert.Single(activity.Events, evt => evt.Name == "exception"); + } + + [Fact] + public async Task Should_Create_Activity_Without_Exception_Event_When_Job_Failed_And_Record_Exception_Is_False() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => options.RecordException = false) + .AddInMemoryExporter(exportedItems) + .Build(); + + // Act + var jobId = BackgroundJob.Enqueue(x => x.ThrowException()); + await this.WaitJobProcessedAsync(jobId, 5); + + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Contains("An exception occurred during performance of the job.", activity.StatusDescription); + Assert.Empty(activity.Events); } private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) From 52585a10e5b4eb9a1f686ca447ee973dd4ab95ed Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 21 Oct 2022 13:22:27 -0400 Subject: [PATCH 0392/1499] Update workflow (#724) --- .github/workflows/integration-md.yml | 2 +- opentelemetry-dotnet-contrib.sln | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index 36c72b382e..f5f31d93b0 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -7,7 +7,7 @@ on: - '**.md' pull_request: branches: [ main ] - paths-ignore: + paths: - '**.md' jobs: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 321f30a763..d0925d4c72 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -30,6 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml + .github\workflows\integration-md.yml = .github\workflows\integration-md.yml .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\linux-ci-md.yml = .github\workflows\linux-ci-md.yml .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml From bb9462cafaf4a6a95ffbe1860559f96257ea97d5 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 21 Oct 2022 12:18:14 -0700 Subject: [PATCH 0393/1499] [Instrumentation.Runtime] Update OTel API version to `1.4.0-beta.2` and change runtime metrics type to ObservableUpDownCounter (#675) --- .../CHANGELOG.md | 21 ++++++- ...enTelemetry.Instrumentation.Runtime.csproj | 2 +- .../README.md | 63 +++++++++++-------- .../RuntimeMetrics.cs | 21 +++---- ...metry.Instrumentation.Runtime.Tests.csproj | 2 +- 5 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index a67c0ffee6..3645874e8c 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,8 +2,25 @@ ## Unreleased -* Update OTel API version to `1.3.1`. - ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) +* Update OTel API version to `1.4.0-beta.2`. + + OTel API updated System.Diagnostics.DiagnosticSource to version 7.0.0 + since [1.4.0-alpha.2](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.4.0-alpha.2). + + With this update, applications targeting .NET 5 and lower will receive a + warning at build time as described [here](https://github.com/dotnet/runtime/pull/72518) + (note: building using older versions of the .NET SDK produces an error at + build time). This is because .NET 5 reached EOL in May 2022 and .NET + Core 3.1 reaches EOL in December 2022. + + There is no guarantee that System.Diagnostics.DiagnosticSource will continue + to work on older versions of .NET. However, the build warning can be + suppressed by setting the SuppressTfmSupportBuildWarnings MSBuild property. + + This does not affect applications targeting .NET Framework. + +* Change runtime metrics type to ObservableUpDownCounter from ObservableGauge + ([#675](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/675)) ## 1.0.0 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 73fb0a8ab2..a1b9a2a3f8 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index f2b465b82e..4fc929d467 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -90,15 +90,11 @@ objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred. -Note: `ObservableGauge` should be changed to `ObservableUpDownCounter` once available, -as `ObservableUpDownCounter` is the best fit of instrument type. The same applies -to all the `ObservableGauge` below. - Note: This metric is only available when targeting .NET6 or later. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|---------|-----------------|------------|------------------|------------------| -| `bytes` | ObservableGauge | `Int64` | No Attributes | N/A | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-------------------------|------------|------------------|------------------| +| `bytes` | ObservableUpDownCounter | `Int64` | No Attributes | N/A | The API used to retrieve the value is: @@ -113,9 +109,9 @@ garbage collection has occurred. Note: This metric is only available when targeting .NET6 or later. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|---------|-----------------|------------|------------------|----------------------------| -| `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-------------------------|------------|------------------|----------------------------| +| `bytes` | ObservableUpDownCounter | `Int64` | generation | gen0, gen1, gen2, loh, poh | The API used to retrieve the value is: @@ -134,9 +130,9 @@ The value will be unavailable until at least one garbage collection has occurred Note: This metric is only available when targeting .NET 7 or later. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|---------|-----------------|------------|------------------|----------------------------| -| `bytes` | ObservableGauge | `Int64` | generation | gen0, gen1, gen2, loh, poh | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-------------------------|------------|------------------|----------------------------| +| `bytes` | ObservableUpDownCounter | `Int64` | generation | gen0, gen1, gen2, loh, poh | The API used to retrieve the value is: @@ -206,9 +202,9 @@ the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter(). The number of thread pool threads that currently exist. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------------|-------------------|------------|------------------|------------------| -| `{threads}` | ObservableGauge | `Int32` | No Attributes | N/A | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------------|-------------------------|------------|------------------|------------------| +| `{threads}` | ObservableUpDownCounter | `Int32` | No Attributes | N/A | #### process.runtime.dotnet.**thread_pool.completed_items.count** @@ -224,9 +220,9 @@ since the process start. The number of work items that are currently queued to be processed by the thread pool. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------------|-------------------|------------|------------------|------------------| -| `{items}` | ObservableGauge | `Int64` | No Attributes | N/A | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-----------|-------------------------|------------|------------------|------------------| +| `{items}` | ObservableUpDownCounter | `Int64` | No Attributes | N/A | #### process.runtime.dotnet.**timer.count** @@ -235,9 +231,9 @@ be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------------|-------------------|------------|------------------|------------------| -| `{timers}` | ObservableGauge | `Int64` | No Attributes | N/A | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|------------|-------------------------|------------|------------------|------------------| +| `{timers}` | ObservableUpDownCounter | `Int64` | No Attributes | N/A | The APIs used to retrieve the values are: @@ -260,9 +256,9 @@ The APIs used to retrieve the values are: The number of .NET assemblies that are currently loaded. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|----------------|-----------------|------------|------------------|------------------| -| `{assemblies}` | ObservableGauge | `Int64` | No Attributes | N/A | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|----------------|-------------------------|------------|------------------|------------------| +| `{assemblies}` | ObservableUpDownCounter | `Int64` | No Attributes | N/A | The API used to retrieve the value is: @@ -301,6 +297,23 @@ metric is available in the .NET version you are running. Some GC related metrics are unavailable until at least one garbage collection has occurred. +## Note + +OTel API updated System.Diagnostics.DiagnosticSource preview to version 7.0.0 +since [1.4.0-alpha.2](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.4.0-alpha.2). + +With this update, applications targeting .NET 5 and lower will receive a +warning at build time as described [here](https://github.com/dotnet/runtime/pull/72518) +(note: building using older versions of the .NET SDK produces an error at +build time). This is because .NET 5 reached EOL in May 2022 and .NET +Core 3.1 reaches EOL in December 2022. + +There is no guarantee that System.Diagnostics.DiagnosticSource will continue +to work on older versions of .NET. However, the build warning can be +suppressed by setting the SuppressTfmSupportBuildWarnings MSBuild property. + +This does not affect applications targeting .NET Framework. + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index ac7d89da01..f0605b0c6d 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -60,8 +60,7 @@ static RuntimeMetrics() #endif #if NET6_0_OR_GREATER - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.gc.committed_memory.size", () => { @@ -90,8 +89,7 @@ static RuntimeMetrics() // Either Environment.Version is not 6 or (it's 6 but internal API GC.GetGenerationSize is valid) if (!isCodeRunningOnBuggyRuntimeVersion || getGenerationSize != null) { - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.gc.heap.size", () => { @@ -124,8 +122,7 @@ static RuntimeMetrics() // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 if (Environment.Version.Major >= 7) { - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.gc.heap.fragmentation.size", () => { @@ -174,8 +171,7 @@ static RuntimeMetrics() () => Monitor.LockContentionCount, description: "The number of times there was contention when trying to acquire a monitor lock since the process start. Monitor locks are commonly acquired by using the lock keyword in C#, or by calling Monitor.Enter() and Monitor.TryEnter()."); - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.thread_pool.threads.count", () => (long)ThreadPool.ThreadCount, description: "The number of thread pool threads that currently exist."); @@ -185,21 +181,18 @@ static RuntimeMetrics() () => ThreadPool.CompletedWorkItemCount, description: "The number of work items that have been processed by the thread pool since the process start."); - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.thread_pool.queue.length", () => ThreadPool.PendingWorkItemCount, description: "The number of work items that are currently queued to be processed by the thread pool."); - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.timer.count", () => Timer.ActiveCount, description: "The number of timer instances that are currently active. Timers can be created by many sources such as System.Threading.Timer, Task.Delay, or the timeout in a CancellationSource. An active timer is registered to tick at some point in the future and has not yet been canceled."); #endif - // TODO: change to ObservableUpDownCounter - MeterInstance.CreateObservableGauge( + MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.assemblies.count", () => (long)AppDomain.CurrentDomain.GetAssemblies().Length, description: "The number of .NET assemblies that are currently loaded."); diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 65615a0ce0..ddc0a98c3d 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -8,7 +8,7 @@ - + all From 63f944c2451e20b3157713f9a902317c8cfda50c Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 21 Oct 2022 13:27:18 -0700 Subject: [PATCH 0394/1499] [Instrumentation.Process] Dropping Snapshot (#718) --- .../ProcessMetrics.cs | 87 ++++--------------- .../ProcessMetricsTests.cs | 10 +-- 2 files changed, 19 insertions(+), 78 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index cd4e743149..b67327dd43 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -27,14 +27,6 @@ internal sealed class ProcessMetrics internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); internal readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); - private readonly Diagnostics.Process currentProcess = Diagnostics.Process.GetCurrentProcess(); - private double? memoryUsageBytes; - private double? virtualMemoryUsageBytes; - private double? userProcessorTimeSeconds; - private double? privilegedProcessorTimeSeconds; - private int? numberOfThreads; - private IEnumerable> cpuUtilization; - // vars for calculating CPU utilization private DateTime lastCollectionTimeUtc; private double lastCollectedUserProcessorTime; @@ -43,22 +35,15 @@ internal sealed class ProcessMetrics public ProcessMetrics(ProcessInstrumentationOptions options) { this.lastCollectionTimeUtc = DateTime.UtcNow; - this.lastCollectedUserProcessorTime = this.currentProcess.UserProcessorTime.TotalSeconds; - this.lastCollectedPrivilegedProcessorTime = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; + this.lastCollectedUserProcessorTime = Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; + this.lastCollectedPrivilegedProcessorTime = Diagnostics.Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; // TODO: change to ObservableUpDownCounter this.MeterInstance.CreateObservableGauge( "process.memory.usage", () => { - if (!this.memoryUsageBytes.HasValue) - { - this.Snapshot(); - } - - var value = this.memoryUsageBytes.Value; - this.memoryUsageBytes = null; - return value; + return Diagnostics.Process.GetCurrentProcess().WorkingSet64; }, unit: "By", description: "The amount of physical memory allocated for this process."); @@ -68,14 +53,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.memory.virtual", () => { - if (!this.virtualMemoryUsageBytes.HasValue) - { - this.Snapshot(); - } - - var value = this.virtualMemoryUsageBytes.Value; - this.virtualMemoryUsageBytes = null; - return value; + return Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; }, unit: "By", description: "The amount of virtual memory allocated for this process that cannot be shared with other processes."); @@ -84,20 +62,11 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.cpu.time", () => { - if (!this.userProcessorTimeSeconds.HasValue || !this.privilegedProcessorTimeSeconds.HasValue) - { - this.Snapshot(); - } - - var userProcessorTimeSecondsValue = this.userProcessorTimeSeconds.Value; - var privilegedProcessorTimeSecondsValue = this.privilegedProcessorTimeSeconds.Value; - this.userProcessorTimeSeconds = null; - this.privilegedProcessorTimeSeconds = null; - + var process = Diagnostics.Process.GetCurrentProcess(); return new[] { - new Measurement(userProcessorTimeSecondsValue, new KeyValuePair("state", "user")), - new Measurement(privilegedProcessorTimeSecondsValue, new KeyValuePair("state", "system")), + new Measurement(process.UserProcessorTime.TotalSeconds, new KeyValuePair("state", "user")), + new Measurement(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("state", "system")), }; }, unit: "s", @@ -107,14 +76,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.cpu.utilization", () => { - if (this.cpuUtilization == null) - { - this.Snapshot(); - } - - var value = this.cpuUtilization; - this.cpuUtilization = null; - return value; + return this.GetCpuUtilization(); }, unit: "1", description: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process."); @@ -124,44 +86,27 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.threads", () => { - if (!this.numberOfThreads.HasValue) - { - this.Snapshot(); - } - - var value = this.numberOfThreads.Value; - this.numberOfThreads = null; - return value; + return Diagnostics.Process.GetCurrentProcess().Threads.Count; }, unit: "{threads}", description: "Process threads count."); } - private void Snapshot() - { - this.currentProcess.Refresh(); - this.memoryUsageBytes = this.currentProcess.WorkingSet64; - this.virtualMemoryUsageBytes = this.currentProcess.PrivateMemorySize64; - this.userProcessorTimeSeconds = this.currentProcess.UserProcessorTime.TotalSeconds; - this.privilegedProcessorTimeSeconds = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; - this.cpuUtilization = this.GetCpuUtilization(); - this.numberOfThreads = this.currentProcess.Threads.Count; - } - private IEnumerable> GetCpuUtilization() { + var process = Diagnostics.Process.GetCurrentProcess(); var elapsedTimeForAllCpus = (DateTime.UtcNow - this.lastCollectionTimeUtc).TotalSeconds * Environment.ProcessorCount; - var userProcessorUtilization = (this.userProcessorTimeSeconds - this.lastCollectedUserProcessorTime) / elapsedTimeForAllCpus; - var privilegedProcessorUtilization = (this.privilegedProcessorTimeSeconds - this.lastCollectedPrivilegedProcessorTime) / elapsedTimeForAllCpus; + var userProcessorUtilization = (process.UserProcessorTime.TotalSeconds - this.lastCollectedUserProcessorTime) / elapsedTimeForAllCpus; + var privilegedProcessorUtilization = (process.PrivilegedProcessorTime.TotalSeconds - this.lastCollectedPrivilegedProcessorTime) / elapsedTimeForAllCpus; this.lastCollectionTimeUtc = DateTime.UtcNow; - this.lastCollectedUserProcessorTime = this.currentProcess.UserProcessorTime.TotalSeconds; - this.lastCollectedPrivilegedProcessorTime = this.currentProcess.PrivilegedProcessorTime.TotalSeconds; + this.lastCollectedUserProcessorTime = process.UserProcessorTime.TotalSeconds; + this.lastCollectedPrivilegedProcessorTime = process.PrivilegedProcessorTime.TotalSeconds; return new[] { - new Measurement(Math.Min(userProcessorUtilization.Value, 1D), new KeyValuePair("state", "user")), - new Measurement(Math.Min(privilegedProcessorUtilization.Value, 1D), new KeyValuePair("state", "system")), + new Measurement(Math.Min(userProcessorUtilization, 1D), new KeyValuePair("state", "user")), + new Measurement(Math.Min(privilegedProcessorUtilization, 1D), new KeyValuePair("state", "system")), }; } } diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index c269f58aa8..451ab51dd3 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -46,7 +46,7 @@ public void ProcessMetricsAreCaptured() var cpuUtilizationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.utilization"); Assert.NotNull(cpuUtilizationMetric); var threadMetric = exportedItems.FirstOrDefault(i => i.Name == "process.threads"); - Assert.NotNull(cpuTimeMetric); + Assert.NotNull(threadMetric); } [Fact] @@ -156,13 +156,9 @@ private static double GetValue(Metric metric) foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { - if (metric.MetricType.IsGauge()) - { - sum += metricPoint.GetGaugeLastValueDouble(); - } - else if (metric.MetricType.IsDouble()) + if (metric.MetricType.IsLong()) { - sum += metricPoint.GetSumDouble(); + sum += metricPoint.GetGaugeLastValueLong(); } } From 3183f82ede23cd60feb7d4efe4f3f0b8f819b0cd Mon Sep 17 00:00:00 2001 From: fred2u Date: Mon, 24 Oct 2022 23:31:44 +0200 Subject: [PATCH 0395/1499] [Instrumentation.Hangfire] Update broken link in documentation (#727) --- src/OpenTelemetry.Instrumentation.Hangfire/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index 951a14054b..ec0f79a22b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -54,7 +54,7 @@ For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to [example](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/examples/AspNetCore/Program.cs). For an ASP.NET application, adding instrumentation is typically done in the -`Global.asax.cs`. Refer to [example](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/examples/AspNet/Global.asax.cs). +`Global.asax.cs`. Refer to [example](../../examples/AspNet/Global.asax.cs). ## References From 6158fdbf5ecfd849fc181f47b1b99819cd5a73fc Mon Sep 17 00:00:00 2001 From: fred2u Date: Mon, 24 Oct 2022 23:33:07 +0200 Subject: [PATCH 0396/1499] [Instrumentation.Hangfire] Update CHANGELOG for 1.0.0 release (#728) * Update CHANGELOG for 1.0.0 release --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 8536e0e104..5333334f49 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0 + +Released 2022-Oct-24 + * Add support to optionally record exceptions ([#719](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/719)) From 5843a6180dbc57a07befdaa441213920fa0e11f0 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 25 Oct 2022 10:29:21 -0400 Subject: [PATCH 0397/1499] Remove unnecessary notes from readme (#729) --- .../README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 4fc929d467..3778ace931 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -297,23 +297,6 @@ metric is available in the .NET version you are running. Some GC related metrics are unavailable until at least one garbage collection has occurred. -## Note - -OTel API updated System.Diagnostics.DiagnosticSource preview to version 7.0.0 -since [1.4.0-alpha.2](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.4.0-alpha.2). - -With this update, applications targeting .NET 5 and lower will receive a -warning at build time as described [here](https://github.com/dotnet/runtime/pull/72518) -(note: building using older versions of the .NET SDK produces an error at -build time). This is because .NET 5 reached EOL in May 2022 and .NET -Core 3.1 reaches EOL in December 2022. - -There is no guarantee that System.Diagnostics.DiagnosticSource will continue -to work on older versions of .NET. However, the build warning can be -suppressed by setting the SuppressTfmSupportBuildWarnings MSBuild property. - -This does not affect applications targeting .NET Framework. - ## References * [OpenTelemetry Project](https://opentelemetry.io/) From 1fbdddbc82ff5efb2ecb461abb738e95c7a58305 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 25 Oct 2022 13:56:27 -0400 Subject: [PATCH 0398/1499] Disable more flaky tests (#730) --- .../EventCountersMetricsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index cf76ea1055..f30011718c 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -46,7 +46,7 @@ public async Task NoMetricsByDefault() Assert.Empty(metricItems); } - [Fact] + [Fact(Skip = "Unstable")] public async Task EventCounter() { // Arrange From 8c069ecfe72c9e6fd2ef4d971241bed8d17de337 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 25 Oct 2022 16:05:46 -0400 Subject: [PATCH 0399/1499] Remove netcoreapp3.1 from Runtime instrumentation (#731) --- .../CHANGELOG.md | 36 ++++++++++++------- ...enTelemetry.Instrumentation.Runtime.csproj | 2 +- .../README.md | 8 ++--- .../RuntimeMetrics.cs | 13 ++----- ...metry.Instrumentation.Runtime.Tests.csproj | 4 +-- 5 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 3645874e8c..54f797597f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -4,24 +4,36 @@ * Update OTel API version to `1.4.0-beta.2`. - OTel API updated System.Diagnostics.DiagnosticSource to version 7.0.0 - since [1.4.0-alpha.2](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.4.0-alpha.2). +* Change ObservableGauge to ObservableUpDownCounter for the below metrics (which + better fit UpDownCounter semantics as they are additive.) + + "process.runtime.dotnet.gc.heap.size", + "process.runtime.dotnet.gc.heap.fragmentation.size", + "process.runtime.dotnet.thread_pool.threads.count", + "process.runtime.dotnet.thread_pool.queue.length", + "process.runtime.dotnet.timer.count", + "process.runtime.dotnet.assemblies.count" + ([#675](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/675)) + + If your backend system distinguishes between ObservableUpDownCounter and + ObservableGauge, then you may need to adjust your queries. Systems like + Prometheus are unaffected by this. - With this update, applications targeting .NET 5 and lower will receive a - warning at build time as described [here](https://github.com/dotnet/runtime/pull/72518) +* Removes NETCoreApp3.1 target as .NET Core 3.1 and .NET 5 are going out of + support. The package keeps `netstandard2.0` target, so it can still be used + with .NET Core 3.1/.NET 5 apps, however certain metrics will not be available + there. Additionally, apps targeting .NET 5 and lower will receive a warning at + build time as described [here](https://github.com/dotnet/runtime/pull/72518) (note: building using older versions of the .NET SDK produces an error at - build time). This is because .NET 5 reached EOL in May 2022 and .NET - Core 3.1 reaches EOL in December 2022. + build time). This is because .NET 5 reached EOL in May 2022 and .NET Core 3.1 + reaches EOL in December 2022. - There is no guarantee that System.Diagnostics.DiagnosticSource will continue - to work on older versions of .NET. However, the build warning can be - suppressed by setting the SuppressTfmSupportBuildWarnings MSBuild property. + The build warning can be suppressed by setting the + SuppressTfmSupportBuildWarnings MSBuild property, but there is no guarantee + that this package will continue to work on older versions of .NET. This does not affect applications targeting .NET Framework. -* Change runtime metrics type to ObservableUpDownCounter from ObservableGauge - ([#675](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/675)) - ## 1.0.0 Released 2022-Aug-03 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index a1b9a2a3f8..733d5a2694 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -1,6 +1,6 @@ - netstandard2.0;net462;netcoreapp3.1;net6.0 + netstandard2.0;net462;net6.0 dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 3778ace931..7bf4f6010d 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -69,7 +69,7 @@ Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap. -Note: This metric is only available when targeting .NET Core 3.1 or later. +Note: This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------|------------|------------------|------------------| @@ -90,7 +90,7 @@ objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred. -Note: This metric is only available when targeting .NET6 or later. +Note: This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------------|------------|------------------|------------------| @@ -107,7 +107,7 @@ The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred. -Note: This metric is only available when targeting .NET6 or later. +Note: This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------------|------------|------------------|----------------------------| @@ -186,7 +186,7 @@ The scope of this value is global. The same applies for other JIT related metric ### Threading related metrics -These metrics are only available when targeting .NET Core 3.1 or later. +These metrics are only available when targeting .NET 6 or later. #### process.runtime.dotnet.**monitor.lock_contention.count** diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index f0605b0c6d..32bb167ea4 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -18,11 +18,8 @@ using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; -#if NETCOREAPP3_1_OR_GREATER -using System.Threading; -#endif - #if NET6_0_OR_GREATER +using System.Threading; using JitInfo = System.Runtime.JitInfo; #endif @@ -51,15 +48,13 @@ static RuntimeMetrics() () => GetGarbageCollectionCounts(), description: "Number of garbage collections that have occurred since process start."); -#if NETCOREAPP3_1_OR_GREATER +#if NET6_0_OR_GREATER MeterInstance.CreateObservableCounter( "process.runtime.dotnet.gc.allocations.size", () => GC.GetTotalAllocatedBytes(), unit: "bytes", description: "Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap."); -#endif -#if NET6_0_OR_GREATER MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.gc.committed_memory.size", () => @@ -144,9 +139,7 @@ static RuntimeMetrics() unit: "bytes", description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); } -#endif -#if NET6_0_OR_GREATER MeterInstance.CreateObservableCounter( "process.runtime.dotnet.jit.il_compiled.size", () => JitInfo.GetCompiledILBytes(), @@ -163,9 +156,7 @@ static RuntimeMetrics() () => JitInfo.GetCompilationTime().Ticks * NanosecondsPerTick, unit: "ns", description: "The amount of time the JIT compiler has spent compiling methods since the process start."); -#endif -#if NETCOREAPP3_1_OR_GREATER MeterInstance.CreateObservableCounter( "process.runtime.dotnet.monitor.lock_contention.count", () => Monitor.LockContentionCount, diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index ddc0a98c3d..73f64ecfbe 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,14 +1,14 @@ - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462 - + all From f3b6d070d9f4780edb27017e7f073f0c9e105539 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 25 Oct 2022 17:02:29 -0400 Subject: [PATCH 0400/1499] Nit fixes to tests (#733) --- .../RuntimeMetricsTests.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 56640da0ca..27d71ee87c 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -75,12 +75,11 @@ public void GcMetricsTest() var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); Assert.NotNull(gcCountMetric); -#if NETCOREAPP3_1_OR_GREATER +#if NET6_0_OR_GREATER + var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); Assert.NotNull(gcAllocationSizeMetric); -#endif -#if NET6_0_OR_GREATER var gcCommittedMemorySizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.committed_memory.size"); Assert.NotNull(gcCommittedMemorySizeMetric); @@ -116,9 +115,7 @@ public void JitRelatedMetricsTest() var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); Assert.NotNull(jitCompilationTimeMetric); } -#endif -#if NETCOREAPP3_1_OR_GREATER [Fact] public void ThreadingRelatedMetricsTest() { From 8f7fbd425c7750cc72c03633ff4bfd3d3aeedc42 Mon Sep 17 00:00:00 2001 From: Norm Johanson Date: Tue, 25 Oct 2022 14:53:11 -0700 Subject: [PATCH 0401/1499] Fix using version 3.7.100 of AWS SDK causing exception not finding EndpointResolver (#726) * Fixed using version 3.7.100 of AWS SDK causing exception not finding EndpointResolver in AWS SDK instrumentation package --- src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md | 6 ++++++ .../Implementation/AWSTracingPipelineCustomizer.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md index 0e903ec307..1ef8260da8 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog - OpenTelemetry.Contrib.Instrumentation.AWS +## Unreleased + +* Fixed issue when using version 3.7.100 of the AWS SDK for .NET triggering an + EndpointResolver not found exception. + ([#726](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/726)) + ## 1.0.1 Released 2021-Feb-24 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index 2f93d2e23f..14bd951e9a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -44,6 +44,6 @@ public void Customize(Type serviceClientType, RuntimePipeline pipeline) return; } - pipeline.AddHandlerAfter(new AWSTracingPipelineHandler(this.options)); + pipeline.AddHandlerBefore(new AWSTracingPipelineHandler(this.options)); } } From 6a2545f3eb0bdb84d776a1b05f1bc91502462c68 Mon Sep 17 00:00:00 2001 From: Vitor Pinto <104011363+vitor-pinto-maersk@users.noreply.github.com> Date: Wed, 26 Oct 2022 17:44:15 +0100 Subject: [PATCH 0402/1499] [Instrumentation.Hangfire] Enable Public API analyzer (#734) --- .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 0 .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 6 ++++++ src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++-- .../OpenTelemetry.Instrumentation.Hangfire.csproj | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..15f3ca1d06 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Trace.HangfireInstrumentationOptions +OpenTelemetry.Trace.HangfireInstrumentationOptions.HangfireInstrumentationOptions() -> void +OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHangfireInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 5333334f49..fec9b5658e 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,9 +2,9 @@ ## Unreleased -## 1.0.0 +## 1.0.0-beta.3 -Released 2022-Oct-24 +Released 2022-Oct-26 * Add support to optionally record exceptions ([#719](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/719)) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 33a91b03ee..d0062d2c6e 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -5,6 +5,7 @@ $(PackageTags);Hangfire Instrumentation.Hangfire- false + true From dd0806191e5136b46946b2305459556c71159e6b Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 27 Oct 2022 13:02:43 -0400 Subject: [PATCH 0403/1499] diable eventcounter tests (#738) --- .../EventCountersMetricsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index f30011718c..26beba4deb 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -104,7 +104,7 @@ public async Task IncrementingEventCounter() Assert.Equal(3, GetActualValue(metric)); } - [Fact] + [Fact(Skip = "Unstable")] public async Task PollingCounter() { // Arrange From 7099b6f1a923a25ab43686a0e82f962bb7d19ccc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Oct 2022 10:59:10 -0400 Subject: [PATCH 0404/1499] Bump actions/setup-dotnet from 3.0.2 to 3.0.3 (#739) --- .github/workflows/dotnet-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index fc56e1dadd..c960b5e808 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v3.0.2 + uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: 6.0.x From 126cc343a7b1a173559210dc0c07e5e85f698508 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 28 Oct 2022 09:29:04 -0700 Subject: [PATCH 0405/1499] [Exporter.Geneva] Update scopes (#736) * Update scopes --- .../CHANGELOG.md | 9 +++ .../MsgPackExporter/MsgPackLogExporter.cs | 66 +++++++++++-------- .../GenevaLogExporterTests.cs | 39 ++++------- 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index ce5397f31f..15cd63b6b8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +* Breaking change: Updated export logic for scopes + * Export scopes which have a non-null key as individual columns (each + key-value pair from the scopes is exported as its own column; these columns + would also be taken into consideration when the CustomFields option is + applied). + * When using formatted strings for scopes, the templated string (`"{OriginalFormat"}`) + will not be exported. + [#736](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/736) + ## 1.4.0-beta.3 Released 2022-Oct-20 diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 70e2f8cd24..17dde9799a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -349,42 +349,31 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; } - ushort scopeDepth = 0; - int indexArrayLength = 0; - logRecord.ForEachScope(ProcessScope, (object)null); - void ProcessScope(LogRecordScope scope, object state) + logRecord.ForEachScope(ProcessScopeForIndividualColumns, (object)null); + void ProcessScopeForIndividualColumns(LogRecordScope scope, object state) { - if (++scopeDepth == 1) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "scopes"); - cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); - indexArrayLength = cursor - 2; - } - - cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int indexMapSizeScope = cursor - 2; - ushort keysCount = 0; - foreach (KeyValuePair scopeItem in scope) { - string key = "scope"; - if (!string.IsNullOrEmpty(scopeItem.Key)) + if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { - key = scopeItem.Key; + continue; } - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); - keysCount++; + if (this.m_customFields == null || this.m_customFields.ContainsKey(scopeItem.Key)) + { + if (scopeItem.Value != null) + { + // null is not supported. + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, scopeItem.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); + cntFields += 1; + } + } + else + { + hasEnvProperties = true; + } } - - MessagePackSerializer.WriteUInt16(buffer, indexMapSizeScope, keysCount); - } - - if (scopeDepth > 0) - { - MessagePackSerializer.WriteUInt16(buffer, indexArrayLength, scopeDepth); - cntFields += 1; } if (hasEnvProperties) @@ -410,6 +399,25 @@ void ProcessScope(LogRecordScope scope, object state) } } + logRecord.ForEachScope(ProcessScopeForEnvProperties, (object)null); + void ProcessScopeForEnvProperties(LogRecordScope scope, object state) + { + foreach (KeyValuePair scopeItem in scope) + { + if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") + { + continue; + } + + if (!this.m_customFields.ContainsKey(scopeItem.Key)) + { + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, scopeItem.Key); + cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); + envPropertiesCount += 1; + } + } + } + cntFields += 1; MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 908884fe39..cf2d9c448d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -381,10 +381,13 @@ public void SerializeILoggerScopes() senderSocket.Listen(1); } + var exportedItems = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.IncludeScopes = true; + options.AddInMemoryExporter(exportedItems); options.AddGenevaLogExporter(options => { options.ConnectionString = exporterOptions.ConnectionString; @@ -405,7 +408,7 @@ public void SerializeILoggerScopes() using (logger.BeginScope("MyOuterScope")) using (logger.BeginScope("MyInnerScope")) - using (logger.BeginScope("MyInnerInnerScope with {name} and {age} of custom", "John Doe", 35)) + using (logger.BeginScope("MyInnerInnerScope with {Name} and {Age} of custom", "John Doe", 35)) using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) { logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); @@ -428,31 +431,15 @@ public void SerializeILoggerScopes() var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - var serializedScopes = mapping["scopes"] as object[]; - - Assert.Equal(4, serializedScopes.Length); - - // Test 1st scope - var scope = serializedScopes[0] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("scope", "MyOuterScope"), scope); - - // Test 2nd scope - scope = serializedScopes[1] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("scope", "MyInnerScope"), scope); - - // Test 3rd scope - scope = serializedScopes[2] as ICollection>; - Assert.Equal(3, scope.Count); - Assert.Contains(new KeyValuePair("name", "John Doe"), scope); - Assert.Contains(new KeyValuePair("age", (byte)35), scope); - Assert.Contains(new KeyValuePair("{OriginalFormat}", "MyInnerInnerScope with {name} and {age} of custom"), scope); - - // Test 4th scope - scope = serializedScopes[3] as ICollection>; - Assert.Single(scope); - Assert.Contains(new KeyValuePair("MyKey", "MyValue"), scope); + Assert.Equal("John Doe", mapping["Name"]); + Assert.Equal((byte)35, mapping["Age"]); + Assert.Equal("MyValue", mapping["MyKey"]); + + // Check other fields + Assert.Single(exportedItems); + var logRecord = exportedItems[0]; + + this.AssertFluentdForwardModeForLogRecord(exporterOptions, fluentdData, logRecord); } finally { From ff47b5aa9f2ce0e03cd219ea029687e229baa195 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 28 Oct 2022 09:50:43 -0700 Subject: [PATCH 0406/1499] Update CHANGELOG for 1.4.0-beta.4 (#741) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 15cd63b6b8..6196a7b3df 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-beta.4 + +Released 2022-Oct-28 + * Breaking change: Updated export logic for scopes * Export scopes which have a non-null key as individual columns (each key-value pair from the scopes is exported as its own column; these columns From 0430fe9bb4f3491632d5f165f0e637a956aa1698 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Tue, 1 Nov 2022 14:27:15 -0700 Subject: [PATCH 0407/1499] Use file-scoped namespaces (#742) --- .editorconfig | 1 + examples/AspNet/App_Start/WebApiConfig.cs | 27 +- examples/AspNet/Controllers/HomeController.cs | 25 +- .../Controllers/WeatherForecastController.cs | 259 ++++++------ examples/AspNet/Global.asax.cs | 133 +++--- examples/AspNet/Models/WeatherForecast.cs | 15 +- .../SuppressInstrumentationHttpModule.cs | 55 ++- .../Implementation/AWSLambdaHttpUtils.cs | 177 ++++---- .../Implementation/CommonExtensions.cs | 49 ++- .../README.md | 59 ++- .../Implementation/AWSLambdaHttpUtilsTests.cs | 381 +++++++++--------- .../Implementation/CommonExtensionsTests.cs | 41 +- 12 files changed, 605 insertions(+), 617 deletions(-) diff --git a/.editorconfig b/.editorconfig index 800da16434..ed2db8319f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -141,6 +141,7 @@ dotnet_diagnostic.IDE0002.severity = warning # IDE0005: Remove unnecessary import dotnet_diagnostic.IDE0005.severity = warning +csharp_style_namespace_declarations = file_scoped:warning [obj/**.cs] generated_code = true diff --git a/examples/AspNet/App_Start/WebApiConfig.cs b/examples/AspNet/App_Start/WebApiConfig.cs index 243637d65d..9827495525 100644 --- a/examples/AspNet/App_Start/WebApiConfig.cs +++ b/examples/AspNet/App_Start/WebApiConfig.cs @@ -17,24 +17,23 @@ using System.Net.Http.Formatting; using System.Web.Http; -namespace Examples.AspNet +namespace Examples.AspNet; + +public static class WebApiConfig { - public static class WebApiConfig + public static void Register(HttpConfiguration config) { - public static void Register(HttpConfiguration config) - { - // Web API configuration and services + // Web API configuration and services - // Web API routes - config.MapHttpAttributeRoutes(); + // Web API routes + config.MapHttpAttributeRoutes(); - config.Routes.MapHttpRoute( - name: "DefaultApi", - routeTemplate: "api/{controller}/{id}", - defaults: new { id = RouteParameter.Optional }); + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional }); - config.Formatters.Clear(); - config.Formatters.Add(new JsonMediaTypeFormatter()); - } + config.Formatters.Clear(); + config.Formatters.Add(new JsonMediaTypeFormatter()); } } diff --git a/examples/AspNet/Controllers/HomeController.cs b/examples/AspNet/Controllers/HomeController.cs index f238805897..e8dd81a468 100644 --- a/examples/AspNet/Controllers/HomeController.cs +++ b/examples/AspNet/Controllers/HomeController.cs @@ -16,22 +16,21 @@ using System.Web.Mvc; -namespace Examples.AspNet.Controllers +namespace Examples.AspNet.Controllers; + +public class HomeController : Controller { - public class HomeController : Controller + // For testing traditional routing. Ex: https://localhost:XXXX/ + public ActionResult Index() { - // For testing traditional routing. Ex: https://localhost:XXXX/ - public ActionResult Index() - { - return this.View(); - } + return this.View(); + } - [Route("about_attr_route/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/about_attr_route - public ActionResult About(int? customerId) - { - this.ViewBag.Message = $"Your application description page for customer {customerId}."; + [Route("about_attr_route/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/about_attr_route + public ActionResult About(int? customerId) + { + this.ViewBag.Message = $"Your application description page for customer {customerId}."; - return this.View(); - } + return this.View(); } } diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index 092bdf0710..107c9e2bdf 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -26,192 +26,191 @@ using Examples.AspNet.Models; using OpenTelemetry; -namespace Examples.AspNet.Controllers +namespace Examples.AspNet.Controllers; + +public class WeatherForecastController : ApiController { - public class WeatherForecastController : ApiController + private static readonly string[] Summaries = new[] { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", - }; + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", + }; - [HttpGet] // For testing traditional routing. Ex: https://localhost:XXXX/api/weatherforecast - public async Task> Get() - { - // Build some dependency spans. + [HttpGet] // For testing traditional routing. Ex: https://localhost:XXXX/api/weatherforecast + public async Task> Get() + { + // Build some dependency spans. - await RequestGoogleHomPageViaHttpClient().ConfigureAwait(false); + await RequestGoogleHomPageViaHttpClient().ConfigureAwait(false); - await this.RequestInvalidViaHttpClient().ConfigureAwait(false); + await this.RequestInvalidViaHttpClient().ConfigureAwait(false); - await this.RequestValidThatReturnsFailedViaHttpClient().ConfigureAwait(false); + await this.RequestValidThatReturnsFailedViaHttpClient().ConfigureAwait(false); - await this.RequestValidThatSpawnsSubSpansViaHttpClient().ConfigureAwait(false); + await this.RequestValidThatSpawnsSubSpansViaHttpClient().ConfigureAwait(false); - return GetWeatherForecast(); - } + return GetWeatherForecast(); + } - [Route("subroute/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/subroute/10 - [HttpGet] - public async Task> Get(int customerId) + [Route("subroute/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/subroute/10 + [HttpGet] + public async Task> Get(int customerId) + { + if (customerId < 0) { - if (customerId < 0) - { - throw new ArgumentException(); - } + throw new ArgumentException(); + } - // Making http calls here to serve as an example of - // how dependency calls will be captured and treated - // automatically as child of incoming request. + // Making http calls here to serve as an example of + // how dependency calls will be captured and treated + // automatically as child of incoming request. - RequestGoogleHomPageViaHttpWebRequestLegacySync(); + RequestGoogleHomPageViaHttpWebRequestLegacySync(); - await RequestGoogleHomPageViaHttpWebRequestLegacyAsync().ConfigureAwait(false); + await RequestGoogleHomPageViaHttpWebRequestLegacyAsync().ConfigureAwait(false); - RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult(); + RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult(); - return GetWeatherForecast(); - } + return GetWeatherForecast(); + } - /// - /// For testing large async operation which causes IIS to jump threads and results in lost AsyncLocals. - /// - [Route("data")] - [HttpGet] - public async Task GetData() - { - Baggage.SetBaggage("key1", "value1"); + /// + /// For testing large async operation which causes IIS to jump threads and results in lost AsyncLocals. + /// + [Route("data")] + [HttpGet] + public async Task GetData() + { + Baggage.SetBaggage("key1", "value1"); - using var rng = RandomNumberGenerator.Create(); + using var rng = RandomNumberGenerator.Create(); - var requestData = new byte[1024 * 1024 * 100]; - rng.GetBytes(requestData); + var requestData = new byte[1024 * 1024 * 100]; + rng.GetBytes(requestData); - using var client = new HttpClient(); + using var client = new HttpClient(); - using var request = new HttpRequestMessage(HttpMethod.Post, this.Url.Content("~/data")); + using var request = new HttpRequestMessage(HttpMethod.Post, this.Url.Content("~/data")); - request.Content = new ByteArrayContent(requestData); + request.Content = new ByteArrayContent(requestData); - using var response = await client.SendAsync(request).ConfigureAwait(false); + using var response = await client.SendAsync(request).ConfigureAwait(false); - response.EnsureSuccessStatusCode(); + response.EnsureSuccessStatusCode(); - var responseData = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + var responseData = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); - return responseData.SequenceEqual(responseData) ? "match" : "mismatch"; - } + return responseData.SequenceEqual(responseData) ? "match" : "mismatch"; + } - [Route("data")] - [HttpPost] - public async Task PostData() + [Route("data")] + [HttpPost] + public async Task PostData() + { + string value1 = Baggage.GetBaggage("key1"); + if (string.IsNullOrEmpty(value1)) { - string value1 = Baggage.GetBaggage("key1"); - if (string.IsNullOrEmpty(value1)) - { - throw new InvalidOperationException("Key1 was not found on Baggage."); - } + throw new InvalidOperationException("Key1 was not found on Baggage."); + } - var stream = await this.Request.Content.ReadAsStreamAsync().ConfigureAwait(false); + var stream = await this.Request.Content.ReadAsStreamAsync().ConfigureAwait(false); - var result = new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new StreamContent(stream), - }; + var result = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StreamContent(stream), + }; - result.Content.Headers.ContentType = this.Request.Content.Headers.ContentType; + result.Content.Headers.ContentType = this.Request.Content.Headers.ContentType; - return result; - } + return result; + } - private static IEnumerable GetWeatherForecast() + private static IEnumerable GetWeatherForecast() + { + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast { - var rng = new Random(); - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = rng.Next(-20, 55), - Summary = Summaries[rng.Next(Summaries.Length)], - }) - .ToArray(); - } + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)], + }) + .ToArray(); + } - // Test successful dependency collection via HttpClient. - private static async Task RequestGoogleHomPageViaHttpClient() - { - using var request = new HttpClient(); + // Test successful dependency collection via HttpClient. + private static async Task RequestGoogleHomPageViaHttpClient() + { + using var request = new HttpClient(); - using var response = await request.GetAsync("http://www.google.com").ConfigureAwait(false); + using var response = await request.GetAsync("http://www.google.com").ConfigureAwait(false); - response.EnsureSuccessStatusCode(); - } + response.EnsureSuccessStatusCode(); + } - // Test dependency collection via legacy HttpWebRequest sync. - private static void RequestGoogleHomPageViaHttpWebRequestLegacySync() - { - var request = WebRequest.Create("http://www.google.com/?sync"); + // Test dependency collection via legacy HttpWebRequest sync. + private static void RequestGoogleHomPageViaHttpWebRequestLegacySync() + { + var request = WebRequest.Create("http://www.google.com/?sync"); - using var response = request.GetResponse(); - } + using var response = request.GetResponse(); + } - // Test dependency collection via legacy HttpWebRequest async. - private static async Task RequestGoogleHomPageViaHttpWebRequestLegacyAsync() - { - var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); + // Test dependency collection via legacy HttpWebRequest async. + private static async Task RequestGoogleHomPageViaHttpWebRequestLegacyAsync() + { + var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); - using var response = await request.GetResponseAsync().ConfigureAwait(false); - } + using var response = await request.GetResponseAsync().ConfigureAwait(false); + } - // Test dependency collection via legacy HttpWebRequest IAsyncResult. - private static void RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult() - { - var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); + // Test dependency collection via legacy HttpWebRequest IAsyncResult. + private static void RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult() + { + var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); - var asyncResult = request.BeginGetResponse(null, null); + var asyncResult = request.BeginGetResponse(null, null); - using var response = request.EndGetResponse(asyncResult); - } + using var response = request.EndGetResponse(asyncResult); + } - // Test exception dependency collection via HttpClient. - private async Task RequestInvalidViaHttpClient() + // Test exception dependency collection via HttpClient. + private async Task RequestInvalidViaHttpClient() + { + try { - try - { - using var request = new HttpClient(); + using var request = new HttpClient(); - // This request is not available over SSL and will throw a handshake exception. + // This request is not available over SSL and will throw a handshake exception. - using var response = await request.GetAsync(this.Url.Content("~/subroute/10").Replace("http", "https")).ConfigureAwait(false); + using var response = await request.GetAsync(this.Url.Content("~/subroute/10").Replace("http", "https")).ConfigureAwait(false); - Debug.Fail("Unreachable"); - } - catch - { - } + Debug.Fail("Unreachable"); } - - // Test exception dependency collection via HttpClient. - private async Task RequestValidThatReturnsFailedViaHttpClient() + catch { - using var request = new HttpClient(); + } + } - // This request will return a 500 error because customerId should be >= 0; + // Test exception dependency collection via HttpClient. + private async Task RequestValidThatReturnsFailedViaHttpClient() + { + using var request = new HttpClient(); - using var response = await request.GetAsync(this.Url.Content("~/subroute/-1")).ConfigureAwait(false); + // This request will return a 500 error because customerId should be >= 0; - Debug.Assert(response.StatusCode == HttpStatusCode.InternalServerError, "response.StatusCode is InternalServerError"); - } + using var response = await request.GetAsync(this.Url.Content("~/subroute/-1")).ConfigureAwait(false); - // Test successful dependency collection via HttpClient. - private async Task RequestValidThatSpawnsSubSpansViaHttpClient() - { - using var request = new HttpClient(); + Debug.Assert(response.StatusCode == HttpStatusCode.InternalServerError, "response.StatusCode is InternalServerError"); + } - // This request will return successfully and cause a bunch of sub-spans; + // Test successful dependency collection via HttpClient. + private async Task RequestValidThatSpawnsSubSpansViaHttpClient() + { + using var request = new HttpClient(); - using var response = await request.GetAsync(this.Url.Content("~/subroute/10")).ConfigureAwait(false); + // This request will return successfully and cause a bunch of sub-spans; - response.EnsureSuccessStatusCode(); - } + using var response = await request.GetAsync(this.Url.Content("~/subroute/10")).ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); } } diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index 260dda7f92..76067b6ad0 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -25,87 +25,84 @@ using OpenTelemetry.Metrics; using OpenTelemetry.Trace; -namespace Examples.AspNet +namespace Examples.AspNet; + +public class WebApiApplication : HttpApplication { -#pragma warning disable SA1649 // File name should match first type name - public class WebApiApplication : HttpApplication -#pragma warning restore SA1649 // File name should match first type name + private IDisposable tracerProvider; + private IDisposable meterProvider; + + protected void Application_Start() { - private IDisposable tracerProvider; - private IDisposable meterProvider; + var builder = Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation() + .AddHttpClientInstrumentation(); - protected void Application_Start() + switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant()) { - var builder = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation() - .AddHttpClientInstrumentation(); - - switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant()) - { - case "jaeger": - builder.AddJaegerExporter(jaegerOptions => - { - jaegerOptions.AgentHost = ConfigurationManager.AppSettings["JaegerHost"]; - jaegerOptions.AgentPort = int.Parse(ConfigurationManager.AppSettings["JaegerPort"]); - }); - break; - case "zipkin": - builder.AddZipkinExporter(zipkinOptions => + case "jaeger": + builder.AddJaegerExporter(jaegerOptions => + { + jaegerOptions.AgentHost = ConfigurationManager.AppSettings["JaegerHost"]; + jaegerOptions.AgentPort = int.Parse(ConfigurationManager.AppSettings["JaegerPort"]); + }); + break; + case "zipkin": + builder.AddZipkinExporter(zipkinOptions => + { + zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]); + }); + break; + case "otlp": + builder.AddOtlpExporter(otlpOptions => { - zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]); + otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); }); - break; - case "otlp": - builder.AddOtlpExporter(otlpOptions => - { - otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); - }); - break; - default: - builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug); - break; - } + break; + default: + builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug); + break; + } - this.tracerProvider = builder.Build(); + this.tracerProvider = builder.Build(); - // Metrics - // Note: Tracerprovider is needed for metrics to work - // https://github.com/open-telemetry/opentelemetry-dotnet/issues/2994 + // Metrics + // Note: Tracerprovider is needed for metrics to work + // https://github.com/open-telemetry/opentelemetry-dotnet/issues/2994 - var meterBuilder = Sdk.CreateMeterProviderBuilder() - .AddAspNetInstrumentation(); + var meterBuilder = Sdk.CreateMeterProviderBuilder() + .AddAspNetInstrumentation(); - switch (ConfigurationManager.AppSettings["UseMetricsExporter"].ToLowerInvariant()) - { - case "otlp": - meterBuilder.AddOtlpExporter(otlpOptions => - { - otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); - }); - break; - case "prometheus": - meterBuilder.AddPrometheusExporter(); - break; - default: - meterBuilder.AddConsoleExporter((exporterOptions, metricReaderOptions) => - { - exporterOptions.Targets = ConsoleExporterOutputTargets.Debug; - }); - break; - } + switch (ConfigurationManager.AppSettings["UseMetricsExporter"].ToLowerInvariant()) + { + case "otlp": + meterBuilder.AddOtlpExporter(otlpOptions => + { + otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); + }); + break; + case "prometheus": + meterBuilder.AddPrometheusExporter(); + break; + default: + meterBuilder.AddConsoleExporter((exporterOptions, metricReaderOptions) => + { + exporterOptions.Targets = ConsoleExporterOutputTargets.Debug; + }); + break; + } - this.meterProvider = meterBuilder.Build(); + this.meterProvider = meterBuilder.Build(); - GlobalConfiguration.Configure(WebApiConfig.Register); + GlobalConfiguration.Configure(WebApiConfig.Register); - AreaRegistration.RegisterAllAreas(); - RouteConfig.RegisterRoutes(RouteTable.Routes); - } + AreaRegistration.RegisterAllAreas(); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } - protected void Application_End() - { - this.tracerProvider?.Dispose(); - this.meterProvider?.Dispose(); - } + protected void Application_End() + { + this.tracerProvider?.Dispose(); + this.meterProvider?.Dispose(); } } diff --git a/examples/AspNet/Models/WeatherForecast.cs b/examples/AspNet/Models/WeatherForecast.cs index 71e8983c6d..d4585e88ff 100644 --- a/examples/AspNet/Models/WeatherForecast.cs +++ b/examples/AspNet/Models/WeatherForecast.cs @@ -16,16 +16,15 @@ using System; -namespace Examples.AspNet.Models +namespace Examples.AspNet.Models; + +public class WeatherForecast { - public class WeatherForecast - { - public DateTime Date { get; set; } + public DateTime Date { get; set; } - public int TemperatureC { get; set; } + public int TemperatureC { get; set; } - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); + public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); - public string Summary { get; set; } - } + public string Summary { get; set; } } diff --git a/examples/AspNet/SuppressInstrumentationHttpModule.cs b/examples/AspNet/SuppressInstrumentationHttpModule.cs index fb83210918..ce0d0ae246 100644 --- a/examples/AspNet/SuppressInstrumentationHttpModule.cs +++ b/examples/AspNet/SuppressInstrumentationHttpModule.cs @@ -18,41 +18,40 @@ using System.Web; using OpenTelemetry; -namespace Examples.AspNet +namespace Examples.AspNet; + +/// +/// A demo which will suppress ASP.NET +/// instrumentation if a request contains "suppress=true" on the query +/// string. Suppressed spans will not be processed/exported by the +/// OpenTelemetry SDK. +/// +public class SuppressInstrumentationHttpModule : IHttpModule { - /// - /// A demo which will suppress ASP.NET - /// instrumentation if a request contains "suppress=true" on the query - /// string. Suppressed spans will not be processed/exported by the - /// OpenTelemetry SDK. - /// - public class SuppressInstrumentationHttpModule : IHttpModule + private IDisposable suppressionScope; + + public void Init(HttpApplication context) { - private IDisposable suppressionScope; + context.BeginRequest += this.Application_BeginRequest; + context.EndRequest += this.Application_EndRequest; + } - public void Init(HttpApplication context) - { - context.BeginRequest += this.Application_BeginRequest; - context.EndRequest += this.Application_EndRequest; - } + public void Dispose() + { + } - public void Dispose() - { - } + private void Application_BeginRequest(object sender, EventArgs e) + { + var context = ((HttpApplication)sender).Context; - private void Application_BeginRequest(object sender, EventArgs e) + if (context.Request.QueryString["suppress"] == "true") { - var context = ((HttpApplication)sender).Context; - - if (context.Request.QueryString["suppress"] == "true") - { - this.suppressionScope = SuppressInstrumentationScope.Begin(); - } + this.suppressionScope = SuppressInstrumentationScope.Begin(); } + } - private void Application_EndRequest(object sender, EventArgs e) - { - this.suppressionScope?.Dispose(); - } + private void Application_EndRequest(object sender, EventArgs e) + { + this.suppressionScope?.Dispose(); } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index 25adefc903..94742e8fd8 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -22,115 +22,114 @@ using Amazon.Lambda.APIGatewayEvents; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; + +internal class AWSLambdaHttpUtils { - internal class AWSLambdaHttpUtils + // x-forwarded-... headers are described here https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html + private const string HeaderXForwardedProto = "x-forwarded-proto"; + private const string HeaderHost = "host"; + + internal static IEnumerable> GetHttpTags(TInput input) { - // x-forwarded-... headers are described here https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html - private const string HeaderXForwardedProto = "x-forwarded-proto"; - private const string HeaderHost = "host"; + var tags = new List>(); + + string httpScheme = null; + string httpTarget = null; + string httpMethod = null; + string hostName = null; + int? hostPort = null; - internal static IEnumerable> GetHttpTags(TInput input) + switch (input) { - var tags = new List>(); + case APIGatewayProxyRequest request: + httpScheme = AWSLambdaUtils.GetHeaderValues(request, HeaderXForwardedProto)?.LastOrDefault(); + httpTarget = string.Concat(request.RequestContext?.Path ?? string.Empty, GetQueryString(request)); + httpMethod = request.HttpMethod; + var hostHeader = AWSLambdaUtils.GetHeaderValues(request, HeaderHost)?.LastOrDefault(); + (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeader); + break; + case APIGatewayHttpApiV2ProxyRequest requestV2: + httpScheme = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderXForwardedProto)?.LastOrDefault(); + httpTarget = string.Concat(requestV2.RawPath ?? string.Empty, GetQueryString(requestV2)); + httpMethod = requestV2.RequestContext?.Http?.Method; + var hostHeaderV2 = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderHost)?.LastOrDefault(); + (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeaderV2); + break; + } - string httpScheme = null; - string httpTarget = null; - string httpMethod = null; - string hostName = null; - int? hostPort = null; + tags.AddTagIfNotNull(SemanticConventions.AttributeHttpScheme, httpScheme); + tags.AddTagIfNotNull(SemanticConventions.AttributeHttpTarget, httpTarget); + tags.AddTagIfNotNull(SemanticConventions.AttributeHttpMethod, httpMethod); + tags.AddTagIfNotNull(SemanticConventions.AttributeNetHostName, hostName); + tags.AddTagIfNotNull(SemanticConventions.AttributeNetHostPort, hostPort); - switch (input) - { - case APIGatewayProxyRequest request: - httpScheme = AWSLambdaUtils.GetHeaderValues(request, HeaderXForwardedProto)?.LastOrDefault(); - httpTarget = string.Concat(request.RequestContext?.Path ?? string.Empty, GetQueryString(request)); - httpMethod = request.HttpMethod; - var hostHeader = AWSLambdaUtils.GetHeaderValues(request, HeaderHost)?.LastOrDefault(); - (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeader); - break; - case APIGatewayHttpApiV2ProxyRequest requestV2: - httpScheme = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderXForwardedProto)?.LastOrDefault(); - httpTarget = string.Concat(requestV2.RawPath ?? string.Empty, GetQueryString(requestV2)); - httpMethod = requestV2.RequestContext?.Http?.Method; - var hostHeaderV2 = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderHost)?.LastOrDefault(); - (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeaderV2); - break; - } - - tags.AddTagIfNotNull(SemanticConventions.AttributeHttpScheme, httpScheme); - tags.AddTagIfNotNull(SemanticConventions.AttributeHttpTarget, httpTarget); - tags.AddTagIfNotNull(SemanticConventions.AttributeHttpMethod, httpMethod); - tags.AddTagIfNotNull(SemanticConventions.AttributeNetHostName, hostName); - tags.AddTagIfNotNull(SemanticConventions.AttributeNetHostPort, hostPort); + return tags; + } - return tags; + internal static void SetHttpTagsFromResult(Activity activity, object result) + { + switch (result) + { + case APIGatewayProxyResponse response: + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + break; + case APIGatewayHttpApiV2ProxyResponse responseV2: + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, responseV2.StatusCode); + break; } + } - internal static void SetHttpTagsFromResult(Activity activity, object result) + internal static string GetQueryString(APIGatewayProxyRequest request) + { + if (request.MultiValueQueryStringParameters == null) { - switch (result) - { - case APIGatewayProxyResponse response: - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); - break; - case APIGatewayHttpApiV2ProxyResponse responseV2: - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, responseV2.StatusCode); - break; - } + return string.Empty; } - internal static string GetQueryString(APIGatewayProxyRequest request) + var queryString = new StringBuilder(); + var separator = '?'; + foreach (var parameterKvp in request.MultiValueQueryStringParameters) { - if (request.MultiValueQueryStringParameters == null) - { - return string.Empty; - } - - var queryString = new StringBuilder(); - var separator = '?'; - foreach (var parameterKvp in request.MultiValueQueryStringParameters) + // Multiple values for the same parameter will be added to query + // as ampersand separated: name=value1&name=value2 + foreach (var value in parameterKvp.Value) { - // Multiple values for the same parameter will be added to query - // as ampersand separated: name=value1&name=value2 - foreach (var value in parameterKvp.Value) - { - queryString.Append(separator) - .Append(HttpUtility.UrlEncode(parameterKvp.Key)) - .Append("=") - .Append(HttpUtility.UrlEncode(value)); - separator = '&'; - } + queryString.Append(separator) + .Append(HttpUtility.UrlEncode(parameterKvp.Key)) + .Append("=") + .Append(HttpUtility.UrlEncode(value)); + separator = '&'; } - - return queryString.ToString(); } - internal static string GetQueryString(APIGatewayHttpApiV2ProxyRequest request) => - string.IsNullOrEmpty(request.RawQueryString) ? string.Empty : "?" + request.RawQueryString; + return queryString.ToString(); + } - internal static (string Host, int? Port) GetHostAndPort(string httpScheme, string hostHeader) - { - if (hostHeader == null) - { - return (null, null); - } + internal static string GetQueryString(APIGatewayHttpApiV2ProxyRequest request) => + string.IsNullOrEmpty(request.RawQueryString) ? string.Empty : "?" + request.RawQueryString; - var hostAndPort = hostHeader.Split(new char[] { ':' }, 2); - if (hostAndPort.Length > 1) - { - var host = hostAndPort[0]; - return int.TryParse(hostAndPort[1], out var port) - ? (host, port) - : (host, null); - } - else - { - return (hostAndPort[0], GetDefaultPort(httpScheme)); - } + internal static (string Host, int? Port) GetHostAndPort(string httpScheme, string hostHeader) + { + if (hostHeader == null) + { + return (null, null); } - private static int? GetDefaultPort(string httpScheme) => - httpScheme == "https" ? 443 : httpScheme == "http" ? 80 : null; + var hostAndPort = hostHeader.Split(new char[] { ':' }, 2); + if (hostAndPort.Length > 1) + { + var host = hostAndPort[0]; + return int.TryParse(hostAndPort[1], out var port) + ? (host, port) + : (host, null); + } + else + { + return (hostAndPort[0], GetDefaultPort(httpScheme)); + } } + + private static int? GetDefaultPort(string httpScheme) => + httpScheme == "https" ? 443 : httpScheme == "http" ? 80 : null; } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs index d82ebfad5e..85e8bf3d90 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs @@ -17,41 +17,40 @@ using System; using System.Collections.Generic; -namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; + +internal static class CommonExtensions { - internal static class CommonExtensions + internal static void AddTagIfNotNull(this List> tags, string tagName, object tagValue) { - internal static void AddTagIfNotNull(this List> tags, string tagName, object tagValue) + if (tagValue != null) { - if (tagValue != null) - { - tags.Add(new(tagName, tagValue)); - } + tags.Add(new(tagName, tagValue)); } + } - internal static T GetValueByKeyIgnoringCase(this IDictionary dict, string key) - { - // TODO: there may be opportunities for performance improvements of this method. + internal static T GetValueByKeyIgnoringCase(this IDictionary dict, string key) + { + // TODO: there may be opportunities for performance improvements of this method. - // We had to introduce case-insensitive headers search as can't fully rely on - // AWS documentation stating that expected headers are lower-case. AWS test - // console offers JSON example with camel case header names. - // See X-Forwarded-Proto or X-Forwarded-Port for example. + // We had to introduce case-insensitive headers search as can't fully rely on + // AWS documentation stating that expected headers are lower-case. AWS test + // console offers JSON example with camel case header names. + // See X-Forwarded-Proto or X-Forwarded-Port for example. - if (dict == null) - { - return default; - } + if (dict == null) + { + return default; + } - foreach (var kvp in dict) + foreach (var kvp in dict) + { + if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(kvp.Key, key, StringComparison.OrdinalIgnoreCase)) - { - return kvp.Value; - } + return kvp.Value; } - - return default; } + + return default; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index 1b3bbe8af1..671e273400 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -53,40 +53,39 @@ using System.Web.Mvc; using System.Web.Routing; using OpenTelemetry.Instrumentation.AspNet; -namespace Examples.AspNet +namespace Examples.AspNet; + +public class WebApiApplication : HttpApplication { - public class WebApiApplication : HttpApplication - { - private ActivityListener aspNetActivityListener; + private ActivityListener aspNetActivityListener; - protected void Application_Start() + protected void Application_Start() + { + this.aspNetActivityListener = new ActivityListener { - this.aspNetActivityListener = new ActivityListener + ShouldListenTo = (activitySource) => { - ShouldListenTo = (activitySource) => - { - // Only listen to TelemetryHttpModule's ActivitySource. - return activitySource.Name == TelemetryHttpModule.AspNetSourceName; - }, - Sample = (ref ActivityCreationOptions options) => - { - // Sample everything created by TelemetryHttpModule's ActivitySource. - return ActivitySamplingResult.AllDataAndRecorded; - }, - }; - - ActivitySource.AddActivityListener(this.aspNetActivityListener); - - GlobalConfiguration.Configure(WebApiConfig.Register); - - AreaRegistration.RegisterAllAreas(); - RouteConfig.RegisterRoutes(RouteTable.Routes); - } - - protected void Application_End() - { - this.aspNetActivityListener?.Dispose(); - } + // Only listen to TelemetryHttpModule's ActivitySource. + return activitySource.Name == TelemetryHttpModule.AspNetSourceName; + }, + Sample = (ref ActivityCreationOptions options) => + { + // Sample everything created by TelemetryHttpModule's ActivitySource. + return ActivitySamplingResult.AllDataAndRecorded; + }, + }; + + ActivitySource.AddActivityListener(this.aspNetActivityListener); + + GlobalConfiguration.Configure(WebApiConfig.Register); + + AreaRegistration.RegisterAllAreas(); + RouteConfig.RegisterRoutes(RouteTable.Routes); + } + + protected void Application_End() + { + this.aspNetActivityListener?.Dispose(); } } ``` diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index a5ecf93424..4f7a548c5a 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -23,247 +23,246 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation; + +public class AWSLambdaHttpUtilsTests { - public class AWSLambdaHttpUtilsTests + [Fact] + public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() { - [Fact] - public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() + var request = new APIGatewayProxyRequest { - var request = new APIGatewayProxyRequest + MultiValueHeaders = new Dictionary> { - MultiValueHeaders = new Dictionary> - { - { "X-Forwarded-Proto", new List { "https" } }, - { "Host", new List { "localhost:1234" } }, - }, - HttpMethod = "GET", - MultiValueQueryStringParameters = new Dictionary> - { - { "q1", new[] { "value1" } }, - }, - RequestContext = new APIGatewayProxyRequest.ProxyRequestContext - { - Path = "/path/test", - }, - }; - - var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); - - var expectedTags = new Dictionary + { "X-Forwarded-Proto", new List { "https" } }, + { "Host", new List { "localhost:1234" } }, + }, + HttpMethod = "GET", + MultiValueQueryStringParameters = new Dictionary> { - { "http.scheme", "https" }, - { "http.target", "/path/test?q1=value1" }, - { "net.host.name", "localhost" }, - { "net.host.port", 1234 }, - { "http.method", "GET" }, - }; + { "q1", new[] { "value1" } }, + }, + RequestContext = new APIGatewayProxyRequest.ProxyRequestContext + { + Path = "/path/test", + }, + }; - AssertTags(expectedTags, actualTags); - } + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.scheme", "https" }, + { "http.target", "/path/test?q1=value1" }, + { "net.host.name", "localhost" }, + { "net.host.port", 1234 }, + { "http.method", "GET" }, + }; + + AssertTags(expectedTags, actualTags); + } - [Fact] - public void GetHttpTags_APIGatewayProxyRequestWithMultiValueHeader_UsesLastValue() + [Fact] + public void GetHttpTags_APIGatewayProxyRequestWithMultiValueHeader_UsesLastValue() + { + var request = new APIGatewayProxyRequest { - var request = new APIGatewayProxyRequest + MultiValueHeaders = new Dictionary> { - MultiValueHeaders = new Dictionary> - { - { "X-Forwarded-Proto", new List { "https", "http" } }, - { "Host", new List { "localhost:1234", "myhost:432" } }, - }, - }; + { "X-Forwarded-Proto", new List { "https", "http" } }, + { "Host", new List { "localhost:1234", "myhost:432" } }, + }, + }; - var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); - var expectedTags = new Dictionary - { - { "http.target", string.Empty }, - { "http.scheme", "http" }, - { "net.host.name", "myhost" }, - { "net.host.port", 432 }, - }; + var expectedTags = new Dictionary + { + { "http.target", string.Empty }, + { "http.scheme", "http" }, + { "net.host.name", "myhost" }, + { "net.host.port", 432 }, + }; - AssertTags(expectedTags, actualTags); - } + AssertTags(expectedTags, actualTags); + } - [Fact] - public void GetHttpTags_APIGatewayHttpApiV2ProxyRequest_ReturnsCorrectTags() + [Fact] + public void GetHttpTags_APIGatewayHttpApiV2ProxyRequest_ReturnsCorrectTags() + { + var request = new APIGatewayHttpApiV2ProxyRequest { - var request = new APIGatewayHttpApiV2ProxyRequest + Headers = new Dictionary { - Headers = new Dictionary - { - { "X-Forwarded-Proto", "https" }, - { "Host", "localhost:1234" }, - }, - RawPath = "/path/test", - RawQueryString = "q1=value1", - RequestContext = new APIGatewayHttpApiV2ProxyRequest.ProxyRequestContext + { "X-Forwarded-Proto", "https" }, + { "Host", "localhost:1234" }, + }, + RawPath = "/path/test", + RawQueryString = "q1=value1", + RequestContext = new APIGatewayHttpApiV2ProxyRequest.ProxyRequestContext + { + Http = new APIGatewayHttpApiV2ProxyRequest.HttpDescription { - Http = new APIGatewayHttpApiV2ProxyRequest.HttpDescription - { - Method = "GET", - }, + Method = "GET", }, - }; + }, + }; - var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); - var expectedTags = new Dictionary - { - { "http.scheme", "https" }, - { "http.target", "/path/test?q1=value1" }, - { "net.host.name", "localhost" }, - { "net.host.port", 1234 }, - { "http.method", "GET" }, - }; - - AssertTags(expectedTags, actualTags); - } + var expectedTags = new Dictionary + { + { "http.scheme", "https" }, + { "http.target", "/path/test?q1=value1" }, + { "net.host.name", "localhost" }, + { "net.host.port", 1234 }, + { "http.method", "GET" }, + }; + + AssertTags(expectedTags, actualTags); + } - [Fact] - public void GetHttpTags_APIGatewayHttpApiV2ProxyRequestWithMultiValueHeader_UsesLastValue() + [Fact] + public void GetHttpTags_APIGatewayHttpApiV2ProxyRequestWithMultiValueHeader_UsesLastValue() + { + var request = new APIGatewayHttpApiV2ProxyRequest { - var request = new APIGatewayHttpApiV2ProxyRequest + Headers = new Dictionary { - Headers = new Dictionary - { - { "X-Forwarded-Proto", "https,http" }, - { "Host", "localhost:1234,myhost:432" }, - }, - }; + { "X-Forwarded-Proto", "https,http" }, + { "Host", "localhost:1234,myhost:432" }, + }, + }; - var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); - var expectedTags = new Dictionary - { - { "http.target", string.Empty }, - { "http.scheme", "http" }, - { "net.host.name", "myhost" }, - { "net.host.port", 432 }, - }; + var expectedTags = new Dictionary + { + { "http.target", string.Empty }, + { "http.scheme", "http" }, + { "net.host.name", "myhost" }, + { "net.host.port", 432 }, + }; - AssertTags(expectedTags, actualTags); - } + AssertTags(expectedTags, actualTags); + } - [Fact] - public void SetHttpTagsFromResult_APIGatewayProxyResponse_SetsCorrectTags() + [Fact] + public void SetHttpTagsFromResult_APIGatewayProxyResponse_SetsCorrectTags() + { + var response = new APIGatewayProxyResponse { - var response = new APIGatewayProxyResponse - { - StatusCode = 200, - }; - var activityProcessor = new Mock>(); + StatusCode = 200, + }; + var activityProcessor = new Mock>(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddSource("TestActivitySource") - .Build(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddSource("TestActivitySource") + .Build(); - using var testActivitySource = new ActivitySource("TestActivitySource"); - using var activity = testActivitySource.StartActivity("TestActivity"); + using var testActivitySource = new ActivitySource("TestActivitySource"); + using var activity = testActivitySource.StartActivity("TestActivity"); - AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); - var expectedTags = new Dictionary - { - { "http.status_code", 200 }, - }; - AssertTags(expectedTags, activity.TagObjects); - } + var expectedTags = new Dictionary + { + { "http.status_code", 200 }, + }; + AssertTags(expectedTags, activity.TagObjects); + } - [Fact] - public void SetHttpTagsFromResult_APIGatewayHttpApiV2ProxyResponse_SetsCorrectTags() + [Fact] + public void SetHttpTagsFromResult_APIGatewayHttpApiV2ProxyResponse_SetsCorrectTags() + { + var response = new APIGatewayHttpApiV2ProxyResponse { - var response = new APIGatewayHttpApiV2ProxyResponse - { - StatusCode = 200, - }; - var activityProcessor = new Mock>(); + StatusCode = 200, + }; + var activityProcessor = new Mock>(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddSource("TestActivitySource") - .Build(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddSource("TestActivitySource") + .Build(); - using var testActivitySource = new ActivitySource("TestActivitySource"); - using var activity = testActivitySource.StartActivity("TestActivity"); + using var testActivitySource = new ActivitySource("TestActivitySource"); + using var activity = testActivitySource.StartActivity("TestActivity"); - AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); - var expectedTags = new Dictionary - { - { "http.status_code", 200 }, - }; - AssertTags(expectedTags, activity.TagObjects); - } - - [Theory] - [InlineData(null, null, null, null)] - [InlineData("", "", "", null)] - [InlineData(null, "localhost:4321", "localhost", 4321)] - [InlineData(null, "localhost:1a", "localhost", null)] - [InlineData(null, "localhost", "localhost", null)] - [InlineData("http", "localhost", "localhost", 80)] - [InlineData("https", "localhost", "localhost", 443)] - public void GetHostAndPort_HostHeader_ReturnsCorrectHostAndPort(string httpSchema, string hostHeader, string expectedHost, int? expectedPort) + var expectedTags = new Dictionary { - (var host, var port) = AWSLambdaHttpUtils.GetHostAndPort(httpSchema, hostHeader); + { "http.status_code", 200 }, + }; + AssertTags(expectedTags, activity.TagObjects); + } - Assert.Equal(expectedHost, host); - Assert.Equal(expectedPort, port); - } + [Theory] + [InlineData(null, null, null, null)] + [InlineData("", "", "", null)] + [InlineData(null, "localhost:4321", "localhost", 4321)] + [InlineData(null, "localhost:1a", "localhost", null)] + [InlineData(null, "localhost", "localhost", null)] + [InlineData("http", "localhost", "localhost", 80)] + [InlineData("https", "localhost", "localhost", 443)] + public void GetHostAndPort_HostHeader_ReturnsCorrectHostAndPort(string httpSchema, string hostHeader, string expectedHost, int? expectedPort) + { + (var host, var port) = AWSLambdaHttpUtils.GetHostAndPort(httpSchema, hostHeader); + + Assert.Equal(expectedHost, host); + Assert.Equal(expectedPort, port); + } - [Theory] - [InlineData(null, "")] - [InlineData(new string[] { }, "")] - [InlineData(new[] { "value1" }, "?name=value1")] - [InlineData(new[] { "value$a" }, "?name=value%24a")] - [InlineData(new[] { "value 1" }, "?name=value+1")] - [InlineData(new[] { "value1", "value2" }, "?name=value1&name=value2")] - public void GetQueryString_APIGatewayProxyRequest_CorrectQueryString(IList values, string expectedQueryString) + [Theory] + [InlineData(null, "")] + [InlineData(new string[] { }, "")] + [InlineData(new[] { "value1" }, "?name=value1")] + [InlineData(new[] { "value$a" }, "?name=value%24a")] + [InlineData(new[] { "value 1" }, "?name=value+1")] + [InlineData(new[] { "value1", "value2" }, "?name=value1&name=value2")] + public void GetQueryString_APIGatewayProxyRequest_CorrectQueryString(IList values, string expectedQueryString) + { + var request = new APIGatewayProxyRequest(); + if (values != null) { - var request = new APIGatewayProxyRequest(); - if (values != null) + request.MultiValueQueryStringParameters = new Dictionary> { - request.MultiValueQueryStringParameters = new Dictionary> - { - { "name", values }, - }; - } + { "name", values }, + }; + } - var queryString = AWSLambdaHttpUtils.GetQueryString(request); + var queryString = AWSLambdaHttpUtils.GetQueryString(request); - Assert.Equal(expectedQueryString, queryString); - } + Assert.Equal(expectedQueryString, queryString); + } - [Theory] - [InlineData(null, "")] - [InlineData("", "")] - [InlineData("name=value1", "?name=value1")] - [InlineData("sdckj9_+", "?sdckj9_+")] - public void GetQueryString_APIGatewayHttpApiV2ProxyRequest_CorrectQueryString(string rawQueryString, string expectedQueryString) + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("name=value1", "?name=value1")] + [InlineData("sdckj9_+", "?sdckj9_+")] + public void GetQueryString_APIGatewayHttpApiV2ProxyRequest_CorrectQueryString(string rawQueryString, string expectedQueryString) + { + var request = new APIGatewayHttpApiV2ProxyRequest { - var request = new APIGatewayHttpApiV2ProxyRequest - { - RawQueryString = rawQueryString, - }; + RawQueryString = rawQueryString, + }; - var queryString = AWSLambdaHttpUtils.GetQueryString(request); + var queryString = AWSLambdaHttpUtils.GetQueryString(request); - Assert.Equal(expectedQueryString, queryString); - } + Assert.Equal(expectedQueryString, queryString); + } - private static void AssertTags(IReadOnlyDictionary expectedTags, IEnumerable> actualTags) - where TActualValue : class + private static void AssertTags(IReadOnlyDictionary expectedTags, IEnumerable> actualTags) + where TActualValue : class + { + Assert.NotNull(actualTags); + Assert.Equal(expectedTags.Count, actualTags.Count()); + foreach (var tag in expectedTags) { - Assert.NotNull(actualTags); - Assert.Equal(expectedTags.Count, actualTags.Count()); - foreach (var tag in expectedTags) - { - Assert.Contains(new KeyValuePair(tag.Key, tag.Value as TActualValue), actualTags); - } + Assert.Contains(new KeyValuePair(tag.Key, tag.Value as TActualValue), actualTags); } } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs index 7cecb57cb5..05b38aa56f 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs @@ -19,31 +19,30 @@ using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using Xunit; -namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation; + +public class CommonExtensionsTests { - public class CommonExtensionsTests + [Theory] + [InlineData("test")] + [InlineData(443)] + [InlineData(null)] + public void AddTagIfNotNull_Tag_CorrectTagsList(object tag) { - [Theory] - [InlineData("test")] - [InlineData(443)] - [InlineData(null)] - public void AddTagIfNotNull_Tag_CorrectTagsList(object tag) - { - var tags = new List>(); + var tags = new List>(); - tags.AddTagIfNotNull("tagName", tag); + tags.AddTagIfNotNull("tagName", tag); - if (tag != null) - { - Assert.Single(tags); - var actualTag = tags.First(); - Assert.Equal("tagName", actualTag.Key); - Assert.Equal(tag, actualTag.Value); - } - else - { - Assert.Empty(tags); - } + if (tag != null) + { + Assert.Single(tags); + var actualTag = tags.First(); + Assert.Equal("tagName", actualTag.Key); + Assert.Equal(tag, actualTag.Value); + } + else + { + Assert.Empty(tags); } } } From f4d4f639e500b6a8b4f164302daba8d6bed81a0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Nov 2022 14:55:24 -0700 Subject: [PATCH 0408/1499] Bump al-cheb/configure-pagefile-action from 1.2 to 1.3 (#743) --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index db3592479e..23e5e346df 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,7 +26,7 @@ jobs: steps: - name: configure Pagefile - uses: al-cheb/configure-pagefile-action@v1.2 + uses: al-cheb/configure-pagefile-action@v1.3 with: minimum-size: 8GB maximum-size: 32GB From 30eddfa36c0a7cfbaecc5ee34304534dd1925ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 2 Nov 2022 16:39:38 +0100 Subject: [PATCH 0409/1499] [Exporter.Instana] Release 1.0.1 (#749) --- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 15 ++++++--------- .../OpenTelemetry.Exporter.Instana.csproj | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 4bb688b84f..d7fc999064 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,19 +2,16 @@ ## Unreleased -## 1.0.2 - -Released 2022-Jun-02 - -* Application is chrashing if environment variables are not defined -[385](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/385) - ## 1.0.1 -Released 2022-May-25 +Released 2022-Nov-02 * Instana span duration was not calculated correctly -[376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/376) + [376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/376) +* Application is crashing if environment variables are not defined + [385](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/385) +* Update OTel SDK version to `1.3.1`. + ([#749](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/749)) ## 1.0.0 diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 2e0d58a608..769f3aed09 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -24,7 +24,7 @@ - + From 39e2c91b9cf041d2d9d9fd6154c4c07f1d16b6dd Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 2 Nov 2022 13:07:45 -0700 Subject: [PATCH 0410/1499] [Instrumentation.Process] Update OTel API version to 1.4.0-beta.2 and change runtime metrics type to ObservableUpDownCounter (#751) --- .../CHANGELOG.md | 7 +++++++ ...penTelemetry.Instrumentation.Process.csproj | 2 +- .../ProcessMetrics.cs | 9 +++------ .../README.md | 18 +++++++++--------- ...emetry.Instrumentation.Process.Tests.csproj | 2 +- .../ProcessMetricsTests.cs | 2 +- 6 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 03cb29b20e..2daf411212 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +* Update OTel API version to be `1.4.0-beta.2` and change process metrics type + from ObservableGauge to `ObservableUpDownCounter`. Updated instruments are: + "process.memory.usage", "process.memory.virtual" and "process.threads". + ([#751](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/751)) + ## 0.1.0-alpha.1 Released 2022-Oct-14 diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index cdf19e7ebd..cbe0817b60 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index b67327dd43..2e1564764c 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -38,8 +38,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) this.lastCollectedUserProcessorTime = Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; this.lastCollectedPrivilegedProcessorTime = Diagnostics.Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; - // TODO: change to ObservableUpDownCounter - this.MeterInstance.CreateObservableGauge( + this.MeterInstance.CreateObservableUpDownCounter( "process.memory.usage", () => { @@ -48,8 +47,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "By", description: "The amount of physical memory allocated for this process."); - // TODO: change to ObservableUpDownCounter - this.MeterInstance.CreateObservableGauge( + this.MeterInstance.CreateObservableUpDownCounter( "process.memory.virtual", () => { @@ -81,8 +79,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "1", description: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process."); - // TODO: change to ObservableUpDownCounter - this.MeterInstance.CreateObservableGauge( + this.MeterInstance.CreateObservableUpDownCounter( "process.threads", () => { diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 7ad6d59a1f..b73b99e3d8 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -49,9 +49,9 @@ complete demo. The amount of physical memory allocated for this process. -| Units | Instrument Type | Value Type | -|-------|-------------------|------------| -| `By` | ObservableGauge | `Double` | +| Units | Instrument Type | Value Type | +|-------|-------------------------|------------| +| `By` | ObservableUpDownCounter | `Double` | The API used to retrieve the value is: @@ -64,9 +64,9 @@ allocated for the associated process. The amount of virtual memory allocated for this process that cannot be shared with other processes. -| Units | Instrument Type | Value Type | -|-------|-------------------|------------| -| `By` | ObservableGauge | `Double` | +| Units | Instrument Type | Value Type | +|-------|-------------------------|------------| +| `By` | ObservableUpDownCounter | `Double` | The API used to retrieve the value is: @@ -111,9 +111,9 @@ Gets the privileged processor time for this process. Process threads count. -| Units | Instrument Type | Value Type | -|-----------------|-------------------|------------| -| `{threads}` | ObservableGauge | `Int32` | +| Units | Instrument Type | Value Type | +|------------|-------------------------|------------| +| `{threads}`| ObservableUpDownCounter | `Int32` | The API used to retrieve the value is: diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 031dce0c55..b2d137e5b4 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -8,7 +8,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 451ab51dd3..c1dbd3e72b 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -158,7 +158,7 @@ private static double GetValue(Metric metric) { if (metric.MetricType.IsLong()) { - sum += metricPoint.GetGaugeLastValueLong(); + sum += metricPoint.GetSumLong(); } } From d4bd617316afc0c85e80ac18cbe69f2c2045afbe Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 2 Nov 2022 15:11:20 -0700 Subject: [PATCH 0411/1499] Add vars for OpenTelemetryCoreLatestPreRelease and OpenTelemetryExporterInMemoryLatestPreReleasePkgVer. (#752) --- build/Common.nonprod.props | 3 ++- build/Common.props | 1 + .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../OpenTelemetry.Instrumentation.Process.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 2 +- 8 files changed, 9 insertions(+), 7 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index a7bbb51661..c87dfe6428 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -27,8 +27,9 @@ [16.11.0,17.0) [4.17.2,5.0) $(OpenTelemetryCoreLatestVersion) + $(OpenTelemetryCoreLatestPrereleaseVersion) [2.4.3,3.0) [2.4.2,3.0) - + diff --git a/build/Common.props b/build/Common.props index e50a2cf7bb..47484919ec 100644 --- a/build/Common.props +++ b/build/Common.props @@ -33,6 +33,7 @@ [3.3.3] [1.1.1,2.0) [1.3.1,2.0) + [1.4.0-beta.2] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 4f7f6b7b96..bcf84eb7bc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index cbe0817b60..55392a4848 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 733d5a2694..c60b35ec43 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index ddbb67ecd0..ab8a17d397 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -31,7 +31,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index b2d137e5b4..e238dd83df 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -8,7 +8,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 73f64ecfbe..42a37927ab 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -8,7 +8,7 @@ - + all From 005fdb71b709d5eefbc8c5b7fa5a2c3f14fddecf Mon Sep 17 00:00:00 2001 From: Christian Prochnow Date: Fri, 4 Nov 2022 19:37:52 +0100 Subject: [PATCH 0412/1499] [Instrumentation.Hangfire] Added support for custom job display names (#756) * Added support for custom job display names * Move JOB prefix to DisplayNameFunc. * Added entry to CHANGELOG.md * Fixed missing period in API docs. --- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 ++ .../CHANGELOG.md | 3 +++ .../HangfireInstrumentationOptions.cs | 12 +++++++++++ .../Implementation/HangfireInstrumentation.cs | 8 +++++++ ...ngfireInstrumentationJobFilterAttribute.cs | 8 ++++++- ...eInstrumentationJobFilterAttributeTests.cs | 21 +++++++++++++++++++ 6 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 15f3ca1d06..f5f2649209 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,6 @@ OpenTelemetry.Trace.HangfireInstrumentationOptions +OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.get -> System.Func +OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.set -> void OpenTelemetry.Trace.HangfireInstrumentationOptions.HangfireInstrumentationOptions() -> void OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index fec9b5658e..03bb6fff97 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add support for custom job display names + ([#756](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/756)) + ## 1.0.0-beta.3 Released 2022-Oct-26 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs index 94d14f569d..d08bd5a4f7 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs @@ -14,6 +14,10 @@ // limitations under the License. // +using System; +using Hangfire; +using OpenTelemetry.Instrumentation.Hangfire.Implementation; + namespace OpenTelemetry.Trace; /// @@ -28,4 +32,12 @@ public class HangfireInstrumentationOptions /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. /// public bool RecordException { get; set; } + + /// + /// Gets or sets a delegate used to format the job name. + /// + /// + /// Defaults to {backgroundJob.Job.Type.Name}.{backgroundJob.Job.Method.Name}. + /// + public Func DisplayNameFunc { get; set; } = HangfireInstrumentation.DefaultDisplayNameFunc; } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index 0fc54b23f3..c58d8d1c91 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using Hangfire; + namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; using System; @@ -41,4 +43,10 @@ internal static class HangfireInstrumentation /// The activity source. /// internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + + /// + /// The default display name delegate. + /// + internal static readonly Func DefaultDisplayNameFunc = + backgroundJob => $"JOB {backgroundJob.Job.Type.Name}.{backgroundJob.Job.Method.Name}"; } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 97e871309b..e74f1aa848 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -14,6 +14,9 @@ // limitations under the License. // +using System; +using Hangfire; + namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; using System.Collections.Generic; @@ -56,7 +59,10 @@ public void OnPerforming(PerformingContext performingContext) if (activity != null) { - activity.DisplayName = $"JOB {performingContext.BackgroundJob.Job.Type.Name}.{performingContext.BackgroundJob.Job.Method.Name}"; + Func displayNameFunc = + this.options.DisplayNameFunc ?? HangfireInstrumentation.DefaultDisplayNameFunc; + + activity.DisplayName = displayNameFunc(performingContext.BackgroundJob); if (activity.IsAllDataRequested) { diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index 3c8920c64c..c1d6ff13b8 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -128,6 +128,27 @@ public async Task Should_Create_Activity_Without_Exception_Event_When_Job_Failed Assert.Empty(activity.Events); } + [Fact] + public async Task Should_Create_Activity_With_Custom_DisplayName() + { + // Arrange + var exportedItems = new List(); + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => options.DisplayNameFunc = backgroundJob => $"JOB {backgroundJob.Id}") + .AddInMemoryExporter(exportedItems) + .Build(); + + // Act + var jobId = BackgroundJob.Enqueue(x => x.Execute()); + await this.WaitJobProcessedAsync(jobId, 5); + + // Assert + Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); + var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Contains($"JOB {jobId}", activity.DisplayName); + Assert.Equal(ActivityKind.Internal, activity.Kind); + } + private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) { var timeout = DateTime.Now.AddSeconds(timeToWaitInSeconds); From 83959fbf69954283ba7ea67440cdcca6bac3a2d5 Mon Sep 17 00:00:00 2001 From: Furer Alexander Date: Wed, 9 Nov 2022 23:23:34 +0200 Subject: [PATCH 0413/1499] [OpenTelemetry.Extensions] Upgrade OpenTelemetry to latest1.4.0-beta.2 (#680) --- src/OpenTelemetry.Extensions/CHANGELOG.md | 7 +++- .../ActivityEventAttachingLogProcessor.cs | 3 +- .../OpenTelemetry.Extensions.csproj | 2 +- ...ActivityEventAttachingLogProcessorTests.cs | 40 ++++++++----------- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index b71c68bdca..fe60b027f7 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,12 +2,17 @@ ## Unreleased +## 1.0.0-beta.4 + +* Update OpenTelemetry to 1.4.0-beta.2 ([#680](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/680)) + * Implemented auto flush activity processor ([#297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/297)) + * Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is .NET 4.6.2. - * Removes net5.0 target as .NET 5.0 is going out +* Removes net5.0 target as .NET 5.0 is going out of support. The package keeps netstandard2.0 target, so it can still be used with .NET5.0 apps. ([#617](https://github.com/open-telemetry/opentelemetry-dotnet/pull/617)) diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index 618c0749d1..ffaf8a75cb 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -61,8 +61,6 @@ public override void OnEnd(LogRecord data) tags[nameof(data.EventId)] = data.EventId; } - var activityEvent = new ActivityEvent("log", data.Timestamp, tags); - data.ForEachScope(ProcessScope, new State(tags, this)); if (data.StateValues != null) @@ -84,6 +82,7 @@ public override void OnEnd(LogRecord data) tags[nameof(data.FormattedMessage)] = data.FormattedMessage; } + var activityEvent = new ActivityEvent("log", data.Timestamp, tags); activity.AddEvent(activityEvent); if (data.Exception != null) diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 2595e97bb1..e2ddc363b9 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -16,7 +16,7 @@ - + diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 25dbbb6f8e..ee0e28f688 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -32,9 +32,6 @@ public sealed class ActivityEventAttachingLogProcessorTests : IDisposable ShouldListenTo = source => true, }; - private readonly ILogger logger; - private readonly ILoggerFactory loggerFactory; - private OpenTelemetryLoggerOptions options; private bool sampled; public ActivityEventAttachingLogProcessorTests() @@ -47,25 +44,12 @@ public ActivityEventAttachingLogProcessorTests() }; ActivitySource.AddActivityListener(this.activityListener); - - this.loggerFactory = LoggerFactory.Create(builder => - { - builder.AddOpenTelemetry(options => - { - this.options = options; - options.AttachLogsToActivityEvent(); - }); - builder.AddFilter(typeof(ActivityEventAttachingLogProcessorTests).FullName, LogLevel.Trace); - }); - - this.logger = this.loggerFactory.CreateLogger(); } public void Dispose() { this.activitySource.Dispose(); this.activityListener.Dispose(); - this.loggerFactory.Dispose(); } [Theory] @@ -82,24 +66,34 @@ public void AttachLogsToActivityEventTest( bool recordException = false) { this.sampled = sampled; - this.options.IncludeFormattedMessage = includeFormattedMessage; - this.options.ParseStateValues = parseStateValues; - this.options.IncludeScopes = includeScopes; + using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => + { + builder.AddOpenTelemetry(options => + { + options.IncludeScopes = includeScopes; + options.IncludeFormattedMessage = includeFormattedMessage; + options.ParseStateValues = parseStateValues; + options.AttachLogsToActivityEvent(); + }); + builder.AddFilter(typeof(ActivityEventAttachingLogProcessorTests).FullName, LogLevel.Trace); + }); + + ILogger logger = loggerFactory.CreateLogger(); Activity activity = this.activitySource.StartActivity("Test"); - using IDisposable scope = this.logger.BeginScope("{NodeId}", 99); + using IDisposable scope = logger.BeginScope("{NodeId}", 99); - this.logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); + logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); Activity innerActivity = null; if (recordException) { innerActivity = this.activitySource.StartActivity("InnerTest"); - using IDisposable innerScope = this.logger.BeginScope("{RequestId}", "1234"); + using IDisposable innerScope = logger.BeginScope("{RequestId}", "1234"); - this.logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); + logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); innerActivity.Dispose(); } From b5adc2a058279e22ba7af70e07e5f82ed129c342 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 9 Nov 2022 13:48:17 -0800 Subject: [PATCH 0414/1499] Update MinVer tag prefix (#764) --- src/OpenTelemetry.Extensions/CHANGELOG.md | 6 +++--- .../OpenTelemetry.Extensions.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index fe60b027f7..6ef75c6144 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,7 +2,9 @@ ## Unreleased -## 1.0.0-beta.4 +## 1.0.0-beta.3 + +Released 2022-Nov-09 * Update OpenTelemetry to 1.4.0-beta.2 ([#680](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/680)) @@ -17,8 +19,6 @@ can still be used with .NET5.0 apps. ([#617](https://github.com/open-telemetry/opentelemetry-dotnet/pull/617)) -## 1.0.0-beta.3 - * Going forward the NuGet package will be [`OpenTelemetry.Extensions`](https://www.nuget.org/packages/OpenTelemetry.Extensions). Older versions will remain at diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index e2ddc363b9..69f9513030 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -4,7 +4,7 @@ net462;netstandard2.0 $(TargetFrameworks);net6.0 OpenTelemetry .NET SDK preview features and extensions - Preview- + Extensions- enable true true From 82b03eef021c02b8bf6cc50aa0b9cc1021c56d90 Mon Sep 17 00:00:00 2001 From: Norm Johanson Date: Thu, 10 Nov 2022 10:30:11 -0800 Subject: [PATCH 0415/1499] Update CHANGELOG for 1.0.2 (#765) --- src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md index 1ef8260da8..3962068ec6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.2 + +Released 2022-Nov-11 + * Fixed issue when using version 3.7.100 of the AWS SDK for .NET triggering an EndpointResolver not found exception. ([#726](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/726)) From 60f9941560c9ad3d39ced083900fe631efb8f90e Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 10 Nov 2022 16:27:16 -0800 Subject: [PATCH 0416/1499] Combine Windows and Linux CI Workflows (#735) --- .../workflows/{linux-ci-md.yml => ci-md.yml} | 6 +--- .github/workflows/{windows-ci.yml => ci.yml} | 15 ++++++--- .github/workflows/linux-ci.yml | 32 ------------------- .github/workflows/windows-ci-md.yml | 25 --------------- opentelemetry-dotnet-contrib.sln | 6 ++-- 5 files changed, 13 insertions(+), 71 deletions(-) rename .github/workflows/{linux-ci-md.yml => ci-md.yml} (88%) rename .github/workflows/{windows-ci.yml => ci.yml} (56%) delete mode 100644 .github/workflows/linux-ci.yml delete mode 100644 .github/workflows/windows-ci-md.yml diff --git a/.github/workflows/linux-ci-md.yml b/.github/workflows/ci-md.yml similarity index 88% rename from .github/workflows/linux-ci-md.yml rename to .github/workflows/ci-md.yml index cec69098ec..7e3de1275d 100644 --- a/.github/workflows/linux-ci-md.yml +++ b/.github/workflows/ci-md.yml @@ -5,7 +5,7 @@ # IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow. -name: Linux +name: Build on: pull_request: @@ -17,9 +17,5 @@ jobs: build-test: runs-on: ubuntu-latest - strategy: - matrix: - version: [netcoreapp3.1,net6.0] - steps: - run: 'echo "No build required"' diff --git a/.github/workflows/windows-ci.yml b/.github/workflows/ci.yml similarity index 56% rename from .github/workflows/windows-ci.yml rename to .github/workflows/ci.yml index 541d0b6414..8c6058fa3d 100644 --- a/.github/workflows/windows-ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: Windows +name: Build on: push: @@ -12,13 +12,18 @@ on: jobs: build-test: - runs-on: windows-latest + strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - version: [net462,netcoreapp3.1,net6.0] + os: [ windows-latest, ubuntu-latest ] + version: [ net462, netcoreapp3.1, net6.0 ] + exclude: + - os: ubuntu-latest + version: net462 + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -29,4 +34,4 @@ jobs: run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **\bin\**\${{ matrix.version }}\*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" + run: dotnet test **/bin/**/${{ matrix.version }}/*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" diff --git a/.github/workflows/linux-ci.yml b/.github/workflows/linux-ci.yml deleted file mode 100644 index 4bf4d64b68..0000000000 --- a/.github/workflows/linux-ci.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Linux - -on: - push: - branches: [ main ] - paths-ignore: - - '**.md' - pull_request: - branches: [ main ] - paths-ignore: - - '**.md' - -jobs: - build-test: - runs-on: ubuntu-latest - - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - version: [netcoreapp3.1,net6.0] - - steps: - - uses: actions/checkout@v3 - - - name: Install dependencies - run: dotnet restore - - - name: Build - run: dotnet build --configuration Release --no-restore - - - name: Test ${{ matrix.version }} - run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" diff --git a/.github/workflows/windows-ci-md.yml b/.github/workflows/windows-ci-md.yml deleted file mode 100644 index 2e2bfd561a..0000000000 --- a/.github/workflows/windows-ci-md.yml +++ /dev/null @@ -1,25 +0,0 @@ -# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions -# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks - -# Description: This workflow exists to unblock documentation-only PRs. - -# IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow. - -name: Windows - -on: - pull_request: - branches: [ main ] - paths: - - '**.md' - -jobs: - build-test: - runs-on: ubuntu-latest - - strategy: - matrix: - version: [net462,netcoreapp3.1,net6.0] - - steps: - - run: 'echo "No build required"' diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index d0925d4c72..22903a6b99 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -27,13 +27,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml + .github\workflows\ci-md.yml = .github\workflows\ci-md.yml + .github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\integration-md.yml = .github\workflows\integration-md.yml .github\workflows\integration.yml = .github\workflows\integration.yml - .github\workflows\linux-ci-md.yml = .github\workflows\linux-ci-md.yml - .github\workflows\linux-ci.yml = .github\workflows\linux-ci.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml @@ -63,8 +63,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml - .github\workflows\windows-ci-md.yml = .github\workflows\windows-ci-md.yml - .github\workflows\windows-ci.yml = .github\workflows\windows-ci.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE-3FA8-4FE0-823A-FD365EAC78AF}" From edae331d35a65249347bd4556b3ed16d71463184 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Thu, 10 Nov 2022 17:45:28 -0800 Subject: [PATCH 0417/1499] [Instrumentation.EventCounters] Support long event source names better in EventCounters instrumentation (#740) * Support long event source names better in EventCounters instrumentation --- .../CHANGELOG.md | 3 + .../EventCountersMetrics.cs | 39 +++++++++- .../EventCountersMetricsTests.cs | 78 +++++++++++++++++-- 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index f3f36b2d94..f58d0aeb96 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -3,6 +3,9 @@ ## Unreleased * Update OpenTelemetry.Api to 1.3.1. +* Change `EventCounter` prefix to `ec` and trim the event source name to keep + instrument name under 63 characters. + ([#740](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/740)) ## 1.0.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index c236463144..fe8f89dacc 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -29,6 +29,9 @@ internal sealed class EventCountersMetrics : EventListener { internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, typeof(EventCountersMetrics).Assembly.GetName().Version.ToString()); + private const string Prefix = "ec"; + private const int MaxInstrumentNameLength = 63; + private readonly EventCountersInstrumentationOptions options; private readonly List preInitEventSources = new(); private readonly ConcurrentDictionary<(string, string), Instrument> instruments = new(); @@ -120,6 +123,39 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) private static Dictionary GetEnableEventsArguments(EventCountersInstrumentationOptions options) => new() { { "EventCounterIntervalSec", options.RefreshIntervalSecs.ToString() } }; + /// + /// If the resulting instrument name is too long, it trims the event source name + /// to fit in as many characters as possible keeping the event name intact. + /// E.g. instrument for `Microsoft-AspNetCore-Server-Kestrel`, `tls-handshakes-per-second` + /// would be too long (64 chars), so it's shortened to `ec.Microsoft-AspNetCore-Server-Kestre.tls-handshakes-per-second`. + /// + /// If there is no room for event source name, returns `ec.{event name}` and + /// if it's still too long, it will be validated and ignored later in the pipeline. + /// + private static string GetInstrumentName(string sourceName, string eventName) + { + int totalLength = Prefix.Length + 1 + sourceName.Length + 1 + eventName.Length; + if (totalLength <= MaxInstrumentNameLength) + { + return string.Concat(Prefix, ".", sourceName, ".", eventName); + } + + var maxEventSourceLength = MaxInstrumentNameLength - Prefix.Length - 2 - eventName.Length; + if (maxEventSourceLength < 1) + { + // event name is too long, there is not enough space for sourceName. + // let ec. flow to metrics SDK and it will suppress it if needed. + return string.Concat(Prefix, ".", eventName); + } + + while (maxEventSourceLength > 0 && (sourceName[maxEventSourceLength - 1] == '.' || sourceName[maxEventSourceLength - 1] == '-')) + { + maxEventSourceLength--; + } + + return string.Concat(Prefix, ".", sourceName.Substring(0, maxEventSourceLength), ".", eventName); + } + private void EnableEvents(EventSource eventSource) { this.EnableEvents(eventSource, EventLevel.Critical, EventKeywords.None, GetEnableEventsArguments(this.options)); @@ -132,10 +168,9 @@ private void UpdateInstrumentWithEvent(bool isGauge, string eventSourceName, str ValueTuple metricKey = new(eventSourceName, name); _ = this.values.AddOrUpdate(metricKey, value, isGauge ? (_, _) => value : (_, existing) => existing + value); - var instrumentName = $"EventCounters.{eventSourceName}.{name}"; - if (!this.instruments.ContainsKey(metricKey)) { + var instrumentName = GetInstrumentName(eventSourceName, name); Instrument instrument = isGauge ? MeterInstance.CreateObservableGauge(instrumentName, () => this.values[metricKey]) : MeterInstance.CreateObservableCounter(instrumentName, () => this.values[metricKey]); diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 26beba4deb..dba23b470f 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.Tracing; +using System.Linq; using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; @@ -68,7 +69,7 @@ public async Task EventCounter() meterProvider.ForceFlush(); // Assert - var metric = metricItems.Find(x => x.Name == "EventCounters.a.c"); + var metric = metricItems.Find(x => x.Name == "ec.a.c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleGauge, metric.MetricType); Assert.Equal(1997.0202, GetActualValue(metric)); @@ -98,7 +99,7 @@ public async Task IncrementingEventCounter() meterProvider.ForceFlush(); // Assert - var metric = metricItems.Find(x => x.Name == "EventCounters.b.inc-c"); + var metric = metricItems.Find(x => x.Name == "ec.b.inc-c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleSum, metric.MetricType); Assert.Equal(3, GetActualValue(metric)); @@ -126,7 +127,7 @@ public async Task PollingCounter() meterProvider.ForceFlush(); // Assert - var metric = metricItems.Find(x => x.Name == "EventCounters.c.poll-c"); + var metric = metricItems.Find(x => x.Name == "ec.c.poll-c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleGauge, metric.MetricType); Assert.Equal(20, GetActualValue(metric)); @@ -154,7 +155,7 @@ public async Task IncrementingPollingCounter() meterProvider.ForceFlush(); // Assert - var metric = metricItems.Find(x => x.Name == "EventCounters.d.inc-poll-c"); + var metric = metricItems.Find(x => x.Name == "ec.d.inc-poll-c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleSum, metric.MetricType); Assert.Equal(2, GetActualValue(metric)); @@ -184,7 +185,7 @@ public async Task EventCounterSameNameUsesNewestCreated() meterProvider.ForceFlush(); // Assert - var metric = metricItems.Find(x => x.Name == "EventCounters.a.c"); + var metric = metricItems.Find(x => x.Name == "ec.a.c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleGauge, metric.MetricType); @@ -214,6 +215,73 @@ public void ThrowExceptionForUnsupportedEventSources() Assert.Equal("Use the `OpenTelemetry.Instrumentation.Runtime` or `OpenTelemetry.Instrumentation.Process` instrumentations.", ex.Message); } + [Theory] + [InlineData("Microsoft-AspNetCore-Server-Kestrel-1", "tls-handshakes-per-second", "ec.Microsoft-AspNetCore-Server-Kestre.tls-handshakes-per-second")] + [InlineData("Microsoft-AspNetCore-Server-Kestrel-1", "tls-handshakes-per-sec", "ec.Microsoft-AspNetCore-Server-Kestrel-1.tls-handshakes-per-sec")] + [InlineData("Microsoft.AspNetCore.Http.Connections-1", "connections-stopped", "ec.Microsoft.AspNetCore.Http.Connections-1.connections-stopped")] + [InlineData("Microsoft.AspNetCore.Http.Connections-1", "connections-timed-out-longer", "ec.Microsoft.AspNetCore.Http.Conne.connections-timed-out-longer")] + [InlineData("Microsoft.AspNetCore.Http.Conn.Something", "connections-timed-out-longer", "ec.Microsoft.AspNetCore.Http.Conn.connections-timed-out-longer")] + [InlineData("Microsoft.AspNetCore.One.Two", "very-very-very-very-very-very-very-very-very-long-event-name", "ec.very-very-very-very-very-very-very-very-very-long-event-name")] + [InlineData("Microsoft.AspNetCore.One.Two", "very-very-very-very-very-very-very-very-long-event-name", "ec.Micr.very-very-very-very-very-very-very-very-long-event-name")] + [InlineData("Microsoft.AspNetCore.One.Two", "very-very-very-very-very-very-very-long-event-name", "ec.Microsoft.very-very-very-very-very-very-very-long-event-name")] + public async Task EventSourceNameShortening(string sourceName, string eventName, string expectedInstrumentName) + { + // Arrange + List metricItems = new(); + EventSource source = new(sourceName); + IncrementingEventCounter connections = new(eventName, source); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + connections.Increment(1); + await Task.Delay(Delay); + meterProvider.ForceFlush(); + + // Assert + Metric metric = metricItems.Find(m => m.Name == expectedInstrumentName); + Assert.NotNull(metric); + Assert.Equal(1, GetActualValue(metric)); + } + + [Fact] + public async Task InstrumentNameTooLong() + { + // Arrange + List metricItems = new(); + EventSource source = new("source"); + + // ec.s. + event name is 63; + string veryLongEventName = new string('e', 100); + IncrementingEventCounter connections = new(veryLongEventName, source); + + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(source.Name); + }) + .AddInMemoryExporter(metricItems) + .Build(); + + // Act + connections.Increment(1); + await Task.Delay(Delay); + meterProvider.ForceFlush(); + + // Assert + foreach (var item in metricItems) + { + Assert.False(item.Name.StartsWith("ec.source.ee")); + Assert.False(item.Name.StartsWith("ec.s.ee")); + } + } + // polling and eventcounter with same instrument name? private static double GetActualValue(Metric metric) From 0b1c34ee9f496934e44d0547505de0f3480f8d48 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 11 Nov 2022 14:13:31 -0800 Subject: [PATCH 0418/1499] Update CHANGELOG for 1.0.0-alpha.2 release (#768) --- src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index f58d0aeb96..5a6e7c8486 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.2 + +Released 2022-Nov-10 + * Update OpenTelemetry.Api to 1.3.1. * Change `EventCounter` prefix to `ec` and trim the event source name to keep instrument name under 63 characters. From cceb2fcc6d7a7d7d73f964e824da051207b84d84 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 11 Nov 2022 22:27:54 -0800 Subject: [PATCH 0419/1499] [Instrumentation.Process] Update .NET API for virtual memory usage (#762) * initial commit * doc * Apply suggestions from code review Co-authored-by: Noah Falk * lint * Apply suggestions from code review Co-authored-by: Utkarsh Umesan Pillai Co-authored-by: Noah Falk Co-authored-by: Utkarsh Umesan Pillai --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ .../ProcessMetrics.cs | 4 ++-- src/OpenTelemetry.Instrumentation.Process/README.md | 10 ++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 2daf411212..2b50d197a2 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Update the .NET API used to retrieve `process.memory.virtual` metric to be + `Process.VirtualMemorySize64`. + ([#762](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/762)) + * Update OTel API version to be `1.4.0-beta.2` and change process metrics type from ObservableGauge to `ObservableUpDownCounter`. Updated instruments are: "process.memory.usage", "process.memory.virtual" and "process.threads". diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 2e1564764c..b724c3d308 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -51,10 +51,10 @@ public ProcessMetrics(ProcessInstrumentationOptions options) "process.memory.virtual", () => { - return Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64; + return Diagnostics.Process.GetCurrentProcess().VirtualMemorySize64; }, unit: "By", - description: "The amount of virtual memory allocated for this process that cannot be shared with other processes."); + description: "The amount of committed virtual memory for this process."); this.MeterInstance.CreateObservableCounter( "process.cpu.time", diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index b73b99e3d8..6d3562b42a 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -61,8 +61,10 @@ allocated for the associated process. ### process.memory.virtual -The amount of virtual memory allocated for this process -that cannot be shared with other processes. +The amount of committed virtual memory for this process. +One way to think of this is all the address space this process can read from +without trigerring an access violation; this includes memory backed solely by RAM, +by a swapfile/pagefile and by other mapped files on disk. | Units | Instrument Type | Value Type | |-------|-------------------------|------------| @@ -70,8 +72,8 @@ that cannot be shared with other processes. The API used to retrieve the value is: -* [Process.WorkingSet64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privatememorysize64): -Gets the amount of private memory, in bytes, +* [Process.VirtualMemorySize64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.virtualmemorysize64): +Gets the amount of the virtual memory, in bytes, allocated for the associated process. ### process.cpu.time From f30ed06c6b4ed26988847a36b2062abd0c855dfc Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 14 Nov 2022 10:43:26 -0800 Subject: [PATCH 0420/1499] Update ci-md.yml - Add back `strategy` (#770) --- .github/workflows/ci-md.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci-md.yml b/.github/workflows/ci-md.yml index 7e3de1275d..345e969cb3 100644 --- a/.github/workflows/ci-md.yml +++ b/.github/workflows/ci-md.yml @@ -17,5 +17,13 @@ jobs: build-test: runs-on: ubuntu-latest + strategy: + matrix: + os: [ windows-latest, ubuntu-latest ] + version: [ net462, netcoreapp3.1, net6.0 ] + exclude: + - os: ubuntu-latest + version: net462 + steps: - run: 'echo "No build required"' From 187c475ef9b98431ae137bc43c341e705b71422b Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 14 Nov 2022 11:55:14 -0800 Subject: [PATCH 0421/1499] [Instrumentation.Process] Release Process instrumentation version 1.0.0-alpha.1 (#771) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 2b50d197a2..2d0a3bd796 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,8 +2,14 @@ ## Unreleased -* Update the .NET API used to retrieve `process.memory.virtual` metric to be - `Process.VirtualMemorySize64`. +## 1.0.0-alpha.1 + +Released 2022-Nov-14 + +* Update the .NET API used to retrieve `process.memory.virtual` metric from + [Process.PrivateMemorySize64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privatememorysize64) + to + [Process.VirtualMemorySize64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.virtualmemorysize64). ([#762](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/762)) * Update OTel API version to be `1.4.0-beta.2` and change process metrics type From b3a921af196d2a6ed2a42120f2aa05a9516d47d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 15 Nov 2022 18:22:27 +0100 Subject: [PATCH 0422/1499] Link fixes (#737) --- .github/workflows/markdownlint.yml | 2 +- .../CHANGELOG.md | 2 +- src/OpenTelemetry.Instrumentation.AspNet/README.md | 12 ++++++------ .../README.md | 2 +- .../README.md | 2 +- src/OpenTelemetry.Instrumentation.Quartz/README.md | 2 +- .../README.md | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 97f85f9e2b..fec61cedeb 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -16,7 +16,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v3 + uses: actions/checkout@v3.1.0 - name: install markdownlint-cli run: sudo npm install -g markdownlint-cli diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index ca186294be..d859c59e1b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -71,7 +71,7 @@ Released 2021-Oct-08 [Microsoft.AspNet.TelemetryCorrelation](https://www.nuget.org/packages/Microsoft.AspNet.TelemetryCorrelation/) to listen for incoming http requests to the process. Please see the (Step 2: Modify - Web.config)[https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.AspNet#step-2-modify-webconfig] + Web.config)[https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.AspNet#step-2-modify-webconfig] README section for details on the new HttpModule definition required. ([#2222](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2222)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 3a2ed2c1b7..aa73d15b14 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -14,7 +14,7 @@ and [traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), -and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) is released, there can be breaking changes. You can track the progress from @@ -57,8 +57,8 @@ following shows changes required to your `Web.config` when using IIS web server. ASP.NET instrumentation must be enabled at application startup. This is typically done in the `Global.asax.cs` as shown below. This example also sets up the OpenTelemetry Jaeger exporter, which requires adding the package -[`OpenTelemetry.Exporter.Jaeger`](../OpenTelemetry.Exporter.Jaeger/README.md) to -the application. +[`OpenTelemetry.Exporter.Jaeger`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Jaeger/README.md) +to the application. ```csharp using OpenTelemetry; @@ -150,9 +150,9 @@ this.tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the -general extensibility point to add additional properties to any activity. The -`Enrich` option is specific to this instrumentation, and is provided to get +[Processor](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#processor), +is the general extensibility point to add additional properties to any activity. +The `Enrich` option is specific to this instrumentation, and is provided to get access to `HttpRequest` and `HttpResponse`. ### RecordException diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md index f6067618dc..cacb56f8a1 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -64,7 +64,7 @@ x.AddMassTransitInstrumentation( })); ``` -For full operation list please see: [OperationName](../OpenTelemetry.Instrumentation.MassTransit/Implementation/OperationName.cs). +For full operation list please see: [OperationName](OperationName.cs). All operations are enabled by default. diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index ea6cb7deee..1aded70cb7 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -50,7 +50,7 @@ the `ConfigureServices` of your `Startup` class. Refer to documentation for [OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the -`Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md). +`Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). Note, If you are using `Mysql.Data` 8.0.31 or later, please add option `Logging=true` in your connection string to enable tracing. diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 6967b65841..da549407b2 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -70,7 +70,7 @@ x.AddQuartzInstrumentation( ``` For full operation list please see: -[OperationName](../OpenTelemetry.Instrumentation.Quartz/Implementation/OperationName.cs). +[OperationName](OperationName.cs). All operations are enabled by default. diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index 5b109755fb..167cae9ff4 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -13,7 +13,7 @@ and collects traces about outgoing calls to Redis. [traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), -and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) is released, there can be breaking changes. You can track the progress from @@ -42,7 +42,7 @@ to make Redis calls. Only those Redis calls made using the same instance of the The following example demonstrates adding StackExchange.Redis instrumentation to a console application. This example also sets up the OpenTelemetry Console exporter, which requires adding the package -[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) to the application. ```csharp @@ -65,7 +65,7 @@ public class Program For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for -[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). +[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). From 679d8710635b3c1e17270192293dc112871efdfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Wed, 16 Nov 2022 16:39:41 +0100 Subject: [PATCH 0423/1499] [Instrumentation.Runtime] Reintroduce current heap size metric (#683) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs | 6 ++++++ .../RuntimeMetricsTests.cs | 3 +++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 54f797597f..beecf3ca90 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -34,6 +34,9 @@ This does not affect applications targeting .NET Framework. +* Add "process.runtime.dotnet.gc.objects.size" metric + ([#683](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/683)) + ## 1.0.0 Released 2022-Aug-03 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 32bb167ea4..ef294f29bc 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -48,6 +48,12 @@ static RuntimeMetrics() () => GetGarbageCollectionCounts(), description: "Number of garbage collections that have occurred since process start."); + MeterInstance.CreateObservableUpDownCounter( + "process.runtime.dotnet.gc.objects.size", + () => GC.GetTotalMemory(false), + unit: "bytes", + description: "Count of bytes currently in use by objects in the GC heap that haven't been collected yet. Fragmentation and other GC committed memory pools are excluded."); + #if NET6_0_OR_GREATER MeterInstance.CreateObservableCounter( "process.runtime.dotnet.gc.allocations.size", diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 27d71ee87c..d9509a5411 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -75,6 +75,9 @@ public void GcMetricsTest() var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); Assert.NotNull(gcCountMetric); + var totalObjectsSize = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.objects.size"); + Assert.NotNull(totalObjectsSize); + #if NET6_0_OR_GREATER var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); From 40a3df3336b7e86c4bbab717d2f039e8dc4d2bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 17 Nov 2022 20:55:00 +0100 Subject: [PATCH 0424/1499] Enable public api analyzer by default (#773) * Enable Public Api analyzers by default --- build/Common.prod.props | 4 +- .../.publicApi/net452/PublicAPI.Shipped.txt | 21 ++++++++ .../.publicApi/net452/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 30 +++++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../.publicApi/net452/PublicAPI.Shipped.txt | 6 +++ .../.publicApi/net452/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 6 +++ .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../OpenTelemetry.Exporter.Geneva.csproj | 1 - .../.publicApi/net461/PublicAPI.Shipped.txt | 2 + .../.publicApi/net461/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 23 +++++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 23 +++++++++ .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++ .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++ .../OpenTelemetry.Extensions.Docker.csproj | 2 +- ...ions.PersistentStorage.Abstractions.csproj | 1 - .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 15 ++++++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 15 ++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 15 ++++++ .../OpenTelemetry.Extensions.csproj | 1 - ...Telemetry.Instrumentation.AWSLambda.csproj | 1 - ...entation.AspNet.TelemetryHttpModule.csproj | 1 - ...penTelemetry.Instrumentation.AspNet.csproj | 1 - ...Instrumentation.ElasticsearchClient.csproj | 1 - .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 8 +++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 7 +++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 25 ++++++++++ ...nTelemetry.Instrumentation.Hangfire.csproj | 1 - ...lemetry.Instrumentation.MassTransit.csproj | 1 - .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 10 ++++ .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 15 ++++++ ...enTelemetry.Instrumentation.Process.csproj | 1 - .../.publicApi/net472/PublicAPI.Shipped.txt | 0 .../.publicApi/net472/PublicAPI.Unshipped.txt | 14 ++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 14 ++++++ ...enTelemetry.Instrumentation.Runtime.csproj | 1 - ....Instrumentation.StackExchangeRedis.csproj | 1 - .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 50 +++++++++++++++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 32 ++++++++++++ 66 files changed, 352 insertions(+), 15 deletions(-) create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/build/Common.prod.props b/build/Common.prod.props index 91603cde24..8e855052d5 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -24,7 +24,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + @@ -53,7 +53,7 @@ - + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..1f0221c530 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt @@ -0,0 +1,21 @@ +OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator +OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void +OpenTelemetry.Resources.ResourceBuilderExtensions +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void +static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder builder, OpenTelemetry.Trace.Sampler sampler) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..29e1279fc9 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,30 @@ +OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.AWSECSResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.AWSLambdaResourceDetector() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void +OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator +OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void +OpenTelemetry.Resources.ResourceBuilderExtensions +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void +static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder builder, OpenTelemetry.Trace.Sampler sampler) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..cb88907ec0 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..cb88907ec0 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index bcf84eb7bc..3867b3e6c5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -8,7 +8,6 @@ netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- - true true diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..5b4e5bba7a --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Shipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions +static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder options) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..5b4e5bba7a --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions +static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder options) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..fa997838e5 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,23 @@ +OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string projectId) -> void +OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batchActivity) -> OpenTelemetry.ExportResult +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string projectId) -> Google.Api.MonitoredResource +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string +static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration +static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable source, int size) -> System.Collections.Generic.IEnumerable> +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string projectId) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..fa997838e5 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,23 @@ +OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string projectId) -> void +OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batchActivity) -> OpenTelemetry.ExportResult +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string projectId) -> Google.Api.MonitoredResource +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string +static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration +static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable source, int size) -> System.Collections.Generic.IEnumerable> +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string projectId) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..f3fcff5f07 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(float samplingRatio) -> void +override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..f3fcff5f07 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(float samplingRatio) -> void +override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..f3fcff5f07 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(float samplingRatio) -> void +override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..dd82aed623 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..dd82aed623 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj index 3eb8b7868a..b38ee0a275 100644 --- a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj +++ b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj @@ -1,6 +1,6 @@ - ;net462;netstandard2.0 + net462;netstandard2.0 OpenTelemetry Extensions - Container Resource Detector from Docker environment. Extensions.Docker- diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj index 9aaa8920c3..eaa49f4591 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -13,7 +13,6 @@ $(NoWarn),1591 enable true - true diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..3f30e4159b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Extensions.PersistentStorage.FileBlob +OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryRead(out byte[] buffer) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..3f30e4159b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Extensions.PersistentStorage.FileBlob +OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryRead(out byte[] buffer) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..3f30e4159b --- /dev/null +++ b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Extensions.PersistentStorage.FileBlob +OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void +OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryRead(out byte[] buffer) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 69f9513030..e0168edc63 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -7,7 +7,6 @@ Extensions- enable true - true diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 4afae25088..14a98b2675 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -5,7 +5,6 @@ AWS Lambda tracing wrapper for OpenTelemetry .NET $(PackageTags);AWS Lambda Instrumentation.AWSLambda- - true diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index da7cfcfe8f..e84816eca4 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -5,7 +5,6 @@ A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI Instrumentation.AspNet.TelemetryHttpModule- - true diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index ea25e6d359..6cac679253 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -6,7 +6,6 @@ $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true Instrumentation.AspNet- - true diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index a9b531ca62..9d8f512ec9 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -5,7 +5,6 @@ $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- true - true diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..5cbec75d76 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EntityFrameworkInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.get -> bool +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.get -> bool +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7321915c50 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,7 @@ +OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions +OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions.AddEventSources(params string![]! names) -> void +OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions.EventCountersInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions.RefreshIntervalSecs.get -> int +OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions.RefreshIntervalSecs.set -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddEventCountersInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..f14acd39b0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,25 @@ +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.ClientTracingInterceptor(OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions options) -> void +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.ClientTracingInterceptorOptions() -> void +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.Propagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.RecordMessageEvents.get -> bool +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.RecordMessageEvents.set -> void +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ServerTracingInterceptor(OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions options) -> void +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.Propagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.RecordMessageEvents.get -> bool +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.RecordMessageEvents.set -> void +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.ServerTracingInterceptorOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncClientStreamingCall(Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncClientStreamingCallContinuation continuation) -> Grpc.Core.AsyncClientStreamingCall +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncDuplexStreamingCall(Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncDuplexStreamingCallContinuation continuation) -> Grpc.Core.AsyncDuplexStreamingCall +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncServerStreamingCall(TRequest request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncServerStreamingCallContinuation continuation) -> Grpc.Core.AsyncServerStreamingCall +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncUnaryCall(TRequest request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncUnaryCallContinuation continuation) -> Grpc.Core.AsyncUnaryCall +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.BlockingUnaryCall(TRequest request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.BlockingUnaryCallContinuation continuation) -> TResponse +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ClientStreamingServerHandler(Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.ServerCallContext context, Grpc.Core.ClientStreamingServerMethod continuation) -> System.Threading.Tasks.Task +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.DuplexStreamingServerHandler(Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context, Grpc.Core.DuplexStreamingServerMethod continuation) -> System.Threading.Tasks.Task +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ServerStreamingServerHandler(TRequest request, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context, Grpc.Core.ServerStreamingServerMethod continuation) -> System.Threading.Tasks.Task +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.UnaryServerHandler(TRequest request, Grpc.Core.ServerCallContext context, Grpc.Core.UnaryServerMethod continuation) -> System.Threading.Tasks.Task +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index d0062d2c6e..33a91b03ee 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -5,7 +5,6 @@ $(PackageTags);Hangfire Instrumentation.Hangfire- false - true diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj index d1a65cfa05..6c93d09294 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj @@ -5,7 +5,6 @@ $(PackageTags);distributed-tracing;MassTransit Instrumentation.MassTransit- true - true diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..439673d005 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,10 @@ +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.EnableConnectionLevelAttributes.get -> bool +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.EnableConnectionLevelAttributes.set -> void +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.MySqlDataInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.get -> bool +OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureMySqlDataInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..028f956bd4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType +OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType.BeginRequest = 0 -> OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType +OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType.EndRequest = 1 -> OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Filter.set -> void +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.OwinInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +Owin.AppBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureOwinInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static Owin.AppBuilderExtensions.UseOpenTelemetry(this Owin.IAppBuilder appBuilder) -> Owin.IAppBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index 55392a4848..b4129cc23e 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -5,7 +5,6 @@ $(PackageTags);process Instrumentation.Process- true - true diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..01e290fd0d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt @@ -0,0 +1,14 @@ +const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Execute = "Quartz.Job.Execute" -> string +const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Veto = "Quartz.Job.Veto" -> string +OpenTelemetry.Instrumentation.Quartz.OperationName +OpenTelemetry.Instrumentation.Quartz.OperationName.Job +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.QuartzInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.set -> void +OpenTelemetry.Trace.TraceProviderBuilderExtensions +static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureQuartzInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..01e290fd0d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,14 @@ +const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Execute = "Quartz.Job.Execute" -> string +const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Veto = "Quartz.Job.Veto" -> string +OpenTelemetry.Instrumentation.Quartz.OperationName +OpenTelemetry.Instrumentation.Quartz.OperationName.Job +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.QuartzInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.set -> void +OpenTelemetry.Trace.TraceProviderBuilderExtensions +static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureQuartzInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index c60b35ec43..d950ce70ab 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,7 +5,6 @@ $(PackageTags);runtime Instrumentation.Runtime- true - true diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index be106c8cf2..f71bb62aff 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -6,7 +6,6 @@ $(PackageTags);distributed-tracing;Redis;StackExchange.Redis true Instrumentation.StackExchangeRedis- - true diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4415915fff --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,50 @@ +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveRequest = "AfterReceiveRequest" -> string +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendReply = "BeforeSendReply" -> string +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string +OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector +OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) -> object +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.TelemetryContractBehaviorAttribute() -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryDispatchMessageInspector +OpenTelemetry.Instrumentation.Wcf.TelemetryDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) -> object +OpenTelemetry.Instrumentation.Wcf.TelemetryDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.TelemetryEndpointBehavior() -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.TelemetryEndpointBehaviorExtensionElement() -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.TelemetryServiceBehavior() -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.Validate(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.TelemetryServiceBehaviorExtensionElement() -> void +OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.get -> bool +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.WcfInstrumentationOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.BehaviorType.get -> System.Type +override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.CreateBehavior() -> object +override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.BehaviorType.get -> System.Type +override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.CreateBehavior() -> object +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..b0b243ca1e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,32 @@ +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string +OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector +OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) -> object +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.TelemetryContractBehaviorAttribute() -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.TelemetryEndpointBehavior() -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.get -> bool +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.WcfInstrumentationOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file From 23dbc397842001e110ea668a4bb6082456294f24 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 17 Nov 2022 16:21:32 -0500 Subject: [PATCH 0425/1499] restore Activity.Current before all IIS LifeCycle events (#761) --- .../CHANGELOG.md | 3 +++ .../TelemetryHttpModule.cs | 7 +------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index bd3006b278..5d81a5b705 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Restore Activity.Current before all IIS Lifecycle events + ([#761](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/761)) + ## 1.0.0-rc9.6 Released 2022-Sep-28 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index 4df4fb4366..62a45ef49d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -84,12 +84,7 @@ private void Application_BeginRequest(object sender, EventArgs e) private void OnExecuteRequestStep(HttpContextBase context, Action step) { // Called only on 4.7.1+ runtimes - - if (context.CurrentNotification == RequestNotification.ExecuteRequestHandler && !context.IsPostNotification) - { - ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context); - } - + ActivityHelper.RestoreContextIfNeeded(context.ApplicationInstance.Context); step(); } From 108843c3eceeac53628e74739b0e6e1005c78606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 17 Nov 2022 23:40:44 +0100 Subject: [PATCH 0426/1499] Fix prerelease reference and bump OTel to 1.4.0-beta.3 (#774) * Fix prerelease reference and bump OTel to 1.4.0-beta.3 --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 2 ++ .../Metrics/GenevaMetricExporter.cs | 6 +++--- src/OpenTelemetry.Extensions/CHANGELOG.md | 2 ++ .../CHANGELOG.md | 2 ++ .../CHANGELOG.md | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 12 ++++++------ .../GenevaMetricExporterTests.cs | 11 +++-------- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/build/Common.props b/build/Common.props index 47484919ec..3672da0751 100644 --- a/build/Common.props +++ b/build/Common.props @@ -33,7 +33,7 @@ [3.3.3] [1.1.1,2.0) [1.3.1,2.0) - [1.4.0-beta.2] + [1.4.0-beta.3] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 6196a7b3df..2176d34d85 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) + ## 1.4.0-beta.4 Released 2022-Oct-28 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index c02b5f6080..e056efa218 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -203,10 +203,10 @@ public override ExportResult Export(in Batch batch) var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); MetricData min = ulongZero; MetricData max = ulongZero; - if (metricPoint.HasMinMax()) + if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) { - min = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMin()) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMax()) }; + min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; } var bodyLength = this.SerializeHistogramMetric( diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 6ef75c6144..33a35b6a0b 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) + ## 1.0.0-beta.3 Released 2022-Nov-09 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 2d0a3bd796..7e09b9b5bd 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) + ## 1.0.0-alpha.1 Released 2022-Nov-14 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index beecf3ca90..2f80020074 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* Update OTel API version to `1.4.0-beta.2`. +* Update OpenTelemetry API to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) * Change ObservableGauge to ObservableUpDownCounter for the below metrics (which better fit UpDownCounter semantics as they are additive.) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 037bca4755..ecadc44be7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -329,10 +329,10 @@ private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData su min = new MetricData { UInt64Value = 0 }; max = new MetricData { UInt64Value = 0 }; - if (metricPoint.HasMinMax()) + if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) { - min = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMin()) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMax()) }; + min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; } return metricPoint; @@ -379,10 +379,10 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData su min = new MetricData { UInt64Value = 0 }; max = new MetricData { UInt64Value = 0 }; - if (metricPoint.HasMinMax()) + if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) { - min = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMin()) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramMax()) }; + min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; } return metricPoint; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 4e5f841e6d..5448566160 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -730,18 +730,13 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - ulong minValue = 0; - ulong maxValue = 0; var min = new MetricData { UInt64Value = 0 }; var max = new MetricData { UInt64Value = 0 }; - if (metricPoint.HasMinMax()) + if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) { - minValue = Convert.ToUInt64(metricPoint.GetHistogramMin()); - maxValue = Convert.ToUInt64(metricPoint.GetHistogramMax()); - - min = new MetricData { UInt64Value = minValue }; - max = new MetricData { UInt64Value = maxValue }; + min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; + max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; } var bodyLength = exporter.SerializeHistogramMetric( From 049f88f7032784dafddf686515cfea811f3a6bc2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 18 Nov 2022 10:34:35 -0800 Subject: [PATCH 0427/1499] Fix build badge to use the new workflow (#776) --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 20f73f6fc0..0bef2e1765 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # OpenTelemetry .NET Contrib [![Slack](https://img.shields.io/badge/slack-@cncf/otel/dotnet-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01N3BC2W7Q) -[![Linux](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/linux-ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/linux-ci.yml) -[![Windows](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/windows-ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/windows-ci.yml) +[![Build](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/ci.yml) This project is intended to provide helpful libraries and standalone OpenTelemetry-based utilities that don't fit the express scope of the From 2658fd07fabbaadc14368e6bcf7fa5affebcf67a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 18 Nov 2022 20:20:41 +0100 Subject: [PATCH 0428/1499] [Instrumentation.Process] Release 1.0.0-alpha.2 (#777) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 7e09b9b5bd..cfe33c8cd1 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.2 + +Released 2022-Nov-18 + * Update OpenTelemetry API to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) ## 1.0.0-alpha.1 From d4688fc364607ba77717c7c2c7e80b02e90b4c50 Mon Sep 17 00:00:00 2001 From: Alexander Batishchev Date: Mon, 21 Nov 2022 11:30:52 -0800 Subject: [PATCH 0429/1499] [Exporter.Geneva] Release 1.4.0-beta.5 (#781) * Update CHANGELOG.md --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 2176d34d85..c0cd43b32f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-beta.5 + +Released 2022-Nov-21 + * Update OpenTelemetry to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) ## 1.4.0-beta.4 From 0834638a877fe73ef3737102a39b03cc2016b483 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 21 Nov 2022 14:05:15 -0800 Subject: [PATCH 0430/1499] add NET7 to CI and tests (#759) * add net7 to CI and tests --- .github/workflows/ci-md.yml | 2 +- .github/workflows/ci.yml | 6 +++++- .github/workflows/dotnet-core-cov.yml | 4 ++++ .github/workflows/dotnet-format.yml | 5 ----- .github/workflows/integration-md.yml | 2 +- .github/workflows/integration.yml | 2 +- build/docker-compose.net7.0.yml | 8 ++++++++ .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 5 +++-- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 5 +++-- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 5 +++-- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 3 ++- .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 5 +++-- .../OpenTelemetry.Extensions.Docker.Tests.csproj | 3 ++- ...penTelemetry.Extensions.PersistentStorage.Tests.csproj | 3 ++- .../OpenTelemetry.Extensions.Tests.csproj | 3 ++- ...metry.Instrumentation.ElasticsearchClient.Tests.csproj | 3 ++- ...metry.Instrumentation.EntityFrameworkCore.Tests.csproj | 7 ++++++- ...enTelemetry.Instrumentation.EventCounters.Tests.csproj | 3 ++- ...OpenTelemetry.Instrumentation.MassTransit.Tests.csproj | 3 ++- .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 3 ++- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 3 ++- .../Dockerfile | 6 +++--- ...emetry.Instrumentation.StackExchangeRedis.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 3 ++- 24 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 build/docker-compose.net7.0.yml diff --git a/.github/workflows/ci-md.yml b/.github/workflows/ci-md.yml index 345e969cb3..edb6c38c0b 100644 --- a/.github/workflows/ci-md.yml +++ b/.github/workflows/ci-md.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, netcoreapp3.1, net6.0 ] + version: [ net462, netcoreapp3.1, net6.0, net7.0 ] exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c6058fa3d..899268d17b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, netcoreapp3.1, net6.0 ] + version: [ net462, netcoreapp3.1, net6.0, net7.0 ] exclude: - os: ubuntu-latest version: net462 @@ -27,6 +27,10 @@ jobs: steps: - uses: actions/checkout@v3 + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 928be44569..38b8d057e4 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -24,6 +24,10 @@ jobs: steps: - uses: actions/checkout@v3 + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index c960b5e808..d7e4bb5a56 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -20,11 +20,6 @@ jobs: - name: check out code uses: actions/checkout@v3 - - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v3.0.3 - with: - dotnet-version: 6.0.x - - name: Install format tool run: dotnet tool install -g dotnet-format diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index f5f31d93b0..cde14ec5ca 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - version: [netcoreapp3.1,net6.0] + version: [netcoreapp3.1,net6.0,net7.0] steps: - run: 'echo "No build required"' diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index b369d1131b..31f5bdaf3d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - version: [netcoreapp3.1,net6.0] + version: [netcoreapp3.1,net6.0,net7.0] steps: - uses: actions/checkout@v3 diff --git a/build/docker-compose.net7.0.yml b/build/docker-compose.net7.0.yml new file mode 100644 index 0000000000..bbc8ac678a --- /dev/null +++ b/build/docker-compose.net7.0.yml @@ -0,0 +1,8 @@ +version: '3.7' + +services: + tests: + build: + args: + PUBLISH_FRAMEWORK: net7.0 + SDK_VERSION: 7.0 diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 5112523ae7..72bcabffc2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -2,8 +2,9 @@ Exe - net6.0 - $(TargetFrameworks);net462;net47;net471;net472;net48 + + net7.0;net6.0 + $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 0ef8e9d09d..63d4f9301e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -2,8 +2,9 @@ Exe - net6.0 - $(TargetFrameworks);net462;net47;net471;net472;net48 + + net7.0;net6.0 + $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1308,SA1201 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index ab8a17d397..72991b1339 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -2,8 +2,9 @@ Unit test project for Geneva Exporters for OpenTelemetry - net6.0 - $(TargetFrameworks);net462;net47;net471;net472;net48 + + net7.0;net6.0 + $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 6ff4659473..a9f56947da 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -1,7 +1,8 @@ Unit test project for Stackdriver Exporter for OpenTelemetry - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index cf6eece6bf..7e7d23d2a9 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -1,7 +1,8 @@ - + - net6.0 + + net7.0;net6.0 diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj index 7e15fdc3b3..73f9bd87a1 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for Docker Detector for OpenTelemetry - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj index 026fe3d98f..7a2cb99370 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj @@ -1,7 +1,8 @@  - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 1fbff07a38..4cbdb29338 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for OpenTelemetry .NET SDK preview features and extensions - net6.0 + + net7.0;net6.0 diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index bbd79698a7..744c556d99 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,7 +1,8 @@  Unit test project for OpenTelemetry Elasticsearch client instrumentation - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 true diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 3d88601ed2..a479ca5dbc 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -1,9 +1,14 @@  Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 + + + + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 674b5abe6e..09426e9f5a 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -1,7 +1,8 @@ - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 true diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj index 157667046f..5193861942 100644 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for OpenTelemetry MassTransit instrumentation - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 true diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index e238dd83df..b486cf4138 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -1,7 +1,8 @@ - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 42a37927ab..e69e3a367a 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,7 +1,8 @@ - net6.0 + + net7.0;net6.0 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile index 5f3f9f866c..084ee428fc 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile @@ -2,10 +2,10 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile . -ARG SDK_VERSION=6.0 -FROM mcr.microsoft.com/dotnet/sdk:6.0-focal AS build +ARG SDK_VERSION=7.0 +FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build ARG PUBLISH_CONFIGURATION=Release -ARG PUBLISH_FRAMEWORK=net6.0 +ARG PUBLISH_FRAMEWORK=net7.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 7a994128d1..9d0d48e8a8 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry StackExchangeRedis instrumentation - net6.0;netcoreapp3.1 + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 $(TARGET_FRAMEWORK) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index ba9a0c04e8..16a9faccdc 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for OpenTelemetry WCF instrumentation - netcoreapp3.1;net6.0 + + net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 From 9ea5026144abd5443bbc788b0e8b958b1575423b Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 21 Nov 2022 14:21:31 -0800 Subject: [PATCH 0431/1499] Update CHANGELOG (#785) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index c0cd43b32f..d8e8550d00 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,19 +6,22 @@ Released 2022-Nov-21 -* Update OpenTelemetry to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) +* Update OpenTelemetry to 1.4.0-beta.3 + ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) ## 1.4.0-beta.4 Released 2022-Oct-28 -* Breaking change: Updated export logic for scopes +* Updated export logic for scopes + * Users upgrading from `1.4.0-beta.1`, `1.4.0-beta.2` or `1.4.0-beta.3` to + this version will see a **breaking change** * Export scopes which have a non-null key as individual columns (each key-value pair from the scopes is exported as its own column; these columns would also be taken into consideration when the CustomFields option is applied). - * When using formatted strings for scopes, the templated string (`"{OriginalFormat"}`) - will not be exported. + * When using formatted strings for scopes, the templated string + (`"{OriginalFormat"}`) will not be exported. [#736](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/736) ## 1.4.0-beta.3 From a8611afa2f2f98f0f0a4427a20e08a2f716d707a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 22 Nov 2022 22:36:50 +0100 Subject: [PATCH 0432/1499] [Instrumentation.Runtime] Release 1.1.0-beta.1 (#786) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 2f80020074..65329cead7 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.1 + +Released 2022-Nov-22 + * Update OpenTelemetry API to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) * Change ObservableGauge to ObservableUpDownCounter for the below metrics (which From 9ce2a2b871b47c89232de0f7f266411e7e682c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 22 Nov 2022 22:48:51 +0100 Subject: [PATCH 0433/1499] Document PublicApi Analyzer (#787) --- CONTRIBUTING.md | 12 ++++++++---- build/RELEASING.md | 5 ++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 40821dff41..933b00e5bf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -183,7 +183,7 @@ Usually it is a good idea to use the latest version. Example: ```xml - + ``` @@ -201,6 +201,12 @@ by you. To ensure your project is versioned appropriately, specify a ``` +* Public API of all packages is analyzed by +[Microsoft.CodeAnalysis.PublicApiAnalyzers](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md). +This analyzer requires files structure to store the information about public API. +Create `PublicAPI.Shipped.txt` and `PublicAPI.Unshipped.txt` for each `TargetFramework` +defined in csproj under `{ProjectFolder}\.publicApi\{TargetFramework}`. + * To build and release your project as nuget, you must provide a GitHub workflow to be triggered when a tag with prefix "Instrumentation.FooBar-" is pushed to the main branch. The workflow file should be named as @@ -227,12 +233,10 @@ the main branch. The workflow file should be named as package. Every project's README file needs to have a link to the Nuget package. You can use the below snippet for reference: - -``` +```md [![NuGet](https://img.shields.io/nuget/v/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) [![NuGet](https://img.shields.io/nuget/dt/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) ``` - * When contributing a new project you are expected to assign either yourself or someone else who would take ownership for the component you are contributing. diff --git a/build/RELEASING.md b/build/RELEASING.md index f0c46cc138..e6a0cb1b9a 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -22,7 +22,10 @@ OpenTelemetry account. 2. Update the Changelog for your project with relevant details. Replace any "Unreleased" heading with this version and add the release date. -3. Submit a PR to update Changelog and get it merged to `main` branch. +3. If you are releasing stable version, update public API definition +in `PublicAPI.Shipped.txt` files and cleanup corresponding `PublicAPI.Unshipped.txt`. + +4. Submit a PR to update Changelog and get it merged to `main` branch. ## Steps From 8282cea80180a0a8f824db1baa647c12aab03d4a Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 22 Nov 2022 15:58:46 -0800 Subject: [PATCH 0434/1499] Update package workflow for instrumentation runtime (#789) --- .github/workflows/package-Instrumentation.Runtime.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index ed86a1a268..a8a47a6e91 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} From eb3f05b2c7fefb56041e749d9059a9775b245dd9 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Tue, 22 Nov 2022 17:24:29 -0800 Subject: [PATCH 0435/1499] restore project (#790) --- .github/workflows/package-Exporter.Geneva.yml | 2 +- .github/workflows/package-Exporter.Instana.yml | 4 ++-- .github/workflows/package-Exporter.Stackdriver.yml | 4 ++-- .github/workflows/package-Extensions.AWSXRay.yml | 4 ++-- .github/workflows/package-Extensions.AzureMonitor.yml | 2 +- .github/workflows/package-Extensions.Docker.yml | 4 ++-- .github/workflows/package-Extensions.PersistentStorage.yml | 2 +- .github/workflows/package-Extensions.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 4 ++-- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 2 +- .github/workflows/package-Instrumentation.AspNet.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 4 ++-- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 4 ++-- .github/workflows/package-Instrumentation.EventCounters.yml | 4 ++-- .github/workflows/package-Instrumentation.GrpcCore.yml | 4 ++-- .github/workflows/package-Instrumentation.Hangfire.yml | 2 +- .github/workflows/package-Instrumentation.MassTransit.yml | 4 ++-- .github/workflows/package-Instrumentation.MySqlData.yml | 4 ++-- .github/workflows/package-Instrumentation.Owin.yml | 2 +- .github/workflows/package-Instrumentation.Process.yml | 4 ++-- .github/workflows/package-Instrumentation.Quartz.yml | 4 ++-- .../workflows/package-Instrumentation.StackExchangeRedis.yml | 4 ++-- .github/workflows/package-Instrumentation.Wcf.yml | 2 +- 24 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index c768599ac0..7fe086d06c 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index 1fdac4e7ed..4de9a7d4e6 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index a4e9301cfb..d7739125ac 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index a2042cde0f..51691308ff 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml index 8a6b44849b..bfe26106bc 100644 --- a/.github/workflows/package-Extensions.AzureMonitor.yml +++ b/.github/workflows/package-Extensions.AzureMonitor.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Extensions.Docker.yml b/.github/workflows/package-Extensions.Docker.yml index bb1bf1680f..32b2936872 100644 --- a/.github/workflows/package-Extensions.Docker.yml +++ b/.github/workflows/package-Extensions.Docker.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index 979f4f1675..fedc66237b 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index 3b03d4bc32..0ce0b245a0 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index f557dcad9a..bab0626df9 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index a7c179e364..82af2141b4 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 1b12b12187..86943348b0 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 00a61079fd..3c3055f634 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 3249ff4b5f..502b51c242 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 68fe869ee6..16f49e0004 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index adfa40a8c3..c96fdeb4bf 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index b7cc235525..648d03b752 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index 31801c6e3e..f2fca41566 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml index d187edab4d..95889aa840 100644 --- a/.github/workflows/package-Instrumentation.MassTransit.yml +++ b/.github/workflows/package-Instrumentation.MassTransit.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index dc530c5d04..85451e2820 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index c7a0a77886..f088689874 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index 3b4d609a0b..8098481bd6 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 0cc104987b..97427f21f9 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index 9c9b6f9b8c..cd4be31403 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true @@ -46,4 +46,4 @@ jobs: - name: Publish Nuget run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} \ No newline at end of file + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 8830ce48bf..176d59d29f 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Install dependencies - run: dotnet restore + run: dotnet restore src/${{env.PROJECT}} - name: dotnet build ${{env.PROJECT}} run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true From 74cda611346cf830542c996bade67ac0a9ae1fb4 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 23 Nov 2022 11:23:14 -0800 Subject: [PATCH 0436/1499] Update package workflow for runtime (#793) * Update package workflow for instrumentation runtime --- .github/workflows/package-Instrumentation.Runtime.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index a8a47a6e91..00d7acdd24 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} From f48c05f5e9528148fcd2c7ff1420ca54fc35108a Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Wed, 23 Nov 2022 11:42:48 -0800 Subject: [PATCH 0437/1499] update package workflows to setup dotnet 7 (#795) --- .github/workflows/package-Exporter.Geneva.yml | 4 ++++ .github/workflows/package-Exporter.Stackdriver.yml | 4 ++++ .github/workflows/package-Extensions.AzureMonitor.yml | 4 ++++ .github/workflows/package-Extensions.Docker.yml | 4 ++++ .github/workflows/package-Extensions.PersistentStorage.yml | 4 ++++ .github/workflows/package-Extensions.yml | 4 ++++ .github/workflows/package-Instrumentation.Elasticsearch.yml | 4 ++++ .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 4 ++++ .github/workflows/package-Instrumentation.EventCounters.yml | 4 ++++ .github/workflows/package-Instrumentation.MassTransit.yml | 4 ++++ .github/workflows/package-Instrumentation.Process.yml | 4 ++++ .../workflows/package-Instrumentation.StackExchangeRedis.yml | 4 ++++ .github/workflows/package-Instrumentation.Wcf.yml | 4 ++++ 13 files changed, 52 insertions(+) diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index 7fe086d06c..6b4d803781 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index d7739125ac..bc7cd8fa47 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml index bfe26106bc..09e65c4415 100644 --- a/.github/workflows/package-Extensions.AzureMonitor.yml +++ b/.github/workflows/package-Extensions.AzureMonitor.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.Docker.yml b/.github/workflows/package-Extensions.Docker.yml index 32b2936872..b01c1531e4 100644 --- a/.github/workflows/package-Extensions.Docker.yml +++ b/.github/workflows/package-Extensions.Docker.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index fedc66237b..261c050c35 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index 0ce0b245a0..bdd2aae165 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 502b51c242..1e58ea7d39 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 16f49e0004..398a2cf207 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index c96fdeb4bf..7000480019 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml index 95889aa840..693abbf0db 100644 --- a/.github/workflows/package-Instrumentation.MassTransit.yml +++ b/.github/workflows/package-Instrumentation.MassTransit.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index 8098481bd6..51cc397bc5 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index cd4be31403..e4ee6dac1c 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 176d59d29f..b9c2cd41af 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} From 2d6a75ae3493f9aa361c7d0f1a2d8dd6b180443c Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Wed, 23 Nov 2022 18:09:12 -0800 Subject: [PATCH 0438/1499] Handle DateTimeOffset in the same way as DateTime (#797) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ .../MsgPackExporter/MessagePackSerializer.cs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index d8e8550d00..38a813d5e3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added support for + [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset). + ([#797](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/797)) + ## 1.4.0-beta.5 Released 2022-Nov-21 diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index f92f79d0db..2d62ebede4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -563,6 +563,8 @@ public static int Serialize(byte[] buffer, int cursor, object obj) return SerializeArray(buffer, cursor, v); case DateTime v: return SerializeUtcDateTime(buffer, cursor, v.ToUniversalTime()); + case DateTimeOffset v: + return SerializeUtcDateTime(buffer, cursor, v.UtcDateTime); default: string repr = null; From f88a532f4cf23f934d2d8e412513c6a21a80463c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Mon, 28 Nov 2022 20:45:49 +0100 Subject: [PATCH 0439/1499] [Instrumentation.Runtime] Update readme after inclusion of process.runtime.dotnet.gc.objects.size (#772) --- .../README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 7bf4f6010d..b7680f166e 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -63,6 +63,25 @@ The API used to retrieve the value is: The number of times garbage collection has occurred for the specified generation of objects. +#### process.runtime.dotnet.**gc.objects.size** + +Count of bytes currently in use by objects in the GC heap that haven't been +collected yet. +Fragmentation and other GC committed memory pools are excluded. +The value is available even before first garbage collection has occurred. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|---------|-------------------------|------------|-------------------|------------------| +| `bytes` | ObservableUpDownCounter | `Int64` | No Attributes | N/A | + +The API used to retrieve the value is: + +* [GC.GetTotalMemory](https://docs.microsoft.com/dotnet/api/system.gc.gettotalmemory): + Retrieves the number of bytes currently thought to be allocated. +The value is an approximate count. API is called with `false` +as a value of forceFullCollection parameter. Returns an instantaneous +value at the time of observation. + #### process.runtime.dotnet.**gc.allocations.size** Count of bytes allocated on the managed GC heap since the process start. From 851a374cf9e38763d05742154f71acd0da1d1ed2 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 28 Nov 2022 15:52:15 -0500 Subject: [PATCH 0440/1499] release Instrumentation.AspNet.TelemetryHttpModule 1.0.0-rc9.7 (#800) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 5d81a5b705..571ea3dab8 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.7 + +Released 2022-Nov-28 + * Restore Activity.Current before all IIS Lifecycle events ([#761](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/761)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index d859c59e1b..2e146bf12e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.7 + +Released 2022-Nov-28 + ## 1.0.0-rc9.6 Released 2022-Sep-28 From 1308cf848398c02acaa77ca99699c00802d7b5f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Tue, 29 Nov 2022 18:01:20 +0100 Subject: [PATCH 0441/1499] Fix typo in changelog for OpenTelemetry.Instrumentation.EntityFrameworkCore (#801) --- .../CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 27c99f63fb..a0ed020ae4 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -6,7 +6,7 @@ [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) * Update the `ActivitySource` name used to the assembly name: -`OpenTelemetry.Instrumentation.StackExchangeRedis` +`OpenTelemetry.Instrumentation.EntityFrameworkCore` [#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486) ## 1.0.0-beta.3 From 4a0cda8faeac5cded1ced44b182f21ab4116d80c Mon Sep 17 00:00:00 2001 From: Tyler Renslow Date: Thu, 1 Dec 2022 00:32:46 +0100 Subject: [PATCH 0442/1499] [Exporter.Stackdriver] Update dependencies (#794) * Update OpenTelemetry.Exporter.Stackdriver.csproj --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 3 +++ .../OpenTelemetry.Exporter.Stackdriver.csproj | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index ec1f06889a..188f54b845 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -4,6 +4,9 @@ * Fix the issue of incorrect handling of null attributes. ([#566](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/566)) +* Support for Google Cloud Dependencies up to 3.x.x + and OTel SDK package to 1.3.1 + ([#794](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/794)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 5ff84b77fb..a20ac500ec 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -6,9 +6,9 @@ Exporter.Stackdriver- - - - + + + From ffba0a5eac0015b923a2711f86a300ed51e8d934 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 6 Dec 2022 22:30:13 -0800 Subject: [PATCH 0443/1499] [Exporter.Geneva] Fix overflow bucket value serialization for Histogram (#805) * Fix Histogram serialization * Update CHANGELOG --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 2 ++ .../Metrics/GenevaMetricExporter.cs | 3 ++- .../GenevaMetricExporterTests.cs | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 38a813d5e3..4d2f8d872b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,8 @@ * Added support for [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset). ([#797](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/797)) +* Fix the overflow bucket value serialization for Histogram. + ([#805](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/805)) ## 1.4.0-beta.5 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index e056efa218..fa250f7ab6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -426,7 +426,6 @@ internal unsafe ushort SerializeHistogramMetric( if (bucket.ExplicitBound != double.PositiveInfinity) { MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - lastExplicitBound = bucket.ExplicitBound; } else { @@ -437,6 +436,8 @@ internal unsafe ushort SerializeHistogramMetric( MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); bucketCount++; } + + lastExplicitBound = bucket.ExplicitBound; } // Write the number of items in distribution emitted and reset back to end. diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 5448566160..8c1ac1b6f5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -768,7 +768,6 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE if (bucket.ExplicitBound != double.PositiveInfinity) { Assert.Equal(bucket.ExplicitBound, valueCountPairs.Columns[listIterator].Value); - lastExplicitBound = bucket.ExplicitBound; } else { @@ -780,6 +779,8 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE listIterator++; bucketsWithPositiveCount++; } + + lastExplicitBound = bucket.ExplicitBound; } Assert.Equal(bucketsWithPositiveCount, valueCountPairs.DistributionSize); From b469b458abdc7c54edcda500de94146e60257db1 Mon Sep 17 00:00:00 2001 From: Tyler Renslow Date: Wed, 7 Dec 2022 19:45:09 +0100 Subject: [PATCH 0444/1499] Update CHANGELOG.md (#806) --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 188f54b845..bd0f760680 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2022-Dec-07 + * Fix the issue of incorrect handling of null attributes. ([#566](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/566)) * Support for Google Cloud Dependencies up to 3.x.x From efb4acea2c2d76733eb74fa0fbc0f87c53440546 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 7 Dec 2022 12:27:01 -0800 Subject: [PATCH 0445/1499] [repo] Run workflows for any branch starting with "main" (#808) --- .github/workflows/ci-md.yml | 2 +- .github/workflows/ci.yml | 7 +++---- .github/workflows/dotnet-core-cov.yml | 6 +++--- .github/workflows/dotnet-format-md.yml | 2 +- .github/workflows/dotnet-format.yml | 4 ++-- .github/workflows/integration-md.yml | 4 ++-- .github/workflows/integration.yml | 4 ++-- .github/workflows/markdownlint.yml | 4 ++-- .github/workflows/sanitycheck.yml | 4 ++-- 9 files changed, 18 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci-md.yml b/.github/workflows/ci-md.yml index edb6c38c0b..c21b08b1f2 100644 --- a/.github/workflows/ci-md.yml +++ b/.github/workflows/ci-md.yml @@ -9,7 +9,7 @@ name: Build on: pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths: - '**.md' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 899268d17b..24fa4312d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,17 +2,16 @@ name: Build on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' jobs: build-test: - strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails @@ -30,7 +29,7 @@ jobs: - uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: '7.0.x' - + - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 38b8d057e4..8ca09760c0 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -2,11 +2,11 @@ name: Code Coverage on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' @@ -27,7 +27,7 @@ jobs: - uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: '7.0.x' - + - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-format-md.yml b/.github/workflows/dotnet-format-md.yml index be810e6c82..758347b3e4 100644 --- a/.github/workflows/dotnet-format-md.yml +++ b/.github/workflows/dotnet-format-md.yml @@ -9,7 +9,7 @@ name: dotnet format on: pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.cs' - '.editorconfig' diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index d7e4bb5a56..ba0fdee8a7 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -2,12 +2,12 @@ name: dotnet format on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths: - '**.cs' - '.editorconfig' pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths: - '**.cs' - '.editorconfig' diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index cde14ec5ca..564201205e 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -2,11 +2,11 @@ name: Integration Tests on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths: - '**.md' diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 31f5bdaf3d..43032bc10c 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -2,11 +2,11 @@ name: Integration Tests on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths-ignore: - '**.md' diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index fec61cedeb..7cca9734b8 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -2,11 +2,11 @@ name: markdownlint on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths: - '**.md' pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] paths: - '**.md' diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index a52563198e..5a2a04f19a 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -2,9 +2,9 @@ name: sanitycheck on: push: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] pull_request: - branches: [ main ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] jobs: misspell: From c49a261d43a161b53ae41304fa1d8b2c0f2fa418 Mon Sep 17 00:00:00 2001 From: Martin Taillefer Date: Wed, 7 Dec 2022 16:01:42 -0800 Subject: [PATCH 0446/1499] Leverage modern .NET features for improved perf. (#803) - When serializing objects, recognize ISpanFormattable on .NET 6 to avoid a temp string allocation in that case. - Use binary primitives to serialize scalar types more efficiently, avoiding repeated bound checks. --- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 38 ++++++++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 5 + .../MsgPackExporter/MessagePackSerializer.cs | 96 +++++++++++++++++-- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- 4 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..be1421894a --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1,38 @@ +Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void +OpenTelemetry.Exporter.Geneva.GenevaLogExporter +OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..62efb0fa1b --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index 2d62ebede4..01f9c14dbc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -15,6 +15,9 @@ // using System; +#if NET6_0_OR_GREATER +using System.Buffers.Binary; +#endif using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; @@ -62,6 +65,8 @@ internal static class MessagePackSerializer private const int LIMIT_MAX_FIX_ARRAY_LENGTH = 15; private const int STRING_SIZE_LIMIT_CHAR_COUNT = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 + private const int MAX_STACK_ALLOC_SIZE_IN_BYTES = 256; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeNull(byte[] buffer, int cursor) { @@ -195,6 +200,10 @@ public static int SerializeUInt64(byte[] buffer, int cursor, ulong value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteInt16(byte[] buffer, int cursor, short value) { +#if NET6_0_OR_GREATER + BinaryPrimitives.WriteInt16BigEndian(buffer.AsSpan(cursor), value); + return cursor + sizeof(short); +#else unchecked { buffer[cursor++] = (byte)(value >> 8); @@ -202,11 +211,16 @@ public static int WriteInt16(byte[] buffer, int cursor, short value) } return cursor; +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteInt32(byte[] buffer, int cursor, int value) { +#if NET6_0_OR_GREATER + BinaryPrimitives.WriteInt32BigEndian(buffer.AsSpan(cursor), value); + return cursor + sizeof(int); +#else unchecked { buffer[cursor++] = (byte)(value >> 24); @@ -216,11 +230,16 @@ public static int WriteInt32(byte[] buffer, int cursor, int value) } return cursor; +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteInt64(byte[] buffer, int cursor, long value) { +#if NET6_0_OR_GREATER + BinaryPrimitives.WriteInt64BigEndian(buffer.AsSpan(cursor), value); + return cursor + sizeof(long); +#else unchecked { buffer[cursor++] = (byte)(value >> 56); @@ -234,11 +253,16 @@ public static int WriteInt64(byte[] buffer, int cursor, long value) } return cursor; +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteUInt16(byte[] buffer, int cursor, ushort value) { +#if NET6_0_OR_GREATER + BinaryPrimitives.WriteUInt16BigEndian(buffer.AsSpan(cursor), value); + return cursor + sizeof(ushort); +#else unchecked { buffer[cursor++] = (byte)(value >> 8); @@ -246,11 +270,16 @@ public static int WriteUInt16(byte[] buffer, int cursor, ushort value) } return cursor; +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteUInt32(byte[] buffer, int cursor, uint value) { +#if NET6_0_OR_GREATER + BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(cursor), value); + return cursor + sizeof(uint); +#else unchecked { buffer[cursor++] = (byte)(value >> 24); @@ -260,11 +289,16 @@ public static int WriteUInt32(byte[] buffer, int cursor, uint value) } return cursor; +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteUInt64(byte[] buffer, int cursor, ulong value) { +#if NET6_0_OR_GREATER + BinaryPrimitives.WriteUInt64BigEndian(buffer.AsSpan(cursor), value); + return cursor + sizeof(ulong); +#else unchecked { buffer[cursor++] = (byte)(value >> 56); @@ -278,6 +312,7 @@ public static int WriteUInt64(byte[] buffer, int cursor, ulong value) } return cursor; +#endif } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -381,6 +416,45 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string value) return cursor; } +#if NET6_0_OR_GREATER + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUnicodeString(byte[] buffer, int cursor, ReadOnlySpan value) + { + if (value == null) + { + return SerializeNull(buffer, cursor); + } + + int start = cursor; + var cch = value.Length; + int cb; + cursor += 3; + if (cch <= STRING_SIZE_LIMIT_CHAR_COUNT) + { + cb = Encoding.UTF8.GetBytes(value.Slice(0, cch), buffer.AsSpan(cursor)); + cursor += cb; + } + else + { + cb = Encoding.UTF8.GetBytes(value.Slice(0, STRING_SIZE_LIMIT_CHAR_COUNT - 3), buffer.AsSpan(cursor)); + cursor += cb; + cb += 3; + + // append "..." to indicate the string truncation + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + buffer[cursor++] = 0x2E; + } + + buffer[start] = STR16; + buffer[start + 1] = unchecked((byte)(cb >> 8)); + buffer[start + 2] = unchecked((byte)cb); + return cursor; + } + +#else + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeUnicodeString(byte[] buffer, int cursor, string value) { @@ -416,6 +490,8 @@ public static int SerializeUnicodeString(byte[] buffer, int cursor, string value return cursor; } +#endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteArrayHeader(byte[] buffer, int cursor, int length) { @@ -565,6 +641,18 @@ public static int Serialize(byte[] buffer, int cursor, object obj) return SerializeUtcDateTime(buffer, cursor, v.ToUniversalTime()); case DateTimeOffset v: return SerializeUtcDateTime(buffer, cursor, v.UtcDateTime); + +#if NET6_0_OR_GREATER + case ISpanFormattable v: + Span tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; + if (v.TryFormat(tmp, out int charsWritten, string.Empty, CultureInfo.InvariantCulture)) + { + return SerializeUnicodeString(buffer, cursor, tmp.Slice(0, charsWritten)); + } + + goto default; +#endif + default: string repr = null; @@ -583,11 +671,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) public static int SerializeSpan(byte[] buffer, int cursor, Span value) { - for (int i = 0; i < value.Length; ++i) - { - buffer[cursor++] = value[i]; - } - - return cursor; + value.CopyTo(buffer.AsSpan(cursor)); + return cursor + value.Length; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 3867b3e6c5..4beabc729f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,7 +5,7 @@ An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 - netstandard2.0 + net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- true From 7cfbe0f21940d8c549ac81fe2ba0aa032e23ec2c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 7 Dec 2022 16:44:34 -0800 Subject: [PATCH 0447/1499] Rename branch to extensions (#811) --- .github/workflows/ci-md.yml | 2 +- .github/workflows/ci.yml | 4 ++-- .github/workflows/dotnet-core-cov.yml | 4 ++-- .github/workflows/dotnet-format-md.yml | 2 +- .github/workflows/dotnet-format.yml | 4 ++-- .github/workflows/integration-md.yml | 4 ++-- .github/workflows/integration.yml | 4 ++-- .github/workflows/markdownlint.yml | 4 ++-- .github/workflows/sanitycheck.yml | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci-md.yml b/.github/workflows/ci-md.yml index c21b08b1f2..6a3744f18e 100644 --- a/.github/workflows/ci-md.yml +++ b/.github/workflows/ci-md.yml @@ -9,7 +9,7 @@ name: Build on: pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: - '**.md' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24fa4312d7..f866f71232 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,11 +2,11 @@ name: Build on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 8ca09760c0..e4e75760e6 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -2,11 +2,11 @@ name: Code Coverage on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' diff --git a/.github/workflows/dotnet-format-md.yml b/.github/workflows/dotnet-format-md.yml index 758347b3e4..6c2d279ca0 100644 --- a/.github/workflows/dotnet-format-md.yml +++ b/.github/workflows/dotnet-format-md.yml @@ -9,7 +9,7 @@ name: dotnet format on: pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.cs' - '.editorconfig' diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index ba0fdee8a7..f10c4a08f7 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -2,12 +2,12 @@ name: dotnet format on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: - '**.cs' - '.editorconfig' pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: - '**.cs' - '.editorconfig' diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index 564201205e..ff74c117b5 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -2,11 +2,11 @@ name: Integration Tests on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: - '**.md' diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 43032bc10c..77ca42fb6d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -2,11 +2,11 @@ name: Integration Tests on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 7cca9734b8..9a94093b16 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -2,11 +2,11 @@ name: markdownlint on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: - '**.md' pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: - '**.md' diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 5a2a04f19a..a9e718d77d 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -2,9 +2,9 @@ name: sanitycheck on: push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extension*' ] + branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] jobs: misspell: From ff92fa3f4d4d181f0ccfc191a4b17cbaae62bfff Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 9 Dec 2022 13:14:52 -0800 Subject: [PATCH 0448/1499] [Exporter.Geneva] Fix EventSource logging for GenevaExporter (#813) * Fix EventSource logging for GenevaExporter --- .../CHANGELOG.md | 2 + .../Internal/ExporterEventSource.cs | 48 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 4d2f8d872b..82ee58ec00 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -7,6 +7,8 @@ ([#797](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/797)) * Fix the overflow bucket value serialization for Histogram. ([#805](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/805)) +* Fix EventSource logging + ([#813](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/813)) ## 1.4.0-beta.5 diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 7e827949c8..65f43be9af 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -22,7 +22,7 @@ namespace OpenTelemetry.Exporter.Geneva; [EventSource(Name = "OpenTelemetry-Exporter-Geneva")] -internal class ExporterEventSource : EventSource +internal sealed class ExporterEventSource : EventSource { public static readonly ExporterEventSource Log = new ExporterEventSource(); private const int EVENT_ID_TRACE = 1; // Failed to send Trace @@ -30,10 +30,10 @@ internal class ExporterEventSource : EventSource private const int EVENT_ID_METRIC = 3; // Failed to send Metric private const int EVENT_ID_ERROR = 4; // Other common exporter exceptions - [Event(EVENT_ID_TRACE, Message = "Exporter failed to send trace data. Exception: {0}", Level = EventLevel.Error)] + [NonEvent] public void FailedToSendTraceData(Exception ex) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { // https://docs.microsoft.com/en-us/windows/win32/etw/about-event-tracing // ETW has a size limit: The total event size is greater than 64K. This includes the ETW header plus the data or payload. @@ -43,40 +43,64 @@ public void FailedToSendTraceData(Exception ex) // descrs[0].Size = ((arg1.Length + 1) * 2); // I'm assuming it calculates the size of string, then it should be: // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). - this.WriteEvent(EVENT_ID_TRACE, ToInvariantString(ex)); + this.FailedToSendTraceData(ToInvariantString(ex)); } } - [Event(EVENT_ID_LOG, Message = "Exporter failed to send log data. Exception: {0}", Level = EventLevel.Error)] + [NonEvent] public void FailedToSendLogData(Exception ex) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { // TODO: Do not hit ETW size limit even for external library exception stack. - this.WriteEvent(EVENT_ID_LOG, ToInvariantString(ex)); + this.FailedToSendLogData(ToInvariantString(ex)); } } - [Event(EVENT_ID_METRIC, Message = "Exporter failed to send metric data. Data will not be sent. MonitoringAccount = {0} MetricNamespace = {1}, MetricName = {2}, Message: {3}", Level = EventLevel.Error)] + [NonEvent] public void FailedToSendMetricData(string monitoringAccount, string metricNamespace, string metricName, Exception ex) { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { // TODO: Do not hit ETW size limit even for external library exception stack. - this.WriteEvent(EVENT_ID_METRIC, monitoringAccount, metricNamespace, metricName, ToInvariantString(ex)); + this.FailedToSendMetricData(monitoringAccount, metricNamespace, metricName, ToInvariantString(ex)); } } - [Event(EVENT_ID_ERROR, Message = "Exporter failed.", Level = EventLevel.Error)] + [NonEvent] public void ExporterException(string message, Exception ex) { if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { // TODO: Do not hit ETW size limit even for external library exception stack. - this.WriteEvent(EVENT_ID_ERROR, message, ToInvariantString(ex)); + this.ExporterException(message, ToInvariantString(ex)); } } + [Event(EVENT_ID_TRACE, Message = "Exporter failed to send trace data. Exception: {0}", Level = EventLevel.Error)] + public void FailedToSendTraceData(string error) + { + this.WriteEvent(EVENT_ID_TRACE, error); + } + + [Event(EVENT_ID_LOG, Message = "Exporter failed to send log data. Exception: {0}", Level = EventLevel.Error)] + public void FailedToSendLogData(string error) + { + this.WriteEvent(EVENT_ID_LOG, error); + } + + [Event(EVENT_ID_METRIC, Message = "Exporter failed to send metric data. Data will not be sent. MonitoringAccount = {0} MetricNamespace = {1}, MetricName = {2}, Message: {3}", Level = EventLevel.Error)] + public void FailedToSendMetricData(string monitoringAccount, string metricNamespace, string metricName, string error) + { + this.WriteEvent(EVENT_ID_METRIC, monitoringAccount, metricNamespace, metricName, error); + } + + [Event(EVENT_ID_ERROR, Message = "Exporter failed. Message: {0}, Exception: {1}", Level = EventLevel.Error)] + public void ExporterException(string message, string error) + { + this.WriteEvent(EVENT_ID_ERROR, message, error); + } + /// /// Returns a culture-independent string representation of the given object, /// appropriate for diagnostics tracing. From 00e3cc92a7e3970eb4ba982970536b625d02d595 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 9 Dec 2022 14:07:11 -0800 Subject: [PATCH 0449/1499] Fix unit tests (#814) --- .../Trace/AutoFlushActivityProcessorTests.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index e1c060fb87..11dffa7a49 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -16,6 +16,7 @@ using System; using System.Diagnostics; +using System.Runtime.CompilerServices; using Moq; using Moq.Protected; using OpenTelemetry.Trace; @@ -29,14 +30,15 @@ public class AutoFlushActivityProcessorTests public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMatchingSpan_Flush() { var mockExporting = new Mock>(); + var sourceName = GetTestMethodName(); using var provider = Sdk.CreateTracerProviderBuilder() .AddProcessor(mockExporting.Object) .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000) - .AddSource("foo") + .AddSource(sourceName) .Build(); - using var source = new ActivitySource("foo"); + using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Server); activity.Dispose(); @@ -47,14 +49,15 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMat public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNonMatchingSpan_DoesNothing() { var mockExporting = new Mock>(); + var sourceName = GetTestMethodName(); using var provider = Sdk.CreateTracerProviderBuilder() .AddProcessor(mockExporting.Object) .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer)) - .AddSource("foo") + .AddSource(sourceName) .Build(); - using var source = new ActivitySource("foo"); + using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Client); activity.Dispose(); @@ -65,17 +68,23 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNon public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() { var mockExporting = new Mock>(); + var sourceName = GetTestMethodName(); using var provider = Sdk.CreateTracerProviderBuilder() .AddProcessor(mockExporting.Object) .AddAutoFlushActivityProcessor(_ => throw new Exception("Predicate throws an exception.")) - .AddSource("foo") + .AddSource(sourceName) .Build(); - using var source = new ActivitySource("foo"); + using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Server); activity.Dispose(); mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); } + + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } } From 03a6540d18542e7d49063b4d9792ee8ec37ba575 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 9 Dec 2022 14:31:16 -0800 Subject: [PATCH 0450/1499] Update CHANGELOG for 1.4.0-beta.6 (#815) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 82ee58ec00..dba152892f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-beta.6 + +Released 2022-Dec-09 + * Added support for [DateTimeOffset](https://learn.microsoft.com/dotnet/api/system.datetimeoffset). ([#797](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/797)) From 6ef8cc49443382f491fe876937f173c7e515d875 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 12 Dec 2022 12:20:07 -0800 Subject: [PATCH 0451/1499] Update unit tests for scopes (#817) --- .../GenevaLogExporterTests.cs | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index cf2d9c448d..edd959d1e8 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -357,8 +357,10 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() } } - [Fact] - public void SerializeILoggerScopes() + [Theory] + [InlineData(false)] + [InlineData(true)] + public void SerializeILoggerScopes(bool hasCustomFields) { string path = string.Empty; Socket senderSocket = null; @@ -381,6 +383,11 @@ public void SerializeILoggerScopes() senderSocket.Listen(1); } + if (hasCustomFields) + { + exporterOptions.CustomFields = new string[] { "food", "Name", "Key1" }; + } + var exportedItems = new List(); using var loggerFactory = LoggerFactory.Create(builder => builder @@ -391,6 +398,7 @@ public void SerializeILoggerScopes() options.AddGenevaLogExporter(options => { options.ConnectionString = exporterOptions.ConnectionString; + options.CustomFields = exporterOptions.CustomFields; }); })); @@ -408,8 +416,8 @@ public void SerializeILoggerScopes() using (logger.BeginScope("MyOuterScope")) using (logger.BeginScope("MyInnerScope")) - using (logger.BeginScope("MyInnerInnerScope with {Name} and {Age} of custom", "John Doe", 35)) - using (logger.BeginScope(new List> { new KeyValuePair("MyKey", "MyValue") })) + using (logger.BeginScope("MyInnerInnerScope with {Name} and {Age} of custom", "John Doe", 25)) + using (logger.BeginScope(new List> { new("Key1", "Value1"), new("Key2", "Value2") })) { logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); } @@ -431,9 +439,39 @@ public void SerializeILoggerScopes() var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - Assert.Equal("John Doe", mapping["Name"]); - Assert.Equal((byte)35, mapping["Age"]); - Assert.Equal("MyValue", mapping["MyKey"]); + + if (hasCustomFields) + { + var envProperties = mapping["env_properties"] as Dictionary; + + // Custom Fields + Assert.Equal("artichoke", mapping["food"]); + Assert.Equal("John Doe", mapping["Name"]); + Assert.Equal("Value1", mapping["Key1"]); + + Assert.False(mapping.ContainsKey("MyOuterScope")); + Assert.False(mapping.ContainsKey("MyInnerScope")); + + // env_properties + Assert.True(Equals(envProperties["price"], 3.99)); + Assert.Equal((byte)25, envProperties["Age"]); + Assert.Equal("Value2", envProperties["Key2"]); + + Assert.False(envProperties.ContainsKey("MyOuterScope")); + Assert.False(envProperties.ContainsKey("MyInnerScope")); + } + else + { + Assert.Equal("artichoke", mapping["food"]); + Assert.True(Equals(mapping["price"], 3.99)); + Assert.Equal("John Doe", mapping["Name"]); + Assert.Equal((byte)25, mapping["Age"]); + Assert.Equal("Value1", mapping["Key1"]); + Assert.Equal("Value2", mapping["Key2"]); + + Assert.False(mapping.ContainsKey("MyOuterScope")); + Assert.False(mapping.ContainsKey("MyInnerScope")); + } // Check other fields Assert.Single(exportedItems); From 9e4364883b4bd171d66a557dbdd6ffd7648d46a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 13 Dec 2022 07:09:22 +0100 Subject: [PATCH 0452/1499] Bump OpenTelemetry prereleased to 1.4.0-rc.1 (#820) * Bump OpenTelemetry prereleased to 1.4.0-rc.1 --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/CHANGELOG.md | 2 +- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 2 ++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/build/Common.props b/build/Common.props index 3672da0751..b1c92633c0 100644 --- a/build/Common.props +++ b/build/Common.props @@ -33,7 +33,7 @@ [3.3.3] [1.1.1,2.0) [1.3.1,2.0) - [1.4.0-beta.3] + [1.4.0-rc.1] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index dba152892f..893db5bfbb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0-rc.1 + ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) + ## 1.4.0-beta.6 Released 2022-Dec-09 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 33a35b6a0b..17e4b61f22 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* Update OpenTelemetry to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) +* Update OpenTelemetry to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index cfe33c8cd1..a04c339d93 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) + ## 1.0.0-alpha.2 Released 2022-Nov-18 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 65329cead7..10bff4ca61 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) + ## 1.1.0-beta.1 Released 2022-Nov-22 From 6b34d54b8e15adfe8803704cb377fd4be2181702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 13 Dec 2022 07:20:44 +0100 Subject: [PATCH 0453/1499] [Instrumentation.Process, Instrumentation.Runtime] Releases with OTel 1.4.0-rc.1 (#821) * [Instrumentation.Process, Instrumentation.Runtime] Releases with OTel 1.4.0-rc.1 --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index a04c339d93..59852cfca0 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.3 + +Released 2022-Dec-13 + * Update OpenTelemetry API to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) ## 1.0.0-alpha.2 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 10bff4ca61..d3518d37cf 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2022-Dec-13 + * Update OpenTelemetry API to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) ## 1.1.0-beta.1 From e4a61e415059668e1a6ab13798d5f243d05d9534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 13 Dec 2022 08:21:29 +0100 Subject: [PATCH 0454/1499] typo fix (#822) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index d3518d37cf..d54c3fe506 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -## 1.0.0-beta.2 +## 1.1.0-beta.2 Released 2022-Dec-13 From 73486c705ea4cf55dec78c9271fe380ab236e0ad Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 15 Dec 2022 13:15:25 -0800 Subject: [PATCH 0455/1499] [repo] Fix netcoreapp3.1 tests failing in CI (#827) * Attempting to get netcoreapp3.1 tests passing. Also includes some misc fixes. * More project and CI updates. * Tweaks. * Tweaks. * Tweak. * Warning cleanup. * Tweaks. * Tweak process instrumentation test to verify disposal. * Test update to verify failure. * Disable failing test. * Attempting to fix AutoFlushActivityProcessor test. * Bump versions of packages used by tests. * Fixes for .net 4.5.2. * Revert package bump for xunit.runner.visualstudio. --- .github/workflows/ci.yml | 8 +++- .github/workflows/dotnet-format.yml | 5 +++ build/Common.nonprod.props | 3 +- build/Common.props | 2 - build/Common.targets | 3 +- build/docker-compose.net6.0.yml | 3 +- build/docker-compose.net7.0.yml | 3 +- build/docker-compose.netcoreapp3.1.yml | 3 +- examples/AspNet/Global.asax.cs | 2 + global.json | 6 +++ opentelemetry-dotnet-contrib.sln | 4 +- .../Internal/ConnectionStringBuilder.cs | 4 ++ .../MsgPackExporter/MessagePackSerializer.cs | 2 + .../ActivityEventAttachingLogProcessor.cs | 2 +- .../OpenTelemetryExtensionsEventSource.cs | 2 +- .../MeterProviderBuilderExtensions.cs | 6 +-- .../ProcessMetrics.cs | 21 ++++++--- ...ry.Contrib.Extensions.AWSXRay.Tests.csproj | 4 +- ...y.Contrib.Instrumentation.AWS.Tests.csproj | 4 +- .../Trace/AutoFlushActivityProcessorTests.cs | 6 +-- ...metry.Instrumentation.Process.Tests.csproj | 2 +- .../ProcessMetricsTests.cs | 43 +++++++++++++++---- .../Dockerfile | 8 ++-- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 4 +- 24 files changed, 107 insertions(+), 43 deletions(-) create mode 100644 global.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f866f71232..74e5c18d24 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,13 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v3.0.3 + - name: Install .NET 3.1 SDK + uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '3.1.x' + + - name: Install .NET 7 SDK + uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index f10c4a08f7..e4a59cccf2 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -20,6 +20,11 @@ jobs: - name: check out code uses: actions/checkout@v3 + - name: Install .NET 7 SDK + uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install format tool run: dotnet tool install -g dotnet-format diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index c87dfe6428..2b63c35109 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -25,7 +25,8 @@ [2.3.1,3.0) [5.0.0,7.0) [16.11.0,17.0) - [4.17.2,5.0) + [4.18.3,5.0) + [4.17.2,5.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) [2.4.3,3.0) diff --git a/build/Common.props b/build/Common.props index b1c92633c0..ff04e2dec8 100644 --- a/build/Common.props +++ b/build/Common.props @@ -24,7 +24,6 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [4.2.0,5.0) - [6.0.0] [17.3.2] [2.1.0,5.0) [3.1.0,) @@ -51,7 +50,6 @@ - diff --git a/build/Common.targets b/build/Common.targets index 6cf892c169..556dd88d22 100644 --- a/build/Common.targets +++ b/build/Common.targets @@ -1,8 +1,7 @@ - AllEnabledByDefault - latest + latest-all diff --git a/build/docker-compose.net6.0.yml b/build/docker-compose.net6.0.yml index c1a9529c51..0d59259753 100644 --- a/build/docker-compose.net6.0.yml +++ b/build/docker-compose.net6.0.yml @@ -5,4 +5,5 @@ services: build: args: PUBLISH_FRAMEWORK: net6.0 - SDK_VERSION: 6.0 + TEST_SDK_VERSION: 6.0 + BUILD_SDK_VERSION: 7.0 diff --git a/build/docker-compose.net7.0.yml b/build/docker-compose.net7.0.yml index bbc8ac678a..d79fa366bb 100644 --- a/build/docker-compose.net7.0.yml +++ b/build/docker-compose.net7.0.yml @@ -5,4 +5,5 @@ services: build: args: PUBLISH_FRAMEWORK: net7.0 - SDK_VERSION: 7.0 + TEST_SDK_VERSION: 7.0 + BUILD_SDK_VERSION: 7.0 diff --git a/build/docker-compose.netcoreapp3.1.yml b/build/docker-compose.netcoreapp3.1.yml index 4d45fa1b3e..ce7102f66c 100644 --- a/build/docker-compose.netcoreapp3.1.yml +++ b/build/docker-compose.netcoreapp3.1.yml @@ -5,4 +5,5 @@ services: build: args: PUBLISH_FRAMEWORK: netcoreapp3.1 - SDK_VERSION: 3.1 + TEST_SDK_VERSION: 3.1 + BUILD_SDK_VERSION: 7.0 diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index 76067b6ad0..b32f6dfaf3 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -27,7 +27,9 @@ namespace Examples.AspNet; +#pragma warning disable SA1649 // File name should match first type name public class WebApiApplication : HttpApplication +#pragma warning restore SA1649 // File name should match first type name { private IDisposable tracerProvider; private IDisposable meterProvider; diff --git a/global.json b/global.json new file mode 100644 index 0000000000..0f417661e6 --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "rollForward": "latestFeature", + "version": "7.0.101" + } +} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 22903a6b99..20cb582f52 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -10,6 +10,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig CONTRIBUTING.md = CONTRIBUTING.md + global.json = global.json NuGet.config = NuGet.config opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj examples\process-instrumentation\process-instrumentation.csproj = examples\process-instrumentation\process-instrumentation.csproj @@ -26,9 +27,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml - .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml .github\workflows\ci.yml = .github\workflows\ci.yml + .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml @@ -73,6 +74,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk 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.netcoreapp3.1.yml = build\docker-compose.netcoreapp3.1.yml build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index bba3ef97d4..65b5471148 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -47,7 +47,11 @@ public ConnectionStringBuilder(string connectionString) continue; } +#if NET6_0_OR_GREATER + var index = token.IndexOf(EqualSign, StringComparison.Ordinal); +#else var index = token.IndexOf(EqualSign); +#endif if (index == -1 || index != token.LastIndexOf(EqualSign)) { continue; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index 01f9c14dbc..5236c386cf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -65,7 +65,9 @@ internal static class MessagePackSerializer private const int LIMIT_MAX_FIX_ARRAY_LENGTH = 15; private const int STRING_SIZE_LIMIT_CHAR_COUNT = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 +#if NET6_0_OR_GREATER private const int MAX_STACK_ALLOC_SIZE_IN_BYTES = 256; +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeNull(byte[] buffer, int cursor) diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index ffaf8a75cb..d52147dd1c 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -92,7 +92,7 @@ public override void OnEnd(LogRecord data) } } - private class State + private sealed class State { public State(ActivityTagsCollection tags, ActivityEventAttachingLogProcessor processor) { diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index 596bd0ec71..5a5d446831 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry; /// EventSource implementation for OpenTelemetry SDK extensions implementation. /// [EventSource(Name = "OpenTelemetry-Extensions")] -internal class OpenTelemetryExtensionsEventSource : EventSource +internal sealed class OpenTelemetryExtensionsEventSource : EventSource { public static OpenTelemetryExtensionsEventSource Log = new OpenTelemetryExtensionsEventSource(); diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index 223808b4a4..dcb0bec65b 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -40,8 +40,8 @@ public static MeterProviderBuilder AddProcessInstrumentation( var options = new ProcessInstrumentationOptions(); configure?.Invoke(options); - var instrumentation = new ProcessMetrics(options); - builder.AddMeter(instrumentation.MeterInstance.Name); - return builder.AddInstrumentation(() => instrumentation); + builder.AddMeter(ProcessMetrics.MeterName); + + return builder.AddInstrumentation(() => new ProcessMetrics(options)); } } diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index b724c3d308..690e73398f 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -22,10 +22,12 @@ namespace OpenTelemetry.Instrumentation.Process; -internal sealed class ProcessMetrics +internal sealed class ProcessMetrics : IDisposable { internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); - internal readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); + internal static readonly string MeterName = AssemblyName.Name; + + private readonly Meter meterInstance = new(MeterName, AssemblyName.Version.ToString()); // vars for calculating CPU utilization private DateTime lastCollectionTimeUtc; @@ -38,7 +40,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) this.lastCollectedUserProcessorTime = Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; this.lastCollectedPrivilegedProcessorTime = Diagnostics.Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; - this.MeterInstance.CreateObservableUpDownCounter( + this.meterInstance.CreateObservableUpDownCounter( "process.memory.usage", () => { @@ -47,7 +49,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "By", description: "The amount of physical memory allocated for this process."); - this.MeterInstance.CreateObservableUpDownCounter( + this.meterInstance.CreateObservableUpDownCounter( "process.memory.virtual", () => { @@ -56,7 +58,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "By", description: "The amount of committed virtual memory for this process."); - this.MeterInstance.CreateObservableCounter( + this.meterInstance.CreateObservableCounter( "process.cpu.time", () => { @@ -70,7 +72,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "s", description: "Total CPU seconds broken down by different states."); - this.MeterInstance.CreateObservableGauge( + this.meterInstance.CreateObservableGauge( "process.cpu.utilization", () => { @@ -79,7 +81,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "1", description: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process."); - this.MeterInstance.CreateObservableUpDownCounter( + this.meterInstance.CreateObservableUpDownCounter( "process.threads", () => { @@ -89,6 +91,11 @@ public ProcessMetrics(ProcessInstrumentationOptions options) description: "Process threads count."); } + public void Dispose() + { + this.meterInstance.Dispose(); + } + private IEnumerable> GetCpuUtilization() { var process = Diagnostics.Process.GetCurrentProcess(); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index c4f3634c9e..aeaadfb5ad 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for AWS X-Ray for OpenTelemetry @@ -9,7 +9,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 9bc689512e..8b47625fbf 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for AWS client instrumentation for OpenTelemetry @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index 11dffa7a49..6c2bf6b701 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -40,7 +40,7 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMat using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Server); - activity.Dispose(); + activity.Stop(); mockExporting.Protected().Verify("OnForceFlush", Times.Once(), 5_000); } @@ -59,7 +59,7 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNon using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Client); - activity.Dispose(); + activity.Stop(); mockExporting.Protected().Verify("OnForceFlush", Times.Never(), It.IsAny()); } @@ -78,7 +78,7 @@ public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Server); - activity.Dispose(); + activity.Stop(); mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); } diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index b486cf4138..d245ea0139 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index c1dbd3e72b..0971c92c31 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -123,7 +123,8 @@ public void CpuUtilizationMetricsAreCaptured() Assert.True(systemCpuUtilizationCaptured); } - [Fact] + // See: https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/831 + [Fact(Skip = "There are known issues with this test.")] public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName() { var exportedItemsA = new List(); @@ -134,19 +135,45 @@ public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName( .AddInMemoryExporter(exportedItemsA) .Build(); - using var meterProviderB = Sdk.CreateMeterProviderBuilder() + using (var meterProviderB = Sdk.CreateMeterProviderBuilder() .AddProcessInstrumentation() .AddInMemoryExporter(exportedItemsB) - .Build(); + .Build()) + { + meterProviderA.ForceFlush(MaxTimeToAllowForFlush); + meterProviderB.ForceFlush(MaxTimeToAllowForFlush); + + var metricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); + var metricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); + + Assert.True(GetValue(metricA) > 0); + Assert.True(GetValue(metricB) > 0); + } + + exportedItemsA.Clear(); + exportedItemsB.Clear(); meterProviderA.ForceFlush(MaxTimeToAllowForFlush); - meterProviderB.ForceFlush(MaxTimeToAllowForFlush); - var metricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); - var metricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); + Assert.NotEmpty(exportedItemsA); + Assert.Empty(exportedItemsB); + + exportedItemsA.Clear(); + exportedItemsB.Clear(); + + meterProviderA.ForceFlush(MaxTimeToAllowForFlush); + + Assert.NotEmpty(exportedItemsA); + Assert.Empty(exportedItemsB); + + exportedItemsA.Clear(); + + meterProviderA.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(GetValue(metricA) > 0); - Assert.True(GetValue(metricB) > 0); + // Note: This fails due to: + // https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/Metrics/MetricReaderExt.cs#L244-L249 + Assert.NotEmpty(exportedItemsA); + Assert.Empty(exportedItemsB); } private static double GetValue(Metric metric) diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile index 084ee428fc..945e7a4d9d 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile @@ -2,8 +2,10 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile . -ARG SDK_VERSION=7.0 -FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +ARG BUILD_SDK_VERSION=7.0 +ARG TEST_SDK_VERSION=7.0 + +FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build ARG PUBLISH_CONFIGURATION=Release ARG PUBLISH_FRAMEWORK=net7.0 WORKDIR /repo @@ -11,7 +13,7 @@ COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" RUN dotnet publish "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} -FROM mcr.microsoft.com/dotnet/sdk:${SDK_VERSION} AS final +FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final WORKDIR /test COPY --from=build /drop . ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.dll"] diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 16a9faccdc..e0a36b7a6b 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for OpenTelemetry WCF instrumentation - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 $(TargetFrameworks);net462 @@ -28,7 +28,7 @@ - + From a77287cb304dfb69345db572b71621f0347aae63 Mon Sep 17 00:00:00 2001 From: Christian Prochnow Date: Fri, 16 Dec 2022 03:57:25 +0100 Subject: [PATCH 0456/1499] [Instrumentation.Hangfire] Update CHANGELOG for 1.0.0-beta.4 release (#830) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 03bb6fff97..ee6525ae80 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2022-Dec-15 + * Add support for custom job display names ([#756](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/756)) From 97f1882e86993bbc8450c5daff61badaa1502a12 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 15 Dec 2022 22:22:34 -0800 Subject: [PATCH 0457/1499] Update workflows (#836) --- .github/workflows/package-Exporter.Instana.yml | 4 ++++ .github/workflows/package-Extensions.AWSXRay.yml | 4 ++++ .../package-Extensions.PersistentStorage.Abstractions.yml | 4 ++++ .github/workflows/package-Instrumentation.AWS.yml | 4 ++++ .github/workflows/package-Instrumentation.AWSLambda.yml | 4 ++++ .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 4 ++++ .github/workflows/package-Instrumentation.AspNet.yml | 4 ++++ .github/workflows/package-Instrumentation.GrpcCore.yml | 4 ++++ .github/workflows/package-Instrumentation.Hangfire.yml | 4 ++++ .github/workflows/package-Instrumentation.MySqlData.yml | 4 ++++ .github/workflows/package-Instrumentation.Owin.yml | 4 ++++ .github/workflows/package-Instrumentation.Quartz.yml | 4 ++++ 12 files changed, 48 insertions(+) diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index 4de9a7d4e6..4f20810a38 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index 51691308ff..ee9a452ccc 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml index 93e14f8f57..5dfda8ee88 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index bab0626df9..9f1957330c 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 82af2141b4..2f5a3d4d81 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 86943348b0..79ca5ae17a 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 3c3055f634..1b36bc2d3b 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index 648d03b752..b02ffb88ba 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index f2fca41566..254581d38e 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index 85451e2820..e55946a334 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index f088689874..a57168293f 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 97427f21f9..c69be134c1 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -26,6 +26,10 @@ jobs: with: fetch-depth: 0 # fetching all + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} From 3768220ace7a2845efd2df97daa72658eb68f720 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 16 Dec 2022 11:22:07 -0800 Subject: [PATCH 0458/1499] [Geneva.Logs] Support prefix-based table name mapping (#796) * Added support for prefix based table mappings in geneva log exporter. * Benchmark tweak. * Patch CHANGELOG. * README updates. * Lint. * Code review. * Code review. * Test updates. * Code review. * Code review. * Code review. * Code review. * Warning cleanup. --- .../CHANGELOG.md | 3 + .../GenevaExporterOptions.cs | 22 +- .../GenevaLogExporter.cs | 2 +- .../GenevaTraceExporter.cs | 2 +- .../Internal/TableNameSerializer.cs | 328 ++++++++++++++++++ .../MsgPackExporter/MessagePackSerializer.cs | 25 +- .../MsgPackExporter/MsgPackExporter.cs | 2 +- .../MsgPackExporter/MsgPackLogExporter.cs | 143 +------- src/OpenTelemetry.Exporter.Geneva/README.md | 72 +++- .../Exporter/LogExporterBenchmarks.cs | 9 +- .../GenevaLogExporterTests.cs | 2 +- .../TableNameSerializerTests.cs | 158 +++++++++ 12 files changed, 616 insertions(+), 152 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 893db5bfbb..6d1edafd77 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -17,6 +17,9 @@ Released 2022-Dec-09 * Fix EventSource logging ([#813](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/813)) +* Add support in logs for prefix-based table name mapping configuration. + [#796](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/796) + ## 1.4.0-beta.5 Released 2022-Nov-21 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index eee0865e0f..3af00bb09c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -47,14 +47,32 @@ public IReadOnlyDictionary TableNameMappings foreach (var entry in value) { + if (string.IsNullOrWhiteSpace(entry.Key)) + { + throw new ArgumentException("A table name mapping key was null, empty, or consisted only of white-space characters.", nameof(this.TableNameMappings)); + } + if (string.IsNullOrWhiteSpace(entry.Value)) { - throw new ArgumentException($"A string-typed value provided for {nameof(this.TableNameMappings)} must not be null, empty, or consist only of white-space characters."); + throw new ArgumentException($"The table name mapping value provided for key '{entry.Key}' was null, empty, or consisted only of white-space characters.", nameof(this.TableNameMappings)); } if (Encoding.UTF8.GetByteCount(entry.Value) != entry.Value.Length) { - throw new ArgumentException($"A string-typed value provided for {nameof(this.TableNameMappings)} must not contain non-ASCII characters.", entry.Value); + throw new ArgumentException($"The table name mapping value '{entry.Value}' provided for key '{entry.Key}' contained non-ASCII characters.", nameof(this.TableNameMappings)); + } + + if (entry.Value != "*") + { + if (!TableNameSerializer.IsValidTableName(entry.Value)) + { + throw new ArgumentException($"The table name mapping value '{entry.Value}' provided for key '{entry.Key}' contained invalid characters or was too long.", nameof(this.TableNameMappings)); + } + + if (TableNameSerializer.IsReservedTableName(entry.Value)) + { + throw new ArgumentException($"The table name mapping value '{entry.Value}' provided for key '{entry.Key}' is reserved and cannot be specified.", nameof(this.TableNameMappings)); + } } copy[entry.Key] = entry.Value; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index b23bd32b10..2f5b6ce3da 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -45,7 +45,7 @@ public GenevaLogExporter(GenevaExporterOptions options) public override ExportResult Export(in Batch batch) { - return this.exportLogRecord(batch); + return this.exportLogRecord(in batch); } protected override void Dispose(bool disposing) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 9c37b6db84..d732fe41cd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -45,7 +45,7 @@ public GenevaTraceExporter(GenevaExporterOptions options) public override ExportResult Export(in Batch batch) { - return this.exportActivity(batch); + return this.exportActivity(in batch); } protected override void Dispose(bool disposing) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs new file mode 100644 index 0000000000..0996827a48 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -0,0 +1,328 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text; + +namespace OpenTelemetry.Exporter.Geneva; + +internal sealed class TableNameSerializer +{ + public const int MaxSanitizedCategoryNameLength = 50; + public const int MaxSanitizedCategoryNameBytes = MaxSanitizedCategoryNameLength + 2; + public const int MaxCachedSanitizedTableNames = 1024; + private const StringComparison DictionaryKeyComparison = StringComparison.Ordinal; + +#pragma warning disable CA1825 // Avoid zero-length array allocations + /* Note: We don't use Array.Empty here because that is used to + indicate an invalid name. We need a different instance to trigger the + pass-through case. */ + private static readonly byte[] s_passthroughTableName = new byte[0]; +#pragma warning restore CA1825 // Avoid zero-length array allocations + private static readonly StringComparer s_dictionaryKeyComparer = StringComparer.Ordinal; + + private readonly byte[] m_defaultTableName; + private readonly Dictionary m_tableMappings; + private readonly bool m_shouldPassThruTableMappings; + private readonly object m_lockObject = new(); + private TableNameCacheDictionary m_tableNameCache = new(); + + public ITableNameCacheDictionary TableNameCache => this.m_tableNameCache; + + public TableNameSerializer(GenevaExporterOptions options, string defaultTableName) + { + Debug.Assert(options != null, "options were null"); + Debug.Assert(!string.IsNullOrWhiteSpace(defaultTableName), "defaultEventName was null or whitespace"); + Debug.Assert(IsValidTableName(defaultTableName), "defaultEventName was invalid"); + + this.m_defaultTableName = BuildStr8BufferForAsciiString(defaultTableName); + + if (options.TableNameMappings != null) + { + var tempTableMappings = new Dictionary(options.TableNameMappings.Count, s_dictionaryKeyComparer); + foreach (var kv in options.TableNameMappings) + { + if (kv.Key == "*") + { + if (kv.Value == "*") + { + this.m_shouldPassThruTableMappings = true; + } + else + { + this.m_defaultTableName = BuildStr8BufferForAsciiString(kv.Value); + } + } + else if (kv.Value == "*") + { + tempTableMappings[kv.Key] = s_passthroughTableName; + } + else + { + tempTableMappings[kv.Key] = BuildStr8BufferForAsciiString(kv.Value); + } + } + + this.m_tableMappings = tempTableMappings; + } + } + + public static bool IsReservedTableName(string tableName) + { + Debug.Assert(!string.IsNullOrWhiteSpace(tableName), "tableName was null or whitespace"); + + // TODO: Implement this if needed. + + return false; + } + + public static bool IsValidTableName(string tableName) + { + Debug.Assert(!string.IsNullOrWhiteSpace(tableName), "tableName was null or whitespace"); + + var length = tableName.Length; + if (length > MaxSanitizedCategoryNameLength) + { + return false; + } + + char firstChar = tableName[0]; + if (firstChar < 'A' || firstChar > 'Z') + { + return false; + } + + for (int i = 1; i < length; i++) + { + char cur = tableName[i]; + if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) + { + continue; + } + + return false; + } + + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ResolveAndSerializeTableNameForCategoryName(byte[] destination, int offset, string categoryName, out ReadOnlySpan tableName) + { + byte[] mappedTableName = this.ResolveTableMappingForCategoryName(categoryName); + + if (mappedTableName == s_passthroughTableName) + { + // Pass-through mode with a full cache. + + int bytesWritten = WriteSanitizedCategoryNameToSpan(new Span(destination, offset, MaxSanitizedCategoryNameBytes), categoryName); + + tableName = new ReadOnlySpan(destination, offset, bytesWritten); + + return offset + bytesWritten; + } + + tableName = mappedTableName; + + return MessagePackSerializer.SerializeSpan(destination, offset, tableName); + } + + private static byte[] BuildStr8BufferForAsciiString(string value) + { + var length = value.Length; + + byte[] buffer = new byte[length + 2]; + + Encoding.ASCII.GetBytes(value, 0, length, buffer, 2); + + MessagePackSerializer.WriteStr8Header(buffer, 0, length); + + return buffer; + } + + // This method would map the logger category to a table name which only contains alphanumeric values with the following additions: + // Any character that is not allowed will be removed. + // If the resulting string is longer than 50 characters, only the first 50 characters will be taken. + // If the first character in the resulting string is a lower-case alphabet, it will be converted to the corresponding upper-case. + // If the resulting string still does not comply with Rule, the category name will not be serialized. + private static int WriteSanitizedCategoryNameToSpan(Span buffer, string categoryName) + { + // Reserve 2 bytes for storing LIMIT_MAX_STR8_LENGTH_IN_BYTES and (byte)validNameLength - + // these 2 bytes will be back filled after iterating through categoryName. + int cursor = 2; + int validNameLength = 0; + + // Special treatment for the first character. + var firstChar = categoryName[0]; + if (firstChar >= 'A' && firstChar <= 'Z') + { + buffer[cursor++] = (byte)firstChar; + ++validNameLength; + } + else if (firstChar >= 'a' && firstChar <= 'z') + { + // If the first character in the resulting string is a lower-case alphabet, + // it will be converted to the corresponding upper-case. + buffer[cursor++] = (byte)(firstChar - 32); + ++validNameLength; + } + else + { + // Not a valid name. + return 0; + } + + for (int i = 1; i < categoryName.Length; ++i) + { + if (validNameLength == MaxSanitizedCategoryNameLength) + { + break; + } + + var cur = categoryName[i]; + if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) + { + buffer[cursor++] = (byte)cur; + ++validNameLength; + } + } + + // Backfilling MessagePack serialization protocol and valid category length to the startIdx of the categoryName byte array. + MessagePackSerializer.WriteStr8Header(buffer, 0, validNameLength); + + return cursor; + } + + private byte[] ResolveTableMappingForCategoryName(string categoryName) + { + var tableNameCache = this.m_tableNameCache; + + if (tableNameCache.TryGetValue(categoryName, out byte[] tableName)) + { + return tableName; + } + + return this.ResolveTableMappingForCategoryNameRare(categoryName); + } + + private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) + { + byte[] mappedTableName = null; + + // If user configured table name mappings run resolution logic. + if (this.m_tableMappings != null + && !this.m_tableMappings.TryGetValue(categoryName, out mappedTableName)) + { + // Find best match if an exact match was not found. + + string currentKey = null; + + foreach (var mapping in this.m_tableMappings) + { + if (!categoryName.StartsWith(mapping.Key, DictionaryKeyComparison)) + { + continue; + } + + if (currentKey == null || mapping.Key.Length >= currentKey.Length) + { + currentKey = mapping.Key; + mappedTableName = mapping.Value; + } + } + } + + mappedTableName ??= !this.m_shouldPassThruTableMappings + ? this.m_defaultTableName + : s_passthroughTableName; + + Span sanitizedTableNameStorage = mappedTableName == s_passthroughTableName + ? stackalloc byte[MaxSanitizedCategoryNameBytes] + : Array.Empty(); + + if (sanitizedTableNameStorage.Length > 0) + { + // We resolved to a wildcard which is pass-through mode. + + int bytesWritten = WriteSanitizedCategoryNameToSpan(sanitizedTableNameStorage, categoryName); + if (bytesWritten > 0) + { + sanitizedTableNameStorage = sanitizedTableNameStorage.Slice(0, bytesWritten); + } + else + { + // Note: When the table name could not be sanitized we cache + // the empty array NOT s_passthroughTableName. + mappedTableName = Array.Empty(); + } + } + + lock (this.m_lockObject) + { + var tableNameCache = this.m_tableNameCache; + + // Check if another thread added the mapping while we waited on the + // lock. + if (tableNameCache.TryGetValue(categoryName, out byte[] tableName)) + { + return tableName; + } + + if (mappedTableName == s_passthroughTableName + && tableNameCache.CachedSanitizedTableNameCount < MaxCachedSanitizedTableNames) + { + mappedTableName = sanitizedTableNameStorage.ToArray(); + tableNameCache.CachedSanitizedTableNameCount++; + } + + // Note: This is using copy-on-write pattern to keep the happy + // path lockless once everything has spun up. + TableNameCacheDictionary newTableNameCache = new(tableNameCache) + { + [categoryName] = mappedTableName, + }; + + this.m_tableNameCache = newTableNameCache; + + return mappedTableName; + } + } + + // Note: This is used for tests. + public interface ITableNameCacheDictionary : IReadOnlyDictionary + { + int CachedSanitizedTableNameCount { get; } + } + + private sealed class TableNameCacheDictionary : Dictionary, ITableNameCacheDictionary + { + public TableNameCacheDictionary() + : base(0, s_dictionaryKeyComparer) + { + } + + public TableNameCacheDictionary(TableNameCacheDictionary sourceCache) + : base(sourceCache, s_dictionaryKeyComparer) + { + this.CachedSanitizedTableNameCount = sourceCache.CachedSanitizedTableNameCount; + } + + public int CachedSanitizedTableNameCount { get; set; } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index 5236c386cf..6d8ed0bb9c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -350,6 +350,13 @@ public static void WriteStr8Header(byte[] buffer, int nameStartIdx, int validNam buffer[nameStartIdx + 1] = unchecked((byte)validNameLength); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteStr8Header(Span buffer, int nameStartIdx, int validNameLength) + { + buffer[nameStartIdx] = STR8; + buffer[nameStartIdx + 1] = unchecked((byte)validNameLength); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeAsciiString(byte[] buffer, int cursor, string value) { @@ -373,7 +380,7 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string value) } else { - throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); + throw new ArgumentException($"The input string: \"{value}\" has non-ASCII characters in it.", nameof(value)); } } @@ -390,7 +397,7 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string value) } else { - throw new ArgumentException("The input string: \"{inputString}\" has non-ASCII characters in it.", value); + throw new ArgumentException($"The input string: \"{value}\" has non-ASCII characters in it.", nameof(value)); } } @@ -656,7 +663,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) #endif default: - string repr = null; + string repr; try { @@ -671,9 +678,17 @@ public static int Serialize(byte[] buffer, int cursor, object obj) } } - public static int SerializeSpan(byte[] buffer, int cursor, Span value) + public static int SerializeSpan(byte[] buffer, int cursor, ReadOnlySpan value) { + var length = value.Length; + + if (length == 0) + { + return SerializeNull(buffer, cursor); + } + value.CopyTo(buffer.AsSpan(cursor)); - return cursor + value.Length; + + return cursor + length; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs index f543b01689..f825c033a0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs @@ -58,7 +58,7 @@ protected static int AddPartAField(byte[] buffer, int cursor, string name, objec return cursor; } - protected static int AddPartAField(byte[] buffer, int cursor, string name, Span value) + protected static int AddPartAField(byte[] buffer, int cursor, string name, ReadOnlySpan value) { if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) { diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 17dde9799a..9719da091a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -28,56 +28,27 @@ namespace OpenTelemetry.Exporter.Geneva; internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable { private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - private const int MaxSanitizedEventNameLength = 50; - private readonly IReadOnlyDictionary m_customFields; - - private readonly ExceptionStackExportMode m_exportExceptionStack; - - private readonly string m_defaultEventName = "Log"; - private readonly IReadOnlyDictionary m_prepopulatedFields; - private readonly List m_prepopulatedFieldKeys; private static readonly ThreadLocal m_buffer = new ThreadLocal(() => null); - private readonly byte[] m_bufferEpilogue; private static readonly string[] logLevels = new string[7] { "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", }; + private readonly TableNameSerializer m_tableNameSerializer; + private readonly Dictionary m_customFields; + private readonly Dictionary m_prepopulatedFields; + private readonly ExceptionStackExportMode m_exportExceptionStack; + private readonly List m_prepopulatedFieldKeys; + private readonly byte[] m_bufferEpilogue; private readonly IDataTransport m_dataTransport; - private readonly bool shouldPassThruTableMappings; private bool isDisposed; public MsgPackLogExporter(GenevaExporterOptions options) { + this.m_tableNameSerializer = new(options, defaultTableName: "Log"); this.m_exportExceptionStack = options.ExceptionStackExportMode; - // TODO: Validate mappings for reserved tablenames etc. - if (options.TableNameMappings != null) - { - var tempTableMappings = new Dictionary(options.TableNameMappings.Count, StringComparer.Ordinal); - foreach (var kv in options.TableNameMappings) - { - if (kv.Key == "*") - { - if (kv.Value == "*") - { - this.shouldPassThruTableMappings = true; - } - else - { - this.m_defaultEventName = kv.Value; - } - } - else - { - tempTableMappings[kv.Key] = kv.Value; - } - } - - this.m_tableMappings = tempTableMappings; - } - var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); switch (connectionStringBuilder.Protocol) { @@ -133,8 +104,6 @@ public MsgPackLogExporter(GenevaExporterOptions options) Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); } - private readonly IReadOnlyDictionary m_tableMappings; - public ExportResult Export(in Batch batch) { var result = ExportResult.Success; @@ -207,40 +176,8 @@ internal int SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); var categoryName = logRecord.CategoryName; - string eventName = null; - - Span sanitizedEventName = default; - - // If user configured explicit TableName, use it. - if (this.m_tableMappings != null && this.m_tableMappings.TryGetValue(categoryName, out eventName)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); - } - else if (!this.shouldPassThruTableMappings) - { - eventName = this.m_defaultEventName; - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, eventName); - } - else - { - int cursorStartIdx = cursor; - - if (categoryName.Length > 0) - { - cursor = SerializeSanitizedCategoryName(buffer, cursor, categoryName); - } - if (cursor == cursorStartIdx) - { - // Serializing null as categoryName could not be sanitized into a valid string. - cursor = MessagePackSerializer.SerializeNull(buffer, cursor); - } - else - { - // Sanitized category name has been serialized. - sanitizedEventName = buffer.AsSpan().Slice(cursorStartIdx, cursor - cursorStartIdx); - } - } + cursor = this.m_tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, cursor, categoryName, out ReadOnlySpan eventName); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); @@ -261,14 +198,7 @@ internal int SerializeLogRecord(LogRecord logRecord) } // Part A - core envelope - if (sanitizedEventName.Length != 0) - { - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, sanitizedEventName); - } - else - { - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); - } + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); cntFields += 1; @@ -493,61 +423,6 @@ private static byte GetSeverityNumber(LogLevel logLevel) } } - // This method would map the logger category to a table name which only contains alphanumeric values with the following additions: - // Any character that is not allowed will be removed. - // If the resulting string is longer than 50 characters, only the first 50 characters will be taken. - // If the first character in the resulting string is a lower-case alphabet, it will be converted to the corresponding upper-case. - // If the resulting string still does not comply with Rule, the category name will not be serialized. - private static int SerializeSanitizedCategoryName(byte[] buffer, int cursor, string categoryName) - { - int cursorStartIdx = cursor; - - // Reserve 2 bytes for storing LIMIT_MAX_STR8_LENGTH_IN_BYTES and (byte)validNameLength - - // these 2 bytes will be back filled after iterating through categoryName. - cursor += 2; - int validNameLength = 0; - - // Special treatment for the first character. - var firstChar = categoryName[0]; - if (firstChar >= 'A' && firstChar <= 'Z') - { - buffer[cursor++] = (byte)firstChar; - ++validNameLength; - } - else if (firstChar >= 'a' && firstChar <= 'z') - { - // If the first character in the resulting string is a lower-case alphabet, - // it will be converted to the corresponding upper-case. - buffer[cursor++] = (byte)(firstChar - 32); - ++validNameLength; - } - else - { - // Not a valid name. - return cursor -= 2; - } - - for (int i = 1; i < categoryName.Length; ++i) - { - if (validNameLength == MaxSanitizedEventNameLength) - { - break; - } - - var cur = categoryName[i]; - if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) - { - buffer[cursor++] = (byte)cur; - ++validNameLength; - } - } - - // Backfilling MessagePack serialization protocol and valid category length to the startIdx of the categoryName byte array. - MessagePackSerializer.WriteStr8Header(buffer, cursorStartIdx, validNameLength); - - return cursor; - } - private static string ToInvariantString(Exception exception) { var originalUICulture = Thread.CurrentThread.CurrentUICulture; diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 24b0ca1626..44d6a7ef25 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -104,14 +104,74 @@ sent through this exporter. This defines the mapping for the table name used to store Logs and Traces. -The default table name used for Traces is `Span`. For changing the table name -for Traces, add an entry with key as `Span`, and value as the custom table name. +##### Trace table name mappings -The default table name used for Logs is `Log`. Mappings can be specified for -each +The default table name used for Traces is `Span`. To change the table name for +Traces add an entry with the key `Span` and set the value to the desired custom +table name. + +**Note:** Only a single table name is supported for Traces. + +##### Log table name mappings + +The default table name used for Logs is `Log`. Mappings can be specified +universally or for individual log message [category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) -of the log. For changing the default table name for Logs, add an entry with key -as `*`, and value as the custom table name. +values. + +* To change the default table name for Logs add an entry with the key `*` and + set the value to the desired custom table name. To enable "pass-through" + mapping set the value of the `*` key to `*`. For details on "pass-through" + mode see below. + +* To change the table name for a specific log + [category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) + add an entry with the key set to the full "category" of the log messages or a + prefix that will match the starting portion of the log message "category". Set + the value of the key to either the desired custom table name or `*` to enable + "pass-through" mapping. For details on "pass-through" mode see below. + + For example, given the configuration... + + ```csharp + var options = new GenevaExporterOptions + { + TableNameMappings = new Dictionary() + { + ["*"] = "DefaultLogs", + ["MyCompany"] = "InternalLogs", + ["MyCompany.Product1"] = "InternalProduct1Logs", + ["MyCompany.Product2"] = "InternalProduct2Logs", + ["MyCompany.Product2.Security"] = "InternalSecurityLogs", + ["MyPartner"] = "*", + }, + }; + ``` + + ...log category mapping would be performed as such: + + * `ILogger`: This would go to "DefaultLogs" + * `ILogger`: This would go to "InternalLogs" + * `ILogger`: This would go to "InternalProduct1Logs" + * `ILogger`: This would go to "InternalProduct2Logs" + * `ILogger`: This would go to + "InternalSecurityLogs" + * `ILogger`: This is marked as pass-through ("*") so + it will be sanitized as "MyPartnerProductThing" table name + +##### Pass-through table name mapping rules + +When "pass-through" mapping is enabled for a given log message the runtime +[category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) +value will be converted into a valid table name. + +* The first character MUST be an ASCII letter. If it is lower-case, it will be + converted into an upper-case letter. If the first character is invalid all log + messages for the "category" will be dropped. + +* Any non-ASCII letter or number will be removed. + +* Only the first 50 valid characters will be used. ### Enable Metrics diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 4c6c4bc122..8252c80b4e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -87,12 +87,19 @@ public LogExporterBenchmarks() ["cloud.roleInstance"] = "CY1SCH030021417", ["cloud.roleVer"] = "9.0.15289.2", }; + exporterOptions.TableNameMappings = new Dictionary + { + ["*"] = "*", + ["TestCompany"] = "*", + ["TestCompany.TestNamespace"] = "*", + ["TestCompany.TestNamespace.TestLogger"] = "TestLoggerTable", + }; }); loggerOptions.IncludeFormattedMessage = this.IncludeFormattedMessage; })); - this.logger = this.loggerFactory.CreateLogger("TestLogger"); + this.logger = this.loggerFactory.CreateLogger("TestCompany.TestNamespace.TestLogger"); // For msgpack serialization + export this.logRecord = GenerateTestLogRecord(); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index edd959d1e8..b317583b58 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -76,7 +76,7 @@ public void SpecialCharactersInTableNameMappings() TableNameMappings = new Dictionary { ["TestCategory"] = null }, }; }); - Assert.Contains("A string-typed value provided for TableNameMappings must not be null, empty, or consist only of white-space characters.", ex.Message); + Assert.Contains("The table name mapping value provided for key 'TestCategory' was null, empty, or consisted only of white-space characters.", ex.Message); // Throw when TableNameMappings is null Assert.Throws(() => diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs new file mode 100644 index 0000000000..399c49584e --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs @@ -0,0 +1,158 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class TableNameSerializerTests +{ + [Theory] + [InlineData("Unknown", "DefaultLogs")] + [InlineData("Unknown", "LogTableName", "LogTableName")] + public void DefaultResolutionTests(string categoryName, string tableName, string defaultTableName = null) + { + var mappings = new Dictionary(); + + if (defaultTableName != null) + { + mappings["*"] = defaultTableName; + } + + var options = new GenevaExporterOptions + { + TableNameMappings = mappings, + }; + + RunTableNameSerializerTest(categoryName, tableName, options); + } + + [Theory] + [InlineData("Unknown", "Unknown")] + [InlineData("unknown.table", "Unknowntable")] + public void PassthroughResolutionTests(string categoryName, string tableName) + { + var options = new GenevaExporterOptions + { + TableNameMappings = new Dictionary() + { + ["*"] = "*", + }, + }; + + RunTableNameSerializerTest(categoryName, tableName, options); + } + + [Theory] + [InlineData("Unknown", "DefaultLogs")] + [InlineData("Prefix.Nonmatch", "PrefixNonmatch")] + [InlineData("Prefix.Sub.Nonmatch", "SubTableName")] + [InlineData("Prefix.Sub.Final", "FinalTableName")] + public void PrefixResolutionTests(string categoryName, string tableName) + { + var options = new GenevaExporterOptions + { + TableNameMappings = new Dictionary() + { + ["Prefix"] = "*", + ["Prefix.Sub"] = "SubTableName", + ["Prefix.Sub.Final"] = "FinalTableName", + }, + }; + + RunTableNameSerializerTest(categoryName, tableName, options); + } + + [Fact] + public void ResolvedTableNameCacheTest() + { + var options = new GenevaExporterOptions(); + + var buffer = new byte[1024]; + + var tableNameSerializer = new TableNameSerializer(options, "DefaultLogs"); + + Assert.Empty(tableNameSerializer.TableNameCache); + + tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, "MyCategory", out _); + + Assert.Single(tableNameSerializer.TableNameCache); + + tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, "MyCategory", out _); + + Assert.Single(tableNameSerializer.TableNameCache); + + tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, "MyCategory2", out _); + + Assert.Equal(2, tableNameSerializer.TableNameCache.Count); + + tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, "MyCategory2", out _); + + Assert.Equal(2, tableNameSerializer.TableNameCache.Count); + } + + [Fact] + public void TableNameCacheTest() + { + var options = new GenevaExporterOptions + { + TableNameMappings = new Dictionary() + { + ["*"] = "*", + }, + }; + + var buffer = new byte[1024]; + + var tableNameSerializer = new TableNameSerializer(options, "DefaultLogs"); + + var numberOfCategoryNames = TableNameSerializer.MaxCachedSanitizedTableNames * 2; + + for (int i = 0; i < numberOfCategoryNames; i++) + { + var categoryName = $"category.{i}-test"; + var sanitizedCategoryName = $"Category{i}test"; + + for (int c = 0; c < 10; c++) + { + var bytesWritten = tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, categoryName, out var tableName); + + Assert.Equal(sanitizedCategoryName.Length + 2, bytesWritten); + Assert.Equal(sanitizedCategoryName, Encoding.ASCII.GetString(tableName.ToArray(), 2, sanitizedCategoryName.Length)); + } + } + + var tableNameCache = tableNameSerializer.TableNameCache; + + Assert.NotNull(tableNameCache); + Assert.Equal(numberOfCategoryNames, tableNameCache.Count); + Assert.Equal(TableNameSerializer.MaxCachedSanitizedTableNames, tableNameCache.CachedSanitizedTableNameCount); + } + + private static void RunTableNameSerializerTest(string categoryName, string tableName, GenevaExporterOptions options) + { + var buffer = new byte[1024]; + + var tableNameSerializer = new TableNameSerializer(options, "DefaultLogs"); + + var bytesWritten = tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, categoryName, out var resolvedTableName); + + Assert.Equal(tableName.Length + 2, bytesWritten); + Assert.Equal(tableName, Encoding.ASCII.GetString(resolvedTableName.ToArray(), 2, tableName.Length)); + } +} From 2c91aa033f7f178b83775b7108c5874620717fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 16 Dec 2022 20:54:42 +0100 Subject: [PATCH 0459/1499] [Instrumentation.WCF] fix rpc.system tag (#837) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 2 ++ .../Implementation/WcfInstrumentationConstants.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index cc6fc94fce..dcac39f89e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OTel SDK version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) +* Change value `rpc.system` from `wcf` to `dotnet_wcf`. + ([#837](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/837)) ## 1.0.0-rc.7 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs index e3f934bb5e..6749eed88d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs @@ -31,5 +31,5 @@ internal static class WcfInstrumentationConstants public const string WcfChannelSchemeTag = "wcf.channel.scheme"; public const string WcfChannelPathTag = "wcf.channel.path"; - public const string WcfSystemValue = "wcf"; + public const string WcfSystemValue = "dotnet_wcf"; } From ae6271d88f31f6bdb6c901a4f45add0d27bb3047 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 16 Dec 2022 13:34:14 -0800 Subject: [PATCH 0460/1499] [GenevaExporter] Update MsgPackTraceExporter for new Enumerate* DS7 APIs (#838) * Update MsgPackTraceExporter for new Enumerate* DS7 APIs. * CHANGELOG update. * Empty links fix. --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 10 ++++++---- .../MsgPackExporter/MsgPackTraceExporter.cs | 15 +++++++++------ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 6d1edafd77..15cecc441a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -4,6 +4,11 @@ * Update OpenTelemetry to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) +* Add support in logs for prefix-based table name mapping configuration. + [#796](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/796) +* Updated the trace exporter to use the new performance APIs introduced in + `System.Diagnostics.DiagnosticSource` v7.0. + [#838](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/838) ## 1.4.0-beta.6 @@ -14,12 +19,9 @@ Released 2022-Dec-09 ([#797](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/797)) * Fix the overflow bucket value serialization for Histogram. ([#805](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/805)) -* Fix EventSource logging +* Fix EventSource logging. ([#813](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/813)) -* Add support in logs for prefix-based table name mapping configuration. - [#796](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/796) - ## 1.4.0-beta.5 Released 2022-Nov-21 diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index bdced95e7d..fabe5e492b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Runtime.InteropServices; using System.Threading; @@ -241,15 +240,18 @@ internal int SerializeActivity(Activity activity) cntFields += 1; } - var links = activity.Links; - if (links.Any()) + var linkEnumerator = activity.EnumerateLinks(); + if (linkEnumerator.MoveNext()) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "links"); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, ushort.MaxValue); // Note: always use Array16 for perf consideration var idxLinkPatch = cursor - 2; + ushort cntLink = 0; - foreach (var link in links) + do { + ref readonly var link = ref linkEnumerator.Current; + cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, 2); cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "toTraceId"); cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.TraceId.ToHexString()); @@ -257,6 +259,7 @@ internal int SerializeActivity(Activity activity) cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, link.Context.SpanId.ToHexString()); cntLink += 1; } + while (linkEnumerator.MoveNext()); MessagePackSerializer.WriteUInt16(buffer, idxLinkPatch, cntLink); cntFields += 1; @@ -274,7 +277,7 @@ internal int SerializeActivity(Activity activity) bool isStatusSuccess = true; string statusDescription = string.Empty; - foreach (var entry in activity.TagObjects) + foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) @@ -319,7 +322,7 @@ internal int SerializeActivity(Activity activity) cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); int idxMapSizeEnvPropertiesPatch = cursor - 2; - foreach (var entry in activity.TagObjects) + foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision if (this.m_dedicatedFields.ContainsKey(entry.Key)) From 285e419e8ec5ca1156ed7a1b99252297f65750e4 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 19 Dec 2022 11:38:34 -0800 Subject: [PATCH 0461/1499] minor refactoring on histogram bucket serialization (#826) --- .../Metrics/GenevaMetricExporter.cs | 29 +++++++++------- .../GenevaMetricExporterTests.cs | 33 +++++++++++-------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index fa250f7ab6..c07657db0d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using OpenTelemetry.Internal; @@ -423,17 +424,7 @@ internal unsafe ushort SerializeHistogramMetric( { if (bucket.BucketCount > 0) { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - } - else - { - // The bucket to catch the overflows is one greater than the last bound provided - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); - } - - MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + this.SerializeHistogramBucket(bucket, ref bufferIndex, lastExplicitBound); bucketCount++; } @@ -470,6 +461,22 @@ internal unsafe ushort SerializeHistogramMetric( return bodyLength; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeHistogramBucket(HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + } + private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) { var serializedKeys = new List(this.prepopulatedDimensionsCount); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 8c1ac1b6f5..da6afdc916 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -316,7 +316,7 @@ public void SuccessfulSerializationWithViews() { Name = "renamedhistogramWithCustomBounds", Description = "modifiedDescription", - Boundaries = new double[] { 500, 1000 }, + Boundaries = new double[] { 500, 1000, 10000 }, }) .AddView(instrument => { @@ -398,7 +398,8 @@ public void SuccessfulSerializationWithViews() // Record the following values for histogramWithCustomBounds: // (-inf - 500] : 3 // (500 - 1000] : 1 - // (1000 - +inf) : 1 + // (1000 - 10000] : 0 + // (10000 - +inf) : 1 // // The corresponding value-count pairs to be sent for histogramWithCustomBounds: // 500: 3 @@ -409,7 +410,7 @@ public void SuccessfulSerializationWithViews() histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(50000, new("tag1", "value1"), new("tag2", "value2")); // Record the following values for histogramWithNoBounds: // (-inf - 500] : 3 @@ -636,6 +637,20 @@ private static string GenerateTempFilePath() } } + private static void AssertHistogramBucketSerialization(HistogramBucket bucket, HistogramValueCountPairs valueCountPairs, int listIterator, double lastExplicitBound) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + Assert.Equal(bucket.ExplicitBound, valueCountPairs.Columns[listIterator].Value); + } + else + { + Assert.Equal((ulong)lastExplicitBound + 1, valueCountPairs.Columns[listIterator].Value); + } + + Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); + } + private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) { var metricType = metric.MetricType; @@ -765,17 +780,7 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE { if (bucket.BucketCount > 0) { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - Assert.Equal(bucket.ExplicitBound, valueCountPairs.Columns[listIterator].Value); - } - else - { - Assert.Equal((ulong)lastExplicitBound + 1, valueCountPairs.Columns[listIterator].Value); - } - - Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); - + AssertHistogramBucketSerialization(bucket, valueCountPairs, listIterator, lastExplicitBound); listIterator++; bucketsWithPositiveCount++; } From e955a0ee01fa2d07f1eb1cba0840f8011f177be6 Mon Sep 17 00:00:00 2001 From: Travis Troyer Date: Mon, 19 Dec 2022 15:19:37 -0500 Subject: [PATCH 0462/1499] [Exporter.Instana] Update Instana Transport with exception-handling and a couple of bug fixes. (#816) --- .../CHANGELOG.md | 6 ++ .../InstanaExporterEventSource.cs | 66 ++++++++++++++++ .../Implementation/InstanaSpanSerializer.cs | 11 +++ .../Implementation/SpanSender.cs | 2 +- .../Implementation/Transport.cs | 78 ++++++++++++------- 5 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index d7fc999064..d33dba8539 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Updated `Transport` with exception-handling and a couple of bug fixes ([#747](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/747)): + * Adds `InstanaExporterEventSource` to provide for error logging. + * Adds exception-handling to `Transport` with logging via `InstanaExporterEventSource`. + * Fixes `Transport` buffering to prevent exceeding underlying array capacity. + * Fixes `Transport` to prevent lost spans due to buffer length. + ## 1.0.1 Released 2022-Nov-02 diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs new file mode 100644 index 0000000000..8a5ede78f0 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs @@ -0,0 +1,66 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Threading; + +namespace OpenTelemetry.Exporter.Instana.Implementation; + +[EventSource(Name = "OpenTelemetry-Exporter-Instana")] +internal sealed class InstanaExporterEventSource : EventSource +{ + public static InstanaExporterEventSource Log = new(); + + private InstanaExporterEventSource() + { + } + + [NonEvent] + public void FailedExport(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.FailedExport(ToInvariantString(ex)); + } + } + + [Event(1, Message = "Failed to send spans: '{0}'", Level = EventLevel.Error)] + public void FailedExport(string exception) + { + this.WriteEvent(1, exception); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 55ca75cb51..ee1cb91b80 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -46,6 +46,17 @@ internal IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) return instanaSpan.Data.Events.GetEnumerator(); } + internal async Task SerializeToByteArrayAsync(InstanaSpan instanaSpan) + { + using var stream = new MemoryStream(); + using var writer = new StreamWriter(stream); + + await this.SerializeToStreamWriterAsync(instanaSpan, writer); + + await writer.FlushAsync(); + return stream.ToArray(); + } + internal async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) { await writer.WriteAsync(OPEN_BRACE); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index 81596ecc3f..5e79e63a10 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -45,7 +45,7 @@ private async void TaskSpanSender() while (true) { // check if we can send spans - if (this.spansQueue.TryPeek(out InstanaSpan dummySpan)) + if (this.spansQueue.TryPeek(out InstanaSpan _)) { // actually send spans await this.transport.SendSpansAsync(this.spansQueue); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index 49e4fd4bd9..9a95393fc7 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -26,6 +26,8 @@ namespace OpenTelemetry.Exporter.Instana.Implementation; internal class Transport { + private const int MultiSpanBufferLimit = 4096000; + private static readonly InstanaSpanSerializer InstanaSpanSerializer = new InstanaSpanSerializer(); private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); @@ -36,8 +38,6 @@ internal class Transport private static string bundleUrl = string.Empty; private static InstanaHttpClient client = null; - private readonly byte[] tracesBuffer = new byte[4096000]; - static Transport() { Configure(); @@ -50,44 +50,66 @@ internal bool IsAvailable internal async Task SendSpansAsync(ConcurrentQueue spanQueue) { - using (MemoryStream sendBuffer = new MemoryStream(this.tracesBuffer)) + try { - using (StreamWriter writer = new StreamWriter(sendBuffer)) + using (MemoryStream sendBuffer = new MemoryStream()) { - await writer.WriteAsync("{\"spans\":["); - bool first = true; - while (spanQueue.TryDequeue(out InstanaSpan span) && sendBuffer.Position < 4070000) + using (StreamWriter writer = new StreamWriter(sendBuffer)) { - if (!first) + await writer.WriteAsync("{\"spans\":["); + bool first = true; + + // peek instead of dequeue, because we don't yet know whether the next span + // fits within our MULTI_SPAN_BUFFER_LIMIT + while (spanQueue.TryPeek(out InstanaSpan span)) { - await writer.WriteAsync(","); - } + var serialized = await InstanaSpanSerializer.SerializeToByteArrayAsync(span); - first = false; - await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer); - } + if (!first) + { + if (sendBuffer.Length + serialized.Length > MultiSpanBufferLimit) + { + break; + } - await writer.WriteAsync("]}"); + await writer.WriteAsync(","); + } - await writer.FlushAsync(); - long length = sendBuffer.Position; - sendBuffer.Position = 0; + first = false; - HttpContent content = new StreamContent(sendBuffer, (int)length); - content.Headers.ContentType = MEDIAHEADER; - content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); + await sendBuffer.WriteAsync(serialized, 0, serialized.Length); - using (var httpMsg = new HttpRequestMessage() - { - Method = HttpMethod.Post, - RequestUri = new Uri(bundleUrl), - }) - { - httpMsg.Content = content; - var res = client.SendAsync(httpMsg).GetAwaiter().GetResult(); + // Now we can dequeue. Note, this means we'll be giving up/losing + // this span if we fail to send for any reason. + spanQueue.TryDequeue(out _); + } + + await writer.WriteAsync("]}"); + + await writer.FlushAsync(); + long length = sendBuffer.Position; + sendBuffer.Position = 0; + + HttpContent content = new StreamContent(sendBuffer, (int)length); + content.Headers.ContentType = MEDIAHEADER; + content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); + + using (var httpMsg = new HttpRequestMessage() + { + Method = HttpMethod.Post, + RequestUri = new Uri(bundleUrl), + }) + { + httpMsg.Content = content; + await client.SendAsync(httpMsg); + } } } } + catch (Exception e) + { + InstanaExporterEventSource.Log.FailedExport(e); + } } private static void Configure() From be1ecde2cbb07e1cef7574b5f790e9f8f1bb238f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 19 Dec 2022 15:34:56 -0800 Subject: [PATCH 0463/1499] [Exporter.Geneva] Avoid allocation for serializing scopes (#818) --- .../CHANGELOG.md | 3 + .../MsgPackExporter/MsgPackLogExporter.cs | 131 ++++++++++++------ .../MsgPackExporter/MsgPackTraceExporter.cs | 2 +- .../Exporter/LogExporterBenchmarks.cs | 53 +++---- 4 files changed, 113 insertions(+), 76 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 15cecc441a..da27836747 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -10,6 +10,9 @@ `System.Diagnostics.DiagnosticSource` v7.0. [#838](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/838) +* Avoid allocation when serializing scopes. + ([#818](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/818)) + ## 1.4.0-beta.6 Released 2022-Dec-09 diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 9719da091a..f02febac53 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -42,6 +42,9 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private readonly List m_prepopulatedFieldKeys; private readonly byte[] m_bufferEpilogue; private readonly IDataTransport m_dataTransport; + + // This is used for Scopes + private readonly ThreadLocal m_serializationData = new(() => null); private bool isDisposed; public MsgPackLogExporter(GenevaExporterOptions options) @@ -279,33 +282,29 @@ internal int SerializeLogRecord(LogRecord logRecord) cntFields += 1; } - logRecord.ForEachScope(ProcessScopeForIndividualColumns, (object)null); - void ProcessScopeForIndividualColumns(LogRecordScope scope, object state) + // Prepare state for scopes + var dataForScopes = this.m_serializationData.Value; + if (dataForScopes == null) { - foreach (KeyValuePair scopeItem in scope) + dataForScopes = new SerializationDataForScopes { - if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") - { - continue; - } + Buffer = buffer, + }; - if (this.m_customFields == null || this.m_customFields.ContainsKey(scopeItem.Key)) - { - if (scopeItem.Value != null) - { - // null is not supported. - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, scopeItem.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); - cntFields += 1; - } - } - else - { - hasEnvProperties = true; - } - } + this.m_serializationData.Value = dataForScopes; } + dataForScopes.Cursor = cursor; + dataForScopes.FieldsCount = cntFields; + dataForScopes.HasEnvProperties = hasEnvProperties; + + logRecord.ForEachScope(ProcessScopeForIndividualColumns, this); + + // Update the variables that could have been modified in ProcessScopeForIndividualColumns + hasEnvProperties = dataForScopes.HasEnvProperties; + cursor = dataForScopes.Cursor; + cntFields = dataForScopes.FieldsCount; + if (hasEnvProperties) { // Iteration #2 - Get all "other" fields and collapse them into single field @@ -329,24 +328,15 @@ void ProcessScopeForIndividualColumns(LogRecordScope scope, object state) } } - logRecord.ForEachScope(ProcessScopeForEnvProperties, (object)null); - void ProcessScopeForEnvProperties(LogRecordScope scope, object state) - { - foreach (KeyValuePair scopeItem in scope) - { - if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") - { - continue; - } - - if (!this.m_customFields.ContainsKey(scopeItem.Key)) - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, scopeItem.Key); - cursor = MessagePackSerializer.Serialize(buffer, cursor, scopeItem.Value); - envPropertiesCount += 1; - } - } - } + // Prepare state for scopes + dataForScopes.Cursor = cursor; + dataForScopes.EnvPropertiesCount = envPropertiesCount; + + logRecord.ForEachScope(ProcessScopeForEnvProperties, this); + + // Update the variables that could have been modified in ProcessScopeForEnvProperties + cursor = dataForScopes.Cursor; + envPropertiesCount = dataForScopes.EnvPropertiesCount; cntFields += 1; MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); @@ -449,6 +439,7 @@ public void Dispose() try { (this.m_dataTransport as IDisposable)?.Dispose(); + this.m_serializationData.Dispose(); this.m_prepopulatedFieldKeys.Clear(); } catch (Exception ex) @@ -458,4 +449,64 @@ public void Dispose() this.isDisposed = true; } + + private static readonly Action ProcessScopeForIndividualColumns = (scope, state) => + { + var stateData = state.m_serializationData.Value; + var customFields = state.m_customFields; + + foreach (KeyValuePair scopeItem in scope) + { + if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") + { + continue; + } + + if (customFields == null || customFields.ContainsKey(scopeItem.Key)) + { + if (scopeItem.Value != null) + { + // null is not supported. + stateData.Cursor = MessagePackSerializer.SerializeUnicodeString(stateData.Buffer, stateData.Cursor, scopeItem.Key); + stateData.Cursor = MessagePackSerializer.Serialize(stateData.Buffer, stateData.Cursor, scopeItem.Value); + stateData.FieldsCount += 1; + } + } + else + { + stateData.HasEnvProperties = true; + } + } + }; + + private static readonly Action ProcessScopeForEnvProperties = (scope, state) => + { + var stateData = state.m_serializationData.Value; + var customFields = state.m_customFields; + + foreach (KeyValuePair scopeItem in scope) + { + if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") + { + continue; + } + + if (!customFields.ContainsKey(scopeItem.Key)) + { + stateData.Cursor = MessagePackSerializer.SerializeUnicodeString(stateData.Buffer, stateData.Cursor, scopeItem.Key); + stateData.Cursor = MessagePackSerializer.Serialize(stateData.Buffer, stateData.Cursor, scopeItem.Value); + stateData.EnvPropertiesCount += 1; + } + } + }; + + private class SerializationDataForScopes + { + public bool HasEnvProperties; + public ushort EnvPropertiesCount; + + public int Cursor; + public byte[] Buffer; + public ushort FieldsCount; + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index fabe5e492b..9ff607ad0a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -400,7 +400,7 @@ public void Dispose() private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - private readonly ThreadLocal m_buffer = new ThreadLocal(() => null); + private readonly ThreadLocal m_buffer = new(() => null); private readonly byte[] m_bufferPrologue; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 8252c80b4e..73857fa604 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -20,42 +20,25 @@ using OpenTelemetry.Logs; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621 +BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.819) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.100-preview.6.22352.1 - [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT - DefaultJob : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT - -Without Scopes - -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | -|-------------------------- |------------------------ |-----------:|--------:|--------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 1,273.1 ns | 6.09 ns | 5.39 ns | 0.0362 | 232 B | -| LoggerWithDirectLoggerAPI | False | 1,213.0 ns | 9.71 ns | 8.61 ns | 0.0572 | 368 B | -| LoggerWithSourceGenerator | False | 1,243.5 ns | 6.13 ns | 5.44 ns | 0.0305 | 192 B | -| SerializeLogRecord | False | 587.7 ns | 2.71 ns | 2.54 ns | - | - | -| Export | False | 955.0 ns | 5.46 ns | 5.11 ns | - | - | -| LoggerWithMessageTemplate | True | 1,261.1 ns | 6.59 ns | 5.84 ns | 0.0362 | 232 B | -| LoggerWithDirectLoggerAPI | True | 1,214.4 ns | 4.56 ns | 4.27 ns | 0.0572 | 368 B | -| LoggerWithSourceGenerator | True | 1,229.6 ns | 6.84 ns | 6.40 ns | 0.0305 | 192 B | -| SerializeLogRecord | True | 581.6 ns | 2.38 ns | 2.11 ns | - | - | -| Export | True | 958.4 ns | 3.02 ns | 2.52 ns | - | - | - - -With Scopes (https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/545) - -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen 0 | Allocated | -|-------------------------- |------------------------ |-----------:|--------:|--------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 1,280.8 ns | 7.45 ns | 6.61 ns | 0.0534 | 336 B | -| LoggerWithDirectLoggerAPI | False | 1,261.5 ns | 6.38 ns | 5.96 ns | 0.0744 | 472 B | -| LoggerWithSourceGenerator | False | 1,309.3 ns | 4.83 ns | 4.52 ns | 0.0458 | 296 B | -| SerializeLogRecord | False | 611.3 ns | 4.63 ns | 4.11 ns | 0.0162 | 104 B | -| Export | False | 1,012.2 ns | 7.56 ns | 7.07 ns | 0.0153 | 104 B | -| LoggerWithMessageTemplate | True | 1,278.3 ns | 6.63 ns | 5.88 ns | 0.0534 | 336 B | -| LoggerWithDirectLoggerAPI | True | 1,263.8 ns | 8.26 ns | 7.73 ns | 0.0744 | 472 B | -| LoggerWithSourceGenerator | True | 1,273.4 ns | 5.57 ns | 5.21 ns | 0.0458 | 296 B | -| SerializeLogRecord | True | 604.3 ns | 2.83 ns | 2.65 ns | 0.0162 | 104 B | -| Export | True | 1,003.6 ns | 9.29 ns | 8.69 ns | 0.0153 | 104 B | +.NET SDK=7.0.100 + [Host] : .NET 6.0.11 (6.0.1122.52304), X64 RyuJIT AVX2 + DefaultJob : .NET 6.0.11 (6.0.1122.52304), X64 RyuJIT AVX2 + + +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen0 | Allocated | +|-------------------------- |------------------------ |---------:|--------:|--------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 832.5 ns | 5.99 ns | 5.00 ns | 0.0162 | 104 B | +| LoggerWithDirectLoggerAPI | False | 766.2 ns | 3.85 ns | 3.60 ns | 0.0381 | 240 B | +| LoggerWithSourceGenerator | False | 815.3 ns | 2.89 ns | 2.41 ns | 0.0095 | 64 B | +| SerializeLogRecord | False | 582.3 ns | 0.81 ns | 0.72 ns | - | - | +| Export | False | 646.0 ns | 1.10 ns | 0.86 ns | - | - | +| LoggerWithMessageTemplate | True | 847.7 ns | 5.56 ns | 5.20 ns | 0.0162 | 104 B | +| LoggerWithDirectLoggerAPI | True | 762.5 ns | 2.72 ns | 2.41 ns | 0.0381 | 240 B | +| LoggerWithSourceGenerator | True | 816.6 ns | 2.79 ns | 2.47 ns | 0.0095 | 64 B | +| SerializeLogRecord | True | 586.3 ns | 1.80 ns | 1.69 ns | - | - | +| Export | True | 659.5 ns | 6.00 ns | 5.61 ns | - | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; From a8878f9d1e1c3155da6a6e1b0a29bb6e369b62ce Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 19 Dec 2022 16:13:22 -0800 Subject: [PATCH 0464/1499] comment (#842) --- .../Metrics/GenevaMetricExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index c07657db0d..d5715c3222 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -462,7 +462,7 @@ internal unsafe ushort SerializeHistogramMetric( } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SerializeHistogramBucket(HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) + private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) { if (bucket.ExplicitBound != double.PositiveInfinity) { From 0f3a06d570473b28755b62397577c13a6b16e848 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 19 Dec 2022 16:33:13 -0800 Subject: [PATCH 0465/1499] Update CHANGELOG for 1.4.0-rc.1 release (#843) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index da27836747..bd66234461 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-rc.1 + +Released 2022-Dec-19 + * Update OpenTelemetry to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) * Add support in logs for prefix-based table name mapping configuration. @@ -9,7 +13,6 @@ * Updated the trace exporter to use the new performance APIs introduced in `System.Diagnostics.DiagnosticSource` v7.0. [#838](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/838) - * Avoid allocation when serializing scopes. ([#818](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/818)) From c6178b57c917792224cbe1241a77606849216493 Mon Sep 17 00:00:00 2001 From: Travis Troyer Date: Mon, 19 Dec 2022 19:44:11 -0600 Subject: [PATCH 0466/1499] Update CHANGELOG.md (#844) * Update CHANGELOG.md --- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index d33dba8539..f39eaafc71 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog -## Unreleased +## 1.0.2 + +Released 2022-Dec-20 * Updated `Transport` with exception-handling and a couple of bug fixes ([#747](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/747)): * Adds `InstanaExporterEventSource` to provide for error logging. From db4b1cadfb84945d773241162e1dfdc57e531d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 20 Dec 2022 06:38:05 +0100 Subject: [PATCH 0467/1499] [Exporter.Instana] Bring back Unreleased Changelog section (#848) --- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index f39eaafc71..7be4707f2d 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## Unreleased + ## 1.0.2 Released 2022-Dec-20 From 20f0e42d5ca5dffa95f9feedaf377c1b93dad8ca Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 20 Dec 2022 11:50:08 -0800 Subject: [PATCH 0468/1499] Update EventCounters Instrumentation (#845) --- .../EventCountersInstrumentationOptions.cs | 6 +-- .../EventCountersMetrics.cs | 40 ++++++++++++++++++- .../MeterProviderBuilderExtensions.cs | 3 +- ...metry.Instrumentation.EventCounters.csproj | 1 + 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs index d373e03fb8..ecf08249fd 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Instrumentation.EventCounters; /// public class EventCountersInstrumentationOptions { - private readonly HashSet eventSourceNames = new(); + internal readonly HashSet EventSourceNames = new(); /// /// Gets or sets the subscription interval in seconds for reading values @@ -44,7 +44,7 @@ public void AddEventSources(params string[] names) throw new NotSupportedException("Use the `OpenTelemetry.Instrumentation.Runtime` or `OpenTelemetry.Instrumentation.Process` instrumentations."); } - this.eventSourceNames.UnionWith(names); + this.EventSourceNames.UnionWith(names); } /// @@ -54,6 +54,6 @@ public void AddEventSources(params string[] names) /// true when an EventSource with the name should be enabled. internal bool ShouldListenToSource(string eventSourceName) { - return this.eventSourceNames.Contains(eventSourceName); + return this.EventSourceNames.Contains(eventSourceName); } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index fe8f89dacc..d39b8dd44b 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Diagnostics.Tracing; +using System.Globalization; namespace OpenTelemetry.Instrumentation.EventCounters; @@ -34,8 +35,10 @@ internal sealed class EventCountersMetrics : EventListener private readonly EventCountersInstrumentationOptions options; private readonly List preInitEventSources = new(); + private readonly List enabledEventSources = new(); private readonly ConcurrentDictionary<(string, string), Instrument> instruments = new(); private readonly ConcurrentDictionary<(string, string), double> values = new(); + private bool isDisposed; /// /// Initializes a new instance of the class. @@ -52,6 +55,7 @@ public EventCountersMetrics(EventCountersInstrumentationOptions options) if (this.options.ShouldListenToSource(eventSource.Name)) { this.EnableEvents(eventSource); + this.enabledEventSources.Add(eventSource); } } @@ -59,11 +63,42 @@ public EventCountersMetrics(EventCountersInstrumentationOptions options) } } + /// + public override void Dispose() + { + if (!this.isDisposed) + { + lock (this.preInitEventSources) + { + if (!this.isDisposed) + { + foreach (var eventSource in this.enabledEventSources) + { + this.DisableEvents(eventSource); + } + + this.isDisposed = true; + } + } + + // DO NOT clear the ConcurrentDictionary instances as some other thread executing the OnEventWritten callback might be using them + this.enabledEventSources.Clear(); + this.options.EventSourceNames.Clear(); + } + + base.Dispose(); + } + /// protected override void OnEventSourceCreated(EventSource eventSource) { lock (this.preInitEventSources) { + if (this.isDisposed) + { + return; + } + if (this.options == null) { this.preInitEventSources.Add(eventSource); @@ -71,6 +106,7 @@ protected override void OnEventSourceCreated(EventSource eventSource) else if (this.options.ShouldListenToSource(eventSource.Name)) { this.EnableEvents(eventSource); + this.enabledEventSources.Add(eventSource); } } } @@ -116,12 +152,12 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) return; } - var value = Convert.ToDouble(hasMean ? mean : increment); + var value = Convert.ToDouble(hasMean ? mean : increment, CultureInfo.InvariantCulture); this.UpdateInstrumentWithEvent(hasMean, eventSourceName, name, value); } private static Dictionary GetEnableEventsArguments(EventCountersInstrumentationOptions options) => - new() { { "EventCounterIntervalSec", options.RefreshIntervalSecs.ToString() } }; + new() { { "EventCounterIntervalSec", options.RefreshIntervalSecs.ToString(CultureInfo.InvariantCulture) } }; /// /// If the resulting instrument name is too long, it trims the event source name diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index 8dedcb5ef5..a0202c04be 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -40,8 +40,7 @@ public static MeterProviderBuilder AddEventCountersInstrumentation( var options = new EventCountersInstrumentationOptions(); configure?.Invoke(options); - var instrumentation = new EventCountersMetrics(options); builder.AddMeter(EventCountersMetrics.MeterInstance.Name); - return builder.AddInstrumentation(() => instrumentation); + return builder.AddInstrumentation(() => new EventCountersMetrics(options)); } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 886f83bec0..ec5f3e960a 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -4,6 +4,7 @@ OpenTelemetry Metrics instrumentation for Dotnet EventCounters $(PackageTags);metrics;eventcounters Instrumentation.EventCounters- + true enable From d38102c4d12f023df05e15e8fe092665e4564d58 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 20 Dec 2022 12:53:55 -0800 Subject: [PATCH 0469/1499] Enable Code Analysis for AzureMonitor Extensions (#846) --- .../ApplicationInsightsSampler.cs | 7 +++++-- .../OpenTelemetry.Extensions.AzureMonitor.csproj | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 04198a1078..4e1d38e5fe 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -71,7 +71,7 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame return this.recordAndSampleSamplingResult; } - double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToLowerInvariant()); + double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToUpperInvariant()); if (sampleScore < this.samplingRatio) { @@ -90,7 +90,10 @@ private static double DJB2SampleScore(string traceIdHex) for (int i = 0; i < traceIdHex.Length; i++) { - hash = ((hash << 5) + hash) + (int)traceIdHex[i]; + unchecked + { + hash = (hash << 5) + hash + (int)traceIdHex[i]; + } } // Take the absolute value of the hash diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 18d1eeca8a..6be2f3683f 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -5,6 +5,7 @@ $(TargetFrameworks);net462 $(TargetFrameworks);net6.0 Extensions.AzureMonitor- + true From f6777d787f94c7ef5d34a94cd494a11b3cf24da7 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 20 Dec 2022 13:24:41 -0800 Subject: [PATCH 0470/1499] Remove unnecessary code analysis warning exceptions (#847) --- .../Metrics/GenevaMetricExporter.cs | 4 +-- .../MsgPackExporter/MsgPackTraceExporter.cs | 34 +++++++++---------- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index d5715c3222..97b6b366b8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -33,6 +33,8 @@ public class GenevaMetricExporter : BaseExporter internal const int MaxDimensionValueSize = 1024; + private static readonly MetricData ulongZero = new MetricData { UInt64Value = 0 }; + private readonly ushort prepopulatedDimensionsCount; private readonly int fixedPayloadStartIndex; @@ -55,8 +57,6 @@ public class GenevaMetricExporter : BaseExporter private readonly int bufferIndexForHistogramMetrics; - private static readonly MetricData ulongZero = new MetricData { UInt64Value = 0 }; - private bool isDisposed; public GenevaMetricExporter(GenevaMetricExporterOptions options) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 9ff607ad0a..da97f746a2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -400,6 +400,23 @@ public void Dispose() private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); + + private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary + { + ["db.system"] = "dbSystem", + ["db.name"] = "dbName", + ["db.statement"] = "dbStatement", + + ["http.method"] = "httpMethod", + ["http.url"] = "httpUrl", + ["http.status_code"] = "httpStatusCode", + + ["messaging.system"] = "messagingSystem", + ["messaging.destination"] = "messagingDestination", + ["messaging.url"] = "messagingUrl", + }; + private readonly ThreadLocal m_buffer = new(() => null); private readonly byte[] m_bufferPrologue; @@ -418,22 +435,5 @@ public void Dispose() private readonly IReadOnlyDictionary m_dedicatedFields; - private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - - private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary - { - ["db.system"] = "dbSystem", - ["db.name"] = "dbName", - ["db.statement"] = "dbStatement", - - ["http.method"] = "httpMethod", - ["http.url"] = "httpUrl", - ["http.status_code"] = "httpStatusCode", - - ["messaging.system"] = "messagingSystem", - ["messaging.destination"] = "messagingDestination", - ["messaging.url"] = "messagingUrl", - }; - private bool isDisposed; } diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 4beabc729f..b2c9982436 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -4,7 +4,7 @@ true An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors - $(NoWarn),NU5104,CS1591,SA1123,SA1310,CA1031,CA1810,CA1822,CA2000,CA2208,SA1204,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 + $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- From 994f90512c907f9c6c6affbcf8977f95a35af511 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 16:00:26 -0800 Subject: [PATCH 0471/1499] Bump actions/stale from 6 to 7 (#850) Bumps [actions/stale](https://github.com/actions/stale) from 6 to 7. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .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 39e8be83df..4fb58ec613 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v6 + - uses: actions/stale@v7 with: stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' From 4d5909e0089dc8e2149af5eb9095580edb2fb6ce Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 21 Dec 2022 10:07:48 -0800 Subject: [PATCH 0472/1499] Update EventCounter unit tests (#849) --- .../EventCountersMetricsTests.cs | 85 +++++++++---------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index dba23b470f..39816f8389 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.Tracing; -using System.Linq; using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; @@ -29,33 +28,33 @@ public class EventCountersMetricsTests private const int Delay = 1200; [Fact(Skip = "Other tests metrics are being exported here")] - public async Task NoMetricsByDefault() + public void NoMetricsByDefault() { // Arrange List metricItems = new(); - var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCountersInstrumentation() + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(null) .AddInMemoryExporter(metricItems) .Build(); // Act - await Task.Delay(Delay); + Task.Delay(Delay).Wait(); meterProvider.ForceFlush(); // Assert Assert.Empty(metricItems); } - [Fact(Skip = "Unstable")] - public async Task EventCounter() + [Fact] + public void EventCounter() { // Arrange List metricItems = new(); - EventSource source = new("a"); - EventCounter counter = new("c", source); + using EventSource source = new("a"); + using EventCounter counter = new("c", source); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -65,7 +64,7 @@ public async Task EventCounter() // Act counter.WriteMetric(1997.0202); - await Task.Delay(Delay); + Task.Delay(Delay).Wait(); meterProvider.ForceFlush(); // Assert @@ -76,14 +75,14 @@ public async Task EventCounter() } [Fact] - public async Task IncrementingEventCounter() + public void IncrementingEventCounter() { // Arrange List metricItems = new(); - EventSource source = new("b"); - IncrementingEventCounter incCounter = new("inc-c", source); + using EventSource source = new("b"); + using IncrementingEventCounter incCounter = new("inc-c", source); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -95,7 +94,7 @@ public async Task IncrementingEventCounter() incCounter.Increment(1); incCounter.Increment(1); incCounter.Increment(1); - await Task.Delay(Delay); + Task.Delay(Delay).Wait(); meterProvider.ForceFlush(); // Assert @@ -106,15 +105,15 @@ public async Task IncrementingEventCounter() } [Fact(Skip = "Unstable")] - public async Task PollingCounter() + public void PollingCounter() { // Arrange int i = 0; List metricItems = new(); - EventSource source = new("c"); - PollingCounter pollCounter = new("poll-c", source, () => ++i * 10); + using EventSource source = new("c"); + using PollingCounter pollCounter = new("poll-c", source, () => ++i * 10); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -123,7 +122,7 @@ public async Task PollingCounter() .Build(); // Act - await Task.Delay(Delay * 2); + Task.Delay(Delay * 2).Wait(); meterProvider.ForceFlush(); // Assert @@ -134,15 +133,15 @@ public async Task PollingCounter() } [Fact(Skip = "Unstable")] - public async Task IncrementingPollingCounter() + public void IncrementingPollingCounter() { // Arrange int i = 1; List metricItems = new(); - EventSource source = new("d"); - IncrementingPollingCounter incPollCounter = new("inc-poll-c", source, () => i++); + using EventSource source = new("d"); + using IncrementingPollingCounter incPollCounter = new("inc-poll-c", source, () => i++); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -151,7 +150,7 @@ public async Task IncrementingPollingCounter() .Build(); // Act - await Task.Delay(Delay * 2); + Task.Delay(Delay * 2).Wait(); meterProvider.ForceFlush(); // Assert @@ -161,16 +160,16 @@ public async Task IncrementingPollingCounter() Assert.Equal(2, GetActualValue(metric)); } - [Fact(Skip = "Unstable")] - public async Task EventCounterSameNameUsesNewestCreated() + [Fact] + public void EventCounterSameNameUsesNewestCreated() { // Arrange List metricItems = new(); - EventSource source = new("a"); - EventCounter counter = new("c", source); - EventCounter counter2 = new("c", source); + using EventSource source = new("a"); + using EventCounter counter = new("c", source); + using EventCounter counter2 = new("c", source); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -181,7 +180,7 @@ public async Task EventCounterSameNameUsesNewestCreated() // Act counter2.WriteMetric(1980.1208); counter.WriteMetric(1997.0202); - await Task.Delay(Delay); + Task.Delay(Delay).Wait(); meterProvider.ForceFlush(); // Assert @@ -224,14 +223,14 @@ public void ThrowExceptionForUnsupportedEventSources() [InlineData("Microsoft.AspNetCore.One.Two", "very-very-very-very-very-very-very-very-very-long-event-name", "ec.very-very-very-very-very-very-very-very-very-long-event-name")] [InlineData("Microsoft.AspNetCore.One.Two", "very-very-very-very-very-very-very-very-long-event-name", "ec.Micr.very-very-very-very-very-very-very-very-long-event-name")] [InlineData("Microsoft.AspNetCore.One.Two", "very-very-very-very-very-very-very-long-event-name", "ec.Microsoft.very-very-very-very-very-very-very-long-event-name")] - public async Task EventSourceNameShortening(string sourceName, string eventName, string expectedInstrumentName) + public void EventSourceNameShortening(string sourceName, string eventName, string expectedInstrumentName) { // Arrange List metricItems = new(); - EventSource source = new(sourceName); - IncrementingEventCounter connections = new(eventName, source); + using EventSource source = new(sourceName); + using IncrementingEventCounter connections = new(eventName, source); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -241,7 +240,7 @@ public async Task EventSourceNameShortening(string sourceName, string eventName, // Act connections.Increment(1); - await Task.Delay(Delay); + Task.Delay(Delay).Wait(); meterProvider.ForceFlush(); // Assert @@ -251,17 +250,17 @@ public async Task EventSourceNameShortening(string sourceName, string eventName, } [Fact] - public async Task InstrumentNameTooLong() + public void InstrumentNameTooLong() { // Arrange List metricItems = new(); - EventSource source = new("source"); + using EventSource source = new("source"); // ec.s. + event name is 63; string veryLongEventName = new string('e', 100); - IncrementingEventCounter connections = new(veryLongEventName, source); + using IncrementingEventCounter connections = new(veryLongEventName, source); - var meterProvider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddEventCountersInstrumentation(options => { options.AddEventSources(source.Name); @@ -271,7 +270,7 @@ public async Task InstrumentNameTooLong() // Act connections.Increment(1); - await Task.Delay(Delay); + Task.Delay(Delay).Wait(); meterProvider.ForceFlush(); // Assert From 6d8dcef68635b0a4f28d40dacf5a074ed84d00bf Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 21 Dec 2022 13:54:15 -0800 Subject: [PATCH 0473/1499] Refactor unit tests (#851) --- .../Exporter/TraceExporterBenchmarks.cs | 1 - .../GenevaLogExporterTests.cs | 1 + .../GenevaTraceExporterTests.cs | 1 + .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 6 ------ .../xunit.runner.json | 4 ---- .../ElasticsearchClientTests.cs | 2 -- .../RuntimeMetricsTests.cs | 2 +- .../TelemetryClientMessageInspectorTests.cs | 7 +++++-- 8 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 test/OpenTelemetry.Exporter.Stackdriver.Tests/xunit.runner.json diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index 3956343f72..f18741d6b9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.Collections.Generic; using System.Diagnostics; using BenchmarkDotNet.Attributes; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index b317583b58..aaae6f5149 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -24,6 +24,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 1f8cab0c1a..f66032f065 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -24,6 +24,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index a9f56947da..6c6c093e4e 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -6,12 +6,6 @@ $(TargetFrameworks);net462 - - - PreserveNewest - - - diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/xunit.runner.json b/test/OpenTelemetry.Exporter.Stackdriver.Tests/xunit.runner.json deleted file mode 100644 index 9fbc901158..0000000000 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/xunit.runner.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "maxParallelThreads": 1, - "parallelizeTestCollections": false -} \ No newline at end of file diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 38e276e2a0..d873f5fa49 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -13,11 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. // -using System; using System.Diagnostics; using System.Linq; using System.Text; -using System.Threading; using System.Threading.Tasks; using Elasticsearch.Net; using Moq; diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index d9509a5411..2418165a2c 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -133,7 +133,7 @@ public void ThreadingRelatedMetricsTest() List tasks = new List(); for (int i = 0; i < taskCount; i++) { - tasks.Add(Task.Run(() => { Console.Write("Hi"); })); + tasks.Add(Task.Run(() => { })); } Task.WaitAll(tasks.ToArray()); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs index 5e535f3f57..88c6a3b85d 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs @@ -53,7 +53,7 @@ public TelemetryClientMessageInspectorTests() } catch { - this.listener.Stop(); + this.listener.Close(); this.listener = null; retryCount--; } @@ -128,7 +128,10 @@ async void Listener() public void Dispose() { - this.listener?.Stop(); + if (this.listener != null) + { + (this.listener as IDisposable).Dispose(); + } } [Theory] From 9a9c21623660ab90021e3e2d78294b50d13cc6cd Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 27 Dec 2022 10:07:30 -0800 Subject: [PATCH 0474/1499] Update GenevaExporter benchmarks (#852) --- .../Exporter/LogExporterBenchmarks.cs | 36 ++++++------- .../Exporter/MetricExporterBenchmarks.cs | 40 +++++++------- .../Exporter/TraceExporterBenchmarks.cs | 53 ++++++++++++++----- ...Telemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../README.md | 2 +- 5 files changed, 81 insertions(+), 52 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 73857fa604..b7aab62793 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -20,25 +20,25 @@ using OpenTelemetry.Logs; /* -BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.819) +BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.100 - [Host] : .NET 6.0.11 (6.0.1122.52304), X64 RyuJIT AVX2 - DefaultJob : .NET 6.0.11 (6.0.1122.52304), X64 RyuJIT AVX2 - - -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen0 | Allocated | -|-------------------------- |------------------------ |---------:|--------:|--------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 832.5 ns | 5.99 ns | 5.00 ns | 0.0162 | 104 B | -| LoggerWithDirectLoggerAPI | False | 766.2 ns | 3.85 ns | 3.60 ns | 0.0381 | 240 B | -| LoggerWithSourceGenerator | False | 815.3 ns | 2.89 ns | 2.41 ns | 0.0095 | 64 B | -| SerializeLogRecord | False | 582.3 ns | 0.81 ns | 0.72 ns | - | - | -| Export | False | 646.0 ns | 1.10 ns | 0.86 ns | - | - | -| LoggerWithMessageTemplate | True | 847.7 ns | 5.56 ns | 5.20 ns | 0.0162 | 104 B | -| LoggerWithDirectLoggerAPI | True | 762.5 ns | 2.72 ns | 2.41 ns | 0.0381 | 240 B | -| LoggerWithSourceGenerator | True | 816.6 ns | 2.79 ns | 2.47 ns | 0.0095 | 64 B | -| SerializeLogRecord | True | 586.3 ns | 1.80 ns | 1.69 ns | - | - | -| Export | True | 659.5 ns | 6.00 ns | 5.61 ns | - | - | +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + + +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen0 | Allocated | +|-------------------------- |------------------------ |-----------:|---------:|---------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 1,221.9 ns | 17.52 ns | 15.53 ns | 0.0153 | 104 B | +| LoggerWithDirectLoggerAPI | False | 1,109.6 ns | 22.14 ns | 34.47 ns | 0.0381 | 240 B | +| LoggerWithSourceGenerator | False | 1,117.7 ns | 9.94 ns | 7.76 ns | 0.0095 | 64 B | +| SerializeLogRecord | False | 560.0 ns | 2.87 ns | 2.40 ns | - | - | +| Export | False | 891.0 ns | 17.06 ns | 32.05 ns | - | - | +| LoggerWithMessageTemplate | True | 1,243.7 ns | 24.79 ns | 35.55 ns | 0.0153 | 104 B | +| LoggerWithDirectLoggerAPI | True | 1,090.8 ns | 12.85 ns | 10.04 ns | 0.0381 | 240 B | +| LoggerWithSourceGenerator | True | 1,186.1 ns | 23.58 ns | 45.99 ns | 0.0095 | 64 B | +| SerializeLogRecord | True | 564.8 ns | 5.20 ns | 4.06 ns | - | - | +| Export | True | 874.5 ns | 17.38 ns | 24.37 ns | - | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index ecadc44be7..81644f50c2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -23,31 +23,31 @@ using OpenTelemetry.Metrics; /* -BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.674) +BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.100-preview.6.22352.1 - [Host] : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2 - DefaultJob : .NET 6.0.10 (6.0.1022.47605), X64 RyuJIT AVX2 +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 | Method | Mean | Error | StdDev | Allocated | |--------------------------------------------------------- |----------:|---------:|---------:|----------:| -| InstrumentWithNoListener3Dimensions | 67.73 ns | 0.232 ns | 0.217 ns | - | -| InstrumentWithNoListener4Dimensions | 109.41 ns | 0.593 ns | 0.526 ns | - | -| InstrumentWithWithListener3Dimensions | 70.75 ns | 0.336 ns | 0.314 ns | - | -| InstrumentWithWithListener4Dimensions | 111.69 ns | 0.455 ns | 0.403 ns | - | -| InstrumentWithWithDummyReader3Dimensions | 187.26 ns | 1.206 ns | 1.128 ns | - | -| InstrumentWithWithDummyReader4Dimensions | 254.82 ns | 0.931 ns | 0.777 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 177.80 ns | 1.325 ns | 1.239 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 255.63 ns | 4.011 ns | 3.752 ns | - | -| SerializeCounterMetricItemWith3Dimensions | 176.72 ns | 0.858 ns | 0.803 ns | - | -| SerializeCounterMetricItemWith4Dimensions | 211.00 ns | 1.069 ns | 1.000 ns | - | -| ExportCounterMetricItemWith3Dimensions | 448.24 ns | 3.487 ns | 3.091 ns | - | -| ExportCounterMetricItemWith4Dimensions | 489.01 ns | 4.478 ns | 3.739 ns | - | -| SerializeHistogramMetricItemWith3Dimensions | 303.49 ns | 5.922 ns | 7.050 ns | - | -| SerializeHistogramMetricItemWith4Dimensions | 330.51 ns | 3.240 ns | 3.030 ns | - | -| ExportHistogramMetricItemWith3Dimensions | 610.94 ns | 3.551 ns | 2.965 ns | - | -| ExportHistogramMetricItemWith4Dimensions | 632.27 ns | 1.829 ns | 1.528 ns | - | +| InstrumentWithNoListener3Dimensions | 64.11 ns | 0.169 ns | 0.132 ns | - | +| InstrumentWithNoListener4Dimensions | 116.30 ns | 0.547 ns | 0.427 ns | - | +| InstrumentWithWithListener3Dimensions | 65.40 ns | 0.422 ns | 0.395 ns | - | +| InstrumentWithWithListener4Dimensions | 112.80 ns | 0.465 ns | 0.435 ns | - | +| InstrumentWithWithDummyReader3Dimensions | 189.56 ns | 0.994 ns | 0.930 ns | - | +| InstrumentWithWithDummyReader4Dimensions | 258.45 ns | 3.355 ns | 2.974 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 193.18 ns | 2.468 ns | 2.309 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 257.24 ns | 1.017 ns | 0.901 ns | - | +| SerializeCounterMetricItemWith3Dimensions | 153.20 ns | 0.609 ns | 0.540 ns | - | +| SerializeCounterMetricItemWith4Dimensions | 176.57 ns | 0.708 ns | 0.662 ns | - | +| ExportCounterMetricItemWith3Dimensions | 420.11 ns | 2.434 ns | 2.033 ns | - | +| ExportCounterMetricItemWith4Dimensions | 440.69 ns | 6.733 ns | 5.968 ns | - | +| SerializeHistogramMetricItemWith3Dimensions | 264.51 ns | 2.299 ns | 2.038 ns | - | +| SerializeHistogramMetricItemWith4Dimensions | 294.36 ns | 1.159 ns | 1.084 ns | - | +| ExportHistogramMetricItemWith3Dimensions | 565.85 ns | 6.144 ns | 4.797 ns | - | +| ExportHistogramMetricItemWith4Dimensions | 591.38 ns | 4.704 ns | 4.170 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index f18741d6b9..c55fdee970 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -20,17 +20,18 @@ using OpenTelemetry.Trace; /* -BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621 +BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.100-preview.6.22352.1 - [Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT - DefaultJob : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Gen 0 | Allocated | -|------------------ |---------:|--------:|--------:|-------:|----------:| -| ExportActivity | 719.9 ns | 5.83 ns | 5.45 ns | 0.0057 | 40 B | -| SerializeActivity | 361.7 ns | 1.09 ns | 0.97 ns | 0.0062 | 40 B | +| Method | Mean | Error | StdDev | Median | Gen0 | Allocated | +|--------------------------------- |---------:|---------:|---------:|---------:|-------:|----------:| +| ExportActivity | 566.3 ns | 3.13 ns | 2.44 ns | 565.9 ns | - | - | +| SerializeActivity | 313.3 ns | 1.71 ns | 1.60 ns | 313.0 ns | - | - | +| CreateActivityWithGenevaExporter | 940.5 ns | 18.77 ns | 54.14 ns | 911.4 ns | 0.0648 | 416 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; @@ -41,6 +42,7 @@ public class TraceExporterBenchmarks private readonly Activity activity; private readonly Batch batch; private readonly MsgPackTraceExporter exporter; + private readonly TracerProvider tracerProvider; private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); public TraceExporterBenchmarks() @@ -49,7 +51,8 @@ public TraceExporterBenchmarks() this.batch = this.CreateBatch(); - using var activityListener = new ActivityListener + #region Create activity to be used for Serialize and Export benchmark methods + var activityListener = new ActivityListener { ActivityStarted = null, ActivityStopped = null, @@ -62,11 +65,14 @@ public TraceExporterBenchmarks() using (var testActivity = this.activitySource.StartActivity("Benchmark")) { this.activity = testActivity; - this.activity?.SetTag("tagString", "value"); - this.activity?.SetTag("tagInt", 100); - this.activity?.SetStatus(Status.Error); + this.activity.SetTag("tagString", "value"); + this.activity.SetTag("tagInt", 100); + this.activity.SetStatus(Status.Error); } + activityListener.Dispose(); + #endregion + this.exporter = new MsgPackTraceExporter(new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", @@ -77,6 +83,21 @@ public TraceExporterBenchmarks() ["cloud.roleVer"] = "9.0.15289.2", }, }); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(this.activitySource.Name) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); } [Benchmark] @@ -91,6 +112,13 @@ public void SerializeActivity() this.exporter.SerializeActivity(this.activity); } + [Benchmark] + public void CreateActivityWithGenevaExporter() + { + // this activity will be created and sent to Geneva exporter + using var activity = this.activitySource.StartActivity("Benchmark"); + } + [GlobalCleanup] public void Cleanup() { @@ -98,6 +126,7 @@ public void Cleanup() this.activitySource.Dispose(); this.batch.Dispose(); this.exporter.Dispose(); + this.tracerProvider.Dispose(); } private Batch CreateBatch() diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 72bcabffc2..05cdcfab4d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md b/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md index 34fdfc14e3..51535d27ae 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md @@ -4,7 +4,7 @@ Navigate to `./test/OpenTelemetry.Exporter.Geneva.Benchmark` directory and run the following command: ```sh -dotnet run -c Release -f net6.0 -- -m +dotnet run -c Release -f net7.0 -- -m `` Then choose the benchmark class that you want to run by entering the required From 2d89c6e585ff9238a52ac877e90aa632c78f76ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 28 Dec 2022 07:33:42 +0100 Subject: [PATCH 0475/1499] [Instrumentation.WCF] Release 1.0.0-rc.8 (#858) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index dcac39f89e..8d25c1f862 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.8 + +Released 2022-Dec-28 + * Update OTel SDK version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) * Change value `rpc.system` from `wcf` to `dotnet_wcf`. From 791bfc3688e06e9d8514100b7d2add0674806a06 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 28 Dec 2022 22:02:27 -0800 Subject: [PATCH 0476/1499] Update versions of common packages used in tests and examples (#857) --- build/Common.nonprod.props | 6 +++--- examples/AspNet/Examples.AspNet.csproj | 6 +++--- .../Examples.GrpcCore.AspNetCore.csproj | 8 ++++---- examples/owin/Examples.Owin.csproj | 4 ++-- examples/wcf/README.md | 4 ++-- ...proj => Examples.Wcf.Client.DotNet.csproj} | 10 +++++----- .../Examples.Wcf.Client.NetFramework.csproj | 4 ++-- .../Examples.Wcf.Server.NetFramework.csproj | 4 ++-- opentelemetry-dotnet-contrib.sln | 2 +- .../AssemblyInfo.cs | 19 +++++++++++++++++++ ...penTelemetry.Exporter.Geneva.Stress.csproj | 2 +- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- ...metry.Extensions.AzureMonitor.Tests.csproj | 4 ++-- ...mentation.EntityFrameworkCore.Tests.csproj | 8 ++++---- .../DiagnosticsMiddlewareTests.cs | 2 +- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 2 +- 16 files changed, 53 insertions(+), 34 deletions(-) rename examples/wcf/client-core/{Examples.Wcf.Client.Core.csproj => Examples.Wcf.Client.DotNet.csproj} (82%) create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/AssemblyInfo.cs diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 2b63c35109..c9f464dd5d 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -20,11 +20,11 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [0.13.2,0.14) - [3.1.2,4.0.0) + [0.13.3,0.14) + [3.2.0,4.0.0) [2.3.1,3.0) [5.0.0,7.0) - [16.11.0,17.0) + [17.3.2,18.0) [4.18.3,5.0) [4.17.2,5.0) $(OpenTelemetryCoreLatestVersion) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index e3f43cf21f..4bdaadfa59 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -76,9 +76,9 @@ - - - + + + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 375fd7eb0d..0f4dde502a 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -1,13 +1,13 @@ - + net6.0 - - - + + + diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index de45e39449..228382acc7 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/examples/wcf/README.md b/examples/wcf/README.md index c97490f97c..177ab8d29d 100644 --- a/examples/wcf/README.md +++ b/examples/wcf/README.md @@ -2,10 +2,10 @@ Project structure: -* Examples.Wcf.Client.Core +* Examples.Wcf.Client.DotNet An example of how to call a WCF service with OpenTelemetry instrumentation on - .NET Core. + .NET. * Examples.Wcf.Client.NetFramework diff --git a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj similarity index 82% rename from examples/wcf/client-core/Examples.Wcf.Client.Core.csproj rename to examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index 388c75e0d8..3fa7c8ea19 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.Core.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -1,16 +1,16 @@ - + Exe - netcoreapp3.1 + net7.0 - - - + + + diff --git a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj index 4a02ccb2cf..2e846ea19e 100644 --- a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj +++ b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj @@ -1,4 +1,4 @@ - + Exe @@ -6,7 +6,7 @@ - + diff --git a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj index 4a02ccb2cf..2e846ea19e 100644 --- a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj +++ b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj @@ -1,4 +1,4 @@ - + Exe @@ -6,7 +6,7 @@ - + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 20cb582f52..6b60979c80 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -106,7 +106,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wcf", "wcf", "{73474960-8F9 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Shared", "examples\wcf\shared\Examples.Wcf.Shared.csproj", "{21716C26-3B2A-4208-BDFB-8E58E2AF49EA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.Core", "examples\wcf\client-core\Examples.Wcf.Client.Core.csproj", "{3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.DotNet", "examples\wcf\client-core\Examples.Wcf.Client.DotNet.csproj", "{3AF5D7E4-CA7D-401B-9729-A6D8F63B023C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.NetFramework", "examples\wcf\client-netframework\Examples.Wcf.Client.NetFramework.csproj", "{2A7867E5-0FD6-42F8-B594-19E897EDA54C}" EndProject diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/AssemblyInfo.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/AssemblyInfo.cs new file mode 100644 index 0000000000..15a0b20209 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/AssemblyInfo.cs @@ -0,0 +1,19 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 63d4f9301e..3aec212cfe 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 72991b1339..71e8440a75 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 7e7d23d2a9..24e2365463 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index a479ca5dbc..295bcd9432 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation @@ -6,15 +6,15 @@ - + - + - + diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 3f48ffe817..4d90b5073b 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -87,7 +87,7 @@ public DiagnosticsMiddlewareTests() } catch { - this.listener.Dispose(); + this.listener?.Dispose(); this.listener = null; retryCount--; } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index e0a36b7a6b..cfd0ec573c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -27,7 +27,7 @@ - + From 6cb05434e0899f45f112ba607bad70d3aae2c4ad Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 3 Jan 2023 09:39:18 -0800 Subject: [PATCH 0477/1499] Update guard and shim internals. (#856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../NotNullWhenAttribute.cs | 32 ---------- ...ions.PersistentStorage.Abstractions.csproj | 6 +- ...emetry.Extensions.PersistentStorage.csproj | 4 +- src/OpenTelemetry.Internal/Guard.cs | 62 ++++++++++++------- src/OpenTelemetry.Internal/IsExternalInit.cs | 25 ++++++++ .../NullableAttributes.cs | 51 +++++++++++++++ 6 files changed, 121 insertions(+), 59 deletions(-) delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs create mode 100644 src/OpenTelemetry.Internal/IsExternalInit.cs create mode 100644 src/OpenTelemetry.Internal/NullableAttributes.cs diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs deleted file mode 100644 index c3c3ffad49..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/NotNullWhenAttribute.cs +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#if NETSTANDARD2_0 || NET462 -namespace System.Diagnostics.CodeAnalysis; - -[AttributeUsage(AttributeTargets.All)] -internal sealed class NotNullWhenAttribute : Attribute -{ - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => this.ReturnValue = returnValue; - - /// Gets a value indicating whether gets the return value condition. - public bool ReturnValue { get; } -} -#endif diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj index eaa49f4591..e2f23516fc 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -15,4 +15,8 @@ true + + + + diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj index 931b637b7a..afe749a640 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Internal/Guard.cs b/src/OpenTelemetry.Internal/Guard.cs index 1b6348cd83..09bc0f8e93 100644 --- a/src/OpenTelemetry.Internal/Guard.cs +++ b/src/OpenTelemetry.Internal/Guard.cs @@ -14,46 +14,50 @@ // limitations under the License. // +#nullable enable + using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Runtime.CompilerServices; using System.Threading; -#if !NETCOREAPP3_0_OR_GREATER +#pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable SA1403 // File may only contain a single namespace +#pragma warning disable SA1649 // File name should match first type name + +#if !NET6_0_OR_GREATER namespace System.Runtime.CompilerServices { - /// - /// Allows capturing of the expressions passed to a method. - /// + /// Allows capturing of the expressions passed to a method. [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] -#pragma warning disable SA1402 // File may only contain a single type -#pragma warning disable SA1649 // File name should match first type name internal sealed class CallerArgumentExpressionAttribute : Attribute -#pragma warning restore SA1649 // File name should match first type name -#pragma warning restore SA1402 // File may only contain a single type { - /// - /// Initializes a new instance of the class. - /// - /// The name of the targeted parameter. public CallerArgumentExpressionAttribute(string parameterName) { this.ParameterName = parameterName; } - /// - /// Gets the target parameter name of the CallerArgumentExpression. - /// public string ParameterName { get; } } } #endif -#nullable enable +#if !NETCOREAPP3_0_OR_GREATER && !NETSTANDARD2_1_OR_GREATER +namespace System.Diagnostics.CodeAnalysis +{ + /// Specifies that an output is not even if + /// the corresponding type allows it. Specifies that an input argument was + /// not when the call returns. + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] + internal sealed class NotNullAttribute : Attribute + { + } +} +#endif -#pragma warning disable SA1403 // File may only contain a single namespace namespace OpenTelemetry.Internal -#pragma warning restore SA1403 // File may only contain a single namespace { /// /// Methods for guarding against exception throwing values. @@ -67,7 +71,7 @@ internal static class Guard /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNull(object value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfNull([NotNull] object? value, [CallerArgumentExpression("value")] string? paramName = null) { if (value is null) { @@ -82,13 +86,15 @@ public static void ThrowIfNull(object value, [CallerArgumentExpression("value")] /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNullOrEmpty(string value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfNullOrEmpty([NotNull] string? value, [CallerArgumentExpression("value")] string? paramName = null) +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. { if (string.IsNullOrEmpty(value)) { throw new ArgumentException("Must not be null or empty", paramName); } } +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. /// /// Throw an exception if the value is null or whitespace. @@ -97,13 +103,15 @@ public static void ThrowIfNullOrEmpty(string value, [CallerArgumentExpression("v /// The parameter name to use in the thrown exception. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ThrowIfNullOrWhitespace(string value, [CallerArgumentExpression("value")] string? paramName = null) + public static void ThrowIfNullOrWhitespace([NotNull] string? value, [CallerArgumentExpression("value")] string? paramName = null) +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. { if (string.IsNullOrWhiteSpace(value)) { throw new ArgumentException("Must not be null or whitespace", paramName); } } +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. /// /// Throw an exception if the value is zero. @@ -176,11 +184,11 @@ public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression("va /// The value casted to the specified type. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T ThrowIfNotOfType(object value, [CallerArgumentExpression("value")] string? paramName = null) + public static T ThrowIfNotOfType([NotNull] object? value, [CallerArgumentExpression("value")] string? paramName = null) { if (value is not T result) { - throw new InvalidCastException($"Cannot cast '{paramName}' from '{value.GetType().Name}' to '{typeof(T).Name}'"); + throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'"); } return result; @@ -195,7 +203,13 @@ private static void Range(T value, string? paramName, T min, T max, string? m { var minMessage = minName != null ? $": {minName}" : string.Empty; var maxMessage = maxName != null ? $": {maxName}" : string.Empty; - var exMessage = message ?? $"Must be in the range: [{min}{minMessage}, {max}{maxMessage}]"; + var exMessage = message ?? string.Format( + CultureInfo.InvariantCulture, + "Must be in the range: [{0}{1}, {2}{3}]", + min, + minMessage, + max, + maxMessage); throw new ArgumentOutOfRangeException(paramName, value, exMessage); } } diff --git a/src/OpenTelemetry.Internal/IsExternalInit.cs b/src/OpenTelemetry.Internal/IsExternalInit.cs new file mode 100644 index 0000000000..de19a976dd --- /dev/null +++ b/src/OpenTelemetry.Internal/IsExternalInit.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER +namespace System.Runtime.CompilerServices +{ + // This enabled "init" keyword in net462 + netstandard2.0 targets. + internal sealed class IsExternalInit + { + } +} +#endif diff --git a/src/OpenTelemetry.Internal/NullableAttributes.cs b/src/OpenTelemetry.Internal/NullableAttributes.cs new file mode 100644 index 0000000000..78bcfeab9a --- /dev/null +++ b/src/OpenTelemetry.Internal/NullableAttributes.cs @@ -0,0 +1,51 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Source: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs + +#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 +namespace System.Diagnostics.CodeAnalysis +{ + /// 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 + { + } + + /// Specifies that an output may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] + internal sealed class MaybeNullAttribute : Attribute + { + } + + /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] + internal sealed class NotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } +} +#endif From 5dad712e4fa8cac64ba6597a2ab35ac4e02eee19 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 3 Jan 2023 13:19:33 -0800 Subject: [PATCH 0478/1499] Update CodeCoverage workflow (#859) --- .github/workflows/dotnet-core-cov.yml | 7 ++++--- build/process-codecoverage.ps1 | 8 ++++++-- opentelemetry-dotnet-contrib.sln | 1 - 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index e4e75760e6..315acf1cef 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -18,13 +18,14 @@ jobs: fail-fast: false matrix: os: [windows-latest] - env: - OS: ${{ matrix.os }} steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - name: Setup .NET 7.0 + uses: actions/setup-dotnet@v3.0.3 with: dotnet-version: '7.0.x' diff --git a/build/process-codecoverage.ps1 b/build/process-codecoverage.ps1 index 33e35e431e..f2df16b80c 100644 --- a/build/process-codecoverage.ps1 +++ b/build/process-codecoverage.ps1 @@ -1,8 +1,12 @@ -$files = Get-ChildItem "TestResults" -Filter "*.coverage" -Recurse +[xml]$commonProps = Get-Content -Path $PSScriptRoot\Common.props +$microsoftCodeCoveragePkgVer = [string]$commonProps.Project.PropertyGroup.MicrosoftCodeCoveragePkgVer # This is collected in the format: "[16.10.0]" +$microsoftCodeCoveragePkgVer = $microsoftCodeCoveragePkgVer.Trim(); +$microsoftCodeCoveragePkgVer = $microsoftCodeCoveragePkgVer.SubString(1, $microsoftCodeCoveragePkgVer.Length - 2) # Removing square brackets +$files = Get-ChildItem "TestResults" -Filter "*.coverage" -Recurse Write-Host $env:USERPROFILE foreach ($file in $files) { - $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\16.11.0\build\netstandard1.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName + $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\' + $microsoftCodeCoveragePkgVer + '\build\netstandard1.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName Write-Host $command Invoke-Expression $command } diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6b60979c80..5c61596560 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -19,7 +19,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A06E14B-DD2F-4536-9D2E-F708C0C43555}" ProjectSection(SolutionItems) = preProject - .github\codecov.yml = .github\codecov.yml CODEOWNERS = CODEOWNERS .github\component_owners.yml = .github\component_owners.yml EndProjectSection From 7199b4ab65d3b21a689ba401b0c41647bca1ba5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 4 Jan 2023 08:22:23 +0100 Subject: [PATCH 0479/1499] Fix tests executed in code coverage (#863) --- .../AssemblyInfo.cs | 19 +++++++++++++++++++ .../HttpInMetricsListenerTests.cs | 8 ++++---- 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs new file mode 100644 index 0000000000..15a0b20209 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs @@ -0,0 +1,19 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index f4d27ffd1b..8ba1903aa2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -36,9 +36,9 @@ public void HttpDurationMetricIsEmitted() new HttpResponse(new StringWriter())); // This is to enable activity creation - // as it is created using activitysource inside TelemetryHttpModule + // as it is created using ActivitySource inside TelemetryHttpModule // TODO: This should not be needed once the dependency on activity is removed from metrics - using var traceprovider = Sdk.CreateTracerProviderBuilder() + using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetInstrumentation(opts => opts.Enrich = (activity, eventName, rawObject) => { @@ -50,7 +50,7 @@ public void HttpDurationMetricIsEmitted() .Build(); var exportedItems = new List(); - using var meterprovider = Sdk.CreateMeterProviderBuilder() + using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddAspNetInstrumentation() .AddInMemoryExporter(exportedItems) .Build(); @@ -58,7 +58,7 @@ public void HttpDurationMetricIsEmitted() var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); - meterprovider.ForceFlush(); + meterProvider.ForceFlush(); var metricPoints = new List(); foreach (var p in exportedItems[0].GetMetricPoints()) From 5cf88795fdb2ed47443943c933c7ee62853b8c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 4 Jan 2023 19:08:14 +0100 Subject: [PATCH 0480/1499] [Instrumentation.Elasticsearch] Update readme - new library (#866) --- .../README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index b446359b08..7037108954 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -1,17 +1,20 @@ # Elasticsearch Client Instrumentation for OpenTelemetry .NET +## NEST/Elasticsearch.Net + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) -Automatically instruments events emitted by the NEST/Elasticsearch.Net client library. +Automatically instruments events emitted by the [NEST/Elasticsearch.Net](https://www.nuget.org/packages/NEST) +client library. -## Installation +### Installation ```shell dotnet add package OpenTelemetry.Instrumentation.ElasticsearchClient ``` -## Configuration +### Configuration ASP.NET Core instrumentation example: @@ -26,9 +29,19 @@ services.AddOpenTelemetryTracing(x => }); ``` +## Elastic.Clients.Elasticsearch + +[Elastic.Clients.Elasticsearch](https://www.nuget.org/packages/Elastic.Clients.Elasticsearch), +that deprecates `NEST/Elasticsearch.Net`, +brings native support for OpenTelemetry. To instrument it you need +to configure the OpenTelemetry SDK to listen to the `ActivitySource` +used by the library by calling `AddSource("Elastic.Clients.Elasticsearch.ElasticsearchClient")` +on the `TracerProviderBuilder`. + ## References * [OpenTelemetry Project](https://opentelemetry.io/) * [Elasticsearch](https://www.elastic.co/) * [NEST Client](https://www.nuget.org/packages/NEST/) * [Elasticsearch.Net Client](https://www.nuget.org/packages/Elasticsearch.Net/) +* [Elastic.Clients.Elasticsearch](https://www.nuget.org/packages/Elastic.Clients.Elasticsearch/) From 446e0f326b0ede9a8f4e7a249b4d386257b29cf9 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Wed, 4 Jan 2023 19:51:17 +0100 Subject: [PATCH 0481/1499] Another null fix. (#840) --- .../Implementation/ActivityExtensions.cs | 4 ++-- .../StackdriverExporterTests.cs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 66cc89a6f0..ae96d6f927 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -83,9 +83,9 @@ public static Span ToSpan(this Activity activity, string projectId) { AttributeMap = { - activity.Tags?.ToDictionary( + activity.Tags.ToDictionary( s => s.Key, - s => s.Value?.ToAttributeValue()), + s => s.Value.ToAttributeValue()), }, }; } diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 509d831452..c9ac11bebd 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -193,6 +193,7 @@ internal static Activity CreateTestActivity( { "doubleKey2", 1F }, { "boolKey", true }, { "nullKey", null }, + { "http.url", null }, }; if (additionalAttributes != null) { @@ -225,7 +226,7 @@ internal static Activity CreateTestActivity( var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = setAttributes ? - attributes.Where(x => x.Value != null).Select(kvp => new KeyValuePair(kvp.Key, kvp.Value.ToString())) + attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value?.ToString())) : null; var links = addLinks ? new[] From 579fc472b99b7726b1c43bb446f87e1a90934cad Mon Sep 17 00:00:00 2001 From: Dawid Szmigielski Date: Thu, 5 Jan 2023 22:08:38 +0100 Subject: [PATCH 0482/1499] Add known issues to wcf documentation (#870) --- .../README.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 8f1cf1b389..9389335bd8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -212,6 +212,29 @@ contracts you want to instrument: } ``` +## Known issues + +WCF library does not provide any extension points to handle exception thrown on +communication (e.g. EndpointNotFoundException). Because of that in case of such +an event the `Activity` will not be stopped correctly. This can be handled in +an application code by catching the exception and stopping the `Activity` manually. + +```csharp + StatusResponse? response = null; + try + { + response = await client.PingAsync(statusRequest).ConfigureAwait(false); + } + catch (Exception) + { + var activity = Activity.Current; + if (activity != null && activity.Source.Name.Contains("OpenTelemetry.Instrumentation.Wcf")) + { + activity.Stop(); + } + } +``` + ## References * [OpenTelemetry Project](https://opentelemetry.io/) From a10f2878c38b85f50f3948dee0b5ffc8c262070f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 5 Jan 2023 13:52:35 -0800 Subject: [PATCH 0483/1499] Update the owner for OpenTelemetry.Extensions.Docker.Tests (#872) --- .github/component_owners.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 8bec8de3df..02eaec0e73 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -90,7 +90,7 @@ components: test/OpenTelemetry.Extensions.Tests/: - codeblanch test/OpenTelemetry.Extensions.Docker.Tests/: - - swetharavichandrancisco + - iskiselev test/OpenTelemetry.Extensions.PersistentStorage.Tests/: - vishweshbankwar test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: From 70f9f0f1b3686d3fb2bae9190d2b30438e2cc84b Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 5 Jan 2023 15:28:38 -0800 Subject: [PATCH 0484/1499] Update GenevaTraceExporter (#871) --- .../MsgPackExporter/MsgPackTraceExporter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index da97f746a2..605bc5f170 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Runtime.InteropServices; using System.Threading; @@ -286,7 +287,7 @@ internal int SerializeActivity(Activity activity) } else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) { - if (string.Equals(entry.Value.ToString(), "ERROR", StringComparison.Ordinal)) + if (string.Equals(Convert.ToString(entry.Value, CultureInfo.InvariantCulture), "ERROR", StringComparison.Ordinal)) { isStatusSuccess = false; } @@ -295,7 +296,7 @@ internal int SerializeActivity(Activity activity) } else if (string.Equals(entry.Key, "otel.status_description", StringComparison.Ordinal)) { - statusDescription = entry.Value.ToString(); + statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) From a9bb44da46064e771fc8894a0bd55ce0afece0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 9 Jan 2023 20:26:14 +0100 Subject: [PATCH 0485/1499] Remove Nullable from NoWarn (#864) --- build/Common.props | 5 ----- .../Implementation/ActivityExtensions.cs | 2 ++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../Internal/ActivityEventAttachingLogProcessor.cs | 2 +- .../Internal/DefaultLogStateConverter.cs | 10 +++++----- .../Logs/LogToActivityEventConversionOptions.cs | 2 +- .../Trace/AutoFlushActivityProcessor.cs | 2 +- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../MeterProviderBuilderExtensions.cs | 2 +- .../ProcessMetrics.cs | 2 ++ .../Processors/EventsActivityProcessorTests.cs | 2 ++ 13 files changed, 19 insertions(+), 18 deletions(-) diff --git a/build/Common.props b/build/Common.props index ff04e2dec8..e37f3faf47 100644 --- a/build/Common.props +++ b/build/Common.props @@ -37,11 +37,6 @@ [1.2.0-beta.435,2.0) - - - $(NoWarn);nullable - - diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index ae96d6f927..18a530fda9 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System.Collections.Generic; using System.Diagnostics; using System.Linq; diff --git a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt index 7104e3f8ec..0caf94ce2c 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt @@ -4,7 +4,7 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! +OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt index 7104e3f8ec..0caf94ce2c 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -4,7 +4,7 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! +OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7104e3f8ec..0caf94ce2c 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -4,7 +4,7 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! +OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index d52147dd1c..eb38ff899b 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -73,7 +73,7 @@ public override void OnEnd(LogRecord data) catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { - OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing state of type [{data.State.GetType().FullName}]", ex); + OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing state of type [{data.State?.GetType().FullName}]", ex); } } diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index 9b6e697a85..2f887ff53f 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -21,13 +21,13 @@ namespace OpenTelemetry.Logs; internal static class DefaultLogStateConverter { - public static void ConvertState(ActivityTagsCollection tags, IReadOnlyList> state) + public static void ConvertState(ActivityTagsCollection tags, IReadOnlyList> state) { for (int i = 0; i < state.Count; i++) { - KeyValuePair stateItem = state[i]; + KeyValuePair stateItem = state[i]; - object value = stateItem.Value; + object? value = stateItem.Value; if (value != null) { if (string.IsNullOrEmpty(stateItem.Key)) @@ -46,9 +46,9 @@ public static void ConvertScope(ActivityTagsCollection tags, int depth, LogRecor { string prefix = $"scope[{depth}]"; - foreach (KeyValuePair scopeItem in scope) + foreach (KeyValuePair scopeItem in scope) { - object value = scopeItem.Value; + object? value = scopeItem.Value; if (value != null) { if (string.IsNullOrEmpty(scopeItem.Key)) diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index a31058fe1f..3451f0775c 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -28,7 +28,7 @@ public class LogToActivityEventConversionOptions /// /// Gets or sets the callback action used to convert log state into tags. /// - public Action>> StateConverter { get; set; } = DefaultLogStateConverter.ConvertState; + public Action>> StateConverter { get; set; } = DefaultLogStateConverter.ConvertState; /// /// Gets or sets the callback action used to convert log scopes into tags. diff --git a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs index bf10f6666d..5a1827916c 100644 --- a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs +++ b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs @@ -87,7 +87,7 @@ public override void OnEnd(Activity data) var shouldFlush = this.RunPredicate(data); if (shouldFlush) { - this.tracerProvider.ForceFlush(this.timeoutMilliseconds); + this.tracerProvider!.ForceFlush(this.timeoutMilliseconds); } } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7321915c50..74ff134b83 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -4,4 +4,4 @@ OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions. OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions.RefreshIntervalSecs.get -> int OpenTelemetry.Instrumentation.EventCounters.EventCountersInstrumentationOptions.RefreshIntervalSecs.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddEventCountersInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder! \ No newline at end of file +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddEventCountersInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index a0202c04be..669d70a341 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -33,7 +33,7 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddEventCountersInstrumentation( this MeterProviderBuilder builder, - Action configure = null) + Action? configure = null) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 690e73398f..410c2f5ce4 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics.Metrics; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index ba761a9e35..4fda20fe75 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; From 7bd2fc9d8126bb48f0d29c8b38641e630aadad99 Mon Sep 17 00:00:00 2001 From: anoopbabu29 <32779456+anoopbabu29@users.noreply.github.com> Date: Mon, 9 Jan 2023 15:25:24 -0500 Subject: [PATCH 0486/1499] Added CGroupv2 support into Docker Extensions (#839) --- .../Resources/DockerResourceDetector.cs | 79 ++++++- .../Resources/DockerResourceDetectorTests.cs | 195 +++++++++++++----- 2 files changed, 208 insertions(+), 66 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs index fb6d25f452..a589117d37 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text.RegularExpressions; using OpenTelemetry.Extensions.Docker.Utils; using OpenTelemetry.Resources; @@ -28,6 +29,24 @@ namespace OpenTelemetry.Extensions.Docker.Resources; public class DockerResourceDetector : IResourceDetector { private const string FILEPATH = "/proc/self/cgroup"; + private const string FILEPATHV2 = "/proc/self/mountinfo"; + private const string HOSTNAME = "hostname"; + + /// + /// CGroup Parse Versions. + /// + internal enum ParseMode + { + /// + /// Represents CGroupV1. + /// + V1, + + /// + /// Represents CGroupV2. + /// + V2, + } /// /// Detects the resource attributes from Docker. @@ -35,17 +54,24 @@ public class DockerResourceDetector : IResourceDetector /// Resource with key-value pairs of resource attributes. public Resource Detect() { - return this.BuildResource(FILEPATH); + var cGroupBuild = this.BuildResource(FILEPATH, ParseMode.V1); + if (cGroupBuild == Resource.Empty) + { + cGroupBuild = this.BuildResource(FILEPATHV2, ParseMode.V2); + } + + return cGroupBuild; } /// /// Builds the resource attributes from Container Id in file path. /// /// File path where container id exists. + /// CGroup Version of file to parse from. /// Returns Resource with list of key-value pairs of container resource attributes if container id exists else empty resource. - internal Resource BuildResource(string path) + internal Resource BuildResource(string path, ParseMode cgroupVersion) { - var containerId = this.ExtractContainerId(path); + var containerId = this.ExtractContainerId(path, cgroupVersion); if (string.IsNullOrEmpty(containerId)) { @@ -58,11 +84,12 @@ internal Resource BuildResource(string path) } /// - /// Extracts Container Id from path. + /// Extracts Container Id from path using the cgroupv1 format. /// /// cgroup path. + /// CGroup Version of file to parse from. /// Container Id, Null if not found or exception being thrown. - private string ExtractContainerId(string path) + private string ExtractContainerId(string path, ParseMode cgroupVersion) { try { @@ -73,7 +100,19 @@ private string ExtractContainerId(string path) foreach (string line in File.ReadLines(path)) { - string containerId = (!string.IsNullOrEmpty(line)) ? this.GetIdFromLine(line) : null; + string containerId = null; + if (!string.IsNullOrEmpty(line)) + { + if (cgroupVersion == ParseMode.V1) + { + containerId = this.GetIdFromLineV1(line); + } + else if (cgroupVersion == ParseMode.V2 && line.Contains(HOSTNAME)) + { + containerId = this.GetIdFromLineV2(line); + } + } + if (!string.IsNullOrEmpty(containerId)) { return containerId; @@ -89,11 +128,11 @@ private string ExtractContainerId(string path) } /// - /// Gets the Container Id from the line after removing the prefix and suffix. + /// Gets the Container Id from the line after removing the prefix and suffix from the cgroupv1 format. /// /// line read from cgroup file. - /// Container Id. - private string GetIdFromLine(string line) + /// Container Id, Null if not found. + private string GetIdFromLineV1(string line) { // This cgroup output line should have the container id in it int lastSlashIndex = line.LastIndexOf('/'); @@ -116,6 +155,28 @@ private string GetIdFromLine(string line) return containerId; } + /// + /// Gets the Container Id from the line of the cgroupv2 format. + /// + /// line read from cgroup file. + /// Container Id, Null if not found. + private string GetIdFromLineV2(string line) + { + string containerId = null; + var match = Regex.Match(line, @".*/.+/([\w+-.]{64})/.*$"); + if (match.Success) + { + containerId = match.Groups[1].Value; + } + + if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) + { + return null; + } + + return containerId; + } + private string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) { startIndex = (startIndex == -1) ? 0 : startIndex + 1; diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs index 004410766e..5c50045727 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs +++ b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System.Collections.Generic; using System.IO; using System.Linq; using OpenTelemetry.Extensions.Docker.Resources; @@ -24,83 +25,152 @@ namespace OpenTelemetry.Extensions.Docker.Tests; public class DockerResourceDetectorTests { - // Invalid cgroup line - private const string INVALIDCGROUPLINE = - "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz"; - - // cgroup line with prefix - private const string CGROUPLINEWITHPREFIX = - "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff"; - - // Expected Container Id with prefix removed - private const string CONTAINERIDWITHPREFIXREMOVED = "e2cc29debdf85dde404998aa128997a819ff"; - - // cgroup line with suffix - private const string CGROUPLINEWITHSUFFIX = - "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa"; - - // Expected Container Id with suffix removed - private const string CONTAINERIDWITHSUFFIXREMOVED = "ac679f8a8319c8cf7d38e1adf263bc08d23"; - - // cgroup line with prefix and suffix - private const string CGROUPLINEWITHPREFIXandSUFFIX = - "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff"; - - // Expected Container Id with both prefix and suffix removed - private const string CONTAINERIDWITHPREFIXANDSUFFIXREMOVED = "dc679f8a8319c8cf7d38e1adf263bc08d23"; - - // cgroup line with container Id - private const string CGROUPLINE = - "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; - - // Expected Container Id - private const string CONTAINERID = - "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"; + private readonly List testValidCasesV1 = new() + { + new TestCase() + { + Name = "cgroupv1 with prefix", + Line = "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff", + ExpectedContainerId = "e2cc29debdf85dde404998aa128997a819ff", + CgroupVersion = DockerResourceDetector.ParseMode.V1, + }, + new TestCase() + { + Name = "cgroupv1 with suffix", + Line = "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", + ExpectedContainerId = "ac679f8a8319c8cf7d38e1adf263bc08d23", + CgroupVersion = DockerResourceDetector.ParseMode.V1, + }, + new TestCase() + { + Name = "cgroupv1 with prefix and suffix", + Line = "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", + ExpectedContainerId = "dc679f8a8319c8cf7d38e1adf263bc08d23", + CgroupVersion = DockerResourceDetector.ParseMode.V1, + }, + new TestCase() + { + Name = "cgroupv1 with container Id", + Line = "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + ExpectedContainerId = "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + CgroupVersion = DockerResourceDetector.ParseMode.V1, + }, + }; + + private readonly List testValidCasesV2 = new() + { + new TestCase() + { + Name = "cgroupv2 with container Id", + Line = "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356/hostname", + ExpectedContainerId = "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + new TestCase() + { + Name = "cgroupv2 with full line", + Line = "473 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", + ExpectedContainerId = "dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + new TestCase() + { + Name = "cgroupv2 with minikube containerd mountinfo", + Line = "1537 1517 8:1 /var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", + ExpectedContainerId = "fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + new TestCase() + { + Name = "cgroupv2 with minikube docker mountinfo", + Line = "2327 2307 8:1 /var/lib/docker/containers/a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", + ExpectedContainerId = "a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + new TestCase() + { + Name = "cgroupv2 with minikube docker mountinfo2", + Line = "929 920 254:1 /docker/volumes/minikube/_data/lib/docker/containers/0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", + ExpectedContainerId = "0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + new TestCase() + { + Name = "cgroupv2 with podman mountinfo", + Line = "1096 1088 0:104 /containers/overlay-containers/1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=813800k,nr_inodes=203450,mode=700,uid=1000,gid=1000", + ExpectedContainerId = "1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + }; + + private readonly List testInvalidCases = new() + { + new TestCase() + { + Name = "Invalid cgroupv1 line", + Line = "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", + CgroupVersion = DockerResourceDetector.ParseMode.V1, + }, + new TestCase() + { + Name = "Invalid hex cgroupv2 line (contains a z)", + Line = "13:name=systemd:/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3fz9320f4402ae6/hostname", + CgroupVersion = DockerResourceDetector.ParseMode.V2, + }, + }; [Fact] public void TestValidContainer() { var dockerResourceDetector = new DockerResourceDetector(); + var allValidTestCases = this.testValidCasesV1.Concat(this.testValidCasesV2); - using (TempFile tempFile = new TempFile()) + foreach (var testCase in allValidTestCases) { - tempFile.Write(CGROUPLINEWITHPREFIX); - Assert.Equal(CONTAINERIDWITHPREFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + using TempFile tempFile = new TempFile(); + tempFile.Write(testCase.Line); + Assert.Equal( + testCase.ExpectedContainerId, + this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion))); } + } - using (TempFile tempFile = new TempFile()) - { - tempFile.Write(CGROUPLINEWITHSUFFIX); - Assert.Equal(CONTAINERIDWITHSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); - } + [Fact] + public void TestInvalidContainer() + { + var dockerResourceDetector = new DockerResourceDetector(); - using (TempFile tempFile = new TempFile()) + // Valid in cgroupv1 is not valid in cgroupv2 + foreach (var testCase in this.testValidCasesV1) { - tempFile.Write(CGROUPLINEWITHPREFIXandSUFFIX); - Assert.Equal(CONTAINERIDWITHPREFIXANDSUFFIXREMOVED, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + using TempFile tempFile = new TempFile(); + tempFile.Write(testCase.Line); + Assert.Equal( + dockerResourceDetector.BuildResource(tempFile.FilePath, DockerResourceDetector.ParseMode.V2), + Resource.Empty); } - using (TempFile tempFile = new TempFile()) + // Valid in cgroupv1 is not valid in cgroupv1 + foreach (var testCase in this.testValidCasesV2) { - tempFile.Write(CGROUPLINE); - Assert.Equal(CONTAINERID, this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath))); + using TempFile tempFile = new TempFile(); + tempFile.Write(testCase.Line); + Assert.Equal( + dockerResourceDetector.BuildResource(tempFile.FilePath, DockerResourceDetector.ParseMode.V1), + Resource.Empty); } - } - [Fact] - public void TestInvalidContainer() - { - var dockerResourceDetector = new DockerResourceDetector(); - - // test invalid containerId (non-hex) - using (TempFile tempFile = new TempFile()) + // test invalid cases + foreach (var testCase in this.testInvalidCases) { - tempFile.Write(INVALIDCGROUPLINE); - Assert.Equal(dockerResourceDetector.BuildResource(tempFile.FilePath), Resource.Empty); + using TempFile tempFile = new TempFile(); + tempFile.Write(testCase.Line); + Assert.Equal(dockerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion), Resource.Empty); } // test invalid file - Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath()), Resource.Empty); + Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath(), DockerResourceDetector.ParseMode.V1), Resource.Empty); + Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath(), DockerResourceDetector.ParseMode.V2), Resource.Empty); } private string GetContainerId(Resource resource) @@ -108,4 +178,15 @@ private string GetContainerId(Resource resource) var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); return resourceAttributes[DockerSemanticConventions.AttributeContainerID]?.ToString(); } + + private class TestCase + { + public string Name { get; set; } + + public string Line { get; set; } + + public string ExpectedContainerId { get; set; } + + public DockerResourceDetector.ParseMode CgroupVersion { get; set; } + } } From 936a8d09c397d94769b75ad60088f07290fea45d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 9 Jan 2023 17:11:29 -0800 Subject: [PATCH 0487/1499] [Exporter.Geneva] Update CHANGELOG (#877) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index bd66234461..c0365318b6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -27,6 +27,11 @@ Released 2022-Dec-09 ([#805](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/805)) * Fix EventSource logging. ([#813](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/813)) +* Update `MessagePackSerializer` to use + [BinaryPrimitives](https://learn.microsoft.com/dotnet/api/system.buffers.binary.binaryprimitives) + to serialize scalar types more efficiently by avoiding repeated bound checks. + Add support for serializing `ISpanFormattable` types. + ([#803](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/803)) ## 1.4.0-beta.5 From cea38d31cf7cc9d152d5037e53994f4735385a90 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 10 Jan 2023 16:26:57 -0800 Subject: [PATCH 0488/1499] [Exporter.Geneva] Add TLDTraceExporter (#662) --- .editorconfig | 1 + .../External/TraceLoggingDynamic.cs | 2623 +++++++++++++++++ .../GenevaTraceExporter.cs | 55 +- .../Internal/ConnectionStringBuilder.cs | 13 + .../TLDExporter/JsonSerializer.cs | 469 +++ .../TLDExporter/TldExporter.cs | 153 + .../TLDExporter/TldTraceExporter.cs | 350 +++ .../TLDExporter/UncheckedASCIIEncoding.cs | 194 ++ .../Exporter/SerializationBenchmarks.cs | 124 + .../Exporter/TLDTraceExporterBenchmarks.cs | 160 + .../GenevaTraceExporterTests.cs | 37 +- .../JsonSerializerTests.cs | 104 + 12 files changed, 4278 insertions(+), 5 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs diff --git a/.editorconfig b/.editorconfig index ed2db8319f..1d890883f0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -144,6 +144,7 @@ dotnet_diagnostic.IDE0005.severity = warning csharp_style_namespace_declarations = file_scoped:warning [obj/**.cs] +[**/External/**.cs] generated_code = true [*.csproj] diff --git a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs new file mode 100644 index 0000000000..0f7654ee8d --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs @@ -0,0 +1,2623 @@ +/* +Dynamic ETW TraceLogging Provider API for .NET. + +GENERAL: + +This implementation of manifest-free ETW supports +more functionality than the implementation in +System.Diagnostics.Tracing.EventSource, +but it also has higher runtime costs. This implementation is intended for use only when +the set of events is not known at compile-time. For example, +TraceLoggingDynamic.cs might be used to implement a library providing +manifest-free ETW to a higher-level API that does not enforce compile-time +event layout. + +USAGE: + + // At start of program: + static readonly EventProvider p = new EventProvider("MyProviderName"); + + // When you want to write an event: + if (p.IsEnabled(EventLevel.Verbose, 0x1234)) // Anybody listening? + { + var eb = new EventBuilder(); // Or reuse an existing EventBuilder + eb.Reset("MyEventName", EventLevel.Verbose, 0x1234); + eb.AddInt32("MyInt32FieldName", intValue); + eb.AddUnicodeString("MyStringFieldName", stringValue); + p.Write(eb); + } + +The EventProvider class encapsulates an ETW REGHANDLE, which is a handle +through which events for a particular provider can be written. The +EventProvider instance should generally be created at component +initialization and one instance should be shared by all code within the +component that needs to write events for the provider. In some cases, it +might be used in a smaller scope, in which case it should be closed via +Dispose(). + +The EventBuilder class is used to build an event. It stores the event name, +field names, field types, and field values. When all of the fields have +been added to the builder, call eventProvider.Write(eventBuilder, ...) to +send the eventBuilder's event to ETW. + +To reduce performance impact, you might want to skip building the event if +there are no ETW listeners. To do this, use eventProvider.IsEnabled(...). +It returns true if there are one or more ETW listeners that would be +interested in an event with the specified level and keyword. You only +need to build and write the event if IsEnabled returned true for the level +and keyword that you will use in the event. + +The EventBuilder object is a class, and it stores two byte[] buffers. +This means each new EventBuilder object generates garbage. You can +minimize garbage by reusing the same EventBuilder object for multiple +events instead of creating a new EventBuilder for each event. + +NOTES: + +Collect the events using Windows SDK tools like traceview or tracelog. +Decode the events using Windows SDK tools like traceview or tracefmt. +For example, for `EventProvider("MyCompany.MyComponent")`: + + tracelog -start MyTrace -f MyTraceFile.etl -guid *MyCompany.MyComponent -level 5 -matchanykw 0xf + + tracelog -stop MyTrace + tracefmt -o MyTraceData.txt MyTraceFile.etl + +ETW events are limited in size (event size = headers + metadata + data). +Windows will drop any event that is larger than 64KB and will drop any event +that is larger than the buffer size of the recording session. + +Most ETW decoding tools are unable to decode an event with more than 128 +fields. +*/ +namespace OpenTelemetry.Exporter.Geneva.External; + +using System; +using System.Globalization; +using System.Runtime.ConstrainedExecution; +using System.Runtime.InteropServices; +using Debug = System.Diagnostics.Debug; +using Encoding = System.Text.Encoding; +using Interlocked = System.Threading.Interlocked; +using SHA1 = System.Security.Cryptography.SHA1; +using Win32Exception = System.ComponentModel.Win32Exception; + +/// +/// The EventProvider class encapsulates an ETW REGHANDLE, which is a handle +/// through which events for a particular provider can be written. The +/// EventProvider instance should generally be created at component +/// initialization and one instance should be shared by all code within the +/// component that needs to write events for the provider. In some cases, it +/// might be used in a smaller scope, in which case it should be closed via +/// Dispose(). +/// + +#pragma warning disable CA5350 +#pragma warning disable CA5392 + +internal sealed class EventProvider + : CriticalFinalizerObject + , IDisposable +{ + private static readonly byte[] namespaceBytes = new byte[] { + 0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8, + 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB, + }; + + private int level = -1; + private readonly int eventRegisterResult; + private long keywordAny = 0; + private long keywordAll = 0; + private long regHandle = 0; + private readonly byte[] providerMeta; + private readonly NativeMethods.EnableCallback enableCallback; // KeepAlive + private readonly string name; + private readonly Guid guid; + + /// + /// Finalizes EventProvider. + /// + ~EventProvider() + { + this.DisposeImpl(); + } + + /// + /// Initializes and registers an ETW provider with the given provider name, + /// using GetGuidForName(name) as the provider GUID. + /// + public EventProvider(string name, EventProviderOptions options = default) + : this(name, GetGuidForName(name), options) + { + return; + } + + /// + /// + /// Initializes and registers an ETW provider with the given provider name + /// and GUID. Note that most providers should use a GUID generated by + /// hashing the provider name (as done by GetGuidForName) rather than using + /// a randomly-generated GUID. Note that provider name and GUID should be a + /// strong and persistent pair, i.e. a name should uniquely identify the + /// GUID, and the GUID should uniquely identify the name. Once a name-GUID + /// pair has been established, do not change the name without also changing + /// the GUID, and do not change the GUID without also changing the name. + /// + /// Note: The status code returned by EventRegister will be recorded in the + /// EventRegisterResult property. It may be appropriate to check the value of + /// this property during development or for diagnostic purposes, e.g. via + /// Debug.Assert(p.EventRegisterResult == 0). The value will not normally be + /// used in release builds because it is usually not necessary to change + /// application behavior simply because ETW failed to initialize. + /// + /// + public EventProvider(string name, Guid guid, EventProviderOptions options = default) + { + // UINT16 size + UINT8 type + GUID. + const byte GroupTraitByteCount = 2 + 1 + 16; + + var encodingUtf8 = Encoding.UTF8; + int nameByteCount = encodingUtf8.GetByteCount(name); + int traitsByteCount = options.GroupGuid.HasValue + ? GroupTraitByteCount + : 0; + + // UINT16 size + UTF8 name + NUL termination for name + traits. + int totalByteCount = 2 + nameByteCount + 1 + traitsByteCount; + + this.providerMeta = new byte[totalByteCount]; + this.enableCallback = this.EnableCallback; + this.name = name; + this.guid = guid; + + int pos = 0; + + // UINT16 size + UTF8 name + NUL termination for name + this.providerMeta[pos++] = (byte)(totalByteCount & 0xff); + this.providerMeta[pos++] = (byte)(totalByteCount >> 8); + pos += encodingUtf8.GetBytes(name, 0, name.Length, this.providerMeta, pos); + this.providerMeta[pos++] = 0; + + if (options.GroupGuid.HasValue) + { + // UINT16 size + UINT8 type + GUID. + this.providerMeta[pos++] = GroupTraitByteCount & 0xff; + this.providerMeta[pos++] = GroupTraitByteCount >> 8; + this.providerMeta[pos++] = 1; // EtwProviderTraitTypeGroup + options.GroupGuid.Value.ToByteArray().CopyTo(this.providerMeta, pos); + pos += 16; + } + + Debug.Assert(totalByteCount == pos, "Provider traits size out-of-sync."); + + this.eventRegisterResult = NativeMethods.EventRegister( + guid, + this.enableCallback, + IntPtr.Zero, + out this.regHandle); + if (this.regHandle == 0) + { + GC.SuppressFinalize(this); + } + else + { + NativeMethods.EventSetInformation( + this.regHandle, + 2, // EventProviderSetTraits + this.providerMeta, + this.providerMeta.Length); + } + } + + /// + /// For debugging/diagnostics only. + /// Gets the Win32 status code that was returned by EventRegister during + /// construction. This might be checked via Debug.Assert to identify issues + /// during development or debugging, but it is not normally used in release + /// builds because most programs should not change behavior just because ETW + /// logging failed to initialize. + /// + public int EventRegisterResult + { + get + { + return this.eventRegisterResult; + } + } + + /// + /// Gets this provider's name. + /// + public string Name + { + get + { + return this.name; + } + } + + /// + /// Gets this provider's GUID (also known as the provider ID or the ETW + /// control GUID). + /// + public Guid Guid + { + get + { + return this.guid; + } + } + + /// + /// Gets the current thread's ETW activity ID. + /// + /// + /// Throws Win32Exception if EventActivityIdControl returns an error. + /// + public static Guid CurrentThreadActivityId + { + get + { + var value = new Guid(); + CheckWin32( + "EventActivityIdControl", + NativeMethods.EventActivityIdControl(EventActivityCtrl.GetId, ref value)); + return value; + } + } + + /// + /// Sets the current thread's ETW activity ID. + /// + /// The previous value of the current thread's ETW activity ID. + /// + /// Throws Win32Exception if EventActivityIdControl returns an error. + /// + public static Guid SetCurrentThreadActivityId(Guid value) + { + CheckWin32( + "EventActivityIdControl", + NativeMethods.EventActivityIdControl(EventActivityCtrl.GetSetId, ref value)); + return value; + } + + /// + /// Uses EventActivityIdControl to generate a new ETW activity ID. + /// Note that an activity ID is not a true GUID because it is not globally-unique. + /// It is unique within the current boot session of Windows. + /// + /// A new ETW activity ID. + /// + /// Throws Win32Exception if EventActivityIdControl returns an error. + /// + public static Guid CreateThreadActivityId() + { + var value = new Guid(); + CheckWin32( + "EventActivityIdControl", + NativeMethods.EventActivityIdControl(EventActivityCtrl.CreateId, ref value)); + return value; + } + + /// + /// Generates a GUID by uppercasing and then hashing the given provider name. + /// This hash uses the same name-hashing algorithm as is used by EventSource, + /// LoggingChannel, WPR, tracelog, traceview, and many other ETW utilities. + /// + public static Guid GetGuidForName(string providerName) + { + using (var sha1 = SHA1.Create()) + { + // Hash = Sha1(namespace + arg.ToUpper().ToUtf16be()) + byte[] nameBytes = Encoding.BigEndianUnicode.GetBytes(providerName.ToUpperInvariant()); + sha1.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0); + sha1.TransformFinalBlock(nameBytes, 0, nameBytes.Length); + + // Guid = Hash[0..15], with Hash[7] tweaked approximately following RFC 4122 + byte[] guidBytes = new byte[16]; + Buffer.BlockCopy(sha1.Hash, 0, guidBytes, 0, 16); + guidBytes[7] = (byte)((guidBytes[7] & 0x0F) | 0x50); + return new Guid(guidBytes); + } + } + + /// + /// Gets a string with the provider name and guid. + /// + public override string ToString() + { + return String.Format(CultureInfo.InvariantCulture, "Provider \"{0}\" {{{1}}}", + this.name, + this.guid.ToString()); + } + + /// + /// Returns true if any consumer is listening for events from this provider. + /// + public bool IsEnabled() + { + return 0 <= this.level; + } + + /// + /// Returns true if any consumer is listening for events from this provider + /// at the specified verbosity, i.e. if an event with the specified level + /// would be considered as enabled. + /// + public bool IsEnabled(EventLevel level) + { + return (int)level <= this.level; + } + + /// + /// Returns true if any consumer is listening for events from this provider + /// at the specified verbosity, i.e. if an event with the specified level + /// and keyword would be considered as enabled. + /// + public bool IsEnabled(EventLevel level, long keyword) + { + return (int)level <= this.level && this.IsEnabledForKeyword(keyword); + } + + /// + /// Returns true if any consumer is listening for events from this provider + /// at the specified verbosity, i.e. if an event with the specified level + /// and keyword would be considered as enabled. + /// + public bool IsEnabled(in EventDescriptor descriptor) + { + return (int)descriptor.Level <= this.level && this.IsEnabledForKeyword(descriptor.Keyword); + } + + /// + /// Writes an event to the provider, using the current thread's ETW activity ID + /// as the activity ID for the event. + /// + /// + /// 0 (ERROR_SUCCESS) if the event is filtered-out or was successfully sent. + /// Otherwise, a Win32 error code if ETW was unable to accept the event. + /// The return code is normally ignored in release code. The return code is + /// normally used for debugging/diagnosis. + /// + public unsafe int Write(EventBuilder eventBuilder) + { + return this.WriteRaw(eventBuilder, null, null); + } + + /// + /// Writes an event to the provider, using the specified activity ID for the + /// event. + /// + /// + /// 0 (ERROR_SUCCESS) if the event is filtered-out or was successfully sent. + /// Otherwise, a Win32 error code if ETW was unable to accept the event. + /// The return code is normally ignored in release code. The return code is + /// normally used for debugging/diagnosis. + /// + public unsafe int Write(EventBuilder eventBuilder, Guid activityId) + { + return this.WriteRaw(eventBuilder, &activityId, null); + } + + /// + /// Writes an event to the provider, using the specified activity ID for the + /// event and including a related activity ID in the event. This should be used + /// only for activity-start events (events with Opcode=Start). + /// + /// + /// 0 (ERROR_SUCCESS) if the event is filtered-out or was successfully sent. + /// Otherwise, a Win32 error code if ETW was unable to accept the event. + /// The return code is normally ignored in release code. The return code is + /// normally used for debugging/diagnosis. + /// + public unsafe int Write(EventBuilder eventBuilder, Guid activityId, Guid relatedActivityId) + { + return this.WriteRaw(eventBuilder, &activityId, &relatedActivityId); + } + + private unsafe int WriteRaw( + EventBuilder eventBuilder, + Guid* activityId, + Guid* relatedActivityId) + { + EventRawInfo rawInfo = eventBuilder.GetRawData(); + + if (rawInfo.MetaSize < 2 || + rawInfo.Meta.Length < rawInfo.MetaSize) + { + throw new ArgumentOutOfRangeException(nameof(rawInfo.MetaSize)); + } + + if (rawInfo.DataSize != 0 && + rawInfo.Data.Length < rawInfo.DataSize) + { + throw new ArgumentOutOfRangeException(nameof(rawInfo.DataSize)); + } + + fixed (byte* + pProviderMeta = this.providerMeta, + pEventMeta = rawInfo.Meta, + pEventData = rawInfo.Data) + { + EventDataDescriptor3 dd3; + + dd3.ProviderMeta = unchecked((ulong)(UIntPtr)pProviderMeta); + dd3.ProviderMetaSize = this.providerMeta.Length; + dd3.ProviderMetaType = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA + + dd3.EventMeta = unchecked((ulong)(UIntPtr)pEventMeta); + dd3.EventMetaSize = rawInfo.MetaSize; + dd3.EventMetaType = 1; // EVENT_DATA_DESCRIPTOR_TYPE_EVENT_METADATA + + dd3.EventData = unchecked((ulong)(UIntPtr)pEventData); + dd3.EventDataSize = rawInfo.DataSize; + dd3.EventDataType = 0; // EVENT_DATA_DESCRIPTOR_TYPE_NONE + + pEventMeta[0] = unchecked((byte)rawInfo.MetaSize); + pEventMeta[1] = unchecked((byte)(rawInfo.MetaSize >> 8)); + + var descriptor = eventBuilder.Descriptor; + return NativeMethods.EventWriteTransfer( + this.regHandle, + &descriptor, + activityId, + relatedActivityId, + 3, + &dd3); + } + } + + /// + /// Closes this provider. + /// + //[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + public void Dispose() + { + this.DisposeImpl(); + GC.SuppressFinalize(this); + } + + //[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + private void DisposeImpl() + { + long oldRegHandle = Interlocked.Exchange(ref this.regHandle, 0); + if (oldRegHandle != 0) + { + NativeMethods.EventUnregister(oldRegHandle); + } + } + + private bool IsEnabledForKeyword(long keyword) + { + return keyword == 0 || ( + (keyword & this.keywordAny) != 0 && + (keyword & this.keywordAll) == this.keywordAll); + } + + private void EnableCallback( + in Guid sourceId, + int command, + byte enableLevel, + long matchAnyKeyword, + long matchAllKeyword, + IntPtr filterData, + IntPtr callbackContext) + { + switch (command) + { + case 0: // EVENT_CONTROL_CODE_DISABLE_PROVIDER + this.level = -1; + break; + case 1: // EVENT_CONTROL_CODE_ENABLE_PROVIDER + this.level = enableLevel; + this.keywordAny = matchAnyKeyword; + this.keywordAll = matchAllKeyword; + break; + } + } + + private static void CheckWin32(string api, int result) + { + if (result != 0) + { + throw new Win32Exception(result, api); + } + } + + internal struct EventRawInfo + { + public byte[] Meta; + public byte[] Data; + public int MetaSize; + public int DataSize; + } + + private enum EventActivityCtrl : int + { + Invalid, + GetId, + SetId, + CreateId, + GetSetId, + CreateSetId, + } + + [StructLayout(LayoutKind.Sequential)] + private struct EventDataDescriptor3 + { + public ulong ProviderMeta; + public int ProviderMetaSize; + public int ProviderMetaType; + public ulong EventMeta; + public int EventMetaSize; + public int EventMetaType; + public ulong EventData; + public int EventDataSize; + public int EventDataType; + } + + private sealed class NativeMethods + { + public delegate void EnableCallback( + in Guid sourceId, + int command, + byte level, + long matchAnyKeyword, + long matchAllKeyword, + IntPtr filterData, + IntPtr callbackContext); + + [DllImport( + "api-ms-win-eventing-provider-l1-1-0.dll", + CharSet = CharSet.Unicode, + ExactSpelling = true, + SetLastError = false)] + public static extern int EventRegister( + in Guid providerId, + EnableCallback enableCallback, + IntPtr callbackContext, + out long regHandle); + + [DllImport( + "api-ms-win-eventing-provider-l1-1-0.dll", + CharSet = CharSet.Unicode, + ExactSpelling = true, + SetLastError = false)] + public static extern int EventUnregister( + long regHandle); + + [DllImport( + "api-ms-win-eventing-provider-l1-1-0.dll", + CharSet = CharSet.Unicode, + ExactSpelling = true, + SetLastError = false)] + public static extern int EventSetInformation( + long regHandle, + int informationClass, + byte[] eventInformation, + int informationLength); + + [DllImport( + "api-ms-win-eventing-provider-l1-1-0.dll", + CharSet = CharSet.Unicode, + ExactSpelling = true, + SetLastError = false)] + public static extern unsafe int EventWriteTransfer( + long regHandle, + [In] EventDescriptor* eventDescriptor, + [In] Guid* activityId, + [In] Guid* relatedActivityId, + int userDataCount, + [In] EventDataDescriptor3* userData); + + [DllImport( + "api-ms-win-eventing-provider-l1-1-0.dll", + CharSet = CharSet.Unicode, + ExactSpelling = true, + SetLastError = false)] + public static extern int EventActivityIdControl( + EventActivityCtrl controlCode, + ref Guid activityId); + } +} + +/// +/// The EventBuilder class is used to build an event. It stores the event name, +/// field names, field types, and field values. Start an event and set the event +/// name by calling Reset. Add fields by calling one of the Add methods. +/// When all of the fields have been added to the builder, call +/// eventProvider.Write(eventBuilder, ...) to send the builder's data to ETW. +/// +/// +/// The EventBuilder methods can throw exceptions in the following conditions: +/// +/// - ArgumentException if AddStruct called with a fieldCount larger than 127. +/// - NullReferenceException if a parameter is null. +/// - InvalidOperationException if an Add method would require a buffer to grow +/// larger than 64KB. +/// - OutOfMemoryException if EventBuilder buffer growth fails. +/// +/// EventBuilder will silently allow you to build events that cannot be written +/// or decoded: +/// +/// - If more than 128 fields are used in an event (i.e. if you call more than +/// 128 Add methods), almost all event decoders will fail to decode it. +/// - If the total event is too large, ETW will reject it. The exact size limit +/// depends on ETW listener configuration, but 65536 bytes is always too big. +/// +/// If garbage needs to be minimized, you will want to reuse each EventBuilder +/// object for multiple events instead of creating a new EventBuilder object for +/// each event. Note that EventBuilder objects are not thread-safe, so you will be +/// responsible for caching objects such that only one thread uses a particular +/// instance of EventBuilder at any one time. +/// +internal class EventBuilder +{ + private enum InType : byte + { + Null, // Invalid type + UnicodeString, // nul-terminated + AnsiString, // nul-terminated + Int8, + UInt8, + Int16, + UInt16, + Int32, + UInt32, + Int64, + UInt64, + Float32, + Float64, + Bool32, + Binary, // counted, doesn't work for arrays. + Guid, // size = 16 + Pointer_NotSupported, + FileTime, // size = 8 + SystemTime, // size = 16 + Sid, // size = 8 + 4 * SubAuthorityCount + HexInt32, + HexInt64, + CountedString, // counted + CountedAnsiString, // counted + Struct, // Use OutType for field count. + CountedBinary, // counted, works for arrays, newer (not always supported) + Mask = 31, + NullArray = 64, // Invalid type + UnicodeStringArray, // nul-terminated + AnsiStringArray, // nul-terminated + Int8Array, + UInt8Array, + Int16Array, + UInt16Array, + Int32Array, + UInt32Array, + Int64Array, + UInt64Array, + Float32Array, + Float64Array, + Bool32Array, + BinaryArray_NotSupported, + GuidArray, // size = 16 + PointerArray_NotSupported, + FileTimeArray, // size = 8 + SystemTimeArray, // size = 16 + SidArray, // size = 8 + 4 * SubAuthorityCount + HexInt32Array, + HexInt64Array, + CountedStringArray, // counted + CountedAnsiStringArray, // counted + StructArray, // Use OutType for field count. + CountedBinaryArray, // counted, works for arrays, newer (not always supported) + } + + private const byte InTypeCcount = 32; + private const byte InTypeVcount = 64; + private const byte ChainBit = 128; + + private string name; + private Encoding utf8NameEncoding; + private EventDescriptor descriptor; + private int tag; + + /// + /// Initial metadata capacity must be a power of 2 in the range 4..65536. + /// + private Vector metadata; + + /// + /// Initial data capacity must be a power of 2 in the range 4..65536. + /// + private Vector data; + + /// + /// Initializes a new instance of the EventBuilder. + /// + /// + /// The initial capacity of the metadata buffer. This must be a power of 2 in the + /// range 4 through 65536. Default is 256 bytes. + /// + /// + /// The initial capacity of the data buffer. This must be a power of 2 in the + /// range 4 through 65536. Default is 256 bytes. + /// + public EventBuilder(int initialMetadataBufferSize = 256, int initialDataBufferSize = 256) + : this(Encoding.UTF8, initialMetadataBufferSize, initialDataBufferSize) + { + } + + /// + /// Advanced scenarios: Initializes a new instance of the EventBuilder class that + /// uses a customized UTF-8 encoding for event and field names. + /// + /// + /// The customized UTF-8 encoding to use for event and field names. + /// + /// + /// The initial capacity of the metadata buffer. This must be a power of 2 in the + /// range 4 through 65536. + /// + /// + /// The initial capacity of the data buffer. This must be a power of 2 in the + /// range 4 through 65536. + /// + public EventBuilder( + Encoding utf8NameEncoding, + int initialMetadataBufferSize = 256, + int initialDataBufferSize = 256) + { + if (initialMetadataBufferSize < 4 || initialMetadataBufferSize > 65536 || + (initialMetadataBufferSize & (initialMetadataBufferSize - 1)) != 0) + { + throw new ArgumentOutOfRangeException(nameof(initialMetadataBufferSize)); + } + + if (initialDataBufferSize < 4 || initialDataBufferSize > 65536 || + (initialDataBufferSize & (initialDataBufferSize - 1)) != 0) + { + throw new ArgumentOutOfRangeException(nameof(initialDataBufferSize)); + } + + this.utf8NameEncoding = utf8NameEncoding; + this.metadata = new Vector(initialMetadataBufferSize); + this.data = new Vector(initialDataBufferSize); + + // The following has the same effect as Reset(""). + this.name = ""; + this.descriptor = new EventDescriptor(EventLevel.Verbose); + this.metadata.ReserveSpaceFor(4); + } + + /// + /// Gets the name for the event. + /// + public string Name { get { return this.name; } } + + /// + /// Gets the level for the event. + /// + public EventLevel Level { get { return this.descriptor.Level; } } + + /// + /// Gets the keyword for the event. + /// + public long Keyword { get { return this.descriptor.Keyword; } } + + /// + /// Gets the descriptor for the event. + /// + public EventDescriptor Descriptor { get { return this.descriptor; } } + + /// + /// Gets the tag for the event. + /// + public int Tag { get { return this.tag; } } + + /// + /// Advanced scenarios: Gets or sets the UTF-8 encoding that will be used for + /// event and field names. + /// + public Encoding Utf8NameEncoding + { + get + { + return this.utf8NameEncoding; + } + + set + { + if (value == null) + { + throw new ArgumentNullException(nameof(Utf8NameEncoding)); + } + + this.utf8NameEncoding = value; + } + } + + /// + /// Resets this EventBuilder and begins building a new event. + /// + /// + /// Identifier (name) of the event. This must not be null or empty. + /// The name string must not include any '\0' characters. + /// Use a short but descriptive name since the name will be included in + /// each event and will be the primary identifier for the event. + /// For best event analysis, ensure that all events with a particular + /// event name have the same field names and field types. + /// + /// + /// Event severity, default is Verbose. + /// + /// + /// Event keyword, default is 0x1. All events should have a non-zero keyword. + /// + /// + /// 28-bit tag to associate with event, or 0 for none. + /// + public void Reset( + string name, + EventLevel level = EventLevel.Verbose, + long keyword = 0x1, + int eventTag = 0) + { + this.name = name; + this.descriptor = new EventDescriptor(level, keyword); + this.tag = eventTag; + this.ResetEvent(); + } + + /// + /// Resets this EventBuilder and begins building a new event. + /// + /// + /// Identifier (name) of the event. This must not be null or empty. + /// The name string must not include any '\0' characters. + /// Use a short but descriptive name since the name will be included in + /// each event and will be the primary identifier for the event. + /// For best event analysis, ensure that all events with a particular + /// event name have the same field names and field types. + /// + /// + /// Level, Keyword, Opcode, Task, Channel, Id, Version for event. + /// + /// + /// 28-bit tag to associate with event, or 0 for none. + /// + public void Reset( + string name, + EventDescriptor descriptor, + int eventTag = 0) + { + this.name = name; + this.descriptor = descriptor; + this.tag = eventTag; + this.ResetEvent(); + } + + /// + /// Adds a UnicodeString field (nul-terminated utf-16le). + /// NOTE: Prefer AddCountedString. Use AddUnicodeString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Xml, Json. + /// + public void AddUnicodeString(string name, String value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UnicodeString, outType, tag); + this.AddScalarDataNulTerminatedString(value, 0, value.Length); + } + + /// + /// Adds a UnicodeString field (nul-terminated utf-16le). + /// NOTE: Prefer AddCountedString. Use AddUnicodeString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Xml, Json. + /// + public void AddUnicodeString(string name, String value, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UnicodeString, outType, tag); + this.AddScalarDataNulTerminatedString(value, startIndex, count); + } + + /// + /// Adds a UnicodeString array field (nul-terminated utf-16le). + /// NOTE: Prefer AddCountedString. Use AddUnicodeString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Xml, Json. + /// + public void AddUnicodeStringArray(string name, String[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UnicodeStringArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (string value in values) + { + this.AddScalarDataNulTerminatedString(value, 0, value.Length); + } + } + + /// + /// Adds an AnsiString field (nul-terminated MBCS). + /// NOTE: Prefer AddCountedAnsiString. Use AddAnsiString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddAnsiString(string name, Byte[] value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.AnsiString, outType, tag); + this.AddScalarDataNulTerminatedByteString(value, 0, value.Length); + } + + /// + /// Adds an AnsiString field (nul-terminated MBCS). + /// NOTE: Prefer AddCountedAnsiString. Use AddAnsiString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddAnsiString(string name, String value, Encoding encoding, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.AnsiString, outType, tag); + this.AddScalarDataNulTerminatedAnsiString(value, encoding, 0, value.Length); + } + + /// + /// Adds an AnsiString field (nul-terminated MBCS). + /// NOTE: Prefer AddCountedAnsiString. Use AddAnsiString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddAnsiString(string name, Byte[] value, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.AnsiString, outType, tag); + this.AddScalarDataNulTerminatedByteString(value, startIndex, count); + } + + /// + /// Adds an AnsiString field (nul-terminated MBCS). + /// NOTE: Prefer AddCountedAnsiString. Use AddAnsiString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddAnsiString(string name, String value, Encoding encoding, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.AnsiString, outType, tag); + this.AddScalarDataNulTerminatedAnsiString(value, encoding, startIndex, count); + } + + /// + /// Adds an AnsiString array field (nul-terminated MBCS). + /// NOTE: Prefer AddCountedAnsiString. Use AddAnsiString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddAnsiStringArray(string name, Byte[][] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.AnsiStringArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (var value in values) + { + this.AddScalarDataNulTerminatedByteString(value, 0, value.Length); + } + } + + /// + /// Adds an AnsiString array field (nul-terminated MBCS). + /// NOTE: Prefer AddCountedAnsiString. Use AddAnsiString only if the decoder requires nul-terminated strings. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddAnsiStringArray(string name, String[] values, Encoding encoding, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.AnsiStringArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (var value in values) + { + this.AddScalarDataNulTerminatedAnsiString(value, encoding, 0, value.Length); + } + } + + /// + /// Adds an Int8 field. + /// Meaningful outTypes: Default (Signed), String (AnsiChar). + /// + public void AddInt8(string name, SByte value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int8, outType, tag); + this.AddScalarDataUInt8(unchecked((Byte)value)); + } + + /// + /// Adds an Int8 array field. + /// Meaningful outTypes: Default (Signed), String (AnsiChar). + /// + public void AddInt8Array(string name, SByte[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int8Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(SByte), 0, values.Length); + } + + /// + /// Adds a UInt8 field. + /// Meaningful outTypes: Default (Unsigned), Hex (HexInt8), String (AnsiChar), Boolean (Bool8). + /// + public void AddUInt8(string name, Byte value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt8, outType, tag); + this.AddScalarDataUInt8(value); + } + + /// + /// Adds a UInt8 array field. + /// Meaningful outTypes: Default (Unsigned), Hex (HexInt8), String (AnsiChar), Boolean (Bool8). + /// + public void AddUInt8Array(string name, Byte[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt8Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Byte), 0, values.Length); + } + + /// + /// Adds an Int16 field. + /// Meaningful outTypes: Default (Signed). + /// + public void AddInt16(string name, Int16 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int16, outType, tag); + this.AddScalarDataUInt16(unchecked((UInt16)value)); + } + + /// + /// Adds an Int16 array field. + /// Meaningful outTypes: Default (Signed). + /// + public void AddInt16Array(string name, Int16[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int16Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int16), 0, values.Length); + } + + /// + /// Adds a UInt16 field. + /// Meaningful outTypes: Default (Unsigned), Port (Big-endian UInt16), Hex (HexInt16), + /// String (Utf16Char). + /// + public void AddUInt16(string name, UInt16 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt16, outType, tag); + this.AddScalarDataUInt16(value); + } + + /// + /// Adds a UInt16 array field. + /// Meaningful outTypes: Default (Unsigned), Port (Big-endian UInt16), Hex (HexInt16), + /// String (Utf16Char). + /// + public void AddUInt16Array(string name, UInt16[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt16Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(UInt16), 0, values.Length); + } + + /// + /// Adds an Int32 field. + /// Meaningful outTypes: Default (Signed), HResult. + /// + public void AddInt32(string name, Int32 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + + /// + /// Adds an Int32 array field. + /// Meaningful outTypes: Default (Signed), HResult. + /// + public void AddInt32Array(string name, Int32[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int32Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int32), 0, values.Length); + } + + /// + /// Adds a UInt32 field. + /// Meaningful outTypes: Default (Unsigned), Pid, Tid, IPv4, Win32Error, NtStatus, Hex, CodePointer. + /// + public void AddUInt32(string name, UInt32 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt32, outType, tag); + this.AddScalarDataUInt32(value); + } + + /// + /// Adds a UInt32 array field. + /// Meaningful outTypes: Default (Unsigned), Pid, Tid, IPv4, Win32Error, NtStatus, Hex, CodePointer. + /// + public void AddUInt32Array(string name, UInt32[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt32Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(UInt32), 0, values.Length); + } + + /// + /// Adds an Int64 field. + /// Meaningful outTypes: Default (Signed). + /// + public void AddInt64(string name, Int64 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int64, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + + /// + /// Adds an Int64 array field. + /// Meaningful outTypes: Default (Signed). + /// + public void AddInt64Array(string name, Int64[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Int64Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int64), 0, values.Length); + } + + /// + /// Adds a UInt64 field. + /// Meaningful outTypes: Default (Unsigned), Hex (HexInt64), CodePointer (HexInt64). + /// + public void AddUInt64(string name, UInt64 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt64, outType, tag); + this.AddScalarDataUInt64(value); + } + + /// + /// Adds a UInt64 array field. + /// Meaningful outTypes: Default (Unsigned), Hex (HexInt64), CodePointer (HexInt64). + /// + public void AddUInt64Array(string name, UInt64[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.UInt64Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(UInt64), 0, values.Length); + } + + /// + /// Adds an IntPtr field. + /// Meaningful outTypes: Default (Signed). + /// + public void AddIntPtr(string name, IntPtr value, EventOutType outType = EventOutType.Default, int tag = 0) + { + if (IntPtr.Size == 8) + { + this.AddMetadata(name, InType.Int64, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + else + { + this.AddMetadata(name, InType.Int32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + } + + /// + /// Adds an IntPtr array field. + /// Meaningful outTypes: Default (Signed). + /// + public void AddIntPtrArray(string name, IntPtr[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, IntPtr.Size == 8 ? InType.Int64Array : InType.Int32Array, outType, tag); + this.AddArrayDataBlockCopy(values, IntPtr.Size, 0, values.Length); + } + + /// + /// Adds a UIntPtr field. + /// Meaningful outTypes: Default (Unsigned). + /// + public void AddUIntPtr(string name, UIntPtr value, EventOutType outType = EventOutType.Default, int tag = 0) + { + if (UIntPtr.Size == 8) + { + this.AddMetadata(name, InType.UInt64, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + else + { + this.AddMetadata(name, InType.UInt32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + } + + /// + /// Adds a UIntPtr array field. + /// Meaningful outTypes: Default (Unsigned). + /// + public void AddUIntPtrArray(string name, UIntPtr[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, UIntPtr.Size == 8 ? InType.UInt64Array : InType.UInt32Array, outType, tag); + this.AddArrayDataBlockCopy(values, UIntPtr.Size, 0, values.Length); + } + + /// + /// Adds a Float32 field. + /// Meaningful outTypes: Default. + /// + public void AddFloat32(string name, Single value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Float32, outType, tag); + this.AddScalarDataFloat32(value); + } + + /// + /// Adds a Float32 array field. + /// Meaningful outTypes: Default. + /// + public void AddFloat32Array(string name, Single[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Float32Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Single), 0, values.Length); + } + + /// + /// Adds a Float64 field. + /// Meaningful outTypes: Default. + /// + public void AddFloat64(string name, Double value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Float64, outType, tag); + this.AddScalarDataFloat64(value); + } + + /// + /// Adds a Float64 array field. + /// Meaningful outTypes: Default. + /// + public void AddFloat64Array(string name, Double[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Float64Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Double), 0, values.Length); + } + + /// + /// Adds a Bool32 field. + /// Meaningful outTypes: Default (Boolean). + /// + public void AddBool32(string name, Int32 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Bool32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + + /// + /// Adds a Bool32 array field. + /// Meaningful outTypes: Default (Boolean). + /// + public void AddBool32Array(string name, Int32[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Bool32Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int32), 0, values.Length); + } + + /// + /// Adds a Binary field. + /// Meaningful outTypes: Default (Hex), IPv6, SocketAddress, Pkcs7WithTypeInfo. + /// + public void AddBinary(string name, Byte[] value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Binary, outType, tag); + this.AddArrayDataBlockCopy(value, sizeof(Byte), 0, value.Length); + } + + /// + /// Adds a Binary field. + /// Meaningful outTypes: Default (Hex), IPv6, SocketAddress, Pkcs7WithTypeInfo. + /// + public void AddBinary(string name, Byte[] value, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Binary, outType, tag); + this.AddArrayDataBlockCopy(value, sizeof(Byte), startIndex, count); + } + + /// + /// Adds a Guid field. + /// Meaningful outTypes: Default. + /// + public unsafe void AddGuid(string name, Guid value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Guid, outType, tag); + int pos = this.data.ReserveSpaceFor(16); + Marshal.Copy((IntPtr)(&value), this.data.data, pos, 16); + + } + + /// + /// Adds a Guid array field. + /// Meaningful outTypes: Default. + /// + public unsafe void AddGuidArray(string name, Guid[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.GuidArray, outType, tag); + fixed (Guid* valuesPtr = values) + { + var valuesLength = values.Length; + var valuesSize = valuesLength * 16; + int pos = this.AddArrayBegin(valuesLength, valuesSize); + if (valuesPtr != null) + { + Marshal.Copy((IntPtr)valuesPtr, this.data.data, pos, valuesSize); + } + } + } + + /// + /// Adds a FileTime field. + /// Meaningful outTypes: Default (FileTime), DateTimeUtc (explicit-UTC FileTime). + /// + public void AddFileTime(string name, Int64 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.FileTime, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + + /// + /// Adds a FileTime array field. + /// Meaningful outTypes: Default (FileTime), DateTimeUtc (explicit-UTC FileTime). + /// + public void AddFileTimeArray(string name, Int64[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.FileTimeArray, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int64), 0, values.Length); + } + + /// + /// Adds a FileTime field. + /// Meaningful outTypes: Default (FileTime), DateTimeUtc (explicit-UTC FileTime). + /// Note: This will record the DateTime's raw time (local or UTC). It is recommended + /// that you use AddField(dateTimeValue.ToUniversalTime()) to ensure that a UTC time + /// is recorded in the ETW event. + /// + public void AddFileTime(string name, DateTime value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.FileTime, outType, tag); + this.AddScalarDataUInt64(DateTimeToFileTime(value)); + } + + /// + /// Adds a FileTime array field. + /// Meaningful outTypes: Default (FileTime), DateTimeUtc (explicit-UTC FileTime). + /// Note: This will record the DateTime's raw time (local or UTC). It is recommended + /// that you use AddField(dateTimeValue.ToUniversalTime()) to ensure that a UTC time + /// is recorded in the ETW event. + /// + public void AddFileTimeArray(string name, DateTime[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.FileTimeArray, outType, tag); + + int pos = this.AddArrayBegin(values.Length, values.Length * sizeof(UInt64)); + foreach (DateTime value in values) + { + pos += this.data.SetUInt64(pos, DateTimeToFileTime(value)); + } + } + + /// + /// Adds a SystemTime field. + /// The input value must be Int16[8] or longer (extra will be ignored). + /// + public void AddSystemTime(string name, Int16[] value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.SystemTime, outType, tag); + int pos = this.data.ReserveSpaceFor(16); + Buffer.BlockCopy(value, 0, this.data.data, pos, 16); + } + + /// + /// Adds a SystemTime array field. + /// The input value must be Int16[8] or longer (extra will be ignored). + /// (extra words will be ignored). + /// + public void AddSystemTimeArray(string name, Int16[][] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.SystemTimeArray, outType, tag); + + var valuesLength = values.Length; + int pos = this.AddArrayBegin(valuesLength, valuesLength * 16); + foreach (var value in values) + { + Buffer.BlockCopy(value, 0, this.data.data, pos, 16); + pos += 16; + } + } + + /// + /// Adds a Sid field. + /// The input value must be byte[8 + 4 * SubAuthorityCount] or longer (extra bytes will be ignored). + /// + public void AddSid(string name, Byte[] value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.Sid, outType, tag); + this.AddDataBytes(value, 8 + 4 * value[1]); + } + + /// + /// Adds a Sid array field. + /// The input value must be byte[8 + 4 * SubAuthorityCount] or longer (extra bytes will be ignored). + /// + public void AddSidArray(string name, Byte[][] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.SidArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (var value in values) + { + this.AddDataBytes(value, 8 + 4 * value[1]); + } + } + + /// + /// Adds a HexInt32 field. + /// Meaningful outTypes: Default (Hex), Win32Error, NtStatus, CodePointer. + /// + public void AddHexInt32(string name, Int32 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + + /// + /// Adds a HexInt32 array field. + /// Meaningful outTypes: Default (Hex), Win32Error, NtStatus, CodePointer. + /// + public void AddHexInt32Array(string name, Int32[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt32Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int32), 0, values.Length); + } + + /// + /// Adds a HexInt32 field. + /// Meaningful outTypes: Default (Hex), Win32Error, NtStatus, CodePointer. + /// + public void AddHexInt32(string name, UInt32 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt32, outType, tag); + this.AddScalarDataUInt32(value); + } + + /// + /// Adds a HexInt32 array field. + /// Meaningful outTypes: Default (Hex), Win32Error, NtStatus, CodePointer. + /// + public void AddHexInt32Array(string name, UInt32[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt32Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(UInt32), 0, values.Length); + } + + /// + /// Adds a HexInt64 field. + /// Meaningful outTypes: Default (Hex), CodePointer. + /// + public void AddHexInt64(string name, Int64 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt64, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + + /// + /// Adds a HexInt64 array field. + /// Meaningful outTypes: Default (Hex), CodePointer. + /// + public void AddHexInt64Array(string name, Int64[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt64Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(Int64), 0, values.Length); + } + + /// + /// Adds a HexInt64 field. + /// Meaningful outTypes: Default (Hex), CodePointer. + /// + public void AddHexInt64(string name, UInt64 value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt64, outType, tag); + this.AddScalarDataUInt64(value); + } + + /// + /// Adds a HexInt64 array field. + /// Meaningful outTypes: Default (Hex), CodePointer. + /// + public void AddHexInt64Array(string name, UInt64[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.HexInt64Array, outType, tag); + this.AddArrayDataBlockCopy(values, sizeof(UInt64), 0, values.Length); + } + + /// + /// Adds a HexIntPtr field. + /// Meaningful outTypes: Default (Hex). + /// + public void AddHexIntPtr(string name, IntPtr value, EventOutType outType = EventOutType.Default, int tag = 0) + { + if (IntPtr.Size == 8) + { + this.AddMetadata(name, InType.HexInt64, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + else + { + this.AddMetadata(name, InType.HexInt32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + } + + /// + /// Adds a HexIntPtr array field. + /// Meaningful outTypes: Default (Hex). + /// + public void AddHexIntPtrArray(string name, IntPtr[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, IntPtr.Size == 8 ? InType.HexInt64Array : InType.HexInt32Array, outType, tag); + this.AddArrayDataBlockCopy(values, IntPtr.Size, 0, values.Length); + } + + /// + /// Adds a HexIntPtr field. + /// Meaningful outTypes: Default (Hex). + /// + public void AddHexIntPtr(string name, UIntPtr value, EventOutType outType = EventOutType.Default, int tag = 0) + { + if (UIntPtr.Size == 8) + { + this.AddMetadata(name, InType.HexInt64, outType, tag); + this.AddScalarDataUInt64(unchecked((UInt64)value)); + } + else + { + this.AddMetadata(name, InType.HexInt32, outType, tag); + this.AddScalarDataUInt32(unchecked((UInt32)value)); + } + } + + /// + /// Adds a HexIntPtr array field. + /// Meaningful outTypes: Default (Hex). + /// + public void AddHexIntPtrArray(string name, UIntPtr[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, UIntPtr.Size == 8 ? InType.HexInt64Array : InType.HexInt32Array, outType, tag); + this.AddArrayDataBlockCopy(values, UIntPtr.Size, 0, values.Length); + } + + /// + /// Adds a CountedString field (utf-16le). + /// Meaningful outTypes: Default (String), Xml, Json. + /// + public void AddCountedString(string name, String value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedString, outType, tag); + this.AddScalarDataCountedString(value, 0, value.Length); + } + + /// + /// Adds a CountedString field (utf-16le). + /// Meaningful outTypes: Default (String), Xml, Json. + /// + public void AddCountedString(string name, String value, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedString, outType, tag); + this.AddScalarDataCountedString(value, startIndex, count); + } + + /// + /// Adds a CountedString array field (utf-16le). + /// Meaningful outTypes: Default (String), Xml, Json. + /// + public void AddCountedStringArray(string name, String[] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedStringArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (string value in values) + { + this.AddScalarDataCountedString(value, 0, value.Length); + } + } + + /// + /// Adds a CountedAnsiString field. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddCountedAnsiString(string name, Byte[] value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedAnsiString, outType, tag); + this.AddArrayDataBlockCopy(value, sizeof(byte), 0, value.Length); + } + + /// + /// Adds a CountedAnsiString field. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddCountedAnsiString(string name, String value, Encoding encoding, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedAnsiString, outType, tag); + this.AddScalarDataCountedAnsiString(value, encoding, 0, value.Length); + } + + /// + /// Adds a CountedAnsiString field. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddCountedAnsiString(string name, Byte[] value, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedAnsiString, outType, tag); + this.AddArrayDataBlockCopy(value, sizeof(byte), startIndex, count); + } + + /// + /// Adds a CountedAnsiString field. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddCountedAnsiString(string name, String value, Encoding encoding, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedAnsiString, outType, tag); + this.AddScalarDataCountedAnsiString(value, encoding, startIndex, count); + } + + /// + /// Adds a CountedAnsiString array field. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddCountedAnsiStringArray(string name, Byte[][] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedAnsiStringArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (var value in values) + { + this.AddArrayDataBlockCopy(value, sizeof(byte), 0, value.Length); + } + } + + /// + /// Adds a CountedAnsiString array field. + /// Meaningful outTypes: Default (String), Utf8, Xml, Json. + /// + public void AddCountedAnsiStringArray(string name, String[] values, Encoding encoding, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedAnsiStringArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (var value in values) + { + this.AddScalarDataCountedAnsiString(value, encoding, 0, value.Length); + } + } + + /// + /// Adds a CountedBinary field. (Decoding requires Windows 2018 Fall Update or later.) + /// Meaningful outTypes: Default (Hex), IPv6, SocketAddress, Pkcs7WithTypeInfo. + /// + public void AddCountedBinary(string name, Byte[] value, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedBinary, outType, tag); + this.AddArrayDataBlockCopy(value, sizeof(Byte), 0, value.Length); + } + + /// + /// Adds a CountedBinary field. (Decoding requires Windows 2018 Fall Update or later.) + /// Meaningful outTypes: Default (Hex), IPv6, SocketAddress, Pkcs7WithTypeInfo. + /// + public void AddCountedBinary(string name, Byte[] value, int startIndex, int count, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedBinary, outType, tag); + this.AddArrayDataBlockCopy(value, sizeof(Byte), startIndex, count); + } + + /// + /// Adds a CountedBinary array field. (Decoding requires Windows 2018 Fall Update or later.) + /// Meaningful outTypes: Default (Hex), IPv6, SocketAddress, Pkcs7WithTypeInfo. + /// + public void AddCountedBinaryArray(string name, Byte[][] values, EventOutType outType = EventOutType.Default, int tag = 0) + { + this.AddMetadata(name, InType.CountedBinaryArray, outType, tag); + this.AddArrayBegin(values.Length, 0); + foreach (var value in values) + { + this.AddArrayDataBlockCopy(value, sizeof(Byte), 0, value.Length); + } + } + + /// + /// Adds a new logical field with the specified name and indicates that the next + /// fieldCount logical fields should be considered as members of this field. + /// Note that fieldCount must be in the range 1 to 127. + /// + /// + /// The offset of the struct size within the metadata. This value is normally + /// ignored. However, if you do not know the number of fields in a structure + /// ahead of time, you can use this value with SetStructFieldCount. + /// + public int AddStruct(string name, byte fieldCount, int tag = 0) + { + if (fieldCount < 1 || fieldCount > 127) + { + throw new ArgumentOutOfRangeException(nameof(fieldCount)); + } + + return this.AddMetadata(name, InType.Struct, (EventOutType)fieldCount, tag); + } + + /// + /// Advanced: Resets the number of logical fields in the specified structure. + /// + /// + /// The position of the metadata field within the structure. This value is + /// returned by the AddStruct method. + /// + /// + /// The actual number of fields in the structure. This value must be in the range + /// 1 to 127. + /// + public void SetStructFieldCount(int metadataPosition, byte fieldCount) + { + if (fieldCount < 1 || fieldCount > 127) + { + throw new ArgumentOutOfRangeException(nameof(fieldCount)); + } + + var meta = this.metadata.data; + meta[metadataPosition] = (byte)((meta[metadataPosition] & 0x80) | (fieldCount & 0x7F)); + } + + /// + /// Advanced: Extracts the raw data for the fields currently in the builder. + /// This can be used to add a group of fields to a builder with AppendRawFields. + /// + /// Raw data that can be used with AppendRawFields + public Tuple GetRawFields() + { + // Find start of first field. + int metaPos = 2; // Skip space reserved for metadata size. + + // Skip past tags. + for (; ; metaPos += 1) + { + Debug.Assert(metaPos < this.metadata.Size); + if ((this.metadata.data[metaPos] & 0x80) == 0) + { + metaPos += 1; + break; + } + } + + // Skip past event name. + int fieldStart = 1 + Array.IndexOf(this.metadata.data, 0, metaPos, this.metadata.Size - metaPos); + Debug.Assert(fieldStart > 0); + + var dataSize = this.data.Size; + var dataCopy = new byte[dataSize]; + Array.Copy(this.data.data, 0, dataCopy, 0, dataSize); + + var metaSize = this.metadata.Size - fieldStart; + var metaCopy = new byte[metaSize]; + Array.Copy(this.metadata.data, fieldStart, metaCopy, 0, metaSize); + + return new Tuple(dataCopy, metaCopy); + } + + /// + /// Advanced: Appends raw data and metadata to the builder. This can be used with + /// the data from GetRawFields. + /// + /// Data from GetRawFields + public void AppendRawFields(Tuple rawFields) + { + var rawData = rawFields.Item1; + int dataPos = this.data.ReserveSpaceFor(rawData.Length); + Buffer.BlockCopy(rawData, 0, this.data.data, dataPos, rawData.Length); + + var rawMeta = rawFields.Item2; + int metaPos = this.metadata.ReserveSpaceFor(rawMeta.Length); + Buffer.BlockCopy(rawMeta, 0, this.metadata.data, metaPos, rawMeta.Length); + } + + /// + /// Internal - for use by EventProvider.Write. + /// Use EventProvider.Write to write events. + /// + internal EventProvider.EventRawInfo GetRawData() + { + return new EventProvider.EventRawInfo + { + Meta = this.metadata.data, + Data = this.data.data, + MetaSize = this.metadata.Size, + DataSize = this.data.Size + }; + } + + /// The position of the outType byte within the metadata array. + private unsafe int AddMetadata(string name, InType inType, EventOutType outType, int tag) + { + int metadataPos; + Debug.Assert(name.IndexOf('\0') < 0, "Field name must not have embedded NUL characters."); + Debug.Assert(((int)outType & 127) == (int)outType, "Invalid outType."); + Debug.Assert((tag & 0xfffffff) == tag, "Tag must be 28-bit value."); + + int pos; + + var nameLength = name.Length; + var nameMaxByteCount = this.utf8NameEncoding.GetMaxByteCount(nameLength); + if (tag != 0) + { + pos = this.metadata.ReserveSpaceFor(nameMaxByteCount + 7); + fixed (char* pName = name) + { + fixed (byte* pMeta = this.metadata.data) + { + pos += this.utf8NameEncoding.GetBytes(pName, nameLength, pMeta + pos, nameMaxByteCount); + pMeta[pos + 0] = 0; // nul + pMeta[pos + 1] = (byte)((byte)inType | ChainBit); + pMeta[pos + 2] = (byte)((byte)outType | ChainBit); + pMeta[pos + 3] = unchecked((byte)(0x80 | tag >> 21)); + pMeta[pos + 4] = unchecked((byte)(0x80 | tag >> 14)); + pMeta[pos + 5] = unchecked((byte)(0x80 | tag >> 7)); + pMeta[pos + 6] = unchecked((byte)(0x7F & tag)); + } + } + this.metadata.SetSize(pos + 7); + metadataPos = pos + 2; + } + else if (outType != EventOutType.Default) + { + pos = this.metadata.ReserveSpaceFor(nameMaxByteCount + 3); + fixed (char* pName = name) + { + fixed (byte* pMeta = this.metadata.data) + { + pos += this.utf8NameEncoding.GetBytes(pName, nameLength, pMeta + pos, nameMaxByteCount); + pMeta[pos + 0] = 0; // nul + pMeta[pos + 1] = (byte)((byte)inType | ChainBit); + pMeta[pos + 2] = (byte)outType; + } + } + this.metadata.SetSize(pos + 3); + metadataPos = pos + 2; + } + else + { + pos = this.metadata.ReserveSpaceFor(nameMaxByteCount + 2); + fixed (char* pName = name) + { + fixed (byte* pMeta = this.metadata.data) + { + pos += this.utf8NameEncoding.GetBytes(pName, nameLength, pMeta + pos, nameMaxByteCount); + pMeta[pos + 0] = 0; // nul + pMeta[pos + 1] = (byte)inType; + } + } + this.metadata.SetSize(pos + 2); + metadataPos = -1; + } + + return metadataPos; + } + + private unsafe int AddMetadataName(string name, int nulInOutTagSize) + { + int nameLength = name.Length; + int byteMax = this.utf8NameEncoding.GetMaxByteCount(nameLength) + nulInOutTagSize; // nul + intype + outtype + tag + + int pos = this.metadata.ReserveSpaceFor(byteMax); + fixed (char* pName = name) + { + fixed (byte* pMeta = this.metadata.data) + { + pos += this.utf8NameEncoding.GetBytes(pName, nameLength, pMeta + pos, byteMax); + } + } + + return pos; + } + + private void AddDataBytes(byte[] value, int length) + { + int pos = this.data.ReserveSpaceFor(length); + Buffer.BlockCopy(value, 0, this.data.data, pos, length); + } + + private void AddScalarDataUInt8(Byte value) + { + int pos = this.data.ReserveSpaceFor(1); + this.data.SetUInt8(pos, value); + } + + private void AddScalarDataUInt16(UInt16 value) + { + int pos = this.data.ReserveSpaceFor(2); + this.data.SetUInt16(pos, value); + } + + private void AddScalarDataUInt32(UInt32 value) + { + int pos = this.data.ReserveSpaceFor(4); + this.data.SetUInt32(pos, value); + } + + private void AddScalarDataUInt64(UInt64 value) + { + int pos = this.data.ReserveSpaceFor(8); + this.data.SetUInt64(pos, value); + } + + private unsafe void AddScalarDataFloat32(Single value) + { + int pos = this.data.ReserveSpaceFor(4); + this.data.SetUInt32(pos, *(UInt32*)&value); + } + + private unsafe void AddScalarDataFloat64(Double value) + { + int pos = this.data.ReserveSpaceFor(8); + this.data.SetUInt64(pos, *(UInt64*)&value); + } + + private void AddScalarDataNulTerminatedByteString(byte[] value, int startIndex, int count) + { + int endIndex = Array.IndexOf(value, (byte)0, startIndex, count); + int copyLength = endIndex < 0 + ? count + : endIndex - startIndex; + int pos = this.data.ReserveSpaceFor(copyLength + sizeof(byte)); + Buffer.BlockCopy(value, startIndex, this.data.data, pos, copyLength); + this.data.SetUInt8(pos + copyLength, 0); + } + + private unsafe void AddScalarDataNulTerminatedString(String value, int startIndex, int count) + { + int endIndex = value.IndexOf('\0', startIndex, count); + int copyLength = endIndex < 0 + ? count + : endIndex - startIndex; + + int valueSize = copyLength * sizeof(UInt16); + int pos = this.data.ReserveSpaceFor(valueSize + sizeof(UInt16)); + fixed (char* pValue = value) + { + fixed (byte* pData = this.data.data) + { + // Safety: startIndex and count were validated by IndexOf. + Buffer.MemoryCopy(pValue + startIndex, pData + pos, valueSize, valueSize); + pos += valueSize; + pData[pos++] = 0; + pData[pos++] = 0; + } + } + } + + private unsafe void AddScalarDataCountedString(String value, int startIndex, int count) + { + int valueLength = value.Length; + if (startIndex < 0 || startIndex > valueLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || count > valueLength - startIndex) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + int valueSize = count * sizeof(UInt16); + int pos = this.data.ReserveSpaceFor(sizeof(UInt16) + valueSize); + fixed (char* pValue = value) + { + fixed (byte* pData = this.data.data) + { + pData[pos++] = (byte)valueSize; + pData[pos++] = (byte)(valueSize >> 8); + + // Safety: startIndex and count validated above. + Buffer.MemoryCopy(pValue + startIndex, pData + pos, valueSize, valueSize); + } + } + } + + private unsafe void AddScalarDataNulTerminatedAnsiString( + String value, + Encoding encoding, + int startIndex, + int count) + { + int endIndex = value.IndexOf('\0', startIndex, count); + int copyLength = endIndex < 0 + ? count + : endIndex - startIndex; + + int maxValueSize = encoding.GetMaxByteCount(copyLength); + int pos = this.data.ReserveSpaceFor(maxValueSize + 1); + fixed (char* pValue = value) + { + fixed (byte* pData = this.data.data) + { + // Safety: startIndex and count were validated by IndexOf. + pos += encoding.GetBytes( + pValue + startIndex, + copyLength, + pData + pos, + maxValueSize); + pData[pos++] = 0; + } + } + + this.data.SetSize(pos); + } + + private unsafe void AddScalarDataCountedAnsiString(String value, Encoding encoding, int startIndex, int count) + { + int valueLength = value.Length; + if (startIndex < 0 || startIndex > valueLength) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + + if (count < 0 || count > valueLength - startIndex) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + int maxValueSize = encoding.GetMaxByteCount(count); + int pos = this.data.ReserveSpaceFor(sizeof(UInt16) + maxValueSize); + fixed (char* pValue = value) + { + fixed (byte* pData = this.data.data) + { + // Safety: startIndex and count validated above. + int valueSize = encoding.GetBytes( + pValue + startIndex, + count, + pData + pos + sizeof(UInt16), + maxValueSize); + pData[pos++] = (byte)valueSize; + pData[pos++] = (byte)(valueSize >> 8); + pos += valueSize; + } + } + + this.data.SetSize(pos); + } + + /// + /// Usage: AddArrayDataBlockCopy(values, sizeof(ValueType)). + /// For primitives only. Do not use if sizeof(ValueType) does not compile. + /// + private void AddArrayDataBlockCopy(Array values, int elementSize, int startIndex, int count) + { + Debug.Assert(count >= 0); + Debug.Assert(count <= values.Length - startIndex); + + int valuesSize = count * elementSize; + int pos = this.AddArrayBegin(count, valuesSize); + Buffer.BlockCopy(values, startIndex * elementSize, this.data.data, pos, valuesSize); + } + + /// + /// Reserves space and writes the array length. + /// Returns the position where array data should be written. + /// + private int AddArrayBegin(int valuesLength, int valuesSize) + { + // UINT16 array size + int pos = this.data.ReserveSpaceFor(sizeof(ushort) + valuesSize); + this.data.SetUInt16(pos, (ushort)valuesLength); + return pos + sizeof(ushort); + } + + private static UInt64 DateTimeToFileTime(DateTime value) + { + long valueTicks = value.Ticks; + return valueTicks < 504911232000000000 ? 0u : (UInt64)valueTicks - 504911232000000000u; + } + + private unsafe void ResetEvent() + { + Debug.Assert(this.name.IndexOf('\0') < 0, "Event name must not have embedded NUL characters."); + this.data.Reset(); + this.metadata.Reset(); + + int pos = 2; // skip UInt16 MetadataSize + + var eventName = this.name; + var eventNameLength = eventName.Length; + var eventNameMaxByteCount = this.utf8NameEncoding.GetMaxByteCount(eventNameLength); + if ((this.tag & 0x0FE00000) == tag) + { + // Event tag fits in 7 bits. + this.metadata.ReserveSpaceFor(eventNameMaxByteCount + 2 + 1 + 1); + fixed (char* pEventName = eventName) + { + fixed (byte* pMeta = this.metadata.data) + { + pMeta[pos++] = unchecked((byte)(this.tag >> 21)); + pos += this.utf8NameEncoding.GetBytes(pEventName, eventNameLength, pMeta + pos, eventNameMaxByteCount); + pMeta[pos++] = 0; + } + } + } + else if ((tag & 0x0FFFC000) == tag) + { + // Event tag fits in 14 bits. + this.metadata.ReserveSpaceFor(eventNameMaxByteCount + 2 + 2 + 1); + fixed (char* pEventName = eventName) + { + fixed (byte* pMeta = this.metadata.data) + { + pMeta[pos++] = unchecked((byte)(0x80 | this.tag >> 21)); + pMeta[pos++] = unchecked((byte)(0x7f & this.tag >> 14)); + pos += this.utf8NameEncoding.GetBytes(pEventName, eventNameLength, pMeta + pos, eventNameMaxByteCount); + pMeta[pos++] = 0; + } + } + } + else if ((this.tag & 0x0FFFFFFF) == tag) + { + // Event tag fits in 28 bits. + this.metadata.ReserveSpaceFor(eventNameMaxByteCount + 2 + 4 + 1); + fixed (char* pEventName = eventName) + { + fixed (byte* pMeta = this.metadata.data) + { + pMeta[pos++] = unchecked((byte)(0x80 | this.tag >> 21)); + pMeta[pos++] = unchecked((byte)(0x80 | this.tag >> 14)); + pMeta[pos++] = unchecked((byte)(0x80 | this.tag >> 7)); + pMeta[pos++] = unchecked((byte)(0x7f & this.tag >> 0)); + pos += this.utf8NameEncoding.GetBytes(pEventName, eventNameLength, pMeta + pos, eventNameMaxByteCount); + pMeta[pos++] = 0; + } + } + } + else + { + throw new ArgumentException("Tag does not fit in 28 bits.", "tag"); + } + + this.metadata.SetSize(pos); + } + + private struct Vector + { + public byte[] data; + private int size; + + public Vector(int initialCapacity) + { + Debug.Assert(0 < initialCapacity, "initialCapacity <= 0"); + Debug.Assert(initialCapacity <= 65536, "initialCapacity > 65536"); + Debug.Assert((initialCapacity & (initialCapacity - 1)) == 0, "initialCapacity is not a power of 2."); + this.data = new byte[initialCapacity]; + this.size = 0; + } + + public int Size + { + get { return this.size; } + } + + public void Reset() + { + this.size = 0; + } + + public int SetUInt8(int pos, Byte value) + { + this.data[pos] = value; + return 1; + } + + public int SetUInt16(int pos, UInt16 value) + { + this.data[pos + 0] = unchecked((byte)(value)); + this.data[pos + 1] = unchecked((byte)(value >> 8)); + return 2; + } + + public int SetUInt32(int pos, UInt32 value) + { + this.data[pos + 0] = unchecked((byte)(value)); + this.data[pos + 1] = unchecked((byte)(value >> 8)); + this.data[pos + 2] = unchecked((byte)(value >> 16)); + this.data[pos + 3] = unchecked((byte)(value >> 24)); + return 4; + } + + public int SetUInt64(int pos, UInt64 value) + { + this.data[pos + 0] = unchecked((byte)(value)); + this.data[pos + 1] = unchecked((byte)(value >> 8)); + this.data[pos + 2] = unchecked((byte)(value >> 16)); + this.data[pos + 3] = unchecked((byte)(value >> 24)); + this.data[pos + 4] = unchecked((byte)(value >> 32)); + this.data[pos + 5] = unchecked((byte)(value >> 40)); + this.data[pos + 6] = unchecked((byte)(value >> 48)); + this.data[pos + 7] = unchecked((byte)(value >> 56)); + return 8; + } + + public int ReserveSpaceFor(int requiredSize) + { + int oldSize = this.size; + if (this.data.Length - oldSize < requiredSize) + { + this.Grow(requiredSize); + } + + this.size += requiredSize; + return oldSize; + } + + public void SetSize(int newSize) + { + Debug.Assert(newSize <= this.size); + this.size = newSize; + } + + private void Grow(int byteSize) + { + int newCapacity = this.data.Length; + while (true) + { + newCapacity *= 2; + + if (newCapacity > 65536) + { + throw new InvalidOperationException("Event too large"); + } + + if (newCapacity - this.size >= byteSize) + { + break; + } + } + + byte[] newData = new byte[newCapacity]; + Buffer.BlockCopy(this.data, 0, newData, 0, this.size); + this.data = newData; + } + } +} + +/// +/// Supplies details that will be recorded with an event. +/// +[StructLayout(LayoutKind.Sequential)] +internal struct EventDescriptor +{ + /// + /// Supplies a unique identifier for this event. Set Id and Version to 0 if the + /// event has no unique identifier. This should be non-zero only if all events + /// with a particular provider guid + event Id + event Version have identical + /// event name, event field names, and event field types. + /// + public short Id; + + /// + /// Supplies a version for the event. Set this to 0 if Id is 0 or if this is + /// the first version of an event. This should be incremented if any change is + /// made to the event name, field names, or field types of an event with a + /// non-zero Id. + /// + public byte Version; + + /// + /// Supplies the channel for an event. This should almost always be set to 11 + /// for TraceLogging events. + /// + public byte Channel; + + /// + /// Supplies a severity level for an event. This value is used for event + /// filtering. Set the level to a value from 1 (Critical Error) to 5 (Verbose). + /// Note that event level 0 is not recommended because it bypasses all level + /// filtering. + /// + public EventLevel Level; + + /// + /// Adds operational semantics to an event, such as "beginning activity" and + /// "ending activity". Event decoders may use these values to group or flag + /// certain events. + /// + public EventOpcode Opcode; + + /// + /// User-defined value. + /// + public short Task; + + /// + /// The lower 48 bits of a keyword are user-defined categories that can be + /// defined and used to filter events. For example, a provider might declare + /// that within the provider, all "networking" events will set bit 0x1 in + /// the event's Keyword. Then when collecting events, if the collector only + /// wants "networking" events then the collector could ask ETW to deliver + /// only the events that have bit 0x1 set in the Keyword. + /// + /// The upper 16 bits of a keyword are reserved for definition by Microsoft. + /// + /// All providers should define keyword and all events should have at least + /// one keyword bit set. Events with no keyword bits set will usually bypass + /// keyword-based filtering, causing problems for event processing. + /// + public long Keyword; + + /// + /// Initializes a new instance of the EventDescriptor struct, setting Level + /// and Keyword as specified and setting Channel to 11. + /// Do not use 0 for level or keyword as that will make it difficult for + /// event listeners to properly filter the event. + /// + public EventDescriptor(EventLevel level, long keyword = 0x1) + { + this.Id = 0; + this.Version = 0; + this.Channel = 11; + this.Level = level; + this.Opcode = EventOpcode.Info; + this.Task = 0; + this.Keyword = keyword; + } +} + +/// +/// Provides advanced options that can be configured when registering a provider. +/// +internal struct EventProviderOptions +{ + /// + /// If specified, the provider will be registered as belonging to the specified + /// provider group. Note that most providers do not use groups so this can + /// usually be left null. + /// + public Nullable GroupGuid; +} + +/// +/// Event field formatting hint. Used by EventBuilder's Add methods. +/// +/// Every ETW field has an InType (base field type) and an OutType (formatting +/// hint). OutType may be ignored by event decoders, and not all OutTypes are valid +/// for all InTypes. For example, the Boolean OutType is a valid hint only for fields +/// with InType UInt8 and InType Bool32. Check the "inTypes" list in winmeta.xml +/// to determine what OutTypes are valid for each InType. +/// +internal enum EventOutType : byte +{ + /// + /// Requests normal (default) formatting for the field. For example, a UInt32 + /// field with OutType=Default will be formatted as "unsigned decimal" because + /// "Unsigned" is the default OutType for UInt32 fields. + /// + Default, + + /// + /// Suggests that the field be hidden. Ignored by most decoders. + /// + NoPrint, + + /// + /// Suggests that the field be formatted as a string. For example, applying + /// OutType=String to a UInt8 field will cause the field to be treated as an ANSI + /// code page character instead of as an unsigned decimal integer. + /// + /// String is meaningful when applied to fields of type Int8, UInt8, UInt16. + /// + /// String is the default OutType for fields of type UnicodeString, AnsiString, + /// CountedString, CountedAnsiString, Sid. + /// + String, + + /// + /// Suggests that the field be formatted as a boolean (true/false). + /// + /// Boolean is meaningful when applied to fields of type UInt8. + /// + /// Boolean is the default OutType for fields of type Bool32. + /// + Boolean, + + /// + /// Suggests that the field be formatted as hexadecimal. + /// + /// Hex is meaningful when applied to fields of type UInt8, UInt16, UInt32, + /// UInt64. + /// + /// Hex is the default OutType for fields of type HexInt32, HexInt64, Binary, + /// CountedBinary. + /// + Hex, + + /// + /// Suggests that the field be formatted as a process identifier. + /// + /// Pid is meaningful when applied to fields of type UInt32. + /// + Pid, + + /// + /// Suggests that the field be formatted as a thread identifier. + /// + /// Tid is meaningful when applied to fields of type UInt32. + /// + Tid, + + /// + /// Suggests that the field be formatted as a big-endian TCP/UDP port. + /// + /// Port is meaningful when applied to fields of type UInt16. + /// + Port, + + /// + /// Suggests that the field be formatted as an IPv4 address (dotted quad). + /// + /// IPv4 is meaningful when applied to fields of type UInt32. + /// + IPv4, + + /// + /// Suggests that the field be formatted as an IPv6 address. + /// + /// IPv6 is meaningful when applied to fields of type Binary, CountedBinary. + /// + IPv6, + + /// + /// Suggests that the field be formatted as a sockaddr. + /// + /// SocketAddress is meaningful when applied to fields of type Binary, + /// CountedBinary. + /// + SocketAddress, + + /// + /// Suggests that the field be formatted as XML text. + /// + /// Xml is meaningful when applied to fields of type UnicodeString, AnsiString, + /// CountedString, CountedAnsiString. + /// + /// Note that When Xml is applied to an AnsiString or CountedAnsiString field, + /// it implies that the field is encoded as UTF-8. + /// + Xml, + + /// + /// Suggests that the field be formatted as JSON text. + /// + /// Json is meaningful when applied to fields of type UnicodeString, AnsiString, + /// CountedString, CountedAnsiString. + /// + /// Note that When Json is applied to an AnsiString or CountedAnsiString field, + /// it implies that the field is encoded as UTF-8. + /// + Json, + + /// + /// Suggests that the field be formatted as a WIN32 result code. + /// + /// Win32Error is meaningful when applied to fields of type UInt32, HexInt32. + /// + Win32Error, + + /// + /// Suggests that the field be formatted as an NTSTATUS result code. + /// + /// NtStatus is meaningful when applied to fields of type UInt32, HexInt32. + /// + NtStatus, + + /// + /// Suggests that the field be formatted as an HRESULT result code. + /// + /// HResult is meaningful when applied to fields of type Int32 + /// (NOT for use with UInt32 or HexInt32). + /// + HResult, + + /// + /// Suggests that the field be formatted as a date/time. + /// + /// FileTime is the default OutType for fields of type FileTime, SystemTime. + /// + FileTime, + + /// + /// Suggests that the field be formatted as a signed decimal integer. + /// + /// Signed is the default OutType for fields of type Int8, Int16, Int32, Int64. + /// + Signed, + + /// + /// Suggests that the field be formatted as an unsigned decimal integer. + /// + /// Unsigned is the default OutType for fields of type UInt8, UInt16, UInt32, + /// UInt64. + /// + Unsigned, + + /// + /// Suggests that the field be formatted as a locale-invariant date/time. + /// + /// CultureInsensitiveDateTime is meaningful when applied to fields of type + /// FileTime, SystemTime. + /// + CultureInsensitiveDateTime = 33, + + /// + /// Suggests that the field be formatted as UTF-8 text. + /// + /// Utf8 is meaningful when applied to fields of type AnsiString, + /// CountedAnsiString. + /// + Utf8 = 35, + + /// + /// Suggests that the field be formatted as a PKCS-7 message followed by optional + /// TraceLogging-style event decoding information. + /// + /// Pkcs7WithTypeInfo is meaningful when applied to fields of type Binary, + /// CountedBinary. + /// + Pkcs7WithTypeInfo = 36, + + /// + /// Suggests that the field be formatted as an address within the running process + /// that could potentially be decoded as a symbol. + /// + /// CodePointer is meaningful when applied to fields of type UInt32, UInt64, + /// HexInt32, HexInt64. + /// + CodePointer = 37, + + /// + /// Suggests that the field be formatted as a UTC date/time. + /// + /// DateTimeUtc is meaningful when applied to fields of type FileTime, + /// SystemTime. + /// + DateTimeUtc = 38, +} + +/// +/// Used in EventDescriptor. Indicates the severity of an event. Lower numerical +/// value is more severe. Used in filtering, e.g. a consumer might only record events +/// at Warning or higher severity (i.e. Warning or lower numerical value). +/// +internal enum EventLevel : byte +{ + LogAlways, + Critical, + Error, + Warning, + Info, + Verbose +} + +/// +/// Used in EventDescriptor. Indicates special semantics of an event that might be +/// used by the event decoder when organizing events. For example, the Start opcode +/// indicates the beginning of an activity and the Stop opcode indicates the end of +/// an activity. Most events default to Info (0). +/// +internal enum EventOpcode : byte +{ + Info, + Start, + Stop, + DataCollectionStart, + DataCollectionStop, + Extension, + Reply, + Resume, + Suspend, + Send, + Receive = 240, + Reserved241, + Reserved242, + Reserved243, + Reserved244, + Reserved245, + Reserved246, + Reserved247, + Reserved248, + Reserved249, + Reserved250, + Reserved251, + Reserved252, + Reserved253, + Reserved254, + Reserved255, +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index d732fe41cd..e19a9f9a87 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -16,6 +16,8 @@ using System; using System.Diagnostics; +using System.Runtime.InteropServices; +using OpenTelemetry.Exporter.Geneva.TldExporter; using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -37,10 +39,55 @@ public GenevaTraceExporter(GenevaExporterOptions options) Guard.ThrowIfNull(options); Guard.ThrowIfNullOrWhitespace(options.ConnectionString); - var msgPackExporter = new MsgPackTraceExporter(options); - this.IsUsingUnixDomainSocket = msgPackExporter.IsUsingUnixDomainSocket; - this.exportActivity = (in Batch batch) => msgPackExporter.Export(in batch); - this.exporter = msgPackExporter; + bool useMsgPackExporter; + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Etw: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); + } + + useMsgPackExporter = true; + break; + + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + useMsgPackExporter = true; + break; + + case TransportProtocol.EtwTld: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("ETW/TLD cannot be used on non-Windows operating systems."); + } + + useMsgPackExporter = false; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } + + if (useMsgPackExporter) + { + var msgPackTraceExporter = new MsgPackTraceExporter(options); + this.IsUsingUnixDomainSocket = msgPackTraceExporter.IsUsingUnixDomainSocket; + this.exportActivity = (in Batch batch) => msgPackTraceExporter.Export(in batch); + this.exporter = msgPackTraceExporter; + } + else + { + var tldTraceExporter = new TldTraceExporter(options); + this.IsUsingUnixDomainSocket = false; + this.exportActivity = (in Batch batch) => tldTraceExporter.Export(in batch); + this.exporter = tldTraceExporter; + } } public override ExportResult Export(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 65b5471148..4ea5dee0b7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -27,6 +27,7 @@ internal enum TransportProtocol Tcp, Udp, Unix, + EtwTld, Unspecified, } @@ -81,6 +82,12 @@ public string EtwSession set => this._parts[nameof(this.EtwSession)] = value; } + public string PrivatePreviewEnableTraceLoggingDynamic + { + get => this.ThrowIfNotExists(nameof(this.PrivatePreviewEnableTraceLoggingDynamic)); + set => this._parts[nameof(this.PrivatePreviewEnableTraceLoggingDynamic)] = value; + } + public string Endpoint { get => this.ThrowIfNotExists(nameof(this.Endpoint)); @@ -96,6 +103,12 @@ public TransportProtocol Protocol // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux if (this._parts.ContainsKey(nameof(this.EtwSession))) { + _ = this._parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var privatePreviewEnableTraceLoggingDynamic); + if (privatePreviewEnableTraceLoggingDynamic != null && privatePreviewEnableTraceLoggingDynamic.ToUpperInvariant() == bool.TrueString.ToUpperInvariant()) + { + return TransportProtocol.EtwTld; + } + return TransportProtocol.Etw; } diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs new file mode 100644 index 0000000000..e80c8477c2 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -0,0 +1,469 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; + +namespace OpenTelemetry.Exporter.Geneva.TldExporter; + +internal static class JsonSerializer +{ + private const byte ASCII_QUOTATION_MARK = 0x22; + private const byte ASCII_REVERSE_SOLIDUS = 0x5C; + private const byte ASCII_SOLIDUS = 0x2F; + private const byte ASCII_BACKSPACE = 0x08; + private const byte ASCII_FORMFEED = 0x0C; + private const byte ASCII_LINEFEED = 0x0A; + private const byte ASCII_CARRIAGE_RETURN = 0x0D; + private const byte ASCII_HORIZONTAL_TAB = 0x09; + +#if NET6_0_OR_GREATER + private const int MAX_STACK_ALLOC_SIZE_IN_BYTES = 256; +#endif + + private static readonly byte[] HEX_CODE; + private static readonly ThreadLocal threadLocalBuffer = new(() => null); + + static JsonSerializer() + { + var mapping = new byte[] + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + }; + HEX_CODE = new byte[512]; + for (int i = 0; i < 256; i++) + { + HEX_CODE[i] = mapping[i >> 4]; + HEX_CODE[i + 256] = mapping[i & 0x0F]; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SerializeNull() + { + var buffer = threadLocalBuffer.Value; + if (buffer == null) + { + buffer = new byte[65360]; + threadLocalBuffer.Value = buffer; + } + + var count = WriteString(buffer, 0, "null"); + return Encoding.UTF8.GetString(buffer, 0, count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeNull(byte[] buffer, int cursor) + { + return WriteString(buffer, cursor, "null"); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SerializeString(string value) + { + var buffer = threadLocalBuffer.Value; + if (buffer == null) + { + buffer = new byte[65360]; + threadLocalBuffer.Value = buffer; + } + + var count = SerializeString(buffer, 0, value); + return Encoding.UTF8.GetString(buffer, 0, count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeString(byte[] buffer, int cursor, string value) + { + if (value == null) + { + return SerializeNull(buffer, cursor); + } + + buffer[cursor++] = ASCII_QUOTATION_MARK; + cursor = WriteString(buffer, cursor, value); + buffer[cursor++] = ASCII_QUOTATION_MARK; + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SerializeArray(T[] array) + { + var buffer = threadLocalBuffer.Value; + if (buffer == null) + { + buffer = new byte[65360]; + threadLocalBuffer.Value = buffer; + } + + var count = SerializeArray(buffer, 0, array); + return Encoding.UTF8.GetString(buffer, 0, count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeArray(byte[] buffer, int cursor, T[] array) + { + if (array == null) + { + return SerializeNull(buffer, cursor); + } + + buffer[cursor++] = unchecked((byte)'['); + var length = array.Length; + if (length >= 1) + { + cursor = Serialize(buffer, cursor, array[0]); + for (int i = 1; i < length; i++) + { + buffer[cursor++] = unchecked((byte)','); + cursor = Serialize(buffer, cursor, array[i]); + } + } + + buffer[cursor++] = unchecked((byte)']'); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string SerializeMap(IEnumerable> map) + { + var buffer = threadLocalBuffer.Value; + if (buffer == null) + { + buffer = new byte[65360]; + threadLocalBuffer.Value = buffer; + } + + var count = SerializeMap(buffer, 0, map); + return Encoding.UTF8.GetString(buffer, 0, count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte[] SerializeKeyValuePairsListAsBytes(List> listKVp, out int count) + { + var buffer = threadLocalBuffer.Value; + if (buffer == null) + { + buffer = new byte[65360]; + threadLocalBuffer.Value = buffer; + } + + count = SerializeKeyValuePairList(buffer, 0, listKVp); + return buffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeMap(byte[] buffer, int cursor, IEnumerable> map) + { + if (map == null) + { + return SerializeNull(buffer, cursor); + } + + buffer[cursor++] = unchecked((byte)'{'); + int count = 0; + foreach (var entry in map) + { + if (count > 0) + { + buffer[cursor++] = unchecked((byte)','); + } + + cursor = SerializeString(buffer, cursor, entry.Key); + buffer[cursor++] = unchecked((byte)':'); + cursor = Serialize(buffer, cursor, entry.Value); + count++; + } + + buffer[cursor++] = unchecked((byte)'}'); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeKeyValuePairList(byte[] buffer, int cursor, List> listKvp) + { + if (listKvp == null) + { + return SerializeNull(buffer, cursor); + } + + buffer[cursor++] = unchecked((byte)'{'); + int count = 0; + for (int i = 0; i < listKvp.Count; i++) + { + if (count > 0) + { + buffer[cursor++] = unchecked((byte)','); + } + + cursor = SerializeString(buffer, cursor, listKvp[i].Key); + buffer[cursor++] = unchecked((byte)':'); + cursor = Serialize(buffer, cursor, listKvp[i].Value); + count++; + } + + buffer[cursor++] = unchecked((byte)'}'); + return cursor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string Serialize(object obj) + { + var buffer = threadLocalBuffer.Value; + if (buffer == null) + { + buffer = new byte[65360]; + threadLocalBuffer.Value = buffer; + } + + var count = Serialize(buffer, 0, obj); + return Encoding.UTF8.GetString(buffer, 0, count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Serialize(byte[] buffer, int cursor, object obj) + { + if (obj == null) + { + return SerializeNull(buffer, cursor); + } + + switch (obj) + { + case bool v: + return WriteString(buffer, cursor, v ? "true" : "false"); +#if NET6_0_OR_GREATER + case byte: + case sbyte: + case short: + case ushort: + case int: + case uint: + case long: + case ulong: + case float: + case double: + Span tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; + (obj as ISpanFormattable).TryFormat(tmp, out int charsWritten, default, CultureInfo.InvariantCulture); + return WriteString(buffer, cursor, tmp.Slice(0, charsWritten)); + case DateTime dt: + tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; + dt = dt.ToUniversalTime(); + dt.TryFormat(tmp, out int count, default, CultureInfo.InvariantCulture); + return WriteString(buffer, cursor, tmp.Slice(0, count)); +#else + case byte: + case sbyte: + case short: + case ushort: + case int: + case uint: + case long: + case ulong: + case float: + case double: + return WriteString(buffer, cursor, Convert.ToString(obj, CultureInfo.InvariantCulture)); + case DateTime dt: + return WriteString(buffer, cursor, Convert.ToString(dt.ToUniversalTime(), CultureInfo.InvariantCulture)); +#endif + case bool[] vbarray: + return SerializeArray(buffer, cursor, vbarray); + case byte[] vui8array: + return SerializeArray(buffer, cursor, vui8array); + case sbyte[] vi8array: + return SerializeArray(buffer, cursor, vi8array); + case short[] vi16array: + return SerializeArray(buffer, cursor, vi16array); + case ushort[] vui16array: + return SerializeArray(buffer, cursor, vui16array); + case int[] vi32array: + return SerializeArray(buffer, cursor, vi32array); + case uint[] vui32array: + return SerializeArray(buffer, cursor, vui32array); + case long[] vi64array: + return SerializeArray(buffer, cursor, vi64array); + case ulong[] vui64array: + return SerializeArray(buffer, cursor, vui64array); + case float[] vfarray: + return SerializeArray(buffer, cursor, vfarray); + case double[] vdarray: + return SerializeArray(buffer, cursor, vdarray); + case string[] vsarray: + return SerializeArray(buffer, cursor, vsarray); + case DateTime[] vdtarray: + return SerializeArray(buffer, cursor, vdtarray); + case string v: + return SerializeString(buffer, cursor, v); + case IEnumerable> v: + return SerializeMap(buffer, cursor, v); + case object[] v: + return SerializeArray(buffer, cursor, v); +#if NET6_0_OR_GREATER + case ISpanFormattable v: + tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; + if (v.TryFormat(tmp, out charsWritten, default, CultureInfo.InvariantCulture)) + { + return WriteString(buffer, cursor, tmp.Slice(0, charsWritten)); + } + + goto default; +#endif + default: + return SerializeString(buffer, cursor, $"ERROR: type {obj.GetType().FullName} is not supported"); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int WriteString(byte[] buffer, int cursor, string value) + { + for (int i = 0; i < value.Length; i++) + { + var ordinal = (ushort)value[i]; + switch (ordinal) + { + case ASCII_QUOTATION_MARK: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = ASCII_QUOTATION_MARK; + break; + case ASCII_REVERSE_SOLIDUS: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + break; + case ASCII_SOLIDUS: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = ASCII_SOLIDUS; + break; + case ASCII_BACKSPACE: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'b'); + break; + case ASCII_FORMFEED: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'f'); + break; + case ASCII_LINEFEED: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'n'); + break; + case ASCII_CARRIAGE_RETURN: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'r'); + break; + case ASCII_HORIZONTAL_TAB: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'t'); + break; + default: + // ASCII printable characters + if (ordinal >= 32 && ordinal < 127) + { + buffer[cursor++] = unchecked((byte)ordinal); + } + + // ASCII control characters, extended ASCII codes or UNICODE + else + { + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + var high = unchecked(ordinal >> 8); + var low = ordinal & 0xFF; + buffer[cursor++] = unchecked((byte)'u'); + buffer[cursor++] = HEX_CODE[high]; + buffer[cursor++] = HEX_CODE[high + 256]; + buffer[cursor++] = HEX_CODE[low]; + buffer[cursor++] = HEX_CODE[low + 256]; + } + + break; + } + } + + return cursor; + } + +#if NET6_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int WriteString(byte[] buffer, int cursor, Span value) + { + for (int i = 0; i < value.Length; i++) + { + var ordinal = (ushort)value[i]; + switch (ordinal) + { + case ASCII_QUOTATION_MARK: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = ASCII_QUOTATION_MARK; + break; + case ASCII_REVERSE_SOLIDUS: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + break; + case ASCII_SOLIDUS: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = ASCII_SOLIDUS; + break; + case ASCII_BACKSPACE: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'b'); + break; + case ASCII_FORMFEED: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'f'); + break; + case ASCII_LINEFEED: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'n'); + break; + case ASCII_CARRIAGE_RETURN: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'r'); + break; + case ASCII_HORIZONTAL_TAB: + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + buffer[cursor++] = unchecked((byte)'t'); + break; + default: + // ASCII printable characters + if (ordinal >= 32 && ordinal < 127) + { + buffer[cursor++] = unchecked((byte)ordinal); + } + + // ASCII control characters, extended ASCII codes or UNICODE + else + { + buffer[cursor++] = ASCII_REVERSE_SOLIDUS; + var high = unchecked(ordinal >> 8); + var low = ordinal & 0xFF; + buffer[cursor++] = unchecked((byte)'u'); + buffer[cursor++] = HEX_CODE[high]; + buffer[cursor++] = HEX_CODE[high + 256]; + buffer[cursor++] = HEX_CODE[low]; + buffer[cursor++] = HEX_CODE[low + 256]; + } + + break; + } + } + + return cursor; + } +#endif +} diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs new file mode 100644 index 0000000000..331c0e12f9 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs @@ -0,0 +1,153 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Text; +using OpenTelemetry.Exporter.Geneva.External; + +namespace OpenTelemetry.Exporter.Geneva.TldExporter; + +internal abstract class TldExporter +{ + internal const int StringLengthLimit = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 + internal static readonly IReadOnlyDictionary V40_PART_A_TLD_MAPPING = new Dictionary + { + // Part A + [Schema.V40.PartA.IKey] = "iKey", + [Schema.V40.PartA.Name] = "name", + [Schema.V40.PartA.Time] = "time", + + // Part A Application Extension + [Schema.V40.PartA.Extensions.App.Id] = "ext_app_id", + [Schema.V40.PartA.Extensions.App.Ver] = "ext_app_ver", + + // Part A Cloud Extension + [Schema.V40.PartA.Extensions.Cloud.Role] = "ext_cloud_role", + [Schema.V40.PartA.Extensions.Cloud.RoleInstance] = "ext_cloud_roleInstance", + [Schema.V40.PartA.Extensions.Cloud.RoleVer] = "ext_cloud_roleVer", + + // Part A Os extension + [Schema.V40.PartA.Extensions.Os.Name] = "ext_os_name", + [Schema.V40.PartA.Extensions.Os.Ver] = "ext_os_ver", + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected static void Serialize(EventBuilder eb, string key, object value) + { + switch (value) + { + case bool vb: + eb.AddUInt8(key, (byte)(vb ? 1 : 0), EventOutType.Boolean); + break; + case byte vui8: + eb.AddUInt8(key, vui8); + break; + case sbyte vi8: + eb.AddInt8(key, vi8); + break; + case short vi16: + eb.AddInt16(key, vi16); + break; + case ushort vui16: + eb.AddUInt16(key, vui16); + break; + case int vi32: + eb.AddInt32(key, vi32); + break; + case uint vui32: + eb.AddUInt32(key, vui32); + break; + case long vi64: + eb.AddInt64(key, vi64); + break; + case ulong vui64: + eb.AddUInt64(key, vui64); + break; + case float vf: + eb.AddFloat32(key, vf); + break; + case double vd: + eb.AddFloat64(key, vd); + break; + case string vs: + eb.AddCountedAnsiString(key, vs, Encoding.UTF8, 0, Math.Min(vs.Length, StringLengthLimit)); + break; + case DateTime vdt: + eb.AddFileTime(key, vdt.ToUniversalTime()); + break; + + // TODO: case bool[] + // TODO: case obj[] + case byte[] vui8array: + eb.AddUInt8Array(key, vui8array); + break; + case sbyte[] vi8array: + eb.AddInt8Array(key, vi8array); + break; + case short[] vi16array: + eb.AddInt16Array(key, vi16array); + break; + case ushort[] vui16array: + eb.AddUInt16Array(key, vui16array); + break; + case int[] vi32array: + eb.AddInt32Array(key, vi32array); + break; + case uint[] vui32array: + eb.AddUInt32Array(key, vui32array); + break; + case long[] vi64array: + eb.AddInt64Array(key, vi64array); + break; + case ulong[] vui64array: + eb.AddUInt64Array(key, vui64array); + break; + case float[] vfarray: + eb.AddFloat32Array(key, vfarray); + break; + case double[] vdarray: + eb.AddFloat64Array(key, vdarray); + break; + case string[] vsarray: + eb.AddCountedStringArray(key, vsarray); + break; + case DateTime[] vdtarray: + for (int i = 0; i < vdtarray.Length; i++) + { + vdtarray[i] = vdtarray[i].ToUniversalTime(); + } + + eb.AddFileTimeArray(key, vdtarray); + break; + default: + string repr; + try + { + repr = Convert.ToString(value, CultureInfo.InvariantCulture); + } + catch + { + repr = $"ERROR: type {value.GetType().FullName} is not supported"; + } + + eb.AddCountedAnsiString(key, repr, Encoding.UTF8, 0, Math.Min(repr.Length, StringLengthLimit)); + break; + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs new file mode 100644 index 0000000000..8a23115b4a --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -0,0 +1,350 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.Text; +using System.Threading; +using OpenTelemetry.Exporter.Geneva.External; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.Geneva.TldExporter; +internal sealed class TldTraceExporter : TldExporter, IDisposable +{ + // TODO: Is using a single ThreadLocal a better idea? + private static readonly ThreadLocal eventBuilder = new(() => null); + private static readonly ThreadLocal>> keyValuePairs = new(() => null); + private static readonly ThreadLocal[]> partCFields = new(() => null); // This is used to temporarily store the PartC fields from tags + + private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); + + private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary + { + ["db.system"] = "dbSystem", + ["db.name"] = "dbName", + ["db.statement"] = "dbStatement", + + ["http.method"] = "httpMethod", + ["http.url"] = "httpUrl", + ["http.status_code"] = "httpStatusCode", + + ["messaging.system"] = "messagingSystem", + ["messaging.destination"] = "messagingDestination", + ["messaging.url"] = "messagingUrl", + }; + + private readonly string partAName = "Span"; + private readonly byte partAFieldsCount = 3; // At least three fields: time, ext_dt_traceId, ext_dt_spanId + private readonly IReadOnlyDictionary m_customFields; + private readonly Tuple repeatedPartAFields; + + private readonly EventProvider eventProvider; + + private bool isDisposed; + + public TldTraceExporter(GenevaExporterOptions options) + { + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); + + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + this.eventProvider = new EventProvider(connectionStringBuilder.EtwSession); + + if (options.TableNameMappings != null + && options.TableNameMappings.TryGetValue("Span", out var customTableName)) + { + this.partAName = customTableName; + } + + // TODO: Validate custom fields (reserved name? etc). + if (options.CustomFields != null) + { + var customFields = new Dictionary(StringComparer.Ordinal); + + // Seed customFields with Span PartB + customFields["azureResourceProvider"] = true; + foreach (var name in CS40_PART_B_MAPPING.Values) + { + customFields[name] = true; + } + + foreach (var name in options.CustomFields) + { + customFields[name] = true; + } + + this.m_customFields = customFields; + } + + if (options.PrepopulatedFields != null) + { + var prePopulatedFieldsCount = (byte)(options.PrepopulatedFields.Count - 1); // PrepopulatedFields option has the key ".ver" added to it which is not needed for TLD + this.partAFieldsCount += prePopulatedFieldsCount; + + var eb = eventBuilder.Value; + if (eb == null) + { + eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); + eventBuilder.Value = eb; + } + + eb.Reset(this.partAName); + + foreach (var entry in options.PrepopulatedFields) + { + var key = entry.Key; + var value = entry.Value; + + if (entry.Key == Schema.V40.PartA.Ver) + { + continue; + } + + V40_PART_A_TLD_MAPPING.TryGetValue(key, out string replacementKey); + var keyToSerialize = replacementKey ?? key; + Serialize(eb, keyToSerialize, value); + + this.repeatedPartAFields = eb.GetRawFields(); + } + } + } + + public ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + if (this.eventProvider.IsEnabled()) + { + foreach (var activity in batch) + { + try + { + this.SerializeActivity(activity); + this.eventProvider.Write(eventBuilder.Value); + } + catch (Exception ex) + { + ExporterEventSource.Log.FailedToSendTraceData(ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } + } + } + else + { + return ExportResult.Failure; + } + + return result; + } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + try + { + // DO NOT Dispose eventBuilder, keyValuePairs, and partCFields as they are static + this.eventProvider?.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("TldTraceExporter Dispose failed.", ex); + } + + this.isDisposed = true; + } + + internal void SerializeActivity(Activity activity) + { + var eb = eventBuilder.Value; + if (eb == null) + { + eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); + eventBuilder.Value = eb; + } + + eb.Reset(this.partAName); + eb.AddUInt16("__csver__", 1024, EventOutType.Hex); + + var dtBegin = activity.StartTimeUtc; + var tsBegin = dtBegin.Ticks; + var tsEnd = tsBegin + activity.Duration.Ticks; + var dtEnd = new DateTime(tsEnd); + + eb.AddStruct("PartA", this.partAFieldsCount); + eb.AddFileTime("time", dtEnd); + eb.AddCountedString("ext_dt_traceId", activity.Context.TraceId.ToHexString()); + eb.AddCountedString("ext_dt_spanId", activity.Context.SpanId.ToHexString()); + if (this.repeatedPartAFields != null) + { + eb.AppendRawFields(this.repeatedPartAFields); + } + + byte partBFieldsCount = 5; + var partBFieldsCountPatch = eb.AddStruct("PartB", partBFieldsCount); // We at least have five fields in PartB: _typeName, name, kind, startTime, success + eb.AddCountedString("_typeName", "Span"); + eb.AddCountedAnsiString("name", activity.DisplayName, Encoding.UTF8); + eb.AddUInt8("kind", (byte)activity.Kind); + eb.AddFileTime("startTime", dtBegin); + + var strParentId = activity.ParentSpanId.ToHexString(); + + // Note: this should be blazing fast since Object.ReferenceEquals(strParentId, INVALID_SPAN_ID) == true + if (!string.Equals(strParentId, INVALID_SPAN_ID, StringComparison.Ordinal)) + { + eb.AddCountedString("parentId", strParentId); + partBFieldsCount++; + } + + var linkEnumerator = activity.EnumerateLinks(); + if (linkEnumerator.MoveNext()) + { + var keyValuePairsForLinks = keyValuePairs.Value; + if (keyValuePairsForLinks == null) + { + keyValuePairsForLinks = new List>(); + keyValuePairs.Value = keyValuePairsForLinks; + } + + keyValuePairsForLinks.Clear(); + + do + { + ref readonly var link = ref linkEnumerator.Current; + + // TODO: This could lead to unbounded memory usage. + keyValuePairsForLinks.Add(new("toTraceId", link.Context.TraceId.ToHexString())); + keyValuePairsForLinks.Add(new("toSpanId", link.Context.SpanId.ToHexString())); + } + while (linkEnumerator.MoveNext()); + + var serializedLinksStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(keyValuePairsForLinks, out var count); + eb.AddCountedAnsiString("links", serializedLinksStringAsBytes, 0, count); + + partBFieldsCount++; + } + + byte hasEnvProperties = 0; + byte isStatusSuccess = 1; + string statusDescription = string.Empty; + + int partCFieldsCountFromTags = 0; + var kvpArrayForPartCFields = partCFields.Value; + if (kvpArrayForPartCFields == null) + { + kvpArrayForPartCFields = new KeyValuePair[120]; + partCFields.Value = kvpArrayForPartCFields; + } + + List> envPropertiesList = null; + + foreach (ref readonly var entry in activity.EnumerateTagObjects()) + { + // TODO: check name collision + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) + { + Serialize(eb, entry.Key, replacementKey); + partBFieldsCount++; + } + else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) + { + if (string.Equals(Convert.ToString(entry.Value, CultureInfo.InvariantCulture), "ERROR", StringComparison.Ordinal)) + { + isStatusSuccess = 0; + } + + continue; + } + else if (string.Equals(entry.Key, "otel.status_description", StringComparison.Ordinal)) + { + statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); + continue; + } + else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + { + // TODO: the above null check can be optimized and avoided inside foreach. + kvpArrayForPartCFields[partCFieldsCountFromTags] = new(entry.Key, entry.Value); + partCFieldsCountFromTags++; + } + else + { + if (hasEnvProperties == 0) + { + hasEnvProperties = 1; + envPropertiesList = keyValuePairs.Value; + if (envPropertiesList == null) + { + envPropertiesList = new List>(); + keyValuePairs.Value = envPropertiesList; + } + + envPropertiesList.Clear(); + } + + // TODO: This could lead to unbounded memory usage. + envPropertiesList.Add(new(entry.Key, entry.Value)); + } + } + + if (activity.Status != ActivityStatusCode.Unset) + { + if (activity.Status == ActivityStatusCode.Error) + { + isStatusSuccess = 0; + } + + if (!string.IsNullOrEmpty(activity.StatusDescription)) + { + eb.AddCountedAnsiString("statusMessage", statusDescription, Encoding.UTF8); + partBFieldsCount++; + } + } + else + { + if (!string.IsNullOrEmpty(activity.StatusDescription)) + { + eb.AddCountedAnsiString("statusMessage", statusDescription, Encoding.UTF8); + partBFieldsCount++; + } + } + + // Do not increment partBFieldsCount here as the field "success" has already been accounted for + eb.AddUInt8("success", isStatusSuccess, EventOutType.Boolean); + + eb.SetStructFieldCount(partBFieldsCountPatch, partBFieldsCount); + + var partCFieldsCount = partCFieldsCountFromTags + hasEnvProperties; + eb.AddStruct("PartC", (byte)partCFieldsCount); + + for (int i = 0; i < partCFieldsCountFromTags; i++) + { + Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); + } + + if (hasEnvProperties == 1) + { + // Get all "other" fields and collapse them into single field + // named "env_properties". + + var serializedEnvPropertiesStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(envPropertiesList, out var count); + eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs new file mode 100644 index 0000000000..8b20e53d62 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -0,0 +1,194 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Text; + +namespace OpenTelemetry.Exporter.Geneva.TldExporter; + +/// +/// Like ASCIIEncoding but instead of checking for non-ASCII characters, it just +/// ignores the top bits of the character. This is significantly faster than +/// ASCIIEncoding and can be used to improve performance in cases where you know a +/// string only contains ASCII characters. +/// + +#pragma warning disable SA1124 +internal sealed class UncheckedASCIIEncoding : Encoding +{ + public static Encoding SharedInstance = new UncheckedASCIIEncoding(); + + public UncheckedASCIIEncoding() + : base(20127) + { + } + + #region Required implementation of Encoding abstract methods + + public override int GetMaxByteCount(int charCount) + { + return charCount; + } + + public override int GetMaxCharCount(int byteCount) + { + return byteCount; + } + + public override int GetByteCount(char[] chars, int charIndex, int charCount) + { + return charCount; + } + + public override int GetCharCount(byte[] bytes, int byteIndex, int byteCount) + { + return byteCount; + } + + public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + { + ValidateArgs(chars, charIndex, charCount, bytes, byteIndex, "char", "byte"); + fixed (char* charPtr = chars) + { + fixed (byte* bytePtr = bytes) + { + return this.GetBytes(charPtr + charIndex, charCount, bytePtr + byteIndex, bytes.Length - byteIndex); + } + } + } + + public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + { + ValidateArgs(bytes, byteIndex, byteCount, chars, charIndex, "byte", "char"); + fixed (byte* bytePtr = bytes) + { + fixed (char* charPtr = chars) + { + return this.GetChars(bytePtr + byteIndex, byteCount, charPtr + charIndex, chars.Length - charIndex); + } + } + } + + #endregion + + #region Required overrides (used by the required implementation) + + public override unsafe int GetBytes(char* charPtr, int charCount, byte* bytePtr, int byteCount) + { + if (byteCount < charCount) + { + throw new ArgumentOutOfRangeException(nameof(byteCount)); + } + + for (int i = 0; i < charCount; i += 1) + { + bytePtr[i] = unchecked((byte)(charPtr[i] & 0x7F)); + } + + return charCount; + } + + public override unsafe int GetChars(byte* bytePtr, int byteCount, char* charPtr, int charCount) + { + if (charCount < byteCount) + { + throw new ArgumentOutOfRangeException(nameof(charCount)); + } + + for (int i = 0; i < byteCount; i += 1) + { + charPtr[i] = (char)bytePtr[i]; + } + + return byteCount; + } + + #endregion + + #region Optional overrides (performance/functionality improvement) + + public override bool IsSingleByte => true; + + public override int GetByteCount(string chars) + { + if (chars == null) + { + throw new ArgumentNullException(nameof(chars)); + } + + return chars.Length; + } + + public override unsafe int GetByteCount(char* charPtr, int charCount) + { + return charCount; + } + + public override unsafe int GetCharCount(byte* bytePtr, int byteCount) + { + return byteCount; + } + + public unsafe override int GetBytes(string chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + { + if (chars == null || bytes == null) + { + throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes)); + } + else if (charIndex < 0 || charCount < 0) + { + throw new ArgumentOutOfRangeException(charIndex < 0 ? nameof(charIndex) : nameof(charCount)); + } + else if (chars.Length - charIndex < charCount) + { + throw new ArgumentOutOfRangeException(chars); + } + else if (byteIndex < 0 || byteIndex > bytes.Length) + { + throw new ArgumentOutOfRangeException(nameof(byteIndex)); + } + + fixed (char* charPtr = chars) + { + fixed (byte* bytePtr = bytes) + { + return this.GetBytes(charPtr + charIndex, charCount, bytePtr + byteIndex, bytes.Length - byteIndex); + } + } + } + + #endregion + + private static void ValidateArgs(TA[] a, int aIndex, int aCount, TB[] b, int bIndex, string aName, string bName) + { + if (a == null || b == null) + { + throw new ArgumentNullException(a == null ? aName + "s" : bName + "s"); + } + else if (aIndex < 0 || aCount < 0) + { + throw new ArgumentOutOfRangeException(aIndex < 0 ? aName + "Index" : aName + "Count"); + } + else if (a.Length - aIndex < aCount) + { + throw new ArgumentOutOfRangeException(aName + "s"); + } + else if (bIndex < 0 || bIndex > b.Length) + { + throw new ArgumentOutOfRangeException(bName + "Index"); + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs new file mode 100644 index 0000000000..938e9c4933 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs @@ -0,0 +1,124 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Text; +using BenchmarkDotNet.Attributes; +using OpenTelemetry.Exporter.Geneva.External; +using OpenTelemetry.Exporter.Geneva.TldExporter; + +/* +BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + + +| Method | Mean | Error | StdDev | Allocated | +|------------------------------- |----------:|----------:|----------:|----------:| +| TLD_SerializeUInt8 | 22.483 ns | 0.0216 ns | 0.0202 ns | - | +| MsgPack_SerializeUInt8 | 7.360 ns | 0.0135 ns | 0.0127 ns | - | +| TLD_SerializeAsciiString | 31.141 ns | 0.0210 ns | 0.0176 ns | - | +| MsgPack_SerializeAsciiString | 19.580 ns | 0.0412 ns | 0.0385 ns | - | +| TLD_SerializeUnicodeSubString | 41.064 ns | 0.0708 ns | 0.0662 ns | - | +| TLD_SerializeUnicodeString | 41.889 ns | 0.0927 ns | 0.0868 ns | - | +| MsgPack_SerializeUnicodeString | 21.806 ns | 0.0281 ns | 0.0249 ns | - | +| TLD_SerializeDateTime | 45.321 ns | 0.1321 ns | 0.1235 ns | - | +| MsgPack_SerializeDateTime | 30.667 ns | 0.0401 ns | 0.0356 ns | - | +| TLD_Reset | 12.739 ns | 0.0351 ns | 0.0328 ns | - | +*/ + +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +[MemoryDiagnoser] +public class SerializationBenchmarks +{ + private const int StringLengthLimit = (1 << 14) - 1; + private const string Key = "ext_dt_traceId"; + private const string Value = "e8ea7e9ac72de94e91fabc613f9686b2"; + private readonly EventBuilder eventBuilder = new(UncheckedASCIIEncoding.SharedInstance); + private readonly byte[] buffer = new byte[65360]; + + [Benchmark] + public void TLD_SerializeUInt8() + { + this.eventBuilder.Reset("test"); + this.eventBuilder.AddUInt8("Number", 123); + } + + [Benchmark] + public void MsgPack_SerializeUInt8() + { + var cursor = MessagePackSerializer.SerializeAsciiString(this.buffer, 0, "Number"); + MessagePackSerializer.SerializeUInt8(this.buffer, cursor, 123); + } + + [Benchmark] + public void TLD_SerializeAsciiString() + { + this.eventBuilder.Reset("test"); + this.eventBuilder.AddCountedString(Key, Value); + } + + [Benchmark] + public void MsgPack_SerializeAsciiString() + { + var cursor = MessagePackSerializer.SerializeAsciiString(this.buffer, 0, Key); + MessagePackSerializer.SerializeAsciiString(this.buffer, cursor, Value); + } + + [Benchmark] + public void TLD_SerializeUnicodeSubString() + { + this.eventBuilder.Reset("test"); + this.eventBuilder.AddCountedAnsiString(Key, Value, Encoding.UTF8, 0, Math.Min(Value.Length, StringLengthLimit)); + } + + [Benchmark] + public void TLD_SerializeUnicodeString() + { + this.eventBuilder.Reset("test"); + this.eventBuilder.AddCountedAnsiString(Key, Value, Encoding.UTF8); + } + + [Benchmark] + public void MsgPack_SerializeUnicodeString() + { + var cursor = MessagePackSerializer.SerializeAsciiString(this.buffer, 0, Key); + MessagePackSerializer.SerializeUnicodeString(this.buffer, cursor, Value); + } + + [Benchmark] + public void TLD_SerializeDateTime() + { + this.eventBuilder.Reset("test"); + this.eventBuilder.AddFileTime("time", DateTime.UtcNow); + } + + [Benchmark] + public void MsgPack_SerializeDateTime() + { + var cursor = MessagePackSerializer.SerializeAsciiString(this.buffer, 0, "time"); + MessagePackSerializer.SerializeUtcDateTime(this.buffer, cursor, DateTime.UtcNow); + } + + [Benchmark] + public void TLD_Reset() + { + this.eventBuilder.Reset("test"); + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs new file mode 100644 index 0000000000..1e6bebef8f --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs @@ -0,0 +1,160 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using BenchmarkDotNet.Attributes; +using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Trace; + +/* +BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + + +| Method | Mean | Error | StdDev | Allocated | +|-------------------------- |---------:|--------:|--------:|----------:| +| MsgPack_SerializeActivity | 300.3 ns | 1.14 ns | 1.07 ns | - | +| TLD_SerializeActivity | 371.0 ns | 0.70 ns | 0.66 ns | - | +| MsgPack_ExportActivity | 680.2 ns | 1.73 ns | 1.62 ns | - | +| TLD_ExportActivity | 729.5 ns | 4.78 ns | 4.24 ns | - | +*/ + +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +[MemoryDiagnoser] +public class TLDTraceExporterBenchmarks +{ + private readonly Activity activity; + private readonly Batch batch; + private readonly MsgPackTraceExporter msgPackExporter; + private readonly TldTraceExporter tldExporter; + private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); + + public TLDTraceExporterBenchmarks() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + + this.batch = this.CreateBatch(); + + using var activityListener = new ActivityListener + { + ActivityStarted = null, + ActivityStopped = null, + ShouldListenTo = (activitySource) => activitySource.Name == this.activitySource.Name, + Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllDataAndRecorded, + }; + + ActivitySource.AddActivityListener(activityListener); + + using (var testActivity = this.activitySource.StartActivity("Benchmark")) + { + this.activity = testActivity; + this.activity?.SetTag("tagString", "value"); + this.activity?.SetTag("tagInt", 100); + this.activity?.SetStatus(Status.Error); + } + + this.msgPackExporter = new MsgPackTraceExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + this.tldExporter = new TldTraceExporter(new GenevaExporterOptions() + { + ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + } + + [Benchmark] + public void MsgPack_SerializeActivity() + { + this.msgPackExporter.SerializeActivity(this.activity); + } + + [Benchmark] + public void TLD_SerializeActivity() + { + this.tldExporter.SerializeActivity(this.activity); + } + + [Benchmark] + public void MsgPack_ExportActivity() + { + this.msgPackExporter.Export(this.batch); + } + + [Benchmark] + public void TLD_ExportActivity() + { + this.tldExporter.Export(this.batch); + } + + [GlobalCleanup] + public void Cleanup() + { + this.activity.Dispose(); + this.batch.Dispose(); + this.activitySource.Dispose(); + this.msgPackExporter.Dispose(); + this.tldExporter.Dispose(); + } + + private Batch CreateBatch() + { + using var batchGeneratorExporter = new BatchGeneratorExporter(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(this.activitySource.Name) + .AddProcessor(new SimpleActivityExportProcessor(batchGeneratorExporter)) + .Build(); + + using (var activity = this.activitySource.StartActivity("Benchmark")) + { + activity.SetTag("tagString", "value"); + activity.SetTag("tagInt", 100); + activity.SetStatus(Status.Error); + } + + return batchGeneratorExporter.Batch; + } + + private class BatchGeneratorExporter : BaseExporter + { + public Batch Batch { get; set; } + + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index f66032f065..51e8faa314 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -24,7 +24,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -using System.Threading.Tasks; using OpenTelemetry.Trace; using Xunit; @@ -476,6 +475,42 @@ public void GenevaTraceExporter_Success_Linux() } } + [Fact] + public void TLDTraceExporter_Success_Windows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + + // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); + + var source = new ActivitySource(sourceName); + using (var activity = source.StartActivity("SayHello")) + { + activity?.SetTag("foo", 1); + activity?.SetTag("bar", "Hello, World!"); + activity?.SetTag("baz", new int[] { 1, 2, 3 }); + activity?.SetStatus(ActivityStatusCode.Ok); + } + } + } + private static string GetRandomFilePath() { while (true) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs new file mode 100644 index 0000000000..2b1e4c11ef --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -0,0 +1,104 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Text; +using OpenTelemetry.Exporter.Geneva.TldExporter; +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public class JsonSerializerTests +{ + private static void TestSerialization(object value, string expected) + { + var buffer = new byte[64 * 1024]; + var length = JsonSerializer.Serialize(buffer, 0, value); + Assert.Equal(expected, Encoding.ASCII.GetString(buffer, 0, length)); + } + + [Fact] + [Trait("Platform", "Any")] + public void JsonSerializer_Null() + { + TestSerialization(null, "null"); + } + + [Fact] + [Trait("Platform", "Any")] + public void JsonSerializer_Boolean() + { + TestSerialization(true, "true"); + TestSerialization(false, "false"); + } + + [Fact] + [Trait("Platform", "Any")] + public void JsonSerializer_Numeric() + { + TestSerialization(0, "0"); + TestSerialization(123, "123"); + TestSerialization(-123, "-123"); + TestSerialization(0.0f, "0"); + TestSerialization(1.0f, "1"); + TestSerialization(3.14f, "3.14"); + TestSerialization(-3.14f, "-3.14"); + TestSerialization(0.0d, "0"); + TestSerialization(3.14d, "3.14"); + TestSerialization(3.1415926d, "3.1415926"); + TestSerialization(-3.1415926d, "-3.1415926"); + } + + [Fact] + [Trait("Platform", "Any")] + public void JsonSerializer_String() + { + TestSerialization((string)null, "null"); + TestSerialization(string.Empty, "''".Replace("'", "\"")); + TestSerialization("Hello, World!", "'Hello, World!'".Replace("'", "\"")); + TestSerialization("\"", "'\\\"'".Replace("'", "\"")); + TestSerialization("\n", "'\\n'".Replace("'", "\"")); + TestSerialization("\t", "'\\t'".Replace("'", "\"")); + TestSerialization("\0", "'\\u0000'".Replace("'", "\"")); + TestSerialization("\u6768", "'\\u6768'".Replace("'", "\"")); + } + + [Fact] + [Trait("Platform", "Any")] + public void JsonSerializer_Array() + { + TestSerialization((object[])null, "null"); + TestSerialization(new object[] { }, "[]"); + TestSerialization(new object[] { 1, 2, 3 }, "[1,2,3]"); + } + + [Fact] + [Trait("Platform", "Any")] + public void JsonSerializer_Map() + { + TestSerialization((Dictionary)null, "null"); + TestSerialization(new Dictionary(), "{}"); + TestSerialization( + new Dictionary + { + ["foo"] = 1, + ["bar"] = "baz", + ["golden ratio"] = 0.6180340f, + ["pi"] = 3.14159265358979d, + }, + "{'foo':1,'bar':'baz','golden ratio':0.618034,'pi':3.14159265358979}".Replace("'", "\"")); + } +} From 168cf8e78f26a2bdf8822189104061e339d28697 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Tue, 10 Jan 2023 16:53:36 -0800 Subject: [PATCH 0489/1499] [EventCounters] Add example project (#860) --- .../Examples.EventCounters.csproj | 19 +++++++++ .../Examples.EventCounters/Program.cs | 42 +++++++++++++++++++ .../Examples.EventCounters/README.md | 21 ++++++++++ opentelemetry-dotnet-contrib.sln | 7 ++++ .../README.md | 3 ++ 5 files changed, 92 insertions(+) create mode 100644 examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj create mode 100644 examples/event-counters/Examples.EventCounters/Program.cs create mode 100644 examples/event-counters/Examples.EventCounters/README.md diff --git a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj new file mode 100644 index 0000000000..29ed2fe979 --- /dev/null +++ b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj @@ -0,0 +1,19 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/examples/event-counters/Examples.EventCounters/Program.cs b/examples/event-counters/Examples.EventCounters/Program.cs new file mode 100644 index 0000000000..fc98de6fbb --- /dev/null +++ b/examples/event-counters/Examples.EventCounters/Program.cs @@ -0,0 +1,42 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; +using OpenTelemetry; +using OpenTelemetry.Metrics; + +// Create EventSources and EventCounters +ThreadLocal random = new(() => new Random()); +using EventSource eventSource = new("MyEventSource"); +using EventCounter eventCounter = new("MyEventCounter", eventSource); +using PollingCounter pollingCounter = new("MyPollingCounter", eventSource, () => random.Value!.NextDouble()); + +// Create and Configure Meter Provider +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddEventCountersInstrumentation(options => + { + options.AddEventSources(eventSource.Name); + options.RefreshIntervalSecs = 1; + }) + .AddConsoleExporter() + .Build(); + +// Write to EventCounters +eventCounter.WriteMetric(0); +eventCounter.WriteMetric(1000); + +// Wait for EventCounter data to be polled (RefreshIntervalSecs is 1 second by default) +Thread.Sleep(1200); diff --git a/examples/event-counters/Examples.EventCounters/README.md b/examples/event-counters/Examples.EventCounters/README.md new file mode 100644 index 0000000000..d79aefe1a6 --- /dev/null +++ b/examples/event-counters/Examples.EventCounters/README.md @@ -0,0 +1,21 @@ +# EventCounters Instrumentation for OpenTelemetry .NET - Examples + +This is an all-in-one sample that shows how to publish EventCounters using +the OpenTelemetry Metrics Api. + +## Expected Output + +After running `dotnet run` from this directory + +```text +Resource associated with Metric: + service.name: unknown_service:Examples.EventCounters + +Export EventCounters.MyEventSource.MyEventCounter, Meter: OpenTelemetry.Instrumentation.EventCounters/1.0.0.0 +(2022-11-01T17:37:37.9046769Z, 2022-11-01T17:37:38.4014060Z] DoubleGauge +Value: 500 + +Export EventCounters.MyEventSource.MyPollingCounter, Meter: OpenTelemetry.Instrumentation.EventCounters/1.0.0.0 +(2022-11-01T17:37:37.9076414Z, 2022-11-01T17:37:38.4014299Z] DoubleGauge +Value: 0.5233669819037192 +``` diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 5c61596560..ff592c7b7b 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -242,6 +242,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "process-instrumentation", "examples\process-instrumentation\process-instrumentation.csproj", "{C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventCounters", "examples\event-counters\Examples.EventCounters\Examples.EventCounters.csproj", "{BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -508,6 +510,10 @@ Global {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Debug|Any CPU.Build.0 = Debug|Any CPU {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Release|Any CPU.ActiveCfg = Release|Any CPU {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75}.Release|Any CPU.Build.0 = Release|Any CPU + {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -586,6 +592,7 @@ Global {0F18B7C8-B192-4236-9578-7AD02BFC7128} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {B40B975E-78B2-4712-8B4D-BADA67DF0C0A} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index bbfc44a413..1be4d33fab 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -11,6 +11,9 @@ using OpenTelemetry Metrics API. ## Steps to enable OpenTelemetry.Instrumentation.EventCounters +You can view an example project using EventCounters at +`/examples/event-counters/Examples.EventCounters`. + ### Step 1: Install Package Add a reference to the From 1cc62626e1b3873c1710603f0b38c344133cf6b8 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 10 Jan 2023 17:55:06 -0800 Subject: [PATCH 0490/1499] [Exporter.Geneva] Add TLDLogExporter (#874) --- .../GenevaLogExporter.cs | 55 +- .../TLDExporter/TldLogExporter.cs | 550 ++++++++++++++++++ .../Exporter/TLDLogExporterBenchmarks.cs | 189 ++++++ .../GenevaLogExporterTests.cs | 27 +- 4 files changed, 816 insertions(+), 5 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 2f5b6ce3da..1633971d68 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -15,6 +15,8 @@ // using System; +using System.Runtime.InteropServices; +using OpenTelemetry.Exporter.Geneva.TldExporter; using OpenTelemetry.Internal; using OpenTelemetry.Logs; @@ -37,10 +39,55 @@ public GenevaLogExporter(GenevaExporterOptions options) Guard.ThrowIfNull(options); Guard.ThrowIfNullOrWhitespace(options.ConnectionString); - var msgPackExporter = new MsgPackLogExporter(options); - this.IsUsingUnixDomainSocket = msgPackExporter.IsUsingUnixDomainSocket; - this.exportLogRecord = (in Batch batch) => msgPackExporter.Export(in batch); - this.exporter = msgPackExporter; + bool useMsgPackExporter; + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Etw: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); + } + + useMsgPackExporter = true; + break; + + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + useMsgPackExporter = true; + break; + + case TransportProtocol.EtwTld: + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("ETW/TLD cannot be used on non-Windows operating systems."); + } + + useMsgPackExporter = false; + break; + + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } + + if (useMsgPackExporter) + { + var msgPackLogExporter = new MsgPackLogExporter(options); + this.IsUsingUnixDomainSocket = msgPackLogExporter.IsUsingUnixDomainSocket; + this.exportLogRecord = (in Batch batch) => msgPackLogExporter.Export(in batch); + this.exporter = msgPackLogExporter; + } + else + { + var tldLogExporter = new TldLogExporter(options); + this.IsUsingUnixDomainSocket = false; + this.exportLogRecord = (in Batch batch) => tldLogExporter.Export(in batch); + this.exporter = tldLogExporter; + } } public override ExportResult Export(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs new file mode 100644 index 0000000000..d056ef9a54 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -0,0 +1,550 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.Geneva.External; +using OpenTelemetry.Internal; +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.Geneva.TldExporter; + +internal sealed class TldLogExporter : TldExporter, IDisposable +{ + private const int MaxSanitizedEventNameLength = 50; + + // TODO: Is using a single ThreadLocal a better idea? + private static readonly ThreadLocal eventBuilder = new(() => null); + private static readonly ThreadLocal>> envProperties = new(() => null); + private static readonly ThreadLocal[]> partCFields = new(() => null); // This is used to temporarily store the PartC fields from tags + + private static readonly string[] logLevels = new string[7] + { + "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", + }; + + private readonly ThreadLocal serializationData = new(() => null); // This is used for Scopes + + private readonly byte partAFieldsCount = 1; // At least one field: time + private readonly bool shouldPassThruTableMappings; + private readonly string defaultEventName = "Log"; + private readonly IReadOnlyDictionary customFields; + private readonly IReadOnlyDictionary tableMappings; + private readonly Tuple repeatedPartAFields; + private readonly ExceptionStackExportMode exceptionStackExportMode; + + private readonly EventProvider eventProvider; + + private bool isDisposed; + + public TldLogExporter(GenevaExporterOptions options) + { + Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(options.ConnectionString); + + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + this.eventProvider = new EventProvider(connectionStringBuilder.EtwSession); + + this.exceptionStackExportMode = options.ExceptionStackExportMode; + + // TODO: Validate mappings for reserved tablenames etc. + if (options.TableNameMappings != null) + { + var tempTableMappings = new Dictionary(options.TableNameMappings.Count, StringComparer.Ordinal); + foreach (var kv in options.TableNameMappings) + { + if (kv.Key == "*") + { + if (kv.Value == "*") + { + this.shouldPassThruTableMappings = true; + } + else + { + this.defaultEventName = kv.Value; + } + } + else + { + tempTableMappings[kv.Key] = kv.Value; + } + } + + this.tableMappings = tempTableMappings; + } + + // TODO: Validate custom fields (reserved name? etc). + if (options.CustomFields != null) + { + var customFields = new Dictionary(StringComparer.Ordinal); + foreach (var name in options.CustomFields) + { + customFields[name] = true; + } + + this.customFields = customFields; + } + + if (options.PrepopulatedFields != null) + { + var prePopulatedFieldsCount = (byte)(options.PrepopulatedFields.Count - 1); // PrepopulatedFields option has the key ".ver" added to it which is not needed for TLD + this.partAFieldsCount += prePopulatedFieldsCount; + + var eb = eventBuilder.Value; + if (eb == null) + { + eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); + eventBuilder.Value = eb; + } + + eb.Reset("_"); // EventName does not matter here as we only need the serialized key-value pairs + + foreach (var entry in options.PrepopulatedFields) + { + var key = entry.Key; + var value = entry.Value; + + if (entry.Key == Schema.V40.PartA.Ver) + { + continue; + } + + V40_PART_A_TLD_MAPPING.TryGetValue(key, out string replacementKey); + var keyToSerialize = replacementKey ?? key; + Serialize(eb, keyToSerialize, value); + + this.repeatedPartAFields = eb.GetRawFields(); + } + } + } + + public ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + if (this.eventProvider.IsEnabled()) + { + foreach (var activity in batch) + { + try + { + this.SerializeLogRecord(activity); + this.eventProvider.Write(eventBuilder.Value); + } + catch (Exception ex) + { + ExporterEventSource.Log.FailedToSendTraceData(ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } + } + } + else + { + return ExportResult.Failure; + } + + return result; + } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + try + { + // DO NOT Dispose eventBuilder, keyValuePairs, and partCFields as they are static + this.eventProvider?.Dispose(); + this.serializationData?.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("TldLogExporter Dispose failed.", ex); + } + + this.isDisposed = true; + } + + internal void SerializeLogRecord(LogRecord logRecord) + { + IReadOnlyList> listKvp; + if (logRecord.State == null) + { + // When State is null, OTel SDK guarantees StateValues is populated + // TODO: Debug.Assert? + listKvp = logRecord.StateValues; + } + else + { + // Attempt to see if State could be ROL_KVP. + listKvp = logRecord.State as IReadOnlyList>; + } + + // Structured log. + // 2 scenarios. + // 1. Structured logging with template + // eg: + // body + // "Hello from {food} {price}." + // part c + // food = onion + // price = 100 + // TODO: 2. Structured with strongly typed logging. + + string eventName; + var categoryName = logRecord.CategoryName; + + // If user configured explicit TableName, use it. + if (this.tableMappings != null && this.tableMappings.TryGetValue(categoryName, out eventName)) + { + } + else if (!this.shouldPassThruTableMappings) + { + eventName = this.defaultEventName; + } + else + { + // TODO: Avoid allocation + eventName = GetSanitizedCategoryName(categoryName); + } + + var eb = eventBuilder.Value; + if (eb == null) + { + eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); + eventBuilder.Value = eb; + } + + var timestamp = logRecord.Timestamp; + + eb.Reset(eventName); + eb.AddUInt16("__csver__", 1024, EventOutType.Hex); + + var partAFieldsCountPatch = eb.AddStruct("PartA", this.partAFieldsCount); + eb.AddFileTime("time", timestamp); + if (this.repeatedPartAFields != null) + { + eb.AppendRawFields(this.repeatedPartAFields); + } + + byte partAFieldsCount = this.partAFieldsCount; + + // Part A - dt extension + if (logRecord.TraceId != default) + { + eb.AddCountedString("ext_dt_traceId", logRecord.TraceId.ToHexString()); + partAFieldsCount++; + } + + if (logRecord.SpanId != default) + { + eb.AddCountedString("ext_dt_spanId", logRecord.TraceId.ToHexString()); + partAFieldsCount++; + } + + // Part A - ex extension + if (logRecord.Exception != null) + { + eb.AddCountedAnsiString("ext_ex_type", logRecord.Exception.GetType().FullName, Encoding.UTF8); + eb.AddCountedAnsiString("ext_ex_msg", logRecord.Exception.Message, Encoding.UTF8); + + partAFieldsCount += 2; + + if (this.exceptionStackExportMode == ExceptionStackExportMode.ExportAsString) + { + // The current approach relies on the existing trim + // capabilities which trims string in excess of STRING_SIZE_LIMIT_CHAR_COUNT + // TODO: Revisit this: + // 1. Trim it off based on how much more bytes are available + // before running out of limit instead of STRING_SIZE_LIMIT_CHAR_COUNT. + // 2. Trim smarter, by trimming the middle of stack, an + // keep top and bottom. + var exceptionStack = ToInvariantString(logRecord.Exception); + eb.AddCountedAnsiString("ext_ex_stack", exceptionStack, Encoding.UTF8, 0, Math.Min(exceptionStack.Length, StringLengthLimit)); + partAFieldsCount++; + } + } + + eb.SetStructFieldCount(partAFieldsCountPatch, partAFieldsCount); + + // Part B + + byte partBFieldsCount = 4; + var partBFieldsCountPatch = eb.AddStruct("PartB", partBFieldsCount); // We at least have three fields in Part B: _typeName, severityText, severityNumber, name + eb.AddCountedString("_typeName", "Log"); + var logLevel = logRecord.LogLevel; + eb.AddCountedString("severityText", logLevels[(int)logLevel]); + eb.AddUInt8("severityNumber", GetSeverityNumber(logLevel)); + eb.AddCountedAnsiString("name", categoryName, Encoding.UTF8); + + byte hasEnvProperties = 0; + bool bodyPopulated = false; + + byte partCFieldsCountFromState = 0; + var kvpArrayForPartCFields = partCFields.Value; + if (kvpArrayForPartCFields == null) + { + kvpArrayForPartCFields = new KeyValuePair[120]; + partCFields.Value = kvpArrayForPartCFields; + } + + List> envPropertiesList = null; + + for (int i = 0; i < listKvp?.Count; i++) + { + var entry = listKvp[i]; + + // Iteration #1 - Get those fields which become dedicated columns + // i.e all Part B fields and opt-in Part C fields. + if (entry.Key == "{OriginalFormat}") + { + eb.AddCountedAnsiString("body", logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture), Encoding.UTF8); + partBFieldsCount++; + bodyPopulated = true; + continue; + } + else if (this.customFields == null || this.customFields.ContainsKey(entry.Key)) + { + // TODO: the above null check can be optimized and avoided inside foreach. + if (entry.Value != null) + { + // null is not supported. + kvpArrayForPartCFields[partCFieldsCountFromState] = new(entry.Key, entry.Value); + partCFieldsCountFromState++; + } + } + else + { + if (hasEnvProperties == 0) + { + hasEnvProperties = 1; + envPropertiesList = envProperties.Value; + if (envPropertiesList == null) + { + envPropertiesList = new List>(); + envProperties.Value = envPropertiesList; + } + + envPropertiesList.Clear(); + } + + // TODO: This could lead to unbounded memory usage. + envPropertiesList.Add(new(entry.Key, entry.Value)); + } + } + + if (!bodyPopulated && logRecord.FormattedMessage != null) + { + eb.AddCountedAnsiString("body", logRecord.FormattedMessage, Encoding.UTF8); + partBFieldsCount++; + } + + eb.SetStructFieldCount(partBFieldsCountPatch, partBFieldsCount); + + // Part C + + // Prepare state for scopes + var dataForScopes = this.serializationData.Value; + if (dataForScopes == null) + { + dataForScopes = new SerializationDataForScopes(); + this.serializationData.Value = dataForScopes; + } + + dataForScopes.HasEnvProperties = hasEnvProperties; + dataForScopes.PartCFieldsCountFromState = partCFieldsCountFromState; + + logRecord.ForEachScope(ProcessScopeForIndividualColumns, this); + + // Update the variables that could have been modified in ProcessScopeForIndividualColumns + hasEnvProperties = dataForScopes.HasEnvProperties; + partCFieldsCountFromState = dataForScopes.PartCFieldsCountFromState; + + int partCFieldsCount = partCFieldsCountFromState + hasEnvProperties; // We at least have these many fields in Part C + var partCFieldsCountPatch = eb.AddStruct("PartC", (byte)partCFieldsCount); + + for (int i = 0; i < partCFieldsCountFromState; i++) + { + Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); + } + + if (hasEnvProperties == 1) + { + // Get all "other" fields and collapse them into single field + // named "env_properties". + var serializedEnvPropertiesStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(envPropertiesList, out var count); + eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); + } + + var eventId = logRecord.EventId; + if (eventId != default) + { + eb.AddInt32("eventId", eventId.Id); + partCFieldsCount++; + } + + eb.SetStructFieldCount(partCFieldsCountPatch, (byte)partCFieldsCount); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static byte GetSeverityNumber(LogLevel logLevel) + { + // Maps the Ilogger LogLevel to OpenTelemetry logging level. + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#mapping-of-severitynumber + // TODO: for improving perf simply do ((int)loglevel * 4) + 1 + // or ((int)logLevel << 2) + 1 + switch (logLevel) + { + case LogLevel.Trace: + return 1; + case LogLevel.Debug: + return 5; + case LogLevel.Information: + return 9; + case LogLevel.Warning: + return 13; + case LogLevel.Error: + return 17; + case LogLevel.Critical: + return 21; + + // we reach default only for LogLevel.None + // but that is filtered out anyway. + // should we throw here then? + default: + return 1; + } + } + + // This method would map the logger category to a table name which only contains alphanumeric values with the following additions: + // Any character that is not allowed will be removed. + // If the resulting string is longer than 50 characters, only the first 50 characters will be taken. + // If the first character in the resulting string is a lower-case alphabet, it will be converted to the corresponding upper-case. + // If the resulting string still does not comply with Rule, the category name will not be serialized. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string GetSanitizedCategoryName(string categoryName) + { + int validNameLength = 0; + Span result = stackalloc char[MaxSanitizedEventNameLength]; + + // Special treatment for the first character. + var firstChar = categoryName[0]; + if (firstChar >= 'A' && firstChar <= 'Z') + { + result[0] = firstChar; + ++validNameLength; + } + else if (firstChar >= 'a' && firstChar <= 'z') + { + // If the first character in the resulting string is a lower-case alphabet, + // it will be converted to the corresponding upper-case. + result[0] = (char)(firstChar - 32); + ++validNameLength; + } + else + { + // Not a valid name. + return string.Empty; + } + + for (int i = 1; i < categoryName.Length; i++) + { + if (validNameLength == MaxSanitizedEventNameLength) + { + break; + } + + var cur = categoryName[i]; + if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) + { + result[i] = cur; + ++validNameLength; + } + } + + return result.Slice(0, validNameLength).ToString(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + + private static readonly Action ProcessScopeForIndividualColumns = (scope, state) => + { + var stateData = state.serializationData.Value; + var customFields = state.customFields; + var kvpArrayForPartCFields = partCFields.Value; + var envPropertiesList = envProperties.Value; + + foreach (KeyValuePair scopeItem in scope) + { + if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") + { + continue; + } + + if (customFields == null || customFields.ContainsKey(scopeItem.Key)) + { + if (scopeItem.Value != null) + { + kvpArrayForPartCFields[stateData.PartCFieldsCountFromState] = new(scopeItem.Key, scopeItem.Value); + stateData.PartCFieldsCountFromState++; + } + } + else + { + if (stateData.HasEnvProperties == 0) + { + stateData.HasEnvProperties = 1; + if (envPropertiesList == null) + { + envPropertiesList = new List>(); + envProperties.Value = envPropertiesList; + } + + envPropertiesList.Clear(); + } + + // TODO: This could lead to unbounded memory usage. + envPropertiesList.Add(new(scopeItem.Key, scopeItem.Value)); + } + } + }; + + private class SerializationDataForScopes + { + public byte HasEnvProperties; + public byte PartCFieldsCountFromState; + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs new file mode 100644 index 0000000000..0335f60d24 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs @@ -0,0 +1,189 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using BenchmarkDotNet.Attributes; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Logs; +using OpenTelemetry.Trace; + +/* +BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + + +| Method | Mean | Error | StdDev | Allocated | +|--------------------------- |---------:|--------:|--------:|----------:| +| MsgPack_SerializeLogRecord | 560.9 ns | 2.92 ns | 2.44 ns | - | +| TLD_SerializeLogRecord | 357.5 ns | 1.01 ns | 0.89 ns | - | +| MsgPack_ExportLogRecord | 957.2 ns | 3.47 ns | 3.25 ns | - | +| TLD_ExportLogRecord | 732.0 ns | 2.04 ns | 1.71 ns | - | +*/ + +namespace OpenTelemetry.Exporter.Geneva.Benchmark; + +[MemoryDiagnoser] +public class TLDLogExporterBenchmarks +{ + private readonly LogRecord logRecord; + private readonly Batch batch; + private readonly MsgPackLogExporter msgPackExporter; + private readonly TldLogExporter tldExporter; + private readonly ILogger loggerForTLD; + private readonly ILogger loggerForMsgPack; + private readonly ILoggerFactory loggerFactoryForTLD; + private readonly ILoggerFactory loggerFactoryForMsgPack; + + public TLDLogExporterBenchmarks() + { + this.msgPackExporter = new MsgPackLogExporter(new GenevaExporterOptions + { + ConnectionString = "EtwSession=OpenTelemetry", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + this.tldExporter = new TldLogExporter(new GenevaExporterOptions() + { + ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true", + PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); + + this.logRecord = GenerateTestLogRecord(); + this.batch = GenerateTestLogRecordBatch(); + + this.loggerFactoryForTLD = LoggerFactory.Create(builder => + builder.AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddGenevaLogExporter(exporterOptions => + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true"; + exporterOptions.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + })); + + this.loggerForTLD = this.loggerFactoryForTLD.CreateLogger(); + + this.loggerFactoryForMsgPack = LoggerFactory.Create(builder => + builder.AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddGenevaLogExporter(exporterOptions => + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + exporterOptions.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + })); + + this.loggerForMsgPack = this.loggerFactoryForMsgPack.CreateLogger(); + } + + [Benchmark] + public void MsgPack_SerializeLogRecord() + { + this.msgPackExporter.SerializeLogRecord(this.logRecord); + } + + [Benchmark] + public void TLD_SerializeLogRecord() + { + this.tldExporter.SerializeLogRecord(this.logRecord); + } + + [Benchmark] + public void MsgPack_ExportLogRecord() + { + this.msgPackExporter.Export(this.batch); + } + + [Benchmark] + public void TLD_ExportLogRecord() + { + this.tldExporter.Export(this.batch); + } + + [GlobalCleanup] + public void Cleanup() + { + this.batch.Dispose(); + this.loggerFactoryForTLD.Dispose(); + this.loggerFactoryForMsgPack.Dispose(); + this.tldExporter.Dispose(); + this.msgPackExporter.Dispose(); + } + + private static LogRecord GenerateTestLogRecord() + { + var exportedItems = new List(1); + using var factory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddInMemoryExporter(exportedItems); + })); + + var logger = factory.CreateLogger("TestLogger"); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return exportedItems[0]; + } + + private static Batch GenerateTestLogRecordBatch() + { + var items = new List(1); + using var batchGeneratorExporter = new BatchGeneratorExporter(); + using var factory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddProcessor(new SimpleLogRecordExportProcessor(batchGeneratorExporter)); + })); + + var logger = factory.CreateLogger("TestLogger"); + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + return batchGeneratorExporter.Batch; + } + + private class BatchGeneratorExporter : BaseExporter + { + public Batch Batch { get; set; } + + public override ExportResult Export(in Batch batch) + { + this.Batch = batch; + return ExportResult.Success; + } + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index aaae6f5149..8192fe0e0a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -24,7 +24,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; using Xunit; @@ -1083,6 +1082,32 @@ public void SerializationTestForEventId() } } + [Fact] + public void TLDLogExporter_Success_Windows() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(loggerOptions => + { + loggerOptions.AddGenevaLogExporter(exporterOptions => + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true"; + exporterOptions.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + })); + + var logger = loggerFactory.CreateLogger(); + + logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + } + } + private static string GenerateTempFilePath() { while (true) From 6cafab9d594cb428ed3b7359b45b70600a61cf38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Jan 2023 04:44:22 +0100 Subject: [PATCH 0491/1499] Bump OTel to 1.4.0-rc.2 (#880) --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/CHANGELOG.md | 6 ++++-- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 9 +++++++-- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 9 +++++++-- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/build/Common.props b/build/Common.props index e37f3faf47..398c4e9c16 100644 --- a/build/Common.props +++ b/build/Common.props @@ -32,7 +32,7 @@ [3.3.3] [1.1.1,2.0) [1.3.1,2.0) - [1.4.0-rc.1] + [1.4.0-rc.2] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index c0365318b6..cdede6893b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0-rc.2 + ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) + ## 1.4.0-rc.1 Released 2022-Dec-19 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 17e4b61f22..26db82b7e3 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,13 +2,15 @@ ## Unreleased -* Update OpenTelemetry to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) +* Update OpenTelemetry to 1.4.0-rc.2 + ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) ## 1.0.0-beta.3 Released 2022-Nov-09 -* Update OpenTelemetry to 1.4.0-beta.2 ([#680](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/680)) +* Update OpenTelemetry to 1.4.0-beta.2 + ([#680](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/680)) * Implemented auto flush activity processor ([#297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/297)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 59852cfca0..f0f75f487e 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,17 +2,22 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.2 + ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) + ## 1.0.0-alpha.3 Released 2022-Dec-13 -* Update OpenTelemetry API to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) +* Update OpenTelemetry API to 1.4.0-rc.1 + ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) ## 1.0.0-alpha.2 Released 2022-Nov-18 -* Update OpenTelemetry API to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) +* Update OpenTelemetry API to 1.4.0-beta.3 + ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) ## 1.0.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index d54c3fe506..8e7ab0941b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,17 +2,22 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.2 + ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) + ## 1.1.0-beta.2 Released 2022-Dec-13 -* Update OpenTelemetry API to 1.4.0-rc.1 ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) +* Update OpenTelemetry API to 1.4.0-rc.1 + ([#820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/820)) ## 1.1.0-beta.1 Released 2022-Nov-22 -* Update OpenTelemetry API to 1.4.0-beta.3 ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) +* Update OpenTelemetry API to 1.4.0-beta.3 + ([#774](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/774)) * Change ObservableGauge to ObservableUpDownCounter for the below metrics (which better fit UpDownCounter semantics as they are additive.) From 4b8e1d156b3f9eac2d6ebe99749f343889e67ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Jan 2023 21:12:25 +0100 Subject: [PATCH 0492/1499] [Instrumentation.Process, Instrumentation.Runtime] Releases with OTel 1.4.0-rc.2 (#884) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index f0f75f487e..1d5f2ecb89 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.4 + +Released 2023-Jan-11 + * Update OpenTelemetry API to 1.4.0-rc.2 ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 8e7ab0941b..8d7a227152 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.3 + +Released 2023-Jan-11 + * Update OpenTelemetry API to 1.4.0-rc.2 ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) From 358dda82a7a7221d9c3f8603bc71bb9154763939 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Fri, 13 Jan 2023 07:42:26 -0800 Subject: [PATCH 0493/1499] [Extensions.AzureMonitor.ApplicationInsightsSampler] fix unit test (#896) * fix test * update comment * cleanup * comments --- .../ApplicationInsightsSamplerTests.cs | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs index 74caecd2cf..92920b3fca 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs @@ -27,39 +27,41 @@ public class ApplicationInsightsSamplerTests [Fact] public void VerifyHashAlgorithmCorrectness() { - byte[] testBytes = new byte[] + byte[] testBytes1 = new byte[] // hex string: 8fffffffffffffff0000000000000000 { 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, }; - byte[] testBytes2 = new byte[] + byte[] testBytes2 = new byte[] // hex string: 0f1f2f3f4f5f6f7f8f9fafbfcfdfefff { 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF, }; - ActivityTraceId testId = ActivityTraceId.CreateFromBytes(testBytes); + ActivityTraceId testId1 = ActivityTraceId.CreateFromBytes(testBytes1); ActivityTraceId testId2 = ActivityTraceId.CreateFromBytes(testBytes2); - ActivityContext parentContext = default(ActivityContext); - SamplingParameters testParams = new SamplingParameters(parentContext, testId, "TestActivity", ActivityKind.Internal); + ActivityContext parentContext = default; + SamplingParameters testParams1 = new SamplingParameters(parentContext, testId1, "TestActivity", ActivityKind.Internal); SamplingParameters testParams2 = new SamplingParameters(parentContext, testId2, "TestActivity", ActivityKind.Internal); - var zeroSampler = new ApplicationInsightsSampler(0); - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1); - - // 0.86 is below the sample score for testId1, but strict enough to drop testId2 - ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(0.86f); - - Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams).Decision); + // Verify sample ratio: 0 + ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(samplingRatio: 0); + Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams2).Decision); - Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams).Decision); + // Verify sample ratio: 1 + ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(samplingRatio: 1); + Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams2).Decision); - Assert.Equal(SamplingDecision.Drop, ratioSampler.ShouldSample(testParams).Decision); + // Verify sample ratio: 0.5. + // This is below the sample score for testId2, but strict enough to drop testId1 + ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(samplingRatio: 0.5f); + Assert.Equal(SamplingDecision.Drop, ratioSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); } From 0e046be4256a6c57ed394ba9638f835ab280110e Mon Sep 17 00:00:00 2001 From: Igor Kiselev Date: Tue, 17 Jan 2023 08:52:38 -0800 Subject: [PATCH 0494/1499] [Extensions.Docker] Update CHANGELOG for 1.0.0-beta.2 release (#886) --- src/OpenTelemetry.Extensions.Docker/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md index a352c0ca85..bce907b69a 100644 --- a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md @@ -2,7 +2,15 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2023-Jan-11 + * Updates to 1.3.1 of OpenTelemetry SDK. +[712](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/712) + +* Added CGroupv2 support. +[839](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/839) ## 1.0.0-beta.1 From bdf15eff4e0937b2199642902c16cb28b338eb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Jan 2023 21:51:36 +0100 Subject: [PATCH 0495/1499] [Instrumentation.MassTransit] deprecate package + remove code (#788) --- .../comp_instrumentation_masstransit.md | 41 -- .github/component_owners.yml | 4 - .../package-Instrumentation.MassTransit.yml | 53 --- opentelemetry-dotnet-contrib.sln | 15 - .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 14 - .../AssemblyInfo.cs | 22 -- .../CHANGELOG.md | 9 +- .../Implementation/DisplayNameHelper.cs | 47 --- .../MassTransitDiagnosticListener.cs | 185 --------- .../MassTransitInstrumentationEventSource.cs | 51 --- .../MassTransitSemanticConventions.cs | 24 -- .../Implementation/TagName.cs | 39 -- .../MassTransitInstrumentation.cs | 46 --- .../MassTransitInstrumentationOptions.cs | 41 -- ...lemetry.Instrumentation.MassTransit.csproj | 16 - .../OperationName.cs | 55 --- .../README.md | 10 + .../TracerProviderBuilderExtensions.cs | 54 --- .../MassTransitInstrumentationTests.cs | 363 ------------------ ...y.Instrumentation.MassTransit.Tests.csproj | 28 -- .../TestConsumer.cs | 28 -- .../TestMessage.cs | 22 -- 23 files changed, 13 insertions(+), 1154 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md delete mode 100644 .github/workflows/package-Instrumentation.MassTransit.yml delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs delete mode 100644 test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs delete mode 100644 test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj delete mode 100644 test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs delete mode 100644 test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md deleted file mode 100644 index 720b590fb8..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_masstransit.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.MassTransit -about: Issue with OpenTelemetry.Instrumentation.MassTransit -labels: comp:instrumentation.masstransit ---- - -# Issue with OpenTelemetry.Instrumentation.MassTransit - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 02eaec0e73..924a5041d6 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -42,8 +42,6 @@ components: - pcwiese src/OpenTelemetry.Instrumentation.Hangfire/: - fred2u - src/OpenTelemetry.Instrumentation.MassTransit/: - - alexvaluyskiy src/OpenTelemetry.Instrumentation.MySqlData/: - moonheart src/OpenTelemetry.Instrumentation.Owin/: @@ -105,8 +103,6 @@ components: - pcwiese test/OpenTelemetry.Instrumentation.Hangfire.Tests/: - fred2u - test/OpenTelemetry.Instrumentation.MassTransit.Tests/: - - alexvaluyskiy test/OpenTelemetry.Instrumentation.MySqlData.Tests/: - moonheart test/OpenTelemetry.Instrumentation.Owin.Tests/: diff --git a/.github/workflows/package-Instrumentation.MassTransit.yml b/.github/workflows/package-Instrumentation.MassTransit.yml deleted file mode 100644 index 693abbf0db..0000000000 --- a/.github/workflows/package-Instrumentation.MassTransit.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Pack OpenTelemetry.Instrumentation.MassTransit - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'Instrumentation.MassTransit-*' # trigger when we create a tag with prefix "Instrumentation.MassTransit-" - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - env: - PROJECT: OpenTelemetry.Instrumentation.MassTransit - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # fetching all - - - uses: actions/setup-dotnet@v3.0.3 - with: - dotnet-version: '7.0.x' - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index ff592c7b7b..06bde9480e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -53,7 +53,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml - .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml @@ -152,10 +151,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Az EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit", "src\OpenTelemetry.Instrumentation.MassTransit\OpenTelemetry.Instrumentation.MassTransit.csproj", "{D4120D09-93F6-4D5C-98C6-A98B459EA83D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MassTransit.Tests", "test\OpenTelemetry.Instrumentation.MassTransit.Tests\OpenTelemetry.Instrumentation.MassTransit.Tests.csproj", "{4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" @@ -338,14 +333,6 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D4120D09-93F6-4D5C-98C6-A98B459EA83D}.Release|Any CPU.Build.0 = Release|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701}.Release|Any CPU.Build.0 = Release|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -547,8 +534,6 @@ Global {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {D4120D09-93F6-4D5C-98C6-A98B459EA83D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {4F8D7FF0-8D2C-4AD3-A033-2B165E59A701} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 7eb6a114de..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,14 +0,0 @@ -const OpenTelemetry.Instrumentation.MassTransit.OperationName.Consumer.Consume = "MassTransit.Consumer.Consume" -> string -const OpenTelemetry.Instrumentation.MassTransit.OperationName.Consumer.Handle = "MassTransit.Consumer.Handle" -> string -const OpenTelemetry.Instrumentation.MassTransit.OperationName.Transport.Receive = "MassTransit.Transport.Receive" -> string -const OpenTelemetry.Instrumentation.MassTransit.OperationName.Transport.Send = "MassTransit.Transport.Send" -> string -OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions -OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.MassTransitInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet -OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.TracedOperations.set -> void -OpenTelemetry.Instrumentation.MassTransit.OperationName -OpenTelemetry.Instrumentation.MassTransit.OperationName.Consumer -OpenTelemetry.Instrumentation.MassTransit.OperationName.Transport -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMassTransitInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureMassTransitInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder -static readonly OpenTelemetry.Instrumentation.MassTransit.MassTransitInstrumentationOptions.DefaultTracedOperations -> System.Collections.Generic.IEnumerable diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs deleted file mode 100644 index 2c45e8a3e5..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/AssemblyInfo.cs +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MassTransit.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MassTransit.Tests")] -#endif diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md index 5905af4a18..4a55dca400 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md @@ -1,12 +1,9 @@ # Changelog -## Unreleased +## Deprecated -* Update OTel SDK version to `1.3.1`. - ([#637](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/637)) -* Remove .NET Framework 4.6.1. The minimum .NET Framework version supported is - .NET Framework 4.6.2 (by .NET Standard 2.0). - ([#637](https://github.com/open-telemetry/opentelemetry-dotnet/issues/637)) +* This package is deprecated. Please check [README.md](README.md#deprecated) + for more details. ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs deleted file mode 100644 index c8f959d19b..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/DisplayNameHelper.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Concurrent; - -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; - -internal static class DisplayNameHelper -{ - private static readonly ConcurrentDictionary SendOperationDisplayNameCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary ReceiveOperationDisplayNameCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary ConsumeOperationDisplayNameCache = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary HandleOperationDisplayNameCache = new ConcurrentDictionary(); - - public static string GetSendOperationDisplayName(string peerAddress) => - SendOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertSendOperationToDisplayName); - - public static string GetReceiveOperationDisplayName(string peerAddress) => - ReceiveOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertReceiveOperationToDisplayName); - - public static string GetConsumeOperationDisplayName(string peerAddress) => - ConsumeOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertConsumeOperationToDisplayName); - - public static string GetHandleOperationDisplayName(string peerAddress) => - HandleOperationDisplayNameCache.GetOrAdd(peerAddress, ConvertHandleOperationToDisplayName); - - private static string ConvertSendOperationToDisplayName(string peerAddress) => $"{peerAddress} send"; - - private static string ConvertReceiveOperationToDisplayName(string peerAddress) => $"{peerAddress} consume"; - - private static string ConvertConsumeOperationToDisplayName(string consumerType) => $"{consumerType} process"; - - private static string ConvertHandleOperationToDisplayName(string peerAddress) => $"{peerAddress} process"; -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs deleted file mode 100644 index 0529db9631..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitDiagnosticListener.cs +++ /dev/null @@ -1,185 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; - -internal class MassTransitDiagnosticListener : ListenerHandler -{ - internal static readonly AssemblyName AssemblyName = typeof(MassTransitDiagnosticListener).Assembly.GetName(); - internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); - - private readonly MassTransitInstrumentationOptions options; - - public MassTransitDiagnosticListener(string name, MassTransitInstrumentationOptions options) - : base(name) - { - this.options = options; - } - - public override void OnStartActivity(Activity activity, object payload) - { - // By this time, samplers have already run and - // activity.IsAllDataRequested populated accordingly. - - if (Sdk.SuppressInstrumentation) - { - return; - } - - if (activity.IsAllDataRequested) - { - if (this.options.TracedOperations != null && !this.options.TracedOperations.Contains(activity.OperationName)) - { - MassTransitInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); - activity.IsAllDataRequested = false; - return; - } - - activity.DisplayName = this.GetDisplayName(activity); - - ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); - ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); - } - } - - public override void OnStopActivity(Activity activity, object payload) - { - if (activity.IsAllDataRequested) - { - try - { - this.TransformMassTransitTags(activity); - } - catch (Exception ex) - { - MassTransitInstrumentationEventSource.Log.EnrichmentException(ex); - } - } - } - - private string GetDisplayName(Activity activity) - { - return activity.OperationName switch - { - OperationName.Transport.Send => DisplayNameHelper.GetSendOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), - OperationName.Transport.Receive => DisplayNameHelper.GetReceiveOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), - OperationName.Consumer.Consume => DisplayNameHelper.GetConsumeOperationDisplayName(this.GetTag(activity.Tags, TagName.ConsumerType)), - OperationName.Consumer.Handle => DisplayNameHelper.GetHandleOperationDisplayName(this.GetTag(activity.Tags, TagName.PeerAddress)), - _ => activity.DisplayName, - }; - } - - private ActivityKind GetActivityKind(Activity activity) - { - return activity.OperationName switch - { - OperationName.Transport.Send => ActivityKind.Producer, - OperationName.Transport.Receive => ActivityKind.Consumer, - OperationName.Consumer.Consume => ActivityKind.Internal, - OperationName.Consumer.Handle => ActivityKind.Internal, - _ => activity.Kind, - }; - } - - private void TransformMassTransitTags(Activity activity) - { - if (activity.OperationName == OperationName.Transport.Send) - { - this.ProcessHostInfo(activity); - - this.RenameTag(activity, TagName.MessageId, SemanticConventions.AttributeMessagingMessageId); - this.RenameTag(activity, TagName.ConversationId, SemanticConventions.AttributeMessagingConversationId); - this.RenameTag(activity, TagName.InitiatorId, MassTransitSemanticConventions.AttributeMessagingMassTransitInitiatorId); - this.RenameTag(activity, TagName.CorrelationId, MassTransitSemanticConventions.AttributeMessagingMassTransitCorrelationId); - - activity.SetTag(TagName.SourceAddress, null); - } - else if (activity.OperationName == OperationName.Transport.Receive) - { - this.ProcessHostInfo(activity); - - this.RenameTag(activity, TagName.MessageId, SemanticConventions.AttributeMessagingMessageId); - this.RenameTag(activity, TagName.ConversationId, SemanticConventions.AttributeMessagingConversationId); - this.RenameTag(activity, TagName.InitiatorId, MassTransitSemanticConventions.AttributeMessagingMassTransitInitiatorId); - this.RenameTag(activity, TagName.CorrelationId, MassTransitSemanticConventions.AttributeMessagingMassTransitCorrelationId); - - activity.SetTag(TagName.MessageId, null); - - activity.SetTag(TagName.MessageTypes, null); - activity.SetTag(TagName.SourceAddress, null); - activity.SetTag(TagName.SourceHostMachine, null); - } - else if (activity.OperationName == OperationName.Consumer.Consume) - { - this.RenameTag(activity, TagName.ConsumerType, MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType); - } - else if (activity.OperationName == OperationName.Consumer.Handle) - { - } - - activity.SetTag(TagName.SpanKind, null); - activity.SetTag(TagName.PeerService, null); - activity.SetTag(TagName.PeerAddress, null); - activity.SetTag(TagName.PeerHost, null); - } - - private void ProcessHostInfo(Activity activity) - { - if (Uri.TryCreate(activity.GetTagValue(TagName.DestinationAddress).ToString(), UriKind.Absolute, out var destinationAddress)) - { - activity.SetTag(SemanticConventions.AttributeMessagingSystem, destinationAddress.Scheme); - activity.SetTag(SemanticConventions.AttributeMessagingDestination, destinationAddress.LocalPath); - - var uriHostNameType = Uri.CheckHostName(destinationAddress.Host); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - activity.SetTag(SemanticConventions.AttributeNetPeerIp, destinationAddress.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeNetPeerName, destinationAddress.Host); - } - - if (destinationAddress.Port > 0) - { - activity.SetTag(SemanticConventions.AttributeNetPeerPort, destinationAddress.Port); - } - - activity.SetTag(TagName.DestinationAddress, null); - } - } - - private string GetTag(IEnumerable> tags, string tagName) - { - var tag = tags.SingleOrDefault(kv => kv.Key == tagName); - return tag.Value; - } - - private void RenameTag(Activity activity, string oldTagName, string newTagName) - { - activity.SetTag(newTagName, activity.GetTagValue(oldTagName)); - activity.SetTag(oldTagName, null); - } -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs deleted file mode 100644 index 650b30d612..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitInstrumentationEventSource.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Diagnostics.Tracing; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; - -/// -/// EventSource events emitted from the project. -/// -[EventSource(Name = "OpenTelemetry-Instrumentation-MassTransit")] -internal class MassTransitInstrumentationEventSource : EventSource -{ - public static MassTransitInstrumentationEventSource Log = new MassTransitInstrumentationEventSource(); - - [Event(1, Message = "Request is filtered out.", Level = EventLevel.Verbose)] - public void RequestIsFilteredOut(string eventName) - { - this.WriteEvent(1, eventName); - } - - [NonEvent] - public void EnrichmentException(Exception ex) - { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.EnrichmentException(ex.ToInvariantString()); - } - } - - [Event(2, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] - public void EnrichmentException(string exception) - { - this.WriteEvent(2, exception); - } -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs deleted file mode 100644 index b943bb077f..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/MassTransitSemanticConventions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; - -internal class MassTransitSemanticConventions -{ - public const string AttributeMessagingMassTransitInitiatorId = "messaging.masstransit.initiator_id"; - public const string AttributeMessagingMassTransitCorrelationId = "messaging.masstransit.correlation_id"; - public const string AttributeMessagingMassTransitConsumerType = "messaging.masstransit.consumer_type"; -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs deleted file mode 100644 index 63d28c63e3..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/Implementation/TagName.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Instrumentation.MassTransit.Implementation; - -internal class TagName -{ - public const string SpanKind = "span.kind"; - - public const string PeerAddress = "peer.address"; - public const string PeerHost = "peer.host"; - public const string PeerService = "peer.service"; - public const string SourceHostMachine = "source-host-machine"; - - public const string MessageId = "message-id"; - public const string ConversationId = "conversation-id"; - public const string CorrelationId = "correlation-id"; - public const string InitiatorId = "initiator-id"; - - public const string ConsumerType = "consumer-type"; - public const string MessageTypes = "message-types"; - - public const string DestinationAddress = "destination-address"; - public const string SourceAddress = "source-address"; - public const string InputAddress = "input-address"; -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs deleted file mode 100644 index 5d674d51fd..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentation.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using OpenTelemetry.Instrumentation.MassTransit.Implementation; - -namespace OpenTelemetry.Instrumentation.MassTransit; - -internal class MassTransitInstrumentation : IDisposable -{ - internal const string MassTransitDiagnosticListenerName = "MassTransit"; - - private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - - /// - /// Initializes a new instance of the class. - /// - /// Instrumentation options. - public MassTransitInstrumentation(MassTransitInstrumentationOptions options) - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( - name => new MassTransitDiagnosticListener(name, options), - listener => listener.Name == MassTransitDiagnosticListenerName, - null); - this.diagnosticSourceSubscriber.Subscribe(); - } - - /// - public void Dispose() - { - this.diagnosticSourceSubscriber?.Dispose(); - } -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs deleted file mode 100644 index bf98c06d8a..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/MassTransitInstrumentationOptions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; - -namespace OpenTelemetry.Instrumentation.MassTransit; - -/// -/// Options for . -/// -public class MassTransitInstrumentationOptions -{ - /// - /// Default traced operations. - /// - public static readonly IEnumerable DefaultTracedOperations = new string[] - { - OperationName.Transport.Send, - OperationName.Transport.Receive, - OperationName.Consumer.Consume, - OperationName.Consumer.Handle, - }; - - /// - /// Gets or sets traced operations set. - /// - public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj b/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj deleted file mode 100644 index 6c93d09294..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OpenTelemetry.Instrumentation.MassTransit.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - netstandard2.0 - OpenTelemetry instrumentation for MassTransit - $(PackageTags);distributed-tracing;MassTransit - Instrumentation.MassTransit- - true - - - - - - - - - diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs b/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs deleted file mode 100644 index 92081d0696..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Instrumentation.MassTransit; - -/// -/// MassTransit diagnostic source operation name constants. -/// -public static class OperationName -{ - /// - /// MassTransit Transport category constants. - /// - public static class Transport - { - /// - /// MassTransit send diagnostic source operation name. - /// - public const string Send = "MassTransit.Transport.Send"; - - /// - /// MassTransit receive diagnostic source operation name. - /// - public const string Receive = "MassTransit.Transport.Receive"; - } - - /// - /// MassTransit Consumer category constants. - /// - public static class Consumer - { - /// - /// MassTransit consume diagnostic source operation name. - /// - public const string Consume = "MassTransit.Consumer.Consume"; - - /// - /// MassTransit handle diagnostic source operation name. - /// - public const string Handle = "MassTransit.Consumer.Handle"; - } -} diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md index cacb56f8a1..06300e2d1d 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -7,6 +7,16 @@ Automatically instruments [DiagnosticSource](https://masstransit-project.com/advanced/monitoring/diagnostic-source.html) events emitted by [MassTransit](https://masstransit-project.com/) library. +## Deprecated + +> **NOTE that this only works with MassTransit v7 (and earlier, where supported)**. +> MassTransit v8.0.0 and later have built-in direct support for Open Telemetry +> via `ActivitySource`. + +To instrument MassTransit v8.0.0+ you need to configure the OpenTelemetry SDK +to listen to the `ActivitySource` used by the library by calling +`AddSource("MassTransit")` on the `TracerProviderBuilder`. + ## Installation ```shell diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs deleted file mode 100644 index bc808da460..0000000000 --- a/src/OpenTelemetry.Instrumentation.MassTransit/TracerProviderBuilderExtensions.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using OpenTelemetry.Instrumentation.MassTransit; -using OpenTelemetry.Instrumentation.MassTransit.Implementation; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Trace; - -/// -/// Extension methods to simplify registering of dependency instrumentation. -/// -public static class TracerProviderBuilderExtensions -{ - /// - /// Enables the outgoing requests automatic data collection for MassTransit. - /// - /// being configured. - /// MassTransit configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddMassTransitInstrumentation( - this TracerProviderBuilder builder, - Action configureMassTransitInstrumentationOptions = null) - { - Guard.ThrowIfNull(builder); - - var options = new MassTransitInstrumentationOptions(); - configureMassTransitInstrumentationOptions?.Invoke(options); - - builder.AddInstrumentation(() => new MassTransitInstrumentation(options)); - builder.AddSource(MassTransitDiagnosticListener.ActivitySourceName); - - builder.AddLegacySource(OperationName.Consumer.Consume); - builder.AddLegacySource(OperationName.Consumer.Handle); - builder.AddLegacySource(OperationName.Transport.Send); - builder.AddLegacySource(OperationName.Transport.Receive); - - return builder; - } -} diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs deleted file mode 100644 index 542f643697..0000000000 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/MassTransitInstrumentationTests.cs +++ /dev/null @@ -1,363 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; -using MassTransit.Testing; -using Moq; -using OpenTelemetry.Instrumentation.MassTransit.Implementation; -using OpenTelemetry.Tests; -using OpenTelemetry.Trace; -using Xunit; - -namespace OpenTelemetry.Instrumentation.MassTransit.Tests; - -public class MassTransitInstrumentationTests -{ - [Fact] - public async Task ShouldMapMassTransitTagsForPublishMessageToOpenTelemetrySpecification() - { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Transport.Send).LastOrDefault(); - - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); - - Assert.Equal("/input_queue send", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Producer, actualActivity.Kind); - Assert.Equal("loopback", actualActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)?.ToString()); - - Assert.Equal(expectedMessageContext.MessageId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingMessageId)?.ToString()); - Assert.Equal(expectedMessageContext.ConversationId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingConversationId)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.AbsolutePath, actualActivity.GetTagValue(SemanticConventions.AttributeMessagingDestination)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.Host, actualActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)?.ToString()); - - Assert.Null(actualActivity.GetTagValue(TagName.MessageId)); - Assert.Null(actualActivity.GetTagValue(TagName.ConversationId)); - Assert.Null(actualActivity.GetTagValue(TagName.DestinationAddress)); - - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - Assert.Null(actualActivity.GetTagValue(TagName.SourceAddress)); - } - } - - [Fact] - public async Task ShouldMapMassTransitTagsForReceiveMessageToOpenTelemetrySpecification() - { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Transport.Receive).LastOrDefault(); - - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); - - Assert.Equal("/input_queue consume", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Consumer, actualActivity.Kind); - Assert.Equal("loopback", actualActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)?.ToString()); - - Assert.Equal(expectedMessageContext.MessageId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingMessageId)?.ToString()); - Assert.Equal(expectedMessageContext.ConversationId.ToString(), actualActivity.GetTagValue(SemanticConventions.AttributeMessagingConversationId)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.AbsolutePath, actualActivity.GetTagValue(SemanticConventions.AttributeMessagingDestination)?.ToString()); - Assert.Equal(expectedMessageContext.DestinationAddress.Host, actualActivity.GetTagValue(SemanticConventions.AttributeNetPeerName)?.ToString()); - - Assert.Null(actualActivity.GetTagValue(TagName.MessageId)); - Assert.Null(actualActivity.GetTagValue(TagName.ConversationId)); - Assert.Null(actualActivity.GetTagValue(TagName.DestinationAddress)); - - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - Assert.Null(actualActivity.GetTagValue(TagName.MessageTypes)); - Assert.Null(actualActivity.GetTagValue(TagName.SourceAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.SourceHostMachine)); - } - } - - [Fact] - public async Task ShouldMapMassTransitTagsForConsumeMessageToOpenTelemetrySpecification() - { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Consumer.Consume).LastOrDefault(); - - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); - Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer process", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Internal, actualActivity.Kind); - Assert.Equal("OpenTelemetry.Instrumentation.MassTransit.Tests.TestConsumer", actualActivity.GetTagValue(MassTransitSemanticConventions.AttributeMessagingMassTransitConsumerType)?.ToString()); - - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - } - } - - [Fact] - public async Task ShouldMapMassTransitTagsForHandleMessageToOpenTelemetrySpecification() - { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - var actualActivity = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, OperationName.Consumer.Handle).LastOrDefault(); - - Assert.NotNull(actualActivity); - Assert.NotNull(expectedMessageContext); - Assert.Equal("TestMessage/OpenTelemetry.Instrumentation.MassTransit.Tests process", actualActivity.DisplayName); - Assert.Equal(ActivityKind.Internal, actualActivity.Kind); - - Assert.Null(actualActivity.GetTagValue(TagName.SpanKind)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerService)); - - Assert.Null(actualActivity.GetTagValue(TagName.PeerAddress)); - Assert.Null(actualActivity.GetTagValue(TagName.PeerHost)); - } - } - - [Theory] - [InlineData(OperationName.Consumer.Consume)] - [InlineData(OperationName.Consumer.Handle)] - [InlineData(OperationName.Transport.Send)] - [InlineData(OperationName.Transport.Receive)] - public async Task MassTransitInstrumentationTestOptions(string operationName) - { - using Activity activity = new Activity("Parent"); - activity.SetParentId( - ActivityTraceId.CreateRandom(), - ActivitySpanId.CreateRandom(), - ActivityTraceFlags.Recorded); - activity.Start(); - - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation(o => - o.TracedOperations = new HashSet(new[] { operationName })) - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new - { - Text = "Hello, world!", - }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - } - - Assert.Equal(8, activityProcessor.Invocations.Count); - - var consumes = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, operationName); - - Assert.Single(consumes); - } - - [Fact] - public async Task ShouldMapMassTransitTagsWhenInstrumentationIsSuppressed() - { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - using var scope = SuppressInstrumentationScope.Begin(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - Assert.NotNull(expectedMessageContext); - } - - // Since instrumentation is suppressed, activity is not emitted - Assert.Equal(3, activityProcessor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose - - // Processor.OnStart and Processor.OnEnd are not called - Assert.DoesNotContain(activityProcessor.Invocations, invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnStart)); - Assert.DoesNotContain(activityProcessor.Invocations, invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnEnd)); - } - - [Theory] - [InlineData(SamplingDecision.Drop, false)] - [InlineData(SamplingDecision.RecordOnly, true)] - [InlineData(SamplingDecision.RecordAndSample, true)] - public async Task ShouldMapMassTransitTagsWhenInstrumentationWhenSampled(SamplingDecision samplingDecision, bool isActivityExpected) - { - var activityProcessor = new Mock>(); - using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) - .AddProcessor(activityProcessor.Object) - .AddMassTransitInstrumentation() - .Build()) - { - var harness = new InMemoryTestHarness(); - var consumerHarness = harness.Consumer(); - var handlerHarness = harness.Handler(); - await harness.Start(); - try - { - await harness.InputQueueSendEndpoint.Send(new { Text = "Hello, world!" }); - - Assert.True(await harness.Consumed.SelectAsync().Any()); - Assert.True(await consumerHarness.Consumed.SelectAsync().Any()); - Assert.True(await handlerHarness.Consumed.SelectAsync().Any()); - } - finally - { - await harness.Stop(); - } - - var expectedMessageContext = harness.Sent.Select().FirstOrDefault()?.Context; - Assert.NotNull(expectedMessageContext); - } - - Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnStart))); - Assert.Equal(isActivityExpected, activityProcessor.Invocations.Any(invocation => invocation.Method.Name == nameof(activityProcessor.Object.OnEnd))); - } - - private IEnumerable GetActivitiesFromInvocationsByOperationName(IEnumerable invocations, string operationName) - { - return - invocations - .Where(i => - i.Arguments.OfType() - .Any(a => a.OperationName == operationName)) - .Where(i => i.Method.Name == "OnEnd") - .Select(i => i.Arguments.OfType().Single()); - } -} diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj deleted file mode 100644 index 5193861942..0000000000 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/OpenTelemetry.Instrumentation.MassTransit.Tests.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - Unit test project for OpenTelemetry MassTransit instrumentation - - net7.0;net6.0;netcoreapp3.1 - $(TargetFrameworks);net462 - true - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs deleted file mode 100644 index 9b6d834054..0000000000 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestConsumer.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Threading.Tasks; -using MassTransit; - -namespace OpenTelemetry.Instrumentation.MassTransit.Tests; - -public class TestConsumer : IConsumer -{ - public Task Consume(ConsumeContext context) - { - return Task.CompletedTask; - } -} diff --git a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs b/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs deleted file mode 100644 index 5c29747ed6..0000000000 --- a/test/OpenTelemetry.Instrumentation.MassTransit.Tests/TestMessage.cs +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Instrumentation.MassTransit.Tests; - -public class TestMessage -{ - public string Text; -} From 363552f54d9a6faeb0bac41d4f54c98c0016035e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Jan 2023 22:30:03 +0100 Subject: [PATCH 0496/1499] Drop test exporter (#887) Co-authored-by: Cijo Thomas --- build/Common.props | 1 - .../TestExporter.cs | 37 ------------------- 2 files changed, 38 deletions(-) delete mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs diff --git a/build/Common.props b/build/Common.props index 398c4e9c16..63ff182803 100644 --- a/build/Common.props +++ b/build/Common.props @@ -66,7 +66,6 @@ - diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs deleted file mode 100644 index 3f48da917e..0000000000 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestExporter.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; - -namespace OpenTelemetry.Tests; - -internal class TestExporter : BaseExporter - where T : class -{ - private readonly Action> processBatchAction; - - public TestExporter(Action> processBatchAction) - { - this.processBatchAction = processBatchAction ?? throw new ArgumentNullException(nameof(processBatchAction)); - } - - public override ExportResult Export(in Batch batch) - { - this.processBatchAction(batch); - - return ExportResult.Success; - } -} From 35f01e3a9a5d244f8b0f886ce4c2dca9b4560750 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 17 Jan 2023 13:32:06 -0800 Subject: [PATCH 0497/1499] [Exporter.Geneva] Add the missing changelog entry (#879) Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index cdede6893b..8f9becdb8d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -36,6 +36,13 @@ Released 2022-Dec-09 Add support for serializing `ISpanFormattable` types. ([#803](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/803)) +## 1.3.1 + +Released 2022-Dec-07 + +* Fix the overflow bucket value serialization for Histogram. + ([#807](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/807)) + ## 1.4.0-beta.5 Released 2022-Nov-21 From 6e38cfd19e63bc75dff32879469fe35fa40090eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Jan 2023 22:58:18 +0100 Subject: [PATCH 0498/1499] AzureMonitor.Tests - fix code coverage execution (#890) * AzureMonitor.Tests - fix code coverage execution * Skip failing test * Revert skip test - fixed in #896 Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 24e2365463..680709dc8f 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -6,12 +6,14 @@ - - - - + + + all + runtime; build; native; contentfiles; analyzers + + From 7d62f100c8d7a86204a18e25cf5401da119da5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 18 Jan 2023 00:51:54 +0100 Subject: [PATCH 0499/1499] [Instrumentation.Quartz] Update OTel + cleanup (#889) --- src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 3 +++ .../Implementation/QuartzDiagnosticListener.cs | 4 ++-- .../Implementation/QuartzInstrumentationEventSource.cs | 2 +- .../Implementation/TagName.cs | 8 -------- .../OpenTelemetry.Instrumentation.Quartz.csproj | 2 +- .../QuartzInstrumentationOptions.cs | 2 +- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 2 +- .../QuartzDiagnosticListenerTests.cs | 7 +++---- 8 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index e92e8f7d5c..4cb5dc75ba 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry.Api to 1.3.1. + ([#889](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/889)) + ## 1.0.0-alpha.1 * This is the first release of `OpenTelemetry.Instrumentation.Quartz` package. diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index bb4bc853df..9208c22bad 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -29,8 +29,8 @@ internal sealed class QuartzDiagnosticListener : ListenerHandler internal static readonly AssemblyName AssemblyName = typeof(QuartzDiagnosticListener).Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); - internal readonly PropertyFetcher JobDetailsPropertyFetcher = new PropertyFetcher("JobDetail"); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal readonly PropertyFetcher JobDetailsPropertyFetcher = new("JobDetail"); private readonly QuartzInstrumentationOptions options; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs index b3cc2ce6de..a0e0d26293 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -26,7 +26,7 @@ namespace OpenTelemetry.Instrumentation.Quartz.Implementation; [EventSource(Name = "OpenTelemetry-Instrumentation-Quartz")] internal class QuartzInstrumentationEventSource : EventSource { - public static readonly QuartzInstrumentationEventSource Log = new QuartzInstrumentationEventSource(); + public static readonly QuartzInstrumentationEventSource Log = new(); [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] public void NullPayload(string handlerName, string eventName) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs index f42440a46d..9adff0e9be 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs @@ -18,13 +18,5 @@ namespace OpenTelemetry.Instrumentation.Quartz.Implementation; internal static class TagName { - public const string DefaultListenerName = "Quartz"; - public const string SchedulerName = "scheduler.name"; - public const string SchedulerId = "scheduler.id"; - public const string FireInstanceId = "fire.instance.id"; - public const string TriggerGroup = "trigger.group"; - public const string TriggerName = "trigger.name"; - public const string JobType = "job.type"; - public const string JobGroup = "job.group"; public const string JobName = "job.name"; } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index b107cf3d4d..220b573743 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -9,7 +9,7 @@ OpenTelemetry.Instrumentation.Quartz - + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index 9f10410c0b..ac9572ef54 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -56,5 +56,5 @@ public class QuartzInstrumentationOptions /// /// Gets or sets traced operations set. /// - public HashSet TracedOperations { get; set; } = new HashSet(DefaultTracedOperations); + public HashSet TracedOperations { get; set; } = new(DefaultTracedOperations); } diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 41ebffb234..09e33684bd 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 56fd496a51..b5f98b7d07 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -98,11 +98,10 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() var activityProcessor = new Mock>(); - var jobDataMapPropertyFetcher = new PropertyFetcher("JobDataMap"); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) .AddQuartzInstrumentation(q => - q.Enrich = (a, s, payload) => + q.Enrich = (a, _, payload) => { if (payload is IJobDetail jobDetail) { @@ -225,7 +224,7 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri .AddQuartzInstrumentation(q => { q.RecordException = true; - q.Enrich = (a, s, p) => + q.Enrich = (a, _, p) => { if (p is IJobDetail jobDetail) { @@ -291,7 +290,7 @@ public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() .AddQuartzInstrumentation(q => { q.RecordException = true; - q.Enrich = (a, s, p) => + q.Enrich = (_, s, _) => { if (s.Equals("OnException")) { From 49bcb44b72e6a5d9002a4b0170cbb98c12d16e59 Mon Sep 17 00:00:00 2001 From: moonheart Date: Thu, 19 Jan 2023 04:19:32 +0800 Subject: [PATCH 0500/1499] [Instrumentation.MysqlData] Compatibility with Mysql.Data 8.0.32. (#902) --- .../CHANGELOG.md | 3 ++ .../MySqlDataInstrumentation.cs | 53 ++++++++++++++++--- .../MySqlDataInstrumentationEventSource.cs | 6 +++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 881231b6f7..f3db83449d 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Compatibility with Mysql.Data 8.0.32 or later. + ([#901](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/901)) + ## 1.0.0-beta.4 Released 2022-Oct-17 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index be4a296afe..1cc31f9012 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Concurrent; using System.Diagnostics; +using System.Linq.Expressions; using System.Reflection; using MySql.Data.MySqlClient; using OpenTelemetry.Trace; @@ -28,10 +29,12 @@ namespace OpenTelemetry.Instrumentation.MySqlData; /// internal class MySqlDataInstrumentation : DefaultTraceListener { - private readonly ConcurrentDictionary dbConn = new ConcurrentDictionary(); + private readonly ConcurrentDictionary dbConn = new(); private readonly MySqlDataInstrumentationOptions options; + private readonly Func builderFactory; + public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null) { this.options = options ?? new MySqlDataInstrumentationOptions(); @@ -40,15 +43,49 @@ public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null) MySqlTrace.Switch.Level = SourceLevels.Information; // Mysql.Data removed `MySql.Data.MySqlClient.MySqlTrace.QueryAnalysisEnabled` since 8.0.31 so we need to set this using reflection. - var queryAnalysisEnabled = typeof(MySqlTrace).GetProperty("QueryAnalysisEnabled", BindingFlags.Public | BindingFlags.Static); + var queryAnalysisEnabled = + typeof(MySqlTrace).GetProperty("QueryAnalysisEnabled", BindingFlags.Public | BindingFlags.Static); if (queryAnalysisEnabled != null) { queryAnalysisEnabled.SetValue(null, true); } + + // Mysql.Data add optional param `isAnalyzed` to MySqlConnectionStringBuilder constructor since 8.0.32 + var ctor = typeof(MySqlConnectionStringBuilder).GetConstructor(new[] { typeof(string), typeof(bool) }); + if (ctor == null) + { + ctor = typeof(MySqlConnectionStringBuilder).GetConstructor(new[] { typeof(string) }); + if (ctor == null) + { + MySqlDataInstrumentationEventSource.Log.ErrorInitialize( + "Failed to get proper MySqlConnectionStringBuilder constructor, maybe unsupported Mysql.Data version. Connection Level Details will not be available.", + string.Empty); + return; + } + + var p1 = Expression.Parameter(typeof(string), "connectionString"); + var newExpression = Expression.New(ctor, p1); + var func = Expression.Lambda>(newExpression, p1).Compile(); + this.builderFactory = s => func(s); + } + else + { + var p1 = Expression.Parameter(typeof(string)); + var p2 = Expression.Parameter(typeof(bool)); + var newExpression = Expression.New(ctor, p1, p2); + var func = Expression.Lambda>(newExpression, p1, p2).Compile(); + this.builderFactory = s => func(s, false); + } } /// - public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object[] args) + public override void TraceEvent( + TraceEventCache eventCache, + string source, + TraceEventType eventType, + int id, + string format, + params object[] args) { try { @@ -56,9 +93,13 @@ public override void TraceEvent(TraceEventCache eventCache, string source, Trace { case MySqlTraceEventType.ConnectionOpened: // args: [driverId, connStr, threadId] - var driverId = (long)args[0]; - var connStr = args[1].ToString(); - this.dbConn[driverId] = new MySqlConnectionStringBuilder(connStr); + if (this.builderFactory != null) + { + var driverId = (long)args[0]; + var connStr = args[1].ToString(); + this.dbConn[driverId] = this.builderFactory(connStr); + } + break; case MySqlTraceEventType.ConnectionClosed: break; diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs index 99436a67d8..573e486199 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs @@ -37,4 +37,10 @@ public void ErrorTraceEvent(int mysqlEventId, string message, string exception) { this.WriteEvent(1, mysqlEventId, message, exception); } + + [Event(2, Message = "Error accured while initializing MySqlDataInstrumentation, Message {0}, Exception: {1}", Level = EventLevel.Warning)] + public void ErrorInitialize(string message, string exception) + { + this.WriteEvent(1, message, exception); + } } From b53b6b96d72e53c5c47d3bb7f8a2dd27469a8120 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 18 Jan 2023 20:33:23 +0000 Subject: [PATCH 0501/1499] Use Array.Empty (#900) --- .../Implementation/AWSLambdaUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 75d0ba2a63..bda6d7677b 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -44,7 +44,7 @@ internal static class AWSLambdaUtils return new[] { value }; } - return new string[0]; + return Array.Empty(); }; internal static ActivityContext GetXRayParentContext() From 6e900056f07874ea5cf883b725bb673f23b17a90 Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Wed, 18 Jan 2023 13:40:37 -0800 Subject: [PATCH 0502/1499] Disabling `EventSourceNameShortening` unit test (#905) It was failing. frequently. --- .../EventCountersMetricsTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 39816f8389..a8a5c5f528 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -214,6 +214,7 @@ public void ThrowExceptionForUnsupportedEventSources() Assert.Equal("Use the `OpenTelemetry.Instrumentation.Runtime` or `OpenTelemetry.Instrumentation.Process` instrumentations.", ex.Message); } + /* [Theory] [InlineData("Microsoft-AspNetCore-Server-Kestrel-1", "tls-handshakes-per-second", "ec.Microsoft-AspNetCore-Server-Kestre.tls-handshakes-per-second")] [InlineData("Microsoft-AspNetCore-Server-Kestrel-1", "tls-handshakes-per-sec", "ec.Microsoft-AspNetCore-Server-Kestrel-1.tls-handshakes-per-sec")] @@ -248,6 +249,7 @@ public void EventSourceNameShortening(string sourceName, string eventName, strin Assert.NotNull(metric); Assert.Equal(1, GetActualValue(metric)); } + */ [Fact] public void InstrumentNameTooLong() From f11a63f535f897974aa97d8729d471e011c21a1b Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Thu, 19 Jan 2023 16:04:46 +0000 Subject: [PATCH 0503/1499] Do not assign in drafts (#909) Do not assign people to draft PRs. --- .github/workflows/assign-reviewers.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/assign-reviewers.yml b/.github/workflows/assign-reviewers.yml index a5110c7031..1cf146e060 100644 --- a/.github/workflows/assign-reviewers.yml +++ b/.github/workflows/assign-reviewers.yml @@ -11,3 +11,5 @@ jobs: name: Assign Reviewers steps: - uses: dyladan/component-owners@main + with: + assign-owners: ${{ github.event.pull_request.draft == false }} From 01a4e966f6e536af029ebf6698e287939842b12a Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Thu, 19 Jan 2023 08:23:32 -0800 Subject: [PATCH 0504/1499] Single Theory+MemberData JsonSerializer.Tests (#904) Co-authored-by: Cijo Thomas --- .../JsonSerializerTests.cs | 110 ++++++------------ 1 file changed, 36 insertions(+), 74 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs index 2b1e4c11ef..0d0846a5d7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Collections.Generic; using System.Text; using OpenTelemetry.Exporter.Geneva.TldExporter; @@ -23,82 +24,43 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; public class JsonSerializerTests { - private static void TestSerialization(object value, string expected) - { - var buffer = new byte[64 * 1024]; - var length = JsonSerializer.Serialize(buffer, 0, value); - Assert.Equal(expected, Encoding.ASCII.GetString(buffer, 0, length)); - } - - [Fact] - [Trait("Platform", "Any")] - public void JsonSerializer_Null() - { - TestSerialization(null, "null"); - } - - [Fact] - [Trait("Platform", "Any")] - public void JsonSerializer_Boolean() - { - TestSerialization(true, "true"); - TestSerialization(false, "false"); - } - - [Fact] - [Trait("Platform", "Any")] - public void JsonSerializer_Numeric() - { - TestSerialization(0, "0"); - TestSerialization(123, "123"); - TestSerialization(-123, "-123"); - TestSerialization(0.0f, "0"); - TestSerialization(1.0f, "1"); - TestSerialization(3.14f, "3.14"); - TestSerialization(-3.14f, "-3.14"); - TestSerialization(0.0d, "0"); - TestSerialization(3.14d, "3.14"); - TestSerialization(3.1415926d, "3.1415926"); - TestSerialization(-3.1415926d, "-3.1415926"); - } - - [Fact] - [Trait("Platform", "Any")] - public void JsonSerializer_String() - { - TestSerialization((string)null, "null"); - TestSerialization(string.Empty, "''".Replace("'", "\"")); - TestSerialization("Hello, World!", "'Hello, World!'".Replace("'", "\"")); - TestSerialization("\"", "'\\\"'".Replace("'", "\"")); - TestSerialization("\n", "'\\n'".Replace("'", "\"")); - TestSerialization("\t", "'\\t'".Replace("'", "\"")); - TestSerialization("\0", "'\\u0000'".Replace("'", "\"")); - TestSerialization("\u6768", "'\\u6768'".Replace("'", "\"")); - } + public static IEnumerable Data => + new List + { + new object[] { null, "null" }, + new object[] { true, "true" }, + new object[] { false, "false" }, + new object[] { 0, "0" }, + new object[] { 123, "123" }, + new object[] { -123, "-123" }, + new object[] { 0.0f, "0" }, + new object[] { 1.0f, "1" }, + new object[] { 3.14f, "3.14" }, + new object[] { -3.14f, "-3.14" }, + new object[] { 0.0d, "0" }, + new object[] { 3.14d, "3.14" }, + new object[] { 3.1415926d, "3.1415926" }, + new object[] { -3.1415926d, "-3.1415926" }, + new object[] { string.Empty, "''".Replace("'", "\"") }, + new object[] { "Hello, World!", "'Hello, World!'".Replace("'", "\"") }, + new object[] { "\"", "'\\\"'".Replace("'", "\"") }, + new object[] { "\n", "'\\n'".Replace("'", "\"") }, + new object[] { "\t", "'\\t'".Replace("'", "\"") }, + new object[] { "\0", "'\\u0000'".Replace("'", "\"") }, + new object[] { "\u6768", "'\\u6768'".Replace("'", "\"") }, + new object[] { Array.Empty(), "[]" }, + new object[] { new object[] { 1, 2, 3 }, "[1,2,3]" }, + new object[] { new Dictionary(), "{}" }, + new object[] { new Dictionary { ["foo"] = 1, ["bar"] = "baz", ["golden ratio"] = 0.6180340f, ["pi"] = 3.14159265358979d }, "{'foo':1,'bar':'baz','golden ratio':0.618034,'pi':3.14159265358979}".Replace("'", "\"") }, + }; - [Fact] + [Theory] + [MemberData(nameof(Data))] [Trait("Platform", "Any")] - public void JsonSerializer_Array() + public void TestSerialization(object value, string expected) { - TestSerialization((object[])null, "null"); - TestSerialization(new object[] { }, "[]"); - TestSerialization(new object[] { 1, 2, 3 }, "[1,2,3]"); - } - - [Fact] - [Trait("Platform", "Any")] - public void JsonSerializer_Map() - { - TestSerialization((Dictionary)null, "null"); - TestSerialization(new Dictionary(), "{}"); - TestSerialization( - new Dictionary - { - ["foo"] = 1, - ["bar"] = "baz", - ["golden ratio"] = 0.6180340f, - ["pi"] = 3.14159265358979d, - }, - "{'foo':1,'bar':'baz','golden ratio':0.618034,'pi':3.14159265358979}".Replace("'", "\"")); + var buffer = new byte[65_536]; + var length = JsonSerializer.Serialize(buffer, 0, value); + Assert.Equal(expected, Encoding.ASCII.GetString(buffer, 0, length)); } } From 87814d59405281950e451bdbadc510ed59b6085e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 19 Jan 2023 17:28:37 +0100 Subject: [PATCH 0505/1499] [Instrumentation.MySqlData] Release 1.0.0-beta.5 (#907) Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index f3db83449d..e90d71500f 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2023-Jan-19 + * Compatibility with Mysql.Data 8.0.32 or later. ([#901](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/901)) From a63793d9e6d203eeb2cd42dc5bb2bf31617c876f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 19 Jan 2023 13:43:38 -0800 Subject: [PATCH 0506/1499] [Exporter.Geneva] Update GenevaExporter CHANGELOG (#885) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 8f9becdb8d..ee894bbca4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,12 @@ * Update OpenTelemetry to 1.4.0-rc.2 ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) +* Add TldTraceExporter and TldLogExporter. Use + `"PrivatePreviewEnableTraceLoggingDynamic=true"` in the connection string to + use these exporters. + ([#662](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/662)) + ([#874](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/874)) + ## 1.4.0-rc.1 Released 2022-Dec-19 From 68f3f90702dbe4c941db0211c915bcf8f4ca0c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 20 Jan 2023 16:22:07 +0100 Subject: [PATCH 0507/1499] [Instrumentation.Quartz] Remove net472 and update tested frameworks (#911) --- .../.publicApi/net472/PublicAPI.Shipped.txt | 0 .../.publicApi/net472/PublicAPI.Unshipped.txt | 14 -------------- .../CHANGELOG.md | 2 ++ .../OpenTelemetry.Instrumentation.Quartz.csproj | 4 ++-- ...enTelemetry.Instrumentation.Quartz.Tests.csproj | 2 +- 5 files changed, 5 insertions(+), 17 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt deleted file mode 100644 index 01e290fd0d..0000000000 --- a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/net472/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,14 +0,0 @@ -const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Execute = "Quartz.Job.Execute" -> string -const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Veto = "Quartz.Job.Veto" -> string -OpenTelemetry.Instrumentation.Quartz.OperationName -OpenTelemetry.Instrumentation.Quartz.OperationName.Job -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.get -> System.Action -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.QuartzInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.get -> bool -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.set -> void -OpenTelemetry.Trace.TraceProviderBuilderExtensions -static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureQuartzInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 4cb5dc75ba..d11a003170 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry.Api to 1.3.1. ([#889](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/889)) +* Removes .NET Framework 4.7.2. It is distributed as .NET Standard 2.0. + ([#911](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/911)) ## 1.0.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 220b573743..97e19a1f72 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -1,10 +1,10 @@ - + OpenTelemetry Quartz.NET Instrumentation $(PackageTags);distributed-tracing Instrumentation.Quartz- true - net472;netstandard2.0 + netstandard2.0 OpenTelemetry.Instrumentation.Quartz OpenTelemetry.Instrumentation.Quartz diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 09e33684bd..e3c389aec6 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry Quartz.NET instrumentation - net472;netcoreapp3.1 + net7.0;net6.0;net472 true From 7e28bdfde7ad712be88d14cf29c4775221704557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 20 Jan 2023 17:06:40 +0100 Subject: [PATCH 0508/1499] [Instrumentation.Process] Enable nullable (#892) * [Instrumentation.Process] Enable nullable * PR feedback - avoid default parameter values Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- .../MeterProviderBuilderExtensions.cs | 12 +++++++++++- .../OpenTelemetry.Instrumentation.Process.csproj | 1 + ...penTelemetry.Instrumentation.Process.Tests.csproj | 1 + .../ProcessMetricsTests.cs | 4 +++- 6 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 0247a31728..78926e8ea9 100644 --- a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,5 @@ OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions.ProcessInstrumentationOptions() -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index dcb0bec65b..ce26b63595 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -25,6 +25,13 @@ namespace OpenTelemetry.Metrics; /// public static class MeterProviderBuilderExtensions { + /// + /// Enables runtime instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddProcessInstrumentation(this MeterProviderBuilder builder) => AddProcessInstrumentationImplementation(builder, configure: null); + /// /// Enables runtime instrumentation. /// @@ -33,7 +40,10 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddProcessInstrumentation( this MeterProviderBuilder builder, - Action configure = null) + Action configure) => + AddProcessInstrumentationImplementation(builder, configure); + + private static MeterProviderBuilder AddProcessInstrumentationImplementation(MeterProviderBuilder builder, Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index b4129cc23e..265bccf4c0 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -5,6 +5,7 @@ $(PackageTags);process Instrumentation.Process- true + enable diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index d245ea0139..690d8cb81a 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 + enable diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 0971c92c31..fd0e4e94b3 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -146,6 +146,9 @@ public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName( var metricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); var metricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); + Assert.NotNull(metricA); + Assert.NotNull(metricB); + Assert.True(GetValue(metricA) > 0); Assert.True(GetValue(metricB) > 0); } @@ -178,7 +181,6 @@ public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName( private static double GetValue(Metric metric) { - Assert.NotNull(metric); double sum = 0; foreach (ref readonly var metricPoint in metric.GetMetricPoints()) From 5bd14dc36eea26a3dc7f995f281de4ee80851005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 20 Jan 2023 17:55:45 +0100 Subject: [PATCH 0509/1499] [Instrumentation.Runtime] Enable nullable (#893) * [Instrumentation.Runtime] Enable nullable * PR feedback - avoid default parameters * cleanup - remove not used publicapi files Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 ++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 ++ .../netcoreapp3.1/PublicAPI.Shipped.txt | 4 -- .../netcoreapp3.1/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 4 ++ .../MeterProviderBuilderExtensions.cs | 16 +++++++- ...enTelemetry.Instrumentation.Runtime.csproj | 1 + .../RuntimeMetrics.cs | 14 +++---- ...metry.Instrumentation.Runtime.Tests.csproj | 39 ++++++++++--------- .../RuntimeMetricsTests.cs | 4 +- 10 files changed, 58 insertions(+), 32 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2..c5e742490b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +#nullable enable +*REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt index e69de29bb2..c5e742490b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +#nullable enable +*REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt deleted file mode 100644 index 4f1e7e604f..0000000000 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt +++ /dev/null @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..c5e742490b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +#nullable enable +*REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index c6616295a1..a3736c1542 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -25,6 +25,15 @@ namespace OpenTelemetry.Metrics; /// public static class MeterProviderBuilderExtensions { + /// + /// Enables runtime instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddRuntimeInstrumentation( + this MeterProviderBuilder builder) => + AddRuntimeInstrumentationImplementation(builder, configure: null); + /// /// Enables runtime instrumentation. /// @@ -33,7 +42,12 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddRuntimeInstrumentation( this MeterProviderBuilder builder, - Action configure = null) + Action configure) => + AddRuntimeInstrumentationImplementation(builder, configure); + + private static MeterProviderBuilder AddRuntimeInstrumentationImplementation( + MeterProviderBuilder builder, + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index d950ce70ab..53580889d5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,6 +5,7 @@ $(PackageTags);runtime Instrumentation.Runtime- true + enable diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index ef294f29bc..68ac758b88 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -31,7 +31,7 @@ namespace OpenTelemetry.Instrumentation.Runtime; internal class RuntimeMetrics { internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); - internal static readonly Meter MeterInstance = new(AssemblyName.Name, AssemblyName.Version.ToString()); + internal static readonly Meter MeterInstance = new(AssemblyName.Name!, AssemblyName.Version?.ToString()); #if NET6_0_OR_GREATER private const long NanosecondsPerTick = 100; @@ -76,11 +76,11 @@ static RuntimeMetrics() description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); // GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 - Func getGenerationSize = null; + Func? getGenerationSize = null; bool isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; if (isCodeRunningOnBuggyRuntimeVersion) { - MethodInfo mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); + var mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); if (mi != null) { getGenerationSize = mi.CreateDelegate>(); @@ -106,11 +106,11 @@ static RuntimeMetrics() { if (isCodeRunningOnBuggyRuntimeVersion) { - measurements[i] = new((long)getGenerationSize(i), new KeyValuePair("generation", GenNames[i])); + measurements[i] = new((long)getGenerationSize!(i), new KeyValuePair("generation", GenNames[i])); } else { - measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); } } @@ -137,7 +137,7 @@ static RuntimeMetrics() int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); for (int i = 0; i < maxSupportedLength; ++i) { - measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); } return measurements; @@ -238,7 +238,7 @@ private static IEnumerable> GetGarbageCollectionCounts() { long collectionsFromThisGeneration = GC.CollectionCount(gen); - yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("generation", GenNames[gen])); + yield return new(collectionsFromThisGeneration - collectionsFromHigherGeneration, new KeyValuePair("generation", GenNames[gen])); collectionsFromHigherGeneration = collectionsFromThisGeneration; } diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index e69e3a367a..5ea624c90b 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,25 +1,26 @@ - - - net7.0;net6.0 - $(TargetFrameworks);net462 - + + + net7.0;net6.0 + $(TargetFrameworks);net462 + enable + - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 2418165a2c..602d35e5bf 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -56,6 +56,7 @@ public void RuntimeMetricsAreCaptured() Assert.NotNull(assembliesCountMetric); var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.exceptions.count"); + Assert.NotNull(exceptionsCountMetric); Assert.True(GetValue(exceptionsCountMetric) >= 1); } @@ -147,6 +148,7 @@ public void ThreadingRelatedMetricsTest() Assert.NotNull(threadCountMetric); var completedItemsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.completed_items.count"); + Assert.NotNull(completedItemsCountMetric); Assert.True(GetValue(completedItemsCountMetric) >= taskCount); var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); @@ -167,6 +169,7 @@ public void ThreadingRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); var timerCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.timer.count"); + Assert.NotNull(timerCountMetric); Assert.True(GetValue(timerCountMetric) >= timerCount); } finally @@ -181,7 +184,6 @@ public void ThreadingRelatedMetricsTest() private static double GetValue(Metric metric) { - Assert.NotNull(metric); double sum = 0; foreach (ref readonly var metricPoint in metric.GetMetricPoints()) From ffe533020887676b9971c0fbbf9df378e4605bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 20 Jan 2023 22:17:58 +0100 Subject: [PATCH 0510/1499] [Instrumentation.Process, Instrumentation.Process] make configure action nullable (#913) * [Instrumentation.Process, Instrumentation.Process] make configure action nullable * public api fix --- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../MeterProviderBuilderExtensions.cs | 7 ++----- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../MeterProviderBuilderExtensions.cs | 7 +------ 6 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 78926e8ea9..1b9d855189 100644 --- a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -2,4 +2,4 @@ OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions.ProcessInstrumentationOptions() -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index ce26b63595..b3ec572477 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -30,7 +30,7 @@ public static class MeterProviderBuilderExtensions /// /// being configured. /// The instance of to chain the calls. - public static MeterProviderBuilder AddProcessInstrumentation(this MeterProviderBuilder builder) => AddProcessInstrumentationImplementation(builder, configure: null); + public static MeterProviderBuilder AddProcessInstrumentation(this MeterProviderBuilder builder) => AddProcessInstrumentation(builder, configure: null); /// /// Enables runtime instrumentation. @@ -40,10 +40,7 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddProcessInstrumentation( this MeterProviderBuilder builder, - Action configure) => - AddProcessInstrumentationImplementation(builder, configure); - - private static MeterProviderBuilder AddProcessInstrumentationImplementation(MeterProviderBuilder builder, Action? configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt index c5e742490b..b9754cf55f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ #nullable enable *REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt index c5e742490b..b9754cf55f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ #nullable enable *REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index c5e742490b..b9754cf55f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ #nullable enable *REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index a3736c1542..1baf6ef0da 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -32,7 +32,7 @@ public static class MeterProviderBuilderExtensions /// The instance of to chain the calls. public static MeterProviderBuilder AddRuntimeInstrumentation( this MeterProviderBuilder builder) => - AddRuntimeInstrumentationImplementation(builder, configure: null); + AddRuntimeInstrumentation(builder, configure: null); /// /// Enables runtime instrumentation. @@ -42,11 +42,6 @@ public static MeterProviderBuilder AddRuntimeInstrumentation( /// The instance of to chain the calls. public static MeterProviderBuilder AddRuntimeInstrumentation( this MeterProviderBuilder builder, - Action configure) => - AddRuntimeInstrumentationImplementation(builder, configure); - - private static MeterProviderBuilder AddRuntimeInstrumentationImplementation( - MeterProviderBuilder builder, Action? configure) { Guard.ThrowIfNull(builder); From 50aa7505aa8f7255702ae4f46dbfc902a0314d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 23 Jan 2023 20:21:24 +0100 Subject: [PATCH 0511/1499] [Instrumentation.EntityFrameworkCore] Bump OTel to 1.3.1 (#915) --- .../CHANGELOG.md | 4 ++-- .../OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index a0ed020ae4..c6316baa3c 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OTel SDK package version to 1.2.0 - [#347](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/347) +* Updated OTel SDK package version to 1.3.1 + [#915](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/915) * Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.EntityFrameworkCore` diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 667f9e5435..b5ac491519 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET @@ -8,7 +8,7 @@ - + From 193940d49992fd758ffb19f4756e7ce802b88e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 23 Jan 2023 22:10:39 +0100 Subject: [PATCH 0512/1499] Bump OpenTelemetry Core packages to 1.3.2 (#917) * Bump OpenTelemetry Core packages to 1.3.2 * changelogs --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 3 +++ src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions.Docker/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ 13 files changed, 34 insertions(+), 7 deletions(-) diff --git a/build/Common.props b/build/Common.props index 63ff182803..16d2b9fa2b 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,7 +31,7 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.3.1,2.0) + [1.3.2,2.0) [1.4.0-rc.2] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 7be4707f2d..1187d12358 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.2`. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.2 Released 2022-Dec-20 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index bd0f760680..84435083d1 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.2`. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-beta.4 Released 2022-Dec-07 diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md index bce907b69a..803906ee89 100644 --- a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updates to 1.3.2 of OpenTelemetry SDK. +[917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917) + ## 1.0.0-beta.2 Released 2023-Jan-11 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 571ea3dab8..fad78ef43c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.3.2`. +([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-rc9.7 Released 2022-Nov-28 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index c6316baa3c..3c498487cc 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OTel SDK package version to 1.3.1 - [#915](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/915) +* Updated OTel SDK package version to 1.3.2 + [#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917) * Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.EntityFrameworkCore` diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 5a6e7c8486..e50bf065dd 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry.Api to 1.3.2. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-alpha.2 Released 2022-Nov-10 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index ee6525ae80..b44eaa7736 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel API version to `1.3.2`. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-beta.4 Released 2022-Dec-15 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index e90d71500f..818fdfdd5e 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel API version to `1.3.2`. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-beta.5 Released 2023-Jan-19 diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 2655c8897d..28f40866da 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry SDK to 1.3.2 + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-rc.3 Released 2022-Sep-20 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index d11a003170..dbf60b970b 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.3.1. - ([#889](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/889)) +* Update OpenTelemetry.Api to 1.3.2. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) * Removes .NET Framework 4.7.2. It is distributed as .NET Standard 2.0. ([#911](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/911)) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 71c9d2b7ab..9a80c8054b 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel API version to `1.3.1`. - ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) +* Update OTel API version to `1.3.2`. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) ## 1.0.0-rc9.7 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 8d25c1f862..ea3dda66a9 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.3.2`. + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) + ## 1.0.0-rc.8 Released 2022-Dec-28 From b1eb56a07f2bc76b704150517a8c10913631e50e Mon Sep 17 00:00:00 2001 From: Michael Murphy <5879863+mrblonde91@users.noreply.github.com> Date: Tue, 24 Jan 2023 20:46:42 +0000 Subject: [PATCH 0513/1499] [Instrumentation.EntityFrameworkCore] Add support to enrich activities in entity (#868) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added an alternative display name option * Add func * formatting * Rename test * Correct typo * Fix mistake * Correct formatting, simplify test * Remove unused * cleanup * Correct public api file and add missing space * Update to include enrichment * Update public api * Add summary * Remove rogue using * Correct response * Relocate enrich * Cleanup * Correct contract * Correct interface name * Update test * Update change log * Update description * Remove rogue summary * Switch to idbcommand * Correction on exception plus blank line * Switch to nameof * Cleanup exception * Corrections * Update src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> * Add string replace * Use command type in instead of text * Rename test * Update src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs Co-authored-by: Cijo Thomas * Add safety check Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz Co-authored-by: Cijo Thomas Co-authored-by: Cijo Thomas --- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../CHANGELOG.md | 3 ++ .../EntityFrameworkInstrumentationOptions.cs | 11 +++++ .../EntityFrameworkDiagnosticListener.cs | 14 ++++++- ...tityFrameworkInstrumentationEventSource.cs | 19 +++++++++ .../EntityFrameworkDiagnosticListenerTests.cs | 41 +++++++++++++++++-- 6 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 5cbec75d76..0445bcf970 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -4,5 +4,7 @@ OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentation OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.get -> bool OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.set -> void +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.get -> System.Action +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 3c498487cc..888d86e110 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -9,6 +9,9 @@ `OpenTelemetry.Instrumentation.EntityFrameworkCore` [#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486) +* Added support to `EnrichWithIDbCommand` + [#868](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/868) + ## 1.0.0-beta.3 * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index f135754acd..597b05a04b 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -14,7 +14,9 @@ // limitations under the License. // +using System; using System.Data; +using System.Diagnostics; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; @@ -33,4 +35,13 @@ public class EntityFrameworkInstrumentationOptions /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. /// public bool SetDbStatementForText { get; set; } = false; + + /// + /// Gets or sets an action to enrich an Activity from the db command. + /// + /// + /// : the activity being enriched. + /// : db command to allow access to command. + /// + public Action EnrichWithIDbCommand { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 300043c491..6193cb7d94 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -87,7 +87,6 @@ public override void OnCustom(string name, Activity activity, object payload) var connection = this.connectionFetcher.Fetch(command); var database = (string)this.databaseFetcher.Fetch(connection); - activity.DisplayName = database; if (activity.IsAllDataRequested) @@ -124,7 +123,6 @@ public override void OnCustom(string name, Activity activity, object payload) } var dataSource = (string)this.dataSourceFetcher.Fetch(connection); - activity.AddTag(AttributeDbName, database); if (!string.IsNullOrEmpty(dataSource)) { @@ -180,6 +178,18 @@ public override void OnCustom(string name, Activity activity, object payload) break; } } + + try + { + if (command is IDbCommand typedCommand) + { + this.options.EnrichWithIDbCommand?.Invoke(activity, typedCommand); + } + } + catch (Exception ex) + { + EntityFrameworkInstrumentationEventSource.Log.EnrichmentException(nameof(EntityFrameworkCoreCommandExecuting), ex); + } } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 8bd40bdd08..1b6e8a2e70 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -18,6 +18,7 @@ using System.Diagnostics.Tracing; using System.Globalization; using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; @@ -35,6 +36,15 @@ public void UnknownErrorProcessingEvent(string handlerName, string eventName, Ex } } + [NonEvent] + public void EnrichmentException(string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(eventName, ex.ToInvariantString()); + } + } + [Event(1, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) { @@ -59,6 +69,15 @@ public void InvalidPayload(string handlerName, string eventName) this.WriteEvent(4, handlerName, eventName); } + [Event(5, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string eventName, string exception) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.WriteEvent(5, eventName, exception); + } + } + /// /// Returns a culture-independent string representation of the given object, /// appropriate for diagnostics tracing. diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 61e4fb0c3e..02897938a7 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -70,6 +70,40 @@ public void EntityFrameworkContextEventsInstrumentedTest() VerifyActivityData(activity); } + [Fact] + public void EntityFrameworkEnrichDisplayNameWithEnrichWithIDbCommand() + { + var activityProcessor = new Mock>(); + var expectedDisplayName = "Text main"; + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation(options => + { + options.EnrichWithIDbCommand = (activity1, command) => + { + var stateDisplayName = $"{command.CommandType} main"; + activity1.DisplayName = stateDisplayName; + activity1.SetTag("db.name", stateDisplayName); + }; + }).Build(); + + using (var context = new ItemsContext(this.contextOptions)) + { + var items = context.Set().OrderBy(e => e.Name).ToList(); + + Assert.Equal(3, items.Count); + Assert.Equal("ItemOne", items[0].Name); + Assert.Equal("ItemThree", items[1].Name); + Assert.Equal("ItemTwo", items[2].Name); + } + + Assert.Equal(3, activityProcessor.Invocations.Count); + + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + VerifyActivityData(activity, altDisplayName: $"{expectedDisplayName}"); + } + [Fact] public void EntityFrameworkContextExceptionEventsInstrumentedTest() { @@ -108,16 +142,17 @@ private static DbConnection CreateInMemoryDatabase() return connection; } - private static void VerifyActivityData(Activity activity, bool isError = false) + private static void VerifyActivityData(Activity activity, bool isError = false, string altDisplayName = null) { - Assert.Equal("main", activity.DisplayName); + Assert.Equal(altDisplayName ?? "main", activity.DisplayName); + Assert.Equal(ActivityKind.Client, activity.Kind); Assert.Equal("sqlite", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbSystem).Value); // TBD: SqlLite not setting the DataSource so it doesn't get set. Assert.DoesNotContain(activity.Tags, t => t.Key == EntityFrameworkDiagnosticListener.AttributePeerService); - Assert.Equal("main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); + Assert.Equal(altDisplayName ?? "main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); Assert.Equal(CommandType.Text.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SpanAttributeConstants.DatabaseStatementTypeKey).Value); if (!isError) From 564a918dba0e0b949141d34cc07adeb4fdc62efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 24 Jan 2023 22:19:48 +0100 Subject: [PATCH 0514/1499] [Instrumentation.EntityFrameworkCore] cleanup test project (#918) * [Instrumentation.EntityFrameworkCore] drop netcoreapp3.1 from tests * [Instrumentation.EntityFrameworkCore] bump OpenTelemetry to 1.3.2 in tests Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- ...metry.Instrumentation.EntityFrameworkCore.Tests.csproj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 295bcd9432..42b5a7f267 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 @@ -13,10 +13,6 @@ - - - - @@ -33,7 +29,7 @@ - + From ca1c0a666b1f9270b260d839c0b4bf6b58fb633f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 25 Jan 2023 20:10:12 +0100 Subject: [PATCH 0515/1499] [Instrumentation.EntityFrameworkCore] Remove AddEntityFrameworkCoreInstrumentation with default parameter (#916) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 3 +++ .../EntityFrameworkInstrumentation.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 14 +++++++++++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 0445bcf970..0288dcace5 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,4 +7,5 @@ OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentation OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.get -> System.Action OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 888d86e110..15b86609c5 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -8,6 +8,9 @@ * Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.EntityFrameworkCore` [#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486) +* Removes `AddEntityFrameworkCoreInstrumentation` method with default configure + default parameter. + ([#916](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/916)) * Added support to `EnrichWithIDbCommand` [#868](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/868) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 636762ab60..5f2a439188 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -23,7 +23,7 @@ internal class EntityFrameworkInstrumentation : IDisposable { private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions options = null) + public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions options) { this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( name => new EntityFrameworkDiagnosticListener(name, options), diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index d0213ede8a..8aa9e3d6c1 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -30,16 +30,24 @@ public static class TracerProviderBuilderExtensions /// Enables Microsoft.EntityFrameworkCore instrumentation. /// /// being configured. - /// EntityFrameworkCore configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( + this TracerProviderBuilder builder) => AddEntityFrameworkCoreInstrumentation(builder, configure: null); + + /// + /// Enables Microsoft.EntityFrameworkCore instrumentation. + /// + /// being configured. + /// EntityFrameworkCore configuration options. /// The instance of to chain the calls. public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( this TracerProviderBuilder builder, - Action configureOptions = null) + Action configure) { Guard.ThrowIfNull(builder); var options = new EntityFrameworkInstrumentationOptions(); - configureOptions?.Invoke(options); + configure?.Invoke(options); builder.AddInstrumentation(() => new EntityFrameworkInstrumentation(options)); From f784ba3b00eed8eaee8686a3e403076c40e0aab5 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Wed, 25 Jan 2023 14:13:38 -0800 Subject: [PATCH 0516/1499] [Instrumentation.EntityFrameworkCore] Update changelog for 1.0.0-beta.4 release (#927) --- .../CHANGELOG.md | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 15b86609c5..4d5c5019e9 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,26 +2,33 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2023-Jan-25 + * Updated OTel SDK package version to 1.3.2 - [#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917) + ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) * Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.EntityFrameworkCore` - [#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486) + ([#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486)) + * Removes `AddEntityFrameworkCoreInstrumentation` method with default configure default parameter. ([#916](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/916)) * Added support to `EnrichWithIDbCommand` - [#868](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/868) + ([#868](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/868)) ## 1.0.0-beta.3 +Released 2022-Mar-18 + * Going forward the NuGet package will be [`OpenTelemetry.Instrumentation.EntityFrameworkCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore). Older versions will remain at [`OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore`](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore) - [(#261)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/261) + ([#261](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/261)) Migration: @@ -31,11 +38,15 @@ ## 1.0.0-beta2 +Released 2021-Jun-11 + * EntityFrameworkCore instrumentation to depend on API and not SDK ([#121](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/121)) ## 0.6.0-beta +Released 2020-Sep-29 + * This is the first release of `OpenTelemetry.Contrib.Instrumentation.EntityFrameworkCore` package. From 840a313cbddeda78cdeb806fb6bd430c0f860e6b Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 26 Jan 2023 08:06:21 +0530 Subject: [PATCH 0517/1499] Add support for BatchProcessorOptions in GenevaExporter (#925) * Add support for batchprocessoroptions * Revert logging * nits --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ .../GenevaExporterHelperExtensions.cs | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index ee894bbca4..64e8ee4d01 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -11,6 +11,10 @@ ([#662](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/662)) ([#874](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/874)) +* Add support for configuring BatchActivityExportProcessor parameters (via + environment variables) used by GenevaTraceExporter in Linux. + ([#925](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/925)) + ## 1.4.0-rc.1 Released 2022-Dec-19 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 09fb5c8942..50de95692b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -43,7 +43,13 @@ private static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderB var exporter = new GenevaTraceExporter(options); if (exporter.IsUsingUnixDomainSocket) { - return builder.AddProcessor(new BatchActivityExportProcessor(exporter)); + var batchOptions = new BatchExportActivityProcessorOptions(); + return builder.AddProcessor(new BatchActivityExportProcessor( + exporter, + batchOptions.MaxQueueSize, + batchOptions.ScheduledDelayMilliseconds, + batchOptions.ExporterTimeoutMilliseconds, + batchOptions.MaxExportBatchSize)); } else { From 80470234f538e94f3a2333fd33371282db41cc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 26 Jan 2023 20:31:00 +0100 Subject: [PATCH 0518/1499] [Instrumentation.Quartz] drop default parameter from registration method (#914) Co-authored-by: Cijo Thomas --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 2 ++ .../TraceProviderBuilderExtensions.cs | 14 +++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 01e290fd0d..39e5f8f8b3 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -11,4 +11,5 @@ OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordExceptio OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.set -> void OpenTelemetry.Trace.TraceProviderBuilderExtensions -static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureQuartzInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index dbf60b970b..8720298814 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -6,6 +6,8 @@ ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) * Removes .NET Framework 4.7.2. It is distributed as .NET Standard 2.0. ([#911](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/911)) +* Removes `AddQuartzInstrumentation` method with default configure default parameter. + ([#914](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/914)) ## 1.0.0-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index 61000e1980..dd84eb51f4 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -30,14 +30,22 @@ public static class TraceProviderBuilderExtensions /// Enables the Quartz.NET Job automatic data collection for Quartz.NET. /// /// being configured. - /// Quartz configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddQuartzInstrumentation( + this TracerProviderBuilder builder) => AddQuartzInstrumentation(builder, configure: null); + + /// + /// Enables the Quartz.NET Job automatic data collection for Quartz.NET. + /// + /// being configured. + /// Quartz configuration options. /// The instance of to chain the calls. public static TracerProviderBuilder AddQuartzInstrumentation( this TracerProviderBuilder builder, - Action configureQuartzInstrumentationOptions = null) + Action configure) { var options = new QuartzInstrumentationOptions(); - configureQuartzInstrumentationOptions?.Invoke(options); + configure?.Invoke(options); builder.AddInstrumentation(() => new QuartzJobInstrumentation(options)); builder.AddSource(QuartzDiagnosticListener.ActivitySourceName); From ce3c05db3ea592d10990a593396f8f8f2055cc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 27 Jan 2023 18:51:11 +0100 Subject: [PATCH 0519/1499] [Instrumentation.WCF] Remove AddWcfInstrumentation with default parameter (#928) --- .../CHANGELOG.md | 2 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 2 ++ .../TracerProviderBuilderExtensions.cs | 10 +++++++++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 4d5c5019e9..8ec769c5e2 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -14,7 +14,7 @@ Released 2023-Jan-25 ([#486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/486)) * Removes `AddEntityFrameworkCoreInstrumentation` method with default configure - default parameter. + parameter. ([#916](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/916)) * Added support to `EnrichWithIDbCommand` diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt index 4415915fff..30bb5ab1fe 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt @@ -47,4 +47,5 @@ override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionEle override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.CreateBehavior() -> object override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.BehaviorType.get -> System.Type override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.CreateBehavior() -> object -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index b0b243ca1e..63b7e2ee2f 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -29,4 +29,5 @@ OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamIn OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.WcfInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index ea3dda66a9..6bfb00c834 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OTel SDK version to `1.3.2`. ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Removes `AddWcfInstrumentation` method with default configure parameter. + ([#928](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/928)) ## 1.0.0-rc.8 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index fbfad45d92..6093fcd5b0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -25,13 +25,21 @@ namespace OpenTelemetry.Trace; /// public static class TracerProviderBuilderExtensions { + /// + /// Enables the outgoing requests automatic data collection for WCF. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder) => + AddWcfInstrumentation(builder, configure: null); + /// /// Enables the outgoing requests automatic data collection for WCF. /// /// being configured. /// Wcf configuration options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action configure = null) + public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action configure) { Guard.ThrowIfNull(builder); From 5c836aea4de7e83b2b0da6a36b18eaa94cab83fc Mon Sep 17 00:00:00 2001 From: Michael Maxwell Date: Mon, 30 Jan 2023 11:53:24 -0800 Subject: [PATCH 0520/1499] [EventCounters] SpinWait for tests (#862) --- .../EventCountersMetricsTests.cs | 109 +++++------------- 1 file changed, 31 insertions(+), 78 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index a8a5c5f528..09669dae30 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -17,6 +17,8 @@ using System; using System.Collections.Generic; using System.Diagnostics.Tracing; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; @@ -25,27 +27,6 @@ namespace OpenTelemetry.Instrumentation.EventCounters.Tests; public class EventCountersMetricsTests { - private const int Delay = 1200; - - [Fact(Skip = "Other tests metrics are being exported here")] - public void NoMetricsByDefault() - { - // Arrange - List metricItems = new(); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCountersInstrumentation(null) - .AddInMemoryExporter(metricItems) - .Build(); - - // Act - Task.Delay(Delay).Wait(); - meterProvider.ForceFlush(); - - // Assert - Assert.Empty(metricItems); - } - [Fact] public void EventCounter() { @@ -64,11 +45,9 @@ public void EventCounter() // Act counter.WriteMetric(1997.0202); - Task.Delay(Delay).Wait(); - meterProvider.ForceFlush(); + var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName: "ec.a.c"); // Assert - var metric = metricItems.Find(x => x.Name == "ec.a.c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleGauge, metric.MetricType); Assert.Equal(1997.0202, GetActualValue(metric)); @@ -94,17 +73,15 @@ public void IncrementingEventCounter() incCounter.Increment(1); incCounter.Increment(1); incCounter.Increment(1); - Task.Delay(Delay).Wait(); - meterProvider.ForceFlush(); + var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName: "ec.b.inc-c"); // Assert - var metric = metricItems.Find(x => x.Name == "ec.b.inc-c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleSum, metric.MetricType); Assert.Equal(3, GetActualValue(metric)); } - [Fact(Skip = "Unstable")] + [Fact] public void PollingCounter() { // Arrange @@ -122,17 +99,15 @@ public void PollingCounter() .Build(); // Act - Task.Delay(Delay * 2).Wait(); - meterProvider.ForceFlush(); + var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName: "ec.c.poll-c"); // Assert - var metric = metricItems.Find(x => x.Name == "ec.c.poll-c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleGauge, metric.MetricType); - Assert.Equal(20, GetActualValue(metric)); + Assert.Equal(10, GetActualValue(metric)); } - [Fact(Skip = "Unstable")] + [Fact] public void IncrementingPollingCounter() { // Arrange @@ -150,46 +125,12 @@ public void IncrementingPollingCounter() .Build(); // Act - Task.Delay(Delay * 2).Wait(); - meterProvider.ForceFlush(); + var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName: "ec.d.inc-poll-c"); // Assert - var metric = metricItems.Find(x => x.Name == "ec.d.inc-poll-c"); Assert.NotNull(metric); Assert.Equal(MetricType.DoubleSum, metric.MetricType); - Assert.Equal(2, GetActualValue(metric)); - } - - [Fact] - public void EventCounterSameNameUsesNewestCreated() - { - // Arrange - List metricItems = new(); - using EventSource source = new("a"); - using EventCounter counter = new("c", source); - using EventCounter counter2 = new("c", source); - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddEventCountersInstrumentation(options => - { - options.AddEventSources(source.Name); - }) - .AddInMemoryExporter(metricItems) - .Build(); - - // Act - counter2.WriteMetric(1980.1208); - counter.WriteMetric(1997.0202); - Task.Delay(Delay).Wait(); - meterProvider.ForceFlush(); - - // Assert - var metric = metricItems.Find(x => x.Name == "ec.a.c"); - Assert.NotNull(metric); - Assert.Equal(MetricType.DoubleGauge, metric.MetricType); - - // Since `counter2` was created after `counter` it is exported - Assert.Equal(1980.1208, GetActualValue(metric)); + Assert.Equal(1, GetActualValue(metric)); } [Fact] @@ -214,7 +155,6 @@ public void ThrowExceptionForUnsupportedEventSources() Assert.Equal("Use the `OpenTelemetry.Instrumentation.Runtime` or `OpenTelemetry.Instrumentation.Process` instrumentations.", ex.Message); } - /* [Theory] [InlineData("Microsoft-AspNetCore-Server-Kestrel-1", "tls-handshakes-per-second", "ec.Microsoft-AspNetCore-Server-Kestre.tls-handshakes-per-second")] [InlineData("Microsoft-AspNetCore-Server-Kestrel-1", "tls-handshakes-per-sec", "ec.Microsoft-AspNetCore-Server-Kestrel-1.tls-handshakes-per-sec")] @@ -241,17 +181,14 @@ public void EventSourceNameShortening(string sourceName, string eventName, strin // Act connections.Increment(1); - Task.Delay(Delay).Wait(); - meterProvider.ForceFlush(); + var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName); // Assert - Metric metric = metricItems.Find(m => m.Name == expectedInstrumentName); Assert.NotNull(metric); Assert.Equal(1, GetActualValue(metric)); } - */ - [Fact] + [Fact(Skip = "This test should properly validate no metrics are exported from event counters with invalid names (too long)")] public void InstrumentNameTooLong() { // Arrange @@ -272,7 +209,8 @@ public void InstrumentNameTooLong() // Act connections.Increment(1); - Task.Delay(Delay).Wait(); + + Task.Delay(1800).Wait(); meterProvider.ForceFlush(); // Assert @@ -283,8 +221,6 @@ public void InstrumentNameTooLong() } } - // polling and eventcounter with same instrument name? - private static double GetActualValue(Metric metric) { double sum = 0; @@ -298,4 +234,21 @@ private static double GetActualValue(Metric metric) return sum; } + + private static Metric AwaitExport(MeterProvider meterProvider, List exportedItems, string expectedInstrumentName) + { + Metric metric = null; + + SpinWait.SpinUntil( + () => + { + Thread.Sleep(100); + meterProvider.ForceFlush(); + metric = exportedItems.Where(x => x.Name == expectedInstrumentName).FirstOrDefault(); + return metric != null; + }, + 10_000); + + return metric; + } } From 8c3efaf3b23254ee85a75e2ee66bf5adeafe06a9 Mon Sep 17 00:00:00 2001 From: Alexander Batishchev Date: Mon, 30 Jan 2023 12:05:31 -0800 Subject: [PATCH 0521/1499] [Exporter.Geneva] Release 1.4.0-rc.2 (#932) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 64e8ee4d01..78705cc8f2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-rc.2 + +Released 2023-Jan-30 + * Update OpenTelemetry to 1.4.0-rc.2 ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) From 9248719aa979286af20fc7106b966f0569512026 Mon Sep 17 00:00:00 2001 From: Paul Spangler Date: Tue, 31 Jan 2023 09:46:25 -0600 Subject: [PATCH 0522/1499] [Instrumentation.Runtime] Fix README description of the value for GC collections count (#895) --- .../README.md | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index b7680f166e..8dee33cc1c 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -48,20 +48,33 @@ to the application. Number of garbage collections that have occurred since process start. -Note: Collecting a generation means collecting objects in that generation and all -its younger generations. However, each dimension for this metrics doesn't include -the collection counts for the lower generation. -e.g. count for gen1 is `GC.CollectionCount(1) - GC.CollectionCount(0)`. +Note: .NET uses a [generational GC](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#generations) +which divides the heap into different generations numbered 0, 1, and 2. In each +collection the GC decides which generation to search for reclaimable memory, +then it searches that generation and all the lower ones. A GC collection that +searches generations 0, 1, and 2 is called a "gen2" collection, searching +generations 0 and 1 is a "gen1" collection and searching generation 0 only is a +"gen0" collection. The gen0, gen1, and gen2 attribute values for this metric +count respectively the number of gen0, gen1, and gen2 collections which have +occurred since the process started. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |-----------------|-------------------|------------|------------------|------------------| | `{collections}` | ObservableCounter | `Int64` | generation | gen0, gen1, gen2 | -The API used to retrieve the value is: +The metric can be computed using the [GC.CollectionCount](https://docs.microsoft.com/dotnet/api/system.gc.collectioncount) +API: + +* `count_gen0_collections = GC.CollectionCount(0) - GC.CollectionCount(1)` +* `count_gen1_collections = GC.CollectionCount(1) - GC.CollectionCount(2)` +* `count_gen2_collections = GC.CollectionCount(2)` -* [GC.CollectionCount](https://docs.microsoft.com/dotnet/api/system.gc.collectioncount): - The number of times garbage collection has occurred for the specified generation -of objects. +GC.CollectionCount(X) counts the number of times objects in generation X have +been searched during any GC collection. Although it may sound similar, notice +this is not the same as the number of genX collections. For example objects in +generation 0 are searched during gen0, gen1, and gen2 collections so +`GC.CollectionCount(0) = count_gen0_collections + count_gen1_collections + count_gen2_collections`. +This is why the expressions above are not direct assignments. #### process.runtime.dotnet.**gc.objects.size** From cad8d76b76728e8773e622baa56ee7d273cfc532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 31 Jan 2023 18:08:09 +0100 Subject: [PATCH 0523/1499] [Instrumentation.AspNet] Remove AddAspNetInstrumentation with default parameter (#942) Co-authored-by: Cijo Thomas --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 3 +++ .../TracerProviderBuilderExtensions.cs | 14 +++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt index a9ba7f916d..9b53ae2ee5 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt @@ -9,4 +9,5 @@ OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordExceptio OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 2e146bf12e..ed61c7622a 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Removes `AddAspNetInstrumentation` method with default configure parameter. + ([#942](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/942)) + ## 1.0.0-rc9.7 Released 2022-Nov-28 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs index e5cbbc5d2f..eec9f981cf 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -29,16 +29,24 @@ public static class TracerProviderBuilderExtensions /// Enables the incoming requests automatic data collection for ASP.NET. /// /// being configured. - /// ASP.NET Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetInstrumentation(this TracerProviderBuilder builder) => + AddAspNetInstrumentation(builder, configure: null); + + /// + /// Enables the incoming requests automatic data collection for ASP.NET. + /// + /// being configured. + /// ASP.NET Request configuration options. /// The instance of to chain the calls. public static TracerProviderBuilder AddAspNetInstrumentation( this TracerProviderBuilder builder, - Action configureAspNetInstrumentationOptions = null) + Action configure) { Guard.ThrowIfNull(builder); var aspnetOptions = new AspNetInstrumentationOptions(); - configureAspNetInstrumentationOptions?.Invoke(aspnetOptions); + configure?.Invoke(aspnetOptions); builder.AddInstrumentation(() => new AspNetInstrumentation(aspnetOptions)); builder.AddSource(TelemetryHttpModule.AspNetSourceName); From 98989a0e43f6ca94632c6dcc555a24fc9107d1c1 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 1 Feb 2023 12:32:44 -0800 Subject: [PATCH 0524/1499] [AzureMonitor] Change drop sampling result to recordOnly (#933) * change drop sampling result to recordOnly * fix test * update change log --- .../ApplicationInsightsSampler.cs | 6 +++--- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 6 ++++++ .../ApplicationInsightsSamplerTests.cs | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index 4e1d38e5fe..f632e2662e 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -26,7 +26,7 @@ namespace OpenTelemetry.Extensions.AzureMonitor; /// public class ApplicationInsightsSampler : Sampler { - private static readonly SamplingResult DropSamplingResult = new(false); + private static readonly SamplingResult RecordOnlySamplingResult = new(SamplingDecision.RecordOnly); private readonly SamplingResult recordAndSampleSamplingResult; private readonly float samplingRatio; @@ -63,7 +63,7 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame { if (this.samplingRatio == 0) { - return DropSamplingResult; + return RecordOnlySamplingResult; } if (this.samplingRatio == 1) @@ -79,7 +79,7 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame } else { - return DropSamplingResult; + return RecordOnlySamplingResult; } } diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 6afa9efb18..1b146392ae 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +* Sampler will now return `RecordOnly` SamplingResult when the telemetry is +sampled out. +([#933](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/933)) + ## 1.0.0-beta.2 Released 2022-Sept-12 diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs index 92920b3fca..5c14e435e1 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs @@ -50,8 +50,8 @@ public void VerifyHashAlgorithmCorrectness() // Verify sample ratio: 0 ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(samplingRatio: 0); - Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams1).Decision); - Assert.Equal(SamplingDecision.Drop, zeroSampler.ShouldSample(testParams2).Decision); + Assert.Equal(SamplingDecision.RecordOnly, zeroSampler.ShouldSample(testParams1).Decision); + Assert.Equal(SamplingDecision.RecordOnly, zeroSampler.ShouldSample(testParams2).Decision); // Verify sample ratio: 1 ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(samplingRatio: 1); @@ -61,7 +61,7 @@ public void VerifyHashAlgorithmCorrectness() // Verify sample ratio: 0.5. // This is below the sample score for testId2, but strict enough to drop testId1 ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(samplingRatio: 0.5f); - Assert.Equal(SamplingDecision.Drop, ratioSampler.ShouldSample(testParams1).Decision); + Assert.Equal(SamplingDecision.RecordOnly, ratioSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); } From a68c7fd1249964b64dfffbe4ecec81f8faf64c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 2 Feb 2023 18:00:22 +0100 Subject: [PATCH 0525/1499] Bump OTel to 1.4.0-rc.3 (#944) --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build/Common.props b/build/Common.props index 16d2b9fa2b..d4a67da1b6 100644 --- a/build/Common.props +++ b/build/Common.props @@ -32,7 +32,7 @@ [3.3.3] [1.1.1,2.0) [1.3.2,2.0) - [1.4.0-rc.2] + [1.4.0-rc.3] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 78705cc8f2..aebf999ce0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0-rc.3 + ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) + ## 1.4.0-rc.2 Released 2023-Jan-30 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 26db82b7e3..ef751909e4 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry to 1.4.0-rc.2 - ([#880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/880)) +* Update OpenTelemetry to 1.4.0-rc.3 + ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 1d5f2ecb89..28274c6d6d 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.3 + ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) + ## 1.0.0-alpha.4 Released 2023-Jan-11 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 8d7a227152..1935065190 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.3 + ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) + ## 1.1.0-beta.3 Released 2023-Jan-11 From 887416d3451218ad915f49f081a152354a11eb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 2 Feb 2023 18:22:40 +0100 Subject: [PATCH 0526/1499] [Instrumentation.Process] Release with OTel 1.4.0-rc.3 (#946) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 28274c6d6d..6e9571be36 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.5 + +Released 2023-Feb-02 + * Update OpenTelemetry API to 1.4.0-rc.3 ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) From d835d5d43be73874fb6ae29b57bfdbfa09127c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 2 Feb 2023 18:23:29 +0100 Subject: [PATCH 0527/1499] [Instrumentation.Runtime] Release1.1.0-beta.4 (#945) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 1935065190..fbbea3d993 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.4 + +Released 2023-Feb-02 + * Update OpenTelemetry API to 1.4.0-rc.3 ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) From 4532ef0ec75087ad3977b510304b08a71c70f1cf Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 7 Feb 2023 00:38:30 +0530 Subject: [PATCH 0528/1499] Ignore unstable tests (#971) --- .../EventCountersMetricsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 09669dae30..09047f031f 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -27,7 +27,7 @@ namespace OpenTelemetry.Instrumentation.EventCounters.Tests; public class EventCountersMetricsTests { - [Fact] + [Fact(Skip = "Unstable")] public void EventCounter() { // Arrange From 52822ba545e363dcb95c86f01e778aac288b0e20 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 6 Feb 2023 19:37:16 +0000 Subject: [PATCH 0529/1499] [Instrumentation.EventCounters] Fix analysis warnings (#968) --- .../EventCountersMetricsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 09047f031f..e6f92a6823 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -216,8 +216,8 @@ public void InstrumentNameTooLong() // Assert foreach (var item in metricItems) { - Assert.False(item.Name.StartsWith("ec.source.ee")); - Assert.False(item.Name.StartsWith("ec.s.ee")); + Assert.False(item.Name.StartsWith("ec.source.ee", StringComparison.Ordinal)); + Assert.False(item.Name.StartsWith("ec.s.ee", StringComparison.Ordinal)); } } From a515f71b1b0d1bcc6be3ac72dfbcd11ce53c3729 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 6 Feb 2023 21:37:45 +0000 Subject: [PATCH 0530/1499] [Exporter.Geneva] Fix analysis warnings (#954) Fix/suppress code analysis warnings in OpenTelemetry.Contrib.Exporter.Geneva. Contributes to #950. Co-authored-by: Cijo Thomas --- .../TLDExporter/UncheckedASCIIEncoding.cs | 7 +- .../Exporter/LogExporterBenchmarks.cs | 6 +- .../Exporter/TLDLogExporterBenchmarks.cs | 4 +- .../DummyServer.cs | 3 +- .../Program.cs | 5 +- .../GenevaLogExporterTests.cs | 49 ++++++------ .../GenevaMetricExporterTests.cs | 4 +- .../GenevaTraceExporterTests.cs | 4 +- .../JsonSerializerTests.cs | 76 ++++++++++++++++++- .../LogSerializationTests.cs | 6 +- .../MessagePackSerializerTests.cs | 9 ++- 11 files changed, 124 insertions(+), 49 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs index 8b20e53d62..b42d324a66 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -16,6 +16,7 @@ using System; using System.Text; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva.TldExporter; @@ -124,11 +125,7 @@ public override unsafe int GetChars(byte* bytePtr, int byteCount, char* charPtr, public override int GetByteCount(string chars) { - if (chars == null) - { - throw new ArgumentNullException(nameof(chars)); - } - + Guard.ThrowIfNull(chars); return chars.Length; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index b7aab62793..18ba6d0dbf 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -102,7 +102,7 @@ public LogExporterBenchmarks() [Benchmark] public void LoggerWithMessageTemplate() { - this.logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + this.logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); } [Benchmark] @@ -158,7 +158,7 @@ private static LogRecord GenerateTestLogRecord() })); var logger = factory.CreateLogger("TestLogger"); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); return items[0]; } @@ -173,7 +173,7 @@ private static Batch GenerateTestLogRecordBatch() })); var logger = factory.CreateLogger("TestLogger"); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); return batchGeneratorExporter.Batch; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs index 0335f60d24..013933e35d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs @@ -157,7 +157,7 @@ private static LogRecord GenerateTestLogRecord() })); var logger = factory.CreateLogger("TestLogger"); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); return exportedItems[0]; } @@ -172,7 +172,7 @@ private static Batch GenerateTestLogRecordBatch() })); var logger = factory.CreateLogger("TestLogger"); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); return batchGeneratorExporter.Batch; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index 1757f49f2e..4137778264 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -18,7 +18,6 @@ using System.IO; using System.Net; using System.Net.Sockets; -using System.Threading; using System.Threading.Tasks; namespace OpenTelemetry.Exporter.Geneva.Stress; @@ -61,7 +60,7 @@ public void Start() Socket acceptSocket = this.serverSocket.Accept(); Task.Run(() => { - int threadId = Thread.CurrentThread.ManagedThreadId; + int threadId = Environment.CurrentManagedThreadId; Console.WriteLine($"ThreadID {threadId}: Start reading from socket."); int totalBytes = 0; try diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index b1b8275038..d528e19fd4 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; @@ -29,7 +30,7 @@ namespace OpenTelemetry.Exporter.Geneva.Stress; internal class Program { private static volatile bool s_bContinue = true; - private static long s_nEvents = 0; + private static long s_nEvents; private static ActivitySource source = new ActivitySource("OpenTelemetry.Exporter.Geneva.Stress"); @@ -135,7 +136,7 @@ private static int EntryPoint(Action init, Action run) watch.Stop(); var nEvents = statistics.Sum(); var nEventPerSecond = (int)((nEvents - s_nEvents) / (watch.ElapsedMilliseconds / 1000.0)); - Console.Title = string.Format("Loops: {0:n0}, Loops/Second: {1:n0}", nEvents, nEventPerSecond); + Console.Title = string.Format(CultureInfo.InvariantCulture, "Loops: {0:n0}, Loops/Second: {1:n0}", nEvents, nEventPerSecond); } }, () => diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 8192fe0e0a..ad823c1b12 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; using System.Net.Sockets; @@ -385,7 +386,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) if (hasCustomFields) { - exporterOptions.CustomFields = new string[] { "food", "Name", "Key1" }; + exporterOptions.CustomFields = new string[] { "Food", "Name", "Key1" }; } var exportedItems = new List(); @@ -419,7 +420,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) using (logger.BeginScope("MyInnerInnerScope with {Name} and {Age} of custom", "John Doe", 25)) using (logger.BeginScope(new List> { new("Key1", "Value1"), new("Key2", "Value2") })) { - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); } byte[] serializedData; @@ -445,7 +446,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) var envProperties = mapping["env_properties"] as Dictionary; // Custom Fields - Assert.Equal("artichoke", mapping["food"]); + Assert.Equal("artichoke", mapping["Food"]); Assert.Equal("John Doe", mapping["Name"]); Assert.Equal("Value1", mapping["Key1"]); @@ -453,7 +454,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) Assert.False(mapping.ContainsKey("MyInnerScope")); // env_properties - Assert.True(Equals(envProperties["price"], 3.99)); + Assert.True(Equals(envProperties["Price"], 3.99)); Assert.Equal((byte)25, envProperties["Age"]); Assert.Equal("Value2", envProperties["Key2"]); @@ -462,8 +463,8 @@ public void SerializeILoggerScopes(bool hasCustomFields) } else { - Assert.Equal("artichoke", mapping["food"]); - Assert.True(Equals(mapping["price"], 3.99)); + Assert.Equal("artichoke", mapping["Food"]); + Assert.True(Equals(mapping["Price"], 3.99)); Assert.Equal("John Doe", mapping["Name"]); Assert.Equal((byte)25, mapping["Age"]); Assert.Equal("Value1", mapping["Key1"]); @@ -757,24 +758,24 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin using (var activity = source.StartActivity("Activity")) { // Log inside an activity to set LogRecord.TraceId and LogRecord.SpanId - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); // structured logging + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); // structured logging } // When the exporter options are configured with TableMappings only "customField" will be logged as a separate key in the mapping // "property" will be logged under "env_properties" in the mapping - logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", "CustomFieldValue", null); - logger.Log(LogLevel.Trace, 101, "Log a {customField} and {property}", null, "PropertyValue"); - logger.Log(LogLevel.Debug, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Information, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Warning, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Error, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); - logger.Log(LogLevel.Critical, 101, "Log a {customField} and {property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Trace, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Trace, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", null); + logger.Log(LogLevel.Trace, 101, "Log a {CustomField} and {Property}", null, "PropertyValue"); + logger.Log(LogLevel.Debug, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Information, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Warning, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Error, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", "PropertyValue"); + logger.Log(LogLevel.Critical, 101, "Log a {CustomField} and {Property}", "CustomFieldValue", "PropertyValue"); logger.LogInformation("Hello World!"); // unstructured logging - logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {food} {price}.", "artichoke", 3.99); + logger.LogError(new InvalidOperationException("Oops! Food is spoiled!"), "Hello from {Food} {Price}.", "artichoke", 3.99); // Exception with a non-ASCII character in its type name - logger.LogError(new CustomException\u0418(), "Hello from {food} {price}.", "artichoke", 3.99); + logger.LogError(new CustomException\u0418(), "Hello from {Food} {Price}.", "artichoke", 3.99); var loggerWithDefaultCategory = loggerFactory.CreateLogger("DefaultCategory"); loggerWithDefaultCategory.LogInformation("Basic test"); @@ -837,7 +838,7 @@ public void SuccessfulExport_Windows() var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); } } @@ -888,7 +889,7 @@ public void SuccessfulExportOnLinux() // Emit a LogRecord and grab a copy of internal buffer for validation. var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); // logRecordList should have a singleLogRecord entry after the logger.LogInformation call Assert.Single(logRecordList); @@ -908,7 +909,7 @@ public void SuccessfulExportOnLinux() // Emit log on a different thread to test for multithreading scenarios var thread = new Thread(() => { - logger.LogInformation("Hello from another thread {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from another thread {Food} {Price}.", "artichoke", 3.99); }); thread.Start(); thread.Join(); @@ -1104,7 +1105,7 @@ public void TLDLogExporter_Success_Windows() var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {food} {price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); } } @@ -1140,9 +1141,9 @@ private static object GetField(object fluentdData, string key) var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - if (mapping.ContainsKey(key)) + if (mapping.TryGetValue(key, out var value)) { - return mapping[key]; + return value; } else { @@ -1286,7 +1287,7 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter if (logRecord.EventId != default) { - Assert.Equal(logRecord.EventId.Id, int.Parse(mapping["eventId"].ToString())); + Assert.Equal(logRecord.EventId.Id, int.Parse(mapping["eventId"].ToString(), CultureInfo.InvariantCulture)); } // Epilouge diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index da6afdc916..6ffbe93a5c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -322,7 +322,7 @@ public void SuccessfulSerializationWithViews() { if (instrument.Name == "histogramWithNoBounds") { - return new ExplicitBucketHistogramConfiguration { Boundaries = new double[] { } }; + return new ExplicitBucketHistogramConfiguration { Boundaries = Array.Empty() }; } return null; @@ -334,7 +334,7 @@ public void SuccessfulSerializationWithViews() RecordMinMax = false, }) .AddView("observableLongCounter", MetricStreamConfiguration.Drop) - .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { } }) + .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = Array.Empty() }) .AddView(instrument => { if (instrument.Name == "observableLongGauge") diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 51e8faa314..0a656ee73d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -85,7 +85,7 @@ public void GenevaTraceExporter_constructor_Invalid_Input() // Supported types for PrepopulatedFields should not throw an exception var exception = Record.Exception(() => { - new GenevaExporterOptions + _ = new GenevaExporterOptions { ConnectionString = "EtwSession=OpenTelemetry", PrepopulatedFields = new Dictionary @@ -663,7 +663,7 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO else { // If CustomFields are proivded, dedicatedFields will be populated - if (exporterOptions.CustomFields == null || dedicatedFields.ContainsKey(tag.Key)) + if (exporterOptions.CustomFields == null || dedicatedFields.TryGetValue(tag.Key, out _)) { Assert.Equal(tag.Value.ToString(), mapping[tag.Key].ToString()); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs index 0d0846a5d7..906b011d9b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -22,7 +22,7 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; -public class JsonSerializerTests +public static class JsonSerializerTests { public static IEnumerable Data => new List @@ -57,10 +57,82 @@ public class JsonSerializerTests [Theory] [MemberData(nameof(Data))] [Trait("Platform", "Any")] - public void TestSerialization(object value, string expected) + public static void TestSerialization(object value, string expected) { var buffer = new byte[65_536]; var length = JsonSerializer.Serialize(buffer, 0, value); Assert.Equal(expected, Encoding.ASCII.GetString(buffer, 0, length)); } + + [Fact] + [Trait("Platform", "Any")] + public static void JsonSerializer_Null() + { + TestSerialization(null, "null"); + } + + [Fact] + [Trait("Platform", "Any")] + public static void JsonSerializer_Boolean() + { + TestSerialization(true, "true"); + TestSerialization(false, "false"); + } + + [Fact] + [Trait("Platform", "Any")] + public static void JsonSerializer_Numeric() + { + TestSerialization(0, "0"); + TestSerialization(123, "123"); + TestSerialization(-123, "-123"); + TestSerialization(0.0f, "0"); + TestSerialization(1.0f, "1"); + TestSerialization(3.14f, "3.14"); + TestSerialization(-3.14f, "-3.14"); + TestSerialization(0.0d, "0"); + TestSerialization(3.14d, "3.14"); + TestSerialization(3.1415926d, "3.1415926"); + TestSerialization(-3.1415926d, "-3.1415926"); + } + + [Fact] + [Trait("Platform", "Any")] + public static void JsonSerializer_String() + { + TestSerialization((string)null, "null"); + TestSerialization(string.Empty, "''".Replace("'", "\"")); + TestSerialization("Hello, World!", "'Hello, World!'".Replace("'", "\"")); + TestSerialization("\"", "'\\\"'".Replace("'", "\"")); + TestSerialization("\n", "'\\n'".Replace("'", "\"")); + TestSerialization("\t", "'\\t'".Replace("'", "\"")); + TestSerialization("\0", "'\\u0000'".Replace("'", "\"")); + TestSerialization("\u6768", "'\\u6768'".Replace("'", "\"")); + } + + [Fact] + [Trait("Platform", "Any")] + public static void JsonSerializer_Array() + { + TestSerialization((object[])null, "null"); + TestSerialization(Array.Empty(), "[]"); + TestSerialization(new object[] { 1, 2, 3 }, "[1,2,3]"); + } + + [Fact] + [Trait("Platform", "Any")] + public static void JsonSerializer_Map() + { + TestSerialization((Dictionary)null, "null"); + TestSerialization(new Dictionary(), "{}"); + TestSerialization( + new Dictionary + { + ["foo"] = 1, + ["bar"] = "baz", + ["golden ratio"] = 0.6180340f, + ["pi"] = 3.14159265358979d, + }, + "{'foo':1,'bar':'baz','golden ratio':0.618034,'pi':3.14159265358979}".Replace("'", "\"")); + } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index b1f6057210..54e1522223 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -77,7 +77,7 @@ public void SerializationTestForExceptionTrim() var exStack = new string('e', 16383 + 1); var ex = new MyException(exceptionMessage, exStack); var exportedFields = GetExportedFieldsAfterLogging( - logger => logger.LogError(ex, "Error occurred. {field1} {field2}", "value1", "value2"), + logger => logger.LogError(ex, "Error occurred. {Field1} {Field2}", "value1", "value2"), (genevaOptions) => genevaOptions.ExceptionStackExportMode = ExceptionStackExportMode.ExportAsString); var actualExceptionMessage = exportedFields["env_ex_msg"]; @@ -89,10 +89,10 @@ public void SerializationTestForExceptionTrim() var actualExceptionStack = exportedFields["env_ex_stack"]; Assert.EndsWith("...", (string)actualExceptionStack); - var actualValue = exportedFields["field1"]; + var actualValue = exportedFields["Field1"]; Assert.Equal("value1", actualValue); - actualValue = exportedFields["field2"]; + actualValue = exportedFields["Field2"]; Assert.Equal("value2", actualValue); // PrintFields(this.output, exportedFields); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index bb6e9ba212..5c6b3fd55e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Text; using Xunit; using Xunit.Sdk; @@ -54,7 +55,9 @@ private void MessagePackSerializer_TestASCIIStringSerialization(string input) if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) { // We truncate the string using `.` in the last three characters which takes 3 bytes of memort +#pragma warning disable CA1846 // Prefer 'AsSpan' over 'Substring' var byteCount = Encoding.ASCII.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; +#pragma warning restore CA1846 // Prefer 'AsSpan' over 'Substring' Assert.Equal(0xDA, buffer[0]); Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); Assert.Equal(byteCount, length - 3); // First three bytes are metadata @@ -109,7 +112,9 @@ private void MessagePackSerializer_TestUnicodeStringSerialization(string input) if (!string.IsNullOrEmpty(input) && input.Length > sizeLimit) { // We truncate the string using `.` in the last three characters which takes 3 bytes of memory +#pragma warning disable CA1846 // Prefer 'AsSpan' over 'Substring' var byteCount = Encoding.UTF8.GetByteCount(input.Substring(0, sizeLimit - 3)) + 3; +#pragma warning restore CA1846 // Prefer 'AsSpan' over 'Substring' Assert.Equal(0xDA, buffer[0]); Assert.Equal(byteCount, (buffer[1] << 8) | buffer[2]); Assert.Equal(byteCount, length - 3); // First three bytes are metadata @@ -347,7 +352,7 @@ public void MessagePackSerializer_SerializeUnicodeString() public void MessagePackSerializer_Array() { this.MessagePackSerializer_TestSerialization((object[])null); - this.MessagePackSerializer_TestSerialization(new object[0]); + this.MessagePackSerializer_TestSerialization(Array.Empty()); // This object array has a custom string which will be serialized as STR16 var objectArrayWithString = new object[] @@ -386,7 +391,7 @@ public void MessagePackSerializer_Map() _ = MessagePackSerializer.Serialize(buffer, 0, dictionaryWithStrings); var dictionaryWithStringsDeserialized = MessagePack.MessagePackSerializer.Deserialize>(buffer); Assert.Equal(dictionaryWithStrings.Count, dictionaryWithStringsDeserialized.Count); - Assert.Equal(dictionaryWithStrings["foo"], Convert.ToInt32(dictionaryWithStringsDeserialized["foo"])); + Assert.Equal(dictionaryWithStrings["foo"], Convert.ToInt32(dictionaryWithStringsDeserialized["foo"], CultureInfo.InvariantCulture)); Assert.Equal(dictionaryWithStrings["bar"], dictionaryWithStringsDeserialized["bar"]); Assert.Equal(dictionaryWithStrings["golden ratio"], dictionaryWithStringsDeserialized["golden ratio"]); Assert.Equal(dictionaryWithStrings["pi"], dictionaryWithStringsDeserialized["pi"]); From 8ee613cdb0c163c45b870bbb01510d4bed82c3eb Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 6 Feb 2023 23:05:06 +0000 Subject: [PATCH 0531/1499] [Extensions.PersistentStorage] Fix analysis warnings (#958) Fix/suppress code analysis warnings in OpenTelemetry.Contrib.Extensions.PersistentStorage. Contributes to #950. Co-authored-by: Cijo Thomas --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 ++-- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 ++-- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 4 ++-- .../FileBlob.cs | 3 +++ .../FileBlobProvider.cs | 2 +- .../PersistentStorageHelper.cs | 10 ++++++++-- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt index 3f30e4159b..03191b5f68 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt @@ -3,7 +3,6 @@ OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool @@ -12,4 +11,5 @@ override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] b override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool \ No newline at end of file +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +virtual OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt index 3f30e4159b..03191b5f68 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -3,7 +3,6 @@ OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool @@ -12,4 +11,5 @@ override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] b override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool \ No newline at end of file +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +virtual OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 3f30e4159b..03191b5f68 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -3,7 +3,6 @@ OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool @@ -12,4 +11,5 @@ override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] b override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool \ No newline at end of file +override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +virtual OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs index 742748bba8..2772a543ba 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs @@ -18,6 +18,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using OpenTelemetry.Extensions.PersistentStorage.Abstractions; +using OpenTelemetry.Internal; namespace OpenTelemetry.Extensions.PersistentStorage; @@ -57,6 +58,8 @@ protected override bool OnTryRead([NotNullWhen(true)] out byte[] buffer) protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) { + Guard.ThrowIfNull(buffer); + string path = this.FullPath + ".tmp"; try diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs index c8abc11b7e..3fc8def5eb 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs @@ -110,7 +110,7 @@ public void Dispose() GC.SuppressFinalize(this); } - public void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) { if (!this.disposedValue) { diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs index f5baa87ab9..377565d74f 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs @@ -204,9 +204,14 @@ internal static DateTime GetDateTimeFromLeaseName(string filePath) internal static string GetSHA256Hash(string input) { - var hashString = new StringBuilder(); - byte[] inputBits = Encoding.Unicode.GetBytes(input); + +#if NET6_0_OR_GREATER +#pragma warning disable CA1308 // Normalize strings to uppercase + return Convert.ToHexString(SHA256.HashData(inputBits)).ToLowerInvariant(); +#pragma warning restore CA1308 // Normalize strings to uppercase +#else + var hashString = new StringBuilder(); using (var sha256 = SHA256.Create()) { byte[] hashBits = sha256.ComputeHash(inputBits); @@ -217,6 +222,7 @@ internal static string GetSHA256Hash(string input) } return hashString.ToString(); +#endif } private static long CalculateFolderSize(string path) From 2cf37da063cec98a365208b6628220e03e9a0c91 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 7 Feb 2023 16:42:25 +0000 Subject: [PATCH 0532/1499] [Instrumentation.AspNet] Fix analysis warnings (#960) --- .../TelemetryHttpModule.cs | 3 +++ .../MeterProviderBuilderExtensions.cs | 3 +-- .../ActivityHelperTest.cs | 6 +++--- .../HttpContextHelper.cs | 8 ++++---- .../WebConfigTransformTest.cs | 9 +++++---- .../WebConfigWithLocationTagTransformTest.cs | 9 +++++---- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index 62a45ef49d..2b9455bca1 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -18,6 +18,7 @@ using System.Diagnostics; using System.Reflection; using System.Web; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.AspNet; @@ -57,6 +58,8 @@ public void Dispose() /// public void Init(HttpApplication context) { + Guard.ThrowIfNull(context); + context.BeginRequest += this.Application_BeginRequest; context.EndRequest += this.Application_EndRequest; context.Error += this.Application_Error; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs index ee69839171..2b2b6cf3cc 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs @@ -34,8 +34,7 @@ public static MeterProviderBuilder AddAspNetInstrumentation( { Guard.ThrowIfNull(builder); - var instrumentation = new AspNetMetrics(); builder.AddMeter(AspNetMetrics.InstrumentationName); - return builder.AddInstrumentation(() => instrumentation); + return builder.AddInstrumentation(() => new AspNetMetrics()); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index 130614390c..f491020cd4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -429,7 +429,9 @@ public void Can_Create_RootActivity_And_Saved_In_HttContext() } [Fact] +#pragma warning disable CA1030 // Use events where appropriate public void Fire_Exception_Events() +#pragma warning restore CA1030 // Use events where appropriate { int callbacksFired = 0; @@ -529,13 +531,11 @@ public TestHttpContext(Exception error = null) private class NoopTextMapPropagator : TextMapPropagator { - private static readonly PropagationContext DefaultPropagationContext = default; - public override ISet Fields => null; public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) { - return DefaultPropagationContext; + return default; } public override void Inject(PropagationContext context, T carrier, Action setter) diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs index dd1864609b..b39a654aa9 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -79,9 +79,9 @@ public override string[][] GetUnknownRequestHeaders() public override string GetUnknownRequestHeader(string name) { - if (this.headers.ContainsKey(name)) + if (this.headers.TryGetValue(name, out var value)) { - return this.headers[name]; + return value; } return base.GetUnknownRequestHeader(name); @@ -91,9 +91,9 @@ public override string GetKnownRequestHeader(int index) { var name = GetKnownRequestHeaderName(index); - if (this.headers.ContainsKey(name)) + if (this.headers.TryGetValue(name, out var value)) { - return this.headers[name]; + return value; } return base.GetKnownRequestHeader(index); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs index a232bb7bb4..e64c93868d 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs @@ -391,16 +391,17 @@ private XDocument ApplyTransformation(string originalConfiguration, string trans var document = new XmlTransformableDocument(); using var transformation = new XmlTransformation(stream, null); stream = null; +#pragma warning disable CA3075 // Insecure DTD processing in XML document.LoadXml(originalConfiguration); +#pragma warning restore CA3075 // Insecure DTD processing in XML transformation.Apply(document); result = XDocument.Parse(document.OuterXml); } finally { - if (stream != null) - { - stream.Dispose(); - } +#pragma warning disable CA1508 // Avoid dead conditional code + stream?.Dispose(); +#pragma warning restore CA1508 // Avoid dead conditional code } return result; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs index 0e84dbb24b..7e39fc8ee4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -421,16 +421,17 @@ private XDocument ApplyTransformation(string originalConfiguration, string trans var document = new XmlTransformableDocument(); using var transformation = new XmlTransformation(stream, null); stream = null; +#pragma warning disable CA3075 // Insecure DTD processing in XML document.LoadXml(originalConfiguration); +#pragma warning restore CA3075 // Insecure DTD processing in XML transformation.Apply(document); result = XDocument.Parse(document.OuterXml); } finally { - if (stream != null) - { - stream.Dispose(); - } +#pragma warning disable CA1508 // Avoid dead conditional code + stream?.Dispose(); +#pragma warning restore CA1508 // Avoid dead conditional code } return result; From 525dd9034ba2eb219142868c01b769d2e570090b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 7 Feb 2023 12:47:50 -0800 Subject: [PATCH 0533/1499] [Extensions.AzureMonitor] Update changelog for release (#975) --- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 1b146392ae..72a69d2839 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -2,8 +2,16 @@ ## Unreleased +## 1.0.0-beta.3 + +Released 2023-Feb-07 + * Sampler will now return `RecordOnly` SamplingResult when the telemetry is -sampled out. +sampled instead of `Drop`. This will result in `Activity` to be created always +and populated with all information such as tag, events etc. This is done in +order to allow metrics collection from the generated activities. **Note**: This +change will have no impact on the overall sampling behavior, +but may have additional performance overhead from creating more activities. ([#933](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/933)) ## 1.0.0-beta.2 From 9c963925d56951abf1e7f07ec166a890eb1d6a69 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 7 Feb 2023 22:52:22 +0000 Subject: [PATCH 0534/1499] [Instrumentation.AWSLambda] Fix analysis warnings (#959) --- .../AWSLambdaWrapper.cs | 30 +++++++++++-------- .../Implementation/AWSLambdaHttpUtils.cs | 2 +- .../SampleLambdaContext.cs | 14 ++++----- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 9359fc17b5..ba62e517cc 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -22,6 +22,7 @@ using System.Threading.Tasks; using Amazon.Lambda.Core; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWSLambda; @@ -69,6 +70,7 @@ public static TResult Trace( ILambdaContext context, ActivityContext parentContext = default) { + Guard.ThrowIfNull(lambdaHandler); return TraceInternal(tracerProvider, lambdaHandler, input, context, parentContext); } @@ -93,12 +95,15 @@ public static void Trace( ILambdaContext context, ActivityContext parentContext = default) { - Func func = (input, context) => + Guard.ThrowIfNull(lambdaHandler); + + object Handler(TInput input, ILambdaContext context) { lambdaHandler(input, context); return null; - }; - TraceInternal(tracerProvider, func, input, context, parentContext); + } + + TraceInternal(tracerProvider, Handler, input, context, parentContext); } /// @@ -123,12 +128,15 @@ public static Task TraceAsync( ILambdaContext context, ActivityContext parentContext = default) { - Func> func = async (input, context) => + Guard.ThrowIfNull(lambdaHandler); + + async Task Handler(TInput input, ILambdaContext context) { - await lambdaHandler(input, context); + await lambdaHandler(input, context).ConfigureAwait(false); return null; - }; - return TraceInternalAsync(tracerProvider, func, input, context, parentContext); + } + + return TraceInternalAsync(tracerProvider, Handler, input, context, parentContext); } /// @@ -154,6 +162,7 @@ public static Task TraceAsync( ILambdaContext context, ActivityContext parentContext = default) { + Guard.ThrowIfNull(lambdaHandler); return TraceInternalAsync(tracerProvider, lambdaHandler, input, context, parentContext); } @@ -182,10 +191,7 @@ internal static Activity OnFunctionStart(TInput input, ILambdaContext co private static void OnFunctionStop(Activity activity, TracerProvider tracerProvider) { - if (activity != null) - { - activity.Stop(); - } + activity?.Stop(); // force flush before function quit in case of Lambda freeze. tracerProvider?.ForceFlush(); @@ -239,7 +245,7 @@ private static async Task TraceInternalAsync( var activity = OnFunctionStart(input, context, parentContext); try { - var result = await handlerAsync(input, context); + var result = await handlerAsync(input, context).ConfigureAwait(false); AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, result); return result; } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index 94742e8fd8..0982d20c9b 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -97,7 +97,7 @@ internal static string GetQueryString(APIGatewayProxyRequest request) { queryString.Append(separator) .Append(HttpUtility.UrlEncode(parameterKvp.Key)) - .Append("=") + .Append('=') .Append(HttpUtility.UrlEncode(value)); separator = '&'; } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index bc36ca20d8..8b77918a75 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -23,23 +23,23 @@ public class SampleLambdaContext : ILambdaContext { public string AwsRequestId { get; } = "testrequestid"; - public IClientContext ClientContext { get; } = null; + public IClientContext ClientContext { get; } public string FunctionName { get; } = "testfunction"; public string FunctionVersion { get; } = "latest"; - public ICognitoIdentity Identity { get; } = null; + public ICognitoIdentity Identity { get; } public string InvokedFunctionArn { get; } = "arn:aws:lambda:us-east-1:111111111111:function:testfunction"; - public ILambdaLogger Logger { get; } = null; + public ILambdaLogger Logger { get; } - public string LogGroupName { get; } = null; + public string LogGroupName { get; } - public string LogStreamName { get; } = null; + public string LogStreamName { get; } - public int MemoryLimitInMB { get; } = 0; + public int MemoryLimitInMB { get; } - public TimeSpan RemainingTime { get; } = default; + public TimeSpan RemainingTime { get; } } From 0c64c7495a83c375feb1a6c6ce1fad9ebc5024d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 8 Feb 2023 00:15:00 +0100 Subject: [PATCH 0535/1499] [Instrumentation.Owin] Remove AddOwinInstrumentation with default parameter (#929) Co-authored-by: Cijo Thomas --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 2 ++ .../TracerProviderBuilderExtensions.cs | 14 +++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt index 028f956bd4..23c619652b 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt @@ -11,5 +11,6 @@ OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.ge OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions Owin.AppBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureOwinInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static Owin.AppBuilderExtensions.UseOpenTelemetry(this Owin.IAppBuilder appBuilder) -> Owin.IAppBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 28f40866da..38e529310c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -4,6 +4,8 @@ * Updated OpenTelemetry SDK to 1.3.2 ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Removes `AddOwinInstrumentation` method with default configure parameter. + ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) ## 1.0.0-rc.3 diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index c2b26c796e..9a3e39835f 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -29,16 +29,24 @@ public static class TracerProviderBuilderExtensions /// Enables the incoming requests automatic data collection for OWIN. /// /// being configured. - /// OWIN Request configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddOwinInstrumentation(this TracerProviderBuilder builder) => + AddOwinInstrumentation(builder, configure: null); + + /// + /// Enables the incoming requests automatic data collection for OWIN. + /// + /// being configured. + /// OWIN Request configuration options. /// The instance of to chain the calls. public static TracerProviderBuilder AddOwinInstrumentation( this TracerProviderBuilder builder, - Action configureOwinInstrumentationOptions = null) + Action configure) { Guard.ThrowIfNull(builder); var owinOptions = new OwinInstrumentationOptions(); - configureOwinInstrumentationOptions?.Invoke(owinOptions); + configure?.Invoke(owinOptions); OwinInstrumentationActivitySource.Options = owinOptions; From a2960dc2e07a4539fc0d98b484d7b32404e11926 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Tue, 7 Feb 2023 16:45:35 -0800 Subject: [PATCH 0536/1499] [Instrumentation.Process] Cleanup public APIs. (#973) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 --- .../CHANGELOG.md | 6 ++++++ .../MeterProviderBuilderExtensions.cs | 17 ++--------------- .../ProcessInstrumentationOptions.cs | 2 +- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 1b9d855189..63ab8f1974 100644 --- a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +1,2 @@ -OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions -OpenTelemetry.Instrumentation.Process.ProcessInstrumentationOptions.ProcessInstrumentationOptions() -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddProcessInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 6e9571be36..2e88c2ec1d 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Removed `ProcessInstrumentationOptions` and + `AddProcessInstrumentation(this MeterProviderBuilder builder,` + `Action? configure)` + from the public APIs. + ([#973](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/973)) + ## 1.0.0-alpha.5 Released 2023-Feb-02 diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index b3ec572477..11ce49531a 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using OpenTelemetry.Instrumentation.Process; using OpenTelemetry.Internal; @@ -26,29 +25,17 @@ namespace OpenTelemetry.Metrics; public static class MeterProviderBuilderExtensions { /// - /// Enables runtime instrumentation. + /// Enables process instrumentation. /// /// being configured. /// The instance of to chain the calls. - public static MeterProviderBuilder AddProcessInstrumentation(this MeterProviderBuilder builder) => AddProcessInstrumentation(builder, configure: null); - - /// - /// Enables runtime instrumentation. - /// - /// being configured. - /// Runtime metrics options. - /// The instance of to chain the calls. public static MeterProviderBuilder AddProcessInstrumentation( - this MeterProviderBuilder builder, - Action? configure) + this MeterProviderBuilder builder) { Guard.ThrowIfNull(builder); var options = new ProcessInstrumentationOptions(); - configure?.Invoke(options); - builder.AddMeter(ProcessMetrics.MeterName); - return builder.AddInstrumentation(() => new ProcessMetrics(options)); } } diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs index bc5b7ddef8..f5d5fd1a7a 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs @@ -19,6 +19,6 @@ namespace OpenTelemetry.Instrumentation.Process; /// /// Options to define the process metrics. /// -public class ProcessInstrumentationOptions +internal class ProcessInstrumentationOptions { } From 429fdbb8703faad752e960442d24df17fab94016 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 8 Feb 2023 00:59:33 +0000 Subject: [PATCH 0537/1499] [Instrumentation.ElasticsearchClient] Fix analysis warnings (#961) --- ...asticsearchClientInstrumentationOptions.cs | 2 +- ...searchRequestPipelineDiagnosticListener.cs | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index 43d42bc6d0..6030bc4a80 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -32,7 +32,7 @@ public class ElasticsearchClientInstrumentationOptions /// /// Gets or sets a value indicating whether the JSON request body should be parsed out of the request debug information and formatted as indented JSON. /// - public bool ParseAndFormatRequest { get; set; } = false; + public bool ParseAndFormatRequest { get; set; } /// /// Gets or sets a value indicating whether or not the OpenTelemetry.Instrumentation.ElasticsearchClient diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index c2c8414ff2..75a2803600 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -87,8 +87,8 @@ public override void OnStartActivity(Activity activity, object payload) SuppressInstrumentationScope.Enter(); } - var elasticIndex = this.GetElasticIndex(uri); - activity.DisplayName = this.GetDisplayName(activity, method, elasticIndex); + var elasticIndex = GetElasticIndex(uri); + activity.DisplayName = GetDisplayName(activity, method, elasticIndex); activity.SetTag(SemanticConventions.AttributeDbSystem, DatabaseSystemName); if (elasticIndex != null) @@ -144,7 +144,7 @@ public override void OnStopActivity(Activity activity, object payload) var debugInformation = this.debugInformationFetcher.Fetch(payload); if (debugInformation != null && this.options.SetDbStatementForRequest) { - var dbStatement = this.ParseAndFormatRequest(activity, debugInformation); + var dbStatement = this.ParseAndFormatRequest(debugInformation); if (this.options.MaxDbStatementLength > 0 && dbStatement.Length > this.options.MaxDbStatementLength) { dbStatement = dbStatement.Substring(0, this.options.MaxDbStatementLength); @@ -201,7 +201,7 @@ public override void OnStopActivity(Activity activity, object payload) } } - private string GetDisplayName(Activity activity, object method, string elasticType = null) + private static string GetDisplayName(Activity activity, object method, string elasticType = null) { switch (activity.OperationName) { @@ -223,7 +223,7 @@ private string GetDisplayName(Activity activity, object method, string elasticTy } } - private string GetElasticIndex(Uri uri) + private static string GetElasticIndex(Uri uri) { // first segment is always / if (uri.Segments.Length < 2) @@ -232,7 +232,7 @@ private string GetElasticIndex(Uri uri) } // operations starting with _ are not indices (_cat, _search, etc) - if (uri.Segments[1].StartsWith("_")) + if (uri.Segments[1].StartsWith("_", StringComparison.Ordinal)) { return null; } @@ -245,7 +245,7 @@ private string GetElasticIndex(Uri uri) return null; } - if (elasticType.EndsWith("/")) + if (elasticType.EndsWith("/", StringComparison.Ordinal)) { elasticType = elasticType.Substring(0, elasticType.Length - 1); } @@ -253,7 +253,7 @@ private string GetElasticIndex(Uri uri) return elasticType; } - private string ParseAndFormatRequest(Activity activity, string debugInformation) + private string ParseAndFormatRequest(string debugInformation) { if (!this.options.ParseAndFormatRequest) { @@ -275,9 +275,10 @@ private string ParseAndFormatRequest(Activity activity, string debugInformation) return debugInformation; } + using (doc) using (var stream = new MemoryStream()) { - var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); + using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); doc.WriteTo(writer); writer.Flush(); body = Encoding.UTF8.GetString(stream.ToArray()); From 9877a3220a3977dce2fb29d7dc2742dee553a0a8 Mon Sep 17 00:00:00 2001 From: ernesto1596 Date: Wed, 8 Feb 2023 07:20:23 -0800 Subject: [PATCH 0538/1499] [OpenTelemetry.Exporter.Geneva] Release 1.4.0-rc.3 (#978) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index aebf999ce0..e8d7203281 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-rc.3 + +Released 2023-Feb-08 + * Update OpenTelemetry to 1.4.0-rc.3 ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) From f46ca2b63fb659291724d836d13cab83b58afaa3 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 8 Feb 2023 16:21:15 +0000 Subject: [PATCH 0539/1499] [Instrumentation.Wcf] Fix analysis warnings (#967) --- .../TelemetryClientMessageInspector.cs | 14 ++++++++++---- .../TelemetryContractBehaviorAttribute.cs | 3 +++ .../TelemetryDispatchMessageInspector.cs | 3 +++ .../TelemetryEndpointBehavior.cs | 3 +++ .../TelemetryServiceBehavior.cs | 3 +++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index 2830e78c91..f34646629f 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -44,6 +44,9 @@ internal TelemetryClientMessageInspector(IDictionary act /// public object BeforeSendRequest(ref Message request, IClientChannel channel) { + Guard.ThrowIfNull(request); + Guard.ThrowIfNull(channel); + try { if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.OutgoingRequestFilter?.Invoke(request) == false) @@ -51,7 +54,7 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel) WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); return new State { - SuppressionScope = this.SuppressDownstreamInstrumentation(), + SuppressionScope = SuppressDownstreamInstrumentation(), }; } } @@ -60,14 +63,14 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel) WcfInstrumentationEventSource.Log.RequestFilterException(ex); return new State { - SuppressionScope = this.SuppressDownstreamInstrumentation(), + SuppressionScope = SuppressDownstreamInstrumentation(), }; } Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( WcfInstrumentationActivitySource.OutgoingRequestActivityName, ActivityKind.Client); - IDisposable suppressionScope = this.SuppressDownstreamInstrumentation(); + IDisposable suppressionScope = SuppressDownstreamInstrumentation(); if (activity != null) { @@ -143,6 +146,9 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel) /// public void AfterReceiveReply(ref Message reply, object correlationState) { + Guard.ThrowIfNull(reply); + Guard.ThrowIfNull(correlationState); + State state = (State)correlationState; state.SuppressionScope?.Dispose(); @@ -171,7 +177,7 @@ public void AfterReceiveReply(ref Message reply, object correlationState) } } - private IDisposable SuppressDownstreamInstrumentation() + private static IDisposable SuppressDownstreamInstrumentation() { return WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false ? SuppressInstrumentationScope.Begin() diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 522dfc9ec3..7669d457b6 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -18,6 +18,7 @@ using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; #if NETFRAMEWORK @@ -45,6 +46,7 @@ public void AddBindingParameters(ContractDescription contractDescription, Servic /// public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { + Guard.ThrowIfNull(clientRuntime); TelemetryEndpointBehavior.ApplyClientBehaviorToClientRuntime(clientRuntime); } @@ -52,6 +54,7 @@ public void ApplyClientBehavior(ContractDescription contractDescription, Service public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { #if NETFRAMEWORK + Guard.ThrowIfNull(dispatchRuntime); TelemetryEndpointBehavior.ApplyDispatchBehaviorToEndpoint(dispatchRuntime.EndpointDispatcher); #endif } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs index 26e109eaa9..476676a534 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs @@ -45,6 +45,9 @@ internal TelemetryDispatchMessageInspector(IDictionary a /// public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { + Guard.ThrowIfNull(request); + Guard.ThrowIfNull(channel); + try { if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.IncomingRequestFilter?.Invoke(request) == false) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index 73417ff793..7b13fb0c93 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -19,6 +19,7 @@ using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; #if NETFRAMEWORK @@ -43,6 +44,7 @@ public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterColle /// public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { + Guard.ThrowIfNull(clientRuntime); ApplyClientBehaviorToClientRuntime(clientRuntime); } @@ -50,6 +52,7 @@ public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRu public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { #if NETFRAMEWORK + Guard.ThrowIfNull(endpointDispatcher); ApplyDispatchBehaviorToEndpoint(endpointDispatcher); #endif } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs index c9cb943025..4a63fc87c3 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -18,6 +18,7 @@ using System.ServiceModel; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; @@ -35,6 +36,8 @@ public void AddBindingParameters(ServiceDescription serviceDescription, ServiceH /// public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { + Guard.ThrowIfNull(serviceHostBase); + foreach (var channelDispatcherBase in serviceHostBase.ChannelDispatchers) { var channelDispatcher = (ChannelDispatcher)channelDispatcherBase; From 047cd058f01abbf61de8274164a901526c545869 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 8 Feb 2023 11:15:47 -0800 Subject: [PATCH 0540/1499] update pr template to include api review check (#980) Co-authored-by: Cijo Thomas --- .github/PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b5fc738afc..e5ef779df5 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,3 +8,4 @@ For significant contributions please make sure you have completed the following * [ ] Appropriate `CHANGELOG.md` updated for non-trivial changes * [ ] Design discussion issue # +* [ ] Changes in public API reviewed From 5474232769ddd9a355f2b56e060025ddbfdfa94b Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 8 Feb 2023 12:28:44 -0800 Subject: [PATCH 0541/1499] [Instrumentation.Process] Removed CPU utilization metric `process.cpu.utilization`. (#972) --- .../CHANGELOG.md | 3 + .../ProcessMetrics.cs | 54 ++------ .../README.md | 17 --- .../ProcessMetricsTests.cs | 123 ++++++++++++------ 4 files changed, 91 insertions(+), 106 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 2e88c2ec1d..1a4619c826 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Removed CPU utilization metric `process.cpu.utilization`. + ([#972](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/972)) + * Removed `ProcessInstrumentationOptions` and `AddProcessInstrumentation(this MeterProviderBuilder builder,` `Action? configure)` diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 410c2f5ce4..5835ce228c 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -16,7 +16,6 @@ #nullable enable -using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; @@ -24,25 +23,16 @@ namespace OpenTelemetry.Instrumentation.Process; -internal sealed class ProcessMetrics : IDisposable +internal sealed class ProcessMetrics { internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); internal static readonly string MeterName = AssemblyName.Name; - private readonly Meter meterInstance = new(MeterName, AssemblyName.Version.ToString()); + private static readonly Meter MeterInstance = new(MeterName, AssemblyName.Version.ToString()); - // vars for calculating CPU utilization - private DateTime lastCollectionTimeUtc; - private double lastCollectedUserProcessorTime; - private double lastCollectedPrivilegedProcessorTime; - - public ProcessMetrics(ProcessInstrumentationOptions options) + static ProcessMetrics() { - this.lastCollectionTimeUtc = DateTime.UtcNow; - this.lastCollectedUserProcessorTime = Diagnostics.Process.GetCurrentProcess().UserProcessorTime.TotalSeconds; - this.lastCollectedPrivilegedProcessorTime = Diagnostics.Process.GetCurrentProcess().PrivilegedProcessorTime.TotalSeconds; - - this.meterInstance.CreateObservableUpDownCounter( + MeterInstance.CreateObservableUpDownCounter( "process.memory.usage", () => { @@ -51,7 +41,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "By", description: "The amount of physical memory allocated for this process."); - this.meterInstance.CreateObservableUpDownCounter( + MeterInstance.CreateObservableUpDownCounter( "process.memory.virtual", () => { @@ -60,7 +50,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "By", description: "The amount of committed virtual memory for this process."); - this.meterInstance.CreateObservableCounter( + MeterInstance.CreateObservableCounter( "process.cpu.time", () => { @@ -74,16 +64,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) unit: "s", description: "Total CPU seconds broken down by different states."); - this.meterInstance.CreateObservableGauge( - "process.cpu.utilization", - () => - { - return this.GetCpuUtilization(); - }, - unit: "1", - description: "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process."); - - this.meterInstance.CreateObservableUpDownCounter( + MeterInstance.CreateObservableUpDownCounter( "process.threads", () => { @@ -93,26 +74,7 @@ public ProcessMetrics(ProcessInstrumentationOptions options) description: "Process threads count."); } - public void Dispose() - { - this.meterInstance.Dispose(); - } - - private IEnumerable> GetCpuUtilization() + public ProcessMetrics(ProcessInstrumentationOptions options) { - var process = Diagnostics.Process.GetCurrentProcess(); - var elapsedTimeForAllCpus = (DateTime.UtcNow - this.lastCollectionTimeUtc).TotalSeconds * Environment.ProcessorCount; - var userProcessorUtilization = (process.UserProcessorTime.TotalSeconds - this.lastCollectedUserProcessorTime) / elapsedTimeForAllCpus; - var privilegedProcessorUtilization = (process.PrivilegedProcessorTime.TotalSeconds - this.lastCollectedPrivilegedProcessorTime) / elapsedTimeForAllCpus; - - this.lastCollectionTimeUtc = DateTime.UtcNow; - this.lastCollectedUserProcessorTime = process.UserProcessorTime.TotalSeconds; - this.lastCollectedPrivilegedProcessorTime = process.PrivilegedProcessorTime.TotalSeconds; - - return new[] - { - new Measurement(Math.Min(userProcessorUtilization, 1D), new KeyValuePair("state", "user")), - new Measurement(Math.Min(privilegedProcessorUtilization, 1D), new KeyValuePair("state", "system")), - }; } } diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 6d3562b42a..9481e7fb58 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -92,23 +92,6 @@ Gets the user processor time for this process. * [Process.PrivilegedProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privilegedprocessortime): Gets the privileged processor time for this process. -### process.cpu.utilization - -Difference in process.cpu.time since the last measurement, -divided by the elapsed time and number of CPUs available to the process. - -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------|-------------------|------------|------------------|------------------| -| `1` | ObservableCounter | `Double` | state | user, system | - -The APIs used to retrieve the values are: - -* [Process.UserProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.userprocessortime): -Gets the user processor time for this process. - -* [Process.PrivilegedProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privilegedprocessortime): -Gets the privileged processor time for this process. - ### process.threads Process threads count. diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index fd0e4e94b3..e63b89f1fe 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -16,6 +16,8 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; @@ -28,25 +30,44 @@ public class ProcessMetricsTests [Fact] public void ProcessMetricsAreCaptured() { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() + var exportedItemsA = new List(); + var meterProviderA = Sdk.CreateMeterProviderBuilder() .AddProcessInstrumentation() - .AddInMemoryExporter(exportedItems) + .AddInMemoryExporter(exportedItemsA) .Build(); - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + meterProviderA.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItems.Count == 5); - var physicalMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.usage"); + Assert.True(exportedItemsA.Count == 4); + var physicalMemoryMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetric); - var virtualMemoryMetric = exportedItems.FirstOrDefault(i => i.Name == "process.memory.virtual"); + var virtualMemoryMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetric); - var cpuTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.time"); + var cpuTimeMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.time"); Assert.NotNull(cpuTimeMetric); - var cpuUtilizationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.utilization"); - Assert.NotNull(cpuUtilizationMetric); - var threadMetric = exportedItems.FirstOrDefault(i => i.Name == "process.threads"); + var threadMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads"); Assert.NotNull(threadMetric); + + exportedItemsA.Clear(); + + var exportedItemsB = new List(); + + using var meterProviderB = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItemsA, metricReaderOptions => + { + metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1500; + }) + .AddInMemoryExporter(exportedItemsB, metricReaderOptions => + { + metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 5000; + }) + .Build(); + + meterProviderB.ForceFlush(MaxTimeToAllowForFlush); + + Assert.True(exportedItemsA.Count == 4); + Assert.True(exportedItemsB.Count == 4); } [Fact] @@ -87,44 +108,62 @@ public void CpuTimeMetricsAreCaptured() } [Fact] - public void CpuUtilizationMetricsAreCaptured() + public void ProcessMetricsAreCapturedWhenTasksOverlap() { - var exportedItems = new List(); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddProcessInstrumentation() - .AddInMemoryExporter(exportedItems) - .Build(); + var exportedItemsA = new List(); + var exportedItemsB = new List(); - meterProvider.ForceFlush(MaxTimeToAllowForFlush); + var tasks = new List() + { + Task.Run(() => + { + var meterProviderA = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItemsA) + .Build(); - var cpuUtilizationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.cpu.utilization"); - Assert.NotNull(cpuUtilizationMetric); + Thread.Sleep(3000); // increase the odds of 2 tasks overlaps - var userCpuUtilizationCaptured = false; - var systemCpuUtilizationCaptured = false; + meterProviderA.ForceFlush(MaxTimeToAllowForFlush); + }), - var iter = cpuUtilizationMetric.GetMetricPoints().GetEnumerator(); - while (iter.MoveNext() && (!userCpuUtilizationCaptured || !systemCpuUtilizationCaptured)) - { - foreach (var tag in iter.Current.Tags) + Task.Run(() => { - if (tag.Key == "state" && tag.Value.ToString() == "user") - { - userCpuUtilizationCaptured = true; - } - else if (tag.Key == "state" && tag.Value.ToString() == "system") - { - systemCpuUtilizationCaptured = true; - } - } - } - - Assert.True(userCpuUtilizationCaptured); - Assert.True(systemCpuUtilizationCaptured); + var meterProviderB = Sdk.CreateMeterProviderBuilder() + .AddProcessInstrumentation() + .AddInMemoryExporter(exportedItemsB) + .Build(); + + Thread.Sleep(3000); // increase the odds of 2 tasks overlaps + + meterProviderB.ForceFlush(MaxTimeToAllowForFlush); + }), + }; + + Task.WaitAll(tasks.ToArray()); + + Assert.True(exportedItemsA.Count == 4); + var physicalMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); + Assert.NotNull(physicalMemoryMetricA); + var virtualMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual"); + Assert.NotNull(virtualMemoryMetricA); + var cpuTimeMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.time"); + Assert.NotNull(cpuTimeMetricA); + var threadMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads"); + Assert.NotNull(threadMetricA); + + Assert.True(exportedItemsB.Count == 4); + var physicalMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); + Assert.NotNull(physicalMemoryMetricB); + var virtualMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.virtual"); + Assert.NotNull(virtualMemoryMetricB); + var cpuTimeMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.cpu.time"); + Assert.NotNull(cpuTimeMetricB); + var threadMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.threads"); + Assert.NotNull(threadMetricB); } - // See: https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/831 - [Fact(Skip = "There are known issues with this test.")] + [Fact] public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName() { var exportedItemsA = new List(); @@ -173,8 +212,6 @@ public void CheckValidGaugeValueWhen2MeterProviderInstancesHaveTheSameMeterName( meterProviderA.ForceFlush(MaxTimeToAllowForFlush); - // Note: This fails due to: - // https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/Metrics/MetricReaderExt.cs#L244-L249 Assert.NotEmpty(exportedItemsA); Assert.Empty(exportedItemsB); } From d016ba1975bd6af1d0bbab3f5706aca540cba123 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Thu, 9 Feb 2023 15:23:44 +0000 Subject: [PATCH 0542/1499] [Exporter.Instana] Fix analysis warnings (#955) --- .../Implementation/InstanaSpanSerializer.cs | 191 +++++++++--------- .../Processors/ActivityProcessorBase.cs | 2 +- .../Processors/DefaultActivityProcessor.cs | 2 +- .../Processors/ErrorActivityProcessor.cs | 2 +- .../Processors/EventsActivityProcessor.cs | 2 +- .../Processors/TagsActivityProcessor.cs | 2 +- .../Implementation/SpanSender.cs | 11 +- .../Implementation/Transport.cs | 34 ++-- .../InstanaExporter.cs | 7 +- .../TracerProviderBuilderExtensions.cs | 2 + .../InstanaExporterTests.cs | 4 +- .../InstanaSpanFactoryTests.cs | 7 +- .../InstanaSpanSerializerTests.cs | 12 +- 13 files changed, 143 insertions(+), 135 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index ee1cb91b80..35dfa433ef 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -17,12 +17,13 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Threading.Tasks; namespace OpenTelemetry.Exporter.Instana.Implementation; -internal class InstanaSpanSerializer +internal static class InstanaSpanSerializer { #pragma warning disable SA1310 // Field names should not contain underscore private const string COMMA = ","; @@ -36,78 +37,80 @@ internal class InstanaSpanSerializer #pragma warning restore SA1310 // Field names should not contain underscore private static readonly long UnixZeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks; - internal IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan) + internal static IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan) { return instanaSpan.Data.Tags.GetEnumerator(); } - internal IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) + internal static IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) { return instanaSpan.Data.Events.GetEnumerator(); } - internal async Task SerializeToByteArrayAsync(InstanaSpan instanaSpan) + internal static async Task SerializeToByteArrayAsync(InstanaSpan instanaSpan) { using var stream = new MemoryStream(); using var writer = new StreamWriter(stream); - await this.SerializeToStreamWriterAsync(instanaSpan, writer); + await SerializeToStreamWriterAsync(instanaSpan, writer).ConfigureAwait(false); - await writer.FlushAsync(); + await writer.FlushAsync().ConfigureAwait(false); return stream.ToArray(); } - internal async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) + internal static async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) { - await writer.WriteAsync(OPEN_BRACE); - await this.AppendProperty(instanaSpan.T, "t", writer); - await writer.WriteAsync(COMMA); - await this.AppendProperty(instanaSpan.S, "s", writer); - await writer.WriteAsync(COMMA); + await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); + await AppendProperty(instanaSpan.T, "t", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await AppendProperty(instanaSpan.S, "s", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); if (!string.IsNullOrEmpty(instanaSpan.P)) { - await this.AppendProperty(instanaSpan.P, "p", writer); - await writer.WriteAsync(COMMA); + await AppendProperty(instanaSpan.P, "p", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); } if (!string.IsNullOrEmpty(instanaSpan.Lt)) { - await this.AppendProperty(instanaSpan.Lt, "lt", writer); - await writer.WriteAsync(COMMA); + await AppendProperty(instanaSpan.Lt, "lt", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); } if (instanaSpan.Tp) { - await this.AppendProperty(true.ToString().ToLower(), "tp", writer); - await writer.WriteAsync(COMMA); +#pragma warning disable CA1308 // Normalize strings to uppercase + await AppendProperty(true.ToString().ToLowerInvariant(), "tp", writer).ConfigureAwait(false); +#pragma warning restore CA1308 // Normalize strings to uppercase + await writer.WriteAsync(COMMA).ConfigureAwait(false); } if (instanaSpan.K != SpanKind.NOT_SET) { - await this.AppendProperty((((int)instanaSpan.K) + 1).ToString(), "k", writer); - await writer.WriteAsync(COMMA); + await AppendProperty((((int)instanaSpan.K) + 1).ToString(CultureInfo.InvariantCulture), "k", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); } - await this.AppendProperty(instanaSpan.N, "n", writer); - await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer); - await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync((long)(instanaSpan.D / 10_000), "d", writer); - await writer.WriteAsync(COMMA); - await this.AppendObjectAsync(this.SerializeDataAsync, "data", instanaSpan, writer); - await writer.WriteAsync(COMMA); - await this.AppendObjectAsync(SerializeFromAsync, "f", instanaSpan, writer); - await writer.WriteAsync(COMMA); - await this.AppendPropertyAsync(instanaSpan.Ec, "ec", writer); - await writer.WriteAsync(CLOSE_BRACE); + await AppendProperty(instanaSpan.N, "n", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await AppendPropertyAsync((long)(instanaSpan.D / 10_000), "d", writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await AppendObjectAsync(SerializeDataAsync, "data", instanaSpan, writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await AppendObjectAsync(SerializeFromAsync, "f", instanaSpan, writer).ConfigureAwait(false); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await AppendPropertyAsync(instanaSpan.Ec, "ec", writer).ConfigureAwait(false); + await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); } private static async Task SerializeFromAsync(InstanaSpan instanaSpan, StreamWriter writer) { - await writer.WriteAsync("{\"e\":\""); - await writer.WriteAsync(instanaSpan.F.E); - await writer.WriteAsync("\"}"); + await writer.WriteAsync("{\"e\":\"").ConfigureAwait(false); + await writer.WriteAsync(instanaSpan.F.E).ConfigureAwait(false); + await writer.WriteAsync("\"}").ConfigureAwait(false); } private static long DateToUnixMillis(long timeStamp) @@ -117,12 +120,12 @@ private static long DateToUnixMillis(long timeStamp) private static async Task SerializeTagsAsync(InstanaSpan instanaSpan, StreamWriter writer) { - await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer); + await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer).ConfigureAwait(false); } private static async Task SerializeTagsLogicAsync(Dictionary tags, StreamWriter writer) { - await writer.WriteAsync(OPEN_BRACE); + await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); using (var enumerator = tags.GetEnumerator()) { byte i = 0; @@ -132,18 +135,18 @@ private static async Task SerializeTagsLogicAsync(Dictionary tag { if (i > 0) { - await writer.WriteAsync(COMMA); + await writer.WriteAsync(COMMA).ConfigureAwait(false); } else { i = 1; } - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(enumerator.Current.Key); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(enumerator.Current.Value); - await writer.WriteAsync(QUOTE); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + await writer.WriteAsync(enumerator.Current.Key).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(enumerator.Current.Value).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); } } catch (InvalidOperationException) @@ -154,37 +157,37 @@ private static async Task SerializeTagsLogicAsync(Dictionary tag } } - await writer.WriteAsync(CLOSE_BRACE); + await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); } - private async Task AppendProperty(string value, string name, StreamWriter json) + private static async Task AppendProperty(string value, string name, StreamWriter json) { - await json.WriteAsync(QUOTE); - await json.WriteAsync(name); - await json.WriteAsync(QUOTE_COLON_QUOTE); - await json.WriteAsync(value); - await json.WriteAsync(QUOTE); + await json.WriteAsync(QUOTE).ConfigureAwait(false); + await json.WriteAsync(name).ConfigureAwait(false); + await json.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await json.WriteAsync(value).ConfigureAwait(false); + await json.WriteAsync(QUOTE).ConfigureAwait(false); } - private async Task AppendPropertyAsync(long value, string name, StreamWriter json) + private static async Task AppendPropertyAsync(long value, string name, StreamWriter json) { - await json.WriteAsync(QUOTE); - await json.WriteAsync(name); - await json.WriteAsync(QUOTE_COLON); - await json.WriteAsync(value.ToString()); + await json.WriteAsync(QUOTE).ConfigureAwait(false); + await json.WriteAsync(name).ConfigureAwait(false); + await json.WriteAsync(QUOTE_COLON).ConfigureAwait(false); + await json.WriteAsync(value.ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false); } - private async Task AppendObjectAsync(Func valueFunction, string name, InstanaSpan instanaSpan, StreamWriter json) + private static async Task AppendObjectAsync(Func valueFunction, string name, InstanaSpan instanaSpan, StreamWriter json) { - await json.WriteAsync(QUOTE); - await json.WriteAsync(name); - await json.WriteAsync(QUOTE_COLON); - await valueFunction(instanaSpan, json); + await json.WriteAsync(QUOTE).ConfigureAwait(false); + await json.WriteAsync(name).ConfigureAwait(false); + await json.WriteAsync(QUOTE_COLON).ConfigureAwait(false); + await valueFunction(instanaSpan, json).ConfigureAwait(false); } - private async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writer) + private static async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writer) { - await writer.WriteAsync(OPEN_BRACE); + await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); using (var enumerator = instanaSpan.Data.data.GetEnumerator()) { byte i = 0; @@ -194,18 +197,18 @@ private async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writ { if (i > 0) { - await writer.WriteAsync(COMMA); + await writer.WriteAsync(COMMA).ConfigureAwait(false); } else { i = 1; } - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(enumerator.Current.Key); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(enumerator.Current.Value.ToString()); - await writer.WriteAsync(QUOTE); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + await writer.WriteAsync(enumerator.Current.Key).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(enumerator.Current.Value.ToString()).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); } } catch (InvalidOperationException) @@ -218,67 +221,67 @@ private async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWriter writ if (instanaSpan.Data.Tags?.Count > 0) { - await writer.WriteAsync(COMMA); + await writer.WriteAsync(COMMA).ConfigureAwait(false); // serialize tags - await this.AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer); + await AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer).ConfigureAwait(false); } if (instanaSpan.Data.Events?.Count > 0) { - await writer.WriteAsync(COMMA); + await writer.WriteAsync(COMMA).ConfigureAwait(false); // serialize tags - await this.AppendObjectAsync(this.SerializeEventsAsync, InstanaExporterConstants.EVENTS_FIELD, instanaSpan, writer); + await AppendObjectAsync(SerializeEventsAsync, InstanaExporterConstants.EVENTS_FIELD, instanaSpan, writer).ConfigureAwait(false); } - await writer.WriteAsync(CLOSE_BRACE); + await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); } - private async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer) + private static async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer) { using (var enumerator = instanaSpan.Data.Events.GetEnumerator()) { byte i = 0; try { - await writer.WriteAsync("["); + await writer.WriteAsync("[").ConfigureAwait(false); while (enumerator.MoveNext()) { if (i > 0) { - await writer.WriteAsync(COMMA); + await writer.WriteAsync(COMMA).ConfigureAwait(false); } else { i = 1; } - await writer.WriteAsync(OPEN_BRACE); - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(enumerator.Current.Name); - await writer.WriteAsync(QUOTE_COMMA_QUOTE); - await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD); - await writer.WriteAsync(QUOTE_COLON_QUOTE); - await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString()); - await writer.WriteAsync(QUOTE); + await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(enumerator.Current.Name).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COMMA_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); if (enumerator.Current.Tags?.Count > 0) { - await writer.WriteAsync(COMMA); - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD); - await writer.WriteAsync(QUOTE); - await writer.WriteAsync(COLON); - await SerializeTagsLogicAsync(enumerator.Current.Tags, writer); + await writer.WriteAsync(COMMA).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + await writer.WriteAsync(COLON).ConfigureAwait(false); + await SerializeTagsLogicAsync(enumerator.Current.Tags, writer).ConfigureAwait(false); } - await writer.WriteAsync(CLOSE_BRACE); + await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); } - await writer.WriteAsync("]"); + await writer.WriteAsync("]").ConfigureAwait(false); } catch (InvalidOperationException) { diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs index 237df5d77c..0f0f02b923 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -28,7 +28,7 @@ public virtual async Task ProcessAsync(Activity activity, InstanaSpan instanaSpa { if (this.NextProcessor != null) { - await this.NextProcessor.ProcessAsync(activity, instanaSpan); + await this.NextProcessor.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs index f4d5a70345..d1a6b566d0 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -62,7 +62,7 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.Tp = true; } - await base.ProcessAsync(activity, instanaSpan); + await base.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); } private static SpanKind GetSpanKind(ActivityKind activityKind) diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs index 5c04e91584..5d5fc3a95d 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs @@ -43,6 +43,6 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.Ec = 0; } - await base.ProcessAsync(activity, instanaSpan); + await base.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs index d0e7bb7edb..c4b4f6ae31 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -51,6 +51,6 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.Data.Events.Add(spanEvent); } - await base.ProcessAsync(activity, instanaSpan); + await base.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs index 1f868bdb30..af1e53dd64 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -53,6 +53,6 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.TransformInfo.StatusCode = statusCode; instanaSpan.TransformInfo.StatusDesc = statusDesc; - await base.ProcessAsync(activity, instanaSpan); + await base.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index 5e79e63a10..6b4f89e390 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -18,10 +18,11 @@ namespace OpenTelemetry.Exporter.Instana.Implementation; -internal class SpanSender : ISpanSender +#pragma warning disable CA1001 // Types that own disposable fields should be disposable +internal sealed class SpanSender : ISpanSender +#pragma warning restore CA1001 // Types that own disposable fields should be disposable { private readonly Task queueSenderTask; - private readonly Transport transport = new Transport(); private readonly ConcurrentQueue spansQueue = new ConcurrentQueue(); public SpanSender() @@ -33,7 +34,7 @@ public SpanSender() public void Enqueue(InstanaSpan instanaSpan) { - if (this.transport.IsAvailable) + if (Transport.IsAvailable) { this.spansQueue.Enqueue(instanaSpan); } @@ -48,11 +49,11 @@ private async void TaskSpanSender() if (this.spansQueue.TryPeek(out InstanaSpan _)) { // actually send spans - await this.transport.SendSpansAsync(this.spansQueue); + await Transport.SendSpansAsync(this.spansQueue).ConfigureAwait(false); } // rest for a while - await Task.Delay(1000); + await Task.Delay(1000).ConfigureAwait(false); } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index 9a95393fc7..87e98f277f 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Concurrent; +using System.Globalization; using System.IO; using System.Net; using System.Net.Http; @@ -24,31 +25,30 @@ namespace OpenTelemetry.Exporter.Instana.Implementation; -internal class Transport +internal static class Transport { private const int MultiSpanBufferLimit = 4096000; - private static readonly InstanaSpanSerializer InstanaSpanSerializer = new InstanaSpanSerializer(); private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); - private static bool isConfigured = false; - private static int backendTimeout = 0; + private static bool isConfigured; + private static int backendTimeout; private static string configuredEndpoint = string.Empty; private static string configuredAgentKey = string.Empty; private static string bundleUrl = string.Empty; - private static InstanaHttpClient client = null; + private static InstanaHttpClient client; static Transport() { Configure(); } - internal bool IsAvailable + internal static bool IsAvailable { get { return isConfigured && client != null; } } - internal async Task SendSpansAsync(ConcurrentQueue spanQueue) + internal static async Task SendSpansAsync(ConcurrentQueue spanQueue) { try { @@ -56,14 +56,14 @@ internal async Task SendSpansAsync(ConcurrentQueue spanQueue) { using (StreamWriter writer = new StreamWriter(sendBuffer)) { - await writer.WriteAsync("{\"spans\":["); + await writer.WriteAsync("{\"spans\":[").ConfigureAwait(false); bool first = true; // peek instead of dequeue, because we don't yet know whether the next span // fits within our MULTI_SPAN_BUFFER_LIMIT while (spanQueue.TryPeek(out InstanaSpan span)) { - var serialized = await InstanaSpanSerializer.SerializeToByteArrayAsync(span); + var serialized = await InstanaSpanSerializer.SerializeToByteArrayAsync(span).ConfigureAwait(false); if (!first) { @@ -72,27 +72,27 @@ internal async Task SendSpansAsync(ConcurrentQueue spanQueue) break; } - await writer.WriteAsync(","); + await writer.WriteAsync(",").ConfigureAwait(false); } first = false; - await sendBuffer.WriteAsync(serialized, 0, serialized.Length); + await sendBuffer.WriteAsync(serialized, 0, serialized.Length).ConfigureAwait(false); // Now we can dequeue. Note, this means we'll be giving up/losing // this span if we fail to send for any reason. spanQueue.TryDequeue(out _); } - await writer.WriteAsync("]}"); + await writer.WriteAsync("]}").ConfigureAwait(false); - await writer.FlushAsync(); + await writer.FlushAsync().ConfigureAwait(false); long length = sendBuffer.Position; sendBuffer.Position = 0; HttpContent content = new StreamContent(sendBuffer, (int)length); content.Headers.ContentType = MEDIAHEADER; - content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); + content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(CultureInfo.InvariantCulture)); using (var httpMsg = new HttpRequestMessage() { @@ -101,7 +101,7 @@ internal async Task SendSpansAsync(ConcurrentQueue spanQueue) }) { httpMsg.Content = content; - await client.SendAsync(httpMsg); + await client.SendAsync(httpMsg).ConfigureAwait(false); } } } @@ -160,7 +160,9 @@ private static void ConfigureBackendClient() return; } +#pragma warning disable CA2000 var configuredHandler = new HttpClientHandler(); +#pragma warning restore CA2000 string proxy = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_PROXY); if (Uri.TryCreate(proxy, UriKind.Absolute, out Uri proxyAddress)) { @@ -171,7 +173,9 @@ private static void ConfigureBackendClient() #pragma warning restore SA1130 // Use lambda syntax } +#pragma warning disable CA5400 client = new InstanaHttpClient(backendTimeout, configuredHandler); +#pragma warning restore CA5400 client.DefaultRequestHeaders.Add("X-INSTANA-KEY", configuredAgentKey); } diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index b9d5c44ac0..917604d0f3 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -16,6 +16,7 @@ using System; using System.Diagnostics; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using OpenTelemetry.Exporter.Instana.Implementation; @@ -30,7 +31,7 @@ internal class InstanaExporter : BaseExporter private string name; private ISpanSender spanSender = new SpanSender(); private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); - private bool shutdownCalled = false; + private bool shutdownCalled; public InstanaExporter(string name = "InstanaExporter", IActivityProcessor activityProcessor = null) { @@ -77,7 +78,7 @@ public override ExportResult Export(in Batch batch) From from = null; if (this.instanaExporterHelper.IsWindows()) { - from = new From() { E = Process.GetCurrentProcess().Id.ToString() }; + from = new From() { E = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture) }; } string serviceName = this.ExtractServiceName(ref from); @@ -175,7 +176,7 @@ private async Task ParseActivityAsync(Activity activity, string ser { InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); - await this.activityProcessor.ProcessAsync(activity, instanaSpan); + await this.activityProcessor.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); if (!string.IsNullOrEmpty(serviceName)) { diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs index a830904a4a..4b917811f2 100644 --- a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -37,6 +37,8 @@ public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilde throw new ArgumentNullException(nameof(options)); } +#pragma warning disable CA2000 // Dispose objects before losing scope return options.AddProcessor(new BatchActivityExportProcessor(new InstanaExporter())); +#pragma warning restore CA2000 // Dispose objects before losing scope } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index 07a5c5c053..0381a473e1 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -30,8 +30,8 @@ public class InstanaExporterTests private readonly Mock instanaExporterHelperMock = new Mock(MockBehavior.Strict); private readonly Mock activityProcessorMock = new Mock(MockBehavior.Strict); private readonly Mock spanSenderMock = new Mock(MockBehavior.Strict); - private InstanaSpan instanaSpan = null; - private InstanaExporter instanaExporter = null; + private InstanaSpan instanaSpan; + private InstanaExporter instanaExporter; [Fact] public void Export() diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs index fc49bf5ad5..f6fd0b3945 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs @@ -19,13 +19,12 @@ namespace OpenTelemetry.Exporter.Instana.Tests; -public class InstanaSpanFactoryTests +public static class InstanaSpanFactoryTests { - private InstanaSpanFactory instanaSpanFactory = new InstanaSpanFactory(); - [Fact] - public void CreateSpan() + public static void CreateSpan() { + _ = new InstanaSpanFactory(); InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); Assert.NotNull(instanaSpan); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 0dcdf4eb2a..a5b3385244 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -24,12 +24,10 @@ namespace OpenTelemetry.Exporter.Instana.Tests; -public class InstanaSpanSerializerTests +public static class InstanaSpanSerializerTests { - private InstanaSpanSerializer instanaSpanSerializer = new InstanaSpanSerializer(); - [Fact] - public async Task SerializeToStreamWriterAsync() + public static async Task SerializeToStreamWriterAsync() { InstanaSpan instanaOtelSpan = InstanaSpanFactory.CreateSpan(); instanaOtelSpan.F = new Implementation.From() { E = "12345", H = "localhost" }; @@ -66,14 +64,14 @@ public async Task SerializeToStreamWriterAsync() { using (StreamWriter writer = new StreamWriter(sendBuffer)) { - await this.instanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); + await InstanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); await writer.FlushAsync(); long length = sendBuffer.Position; sendBuffer.Position = 0; sendBuffer.SetLength(length); - Newtonsoft.Json.JsonSerializer serializer = null; - serializer = new Newtonsoft.Json.JsonSerializer(); + JsonSerializer serializer = null; + serializer = new JsonSerializer(); serializer.Converters.Add(new JavaScriptDateTimeConverter()); serializer.NullValueHandling = NullValueHandling.Ignore; From 4bfba0f39478f34c9bb9a43019eb745e165fcff4 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 9 Feb 2023 16:20:05 -0800 Subject: [PATCH 0543/1499] Add new project `OpenTelemetry.ResourceDetectors.Azure` (#987) --- .github/component_owners.yml | 3 ++ .../package-ResourceDetectors.Azure.yml | 53 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 7 +++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../CHANGELOG.md | 5 ++ ...enTelemetry.ResourceDetectors.Azure.csproj | 18 +++++++ .../README.md | 3 ++ 8 files changed, 90 insertions(+) create mode 100644 .github/workflows/package-ResourceDetectors.Azure.yml create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/README.md diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 924a5041d6..02ffc013ab 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -55,6 +55,9 @@ components: - xiang17 src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch + src/OpenTelemetry.ResourceDetectors.Azure/: + - rajkumar-rangaraj + - vishweshbankwar test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml new file mode 100644 index 0000000000..f3d11736c9 --- /dev/null +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -0,0 +1,53 @@ +name: Pack OpenTelemetry.ResourceDetectors.Azure + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'ResourceDetectors.Azure-*' # trigger when we create a tag with prefix "ResourceDetectors.Azure-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.ResourceDetectors.Azure + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 06bde9480e..63ab84dba1 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -239,6 +239,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "process-instrumentation", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventCounters", "examples\event-counters\Examples.EventCounters\Examples.EventCounters.csproj", "{BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure", "src\OpenTelemetry.ResourceDetectors.Azure\OpenTelemetry.ResourceDetectors.Azure.csproj", "{B07DC3CB-F724-40A5-889A-DA6601F462F3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -501,6 +503,10 @@ Global {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Debug|Any CPU.Build.0 = Debug|Any CPU {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Release|Any CPU.ActiveCfg = Release|Any CPU {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Release|Any CPU.Build.0 = Release|Any CPU + {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -578,6 +584,7 @@ Global {B40B975E-78B2-4712-8B4D-BADA67DF0C0A} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {B07DC3CB-F724-40A5-889A-DA6601F462F3} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md new file mode 100644 index 0000000000..a99ef6f9cf --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj new file mode 100644 index 0000000000..5e01a9570a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -0,0 +1,18 @@ + + + netstandard2.0 + OpenTelemetry Resource Detectors for Azure cloud environments + $(PackageTags);ResourceDetector + ResourceDetectors.Azure- + true + enable + + + + + + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md new file mode 100644 index 0000000000..3389bf6c6a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -0,0 +1,3 @@ +# Resource Detectors for Azure cloud environments + +TODO From 948fcc26a68777b5e5c31386c257afd4666e39ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 10 Feb 2023 18:18:48 +0100 Subject: [PATCH 0544/1499] Create GitHub releases (#986) --- .github/workflows/package-Exporter.Geneva.yml | 14 ++++++++++++++ .github/workflows/package-Exporter.Instana.yml | 14 ++++++++++++++ .github/workflows/package-Exporter.Stackdriver.yml | 14 ++++++++++++++ .github/workflows/package-Extensions.AWSXRay.yml | 14 ++++++++++++++ .../workflows/package-Extensions.AzureMonitor.yml | 14 ++++++++++++++ .github/workflows/package-Extensions.Docker.yml | 14 ++++++++++++++ ...e-Extensions.PersistentStorage.Abstractions.yml | 14 ++++++++++++++ .../package-Extensions.PersistentStorage.yml | 14 ++++++++++++++ .github/workflows/package-Extensions.yml | 14 ++++++++++++++ .github/workflows/package-Instrumentation.AWS.yml | 14 ++++++++++++++ .../package-Instrumentation.AWSLambda.yml | 14 ++++++++++++++ ...-Instrumentation.AspNet.TelemetryHttpModule.yml | 14 ++++++++++++++ .../workflows/package-Instrumentation.AspNet.yml | 14 ++++++++++++++ .../package-Instrumentation.Elasticsearch.yml | 14 ++++++++++++++ ...package-Instrumentation.EntityFrameworkCore.yml | 14 ++++++++++++++ .../package-Instrumentation.EventCounters.yml | 14 ++++++++++++++ .../workflows/package-Instrumentation.GrpcCore.yml | 14 ++++++++++++++ .../workflows/package-Instrumentation.Hangfire.yml | 14 ++++++++++++++ .../package-Instrumentation.MySqlData.yml | 14 ++++++++++++++ .github/workflows/package-Instrumentation.Owin.yml | 14 ++++++++++++++ .../workflows/package-Instrumentation.Process.yml | 14 ++++++++++++++ .../workflows/package-Instrumentation.Quartz.yml | 14 ++++++++++++++ .../workflows/package-Instrumentation.Runtime.yml | 14 ++++++++++++++ .../package-Instrumentation.StackExchangeRedis.yml | 14 ++++++++++++++ .github/workflows/package-Instrumentation.Wcf.yml | 14 ++++++++++++++ .../workflows/package-ResourceDetectors.Azure.yml | 14 ++++++++++++++ build/RELEASING.md | 9 ++++++--- 27 files changed, 370 insertions(+), 3 deletions(-) diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index 6b4d803781..763212c293 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Exporter.Geneva @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index 4f20810a38..4e3aa0cc77 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Exporter.Instana @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index bc7cd8fa47..f3a62de95c 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Exporter.Stackdriver @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index ee9a452ccc..dd9f35b59d 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Contrib.Extensions.AWSXRay @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml index 09e65c4415..2107d1d587 100644 --- a/.github/workflows/package-Extensions.AzureMonitor.yml +++ b/.github/workflows/package-Extensions.AzureMonitor.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Extensions.AzureMonitor @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Extensions.Docker.yml b/.github/workflows/package-Extensions.Docker.yml index b01c1531e4..cdb3390e4c 100644 --- a/.github/workflows/package-Extensions.Docker.yml +++ b/.github/workflows/package-Extensions.Docker.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Extensions.Docker @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml index 5dfda8ee88..afdff942ae 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Extensions.PersistentStorage.Abstractions @@ -48,3 +50,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-Extensions.PersistentStorage.yml index 261c050c35..0d24fef3a1 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-Extensions.PersistentStorage.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Extensions.PersistentStorage @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index bdd2aae165..07cd334e96 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Extensions @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index 9f1957330c..12b140a9a4 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Contrib.Instrumentation.AWS @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 2f5a3d4d81..38ff751d3c 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.AWSLambda @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 79ca5ae17a..80a248c6bb 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 1b36bc2d3b..7f17792934 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.AspNet @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 1e58ea7d39..41d72e55a8 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.ElasticsearchClient @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 398a2cf207..7a182d5148 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.EntityFrameworkCore @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index 7000480019..94ecd0feac 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.EventCounters @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index b02ffb88ba..2c8f515af9 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.GrpcCore @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index 254581d38e..d8a146426d 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.Hangfire @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index e55946a334..e8e524b2ae 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.MySqlData @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index a57168293f..b5a38a4aed 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.Owin @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index 51cc397bc5..a94f937909 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.Process @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index c69be134c1..7625a96310 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.Quartz @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index 00d7acdd24..8a67ce59e8 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.Runtime @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index e4ee6dac1c..71a82604e2 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.StackExchangeRedis @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index b9c2cd41af..119864f124 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.Instrumentation.Wcf @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml index f3d11736c9..7191c14468 100644 --- a/.github/workflows/package-ResourceDetectors.Azure.yml +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -14,6 +14,8 @@ on: jobs: build-test-pack: runs-on: ${{ matrix.os }} + permissions: + contents: write env: PROJECT: OpenTelemetry.ResourceDetectors.Azure @@ -51,3 +53,15 @@ jobs: - name: Publish Nuget run: | nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build/RELEASING.md b/build/RELEASING.md index e6a0cb1b9a..476d75c824 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -34,7 +34,7 @@ on the `main` branch is the one which added/updated the Changelog to the project being released. *This latest commit will be tagged on the release.* 1. Create and push git tag for the project and the version of the project -you want to release. The version shoud the one used in the **Pre-steps** to +you want to release. The version should be the one used in the **Pre-steps** to update the Changelog. ```powershell @@ -68,7 +68,10 @@ update the Changelog. 2. Navigate to the [**Actions**](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions) tab on the repo and monitor the "Pack YOUR_PROJECT_NAME" workflow. The last step -in the workflow is to publish to Nuget.org. +in the workflow is to publish to Nuget.org and prepare corresponding github +release page. -3. Validate that the new version (as specified in step1) of the project is +3. Validate that the new version (as specified in step 1) of the project is successfully published to nuget.org under OpenTelemetry owner. + +4. Validate that the new version was published in GitHub. From 218d541f732e513658dae895c09e69be92392932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 10 Feb 2023 20:08:53 +0100 Subject: [PATCH 0545/1499] typo fix (#988) Co-authored-by: Cijo Thomas --- .../TelemetryHttpModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index 2b9455bca1..2ad4514574 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -66,7 +66,7 @@ public void Init(HttpApplication context) if (HttpRuntime.UsingIntegratedPipeline && OnExecuteRequestStepMethodInfo != null) { - // OnExecuteRequestStep is availabile starting with 4.7.1 + // OnExecuteRequestStep is available starting with 4.7.1 try { OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action)this.OnExecuteRequestStep }); From ac6daa4ec29faaba1c330d7f8fe635d980650bbf Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 10 Feb 2023 13:56:50 -0800 Subject: [PATCH 0546/1499] [ResourceDetectors.Azure] AppService resource detector (#989) --- .github/component_owners.yml | 3 + opentelemetry-dotnet-contrib.sln | 7 ++ .../Api/ResourceSemanticConventions.cs | 64 +++++++++++++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 3 + .../AppServiceResourceDetector.cs | 60 +++++++++++++++++ .../AssemblyInfo.cs | 22 +++++++ .../CHANGELOG.md | 3 + ...enTelemetry.ResourceDetectors.Azure.csproj | 3 +- .../AzureResourceDetectorTests.cs | 49 ++++++++++++++ ...metry.ResourceDetectors.Azure.Tests.csproj | 21 ++++++ 10 files changed, 234 insertions(+), 1 deletion(-) create mode 100644 src/OpenTelemetry.Contrib.Shared/Api/ResourceSemanticConventions.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs create mode 100644 test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs create mode 100644 test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 02ffc013ab..1cd3298842 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -117,3 +117,6 @@ components: - xiang17 test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch + test/OpenTelemetry.ResourceDetectors.Azure.Tests/: + - rajkumar-rangaraj + - vishweshbankwar diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 63ab84dba1..87559b7581 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -241,6 +241,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventCounters", "e EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure", "src\OpenTelemetry.ResourceDetectors.Azure\OpenTelemetry.ResourceDetectors.Azure.csproj", "{B07DC3CB-F724-40A5-889A-DA6601F462F3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure.Tests", "test\OpenTelemetry.ResourceDetectors.Azure.Tests\OpenTelemetry.ResourceDetectors.Azure.Tests.csproj", "{DFC6A4A9-5262-4507-B747-CC6B814205E6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -507,6 +509,10 @@ Global {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Release|Any CPU.Build.0 = Release|Any CPU + {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -585,6 +591,7 @@ Global {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {B07DC3CB-F724-40A5-889A-DA6601F462F3} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {DFC6A4A9-5262-4507-B747-CC6B814205E6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ResourceSemanticConventions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ResourceSemanticConventions.cs new file mode 100644 index 0000000000..3d0adc5073 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Shared/Api/ResourceSemanticConventions.cs @@ -0,0 +1,64 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Trace; + +internal static class ResourceSemanticConventions +{ + public const string AttributeServiceName = "service.name"; + public const string AttributeServiceNamespace = "service.namespace"; + public const string AttributeServiceInstance = "service.instance.id"; + public const string AttributeServiceVersion = "service.version"; + + public const string AttributeTelemetrySdkName = "telemetry.sdk.name"; + public const string AttributeTelemetrySdkLanguage = "telemetry.sdk.language"; + public const string AttributeTelemetrySdkVersion = "telemetry.sdk.version"; + + public const string AttributeContainerName = "container.name"; + public const string AttributeContainerImage = "container.image.name"; + public const string AttributeContainerTag = "container.image.tag"; + + public const string AttributeFaasName = "faas.name"; + public const string AttributeFaasId = "faas.id"; + public const string AttributeFaasVersion = "faas.version"; + public const string AttributeFaasInstance = "faas.instance"; + + public const string AttributeK8sCluster = "k8s.cluster.name"; + public const string AttributeK8sNamespace = "k8s.namespace.name"; + public const string AttributeK8sPod = "k8s.pod.name"; + public const string AttributeK8sDeployment = "k8s.deployment.name"; + + public const string AttributeHostHostname = "host.hostname"; + public const string AttributeHostId = "host.id"; + public const string AttributeHostName = "host.name"; + public const string AttributeHostType = "host.type"; + public const string AttributeHostImageName = "host.image.name"; + public const string AttributeHostImageId = "host.image.id"; + public const string AttributeHostImageVersion = "host.image.version"; + + public const string AttributeProcessId = "process.id"; + public const string AttributeProcessExecutableName = "process.executable.name"; + public const string AttributeProcessExecutablePath = "process.executable.path"; + public const string AttributeProcessCommand = "process.command"; + public const string AttributeProcessCommandLine = "process.command_line"; + public const string AttributeProcessUsername = "process.username"; + + public const string AttributeCloudProvider = "cloud.provider"; + public const string AttributeCloudAccount = "cloud.account.id"; + public const string AttributeCloudRegion = "cloud.region"; + public const string AttributeCloudZone = "cloud.zone"; + public const string AttributeComponent = "component"; +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..6388753f6e 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource? \ No newline at end of file diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs new file mode 100644 index 0000000000..e9ed7bbf43 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -0,0 +1,60 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.ResourceDetectors.Azure; + +/// +/// Resource detector for Azure AppService environment. +/// +public sealed class AppServiceResourceDetector : IResourceDetector +{ + /// + public Resource? Detect() + { + string? serviceName = null; + try + { + // https://learn.microsoft.com/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet#app-environment + serviceName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); + } + catch + { + // TODO: log exception. + } + + List>? attributeList = null; + + if (serviceName != null) + { + attributeList = new(); + + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, serviceName)); + + // TODO: Add other attributes e.g. service.instance.id + } + else + { + return Resource.Empty; + } + + return new Resource(attributeList); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs new file mode 100644 index 0000000000..1b065a4d99 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Azure.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Azure.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index a99ef6f9cf..ef8912a5bc 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,4 +2,7 @@ ## Unreleased +* Add AppService resource detector. +([#989](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/989)) + For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index 5e01a9570a..cb303071bf 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 OpenTelemetry Resource Detectors for Azure cloud environments @@ -14,5 +14,6 @@ + diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs new file mode 100644 index 0000000000..a785f9b133 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.ResourceDetectors.Azure.Tests; + +public class AzureResourceDetectorTests +{ + [Fact] + public void AppServiceResourceDetectorReturnsResourceWithAttributes() + { + try + { + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "AzureAppService"); + var resource = ResourceBuilder.CreateEmpty().AddDetector(new AppServiceResourceDetector()).Build(); + Assert.NotNull(resource); + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "AzureAppService"), resource.Attributes); + } + finally + { + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", null); + } + } + + [Fact] + public void AppServiceResourceDetectorReturnsNullOutsideOfAppService() + { + var resource = new AppServiceResourceDetector().Detect(); + Assert.Empty(resource.Attributes); + } +} diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj new file mode 100644 index 0000000000..feec95205c --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj @@ -0,0 +1,21 @@ + + + + + net7.0;net6.0; + $(TargetFrameworks);net462 + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + From cb6f4fe1b139e6fa469b11ca9b76993c95d14aa0 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 10 Feb 2023 22:59:28 +0000 Subject: [PATCH 0547/1499] [Extensions.Docker] Fix analysis warnings (#957) --- .../Resources/DockerResourceDetector.cs | 96 +++++++++---------- .../Resources/DockerResourceDetectorTests.cs | 6 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs index a589117d37..e1eee6ac64 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs @@ -83,56 +83,12 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) } } - /// - /// Extracts Container Id from path using the cgroupv1 format. - /// - /// cgroup path. - /// CGroup Version of file to parse from. - /// Container Id, Null if not found or exception being thrown. - private string ExtractContainerId(string path, ParseMode cgroupVersion) - { - try - { - if (!File.Exists(path)) - { - return null; - } - - foreach (string line in File.ReadLines(path)) - { - string containerId = null; - if (!string.IsNullOrEmpty(line)) - { - if (cgroupVersion == ParseMode.V1) - { - containerId = this.GetIdFromLineV1(line); - } - else if (cgroupVersion == ParseMode.V2 && line.Contains(HOSTNAME)) - { - containerId = this.GetIdFromLineV2(line); - } - } - - if (!string.IsNullOrEmpty(containerId)) - { - return containerId; - } - } - } - catch (Exception ex) - { - DockerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(DockerResourceDetector)} : Failed to extract Container id from path", ex); - } - - return null; - } - /// /// Gets the Container Id from the line after removing the prefix and suffix from the cgroupv1 format. /// /// line read from cgroup file. /// Container Id, Null if not found. - private string GetIdFromLineV1(string line) + private static string GetIdFromLineV1(string line) { // This cgroup output line should have the container id in it int lastSlashIndex = line.LastIndexOf('/'); @@ -145,7 +101,7 @@ private string GetIdFromLineV1(string line) int startIndex = lastSection.LastIndexOf('-'); int endIndex = lastSection.LastIndexOf('.'); - string containerId = this.RemovePrefixAndSuffixIfneeded(lastSection, startIndex, endIndex); + string containerId = RemovePrefixAndSuffixIfneeded(lastSection, startIndex, endIndex); if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) { @@ -160,7 +116,7 @@ private string GetIdFromLineV1(string line) /// /// line read from cgroup file. /// Container Id, Null if not found. - private string GetIdFromLineV2(string line) + private static string GetIdFromLineV2(string line) { string containerId = null; var match = Regex.Match(line, @".*/.+/([\w+-.]{64})/.*$"); @@ -177,7 +133,7 @@ private string GetIdFromLineV2(string line) return containerId; } - private string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) + private static string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) { startIndex = (startIndex == -1) ? 0 : startIndex + 1; @@ -188,4 +144,48 @@ private string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int e return input.Substring(startIndex, endIndex - startIndex); } + + /// + /// Extracts Container Id from path using the cgroupv1 format. + /// + /// cgroup path. + /// CGroup Version of file to parse from. + /// Container Id, Null if not found or exception being thrown. + private string ExtractContainerId(string path, ParseMode cgroupVersion) + { + try + { + if (!File.Exists(path)) + { + return null; + } + + foreach (string line in File.ReadLines(path)) + { + string containerId = null; + if (!string.IsNullOrEmpty(line)) + { + if (cgroupVersion == ParseMode.V1) + { + containerId = GetIdFromLineV1(line); + } + else if (cgroupVersion == ParseMode.V2 && line.Contains(HOSTNAME)) + { + containerId = GetIdFromLineV2(line); + } + } + + if (!string.IsNullOrEmpty(containerId)) + { + return containerId; + } + } + } + catch (Exception ex) + { + DockerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(DockerResourceDetector)} : Failed to extract Container id from path", ex); + } + + return null; + } } diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs index 5c50045727..c5b6120819 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs +++ b/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs @@ -131,7 +131,7 @@ public void TestValidContainer() tempFile.Write(testCase.Line); Assert.Equal( testCase.ExpectedContainerId, - this.GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion))); + GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion))); } } @@ -173,13 +173,13 @@ public void TestInvalidContainer() Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath(), DockerResourceDetector.ParseMode.V2), Resource.Empty); } - private string GetContainerId(Resource resource) + private static string GetContainerId(Resource resource) { var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); return resourceAttributes[DockerSemanticConventions.AttributeContainerID]?.ToString(); } - private class TestCase + private sealed class TestCase { public string Name { get; set; } From 303485e3a9fc6f86ca85faa25980795f7cc48482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 13 Feb 2023 17:01:29 +0100 Subject: [PATCH 0548/1499] Bump OTel to 1.4.0-rc.4 (#990) --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index d4a67da1b6..2a42cbf61f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -32,7 +32,7 @@ [3.3.3] [1.1.1,2.0) [1.3.2,2.0) - [1.4.0-rc.3] + [1.4.0-rc.4] [2.1.58,3.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index e8d7203281..f2c164b407 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0-rc.4 + ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) + ## 1.4.0-rc.3 Released 2023-Feb-08 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index ef751909e4..eef4594df2 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +* Update OpenTelemetry to 1.4.0-rc.4 + ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) + ## Unreleased * Update OpenTelemetry to 1.4.0-rc.3 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 1a4619c826..99d23a5f79 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.4 + ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) + * Removed CPU utilization metric `process.cpu.utilization`. ([#972](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/972)) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index fbbea3d993..06739bef1a 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0-rc.4 + ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) + ## 1.1.0-beta.4 Released 2023-Feb-02 From e1312f9fbb7b24aa9122e17859229737b7c3fe90 Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Mon, 13 Feb 2023 17:44:16 +0100 Subject: [PATCH 0549/1499] [Instana Exporter] Wrong JSON format for serialized spans (#979) --- .../CHANGELOG.md | 2 ++ .../Implementation/InstanaSpanSerializer.cs | 11 ------- .../Implementation/Transport.cs | 30 ++++++++----------- .../OpenTelemetry.Exporter.Instana.csproj | 2 +- 4 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 1187d12358..6aa0f0db0f 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Fixes issue in span serialization process introduced in 1.0.2 version. + ([#979](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/979)) * Update OTel SDK version to `1.3.2`. ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 35dfa433ef..c6f45e4f43 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -47,17 +47,6 @@ internal static IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) return instanaSpan.Data.Events.GetEnumerator(); } - internal static async Task SerializeToByteArrayAsync(InstanaSpan instanaSpan) - { - using var stream = new MemoryStream(); - using var writer = new StreamWriter(stream); - - await SerializeToStreamWriterAsync(instanaSpan, writer).ConfigureAwait(false); - - await writer.FlushAsync().ConfigureAwait(false); - return stream.ToArray(); - } - internal static async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, StreamWriter writer) { await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index 87e98f277f..56f6a257ae 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -27,12 +27,12 @@ namespace OpenTelemetry.Exporter.Instana.Implementation; internal static class Transport { - private const int MultiSpanBufferLimit = 4096000; - + private const int MultiSpanBufferSize = 4096000; + private const int MultiSpanBufferLimit = 4070000; private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); - - private static bool isConfigured; - private static int backendTimeout; + private static readonly byte[] TracesBuffer; + private static bool isConfigured = false; + private static int backendTimeout = 0; private static string configuredEndpoint = string.Empty; private static string configuredAgentKey = string.Empty; private static string bundleUrl = string.Empty; @@ -40,6 +40,7 @@ internal static class Transport static Transport() { + TracesBuffer = new byte[MultiSpanBufferSize]; Configure(); } @@ -52,7 +53,7 @@ internal static async Task SendSpansAsync(ConcurrentQueue spanQueue { try { - using (MemoryStream sendBuffer = new MemoryStream()) + using (MemoryStream sendBuffer = new MemoryStream(TracesBuffer)) { using (StreamWriter writer = new StreamWriter(sendBuffer)) { @@ -61,23 +62,17 @@ internal static async Task SendSpansAsync(ConcurrentQueue spanQueue // peek instead of dequeue, because we don't yet know whether the next span // fits within our MULTI_SPAN_BUFFER_LIMIT - while (spanQueue.TryPeek(out InstanaSpan span)) + while (spanQueue.TryPeek(out InstanaSpan span) && sendBuffer.Position < MultiSpanBufferLimit) { - var serialized = await InstanaSpanSerializer.SerializeToByteArrayAsync(span).ConfigureAwait(false); - if (!first) { - if (sendBuffer.Length + serialized.Length > MultiSpanBufferLimit) - { - break; - } - await writer.WriteAsync(",").ConfigureAwait(false); } - first = false; + await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer).ConfigureAwait(false); + await writer.FlushAsync().ConfigureAwait(false); - await sendBuffer.WriteAsync(serialized, 0, serialized.Length).ConfigureAwait(false); + first = false; // Now we can dequeue. Note, this means we'll be giving up/losing // this span if we fail to send for any reason. @@ -85,10 +80,11 @@ internal static async Task SendSpansAsync(ConcurrentQueue spanQueue } await writer.WriteAsync("]}").ConfigureAwait(false); - await writer.FlushAsync().ConfigureAwait(false); + long length = sendBuffer.Position; sendBuffer.Position = 0; + sendBuffer.SetLength(length); HttpContent content = new StreamContent(sendBuffer, (int)length); content.Headers.ContentType = MEDIAHEADER; diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 769f3aed09..5725bf828c 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net461 From f64ea3476ce5f6d0ce3554a8d2257b16e15fd0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 13 Feb 2023 22:17:43 +0100 Subject: [PATCH 0550/1499] Allow to use further releases of OTel for prerelease version (#994) --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index 2a42cbf61f..52d940a9e5 100644 --- a/build/Common.props +++ b/build/Common.props @@ -32,7 +32,7 @@ [3.3.3] [1.1.1,2.0) [1.3.2,2.0) - [1.4.0-rc.4] + [1.4.0-rc.4,2.0) [2.1.58,3.0) [1.2.0-beta.435,2.0) From c736768caff8b5bbf82044272c7c7b1b676a4189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 14 Feb 2023 00:52:50 +0100 Subject: [PATCH 0551/1499] [Instrumentation.Process, Instrumentation.Runtime] Release wtih OTel 1.4.0-rc.4 (#993) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 99d23a5f79..280d11a7cd 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.6 + +Released 2023-Feb-13 + * Update OpenTelemetry API to 1.4.0-rc.4 ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 06739bef1a..7e79d03ad0 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-rc.1 + +Released 2023-Feb-13 + * Update OpenTelemetry API to 1.4.0-rc.4 ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) From cff21ce542f6298d509318909ffc70503b9639f3 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 14 Feb 2023 05:58:36 +0530 Subject: [PATCH 0552/1499] Update changelog for Exporter.Geneva release (#997) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f2c164b407..923cfb709d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-rc.4 + +Released 2023-Feb-13 + * Update OpenTelemetry to 1.4.0-rc.4 ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) From d0c0993a367a4066616e3f77cf3cf6b58ebb8404 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 13 Feb 2023 16:39:09 -0800 Subject: [PATCH 0553/1499] fix typo (#996) Co-authored-by: Cijo Thomas --- .github/workflows/integration-md.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index ff74c117b5..a248d6ccb0 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -3,7 +3,7 @@ name: Integration Tests on: push: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: + paths: - '**.md' pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] From 13b28723bc6633fa84ee616a3e69af191ea0bce4 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 13 Feb 2023 16:53:27 -0800 Subject: [PATCH 0554/1499] First step towards decoupling the CI (#995) * first step towards decoupling the CI * polish * polish * cleanup * trigger ci * try different names * revert * cleanup --- .../workflows/ci-Instrumentation.Process.yml | 41 +++++++++++++++++++ .github/workflows/ci.yml | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-Instrumentation.Process.yml diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml new file mode 100644 index 0000000000..a70559dc53 --- /dev/null +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -0,0 +1,41 @@ +name: OpenTelemetry.Instrumentation.Process + +on: + pull_request: + branches: [ 'main*' ] + paths: + - 'src/OpenTelemetry.Instrumentation.Process/**' + - 'test/OpenTelemetry.Instrumentation.Process.Tests/**' + +jobs: + build-test: + + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + os: [ windows-latest, ubuntu-latest ] + version: [ net462, netcoreapp3.1, net6.0, net7.0 ] + exclude: + - os: ubuntu-latest + version: net462 + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + + - name: Install .NET 3.1 SDK + uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '3.1.x' + + - name: Install .NET 7 SDK + uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Build + run: dotnet build --configuration Release test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj + + - name: Test ${{ matrix.version }} + run: dotnet test test/OpenTelemetry.Instrumentatio + n.Process.Tests/bin/Release/${{ matrix.version }}/OpenTelemetry.Instrumentation.Process.Tests.dll --logger:"console;verbosity=detailed" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74e5c18d24..f8ef6da230 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,4 +43,4 @@ jobs: run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **/bin/**/${{ matrix.version }}/*Tests.dll --configuration Release --no-build --logger:"console;verbosity=detailed" + run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --logger:"console;verbosity=detailed" From 22e6a018ee2ff95a83f4a5d0844bee239c7add8f Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 13 Feb 2023 20:12:36 -0800 Subject: [PATCH 0555/1499] Improve CI workflow (#998) --- .../workflows/ci-Instrumentation.Process.yml | 21 ++++++++----------- .../CHANGELOG.md | 2 ++ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index a70559dc53..7de64e9e77 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -1,4 +1,4 @@ -name: OpenTelemetry.Instrumentation.Process +name: Instrumentation.Process on: pull_request: @@ -7,17 +7,15 @@ on: - 'src/OpenTelemetry.Instrumentation.Process/**' - 'test/OpenTelemetry.Instrumentation.Process.Tests/**' -jobs: - build-test: +env: + COMPONENT_NAME: OpenTelemetry.Instrumentation.Process +jobs: + unit-test: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, netcoreapp3.1, net6.0, net7.0 ] - exclude: - - os: ubuntu-latest - version: net462 + os: [ ubuntu-latest, windows-latest ] runs-on: ${{ matrix.os }} steps: @@ -34,8 +32,7 @@ jobs: dotnet-version: '7.0.x' - name: Build - run: dotnet build --configuration Release test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj + run: dotnet build --configuration Release test/${{ env.COMPONENT_NAME }}.Tests/${{ env.COMPONENT_NAME }}.Tests.csproj - - name: Test ${{ matrix.version }} - run: dotnet test test/OpenTelemetry.Instrumentatio - n.Process.Tests/bin/Release/${{ matrix.version }}/OpenTelemetry.Instrumentation.Process.Tests.dll --logger:"console;verbosity=detailed" + - name: Test + run: dotnet test test/${{ env.COMPONENT_NAME }}.Tests/bin/Release/**/${{ env.COMPONENT_NAME }}.Tests.dll --logger:"console;verbosity=detailed" diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 280d11a7cd..ef9871aa97 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +TBD + ## 1.0.0-alpha.6 Released 2023-Feb-13 From 449e7845934d3f47cc988e1aa437b51e9ddfd302 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Tue, 14 Feb 2023 09:11:12 -0800 Subject: [PATCH 0556/1499] Updated .NET build requirements. (#999) --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 933b00e5bf..a978b21a1b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,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 6.0+ +* .NET 7.0+ Please note that individual project requirements might vary. @@ -50,7 +50,7 @@ are disabled outside of Windows. ### Windows * Visual Studio 2022+ or Visual Studio Code -* .NET Framework 4.6.1+ +* .NET Framework 4.6.2+ ## Pull Requests From fab1a17fc16af9d48e28a59dd3bb4bafc74f0bc3 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Tue, 14 Feb 2023 09:29:50 -0800 Subject: [PATCH 0557/1499] Add settings for VS Code build support. (#1000) Co-authored-by: Cijo Thomas --- .vscode/extensions.json | 8 ++++++++ .vscode/tasks.json | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..67fb4df623 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "editorconfig.editorconfig", + "davidanson.vscode-markdownlint", + "ms-dotnettools.csharp", + "streetsidesoftware.code-spell-checker" + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..8f90f49d7a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,37 @@ +{ + "tasks": [ + { + "args": [ + "build", + "${workspaceFolder}/opentelemetry-dotnet-contrib.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "command": "dotnet", + "group": { + "isDefault": true, + "kind": "build" + }, + "label": "build", + "problemMatcher": "$msCompile", + "type": "process" + }, + { + "args": [ + "test", + "${workspaceFolder}/opentelemetry-dotnet-contrib.sln", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "command": "dotnet", + "group": { + "isDefault": true, + "kind": "test" + }, + "label": "test", + "problemMatcher": "$msCompile", + "type": "process" + } + ], + "version": "2.0.0" +} From 4d7f93ef61e2c449635918e7008f9d942281b9bc Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 14 Feb 2023 23:06:54 +0000 Subject: [PATCH 0558/1499] [Instrumentation.EntityFrameworkCore] Fix analysis warning (#962) --- .../EntityFrameworkInstrumentationOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 597b05a04b..722221306f 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -34,7 +34,7 @@ public class EntityFrameworkInstrumentationOptions /// /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. /// - public bool SetDbStatementForText { get; set; } = false; + public bool SetDbStatementForText { get; set; } /// /// Gets or sets an action to enrich an Activity from the db command. From 9c89abf4780fe17508c8cb9d78d716df9e6663ab Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 15 Feb 2023 23:13:20 +0530 Subject: [PATCH 0559/1499] Update contribution guide (#976) --- CONTRIBUTING.md | 54 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a978b21a1b..dd08a1ac28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -169,23 +169,44 @@ build. Breaking the rules will result in a build failure. This repo is a great place to contribute a new instrumentation, exporter or any kind of extension. Please refer to [this page](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#extending-the-opentelemetry-net-sdk) -for help writing your component. Although the projects within this repo share -some properties and configurations, they are built and released independently. -So if you are creating a new project within `/src` and corresponding test -project within `/test`, here are a few things you should do to ensure that your -project is automatically built and shipped through CI. +for help writing your component. + +When contributing a new project you are expected to assign either yourself or +someone else who would take ownership of the component you are contributing. The +owner should at least be an [OpenTelemetry +Member](https://github.com/open-telemetry/community/blob/main/community-membership.md#member) +to be eligible to assigned as component owner. This is required to ensure that +reviews can be automatically requested from the owners. Once the owner is +identified, please update [component_owners](./.github/component_owners.yml) +file for the new project. The component owner(s) are expected to respond to +issues and review PRs affecting their component. + +Although the projects within this repo share some properties and configurations, +they are built and released independently. So if you are creating a new project +within `/src` and corresponding test project within `/test`, here are a few +things you should do to ensure that your project is automatically built and +shipped through CI. * Based on what your project is, you may need to depend on the [OpenTelemetry SDK](https://www.nuget.org/packages/OpenTelemetry) or the [OpenTelemetry API](https://www.nuget.org/packages/OpenTelemetry.Api) Include the necessary package in your project. You can choose the version that you want to depend on. -Usually it is a good idea to use the latest version. Example: +Usually, it is a good idea to use the latest stable version. For example: - ```xml - +```xml + - - ``` + +``` + +* If your component relies on new features not yet part of the stable release, you +can refer to the latest pre-release version. + +```xml + + + +``` * The assembly and nuget versioning is managed through [MinVer](https://github.com/adamralph/minver) for all the projects in the repo. @@ -195,11 +216,11 @@ by you. To ensure your project is versioned appropriately, specify a "OpenTelemetry.Instrumentation.FooBar", the MinVerTagPrefix must be "Instrumentation.FooBar-". Example: - ```xml - +```xml + Instrumentation.FooBar- - - ``` + +``` * Public API of all packages is analyzed by [Microsoft.CodeAnalysis.PublicApiAnalyzers](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md). @@ -237,8 +258,3 @@ the main branch. The workflow file should be named as [![NuGet](https://img.shields.io/nuget/v/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) [![NuGet](https://img.shields.io/nuget/dt/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) ``` - -* When contributing a new project you are expected to assign either yourself or -someone else who would take ownership for the component you are contributing. -Please add the right owner for your project in the -[component_owners](./.github/component_owners.yml) file. From f88afdbcfcccb8e4e67645ac2cd52f6d2ecea85d Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 15 Feb 2023 23:54:57 +0530 Subject: [PATCH 0560/1499] Disable flaky tests (#1004) --- .../Trace/AutoFlushActivityProcessorTests.cs | 2 +- .../EventCountersMetricsTests.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index 6c2bf6b701..4f279c4410 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -26,7 +26,7 @@ namespace OpenTelemetry.Extensions.Tests.Trace; public class AutoFlushActivityProcessorTests { - [Fact] + [Fact(Skip = "Unstable")] public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMatchingSpan_Flush() { var mockExporting = new Mock>(); diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index e6f92a6823..3476430c35 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -53,7 +53,7 @@ public void EventCounter() Assert.Equal(1997.0202, GetActualValue(metric)); } - [Fact] + [Fact(Skip = "Unstable")] public void IncrementingEventCounter() { // Arrange @@ -81,7 +81,7 @@ public void IncrementingEventCounter() Assert.Equal(3, GetActualValue(metric)); } - [Fact] + [Fact(Skip = "Unstable")] public void PollingCounter() { // Arrange @@ -107,7 +107,7 @@ public void PollingCounter() Assert.Equal(10, GetActualValue(metric)); } - [Fact] + [Fact(Skip = "Unstable")] public void IncrementingPollingCounter() { // Arrange From c6860471a02cf4c6e7e59131e9934ea97745b371 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 15 Feb 2023 11:29:40 -0800 Subject: [PATCH 0561/1499] [Instrumentation.Process] Exposed required metric `process.cpu.count` for computing CPU utilization in the backend. (#981) --- .../CHANGELOG.md | 3 ++- .../ProcessMetrics.cs | 10 ++++++++++ .../README.md | 17 +++++++++++++++++ .../ProcessMetricsTests.cs | 18 ++++++++++++------ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index ef9871aa97..5a65615f4f 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,7 +2,8 @@ ## Unreleased -TBD +* Added `process.cpu.count` metric. + ([#981](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/981)) ## 1.0.0-alpha.6 diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 5835ce228c..222eccaf8f 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -16,6 +16,7 @@ #nullable enable +using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; @@ -64,6 +65,15 @@ static ProcessMetrics() unit: "s", description: "Total CPU seconds broken down by different states."); + MeterInstance.CreateObservableUpDownCounter( + "process.cpu.count", + () => + { + return Environment.ProcessorCount; + }, + unit: "{processors}", + description: "The number of processors (CPU cores) available to the current process."); + MeterInstance.CreateObservableUpDownCounter( "process.threads", () => diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 9481e7fb58..b4432e3670 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -92,6 +92,23 @@ Gets the user processor time for this process. * [Process.PrivilegedProcessorTime](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.privilegedprocessortime): Gets the privileged processor time for this process. +### process.cpu.count + +The number of processors (CPU cores) available to the current process. + +| Units | Instrument Type | Value Type | +|---------------|-------------------------|------------| +| `{processors}`| ObservableUpDownCounter | `Int32` | + +The API used to retrieve the value is [System.Environment.ProcessorCount](https://learn.microsoft.com/dotnet/api/system.environment.processorcount). + +> **Note** +> This metric is under [discussion][1] and not part of the +[Process Metrics Spec][2] at this time. + +[1]: https://github.com/open-telemetry/opentelemetry-specification/issues/3200 +[2]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md + ### process.threads Process threads count. diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index e63b89f1fe..0ba48f3151 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -38,14 +38,16 @@ public void ProcessMetricsAreCaptured() meterProviderA.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItemsA.Count == 4); + Assert.True(exportedItemsA.Count == 5); var physicalMemoryMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetric); var virtualMemoryMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetric); var cpuTimeMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.time"); Assert.NotNull(cpuTimeMetric); - var threadMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads"); + var processorCountMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count"); + Assert.NotNull(processorCountMetric); + var threadMetric = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count"); Assert.NotNull(threadMetric); exportedItemsA.Clear(); @@ -66,8 +68,8 @@ public void ProcessMetricsAreCaptured() meterProviderB.ForceFlush(MaxTimeToAllowForFlush); - Assert.True(exportedItemsA.Count == 4); - Assert.True(exportedItemsB.Count == 4); + Assert.True(exportedItemsA.Count == 5); + Assert.True(exportedItemsB.Count == 5); } [Fact] @@ -142,23 +144,27 @@ public void ProcessMetricsAreCapturedWhenTasksOverlap() Task.WaitAll(tasks.ToArray()); - Assert.True(exportedItemsA.Count == 4); + Assert.True(exportedItemsA.Count == 5); var physicalMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetricA); var virtualMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetricA); var cpuTimeMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.time"); Assert.NotNull(cpuTimeMetricA); + var processorCountMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count"); + Assert.NotNull(processorCountMetricA); var threadMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads"); Assert.NotNull(threadMetricA); - Assert.True(exportedItemsB.Count == 4); + Assert.True(exportedItemsB.Count == 5); var physicalMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetricB); var virtualMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.virtual"); Assert.NotNull(virtualMemoryMetricB); var cpuTimeMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.cpu.time"); Assert.NotNull(cpuTimeMetricB); + var processorCountMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.cpu.count"); + Assert.NotNull(processorCountMetricB); var threadMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.threads"); Assert.NotNull(threadMetricB); } From 46acca0b06d7fb231fd48ff8dc6ef7506dccfab7 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 15 Feb 2023 11:39:35 -0800 Subject: [PATCH 0562/1499] draft (#1005) Co-authored-by: Cijo Thomas --- CONTRIBUTING.md | 2 +- examples/wcf/README.md | 5 +++-- src/OpenTelemetry.Exporter.Geneva/README.md | 3 ++- .../CHANGELOG.md | 6 ++++-- .../README.md | 3 ++- .../README.md | 5 +++-- .../README.md | 3 ++- .../README.md | 18 ++++++++++++------ .../README.md | 5 +++-- 9 files changed, 32 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dd08a1ac28..68de883fc0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -132,7 +132,7 @@ A PR is considered to be **ready to merge** when: * 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 +Any Maintainer can merge the PR once it is **ready to merge**. Note that some PR may not be merged immediately if repo is being in process of a major release and the new feature doesn't fit it. diff --git a/examples/wcf/README.md b/examples/wcf/README.md index 177ab8d29d..c496b5d3a2 100644 --- a/examples/wcf/README.md +++ b/examples/wcf/README.md @@ -20,8 +20,9 @@ Project structure: admin privileges. For details see: [Configuring HTTP and HTTPS](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/configuring-http-and-https). - Note: There is no .NET Core server example because only the client libraries - for WCF are available on .NET Core / .NET 5. + > **Note** + > There is no .NET Core server example because only the client libraries + for WCF are available on .NET Core / .NET 5. * Examples.Wcf.Shared diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 44d6a7ef25..fd69f95187 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -110,7 +110,8 @@ The default table name used for Traces is `Span`. To change the table name for Traces add an entry with the key `Span` and set the value to the desired custom table name. -**Note:** Only a single table name is supported for Traces. +> **Note** +> Only a single table name is supported for Traces. ##### Log table name mappings diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index 72a69d2839..c1d8afc74c 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -9,8 +9,10 @@ Released 2023-Feb-07 * Sampler will now return `RecordOnly` SamplingResult when the telemetry is sampled instead of `Drop`. This will result in `Activity` to be created always and populated with all information such as tag, events etc. This is done in -order to allow metrics collection from the generated activities. **Note**: This -change will have no impact on the overall sampling behavior, +order to allow metrics collection from the generated activities. + +> **Note** +> This change will have no impact on the overall sampling behavior, but may have additional performance overhead from creating more activities. ([#933](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/933)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index 671e273400..af2173796b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -120,7 +120,8 @@ TelemetryHttpModuleOptions.TextMapPropagator = new CompositeTextMapPropagator( }); ``` -Note: When using the `OpenTelemetry.Instrumentation.AspNet` +> **Note** +> When using the `OpenTelemetry.Instrumentation.AspNet` `TelemetryHttpModuleOptions.TextMapPropagator` is automatically initialized to the SDK default propagator (`Propagators.DefaultTextMapPropagator`) which by default supports W3C Trace Context & Baggage. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index aa73d15b14..46586814be 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -8,7 +8,8 @@ Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main which instruments [ASP.NET](https://docs.microsoft.com/aspnet/overview) and collect metrics and traces about incoming web requests. -**Note: This component is based on the OpenTelemetry semantic conventions for +> **Note** +> This component is based on the OpenTelemetry semantic conventions for [metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) and [traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). @@ -18,7 +19,7 @@ and hence, this package is a [pre-release](https://github.com/open-telemetry/ope Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) is released, there can be breaking changes. You can track the progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). ## Steps to enable OpenTelemetry.Instrumentation.AspNet diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index 1aded70cb7..02f0fcf9e9 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -52,7 +52,8 @@ the `ConfigureServices` of your `Startup` class. Refer to documentation for For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). -Note, If you are using `Mysql.Data` 8.0.31 or later, please add +> **Note** +> If you are using `Mysql.Data` 8.0.31 or later, please add option `Logging=true` in your connection string to enable tracing. See issue #691 for details. diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 8dee33cc1c..ecaba50b53 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -48,7 +48,8 @@ to the application. Number of garbage collections that have occurred since process start. -Note: .NET uses a [generational GC](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#generations) +> **Note** +> .NET uses a [generational GC](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#generations) which divides the heap into different generations numbered 0, 1, and 2. In each collection the GC decides which generation to search for reclaimable memory, then it searches that generation and all the lower ones. A GC collection that @@ -101,7 +102,8 @@ Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap. -Note: This metric is only available when targeting .NET 6 or later. +> **Note** +> This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------|------------|------------------|------------------| @@ -122,7 +124,8 @@ objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred. -Note: This metric is only available when targeting .NET 6 or later. +> **Note** +> This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------------|------------|------------------|------------------| @@ -139,7 +142,8 @@ The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred. -Note: This metric is only available when targeting .NET 6 or later. +> **Note** +> This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------------|------------|------------------|----------------------------| @@ -160,7 +164,8 @@ The API used to retrieve the value is: The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred. -Note: This metric is only available when targeting .NET 7 or later. +> **Note** +> This metric is only available when targeting .NET 7 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | |---------|-------------------------|------------|------------------|----------------------------| @@ -306,7 +311,8 @@ Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization. -Note: The value is tracked by incrementing a counter whenever an AppDomain.FirstChanceException +> **Note** +> The value is tracked by incrementing a counter whenever an AppDomain.FirstChanceException event occurs. The observation starts when the Runtime instrumentation library is initialized, so the value will be unavailable until an exception has been thrown after the initialization. diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index 167cae9ff4..0bf36733e7 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -9,7 +9,8 @@ which instruments [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis/) and collects traces about outgoing calls to Redis. -**Note: This component is based on the OpenTelemetry semantic conventions for +> **Note** +> This component is based on the OpenTelemetry semantic conventions for [traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), @@ -17,7 +18,7 @@ and hence, this package is a [pre-release](https://github.com/open-telemetry/ope Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) is released, there can be breaking changes. You can track the progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). ## Steps to enable OpenTelemetry.Instrumentation.StackExchangeRedis From 1c8cc26cdd1605bb547ae410d4f6da4a5b2309b6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 15 Feb 2023 13:02:16 -0800 Subject: [PATCH 0563/1499] [OneCollectorExporter] Initial code (#1003) * Initial push. * Solution and props updates. * Clean up and refactoring. * A bit of MD content. * Warnings and public API. * Package description tweak. * Test refactoring. * More README content. * Tests and fixes. * GitHub ceremony. * Add HttpJsonPostTransport tests. * Owners update. * Code review. * Fixes for dotnet format. * Warning cleanup. * Test fixes. * Test clean up. --- .github/component_owners.yml | 6 + .../package-Exporter.OneCollector.yml | 67 +++++ build/Common.props | 4 +- opentelemetry-dotnet-contrib.sln | 16 ++ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 21 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 21 ++ .../.publicApi/net7.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 21 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 21 ++ .../netstandard2.1/PublicAPI.Shipped.txt | 1 + .../netstandard2.1/PublicAPI.Unshipped.txt | 21 ++ .../AssemblyInfo.cs | 30 +++ .../CHANGELOG.md | 5 + .../Internal/EventNameManager.cs | 200 +++++++++++++++ .../OneCollectorExporterEventSource.cs | 148 +++++++++++ .../Serialization/BatchSerializationResult.cs | 38 +++ .../CommonSchemaJsonSerializationHelper.cs | 215 ++++++++++++++++ .../CommonSchemaJsonSerializer.cs | 119 +++++++++ .../Internal/Serialization/ISerializer.cs | 32 +++ .../LogRecordCommonSchemaJsonSerializer.cs | 165 ++++++++++++ .../Internal/Sinks/ISink.cs | 27 ++ .../Internal/Sinks/ISinkFactory.cs | 23 ++ .../Sinks/WriteDirectlyToTransportSink.cs | 172 +++++++++++++ .../Internal/ThreadStorageHelper.cs | 25 ++ .../Transports/HttpJsonPostTransport.cs | 208 +++++++++++++++ .../Internal/Transports/ITransport.cs | 24 ++ .../Transports/TransportSendRequest.cs | 47 ++++ .../Logs/OneCollectorLogExporter.cs | 35 +++ .../Logs/OneCollectorLogExporterOptions.cs | 91 +++++++ ...torOpenTelemetryLoggerOptionsExtensions.cs | 71 ++++++ .../OneCollectorExporter.cs | 77 ++++++ ...torExporterHttpTransportCompressionType.cs | 33 +++ .../OneCollectorExporterOptions.cs | 57 +++++ .../OneCollectorExporterTransportOptions.cs | 109 ++++++++ ...eCollectorExporterTransportProtocolType.cs | 28 +++ ...OpenTelemetry.Exporter.OneCollector.csproj | 25 ++ .../README.md | 39 +++ src/OpenTelemetry.Internal/Guard.cs | 7 + .../TestHttpServer.cs | 134 ++++++++++ ...ommonSchemaJsonSerializationHelperTests.cs | 186 ++++++++++++++ .../EventNameManagerTests.cs | 126 ++++++++++ .../HttpJsonPostTransportTests.cs | 163 ++++++++++++ ...ogRecordCommonSchemaJsonSerializerTests.cs | 236 ++++++++++++++++++ ...lemetry.Exporter.OneCollector.Tests.csproj | 32 +++ .../WriteDirectlyToTransportSinkTests.cs | 180 +++++++++++++ 48 files changed, 3309 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/package-Exporter.OneCollector.yml create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj create mode 100644 src/OpenTelemetry.Exporter.OneCollector/README.md create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 1cd3298842..e6eb61f68b 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -17,6 +17,9 @@ components: - Yun-Ting src/OpenTelemetry.Exporter.Instana/: - zivaninstana + src/OpenTelemetry.Exporter.OneCollector/: + - codeblanch + - reyang src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev src/OpenTelemetry.Extensions/: @@ -86,6 +89,9 @@ components: - Yun-Ting test/OpenTelemetry.Exporter.Instana.Tests/: - zivaninstana + test/OpenTelemetry.Exporter.OneCollector.Tests/: + - codeblanch + - reyang test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml new file mode 100644 index 0000000000..9ffde4b334 --- /dev/null +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -0,0 +1,67 @@ +name: Pack OpenTelemetry.Exporter.OneCollector + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Exporter.OneCollector-*' # trigger when we create a tag with prefix "Exporter.OneCollector-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + permissions: + contents: write + env: + PROJECT: OpenTelemetry.Exporter.OneCollector + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build/Common.props b/build/Common.props index 52d940a9e5..469e35cdbe 100644 --- a/build/Common.props +++ b/build/Common.props @@ -1,6 +1,6 @@ - 10.0 + 11.0 true $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) $(MSBuildThisFileDirectory)debug.snk @@ -35,6 +35,8 @@ [1.4.0-rc.4,2.0) [2.1.58,3.0) [1.2.0-beta.435,2.0) + [4.3.4,) + [6.0.0,) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 87559b7581..820b0db25e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -37,6 +37,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml + .github\workflows\package-Exporter.OneCollector.yml = .github\workflows\package-Exporter.OneCollector.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.AzureMonitor.yml = .github\workflows\package-Extensions.AzureMonitor.yml @@ -53,6 +54,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml + .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml @@ -243,6 +245,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure.Tests", "test\OpenTelemetry.ResourceDetectors.Azure.Tests\OpenTelemetry.ResourceDetectors.Azure.Tests.csproj", "{DFC6A4A9-5262-4507-B747-CC6B814205E6}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector", "src\OpenTelemetry.Exporter.OneCollector\OpenTelemetry.Exporter.OneCollector.csproj", "{73C10993-03AC-42F4-85BB-96EAAA8212D9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Tests", "test\OpenTelemetry.Exporter.OneCollector.Tests\OpenTelemetry.Exporter.OneCollector.Tests.csproj", "{61520801-1CAA-4041-A3EF-CFFB9D4A180B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -513,6 +519,14 @@ Global {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {DFC6A4A9-5262-4507-B747-CC6B814205E6}.Release|Any CPU.Build.0 = Release|Any CPU + {73C10993-03AC-42F4-85BB-96EAAA8212D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73C10993-03AC-42F4-85BB-96EAAA8212D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73C10993-03AC-42F4-85BB-96EAAA8212D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73C10993-03AC-42F4-85BB-96EAAA8212D9}.Release|Any CPU.Build.0 = Release|Any CPU + {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -592,6 +606,8 @@ Global {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {B07DC3CB-F724-40A5-889A-DA6601F462F3} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {DFC6A4A9-5262-4507-B747-CC6B814205E6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {73C10993-03AC-42F4-85BB-96EAAA8212D9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {61520801-1CAA-4041-A3EF-CFFB9D4A180B} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8e36c38895 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,21 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8e36c38895 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,21 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8e36c38895 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -0,0 +1,21 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8e36c38895 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,21 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..8e36c38895 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -0,0 +1,21 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs new file mode 100644 index 0000000000..19c1510b3e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs @@ -0,0 +1,30 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +[assembly: CLSCompliant(false)] + +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OneCollector.Tests" + AssemblyInfo.PublicKey)] + +internal static class AssemblyInfo +{ +#if SIGNED + public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; +#else + public const string PublicKey = ""; +#endif +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md new file mode 100644 index 0000000000..63bfc986bd --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +Initial release. diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs new file mode 100644 index 0000000000..e290f6cfa7 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs @@ -0,0 +1,200 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections; +using System.Diagnostics; +using System.Text.RegularExpressions; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class EventNameManager +{ + private const int MinimumEventFullNameLength = 4; + private const int MaximumEventFullNameLength = 100; + private static readonly Regex EventNamespaceValidationRegex = new(@"^[A-Za-z](?:\.?[A-Za-z0-9]+?)*$", RegexOptions.Compiled); + private static readonly Regex EventNameValidationRegex = new(@"^[A-Za-z][A-Za-z0-9]*$", RegexOptions.Compiled); + + private readonly string defaultEventNamespace; + private readonly string defaultEventName; + private readonly byte[] defaultEventFullName; + private readonly Hashtable eventNamespaceCache = new(StringComparer.OrdinalIgnoreCase); + + public EventNameManager(string defaultEventNamespace, string defaultEventName) + { + Debug.Assert(defaultEventNamespace != null, "defaultEventNamespace was null"); + Debug.Assert(defaultEventName != null, "defaultEventName was null"); + + this.defaultEventNamespace = defaultEventNamespace!; + this.defaultEventName = defaultEventName!; + + if (!IsEventNamespaceValid(defaultEventNamespace!)) + { + throw new ArgumentException($"Default event namespace '{defaultEventNamespace}' was invalid.", nameof(defaultEventNamespace)); + } + + if (!IsEventNamespaceValid(defaultEventName!)) + { + throw new ArgumentException($"Default event name '{defaultEventName}' was invalid.", nameof(defaultEventName)); + } + + var defaultEventFullNameLength = defaultEventNamespace!.Length + defaultEventName!.Length + 1; + if (defaultEventFullNameLength < MinimumEventFullNameLength || defaultEventFullNameLength > MaximumEventFullNameLength) + { + throw new ArgumentException($"Default event full name '{defaultEventNamespace}.{defaultEventName}' does not meet length requirements.", nameof(defaultEventName)); + } + + this.defaultEventFullName = BuildEventFullName(defaultEventNamespace, defaultEventName)!; + +#if NET6_0_OR_GREATER + Debug.Assert(this.defaultEventFullName != null, "this.defaultFullyQualifiedEventName was null"); +#endif + } + + // Note: This is exposed for unit tests. + internal Hashtable EventNamespaceCache => this.eventNamespaceCache; + + public static bool IsEventNamespaceValid(string eventNamespace) + => EventNamespaceValidationRegex.IsMatch(eventNamespace); + + public static bool IsEventNameValid(string eventName) + => EventNameValidationRegex.IsMatch(eventName); + + public ReadOnlySpan ResolveEventFullName( + string? eventNamespace, + string? eventName) + { + var eventNameIsNullOrWhiteSpace = string.IsNullOrWhiteSpace(eventName); + + if (string.IsNullOrWhiteSpace(eventNamespace)) + { + if (eventNameIsNullOrWhiteSpace) + { + return this.defaultEventFullName; + } + + eventNamespace = this.defaultEventNamespace; + } + + if (eventNameIsNullOrWhiteSpace) + { + eventName = this.defaultEventName; + } + + var eventNameCache = this.GetEventNameCacheForEventNamespace(eventNamespace!); + + if (eventNameCache[eventName!] is byte[] cachedEventFullName) + { + return cachedEventFullName; + } + + return this.ResolveEventNameRare(eventNameCache, eventNamespace!, eventName!); + } + + private static byte[] BuildEventFullName(string eventNamespace, string eventName) + { + Span destination = stackalloc byte[128]; + + destination[0] = (byte)'\"'; + + var cursor = 1; + + WriteEventFullNameComponent(eventNamespace, destination, ref cursor); + + destination[cursor++] = (byte)'.'; + + WriteEventFullNameComponent(eventName, destination, ref cursor); + + destination[cursor++] = (byte)'\"'; + + return destination.Slice(0, cursor).ToArray(); + } + + private static void WriteEventFullNameComponent(string component, Span destination, ref int cursor) + { + char firstChar = component[0]; + if (firstChar >= 'a' && firstChar <= 'z') + { + firstChar -= (char)32; + } + + destination[cursor++] = (byte)firstChar; + + for (int i = 1; i < component.Length; i++) + { + destination[cursor++] = (byte)component[i]; + } + } + + private Hashtable GetEventNameCacheForEventNamespace(string eventNamespace) + { + var eventNamespaceCache = this.eventNamespaceCache; + + if (eventNamespaceCache[eventNamespace] is not Hashtable eventNameCacheForNamespace) + { + lock (eventNamespaceCache) + { + eventNameCacheForNamespace = (eventNamespaceCache[eventNamespace] as Hashtable)!; + if (eventNameCacheForNamespace == null) + { + eventNameCacheForNamespace = new Hashtable(StringComparer.OrdinalIgnoreCase); + eventNamespaceCache[eventNamespace] = eventNameCacheForNamespace; + } + } + } + + return eventNameCacheForNamespace; + } + + private byte[] ResolveEventNameRare(Hashtable eventNameCache, string eventNamespace, string eventName) + { + if (!IsEventNamespaceValid(eventNamespace)) + { + OneCollectorExporterEventSource.Log.EventNamespaceInvalid(eventNamespace); + eventNamespace = this.defaultEventNamespace; + } + + var eventNameHashtableKey = eventName; + + if (!IsEventNameValid(eventName)) + { + OneCollectorExporterEventSource.Log.EventNameInvalid(eventName); + eventName = this.defaultEventName; + } + + byte[] eventFullName; + + var finalEventFullNameLength = eventNamespace.Length + eventName.Length + 1; + if (finalEventFullNameLength < MinimumEventFullNameLength || finalEventFullNameLength > MaximumEventFullNameLength) + { + OneCollectorExporterEventSource.Log.EventFullNameDiscarded(eventNamespace, eventName); + eventFullName = this.defaultEventFullName; + } + else + { + eventFullName = BuildEventFullName(eventNamespace!, eventName!); + } + + lock (eventNameCache) + { + if (eventNameCache[eventNameHashtableKey] is null) + { + eventNameCache[eventNameHashtableKey] = eventFullName; + } + } + + return eventFullName; + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs new file mode 100644 index 0000000000..aa5f21c7be --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -0,0 +1,148 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Runtime.CompilerServices; + +namespace OpenTelemetry.Exporter.OneCollector; + +[EventSource(Name = "OpenTelemetry-Exporter-OneCollector")] +internal sealed class OneCollectorExporterEventSource : EventSource +{ + public static OneCollectorExporterEventSource Log { get; } = new OneCollectorExporterEventSource(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool IsInformationalLoggingEnabled() => this.IsEnabled(EventLevel.Informational, EventKeywords.All); + + [NonEvent] + public void WriteExportExceptionThrownEventIfEnabled(string itemType, Exception exception) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.ExportExceptionThrown(itemType, ExceptionToInvariantString(exception)); + } + } + + [NonEvent] + public void WriteTransportDataSentEventIfEnabled(string itemType, int? numberOfRecords, string transportDescription) + { + if (this.IsInformationalLoggingEnabled()) + { + this.TransportDataSent(itemType, numberOfRecords ?? -1, transportDescription); + } + } + + [NonEvent] + public void WriteSinkDataWrittenEventIfEnabled(string itemType, int numberOfRecords, string sinkDescription) + { + if (this.IsInformationalLoggingEnabled()) + { + this.SinkDataWritten(itemType, numberOfRecords, sinkDescription); + } + } + + [NonEvent] + public void WriteTransportExceptionThrownEventIfEnabled(string transportType, Exception exception) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.TransportExceptionThrown(transportType, ExceptionToInvariantString(exception)); + } + } + + [NonEvent] + public void WriteHttpTransportErrorResponseReceivedEventIfEnabled(string transportType, int statusCode, IEnumerable? errorMessages, string? errorDetails) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.HttpTransportErrorResponseReceived(transportType, statusCode, errorMessages?.FirstOrDefault() ?? string.Empty, errorDetails ?? string.Empty); + } + } + + [Event(1, Message = "Exception thrown exporting '{0}' batch: {1}.", Level = EventLevel.Error)] + public void ExportExceptionThrown(string itemType, string exception) + { + this.WriteEvent(1, itemType, exception); + } + + [Event(2, Message = "Sent '{0}' batch of {1} item(s) to '{2}' transport.", Level = EventLevel.Informational)] + public void TransportDataSent(string itemType, int numberOfRecords, string transportDescription) + { + this.WriteEvent(2, itemType, numberOfRecords, transportDescription); + } + + [Event(3, Message = "Wrote '{0}' batch of {1} item(s) to '{2}' sink.", Level = EventLevel.Informational)] + public void SinkDataWritten(string itemType, int numberOfRecords, string sinkDescription) + { + this.WriteEvent(3, itemType, numberOfRecords, sinkDescription); + } + + [Event(4, Message = "Dropped {1} '{0}' item(s).", Level = EventLevel.Warning)] + public void DataDropped(string itemType, int numberOfRecords) + { + this.WriteEvent(4, itemType, numberOfRecords); + } + + [Event(5, Message = "Exception thrown by '{0}' transport: {1}", Level = EventLevel.Error)] + public void TransportExceptionThrown(string transportType, string exception) + { + this.WriteEvent(5, transportType, exception); + } + + [Event(6, Message = "Error response received by '{0}' transport. StatusCode: {1}, ErrorMessage: '{2}', ErrorDetails: '{3}'", Level = EventLevel.Error)] + public void HttpTransportErrorResponseReceived(string transportType, int statusCode, string errorMessage, string errorDetails) + { + this.WriteEvent(6, transportType, statusCode, errorMessage, errorDetails); + } + + [Event(7, Message = "Event full name discarded. EventNamespace: '{0}', EventName: '{1}'", Level = EventLevel.Warning)] + public void EventFullNameDiscarded(string eventNamespace, string eventName) + { + this.WriteEvent(7, eventNamespace, eventName); + } + + [Event(8, Message = "Event namespace invalid. EventNamespace: '{0}'", Level = EventLevel.Warning)] + public void EventNamespaceInvalid(string eventNamespace) + { + this.WriteEvent(8, eventNamespace); + } + + [Event(9, Message = "Event name invalid. EventName: '{0}'", Level = EventLevel.Warning)] + public void EventNameInvalid(string eventName) + { + this.WriteEvent(9, eventName); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ExceptionToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs new file mode 100644 index 0000000000..5072dc6418 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Note: StyleCop doesn't understand the C#11 "required" modifier yet. Remove +// this in the future once StyleCop is updated. See: +// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3527 + +#pragma warning disable SA1206 // Declaration keywords should follow order + +namespace OpenTelemetry.Exporter.OneCollector; + +internal readonly struct BatchSerializationResult +{ +#if NET7_0_OR_GREATER + public required int NumberOfItemsSerialized { get; init; } + + public required long PayloadSizeInBytes { get; init; } +#else + public int NumberOfItemsSerialized { get; init; } + + public long PayloadSizeInBytes { get; init; } +#endif + + public long? PayloadOverflowItemSizeInBytes { get; init; } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs new file mode 100644 index 0000000000..3406c74214 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -0,0 +1,215 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Globalization; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal static class CommonSchemaJsonSerializationHelper +{ +#if NET6_0_OR_GREATER + public const int MaximumStackAllocSizeInBytes = 256; +#endif + + public static void SerializeKeyValueToJson(string key, object? value, Utf8JsonWriter writer) + { + writer.WritePropertyName(key); + SerializeValueToJson(value, writer); + } + + public static void SerializeValueToJson(object? value, Utf8JsonWriter writer) + { + if (value is null) + { + writer.WriteNullValue(); + return; + } + + switch (value) + { + case bool v: + writer.WriteBooleanValue(v); + return; + + case byte v: + writer.WriteNumberValue(v); + return; + + case sbyte v: + writer.WriteNumberValue(v); + return; + + case short v: + writer.WriteNumberValue(v); + return; + + case ushort v: + writer.WriteNumberValue(v); + return; + + case int v: + writer.WriteNumberValue(v); + return; + + case uint v: + writer.WriteNumberValue(v); + return; + + case long v: + writer.WriteNumberValue(v); + return; + + case ulong v: + writer.WriteNumberValue(v); + return; + + case float v: + writer.WriteNumberValue(v); + return; + + case double v: + writer.WriteNumberValue(v); + return; + + case decimal v: + writer.WriteNumberValue(v); + return; + + case string v: + writer.WriteStringValue(v); + return; + + case DateTime v: + writer.WriteStringValue(v.ToUniversalTime()); + return; + + case DateTimeOffset v: + writer.WriteStringValue(v); + return; + +#if NET7_0_OR_GREATER + case DateOnly v: + JsonMetadataServices.DateOnlyConverter.Write(writer, v, null!); + return; +#endif + + case TimeSpan v: + JsonMetadataServices.TimeSpanConverter.Write(writer, v, null!); + return; + +#if NET7_0_OR_GREATER + case TimeOnly v: + JsonMetadataServices.TimeOnlyConverter.Write(writer, v, null!); + return; +#endif + + case Guid v: + writer.WriteStringValue(v); + return; + + case Uri v: + JsonMetadataServices.UriConverter.Write(writer, v, null!); + return; + + case Version v: + JsonMetadataServices.VersionConverter.Write(writer, v, null!); + return; + + case byte[] v: + writer.WriteBase64StringValue(v); + return; + + case Memory v: + writer.WriteBase64StringValue(v.Span); + return; + + case ArraySegment v: + writer.WriteBase64StringValue(v); + return; + + case Array v: + SerializeArrayValueToJson(v, writer); + return; + + case IEnumerable> v: + SerializeMapValueToJson(v, writer); + return; + + default: + SerializeObjectValueToJson(value, writer); + return; + } + } + + private static void SerializeArrayValueToJson(Array value, Utf8JsonWriter writer) + { + writer.WriteStartArray(); + + foreach (var element in value) + { + SerializeValueToJson(element, writer); + } + + writer.WriteEndArray(); + } + + private static void SerializeMapValueToJson(IEnumerable> value, Utf8JsonWriter writer) + { + writer.WriteStartObject(); + + foreach (var element in value) + { + if (string.IsNullOrEmpty(element.Key)) + { + continue; + } + + SerializeKeyValueToJson(element.Key, element.Value, writer); + } + + writer.WriteEndObject(); + } + + private static void SerializeObjectValueToJson(object value, Utf8JsonWriter writer) + { +#if NET6_0_OR_GREATER + if (value is ISpanFormattable spanFormattable) + { + Span destination = stackalloc char[MaximumStackAllocSizeInBytes / 2]; + if (spanFormattable.TryFormat(destination, out int charsWritten, string.Empty, CultureInfo.InvariantCulture)) + { + writer.WriteStringValue(destination.Slice(0, charsWritten)); + return; + } + } +#endif + + string v; + + try + { + v = Convert.ToString(value, CultureInfo.InvariantCulture)!; + } + catch + { + v = $"ERROR: type {value.GetType().FullName} is not supported"; + } + + writer.WriteStringValue(v); + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs new file mode 100644 index 0000000000..266d56fbcd --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -0,0 +1,119 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Text.Json; +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal abstract class CommonSchemaJsonSerializer : ISerializer + where T : class +{ + protected static readonly JsonEncodedText VersionProperty = JsonEncodedText.Encode("ver"); + protected static readonly JsonEncodedText Version4Value = JsonEncodedText.Encode("4.0"); + protected static readonly JsonEncodedText NameProperty = JsonEncodedText.Encode("name"); + protected static readonly JsonEncodedText TimeProperty = JsonEncodedText.Encode("time"); + protected static readonly JsonEncodedText IKeyProperty = JsonEncodedText.Encode("iKey"); + protected static readonly JsonEncodedText DataProperty = JsonEncodedText.Encode("data"); + + private const char OneCollectorTenancySymbol = 'o'; + + private static readonly byte[] NewLine = "\n"u8.ToArray(); + + private readonly int maxPayloadSizeInBytes; + private readonly int maxNumberOfItemsPerPayload; + + protected CommonSchemaJsonSerializer( + string tenantToken, + int maxPayloadSizeInBytes = int.MaxValue, + int maxNumberOfItemsPerPayload = int.MaxValue) + { + Debug.Assert(!string.IsNullOrEmpty(tenantToken), "tenantToken was null or empty."); + + this.maxPayloadSizeInBytes = maxPayloadSizeInBytes; + this.maxNumberOfItemsPerPayload = maxNumberOfItemsPerPayload; + + this.TenantTokenWithTenancySystemSymbol = JsonEncodedText.Encode($"{OneCollectorTenancySymbol}:{tenantToken}"); + } + + public abstract string Description { get; } + + protected JsonEncodedText TenantTokenWithTenancySystemSymbol { get; } + + public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, Stream stream, int initialSizeOfPayloadInBytes, out BatchSerializationResult result) + { + Guard.ThrowIfNull(stream); + + var numberOfSerializedItems = 0; + long payloadSizeInBytes = initialSizeOfPayloadInBytes; + + var writer = ThreadStorageHelper.Utf8JsonWriter ??= new( + stream, + new JsonWriterOptions + { +#if DEBUG + SkipValidation = false, +#else + SkipValidation = true, +#endif + }); + + foreach (var item in batch) + { + // Note: This is a slow operation. We call this each iteration + // (instead of once per batch) to reset _currentDepth on + // Utf8JsonWriter so it doesn't write a comma after each record. + // Need a faster solution here! + writer.Reset(stream); + + this.SerializeItemToJson(resource, item, writer); + + var currentItemSizeInBytes = writer.BytesCommitted + writer.BytesPending + 1; + + payloadSizeInBytes += currentItemSizeInBytes; + + writer.Flush(); + + stream.Write(NewLine, 0, 1); + + if (++numberOfSerializedItems >= this.maxNumberOfItemsPerPayload) + { + break; + } + + if (payloadSizeInBytes >= this.maxPayloadSizeInBytes) + { + result = new BatchSerializationResult + { + NumberOfItemsSerialized = numberOfSerializedItems, + PayloadSizeInBytes = payloadSizeInBytes, + PayloadOverflowItemSizeInBytes = currentItemSizeInBytes, + }; + return; + } + } + + result = new BatchSerializationResult + { + NumberOfItemsSerialized = numberOfSerializedItems, + PayloadSizeInBytes = payloadSizeInBytes, + }; + } + + protected abstract void SerializeItemToJson(Resource resource, T item, Utf8JsonWriter writer); +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs new file mode 100644 index 0000000000..bcd607f084 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs @@ -0,0 +1,32 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal interface ISerializer + where T : class +{ + string Description { get; } + + void SerializeBatchOfItemsToStream( + Resource resource, + in Batch batch, + Stream stream, + int initialSizeOfPayloadInBytes, + out BatchSerializationResult serializationResult); +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs new file mode 100644 index 0000000000..456212d4fc --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -0,0 +1,165 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Text.Json; +using OpenTelemetry.Logs; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSerializer +{ + private static readonly JsonEncodedText SeverityTextProperty = JsonEncodedText.Encode("severityText"); + private static readonly JsonEncodedText SeverityNumberProperty = JsonEncodedText.Encode("severityNumber"); + private static readonly JsonEncodedText BodyProperty = JsonEncodedText.Encode("body"); + + private static readonly JsonEncodedText[] LogLevelToSeverityTextMappings = new JsonEncodedText[] + { + JsonEncodedText.Encode("Trace"), + JsonEncodedText.Encode("Debug"), + JsonEncodedText.Encode("Information"), + JsonEncodedText.Encode("Warning"), + JsonEncodedText.Encode("Error"), + JsonEncodedText.Encode("Critical"), + JsonEncodedText.Encode("Trace"), // Note: This is the "None" bucket. + }; + + private static readonly int[] LogLevelToSeverityNumberMappings = new int[] + { + 1, 5, 9, 13, 17, 21, 1, + }; + + private static readonly Action SerializeScopeItemToJson = (s, w) => + { + foreach (KeyValuePair scopeAttribute in s) + { + if (scopeAttribute.Key == "{OriginalFormat}") + { + return; + } + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(scopeAttribute.Key, scopeAttribute.Value, w); + } + }; + + private readonly EventNameManager eventNameManager; + + public LogRecordCommonSchemaJsonSerializer( + EventNameManager eventNameManager, + string tenantToken, + int maxPayloadSizeInBytes = int.MaxValue, + int maxNumberOfItemsPerPayload = int.MaxValue) + : base(tenantToken, maxPayloadSizeInBytes, maxNumberOfItemsPerPayload) + { + Debug.Assert(eventNameManager != null, "eventNameManager was null"); + + this.eventNameManager = eventNameManager!; + } + + public override string Description => "LogRecord Common Schema JSON"; + + protected override void SerializeItemToJson(Resource resource, LogRecord item, Utf8JsonWriter writer) + { + var eventName = this.eventNameManager.ResolveEventFullName( + item.CategoryName, + item.EventId.Name); + + writer.WriteStartObject(); + + writer.WriteString(VersionProperty, Version4Value); + + writer.WritePropertyName(NameProperty); +#if DEBUG + writer.WriteRawValue(eventName, skipInputValidation: false); +#else + writer.WriteRawValue(eventName, skipInputValidation: true); +#endif + + writer.WriteString(TimeProperty, item.Timestamp); + + writer.WriteString(IKeyProperty, this.TenantTokenWithTenancySystemSymbol); + + writer.WriteStartObject(DataProperty); + + /* TODO: There doesn't seem to be a spot in common schema defined for + event.id so we will drop for now. + + if (item.EventId.Id != 0) + { + writer.WriteNumber(EventIdProperty, item.EventId.Id); + }*/ + + var logLevel = (int)item.LogLevel; + writer.WriteString(SeverityTextProperty, LogLevelToSeverityTextMappings[logLevel]); + writer.WriteNumber(SeverityNumberProperty, LogLevelToSeverityNumberMappings[logLevel]); + + string? body = null; + + if (item.StateValues != null) + { + for (int i = 0; i < item.StateValues.Count; i++) + { + var attribute = item.StateValues[i]; + + if (string.IsNullOrEmpty(attribute.Key)) + { + continue; + } + + if (attribute.Key == "{OriginalFormat}") + { + body = attribute.Value as string; + continue; + } + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(attribute.Key, attribute.Value, writer); + } + } + + if (!string.IsNullOrEmpty(body)) + { + writer.WriteString(BodyProperty, body); + } + else if (!string.IsNullOrEmpty(item.FormattedMessage)) + { + writer.WriteString(BodyProperty, item.FormattedMessage); + } + + if (resource.Attributes is IReadOnlyList> resourceAttributeList) + { + for (int i = 0; i < resourceAttributeList.Count; i++) + { + var resourceAttribute = resourceAttributeList[i]; + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(resourceAttribute.Key, resourceAttribute.Value, writer); + } + } + else + { + foreach (KeyValuePair resourceAttribute in resource.Attributes) + { + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(resourceAttribute.Key, resourceAttribute.Value, writer); + } + } + + item.ForEachScope(SerializeScopeItemToJson, writer); + + writer.WriteEndObject(); + + writer.WriteEndObject(); + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs new file mode 100644 index 0000000000..ba914c1e10 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal interface ISink + where T : class +{ + string Description { get; } + + int Write(Resource resource, in Batch batch); +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs new file mode 100644 index 0000000000..46adf69e4f --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +internal interface ISinkFactory + where T : class +{ + ISink CreateSink(); +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs new file mode 100644 index 0000000000..b6f49c6866 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs @@ -0,0 +1,172 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK || NETSTANDARD2_0 +using System.Buffers; +#endif +using System.Diagnostics; +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class WriteDirectlyToTransportSink : ISink, IDisposable + where T : class +{ + private readonly string typeName; + private readonly ISerializer serializer; + private readonly ITransport transport; + private readonly MemoryStream buffer; + + public WriteDirectlyToTransportSink( + ISerializer serializer, + ITransport transport, + int initialBufferCapacity = 8192) + { + Guard.ThrowIfNull(serializer); + Guard.ThrowIfNull(transport); + Guard.ThrowIfOutOfRange(initialBufferCapacity, min: 0); + + this.typeName = typeof(T).Name; + this.serializer = serializer; + this.transport = transport; + this.buffer = new(initialBufferCapacity); + } + + public string Description => "WriteDirectlyToTransportSink"; + + internal MemoryStream Buffer => this.buffer; + + public void Dispose() + { + this.TrySendRemainingData(); + + (this.serializer as IDisposable)?.Dispose(); + (this.transport as IDisposable)?.Dispose(); + } + + public int Write(Resource resource, in Batch batch) + { + Span remainingData = default; + + var buffer = this.buffer; + + try + { + this.serializer.SerializeBatchOfItemsToStream(resource, in batch, buffer, (int)buffer.Length, out var serializationResult); + + var numberOfItemsSerialized = serializationResult.NumberOfItemsSerialized; + + if (numberOfItemsSerialized <= 0) + { + return 0; + } + + OneCollectorExporterEventSource.Log.WriteSinkDataWrittenEventIfEnabled(this.typeName, numberOfItemsSerialized, this.Description); + + var numberOfItemsToSend = numberOfItemsSerialized; + + if (serializationResult.PayloadOverflowItemSizeInBytes.HasValue) + { + var hasUnderlyingBuffer = buffer.TryGetBuffer(out var underlyingBuffer); + Debug.Assert(hasUnderlyingBuffer, "Could not access underlying buffer"); + + var endPositionOfValidMessages = (int)(serializationResult.PayloadSizeInBytes - serializationResult.PayloadOverflowItemSizeInBytes); + + remainingData = underlyingBuffer.AsSpan().Slice( + endPositionOfValidMessages, + (int)serializationResult.PayloadOverflowItemSizeInBytes.Value); + + buffer.SetLength(endPositionOfValidMessages); + + numberOfItemsToSend--; + } + + buffer.Position = 0; + + if (!this.transport.Send( + new TransportSendRequest + { + ItemType = this.typeName, + ItemStream = buffer, + NumberOfItems = numberOfItemsToSend, + })) + { + OneCollectorExporterEventSource.Log.DataDropped(this.typeName, numberOfItemsToSend); + } + + return numberOfItemsSerialized; + } + finally + { + if (remainingData.Length > 0) + { + buffer.Position = 0; +#if NETFRAMEWORK || NETSTANDARD2_0 + var rentedBuffer = ArrayPool.Shared.Rent(remainingData.Length); + try + { + remainingData.CopyTo(rentedBuffer); + buffer.Write(rentedBuffer, 0, remainingData.Length); + } + finally + { + ArrayPool.Shared.Return(rentedBuffer); + } +#else + buffer.Write(remainingData); +#endif + buffer.SetLength(remainingData.Length); + } + else + { + buffer.SetLength(0); + } + } + } + + private void TrySendRemainingData() + { + var buffer = this.buffer; + if (buffer != null && buffer.Length > 0) + { + buffer.Position = 0; + + try + { + if (!this.transport.Send( + new TransportSendRequest + { + ItemType = this.typeName, + ItemStream = buffer, + NumberOfItems = 1, + })) + { + OneCollectorExporterEventSource.Log.DataDropped(this.typeName, 1); + } + } + catch (Exception ex) + { + OneCollectorExporterEventSource.Log.DataDropped(this.typeName, 1); + OneCollectorExporterEventSource.Log.WriteExportExceptionThrownEventIfEnabled(this.typeName, ex); + } + finally + { + buffer.SetLength(0); + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs new file mode 100644 index 0000000000..13c056a44c --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal static class ThreadStorageHelper +{ + [ThreadStatic] + public static Utf8JsonWriter? Utf8JsonWriter; +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs new file mode 100644 index 0000000000..f2b6d78af3 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -0,0 +1,208 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.IO.Compression; +using System.Net; +using System.Net.Http.Headers; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class HttpJsonPostTransport : ITransport, IDisposable +{ + private static readonly string SdkVersion = $"OTel-{Environment.OSVersion.Platform}-.net-{typeof(OneCollectorExporter<>).Assembly.GetName()?.Version?.ToString() ?? "0.0.0"}"; + private static readonly string UserAgent = $".NET/{Environment.Version} HttpClient"; + + private readonly Uri endpoint; + private readonly string instrumentationKey; + private readonly OneCollectorExporterHttpTransportCompressionType compressionType; + private readonly HttpClient httpClient; + private MemoryStream? buffer; + + public HttpJsonPostTransport( + string instrumentationKey, + Uri endpoint, + OneCollectorExporterHttpTransportCompressionType compressionType, + HttpClient httpClient) + { + Debug.Assert(!string.IsNullOrWhiteSpace(instrumentationKey), "instrumentationKey was null or whitespace"); + Debug.Assert(endpoint != null, "endpoint was null"); + Debug.Assert(httpClient != null, "httpClient was null"); + + this.instrumentationKey = instrumentationKey!; + this.endpoint = endpoint!; + this.compressionType = compressionType; + this.httpClient = httpClient!; + + this.Description = $"http.jsonpost@{endpoint}"; + } + + public string Description { get; } + + public void Dispose() + { + this.buffer?.Dispose(); + } + + public bool Send(in TransportSendRequest sendRequest) + { + // Prevent OneCollector's HTTP operations from being instrumented. + using var scope = SuppressInstrumentationScope.Begin(); + + try + { + var content = this.BuildRequestContent(sendRequest.ItemStream); + + content.Headers.ContentType = new MediaTypeHeaderValue("application/x-json-stream") + { + CharSet = "utf-8", + }; + + using var request = new HttpRequestMessage(HttpMethod.Post, this.endpoint) + { + Content = content, + }; + + request.Headers.TryAddWithoutValidation("User-Agent", UserAgent); + request.Headers.TryAddWithoutValidation("sdk-version", SdkVersion); + request.Headers.TryAddWithoutValidation("x-apikey", this.instrumentationKey); + + bool logResponseDetails = OneCollectorExporterEventSource.Log.IsInformationalLoggingEnabled(); + + if (!logResponseDetails) + { + request.Headers.TryAddWithoutValidation("NoResponseBody", "true"); + } + +#if NET6_0_OR_GREATER + using var response = this.httpClient.Send(request, CancellationToken.None); +#else + using var response = this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); +#endif + + try + { + response.EnsureSuccessStatusCode(); + + OneCollectorExporterEventSource.Log.WriteTransportDataSentEventIfEnabled(sendRequest.ItemType, sendRequest.NumberOfItems, this.Description); + } + catch + { + response.Headers.TryGetValues("Collector-Error", out var collectorErrors); + + var errorDetails = logResponseDetails ? response.Content.ReadAsStringAsync().GetAwaiter().GetResult() : null; + + OneCollectorExporterEventSource.Log.WriteHttpTransportErrorResponseReceivedEventIfEnabled( + this.Description, + (int)response.StatusCode, + collectorErrors, + errorDetails); + + return false; + } + } + catch (Exception ex) + { + OneCollectorExporterEventSource.Log.WriteTransportExceptionThrownEventIfEnabled(this.Description, ex); + + return false; + } + + return true; + } + + private HttpContent BuildRequestContent(Stream stream) + { + switch (this.compressionType) + { + case OneCollectorExporterHttpTransportCompressionType.None: + return new NonDisposingStreamContent(stream); + + case OneCollectorExporterHttpTransportCompressionType.Deflate: + var buffer = this.buffer; + if (buffer == null) + { + buffer = this.buffer = new MemoryStream(8192); + } + else + { + buffer.SetLength(0); + } + + using (var compressionStream = new DeflateStream(buffer, CompressionLevel.Optimal, leaveOpen: true)) + { + stream.CopyTo(compressionStream); + } + + buffer.Position = 0; + + var content = new NonDisposingStreamContent(buffer); + + content.Headers.TryAddWithoutValidation("Content-Encoding", "deflate"); + + return content; + + default: + throw new NotSupportedException($"Compression type '{this.compressionType}' is not supported."); + } + } + + private sealed class NonDisposingStreamContent : HttpContent + { +#pragma warning disable CA2213 // Disposable fields should be disposed + private readonly Stream stream; +#pragma warning restore CA2213 // Disposable fields should be disposed + + public NonDisposingStreamContent(Stream stream) + { + Debug.Assert(stream != null, "stream was null"); + + this.stream = stream!; + } + + protected override bool TryComputeLength(out long length) + { + var stream = this.stream; + if (stream.CanSeek) + { + length = stream.Length - stream.Position; + return true; + } + else + { + length = 0; + return false; + } + } + +#if NET6_0_OR_GREATER + protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken) + { + this.stream.CopyTo(stream); + } + + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context, CancellationToken cancellationToken) + { + return this.stream.CopyToAsync(stream, cancellationToken); + } +#endif + + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) + { + return this.stream.CopyToAsync(stream); + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs new file mode 100644 index 0000000000..9edc4a601e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs @@ -0,0 +1,24 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +internal interface ITransport +{ + string Description { get; } + + bool Send(in TransportSendRequest sendRequest); +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs new file mode 100644 index 0000000000..90505bfa41 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Note: StyleCop doesn't understand the C#11 "required" modifier yet. Remove +// this in the future once StyleCop is updated. See: +// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3527 + +#pragma warning disable SA1206 // Declaration keywords should follow order + +namespace OpenTelemetry.Exporter.OneCollector; + +internal readonly struct TransportSendRequest +{ + public TransportSendRequest() + { +#if !NET7_0_OR_GREATER + // Note: This is needed because < NET7 doesn't understand required. + this.ItemType = string.Empty; + this.ItemStream = default!; +#endif + } + +#if NET7_0_OR_GREATER + public required string ItemType { get; init; } + + public required Stream ItemStream { get; init; } +#else + public string ItemType { get; init; } + + public Stream ItemStream { get; init; } +#endif + + public int? NumberOfItems { get; init; } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs new file mode 100644 index 0000000000..85d86f3ba2 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// OpenTelemetry exporter implementation for sending +/// telemetry data to Microsoft OneCollector. +/// +public sealed class OneCollectorLogExporter : OneCollectorExporter +{ + /// + /// Initializes a new instance of the class. + /// + /// . + public OneCollectorLogExporter(OneCollectorLogExporterOptions options) + : base(options) + { + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs new file mode 100644 index 0000000000..114760cee9 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -0,0 +1,91 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Reflection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Contains options for the class. +/// +public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions, ISinkFactory +{ + /// + /// Gets or sets the default event name. Default value: Log. + /// + /// + /// Note: The default event name is used when an has a null or whitespace . + /// + public string DefaultEventName { get; set; } = "Log"; + + /// + /// Gets the options. + /// + public BatchExportProcessorOptions BatchOptions { get; } = new(); + + /// + /// Gets or sets the default event namespace. Default value: from the assembly returned by . + /// + /// + /// Note: The default event namespace is used if a is not supplied. This is internal at the + /// moment because using the interface there should + /// always be a category name. + /// + internal string DefaultEventNamespace { get; set; } = Assembly.GetEntryAssembly()?.GetName().Name ?? string.Empty; + + ISink ISinkFactory.CreateSink() + { + this.Validate(); + + var transportOptions = this.TransportOptions; + +#pragma warning disable CA2000 // Dispose objects before losing scope + return new WriteDirectlyToTransportSink( + new LogRecordCommonSchemaJsonSerializer( + new EventNameManager(this.DefaultEventNamespace, this.DefaultEventName), + this.TenantToken!, + transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, + transportOptions.MaxNumberOfItemsPerPayload == -1 ? int.MaxValue : transportOptions.MaxNumberOfItemsPerPayload), + new HttpJsonPostTransport( + this.InstrumentationKey!, + transportOptions.Endpoint, + transportOptions.HttpCompression, + transportOptions.HttpClientFactory() ?? throw new InvalidOperationException($"{nameof(OneCollectorLogExporterOptions)} was missing HttpClientFactory or it returned null."))); +#pragma warning restore CA2000 // Dispose objects before losing scope + } + + internal override void Validate() + { + if (string.IsNullOrWhiteSpace(this.DefaultEventNamespace)) + { + throw new InvalidOperationException($"{nameof(this.DefaultEventNamespace)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); + } + + if (string.IsNullOrWhiteSpace(this.DefaultEventName)) + { + throw new InvalidOperationException($"{nameof(this.DefaultEventName)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); + } + + base.Validate(); + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs new file mode 100644 index 0000000000..36e26d989e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs @@ -0,0 +1,71 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Exporter.OneCollector; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Logs; + +/// +/// Contains extension methods to register the OneCollector log exporter. +/// +public static class OneCollectorOpenTelemetryLoggerOptionsExtensions +{ + /// + /// Add OneCollector exporter to the . + /// + /// . + /// The supplied for call + /// chaining. + public static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options) + => AddOneCollectorExporter(options, _ => { }); + + /// + /// Add OneCollector exporter to the . + /// + /// . + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options, + Action configure) + { + Guard.ThrowIfNull(options); + Guard.ThrowIfNull(configure); + + var logExporterOptions = new OneCollectorLogExporterOptions(); + + configure?.Invoke(logExporterOptions); + + var batchOptions = logExporterOptions.BatchOptions; + +#pragma warning disable CA2000 // Dispose objects before losing scope + options.AddProcessor( + new BatchLogRecordExportProcessor( + new OneCollectorLogExporter(logExporterOptions), + batchOptions.MaxQueueSize, + batchOptions.ScheduledDelayMilliseconds, + batchOptions.ExporterTimeoutMilliseconds, + batchOptions.MaxExportBatchSize)); +#pragma warning restore CA2000 // Dispose objects before losing scope + + return options; + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs new file mode 100644 index 0000000000..8190c71413 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs @@ -0,0 +1,77 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Internal; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// OpenTelemetry exporter implementation for sending telemetry data to +/// Microsoft OneCollector. +/// +/// Item type. +public class OneCollectorExporter : BaseExporter + where T : class +{ + private readonly string typeName; + private readonly ISink sink; + private Resource? resource; + + /// + /// Initializes a new instance of the class. + /// + /// . + internal OneCollectorExporter(ISinkFactory sinkFactory) + { + Guard.ThrowIfNull(sinkFactory); + + this.typeName = typeof(T).Name; + this.sink = sinkFactory.CreateSink(); + } + + /// + public sealed override ExportResult Export(in Batch batch) + { + try + { + var resource = this.resource ??= this.ParentProvider?.GetResource() ?? Resource.Empty; + + var numberOfRecordsWritten = this.sink.Write(resource, in batch); + + return numberOfRecordsWritten > 0 + ? ExportResult.Success + : ExportResult.Failure; + } + catch (Exception ex) + { + OneCollectorExporterEventSource.Log.WriteExportExceptionThrownEventIfEnabled(this.typeName, ex); + + return ExportResult.Failure; + } + } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + (this.sink as IDisposable)?.Dispose(); + } + + base.Dispose(disposing); + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs new file mode 100644 index 0000000000..067e3e241a --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs @@ -0,0 +1,33 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Describes the OneCollector compression algorithm type to use when sending telemetry over HTTP. +/// +internal enum OneCollectorExporterHttpTransportCompressionType +{ + /// + /// Uncompressed telemetry data. + /// + None, + + /// + /// Compressed telemetry data using the Deflate algorithm. + /// + Deflate, +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs new file mode 100644 index 0000000000..fae8c8a977 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -0,0 +1,57 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Contains options for the class. +/// +public abstract class OneCollectorExporterOptions +{ + internal OneCollectorExporterOptions() + { + } + + /// + /// Gets or sets the OneCollector tenant token. + /// + public string? TenantToken { get; set; } + + /// + /// Gets or sets the OneCollector instrumentation key. + /// + public string? InstrumentationKey { get; set; } + + /// + /// Gets the OneCollector transport options. + /// + public OneCollectorExporterTransportOptions TransportOptions { get; } = new(); + + internal virtual void Validate() + { + if (string.IsNullOrWhiteSpace(this.TenantToken)) + { + throw new InvalidOperationException($"{nameof(this.TenantToken)} was not specified on {this.GetType().Name} options."); + } + + if (string.IsNullOrWhiteSpace(this.InstrumentationKey)) + { + throw new InvalidOperationException($"{nameof(this.InstrumentationKey)} was not specified on {this.GetType().Name} options."); + } + + this.TransportOptions.Validate(); + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs new file mode 100644 index 0000000000..ef82e213ef --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs @@ -0,0 +1,109 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Contains transport options for the class. +/// +public sealed class OneCollectorExporterTransportOptions +{ + internal const string DefaultOneCollectorEndpoint = "https://mobile.events.data.microsoft.com/OneCollector/1.0/"; + internal const int DefaultMaxPayloadSizeInBytes = 1024 * 1024 * 4; + internal const int DefaultMaxNumberOfItemsPerPayload = 1500; + + internal static readonly Func DefaultHttpClientFactory = () => new HttpClient(); + + internal OneCollectorExporterTransportOptions() + { + } + + /// + /// Gets or sets OneCollector endpoint address. Default value: + /// https://mobile.events.data.microsoft.com/OneCollector/1.0/. + /// + public Uri Endpoint { get; set; } = new Uri(DefaultOneCollectorEndpoint); + + /// + /// Gets or sets OneCollector transport protocol. Default value: . + /// + internal OneCollectorExporterTransportProtocolType Protocol { get; set; } = OneCollectorExporterTransportProtocolType.HttpJsonPost; + + /// + /// Gets or sets the maximum request payload size in bytes when sending data + /// to OneCollector. Default value: 4,194,304. + /// + /// + /// Note: Set to -1 for unlimited request payload size. + /// + internal int MaxPayloadSizeInBytes { get; set; } = DefaultMaxPayloadSizeInBytes; + + /// + /// Gets or sets the maximum number of items per request payload when + /// sending data to OneCollector. Default value: 1500. + /// + /// + /// Note: Set to -1 for unlimited number of items per request payload. + /// + internal int MaxNumberOfItemsPerPayload { get; set; } = DefaultMaxNumberOfItemsPerPayload; + + /// + /// Gets or sets the compression type to use when transmiting telemetry over + /// HTTP. Default value: . + /// + internal OneCollectorExporterHttpTransportCompressionType HttpCompression { get; set; } = OneCollectorExporterHttpTransportCompressionType.Deflate; + + /// + /// Gets or sets the factory function called to create the instance that will be used at runtime to transmit + /// telemetry over HTTP. The returned instance will be reused for all export + /// invocations. + /// + /// + /// Notes: + /// + /// The default behavior when using the class is an will be instantiated directly. + /// + /// + internal Func HttpClientFactory { get; set; } = DefaultHttpClientFactory; + + internal void Validate() + { + if (this.Endpoint == null) + { + throw new InvalidOperationException($"{nameof(this.Endpoint)} was not specified on {this.GetType().Name} options."); + } + + if (this.HttpClientFactory == null) + { + throw new InvalidOperationException($"{nameof(this.HttpClientFactory)} was not specified on {this.GetType().Name} options."); + } + + if (this.MaxPayloadSizeInBytes <= 0 && this.MaxPayloadSizeInBytes != -1) + { + throw new InvalidOperationException($"{nameof(this.MaxPayloadSizeInBytes)} was invalid on {this.GetType().Name} options."); + } + + if (this.MaxNumberOfItemsPerPayload <= 0 && this.MaxNumberOfItemsPerPayload != -1) + { + throw new InvalidOperationException($"{nameof(this.MaxNumberOfItemsPerPayload)} was invalid on {this.GetType().Name} options."); + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs new file mode 100644 index 0000000000..51a55c1777 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs @@ -0,0 +1,28 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Describes the OneCollector transport protocol to use when sending telemetry. +/// +internal enum OneCollectorExporterTransportProtocolType +{ + /// + /// HTTP JSON POST protocol. + /// + HttpJsonPost, +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj new file mode 100644 index 0000000000..a156a0eac1 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -0,0 +1,25 @@ + + + + true + An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector + OpenTelemetry Authors + net7.0;net6.0;netstandard2.1;netstandard2.0 + $(TargetFrameworks);net462 + Exporter.OneCollector- + enable + true + true + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md new file mode 100644 index 0000000000..7b2e42370e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -0,0 +1,39 @@ +# OneCollector Exporter for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) + +The OneCollector Exporter exports telemetry to the Microsoft OneCollector +backend. + +> **Warning** +> This is an early preview version breaking changes should be expected. + +## Installation + +```shell +dotnet add package --prerelease OpenTelemetry.Exporter.OneCollector +``` + +## Basic usage + +```csharp +using var logFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.ParseStateValues = true; + builder.IncludeScopes = true; + builder.AddOneCollectorExporter(o => + { + o.TenantToken = "tenant-token-here"; + o.InstrumentationKey = "instrumentation-key-here"; + }); + })); + +var logger = logFactory.CreateLogger(); + +using var scope = logger.BeginScope("{requestContext}", Guid.NewGuid()); + +logger.LogInformation("Request received {requestId}!", 1); +logger.LogWarning("Warning encountered {error_code}!", 0xBAADBEEF); +``` diff --git a/src/OpenTelemetry.Internal/Guard.cs b/src/OpenTelemetry.Internal/Guard.cs index 09bc0f8e93..0015ea41f4 100644 --- a/src/OpenTelemetry.Internal/Guard.cs +++ b/src/OpenTelemetry.Internal/Guard.cs @@ -16,6 +16,13 @@ #nullable enable +// Note: When implicit usings are enabled in a project this file will generate +// warnings/errors without this suppression. +#pragma warning disable IDE0005 // Using directive is unnecessary. + +// Note: For some targets this file will contain more than one type/namespace. +#pragma warning disable IDE0161 // Convert to file-scoped namespace + using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs new file mode 100644 index 0000000000..96fafa8fcf --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs @@ -0,0 +1,134 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Note: When implicit usings are enabled in a project this file will generate +// warnings/errors without this suppression. +#pragma warning disable IDE0005 // Using directive is unnecessary. + +#nullable enable + +using System; +using System.Net; +using System.Security.Cryptography; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTelemetry.Tests; + +internal static class TestHttpServer +{ +#if !NET6_0_OR_GREATER + private static readonly Random GlobalRandom = new(); +#endif + + public static IDisposable RunServer(Action action, out string host, out int port) + { + host = "localhost"; + port = 0; + RunningServer? server = null; + + var retryCount = 5; + while (true) + { + try + { +#if NET6_0_OR_GREATER + port = RandomNumberGenerator.GetInt32(2000, 5000); +#else +#pragma warning disable CA5394 // Do not use insecure randomness + port = GlobalRandom.Next(2000, 5000); +#pragma warning restore CA5394 // Do not use insecure randomness +#endif + server = new RunningServer(action, host, port); + server.Start(); + break; + } + catch (HttpListenerException ex) + { + server?.Dispose(); + server = null; + if (--retryCount <= 0) + { + throw new InvalidOperationException("TestHttpServer could not be started.", ex); + } + } + } + + return server; + } + + private sealed class RunningServer : IDisposable + { + private readonly Task httpListenerTask; + private readonly HttpListener listener; + private readonly AutoResetEvent initialized = new(false); + + public RunningServer(Action action, string host, int port) + { + this.listener = new HttpListener(); + + this.listener.Prefixes.Add($"http://{host}:{port}/"); + this.listener.Start(); + + this.httpListenerTask = new Task(async () => + { + while (true) + { + try + { + var ctxTask = this.listener.GetContextAsync(); + + this.initialized.Set(); + + action(await ctxTask.ConfigureAwait(false)); + } + catch (Exception ex) + { + if (ex is ObjectDisposedException + || (ex is HttpListenerException httpEx && httpEx.ErrorCode == 995)) + { + // Listener was closed before we got into GetContextAsync or + // Listener was closed while we were in GetContextAsync. + break; + } + + throw; + } + } + }); + } + + public void Start() + { + this.httpListenerTask.Start(); + this.initialized.WaitOne(); + } + + public void Dispose() + { + try + { + this.listener.Close(); + this.httpListenerTask?.Wait(); + this.initialized.Dispose(); + } + catch (ObjectDisposedException) + { + // swallow this exception just in case + } + } + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs new file mode 100644 index 0000000000..cb7673710b --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -0,0 +1,186 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text; +using System.Text.Json; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class CommonSchemaJsonSerializationHelperTests +{ + [Fact] + public void SerializeKeyValueToJsonTest() + { + string actualJson = GetJson(key: "key1", value: "value1"); + + Assert.Equal("\"key1\":\"value1\"", actualJson); + } + + [Theory] + [InlineData("stringValue1", "\"stringValue1\"")] + [InlineData(18, "18")] + [InlineData(18L, "18")] + [InlineData((short)18, "18")] + [InlineData(18U, "18")] + [InlineData(18UL, "18")] + [InlineData((ushort)18, "18")] + [InlineData((byte)18, "18")] + [InlineData((sbyte)18, "18")] + [InlineData(true, "true")] + [InlineData(false, "false")] + [InlineData(null, "null")] + [InlineData(1.01D, "1.01")] +#if NETFRAMEWORK + // Note: There seems to be some kind of round-tripping bug in .NET + // Framework. See: + // https://stackoverflow.com/questions/24299692/why-is-a-round-trip-conversion-via-a-string-not-safe-for-a-double + [InlineData(2.1099999F, "2.1099999")] +#else + [InlineData(1.02F, "1.02")] +#endif + public void SerializeValueToJsonTest(object? value, string expectedJson) + { + string actualJson = GetJson(value); + + Assert.Equal(expectedJson, actualJson); + } + + [Fact] + public void SerializeComplexValueToJsonTest() + { + this.SerializeValueToJsonTest(18.99M, "18.99"); + + /* Begin note: STJ does some trimming of DateTime\Offsets so we manually + * construct these values. See: + * https://github.com/dotnet/runtime/blob/78ed4438a42acab80541e9bde1910abaa8841db2/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Date.cs#L43 + */ + var dt = DateTime.SpecifyKind(new DateTime(2023, 1, 18, 10, 18, 0), DateTimeKind.Utc); + this.SerializeValueToJsonTest(dt, "\"2023-01-18T10:18:00Z\""); + var dto = new DateTimeOffset(new DateTime(2023, 1, 18, 10, 18, 0), new TimeSpan(1, 0, 0)); + this.SerializeValueToJsonTest(dto, "\"2023-01-18T10:18:00+01:00\""); + /* End note. */ + + var byteArray = new byte[] { 0, 0xff }; + this.SerializeValueToJsonTest(byteArray, "\"AP8=\""); + this.SerializeValueToJsonTest(new ArraySegment(byteArray, 0, byteArray.Length), "\"AP8=\""); + this.SerializeValueToJsonTest(new Memory(byteArray, 0, byteArray.Length), "\"AP8=\""); + + var array = new[] { 0, 1, 18 }; + this.SerializeValueToJsonTest(array, "[0,1,18]"); + + var map = new List> { new KeyValuePair("key1", "value1") }; + this.SerializeValueToJsonTest(map, "{\"key1\":\"value1\"}"); + + var typeWithToString = new TypeWithToString(); + this.SerializeValueToJsonTest(typeWithToString, "\"Hello world\""); + + var typeWithThrowingToString = new TypeWithThrowingToString(); + this.SerializeValueToJsonTest(typeWithThrowingToString, $"\"ERROR: type {typeof(CommonSchemaJsonSerializationHelperTests).FullName}\\u002B{typeof(TypeWithThrowingToString).Name} is not supported\""); + + var ts = new TimeSpan(0, 10, 18, 59, 1); + this.SerializeValueToJsonTest(ts, "\"10:18:59.0010000\""); + + var guid = Guid.NewGuid(); + this.SerializeValueToJsonTest(guid, $"\"{guid}\""); + + var uri = new Uri("http://www.localhost.com"); + this.SerializeValueToJsonTest(uri, "\"http://www.localhost.com\""); + + var version = new Version("1.4.0"); + this.SerializeValueToJsonTest(version, "\"1.4.0\""); + +#if NET6_0_OR_GREATER + var typeWithISpanFormattable = new TypeWithISpanFormattable(overflow: false); + this.SerializeValueToJsonTest(typeWithISpanFormattable, "\"hello\""); + + var typeWithISpanFormattableOverflow = new TypeWithISpanFormattable(overflow: true); + this.SerializeValueToJsonTest(typeWithISpanFormattableOverflow, "\"Overflow\""); +#endif + +#if NET7_0_OR_GREATER + var dateOnly = DateOnly.FromDateTime(dt); + this.SerializeValueToJsonTest(dateOnly, $"\"{dateOnly:O}\""); + + var to = TimeOnly.FromTimeSpan(ts); + this.SerializeValueToJsonTest(to, "\"10:18:59.0010000\""); +#endif + } + + private static string GetJson(object? value, string? key = null) + { + using var stream = new MemoryStream(); + + using (var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { SkipValidation = true })) + { + if (key is not null) + { + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(key, value, writer); + } + else + { + CommonSchemaJsonSerializationHelper.SerializeValueToJson(value, writer); + } + } + + return Encoding.UTF8.GetString(stream.ToArray()); + } + + private sealed class TypeWithToString + { + public override string ToString() => "Hello world"; + } + + private sealed class TypeWithThrowingToString + { + public override string ToString() => throw new NotImplementedException(); + } + +#if NET6_0_OR_GREATER + private sealed class TypeWithISpanFormattable : ISpanFormattable + { + private readonly bool overflow; + + public TypeWithISpanFormattable(bool overflow) + { + this.overflow = overflow; + } + + public override string ToString() + => "Overflow"; + + public string ToString(string? format, IFormatProvider? formatProvider) + => this.ToString(); + + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) + { + if (!this.overflow && destination.Length >= 5) + { + destination[0] = 'h'; + destination[1] = 'e'; + destination[2] = 'l'; + destination[3] = 'l'; + destination[4] = 'o'; + charsWritten = 5; + return true; + } + + charsWritten = 0; + return false; + } + } +#endif +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs new file mode 100644 index 0000000000..a9d9d8683c --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs @@ -0,0 +1,126 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections; +using System.Text; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class EventNameManagerTests +{ + [Theory] + [InlineData("Company.Product")] + [InlineData("Company")] + [InlineData("company.product")] + [InlineData("company99.1product")] + [InlineData("c")] + public void ValidEventNamespaceTest(string eventNamespace) + { + Assert.True(EventNameManager.IsEventNamespaceValid(eventNamespace)); + } + + [Theory] + [InlineData("9")] + [InlineData("Company..Product")] + [InlineData("Company.")] + [InlineData(".Company")] + [InlineData("")] + public void InvalidEventNamespaceTest(string eventNamespace) + { + Assert.False(EventNameManager.IsEventNamespaceValid(eventNamespace)); + } + + [Theory] + [InlineData("Opened")] + [InlineData("closed")] + [InlineData("c")] + [InlineData("event9")] + public void ValidEventNameTest(string eventNamespace) + { + Assert.True(EventNameManager.IsEventNameValid(eventNamespace)); + } + + [Theory] + [InlineData("9")] + [InlineData("Some.Event")] + [InlineData("Event.")] + [InlineData(".Event")] + [InlineData("")] + public void InvalidEventNameTest(string eventNamespace) + { + Assert.False(EventNameManager.IsEventNameValid(eventNamespace)); + } + + [Fact] + public void DefaultEventFullNameLengthTest() + { + Assert.Throws(() => new EventNameManager("N", "N")); + Assert.Throws(() => new EventNameManager(new string('N', 99), "N")); + Assert.Throws(() => new EventNameManager("N", new string('N', 99))); + } + + [Theory] + [InlineData(null, null, "DefaultNamespace.DefaultName")] + [InlineData("myNamespace", null, "MyNamespace.DefaultName")] + [InlineData(null, "myEvent", "DefaultNamespace.MyEvent")] + [InlineData("", " ", "DefaultNamespace.DefaultName")] + [InlineData("9", "[]", "DefaultNamespace.DefaultName")] + public void DefaultEventNamespaceAndNameUsedToGenerateFullNameTest(string? eventNamespace, string? eventName, string expectedEventFullName) + { + var eventNameManager = new EventNameManager("defaultNamespace", "defaultName"); + + var resolveEventFullName = eventNameManager.ResolveEventFullName(eventNamespace, eventName); + + Assert.Equal(Encoding.ASCII.GetBytes($"\"{expectedEventFullName}\""), resolveEventFullName.ToArray()); + } + + [Fact] + public void DefaultEventNamespaceAndNameUsedToGenerateFullNameLengthTest() + { + var eventNameManager = new EventNameManager("defaultNamespace", "defaultName"); + + var resolveEventFullName = eventNameManager.ResolveEventFullName("N", "N"); + + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.ToArray()); + + resolveEventFullName = eventNameManager.ResolveEventFullName(new string('N', 99), "N"); + + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.ToArray()); + + resolveEventFullName = eventNameManager.ResolveEventFullName("N", new string('N', 99)); + + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.ToArray()); + } + + [Fact] + public void EventNameCacheTest() + { + var eventNameManager = new EventNameManager("defaultNamespace", "defaultName"); + + Assert.Empty(eventNameManager.EventNamespaceCache); + + eventNameManager.ResolveEventFullName("Test", "Test"); + + Assert.Single(eventNameManager.EventNamespaceCache); + Assert.Single((eventNameManager.EventNamespaceCache["Test"] as Hashtable)!); + + eventNameManager.ResolveEventFullName("test", "test"); + + Assert.Single(eventNameManager.EventNamespaceCache); + Assert.Single((eventNameManager.EventNamespaceCache["Test"] as Hashtable)!); + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs new file mode 100644 index 0000000000..910c5bdd85 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -0,0 +1,163 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.IO.Compression; +using System.Net; +using System.Text; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class HttpJsonPostTransportTests +{ + [Fact] + public void RequestWithoutCompressionTest() + { + var request = "{\"key1\":\"value1\"}"; + + using var httpClient = new HttpClient(); + + RunHttpServerTest( + request, + requestUri => + { + return new HttpJsonPostTransport( + "instrumentation-key", + requestUri, + OneCollectorExporterHttpTransportCompressionType.None, + httpClient); + }, + (req, body) => + { + AssertStandardHeaders(req); + Assert.True(string.IsNullOrWhiteSpace(req.Headers["Content-Encoding"])); + Assert.Equal(request, Encoding.ASCII.GetString(body.ToArray())); + }); + } + + [Fact] + public void RequestUsingDeflateCompressionTest() + { + var request = "{\"key1\":\"value1\"}"; + + using var httpClient = new HttpClient(); + + RunHttpServerTest( + request, + requestUri => + { + return new HttpJsonPostTransport( + "instrumentation-key", + requestUri, + OneCollectorExporterHttpTransportCompressionType.Deflate, + httpClient); + }, + (req, body) => + { + AssertStandardHeaders(req); + Assert.Equal("deflate", req.Headers["Content-Encoding"]); + + using var uncompressedStream = new MemoryStream(); + + using (var compressionStream = new DeflateStream(body, CompressionMode.Decompress)) + { + compressionStream.CopyTo(uncompressedStream); + } + + uncompressedStream.Position = 0; + + Assert.Equal(request, Encoding.ASCII.GetString(uncompressedStream.ToArray())); + }); + } + + private static void AssertStandardHeaders(HttpListenerRequest request) + { + Assert.Equal("POST", request.HttpMethod); + Assert.True(!string.IsNullOrWhiteSpace(request.Headers["User-Agent"])); + Assert.True(!string.IsNullOrWhiteSpace(request.Headers["sdk-version"])); + Assert.True(!string.IsNullOrWhiteSpace(request.Headers["x-apikey"])); + Assert.Equal("application/x-json-stream; charset=utf-8", request.Headers["Content-Type"]); + Assert.Equal("true", request.Headers["NoResponseBody"]); + } + + private static void RunHttpServerTest( + string requestBody, + Func createTransportFunc, + Action assertRequestAction) + { + bool requestReceivedAndAsserted = false; + Exception? testException = null; + + using var testServer = TestHttpServer.RunServer( + context => + { + context.Response.StatusCode = 200; + + using MemoryStream requestBody = new MemoryStream(); + + context.Request.InputStream.CopyTo(requestBody); + + try + { + requestBody.Position = 0; + + assertRequestAction(context.Request, requestBody); + + requestReceivedAndAsserted = true; + } + catch (Exception ex) + { + testException = ex; + } + finally + { + context.Response.OutputStream.Close(); + } + }, + out var testServerHost, + out var testServerPort); + + var transport = createTransportFunc( + new Uri($"http://{testServerHost}:{testServerPort}/")); + + try + { + var requestBodyBytes = Encoding.ASCII.GetBytes(requestBody); + + using var requestBodyStream = new MemoryStream(requestBodyBytes); + + var result = transport.Send( + new TransportSendRequest + { + ItemStream = requestBodyStream, + ItemType = "TestRequest", + }); + + if (testException != null) + { + throw testException; + } + + Assert.True(result); + Assert.True(requestReceivedAndAsserted); + } + finally + { + (transport as IDisposable)?.Dispose(); + } + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs new file mode 100644 index 0000000000..ec091eb302 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -0,0 +1,236 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Reflection; +using System.Text; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class LogRecordCommonSchemaJsonSerializerTests +{ + [Fact] + public void EmptyLogRecordJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => { }); + + Assert.Equal( + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + json); + } + + [Fact] + public void MultipleEmptyLogRecordJsonTest() + { + string json = GetLogRecordJson(2, (index, logRecord) => { }); + + Assert.Equal( + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n" + + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + json); + } + + [Theory] + [InlineData(LogLevel.Trace, "Trace", 1)] + [InlineData(LogLevel.Debug, "Debug", 5)] + [InlineData(LogLevel.Information, "Information", 9)] + [InlineData(LogLevel.Warning, "Warning", 13)] + [InlineData(LogLevel.Error, "Error", 17)] + [InlineData(LogLevel.Critical, "Critical", 21)] + [InlineData(LogLevel.None, "Trace", 1)] + public void LogRecordLogLevelJsonTest(LogLevel logLevel, string severityText, int severityNumber) + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.LogLevel = logLevel; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"{severityText}\",\"severityNumber\":{severityNumber}}}}}\n", + json); + } + + [Theory] + [InlineData("MyClass.Company", null)] + [InlineData("MyClass.Company", "MyEvent")] + public void LogRecordCategoryNameAndEventNameJsonTest(string categoryName, string? eventName) + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.CategoryName = categoryName; + logRecord.EventId = new(0, eventName); + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"{categoryName}.{eventName ?? "Name"}\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}}}}\n", + json); + } + + [Fact] + public void LogRecordTimestampJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.Timestamp = DateTime.SpecifyKind(new DateTime(2023, 1, 18, 10, 18, 0), DateTimeKind.Utc); + }); + + Assert.Equal( + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2023-01-18T10:18:00Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + json); + } + + [Fact] + public void LogRecordOriginalFormatBodyJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.StateValues = new List> { new KeyValuePair("{OriginalFormat}", "hello world") }; + logRecord.FormattedMessage = "goodbye world"; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\"}}}}\n", + json); + } + + [Fact] + public void LogRecordFormattedMessageBodyJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.FormattedMessage = "goodbye world"; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"goodbye world\"}}}}\n", + json); + } + + [Fact] + public void LogRecordResourceJsonTest() + { + var resource = ResourceBuilder.CreateEmpty() + .AddAttributes(new Dictionary + { + ["resourceKey1"] = "resourceValue1", + ["resourceKey2"] = "resourceValue2", + }) + .Build(); + + string json = GetLogRecordJson(1, (index, logRecord) => { }, resource); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"resourceKey1\":\"resourceValue1\",\"resourceKey2\":\"resourceValue2\"}}}}\n", + json); + } + + [Fact] + public void LogRecordScopesJsonTest() + { + var scopeProvider = new ScopeProvider( + new List> { new KeyValuePair("scope1Key1", "scope1Value1"), new KeyValuePair("scope1Key2", "scope1Value2") }, + new List> { new KeyValuePair("scope2Key1", "scope2Value1") }); + + string json = GetLogRecordJson(1, (index, logRecord) => { }, scopeProvider: scopeProvider); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"scope1Key1\":\"scope1Value1\",\"scope1Key2\":\"scope1Value2\",\"scope2Key1\":\"scope2Value1\"}}}}\n", + json); + } + + [Fact] + public void LogRecordStateValuesJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.StateValues = new List> { new KeyValuePair("stateKey1", "stateValue1"), new KeyValuePair("stateKey2", "stateValue2") }; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"stateKey1\":\"stateValue1\",\"stateKey2\":\"stateValue2\"}}}}\n", + json); + } + + private static string GetLogRecordJson( + int numberOfLogRecords, + Action writeLogRecordCallback, + Resource? resource = null, + ScopeProvider? scopeProvider = null) + { + var serializer = new LogRecordCommonSchemaJsonSerializer( + new("Namespace", "Name"), + "tenant-token"); + + using var stream = new MemoryStream(); + + var logRecords = new LogRecord[numberOfLogRecords]; + + for (int i = 0; i < numberOfLogRecords; i++) + { + var logRecord = (LogRecord)Activator.CreateInstance(typeof(LogRecord), nonPublic: true)!; + + logRecord.Timestamp = DateTime.SpecifyKind(new DateTime(2032, 1, 18, 10, 11, 12), DateTimeKind.Utc); + + if (scopeProvider != null) + { + var setScopeProviderMethod = typeof(LogRecord).GetProperty("ScopeProvider", BindingFlags.Instance | BindingFlags.NonPublic)?.SetMethod + ?? throw new InvalidOperationException("LogRecord.ScopeProvider.Set could not be found reflectively."); + + setScopeProviderMethod.Invoke(logRecord, new object[] { scopeProvider }); + } + + writeLogRecordCallback(i, logRecord); + logRecords[i] = logRecord; + } + + var batch = new Batch(logRecords, numberOfLogRecords); + + serializer.SerializeBatchOfItemsToStream( + resource ?? Resource.Empty, + in batch, + stream, + initialSizeOfPayloadInBytes: 0, + out var result); + + return Encoding.UTF8.GetString(stream.ToArray()); + } + + private sealed class ScopeProvider : IExternalScopeProvider + { + private readonly List>[] scopes; + + public ScopeProvider(params List>[] scopes) + { + this.scopes = scopes; + } + + public void ForEachScope(Action callback, TState state) + { + foreach (var scope in this.scopes) + { + callback(scope, state); + } + } + + public IDisposable Push(object state) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj new file mode 100644 index 0000000000..bf5c8efbf9 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -0,0 +1,32 @@ + + + + Unit test project for OneCollector Exporters for OpenTelemetry + + net7.0;net6.0 + $(TargetFrameworks);net48;net472;net471;net47;net462 + enable + true + true + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs new file mode 100644 index 0000000000..f2ac6df9ff --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -0,0 +1,180 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text; +using System.Text.Json; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +// Suppressed because the underscores help with readability. That and artistic +// license! +#pragma warning disable CA1707 // Identifiers should not contain underscores + +public class WriteDirectlyToTransportSinkTests +{ + [Fact] + public void FullDataWrittenToTransportTest() + { + var transport = new TestTransport(); + + using var sink = new WriteDirectlyToTransportSink( + new TestSerializer(), + transport); + + var items = new string[] + { + "item1", + "item2", + "item3", + }; + + var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + + Assert.Equal(3, numberOfRecordsWritten); + + var data = transport.ExportedData[0]; + + Assert.NotNull(data); + + Assert.Equal("\"item1\"\n\"item2\"\n\"item3\"\n", Encoding.ASCII.GetString(data)); + + Assert.Equal(0, sink.Buffer.Length); + } + + [Fact] + public void PartialDataWrittenToTransport_MaxItemsPerPayload_Test() + { + var transport = new TestTransport(); + + using var sink = new WriteDirectlyToTransportSink( + new TestSerializer(maxNumberOfItemsPerPayload: 2), + transport); + + var items = new string[] + { + "item1", + "item2", + "item3", + }; + + var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + + Assert.Equal(2, numberOfRecordsWritten); + + var data = transport.ExportedData[0]; + + Assert.NotNull(data); + + Assert.Equal("\"item1\"\n\"item2\"\n", Encoding.ASCII.GetString(data)); + + Assert.Equal(0, sink.Buffer.Length); + } + + [Fact] + public void PartialDataWrittenToTransport_MaxPayloadSize_Test() + { + var expectedPayloadSizeInBytes = "\"item1\"\n\"item2\"\n".Length; + + var transport = new TestTransport(); + + var sink = new WriteDirectlyToTransportSink( + new TestSerializer(maxPayloadSizeInBytes: expectedPayloadSizeInBytes + 1), + transport); + + var items = new string[] + { + "item1", + "item2", + "item3", + }; + + var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + + Assert.Equal(3, numberOfRecordsWritten); + + var data = transport.ExportedData[0]; + + Assert.NotNull(data); + Assert.Equal(expectedPayloadSizeInBytes, data.Length); + Assert.Equal("\"item1\"\n\"item2\"\n", Encoding.ASCII.GetString(data)); + + Assert.NotEqual(0, sink.Buffer.Length); + + items = new string[] + { + "item4", + "item5", + }; + + numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + + Assert.Equal(2, numberOfRecordsWritten); + + data = transport.ExportedData[1]; + + Assert.NotNull(data); + Assert.Equal(expectedPayloadSizeInBytes, data.Length); + Assert.Equal("\"item3\"\n\"item4\"\n", Encoding.ASCII.GetString(data)); + + Assert.NotEqual(0, sink.Buffer.Length); + + sink.Dispose(); + + Assert.Equal(0, sink.Buffer.Length); + + data = transport.ExportedData[2]; + + Assert.NotNull(data); + Assert.Equal("\"item5\"\n", Encoding.ASCII.GetString(data)); + } + + private sealed class TestSerializer : CommonSchemaJsonSerializer + { + public TestSerializer( + int maxPayloadSizeInBytes = int.MaxValue, + int maxNumberOfItemsPerPayload = int.MaxValue) + : base("tenant-token", maxPayloadSizeInBytes, maxNumberOfItemsPerPayload) + { + } + + public override string Description => nameof(TestSerializer); + + protected override void SerializeItemToJson(Resource resource, string item, Utf8JsonWriter writer) + { + writer.WriteStringValue(item); + } + } + + private sealed class TestTransport : ITransport + { + public string Description => nameof(TestTransport); + + public List ExportedData { get; } = new(); + + public bool Send(in TransportSendRequest sendRequest) + { + var stream = new MemoryStream(); + + sendRequest.ItemStream.CopyTo(stream); + + this.ExportedData.Add(stream.ToArray()); + + return true; + } + } +} From 673e1f6b3adfebfc664f871967ceafebd0e77e71 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 15 Feb 2023 14:53:01 -0800 Subject: [PATCH 0564/1499] Updated projects to build better with VS Code / OmniSharp on Mac (#1002) --- .vscode/settings.json | 7 ++++- .../wcf/shared/Examples.Wcf.Shared.csproj | 3 +- ...elemetry.Contrib.Extensions.AWSXRay.csproj | 3 +- ...lemetry.Contrib.Instrumentation.AWS.csproj | 3 +- .../OpenTelemetry.Exporter.Geneva.csproj | 1 + .../OpenTelemetry.Exporter.Instana.csproj | 7 +++-- .../OpenTelemetry.Exporter.Stackdriver.csproj | 1 + ...enTelemetry.Extensions.AzureMonitor.csproj | 3 +- .../OpenTelemetry.Extensions.Docker.csproj | 3 +- ...ions.PersistentStorage.Abstractions.csproj | 3 +- ...emetry.Extensions.PersistentStorage.csproj | 3 +- .../OpenTelemetry.Extensions.csproj | 5 ++-- ...Instrumentation.ElasticsearchClient.csproj | 1 + .../AsyncStreamReaderProxy.cs | 4 +-- .../ClientStreamWriterProxy.cs | 4 +-- .../ClientTracingInterceptor.cs | 6 ++-- .../RpcScope.cs | 4 +-- .../ServerStreamWriterProxy.cs | 4 +-- .../ServerTracingInterceptor.cs | 6 ++-- ...ngfireInstrumentationJobFilterAttribute.cs | 2 +- ...enTelemetry.Instrumentation.Runtime.csproj | 3 +- .../OpenTelemetry.Instrumentation.Wcf.csproj | 3 +- ...ry.Contrib.Extensions.AWSXRay.Tests.csproj | 3 +- ...TestServerCertificateValidationProvider.cs | 29 ++++++++++-------- ...y.Contrib.Instrumentation.AWS.Tests.csproj | 3 +- .../Tools/MockHttpRequest.cs | 4 +-- ...Telemetry.Exporter.Geneva.Benchmark.csproj | 30 +++++++++---------- .../UnixDomainSocketDataTransportTests.cs | 11 +++++-- ...elemetry.Exporter.Stackdriver.Tests.csproj | 2 +- ...metry.Extensions.AzureMonitor.Tests.csproj | 2 +- ...enTelemetry.Extensions.Docker.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.Tests.csproj | 2 +- ...try.Instrumentation.AWSLambda.Tests.csproj | 2 +- ...on.AspNet.TelemetryHttpModule.Tests.csproj | 2 +- ...mentation.EntityFrameworkCore.Tests.csproj | 2 +- ...Instrumentation.EventCounters.Tests.csproj | 2 +- .../FoobarService.cs | 2 +- .../GrpcCoreClientInterceptorTests.cs | 4 +-- ...etry.Instrumentation.GrpcCore.Tests.csproj | 2 +- ...etry.Instrumentation.Hangfire.Tests.csproj | 5 ++-- ...try.Instrumentation.MySqlData.Tests.csproj | 2 +- ...metry.Instrumentation.Process.Tests.csproj | 2 +- ...emetry.Instrumentation.Quartz.Tests.csproj | 5 ++-- ...metry.Instrumentation.Runtime.Tests.csproj | 2 +- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 2 +- 45 files changed, 118 insertions(+), 83 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5c19a07622..6b2aa6484b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,10 @@ { "cSpell.words": [ - "fluentdData" + "awsx", + "fluentddata", + "otel", + "protobuf", + "traceparent", + "xunit" ] } diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index edcee4349e..e4e7f643f8 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -1,7 +1,8 @@  - net462;netstandard2.0 + + netstandard2.0;net462 diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 1064cc11a9..9f5a91f4e3 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -1,6 +1,7 @@  - net452;netstandard2.0 + + netstandard2.0;net452 OpenTelemetry extensions for AWS X-Ray. Extensions.AWSXRay- diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 01adf3f3f5..1a7b34718c 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -1,7 +1,8 @@ - net452;netstandard2.0 + + netstandard2.0;net452 AWS client instrumentation for OpenTelemetry .NET Instrumentation.AWS- diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index b2c9982436..41c3ddcc7b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,6 +5,7 @@ An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 + net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 5725bf828c..1106dbce56 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -1,10 +1,11 @@ + netstandard2.0;net461 - Instana Tracing APM - Instana .NET Exporter for OpenTelemetry - Exporter.Instana- + Instana Tracing APM + Instana .NET Exporter for OpenTelemetry + Exporter.Instana- diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index a20ac500ec..f8fbd7ea5a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -1,5 +1,6 @@  + netstandard2.0;net462 Stackdriver .NET Exporter for OpenTelemetry. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 6be2f3683f..1780ea877a 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -1,9 +1,10 @@ + netstandard2.0 $(TargetFrameworks);net462 - $(TargetFrameworks);net6.0 + net6.0;$(TargetFrameworks) Extensions.AzureMonitor- true diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj index b38ee0a275..5fea9c27cb 100644 --- a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj +++ b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj @@ -1,6 +1,7 @@ - net462;netstandard2.0 + + netstandard2.0;net462 OpenTelemetry Extensions - Container Resource Detector from Docker environment. Extensions.Docker- diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj index e2f23516fc..1e434c0cb4 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj @@ -1,9 +1,10 @@ + netstandard2.0 $(TargetFrameworks);net462 - $(TargetFrameworks);net6.0 + net6.0;$(TargetFrameworks) OpenTelemetry Persistent Storage Abstractions Extensions.PersistentStorage.Abstractions- $(NoWarn),CA1031 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj index afe749a640..e3c0346648 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj @@ -1,9 +1,10 @@ + netstandard2.0 $(TargetFrameworks);net462 - $(TargetFrameworks);net6.0 + net6.0;$(TargetFrameworks) OpenTelemetry Persistent Storage Extensions.PersistentStorage- diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index e0168edc63..13eecc4e34 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -1,8 +1,9 @@ - net462;netstandard2.0 - $(TargetFrameworks);net6.0 + + netstandard2.0;net462; + net6.0;$(TargetFrameworks) OpenTelemetry .NET SDK preview features and extensions Extensions- enable diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 9d8f512ec9..64150f4f68 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -1,5 +1,6 @@  + netstandard2.0;net462 Elasticsearch instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index cc4b603d14..d440730f74 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -17,7 +17,7 @@ using System; using System.Threading; using System.Threading.Tasks; -using global::Grpc.Core; +using Grpc.Core; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -29,7 +29,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore; /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingAsyncStreamReader.cs. /// /// The message type. -/// +/// internal class AsyncStreamReaderProxy : IAsyncStreamReader { /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index 95fa3f69fb..b010e47724 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -16,7 +16,7 @@ using System; using System.Threading.Tasks; -using global::Grpc.Core; +using Grpc.Core; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -28,7 +28,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore; /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingClientStreamWriter.cs. /// /// The message type. -/// +/// internal class ClientStreamWriterProxy : IClientStreamWriter { /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 72716be951..146b30dce9 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -17,8 +17,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using global::Grpc.Core; -using global::Grpc.Core.Interceptors; +using Grpc.Core; +using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; @@ -27,7 +27,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore; /// /// A client interceptor that starts and stops an Activity for each outbound RPC. /// -/// +/// public class ClientTracingInterceptor : Interceptor { /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index e179a19454..a1a7c50cdf 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -18,8 +18,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading; -using global::Grpc.Core; using Google.Protobuf; +using Grpc.Core; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -197,7 +197,7 @@ private void StopActivity(int statusCode, string statusDescription = null) this.activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, statusCode); if (statusDescription != null) { - this.activity.SetStatus(OpenTelemetry.Trace.Status.Error.WithDescription(statusDescription)); + this.activity.SetStatus(Trace.Status.Error.WithDescription(statusDescription)); } this.activity.Stop(); diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index 8f9abc417c..f6c69776b2 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -16,7 +16,7 @@ using System; using System.Threading.Tasks; -using global::Grpc.Core; +using Grpc.Core; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -28,7 +28,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore; /// https://github.com/opentracing-contrib/csharp-grpc/blob/master/src/OpenTracing.Contrib.Grpc/Streaming/TracingServerStreamWriter.cs. /// /// The message type. -/// +/// internal class ServerStreamWriterProxy : IServerStreamWriter { /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index cf6ff03467..aaab133b95 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -19,8 +19,8 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using global::Grpc.Core; -using global::Grpc.Core.Interceptors; +using Grpc.Core; +using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; @@ -29,7 +29,7 @@ namespace OpenTelemetry.Instrumentation.GrpcCore; /// /// A service interceptor that starts and stops an Activity for each inbound RPC. /// -/// +/// public class ServerTracingInterceptor : Interceptor { /// diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index e74f1aa848..88279bedf7 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -126,7 +126,7 @@ private static IEnumerable ExtractActivityProperties(Dictionary(); } - private void SetStatusAndRecordException(Activity activity, System.Exception exception) + private void SetStatusAndRecordException(Activity activity, Exception exception) { activity.SetStatus(ActivityStatusCode.Error, exception.Message); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 53580889d5..2f79c511f8 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -1,6 +1,7 @@ - netstandard2.0;net462;net6.0 + + net6.0;netstandard2.0;net462 dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index dacec3f16e..922b8fd1a9 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -1,7 +1,8 @@ - net462;netstandard2.0 + + netstandard2.0;net462 OpenTelemetry instrumentation for WCF $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index aeaadfb5ad..0e4cc8e110 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -2,6 +2,7 @@ Unit test project for AWS X-Ray for OpenTelemetry + netcoreapp3.1 $(TargetFrameworks);net452 @@ -10,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs index 6e1d910cbd..4f99057056 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; using Xunit; @@ -27,23 +28,27 @@ public class TestServerCertificateValidationProvider [Fact] public void TestValidCertificate() { - using (CertificateUploader certificateUploader = new CertificateUploader()) + // This test fails on Linux in netcoreapp3.1, but passes in net6.0 and net7.0. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - certificateUploader.Create(); + using (CertificateUploader certificateUploader = new CertificateUploader()) + { + certificateUploader.Create(); - // Loads the certificate to the trusted collection from the file - ServerCertificateValidationProvider serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + // Loads the certificate to the trusted collection from the file + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); - // Validates if the certificate loaded into the trusted collection. - Assert.True(serverCertificateValidationProvider.IsCertificateLoaded); + // Validates if the certificate loaded into the trusted collection. + Assert.True(serverCertificateValidationProvider.IsCertificateLoaded); - var certificate = new X509Certificate2(certificateUploader.FilePath); - X509Chain chain = new X509Chain(); - chain.Build(certificate); + var certificate = new X509Certificate2(certificateUploader.FilePath); + X509Chain chain = new X509Chain(); + chain.Build(certificate); - // validates if certificate is valid - Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); + // validates if certificate is valid + Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); + } } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 8b47625fbf..e8fa57bb14 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -2,6 +2,7 @@ Unit test project for AWS client instrumentation for OpenTelemetry + netcoreapp3.1 $(TargetFrameworks);net452 @@ -13,7 +14,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index 5aefb6fc6e..8264bfe26f 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -212,7 +212,7 @@ public HttpContent GetRequestContent() public Task GetRequestContentAsync() { - return Task.FromResult(new HttpRequestMessage().Content); + return Task.FromResult(new HttpRequestMessage().Content); } public IWebResponseData GetResponse() @@ -227,7 +227,7 @@ public Task GetResponseAsync(CancellationToken cancellationTok { this.GetResponseAction?.Invoke(); var response = this.ResponseCreator(this); - return Task.FromResult(CustomWebResponse.GenerateWebResponse(response)); + return Task.FromResult(CustomWebResponse.GenerateWebResponse(response)); } public void SetRequestHeaders(IDictionary headers) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 05cdcfab4d..fd73af1422 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -1,21 +1,21 @@ - - Exe - - net7.0;net6.0 - $(TargetFrameworks);net48;net472;net471;net47;net462 - $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 - + + Exe + + net7.0;net6.0 + $(TargetFrameworks);net48;net472;net471;net47;net462 + $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 + - - - - - + + + + + - - - + + + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 03f9f297c2..4332125d8a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -150,8 +150,15 @@ public void UnixDomainSocketDataTransport_ServerRestart_Linux() serverSocket.Shutdown(SocketShutdown.Both); serverSocket.Disconnect(false); serverSocket.Dispose(); - server.Shutdown(SocketShutdown.Both); - server.Disconnect(false); + + if (server.Connected) + { + // On MacOS the 'server' socket never shows up as connected + // so trying to shutdown/disconnect throws an exception. + server.Shutdown(SocketShutdown.Both); + server.Disconnect(false); + } + server.Dispose(); try { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 6c6c093e4e..d934ebd635 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -15,7 +15,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index 680709dc8f..ee29cac225 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -9,7 +9,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj index 73f9bd87a1..b5f979b411 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -10,7 +10,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 4cbdb29338..53aa232c25 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -10,7 +10,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 4b5203ccdf..a98b7b9207 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -10,7 +10,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index 2fbd767b8b..c68c2175a8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 42b5a7f267..f7d381ba8e 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 09426e9f5a..6c2b7a8ba7 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 73f545680a..09a4c2dfd2 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -250,7 +250,7 @@ private void CheckForFailure(ServerCallContext context) /// /// Wraps server shutdown with an IDisposable pattern. /// - /// + /// public sealed class DisposableServer : IDisposable { /// diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 56b5fb8d40..458075c61e 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -245,7 +245,7 @@ public async Task DownstreamInterceptorActivityAccess() Assert.True(Activity.Current.Source == GrpcCoreInstrumentation.ActivitySource); Assert.Equal(parentActivity.Id, Activity.Current.ParentId); - // Set a tag on the Activity and make sure we can see it afterwardsd + // Set a tag on the Activity and make sure we can see it afterwards Activity.Current.SetTag("foo", "bar"); return metadata; }); @@ -321,7 +321,7 @@ static void ValidateNewTagOnActivity(InterceptorActivityListener listener) /// if set to true [recorded messages]. internal static void ValidateCommonActivityTags( Activity activity, - Grpc.Core.StatusCode expectedStatusCode = Grpc.Core.StatusCode.OK, + StatusCode expectedStatusCode = StatusCode.OK, bool recordedMessages = false) { Assert.NotNull(activity); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 13cd736850..d759e09e21 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 36dc2b09eb..666bf9dae1 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -1,7 +1,8 @@ Unit test project for OpenTelemetry Hangfire instrumentation - net472;netcoreapp3.1 + + netcoreapp3.1;net472 false @@ -10,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 13742dc9fa..5e59fbcbe0 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -10,7 +10,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 690d8cb81a..a7c36d8081 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index e3c389aec6..a722caeee5 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for OpenTelemetry Quartz.NET instrumentation - net7.0;net6.0;net472 + net7.0;net6.0 + $(TargetFrameworks);net472 true @@ -13,7 +14,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 5ea624c90b..bd78af628a 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index cfd0ec573c..b7f42bf70f 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers From b6476c56fa6be23f28bf8b203aef84dff72d9a08 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 15 Feb 2023 16:26:09 -0800 Subject: [PATCH 0565/1499] Use a constant for DefaultEventNamespace. (#1008) --- .../Logs/OneCollectorLogExporterOptions.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index 114760cee9..e08641f56a 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System.Reflection; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; @@ -41,9 +40,8 @@ public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions public BatchExportProcessorOptions BatchOptions { get; } = new(); /// - /// Gets or sets the default event namespace. Default value: from the assembly returned by . + /// Gets or sets the default event namespace. Default value: + /// OpenTelemetry.Logs. /// /// /// Note: The default event namespace is used if a interface there should /// always be a category name. /// - internal string DefaultEventNamespace { get; set; } = Assembly.GetEntryAssembly()?.GetName().Name ?? string.Empty; + internal string DefaultEventNamespace { get; set; } = "OpenTelemetry.Logs"; ISink ISinkFactory.CreateSink() { From e9c702a3b9fc9808ba67f17b5f86da37b1441893 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 15 Feb 2023 18:09:10 -0800 Subject: [PATCH 0566/1499] CHANGELOG update for 0.1.0-alpha.1. (#1009) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 63bfc986bd..22e4a43d8d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,4 +2,8 @@ ## Unreleased -Initial release. +## 0.1.0-alpha.1 + +Released 2023-Feb-16 + +* Initial release. From 783a743bf628a1baa78ba90421db1af71ec2aedd Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 15 Feb 2023 18:20:31 -0800 Subject: [PATCH 0567/1499] [Instrumentation.Process] Doc update: added opentelemetry spec link (#1010) --- src/OpenTelemetry.Instrumentation.Process/README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index b4432e3670..8c1b6011f9 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -8,6 +8,11 @@ Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main which instruments [.NET](https://docs.microsoft.com/dotnet) and collect telemetry about process behavior. +The process metric instruments being implemented are following OpenTelemetry +[metrics semantic conventions][1]. + +[1]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md#metric-instruments + ## Steps to enable OpenTelemetry.Instrumentation.Process ### Step 1: Install package @@ -103,11 +108,11 @@ The number of processors (CPU cores) available to the current process. The API used to retrieve the value is [System.Environment.ProcessorCount](https://learn.microsoft.com/dotnet/api/system.environment.processorcount). > **Note** -> This metric is under [discussion][1] and not part of the -[Process Metrics Spec][2] at this time. +> This metric is under [discussion][2] and not part of the +[Process Metrics Spec][3] at this time. -[1]: https://github.com/open-telemetry/opentelemetry-specification/issues/3200 -[2]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md +[2]: https://github.com/open-telemetry/opentelemetry-specification/issues/3200 +[3]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md ### process.threads From 7998816895687c4f19a87f8bd844ccc379aa2b83 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 17 Feb 2023 11:57:45 -0800 Subject: [PATCH 0568/1499] Added some text to OneCollector README to explain the project. (#1015) --- src/OpenTelemetry.Exporter.OneCollector/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index 7b2e42370e..c20dc71759 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -3,12 +3,14 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) -The OneCollector Exporter exports telemetry to the Microsoft OneCollector -backend. - > **Warning** > This is an early preview version breaking changes should be expected. +The OneCollectorExporter is designed for Microsoft products to send data to +public-facing end-points which route to Microsoft's internal data pipeline. It +is not meant to be used outside of Microsoft products and is open sourced to +demonstrate best practices and to be transparent about what is being collected. + ## Installation ```shell From a36805621db55149263c28619b60167a1226c5ac Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 17 Feb 2023 12:49:22 -0800 Subject: [PATCH 0569/1499] [Instrumentation.Process] Release Process instrumentation version 0.5.0 (#1011) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 5a65615f4f..bfc8e1d554 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +## 0.5.0-beta.1 + +Released 2023-Feb-17 + +> **Note** +> The version number was lowered from 1.0.0 to 0.5.0 to better reflect the +experimental state of Opentelemetry process metrics specification status. +Packages that were older than this release will be delisted to avoid confusion. + * Added `process.cpu.count` metric. ([#981](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/981)) From 92779300507f87e41ef55413ae7defb91ee7f4df Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Fri, 17 Feb 2023 13:08:55 -0800 Subject: [PATCH 0570/1499] initial (#1017) Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Instrumentation.Process/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 8c1b6011f9..89c3c949b6 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -68,7 +68,7 @@ allocated for the associated process. The amount of committed virtual memory for this process. One way to think of this is all the address space this process can read from -without trigerring an access violation; this includes memory backed solely by RAM, +without triggering an access violation; this includes memory backed solely by RAM, by a swapfile/pagefile and by other mapped files on disk. | Units | Instrument Type | Value Type | From d3f6d09b65a7878cf18b22eeda826149279daa71 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 21 Feb 2023 09:59:48 -0800 Subject: [PATCH 0571/1499] [Azure.ResourceDetectors] Add appservice service.instance.id (#1012) --- .../AppServiceResourceDetector.cs | 36 +++++++++++-------- .../AzureResourceDetectorTests.cs | 25 ++++++------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index e9ed7bbf43..3ab8352c10 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -29,29 +29,35 @@ public sealed class AppServiceResourceDetector : IResourceDetector /// public Resource? Detect() { - string? serviceName = null; + List>? attributeList = null; + try { + string? serviceName = null; + string? serviceInstanceId = null; + // https://learn.microsoft.com/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet#app-environment serviceName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); - } - catch - { - // TODO: log exception. - } - - List>? attributeList = null; + serviceInstanceId = Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"); + if (serviceName != null) + { + attributeList = new(); - if (serviceName != null) - { - attributeList = new(); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, serviceName)); - attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, serviceName)); - - // TODO: Add other attributes e.g. service.instance.id + if (serviceInstanceId != null) + { + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceInstance, serviceInstanceId)); + } + } + else + { + return Resource.Empty; + } } - else + catch { + // TODO: log exception. return Resource.Empty; } diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index a785f9b133..2e91877be4 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -22,22 +22,17 @@ namespace OpenTelemetry.ResourceDetectors.Azure.Tests; -public class AzureResourceDetectorTests +public class AzureResourceDetectorTests : IDisposable { [Fact] public void AppServiceResourceDetectorReturnsResourceWithAttributes() { - try - { - Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "AzureAppService"); - var resource = ResourceBuilder.CreateEmpty().AddDetector(new AppServiceResourceDetector()).Build(); - Assert.NotNull(resource); - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "AzureAppService"), resource.Attributes); - } - finally - { - Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", null); - } + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "AzureAppService"); + Environment.SetEnvironmentVariable("WEBSITE_INSTANCE_ID", "AzureInstance"); + var resource = ResourceBuilder.CreateEmpty().AddDetector(new AppServiceResourceDetector()).Build(); + Assert.NotNull(resource); + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "AzureAppService"), resource.Attributes); + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceInstance, "AzureInstance"), resource.Attributes); } [Fact] @@ -46,4 +41,10 @@ public void AppServiceResourceDetectorReturnsNullOutsideOfAppService() var resource = new AppServiceResourceDetector().Detect(); Assert.Empty(resource.Attributes); } + + public void Dispose() + { + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", null); + Environment.SetEnvironmentVariable("WEBSITE_INSTANCE_ID", null); + } } From e2674dce70ed253d9b6be4dfdec4c95934747b84 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 21 Feb 2023 13:37:11 -0800 Subject: [PATCH 0572/1499] Add issue template for ResourceDetectors.Azure (#1023) --- .../comp_resourcedetectors_azure.md | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md new file mode 100644 index 0000000000..0d31102c10 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.ResourceDetectors.Azure +about: OpenTelemetry.ResourceDetectors.Azure +labels: comp:resourcedetectors.azure +--- + +# Issue with OpenTelemetry.ResourceDetectors.Azure + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.0.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. From c6e22003b3806f23d229943d3edf80b727225870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 22 Feb 2023 15:57:49 +0100 Subject: [PATCH 0573/1499] Update versions in issue templates (#1025) --- .github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md | 4 ++-- .../comp_contrib_instrumentation_awslambda.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_exporter_geneva.md | 7 +++---- .github/ISSUE_TEMPLATE/comp_exporter_instana.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_extensions.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_extensions_docker.md | 4 ++-- .../comp_extensions_persistentstorage.abstractions.md | 4 ++-- .../ISSUE_TEMPLATE/comp_extensions_persistentstorage.md | 4 ++-- .../comp_instrumentation_AspNet.TelemetryHttpModule.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md | 4 ++-- .../comp_instrumentation_elasticsearchclient.md | 4 ++-- .../comp_instrumentation_entityframeworkcore.md | 4 ++-- .../ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_owin.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_process.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md | 4 ++-- .../comp_instrumentation_stackexchangeredis.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md | 4 ++-- .github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md | 4 ++-- 26 files changed, 53 insertions(+), 54 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md b/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md index e1c5b43942..52699a97ff 100644 --- a/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md +++ b/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md @@ -8,11 +8,11 @@ labels: comp:contrib.extensions.awsxray List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md index af4c13a952..caf78e5996 100644 --- a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md +++ b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md @@ -8,11 +8,11 @@ labels: comp:contrib.instrumentation.aws List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md index 66089c059e..fd37e8dcfc 100644 --- a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md +++ b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.awslambda List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md b/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md index f54d5bfc4b..70bcdb9d2c 100644 --- a/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md +++ b/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md @@ -8,12 +8,11 @@ labels: comp:exporter.geneva List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): -* [OpenTelemetry.Exporter.Geneva - 1.2.6](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva/1.2.6) +* TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_instana.md b/.github/ISSUE_TEMPLATE/comp_exporter_instana.md index c03d1270c4..38c3cd5674 100644 --- a/.github/ISSUE_TEMPLATE/comp_exporter_instana.md +++ b/.github/ISSUE_TEMPLATE/comp_exporter_instana.md @@ -8,11 +8,11 @@ labels: comp:exporter.instana List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md b/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md index 6afeebd9c6..c520aed3c7 100644 --- a/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md +++ b/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md @@ -8,11 +8,11 @@ labels: comp:exporter.stackdriver List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_extensions.md b/.github/ISSUE_TEMPLATE/comp_extensions.md index 89fb00ecf1..d79ed71aeb 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions.md +++ b/.github/ISSUE_TEMPLATE/comp_extensions.md @@ -8,11 +8,11 @@ labels: comp:extensions List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md b/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md index 50f63a6386..ced841fd38 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md +++ b/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md @@ -8,11 +8,11 @@ labels: comp:extensions.azuremonitor List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_docker.md b/.github/ISSUE_TEMPLATE/comp_extensions_docker.md index 0f6b510858..bb88ba26f2 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_docker.md +++ b/.github/ISSUE_TEMPLATE/comp_extensions_docker.md @@ -8,11 +8,11 @@ labels: comp:extensions.docker List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md index 7dd883b08a..bb667eec36 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md +++ b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md @@ -8,11 +8,11 @@ labels: comp:extensions.persistentstorage.abstractions List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md index 4c069cd0bb..02b39031d2 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md +++ b/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md @@ -8,11 +8,11 @@ labels: comp:extensions.persistentstorage List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md index dc3d2f78c1..150414bf0a 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.AspNet.TelemetryHttpModule List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.2.0`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md index 9f54a19034..80efb79cd1 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.AspNet List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.2.0`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md index 9d534eae7e..d110e42ea6 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.elasticsearchclient List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md index 9113cb62a4..8b4ad4e9e3 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.entityframeworkcore List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md index 27433bb4d4..5d65375dca 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.eventcounters List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md index 467441e7b3..bdcdbc37dd 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.grpccore List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md index 745d1427c1..c5efb1c3b2 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.hangfire List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md index cd0c9b600a..654ca953e3 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.mysqldata List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md index 9557899b12..4267fc8ecd 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.owin List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md index c91853c544..0c26529198 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.process List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Process version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md index d58aa6d1cc..628792e62d 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.quartz List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md index 9c0edab241..ae104dbc81 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.runtime List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md index 87f3f6bf7a..38eb69e5f5 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.stackexchangeredis List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.2.0`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md index baa913280c..d447cc420e 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md @@ -8,11 +8,11 @@ labels: comp:instrumentation.wcf List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md index 0d31102c10..35c64b3841 100644 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md @@ -8,11 +8,11 @@ labels: comp:resourcedetectors.azure List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.0.2`): +using (e.g. `OpenTelemetry 1.3.2`): * TBD -Runtime version (e.g. `net462`, `net48`, `netcoreapp3.1`, `net6.0` etc. You can +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can find this information from the `*.csproj` file): * TBD From 91cea973becd14cd635e223d5b70d87f61de4b3a Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Wed, 22 Feb 2023 16:34:20 +0100 Subject: [PATCH 0574/1499] [Exporter.Instana] Release 1.0.3 (#1022) --- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 6aa0f0db0f..3c164dd737 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.3 + +Released 2023-Feb-21 + * Fixes issue in span serialization process introduced in 1.0.2 version. ([#979](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/979)) * Update OTel SDK version to `1.3.2`. From 48da125b4181b21507abbad8938f021e862ec114 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 22 Feb 2023 18:56:54 +0000 Subject: [PATCH 0575/1499] [Instrumentation.Quartz] Fix analysis warnings (#966) Fix/suppress code analysis warnings in OpenTelemetry.Instrumentation.Quartz. Contributes to #950. --- .../Implementation/QuartzDiagnosticListener.cs | 14 +++++++------- .../OperationName.cs | 2 ++ .../QuartzInstrumentationOptions.cs | 2 ++ .../TraceProviderBuilderExtensions.cs | 3 +++ .../QuartzDiagnosticListenerTests.cs | 8 ++++---- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 9208c22bad..6e38ee2f7f 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -53,10 +53,10 @@ public override void OnStartActivity(Activity activity, object payload) return; } - activity.DisplayName = this.GetDisplayName(activity); + activity.DisplayName = GetDisplayName(activity); ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); - ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity)); + ActivityInstrumentationHelper.SetKindProperty(activity, GetActivityKind(activity)); try { @@ -115,17 +115,17 @@ public override void OnException(Activity activity, object payload) } } - private string GetDisplayName(Activity activity) + private static string GetDisplayName(Activity activity) { return activity.OperationName switch { - OperationName.Job.Execute => $"execute {this.GetTag(activity.Tags, TagName.JobName)}", - OperationName.Job.Veto => $"veto {this.GetTag(activity.Tags, TagName.JobName)}", + OperationName.Job.Execute => $"execute {GetTag(activity.Tags, TagName.JobName)}", + OperationName.Job.Veto => $"veto {GetTag(activity.Tags, TagName.JobName)}", _ => activity.DisplayName, }; } - private ActivityKind GetActivityKind(Activity activity) + private static ActivityKind GetActivityKind(Activity activity) { return activity.OperationName switch { @@ -135,7 +135,7 @@ private ActivityKind GetActivityKind(Activity activity) }; } - private string GetTag(IEnumerable> tags, string tagName) + private static string GetTag(IEnumerable> tags, string tagName) { var tag = tags.SingleOrDefault(kv => kv.Key == tagName); return tag.Value; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs index b173e14041..4a1e6ed492 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs @@ -24,7 +24,9 @@ public static class OperationName /// /// Quartz Job category constants. /// +#pragma warning disable CA1034 // Nested types should not be visible public static class Job +#pragma warning restore CA1034 // Nested types should not be visible { /// /// Quartz job execute diagnostic source operation name. diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index ac9572ef54..4e726f3f72 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -56,5 +56,7 @@ public class QuartzInstrumentationOptions /// /// Gets or sets traced operations set. /// +#pragma warning disable CA2227 // Collection properties should be read only public HashSet TracedOperations { get; set; } = new(DefaultTracedOperations); +#pragma warning restore CA2227 // Collection properties should be read only } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index dd84eb51f4..9461dcc585 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -17,6 +17,7 @@ using System; using OpenTelemetry.Instrumentation.Quartz; using OpenTelemetry.Instrumentation.Quartz.Implementation; +using OpenTelemetry.Internal; // ReSharper disable once CheckNamespace namespace OpenTelemetry.Trace; @@ -44,6 +45,8 @@ public static TracerProviderBuilder AddQuartzInstrumentation( this TracerProviderBuilder builder, Action configure) { + Guard.ThrowIfNull(builder); + var options = new QuartzInstrumentationOptions(); configure?.Invoke(options); diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index b5f98b7d07..10a3e9ff76 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -106,9 +106,9 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() if (payload is IJobDetail jobDetail) { var dataMap = jobDetail.JobDataMap; - if (dataMap.ContainsKey("TestId")) + if (dataMap.TryGetValue("TestId", out var value)) { - a.SetTag("test.id", dataMap["TestId"]); + a.SetTag("test.id", value); } } }) @@ -229,9 +229,9 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri if (p is IJobDetail jobDetail) { var dataMap = jobDetail.JobDataMap; - if (dataMap.ContainsKey("TestId")) + if (dataMap.TryGetValue("TestId", out var value)) { - a.SetTag("test.id", dataMap["TestId"]); + a.SetTag("test.id", value); } } }; From 3ccf594c434e0751fce83e5ce66d217c6d08fa93 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 22 Feb 2023 19:27:49 +0000 Subject: [PATCH 0576/1499] [Instrumentation.MySqlData] Fix analysis warnings (#965) Fix/suppress code analysis warnings in OpenTelemetry.Instrumentation.MySqlData. Contributes to #950. --- .../MySqlDataInstrumentation.cs | 73 ++++++++++--------- .../MySqlDataTests.cs | 4 +- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index 1cc31f9012..31f10c9968 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Concurrent; using System.Diagnostics; +using System.Globalization; using System.Linq.Expressions; using System.Reflection; using MySql.Data.MySqlClient; @@ -113,7 +114,7 @@ public override void TraceEvent( break; case MySqlTraceEventType.QueryClosed: // args: [driverId] - this.AfterExecuteCommand(); + AfterExecuteCommand(); break; case MySqlTraceEventType.StatementPrepared: break; @@ -129,7 +130,7 @@ public override void TraceEvent( break; case MySqlTraceEventType.Error: // args: [driverId, exNumber, exMessage] - this.ErrorExecuteCommand(this.GetMySqlErrorException(args[2])); + this.ErrorExecuteCommand(GetMySqlErrorException(args[2])); break; case MySqlTraceEventType.QueryNormalized: // Should use QueryNormalized event when it exists. Because cmdText in QueryOpened event is incomplete when cmdText.length>300 @@ -137,13 +138,46 @@ public override void TraceEvent( this.OverwriteDbStatement(this.GetCommand(args[0], args[2])); break; default: - MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(id, string.Format(format, args)); + MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(id, string.Format(CultureInfo.InvariantCulture, format, args)); break; } } catch (Exception e) { - MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(id, string.Format(format, args), e.ToString()); + MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(id, string.Format(CultureInfo.InvariantCulture, format, args), e.ToString()); + } + } + + private static Exception GetMySqlErrorException(object errorMsg) + { +#pragma warning disable CA2201 // Do not raise reserved exception types + return new Exception(errorMsg?.ToString()); +#pragma warning restore CA2201 // Do not raise reserved exception types + } + + private static void AfterExecuteCommand() + { + var activity = Activity.Current; + if (activity == null) + { + return; + } + + if (activity.Source != MySqlActivitySourceHelper.ActivitySource) + { + return; + } + + try + { + if (activity.IsAllDataRequested) + { + activity.SetStatus(Status.Unset); + } + } + finally + { + activity.Stop(); } } @@ -198,32 +232,6 @@ private void OverwriteDbStatement(MySqlDataTraceCommand command) } } - private void AfterExecuteCommand() - { - var activity = Activity.Current; - if (activity == null) - { - return; - } - - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } - - try - { - if (activity.IsAllDataRequested) - { - activity.SetStatus(Status.Unset); - } - } - finally - { - activity.Stop(); - } - } - private void ErrorExecuteCommand(Exception exception) { var activity = Activity.Current; @@ -266,11 +274,6 @@ private MySqlDataTraceCommand GetCommand(object driverIdObj, object cmd) return command; } - private Exception GetMySqlErrorException(object errorMsg) - { - return new Exception($"{errorMsg}"); - } - private void AddConnectionLevelDetailsToActivity(MySqlConnectionStringBuilder dataSource, Activity sqlActivity) { if (!this.options.EnableConnectionLevelAttributes) diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs index 3f4c105897..0f29d966f6 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs @@ -55,7 +55,7 @@ public void SuccessTraceEventTest( var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); - this.ExecuteSuccessQuery(traceListener, commandText, isFailure); + ExecuteSuccessQuery(traceListener, commandText, isFailure); Assert.Equal(3, activityProcessor.Invocations.Count); @@ -170,7 +170,7 @@ private static void VerifyActivityData( } } - private void ExecuteSuccessQuery(TraceListener listener, string query, bool isFailure) + private static void ExecuteSuccessQuery(TraceListener listener, string query, bool isFailure) { // Connection opened listener.TraceEvent( From 2402943cd262443dd32f2847afd6e09a2da964cd Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 22 Feb 2023 19:44:16 +0000 Subject: [PATCH 0577/1499] [Instrumentation.Hangfire] Fix analysis warnings (#964) Fix/suppress code analysis warnings in OpenTelemetry.Instrumentation.Hangfire. Contributes to #950. --- .../HangfireInstrumentationJobFilterAttribute.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 88279bedf7..dbddf6abf2 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -28,7 +28,7 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Trace; -internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter +internal sealed class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter { private readonly HangfireInstrumentationOptions options; @@ -37,6 +37,8 @@ public HangfireInstrumentationJobFilterAttribute(HangfireInstrumentationOptions this.options = options; } + public HangfireInstrumentationOptions Options { get; } + public void OnPerforming(PerformingContext performingContext) { // Short-circuit if nobody is listening @@ -123,7 +125,7 @@ private static void InjectActivityProperties(IDictionary jobPara private static IEnumerable ExtractActivityProperties(Dictionary telemetryData, string key) { - return telemetryData.ContainsKey(key) ? new[] { telemetryData[key] } : Enumerable.Empty(); + return telemetryData.TryGetValue(key, out var value) ? new[] { value } : Enumerable.Empty(); } private void SetStatusAndRecordException(Activity activity, Exception exception) From 82b072ff9f6880ea330b3fba955f8dc1e5832b93 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 22 Feb 2023 19:55:54 +0000 Subject: [PATCH 0578/1499] [Instrumentation.GrpcCore] Fix analysis warnings (#963) Fix/suppress code analysis warnings in OpenTelemetry.Instrumentation.GrpcCore. Contributes to #950. --- .../Examples.GrpcCore.AspNetCore/Startup.cs | 2 +- .../ClientTracingInterceptor.cs | 30 +++++++++++++++++-- .../ClientTracingInterceptorOptions.cs | 2 +- .../RpcScope.cs | 2 +- .../ServerTracingInterceptor.cs | 12 ++++++++ .../ServerTracingInterceptorOptions.cs | 2 +- .../FoobarService.cs | 22 +++++++------- .../GrpcCoreClientInterceptorTests.cs | 28 ++++++++--------- .../GrpcCoreServerInterceptorTests.cs | 20 ++++++------- 9 files changed, 79 insertions(+), 41 deletions(-) diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index 374ec30c48..86657cced5 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -110,7 +110,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken) tcs.SetResult(true); }); - return tcs.Task.ContinueWith(antecedent => tokenRegistration.Dispose()); + return tcs.Task.ContinueWith(antecedent => tokenRegistration.Dispose(), stoppingToken); } } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 146b30dce9..b1ea6d2a72 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; @@ -52,6 +53,9 @@ public override TResponse BlockingUnaryCall( ClientInterceptorContext context, BlockingUnaryCallContinuation continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + ClientRpcScope rpcScope = null; try @@ -81,11 +85,16 @@ public override AsyncUnaryCall AsyncUnaryCall( ClientInterceptorContext context, AsyncUnaryCallContinuation continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + ClientRpcScope rpcScope = null; try { +#pragma warning disable CA2000 rpcScope = new ClientRpcScope(context, this.options); +#pragma warning restore CA2000 rpcScope.RecordRequest(request); var responseContinuation = continuation(request, rpcScope.Context); var responseAsync = responseContinuation.ResponseAsync.ContinueWith( @@ -103,7 +112,8 @@ public override AsyncUnaryCall AsyncUnaryCall( rpcScope.CompleteWithException(ex.InnerException); throw ex.InnerException; } - }); + }, + TaskScheduler.Current); return new AsyncUnaryCall( responseAsync, @@ -128,11 +138,16 @@ public override AsyncClientStreamingCall AsyncClientStreami ClientInterceptorContext context, AsyncClientStreamingCallContinuation continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + ClientRpcScope rpcScope = null; try { +#pragma warning disable CA2000 rpcScope = new ClientRpcScope(context, this.options); +#pragma warning restore CA2000 var responseContinuation = continuation(rpcScope.Context); var clientRequestStreamProxy = new ClientStreamWriterProxy( responseContinuation.RequestStream, @@ -154,7 +169,8 @@ public override AsyncClientStreamingCall AsyncClientStreami rpcScope.CompleteWithException(ex.InnerException); throw ex.InnerException; } - }); + }, + TaskScheduler.Current); return new AsyncClientStreamingCall( clientRequestStreamProxy, @@ -181,11 +197,16 @@ public override AsyncServerStreamingCall AsyncServerStreamingCall context, AsyncServerStreamingCallContinuation continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + ClientRpcScope rpcScope = null; try { +#pragma warning disable CA2000 rpcScope = new ClientRpcScope(context, this.options); +#pragma warning restore CA2000 rpcScope.RecordRequest(request); var responseContinuation = continuation(request, rpcScope.Context); @@ -218,11 +239,16 @@ public override AsyncDuplexStreamingCall AsyncDuplexStreami ClientInterceptorContext context, AsyncDuplexStreamingCallContinuation continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + ClientRpcScope rpcScope = null; try { +#pragma warning disable CA2000 rpcScope = new ClientRpcScope(context, this.options); +#pragma warning restore CA2000 var responseContinuation = continuation(rpcScope.Context); var requestStreamProxy = new ClientStreamWriterProxy( diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 5e7898b58d..79b23e9320 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -27,7 +27,7 @@ public class ClientTracingInterceptorOptions /// /// Gets or sets a value indicating whether or not to record individual message events. /// - public bool RecordMessageEvents { get; set; } = false; + public bool RecordMessageEvents { get; set; } /// /// Gets the propagator. diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index a1a7c50cdf..d5c8c6d882 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -46,7 +46,7 @@ internal abstract class RpcScope : IDisposable /// /// The complete flag. /// - private long complete = 0; + private long complete; /// /// The request message counter. diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index aaab133b95..919dd8a0da 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -54,6 +54,9 @@ public override async Task UnaryServerHandler( ServerCallContext context, UnaryServerMethod continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + using var rpcScope = new ServerRpcScope(context, this.options); try @@ -77,6 +80,9 @@ public override async Task ClientStreamingServerHandler continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + using var rpcScope = new ServerRpcScope(context, this.options); try @@ -104,6 +110,9 @@ public override async Task ServerStreamingServerHandler( ServerCallContext context, ServerStreamingServerMethod continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + using var rpcScope = new ServerRpcScope(context, this.options); try @@ -127,6 +136,9 @@ public override async Task ServerStreamingServerHandler( /// public override async Task DuplexStreamingServerHandler(IAsyncStreamReader requestStream, IServerStreamWriter responseStream, ServerCallContext context, DuplexStreamingServerMethod continuation) { + Guard.ThrowIfNull(context); + Guard.ThrowIfNull(continuation); + using var rpcScope = new ServerRpcScope(context, this.options); try diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index 94fbea9967..3b982d0c08 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -27,7 +27,7 @@ public class ServerTracingInterceptorOptions /// /// Gets or sets a value indicating whether or not to record individual message events. /// - public bool RecordMessageEvents { get; set; } = false; + public bool RecordMessageEvents { get; set; } /// /// Gets the propagator. diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 09a4c2dfd2..7bb3af2851 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -33,7 +33,17 @@ internal class FoobarService : Foobar.FoobarBase /// /// Default traceparent header value with the sampling bit on. /// - internal static readonly string DefaultTraceparentWithSampling = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; + internal const string DefaultTraceparentWithSampling = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"; + + /// + /// The request header fail with status code. + /// + internal const string RequestHeaderFailWithStatusCode = "failurestatuscode"; + + /// + /// The request header error description. + /// + internal const string RequestHeaderErrorDescription = "failuredescription"; /// /// The default parent from a traceparent header. @@ -60,16 +70,6 @@ internal class FoobarService : Foobar.FoobarBase /// internal static readonly int DefaultResponseMessageSize = ((IMessage)DefaultResponseMessage).CalculateSize(); - /// - /// The request header fail with status code. - /// - internal static readonly string RequestHeaderFailWithStatusCode = "failurestatuscode"; - - /// - /// The request header error description. - /// - internal static readonly string RequestHeaderErrorDescription = "failuredescription"; - /// /// Starts the specified service. /// diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 458075c61e..53e8b810f0 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -35,7 +35,7 @@ public class GrpcCoreClientInterceptorTests /// /// A bogus server uri. /// - private static readonly string BogusServerUri = "dns:i.dont.exist:77923"; + private const string BogusServerUri = "dns:i.dont.exist:77923"; /// /// The default metadata func. @@ -49,7 +49,7 @@ public class GrpcCoreClientInterceptorTests [Fact] public async Task AsyncUnarySuccess() { - await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest, DefaultMetadataFunc()).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest, DefaultMetadataFunc()).ConfigureAwait(false); } /// @@ -59,7 +59,7 @@ public async Task AsyncUnarySuccess() [Fact] public async Task AsyncUnaryUnavailable() { - await this.TestHandlerFailure( + await TestHandlerFailure( FoobarService.MakeUnaryAsyncRequest, StatusCode.Unavailable, validateErrorDescription: false, @@ -73,7 +73,7 @@ await this.TestHandlerFailure( [Fact] public async Task AsyncUnaryFail() { - await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); } /// @@ -97,7 +97,7 @@ static void MakeRequest(Foobar.FoobarClient client) [Fact] public async Task ClientStreamingSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeClientStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); } /// @@ -107,7 +107,7 @@ public async Task ClientStreamingSuccess() [Fact] public async Task ClientStreamingUnavailable() { - await this.TestHandlerFailure( + await TestHandlerFailure( FoobarService.MakeClientStreamingRequest, StatusCode.Unavailable, validateErrorDescription: false, @@ -121,7 +121,7 @@ await this.TestHandlerFailure( [Fact] public async Task ClientStreamingFail() { - await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); } /// @@ -145,7 +145,7 @@ static void MakeRequest(Foobar.FoobarClient client) [Fact] public async Task ServerStreamingSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeServerStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); } /// @@ -155,7 +155,7 @@ public async Task ServerStreamingSuccess() [Fact] public async Task ServerStreamingFail() { - await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); } /// @@ -179,7 +179,7 @@ static void MakeRequest(Foobar.FoobarClient client) [Fact] public async Task DuplexStreamingSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest, DefaultMetadataFunc()).ConfigureAwait(false); } /// @@ -189,7 +189,7 @@ public async Task DuplexStreamingSuccess() [Fact] public async Task DuplexStreamingUnavailable() { - await this.TestHandlerFailure( + await TestHandlerFailure( FoobarService.MakeDuplexStreamingRequest, StatusCode.Unavailable, validateErrorDescription: false, @@ -203,7 +203,7 @@ await this.TestHandlerFailure( [Fact] public async Task DuplexStreamingFail() { - await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); } /// @@ -376,7 +376,7 @@ static void ValidateCommonEventAttributes(ActivityEvent activityEvent) /// The client request function. /// The additional metadata, if any. /// A Task. - private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) + private static async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) { var mockPropagator = new Mock(); PropagationContext capturedPropagationContext = default; @@ -482,7 +482,7 @@ private async Task TestHandlerSuccess(Func /// /// A Task. /// - private async Task TestHandlerFailure( + private static async Task TestHandlerFailure( Func clientRequestFunc, StatusCode statusCode = StatusCode.ResourceExhausted, bool validateErrorDescription = true, diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 947f6cc88b..916f5779dd 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -35,7 +35,7 @@ public class GrpcCoreServerInterceptorTests [Fact] public async Task UnaryServerHandlerSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); } /// @@ -45,7 +45,7 @@ public async Task UnaryServerHandlerSuccess() [Fact] public async Task UnaryServerHandlerFail() { - await this.TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeUnaryAsyncRequest).ConfigureAwait(false); } /// @@ -55,7 +55,7 @@ public async Task UnaryServerHandlerFail() [Fact] public async Task ClientStreamingServerHandlerSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); } /// @@ -65,7 +65,7 @@ public async Task ClientStreamingServerHandlerSuccess() [Fact] public async Task ClientStreamingServerHandlerFail() { - await this.TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeClientStreamingRequest).ConfigureAwait(false); } /// @@ -75,7 +75,7 @@ public async Task ClientStreamingServerHandlerFail() [Fact] public async Task ServerStreamingServerHandlerSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); } /// @@ -85,7 +85,7 @@ public async Task ServerStreamingServerHandlerSuccess() [Fact] public async Task ServerStreamingServerHandlerFail() { - await this.TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeServerStreamingRequest).ConfigureAwait(false); } /// @@ -95,7 +95,7 @@ public async Task ServerStreamingServerHandlerFail() [Fact] public async Task DuplexStreamingServerHandlerSuccess() { - await this.TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + await TestHandlerSuccess(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); } /// @@ -105,7 +105,7 @@ public async Task DuplexStreamingServerHandlerSuccess() [Fact] public async Task DuplexStreamingServerHandlerFail() { - await this.TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); + await TestHandlerFailure(FoobarService.MakeDuplexStreamingRequest).ConfigureAwait(false); } /// @@ -114,7 +114,7 @@ public async Task DuplexStreamingServerHandlerFail() /// The specific client request function. /// The additional metadata, if any. /// A Task. - private async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) + private static async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) { // starts the server with the server interceptor var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid() }; @@ -155,7 +155,7 @@ private async Task TestHandlerSuccess(Func /// The specific client request function. /// The additional metadata, if any. /// A Task. - private async Task TestHandlerFailure(Func clientRequestFunc, Metadata additionalMetadata = null) + private static async Task TestHandlerFailure(Func clientRequestFunc, Metadata additionalMetadata = null) { // starts the server with the server interceptor var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; From e080a57c7c1de66203fef2563b1141e4d6ced64c Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 22 Feb 2023 20:05:56 +0000 Subject: [PATCH 0579/1499] [Exporter.Stackdriver] Fix analysis warnings (#956) Fix/suppress code analysis warnings in OpenTelemetry.Contrib.Exporter.Stackdriver. Contributes to #950. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../Implementation/ActivityExtensions.cs | 7 ++-- .../Implementation/Constants.cs | 39 ++++++++++--------- .../StackdriverTraceExporter.cs | 6 ++- .../TracerProviderBuilderExtensions.cs | 2 + .../Utils/CommonUtils.cs | 5 +++ .../TestActivityProcessor.cs | 14 +++---- 8 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt index fa997838e5..1fd1f60339 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt @@ -15,7 +15,7 @@ OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string projectId) -> void OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batchActivity) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string projectId) -> Google.Api.MonitoredResource static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index fa997838e5..1fd1f60339 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -15,7 +15,7 @@ OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string projectId) -> void OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batchActivity) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string projectId) -> Google.Api.MonitoredResource static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 18a530fda9..240c2af077 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; using Google.Cloud.Trace.V2; using Google.Protobuf.WellKnownTypes; @@ -27,7 +28,7 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation; internal static class ActivityExtensions { - private static Dictionary labelsToReplace = new Dictionary + private static readonly Dictionary LabelsToReplace = new Dictionary { { "component", "/component" }, { "http.method", "/http/method" }, @@ -94,7 +95,7 @@ public static Span ToSpan(this Activity activity, string projectId) // StackDriver uses different labels that are used to categorize spans // replace attribute keys with StackDriver version - foreach (var entry in labelsToReplace) + foreach (var entry in LabelsToReplace) { if (span.Attributes.AttributeMap.TryGetValue(entry.Key, out var attrValue)) { @@ -146,7 +147,7 @@ public static AttributeValue ToAttributeValue(this object? av) case double d: return new AttributeValue() { - StringValue = new TruncatableString() { Value = d.ToString() }, + StringValue = new TruncatableString() { Value = d.ToString(CultureInfo.InvariantCulture) }, }; case null: return new AttributeValue(); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs index 9f20621d53..800a31aa74 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs @@ -20,30 +20,31 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation; internal class Constants { - public static readonly string PackagVersionUndefined = "undefined"; + public const string PackagVersionUndefined = "undefined"; - public static readonly string LabelDescription = "OpenTelemetry string"; - public static readonly string OpenTelemetryTask = "OpenTelemetry_task"; - public static readonly string OpenTelemetryTaskDescription = "OpenTelemetry task identifier"; + public const string LabelDescription = "OpenTelemetry string"; + public const string OpenTelemetryTask = "OpenTelemetry_task"; + public const string OpenTelemetryTaskDescription = "OpenTelemetry task identifier"; - public static readonly string GcpGkeContainer = "k8s_container"; - public static readonly string GcpGceInstance = "gce_instance"; - public static readonly string AwsEc2Instance = "aws_ec2_instance"; - public static readonly string Global = "global"; + public const string GcpGkeContainer = "k8s_container"; + public const string GcpGceInstance = "gce_instance"; + public const string AwsEc2Instance = "aws_ec2_instance"; + public const string Global = "global"; - public static readonly string ProjectIdLabelKey = "project_id"; - public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue(); + public const string ProjectIdLabelKey = "project_id"; + + public const string GceGcpInstanceType = "cloud.google.com/gce/instance"; + public const string GcpInstanceIdKey = "cloud.google.com/gce/instance_id"; + public const string GcpAccountIdKey = "cloud.google.com/gce/project_id"; + public const string GcpZoneKey = "cloud.google.com/gce/zone"; - public static readonly string GceGcpInstanceType = "cloud.google.com/gce/instance"; - public static readonly string GcpInstanceIdKey = "cloud.google.com/gce/instance_id"; - public static readonly string GcpAccountIdKey = "cloud.google.com/gce/project_id"; - public static readonly string GcpZoneKey = "cloud.google.com/gce/zone"; + public const string K8sContainerType = "k8s.io/container"; + public const string K8sClusterNameKey = "k8s.io/cluster/name"; + public const string K8sContainerNameKey = "k8s.io/container/name"; + public const string K8sNamespaceNameKey = "k8s.io/namespace/name"; + public const string K8sPodNameKey = "k8s.io/pod/name"; - public static readonly string K8sContainerType = "k8s.io/container"; - public static readonly string K8sClusterNameKey = "k8s.io/cluster/name"; - public static readonly string K8sContainerNameKey = "k8s.io/container/name"; - public static readonly string K8sNamespaceNameKey = "k8s.io/namespace/name"; - public static readonly string K8sPodNameKey = "k8s.io/pod/name"; + public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue(); private static string GenerateDefaultTaskValue() { diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 222c5c12f0..e109388329 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -37,7 +37,9 @@ public class StackdriverTraceExporter : BaseExporter private readonly TraceServiceSettings traceServiceSettings; private readonly TraceServiceClient traceServiceClient; +#pragma warning disable CA1810 // Initialize reference type static fields inline static StackdriverTraceExporter() +#pragma warning restore CA1810 // Initialize reference type static fields inline { try { @@ -87,7 +89,7 @@ internal StackdriverTraceExporter(string projectId, TraceServiceClient traceServ } /// - public override ExportResult Export(in Batch batchActivity) + public override ExportResult Export(in Batch batch) { TraceServiceClient traceWriter = this.traceServiceClient; if (this.traceServiceClient == null) @@ -103,7 +105,7 @@ public override ExportResult Export(in Batch batchActivity) ProjectName = this.googleCloudProjectId, }; - foreach (var activity in batchActivity) + foreach (var activity in batch) { // It should never happen that the time has no correct kind, only if OpenTelemetry is used incorrectly. if (activity.StartTimeUtc.Kind == DateTimeKind.Utc) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index 6d08567660..e96e34b8cb 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -36,8 +36,10 @@ public static TracerProviderBuilder UseStackdriverExporter( { Guard.ThrowIfNull(builder); +#pragma warning disable CA2000 // Dispose objects before losing scope var activityExporter = new StackdriverTraceExporter(projectId); return builder.AddProcessor(new BatchActivityExportProcessor(activityExporter)); +#pragma warning restore CA2000 // Dispose objects before losing scope } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs index 3aac886d42..ef9067fc54 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs @@ -32,6 +32,11 @@ public static class CommonUtils /// . public static IEnumerable> Partition(this IEnumerable source, int size) { + if (source == null) + { + throw new System.ArgumentNullException(nameof(source)); + } + using var enumerator = source.GetEnumerator(); while (enumerator.MoveNext()) { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index 816c34a496..c4a55c3755 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -34,20 +34,20 @@ public TestActivityProcessor(Action onStart, Action onEnd) this.EndAction = onEnd; } - public bool ShutdownCalled { get; private set; } = false; + public bool ShutdownCalled { get; private set; } - public bool ForceFlushCalled { get; private set; } = false; + public bool ForceFlushCalled { get; private set; } - public bool DisposedCalled { get; private set; } = false; + public bool DisposedCalled { get; private set; } - public override void OnStart(Activity activity) + public override void OnStart(Activity data) { - this.StartAction?.Invoke(activity); + this.StartAction?.Invoke(data); } - public override void OnEnd(Activity activity) + public override void OnEnd(Activity data) { - this.EndAction?.Invoke(activity); + this.EndAction?.Invoke(data); } protected override bool OnShutdown(int timeoutMilliseconds) From d0190c349d624417685b01ec44528e768db02b55 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 22 Feb 2023 12:56:48 -0800 Subject: [PATCH 0580/1499] [OneCollector] Registration extension + tenant token tweaks (#1032) * OneCollector registration extension + tenant token tweaks. * CHANGELOG patch. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 14 ++- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 14 ++- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 14 ++- .../netstandard2.0/PublicAPI.Unshipped.txt | 14 ++- .../netstandard2.1/PublicAPI.Unshipped.txt | 14 ++- .../CHANGELOG.md | 5 + .../Logs/OneCollectorLogExporterBuilder.cs | 118 ++++++++++++++++++ .../Logs/OneCollectorLogExporterOptions.cs | 4 +- ...torOpenTelemetryLoggerOptionsExtensions.cs | 104 +++++++++++++-- .../OneCollectorExporterOptions.cs | 31 +++-- .../OneCollectorExporterTransportOptions.cs | 6 +- .../README.md | 6 +- ...enTelemetryLoggerOptionsExtensionsTests.cs | 52 ++++++++ 13 files changed, 350 insertions(+), 46 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index 8e36c38895..80dca438b6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -2,8 +2,6 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! @@ -15,7 +13,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions. OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExporterBuilder +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index 8e36c38895..80dca438b6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -2,8 +2,6 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! @@ -15,7 +13,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions. OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExporterBuilder +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index 8e36c38895..80dca438b6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -2,8 +2,6 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! @@ -15,7 +13,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions. OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExporterBuilder +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 8e36c38895..80dca438b6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -2,8 +2,6 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! @@ -15,7 +13,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions. OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExporterBuilder +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 8e36c38895..80dca438b6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -2,8 +2,6 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TenantToken.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! @@ -15,7 +13,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions. OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExporterBuilder +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 22e4a43d8d..621c997c8f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Tenant token is no longer exposed on `OneCollectorExporterOptions` and will be + set automatically from the instrumentation key. Added new registration + overloads and a builder to help with configuration. + ([#1032](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1032)) + ## 0.1.0-alpha.1 Released 2023-Feb-16 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs new file mode 100644 index 0000000000..25b5b5cad3 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs @@ -0,0 +1,118 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Exporter.OneCollector; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Logs; + +/// +/// Contains methods for building instances. +/// +public sealed class OneCollectorLogExporterBuilder +{ + internal OneCollectorLogExporterBuilder(string? instrumentationKey) + { + this.Options = new() + { + InstrumentationKey = instrumentationKey, + }; + } + + internal OneCollectorLogExporterBuilder(IConfiguration configuration) + : this(instrumentationKey: null) + { + Debug.Assert(configuration != null, "configuration was null"); + + configuration.Bind(this.Options); + } + + internal OneCollectorLogExporterOptions Options { get; } + + /// + /// Register a callback action for configuring the batch options of . + /// + /// Callback action for configuring . + /// The supplied for + /// call chaining. + public OneCollectorLogExporterBuilder ConfigureBatchOptions(Action> configure) + { + Guard.ThrowIfNull(configure); + + configure(this.Options.BatchOptions); + + return this; + } + + /// + /// Register a callback action for configuring the transport options of . + /// + /// Callback action for configuring . + /// The supplied for + /// call chaining. + public OneCollectorLogExporterBuilder ConfigureTransportOptions(Action configure) + { + Guard.ThrowIfNull(configure); + + configure(this.Options.TransportOptions); + + return this; + } + + /// + /// Sets the + /// property. Default value: Log. + /// + /// + /// Default event name. + /// The supplied for + /// call chaining. + public OneCollectorLogExporterBuilder SetDefaultEventName(string defaultEventName) + { + Guard.ThrowIfNullOrWhitespace(defaultEventName); + + this.Options.DefaultEventName = defaultEventName; + + return this; + } + + /// + /// Sets the + /// property. + /// + /// + /// Instrumentation key. + /// The supplied for + /// call chaining. + public OneCollectorLogExporterBuilder SetInstrumentationKey(string instrumentationKey) + { + Guard.ThrowIfNullOrWhitespace(instrumentationKey); + + this.Options.InstrumentationKey = instrumentationKey; + + return this; + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index e08641f56a..ef02b0733f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Exporter.OneCollector; public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions, ISinkFactory { /// - /// Gets or sets the default event name. Default value: Log. + /// Gets or sets the default event name. Default value: Log. /// /// /// Note: The default event name is used when an /// Gets or sets the default event namespace. Default value: - /// OpenTelemetry.Logs. + /// OpenTelemetry.Logs. /// /// /// Note: The default event namespace is used if a +using Microsoft.Extensions.Configuration; using OpenTelemetry.Exporter.OneCollector; using OpenTelemetry.Internal; @@ -24,6 +25,8 @@ namespace OpenTelemetry.Logs; /// public static class OneCollectorOpenTelemetryLoggerOptionsExtensions { + /* + TODO: Enable this once logging supports DI/options binding. /// /// Add OneCollector exporter to the . @@ -34,32 +37,119 @@ public static class OneCollectorOpenTelemetryLoggerOptionsExtensions public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options) => AddOneCollectorExporter(options, _ => { }); + */ /// /// Add OneCollector exporter to the . /// /// . - /// Callback action for configuring . + /// Callback action for configuring . /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, - Action configure) + Action configure) { - Guard.ThrowIfNull(options); Guard.ThrowIfNull(configure); - var logExporterOptions = new OneCollectorLogExporterOptions(); + return AddOneCollectorExporter(options, instrumentationKey: null, configuration: null, configure); + } + + /// + /// Add OneCollector exporter to the . + /// + /// . + /// OneCollector instrumentation key. + /// The supplied for call + /// chaining. + public static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options, + string instrumentationKey) + { + Guard.ThrowIfNullOrWhitespace(instrumentationKey); + + return AddOneCollectorExporter(options, instrumentationKey, configuration: null, configure: null); + } + + /// + /// Add OneCollector exporter to the . + /// + /// . + /// OneCollector instrumentation key. + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options, + string instrumentationKey, + Action configure) + { + Guard.ThrowIfNullOrWhitespace(instrumentationKey); + + return AddOneCollectorExporter(options, instrumentationKey, configuration: null, configure); + } + + /// + /// Add OneCollector exporter to the . + /// + /// . + /// Configuration used to build . + /// The supplied for call + /// chaining. + public static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options, + IConfiguration configuration) + { + Guard.ThrowIfNull(configuration); + + return AddOneCollectorExporter(options, instrumentationKey: null, configuration, configure: null); + } + + /// + /// Add OneCollector exporter to the . + /// + /// . + /// Configuration used to build . + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options, + IConfiguration configuration, + Action configure) + { + Guard.ThrowIfNull(configuration); + + return AddOneCollectorExporter(options, instrumentationKey: null, configuration, configure); + } + + internal static OpenTelemetryLoggerOptions AddOneCollectorExporter( + this OpenTelemetryLoggerOptions options, + string? instrumentationKey, + IConfiguration? configuration, + Action? configure) + { + Guard.ThrowIfNull(options); + + var builder = configuration == null + ? new OneCollectorLogExporterBuilder(instrumentationKey) + : new OneCollectorLogExporterBuilder(configuration); + + configure?.Invoke(builder); - configure?.Invoke(logExporterOptions); + var exporterOptions = builder.Options; - var batchOptions = logExporterOptions.BatchOptions; + var batchOptions = exporterOptions.BatchOptions; #pragma warning disable CA2000 // Dispose objects before losing scope options.AddProcessor( new BatchLogRecordExportProcessor( - new OneCollectorLogExporter(logExporterOptions), + new OneCollectorLogExporter(exporterOptions), batchOptions.MaxQueueSize, batchOptions.ScheduledDelayMilliseconds, batchOptions.ExporterTimeoutMilliseconds, diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs index fae8c8a977..533e14d3c7 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using System.ComponentModel.DataAnnotations; + namespace OpenTelemetry.Exporter.OneCollector; /// @@ -25,14 +27,13 @@ internal OneCollectorExporterOptions() { } - /// - /// Gets or sets the OneCollector tenant token. - /// - public string? TenantToken { get; set; } - /// /// Gets or sets the OneCollector instrumentation key. /// + /// + /// Note: Instrumentation key is required. + /// + [Required] public string? InstrumentationKey { get; set; } /// @@ -40,18 +41,30 @@ internal OneCollectorExporterOptions() /// public OneCollectorExporterTransportOptions TransportOptions { get; } = new(); + /// + /// Gets the OneCollector tenant token. + /// + internal string? TenantToken { get; private set; } + internal virtual void Validate() { - if (string.IsNullOrWhiteSpace(this.TenantToken)) + if (string.IsNullOrWhiteSpace(this.InstrumentationKey)) { - throw new InvalidOperationException($"{nameof(this.TenantToken)} was not specified on {this.GetType().Name} options."); + throw new InvalidOperationException($"{nameof(this.InstrumentationKey)} was not specified on {this.GetType().Name} options."); } - if (string.IsNullOrWhiteSpace(this.InstrumentationKey)) +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER + var positionOfFirstDash = this.InstrumentationKey.IndexOf('-', StringComparison.OrdinalIgnoreCase); +#else + var positionOfFirstDash = this.InstrumentationKey!.IndexOf('-'); +#endif + if (positionOfFirstDash < 0) { - throw new InvalidOperationException($"{nameof(this.InstrumentationKey)} was not specified on {this.GetType().Name} options."); + throw new InvalidOperationException($"{nameof(this.InstrumentationKey)} specified on {this.GetType().Name} options is invalid."); } + this.TenantToken = this.InstrumentationKey.Substring(0, positionOfFirstDash); + this.TransportOptions.Validate(); } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs index ef82e213ef..bc59b956ee 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs @@ -33,7 +33,7 @@ internal OneCollectorExporterTransportOptions() /// /// Gets or sets OneCollector endpoint address. Default value: - /// https://mobile.events.data.microsoft.com/OneCollector/1.0/. + /// https://mobile.events.data.microsoft.com/OneCollector/1.0/. /// public Uri Endpoint { get; set; } = new Uri(DefaultOneCollectorEndpoint); @@ -45,7 +45,7 @@ internal OneCollectorExporterTransportOptions() /// /// Gets or sets the maximum request payload size in bytes when sending data - /// to OneCollector. Default value: 4,194,304. + /// to OneCollector. Default value: 4,194,304. /// /// /// Note: Set to -1 for unlimited request payload size. @@ -54,7 +54,7 @@ internal OneCollectorExporterTransportOptions() /// /// Gets or sets the maximum number of items per request payload when - /// sending data to OneCollector. Default value: 1500. + /// sending data to OneCollector. Default value: 1500. /// /// /// Note: Set to -1 for unlimited number of items per request payload. diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index c20dc71759..d587afa987 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -25,11 +25,7 @@ using var logFactory = LoggerFactory.Create(builder => builder { builder.ParseStateValues = true; builder.IncludeScopes = true; - builder.AddOneCollectorExporter(o => - { - o.TenantToken = "tenant-token-here"; - o.InstrumentationKey = "instrumentation-key-here"; - }); + builder.AddOneCollectorExporter("instrumentation-key-here"); })); var logger = logFactory.CreateLogger(); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs new file mode 100644 index 0000000000..08a61d6bbd --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs @@ -0,0 +1,52 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class OneCollectorOpenTelemetryLoggerOptionsExtensionsTests +{ + [Fact] + public void InstrumentationKeyAndTenantTokenValidationTest() + { + Assert.Throws(() => + { + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter(options => { }); + })); + }); + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter("token-extrainformation"); + })); + + Assert.Throws(() => + { + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter("invalidinstrumentationkey"); + })); + }); + } +} From 978784693c570283e6105aaec3732d61defe9627 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 22 Feb 2023 21:34:24 +0000 Subject: [PATCH 0581/1499] [Shared] Fix analysis warnings (#953) * [Shared] Fix analysis warnings Fix/suppress code analysis warnings in OpenTelemetry.Contrib.Shared. Contributes to #950. * Condense IDisposable implemnetation Apply code review feedback and put the code to dispose inline. --------- --- .../DiagnosticSourceListener.cs | 2 +- .../DiagnosticSourceSubscriber.cs | 10 +++------- .../InstrumentationEventSource.cs | 2 +- .../MultiTypePropertyFetcher.cs | 10 +++++++--- .../DiagnosticSourceInstrumentation/PropertyFetcher.cs | 10 +++++++--- .../TestActivityProcessor.cs | 9 +++++---- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs index ef3a0c46be..9dc3f74a7b 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs @@ -21,7 +21,7 @@ namespace OpenTelemetry.Instrumentation; -internal class DiagnosticSourceListener : IObserver> +internal sealed class DiagnosticSourceListener : IObserver> { private readonly ListenerHandler handler; diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs index f0065c97ac..99a25bbf7f 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs @@ -21,7 +21,9 @@ namespace OpenTelemetry.Instrumentation; -internal class DiagnosticSourceSubscriber : IDisposable, IObserver +#pragma warning disable CA1812 +internal sealed class DiagnosticSourceSubscriber : IDisposable, IObserver +#pragma warning restore CA1812 { private readonly Func handlerFactory; private readonly Func diagnosticSourceFilter; @@ -86,12 +88,6 @@ public void OnError(Exception error) /// public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) { if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 1) { diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs index 53b684f707..07f9f56057 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Instrumentation; /// EventSource events emitted from the project. /// [EventSource(Name = "OpenTelemetry-Instrumentation")] -internal class InstrumentationEventSource : EventSource +internal sealed class InstrumentationEventSource : EventSource { public static InstrumentationEventSource Log = new InstrumentationEventSource(); diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs index 8ed27681e4..122d40743f 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs @@ -25,7 +25,9 @@ namespace OpenTelemetry.Instrumentation; /// PropertyFetcher fetches a property from an object. /// /// The type of the property being fetched. -internal class MultiTypePropertyFetcher +#pragma warning disable CA1812 +internal sealed class MultiTypePropertyFetcher +#pragma warning restore CA1812 { private readonly string propertyName; private readonly ConcurrentDictionary innerFetcher = new ConcurrentDictionary(); @@ -55,7 +57,7 @@ public T Fetch(object obj) PropertyFetch fetcher = null; if (!this.innerFetcher.TryGetValue(type, out fetcher)) { - var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.InvariantCultureIgnoreCase)); + var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.OrdinalIgnoreCase)); if (property == null) { property = type.GetProperty(this.propertyName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); @@ -100,7 +102,9 @@ public virtual T Fetch(object obj) return default; } - private class TypedPropertyFetch : PropertyFetch +#pragma warning disable CA1812 + private sealed class TypedPropertyFetch : PropertyFetch +#pragma warning restore CA1812 where TDeclaredProperty : T { private readonly Func propertyFetch; diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs index 15e3d099b6..8aab31e0be 100644 --- a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs +++ b/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs @@ -24,7 +24,9 @@ namespace OpenTelemetry.Instrumentation; /// PropertyFetcher fetches a property from an object. /// /// The type of the property being fetched. -internal class PropertyFetcher +#pragma warning disable CA1812 +internal sealed class PropertyFetcher +#pragma warning restore CA1812 { private readonly string propertyName; private PropertyFetch innerFetcher; @@ -70,7 +72,7 @@ public bool TryFetch(object obj, out T value) if (this.innerFetcher == null) { var type = obj.GetType().GetTypeInfo(); - var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.InvariantCultureIgnoreCase)); + var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.OrdinalIgnoreCase)); if (property == null) { property = type.GetProperty(this.propertyName); @@ -109,7 +111,9 @@ public virtual bool TryFetch(object obj, out T value) return false; } - private class TypedPropertyFetch : PropertyFetch +#pragma warning disable CA1812 + private sealed class TypedPropertyFetch : PropertyFetch +#pragma warning restore CA1812 where TDeclaredProperty : T { private readonly Func propertyFetch; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs index dc127c38f8..21ab4cf235 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs @@ -19,7 +19,7 @@ namespace OpenTelemetry.Tests; -internal class TestActivityProcessor : BaseProcessor +internal sealed class TestActivityProcessor : BaseProcessor { public Action StartAction; public Action EndAction; @@ -34,11 +34,11 @@ public TestActivityProcessor(Action onStart, Action onEnd) this.EndAction = onEnd; } - public bool ShutdownCalled { get; private set; } = false; + public bool ShutdownCalled { get; private set; } - public bool ForceFlushCalled { get; private set; } = false; + public bool ForceFlushCalled { get; private set; } - public bool DisposedCalled { get; private set; } = false; + public bool DisposedCalled { get; private set; } public override void OnStart(Activity span) { @@ -64,6 +64,7 @@ protected override bool OnShutdown(int timeoutMilliseconds) protected override void Dispose(bool disposing) { + base.Dispose(disposing); this.DisposedCalled = true; } } From 31229a5be33e2c224e78acf228d1c20c2e8c5d3a Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 22 Feb 2023 13:55:23 -0800 Subject: [PATCH 0582/1499] [Instrumentation.Process] Added Grafana dashboard template to the example folder. (#1016) * initial * comment * comment * relative link * Update src/OpenTelemetry.Instrumentation.Process/README.md Co-authored-by: Reiley Yang * lint * update link style and use rewrap * CI * CI * Update src/OpenTelemetry.Instrumentation.Process/README.md --------- --- ...trumentation-grafana-dashboard-sample.json | 640 ++++++++++++++++++ .../README.md | 60 +- 2 files changed, 677 insertions(+), 23 deletions(-) create mode 100644 examples/process-instrumentation/process-instrumentation-grafana-dashboard-sample.json diff --git a/examples/process-instrumentation/process-instrumentation-grafana-dashboard-sample.json b/examples/process-instrumentation/process-instrumentation-grafana-dashboard-sample.json new file mode 100644 index 0000000000..3d8dceff0c --- /dev/null +++ b/examples/process-instrumentation/process-instrumentation-grafana-dashboard-sample.json @@ -0,0 +1,640 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "description": "The amount of committed virtual memory. One way to think of this is all the address space this process can read from without triggering an access violation; this includes memory backed solely by RAM, by a swapfile/pagefile and by other mapped files on disk.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "{__name__=\"process_memory_virtual_By\", instance=\"localhost:9464\", job=\"otel\"}" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 5, + "w": 9, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "process_memory_virtual_By", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "virtual memory usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "description": "the amount of physical memory allocated", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 10, + "x": 9, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "process_memory_usage_By", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "physical memory usage", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "description": "Total CPU seconds broken down by states.\nProcess.UserProcessorTime: Gets the user processor time.\nProcess.PrivilegedProcessorTime: Gets the privileged processor time.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 9, + "x": 0, + "y": 5 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "process_cpu_time_s", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "cpu time", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "description": "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "{instance=\"localhost:9464\", job=\"otel\"}" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": false, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 10, + "x": 9, + "y": 5 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "100 * (delta(process_cpu_time_s{state='system'}[30s])/ignoring(state)(process_cpu_count__processors_* 30))", + "legendFormat": "__auto", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "100 * (delta(process_cpu_time_s{state='user'}[30s])/ignoring(state)(process_cpu_count__processors_* 30))", + "hide": false, + "legendFormat": "__auto", + "range": true, + "refId": "B" + } + ], + "title": "cpu utilization", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "description": "Process threads count.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 9, + "x": 0, + "y": 11 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "process_threads__threads_", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "thread count", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "description": "The number of processors (CPU cores) available.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 3, + "x": 9, + "y": 11 + }, + "id": 8, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "InQLY014z" + }, + "editorMode": "code", + "expr": "process_cpu_count__processors_", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "cpu count", + "type": "gauge" + } + ], + "refresh": "5s", + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-2h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "process instrumentation", + "uid": "WPv6P0JVk", + "version": 6, + "weekStart": "" +} diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 89c3c949b6..83686c293b 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -5,13 +5,12 @@ This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), -which instruments [.NET](https://docs.microsoft.com/dotnet) and -collect telemetry about process behavior. +which instruments [.NET](https://docs.microsoft.com/dotnet) and collects +telemetry about process behavior. The process metric instruments being implemented are following OpenTelemetry -[metrics semantic conventions][1]. - -[1]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md#metric-instruments +[metrics semantic +conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md#metric-instruments). ## Steps to enable OpenTelemetry.Instrumentation.Process @@ -46,7 +45,23 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder() ``` Refer to [Program.cs](../../examples/process-instrumentation/Program.cs) for a -complete demo. +complete demo. This examples sets up the OpenTelemetry Prometheus exporter, +which requires adding the package +[`OpenTelemetry.Exporter.Prometheus.HttpListener`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +to the application. + +Additionally, this +[document](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/metrics/getting-started-prometheus-grafana/README.md) +shows how to use Prometheus and Grafana to build a dashboard for your +application. +[This](../../examples/process-instrumentation/process-instrumentation-grafana-dashboard-sample.json) +is the Grafana dashboard template which has all the metrics currently supported +by this package; plus an additional aggregated metric `CPU utilization` +calculated with the raw metrics, `CPU time` and `CPU count`. + +Please follow the instructions in this +[document](https://grafana.com/docs/grafana/v9.0/dashboards/export-import/) to +import a Grafana dashboard by uploading the JSON template file. ## Metrics @@ -61,15 +76,15 @@ The amount of physical memory allocated for this process. The API used to retrieve the value is: * [Process.WorkingSet64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.workingset64): -Gets the amount of physical memory, in bytes, -allocated for the associated process. +Gets the amount of physical memory, in bytes, allocated for the associated +process. ### process.memory.virtual -The amount of committed virtual memory for this process. -One way to think of this is all the address space this process can read from -without triggering an access violation; this includes memory backed solely by RAM, -by a swapfile/pagefile and by other mapped files on disk. +The amount of committed virtual memory for this process. One way to think of +this is all the address space this process can read from without triggering an +access violation; this includes memory backed solely by RAM, by a +swapfile/pagefile and by other mapped files on disk. | Units | Instrument Type | Value Type | |-------|-------------------------|------------| @@ -78,8 +93,8 @@ by a swapfile/pagefile and by other mapped files on disk. The API used to retrieve the value is: * [Process.VirtualMemorySize64](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.virtualmemorysize64): -Gets the amount of the virtual memory, in bytes, -allocated for the associated process. +Gets the amount of the virtual memory, in bytes, allocated for the associated +process. ### process.cpu.time @@ -105,14 +120,14 @@ The number of processors (CPU cores) available to the current process. |---------------|-------------------------|------------| | `{processors}`| ObservableUpDownCounter | `Int32` | -The API used to retrieve the value is [System.Environment.ProcessorCount](https://learn.microsoft.com/dotnet/api/system.environment.processorcount). - -> **Note** -> This metric is under [discussion][2] and not part of the -[Process Metrics Spec][3] at this time. +The API used to retrieve the value is +[System.Environment.ProcessorCount](https://learn.microsoft.com/dotnet/api/system.environment.processorcount). -[2]: https://github.com/open-telemetry/opentelemetry-specification/issues/3200 -[3]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md +> **Note** This metric is under +> [discussion](https://github.com/open-telemetry/opentelemetry-specification/issues/3200) +and not part of the [Process Metrics +Spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md) +at this time. ### process.threads @@ -125,8 +140,7 @@ Process threads count. The API used to retrieve the value is: * [Process.Threads](https://learn.microsoft.com/dotnet/api/system.diagnostics.process.threads): -Gets the set of threads that are running -in the associated process. +Gets the set of threads that are running in the associated process. ## References From 6d4fb62ee904582f2b0787ee5e02d227558c5359 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 22 Feb 2023 14:33:24 -0800 Subject: [PATCH 0583/1499] Update Utf8JsonWriter logic. (#1033) --- .../CommonSchemaJsonSerializer.cs | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs index 266d56fbcd..a6cf0d7a64 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -62,25 +62,20 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, var numberOfSerializedItems = 0; long payloadSizeInBytes = initialSizeOfPayloadInBytes; - var writer = ThreadStorageHelper.Utf8JsonWriter ??= new( - stream, - new JsonWriterOptions - { -#if DEBUG - SkipValidation = false, -#else - SkipValidation = true, -#endif - }); - - foreach (var item in batch) + var writer = ThreadStorageHelper.Utf8JsonWriter; + if (writer == null) + { + writer = ThreadStorageHelper.Utf8JsonWriter = new( + stream, + new JsonWriterOptions { SkipValidation = true }); + } + else { - // Note: This is a slow operation. We call this each iteration - // (instead of once per batch) to reset _currentDepth on - // Utf8JsonWriter so it doesn't write a comma after each record. - // Need a faster solution here! writer.Reset(stream); + } + foreach (var item in batch) + { this.SerializeItemToJson(resource, item, writer); var currentItemSizeInBytes = writer.BytesCommitted + writer.BytesPending + 1; @@ -88,6 +83,7 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, payloadSizeInBytes += currentItemSizeInBytes; writer.Flush(); + writer.Reset(); stream.Write(NewLine, 0, 1); From e6a714d14be5942af7a5faf805a0835cd1e2ce9c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 23 Feb 2023 12:43:50 -0800 Subject: [PATCH 0584/1499] [OneCollectorExporter] Connection string design (#1037) * Connection string design for OneCollectorExporter. * CHANGELOG patch. --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 14 ++-- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 14 ++-- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 14 ++-- .../netstandard2.0/PublicAPI.Unshipped.txt | 14 ++-- .../netstandard2.1/PublicAPI.Unshipped.txt | 16 ++-- .../CHANGELOG.md | 4 + .../Internal/ConnectionStringParser.cs | 76 +++++++++++++++++++ .../Logs/OneCollectorLogExporterBuilder.cs | 34 ++++----- .../Logs/OneCollectorLogExporterOptions.cs | 6 +- ...torOpenTelemetryLoggerOptionsExtensions.cs | 26 +++---- .../OneCollectorExporterOptions.cs | 21 +++-- .../OneCollectorExporterTransportOptions.cs | 14 +++- ...OneCollectorExporterValidationException.cs | 61 +++++++++++++++ .../README.md | 2 +- .../ConnectionStringParserTests.cs | 59 ++++++++++++++ ...enTelemetryLoggerOptionsExtensionsTests.cs | 37 ++++++--- 16 files changed, 334 insertions(+), 78 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index 80dca438b6..438e9e6c3d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,11 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions @@ -16,12 +20,12 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorL OpenTelemetry.Logs.OneCollectorLogExporterBuilder OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index 80dca438b6..438e9e6c3d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,11 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions @@ -16,12 +20,12 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorL OpenTelemetry.Logs.OneCollectorLogExporterBuilder OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index 80dca438b6..438e9e6c3d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -1,11 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions @@ -16,12 +20,12 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorL OpenTelemetry.Logs.OneCollectorLogExporterBuilder OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 80dca438b6..438e9e6c3d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,11 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions @@ -16,12 +20,12 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorL OpenTelemetry.Logs.OneCollectorLogExporterBuilder OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 80dca438b6..9087227582 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,11 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.InstrumentationKey.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions @@ -16,12 +20,12 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorL OpenTelemetry.Logs.OneCollectorLogExporterBuilder OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetInstrumentationKey(string! instrumentationKey) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! instrumentationKey, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 621c997c8f..581cc97f28 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -7,6 +7,10 @@ overloads and a builder to help with configuration. ([#1032](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1032)) +* Switched to using a connection string design instead of passing + instrumentation key directly. + ([#1037](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1037)) + ## 0.1.0-alpha.1 Released 2023-Feb-16 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs new file mode 100644 index 0000000000..9ed57f0bef --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs @@ -0,0 +1,76 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class ConnectionStringParser +{ + public ConnectionStringParser(string connectionString) + { + Guard.ThrowIfNullOrWhitespace(connectionString); + + const char Semicolon = ';'; + const char EqualSign = '='; + + foreach (var token in connectionString.Split(Semicolon)) + { + if (string.IsNullOrWhiteSpace(token)) + { + continue; + } + +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER + var index = token.IndexOf(EqualSign, StringComparison.Ordinal); +#else + var index = token.IndexOf(EqualSign); +#endif + if (index == -1 || index != token.LastIndexOf(EqualSign)) + { + continue; + } + + var pair = token.Trim().Split(EqualSign); + + var key = pair[0].Trim(); + var value = pair[1].Trim(); + if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) + { + throw new ArgumentException("Connection string cannot contain empty keys or values.", nameof(connectionString)); + } + + this.ParsedKeyValues[key] = value; + } + + if (this.ParsedKeyValues.Count == 0) + { + throw new ArgumentException("Connection string is invalid.", nameof(connectionString)); + } + } + + public string? InstrumentationKey + { + get + { + this.ParsedKeyValues.TryGetValue(nameof(this.InstrumentationKey), out string? instrumentationKey); + + return instrumentationKey; + } + } + + internal Dictionary ParsedKeyValues { get; } = new(StringComparer.Ordinal); +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs index 25b5b5cad3..52aa8a807e 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs @@ -26,16 +26,16 @@ namespace OpenTelemetry.Logs; /// public sealed class OneCollectorLogExporterBuilder { - internal OneCollectorLogExporterBuilder(string? instrumentationKey) + internal OneCollectorLogExporterBuilder(string? connectionString) { this.Options = new() { - InstrumentationKey = instrumentationKey, + ConnectionString = connectionString, }; } internal OneCollectorLogExporterBuilder(IConfiguration configuration) - : this(instrumentationKey: null) + : this(connectionString: null) { Debug.Assert(configuration != null, "configuration was null"); @@ -79,39 +79,39 @@ public OneCollectorLogExporterBuilder ConfigureTransportOptions(Action - /// Sets the - /// property. Default value: Log. + /// Sets the + /// property. /// /// - /// Default event name. + /// Connection string. /// The supplied for /// call chaining. - public OneCollectorLogExporterBuilder SetDefaultEventName(string defaultEventName) + public OneCollectorLogExporterBuilder SetConnectionString(string connectionString) { - Guard.ThrowIfNullOrWhitespace(defaultEventName); + Guard.ThrowIfNullOrWhitespace(connectionString); - this.Options.DefaultEventName = defaultEventName; + this.Options.ConnectionString = connectionString; return this; } /// - /// Sets the - /// property. + /// Sets the + /// property. Default value: Log. /// /// - /// Instrumentation key. + /// Default event name. /// The supplied for /// call chaining. - public OneCollectorLogExporterBuilder SetInstrumentationKey(string instrumentationKey) + public OneCollectorLogExporterBuilder SetDefaultEventName(string defaultEventName) { - Guard.ThrowIfNullOrWhitespace(instrumentationKey); + Guard.ThrowIfNullOrWhitespace(defaultEventName); - this.Options.InstrumentationKey = instrumentationKey; + this.Options.DefaultEventName = defaultEventName; return this; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index ef02b0733f..2c036105e3 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -68,7 +68,7 @@ ISink ISinkFactory.CreateSink() this.InstrumentationKey!, transportOptions.Endpoint, transportOptions.HttpCompression, - transportOptions.HttpClientFactory() ?? throw new InvalidOperationException($"{nameof(OneCollectorLogExporterOptions)} was missing HttpClientFactory or it returned null."))); + transportOptions.HttpClientFactory() ?? throw new OneCollectorExporterValidationException($"{nameof(OneCollectorLogExporterOptions)} was missing HttpClientFactory or it returned null."))); #pragma warning restore CA2000 // Dispose objects before losing scope } @@ -76,12 +76,12 @@ internal override void Validate() { if (string.IsNullOrWhiteSpace(this.DefaultEventNamespace)) { - throw new InvalidOperationException($"{nameof(this.DefaultEventNamespace)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventNamespace)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); } if (string.IsNullOrWhiteSpace(this.DefaultEventName)) { - throw new InvalidOperationException($"{nameof(this.DefaultEventName)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventName)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); } base.Validate(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs index 41e3d40eee..c3ab41f770 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs @@ -53,7 +53,7 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( { Guard.ThrowIfNull(configure); - return AddOneCollectorExporter(options, instrumentationKey: null, configuration: null, configure); + return AddOneCollectorExporter(options, connectionString: null, configuration: null, configure); } /// @@ -61,16 +61,16 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( /// cref="OpenTelemetryLoggerOptions"/>. /// /// . - /// OneCollector instrumentation key. + /// OneCollector connection string. /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, - string instrumentationKey) + string connectionString) { - Guard.ThrowIfNullOrWhitespace(instrumentationKey); + Guard.ThrowIfNullOrWhitespace(connectionString); - return AddOneCollectorExporter(options, instrumentationKey, configuration: null, configure: null); + return AddOneCollectorExporter(options, connectionString, configuration: null, configure: null); } /// @@ -78,18 +78,18 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( /// cref="OpenTelemetryLoggerOptions"/>. /// /// . - /// OneCollector instrumentation key. + /// OneCollector connection string. /// Callback action for configuring . /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, - string instrumentationKey, + string connectionString, Action configure) { - Guard.ThrowIfNullOrWhitespace(instrumentationKey); + Guard.ThrowIfNullOrWhitespace(connectionString); - return AddOneCollectorExporter(options, instrumentationKey, configuration: null, configure); + return AddOneCollectorExporter(options, connectionString, configuration: null, configure); } /// @@ -106,7 +106,7 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( { Guard.ThrowIfNull(configuration); - return AddOneCollectorExporter(options, instrumentationKey: null, configuration, configure: null); + return AddOneCollectorExporter(options, connectionString: null, configuration, configure: null); } /// @@ -125,19 +125,19 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( { Guard.ThrowIfNull(configuration); - return AddOneCollectorExporter(options, instrumentationKey: null, configuration, configure); + return AddOneCollectorExporter(options, connectionString: null, configuration, configure); } internal static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, - string? instrumentationKey, + string? connectionString, IConfiguration? configuration, Action? configure) { Guard.ThrowIfNull(options); var builder = configuration == null - ? new OneCollectorLogExporterBuilder(instrumentationKey) + ? new OneCollectorLogExporterBuilder(connectionString) : new OneCollectorLogExporterBuilder(configuration); configure?.Invoke(builder); diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs index 533e14d3c7..8ea82c4caf 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -28,19 +28,24 @@ internal OneCollectorExporterOptions() } /// - /// Gets or sets the OneCollector instrumentation key. + /// Gets or sets the OneCollector connection string. /// /// - /// Note: Instrumentation key is required. + /// Note: Connection string is required. /// [Required] - public string? InstrumentationKey { get; set; } + public string? ConnectionString { get; set; } /// /// Gets the OneCollector transport options. /// public OneCollectorExporterTransportOptions TransportOptions { get; } = new(); + /// + /// Gets the OneCollector instrumentation key. + /// + internal string? InstrumentationKey { get; private set; } + /// /// Gets the OneCollector tenant token. /// @@ -48,9 +53,15 @@ internal OneCollectorExporterOptions() internal virtual void Validate() { + if (string.IsNullOrWhiteSpace(this.ConnectionString)) + { + throw new OneCollectorExporterValidationException($"{nameof(this.ConnectionString)} was not specified on {this.GetType().Name} options."); + } + + this.InstrumentationKey = new ConnectionStringParser(this.ConnectionString!).InstrumentationKey; if (string.IsNullOrWhiteSpace(this.InstrumentationKey)) { - throw new InvalidOperationException($"{nameof(this.InstrumentationKey)} was not specified on {this.GetType().Name} options."); + throw new OneCollectorExporterValidationException("Instrumentation key was not specified on connection string."); } #if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -60,7 +71,7 @@ internal virtual void Validate() #endif if (positionOfFirstDash < 0) { - throw new InvalidOperationException($"{nameof(this.InstrumentationKey)} specified on {this.GetType().Name} options is invalid."); + throw new OneCollectorExporterValidationException($"Instrumentation key specified as part of {nameof(this.ConnectionString)} on {this.GetType().Name} options is invalid."); } this.TenantToken = this.InstrumentationKey.Substring(0, positionOfFirstDash); diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs index bc59b956ee..a65365dbe0 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs @@ -14,6 +14,8 @@ // limitations under the License. // +using System.ComponentModel.DataAnnotations; + namespace OpenTelemetry.Exporter.OneCollector; /// @@ -35,6 +37,10 @@ internal OneCollectorExporterTransportOptions() /// Gets or sets OneCollector endpoint address. Default value: /// https://mobile.events.data.microsoft.com/OneCollector/1.0/. /// + /// + /// Note: Endpoint is required. + /// + [Required] public Uri Endpoint { get; set; } = new Uri(DefaultOneCollectorEndpoint); /// @@ -88,22 +94,22 @@ internal void Validate() { if (this.Endpoint == null) { - throw new InvalidOperationException($"{nameof(this.Endpoint)} was not specified on {this.GetType().Name} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.Endpoint)} was not specified on {this.GetType().Name} options."); } if (this.HttpClientFactory == null) { - throw new InvalidOperationException($"{nameof(this.HttpClientFactory)} was not specified on {this.GetType().Name} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.HttpClientFactory)} was not specified on {this.GetType().Name} options."); } if (this.MaxPayloadSizeInBytes <= 0 && this.MaxPayloadSizeInBytes != -1) { - throw new InvalidOperationException($"{nameof(this.MaxPayloadSizeInBytes)} was invalid on {this.GetType().Name} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.MaxPayloadSizeInBytes)} was invalid on {this.GetType().Name} options."); } if (this.MaxNumberOfItemsPerPayload <= 0 && this.MaxNumberOfItemsPerPayload != -1) { - throw new InvalidOperationException($"{nameof(this.MaxNumberOfItemsPerPayload)} was invalid on {this.GetType().Name} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.MaxNumberOfItemsPerPayload)} was invalid on {this.GetType().Name} options."); } } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs new file mode 100644 index 0000000000..717c4abd6e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs @@ -0,0 +1,61 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.Serialization; + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Represents errors that occur validating OneCollectorExporter configuration. +/// +[Serializable] +public sealed class OneCollectorExporterValidationException : Exception +{ + /// + /// Initializes a new instance of the class. + /// + public OneCollectorExporterValidationException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + public OneCollectorExporterValidationException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the + /// exception. + /// The exception that is the cause of the + /// current exception, or a reference if no inner + /// exception is specified. + public OneCollectorExporterValidationException(string message, Exception? innerException) + : base(message, innerException) + { + } + + private OneCollectorExporterValidationException(SerializationInfo serializationInfo, StreamingContext streamingContext) + : base(serializationInfo, streamingContext) + { + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index d587afa987..009de85089 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -25,7 +25,7 @@ using var logFactory = LoggerFactory.Create(builder => builder { builder.ParseStateValues = true; builder.IncludeScopes = true; - builder.AddOneCollectorExporter("instrumentation-key-here"); + builder.AddOneCollectorExporter("InstrumentationKey=instrumentation-key-here"); })); var logger = logFactory.CreateLogger(); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs new file mode 100644 index 0000000000..a4ebace172 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs @@ -0,0 +1,59 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class ConnectionStringParserTests +{ + [Fact] + public void InvalidConnectionStringTest() + { + Assert.Throws(() => + { + new ConnectionStringParser("invalid-connection-string"); + }); + + Assert.Throws(() => + { + new ConnectionStringParser("Key="); + }); + + Assert.Throws(() => + { + new ConnectionStringParser("Key1=Value1;Key2="); + }); + } + + [Fact] + public void ExtraDataIgnoredInConnectionStringTest() + { + var builder = new ConnectionStringParser("Key1=Value1;;;Key2;"); + + Assert.Single(builder.ParsedKeyValues); + Assert.Contains(builder.ParsedKeyValues, kvp => kvp.Key == "Key1" && kvp.Value == "Value1"); + } + + [Fact] + public void LastOneWinsInConnectionStringTest() + { + var builder = new ConnectionStringParser("Key1=Value1;Key1=Value2;"); + + Assert.Single(builder.ParsedKeyValues); + Assert.Contains(builder.ParsedKeyValues, kvp => kvp.Key == "Key1" && kvp.Value == "Value2"); + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs index 08a61d6bbd..6f9d4bac94 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs @@ -25,27 +25,46 @@ public class OneCollectorOpenTelemetryLoggerOptionsExtensionsTests [Fact] public void InstrumentationKeyAndTenantTokenValidationTest() { - Assert.Throws(() => { using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(builder => { - builder.AddOneCollectorExporter(options => { }); + builder.AddOneCollectorExporter("InstrumentationKey=token-extrainformation"); + })); + } + + { + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter(configure => configure.SetConnectionString("InstrumentationKey=token-extrainformation")); + })); + } + + Assert.Throws(() => + { + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter(configure => { }); })); }); - using var loggerFactory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(builder => - { - builder.AddOneCollectorExporter("token-extrainformation"); - })); + Assert.Throws(() => + { + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter("InstrumentationKey=invalidinstrumentationkey"); + })); + }); - Assert.Throws(() => + Assert.Throws(() => { using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(builder => { - builder.AddOneCollectorExporter("invalidinstrumentationkey"); + builder.AddOneCollectorExporter("UnknownKey=invalidinstrumentationkey"); })); }); } From e280873085ea96712cc636f00941c0e7acef7f3e Mon Sep 17 00:00:00 2001 From: Fernando Nunes Date: Fri, 24 Feb 2023 19:27:10 +0000 Subject: [PATCH 0585/1499] Enable Nulls on Contrib.Extensions.AWSXRay & Test Projects (#920) --- .../.publicApi/net452/PublicAPI.Shipped.txt | 19 +++++++------ .../.publicApi/net452/PublicAPI.Unshipped.txt | 1 + .../netstandard2.0/PublicAPI.Shipped.txt | 25 +++++++++-------- .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + .../AWSXRayIdGenerator.cs | 2 +- ...elemetry.Contrib.Extensions.AWSXRay.csproj | 3 +- .../Resources/AWSEBSResourceDetector.cs | 24 ++++++++-------- .../Resources/AWSEC2ResourceDetector.cs | 28 +++++++++---------- .../Resources/AWSECSResourceDetector.cs | 18 ++++++------ .../Resources/AWSEKSResourceDetector.cs | 28 +++++++++---------- .../Resources/AWSLambdaResourceDetector.cs | 18 ++++++------ .../Resources/Http/Handler.cs | 9 ++++-- .../ServerCertificateValidationProvider.cs | 22 ++++++++++----- .../Resources/IResourceDetector.cs | 2 +- .../Resources/Models/AWSEBSMetadataModel.cs | 6 ++-- .../Models/AWSEC2IdentityDocumentModel.cs | 10 +++---- .../Models/AWSEKSClusterDataModel.cs | 2 +- .../Models/AWSEKSClusterInformationModel.cs | 2 +- .../Resources/ResourceDetectorUtils.cs | 8 +++--- ...ry.Contrib.Extensions.AWSXRay.Tests.csproj | 1 + ...TestServerCertificateValidationProvider.cs | 2 ++ .../Resources/TestAWSEBSResourceDetector.cs | 7 +++-- .../Resources/TestAWSEC2ResourceDetector.cs | 7 +++-- .../Resources/TestAWSECSResourceDetector.cs | 6 ++-- .../Resources/TestAWSEKSResourceDetector.cs | 8 ++++-- .../TestAWSXRayIdGenerator.cs | 4 +-- 26 files changed, 144 insertions(+), 119 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt index 1f0221c530..c9c69207b1 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt @@ -1,21 +1,22 @@ +#nullable enable OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void OpenTelemetry.Resources.ResourceBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void -static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder builder, OpenTelemetry.Trace.Sampler sampler) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder! resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector! resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 29e1279fc9..0c8b8d923f 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1,30 +1,31 @@ +#nullable enable OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.AWSECSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.AWSLambdaResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void OpenTelemetry.Resources.ResourceBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func> getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action setter) -> void -static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder builder, OpenTelemetry.Trace.Sampler sampler) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder! resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector! resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs index a84843e169..32380686f6 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs @@ -39,7 +39,7 @@ public static class AWSXRayIdGenerator private static readonly Random Global = new Random(); private static object randLock = new object(); - internal static void ReplaceTraceId(Sampler sampler = null) + internal static void ReplaceTraceId(Sampler? sampler = null) { var awsXRayActivityListener = new ActivityListener { diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 9f5a91f4e3..e70b11a93c 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -1,9 +1,10 @@ - + netstandard2.0;net452 OpenTelemetry extensions for AWS X-Ray. Extensions.AWSXRay- + enable diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs index 0b3ffe119a..141464c14e 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs @@ -35,13 +35,13 @@ public class AWSEBSResourceDetector : IResourceDetector /// Detector the required and optional resource attributes from AWS ElasticBeanstalk. /// /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + public IEnumerable>? Detect() { - List> resourceAttributes = null; + List>? resourceAttributes = null; try { - string filePath = null; + string? filePath = null; #if NETSTANDARD if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -67,22 +67,22 @@ public IEnumerable> Detect() return resourceAttributes; } - internal List> ExtractResourceAttributes(AWSEBSMetadataModel metadata) + internal List>? ExtractResourceAttributes(AWSEBSMetadataModel? metadata) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceNamespace, metadata.EnvironmentName), - new KeyValuePair(AWSSemanticConventions.AttributeServiceInstanceID, metadata.DeploymentId), - new KeyValuePair(AWSSemanticConventions.AttributeServiceVersion, metadata.VersionLabel), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), + new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), + new KeyValuePair(AWSSemanticConventions.AttributeServiceNamespace, metadata?.EnvironmentName), + new KeyValuePair(AWSSemanticConventions.AttributeServiceInstanceID, metadata?.DeploymentId), + new KeyValuePair(AWSSemanticConventions.AttributeServiceVersion, metadata?.VersionLabel), }; return resourceAttributes; } - internal AWSEBSMetadataModel GetEBSMetadata(string filePath) + internal AWSEBSMetadataModel? GetEBSMetadata(string filePath) { return ResourceDetectorUtils.DeserializeFromFile(filePath); } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs index 6c6acf5ae0..b6c5908929 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs @@ -35,9 +35,9 @@ public class AWSEC2ResourceDetector : IResourceDetector /// Detector the required and optional resource attributes from AWS EC2. /// /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + public IEnumerable>? Detect() { - List> resourceAttributes = null; + List>? resourceAttributes = null; try { @@ -55,24 +55,24 @@ public IEnumerable> Detect() return resourceAttributes; } - internal List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel identity, string hostName) + internal List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel? identity, string hostName) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, identity.AccountId), - new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity.AvailabilityZone), - new KeyValuePair(AWSSemanticConventions.AttributeHostID, identity.InstanceId), - new KeyValuePair(AWSSemanticConventions.AttributeHostType, identity.InstanceType), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, identity.Region), - new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, identity?.AccountId), + new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity?.AvailabilityZone), + new KeyValuePair(AWSSemanticConventions.AttributeHostID, identity?.InstanceId), + new KeyValuePair(AWSSemanticConventions.AttributeHostType, identity?.InstanceType), + new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, identity?.Region), + new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), }; return resourceAttributes; } - internal AWSEC2IdentityDocumentModel DeserializeResponse(string response) + internal AWSEC2IdentityDocumentModel? DeserializeResponse(string response) { return ResourceDetectorUtils.DeserializeFromString(response); } @@ -82,7 +82,7 @@ private string GetAWSEC2Token() return ResourceDetectorUtils.SendOutRequest(AWSEC2MetadataTokenUrl, "PUT", new KeyValuePair(AWSEC2MetadataTokenTTLHeader, "60")).Result; } - private AWSEC2IdentityDocumentModel GetAWSEC2Identity(string token) + private AWSEC2IdentityDocumentModel? GetAWSEC2Identity(string token) { var identity = this.GetIdentityResponse(token); var identityDocument = this.DeserializeResponse(identity); diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index fc25011d7d..9331685a8e 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -32,9 +32,9 @@ public class AWSECSResourceDetector : IResourceDetector /// Detector the required and optional resource attributes from AWS ECS. /// /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + public IEnumerable>? Detect() { - List> resourceAttributes = null; + List>? resourceAttributes = null; if (!this.IsECSProcess()) { @@ -55,21 +55,21 @@ public IEnumerable> Detect() return resourceAttributes; } - internal List> ExtractResourceAttributes(string containerId) + internal List> ExtractResourceAttributes(string? containerId) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), - new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), + new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId), }; return resourceAttributes; } - internal string GetECSContainerId(string path) + internal string? GetECSContainerId(string path) { - string containerId = null; + string? containerId = null; using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) { diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index a58fd0ee60..51c83c24be 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -38,7 +38,7 @@ public class AWSEKSResourceDetector : IResourceDetector /// Detector the required and optional resource attributes from AWS EKS. /// /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + public IEnumerable>? Detect() { var credentials = this.GetEKSCredentials(AWSEKSCredentialPath); var httpClientHandler = Handler.Create(AWSEKSCertificatePath); @@ -53,28 +53,28 @@ public IEnumerable> Detect() this.GetEKSContainerId(AWSEKSMetadataFilePath)); } - internal List> ExtractResourceAttributes(string clusterName, string containerId) + internal List> ExtractResourceAttributes(string? clusterName, string? containerId) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), }; if (!string.IsNullOrEmpty(clusterName)) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName)); } if (!string.IsNullOrEmpty(containerId)) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); } return resourceAttributes; } - internal string GetEKSCredentials(string path) + internal string? GetEKSCredentials(string path) { try { @@ -98,7 +98,7 @@ internal string GetEKSCredentials(string path) return null; } - internal string GetEKSContainerId(string path) + internal string? GetEKSContainerId(string path) { try { @@ -122,12 +122,12 @@ internal string GetEKSContainerId(string path) return null; } - internal AWSEKSClusterInformationModel DeserializeResponse(string response) + internal AWSEKSClusterInformationModel? DeserializeResponse(string response) { return ResourceDetectorUtils.DeserializeFromString(response); } - private string GetEKSClusterName(string credentials, HttpClientHandler httpClientHandler) + private string? GetEKSClusterName(string credentials, HttpClientHandler? httpClientHandler) { try { @@ -142,9 +142,9 @@ private string GetEKSClusterName(string credentials, HttpClientHandler httpClien return null; } - private bool IsEKSProcess(string credentials, HttpClientHandler httpClientHandler) + private bool IsEKSProcess(string credentials, HttpClientHandler? httpClientHandler) { - string awsAuth = null; + string? awsAuth = null; try { awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; @@ -157,7 +157,7 @@ private bool IsEKSProcess(string credentials, HttpClientHandler httpClientHandle return !string.IsNullOrEmpty(awsAuth); } - private string GetEKSClusterInfo(string credentials, HttpClientHandler httpClientHandler) + private string GetEKSClusterInfo(string credentials, HttpClientHandler? httpClientHandler) { return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs index 9fd80e3552..ec163976b7 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs @@ -32,9 +32,9 @@ public class AWSLambdaResourceDetector : IResourceDetector /// Detector the required and optional resource attributes from AWS Lambda. /// /// List of key-value pairs of resource attributes. - public IEnumerable> Detect() + public IEnumerable>? Detect() { - List> resourceAttributes = null; + List>? resourceAttributes = null; try { @@ -48,15 +48,15 @@ public IEnumerable> Detect() return resourceAttributes; } - internal List> ExtractResourceAttributes() + internal List> ExtractResourceAttributes() { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), + new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), + new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), }; return resourceAttributes; diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs index f3ef7ae450..5ee545e2dd 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs @@ -21,19 +21,24 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; internal class Handler { - public static HttpClientHandler Create(string certificateFile) + public static HttpClientHandler? Create(string certificateFile) { try { ServerCertificateValidationProvider serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile); - if (!serverCertificateValidationProvider.IsCertificateLoaded) + if (!serverCertificateValidationProvider.IsCertificateLoaded ?? false) { AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); return null; } + if (serverCertificateValidationProvider.ValidationCallback == null) + { + return null; + } + var clientHandler = new HttpClientHandler(); clientHandler.ServerCertificateCustomValidationCallback = (sender, x509Certificate2, x509Chain, sslPolicyErrors) => diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs index e37f710894..03d725dbd2 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs @@ -27,9 +27,9 @@ internal class ServerCertificateValidationProvider private static readonly ServerCertificateValidationProvider InvalidProvider = new ServerCertificateValidationProvider(null); - private readonly X509Certificate2Collection trustedCertificates; + private readonly X509Certificate2Collection? trustedCertificates; - private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates) + private ServerCertificateValidationProvider(X509Certificate2Collection? trustedCertificates) { if (trustedCertificates == null) { @@ -45,9 +45,9 @@ private ServerCertificateValidationProvider(X509Certificate2Collection trustedCe this.IsCertificateLoaded = true; } - public bool IsCertificateLoaded { get; } + public bool? IsCertificateLoaded { get; } - public RemoteCertificateValidationCallback ValidationCallback { get; } + public RemoteCertificateValidationCallback? ValidationCallback { get; } public static ServerCertificateValidationProvider FromCertificateFile(string certificateFile) { @@ -129,9 +129,12 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli } var trustCertificates = string.Empty; - foreach (var trustCertificate in this.trustedCertificates) + if (this.trustedCertificates != null) { - trustCertificates += " " + trustCertificate.Subject; + foreach (var trustCertificate in this.trustedCertificates) + { + trustCertificates += " " + trustCertificate.Subject; + } } AWSXRayEventSource.Log.FailedToValidateCertificate( @@ -142,8 +145,13 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli return isSslPolicyPassed && isValidChain && isTrusted; } - private bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection collection) + private bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection) { + if (collection == null) + { + return false; + } + foreach (var chainElement in chain.ChainElements) { foreach (var certificate in collection) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs index ef262b706b..7ee26bd3af 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs @@ -28,5 +28,5 @@ public interface IResourceDetector /// Called to get key-value pairs of attribute from detector. /// /// List of key-value pairs of resource attributes. - IEnumerable> Detect(); + IEnumerable>? Detect(); } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs index f3acf9d8a0..656fd150c5 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs @@ -21,11 +21,11 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; internal class AWSEBSMetadataModel { [JsonProperty(PropertyName = "deployment_id")] - public string DeploymentId { get; set; } + public string? DeploymentId { get; set; } [JsonProperty(PropertyName = "environment_name")] - public string EnvironmentName { get; set; } + public string? EnvironmentName { get; set; } [JsonProperty(PropertyName = "version_label")] - public string VersionLabel { get; set; } + public string? VersionLabel { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs index 9a9ea20d63..9753ed7af1 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs @@ -18,13 +18,13 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; internal class AWSEC2IdentityDocumentModel { - public string AccountId { get; set; } + public string? AccountId { get; set; } - public string AvailabilityZone { get; set; } + public string? AvailabilityZone { get; set; } - public string Region { get; set; } + public string? Region { get; set; } - public string InstanceId { get; set; } + public string? InstanceId { get; set; } - public string InstanceType { get; set; } + public string? InstanceType { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs index e81fbfd050..3dadd91cf6 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs @@ -21,5 +21,5 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; internal class AWSEKSClusterDataModel { [JsonProperty(PropertyName = "cluster.name")] - public string ClusterName { get; set; } + public string? ClusterName { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs index 78eed916ba..d6193e47ab 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs @@ -18,5 +18,5 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; internal class AWSEKSClusterInformationModel { - public AWSEKSClusterDataModel Data { get; set; } + public AWSEKSClusterDataModel? Data { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs index b0a525424c..74509c9cad 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs @@ -29,7 +29,7 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; /// public class ResourceDetectorUtils { - internal static async Task SendOutRequest(string url, string method, KeyValuePair header, HttpClientHandler handler = null) + internal static async Task SendOutRequest(string url, string method, KeyValuePair header, HttpClientHandler? handler = null) { using (var httpRequestMessage = new HttpRequestMessage()) { @@ -46,16 +46,16 @@ internal static async Task SendOutRequest(string url, string method, Key } } - internal static T DeserializeFromFile(string filePath) + internal static T? DeserializeFromFile(string filePath) { using (var streamReader = GetStreamReader(filePath)) { JsonSerializer serializer = new JsonSerializer(); - return (T)serializer.Deserialize(streamReader, typeof(T)); + return (T?)serializer.Deserialize(streamReader, typeof(T)); } } - internal static T DeserializeFromString(string json) + internal static T? DeserializeFromString(string json) { return JsonConvert.DeserializeObject(json); } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index 0e4cc8e110..a666403913 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -5,6 +5,7 @@ netcoreapp3.1 $(TargetFrameworks);net452 + enable diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs index 4f99057056..baa289b2db 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs @@ -47,6 +47,8 @@ public void TestValidCertificate() chain.Build(certificate); // validates if certificate is valid + Assert.NotNull(serverCertificateValidationProvider); + Assert.NotNull(serverCertificateValidationProvider.ValidationCallback); Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs index 5aad80cc3b..1b3df6c3e8 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System.Collections.Generic; using System.Linq; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; @@ -28,9 +27,10 @@ public class TestAWSEBSResourceDetector [Fact] public void TestDetect() { - IEnumerable> resourceAttributes; var ebsResourceDetector = new AWSEBSResourceDetector(); - resourceAttributes = ebsResourceDetector.Detect(); + + var resourceAttributes = ebsResourceDetector.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in ebs environment } @@ -56,6 +56,7 @@ public void TestGetEBSMetadata() var ebsResourceDetector = new AWSEBSResourceDetector(); var ebsMetadata = ebsResourceDetector.GetEBSMetadata(AWSEBSMetadataFilePath); + Assert.NotNull(ebsMetadata); Assert.Equal("1234567890", ebsMetadata.DeploymentId); Assert.Equal("Test AWS Elastic Beanstalk Environment Name", ebsMetadata.EnvironmentName); Assert.Equal("Test Version", ebsMetadata.VersionLabel); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs index 424ee1bb32..8fff5c438c 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System.Collections.Generic; using System.Linq; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; @@ -26,9 +25,10 @@ public class TestAWSEC2ResourceDetector [Fact] public void TestDetect() { - IEnumerable> resourceAttributes; var ec2ResourceDetector = new AWSEC2ResourceDetector(); - resourceAttributes = ec2ResourceDetector.Detect(); + + var resourceAttributes = ec2ResourceDetector.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in ec2 environment } @@ -59,6 +59,7 @@ public void TestDeserializeResponse() var ec2IdentityDocumentModel = ec2ResourceDetector.DeserializeResponse(ec2IdentityDocument); + Assert.NotNull(ec2IdentityDocumentModel); Assert.Equal("123456789012", ec2IdentityDocumentModel.AccountId); Assert.Equal("us-east-1a", ec2IdentityDocumentModel.AvailabilityZone); Assert.Equal("i-12345678901234567", ec2IdentityDocumentModel.InstanceId); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs index 3f6739960f..73223bb2a7 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs @@ -15,7 +15,6 @@ // using System; -using System.Collections.Generic; using System.Linq; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; @@ -31,9 +30,10 @@ public class TestAWSECSResourceDetector [Fact] public void TestDetect() { - IEnumerable> resourceAttributes; var ecsResourceDetector = new AWSECSResourceDetector(); - resourceAttributes = ecsResourceDetector.Detect(); + + var resourceAttributes = ecsResourceDetector?.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in ecs environment } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index 99c6b14717..d7689835be 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System.Collections.Generic; using System.Linq; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; @@ -29,9 +28,10 @@ public class TestAWSEKSResourceDetector [Fact] public void TestDetect() { - IEnumerable> resourceAttributes; var eksResourceDetector = new AWSEKSResourceDetector(); - resourceAttributes = eksResourceDetector.Detect(); + + var resourceAttributes = eksResourceDetector?.Detect(); + Assert.Null(resourceAttributes); // will be null as it's not in eks environment } @@ -107,6 +107,8 @@ public void TestDeserializeResponse() var eksResourceDetector = new AWSEKSResourceDetector(); var eksClusterInformation = eksResourceDetector.DeserializeResponse(awsEKSClusterInformation); + Assert.NotNull(eksClusterInformation); + Assert.NotNull(eksClusterInformation.Data); Assert.Equal("Test", eksClusterInformation.Data.ClusterName); } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs index d781ce40d6..ff779da30d 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs @@ -91,7 +91,7 @@ public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSam { using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) { - Assert.True(activity.ActivityTraceFlags == ActivityTraceFlags.Recorded); + Assert.True(activity?.ActivityTraceFlags == ActivityTraceFlags.Recorded); } } } @@ -110,7 +110,7 @@ public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSam { using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) { - Assert.True(activity.ActivityTraceFlags == ActivityTraceFlags.None); + Assert.True(activity?.ActivityTraceFlags == ActivityTraceFlags.None); } } } From 1c7fd9afa4d2f0d68f879b4c69a631725a94c577 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Sat, 25 Feb 2023 06:52:17 -0800 Subject: [PATCH 0586/1499] Remove shared code using `DynamicMethod` (#1041) --- build/Common.props | 3 - .../Api/ActivityHelperExtensions.cs | 108 ----------- .../Api/EnumerationHelper.cs | 179 ------------------ .../Api/IActivityEnumerator.cs | 33 ---- .../OpenTelemetry.Contrib.Shared.csproj | 3 +- ...Telemetry.Instrumentation.MySqlData.csproj | 3 - .../ActivityHelperExtensions.cs | 37 ++++ .../AWSLambdaWrapperTests.cs | 1 + ...try.Instrumentation.AWSLambda.Tests.csproj | 4 + ...emetry.Instrumentation.AspNet.Tests.csproj | 4 +- ...mentation.ElasticsearchClient.Tests.csproj | 6 +- ...try.Instrumentation.MySqlData.Tests.csproj | 6 +- ...isProfilerEntryToActivityConverterTests.cs | 1 + ...umentation.StackExchangeRedis.Tests.csproj | 1 + 14 files changed, 56 insertions(+), 333 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs delete mode 100644 src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs delete mode 100644 src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs diff --git a/build/Common.props b/build/Common.props index 469e35cdbe..1e7bfad803 100644 --- a/build/Common.props +++ b/build/Common.props @@ -57,10 +57,7 @@ - - - diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs deleted file mode 100644 index 7e49b4d713..0000000000 --- a/src/OpenTelemetry.Contrib.Shared/Api/ActivityHelperExtensions.cs +++ /dev/null @@ -1,108 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Runtime.CompilerServices; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Trace; - -/// -/// Extension methods on Activity. -/// -internal static class ActivityHelperExtensions -{ - /// - /// Gets the value of a specific tag on an . - /// - /// Activity instance. - /// Case-sensitive tag name to retrieve. - /// Tag value or null if a match was not found. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "ActivityProcessor is hot path")] - public static object GetTagValue(this Activity activity, string tagName) - { - Debug.Assert(activity != null, "Activity should not be null"); - - // TODO: Update to use - // https://docs.microsoft.com/dotnet/api/system.diagnostics.activity.enumeratetagobjects?view=net-7.0 - // instead of reflection. See: - // https://github.com/open-telemetry/opentelemetry-dotnet/blob/928d77056c1d353d8ba72ad3b4b565398117b352/src/OpenTelemetry.Api/Internal/ActivityHelperExtensions.cs#L85-L98 - - ActivitySingleTagEnumerator state = new ActivitySingleTagEnumerator(tagName); - - ActivityTagsEnumeratorFactory.Enumerate(activity, ref state); - - return state.Value; - } - - private struct ActivitySingleTagEnumerator : IActivityEnumerator> - { - public object Value; - - private readonly string tagName; - - public ActivitySingleTagEnumerator(string tagName) - { - this.tagName = tagName; - this.Value = null; - } - - public bool ForEach(KeyValuePair item) - { - if (item.Key == this.tagName) - { - this.Value = item.Value; - return false; - } - - return true; - } - } - - private static class ActivityTagsEnumeratorFactory - where TState : struct, IActivityEnumerator> - { - private static readonly object EmptyActivityTagObjects = typeof(Activity).GetField("s_emptyTagObjects", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); - - private static readonly DictionaryEnumerator.AllocationFreeForEachDelegate - ActivityTagObjectsEnumerator = DictionaryEnumerator.BuildAllocationFreeForEachDelegate( - typeof(Activity).GetField("_tags", BindingFlags.Instance | BindingFlags.NonPublic).FieldType); - - private static readonly DictionaryEnumerator.ForEachDelegate ForEachTagValueCallbackRef = ForEachTagValueCallback; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Enumerate(Activity activity, ref TState state) - { - var tagObjects = activity.TagObjects; - - if (ReferenceEquals(tagObjects, EmptyActivityTagObjects)) - { - return; - } - - ActivityTagObjectsEnumerator( - tagObjects, - ref state, - ForEachTagValueCallbackRef); - } - - private static bool ForEachTagValueCallback(ref TState state, KeyValuePair item) - => state.ForEach(item); - } -} diff --git a/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs deleted file mode 100644 index dbae60c27d..0000000000 --- a/src/OpenTelemetry.Contrib.Shared/Api/EnumerationHelper.cs +++ /dev/null @@ -1,179 +0,0 @@ -// -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; - -namespace OpenTelemetry.Internal; - -internal class DictionaryEnumerator : Enumerator ->, - KeyValuePair, - TState> - where TState : struct -{ - protected DictionaryEnumerator() - { - } -} - -internal class ListEnumerator : Enumerator -, - TValue, - TState> - where TState : struct -{ - protected ListEnumerator() - { - } -} - -// A helper class for enumerating over IEnumerable without allocation if a struct enumerator is available. -internal class Enumerator - where TEnumerable : IEnumerable - where TState : struct -{ - private static readonly MethodInfo GenericGetEnumeratorMethod = typeof(IEnumerable).GetMethod("GetEnumerator"); - private static readonly MethodInfo GeneircCurrentGetMethod = typeof(IEnumerator).GetProperty("Current").GetMethod; - private static readonly MethodInfo MoveNextMethod = typeof(IEnumerator).GetMethod("MoveNext"); - private static readonly MethodInfo DisposeMethod = typeof(IDisposable).GetMethod("Dispose"); - - public delegate void AllocationFreeForEachDelegate(TEnumerable instance, ref TState state, ForEachDelegate itemCallback); - - public delegate bool ForEachDelegate(ref TState state, TItem item); - - protected Enumerator() - { - } - - /* We want to do this type of logic... - public static void AllocationFreeForEach(Dictionary dictionary, ref TState state, ForEachDelegate itemCallback) - { - using (Dictionary.Enumerator enumerator = dictionary.GetEnumerator()) - { - while (enumerator.MoveNext()) - { - if (!itemCallback(ref state, enumerator.Current)) - break; - } - } - } - ...because it takes advantage of the struct Enumerator on the built-in types which give an allocation-free way to enumerate. - */ - public static AllocationFreeForEachDelegate BuildAllocationFreeForEachDelegate(Type enumerableType) - { - var itemCallbackType = typeof(ForEachDelegate); - - var getEnumeratorMethod = ResolveGetEnumeratorMethodForType(enumerableType); - if (getEnumeratorMethod == null) - { - // Fallback to allocation mode and use IEnumerable.GetEnumerator. - // Primarily for Array.Empty and Enumerable.Empty case, but also for user types. - getEnumeratorMethod = GenericGetEnumeratorMethod; - } - - var enumeratorType = getEnumeratorMethod.ReturnType; - - var dynamicMethod = new DynamicMethod( - nameof(AllocationFreeForEachDelegate), - null, - new[] { typeof(TEnumerable), typeof(TState).MakeByRefType(), itemCallbackType }, - typeof(AllocationFreeForEachDelegate).Module, - skipVisibility: true); - - var generator = dynamicMethod.GetILGenerator(); - - generator.DeclareLocal(enumeratorType); - - var beginLoopLabel = generator.DefineLabel(); - var processCurrentLabel = generator.DefineLabel(); - var returnLabel = generator.DefineLabel(); - var breakLoopLabel = generator.DefineLabel(); - - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Callvirt, getEnumeratorMethod); - generator.Emit(OpCodes.Stloc_0); - - // try - generator.BeginExceptionBlock(); - { - generator.Emit(OpCodes.Br_S, beginLoopLabel); - - generator.MarkLabel(processCurrentLabel); - - generator.Emit(OpCodes.Ldarg_2); - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Ldloca_S, 0); - generator.Emit(OpCodes.Constrained, enumeratorType); - generator.Emit(OpCodes.Callvirt, GeneircCurrentGetMethod); - - generator.Emit(OpCodes.Callvirt, itemCallbackType.GetMethod("Invoke")); - - generator.Emit(OpCodes.Brtrue_S, beginLoopLabel); - - generator.Emit(OpCodes.Leave_S, returnLabel); - - generator.MarkLabel(beginLoopLabel); - - generator.Emit(OpCodes.Ldloca_S, 0); - generator.Emit(OpCodes.Constrained, enumeratorType); - generator.Emit(OpCodes.Callvirt, MoveNextMethod); - - generator.Emit(OpCodes.Brtrue_S, processCurrentLabel); - - generator.MarkLabel(breakLoopLabel); - - generator.Emit(OpCodes.Leave_S, returnLabel); - } - - // finally - generator.BeginFinallyBlock(); - { - if (typeof(IDisposable).IsAssignableFrom(enumeratorType)) - { - generator.Emit(OpCodes.Ldloca_S, 0); - generator.Emit(OpCodes.Constrained, enumeratorType); - generator.Emit(OpCodes.Callvirt, DisposeMethod); - } - } - - generator.EndExceptionBlock(); - - generator.MarkLabel(returnLabel); - - generator.Emit(OpCodes.Ret); - - return (AllocationFreeForEachDelegate)dynamicMethod.CreateDelegate(typeof(AllocationFreeForEachDelegate)); - } - - private static MethodInfo ResolveGetEnumeratorMethodForType(Type type) - { - var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - - foreach (var method in methods) - { - if (method.Name == "GetEnumerator" && !method.ReturnType.IsInterface) - { - return method; - } - } - - return null; - } -} diff --git a/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs b/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs deleted file mode 100644 index 3a55f61399..0000000000 --- a/src/OpenTelemetry.Contrib.Shared/Api/IActivityEnumerator.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics; - -namespace OpenTelemetry.Trace; - -/// -/// An interface used to perform zero-allocation enumeration of elements. Implementation must be a struct. -/// -/// Enumerated item type. -internal interface IActivityEnumerator -{ - /// - /// Called for each item while the enumeration is executing. - /// - /// Enumeration item. - /// to continue the enumeration of records or to stop (break) the enumeration. - bool ForEach(T item); -} diff --git a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj index 5bfdb9cac6..adb7aad559 100644 --- a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj +++ b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj @@ -5,8 +5,7 @@ - - + diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index 322698ecec..83b39ef2f4 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -14,9 +14,6 @@ - - - diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs b/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs new file mode 100644 index 0000000000..c4fec75bd4 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Tests; + +internal static class ActivityHelperExtensions +{ + public static object GetTagValue(this Activity activity, string tagName) + { + Debug.Assert(activity != null, "Activity should not be null"); + + foreach (var tag in activity.TagObjects) + { + if (tag.Key == tagName) + { + return tag.Value; + } + } + + return null; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 9d4ace50ce..b05b34c12a 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -22,6 +22,7 @@ using Moq; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Resources; +using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index a98b7b9207..ecc88c9a31 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 1809ae8dbf..92750cb40e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -28,9 +28,7 @@ - - - + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 744c556d99..853bf851a4 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,4 +1,4 @@ - + Unit test project for OpenTelemetry Elasticsearch client instrumentation @@ -23,4 +23,8 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 5e59fbcbe0..e24d8f3916 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -23,4 +23,8 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index f718265990..784f9a528b 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -19,6 +19,7 @@ using System.Net; using System.Net.Sockets; using Moq; +using OpenTelemetry.Tests; using OpenTelemetry.Trace; using StackExchange.Redis; using StackExchange.Redis.Profiling; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 9d0d48e8a8..95b848e959 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -8,6 +8,7 @@ + From 4cafded6d05f33151b8fee1d20430a6057c38058 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 27 Feb 2023 10:01:44 -0800 Subject: [PATCH 0587/1499] [OneCollector] Add issue template (#1046) --- .../comp_exporter_onecollector.md | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_onecollector.md diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_onecollector.md b/.github/ISSUE_TEMPLATE/comp_exporter_onecollector.md new file mode 100644 index 0000000000..a18b837921 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_exporter_onecollector.md @@ -0,0 +1,54 @@ +--- +name: OpenTelemetry.Exporter.OneCollector +about: Issue with OpenTelemetry.Exporter.OneCollector +labels: comp:exporter.onecollector +--- + +# Issue with OpenTelemetry.Exporter.OneCollector + +**What type of request is this?** + +* [ ] Feature Request +* [ ] Bug +* [ ] Question + +## Request Details + +**What are the OpenTelemetry packages and versions you are using?** + +_List [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.4.0`)._ + +**What environment are you using?** + +_Please include the runtime versions (e.g. `net462`, `net48`, `net6.0`, `net7.0` +etc.), OS details (e.g.Windows, Linux, etc.), architecture (e.g. 32bit, 64bit, +etc.), and anything else important (e.g. IIS, container, etc.)._ + +**What is the expected behavior?** + +_Describe what you expected to see._ + +**What is the actual behavior?** + +_Describe what you saw instead._ + +**What are the steps to reproduce the issue?** + +_Describe how to reproduce the issue._ + +If you are reporting a non-obvious bug, please create a self-contained project +and apply the minimum required code to result in the issue you're observing. + +We will close this issue if: + +* The repro project you share with us is too complex. We can't investigate + custom projects please try to keep it to just what is needed to demonstrate + the issue. + +* We can't reproduce the behavior you're reporting. + +## Additional Context + +_Include any other context about the bug or feature request here._ From 3ca2b349589459e099678a68cda19257b30e8244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 27 Feb 2023 20:49:20 +0100 Subject: [PATCH 0588/1499] Bump OTel to 1.4.0 (#1038) --- build/Common.props | 5 ++- examples/AspNet/Examples.AspNet.csproj | 2 +- examples/AspNet/Web.config | 8 ++-- .../Examples.GrpcCore.AspNetCore.csproj | 4 +- .../Examples.GrpcCore.AspNetCore/Startup.cs | 4 +- .../process-instrumentation.csproj | 2 +- .../runtime-instrumentation.csproj | 2 +- .../OpenTelemetry.Contrib.Shared.csproj | 2 +- .../CHANGELOG.md | 3 ++ .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../OpenTelemetry.Exporter.Instana.csproj | 2 +- .../CHANGELOG.md | 3 ++ ...OpenTelemetry.Exporter.OneCollector.csproj | 2 +- .../CHANGELOG.md | 4 +- .../CHANGELOG.md | 4 +- src/OpenTelemetry.Extensions/CHANGELOG.md | 4 +- .../OpenTelemetry.Extensions.csproj | 2 +- .../CHANGELOG.md | 4 +- .../README.md | 2 +- .../CHANGELOG.md | 3 ++ .../CHANGELOG.md | 4 +- .../README.md | 2 +- .../CHANGELOG.md | 4 +- .../CHANGELOG.md | 4 +- ...Telemetry.Instrumentation.MySqlData.csproj | 2 +- .../CHANGELOG.md | 4 +- .../CHANGELOG.md | 3 ++ ...enTelemetry.Instrumentation.Process.csproj | 2 +- .../CHANGELOG.md | 4 +- .../README.md | 2 +- .../CHANGELOG.md | 3 ++ ...enTelemetry.Instrumentation.Runtime.csproj | 2 +- .../CHANGELOG.md | 7 +++- ....Instrumentation.StackExchangeRedis.csproj | 1 + .../CHANGELOG.md | 4 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../AppServiceResourceDetector.cs | 2 +- ...penTelemetry.Exporter.Instana.Tests.csproj | 5 ++- ...elemetry.Exporter.Stackdriver.Tests.csproj | 1 + ...enTelemetry.Extensions.Docker.Tests.csproj | 1 + ...Instrumentation.EventCounters.Tests.csproj | 2 +- ...etry.Instrumentation.Hangfire.Tests.csproj | 3 +- ...try.Instrumentation.MySqlData.Tests.csproj | 41 ++++++++++--------- ...umentation.StackExchangeRedis.Tests.csproj | 3 +- ...kExchangeRedisCallsInstrumentationTests.cs | 7 ++-- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 2 +- .../TelemetryClientMessageInspectorTests.cs | 2 +- 47 files changed, 104 insertions(+), 79 deletions(-) diff --git a/build/Common.props b/build/Common.props index 1e7bfad803..c322c24bcd 100644 --- a/build/Common.props +++ b/build/Common.props @@ -31,11 +31,12 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.3.2,2.0) - [1.4.0-rc.4,2.0) + [1.4.0,2.0) + [1.4.0,2.0) [2.1.58,3.0) [1.2.0-beta.435,2.0) [4.3.4,) + 4.7.0 [6.0.0,) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 4bdaadfa59..9a71f598b7 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -80,7 +80,7 @@ - + diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index bd4f12f8b1..d5496c456d 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -14,9 +14,7 @@ - + @@ -31,7 +29,7 @@ - + @@ -51,7 +49,7 @@ - + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 0f4dde502a..8053b78dba 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index 86657cced5..0f61e44bc6 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -43,8 +43,8 @@ public void ConfigureServices(IServiceCollection services) services.AddControllers(); // Wire in otel - services.AddOpenTelemetryTracing( - (builder) => builder + services.AddOpenTelemetry().WithTracing( + builder => builder .AddAspNetCoreInstrumentation() .AddGrpcCoreInstrumentation() .AddConsoleExporter()); diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj index 3ac8e20efd..727523e7b5 100644 --- a/examples/process-instrumentation/process-instrumentation.csproj +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index 3531e02f48..971a331c3d 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj index adb7aad559..2525d8bf35 100644 --- a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj +++ b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 923cfb709d..770cf13c49 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + ## 1.4.0-rc.4 Released 2023-Feb-13 diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 41c3ddcc7b..d095eef969 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 1106dbce56..9921d0470a 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 581cc97f28..16a028098e 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + * Tenant token is no longer exposed on `OneCollectorExporterOptions` and will be set automatically from the instrumentation key. Added new registration overloads and a builder to help with configuration. diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index a156a0eac1..bb4ac8d267 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 84435083d1..1e420b07aa 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel SDK version to `1.3.2`. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OTel SDK version to `1.4.0`. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md index 803906ee89..65b8ae1498 100644 --- a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.3.2 of OpenTelemetry SDK. -[917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917) +* Updates to 1.4.0 of OpenTelemetry SDK. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-beta.2 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index eef4594df2..d9def289e6 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog -* Update OpenTelemetry to 1.4.0-rc.4 - ([#990](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/990)) +* Update OpenTelemetry to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## Unreleased diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 13eecc4e34..8462a7674f 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index fad78ef43c..c8add8c51b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update `OpenTelemetry.Api` to `1.3.2`. -([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update `OpenTelemetry.Api` to `1.4.0`. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-rc9.7 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 7037108954..1c5734e509 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -20,7 +20,7 @@ ASP.NET Core instrumentation example: ```csharp // Add OpenTelemetry and Elasticsearch client instrumentation -services.AddOpenTelemetryTracing(x => +services.AddOpenTelemetry().WithTracing(x => { x.AddElasticsearchClientInstrumentation(); x.UseJaegerExporter(config => { diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 8ec769c5e2..11860b8c0d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + ## 1.0.0-beta.4 Released 2023-Jan-25 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index e50bf065dd..6df60b7a5b 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.3.2. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OpenTelemetry.Api to 1.4.0. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-alpha.2 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md index 5c629b815c..73be2ba56d 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -27,7 +27,7 @@ ASP.NET Core instrumentation example: ```csharp // Add OpenTelemetry and gRPC Core instrumentation -services.AddOpenTelemetryTracing(x => +services.AddOpenTelemetry().WithTracing(x => { x.AddGrpcCoreInstrumentation(); ... diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index b44eaa7736..e8caed7660 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel API version to `1.3.2`. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OTel API version to `1.4.0`. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 818fdfdd5e..b73f86123d 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel API version to `1.3.2`. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OTel API version to `1.4.0`. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index 83b39ef2f4..221dec0bd4 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 38e529310c..f9b1a72736 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OpenTelemetry SDK to 1.3.2 - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Updated OpenTelemetry SDK to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes `AddOwinInstrumentation` method with default configure parameter. ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index bfc8e1d554..6922e8e798 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + ## 0.5.0-beta.1 Released 2023-Feb-17 diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index 265bccf4c0..4f7202a8f8 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 8720298814..23cc7aec70 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.3.2. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OpenTelemetry.Api to 1.4.0. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes .NET Framework 4.7.2. It is distributed as .NET Standard 2.0. ([#911](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/911)) * Removes `AddQuartzInstrumentation` method with default configure default parameter. diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index da549407b2..0e7edb1e2d 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -42,7 +42,7 @@ public void ConfigureServices(IServiceCollection services) } // Add OpenTelemetry and Quartz instrumentation -services.AddOpenTelemetryTracing(x => +services.AddOpenTelemetry().WithTracing(x => { x.AddQuartzInstrumentation(); x.UseJaegerExporter(config => { diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 7e79d03ad0..12fd47ab46 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + ## 1.1.0-rc.1 Released 2023-Feb-13 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 2f79c511f8..dc81b9be78 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 9a80c8054b..a9c10eef1e 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased -* Update OTel API version to `1.3.2`. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OTel API version to `1.4.0`. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Added a direct dependency on System.Reflection.Emit.Lightweight which + previously came transitively through the OpenTelemetry API. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-rc9.7 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index f71bb62aff..c12e750ae0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -17,6 +17,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 6bfb00c834..61296f7556 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel SDK version to `1.3.2`. - ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) +* Update OTel SDK version to `1.4.0`. + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes `AddWcfInstrumentation` method with default configure parameter. ([#928](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/928)) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 6388753f6e..e3dbfb40fc 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,3 @@ OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource? \ No newline at end of file +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index 3ab8352c10..88f5597e4f 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -27,7 +27,7 @@ namespace OpenTelemetry.ResourceDetectors.Azure; public sealed class AppServiceResourceDetector : IResourceDetector { /// - public Resource? Detect() + public Resource Detect() { List>? attributeList = null; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index a08c3fc4e3..145a5d743b 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -1,7 +1,8 @@ - + - netcoreapp3.1 + net7.0;net6.0;netcoreapp3.1 + true diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index d934ebd635..eeca559b44 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 + true diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj index b5f979b411..9d76d1a0c2 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -5,6 +5,7 @@ net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 + true diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 6c2b7a8ba7..81177f9a06 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 true diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 666bf9dae1..02ba50abd0 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -2,7 +2,8 @@ Unit test project for OpenTelemetry Hangfire instrumentation - netcoreapp3.1;net472 + net7.0;net6.0;netcoreapp3.1;net472 + true false diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index e24d8f3916..7feadad48a 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -1,27 +1,28 @@ - - netcoreapp3.1 - true - + + net7.0;net6.0;netcoreapp3.1 + true + true + - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 95b848e959..8e05b89b1d 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0;netcoreapp3.1 $(TargetFrameworks);net462 + true $(TARGET_FRAMEWORK) @@ -20,7 +21,7 @@ - + all diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 1066317736..0539a93d4e 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -307,11 +307,12 @@ public void StackExchangeRedis_BadArgs() Assert.Throws(() => builder.AddRedisInstrumentation(null)); var activityProcessor = new Mock>(); - Assert.Throws(() => + var exception = Assert.Throws(() => Sdk.CreateTracerProviderBuilder() .AddProcessor(activityProcessor.Object) .AddRedisInstrumentation(null) .Build()); + Assert.Equal("StackExchange.Redis IConnectionMultiplexer could not be resolved through application IServiceProvider", exception.Message); } [Fact] @@ -336,7 +337,7 @@ public void StackExchangeRedis_DependencyInjection_Success() { optionsPickedFromDI = true; }); - services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); + services.AddOpenTelemetry().WithTracing(builder => builder.AddRedisInstrumentation()); using var serviceProvider = services.BuildServiceProvider(); @@ -351,7 +352,7 @@ public void StackExchangeRedis_DependencyInjection_Failure() { var services = new ServiceCollection(); - services.AddOpenTelemetryTracing(builder => builder.AddRedisInstrumentation()); + services.AddOpenTelemetry().WithTracing(builder => builder.AddRedisInstrumentation()); using var serviceProvider = services.BuildServiceProvider(); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index b7f42bf70f..dbf214f264 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs index 88c6a3b85d..555e1c2623 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs @@ -153,7 +153,7 @@ public async Task OutgoingRequestInstrumentationTest( bool emptyOrNullAction = false) { #if NETFRAMEWORK - const string OutgoingHttpOperationName = "OpenTelemetry.HttpWebRequest.HttpRequestOut"; + const string OutgoingHttpOperationName = "OpenTelemetry.Instrumentation.Http.HttpWebRequest.HttpRequestOut"; #else const string OutgoingHttpOperationName = "System.Net.Http.HttpRequestOut"; #endif From bf09ab944f4218a9c7ea1bd26814a4bdfcc8cc10 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 27 Feb 2023 20:04:34 +0000 Subject: [PATCH 0589/1499] [Exporter.Instana] Fix analysis warnings (#1043) --- .../Implementation/Transport.cs | 7 +++---- src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs | 7 ++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index 56f6a257ae..5d067e8837 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -30,9 +30,9 @@ internal static class Transport private const int MultiSpanBufferSize = 4096000; private const int MultiSpanBufferLimit = 4070000; private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); - private static readonly byte[] TracesBuffer; - private static bool isConfigured = false; - private static int backendTimeout = 0; + private static readonly byte[] TracesBuffer = new byte[MultiSpanBufferSize]; + private static bool isConfigured; + private static int backendTimeout; private static string configuredEndpoint = string.Empty; private static string configuredAgentKey = string.Empty; private static string bundleUrl = string.Empty; @@ -40,7 +40,6 @@ internal static class Transport static Transport() { - TracesBuffer = new byte[MultiSpanBufferSize]; Configure(); } diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index 917604d0f3..ca3583ea26 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -25,18 +25,15 @@ namespace OpenTelemetry.Exporter.Instana; -internal class InstanaExporter : BaseExporter +internal sealed class InstanaExporter : BaseExporter { private readonly IActivityProcessor activityProcessor; - private string name; private ISpanSender spanSender = new SpanSender(); private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); private bool shutdownCalled; - public InstanaExporter(string name = "InstanaExporter", IActivityProcessor activityProcessor = null) + public InstanaExporter(IActivityProcessor activityProcessor = null) { - this.name = name; - if (activityProcessor != null) { this.activityProcessor = activityProcessor; From db2a24d507fb3676dfa724cccfae8b9ca2e6708d Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 27 Feb 2023 12:07:27 -0800 Subject: [PATCH 0590/1499] [Instrumentation.Runtime] fix doc (#1030) --- src/OpenTelemetry.Instrumentation.Runtime/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index ecaba50b53..fb95cc1dce 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -28,16 +28,16 @@ Runtime instrumentation should be enabled at application startup using the ```csharp using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddRuntimeInstrumentation() - .AddPrometheusExporter() + .AddPrometheusHttpListener() .Build(); ``` Refer to [Program.cs](../../examples/runtime-instrumentation/Program.cs) for a complete demo. -Additionally, this examples sets up the OpenTelemetry Prometheus exporter, which -requires adding the package -[`OpenTelemetry.Exporter.Prometheus`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +Additionally, the above example snippet sets up the OpenTelemetry Prometheus Exporter +HttpListener as well, which requires adding the package +[`OpenTelemetry.Exporter.Prometheus.HttpListener`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) to the application. ## Metrics From 3c17a165f2858b17ad6e8bce296bc52855e5c3af Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 27 Feb 2023 16:17:35 -0800 Subject: [PATCH 0591/1499] [Geneva.Metrics] Add option to disable name validation (#1006) Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 4 ++ .../Internal/ConnectionStringBuilder.cs | 14 +++++ .../Metrics/GenevaMetricExporter.cs | 23 ++++++++ .../GenevaMetricExporterTests.cs | 56 +++++++++++++++++++ 4 files changed, 97 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 770cf13c49..11c85b8402 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,10 @@ * Update OpenTelemetry to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Add `DisableMetricNameValidation` connection string flag for controlling + metric name validation performed by the OpenTelemetry SDK. + ([#1006](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1006)) + ## 1.4.0-rc.4 Released 2023-Feb-13 diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 4ea5dee0b7..d34d91f337 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -230,6 +230,20 @@ public string Namespace set => this._parts[nameof(this.Namespace)] = value; } + public bool DisableMetricNameValidation + { + get + { + if (!this._parts.TryGetValue(nameof(this.DisableMetricNameValidation), out var value)) + { + return false; + } + + return string.Equals(bool.TrueString, value, StringComparison.OrdinalIgnoreCase); + } + set => this._parts[nameof(this.DisableMetricNameValidation)] = value ? bool.TrueString : bool.FalseString; + } + private T ThrowIfNotExists(string name) { if (!this._parts.TryGetValue(name, out var value)) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 97b6b366b8..485982c91c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -17,9 +17,11 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; +using System.Text.RegularExpressions; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -108,6 +110,11 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) { this.fixedPayloadStartIndex = sizeof(BinaryHeader); } + + if (connectionStringBuilder.DisableMetricNameValidation) + { + DisableOpenTelemetrySdkMetricNameValidation(); + } } public override ExportResult Export(in Batch batch) @@ -258,6 +265,22 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + internal static PropertyInfo GetOpenTelemetryInstrumentNameRegexProperty() + { + var meterProviderBuilderSdkType = typeof(Sdk).Assembly.GetType("OpenTelemetry.Metrics.MeterProviderBuilderSdk", throwOnError: false) + ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk type could not be found reflectively."); + + var instrumentNameRegexProperty = meterProviderBuilderSdkType.GetProperty("InstrumentNameRegex", BindingFlags.Public | BindingFlags.Static) + ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk.InstrumentNameRegex property could not be found reflectively."); + + return instrumentNameRegexProperty; + } + + internal static void DisableOpenTelemetrySdkMetricNameValidation() + { + GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, new Regex(".*", RegexOptions.Compiled)); + } + internal unsafe ushort SerializeMetric( MetricEventType eventType, string metricName, diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 6ffbe93a5c..344aae91c6 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -625,6 +625,62 @@ public void SuccessfulExportOnLinux() } } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void DisableMetricNameValidationTest(bool disableMetricNameValidation) + { + var instrumentNameRegexProperty = GenevaMetricExporter.GetOpenTelemetryInstrumentNameRegexProperty(); + var initialInstrumentNameRegexValue = instrumentNameRegexProperty.GetValue(null); + Socket server = null; + try + { + var exportedMetrics = new List(); + + using var meter = new Meter(Guid.NewGuid().ToString()); + + using (var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddGenevaMetricExporter(options => + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + } + else + { + var path = GenerateTempFilePath(); + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + }) + .AddInMemoryExporter(exportedMetrics) + .Build()) + { + var counter = meter.CreateCounter("count/invalid"); + counter.Add(1); + } + + if (disableMetricNameValidation) + { + Assert.Single(exportedMetrics); + } + else + { + Assert.Empty(exportedMetrics); + } + } + finally + { + instrumentNameRegexProperty.SetValue(null, initialInstrumentNameRegexValue); + server?.Dispose(); + } + } + private static string GenerateTempFilePath() { while (true) From 7f153f1a73d273bb44701a1ccaa2f5ea21faea33 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 27 Feb 2023 16:29:43 -0800 Subject: [PATCH 0592/1499] [GenevaExporter] Update CHANGELOG for 1.4.0 release (#1048) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 11c85b8402..bea44b9f2d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0 + +Released 2023-Feb-27 + * Update OpenTelemetry to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) From dcd0f152d60f9488ec9e2c6b772ec57cc7c2d59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 28 Feb 2023 02:12:15 +0100 Subject: [PATCH 0593/1499] Releases based on OTel 1.4.0 (#1047) --- src/OpenTelemetry.Extensions/CHANGELOG.md | 11 ++++++----- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 10 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index d9def289e6..f0c228edd6 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -1,12 +1,13 @@ # Changelog -* Update OpenTelemetry to 1.4.0 - ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) - ## Unreleased -* Update OpenTelemetry to 1.4.0-rc.3 - ([#944](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/944)) +## 1.0.0-beta.4 + +Released 2023-Feb-27 + +* Update OpenTelemetry to 1.4.0 + ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index c8add8c51b..96c4445b19 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.8 + +Released 2023-Feb-27 + * Update `OpenTelemetry.Api` to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index ed61c7622a..12cca59058 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.8 + +Released 2023-Feb-27 + * Removes `AddAspNetInstrumentation` method with default configure parameter. ([#942](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/942)) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 11860b8c0d..4c0248e01a 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2023-Feb-27 + * Updated OTel SDK package version to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index b73f86123d..6e63e17541 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.6 + +Released 2023-Feb-27 + * Update OTel API version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 6922e8e798..490331cba4 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.5.0-beta.2 + +Released 2023-Feb-27 + * Update OpenTelemetry API to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 23cc7aec70..6efa30b017 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.2 + +Released 2023-Feb-27 + * Update OpenTelemetry.Api to 1.4.0. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes .NET Framework 4.7.2. It is distributed as .NET Standard 2.0. diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 12fd47ab46..de8698354f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-rc.2 + +Released 2023-Feb-27 + * Update OpenTelemetry API to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index a9c10eef1e..3f4f5845c2 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.8 + +Released 2023-Feb-27 + * Update OTel API version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Added a direct dependency on System.Reflection.Emit.Lightweight which diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 61296f7556..2a6588a8c4 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.9 + +Released 2023-Feb-27 + * Update OTel SDK version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes `AddWcfInstrumentation` method with default configure parameter. From ae8636741cae3ea2034fdc77aa03a89dd855a52e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 27 Feb 2023 18:46:28 -0800 Subject: [PATCH 0594/1499] [Exporter.Geneva] Update publicAPI files for GenevaExporter (#1049) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 5 +++++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 5 ----- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 5 +++++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 5 ----- .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 5 +++++ .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 5 ----- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt index be1421894a..37648818db 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt @@ -1,4 +1,7 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -7,6 +10,8 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> stri OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt index 62efb0fa1b..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,5 +0,0 @@ -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt index be1421894a..37648818db 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -1,4 +1,7 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -7,6 +10,8 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> stri OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt index 62efb0fa1b..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,5 +0,0 @@ -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index be1421894a..37648818db 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1,4 +1,7 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -7,6 +10,8 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> stri OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 62efb0fa1b..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +0,0 @@ -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void From 7fdb0e3f895fc48ec1741238165afa0dfa5ba947 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 28 Feb 2023 10:24:49 -0800 Subject: [PATCH 0595/1499] [Extensions.PersistentStorage] Remove netcoreapp3.1 from tests (#1052) --- .../OpenTelemetry.Extensions.PersistentStorage.Tests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj index 7a2cb99370..caae49f8bd 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj @@ -1,8 +1,8 @@ - + - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 $(TargetFrameworks);net462 From 3d0e0d4f2876f4abe7127f69ee5428d425dd9158 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 28 Feb 2023 10:48:51 -0800 Subject: [PATCH 0596/1499] [StackExchangeRedis] Remove netcoreapp3.1 from test (#1053) Co-authored-by: Cijo Thomas --- ...enTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 8e05b89b1d..b59e09db8a 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,9 +2,8 @@ Unit test project for OpenTelemetry StackExchangeRedis instrumentation - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 $(TargetFrameworks);net462 - true $(TARGET_FRAMEWORK) From e4582ffece4d43254f34d081aec78dfea83073ac Mon Sep 17 00:00:00 2001 From: Arun Mohan Kumar <43769805+arunmk-ms@users.noreply.github.com> Date: Tue, 28 Feb 2023 16:31:39 -0800 Subject: [PATCH 0597/1499] Handle exception while opening connection from constructor (#935) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 +++++++ .../Transport/UnixDomainSocketDataTransport.cs | 9 ++++++++- .../GenevaTraceExporterTests.cs | 7 +++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index bea44b9f2d..531b8613e4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +* Changed the behavior of Unix domain socket connection at startup. Before this + change, the exporter initialization would throw exception if the target Unix + Domain Socket does not exist. After this change, the exporter initialization + would return success and the exporting background thread will try to + establish the connection. + ([#935](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/935)) + ## 1.4.0 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs index 04628e7a49..0490dcc70b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs @@ -43,7 +43,14 @@ public UnixDomainSocketDataTransport( { this.unixEndpoint = new UnixDomainSocketEndPoint(unixDomainSocketPath); this.timeoutMilliseconds = timeoutMilliseconds; - this.Connect(); + try + { + this.Connect(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("UDS unavailable at startup.", ex); + } } public bool IsEnabled() diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 0a656ee73d..0ca2f0b373 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -359,7 +359,10 @@ public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() options.ConnectionString = "Endpoint=unix:" + path; }) .Build(); - Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + + // GenevaExporter would not throw if it was not able to connect to the UDS socket in ctor. It would + // keep attempting to connect to the socket when sending telemetry. + Assert.True(true, "GenevaTraceExporter should not fail in constructor."); } catch (SocketException ex) { @@ -373,7 +376,7 @@ public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() { ConnectionString = "Endpoint=unix:" + path, }); - Assert.True(false, "Should never reach here. GenevaTraceExporter should fail in constructor."); + Assert.True(true, "GenevaTraceExporter should not fail in constructor."); } catch (SocketException ex) { From 6f657e4750698ef47a72c184a5b5fb8cd591e64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 1 Mar 2023 19:26:53 +0100 Subject: [PATCH 0598/1499] [Exporter.Instana] Bump OTel to 1.4.0 (#1050) Co-authored-by: Utkarsh Umesan Pillai --- .../{net461 => net462}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../CHANGELOG.md | 6 ++++++ .../OpenTelemetry.Exporter.Instana.csproj | 20 ++----------------- src/OpenTelemetry.Exporter.Instana/README.md | 2 +- .../TracerProviderBuilderExtensions.cs | 2 -- ...penTelemetry.Exporter.Instana.Tests.csproj | 4 +++- 7 files changed, 12 insertions(+), 22 deletions(-) rename src/OpenTelemetry.Exporter.Instana/.publicApi/{net461 => net462}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.Instana/.publicApi/{net461 => net462}/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Instana/.publicApi/net461/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 3c164dd737..ecb16daf01 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Update OTel SDK version to `1.4.0`. + ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) +* Drop support for .NET Framework 4.6.1. + The lowest supported version is .NET Framework 4.6.2. + ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) + ## 1.0.3 Released 2023-Feb-21 diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 9921d0470a..8977649b0f 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -2,30 +2,14 @@ - netstandard2.0;net461 + netstandard2.0;net462 Instana Tracing APM Instana .NET Exporter for OpenTelemetry Exporter.Instana- - - 4 - - - - 4 - - - - 4 - - - - 4 - - - + diff --git a/src/OpenTelemetry.Exporter.Instana/README.md b/src/OpenTelemetry.Exporter.Instana/README.md index 379f6df1b8..f9a3afd5af 100644 --- a/src/OpenTelemetry.Exporter.Instana/README.md +++ b/src/OpenTelemetry.Exporter.Instana/README.md @@ -3,7 +3,7 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Instana.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) -The Instana Exporter exports telemetry to Instana backand. +The Instana Exporter exports telemetry to Instana backend. ## Installation diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs index 4b917811f2..a830904a4a 100644 --- a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -37,8 +37,6 @@ public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilde throw new ArgumentNullException(nameof(options)); } -#pragma warning disable CA2000 // Dispose objects before losing scope return options.AddProcessor(new BatchActivityExportProcessor(new InstanaExporter())); -#pragma warning restore CA2000 // Dispose objects before losing scope } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 145a5d743b..c374a737ea 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -1,7 +1,8 @@ - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 + $(TargetFrameworks);net462 true @@ -13,6 +14,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + From a62f1805483192d51190e309c73a99f2f2aeebda Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 1 Mar 2023 13:37:32 -0800 Subject: [PATCH 0599/1499] [Stackdriver] Remove netcoreapp3.1 from tests (#1054) --- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index eeca559b44..52327d652c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -2,9 +2,8 @@ Unit test project for Stackdriver Exporter for OpenTelemetry - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 $(TargetFrameworks);net462 - true From fca4f423cc39e8196f88f23941eac76b69365993 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 1 Mar 2023 13:49:36 -0800 Subject: [PATCH 0600/1499] [MySqlData] Remove netcoreapp3.1 from tests (#1055) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Cijo Thomas --- .../OpenTelemetry.Instrumentation.MySqlData.Tests.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index 7feadad48a..b3cd48bbc9 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -1,8 +1,7 @@ - net7.0;net6.0;netcoreapp3.1 - true + net7.0;net6.0 true From 16d8891abcea4134e0b9f9c238e0c78a35c9e3eb Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 1 Mar 2023 15:37:43 -0800 Subject: [PATCH 0601/1499] [Hangfire] Remove netcoreapp3.1 from tests (#1057) --- .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 02ba50abd0..7588f459c8 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -2,8 +2,8 @@ Unit test project for OpenTelemetry Hangfire instrumentation - net7.0;net6.0;netcoreapp3.1;net472 - true + net7.0;net6.0 + $(TargetFrameworks);net462 false From fd72cac5ff817345dc319e737cc58d695cf19b30 Mon Sep 17 00:00:00 2001 From: Michael Murphy <5879863+mrblonde91@users.noreply.github.com> Date: Thu, 2 Mar 2023 00:59:25 +0000 Subject: [PATCH 0602/1499] Add missing db providers to db.system (#898) --- .../CHANGELOG.md | 4 +++ .../EntityFrameworkDiagnosticListener.cs | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 4c0248e01a..0932c9f920 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -27,6 +27,10 @@ Released 2023-Jan-25 * Added support to `EnrichWithIDbCommand` ([#868](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/868)) +* Map missing dbs to db.system: +`OpenTelemetry.Instrumentation.EntityFrameworkCore` + [#898](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/898) + ## 1.0.0-beta.3 Released 2022-Mar-18 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 6193cb7d94..1740e012c6 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -104,18 +104,47 @@ public override void OnCustom(string name, Activity activity, object payload) activity.AddTag(AttributeDbSystem, "cosmosdb"); break; case "Microsoft.EntityFrameworkCore.Sqlite": + case "Devart.Data.SQLite.EFCore": activity.AddTag(AttributeDbSystem, "sqlite"); break; case "MySql.Data.EntityFrameworkCore": case "Pomelo.EntityFrameworkCore.MySql": + case "Devart.Data.MySql.EFCore": activity.AddTag(AttributeDbSystem, "mysql"); break; case "Npgsql.EntityFrameworkCore.PostgreSQL": + case "Devart.Data.PostgreSql.EFCore": activity.AddTag(AttributeDbSystem, "postgresql"); break; case "Oracle.EntityFrameworkCore": + case "Devart.Data.Oracle.EFCore": activity.AddTag(AttributeDbSystem, "oracle"); break; + case "Microsoft.EntityFrameworkCore.InMemory": + activity.AddTag(AttributeDbSystem, "efcoreinmemory"); + break; + case "FirebirdSql.EntityFrameworkCore.Firebird": + activity.AddTag(AttributeDbSystem, "firebird"); + break; + case "FileContextCore": + activity.AddTag(AttributeDbSystem, "filecontextcore"); + break; + case "EntityFrameworkCore.SqlServerCompact35": + case "EntityFrameworkCore.SqlServerCompact40": + activity.AddTag(AttributeDbSystem, "mssqlcompact"); + break; + case "EntityFrameworkCore.OpenEdge": + activity.AddTag(AttributeDbSystem, "openedge"); + break; + case "EntityFrameworkCore.Jet": + activity.AddTag(AttributeDbSystem, "jet"); + break; + case "Google.Cloud.EntityFrameworkCore.Spanner": + activity.AddTag(AttributeDbSystem, "spanner"); + break; + case "Teradata.EntityFrameworkCore": + activity.AddTag(AttributeDbSystem, "teradata"); + break; default: activity.AddTag(AttributeDbSystem, "other_sql"); activity.AddTag("ef.provider", providerName); From c7d64b5d5cf81db5e038c3138f5b339a27f5e553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 2 Mar 2023 02:26:26 +0100 Subject: [PATCH 0603/1499] [Instrumentation.MySQL] Remove AddMySqlDataInstrumentation with default parameter (#930) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 3 +++ .../TracerProviderBuilderExtensions.cs | 14 +++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 439673d005..dfbbe41dcb 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,4 +7,5 @@ OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.RecordEx OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.get -> bool OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureMySqlDataInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 6e63e17541..03de56197c 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Removes `AddMySqlDataInstrumentation` method with default configure parameter. + ([#930](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/930)) + ## 1.0.0-beta.6 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs index e14edba2ed..111cf5e74e 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs @@ -29,16 +29,24 @@ public static class TracerProviderBuilderExtensions /// Enables SqlClient instrumentation. /// /// being configured. - /// SqlClient configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddMySqlDataInstrumentation(this TracerProviderBuilder builder) => + AddMySqlDataInstrumentation(builder, configure: null); + + /// + /// Enables SqlClient instrumentation. + /// + /// being configured. + /// SqlClient configuration options. /// The instance of to chain the calls. public static TracerProviderBuilder AddMySqlDataInstrumentation( this TracerProviderBuilder builder, - Action configureMySqlDataInstrumentationOptions = null) + Action configure) { Guard.ThrowIfNull(builder); var sqlOptions = new MySqlDataInstrumentationOptions(); - configureMySqlDataInstrumentationOptions?.Invoke(sqlOptions); + configure?.Invoke(sqlOptions); builder.AddInstrumentation(() => new MySqlDataInstrumentation(sqlOptions)); builder.AddSource(MySqlActivitySourceHelper.ActivitySourceName); From 25632df6c79bd7920e10a1293e5f9ad519a073fd Mon Sep 17 00:00:00 2001 From: Fernando Nunes Date: Thu, 2 Mar 2023 20:02:05 +0000 Subject: [PATCH 0604/1499] Enable Nulls on Contrib.Instrumentation.AWS & Test Projects (#926) --- .../.publicApi/net452/PublicAPI.Shipped.txt | 3 +- .../.publicApi/net452/PublicAPI.Unshipped.txt | 1 + .../netstandard2.0/PublicAPI.Shipped.txt | 3 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + .../AWSTracingPipelineHandler.cs | 6 +-- .../Implementation/Utils.cs | 4 +- ...lemetry.Contrib.Instrumentation.AWS.csproj | 3 +- .../TracerProviderBuilderExtensions.cs | 2 +- ...y.Contrib.Instrumentation.AWS.Tests.csproj | 1 + .../Tools/CustomResponses.cs | 20 +++---- .../Tools/CustomWebResponse.cs | 20 +++---- .../Tools/HttpResponseMessageBody.cs | 7 +-- .../Tools/MockHttpRequest.cs | 22 ++++---- .../Tools/MockHttpRequestFactory.cs | 12 ++--- .../Tools/MockWebResponse.cs | 53 +++++++++++-------- .../Tools/Utils.cs | 14 +++-- 16 files changed, 97 insertions(+), 75 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt index cb88907ec0..b9b90d106a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt @@ -1,6 +1,7 @@ +#nullable enable OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index cb88907ec0..3906c385a7 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1,6 +1,7 @@ +#nullable enable OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index bbce612cf6..c10ca0bd7f 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -73,7 +73,7 @@ public override void InvokeSync(IExecutionContext executionContext) public override async Task InvokeAsync(IExecutionContext executionContext) { - T ret = null; + T? ret = null; var activity = this.ProcessBeginRequest(executionContext); try @@ -100,9 +100,9 @@ public override async Task InvokeAsync(IExecutionContext executionContext) return ret; } - private Activity ProcessBeginRequest(IExecutionContext executionContext) + private Activity? ProcessBeginRequest(IExecutionContext executionContext) { - Activity activity = null; + Activity? activity = null; var requestContext = executionContext.RequestContext; var service = AWSServiceHelper.GetAWSServiceName(requestContext); diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs index 6eec23f4fb..ff51298620 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs @@ -21,9 +21,9 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; internal class Utils { - internal static object GetTagValue(Activity activity, string tagName) + internal static object? GetTagValue(Activity activity, string tagName) { - foreach (KeyValuePair tag in activity.TagObjects) + foreach (KeyValuePair tag in activity.TagObjects) { if (tag.Key.Equals(tagName)) { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 1a7b34718c..35155529f5 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -4,7 +4,8 @@ netstandard2.0;net452 AWS client instrumentation for OpenTelemetry .NET - Instrumentation.AWS- + Instrumentation.AWS- + enable diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index 80c0d0efed..526d152eec 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -34,7 +34,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddAWSInstrumentation( this TracerProviderBuilder builder, - Action configure = null) + Action? configure = null) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index e8fa57bb14..b895bfeeb7 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -5,6 +5,7 @@ netcoreapp3.1 $(TargetFrameworks);net452 + enable diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index 31c9f6837d..abf81a2cb5 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -36,7 +36,7 @@ internal static class CustomResponses { #if NET452 public static void SetResponse( - AmazonServiceClient client, string content, string requestId, bool isOK) + AmazonServiceClient client, string? content, string requestId, bool isOK) { var response = Create(content, requestId, isOK); SetResponse(client, response); @@ -44,22 +44,22 @@ public static void SetResponse( public static void SetResponse( AmazonServiceClient client, - Func responseCreator) + Func responseCreator) { var pipeline = client .GetType() - .GetProperty("RuntimePipeline", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic) + .GetProperty("RuntimePipeline", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)? .GetValue(client, null) as RuntimePipeline; var requestFactory = new MockHttpRequestFactory(); requestFactory.ResponseCreator = responseCreator; var httpHandler = new HttpHandler(requestFactory, client); - pipeline.ReplaceHandler>(httpHandler); + pipeline?.ReplaceHandler>(httpHandler); } - private static Func Create( - string content, string requestId, bool isOK) + private static Func Create( + string? content, string requestId, bool isOK) { var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; @@ -82,7 +82,7 @@ private static Func Create( }; } #else - public static void SetResponse(AmazonServiceClient client, string content, string requestId, bool isOK) + public static void SetResponse(AmazonServiceClient client, string? content, string requestId, bool isOK) { var response = Create(content, requestId, isOK); SetResponse(client, response); @@ -92,18 +92,18 @@ public static void SetResponse(AmazonServiceClient client, Func(requestFactory, client); - pipeline.ReplaceHandler>(httpHandler); + pipeline?.ReplaceHandler>(httpHandler); } private static Func Create( - string content, string requestId, bool isOK) + string? content, string requestId, bool isOK) { var status = isOK ? HttpStatusCode.OK : HttpStatusCode.NotFound; diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index 9a19394d84..d1dc94d124 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -27,16 +27,16 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; internal class CustomWebResponse : IWebResponseData { private HttpResponseMessageBody response; - private string[] headerNames; - private Dictionary headers; - private HashSet headerNamesSet; + private string[]? headerNames; + private Dictionary? headers; + private HashSet? headerNamesSet; public CustomWebResponse(HttpResponseMessage response) : this(response, null, false) { } - public CustomWebResponse(HttpResponseMessage responseMsg, HttpClient httpClient, bool disposeClient) + public CustomWebResponse(HttpResponseMessage responseMsg, HttpClient? httpClient, bool disposeClient) { this.response = new HttpResponseMessageBody(responseMsg, httpClient, disposeClient); @@ -50,7 +50,7 @@ public CustomWebResponse(HttpResponseMessage responseMsg, HttpClient httpClient, public bool IsSuccessStatusCode { get; private set; } - public string ContentType { get; private set; } + public string? ContentType { get; private set; } public long ContentLength { get; private set; } @@ -66,8 +66,8 @@ public static IWebResponseData GenerateWebResponse(HttpResponseMessage response) public string GetHeaderValue(string headerName) { - string headerValue; - if (this.headers.TryGetValue(headerName, out headerValue)) + string? headerValue; + if (this.headers != null && this.headers.TryGetValue(headerName, out headerValue)) { return headerValue; } @@ -77,10 +77,10 @@ public string GetHeaderValue(string headerName) public bool IsHeaderPresent(string headerName) { - return this.headerNamesSet.Contains(headerName); + return this.headerNamesSet != null && this.headerNamesSet.Contains(headerName); } - public string[] GetHeaderNames() + public string[]? GetHeaderNames() { return this.headerNames; } @@ -116,7 +116,7 @@ private void CopyHeaderValues(HttpResponseMessage response) private string GetFirstHeaderValue(HttpHeaders headers, string key) { - IEnumerable headerValues = null; + IEnumerable? headerValues = null; if (headers.TryGetValues(key, out headerValues)) { return headerValues.FirstOrDefault(); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index d5b8ee4857..65edbf905b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -24,12 +24,12 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; internal class HttpResponseMessageBody : IHttpResponseBody { - private HttpClient httpClient; + private HttpClient? httpClient; private HttpResponseMessage response; private bool disposeClient = false; private bool disposed = false; - public HttpResponseMessageBody(HttpResponseMessage response, HttpClient httpClient, bool disposeClient) + public HttpResponseMessageBody(HttpResponseMessage response, HttpClient? httpClient, bool disposeClient) { this.httpClient = httpClient; this.response = response; @@ -65,7 +65,8 @@ Task IHttpResponseBody.OpenResponseAsync() } else { - return null; + var ms = new MemoryStream(); + return Task.FromResult(ms); } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index 8264bfe26f..d253897b8b 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -32,9 +32,9 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; #if NET452 internal class MockHttpRequest : IHttpRequest { - private Stream requestStream = null; + private Stream? requestStream = null; - public MockHttpRequest(Uri requestUri, Action action, Func responseCreator = null) + public MockHttpRequest(Uri requestUri, Action? action, Func? responseCreator = null) { this.RequestUri = requestUri; this.GetResponseAction = action; @@ -51,13 +51,13 @@ public MockHttpRequest(Uri requestUri, Action action, Func ResponseCreator { get; set; } + public Func ResponseCreator { get; set; } public void ConfigureRequest(IRequestContext requestContext) { @@ -106,7 +106,7 @@ public Task GetRequestContentAsync() return Task.FromResult(new MemoryStream()); } - public Task GetResponseAsync(System.Threading.CancellationToken cancellationToken) + public Task GetResponseAsync(CancellationToken cancellationToken) { this.GetResponseAction?.Invoke(); @@ -144,7 +144,7 @@ private HttpWebResponse CreateResponse(MockHttpRequest request) var resourceName = request.RequestUri.Host.Split('.').Last(); var response = MockWebResponse.CreateFromResource(resourceName); - if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) + if (response?.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) { return response; } @@ -157,7 +157,7 @@ private HttpWebResponse CreateResponse(MockHttpRequest request) #else internal class MockHttpRequest : IHttpRequest { - public MockHttpRequest(Uri requestUri, Action action, Func responseCreator = null) + public MockHttpRequest(Uri requestUri, Action? action, Func? responseCreator = null) { this.RequestUri = requestUri; this.GetResponseAction = action; @@ -174,11 +174,11 @@ public MockHttpRequest(Uri requestUri, Action action, Func ResponseCreator { get; set; } @@ -206,7 +206,7 @@ public HttpContent GetRequestContent() } catch (AggregateException e) { - throw e.InnerException; + throw e.InnerException ?? e; } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index 69584cc84f..67605511f3 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -27,11 +27,11 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; #if NET452 internal class MockHttpRequestFactory : IHttpRequestFactory { - public Action GetResponseAction { get; set; } + public Action? GetResponseAction { get; set; } - public Func ResponseCreator { get; set; } + public Func? ResponseCreator { get; set; } - public MockHttpRequest LastCreatedRequest { get; private set; } + public MockHttpRequest? LastCreatedRequest { get; private set; } public IHttpRequest CreateHttpRequest(Uri requestUri) { @@ -46,11 +46,11 @@ public void Dispose() #else internal class MockHttpRequestFactory : IHttpRequestFactory { - public Action GetResponseAction { get; set; } + public Action? GetResponseAction { get; set; } - public MockHttpRequest LastCreatedRequest { get; private set; } + public MockHttpRequest? LastCreatedRequest { get; private set; } - public Func ResponseCreator { get; set; } + public Func? ResponseCreator { get; set; } public IHttpRequest CreateHttpRequest(Uri requestUri) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 46e41168f8..cad99085df 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -31,7 +31,7 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; internal class MockWebResponse { #if NET452 - public static HttpWebResponse CreateFromResource(string resourceName) + public static HttpWebResponse? CreateFromResource(string resourceName) { var rawResponse = Utils.GetResourceText(resourceName); var response = ParseRawReponse(rawResponse); @@ -39,11 +39,16 @@ public static HttpWebResponse CreateFromResource(string resourceName) return Create(statusCode, response.Headers, response.Body); } - public static HttpWebResponse Create(HttpStatusCode statusCode, IDictionary headers, string body = null) + public static HttpWebResponse? Create(HttpStatusCode statusCode, IDictionary? headers, string? body = null) { var type = typeof(HttpWebResponse); var assembly = Assembly.GetAssembly(type); - var obj = assembly.CreateInstance("System.Net.HttpWebResponse"); + var obj = assembly?.CreateInstance("System.Net.HttpWebResponse") as HttpWebResponse; + + if (obj == null) + { + return null; + } var webHeaders = new WebHeaderCollection(); if (headers != null) @@ -54,9 +59,8 @@ public static HttpWebResponse Create(HttpStatusCode statusCode, IDictionary headers, string body = null) + public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary? headers, string? body = null) { + HttpResponseMessage? httpResponseMessage = null; var type = typeof(HttpResponseMessage); var assembly = Assembly.GetAssembly(type); - var obj = assembly.CreateInstance("System.Net.Http.HttpResponseMessage"); + if (assembly != null) + { + httpResponseMessage = assembly.CreateInstance("System.Net.Http.HttpResponseMessage") as HttpResponseMessage; + } + + httpResponseMessage ??= new HttpResponseMessage(statusCode); - HttpResponseMessage httpResponseMessage = obj as HttpResponseMessage; var webHeaders = new WebHeaderCollection(); if (headers != null) { foreach (var header in headers) { webHeaders.Add(header.Key, header.Value); - httpResponseMessage.Headers.Add(header.Key, header.Value); + httpResponseMessage?.Headers.Add(header.Key, header.Value); } } @@ -116,7 +125,7 @@ public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary< #endif public static HttpResponse ParseRawReponse(string rawResponse) { - var response = new HttpResponse(); + HttpResponse response = new HttpResponse(); response.StatusLine = rawResponse; var responseLines = rawResponse.Split('\n'); @@ -149,7 +158,7 @@ public static HttpResponse ParseRawReponse(string rawResponse) { var headerKey = currentLine.Substring(0, index); var headerValue = currentLine.Substring(index + 1); - response.Headers.Add(headerKey.Trim(), headerValue.Trim()); + response.Headers?.Add(headerKey.Trim(), headerValue.Trim()); } } } @@ -159,12 +168,12 @@ public static HttpResponse ParseRawReponse(string rawResponse) return response; } - private static HttpStatusCode ParseStatusCode(string statusLine) + private static HttpStatusCode ParseStatusCode(string? statusLine) { var statusCode = string.Empty; try { - statusCode = statusLine.Split(' ')[1]; + statusCode = (statusLine ?? string.Empty).Split(' ')[1]; return (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), statusCode); } catch (Exception exception) @@ -180,10 +189,10 @@ public HttpResponse() this.Headers = new Dictionary(); } - public string StatusLine { get; set; } + public string? StatusLine { get; set; } - public IDictionary Headers { get; private set; } + public IDictionary? Headers { get; private set; } - public string Body { get; set; } + public string? Body { get; set; } } } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs index 635f5efabf..211e7242fa 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -35,17 +35,23 @@ public static Stream CreateStreamFromString(string s) return stream; } - public static Stream GetResourceStream(string resourceName) + public static Stream? GetResourceStream(string resourceName) { Assembly assembly = typeof(Utils).Assembly; var resource = FindResourceName(resourceName); - Stream stream = assembly.GetManifestResourceStream(resource); + Stream? stream = assembly.GetManifestResourceStream(resource); return stream; } public static string GetResourceText(string resourceName) { - using (StreamReader reader = new StreamReader(GetResourceStream(resourceName))) + var stream = GetResourceStream(resourceName); + if (stream == null) + { + return string.Empty; + } + + using (StreamReader reader = new StreamReader(stream)) { return reader.ReadToEnd(); } @@ -69,7 +75,7 @@ public static IEnumerable FindResourceName(Predicate match) } } - public static object GetTagValue(Activity activity, string tagName) + public static object? GetTagValue(Activity activity, string tagName) { return Implementation.Utils.GetTagValue(activity, tagName); } From 0b17dd813929658bead9a921d368e6623bbd71f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 3 Mar 2023 16:53:32 +0100 Subject: [PATCH 0605/1499] Remove references to Jaeger exporter (#1060) --- examples/AspNet/Examples.AspNet.csproj | 1 - examples/AspNet/Global.asax.cs | 7 ------- examples/AspNet/Web.config | 2 -- src/OpenTelemetry.Instrumentation.AspNet/README.md | 6 +++--- .../README.md | 4 ++-- src/OpenTelemetry.Instrumentation.MassTransit/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Quartz/README.md | 6 +++--- 7 files changed, 10 insertions(+), 20 deletions(-) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 9a71f598b7..0d181ef44c 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -83,7 +83,6 @@ - diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index b32f6dfaf3..db50f5bd43 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -42,13 +42,6 @@ protected void Application_Start() switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant()) { - case "jaeger": - builder.AddJaegerExporter(jaegerOptions => - { - jaegerOptions.AgentHost = ConfigurationManager.AppSettings["JaegerHost"]; - jaegerOptions.AgentPort = int.Parse(ConfigurationManager.AppSettings["JaegerPort"]); - }); - break; case "zipkin": builder.AddZipkinExporter(zipkinOptions => { diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index d5496c456d..9eebb5c685 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -7,8 +7,6 @@ - - diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 46586814be..0ba136ba1d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -57,8 +57,8 @@ following shows changes required to your `Web.config` when using IIS web server. ASP.NET instrumentation must be enabled at application startup. This is typically done in the `Global.asax.cs` as shown below. This example also sets up -the OpenTelemetry Jaeger exporter, which requires adding the package -[`OpenTelemetry.Exporter.Jaeger`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Jaeger/README.md) +the OpenTelemetry OTLP exporter, which requires adding the package +[`OpenTelemetry.Exporter.OpenTelemetryProtocol`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) to the application. ```csharp @@ -72,7 +72,7 @@ public class WebApiApplication : HttpApplication { this.tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetInstrumentation() - .AddJaegerExporter() + .AddOtlpExporter() .Build(); } protected void Application_End() diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 1c5734e509..9c2d8c555e 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -23,8 +23,8 @@ ASP.NET Core instrumentation example: services.AddOpenTelemetry().WithTracing(x => { x.AddElasticsearchClientInstrumentation(); - x.UseJaegerExporter(config => { - // Configure Jaeger + x.AddOtlpExporter(config => { + // Configure OTLP }); }); ``` diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md index 06300e2d1d..159adc9558 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -52,8 +52,8 @@ services.AddMassTransitHostedService(); services.AddOpenTelemetrySdk(x => { x.AddMassTransitInstrumentation(); - x.UseJaegerExporter(config => { - // Configure Jaeger + x.AddOtlpExporter(config => { + // Configure OTLP }); }); ``` diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 0e7edb1e2d..06653ecda6 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -9,7 +9,7 @@ Automatically instruments the Quartz jobs from ## Supported Frameworks QuartzNET Instrumentation is only supported when using .NET Framework >= -`net472` and netstandard >= `netstandard2.0`. Quartz`net461` support for +`net472` and .NET Standard >= `netstandard2.0`. Quartz`net461` support for activity sources has been removed, more information can be found [here](https://www.quartz-scheduler.net/2021/04/07/quartznet-3-3-released/). @@ -45,8 +45,8 @@ public void ConfigureServices(IServiceCollection services) services.AddOpenTelemetry().WithTracing(x => { x.AddQuartzInstrumentation(); - x.UseJaegerExporter(config => { - // Configure Jaeger + x.AddOtlpExporter(config => { + // Configure OTLP }); }); ``` From 6dc0417817995b33ede6f9ae6a70deaf1bcc6a3c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 3 Mar 2023 08:06:57 -0800 Subject: [PATCH 0606/1499] [OneCollector] Add RegisterPayloadTransmittedCallback API (#1058) Co-authored-by: Cijo Thomas --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 27 ++- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 27 ++- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 27 ++- .../netstandard2.0/PublicAPI.Unshipped.txt | 27 ++- .../netstandard2.1/PublicAPI.Unshipped.txt | 27 ++- .../CHANGELOG.md | 3 + .../Internal/CallbackManager.cs | 78 ++++++ .../OneCollectorExporterEventSource.cs | 15 ++ .../CommonSchemaJsonSerializer.cs | 2 + .../Internal/Serialization/ISerializer.cs | 2 + .../Internal/Sinks/ISink.cs | 2 + .../Sinks/WriteDirectlyToTransportSink.cs | 13 +- .../Transports/HttpJsonPostTransport.cs | 72 +++++- .../Internal/Transports/ITransport.cs | 2 + .../Transports/TransportSendRequest.cs | 10 +- .../OneCollectorLogExportProcessorBuilder.cs | 225 ++++++++++++++++++ .../Logs/OneCollectorLogExporter.cs | 35 --- .../Logs/OneCollectorLogExporterBuilder.cs | 118 --------- .../Logs/OneCollectorLogExporterOptions.cs | 31 +-- ...torOpenTelemetryLoggerOptionsExtensions.cs | 68 +++--- .../OneCollectorExporter.cs | 23 +- .../OneCollectorExporterOptions.cs | 6 + ...rterPayloadTransmittedCallbackArguments.cs | 93 ++++++++ ...llectorExporterSerializationFormatType.cs} | 13 +- .../OneCollectorExporterTransportOptions.cs | 23 -- .../HttpJsonPostTransportTests.cs | 136 ++++++++++- ...enTelemetryLoggerOptionsExtensionsTests.cs | 24 ++ .../WriteDirectlyToTransportSinkTests.cs | 5 + 28 files changed, 797 insertions(+), 337 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs rename src/OpenTelemetry.Exporter.OneCollector/{Internal/Sinks/ISinkFactory.cs => OneCollectorExporterSerializationFormatType.cs} (62%) diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index 438e9e6c3d..baf438cdc1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -10,22 +17,20 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExporterBuilder -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index 438e9e6c3d..baf438cdc1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -10,22 +17,20 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExporterBuilder -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index 438e9e6c3d..baf438cdc1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -10,22 +17,20 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExporterBuilder -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 438e9e6c3d..baf438cdc1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -10,22 +17,20 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExporterBuilder -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 9087227582..baf438cdc1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,8 +1,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -10,22 +17,20 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporter.OneCollectorLogExporter(OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions! options) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.BatchOptions.get -> OpenTelemetry.BatchExportProcessorOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExporterBuilder -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! -OpenTelemetry.Logs.OneCollectorLogExporterBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExporterBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! \ No newline at end of file +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 16a028098e..a3b6cab3dd 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -14,6 +14,9 @@ instrumentation key directly. ([#1037](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1037)) +* Added `RegisterPayloadTransmittedCallback` API on `OneCollectorExporter`. + ([#1058](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1058)) + ## 0.1.0-alpha.1 Released 2023-Feb-16 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs new file mode 100644 index 0000000000..a545bce80a --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs @@ -0,0 +1,78 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class CallbackManager : IDisposable + where T : Delegate +{ + private readonly object lockObject = new(); + private T? root; + private bool disposed; + + public T? Root { get => this.root; } + + public IDisposable Add(T callback) + { + Debug.Assert(callback != null, "callback was null"); + + lock (this.lockObject) + { + if (this.disposed) + { + throw new ObjectDisposedException(nameof(CallbackManager)); + } + + this.root = (T)Delegate.Combine(this.root, callback); + } + + return new CallbackManagerRegistration(() => + { + lock (this.lockObject) + { + this.root = (T?)Delegate.Remove(this.root, callback); + } + }); + } + + public void Dispose() + { + lock (this.lockObject) + { + this.root = null; + this.disposed = true; + } + } + + private sealed class CallbackManagerRegistration : IDisposable + { + private readonly Action disposeAction; + + public CallbackManagerRegistration(Action disposeAction) + { + Debug.Assert(disposeAction != null, "disposeAction was null"); + + this.disposeAction = disposeAction!; + } + + public void Dispose() + { + this.disposeAction(); + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index aa5f21c7be..0ab1a1eb0c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -73,6 +73,15 @@ public void WriteHttpTransportErrorResponseReceivedEventIfEnabled(string transpo } } + [NonEvent] + public void WriteExceptionThrownFromUserCodeEventIfEnabled(string userCodeType, Exception exception) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.ExceptionThrownFromUserCode(userCodeType, ExceptionToInvariantString(exception)); + } + } + [Event(1, Message = "Exception thrown exporting '{0}' batch: {1}.", Level = EventLevel.Error)] public void ExportExceptionThrown(string itemType, string exception) { @@ -127,6 +136,12 @@ public void EventNameInvalid(string eventName) this.WriteEvent(9, eventName); } + [Event(10, Message = "Exception thrown by '{0}' user code: {1}", Level = EventLevel.Error)] + public void ExceptionThrownFromUserCode(string userCodeType, string exception) + { + this.WriteEvent(10, userCodeType, exception); + } + /// /// Returns a culture-independent string representation of the given object, /// appropriate for diagnostics tracing. diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs index a6cf0d7a64..bd9793ca70 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -53,6 +53,8 @@ protected CommonSchemaJsonSerializer( public abstract string Description { get; } + public OneCollectorExporterSerializationFormatType SerializationFormat => OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream; + protected JsonEncodedText TenantTokenWithTenancySystemSymbol { get; } public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, Stream stream, int initialSizeOfPayloadInBytes, out BatchSerializationResult result) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs index bcd607f084..1b2669aeeb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs @@ -23,6 +23,8 @@ internal interface ISerializer { string Description { get; } + OneCollectorExporterSerializationFormatType SerializationFormat { get; } + void SerializeBatchOfItemsToStream( Resource resource, in Batch batch, diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs index ba914c1e10..e404f1f548 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs @@ -23,5 +23,7 @@ internal interface ISink { string Description { get; } + ITransport? Transport { get; } + int Write(Resource resource, in Batch batch); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs index b6f49c6866..3f228dba0b 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs @@ -28,7 +28,6 @@ internal sealed class WriteDirectlyToTransportSink : ISink, IDisposable { private readonly string typeName; private readonly ISerializer serializer; - private readonly ITransport transport; private readonly MemoryStream buffer; public WriteDirectlyToTransportSink( @@ -42,12 +41,14 @@ public WriteDirectlyToTransportSink( this.typeName = typeof(T).Name; this.serializer = serializer; - this.transport = transport; + this.Transport = transport; this.buffer = new(initialBufferCapacity); } public string Description => "WriteDirectlyToTransportSink"; + public ITransport Transport { get; } + internal MemoryStream Buffer => this.buffer; public void Dispose() @@ -55,7 +56,7 @@ public void Dispose() this.TrySendRemainingData(); (this.serializer as IDisposable)?.Dispose(); - (this.transport as IDisposable)?.Dispose(); + (this.Transport as IDisposable)?.Dispose(); } public int Write(Resource resource, in Batch batch) @@ -97,10 +98,11 @@ public int Write(Resource resource, in Batch batch) buffer.Position = 0; - if (!this.transport.Send( + if (!this.Transport.Send( new TransportSendRequest { ItemType = this.typeName, + ItemSerializationFormat = this.serializer.SerializationFormat, ItemStream = buffer, NumberOfItems = numberOfItemsToSend, })) @@ -147,10 +149,11 @@ private void TrySendRemainingData() try { - if (!this.transport.Send( + if (!this.Transport.Send( new TransportSendRequest { ItemType = this.typeName, + ItemSerializationFormat = this.serializer.SerializationFormat, ItemStream = buffer, NumberOfItems = 1, })) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index f2b6d78af3..2324ef4a97 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -18,6 +18,7 @@ using System.IO.Compression; using System.Net; using System.Net.Http.Headers; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.OneCollector; @@ -26,6 +27,7 @@ internal sealed class HttpJsonPostTransport : ITransport, IDisposable private static readonly string SdkVersion = $"OTel-{Environment.OSVersion.Platform}-.net-{typeof(OneCollectorExporter<>).Assembly.GetName()?.Version?.ToString() ?? "0.0.0"}"; private static readonly string UserAgent = $".NET/{Environment.Version} HttpClient"; + private readonly CallbackManager payloadTransmittedCallbacks = new(); private readonly Uri endpoint; private readonly string instrumentationKey; private readonly OneCollectorExporterHttpTransportCompressionType compressionType; @@ -54,11 +56,26 @@ public HttpJsonPostTransport( public void Dispose() { + this.payloadTransmittedCallbacks.Dispose(); this.buffer?.Dispose(); } + public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback) + { + Guard.ThrowIfNull(callback); + + return this.payloadTransmittedCallbacks.Add(callback); + } + public bool Send(in TransportSendRequest sendRequest) { + Debug.Assert(sendRequest.ItemStream.CanSeek, "ItemStream was not seekable."); + Debug.Assert( + sendRequest.ItemSerializationFormat == OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream, + "sendRequest.ItemSerializationFormat was not CommonSchemaV4JsonStream"); + + var streamStartingPosition = sendRequest.ItemStream.Position; + // Prevent OneCollector's HTTP operations from being instrumented. using var scope = SuppressInstrumentationScope.Begin(); @@ -98,6 +115,17 @@ public bool Send(in TransportSendRequest sendRequest) response.EnsureSuccessStatusCode(); OneCollectorExporterEventSource.Log.WriteTransportDataSentEventIfEnabled(sendRequest.ItemType, sendRequest.NumberOfItems, this.Description); + + var root = this.payloadTransmittedCallbacks.Root; + if (root != null) + { + this.InvokePayloadTransmittedCallbacks( + root, + streamStartingPosition, + in sendRequest); + } + + return true; } catch { @@ -120,8 +148,6 @@ public bool Send(in TransportSendRequest sendRequest) return false; } - - return true; } private HttpContent BuildRequestContent(Stream stream) @@ -160,6 +186,36 @@ private HttpContent BuildRequestContent(Stream stream) } } + private void InvokePayloadTransmittedCallbacks( + OneCollectorExporterPayloadTransmittedCallbackAction callback, + long streamStartingPosition, + in TransportSendRequest sendRequest) + { + var stream = sendRequest.ItemStream; + + var currentPosition = stream.Position; + + try + { + stream.Position = streamStartingPosition; + + callback( + new OneCollectorExporterPayloadTransmittedCallbackArguments( + sendRequest.ItemSerializationFormat, + stream, + OneCollectorExporterTransportProtocolType.HttpJsonPost, + this.endpoint)); + } + catch (Exception ex) + { + OneCollectorExporterEventSource.Log.WriteExceptionThrownFromUserCodeEventIfEnabled("PayloadTransmittedCallback", ex); + } + finally + { + stream.Position = currentPosition; + } + } + private sealed class NonDisposingStreamContent : HttpContent { #pragma warning disable CA2213 // Disposable fields should be disposed @@ -176,16 +232,8 @@ public NonDisposingStreamContent(Stream stream) protected override bool TryComputeLength(out long length) { var stream = this.stream; - if (stream.CanSeek) - { - length = stream.Length - stream.Position; - return true; - } - else - { - length = 0; - return false; - } + length = stream.Length - stream.Position; + return true; } #if NET6_0_OR_GREATER diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs index 9edc4a601e..4abed07d5b 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs @@ -21,4 +21,6 @@ internal interface ITransport string Description { get; } bool Send(in TransportSendRequest sendRequest); + + IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs index 90505bfa41..7490be62a2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs @@ -36,12 +36,18 @@ public TransportSendRequest() #if NET7_0_OR_GREATER public required string ItemType { get; init; } + public required OneCollectorExporterSerializationFormatType ItemSerializationFormat { get; init; } + public required Stream ItemStream { get; init; } + + public required int NumberOfItems { get; init; } #else public string ItemType { get; init; } + public OneCollectorExporterSerializationFormatType ItemSerializationFormat { get; init; } + public Stream ItemStream { get; init; } -#endif - public int? NumberOfItems { get; init; } + public int NumberOfItems { get; init; } +#endif } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs new file mode 100644 index 0000000000..69e47a6734 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs @@ -0,0 +1,225 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Exporter.OneCollector; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Logs; + +/// +/// Contains methods for building and instances for exporting telemetry data. +/// +public sealed class OneCollectorLogExportProcessorBuilder +{ + private static readonly Func DefaultHttpClientFactory = () => new HttpClient(); + private readonly OneCollectorLogExporterOptions exporterOptions = new(); + private readonly BatchExportProcessorOptions batchOptions = new(); + private readonly List>> configureExporterActions = new(); + private Func? httpClientFactory; + + internal OneCollectorLogExportProcessorBuilder( + IConfiguration? configuration) + { + if (configuration != null) + { + configuration.Bind(this.exporterOptions); + configuration.GetSection("BatchOptions").Bind(this.batchOptions); + } + } + + /// + /// Register a callback action for configuring the batch options of the + /// processor used to invoke the . + /// + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder ConfigureBatchOptions( + Action> configure) + { + Guard.ThrowIfNull(configure); + + configure(this.batchOptions); + + return this; + } + + /// + /// Register a callback action for configuring the created by the builder. + /// + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder ConfigureExporter( + Action> configure) + { + Guard.ThrowIfNull(configure); + + this.configureExporterActions.Add(configure); + + return this; + } + + /// + /// Register a callback action for configuring the transport options used by + /// the created by the builder. + /// + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder ConfigureTransportOptions( + Action configure) + { + Guard.ThrowIfNull(configure); + + configure(this.exporterOptions.TransportOptions); + + return this; + } + + /// + /// Sets the connection string used by the created by the builder. + /// + /// + /// Connection string. + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder SetConnectionString( + string connectionString) + { + Guard.ThrowIfNullOrWhitespace(connectionString); + + this.exporterOptions.ConnectionString = connectionString; + + return this; + } + + /// + /// Sets the default event name used by the created by the builder. Default value: + /// Log. + /// + /// + /// Default event name. + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder SetDefaultEventName( + string defaultEventName) + { + Guard.ThrowIfNullOrWhitespace(defaultEventName); + + this.exporterOptions.DefaultEventName = defaultEventName; + + return this; + } + + /// + /// Sets the factory function called to create the + /// instance that will be used at runtime to transmit telemetry over HTTP + /// transports. The returned instance will be reused for all export + /// invocations. + /// + /// + /// Note: The default behavior is an will be + /// instantiated directly. + /// + /// Factory function which returns the instance to use. + /// The supplied for call + /// chaining. + internal OneCollectorLogExportProcessorBuilder SetHttpClientFactory( + Func httpClientFactory) + { + Guard.ThrowIfNull(httpClientFactory); + + this.httpClientFactory = httpClientFactory; + + return this; + } + + internal BaseProcessor BuildProcessor() + { +#pragma warning disable CA2000 // Dispose objects before losing scope + return new BatchLogRecordExportProcessor( + this.BuildExporter(), + this.batchOptions.MaxQueueSize, + this.batchOptions.ScheduledDelayMilliseconds, + this.batchOptions.ExporterTimeoutMilliseconds, + this.batchOptions.MaxExportBatchSize); +#pragma warning restore CA2000 // Dispose objects before losing scope + } + + private OneCollectorExporter BuildExporter() + { + var exporter = new OneCollectorExporter(this.CreateSink()); + + try + { + int index = 0; + while (index < this.configureExporterActions.Count) + { + var action = this.configureExporterActions[index++]; + action(exporter); + } + } + catch + { + exporter.Dispose(); + throw; + } + + return exporter; + } + + private ISink CreateSink() + { + this.exporterOptions.Validate(); + + var transportOptions = this.exporterOptions.TransportOptions; + +#pragma warning disable CA2000 // Dispose objects before losing scope + return new WriteDirectlyToTransportSink( + new LogRecordCommonSchemaJsonSerializer( + new EventNameManager(this.exporterOptions.DefaultEventNamespace, this.exporterOptions.DefaultEventName), + this.exporterOptions.TenantToken!, + transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, + transportOptions.MaxNumberOfItemsPerPayload == -1 ? int.MaxValue : transportOptions.MaxNumberOfItemsPerPayload), + new HttpJsonPostTransport( + this.exporterOptions.InstrumentationKey!, + transportOptions.Endpoint, + transportOptions.HttpCompression, + (this.httpClientFactory ?? DefaultHttpClientFactory)() ?? throw new NotSupportedException("HttpClientFactory cannot return a null instance."))); +#pragma warning restore CA2000 // Dispose objects before losing scope + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs deleted file mode 100644 index 85d86f3ba2..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporter.cs +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using OpenTelemetry.Logs; - -namespace OpenTelemetry.Exporter.OneCollector; - -/// -/// OpenTelemetry exporter implementation for sending -/// telemetry data to Microsoft OneCollector. -/// -public sealed class OneCollectorLogExporter : OneCollectorExporter -{ - /// - /// Initializes a new instance of the class. - /// - /// . - public OneCollectorLogExporter(OneCollectorLogExporterOptions options) - : base(options) - { - } -} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs deleted file mode 100644 index 52aa8a807e..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterBuilder.cs +++ /dev/null @@ -1,118 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics; -using Microsoft.Extensions.Configuration; -using OpenTelemetry.Exporter.OneCollector; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Logs; - -/// -/// Contains methods for building instances. -/// -public sealed class OneCollectorLogExporterBuilder -{ - internal OneCollectorLogExporterBuilder(string? connectionString) - { - this.Options = new() - { - ConnectionString = connectionString, - }; - } - - internal OneCollectorLogExporterBuilder(IConfiguration configuration) - : this(connectionString: null) - { - Debug.Assert(configuration != null, "configuration was null"); - - configuration.Bind(this.Options); - } - - internal OneCollectorLogExporterOptions Options { get; } - - /// - /// Register a callback action for configuring the batch options of . - /// - /// Callback action for configuring . - /// The supplied for - /// call chaining. - public OneCollectorLogExporterBuilder ConfigureBatchOptions(Action> configure) - { - Guard.ThrowIfNull(configure); - - configure(this.Options.BatchOptions); - - return this; - } - - /// - /// Register a callback action for configuring the transport options of . - /// - /// Callback action for configuring . - /// The supplied for - /// call chaining. - public OneCollectorLogExporterBuilder ConfigureTransportOptions(Action configure) - { - Guard.ThrowIfNull(configure); - - configure(this.Options.TransportOptions); - - return this; - } - - /// - /// Sets the - /// property. - /// - /// - /// Connection string. - /// The supplied for - /// call chaining. - public OneCollectorLogExporterBuilder SetConnectionString(string connectionString) - { - Guard.ThrowIfNullOrWhitespace(connectionString); - - this.Options.ConnectionString = connectionString; - - return this; - } - - /// - /// Sets the - /// property. Default value: Log. - /// - /// - /// Default event name. - /// The supplied for - /// call chaining. - public OneCollectorLogExporterBuilder SetDefaultEventName(string defaultEventName) - { - Guard.ThrowIfNullOrWhitespace(defaultEventName); - - this.Options.DefaultEventName = defaultEventName; - - return this; - } -} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index 2c036105e3..f6018e1f26 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -20,9 +20,10 @@ namespace OpenTelemetry.Exporter.OneCollector; /// -/// Contains options for the class. +/// Contains options used to build a +/// instance for exporting telemetry data. /// -public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions, ISinkFactory +public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions { /// /// Gets or sets the default event name. Default value: Log. @@ -34,11 +35,6 @@ public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions /// public string DefaultEventName { get; set; } = "Log"; - /// - /// Gets the options. - /// - public BatchExportProcessorOptions BatchOptions { get; } = new(); - /// /// Gets or sets the default event namespace. Default value: /// OpenTelemetry.Logs. @@ -51,27 +47,6 @@ public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions /// internal string DefaultEventNamespace { get; set; } = "OpenTelemetry.Logs"; - ISink ISinkFactory.CreateSink() - { - this.Validate(); - - var transportOptions = this.TransportOptions; - -#pragma warning disable CA2000 // Dispose objects before losing scope - return new WriteDirectlyToTransportSink( - new LogRecordCommonSchemaJsonSerializer( - new EventNameManager(this.DefaultEventNamespace, this.DefaultEventName), - this.TenantToken!, - transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, - transportOptions.MaxNumberOfItemsPerPayload == -1 ? int.MaxValue : transportOptions.MaxNumberOfItemsPerPayload), - new HttpJsonPostTransport( - this.InstrumentationKey!, - transportOptions.Endpoint, - transportOptions.HttpCompression, - transportOptions.HttpClientFactory() ?? throw new OneCollectorExporterValidationException($"{nameof(OneCollectorLogExporterOptions)} was missing HttpClientFactory or it returned null."))); -#pragma warning restore CA2000 // Dispose objects before losing scope - } - internal override void Validate() { if (string.IsNullOrWhiteSpace(this.DefaultEventNamespace)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs index c3ab41f770..120c1b2739 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs @@ -25,31 +25,18 @@ namespace OpenTelemetry.Logs; /// public static class OneCollectorOpenTelemetryLoggerOptionsExtensions { - /* - TODO: Enable this once logging supports DI/options binding. /// /// Add OneCollector exporter to the . /// /// . - /// The supplied for call - /// chaining. - public static OpenTelemetryLoggerOptions AddOneCollectorExporter( - this OpenTelemetryLoggerOptions options) - => AddOneCollectorExporter(options, _ => { }); - */ - - /// - /// Add OneCollector exporter to the . - /// - /// . - /// Callback action for configuring . + /// Callback action for configuring . /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, - Action configure) + Action configure) { Guard.ThrowIfNull(configure); @@ -79,13 +66,14 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( /// /// . /// OneCollector connection string. - /// Callback action for configuring . + /// Callback action for configuring . /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, string connectionString, - Action configure) + Action configure) { Guard.ThrowIfNullOrWhitespace(connectionString); @@ -96,8 +84,14 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( /// Add OneCollector exporter to the . /// + /// Note: Batch options () are bound to the "BatchOptions" + /// sub-section of the supplied in the + /// parameter. /// . - /// Configuration used to build . + /// Configuration used to build and . /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( @@ -113,47 +107,47 @@ public static OpenTelemetryLoggerOptions AddOneCollectorExporter( /// Add OneCollector exporter to the . /// + /// /// . - /// Configuration used to build . - /// Callback action for configuring . + /// + /// Callback action for configuring . /// The supplied for call /// chaining. public static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, IConfiguration configuration, - Action configure) + Action configure) { Guard.ThrowIfNull(configuration); return AddOneCollectorExporter(options, connectionString: null, configuration, configure); } - internal static OpenTelemetryLoggerOptions AddOneCollectorExporter( + private static OpenTelemetryLoggerOptions AddOneCollectorExporter( this OpenTelemetryLoggerOptions options, string? connectionString, IConfiguration? configuration, - Action? configure) + Action? configure) { Guard.ThrowIfNull(options); - var builder = configuration == null - ? new OneCollectorLogExporterBuilder(connectionString) - : new OneCollectorLogExporterBuilder(configuration); + var builder = new OneCollectorLogExportProcessorBuilder(configuration); - configure?.Invoke(builder); - - var exporterOptions = builder.Options; + if (!string.IsNullOrWhiteSpace(connectionString)) + { + builder.SetConnectionString(connectionString!); + } - var batchOptions = exporterOptions.BatchOptions; + configure?.Invoke(builder); #pragma warning disable CA2000 // Dispose objects before losing scope options.AddProcessor( - new BatchLogRecordExportProcessor( - new OneCollectorLogExporter(exporterOptions), - batchOptions.MaxQueueSize, - batchOptions.ScheduledDelayMilliseconds, - batchOptions.ExporterTimeoutMilliseconds, - batchOptions.MaxExportBatchSize)); + builder.BuildProcessor()); #pragma warning restore CA2000 // Dispose objects before losing scope return options; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs index 8190c71413..b9c1fff210 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Exporter.OneCollector; /// Microsoft OneCollector. /// /// Item type. -public class OneCollectorExporter : BaseExporter +public sealed class OneCollectorExporter : BaseExporter where T : class { private readonly string typeName; @@ -34,13 +34,13 @@ public class OneCollectorExporter : BaseExporter /// /// Initializes a new instance of the class. /// - /// . - internal OneCollectorExporter(ISinkFactory sinkFactory) + /// . + internal OneCollectorExporter(ISink sink) { - Guard.ThrowIfNull(sinkFactory); + Guard.ThrowIfNull(sink); this.typeName = typeof(T).Name; - this.sink = sinkFactory.CreateSink(); + this.sink = sink; } /// @@ -64,6 +64,19 @@ public sealed override ExportResult Export(in Batch batch) } } + /// + /// Register a callback action that will be triggered any time a payload is + /// transmitted by the exporter. + /// + /// . + /// if no transport is tied to the exporter + /// or an representing the registered callback. + /// Call on the returned instance to + /// cancel the registration. + public IDisposable? RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback) + => this.sink.Transport?.RegisterPayloadTransmittedCallback(callback); + /// protected override void Dispose(bool disposing) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs index 8ea82c4caf..540d9e0e7e 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -51,6 +51,12 @@ internal OneCollectorExporterOptions() /// internal string? TenantToken { get; private set; } + /// + /// Gets or sets OneCollector serialization format. Default value: . + /// + internal OneCollectorExporterSerializationFormatType SerializationFormat { get; set; } = OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream; + internal virtual void Validate() { if (string.IsNullOrWhiteSpace(this.ConnectionString)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs new file mode 100644 index 0000000000..2f720c4c5e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs @@ -0,0 +1,93 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Defines a callback delegate for handling payload transmitted events in the +/// class. +/// +/// Arguments. +public delegate void OneCollectorExporterPayloadTransmittedCallbackAction( + in OneCollectorExporterPayloadTransmittedCallbackArguments args); + +/// +/// Contains arguments for the +/// callback delegate. +/// +public readonly ref struct OneCollectorExporterPayloadTransmittedCallbackArguments +{ + private readonly Stream payloadStream; + + internal OneCollectorExporterPayloadTransmittedCallbackArguments( + OneCollectorExporterSerializationFormatType payloadSerializationFormat, + Stream payloadStream, + OneCollectorExporterTransportProtocolType transportProtocol, + Uri transportEndpoint) + { + Debug.Assert(payloadStream != null, "payload stream was null"); + Debug.Assert(payloadStream!.CanSeek, "payload stream was not seekable"); + Debug.Assert(transportEndpoint != null, "transportEndpoint was null"); + + this.PayloadSerializationFormat = payloadSerializationFormat; + this.payloadStream = payloadStream; + this.TransportProtocol = transportProtocol; + this.TransportEndpoint = transportEndpoint!; + } + + /// + /// Gets the payload size in bytes. + /// + public long PayloadSizeInBytes => this.payloadStream!.Length; + + /// + /// Gets the transport endpoint. + /// + public Uri TransportEndpoint { get; } + + /// + /// Gets the payload serialization format. + /// + internal OneCollectorExporterSerializationFormatType PayloadSerializationFormat { get; } + + /// + /// Gets the transport protocol. + /// + internal OneCollectorExporterTransportProtocolType TransportProtocol { get; } + + /// + /// Copy the bytes of the payload to the stream specified by the parameter. + /// + /// Destination . + public void CopyPayloadToStream(Stream destination) + { + Guard.ThrowIfNull(destination); + + var startPosition = this.payloadStream.Position; + try + { + this.payloadStream.CopyTo(destination); + } + finally + { + this.payloadStream.Position = startPosition; + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs similarity index 62% rename from src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs rename to src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs index 46adf69e4f..e9f42365cb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISinkFactory.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,8 +16,13 @@ namespace OpenTelemetry.Exporter.OneCollector; -internal interface ISinkFactory - where T : class +/// +/// Describes the OneCollector serialization format to use when writing telemetry. +/// +internal enum OneCollectorExporterSerializationFormatType { - ISink CreateSink(); + /// + /// Common Schema v4.0 UTF-8 JSON stream serialization format. + /// + CommonSchemaV4JsonStream, } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs index a65365dbe0..5f1759f3ce 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs @@ -27,8 +27,6 @@ public sealed class OneCollectorExporterTransportOptions internal const int DefaultMaxPayloadSizeInBytes = 1024 * 1024 * 4; internal const int DefaultMaxNumberOfItemsPerPayload = 1500; - internal static readonly Func DefaultHttpClientFactory = () => new HttpClient(); - internal OneCollectorExporterTransportOptions() { } @@ -74,22 +72,6 @@ internal OneCollectorExporterTransportOptions() /// internal OneCollectorExporterHttpTransportCompressionType HttpCompression { get; set; } = OneCollectorExporterHttpTransportCompressionType.Deflate; - /// - /// Gets or sets the factory function called to create the instance that will be used at runtime to transmit - /// telemetry over HTTP. The returned instance will be reused for all export - /// invocations. - /// - /// - /// Notes: - /// - /// The default behavior when using the class is an will be instantiated directly. - /// - /// - internal Func HttpClientFactory { get; set; } = DefaultHttpClientFactory; - internal void Validate() { if (this.Endpoint == null) @@ -97,11 +79,6 @@ internal void Validate() throw new OneCollectorExporterValidationException($"{nameof(this.Endpoint)} was not specified on {this.GetType().Name} options."); } - if (this.HttpClientFactory == null) - { - throw new OneCollectorExporterValidationException($"{nameof(this.HttpClientFactory)} was not specified on {this.GetType().Name} options."); - } - if (this.MaxPayloadSizeInBytes <= 0 && this.MaxPayloadSizeInBytes != -1) { throw new OneCollectorExporterValidationException($"{nameof(this.MaxPayloadSizeInBytes)} was invalid on {this.GetType().Name} options."); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index 910c5bdd85..140fc7c6a3 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -84,6 +84,103 @@ public void RequestUsingDeflateCompressionTest() }); } + [Fact] + public void RegisterPayloadTransmittedCallbackTest() + { + var request = "{\"key1\":\"value1\"}"; + + using var httpClient = new HttpClient(); + + int lastCompletedIteration = -1; + IDisposable? callbackRegistration = null; + bool callbackFired = false; + + /* + * This test runs a few different iterations... + * + * 0) Callback is attached and verified to fire. + * 1) Exisiting callback fires again and is verified. Then we remove the callback. + * 2) Verifies callback is NOT attached and NOT fired. + * 3) Callback is attached again and verified to fire. Then we remove the callback. + */ + + RunHttpServerTest( + request, + requestUri => + { + var transport = new HttpJsonPostTransport( + "instrumentation-key", + requestUri, + OneCollectorExporterHttpTransportCompressionType.None, + httpClient); + + return transport; + }, + (req, body) => + { + AssertStandardHeaders(req); + Assert.True(string.IsNullOrWhiteSpace(req.Headers["Content-Encoding"])); + Assert.Equal(request, Encoding.ASCII.GetString(body.ToArray())); + }, + testStartingAction: (iteration, transport) => + { + switch (iteration) + { + case 0: + case 3: + Assert.Null(callbackRegistration); + callbackRegistration = transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted); + break; + case 1: + Assert.NotNull(callbackRegistration); + break; + case 2: + Assert.Null(callbackRegistration); + break; + } + }, + testFinishedAction: (iteration, transport) => + { + switch (iteration) + { + case 0: + Assert.NotNull(callbackRegistration); + Assert.True(callbackFired); + break; + case 1: + case 3: + Assert.NotNull(callbackRegistration); + Assert.True(callbackFired); + callbackRegistration.Dispose(); + callbackRegistration = null; + break; + case 2: + Assert.Null(callbackRegistration); + Assert.False(callbackFired); + break; + } + + callbackFired = false; + lastCompletedIteration = iteration; + }, + testIterations: 4); + + Assert.Equal(3, lastCompletedIteration); + + void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallbackArguments arguments) + { + callbackFired = true; + + using var stream = new MemoryStream(); + arguments.CopyPayloadToStream(stream); + + Assert.Equal(Encoding.ASCII.GetBytes(request), stream.ToArray()); + Assert.Equal(OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream, arguments.PayloadSerializationFormat); + Assert.Equal(OneCollectorExporterTransportProtocolType.HttpJsonPost, arguments.TransportProtocol); + Assert.NotNull(arguments.TransportEndpoint); + } + } + private static void AssertStandardHeaders(HttpListenerRequest request) { Assert.Equal("POST", request.HttpMethod); @@ -97,7 +194,11 @@ private static void AssertStandardHeaders(HttpListenerRequest request) private static void RunHttpServerTest( string requestBody, Func createTransportFunc, - Action assertRequestAction) + Action assertRequestAction, + int numberOfItemsInRequestBody = 1, + int testIterations = 1, + Action? testStartingAction = null, + Action? testFinishedAction = null) { bool requestReceivedAndAsserted = false; Exception? testException = null; @@ -138,22 +239,31 @@ private static void RunHttpServerTest( { var requestBodyBytes = Encoding.ASCII.GetBytes(requestBody); - using var requestBodyStream = new MemoryStream(requestBodyBytes); + for (int i = 0; i < testIterations; i++) + { + testStartingAction?.Invoke(i, transport); + + using var requestBodyStream = new MemoryStream(requestBodyBytes); + + var result = transport.Send( + new TransportSendRequest + { + ItemStream = requestBodyStream, + ItemSerializationFormat = OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream, + ItemType = "TestRequest", + NumberOfItems = numberOfItemsInRequestBody, + }); - var result = transport.Send( - new TransportSendRequest + if (testException != null) { - ItemStream = requestBodyStream, - ItemType = "TestRequest", - }); + throw testException; + } - if (testException != null) - { - throw testException; - } + Assert.True(result); + Assert.True(requestReceivedAndAsserted); - Assert.True(result); - Assert.True(requestReceivedAndAsserted); + testFinishedAction?.Invoke(i, transport); + } } finally { diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs index 6f9d4bac94..e157ff08f1 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs @@ -22,6 +22,30 @@ namespace OpenTelemetry.Exporter.OneCollector.Tests; public class OneCollectorOpenTelemetryLoggerOptionsExtensionsTests { + [Fact] + public void ConfigureExporterTest() + { + OneCollectorExporter? exporterInstance = null; + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(builder => + { + builder.AddOneCollectorExporter( + "InstrumentationKey=token-extrainformation", + configure => configure.ConfigureExporter(exporter => exporterInstance = exporter)); + })); + + Assert.NotNull(exporterInstance); + + using var payloadTransmittedRegistration = exporterInstance.RegisterPayloadTransmittedCallback(OnPayloadTransmitted); + + Assert.NotNull(payloadTransmittedRegistration); + + static void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallbackArguments args) + { + } + } + [Fact] public void InstrumentationKeyAndTenantTokenValidationTest() { diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs index f2ac6df9ff..58df6d47df 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -166,6 +166,11 @@ private sealed class TestTransport : ITransport public List ExportedData { get; } = new(); + public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback) + { + throw new NotImplementedException(); + } + public bool Send(in TransportSendRequest sendRequest) { var stream = new MemoryStream(); From 0c7f2a0908bef1475a64df12b9a58220a9f86c9d Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 3 Mar 2023 19:25:39 +0000 Subject: [PATCH 0607/1499] Suppress two analysis warnings (#1061) --- .../TracerProviderBuilderExtensions.cs | 10 ++++++---- .../GenevaMetricExporterTests.cs | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs index a830904a4a..e1c94fe726 100644 --- a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -20,16 +20,16 @@ namespace OpenTelemetry.Exporter.Instana; /// -/// Todo. +/// Extension methods for for using Instana. /// public static class TracerProviderBuilderExtensions { /// - /// Instana test provider builder extension. + /// Instana tracer provider builder extension. /// - /// Test provider builder. + /// Tracer provider builder. /// todo. - /// Test provider builder is null. + /// Tracer provider builder is null. public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilder options) { if (options == null) @@ -37,6 +37,8 @@ public static TracerProviderBuilder AddInstanaExporter(this TracerProviderBuilde throw new ArgumentNullException(nameof(options)); } +#pragma warning disable CA2000 return options.AddProcessor(new BatchActivityExportProcessor(new InstanaExporter())); +#pragma warning restore CA2000 } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 344aae91c6..0f75779db8 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -677,7 +677,9 @@ public void DisableMetricNameValidationTest(bool disableMetricNameValidation) finally { instrumentNameRegexProperty.SetValue(null, initialInstrumentNameRegexValue); +#pragma warning disable CA1508 server?.Dispose(); +#pragma warning restore CA1508 } } From 4485a1c328f2c7bb5a745c9b44c8b4f197fdc1e1 Mon Sep 17 00:00:00 2001 From: Pierre Tessier Date: Sat, 4 Mar 2023 15:49:36 -0500 Subject: [PATCH 0608/1499] [Instrumentation.AspNet] fix metric description (#1063) --- .../Implementation/HttpInMetricsListener.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index aa88a78898..eeda8049f4 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -28,7 +28,7 @@ internal sealed class HttpInMetricsListener : IDisposable public HttpInMetricsListener(Meter meter) { - this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "measures the duration of the inbound HTTP request"); + this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "Measures the duration of inbound HTTP requests."); TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; } From f885ff81559baa613f72a6f41e034d615e0dea82 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Mon, 6 Mar 2023 18:40:41 +0200 Subject: [PATCH 0609/1499] Add options support to ElasticsearchClient instrumentation (#1019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Utkarsh Umesan Pillai --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +- .../CHANGELOG.md | 12 ++- ...Instrumentation.ElasticsearchClient.csproj | 2 +- .../README.md | 101 +++++++++++++++--- .../TracerProviderBuilderExtensions.cs | 41 ++++++- .../DependencyInjectionConfigTests.cs | 65 +++++++++++ ...mentation.ElasticsearchClient.Tests.csproj | 5 +- 8 files changed, 211 insertions(+), 23 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt index 079ec48823..95461d9b80 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt @@ -11,4 +11,6 @@ OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumenta OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 079ec48823..95461d9b80 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -11,4 +11,6 @@ OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumenta OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index a5885260dd..6606879c25 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,12 +2,20 @@ ## Unreleased -* Updated OTel SDK package version to 1.2.0 +* Updated OTel SDK package version to 1.4.0 + ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) * Update minimum full framework support to net462 * Requests that get an HTTP status code of 404 are not marked as an error span status * Add MaxDbStatementLength option with default of 4096 * Remove duplicated HTTP method and URL from db.statement attribute value -* Fix faulty logic of MaxDbStatementLength option [(#425)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/425) +* Fix faulty logic of MaxDbStatementLength option + ([#425](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/425)) +* Remove method with default attribute + ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddElasticsearchClientInstrumentation` extension to allow for more fine-grained + options management + ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 64150f4f68..b0323bbc18 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -8,7 +8,7 @@ true - + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 9c2d8c555e..95934edaf5 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -5,28 +5,105 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) -Automatically instruments events emitted by the [NEST/Elasticsearch.Net](https://www.nuget.org/packages/NEST) -client library. +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments [NEST/Elasticsearch.Net](https://www.nuget.org/packages/NEST) +and collects traces about outgoing requests. -### Installation +**Note: This component is based on the OpenTelemetry semantic conventions for +[metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) +and +[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +These conventions are +[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), +and hence, this package is a +[pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). +Until a [stable +version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be [breaking changes](./CHANGELOG.md). You can track the +progress from +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** + +## Steps to enable OpenTelemetry.Instrumentation.ElasticsearchClient + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.ElasticsearchClient`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) +package. Also, add any other instrumentations & exporters you will need. ```shell -dotnet add package OpenTelemetry.Instrumentation.ElasticsearchClient +dotnet add package --prerelease OpenTelemetry.Instrumentation.ElasticsearchClient +``` + +### Step 2: Enable NEST/Elasticsearch.Net Instrumentation at application startup + +`NEST/Elasticsearch.Net` instrumentation must be enabled at application startup. + +The following example demonstrates adding `NEST/Elasticsearch.Net` +instrumentation to a console application. This example also sets up the +OpenTelemetry Console exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddElasticsearchClientInstrumentation() + .AddConsoleExporter() + .Build(); + } +} ``` -### Configuration +For an ASP.NET Core application, adding instrumentation is typically done in the +`ConfigureServices` of your `Startup` class. Refer to documentation for +[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). + +For an ASP.NET application, adding instrumentation is typically done in the +`Global.asax.cs`. Refer to the documentation for +[OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). -ASP.NET Core instrumentation example: +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`ElasticsearchClientInstrumentationOptions`. ```csharp -// Add OpenTelemetry and Elasticsearch client instrumentation -services.AddOpenTelemetry().WithTracing(x => +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddElasticsearchClientInstrumentation(options => + { + // add request json as db.statement attribute tag + options.SetDbStatementForRequest = true; + }) + .AddConsoleExporter()); +``` + +When used with +[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md), +all configurations to `ElasticsearchClientInstrumentationOptions` +can be done in the `ConfigureServices` method of you applications `Startup` +class as shown below. + +```csharp +// Configure +services.Configure(options => { - x.AddElasticsearchClientInstrumentation(); - x.AddOtlpExporter(config => { - // Configure OTLP - }); + // add request json as db.statement attribute tag + options.SetDbStatementForRequest = true; }); + +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddElasticsearchClientInstrumentation() + .AddConsoleExporter()); ``` ## Elastic.Clients.Elasticsearch diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index 6a14569a0b..8933b157f4 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ElasticsearchClient; using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; using OpenTelemetry.Internal; @@ -30,18 +32,49 @@ public static class TracerProviderBuilderExtensions /// Enables Elasticsearch client Instrumentation. /// /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddElasticsearchClientInstrumentation( + this TracerProviderBuilder builder) => + AddElasticsearchClientInstrumentation(builder, name: null, configure: null); + + /// + /// Enables Elasticsearch client Instrumentation. + /// + /// being configured. + /// Elasticsearch client configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddElasticsearchClientInstrumentation( + this TracerProviderBuilder builder, + Action configure) => + AddElasticsearchClientInstrumentation(builder, name: null, configure); + + /// + /// Enables Elasticsearch client Instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. /// Elasticsearch client configuration options. /// The instance of to chain the calls. public static TracerProviderBuilder AddElasticsearchClientInstrumentation( this TracerProviderBuilder builder, - Action configure = null) + string name, + Action configure) { Guard.ThrowIfNull(builder); - var elasticsearchClientOptions = new ElasticsearchClientInstrumentationOptions(); - configure?.Invoke(elasticsearchClientOptions); + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } + + builder.AddInstrumentation(sp => + { + var options = sp.GetRequiredService>().Get(name); + return new ElasticsearchClientInstrumentation(options); + }); - builder.AddInstrumentation(() => new ElasticsearchClientInstrumentation(elasticsearchClientOptions)); builder.AddSource(ElasticsearchRequestPipelineDiagnosticListener.ActivitySourceName); builder.AddLegacySource("CallElasticsearch"); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs new file mode 100644 index 0000000000..0205eb1729 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs @@ -0,0 +1,65 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; + +public class DependencyInjectionConfigTests +{ + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public async Task TestTracingOptionsDiConfig(string name) + { + bool optionsPickedFromDi = false; + + var services = new ServiceCollection(); + + services + .Configure(name, _ => optionsPickedFromDi = true) + .AddOpenTelemetry() + .WithTracing(builder => + builder.AddElasticsearchClientInstrumentation(name, configure: null)); + + var sp = services.BuildServiceProvider(); + + try + { + foreach (var hostedService in sp.GetServices()) + { + await hostedService.StartAsync(CancellationToken.None); + } + + Assert.True(optionsPickedFromDi); + } + finally + { + foreach (var hostedService in sp.GetServices().Reverse()) + { + await hostedService.StopAsync(CancellationToken.None); + } + + await sp.DisposeAsync(); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 853bf851a4..592864c354 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,14 +1,15 @@ - + Unit test project for OpenTelemetry Elasticsearch client instrumentation - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 true + all From e86dcd0312e54c692e77a2e3218277abdaa0f94b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 6 Mar 2023 14:37:03 -0800 Subject: [PATCH 0610/1499] [OneCollector] CHANGELOG update for 0.1.0-alpha.2 release (#1065) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index a3b6cab3dd..c8befa9ccd 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.2 + +Released 2023-Mar-6 + * Update OpenTelemetry to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) From 588264e621cead4bd0c333d9c5035a7007343d2d Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Tue, 7 Mar 2023 20:35:26 +0200 Subject: [PATCH 0611/1499] Release OpenTelemetry.Instrumentation.ElasticsearchClient 1.0.0-beta.4 (#1064) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 6606879c25..4bfcb84e5d 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2023-Mar-06 + * Updated OTel SDK package version to 1.4.0 ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) * Update minimum full framework support to net462 From a0d42df0137153f788df775eead383645ecf2e3f Mon Sep 17 00:00:00 2001 From: Evgeny Fedorov <25526458+evgenyfedorov2@users.noreply.github.com> Date: Thu, 9 Mar 2023 19:20:49 +0100 Subject: [PATCH 0612/1499] Introduce Trace enrichment framework (#949) Co-authored-by: Cijo Thomas --- .../comp_extensions_enrichment.md | 54 +++++ .github/component_owners.yml | 4 + .../package-Extensions.Enrichment.yml | 67 ++++++ build/Common.props | 2 + opentelemetry-dotnet-contrib.sln | 14 ++ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 20 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 20 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 20 ++ .../BaseEnricher.cs | 26 +++ .../CHANGELOG.md | 1 + .../EnrichmentActions.cs | 41 ++++ ...OpenTelemetry.Extensions.Enrichment.csproj | 21 ++ ...etryEnrichmentProviderBuilderExtensions.cs | 105 ++++++++++ ...ryEnrichmentServiceCollectionExtensions.cs | 128 ++++++++++++ .../README.md | 11 + .../TraceEnricher.cs | 31 +++ .../TraceEnrichmentBag.cs | 36 ++++ .../TraceEnrichmentProcessor.cs | 43 ++++ src/OpenTelemetry.Internal/IsExternalInit.cs | 9 +- .../MyTraceEnricher.cs | 29 +++ .../MyTraceEnricher2.cs | 29 +++ ...lemetry.Extensions.Enrichment.Tests.csproj | 29 +++ ...etryEnrichmentProviderBuilderExtensions.cs | 148 +++++++++++++ ...ichmentServiceCollectionExtensionsTests.cs | 194 ++++++++++++++++++ 27 files changed, 1080 insertions(+), 5 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_enrichment.md create mode 100644 .github/workflows/package-Extensions.Enrichment.yml create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs create mode 100644 src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md create mode 100644 src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs create mode 100644 src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj create mode 100644 src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs create mode 100644 src/OpenTelemetry.Extensions.Enrichment/README.md create mode 100644 src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs create mode 100644 src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs create mode 100644 src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs create mode 100644 test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs create mode 100644 test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs create mode 100644 test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj create mode 100644 test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_enrichment.md b/.github/ISSUE_TEMPLATE/comp_extensions_enrichment.md new file mode 100644 index 0000000000..4e10dc3c77 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_extensions_enrichment.md @@ -0,0 +1,54 @@ +--- +name: OpenTelemetry.Extensions.Enrichment +about: Issue with OpenTelemetry.Extensions.Enrichment +labels: comp:extensions.enrichment +--- + +# Issue with OpenTelemetry.Extensions.Enrichment + +**What type of request is this?** + +* [ ] Feature Request +* [ ] Bug +* [ ] Question + +## Request Details + +**What are the OpenTelemetry packages and versions you are using?** + +_List [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.4.0`)._ + +**What environment are you using?** + +_Please include the runtime versions (e.g. `net462`, `net48`, `net6.0`, `net7.0` +etc.), OS details (e.g.Windows, Linux, etc.), architecture (e.g. 32bit, 64bit, +etc.), and anything else important (e.g. IIS, container, etc.)._ + +**What is the expected behavior?** + +_Describe what you expected to see._ + +**What is the actual behavior?** + +_Describe what you saw instead._ + +**What are the steps to reproduce the issue?** + +_Describe how to reproduce the issue._ + +If you are reporting a non-obvious bug, please create a self-contained project +and apply the minimum required code to result in the issue you're observing. + +We will close this issue if: + +* The repro project you share with us is too complex. We can't investigate + custom projects please try to keep it to just what is needed to demonstrate + the issue. + +* We can't reproduce the behavior you're reporting. + +## Additional Context + +_Include any other context about the bug or feature request here._ diff --git a/.github/component_owners.yml b/.github/component_owners.yml index e6eb61f68b..37ee61990c 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -29,6 +29,8 @@ components: - vishweshbankwar src/OpenTelemetry.Extensions.Docker/: - iskiselev + src/OpenTelemetry.Extensions.Enrichment/: + - xakep139 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/: - vishweshbankwar src/OpenTelemetry.Extensions.PersistentStorage/: @@ -98,6 +100,8 @@ components: - codeblanch test/OpenTelemetry.Extensions.Docker.Tests/: - iskiselev + test/OpenTelemetry.Extensions.Enrichment.Tests/: + - xakep139 test/OpenTelemetry.Extensions.PersistentStorage.Tests/: - vishweshbankwar test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml new file mode 100644 index 0000000000..7d6fc0629c --- /dev/null +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -0,0 +1,67 @@ +name: Pack OpenTelemetry.Extensions.Enrichment + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Extensions.Enrichment-*' # trigger when we create a tag with prefix "Extensions.Enrichment-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + permissions: + contents: write + env: + PROJECT: OpenTelemetry.Extensions.Enrichment + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build/Common.props b/build/Common.props index c322c24bcd..3420b287d8 100644 --- a/build/Common.props +++ b/build/Common.props @@ -7,6 +7,8 @@ $(DefineConstants);SIGNED true net462 + net6.0 + netstandard2.0 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 820b0db25e..a2ad722e26 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -249,6 +249,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneC EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Tests", "test\OpenTelemetry.Exporter.OneCollector.Tests\OpenTelemetry.Exporter.OneCollector.Tests.csproj", "{61520801-1CAA-4041-A3EF-CFFB9D4A180B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Enrichment", "src\OpenTelemetry.Extensions.Enrichment\OpenTelemetry.Extensions.Enrichment.csproj", "{5BA85306-64B8-4E04-90EB-7069C187E250}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Enrichment.Tests", "test\OpenTelemetry.Extensions.Enrichment.Tests\OpenTelemetry.Extensions.Enrichment.Tests.csproj", "{5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -527,6 +531,14 @@ Global {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Debug|Any CPU.Build.0 = Debug|Any CPU {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Release|Any CPU.ActiveCfg = Release|Any CPU {61520801-1CAA-4041-A3EF-CFFB9D4A180B}.Release|Any CPU.Build.0 = Release|Any CPU + {5BA85306-64B8-4E04-90EB-7069C187E250}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5BA85306-64B8-4E04-90EB-7069C187E250}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5BA85306-64B8-4E04-90EB-7069C187E250}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5BA85306-64B8-4E04-90EB-7069C187E250}.Release|Any CPU.Build.0 = Release|Any CPU + {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -608,6 +620,8 @@ Global {DFC6A4A9-5262-4507-B747-CC6B814205E6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {73C10993-03AC-42F4-85BB-96EAAA8212D9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {61520801-1CAA-4041-A3EF-CFFB9D4A180B} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {5BA85306-64B8-4E04-90EB-7069C187E250} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..bc0e2eeb73 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(T enrichmentBag) -> void +Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions +OpenTelemetry.Extensions.Enrichment.BaseEnricher +OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void +OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions +OpenTelemetry.Extensions.Enrichment.TraceEnricher +OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(ref OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag traceEnrichmentBag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..bc0e2eeb73 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(T enrichmentBag) -> void +Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions +OpenTelemetry.Extensions.Enrichment.BaseEnricher +OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void +OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions +OpenTelemetry.Extensions.Enrichment.TraceEnricher +OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(ref OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag traceEnrichmentBag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..bc0e2eeb73 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(T enrichmentBag) -> void +Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions +OpenTelemetry.Extensions.Enrichment.BaseEnricher +OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void +OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions +OpenTelemetry.Extensions.Enrichment.TraceEnricher +OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(ref OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag traceEnrichmentBag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs new file mode 100644 index 0000000000..c1efec51a9 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs @@ -0,0 +1,26 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Extensions.Enrichment; + +public abstract class BaseEnricher +{ + protected BaseEnricher() + { + } + + public abstract void Enrich(T enrichmentBag); +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md new file mode 100644 index 0000000000..825c32f0d0 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog diff --git a/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs b/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs new file mode 100644 index 0000000000..c615155cd5 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs @@ -0,0 +1,41 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenTelemetry.Extensions.Enrichment; + +#pragma warning disable CA1812 // Class is instantiated through dependency injection +internal sealed class EnrichmentActions : TraceEnricher +#pragma warning restore CA1812 // Class is instantiated through dependency injection +{ + private readonly Action[] actions; + + public EnrichmentActions(IEnumerable> actions) + { + this.actions = actions.ToArray(); + } + + public override void Enrich(TraceEnrichmentBag enrichmentBag) + { + for (int i = 0; i < this.actions.Length; i++) + { + this.actions[i].Invoke(enrichmentBag); + } + } +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj new file mode 100644 index 0000000000..3b41bba5e1 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -0,0 +1,21 @@ + + + + $(NetFrameworkMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) + OpenTelemetry .NET SDK telemetry enrichment. + $(NoWarn),CS1591 + Extensions.Enrichment- + enable + latest-all + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs new file mode 100644 index 0000000000..e4c05b4ece --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs @@ -0,0 +1,105 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Extensions.Enrichment; + +/// +/// Extension methods to register telemery enrichers. +/// +public static class OpenTelemetryEnrichmentProviderBuilderExtensions +{ + /// + /// Adds trace enricher. + /// + /// being configured. + /// Enricher object type. + /// Thrown when the is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder builder) + where T : TraceEnricher + { + Guard.ThrowIfNull(builder); + + return builder + .ConfigureServices(services => services.AddTraceEnricher()); + } + + /// + /// Adds trace enricher. + /// + /// being configured. + /// The object being added. + /// Thrown when the or is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder builder, TraceEnricher enricher) + { + Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(enricher); + + return builder + .ConfigureServices(services => services.AddTraceEnricher(enricher)); + } + + /// + /// Adds trace enricher. + /// + /// being configured. + /// The delegate to enrich traces. + /// Thrown when the or is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder builder, Action enrichmentAction) + { + Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(enrichmentAction); + + return builder + .ConfigureServices(services => services.AddTraceEnricher(enrichmentAction)); + } + + /// + /// Adds trace enricher. + /// + /// being configured. + /// The object being added using implementation factory. + /// Thrown when the or is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder builder, Func enricherImplementationFactory) + { + Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(enricherImplementationFactory); + + return builder + .ConfigureServices(services => services + .AddTraceEnricher(enricherImplementationFactory)); + } +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs new file mode 100644 index 0000000000..4738a2940e --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs @@ -0,0 +1,128 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Linq; +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Extensions.Enrichment; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extension methods to register telemery enrichers. +/// +public static class OpenTelemetryEnrichmentServiceCollectionExtensions +{ + /// + /// Adds trace enricher. + /// + /// being configured. + /// Enricher object type. + /// Thrown when the is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static IServiceCollection AddTraceEnricher(this IServiceCollection services) + where T : TraceEnricher + { + Guard.ThrowIfNull(services); + + return services + .TryAddEnrichment() + .AddSingleton(); + } + + /// + /// Adds trace enricher. + /// + /// being configured. + /// The object being added. + /// Thrown when the or is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static IServiceCollection AddTraceEnricher(this IServiceCollection services, TraceEnricher enricher) + { + Guard.ThrowIfNull(services); + Guard.ThrowIfNull(enricher); + + return services + .TryAddEnrichment() + .AddSingleton(enricher); + } + + /// + /// Adds trace enricher. + /// + /// being configured. + /// The delegate to enrich traces. + /// Thrown when the or is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static IServiceCollection AddTraceEnricher(this IServiceCollection services, Action enrichmentAction) + { + Guard.ThrowIfNull(services); + Guard.ThrowIfNull(enrichmentAction); + + services.TryAddSingleton(); + + return services + .TryAddEnrichment() + .AddSingleton(enrichmentAction); + } + + /// + /// Adds trace enricher. + /// + /// being configured. + /// The object being added using implementation factory. + /// Thrown when the or is . + /// The instance of to chain the calls. + /// + /// Add this enricher *before* exporter related Activity processors. + /// + public static IServiceCollection AddTraceEnricher(this IServiceCollection services, Func enricherImplementationFactory) + { + Guard.ThrowIfNull(services); + Guard.ThrowIfNull(enricherImplementationFactory); + + return services + .TryAddEnrichment() + .AddSingleton((serviceProvider) => enricherImplementationFactory(serviceProvider)); + } + + private static IServiceCollection TryAddEnrichment(this IServiceCollection services) + { + if (!services.Any(x => x.ServiceType == typeof(TraceEnrichmentProcessor))) + { + services + .AddSingleton() + .ConfigureOpenTelemetryTracerProvider((sp, builder) => + { + var proc = sp.GetRequiredService(); + builder.AddProcessor(proc); + }); + } + + return services; + } +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md new file mode 100644 index 0000000000..6a8ed5095c --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -0,0 +1,11 @@ +# OpenTelemetry .NET SDK telemetry enrichment framework + +[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Enrichment.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.Enrichment.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) + +Contains OpenTelemetry .NET SDK telemetry enrichment framework +which is used for enrichment of traces. + +## Traces + +TBD diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs new file mode 100644 index 0000000000..bbd6b2445b --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Extensions.Enrichment; + +public abstract class TraceEnricher : BaseEnricher +{ + protected TraceEnricher() + { + } + + public virtual void Enrich(ref TraceEnrichmentBag traceEnrichmentBag) + { + throw new NotImplementedException(); + } +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs new file mode 100644 index 0000000000..2b01eaadd9 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Extensions.Enrichment; + +#pragma warning disable CA1815 // Override equals and operator equals on value types +public readonly struct TraceEnrichmentBag +#pragma warning restore CA1815 // Override equals and operator equals on value types +{ + private readonly Activity activity; + + public TraceEnrichmentBag(Activity activity) + { + this.activity = activity; + } + + public void Add(string key, object? value) + { + this.activity.SetTag(key, value); + } +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs new file mode 100644 index 0000000000..5dc9628baa --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; + +namespace OpenTelemetry.Extensions.Enrichment; + +#pragma warning disable CA1812 // Class is instantiated through dependency injection +internal sealed class TraceEnrichmentProcessor : BaseProcessor +#pragma warning restore CA1812 // Class is instantiated through dependency injection +{ + private readonly TraceEnricher[] traceEnrichers; + + public TraceEnrichmentProcessor(IEnumerable traceEnrichers) + { + this.traceEnrichers = traceEnrichers.ToArray(); + } + + public override void OnEnd(Activity activity) + { + var propertyBag = new TraceEnrichmentBag(activity); + + foreach (var enricher in this.traceEnrichers) + { + enricher.Enrich(propertyBag); + } + } +} diff --git a/src/OpenTelemetry.Internal/IsExternalInit.cs b/src/OpenTelemetry.Internal/IsExternalInit.cs index de19a976dd..c0809ffb0e 100644 --- a/src/OpenTelemetry.Internal/IsExternalInit.cs +++ b/src/OpenTelemetry.Internal/IsExternalInit.cs @@ -15,11 +15,10 @@ // #if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER -namespace System.Runtime.CompilerServices +namespace System.Runtime.CompilerServices; + +// This enabled "init" keyword in net462 + netstandard2.0 targets. +internal static class IsExternalInit { - // This enabled "init" keyword in net462 + netstandard2.0 targets. - internal sealed class IsExternalInit - { - } } #endif diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs new file mode 100644 index 0000000000..c225b38b9d --- /dev/null +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Extensions.Enrichment.Tests; + +internal class MyTraceEnricher : TraceEnricher +{ + public const string Key = nameof(MyTraceEnricher); + + public int TimesCalled { get; private set; } + + public override void Enrich(TraceEnrichmentBag enrichmentBag) + { + enrichmentBag.Add(Key, ++this.TimesCalled); + } +} diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs new file mode 100644 index 0000000000..8631f2f6bf --- /dev/null +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Extensions.Enrichment.Tests; + +internal class MyTraceEnricher2 : TraceEnricher +{ + public const string Key = nameof(MyTraceEnricher2); + + public int TimesCalled { get; private set; } + + public override void Enrich(TraceEnrichmentBag enrichmentBag) + { + enrichmentBag.Add(Key, ++this.TimesCalled); + } +} diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj new file mode 100644 index 0000000000..48538d1d58 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -0,0 +1,29 @@ + + + + Unit test project for OpenTelemetry .NET SDK telemetry enrichment. + + $(NetFrameworkMinimumSupportedVersion) + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs new file mode 100644 index 0000000000..032105b732 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs @@ -0,0 +1,148 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Enrichment.Tests; + +public sealed class OpenTelemetryEnrichmentProviderBuilderExtensions +{ + private const string SourceName = nameof(OpenTelemetryEnrichmentProviderBuilderExtensions); + + [Fact] + public void AddTraceEnricherOfTRegistersEnricher() + { + var exportedItems = new List(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(SourceName) + .AddTraceEnricher() + .AddTraceEnricher() + .AddInMemoryExporter(exportedItems) + .Build(); + + using var source = new ActivitySource(SourceName); + using (var activity = source.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == MyTraceEnricher.Key); + Assert.Equal(1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == MyTraceEnricher2.Key); + Assert.Equal(1, tagObject2.Single().Value); + } + } + + [Fact] + public void AddTraceEnricherRegistersEnricher() + { + var exportedItems = new List(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(SourceName) + .AddTraceEnricher(new MyTraceEnricher()) + .AddTraceEnricher(new MyTraceEnricher2()) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var source1 = new ActivitySource(SourceName); + + using (var activity = source1.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == MyTraceEnricher.Key); + Assert.Equal(1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == MyTraceEnricher2.Key); + Assert.Equal(1, tagObject2.Single().Value); + } + } + + [Fact] + public void AddTraceEnricherActionRegistersEnricher() + { + var exportedItems = new List(); + + const string testKey1 = "key1"; + const string testValue1 = "value1"; + const string testKey2 = "key2"; + const string testValue2 = "value2"; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(SourceName) + .AddTraceEnricher(bag => bag.Add(testKey1, testValue1)) + .AddTraceEnricher(bag => bag.Add(testKey2, testValue2)) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var source1 = new ActivitySource(SourceName); + + using (var activity = source1.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == testKey1); + Assert.Equal(testValue1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == testKey2); + Assert.Equal(testValue2, tagObject2.Single().Value); + } + } + + [Fact] + public void AddTraceEnricherFactoryRegistersEnricher() + { + var exportedItems = new List(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(SourceName) + .AddTraceEnricher(sp => new MyTraceEnricher()) + .AddTraceEnricher(sp => new MyTraceEnricher2()) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var source1 = new ActivitySource(SourceName); + + using (var activity = source1.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == MyTraceEnricher.Key); + Assert.Equal(1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == MyTraceEnricher2.Key); + Assert.Equal(1, tagObject2.Single().Value); + } + } +} diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs new file mode 100644 index 0000000000..96b4ac80d5 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs @@ -0,0 +1,194 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Enrichment.Tests; + +public sealed class OpenTelemetryEnrichmentServiceCollectionExtensionsTests +{ + private const string SourceName = nameof(OpenTelemetryEnrichmentServiceCollectionExtensionsTests); + + [Fact] + public async Task AddTraceEnricherOfTRegistersEnricher() + { + var exportedItems = new List(); + + using var host = Host.CreateDefaultBuilder() + .ConfigureServices(services => services + .AddOpenTelemetry() + .WithTracing(builder => builder + .AddSource(SourceName) + .AddInMemoryExporter(exportedItems)) + .Services + .AddTraceEnricher() + .AddTraceEnricher()) + .Build(); + + await host.StartAsync().ConfigureAwait(false); + + var enrichers = host.Services.GetServices().ToArray(); + Assert.NotNull(enrichers); + Assert.Equal(2, enrichers.Length); + + using var source = new ActivitySource(SourceName); + using (var activity = source.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Equal(1, (enrichers[0] as MyTraceEnricher).TimesCalled); + Assert.Equal(1, (enrichers[1] as MyTraceEnricher2).TimesCalled); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == MyTraceEnricher.Key); + Assert.Equal(1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == MyTraceEnricher2.Key); + Assert.Equal(1, tagObject2.Single().Value); + } + + await host.StopAsync().ConfigureAwait(false); + } + + [Fact] + public async Task AddTraceEnricherRegistersEnricher() + { + var exportedItems = new List(); + + using var host = Host.CreateDefaultBuilder() + .ConfigureServices(services => services + .AddOpenTelemetry() + .WithTracing(builder => builder + .AddSource(SourceName) + .AddInMemoryExporter(exportedItems)) + .Services + .AddTraceEnricher(new MyTraceEnricher()) + .AddTraceEnricher(new MyTraceEnricher2())) + .Build(); + + await host.StartAsync().ConfigureAwait(false); + + var enrichers = host.Services.GetServices().ToArray(); + Assert.NotNull(enrichers); + Assert.Equal(2, enrichers.Length); + + using var source = new ActivitySource(SourceName); + using (var activity = source.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == MyTraceEnricher.Key); + Assert.Equal(1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == MyTraceEnricher2.Key); + Assert.Equal(1, tagObject2.Single().Value); + } + + await host.StopAsync().ConfigureAwait(false); + } + + [Fact] + public async Task AddTraceEnricherActionRegistersEnricher() + { + var exportedItems = new List(); + + const string testKey1 = "key1"; + const string testValue1 = "value1"; + const string testKey2 = "key2"; + const string testValue2 = "value2"; + + using var host = Host.CreateDefaultBuilder() + .ConfigureServices(services => services + .AddOpenTelemetry() + .WithTracing(builder => builder + .AddSource(SourceName) + .AddInMemoryExporter(exportedItems)) + .Services + .AddTraceEnricher(bag => bag.Add(testKey1, testValue1)) + .AddTraceEnricher(bag => bag.Add(testKey2, testValue2))) + .Build(); + + await host.StartAsync().ConfigureAwait(false); + + using var source1 = new ActivitySource(SourceName); + + using (var activity = source1.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == testKey1); + Assert.Equal(testValue1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == testKey2); + Assert.Equal(testValue2, tagObject2.Single().Value); + } + } + + [Fact] + public async Task AddTraceEnricherFactoryRegistersEnricher() + { + var exportedItems = new List(); + + using var host = Host.CreateDefaultBuilder() + .ConfigureServices(services => services + .AddOpenTelemetry() + .WithTracing(builder => builder + .AddSource(SourceName) + .AddInMemoryExporter(exportedItems)) + .Services + .AddTraceEnricher(sp => new MyTraceEnricher()) + .AddTraceEnricher(sp => new MyTraceEnricher2())) + .Build(); + + await host.StartAsync().ConfigureAwait(false); + + var enrichers = host.Services.GetServices().ToArray(); + Assert.NotNull(enrichers); + Assert.Equal(2, enrichers.Length); + + using var source = new ActivitySource(SourceName); + using (var activity = source.StartActivity(SourceName)) + { + activity.Stop(); + + Assert.Single(exportedItems); + + var tagObjects = exportedItems[0].TagObjects; + var tagObject1 = tagObjects.Where(tag => tag.Key == MyTraceEnricher.Key); + Assert.Equal(1, tagObject1.Single().Value); + + var tagObject2 = tagObjects.Where(tag => tag.Key == MyTraceEnricher2.Key); + Assert.Equal(1, tagObject2.Single().Value); + } + + await host.StopAsync().ConfigureAwait(false); + } +} From 74c6b0107d5633899558f3ed2fc20d1cb85b9224 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 10 Mar 2023 03:28:49 +0000 Subject: [PATCH 0613/1499] [Extensions.AWS] Fix analysis warnings (#952) --- .../AWSTracingPipelineHandler.cs | 100 +++++++++--------- .../Implementation/Utils.cs | 7 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../Tools/HttpResponseMessageBody.cs | 4 +- .../Tools/MockHttpRequest.cs | 2 +- .../Tools/MockWebResponse.cs | 22 ++-- .../Tools/Utils.cs | 2 + 7 files changed, 69 insertions(+), 70 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index c10ca0bd7f..78879e2459 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -57,7 +57,7 @@ public override void InvokeSync(IExecutionContext executionContext) { if (activity != null) { - this.ProcessException(activity, ex); + ProcessException(activity, ex); } throw; @@ -66,7 +66,7 @@ public override void InvokeSync(IExecutionContext executionContext) { if (activity != null) { - this.ProcessEndRequest(executionContext, activity); + ProcessEndRequest(executionContext, activity); } } } @@ -84,7 +84,7 @@ public override async Task InvokeAsync(IExecutionContext executionContext) { if (activity != null) { - this.ProcessException(activity, ex); + ProcessException(activity, ex); } throw; @@ -93,53 +93,14 @@ public override async Task InvokeAsync(IExecutionContext executionContext) { if (activity != null) { - this.ProcessEndRequest(executionContext, activity); + ProcessEndRequest(executionContext, activity); } } return ret; } - private Activity? ProcessBeginRequest(IExecutionContext executionContext) - { - Activity? activity = null; - - var requestContext = executionContext.RequestContext; - var service = AWSServiceHelper.GetAWSServiceName(requestContext); - var operation = AWSServiceHelper.GetAWSOperationName(requestContext); - - activity = AWSSDKActivitySource.StartActivity(service + "." + operation, ActivityKind.Client); - - if (activity == null) - { - return null; - } - - if (this.options.SuppressDownstreamInstrumentation) - { - SuppressInstrumentationScope.Enter(); - } - - if (activity.IsAllDataRequested) - { - activity.SetTag(AWSSemanticConventions.AttributeAWSServiceName, service); - activity.SetTag(AWSSemanticConventions.AttributeAWSOperationName, operation); - var client = executionContext.RequestContext.ClientConfig; - if (client != null) - { - var region = client.RegionEndpoint?.SystemName; - activity.SetTag(AWSSemanticConventions.AttributeAWSRegion, region ?? AWSSDKUtils.DetermineRegion(client.ServiceURL)); - } - - this.AddRequestSpecificInformation(activity, requestContext, service); - } - - AwsPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), requestContext.Request.Headers, Setter); - - return activity; - } - - private void ProcessEndRequest(IExecutionContext executionContext, Activity activity) + private static void ProcessEndRequest(IExecutionContext executionContext, Activity activity) { var responseContext = executionContext.ResponseContext; var requestContext = executionContext.RequestContext; @@ -148,7 +109,7 @@ private void ProcessEndRequest(IExecutionContext executionContext, Activity acti { if (Utils.GetTagValue(activity, AWSSemanticConventions.AttributeAWSRequestId) == null) { - activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, this.FetchRequestId(requestContext, responseContext)); + activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, FetchRequestId(requestContext, responseContext)); } var httpResponse = responseContext.HttpResponse; @@ -156,7 +117,7 @@ private void ProcessEndRequest(IExecutionContext executionContext, Activity acti { int statusCode = (int)httpResponse.StatusCode; - this.AddStatusCodeToActivity(activity, statusCode); + AddStatusCodeToActivity(activity, statusCode); activity.SetTag(AWSSemanticConventions.AttributeHttpResponseContentLength, httpResponse.ContentLength); } } @@ -164,7 +125,7 @@ private void ProcessEndRequest(IExecutionContext executionContext, Activity acti activity.Stop(); } - private void ProcessException(Activity activity, Exception ex) + private static void ProcessException(Activity activity, Exception ex) { if (activity.IsAllDataRequested) { @@ -174,13 +135,13 @@ private void ProcessException(Activity activity, Exception ex) if (ex is AmazonServiceException amazonServiceException) { - this.AddStatusCodeToActivity(activity, (int)amazonServiceException.StatusCode); + AddStatusCodeToActivity(activity, (int)amazonServiceException.StatusCode); activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, amazonServiceException.RequestId); } } } - private void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) + private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) { if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out string parameter)) { @@ -202,12 +163,12 @@ private void AddRequestSpecificInformation(Activity activity, IRequestContext re } } - private void AddStatusCodeToActivity(Activity activity, int status_code) + private static void AddStatusCodeToActivity(Activity activity, int status_code) { activity.SetTag(AWSSemanticConventions.AttributeHttpStatusCode, status_code); } - private string FetchRequestId(IRequestContext requestContext, IResponseContext responseContext) + private static string FetchRequestId(IRequestContext requestContext, IResponseContext responseContext) { string request_id = string.Empty; var response = responseContext.Response; @@ -236,4 +197,41 @@ private string FetchRequestId(IRequestContext requestContext, IResponseContext r return request_id; } + + private Activity? ProcessBeginRequest(IExecutionContext executionContext) + { + var requestContext = executionContext.RequestContext; + var service = AWSServiceHelper.GetAWSServiceName(requestContext); + var operation = AWSServiceHelper.GetAWSOperationName(requestContext); + + Activity? activity = AWSSDKActivitySource.StartActivity(service + "." + operation, ActivityKind.Client); + + if (activity == null) + { + return null; + } + + if (this.options.SuppressDownstreamInstrumentation) + { + SuppressInstrumentationScope.Enter(); + } + + if (activity.IsAllDataRequested) + { + activity.SetTag(AWSSemanticConventions.AttributeAWSServiceName, service); + activity.SetTag(AWSSemanticConventions.AttributeAWSOperationName, operation); + var client = executionContext.RequestContext.ClientConfig; + if (client != null) + { + var region = client.RegionEndpoint?.SystemName; + activity.SetTag(AWSSemanticConventions.AttributeAWSRegion, region ?? AWSSDKUtils.DetermineRegion(client.ServiceURL)); + } + + AddRequestSpecificInformation(activity, requestContext, service); + } + + AwsPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), requestContext.Request.Headers, Setter); + + return activity; + } } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs index ff51298620..45f44990fa 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Collections.Generic; using System.Diagnostics; @@ -25,7 +26,7 @@ internal class Utils { foreach (KeyValuePair tag in activity.TagObjects) { - if (tag.Key.Equals(tagName)) + if (tag.Key.Equals(tagName, StringComparison.Ordinal)) { return tag.Value; } @@ -41,7 +42,7 @@ internal static string RemoveSuffix(string originalString, string suffix) return string.Empty; } - if (originalString.EndsWith(suffix)) + if (originalString.EndsWith(suffix, StringComparison.Ordinal)) { return originalString.Substring(0, originalString.Length - suffix.Length); } @@ -69,7 +70,7 @@ private static string RemovePrefix(string originalString, string prefix) return string.Empty; } - if (originalString.StartsWith(prefix)) + if (originalString.StartsWith(prefix, StringComparison.Ordinal)) { return originalString.Substring(prefix.Length); } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index 526d152eec..47063958d0 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -41,7 +41,7 @@ public static TracerProviderBuilder AddAWSInstrumentation( var awsClientOptions = new AWSClientInstrumentationOptions(); configure?.Invoke(awsClientOptions); - new AWSClientsInstrumentation(awsClientOptions); + _ = new AWSClientsInstrumentation(awsClientOptions); builder.AddSource("Amazon.AWS.AWSClientInstrumentation"); return builder; } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index 65edbf905b..80f6d26bfa 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -26,8 +26,8 @@ internal class HttpResponseMessageBody : IHttpResponseBody { private HttpClient? httpClient; private HttpResponseMessage response; - private bool disposeClient = false; - private bool disposed = false; + private bool disposeClient; + private bool disposed; public HttpResponseMessageBody(HttpResponseMessage response, HttpClient? httpClient, bool disposeClient) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index d253897b8b..a6229f8d29 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -32,7 +32,7 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; #if NET452 internal class MockHttpRequest : IHttpRequest { - private Stream? requestStream = null; + private Stream? requestStream; public MockHttpRequest(Uri requestUri, Action? action, Func? responseCreator = null) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index cad99085df..326bdfa0f8 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -19,7 +19,6 @@ #if NET452 using System.IO; #endif -using System.Linq; using System.Net; #if !NET452 using System.Net.Http; @@ -130,30 +129,30 @@ public static HttpResponse ParseRawReponse(string rawResponse) var responseLines = rawResponse.Split('\n'); - if (responseLines.Count() == 0) + if (responseLines.Length == 0) { throw new ArgumentException( "The resource does not contain a valid HTTP response.", - "resourceName"); + nameof(rawResponse)); } response.StatusLine = responseLines[0]; var currentLine = responseLines[0]; - var statusCode = ParseStatusCode(currentLine); + _ = ParseStatusCode(currentLine); - var lineIndex = 0; - if (responseLines.Count() > 1) + int lineIndex; + if (responseLines.Length > 1) { - for (lineIndex = 1; lineIndex < responseLines.Count(); lineIndex++) + for (lineIndex = 1; lineIndex < responseLines.Length; lineIndex++) { currentLine = responseLines[lineIndex]; - if (currentLine.Trim() == string.Empty) + if (string.IsNullOrEmpty(currentLine.Trim())) { currentLine = responseLines[lineIndex - 1]; break; } - var index = currentLine.IndexOf(":"); + var index = currentLine.IndexOf(":", StringComparison.Ordinal); if (index != -1) { var headerKey = currentLine.Substring(0, index); @@ -163,17 +162,16 @@ public static HttpResponse ParseRawReponse(string rawResponse) } } - var startOfBody = rawResponse.IndexOf(currentLine) + currentLine.Length; + var startOfBody = rawResponse.IndexOf(currentLine, StringComparison.Ordinal) + currentLine.Length; response.Body = rawResponse.Substring(startOfBody).Trim(); return response; } private static HttpStatusCode ParseStatusCode(string? statusLine) { - var statusCode = string.Empty; try { - statusCode = (statusLine ?? string.Empty).Split(' ')[1]; + string statusCode = statusLine?.Split(' ')[1] ?? string.Empty; return (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), statusCode); } catch (Exception exception) diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs index 211e7242fa..6f060b217d 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -59,7 +59,9 @@ public static string GetResourceText(string resourceName) public static string FindResourceName(string partialName) { +#pragma warning disable CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf' return FindResourceName(s => s.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) >= 0).SingleOrDefault(); +#pragma warning restore CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf' } public static IEnumerable FindResourceName(Predicate match) From 9dd714ac7110da7ffc38357a3f0006a0bc811bb4 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Fri, 10 Mar 2023 21:22:28 +0200 Subject: [PATCH 0614/1499] Add options support to EntityFrameworkCore instrumentation (#1020) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + .../CHANGELOG.md | 5 + ...Instrumentation.EntityFrameworkCore.csproj | 5 +- .../README.md | 108 +++++++++++++++++- .../TracerProviderBuilderExtensions.cs | 32 +++++- .../DependencyInjectionConfigTests.cs | 65 +++++++++++ ...mentation.EntityFrameworkCore.Tests.csproj | 2 +- 7 files changed, 207 insertions(+), 11 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 0288dcace5..e1de3a6e74 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -8,4 +8,5 @@ OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentation OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 0932c9f920..a10413b0cd 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added overloads which accept a name to the `TracerProviderBuilder` + `EntityFrameworkInstrumentationOptions` extension to allow for more fine-grained + options management + ([#1020](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1020)) + ## 1.0.0-beta.5 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index b5ac491519..7cb47060c4 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET @@ -8,7 +8,8 @@ - + + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index 00a9ef753b..48a3cd970b 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -3,13 +3,113 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EntityFrameworkCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) -Automatically instruments the outgoing database requests from -[Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore). +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments +[Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore) +and collects traces about outgoing requests. -## Installation +**Note: This component is based on the OpenTelemetry semantic conventions for +[metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) +and +[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +These conventions are +[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), +and hence, this package is a +[pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). +Until a [stable +version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be [breaking changes](./CHANGELOG.md). You can track the +progress from +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** + +## Steps to enable OpenTelemetry.Instrumentation.EntityFrameworkCore + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.EntityFrameworkCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) +package. Also, add any other instrumentations & exporters you will need. ```shell -dotnet add package OpenTelemetry.Instrumentation.EntityFrameworkCore +dotnet add package --prerelease OpenTelemetry.Instrumentation.EntityFrameworkCore +``` + +### Step 2: Enable EntityFrameworkCore Instrumentation at application startup + +`EntityFrameworkCore` instrumentation must be enabled at application startup. + +The following example demonstrates adding `EntityFrameworkCore` +instrumentation to a console application. This example also sets up the +OpenTelemetry Console exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Trace; +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddEntityFrameworkCoreInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +For an ASP.NET Core application, adding instrumentation is typically done in +the `ConfigureServices` of your `Startup` class. Refer to documentation for +[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). + +For an ASP.NET application, adding instrumentation is typically done in the +`Global.asax.cs`. Refer to the documentation for +[OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). + +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`EntityFrameworkInstrumentationOptions`. + +```csharp +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddEntityFrameworkCoreInstrumentation(options => + { + options.EnrichWithIDbCommand = (activity, command) => + { + var stateDisplayName = $"{command.CommandType} main"; + activity.DisplayName = stateDisplayName; + activity.SetTag("db.name", stateDisplayName); + }; + }) + .AddConsoleExporter()); +``` + +When used with +[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md), +all configurations to `EntityFrameworkInstrumentationOptions` +can be done in the `ConfigureServices` method of you applications `Startup` +class as shown below. + +```csharp +// Configure +services.Configure(options => +{ + options.EnrichWithIDbCommand = (activity, command) => + { + var stateDisplayName = $"{command.CommandType} main"; + activity.DisplayName = stateDisplayName; + activity.SetTag("db.name", stateDisplayName); + }; +}); + +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddEntityFrameworkCoreInstrumentation() + .AddConsoleExporter()); ``` ## References diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 8aa9e3d6c1..2240cb090c 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.EntityFrameworkCore; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; using OpenTelemetry.Internal; @@ -32,7 +34,8 @@ public static class TracerProviderBuilderExtensions /// being configured. /// The instance of to chain the calls. public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( - this TracerProviderBuilder builder) => AddEntityFrameworkCoreInstrumentation(builder, configure: null); + this TracerProviderBuilder builder) => + AddEntityFrameworkCoreInstrumentation(builder, name: null, configure: null); /// /// Enables Microsoft.EntityFrameworkCore instrumentation. @@ -42,14 +45,35 @@ public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( this TracerProviderBuilder builder, + Action configure) => + AddEntityFrameworkCoreInstrumentation(builder, name: null, configure); + + /// + /// Enables Microsoft.EntityFrameworkCore instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// EntityFrameworkCore configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( + this TracerProviderBuilder builder, + string name, Action configure) { Guard.ThrowIfNull(builder); - var options = new EntityFrameworkInstrumentationOptions(); - configure?.Invoke(options); + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } - builder.AddInstrumentation(() => new EntityFrameworkInstrumentation(options)); + builder.AddInstrumentation(sp => + { + var options = sp.GetRequiredService>().Get(name); + return new EntityFrameworkInstrumentation(options); + }); builder.AddSource(EntityFrameworkDiagnosticListener.ActivitySourceName); diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs new file mode 100644 index 0000000000..2832d20da8 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs @@ -0,0 +1,65 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests; + +public class DependencyInjectionConfigTests +{ + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public async Task TestTracingOptionsDiConfig(string name) + { + bool optionsPickedFromDi = false; + + var services = new ServiceCollection(); + + services + .Configure(name, _ => optionsPickedFromDi = true) + .AddOpenTelemetry() + .WithTracing(builder => + builder.AddEntityFrameworkCoreInstrumentation(name, configure: null)); + + var sp = services.BuildServiceProvider(); + + try + { + foreach (var hostedService in sp.GetServices()) + { + await hostedService.StartAsync(CancellationToken.None); + } + + Assert.True(optionsPickedFromDi); + } + finally + { + foreach (var hostedService in sp.GetServices().Reverse()) + { + await hostedService.StopAsync(CancellationToken.None); + } + + await sp.DisposeAsync(); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index f7d381ba8e..d98e5a9248 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -29,7 +29,7 @@ - + From 7fda8d43b3d2c7a3f314df88063b28b4ea2078bb Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 10 Mar 2023 19:49:27 +0000 Subject: [PATCH 0615/1499] [Extensions.AWSXRay] Fix analysis warnings (#951) --- .../AWSXRayIdGenerator.cs | 6 +++ .../Resources/AWSEBSResourceDetector.cs | 10 +++-- .../Resources/AWSEC2ResourceDetector.cs | 24 +++++----- .../Resources/AWSECSResourceDetector.cs | 12 ++--- .../Resources/AWSEKSResourceDetector.cs | 36 ++++++++------- .../Resources/AWSLambdaResourceDetector.cs | 4 +- .../ServerCertificateValidationProvider.cs | 44 +++++++++---------- .../Resources/ResourceDetectorUtils.cs | 8 +++- .../Trace/AWSXRayPropagator.cs | 5 ++- .../Resources/TestAWSEBSResourceDetector.cs | 6 +-- .../Resources/TestAWSEC2ResourceDetector.cs | 7 +-- .../Resources/TestAWSECSResourceDetector.cs | 12 ++--- .../Resources/TestAWSEKSResourceDetector.cs | 18 +++----- .../Trace/TestAWSXRayPropagator.cs | 5 +++ 14 files changed, 101 insertions(+), 96 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs index 32380686f6..7741963524 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs @@ -41,6 +41,7 @@ public static class AWSXRayIdGenerator internal static void ReplaceTraceId(Sampler? sampler = null) { +#pragma warning disable CA2000 // Dispose objects before losing scope var awsXRayActivityListener = new ActivityListener { ActivityStarted = (activity) => @@ -63,6 +64,7 @@ internal static void ReplaceTraceId(Sampler? sampler = null) ShouldListenTo = (_) => true, }; +#pragma warning restore CA2000 // Dispose objects before losing scope ActivitySource.AddActivityListener(awsXRayActivityListener); } @@ -141,7 +143,9 @@ private static string GenerateHexNumber(int digits) /// An array of bytes to contain random numbers. private static void NextBytes(byte[] buffer) { +#pragma warning disable CA5394 // Do not use insecure randomness Global.NextBytes(buffer); +#pragma warning restore CA5394 // Do not use insecure randomness } /// @@ -151,7 +155,9 @@ private static void NextBytes(byte[] buffer) /// A 32-bit signed integer that is greater than or equal to 0, and less than maxValue. private static int Next(int maxValue) { +#pragma warning disable CA5394 // Do not use insecure randomness return Global.Next(maxValue); +#pragma warning restore CA5394 // Do not use insecure randomness } private static ActivitySamplingResult ComputeRootActivitySamplingResult( diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs index 141464c14e..7e30090643 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs @@ -29,7 +29,9 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; public class AWSEBSResourceDetector : IResourceDetector { private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; +#if NETSTANDARD private const string AWSEBSMetadataLinuxFilePath = "/var/elasticbeanstalk/xray/environment.conf"; +#endif /// /// Detector the required and optional resource attributes from AWS ElasticBeanstalk. @@ -55,9 +57,9 @@ public class AWSEBSResourceDetector : IResourceDetector filePath = AWSEBSMetadataWindowsFilePath; #endif - var metadata = this.GetEBSMetadata(filePath); + var metadata = GetEBSMetadata(filePath); - resourceAttributes = this.ExtractResourceAttributes(metadata); + resourceAttributes = ExtractResourceAttributes(metadata); } catch (Exception ex) { @@ -67,7 +69,7 @@ public class AWSEBSResourceDetector : IResourceDetector return resourceAttributes; } - internal List>? ExtractResourceAttributes(AWSEBSMetadataModel? metadata) + internal static List>? ExtractResourceAttributes(AWSEBSMetadataModel? metadata) { var resourceAttributes = new List>() { @@ -82,7 +84,7 @@ public class AWSEBSResourceDetector : IResourceDetector return resourceAttributes; } - internal AWSEBSMetadataModel? GetEBSMetadata(string filePath) + internal static AWSEBSMetadataModel? GetEBSMetadata(string filePath) { return ResourceDetectorUtils.DeserializeFromFile(filePath); } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs index b6c5908929..9b613bd2b2 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs @@ -41,11 +41,11 @@ public class AWSEC2ResourceDetector : IResourceDetector try { - var token = this.GetAWSEC2Token(); - var identity = this.GetAWSEC2Identity(token); - var hostName = this.GetAWSEC2HostName(token); + var token = GetAWSEC2Token(); + var identity = GetAWSEC2Identity(token); + var hostName = GetAWSEC2HostName(token); - resourceAttributes = this.ExtractResourceAttributes(identity, hostName); + resourceAttributes = ExtractResourceAttributes(identity, hostName); } catch (Exception ex) { @@ -55,7 +55,7 @@ public class AWSEC2ResourceDetector : IResourceDetector return resourceAttributes; } - internal List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel? identity, string hostName) + internal static List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel? identity, string hostName) { var resourceAttributes = new List>() { @@ -72,30 +72,30 @@ public class AWSEC2ResourceDetector : IResourceDetector return resourceAttributes; } - internal AWSEC2IdentityDocumentModel? DeserializeResponse(string response) + internal static AWSEC2IdentityDocumentModel? DeserializeResponse(string response) { return ResourceDetectorUtils.DeserializeFromString(response); } - private string GetAWSEC2Token() + private static string GetAWSEC2Token() { return ResourceDetectorUtils.SendOutRequest(AWSEC2MetadataTokenUrl, "PUT", new KeyValuePair(AWSEC2MetadataTokenTTLHeader, "60")).Result; } - private AWSEC2IdentityDocumentModel? GetAWSEC2Identity(string token) + private static AWSEC2IdentityDocumentModel? GetAWSEC2Identity(string token) { - var identity = this.GetIdentityResponse(token); - var identityDocument = this.DeserializeResponse(identity); + var identity = GetIdentityResponse(token); + var identityDocument = DeserializeResponse(identity); return identityDocument; } - private string GetIdentityResponse(string token) + private static string GetIdentityResponse(string token) { return ResourceDetectorUtils.SendOutRequest(AWSEC2IdentityDocumentUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; } - private string GetAWSEC2HostName(string token) + private static string GetAWSEC2HostName(string token) { return ResourceDetectorUtils.SendOutRequest(AWSEC2HostNameUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index 9331685a8e..b33b37568a 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -36,16 +36,16 @@ public class AWSECSResourceDetector : IResourceDetector { List>? resourceAttributes = null; - if (!this.IsECSProcess()) + if (!IsECSProcess()) { return resourceAttributes; } try { - var containerId = this.GetECSContainerId(AWSECSMetadataPath); + var containerId = GetECSContainerId(AWSECSMetadataPath); - resourceAttributes = this.ExtractResourceAttributes(containerId); + resourceAttributes = ExtractResourceAttributes(containerId); } catch (Exception ex) { @@ -55,7 +55,7 @@ public class AWSECSResourceDetector : IResourceDetector return resourceAttributes; } - internal List> ExtractResourceAttributes(string? containerId) + internal static List> ExtractResourceAttributes(string? containerId) { var resourceAttributes = new List>() { @@ -67,7 +67,7 @@ public class AWSECSResourceDetector : IResourceDetector return resourceAttributes; } - internal string? GetECSContainerId(string path) + internal static string? GetECSContainerId(string path) { string? containerId = null; @@ -87,7 +87,7 @@ public class AWSECSResourceDetector : IResourceDetector return containerId; } - internal bool IsECSProcess() + internal static bool IsECSProcess() { return Environment.GetEnvironmentVariable(AWSECSMetadataURLKey) != null || Environment.GetEnvironmentVariable(AWSECSMetadataURLV4Key) != null; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index 51c83c24be..7587506300 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -40,20 +40,20 @@ public class AWSEKSResourceDetector : IResourceDetector /// List of key-value pairs of resource attributes. public IEnumerable>? Detect() { - var credentials = this.GetEKSCredentials(AWSEKSCredentialPath); - var httpClientHandler = Handler.Create(AWSEKSCertificatePath); + var credentials = GetEKSCredentials(AWSEKSCredentialPath); + using var httpClientHandler = Handler.Create(AWSEKSCertificatePath); - if (credentials == null || !this.IsEKSProcess(credentials, httpClientHandler)) + if (credentials == null || !IsEKSProcess(credentials, httpClientHandler)) { return null; } - return this.ExtractResourceAttributes( - this.GetEKSClusterName(credentials, httpClientHandler), - this.GetEKSContainerId(AWSEKSMetadataFilePath)); + return ExtractResourceAttributes( + GetEKSClusterName(credentials, httpClientHandler), + GetEKSContainerId(AWSEKSMetadataFilePath)); } - internal List> ExtractResourceAttributes(string? clusterName, string? containerId) + internal static List> ExtractResourceAttributes(string? clusterName, string? containerId) { var resourceAttributes = new List>() { @@ -74,11 +74,11 @@ public class AWSEKSResourceDetector : IResourceDetector return resourceAttributes; } - internal string? GetEKSCredentials(string path) + internal static string? GetEKSCredentials(string path) { try { - StringBuilder stringBuilder = new StringBuilder(); + var stringBuilder = new StringBuilder(); using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) { @@ -88,7 +88,9 @@ public class AWSEKSResourceDetector : IResourceDetector } } - return "Bearer " + stringBuilder.ToString(); + stringBuilder.Insert(0, "Bearer "); + + return stringBuilder.ToString(); } catch (Exception ex) { @@ -98,7 +100,7 @@ public class AWSEKSResourceDetector : IResourceDetector return null; } - internal string? GetEKSContainerId(string path) + internal static string? GetEKSContainerId(string path) { try { @@ -122,17 +124,17 @@ public class AWSEKSResourceDetector : IResourceDetector return null; } - internal AWSEKSClusterInformationModel? DeserializeResponse(string response) + internal static AWSEKSClusterInformationModel? DeserializeResponse(string response) { return ResourceDetectorUtils.DeserializeFromString(response); } - private string? GetEKSClusterName(string credentials, HttpClientHandler? httpClientHandler) + private static string? GetEKSClusterName(string credentials, HttpClientHandler? httpClientHandler) { try { - var clusterInfo = this.GetEKSClusterInfo(credentials, httpClientHandler); - return this.DeserializeResponse(clusterInfo)?.Data?.ClusterName; + var clusterInfo = GetEKSClusterInfo(credentials, httpClientHandler); + return DeserializeResponse(clusterInfo)?.Data?.ClusterName; } catch (Exception ex) { @@ -142,7 +144,7 @@ public class AWSEKSResourceDetector : IResourceDetector return null; } - private bool IsEKSProcess(string credentials, HttpClientHandler? httpClientHandler) + private static bool IsEKSProcess(string credentials, HttpClientHandler? httpClientHandler) { string? awsAuth = null; try @@ -157,7 +159,7 @@ private bool IsEKSProcess(string credentials, HttpClientHandler? httpClientHandl return !string.IsNullOrEmpty(awsAuth); } - private string GetEKSClusterInfo(string credentials, HttpClientHandler? httpClientHandler) + private static string GetEKSClusterInfo(string credentials, HttpClientHandler? httpClientHandler) { return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs index ec163976b7..7da1884ff0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs @@ -38,7 +38,7 @@ public class AWSLambdaResourceDetector : IResourceDetector try { - resourceAttributes = this.ExtractResourceAttributes(); + resourceAttributes = ExtractResourceAttributes(); } catch (Exception ex) { @@ -48,7 +48,7 @@ public class AWSLambdaResourceDetector : IResourceDetector return resourceAttributes; } - internal List> ExtractResourceAttributes() + internal static List> ExtractResourceAttributes() { var resourceAttributes = new List>() { diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs index 03d725dbd2..fc48b71aac 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs @@ -80,6 +80,27 @@ private static bool LoadCertificateToTrustedCollection(X509Certificate2Collectio } } + private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection) + { + if (collection == null) + { + return false; + } + + foreach (var chainElement in chain.ChainElements) + { + foreach (var certificate in collection) + { + if (Enumerable.SequenceEqual(chainElement.Certificate.GetPublicKey(), certificate.GetPublicKey())) + { + return true; + } + } + } + + return false; + } + private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPolicyErrors errors) { var isSslPolicyPassed = errors == SslPolicyErrors.None || @@ -119,7 +140,7 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli } // check if at least one certificate in the chain is in our trust list - var isTrusted = this.HasCommonCertificate(chain, this.trustedCertificates); + var isTrusted = HasCommonCertificate(chain, this.trustedCertificates); if (!isTrusted) { var serverCertificates = string.Empty; @@ -144,25 +165,4 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli return isSslPolicyPassed && isValidChain && isTrusted; } - - private bool HasCommonCertificate(X509Chain chain, X509Certificate2Collection? collection) - { - if (collection == null) - { - return false; - } - - foreach (var chainElement in chain.ChainElements) - { - foreach (var certificate in collection) - { - if (Enumerable.SequenceEqual(chainElement.Certificate.GetPublicKey(), certificate.GetPublicKey())) - { - return true; - } - } - } - - return false; - } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs index 74509c9cad..2c774d340b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs @@ -27,7 +27,9 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; /// /// Class for resource detector utils. /// +#pragma warning disable CA1052 public class ResourceDetectorUtils +#pragma warning restore CA1052 { internal static async Task SendOutRequest(string url, string method, KeyValuePair header, HttpClientHandler? handler = null) { @@ -37,11 +39,13 @@ internal static async Task SendOutRequest(string url, string method, Key httpRequestMessage.Method = new HttpMethod(method); httpRequestMessage.Headers.Add(header.Key, header.Value); +#pragma warning disable CA2000 // Dispose objects before losing scope var httpClient = handler == null ? new HttpClient() : new HttpClient(handler); - using (var response = await httpClient.SendAsync(httpRequestMessage)) +#pragma warning restore CA2000 // Dispose objects before losing scope + using (var response = await httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false)) { response.EnsureSuccessStatusCode(); - return await response.Content.ReadAsStringAsync(); + return await response.Content.ReadAsStringAsync().ConfigureAwait(false); } } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs index 5e899960cd..73ae58c161 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs @@ -35,7 +35,7 @@ public class AWSXRayPropagator : TextMapPropagator private const char TraceHeaderDelimiter = ';'; private const string RootKey = "Root"; - private const string Version = "1"; + private const char Version = '1'; private const int RandomNumberHexDigits = 24; private const int EpochHexDigits = 8; private const int TotalLength = 35; @@ -232,7 +232,7 @@ internal static bool TryParseOTFormatTraceId(ReadOnlySpan traceId, out Rea return false; } - if (!traceId.StartsWith(Version.AsSpan())) + if (traceId.Length < 1 || traceId[0] != Version) { return false; } @@ -303,6 +303,7 @@ internal static bool TryParseSampleDecision(ReadOnlySpan sampleDecision, o internal static string ToXRayTraceIdFormat(string traceId) { var sb = new StringBuilder(); + sb.Append(Version); sb.Append(TraceIdDelimiter); sb.Append(traceId.Substring(0, EpochHexDigits)); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs index 1b3df6c3e8..47d2587ecc 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs @@ -37,10 +37,9 @@ public void TestDetect() [Fact] public void TestExtractResourceAttributes() { - var ebsResourceDetector = new AWSEBSResourceDetector(); var sampleModel = new SampleAWSEBSMetadataModel(); - var resourceAttributes = ebsResourceDetector.ExtractResourceAttributes(sampleModel).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = AWSEBSResourceDetector.ExtractResourceAttributes(sampleModel).ToDictionary(x => x.Key, x => x.Value); Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); Assert.Equal("aws_elastic_beanstalk", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); @@ -53,8 +52,7 @@ public void TestExtractResourceAttributes() [Fact] public void TestGetEBSMetadata() { - var ebsResourceDetector = new AWSEBSResourceDetector(); - var ebsMetadata = ebsResourceDetector.GetEBSMetadata(AWSEBSMetadataFilePath); + var ebsMetadata = AWSEBSResourceDetector.GetEBSMetadata(AWSEBSMetadataFilePath); Assert.NotNull(ebsMetadata); Assert.Equal("1234567890", ebsMetadata.DeploymentId); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs index 8fff5c438c..23a7ebea8b 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs @@ -35,10 +35,9 @@ public void TestDetect() [Fact] public void TestExtractResourceAttributes() { - var ec2ResourceDetector = new AWSEC2ResourceDetector(); var sampleEC2IdentityDocumentModel = new SampleAWSEC2IdentityDocumentModel(); var hostName = "Test host name"; - var resourceAttributes = ec2ResourceDetector.ExtractResourceAttributes(sampleEC2IdentityDocumentModel, hostName).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = AWSEC2ResourceDetector.ExtractResourceAttributes(sampleEC2IdentityDocumentModel, hostName).ToDictionary(x => x.Key, x => x.Value); Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); Assert.Equal("aws_ec2", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); @@ -55,9 +54,7 @@ public void TestDeserializeResponse() { var ec2IdentityDocument = "{\"accountId\": \"123456789012\", \"architecture\": \"x86_64\", \"availabilityZone\": \"us-east-1a\", \"billingProducts\": null, \"devpayProductCodes\": null, \"marketplaceProductCodes\": null, \"imageId\": \"ami-12345678901234567\", \"instanceId\": \"i-12345678901234567\", \"instanceType\": \"t2.micro\", \"kernelId\": null, \"pendingTime\": \"2021-08-11T22:41:54Z\", \"privateIp\": \"123.456.789.123\", \"ramdiskId\": null, \"region\": \"us-east-1\", \"version\": \"2021-08-11\"}"; - var ec2ResourceDetector = new AWSEC2ResourceDetector(); - - var ec2IdentityDocumentModel = ec2ResourceDetector.DeserializeResponse(ec2IdentityDocument); + var ec2IdentityDocumentModel = AWSEC2ResourceDetector.DeserializeResponse(ec2IdentityDocument); Assert.NotNull(ec2IdentityDocumentModel); Assert.Equal("123456789012", ec2IdentityDocumentModel.AccountId); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs index 73223bb2a7..daf37dabda 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs @@ -40,10 +40,9 @@ public void TestDetect() [Fact] public void TestExtractResourceAttributes() { - var ecsResourceDetector = new AWSECSResourceDetector(); var containerId = "Test container id"; - var resourceAttributes = ecsResourceDetector.ExtractResourceAttributes(containerId).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = AWSECSResourceDetector.ExtractResourceAttributes(containerId).ToDictionary(x => x.Key, x => x.Value); Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); Assert.Equal("aws_ecs", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); @@ -53,8 +52,7 @@ public void TestExtractResourceAttributes() [Fact] public void TestGetECSContainerId() { - var ecsResourceDetector = new AWSECSResourceDetector(); - var ecsContainerId = ecsResourceDetector.GetECSContainerId(AWSECSMetadataFilePath); + var ecsContainerId = AWSECSResourceDetector.GetECSContainerId(AWSECSMetadataFilePath); Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", ecsContainerId); } @@ -65,8 +63,7 @@ public void TestIsECSProcess() Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, "TestECSURIKey"); Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, "TestECSURIV4Key"); - var ecsResourceDetector = new AWSECSResourceDetector(); - var isEcsProcess = ecsResourceDetector.IsECSProcess(); + var isEcsProcess = AWSECSResourceDetector.IsECSProcess(); Assert.True(isEcsProcess); } @@ -74,8 +71,7 @@ public void TestIsECSProcess() [Fact] public void TestIsNotECSProcess() { - var ecsResourceDetector = new AWSECSResourceDetector(); - var isEcsProcess = ecsResourceDetector.IsECSProcess(); + var isEcsProcess = AWSECSResourceDetector.IsECSProcess(); Assert.False(isEcsProcess); } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index d7689835be..bae0540d8f 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -38,11 +38,10 @@ public void TestDetect() [Fact] public void TestExtractResourceAttributes() { - var eksResourceDetector = new AWSEKSResourceDetector(); var clusterName = "Test cluster name"; var containerId = "Test container id"; - var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, containerId).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = AWSEKSResourceDetector.ExtractResourceAttributes(clusterName, containerId).ToDictionary(x => x.Key, x => x.Value); Assert.Equal(4, resourceAttributes.Count); Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); @@ -54,10 +53,9 @@ public void TestExtractResourceAttributes() [Fact] public void TestExtractResourceAttributesWithEmptyClusterName() { - var eksResourceDetector = new AWSEKSResourceDetector(); var containerId = "Test container id"; - var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(string.Empty, containerId).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = AWSEKSResourceDetector.ExtractResourceAttributes(string.Empty, containerId).ToDictionary(x => x.Key, x => x.Value); // Validate the count of resourceAttributes -> Excluding cluster name, there will be only three resourceAttributes Assert.Equal(3, resourceAttributes.Count); @@ -69,10 +67,9 @@ public void TestExtractResourceAttributesWithEmptyClusterName() [Fact] public void TestExtractResourceAttributesWithEmptyContainerId() { - var eksResourceDetector = new AWSEKSResourceDetector(); var clusterName = "Test cluster name"; - var resourceAttributes = eksResourceDetector.ExtractResourceAttributes(clusterName, string.Empty).ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = AWSEKSResourceDetector.ExtractResourceAttributes(clusterName, string.Empty).ToDictionary(x => x.Key, x => x.Value); // Validate the count of resourceAttributes -> Excluding container id, there will be only three resourceAttributes Assert.Equal(3, resourceAttributes.Count); @@ -84,8 +81,7 @@ public void TestExtractResourceAttributesWithEmptyContainerId() [Fact] public void TestGetEKSCredentials() { - var eksResourceDetector = new AWSEKSResourceDetector(); - var eksCredentials = eksResourceDetector.GetEKSCredentials(AWSEKSCredentialsPath); + var eksCredentials = AWSEKSResourceDetector.GetEKSCredentials(AWSEKSCredentialsPath); Assert.Equal("Bearer Test AWS EKS Token", eksCredentials); } @@ -93,8 +89,7 @@ public void TestGetEKSCredentials() [Fact] public void TestGetEKSContainerId() { - var eksResourceDetector = new AWSEKSResourceDetector(); - var eksContainerId = eksResourceDetector.GetEKSContainerId(AWSEKSMetadataFilePath); + var eksContainerId = AWSEKSResourceDetector.GetEKSContainerId(AWSEKSMetadataFilePath); Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", eksContainerId); } @@ -104,8 +99,7 @@ public void TestDeserializeResponse() { var awsEKSClusterInformation = "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": {\"name\": \"cluster-info\", \"namespace\": \"amazon-cloudwatch\", \"selfLink\": \"/api/v1/namespaces/amazon-cloudwatch/configmaps/cluster-info\", \"uid\": \"0734438c-48f4-45c3-b06d-b6f16f7f0e1e\", \"resourceVersion\": \"25911\", \"creationTimestamp\": \"2021-07-23T18:41:56Z\", \"annotations\": {\"kubectl.kubernetes.io/last-applied-configuration\": \"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"cluster.name\\\":\\\"Test\\\",\\\"logs.region\\\":\\\"us-west-2\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"cluster-info\\\",\\\"namespace\\\":\\\"amazon-cloudwatch\\\"}}\\n\"}}, \"data\": {\"cluster.name\": \"Test\", \"logs.region\": \"us-west-2\"}}"; - var eksResourceDetector = new AWSEKSResourceDetector(); - var eksClusterInformation = eksResourceDetector.DeserializeResponse(awsEKSClusterInformation); + var eksClusterInformation = AWSEKSResourceDetector.DeserializeResponse(awsEKSClusterInformation); Assert.NotNull(eksClusterInformation); Assert.NotNull(eksClusterInformation.Data); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs index a3d4f8f80e..a314b89850 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs @@ -29,7 +29,12 @@ public class TestAWSXRayPropagator private const string TraceId = "5759e988bd862e3fe1be46a994272793"; private const string ParentId = "53995c3f42cd8ad8"; +#if NETFRAMEWORK private static readonly string[] Empty = new string[0]; +#else + private static readonly string[] Empty = Array.Empty(); +#endif + private static readonly Func, string, IEnumerable> Getter = (headers, name) => { if (headers.TryGetValue(name, out var value)) From 5f33458de1bd1825f7377b4ddda4d1219ac07ddf Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Mon, 13 Mar 2023 18:48:13 +0100 Subject: [PATCH 0616/1499] Add ECS and Logs attributes based on Metadata v4 endpoint (#875) --- .../Properties/launchSettings.json | 27 ++- .../.publicApi/net452/PublicAPI.Unshipped.txt | 1 - .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../PublicAPI.Unshipped.txt} | 11 +- .../netstandard2.0/PublicAPI.Shipped.txt | 2 - .../netstandard2.0/PublicAPI.Unshipped.txt | 20 +++ .../CHANGELOG.md | 11 ++ ...elemetry.Contrib.Extensions.AWSXRay.csproj | 6 +- .../Resources/AWSEBSResourceDetector.cs | 43 +++-- .../Resources/AWSEC2ResourceDetector.cs | 55 ++++-- .../Resources/AWSECSResourceDetector.cs | 143 ++++++++++++++-- .../Resources/AWSEKSResourceDetector.cs | 24 +-- .../Resources/AWSLambdaResourceDetector.cs | 25 ++- .../Resources/AWSSemanticConventions.cs | 14 ++ .../Resources/IResourceDetector.cs | 32 ---- .../Resources/ResourceBuilderExtensions.cs | 46 ----- .../Resources/ResourceDetectorUtils.cs | 7 +- ...ry.Contrib.Extensions.AWSXRay.Tests.csproj | 26 ++- .../Resources/TestAWSEBSResourceDetector.cs | 6 +- .../Resources/TestAWSEC2ResourceDetector.cs | 6 +- .../Resources/TestAWSECSResourceDetector.cs | 157 +++++++++++++++--- .../Resources/TestAWSEKSResourceDetector.cs | 6 +- .../TestAWSLambdaResourceDetector.cs | 3 +- .../TestResourceBuilderExtensions.cs | 54 ------ .../metadatav4-response-container-ec2.json | 44 +++++ ...metadatav4-response-container-fargate.json | 50 ++++++ .../metadatav4-response-task-ec2.json | 94 +++++++++++ .../metadatav4-response-task-fargate.json | 77 +++++++++ 28 files changed, 712 insertions(+), 279 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Shipped.txt rename src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/{net452/PublicAPI.Shipped.txt => net462/PublicAPI.Unshipped.txt} (69%) delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs delete mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-ec2.json create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-fargate.json create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-ec2.json create mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-fargate.json diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json index 7a842180a4..734290b4b9 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json @@ -1,14 +1,13 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "Examples.GrpcCore.AspNetCore": { - "commandName": "Project", - "dotnetRunMessages": "true", - "launchBrowser": true, - "applicationUrl": "http://localhost:5000/weatherforecast", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "Examples.GrpcCore.AspNetCore": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "http://localhost:5000/weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Unshipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..815c92006a --- /dev/null +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt similarity index 69% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt index c9c69207b1..1c7d693b10 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net452/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,22 +1,17 @@ -#nullable enable OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void -OpenTelemetry.Resources.ResourceBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void -static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder! resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector! resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 0c8b8d923f..724b124e9b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -21,11 +21,9 @@ OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void -OpenTelemetry.Resources.ResourceBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void -static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder! resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector! resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7dc5c58110..ad1e9026fa 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1,21 @@ #nullable enable +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> +OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>?' +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Resources.ResourceBuilderExtensions +*REMOVED*static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index 2a694f0725..0b3cb1d475 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -5,6 +5,17 @@ * Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random instance instead of recreating with ThreadLocal ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) +* Raised minimum .NET version to `net462` + ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) +* Updated OTel SDK package version to 1.3.1 + ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) +* Enhancement - AWSECSResourceDetector - Implement `aws.{ecs.*,log.*}` resource + attributes with data from ECS Metadata endpoint v4 + ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) +* Removal - IResourceDetector - Remove local IResourceDetector interface and its + supporting ResourceBuilderExtensions extension, and migrate all detectors to + implement OpenTelemetry.Resources.IResourceDetector + ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) ## 1.2.0 diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index e70b11a93c..7dbba22c44 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net452 + netstandard2.0;$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS X-Ray. Extensions.AWSXRay- enable @@ -9,11 +9,11 @@ - + - + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs index 7e30090643..a4175dee53 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs @@ -19,7 +19,9 @@ #if NETSTANDARD using System.Runtime.InteropServices; #endif + using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.Resources; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -36,11 +38,9 @@ public class AWSEBSResourceDetector : IResourceDetector /// /// Detector the required and optional resource attributes from AWS ElasticBeanstalk. /// - /// List of key-value pairs of resource attributes. - public IEnumerable>? Detect() + /// Resource with key-value pairs of resource attributes. + public Resource Detect() { - List>? resourceAttributes = null; - try { string? filePath = null; @@ -59,28 +59,43 @@ public class AWSEBSResourceDetector : IResourceDetector var metadata = GetEBSMetadata(filePath); - resourceAttributes = ExtractResourceAttributes(metadata); + return new Resource(ExtractResourceAttributes(metadata)); } catch (Exception ex) { AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSResourceDetector), ex); } - return resourceAttributes; + return Resource.Empty; } - internal static List>? ExtractResourceAttributes(AWSEBSMetadataModel? metadata) + internal static List> ExtractResourceAttributes(AWSEBSMetadataModel? metadata) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceNamespace, metadata?.EnvironmentName), - new KeyValuePair(AWSSemanticConventions.AttributeServiceInstanceID, metadata?.DeploymentId), - new KeyValuePair(AWSSemanticConventions.AttributeServiceVersion, metadata?.VersionLabel), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), + new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), }; + if (metadata != null) + { + if (metadata.EnvironmentName != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeServiceNamespace, metadata.EnvironmentName)); + } + + if (metadata.DeploymentId != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeServiceInstanceID, metadata.DeploymentId)); + } + + if (metadata.VersionLabel != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeServiceVersion, metadata.VersionLabel)); + } + } + return resourceAttributes; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs index 9b613bd2b2..b1014ddfa0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs @@ -16,7 +16,9 @@ using System; using System.Collections.Generic; + using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.Resources; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -34,41 +36,62 @@ public class AWSEC2ResourceDetector : IResourceDetector /// /// Detector the required and optional resource attributes from AWS EC2. /// - /// List of key-value pairs of resource attributes. - public IEnumerable>? Detect() + /// Resource with key-value pairs of resource attributes. + public Resource Detect() { - List>? resourceAttributes = null; - try { var token = GetAWSEC2Token(); var identity = GetAWSEC2Identity(token); var hostName = GetAWSEC2HostName(token); - resourceAttributes = ExtractResourceAttributes(identity, hostName); + return new Resource(ExtractResourceAttributes(identity, hostName)); } catch (Exception ex) { AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2ResourceDetector), ex); } - return resourceAttributes; + return Resource.Empty; } - internal static List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel? identity, string hostName) + internal static List> ExtractResourceAttributes(AWSEC2IdentityDocumentModel? identity, string hostName) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, identity?.AccountId), - new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity?.AvailabilityZone), - new KeyValuePair(AWSSemanticConventions.AttributeHostID, identity?.InstanceId), - new KeyValuePair(AWSSemanticConventions.AttributeHostType, identity?.InstanceType), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, identity?.Region), - new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), + new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), }; + if (identity != null) + { + if (identity.AccountId != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, identity.AccountId)); + } + + if (identity.AvailabilityZone != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity.AvailabilityZone)); + } + + if (identity.InstanceId != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeHostID, identity.InstanceId)); + } + + if (identity.InstanceType != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeHostType, identity.InstanceType)); + } + + if (identity.Region != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, identity.Region)); + } + } + return resourceAttributes; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index b33b37568a..d252b35bb7 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -16,6 +16,12 @@ using System; using System.Collections.Generic; +using System.Net.Http; +using System.Text.RegularExpressions; + +using Newtonsoft.Json.Linq; + +using OpenTelemetry.Resources; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -31,39 +37,152 @@ public class AWSECSResourceDetector : IResourceDetector /// /// Detector the required and optional resource attributes from AWS ECS. /// - /// List of key-value pairs of resource attributes. - public IEnumerable>? Detect() + /// Resource with key-value pairs of resource attributes. + public Resource Detect() { - List>? resourceAttributes = null; - if (!IsECSProcess()) { - return resourceAttributes; + return Resource.Empty; } + var resourceAttributes = new List>() + { + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), + }; + try { var containerId = GetECSContainerId(AWSECSMetadataPath); + if (containerId != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); + } + } + catch (Exception ex) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); + } - resourceAttributes = ExtractResourceAttributes(containerId); + try + { + resourceAttributes.AddRange(ExtractMetadataV4ResourceAttributes()); } catch (Exception ex) { AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); } - return resourceAttributes; + return new Resource(resourceAttributes); } - internal static List> ExtractResourceAttributes(string? containerId) + internal static List> ExtractMetadataV4ResourceAttributes() { - var resourceAttributes = new List>() + var metadataV4Url = Environment.GetEnvironmentVariable(AWSECSMetadataURLV4Key); + if (metadataV4Url == null) + { + return new List>(); + } + + var httpClientHandler = new HttpClientHandler(); + var metadataV4ContainerResponse = ResourceDetectorUtils.SendOutRequest(metadataV4Url, "GET", null, httpClientHandler).Result; + var metadataV4TaskResponse = ResourceDetectorUtils.SendOutRequest($"{metadataV4Url.TrimEnd('/')}/task", "GET", null, httpClientHandler).Result; + + var containerResponse = JObject.Parse(metadataV4ContainerResponse); + var taskResponse = JObject.Parse(metadataV4TaskResponse); + + var containerArn = containerResponse.Value("ContainerARN"); + if (containerArn == null) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); + return new List>(); + } + + var clusterArn = taskResponse.Value("Cluster"); + if (clusterArn == null) + { + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); + return new List>(); + } + + if (!clusterArn.StartsWith("arn:")) + { + var baseArn = containerArn.Substring(containerArn.LastIndexOf(":")); + clusterArn = $"{baseArn}:cluster/{clusterArn}"; + } + + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), - new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId), + new KeyValuePair(AWSSemanticConventions.AttributeEcsContainerArn, containerArn), + new KeyValuePair(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn), }; + var launchType = taskResponse.Value("LaunchType") switch + { + string type when "ec2".Equals(type.ToLower()) => AWSSemanticConventions.ValueEcsLaunchTypeEc2, + string type when "fargate".Equals(type.ToLower()) => AWSSemanticConventions.ValueEcsLaunchTypeFargate, + _ => null, + }; + + if (launchType != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsLaunchtype, launchType)); + } + else + { + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{taskResponse["LaunchType"]}'")); + } + + var taskArn = taskResponse.Value("TaskARN"); + if (taskArn != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskArn, taskArn)); + } + + var family = taskResponse.Value("Family"); + if (family != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskFamily, family)); + } + + var revision = taskResponse.Value("Revision"); + if (revision != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskRevision, revision)); + } + + if ("awslogs".Equals(containerResponse.Value("LogDriver"))) + { + JObject? logOptions = containerResponse.Value("LogOptions"); + if (logOptions != null) + { + var regex = new Regex(@"arn:aws:ecs:([^:]+):([^:]+):.*"); + var match = regex.Match(containerArn); + + if (!match.Success) + { + throw new ArgumentOutOfRangeException($"Cannot parse region and account from the container ARN '{containerArn}'"); + } + + var logsRegion = match.Groups[1]; + var logsAccount = match.Groups[2]; + + var logGroupName = logOptions.Value("awslogs-group"); + if (logGroupName != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupNames, new string[] { logGroupName })); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:*" })); + + var logStreamName = logOptions.Value("awslogs-stream"); + if (logStreamName != null) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamNames, new string[] { logStreamName })); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:log-stream:{logStreamName}" })); + } + } + } + } + return resourceAttributes; } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs index 7587506300..a03bc0db02 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs @@ -18,8 +18,10 @@ using System.Collections.Generic; using System.Net.Http; using System.Text; + using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.Resources; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -37,38 +39,38 @@ public class AWSEKSResourceDetector : IResourceDetector /// /// Detector the required and optional resource attributes from AWS EKS. /// - /// List of key-value pairs of resource attributes. - public IEnumerable>? Detect() + /// Resource with key-value pairs of resource attributes. + public Resource Detect() { var credentials = GetEKSCredentials(AWSEKSCredentialPath); using var httpClientHandler = Handler.Create(AWSEKSCertificatePath); if (credentials == null || !IsEKSProcess(credentials, httpClientHandler)) { - return null; + return Resource.Empty; } - return ExtractResourceAttributes( + return new Resource(ExtractResourceAttributes( GetEKSClusterName(credentials, httpClientHandler), - GetEKSContainerId(AWSEKSMetadataFilePath)); + GetEKSContainerId(AWSEKSMetadataFilePath))); } - internal static List> ExtractResourceAttributes(string? clusterName, string? containerId) + internal static List> ExtractResourceAttributes(string? clusterName, string? containerId) { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), }; if (!string.IsNullOrEmpty(clusterName)) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeK8SClusterName, clusterName!)); } if (!string.IsNullOrEmpty(containerId)) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeContainerID, containerId!)); } return resourceAttributes; diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs index 7da1884ff0..5db498f547 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using OpenTelemetry.Resources; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -31,32 +32,30 @@ public class AWSLambdaResourceDetector : IResourceDetector /// /// Detector the required and optional resource attributes from AWS Lambda. /// - /// List of key-value pairs of resource attributes. - public IEnumerable>? Detect() + /// Resource with key-value pairs of resource attributes. + public Resource Detect() { - List>? resourceAttributes = null; - try { - resourceAttributes = ExtractResourceAttributes(); + return new Resource(ExtractResourceAttributes()); } catch (Exception ex) { AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSLambdaResourceDetector), ex); } - return resourceAttributes; + return Resource.Empty; } - internal static List> ExtractResourceAttributes() + internal static List> ExtractResourceAttributes() { - var resourceAttributes = new List>() + var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), + new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), + new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), + new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), + new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), }; return resourceAttributes; diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs index 5291bcf77b..afb4341c5b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs @@ -26,6 +26,15 @@ internal static class AWSSemanticConventions public const string AttributeContainerID = "container.id"; + public const string AttributeEcsContainerArn = "aws.ecs.container.arn"; + public const string AttributeEcsClusterArn = "aws.ecs.cluster.arn"; + public const string AttributeEcsLaunchtype = "aws.ecs.launchtype"; + public const string ValueEcsLaunchTypeEc2 = "ec2"; + public const string ValueEcsLaunchTypeFargate = "fargate"; + public const string AttributeEcsTaskArn = "aws.ecs.task.arn"; + public const string AttributeEcsTaskFamily = "aws.ecs.task.family"; + public const string AttributeEcsTaskRevision = "aws.ecs.task.revision"; + public const string AttributeFaasExecution = "faas.execution"; public const string AttributeFaasID = "faas.id"; public const string AttributeFaasName = "faas.name"; @@ -37,6 +46,11 @@ internal static class AWSSemanticConventions public const string AttributeK8SClusterName = "k8s.cluster.name"; + public const string AttributeLogGroupNames = "aws.log.group.names"; + public const string AttributeLogGroupArns = "aws.log.group.arns"; + public const string AttributeLogStreamNames = "aws.log.stream.names"; + public const string AttributeLogStreamArns = "aws.log.stream.arns"; + public const string AttributeServiceName = "service.name"; public const string AttributeServiceNamespace = "service.namespace"; public const string AttributeServiceInstanceID = "service.instance.id"; diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs deleted file mode 100644 index 7ee26bd3af..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/IResourceDetector.cs +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Collections.Generic; - -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; - -/// -/// Resource detector interface. -/// Mocking https://github.com/open-telemetry/opentelemetry-dotnet/blob/6b7f2dd77cf9d37260a853fcc95f7b77e296065d/src/OpenTelemetry/Resources/IResourceDetector.cs. -/// -public interface IResourceDetector -{ - /// - /// Called to get key-value pairs of attribute from detector. - /// - /// List of key-value pairs of resource attributes. - IEnumerable>? Detect(); -} diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs deleted file mode 100644 index 0aa64e40a2..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceBuilderExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Resources; - -/// -/// Extension class for ResourceBuilder. -/// -public static class ResourceBuilderExtensions -{ - /// - /// Add resource detector to ResourceBuilder. - /// - /// being configured. - /// being added. - /// The instance of to chain the calls. - public static ResourceBuilder AddDetector(this ResourceBuilder resourceBuilder, IResourceDetector resourceDetector) - { - Guard.ThrowIfNull(resourceDetector); - - var resourceAttributes = resourceDetector.Detect(); - - if (resourceAttributes != null) - { - resourceBuilder.AddAttributes(resourceAttributes); - } - - return resourceBuilder; - } -} diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs index 2c774d340b..5410c6df44 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs @@ -31,13 +31,16 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; public class ResourceDetectorUtils #pragma warning restore CA1052 { - internal static async Task SendOutRequest(string url, string method, KeyValuePair header, HttpClientHandler? handler = null) + internal static async Task SendOutRequest(string url, string method, KeyValuePair? header, HttpClientHandler? handler = null) { using (var httpRequestMessage = new HttpRequestMessage()) { httpRequestMessage.RequestUri = new Uri(url); httpRequestMessage.Method = new HttpMethod(method); - httpRequestMessage.Headers.Add(header.Key, header.Value); + if (header.HasValue) + { + httpRequestMessage.Headers.Add(header.Value.Key, header.Value.Value); + } #pragma warning disable CA2000 // Dispose objects before losing scope var httpClient = handler == null ? new HttpClient() : new HttpClient(handler); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index a666403913..68fa51593c 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -1,11 +1,8 @@ - Unit test project for AWS X-Ray for OpenTelemetry - - netcoreapp3.1 - $(TargetFrameworks);net452 - enable + net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) @@ -23,11 +20,23 @@ - - + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + - + @@ -35,7 +44,6 @@ - diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs index 47d2587ecc..7c63dc09d9 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs @@ -27,11 +27,7 @@ public class TestAWSEBSResourceDetector [Fact] public void TestDetect() { - var ebsResourceDetector = new AWSEBSResourceDetector(); - - var resourceAttributes = ebsResourceDetector.Detect(); - - Assert.Null(resourceAttributes); // will be null as it's not in ebs environment + Assert.Empty(new AWSEBSResourceDetector().Detect().Attributes); // will be null as it's not in ebs environment } [Fact] diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs index 23a7ebea8b..8750fa7cdd 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs @@ -25,11 +25,7 @@ public class TestAWSEC2ResourceDetector [Fact] public void TestDetect() { - var ec2ResourceDetector = new AWSEC2ResourceDetector(); - - var resourceAttributes = ec2ResourceDetector.Detect(); - - Assert.Null(resourceAttributes); // will be null as it's not in ec2 environment + Assert.Empty(new AWSEC2ResourceDetector().Detect().Attributes); // will be null as it's not in ec2 environment } [Fact] diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs index daf37dabda..4a43a46fd3 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs @@ -15,64 +15,171 @@ // using System; +using System.IO; using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.AspNetCore.Http; + using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; -public class TestAWSECSResourceDetector +public class TestAWSECSResourceDetector : IDisposable { private const string AWSECSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; - [Fact] - public void TestDetect() + public TestAWSECSResourceDetector() { - var ecsResourceDetector = new AWSECSResourceDetector(); - - var resourceAttributes = ecsResourceDetector?.Detect(); + this.ResetEnvironment(); + } - Assert.Null(resourceAttributes); // will be null as it's not in ecs environment + public void Dispose() + { + this.ResetEnvironment(); } [Fact] - public void TestExtractResourceAttributes() + public void TestNotOnEcs() { - var containerId = "Test container id"; - - var resourceAttributes = AWSECSResourceDetector.ExtractResourceAttributes(containerId).ToDictionary(x => x.Key, x => x.Value); - - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_ecs", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("Test container id", resourceAttributes[AWSSemanticConventions.AttributeContainerID]); + Assert.Empty(new AWSECSResourceDetector().Detect().Attributes); } [Fact] public void TestGetECSContainerId() { - var ecsContainerId = AWSECSResourceDetector.GetECSContainerId(AWSECSMetadataFilePath); - - Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", ecsContainerId); + Assert.Equal("a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856", AWSECSResourceDetector.GetECSContainerId(AWSECSMetadataFilePath)); } [Fact] - public void TestIsECSProcess() + public void TestEcsMetadataV3() { Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, "TestECSURIKey"); - Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, "TestECSURIV4Key"); - var isEcsProcess = AWSECSResourceDetector.IsECSProcess(); + var resourceAttributes = new AWSECSResourceDetector().Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); - Assert.True(isEcsProcess); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudProvider], "aws"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform], "aws_ecs"); } [Fact] - public void TestIsNotECSProcess() + public async void TestEcsMetadataV4Ec2() { - var isEcsProcess = AWSECSResourceDetector.IsECSProcess(); + var source = new CancellationTokenSource(); + var token = source.Token; + + await using (var metadataEndpoint = new MockEcsMetadataEndpoint("ecs_metadata/metadatav4-response-container-ec2.json", "ecs_metadata/metadatav4-response-task-ec2.json")) + { + Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, metadataEndpoint.Address.ToString()); + var resourceAttributes = new AWSECSResourceDetector().Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); + + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudProvider], "aws"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsLaunchtype], "ec2"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskFamily], "curltest"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskRevision], "26"); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/metadata" }); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata" }); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/8f03e41243824aea923aca126495f665" }); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665" }); + } + } + + [Fact] + public async void TestEcsMetadataV4Fargate() + { + var source = new CancellationTokenSource(); + var token = source.Token; + + await using (var metadataEndpoint = new MockEcsMetadataEndpoint("ecs_metadata/metadatav4-response-container-fargate.json", "ecs_metadata/metadatav4-response-task-fargate.json")) + { + Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, metadataEndpoint.Address.ToString()); + + var resourceAttributes = new AWSECSResourceDetector().Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); + + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudProvider], "aws"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsLaunchtype], "fargate"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskFamily], "curltest"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskRevision], "3"); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/containerlogs" }); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs" }); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/cd189a933e5849daa93386466019ab50" }); + Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs:log-stream:ecs/curl/cd189a933e5849daa93386466019ab50" }); + } + } - Assert.False(isEcsProcess); + internal void ResetEnvironment() + { + Environment.SetEnvironmentVariable(AWSECSMetadataURLKey, null); + Environment.SetEnvironmentVariable(AWSECSMetadataURLV4Key, null); + } + + internal class MockEcsMetadataEndpoint : IAsyncDisposable + { + public readonly Uri Address; + private readonly string containerJsonPath; + private readonly string taskJsonPath; + private readonly IWebHost server; + + public MockEcsMetadataEndpoint(string containerJsonPath, string taskJsonPath) + { + this.containerJsonPath = containerJsonPath; + this.taskJsonPath = taskJsonPath; + + this.server = new WebHostBuilder() + .UseKestrel() + .UseUrls("http://127.0.0.1:0") // Use random localhost port + .Configure(app => + { + app.Run(async context => + { + if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/") + { + var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/Resources/{containerJsonPath}"); + var data = Encoding.UTF8.GetBytes(content); + context.Response.ContentType = "application/json"; + await context.Response.Body.WriteAsync(data, 0, data.Length); + } + else if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/task") + { + var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/Resources/{taskJsonPath}"); + var data = Encoding.UTF8.GetBytes(content); + context.Response.ContentType = "application/json"; + await context.Response.Body.WriteAsync(data, 0, data.Length); + } + else + { + context.Response.StatusCode = StatusCodes.Status404NotFound; + await context.Response.WriteAsync("Not found"); + } + }); + }).Build(); + this.server.Start(); + + this.Address = new Uri(this.server.ServerFeatures.Get().Addresses.First()); + } + + public async ValueTask DisposeAsync() + { + await this.DisposeAsyncCore(); + } + + protected virtual async ValueTask DisposeAsyncCore() + { + await this.server.StopAsync(); + } } } diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index bae0540d8f..55ed6258b7 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -28,11 +28,7 @@ public class TestAWSEKSResourceDetector [Fact] public void TestDetect() { - var eksResourceDetector = new AWSEKSResourceDetector(); - - var resourceAttributes = eksResourceDetector?.Detect(); - - Assert.Null(resourceAttributes); // will be null as it's not in eks environment + Assert.Empty(new AWSEKSResourceDetector().Detect().Attributes); // will be null as it's not in eks environment } [Fact] diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs index 78a8c3fdd6..0b6a62a1cc 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs @@ -30,8 +30,7 @@ public void TestDetect() Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); - var lambdaResourceDetector = new AWSLambdaResourceDetector(); - var resourceAttributes = lambdaResourceDetector.Detect().ToDictionary(x => x.Key, x => x.Value); + var resourceAttributes = new AWSLambdaResourceDetector().Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs deleted file mode 100644 index 7ce8115975..0000000000 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestResourceBuilderExtensions.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Linq; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; -using OpenTelemetry.Resources; -using OpenTelemetry.Trace; -using Xunit; - -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; - -public class TestResourceBuilderExtensions -{ - [Fact] - public void TestAddDetector() - { - Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); - - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetResourceBuilder(ResourceBuilder - .CreateDefault() - .AddDetector(new AWSLambdaResourceDetector())) // use lambda resource detector here as it doesn't require sending identical http request to aws endpoint - .Build(); - - var resource = tracerProvider.GetResource(); - var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("us-east-1", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); - Assert.Equal("testfunction", resourceAttributes[AWSSemanticConventions.AttributeFaasName]); - Assert.Equal("latest", resourceAttributes[AWSSemanticConventions.AttributeFaasVersion]); - - Environment.SetEnvironmentVariable("AWS_REGION", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", null); - } -} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-ec2.json b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-ec2.json new file mode 100644 index 0000000000..b43c2b0d7d --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-ec2.json @@ -0,0 +1,44 @@ +{ + "DockerId": "ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66", + "Name": "curl", + "DockerName": "ecs-curltest-24-curl-cca48e8dcadd97805600", + "Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest", + "ImageID": "sha256:d691691e9652791a60114e67b365688d20d19940dde7c4736ea30e660d8d3553", + "Labels": { + "com.amazonaws.ecs.cluster": "default", + "com.amazonaws.ecs.container-name": "curl", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/8f03e41243824aea923aca126495f665", + "com.amazonaws.ecs.task-definition-family": "curltest", + "com.amazonaws.ecs.task-definition-version": "24" + }, + "DesiredStatus": "RUNNING", + "KnownStatus": "RUNNING", + "Limits": { + "CPU": 10, + "Memory": 128 + }, + "CreatedAt": "2020-10-02T00:15:07.620912337Z", + "StartedAt": "2020-10-02T00:15:08.062559351Z", + "Type": "NORMAL", + "LogDriver": "awslogs", + "LogOptions": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/metadata", + "awslogs-region": "us-west-2", + "awslogs-stream": "ecs/curl/8f03e41243824aea923aca126495f665" + }, + "ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9", + "Networks": [ + { + "NetworkMode": "awsvpc", + "IPv4Addresses": [ + "10.0.2.100" + ], + "AttachmentIndex": 0, + "MACAddress": "0e:9e:32:c7:48:85", + "IPv4SubnetCIDRBlock": "10.0.2.0/24", + "PrivateDNSName": "ip-10-0-2-100.us-west-2.compute.internal", + "SubnetGatewayIpv4Address": "10.0.2.1/24" + } + ] +} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-fargate.json b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-fargate.json new file mode 100644 index 0000000000..ccbe70bc44 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-fargate.json @@ -0,0 +1,50 @@ +{ + "DockerId": "cd189a933e5849daa93386466019ab50-2495160603", + "Name": "curl", + "DockerName": "curl", + "Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest", + "ImageID": "sha256:25f3695bedfb454a50f12d127839a68ad3caf91e451c1da073db34c542c4d2cb", + "Labels": { + "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-west-2:111122223333:cluster/default", + "com.amazonaws.ecs.container-name": "curl", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/cd189a933e5849daa93386466019ab50", + "com.amazonaws.ecs.task-definition-family": "curltest", + "com.amazonaws.ecs.task-definition-version": "2" + }, + "DesiredStatus": "RUNNING", + "KnownStatus": "RUNNING", + "Limits": { + "CPU": 10, + "Memory": 128 + }, + "CreatedAt": "2020-10-08T20:09:11.44527186Z", + "StartedAt": "2020-10-08T20:09:11.44527186Z", + "Type": "NORMAL", + "Networks": [ + { + "NetworkMode": "awsvpc", + "IPv4Addresses": [ + "192.0.2.3" + ], + "AttachmentIndex": 0, + "MACAddress": "0a:de:f6:10:51:e5", + "IPv4SubnetCIDRBlock": "192.0.2.0/24", + "DomainNameServers": [ + "192.0.2.2" + ], + "DomainNameSearchList": [ + "us-west-2.compute.internal" + ], + "PrivateDNSName": "ip-10-0-0-222.us-west-2.compute.internal", + "SubnetGatewayIpv4Address": "192.0.2.0/24" + } + ], + "ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1", + "LogOptions": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/containerlogs", + "awslogs-region": "us-west-2", + "awslogs-stream": "ecs/curl/cd189a933e5849daa93386466019ab50" + }, + "LogDriver": "awslogs" +} \ No newline at end of file diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-ec2.json b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-ec2.json new file mode 100644 index 0000000000..101efe0214 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-ec2.json @@ -0,0 +1,94 @@ +{ + "Cluster": "default", + "TaskARN": "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c", + "Family": "curltest", + "Revision": "26", + "DesiredStatus": "RUNNING", + "KnownStatus": "RUNNING", + "PullStartedAt": "2020-10-02T00:43:06.202617438Z", + "PullStoppedAt": "2020-10-02T00:43:06.31288465Z", + "AvailabilityZone": "us-west-2d", + "LaunchType": "EC2", + "Containers": [ + { + "DockerId": "598cba581fe3f939459eaba1e071d5c93bb2c49b7d1ba7db6bb19deeb70d8e38", + "Name": "~internal~ecs~pause", + "DockerName": "ecs-curltest-26-internalecspause-e292d586b6f9dade4a00", + "Image": "amazon/amazon-ecs-pause:0.1.0", + "ImageID": "", + "Labels": { + "com.amazonaws.ecs.cluster": "default", + "com.amazonaws.ecs.container-name": "~internal~ecs~pause", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c", + "com.amazonaws.ecs.task-definition-family": "curltest", + "com.amazonaws.ecs.task-definition-version": "26" + }, + "DesiredStatus": "RESOURCES_PROVISIONED", + "KnownStatus": "RESOURCES_PROVISIONED", + "Limits": { + "CPU": 0, + "Memory": 0 + }, + "CreatedAt": "2020-10-02T00:43:05.602352471Z", + "StartedAt": "2020-10-02T00:43:06.076707576Z", + "Type": "CNI_PAUSE", + "Networks": [ + { + "NetworkMode": "awsvpc", + "IPv4Addresses": [ + "10.0.2.61" + ], + "AttachmentIndex": 0, + "MACAddress": "0e:10:e2:01:bd:91", + "IPv4SubnetCIDRBlock": "10.0.2.0/24", + "PrivateDNSName": "ip-10-0-2-61.us-west-2.compute.internal", + "SubnetGatewayIpv4Address": "10.0.2.1/24" + } + ] + }, + { + "DockerId": "ee08638adaaf009d78c248913f629e38299471d45fe7dc944d1039077e3424ca", + "Name": "curl", + "DockerName": "ecs-curltest-26-curl-a0e7dba5aca6d8cb2e00", + "Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest", + "ImageID": "sha256:d691691e9652791a60114e67b365688d20d19940dde7c4736ea30e660d8d3553", + "Labels": { + "com.amazonaws.ecs.cluster": "default", + "com.amazonaws.ecs.container-name": "curl", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c", + "com.amazonaws.ecs.task-definition-family": "curltest", + "com.amazonaws.ecs.task-definition-version": "26" + }, + "DesiredStatus": "RUNNING", + "KnownStatus": "RUNNING", + "Limits": { + "CPU": 10, + "Memory": 128 + }, + "CreatedAt": "2020-10-02T00:43:06.326590752Z", + "StartedAt": "2020-10-02T00:43:06.767535449Z", + "Type": "NORMAL", + "LogDriver": "awslogs", + "LogOptions": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/metadata", + "awslogs-region": "us-west-2", + "awslogs-stream": "ecs/curl/158d1c8083dd49d6b527399fd6414f5c" + }, + "ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/abb51bdd-11b4-467f-8f6c-adcfe1fe059d", + "Networks": [ + { + "NetworkMode": "awsvpc", + "IPv4Addresses": [ + "10.0.2.61" + ], + "AttachmentIndex": 0, + "MACAddress": "0e:10:e2:01:bd:91", + "IPv4SubnetCIDRBlock": "10.0.2.0/24", + "PrivateDNSName": "ip-10-0-2-61.us-west-2.compute.internal", + "SubnetGatewayIpv4Address": "10.0.2.1/24" + } + ] + } + ] +} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-fargate.json b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-fargate.json new file mode 100644 index 0000000000..7979db708d --- /dev/null +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-fargate.json @@ -0,0 +1,77 @@ +{ + "Cluster": "arn:aws:ecs:us-west-2:111122223333:cluster/default", + "TaskARN": "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3", + "Family": "curltest", + "Revision": "3", + "DesiredStatus": "RUNNING", + "KnownStatus": "RUNNING", + "Limits": { + "CPU": 0.25, + "Memory": 512 + }, + "PullStartedAt": "2020-10-08T20:47:16.053330955Z", + "PullStoppedAt": "2020-10-08T20:47:19.592684631Z", + "AvailabilityZone": "us-west-2a", + "Containers": [ + { + "DockerId": "e9028f8d5d8e4f258373e7b93ce9a3c3-2495160603", + "Name": "curl", + "DockerName": "curl", + "Image": "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest:latest", + "ImageID": "sha256:25f3695bedfb454a50f12d127839a68ad3caf91e451c1da073db34c542c4d2cb", + "Labels": { + "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-west-2:111122223333:cluster/default", + "com.amazonaws.ecs.container-name": "curl", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3", + "com.amazonaws.ecs.task-definition-family": "curltest", + "com.amazonaws.ecs.task-definition-version": "3" + }, + "DesiredStatus": "RUNNING", + "KnownStatus": "RUNNING", + "Limits": { + "CPU": 10, + "Memory": 128 + }, + "CreatedAt": "2020-10-08T20:47:20.567813946Z", + "StartedAt": "2020-10-08T20:47:20.567813946Z", + "Type": "NORMAL", + "Networks": [ + { + "NetworkMode": "awsvpc", + "IPv4Addresses": [ + "192.0.2.3" + ], + "IPv6Addresses": [ + "2001:dB8:10b:1a00:32bf:a372:d80f:e958" + ], + "AttachmentIndex": 0, + "MACAddress": "02:b7:20:19:72:39", + "IPv4SubnetCIDRBlock": "192.0.2.0/24", + "IPv6SubnetCIDRBlock": "2600:1f13:10b:1a00::/64", + "DomainNameServers": [ + "192.0.2.2" + ], + "DomainNameSearchList": [ + "us-west-2.compute.internal" + ], + "PrivateDNSName": "ip-172-31-30-173.us-west-2.compute.internal", + "SubnetGatewayIpv4Address": "192.0.2.0/24" + } + ], + "ClockDrift": { + "ClockErrorBound": 0.5458234999999999, + "ReferenceTimestamp": "2021-09-07T16:57:44Z", + "ClockSynchronizationStatus": "SYNCHRONIZED" + }, + "ContainerARN": "arn:aws:ecs:us-west-2:111122223333:container/1bdcca8b-f905-4ee6-885c-4064cb70f6e6", + "LogOptions": { + "awslogs-create-group": "true", + "awslogs-group": "/ecs/containerlogs", + "awslogs-region": "us-west-2", + "awslogs-stream": "ecs/curl/e9028f8d5d8e4f258373e7b93ce9a3c3" + }, + "LogDriver": "awslogs" + } + ], + "LaunchType": "FARGATE" +} \ No newline at end of file From d8ec6e0dd4d0e081cc89ee86f312c7d303da2fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 13 Mar 2023 19:33:03 +0100 Subject: [PATCH 0617/1499] [Instrumentation.AWSLambda] Remove AddAWSLambdaConfigurations with default parameter (#943) --- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 4 ++++ .../TracerProviderBuilderExtensions.cs | 10 +++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 78ca482d91..04f3cd5b24 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -8,4 +8,5 @@ static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Action lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func> lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task -static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 729760a2cf..42efbc8a16 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -4,9 +4,13 @@ * Add HTTP server span attributes for API Gateway triggers ([#626](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/626)) +* Removes `AddAWSLambdaConfigurations` method with default configure parameter. + ([#943](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/943)) ## 1.1.0-beta.2 +Released 2022-Sep-14 + Release PR: [#590](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/590) & [#639](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/639). diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index e6c523bd31..e6eb7d7daa 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -27,6 +27,14 @@ namespace OpenTelemetry.Instrumentation.AWSLambda; /// public static class TracerProviderBuilderExtensions { + /// + /// Add AWS Lambda configurations. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAWSLambdaConfigurations(this TracerProviderBuilder builder) => + AddAWSLambdaConfigurations(builder, configure: null); + /// /// Add AWS Lambda configurations. /// @@ -35,7 +43,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddAWSLambdaConfigurations( this TracerProviderBuilder builder, - Action configure = null) + Action configure) { Guard.ThrowIfNull(builder); From c83fb4a081a0674b21e5e722bb982248cb9a41a8 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 13 Mar 2023 16:15:12 -0700 Subject: [PATCH 0618/1499] [OneCollector] Support common schema extensions in json (#1073) --- .../CHANGELOG.md | 8 + .../ExtensionFieldInformationManager.cs | 104 ++++++++++ .../OneCollectorExporterEventSource.cs | 6 + .../CommonSchemaJsonSerializationHelper.cs | 12 ++ .../CommonSchemaJsonSerializationState.cs | 180 ++++++++++++++++++ .../CommonSchemaJsonSerializer.cs | 78 +++++--- .../LogRecordCommonSchemaJsonSerializer.cs | 86 ++++++--- .../Internal/ThreadStorageHelper.cs | 32 +++- ...CommonSchemaJsonSerializationStateTests.cs | 142 ++++++++++++++ .../ExtensionFieldInformationManagerTests.cs | 90 +++++++++ ...ogRecordCommonSchemaJsonSerializerTests.cs | 46 +++++ .../WriteDirectlyToTransportSinkTests.cs | 5 +- 12 files changed, 734 insertions(+), 55 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index c8befa9ccd..83e5ad027f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* Added support for sending common schema extensions using `ext.[name].[field]` + syntax. + ([#1073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1073)) + +* Added support for sending common schema `dt` (Distributed Tracing) extensions + when trace context is present on `LogRecord`s. + ([#1073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1073)) + ## 0.1.0-alpha.2 Released 2023-Mar-6 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs new file mode 100644 index 0000000000..f2a92b62d1 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs @@ -0,0 +1,104 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections; +using System.Diagnostics; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class ExtensionFieldInformationManager +{ + public const int MaxNumberOfCachedFieldInformations = 2048; + private readonly Hashtable fieldInformationCache = new(16, StringComparer.OrdinalIgnoreCase); + + public static ExtensionFieldInformationManager SharedCache { get; } = new(); + + public int CountOfCachedExtensionFields => this.fieldInformationCache.Count; + + public bool TryResolveExtensionFieldInformation(string fullFieldName, out (string ExtensionName, string FieldName) resolvedFieldInformation) + { + if (this.fieldInformationCache[fullFieldName] is not FieldInformation fieldInformation) + { + fieldInformation = this.ResolveExtensionFieldInformationRare(fullFieldName); + } + + if (!fieldInformation.IsValid) + { + resolvedFieldInformation = default; + return false; + } + + resolvedFieldInformation = new(fieldInformation.ExtensionName!, fieldInformation.FieldName!); + return true; + } + + private static FieldInformation BuildFieldInformation(string fullFieldName) + { + Debug.Assert(fullFieldName.Length >= 4, "fullFieldName length was invalid"); + Debug.Assert(fullFieldName.StartsWith("ext.", StringComparison.OrdinalIgnoreCase), "fullFieldName did not start with 'ext.'"); + + var extensionName = fullFieldName.AsSpan().Slice(4); + var locationOfDot = extensionName.IndexOf('.'); + if (locationOfDot <= 0) + { + return new(); + } + + var fieldName = extensionName.Slice(locationOfDot + 1); + if (fieldName.Length <= 0) + { + return new(); + } + + extensionName = extensionName.Slice(0, locationOfDot); + + return new FieldInformation + { + ExtensionName = extensionName.ToString(), + FieldName = fieldName.ToString(), + IsValid = true, + }; + } + + private FieldInformation ResolveExtensionFieldInformationRare(string fullFieldName) + { + if (this.fieldInformationCache.Count >= MaxNumberOfCachedFieldInformations) + { + return BuildFieldInformation(fullFieldName); + } + + lock (this.fieldInformationCache) + { + if (this.fieldInformationCache[fullFieldName] is not FieldInformation fieldInformation) + { + fieldInformation = BuildFieldInformation(fullFieldName); + if (this.fieldInformationCache.Count < MaxNumberOfCachedFieldInformations) + { + this.fieldInformationCache[fullFieldName] = fieldInformation; + } + } + + return fieldInformation; + } + } + + private sealed class FieldInformation + { + public string? ExtensionName; + public string? FieldName; + public bool IsValid; + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index 0ab1a1eb0c..ea5c1edd0c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -142,6 +142,12 @@ public void ExceptionThrownFromUserCode(string userCodeType, string exception) this.WriteEvent(10, userCodeType, exception); } + [Event(11, Message = "Dropped {0} attribute '{1}': {2}", Level = EventLevel.Warning)] + public void AttributeDropped(string itemType, string name, string reason) + { + this.WriteEvent(11, itemType, name, reason); + } + /// /// Returns a culture-independent string representation of the given object, /// appropriate for diagnostics tracing. diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index 3406c74214..dd687a15b3 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -26,6 +26,18 @@ internal static class CommonSchemaJsonSerializationHelper public const int MaximumStackAllocSizeInBytes = 256; #endif + public const char OneCollectorTenancySymbol = 'o'; + + public static readonly byte[] NewLine = "\n"u8.ToArray(); + + public static readonly JsonEncodedText VersionProperty = JsonEncodedText.Encode("ver"); + public static readonly JsonEncodedText Version4Value = JsonEncodedText.Encode("4.0"); + public static readonly JsonEncodedText NameProperty = JsonEncodedText.Encode("name"); + public static readonly JsonEncodedText TimeProperty = JsonEncodedText.Encode("time"); + public static readonly JsonEncodedText IKeyProperty = JsonEncodedText.Encode("iKey"); + public static readonly JsonEncodedText ExtensionsProperty = JsonEncodedText.Encode("ext"); + public static readonly JsonEncodedText DataProperty = JsonEncodedText.Encode("data"); + public static void SerializeKeyValueToJson(string key, object? value, Utf8JsonWriter writer) { writer.WritePropertyName(key); diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs new file mode 100644 index 0000000000..52b992aaa1 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs @@ -0,0 +1,180 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NET6_0_OR_GREATER +using System.Runtime.InteropServices; +#endif +using System.Text.Json; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class CommonSchemaJsonSerializationState +{ + public const int MaxNumberOfExtensionKeys = 64; + public const int MaxNumberOfExtensionValuesPerKey = 16; + private readonly Dictionary keys = new(4, StringComparer.OrdinalIgnoreCase); + private readonly List> allValues = new(16); + private string itemType; + private int nextKeysToAllValuesLookupIndex; + private KeyValueLookup[] keysToAllValuesLookup = new KeyValueLookup[4]; + + public CommonSchemaJsonSerializationState(string itemType, Utf8JsonWriter writer) + { + this.itemType = itemType; + this.Writer = writer; + } + + public Utf8JsonWriter Writer { get; private set; } + + public int ExtensionPropertyCount => this.nextKeysToAllValuesLookupIndex; + + public int ExtensionAttributeCount => this.allValues.Count; + + public void AddExtensionAttribute(KeyValuePair attribute) + { + if (!ExtensionFieldInformationManager.SharedCache.TryResolveExtensionFieldInformation( + attribute.Key, + out (string ExtensionName, string FieldName) fieldInformation)) + { + OneCollectorExporterEventSource.Log.AttributeDropped(this.itemType, attribute.Key, "Invalid extension field name"); + return; + } + +#if NET6_0_OR_GREATER + ref var lookupIndex = ref CollectionsMarshal.GetValueRefOrAddDefault(this.keys, fieldInformation.ExtensionName, out var existed); + if (!existed) + { + this.AssignNewExtensionToLookupIndex(ref lookupIndex); + } +#else + if (!this.keys.TryGetValue(fieldInformation.ExtensionName, out int lookupIndex)) + { + this.AssignNewExtensionToLookupIndex(ref lookupIndex); + this.keys[fieldInformation.ExtensionName] = lookupIndex; + } +#endif + + if (lookupIndex == -1) + { + OneCollectorExporterEventSource.Log.AttributeDropped(this.itemType, attribute.Key, "Extension limit reached"); + return; + } + + ref KeyValueLookup keyLookup = ref this.keysToAllValuesLookup[lookupIndex]; + + if (keyLookup.Count >= MaxNumberOfExtensionValuesPerKey) + { + OneCollectorExporterEventSource.Log.AttributeDropped(this.itemType, attribute.Key, "Extension value limit reached"); + return; + } + + int index = this.allValues.Count; + this.allValues.Add(new KeyValuePair(fieldInformation.FieldName, attribute.Value)); + + unsafe + { + keyLookup.ValueIndicies[keyLookup.Count++] = index; + } + } + + public void SerializeExtensionPropertiesToJson(bool writeExtensionObjectEnvelope) + { + var writer = this.Writer; + + if (writeExtensionObjectEnvelope) + { + writer.WriteStartObject(CommonSchemaJsonSerializationHelper.ExtensionsProperty); + } + +#if NET6_0_OR_GREATER + var allValues = CollectionsMarshal.AsSpan(this.allValues); +#else + var allValues = this.allValues; +#endif + + foreach (var extensionPropertyKey in this.keys) + { + writer.WriteStartObject(extensionPropertyKey.Key); + + ref KeyValueLookup keyLookup = ref this.keysToAllValuesLookup[extensionPropertyKey.Value]; + + for (int i = 0; i < keyLookup.Count; i++) + { + unsafe + { +#if NET6_0_OR_GREATER + ref var attribute = ref allValues[keyLookup.ValueIndicies[i]]; +#else + var attribute = allValues[keyLookup.ValueIndicies[i]]; +#endif + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(attribute.Key, attribute.Value, writer); + } + } + + writer.WriteEndObject(); + } + + if (writeExtensionObjectEnvelope) + { + writer.WriteEndObject(); + } + } + + public void Reset(string itemType, Utf8JsonWriter writer) + { + this.itemType = itemType; + this.Writer = writer; + + for (int i = 0; i < this.nextKeysToAllValuesLookupIndex; i++) + { + ref var lookup = ref this.keysToAllValuesLookup[i]; + lookup.Count = 0; + } + + this.nextKeysToAllValuesLookupIndex = 0; + + this.keys.Clear(); + + this.allValues.Clear(); + } + + private void AssignNewExtensionToLookupIndex(ref int lookupIndex) + { + lookupIndex = this.nextKeysToAllValuesLookupIndex; + + if (lookupIndex >= this.keysToAllValuesLookup.Length) + { + if (this.keysToAllValuesLookup.Length >= MaxNumberOfExtensionKeys) + { + lookupIndex = -1; + return; + } + + var newKeysToAllValuesLookup = new KeyValueLookup[this.keysToAllValuesLookup.Length * 2]; + this.keysToAllValuesLookup.CopyTo(newKeysToAllValuesLookup, 0); + this.keysToAllValuesLookup = newKeysToAllValuesLookup; + } + + this.nextKeysToAllValuesLookupIndex++; + } + + private unsafe struct KeyValueLookup + { + public int Count; + public fixed int ValueIndicies[MaxNumberOfExtensionValuesPerKey]; + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs index bd9793ca70..585994b438 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -24,19 +24,9 @@ namespace OpenTelemetry.Exporter.OneCollector; internal abstract class CommonSchemaJsonSerializer : ISerializer where T : class { - protected static readonly JsonEncodedText VersionProperty = JsonEncodedText.Encode("ver"); - protected static readonly JsonEncodedText Version4Value = JsonEncodedText.Encode("4.0"); - protected static readonly JsonEncodedText NameProperty = JsonEncodedText.Encode("name"); - protected static readonly JsonEncodedText TimeProperty = JsonEncodedText.Encode("time"); - protected static readonly JsonEncodedText IKeyProperty = JsonEncodedText.Encode("iKey"); - protected static readonly JsonEncodedText DataProperty = JsonEncodedText.Encode("data"); - - private const char OneCollectorTenancySymbol = 'o'; - - private static readonly byte[] NewLine = "\n"u8.ToArray(); - private readonly int maxPayloadSizeInBytes; private readonly int maxNumberOfItemsPerPayload; + private readonly string itemType = typeof(T).Name; protected CommonSchemaJsonSerializer( string tenantToken, @@ -48,7 +38,7 @@ protected CommonSchemaJsonSerializer( this.maxPayloadSizeInBytes = maxPayloadSizeInBytes; this.maxNumberOfItemsPerPayload = maxNumberOfItemsPerPayload; - this.TenantTokenWithTenancySystemSymbol = JsonEncodedText.Encode($"{OneCollectorTenancySymbol}:{tenantToken}"); + this.TenantTokenWithTenancySystemSymbol = JsonEncodedText.Encode($"{CommonSchemaJsonSerializationHelper.OneCollectorTenancySymbol}:{tenantToken}"); } public abstract string Description { get; } @@ -64,21 +54,13 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, var numberOfSerializedItems = 0; long payloadSizeInBytes = initialSizeOfPayloadInBytes; - var writer = ThreadStorageHelper.Utf8JsonWriter; - if (writer == null) - { - writer = ThreadStorageHelper.Utf8JsonWriter = new( - stream, - new JsonWriterOptions { SkipValidation = true }); - } - else - { - writer.Reset(stream); - } + var state = ThreadStorageHelper.GetCommonSchemaJsonSerializationState(this.itemType, stream); + + var writer = state.Writer; foreach (var item in batch) { - this.SerializeItemToJson(resource, item, writer); + this.SerializeItemToJson(resource, item, state); var currentItemSizeInBytes = writer.BytesCommitted + writer.BytesPending + 1; @@ -87,7 +69,7 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, writer.Flush(); writer.Reset(); - stream.Write(NewLine, 0, 1); + stream.Write(CommonSchemaJsonSerializationHelper.NewLine, 0, 1); if (++numberOfSerializedItems >= this.maxNumberOfItemsPerPayload) { @@ -113,5 +95,49 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, }; } - protected abstract void SerializeItemToJson(Resource resource, T item, Utf8JsonWriter writer); + protected static bool AttributeKeyStartWithExtensionPrefix(string attributeKey) + { + return attributeKey.StartsWith("ext.", StringComparison.OrdinalIgnoreCase); + } + + protected static void SerializeResourceToJsonInsideCurrentObject(Resource resource, CommonSchemaJsonSerializationState serializationState) + { + Debug.Assert(resource != null, "resource was null"); + Debug.Assert(serializationState != null, "serializationState was null"); + + var writer = serializationState!.Writer; + + Debug.Assert(writer != null, "writer was null"); + + if (resource!.Attributes is IReadOnlyList> resourceAttributeList) + { + for (int i = 0; i < resourceAttributeList.Count; i++) + { + var resourceAttribute = resourceAttributeList[i]; + + if (AttributeKeyStartWithExtensionPrefix(resourceAttribute.Key)) + { + serializationState.AddExtensionAttribute(resourceAttribute); + continue; + } + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(resourceAttribute.Key, resourceAttribute.Value, writer!); + } + } + else + { + foreach (KeyValuePair resourceAttribute in resource.Attributes) + { + if (AttributeKeyStartWithExtensionPrefix(resourceAttribute.Key)) + { + serializationState.AddExtensionAttribute(resourceAttribute!); + continue; + } + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(resourceAttribute.Key, resourceAttribute.Value, writer!); + } + } + } + + protected abstract void SerializeItemToJson(Resource resource, T item, CommonSchemaJsonSerializationState serializationState); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 456212d4fc..f78ae052a5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -26,6 +26,10 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText SeverityTextProperty = JsonEncodedText.Encode("severityText"); private static readonly JsonEncodedText SeverityNumberProperty = JsonEncodedText.Encode("severityNumber"); private static readonly JsonEncodedText BodyProperty = JsonEncodedText.Encode("body"); + private static readonly JsonEncodedText DistributedTraceExtensionProperty = JsonEncodedText.Encode("dt"); + private static readonly JsonEncodedText DistributedTraceExtensionTraceIdProperty = JsonEncodedText.Encode("traceId"); + private static readonly JsonEncodedText DistributedTraceExtensionSpanIdProperty = JsonEncodedText.Encode("spanId"); + private static readonly JsonEncodedText DistributedTraceExtensionTraceFlagsProperty = JsonEncodedText.Encode("traceFlags"); private static readonly JsonEncodedText[] LogLevelToSeverityTextMappings = new JsonEncodedText[] { @@ -43,16 +47,24 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri 1, 5, 9, 13, 17, 21, 1, }; - private static readonly Action SerializeScopeItemToJson = (s, w) => + private static readonly Action SerializeScopeItemToJson = (scope, serializationState) => { - foreach (KeyValuePair scopeAttribute in s) + var writer = serializationState.Writer; + + foreach (KeyValuePair scopeAttribute in scope) { if (scopeAttribute.Key == "{OriginalFormat}") { return; } - CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(scopeAttribute.Key, scopeAttribute.Value, w); + if (AttributeKeyStartWithExtensionPrefix(scopeAttribute.Key)) + { + serializationState.AddExtensionAttribute(scopeAttribute!); + continue; + } + + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(scopeAttribute.Key, scopeAttribute.Value, writer); } }; @@ -72,28 +84,34 @@ public LogRecordCommonSchemaJsonSerializer( public override string Description => "LogRecord Common Schema JSON"; - protected override void SerializeItemToJson(Resource resource, LogRecord item, Utf8JsonWriter writer) + protected override void SerializeItemToJson(Resource resource, LogRecord item, CommonSchemaJsonSerializationState serializationState) { + Debug.Assert(serializationState != null, "serializationState was null"); + + var writer = serializationState!.Writer; + + Debug.Assert(writer != null, "writer was null"); + var eventName = this.eventNameManager.ResolveEventFullName( item.CategoryName, item.EventId.Name); - writer.WriteStartObject(); + writer!.WriteStartObject(); - writer.WriteString(VersionProperty, Version4Value); + writer.WriteString(CommonSchemaJsonSerializationHelper.VersionProperty, CommonSchemaJsonSerializationHelper.Version4Value); - writer.WritePropertyName(NameProperty); + writer.WritePropertyName(CommonSchemaJsonSerializationHelper.NameProperty); #if DEBUG writer.WriteRawValue(eventName, skipInputValidation: false); #else writer.WriteRawValue(eventName, skipInputValidation: true); #endif - writer.WriteString(TimeProperty, item.Timestamp); + writer.WriteString(CommonSchemaJsonSerializationHelper.TimeProperty, item.Timestamp); - writer.WriteString(IKeyProperty, this.TenantTokenWithTenancySystemSymbol); + writer.WriteString(CommonSchemaJsonSerializationHelper.IKeyProperty, this.TenantTokenWithTenancySystemSymbol); - writer.WriteStartObject(DataProperty); + writer.WriteStartObject(CommonSchemaJsonSerializationHelper.DataProperty); /* TODO: There doesn't seem to be a spot in common schema defined for event.id so we will drop for now. @@ -126,6 +144,12 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, U continue; } + if (AttributeKeyStartWithExtensionPrefix(attribute.Key)) + { + serializationState.AddExtensionAttribute(attribute); + continue; + } + CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(attribute.Key, attribute.Value, writer); } } @@ -139,26 +163,38 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, U writer.WriteString(BodyProperty, item.FormattedMessage); } - if (resource.Attributes is IReadOnlyList> resourceAttributeList) - { - for (int i = 0; i < resourceAttributeList.Count; i++) - { - var resourceAttribute = resourceAttributeList[i]; + SerializeResourceToJsonInsideCurrentObject(resource, serializationState); - CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(resourceAttribute.Key, resourceAttribute.Value, writer); - } - } - else + item.ForEachScope(SerializeScopeItemToJson, serializationState); + + writer.WriteEndObject(); + + SerializeExtensionPropertiesToJson(item, writer, serializationState); + + writer.WriteEndObject(); + } + + private static void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter writer, CommonSchemaJsonSerializationState serializationState) + { + var hasTraceContext = item.TraceId != default; + + if (!hasTraceContext && serializationState.ExtensionAttributeCount <= 0) { - foreach (KeyValuePair resourceAttribute in resource.Attributes) - { - CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(resourceAttribute.Key, resourceAttribute.Value, writer); - } + return; } - item.ForEachScope(SerializeScopeItemToJson, writer); + writer.WriteStartObject(CommonSchemaJsonSerializationHelper.ExtensionsProperty); - writer.WriteEndObject(); + if (hasTraceContext) + { + writer.WriteStartObject(DistributedTraceExtensionProperty); + writer.WriteString(DistributedTraceExtensionTraceIdProperty, item.TraceId.ToHexString()); + writer.WriteString(DistributedTraceExtensionSpanIdProperty, item.SpanId.ToHexString()); + writer.WriteNumber(DistributedTraceExtensionTraceFlagsProperty, (int)item.TraceFlags); + writer.WriteEndObject(); + } + + serializationState.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: false); writer.WriteEndObject(); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs index 13c056a44c..3a1968c9af 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs @@ -21,5 +21,35 @@ namespace OpenTelemetry.Exporter.OneCollector; internal static class ThreadStorageHelper { [ThreadStatic] - public static Utf8JsonWriter? Utf8JsonWriter; + private static Utf8JsonWriter? utf8JsonWriter; + + [ThreadStatic] + private static CommonSchemaJsonSerializationState? commonSchemaJsonSerializationState; + + public static CommonSchemaJsonSerializationState GetCommonSchemaJsonSerializationState(string itemType, Stream stream) + { + var writer = utf8JsonWriter; + if (writer == null) + { + writer = utf8JsonWriter = new( + stream, + new JsonWriterOptions { SkipValidation = true }); + } + else + { + writer.Reset(stream); + } + + var serializationState = commonSchemaJsonSerializationState; + if (serializationState == null) + { + serializationState = commonSchemaJsonSerializationState ??= new(itemType, writer); + } + else + { + serializationState.Reset(itemType, writer); + } + + return serializationState; + } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs new file mode 100644 index 0000000000..0363ca3996 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs @@ -0,0 +1,142 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text; +using System.Text.Json; +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class CommonSchemaJsonSerializationStateTests +{ + [Fact] + public void AddExtensionAttributeTest() + { + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + + var state = new CommonSchemaJsonSerializationState("Test", writer); + + state.AddExtensionAttribute(new KeyValuePair("ext.something.field1", 1)); + state.AddExtensionAttribute(new KeyValuePair("ext.something.field2", 2)); + state.AddExtensionAttribute(new KeyValuePair("ext.something.field3", 3)); + + state.AddExtensionAttribute(new KeyValuePair("ext.food.field1", 4)); + state.AddExtensionAttribute(new KeyValuePair("ext.food.field2", 5)); + + state.AddExtensionAttribute(new KeyValuePair("ext.something.field4", 6)); + + Assert.Equal(2, state.ExtensionPropertyCount); + Assert.Equal(6, state.ExtensionAttributeCount); + + writer.WriteStartObject(); + state.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: true); + writer.WriteEndObject(); + writer.Flush(); + + var json = Encoding.UTF8.GetString(stream.ToArray()); + + Assert.Equal( + "{\"ext\":{\"something\":{\"field1\":1,\"field2\":2,\"field3\":3,\"field4\":6},\"food\":{\"field1\":4,\"field2\":5}}}", + json); + + stream.SetLength(0); + writer.Reset(stream); + state.Reset("Test", writer); + + Assert.Equal(0, state.ExtensionPropertyCount); + Assert.Equal(0, state.ExtensionAttributeCount); + + state.AddExtensionAttribute(new KeyValuePair("ext.something.field1", 1)); + state.AddExtensionAttribute(new KeyValuePair("ext.food.field1", 1)); + + Assert.Equal(2, state.ExtensionPropertyCount); + Assert.Equal(2, state.ExtensionAttributeCount); + + writer.WriteStartObject(); + state.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: true); + writer.WriteEndObject(); + writer.Flush(); + + json = Encoding.UTF8.GetString(stream.ToArray()); + + Assert.Equal( + "{\"ext\":{\"something\":{\"field1\":1},\"food\":{\"field1\":1}}}", + json); + } + + [Fact] + public void AddExtensionAttributeDuplicatesTest() + { + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + + var state = new CommonSchemaJsonSerializationState("Test", writer); + + // Note: This test is just to verify de-duping is NOT currently supported. + + state.AddExtensionAttribute(new KeyValuePair("ext.something.field1", 1)); + state.AddExtensionAttribute(new KeyValuePair("ext.something.field1", 2)); + + Assert.Equal(1, state.ExtensionPropertyCount); + Assert.Equal(2, state.ExtensionAttributeCount); + + writer.WriteStartObject(); + state.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: true); + writer.WriteEndObject(); + writer.Flush(); + + var json = Encoding.UTF8.GetString(stream.ToArray()); + + Assert.Equal( + "{\"ext\":{\"something\":{\"field1\":1,\"field1\":2}}}", + json); + } + + [Fact] + public void AddExtensionAttributeKeyLimitTest() + { + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + + var state = new CommonSchemaJsonSerializationState("Test", writer); + + for (int i = 0; i < CommonSchemaJsonSerializationState.MaxNumberOfExtensionKeys + 10; i++) + { + state.AddExtensionAttribute(new KeyValuePair($"ext.something{i}.field1", 1)); + } + + Assert.Equal(CommonSchemaJsonSerializationState.MaxNumberOfExtensionKeys, state.ExtensionPropertyCount); + Assert.Equal(CommonSchemaJsonSerializationState.MaxNumberOfExtensionKeys, state.ExtensionAttributeCount); + } + + [Fact] + public void AddExtensionAttributeKeyValueLimitTest() + { + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + + var state = new CommonSchemaJsonSerializationState("Test", writer); + + for (int i = 0; i < CommonSchemaJsonSerializationState.MaxNumberOfExtensionValuesPerKey + 10; i++) + { + state.AddExtensionAttribute(new KeyValuePair($"ext.something.field{i}", i)); + } + + Assert.Equal(1, state.ExtensionPropertyCount); + Assert.Equal(CommonSchemaJsonSerializationState.MaxNumberOfExtensionValuesPerKey, state.ExtensionAttributeCount); + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs new file mode 100644 index 0000000000..e2b0de5890 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs @@ -0,0 +1,90 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public class ExtensionFieldInformationManagerTests +{ + [Fact] + public void FieldInformationIsCachedTest() + { + var extensionFieldInformationManager = new ExtensionFieldInformationManager(); + + var result = extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something.fieldName1", out var fieldInformation); + + Assert.True(result); + Assert.Equal("something", fieldInformation.ExtensionName); + Assert.Equal("fieldName1", fieldInformation.FieldName); + + Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); + + result = extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something.fieldName1", out fieldInformation); + + Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); + + Assert.True(result); + Assert.Equal("something", fieldInformation.ExtensionName); + Assert.Equal("fieldName1", fieldInformation.FieldName); + + result = extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something.field.Name2", out fieldInformation); + + Assert.Equal(2, extensionFieldInformationManager.CountOfCachedExtensionFields); + + Assert.True(result); + Assert.Equal("something", fieldInformation.ExtensionName); + Assert.Equal("field.Name2", fieldInformation.FieldName); + } + + [Fact] + public void InvalidFieldNamesIgnoredTest() + { + var extensionFieldInformationManager = new ExtensionFieldInformationManager(); + + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.", out _)); + + Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); + + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.", out _)); + + Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); + + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something", out _)); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something.", out _)); + + Assert.Equal(3, extensionFieldInformationManager.CountOfCachedExtensionFields); + } + + [Fact] + public void FieldInformationCacheLimitTest() + { + var extensionFieldInformationManager = new ExtensionFieldInformationManager(); + + for (int i = 0; i < ExtensionFieldInformationManager.MaxNumberOfCachedFieldInformations + 128; i++) + { + var fieldName = $"fieldName{i}"; + + var result = extensionFieldInformationManager.TryResolveExtensionFieldInformation($"ext.something.{fieldName}", out var fieldInformation); + + Assert.True(result); + Assert.Equal("something", fieldInformation.ExtensionName); + Assert.Equal(fieldName, fieldInformation.FieldName); + } + + Assert.Equal(ExtensionFieldInformationManager.MaxNumberOfCachedFieldInformations, extensionFieldInformationManager.CountOfCachedExtensionFields); + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index ec091eb302..ec20cd563e 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System.Diagnostics; using System.Reflection; using System.Text; using Microsoft.Extensions.Logging; @@ -167,6 +168,51 @@ public void LogRecordStateValuesJsonTest() json); } + [Fact] + public void LogRecordTraceContextJsonTest() + { + var traceId = ActivityTraceId.CreateRandom(); + var spanId = ActivitySpanId.CreateRandom(); + + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.TraceId = traceId; + logRecord.SpanId = spanId; + logRecord.TraceFlags = ActivityTraceFlags.Recorded; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}},\"ext\":{{\"dt\":{{\"traceId\":\"{traceId}\",\"spanId\":\"{spanId}\",\"traceFlags\":1}}}}}}\n", + json); + } + + [Fact] + public void LogRecordExtensionsJsonTest() + { + var scopeProvider = new ScopeProvider( + new List> { new KeyValuePair("ext.scope.field", "scopeValue1") }); + + var resource = ResourceBuilder.CreateEmpty() + .AddAttributes(new Dictionary + { + ["ext.resource.field"] = "resourceValue1", + }) + .Build(); + + string json = GetLogRecordJson( + 1, + (index, logRecord) => + { + logRecord.StateValues = new List> { new KeyValuePair("ext.state.field", "stateValue1") }; + }, + resource, + scopeProvider); + + Assert.Equal( + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1},\"ext\":{\"state\":{\"field\":\"stateValue1\"},\"resource\":{\"field\":\"resourceValue1\"},\"scope\":{\"field\":\"scopeValue1\"}}}\n", + json); + } + private static string GetLogRecordJson( int numberOfLogRecords, Action writeLogRecordCallback, diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs index 58df6d47df..d519fcf658 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -15,7 +15,6 @@ // using System.Text; -using System.Text.Json; using OpenTelemetry.Resources; using Xunit; @@ -154,9 +153,9 @@ public TestSerializer( public override string Description => nameof(TestSerializer); - protected override void SerializeItemToJson(Resource resource, string item, Utf8JsonWriter writer) + protected override void SerializeItemToJson(Resource resource, string item, CommonSchemaJsonSerializationState serializationState) { - writer.WriteStringValue(item); + serializationState.Writer.WriteStringValue(item); } } From 3af36658d7bf267c041a6d39dc1c4394ec4c4be9 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 13 Mar 2023 17:05:53 -0700 Subject: [PATCH 0619/1499] [Exporter.Geneva] Update GenevaMetricExporter to export Exemplars (#1069) --- build/Common.props | 2 +- .../CHANGELOG.md | 9 +- .../Metrics/GenevaMetricExporter.cs | 530 +++++++++++++++++- .../Metrics/MetricSerializer.cs | 208 +++++++ .../Transport/MetricEtwDataTransport.cs | 5 + .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../GenevaMetricExporterTests.cs | 11 +- 7 files changed, 735 insertions(+), 32 deletions(-) diff --git a/build/Common.props b/build/Common.props index 3420b287d8..a35274d9ae 100644 --- a/build/Common.props +++ b/build/Common.props @@ -34,7 +34,7 @@ [3.3.3] [1.1.1,2.0) [1.4.0,2.0) - [1.4.0,2.0) + [1.5.0-alpha.1] [2.1.58,3.0) [1.2.0-beta.435,2.0) [4.3.4,) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 531b8613e4..99ca6b4a83 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,10 +5,15 @@ * Changed the behavior of Unix domain socket connection at startup. Before this change, the exporter initialization would throw exception if the target Unix Domain Socket does not exist. After this change, the exporter initialization - would return success and the exporting background thread will try to - establish the connection. + would return success and the exporting background thread will try to establish + the connection. ([#935](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/935)) +* Update OTel SDK version to `1.5.0-alpha.1`. +* Update GenevaMetricExporter to use TLV format serialization. +* Add support for exporting exemplars. + ([#1069](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1069)) + ## 1.4.0 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 485982c91c..6f314f4249 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -35,8 +35,6 @@ public class GenevaMetricExporter : BaseExporter internal const int MaxDimensionValueSize = 1024; - private static readonly MetricData ulongZero = new MetricData { UInt64Value = 0 }; - private readonly ushort prepopulatedDimensionsCount; private readonly int fixedPayloadStartIndex; @@ -51,6 +49,8 @@ public class GenevaMetricExporter : BaseExporter private readonly List serializedPrepopulatedDimensionsValues; + private readonly byte[] buffer = new byte[BufferSize]; + private readonly byte[] bufferForNonHistogramMetrics = new byte[BufferSize]; private readonly byte[] bufferForHistogramMetrics = new byte[BufferSize]; @@ -126,19 +126,22 @@ public override ExportResult Export(in Batch batch) { try { + var exemplars = metricPoint.GetExemplars(); + switch (metric.MetricType) { case MetricType.LongSum: { var ulongSum = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = ulongSum }; - var bodyLength = this.SerializeMetric( + var bodyLength = this.SerializeMetricWithTLV( MetricEventType.ULongMetric, metric.Name, metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.ULongMetric, this.bufferForNonHistogramMetrics, bodyLength); + metricData, + exemplars); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -149,13 +152,14 @@ public override ExportResult Export(in Batch batch) // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions var doubleSum = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetric( + var bodyLength = this.SerializeMetricWithTLV( MetricEventType.DoubleMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + metricData, + exemplars); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -166,13 +170,14 @@ public override ExportResult Export(in Batch batch) // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions var doubleSum = Convert.ToDouble(metricPoint.GetSumLong()); var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetric( + var bodyLength = this.SerializeMetricWithTLV( MetricEventType.DoubleMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + metricData, + exemplars); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -181,13 +186,14 @@ public override ExportResult Export(in Batch batch) { var doubleSum = metricPoint.GetSumDouble(); var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetric( + var bodyLength = this.SerializeMetricWithTLV( MetricEventType.DoubleMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + metricData, + exemplars); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -195,29 +201,28 @@ public override ExportResult Export(in Batch batch) { var doubleSum = metricPoint.GetGaugeLastValueDouble(); var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetric( + var bodyLength = this.SerializeMetricWithTLV( MetricEventType.DoubleMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, - metricData); - this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + metricData, + exemplars); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } case MetricType.Histogram: { - var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - MetricData min = ulongZero; - MetricData max = ulongZero; - if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) + if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) { - min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; + min = 0; + max = 0; } - var bodyLength = this.SerializeHistogramMetric( + var bodyLength = this.SerializeHistogramMetricWithTLV( metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, @@ -225,8 +230,9 @@ public override ExportResult Export(in Batch batch) sum, count, min, - max); - this.metricDataTransport.Send(MetricEventType.ExternallyAggregatedULongDistributionMetric, this.bufferForHistogramMetrics, bodyLength); + max, + exemplars); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } } @@ -484,6 +490,384 @@ internal unsafe ushort SerializeHistogramMetric( return bodyLength; } + internal unsafe ushort SerializeMetricWithTLV( + MetricEventType eventType, + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + MetricData value, + Exemplar[] exemplars) + { + ushort bodyLength; + try + { + // The buffer format is as follows: + // -- BinaryHeader + // -- Sequence of payload types + + // Leave enough space for the header + var bufferIndex = sizeof(BinaryHeader); + + // Serialize metric name + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.MetricName); + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricName)); + + #region Serialize metric data + + var payloadType = eventType == MetricEventType.ULongMetric ? PayloadType.ULongMetric : PayloadType.DoubleMetric; + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)payloadType); + + // Get a placeholder to add the payloadType length + int payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, (ulong)timestamp); // timestamp + + if (payloadType == PayloadType.ULongMetric) + { + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, value.UInt64Value); + } + else + { + MetricSerializer.SerializeFloat64(this.buffer, ref bufferIndex, value.DoubleValue); + } + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + #endregion + + #region Serialize metric dimensions + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Dimensions); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add dimensions count later + var bufferIndexForDimensionsCount = bufferIndex; + bufferIndex += 2; + + ushort dimensionsWritten = 0; + + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.buffer, ref bufferIndex, tag.Key); + } + + dimensionsWritten += (ushort)tags.Count; + + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } + + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.buffer, ref bufferIndex, dimensionValue); + } + + // Backfill the number of dimensions written + MetricSerializer.SerializeUInt16(this.buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + #endregion + + #region Serialize exemplars + + if (exemplars.Length > 0) + { + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Exemplars); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version + + var exemplarsCount = 0; + foreach (var exemplar in exemplars) + { + if (exemplar.Timestamp != default) + { + exemplarsCount++; + } + } + + MetricSerializer.SerializeInt32AsBase128(this.buffer, ref bufferIndex, exemplarsCount); + + foreach (var exemplar in exemplars) + { + if (exemplar.Timestamp != default) + { + this.SerializeExemplar(exemplar, ref bufferIndex); + } + } + } + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + #endregion + + // Serialize monitoring account + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.AccountName); + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.monitoringAccount)); + + // Serialize metric namespace + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Namespace); + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.metricNamespace)); + + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.buffer) + { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.TLV; + ptr->BodyLength = bodyLength; + } + } + finally + { + } + + return bodyLength; + } + + internal unsafe ushort SerializeHistogramMetricWithTLV( + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + HistogramBuckets buckets, + double sum, + uint count, + double min, + double max, + Exemplar[] exemplars) + { + ushort bodyLength; + try + { + // The buffer format is as follows: + // -- BinaryHeader + // -- Sequence of payload types + + // Leave enough space for the header + var bufferIndex = sizeof(BinaryHeader); + + // Serialize metric name + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.MetricName); + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricName)); + + #region Serialize histogram metric data + + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.ExternallyAggregatedULongDistributionMetric); + + // Get a placeholder to add the payloadType length + int payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Serialize sum, count, min, and max + MetricSerializer.SerializeUInt32(this.buffer, ref bufferIndex, count); // histogram count + MetricSerializer.SerializeUInt32(this.buffer, ref bufferIndex, 0); // padding + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, (ulong)timestamp); // timestamp + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(sum)); // histogram sum + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(min)); // histogram min + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(max)); // histogram max + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + // Serialize histogram buckets as value-count pairs + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.HistogramULongValueCountPairs); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add the number of value-count pairs added + // with value being the bucket boundary and count being the respective count + + var itemsWrittenIndex = bufferIndex; + MetricSerializer.SerializeUInt16(this.buffer, ref bufferIndex, 0); + + // Bucket values + ushort bucketCount = 0; + double lastExplicitBound = default; + foreach (var bucket in buckets) + { + if (bucket.BucketCount > 0) + { + this.SerializeHistogramBucketWithTLV(bucket, ref bufferIndex, lastExplicitBound); + bucketCount++; + } + + lastExplicitBound = bucket.ExplicitBound; + } + + // Write the number of items in distribution emitted and reset back to end. + MetricSerializer.SerializeUInt16(this.buffer, ref itemsWrittenIndex, bucketCount); + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + #endregion + + #region Serialize metric dimensions + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Dimensions); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add dimensions count later + var bufferIndexForDimensionsCount = bufferIndex; + bufferIndex += 2; + + ushort dimensionsWritten = 0; + + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.buffer, ref bufferIndex, tag.Key); + } + + dimensionsWritten += (ushort)tags.Count; + + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } + + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(this.buffer, ref bufferIndex, dimensionValue); + } + + // Backfill the number of dimensions written + MetricSerializer.SerializeUInt16(this.buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + #endregion + + #region Serialize exemplars + + if (exemplars.Length > 0) + { + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Exemplars); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version + + var exemplarsCount = 0; + foreach (var exemplar in exemplars) + { + if (exemplar.Timestamp != default) + { + exemplarsCount++; + } + } + + MetricSerializer.SerializeInt32AsBase128(this.buffer, ref bufferIndex, exemplarsCount); + + foreach (var exemplar in exemplars) + { + if (exemplar.Timestamp != default) + { + this.SerializeExemplar(exemplar, ref bufferIndex); + } + } + } + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + + #endregion + + // Serialize monitoring account + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.AccountName); + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.monitoringAccount)); + + // Serialize metric namespace + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Namespace); + MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.metricNamespace)); + + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.buffer) + { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.TLV; + ptr->BodyLength = bodyLength; + } + } + finally + { + } + + return bodyLength; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) { @@ -500,6 +884,100 @@ private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferI MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(this.buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) + { + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version + + var bufferIndexForLength = bufferIndex; + bufferIndex++; + + var bufferIndexForFlags = bufferIndex; + bufferIndex++; + + var flags = ExemplarFlags.IsTimestampAvailable; // we only serialize exemplars with Timestamp != default + + // TODO: Update the code whenn Exemplars support long values + var value = exemplar.DoubleValue; + + // Check if the double value is actually a whole number that can be serialized as a long instead + var valueAsLong = (long)value; + bool isWholeNumber = valueAsLong == value; + if (isWholeNumber) + { + flags |= ExemplarFlags.IsMetricValueDoubleStoredAsLong; + MetricSerializer.SerializeInt64AsBase128(this.buffer, ref bufferIndex, valueAsLong); // serialize long value + } + else + { + MetricSerializer.SerializeFloat64(this.buffer, ref bufferIndex, value); // serialize double value + } + + var bufferIndexForNumberOfLabels = bufferIndex; + MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // serialize zero as the count of labels; this would be updated later if the exemplar has labels + byte numberOfLabels = 0; + + // Convert exemplar timestamp to unix nanoseconds + var unixNanoSeconds = DateTime.FromFileTimeUtc(exemplar.Timestamp.ToFileTime()) + .ToUniversalTime() + .Subtract(new DateTime(1970, 1, 1)) + .TotalMilliseconds * 1000000; + + MetricSerializer.SerializeInt64(this.buffer, ref bufferIndex, (long)unixNanoSeconds); // serialize timestamp + + if (exemplar.TraceId.HasValue) + { + Span traceIdBytes = stackalloc byte[16]; + exemplar.TraceId.Value.CopyTo(traceIdBytes); + MetricSerializer.SerializeSpanOfBytes(this.buffer, ref bufferIndex, traceIdBytes, traceIdBytes.Length); // serialize traceId + + flags |= ExemplarFlags.TraceIdExists; + } + + if (exemplar.SpanId.HasValue) + { + Span spanIdBytes = stackalloc byte[8]; + exemplar.SpanId.Value.CopyTo(spanIdBytes); + MetricSerializer.SerializeSpanOfBytes(this.buffer, ref bufferIndex, spanIdBytes, spanIdBytes.Length); // serialize spanId + + flags |= ExemplarFlags.SpanIdExists; + } + + bool hasLabels = exemplar.FilteredTags != null && exemplar.FilteredTags.Count > 0; + if (hasLabels) + { + foreach (var tag in exemplar.FilteredTags) + { + MetricSerializer.SerializeBase128String(this.buffer, ref bufferIndex, tag.Key); + MetricSerializer.SerializeBase128String(this.buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); + numberOfLabels++; + } + + MetricSerializer.SerializeByte(this.buffer, ref bufferIndexForNumberOfLabels, numberOfLabels); + } + + MetricSerializer.SerializeByte(this.buffer, ref bufferIndexForFlags, (byte)flags); + + var exemplarLength = bufferIndex - bufferIndexForLength + 1; + MetricSerializer.SerializeByte(this.buffer, ref bufferIndexForLength, (byte)exemplarLength); + } + private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) { var serializedKeys = new List(this.prepopulatedDimensionsCount); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs index fa1615c672..31322ec28a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs @@ -193,6 +193,189 @@ public static void SerializeUInt64(byte[] buffer, ref int bufferIndex, ulong val buffer[bufferIndex + 7] = (byte)(value >> 0x38); bufferIndex += sizeof(ulong); } + + /// + /// Writes the long to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeInt64(byte[] buffer, ref int bufferIndex, long value) + { + if (bufferIndex + sizeof(long) >= buffer.Length) + { + } + + buffer[bufferIndex] = (byte)value; + buffer[bufferIndex + 1] = (byte)(value >> 8); + buffer[bufferIndex + 2] = (byte)(value >> 0x10); + buffer[bufferIndex + 3] = (byte)(value >> 0x18); + buffer[bufferIndex + 4] = (byte)(value >> 0x20); + buffer[bufferIndex + 5] = (byte)(value >> 0x28); + buffer[bufferIndex + 6] = (byte)(value >> 0x30); + buffer[bufferIndex + 7] = (byte)(value >> 0x38); + bufferIndex += sizeof(long); + } + + /// + /// Writes the double to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void SerializeFloat64(byte[] buffer, ref int bufferIndex, double value) + { + if (bufferIndex + sizeof(double) >= buffer.Length) + { + // TODO: What should we do when the data is invalid? + } + + fixed (byte* bp = buffer) + { + *(double*)(bp + bufferIndex) = value; + } + + bufferIndex += sizeof(double); + } + + /// + /// Writes the base128 string to buffer. + /// + /// The buffer. + /// Index of the buffer. + /// The value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeBase128String(byte[] buffer, ref int bufferIndex, string value) + { + if (!string.IsNullOrEmpty(value)) + { + if (bufferIndex + value.Length + sizeof(short) >= buffer.Length) + { + } + + var encodedValue = Encoding.UTF8.GetBytes(value); + SerializeUInt64AsBase128(buffer, ref bufferIndex, (ulong)encodedValue.Length); + Array.Copy(encodedValue, 0, buffer, bufferIndex, encodedValue.Length); + bufferIndex += encodedValue.Length; + } + else + { + SerializeInt16(buffer, ref bufferIndex, 0); + } + } + + /// + /// Writes unsigned int value Base-128 encoded. + /// + /// Buffer used for writing. + /// Offset to start with. Will be moved to the next byte after written. + /// Value to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt32AsBase128(byte[] buffer, ref int offset, uint value) + { + SerializeUInt64AsBase128(buffer, ref offset, value); + } + + /// + /// Writes ulong value Base-128 encoded to the buffer starting from the specified offset. + /// + /// Buffer used for writing. + /// Offset to start with. Will be moved to the next byte after written. + /// Value to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeUInt64AsBase128(byte[] buffer, ref int offset, ulong value) + { + var t = value; + do + { + var b = (byte)(t & 0x7f); + t >>= 7; + if (t > 0) + { + b |= 0x80; + } + + buffer[offset++] = b; + } + while (t > 0); + } + + /// + /// Writes int value Base-128 encoded. + /// + /// Buffer used for writing. + /// Offset to start with. Will be moved to the next byte after written. + /// Value to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeInt32AsBase128(byte[] buffer, ref int offset, int value) + { + SerializeInt64AsBase128(buffer, ref offset, value); + } + + /// + /// Writes long value Base-128 encoded. + /// + /// Buffer used for writing. + /// Offset to start with. Will be moved to the next byte after written. + /// Value to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeInt64AsBase128(byte[] buffer, ref int offset, long value) + { + var negative = value < 0; + var t = negative ? -value : value; + var first = true; + do + { + byte b; + if (first) + { + b = (byte)(t & 0x3f); + t >>= 6; + if (negative) + { + b = (byte)(b | 0x40); + } + + first = false; + } + else + { + b = (byte)(t & 0x7f); + t >>= 7; + } + + if (t > 0) + { + b |= 0x80; + } + + buffer[offset++] = b; + } + while (t > 0); + } + + /// + /// Writes the encoded string to buffer. + /// + /// The buffer to write data into. + /// Index of the buffer. + /// Source data. + /// Number of bytes to copy. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void SerializeSpanOfBytes(byte[] buffer, ref int bufferIndex, Span data, int dataLength) + { + if (bufferIndex + dataLength + sizeof(short) >= buffer.Length) + { + } + + ReadOnlySpan source = data.Slice(0, dataLength); + var target = new Span(buffer, bufferIndex, dataLength); + + source.CopyTo(target); + bufferIndex += dataLength; + } } internal enum MetricEventType @@ -200,6 +383,31 @@ internal enum MetricEventType ULongMetric = 50, DoubleMetric = 55, ExternallyAggregatedULongDistributionMetric = 56, + TLV = 70, +} + +internal enum PayloadType +{ + AccountName = 1, + Namespace = 2, + MetricName = 3, + Dimensions = 4, + ULongMetric = 5, + DoubleMetric = 6, + ExternallyAggregatedULongDistributionMetric = 8, + HistogramULongValueCountPairs = 12, + Exemplars = 15, +} + +[Flags] +internal enum ExemplarFlags : byte +{ + None = 0x0, + IsMetricValueDoubleStoredAsLong = 0x1, + IsTimestampAvailable = 0x2, + SpanIdExists = 0x4, + TraceIdExists = 0x8, + SampleCountExists = 0x10, } /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index cee3871f86..9d825ce249 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -58,4 +58,9 @@ private void DoubleMetricEvent() private void ExternallyAggregatedDoubleDistributionMetric() { } + + [Event((int)MetricEventType.TLV)] + private void TLVMetricEvent() + { + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index d095eef969..41c3ddcc7b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 0f75779db8..a3b660bd58 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -569,12 +569,15 @@ public void SuccessfulExportOnLinux() var metricPoint = metricPointsEnumerator.Current; var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; - var bodyLength = exporter.SerializeMetric( + + var exemplars = metricPoint.GetExemplars(); + var bodyLength = exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, - metricData); + metricData, + exemplars); // Wait a little more than the ExportInterval for the exporter to export the data. Task.Delay(5500).Wait(); @@ -589,6 +592,9 @@ public void SuccessfulExportOnLinux() // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); + // TODO: Update the unit test to test TLV based serialization + + /* var stream = new KaitaiStream(receivedData); var data = new MetricsContract(stream); @@ -611,6 +617,7 @@ public void SuccessfulExportOnLinux() Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); Assert.Equal(bodyLength, data.LenBody); + */ } finally { From 8f609d2a789958d54cfa49a8cc41ecdafc7687d7 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Tue, 14 Mar 2023 02:27:35 +0200 Subject: [PATCH 0620/1499] Release OpenTelemetry.Instrumentation.EntityFrameworkCore 1.0.0-beta.6 (#1070) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index a10413b0cd..e6428d823d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.6 + +Released 2023-Mar-13 + * Added overloads which accept a name to the `TracerProviderBuilder` `EntityFrameworkInstrumentationOptions` extension to allow for more fine-grained options management From 78fbf822faf5ead505c3717eec9a455d1b781ebc Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 13 Mar 2023 18:48:09 -0700 Subject: [PATCH 0621/1499] Update GenevaExporter CHANGELOG for 1.5.0-alpha.1 release (#1075) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 99ca6b4a83..8e52a56a2e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.0-alpha.1 + +Released 2023-Mar-13 + * Changed the behavior of Unix domain socket connection at startup. Before this change, the exporter initialization would throw exception if the target Unix Domain Socket does not exist. After this change, the exporter initialization From 9afb1e1085df5a591efd34bfdcb8ca444452248a Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 14 Mar 2023 10:07:46 -0700 Subject: [PATCH 0622/1499] Add Piotr as Maintainer (#1074) --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 0bef2e1765..59896c989d 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,6 @@ expected to directly contribute to every component. Approvers ([@open-telemetry/dotnet-contrib-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers)): -* [Piotr Kiełkowicz](https://github.com/Kielek), Splunk - *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).* @@ -39,6 +37,7 @@ Maintainers * [Alan West](https://github.com/alanwest), New Relic * [Cijo Thomas](https://github.com/cijothomas), Microsoft * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft +* [Piotr Kiełkowicz](https://github.com/Kielek), Splunk * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft *Find more about the maintainer role in [community From 79d8297e0607cb7812a7054861a29d6789c7479f Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 14 Mar 2023 17:23:01 +0000 Subject: [PATCH 0623/1499] Enable AnalysisLevel latest-All (#969) --- build/Common.props | 1 + build/OpenTelemetryContrib.test.ruleset | 30 +++++++++++++++++++ .../Resources/AWSECSResourceDetector.cs | 12 ++++---- .../Resources/TestAWSECSResourceDetector.cs | 10 +++++-- .../Resources/TestAWSEKSResourceDetector.cs | 6 +++- .../Trace/TestAWSXRayPropagator.cs | 4 --- 6 files changed, 49 insertions(+), 14 deletions(-) diff --git a/build/Common.props b/build/Common.props index a35274d9ae..20078f7b13 100644 --- a/build/Common.props +++ b/build/Common.props @@ -9,6 +9,7 @@ net462 net6.0 netstandard2.0 + latest-All diff --git a/build/OpenTelemetryContrib.test.ruleset b/build/OpenTelemetryContrib.test.ruleset index eabc727093..9818eca018 100644 --- a/build/OpenTelemetryContrib.test.ruleset +++ b/build/OpenTelemetryContrib.test.ruleset @@ -4,6 +4,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index d252b35bb7..0379246622 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -84,7 +84,7 @@ internal static List> ExtractMetadataV4ResourceAttr return new List>(); } - var httpClientHandler = new HttpClientHandler(); + using var httpClientHandler = new HttpClientHandler(); var metadataV4ContainerResponse = ResourceDetectorUtils.SendOutRequest(metadataV4Url, "GET", null, httpClientHandler).Result; var metadataV4TaskResponse = ResourceDetectorUtils.SendOutRequest($"{metadataV4Url.TrimEnd('/')}/task", "GET", null, httpClientHandler).Result; @@ -105,9 +105,9 @@ internal static List> ExtractMetadataV4ResourceAttr return new List>(); } - if (!clusterArn.StartsWith("arn:")) + if (!clusterArn.StartsWith("arn:", StringComparison.Ordinal)) { - var baseArn = containerArn.Substring(containerArn.LastIndexOf(":")); + var baseArn = containerArn.Substring(containerArn.LastIndexOf(":", StringComparison.Ordinal)); clusterArn = $"{baseArn}:cluster/{clusterArn}"; } @@ -119,8 +119,8 @@ internal static List> ExtractMetadataV4ResourceAttr var launchType = taskResponse.Value("LaunchType") switch { - string type when "ec2".Equals(type.ToLower()) => AWSSemanticConventions.ValueEcsLaunchTypeEc2, - string type when "fargate".Equals(type.ToLower()) => AWSSemanticConventions.ValueEcsLaunchTypeFargate, + string type when string.Equals("ec2", type, StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeEc2, + string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeFargate, _ => null, }; @@ -151,7 +151,7 @@ internal static List> ExtractMetadataV4ResourceAttr resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskRevision, revision)); } - if ("awslogs".Equals(containerResponse.Value("LogDriver"))) + if (string.Equals("awslogs", containerResponse.Value("LogDriver"), StringComparison.Ordinal)) { JObject? logOptions = containerResponse.Value("LogOptions"); if (logOptions != null) diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs index 4a43a46fd3..53d029ba0d 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs @@ -50,7 +50,11 @@ public void Dispose() [Fact] public void TestNotOnEcs() { - Assert.Empty(new AWSECSResourceDetector().Detect().Attributes); + var ecsResourceDetector = new AWSECSResourceDetector(); + var resourceAttributes = ecsResourceDetector.Detect(); + + Assert.NotNull(resourceAttributes); + Assert.Empty(resourceAttributes.Attributes); } [Fact] @@ -151,14 +155,14 @@ public MockEcsMetadataEndpoint(string containerJsonPath, string taskJsonPath) var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/Resources/{containerJsonPath}"); var data = Encoding.UTF8.GetBytes(content); context.Response.ContentType = "application/json"; - await context.Response.Body.WriteAsync(data, 0, data.Length); + await context.Response.Body.WriteAsync(data); } else if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/task") { var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/Resources/{taskJsonPath}"); var data = Encoding.UTF8.GetBytes(content); context.Response.ContentType = "application/json"; - await context.Response.Body.WriteAsync(data, 0, data.Length); + await context.Response.Body.WriteAsync(data); } else { diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs index 55ed6258b7..338ca4aaa2 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs @@ -28,7 +28,11 @@ public class TestAWSEKSResourceDetector [Fact] public void TestDetect() { - Assert.Empty(new AWSEKSResourceDetector().Detect().Attributes); // will be null as it's not in eks environment + var eksResourceDetector = new AWSEKSResourceDetector(); + var resourceAttributes = eksResourceDetector.Detect(); + + Assert.NotNull(resourceAttributes); + Assert.Empty(resourceAttributes.Attributes); } [Fact] diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs index a314b89850..b3a6b4aa35 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs @@ -29,11 +29,7 @@ public class TestAWSXRayPropagator private const string TraceId = "5759e988bd862e3fe1be46a994272793"; private const string ParentId = "53995c3f42cd8ad8"; -#if NETFRAMEWORK - private static readonly string[] Empty = new string[0]; -#else private static readonly string[] Empty = Array.Empty(); -#endif private static readonly Func, string, IEnumerable> Getter = (headers, name) => { From 8ed8e583c68659ad0effadd5ded6287fa3cf453f Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 14 Mar 2023 13:35:01 -0700 Subject: [PATCH 0624/1499] Rename PersistentStorage packages (#1079) --- .github/component_owners.yml | 6 +-- ...ackage-PersistentStorage.Abstractions.yml} | 8 ++-- ... package-PersistentStorage.FileSystem.yml} | 8 ++-- opentelemetry-dotnet-contrib.sln | 42 +++++++++---------- .../.publicApi/net462/PublicAPI.Unshipped.txt | 20 --------- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 20 --------- .../netstandard2.0/PublicAPI.Unshipped.txt | 20 --------- .../.publicApi/net462/PublicAPI.Unshipped.txt | 15 ------- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 15 ------- .../netstandard2.0/PublicAPI.Unshipped.txt | 15 ------- .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 20 +++++++++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 20 +++++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 20 +++++++++ .../AssemblyInfo.cs | 0 .../CHANGELOG.md | 2 + ...try.PersistentStorage.Abstractions.csproj} | 0 .../PersistentBlob.cs | 2 +- .../PersistentBlobProvider.cs | 2 +- ...ersistentStorageAbstractionsEventSource.cs | 4 +- .../README.md | 2 + .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 15 +++++++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 15 +++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 15 +++++++ .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 4 +- .../FileBlob.cs | 4 +- .../FileBlobProvider.cs | 4 +- ...metry.PersistentStorage.FileSystem.csproj} | 2 +- .../PersistentStorageEventSource.cs | 4 +- .../PersistentStorageHelper.cs | 2 +- .../README.md | 2 + .../FileBlobProviderTests.cs | 2 +- .../FileBlobTests.cs | 4 +- ...PersistentStorage.FileSystem.Tests.csproj} | 2 +- 40 files changed, 163 insertions(+), 155 deletions(-) rename .github/workflows/{package-Extensions.PersistentStorage.Abstractions.yml => package-PersistentStorage.Abstractions.yml} (82%) rename .github/workflows/{package-Extensions.PersistentStorage.yml => package-PersistentStorage.FileSystem.yml} (89%) delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/.publicApi/net462/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/.publicApi/net6.0/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/.publicApi/netstandard2.0/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/AssemblyInfo.cs (100%) rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/CHANGELOG.md (88%) rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj => OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj} (100%) rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/PersistentBlob.cs (98%) rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/PersistentBlobProvider.cs (98%) rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/PersistentStorageAbstractionsEventSource.cs (93%) rename src/{OpenTelemetry.Extensions.PersistentStorage.Abstractions => OpenTelemetry.PersistentStorage.Abstractions}/README.md (96%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/.publicApi/net462/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/.publicApi/net6.0/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/.publicApi/netstandard2.0/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/AssemblyInfo.cs (94%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/CHANGELOG.md (93%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/FileBlob.cs (96%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/FileBlobProvider.cs (98%) rename src/{OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj => OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj} (85%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/PersistentStorageEventSource.cs (97%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/PersistentStorageHelper.cs (99%) rename src/{OpenTelemetry.Extensions.PersistentStorage => OpenTelemetry.PersistentStorage.FileSystem}/README.md (99%) rename test/{OpenTelemetry.Extensions.PersistentStorage.Tests => OpenTelemetry.PersistentStorage.FileSystem.Tests}/FileBlobProviderTests.cs (99%) rename test/{OpenTelemetry.Extensions.PersistentStorage.Tests => OpenTelemetry.PersistentStorage.FileSystem.Tests}/FileBlobTests.cs (98%) rename test/{OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj => OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj} (85%) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 37ee61990c..e851415414 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -31,9 +31,9 @@ components: - iskiselev src/OpenTelemetry.Extensions.Enrichment/: - xakep139 - src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/: + src/OpenTelemetry.PersistentStorage.Abstractions/: - vishweshbankwar - src/OpenTelemetry.Extensions.PersistentStorage/: + src/OpenTelemetry.PersistentStorage.FileSystem/: - vishweshbankwar src/OpenTelemetry.Instrumentation.AWSLambda/: - rypdal @@ -102,7 +102,7 @@ components: - iskiselev test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 - test/OpenTelemetry.Extensions.PersistentStorage.Tests/: + test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: - vishweshbankwar test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: - rypdal diff --git a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml b/.github/workflows/package-PersistentStorage.Abstractions.yml similarity index 82% rename from .github/workflows/package-Extensions.PersistentStorage.Abstractions.yml rename to .github/workflows/package-PersistentStorage.Abstractions.yml index afdff942ae..1fb68c9672 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-PersistentStorage.Abstractions.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Extensions.PersistentStorage.Abstractions +name: Pack OpenTelemetry.PersistentStorage.Abstractions on: workflow_dispatch: @@ -9,7 +9,7 @@ on: default: 'warning' push: tags: - - 'Extensions.PersistentStorage.Abstractions-*' # trigger when we create a tag with prefix "Extensions.PersistentStorage.Abstractions-" + - 'PersistentStorage.Abstractions-*' # trigger when we create a tag with prefix "PersistentStorage.Abstractions-" jobs: build-test-pack: @@ -17,7 +17,7 @@ jobs: permissions: contents: write env: - PROJECT: OpenTelemetry.Extensions.PersistentStorage.Abstractions + PROJECT: OpenTelemetry.PersistentStorage.Abstractions strategy: matrix: @@ -39,7 +39,7 @@ jobs: run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions.PersistentStorage.Abstractions has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.PersistentStorage.Abstractions has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts uses: actions/upload-artifact@v3 diff --git a/.github/workflows/package-Extensions.PersistentStorage.yml b/.github/workflows/package-PersistentStorage.FileSystem.yml similarity index 89% rename from .github/workflows/package-Extensions.PersistentStorage.yml rename to .github/workflows/package-PersistentStorage.FileSystem.yml index 0d24fef3a1..67abae901f 100644 --- a/.github/workflows/package-Extensions.PersistentStorage.yml +++ b/.github/workflows/package-PersistentStorage.FileSystem.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Extensions.PersistentStorage +name: Pack OpenTelemetry.PersistentStorage.FileSystem on: workflow_dispatch: @@ -9,7 +9,7 @@ on: default: 'warning' push: tags: - - 'Extensions.PersistentStorage-*' # trigger when we create a tag with prefix "Extensions.PersistentStorage-" + - 'PersistentStorage.FileSystem-*' # trigger when we create a tag with prefix "PersistentStorage.FileSystem-" jobs: build-test-pack: @@ -17,7 +17,7 @@ jobs: permissions: contents: write env: - PROJECT: OpenTelemetry.Extensions.PersistentStorage + PROJECT: OpenTelemetry.PersistentStorage.FileSystem strategy: matrix: @@ -42,7 +42,7 @@ jobs: run: dotnet test test/${{env.PROJECT}}.Tests - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions.PersistentStorage has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) + run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.PersistentStorage.FileSystem has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - name: Publish Artifacts uses: actions/upload-artifact@v3 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a2ad722e26..7996cef694 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -157,10 +157,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage", "src\OpenTelemetry.Extensions.PersistentStorage\OpenTelemetry.Extensions.PersistentStorage.csproj", "{C2B9190B-E2F6-4D40-B298-91521E383A50}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Tests", "test\OpenTelemetry.Extensions.PersistentStorage.Tests\OpenTelemetry.Extensions.PersistentStorage.Tests.csproj", "{61F40874-7BD2-4814-886E-8D7A463D7F5E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Instrumentation.EntityFrameworkCore\OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj", "{D4468444-69EF-4BF3-B13F-61F4AB728813}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj", "{A1F7FA66-C83D-485D-90FE-71C4018971D4}" @@ -197,8 +193,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Hangfire.Tests", "test\OpenTelemetry.Instrumentation.Hangfire.Tests\OpenTelemetry.Instrumentation.Hangfire.Tests.csproj", "{ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.PersistentStorage.Abstractions", "src\OpenTelemetry.Extensions.PersistentStorage.Abstractions\OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj", "{17E3936A-265A-4C9F-9DD5-4568F80E6D91}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana", "src\OpenTelemetry.Exporter.Instana\OpenTelemetry.Exporter.Instana.csproj", "{BD3C6377-6F8D-47D6-9710-1681ED4E6772}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Instana.Tests", "test\OpenTelemetry.Exporter.Instana.Tests\OpenTelemetry.Exporter.Instana.Tests.csproj", "{77E7DDB9-32CF-450E-B596-E893149D07DD}" @@ -253,6 +247,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.En EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Enrichment.Tests", "test\OpenTelemetry.Extensions.Enrichment.Tests\OpenTelemetry.Extensions.Enrichment.Tests.csproj", "{5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.Abstractions", "src\OpenTelemetry.PersistentStorage.Abstractions\OpenTelemetry.PersistentStorage.Abstractions.csproj", "{EC73B88E-D544-4A6A-90D5-E291035FEA35}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.FileSystem", "src\OpenTelemetry.PersistentStorage.FileSystem\OpenTelemetry.PersistentStorage.FileSystem.csproj", "{74EF2C61-9176-4D4E-91D3-E17E28054FF8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.FileSystem.Tests", "test\OpenTelemetry.PersistentStorage.FileSystem.Tests\OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj", "{C7215B69-0D77-4D52-AFBB-A6662249B3AC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -355,14 +355,6 @@ Global {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.Build.0 = Release|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C2B9190B-E2F6-4D40-B298-91521E383A50}.Release|Any CPU.Build.0 = Release|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {61F40874-7BD2-4814-886E-8D7A463D7F5E}.Release|Any CPU.Build.0 = Release|Any CPU {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -435,10 +427,6 @@ Global {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5}.Release|Any CPU.Build.0 = Release|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {17E3936A-265A-4C9F-9DD5-4568F80E6D91}.Release|Any CPU.Build.0 = Release|Any CPU {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Debug|Any CPU.Build.0 = Debug|Any CPU {BD3C6377-6F8D-47D6-9710-1681ED4E6772}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -539,6 +527,18 @@ Global {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Debug|Any CPU.Build.0 = Debug|Any CPU {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Release|Any CPU.ActiveCfg = Release|Any CPU {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38}.Release|Any CPU.Build.0 = Release|Any CPU + {EC73B88E-D544-4A6A-90D5-E291035FEA35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC73B88E-D544-4A6A-90D5-E291035FEA35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC73B88E-D544-4A6A-90D5-E291035FEA35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC73B88E-D544-4A6A-90D5-E291035FEA35}.Release|Any CPU.Build.0 = Release|Any CPU + {74EF2C61-9176-4D4E-91D3-E17E28054FF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74EF2C61-9176-4D4E-91D3-E17E28054FF8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74EF2C61-9176-4D4E-91D3-E17E28054FF8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74EF2C61-9176-4D4E-91D3-E17E28054FF8}.Release|Any CPU.Build.0 = Release|Any CPU + {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -574,8 +574,6 @@ Global {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {C2B9190B-E2F6-4D40-B298-91521E383A50} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {61F40874-7BD2-4814-886E-8D7A463D7F5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A1F7FA66-C83D-485D-90FE-71C4018971D4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -594,7 +592,6 @@ Global {A3EB4E60-256C-45EC-92EE-68FD035CAD11} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {BE5FFBBB-D73F-4071-92F4-F1694881604F} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {ED774FC3-C1C0-44CD-BA41-686C04BEB3E5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {17E3936A-265A-4C9F-9DD5-4568F80E6D91} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {BD3C6377-6F8D-47D6-9710-1681ED4E6772} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {77E7DDB9-32CF-450E-B596-E893149D07DD} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {14BAEC26-CCD1-44B5-94D7-F219057B0B4D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -622,6 +619,9 @@ Global {61520801-1CAA-4041-A3EF-CFFB9D4A180B} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {5BA85306-64B8-4E04-90EB-7069C187E250} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {5A7BE9DA-3582-49D8-A8E7-164C1E3CDB38} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {EC73B88E-D544-4A6A-90D5-E291035FEA35} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {74EF2C61-9176-4D4E-91D3-E17E28054FF8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {C7215B69-0D77-4D52-AFBB-A6662249B3AC} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index 5fa88c4d7b..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,20 +0,0 @@ -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 5fa88c4d7b..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,20 +0,0 @@ -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 5fa88c4d7b..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,20 +0,0 @@ -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index 03191b5f68..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,15 +0,0 @@ -OpenTelemetry.Extensions.PersistentStorage.FileBlob -OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryRead(out byte[] buffer) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -virtual OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 03191b5f68..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,15 +0,0 @@ -OpenTelemetry.Extensions.PersistentStorage.FileBlob -OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryRead(out byte[] buffer) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -virtual OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 03191b5f68..0000000000 --- a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,15 +0,0 @@ -OpenTelemetry.Extensions.PersistentStorage.FileBlob -OpenTelemetry.Extensions.PersistentStorage.FileBlob.FileBlob(string fullPath) -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlob.FullPath.get -> string -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose() -> void -OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryRead(out byte[] buffer) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.Extensions.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -virtual OpenTelemetry.Extensions.PersistentStorage.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..9e3f0feda4 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..9e3f0feda4 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..9e3f0feda4 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/AssemblyInfo.cs rename to src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md similarity index 88% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md rename to src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md index 1905836144..951b8da36b 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +// TODO: update changelog + ## 1.0.0-beta.1 ## 1.0.0-alpha.4 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/OpenTelemetry.Extensions.PersistentStorage.Abstractions.csproj rename to src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs similarity index 98% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs rename to src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs index 9f4d6c979b..7b01fff629 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs @@ -17,7 +17,7 @@ using System; using System.Diagnostics.CodeAnalysis; -namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions; +namespace OpenTelemetry.PersistentStorage.Abstractions; /// /// Represents a persistent blob. diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs similarity index 98% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs rename to src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs index 82b5df58f9..a6adcec637 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -19,7 +19,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; -namespace OpenTelemetry.Extensions.PersistentStorage.Abstractions; +namespace OpenTelemetry.PersistentStorage.Abstractions; /// /// Represents persistent blob provider. diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs similarity index 93% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs rename to src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs index 2e15b8b8d5..4c122d7217 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -19,13 +19,13 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Extensions.PersistentStorage; +namespace OpenTelemetry.PersistentStorage.Abstractions; [EventSource(Name = EventSourceName)] internal sealed class PersistentStorageAbstractionsEventSource : EventSource { public static PersistentStorageAbstractionsEventSource Log = new PersistentStorageAbstractionsEventSource(); - private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage-Abstractions"; + private const string EventSourceName = "OpenTelemetry-PersistentStorage-Abstractions"; [NonEvent] public void PersistentStorageAbstractionsException(string className, string message, Exception ex) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md similarity index 96% rename from src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md rename to src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 7824d9e1e6..3dbe8aa1d3 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -1,5 +1,7 @@ # Persistent Storage Abstractions +TODO:// Update Readme + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..d653ae4116 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.PersistentStorage.FileSystem.FileBlob +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[] buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..d653ae4116 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.PersistentStorage.FileSystem.FileBlob +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[] buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.PersistentStorage/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..d653ae4116 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,15 @@ +OpenTelemetry.PersistentStorage.FileSystem.FileBlob +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[] buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs similarity index 94% rename from src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs rename to src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs index 414feeffd5..7ce6e038aa 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/AssemblyInfo.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs @@ -16,7 +16,7 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.PersistentStorage.Tests" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.PersistentStorage.FileSystem.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md similarity index 93% rename from src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md rename to src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index fe44762587..19d893c4b8 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -1,4 +1,6 @@ -# Changelog - OpenTelemetry.Extensions.PersistentStorage +# Changelog - OpenTelemetry.PersistentStorage.FileSystem + +// TODO: Update changelog ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs similarity index 96% rename from src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs rename to src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs index 2772a543ba..3e07a4c1de 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs @@ -17,10 +17,10 @@ using System; using System.Diagnostics.CodeAnalysis; using System.IO; -using OpenTelemetry.Extensions.PersistentStorage.Abstractions; using OpenTelemetry.Internal; +using OpenTelemetry.PersistentStorage.Abstractions; -namespace OpenTelemetry.Extensions.PersistentStorage; +namespace OpenTelemetry.PersistentStorage.FileSystem; /// /// The allows to save a blob diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs similarity index 98% rename from src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs rename to src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index 3fc8def5eb..1fcc2e2c8e 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -20,10 +20,10 @@ using System.IO; using System.Linq; using System.Timers; -using OpenTelemetry.Extensions.PersistentStorage.Abstractions; using OpenTelemetry.Internal; +using OpenTelemetry.PersistentStorage.Abstractions; -namespace OpenTelemetry.Extensions.PersistentStorage; +namespace OpenTelemetry.PersistentStorage.FileSystem; /// /// Persistent file storage allows to save data diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj similarity index 85% rename from src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj rename to src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index e3c0346648..9532d09d8c 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/OpenTelemetry.Extensions.PersistentStorage.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs similarity index 97% rename from src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs rename to src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs index c310eeadcd..3192c453fa 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs @@ -19,13 +19,13 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Extensions.PersistentStorage; +namespace OpenTelemetry.PersistentStorage.FileSystem; [EventSource(Name = EventSourceName)] internal sealed class PersistentStorageEventSource : EventSource { public static PersistentStorageEventSource Log = new PersistentStorageEventSource(); - private const string EventSourceName = "OpenTelemetry-Extensions-PersistentStorage"; + private const string EventSourceName = "OpenTelemetry-PersistentStorage-FileSystem"; [NonEvent] public void CouldNotReadFileBlob(string filePath, Exception ex) diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs similarity index 99% rename from src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs rename to src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs index 377565d74f..e8bf18339f 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs @@ -24,7 +24,7 @@ using System.Text; using System.Threading; -namespace OpenTelemetry.Extensions.PersistentStorage; +namespace OpenTelemetry.PersistentStorage.FileSystem; internal static class PersistentStorageHelper { diff --git a/src/OpenTelemetry.Extensions.PersistentStorage/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md similarity index 99% rename from src/OpenTelemetry.Extensions.PersistentStorage/README.md rename to src/OpenTelemetry.PersistentStorage.FileSystem/README.md index c8c2749ac3..44bf5329d2 100644 --- a/src/OpenTelemetry.Extensions.PersistentStorage/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -1,5 +1,7 @@ # Persistent Storage file based implementation +// TODO: Update Readme + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs similarity index 99% rename from test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs rename to test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index 23be0a0f54..aee39ba1d5 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -20,7 +20,7 @@ using System.Threading; using Xunit; -namespace OpenTelemetry.Extensions.PersistentStorage.Tests; +namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; public class FileBlobProviderTests { diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs similarity index 98% rename from test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs rename to test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs index 3b752eab57..ede8b0d2d9 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs @@ -17,10 +17,10 @@ using System.IO; using System.Text; using System.Threading; -using OpenTelemetry.Extensions.PersistentStorage.Abstractions; +using OpenTelemetry.PersistentStorage.Abstractions; using Xunit; -namespace OpenTelemetry.Extensions.PersistentStorage.Tests; +namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; public class FileBlobTests { diff --git a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj similarity index 85% rename from test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj rename to test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index caae49f8bd..76d872a709 100644 --- a/test/OpenTelemetry.Extensions.PersistentStorage.Tests/OpenTelemetry.Extensions.PersistentStorage.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -16,7 +16,7 @@ - + From bd75ad214b234d80a5ebf21ba268fd2342eea903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 15 Mar 2023 14:35:56 +0100 Subject: [PATCH 0625/1499] [PersistentStorage] Fix issue templates (#1081) --- ...ractions.md => comp_persistentstorage.abstractions.md} | 8 ++++---- ...entstorage.md => comp_persistentstorage_filesystem.md} | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) rename .github/ISSUE_TEMPLATE/{comp_extensions_persistentstorage.abstractions.md => comp_persistentstorage.abstractions.md} (78%) rename .github/ISSUE_TEMPLATE/{comp_extensions_persistentstorage.md => comp_persistentstorage_filesystem.md} (82%) diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md b/.github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md similarity index 78% rename from .github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md rename to .github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md index bb667eec36..4f5d588e66 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.abstractions.md +++ b/.github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md @@ -1,10 +1,10 @@ --- -name: OpenTelemetry.Extensions.PersistentStorage.Abstractions -about: Issue with OpenTelemetry.Extensions.PersistentStorage.Abstractions -labels: comp:extensions.persistentstorage.abstractions +name: OpenTelemetry.PersistentStorage.Abstractions +about: Issue with OpenTelemetry.PersistentStorage.Abstractions +labels: comp:persistentstorage.abstractions --- -# Issue with OpenTelemetry.Extensions.PersistentStorage.Abstractions +# Issue with OpenTelemetry.PersistentStorage.Abstractions List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md b/.github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md similarity index 82% rename from .github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md rename to .github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md index 02b39031d2..20aec1fc5d 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_persistentstorage.md +++ b/.github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md @@ -1,10 +1,10 @@ --- -name: OpenTelemetry.Extensions.PersistentStorage -about: Issue with OpenTelemetry.Extensions.PersistentStorage -labels: comp:extensions.persistentstorage +name: OpenTelemetry.PersistentStorage.FileSystem +about: Issue with OpenTelemetry.PersistentStorage.FileSystem +labels: comp:persistentstorage.filesystem --- -# Issue with OpenTelemetry.Extensions.PersistentStorage +# Issue with PersistentStorage.FileSystem List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are From 71d9ac5cd5890293ac85440c1e2dd81c631e6221 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 15 Mar 2023 17:11:14 -0700 Subject: [PATCH 0626/1499] [PersistentStorage] Update readme and changelog after rename (#1083) --- .../CHANGELOG.md | 14 +++++++++++++- .../README.md | 8 +++----- .../CHANGELOG.md | 14 +++++++++++++- .../README.md | 8 ++++---- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md index 951b8da36b..2e059f6ad4 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,6 +1,18 @@ # Changelog -// TODO: update changelog +## 1.0.0-beta.2 (Unreleased) + +* Going forward the NuGet package will be + [`OpenTelemetry.PersistentStorage.Abstractions`](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions). + Older versions will remain at + [`OpenTelemetry.Extensions.PersistentStorage.Abstractions`](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) + [#1079](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1079) + + Migration: + + * In code update namespaces (e.g. `using + OpenTelemetry.Extensions.PersistentStorage.Abstractions` -> `using + OpenTelemetry.PersistentStorage.Abstractions`) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 3dbe8aa1d3..203dee2780 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -1,9 +1,7 @@ # Persistent Storage Abstractions -TODO:// Update Readme - -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage.Abstractions) +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) This package includes APIs which can be extended by exporter owners to implement persistent storage. @@ -11,5 +9,5 @@ persistent storage. ## Installation ```shell -dotnet add package OpenTelemetry.Extensions.PersistentStorage.Abstractions +dotnet add package --prerelease OpenTelemetry.PersistentStorage.Abstractions ``` diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index 19d893c4b8..f9a1de58f0 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -1,6 +1,18 @@ # Changelog - OpenTelemetry.PersistentStorage.FileSystem -// TODO: Update changelog +## 1.0.0-beta.2 (Unreleased) + +* Going forward the NuGet package will be + [`OpenTelemetry.PersistentStorage.FileSystem`](https://www.nuget.org/packages/OpenTelemetry.Extensions.FileSystem). + Older versions will remain at + [`OpenTelemetry.Extensions.PersistentStorage`](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) + [(#1079)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1079) + + Migration: + + * In code update namespaces (e.g. `using + OpenTelemetry.Extensions.PersistentStorage` -> `using + OpenTelemetry.Extensions.FileSystem`) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index 44bf5329d2..59e22e886a 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -2,18 +2,18 @@ // TODO: Update Readme -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.PersistentStorage.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) This package provides an implementation of -[persistent-storage-abstractions](../OpenTelemetry.Extensions.PersistentStorage.Abstractions/README.md#Persistent-Storage-Abstractions) +[persistent-storage-abstractions](../OpenTelemetry.PersistentStorage.Abstractions/README.md#Persistent-Storage-Abstractions) based on local file system. This component can be used by OpenTelemetry exporters to improve the reliability of data delivery. ## Installation ```shell -dotnet add package OpenTelemetry.Extensions.PersistentStorage +dotnet add package --prerelease OpenTelemetry.PersistentStorage.FileSystem ``` ## Basic Usage From fa26ec8d296e6dedc993b07cc34d577eb3f1d4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 16 Mar 2023 17:09:46 +0100 Subject: [PATCH 0627/1499] Execute PublicAPI analyzer on all systems (#1086) --- build/Common.prod.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.prod.props b/build/Common.prod.props index 8e855052d5..8e00384709 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -24,7 +24,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + From 90e7888350d9fd4d5913440d1bbca1068f6f065c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 16 Mar 2023 10:24:19 -0700 Subject: [PATCH 0628/1499] [OneCollector] Support common schema exception extension (#1082) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 9 ++++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 9 ++++ .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 9 ++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 9 ++++ .../netstandard2.1/PublicAPI.Unshipped.txt | 9 ++++ .../AssemblyInfo.cs | 1 + .../CHANGELOG.md | 6 ++- .../OneCollectorExporterEventSource.cs | 6 +-- .../LogRecordCommonSchemaJsonSerializer.cs | 28 +++++++++-- .../Transports/HttpJsonPostTransport.cs | 8 +--- .../Internal/Transports/IHttpClient.cs | 41 ++++++++++++++++ .../OneCollectorLogExportProcessorBuilder.cs | 25 +++++++++- .../Logs/OneCollectorLogExporterOptions.cs | 7 +++ ...ollectorLogExporterSerializationOptions.cs | 47 +++++++++++++++++++ .../OneCollectorExporterOptions.cs | 6 --- ...lizationExceptionStackTraceHandlingType.cs | 35 ++++++++++++++ .../HttpJsonPostTransportTests.cs | 6 +-- ...ogRecordCommonSchemaJsonSerializerTests.cs | 28 ++++++++++- ...lemetry.Exporter.OneCollector.Tests.csproj | 2 +- 19 files changed, 263 insertions(+), 28 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs create mode 100644 src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index baf438cdc1..427f6f8f5f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -10,6 +10,9 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallba OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -21,9 +24,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index baf438cdc1..427f6f8f5f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -10,6 +10,9 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallba OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -21,9 +24,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index baf438cdc1..427f6f8f5f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -10,6 +10,9 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallba OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -21,9 +24,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index baf438cdc1..427f6f8f5f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -10,6 +10,9 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallba OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -21,9 +24,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index baf438cdc1..427f6f8f5f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -10,6 +10,9 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallba OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void @@ -21,9 +24,15 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! diff --git a/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs index 19c1510b3e..43c488ffc0 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs @@ -18,6 +18,7 @@ [assembly: CLSCompliant(false)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OneCollector.Benchmarks" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.OneCollector.Tests" + AssemblyInfo.PublicKey)] internal static class AssemblyInfo diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 83e5ad027f..b17bc47694 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -6,10 +6,14 @@ syntax. ([#1073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1073)) -* Added support for sending common schema `dt` (Distributed Tracing) extensions +* Added support for sending common schema `dt` (Distributed Tracing) extension when trace context is present on `LogRecord`s. ([#1073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1073)) +* Added support for sending common schema `ex` (Exception) extension when + exception is present on `LogRecord`s. + ([#1082](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1082)) + ## 0.1.0-alpha.2 Released 2023-Mar-6 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index ea5c1edd0c..bb73a80a13 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -148,11 +148,7 @@ public void AttributeDropped(string itemType, string name, string reason) this.WriteEvent(11, itemType, name, reason); } - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ExceptionToInvariantString(Exception exception) + internal static string ExceptionToInvariantString(Exception exception) { var originalUICulture = Thread.CurrentThread.CurrentUICulture; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index f78ae052a5..b2d2f7f957 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -30,6 +30,10 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText DistributedTraceExtensionTraceIdProperty = JsonEncodedText.Encode("traceId"); private static readonly JsonEncodedText DistributedTraceExtensionSpanIdProperty = JsonEncodedText.Encode("spanId"); private static readonly JsonEncodedText DistributedTraceExtensionTraceFlagsProperty = JsonEncodedText.Encode("traceFlags"); + private static readonly JsonEncodedText ExceptionExtensionProperty = JsonEncodedText.Encode("ex"); + private static readonly JsonEncodedText ExceptionExtensionTypeProperty = JsonEncodedText.Encode("type"); + private static readonly JsonEncodedText ExceptionExtensionMessageProperty = JsonEncodedText.Encode("msg"); + private static readonly JsonEncodedText ExceptionExtensionStackTraceProperty = JsonEncodedText.Encode("stack"); private static readonly JsonEncodedText[] LogLevelToSeverityTextMappings = new JsonEncodedText[] { @@ -69,10 +73,12 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri }; private readonly EventNameManager eventNameManager; + private readonly OneCollectorExporterSerializationExceptionStackTraceHandlingType exceptionStackTraceHandling; public LogRecordCommonSchemaJsonSerializer( EventNameManager eventNameManager, string tenantToken, + OneCollectorExporterSerializationExceptionStackTraceHandlingType exceptionStackTraceHandling = OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore, int maxPayloadSizeInBytes = int.MaxValue, int maxNumberOfItemsPerPayload = int.MaxValue) : base(tenantToken, maxPayloadSizeInBytes, maxNumberOfItemsPerPayload) @@ -80,6 +86,7 @@ public LogRecordCommonSchemaJsonSerializer( Debug.Assert(eventNameManager != null, "eventNameManager was null"); this.eventNameManager = eventNameManager!; + this.exceptionStackTraceHandling = exceptionStackTraceHandling; } public override string Description => "LogRecord Common Schema JSON"; @@ -169,16 +176,17 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C writer.WriteEndObject(); - SerializeExtensionPropertiesToJson(item, writer, serializationState); + this.SerializeExtensionPropertiesToJson(item, writer, serializationState); writer.WriteEndObject(); } - private static void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter writer, CommonSchemaJsonSerializationState serializationState) + private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter writer, CommonSchemaJsonSerializationState serializationState) { var hasTraceContext = item.TraceId != default; + var hasException = item.Exception != null; - if (!hasTraceContext && serializationState.ExtensionAttributeCount <= 0) + if (!hasTraceContext && !hasException && serializationState.ExtensionAttributeCount <= 0) { return; } @@ -194,6 +202,20 @@ private static void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonW writer.WriteEndObject(); } + if (hasException) + { + writer.WriteStartObject(ExceptionExtensionProperty); + writer.WriteString(ExceptionExtensionTypeProperty, item.Exception!.GetType().FullName); + writer.WriteString(ExceptionExtensionMessageProperty, item.Exception.Message); + + if (this.exceptionStackTraceHandling == OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString) + { + writer.WriteString(ExceptionExtensionStackTraceProperty, OneCollectorExporterEventSource.ExceptionToInvariantString(item.Exception)); + } + + writer.WriteEndObject(); + } + serializationState.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: false); writer.WriteEndObject(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index 2324ef4a97..a65af89c19 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -31,14 +31,14 @@ internal sealed class HttpJsonPostTransport : ITransport, IDisposable private readonly Uri endpoint; private readonly string instrumentationKey; private readonly OneCollectorExporterHttpTransportCompressionType compressionType; - private readonly HttpClient httpClient; + private readonly IHttpClient httpClient; private MemoryStream? buffer; public HttpJsonPostTransport( string instrumentationKey, Uri endpoint, OneCollectorExporterHttpTransportCompressionType compressionType, - HttpClient httpClient) + IHttpClient httpClient) { Debug.Assert(!string.IsNullOrWhiteSpace(instrumentationKey), "instrumentationKey was null or whitespace"); Debug.Assert(endpoint != null, "endpoint was null"); @@ -104,11 +104,7 @@ public bool Send(in TransportSendRequest sendRequest) request.Headers.TryAddWithoutValidation("NoResponseBody", "true"); } -#if NET6_0_OR_GREATER using var response = this.httpClient.Send(request, CancellationToken.None); -#else - using var response = this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); -#endif try { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs new file mode 100644 index 0000000000..66dff2933b --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs @@ -0,0 +1,41 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +internal interface IHttpClient +{ + HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken); +} + +internal sealed class HttpClientWrapper : IHttpClient +{ + private readonly HttpClient httpClient; + + public HttpClientWrapper(HttpClient httpClient) + { + this.httpClient = httpClient; + } + + public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) + { +#if NET6_0_OR_GREATER + return this.httpClient.Send(request, CancellationToken.None); +#else + return this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); +#endif + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs index 69e47a6734..841bdcdeca 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs @@ -81,6 +81,26 @@ public OneCollectorLogExportProcessorBuilder ConfigureExporter( return this; } + /// + /// Register a callback action for configuring the serialization options + /// used by the created by the + /// builder. + /// + /// Callback action for configuring . + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder ConfigureSerializationOptions( + Action configure) + { + Guard.ThrowIfNull(configure); + + configure(this.exporterOptions.SerializationOptions); + + return this; + } + /// /// Register a callback action for configuring the transport options used by /// the created by the builder. @@ -208,18 +228,21 @@ private ISink CreateSink() var transportOptions = this.exporterOptions.TransportOptions; + var httpClient = (this.httpClientFactory ?? DefaultHttpClientFactory)() ?? throw new NotSupportedException("HttpClientFactory cannot return a null instance."); + #pragma warning disable CA2000 // Dispose objects before losing scope return new WriteDirectlyToTransportSink( new LogRecordCommonSchemaJsonSerializer( new EventNameManager(this.exporterOptions.DefaultEventNamespace, this.exporterOptions.DefaultEventName), this.exporterOptions.TenantToken!, + this.exporterOptions.SerializationOptions.ExceptionStackTraceHandling, transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, transportOptions.MaxNumberOfItemsPerPayload == -1 ? int.MaxValue : transportOptions.MaxNumberOfItemsPerPayload), new HttpJsonPostTransport( this.exporterOptions.InstrumentationKey!, transportOptions.Endpoint, transportOptions.HttpCompression, - (this.httpClientFactory ?? DefaultHttpClientFactory)() ?? throw new NotSupportedException("HttpClientFactory cannot return a null instance."))); + new HttpClientWrapper(httpClient))); #pragma warning restore CA2000 // Dispose objects before losing scope } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index f6018e1f26..9be886af87 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -35,6 +35,11 @@ public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions /// public string DefaultEventName { get; set; } = "Log"; + /// + /// Gets the OneCollector log serialization options. + /// + public OneCollectorLogExporterSerializationOptions SerializationOptions { get; } = new(); + /// /// Gets or sets the default event namespace. Default value: /// OpenTelemetry.Logs. @@ -59,6 +64,8 @@ internal override void Validate() throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventName)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); } + this.SerializationOptions.Validate(); + base.Validate(); } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs new file mode 100644 index 0000000000..8230b30d9e --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Contains serialization options used to build a instance for exporting telemetry data. +/// +public sealed class OneCollectorLogExporterSerializationOptions +{ + /// + /// Gets or sets the exception stack trace handling type. Default + /// value: . + /// + public OneCollectorExporterSerializationExceptionStackTraceHandlingType ExceptionStackTraceHandling { get; set; } + = OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore; + + /// + /// Gets or sets OneCollector serialization format. Default value: . + /// + internal OneCollectorExporterSerializationFormatType Format { get; set; } = OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream; + +#pragma warning disable CA1822 // Mark members as static + internal void Validate() +#pragma warning restore CA1822 // Mark members as static + { + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs index 540d9e0e7e..8ea82c4caf 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -51,12 +51,6 @@ internal OneCollectorExporterOptions() /// internal string? TenantToken { get; private set; } - /// - /// Gets or sets OneCollector serialization format. Default value: . - /// - internal OneCollectorExporterSerializationFormatType SerializationFormat { get; set; } = OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream; - internal virtual void Validate() { if (string.IsNullOrWhiteSpace(this.ConnectionString)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs new file mode 100644 index 0000000000..5f230c00fd --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.OneCollector; + +/// +/// Describes the OneCollector serialization behavior to use when writing the +/// stack trace for telemetry containing an instance. +/// +public enum OneCollectorExporterSerializationExceptionStackTraceHandlingType +{ + /// + /// Exception stack traces will be ignored when serializing. + /// + Ignore, + + /// + /// Exception stack traces will be included when serializing by calling . + /// + IncludeAsString, +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index 140fc7c6a3..c48fb38cc5 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -39,7 +39,7 @@ public void RequestWithoutCompressionTest() "instrumentation-key", requestUri, OneCollectorExporterHttpTransportCompressionType.None, - httpClient); + new HttpClientWrapper(httpClient)); }, (req, body) => { @@ -64,7 +64,7 @@ public void RequestUsingDeflateCompressionTest() "instrumentation-key", requestUri, OneCollectorExporterHttpTransportCompressionType.Deflate, - httpClient); + new HttpClientWrapper(httpClient)); }, (req, body) => { @@ -112,7 +112,7 @@ public void RegisterPayloadTransmittedCallbackTest() "instrumentation-key", requestUri, OneCollectorExporterHttpTransportCompressionType.None, - httpClient); + new HttpClientWrapper(httpClient)); return transport; }, diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index ec20cd563e..5c1b506325 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -186,6 +186,28 @@ public void LogRecordTraceContextJsonTest() json); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void LogRecordExceptionJsonTest(bool includeStackTraceAsString) + { + string json = GetLogRecordJson( + 1, + (index, logRecord) => + { + logRecord.Exception = new InvalidOperationException(); + }, + includeStackTraceAsString: includeStackTraceAsString); + + var stackJson = includeStackTraceAsString + ? $",\"stack\":\"System.InvalidOperationException: Operation is not valid due to the current state of the object.\"" + : string.Empty; + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}},\"ext\":{{\"ex\":{{\"type\":\"System.InvalidOperationException\",\"msg\":\"Operation is not valid due to the current state of the object.\"{stackJson}}}}}}}\n", + json); + } + [Fact] public void LogRecordExtensionsJsonTest() { @@ -217,11 +239,13 @@ private static string GetLogRecordJson( int numberOfLogRecords, Action writeLogRecordCallback, Resource? resource = null, - ScopeProvider? scopeProvider = null) + ScopeProvider? scopeProvider = null, + bool includeStackTraceAsString = false) { var serializer = new LogRecordCommonSchemaJsonSerializer( new("Namespace", "Name"), - "tenant-token"); + "tenant-token", + exceptionStackTraceHandling: includeStackTraceAsString ? OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString : OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore); using var stream = new MemoryStream(); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index bf5c8efbf9..be7e96512f 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -1,7 +1,7 @@ - Unit test project for OneCollector Exporters for OpenTelemetry + Unit test project for OpenTelemetry .NET OneCollectorExporter. net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 From 5f587d47e394dbdffe75b7bbfbc6c292604a8429 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 16 Mar 2023 13:59:07 -0700 Subject: [PATCH 0629/1499] [Persistent storage] Disable unstable test (#1090) --- .../FileBlobProviderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index aee39ba1d5..ea9161f8f6 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -50,7 +50,7 @@ public void FileBlobProvider_E2E_Test() testDirectory.Delete(true); } - [Fact] + [Fact(Skip = "Unstable")] public void FileBlobProvider_CreateBlobReturnsNullIfblobProviderIsFull() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); From 8f8d153e4b9cd9cd039d19e809dee7bebf880632 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 16 Mar 2023 15:34:33 -0700 Subject: [PATCH 0630/1499] [OneCollector] Add benchmark project (#1088) --- .github/component_owners.yml | 3 + opentelemetry-dotnet-contrib.sln | 7 + ...ecordCommonSchemaJsonHttpPostBenchmarks.cs | 194 ++++++++++++++++++ ...ry.Exporter.OneCollector.Benchmarks.csproj | 23 +++ .../Program.cs | 49 +++++ 5 files changed, 276 insertions(+) create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs diff --git a/.github/component_owners.yml b/.github/component_owners.yml index e851415414..b56276d2b2 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -91,6 +91,9 @@ components: - Yun-Ting test/OpenTelemetry.Exporter.Instana.Tests/: - zivaninstana + test/OpenTelemetry.Exporter.OneCollector.Benchmarks/: + - codeblanch + - reyang test/OpenTelemetry.Exporter.OneCollector.Tests/: - codeblanch - reyang diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7996cef694..0cd96af5e0 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -253,6 +253,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentSto EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.FileSystem.Tests", "test\OpenTelemetry.PersistentStorage.FileSystem.Tests\OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj", "{C7215B69-0D77-4D52-AFBB-A6662249B3AC}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Benchmarks", "test\OpenTelemetry.Exporter.OneCollector.Benchmarks\OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj", "{C42868C8-968A-473F-AC39-AC97C5D47E84}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -539,6 +541,10 @@ Global {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Release|Any CPU.Build.0 = Release|Any CPU + {C42868C8-968A-473F-AC39-AC97C5D47E84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C42868C8-968A-473F-AC39-AC97C5D47E84}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C42868C8-968A-473F-AC39-AC97C5D47E84}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C42868C8-968A-473F-AC39-AC97C5D47E84}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -622,6 +628,7 @@ Global {EC73B88E-D544-4A6A-90D5-E291035FEA35} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {74EF2C61-9176-4D4E-91D3-E17E28054FF8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {C7215B69-0D77-4D52-AFBB-A6662249B3AC} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {C42868C8-968A-473F-AC39-AC97C5D47E84} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs new file mode 100644 index 0000000000..1fc6e46c24 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -0,0 +1,194 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Net; +using System.Reflection; +using BenchmarkDotNet.Attributes; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Exporter.OneCollector.Benchmarks; + +[MemoryDiagnoser] +public class LogRecordCommonSchemaJsonHttpPostBenchmarks +{ + private static readonly MethodInfo LogRecordSetScopeProviderMethodInfo = typeof(LogRecord).GetProperty("ScopeProvider", BindingFlags.Instance | BindingFlags.NonPublic)?.SetMethod + ?? throw new InvalidOperationException("LogRecord.ScopeProvider.Set could not be found reflectively."); + + private LogRecord[]? logRecords; + private OneCollectorExporter? exporter; + + [Params(1, 10, 100)] + public int NumberOfBatches { get; set; } + + [Params(1000, 10_000)] + public int NumberOfLogRecordsPerBatch { get; set; } + + [Params(true, false)] + public bool EnableCompression { get; set; } + + [GlobalSetup] + public void GlobalSetup() + { + this.logRecords = new LogRecord[this.NumberOfLogRecordsPerBatch]; + + for (int i = 0; i < this.NumberOfLogRecordsPerBatch; i++) + { + this.logRecords[i] = CreateLogRecord(i); + } + + var exporterOptions = new OneCollectorLogExporterOptions + { + ConnectionString = "InstrumentationKey=token-extrainformation", + }; + + exporterOptions.Validate(); + + var transportOptions = exporterOptions.TransportOptions; + + transportOptions.HttpCompression = this.EnableCompression + ? OneCollectorExporterHttpTransportCompressionType.Deflate + : OneCollectorExporterHttpTransportCompressionType.None; + + var sink = new WriteDirectlyToTransportSink( + new LogRecordCommonSchemaJsonSerializer( + new EventNameManager(exporterOptions.DefaultEventNamespace, exporterOptions.DefaultEventName), + exporterOptions.TenantToken!, + exporterOptions.SerializationOptions.ExceptionStackTraceHandling, + transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, + transportOptions.MaxNumberOfItemsPerPayload == -1 ? int.MaxValue : transportOptions.MaxNumberOfItemsPerPayload), + new HttpJsonPostTransport( + exporterOptions.InstrumentationKey!, + transportOptions.Endpoint, + transportOptions.HttpCompression, + new NoopHttpClient())); + + this.exporter = new OneCollectorExporter(sink); + } + + [GlobalCleanup] + public void GlobalCleanup() + { + this.exporter?.Dispose(); + } + + [Benchmark] + public void Export() + { + for (int i = 0; i < this.NumberOfBatches; i++) + { + this.exporter!.Export(new Batch(this.logRecords!, this.logRecords!.Length)); + } + } + + private static LogRecord CreateLogRecord(int index) + { + var logRecord = (LogRecord)Activator.CreateInstance(typeof(LogRecord), nonPublic: true)!; + + logRecord.Timestamp = DateTime.UtcNow; + logRecord.CategoryName = typeof(LogRecordCommonSchemaJsonHttpPostBenchmarks).FullName; + logRecord.LogLevel = LogLevel.Information; + + if (index % 2 == 0) + { + if (index % 4 == 0) + { + logRecord.EventId = new EventId(2, "MyEvent"); + } + else + { + logRecord.EventId = new EventId(1); + } + + logRecord.StateValues = new List> + { + new KeyValuePair("userId", 18), + new KeyValuePair("greeting", "hello world"), + new KeyValuePair("{OriginalFormat}", "Structured logging {userId} {greeting}"), + }; + + if (index % 3 == 0) + { + var scopeProvider = new ScopeProvider( + new List> { new KeyValuePair("scope1Key1", "scope1Value1"), new KeyValuePair("scope1Key2", "scope1Value2") }, + new List> { new KeyValuePair("scope2Key1", "scope2Value1") }); + + LogRecordSetScopeProviderMethodInfo.Invoke(logRecord, new object[] { scopeProvider }); + } + } + else + { + logRecord.FormattedMessage = "Non-structured log message"; + } + + if (index % 3 == 0) + { + logRecord.TraceId = ActivityTraceId.CreateRandom(); + logRecord.SpanId = ActivitySpanId.CreateRandom(); + + if (index % 6 == 0) + { + logRecord.TraceFlags = ActivityTraceFlags.None; + } + else + { + logRecord.TraceFlags = ActivityTraceFlags.Recorded; + } + } + + if (index % 9 == 0) + { + logRecord.Exception = new InvalidOperationException(); + } + + return logRecord; + } + + private sealed class NoopHttpClient : IHttpClient + { + public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) + { + return new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + }; + } + } + + private sealed class ScopeProvider : IExternalScopeProvider + { + private readonly List>[] scopes; + + public ScopeProvider(params List>[] scopes) + { + this.scopes = scopes; + } + + public void ForEachScope(Action callback, TState state) + { + foreach (var scope in this.scopes) + { + callback(scope, state); + } + } + + public IDisposable Push(object state) + { + throw new NotImplementedException(); + } + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj new file mode 100644 index 0000000000..8e257e1321 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -0,0 +1,23 @@ + + + + Exe + Benchmark project for OpenTelemetry .NET OneCollectorExporter. + + net7.0;net6.0 + $(TargetFrameworks);net48;net472;net471;net47;net462 + enable + true + true + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs new file mode 100644 index 0000000000..85eef601f1 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using BenchmarkDotNet.Running; + +namespace OpenTelemetry.Exporter.OneCollector.Benchmarks; + +internal static class Program +{ + public static void Main(string[] args) + { + if (Debugger.IsAttached) + { + // Note: This block is so you can start the project with debugger + // attached and step through the code. It is helpful when working on + // it. + var benchmarks = new LogRecordCommonSchemaJsonHttpPostBenchmarks + { + NumberOfBatches = 10_000, + NumberOfLogRecordsPerBatch = 1000, + EnableCompression = true, + }; + + benchmarks.GlobalSetup(); + + benchmarks.Export(); + + benchmarks.GlobalCleanup(); + } + else + { + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); + } + } +} From 6c29bc90653a1c8a342dd7bcd93cf8f6fac1134f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 17 Mar 2023 20:30:26 +0100 Subject: [PATCH 0631/1499] [PersistentStorage.FileSystem] Nullable (#1085) --- ...metry.PersistentStorage.Abstractions.csproj | 4 ---- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 18 +++++++++--------- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 18 +++++++++--------- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 18 +++++++++--------- .../FileBlob.cs | 2 +- .../FileBlobProvider.cs | 10 +++++----- ...lemetry.PersistentStorage.FileSystem.csproj | 1 + .../FileBlobProviderTests.cs | 6 ------ .../FileBlobTests.cs | 7 ++++--- ...y.PersistentStorage.FileSystem.Tests.csproj | 1 + 13 files changed, 42 insertions(+), 46 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index 1e434c0cb4..3c2fc65c5c 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -7,10 +7,6 @@ net6.0;$(TargetFrameworks) OpenTelemetry Persistent Storage Abstractions Extensions.PersistentStorage.Abstractions- - $(NoWarn),CA1031 - - - $(NoWarn),1591 enable true diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt index d653ae4116..a3ca421004 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,15 +1,15 @@ OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[] buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt index d653ae4116..a3ca421004 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,15 +1,15 @@ OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[] buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index d653ae4116..a3ca421004 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,15 +1,15 @@ OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[] buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[] buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs index 3e07a4c1de..2b18bb87a4 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs @@ -40,7 +40,7 @@ public FileBlob(string fullPath) public string FullPath { get; private set; } - protected override bool OnTryRead([NotNullWhen(true)] out byte[] buffer) + protected override bool OnTryRead([NotNullWhen(true)] out byte[]? buffer) { try { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index 1fcc2e2c8e..cf0477980d 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -137,28 +137,28 @@ protected override IEnumerable OnGetBlobs() } } - protected override bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob blob) + protected override bool OnTryCreateBlob(byte[] buffer, int leasePeriodMilliseconds, [NotNullWhen(true)] out PersistentBlob? blob) { blob = this.CreateFileBlob(buffer, leasePeriodMilliseconds); return blob != null; } - protected override bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob blob) + protected override bool OnTryCreateBlob(byte[] buffer, [NotNullWhen(true)] out PersistentBlob? blob) { blob = this.CreateFileBlob(buffer); return blob != null; } - protected override bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob blob) + protected override bool OnTryGetBlob([NotNullWhen(true)] out PersistentBlob? blob) { blob = this.OnGetBlobs().FirstOrDefault(); return blob != null; } - private void OnMaintenanceEvent(object source, ElapsedEventArgs e) + private void OnMaintenanceEvent(object? source, ElapsedEventArgs e) { try { @@ -191,7 +191,7 @@ private bool CheckStorageSize() return true; } - private PersistentBlob CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) + private PersistentBlob? CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) { if (!this.CheckStorageSize()) { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 9532d09d8c..9deb66221d 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -11,6 +11,7 @@ $(NoWarn),1591 + enable diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index ea9161f8f6..8cd5a9127e 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -66,12 +66,6 @@ public void FileBlobProvider_CreateBlobReturnsNullIfblobProviderIsFull() testDirectory.Delete(true); } - [Fact] - public void FileBlobProvider_PathIsRequired() - { - Assert.Throws(() => new FileBlobProvider(null)); - } - [Fact] public void FileBlobProvider_TestRetentionPeriod() { diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs index ede8b0d2d9..8c6aeb938b 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.IO; using System.Text; using System.Threading; @@ -184,9 +185,9 @@ public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() [Fact] public void FileBlobTests_FailedWrite() { - var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob = new FileBlob(testFile.FullName); + var nonExistingPath = Path.Combine("FakePath:/", Path.GetRandomFileName()); + FileBlob blob = new FileBlob(nonExistingPath); - Assert.False(blob.TryWrite(null)); + Assert.False(blob.TryWrite(Array.Empty())); } } diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 76d872a709..4e658387ac 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 + enable From 9b8a7740f3a0cea8a9ba55af15551347c5786ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 20 Mar 2023 18:58:07 +0100 Subject: [PATCH 0632/1499] [Instrumentation.MySqlData] Nullable (#1094) --- .../Api/StatusHelper.cs | 10 +++--- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 4 +-- .../MySqlActivitySourceHelper.cs | 4 +-- .../MySqlDataInstrumentation.cs | 8 ++--- .../MySqlDataTraceCommand.cs | 4 +-- ...Telemetry.Instrumentation.MySqlData.csproj | 31 ++++++++++--------- .../TracerProviderBuilderExtensions.cs | 2 +- .../ActivityHelperExtensions.cs | 6 ++-- .../TestActivityExportProcessor.cs | 2 ++ .../TestActivityProcessor.cs | 6 ++-- .../TestSampler.cs | 4 ++- .../MySqlDataTests.cs | 4 +-- ...try.Instrumentation.MySqlData.Tests.csproj | 1 + 14 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs index 36db9d9e94..51f4b69163 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Runtime.CompilerServices; using OpenTelemetry.Trace; @@ -27,7 +29,7 @@ internal static class StatusHelper public const string ErrorStatusCodeTagValue = "ERROR"; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string GetTagValueForStatusCode(StatusCode statusCode) + public static string? GetTagValueForStatusCode(StatusCode statusCode) { return statusCode switch { @@ -53,9 +55,9 @@ public static string GetTagValueForStatusCode(StatusCode statusCode) * first because assumption is most spans will be * Unset, then Error. Ok is not set by the SDK. */ - string _ when UnsetStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Unset, - string _ when ErrorStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Error, - string _ when OkStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Ok, + not null when UnsetStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Unset, + not null when ErrorStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Error, + not null when OkStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Ok, _ => (StatusCode?)null, }; } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index dfbbe41dcb..ab0a45b98a 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,5 +7,5 @@ OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.RecordEx OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.get -> bool OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs index fdb1866307..96a7648d55 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs @@ -33,9 +33,9 @@ internal class MySqlActivitySourceHelper public static readonly string ActivitySourceName = AssemblyName.Name; public static readonly string ActivityName = ActivitySourceName + ".Execute"; - public static readonly IEnumerable> CreationTags = new[] + public static readonly IEnumerable> CreationTags = new[] { - new KeyValuePair(SemanticConventions.AttributeDbSystem, MysqlDatabaseSystemName), + new KeyValuePair(SemanticConventions.AttributeDbSystem, MysqlDatabaseSystemName), }; private static readonly Version Version = typeof(MySqlActivitySourceHelper).Assembly.GetName().Version; diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index 31f10c9968..60478a2edf 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -34,9 +34,9 @@ internal class MySqlDataInstrumentation : DefaultTraceListener private readonly MySqlDataInstrumentationOptions options; - private readonly Func builderFactory; + private readonly Func? builderFactory; - public MySqlDataInstrumentation(MySqlDataInstrumentationOptions options = null) + public MySqlDataInstrumentation(MySqlDataInstrumentationOptions? options = null) { this.options = options ?? new MySqlDataInstrumentationOptions(); MySqlTrace.Listeners.Clear(); @@ -186,7 +186,7 @@ private void BeforeExecuteCommand(MySqlDataTraceCommand command) var activity = MySqlActivitySourceHelper.ActivitySource.StartActivity( MySqlActivitySourceHelper.ActivityName, ActivityKind.Client, - Activity.Current?.Context ?? default(ActivityContext), + Activity.Current?.Context ?? default, MySqlActivitySourceHelper.CreationTags); if (activity == null) { @@ -262,7 +262,7 @@ private void ErrorExecuteCommand(Exception exception) } } - private MySqlDataTraceCommand GetCommand(object driverIdObj, object cmd) + private MySqlDataTraceCommand GetCommand(object driverIdObj, object? cmd) { var command = new MySqlDataTraceCommand(); if (this.dbConn.TryGetValue((long)driverIdObj, out var database)) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs index 3d988581ed..9cb857725c 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Instrumentation.MySqlData; /// internal class MySqlDataTraceCommand { - public MySqlConnectionStringBuilder ConnectionStringBuilder { get; set; } + public MySqlConnectionStringBuilder? ConnectionStringBuilder { get; set; } - public string SqlText { get; set; } + public string SqlText { get; set; } = string.Empty; } diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index 221dec0bd4..f11c391fd3 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -1,22 +1,23 @@ - - netstandard2.0 - OpenTelemetry instrumentation for MySql.Data - $(PackageTags);distributed-tracing;MySql.Data - Instrumentation.MySqlData- - + + netstandard2.0 + OpenTelemetry instrumentation for MySql.Data + $(PackageTags);distributed-tracing;MySql.Data + Instrumentation.MySqlData- + enable + - - - - + + + + - - - - - + + + + + diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs index 111cf5e74e..ac4e5d2550 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs @@ -41,7 +41,7 @@ public static TracerProviderBuilder AddMySqlDataInstrumentation(this TracerProvi /// The instance of to chain the calls. public static TracerProviderBuilder AddMySqlDataInstrumentation( this TracerProviderBuilder builder, - Action configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs b/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs index c4fec75bd4..af79715a55 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs @@ -14,16 +14,16 @@ // limitations under the License. // +#nullable enable + using System.Diagnostics; namespace OpenTelemetry.Tests; internal static class ActivityHelperExtensions { - public static object GetTagValue(this Activity activity, string tagName) + public static object? GetTagValue(this Activity activity, string tagName) { - Debug.Assert(activity != null, "Activity should not be null"); - foreach (var tag in activity.TagObjects) { if (tag.Key == tagName) diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs index 129e806e3a..d063109fca 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs index 21ab4cf235..1bc05b08fe 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Diagnostics; @@ -21,8 +23,8 @@ namespace OpenTelemetry.Tests; internal sealed class TestActivityProcessor : BaseProcessor { - public Action StartAction; - public Action EndAction; + public Action? StartAction; + public Action? EndAction; public TestActivityProcessor() { diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs index 7ab20376a3..a275d8d97c 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using OpenTelemetry.Trace; @@ -21,7 +23,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.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs index 0f29d966f6..af3c489051 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs @@ -53,7 +53,7 @@ public void SuccessTraceEventTest( }) .Build(); - var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); + var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners)!; ExecuteSuccessQuery(traceListener, commandText, isFailure); @@ -93,7 +93,7 @@ public void UnknownMySqlTraceEventType(MySqlTraceEventType eventType) .AddMySqlDataInstrumentation() .Build(); - var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners); + var traceListener = (TraceListener?)Assert.Single(MySqlTrace.Listeners); traceListener?.TraceEvent( new TraceEventCache(), diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj index b3cd48bbc9..cc1be05fd1 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj @@ -3,6 +3,7 @@ net7.0;net6.0 true + enable From b06a6f290fc59a292994e2ba9973eefe0691fa19 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Mon, 20 Mar 2023 13:48:34 -0700 Subject: [PATCH 0633/1499] [Exporter.Geneva] Update GenevaMetricExporter tests (#1076) --- .../External/MetricsContract.cs | 1441 +++++++++++++++++ .../External/VlqBase128Le.cs | 158 ++ .../GenevaMetricExporterTests.cs | 43 +- .../MetricsContract.cs | 664 -------- 4 files changed, 1624 insertions(+), 682 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/External/MetricsContract.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/External/VlqBase128Le.cs delete mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/External/MetricsContract.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/External/MetricsContract.cs new file mode 100644 index 0000000000..0f356132d7 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/External/MetricsContract.cs @@ -0,0 +1,1441 @@ +// + +using System.Collections.Generic; +using Kaitai; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +public partial class MetricsContract : KaitaiStruct +{ + public static MetricsContract FromFile(string fileName) + { + return new MetricsContract(new KaitaiStream(fileName)); + } + + + public enum MetricEventType + { + Old = 0, + Uint64Metric = 50, + DoubleScaledToLongMetric = 51, + BatchMetric = 52, + ExternallyAggregatedUlongMetric = 53, + ExternallyAggregatedDoubleMetric = 54, + DoubleMetric = 55, + ExternallyAggregatedUlongDistributionMetric = 56, + ExternallyAggregatedDoubleDistributionMetric = 57, + ExternallyAggregatedDoubleScaledToLongDistributionMetric = 58, + Tlv = 70, + } + + public enum DistributionType + { + Bucketed = 0, + MonBucketed = 1, + ValueCountPairs = 2, + } + + public enum PayloadTypes + { + AccountName = 1, + NamespaceName = 2, + MetricName = 3, + Dimensions = 4, + SingleUint64Value = 5, + SingleDoubleValue = 6, + SingleDoubleScaledToUint64Value = 7, + ExtAggregatedUint64Value = 8, + ExtAggregatedDoubleValue = 9, + ExtAggregatedDoubleScaledToUint64Value = 10, + HistogramUint16Bucketed = 11, + HistogramUint64ValueCountPairs = 12, + HistogramDoubleScaledToUint64ValueCountPairs = 13, + ReservedForDoubleHistogram = 14, + Exemplars = 15, + } + public MetricsContract(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root ?? this; + f_eventType = false; + _read(); + } + private void _read() + { + _eventId = m_io.ReadU2le(); + _lenBody = m_io.ReadU2le(); + switch (EventType) + { + case MetricEventType.Tlv: + { + __raw_body = m_io.ReadBytes(LenBody); + var io___raw_body = new KaitaiStream(__raw_body); + _body = new UserdataV2(io___raw_body, this, m_root); + break; + } + default: + { + __raw_body = m_io.ReadBytes(LenBody); + var io___raw_body = new KaitaiStream(__raw_body); + _body = new Userdata(EventId, io___raw_body, this, m_root); + break; + } + } + } + + /// + /// This type represents "UserData" or "body" portion of Metrics message. + /// + public partial class Userdata : KaitaiStruct + { + public Userdata(ushort p_eventId, KaitaiStream p__io, MetricsContract p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _eventId = p_eventId; + _read(); + } + private void _read() + { + _numDimensions = m_io.ReadU2le(); + _padding = m_io.ReadBytes(2); + switch (M_Parent.EventType) + { + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric: + { + _valueSection = new ExtAggregatedDoubleValue(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.DoubleMetric: + { + _valueSection = new SingleDoubleValue(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedUlongMetric: + { + _valueSection = new ExtAggregatedUint64Value(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric: + { + _valueSection = new ExtAggregatedUint64Value(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric: + { + _valueSection = new ExtAggregatedDoubleValue(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.DoubleScaledToLongMetric: + { + _valueSection = new SingleDoubleValue(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.Uint64Metric: + { + _valueSection = new SingleUint64Value(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.ExternallyAggregatedDoubleMetric: + { + _valueSection = new ExtAggregatedDoubleValue(m_io, this, m_root); + break; + } + case MetricsContract.MetricEventType.Old: + { + _valueSection = new SingleUint64Value(m_io, this, m_root); + break; + } + } + _metricAccount = new LenString(m_io, this, m_root); + _metricNamespace = new LenString(m_io, this, m_root); + _metricName = new LenString(m_io, this, m_root); + _dimensionsNames = new List((int)(NumDimensions)); + for (var i = 0; i < NumDimensions; i++) + { + _dimensionsNames.Add(new LenString(m_io, this, m_root)); + } + _dimensionsValues = new List((int)(NumDimensions)); + for (var i = 0; i < NumDimensions; i++) + { + _dimensionsValues.Add(new LenString(m_io, this, m_root)); + } + if (!(M_Io.IsEof)) + { + _apContainer = new LenString(m_io, this, m_root); + } + if (((((M_Parent.EventType == MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric) || (M_Parent.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric) || (M_Parent.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric))) && (!(M_Io.IsEof)))) + { + _histogram = new Histogram(m_io, this, m_root); + } + } + private ushort _numDimensions; + private byte[] _padding; + private KaitaiStruct _valueSection; + private LenString _metricAccount; + private LenString _metricNamespace; + private LenString _metricName; + private List _dimensionsNames; + private List _dimensionsValues; + private LenString _apContainer; + private Histogram _histogram; + private ushort _eventId; + private MetricsContract m_root; + private MetricsContract m_parent; + + /// + /// Number of dimensions specified in this event. + /// + public ushort NumDimensions { get { return _numDimensions; } } + public byte[] Padding { get { return _padding; } } + + /// + /// Value section of the body, stores fixed numeric metric value(s), as per event type. + /// + public KaitaiStruct ValueSection { get { return _valueSection; } } + + /// + /// Geneva Metrics account name to be used for this metric. + /// + public LenString MetricAccount { get { return _metricAccount; } } + + /// + /// Geneva Metrics namespace name to be used for this metric. + /// + public LenString MetricNamespace { get { return _metricNamespace; } } + + /// + /// Geneva Metrics metric name to be used. + /// + public LenString MetricName { get { return _metricName; } } + + /// + /// Dimension names strings ("key" parts of key-value pairs). Must be sorted, + /// unless MetricsExtenion's option `enableDimensionSortingOnIngestion` is + /// enabled. + /// + public List DimensionsNames { get { return _dimensionsNames; } } + + /// + /// Dimension values strings ("value" parts of key-value pairs). + /// + public List DimensionsValues { get { return _dimensionsValues; } } + + public LenString ApContainer { get { return _apContainer; } } + public Histogram Histogram { get { return _histogram; } } + + /// + /// Type of message, affects format of the body. + /// + public ushort EventId { get { return _eventId; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract M_Parent { get { return m_parent; } } + } + + /// + /// Bucket with an explicitly-defined value coordinate `value`, claiming to + /// hold `count` hits. Normally used to represent non-linear (e.g. exponential) + /// histograms payloads. + /// + public partial class PairValueCount : KaitaiStruct + { + public static PairValueCount FromFile(string fileName) + { + return new PairValueCount(new KaitaiStream(fileName)); + } + + public PairValueCount(KaitaiStream p__io, MetricsContract.HistogramValueCountPairs p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _value = m_io.ReadU8le(); + _count = m_io.ReadU4le(); + } + private ulong _value; + private uint _count; + private MetricsContract m_root; + private MetricsContract.HistogramValueCountPairs m_parent; + public ulong Value { get { return _value; } } + public uint Count { get { return _count; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.HistogramValueCountPairs M_Parent { get { return m_parent; } } + } + public partial class ExemplarFlags : KaitaiStruct + { + public static ExemplarFlags FromFile(string fileName) + { + return new ExemplarFlags(new KaitaiStream(fileName)); + } + + public ExemplarFlags(KaitaiStream p__io, MetricsContract.SingleExemplarBody p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + __unnamed0 = m_io.ReadBitsIntBe(3); + _sampleCountExists = m_io.ReadBitsIntBe(1) != 0; + _traceIdExists = m_io.ReadBitsIntBe(1) != 0; + _spanIdExists = m_io.ReadBitsIntBe(1) != 0; + _isTimestampAvailable = m_io.ReadBitsIntBe(1) != 0; + _isMetricValueDoubleStoredAsLong = m_io.ReadBitsIntBe(1) != 0; + } + private ulong __unnamed0; + private bool _sampleCountExists; + private bool _traceIdExists; + private bool _spanIdExists; + private bool _isTimestampAvailable; + private bool _isMetricValueDoubleStoredAsLong; + private MetricsContract m_root; + private MetricsContract.SingleExemplarBody m_parent; + public ulong Unnamed_0 { get { return __unnamed0; } } + public bool SampleCountExists { get { return _sampleCountExists; } } + public bool TraceIdExists { get { return _traceIdExists; } } + public bool SpanIdExists { get { return _spanIdExists; } } + public bool IsTimestampAvailable { get { return _isTimestampAvailable; } } + public bool IsMetricValueDoubleStoredAsLong { get { return _isMetricValueDoubleStoredAsLong; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.SingleExemplarBody M_Parent { get { return m_parent; } } + } + public partial class SingleUint64ValueV2 : KaitaiStruct + { + public static SingleUint64ValueV2 FromFile(string fileName) + { + return new SingleUint64ValueV2(new KaitaiStream(fileName)); + } + + public SingleUint64ValueV2(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _timestamp = m_io.ReadU8le(); + _value = m_io.ReadU8le(); + } + private ulong _timestamp; + private ulong _value; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Metric value as 64-bit unsigned integer. + /// + public ulong Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + public partial class WrappedString : KaitaiStruct + { + public static WrappedString FromFile(string fileName) + { + return new WrappedString(new KaitaiStream(fileName)); + } + + public WrappedString(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _value = System.Text.Encoding.GetEncoding("UTF-8").GetString(m_io.ReadBytesFull()); + } + private string _value; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + public string Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + + /// + /// Payload of a histogram with linear distribution of buckets. Such histogram + /// is defined by the parameters specified in `min`, `bucket_size` and + /// `bucket_count`. It is modelled as a series of buckets. First (index 0) and + /// last (indexed `bucket_count - 1`) buckets are special and are supposed to + /// catch all "underflow" and "overflow" values. Buckets with indexes 1 up to + /// `bucket_count - 2` are regular buckets of size `bucket_size`. + /// + public partial class HistogramUint16Bucketed : KaitaiStruct + { + public static HistogramUint16Bucketed FromFile(string fileName) + { + return new HistogramUint16Bucketed(new KaitaiStream(fileName)); + } + + public HistogramUint16Bucketed(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _min = m_io.ReadU8le(); + _bucketSize = m_io.ReadU4le(); + _bucketCount = m_io.ReadU4le(); + _distributionSize = m_io.ReadU2le(); + _columns = new List((int)(DistributionSize)); + for (var i = 0; i < DistributionSize; i++) + { + _columns.Add(new PairUint16(m_io, this, m_root)); + } + } + private ulong _min; + private uint _bucketSize; + private uint _bucketCount; + private ushort _distributionSize; + private List _columns; + private MetricsContract m_root; + private KaitaiStruct m_parent; + public ulong Min { get { return _min; } } + public uint BucketSize { get { return _bucketSize; } } + public uint BucketCount { get { return _bucketCount; } } + public ushort DistributionSize { get { return _distributionSize; } } + public List Columns { get { return _columns; } } + public MetricsContract M_Root { get { return m_root; } } + public KaitaiStruct M_Parent { get { return m_parent; } } + } + public partial class HistogramValueCountPairs : KaitaiStruct + { + public static HistogramValueCountPairs FromFile(string fileName) + { + return new HistogramValueCountPairs(new KaitaiStream(fileName)); + } + + public HistogramValueCountPairs(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _distributionSize = m_io.ReadU2le(); + _columns = new List((int)(DistributionSize)); + for (var i = 0; i < DistributionSize; i++) + { + _columns.Add(new PairValueCount(m_io, this, m_root)); + } + } + private ushort _distributionSize; + private List _columns; + private MetricsContract m_root; + private KaitaiStruct m_parent; + public ushort DistributionSize { get { return _distributionSize; } } + public List Columns { get { return _columns; } } + public MetricsContract M_Root { get { return m_root; } } + public KaitaiStruct M_Parent { get { return m_parent; } } + } + + /// + /// Recorded values that associates trace signals to a metric event within a metric. + /// + public partial class Exemplars : KaitaiStruct + { + public static Exemplars FromFile(string fileName) + { + return new Exemplars(new KaitaiStream(fileName)); + } + + public Exemplars(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _version = m_io.ReadU1(); + _numberOfExemplars = new VlqBase128Le(m_io); + _exemplarList = new List((int)(NumberOfExemplars.Value)); + for (var i = 0; i < NumberOfExemplars.Value; i++) + { + _exemplarList.Add(new SingleExemplar(m_io, this, m_root)); + } + } + private byte _version; + private VlqBase128Le _numberOfExemplars; + private List _exemplarList; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + + /// + /// The version of exemplar package. + /// + public byte Version { get { return _version; } } + public VlqBase128Le NumberOfExemplars { get { return _numberOfExemplars; } } + public List ExemplarList { get { return _exemplarList; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + public partial class SingleDoubleValueV2 : KaitaiStruct + { + public static SingleDoubleValueV2 FromFile(string fileName) + { + return new SingleDoubleValueV2(new KaitaiStream(fileName)); + } + + public SingleDoubleValueV2(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _timestamp = m_io.ReadU8le(); + _value = m_io.ReadF8le(); + } + private ulong _timestamp; + private double _value; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Metric value as double. + /// + public double Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + public partial class ExtAggregatedUint64ValueV2 : KaitaiStruct + { + public static ExtAggregatedUint64ValueV2 FromFile(string fileName) + { + return new ExtAggregatedUint64ValueV2(new KaitaiStream(fileName)); + } + + public ExtAggregatedUint64ValueV2(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _count = m_io.ReadU4le(); + _padding = m_io.ReadBytes(4); + _timestamp = m_io.ReadU8le(); + _sum = m_io.ReadU8le(); + _min = m_io.ReadU8le(); + _max = m_io.ReadU8le(); + } + private uint _count; + private byte[] _padding; + private ulong _timestamp; + private ulong _sum; + private ulong _min; + private ulong _max; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + public uint Count { get { return _count; } } + + /// + /// Count of events aggregated in this event. + /// + public byte[] Padding { get { return _padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public ulong Sum { get { return _sum; } } + + /// + /// Minimum of all metric values aggregated in this event. + /// + public ulong Min { get { return _min; } } + + /// + /// Maximum of all metric values aggregated in this event. + /// + public ulong Max { get { return _max; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + public partial class Histogram : KaitaiStruct + { + public static Histogram FromFile(string fileName) + { + return new Histogram(new KaitaiStream(fileName)); + } + + public Histogram(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _version = m_io.ReadU1(); + _type = ((MetricsContract.DistributionType)m_io.ReadU1()); + switch (Type) + { + case MetricsContract.DistributionType.Bucketed: + { + _body = new HistogramUint16Bucketed(m_io, this, m_root); + break; + } + case MetricsContract.DistributionType.MonBucketed: + { + _body = new HistogramUint16Bucketed(m_io, this, m_root); + break; + } + case MetricsContract.DistributionType.ValueCountPairs: + { + _body = new HistogramValueCountPairs(m_io, this, m_root); + break; + } + } + } + private byte _version; + private DistributionType _type; + private KaitaiStruct _body; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte Version { get { return _version; } } + public DistributionType Type { get { return _type; } } + public KaitaiStruct Body { get { return _body; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.Userdata M_Parent { get { return m_parent; } } + } + + /// + /// double or long stored as base 128encoded. + /// + public partial class DoubleOrVlq : KaitaiStruct + { + public DoubleOrVlq(bool p_isDoubleStoredAsLong, KaitaiStream p__io, MetricsContract.SingleExemplarBody p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _isDoubleStoredAsLong = p_isDoubleStoredAsLong; + _read(); + } + private void _read() + { + if (IsDoubleStoredAsLong) + { + _valueAsVlq = new VlqBase128Le(m_io); + } + if (IsDoubleStoredAsLong == false) + { + _valueAsDouble = m_io.ReadF8le(); + } + } + private VlqBase128Le _valueAsVlq; + private double? _valueAsDouble; + private bool _isDoubleStoredAsLong; + private MetricsContract m_root; + private MetricsContract.SingleExemplarBody m_parent; + public VlqBase128Le ValueAsVlq { get { return _valueAsVlq; } } + public double? ValueAsDouble { get { return _valueAsDouble; } } + public bool IsDoubleStoredAsLong { get { return _isDoubleStoredAsLong; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.SingleExemplarBody M_Parent { get { return m_parent; } } + } + + /// + /// A single exemplar data. + /// + public partial class SingleExemplar : KaitaiStruct + { + public static SingleExemplar FromFile(string fileName) + { + return new SingleExemplar(new KaitaiStream(fileName)); + } + + public SingleExemplar(KaitaiStream p__io, MetricsContract.Exemplars p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _version = m_io.ReadU1(); + _length = m_io.ReadU1(); + __raw_body = m_io.ReadBytes((Length - 2)); + var io___raw_body = new KaitaiStream(__raw_body); + _body = new SingleExemplarBody(io___raw_body, this, m_root); + } + private byte _version; + private byte _length; + private SingleExemplarBody _body; + private MetricsContract m_root; + private MetricsContract.Exemplars m_parent; + private byte[] __raw_body; + + /// + /// The version of single exemplar scheme. + /// + public byte Version { get { return _version; } } + + /// + /// Total length of single_exemplar, allows to skip parsing the exemplar data during aggregation. + /// + public byte Length { get { return _length; } } + + /// + /// Minus 2 comes from the size of version + size of length fields) + /// + public SingleExemplarBody Body { get { return _body; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.Exemplars M_Parent { get { return m_parent; } } + public byte[] M_RawBody { get { return __raw_body; } } + } + public partial class TlvField : KaitaiStruct + { + public static TlvField FromFile(string fileName) + { + return new TlvField(new KaitaiStream(fileName)); + } + + public TlvField(KaitaiStream p__io, MetricsContract.UserdataV2 p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _type = ((MetricsContract.PayloadTypes)m_io.ReadU1()); + _lenValue = m_io.ReadU2le(); + switch (Type) + { + case MetricsContract.PayloadTypes.HistogramDoubleScaledToUint64ValueCountPairs: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new HistogramValueCountPairs(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.SingleDoubleScaledToUint64Value: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new SingleDoubleValueV2(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.MetricName: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new WrappedString(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.ExtAggregatedUint64Value: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new ExtAggregatedUint64ValueV2(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.ExtAggregatedDoubleValue: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new ExtAggregatedDoubleValueV2(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.SingleDoubleValue: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new SingleDoubleValueV2(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.SingleUint64Value: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new SingleUint64ValueV2(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.Dimensions: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new Dimensions(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.NamespaceName: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new WrappedString(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.ExtAggregatedDoubleScaledToUint64Value: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new ExtAggregatedDoubleValueV2(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.Exemplars: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new Exemplars(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.HistogramUint64ValueCountPairs: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new HistogramValueCountPairs(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.AccountName: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new WrappedString(io___raw_value, this, m_root); + break; + } + case MetricsContract.PayloadTypes.HistogramUint16Bucketed: + { + __raw_value = m_io.ReadBytes(LenValue); + var io___raw_value = new KaitaiStream(__raw_value); + _value = new HistogramUint16Bucketed(io___raw_value, this, m_root); + break; + } + default: + { + _value = m_io.ReadBytes(LenValue); + break; + } + } + } + private PayloadTypes _type; + private ushort _lenValue; + private object _value; + private MetricsContract m_root; + private MetricsContract.UserdataV2 m_parent; + private byte[] __raw_value; + public PayloadTypes Type { get { return _type; } } + public ushort LenValue { get { return _lenValue; } } + public object Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.UserdataV2 M_Parent { get { return m_parent; } } + public byte[] M_RawValue { get { return __raw_value; } } + } + + /// + /// Bucket #index, claiming to hold exactly `count` hits. See notes in + /// `histogram_uint16_bucketed` for interpreting index. + /// + public partial class PairUint16 : KaitaiStruct + { + public static PairUint16 FromFile(string fileName) + { + return new PairUint16(new KaitaiStream(fileName)); + } + + public PairUint16(KaitaiStream p__io, MetricsContract.HistogramUint16Bucketed p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _index = m_io.ReadU2le(); + _count = m_io.ReadU2le(); + } + private ushort _index; + private ushort _count; + private MetricsContract m_root; + private MetricsContract.HistogramUint16Bucketed m_parent; + public ushort Index { get { return _index; } } + public ushort Count { get { return _count; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.HistogramUint16Bucketed M_Parent { get { return m_parent; } } + } + public partial class SingleUint64Value : KaitaiStruct + { + public static SingleUint64Value FromFile(string fileName) + { + return new SingleUint64Value(new KaitaiStream(fileName)); + } + + public SingleUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _padding = m_io.ReadBytes(4); + _timestamp = m_io.ReadU8le(); + _value = m_io.ReadU8le(); + } + private byte[] _padding; + private ulong _timestamp; + private ulong _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte[] Padding { get { return _padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Metric value as 64-bit unsigned integer. + /// + public ulong Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.Userdata M_Parent { get { return m_parent; } } + } + public partial class Dimensions : KaitaiStruct + { + public static Dimensions FromFile(string fileName) + { + return new Dimensions(new KaitaiStream(fileName)); + } + + public Dimensions(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _numDimensions = m_io.ReadU2le(); + _dimensionsNames = new List((int)(NumDimensions)); + for (var i = 0; i < NumDimensions; i++) + { + _dimensionsNames.Add(new LenString(m_io, this, m_root)); + } + _dimensionsValues = new List((int)(NumDimensions)); + for (var i = 0; i < NumDimensions; i++) + { + _dimensionsValues.Add(new LenString(m_io, this, m_root)); + } + } + private ushort _numDimensions; + private List _dimensionsNames; + private List _dimensionsValues; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + + /// + /// Number of dimensions specified in this event. + /// + public ushort NumDimensions { get { return _numDimensions; } } + + /// + /// Dimension names strings ("key" parts of key-value pairs). Must be sorted, + /// unless MetricsExtenion's option `enableDimensionSortingOnIngestion` is + /// enabled. + /// + public List DimensionsNames { get { return _dimensionsNames; } } + + /// + /// Dimension values strings ("value" parts of key-value pairs). + /// + public List DimensionsValues { get { return _dimensionsValues; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + public partial class ExtAggregatedDoubleValue : KaitaiStruct + { + public static ExtAggregatedDoubleValue FromFile(string fileName) + { + return new ExtAggregatedDoubleValue(new KaitaiStream(fileName)); + } + + public ExtAggregatedDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _count = m_io.ReadU4le(); + _timestamp = m_io.ReadU8le(); + _sum = m_io.ReadF8le(); + _min = m_io.ReadF8le(); + _max = m_io.ReadF8le(); + } + private uint _count; + private ulong _timestamp; + private double _sum; + private double _min; + private double _max; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + + /// + /// Count of events aggregated in this event. + /// + public uint Count { get { return _count; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public double Sum { get { return _sum; } } + + /// + /// Minimum of all metric values aggregated in this event. + /// + public double Min { get { return _min; } } + + /// + /// Maximum of all metric values aggregated in this event. + /// + public double Max { get { return _max; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.Userdata M_Parent { get { return m_parent; } } + } + public partial class ExtAggregatedUint64Value : KaitaiStruct + { + public static ExtAggregatedUint64Value FromFile(string fileName) + { + return new ExtAggregatedUint64Value(new KaitaiStream(fileName)); + } + + public ExtAggregatedUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _count = m_io.ReadU4le(); + _timestamp = m_io.ReadU8le(); + _sum = m_io.ReadU8le(); + _min = m_io.ReadU8le(); + _max = m_io.ReadU8le(); + } + private uint _count; + private ulong _timestamp; + private ulong _sum; + private ulong _min; + private ulong _max; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + + /// + /// Count of events aggregated in this event. + /// + public uint Count { get { return _count; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public ulong Sum { get { return _sum; } } + + /// + /// Minimum of all metric values aggregated in this event. + /// + public ulong Min { get { return _min; } } + + /// + /// Maximum of all metric values aggregated in this event. + /// + public ulong Max { get { return _max; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.Userdata M_Parent { get { return m_parent; } } + } + public partial class SingleDoubleValue : KaitaiStruct + { + public static SingleDoubleValue FromFile(string fileName) + { + return new SingleDoubleValue(new KaitaiStream(fileName)); + } + + public SingleDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _padding = m_io.ReadBytes(4); + _timestamp = m_io.ReadU8le(); + _value = m_io.ReadF8le(); + } + private byte[] _padding; + private ulong _timestamp; + private double _value; + private MetricsContract m_root; + private MetricsContract.Userdata m_parent; + public byte[] Padding { get { return _padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Metric value as double. + /// + public double Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.Userdata M_Parent { get { return m_parent; } } + } + + /// + /// Label name-value pair which are in vlq_string type. + /// + public partial class LabelPair : KaitaiStruct + { + public static LabelPair FromFile(string fileName) + { + return new LabelPair(new KaitaiStream(fileName)); + } + + public LabelPair(KaitaiStream p__io, MetricsContract.SingleExemplarBody p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _name = new VlqString(m_io, this, m_root); + _value = new VlqString(m_io, this, m_root); + } + private VlqString _name; + private VlqString _value; + private MetricsContract m_root; + private MetricsContract.SingleExemplarBody m_parent; + public VlqString Name { get { return _name; } } + public VlqString Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.SingleExemplarBody M_Parent { get { return m_parent; } } + } + public partial class ExtAggregatedDoubleValueV2 : KaitaiStruct + { + public static ExtAggregatedDoubleValueV2 FromFile(string fileName) + { + return new ExtAggregatedDoubleValueV2(new KaitaiStream(fileName)); + } + + public ExtAggregatedDoubleValueV2(KaitaiStream p__io, MetricsContract.TlvField p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _count = m_io.ReadU4le(); + _padding = m_io.ReadBytes(4); + _timestamp = m_io.ReadU8le(); + _sum = m_io.ReadF8le(); + _min = m_io.ReadF8le(); + _max = m_io.ReadF8le(); + } + private uint _count; + private byte[] _padding; + private ulong _timestamp; + private double _sum; + private double _min; + private double _max; + private MetricsContract m_root; + private MetricsContract.TlvField m_parent; + + /// + /// Count of events aggregated in this event. + /// + public uint Count { get { return _count; } } + public byte[] Padding { get { return _padding; } } + + /// + /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. + /// + public ulong Timestamp { get { return _timestamp; } } + + /// + /// Sum of all metric values aggregated in this event. + /// + public double Sum { get { return _sum; } } + + /// + /// Minimum of all metric values aggregated in this event. + /// + public double Min { get { return _min; } } + + /// + /// Maximum of all metric values aggregated in this event. + /// + public double Max { get { return _max; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.TlvField M_Parent { get { return m_parent; } } + } + + /// + /// A single exemplar data. + /// + public partial class SingleExemplarBody : KaitaiStruct + { + public static SingleExemplarBody FromFile(string fileName) + { + return new SingleExemplarBody(new KaitaiStream(fileName)); + } + + public SingleExemplarBody(KaitaiStream p__io, MetricsContract.SingleExemplar p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _flags = new ExemplarFlags(m_io, this, m_root); + _value = new DoubleOrVlq(Flags.IsMetricValueDoubleStoredAsLong, m_io, this, m_root); + _numberOfLabels = m_io.ReadU1(); + if (Flags.IsTimestampAvailable) + { + _timeUnixNano = m_io.ReadU8le(); + } + if (Flags.TraceIdExists) + { + _traceId = m_io.ReadBytes(16); + } + if (Flags.SpanIdExists) + { + _spanId = m_io.ReadBytes(8); + } + if (Flags.SampleCountExists) + { + _sampleCount = m_io.ReadF8le(); + } + _labels = new List((int)(NumberOfLabels)); + for (var i = 0; i < NumberOfLabels; i++) + { + _labels.Add(new LabelPair(m_io, this, m_root)); + } + } + private ExemplarFlags _flags; + private DoubleOrVlq _value; + private byte _numberOfLabels; + private ulong? _timeUnixNano; + private byte[] _traceId; + private byte[] _spanId; + private double? _sampleCount; + private List _labels; + private MetricsContract m_root; + private MetricsContract.SingleExemplar m_parent; + + /// + /// Defines characteristics of an exemplar. + /// + public ExemplarFlags Flags { get { return _flags; } } + + /// + /// Metric value as double. + /// + public DoubleOrVlq Value { get { return _value; } } + + /// + /// Total number of filtered labels. + /// + public byte NumberOfLabels { get { return _numberOfLabels; } } + + /// + /// Exact time that the measurement was recorded. + /// + public ulong? TimeUnixNano { get { return _timeUnixNano; } } + + /// + /// Trace ID of the current trace. + /// + public byte[] TraceId { get { return _traceId; } } + + /// + /// Span ID of the current trace. + /// + public byte[] SpanId { get { return _spanId; } } + + /// + /// When sample_count is non-zero, this exemplar has been chosen in a statistically + /// unbiased way such that the exemplar is representative of `sample_count` individual events. + /// + public double? SampleCount { get { return _sampleCount; } } + + /// + /// Dimension key-value pairs. + /// + public List Labels { get { return _labels; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.SingleExemplar M_Parent { get { return m_parent; } } + } + public partial class UserdataV2 : KaitaiStruct + { + public static UserdataV2 FromFile(string fileName) + { + return new UserdataV2(new KaitaiStream(fileName)); + } + + public UserdataV2(KaitaiStream p__io, MetricsContract p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _fields = new List(); + { + var i = 0; + while (!m_io.IsEof) + { + _fields.Add(new TlvField(m_io, this, m_root)); + i++; + } + } + } + private List _fields; + private MetricsContract m_root; + private MetricsContract m_parent; + public List Fields { get { return _fields; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract M_Parent { get { return m_parent; } } + } + + /// + /// A simple string, length-prefixed with a 2-byte integer. + /// + public partial class LenString : KaitaiStruct + { + public static LenString FromFile(string fileName) + { + return new LenString(new KaitaiStream(fileName)); + } + + public LenString(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _lenValue = m_io.ReadU2le(); + _value = System.Text.Encoding.GetEncoding("UTF-8").GetString(m_io.ReadBytes(LenValue)); + } + private ushort _lenValue; + private string _value; + private MetricsContract m_root; + private KaitaiStruct m_parent; + public ushort LenValue { get { return _lenValue; } } + public string Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public KaitaiStruct M_Parent { get { return m_parent; } } + } + + /// + /// UTF-8 string with its length prefixed using a VLQ integer. + /// + public partial class VlqString : KaitaiStruct + { + public static VlqString FromFile(string fileName) + { + return new VlqString(new KaitaiStream(fileName)); + } + + public VlqString(KaitaiStream p__io, MetricsContract.LabelPair p__parent = null, MetricsContract p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + _read(); + } + private void _read() + { + _lenValue = new VlqBase128Le(m_io); + _value = System.Text.Encoding.GetEncoding("UTF-8").GetString(m_io.ReadBytes(LenValue.Value)); + } + private VlqBase128Le _lenValue; + private string _value; + private MetricsContract m_root; + private MetricsContract.LabelPair m_parent; + public VlqBase128Le LenValue { get { return _lenValue; } } + public string Value { get { return _value; } } + public MetricsContract M_Root { get { return m_root; } } + public MetricsContract.LabelPair M_Parent { get { return m_parent; } } + } + private bool f_eventType; + private MetricEventType _eventType; + public MetricEventType EventType + { + get + { + if (f_eventType) + return _eventType; + _eventType = (MetricEventType)(((MetricEventType)EventId)); + f_eventType = true; + return _eventType; + } + } + private ushort _eventId; + private ushort _lenBody; + private KaitaiStruct _body; + private MetricsContract m_root; + private KaitaiStruct m_parent; + private byte[] __raw_body; + + /// + /// Type of message, affects format of the body. + /// + public ushort EventId { get { return _eventId; } } + + /// + /// Size of body in bytes. + /// + public ushort LenBody { get { return _lenBody; } } + + /// + /// Body of Metrics binary protocol message. + /// + public KaitaiStruct Body { get { return _body; } } + public MetricsContract M_Root { get { return m_root; } } + public KaitaiStruct M_Parent { get { return m_parent; } } + public byte[] M_RawBody { get { return __raw_body; } } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/External/VlqBase128Le.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/External/VlqBase128Le.cs new file mode 100644 index 0000000000..c33b43dfb0 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/External/VlqBase128Le.cs @@ -0,0 +1,158 @@ +// + +using System.Collections.Generic; +using Kaitai; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +/// +/// A variable-length unsigned integer using base128 encoding. 1-byte groups +/// consist of 1-bit flag of continuation and 7-bit value chunk, and are ordered +/// "least significant group first", i.e. in "little-endian" manner. +/// +/// This particular encoding is specified and used in: +/// +/// * DWARF debug file format, where it's dubbed "unsigned LEB128" or "ULEB128". +/// http://dwarfstd.org/doc/dwarf-2.0.0.pdf - page 139 +/// * Google Protocol Buffers, where it's called "Base 128 Varints". +/// https://developers.google.com/protocol-buffers/docs/encoding?csw=1#varints +/// * Apache Lucene, where it's called "VInt" +/// http://lucene.apache.org/core/3_5_0/fileformats.html#VInt +/// * Apache Avro uses this as a basis for integer encoding, adding ZigZag on +/// top of it for signed ints +/// http://avro.apache.org/docs/current/spec.html#binary_encode_primitive +/// +/// More information on this encoding is available at https://en.wikipedia.org/wiki/LEB128 +/// +/// This particular implementation supports serialized values to up 8 bytes long. +/// +public partial class VlqBase128Le : KaitaiStruct +{ + public static VlqBase128Le FromFile(string fileName) + { + return new VlqBase128Le(new KaitaiStream(fileName)); + } + + public VlqBase128Le(KaitaiStream p__io, KaitaiStruct p__parent = null, VlqBase128Le p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root ?? this; + f_len = false; + f_value = false; + _read(); + } + private void _read() + { + _groups = new List(); + { + var i = 0; + Group M_; + do + { + M_ = new Group(m_io, this, m_root); + _groups.Add(M_); + i++; + } while (!(!(M_.HasNext))); + } + } + + /// + /// One byte group, clearly divided into 7-bit "value" chunk and 1-bit "continuation" flag. + /// + public partial class Group : KaitaiStruct + { + public static Group FromFile(string fileName) + { + return new Group(new KaitaiStream(fileName)); + } + + public Group(KaitaiStream p__io, VlqBase128Le p__parent = null, VlqBase128Le p__root = null) : base(p__io) + { + m_parent = p__parent; + m_root = p__root; + f_hasNext = false; + f_value = false; + _read(); + } + private void _read() + { + _b = m_io.ReadU1(); + } + private bool f_hasNext; + private bool _hasNext; + + /// + /// If true, then we have more bytes to read + /// + public bool HasNext + { + get + { + if (f_hasNext) + return _hasNext; + _hasNext = (bool)((B & 128) != 0); + f_hasNext = true; + return _hasNext; + } + } + private bool f_value; + private int _value; + + /// + /// The 7-bit (base128) numeric value chunk of this group + /// + public int Value + { + get + { + if (f_value) + return _value; + _value = (int)((B & 127)); + f_value = true; + return _value; + } + } + private byte _b; + private VlqBase128Le m_root; + private VlqBase128Le m_parent; + public byte B { get { return _b; } } + public VlqBase128Le M_Root { get { return m_root; } } + public VlqBase128Le M_Parent { get { return m_parent; } } + } + private bool f_len; + private int _len; + public int Len + { + get + { + if (f_len) + return _len; + _len = (int)(Groups.Count); + f_len = true; + return _len; + } + } + private bool f_value; + private int _value; + + /// + /// Resulting value as normal integer + /// + public int Value + { + get + { + if (f_value) + return _value; + _value = (int)((((((((Groups[0].Value + (Len >= 2 ? (Groups[1].Value << 7) : 0)) + (Len >= 3 ? (Groups[2].Value << 14) : 0)) + (Len >= 4 ? (Groups[3].Value << 21) : 0)) + (Len >= 5 ? (Groups[4].Value << 28) : 0)) + (Len >= 6 ? (Groups[5].Value << 35) : 0)) + (Len >= 7 ? (Groups[6].Value << 42) : 0)) + (Len >= 8 ? (Groups[7].Value << 49) : 0))); + f_value = true; + return _value; + } + } + private List _groups; + private VlqBase128Le m_root; + private KaitaiStruct m_parent; + public List Groups { get { return _groups; } } + public VlqBase128Le M_Root { get { return m_root; } } + public KaitaiStruct M_Parent { get { return m_parent; } } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index a3b660bd58..be873f2a89 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -723,6 +723,7 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; MetricsContract data = null; + Userdata userData = null; // Check metric value, timestamp, eventId, and length of payload if (metricType == MetricType.LongSum) @@ -738,7 +739,8 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as SingleUint64Value; + userData = data.Body as Userdata; + var valueSection = userData.ValueSection as SingleUint64Value; Assert.Equal(metricDataValue, valueSection.Value); Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); @@ -757,7 +759,8 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as SingleDoubleValue; + userData = data.Body as Userdata; + var valueSection = userData.ValueSection as SingleDoubleValue; Assert.Equal(metricDataValue, valueSection.Value); Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); @@ -778,7 +781,8 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as SingleDoubleValue; + userData = data.Body as Userdata; + var valueSection = userData.ValueSection as SingleDoubleValue; Assert.Equal(metricDataValue, valueSection.Value); Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); @@ -799,7 +803,8 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as SingleDoubleValue; + userData = data.Body as Userdata; + var valueSection = userData.ValueSection as SingleDoubleValue; Assert.Equal(metricDataValue, valueSection.Value); Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); @@ -832,11 +837,13 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE var buffer = typeof(GenevaMetricExporter).GetField("bufferForHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); data = new MetricsContract(stream); - var valueSection = data.Body.ValueSection as ExtAggregatedUint64Value; - var valueCountPairs = data.Body.Histogram.Body as HistogramValueCountPairs; + userData = data.Body as Userdata; + var valueSection = userData.ValueSection as ExtAggregatedUint64Value; + var histogram = userData.Histogram; + var valueCountPairs = userData.Histogram.Body as HistogramValueCountPairs; - Assert.Equal(0, data.Body.Histogram.Version); - Assert.Equal(2, (int)data.Body.Histogram.Type); + Assert.Equal(0, histogram.Version); + Assert.Equal(2, (int)histogram.Type); int listIterator = 0; int bucketsWithPositiveCount = 0; @@ -866,17 +873,17 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); - Assert.Equal(metric.Name, data.Body.MetricName.Value); - Assert.Equal(connectionStringBuilder.Account, data.Body.MetricAccount.Value); - Assert.Equal(connectionStringBuilder.Namespace, data.Body.MetricNamespace.Value); + Assert.Equal(metric.Name, userData.MetricName.Value); + Assert.Equal(connectionStringBuilder.Account, userData.MetricAccount.Value); + Assert.Equal(connectionStringBuilder.Namespace, userData.MetricNamespace.Value); var dimensionsCount = 0; if (exporterOptions.PrepopulatedMetricDimensions != null) { foreach (var entry in exporterOptions.PrepopulatedMetricDimensions) { - Assert.Contains(data.Body.DimensionsNames, dim => dim.Value == entry.Key); - Assert.Contains(data.Body.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); + Assert.Contains(userData.DimensionsNames, dim => dim.Value == entry.Key); + Assert.Contains(userData.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); } dimensionsCount += exporterOptions.PrepopulatedMetricDimensions.Count; @@ -886,20 +893,20 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE int i = 0; foreach (var item in exporterOptions.PrepopulatedMetricDimensions) { - Assert.Equal(item.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(item.Value, data.Body.DimensionsValues[i].Value); + Assert.Equal(item.Key, userData.DimensionsNames[i].Value); + Assert.Equal(item.Value, userData.DimensionsValues[i].Value); i++; } foreach (var tag in metricPoint.Tags) { - Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); + Assert.Equal(tag.Key, userData.DimensionsNames[i].Value); + Assert.Equal(tag.Value, userData.DimensionsValues[i].Value); i++; } dimensionsCount += metricPoint.Tags.Count; - Assert.Equal(dimensionsCount, data.Body.NumDimensions); + Assert.Equal(dimensionsCount, userData.NumDimensions); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs deleted file mode 100644 index d14dcbf93f..0000000000 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MetricsContract.cs +++ /dev/null @@ -1,664 +0,0 @@ -// - -using System.Collections.Generic; -using Kaitai; - -namespace OpenTelemetry.Exporter.Geneva.Tests; - -public partial class MetricsContract : KaitaiStruct -{ - public static MetricsContract FromFile(string fileName) - { - return new MetricsContract(new KaitaiStream(fileName)); - } - - - public enum MetricEventType - { - Old = 0, - Uint64Metric = 50, - DoubleScaledToLongMetric = 51, - BatchMetric = 52, - ExternallyAggregatedUlongMetric = 53, - ExternallyAggregatedDoubleMetric = 54, - DoubleMetric = 55, - ExternallyAggregatedUlongDistributionMetric = 56, - ExternallyAggregatedDoubleDistributionMetric = 57, - ExternallyAggregatedDoubleScaledToLongDistributionMetric = 58, - } - - public enum DistributionType - { - Bucketed = 0, - MonBucketed = 1, - ValueCountPairs = 2, - } - public MetricsContract(KaitaiStream p__io, KaitaiStruct p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root ?? this; - this._read(); - } - private void _read() - { - this._eventId = this.m_io.ReadU2le(); - this._lenBody = this.m_io.ReadU2le(); - this.__raw_body = this.m_io.ReadBytes(this.LenBody); - var io___raw_body = new KaitaiStream(this.__raw_body); - this._body = new Userdata(this.EventId, io___raw_body, this, this.m_root); - } - - /// - /// This type represents "UserData" or "body" portion of Metrics message. - /// - public partial class Userdata : KaitaiStruct - { - public Userdata(ushort p_eventId, KaitaiStream p__io, MetricsContract p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._eventId = p_eventId; - this.f_eventType = false; - this._read(); - } - private void _read() - { - this._numDimensions = this.m_io.ReadU2le(); - this._padding = this.m_io.ReadBytes(2); - switch (this.EventType) - { - case MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric: - { - this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.DoubleMetric: - { - this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedUlongMetric: - { - this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric: - { - this._valueSection = new ExtAggregatedUint64Value(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric: - { - this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.DoubleScaledToLongMetric: - { - this._valueSection = new SingleDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.Uint64Metric: - { - this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.ExternallyAggregatedDoubleMetric: - { - this._valueSection = new ExtAggregatedDoubleValue(this.m_io, this, this.m_root); - break; - } - case MetricsContract.MetricEventType.Old: - { - this._valueSection = new SingleUint64Value(this.m_io, this, this.m_root); - break; - } - } - this._metricAccount = new LenString(this.m_io, this, this.m_root); - this._metricNamespace = new LenString(this.m_io, this, this.m_root); - this._metricName = new LenString(this.m_io, this, this.m_root); - this._dimensionsNames = new List((int)this.NumDimensions); - for (var i = 0; i < this.NumDimensions; i++) - { - this._dimensionsNames.Add(new LenString(this.m_io, this, this.m_root)); - } - this._dimensionsValues = new List((int)this.NumDimensions); - for (var i = 0; i < this.NumDimensions; i++) - { - this._dimensionsValues.Add(new LenString(this.m_io, this, this.m_root)); - } - if (!this.M_Io.IsEof) - { - this._apContainer = new LenString(this.m_io, this, this.m_root); - } - if (((this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedUlongDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleDistributionMetric) || (this.EventType == MetricsContract.MetricEventType.ExternallyAggregatedDoubleScaledToLongDistributionMetric)) && (!this.M_Io.IsEof)) - { - this._histogram = new Histogram(this.m_io, this, this.m_root); - } - } - private bool f_eventType; - private MetricEventType _eventType; - public MetricEventType EventType - { - get - { - if (this.f_eventType) - return this._eventType; - this._eventType = (MetricEventType)(MetricsContract.MetricEventType)this.EventId; - this.f_eventType = true; - return this._eventType; - } - } - private ushort _numDimensions; - private byte[] _padding; - private KaitaiStruct _valueSection; - private LenString _metricAccount; - private LenString _metricNamespace; - private LenString _metricName; - private List _dimensionsNames; - private List _dimensionsValues; - private LenString _apContainer; - private Histogram _histogram; - private ushort _eventId; - private MetricsContract m_root; - private MetricsContract m_parent; - - /// - /// Number of dimensions specified in this event. - /// - public ushort NumDimensions { get { return this._numDimensions; } } - public byte[] Padding { get { return this._padding; } } - - /// - /// Value section of the body, stores fixed numeric metric value(s), as per event type. - /// - public KaitaiStruct ValueSection { get { return this._valueSection; } } - - /// - /// Geneva Metrics account name to be used for this metric. - /// - public LenString MetricAccount { get { return this._metricAccount; } } - - /// - /// Geneva Metrics namespace name to be used for this metric. - /// - public LenString MetricNamespace { get { return this._metricNamespace; } } - - /// - /// Geneva Metrics metric name to be used. - /// - public LenString MetricName { get { return this._metricName; } } - - /// - /// Dimension names strings ("key" parts of key-value pairs). Must be sorted, - /// unless MetricsExtenion's option `enableDimensionSortingOnIngestion` is - /// enabled. - /// - public List DimensionsNames { get { return this._dimensionsNames; } } - - /// - /// Dimension values strings ("value" parts of key-value pairs). - /// - public List DimensionsValues { get { return this._dimensionsValues; } } - - /// - /// AutoPilot container string, required for correct AP PKI certificate loading - /// in AutoPilot containers environment. - /// - public LenString ApContainer { get { return this._apContainer; } } - public Histogram Histogram { get { return this._histogram; } } - - /// - /// Type of message, affects format of the body. - /// - public ushort EventId { get { return this._eventId; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract M_Parent { get { return this.m_parent; } } - } - - /// - /// Bucket with an explicitly-defined value coordinate `value`, claiming to - /// hold `count` hits. Normally used to represent non-linear (e.g. exponential) - /// histograms payloads. - /// - public partial class PairValueCount : KaitaiStruct - { - public static PairValueCount FromFile(string fileName) - { - return new PairValueCount(new KaitaiStream(fileName)); - } - - public PairValueCount(KaitaiStream p__io, MetricsContract.HistogramValueCountPairs p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._value = this.m_io.ReadU8le(); - this._count = this.m_io.ReadU4le(); - } - private ulong _value; - private uint _count; - private MetricsContract m_root; - private MetricsContract.HistogramValueCountPairs m_parent; - public ulong Value { get { return this._value; } } - public uint Count { get { return this._count; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.HistogramValueCountPairs M_Parent { get { return this.m_parent; } } - } - - /// - /// Payload of a histogram with linear distribution of buckets. Such histogram - /// is defined by the parameters specified in `min`, `bucket_size` and - /// `bucket_count`. It is modelled as a series of buckets. First (index 0) and - /// last (indexed `bucket_count - 1`) buckets are special and are supposed to - /// catch all "underflow" and "overflow" values. Buckets with indexes 1 up to - /// `bucket_count - 2` are regular buckets of size `bucket_size`. - /// - public partial class HistogramUint16Bucketed : KaitaiStruct - { - public static HistogramUint16Bucketed FromFile(string fileName) - { - return new HistogramUint16Bucketed(new KaitaiStream(fileName)); - } - - public HistogramUint16Bucketed(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._min = this.m_io.ReadU8le(); - this._bucketSize = this.m_io.ReadU4le(); - this._bucketCount = this.m_io.ReadU4le(); - this._distributionSize = this.m_io.ReadU2le(); - this._columns = new List((int)this.DistributionSize); - for (var i = 0; i < this.DistributionSize; i++) - { - this._columns.Add(new PairUint16(this.m_io, this, this.m_root)); - } - } - private ulong _min; - private uint _bucketSize; - private uint _bucketCount; - private ushort _distributionSize; - private List _columns; - private MetricsContract m_root; - private MetricsContract.Histogram m_parent; - public ulong Min { get { return this._min; } } - public uint BucketSize { get { return this._bucketSize; } } - public uint BucketCount { get { return this._bucketCount; } } - public ushort DistributionSize { get { return this._distributionSize; } } - public List Columns { get { return this._columns; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } - } - public partial class HistogramValueCountPairs : KaitaiStruct - { - public static HistogramValueCountPairs FromFile(string fileName) - { - return new HistogramValueCountPairs(new KaitaiStream(fileName)); - } - - public HistogramValueCountPairs(KaitaiStream p__io, MetricsContract.Histogram p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._distributionSize = this.m_io.ReadU2le(); - this._columns = new List((int)this.DistributionSize); - for (var i = 0; i < this.DistributionSize; i++) - { - this._columns.Add(new PairValueCount(this.m_io, this, this.m_root)); - } - } - private ushort _distributionSize; - private List _columns; - private MetricsContract m_root; - private MetricsContract.Histogram m_parent; - public ushort DistributionSize { get { return this._distributionSize; } } - public List Columns { get { return this._columns; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Histogram M_Parent { get { return this.m_parent; } } - } - public partial class Histogram : KaitaiStruct - { - public static Histogram FromFile(string fileName) - { - return new Histogram(new KaitaiStream(fileName)); - } - - public Histogram(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._version = this.m_io.ReadU1(); - this._type = (MetricsContract.DistributionType)this.m_io.ReadU1(); - switch (this.Type) - { - case MetricsContract.DistributionType.Bucketed: - { - this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); - break; - } - case MetricsContract.DistributionType.MonBucketed: - { - this._body = new HistogramUint16Bucketed(this.m_io, this, this.m_root); - break; - } - case MetricsContract.DistributionType.ValueCountPairs: - { - this._body = new HistogramValueCountPairs(this.m_io, this, this.m_root); - break; - } - } - } - private byte _version; - private DistributionType _type; - private KaitaiStruct _body; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public byte Version { get { return this._version; } } - public DistributionType Type { get { return this._type; } } - public KaitaiStruct Body { get { return this._body; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - - /// - /// Bucket #index, claiming to hold exactly `count` hits. See notes in - /// `histogram_uint16_bucketed` for interpreting index. - /// - public partial class PairUint16 : KaitaiStruct - { - public static PairUint16 FromFile(string fileName) - { - return new PairUint16(new KaitaiStream(fileName)); - } - - public PairUint16(KaitaiStream p__io, MetricsContract.HistogramUint16Bucketed p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._index = this.m_io.ReadU2le(); - this._count = this.m_io.ReadU2le(); - } - private ushort _index; - private ushort _count; - private MetricsContract m_root; - private MetricsContract.HistogramUint16Bucketed m_parent; - public ushort Index { get { return this._index; } } - public ushort Count { get { return this._count; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.HistogramUint16Bucketed M_Parent { get { return this.m_parent; } } - } - public partial class SingleUint64Value : KaitaiStruct - { - public static SingleUint64Value FromFile(string fileName) - { - return new SingleUint64Value(new KaitaiStream(fileName)); - } - - public SingleUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._padding = this.m_io.ReadBytes(4); - this._timestamp = this.m_io.ReadU8le(); - this._value = this.m_io.ReadU8le(); - } - private byte[] _padding; - private ulong _timestamp; - private ulong _value; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public byte[] Padding { get { return this._padding; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Metric value as 64-bit unsigned integer. - /// - public ulong Value { get { return this._value; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - public partial class ExtAggregatedDoubleValue : KaitaiStruct - { - public static ExtAggregatedDoubleValue FromFile(string fileName) - { - return new ExtAggregatedDoubleValue(new KaitaiStream(fileName)); - } - - public ExtAggregatedDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._count = this.m_io.ReadU4le(); - this._timestamp = this.m_io.ReadU8le(); - this._sum = this.m_io.ReadF8le(); - this._min = this.m_io.ReadF8le(); - this._max = this.m_io.ReadF8le(); - } - private uint _count; - private ulong _timestamp; - private double _sum; - private double _min; - private double _max; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - - /// - /// Count of events aggregated in this event. - /// - public uint Count { get { return this._count; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Sum of all metric values aggregated in this event. - /// - public double Sum { get { return this._sum; } } - - /// - /// Minimum of all metric values aggregated in this event. - /// - public double Min { get { return this._min; } } - - /// - /// Maximum of all metric values aggregated in this event. - /// - public double Max { get { return this._max; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - public partial class ExtAggregatedUint64Value : KaitaiStruct - { - public static ExtAggregatedUint64Value FromFile(string fileName) - { - return new ExtAggregatedUint64Value(new KaitaiStream(fileName)); - } - - public ExtAggregatedUint64Value(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._count = this.m_io.ReadU4le(); - this._timestamp = this.m_io.ReadU8le(); - this._sum = this.m_io.ReadU8le(); - this._min = this.m_io.ReadU8le(); - this._max = this.m_io.ReadU8le(); - } - private uint _count; - private ulong _timestamp; - private ulong _sum; - private ulong _min; - private ulong _max; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - - /// - /// Count of events aggregated in this event. - /// - public uint Count { get { return this._count; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Sum of all metric values aggregated in this event. - /// - public ulong Sum { get { return this._sum; } } - - /// - /// Minimum of all metric values aggregated in this event. - /// - public ulong Min { get { return this._min; } } - - /// - /// Maximum of all metric values aggregated in this event. - /// - public ulong Max { get { return this._max; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - public partial class SingleDoubleValue : KaitaiStruct - { - public static SingleDoubleValue FromFile(string fileName) - { - return new SingleDoubleValue(new KaitaiStream(fileName)); - } - - public SingleDoubleValue(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._padding = this.m_io.ReadBytes(4); - this._timestamp = this.m_io.ReadU8le(); - this._value = this.m_io.ReadF8le(); - } - private byte[] _padding; - private ulong _timestamp; - private double _value; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public byte[] Padding { get { return this._padding; } } - - /// - /// Timestamp in Windows FILETIME format, i.e. number of 100 ns ticks passed since 1601-01-01 00:00:00 UTC. - /// - public ulong Timestamp { get { return this._timestamp; } } - - /// - /// Metric value as double. - /// - public double Value { get { return this._value; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - - /// - /// A simple string, length-prefixed with a 2-byte integer. - /// - public partial class LenString : KaitaiStruct - { - public static LenString FromFile(string fileName) - { - return new LenString(new KaitaiStream(fileName)); - } - - public LenString(KaitaiStream p__io, MetricsContract.Userdata p__parent = null, MetricsContract p__root = null) - : base(p__io) - { - this.m_parent = p__parent; - this.m_root = p__root; - this._read(); - } - private void _read() - { - this._lenValue = this.m_io.ReadU2le(); - this._value = System.Text.Encoding.GetEncoding("UTF-8").GetString(this.m_io.ReadBytes(this.LenValue)); - } - private ushort _lenValue; - private string _value; - private MetricsContract m_root; - private MetricsContract.Userdata m_parent; - public ushort LenValue { get { return this._lenValue; } } - public string Value { get { return this._value; } } - public MetricsContract M_Root { get { return this.m_root; } } - public MetricsContract.Userdata M_Parent { get { return this.m_parent; } } - } - private ushort _eventId; - private ushort _lenBody; - private Userdata _body; - private MetricsContract m_root; - private KaitaiStruct m_parent; - private byte[] __raw_body; - - /// - /// Type of message, affects format of the body. - /// - public ushort EventId { get { return this._eventId; } } - - /// - /// Size of body in bytes. - /// - public ushort LenBody { get { return this._lenBody; } } - - /// - /// Body of Metrics binary protocol message. - /// - public Userdata Body { get { return this._body; } } - public MetricsContract M_Root { get { return this.m_root; } } - public KaitaiStruct M_Parent { get { return this.m_parent; } } - public byte[] M_RawBody { get { return this.__raw_body; } } -} From 51e0dbe54f71e952cdbb12f47a9df41bd9c9d645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 21 Mar 2023 14:36:25 +0100 Subject: [PATCH 0634/1499] [Instrumentation.AspNet] Document metrics --- src/OpenTelemetry.Instrumentation.AspNet/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 0ba136ba1d..cd0851606e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -82,6 +82,12 @@ public class WebApiApplication : HttpApplication } ``` +## Metrics + +This package produces following metrics: + +* [`http.server.duration`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration) + ## Advanced configuration This instrumentation can be configured to change the default behavior by using From 7d3ea18b00ec83212ee3a01a3128dfd979b9fa0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 22 Mar 2023 17:31:11 +0100 Subject: [PATCH 0635/1499] [Instrumentation.AspNet] Document metrics (#1098) --- .../README.md | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index cd0851606e..a16fa6a76d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -56,8 +56,14 @@ following shows changes required to your `Web.config` when using IIS web server. ### Step 3: Enable ASP.NET Instrumentation at application startup ASP.NET instrumentation must be enabled at application startup. This is -typically done in the `Global.asax.cs` as shown below. This example also sets up -the OpenTelemetry OTLP exporter, which requires adding the package +typically done in the `Global.asax.cs`. + +#### Traces + +The following example demonstrates adding ASP.NET instrumentation with the +extension method `.AddAspNetInstrumentation()` on `TracerProviderBuilder` to +an application. This example also sets up +the OTLP (OpenTelemetry Protocol) exporter, which requires adding the package [`OpenTelemetry.Exporter.OpenTelemetryProtocol`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) to the application. @@ -82,11 +88,45 @@ public class WebApiApplication : HttpApplication } ``` -## Metrics +#### Metrics + +The following example demonstrates adding ASP.NET instrumentation with the +extension method `.AddAspNetInstrumentation()` on `MeterProviderBuilder` to +an application. This example also sets up +the OTLP (OpenTelemetry Protocol) exporter, which requires adding the package +[`OpenTelemetry.Exporter.OpenTelemetryProtocol`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) +to the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Metrics; + +public class WebApiApplication : HttpApplication +{ + private MeterProvider meterProvider; + protected void Application_Start() + { + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetInstrumentation() + .AddOtlpExporter() + .Build(); + } + protected void Application_End() + { + this.meterProvider?.Dispose(); + } +} +``` + +#### List of metrics produced -This package produces following metrics: +The instrumentation is implemented based on [metrics semantic +conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration). +Currently, the instrumentation supports the following metric. -* [`http.server.duration`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration) +| Name | Instrument Type | Unit | Description | +|-------|-----------------|------|-------------| +| `http.server.duration` | Histogram | `ms` | Measures the duration of inbound HTTP requests. | ## Advanced configuration From d293201e4c088c6a50788010abbe4e9119aff42d Mon Sep 17 00:00:00 2001 From: Eric Hornby <31316161+ehornby@users.noreply.github.com> Date: Wed, 22 Mar 2023 13:01:25 -0500 Subject: [PATCH 0636/1499] Removing automatic service name from Lambda instrumentation (#1080) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Neumüller --- src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 2 ++ .../TracerProviderBuilderExtensions.cs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 42efbc8a16..3cbdb46d89 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -6,6 +6,8 @@ ([#626](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/626)) * Removes `AddAWSLambdaConfigurations` method with default configure parameter. ([#943](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/943)) +* BREAKING (behavior): `AddAWSLambdaConfigurations` no longer calls `AddService` + ([#1080](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1080)) ## 1.1.0-beta.2 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index e6eb7d7daa..5be84b18df 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -55,7 +55,6 @@ public static TracerProviderBuilder AddAWSLambdaConfigurations( builder.AddSource(AWSLambdaWrapper.ActivitySourceName); builder.SetResourceBuilder(ResourceBuilder .CreateEmpty() - .AddService(AWSLambdaUtils.GetFunctionName(), null, null, false) .AddTelemetrySdk() .AddAttributes(AWSLambdaResourceDetector.Detect())); From 5cdcf2dfc85a735128c4c0b282a2a5951c8449fd Mon Sep 17 00:00:00 2001 From: Soheil Alizadeh Date: Wed, 22 Mar 2023 23:20:00 +0100 Subject: [PATCH 0637/1499] [Instrumentation.Cassandra] Add Cassandra metrics support (#970) --- .../comp_instrumentation_cassandra.md | 41 +++++ .github/component_owners.yml | 5 + .../package-Instrumentation.Cassandra.yml | 65 ++++++++ build/Common.props | 1 + opentelemetry-dotnet-contrib.sln | 13 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 5 + .../CHANGELOG.md | 5 + .../CassandraBuilderExtensions.cs | 62 +++++++ .../CassandraDriverMetricsProvider.cs | 55 ++++++ .../CassandraMeter.cs | 24 +++ .../DriverCounter.cs | 40 +++++ .../DriverGauge.cs | 31 ++++ .../DriverMeter.cs | 35 ++++ .../DriverTimer.cs | 37 +++++ .../MeterProviderBuilderExtensions.cs | 40 +++++ ...Telemetry.Instrumentation.Cassandra.csproj | 20 +++ .../README.md | 80 +++++++++ .../SkipUnlessEnvVarFoundFactAttribute.cs | 39 +++++ .../BooksEntity.cs | 37 +++++ .../CassandraInstrumentationTests.cs | 156 ++++++++++++++++++ .../Dockerfile | 19 +++ ...try.Instrumentation.Cassandra.Tests.csproj | 32 ++++ .../docker-compose.yml | 28 ++++ 24 files changed, 872 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md create mode 100644 .github/workflows/package-Instrumentation.Cassandra.yml create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj create mode 100644 src/OpenTelemetry.Instrumentation.Cassandra/README.md create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs create mode 100644 test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs create mode 100644 test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile create mode 100644 test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md new file mode 100644 index 0000000000..aeedc67310 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Cassandra +about: Issue with OpenTelemetry.Instrumentation.Cassandra +labels: comp:instrumentation.cassandra +--- + +# Issue with OpenTelemetry.Instrumentation.Cassandra + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index b56276d2b2..8853669a57 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -38,6 +38,8 @@ components: src/OpenTelemetry.Instrumentation.AWSLambda/: - rypdal - Oberon00 + src/OpenTelemetry.Instrumentation.Cassandra/: + - xsoheilalizadeh src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith src/OpenTelemetry.Instrumentation.EventCounters/: @@ -110,6 +112,8 @@ components: test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: - rypdal - Oberon00 + test/OpenTelemetry.Instrumentation.Cassandra.Tests/: + - xsoheilalizadeh test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith test/OpenTelemetry.Instrumentation.EventCounters.Tests/: @@ -133,3 +137,4 @@ components: test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - rajkumar-rangaraj - vishweshbankwar + diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml new file mode 100644 index 0000000000..260ac22d4a --- /dev/null +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -0,0 +1,65 @@ +name: Pack OpenTelemetry.Instrumentation.Cassandra + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.Cassandra-*' + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + env: + PROJECT: OpenTelemetry.Instrumentation.Cassandra + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build/Common.props b/build/Common.props index 20078f7b13..49b7ac1f3f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -37,6 +37,7 @@ [1.4.0,2.0) [1.5.0-alpha.1] [2.1.58,3.0) + [3.16.0,4.0) [1.2.0-beta.435,2.0) [4.3.4,) 4.7.0 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 0cd96af5e0..bf2ff36f22 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -235,6 +235,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "process-instrumentation", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventCounters", "examples\event-counters\Examples.EventCounters\Examples.EventCounters.csproj", "{BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.Cassandra", "src\OpenTelemetry.Instrumentation.Cassandra\OpenTelemetry.Instrumentation.Cassandra.csproj", "{3313F7DF-E3A5-4A7F-965D-86807A017131}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.Cassandra.Tests", "test\OpenTelemetry.Instrumentation.Cassandra.Tests\OpenTelemetry.Instrumentation.Cassandra.Tests.csproj", "{FB48DC44-8C56-4329-9988-AEDF931E81E8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure", "src\OpenTelemetry.ResourceDetectors.Azure\OpenTelemetry.ResourceDetectors.Azure.csproj", "{B07DC3CB-F724-40A5-889A-DA6601F462F3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure.Tests", "test\OpenTelemetry.ResourceDetectors.Azure.Tests\OpenTelemetry.ResourceDetectors.Azure.Tests.csproj", "{DFC6A4A9-5262-4507-B747-CC6B814205E6}" @@ -505,6 +508,14 @@ Global {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Debug|Any CPU.Build.0 = Debug|Any CPU {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Release|Any CPU.ActiveCfg = Release|Any CPU {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}.Release|Any CPU.Build.0 = Release|Any CPU + {3313F7DF-E3A5-4A7F-965D-86807A017131}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3313F7DF-E3A5-4A7F-965D-86807A017131}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3313F7DF-E3A5-4A7F-965D-86807A017131}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3313F7DF-E3A5-4A7F-965D-86807A017131}.Release|Any CPU.Build.0 = Release|Any CPU + {FB48DC44-8C56-4329-9988-AEDF931E81E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB48DC44-8C56-4329-9988-AEDF931E81E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB48DC44-8C56-4329-9988-AEDF931E81E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB48DC44-8C56-4329-9988-AEDF931E81E8}.Release|Any CPU.Build.0 = Release|Any CPU {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {B07DC3CB-F724-40A5-889A-DA6601F462F3}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -619,6 +630,8 @@ Global {B40B975E-78B2-4712-8B4D-BADA67DF0C0A} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {C3B3BBAF-CC38-4D5C-AFA2-33184D07BF75} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {3313F7DF-E3A5-4A7F-965D-86807A017131} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {FB48DC44-8C56-4329-9988-AEDF931E81E8} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {B07DC3CB-F724-40A5-889A-DA6601F462F3} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {DFC6A4A9-5262-4507-B747-CC6B814205E6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {73C10993-03AC-42F4-85BB-96EAAA8212D9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..074c6ad103 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1,2 @@ +#nullable enable + diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..40bb721609 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Instrumentation.Cassandra.CassandraBuilderExtensions +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Instrumentation.Cassandra.CassandraBuilderExtensions.WithOpenTelemetryMetrics(this Cassandra.Builder! builder) -> Cassandra.Builder! +static OpenTelemetry.Instrumentation.Cassandra.CassandraBuilderExtensions.WithOpenTelemetryMetrics(this Cassandra.Builder! builder, Cassandra.Metrics.DriverMetricsOptions? options) -> Cassandra.Builder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddCassandraInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md new file mode 100644 index 0000000000..63bfc986bd --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +Initial release. diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs new file mode 100644 index 0000000000..c695b5dc43 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs @@ -0,0 +1,62 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Cassandra; +using Cassandra.Metrics; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +/// +/// Extension methods to simplify registering cassandra driver metrics. +/// +public static class CassandraBuilderExtensions +{ + /// + /// Configuring open telemetry metrics for cassandra. + /// + /// Cassandra builder. + /// Returning Cassandra builder. + public static Builder WithOpenTelemetryMetrics(this Builder builder) + { + Guard.ThrowIfNull(builder); + + return builder.WithMetrics(new CassandraDriverMetricsProvider(), GetDefaultOptions()); + } + + /// + /// Configuring open telemetry metrics for cassandra. + /// + /// Cassandra builder. + /// Cassandra driver metrics options. + /// Returning Cassandra builder. + public static Builder WithOpenTelemetryMetrics(this Builder builder, DriverMetricsOptions? options) + { + Guard.ThrowIfNull(builder); + + return builder.WithMetrics(new CassandraDriverMetricsProvider(), options ?? GetDefaultOptions()); + } + + private static DriverMetricsOptions GetDefaultOptions() + { + var options = new DriverMetricsOptions(); + + options.SetEnabledNodeMetrics(NodeMetric.AllNodeMetrics); + options.SetEnabledSessionMetrics(SessionMetric.AllSessionMetrics); + + return options; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs new file mode 100644 index 0000000000..61f18c904e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs @@ -0,0 +1,55 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Cassandra.Metrics; +using Cassandra.Metrics.Abstractions; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +internal sealed class CassandraDriverMetricsProvider : IDriverMetricsProvider +{ + private const string Prefix = "cassandra"; + + public IDriverTimer Timer(string bucket, IMetric metric) + { + return new DriverTimer($"{Prefix}.{metric.Name}"); + } + + public IDriverMeter Meter(string bucket, IMetric metric) + { + return new DriverMeter($"{Prefix}.{metric.Name}"); + } + + public IDriverCounter Counter(string bucket, IMetric metric) + { + return new DriverCounter($"{Prefix}.{metric.Name}"); + } + + public IDriverGauge Gauge(string bucket, IMetric metric, Func valueProvider) + { + return new DriverGauge($"{Prefix}.{metric.Name}", Value(valueProvider)); + } + + public void ShutdownMetricsBucket(string bucket) + { + } + + private static Func Value(Func valueProvider) + { + return () => valueProvider.Invoke() ?? 0; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs new file mode 100644 index 0000000000..7d48a76c99 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs @@ -0,0 +1,24 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +internal static class CassandraMeter +{ + public static Meter Instance => new Meter(typeof(CassandraMeter).Assembly.GetName().Name); +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs new file mode 100644 index 0000000000..b7d21a9e25 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; +using Cassandra.Metrics.Abstractions; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +internal sealed class DriverCounter : IDriverCounter +{ + private readonly Counter counter; + + public DriverCounter(string name) + { + this.counter = CassandraMeter.Instance.CreateCounter(name); + } + + public void Increment() + { + this.counter.Add(1); + } + + public void Increment(long value) + { + this.counter.Add(value); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs new file mode 100644 index 0000000000..91da2e0f99 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Metrics; +using Cassandra.Metrics.Abstractions; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +internal sealed class DriverGauge : IDriverGauge +{ + private readonly ObservableGauge gauge; + + public DriverGauge(string name, Func value) + { + this.gauge = CassandraMeter.Instance.CreateObservableGauge(name, value); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs new file mode 100644 index 0000000000..e565d75834 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; +using Cassandra.Metrics.Abstractions; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +internal sealed class DriverMeter : IDriverMeter +{ + private readonly Histogram meter; + + public DriverMeter(string name) + { + this.meter = CassandraMeter.Instance.CreateHistogram(name); + } + + public void Mark(long amount) + { + this.meter.Record(amount); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs new file mode 100644 index 0000000000..abc04027e5 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; +using Cassandra.Metrics.Abstractions; + +namespace OpenTelemetry.Instrumentation.Cassandra; + +internal sealed class DriverTimer : IDriverTimer +{ + private readonly Histogram timer; + + public DriverTimer(string name) + { + this.timer = CassandraMeter.Instance.CreateHistogram(name, "ms"); + } + + public void Record(long elapsedNanoseconds) + { + var elapsedMilliseconds = elapsedNanoseconds * 0.000001; + + this.timer.Record(elapsedMilliseconds); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..3597d89cfd --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Instrumentation.Cassandra; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class MeterProviderBuilderExtensions +{ + /// + /// Enables Cassandra instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddCassandraInstrumentation(this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + + builder.AddMeter(CassandraMeter.Instance.Name); + + return builder; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj new file mode 100644 index 0000000000..ae8b086b9e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.0 + OpenTelemetry Cassandra Instrumentation + $(PackageTags);Cassandra;CassandraCSharpDriver + Instrumentation.Cassandra- + enable + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md new file mode 100644 index 0000000000..c8612dad6a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -0,0 +1,80 @@ +# Cassandra Instrumentation for OpenTelemetry + +This is an +[Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments [CassandraCSharpDriver](https://github.com/datastax/csharp-driver) +and collects telemetry about cassandra metrics. + +## Steps to enable OpenTelemetry.Instrumentation.Cassandra + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.Cassandra`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.Cassandra +``` + +### Step 2: Enable Cassandra Instrumentation at application startup + +Cassandra instrumentation must be enabled at application startup. + +The following example demonstrates adding Cassandra instrumentation to a +console application. This example also sets up the OpenTelemetry Console +exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://www.nuget.org/packages/OpenTelemetry.Exporter.Console) +to the application. + +```csharp +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + using var metricProvider = Sdk.CreateMeterProviderBuilder() + .AddCassandraInstrumentation() + .AddConsoleExporter() + .Build(); + + var cluster = new Builder() + .WithConnectionString(yourCassandraConnectionString) + .WithOpenTelemetryMetrics() + .Build(); + } +} +``` + +For an ASP.NET Core application, adding instrumentation is typically done in +the `ConfigureServices` of your `Startup` class. Refer to documentation for +[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). + +For an ASP.NET application, adding instrumentation is typically done in the +`Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). + +## Configuration options + +You are able to configure your own cassandra driver metrics options in +`WithOpenTelemetryMetrics` the by default configuration includes all the metrics + that the driver can provide. + +```csharp +var options = new DriverMetricsOptions(); + +options.SetEnabledNodeMetrics(new[] {NodeMetric.Gauges.InFlight}); + +var cluster = new Builder() + .WithConnectionString(yourCassandraConnectionString) + .WithOpenTelemetryMetrics(options) + .Build(); +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) + +* [OpenTelemetry semantic conventions for database calls](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md) + +* [Cassandra C# Driver](https://github.com/datastax/csharp-driver) diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs new file mode 100644 index 0000000000..afb6cd8318 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -0,0 +1,39 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Xunit; + +namespace OpenTelemetry.Tests; +#nullable enable + +internal class SkipUnlessEnvVarFoundFactAttribute : FactAttribute +{ + public SkipUnlessEnvVarFoundFactAttribute(string environmentVariable) + { + var environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariable, EnvironmentVariableTarget.Process)!; + + if (string.IsNullOrEmpty(environmentVariableValue)) + { + environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariable, EnvironmentVariableTarget.Machine); + } + + if (string.IsNullOrEmpty(environmentVariableValue)) + { + this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs new file mode 100644 index 0000000000..201df1a6a7 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Cassandra.Mapping.Attributes; + +namespace OpenTelemetry.Instrumentation.Cassandra.Tests; + +[Table("books")] +public class BooksEntity +{ + public BooksEntity(Guid id, string name) + { + this.Id = id; + this.Name = name; + } + + [PartitionKey] + [Column("id")] + public Guid Id { get; set; } + + [Column("name")] + public string Name { get; set; } +} diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs new file mode 100644 index 0000000000..fc56ad0ef5 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs @@ -0,0 +1,156 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Cassandra; +using Cassandra.Mapping; +using Cassandra.Metrics; +using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; +using Xunit; +using CassandraData = Cassandra.Data.Linq; + +namespace OpenTelemetry.Instrumentation.Cassandra.Tests; + +[Collection("Cassandra")] +public class CassandraInstrumentationTests +{ + private const int MaxTimeToAllowForFlush = 20000; + + private const string CassandraConnectionStringEnvName = "OTEL_CASSANDRA_CONNECTION_STRING"; + private readonly string? cassandraConnectionString; + + public CassandraInstrumentationTests() + { + this.cassandraConnectionString = Environment.GetEnvironmentVariable(CassandraConnectionStringEnvName); + } + + [Trait("CategoryName", "CassandraIntegrationTests")] + [SkipUnlessEnvVarFoundFact(CassandraConnectionStringEnvName)] + public async Task CassandraMetricsAreCaptured() + { + var exportedItems = new List(); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddCassandraInstrumentation() + .Build(); + + var cluster = new Builder() + .WithConnectionString(this.cassandraConnectionString) + .WithOpenTelemetryMetrics() + .Build(); + + var session = cluster.ConnectAndCreateDefaultKeyspaceIfNotExists(); + + var table = new CassandraData.Table(session, new MappingConfiguration()); + + await table.CreateIfNotExistsAsync(); + + var mapper = new Mapper(session); + + await mapper.InsertAsync(new BooksEntity(Guid.NewGuid(), "Good book")); + await mapper.InsertAsync(new BooksEntity(Guid.NewGuid(), "Bad book")); + + var books = await mapper.FetchAsync(); + + provider.ForceFlush(MaxTimeToAllowForFlush); + + Assert.True(exportedItems.Count > 1); + Assert.NotEmpty(books); + } + + [Trait("CategoryName", "CassandraIntegrationTests")] + [SkipUnlessEnvVarFoundFact(CassandraConnectionStringEnvName)] + public async Task CassandraMetricsWithCustomOptionsCaptured() + { + var exportedItems = new List(); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddCassandraInstrumentation() + .Build(); + + var options = new DriverMetricsOptions(); + + options.SetEnabledNodeMetrics(new[] { NodeMetric.Gauges.InFlight }); + options.SetEnabledSessionMetrics(new List()); + + var cluster = new Builder() + .WithConnectionString(this.cassandraConnectionString) + .WithOpenTelemetryMetrics(options) + .Build(); + + var session = cluster.ConnectAndCreateDefaultKeyspaceIfNotExists(); + + var table = new CassandraData.Table(session, new MappingConfiguration()); + + await table.CreateIfNotExistsAsync(); + + var mapper = new Mapper(session); + + await mapper.InsertAsync(new BooksEntity(Guid.NewGuid(), "Good book")); + await mapper.InsertAsync(new BooksEntity(Guid.NewGuid(), "Bad book")); + + var books = await mapper.FetchAsync(); + + provider.ForceFlush(MaxTimeToAllowForFlush); + + var inFlightConnection = exportedItems.FirstOrDefault(i => i.Name == "cassandra.pool.in-flight"); + Assert.NotNull(inFlightConnection); + Assert.True(exportedItems.Count == 1); + Assert.NotEmpty(books); + } + + [Trait("CategoryName", "CassandraIntegrationTests")] + [SkipUnlessEnvVarFoundFact(CassandraConnectionStringEnvName)] + public async Task CassandraRequestsLatencyMetricsAreCaptured() + { + var exportedItems = new List(); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddCassandraInstrumentation() + .Build(); + + var cluster = new Builder() + .WithConnectionString(this.cassandraConnectionString) + .WithOpenTelemetryMetrics() + .Build(); + + var session = cluster.ConnectAndCreateDefaultKeyspaceIfNotExists(); + + var table = new CassandraData.Table(session, new MappingConfiguration()); + + await table.CreateIfNotExistsAsync(); + + var mapper = new Mapper(session); + + await mapper.InsertAsync(new BooksEntity(Guid.NewGuid(), "Good book")); + await mapper.InsertAsync(new BooksEntity(Guid.NewGuid(), "Bad book")); + + var books = await mapper.FetchAsync(); + + provider.ForceFlush(MaxTimeToAllowForFlush); + + var cqlMessageLatency = exportedItems.FirstOrDefault(i => i.Name == "cassandra.cql-requests"); + Assert.NotNull(cqlMessageLatency); + Assert.NotEmpty(books); + } +} diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile new file mode 100644 index 0000000000..3f06615552 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile @@ -0,0 +1,19 @@ +# Create a container for running the OpenTelemetry Cassandra integration tests. +# This should be run from the root of the repo: +# docker build --file test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile . + +ARG BUILD_SDK_VERSION=7.0 +ARG TEST_SDK_VERSION=7.0 + +FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build +ARG PUBLISH_CONFIGURATION=Release +ARG PUBLISH_FRAMEWORK=net7.0 +WORKDIR /repo +COPY . ./ +WORKDIR "/repo/test/OpenTelemetry.Instrumentation.Cassandra.Tests" +RUN dotnet publish "OpenTelemetry.Instrumentation.Cassandra.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} + +FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final +WORKDIR /test +COPY --from=build /drop . +ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Instrumentation.Cassandra.Tests.dll"] diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj new file mode 100644 index 0000000000..3cc4e5c4d0 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -0,0 +1,32 @@ + + + + net7.0;net6.0 + $(TargetFrameworks);net462 + enable + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml new file mode 100644 index 0000000000..5fa4a2f8b9 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml @@ -0,0 +1,28 @@ +# Start a redis container and then run OpenTelemetry redis integration tests. +# This should be run from the root of the repo: +# opentelemetry>docker-compose --file=test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build +version: '3.7' + +services: + cassandra: + image: cassandra + ports: + - "9042:9042" + healthcheck: + test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces" ] + interval: 15s + timeout: 10s + retries: 10 + + tests: + build: + context: . + dockerfile: ./test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile + command: --TestCaseFilter:CategoryName=CassandraIntegrationTests + environment: + - OTEL_CASSANDRA_CONNECTION_STRING=Contact Points=cassandra;Port=9042;Default Keyspace=OT_Cassandra_Testing + depends_on: + cassandra: + condition: service_healthy + + From 8532a4657f1ccc894c72e483c52074d50013c31c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 22 Mar 2023 17:33:11 -0700 Subject: [PATCH 0638/1499] [Exporter.Geneva] Fix serialization issue when there are no exemplars (#1099) --- .../Metrics/GenevaMetricExporter.cs | 16 +- .../GenevaMetricExporterTests.cs | 914 ++++++++++++++++-- 2 files changed, 826 insertions(+), 104 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 6f314f4249..4128c03bb3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -612,6 +612,7 @@ internal unsafe ushort SerializeMetricWithTLV( MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version + // TODO: Avoid this additional enumeration var exemplarsCount = 0; foreach (var exemplar in exemplars) { @@ -630,10 +631,10 @@ internal unsafe ushort SerializeMetricWithTLV( this.SerializeExemplar(exemplar, ref bufferIndex); } } - } - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + } #endregion @@ -817,6 +818,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version + // TODO: Avoid this additional enumeration var exemplarsCount = 0; foreach (var exemplar in exemplars) { @@ -835,10 +837,10 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( this.SerializeExemplar(exemplar, ref bufferIndex); } } - } - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + } #endregion @@ -913,7 +915,7 @@ private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) var flags = ExemplarFlags.IsTimestampAvailable; // we only serialize exemplars with Timestamp != default - // TODO: Update the code whenn Exemplars support long values + // TODO: Update the code when Exemplars support long values var value = exemplar.DoubleValue; // Check if the double value is actually a whole number that can be serialized as a long instead diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index be873f2a89..56bb3892eb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.Metrics; using System.Globalization; using System.IO; @@ -246,37 +247,37 @@ public void SuccessfulSerialization(bool testMaxLimits) Assert.Equal(11, exportedItems.Count); // check serialization for longCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); // check serialization for doubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); // check serialization for longUpDownCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); // check serialization for doubleUpDownCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); // check serialization for histogram - this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); // check serialization for observableLongCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); // check serialization for observableDoubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); // check serialization for observableLongGauge - this.CheckSerializationForSingleMetricPoint(exportedItems[7], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[7], exporter, exporterOptions); // check serialization for observableDoubleGauge - this.CheckSerializationForSingleMetricPoint(exportedItems[8], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[8], exporter, exporterOptions); // check serialization for observableUpDownLongCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[9], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[9], exporter, exporterOptions); // check serialization for observableUpDownDoubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[10], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[10], exporter, exporterOptions); } finally { @@ -468,22 +469,22 @@ public void SuccessfulSerializationWithViews() Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); // check serialization for longCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); // check serialization for doubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); // check serialization for histogramWithCustomBounds - this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); // check serialization for histogramWithNoBounds - this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); // check serialization for observableDoubleCounter - this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); // check serialization for observableLongGauge - this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); } finally { @@ -592,101 +593,540 @@ public void SuccessfulExportOnLinux() // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); - // TODO: Update the unit test to test TLV based serialization - - /* var stream = new KaitaiStream(receivedData); var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + var fields = userData.Fields; + + Assert.Contains(fields, field => field.Type == PayloadTypes.MetricName && (field.Value as WrappedString).Value == metric.Name); + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == "OTelMonitoringAccount"); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == "OTelMetricNamespace"); + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleUint64Value).Value as SingleUint64ValueV2; + Assert.Equal(metricDataValue, valueSection.Value); + + var dimensions = fields.FirstOrDefault(field => field.Type == PayloadTypes.Dimensions).Value as Dimensions; + Assert.Equal(2, dimensions.NumDimensions); + + int i = 0; + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, dimensions.DimensionsNames[i].Value); + Assert.Equal(tag.Value, dimensions.DimensionsValues[i].Value); + i++; + } + + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + finally + { + try + { + File.Delete(path); + } + catch + { + } + } + } + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void DisableMetricNameValidationTest(bool disableMetricNameValidation) + { + var instrumentNameRegexProperty = GenevaMetricExporter.GetOpenTelemetryInstrumentNameRegexProperty(); + var initialInstrumentNameRegexValue = instrumentNameRegexProperty.GetValue(null); + Socket server = null; + try + { + var exportedMetrics = new List(); + + using var meter = new Meter(Guid.NewGuid().ToString()); + + using (var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddGenevaMetricExporter(options => + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + } + else + { + var path = GenerateTempFilePath(); + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + }) + .AddInMemoryExporter(exportedMetrics) + .Build()) + { + var counter = meter.CreateCounter("count/invalid"); + counter.Add(1); + } + + if (disableMetricNameValidation) + { + Assert.Single(exportedMetrics); + } + else + { + Assert.Empty(exportedMetrics); + } + } + finally + { + instrumentNameRegexProperty.SetValue(null, initialInstrumentNameRegexValue); +#pragma warning disable CA1508 + server?.Dispose(); +#pragma warning restore CA1508 + } + } + + [Theory] + [InlineData(false, false, false, false)] + [InlineData(false, false, false, true)] + [InlineData(false, false, true, false)] + [InlineData(false, false, true, true)] + [InlineData(false, true, false, false)] + [InlineData(false, true, false, true)] + [InlineData(false, true, true, false)] + [InlineData(false, true, true, true)] + [InlineData(true, false, false, false)] + [InlineData(true, false, false, true)] + [InlineData(true, false, true, false)] + [InlineData(true, false, true, true)] + [InlineData(true, true, false, false)] + [InlineData(true, true, false, true)] + [InlineData(true, true, true, false)] + [InlineData(true, true, true, true)] + public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars, bool isWithinAnActivityContext, bool hasFilteredTagsForExemplars) + { + using var meter = new Meter("SuccessfulSerialization", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var longUpDownCounter = meter.CreateUpDownCounter("longUpDownCounter"); + var doubleUpDownCounter = meter.CreateUpDownCounter("doubleUpDownCounter"); + var histogram = meter.CreateHistogram("histogram"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerialization") + .AddReader(inMemoryReader); + + if (hasExemplars) + { + meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); + } + + if (hasFilteredTagsForExemplars) + { + meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = new string[] { "tag1", "tag2" } }); + } + + using var meterProvider = meterProviderBuilder.Build(); + + long longValue = 123; + double doubleValue = 123.45; + + if (testMaxLimits) + { + longValue = long.MaxValue; + doubleValue = double.MaxValue; + } + + Activity activity = null; + + if (isWithinAnActivityContext) + { + activity = new Activity("Custom Activity"); + activity.Start(); + } + + longCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + + doubleCounter.Add( + doubleValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + + longUpDownCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + + doubleUpDownCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + + meter.CreateObservableCounter( + "observableLongCounter", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")), + }); + + meter.CreateObservableCounter( + "observableDoubleCounter", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")), + }); + + meter.CreateObservableGauge( + "observableLongGauge", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")), + }); + + meter.CreateObservableGauge( + "observableDoubleGauge", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")), + }); + + meter.CreateObservableUpDownCounter( + "observableUpDownLongCounter", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")), + }); + + meter.CreateObservableUpDownCounter( + "observableUpDownDoubleCounter", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")), + }); + + if (testMaxLimits) + { + // only testing the max value allowed for sum + // max value allowed for count is uint.MaxValue. It's not feasible to test that + histogram.Record(longValue, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + } + else + { + // Record the following values from Histogram: + // (-inf - 0] : 1 + // (0 - 5] : 0 + // (5 - 10] : 0 + // (10 - 25] : 0 + // (25 - 50] : 0 + // (50 - 75] : 0 + // (75 - 100] : 0 + // (100 - 250] : 2 + // (250 - 500] : 0 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for the given distribution: + // 0: 1 + // 250: 2 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogram.Record(0, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + histogram.Record(750, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); + } + + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + exporterOptions.PrepopulatedMetricDimensions = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + + using var exporter = new GenevaMetricExporter(exporterOptions); + + inMemoryReader.Collect(); + + Assert.Equal(11, exportedItems.Count); + + // check serialization for longCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + + // check serialization for doubleCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + + // check serialization for longUpDownCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + + // check serialization for doubleUpDownCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); + + // check serialization for histogram + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); + + // check serialization for observableLongCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); + + // check serialization for observableDoubleCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + + // check serialization for observableLongGauge + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[7], exporter, exporterOptions); + + // check serialization for observableDoubleGauge + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[8], exporter, exporterOptions); + + // check serialization for observableUpDownLongCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[9], exporter, exporterOptions); + + // check serialization for observableUpDownDoubleCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[10], exporter, exporterOptions); + + activity?.Stop(); + } + finally + { + activity?.Dispose(); + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + + [Fact] + public void SuccessfulSerializationWithTLVWithViews() + { + using var meter = new Meter("SuccessfulSerializationWithViews", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var histogramWithCustomBounds = meter.CreateHistogram("histogramWithCustomBounds"); + var histogramWithNoBounds = meter.CreateHistogram("histogramWithNoBounds"); + var histogramWithNoMinMax = meter.CreateHistogram("histogramWithNoMinMax"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerializationWithViews") + .AddView("longCounter", "renamedLongCounter") + .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { "tag1" } }) + .AddView( + "histogramWithCustomBounds", + new ExplicitBucketHistogramConfiguration + { + Name = "renamedhistogramWithCustomBounds", + Description = "modifiedDescription", + Boundaries = new double[] { 500, 1000, 10000 }, + }) + .AddView(instrument => + { + if (instrument.Name == "histogramWithNoBounds") + { + return new ExplicitBucketHistogramConfiguration { Boundaries = Array.Empty() }; + } + + return null; + }) + .AddView( + "histogramWithNoMinMax", + new HistogramConfiguration + { + RecordMinMax = false, + }) + .AddView("observableLongCounter", MetricStreamConfiguration.Drop) + .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = Array.Empty() }) + .AddView(instrument => + { + if (instrument.Name == "observableLongGauge") + { + return new MetricStreamConfiguration + { + Name = "renamedobservableLongGauge", + Description = "modifiedDescription", + TagKeys = new string[] { "tag1" }, + }; + } + + return null; + }) + .AddView(instrument => + { + if (instrument.Name == "observableDoubleGauge") + { + return MetricStreamConfiguration.Drop; + } + + return null; + }) + .AddReader(inMemoryReader) + .Build(); + + longCounter.Add( + 123, new("tag1", "value1"), new("tag2", "value2")); + + doubleCounter.Add( + 123.45, new("tag1", "value1"), new("tag2", "value2")); + + meter.CreateObservableCounter( + "observableLongCounter", + () => new List>() + { + new(123, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableCounter( + "observableDoubleCounter", + () => new List>() + { + new(123.45, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableGauge( + "observableLongGauge", + () => new List>() + { + new(123, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableGauge( + "observableDoubleGauge", + () => new List>() + { + new(123.45, new("tag1", "value1"), new("tag2", "value2")), + }); + + // Record the following values for histogramWithCustomBounds: + // (-inf - 500] : 3 + // (500 - 1000] : 1 + // (1000 - 10000] : 0 + // (10000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for histogramWithCustomBounds: + // 500: 3 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogramWithCustomBounds.Record(0, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithCustomBounds.Record(50000, new("tag1", "value1"), new("tag2", "value2")); + + // Record the following values for histogramWithNoBounds: + // (-inf - 500] : 3 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // Only `sum` and `count` are sent for histogramWithNoBounds + // No value-count pairs are sent for histogramWithNoBounds + + histogramWithNoBounds.Record(0, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + + histogramWithNoMinMax.Record(-1, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(150, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(750, new("tag1", "value1"), new("tag2", "value2")); + histogramWithNoMinMax.Record(2500, new("tag1", "value1"), new("tag2", "value2")); + + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + exporterOptions.PrepopulatedMetricDimensions = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; - Assert.Equal(metric.Name, data.Body.MetricName.Value); - Assert.Equal("OTelMonitoringAccount", data.Body.MetricAccount.Value); - Assert.Equal("OTelMetricNamespace", data.Body.MetricNamespace.Value); + using var exporter = new GenevaMetricExporter(exporterOptions); - var valueSection = data.Body.ValueSection as SingleUint64Value; - Assert.Equal(metricDataValue, valueSection.Value); + inMemoryReader.Collect(); - Assert.Equal(2, data.Body.NumDimensions); + Assert.Equal(7, exportedItems.Count); - int i = 0; - foreach (var tag in metricPoint.Tags) - { - Assert.Equal(tag.Key, data.Body.DimensionsNames[i].Value); - Assert.Equal(tag.Value, data.Body.DimensionsValues[i].Value); - i++; - } + // observableLongCounter and observableDoubleGauge are dropped + Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); - Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - */ - } - finally - { - try - { - File.Delete(path); - } - catch - { - } - } - } - } + // check serialization for longCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); - [Theory] - [InlineData(true)] - [InlineData(false)] - public void DisableMetricNameValidationTest(bool disableMetricNameValidation) - { - var instrumentNameRegexProperty = GenevaMetricExporter.GetOpenTelemetryInstrumentNameRegexProperty(); - var initialInstrumentNameRegexValue = instrumentNameRegexProperty.GetValue(null); - Socket server = null; - try - { - var exportedMetrics = new List(); + // check serialization for doubleCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - using var meter = new Meter(Guid.NewGuid().ToString()); + // check serialization for histogramWithCustomBounds + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - using (var provider = Sdk.CreateMeterProviderBuilder() - .AddMeter(meter.Name) - .AddGenevaMetricExporter(options => - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; - } - else - { - var path = GenerateTempFilePath(); - options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + // check serialization for histogramWithNoBounds + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } - }) - .AddInMemoryExporter(exportedMetrics) - .Build()) - { - var counter = meter.CreateCounter("count/invalid"); - counter.Add(1); - } + // check serialization for observableDoubleCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - if (disableMetricNameValidation) - { - Assert.Single(exportedMetrics); - } - else - { - Assert.Empty(exportedMetrics); - } + // check serialization for observableLongGauge + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); } finally { - instrumentNameRegexProperty.SetValue(null, initialInstrumentNameRegexValue); -#pragma warning disable CA1508 server?.Dispose(); -#pragma warning restore CA1508 + try + { + File.Delete(path); + } + catch + { + } } } @@ -716,7 +1156,7 @@ private static void AssertHistogramBucketSerialization(HistogramBucket bucket, H Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); } - private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) + private static void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) { var metricType = metric.MetricType; var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); @@ -909,4 +1349,284 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE Assert.Equal(dimensionsCount, userData.NumDimensions); } + + private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) + { + var metricType = metric.MetricType; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var exemplars = metricPoint.GetExemplars(); + + List fields = null; + + // Check metric value, timestamp, eventId, and length of payload + if (metricType == MetricType.LongSum) + { + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + var bodyLength = exporter.SerializeMetricWithTLV( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + fields = userData.Fields; + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleUint64Value).Value as SingleUint64ValueV2; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.LongGauge) + { + var metricDataValue = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + fields = userData.Fields; + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleDoubleValue).Value as SingleDoubleValueV2; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + { + var metricDataValue = metricType == MetricType.DoubleSum ? + metricPoint.GetSumDouble() : + metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + fields = userData.Fields; + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleDoubleValue).Value as SingleDoubleValueV2; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) + { + var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? + Convert.ToDouble(metricPoint.GetSumLong()) : + Convert.ToDouble(metricPoint.GetSumDouble()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + fields = userData.Fields; + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleDoubleValue).Value as SingleDoubleValueV2; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + else if (metricType == MetricType.Histogram) + { + var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + min = 0; + max = 0; + } + + var bodyLength = exporter.SerializeHistogramMetricWithTLV( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count, + min, + max, + exemplars); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + fields = userData.Fields; + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.ExtAggregatedUint64Value).Value as ExtAggregatedUint64ValueV2; + var valueCountPairs = fields.FirstOrDefault(field => field.Type == PayloadTypes.HistogramUint64ValueCountPairs).Value as HistogramValueCountPairs; + + int listIterator = 0; + int bucketsWithPositiveCount = 0; + double lastExplicitBound = default; + foreach (var bucket in metricPoint.GetHistogramBuckets()) + { + if (bucket.BucketCount > 0) + { + AssertHistogramBucketSerialization(bucket, valueCountPairs, listIterator, lastExplicitBound); + listIterator++; + bucketsWithPositiveCount++; + } + + lastExplicitBound = bucket.ExplicitBound; + } + + Assert.Equal(bucketsWithPositiveCount, valueCountPairs.DistributionSize); + + Assert.Equal(count, valueSection.Count); + Assert.Equal(Convert.ToUInt64(metricPoint.GetHistogramSum()), valueSection.Sum); + Assert.Equal(min, valueSection.Min); + Assert.Equal(max, valueSection.Max); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + + if (exemplars.Length > 0) + { + var validExemplars = exemplars.Where(exemplar => exemplar.Timestamp != default).ToList(); + + var exemplarsPayload = fields.FirstOrDefault(field => field.Type == PayloadTypes.Exemplars).Value as Exemplars; + var singleExemplarList = exemplarsPayload.ExemplarList; + + Assert.Equal(0, exemplarsPayload.Version); + Assert.True(singleExemplarList.All(singleExemplar => singleExemplar.Version == 0)); + + Assert.Equal(validExemplars.Count, exemplarsPayload.NumberOfExemplars.Value); + Assert.Equal(validExemplars.Count, singleExemplarList.Count); + + for (int i = 0; i < validExemplars.Count; i++) + { + var expectedExemplar = validExemplars[i]; + var serializedExemplar = singleExemplarList[i]; + + AssertExemplarFilteredTagSerialization(expectedExemplar, serializedExemplar); + } + } + + // Check metric name, account, and namespace + var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); + Assert.Contains(fields, field => field.Type == PayloadTypes.MetricName && (field.Value as WrappedString).Value == metric.Name); + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == connectionStringBuilder.Account); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == connectionStringBuilder.Namespace); + + // Check dimensions + var dimensions = fields.FirstOrDefault(field => field.Type == PayloadTypes.Dimensions).Value as Dimensions; + var dimensionsCount = 0; + if (exporterOptions.PrepopulatedMetricDimensions != null) + { + foreach (var entry in exporterOptions.PrepopulatedMetricDimensions) + { + Assert.Contains(dimensions.DimensionsNames, dim => dim.Value == entry.Key); + Assert.Contains(dimensions.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); + } + + dimensionsCount += exporterOptions.PrepopulatedMetricDimensions.Count; + } + + // Check metric dimensions + int index = 0; + foreach (var item in exporterOptions.PrepopulatedMetricDimensions) + { + Assert.Equal(item.Key, dimensions.DimensionsNames[index].Value); + Assert.Equal(item.Value, dimensions.DimensionsValues[index].Value); + index++; + } + + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, dimensions.DimensionsNames[index].Value); + Assert.Equal(tag.Value, dimensions.DimensionsValues[index].Value); + index++; + } + + dimensionsCount += metricPoint.Tags.Count; + + Assert.Equal(dimensionsCount, dimensions.NumDimensions); + } + + private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExemplar, SingleExemplar serializedExemplar) + { + var serializedExemplarBody = serializedExemplar.Body; + + var expectedUnixNanoSeconds = DateTime.FromFileTimeUtc(expectedExemplar.Timestamp.ToFileTime()) + .ToUniversalTime() + .Subtract(new DateTime(1970, 1, 1)) + .TotalMilliseconds * 1000000; + + // TODO: Test for exemplar values stored as long + if (!serializedExemplarBody.Value.IsDoubleStoredAsLong) + { + Assert.Equal(expectedExemplar.DoubleValue, serializedExemplarBody.Value.ValueAsDouble); + } + + Assert.Equal((ulong)expectedUnixNanoSeconds, serializedExemplarBody.TimeUnixNano); + + if (expectedExemplar.TraceId.HasValue) + { + var traceIdBytes = new byte[16]; + expectedExemplar.TraceId.Value.CopyTo(traceIdBytes); + + Assert.Equal(16, serializedExemplarBody.TraceId.Length); + Assert.True(traceIdBytes.SequenceEqual(serializedExemplarBody.TraceId)); + } + + if (expectedExemplar.SpanId.HasValue) + { + var spanIdBytes = new byte[8]; + expectedExemplar.SpanId.Value.CopyTo(spanIdBytes); + + Assert.Equal(8, serializedExemplarBody.SpanId.Length); + Assert.True(spanIdBytes.SequenceEqual(serializedExemplarBody.SpanId)); + } + + if (expectedExemplar.FilteredTags != null && expectedExemplar.FilteredTags.Count > 0) + { + Assert.Equal(expectedExemplar.FilteredTags.Count, serializedExemplarBody.NumberOfLabels); + + for (int i = 0; i < expectedExemplar.FilteredTags.Count; i++) + { + var expectedFilteredTag = expectedExemplar.FilteredTags[i]; + var serializedFilteredTag = serializedExemplarBody.Labels[i]; + + Assert.Equal(expectedFilteredTag.Key, serializedFilteredTag.Name.Value); + Assert.Equal(expectedFilteredTag.Value, serializedFilteredTag.Value.Value); + } + } + } } From 29e33b12681a9937143f8a1fff24364687fb9a3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 17:29:46 -0700 Subject: [PATCH 0639/1499] Bump actions/stale from 7 to 8 (#1103) --- .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 4fb58ec613..e299eaf3a8 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v7 + - uses: actions/stale@v8 with: stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' From 365e131c87a3b649a579b6d299d59d81a8b6b8b4 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 23 Mar 2023 22:54:22 -0700 Subject: [PATCH 0640/1499] [Extensions.Docker] Remove netcoreapp3.1 from test (#1056) --- .../OpenTelemetry.Extensions.Docker.Tests.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj index 9d76d1a0c2..13262237e2 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -3,9 +3,8 @@ Unit test project for Docker Detector for OpenTelemetry - net7.0;net6.0;netcoreapp3.1 + net7.0;net6.0 $(TargetFrameworks);net462 - true From b908088a1c8e2fde825ad40ba29eb9abcefc4358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 24 Mar 2023 07:04:59 +0100 Subject: [PATCH 0641/1499] [Extensions.Docker] Nullable (#1101) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 ++-- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 4 ++-- .../OpenTelemetry.Extensions.Docker.csproj | 1 + .../Resources/DockerResourceDetector.cs | 18 +++++++++--------- ...penTelemetry.Extensions.Docker.Tests.csproj | 1 + 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt index dd82aed623..e97a3917d4 100644 --- a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,3 +1,3 @@ OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void \ No newline at end of file +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index dd82aed623..e97a3917d4 100644 --- a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,3 @@ OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void \ No newline at end of file +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj index 5fea9c27cb..3f82d2a3cc 100644 --- a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj +++ b/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj @@ -4,6 +4,7 @@ netstandard2.0;net462 OpenTelemetry Extensions - Container Resource Detector from Docker environment. Extensions.Docker- + enable diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs index e1eee6ac64..4c96171049 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs +++ b/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs @@ -79,7 +79,7 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) } else { - return new Resource(new List>() { new KeyValuePair(DockerSemanticConventions.AttributeContainerID, containerId), }); + return new Resource(new List>(1) { new(DockerSemanticConventions.AttributeContainerID, containerId!) }); } } @@ -88,7 +88,7 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) /// /// line read from cgroup file. /// Container Id, Null if not found. - private static string GetIdFromLineV1(string line) + private static string? GetIdFromLineV1(string line) { // This cgroup output line should have the container id in it int lastSlashIndex = line.LastIndexOf('/'); @@ -101,7 +101,7 @@ private static string GetIdFromLineV1(string line) int startIndex = lastSection.LastIndexOf('-'); int endIndex = lastSection.LastIndexOf('.'); - string containerId = RemovePrefixAndSuffixIfneeded(lastSection, startIndex, endIndex); + string containerId = RemovePrefixAndSuffixIfNeeded(lastSection, startIndex, endIndex); if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) { @@ -116,16 +116,16 @@ private static string GetIdFromLineV1(string line) /// /// line read from cgroup file. /// Container Id, Null if not found. - private static string GetIdFromLineV2(string line) + private static string? GetIdFromLineV2(string line) { - string containerId = null; + string? containerId = null; var match = Regex.Match(line, @".*/.+/([\w+-.]{64})/.*$"); if (match.Success) { containerId = match.Groups[1].Value; } - if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) + if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId!)) { return null; } @@ -133,7 +133,7 @@ private static string GetIdFromLineV2(string line) return containerId; } - private static string RemovePrefixAndSuffixIfneeded(string input, int startIndex, int endIndex) + private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex, int endIndex) { startIndex = (startIndex == -1) ? 0 : startIndex + 1; @@ -151,7 +151,7 @@ private static string RemovePrefixAndSuffixIfneeded(string input, int startIndex /// cgroup path. /// CGroup Version of file to parse from. /// Container Id, Null if not found or exception being thrown. - private string ExtractContainerId(string path, ParseMode cgroupVersion) + private string? ExtractContainerId(string path, ParseMode cgroupVersion) { try { @@ -162,7 +162,7 @@ private string ExtractContainerId(string path, ParseMode cgroupVersion) foreach (string line in File.ReadLines(path)) { - string containerId = null; + string? containerId = null; if (!string.IsNullOrEmpty(line)) { if (cgroupVersion == ParseMode.V1) diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj index 13262237e2..8457c84d05 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj @@ -5,6 +5,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 + enable From 1e47f1cb819ac13ec344c93ceaa088dc0e4eaed1 Mon Sep 17 00:00:00 2001 From: Will Rogers Date: Fri, 24 Mar 2023 02:23:34 -0400 Subject: [PATCH 0642/1499] [Extensions.AWSXray] Replace Newtonsoft.Json with System.Text.Json (#1092) --- .../CHANGELOG.md | 2 + ...elemetry.Contrib.Extensions.AWSXRay.csproj | 5 +- .../Resources/AWSECSResourceDetector.cs | 58 ++++++++++--------- .../Resources/Models/AWSEBSMetadataModel.cs | 8 +-- .../Models/AWSEKSClusterDataModel.cs | 4 +- .../Resources/ResourceDetectorUtils.cs | 18 ++++-- 6 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index 0b3cb1d475..168af55a2f 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -7,6 +7,8 @@ ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) * Raised minimum .NET version to `net462` ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) +* Replaced Newtonsoft.Json dependency with System.Text.Json + ([#1092](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1092)) * Updated OTel SDK package version to 1.3.1 ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) * Enhancement - AWSECSResourceDetector - Implement `aws.{ecs.*,log.*}` resource diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 7dbba22c44..d804733696 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -8,7 +8,6 @@ - @@ -21,6 +20,10 @@ + + + + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs index 0379246622..86d0474c9c 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs @@ -17,10 +17,9 @@ using System; using System.Collections.Generic; using System.Net.Http; +using System.Text.Json; using System.Text.RegularExpressions; -using Newtonsoft.Json.Linq; - using OpenTelemetry.Resources; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -88,18 +87,18 @@ internal static List> ExtractMetadataV4ResourceAttr var metadataV4ContainerResponse = ResourceDetectorUtils.SendOutRequest(metadataV4Url, "GET", null, httpClientHandler).Result; var metadataV4TaskResponse = ResourceDetectorUtils.SendOutRequest($"{metadataV4Url.TrimEnd('/')}/task", "GET", null, httpClientHandler).Result; - var containerResponse = JObject.Parse(metadataV4ContainerResponse); - var taskResponse = JObject.Parse(metadataV4TaskResponse); + using var containerResponse = JsonDocument.Parse(metadataV4ContainerResponse); + using var taskResponse = JsonDocument.Parse(metadataV4TaskResponse); - var containerArn = containerResponse.Value("ContainerARN"); - if (containerArn == null) + if (!containerResponse.RootElement.TryGetProperty("ContainerARN", out var containerArnElement) + || containerArnElement.GetString() is not string containerArn) { AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); return new List>(); } - var clusterArn = taskResponse.Value("Cluster"); - if (clusterArn == null) + if (!taskResponse.RootElement.TryGetProperty("Cluster", out var clusterArnElement) + || clusterArnElement.GetString() is not string clusterArn) { AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); return new List>(); @@ -117,10 +116,15 @@ internal static List> ExtractMetadataV4ResourceAttr new KeyValuePair(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn), }; - var launchType = taskResponse.Value("LaunchType") switch + if (!taskResponse.RootElement.TryGetProperty("LaunchType", out var launchTypeElement)) + { + launchTypeElement = default; + } + + var launchType = launchTypeElement switch { - string type when string.Equals("ec2", type, StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeEc2, - string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeFargate, + { ValueKind: JsonValueKind.String } when string.Equals("ec2", launchTypeElement.GetString(), StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeEc2, + { ValueKind: JsonValueKind.String } when string.Equals("fargate", launchTypeElement.GetString(), StringComparison.OrdinalIgnoreCase) => AWSSemanticConventions.ValueEcsLaunchTypeFargate, _ => null, }; @@ -130,31 +134,29 @@ string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCa } else { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{taskResponse["LaunchType"]}'")); + AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{launchTypeElement}'")); } - var taskArn = taskResponse.Value("TaskARN"); - if (taskArn != null) + if (taskResponse.RootElement.TryGetProperty("TaskARN", out var taskArnElement) && taskArnElement.ValueKind == JsonValueKind.String) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskArn, taskArn)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskArn, taskArnElement.GetString()!)); } - var family = taskResponse.Value("Family"); - if (family != null) + if (taskResponse.RootElement.TryGetProperty("Family", out var familyElement) && familyElement.ValueKind == JsonValueKind.String) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskFamily, family)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskFamily, familyElement.GetString()!)); } - var revision = taskResponse.Value("Revision"); - if (revision != null) + if (taskResponse.RootElement.TryGetProperty("Revision", out var revisionElement) && revisionElement.ValueKind == JsonValueKind.String) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskRevision, revision)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskRevision, revisionElement.GetString()!)); } - if (string.Equals("awslogs", containerResponse.Value("LogDriver"), StringComparison.Ordinal)) + if (containerResponse.RootElement.TryGetProperty("LogDriver", out var logDriverElement) + && logDriverElement.ValueKind == JsonValueKind.String + && logDriverElement.ValueEquals("awslogs")) { - JObject? logOptions = containerResponse.Value("LogOptions"); - if (logOptions != null) + if (containerResponse.RootElement.TryGetProperty("LogOptions", out var logOptionsElement)) { var regex = new Regex(@"arn:aws:ecs:([^:]+):([^:]+):.*"); var match = regex.Match(containerArn); @@ -167,15 +169,15 @@ string type when string.Equals("fargate", type, StringComparison.OrdinalIgnoreCa var logsRegion = match.Groups[1]; var logsAccount = match.Groups[2]; - var logGroupName = logOptions.Value("awslogs-group"); - if (logGroupName != null) + if (logOptionsElement.TryGetProperty("awslogs-group", out var logGroupElement) && logGroupElement.ValueKind == JsonValueKind.String) { + var logGroupName = logGroupElement.GetString()!; resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupNames, new string[] { logGroupName })); resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:*" })); - var logStreamName = logOptions.Value("awslogs-stream"); - if (logStreamName != null) + if (logOptionsElement.TryGetProperty("awslogs-stream", out var logStreamElement) && logStreamElement.ValueKind == JsonValueKind.String) { + var logStreamName = logStreamElement.GetString()!; resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamNames, new string[] { logStreamName })); resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:log-stream:{logStreamName}" })); } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs index 656fd150c5..ffb51d0ec1 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs @@ -14,18 +14,18 @@ // limitations under the License. // -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; internal class AWSEBSMetadataModel { - [JsonProperty(PropertyName = "deployment_id")] + [JsonPropertyName("deployment_id")] public string? DeploymentId { get; set; } - [JsonProperty(PropertyName = "environment_name")] + [JsonPropertyName("environment_name")] public string? EnvironmentName { get; set; } - [JsonProperty(PropertyName = "version_label")] + [JsonPropertyName("version_label")] public string? VersionLabel { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs index 3dadd91cf6..7d36f83063 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs @@ -14,12 +14,12 @@ // limitations under the License. // -using Newtonsoft.Json; +using System.Text.Json.Serialization; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; internal class AWSEKSClusterDataModel { - [JsonProperty(PropertyName = "cluster.name")] + [JsonPropertyName("cluster.name")] public string? ClusterName { get; set; } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs index 5410c6df44..2006ab040d 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs @@ -19,8 +19,8 @@ using System.IO; using System.Net.Http; using System.Text; +using System.Text.Json; using System.Threading.Tasks; -using Newtonsoft.Json; namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; @@ -31,6 +31,8 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; public class ResourceDetectorUtils #pragma warning restore CA1052 { + private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); + internal static async Task SendOutRequest(string url, string method, KeyValuePair? header, HttpClientHandler? handler = null) { using (var httpRequestMessage = new HttpRequestMessage()) @@ -55,21 +57,25 @@ internal static async Task SendOutRequest(string url, string method, Key internal static T? DeserializeFromFile(string filePath) { - using (var streamReader = GetStreamReader(filePath)) + using (var stream = GetStream(filePath)) { - JsonSerializer serializer = new JsonSerializer(); - return (T?)serializer.Deserialize(streamReader, typeof(T)); + return (T?)JsonSerializer.Deserialize(stream, typeof(T), JsonSerializerOptions); } } internal static T? DeserializeFromString(string json) { - return JsonConvert.DeserializeObject(json); + return JsonSerializer.Deserialize(json, JsonSerializerOptions); + } + + internal static Stream GetStream(string filePath) + { + return new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } internal static StreamReader GetStreamReader(string filePath) { - var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var fileStream = GetStream(filePath); var streamReader = new StreamReader(fileStream, Encoding.UTF8); return streamReader; } From 0bbdb25f98764c1665acc3e4f924038ed87e11b7 Mon Sep 17 00:00:00 2001 From: Jan Trejbal Date: Fri, 24 Mar 2023 17:04:21 +0100 Subject: [PATCH 0643/1499] [Extensions] Add LogToActivityEventConversionOptions.Filter callback (#1059) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + src/OpenTelemetry.Extensions/CHANGELOG.md | 3 + .../ActivityEventAttachingLogProcessor.cs | 15 ++++ .../OpenTelemetryExtensionsEventSource.cs | 15 ++++ .../LogToActivityEventConversionOptions.cs | 13 +++ ...ActivityEventAttachingLogProcessorTests.cs | 79 ++++++++++++++++++- 8 files changed, 129 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt index 0caf94ce2c..02a765cd0b 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,6 +1,8 @@ #nullable enable Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions OpenTelemetry.Logs.LogToActivityEventConversionOptions +OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.get -> System.Func? +OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void diff --git a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt index 0caf94ce2c..02a765cd0b 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,6 +1,8 @@ #nullable enable Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions OpenTelemetry.Logs.LogToActivityEventConversionOptions +OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.get -> System.Func? +OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void diff --git a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 0caf94ce2c..02a765cd0b 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,8 @@ #nullable enable Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions OpenTelemetry.Logs.LogToActivityEventConversionOptions +OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.get -> System.Func? +OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index f0c228edd6..0e618d7a3d 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add LogToActivityEventConversionOptions.Filter callback + ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) + ## 1.0.0-beta.4 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index eb38ff899b..33e8b2f887 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -50,6 +50,21 @@ public override void OnEnd(LogRecord data) if (activity?.IsAllDataRequested == true) { + try + { + if (this.options.Filter?.Invoke(data) == false) + { + return; + } + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception ex) +#pragma warning restore CA1031 // Do not catch general exception types + { + OpenTelemetryExtensionsEventSource.Log.LogRecordFilterException(data.CategoryName, ex); + return; + } + var tags = new ActivityTagsCollection { { nameof(data.CategoryName), data.CategoryName }, diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index 5a5d446831..1b199c2832 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -42,4 +42,19 @@ public void LogProcessorException(string @event, string exception) { this.WriteEvent(1, @event, exception); } + + [NonEvent] + public void LogRecordFilterException(string? categoryName, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) + { + this.LogRecordFilterException(categoryName, ex.ToInvariantString()); + } + } + + [Event(2, Message = "Filter threw an exception, log record will not be attached to an activity, the log record would flow to its pipeline unaffected. CategoryName: '{0}', Exception: {1}.", Level = EventLevel.Warning)] + public void LogRecordFilterException(string? categoryName, string exception) + { + this.WriteEvent(2, categoryName, exception); + } } diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index 3451f0775c..fa79214378 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -34,4 +34,17 @@ public class LogToActivityEventConversionOptions /// Gets or sets the callback action used to convert log scopes into tags. /// public Action ScopeConverter { get; set; } = DefaultLogStateConverter.ConvertScope; + + /// + /// Gets or sets the callback method allowing to filter out particular . + /// + /// + /// The filter callback receives the for the + /// processed logRecord and should return a boolean. + /// + /// If filter returns the event is collected. + /// If filter returns or throws an exception the event is filtered out (NOT collected). + /// + /// + public Func? Filter { get; set; } } diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index ee0e28f688..e0a787ba73 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -57,13 +57,16 @@ public void Dispose() [InlineData(false)] [InlineData(true, 18, true, true, true)] [InlineData(true, 0, false, false, true, true)] + [InlineData(true, 18, true, true, true, false, true)] + [InlineData(true, 0, false, false, true, true, true)] public void AttachLogsToActivityEventTest( bool sampled, int eventId = 0, bool includeFormattedMessage = false, bool parseStateValues = false, bool includeScopes = false, - bool recordException = false) + bool recordException = false, + bool? filter = null) { this.sampled = sampled; @@ -74,7 +77,15 @@ public void AttachLogsToActivityEventTest( options.IncludeScopes = includeScopes; options.IncludeFormattedMessage = includeFormattedMessage; options.ParseStateValues = parseStateValues; - options.AttachLogsToActivityEvent(); + options.AttachLogsToActivityEvent(x => + { + x.Filter = filter switch + { + true => _ => true, + false => _ => false, + null => null, + }; + }); }); builder.AddFilter(typeof(ActivityEventAttachingLogProcessorTests).FullName, LogLevel.Trace); }); @@ -180,4 +191,68 @@ public void AttachLogsToActivityEventTest( Assert.Empty(activity.Events); } } + + [Theory] + [InlineData(true, true)] + [InlineData(false, true)] + [InlineData(true, true, 18, true, true, true)] + [InlineData(true, true, 0, false, false, true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(true, false, 18, true, true, true)] + [InlineData(true, false, 0, false, false, true, true)] + public void AttachLogsToActivityEventTest_Filter( + bool sampled, + bool filterThrows, + int eventId = 0, + bool includeFormattedMessage = false, + bool parseStateValues = false, + bool includeScopes = false, + bool recordException = false) + { + this.sampled = sampled; + + using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => + { + builder.AddOpenTelemetry(options => + { + options.IncludeScopes = includeScopes; + options.IncludeFormattedMessage = includeFormattedMessage; + options.ParseStateValues = parseStateValues; + options.AttachLogsToActivityEvent(x => x.Filter = _ => filterThrows + ? throw new Exception() + : false); + }); + builder.AddFilter(typeof(ActivityEventAttachingLogProcessorTests).FullName, LogLevel.Trace); + }); + + ILogger logger = loggerFactory.CreateLogger(); + Activity activity = this.activitySource.StartActivity("Test"); + + using IDisposable scope = logger.BeginScope("{NodeId}", 99); + + logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); + + if (recordException) + { + var innerActivity = this.activitySource.StartActivity("InnerTest"); + + using IDisposable innerScope = logger.BeginScope("{RequestId}", "1234"); + + logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); + + innerActivity.Dispose(); + } + + activity.Dispose(); + + if (sampled) + { + Assert.DoesNotContain(activity.Events, x => x.Name == "log"); + } + else + { + Assert.Empty(activity.Events); + } + } } From 595a9a34e3e0f10f25df64153a83889ad386a3fc Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 24 Mar 2023 09:26:42 -0700 Subject: [PATCH 0644/1499] [Exporter.Geneva] Refactor GenevaMetricExporter (#1102) Co-authored-by: Cijo Thomas --- .../Metrics/GenevaMetricExporter.cs | 555 ++++++++---------- 1 file changed, 238 insertions(+), 317 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 4128c03bb3..72819a4f56 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -508,143 +508,17 @@ internal unsafe ushort SerializeMetricWithTLV( // Leave enough space for the header var bufferIndex = sizeof(BinaryHeader); - // Serialize metric name - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.MetricName); - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricName)); + SerializeMetricName(metricName, this.buffer, ref bufferIndex); - #region Serialize metric data + SerializeNonHistogramMetricData(eventType, value, timestamp, this.buffer, ref bufferIndex); - var payloadType = eventType == MetricEventType.ULongMetric ? PayloadType.ULongMetric : PayloadType.DoubleMetric; - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)payloadType); + SerializeMetricDimensions(tags, this.prepopulatedDimensionsCount, this.serializedPrepopulatedDimensionsKeys, this.serializedPrepopulatedDimensionsValues, this.buffer, ref bufferIndex); - // Get a placeholder to add the payloadType length - int payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, (ulong)timestamp); // timestamp - - if (payloadType == PayloadType.ULongMetric) - { - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, value.UInt64Value); - } - else - { - MetricSerializer.SerializeFloat64(this.buffer, ref bufferIndex, value.DoubleValue); - } - - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); - - #endregion - - #region Serialize metric dimensions - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Dimensions); - - // Get a placeholder to add the payloadType length - payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - // Get a placeholder to add dimensions count later - var bufferIndexForDimensionsCount = bufferIndex; - bufferIndex += 2; - - ushort dimensionsWritten = 0; - - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } - - if (this.prepopulatedDimensionsCount > 0) - { - dimensionsWritten += this.prepopulatedDimensionsCount; - } - - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.buffer, ref bufferIndex, tag.Key); - } - - dimensionsWritten += (ushort)tags.Count; - - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); - } - - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.buffer, ref bufferIndex, dimensionValue); - } - - // Backfill the number of dimensions written - MetricSerializer.SerializeUInt16(this.buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); - - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); - - #endregion - - #region Serialize exemplars - - if (exemplars.Length > 0) - { - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Exemplars); - - // Get a placeholder to add the payloadType length - payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version - - // TODO: Avoid this additional enumeration - var exemplarsCount = 0; - foreach (var exemplar in exemplars) - { - if (exemplar.Timestamp != default) - { - exemplarsCount++; - } - } - - MetricSerializer.SerializeInt32AsBase128(this.buffer, ref bufferIndex, exemplarsCount); - - foreach (var exemplar in exemplars) - { - if (exemplar.Timestamp != default) - { - this.SerializeExemplar(exemplar, ref bufferIndex); - } - } + SerializeExemplars(exemplars, this.buffer, ref bufferIndex); - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); - } + SerializeMonitoringAccount(this.monitoringAccount, this.buffer, ref bufferIndex); - #endregion - - // Serialize monitoring account - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.AccountName); - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.monitoringAccount)); - - // Serialize metric namespace - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Namespace); - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.metricNamespace)); + SerializeMetricNamespace(this.metricNamespace, this.buffer, ref bufferIndex); // Write the final size of the payload bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); @@ -685,227 +559,163 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( // Leave enough space for the header var bufferIndex = sizeof(BinaryHeader); - // Serialize metric name - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.MetricName); - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricName)); - - #region Serialize histogram metric data - - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.ExternallyAggregatedULongDistributionMetric); + SerializeMetricName(metricName, this.buffer, ref bufferIndex); - // Get a placeholder to add the payloadType length - int payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; + SerializeHistogramMetricData(buckets, sum, count, min, max, timestamp, this.buffer, ref bufferIndex); - // Serialize sum, count, min, and max - MetricSerializer.SerializeUInt32(this.buffer, ref bufferIndex, count); // histogram count - MetricSerializer.SerializeUInt32(this.buffer, ref bufferIndex, 0); // padding - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, (ulong)timestamp); // timestamp - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(sum)); // histogram sum - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(min)); // histogram min - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(max)); // histogram max + SerializeMetricDimensions(tags, this.prepopulatedDimensionsCount, this.serializedPrepopulatedDimensionsKeys, this.serializedPrepopulatedDimensionsValues, this.buffer, ref bufferIndex); - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + SerializeExemplars(exemplars, this.buffer, ref bufferIndex); - // Serialize histogram buckets as value-count pairs - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.HistogramULongValueCountPairs); + SerializeMonitoringAccount(this.monitoringAccount, this.buffer, ref bufferIndex); - // Get a placeholder to add the payloadType length - payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; + SerializeMetricNamespace(this.metricNamespace, this.buffer, ref bufferIndex); - // Get a placeholder to add the number of value-count pairs added - // with value being the bucket boundary and count being the respective count - - var itemsWrittenIndex = bufferIndex; - MetricSerializer.SerializeUInt16(this.buffer, ref bufferIndex, 0); + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - // Bucket values - ushort bucketCount = 0; - double lastExplicitBound = default; - foreach (var bucket in buckets) + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.buffer) { - if (bucket.BucketCount > 0) - { - this.SerializeHistogramBucketWithTLV(bucket, ref bufferIndex, lastExplicitBound); - bucketCount++; - } - - lastExplicitBound = bucket.ExplicitBound; + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.TLV; + ptr->BodyLength = bodyLength; } + } + finally + { + } - // Write the number of items in distribution emitted and reset back to end. - MetricSerializer.SerializeUInt16(this.buffer, ref itemsWrittenIndex, bucketCount); + return bodyLength; + } - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMetricName(string metricName, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.MetricName); + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricName)); + } - #endregion + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMetricNamespace(string metricNamespace, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Namespace); + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricNamespace)); + } - #region Serialize metric dimensions - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Dimensions); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMonitoringAccount(string monitoringAccount, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.AccountName); + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(monitoringAccount)); + } - // Get a placeholder to add the payloadType length - payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMetricDimensions(in ReadOnlyTagCollection tags, ushort prepopulatedDimensionsCount, List serializedPrepopulatedDimensionsKeys, List serializedPrepopulatedDimensionsValues, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Dimensions); - // Get a placeholder to add dimensions count later - var bufferIndexForDimensionsCount = bufferIndex; - bufferIndex += 2; + // Get a placeholder to add the payloadType length + var payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; - ushort dimensionsWritten = 0; + // Get a placeholder to add dimensions count later + var bufferIndexForDimensionsCount = bufferIndex; + bufferIndex += 2; - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } + ushort dimensionsWritten = 0; - if (this.prepopulatedDimensionsCount > 0) + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, serializedPrepopulatedDimensionsKeys[i]); + } + + if (prepopulatedDimensionsCount > 0) + { + dimensionsWritten += prepopulatedDimensionsCount; + } + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) { - dimensionsWritten += this.prepopulatedDimensionsCount; + // TODO: Data Validation } - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } + MetricSerializer.SerializeString(buffer, ref bufferIndex, tag.Key); + } - MetricSerializer.SerializeString(this.buffer, ref bufferIndex, tag.Key); - } + dimensionsWritten += (ushort)tags.Count; - dimensionsWritten += (ushort)tags.Count; + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, serializedPrepopulatedDimensionsValues[i]); + } - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) { - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + // TODO: Data Validation } - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } + MetricSerializer.SerializeString(buffer, ref bufferIndex, dimensionValue); + } - MetricSerializer.SerializeString(this.buffer, ref bufferIndex, dimensionValue); - } + // Backfill the number of dimensions written + MetricSerializer.SerializeUInt16(buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); - // Backfill the number of dimensions written - MetricSerializer.SerializeUInt16(this.buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) + { + if (exemplars.Length > 0) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Exemplars); - #endregion + // Get a placeholder to add the payloadType length + var payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; - #region Serialize exemplars + MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version - if (exemplars.Length > 0) + // TODO: Avoid this additional enumeration + var exemplarsCount = 0; + foreach (var exemplar in exemplars) { - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Exemplars); - - // Get a placeholder to add the payloadType length - payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version - - // TODO: Avoid this additional enumeration - var exemplarsCount = 0; - foreach (var exemplar in exemplars) - { - if (exemplar.Timestamp != default) - { - exemplarsCount++; - } - } - - MetricSerializer.SerializeInt32AsBase128(this.buffer, ref bufferIndex, exemplarsCount); - - foreach (var exemplar in exemplars) + if (exemplar.Timestamp != default) { - if (exemplar.Timestamp != default) - { - this.SerializeExemplar(exemplar, ref bufferIndex); - } + exemplarsCount++; } - - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(this.buffer, ref payloadTypeStartIndex, payloadTypeLength); } - #endregion - - // Serialize monitoring account - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.AccountName); - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.monitoringAccount)); - - // Serialize metric namespace - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, (byte)PayloadType.Namespace); - MetricSerializer.SerializeEncodedString(this.buffer, ref bufferIndex, Encoding.UTF8.GetBytes(this.metricNamespace)); + MetricSerializer.SerializeInt32AsBase128(buffer, ref bufferIndex, exemplarsCount); - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.buffer) + foreach (var exemplar in exemplars) { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)MetricEventType.TLV; - ptr->BodyLength = bodyLength; + if (exemplar.Timestamp != default) + { + SerializeSingleExmeplar(exemplar, buffer, ref bufferIndex); + } } - } - finally - { - } - - return bodyLength; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) - { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - } - else - { - // The bucket to catch the overflows is one greater than the last bound provided - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); - } - - MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) - { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - } - else - { - // The bucket to catch the overflows is one greater than the last bound provided - MetricSerializer.SerializeUInt64(this.buffer, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); } - - MetricSerializer.SerializeUInt32(this.buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) + private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, ref int bufferIndex) { - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // version + MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version var bufferIndexForLength = bufferIndex; bufferIndex++; @@ -924,15 +734,15 @@ private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) if (isWholeNumber) { flags |= ExemplarFlags.IsMetricValueDoubleStoredAsLong; - MetricSerializer.SerializeInt64AsBase128(this.buffer, ref bufferIndex, valueAsLong); // serialize long value + MetricSerializer.SerializeInt64AsBase128(buffer, ref bufferIndex, valueAsLong); // serialize long value } else { - MetricSerializer.SerializeFloat64(this.buffer, ref bufferIndex, value); // serialize double value + MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value); // serialize double value } var bufferIndexForNumberOfLabels = bufferIndex; - MetricSerializer.SerializeByte(this.buffer, ref bufferIndex, 0); // serialize zero as the count of labels; this would be updated later if the exemplar has labels + MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // serialize zero as the count of labels; this would be updated later if the exemplar has labels byte numberOfLabels = 0; // Convert exemplar timestamp to unix nanoseconds @@ -941,13 +751,13 @@ private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) .Subtract(new DateTime(1970, 1, 1)) .TotalMilliseconds * 1000000; - MetricSerializer.SerializeInt64(this.buffer, ref bufferIndex, (long)unixNanoSeconds); // serialize timestamp + MetricSerializer.SerializeInt64(buffer, ref bufferIndex, (long)unixNanoSeconds); // serialize timestamp if (exemplar.TraceId.HasValue) { Span traceIdBytes = stackalloc byte[16]; exemplar.TraceId.Value.CopyTo(traceIdBytes); - MetricSerializer.SerializeSpanOfBytes(this.buffer, ref bufferIndex, traceIdBytes, traceIdBytes.Length); // serialize traceId + MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, traceIdBytes, traceIdBytes.Length); // serialize traceId flags |= ExemplarFlags.TraceIdExists; } @@ -956,7 +766,7 @@ private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) { Span spanIdBytes = stackalloc byte[8]; exemplar.SpanId.Value.CopyTo(spanIdBytes); - MetricSerializer.SerializeSpanOfBytes(this.buffer, ref bufferIndex, spanIdBytes, spanIdBytes.Length); // serialize spanId + MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, spanIdBytes, spanIdBytes.Length); // serialize spanId flags |= ExemplarFlags.SpanIdExists; } @@ -966,18 +776,129 @@ private void SerializeExemplar(Exemplar exemplar, ref int bufferIndex) { foreach (var tag in exemplar.FilteredTags) { - MetricSerializer.SerializeBase128String(this.buffer, ref bufferIndex, tag.Key); - MetricSerializer.SerializeBase128String(this.buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); + MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, tag.Key); + MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); numberOfLabels++; } - MetricSerializer.SerializeByte(this.buffer, ref bufferIndexForNumberOfLabels, numberOfLabels); + MetricSerializer.SerializeByte(buffer, ref bufferIndexForNumberOfLabels, numberOfLabels); } - MetricSerializer.SerializeByte(this.buffer, ref bufferIndexForFlags, (byte)flags); + MetricSerializer.SerializeByte(buffer, ref bufferIndexForFlags, (byte)flags); var exemplarLength = bufferIndex - bufferIndexForLength + 1; - MetricSerializer.SerializeByte(this.buffer, ref bufferIndexForLength, (byte)exemplarLength); + MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) + { + var payloadType = eventType == MetricEventType.ULongMetric ? PayloadType.ULongMetric : PayloadType.DoubleMetric; + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)payloadType); + + // Get a placeholder to add the payloadType length + int payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp + + if (payloadType == PayloadType.ULongMetric) + { + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, value.UInt64Value); + } + else + { + MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value.DoubleValue); + } + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeHistogramMetricData(HistogramBuckets buckets, double sum, uint count, double min, double max, long timestamp, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.ExternallyAggregatedULongDistributionMetric); + + // Get a placeholder to add the payloadType length + int payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Serialize sum, count, min, and max + MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, count); // histogram count + MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, 0); // padding + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(sum)); // histogram sum + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(min)); // histogram min + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(max)); // histogram max + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + + // Serialize histogram buckets as value-count pairs + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.HistogramULongValueCountPairs); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add the number of value-count pairs added + // with value being the bucket boundary and count being the respective count + + var itemsWrittenIndex = bufferIndex; + MetricSerializer.SerializeUInt16(buffer, ref bufferIndex, 0); + + // Bucket values + ushort bucketCount = 0; + double lastExplicitBound = default; + foreach (var bucket in buckets) + { + if (bucket.BucketCount > 0) + { + SerializeHistogramBucketWithTLV(bucket, buffer, ref bufferIndex, lastExplicitBound); + bucketCount++; + } + + lastExplicitBound = bucket.ExplicitBound; + } + + // Write the number of items in distribution emitted and reset back to end. + MetricSerializer.SerializeUInt16(buffer, ref itemsWrittenIndex, bucketCount); + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, byte[] buffer, ref int bufferIndex, double lastExplicitBound) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); } private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) From e4b49d225c801830a2e7bc29998a03b5cc94ec67 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 27 Mar 2023 16:03:36 -0700 Subject: [PATCH 0645/1499] [GenevaExporter] Remove extra table name mapping validation (#1109) --- .../CHANGELOG.md | 4 ++ .../GenevaExporterOptions.cs | 3 +- .../Internal/TableNameSerializer.cs | 40 ------------------- .../GenevaLogExporterTests.cs | 1 + 4 files changed, 7 insertions(+), 41 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 8e52a56a2e..84dfece69b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Relaxed table name mapping validation rules to restore the previous behavior + from version 1.3.0. + ([#1109](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1109)) + ## 1.5.0-alpha.1 Released 2023-Mar-13 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 3af00bb09c..5d781ec8ac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -62,6 +62,7 @@ public IReadOnlyDictionary TableNameMappings throw new ArgumentException($"The table name mapping value '{entry.Value}' provided for key '{entry.Key}' contained non-ASCII characters.", nameof(this.TableNameMappings)); } + /* Note: Validation disabled because it broke previously released versions. if (entry.Value != "*") { if (!TableNameSerializer.IsValidTableName(entry.Value)) @@ -73,7 +74,7 @@ public IReadOnlyDictionary TableNameMappings { throw new ArgumentException($"The table name mapping value '{entry.Value}' provided for key '{entry.Key}' is reserved and cannot be specified.", nameof(this.TableNameMappings)); } - } + }*/ copy[entry.Key] = entry.Value; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index 0996827a48..f22ff8336b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -49,7 +49,6 @@ public TableNameSerializer(GenevaExporterOptions options, string defaultTableNam { Debug.Assert(options != null, "options were null"); Debug.Assert(!string.IsNullOrWhiteSpace(defaultTableName), "defaultEventName was null or whitespace"); - Debug.Assert(IsValidTableName(defaultTableName), "defaultEventName was invalid"); this.m_defaultTableName = BuildStr8BufferForAsciiString(defaultTableName); @@ -83,45 +82,6 @@ public TableNameSerializer(GenevaExporterOptions options, string defaultTableNam } } - public static bool IsReservedTableName(string tableName) - { - Debug.Assert(!string.IsNullOrWhiteSpace(tableName), "tableName was null or whitespace"); - - // TODO: Implement this if needed. - - return false; - } - - public static bool IsValidTableName(string tableName) - { - Debug.Assert(!string.IsNullOrWhiteSpace(tableName), "tableName was null or whitespace"); - - var length = tableName.Length; - if (length > MaxSanitizedCategoryNameLength) - { - return false; - } - - char firstChar = tableName[0]; - if (firstChar < 'A' || firstChar > 'Z') - { - return false; - } - - for (int i = 1; i < length; i++) - { - char cur = tableName[i]; - if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) - { - continue; - } - - return false; - } - - return true; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ResolveAndSerializeTableNameForCategoryName(byte[] destination, int offset, string categoryName, out ReadOnlySpan tableName) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index ad823c1b12..04f3c055db 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -135,6 +135,7 @@ public void IncompatibleConnectionString_Linux() [InlineData("categoryB", "TableB")] [InlineData("categoryA", "TableA", "categoryB", "TableB")] [InlineData("categoryA", "TableA", "*", "CatchAll")] + [InlineData("Example.DefaultService", "myTableName")] [InlineData(null)] public void TableNameMappingTest(params string[] category) { From 86eae833af4628c11cfe627c5f1a9da84d022958 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 27 Mar 2023 16:26:27 -0700 Subject: [PATCH 0646/1499] [PersistentStorage.FileSystem] Remove custom folder structure for file (#1110) --- .../CHANGELOG.md | 4 ++++ .../FileBlobProvider.cs | 16 ++++++++-------- .../PersistentStorageHelper.cs | 18 +++--------------- .../FileBlobProviderTests.cs | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index f9a1de58f0..380611ae50 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## 1.0.0-beta.2 (Unreleased) +* `FileBlobProvider` will now use the path provided during initialization as is +* for storing blobs, without adding additional hash of current user and process. +([#1110](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1110)) + * Going forward the NuGet package will be [`OpenTelemetry.PersistentStorage.FileSystem`](https://www.nuget.org/packages/OpenTelemetry.Extensions.FileSystem). Older versions will remain at diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index cf0477980d..188defef62 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -31,7 +31,7 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; /// public class FileBlobProvider : PersistentBlobProvider, IDisposable { - private readonly string directoryPath; + internal readonly string DirectoryPath; private readonly long maxSizeInBytes; private readonly long retentionPeriodInMilliseconds; private readonly int writeTimeoutInMilliseconds; @@ -93,7 +93,7 @@ public FileBlobProvider( Guard.ThrowIfNull(path); // TODO: Validate time period values - this.directoryPath = PersistentStorageHelper.CreateSubdirectory(path); + this.DirectoryPath = PersistentStorageHelper.CreateSubdirectory(path); this.maxSizeInBytes = maxSizeInBytes; this.retentionPeriodInMilliseconds = retentionPeriodInMilliseconds; this.writeTimeoutInMilliseconds = writeTimeoutInMilliseconds; @@ -127,7 +127,7 @@ protected override IEnumerable OnGetBlobs() { var retentionDeadline = DateTime.UtcNow - TimeSpan.FromMilliseconds(this.retentionPeriodInMilliseconds); - foreach (var file in Directory.EnumerateFiles(this.directoryPath, "*.blob", SearchOption.TopDirectoryOnly).OrderByDescending(f => f)) + foreach (var file in Directory.EnumerateFiles(this.DirectoryPath, "*.blob", SearchOption.TopDirectoryOnly).OrderByDescending(f => f)) { DateTime fileDateTime = PersistentStorageHelper.GetDateTimeFromBlobName(file); if (fileDateTime > retentionDeadline) @@ -162,18 +162,18 @@ private void OnMaintenanceEvent(object? source, ElapsedEventArgs e) { try { - if (!Directory.Exists(this.directoryPath)) + if (!Directory.Exists(this.DirectoryPath)) { - Directory.CreateDirectory(this.directoryPath); + Directory.CreateDirectory(this.DirectoryPath); } } catch (Exception ex) { - PersistentStorageEventSource.Log.PersistentStorageException(nameof(FileBlobProvider), $"Error creating directory {this.directoryPath}", ex); + PersistentStorageEventSource.Log.PersistentStorageException(nameof(FileBlobProvider), $"Error creating directory {this.DirectoryPath}", ex); return; } - PersistentStorageHelper.RemoveExpiredBlobs(this.directoryPath, this.retentionPeriodInMilliseconds, this.writeTimeoutInMilliseconds); + PersistentStorageHelper.RemoveExpiredBlobs(this.DirectoryPath, this.retentionPeriodInMilliseconds, this.writeTimeoutInMilliseconds); } private bool CheckStorageSize() @@ -200,7 +200,7 @@ private bool CheckStorageSize() try { - var blobFilePath = Path.Combine(this.directoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); + var blobFilePath = Path.Combine(this.DirectoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); var blob = new FileBlob(blobFilePath); if (blob.TryWrite(buffer, leasePeriodMilliseconds)) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs index e8bf18339f..71584b491c 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs @@ -15,7 +15,6 @@ // using System; -using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -160,21 +159,10 @@ internal static string GetUniqueFileName(string extension) internal static string CreateSubdirectory(string path) { - string subdirectoryPath = string.Empty; - string baseDirectory = string.Empty; -#if !NETSTANDARD - baseDirectory = AppDomain.CurrentDomain.BaseDirectory; -#else - baseDirectory = AppContext.BaseDirectory; -#endif - - string appIdentity = Environment.UserName + "@" + Path.Combine(baseDirectory, Process.GetCurrentProcess().ProcessName); - string subdirectoryName = GetSHA256Hash(appIdentity); - subdirectoryPath = Path.Combine(path, subdirectoryName); - Directory.CreateDirectory(subdirectoryPath); + Directory.CreateDirectory(path); - directorySize = CalculateFolderSize(subdirectoryPath); - return subdirectoryPath; + directorySize = CalculateFolderSize(path); + return path; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index 8cd5a9127e..f9aebd1dc4 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -24,6 +24,20 @@ namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; public class FileBlobProviderTests { + [Fact] + public void FileBlobProvider_CreatesSubDirectory() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + + using var blobProvider = new FileBlobProvider(testDirectory.FullName); + + Assert.Equal(testDirectory.FullName, blobProvider.DirectoryPath); + Directory.Exists(testDirectory.FullName); + + // clean up + Directory.Delete(testDirectory.FullName, true); + } + [Fact] public void FileBlobProvider_E2E_Test() { From e19674f2e4c31297dc300feb53bf5b3fcd5896d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 28 Mar 2023 17:42:04 +0200 Subject: [PATCH 0647/1499] [Extenstions.AzureMonitor] Codeowners for tests (#1113) --- .github/component_owners.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 8853669a57..bcdd4deb0a 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -103,6 +103,9 @@ components: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: - codeblanch + test/OpenTelemetry.Extensions.AzureMonitor.Tests/: + - rajkumar-rangaraj + - vishweshbankwar test/OpenTelemetry.Extensions.Docker.Tests/: - iskiselev test/OpenTelemetry.Extensions.Enrichment.Tests/: From 25e85fe058a2bedacf1db7ddc4ed1ffe060f4000 Mon Sep 17 00:00:00 2001 From: Will Rogers Date: Tue, 28 Mar 2023 11:54:51 -0400 Subject: [PATCH 0648/1499] [Instrumentation.AWS] Replace net452 target with net462 (#1095) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cijo Thomas Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/{net452 => net462}/PublicAPI.Shipped.txt | 0 .../.publicApi/{net452 => net462}/PublicAPI.Unshipped.txt | 0 .../CHANGELOG.md | 3 +++ .../OpenTelemetry.Contrib.Instrumentation.AWS.csproj | 2 +- ...OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj | 5 ++--- .../TestAWSClientInstrumentation.cs | 8 ++++---- .../Tools/CustomResponses.cs | 8 ++++---- .../Tools/MockHttpRequest.cs | 6 +++--- .../Tools/MockHttpRequestFactory.cs | 4 ++-- .../Tools/MockWebResponse.cs | 6 +++--- 10 files changed, 22 insertions(+), 20 deletions(-) rename src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/{net452 => net462}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/{net452 => net462}/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net452/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md index 3962068ec6..28303b32a3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Raised the minimum .NET version to `net462` + ([#1095](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1095)) + ## 1.0.2 Released 2022-Nov-11 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 35155529f5..1d908482c2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -2,7 +2,7 @@ - netstandard2.0;net452 + netstandard2.0;$(NetFrameworkMinimumSupportedVersion) AWS client instrumentation for OpenTelemetry .NET Instrumentation.AWS- enable diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index b895bfeeb7..8df48f35a5 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -4,7 +4,7 @@ Unit test project for AWS client instrumentation for OpenTelemetry netcoreapp3.1 - $(TargetFrameworks);net452 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) enable @@ -26,10 +26,9 @@ - + - diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 014d1fdae1..b33946eb02 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -53,7 +53,7 @@ public void TestDDBScanSuccessful() scan_request.TableName = "SampleProduct"; scan_request.AttributesToGet = new List() { "Id", "Name" }; -#if NET452 +#if NETFRAMEWORK ddb.Scan(scan_request); #else ddb.ScanAsync(scan_request).Wait(); @@ -73,7 +73,7 @@ public void TestDDBScanSuccessful() } [Fact] -#if NET452 +#if NETFRAMEWORK public void TestDDBScanUnsuccessful() #else public async Task TestDDBScanUnsuccessful() @@ -103,7 +103,7 @@ public async Task TestDDBScanUnsuccessful() try { -#if NET452 +#if NETFRAMEWORK ddb.Scan(scan_request); #else await ddb.ScanAsync(scan_request); @@ -148,7 +148,7 @@ public void TestSQSSendMessageSuccessful() var send_msg_req = new SendMessageRequest(); send_msg_req.QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue"; send_msg_req.MessageBody = "Hello from OT"; -#if NET452 +#if NETFRAMEWORK sqs.SendMessage(send_msg_req); #else sqs.SendMessageAsync(send_msg_req).Wait(); diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index abf81a2cb5..d4889e9fbd 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -16,16 +16,16 @@ using System; using System.Collections.Generic; -#if NET452 +#if NETFRAMEWORK using System.IO; #endif using System.Net; -#if !NET452 +#if !NETFRAMEWORK using System.Net.Http; #endif using Amazon.Runtime; using Amazon.Runtime.Internal; -#if NET452 +#if NETFRAMEWORK using Amazon.Runtime.Internal.Transform; #endif using Amazon.Util; @@ -34,7 +34,7 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; internal static class CustomResponses { -#if NET452 +#if NETFRAMEWORK public static void SetResponse( AmazonServiceClient client, string? content, string requestId, bool isOK) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index a6229f8d29..29c0ceeb26 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -19,7 +19,7 @@ using System.IO; using System.Linq; using System.Net; -#if !NET452 +#if !NETFRAMEWORK using System.Net.Http; #endif using System.Threading; @@ -29,7 +29,7 @@ using Amazon.Runtime.Internal.Transform; namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; -#if NET452 +#if NETFRAMEWORK internal class MockHttpRequest : IHttpRequest { private Stream? requestStream; @@ -76,7 +76,7 @@ public Stream GetRequestContent() return this.requestStream; } - public Amazon.Runtime.Internal.Transform.IWebResponseData GetResponse() + public IWebResponseData GetResponse() { if (this.GetResponseAction != null) { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index 67605511f3..8fffae1b0e 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -15,7 +15,7 @@ // using System; -#if NET452 +#if NETFRAMEWORK using System.IO; using System.Net; #else @@ -24,7 +24,7 @@ using Amazon.Runtime; namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; -#if NET452 +#if NETFRAMEWORK internal class MockHttpRequestFactory : IHttpRequestFactory { public Action? GetResponseAction { get; set; } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 326bdfa0f8..56439d0aa2 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -16,11 +16,11 @@ using System; using System.Collections.Generic; -#if NET452 +#if NETFRAMEWORK using System.IO; #endif using System.Net; -#if !NET452 +#if !NETFRAMEWORK using System.Net.Http; #endif using System.Reflection; @@ -29,7 +29,7 @@ namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; internal class MockWebResponse { -#if NET452 +#if NETFRAMEWORK public static HttpWebResponse? CreateFromResource(string resourceName) { var rawResponse = Utils.GetResourceText(resourceName); From 8194f0581fd00f2d189513d0b0d8dd9397093f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 28 Mar 2023 23:37:24 +0200 Subject: [PATCH 0649/1499] [Extenstions.AzureMonitor] Nullable (#1112) Co-authored-by: Utkarsh Umesan Pillai --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 1 + .../OpenTelemetry.Extensions.AzureMonitor.csproj | 1 + .../OpenTelemetry.Extensions.AzureMonitor.Tests.csproj | 1 + 5 files changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 1780ea877a..761d805b1f 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -7,6 +7,7 @@ net6.0;$(TargetFrameworks) Extensions.AzureMonitor- true + enable diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj index ee29cac225..e2b1efa2e7 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj @@ -3,6 +3,7 @@ net7.0;net6.0 + enable From dcac9b8b426f9e345d207781ed33dc3ddbaff737 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Tue, 28 Mar 2023 15:09:43 -0700 Subject: [PATCH 0650/1499] [Sampler.AWS] AWS X-Ray remote sampler part 1 (#1091) --- .github/ISSUE_TEMPLATE/comp_sampler_aws.md | 41 ++++++ .github/component_owners.yml | 5 +- .github/workflows/package-Sampler.AWS.yml | 67 ++++++++++ build/Common.nonprod.props | 1 + opentelemetry-dotnet-contrib.sln | 14 ++ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 9 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 9 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 9 ++ .../AWSSamplerEventSource.cs | 65 ++++++++++ .../AWSXRayRemoteSampler.cs | 84 ++++++++++++ .../AWSXRayRemoteSamplerBuilder.cs | 83 ++++++++++++ .../AWSXRaySamplerClient.cs | 114 +++++++++++++++++ src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs | 22 ++++ src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 8 ++ .../GetSamplingRulesResponse.cs | 29 +++++ .../OpenTelemetry.Sampler.AWS.csproj | 24 ++++ src/OpenTelemetry.Sampler.AWS/README.md | 37 ++++++ src/OpenTelemetry.Sampler.AWS/SamplingRule.cs | 94 ++++++++++++++ .../SamplingRuleRecord.cs | 31 +++++ .../Data/GetSamplingRulesResponse.json | 65 ++++++++++ .../OpenTelemetry.Sampler.AWS.Tests.csproj | 29 +++++ .../TestAWSXRayRemoteSampler.cs | 62 +++++++++ .../TestAWSXRaySamplerClient.cs | 121 ++++++++++++++++++ 26 files changed, 1025 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_sampler_aws.md create mode 100644 .github/workflows/package-Sampler.AWS.yml create mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/CHANGELOG.md create mode 100644 src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj create mode 100644 src/OpenTelemetry.Sampler.AWS/README.md create mode 100644 src/OpenTelemetry.Sampler.AWS/SamplingRule.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponse.json create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs diff --git a/.github/ISSUE_TEMPLATE/comp_sampler_aws.md b/.github/ISSUE_TEMPLATE/comp_sampler_aws.md new file mode 100644 index 0000000000..80463dcf30 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_sampler_aws.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Sampler.AWS +about: Issue with OpenTelemetry.Sampler.AWS +labels: comp:sampler.aws +--- + +# Issue with OpenTelemetry.Sampler.AWS + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index bcdd4deb0a..f7b647ef1a 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -65,6 +65,8 @@ components: src/OpenTelemetry.ResourceDetectors.Azure/: - rajkumar-rangaraj - vishweshbankwar + src/OpenTelemetry.Sampler.AWS/: + - srprash test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - lupengamzn @@ -140,4 +142,5 @@ components: test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - rajkumar-rangaraj - vishweshbankwar - + test/OpenTelemetry.Sampler.AWS.Tests/: + - srprash diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml new file mode 100644 index 0000000000..eb9036ccbb --- /dev/null +++ b/.github/workflows/package-Sampler.AWS.yml @@ -0,0 +1,67 @@ +name: Pack OpenTelemetry.Sampler.AWS + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Sampler.AWS-*' # trigger when we create a tag with prefix "Sampler.AWS-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + permissions: + contents: write + env: + PROJECT: OpenTelemetry.Sampler.AWS + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index c9f464dd5d..a8ec7107cb 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -31,6 +31,7 @@ $(OpenTelemetryCoreLatestPrereleaseVersion) [2.4.3,3.0) [2.4.2,3.0) + [1.5.20,2.0) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index bf2ff36f22..a1c0b69b94 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -256,6 +256,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentSto EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.FileSystem.Tests", "test\OpenTelemetry.PersistentStorage.FileSystem.Tests\OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj", "{C7215B69-0D77-4D52-AFBB-A6662249B3AC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Sampler.AWS", "src\OpenTelemetry.Sampler.AWS\OpenTelemetry.Sampler.AWS.csproj", "{54002B08-F6AE-4B2B-AB0C-86E5A05926A3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Sampler.AWS.Tests", "test\OpenTelemetry.Sampler.AWS.Tests\OpenTelemetry.Sampler.AWS.Tests.csproj", "{48C29501-3FA2-46A7-B5BA-D282EA8F1274}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Benchmarks", "test\OpenTelemetry.Exporter.OneCollector.Benchmarks\OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj", "{C42868C8-968A-473F-AC39-AC97C5D47E84}" EndProject Global @@ -552,6 +556,14 @@ Global {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7215B69-0D77-4D52-AFBB-A6662249B3AC}.Release|Any CPU.Build.0 = Release|Any CPU + {54002B08-F6AE-4B2B-AB0C-86E5A05926A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {54002B08-F6AE-4B2B-AB0C-86E5A05926A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {54002B08-F6AE-4B2B-AB0C-86E5A05926A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {54002B08-F6AE-4B2B-AB0C-86E5A05926A3}.Release|Any CPU.Build.0 = Release|Any CPU + {48C29501-3FA2-46A7-B5BA-D282EA8F1274}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {48C29501-3FA2-46A7-B5BA-D282EA8F1274}.Debug|Any CPU.Build.0 = Debug|Any CPU + {48C29501-3FA2-46A7-B5BA-D282EA8F1274}.Release|Any CPU.ActiveCfg = Release|Any CPU + {48C29501-3FA2-46A7-B5BA-D282EA8F1274}.Release|Any CPU.Build.0 = Release|Any CPU {C42868C8-968A-473F-AC39-AC97C5D47E84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C42868C8-968A-473F-AC39-AC97C5D47E84}.Debug|Any CPU.Build.0 = Debug|Any CPU {C42868C8-968A-473F-AC39-AC97C5D47E84}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -641,6 +653,8 @@ Global {EC73B88E-D544-4A6A-90D5-E291035FEA35} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {74EF2C61-9176-4D4E-91D3-E17E28054FF8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {C7215B69-0D77-4D52-AFBB-A6662249B3AC} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {54002B08-F6AE-4B2B-AB0C-86E5A05926A3} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {48C29501-3FA2-46A7-B5BA-D282EA8F1274} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C42868C8-968A-473F-AC39-AC97C5D47E84} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a2403cda2c --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +#nullable enable +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Dispose() -> void +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a2403cda2c --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +#nullable enable +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Dispose() -> void +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a2403cda2c --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +#nullable enable +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Dispose() -> void +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult +static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs new file mode 100644 index 0000000000..702fe6886f --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs @@ -0,0 +1,65 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Threading; + +namespace OpenTelemetry.Sampler.AWS; + +[EventSource(Name = "OpenTelemetry-Sampler-AWS")] +internal class AWSSamplerEventSource : EventSource +{ + public static AWSSamplerEventSource Log = new AWSSamplerEventSource(); + + [Event(1, Message = "Error response from {0} with status code {1}", Level = EventLevel.Warning)] + public void FailedToGetSuccessResponse(string endpoint, string statusCode) + { + this.WriteEvent(1, endpoint, statusCode); + } + + [Event(2, Message = "Exception from AWSXRayRemoteSampler while executing request {0})}", Level = EventLevel.Warning)] + public void ExceptionFromSampler(string message) + { + this.WriteEvent(2, message); + } + + [Event(3, Message = "Failed to deserialize to object in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] + public void FailedToDeserializeResponse(string format, string error) + { + this.WriteEvent(3, format, error); + } + + /// + /// Returns a culture-independent string representation of the given object, + /// appropriate for diagnostics tracing. + /// + private static string ToInvariantString(Exception exception) + { + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + + try + { + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + return exception.ToString(); + } + finally + { + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs new file mode 100644 index 0000000000..676bf5bfe6 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -0,0 +1,84 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Threading; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Sampler.AWS; + +/// +/// Remote sampler that gets sampling configuration from AWS X-Ray. +/// +public sealed class AWSXRayRemoteSampler : Trace.Sampler, IDisposable +{ + internal AWSXRayRemoteSampler(TimeSpan pollingInterval, string endpoint) + { + this.PollingInterval = pollingInterval; + this.Endpoint = endpoint; + this.Client = new AWSXRaySamplerClient(endpoint); + + // execute the first update right away + this.RulePollerTimer = new Timer(this.GetAndUpdateSampler, null, TimeSpan.Zero, this.PollingInterval); + } + + internal TimeSpan PollingInterval { get; } + + internal string Endpoint { get; } + + internal AWSXRaySamplerClient Client { get; } + + internal Timer RulePollerTimer { get; } + + /// + /// Initializes a for the sampler. + /// + /// an instance of . + public static AWSXRayRemoteSamplerBuilder Builder() + { + return new AWSXRayRemoteSamplerBuilder(); + } + + /// + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + // TODO: add the actual functionality for sampling. + throw new System.NotImplementedException(); + } + + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposing) + { + this.RulePollerTimer?.Dispose(); + this.Client?.Dispose(); + } + } + + private async void GetAndUpdateSampler(object? state) + { + await this.Client.GetSamplingRules().ConfigureAwait(false); + + // TODO: more functionality to be added. + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs new file mode 100644 index 0000000000..d5c39224a3 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs @@ -0,0 +1,83 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Sampler.AWS; + +/// +/// A builder for AWSXRayRemoteSampler. +/// +public class AWSXRayRemoteSamplerBuilder +{ + private const string DefaultEndpoint = "http://localhost:2000"; + + private static readonly TimeSpan DefaultPollingInterval = TimeSpan.FromMinutes(5); + + private TimeSpan pollingInterval; + private string endpoint; + + internal AWSXRayRemoteSamplerBuilder() + { + this.pollingInterval = DefaultPollingInterval; + this.endpoint = DefaultEndpoint; + } + + /// + /// Sets the polling interval for configuration updates. If unset, defaults to 5 minutes. + /// Must be positive. + /// + /// the polling interval. + /// the same instance of . + /// if the argument is non-positive. + public AWSXRayRemoteSamplerBuilder SetPollingInterval(TimeSpan pollingInterval) + { + if (pollingInterval < TimeSpan.Zero) + { + throw new ArgumentException("Polling interval must be non-negative."); + } + + this.pollingInterval = pollingInterval; + + return this; + } + + /// + /// Sets the endpoint for the TCP proxy to connect to. This is the address to the port on the + /// OpenTelemetry Collector configured for proxying X-Ray sampling requests.If unset, defaults to + /// . + /// + /// the endpoint for the TCP proxy. + /// the same instance of . + public AWSXRayRemoteSamplerBuilder SetEndpoint(string endpoint) + { + if (!string.IsNullOrEmpty(endpoint)) + { + this.endpoint = endpoint; + } + + return this; + } + + /// + /// Returns a with configuration of this builder. + /// + /// an instance of . + public AWSXRayRemoteSampler Build() + { + return new AWSXRayRemoteSampler(this.pollingInterval, this.endpoint); + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs new file mode 100644 index 0000000000..b4756e14f3 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -0,0 +1,114 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace OpenTelemetry.Sampler.AWS; + +internal class AWSXRaySamplerClient : IDisposable +{ + private readonly string getSamplingRulesEndpoint; + private readonly HttpClient httpClient; + private readonly string jsonContentType = "application/json"; + + public AWSXRaySamplerClient(string host) + { + this.getSamplingRulesEndpoint = host + "/GetSamplingRules"; + this.httpClient = new HttpClient(); + } + + public async Task> GetSamplingRules() + { + List samplingRules = new List(); + + using (var request = new HttpRequestMessage(HttpMethod.Post, this.getSamplingRulesEndpoint) + { + Content = new StringContent(string.Empty, Encoding.UTF8, this.jsonContentType), + }) + { + var responseJson = await this.DoRequestAsync(this.getSamplingRulesEndpoint, request).ConfigureAwait(false); + + try + { + GetSamplingRulesResponse? getSamplingRulesResponse = JsonSerializer.Deserialize(responseJson); + if (getSamplingRulesResponse is not null) + { + if (getSamplingRulesResponse.SamplingRuleRecords is not null) + { + foreach (var samplingRuleRecord in getSamplingRulesResponse.SamplingRuleRecords) + { + if (samplingRuleRecord.SamplingRule is not null) + { + samplingRules.Add(samplingRuleRecord.SamplingRule); + } + } + } + + // TODO: this line here is only for testing. Remove in next more complete iterations. + // Console.WriteLine("Got sampling rules! Count: " + samplingRules.Count); + } + } + catch (Exception ex) + { + AWSSamplerEventSource.Log.FailedToDeserializeResponse( + nameof(AWSXRaySamplerClient.GetSamplingRules), + ex.Message); + } + } + + return samplingRules; + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (disposing) + { + this.httpClient?.Dispose(); + } + } + + private async Task DoRequestAsync(string endpoint, HttpRequestMessage request) + { + try + { + var response = await this.httpClient.SendAsync(request).ConfigureAwait(false); + if (!response.IsSuccessStatusCode) + { + AWSSamplerEventSource.Log.FailedToGetSuccessResponse(endpoint, response.StatusCode.ToString()); + return string.Empty; + } + + var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return responseString; + } + catch (Exception ex) + { + AWSSamplerEventSource.Log.ExceptionFromSampler(ex.Message); + return string.Empty; + } + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs new file mode 100644 index 0000000000..c13fb204d6 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Sampler.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Sampler.AWS.Tests")] +#endif diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md new file mode 100644 index 0000000000..c847e5dc16 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog - OpenTelemetry.Samplers.AWS + +## Unreleased + +Initial release of `OpenTelemetry.Sampler.AWS`. + +* Feature - AWSXRayRemoteSampler - Add support for AWS X-Ray remote sampling + ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091)) diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs new file mode 100644 index 0000000000..2d6234c12a --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class GetSamplingRulesResponse +{ + [JsonPropertyName("NextToken")] + public string? NextToken { get; set; } + + [JsonPropertyName("SamplingRuleRecords")] + public List? SamplingRuleRecords { get; set; } +} diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj new file mode 100644 index 0000000000..ed94f96cc4 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -0,0 +1,24 @@ + + + + net6.0;netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry remote sampler for AWS X-Ray. + Sampler.AWS- + enable + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md new file mode 100644 index 0000000000..f10d151e31 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -0,0 +1,37 @@ +# AWS X-Ray Remote Sampler + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Sampler.AWS.svg)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Sampler.AWS.svg)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) + +This package provides a sampler which can get sampling +configurations from AWS X-Ray to make sampling decisions. +See: [AWS X-Ray Sampling](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-sampling) + +Start with installing the package + +```shell +dotnet add package OpenTelemetry.Sampler.AWS +``` + +You can configure the `AWSXRayRemoteSampler` as per the following example. +Note that you will need to configure your [OpenTelemetry Collector for +X-Ray remote sampling](https://aws-otel.github.io/docs/getting-started/remote-sampling) + +```csharp +using OpenTelemetry; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Trace; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .SetSampler(AWSXRayRemoteSampler.Builder() + .SetPollingInterval(TimeSpan.FromSeconds(10)) + .SetEndpoint("http://localhost:2000") + .Build()) + .Build(); +``` + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) +- [AWS Distro for OpenTelemetry .NET](https://aws-otel.github.io/docs/getting-started/dotnet-sdk) diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs new file mode 100644 index 0000000000..1805951b6f --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs @@ -0,0 +1,94 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class SamplingRule : IComparable +{ + public SamplingRule( + string ruleName, + int priority, + double fixedRate, + int reservoirSize, + string host, + string httpMethod, + string resourceArn, + string serviceName, + string urlPath, + int version, + Dictionary attributes) + { + this.RuleName = ruleName; + this.Priority = priority; + this.FixedRate = fixedRate; + this.ReservoirSize = reservoirSize; + this.Host = host; + this.HttpMethod = httpMethod; + this.ResourceArn = resourceArn; + this.ServiceName = serviceName; + this.UrlPath = urlPath; + this.Version = version; + this.Attributes = attributes; + } + + [JsonPropertyName("RuleName")] + public string RuleName { get; set; } + + [JsonPropertyName("Priority")] + public int Priority { get; set; } + + [JsonPropertyName("FixedRate")] + public double FixedRate { get; set; } + + [JsonPropertyName("ReservoirSize")] + public int ReservoirSize { get; set; } + + [JsonPropertyName("Host")] + public string Host { get; set; } + + [JsonPropertyName("HTTPMethod")] + public string HttpMethod { get; set; } + + [JsonPropertyName("ResourceARN")] + public string ResourceArn { get; set; } + + [JsonPropertyName("ServiceName")] + public string ServiceName { get; set; } + + [JsonPropertyName("URLPath")] + public string UrlPath { get; set; } + + [JsonPropertyName("Version")] + public int Version { get; set; } + + [JsonPropertyName("Attributes")] + public Dictionary? Attributes { get; set; } + + public int CompareTo(SamplingRule? other) + { + int result = this.Priority.CompareTo(other?.Priority); + if (result == 0) + { + result = string.Compare(this.RuleName, other?.RuleName, StringComparison.Ordinal); + } + + return result; + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs new file mode 100644 index 0000000000..0387908054 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class SamplingRuleRecord +{ + [JsonPropertyName("CreatedAt")] + public double CreatedAt { get; set; } + + [JsonPropertyName("ModifiedAt")] + public double ModifiedAt { get; set; } + + [JsonPropertyName("SamplingRule")] + public SamplingRule? SamplingRule { get; set; } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponse.json b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponse.json new file mode 100644 index 0000000000..882ffd329a --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponse.json @@ -0,0 +1,65 @@ +{ + "NextToken": null, + "SamplingRuleRecords": [ + { + "CreatedAt": 1.67799933E9, + "ModifiedAt": 1.67799933E9, + "SamplingRule": { + "Attributes": { + "foo": "bar", + "doo": "baz" + }, + "FixedRate": 0.05, + "HTTPMethod": "*", + "Host": "*", + "Priority": 1000, + "ReservoirSize": 10, + "ResourceARN": "*", + "RuleARN": "arn:aws:xray:us-west-2:123456789000:sampling-rule/Rule1", + "RuleName": "Rule1", + "ServiceName": "*", + "ServiceType": "AWS::Foo::Bar", + "URLPath": "*", + "Version": 1 + } + }, + { + "CreatedAt": 0.0, + "ModifiedAt": 1.611564245E9, + "SamplingRule": { + "Attributes": {}, + "FixedRate": 0.05, + "HTTPMethod": "*", + "Host": "*", + "Priority": 10000, + "ReservoirSize": 1, + "ResourceARN": "*", + "RuleARN": "arn:aws:xray:us-west-2:123456789000:sampling-rule/Default", + "RuleName": "Default", + "ServiceName": "*", + "ServiceType": "*", + "URLPath": "*", + "Version": 1 + } + }, + { + "CreatedAt": 1.676038494E9, + "ModifiedAt": 1.676038494E9, + "SamplingRule": { + "Attributes": {}, + "FixedRate": 0.2, + "HTTPMethod": "GET", + "Host": "*", + "Priority": 1, + "ReservoirSize": 10, + "ResourceARN": "*", + "RuleARN": "arn:aws:xray:us-west-2:123456789000:sampling-rule/Rule2", + "RuleName": "Rule2", + "ServiceName": "FooBar", + "ServiceType": "*", + "URLPath": "/foo/bar", + "Version": 1 + } + } + ] +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj new file mode 100644 index 0000000000..bb8099097e --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -0,0 +1,29 @@ + + + + net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + PreserveNewest + + + + diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs new file mode 100644 index 0000000000..ee63f9ff9a --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -0,0 +1,62 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Sampler.AWS; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +public class TestAWSXRayRemoteSampler +{ + [Fact] + public void TestSamplerWithConfiguration() + { + TimeSpan pollingInterval = TimeSpan.FromSeconds(5); + string endpoint = "http://localhost:3000"; + + AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder() + .SetPollingInterval(pollingInterval) + .SetEndpoint(endpoint) + .Build(); + + Assert.Equal(pollingInterval, sampler.PollingInterval); + Assert.Equal(endpoint, sampler.Endpoint); + Assert.NotNull(sampler.RulePollerTimer); + Assert.NotNull(sampler.Client); + } + + [Fact] + public void TestSamplerWithDefaults() + { + AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder().Build(); + + Assert.Equal(TimeSpan.FromMinutes(5), sampler.PollingInterval); + Assert.Equal("http://localhost:2000", sampler.Endpoint); + Assert.NotNull(sampler.RulePollerTimer); + Assert.NotNull(sampler.Client); + } + + [Fact] + public void TestSamplerShouldSample() + { + Trace.Sampler sampler = AWSXRayRemoteSampler.Builder().Build(); + + // TODO: update the test when the method is implemented. + Assert.Throws(() => sampler.ShouldSample(default(SamplingParameters))); + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs new file mode 100644 index 0000000000..cf2330c282 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -0,0 +1,121 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.IO; +using OpenTelemetry.Sampler.AWS; +using WireMock.RequestBuilders; +using WireMock.ResponseBuilders; +using WireMock.Server; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +public class TestAWSXRaySamplerClient : IDisposable +{ + private WireMockServer mockServer; + + private AWSXRaySamplerClient client; + + public TestAWSXRaySamplerClient() + { + this.mockServer = WireMockServer.Start(); + this.client = new AWSXRaySamplerClient(this.mockServer.Url); + } + + public void Dispose() + { + this.mockServer.Dispose(); + this.client.Dispose(); + } + + [Fact] + public void TestGetSamplingRules() + { + this.CreateResponse("/GetSamplingRules", "Data/GetSamplingRulesResponse.json"); + + var responseTask = this.client.GetSamplingRules(); + responseTask.Wait(); + + List rules = responseTask.Result; + + Assert.Equal(3, rules.Count); + + Assert.Equal("Rule1", rules[0].RuleName); + Assert.Equal(1000, rules[0].Priority); + Assert.Equal(0.05, rules[0].FixedRate); + Assert.Equal(10, rules[0].ReservoirSize); + Assert.Equal("*", rules[0].Host); + Assert.Equal("*", rules[0].HttpMethod); + Assert.Equal("*", rules[0].ResourceArn); + Assert.Equal("*", rules[0].ServiceName); + Assert.Equal("*", rules[0].UrlPath); + Assert.Equal(1, rules[0].Version); + Assert.Equal(2, rules[0].Attributes.Count); + Assert.Equal("bar", rules[0].Attributes["foo"]); + Assert.Equal("baz", rules[0].Attributes["doo"]); + + Assert.Equal("Default", rules[1].RuleName); + Assert.Equal(10000, rules[1].Priority); + Assert.Equal(0.05, rules[1].FixedRate); + Assert.Equal(1, rules[1].ReservoirSize); + Assert.Equal("*", rules[1].Host); + Assert.Equal("*", rules[1].HttpMethod); + Assert.Equal("*", rules[1].ResourceArn); + Assert.Equal("*", rules[1].ServiceName); + Assert.Equal("*", rules[1].UrlPath); + Assert.Equal(1, rules[1].Version); + Assert.Empty(rules[1].Attributes); + + Assert.Equal("Rule2", rules[2].RuleName); + Assert.Equal(1, rules[2].Priority); + Assert.Equal(0.2, rules[2].FixedRate); + Assert.Equal(10, rules[2].ReservoirSize); + Assert.Equal("*", rules[2].Host); + Assert.Equal("GET", rules[2].HttpMethod); + Assert.Equal("*", rules[2].ResourceArn); + Assert.Equal("FooBar", rules[2].ServiceName); + Assert.Equal("/foo/bar", rules[2].UrlPath); + Assert.Equal(1, rules[2].Version); + Assert.Empty(rules[2].Attributes); + } + + [Fact] + public void TestGetSamplingRulesMalformed() + { + this.mockServer + .Given(Request.Create().WithPath("/GetSamplingRules").UsingPost()) + .RespondWith( + Response.Create().WithStatusCode(200).WithHeader("Content-Type", "application/json").WithBody("notJson")); + + var responseTask = this.client.GetSamplingRules(); + responseTask.Wait(); + + List rules = responseTask.Result; + + Assert.Empty(rules); + } + + private void CreateResponse(string endpoint, string filePath) + { + string mockResponse = File.ReadAllText(filePath); + this.mockServer + .Given(Request.Create().WithPath(endpoint).UsingPost()) + .RespondWith( + Response.Create().WithStatusCode(200).WithHeader("Content-Type", "application/json").WithBody(mockResponse)); + } +} From d99d1d3c99da586b110a7c53b52e686762fd82e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 29 Mar 2023 00:26:30 +0200 Subject: [PATCH 0651/1499] [Extensions.AWSXRay] Update Moq (#1114) --- .../OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index 68fa51593c..b1b26be408 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers From 8601d62b9157f9903679c7d2c6e6fc56747ddaf9 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 28 Mar 2023 18:31:44 -0700 Subject: [PATCH 0652/1499] [Exporter.Geneva] Add support for exporting metrics to different combinations of account and namespace (#1111) --- .../CHANGELOG.md | 14 + .../Metrics/GenevaMetricExporter.cs | 247 ++++++++----- .../Metrics/GenevaMetricExporterOptions.cs | 6 + .../GenevaMetricExporterTests.cs | 330 +++++++++++++++++- 4 files changed, 497 insertions(+), 100 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 84dfece69b..e52f423ed0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,10 +2,24 @@ ## Unreleased +* Fix a bug where metrics without exemplars were not getting exported. + ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1099)) + * Relaxed table name mapping validation rules to restore the previous behavior from version 1.3.0. ([#1109](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1109)) +* Add support for exporting metrics to more than a single account/namespace + combination using a single GenevaMetricExporter instance. Users can now export + individual metric streams to: + * An account of their choice by adding the dimension + `_microsoft_metrics_account` and providing a `string` value for it as the + account name. + * A metric namespace of their choice by adding the dimension + `_microsoft_metrics_namespace` and providing a `string` value for it as the + namespace name. + ([#1111](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1111)) + ## 1.5.0-alpha.1 Released 2023-Mar-13 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 72819a4f56..a9cafcfbb5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -35,13 +35,13 @@ public class GenevaMetricExporter : BaseExporter internal const int MaxDimensionValueSize = 1024; - private readonly ushort prepopulatedDimensionsCount; + internal const string DimensionKeyForCustomMonitoringAccount = "_microsoft_metrics_account"; - private readonly int fixedPayloadStartIndex; + internal const string DimensionKeyForCustomMetricsNamespace = "_microsoft_metrics_namespace"; - private readonly string monitoringAccount; + private readonly ushort prepopulatedDimensionsCount; - private readonly string metricNamespace; + private readonly int fixedPayloadStartIndex; private readonly IMetricDataTransport metricDataTransport; @@ -59,6 +59,10 @@ public class GenevaMetricExporter : BaseExporter private readonly int bufferIndexForHistogramMetrics; + private readonly string defaultMonitoringAccount; + + private readonly string defaultMetricNamespace; + private bool isDisposed; public GenevaMetricExporter(GenevaMetricExporterOptions options) @@ -67,8 +71,8 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) Guard.ThrowIfNullOrWhitespace(options.ConnectionString); var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - this.monitoringAccount = connectionStringBuilder.Account; - this.metricNamespace = connectionStringBuilder.Namespace; + this.defaultMonitoringAccount = connectionStringBuilder.Account; + this.defaultMetricNamespace = connectionStringBuilder.Namespace; if (options.PrepopulatedMetricDimensions != null) { @@ -119,6 +123,9 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) public override ExportResult Export(in Batch batch) { + string monitoringAccount = this.defaultMonitoringAccount; + string metricNamespace = this.defaultMetricNamespace; + var result = ExportResult.Success; foreach (var metric in batch) { @@ -140,7 +147,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp metricPoint.Tags, metricData, - exemplars); + exemplars, + out monitoringAccount, + out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -158,7 +167,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out monitoringAccount, + out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -176,7 +187,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out monitoringAccount, + out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -192,7 +205,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out monitoringAccount, + out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -207,7 +222,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out monitoringAccount, + out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -231,7 +248,9 @@ public override ExportResult Export(in Batch batch) count, min, max, - exemplars); + exemplars, + out monitoringAccount, + out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } @@ -239,7 +258,7 @@ public override ExportResult Export(in Batch batch) } catch (Exception ex) { - ExporterEventSource.Log.FailedToSendMetricData(this.monitoringAccount, this.metricNamespace, metric.Name, ex); // TODO: preallocate exception or no exception + ExporterEventSource.Log.FailedToSendMetricData(monitoringAccount, metricNamespace, metric.Name, ex); // TODO: preallocate exception or no exception result = ExportResult.Failure; } } @@ -496,7 +515,9 @@ internal unsafe ushort SerializeMetricWithTLV( long timestamp, in ReadOnlyTagCollection tags, MetricData value, - Exemplar[] exemplars) + Exemplar[] exemplars, + out string monitoringAccount, + out string metricNamespace) { ushort bodyLength; try @@ -512,13 +533,20 @@ internal unsafe ushort SerializeMetricWithTLV( SerializeNonHistogramMetricData(eventType, value, timestamp, this.buffer, ref bufferIndex); - SerializeMetricDimensions(tags, this.prepopulatedDimensionsCount, this.serializedPrepopulatedDimensionsKeys, this.serializedPrepopulatedDimensionsValues, this.buffer, ref bufferIndex); + // Serializes metric dimensions and also gets the custom account name and metric namespace + // if specified by adding custom tags: _microsoft_metrics_namespace and _microsoft_metrics_namespace + this.SerializeDimensionsAndGetCustomAccountNamespace( + tags, + this.buffer, + ref bufferIndex, + out monitoringAccount, + out metricNamespace); SerializeExemplars(exemplars, this.buffer, ref bufferIndex); - SerializeMonitoringAccount(this.monitoringAccount, this.buffer, ref bufferIndex); + SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); - SerializeMetricNamespace(this.metricNamespace, this.buffer, ref bufferIndex); + SerializeMetricNamespace(metricNamespace, this.buffer, ref bufferIndex); // Write the final size of the payload bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); @@ -547,7 +575,9 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( uint count, double min, double max, - Exemplar[] exemplars) + Exemplar[] exemplars, + out string monitoringAccount, + out string metricNamespace) { ushort bodyLength; try @@ -563,13 +593,20 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( SerializeHistogramMetricData(buckets, sum, count, min, max, timestamp, this.buffer, ref bufferIndex); - SerializeMetricDimensions(tags, this.prepopulatedDimensionsCount, this.serializedPrepopulatedDimensionsKeys, this.serializedPrepopulatedDimensionsValues, this.buffer, ref bufferIndex); + // Serializes metric dimensions and also gets the custom account name and metric namespace + // if specified by adding custom tags: _microsoft_metrics_namespace and _microsoft_metrics_namespace + this.SerializeDimensionsAndGetCustomAccountNamespace( + tags, + this.buffer, + ref bufferIndex, + out monitoringAccount, + out metricNamespace); SerializeExemplars(exemplars, this.buffer, ref bufferIndex); - SerializeMonitoringAccount(this.monitoringAccount, this.buffer, ref bufferIndex); + SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); - SerializeMetricNamespace(this.metricNamespace, this.buffer, ref bufferIndex); + SerializeMetricNamespace(metricNamespace, this.buffer, ref bufferIndex); // Write the final size of the payload bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); @@ -610,70 +647,6 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(monitoringAccount)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeMetricDimensions(in ReadOnlyTagCollection tags, ushort prepopulatedDimensionsCount, List serializedPrepopulatedDimensionsKeys, List serializedPrepopulatedDimensionsValues, byte[] buffer, ref int bufferIndex) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Dimensions); - - // Get a placeholder to add the payloadType length - var payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - // Get a placeholder to add dimensions count later - var bufferIndexForDimensionsCount = bufferIndex; - bufferIndex += 2; - - ushort dimensionsWritten = 0; - - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, serializedPrepopulatedDimensionsKeys[i]); - } - - if (prepopulatedDimensionsCount > 0) - { - dimensionsWritten += prepopulatedDimensionsCount; - } - - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(buffer, ref bufferIndex, tag.Key); - } - - dimensionsWritten += (ushort)tags.Count; - - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, serializedPrepopulatedDimensionsValues[i]); - } - - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(buffer, ref bufferIndex, dimensionValue); - } - - // Backfill the number of dimensions written - MetricSerializer.SerializeUInt16(buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); - - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) { @@ -885,6 +858,102 @@ private static void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, b MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagCollection tags, byte[] buffer, ref int bufferIndex, out string monitoringAccount, out string metricNamespace) + { + monitoringAccount = this.defaultMonitoringAccount; + metricNamespace = this.defaultMetricNamespace; + + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Dimensions); + + // Get a placeholder to add the payloadType length + var payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add dimensions count later + var bufferIndexForDimensionsCount = bufferIndex; + bufferIndex += 2; + + ushort dimensionsWritten = 0; + + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + int reservedTags = 0; + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > MaxDimensionNameSize) + { + // TODO: Data Validation + } + + if (tag.Key.Equals(DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) || + tag.Key.Equals(DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase)) + { + reservedTags++; + continue; + } + + MetricSerializer.SerializeString(buffer, ref bufferIndex, tag.Key); + } + + dimensionsWritten += (ushort)(tags.Count - reservedTags); + + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } + + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + if (tag.Key.Equals(DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsAccount) + { + if (!string.IsNullOrWhiteSpace(metricsAccount)) + { + monitoringAccount = metricsAccount; + } + + continue; + } + + if (tag.Key.Equals(DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsNamespace) + { + if (!string.IsNullOrWhiteSpace(metricsNamespace)) + { + metricNamespace = metricsNamespace; + } + + continue; + } + + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > MaxDimensionValueSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(buffer, ref bufferIndex, dimensionValue); + } + + // Backfill the number of dimensions written + MetricSerializer.SerializeUInt16(buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) { @@ -934,8 +1003,8 @@ private unsafe int InitializeBufferForNonHistogramMetrics() // Leave enough space for the header and fixed payload var bufferIndex = sizeof(BinaryHeader) + sizeof(MetricPayload); - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.monitoringAccount); - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.metricNamespace); + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.defaultMonitoringAccount); + MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.defaultMetricNamespace); return bufferIndex; } @@ -950,8 +1019,8 @@ private unsafe int InitializeBufferForHistogramMetrics() // Leave enough space for the header and fixed payload var bufferIndex = sizeof(BinaryHeader) + sizeof(ExternalPayload); - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.monitoringAccount); - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.metricNamespace); + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.defaultMonitoringAccount); + MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.defaultMetricNamespace); return bufferIndex; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index 6488e894f8..2132e5ef95 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -68,6 +68,12 @@ public IReadOnlyDictionary PrepopulatedMetricDimensions foreach (var entry in value) { + if (entry.Key.Equals(GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) || + entry.Key.Equals(GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase)) + { + throw new ArgumentException($"The dimension: {entry.Key} is reserved and cannot be used as a prepopulated dimension."); + } + if (entry.Key.Length > GenevaMetricExporter.MaxDimensionNameSize) { throw new ArgumentException($"The dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 56bb3892eb..1bc4d76708 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -77,8 +77,8 @@ public void ParseConnectionStringCorrectly() } using var exporter = new GenevaMetricExporter(exporterOptions); - var monitoringAccount = typeof(GenevaMetricExporter).GetField("monitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; - var metricNamespace = typeof(GenevaMetricExporter).GetField("metricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + var monitoringAccount = typeof(GenevaMetricExporter).GetField("defaultMonitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + var metricNamespace = typeof(GenevaMetricExporter).GetField("defaultMetricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; Assert.Equal("OTelMonitoringAccount", monitoringAccount); Assert.Equal("OTelMetricNamespace", metricNamespace); } @@ -95,6 +95,33 @@ public void ParseConnectionStringCorrectly() } } + [Fact] + public void CannotUseReservedDimensionsInPrepopulatedFields() + { + var exporterOptions = new GenevaMetricExporterOptions(); + var prepopulatedMetricDimensions = new Dictionary + { + ["_microsoft_metrics_account"] = "MetricsAccount", + }; + + Assert.Throws(() => { exporterOptions.PrepopulatedMetricDimensions = prepopulatedMetricDimensions; }); + + prepopulatedMetricDimensions = new Dictionary + { + ["_microsoft_metrics_namespace"] = "MetricsNamespace", + }; + + Assert.Throws(() => { exporterOptions.PrepopulatedMetricDimensions = prepopulatedMetricDimensions; }); + + prepopulatedMetricDimensions = new Dictionary + { + ["_microsoft_metrics_account"] = "MetricsAccount", + ["_microsoft_metrics_namespace"] = "MetricsNamespace", + }; + + Assert.Throws(() => { exporterOptions.PrepopulatedMetricDimensions = prepopulatedMetricDimensions; }); + } + [Theory] [InlineData(false)] [InlineData(true)] @@ -578,7 +605,9 @@ public void SuccessfulExportOnLinux() metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out _, + out _); // Wait a little more than the ExportInterval for the exporter to export the data. Task.Delay(5500).Wait(); @@ -1130,6 +1159,124 @@ public void SuccessfulSerializationWithTLVWithViews() } } + [Fact] + public void SuccessfulSerializationWithCustomAccountAndNamespace() + { + using var meter = new Meter("SuccessfulSerializationWithCustomAccountAndNamespace", "0.0.1"); + var longCounter = meter.CreateCounter("longCounter"); + var doubleCounter = meter.CreateCounter("doubleCounter"); + var histogram = meter.CreateHistogram("histogram"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulSerializationWithCustomAccountAndNamespace") + .AddReader(inMemoryReader) + .Build(); + + long longValue = 123; + double doubleValue = 123.45; + + longCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForLongCounter")); + + doubleCounter.Add( + doubleValue, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_namespace", "NamespaceForDoubleCounter")); + + // Record the following values from Histogram: + // (-inf - 0] : 1 + // (0 - 5] : 0 + // (5 - 10] : 0 + // (10 - 25] : 0 + // (25 - 50] : 0 + // (50 - 75] : 0 + // (75 - 100] : 0 + // (100 - 250] : 2 + // (250 - 500] : 0 + // (500 - 1000] : 1 + // (1000 - +inf) : 1 + // + // The corresponding value-count pairs to be sent for the given distribution: + // 0: 1 + // 250: 2 + // 1000: 1 + // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) + + histogram.Record(0, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); + histogram.Record(150, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); + histogram.Record(750, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); + histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); + + string path = string.Empty; + Socket server = null; + try + { + var exporterOptions = new GenevaMetricExporterOptions(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + exporterOptions.PrepopulatedMetricDimensions = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + + using var exporter = new GenevaMetricExporter(exporterOptions); + + inMemoryReader.Collect(); + + Assert.Equal(3, exportedItems.Count); + + // check serialization for longCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); + var data = GetSerializedData(exportedItems[0], exporter); + var fields = data.Fields; + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == "AccountForLongCounter"); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == "OTelMetricNamespace"); + + // check serialization for doubleCounter + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); + data = GetSerializedData(exportedItems[1], exporter); + fields = data.Fields; + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == "OTelMonitoringAccount"); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == "NamespaceForDoubleCounter"); + + // check serialization for histogram + CheckSerializationWithTLVForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); + data = GetSerializedData(exportedItems[2], exporter); + fields = data.Fields; + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == "AccountForHistogram"); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == "NamespaceForHistogram"); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + private static string GenerateTempFilePath() { while (true) @@ -1371,7 +1518,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out _, + out _); var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); @@ -1395,7 +1544,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out _, + out _); var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); @@ -1421,7 +1572,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out _, + out _); var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); @@ -1447,7 +1600,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars); + exemplars, + out _, + out _); var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); @@ -1480,7 +1635,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, count, min, max, - exemplars); + exemplars, + out _, + out _); var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); @@ -1541,9 +1698,31 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); + + string monitoringAccount = connectionStringBuilder.Account; + string metricNamespace = connectionStringBuilder.Namespace; + + foreach (var tag in metricPoint.Tags) + { + if (tag.Key.Equals("_microsoft_metrics_account", StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsAccount) + { + if (!string.IsNullOrWhiteSpace(metricsAccount)) + { + monitoringAccount = metricsAccount; + } + } + else if (tag.Key.Equals("_microsoft_metrics_namespace", StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsNamespace) + { + if (!string.IsNullOrWhiteSpace(metricsNamespace)) + { + metricNamespace = metricsNamespace; + } + } + } + Assert.Contains(fields, field => field.Type == PayloadTypes.MetricName && (field.Value as WrappedString).Value == metric.Name); - Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == connectionStringBuilder.Account); - Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == connectionStringBuilder.Namespace); + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == monitoringAccount); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == metricNamespace); // Check dimensions var dimensions = fields.FirstOrDefault(field => field.Type == PayloadTypes.Dimensions).Value as Dimensions; @@ -1568,14 +1747,22 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, index++; } + int reservedTags = 0; foreach (var tag in metricPoint.Tags) { + if (tag.Key.Equals("_microsoft_metrics_account", StringComparison.OrdinalIgnoreCase) || + tag.Key.Equals("_microsoft_metrics_namespace", StringComparison.OrdinalIgnoreCase)) + { + reservedTags++; + continue; + } + Assert.Equal(tag.Key, dimensions.DimensionsNames[index].Value); Assert.Equal(tag.Value, dimensions.DimensionsValues[index].Value); index++; } - dimensionsCount += metricPoint.Tags.Count; + dimensionsCount += (ushort)(metricPoint.Tags.Count - reservedTags); Assert.Equal(dimensionsCount, dimensions.NumDimensions); } @@ -1629,4 +1816,125 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem } } } + + private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter exporter) + { + var metricType = metric.MetricType; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var exemplars = metricPoint.GetExemplars(); + UserdataV2 result = null; + + if (metricType == MetricType.LongSum) + { + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + _ = exporter.SerializeMetricWithTLV( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars, + out _, + out _); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + result = data.Body as UserdataV2; + } + else if (metricType == MetricType.LongGauge) + { + var metricDataValue = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + _ = exporter.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars, + out _, + out _); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + result = data.Body as UserdataV2; + } + else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + { + var metricDataValue = metricType == MetricType.DoubleSum ? + metricPoint.GetSumDouble() : + metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = metricDataValue }; + _ = exporter.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars, + out _, + out _); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + result = data.Body as UserdataV2; + } + else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) + { + var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? + Convert.ToDouble(metricPoint.GetSumLong()) : + Convert.ToDouble(metricPoint.GetSumDouble()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + _ = exporter.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + exemplars, + out _, + out _); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + result = data.Body as UserdataV2; + } + else if (metricType == MetricType.Histogram) + { + var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + min = 0; + max = 0; + } + + _ = exporter.SerializeHistogramMetricWithTLV( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count, + min, + max, + exemplars, + out _, + out _); + + var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + var data = new MetricsContract(stream); + result = data.Body as UserdataV2; + } + + return result; + } } From 131b1496cd492084dfaefefe6f73a45b43f47819 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Tue, 28 Mar 2023 21:08:47 -0700 Subject: [PATCH 0653/1499] [Exporter.Geneva][TldTraceExporter] Fix serialization bug (#1115) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ .../TLDExporter/TldTraceExporter.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index e52f423ed0..b0393e7ea0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -20,6 +20,9 @@ namespace name. ([#1111](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1111)) +* Fix a bug in TldTraceExporter for incorrect serialization of special tags. + ([#1115](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1115)) + ## 1.5.0-alpha.1 Released 2023-Mar-13 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index 8a23115b4a..4c482cf890 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -260,7 +260,7 @@ internal void SerializeActivity(Activity activity) // TODO: check name collision if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) { - Serialize(eb, entry.Key, replacementKey); + Serialize(eb, replacementKey, entry.Value); partBFieldsCount++; } else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) From bc7fd36366e630c0aaef436b3fb12ecbdec7bace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 29 Mar 2023 18:10:22 +0200 Subject: [PATCH 0654/1499] Issue Templates - lowercase labels (#1118) --- ...instrumentation_AspNet.md => comp_instrumentation_aspnet.md} | 2 +- ...le.md => comp_instrumentation_aspnet.telemetryhttpmodule.md} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename .github/ISSUE_TEMPLATE/{comp_instrumentation_AspNet.md => comp_instrumentation_aspnet.md} (96%) rename .github/ISSUE_TEMPLATE/{comp_instrumentation_AspNet.TelemetryHttpModule.md => comp_instrumentation_aspnet.telemetryhttpmodule.md} (95%) diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md similarity index 96% rename from .github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md rename to .github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md index 80efb79cd1..9942824b40 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md @@ -1,7 +1,7 @@ --- name: OpenTelemetry.Instrumentation.AspNet about: Issue with OpenTelemetry.Instrumentation.AspNet -labels: comp:instrumentation.AspNet +labels: comp:instrumentation.aspnet --- # Issue with OpenTelemetry.Instrumentation.AspNet diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md similarity index 95% rename from .github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md rename to .github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md index 150414bf0a..d9cefb6957 100644 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_AspNet.TelemetryHttpModule.md +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md @@ -1,7 +1,7 @@ --- name: OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule about: Issue with OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule -labels: comp:instrumentation.AspNet.TelemetryHttpModule +labels: comp:instrumentation.aspnet.telemetryhttpmodule --- # Issue with OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule From a1e612550caf94074d83e759f137b869d016fc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 29 Mar 2023 22:57:00 +0200 Subject: [PATCH 0655/1499] Bump test dependencies (#1116) --- build/Common.nonprod.props | 9 ++++----- build/Common.props | 2 +- build/process-codecoverage.ps1 | 2 +- ...penTelemetry.Contrib.Instrumentation.AWS.Tests.csproj | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index a8ec7107cb..528ff99e26 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -24,14 +24,13 @@ [3.2.0,4.0.0) [2.3.1,3.0) [5.0.0,7.0) - [17.3.2,18.0) - [4.18.3,5.0) - [4.17.2,5.0) + [17.5.0,18.0) + [4.18.4,5.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) - [2.4.3,3.0) + [2.4.5,3.0) [2.4.2,3.0) - [1.5.20,2.0) + [1.5.21,2.0) diff --git a/build/Common.props b/build/Common.props index 49b7ac1f3f..fd517f699f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -27,7 +27,7 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [4.2.0,5.0) - [17.3.2] + [17.5.0] [2.1.0,5.0) [3.1.0,) [1.0.3,2.0) diff --git a/build/process-codecoverage.ps1 b/build/process-codecoverage.ps1 index f2df16b80c..ff0bdf6d8f 100644 --- a/build/process-codecoverage.ps1 +++ b/build/process-codecoverage.ps1 @@ -6,7 +6,7 @@ $files = Get-ChildItem "TestResults" -Filter "*.coverage" -Recurse Write-Host $env:USERPROFILE foreach ($file in $files) { - $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\' + $microsoftCodeCoveragePkgVer + '\build\netstandard1.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName + $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\' + $microsoftCodeCoveragePkgVer + '\build\netstandard2.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName Write-Host $command Invoke-Expression $command } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 8df48f35a5..3a88d8a22a 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -14,7 +14,7 @@ - + all runtime; build; native; contentfiles; analyzers From 8e0b8bdc984aaa886e0e0c6f525617a4a00e77d0 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 29 Mar 2023 14:57:39 -0700 Subject: [PATCH 0656/1499] [Exporter.Geneva] Update CHANGELOG for 1.5.0-alpha.2 version (#1121) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index b0393e7ea0..e66996a40a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,12 +2,16 @@ ## Unreleased +## 1.5.0-alpha.2 + +Released 2023-Mar-29 + * Fix a bug where metrics without exemplars were not getting exported. ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1099)) * Relaxed table name mapping validation rules to restore the previous behavior - from version 1.3.0. - ([#1109](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1109)) + from version 1.3.0. ([Issue + #1105](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1105)) * Add support for exporting metrics to more than a single account/namespace combination using a single GenevaMetricExporter instance. Users can now export @@ -16,8 +20,8 @@ `_microsoft_metrics_account` and providing a `string` value for it as the account name. * A metric namespace of their choice by adding the dimension - `_microsoft_metrics_namespace` and providing a `string` value for it as the - namespace name. + `_microsoft_metrics_namespace` and providing a `string` value for it as the + namespace name. ([#1111](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1111)) * Fix a bug in TldTraceExporter for incorrect serialization of special tags. From bf9089aef56308f14e623fe5dcbde3089ce518c3 Mon Sep 17 00:00:00 2001 From: Soheil Alizadeh Date: Thu, 30 Mar 2023 09:01:00 +0200 Subject: [PATCH 0657/1499] [Instrumentation.Cassandra] Release 1.0.0-beta.1 (#1119) --- src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 63bfc986bd..d3add35586 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,4 +2,8 @@ ## Unreleased -Initial release. +## 1.0.0-beta.1 + +Released 2023-Mar-30 + +- Initial release From 57adc16022cf23ee34e52586e4ae3ec0836bf6e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 30 Mar 2023 20:13:10 +0200 Subject: [PATCH 0658/1499] [ResourceDetectors.Container] Rename Container package (#1123) --- ...md => comp_resourcedetectors_container.md} | 8 +- .github/component_owners.yml | 8 +- ...> package-ResourceDetectors.Container.yml} | 6 +- opentelemetry-dotnet-contrib.sln | 13 +-- .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 - .../netstandard2.0/PublicAPI.Unshipped.txt | 3 - .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 + .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 3 + .../AssemblyInfo.cs | 4 +- .../CHANGELOG.md | 13 +++ .../ContainerExtensionsEventSource.cs} | 10 +-- .../ContainerResourceDetector.cs} | 28 +++---- .../ContainerSemanticConventions.cs} | 8 +- ...emetry.ResourceDetectors.Container.csproj} | 4 +- .../README.md | 18 ++-- .../Utils/EncodingUtils.cs | 6 +- .../ContainerResourceDetectorTests.cs} | 83 +++++++++---------- ....ResourceDetectors.Container.Tests.csproj} | 8 +- .../TempFile.cs | 20 ++--- 21 files changed, 130 insertions(+), 119 deletions(-) rename .github/ISSUE_TEMPLATE/{comp_extensions_docker.md => comp_resourcedetectors_container.md} (82%) rename .github/workflows/{package-Extensions.Docker.yml => package-ResourceDetectors.Container.yml} (91%) delete mode 100644 src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.Docker => OpenTelemetry.ResourceDetectors.Container}/.publicApi/net462/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.Docker => OpenTelemetry.ResourceDetectors.Container}/.publicApi/netstandard2.0/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.Docker => OpenTelemetry.ResourceDetectors.Container}/AssemblyInfo.cs (60%) rename src/{OpenTelemetry.Extensions.Docker => OpenTelemetry.ResourceDetectors.Container}/CHANGELOG.md (51%) rename src/{OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs => OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs} (84%) rename src/{OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs => OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs} (84%) rename src/{OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs => OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs} (70%) rename src/{OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj => OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj} (80%) rename src/{OpenTelemetry.Extensions.Docker => OpenTelemetry.ResourceDetectors.Container}/README.md (54%) rename src/{OpenTelemetry.Extensions.Docker => OpenTelemetry.ResourceDetectors.Container}/Utils/EncodingUtils.cs (89%) rename test/{OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs => OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs} (70%) rename test/{OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj => OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj} (76%) rename test/{OpenTelemetry.Extensions.Docker.Tests/Resources => OpenTelemetry.ResourceDetectors.Container.Tests}/TempFile.cs (71%) diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_docker.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md similarity index 82% rename from .github/ISSUE_TEMPLATE/comp_extensions_docker.md rename to .github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md index bb88ba26f2..2a2d04bd8e 100644 --- a/.github/ISSUE_TEMPLATE/comp_extensions_docker.md +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md @@ -1,10 +1,10 @@ --- -name: OpenTelemetry.Extensions.Docker -about: Issue with OpenTelemetry.Extensions.Docker -labels: comp:extensions.docker +name: OpenTelemetry.ResourceDetectors.Container +about: Issue with OpenTelemetry.ResourceDetectors.Container +labels: comp:resourcedetectors.container --- -# Issue with OpenTelemetry.Extensions.Docker +# Issue with OpenTelemetry.ResourceDetectors.Container List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are diff --git a/.github/component_owners.yml b/.github/component_owners.yml index f7b647ef1a..acf4632141 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -27,8 +27,6 @@ components: src/OpenTelemetry.Extensions.AzureMonitor/: - rajkumar-rangaraj - vishweshbankwar - src/OpenTelemetry.Extensions.Docker/: - - iskiselev src/OpenTelemetry.Extensions.Enrichment/: - xakep139 src/OpenTelemetry.PersistentStorage.Abstractions/: @@ -65,6 +63,8 @@ components: src/OpenTelemetry.ResourceDetectors.Azure/: - rajkumar-rangaraj - vishweshbankwar + src/OpenTelemetry.ResourceDetectors.Container/: + - iskiselev src/OpenTelemetry.Sampler.AWS/: - srprash test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: @@ -108,8 +108,6 @@ components: test/OpenTelemetry.Extensions.AzureMonitor.Tests/: - rajkumar-rangaraj - vishweshbankwar - test/OpenTelemetry.Extensions.Docker.Tests/: - - iskiselev test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: @@ -142,5 +140,7 @@ components: test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - rajkumar-rangaraj - vishweshbankwar + test/OpenTelemetry.ResourceDetectors.Container.Tests/: + - iskiselev test/OpenTelemetry.Sampler.AWS.Tests/: - srprash diff --git a/.github/workflows/package-Extensions.Docker.yml b/.github/workflows/package-ResourceDetectors.Container.yml similarity index 91% rename from .github/workflows/package-Extensions.Docker.yml rename to .github/workflows/package-ResourceDetectors.Container.yml index cdb3390e4c..ee307b95f5 100644 --- a/.github/workflows/package-Extensions.Docker.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Extensions.Docker +name: Pack OpenTelemetry.ResourceDetectors.Container on: workflow_dispatch: @@ -9,7 +9,7 @@ on: default: 'warning' push: tags: - - 'Extensions.Docker-*' # trigger when we create a tag with prefix "Extensions.Docker-" + - 'ResourceDetectors.Container-*' # trigger when we create a tag with prefix "ResourceDetectors.Container-" jobs: build-test-pack: @@ -17,7 +17,7 @@ jobs: permissions: contents: write env: - PROJECT: OpenTelemetry.Extensions.Docker + PROJECT: OpenTelemetry.ResourceDetectors.Container strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a1c0b69b94..d03f11d7c4 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -177,9 +177,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Tests", "test\OpenTelemetry.Extensions.Tests\OpenTelemetry.Extensions.Tests.csproj", "{2117F4E3-6612-4E4D-A757-27271EEB7783}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Docker", "src\OpenTelemetry.Extensions.Docker\OpenTelemetry.Extensions.Docker.csproj", "{498A6808-C0DF-441F-A764-51A3BC4B8FC5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Container", "src\OpenTelemetry.ResourceDetectors.Container\OpenTelemetry.ResourceDetectors.Container.csproj", "{498A6808-C0DF-441F-A764-51A3BC4B8FC5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Docker.Tests", "test\OpenTelemetry.Extensions.Docker.Tests\OpenTelemetry.Extensions.Docker.Tests.csproj", "{FB41E19E-2682-4D07-BA59-FD5205AFA71E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Container.Tests", "test\OpenTelemetry.ResourceDetectors.Container.Tests\OpenTelemetry.ResourceDetectors.Container.Tests.csproj", "{FB41E19E-2682-4D07-BA59-FD5205AFA71E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva", "src\OpenTelemetry.Exporter.Geneva\OpenTelemetry.Exporter.Geneva.csproj", "{1105C814-31DA-4214-BEA8-6DB5FC12C808}" EndProject @@ -235,9 +235,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "process-instrumentation", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.EventCounters", "examples\event-counters\Examples.EventCounters\Examples.EventCounters.csproj", "{BA58CC8B-F5CA-4DC7-A3A8-D01B2E10731E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.Cassandra", "src\OpenTelemetry.Instrumentation.Cassandra\OpenTelemetry.Instrumentation.Cassandra.csproj", "{3313F7DF-E3A5-4A7F-965D-86807A017131}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Cassandra", "src\OpenTelemetry.Instrumentation.Cassandra\OpenTelemetry.Instrumentation.Cassandra.csproj", "{3313F7DF-E3A5-4A7F-965D-86807A017131}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Cassandra.Tests", "test\OpenTelemetry.Instrumentation.Cassandra.Tests\OpenTelemetry.Instrumentation.Cassandra.Tests.csproj", "{FB48DC44-8C56-4329-9988-AEDF931E81E8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.Cassandra.Tests", "test\OpenTelemetry.Instrumentation.Cassandra.Tests\OpenTelemetry.Instrumentation.Cassandra.Tests.csproj", "{FB48DC44-8C56-4329-9988-AEDF931E81E8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure", "src\OpenTelemetry.ResourceDetectors.Azure\OpenTelemetry.ResourceDetectors.Azure.csproj", "{B07DC3CB-F724-40A5-889A-DA6601F462F3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure.Tests", "test\OpenTelemetry.ResourceDetectors.Azure.Tests\OpenTelemetry.ResourceDetectors.Azure.Tests.csproj", "{DFC6A4A9-5262-4507-B747-CC6B814205E6}" @@ -256,9 +257,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentSto EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.FileSystem.Tests", "test\OpenTelemetry.PersistentStorage.FileSystem.Tests\OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj", "{C7215B69-0D77-4D52-AFBB-A6662249B3AC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Sampler.AWS", "src\OpenTelemetry.Sampler.AWS\OpenTelemetry.Sampler.AWS.csproj", "{54002B08-F6AE-4B2B-AB0C-86E5A05926A3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Sampler.AWS", "src\OpenTelemetry.Sampler.AWS\OpenTelemetry.Sampler.AWS.csproj", "{54002B08-F6AE-4B2B-AB0C-86E5A05926A3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Sampler.AWS.Tests", "test\OpenTelemetry.Sampler.AWS.Tests\OpenTelemetry.Sampler.AWS.Tests.csproj", "{48C29501-3FA2-46A7-B5BA-D282EA8F1274}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Sampler.AWS.Tests", "test\OpenTelemetry.Sampler.AWS.Tests\OpenTelemetry.Sampler.AWS.Tests.csproj", "{48C29501-3FA2-46A7-B5BA-D282EA8F1274}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Benchmarks", "test\OpenTelemetry.Exporter.OneCollector.Benchmarks\OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj", "{C42868C8-968A-473F-AC39-AC97C5D47E84}" EndProject diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index e97a3917d4..0000000000 --- a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e97a3917d4..0000000000 --- a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.Extensions.Docker.Resources.DockerResourceDetector.DockerResourceDetector() -> void diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Docker/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..9da4e0d8d8 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector +OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector.ContainerResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Docker/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..9da4e0d8d8 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector +OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector.ContainerResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs similarity index 60% rename from src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs rename to src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs index a6a0089eba..874cf880ac 100644 --- a/src/OpenTelemetry.Extensions.Docker/AssemblyInfo.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Docker.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Container.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.Docker.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Container.Tests")] #endif diff --git a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md similarity index 51% rename from src/OpenTelemetry.Extensions.Docker/CHANGELOG.md rename to src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 65b8ae1498..f3e5bf6ec8 100644 --- a/src/OpenTelemetry.Extensions.Docker/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,19 @@ ## Unreleased +* Going forward the NuGet package will be + [`OpenTelemetry.ResourceDetectors.Container`](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Container). + Older versions will remain at + [`OpenTelemetry.Extensions.Docker`](https://www.nuget.org/packages/OpenTelemetry.Extensions.Docker) + [(#881)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/881) + + Migration: + + * In code update namespaces (eg `using + OpenTelemetry.Extensions.Docker.Resources` -> `using + OpenTelemetry.ResourceDetectors.Container`) + and the class name (`DockerResourceDetector` to `ContainerResourceDetector`). + ([#1123](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1123)) * Updates to 1.4.0 of OpenTelemetry SDK. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs similarity index 84% rename from src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs rename to src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs index 0478b5bdb6..6e2eda010b 100644 --- a/src/OpenTelemetry.Extensions.Docker/DockerExtensionsEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,12 +19,12 @@ using System.Globalization; using System.Threading; -namespace OpenTelemetry.Extensions.Docker; +namespace OpenTelemetry.ResourceDetectors.Container; -[EventSource(Name = "OpenTelemetry-Extensions-Docker")] -internal class DockerExtensionsEventSource : EventSource +[EventSource(Name = "OpenTelemetry-ResourceDetectors-Container")] +internal class ContainerExtensionsEventSource : EventSource { - public static DockerExtensionsEventSource Log = new DockerExtensionsEventSource(); + public static ContainerExtensionsEventSource Log = new(); [NonEvent] public void ExtractResourceAttributesException(string format, Exception ex) diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs similarity index 84% rename from src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs rename to src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs index 4c96171049..c0acba8b91 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,19 +18,19 @@ using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; -using OpenTelemetry.Extensions.Docker.Utils; +using OpenTelemetry.ResourceDetectors.Container.Utils; using OpenTelemetry.Resources; -namespace OpenTelemetry.Extensions.Docker.Resources; +namespace OpenTelemetry.ResourceDetectors.Container; /// -/// Resource detector for application running in Docker environment. +/// Resource detector for application running in Container environment. /// -public class DockerResourceDetector : IResourceDetector +public class ContainerResourceDetector : IResourceDetector { - private const string FILEPATH = "/proc/self/cgroup"; - private const string FILEPATHV2 = "/proc/self/mountinfo"; - private const string HOSTNAME = "hostname"; + private const string Filepath = "/proc/self/cgroup"; + private const string FilepathV2 = "/proc/self/mountinfo"; + private const string Hostname = "hostname"; /// /// CGroup Parse Versions. @@ -49,15 +49,15 @@ internal enum ParseMode } /// - /// Detects the resource attributes from Docker. + /// Detects the resource attributes from Container. /// /// Resource with key-value pairs of resource attributes. public Resource Detect() { - var cGroupBuild = this.BuildResource(FILEPATH, ParseMode.V1); + var cGroupBuild = this.BuildResource(Filepath, ParseMode.V1); if (cGroupBuild == Resource.Empty) { - cGroupBuild = this.BuildResource(FILEPATHV2, ParseMode.V2); + cGroupBuild = this.BuildResource(FilepathV2, ParseMode.V2); } return cGroupBuild; @@ -79,7 +79,7 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) } else { - return new Resource(new List>(1) { new(DockerSemanticConventions.AttributeContainerID, containerId!) }); + return new Resource(new List>(1) { new(ContainerSemanticConventions.AttributeContainerId, containerId!) }); } } @@ -169,7 +169,7 @@ private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex { containerId = GetIdFromLineV1(line); } - else if (cgroupVersion == ParseMode.V2 && line.Contains(HOSTNAME)) + else if (cgroupVersion == ParseMode.V2 && line.Contains(Hostname)) { containerId = GetIdFromLineV2(line); } @@ -183,7 +183,7 @@ private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex } catch (Exception ex) { - DockerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(DockerResourceDetector)} : Failed to extract Container id from path", ex); + ContainerExtensionsEventSource.Log.ExtractResourceAttributesException($"{nameof(ContainerResourceDetector)} : Failed to extract Container id from path", ex); } return null; diff --git a/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs similarity index 70% rename from src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs rename to src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs index 0b554a79d0..2400ecc61b 100644 --- a/src/OpenTelemetry.Extensions.Docker/Resources/DockerSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,9 +14,9 @@ // limitations under the License. // -namespace OpenTelemetry.Extensions.Docker.Resources; +namespace OpenTelemetry.ResourceDetectors.Container; -internal static class DockerSemanticConventions +internal static class ContainerSemanticConventions { - public const string AttributeContainerID = "container.id"; + public const string AttributeContainerId = "container.id"; } diff --git a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj similarity index 80% rename from src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj rename to src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj index 3f82d2a3cc..da126da3d5 100644 --- a/src/OpenTelemetry.Extensions.Docker/OpenTelemetry.Extensions.Docker.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj @@ -2,8 +2,8 @@ netstandard2.0;net462 - OpenTelemetry Extensions - Container Resource Detector from Docker environment. - Extensions.Docker- + OpenTelemetry Extensions - Container Resource Detector from Container environment. + ResourceDetectors.Container- enable diff --git a/src/OpenTelemetry.Extensions.Docker/README.md b/src/OpenTelemetry.ResourceDetectors.Container/README.md similarity index 54% rename from src/OpenTelemetry.Extensions.Docker/README.md rename to src/OpenTelemetry.ResourceDetectors.Container/README.md index 1d8b0ed735..3c6f251b42 100644 --- a/src/OpenTelemetry.Extensions.Docker/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/README.md @@ -1,37 +1,37 @@ -# Docker Resource Detectors +# Container Resource Detectors ## Getting Started You need to install the -`OpenTelemetry.Extensions.Docker` to be able to use the -Docker Resource Detectors. It detects container.id from -Docker environment. +`OpenTelemetry.ResourceDetectors.Container` to be able to use the +Container Resource Detectors. It detects container.id from +Container environment. ```shell -dotnet add package OpenTelemetry.Extensions.Docker +dotnet add package OpenTelemetry.ResourceDetectors.Container --prerelease ``` ## Usage -You can configure Docker resource detector to +You can configure Container resource detector to the `TracerProvider` with the following example below. ```csharp using OpenTelemetry; -using OpenTelemetry.Extensions.Docker.Resources; +using OpenTelemetry.ResourceDetectors.Container; var tracerProvider = Sdk.CreateTracerProviderBuilder() // other configurations .SetResourceBuilder(ResourceBuilder .CreateEmpty() - .AddDetector(new DockerResourceDetector())) + .AddDetector(new ContainerResourceDetector())) .Build(); ``` The resource detectors will record the following metadata based on where your application is running: -- **DockerResourceDetector**: container.id. +- **ContainerResourceDetector**: container.id. ## References diff --git a/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs b/src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs similarity index 89% rename from src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs rename to src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs index 28bd35bc38..eb258ef92f 100644 --- a/src/OpenTelemetry.Extensions.Docker/Utils/EncodingUtils.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs @@ -17,7 +17,7 @@ using System.Collections.Generic; using System.Linq; -namespace OpenTelemetry.Extensions.Docker.Utils; +namespace OpenTelemetry.ResourceDetectors.Container.Utils; internal class EncodingUtils { @@ -28,9 +28,9 @@ internal class EncodingUtils /// true if valid else false. public static bool IsValidHexString(IEnumerable hexString) { - return hexString.Select(currentCharacter => + return hexString.All(currentCharacter => (currentCharacter >= '0' && currentCharacter <= '9') || (currentCharacter >= 'a' && currentCharacter <= 'f') || - (currentCharacter >= 'A' && currentCharacter <= 'F')).All(isHexCharacter => isHexCharacter); + (currentCharacter >= 'A' && currentCharacter <= 'F')); } } diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs similarity index 70% rename from test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs rename to test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs index c5b6120819..18740e0226 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/DockerResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,166 +17,165 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using OpenTelemetry.Extensions.Docker.Resources; using OpenTelemetry.Resources; using Xunit; -namespace OpenTelemetry.Extensions.Docker.Tests; +namespace OpenTelemetry.ResourceDetectors.Container.Tests; -public class DockerResourceDetectorTests +public class ContainerResourceDetectorTests { private readonly List testValidCasesV1 = new() { - new TestCase() + new TestCase { Name = "cgroupv1 with prefix", Line = "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff", ExpectedContainerId = "e2cc29debdf85dde404998aa128997a819ff", - CgroupVersion = DockerResourceDetector.ParseMode.V1, + CgroupVersion = ContainerResourceDetector.ParseMode.V1, }, - new TestCase() + new TestCase { Name = "cgroupv1 with suffix", Line = "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", ExpectedContainerId = "ac679f8a8319c8cf7d38e1adf263bc08d23", - CgroupVersion = DockerResourceDetector.ParseMode.V1, + CgroupVersion = ContainerResourceDetector.ParseMode.V1, }, - new TestCase() + new TestCase { Name = "cgroupv1 with prefix and suffix", Line = "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", ExpectedContainerId = "dc679f8a8319c8cf7d38e1adf263bc08d23", - CgroupVersion = DockerResourceDetector.ParseMode.V1, + CgroupVersion = ContainerResourceDetector.ParseMode.V1, }, - new TestCase() + new TestCase { Name = "cgroupv1 with container Id", Line = "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", ExpectedContainerId = "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", - CgroupVersion = DockerResourceDetector.ParseMode.V1, + CgroupVersion = ContainerResourceDetector.ParseMode.V1, }, }; private readonly List testValidCasesV2 = new() { - new TestCase() + new TestCase { Name = "cgroupv2 with container Id", Line = "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356/hostname", ExpectedContainerId = "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, - new TestCase() + new TestCase { Name = "cgroupv2 with full line", Line = "473 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", ExpectedContainerId = "dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, - new TestCase() + new TestCase { Name = "cgroupv2 with minikube containerd mountinfo", Line = "1537 1517 8:1 /var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", ExpectedContainerId = "fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, - new TestCase() + new TestCase { Name = "cgroupv2 with minikube docker mountinfo", Line = "2327 2307 8:1 /var/lib/docker/containers/a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", ExpectedContainerId = "a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, - new TestCase() + new TestCase { Name = "cgroupv2 with minikube docker mountinfo2", Line = "929 920 254:1 /docker/volumes/minikube/_data/lib/docker/containers/0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", ExpectedContainerId = "0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, - new TestCase() + new TestCase { Name = "cgroupv2 with podman mountinfo", Line = "1096 1088 0:104 /containers/overlay-containers/1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=813800k,nr_inodes=203450,mode=700,uid=1000,gid=1000", ExpectedContainerId = "1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, }; private readonly List testInvalidCases = new() { - new TestCase() + new TestCase { Name = "Invalid cgroupv1 line", Line = "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", - CgroupVersion = DockerResourceDetector.ParseMode.V1, + CgroupVersion = ContainerResourceDetector.ParseMode.V1, }, - new TestCase() + new TestCase { Name = "Invalid hex cgroupv2 line (contains a z)", Line = "13:name=systemd:/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3fz9320f4402ae6/hostname", - CgroupVersion = DockerResourceDetector.ParseMode.V2, + CgroupVersion = ContainerResourceDetector.ParseMode.V2, }, }; [Fact] public void TestValidContainer() { - var dockerResourceDetector = new DockerResourceDetector(); + var containerResourceDetector = new ContainerResourceDetector(); var allValidTestCases = this.testValidCasesV1.Concat(this.testValidCasesV2); foreach (var testCase in allValidTestCases) { - using TempFile tempFile = new TempFile(); + using var tempFile = new TempFile(); tempFile.Write(testCase.Line); Assert.Equal( testCase.ExpectedContainerId, - GetContainerId(dockerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion))); + GetContainerId(containerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion))); } } [Fact] public void TestInvalidContainer() { - var dockerResourceDetector = new DockerResourceDetector(); + var containerResourceDetector = new ContainerResourceDetector(); // Valid in cgroupv1 is not valid in cgroupv2 foreach (var testCase in this.testValidCasesV1) { - using TempFile tempFile = new TempFile(); + using var tempFile = new TempFile(); tempFile.Write(testCase.Line); Assert.Equal( - dockerResourceDetector.BuildResource(tempFile.FilePath, DockerResourceDetector.ParseMode.V2), + containerResourceDetector.BuildResource(tempFile.FilePath, ContainerResourceDetector.ParseMode.V2), Resource.Empty); } // Valid in cgroupv1 is not valid in cgroupv1 foreach (var testCase in this.testValidCasesV2) { - using TempFile tempFile = new TempFile(); + using var tempFile = new TempFile(); tempFile.Write(testCase.Line); Assert.Equal( - dockerResourceDetector.BuildResource(tempFile.FilePath, DockerResourceDetector.ParseMode.V1), + containerResourceDetector.BuildResource(tempFile.FilePath, ContainerResourceDetector.ParseMode.V1), Resource.Empty); } // test invalid cases foreach (var testCase in this.testInvalidCases) { - using TempFile tempFile = new TempFile(); + using var tempFile = new TempFile(); tempFile.Write(testCase.Line); - Assert.Equal(dockerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion), Resource.Empty); + Assert.Equal(containerResourceDetector.BuildResource(tempFile.FilePath, testCase.CgroupVersion), Resource.Empty); } // test invalid file - Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath(), DockerResourceDetector.ParseMode.V1), Resource.Empty); - Assert.Equal(dockerResourceDetector.BuildResource(Path.GetTempPath(), DockerResourceDetector.ParseMode.V2), Resource.Empty); + Assert.Equal(containerResourceDetector.BuildResource(Path.GetTempPath(), ContainerResourceDetector.ParseMode.V1), Resource.Empty); + Assert.Equal(containerResourceDetector.BuildResource(Path.GetTempPath(), ContainerResourceDetector.ParseMode.V2), Resource.Empty); } private static string GetContainerId(Resource resource) { var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - return resourceAttributes[DockerSemanticConventions.AttributeContainerID]?.ToString(); + return resourceAttributes[ContainerSemanticConventions.AttributeContainerId]?.ToString(); } private sealed class TestCase @@ -187,6 +186,6 @@ private sealed class TestCase public string ExpectedContainerId { get; set; } - public DockerResourceDetector.ParseMode CgroupVersion { get; set; } + public ContainerResourceDetector.ParseMode CgroupVersion { get; set; } } } diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj similarity index 76% rename from test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj rename to test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj index 8457c84d05..6c4811cb1f 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/OpenTelemetry.Extensions.Docker.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj @@ -1,7 +1,7 @@ - Unit test project for Docker Detector for OpenTelemetry + Unit test project for Container Detector for OpenTelemetry net7.0;net6.0 $(TargetFrameworks);net462 @@ -19,7 +19,11 @@ - + + + + + diff --git a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs b/test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs similarity index 71% rename from test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs rename to test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs index 61bb38d80f..64c66fe657 100644 --- a/test/OpenTelemetry.Extensions.Docker.Tests/Resources/TempFile.cs +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs @@ -18,28 +18,22 @@ using System.IO; using System.Threading; -namespace OpenTelemetry.Extensions.Docker.Tests; +namespace OpenTelemetry.ResourceDetectors.Container.Tests; internal class TempFile : IDisposable { - private string filePath; - public TempFile() { - this.filePath = Path.GetTempFileName(); + this.FilePath = Path.GetTempFileName(); } - public string FilePath - { - get { return this.filePath; } - set { this.filePath = value; } - } + public string FilePath { get; set; } public void Write(string data) { - using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + using (var stream = new FileStream(this.FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) { - using (StreamWriter sw = new StreamWriter(stream)) + using (var sw = new StreamWriter(stream)) { sw.Write(data); } @@ -48,11 +42,11 @@ public void Write(string data) public void Dispose() { - for (int tries = 0; ; tries++) + for (var tries = 0; ; tries++) { try { - File.Delete(this.filePath); + File.Delete(this.FilePath); return; } catch (IOException) when (tries < 3) From 11c69f199e97be065a7bd119f2f9d87bca3738b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Sat, 1 Apr 2023 02:32:24 +0200 Subject: [PATCH 0659/1499] [Instrumentation.AWS] drop default parameter from registration method (#1117) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 4 +++- .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 4 +++- .../CHANGELOG.md | 2 ++ .../TracerProviderBuilderExtensions.cs | 10 +++++++++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt index 7dc5c58110..fb419c1de8 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ -#nullable enable +*REMOVED*static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7dc5c58110..fb419c1de8 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ -#nullable enable +*REMOVED*static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md index 28303b32a3..ae9dc28eab 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md @@ -4,6 +4,8 @@ * Raised the minimum .NET version to `net462` ([#1095](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1095)) +* Removes `AddAWSInstrumentation` method with default configure default parameter. + ([#1117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1117)) ## 1.0.2 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index 47063958d0..32bcbfe2ba 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -26,6 +26,14 @@ namespace OpenTelemetry.Trace; /// public static class TracerProviderBuilderExtensions { + /// + /// Enables AWS Instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAWSInstrumentation( + this TracerProviderBuilder builder) => AddAWSInstrumentation(builder, configure: null); + /// /// Enables AWS Instrumentation. /// @@ -34,7 +42,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddAWSInstrumentation( this TracerProviderBuilder builder, - Action? configure = null) + Action? configure) { Guard.ThrowIfNull(builder); From af46ef24f0377f246463a38b91f2e7a50e664ece Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 3 Apr 2023 11:05:07 -0700 Subject: [PATCH 0660/1499] [OneCollectorExporter] eventId support (#1127) --- .../CHANGELOG.md | 4 ++++ .../LogRecordCommonSchemaJsonSerializer.cs | 6 ++---- .../LogRecordCommonSchemaJsonSerializerTests.cs | 13 +++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index b17bc47694..4de8d3d852 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -14,6 +14,10 @@ exception is present on `LogRecord`s. ([#1082](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1082)) +* Added support for sending common schema `eventId` field when `EventId.Id` is + non-zero on `LogRecord`s. + ([#1127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1127)) + ## 0.1.0-alpha.2 Released 2023-Mar-6 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index b2d2f7f957..9af77e3f22 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -23,6 +23,7 @@ namespace OpenTelemetry.Exporter.OneCollector; internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSerializer { + private static readonly JsonEncodedText EventIdProperty = JsonEncodedText.Encode("eventId"); private static readonly JsonEncodedText SeverityTextProperty = JsonEncodedText.Encode("severityText"); private static readonly JsonEncodedText SeverityNumberProperty = JsonEncodedText.Encode("severityNumber"); private static readonly JsonEncodedText BodyProperty = JsonEncodedText.Encode("body"); @@ -120,13 +121,10 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C writer.WriteStartObject(CommonSchemaJsonSerializationHelper.DataProperty); - /* TODO: There doesn't seem to be a spot in common schema defined for - event.id so we will drop for now. - if (item.EventId.Id != 0) { writer.WriteNumber(EventIdProperty, item.EventId.Id); - }*/ + } var logLevel = (int)item.LogLevel; writer.WriteString(SeverityTextProperty, LogLevelToSeverityTextMappings[logLevel]); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 5c1b506325..a42e14d2db 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -83,6 +83,19 @@ public void LogRecordCategoryNameAndEventNameJsonTest(string categoryName, strin json); } + [Fact] + public void LogRecordEventIdJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.EventId = new(18); + }); + + Assert.Equal( + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"eventId\":18,\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + json); + } + [Fact] public void LogRecordTimestampJsonTest() { From a1acd45cb962088aac83e8745b74ce8f3696b18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 4 Apr 2023 06:31:47 +0200 Subject: [PATCH 0661/1499] Unify Exception ToInvariantString method (#1126) --- build/Common.props | 5 +- .../AWSXRayEventSource.cs | 26 ++------- ...elemetry.Contrib.Extensions.AWSXRay.csproj | 1 + .../Api/ExceptionExtensions.cs | 12 ++--- .../Internal/ExporterEventSource.cs | 30 ++--------- .../MsgPackExporter/MsgPackLogExporter.cs | 18 +------ .../OpenTelemetry.Exporter.Geneva.csproj | 1 + .../TLDExporter/TldLogExporter.cs | 18 +------ .../InstanaExporterEventSource.cs | 24 +-------- .../OpenTelemetry.Exporter.Instana.csproj | 1 + .../OneCollectorExporterEventSource.cs | 23 ++------ .../LogRecordCommonSchemaJsonSerializer.cs | 3 +- ...OpenTelemetry.Exporter.OneCollector.csproj | 1 + .../ExporterStackdriverEventSource.cs | 54 +------------------ .../OpenTelemetry.Exporter.Stackdriver.csproj | 3 +- .../OpenTelemetry.Extensions.csproj | 2 +- ...entation.AspNet.TelemetryHttpModule.csproj | 2 +- ...penTelemetry.Instrumentation.AspNet.csproj | 2 +- ...Instrumentation.ElasticsearchClient.csproj | 3 +- ...tityFrameworkInstrumentationEventSource.cs | 23 +------- ...Instrumentation.EntityFrameworkCore.csproj | 3 +- .../OwinInstrumentationEventSource.cs | 26 ++------- .../OpenTelemetry.Instrumentation.Owin.csproj | 2 +- ...penTelemetry.Instrumentation.Quartz.csproj | 3 +- ....Instrumentation.StackExchangeRedis.csproj | 1 + .../WcfInstrumentationEventSource.cs | 26 ++------- .../OpenTelemetry.Instrumentation.Wcf.csproj | 1 + ...etry.PersistentStorage.Abstractions.csproj | 1 + ...ersistentStorageAbstractionsEventSource.cs | 24 +-------- ...emetry.PersistentStorage.FileSystem.csproj | 1 + .../PersistentStorageEventSource.cs | 40 ++++---------- .../ContainerExtensionsEventSource.cs | 24 +-------- ...lemetry.ResourceDetectors.Container.csproj | 1 + .../AWSSamplerEventSource.cs | 22 -------- ...try.Instrumentation.AWSLambda.Tests.csproj | 1 + 35 files changed, 73 insertions(+), 355 deletions(-) diff --git a/build/Common.props b/build/Common.props index fd517f699f..5e644908d3 100644 --- a/build/Common.props +++ b/build/Common.props @@ -54,6 +54,10 @@ + + + + @@ -62,7 +66,6 @@ - diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs index c42b4eac89..4e0ba6c9d9 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Contrib.Extensions.AWSXRay; @@ -31,7 +30,7 @@ public void ActivityContextExtractException(string format, Exception ex) { if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) { - this.FailedToExtractActivityContext(format, ToInvariantString(ex)); + this.FailedToExtractActivityContext(format, ex.ToInvariantString()); } } @@ -40,7 +39,7 @@ public void ResourceAttributesExtractException(string format, Exception ex) { if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) { - this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); + this.FailedToExtractResourceAttributes(format, ex.ToInvariantString()); } } @@ -67,23 +66,4 @@ public void FailedToValidateCertificate(string format, string error) { this.WriteEvent(4, format, error); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index d804733696..d06b9eb9ca 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -5,6 +5,7 @@ OpenTelemetry extensions for AWS X-Ray. Extensions.AWSXRay- enable + true diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs b/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs index 9fc3296917..dea6a61c66 100644 --- a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs +++ b/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs @@ -14,9 +14,9 @@ // limitations under the License. // -using System; +#nullable enable + using System.Globalization; -using System.Threading; namespace OpenTelemetry.Internal; @@ -28,18 +28,18 @@ internal static class ExceptionExtensions /// /// Exception to convert to string. /// Exception as string with no culture. - public static string ToInvariantString(this Exception exception) + public static string ToInvariantString(this System.Exception exception) { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; + var originalUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; try { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; return exception.ToString(); } finally { - Thread.CurrentThread.CurrentUICulture = originalUICulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 65f43be9af..91cf275805 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -43,7 +42,7 @@ public void FailedToSendTraceData(Exception ex) // descrs[0].Size = ((arg1.Length + 1) * 2); // I'm assuming it calculates the size of string, then it should be: // (count of chars) * sizeof(char) + sizeof(Length:int) = (str.Length * 2 + 4). - this.FailedToSendTraceData(ToInvariantString(ex)); + this.FailedToSendTraceData(ex.ToInvariantString()); } } @@ -53,7 +52,7 @@ public void FailedToSendLogData(Exception ex) if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { // TODO: Do not hit ETW size limit even for external library exception stack. - this.FailedToSendLogData(ToInvariantString(ex)); + this.FailedToSendLogData(ex.ToInvariantString()); } } @@ -63,7 +62,7 @@ public void FailedToSendMetricData(string monitoringAccount, string metricNamesp if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { // TODO: Do not hit ETW size limit even for external library exception stack. - this.FailedToSendMetricData(monitoringAccount, metricNamespace, metricName, ToInvariantString(ex)); + this.FailedToSendMetricData(monitoringAccount, metricNamespace, metricName, ex.ToInvariantString()); } } @@ -73,7 +72,7 @@ public void ExporterException(string message, Exception ex) if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { // TODO: Do not hit ETW size limit even for external library exception stack. - this.ExporterException(message, ToInvariantString(ex)); + this.ExporterException(message, ex.ToInvariantString()); } } @@ -100,23 +99,4 @@ public void ExporterException(string message, string error) { this.WriteEvent(EVENT_ID_ERROR, message, error); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index f02febac53..b8c9534796 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -21,6 +21,7 @@ using System.Runtime.InteropServices; using System.Threading; using Microsoft.Extensions.Logging; +using OpenTelemetry.Internal; using OpenTelemetry.Logs; namespace OpenTelemetry.Exporter.Geneva; @@ -370,7 +371,7 @@ internal int SerializeLogRecord(LogRecord logRecord) // before running out of limit instead of STRING_SIZE_LIMIT_CHAR_COUNT. // 2. Trim smarter, by trimming the middle of stack, an // keep top and bottom. - var exceptionStack = ToInvariantString(logRecord.Exception); + var exceptionStack = logRecord.Exception.ToInvariantString(); cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_stack"); cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, exceptionStack); cntFields += 1; @@ -413,21 +414,6 @@ private static byte GetSeverityNumber(LogLevel logLevel) } } - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } - public void Dispose() { if (this.isDisposed) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 41c3ddcc7b..4478d94496 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -10,6 +10,7 @@ $(TargetFrameworks);net462 Exporter.Geneva- true + true diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index d056ef9a54..415891a9c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -278,7 +278,7 @@ internal void SerializeLogRecord(LogRecord logRecord) // before running out of limit instead of STRING_SIZE_LIMIT_CHAR_COUNT. // 2. Trim smarter, by trimming the middle of stack, an // keep top and bottom. - var exceptionStack = ToInvariantString(logRecord.Exception); + var exceptionStack = logRecord.Exception.ToInvariantString(); eb.AddCountedAnsiString("ext_ex_stack", exceptionStack, Encoding.UTF8, 0, Math.Min(exceptionStack.Length, StringLengthLimit)); partAFieldsCount++; } @@ -484,22 +484,6 @@ private static string GetSanitizedCategoryName(string categoryName) return result.Slice(0, validNameLength).ToString(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } - private static readonly Action ProcessScopeForIndividualColumns = (scope, state) => { var stateData = state.serializationData.Value; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs index 8a5ede78f0..1d797a2bda 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Instana.Implementation; @@ -35,7 +34,7 @@ public void FailedExport(Exception ex) { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.FailedExport(ToInvariantString(ex)); + this.FailedExport(ex.ToInvariantString()); } } @@ -44,23 +43,4 @@ public void FailedExport(string exception) { this.WriteEvent(1, exception); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 8977649b0f..6afb43a629 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -6,6 +6,7 @@ Instana Tracing APM Instana .NET Exporter for OpenTelemetry Exporter.Instana- + true diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index bb73a80a13..8cfefcbe63 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -15,8 +15,8 @@ // using System.Diagnostics.Tracing; -using System.Globalization; using System.Runtime.CompilerServices; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.OneCollector; @@ -33,7 +33,7 @@ public void WriteExportExceptionThrownEventIfEnabled(string itemType, Exception { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.ExportExceptionThrown(itemType, ExceptionToInvariantString(exception)); + this.ExportExceptionThrown(itemType, exception.ToInvariantString()); } } @@ -60,7 +60,7 @@ public void WriteTransportExceptionThrownEventIfEnabled(string transportType, Ex { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.TransportExceptionThrown(transportType, ExceptionToInvariantString(exception)); + this.TransportExceptionThrown(transportType, exception.ToInvariantString()); } } @@ -78,7 +78,7 @@ public void WriteExceptionThrownFromUserCodeEventIfEnabled(string userCodeType, { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.ExceptionThrownFromUserCode(userCodeType, ExceptionToInvariantString(exception)); + this.ExceptionThrownFromUserCode(userCodeType, exception.ToInvariantString()); } } @@ -147,19 +147,4 @@ public void AttributeDropped(string itemType, string name, string reason) { this.WriteEvent(11, itemType, name, reason); } - - internal static string ExceptionToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 9af77e3f22..2d202236b7 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -16,6 +16,7 @@ using System.Diagnostics; using System.Text.Json; +using OpenTelemetry.Internal; using OpenTelemetry.Logs; using OpenTelemetry.Resources; @@ -208,7 +209,7 @@ private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter w if (this.exceptionStackTraceHandling == OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString) { - writer.WriteString(ExceptionExtensionStackTraceProperty, OneCollectorExporterEventSource.ExceptionToInvariantString(item.Exception)); + writer.WriteString(ExceptionExtensionStackTraceProperty, item.Exception.ToInvariantString()); } writer.WriteEndObject(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index bb4ac8d267..cd6db1ff7d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -10,6 +10,7 @@ enable true true + true diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs index c6c55009ec..118f88aac5 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Stackdriver.Implementation; @@ -26,42 +25,12 @@ internal class ExporterStackdriverEventSource : EventSource { public static readonly ExporterStackdriverEventSource Log = new ExporterStackdriverEventSource(); - [NonEvent] - public void UnknownProblemInWorkerThreadError(Exception ex) - { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.UnknownProblemInWorkerThreadError(ToInvariantString(ex)); - } - } - - [Event(1, Message = "Stackdriver exporter encountered an unknown error and will shut down. Exception: {0}", Level = EventLevel.Error)] - public void UnknownProblemInWorkerThreadError(string ex) - { - this.WriteEvent(1, ex); - } - - [NonEvent] - public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(Exception ex) - { - if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.UnknownProblemWhileCreatingStackdriverTimeSeriesError(ToInvariantString(ex)); - } - } - - [Event(2, Message = "Stackdriver exporter failed to create time series. Time series will be lost. Exception: {0}", Level = EventLevel.Error)] - public void UnknownProblemWhileCreatingStackdriverTimeSeriesError(string ex) - { - this.WriteEvent(2, ex); - } - [NonEvent] public void ExportMethodException(Exception ex) { if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.ExportMethodException(ToInvariantString(ex)); + this.ExportMethodException(ex.ToInvariantString()); } } @@ -70,23 +39,4 @@ public void ExportMethodException(string ex) { this.WriteEvent(1, ex); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index f8fbd7ea5a..34f46926f4 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -1,10 +1,11 @@ - + netstandard2.0;net462 Stackdriver .NET Exporter for OpenTelemetry. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- + true diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 8462a7674f..6518979045 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -4,6 +4,7 @@ netstandard2.0;net462; net6.0;$(TargetFrameworks) + true OpenTelemetry .NET SDK preview features and extensions Extensions- enable @@ -11,7 +12,6 @@ - diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index e84816eca4..a084f11f68 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -2,13 +2,13 @@ $(NetFrameworkMinimumSupportedVersion) + true A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI Instrumentation.AspNet.TelemetryHttpModule- - diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 6cac679253..f0eec1af27 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -2,6 +2,7 @@ $(NetFrameworkMinimumSupportedVersion) + true ASP.NET instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true @@ -14,7 +15,6 @@ - diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index b0323bbc18..e8560eac26 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net462 @@ -6,6 +6,7 @@ $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- true + true diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 1b6e8a2e70..520c3063a3 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -16,8 +16,6 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; @@ -32,7 +30,7 @@ public void UnknownErrorProcessingEvent(string handlerName, string eventName, Ex { if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - this.UnknownErrorProcessingEvent(handlerName, eventName, ToInvariantString(ex)); + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); } } @@ -77,23 +75,4 @@ public void EnrichmentException(string eventName, string exception) this.WriteEvent(5, eventName, exception); } } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 7cb47060c4..f4d574d930 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -1,10 +1,11 @@ - + netstandard2.0 Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.EntityFrameworkCore- true + true diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index ddcd595f10..be5229504e 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Owin; @@ -34,7 +33,7 @@ public void RequestFilterException(Exception ex) { if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - this.RequestFilterException(ToInvariantString(ex)); + this.RequestFilterException(ex.ToInvariantString()); } } @@ -55,7 +54,7 @@ public void EnrichmentException(Exception exception) { if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - this.EnrichmentException(ToInvariantString(exception)); + this.EnrichmentException(exception.ToInvariantString()); } } @@ -65,25 +64,6 @@ public void EnrichmentException(string exception) this.WriteEvent(EventIds.EnrichmentException, exception); } - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } - private class EventIds { public const int RequestIsFilteredOut = 1; diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 65ebc2363d..de6e33c97f 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -1,6 +1,7 @@  $(NetFrameworkMinimumSupportedVersion) + true OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- @@ -8,7 +9,6 @@ - diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 97e19a1f72..0b271ac9da 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -5,8 +5,7 @@ Instrumentation.Quartz- true netstandard2.0 - OpenTelemetry.Instrumentation.Quartz - OpenTelemetry.Instrumentation.Quartz + true diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index c12e750ae0..29b7e82417 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -5,6 +5,7 @@ StackExchange.Redis instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;Redis;StackExchange.Redis true + true Instrumentation.StackExchangeRedis- diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index fa73b497c1..bd23a2e9c6 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf.Implementation; @@ -31,7 +30,7 @@ public void RequestFilterException(Exception ex) { if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - this.RequestFilterException(ToInvariantString(ex)); + this.RequestFilterException(ex.ToInvariantString()); } } @@ -52,7 +51,7 @@ public void EnrichmentException(Exception exception) { if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - this.EnrichmentException(ToInvariantString(exception)); + this.EnrichmentException(exception.ToInvariantString()); } } @@ -62,25 +61,6 @@ public void EnrichmentException(string exception) this.WriteEvent(EventIds.EnrichmentException, exception); } - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } - private class EventIds { public const int RequestIsFilteredOut = 1; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 922b8fd1a9..cc6da9eac8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -3,6 +3,7 @@ netstandard2.0;net462 + true OpenTelemetry instrumentation for WCF $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index 3c2fc65c5c..f23566e9bf 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -5,6 +5,7 @@ netstandard2.0 $(TargetFrameworks);net462 net6.0;$(TargetFrameworks) + true OpenTelemetry Persistent Storage Abstractions Extensions.PersistentStorage.Abstractions- $(NoWarn),1591 diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs index 4c122d7217..7c0d1d2861 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.PersistentStorage.Abstractions; @@ -32,7 +31,7 @@ public void PersistentStorageAbstractionsException(string className, string mess { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.PersistentStorageAbstractionsException(className, message, ToInvariantString(ex)); + this.PersistentStorageAbstractionsException(className, message, ex.ToInvariantString()); } } @@ -41,23 +40,4 @@ public void PersistentStorageAbstractionsException(string className, string mess { this.WriteEvent(1, className, message, ex); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 9deb66221d..c3c1452e07 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -5,6 +5,7 @@ netstandard2.0 $(TargetFrameworks);net462 net6.0;$(TargetFrameworks) + true OpenTelemetry Persistent Storage Extensions.PersistentStorage- diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs index 3192c453fa..8ba898fae6 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.PersistentStorage.FileSystem; @@ -32,7 +31,7 @@ public void CouldNotReadFileBlob(string filePath, Exception ex) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - this.CouldNotReadFileBlob(filePath, ToInvariantString(ex)); + this.CouldNotReadFileBlob(filePath, ex.ToInvariantString()); } } @@ -41,7 +40,7 @@ public void CouldNotWriteFileBlob(string filePath, Exception ex) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - this.CouldNotWriteFileBlob(filePath, ToInvariantString(ex)); + this.CouldNotWriteFileBlob(filePath, ex.ToInvariantString()); } } @@ -50,7 +49,7 @@ public void CouldNotLeaseFileBlob(string filePath, Exception ex) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - this.CouldNotLeaseFileBlob(filePath, ToInvariantString(ex)); + this.CouldNotLeaseFileBlob(filePath, ex.ToInvariantString()); } } @@ -59,7 +58,7 @@ public void CouldNotDeleteFileBlob(string filePath, Exception ex) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - this.CouldNotDeleteFileBlob(filePath, ToInvariantString(ex)); + this.CouldNotDeleteFileBlob(filePath, ex.ToInvariantString()); } } @@ -68,7 +67,7 @@ public void CouldNotCreateFileBlob(Exception ex) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - this.CouldNotCreateFileBlob(ToInvariantString(ex)); + this.CouldNotCreateFileBlob(ex.ToInvariantString()); } } @@ -77,7 +76,7 @@ public void CouldNotRemoveExpiredBlob(string filePath, Exception ex) { if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) { - this.CouldNotRemoveExpiredBlob(filePath, ToInvariantString(ex)); + this.CouldNotRemoveExpiredBlob(filePath, ex.ToInvariantString()); } } @@ -86,7 +85,7 @@ public void CouldNotRemoveTimedOutTmpFile(string filePath, Exception ex) { if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) { - this.CouldNotRemoveTimedOutTmpFile(filePath, ToInvariantString(ex)); + this.CouldNotRemoveTimedOutTmpFile(filePath, ex.ToInvariantString()); } } @@ -95,7 +94,7 @@ public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, { if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) { - this.CouldNotRemoveExpiredLease(srcFilePath, destFilePath, ToInvariantString(ex)); + this.CouldNotRemoveExpiredLease(srcFilePath, destFilePath, ex.ToInvariantString()); } } @@ -104,7 +103,7 @@ public void PersistentStorageException(string className, string message, Excepti { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.PersistentStorageException(className, message, ToInvariantString(ex)); + this.PersistentStorageException(className, message, ex.ToInvariantString()); } } @@ -173,23 +172,4 @@ public void PersistentStorageInformation(string className, string message) { this.WriteEvent(11, className, message); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs index 6e2eda010b..7525df7c27 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs @@ -16,8 +16,7 @@ using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.ResourceDetectors.Container; @@ -31,7 +30,7 @@ public void ExtractResourceAttributesException(string format, Exception ex) { if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) { - this.FailedToExtractResourceAttributes(format, ToInvariantString(ex)); + this.FailedToExtractResourceAttributes(format, ex.ToInvariantString()); } } @@ -40,23 +39,4 @@ public void FailedToExtractResourceAttributes(string format, string exception) { this.WriteEvent(1, format, exception); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj index da126da3d5..ff5eb95467 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj @@ -5,6 +5,7 @@ OpenTelemetry Extensions - Container Resource Detector from Container environment. ResourceDetectors.Container- enable + true diff --git a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs index 702fe6886f..6e5e58143d 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs @@ -14,10 +14,7 @@ // limitations under the License. // -using System; using System.Diagnostics.Tracing; -using System.Globalization; -using System.Threading; namespace OpenTelemetry.Sampler.AWS; @@ -43,23 +40,4 @@ public void FailedToDeserializeResponse(string format, string error) { this.WriteEvent(3, format, error); } - - /// - /// Returns a culture-independent string representation of the given object, - /// appropriate for diagnostics tracing. - /// - private static string ToInvariantString(Exception exception) - { - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - - try - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; - return exception.ToString(); - } - finally - { - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index ecc88c9a31..681bd2ba2f 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -4,6 +4,7 @@ Unit test project of OpenTelemetry instrumentation for AWS Lambda netcoreapp3.1 true + true From bb8f923a4e934dd440fa70dfb21588b31cdd750f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 5 Apr 2023 22:21:06 +0200 Subject: [PATCH 0662/1499] Remove unused StatusHelper (#1128) --- build/Common.props | 1 - .../Api/StatusHelper.cs | 64 ------------------- ...Telemetry.Instrumentation.MySqlData.csproj | 1 - ...emetry.Instrumentation.AspNet.Tests.csproj | 1 - 4 files changed, 67 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs diff --git a/build/Common.props b/build/Common.props index 5e644908d3..78f7845324 100644 --- a/build/Common.props +++ b/build/Common.props @@ -69,7 +69,6 @@ - diff --git a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs b/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs deleted file mode 100644 index 51f4b69163..0000000000 --- a/src/OpenTelemetry.Contrib.Shared/Api/StatusHelper.cs +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#nullable enable - -using System; -using System.Runtime.CompilerServices; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Internal; - -internal static class StatusHelper -{ - public const string UnsetStatusCodeTagValue = "UNSET"; - public const string OkStatusCodeTagValue = "OK"; - public const string ErrorStatusCodeTagValue = "ERROR"; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string? GetTagValueForStatusCode(StatusCode statusCode) - { - return statusCode 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. - */ - StatusCode.Unset => UnsetStatusCodeTagValue, - StatusCode.Error => ErrorStatusCodeTagValue, - StatusCode.Ok => OkStatusCodeTagValue, - _ => null, - }; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static StatusCode? GetStatusCodeForTagValue(string statusCodeTagValue) - { - return statusCodeTagValue 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(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Unset, - not null when ErrorStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Error, - not null when OkStatusCodeTagValue.Equals(statusCodeTagValue, StringComparison.OrdinalIgnoreCase) => StatusCode.Ok, - _ => (StatusCode?)null, - }; - } -} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index f11c391fd3..5397712c47 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -16,7 +16,6 @@ - diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 92750cb40e..5a1b585cda 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -26,7 +26,6 @@ - From 59640b6d555954bd2257be4982c93885ee2802cf Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 5 Apr 2023 13:55:59 -0700 Subject: [PATCH 0663/1499] Remove unused code (#1131) Co-authored-by: Utkarsh Umesan Pillai --- .../PersistentStorageHelper.cs | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs index 71584b491c..3ce0a062fa 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs @@ -19,8 +19,6 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; -using System.Security.Cryptography; -using System.Text; using System.Threading; namespace OpenTelemetry.PersistentStorage.FileSystem; @@ -190,29 +188,6 @@ internal static DateTime GetDateTimeFromLeaseName(string filePath) return dateTime.ToUniversalTime(); } - internal static string GetSHA256Hash(string input) - { - byte[] inputBits = Encoding.Unicode.GetBytes(input); - -#if NET6_0_OR_GREATER -#pragma warning disable CA1308 // Normalize strings to uppercase - return Convert.ToHexString(SHA256.HashData(inputBits)).ToLowerInvariant(); -#pragma warning restore CA1308 // Normalize strings to uppercase -#else - var hashString = new StringBuilder(); - using (var sha256 = SHA256.Create()) - { - byte[] hashBits = sha256.ComputeHash(inputBits); - foreach (byte b in hashBits) - { - hashString.Append(b.ToString("x2", CultureInfo.InvariantCulture)); - } - } - - return hashString.ToString(); -#endif - } - private static long CalculateFolderSize(string path) { if (!Directory.Exists(path)) From a50e1cdbbe869ab2204d100610067e9325a338b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 6 Apr 2023 06:22:35 +0200 Subject: [PATCH 0664/1499] [Instrumentation.Hangfire] drop default parameter from registration method (#1129) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 ++- .../CHANGELOG.md | 2 ++ .../TracerProviderBuilderExtensions.cs | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index f5f2649209..61a9676a20 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -5,4 +5,5 @@ OpenTelemetry.Trace.HangfireInstrumentationOptions.HangfireInstrumentationOption OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHangfireInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index e8caed7660..989674df6b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OTel API version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Removes `AddHangfireInstrumentation` method with default configure default parameter. + ([#1129](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1129)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index e1d3a9d2e7..551edf445a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -29,16 +29,25 @@ public static class TracerProviderBuilderExtensions /// Adds Hangfire instrumentation to the tracer provider. /// /// being configured. - /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHangfireInstrumentation( + this TracerProviderBuilder builder) => + AddHangfireInstrumentation(builder, configure: null); + + /// + /// Adds Hangfire instrumentation to the tracer provider. + /// + /// being configured. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddHangfireInstrumentation( this TracerProviderBuilder builder, - Action configureHangfireInstrumentationOptions = null) + Action configure) { Guard.ThrowIfNull(builder); var options = new HangfireInstrumentationOptions(); - configureHangfireInstrumentationOptions?.Invoke(options); + configure?.Invoke(options); Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute(options)); From c5b2adefa5f06d1908c23069b9f7dc3a4db0b2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 7 Apr 2023 06:56:38 +0200 Subject: [PATCH 0665/1499] [ResourceDetectors.Container] Release 1.0.0-beta.3 (#1132) --- src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index f3e5bf6ec8..09cff2b9b3 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.3 + +Released 2023-Apr-7 + * Going forward the NuGet package will be [`OpenTelemetry.ResourceDetectors.Container`](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Container). Older versions will remain at From 8d8be7004234e30d7dc07050bec94a64e24bbfd0 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Fri, 7 Apr 2023 01:14:06 -0700 Subject: [PATCH 0666/1499] [Exporter.Geneva][TldLogExporter] Update TldLogExporter to log eventId.Id as a PartB field (#1134) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ .../TLDExporter/TldLogExporter.cs | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index e66996a40a..47a2080158 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* TldLogExporter to export `eventId.Id` as a Part B field instead of Part C + field. + ([#1134](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1134)) + ## 1.5.0-alpha.2 Released 2023-Mar-29 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 415891a9c2..d4238b86f7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -296,6 +296,13 @@ internal void SerializeLogRecord(LogRecord logRecord) eb.AddUInt8("severityNumber", GetSeverityNumber(logLevel)); eb.AddCountedAnsiString("name", categoryName, Encoding.UTF8); + var eventId = logRecord.EventId; + if (eventId != default) + { + eb.AddInt32("eventId", eventId.Id); + partBFieldsCount++; + } + byte hasEnvProperties = 0; bool bodyPopulated = false; @@ -395,13 +402,6 @@ internal void SerializeLogRecord(LogRecord logRecord) eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); } - var eventId = logRecord.EventId; - if (eventId != default) - { - eb.AddInt32("eventId", eventId.Id); - partCFieldsCount++; - } - eb.SetStructFieldCount(partCFieldsCountPatch, (byte)partCFieldsCount); } From 18ba3ba4985e3058cefd5a22e46295d901fa204a Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 7 Apr 2023 10:22:49 -0700 Subject: [PATCH 0667/1499] [Exporter.Geneva] Fix changelog (#1136) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 47a2080158..3592898456 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,6 +6,14 @@ field. ([#1134](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1134)) +## 1.4.1 + +Released 2023-Mar-29 + +* Relaxed table name mapping validation rules to restore the previous behavior + from version 1.3.0. + ([#1120](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1120)) + ## 1.5.0-alpha.2 Released 2023-Mar-29 @@ -14,8 +22,8 @@ Released 2023-Mar-29 ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1099)) * Relaxed table name mapping validation rules to restore the previous behavior - from version 1.3.0. ([Issue - #1105](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1105)) + from version 1.3.0. + ([#1109](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1109)) * Add support for exporting metrics to more than a single account/namespace combination using a single GenevaMetricExporter instance. Users can now export From be07337e16cc34e18ad731d2782f8d6e735f6732 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 10 Apr 2023 23:01:29 -0700 Subject: [PATCH 0668/1499] [PersistentStorage.FileSystem] fix directory size bug (#1133) --- .../CHANGELOG.md | 5 +- .../DirectorySizeTracker.cs | 86 +++++++++++++++++++ .../FileBlob.cs | 12 ++- .../FileBlobProvider.cs | 14 +-- .../PersistentStorageHelper.cs | 59 +------------ .../DirectorySizeTrackerTests.cs | 60 +++++++++++++ .../FileBlobProviderTests.cs | 9 +- 7 files changed, 176 insertions(+), 69 deletions(-) create mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs create mode 100644 test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index 380611ae50..ec38a42e07 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -2,8 +2,11 @@ ## 1.0.0-beta.2 (Unreleased) +* Fix a bug affecting the directory size when multiple `FileBlobProvider`s + were in a single process. [(#1133)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1133) + * `FileBlobProvider` will now use the path provided during initialization as is -* for storing blobs, without adding additional hash of current user and process. + for storing blobs, without adding additional hash of current user and process. ([#1110](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1110)) * Going forward the NuGet package will be diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs new file mode 100644 index 0000000000..7d942ec7e9 --- /dev/null +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs @@ -0,0 +1,86 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.IO; +using System.Threading; + +namespace OpenTelemetry.PersistentStorage.FileSystem; + +/// +/// Tracks the available storage in a specified directory. +/// +internal class DirectorySizeTracker +{ + private readonly long maxSizeInBytes; + private readonly string path; + private long directoryCurrentSizeInBytes; + + public DirectorySizeTracker(long maxSizeInBytes, string path) + { + this.maxSizeInBytes = maxSizeInBytes; + this.path = path; + this.directoryCurrentSizeInBytes = CalculateFolderSize(path); + } + + public void FileAdded(long fileSizeInBytes) => Interlocked.Add(ref this.directoryCurrentSizeInBytes, fileSizeInBytes); + + public void FileRemoved(long fileSizeInBytes) => Interlocked.Add(ref this.directoryCurrentSizeInBytes, fileSizeInBytes * -1); + + public bool IsSpaceAvailable(out long currentSizeInBytes) + { + currentSizeInBytes = Interlocked.Read(ref this.directoryCurrentSizeInBytes); + return currentSizeInBytes < this.maxSizeInBytes; + } + + public void RecountCurrentSize() + { + var size = CalculateFolderSize(this.path); + Interlocked.Exchange(ref this.directoryCurrentSizeInBytes, size); + } + + internal static long CalculateFolderSize(string path) + { + if (!Directory.Exists(path)) + { + return 0; + } + + long directorySize = 0; + try + { + foreach (string file in Directory.EnumerateFiles(path)) + { + if (File.Exists(file)) + { + FileInfo fileInfo = new FileInfo(file); + directorySize += fileInfo.Length; + } + } + + foreach (string dir in Directory.GetDirectories(path)) + { + directorySize += CalculateFolderSize(dir); + } + } + catch (Exception ex) + { + PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), "Error calculating folder size", ex); + } + + return directorySize; + } +} diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs index 2b18bb87a4..b3e2258afc 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs @@ -28,14 +28,22 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; /// public class FileBlob : PersistentBlob { + private readonly DirectorySizeTracker? directorySizeTracker; + /// /// Initializes a new instance of the /// class. /// /// Absolute file path of the blob. public FileBlob(string fullPath) + : this(fullPath, null) + { + } + + internal FileBlob(string fullPath, DirectorySizeTracker? directorySizeTracker) { this.FullPath = fullPath; + this.directorySizeTracker = directorySizeTracker; } public string FullPath { get; private set; } @@ -80,6 +88,7 @@ protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = return false; } + this.directorySizeTracker?.FileAdded(buffer.LongLength); return true; } @@ -113,7 +122,8 @@ protected override bool OnTryDelete() { try { - PersistentStorageHelper.RemoveFile(this.FullPath); + PersistentStorageHelper.RemoveFile(this.FullPath, out var fileSize); + this.directorySizeTracker?.FileRemoved(fileSize); } catch (Exception ex) { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index 188defef62..2b6d053aad 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -32,7 +32,7 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; public class FileBlobProvider : PersistentBlobProvider, IDisposable { internal readonly string DirectoryPath; - private readonly long maxSizeInBytes; + private readonly DirectorySizeTracker directorySizeTracker; private readonly long retentionPeriodInMilliseconds; private readonly int writeTimeoutInMilliseconds; private readonly Timer maintenanceTimer; @@ -94,7 +94,7 @@ public FileBlobProvider( // TODO: Validate time period values this.DirectoryPath = PersistentStorageHelper.CreateSubdirectory(path); - this.maxSizeInBytes = maxSizeInBytes; + this.directorySizeTracker = new DirectorySizeTracker(maxSizeInBytes, path); this.retentionPeriodInMilliseconds = retentionPeriodInMilliseconds; this.writeTimeoutInMilliseconds = writeTimeoutInMilliseconds; @@ -132,7 +132,7 @@ protected override IEnumerable OnGetBlobs() DateTime fileDateTime = PersistentStorageHelper.GetDateTimeFromBlobName(file); if (fileDateTime > retentionDeadline) { - yield return new FileBlob(file); + yield return new FileBlob(file, this.directorySizeTracker); } } } @@ -174,12 +174,14 @@ private void OnMaintenanceEvent(object? source, ElapsedEventArgs e) } PersistentStorageHelper.RemoveExpiredBlobs(this.DirectoryPath, this.retentionPeriodInMilliseconds, this.writeTimeoutInMilliseconds); + + // It is faster to calculate the directory size, instead of removing length of expired files. + this.directorySizeTracker.RecountCurrentSize(); } private bool CheckStorageSize() { - var size = PersistentStorageHelper.GetDirectorySize(); - if (size >= this.maxSizeInBytes) + if (!this.directorySizeTracker.IsSpaceAvailable(out long size)) { // TODO: check accuracy of size reporting. PersistentStorageEventSource.Log.PersistentStorageWarning( @@ -201,7 +203,7 @@ private bool CheckStorageSize() try { var blobFilePath = Path.Combine(this.DirectoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); - var blob = new FileBlob(blobFilePath); + var blob = new FileBlob(blobFilePath, this.directorySizeTracker); if (blob.TryWrite(buffer, leasePeriodMilliseconds)) { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs index 3ce0a062fa..60d31fd4e7 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs @@ -19,14 +19,11 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; -using System.Threading; namespace OpenTelemetry.PersistentStorage.FileSystem; internal static class PersistentStorageHelper { - private static long directorySize; - internal static void RemoveExpiredBlob(DateTime retentionDeadline, string filePath) { if (filePath.EndsWith(".blob", StringComparison.OrdinalIgnoreCase)) @@ -121,32 +118,20 @@ internal static void RemoveExpiredBlobs(string directoryPath, long retentionPeri RemoveExpiredBlob(retentionDeadline, file); } } - - // It is faster to calculate the directory size, instead of removing length of expired files. - var size = CalculateFolderSize(directoryPath); - Interlocked.Exchange(ref directorySize, size); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static long GetDirectorySize() - { - return Interlocked.Read(ref directorySize); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void WriteAllBytes(string path, byte[] buffer) { File.WriteAllBytes(path, buffer); - UpdateDirectorySize(buffer.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void RemoveFile(string fileName) + internal static void RemoveFile(string fileName, out long fileSize) { var fileInfo = new FileInfo(fileName); - var fileSize = fileInfo.Length; + fileSize = fileInfo.Length; fileInfo.Delete(); - UpdateDirectorySize(fileSize * -1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -158,17 +143,9 @@ internal static string GetUniqueFileName(string extension) internal static string CreateSubdirectory(string path) { Directory.CreateDirectory(path); - - directorySize = CalculateFolderSize(path); return path; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static long UpdateDirectorySize(long fileContentLength) - { - return Interlocked.Add(ref directorySize, fileContentLength); - } - internal static DateTime GetDateTimeFromBlobName(string filePath) { var fileName = Path.GetFileNameWithoutExtension(filePath); @@ -187,36 +164,4 @@ internal static DateTime GetDateTimeFromLeaseName(string filePath) DateTime.TryParseExact(time, "yyyy-MM-ddTHHmmss.fffffffZ", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime); return dateTime.ToUniversalTime(); } - - private static long CalculateFolderSize(string path) - { - if (!Directory.Exists(path)) - { - return 0; - } - - long directorySize = 0; - try - { - foreach (string file in Directory.EnumerateFiles(path)) - { - if (File.Exists(file)) - { - FileInfo fileInfo = new FileInfo(file); - directorySize += fileInfo.Length; - } - } - - foreach (string dir in Directory.GetDirectories(path)) - { - directorySize += CalculateFolderSize(dir); - } - } - catch (Exception ex) - { - PersistentStorageEventSource.Log.PersistentStorageException(nameof(PersistentStorageHelper), "Error calculating folder size", ex); - } - - return directorySize; - } } diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs new file mode 100644 index 0000000000..d349e4107a --- /dev/null +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs @@ -0,0 +1,60 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.IO; +using Xunit; + +namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; + +public class DirectorySizeTrackerTests +{ + [Fact] + public void VerifyDirectorySizeTracker() + { + var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); + testDirectory.Create(); + + var directorySizeTracker = new DirectorySizeTracker(maxSizeInBytes: 100, path: testDirectory.FullName); + + // new directory, expected to have space + Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize1)); + Assert.Equal(0, currentSize1); + + // add a file and check current space. + directorySizeTracker.FileAdded(30); + Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize2)); + Assert.Equal(30, currentSize2); + + // add a file and check current space. Here we've exceeded the configured max size + directorySizeTracker.FileAdded(100); + Assert.False(directorySizeTracker.IsSpaceAvailable(out long currentSize3)); + Assert.Equal(130, currentSize3); + + // remove a file and check current space. + directorySizeTracker.FileRemoved(50); + Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize4)); + Assert.Equal(80, currentSize4); + + // since we haven't actually written any files to disk, + // Recount will reset to zero. + directorySizeTracker.RecountCurrentSize(); + Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize5)); + Assert.Equal(0, currentSize5); + + // cleanup + testDirectory.Delete(); + } +} diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index f9aebd1dc4..036b321aa4 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -64,13 +64,14 @@ public void FileBlobProvider_E2E_Test() testDirectory.Delete(true); } - [Fact(Skip = "Unstable")] - public void FileBlobProvider_CreateBlobReturnsNullIfblobProviderIsFull() + [Fact] + public void FileBlobProvider_CreateBlobReturnsNullIfBlobProviderIsFull() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - using var blobProvider = new FileBlobProvider(testDirectory.FullName, 10000); + using var blobProvider = new FileBlobProvider(testDirectory.FullName, 100); - PersistentStorageHelper.UpdateDirectorySize(10000); + // write a file to fill up the configured max space. + Assert.True(blobProvider.TryCreateBlob(new byte[100], out _)); var data = Encoding.UTF8.GetBytes("Hello, World!"); From 59075730c47e12d2bee1a372a31a50e62f22b677 Mon Sep 17 00:00:00 2001 From: yan xu <58940428+xyq175com@users.noreply.github.com> Date: Tue, 11 Apr 2023 14:19:50 +0800 Subject: [PATCH 0669/1499] [Examples.AspNet] Update Prometheus exporter (#1107) Signed-off-by: Xu, Yan --- examples/AspNet/Examples.AspNet.csproj | 2 +- examples/AspNet/Global.asax.cs | 2 +- examples/AspNet/Views/Web.config | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 0d181ef44c..d7d8ac9dc1 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -84,7 +84,7 @@ - + diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index db50f5bd43..8250029c0d 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -77,7 +77,7 @@ protected void Application_Start() }); break; case "prometheus": - meterBuilder.AddPrometheusExporter(); + meterBuilder.AddPrometheusHttpListener(); break; default: meterBuilder.AddConsoleExporter((exporterOptions, metricReaderOptions) => diff --git a/examples/AspNet/Views/Web.config b/examples/AspNet/Views/Web.config index 6e67a6c67f..b9508f1106 100644 --- a/examples/AspNet/Views/Web.config +++ b/examples/AspNet/Views/Web.config @@ -1,4 +1,4 @@ - + @@ -9,7 +9,7 @@ - + @@ -34,7 +34,7 @@ - + From b90938d6704c78e82b8dd750a351f5e1410caa3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 17:20:11 -0700 Subject: [PATCH 0670/1499] Bump codecov/codecov-action from 3.1.1 to 3.1.2 (#1143) --- .github/workflows/dotnet-core-cov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 315acf1cef..1f71a5119c 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -48,7 +48,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - uses: codecov/codecov-action@v3.1.1 + - uses: codecov/codecov-action@v3.1.2 with: file: TestResults/Cobertura.xml env_vars: OS From 8e996b0ce0e272d4ebd133b2b62f26d1f1c2407a Mon Sep 17 00:00:00 2001 From: Evgeny Fedorov <25526458+evgenyfedorov2@users.noreply.github.com> Date: Wed, 12 Apr 2023 16:15:29 +0200 Subject: [PATCH 0671/1499] [Extensions.Enrichment] Update README.md in OpenTelemetry.Extensions.Enrichment (#1072) --- .../Examples.Enrichment.csproj | 18 ++ .../Examples.Enrichment/IMyService.cs | 22 +++ .../Examples.Enrichment/MyService.cs | 40 ++++ .../Examples.Enrichment/MyTraceEnricher.cs | 36 ++++ .../enrichment/Examples.Enrichment/Program.cs | 54 ++++++ opentelemetry-dotnet-contrib.sln | 10 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 +- .../BaseEnricher.cs | 2 +- .../EnrichmentActions.cs | 2 +- .../README.md | 177 +++++++++++++++++- .../TraceEnricher.cs | 7 - .../MyTraceEnricher.cs | 2 +- .../MyTraceEnricher2.cs | 2 +- 15 files changed, 363 insertions(+), 18 deletions(-) create mode 100644 examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj create mode 100644 examples/enrichment/Examples.Enrichment/IMyService.cs create mode 100644 examples/enrichment/Examples.Enrichment/MyService.cs create mode 100644 examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs create mode 100644 examples/enrichment/Examples.Enrichment/Program.cs diff --git a/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj b/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj new file mode 100644 index 0000000000..0729f1a64b --- /dev/null +++ b/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj @@ -0,0 +1,18 @@ + + + + Exe + net6.0 + enable + + + + + + + + + + + + diff --git a/examples/enrichment/Examples.Enrichment/IMyService.cs b/examples/enrichment/Examples.Enrichment/IMyService.cs new file mode 100644 index 0000000000..9e3a2ab789 --- /dev/null +++ b/examples/enrichment/Examples.Enrichment/IMyService.cs @@ -0,0 +1,22 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace Examples.Enrichment; + +public interface IMyService +{ + public (string Service, string Status) MyDailyStatus(); +} diff --git a/examples/enrichment/Examples.Enrichment/MyService.cs b/examples/enrichment/Examples.Enrichment/MyService.cs new file mode 100644 index 0000000000..3e4071d1f8 --- /dev/null +++ b/examples/enrichment/Examples.Enrichment/MyService.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; + +namespace Examples.Enrichment; + +internal sealed class MyService : IMyService +{ + private readonly List statuses = new() + { + "Blocked", + "No blockers", + "Out of office", + }; + + /// + /// Returns daily status. + /// + /// A tuple with service name and status. + public (string Service, string Status) MyDailyStatus() + { + var statusNumber = Random.Shared.Next(0, this.statuses.Count); + return new(nameof(MyService), this.statuses[statusNumber]); + } +} diff --git a/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs b/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs new file mode 100644 index 0000000000..496639c3f2 --- /dev/null +++ b/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Extensions.Enrichment; + +namespace Examples.Enrichment; + +internal sealed class MyTraceEnricher : TraceEnricher +{ + private readonly IMyService myService; + + public MyTraceEnricher(IMyService myService) + { + this.myService = myService; + } + + public override void Enrich(in TraceEnrichmentBag bag) + { + var (service, status) = this.myService.MyDailyStatus(); + + bag.Add(service, status); + } +} diff --git a/examples/enrichment/Examples.Enrichment/Program.cs b/examples/enrichment/Examples.Enrichment/Program.cs new file mode 100644 index 0000000000..3d7b2e7cad --- /dev/null +++ b/examples/enrichment/Examples.Enrichment/Program.cs @@ -0,0 +1,54 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry; +using OpenTelemetry.Extensions.Enrichment; +using OpenTelemetry.Trace; + +namespace Examples.Enrichment; + +public static class Program +{ + public static void Main() + { + // Create an ActivitySource. + using var myActivitySource = new ActivitySource("MyCompany.MyProduct.MyLibrary"); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + + // Register MyService in the DI container. + .ConfigureServices(services => services.AddSingleton()) + + // Register the ActivitySource as usual. + .AddSource("MyCompany.MyProduct.MyLibrary") + + // Register an enricher class. + // Important: AddTraceEnricher() must be called before any exporeters. + .AddTraceEnricher() + + // Add Console exporter to see the output of this example. + .AddConsoleExporter() + .Build(); + + // Create an Activity and add some tags to it. + using var activity = myActivitySource.StartActivity("SayHello"); + activity?.SetTag("hello", "world"); + + // Tags from the enricher class will be added automatically to the created Activity. + } +} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index d03f11d7c4..994981773d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -263,6 +263,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Sampler.AWS.T EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Benchmarks", "test\OpenTelemetry.Exporter.OneCollector.Benchmarks\OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj", "{C42868C8-968A-473F-AC39-AC97C5D47E84}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.Enrichment", "examples\enrichment\Examples.Enrichment\Examples.Enrichment.csproj", "{9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "enrichment", "enrichment", "{93503FAF-D43D-48C0-818C-92EB90F7606B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -569,6 +573,10 @@ Global {C42868C8-968A-473F-AC39-AC97C5D47E84}.Debug|Any CPU.Build.0 = Debug|Any CPU {C42868C8-968A-473F-AC39-AC97C5D47E84}.Release|Any CPU.ActiveCfg = Release|Any CPU {C42868C8-968A-473F-AC39-AC97C5D47E84}.Release|Any CPU.Build.0 = Release|Any CPU + {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -657,6 +665,8 @@ Global {54002B08-F6AE-4B2B-AB0C-86E5A05926A3} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {48C29501-3FA2-46A7-B5BA-D282EA8F1274} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {C42868C8-968A-473F-AC39-AC97C5D47E84} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA} = {93503FAF-D43D-48C0-818C-92EB90F7606B} + {93503FAF-D43D-48C0-818C-92EB90F7606B} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt index bc0e2eeb73..21468d4cd0 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ -abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(T enrichmentBag) -> void +abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(in T enrichmentBag) -> void Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions OpenTelemetry.Extensions.Enrichment.BaseEnricher OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void @@ -17,4 +17,3 @@ static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilde static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(ref OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag traceEnrichmentBag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt index bc0e2eeb73..21468d4cd0 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ -abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(T enrichmentBag) -> void +abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(in T enrichmentBag) -> void Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions OpenTelemetry.Extensions.Enrichment.BaseEnricher OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void @@ -17,4 +17,3 @@ static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilde static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(ref OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag traceEnrichmentBag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index bc0e2eeb73..21468d4cd0 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ -abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(T enrichmentBag) -> void +abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(in T enrichmentBag) -> void Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions OpenTelemetry.Extensions.Enrichment.BaseEnricher OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void @@ -17,4 +17,3 @@ static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilde static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(ref OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag traceEnrichmentBag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs index c1efec51a9..4c9db69956 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs @@ -22,5 +22,5 @@ protected BaseEnricher() { } - public abstract void Enrich(T enrichmentBag); + public abstract void Enrich(in T enrichmentBag); } diff --git a/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs b/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs index c615155cd5..f83c2dec3b 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs @@ -31,7 +31,7 @@ public EnrichmentActions(IEnumerable> actions) this.actions = actions.ToArray(); } - public override void Enrich(TraceEnrichmentBag enrichmentBag) + public override void Enrich(in TraceEnrichmentBag enrichmentBag) { for (int i = 0; i < this.actions.Length; i++) { diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index 6a8ed5095c..312a71775e 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -6,6 +6,181 @@ Contains OpenTelemetry .NET SDK telemetry enrichment framework which is used for enrichment of traces. +## Introduction + +Telemetry enrichment attaches various types of information to traces. +You can use the telemetry enrichment framework to attach any custom information +that you would like to be present in all of your traces. + +With telemetry enrichment framework, you don't need to worry about attaching +the information carefully to each telemetry object you touch. +Instead, if you implement your enricher class, it takes care of the details +automatically. You simply register your class with the enrichment framework +and the enrichment framework will make sure to call the `Enrich()` method of your +class every time there is an `Activity` in your app. + ## Traces -TBD +Currently this package supports trace enrichment only. + +### Steps to enable OpenTelemetry.Extensions.Enrichment + +You can view an example project using Enrichment at +[Examples.Enrichment](../../examples/enrichment/Examples.Enrichment/Program.cs). + +### Step 1: Install package + +Download the `OpenTelemetry.Extensions.Enrichment` package: + +```shell +dotnet add package OpenTelemetry.Extensions.Enrichment --prerelease +``` + +### Step 2: Create enricher class + +Create your custom enricher class that inherits from the `TraceEnricher` class +and override the `public abstract void Enrich(in TraceEnrichmentBag bag)` method. +Optionally, inject other services you enricher class depends on: + +```csharp +internal sealed class MyTraceEnricher : TraceEnricher +{ + private readonly IMyService myService; + + public MyTraceEnricher(IMyService myService) + { + this.myService = myService; + } + + public override void Enrich(in TraceEnrichmentBag bag) + { + var (service, status) = this.myService.MyDailyStatus(); + + bag.Add(service, status); + } +} +``` + +An example of IMyService implementation is available +[here](../../examples/enrichment/Examples.Enrichment/MyService.cs). + +For every `Activity`, the `Enrich()` +method is guaranteed to be called exactly once. Semantically, +for the example above it means that a new [tag object](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.tagobjects?view=net-7.0) +with the service key and the status value will be added to every `Activity` +in your application. + +### Step 3: Register enricher class + +Add your custom enricher class to the `TracerProviderBuilder` by calling the +`AddTraceEnricher()` method. Configure other services via +`ConfigureServices()`, add `ActivitySource` and an exporter as usual: + +```csharp +using var MyActivitySource = new ActivitySource("MyCompany.MyProduct.MyLibrary"); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton()) + .AddSource("MyCompany.MyProduct.MyLibrary") + .AddTraceEnricher() + .AddConsoleExporter() + .Build(); +``` + +Alternatively, you can add your custom enricher to the `IServiceCollection` +(as well as `ActivitySource` and exporter), typically +this is done inside the [ConfigureServices()](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.hosting.startupbase.configureservices) +method: + +```csharp +public void ConfigureServices(IServiceCollection services) +{ + services.AddSingleton(); + services.AddOpenTelemetry().WithTracing((builder) => builder + .AddSource("MyCompany.MyProduct.MyLibrary") + .AddTraceEnricher() + .AddConsoleExporter()); +} +``` + +> **Note** +> The `AddTraceEnricher()` method call should be done *before* registering exporter +related Activity processors. + +### Step 4: Usage + +Create an `Activity` and add tags as usual: + +```csharp +using var activity = myActivitySource.StartActivity("SayHello"); +activity?.SetTag("hello", "world"); +``` + +Run your application and verify that the `MyService` tag is added to `Activity`: + +```shell +Activity.TraceId: 0e1dc24e2e63796bfc8186e24f916f5f +Activity.SpanId: bfcbf9d5746009d6 +Activity.TraceFlags: Recorded +Activity.ActivitySourceName: MyCompany.MyProduct.MyLibrary +Activity.DisplayName: SayHello +Activity.Kind: Internal +Activity.StartTime: 2023-03-20T09:39:21.9642338Z +Activity.Duration: 00:00:00.0016887 +Activity.Tags: + hello: world + MyService: No blockers +Resource associated with Activity: + service.name: unknown_service:Examples.Enrichment +``` + +### Extension methods + +Extension methods with different signatures are provided to enable common registration +styles. The methods relying on `TracerProviderBuilder` are for OpenTelemetry +.NET component authors. Conversely, the methods that utilize `IServiceCollection` +are for general library authors who may not have a reference to +`TracerProviderBuilder` or who want to register enrichers with other general services. +Anyway, both ways can be used within the same app. + +In case you would like to use a comprehensive enricher class that may require +injection or interaction with other classes, you may utilize either of these +two methods. Both methods take a type T parameter to specify the type of your +enricher class. In this case, the enricher class will be created for you by +Dependency Injection: + +```csharp +public static AddTraceEnricher(this IServiceCollection services) +public static AddTraceEnricher(this TracerProviderBuilder builder) +``` + +If you prefer to instantiate your enricher class on your own, you may use one of +these methods which allow for the usage of pre-existing enricher objects: + +```csharp +public static AddTraceEnricher(this IServiceCollection services, TraceEnricher enricher) +public static AddTraceEnricher(this TracerProviderBuilder builder, TraceEnricher enricher) +``` + +If you only need to enrich a small amount of data, it may not be necessary to create +an enricher class. Instead, you can make use of the following methods which accept +an `Action` delegate: + +```csharp +public static AddTraceEnricher(this IServiceCollection services, Action enrichmentAction) +public static AddTraceEnricher(this TracerProviderBuilder builder, Action enrichmentAction) +``` + +If you would rather use a factory method to instantiate your enricher class, +with the possibility of interacting with `IServiceProvider,` you can utilize one +of these two methods: + +```csharp +public static AddTraceEnricher(this IServiceCollection services, Func enricherImplementationFactory) +public static AddTraceEnricher(this TracerProviderBuilder builder, Func enricherImplementationFactory) +``` + +## Recommendations and best practices + +You can add any number of custom enrichers, but it is advisable to only include +properties that are truly beneficial to prevent an excessive increase in the +number of tags associated with each `Activity`. diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs index bbd6b2445b..6bd8c6b520 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs @@ -14,8 +14,6 @@ // limitations under the License. // -using System; - namespace OpenTelemetry.Extensions.Enrichment; public abstract class TraceEnricher : BaseEnricher @@ -23,9 +21,4 @@ public abstract class TraceEnricher : BaseEnricher protected TraceEnricher() { } - - public virtual void Enrich(ref TraceEnrichmentBag traceEnrichmentBag) - { - throw new NotImplementedException(); - } } diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs index c225b38b9d..35a4c8fe3d 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs @@ -22,7 +22,7 @@ internal class MyTraceEnricher : TraceEnricher public int TimesCalled { get; private set; } - public override void Enrich(TraceEnrichmentBag enrichmentBag) + public override void Enrich(in TraceEnrichmentBag enrichmentBag) { enrichmentBag.Add(Key, ++this.TimesCalled); } diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs index 8631f2f6bf..fd50a9d61b 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs @@ -22,7 +22,7 @@ internal class MyTraceEnricher2 : TraceEnricher public int TimesCalled { get; private set; } - public override void Enrich(TraceEnrichmentBag enrichmentBag) + public override void Enrich(in TraceEnrichmentBag enrichmentBag) { enrichmentBag.Add(Key, ++this.TimesCalled); } From 13ae94480a22640d302c6795d6f8b93b6cce6c72 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 13 Apr 2023 21:43:43 -0700 Subject: [PATCH 0672/1499] [PersistentStorage] Update changelog for release storage (#1144) --- .../CHANGELOG.md | 6 +++++- src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md index 2e059f6ad4..a319aa4597 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog -## 1.0.0-beta.2 (Unreleased) +## Unreleased + +## 1.0.0-beta.2 + +Released 2023-Apr-14 * Going forward the NuGet package will be [`OpenTelemetry.PersistentStorage.Abstractions`](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions). diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index ec38a42e07..3e67122ba0 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog - OpenTelemetry.PersistentStorage.FileSystem -## 1.0.0-beta.2 (Unreleased) +## Unreleased * Fix a bug affecting the directory size when multiple `FileBlobProvider`s were in a single process. [(#1133)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1133) From 6b228e0a02e7752a327c100ef630a6138e4089dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 14 Apr 2023 07:03:02 +0200 Subject: [PATCH 0673/1499] [PersistentStorage.*] Fix release tags in csproj (#1145) --- .../OpenTelemetry.PersistentStorage.Abstractions.csproj | 2 +- .../OpenTelemetry.PersistentStorage.FileSystem.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index f23566e9bf..b33f879639 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -7,7 +7,7 @@ net6.0;$(TargetFrameworks) true OpenTelemetry Persistent Storage Abstractions - Extensions.PersistentStorage.Abstractions- + PersistentStorage.Abstractions- $(NoWarn),1591 enable true diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index c3c1452e07..a3488345ca 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -7,7 +7,7 @@ net6.0;$(TargetFrameworks) true OpenTelemetry Persistent Storage - Extensions.PersistentStorage- + PersistentStorage.FileSystem- From d6bf4887b2a5ebf23bcc9fd8d349118c1e9b1cba Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 17 Apr 2023 14:14:05 -0700 Subject: [PATCH 0674/1499] Changelog for release PersistentStorage.Filesystem (#1146) --- src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md | 4 ++++ .../OpenTelemetry.PersistentStorage.FileSystem.csproj | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index 3e67122ba0..e50ba87d19 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2023-Apr-17 + * Fix a bug affecting the directory size when multiple `FileBlobProvider`s were in a single process. [(#1133)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1133) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index a3488345ca..5b86be8b0a 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -18,7 +18,7 @@ - + From f9528610ac99eb67f730cbe3ba810026b446b840 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 17 Apr 2023 15:14:34 -0700 Subject: [PATCH 0675/1499] [ResourceDetectors.Azure] Add additional attributes to Appservice detector (#1148) --- .../AppServiceResourceDetector.cs | 35 +++++++------- .../AzureResourceDetectorTests.cs | 47 ++++++++++++++----- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index 88f5597e4f..e71e8842a0 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -26,34 +26,33 @@ namespace OpenTelemetry.ResourceDetectors.Azure; /// public sealed class AppServiceResourceDetector : IResourceDetector { + internal static readonly IReadOnlyDictionary AppServiceResourceAttributes = new Dictionary + { + ["appSrv_SiteName"] = "WEBSITE_SITE_NAME", + [ResourceSemanticConventions.AttributeServiceName] = "WEBSITE_SITE_NAME", + [ResourceSemanticConventions.AttributeServiceInstance] = "WEBSITE_INSTANCE_ID", + ["appSrv_SlotName"] = "WEBSITE_SLOT_NAME", + ["appSrv_wsStamp"] = "WEBSITE_HOME_STAMPNAME", + ["appSrv_wsHost"] = "WEBSITE_HOSTNAME", + ["appSrv_wsOwner"] = "WEBSITE_OWNER_NAME", + ["appSrv_ResourceGroup"] = "WEBSITE_RESOURCE_GROUP", + }; + /// public Resource Detect() { - List>? attributeList = null; + List> attributeList = new(); try { - string? serviceName = null; - string? serviceInstanceId = null; - - // https://learn.microsoft.com/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet#app-environment - serviceName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); - serviceInstanceId = Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"); - if (serviceName != null) + foreach (var kvp in AppServiceResourceAttributes) { - attributeList = new(); - - attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, serviceName)); - - if (serviceInstanceId != null) + var attributeValue = Environment.GetEnvironmentVariable(kvp.Value); + if (attributeValue != null) { - attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceInstance, serviceInstanceId)); + attributeList.Add(new KeyValuePair(kvp.Key, attributeValue)); } } - else - { - return Resource.Empty; - } } catch { diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index 2e91877be4..42404a0a1a 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using OpenTelemetry.Resources; -using OpenTelemetry.Trace; using Xunit; namespace OpenTelemetry.ResourceDetectors.Azure.Tests; @@ -27,24 +26,46 @@ public class AzureResourceDetectorTests : IDisposable [Fact] public void AppServiceResourceDetectorReturnsResourceWithAttributes() { - Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "AzureAppService"); - Environment.SetEnvironmentVariable("WEBSITE_INSTANCE_ID", "AzureInstance"); + try + { + foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) + { + if (kvp.Value == "WEBSITE_SITE_NAME") + { + continue; + } + + Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); + } + + // Special case for service.name and appSrv_SiteName attribute + Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "ServiceName"); + } + catch + { + } + var resource = ResourceBuilder.CreateEmpty().AddDetector(new AppServiceResourceDetector()).Build(); Assert.NotNull(resource); - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "AzureAppService"), resource.Attributes); - Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceInstance, "AzureInstance"), resource.Attributes); - } - [Fact] - public void AppServiceResourceDetectorReturnsNullOutsideOfAppService() - { - var resource = new AppServiceResourceDetector().Detect(); - Assert.Empty(resource.Attributes); + foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) + { + if (kvp.Value == "WEBSITE_SITE_NAME") + { + Assert.Contains(new KeyValuePair(kvp.Key, "ServiceName"), resource.Attributes); + } + else + { + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + } + } } public void Dispose() { - Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", null); - Environment.SetEnvironmentVariable("WEBSITE_INSTANCE_ID", null); + foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) + { + Environment.SetEnvironmentVariable(kvp.Value, null); + } } } From 7c4ce8b379a693db0a41d233c2d737f217e1542f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 19 Apr 2023 10:56:30 -0700 Subject: [PATCH 0676/1499] [Exporter.Geneva] Update GenevaLogExporter to export eventName (#1135) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 5 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 5 + .../netstandard2.0/PublicAPI.Unshipped.txt | 5 + .../CHANGELOG.md | 4 + .../EventNameExportMode.cs | 43 ++++++ .../GenevaExporterOptions.cs | 2 + .../MsgPackExporter/MsgPackLogExporter.cs | 23 ++- .../GenevaLogExporterTests.cs | 140 ++++++++++++++++++ 8 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2..1fd2dcd539 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt index e69de29bb2..4ca0ea2c19 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..1fd2dcd539 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,5 @@ +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 3592898456..557aa89572 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,6 +6,10 @@ field. ([#1134](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1134)) +* Update GenevaLogExporter to export `eventId.Name` as the value for Part A + `name` field when the `EventNameExportMode` option is set to `ExportAsPartAName`. + ([#1135](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1135)) + ## 1.4.1 Released 2023-Mar-29 diff --git a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs new file mode 100644 index 0000000000..7e9e18528f --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Exporter.Geneva; + +[Flags] +public enum EventNameExportMode +{ + /// + /// GenevaExporter will not export eventId.Name + /// if the enum instance has no other flag selected. + /// + None = 0, + + /// + /// GenevaExporter will export eventId.Name + /// as Part A name field when this flag is selected. + /// + ExportAsPartAName = 1, + + /* Note: This might be added in future. + /// + /// GenevaExporter will export eventId.Name + /// as the table name when this flag is selected. + /// + ExportAsTableName = 2, + */ +} diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 5d781ec8ac..82cdb3a3ac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -36,6 +36,8 @@ public class GenevaExporterOptions public ExceptionStackExportMode ExceptionStackExportMode { get; set; } + public EventNameExportMode EventNameExportMode { get; set; } + public IReadOnlyDictionary TableNameMappings { get => this._tableNameMappings; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index b8c9534796..2c353b8337 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -36,6 +36,7 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", }; + private readonly bool m_shouldExportEventName; private readonly TableNameSerializer m_tableNameSerializer; private readonly Dictionary m_customFields; private readonly Dictionary m_prepopulatedFields; @@ -53,6 +54,8 @@ public MsgPackLogExporter(GenevaExporterOptions options) this.m_tableNameSerializer = new(options, defaultTableName: "Log"); this.m_exportExceptionStack = options.ExceptionStackExportMode; + this.m_shouldExportEventName = (options.EventNameExportMode & EventNameExportMode.ExportAsPartAName) != 0; + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); switch (connectionStringBuilder.Protocol) { @@ -202,9 +205,22 @@ internal int SerializeLogRecord(LogRecord logRecord) } // Part A - core envelope - cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); - cntFields += 1; + var eventId = logRecord.EventId; + bool hasEventId = eventId != default; + + if (hasEventId && this.m_shouldExportEventName && !string.IsNullOrWhiteSpace(eventId.Name)) + { + // Export `eventId.Name` as the value for `env_name` + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventId.Name); + cntFields += 1; + } + else + { + // Export the table name as the value for `env_name` + cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventName); + cntFields += 1; + } cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_time"); cursor = MessagePackSerializer.SerializeUtcDateTime(buffer, cursor, timestamp); // LogRecord.Timestamp should already be converted to UTC format in the SDK @@ -343,8 +359,7 @@ internal int SerializeLogRecord(LogRecord logRecord) MessagePackSerializer.WriteUInt16(buffer, idxMapSizeEnvPropertiesPatch, envPropertiesCount); } - var eventId = logRecord.EventId; - if (eventId != default) + if (hasEventId) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "eventId"); cursor = MessagePackSerializer.SerializeInt32(buffer, cursor, eventId.Id); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 04f3c055db..aba31bb007 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -50,6 +50,13 @@ public void ExportExceptionStackDefaultIsDrop() Assert.Equal(ExceptionStackExportMode.Drop, exporterOptions.ExceptionStackExportMode); } + [Fact] + public void ExportEventNameDefaultIsNone() + { + GenevaExporterOptions exporterOptions = new GenevaExporterOptions(); + Assert.Equal(EventNameExportMode.None, exporterOptions.EventNameExportMode); + } + [Fact] public void SpecialCharactersInTableNameMappings() { @@ -1009,6 +1016,139 @@ public void SerializationTestForException() } } + [Theory] + [InlineData(EventNameExportMode.None, false)] + [InlineData(EventNameExportMode.None, true)] + [InlineData(EventNameExportMode.ExportAsPartAName, false)] + [InlineData(EventNameExportMode.ExportAsPartAName, true)] + public void SerializationTestForEventName(EventNameExportMode eventNameExportMode, bool hasTableNameMapping) + { + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions(); + exporterOptions.EventNameExportMode = eventNameExportMode; + + if (hasTableNameMapping) + { + exporterOptions.TableNameMappings = new Dictionary() + { + ["*"] = "CustomTableName", + }; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + options.EventNameExportMode = exporterOptions.EventNameExportMode; + + if (hasTableNameMapping) + { + options.TableNameMappings = exporterOptions.TableNameMappings; + } + }); + options.AddInMemoryExporter(logRecordList); + })); + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new MsgPackLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); + + // ACT + // This is treated as structured logging as the state can be converted to IReadOnlyList> + + #region Test for `ILogger.Log` + logger.Log( + logLevel: LogLevel.Information, + eventId: new EventId(1, "TestEventNameWithLogMethod"), + state: null, + exception: new Exception("Exception Message"), + formatter: null); + + // VALIDATE + Assert.Single(logRecordList); + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var eventName = GetField(fluentdData, "env_name"); + + if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) + { + Assert.Equal("TestEventNameWithLogMethod", eventName); + } + else + { + Assert.Equal(hasTableNameMapping ? "CustomTableName" : "Log", eventName); + } + + #endregion + + logRecordList.Clear(); + + #region Test for extension method + logger.LogInformation(eventId: new EventId(1, "TestEventNameWithLogExtensionMethod"), "Hello from {Name} {Price}.", "tomato", 2.99); + + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + eventName = GetField(fluentdData, "env_name"); + + if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) + { + Assert.Equal("TestEventNameWithLogExtensionMethod", eventName); + } + else + { + Assert.Equal(hasTableNameMapping ? "CustomTableName" : "Log", eventName); + } + #endregion + + logRecordList.Clear(); + + #region Test with eventName as null + logger.LogInformation(eventId: 1, "Hello from {Name} {Price}.", "tomato", 2.99); + + _ = exporter.SerializeLogRecord(logRecordList[0]); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + eventName = GetField(fluentdData, "env_name"); + Assert.Equal(hasTableNameMapping ? "CustomTableName" : "Log", eventName); + #endregion + + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + [Fact] public void SerializationTestForEventId() { From e62e82e215e1cea375af05b6703d379d7ee5b27d Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 19 Apr 2023 16:28:50 -0700 Subject: [PATCH 0677/1499] [ResourceDetectors.Azure] Readme + Changelog (#1150) --- .../CHANGELOG.md | 4 +++ .../README.md | 29 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index ef8912a5bc..32baee3f54 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.1 + +Released 2023-Apr-19 + * Add AppService resource detector. ([#989](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/989)) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 3389bf6c6a..660d6b595b 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -1,3 +1,30 @@ # Resource Detectors for Azure cloud environments -TODO +This package contains [Resource +Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) +for applications running in Azure environment. + +## Installation + +```shell +dotnet add package --prerelease OpenTelemetry.ResourceDetectors.Azure +``` + +## Appservice Resource Detector + +Adds resource attributes for the applications running in Appservice. The +following example shows how to add `AppServiceResourceDetector` to +`TracerProvider` configuration: + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.Azure; +using OpenTelemetry.Resources; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .SetResourceBuilder(ResourceBuilder + .CreateDefault() + .AddDetector(new AppServiceResourceDetector())) + .Build(); +``` From 87c3b0520dcf6c79ec7aec641aa67058a6ae1804 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 19 Apr 2023 17:07:57 -0700 Subject: [PATCH 0678/1499] [Exporter.Geneva] Update CHANGELOG for 1.5.0-alpha.3 (#1154) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 557aa89572..7ce77b5913 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,12 +2,17 @@ ## Unreleased +## 1.5.0-alpha.3 + +Released 2023-Apr-19 + * TldLogExporter to export `eventId.Id` as a Part B field instead of Part C field. ([#1134](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1134)) * Update GenevaLogExporter to export `eventId.Name` as the value for Part A - `name` field when the `EventNameExportMode` option is set to `ExportAsPartAName`. + `name` field when the `EventNameExportMode` option is set to + `ExportAsPartAName`. ([#1135](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1135)) ## 1.4.1 From 47208ba3de7229f4416b84003954383432b9cf23 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Wed, 19 Apr 2023 17:38:54 -0700 Subject: [PATCH 0679/1499] [Exporter.Geneva] Update component owners (#1155) --- .github/component_owners.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index acf4632141..5cee7a9e64 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -11,7 +11,6 @@ components: src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch - - mic-max - reyang - utpilla - Yun-Ting @@ -75,21 +74,18 @@ components: test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch - - mic-max - reyang - utpilla - Yun-Ting test/OpenTelemetry.Exporter.Geneva.Stress/: - cijothomas - codeblanch - - mic-max - reyang - utpilla - Yun-Ting test/OpenTelemetry.Exporter.Geneva.Tests/: - cijothomas - codeblanch - - mic-max - reyang - utpilla - Yun-Ting From 7a9636b7e3ace069472d52028954c78c201ad3d2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 20 Apr 2023 10:50:05 -0700 Subject: [PATCH 0680/1499] Move shared files to a folder instead of keeping them in a project (#1149) --- build/Common.props | 22 ++++++------- opentelemetry-dotnet-contrib.sln | 31 +++++++++++++------ ...elemetry.Contrib.Extensions.AWSXRay.csproj | 2 +- ...lemetry.Contrib.Instrumentation.AWS.csproj | 4 +-- .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../OpenTelemetry.Contrib.Shared.csproj | 16 ---------- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- ...OpenTelemetry.Exporter.OneCollector.csproj | 4 +-- .../OpenTelemetry.Exporter.Stackdriver.csproj | 2 +- ...enTelemetry.Extensions.AzureMonitor.csproj | 2 +- ...OpenTelemetry.Extensions.Enrichment.csproj | 4 +-- .../OpenTelemetry.Extensions.csproj | 2 +- ...Telemetry.Instrumentation.AWSLambda.csproj | 4 +-- ...entation.AspNet.TelemetryHttpModule.csproj | 2 +- ...penTelemetry.Instrumentation.AspNet.csproj | 6 ++-- ...Telemetry.Instrumentation.Cassandra.csproj | 2 +- ...Instrumentation.ElasticsearchClient.csproj | 2 +- ...Instrumentation.EntityFrameworkCore.csproj | 2 +- ...metry.Instrumentation.EventCounters.csproj | 2 +- ...nTelemetry.Instrumentation.GrpcCore.csproj | 2 +- ...nTelemetry.Instrumentation.Hangfire.csproj | 2 +- ...Telemetry.Instrumentation.MySqlData.csproj | 6 ++-- .../OpenTelemetry.Instrumentation.Owin.csproj | 8 ++--- ...enTelemetry.Instrumentation.Process.csproj | 2 +- ...penTelemetry.Instrumentation.Quartz.csproj | 2 +- ...enTelemetry.Instrumentation.Runtime.csproj | 2 +- ....Instrumentation.StackExchangeRedis.csproj | 4 +-- .../OpenTelemetry.Instrumentation.Wcf.csproj | 2 +- ...etry.PersistentStorage.Abstractions.csproj | 2 +- ...emetry.PersistentStorage.FileSystem.csproj | 4 +-- ...enTelemetry.ResourceDetectors.Azure.csproj | 6 ++-- .../OpenTelemetry.Sampler.AWS.csproj | 2 +- .../ActivityInstrumentationHelper.cs | 0 .../DiagnosticSourceListener.cs | 0 .../DiagnosticSourceSubscriber.cs | 0 .../Api => Shared}/ExceptionExtensions.cs | 0 .../Guard.cs | 0 .../InstrumentationEventSource.cs | 0 .../IsExternalInit.cs | 0 .../ListenerHandler.cs | 0 .../MultiTypePropertyFetcher.cs | 0 .../NullableAttributes.cs | 0 .../PropertyFetcher.cs | 0 .../ResourceSemanticConventions.cs | 0 .../Api => Shared}/SemanticConventions.cs | 0 .../ServiceProviderExtensions.cs | 0 .../Api => Shared}/SpanAttributeConstants.cs | 0 .../Api => Shared}/SpanHelper.cs | 0 ...emetry.Instrumentation.AspNet.Tests.csproj | 2 +- 50 files changed, 77 insertions(+), 80 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/ActivityInstrumentationHelper.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/DiagnosticSourceListener.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/DiagnosticSourceSubscriber.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/Api => Shared}/ExceptionExtensions.cs (100%) rename src/{OpenTelemetry.Internal => Shared}/Guard.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/InstrumentationEventSource.cs (100%) rename src/{OpenTelemetry.Internal => Shared}/IsExternalInit.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/ListenerHandler.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/MultiTypePropertyFetcher.cs (100%) rename src/{OpenTelemetry.Internal => Shared}/NullableAttributes.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation => Shared}/PropertyFetcher.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/Api => Shared}/ResourceSemanticConventions.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/Api => Shared}/SemanticConventions.cs (100%) rename src/{OpenTelemetry.Contrib.Shared => Shared}/ServiceProviderExtensions.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/Api => Shared}/SpanAttributeConstants.cs (100%) rename src/{OpenTelemetry.Contrib.Shared/Api => Shared}/SpanHelper.cs (100%) diff --git a/build/Common.props b/build/Common.props index 78f7845324..07c8eaae50 100644 --- a/build/Common.props +++ b/build/Common.props @@ -55,20 +55,20 @@ - + - - - - - - - - - - + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 994981773d..b8556d00c5 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -13,7 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution global.json = global.json NuGet.config = NuGet.config opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj - examples\process-instrumentation\process-instrumentation.csproj = examples\process-instrumentation\process-instrumentation.csproj README.md = README.md EndProjectSection EndProject @@ -120,8 +119,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWS.Tests\OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj", "{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared", "src\OpenTelemetry.Contrib.Shared\OpenTelemetry.Contrib.Shared.csproj", "{F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{58D1DE55-B0A5-4BC4-AB37-09B1C7B26752}" @@ -263,10 +260,30 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Sampler.AWS.T EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector.Benchmarks", "test\OpenTelemetry.Exporter.OneCollector.Benchmarks\OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj", "{C42868C8-968A-473F-AC39-AC97C5D47E84}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.Enrichment", "examples\enrichment\Examples.Enrichment\Examples.Enrichment.csproj", "{9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Enrichment", "examples\enrichment\Examples.Enrichment\Examples.Enrichment.csproj", "{9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "enrichment", "enrichment", "{93503FAF-D43D-48C0-818C-92EB90F7606B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9}" + ProjectSection(SolutionItems) = preProject + src\Shared\ActivityInstrumentationHelper.cs = src\Shared\ActivityInstrumentationHelper.cs + src\Shared\DiagnosticSourceListener.cs = src\Shared\DiagnosticSourceListener.cs + src\Shared\DiagnosticSourceSubscriber.cs = src\Shared\DiagnosticSourceSubscriber.cs + src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs + src\Shared\Guard.cs = src\Shared\Guard.cs + src\Shared\InstrumentationEventSource.cs = src\Shared\InstrumentationEventSource.cs + src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs + src\Shared\ListenerHandler.cs = src\Shared\ListenerHandler.cs + src\Shared\MultiTypePropertyFetcher.cs = src\Shared\MultiTypePropertyFetcher.cs + src\Shared\NullableAttributes.cs = src\Shared\NullableAttributes.cs + src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs + src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs + src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs + src\Shared\ServiceProviderExtensions.cs = src\Shared\ServiceProviderExtensions.cs + src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs + src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -309,10 +326,6 @@ Global {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Debug|Any CPU.Build.0 = Debug|Any CPU {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.ActiveCfg = Release|Any CPU {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}.Release|Any CPU.Build.0 = Release|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6}.Release|Any CPU.Build.0 = Release|Any CPU {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Debug|Any CPU.Build.0 = Debug|Any CPU {76BAB24F-85DB-4FCE-89D0-EFB4185004C9}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -595,7 +608,6 @@ Global {9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {970673DA-F308-4960-A58D-ECCEA44CEF6B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {CAB66B50-DAB6-49B8-83F9-6CCF520C4A36} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {F52B9D81-2155-433A-B6F2-4CD7CBBEC7E6} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} @@ -667,6 +679,7 @@ Global {C42868C8-968A-473F-AC39-AC97C5D47E84} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA} = {93503FAF-D43D-48C0-818C-92EB90F7606B} {93503FAF-D43D-48C0-818C-92EB90F7606B} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index d06b9eb9ca..17a1720792 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 1d908482c2..8a63f31667 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -14,7 +14,7 @@ - - + + diff --git a/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Shared/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj b/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj deleted file mode 100644 index 2525d8bf35..0000000000 --- a/src/OpenTelemetry.Contrib.Shared/OpenTelemetry.Contrib.Shared.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - netstandard2.0 - - - - - - - - - - - - diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 4478d94496..93599774e7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index cd6db1ff7d..2990eb9ae4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -19,8 +19,8 @@ - - + + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 34f46926f4..025d4ddd29 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -14,6 +14,6 @@ - + diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj index 761d805b1f..fe20b5c2f7 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index 3b41bba5e1..ffab6b1f36 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 6518979045..a8f69a0230 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 14a98b2675..28929ee4b4 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index a084f11f68..395a6adc25 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index f0eec1af27..3072fd37da 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -14,9 +14,9 @@ - - - + + + diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index ae8b086b9e..fb51ba0d92 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index e8560eac26..167a22babb 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -14,6 +14,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index f4d574d930..96eaf37e4f 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index ec5f3e960a..a92edeb866 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -12,6 +12,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 6133308c08..f00e38357f 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -12,6 +12,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 33a91b03ee..d842b71a81 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -11,6 +11,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj index 5397712c47..2c721cafb6 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj @@ -14,9 +14,9 @@ - - - + + + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index de6e33c97f..47748d2105 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -1,4 +1,4 @@ - + $(NetFrameworkMinimumSupportedVersion) true @@ -9,9 +9,9 @@ - - - + + + diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index 4f7202a8f8..49e32f3588 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 0b271ac9da..c794f15c85 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -12,6 +12,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index dc81b9be78..06adbebe66 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -14,6 +14,6 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 29b7e82417..45aa8b140d 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index cc6da9eac8..7b01ca3fb1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -23,7 +23,7 @@ - + diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index b33f879639..bd71e8127b 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 5b86be8b0a..7dffd68dec 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -16,8 +16,8 @@ - - + + diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index cb303071bf..19c0f3f377 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 OpenTelemetry Resource Detectors for Azure cloud environments @@ -13,7 +13,7 @@ - - + + diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index ed94f96cc4..341fabd468 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs b/src/Shared/ActivityInstrumentationHelper.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ActivityInstrumentationHelper.cs rename to src/Shared/ActivityInstrumentationHelper.cs diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceListener.cs rename to src/Shared/DiagnosticSourceListener.cs diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/DiagnosticSourceSubscriber.cs rename to src/Shared/DiagnosticSourceSubscriber.cs diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs b/src/Shared/ExceptionExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/Api/ExceptionExtensions.cs rename to src/Shared/ExceptionExtensions.cs diff --git a/src/OpenTelemetry.Internal/Guard.cs b/src/Shared/Guard.cs similarity index 100% rename from src/OpenTelemetry.Internal/Guard.cs rename to src/Shared/Guard.cs diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs b/src/Shared/InstrumentationEventSource.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/InstrumentationEventSource.cs rename to src/Shared/InstrumentationEventSource.cs diff --git a/src/OpenTelemetry.Internal/IsExternalInit.cs b/src/Shared/IsExternalInit.cs similarity index 100% rename from src/OpenTelemetry.Internal/IsExternalInit.cs rename to src/Shared/IsExternalInit.cs diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs b/src/Shared/ListenerHandler.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/ListenerHandler.cs rename to src/Shared/ListenerHandler.cs diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs b/src/Shared/MultiTypePropertyFetcher.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/MultiTypePropertyFetcher.cs rename to src/Shared/MultiTypePropertyFetcher.cs diff --git a/src/OpenTelemetry.Internal/NullableAttributes.cs b/src/Shared/NullableAttributes.cs similarity index 100% rename from src/OpenTelemetry.Internal/NullableAttributes.cs rename to src/Shared/NullableAttributes.cs diff --git a/src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs b/src/Shared/PropertyFetcher.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs rename to src/Shared/PropertyFetcher.cs diff --git a/src/OpenTelemetry.Contrib.Shared/Api/ResourceSemanticConventions.cs b/src/Shared/ResourceSemanticConventions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/Api/ResourceSemanticConventions.cs rename to src/Shared/ResourceSemanticConventions.cs diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs b/src/Shared/SemanticConventions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/Api/SemanticConventions.cs rename to src/Shared/SemanticConventions.cs diff --git a/src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs b/src/Shared/ServiceProviderExtensions.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/ServiceProviderExtensions.cs rename to src/Shared/ServiceProviderExtensions.cs diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs b/src/Shared/SpanAttributeConstants.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/Api/SpanAttributeConstants.cs rename to src/Shared/SpanAttributeConstants.cs diff --git a/src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs b/src/Shared/SpanHelper.cs similarity index 100% rename from src/OpenTelemetry.Contrib.Shared/Api/SpanHelper.cs rename to src/Shared/SpanHelper.cs diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 5a1b585cda..f59b1e785e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -26,7 +26,7 @@ - + From eccfe8a6c1b4a5cb5710680bbe721914a2ee145e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 18:18:49 -0700 Subject: [PATCH 0681/1499] Bump codecov/codecov-action from 3.1.2 to 3.1.3 (#1156) --- .github/workflows/dotnet-core-cov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 1f71a5119c..5c60677a4c 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -48,7 +48,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - uses: codecov/codecov-action@v3.1.2 + - uses: codecov/codecov-action@v3.1.3 with: file: TestResults/Cobertura.xml env_vars: OS From 940cc853f65dc6ac3653729b6a7e44eb6faa694f Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 24 Apr 2023 12:16:31 -0700 Subject: [PATCH 0682/1499] Add nuget link ResourceDetector.Azure (#1158) --- src/OpenTelemetry.PersistentStorage.FileSystem/README.md | 2 -- src/OpenTelemetry.ResourceDetectors.Azure/README.md | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index 59e22e886a..e77c011d73 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -1,7 +1,5 @@ # Persistent Storage file based implementation -// TODO: Update Readme - [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 660d6b595b..e2cd8b8b0c 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -1,5 +1,8 @@ # Resource Detectors for Azure cloud environments +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Azure.svg)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Azure.svg)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) + This package contains [Resource Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) for applications running in Azure environment. From 4becfe5f81c477e0ab422bce929384e10670531a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 24 Apr 2023 23:30:43 +0200 Subject: [PATCH 0683/1499] [Exporter.Stackdriver] Nullable (#1130) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 22 +++++++-------- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 22 +++++++-------- .../Implementation/ActivityExtensions.cs | 18 ++++++------ .../Implementation/Constants.cs | 28 ------------------- .../ExporterStackdriverEventSource.cs | 2 +- .../GoogleCloudResourceUtils.cs | 4 +-- .../StackdriverStatsConfiguration.cs | 8 +++--- .../OpenTelemetry.Exporter.Stackdriver.csproj | 1 + .../README.md | 2 +- .../StackdriverTraceExporter.cs | 6 ++-- ...elemetry.Exporter.Stackdriver.Tests.csproj | 1 + .../StackdriverExporterTests.cs | 25 ++++++----------- .../TestActivityProcessor.cs | 4 +-- 15 files changed, 56 insertions(+), 89 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt index 1fd1f60339..f09de33268 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt @@ -2,22 +2,22 @@ OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter -OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string projectId) -> void +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string! projectId) -> void OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string projectId) -> Google.Api.MonitoredResource -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string -static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration -static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable source, int size) -> System.Collections.Generic.IEnumerable> -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string projectId) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string? projectId) -> Google.Api.MonitoredResource! +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string? +static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration! +static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable! source, int size) -> System.Collections.Generic.IEnumerable!>! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string! projectId) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 1fd1f60339..f09de33268 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -2,22 +2,22 @@ OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string? OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter -OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string projectId) -> void +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string! projectId) -> void OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string projectId) -> Google.Api.MonitoredResource -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string -static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration -static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable source, int size) -> System.Collections.Generic.IEnumerable> -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string projectId) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string? projectId) -> Google.Api.MonitoredResource! +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string? +static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration! +static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable! source, int size) -> System.Collections.Generic.IEnumerable!>! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string! projectId) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 240c2af077..36aa1f032f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -14,8 +14,6 @@ // limitations under the License. // -#nullable enable - using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -136,25 +134,25 @@ public static AttributeValue ToAttributeValue(this object? av) switch (av) { case string s: - return new AttributeValue() + return new AttributeValue { - StringValue = new TruncatableString() { Value = s }, + StringValue = new TruncatableString { Value = s }, }; case bool b: - return new AttributeValue() { BoolValue = b }; + return new AttributeValue { BoolValue = b }; case long l: - return new AttributeValue() { IntValue = l }; + return new AttributeValue { IntValue = l }; case double d: - return new AttributeValue() + return new AttributeValue { - StringValue = new TruncatableString() { Value = d.ToString(CultureInfo.InvariantCulture) }, + StringValue = new TruncatableString { Value = d.ToString(CultureInfo.InvariantCulture) }, }; case null: return new AttributeValue(); default: - return new AttributeValue() + return new AttributeValue { - StringValue = new TruncatableString() { Value = av.ToString() }, + StringValue = new TruncatableString { Value = av.ToString() }, }; } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs index 800a31aa74..ee3797181e 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs @@ -14,41 +14,13 @@ // limitations under the License. // -using System; - namespace OpenTelemetry.Exporter.Stackdriver.Implementation; internal class Constants { public const string PackagVersionUndefined = "undefined"; - public const string LabelDescription = "OpenTelemetry string"; - public const string OpenTelemetryTask = "OpenTelemetry_task"; - public const string OpenTelemetryTaskDescription = "OpenTelemetry task identifier"; - - public const string GcpGkeContainer = "k8s_container"; - public const string GcpGceInstance = "gce_instance"; - public const string AwsEc2Instance = "aws_ec2_instance"; public const string Global = "global"; public const string ProjectIdLabelKey = "project_id"; - - public const string GceGcpInstanceType = "cloud.google.com/gce/instance"; - public const string GcpInstanceIdKey = "cloud.google.com/gce/instance_id"; - public const string GcpAccountIdKey = "cloud.google.com/gce/project_id"; - public const string GcpZoneKey = "cloud.google.com/gce/zone"; - - public const string K8sContainerType = "k8s.io/container"; - public const string K8sClusterNameKey = "k8s.io/cluster/name"; - public const string K8sContainerNameKey = "k8s.io/container/name"; - public const string K8sNamespaceNameKey = "k8s.io/namespace/name"; - public const string K8sPodNameKey = "k8s.io/pod/name"; - - public static readonly string OpenTelemetryTaskValueDefault = GenerateDefaultTaskValue(); - - private static string GenerateDefaultTaskValue() - { - // Something like '@' - return $"dotnet-{System.Diagnostics.Process.GetCurrentProcess().Id}@{Environment.MachineName}"; - } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs index 118f88aac5..818383e680 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation; [EventSource(Name = "OpenTelemetry-Exporter-Stackdriver")] internal class ExporterStackdriverEventSource : EventSource { - public static readonly ExporterStackdriverEventSource Log = new ExporterStackdriverEventSource(); + public static readonly ExporterStackdriverEventSource Log = new(); [NonEvent] public void ExportMethodException(Exception ex) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs index 8f924ccf0e..2dfb3e0270 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs @@ -32,7 +32,7 @@ public static class GoogleCloudResourceUtils /// the method returns null. /// /// Google Cloud Project ID. - public static string GetProjectId() + public static string? GetProjectId() { // Try to detect projectId from the environment where the code is running var instance = Google.Api.Gax.Platform.Instance(); @@ -60,7 +60,7 @@ public static string GetProjectId() /// /// The project id. /// Stackdriver Monitored Resource. - public static MonitoredResource GetDefaultResource(string projectId) + public static MonitoredResource GetDefaultResource(string? projectId) { var resource = new MonitoredResource(); resource.Type = Constants.Global; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs index 2ebe727993..8d436432a5 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs @@ -54,17 +54,17 @@ public static StackdriverStatsConfiguration Default /// /// Gets or sets the prefix to append to every OpenTelemetry metric name in Stackdriver. /// - public string MetricNamePrefix { get; set; } + public string? MetricNamePrefix { get; set; } /// /// Gets or sets google Cloud Project Id. /// - public string ProjectId { get; set; } + public string? ProjectId { get; set; } /// /// Gets or sets credential used to authenticate against Google Stackdriver Monitoring APIs. /// - public GoogleCredential GoogleCredential { get; set; } + public GoogleCredential? GoogleCredential { get; set; } /// /// Gets or sets monitored Resource associated with metrics collection. @@ -72,5 +72,5 @@ public static StackdriverStatsConfiguration Default /// such as GKE/AWS/GCE. If the exporter is running on a different environment, /// monitored resource will be identified as "general". /// - public MonitoredResource MonitoredResource { get; set; } + public MonitoredResource? MonitoredResource { get; set; } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 025d4ddd29..515cde9d2a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -6,6 +6,7 @@ $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- true + enable diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 911543af79..4f26b1e07a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -22,7 +22,7 @@ constructor for specifying path to the service account credential. ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.Stackdriver +dotnet add package OpenTelemetry.Contrib.Instrumentation.Stackdriver --prerelease ``` ## Traces diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index e109388329..22d3b57418 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -35,7 +35,7 @@ public class StackdriverTraceExporter : BaseExporter private readonly Google.Api.Gax.ResourceNames.ProjectName googleCloudProjectId; private readonly TraceServiceSettings traceServiceSettings; - private readonly TraceServiceClient traceServiceClient; + private readonly TraceServiceClient? traceServiceClient; #pragma warning disable CA1810 // Initialize reference type static fields inline static StackdriverTraceExporter() @@ -91,8 +91,8 @@ internal StackdriverTraceExporter(string projectId, TraceServiceClient traceServ /// public override ExportResult Export(in Batch batch) { - TraceServiceClient traceWriter = this.traceServiceClient; - if (this.traceServiceClient == null) + TraceServiceClient? traceWriter = this.traceServiceClient; + if (traceWriter == null) { traceWriter = new TraceServiceClientBuilder { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 52327d652c..bb8e66d5b6 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 + enable diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index c9ac11bebd..3c9a7fb4d0 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -46,13 +46,6 @@ static StackdriverExporterTests() ActivitySource.AddActivityListener(listener); } - [Fact] - public void StackdriverExporter_BadArgs() - { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.UseStackdriverExporter(string.Empty)); - } - [Fact] public void StackdriverExporter_CustomActivityProcessor() { @@ -91,7 +84,7 @@ public void StackdriverExporter_CustomActivityProcessor() [Fact] public void StackdriverExporter_TraceClientThrows_ExportResultFailure() { - Exception exception = null; + Exception? exception; ExportResult result = ExportResult.Success; var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; @@ -132,7 +125,7 @@ void RunTest(Batch batch) [Fact] public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() { - Exception exception = null; + Exception? exception; ExportResult result = ExportResult.Failure; var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; @@ -171,10 +164,10 @@ void RunTest(Batch batch) internal static Activity CreateTestActivity( 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) { var startTimestamp = DateTime.UtcNow; @@ -184,7 +177,7 @@ internal static Activity CreateTestActivity( var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); - var attributes = new Dictionary + var attributes = new Dictionary { { "stringKey", "value" }, { "longKey", 1L }, @@ -205,14 +198,14 @@ internal static Activity CreateTestActivity( var events = new List { - new ActivityEvent( + new( "Event1", eventTimestamp, new ActivityTagsCollection { { "key", "value" }, }), - new ActivityEvent( + new( "Event2", eventTimestamp, new ActivityTagsCollection @@ -226,7 +219,7 @@ internal static Activity CreateTestActivity( var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = setAttributes ? - attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value?.ToString())) + attributes.Select(kvp => new KeyValuePair(kvp.Key, kvp.Value?.ToString())) : null; var links = addLinks ? new[] @@ -244,7 +237,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.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index c4a55c3755..477140520c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -21,8 +21,8 @@ namespace OpenTelemetry.Exporter.Stackdriver.Tests; public class TestActivityProcessor : BaseProcessor, IDisposable { - public Action StartAction; - public Action EndAction; + public Action? StartAction; + public Action? EndAction; public TestActivityProcessor() { From 4cc8429220b7e049b6ecaac70b3ee4e97c910b9c Mon Sep 17 00:00:00 2001 From: Jon Steinich Date: Tue, 25 Apr 2023 01:52:48 -0500 Subject: [PATCH 0684/1499] Allow subtypes of default AWS service clients to be instrumented (#1142) --- .../AWSTracingPipelineCustomizer.cs | 2 +- .../TestAWSClientInstrumentation.cs | 40 +++++++++++++++++++ .../Tools/TestAmazonDynamoDBClient.cs | 29 ++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index 14bd951e9a..c7693d729a 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -39,7 +39,7 @@ public string UniqueName public void Customize(Type serviceClientType, RuntimePipeline pipeline) { - if (serviceClientType.BaseType != typeof(AmazonServiceClient)) + if (!typeof(AmazonServiceClient).IsAssignableFrom(serviceClientType)) { return; } diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index b33946eb02..148e61acce 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -72,6 +72,46 @@ public void TestDDBScanSuccessful() } } + [Fact] + public void TestDDBSubtypeScanSuccessful() + { + var processor = new Mock>(); + + var parent = new Activity("parent").Start(); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddXRayTraceId() + .AddAWSInstrumentation() + .AddProcessor(processor.Object) + .Build()) + { + var ddb = new TestAmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + CustomResponses.SetResponse(ddb, null, requestId, true); + var scan_request = new ScanRequest(); + + scan_request.TableName = "SampleProduct"; + scan_request.AttributesToGet = new List() { "Id", "Name" }; +#if NETFRAMEWORK + ddb.Scan(scan_request); +#else + ddb.ScanAsync(scan_request).Wait(); +#endif + var count = processor.Invocations.Count; + + Assert.Equal(3, count); + + Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateDynamoActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); + } + } + [Fact] #if NETFRAMEWORK public void TestDDBScanUnsuccessful() diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs new file mode 100644 index 0000000000..5085ca5f25 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Amazon; +using Amazon.DynamoDBv2; +using Amazon.Runtime; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; + +internal class TestAmazonDynamoDBClient : AmazonDynamoDBClient +{ + public TestAmazonDynamoDBClient(AWSCredentials credentials, RegionEndpoint region) + : base(credentials, region) + { + } +} From 1a584314e714d2c9ecf47a54cdad659e32334bed Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Tue, 25 Apr 2023 22:57:58 -0700 Subject: [PATCH 0685/1499] [Sampler.AWS] Part-2: Add rules cache and rule matching logic (#1124) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 +- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../AWSSamplerEventSource.cs | 6 + .../AWSXRayRemoteSampler.cs | 86 +++++-- .../AWSXRayRemoteSamplerBuilder.cs | 23 +- .../AWSXRaySamplerClient.cs | 3 - src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 3 +- src/OpenTelemetry.Sampler.AWS/Clock.cs | 36 +++ .../FallbackSampler.cs | 38 +++ src/OpenTelemetry.Sampler.AWS/Matcher.cs | 144 ++++++++++++ .../OpenTelemetry.Sampler.AWS.csproj | 1 + src/OpenTelemetry.Sampler.AWS/README.md | 30 ++- src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 138 +++++++++++ src/OpenTelemetry.Sampler.AWS/SamplingRule.cs | 7 +- .../SamplingRuleApplier.cs | 154 ++++++++++++ src/OpenTelemetry.Sampler.AWS/Statistics.cs | 26 +++ src/OpenTelemetry.Sampler.AWS/SystemClock.cs | 62 +++++ .../TestAWSXRayRemoteSampler.cs | 15 +- .../TestAWSXRaySamplerClient.cs | 1 - .../TestClock.cs | 64 +++++ .../TestMatcher.cs | 94 ++++++++ .../TestRulesCache.cs | 123 ++++++++++ .../TestSamplingRuleApplier.cs | 221 ++++++++++++++++++ test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs | 60 +++++ 25 files changed, 1301 insertions(+), 40 deletions(-) create mode 100644 src/OpenTelemetry.Sampler.AWS/Clock.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/Matcher.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/RulesCache.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/Statistics.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/SystemClock.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt index a2403cda2c..063bdbf96d 100644 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt @@ -6,4 +6,4 @@ OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.S OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult -static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder(OpenTelemetry.Resources.Resource! resource) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt index a2403cda2c..063bdbf96d 100644 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -6,4 +6,4 @@ OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.S OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult -static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder(OpenTelemetry.Resources.Resource! resource) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index a2403cda2c..063bdbf96d 100644 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,4 +6,4 @@ OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.S OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult -static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! +static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder(OpenTelemetry.Resources.Resource! resource) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs index 6e5e58143d..de9bfe5f04 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs @@ -40,4 +40,10 @@ public void FailedToDeserializeResponse(string format, string error) { this.WriteEvent(3, format, error); } + + [Event(4, Message = "Using fallback sampler. Either rules cache has expired or no rules matched the request.", Level = EventLevel.Informational)] + public void InfoUsingFallbackSampler() + { + this.WriteEvent(4); + } } diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs index 676bf5bfe6..b688720016 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -15,7 +15,10 @@ // using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Threading; +using OpenTelemetry.Resources; using OpenTelemetry.Trace; namespace OpenTelemetry.Sampler.AWS; @@ -25,38 +28,71 @@ namespace OpenTelemetry.Sampler.AWS; /// public sealed class AWSXRayRemoteSampler : Trace.Sampler, IDisposable { - internal AWSXRayRemoteSampler(TimeSpan pollingInterval, string endpoint) + internal static readonly TimeSpan DefaultTargetInterval = TimeSpan.FromSeconds(10); + + private static readonly Random Random = new Random(); + + [SuppressMessage("Performance", "CA5394: Do not use insecure randomness", Justification = "Secure random is not required for jitters.")] + internal AWSXRayRemoteSampler(Resource resource, TimeSpan pollingInterval, string endpoint, Clock clock) { + this.Resource = resource; this.PollingInterval = pollingInterval; this.Endpoint = endpoint; - this.Client = new AWSXRaySamplerClient(endpoint); + this.Clock = clock; + this.ClientId = GenerateClientId(); + this.Client = new AWSXRaySamplerClient(this.Endpoint); + this.FallbackSampler = new FallbackSampler(this.Clock); + this.RulesCache = new RulesCache(this.Clock, this.ClientId, this.Resource, this.FallbackSampler); + + // upto 5 seconds of jitter for rule polling + this.RulePollerJitter = TimeSpan.FromMilliseconds(Random.Next(1, 5000)); - // execute the first update right away - this.RulePollerTimer = new Timer(this.GetAndUpdateSampler, null, TimeSpan.Zero, this.PollingInterval); + // execute the first update right away and schedule subsequent update later. + this.RulePollerTimer = new Timer(this.GetAndUpdateRules, null, TimeSpan.Zero, Timeout.InfiniteTimeSpan); } - internal TimeSpan PollingInterval { get; } + internal TimeSpan RulePollerJitter { get; set; } + + internal Clock Clock { get; set; } + + internal string ClientId { get; set; } - internal string Endpoint { get; } + internal Resource Resource { get; set; } - internal AWSXRaySamplerClient Client { get; } + internal string Endpoint { get; set; } - internal Timer RulePollerTimer { get; } + internal AWSXRaySamplerClient Client { get; set; } + + internal RulesCache RulesCache { get; set; } + + internal Timer RulePollerTimer { get; set; } + + internal TimeSpan PollingInterval { get; set; } + + internal Trace.Sampler FallbackSampler { get; set; } /// /// Initializes a for the sampler. /// + /// an instance of + /// to identify the service attributes for sampling. This resource should + /// be the same as what the OpenTelemetry SDK is configured with. /// an instance of . - public static AWSXRayRemoteSamplerBuilder Builder() + public static AWSXRayRemoteSamplerBuilder Builder(Resource resource) { - return new AWSXRayRemoteSamplerBuilder(); + return new AWSXRayRemoteSamplerBuilder(resource); } /// public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { - // TODO: add the actual functionality for sampling. - throw new System.NotImplementedException(); + if (this.RulesCache.Expired()) + { + AWSSamplerEventSource.Log.InfoUsingFallbackSampler(); + return this.FallbackSampler.ShouldSample(in samplingParameters); + } + + return this.RulesCache.ShouldSample(in samplingParameters); } /// @@ -66,19 +102,39 @@ public void Dispose() GC.SuppressFinalize(this); } + [SuppressMessage( + "Usage", + "CA5394: Do not use insecure randomness", + Justification = "using insecure random is fine here since clientId doesn't need to be secure.")] + private static string GenerateClientId() + { + char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + char[] clientIdChars = new char[24]; + for (int i = 0; i < clientIdChars.Length; i++) + { + clientIdChars[i] = hex[Random.Next(hex.Length)]; + } + + return new string(clientIdChars); + } + private void Dispose(bool disposing) { if (disposing) { this.RulePollerTimer?.Dispose(); this.Client?.Dispose(); + this.RulesCache?.Dispose(); } } - private async void GetAndUpdateSampler(object? state) + private async void GetAndUpdateRules(object? state) { - await this.Client.GetSamplingRules().ConfigureAwait(false); + List rules = await this.Client.GetSamplingRules().ConfigureAwait(false); + + this.RulesCache.UpdateRules(rules); - // TODO: more functionality to be added. + // schedule the next rule poll. + this.RulePollerTimer.Change(this.PollingInterval.Add(this.RulePollerJitter), Timeout.InfiniteTimeSpan); } } diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs index d5c39224a3..0aa3aa32d8 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs @@ -15,6 +15,7 @@ // using System; +using OpenTelemetry.Resources; namespace OpenTelemetry.Sampler.AWS; @@ -27,13 +28,17 @@ public class AWSXRayRemoteSamplerBuilder private static readonly TimeSpan DefaultPollingInterval = TimeSpan.FromMinutes(5); + private Resource resource; private TimeSpan pollingInterval; private string endpoint; + private Clock clock; - internal AWSXRayRemoteSamplerBuilder() + internal AWSXRayRemoteSamplerBuilder(Resource resource) { + this.resource = resource; this.pollingInterval = DefaultPollingInterval; this.endpoint = DefaultEndpoint; + this.clock = Clock.GetDefault(); } /// @@ -78,6 +83,20 @@ public AWSXRayRemoteSamplerBuilder SetEndpoint(string endpoint) /// an instance of . public AWSXRayRemoteSampler Build() { - return new AWSXRayRemoteSampler(this.pollingInterval, this.endpoint); + return new AWSXRayRemoteSampler(this.resource, this.pollingInterval, this.endpoint, this.clock); + } + + // This is intended for testing with a mock clock. + // Should not be exposed to public. + internal AWSXRayRemoteSamplerBuilder SetClock(Clock clock) + { + if (clock == null) + { + throw new ArgumentNullException(nameof(clock)); + } + + this.clock = clock; + + return this; } } diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index b4756e14f3..1a40673fb5 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -61,9 +61,6 @@ public async Task> GetSamplingRules() } } } - - // TODO: this line here is only for testing. Remove in next more complete iterations. - // Console.WriteLine("Got sampling rules! Count: " + samplingRules.Count); } } catch (Exception ex) diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index c847e5dc16..b50bb6dbc1 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -5,4 +5,5 @@ Initial release of `OpenTelemetry.Sampler.AWS`. * Feature - AWSXRayRemoteSampler - Add support for AWS X-Ray remote sampling - ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091)) + ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091), + [#1124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1124)) diff --git a/src/OpenTelemetry.Sampler.AWS/Clock.cs b/src/OpenTelemetry.Sampler.AWS/Clock.cs new file mode 100644 index 0000000000..39218fbdf2 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/Clock.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Sampler.AWS; + +// A time keeper for the purpose of this sampler. +internal abstract class Clock +{ + public static Clock GetDefault() + { + return SystemClock.GetInstance(); + } + + public abstract DateTime Now(); + + public abstract long NowInSeconds(); + + public abstract DateTime ToDateTime(double seconds); + + public abstract double ToDouble(DateTime dateTime); +} diff --git a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs new file mode 100644 index 0000000000..3917c407fe --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Sampler.AWS; + +internal class FallbackSampler : Trace.Sampler +{ + private static readonly Trace.Sampler AlwaysOn = new AlwaysOnSampler(); + + private readonly Clock clock; + + public FallbackSampler(Clock clock) + { + this.clock = clock; + } + + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + // For now just do an always on sampler. + // TODO: update to a rate limiting sampler. + return AlwaysOn.ShouldSample(samplingParameters); + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/Matcher.cs b/src/OpenTelemetry.Sampler.AWS/Matcher.cs new file mode 100644 index 0000000000..e135293e9f --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/Matcher.cs @@ -0,0 +1,144 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace OpenTelemetry.Sampler.AWS; + +internal static class Matcher +{ + public static readonly IReadOnlyDictionary XRayCloudPlatform = new Dictionary() + { + { "aws_ec2", "AWS::EC2::Instance" }, + { "aws_ecs", "AWS::ECS::Container" }, + { "aws_eks", "AWS::EKS::Container" }, + { "aws_elastic_beanstalk", "AWS::ElasticBeanstalk::Environment" }, + { "aws_lambda", "AWS::Lambda::Function" }, + }; + + public static bool WildcardMatch(string? text, string? globPattern) + { + if (globPattern == "*") + { + return true; + } + + if (text == null || globPattern == null) + { + return false; + } + + if (globPattern.Length == 0) + { + return text.Length == 0; + } + + // it is faster to check if we need a regex comparison than + // doing always regex comparison, even where we may not need it. + foreach (char c in globPattern) + { + if (c == '*' || c == '?') + { + return Regex.IsMatch(text, ToRegexPattern(globPattern)); + } + } + + return string.Equals(text, globPattern, StringComparison.OrdinalIgnoreCase); + } + + public static bool AttributeMatch(IEnumerable>? tags, Dictionary ruleAttributes) + { + if (ruleAttributes.Count == 0) + { + return true; + } + + if (tags == null) + { + return false; + } + + int matchedCount = 0; + + foreach (var tag in tags) + { + var textToMatch = tag.Value?.ToString(); + ruleAttributes.TryGetValue(tag.Key, out var globPattern); + + if (globPattern == null) + { + continue; + } + + if (WildcardMatch(textToMatch, globPattern)) + { + matchedCount++; + } + } + + if (matchedCount == ruleAttributes.Count) + { + return true; + } + + return false; + } + + private static string ToRegexPattern(string globPattern) + { + int tokenStart = -1; + StringBuilder patternBuilder = new StringBuilder(); + + for (int i = 0; i < globPattern.Length; i++) + { + char c = globPattern[i]; + if (c == '*' || c == '?') + { + if (tokenStart != -1) + { + patternBuilder.Append(Regex.Escape(globPattern.Substring(tokenStart, i - tokenStart))); + tokenStart = -1; + } + + if (c == '*') + { + patternBuilder.Append(".*"); + } + else + { + patternBuilder.Append('.'); + } + } + else + { + if (tokenStart == -1) + { + tokenStart = i; + } + } + } + + if (tokenStart != -1) + { + patternBuilder.Append(Regex.Escape(globPattern.Substring(tokenStart))); + } + + return patternBuilder.ToString(); + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index 341fabd468..8427c7659c 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -19,6 +19,7 @@ + diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md index f10d151e31..0ed8bb6d43 100644 --- a/src/OpenTelemetry.Sampler.AWS/README.md +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -15,20 +15,34 @@ dotnet add package OpenTelemetry.Sampler.AWS You can configure the `AWSXRayRemoteSampler` as per the following example. Note that you will need to configure your [OpenTelemetry Collector for -X-Ray remote sampling](https://aws-otel.github.io/docs/getting-started/remote-sampling) +X-Ray remote sampling](https://aws-otel.github.io/docs/getting-started/remote-sampling). +This example also sets up the Console Exporter, +which requires adding the package [`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) +to the application. ```csharp using OpenTelemetry; +using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Sampler.AWS; using OpenTelemetry.Trace; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .SetSampler(AWSXRayRemoteSampler.Builder() - .SetPollingInterval(TimeSpan.FromSeconds(10)) - .SetEndpoint("http://localhost:2000") - .Build()) - .Build(); +var serviceName = "MyServiceName"; + +var resourceBuilder = ResourceBuilder + .CreateDefault() + .AddService(serviceName: serviceName) + .AddDetector(new AWSEC2ResourceDetector()); + +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource(serviceName) + .SetResourceBuilder(resourceBuilder) + .AddConsoleExporter() + .SetSampler(AWSXRayRemoteSampler.Builder(resourceBuilder.Build()) // you must provide a resource + .SetPollingInterval(TimeSpan.FromSeconds(5)) + .SetEndpoint("http://localhost:2000") + .Build()) + .Build(); ``` ## References diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs new file mode 100644 index 0000000000..182ab0b013 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -0,0 +1,138 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Sampler.AWS; + +internal class RulesCache : IDisposable +{ + private const int CacheTTL = 60 * 60; // cache expires 1 hour after the refresh (in sec) + + private readonly ReaderWriterLockSlim rwLock; + + public RulesCache(Clock clock, string clientId, Resource resource, Trace.Sampler fallbackSampler) + { + this.rwLock = new ReaderWriterLockSlim(); + this.Clock = clock; + this.ClientId = clientId; + this.Resource = resource; + this.FallbackSampler = fallbackSampler; + this.RuleAppliers = new List(); + this.UpdatedAt = this.Clock.Now(); + } + + internal Clock Clock { get; set; } + + internal string ClientId { get; set; } + + internal Resource Resource { get; set; } + + internal Trace.Sampler FallbackSampler { get; set; } + + internal List RuleAppliers { get; set; } + + internal DateTime UpdatedAt { get; set; } + + public bool Expired() + { + this.rwLock.EnterReadLock(); + try + { + return this.Clock.Now() > this.UpdatedAt.AddSeconds(CacheTTL); + } + finally + { + this.rwLock.ExitReadLock(); + } + } + + public void UpdateRules(List newRules) + { + // sort the new rules + newRules.Sort((x, y) => x.CompareTo(y)); + + List newRuleAppliers = new List(); + foreach (var rule in newRules) + { + var currentStatistics = this.RuleAppliers + .FirstOrDefault(currentApplier => currentApplier.RuleName == rule.RuleName) + ?.Statistics ?? new Statistics(); + + var ruleApplier = new SamplingRuleApplier(this.ClientId, this.Clock, rule, currentStatistics); + newRuleAppliers.Add(ruleApplier); + } + + this.rwLock.EnterWriteLock(); + try + { + this.RuleAppliers = newRuleAppliers; + this.UpdatedAt = this.Clock.Now(); + } + finally + { + this.rwLock.ExitWriteLock(); + } + } + + public SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + foreach (var ruleApplier in this.RuleAppliers) + { + if (ruleApplier.Matches(samplingParameters, this.Resource)) + { + return ruleApplier.ShouldSample(in samplingParameters); + } + } + + // ideally the default rule should have matched. + // if we are here then likely due to a bug. + AWSSamplerEventSource.Log.InfoUsingFallbackSampler(); + return this.FallbackSampler.ShouldSample(in samplingParameters); + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + internal DateTime GetUpdatedAt() + { + this.rwLock.EnterReadLock(); + try + { + return this.UpdatedAt; + } + finally + { + this.rwLock.ExitReadLock(); + } + } + + private void Dispose(bool disposing) + { + if (disposing) + { + this.rwLock.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs index 1805951b6f..c4907675b5 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs @@ -31,6 +31,7 @@ public SamplingRule( string httpMethod, string resourceArn, string serviceName, + string serviceType, string urlPath, int version, Dictionary attributes) @@ -43,6 +44,7 @@ public SamplingRule( this.HttpMethod = httpMethod; this.ResourceArn = resourceArn; this.ServiceName = serviceName; + this.ServiceType = serviceType; this.UrlPath = urlPath; this.Version = version; this.Attributes = attributes; @@ -72,6 +74,9 @@ public SamplingRule( [JsonPropertyName("ServiceName")] public string ServiceName { get; set; } + [JsonPropertyName("ServiceType")] + public string ServiceType { get; set; } + [JsonPropertyName("URLPath")] public string UrlPath { get; set; } @@ -79,7 +84,7 @@ public SamplingRule( public int Version { get; set; } [JsonPropertyName("Attributes")] - public Dictionary? Attributes { get; set; } + public Dictionary Attributes { get; set; } public int CompareTo(SamplingRule? other) { diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs new file mode 100644 index 0000000000..abfba82618 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -0,0 +1,154 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Sampler.AWS; + +internal class SamplingRuleApplier +{ + public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Statistics statistics) + { + this.ClientId = clientId; + this.Clock = clock; + this.Rule = rule; + this.RuleName = this.Rule.RuleName; + this.Statistics = statistics ?? new Statistics(); + } + + internal string ClientId { get; set; } + + internal SamplingRule Rule { get; set; } + + internal string RuleName { get; set; } + + internal Clock Clock { get; set; } + + internal Statistics Statistics { get; set; } + + // check if this rule applier matches the request + public bool Matches(SamplingParameters samplingParameters, Resource resource) + { + string? httpTarget = null; + string? httpUrl = null; + string? httpMethod = null; + string? httpHost = null; + + if (samplingParameters.Tags is not null) + { + foreach (var tag in samplingParameters.Tags) + { + if (tag.Key.Equals(SemanticConventions.AttributeHttpTarget, StringComparison.Ordinal)) + { + httpTarget = (string?)tag.Value; + } + else if (tag.Key.Equals(SemanticConventions.AttributeHttpUrl, StringComparison.Ordinal)) + { + httpUrl = (string?)tag.Value; + } + else if (tag.Key.Equals(SemanticConventions.AttributeHttpMethod, StringComparison.Ordinal)) + { + httpMethod = (string?)tag.Value; + } + else if (tag.Key.Equals(SemanticConventions.AttributeHttpHost, StringComparison.Ordinal)) + { + httpHost = (string?)tag.Value; + } + } + } + + // URL path may be in either http.target or http.url + if (httpTarget == null && httpUrl != null) + { + int schemeEndIndex = httpUrl.IndexOf("://", StringComparison.Ordinal); + + // Per spec, http.url is always populated with scheme://host/target. If scheme doesn't + // match, assume it's bad instrumentation and ignore. + if (schemeEndIndex > 0) + { + int pathIndex = httpUrl.IndexOf('/', schemeEndIndex + "://".Length); + if (pathIndex < 0) + { + httpTarget = "/"; + } + else + { + httpTarget = httpUrl.Substring(pathIndex); + } + } + } + + string serviceName = (string)resource.Attributes.FirstOrDefault(kvp => + kvp.Key.Equals("service.name", StringComparison.Ordinal)).Value; + + return Matcher.AttributeMatch(samplingParameters.Tags, this.Rule.Attributes) && + Matcher.WildcardMatch(httpTarget, this.Rule.UrlPath) && + Matcher.WildcardMatch(httpMethod, this.Rule.HttpMethod) && + Matcher.WildcardMatch(httpHost, this.Rule.Host) && + Matcher.WildcardMatch(serviceName, this.Rule.ServiceName) && + Matcher.WildcardMatch(GetServiceType(resource), this.Rule.ServiceType) && + Matcher.WildcardMatch(GetArn(in samplingParameters, resource), this.Rule.ResourceArn); + } + + [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "method work in progress")] + public SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + // for now return drop sampling result. + // TODO: use reservoir and fixed rate sampler + return new SamplingResult(false); + } + + private static string GetServiceType(Resource resource) + { + string cloudPlatform = (string)resource.Attributes.FirstOrDefault(kvp => + kvp.Key.Equals("cloud.platform", StringComparison.Ordinal)).Value; + + if (cloudPlatform == null) + { + return string.Empty; + } + + return Matcher.XRayCloudPlatform.TryGetValue(cloudPlatform, out string? value) ? value : string.Empty; + } + + private static string GetArn(in SamplingParameters samplingParameters, Resource resource) + { + // currently the aws resource detectors only capture ARNs for ECS and Lambda environments. + string? arn = (string?)resource.Attributes.FirstOrDefault(kvp => + kvp.Key.Equals("aws.ecs.container.arn", StringComparison.Ordinal)).Value; + + if (arn != null) + { + return arn; + } + + if (GetServiceType(resource).Equals("AWS::Lambda::Function", StringComparison.Ordinal)) + { + arn = (string?)samplingParameters.Tags?.FirstOrDefault(kvp => kvp.Key.Equals("faas.id", StringComparison.Ordinal)).Value; + + if (arn != null) + { + return arn; + } + } + + return string.Empty; + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/Statistics.cs b/src/OpenTelemetry.Sampler.AWS/Statistics.cs new file mode 100644 index 0000000000..9b790eb0e8 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/Statistics.cs @@ -0,0 +1,26 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Sampler.AWS; + +internal class Statistics +{ + public int RequestCount { get; internal set; } + + public int BorrowCount { get; internal set; } + + public int SampleCount { get; internal set; } +} diff --git a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs new file mode 100644 index 0000000000..d2ec6eb090 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs @@ -0,0 +1,62 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; + +namespace OpenTelemetry.Sampler.AWS; + +// A clock based on System time. +internal class SystemClock : Clock +{ + private static readonly SystemClock Instance = new SystemClock(); + + private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + private SystemClock() + { + } + + public static Clock GetInstance() + { + return Instance; + } + + public override DateTime Now() + { + return DateTime.UtcNow; + } + + public override long NowInSeconds() + { + double ts = Stopwatch.GetTimestamp(); + double s = ts / Stopwatch.Frequency; + + return (long)s; + } + + public override DateTime ToDateTime(double seconds) + { + return EpochStart.AddSeconds(seconds); + } + + public override double ToDouble(DateTime dateTime) + { + var current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); + double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; + return timestamp; + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index ee63f9ff9a..5cff06fa5f 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -15,7 +15,8 @@ // using System; -using OpenTelemetry.Sampler.AWS; +using System.Collections.Generic; +using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Xunit; @@ -29,7 +30,7 @@ public void TestSamplerWithConfiguration() TimeSpan pollingInterval = TimeSpan.FromSeconds(5); string endpoint = "http://localhost:3000"; - AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder() + AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) .SetPollingInterval(pollingInterval) .SetEndpoint(endpoint) .Build(); @@ -43,7 +44,7 @@ public void TestSamplerWithConfiguration() [Fact] public void TestSamplerWithDefaults() { - AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder().Build(); + AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); Assert.Equal(TimeSpan.FromMinutes(5), sampler.PollingInterval); Assert.Equal("http://localhost:2000", sampler.Endpoint); @@ -54,9 +55,11 @@ public void TestSamplerWithDefaults() [Fact] public void TestSamplerShouldSample() { - Trace.Sampler sampler = AWSXRayRemoteSampler.Builder().Build(); + Trace.Sampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); - // TODO: update the test when the method is implemented. - Assert.Throws(() => sampler.ShouldSample(default(SamplingParameters))); + // for now the fallback sampler should be making the sampling decision + Assert.Equal( + SamplingDecision.RecordAndSample, + sampler.ShouldSample(Utils.CreateSamplingParametersWithTags(new Dictionary())).Decision); } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs index cf2330c282..2b9863c1f8 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.IO; -using OpenTelemetry.Sampler.AWS; using WireMock.RequestBuilders; using WireMock.ResponseBuilders; using WireMock.Server; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs new file mode 100644 index 0000000000..a5be1d33df --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -0,0 +1,64 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +internal class TestClock : Clock +{ + private DateTime nowTime; + + public TestClock() + { + this.nowTime = DateTime.Now; + } + + public TestClock(DateTime time) + { + this.nowTime = time; + } + + public override DateTime Now() + { + return this.nowTime; + } + + public override long NowInSeconds() + { + throw new NotImplementedException(); + } + + public override DateTime ToDateTime(double seconds) + { + throw new NotImplementedException(); + } + + public override double ToDouble(DateTime dateTime) + { + throw new NotImplementedException(); + } + + // Advnaces the clock by a given time span. + public void Advance(TimeSpan time) + { + this.nowTime = this.nowTime.Add(time); + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs new file mode 100644 index 0000000000..3c320f2d81 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs @@ -0,0 +1,94 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +public class TestMatcher +{ + [Theory] + [InlineData(null, "*")] + [InlineData("", "*")] + [InlineData("HelloWorld", "*")] + [InlineData("HelloWorld", "HelloWorld")] + [InlineData("HelloWorld", "Hello*")] + [InlineData("HelloWorld", "*World")] + [InlineData("HelloWorld", "?ello*")] + [InlineData("HelloWorld", "Hell?W*d")] + [InlineData("Hello.World", "*.World")] + [InlineData("Bye.World", "*.World")] + public void TestWildcardMatch(string input, string pattern) + { + Assert.True(Matcher.WildcardMatch(input, pattern)); + } + + [Theory] + [InlineData(null, "Hello*")] + [InlineData("HelloWorld", null)] + public void TestWildcardDoesNotMatch(string input, string pattern) + { + Assert.False(Matcher.WildcardMatch(input, pattern)); + } + + [Fact] + public void TestAttributeMatching() + { + var tags = new List>() + { + new KeyValuePair("dog", "bark"), + new KeyValuePair("cat", "meow"), + new KeyValuePair("cow", "mooo"), + }; + + var ruleAttributes = new Dictionary() + { + { "dog", "bar?" }, + { "cow", "mooo" }, + }; + + Assert.True(Matcher.AttributeMatch(tags, ruleAttributes)); + } + + [Fact] + public void TestAttributeMatchingWithoutRuleAttributes() + { + var tags = new List>() + { + new KeyValuePair("dog", "bark"), + new KeyValuePair("cat", "meow"), + new KeyValuePair("cow", "mooo"), + }; + + var ruleAttributes = new Dictionary(); + + Assert.True(Matcher.AttributeMatch(tags, ruleAttributes)); + } + + [Fact] + public void TestAttributeMatchingWithoutSpanTags() + { + var ruleAttributes = new Dictionary() + { + { "dog", "bar?" }, + { "cow", "mooo" }, + }; + + Assert.False(Matcher.AttributeMatch(new List>(), ruleAttributes)); + Assert.False(Matcher.AttributeMatch(null, ruleAttributes)); + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs new file mode 100644 index 0000000000..57391ce932 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs @@ -0,0 +1,123 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +public class TestRulesCache +{ + [Fact] + public void TestExpiredRulesCache() + { + var testClock = new TestClock(new DateTime(2023, 4, 15)); + var rulesCache = new RulesCache(testClock, "testId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOnSampler()); + + // advance the clock by 2 hours + testClock.Advance(TimeSpan.FromHours(2)); + Assert.True(rulesCache.Expired()); + } + + [Fact] + public void TestUpdateRules() + { + var clock = new TestClock(); + + // set up rules cache with a default rule + var defaultRule = this.CreateDefaultRule(1, 0.05); + var stats = new Statistics() + { + RequestCount = 10, + SampleCount = 5, + BorrowCount = 5, + }; + + var cache = new RulesCache(clock, "test", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) + { + RuleAppliers = new List() + { + { new SamplingRuleApplier("testId", clock, defaultRule, stats) }, + }, + }; + + // update the default rule + var newDefaultRule = this.CreateDefaultRule(10, 0.20); + cache.UpdateRules(new List { newDefaultRule }); + + // asserts + Assert.Single(cache.RuleAppliers); + var rule = cache.RuleAppliers[0]; + Assert.Equal("Default", rule.RuleName); + + // assert that the statistics has been copied over to new rule + Assert.Equal(10, rule.Statistics.RequestCount); + Assert.Equal(5, rule.Statistics.BorrowCount); + Assert.Equal(5, rule.Statistics.SampleCount); + } + + [Fact] + public void TestUpdateRulesRemovesOlderRule() + { + var clock = new TestClock(); + + // set up rule cache with 2 rules + var rulesCache = new RulesCache(clock, "test", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) + { + RuleAppliers = new List() + { + { new SamplingRuleApplier("testId", clock, this.CreateDefaultRule(1, 0.05), null) }, + { new SamplingRuleApplier("testId", clock, this.CreateRule("Rule1", 5, 0.20, 1), null) }, + }, + }; + + // the update contains only the default rule + var newDefaultRule = this.CreateDefaultRule(10, 0.20); + rulesCache.UpdateRules(new List { newDefaultRule }); + + // assert that Rule1 doesn't exist in rules cache + Assert.Single(rulesCache.RuleAppliers); + Assert.Single(rulesCache.RuleAppliers); + Assert.Equal("Default", rulesCache.RuleAppliers[0].RuleName); + } + + // TODO: Add tests for matching sampling rules once the reservoir and fixed rate samplers are added. + + private SamplingRule CreateDefaultRule(int reservoirSize, double fixedRate) + { + return this.CreateRule("Default", reservoirSize, fixedRate, 10000); + } + + private SamplingRule CreateRule(string name, int reservoirSize, double fixedRate, int priority) + { + return new SamplingRule( + ruleName: name, + priority: priority, + fixedRate: fixedRate, + reservoirSize: reservoirSize, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "*", + serviceType: "*", + urlPath: "*", + version: 1, + attributes: new Dictionary()); + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs new file mode 100644 index 0000000000..b62fc93c41 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -0,0 +1,221 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +public class TestSamplingRuleApplier +{ + [Fact] + public void TestRuleMatchesWithAllAttributes() + { + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "localhost", + httpMethod: "GET", + resourceArn: "arn:aws:lambda:us-west-2:123456789012:function:my-function", + serviceName: "myServiceName", + serviceType: "AWS::Lambda::Function", + urlPath: "/helloworld", + version: 1, + attributes: new Dictionary()); + + var activityTags = new Dictionary() + { + { "http.host", "localhost" }, + { "http.method", "GET" }, + { "http.url", @"http://127.0.0.1:5000/helloworld" }, + { "faas.id", "arn:aws:lambda:us-west-2:123456789012:function:my-function" }, + }; + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.True(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_lambda"))); + } + + [Fact] + public void TestRuleMatchesWithWildcardAttributes() + { + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "myServiceName", + serviceType: "*", + urlPath: "/helloworld", + version: 1, + attributes: new Dictionary()); + + var activityTags = new Dictionary() + { + { "http.host", "localhost" }, + { "http.method", "GET" }, + { "http.url", @"http://127.0.0.1:5000/helloworld" }, + }; + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.True(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_ec2"))); + } + + [Fact] + public void TestRuleMatchesWithNoActivityAttributes() + { + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "myServiceName", + serviceType: "*", + urlPath: "/helloworld", + version: 1, + attributes: new Dictionary()); + + var activityTags = new Dictionary(); + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.False(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_ec2"))); + } + + [Fact] + public void TestRuleMatchesWithNoActivityAttributesAndWildcardRules() + { + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "myServiceName", + serviceType: "*", + urlPath: "*", + version: 1, + attributes: new Dictionary()); + + var activityTags = new Dictionary(); + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.True(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_ec2"))); + } + + [Fact] + public void TestRuleMatchesWithHttpTarget() + { + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "*", + serviceType: "*", + urlPath: "/hello*", + version: 1, + attributes: new Dictionary()); + + var activityTags = new Dictionary() + { + { "http.target", "/helloworld" }, + }; + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.True(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", string.Empty))); + } + + [Fact] + public void TestAttributeMatching() + { + var ruleAttributes = new Dictionary() + { + { "dog", "bark" }, + { "cat", "meow" }, + }; + + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "*", + serviceType: "*", + urlPath: "*", + version: 1, + attributes: ruleAttributes); + + var activityTags = new Dictionary() + { + { "http.target", "/helloworld" }, + { "dog", "bark" }, + { "cat", "meow" }, + }; + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.True(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_ecs"))); + } + + [Fact] + public void TestAttributeMatchingWithLessActivityTags() + { + var ruleAttributes = new Dictionary() + { + { "dog", "bark" }, + { "cat", "meow" }, + }; + + var rule = new SamplingRule( + ruleName: "testRule", + priority: 1, + fixedRate: 0.05, + reservoirSize: 1, + host: "*", + httpMethod: "*", + resourceArn: "*", + serviceName: "*", + serviceType: "*", + urlPath: "*", + version: 1, + attributes: ruleAttributes); + + var activityTags = new Dictionary() + { + { "http.target", "/helloworld" }, + { "dog", "bark" }, + }; + + var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); + Assert.False(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_ecs"))); + } + + // TODO: Add more test cases for ShouldSample once the sampling logic is added. +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs new file mode 100644 index 0000000000..d5a1babd46 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs @@ -0,0 +1,60 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +internal static class Utils +{ + internal static SamplingParameters CreateSamplingParametersWithTags(Dictionary tags) + { + ActivityTraceId traceId = ActivityTraceId.CreateRandom(); + ActivitySpanId parentSpanId = ActivitySpanId.CreateRandom(); + ActivityTraceFlags traceFlags = ActivityTraceFlags.None; + + var parentContext = new ActivityContext(traceId, parentSpanId, traceFlags); + + var tagList = new List>(); + + foreach (var tag in tags) + { + tagList.Add(new KeyValuePair(tag.Key, tag.Value)); + } + + return new SamplingParameters( + parentContext, + traceId, + "myActivityName", + ActivityKind.Server, + tagList, + null); + } + + internal static Resource CreateResource(string serviceName, string cloudPlatform) + { + var resourceAttributes = new List>() + { + new KeyValuePair("service.name", serviceName), + new KeyValuePair("cloud.platform", cloudPlatform), + }; + + return ResourceBuilder.CreateEmpty().AddAttributes(resourceAttributes).Build(); + } +} From 71a7216cb76ab45deca8cc1793a3286cdb77f827 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 27 Apr 2023 11:24:08 -0700 Subject: [PATCH 0686/1499] [AzureMonitor] Add ApplicationInsightsSamplerOptions to improve Dependency Injection support (#1160) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 6 +++- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 6 +++- .../netstandard2.0/PublicAPI.Unshipped.txt | 6 +++- .../ApplicationInsightsSampler.cs | 17 ++++++----- .../ApplicationInsightsSamplerOptions.cs | 30 +++++++++++++++++++ .../CHANGELOG.md | 5 ++++ .../ApplicationInsightsSamplerTests.cs | 18 +++++------ 7 files changed, 68 insertions(+), 20 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt index f3fcff5f07..05811804ba 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,3 +1,7 @@ OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(float samplingRatio) -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions! options) -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.ApplicationInsightsSamplerOptions() -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.get -> float +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.set -> void override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt index f3fcff5f07..05811804ba 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,3 +1,7 @@ OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(float samplingRatio) -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions! options) -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.ApplicationInsightsSamplerOptions() -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.get -> float +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.set -> void override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index f3fcff5f07..05811804ba 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,7 @@ OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(float samplingRatio) -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions! options) -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.ApplicationInsightsSamplerOptions() -> void +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.get -> float +OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.set -> void override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs index f632e2662e..e1501d439d 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs @@ -33,18 +33,19 @@ public class ApplicationInsightsSampler : Sampler /// /// Initializes a new instance of the class. /// - /// - /// Ratio of telemetry that should be sampled. - /// For example; Specifying 0.4F means 40% of traces are sampled and 60% are dropped. + /// + /// for configuring the ApplicationInsightsSampler. /// - public ApplicationInsightsSampler(float samplingRatio) + public ApplicationInsightsSampler(ApplicationInsightsSamplerOptions options) { + Guard.ThrowIfNull(options); + // Ensure passed ratio is between 0 and 1, inclusive - Guard.ThrowIfOutOfRange((double)samplingRatio, min: 0.0, max: 1.0); + Guard.ThrowIfOutOfRange((double)options.SamplingRatio, min: 0.0, max: 1.0); - this.samplingRatio = samplingRatio; - this.Description = "ApplicationInsightsSampler{" + samplingRatio + "}"; - var sampleRate = (float)Math.Round(samplingRatio * 100); + this.samplingRatio = options.SamplingRatio; + this.Description = "ApplicationInsightsSampler{" + options.SamplingRatio + "}"; + var sampleRate = (float)Math.Round(options.SamplingRatio * 100); this.recordAndSampleSamplingResult = new SamplingResult( SamplingDecision.RecordAndSample, new Dictionary diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs new file mode 100644 index 0000000000..f33fc66f8b --- /dev/null +++ b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs @@ -0,0 +1,30 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Extensions.AzureMonitor; + +/// +/// Options for configuring an to customize +/// its sampling behavior. +/// +public class ApplicationInsightsSamplerOptions +{ + /// + /// Gets or sets the ratio of telemetry items to be sampled. The value must be between 0.0F and 1.0F, inclusive. + /// For example, specifying 0.4 means that 40% of traces are sampled and 60% are dropped. + /// + public float SamplingRatio { get; set; } +} diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index c1d8afc74c..d80c688a3f 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Updated `ApplicationInsightsSampler` constructor to accept + `ApplicationInsightsSamplerOptions` instead of a float `samplingRatio`, and + introduced `ApplicationInsightsSamplerOptions` for Dependency Injection + support. + ## 1.0.0-beta.3 Released 2023-Feb-07 diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs index 5c14e435e1..b4e8fa607a 100644 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs @@ -49,18 +49,18 @@ public void VerifyHashAlgorithmCorrectness() SamplingParameters testParams2 = new SamplingParameters(parentContext, testId2, "TestActivity", ActivityKind.Internal); // Verify sample ratio: 0 - ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(samplingRatio: 0); + ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0 }); Assert.Equal(SamplingDecision.RecordOnly, zeroSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.RecordOnly, zeroSampler.ShouldSample(testParams2).Decision); // Verify sample ratio: 1 - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(samplingRatio: 1); + ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 1 }); Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams2).Decision); // Verify sample ratio: 0.5. // This is below the sample score for testId2, but strict enough to drop testId1 - ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(samplingRatio: 0.5f); + ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0.5f }); Assert.Equal(SamplingDecision.RecordOnly, ratioSampler.ShouldSample(testParams1).Decision); Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); } @@ -68,27 +68,27 @@ public void VerifyHashAlgorithmCorrectness() [Fact] public void ApplicationInsightsSamplerGoodArgs() { - ApplicationInsightsSampler pointFiveSampler = new ApplicationInsightsSampler(0.5f); + ApplicationInsightsSampler pointFiveSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0.5f }); Assert.NotNull(pointFiveSampler); - ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(0f); + ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0f }); Assert.NotNull(zeroSampler); - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(1f); + ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 1f }); Assert.NotNull(oneSampler); } [Fact] public void ApplicationInsightsSamplerBadArgs() { - Assert.Throws(() => new ApplicationInsightsSampler(-2f)); - Assert.Throws(() => new ApplicationInsightsSampler(2f)); + Assert.Throws(() => new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = -2f })); + Assert.Throws(() => new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 2f })); } [Fact] public void GetDescriptionMatchesSpec() { var expectedDescription = "ApplicationInsightsSampler{0.5}"; - Assert.Equal(expectedDescription, new ApplicationInsightsSampler(0.5f).Description); + Assert.Equal(expectedDescription, new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0.5f }).Description); } } From cc74494ac2c0ded5dbb63fadade24bff608dbb33 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Tue, 2 May 2023 17:03:27 -0700 Subject: [PATCH 0687/1499] Add atshaw43 as AWS components co-owner (#1166) --- .github/component_owners.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 5cee7a9e64..5a84797f2a 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -5,9 +5,10 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - - lupengamzn + - atshaw43 src/OpenTelemetry.Contrib.Instrumentation.AWS/: - srprash + - atshaw43 src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch @@ -66,11 +67,13 @@ components: - iskiselev src/OpenTelemetry.Sampler.AWS/: - srprash + - atshaw43 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - - lupengamzn + - atshaw43 test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/: - srprash + - atshaw43 test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch @@ -140,3 +143,4 @@ components: - iskiselev test/OpenTelemetry.Sampler.AWS.Tests/: - srprash + - atshaw43 From 8b8a3aee934acbb42459d61ff1786a84a7227fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 5 May 2023 21:12:57 +0200 Subject: [PATCH 0688/1499] [Exporter.Stackdriver] Fix readme after project rename (#1168) --- src/OpenTelemetry.Exporter.Stackdriver/README.md | 2 +- src/OpenTelemetry.Instrumentation.Runtime/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 4f26b1e07a..69d6a3fcbf 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -22,7 +22,7 @@ constructor for specifying path to the service account credential. ## Installation ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.Stackdriver --prerelease +dotnet add package OpenTelemetry.Exporter.Stackdriver --prerelease ``` ## Traces diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index fb95cc1dce..79734bfc79 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -151,7 +151,7 @@ garbage collection has occurred. The API used to retrieve the value is: -* [GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo): +* [GC.GetGCMemoryInfo().GenerationInfo\[i\].SizeAfterBytes](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo): Represents the size in bytes of a generation on exit of the GC reported in GCMemoryInfo. Note that this API on .NET 6 has a [bug](https://github.com/dotnet/runtime/pull/60309). For .NET 6, heap size is retrieved with an internal method `GC.GetGenerationSize`, From 6e32f90799c77edd38abbf631c110afdc2ba836a Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 5 May 2023 19:25:06 -0700 Subject: [PATCH 0689/1499] [Extensions.AzureMonitor] Update changelog for release (#1169) --- src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md index d80c688a3f..bcc4a71014 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2023-May-05 + * Updated `ApplicationInsightsSampler` constructor to accept `ApplicationInsightsSamplerOptions` instead of a float `samplingRatio`, and introduced `ApplicationInsightsSamplerOptions` for Dependency Injection From f91f73e94e823b857bc9607f1eeddb0aafaf5f55 Mon Sep 17 00:00:00 2001 From: Havret Date: Mon, 8 May 2023 18:12:51 +0200 Subject: [PATCH 0690/1499] [Exporter.Geneva] Fix installation instruction (#1171) --- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index fd69f95187..0faf04b64a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -26,7 +26,7 @@ Install the latest stable version of [`Microsoft.Extensions.Logging`](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) ```shell -dotnet add package OpenTelemetry.Exporter.Geneva +dotnet add package Microsoft.Extensions.Logging ``` This snippet shows how to configure the Geneva Exporter for Logs From d050f98e5f093cd38b693246b932919804ae7a3b Mon Sep 17 00:00:00 2001 From: Darius Letterman Date: Tue, 9 May 2023 22:35:57 +0200 Subject: [PATCH 0691/1499] Fix indexing issue in GetSanitizedCategoryName (#1175) --- src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index d4238b86f7..701748e2e9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -476,7 +476,7 @@ private static string GetSanitizedCategoryName(string categoryName) var cur = categoryName[i]; if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) { - result[i] = cur; + result[validNameLength] = cur; ++validNameLength; } } From 2e543dfa686192d4eda0397c47fa8e4b04c9db92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 May 2023 18:07:52 +0200 Subject: [PATCH 0692/1499] [Instrumentation.MySqlData,Instrumentation.StackExchangeRedis] Avoid SetStatus(Unset) (#1180) --- .../MySqlDataInstrumentation.cs | 12 +----------- .../RedisProfilerEntryToActivityConverter.cs | 2 -- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs index 60478a2edf..75d5d87814 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs @@ -168,17 +168,7 @@ private static void AfterExecuteCommand() return; } - try - { - if (activity.IsAllDataRequested) - { - activity.SetStatus(Status.Unset); - } - } - finally - { - activity.Stop(); - } + activity.Stop(); } private void BeforeExecuteCommand(MySqlDataTraceCommand command) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 0cd0bdc319..1b7a432db8 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -107,8 +107,6 @@ public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfi // Total: // command.ElapsedTime; // 00:00:32.4988020 - activity.SetStatus(Status.Unset); - activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName, command.Flags.ToString()); if (options.SetVerboseDatabaseStatements) From 9465067b27556bcaaa71318e8a2eae3879dbd7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 May 2023 19:32:00 +0200 Subject: [PATCH 0693/1499] [Instrumenation.MySqlData] Fix typos (#1178) --- .../MySqlDataInstrumentationEventSource.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs index 573e486199..d2721d4375 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs @@ -32,13 +32,13 @@ public void UnknownMySqlTraceEventType(int mysqlEventId, string message) this.WriteEvent(1, mysqlEventId, message); } - [Event(2, Message = "Error accured while processing trace event, MySqlTraceEventType: {0}, Message {1}, Exception: {2}", Level = EventLevel.Error)] + [Event(2, Message = "Error while processing trace event, MySqlTraceEventType: {0}, Message {1}, Exception: {2}", Level = EventLevel.Error)] public void ErrorTraceEvent(int mysqlEventId, string message, string exception) { this.WriteEvent(1, mysqlEventId, message, exception); } - [Event(2, Message = "Error accured while initializing MySqlDataInstrumentation, Message {0}, Exception: {1}", Level = EventLevel.Warning)] + [Event(3, Message = "Error while initializing MySqlDataInstrumentation, Message {0}, Exception: {1}", Level = EventLevel.Warning)] public void ErrorInitialize(string message, string exception) { this.WriteEvent(1, message, exception); From 006c06e23cbd3200751ef5331c1708c2d17d0b40 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 10 May 2023 18:18:46 -0700 Subject: [PATCH 0694/1499] Add azure vm resource detector (#1182) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 + .../AzureVMResourceDetector.cs | 68 ++++++++++++ .../AzureVmMetaDataRequestor.cs | 43 ++++++++ .../AzureVmMetadataResponse.cs | 104 ++++++++++++++++++ .../CHANGELOG.md | 3 + ...enTelemetry.ResourceDetectors.Azure.csproj | 1 + .../AzureResourceDetectorTests.cs | 37 +++++++ 7 files changed, 259 insertions(+) create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e3dbfb40fc..00226a19b1 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,6 @@ OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector +OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.AzureVMResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs new file mode 100644 index 0000000000..d71e890aac --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs @@ -0,0 +1,68 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.ResourceDetectors.Azure; + +/// +/// Resource detector for Azure VM environment. +/// +public sealed class AzureVMResourceDetector : IResourceDetector +{ + internal static readonly IReadOnlyCollection ExpectedAzureAmsFields = new string[] + { + "azInst_location", + "azInst_name", + "azInst_osType", + "azInst_resourceGroupName", + "azInst_resourceId", + "azInst_sku", + "azInst_subscriptionId", + "azInst_version", + "azInst_vmId", + "azInst_vmSize", + "azInst_vmScaleSetName", + ResourceSemanticConventions.AttributeServiceInstance, + }; + + /// + public Resource Detect() + { + List>? attributeList = null; + try + { + var vmMetaDataResponse = AzureVmMetaDataRequestor.GetAzureVmMetaDataResponse(); + if (vmMetaDataResponse != null) + { + attributeList = new List>(ExpectedAzureAmsFields.Count); + foreach (var field in ExpectedAzureAmsFields) + { + attributeList.Add(new KeyValuePair(field, vmMetaDataResponse.GetValueForField(field))); + } + } + } + catch + { + // TODO: log exception. + return Resource.Empty; + } + + return attributeList == null ? Resource.Empty : new Resource(attributeList); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs new file mode 100644 index 0000000000..4bbb36ab03 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Net.Http; +using System.Text.Json; + +namespace OpenTelemetry.ResourceDetectors.Azure; + +internal static class AzureVmMetaDataRequestor +{ + private const string AzureVmMetadataEndpointURL = "http://169.254.169.254/metadata/instance/compute?api-version=2021-12-13&format=json"; + + public static Func GetAzureVmMetaDataResponse { get; internal set; } = GetAzureVmMetaDataResponseDefault!; + + public static AzureVmMetadataResponse? GetAzureVmMetaDataResponseDefault() + { + using var httpClient = new HttpClient(); + + httpClient.DefaultRequestHeaders.Add("Metadata", "True"); + var res = httpClient.GetStringAsync(AzureVmMetadataEndpointURL).ConfigureAwait(false).GetAwaiter().GetResult(); + + if (res != null) + { + return JsonSerializer.Deserialize(res); + } + + return null; + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs new file mode 100644 index 0000000000..952a8ec9cf --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs @@ -0,0 +1,104 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json.Serialization; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.ResourceDetectors.Azure; +internal sealed class AzureVmMetadataResponse +{ + [JsonPropertyName("location")] + public string? Location { get; set; } + + [JsonPropertyName("name")] + public string? Name { get; set; } + + [JsonPropertyName("osType")] + public string? OsType { get; set; } + + [JsonPropertyName("resourceGroupName")] + public string? ResourceGroupName { get; set; } + + [JsonPropertyName("resourceId")] + public string? ResourceId { get; set; } + + [JsonPropertyName("sku")] + public string? Sku { get; set; } + + [JsonPropertyName("subscriptionId")] + public string? SubscriptionId { get; set; } + + [JsonPropertyName("version")] + public string? Version { get; set; } + + [JsonPropertyName("vmId")] + public string? VmId { get; set; } + + [JsonPropertyName("vmScaleSetName")] + public string? VmScaleSetName { get; set; } + + [JsonPropertyName("vmSize")] + public string? VmSize { get; set; } + + internal string GetValueForField(string fieldName) + { + string? amsValue = null; + switch (fieldName) + { + case "azInst_osType": + amsValue = this.OsType; + break; + case "azInst_location": + amsValue = this.Location; + break; + case "azInst_name": + amsValue = this.Name; + break; + case "azInst_sku": + amsValue = this.Sku; + break; + case "azInst_version": + amsValue = this.Version; + break; + case "azInst_vmId": + case ResourceSemanticConventions.AttributeServiceInstance: + amsValue = this.VmId; + break; + case "azInst_vmSize": + amsValue = this.VmSize; + break; + case "azInst_subscriptionId": + amsValue = this.SubscriptionId; + break; + case "azInst_resourceId": + amsValue = this.ResourceId; + break; + case "azInst_resourceGroupName": + amsValue = this.ResourceGroupName; + break; + case "azInst_vmScaleSetName": + amsValue = this.VmScaleSetName; + break; + } + + if (amsValue == null) + { + amsValue = string.Empty; + } + + return amsValue; + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 32baee3f54..d5cad43209 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added Azure VM resource detector. +([#1182](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1182)) + ## 1.0.0-alpha.1 Released 2023-Apr-19 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index 19c0f3f377..5ddc90d943 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -10,6 +10,7 @@ + diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index 42404a0a1a..b3e64b2056 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using OpenTelemetry.Resources; +using OpenTelemetry.Trace; using Xunit; namespace OpenTelemetry.ResourceDetectors.Azure.Tests; @@ -61,6 +62,42 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() } } + [Fact] + public void TestAzureVmResourceDetector() + { + AzureVmMetaDataRequestor.GetAzureVmMetaDataResponse = () => + { + return new AzureVmMetadataResponse() + { + // using values same as key for test. + Location = "azInst_location", + Name = "azInst_name", + OsType = "azInst_osType", + ResourceGroupName = "azInst_resourceGroupName", + ResourceId = "azInst_resourceId", + Sku = "azInst_sku", + SubscriptionId = "azInst_subscriptionId", + Version = "azInst_version", + VmId = "azInst_vmId", + VmSize = "azInst_vmSize", + VmScaleSetName = "azInst_vmScaleSetName", + }; + }; + + var resource = ResourceBuilder.CreateEmpty().AddDetector(new AzureVMResourceDetector()).Build(); + Assert.NotNull(resource); + foreach (var field in AzureVMResourceDetector.ExpectedAzureAmsFields) + { + if (field == ResourceSemanticConventions.AttributeServiceInstance) + { + Assert.Contains(new KeyValuePair(field, "azInst_vmId"), resource.Attributes); + continue; + } + + Assert.Contains(new KeyValuePair(field, field), resource.Attributes); + } + } + public void Dispose() { foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) From 8d75f2aa85ed61a73627b25aa603745f31352e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 11 May 2023 06:58:29 +0200 Subject: [PATCH 0695/1499] [ResourceDetectors.AWS] Extract package (#1140) Co-authored-by: Utkarsh Umesan Pillai --- .../comp_resourcedetectors_aws.md | 41 ++++++++++ .github/component_owners.yml | 6 ++ .../package-ResourceDetectors.AWS.yml | 67 ++++++++++++++++ opentelemetry-dotnet-contrib.sln | 14 ++++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 10 +-- .../netstandard2.0/PublicAPI.Unshipped.txt | 28 ++++--- .../AWSXRayEventSource.cs | 23 +----- .../CHANGELOG.md | 6 ++ ...elemetry.Contrib.Extensions.AWSXRay.csproj | 8 -- .../README.md | 33 -------- .../Resources/AWSLambdaResourceDetector.cs | 78 ------------------- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 6 ++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 12 +++ .../AWSEBSResourceDetector.cs | 15 ++-- .../AWSEC2ResourceDetector.cs | 13 ++-- .../AWSECSResourceDetector.cs | 25 +++--- .../AWSEKSResourceDetector.cs | 15 ++-- .../AWSResourcesEventSource.cs | 48 ++++++++++++ .../AWSSemanticConventions.cs | 2 +- .../AssemblyInfo.cs | 23 ++++++ .../CHANGELOG.md | 7 ++ .../Http/Handler.cs | 6 +- .../ServerCertificateValidationProvider.cs | 17 ++-- .../Models/AWSEBSMetadataModel.cs | 2 +- .../Models/AWSEC2IdentityDocumentModel.cs | 2 +- .../Models/AWSEKSClusterDataModel.cs | 2 +- .../Models/AWSEKSClusterInformationModel.cs | 2 +- ...OpenTelemetry.ResourceDetectors.AWS.csproj | 33 ++++++++ .../README.md | 47 +++++++++++ .../ResourceDetectorUtils.cs | 6 +- ...ry.Contrib.Extensions.AWSXRay.Tests.csproj | 34 -------- .../TestAWSLambdaResourceDetector.cs | 45 ----------- .../AWSEBSResourceDetectorTests.cs} | 9 +-- .../AWSEC2ResourceDetectorTests.cs} | 7 +- .../AWSECSResourceDetectorTests.cs} | 25 +++--- .../AWSEKSResourceDetectorTests.cs} | 15 ++-- .../Http/CertificateUploader.cs | 6 +- .../Http/HandlerTests.cs} | 12 ++- ...rverCertificateValidationProviderTests.cs} | 12 ++- ...lemetry.ResourceDetectors.AWS.Tests.csproj | 52 +++++++++++++ .../SampleAWSEBSMetadataModel.cs | 4 +- .../SampleAWSEC2IdentityDocumentModel.cs | 4 +- .../SampleMetadataFiles/environment.conf | 0 .../SampleMetadataFiles/testcgroup | 0 .../SampleMetadataFiles/testekstoken | 0 .../metadatav4-response-container-ec2.json | 0 ...metadatav4-response-container-fargate.json | 0 .../metadatav4-response-task-ec2.json | 0 .../metadatav4-response-task-fargate.json | 0 51 files changed, 481 insertions(+), 343 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md create mode 100644 .github/workflows/package-ResourceDetectors.AWS.yml delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/AWSEBSResourceDetector.cs (84%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/AWSEC2ResourceDetector.cs (89%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/AWSECSResourceDetector.cs (85%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/AWSEKSResourceDetector.cs (87%) create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/AWSSemanticConventions.cs (97%) create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/Http/Handler.cs (83%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/Http/ServerCertificateValidationProvider.cs (83%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/Models/AWSEBSMetadataModel.cs (93%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/Models/AWSEC2IdentityDocumentModel.cs (93%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/Models/AWSEKSClusterDataModel.cs (92%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/Models/AWSEKSClusterInformationModel.cs (92%) create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/README.md rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/Resources => OpenTelemetry.ResourceDetectors.AWS}/ResourceDetectorUtils.cs (94%) delete mode 100644 test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs => OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs} (86%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs => OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs} (92%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs => OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs} (92%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs => OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs} (91%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/Http/CertificateUploader.cs (97%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs => OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs} (84%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs => OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs} (90%) create mode 100644 test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/SampleAWSEBSMetadataModel.cs (87%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/SampleAWSEC2IdentityDocumentModel.cs (89%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/SampleMetadataFiles/environment.conf (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/SampleMetadataFiles/testcgroup (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/SampleMetadataFiles/testekstoken (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/ecs_metadata/metadatav4-response-container-ec2.json (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/ecs_metadata/metadatav4-response-container-fargate.json (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/ecs_metadata/metadatav4-response-task-ec2.json (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources => OpenTelemetry.ResourceDetectors.AWS.Tests}/ecs_metadata/metadatav4-response-task-fargate.json (100%) diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md new file mode 100644 index 0000000000..06df0a1b1d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.ResourceDetectors.AWS +about: Issue with OpenTelemetry.ResourceDetectors.AWS +labels: comp:resourcedetectors.aws +--- + +# Issue with OpenTelemetry.ResourceDetectors.AWS + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 5a84797f2a..b6185d5eb7 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -60,6 +60,9 @@ components: - xiang17 src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch + src/OpenTelemetry.ResourceDetectors.AWS/: + - srprash + - atshaw43 src/OpenTelemetry.ResourceDetectors.Azure/: - rajkumar-rangaraj - vishweshbankwar @@ -136,6 +139,9 @@ components: - xiang17 test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch + test/OpenTelemetry.ResourceDetectors.AWS.Tests/: + - srprash + - atshaw43 test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - rajkumar-rangaraj - vishweshbankwar diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml new file mode 100644 index 0000000000..bad669cca3 --- /dev/null +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -0,0 +1,67 @@ +name: Pack OpenTelemetry.ResourceDetectors.AWS + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'ResourceDetectors.AWS-*' # trigger when we create a tag with prefix "ResourceDetectors.AWS-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + permissions: + contents: write + env: + PROJECT: OpenTelemetry.ResourceDetectors.AWS + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index b8556d00c5..be1461ec46 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -284,6 +284,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS", "src\OpenTelemetry.ResourceDetectors.AWS\OpenTelemetry.ResourceDetectors.AWS.csproj", "{71BABAC0-E299-48BF-93E2-C11C3840B037}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS.Tests", "test\OpenTelemetry.ResourceDetectors.AWS.Tests\OpenTelemetry.ResourceDetectors.AWS.Tests.csproj", "{DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -590,6 +594,14 @@ Global {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA}.Release|Any CPU.Build.0 = Release|Any CPU + {71BABAC0-E299-48BF-93E2-C11C3840B037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {71BABAC0-E299-48BF-93E2-C11C3840B037}.Debug|Any CPU.Build.0 = Debug|Any CPU + {71BABAC0-E299-48BF-93E2-C11C3840B037}.Release|Any CPU.ActiveCfg = Release|Any CPU + {71BABAC0-E299-48BF-93E2-C11C3840B037}.Release|Any CPU.Build.0 = Release|Any CPU + {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -680,6 +692,8 @@ Global {9B7F7605-ADFF-4A47-9B64-FFF3E2EC9DEA} = {93503FAF-D43D-48C0-818C-92EB90F7606B} {93503FAF-D43D-48C0-818C-92EB90F7606B} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {71BABAC0-E299-48BF-93E2-C11C3840B037} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt index 1c7d693b10..94d28c0a6e 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,12 +1,4 @@ OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions @@ -14,4 +6,4 @@ override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extrac override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index ad1e9026fa..639ff112a6 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,21 +1,19 @@ -#nullable enable -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable> -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>?' -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void *REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void *REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.AWSECSResourceDetector() -> void *REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void *REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.AWSLambdaResourceDetector() -> void +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? *REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector *REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Resources.ResourceBuilderExtensions -*REMOVED*static OpenTelemetry.Resources.ResourceBuilderExtensions.AddDetector(this OpenTelemetry.Resources.ResourceBuilder resourceBuilder, OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector resourceDetector) -> OpenTelemetry.Resources.ResourceBuilder \ No newline at end of file +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils +*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs index 4e0ba6c9d9..1dff10cda4 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Contrib.Extensions.AWSXRay; [EventSource(Name = "OpenTelemetry-AWS-XRay")] internal class AWSXRayEventSource : EventSource { - public static AWSXRayEventSource Log = new AWSXRayEventSource(); + public static AWSXRayEventSource Log = new(); [NonEvent] public void ActivityContextExtractException(string format, Exception ex) @@ -34,15 +34,6 @@ public void ActivityContextExtractException(string format, Exception ex) } } - [NonEvent] - public void ResourceAttributesExtractException(string format, Exception ex) - { - if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) - { - this.FailedToExtractResourceAttributes(format, ex.ToInvariantString()); - } - } - [Event(1, Message = "Failed to extract activity context in format: '{0}', context: '{1}'.", Level = EventLevel.Warning)] public void FailedToExtractActivityContext(string format, string exception) { @@ -54,16 +45,4 @@ public void FailedToInjectActivityContext(string format, string error) { this.WriteEvent(2, format, error); } - - [Event(3, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] - public void FailedToExtractResourceAttributes(string format, string exception) - { - this.WriteEvent(3, format, exception); - } - - [Event(4, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] - public void FailedToValidateCertificate(string format, string error) - { - this.WriteEvent(4, format, error); - } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index 168af55a2f..e3cc1d02e0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -18,6 +18,12 @@ supporting ResourceBuilderExtensions extension, and migrate all detectors to implement OpenTelemetry.Resources.IResourceDetector ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) +* Drop support for `AWSLambdaResourceDetector`. + AWS Lambda Resources are detected by `OpenTelemetry.Instrumentation.AWSLambda` + package + ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) +* Extract AWS Resource Detectors to dedicated package `OpenTelemetry.ResourceDetectors.AWS` + ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) ## 1.2.0 diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj index 17a1720792..797ef8aca7 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj @@ -13,14 +13,6 @@ - - - - - - - - diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md index 7c6cc02923..25faacb78e 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md @@ -38,39 +38,6 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() Sdk.SetDefaultTextMapPropagator(new AWSXRayPropagator()); ``` -### AWS Resource Detectors - -The ADOT .NET SDK supports automatically recording metadata in -EC2, Elastic Beanstalk, ECS, and EKS environments. You can configure -the corresponding resource detector to the `TracerProvider` following -the EC2 example below. - -```csharp -using OpenTelemetry; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; -using OpenTelemetry.Resources; - -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .SetResourceBuilder(ResourceBuilder - .CreateDefault() - .AddDetector(new AWSEC2ResourceDetector())) - .Build(); -``` - -The resource detectors will record the following metadata based on where -your application is running: - -- **AWSEC2ResourceDetector**: cloud provider, cloud platform, account id, -cloud available zone, host id, host type, aws region, host name. -- **AWSEBSResourceDetector**: cloud provider, cloud platform, service name, -service namespace, instance id, service version. -- **AWSECSResourceDetector**: cloud provider, cloud platform, container id. -- **AWSEKSResourceDetector**: cloud provider, cloud platform, cluster name, -container id. -- **AWSLambdaResourceDetector**: cloud provider, cloud platform, aws region, -function name, function version. - ## References - [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs deleted file mode 100644 index 5db498f547..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSLambdaResourceDetector.cs +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using OpenTelemetry.Resources; - -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; - -/// -/// Resource detector for application running in AWS Lambda. -/// -public class AWSLambdaResourceDetector : IResourceDetector -{ - private const string AWSLambdaRegion = "AWS_REGION"; - private const string AWSLambdaFunctionName = "AWS_LAMBDA_FUNCTION_NAME"; - private const string AWSLambdaFunctionVersion = "AWS_LAMBDA_FUNCTION_VERSION"; - - /// - /// Detector the required and optional resource attributes from AWS Lambda. - /// - /// Resource with key-value pairs of resource attributes. - public Resource Detect() - { - try - { - return new Resource(ExtractResourceAttributes()); - } - catch (Exception ex) - { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSLambdaResourceDetector), ex); - } - - return Resource.Empty; - } - - internal static List> ExtractResourceAttributes() - { - var resourceAttributes = new List>() - { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_lambda"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, GetAWSRegion()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasName, GetFunctionName()), - new KeyValuePair(AWSSemanticConventions.AttributeFaasVersion, GetFunctionVersion()), - }; - - return resourceAttributes; - } - - private static string GetAWSRegion() - { - return Environment.GetEnvironmentVariable(AWSLambdaRegion); - } - - private static string GetFunctionName() - { - return Environment.GetEnvironmentVariable(AWSLambdaFunctionName); - } - - private static string GetFunctionVersion() - { - return Environment.GetEnvironmentVariable(AWSLambdaFunctionVersion); - } -} diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..815c92006a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable \ No newline at end of file diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..2ca53c2ade --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector +OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void +OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector +OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void +OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4a0f8f92ce --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,12 @@ +OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector +OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void +OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector +OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void +OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector +OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector.AWSECSResourceDetector() -> void +OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.AWS.AWSEKSResourceDetector +OpenTelemetry.ResourceDetectors.AWS.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void +OpenTelemetry.ResourceDetectors.AWS.AWSEKSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs similarity index 84% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs index a4175dee53..00d53eb3fe 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs @@ -19,11 +19,10 @@ #if NETSTANDARD using System.Runtime.InteropServices; #endif - -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.ResourceDetectors.AWS.Models; using OpenTelemetry.Resources; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running in AWS ElasticBeanstalk environment. @@ -43,7 +42,7 @@ public Resource Detect() { try { - string? filePath = null; + string? filePath; #if NETSTANDARD if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -63,7 +62,7 @@ public Resource Detect() } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSResourceDetector), ex); } return Resource.Empty; @@ -73,9 +72,9 @@ internal static List> ExtractResourceAttributes(AWS { var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), - new KeyValuePair(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), + new(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), + new(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), }; if (metadata != null) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs similarity index 89% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs index b1014ddfa0..954cfdf060 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs @@ -16,11 +16,10 @@ using System; using System.Collections.Generic; - -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.ResourceDetectors.AWS.Models; using OpenTelemetry.Resources; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running on AWS EC2 instance. @@ -49,7 +48,7 @@ public Resource Detect() } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2ResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2ResourceDetector), ex); } return Resource.Empty; @@ -59,9 +58,9 @@ internal static List> ExtractResourceAttributes(AWS { var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), - new KeyValuePair(AWSSemanticConventions.AttributeHostName, hostName), + new(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), + new(AWSSemanticConventions.AttributeHostName, hostName), }; if (identity != null) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs similarity index 85% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index 86d0474c9c..b7de0f6e82 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -19,10 +19,9 @@ using System.Net.Http; using System.Text.Json; using System.Text.RegularExpressions; - using OpenTelemetry.Resources; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running in AWS ECS. @@ -46,8 +45,8 @@ public Resource Detect() var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), + new(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), }; try @@ -60,7 +59,7 @@ public Resource Detect() } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); } try @@ -69,7 +68,7 @@ public Resource Detect() } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); } return new Resource(resourceAttributes); @@ -93,14 +92,14 @@ internal static List> ExtractMetadataV4ResourceAttr if (!containerResponse.RootElement.TryGetProperty("ContainerARN", out var containerArnElement) || containerArnElement.GetString() is not string containerArn) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); return new List>(); } if (!taskResponse.RootElement.TryGetProperty("Cluster", out var clusterArnElement) || clusterArnElement.GetString() is not string clusterArn) { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); return new List>(); } @@ -134,7 +133,7 @@ internal static List> ExtractMetadataV4ResourceAttr } else { - AWSXRayEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{launchTypeElement}'")); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{launchTypeElement}'")); } if (taskResponse.RootElement.TryGetProperty("TaskARN", out var taskArnElement) && taskArnElement.ValueKind == JsonValueKind.String) @@ -172,14 +171,14 @@ internal static List> ExtractMetadataV4ResourceAttr if (logOptionsElement.TryGetProperty("awslogs-group", out var logGroupElement) && logGroupElement.ValueKind == JsonValueKind.String) { var logGroupName = logGroupElement.GetString()!; - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupNames, new string[] { logGroupName })); - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:*" })); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupNames, new[] { logGroupName })); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogGroupArns, new[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:*" })); if (logOptionsElement.TryGetProperty("awslogs-stream", out var logStreamElement) && logStreamElement.ValueKind == JsonValueKind.String) { var logStreamName = logStreamElement.GetString()!; - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamNames, new string[] { logStreamName })); - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamArns, new string[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:log-stream:{logStreamName}" })); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamNames, new[] { logStreamName })); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeLogStreamArns, new[] { $"arn:aws:logs:{logsRegion}:{logsAccount}:log-group:{logGroupName}:log-stream:{logStreamName}" })); } } } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs similarity index 87% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs index a03bc0db02..4f4faf4e77 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs @@ -18,12 +18,11 @@ using System.Collections.Generic; using System.Net.Http; using System.Text; - -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.ResourceDetectors.AWS.Http; +using OpenTelemetry.ResourceDetectors.AWS.Models; using OpenTelemetry.Resources; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running in AWS EKS. @@ -96,7 +95,7 @@ internal static List> ExtractResourceAttributes(str } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to load client token", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to load client token", ex); } return null; @@ -120,7 +119,7 @@ internal static List> ExtractResourceAttributes(str } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get Container Id", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get Container Id", ex); } return null; @@ -140,7 +139,7 @@ internal static List> ExtractResourceAttributes(str } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get cluster information", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get cluster information", ex); } return null; @@ -155,7 +154,7 @@ private static bool IsEKSProcess(string credentials, HttpClientHandler? httpClie } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get EKS information", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get EKS information", ex); } return !string.IsNullOrEmpty(awsAuth); diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs new file mode 100644 index 0000000000..b1f28aa6fc --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs @@ -0,0 +1,48 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.ResourceDetectors.AWS; + +[EventSource(Name = "OpenTelemetry-ResourceDetectors-AWS")] +internal class AWSResourcesEventSource : EventSource +{ + public static AWSResourcesEventSource Log = new(); + + [NonEvent] + public void ResourceAttributesExtractException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, (EventKeywords)(-1))) + { + this.FailedToExtractResourceAttributes(format, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] + public void FailedToExtractResourceAttributes(string format, string exception) + { + this.WriteEvent(3, format, exception); + } + + [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] + public void FailedToValidateCertificate(string format, string error) + { + this.WriteEvent(4, format, error); + } +} diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs index afb4341c5b..b84ce97b17 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS; internal static class AWSSemanticConventions { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs new file mode 100644 index 0000000000..ab546998b6 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.AWS.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md new file mode 100644 index 0000000000..c3c3cc2a72 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## Unreleased + +* Initial release. Previously it was part of `OpenTelemetry.Contrib.Extensions.AWSXRay` + package. + ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs similarity index 83% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs index 5ee545e2dd..27b89b2e2b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/Handler.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs @@ -17,7 +17,7 @@ using System; using System.Net.Http; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; +namespace OpenTelemetry.ResourceDetectors.AWS.Http; internal class Handler { @@ -30,7 +30,7 @@ internal class Handler if (!serverCertificateValidationProvider.IsCertificateLoaded ?? false) { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); return null; } @@ -47,7 +47,7 @@ internal class Handler } catch (Exception ex) { - AWSXRayEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex); } return null; diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs similarity index 83% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs index fc48b71aac..5f26f4f064 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs @@ -20,12 +20,11 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; +namespace OpenTelemetry.ResourceDetectors.AWS.Http; internal class ServerCertificateValidationProvider { - private static readonly ServerCertificateValidationProvider InvalidProvider = - new ServerCertificateValidationProvider(null); + private static readonly ServerCertificateValidationProvider InvalidProvider = new(null); private readonly X509Certificate2Collection? trustedCertificates; @@ -53,14 +52,14 @@ public static ServerCertificateValidationProvider FromCertificateFile(string cer { if (!File.Exists(certificateFile)) { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); return InvalidProvider; } var trustedCertificates = new X509Certificate2Collection(); if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile)) { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); return InvalidProvider; } @@ -109,12 +108,12 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli { if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable"); } if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors) { - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch"); } } @@ -136,7 +135,7 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli } } - AWSXRayEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}"); } // check if at least one certificate in the chain is in our trust list @@ -158,7 +157,7 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli } } - AWSXRayEventSource.Log.FailedToValidateCertificate( + AWSResourcesEventSource.Log.FailedToValidateCertificate( nameof(ServerCertificateValidationProvider), $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}"); } diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs index ffb51d0ec1..a52c3b1526 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs @@ -16,7 +16,7 @@ using System.Text.Json.Serialization; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +namespace OpenTelemetry.ResourceDetectors.AWS.Models; internal class AWSEBSMetadataModel { diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs index 9753ed7af1..666289cb13 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +namespace OpenTelemetry.ResourceDetectors.AWS.Models; internal class AWSEC2IdentityDocumentModel { diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs similarity index 92% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs index 7d36f83063..2345a7ded0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs @@ -16,7 +16,7 @@ using System.Text.Json.Serialization; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +namespace OpenTelemetry.ResourceDetectors.AWS.Models; internal class AWSEKSClusterDataModel { diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs similarity index 92% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs index d6193e47ab..1a9839b6a9 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +namespace OpenTelemetry.ResourceDetectors.AWS.Models; internal class AWSEKSClusterInformationModel { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj new file mode 100644 index 0000000000..a4ec9726b9 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -0,0 +1,33 @@ + + + + + netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. + ResourceDetectors.AWS- + enable + true + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/README.md b/src/OpenTelemetry.ResourceDetectors.AWS/README.md new file mode 100644 index 0000000000..525cbb75f4 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/README.md @@ -0,0 +1,47 @@ +# AWS Resource Detectors + +## Getting Started + +You need to install the +`OpenTelemetry.ResourceDetectors.AWS` to be able to use the +AWS Resource Detectors. + +The ADOT .NET SDK supports automatically recording metadata in +EC2, Elastic Beanstalk, ECS, and EKS environments. + +```shell +dotnet add package OpenTelemetry.ResourceDetectors.AWS +``` + +## Usage + +You can configure AWS resource detector to +the `TracerProvider` with the following EC2 example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.AWS; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .SetResourceBuilder(ResourceBuilder + .CreateEmpty() + .AddDetector(new AWSEC2ResourceDetector())) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **AWSEC2ResourceDetector**: cloud provider, cloud platform, account id, +cloud available zone, host id, host type, aws region, host name. +- **AWSEBSResourceDetector**: cloud provider, cloud platform, service name, +service namespace, instance id, service version. +- **AWSECSResourceDetector**: cloud provider, cloud platform, container id. +- **AWSEKSResourceDetector**: cloud provider, cloud platform, cluster name, +container id. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) +- [AWS Distro for OpenTelemetry .NET](https://aws-otel.github.io/docs/getting-started/dotnet-sdk) diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs rename to src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs index 2006ab040d..a54203e6b0 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Resources/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs @@ -22,16 +22,16 @@ using System.Text.Json; using System.Threading.Tasks; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Class for resource detector utils. /// #pragma warning disable CA1052 -public class ResourceDetectorUtils +internal class ResourceDetectorUtils #pragma warning restore CA1052 { - private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); + private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); internal static async Task SendOutRequest(string url, string method, KeyValuePair? header, HttpClientHandler? handler = null) { diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj index b1b26be408..908d078099 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj @@ -22,40 +22,6 @@ - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs b/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs deleted file mode 100644 index 0b6a62a1cc..0000000000 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSLambdaResourceDetector.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Linq; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; -using Xunit; - -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; - -public class TestAWSLambdaResourceDetector -{ - [Fact] - public void TestDetect() - { - Environment.SetEnvironmentVariable("AWS_REGION", "us-east-1"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", "testfunction"); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", "latest"); - - var resourceAttributes = new AWSLambdaResourceDetector().Detect().Attributes.ToDictionary(x => x.Key, x => x.Value); - - Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); - Assert.Equal("aws_lambda", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); - Assert.Equal("us-east-1", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); - Assert.Equal("testfunction", resourceAttributes[AWSSemanticConventions.AttributeFaasName]); - Assert.Equal("latest", resourceAttributes[AWSSemanticConventions.AttributeFaasVersion]); - - Environment.SetEnvironmentVariable("AWS_REGION", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_NAME", null); - Environment.SetEnvironmentVariable("AWS_LAMBDA_FUNCTION_VERSION", null); - } -} diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs similarity index 86% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs index 7c63dc09d9..82a6337d84 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEBSResourceDetector.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,14 +15,13 @@ // using System.Linq; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests; -public class TestAWSEBSResourceDetector +public class AWSEBSResourceDetectorTests { - private const string AWSEBSMetadataFilePath = "Resources/SampleMetadataFiles/environment.conf"; + private const string AWSEBSMetadataFilePath = "SampleMetadataFiles/environment.conf"; [Fact] public void TestDetect() diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs similarity index 92% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs index 8750fa7cdd..e3a5444e58 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEC2ResourceDetector.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +15,11 @@ // using System.Linq; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests; -public class TestAWSEC2ResourceDetector +public class AWSEC2ResourceDetectorTests { [Fact] public void TestDetect() diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs similarity index 92% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs index 53d029ba0d..02832a6edf 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSECSResourceDetector.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,30 +14,29 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; - using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Http; - -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests; -public class TestAWSECSResourceDetector : IDisposable +public class AWSECSResourceDetectorTests : IDisposable { - private const string AWSECSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; + private const string AWSECSMetadataFilePath = "SampleMetadataFiles/testcgroup"; private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; private const string AWSECSMetadataURLV4Key = "ECS_CONTAINER_METADATA_URI_V4"; - public TestAWSECSResourceDetector() + public AWSECSResourceDetectorTests() { this.ResetEnvironment(); } @@ -134,15 +133,10 @@ internal void ResetEnvironment() internal class MockEcsMetadataEndpoint : IAsyncDisposable { public readonly Uri Address; - private readonly string containerJsonPath; - private readonly string taskJsonPath; private readonly IWebHost server; public MockEcsMetadataEndpoint(string containerJsonPath, string taskJsonPath) { - this.containerJsonPath = containerJsonPath; - this.taskJsonPath = taskJsonPath; - this.server = new WebHostBuilder() .UseKestrel() .UseUrls("http://127.0.0.1:0") // Use random localhost port @@ -152,14 +146,14 @@ public MockEcsMetadataEndpoint(string containerJsonPath, string taskJsonPath) { if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/") { - var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/Resources/{containerJsonPath}"); + var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/{containerJsonPath}"); var data = Encoding.UTF8.GetBytes(content); context.Response.ContentType = "application/json"; await context.Response.Body.WriteAsync(data); } else if (context.Request.Method == HttpMethods.Get && context.Request.Path == "/task") { - var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/Resources/{taskJsonPath}"); + var content = await File.ReadAllTextAsync($"{Environment.CurrentDirectory}/{taskJsonPath}"); var data = Encoding.UTF8.GetBytes(content); context.Response.ContentType = "application/json"; await context.Response.Body.WriteAsync(data); @@ -187,3 +181,4 @@ protected virtual async ValueTask DisposeAsyncCore() } } } +#endif diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs similarity index 91% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs index 338ca4aaa2..643a468c97 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/TestAWSEKSResourceDetector.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,16 +14,17 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System.Linq; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests; -public class TestAWSEKSResourceDetector +public class AWSEKSResourceDetectorTests { - private const string AWSEKSCredentialsPath = "Resources/SampleMetadataFiles/testekstoken"; - private const string AWSEKSMetadataFilePath = "Resources/SampleMetadataFiles/testcgroup"; + private const string AWSEKSCredentialsPath = "SampleMetadataFiles/testekstoken"; + private const string AWSEKSMetadataFilePath = "SampleMetadataFiles/testcgroup"; [Fact] public void TestDetect() @@ -106,3 +107,5 @@ public void TestDeserializeResponse() Assert.Equal("Test", eksClusterInformation.Data.ClusterName); } } + +#endif diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs index 5b9c310500..1a791bf2e3 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/CertificateUploader.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs @@ -14,13 +14,15 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; internal class CertificateUploader : IDisposable { @@ -81,3 +83,5 @@ public void Dispose() } } } + +#endif diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs similarity index 84% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs index cbac46d149..4a08e6ee05 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestHandler.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +14,14 @@ // limitations under the License. // -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; +#if !NETFRAMEWORK + +using OpenTelemetry.ResourceDetectors.AWS.Http; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; -public class TestHandler +public class HandlerTests { private const string INVALIDCRTNAME = "invalidcert"; @@ -42,3 +44,5 @@ public void TestInValidHandler() Assert.Null(Handler.Create(INVALIDCRTNAME)); } } + +#endif diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs similarity index 90% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index baa289b2db..7f69902b6c 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/Http/TestServerCertificateValidationProvider.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,14 +14,16 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Http; +using OpenTelemetry.ResourceDetectors.AWS.Http; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources.Http; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; -public class TestServerCertificateValidationProvider +public class ServerCertificateValidationProviderTests { private const string INVALIDCRTNAME = "invalidcert"; @@ -65,3 +67,5 @@ public void TestInValidCertificate() Assert.False(serverCertificateValidationProvider.IsCertificateLoaded); } } + +#endif diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj new file mode 100644 index 0000000000..061f4214ac --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj @@ -0,0 +1,52 @@ + + + + Unit test project for AWS Detector for OpenTelemetry + + net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs similarity index 87% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs index 5b473225cd..d3a7e3efca 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEBSMetadataModel.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs @@ -14,9 +14,9 @@ // limitations under the License. // -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.ResourceDetectors.AWS.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests; internal class SampleAWSEBSMetadataModel : AWSEBSMetadataModel { diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs similarity index 89% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs index 45a068bf86..b2cefe849a 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleAWSEC2IdentityDocumentModel.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs @@ -14,9 +14,9 @@ // limitations under the License. // -using OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.Models; +using OpenTelemetry.ResourceDetectors.AWS.Models; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.Resources; +namespace OpenTelemetry.ResourceDetectors.AWS.Tests; internal class SampleAWSEC2IdentityDocumentModel : AWSEC2IdentityDocumentModel { diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleMetadataFiles/environment.conf b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleMetadataFiles/environment.conf similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleMetadataFiles/environment.conf rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleMetadataFiles/environment.conf diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleMetadataFiles/testcgroup b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleMetadataFiles/testcgroup similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleMetadataFiles/testcgroup rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleMetadataFiles/testcgroup diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleMetadataFiles/testekstoken b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleMetadataFiles/testekstoken similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/SampleMetadataFiles/testekstoken rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleMetadataFiles/testekstoken diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-ec2.json b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-container-ec2.json similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-ec2.json rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-container-ec2.json diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-fargate.json b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-container-fargate.json similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-container-fargate.json rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-container-fargate.json diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-ec2.json b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-task-ec2.json similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-ec2.json rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-task-ec2.json diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-fargate.json b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-task-fargate.json similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Resources/ecs_metadata/metadatav4-response-task-fargate.json rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/ecs_metadata/metadatav4-response-task-fargate.json From ae4e17d10c1dce45c971649f58e5b07323bbdf6d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 11 May 2023 08:03:00 -0700 Subject: [PATCH 0696/1499] [redis] Modernize the StackExchangeRedis project (#1183) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 8 +- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 8 +- .../CHANGELOG.md | 5 + .../RedisProfilerEntryToActivityConverter.cs | 18 ++- ....Instrumentation.StackExchangeRedis.csproj | 5 +- .../StackExchangeRedisCallsInstrumentation.cs | 11 +- ...xchangeRedisCallsInstrumentationOptions.cs | 3 +- .../TracerProviderBuilderExtensions.cs | 122 +++++++++++++----- src/Shared/ActivityInstrumentationHelper.cs | 4 + src/Shared/DiagnosticSourceListener.cs | 4 + src/Shared/DiagnosticSourceSubscriber.cs | 5 + src/Shared/InstrumentationEventSource.cs | 4 + src/Shared/MultiTypePropertyFetcher.cs | 4 + src/Shared/PropertyFetcher.cs | 4 + ...kExchangeRedisCallsInstrumentationTests.cs | 5 +- 17 files changed, 151 insertions(+), 61 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt index 7d34433831..09483f805d 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,5 +1,5 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.get -> System.TimeSpan OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.set -> void @@ -9,4 +9,8 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrume OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, StackExchange.Redis.IConnectionMultiplexer connection = null, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7d34433831..09483f805d 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +1,5 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.get -> System.TimeSpan OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.set -> void @@ -9,4 +9,8 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrume OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, StackExchange.Redis.IConnectionMultiplexer connection = null, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 3f4f5845c2..4ee8f6ee7b 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added a dependency on `OpenTelemetry.Api.ProviderBuilderExtensions` and + updated `TracerProviderBuilder.AddRedisInstrumentation` to support named + options. + ([#1183](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1183)) + ## 1.0.0-rc9.8 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 1b7a432db8..c4bca0e8ef 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -14,8 +14,6 @@ // limitations under the License. // -using System; -using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Reflection; @@ -27,7 +25,7 @@ namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; internal static class RedisProfilerEntryToActivityConverter { - private static readonly Lazy> MessageDataGetter = new(() => + private static readonly Lazy> MessageDataGetter = new(() => { var redisAssembly = typeof(IProfiledCommand).Assembly; Type profiledCommandType = redisAssembly.GetType("StackExchange.Redis.Profiling.ProfiledCommand"); @@ -39,10 +37,10 @@ internal static class RedisProfilerEntryToActivityConverter if (messageDelegate == null) { - return new Func(source => (null, null)); + return new Func(source => (null, null)); } - return new Func(source => + return new Func(source => { if (source == null) { @@ -55,10 +53,10 @@ internal static class RedisProfilerEntryToActivityConverter return (null, null); } - string script = null; + string? script = null; if (message.GetType() == scriptMessageType) { - script = scriptDelegate.Invoke(message); + script = scriptDelegate?.Invoke(message); } if (commandAndKeyFetcher.TryFetch(message, out var value)) @@ -70,7 +68,7 @@ internal static class RedisProfilerEntryToActivityConverter }); }); - public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfiledCommand command, StackExchangeRedisCallsInstrumentationOptions options) + public static Activity? ProfilerCommandToActivity(Activity? parentActivity, IProfiledCommand command, StackExchangeRedisCallsInstrumentationOptions options) { var name = command.Command; // Example: SET; if (string.IsNullOrEmpty(name)) @@ -176,7 +174,7 @@ public static Activity ProfilerCommandToActivity(Activity parentActivity, IProfi return activity; } - public static void DrainSession(Activity parentActivity, IEnumerable sessionCommands, StackExchangeRedisCallsInstrumentationOptions options) + public static void DrainSession(Activity? parentActivity, IEnumerable sessionCommands, StackExchangeRedisCallsInstrumentationOptions options) { foreach (var command in sessionCommands) { @@ -188,7 +186,7 @@ public static void DrainSession(Activity parentActivity, IEnumerable - private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) + private static Func? CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) { FieldInfo field = classType.GetField(fieldName, flags); if (field != null) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 45aa8b140d..36b3af1092 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -7,6 +7,9 @@ true true Instrumentation.StackExchangeRedis- + enable + true + true @@ -15,7 +18,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs index 8d451142cd..63872364a0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs @@ -14,11 +14,8 @@ // limitations under the License. // -using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Diagnostics; -using System.Threading; using OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -38,9 +35,9 @@ internal class StackExchangeRedisCallsInstrumentation : IDisposable internal static readonly string ActivityName = ActivitySourceName + ".Execute"; internal static readonly Version Version = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Version; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); - internal static readonly IEnumerable> CreationTags = new[] + internal static readonly IEnumerable> CreationTags = new[] { - new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), + new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), }; internal readonly ConcurrentDictionary<(ActivityTraceId TraceId, ActivitySpanId SpanId), (Activity Activity, ProfilingSession Session)> Cache @@ -77,7 +74,7 @@ public StackExchangeRedisCallsInstrumentation(IConnectionMultiplexer connection, /// Returns session for the Redis calls recording. /// /// Session associated with the current span context to record Redis calls. - public Func GetProfilerSessionsFactory() + public Func GetProfilerSessionsFactory() { return () => { @@ -86,7 +83,7 @@ public Func GetProfilerSessionsFactory() return null; } - Activity parent = Activity.Current; + var parent = Activity.Current; // If no parent use the default session. if (parent == null || parent.IdFormat != ActivityIdFormat.W3C) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs index 4b9e7c99f3..0e27e838d5 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.Diagnostics; using OpenTelemetry.Trace; using StackExchange.Redis.Profiling; @@ -43,7 +42,7 @@ public class StackExchangeRedisCallsInstrumentationOptions /// : the activity being enriched. /// : the profiled redis command from which additional information can be extracted to enrich the activity. /// - public Action Enrich { get; set; } + public Action? Enrich { get; set; } /// /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index 22c7e56494..3bd9947930 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -14,7 +14,8 @@ // limitations under the License. // -using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.StackExchangeRedis; using OpenTelemetry.Internal; using StackExchange.Redis; @@ -26,6 +27,71 @@ namespace OpenTelemetry.Trace; /// public static class TracerProviderBuilderExtensions { + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// + /// Note: A will be resolved using the + /// application . + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder) + => AddRedisInstrumentation(builder, name: null, connection: null, configure: null); + + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// being configured. + /// to instrument. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + IConnectionMultiplexer connection) + { + Guard.ThrowIfNull(connection); + + return AddRedisInstrumentation(builder, name: null, connection, configure: null); + } + + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// + /// Note: A will be resolved using the + /// application . + /// + /// being configured. + /// Callback to configure options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + Action configure) + { + Guard.ThrowIfNull(configure); + + return AddRedisInstrumentation(builder, name: null, connection: null, configure); + } + + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// being configured. + /// to instrument. + /// Callback to configure options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + IConnectionMultiplexer connection, + Action configure) + { + Guard.ThrowIfNull(connection); + Guard.ThrowIfNull(configure); + + return AddRedisInstrumentation(builder, name: null, connection, configure); + } + /// /// Enables automatic data collection of outgoing requests to Redis. /// @@ -35,55 +101,41 @@ public static class TracerProviderBuilderExtensions /// resolved using the application . /// /// being configured. + /// Optional name which is used when retrieving options. /// Optional to instrument. /// Optional callback to configure options. /// The instance of to chain the calls. public static TracerProviderBuilder AddRedisInstrumentation( this TracerProviderBuilder builder, - IConnectionMultiplexer connection = null, - Action configure = null) + string? name, + IConnectionMultiplexer? connection, + Action? configure) { Guard.ThrowIfNull(builder); - if (builder is not IDeferredTracerProviderBuilder deferredTracerProviderBuilder) - { - if (connection == null) - { - throw new NotSupportedException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} must be supplied when dependency injection is unavailable - to enable dependency injection use the OpenTelemetry.Extensions.Hosting package"); - } + name ??= Options.DefaultName; - return AddRedisInstrumentation(builder, connection, new StackExchangeRedisCallsInstrumentationOptions(), configure); + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); } - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - if (connection == null) + return builder + .AddSource(StackExchangeRedisCallsInstrumentation.ActivitySourceName) + .AddInstrumentation(sp => { - connection = (IConnectionMultiplexer)sp.GetService(typeof(IConnectionMultiplexer)); if (connection == null) { - throw new InvalidOperationException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} could not be resolved through application {nameof(IServiceProvider)}"); + connection = sp.GetService(); + if (connection == null) + { + throw new InvalidOperationException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} could not be resolved through application {nameof(IServiceProvider)}"); + } } - } - AddRedisInstrumentation( - builder, - connection, - sp.GetOptions(), - configure); - }); - } - - private static TracerProviderBuilder AddRedisInstrumentation( - TracerProviderBuilder builder, - IConnectionMultiplexer connection, - StackExchangeRedisCallsInstrumentationOptions options, - Action configure) - { - configure?.Invoke(options); - - return builder - .AddInstrumentation(() => new StackExchangeRedisCallsInstrumentation(connection, options)) - .AddSource(StackExchangeRedisCallsInstrumentation.ActivitySourceName); + return new StackExchangeRedisCallsInstrumentation( + connection, + sp.GetRequiredService>().Get(name)); + }); } } diff --git a/src/Shared/ActivityInstrumentationHelper.cs b/src/Shared/ActivityInstrumentationHelper.cs index 1ba9636dfa..1c2f97ce70 100644 --- a/src/Shared/ActivityInstrumentationHelper.cs +++ b/src/Shared/ActivityInstrumentationHelper.cs @@ -14,9 +14,13 @@ // limitations under the License. // +#nullable disable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Diagnostics; using System.Linq.Expressions; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; diff --git a/src/Shared/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs index 9dc3f74a7b..38a6ee2410 100644 --- a/src/Shared/DiagnosticSourceListener.cs +++ b/src/Shared/DiagnosticSourceListener.cs @@ -14,10 +14,14 @@ // limitations under the License. // +#nullable disable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Collections.Generic; using System.Diagnostics; using OpenTelemetry.Internal; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index 99a25bbf7f..5435b90a3f 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -13,11 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. // + +#nullable disable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using OpenTelemetry.Internal; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; diff --git a/src/Shared/InstrumentationEventSource.cs b/src/Shared/InstrumentationEventSource.cs index 07f9f56057..4321679472 100644 --- a/src/Shared/InstrumentationEventSource.cs +++ b/src/Shared/InstrumentationEventSource.cs @@ -14,9 +14,13 @@ // limitations under the License. // +#nullable disable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Diagnostics.Tracing; using OpenTelemetry.Internal; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; diff --git a/src/Shared/MultiTypePropertyFetcher.cs b/src/Shared/MultiTypePropertyFetcher.cs index 122d40743f..4c8fb3fb0c 100644 --- a/src/Shared/MultiTypePropertyFetcher.cs +++ b/src/Shared/MultiTypePropertyFetcher.cs @@ -14,10 +14,14 @@ // limitations under the License. // +#nullable disable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Collections.Concurrent; using System.Linq; using System.Reflection; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; diff --git a/src/Shared/PropertyFetcher.cs b/src/Shared/PropertyFetcher.cs index 8aab31e0be..4549699132 100644 --- a/src/Shared/PropertyFetcher.cs +++ b/src/Shared/PropertyFetcher.cs @@ -14,9 +14,13 @@ // limitations under the License. // +#nullable disable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Linq; using System.Reflection; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 0539a93d4e..55cdb58011 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -13,6 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // + using System; using System.Diagnostics; using System.Net; @@ -304,13 +305,13 @@ public async Task ProfilerSessionsHandleMultipleSpans() public void StackExchangeRedis_BadArgs() { TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddRedisInstrumentation(null)); + Assert.Throws(() => builder.AddRedisInstrumentation(connection: null)); var activityProcessor = new Mock>(); var exception = Assert.Throws(() => Sdk.CreateTracerProviderBuilder() .AddProcessor(activityProcessor.Object) - .AddRedisInstrumentation(null) + .AddRedisInstrumentation(name: null, connection: null, configure: null) .Build()); Assert.Equal("StackExchange.Redis IConnectionMultiplexer could not be resolved through application IServiceProvider", exception.Message); } From 9e3fe44908af7af867fecbf42cb543fc4893c440 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 11 May 2023 19:41:58 -0700 Subject: [PATCH 0697/1499] [ResourceDetector.Azure] Follow ups (#1185) --- .../AppServiceResourceDetector.cs | 16 +++--- .../AzureVMResourceDetector.cs | 22 ++++----- .../AzureVmMetadataResponse.cs | 5 +- .../ResourceAttributeConstants.cs | 49 +++++++++++++++++++ .../AzureResourceDetectorTests.cs | 37 +++++++------- 5 files changed, 87 insertions(+), 42 deletions(-) create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index e71e8842a0..277756f7cb 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -28,14 +28,14 @@ public sealed class AppServiceResourceDetector : IResourceDetector { internal static readonly IReadOnlyDictionary AppServiceResourceAttributes = new Dictionary { - ["appSrv_SiteName"] = "WEBSITE_SITE_NAME", - [ResourceSemanticConventions.AttributeServiceName] = "WEBSITE_SITE_NAME", - [ResourceSemanticConventions.AttributeServiceInstance] = "WEBSITE_INSTANCE_ID", - ["appSrv_SlotName"] = "WEBSITE_SLOT_NAME", - ["appSrv_wsStamp"] = "WEBSITE_HOME_STAMPNAME", - ["appSrv_wsHost"] = "WEBSITE_HOSTNAME", - ["appSrv_wsOwner"] = "WEBSITE_OWNER_NAME", - ["appSrv_ResourceGroup"] = "WEBSITE_RESOURCE_GROUP", + [ResourceAttributeConstants.AppServiceSiteName] = ResourceAttributeConstants.AppServiceSiteNameEnvVar, + [ResourceSemanticConventions.AttributeServiceName] = ResourceAttributeConstants.AppServiceSiteNameEnvVar, + [ResourceSemanticConventions.AttributeServiceInstance] = ResourceAttributeConstants.AppServiceInstanceIdEnvVar, + [ResourceAttributeConstants.AppServiceSlotName] = ResourceAttributeConstants.AppServiceSlotNameEnvVar, + [ResourceAttributeConstants.AppServiceStamp] = ResourceAttributeConstants.AppServiceStampNameEnvVar, + [ResourceAttributeConstants.AppServiceHost] = ResourceAttributeConstants.AppServiceHostNameEnvVar, + [ResourceAttributeConstants.AppServiceOwner] = ResourceAttributeConstants.AppServiceOwnerNameEnvVar, + [ResourceAttributeConstants.AppServiceResourceGroup] = ResourceAttributeConstants.AppServiceResourceGroupEnvVar, }; /// diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs index d71e890aac..f5f702de74 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs @@ -27,17 +27,17 @@ public sealed class AzureVMResourceDetector : IResourceDetector { internal static readonly IReadOnlyCollection ExpectedAzureAmsFields = new string[] { - "azInst_location", - "azInst_name", - "azInst_osType", - "azInst_resourceGroupName", - "azInst_resourceId", - "azInst_sku", - "azInst_subscriptionId", - "azInst_version", - "azInst_vmId", - "azInst_vmSize", - "azInst_vmScaleSetName", + ResourceAttributeConstants.AzureVmId, + ResourceAttributeConstants.AzureVmLocation, + ResourceAttributeConstants.AzureVmName, + ResourceAttributeConstants.AzureVmOsType, + ResourceAttributeConstants.AzureVmResourceGroup, + ResourceAttributeConstants.AzureVmResourceId, + ResourceAttributeConstants.AzureVmSku, + ResourceAttributeConstants.AzureVmVersion, + ResourceAttributeConstants.AzureVmSize, + ResourceAttributeConstants.AzureVmScaleSetName, + ResourceAttributeConstants.AzureVmSubscriptionId, ResourceSemanticConventions.AttributeServiceInstance, }; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs index 952a8ec9cf..41a2c1bc2f 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs @@ -94,10 +94,7 @@ internal string GetValueForField(string fieldName) break; } - if (amsValue == null) - { - amsValue = string.Empty; - } + amsValue ??= string.Empty; return amsValue; } diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs new file mode 100644 index 0000000000..299046fe60 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.ResourceDetectors.Azure; +internal class ResourceAttributeConstants +{ + // AppService resource attributes + internal const string AppServiceSiteName = "appSrv_SiteName"; + internal const string AppServiceSlotName = "appSrv_SlotName"; + internal const string AppServiceStamp = "appSrv_wsStamp"; + internal const string AppServiceHost = "appSrv_wsHost"; + internal const string AppServiceOwner = "appSrv_wsOwner"; + internal const string AppServiceResourceGroup = "appSrv_ResourceGroup"; + + // Azure VM resource attributes + internal const string AzureVmId = "azInst_vmId"; + internal const string AzureVmLocation = "azInst_location"; + internal const string AzureVmName = "azInst_name"; + internal const string AzureVmOsType = "azInst_osType"; + internal const string AzureVmResourceGroup = "azInst_resourceGroupName"; + internal const string AzureVmResourceId = "azInst_resourceId"; + internal const string AzureVmSku = "azInst_sku"; + internal const string AzureVmVersion = "azInst_version"; + internal const string AzureVmSize = "azInst_vmSize"; + internal const string AzureVmScaleSetName = "azInst_vmScaleSetName"; + internal const string AzureVmSubscriptionId = "azInst_subscriptionId"; + + // AppService environment variables + internal const string AppServiceSiteNameEnvVar = "WEBSITE_SITE_NAME"; + internal const string AppServiceInstanceIdEnvVar = "WEBSITE_INSTANCE_ID"; + internal const string AppServiceSlotNameEnvVar = "WEBSITE_SLOT_NAME"; + internal const string AppServiceStampNameEnvVar = "WEBSITE_HOME_STAMPNAME"; + internal const string AppServiceHostNameEnvVar = "WEBSITE_HOSTNAME"; + internal const string AppServiceOwnerNameEnvVar = "WEBSITE_OWNER_NAME"; + internal const string AppServiceResourceGroupEnvVar = "WEBSITE_RESOURCE_GROUP"; +} diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index b3e64b2056..03c04a34da 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -31,7 +31,7 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() { foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) { - if (kvp.Value == "WEBSITE_SITE_NAME") + if (kvp.Value == ResourceAttributeConstants.AppServiceSiteNameEnvVar) { continue; } @@ -40,7 +40,7 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() } // Special case for service.name and appSrv_SiteName attribute - Environment.SetEnvironmentVariable("WEBSITE_SITE_NAME", "ServiceName"); + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceSiteNameEnvVar, "ServiceName"); } catch { @@ -51,14 +51,13 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) { - if (kvp.Value == "WEBSITE_SITE_NAME") + if (kvp.Value == ResourceAttributeConstants.AppServiceSiteNameEnvVar) { Assert.Contains(new KeyValuePair(kvp.Key, "ServiceName"), resource.Attributes); + continue; } - else - { - Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); - } + + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); } } @@ -70,17 +69,17 @@ public void TestAzureVmResourceDetector() return new AzureVmMetadataResponse() { // using values same as key for test. - Location = "azInst_location", - Name = "azInst_name", - OsType = "azInst_osType", - ResourceGroupName = "azInst_resourceGroupName", - ResourceId = "azInst_resourceId", - Sku = "azInst_sku", - SubscriptionId = "azInst_subscriptionId", - Version = "azInst_version", - VmId = "azInst_vmId", - VmSize = "azInst_vmSize", - VmScaleSetName = "azInst_vmScaleSetName", + VmId = ResourceAttributeConstants.AzureVmId, + Location = ResourceAttributeConstants.AzureVmLocation, + Name = ResourceAttributeConstants.AzureVmName, + OsType = ResourceAttributeConstants.AzureVmOsType, + ResourceGroupName = ResourceAttributeConstants.AzureVmResourceGroup, + ResourceId = ResourceAttributeConstants.AzureVmResourceId, + Sku = ResourceAttributeConstants.AzureVmSku, + Version = ResourceAttributeConstants.AzureVmVersion, + VmSize = ResourceAttributeConstants.AzureVmSize, + VmScaleSetName = ResourceAttributeConstants.AzureVmScaleSetName, + SubscriptionId = ResourceAttributeConstants.AzureVmSubscriptionId, }; }; @@ -90,7 +89,7 @@ public void TestAzureVmResourceDetector() { if (field == ResourceSemanticConventions.AttributeServiceInstance) { - Assert.Contains(new KeyValuePair(field, "azInst_vmId"), resource.Attributes); + Assert.Contains(new KeyValuePair(field, ResourceAttributeConstants.AzureVmId), resource.Attributes); continue; } From d3f70efcee4d48b88753b5759b9f9a8537b02f7b Mon Sep 17 00:00:00 2001 From: Marian Dziubiak Date: Fri, 12 May 2023 17:56:20 +0100 Subject: [PATCH 0698/1499] Assign correct value to ext_dt_spanId in Tld Geneva exporter (#1184) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ .../TLDExporter/TldLogExporter.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 7ce77b5913..0647e6f08a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* TldLogExporter to export `SpanId` value in `ext_dt_spanId` field instead of + `TraceId` value. + ([#1184](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1184)) + ## 1.5.0-alpha.3 Released 2023-Apr-19 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 701748e2e9..2e1a1d1cf1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -257,7 +257,7 @@ internal void SerializeLogRecord(LogRecord logRecord) if (logRecord.SpanId != default) { - eb.AddCountedString("ext_dt_spanId", logRecord.TraceId.ToHexString()); + eb.AddCountedString("ext_dt_spanId", logRecord.SpanId.ToHexString()); partAFieldsCount++; } From ee5749cb3760e9f20697f08167da27bd04733cb7 Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Mon, 15 May 2023 22:05:15 +0200 Subject: [PATCH 0699/1499] #1034: AWS SQS and SNS support (#1051) --- .../CHANGELOG.md | 3 + .../Implementation/AWSMessagingUtils.cs | 30 +++ .../Implementation/AWSServiceHelper.cs | 11 +- .../Implementation/AWSServiceType.cs | 35 ++++ .../AWSTracingPipelineHandler.cs | 12 +- .../Implementation/SnsRequestContextHelper.cs | 72 ++++++++ .../Implementation/SqsRequestContextHelper.cs | 72 ++++++++ ...lemetry.Contrib.Instrumentation.AWS.csproj | 5 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../AWSLambdaInstrumentationOptions.cs | 9 + .../AWSLambdaWrapper.cs | 6 +- .../CHANGELOG.md | 2 + .../Implementation/AWSLambdaUtils.cs | 25 ++- .../Implementation/AWSMessagingUtils.cs | 162 ++++++++++++++++ ...Telemetry.Instrumentation.AWSLambda.csproj | 2 + .../TracerProviderBuilderExtensions.cs | 1 + .../RequestContextHelperTests.cs | 174 ++++++++++++++++++ .../Implementation/TestsHelper.cs | 140 ++++++++++++++ ...y.Contrib.Instrumentation.AWS.Tests.csproj | 2 - .../Tools/Utils.cs | 2 +- .../Implementation/AWSMessagingUtilsTests.cs | 79 ++++++++ 21 files changed, 825 insertions(+), 21 deletions(-) create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs create mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs create mode 100644 test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs create mode 100644 test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md index ae9dc28eab..31cde222a7 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md @@ -6,6 +6,9 @@ ([#1095](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1095)) * Removes `AddAWSInstrumentation` method with default configure default parameter. ([#1117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1117)) +* Global propagator is now used to inject into sent SQS and SNS message + attributes (in addition to X-Ray propagation). + ([#1051](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1051)) ## 1.0.2 diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs new file mode 100644 index 0000000000..d723743c3a --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs @@ -0,0 +1,30 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal static class AWSMessagingUtils +{ + internal static IReadOnlyDictionary InjectIntoDictionary(PropagationContext propagationContext) + { + var carrier = new Dictionary(); + Propagators.DefaultTextMapPropagator.Inject(propagationContext, carrier, (c, k, v) => c[k] = v); + return carrier; + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index b36964b4ea..8c11883331 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.Collections.Generic; using Amazon.Runtime; @@ -24,8 +23,8 @@ internal class AWSServiceHelper { internal static IReadOnlyDictionary ServiceParameterMap = new Dictionary() { - { DynamoDbService, "TableName" }, - { SQSService, "QueueUrl" }, + { AWSServiceType.DynamoDbService, "TableName" }, + { AWSServiceType.SQSService, "QueueUrl" }, }; internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() @@ -34,9 +33,6 @@ internal class AWSServiceHelper { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, }; - private const string DynamoDbService = "DynamoDBv2"; - private const string SQSService = "SQS"; - internal static string GetAWSServiceName(IRequestContext requestContext) => Utils.RemoveAmazonPrefixFromServiceName(requestContext.Request.ServiceName); @@ -47,7 +43,4 @@ internal static string GetAWSOperationName(IRequestContext requestContext) var operationName = Utils.RemoveSuffix(completeRequestName, suffix); return operationName; } - - internal static bool IsDynamoDbService(string service) - => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); } diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs new file mode 100644 index 0000000000..750fab7b23 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; + +internal class AWSServiceType +{ + internal const string DynamoDbService = "DynamoDBv2"; + internal const string SQSService = "SQS"; + internal const string SNSService = "SimpleNotificationService"; // SNS + + internal static bool IsDynamoDbService(string service) + => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); + + internal static bool IsSqsService(string service) + => SQSService.Equals(service, StringComparison.OrdinalIgnoreCase); + + internal static bool IsSnsService(string service) + => SNSService.Equals(service, StringComparison.OrdinalIgnoreCase); +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 78879e2459..47ce566498 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -157,10 +157,20 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon } } - if (AWSServiceHelper.IsDynamoDbService(service)) + if (AWSServiceType.IsDynamoDbService(service)) { activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); } + else if (AWSServiceType.IsSqsService(service)) + { + SqsRequestContextHelper.AddAttributes( + requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); + } + else if (AWSServiceType.IsSnsService(service)) + { + SnsRequestContextHelper.AddAttributes( + requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); + } } private static void AddStatusCodeToActivity(Activity activity, int status_code) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs new file mode 100644 index 0000000000..5b8b09da87 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs @@ -0,0 +1,72 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Linq; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using Amazon.SimpleNotificationService.Model; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +internal class SnsRequestContextHelper +{ + // SQS/SNS message attributes collection size limit according to + // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-metadata.html and + // https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html + private const int MaxMessageAttributes = 10; + + internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary attributes) + { + var parameters = context.Request?.ParameterCollection; + var originalRequest = context.OriginalRequest as PublishRequest; + if (originalRequest?.MessageAttributes == null || parameters == null) + { + return; + } + + if (attributes.Keys.Any(k => originalRequest.MessageAttributes.ContainsKey(k))) + { + // If at least one attribute is already present in the request then we skip the injection. + return; + } + + int attributesCount = originalRequest.MessageAttributes.Count; + if (attributes.Count + attributesCount > MaxMessageAttributes) + { + // TODO: add logging (event source). + return; + } + + int nextAttributeIndex = attributesCount + 1; + foreach (var param in attributes) + { + AddAttribute(parameters, originalRequest, param.Key, param.Value, nextAttributeIndex); + nextAttributeIndex++; + } + } + + private static void AddAttribute(ParameterCollection parameters, PublishRequest originalRequest, string name, string value, int attributeIndex) + { + var prefix = "MessageAttributes.entry." + attributeIndex; + parameters.Add(prefix + ".Name", name); + parameters.Add(prefix + ".Value.DataType", "String"); + parameters.Add(prefix + ".Value.StringValue", value); + + // Add injected attributes to the original request as well. + // This dictionary must be in sync with parameters collection to pass through the MD5 hash matching check. + originalRequest.MessageAttributes.Add(name, new MessageAttributeValue { DataType = "String", StringValue = value }); + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs new file mode 100644 index 0000000000..aad44cd023 --- /dev/null +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs @@ -0,0 +1,72 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Linq; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using Amazon.SQS.Model; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +internal class SqsRequestContextHelper +{ + // SQS/SNS message attributes collection size limit according to + // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-metadata.html and + // https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html + private const int MaxMessageAttributes = 10; + + internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary attributes) + { + var parameters = context.Request?.ParameterCollection; + var originalRequest = context.OriginalRequest as SendMessageRequest; + if (originalRequest?.MessageAttributes == null || parameters == null) + { + return; + } + + if (attributes.Keys.Any(k => originalRequest.MessageAttributes.ContainsKey(k))) + { + // If at least one attribute is already present in the request then we skip the injection. + return; + } + + int attributesCount = originalRequest.MessageAttributes.Count; + if (attributes.Count + attributesCount > MaxMessageAttributes) + { + // TODO: add logging (event source). + return; + } + + int nextAttributeIndex = attributesCount + 1; + foreach (var param in attributes) + { + AddAttribute(parameters, originalRequest, param.Key, param.Value, nextAttributeIndex); + nextAttributeIndex++; + } + } + + private static void AddAttribute(ParameterCollection parameters, SendMessageRequest originalRequest, string name, string value, int attributeIndex) + { + var prefix = "MessageAttribute." + attributeIndex; + parameters.Add(prefix + ".Name", name); + parameters.Add(prefix + ".Value.DataType", "String"); + parameters.Add(prefix + ".Value.StringValue", value); + + // Add injected attributes to the original request as well. + // This dictionary must be in sync with parameters collection to pass through the MD5 hash matching check. + originalRequest.MessageAttributes.Add(name, new MessageAttributeValue { DataType = "String", StringValue = value }); + } +} diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj index 8a63f31667..31fd85a320 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj @@ -9,12 +9,15 @@ - + + + + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 04f3cd5b24..d5ed4319ec 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.AWSLambdaInstrumentationOptions() -> void OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction.get -> bool OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction.set -> void +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.SetParentFromBatch.get -> bool +OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.SetParentFromBatch.set -> void OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> TResult diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs index 1fc086521c..8930b25a49 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs @@ -25,4 +25,13 @@ public class AWSLambdaInstrumentationOptions /// Gets or sets a value indicating whether AWS X-Ray context extraction should be disabled. /// public bool DisableAwsXRayContextExtraction { get; set; } + + /// + /// Gets or sets a value indicating whether the parent Activity should be set when a potentially batched event is received where multiple parents are potentially available (e.g. SQS). + /// If set to true, the parent is set using the last received record (e.g. last message). Otherwise the parent is not set. In both cases, links will be created for such events. + /// + /// + /// Currently, the only event type to which this applies is SQS. + /// + public bool SetParentFromBatch { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index ba62e517cc..937ad3f9aa 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -15,6 +15,7 @@ // using System; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -170,9 +171,10 @@ public static Task TraceAsync( internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) { + IEnumerable links = null; if (parentContext == default) { - parentContext = AWSLambdaUtils.ExtractParentContext(input); + (parentContext, links) = AWSLambdaUtils.ExtractParentContext(input); if (parentContext == default && !DisableAwsXRayContextExtraction) { parentContext = AWSLambdaUtils.GetXRayParentContext(); @@ -184,7 +186,7 @@ internal static Activity OnFunctionStart(TInput input, ILambdaContext co // We assume that functionTags and httpTags have no intersection. var activityName = AWSLambdaUtils.GetFunctionName(context) ?? "AWS Lambda Invoke"; - var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, functionTags.Concat(httpTags)); + var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, functionTags.Concat(httpTags), links); return activity; } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 3cbdb46d89..fb136f3eb6 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -8,6 +8,8 @@ ([#943](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/943)) * BREAKING (behavior): `AddAWSLambdaConfigurations` no longer calls `AddService` ([#1080](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1080)) +* Added tracing of AWS Lambda handlers receiving SQS and SNS messages. + ([#1051](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1051)) ## 1.1.0-beta.2 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index bda6d7677b..234b86fb62 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -20,6 +20,8 @@ using System.Linq; using Amazon.Lambda.APIGatewayEvents; using Amazon.Lambda.Core; +using Amazon.Lambda.SNSEvents; +using Amazon.Lambda.SQSEvents; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; @@ -63,20 +65,33 @@ internal static ActivityContext GetXRayParentContext() return activityContext; } - internal static ActivityContext ExtractParentContext(TInput input) + internal static (ActivityContext ParentContext, IEnumerable Links) ExtractParentContext(TInput input) { - PropagationContext propagationContext = default; + PropagationContext parentContext = default; + IEnumerable links = null; switch (input) { case APIGatewayProxyRequest apiGatewayProxyRequest: - propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayProxyRequest, GetHeaderValues); + parentContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayProxyRequest, GetHeaderValues); break; case APIGatewayHttpApiV2ProxyRequest apiGatewayHttpApiV2ProxyRequest: - propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayHttpApiV2ProxyRequest, GetHeaderValues); + parentContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayHttpApiV2ProxyRequest, GetHeaderValues); + break; + case SQSEvent sqsEvent: + (parentContext, links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + break; + case SQSEvent.SQSMessage sqsMessage: + parentContext = AWSMessagingUtils.ExtractParentContext(sqsMessage); + break; + case SNSEvent snsEvent: + parentContext = AWSMessagingUtils.ExtractParentContext(snsEvent); + break; + case SNSEvent.SNSRecord snsRecord: + parentContext = AWSMessagingUtils.ExtractParentContext(snsRecord); break; } - return propagationContext.ActivityContext; + return (parentContext.ActivityContext, links); } internal static string GetCloudProvider() diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs new file mode 100644 index 0000000000..05f28caacf --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -0,0 +1,162 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Amazon.Lambda.SNSEvents; +using Amazon.Lambda.SQSEvents; +using Newtonsoft.Json; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; + +internal class AWSMessagingUtils +{ + // SNS attribute types: https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html + private const string SnsAttributeTypeString = "String"; + private const string SnsAttributeTypeStringArray = "String.Array"; + private const string SnsMessageAttributes = "MessageAttributes"; + + /// + /// Gets or sets a value indicating whether the parent Activity should be set when SQS message batch is received. + /// If option is set to true then the parent is set using the last received message otherwise the parent is not set at all. + /// + internal static bool SetParentFromMessageBatch { get; set; } + + internal static (PropagationContext ParentContext, IEnumerable Links) ExtractParentContext(SQSEvent sqsEvent) + { + if (sqsEvent?.Records == null) + { + return (default, null); + } + + // We choose the last message (record) as the carrier to set the parent. + var parentRecord = SetParentFromMessageBatch ? sqsEvent.Records.LastOrDefault() : null; + var parentContext = (parentRecord != null) ? ExtractParentContext(parentRecord) : default; + + var links = new List(); + foreach (var record in sqsEvent.Records) + { + var context = ReferenceEquals(record, parentRecord) ? parentContext : ExtractParentContext(record); + if (context != default) + { + links.Add(new ActivityLink(context.ActivityContext)); + } + } + + return (parentContext, links); + } + + internal static PropagationContext ExtractParentContext(SQSEvent.SQSMessage sqsMessage) + { + if (sqsMessage?.MessageAttributes == null) + { + return default; + } + + var parentContext = Propagators.DefaultTextMapPropagator.Extract(default, sqsMessage.MessageAttributes, SqsMessageAttributeGetter); + if (parentContext == default) + { + // SQS subscribed to SNS topic with raw delivery disabled case, i.e. SNS record serialized into SQS body. + // https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html + SNSEvent.SNSMessage snsMessage = GetSnsMessage(sqsMessage); + if (snsMessage != null) + { + parentContext = ExtractParentContext(snsMessage); + } + } + + return parentContext; + } + + internal static PropagationContext ExtractParentContext(SNSEvent snsEvent) + { + // We assume there can be only a single SNS record (message) and records list is kept in the model consistency. + // See https://aws.amazon.com/sns/faqs/#Reliability for details. + var record = snsEvent?.Records?.LastOrDefault(); + return ExtractParentContext(record); + } + + internal static PropagationContext ExtractParentContext(SNSEvent.SNSRecord record) + { + return (record?.Sns?.MessageAttributes != null) ? + Propagators.DefaultTextMapPropagator.Extract(default, record.Sns.MessageAttributes, SnsMessageAttributeGetter) : + default; + } + + internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage message) + { + return (message?.MessageAttributes != null) ? + Propagators.DefaultTextMapPropagator.Extract(default, message.MessageAttributes, SnsMessageAttributeGetter) : + default; + } + + private static IEnumerable SqsMessageAttributeGetter(IDictionary attributes, string attributeName) + { + if (!attributes.TryGetValue(attributeName, out var attribute)) + { + return null; + } + + return attribute?.StringValue != null ? + new[] { attribute.StringValue } : + attribute?.StringListValues; + } + + private static IEnumerable SnsMessageAttributeGetter(IDictionary attributes, string attributeName) + { + if (!attributes.TryGetValue(attributeName, out var attribute)) + { + return null; + } + + switch (attribute?.Type) + { + case SnsAttributeTypeString when attribute.Value != null: + return new[] { attribute.Value }; + case SnsAttributeTypeStringArray when attribute.Value != null: + // Multiple values are stored as CSV (https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html). + return attribute.Value.Split(','); + default: + return null; + } + } + + private static SNSEvent.SNSMessage GetSnsMessage(SQSEvent.SQSMessage sqsMessage) + { + SNSEvent.SNSMessage snsMessage = null; + + var body = sqsMessage.Body; + if (body != null && + body.TrimStart().StartsWith("{", StringComparison.Ordinal) && + body.Contains(SnsMessageAttributes)) + { + try + { + snsMessage = JsonConvert.DeserializeObject(body); + } + catch (Exception) + { + // TODO: log exception. + return null; + } + } + + return snsMessage; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 28929ee4b4..4853e9dbd6 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -10,6 +10,8 @@ + + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index 5be84b18df..e543c9dc94 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -51,6 +51,7 @@ public static TracerProviderBuilder AddAWSLambdaConfigurations( configure?.Invoke(options); AWSLambdaWrapper.DisableAwsXRayContextExtraction = options.DisableAwsXRayContextExtraction; + AWSMessagingUtils.SetParentFromMessageBatch = options.SetParentFromBatch; builder.AddSource(AWSLambdaWrapper.ActivitySourceName); builder.SetResourceBuilder(ResourceBuilder diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs new file mode 100644 index 0000000000..41426d2a61 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -0,0 +1,174 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using Moq; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests.Implementation; + +public class RequestContextHelperTests +{ + private const string TraceId = "5759e988bd862e3fe1be46a994272793"; + private const string ParentId = "53995c3f42cd8ad8"; + private const string TraceState = "trace-state"; + + public RequestContextHelperTests() + { + Sdk.CreateTracerProviderBuilder() + .Build(); + } + + [Theory] + [InlineData(AWSServiceType.SQSService)] + [InlineData(AWSServiceType.SNSService)] + public void AddAttributes_ParametersCollectionSizeReachesLimit_TraceDataNotInjected(string serviceType) + { + AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 10); + var parameters = new ParameterCollection(); + parameters.AddStringParameters(serviceType, originalRequest); + + var request = new Mock(); + request.Setup(x => x.ParameterCollection) + .Returns(parameters); + + var context = new Mock(); + context.Setup(x => x.OriginalRequest) + .Returns(originalRequest); + context.Setup(x => x.Request) + .Returns(request.Object); + + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); + addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + + Assert.Equal(30, parameters.Count); + } + + [Theory] + [InlineData(AWSServiceType.SQSService)] + [InlineData(AWSServiceType.SNSService)] + public void AddAttributes_ParametersCollection_TraceDataInjected(string serviceType) + { + var expectedParameters = new List>() + { + new KeyValuePair("traceparent", $"00-{TraceId}-{ParentId}-00"), + new KeyValuePair("tracestate", "trace-state"), + }; + + AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 0); + var parameters = new ParameterCollection(); + + var request = new Mock(); + request.Setup(x => x.ParameterCollection) + .Returns(parameters); + + var context = new Mock(); + context.Setup(x => x.OriginalRequest) + .Returns(originalRequest); + context.Setup(x => x.Request) + .Returns(request.Object); + + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); + addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + + TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); + } + + [Theory] + [InlineData(AWSServiceType.SQSService)] + [InlineData(AWSServiceType.SNSService)] + public void AddAttributes_ParametersCollectionWithCustomParameter_TraceDataInjected(string serviceType) + { + var expectedParameters = new List>() + { + new KeyValuePair("name1", "value1"), + new KeyValuePair("traceparent", $"00-{TraceId}-{ParentId}-00"), + new KeyValuePair("tracestate", "trace-state"), + }; + + AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 1); + var parameters = new ParameterCollection(); + parameters.AddStringParameters(serviceType, originalRequest); + + var request = new Mock(); + request.Setup(x => x.ParameterCollection) + .Returns(parameters); + + var context = new Mock(); + context.Setup(x => x.OriginalRequest) + .Returns(originalRequest); + context.Setup(x => x.Request) + .Returns(request.Object); + + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); + addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + + TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); + } + + [Theory] + [InlineData(AWSServiceType.SQSService)] + [InlineData(AWSServiceType.SNSService)] + public void AddAttributes_ParametersCollectionWithTraceParent_TraceStateNotInjected(string serviceType) + { + // This test just checks the common implementation logic: + // if at least one attribute is already present the whole injection is skipped. + // We just use default trace propagator as an example which injects only traceparent and tracestate. + + var expectedParameters = new List>() + { + new KeyValuePair("traceparent", $"00-{TraceId}-{ParentId}-00"), + }; + + AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 0); + originalRequest.AddAttribute("traceparent", $"00-{TraceId}-{ParentId}-00"); + + var parameters = new ParameterCollection(); + parameters.AddStringParameters(serviceType, originalRequest); + + var request = new Mock(); + request.Setup(x => x.ParameterCollection) + .Returns(parameters); + + var context = new Mock(); + context.Setup(x => x.OriginalRequest) + .Returns(originalRequest); + context.Setup(x => x.Request) + .Returns(request.Object); + + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); + addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + + TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); + } + + private static PropagationContext CreatePropagationContext() + { + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.None; + var activityContext = new ActivityContext(traceId, parentId, traceFlags, TraceState, isRemote: true); + + return new PropagationContext(activityContext, Baggage.Current); + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs new file mode 100644 index 0000000000..d2d8107015 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -0,0 +1,140 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +using Xunit; +using SNS = Amazon.SimpleNotificationService.Model; +using SQS = Amazon.SQS.Model; + +namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests.Implementation; +internal static class TestsHelper +{ + internal static Action>? CreateAddAttributesAction(string serviceType, IRequestContext context) + { + return serviceType switch + { + AWSServiceType.SQSService => SqsRequestContextHelper.AddAttributes, + AWSServiceType.SNSService => SnsRequestContextHelper.AddAttributes, + _ => throw new NotSupportedException($"Tests for service type {serviceType} not supported."), + }; + } + + internal static AmazonWebServiceRequest CreateOriginalRequest(string serviceType, int attributesCount) + { + AmazonWebServiceRequest resultRequest; + var sendRequest = new SQS::SendMessageRequest(); + var publishRequest = new SNS::PublishRequest(); + Action addAttribute; + + switch (serviceType) + { + case AWSServiceType.SQSService: + resultRequest = sendRequest; + addAttribute = i => sendRequest.MessageAttributes.Add($"name{i}", new SQS::MessageAttributeValue { DataType = "String", StringValue = $"value{i}" }); + break; + case AWSServiceType.SNSService: + resultRequest = publishRequest; + addAttribute = i => publishRequest.MessageAttributes.Add($"name{i}", new SNS::MessageAttributeValue { DataType = "String", StringValue = $"value{i}" }); + break; + default: + throw new NotSupportedException($"Tests for service type {serviceType} not supported."); + } + + for (int i = 1; i <= attributesCount; i++) + { + addAttribute(i); + } + + return resultRequest; + } + + internal static void AddAttribute(this AmazonWebServiceRequest serviceRequest, string name, string value) + { + var sendRequest = serviceRequest as SQS::SendMessageRequest; + var publishRequest = serviceRequest as SNS::PublishRequest; + if (sendRequest != null) + { + sendRequest.MessageAttributes.Add(name, new SQS::MessageAttributeValue { DataType = "String", StringValue = value }); + } + else if (publishRequest != null) + { + publishRequest.MessageAttributes.Add(name, new SNS::MessageAttributeValue { DataType = "String", StringValue = value }); + } + } + + internal static void AddStringParameter(this ParameterCollection parameters, string serviceType, string name, string value, int index) + { + var prefix = $"{GetNamePrefix(serviceType)}.{index}"; + parameters.Add($"{prefix}.Name", name); + parameters.Add($"{prefix}.Value.DataType", "String"); + parameters.Add($"{prefix}.Value.StringValue", value); + } + + internal static void AddStringParameters(this ParameterCollection parameters, string serviceType, AmazonWebServiceRequest serviceRequest) + { + var sendRequest = serviceRequest as SQS::SendMessageRequest; + var publishRequest = serviceRequest as SNS::PublishRequest; + int index = 1; + if (sendRequest != null) + { + foreach (var a in sendRequest.MessageAttributes) + { + AddStringParameter(parameters, serviceType, a.Key, a.Value.StringValue, index++); + } + } + else if (publishRequest != null) + { + foreach (var a in publishRequest.MessageAttributes) + { + AddStringParameter(parameters, serviceType, a.Key, a.Value.StringValue, index++); + } + } + } + + internal static void AssertStringParameters(string serviceType, List> expectedParameters, ParameterCollection parameters) + { + Assert.Equal(expectedParameters.Count * 3, parameters.Count); + + for (int i = 0; i < expectedParameters.Count; i++) + { + var prefix = $"{GetNamePrefix(serviceType)}.{i + 1}"; + static string? Value(ParameterValue p) => (p as StringParameterValue)?.Value; + + Assert.True(parameters.ContainsKey($"{prefix}.Name")); + Assert.Equal(expectedParameters[i].Key, Value(parameters[$"{prefix}.Name"])); + + Assert.True(parameters.ContainsKey($"{prefix}.Value.DataType")); + Assert.Equal("String", Value(parameters[$"{prefix}.Value.DataType"])); + + Assert.True(parameters.ContainsKey($"{prefix}.Value.StringValue")); + Assert.Equal(expectedParameters[i].Value, Value(parameters[$"{prefix}.Value.StringValue"])); + } + } + + private static string GetNamePrefix(string serviceType) + { + return serviceType switch + { + AWSServiceType.SQSService => "MessageAttribute", + AWSServiceType.SNSService => "MessageAttributes.entry", + _ => throw new NotSupportedException($"Tests for service type {serviceType} not supported."), + }; + } +} diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj index 3a88d8a22a..8173c3ff18 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj @@ -11,8 +11,6 @@ - - diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs index 6f060b217d..e24e6899f3 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -79,6 +79,6 @@ public static IEnumerable FindResourceName(Predicate match) public static object? GetTagValue(Activity activity, string tagName) { - return Implementation.Utils.GetTagValue(activity, tagName); + return AWS.Implementation.Utils.GetTagValue(activity, tagName); } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs new file mode 100644 index 0000000000..aba531493b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -0,0 +1,79 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Amazon.Lambda.SQSEvents; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.AWSLambda.Implementation; +using OpenTelemetry.Trace; +using Xunit; +using static Amazon.Lambda.SQSEvents.SQSEvent; + +namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation; + +public class AWSMessagingUtilsTests +{ + private const string TraceId = "0af7651916cd43dd8448eb211c80319c"; + private const string SpanId1 = "b9c7c989f97918e1"; + private const string SpanId2 = "b9c7c989f97918e2"; + + public AWSMessagingUtilsTests() + { + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .Build(); + } + + [Fact] + public void ExtractParentContext_SetParentFromMessageBatchIsDisabled_ParentIsNotSet() + { + AWSMessagingUtils.SetParentFromMessageBatch = false; + var sqsEvent = CreateSqsEventWithMessages(new[] { SpanId1, SpanId2 }); + + (PropagationContext parentContext, IEnumerable links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + + Assert.Equal(default, parentContext); + Assert.Equal(2, links.Count()); + } + + [Fact] + public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetFromLastMessage() + { + AWSMessagingUtils.SetParentFromMessageBatch = true; + var sqsEvent = CreateSqsEventWithMessages(new[] { SpanId1, SpanId2 }); + + (PropagationContext parentContext, IEnumerable links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + + Assert.NotEqual(default, parentContext); + Assert.Equal(SpanId2, parentContext.ActivityContext.SpanId.ToHexString()); + Assert.Equal(2, links.Count()); + } + + private static SQSEvent CreateSqsEventWithMessages(string[] spans) + { + var @event = new SQSEvent { Records = new List() }; + for (var i = 0; i < spans.Length; i++) + { + var message = new SQSMessage { MessageAttributes = new Dictionary() }; + message.MessageAttributes.Add("traceparent", new MessageAttribute { StringValue = $"00-{TraceId}-{spans[i]}-01" }); + message.MessageAttributes.Add("tracestate", new MessageAttribute { StringValue = $"k1=v1,k2=v2" }); + @event.Records.Add(message); + } + + return @event; + } +} From 4030777378e536cccb71e928f409ded3623dc8da Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Mon, 15 May 2023 23:03:16 +0200 Subject: [PATCH 0700/1499] Add InfluxDB exporter (#1176) --- .../ISSUE_TEMPLATE/comp_exporter_influxdb.md | 41 ++ .github/component_owners.yml | 4 + .../workflows/package-Exporter.InfluxDB.yml | 67 +++ .../Examples.InfluxDB.csproj | 19 + .../InfluxDB/Examples.InfluxDB/Program.cs | 42 ++ opentelemetry-dotnet-contrib.sln | 24 + .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 20 + .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 20 + .../CHANGELOG.md | 1 + .../IMetricsWriter.cs | 25 + .../InfluxDBEventSource.cs | 38 ++ .../InfluxDBExporterExtensions.cs | 81 +++ .../InfluxDBMetricsExporter.cs | 75 +++ .../InfluxDBMetricsExporterOptions.cs | 55 ++ .../MetricsSchema.cs | 27 + .../OpenTelemetry.Exporter.InfluxDB.csproj | 24 + .../PointDataExtensions.cs | 32 ++ src/OpenTelemetry.Exporter.InfluxDB/README.md | 136 +++++ .../TelegrafPrometheusWriterV1.cs | 153 ++++++ .../TelegrafPrometheusWriterV2.cs | 160 ++++++ .../InfluxDBMetricsExporterTests.cs | 480 ++++++++++++++++++ ...enTelemetry.Exporter.InfluxDB.Tests.csproj | 32 ++ .../Utils/AssertUtils.cs | 35 ++ .../Utils/InfluxDBFakeServer.cs | 67 +++ ...xDBMetricsExporterOptionsTestExtensions.cs | 30 ++ .../Utils/LineProtocolParser.cs | 99 ++++ .../Utils/PointData.cs | 28 + 29 files changed, 1815 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_influxdb.md create mode 100644 .github/workflows/package-Exporter.InfluxDB.yml create mode 100644 examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj create mode 100644 examples/InfluxDB/Examples.InfluxDB/Program.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/README.md create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs create mode 100644 src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_influxdb.md b/.github/ISSUE_TEMPLATE/comp_exporter_influxdb.md new file mode 100644 index 0000000000..94ae00bab7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_exporter_influxdb.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Exporter.InfluxDB +about: Issue with OpenTelemetry.Exporter.InfluxDB +labels: comp:exporter.influxdb +--- + +# Issue with OpenTelemetry.Exporter.InfluxDB + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index b6185d5eb7..95df28fb23 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -15,6 +15,8 @@ components: - reyang - utpilla - Yun-Ting + src/OpenTelemetry.Exporter.InfluxDB/: + - havret src/OpenTelemetry.Exporter.Instana/: - zivaninstana src/OpenTelemetry.Exporter.OneCollector/: @@ -95,6 +97,8 @@ components: - reyang - utpilla - Yun-Ting + test/OpenTelemetry.Exporter.InfluxDB.Tests/: + - havret test/OpenTelemetry.Exporter.Instana.Tests/: - zivaninstana test/OpenTelemetry.Exporter.OneCollector.Benchmarks/: diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml new file mode 100644 index 0000000000..eb3925ea7a --- /dev/null +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -0,0 +1,67 @@ +name: Pack OpenTelemetry.Exporter.InfluxDB + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Exporter.InfluxDB-*' # trigger when we create a tag with prefix "Exporter.InfluxDB-" + +jobs: + build-test-pack: + runs-on: ${{ matrix.os }} + permissions: + contents: write + env: + PROJECT: OpenTelemetry.Exporter.InfluxDB + + strategy: + matrix: + os: [windows-latest] + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetching all + + - uses: actions/setup-dotnet@v3.0.3 + with: + dotnet-version: '7.0.x' + + - name: Install dependencies + run: dotnet restore src/${{env.PROJECT}} + + - name: dotnet build ${{env.PROJECT}} + run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test ${{env.PROJECT}} + run: dotnet test test/${{env.PROJECT}}.Tests + + - name: dotnet pack ${{env.PROJECT}} + run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{env.PROJECT}}-packages + path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj new file mode 100644 index 0000000000..acb83f28cf --- /dev/null +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -0,0 +1,19 @@ + + + + Exe + net7.0 + enable + enable + Examples.InfluxDB + + + + + + + + + + + diff --git a/examples/InfluxDB/Examples.InfluxDB/Program.cs b/examples/InfluxDB/Examples.InfluxDB/Program.cs new file mode 100644 index 0000000000..c9f496f963 --- /dev/null +++ b/examples/InfluxDB/Examples.InfluxDB/Program.cs @@ -0,0 +1,42 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry; +using OpenTelemetry.Exporter.InfluxDB; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; + +Action configureResource = r => r.AddService( + serviceName: "influx-exporter-test", + serviceVersion: typeof(Program).Assembly.GetName().Version?.ToString() ?? "unknown", + serviceInstanceId: Environment.MachineName); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(configureResource) + .AddRuntimeInstrumentation() + .AddInfluxDBMetricsExporter(options => + { + options.Org = "org"; + options.Bucket = "bucket"; + options.Token = "token"; + options.Endpoint = new Uri("http://localhost:8086"); + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV2; + }) + .Build(); + +meterProvider.ForceFlush(); + +await Task.Delay(TimeSpan.FromSeconds(10)); diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index be1461ec46..eb25c80b53 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -288,6 +288,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS.Tests", "test\OpenTelemetry.ResourceDetectors.AWS.Tests\OpenTelemetry.ResourceDetectors.AWS.Tests.csproj", "{DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.InfluxDB", "src\OpenTelemetry.Exporter.InfluxDB\OpenTelemetry.Exporter.InfluxDB.csproj", "{FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.InfluxDB.Tests", "test\OpenTelemetry.Exporter.InfluxDB.Tests\OpenTelemetry.Exporter.InfluxDB.Tests.csproj", "{4847A991-D0C3-4421-B0D3-EA189959E639}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InfluxDB", "InfluxDB", "{2D354354-BAFB-490B-A26F-6A16A52A1A45}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.InfluxDB", "examples\InfluxDB\Examples.InfluxDB\Examples.InfluxDB.csproj", "{B4951583-D432-4E87-85CF-498FDD6A35E6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -602,6 +610,18 @@ Global {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Debug|Any CPU.Build.0 = Debug|Any CPU {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Release|Any CPU.ActiveCfg = Release|Any CPU {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}.Release|Any CPU.Build.0 = Release|Any CPU + {FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}.Release|Any CPU.Build.0 = Release|Any CPU + {4847A991-D0C3-4421-B0D3-EA189959E639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4847A991-D0C3-4421-B0D3-EA189959E639}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4847A991-D0C3-4421-B0D3-EA189959E639}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4847A991-D0C3-4421-B0D3-EA189959E639}.Release|Any CPU.Build.0 = Release|Any CPU + {B4951583-D432-4E87-85CF-498FDD6A35E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4951583-D432-4E87-85CF-498FDD6A35E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4951583-D432-4E87-85CF-498FDD6A35E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4951583-D432-4E87-85CF-498FDD6A35E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -694,6 +714,10 @@ Global {1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {71BABAC0-E299-48BF-93E2-C11C3840B037} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {DE898A1E-920E-476F-B0DB-A98AFD6E3BF4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {FD5E9AC8-DC05-4C64-BDC6-D26F5552808E} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {4847A991-D0C3-4421-B0D3-EA189959E639} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {2D354354-BAFB-490B-A26F-6A16A52A1A45} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7f0ab9edcf --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.set -> void +OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.MetricsSchema.None = 0 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV1 = 1 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV2 = 2 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Metrics.InfluxDBExporterExtensions +static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7f0ab9edcf --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.set -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.set -> void +OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.MetricsSchema.None = 0 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV1 = 1 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV2 = 2 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema +OpenTelemetry.Metrics.InfluxDBExporterExtensions +static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md new file mode 100644 index 0000000000..825c32f0d0 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog diff --git a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs new file mode 100644 index 0000000000..1f33751489 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using InfluxDB.Client; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.InfluxDB; + +internal interface IMetricsWriter +{ + void Write(Metric metric, WriteApi writeApi); +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs new file mode 100644 index 0000000000..61de60ad9b --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Tracing; + +namespace OpenTelemetry.Exporter.InfluxDB; + +/// +/// EventSource event emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Exporter-InfluxDB")] +internal sealed class InfluxDBEventSource : EventSource +{ + public static InfluxDBEventSource Log = new(); + + private InfluxDBEventSource() + { + } + + [Event(1, Message = "Failed to export metrics: '{0}'", Level = EventLevel.Error)] + public void FailedToExport(string exception) + { + this.WriteEvent(1, exception); + } +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs new file mode 100644 index 0000000000..653df5ec48 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs @@ -0,0 +1,81 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using InfluxDB.Client; +using OpenTelemetry.Exporter.InfluxDB; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods for for using InfluxDB. +/// +public static class InfluxDBExporterExtensions +{ + /// + /// Adds InfluxDB exporter to the TracerProvider. + /// + /// builder to use. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static MeterProviderBuilder AddInfluxDBMetricsExporter(this MeterProviderBuilder builder, Action configure) + { + builder.AddReader(_ => + { + var options = new InfluxDBMetricsExporterOptions(); + configure.Invoke(options); + + var influxDbClientOptions = new InfluxDBClientOptions(options.Endpoint.ToString()); + if (!string.IsNullOrWhiteSpace(options.Bucket)) + { + influxDbClientOptions.Bucket = options.Bucket; + } + + if (!string.IsNullOrWhiteSpace(options.Org)) + { + influxDbClientOptions.Org = options.Org; + } + + if (!string.IsNullOrWhiteSpace(options.Token)) + { + influxDbClientOptions.Token = options.Token; + } + + var influxDbClient = new InfluxDBClient(influxDbClientOptions); + var writeApi = influxDbClient.GetWriteApi(new WriteOptions + { + FlushInterval = options.FlushInterval, + }); + var metricsWriter = CreateMetricsWriter(options.MetricsSchema); + var exporter = new InfluxDBMetricsExporter(metricsWriter, influxDbClient, writeApi); + return new PeriodicExportingMetricReader(exporter) + { + TemporalityPreference = MetricReaderTemporalityPreference.Cumulative, + }; + }); + return builder; + } + + private static IMetricsWriter CreateMetricsWriter(MetricsSchema metricsSchema) + { + return metricsSchema switch + { + MetricsSchema.TelegrafPrometheusV2 => new TelegrafPrometheusWriterV2(), + _ => new TelegrafPrometheusWriterV1(), + }; + } +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs new file mode 100644 index 0000000000..0390d351ab --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs @@ -0,0 +1,75 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using InfluxDB.Client; +using InfluxDB.Client.Writes; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.InfluxDB; + +internal sealed class InfluxDBMetricsExporter : BaseExporter +{ + private readonly IMetricsWriter writer; + private readonly InfluxDBClient influxDbClient; + private readonly WriteApi writeApi; + + public InfluxDBMetricsExporter(IMetricsWriter writer, InfluxDBClient influxDbClient, WriteApi writeApi) + { + this.writer = writer; + this.influxDbClient = influxDbClient; + this.writeApi = writeApi; + + this.writeApi.EventHandler += (_, args) => + { + switch (args) + { + case WriteErrorEvent writeErrorEvent: + InfluxDBEventSource.Log.FailedToExport(writeErrorEvent.Exception.Message); + break; + } + }; + } + + public override ExportResult Export(in Batch batch) + { + try + { + foreach (var metric in batch) + { + this.writer.Write(metric, this.writeApi); + } + + return ExportResult.Success; + } + catch (Exception exception) + { + InfluxDBEventSource.Log.FailedToExport(exception.Message); + return ExportResult.Failure; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.writeApi.Dispose(); + this.influxDbClient.Dispose(); + } + + base.Dispose(disposing); + } +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs new file mode 100644 index 0000000000..f0bf2e3011 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs @@ -0,0 +1,55 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +namespace OpenTelemetry.Exporter.InfluxDB; + +/// +/// InfluxDB exporter options. +/// +public class InfluxDBMetricsExporterOptions +{ + /// + /// Gets or sets HTTP/S destination for line protocol. + /// + public Uri Endpoint { get; set; } + + /// + /// Gets or sets name of InfluxDB organization that owns the destination bucket. + /// + public string Org { get; set; } + + /// + /// Gets or sets the name of InfluxDB bucket to which signals will be written. + /// + public string Bucket { get; set; } + + /// + /// Gets or sets the authentication token for InfluxDB. + /// + public string Token { get; set; } + + /// + /// Gets or sets the chosen metrics schema to write. + /// + public MetricsSchema MetricsSchema { get; set; } = MetricsSchema.TelegrafPrometheusV1; + + /// + /// Gets or sets the time to wait at most (milliseconds) with the write. + /// + public int FlushInterval { get; set; } = 1000; +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs b/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs new file mode 100644 index 0000000000..c5c684982e --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.InfluxDB; + +/// +/// The OpenTelemetry->InfluxDB conversion schema. +/// +public enum MetricsSchema +{ + None, + TelegrafPrometheusV1 = 1, + TelegrafPrometheusV2 = 2, +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj new file mode 100644 index 0000000000..b9ea284291 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -0,0 +1,24 @@ + + + + true + An OpenTelemetry .NET exporter that exports to InfluxDB + OpenTelemetry Authors + $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 + + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) + Exporter.InfluxDB- + true + true + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs new file mode 100644 index 0000000000..b849a9db68 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs @@ -0,0 +1,32 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using InfluxDB.Client.Writes; + +namespace OpenTelemetry.Exporter.InfluxDB; + +internal static class PointDataExtensions +{ + public static PointData Tags(this PointData pointData, ReadOnlyTagCollection tags) + { + foreach (var tag in tags) + { + pointData = pointData.Tag(tag.Key, tag.Value.ToString()); + } + + return pointData; + } +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/README.md b/src/OpenTelemetry.Exporter.InfluxDB/README.md new file mode 100644 index 0000000000..550a380c6d --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/README.md @@ -0,0 +1,136 @@ +# InfluxDB Exporter for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.InfluxDB.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.InfluxDB.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) + +The InfluxDB exporter converts OpenTelemetry metrics into the InfluxDB model +following the [OpenTelemetry->InfluxDB conversion schema](https://github.com/influxdata/influxdb-observability/blob/main/docs/index.md). + +This exporter can be used with InfluxDB 2.x and InfluxDB 1.8+ ([see details](#influxdb-18-api-compatibility)). + +## Prerequisite + +* [Get InfluxDB](https://portal.influxdata.com/downloads/) + +### Step 1: Install Package + +```shell +dotnet add package --prerelease OpenTelemetry.Exporter.InfluxDB +``` + +### Step 2: Configure OpenTelemetry MeterProvider + +* When using the [OpenTelemetry.Extensions.Hosting](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Extensions.Hosting/README.md) +package on .NET 6.0+: + +```csharp + services.AddOpenTelemetry() + .WithMetrics(builder => builder + .AddInfluxDBMetricsExporter(options => + { + options.Org = "org"; + options.Bucket = "bucket"; + options.Token = "token"; + options.Endpoint = new Uri("http://localhost:8086"); + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV2; + })); +``` + +* Or configure directly: + + Call the `MeterProviderBuilder.AddInfluxDBMetricsExporter` extension to + register the Prometheus exporter. + +```csharp + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddInfluxDBMetricsExporter(options => + { + options.Org = "org"; + options.Bucket = "bucket"; + options.Token = "token"; + options.Endpoint = new Uri("http://localhost:8086"); + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV2; + }) + .Build(); + builder.Services.AddSingleton(meterProvider); +``` + +## Configuration + +You can configure the `InfluxDBMetricsExporter` through +`InfluxDBMetricsExporterOptions`. + +### Endpoint + +HTTP/S destination for the line protocol. + +### Org + +The name of the InfluxDB organization that owns the destination bucket. + +### Bucket + +The name of the InfluxDB bucket to which signals will be written. + +### Token + +The authentication token for InfluxDB. + +### MetricsSchema + +The chosen metrics schema to write. Default value is +`MetricsSchema.TelegrafPrometheusV1`. + +### FlushInterval + +The time to wait at most (in milliseconds) with the write. Default value +is 1000. + +## InfluxDB 1.8 API Compatibility + +InfluxDB 1.8.0 introduced forward compatibility APIs for InfluxDB 2.0, +allowing you to easily transition from InfluxDB 1.x to InfluxDB 2.0 Cloud +or open source. + +Here's a summary of the client API usage differences: + +* Token + +Use the format `username:password` for an authentication token, e.g., +`my-user:my-password`. If the server doesn't require authentication, +use an empty string (""). + +* Org + +The organization parameter is not used in InfluxDB 1.8. +Use a hyphen ("-") where necessary. + +* Bucket + +Use the format database/retention-policy where a bucket is required. If the +default retention policy should be used, skip the retention policy. +Examples: `telegraf/autogen`, `telegraf`. + +When using InfluxDB 1.8, modify the AddInfluxDBMetricsExporter options +accordingly: + +```csharp + services.AddOpenTelemetry() + .WithMetrics(builder => builder + .AddInfluxDBMetricsExporter(options => + { + options.Org = "-"; + options.Bucket = "telegraf/autogen"; + options.Token = "my-user:my-password"; + options.Endpoint = new Uri("http://localhost:8086"); + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV2; + })); +``` + +## Troubleshooting + +This component uses an +[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) +with the name "OpenTelemetry-Exporter-InfluxDB" for its internal logging. +Please refer to [SDK troubleshooting](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#troubleshooting) +for instructions on seeing these internal logs. diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs new file mode 100644 index 0000000000..e7c80a55c1 --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs @@ -0,0 +1,153 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Globalization; +using InfluxDB.Client; +using InfluxDB.Client.Api.Domain; +using InfluxDB.Client.Writes; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.InfluxDB; + +internal sealed class TelegrafPrometheusWriterV1 : IMetricsWriter +{ + public void Write(Metric metric, WriteApi writeApi) + { + var measurement = metric.Name; + + switch (metric.MetricType) + { + case MetricType.LongGauge: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("gauge", dataPoint.GetGaugeLastValueLong()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.DoubleGauge: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("gauge", dataPoint.GetGaugeLastValueDouble()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.LongSum: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("counter", dataPoint.GetSumLong()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.DoubleSum: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("counter", dataPoint.GetSumDouble()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.LongSumNonMonotonic: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("gauge", dataPoint.GetSumLong()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.DoubleSumNonMonotonic: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("gauge", dataPoint.GetSumDouble()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.Histogram: + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field("count", dataPoint.GetHistogramCount()) + .Field("sum", dataPoint.GetHistogramSum()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + + if (dataPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + pointData = pointData.Field("min", min) + .Field("max", max); + } + + foreach (var histogramBucket in dataPoint.GetHistogramBuckets()) + { + var boundFieldKey = double.IsPositiveInfinity(histogramBucket.ExplicitBound) + ? "+Inf" + : histogramBucket.ExplicitBound.ToString("F", CultureInfo.InvariantCulture); + pointData = pointData.Field(boundFieldKey, histogramBucket.BucketCount); + } + + writeApi.WritePoint(pointData); + } + + break; + } + } +} diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs new file mode 100644 index 0000000000..5350d7eb0b --- /dev/null +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs @@ -0,0 +1,160 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Globalization; +using InfluxDB.Client; +using InfluxDB.Client.Api.Domain; +using InfluxDB.Client.Writes; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.InfluxDB; + +internal sealed class TelegrafPrometheusWriterV2 : IMetricsWriter +{ + public void Write(Metric metric, WriteApi writeApi) + { + var measurement = "prometheus"; + var metricName = metric.Name; + + switch (metric.MetricType) + { + case MetricType.LongGauge: + { + foreach (var metricPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field(metricName, metricPoint.GetGaugeLastValueLong()) + .Tags(metricPoint.Tags) + .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.DoubleGauge: + { + foreach (var metricPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field(metricName, metricPoint.GetGaugeLastValueDouble()) + .Tags(metricPoint.Tags) + .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.LongSum: + { + foreach (var metricPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field(metricName, metricPoint.GetSumLong()) + .Tags(metricPoint.Tags) + .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.DoubleSum: + { + foreach (var metricPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field(metricName, metricPoint.GetSumDouble()) + .Tags(metricPoint.Tags) + .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.LongSumNonMonotonic: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field(metricName, dataPoint.GetSumLong()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.DoubleSumNonMonotonic: + { + foreach (var dataPoint in metric.GetMetricPoints()) + { + var pointData = PointData + .Measurement(measurement) + .Field(metricName, dataPoint.GetSumDouble()) + .Tags(dataPoint.Tags) + .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); + writeApi.WritePoint(pointData); + } + + break; + } + + case MetricType.Histogram: + foreach (var metricPoint in metric.GetMetricPoints()) + { + var basePoint = PointData + .Measurement(measurement) + .Tags(metricPoint.Tags) + .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); + + var headPoint = basePoint + .Field($"{metricName}_count", metricPoint.GetHistogramCount()) + .Field($"{metricName}_sum", metricPoint.GetHistogramSum()); + + if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + headPoint = headPoint + .Field($"{metricName}_min", min) + .Field($"{metricName}_max", max); + } + + writeApi.WritePoint(headPoint); + + foreach (var histogramBucket in metricPoint.GetHistogramBuckets()) + { + var boundFieldKey = double.IsPositiveInfinity(histogramBucket.ExplicitBound) + ? "+Inf" + : histogramBucket.ExplicitBound.ToString("F", CultureInfo.InvariantCulture); + var bucketPoint = basePoint + .Tag("le", boundFieldKey) + .Field($"{metricName}_bucket", histogramBucket.BucketCount); + writeApi.WritePoint(bucketPoint); + } + } + + break; + } + } +} diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs new file mode 100644 index 0000000000..4c62c0a7f8 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -0,0 +1,480 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; +using OpenTelemetry.Exporter.InfluxDB.Tests.Utils; +using OpenTelemetry.Metrics; +using Xunit; + +namespace OpenTelemetry.Exporter.InfluxDB.Tests; + +public class InfluxDBMetricsExporterTests +{ + [Theory] + [InlineData(MetricsSchema.TelegrafPrometheusV1, "test-gauge", "gauge")] + [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "test-gauge")] + public void ExportIntGaugeMetric(MetricsSchema metricsSchema, string measurement, string valueKey) + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("test-meter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = metricsSchema; + }) + .Build(); + + // Act + _ = meter.CreateObservableGauge("test-gauge", () => new[] + { + new Measurement(42, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")), + }); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal(measurement, dataPoint.Measurement); + + Assert.Equal(1, dataPoint.Fields.Count); + AssertUtils.HasField(valueKey, 42L, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Theory] + [InlineData(MetricsSchema.TelegrafPrometheusV1, "test-gauge", "gauge")] + [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "test-gauge")] + public void ExportDoubleGaugeMetric(MetricsSchema metricsSchema, string measurement, string valueKey) + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("test-meter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = metricsSchema; + }) + .Build(); + + // Act + _ = meter.CreateObservableGauge("test-gauge", () => new[] + { + new Measurement(55.42, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")), + }); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal(measurement, dataPoint.Measurement); + + Assert.Equal(1, dataPoint.Fields.Count); + AssertUtils.HasField(valueKey, 55.42D, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Theory] + [InlineData(MetricsSchema.TelegrafPrometheusV1, "test-counter", "counter")] + [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "test-counter")] + public void ExportIntSumMetric(MetricsSchema metricsSchema, string measurement, string valueKey) + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = metricsSchema; + }) + .Build(); + + // Act + var counter = meter.CreateCounter("test-counter"); + counter.Add(100, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal(measurement, dataPoint.Measurement); + + Assert.Equal(1, dataPoint.Fields.Count); + AssertUtils.HasField(valueKey, 100L, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Theory] + [InlineData(MetricsSchema.TelegrafPrometheusV1, "test-counter", "counter")] + [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "test-counter")] + public void ExportDoubleSumMetric(MetricsSchema metricsSchema, string measurement, string valueKey) + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = metricsSchema; + }) + .Build(); + + // Act + var counter = meter.CreateCounter("test-counter"); + counter.Add(12.59, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal(measurement, dataPoint.Measurement); + + Assert.Equal(1, dataPoint.Fields.Count); + AssertUtils.HasField(valueKey, 12.59D, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Theory] + [InlineData(MetricsSchema.TelegrafPrometheusV1, "non_monotonic_sum", "gauge")] + [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "non_monotonic_sum")] + public void ExportNonMonotonicIntSumMetric(MetricsSchema metricsSchema, string measurement, string valueKey) + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = metricsSchema; + }) + .Build(); + + // Act + var upDownCounter = meter.CreateUpDownCounter("non_monotonic_sum"); + upDownCounter.Add(50, new("tag_key_1", "tag_value_1"), new("tag_key_2", "tag_value_2")); + upDownCounter.Add(-100, new("tag_key_1", "tag_value_1"), new("tag_key_2", "tag_value_2")); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal(measurement, dataPoint.Measurement); + + Assert.Equal(1, dataPoint.Fields.Count); + AssertUtils.HasField(valueKey, -50L, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Theory] + [InlineData(MetricsSchema.TelegrafPrometheusV1, "non_monotonic_sum", "gauge")] + [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "non_monotonic_sum")] + public void ExportNonMonotonicDoubleSumMetric(MetricsSchema metricsSchema, string measurement, string valueKey) + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = metricsSchema; + }) + .Build(); + + // Act + var upDownCounter = meter.CreateUpDownCounter("non_monotonic_sum"); + upDownCounter.Add(50.11, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + upDownCounter.Add(-100.22, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal(measurement, dataPoint.Measurement); + + Assert.Equal(1, dataPoint.Fields.Count); + AssertUtils.HasField(valueKey, -50.11D, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Fact] + public void ExportHistogramMetricWhenTelegrafPrometheusV1MetricsSchemaUsed() + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddView("histogram_metric", new ExplicitBucketHistogramConfiguration + { + Boundaries = new[] { 10D, 20D, 100D, 200D }, + RecordMinMax = true, + }) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV1; + }) + .Build(); + + // Act + var histogram = meter.CreateHistogram("histogram_metric"); + histogram.Record(50, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + histogram.Record(100, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + histogram.Record(150, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + histogram.Record(250, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal("histogram_metric", dataPoint.Measurement); + + Assert.Equal(9, dataPoint.Fields.Count); + AssertUtils.HasField("count", 4L, dataPoint.Fields); + AssertUtils.HasField("sum", 550D, dataPoint.Fields); + AssertUtils.HasField("min", 50D, dataPoint.Fields); + AssertUtils.HasField("max", 250D, dataPoint.Fields); + AssertUtils.HasField("10.00", 0L, dataPoint.Fields); + AssertUtils.HasField("20.00", 0L, dataPoint.Fields); + AssertUtils.HasField("100.00", 2L, dataPoint.Fields); + AssertUtils.HasField("200.00", 1L, dataPoint.Fields); + AssertUtils.HasField("+Inf", 1L, dataPoint.Fields); + + Assert.Equal(2, dataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + + Assert.InRange(dataPoint.Timestamp, before, after); + } + + [Fact] + public void ExportHistogramMetricWithoutMinMaxFieldsWhenTelegrafPrometheusV1MetricsSchemaUsed() + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddView("histogram_metric", new ExplicitBucketHistogramConfiguration + { + RecordMinMax = false, + }) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV1; + }) + .Build(); + + // Act + var histogram = meter.CreateHistogram("histogram_metric"); + histogram.Record(50); + provider.ForceFlush(); + + // Assert + var dataPoint = influxServer.ReadPoint(); + Assert.Equal("histogram_metric", dataPoint.Measurement); + Assert.DoesNotContain("min", dataPoint.Fields); + Assert.DoesNotContain("max", dataPoint.Fields); + } + + [Fact] + public void ExportHistogramMetricWhenTelegrafPrometheusV2MetricsSchemaUsed() + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddView("histogram_metric", new ExplicitBucketHistogramConfiguration + { + Boundaries = new[] { 10D, 20D, 100D, 200D }, + RecordMinMax = true, + }) + .AddInfluxDBMetricsExporter(options => + { + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV2; + options.WithDefaultTestConfiguration(); + }) + .Build(); + + // Act + var histogram = meter.CreateHistogram("histogram_metric"); + histogram.Record(50, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + histogram.Record(100, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + histogram.Record(150, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + histogram.Record(250, new("tag_key_2", "tag_value_2"), new("tag_key_1", "tag_value_1")); + + var before = DateTime.UtcNow; + provider.ForceFlush(); + var after = DateTime.UtcNow; + + // Assert + var headDataPoint = influxServer.ReadPoint(); + Assert.Equal("prometheus", headDataPoint.Measurement); + Assert.Equal(4, headDataPoint.Fields.Count); + AssertUtils.HasField("histogram_metric_count", 4L, headDataPoint.Fields); + AssertUtils.HasField("histogram_metric_sum", 550D, headDataPoint.Fields); + AssertUtils.HasField("histogram_metric_min", 50D, headDataPoint.Fields); + AssertUtils.HasField("histogram_metric_max", 250D, headDataPoint.Fields); + Assert.Equal(2, headDataPoint.Tags.Count); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, headDataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, headDataPoint.Tags); + Assert.InRange(headDataPoint.Timestamp, before, after); + + AssertBucketDataPoint(influxServer.ReadPoint(), "10.00", 0); + AssertBucketDataPoint(influxServer.ReadPoint(), "20.00", 0); + AssertBucketDataPoint(influxServer.ReadPoint(), "100.00", 2); + AssertBucketDataPoint(influxServer.ReadPoint(), "200.00", 1); + AssertBucketDataPoint(influxServer.ReadPoint(), "+Inf", 1); + + static void AssertBucketDataPoint(PointData dataPoint, string bound, long count) + { + Assert.Equal("prometheus", dataPoint.Measurement); + AssertUtils.HasField("histogram_metric_bucket", count, dataPoint.Fields); + AssertUtils.HasTag("le", bound, 0, dataPoint.Tags); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 1, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 2, dataPoint.Tags); + } + } + + [Fact] + public void ExportHistogramMetricWithoutMinMaxFieldsWhenTelegrafPrometheusV2MetricsSchemaUsed() + { + // Arrange + using var influxServer = new InfluxDBFakeServer(); + var influxServerEndpoint = influxServer.Endpoint; + + using var meter = new Meter("MyMeter", "0.0.1"); + + using var provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddView("histogram_metric", new ExplicitBucketHistogramConfiguration + { + RecordMinMax = false, + }) + .AddInfluxDBMetricsExporter(options => + { + options.WithDefaultTestConfiguration(); + options.Endpoint = influxServerEndpoint; + options.MetricsSchema = MetricsSchema.TelegrafPrometheusV2; + }) + .Build(); + + // Act + var histogram = meter.CreateHistogram("histogram_metric"); + histogram.Record(50); + provider.ForceFlush(); + + // Assert + var pointData = influxServer.ReadPoint(); + Assert.Equal("prometheus", pointData.Measurement); + Assert.DoesNotContain("histogram_metric_min", pointData.Fields); + Assert.DoesNotContain("histogram_metric_max", pointData.Fields); + } +} diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj new file mode 100644 index 0000000000..b1944fa798 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -0,0 +1,32 @@ + + + + Unit test project for InfluxDB Exporter for OpenTelemetry. + + $(NetMinimumSupportedVersion) + $(TargetFramework);net48;net472;net471;net47;net462 + enable + true + true + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs new file mode 100644 index 0000000000..8c40e2b3d4 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Xunit; + +namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; + +public static class AssertUtils +{ + public static void HasField(TKey expectedKey, TValue expectedValue, IReadOnlyDictionary collection) + where TKey : notnull + { + Assert.Contains(expectedKey, collection); + Assert.Equal(expectedValue, collection[expectedKey]); + } + + public static void HasTag(string expectedKey, string expectedValue, int index, IReadOnlyList> collection) + { + Assert.Equal(expectedKey, collection[index].Key); + Assert.Equal(expectedValue, collection[index].Value); + } +} diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs new file mode 100644 index 0000000000..55c9c4f742 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs @@ -0,0 +1,67 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Concurrent; +using System.Net; +using System.Text; +using OpenTelemetry.Tests; + +namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; + +public class InfluxDBFakeServer : IDisposable +{ + private readonly IDisposable httpServer; + private readonly BlockingCollection lines; + + public InfluxDBFakeServer() + { + this.lines = new BlockingCollection(); + this.httpServer = TestHttpServer.RunServer( + context => + { + byte[] buffer = new byte[context.Request.ContentLength64]; + _ = context.Request.InputStream.Read(buffer, 0, buffer.Length); + string text = Encoding.UTF8.GetString(buffer); + foreach (var line in text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)) + { + this.lines.Add(line); + } + + context.Response.StatusCode = (int)HttpStatusCode.OK; + context.Response.Close(); + }, + out var host, + out var port); + this.Endpoint = new Uri($"http://{host}:{port}"); + } + + public Uri Endpoint { get; } + + public void Dispose() + { + this.httpServer.Dispose(); + } + + public PointData ReadPoint() + { + if (this.lines.TryTake(out var line, TimeSpan.FromSeconds(5))) + { + return LineProtocolParser.ParseLine(line); + } + + throw new InvalidOperationException("Failed to read a data point from the InfluxDB server within the 5-second timeout."); + } +} diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs new file mode 100644 index 0000000000..67ddb93541 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs @@ -0,0 +1,30 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; + +public static class InfluxDBMetricsExporterOptionsTestExtensions +{ + public static void WithDefaultTestConfiguration(this InfluxDBMetricsExporterOptions options) + { + options.Bucket = "MyBucket"; + options.Org = "MyOrg"; + options.Token = "MyToken"; + + // For tests we want to flush the metrics ASAP + options.FlushInterval = 1; + } +} diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs new file mode 100644 index 0000000000..0c32e0d153 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs @@ -0,0 +1,99 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Globalization; + +namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; + +public class LineProtocolParser +{ + public static PointData ParseLine(string line) + { + var segments = line.Split(' '); + if (segments.Length is < 2 or > 3) + { + throw new ArgumentException("Invalid InfluxDB Line Protocol format.", nameof(line)); + } + + var measurementAndTags = segments[0]; + var fieldsSection = segments[1]; + var timestampSection = segments.Length == 3 ? segments[2] : null; + + var measurementAndTagsParts = measurementAndTags.Split(','); + var measurement = measurementAndTagsParts[0]; + var tags = ParseTags(measurementAndTagsParts.Skip(1)); + var fields = ParseFields(fieldsSection); + var timestamp = ParseTimestamp(timestampSection); + + return new PointData { Measurement = measurement, Tags = tags, Fields = fields, Timestamp = timestamp }; + } + + private static Dictionary ParseFields(string fieldsSection) + { + return fieldsSection.Split(',') + .Where(field => !string.IsNullOrEmpty(field)) + .Select(field => + { + var kv = field.Split('='); + var key = kv[0]; + var value = ParseFieldValue(kv[1]); + return new KeyValuePair(key, value); + }) + .ToDictionary(x => x.Key, x => x.Value); + } + + private static List> ParseTags(IEnumerable tagParts) + { + return tagParts + .Select(tagPart => + { + var kv = tagPart.Split('='); + return new KeyValuePair(kv[0], kv[1]); + }) + .ToList(); + } + + private static object ParseFieldValue(string fieldValue) + { + if (bool.TryParse(fieldValue, out bool boolValue)) + { + return boolValue; + } + + if (fieldValue.EndsWith("i", StringComparison.Ordinal) && long.TryParse(fieldValue.AsSpan(0, fieldValue.Length - 1), out long intValue)) + { + return intValue; + } + + if (double.TryParse(fieldValue, NumberStyles.Float, CultureInfo.InvariantCulture, out double doubleValue)) + { + return doubleValue; + } + + return fieldValue; + } + + private static DateTime ParseTimestamp(string? timestampSection) + { + if (string.IsNullOrEmpty(timestampSection) || !long.TryParse(timestampSection, out long unixTimeNanoseconds)) + { + throw new ArgumentException("Invalid formatted timestamp."); + } + + long ticks = unixTimeNanoseconds / 100; + return DateTime.UnixEpoch.AddTicks(ticks); + } +} diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs new file mode 100644 index 0000000000..c48e2a06c8 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs @@ -0,0 +1,28 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; + +public class PointData +{ + public string Measurement { get; init; } = null!; + + public IReadOnlyList> Tags { get; init; } = null!; + + public IReadOnlyDictionary Fields { get; init; } = null!; + + public DateTime Timestamp { get; init; } +} From da2fe978c3cf9c8645d6e1b163e6f0763127df83 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 17:30:10 -0700 Subject: [PATCH 0701/1499] Bump codecov/codecov-action from 3.1.3 to 3.1.4 (#1190) --- .github/workflows/dotnet-core-cov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 5c60677a4c..00b45b12a8 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -48,7 +48,7 @@ jobs: - name: Merging test results run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - uses: codecov/codecov-action@v3.1.3 + - uses: codecov/codecov-action@v3.1.4 with: file: TestResults/Cobertura.xml env_vars: OS From 66b7d31343240496721c4540ce42cc0033e6fec5 Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Tue, 16 May 2023 20:44:48 +0200 Subject: [PATCH 0702/1499] [OpenTelemetry.Exporter.InfluxDB] Get rid of the no-warn exclusions (#1191) --- .../MetricsSchema.cs | 17 +++++++++++++++++ .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 - 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs b/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs index c5c684982e..4c52417c60 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs @@ -21,7 +21,24 @@ namespace OpenTelemetry.Exporter.InfluxDB; /// public enum MetricsSchema { + /// + /// No schema selected. Default schema will be used. + /// None, + + /// + /// Represents the Telegraf Prometheus V1 schema. + /// This option converts OpenTelemetry metrics to the first version of the Telegraf Prometheus schema. + /// - Telegraf/InfluxDB measurement per Prometheus metric + /// - Fields `count`/`sum`/`gauge`/etc contain metric values. + /// TelegrafPrometheusV1 = 1, + + /// + /// Represents the Telegraf Prometheus V2 schema. + /// This option converts OpenTelemetry metrics to the second version of the Telegraf Prometheus schema. + /// - One measurement `prometheus` + /// - Fields (Prometheus metric name) + `_` + `count`/`sum`/`gauge`/etc contain metric values. + /// TelegrafPrometheusV2 = 2, } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index b9ea284291..8a3103c39c 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -4,7 +4,6 @@ true An OpenTelemetry .NET exporter that exports to InfluxDB OpenTelemetry Authors - $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) Exporter.InfluxDB- From de0ec238e858616cadfb2c6a31bbaefa68b5f829 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai Date: Thu, 18 May 2023 09:36:11 -0700 Subject: [PATCH 0703/1499] [Exporter.Geneva] Cleanup GenevaMetricExporter (#1195) --- build/Common.nonprod.props | 2 +- .../Metrics/GenevaMetricExporter.cs | 268 +------- .../Exporter/MetricExporterBenchmarks.cs | 106 ++-- .../GenevaMetricExporterTests.cs | 598 ------------------ 4 files changed, 60 insertions(+), 914 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 528ff99e26..2d2b21bb27 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -20,7 +20,7 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [0.13.3,0.14) + [0.13.5,0.14) [3.2.0,4.0.0) [2.3.1,3.0) [5.0.0,7.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index a9cafcfbb5..ccac1bddfa 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -51,14 +51,6 @@ public class GenevaMetricExporter : BaseExporter private readonly byte[] buffer = new byte[BufferSize]; - private readonly byte[] bufferForNonHistogramMetrics = new byte[BufferSize]; - - private readonly byte[] bufferForHistogramMetrics = new byte[BufferSize]; - - private readonly int bufferIndexForNonHistogramMetrics; - - private readonly int bufferIndexForHistogramMetrics; - private readonly string defaultMonitoringAccount; private readonly string defaultMetricNamespace; @@ -107,9 +99,6 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); } - this.bufferIndexForNonHistogramMetrics = this.InitializeBufferForNonHistogramMetrics(); - this.bufferIndexForHistogramMetrics = this.InitializeBufferForHistogramMetrics(); - unsafe { this.fixedPayloadStartIndex = sizeof(BinaryHeader); @@ -306,209 +295,6 @@ internal static void DisableOpenTelemetrySdkMetricNameValidation() GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, new Regex(".*", RegexOptions.Compiled)); } - internal unsafe ushort SerializeMetric( - MetricEventType eventType, - string metricName, - long timestamp, - in ReadOnlyTagCollection tags, - MetricData value) - { - ushort bodyLength; - try - { - var bufferIndex = this.bufferIndexForNonHistogramMetrics; - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, metricName); - - ushort dimensionsWritten = 0; - - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } - - if (this.prepopulatedDimensionsCount > 0) - { - dimensionsWritten += this.prepopulatedDimensionsCount; - } - - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, tag.Key); - } - - dimensionsWritten += (ushort)tags.Count; - - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); - } - - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, dimensionValue); - } - - // The Autopilot container name is optional but still preserve the location with zero length if it is empty. - MetricSerializer.SerializeInt16(this.bufferForNonHistogramMetrics, ref bufferIndex, 0); - - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.bufferForNonHistogramMetrics) - { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)eventType; - ptr->BodyLength = bodyLength; - - var payloadPtr = (MetricPayload*)&bufferBytes[this.fixedPayloadStartIndex]; - payloadPtr->CountDimension = dimensionsWritten; - payloadPtr->ReservedWord = 0; - payloadPtr->ReservedDword = 0; - payloadPtr->TimestampUtc = (ulong)timestamp; - payloadPtr->Data = value; - } - } - finally - { - } - - return bodyLength; - } - - internal unsafe ushort SerializeHistogramMetric( - string metricName, - long timestamp, - in ReadOnlyTagCollection tags, - HistogramBuckets buckets, - MetricData sum, - uint count, - MetricData min, - MetricData max) - { - ushort bodyLength; - try - { - var bufferIndex = this.bufferIndexForHistogramMetrics; - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, metricName); - - ushort dimensionsWritten = 0; - - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } - - if (this.prepopulatedDimensionsCount > 0) - { - dimensionsWritten += this.prepopulatedDimensionsCount; - } - - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, tag.Key); - } - - dimensionsWritten += (ushort)tags.Count; - - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(this.bufferForHistogramMetrics, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); - } - - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, dimensionValue); - } - - // The Autopilot container name is optional but still preserve the location with zero length if it is empty. - MetricSerializer.SerializeInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); - - // Version - MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 0); - - // Meta-data - // Value-count pairs is associated with the constant value of 2 in the distribution_type enum. - MetricSerializer.SerializeByte(this.bufferForHistogramMetrics, ref bufferIndex, 2); - - // Keep a position to record how many buckets are added - var itemsWrittenIndex = bufferIndex; - MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref bufferIndex, 0); - - // Bucket values - ushort bucketCount = 0; - double lastExplicitBound = default; - foreach (var bucket in buckets) - { - if (bucket.BucketCount > 0) - { - this.SerializeHistogramBucket(bucket, ref bufferIndex, lastExplicitBound); - bucketCount++; - } - - lastExplicitBound = bucket.ExplicitBound; - } - - // Write the number of items in distribution emitted and reset back to end. - MetricSerializer.SerializeUInt16(this.bufferForHistogramMetrics, ref itemsWrittenIndex, bucketCount); - - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.bufferForHistogramMetrics) - { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric; - ptr->BodyLength = bodyLength; - - var payloadPtr = (ExternalPayload*)&bufferBytes[this.fixedPayloadStartIndex]; - payloadPtr[0].CountDimension = dimensionsWritten; - payloadPtr[0].ReservedWord = 0; - payloadPtr[0].Count = count; - payloadPtr[0].TimestampUtc = (ulong)timestamp; - payloadPtr[0].Sum = sum; - payloadPtr[0].Min = min; - payloadPtr[0].Max = max; - } - } - finally - { - } - - return bodyLength; - } - internal unsafe ushort SerializeMetricWithTLV( MetricEventType eventType, string metricName, @@ -630,21 +416,21 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( private static void SerializeMetricName(string metricName, byte[] buffer, ref int bufferIndex) { MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.MetricName); - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricName)); + MetricSerializer.SerializeString(buffer, ref bufferIndex, metricName); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeMetricNamespace(string metricNamespace, byte[] buffer, ref int bufferIndex) { MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Namespace); - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(metricNamespace)); + MetricSerializer.SerializeString(buffer, ref bufferIndex, metricNamespace); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeMonitoringAccount(string monitoringAccount, byte[] buffer, ref int bufferIndex) { MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.AccountName); - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, Encoding.UTF8.GetBytes(monitoringAccount)); + MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -954,22 +740,6 @@ private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagColle MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SerializeHistogramBucket(in HistogramBucket bucket, ref int bufferIndex, double lastExplicitBound) - { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - } - else - { - // The bucket to catch the overflows is one greater than the last bound provided - MetricSerializer.SerializeUInt64(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); - } - - MetricSerializer.SerializeUInt32(this.bufferForHistogramMetrics, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); - } - private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) { var serializedKeys = new List(this.prepopulatedDimensionsCount); @@ -992,36 +762,4 @@ private List SerializePrepopulatedDimensionsValues(IEnumerable v return serializedValues; } - - private unsafe int InitializeBufferForNonHistogramMetrics() - { - // The buffer format is as follows: - // -- BinaryHeader - // -- MetricPayload - // -- Variable length content - - // Leave enough space for the header and fixed payload - var bufferIndex = sizeof(BinaryHeader) + sizeof(MetricPayload); - - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.defaultMonitoringAccount); - MetricSerializer.SerializeString(this.bufferForNonHistogramMetrics, ref bufferIndex, this.defaultMetricNamespace); - - return bufferIndex; - } - - private unsafe int InitializeBufferForHistogramMetrics() - { - // The buffer format is as follows: - // -- BinaryHeader - // -- ExternalPayload - // -- Variable length content - - // Leave enough space for the header and fixed payload - var bufferIndex = sizeof(BinaryHeader) + sizeof(ExternalPayload); - - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.defaultMonitoringAccount); - MetricSerializer.SerializeString(this.bufferForHistogramMetrics, ref bufferIndex, this.defaultMetricNamespace); - - return bufferIndex; - } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 81644f50c2..976ae3d584 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -23,31 +23,31 @@ using OpenTelemetry.Metrics; /* -BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963) +BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 +.NET SDK=7.0.203 + [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 | Method | Mean | Error | StdDev | Allocated | |--------------------------------------------------------- |----------:|---------:|---------:|----------:| -| InstrumentWithNoListener3Dimensions | 64.11 ns | 0.169 ns | 0.132 ns | - | -| InstrumentWithNoListener4Dimensions | 116.30 ns | 0.547 ns | 0.427 ns | - | -| InstrumentWithWithListener3Dimensions | 65.40 ns | 0.422 ns | 0.395 ns | - | -| InstrumentWithWithListener4Dimensions | 112.80 ns | 0.465 ns | 0.435 ns | - | -| InstrumentWithWithDummyReader3Dimensions | 189.56 ns | 0.994 ns | 0.930 ns | - | -| InstrumentWithWithDummyReader4Dimensions | 258.45 ns | 3.355 ns | 2.974 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 193.18 ns | 2.468 ns | 2.309 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 257.24 ns | 1.017 ns | 0.901 ns | - | -| SerializeCounterMetricItemWith3Dimensions | 153.20 ns | 0.609 ns | 0.540 ns | - | -| SerializeCounterMetricItemWith4Dimensions | 176.57 ns | 0.708 ns | 0.662 ns | - | -| ExportCounterMetricItemWith3Dimensions | 420.11 ns | 2.434 ns | 2.033 ns | - | -| ExportCounterMetricItemWith4Dimensions | 440.69 ns | 6.733 ns | 5.968 ns | - | -| SerializeHistogramMetricItemWith3Dimensions | 264.51 ns | 2.299 ns | 2.038 ns | - | -| SerializeHistogramMetricItemWith4Dimensions | 294.36 ns | 1.159 ns | 1.084 ns | - | -| ExportHistogramMetricItemWith3Dimensions | 565.85 ns | 6.144 ns | 4.797 ns | - | -| ExportHistogramMetricItemWith4Dimensions | 591.38 ns | 4.704 ns | 4.170 ns | - | +| InstrumentWithNoListener3Dimensions | 66.17 ns | 0.316 ns | 0.296 ns | - | +| InstrumentWithNoListener4Dimensions | 112.15 ns | 0.540 ns | 0.478 ns | - | +| InstrumentWithWithListener3Dimensions | 70.17 ns | 0.110 ns | 0.097 ns | - | +| InstrumentWithWithListener4Dimensions | 114.77 ns | 0.343 ns | 0.304 ns | - | +| InstrumentWithWithDummyReader3Dimensions | 192.32 ns | 0.369 ns | 0.288 ns | - | +| InstrumentWithWithDummyReader4Dimensions | 261.23 ns | 3.515 ns | 2.745 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 198.50 ns | 1.153 ns | 1.022 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 261.38 ns | 1.856 ns | 1.736 ns | - | +| SerializeCounterMetricItemWith3Dimensions | 215.62 ns | 0.759 ns | 0.673 ns | - | +| SerializeCounterMetricItemWith4Dimensions | 241.33 ns | 0.466 ns | 0.364 ns | - | +| ExportCounterMetricItemWith3Dimensions | 257.88 ns | 0.572 ns | 0.507 ns | - | +| ExportCounterMetricItemWith4Dimensions | 285.43 ns | 1.300 ns | 1.216 ns | - | +| SerializeHistogramMetricItemWith3Dimensions | 380.58 ns | 6.226 ns | 5.823 ns | - | +| SerializeHistogramMetricItemWith4Dimensions | 404.64 ns | 3.981 ns | 3.723 ns | - | +| ExportHistogramMetricItemWith3Dimensions | 438.35 ns | 2.442 ns | 2.040 ns | - | +| ExportHistogramMetricItemWith4Dimensions | 477.16 ns | 2.555 ns | 2.133 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; @@ -67,12 +67,12 @@ public class MetricExporterBenchmarks private Metric histogramMetricWith4Dimensions; private MetricPoint histogramMetricPointWith3Dimensions; private MetricPoint histogramMetricPointWith4Dimensions; - private MetricData histogramSumWith3Dimensions; - private MetricData histogramSumWith4Dimensions; - private MetricData histogramMinWith3Dimensions; - private MetricData histogramMinWith4Dimensions; - private MetricData histogramMaxWith3Dimensions; - private MetricData histogramMaxWith4Dimensions; + private ulong histogramSumWith3Dimensions; + private ulong histogramSumWith4Dimensions; + private double histogramMinWith3Dimensions; + private double histogramMinWith4Dimensions; + private double histogramMaxWith3Dimensions; + private double histogramMaxWith4Dimensions; private uint histogramCountWith3Dimensions; private uint histogramCountWith4Dimensions; private Batch histogramMetricBatchWith3Dimensions; @@ -292,7 +292,7 @@ private Batch GenerateCounterBatchWith4Dimensions() return batchGeneratorExporter.Batch; } - private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData sum, out uint count, out MetricData min, out MetricData max) + private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out ulong sum, out uint count, out double min, out double max) { using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith3Dimensions", "0.0.1"); var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith3Dimensions"); @@ -323,22 +323,19 @@ private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out MetricData su var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - min = new MetricData { UInt64Value = 0 }; - max = new MetricData { UInt64Value = 0 }; - - if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) + if (!metricPoint.TryGetHistogramMinMaxValues(out min, out max)) { - min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; + min = 0; + max = 0; } return metricPoint; } - private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData sum, out uint count, out MetricData min, out MetricData max) + private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out ulong sum, out uint count, out double min, out double max) { using var meterWithInMemoryExporter = new Meter("GenerateHistogramMetricItemWith4Dimensions", "0.0.1"); var histogram = meterWithInMemoryExporter.CreateHistogram("HistogramWith4Dimensions"); @@ -373,16 +370,13 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out MetricData su var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; + sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - min = new MetricData { UInt64Value = 0 }; - max = new MetricData { UInt64Value = 0 }; - - if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) + if (!metricPoint.TryGetHistogramMinMaxValues(out min, out max)) { - min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; + min = 0; + max = 0; } return metricPoint; @@ -566,23 +560,29 @@ public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() [Benchmark] public void SerializeCounterMetricItemWith3Dimensions() { - this.exporter.SerializeMetric( + this.exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith3Dimensions.Name, this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith3Dimensions.Tags, - this.counterMetricDataWith3Dimensions); + this.counterMetricDataWith3Dimensions, + Array.Empty(), + out _, + out _); } [Benchmark] public void SerializeCounterMetricItemWith4Dimensions() { - this.exporter.SerializeMetric( + this.exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith4Dimensions.Name, this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith4Dimensions.Tags, - this.counterMetricDataWith4Dimensions); + this.counterMetricDataWith4Dimensions, + Array.Empty(), + out _, + out _); } [Benchmark] @@ -600,7 +600,7 @@ public void ExportCounterMetricItemWith4Dimensions() [Benchmark] public void SerializeHistogramMetricItemWith3Dimensions() { - this.exporter.SerializeHistogramMetric( + this.exporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith3Dimensions.Name, this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), this.histogramMetricPointWith3Dimensions.Tags, @@ -608,13 +608,16 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramSumWith3Dimensions, this.histogramCountWith3Dimensions, this.histogramMinWith3Dimensions, - this.histogramMaxWith3Dimensions); + this.histogramMaxWith3Dimensions, + Array.Empty(), + out _, + out _); } [Benchmark] public void SerializeHistogramMetricItemWith4Dimensions() { - this.exporter.SerializeHistogramMetric( + this.exporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith4Dimensions.Name, this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), this.histogramMetricPointWith4Dimensions.Tags, @@ -622,7 +625,10 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramSumWith4Dimensions, this.histogramCountWith4Dimensions, this.histogramMinWith4Dimensions, - this.histogramMaxWith4Dimensions); + this.histogramMaxWith4Dimensions, + Array.Empty(), + out _, + out _); } [Benchmark] diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 1bc4d76708..2054179466 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -122,410 +122,6 @@ public void CannotUseReservedDimensionsInPrepopulatedFields() Assert.Throws(() => { exporterOptions.PrepopulatedMetricDimensions = prepopulatedMetricDimensions; }); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void SuccessfulSerialization(bool testMaxLimits) - { - using var meter = new Meter("SuccessfulSerialization", "0.0.1"); - var longCounter = meter.CreateCounter("longCounter"); - var doubleCounter = meter.CreateCounter("doubleCounter"); - var longUpDownCounter = meter.CreateUpDownCounter("longUpDownCounter"); - var doubleUpDownCounter = meter.CreateUpDownCounter("doubleUpDownCounter"); - var histogram = meter.CreateHistogram("histogram"); - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulSerialization") - .AddReader(inMemoryReader) - .Build(); - - long longValue = 123; - double doubleValue = 123.45; - - if (testMaxLimits) - { - longValue = long.MaxValue; - doubleValue = double.MaxValue; - } - - longCounter.Add( - longValue, new("tag1", "value1"), new("tag2", "value2")); - - doubleCounter.Add( - doubleValue, new("tag1", "value1"), new("tag2", "value2")); - - longUpDownCounter.Add( - longValue, new("tag1", "value1"), new("tag2", "value2")); - - doubleUpDownCounter.Add( - longValue, new("tag1", "value1"), new("tag2", "value2")); - - meter.CreateObservableCounter( - "observableLongCounter", - () => new List>() - { - new(longValue, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableCounter( - "observableDoubleCounter", - () => new List>() - { - new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableGauge( - "observableLongGauge", - () => new List>() - { - new(longValue, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableGauge( - "observableDoubleGauge", - () => new List>() - { - new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableUpDownCounter( - "observableUpDownLongCounter", - () => new List>() - { - new(longValue, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableUpDownCounter( - "observableUpDownDoubleCounter", - () => new List>() - { - new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), - }); - - if (testMaxLimits) - { - // only testing the max value allowed for sum - // max value allowed for count is uint.MaxValue. It's not feasible to test that - histogram.Record(longValue, new("tag1", "value1"), new("tag2", "value2")); - } - else - { - // Record the following values from Histogram: - // (-inf - 0] : 1 - // (0 - 5] : 0 - // (5 - 10] : 0 - // (10 - 25] : 0 - // (25 - 50] : 0 - // (50 - 75] : 0 - // (75 - 100] : 0 - // (100 - 250] : 2 - // (250 - 500] : 0 - // (500 - 1000] : 1 - // (1000 - +inf) : 1 - // - // The corresponding value-count pairs to be sent for the given distribution: - // 0: 1 - // 250: 2 - // 1000: 1 - // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) - - histogram.Record(0, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2")); - } - - string path = string.Empty; - Socket server = null; - try - { - var exporterOptions = new GenevaMetricExporterOptions(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } - - exporterOptions.PrepopulatedMetricDimensions = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - - using var exporter = new GenevaMetricExporter(exporterOptions); - - inMemoryReader.Collect(); - - Assert.Equal(11, exportedItems.Count); - - // check serialization for longCounter - CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); - - // check serialization for doubleCounter - CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - - // check serialization for longUpDownCounter - CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - - // check serialization for doubleUpDownCounter - CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - - // check serialization for histogram - CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - - // check serialization for observableLongCounter - CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); - - // check serialization for observableDoubleCounter - CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); - - // check serialization for observableLongGauge - CheckSerializationForSingleMetricPoint(exportedItems[7], exporter, exporterOptions); - - // check serialization for observableDoubleGauge - CheckSerializationForSingleMetricPoint(exportedItems[8], exporter, exporterOptions); - - // check serialization for observableUpDownLongCounter - CheckSerializationForSingleMetricPoint(exportedItems[9], exporter, exporterOptions); - - // check serialization for observableUpDownDoubleCounter - CheckSerializationForSingleMetricPoint(exportedItems[10], exporter, exporterOptions); - } - finally - { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } - } - } - - [Fact] - public void SuccessfulSerializationWithViews() - { - using var meter = new Meter("SuccessfulSerializationWithViews", "0.0.1"); - var longCounter = meter.CreateCounter("longCounter"); - var doubleCounter = meter.CreateCounter("doubleCounter"); - var histogramWithCustomBounds = meter.CreateHistogram("histogramWithCustomBounds"); - var histogramWithNoBounds = meter.CreateHistogram("histogramWithNoBounds"); - var histogramWithNoMinMax = meter.CreateHistogram("histogramWithNoMinMax"); - var exportedItems = new List(); - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; - - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulSerializationWithViews") - .AddView("longCounter", "renamedLongCounter") - .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { "tag1" } }) - .AddView( - "histogramWithCustomBounds", - new ExplicitBucketHistogramConfiguration - { - Name = "renamedhistogramWithCustomBounds", - Description = "modifiedDescription", - Boundaries = new double[] { 500, 1000, 10000 }, - }) - .AddView(instrument => - { - if (instrument.Name == "histogramWithNoBounds") - { - return new ExplicitBucketHistogramConfiguration { Boundaries = Array.Empty() }; - } - - return null; - }) - .AddView( - "histogramWithNoMinMax", - new HistogramConfiguration - { - RecordMinMax = false, - }) - .AddView("observableLongCounter", MetricStreamConfiguration.Drop) - .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = Array.Empty() }) - .AddView(instrument => - { - if (instrument.Name == "observableLongGauge") - { - return new MetricStreamConfiguration - { - Name = "renamedobservableLongGauge", - Description = "modifiedDescription", - TagKeys = new string[] { "tag1" }, - }; - } - - return null; - }) - .AddView(instrument => - { - if (instrument.Name == "observableDoubleGauge") - { - return MetricStreamConfiguration.Drop; - } - - return null; - }) - .AddReader(inMemoryReader) - .Build(); - - longCounter.Add( - 123, new("tag1", "value1"), new("tag2", "value2")); - - doubleCounter.Add( - 123.45, new("tag1", "value1"), new("tag2", "value2")); - - meter.CreateObservableCounter( - "observableLongCounter", - () => new List>() - { - new(123, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableCounter( - "observableDoubleCounter", - () => new List>() - { - new(123.45, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableGauge( - "observableLongGauge", - () => new List>() - { - new(123, new("tag1", "value1"), new("tag2", "value2")), - }); - - meter.CreateObservableGauge( - "observableDoubleGauge", - () => new List>() - { - new(123.45, new("tag1", "value1"), new("tag2", "value2")), - }); - - // Record the following values for histogramWithCustomBounds: - // (-inf - 500] : 3 - // (500 - 1000] : 1 - // (1000 - 10000] : 0 - // (10000 - +inf) : 1 - // - // The corresponding value-count pairs to be sent for histogramWithCustomBounds: - // 500: 3 - // 1000: 1 - // 1001: 1 (We use one greater than the last bound provided (1000 + 1) as the value for the overflow bucket) - - histogramWithCustomBounds.Record(0, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogramWithCustomBounds.Record(50000, new("tag1", "value1"), new("tag2", "value2")); - - // Record the following values for histogramWithNoBounds: - // (-inf - 500] : 3 - // (500 - 1000] : 1 - // (1000 - +inf) : 1 - // - // Only `sum` and `count` are sent for histogramWithNoBounds - // No value-count pairs are sent for histogramWithNoBounds - - histogramWithNoBounds.Record(0, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoBounds.Record(2500, new("tag1", "value1"), new("tag2", "value2")); - - histogramWithNoMinMax.Record(-1, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoMinMax.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoMinMax.Record(150, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoMinMax.Record(750, new("tag1", "value1"), new("tag2", "value2")); - histogramWithNoMinMax.Record(2500, new("tag1", "value1"), new("tag2", "value2")); - - string path = string.Empty; - Socket server = null; - try - { - var exporterOptions = new GenevaMetricExporterOptions(); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - exporterOptions.ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - } - else - { - path = GenerateTempFilePath(); - exporterOptions.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - var endpoint = new UnixDomainSocketEndPoint(path); - server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - } - - exporterOptions.PrepopulatedMetricDimensions = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - - using var exporter = new GenevaMetricExporter(exporterOptions); - - inMemoryReader.Collect(); - - Assert.Equal(7, exportedItems.Count); - - // observableLongCounter and observableDoubleGauge are dropped - Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); - - // check serialization for longCounter - CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); - - // check serialization for doubleCounter - CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - - // check serialization for histogramWithCustomBounds - CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - - // check serialization for histogramWithNoBounds - CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - - // check serialization for observableDoubleCounter - CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - - // check serialization for observableLongGauge - CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); - } - finally - { - server?.Dispose(); - try - { - File.Delete(path); - } - catch - { - } - } - } - [Fact] public void SuccessfulExportOnLinux() { @@ -1303,200 +899,6 @@ private static void AssertHistogramBucketSerialization(HistogramBucket bucket, H Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); } - private static void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) - { - var metricType = metric.MetricType; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - MetricsContract data = null; - Userdata userData = null; - - // Check metric value, timestamp, eventId, and length of payload - if (metricType == MetricType.LongSum) - { - var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); - var metricData = new MetricData { UInt64Value = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - userData = data.Body as Userdata; - var valueSection = userData.ValueSection as SingleUint64Value; - Assert.Equal(metricDataValue, valueSection.Value); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.ULongMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - else if (metricType == MetricType.LongGauge) - { - var metricDataValue = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); - var metricData = new MetricData { DoubleValue = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - userData = data.Body as Userdata; - var valueSection = userData.ValueSection as SingleDoubleValue; - Assert.Equal(metricDataValue, valueSection.Value); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) - { - var metricDataValue = metricType == MetricType.DoubleSum ? - metricPoint.GetSumDouble() : - metricPoint.GetGaugeLastValueDouble(); - var metricData = new MetricData { DoubleValue = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - userData = data.Body as Userdata; - var valueSection = userData.ValueSection as SingleDoubleValue; - Assert.Equal(metricDataValue, valueSection.Value); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) - { - var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? - Convert.ToDouble(metricPoint.GetSumLong()) : - Convert.ToDouble(metricPoint.GetSumDouble()); - var metricData = new MetricData { DoubleValue = metricDataValue }; - var bodyLength = exporter.SerializeMetric( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData); - var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - userData = data.Body as Userdata; - var valueSection = userData.ValueSection as SingleDoubleValue; - Assert.Equal(metricDataValue, valueSection.Value); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - else if (metricType == MetricType.Histogram) - { - var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; - var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - - var min = new MetricData { UInt64Value = 0 }; - var max = new MetricData { UInt64Value = 0 }; - - if (metricPoint.TryGetHistogramMinMaxValues(out var minValue, out var maxValue)) - { - min = new MetricData { UInt64Value = Convert.ToUInt64(minValue) }; - max = new MetricData { UInt64Value = Convert.ToUInt64(maxValue) }; - } - - var bodyLength = exporter.SerializeHistogramMetric( - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricPoint.GetHistogramBuckets(), - sum, - count, - min, - max); - - var buffer = typeof(GenevaMetricExporter).GetField("bufferForHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; - var stream = new KaitaiStream(buffer); - data = new MetricsContract(stream); - userData = data.Body as Userdata; - var valueSection = userData.ValueSection as ExtAggregatedUint64Value; - var histogram = userData.Histogram; - var valueCountPairs = userData.Histogram.Body as HistogramValueCountPairs; - - Assert.Equal(0, histogram.Version); - Assert.Equal(2, (int)histogram.Type); - - int listIterator = 0; - int bucketsWithPositiveCount = 0; - double lastExplicitBound = default; - foreach (var bucket in metricPoint.GetHistogramBuckets()) - { - if (bucket.BucketCount > 0) - { - AssertHistogramBucketSerialization(bucket, valueCountPairs, listIterator, lastExplicitBound); - listIterator++; - bucketsWithPositiveCount++; - } - - lastExplicitBound = bucket.ExplicitBound; - } - - Assert.Equal(bucketsWithPositiveCount, valueCountPairs.DistributionSize); - - Assert.Equal(count, valueSection.Count); - Assert.Equal(Convert.ToUInt64(metricPoint.GetHistogramSum()), valueSection.Sum); - Assert.Equal(minValue, valueSection.Min); - Assert.Equal(maxValue, valueSection.Max); - Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); - Assert.Equal((ushort)MetricEventType.ExternallyAggregatedULongDistributionMetric, data.EventId); - Assert.Equal(bodyLength, data.LenBody); - } - - // Check metric name, account, and namespace - var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); - Assert.Equal(metric.Name, userData.MetricName.Value); - Assert.Equal(connectionStringBuilder.Account, userData.MetricAccount.Value); - Assert.Equal(connectionStringBuilder.Namespace, userData.MetricNamespace.Value); - - var dimensionsCount = 0; - if (exporterOptions.PrepopulatedMetricDimensions != null) - { - foreach (var entry in exporterOptions.PrepopulatedMetricDimensions) - { - Assert.Contains(userData.DimensionsNames, dim => dim.Value == entry.Key); - Assert.Contains(userData.DimensionsValues, dim => dim.Value == Convert.ToString(entry.Value, CultureInfo.InvariantCulture)); - } - - dimensionsCount += exporterOptions.PrepopulatedMetricDimensions.Count; - } - - // Check metric dimensions - int i = 0; - foreach (var item in exporterOptions.PrepopulatedMetricDimensions) - { - Assert.Equal(item.Key, userData.DimensionsNames[i].Value); - Assert.Equal(item.Value, userData.DimensionsValues[i].Value); - i++; - } - - foreach (var tag in metricPoint.Tags) - { - Assert.Equal(tag.Key, userData.DimensionsNames[i].Value); - Assert.Equal(tag.Value, userData.DimensionsValues[i].Value); - i++; - } - - dimensionsCount += metricPoint.Tags.Count; - - Assert.Equal(dimensionsCount, userData.NumDimensions); - } - private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) { var metricType = metric.MetricType; From 2ba1a0b4f8aea52bc43a15e265e2d1000be82d74 Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Fri, 19 May 2023 03:19:18 +0200 Subject: [PATCH 0704/1499] [Exporter.InfluxDB] Update CHANGELOG for 1.0.0-alpha.1 release (#1196) --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 825c32f0d0..ed95eac92a 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -1 +1,5 @@ # Changelog + +## 1.0.0-alpha.1 + +Released 2023-May-18 From cb57fa8f23093d0f8b993074b1013104a2368e3e Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Fri, 19 May 2023 07:11:52 +0200 Subject: [PATCH 0705/1499] [Exporter.InfluxDB] Update CHANGELOG after the initial release (#1197) --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index ed95eac92a..116da71e91 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + ## 1.0.0-alpha.1 Released 2023-May-18 + +* This is the first release of `OpenTelemetry.Exporter.InfluxDB` package. + +For more details, please refer to the [README](README.md). From 35e4ca31e7b91d531cbb5bd77443bd7824d62536 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 22 May 2023 11:08:08 -0700 Subject: [PATCH 0706/1499] [Exporter.InfluxDB] Fix issues with the test project (#1200) --- .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 5 +++-- .../Utils/InfluxDBFakeServer.cs | 3 ++- .../Utils/LineProtocolParser.cs | 7 +++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index b1944fa798..2f1e775e66 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -3,8 +3,8 @@ Unit test project for InfluxDB Exporter for OpenTelemetry. - $(NetMinimumSupportedVersion) - $(TargetFramework);net48;net472;net471;net47;net462 + $(NetMinimumSupportedVersion) + $(TargetFrameworks);net48;net472;net471;net47;net462 enable true true @@ -27,6 +27,7 @@ + diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs index 55c9c4f742..076f9f19f2 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs @@ -23,6 +23,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; public class InfluxDBFakeServer : IDisposable { + private static readonly char[] SplitChars = Environment.NewLine.ToCharArray(); private readonly IDisposable httpServer; private readonly BlockingCollection lines; @@ -35,7 +36,7 @@ public InfluxDBFakeServer() byte[] buffer = new byte[context.Request.ContentLength64]; _ = context.Request.InputStream.Read(buffer, 0, buffer.Length); string text = Encoding.UTF8.GetString(buffer); - foreach (var line in text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries)) + foreach (var line in text.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries)) { this.lines.Add(line); } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs index 0c32e0d153..97764fbbdf 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs @@ -20,6 +20,8 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; public class LineProtocolParser { + private static readonly DateTime UnixEpoch = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc); + public static PointData ParseLine(string line) { var segments = line.Split(' '); @@ -73,7 +75,8 @@ private static object ParseFieldValue(string fieldValue) return boolValue; } - if (fieldValue.EndsWith("i", StringComparison.Ordinal) && long.TryParse(fieldValue.AsSpan(0, fieldValue.Length - 1), out long intValue)) + if (fieldValue.EndsWith("i", StringComparison.Ordinal) + && long.TryParse(fieldValue.AsSpan(0, fieldValue.Length - 1).ToString(), out long intValue)) { return intValue; } @@ -94,6 +97,6 @@ private static DateTime ParseTimestamp(string? timestampSection) } long ticks = unixTimeNanoseconds / 100; - return DateTime.UnixEpoch.AddTicks(ticks); + return UnixEpoch.AddTicks(ticks); } } From 22f7c56619d18c2ead59f899ed74cafb61e2242f Mon Sep 17 00:00:00 2001 From: fred2u Date: Tue, 23 May 2023 16:58:09 +0200 Subject: [PATCH 0707/1499] [Instrumentation.Hangfire] Support Hangfire 1.8 (#1202) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 2 ++ .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 +- .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 989674df6b..967f858177 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -6,6 +6,8 @@ ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes `AddHangfireInstrumentation` method with default configure default parameter. ([#1129](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1129)) +* Support Hangfire `1.8`. + ([#1202](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1202)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index d842b71a81..772177dc9f 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -7,7 +7,7 @@ false - + diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 7588f459c8..7da4e0ba0f 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -7,7 +7,7 @@ false - + From efda793ca535127cebca9205490c8bf6efa84256 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 23 May 2023 13:04:04 -0700 Subject: [PATCH 0708/1499] [redis] Support manual connection management (#1193) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 32 +++-- .../netstandard2.0/PublicAPI.Unshipped.txt | 32 +++-- .../CHANGELOG.md | 11 ++ .../RedisProfilerEntryToActivityConverter.cs | 14 +-- .../README.md | 62 ++++++++++ ...ExchangeRedisConnectionInstrumentation.cs} | 18 +-- .../StackExchangeRedisInstrumentation.cs | 107 ++++++++++++++++ ...ackExchangeRedisInstrumentationOptions.cs} | 8 +- .../TracerProviderBuilderExtensions.cs | 85 ++++++++++--- ...isProfilerEntryToActivityConverterTests.cs | 20 +-- ...kExchangeRedisCallsInstrumentationTests.cs | 115 ++++++++++++------ 11 files changed, 398 insertions(+), 106 deletions(-) rename src/OpenTelemetry.Instrumentation.StackExchangeRedis/{StackExchangeRedisCallsInstrumentation.cs => StackExchangeRedisConnectionInstrumentation.cs} (86%) create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs rename src/OpenTelemetry.Instrumentation.StackExchangeRedis/{StackExchangeRedisCallsInstrumentationOptions.cs => StackExchangeRedisInstrumentationOptions.cs} (78%) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt index 09483f805d..c76bae94e0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,16 +1,22 @@ -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.get -> System.TimeSpan -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.StackExchangeRedisCallsInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(string! name, StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.Dispose() -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.get -> System.Action? +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.get -> System.TimeSpan +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.StackExchangeRedisInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 09483f805d..c76bae94e0 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,16 +1,22 @@ -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.get -> System.TimeSpan -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.FlushInterval.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.SetVerboseDatabaseStatements.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.StackExchangeRedisCallsInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(string! name, StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.Dispose() -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.get -> System.Action? +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.get -> System.TimeSpan +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.StackExchangeRedisInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 4ee8f6ee7b..9aa2cc6049 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -7,6 +7,17 @@ options. ([#1183](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1183)) +* **\*\*BREAKING CHANGE\*\*** Renamed the + `StackExchangeRedisCallsInstrumentationOptions` class to + `StackExchangeRedisInstrumentationOptions`. + ([#1193](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1193)) + +* Added a new extension `TracerProviderBuilder.ConfigureRedisInstrumentation` + which can be used to obtain the `StackExchangeRedisInstrumentation` instance + in order to dynamically add connections for instrumentation after the + `TracerProvider` has been created. + ([#1193](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1193)) + ## 1.0.0-rc9.8 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index c4bca0e8ef..00dc74295e 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -68,19 +68,19 @@ internal static class RedisProfilerEntryToActivityConverter }); }); - public static Activity? ProfilerCommandToActivity(Activity? parentActivity, IProfiledCommand command, StackExchangeRedisCallsInstrumentationOptions options) + public static Activity? ProfilerCommandToActivity(Activity? parentActivity, IProfiledCommand command, StackExchangeRedisInstrumentationOptions options) { var name = command.Command; // Example: SET; if (string.IsNullOrEmpty(name)) { - name = StackExchangeRedisCallsInstrumentation.ActivityName; + name = StackExchangeRedisConnectionInstrumentation.ActivityName; } - var activity = StackExchangeRedisCallsInstrumentation.ActivitySource.StartActivity( + var activity = StackExchangeRedisConnectionInstrumentation.ActivitySource.StartActivity( name, ActivityKind.Client, parentActivity?.Context ?? default, - StackExchangeRedisCallsInstrumentation.CreationTags, + StackExchangeRedisConnectionInstrumentation.CreationTags, startTime: command.CommandCreated); if (activity == null) @@ -105,7 +105,7 @@ internal static class RedisProfilerEntryToActivityConverter // Total: // command.ElapsedTime; // 00:00:32.4988020 - activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName, command.Flags.ToString()); + activity.SetTag(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName, command.Flags.ToString()); if (options.SetVerboseDatabaseStatements) { @@ -149,7 +149,7 @@ internal static class RedisProfilerEntryToActivityConverter } } - activity.SetTag(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName, command.Db); + activity.SetTag(StackExchangeRedisConnectionInstrumentation.RedisDatabaseIndexKeyName, command.Db); // TODO: deal with the re-transmission // command.RetransmissionOf; @@ -174,7 +174,7 @@ internal static class RedisProfilerEntryToActivityConverter return activity; } - public static void DrainSession(Activity? parentActivity, IEnumerable sessionCommands, StackExchangeRedisCallsInstrumentationOptions options) + public static void DrainSession(Activity? parentActivity, IEnumerable sessionCommands, StackExchangeRedisInstrumentationOptions options) { foreach (var command in sessionCommands) { diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index 0bf36733e7..d5ccbcc3de 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -71,6 +71,68 @@ the `ConfigureServices` of your `Startup` class. Refer to documentation for For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). +## Specify the Redis connection + +The following sections cover different ways to specify the `StackExchange.Redis` +connection(s) that will be instrumented and captured by OpenTelemetry. + +### Pass a Redis connection when calling AddRedisInstrumentation + +The simplest thing to do is pass a created connection to the +`AddRedisInstrumentation` extension method: + +```csharp +using var connection = ConnectionMultiplexer.Connect("localhost:6379"); + +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation(connection) + .Build(); +``` + +Whatever connection is specified will be collected by OpenTelemetry. + +### Use the application IServiceProvider + +Users using the `OpenTelemetry.Extensions.Hosting` package may prefer to manage +the Redis connection via the application `IServiceCollection`. To support this +scenario, if a connection is not passed to the `AddRedisInstrumentation` +extension manually one will be resolved one using the `IServiceProvider`: + +```csharp +appBuilder.Services.AddSingleton( + sp => MyRedisConnectionHelper.CreateConnection(sp)); + +appBuilder.Services + .AddOpenTelemetry() + .WithTracing(tracing => tracing.AddRedisInstrumentation()); +``` + +Whatever connection is found in the `IServiceProvider` will be collected by +OpenTelemetry. + +### Interact with StackExchangeRedisInstrumentation directly + +For full control of the Redis connection(s) being instrumented the +`ConfigureRedisInstrumentation` extension is provided to expose the +`StackExchangeRedisInstrumentation` class directly: + +```csharp +StackExchangeRedisInstrumentation redisInstrumentation = null; + +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddRedisInstrumentation() + .ConfigureRedisInstrumentation(instrumentation => redisInstrumentation = instrumentation) + .Build(); + +using var connection1 = ConnectionMultiplexer.Connect("localhost:6379"); +redisInstrumentation.AddConnection(connection1); + +using var connection2 = ConnectionMultiplexer.Connect("localhost:6380"); +redisInstrumentation.AddConnection(connection2); +``` + +Connections may be added or removed at any time. + ## Advanced configuration This instrumentation can be configured to change the default behavior by using diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs similarity index 86% rename from src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs index 63872364a0..4d09b762d1 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,15 +25,15 @@ namespace OpenTelemetry.Instrumentation.StackExchangeRedis; /// -/// Redis calls instrumentation. +/// StackExchange.Redis instrumentation. /// -internal class StackExchangeRedisCallsInstrumentation : IDisposable +internal sealed class StackExchangeRedisConnectionInstrumentation : IDisposable { internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; internal const string RedisFlagsKeyName = "db.redis.flags"; - internal static readonly string ActivitySourceName = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Name; + internal static readonly string ActivitySourceName = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Name; internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - internal static readonly Version Version = typeof(StackExchangeRedisCallsInstrumentation).Assembly.GetName().Version; + internal static readonly Version Version = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Version; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); internal static readonly IEnumerable> CreationTags = new[] { @@ -43,22 +43,22 @@ internal class StackExchangeRedisCallsInstrumentation : IDisposable internal readonly ConcurrentDictionary<(ActivityTraceId TraceId, ActivitySpanId SpanId), (Activity Activity, ProfilingSession Session)> Cache = new(); - private readonly StackExchangeRedisCallsInstrumentationOptions options; + private readonly StackExchangeRedisInstrumentationOptions options; private readonly EventWaitHandle stopHandle = new(false, EventResetMode.ManualReset); private readonly Thread drainThread; private readonly ProfilingSession defaultSession = new(); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// to instrument. /// Configuration options for redis instrumentation. - public StackExchangeRedisCallsInstrumentation(IConnectionMultiplexer connection, StackExchangeRedisCallsInstrumentationOptions options) + public StackExchangeRedisConnectionInstrumentation(IConnectionMultiplexer connection, StackExchangeRedisInstrumentationOptions options) { Guard.ThrowIfNull(connection); - this.options = options ?? new StackExchangeRedisCallsInstrumentationOptions(); + this.options = options ?? new StackExchangeRedisInstrumentationOptions(); this.drainThread = new Thread(this.DrainEntries) { diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs new file mode 100644 index 0000000000..cee5940681 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs @@ -0,0 +1,107 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Microsoft.Extensions.Options; +using OpenTelemetry.Internal; +using StackExchange.Redis; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis; + +/// +/// StackExchange.Redis instrumentation. +/// +public sealed class StackExchangeRedisInstrumentation : IDisposable +{ + private readonly IOptionsMonitor options; + + internal StackExchangeRedisInstrumentation( + IOptionsMonitor options) + { + this.options = options; + } + + internal List InstrumentedConnections { get; } = new(); + + /// + /// Adds an to the instrumentation. + /// + /// . + /// to cancel the registration. + public IDisposable AddConnection(IConnectionMultiplexer connection) + => this.AddConnection(Options.DefaultName, connection); + + /// + /// Adds an to the instrumentation. + /// + /// Name to use when retrieving options. + /// . + /// to cancel the registration. + public IDisposable AddConnection(string name, IConnectionMultiplexer connection) + { + Guard.ThrowIfNull(name); + Guard.ThrowIfNull(connection); + + var options = this.options.Get(name); + + lock (this.InstrumentedConnections) + { + var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, options); + + this.InstrumentedConnections.Add(instrumentation); + + return new StackExchangeRedisConnectionInstrumentationRegistration(() => + { + lock (this.InstrumentedConnections) + { + if (this.InstrumentedConnections.Remove(instrumentation)) + { + instrumentation.Dispose(); + } + } + }); + } + } + + /// + public void Dispose() + { + lock (this.InstrumentedConnections) + { + foreach (var instrumentation in this.InstrumentedConnections) + { + instrumentation.Dispose(); + } + + this.InstrumentedConnections.Clear(); + } + } + + private sealed class StackExchangeRedisConnectionInstrumentationRegistration : IDisposable + { + private readonly Action disposalAction; + + public StackExchangeRedisConnectionInstrumentationRegistration( + Action disposalAction) + { + this.disposalAction = disposalAction; + } + + public void Dispose() + { + this.disposalAction(); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs similarity index 78% rename from src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs index 0e27e838d5..71a317e756 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisCallsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,7 @@ namespace OpenTelemetry.Instrumentation.StackExchangeRedis; /// /// Options for StackExchange.Redis instrumentation. /// -public class StackExchangeRedisCallsInstrumentationOptions +public class StackExchangeRedisInstrumentationOptions { /// /// Gets or sets the maximum time that should elapse between flushing the internal buffer of Redis profiling sessions and creating objects. Default value: 00:00:10. @@ -31,7 +31,7 @@ public class StackExchangeRedisCallsInstrumentationOptions public TimeSpan FlushInterval { get; set; } = TimeSpan.FromSeconds(10); /// - /// Gets or sets a value indicating whether or not the should use reflection to get more detailed tag values. Default value: False. + /// Gets or sets a value indicating whether or not the should use reflection to get more detailed tag values. Default value: False. /// public bool SetVerboseDatabaseStatements { get; set; } @@ -45,7 +45,7 @@ public class StackExchangeRedisCallsInstrumentationOptions public Action? Enrich { get; set; } /// - /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. + /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. /// public bool EnrichActivityWithTimingEvents { get; set; } = true; } diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index 3bd9947930..842b3053c7 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -15,6 +15,7 @@ // using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.StackExchangeRedis; using OpenTelemetry.Internal; @@ -67,7 +68,7 @@ public static TracerProviderBuilder AddRedisInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddRedisInstrumentation( this TracerProviderBuilder builder, - Action configure) + Action configure) { Guard.ThrowIfNull(configure); @@ -84,7 +85,7 @@ public static TracerProviderBuilder AddRedisInstrumentation( public static TracerProviderBuilder AddRedisInstrumentation( this TracerProviderBuilder builder, IConnectionMultiplexer connection, - Action configure) + Action configure) { Guard.ThrowIfNull(connection); Guard.ThrowIfNull(configure); @@ -109,33 +110,89 @@ public static TracerProviderBuilder AddRedisInstrumentation( this TracerProviderBuilder builder, string? name, IConnectionMultiplexer? connection, - Action? configure) + Action? configure) { Guard.ThrowIfNull(builder); name ??= Options.DefaultName; + builder.AddRedisInstrumentationSharedServices(); + if (configure != null) { - builder.ConfigureServices(services => services.Configure(name, configure)); + builder.ConfigureServices(services => + { + services.Configure(name, configure); + }); } return builder - .AddSource(StackExchangeRedisCallsInstrumentation.ActivitySourceName) + .AddSource(StackExchangeRedisConnectionInstrumentation.ActivitySourceName) .AddInstrumentation(sp => { - if (connection == null) + var instrumentation = sp.GetRequiredService(); + + connection ??= sp.GetService(); + + if (connection != null) { - connection = sp.GetService(); - if (connection == null) - { - throw new InvalidOperationException($"StackExchange.Redis {nameof(IConnectionMultiplexer)} could not be resolved through application {nameof(IServiceProvider)}"); - } + instrumentation.AddConnection(name, connection); } - return new StackExchangeRedisCallsInstrumentation( - connection, - sp.GetRequiredService>().Get(name)); + return instrumentation; }); } + + /// + /// Registers a callback for configuring Redis instrumentation. + /// + /// being configured. + /// Callback to configure instrumentation. + /// The instance of to chain the calls. + public static TracerProviderBuilder ConfigureRedisInstrumentation( + this TracerProviderBuilder builder, + Action configure) + { + Guard.ThrowIfNull(configure); + + return ConfigureRedisInstrumentation(builder, (sp, instrumentation) => configure(instrumentation)); + } + + /// + /// Registers a callback for configuring Redis instrumentation. + /// + /// being configured. + /// Callback to configure instrumentation. + /// The instance of to chain the calls. + public static TracerProviderBuilder ConfigureRedisInstrumentation( + this TracerProviderBuilder builder, + Action configure) + { + Guard.ThrowIfNull(configure); + + if (builder is not IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + throw new NotSupportedException("ConfigureRedisInstrumentation is not supported on the supplied builder type."); + } + + builder.AddRedisInstrumentationSharedServices(); + + deferredTracerProviderBuilder.Configure( + (sp, builder) => configure(sp, sp.GetRequiredService())); + + return builder; + } + + private static TracerProviderBuilder AddRedisInstrumentationSharedServices( + this TracerProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + + return builder.ConfigureServices(services => + { + services.TryAddSingleton( + sp => new StackExchangeRedisInstrumentation( + sp.GetRequiredService>())); + }); + } } diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index 784f9a528b..f92bf20aaa 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -63,7 +63,7 @@ public void ProfilerCommandToActivity_UsesCommandAsName() profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); profiledCommand.Setup(m => m.Command).Returns("SET"); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.Equal("SET", result.DisplayName); } @@ -76,7 +76,7 @@ public void ProfilerCommandToActivity_UsesTimestampAsStartTime() var profiledCommand = new Mock(); profiledCommand.Setup(m => m.CommandCreated).Returns(now.DateTime); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.Equal(now, result.StartTimeUtc); } @@ -88,7 +88,7 @@ public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() var profiledCommand = new Mock(); profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbSystem)); Assert.Equal("redis", result.GetTagValue(SemanticConventions.AttributeDbSystem)); @@ -102,7 +102,7 @@ public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); profiledCommand.Setup(m => m.Command).Returns("SET"); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbStatement)); Assert.Equal("SET", result.GetTagValue(SemanticConventions.AttributeDbStatement)); @@ -118,10 +118,10 @@ public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() CommandFlags.NoRedirect; profiledCommand.Setup(m => m.Flags).Returns(expectedFlags); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); - Assert.NotNull(result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); - Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisFlagsKeyName)); + Assert.NotNull(result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); + Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); } [Fact] @@ -136,7 +136,7 @@ public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); profiledCommand.Setup(m => m.EndPoint).Returns(ipLocalEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); Assert.Equal($"{address}.0.0.0", result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); @@ -154,7 +154,7 @@ public void ProfilerCommandToActivity_UsesDnsEndPointAsEndPoint() profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); profiledCommand.Setup(m => m.EndPoint).Returns(dnsEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerName)); Assert.Equal(dnsEndPoint.Host, result.GetTagValue(SemanticConventions.AttributeNetPeerName)); @@ -172,7 +172,7 @@ public void ProfilerCommandToActivity_UsesOtherEndPointAsEndPoint() profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); profiledCommand.Setup(m => m.EndPoint).Returns(unixEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisCallsInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributePeerService)); Assert.Equal(unixEndPoint.ToString(), result.GetTagValue(SemanticConventions.AttributePeerService)); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 55cdb58011..d0be5f00d2 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -19,6 +19,7 @@ using System.Net; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Moq; using OpenTelemetry.Tests; using OpenTelemetry.Trace; @@ -107,16 +108,24 @@ public void SuccessfulCommandTest(string value) }; connectionOptions.EndPoints.Add(RedisEndPoint); - using var connection = ConnectionMultiplexer.Connect(connectionOptions); - + IConnectionMultiplexer connection = null; var activityProcessor = new Mock>(); var sampler = new TestSampler(); using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = false) - .Build()) + .ConfigureServices(services => + { + services.TryAddSingleton(sp => + { + return connection = ConnectionMultiplexer.Connect(connectionOptions); + }); + }) + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(c => c.SetVerboseDatabaseStatements = false) + .Build()) { + Assert.NotNull(connection); + var db = connection.GetDatabase(); bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); @@ -149,7 +158,7 @@ public async void ProfilerSessionUsesTheSameDefault() var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, new StackExchangeRedisInstrumentationOptions()); var profilerFactory = instrumentation.GetProfilerSessionsFactory(); var first = profilerFactory(); var second = profilerFactory(); @@ -164,28 +173,36 @@ public async void ProfilerSessionUsesTheSameDefault() [InlineData("value1")] public void CanEnrichActivityFromCommand(string value) { + StackExchangeRedisInstrumentation instrumentation = null; + var connectionOptions = new ConfigurationOptions { AbortOnConnectFail = true, }; connectionOptions.EndPoints.Add(RedisEndPoint); - using var connection = ConnectionMultiplexer.Connect(connectionOptions); var activityProcessor = new Mock>(); var sampler = new TestSampler(); - using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddRedisInstrumentation(connection, c => c.Enrich = (activity, command) => - { - if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) - { - activity.AddTag("is_fast", true); - } - }) - .Build()) + + var builder = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(c => c.Enrich = (activity, command) => + { + if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) + { + activity.AddTag("is_fast", true); + } + }) + .ConfigureRedisInstrumentation(i => instrumentation = i); + + using (builder.Build()) { + Assert.NotNull(instrumentation); + + instrumentation.AddConnection(connection); + var db = connection.GetDatabase(); bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); @@ -219,7 +236,7 @@ public void CheckCacheIsFlushedProperly() var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, new StackExchangeRedisInstrumentationOptions()); var profilerFactory = instrumentation.GetProfilerSessionsFactory(); // start a root level activity @@ -259,7 +276,7 @@ public async Task ProfilerSessionsHandleMultipleSpans() var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisCallsInstrumentation(connection, new StackExchangeRedisCallsInstrumentationOptions()); + using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, new StackExchangeRedisInstrumentationOptions()); var profilerFactory = instrumentation.GetProfilerSessionsFactory(); // start a root level activity @@ -306,14 +323,6 @@ public void StackExchangeRedis_BadArgs() { TracerProviderBuilder builder = null; Assert.Throws(() => builder.AddRedisInstrumentation(connection: null)); - - var activityProcessor = new Mock>(); - var exception = Assert.Throws(() => - Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .AddRedisInstrumentation(name: null, connection: null, configure: null) - .Build()); - Assert.Equal("StackExchange.Redis IConnectionMultiplexer could not be resolved through application IServiceProvider", exception.Message); } [Fact] @@ -334,7 +343,7 @@ public void StackExchangeRedis_DependencyInjection_Success() connectionMultiplexerPickedFromDI = true; return ConnectionMultiplexer.Connect(connectionOptions); }); - services.Configure(options => + services.Configure(options => { optionsPickedFromDI = true; }); @@ -349,15 +358,49 @@ public void StackExchangeRedis_DependencyInjection_Success() } [Fact] - public void StackExchangeRedis_DependencyInjection_Failure() + public void StackExchangeRedis_StackExchangeRedisInstrumentation_Test() { - var services = new ServiceCollection(); + StackExchangeRedisInstrumentation instrumentation = null; - services.AddOpenTelemetry().WithTracing(builder => builder.AddRedisInstrumentation()); + var connectionOptions = new ConfigurationOptions + { + AbortOnConnectFail = false, + }; + connectionOptions.EndPoints.Add("localhost"); - using var serviceProvider = services.BuildServiceProvider(); + using var connection = ConnectionMultiplexer.Connect(connectionOptions); + + var activityProcessor = new Mock>(); + var sampler = new TestSampler(); + + var builder = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .SetSampler(sampler) + .AddRedisInstrumentation(c => c.Enrich = (activity, command) => + { + if (command.ElapsedTime < TimeSpan.FromMilliseconds(100)) + { + activity.AddTag("is_fast", true); + } + }) + .ConfigureRedisInstrumentation(i => instrumentation = i); + + using (builder.Build()) + { + Assert.NotNull(instrumentation); + + var registration = instrumentation.AddConnection(connection); + + Assert.NotEmpty(instrumentation.InstrumentedConnections); + + registration.Dispose(); + + Assert.Empty(instrumentation.InstrumentedConnections); + + instrumentation.AddConnection(connection); + } - Assert.Throws(() => serviceProvider.GetRequiredService()); + Assert.Empty(instrumentation.InstrumentedConnections); } private static void VerifyActivityData(Activity activity, bool isSet, EndPoint endPoint, bool setCommandKey = false) @@ -389,7 +432,7 @@ private static void VerifyActivityData(Activity activity, bool isSet, EndPoint e Assert.Equal(Status.Unset, activity.GetStatus()); Assert.Equal("redis", activity.GetTagValue(SemanticConventions.AttributeDbSystem)); - Assert.Equal(0, activity.GetTagValue(StackExchangeRedisCallsInstrumentation.RedisDatabaseIndexKeyName)); + Assert.Equal(0, activity.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisDatabaseIndexKeyName)); if (endPoint is IPEndPoint ipEndPoint) { From e1a934036aef4b82d9f1f976f635465c140971b3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 May 2023 00:14:49 -0700 Subject: [PATCH 0709/1499] [redis] Append options name to the background thread (#1205) --- .../CHANGELOG.md | 5 +++++ .../StackExchangeRedisConnectionInstrumentation.cs | 8 ++++++-- .../StackExchangeRedisInstrumentation.cs | 2 +- .../StackExchangeRedisCallsInstrumentationTests.cs | 6 +++--- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 9aa2cc6049..0de7a0b741 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -18,6 +18,11 @@ `TracerProvider` has been created. ([#1193](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1193)) +* When using named options the name will now be applied to the background thread + created for each instrumented connection in the format + `OpenTelemetry.Redis{OPTIONS_NAME_HERE}`. + ([#1205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1205)) + ## 1.0.0-rc9.8 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs index 4d09b762d1..f1a4a9e528 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs @@ -53,8 +53,12 @@ internal sealed class StackExchangeRedisConnectionInstrumentation : IDisposable /// Initializes a new instance of the class. /// /// to instrument. + /// Optional name for the connection. /// Configuration options for redis instrumentation. - public StackExchangeRedisConnectionInstrumentation(IConnectionMultiplexer connection, StackExchangeRedisInstrumentationOptions options) + public StackExchangeRedisConnectionInstrumentation( + IConnectionMultiplexer connection, + string? name, + StackExchangeRedisInstrumentationOptions options) { Guard.ThrowIfNull(connection); @@ -62,7 +66,7 @@ public StackExchangeRedisConnectionInstrumentation(IConnectionMultiplexer connec this.drainThread = new Thread(this.DrainEntries) { - Name = "OpenTelemetry.Redis", + Name = string.IsNullOrWhiteSpace(name) ? "OpenTelemetry.Redis" : $"OpenTelemetry.Redis{{{name}}}", IsBackground = true, }; this.drainThread.Start(); diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs index cee5940681..cd8fdbb3f1 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs @@ -58,7 +58,7 @@ public IDisposable AddConnection(string name, IConnectionMultiplexer connection) lock (this.InstrumentedConnections) { - var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, options); + var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, name, options); this.InstrumentedConnections.Add(instrumentation); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index d0be5f00d2..c3b40c7050 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -158,7 +158,7 @@ public async void ProfilerSessionUsesTheSameDefault() var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, new StackExchangeRedisInstrumentationOptions()); + using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, name: null, new StackExchangeRedisInstrumentationOptions()); var profilerFactory = instrumentation.GetProfilerSessionsFactory(); var first = profilerFactory(); var second = profilerFactory(); @@ -236,7 +236,7 @@ public void CheckCacheIsFlushedProperly() var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, new StackExchangeRedisInstrumentationOptions()); + using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, name: null, new StackExchangeRedisInstrumentationOptions()); var profilerFactory = instrumentation.GetProfilerSessionsFactory(); // start a root level activity @@ -276,7 +276,7 @@ public async Task ProfilerSessionsHandleMultipleSpans() var connection = ConnectionMultiplexer.Connect(connectionOptions); - using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, new StackExchangeRedisInstrumentationOptions()); + using var instrumentation = new StackExchangeRedisConnectionInstrumentation(connection, name: null, new StackExchangeRedisInstrumentationOptions()); var profilerFactory = instrumentation.GetProfilerSessionsFactory(); // start a root level activity From ab568a54d153c36892e55b183647de5e5dc16bc0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 May 2023 10:42:16 -0700 Subject: [PATCH 0710/1499] [redis] CHANGELOG update for 1.0.0-rc11 release (#1207) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 0de7a0b741..9fb79c30df 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc11 + +Released 2023-May-25 + * Added a dependency on `OpenTelemetry.Api.ProviderBuilderExtensions` and updated `TracerProviderBuilder.AddRedisInstrumentation` to support named options. From c540f4d39dd4d36ff4b9e66dd893a215ede081a3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 May 2023 11:25:18 -0700 Subject: [PATCH 0711/1499] [redis] Switch CHANGELOG to use version rc9.9 (#1208) --- .../CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 9fb79c30df..dd61aafd97 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -## 1.0.0-rc11 +## 1.0.0-rc9.9 Released 2023-May-25 From 18b0b0319082880e939516504c1162c1cd1e51a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 May 2023 17:18:48 -0700 Subject: [PATCH 0712/1499] Bump actions/setup-dotnet from 3.0.3 to 3.1.0 (#1209) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-Instrumentation.Process.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/dotnet-core-cov.yml | 2 +- .github/workflows/dotnet-format.yml | 2 +- .github/workflows/package-Exporter.Geneva.yml | 2 +- .github/workflows/package-Exporter.InfluxDB.yml | 2 +- .github/workflows/package-Exporter.Instana.yml | 2 +- .github/workflows/package-Exporter.OneCollector.yml | 2 +- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWSXRay.yml | 2 +- .github/workflows/package-Extensions.AzureMonitor.yml | 2 +- .github/workflows/package-Extensions.Enrichment.yml | 2 +- .github/workflows/package-Extensions.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 2 +- .github/workflows/package-Instrumentation.AspNet.yml | 2 +- .github/workflows/package-Instrumentation.Cassandra.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.EventCounters.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.Hangfire.yml | 2 +- .github/workflows/package-Instrumentation.MySqlData.yml | 2 +- .github/workflows/package-Instrumentation.Owin.yml | 2 +- .github/workflows/package-Instrumentation.Process.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-Instrumentation.Runtime.yml | 2 +- .../workflows/package-Instrumentation.StackExchangeRedis.yml | 2 +- .github/workflows/package-Instrumentation.Wcf.yml | 2 +- .github/workflows/package-PersistentStorage.Abstractions.yml | 2 +- .github/workflows/package-PersistentStorage.FileSystem.yml | 2 +- .github/workflows/package-ResourceDetectors.AWS.yml | 2 +- .github/workflows/package-ResourceDetectors.Azure.yml | 2 +- .github/workflows/package-ResourceDetectors.Container.yml | 2 +- .github/workflows/package-Sampler.AWS.yml | 2 +- 36 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index 7de64e9e77..e787cfb98b 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -22,12 +22,12 @@ jobs: - uses: actions/checkout@v3 - name: Install .NET 3.1 SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '3.1.x' - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8ef6da230..63cbdb9bf6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,12 +27,12 @@ jobs: - uses: actions/checkout@v3 - name: Install .NET 3.1 SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '3.1.x' - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index 00b45b12a8..da5562aef2 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -25,7 +25,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup .NET 7.0 - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index e4a59cccf2..1afc16d992 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.0.3 + uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index 763212c293..e4d53ca4fc 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml index eb3925ea7a..e766237ad9 100644 --- a/.github/workflows/package-Exporter.InfluxDB.yml +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index 4e3aa0cc77..c55a92aa79 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml index 9ffde4b334..02233dcf2a 100644 --- a/.github/workflows/package-Exporter.OneCollector.yml +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index f3a62de95c..1d4fe48348 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index dd9f35b59d..c277286bd8 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml index 2107d1d587..75369ca91f 100644 --- a/.github/workflows/package-Extensions.AzureMonitor.yml +++ b/.github/workflows/package-Extensions.AzureMonitor.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml index 7d6fc0629c..121bc96b22 100644 --- a/.github/workflows/package-Extensions.Enrichment.yml +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index 07cd334e96..b6749649a7 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index 12b140a9a4..722afb440e 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 38ff751d3c..80ab4f061e 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 80a248c6bb..9135c20160 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 7f17792934..415182bf1d 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml index 260ac22d4a..4885b6174b 100644 --- a/.github/workflows/package-Instrumentation.Cassandra.yml +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -26,7 +26,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 41d72e55a8..a138e19045 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 7a182d5148..53e05c9a3b 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index 94ecd0feac..ebf95a3d15 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index 2c8f515af9..cb05ef3756 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index d8a146426d..bc70ae2d27 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index e8e524b2ae..66b26dfcd6 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index b5a38a4aed..bc025dddb8 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index a94f937909..ade8d43c77 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 7625a96310..cdb2237401 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index 8a67ce59e8..da8772f35d 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index 71a82604e2..460ea03937 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 119864f124..0f4c958907 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-PersistentStorage.Abstractions.yml b/.github/workflows/package-PersistentStorage.Abstractions.yml index 1fb68c9672..06a4ed0c9b 100644 --- a/.github/workflows/package-PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-PersistentStorage.Abstractions.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-PersistentStorage.FileSystem.yml b/.github/workflows/package-PersistentStorage.FileSystem.yml index 67abae901f..5c7e6d486d 100644 --- a/.github/workflows/package-PersistentStorage.FileSystem.yml +++ b/.github/workflows/package-PersistentStorage.FileSystem.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml index bad669cca3..920afabcf6 100644 --- a/.github/workflows/package-ResourceDetectors.AWS.yml +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml index 7191c14468..2773d8a38c 100644 --- a/.github/workflows/package-ResourceDetectors.Azure.yml +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-ResourceDetectors.Container.yml b/.github/workflows/package-ResourceDetectors.Container.yml index ee307b95f5..a1ac34bb54 100644 --- a/.github/workflows/package-ResourceDetectors.Container.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml index eb9036ccbb..843e379f15 100644 --- a/.github/workflows/package-Sampler.AWS.yml +++ b/.github/workflows/package-Sampler.AWS.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.0.3 + - uses: actions/setup-dotnet@v3.1.0 with: dotnet-version: '7.0.x' From 614bdf9a20c7ff325e82e7b3e8735c23a600772e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 06:31:08 +0200 Subject: [PATCH 0713/1499] Bump actions/setup-dotnet from 3.1.0 to 3.2.0 (#1211) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci-Instrumentation.Process.yml | 4 ++-- .github/workflows/ci.yml | 4 ++-- .github/workflows/dotnet-core-cov.yml | 2 +- .github/workflows/dotnet-format.yml | 2 +- .github/workflows/package-Exporter.Geneva.yml | 2 +- .github/workflows/package-Exporter.InfluxDB.yml | 2 +- .github/workflows/package-Exporter.Instana.yml | 2 +- .github/workflows/package-Exporter.OneCollector.yml | 2 +- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWSXRay.yml | 2 +- .github/workflows/package-Extensions.AzureMonitor.yml | 2 +- .github/workflows/package-Extensions.Enrichment.yml | 2 +- .github/workflows/package-Extensions.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 2 +- .github/workflows/package-Instrumentation.AspNet.yml | 2 +- .github/workflows/package-Instrumentation.Cassandra.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.EventCounters.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.Hangfire.yml | 2 +- .github/workflows/package-Instrumentation.MySqlData.yml | 2 +- .github/workflows/package-Instrumentation.Owin.yml | 2 +- .github/workflows/package-Instrumentation.Process.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-Instrumentation.Runtime.yml | 2 +- .../workflows/package-Instrumentation.StackExchangeRedis.yml | 2 +- .github/workflows/package-Instrumentation.Wcf.yml | 2 +- .github/workflows/package-PersistentStorage.Abstractions.yml | 2 +- .github/workflows/package-PersistentStorage.FileSystem.yml | 2 +- .github/workflows/package-ResourceDetectors.AWS.yml | 2 +- .github/workflows/package-ResourceDetectors.Azure.yml | 2 +- .github/workflows/package-ResourceDetectors.Container.yml | 2 +- .github/workflows/package-Sampler.AWS.yml | 2 +- 36 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index e787cfb98b..206594fad6 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -22,12 +22,12 @@ jobs: - uses: actions/checkout@v3 - name: Install .NET 3.1 SDK - uses: actions/setup-dotnet@v3.1.0 + uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '3.1.x' - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.1.0 + uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63cbdb9bf6..a89029349b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,12 +27,12 @@ jobs: - uses: actions/checkout@v3 - name: Install .NET 3.1 SDK - uses: actions/setup-dotnet@v3.1.0 + uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '3.1.x' - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.1.0 + uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index da5562aef2..be6b24e964 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -25,7 +25,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup .NET 7.0 - uses: actions/setup-dotnet@v3.1.0 + uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 1afc16d992..45f9c26166 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v3 - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.1.0 + uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index e4d53ca4fc..44111dca8b 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml index e766237ad9..fcceeaa2cf 100644 --- a/.github/workflows/package-Exporter.InfluxDB.yml +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index c55a92aa79..71168712b3 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml index 02233dcf2a..910bdaa0a2 100644 --- a/.github/workflows/package-Exporter.OneCollector.yml +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index 1d4fe48348..399dc1f707 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWSXRay.yml index c277286bd8..dd177767be 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWSXRay.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml index 75369ca91f..c79ea529bc 100644 --- a/.github/workflows/package-Extensions.AzureMonitor.yml +++ b/.github/workflows/package-Extensions.AzureMonitor.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml index 121bc96b22..ebcd7b80a1 100644 --- a/.github/workflows/package-Extensions.Enrichment.yml +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index b6749649a7..3efc67ad40 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index 722afb440e..61db291d20 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 80ab4f061e..8043daf093 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 9135c20160..67e2e0f61d 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 415182bf1d..748fe3d5ee 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml index 4885b6174b..bc43454401 100644 --- a/.github/workflows/package-Instrumentation.Cassandra.yml +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -26,7 +26,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index a138e19045..927fdf59ea 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 53e05c9a3b..154369efd3 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index ebf95a3d15..b5baf9ff3b 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index cb05ef3756..04e6174c5a 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index bc70ae2d27..d27017c7bd 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index 66b26dfcd6..97252dc255 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index bc025dddb8..0361835651 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index ade8d43c77..ffc2e8d456 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index cdb2237401..36c7ec098e 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index da8772f35d..b717dd6f0e 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index 460ea03937..54b38de3cd 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 0f4c958907..35bed0e435 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-PersistentStorage.Abstractions.yml b/.github/workflows/package-PersistentStorage.Abstractions.yml index 06a4ed0c9b..327c47d364 100644 --- a/.github/workflows/package-PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-PersistentStorage.Abstractions.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-PersistentStorage.FileSystem.yml b/.github/workflows/package-PersistentStorage.FileSystem.yml index 5c7e6d486d..0a6dd92858 100644 --- a/.github/workflows/package-PersistentStorage.FileSystem.yml +++ b/.github/workflows/package-PersistentStorage.FileSystem.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml index 920afabcf6..e9c4c8e286 100644 --- a/.github/workflows/package-ResourceDetectors.AWS.yml +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml index 2773d8a38c..fc467ad5ce 100644 --- a/.github/workflows/package-ResourceDetectors.Azure.yml +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-ResourceDetectors.Container.yml b/.github/workflows/package-ResourceDetectors.Container.yml index a1ac34bb54..2065f874c1 100644 --- a/.github/workflows/package-ResourceDetectors.Container.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml index 843e379f15..04619fbb07 100644 --- a/.github/workflows/package-Sampler.AWS.yml +++ b/.github/workflows/package-Sampler.AWS.yml @@ -28,7 +28,7 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.1.0 + - uses: actions/setup-dotnet@v3.2.0 with: dotnet-version: '7.0.x' From 964e2bd79a2eb3677f881738bd2a0c1977de24a9 Mon Sep 17 00:00:00 2001 From: Prashant Srivastava <50466688+srprash@users.noreply.github.com> Date: Tue, 30 May 2023 09:32:44 -0700 Subject: [PATCH 0714/1499] [Sampler.AWS] Part-3: Update targets. Add rate limiting and fixed rate samplers. (#1151) --- .../AWSXRayRemoteSampler.cs | 52 +++++ .../AWSXRaySamplerClient.cs | 31 +++ src/OpenTelemetry.Sampler.AWS/Clock.cs | 2 +- .../FallbackSampler.cs | 16 +- .../GetSamplingTargetsRequest.cs | 31 +++ .../GetSamplingTargetsResponse.cs | 43 ++++ src/OpenTelemetry.Sampler.AWS/RateLimiter.cs | 62 ++++++ .../RateLimitingSampler.cs | 38 ++++ src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 60 +++++ .../SamplingRuleApplier.cs | 144 +++++++++++- .../SamplingStatisticsDocument.cs | 50 +++++ .../SamplingTargetDocument.cs | 37 ++++ src/OpenTelemetry.Sampler.AWS/Statistics.cs | 8 +- src/OpenTelemetry.Sampler.AWS/SystemClock.cs | 8 +- .../UnprocessedStatistic.cs | 38 ++++ ...etSamplingRulesResponseOptionalFields.json | 42 ++++ .../Data/GetSamplingTargetsResponse.json | 23 ++ ...SamplingTargetsResponseOptionalFields.json | 16 ++ .../OpenTelemetry.Sampler.AWS.Tests.csproj | 7 +- .../TestAWSXRayRemoteSampler.cs | 76 ++++++- .../TestAWSXRaySamplerClient.cs | 85 ++++++++ .../TestClock.cs | 12 +- .../TestRateLimiter.cs | 163 ++++++++++++++ .../TestRateLimitingSampler.cs | 44 ++++ .../TestRulesCache.cs | 132 ++++++++++- .../TestSamplingRuleApplier.cs | 206 +++++++++++++++++- test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs | 16 ++ 27 files changed, 1405 insertions(+), 37 deletions(-) create mode 100644 src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/RateLimiter.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponseOptionalFields.json create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponse.json create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponseOptionalFields.json create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs create mode 100644 test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs index b688720016..179de0ec3b 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -47,12 +47,20 @@ internal AWSXRayRemoteSampler(Resource resource, TimeSpan pollingInterval, strin // upto 5 seconds of jitter for rule polling this.RulePollerJitter = TimeSpan.FromMilliseconds(Random.Next(1, 5000)); + // upto 100 milliseconds of jitter for target polling + this.TargetPollerJitter = TimeSpan.FromMilliseconds(Random.Next(1, 100)); + // execute the first update right away and schedule subsequent update later. this.RulePollerTimer = new Timer(this.GetAndUpdateRules, null, TimeSpan.Zero, Timeout.InfiniteTimeSpan); + + // set up the target poller to go off once after the default interval. We will update the timer later. + this.TargetPollerTimer = new Timer(this.GetAndUpdateTargets, null, DefaultTargetInterval, Timeout.InfiniteTimeSpan); } internal TimeSpan RulePollerJitter { get; set; } + internal TimeSpan TargetPollerJitter { get; set; } + internal Clock Clock { get; set; } internal string ClientId { get; set; } @@ -67,6 +75,8 @@ internal AWSXRayRemoteSampler(Resource resource, TimeSpan pollingInterval, strin internal Timer RulePollerTimer { get; set; } + internal Timer TargetPollerTimer { get; set; } + internal TimeSpan PollingInterval { get; set; } internal Trace.Sampler FallbackSampler { get; set; } @@ -137,4 +147,46 @@ private async void GetAndUpdateRules(object? state) // schedule the next rule poll. this.RulePollerTimer.Change(this.PollingInterval.Add(this.RulePollerJitter), Timeout.InfiniteTimeSpan); } + + private async void GetAndUpdateTargets(object? state) + { + List statistics = this.RulesCache.Snapshot(this.Clock.Now()); + + GetSamplingTargetsRequest request = new GetSamplingTargetsRequest(statistics); + GetSamplingTargetsResponse? response = await this.Client.GetSamplingTargets(request).ConfigureAwait(false); + if (response != null) + { + Dictionary targets = new Dictionary(); + foreach (SamplingTargetDocument target in response.SamplingTargetDocuments) + { + if (target.RuleName != null) + { + targets[target.RuleName] = target; + } + } + + this.RulesCache.UpdateTargets(targets); + + if (response.LastRuleModification > 0) + { + DateTime lastRuleModificationTime = this.Clock.ToDateTime(response.LastRuleModification); + + if (lastRuleModificationTime > this.RulesCache.GetUpdatedAt()) + { + // rules have been updated. fetch the new ones right away. + this.RulePollerTimer.Change(TimeSpan.Zero, Timeout.InfiniteTimeSpan); + } + } + } + + // schedule next target poll + DateTime nextTargetFetchTime = this.RulesCache.NextTargetFetchTime(); + TimeSpan nextTargetFetchInterval = nextTargetFetchTime.Subtract(this.Clock.Now()); + if (nextTargetFetchInterval < TimeSpan.Zero) + { + nextTargetFetchInterval = DefaultTargetInterval; + } + + this.TargetPollerTimer.Change(nextTargetFetchInterval.Add(this.TargetPollerJitter), Timeout.InfiniteTimeSpan); + } } diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index 1a40673fb5..64b7649e8f 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -26,12 +26,15 @@ namespace OpenTelemetry.Sampler.AWS; internal class AWSXRaySamplerClient : IDisposable { private readonly string getSamplingRulesEndpoint; + private readonly string getSamplingTargetsEndpoint; + private readonly HttpClient httpClient; private readonly string jsonContentType = "application/json"; public AWSXRaySamplerClient(string host) { this.getSamplingRulesEndpoint = host + "/GetSamplingRules"; + this.getSamplingTargetsEndpoint = host + "/SamplingTargets"; this.httpClient = new HttpClient(); } @@ -74,6 +77,34 @@ public async Task> GetSamplingRules() return samplingRules; } + public async Task GetSamplingTargets(GetSamplingTargetsRequest getSamplingTargetsRequest) + { + var content = new StringContent(JsonSerializer.Serialize(getSamplingTargetsRequest), Encoding.UTF8, this.jsonContentType); + + using var request = new HttpRequestMessage(HttpMethod.Post, this.getSamplingTargetsEndpoint) + { + Content = content, + }; + + var responseJson = await this.DoRequestAsync(this.getSamplingTargetsEndpoint, request).ConfigureAwait(false); + + try + { + GetSamplingTargetsResponse? getSamplingTargetsResponse = JsonSerializer + .Deserialize(responseJson); + + return getSamplingTargetsResponse; + } + catch (Exception ex) + { + AWSSamplerEventSource.Log.FailedToDeserializeResponse( + nameof(AWSXRaySamplerClient.GetSamplingTargets), + ex.Message); + } + + return null; + } + public void Dispose() { this.Dispose(true); diff --git a/src/OpenTelemetry.Sampler.AWS/Clock.cs b/src/OpenTelemetry.Sampler.AWS/Clock.cs index 39218fbdf2..1043e4aa36 100644 --- a/src/OpenTelemetry.Sampler.AWS/Clock.cs +++ b/src/OpenTelemetry.Sampler.AWS/Clock.cs @@ -28,7 +28,7 @@ public static Clock GetDefault() public abstract DateTime Now(); - public abstract long NowInSeconds(); + public abstract long NowInMilliSeconds(); public abstract DateTime ToDateTime(double seconds); diff --git a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs index 3917c407fe..72d756b322 100644 --- a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs @@ -20,19 +20,25 @@ namespace OpenTelemetry.Sampler.AWS; internal class FallbackSampler : Trace.Sampler { - private static readonly Trace.Sampler AlwaysOn = new AlwaysOnSampler(); - + private readonly Trace.Sampler reservoirSampler; + private readonly Trace.Sampler fixedRateSampler; private readonly Clock clock; public FallbackSampler(Clock clock) { this.clock = clock; + this.reservoirSampler = new ParentBasedSampler(new RateLimitingSampler(1, clock)); + this.fixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(0.05)); } public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { - // For now just do an always on sampler. - // TODO: update to a rate limiting sampler. - return AlwaysOn.ShouldSample(samplingParameters); + SamplingResult result = this.reservoirSampler.ShouldSample(in samplingParameters); + if (result.Decision != SamplingDecision.Drop) + { + return result; + } + + return this.fixedRateSampler.ShouldSample(in samplingParameters); } } diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs new file mode 100644 index 0000000000..f7bafb0921 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class GetSamplingTargetsRequest +{ + public GetSamplingTargetsRequest(List documents) + { + this.SamplingStatisticsDocuments = documents; + } + + [JsonPropertyName("SamplingStatisticsDocuments")] + public List SamplingStatisticsDocuments { get; set; } +} diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs new file mode 100644 index 0000000000..1490e5e6d7 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class GetSamplingTargetsResponse +{ + public GetSamplingTargetsResponse( + double lastRuleModification, + List samplingTargetDocuments, + List unprocessedStatistics) + { + this.LastRuleModification = lastRuleModification; + this.SamplingTargetDocuments = samplingTargetDocuments; + this.UnprocessedStatistics = unprocessedStatistics; + } + + // This is actually a time in unix seconds. + [JsonPropertyName("LastRuleModification")] + public double LastRuleModification { get; set; } + + [JsonPropertyName("SamplingTargetDocuments")] + public List SamplingTargetDocuments { get; set; } + + [JsonPropertyName("UnprocessedStatistics")] + public List UnprocessedStatistics { get; set; } +} diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs new file mode 100644 index 0000000000..aba7ea134d --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs @@ -0,0 +1,62 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Threading; + +namespace OpenTelemetry.Sampler.AWS; +internal sealed class RateLimiter +{ + private readonly Clock clock; + private readonly double creditsPerMillisecond; + private readonly long maxBalance; + private long currentBalance; + + internal RateLimiter(double creditsPerSecond, double maxBalance, Clock clock) + { + this.clock = clock; + this.creditsPerMillisecond = creditsPerSecond / 1.0e3; + this.maxBalance = (long)(maxBalance / this.creditsPerMillisecond); + this.currentBalance = this.clock.NowInMilliSeconds() - this.maxBalance; + } + + public bool TrySpend(double itemCost) + { + long cost = (long)(itemCost / this.creditsPerMillisecond); + long currentMillis; + long currentBalanceMillis; + long availableBalanceAfterWithdrawal; + + do + { + currentBalanceMillis = Interlocked.Read(ref this.currentBalance); + currentMillis = this.clock.NowInMilliSeconds(); + long currentAvailableBalance = currentMillis - currentBalanceMillis; + if (currentAvailableBalance > this.maxBalance) + { + currentAvailableBalance = this.maxBalance; + } + + availableBalanceAfterWithdrawal = currentAvailableBalance - cost; + if (availableBalanceAfterWithdrawal < 0) + { + return false; + } + } + while (Interlocked.CompareExchange(ref this.currentBalance, currentMillis - availableBalanceAfterWithdrawal, currentBalanceMillis) != currentBalanceMillis); + + return true; + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs b/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs new file mode 100644 index 0000000000..2a315787c7 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Sampler.AWS; +internal class RateLimitingSampler : Trace.Sampler +{ + private readonly RateLimiter limiter; + + public RateLimitingSampler(long numPerSecond, Clock clock) + { + this.limiter = new RateLimiter(numPerSecond, numPerSecond, clock); + } + + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + if (this.limiter.TrySpend(1)) + { + return new SamplingResult(SamplingDecision.RecordAndSample); + } + + return new SamplingResult(SamplingDecision.Drop); + } +} diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs index 182ab0b013..3e8efce9c3 100644 --- a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -109,6 +109,66 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters) return this.FallbackSampler.ShouldSample(in samplingParameters); } + public List Snapshot(DateTime now) + { + List snapshots = new List(); + foreach (var ruleApplier in this.RuleAppliers) + { + snapshots.Add(ruleApplier.Snapshot(now)); + } + + return snapshots; + } + + public void UpdateTargets(Dictionary targets) + { + List newRuleAppliers = new List(); + foreach (var ruleApplier in this.RuleAppliers) + { + targets.TryGetValue(ruleApplier.RuleName, out SamplingTargetDocument? target); + if (target != null) + { + newRuleAppliers.Add(ruleApplier.WithTarget(target, this.Clock.Now())); + } + else + { + // did not get target for this rule. Will be updated in future target poll. + newRuleAppliers.Add(ruleApplier); + } + } + + this.rwLock.EnterWriteLock(); + try + { + this.RuleAppliers = newRuleAppliers; + } + finally + { + this.rwLock.ExitWriteLock(); + } + } + + public DateTime NextTargetFetchTime() + { + var defaultPollingTime = this.Clock.Now().AddSeconds(AWSXRayRemoteSampler.DefaultTargetInterval.TotalSeconds); + + if (this.RuleAppliers.Count == 0) + { + return defaultPollingTime; + } + + var minPollingTime = this.RuleAppliers + .Select(r => r.NextSnapshotTime) + .Min(); + + if (minPollingTime < this.Clock.Now()) + { + return defaultPollingTime; + } + + return minPollingTime; + } + public void Dispose() { this.Dispose(true); diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index abfba82618..56cc0f0443 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -15,8 +15,8 @@ // using System; -using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Threading; using OpenTelemetry.Resources; using OpenTelemetry.Trace; @@ -31,6 +31,51 @@ public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Stat this.Rule = rule; this.RuleName = this.Rule.RuleName; this.Statistics = statistics ?? new Statistics(); + + if (rule.ReservoirSize > 0) + { + // Until calling GetSamplingTargets, the default is to borrow 1/s if reservoir size is + // positive. + this.ReservoirSampler = new ParentBasedSampler(new RateLimitingSampler(1, this.Clock)); + this.Borrowing = true; + } + else + { + // No reservoir sampling, we will always use the fixed rate. + this.ReservoirSampler = new AlwaysOffSampler(); + this.Borrowing = false; + } + + this.FixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(rule.FixedRate)); + + // We either have no reservoir sampling or borrow until we get a quota so have no end time. + this.ReservoirEndTime = DateTime.MaxValue; + + // We don't have a SamplingTarget so are ready to report a snapshot right away. + this.NextSnapshotTime = this.Clock.Now(); + } + + private SamplingRuleApplier( + string clientId, + SamplingRule rule, + Clock clock, + Trace.Sampler reservoirSampler, + Trace.Sampler fixedRateSampler, + bool borrowing, + Statistics statistics, + DateTime reservoirEndTime, + DateTime nextSnapshotTime) + { + this.ClientId = clientId; + this.Rule = rule; + this.RuleName = rule.RuleName; + this.Clock = clock; + this.ReservoirSampler = reservoirSampler; + this.FixedRateSampler = fixedRateSampler; + this.Borrowing = borrowing; + this.Statistics = statistics; + this.ReservoirEndTime = reservoirEndTime; + this.NextSnapshotTime = nextSnapshotTime; } internal string ClientId { get; set; } @@ -43,6 +88,16 @@ public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Stat internal Statistics Statistics { get; set; } + internal Trace.Sampler ReservoirSampler { get; set; } + + internal Trace.Sampler FixedRateSampler { get; set; } + + internal bool Borrowing { get; set; } + + internal DateTime ReservoirEndTime { get; set; } + + internal DateTime NextSnapshotTime { get; set; } + // check if this rule applier matches the request public bool Matches(SamplingParameters samplingParameters, Resource resource) { @@ -107,12 +162,91 @@ public bool Matches(SamplingParameters samplingParameters, Resource resource) Matcher.WildcardMatch(GetArn(in samplingParameters, resource), this.Rule.ResourceArn); } - [SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "method work in progress")] public SamplingResult ShouldSample(in SamplingParameters samplingParameters) { - // for now return drop sampling result. - // TODO: use reservoir and fixed rate sampler - return new SamplingResult(false); + Interlocked.Increment(ref this.Statistics.RequestCount); + bool reservoirExpired = this.Clock.Now() >= this.ReservoirEndTime; + SamplingResult result = !reservoirExpired + ? this.ReservoirSampler.ShouldSample(in samplingParameters) + : new SamplingResult(SamplingDecision.Drop); + + if (result.Decision != SamplingDecision.Drop) + { + if (this.Borrowing) + { + Interlocked.Increment(ref this.Statistics.BorrowCount); + } + + Interlocked.Increment(ref this.Statistics.SampleCount); + + return result; + } + + result = this.FixedRateSampler.ShouldSample(samplingParameters); + if (result.Decision != SamplingDecision.Drop) + { + Interlocked.Increment(ref this.Statistics.SampleCount); + } + + return result; + } + + // take the snapshot and reset the statistics. + public SamplingStatisticsDocument Snapshot(DateTime now) + { + double timestamp = this.Clock.ToDouble(now); + + long matchedRequests = Interlocked.Exchange(ref this.Statistics.RequestCount, 0L); + long sampledRequests = Interlocked.Exchange(ref this.Statistics.SampleCount, 0L); + long borrowedRequests = Interlocked.Exchange(ref this.Statistics.BorrowCount, 0L); + + SamplingStatisticsDocument statiscticsDocument = new SamplingStatisticsDocument( + this.ClientId, + this.RuleName, + matchedRequests, + sampledRequests, + borrowedRequests, + timestamp); + + return statiscticsDocument; + } + + public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTime now) + { + Trace.Sampler newFixedRateSampler = target.FixedRate != null + ? new ParentBasedSampler(new TraceIdRatioBasedSampler(target.FixedRate.Value)) + : this.FixedRateSampler; + + Trace.Sampler newReservoirSampler = new AlwaysOffSampler(); + DateTime newReservoirEndTime = DateTime.MaxValue; + if (target.ReservoirQuota != null && target.ReservoirQuotaTTL != null) + { + if (target.ReservoirQuota > 0) + { + newReservoirSampler = new ParentBasedSampler(new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock)); + } + else + { + newReservoirSampler = new AlwaysOffSampler(); + } + + newReservoirEndTime = this.Clock.ToDateTime(target.ReservoirQuotaTTL.Value); + } + + DateTime newNextSnapshotTime = target.Interval != null + ? now.AddSeconds(target.Interval.Value) + : now.Add(AWSXRayRemoteSampler.DefaultTargetInterval); + + return new SamplingRuleApplier( + this.ClientId, + this.Rule, + this.Clock, + newReservoirSampler, + newFixedRateSampler, + false, // no need for borrow + this.Statistics, + newReservoirEndTime, + newNextSnapshotTime); } private static string GetServiceType(Resource resource) diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs b/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs new file mode 100644 index 0000000000..f452808e95 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs @@ -0,0 +1,50 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class SamplingStatisticsDocument +{ + public SamplingStatisticsDocument(string clientID, string ruleName, long requestCount, long sampledCount, long borrowCount, double timestamp) + { + this.ClientID = clientID; + this.RuleName = ruleName; + this.RequestCount = requestCount; + this.SampledCount = sampledCount; + this.BorrowCount = borrowCount; + this.Timestamp = timestamp; + } + + [JsonPropertyName("ClientID")] + public string ClientID { get; set; } + + [JsonPropertyName("RuleName")] + public string RuleName { get; set; } + + [JsonPropertyName("RequestCount")] + public long RequestCount { get; set; } + + [JsonPropertyName("SampledCount")] + public long SampledCount { get; set; } + + [JsonPropertyName("BorrowCount")] + public long BorrowCount { get; set; } + + [JsonPropertyName("Timestamp")] + public double Timestamp { get; set; } +} diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs b/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs new file mode 100644 index 0000000000..3fa7091b73 --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs @@ -0,0 +1,37 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class SamplingTargetDocument +{ + [JsonPropertyName("FixedRate")] + public double? FixedRate { get; set; } + + [JsonPropertyName("Interval")] + public long? Interval { get; set; } + + [JsonPropertyName("ReservoirQuota")] + public long? ReservoirQuota { get; set; } + + [JsonPropertyName("ReservoirQuotaTTL")] + public double? ReservoirQuotaTTL { get; set; } + + [JsonPropertyName("RuleName")] + public string? RuleName { get; set; } +} diff --git a/src/OpenTelemetry.Sampler.AWS/Statistics.cs b/src/OpenTelemetry.Sampler.AWS/Statistics.cs index 9b790eb0e8..e278aab772 100644 --- a/src/OpenTelemetry.Sampler.AWS/Statistics.cs +++ b/src/OpenTelemetry.Sampler.AWS/Statistics.cs @@ -18,9 +18,7 @@ namespace OpenTelemetry.Sampler.AWS; internal class Statistics { - public int RequestCount { get; internal set; } - - public int BorrowCount { get; internal set; } - - public int SampleCount { get; internal set; } + public long RequestCount; + public long BorrowCount; + public long SampleCount; } diff --git a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs index d2ec6eb090..4f23ae6704 100644 --- a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs +++ b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs @@ -15,7 +15,6 @@ // using System; -using System.Diagnostics; namespace OpenTelemetry.Sampler.AWS; @@ -40,12 +39,9 @@ public override DateTime Now() return DateTime.UtcNow; } - public override long NowInSeconds() + public override long NowInMilliSeconds() { - double ts = Stopwatch.GetTimestamp(); - double s = ts / Stopwatch.Frequency; - - return (long)s; + return (long)this.Now().ToUniversalTime().Subtract(EpochStart).TotalMilliseconds; } public override DateTime ToDateTime(double seconds) diff --git a/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs b/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs new file mode 100644 index 0000000000..9b03449b2f --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +internal class UnprocessedStatistic +{ + public UnprocessedStatistic(string? errorCode, string? message, string? ruleName) + { + this.ErrorCode = errorCode; + this.Message = message; + this.RuleName = ruleName; + } + + [JsonPropertyName("ErrorCode")] + public string? ErrorCode { get; set; } + + [JsonPropertyName("Message")] + public string? Message { get; set; } + + [JsonPropertyName("RuleName")] + public string? RuleName { get; set; } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponseOptionalFields.json b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponseOptionalFields.json new file mode 100644 index 0000000000..c0b9813c11 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingRulesResponseOptionalFields.json @@ -0,0 +1,42 @@ +{ + "SamplingRuleRecords": [ + { + "SamplingRule": { + "RuleName": "Test", + "RuleARN": "arn:aws:xray:us-east-1:123456789000:sampling-rule/Test", + "ResourceARN": "*", + "Priority": 1, + "FixedRate": 0.0, + "ReservoirSize": 0, + "ServiceName": "*", + "ServiceType": "*", + "Host": "*", + "HTTPMethod": "*", + "URLPath": "*", + "Version": 1, + "Attributes": { "test": "cat-service" } + }, + "CreatedAt": 1.67799933E9, + "ModifiedAt": 1.67799933E9 + }, + { + "SamplingRule": { + "RuleName": "Default", + "RuleARN": "arn:aws:xray:us-east-1:123456789000:sampling-rule/Default", + "ResourceARN": "*", + "Priority": 10000, + "FixedRate": 0.0, + "ReservoirSize": 1, + "ServiceName": "*", + "ServiceType": "*", + "Host": "*", + "HTTPMethod": "*", + "URLPath": "*", + "Version": 1, + "Attributes": {} + }, + "CreatedAt": 0.0, + "ModifiedAt": 1.681856516E9 + } + ] +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponse.json b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponse.json new file mode 100644 index 0000000000..0293d57330 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponse.json @@ -0,0 +1,23 @@ +{ + "SamplingTargetDocuments": [ + { + "RuleName": "rule1", + "FixedRate": 0.1, + "ReservoirQuota": 2, + "ReservoirQuotaTTL": 1530923107.0, + "Interval": 10 + }, + { + "RuleName": "rule3", + "FixedRate": 0.003 + } + ], + "LastRuleModification": 1530920505.0, + "UnprocessedStatistics": [ + { + "RuleName": "rule2", + "ErrorCode": "400", + "Message": "Unknown rule" + } + ] +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponseOptionalFields.json b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponseOptionalFields.json new file mode 100644 index 0000000000..b7ca420ecd --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Data/GetSamplingTargetsResponseOptionalFields.json @@ -0,0 +1,16 @@ +{ + "SamplingTargetDocuments": [ + { + "RuleName": "Test", + "FixedRate": 1.0 + } + ], + "LastRuleModification": 1530920505.0, + "UnprocessedStatistics": [ + { + "RuleName": "Default", + "ErrorCode": "400", + "Message": "Unknown rule" + } + ] +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index bb8099097e..e0fb3a51f5 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -21,9 +21,10 @@ - - PreserveNewest - + + + + diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index 5cff06fa5f..ce59cad264 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -16,8 +16,14 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Threading; using OpenTelemetry.Resources; using OpenTelemetry.Trace; +using WireMock.RequestBuilders; +using WireMock.ResponseBuilders; +using WireMock.Server; using Xunit; namespace OpenTelemetry.Sampler.AWS.Tests; @@ -53,13 +59,71 @@ public void TestSamplerWithDefaults() } [Fact] - public void TestSamplerShouldSample() + public void TestSamplerUpdateAndSample() { - Trace.Sampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); + // setup mock server + TestClock clock = new TestClock(); + WireMockServer mockServer = WireMockServer.Start(); - // for now the fallback sampler should be making the sampling decision - Assert.Equal( - SamplingDecision.RecordAndSample, - sampler.ShouldSample(Utils.CreateSamplingParametersWithTags(new Dictionary())).Decision); + // create sampler + AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) + .SetPollingInterval(TimeSpan.FromMilliseconds(10)) + .SetEndpoint(mockServer.Url) + .SetClock(clock) + .Build(); + + // the sampler will use fallback sampler until rules are fetched. + Assert.Equal(SamplingDecision.RecordAndSample, this.DoSample(sampler, "cat-service")); + Assert.Equal(SamplingDecision.Drop, this.DoSample(sampler, "cat-service")); + + // GetSamplingRules mock response + mockServer + .Given(Request.Create().WithPath("/GetSamplingRules").UsingPost()) + .RespondWith( + Response.Create() + .WithStatusCode(200) + .WithHeader("Content-Type", "application/json") + .WithBody(File.ReadAllText("Data/GetSamplingRulesResponseOptionalFields.json"))); + + // rules will be polled in 10 milliseconds + Thread.Sleep(2000); + + // sampler will drop because rule has 0 reservoir and 0 fixed rate + Assert.Equal(SamplingDecision.Drop, this.DoSample(sampler, "cat-service")); + + // GetSamplingTargets mock response + mockServer + .Given(Request.Create().WithPath("/SamplingTargets").UsingPost()) + .RespondWith( + Response.Create() + .WithStatusCode(200) + .WithHeader("Content-Type", "application/json") + .WithBody(File.ReadAllText("Data/GetSamplingTargetsResponseOptionalFields.json"))); + + // targets will be polled in 10 seconds + Thread.Sleep(13000); + + // sampler will always sampler since target has 100% fixed rate + Assert.Equal(SamplingDecision.RecordAndSample, this.DoSample(sampler, "cat-service")); + Assert.Equal(SamplingDecision.RecordAndSample, this.DoSample(sampler, "cat-service")); + Assert.Equal(SamplingDecision.RecordAndSample, this.DoSample(sampler, "cat-service")); + + mockServer.Stop(); + } + + private SamplingDecision DoSample(Trace.Sampler sampler, string serviceName) + { + var samplingParams = new SamplingParameters( + default, + ActivityTraceId.CreateRandom(), + "myActivityName", + ActivityKind.Server, + new List>() + { + new KeyValuePair("test", serviceName), + }, + null); + + return sampler.ShouldSample(samplingParams).Decision; } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs index 2b9863c1f8..fa78d9a108 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -109,6 +109,91 @@ public void TestGetSamplingRulesMalformed() Assert.Empty(rules); } + [Fact] + public void TestGetSamplingTargets() + { + TestClock clock = new TestClock(); + + this.CreateResponse("/SamplingTargets", "Data/GetSamplingTargetsResponse.json"); + + var request = new GetSamplingTargetsRequest(new List() + { + new SamplingStatisticsDocument( + "clientId", + "rule1", + 100, + 50, + 10, + clock.ToDouble(clock.Now())), + new SamplingStatisticsDocument( + "clientId", + "rule2", + 200, + 100, + 20, + clock.ToDouble(clock.Now())), + new SamplingStatisticsDocument( + "clientId", + "rule3", + 20, + 10, + 2, + clock.ToDouble(clock.Now())), + }); + + var responseTask = this.client.GetSamplingTargets(request); + responseTask.Wait(); + + GetSamplingTargetsResponse targetsResponse = responseTask.Result; + + Assert.Equal(2, targetsResponse.SamplingTargetDocuments.Count); + Assert.Single(targetsResponse.UnprocessedStatistics); + + Assert.Equal("rule1", targetsResponse.SamplingTargetDocuments[0].RuleName); + Assert.Equal(0.1, targetsResponse.SamplingTargetDocuments[0].FixedRate); + Assert.Equal(2, targetsResponse.SamplingTargetDocuments[0].ReservoirQuota); + Assert.Equal(1530923107.0, targetsResponse.SamplingTargetDocuments[0].ReservoirQuotaTTL); + Assert.Equal(10, targetsResponse.SamplingTargetDocuments[0].Interval); + + Assert.Equal("rule3", targetsResponse.SamplingTargetDocuments[1].RuleName); + Assert.Equal(0.003, targetsResponse.SamplingTargetDocuments[1].FixedRate); + Assert.Null(targetsResponse.SamplingTargetDocuments[1].ReservoirQuota); + Assert.Null(targetsResponse.SamplingTargetDocuments[1].ReservoirQuotaTTL); + Assert.Null(targetsResponse.SamplingTargetDocuments[1].Interval); + + Assert.Equal("rule2", targetsResponse.UnprocessedStatistics[0].RuleName); + Assert.Equal("400", targetsResponse.UnprocessedStatistics[0].ErrorCode); + Assert.Equal("Unknown rule", targetsResponse.UnprocessedStatistics[0].Message); + } + + [Fact] + public void TestGetSamplingTargetsWithMalformed() + { + TestClock clock = new TestClock(); + this.mockServer + .Given(Request.Create().WithPath("/SamplingTargets").UsingPost()) + .RespondWith( + Response.Create().WithStatusCode(200).WithHeader("Content-Type", "application/json").WithBody("notJson")); + + var request = new GetSamplingTargetsRequest(new List() + { + new SamplingStatisticsDocument( + "clientId", + "rule1", + 100, + 50, + 10, + clock.ToDouble(clock.Now())), + }); + + var responseTask = this.client.GetSamplingTargets(request); + responseTask.Wait(); + + GetSamplingTargetsResponse targetsResponse = responseTask.Result; + + Assert.Null(targetsResponse); + } + private void CreateResponse(string endpoint, string filePath) { string mockResponse = File.ReadAllText(filePath); diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index a5be1d33df..2de7500de5 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -24,6 +25,7 @@ namespace OpenTelemetry.Sampler.AWS.Tests; internal class TestClock : Clock { + private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private DateTime nowTime; public TestClock() @@ -41,19 +43,21 @@ public override DateTime Now() return this.nowTime; } - public override long NowInSeconds() + public override long NowInMilliSeconds() { - throw new NotImplementedException(); + return (long)this.nowTime.ToUniversalTime().Subtract(EpochStart).TotalMilliseconds; } public override DateTime ToDateTime(double seconds) { - throw new NotImplementedException(); + return EpochStart.AddSeconds(seconds); } public override double ToDouble(DateTime dateTime) { - throw new NotImplementedException(); + TimeSpan current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); + double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; + return timestamp; } // Advnaces the clock by a given time span. diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs new file mode 100644 index 0000000000..4ac5fb4aa9 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs @@ -0,0 +1,163 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +/// +/// This class is a .Net port of the original Java implementation. +/// This class was taken from Jaeger java client. +/// https://github.com/jaegertracing/jaeger-client-java/blob/master/jaeger-core/src/test/java/io/jaegertracing/internal/utils/RateLimiterTest.java +/// +public class TestRateLimiter +{ + [Fact] + public void TestRateLimiterWholeNumber() + { + var testClock = new TestClock(); + RateLimiter limiter = new RateLimiter(2.0, 2.0, testClock); + + Assert.True(limiter.TrySpend(1.0)); + Assert.True(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + + // move time 250ms forward, not enough credits to pay for 1.0 item + testClock.Advance(TimeSpan.FromMilliseconds(250)); + Assert.False(limiter.TrySpend(1.0)); + + // move time 500ms forward, now enough credits to pay for 1.0 item + testClock.Advance(TimeSpan.FromMilliseconds(500)); + Assert.True(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + + // move time 5s forward, enough to accumulate credits for 10 messages, but it should still be + // capped at 2 + testClock.Advance(TimeSpan.FromSeconds(5)); + Assert.True(limiter.TrySpend(1.0)); + Assert.True(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + } + + [Fact] + public void TestRateLimiterLessThanOne() + { + TestClock clock = new TestClock(); + RateLimiter limiter = new RateLimiter(0.5, 0.5, clock); + + Assert.True(limiter.TrySpend(0.25)); + Assert.True(limiter.TrySpend(0.25)); + Assert.False(limiter.TrySpend(0.25)); + + // move time 250ms forward, not enough credits to pay for 0.25 item + clock.Advance(TimeSpan.FromMilliseconds(250)); + Assert.False(limiter.TrySpend(0.25)); + + // move clock 500ms forward, enough credits for 0.25 item + clock.Advance(TimeSpan.FromMilliseconds(500)); + Assert.True(limiter.TrySpend(0.25)); + + // move time 5s forward, enough to accumulate credits for 2.5 messages, but it should still be + // capped at 0.5 + clock.Advance(TimeSpan.FromSeconds(5)); + Assert.True(limiter.TrySpend(0.25)); + Assert.True(limiter.TrySpend(0.25)); + Assert.False(limiter.TrySpend(0.25)); + Assert.False(limiter.TrySpend(0.25)); + Assert.False(limiter.TrySpend(0.25)); + } + + [Fact] + public void TestRateLimiterMaxBalance() + { + TestClock clock = new TestClock(); + RateLimiter limiter = new RateLimiter(0.1, 1.0, clock); + + clock.Advance(TimeSpan.FromMilliseconds(0.1)); + Assert.True(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + + // move time 20s forward, enough to accumulate credits for 2 messages, but it should still be + // capped at 1 + clock.Advance(TimeSpan.FromSeconds(20)); + + Assert.True(limiter.TrySpend(1.0)); + Assert.False(limiter.TrySpend(1.0)); + } + + [Fact] + public void TestRateLimiterInitial() + { + TestClock clock = new TestClock(); + RateLimiter limiter = new RateLimiter(1000, 100, clock); + + Assert.True(limiter.TrySpend(100)); // consume initial (max) balance + Assert.False(limiter.TrySpend(1)); + + clock.Advance(TimeSpan.FromMilliseconds(49)); // add 49 credits + Assert.False(limiter.TrySpend(50)); + + clock.Advance(TimeSpan.FromMilliseconds(1)); // add 1 credit + Assert.True(limiter.TrySpend(50)); // consume accrued balance + Assert.False(limiter.TrySpend(1)); + + clock.Advance(TimeSpan.FromSeconds(1000)); // add a lot of credits (max out balance) + Assert.True(limiter.TrySpend(1)); // take 1 credit + + clock.Advance(TimeSpan.FromSeconds(1000)); // add a lot of credits (max out balance) + Assert.False(limiter.TrySpend(101)); // can't consume more than max balance + Assert.True(limiter.TrySpend(100)); // consume max balance + Assert.False(limiter.TrySpend(1)); + } + + [Fact] + public async Task TestRateLimiterConcurrencyAsync() + { + int numWorkers = 8; + int creditsPerWorker = 1000; + TestClock clock = new TestClock(); + RateLimiter limiter = new RateLimiter(1, numWorkers * creditsPerWorker, clock); + int count = 0; + List tasks = new List(numWorkers); + + for (int w = 0; w < numWorkers; ++w) + { + Task task = Task.Run(() => + { + for (int i = 0; i < creditsPerWorker * 2; ++i) + { + if (limiter.TrySpend(1)) + { + Interlocked.Increment(ref count); // count allowed operations + } + } + }); + + tasks.Add(task); + } + + await Task.WhenAll(tasks); + + Assert.Equal(numWorkers * creditsPerWorker, count); + Assert.False(limiter.TrySpend(1)); + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs new file mode 100644 index 0000000000..9335667956 --- /dev/null +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Sampler.AWS.Tests; + +public class TestRateLimitingSampler +{ + [Fact] + public void TestLimitsRate() + { + TestClock clock = new TestClock(); + Trace.Sampler sampler = new RateLimitingSampler(1, clock); + + Assert.Equal(SamplingDecision.RecordAndSample, sampler.ShouldSample(Utils.CreateSamplingParameters()).Decision); + + // balance used up + Assert.Equal(SamplingDecision.Drop, sampler.ShouldSample(Utils.CreateSamplingParameters()).Decision); + + // balance restore after 1 second, not yet + clock.Advance(TimeSpan.FromMilliseconds(100)); + Assert.Equal(SamplingDecision.Drop, sampler.ShouldSample(Utils.CreateSamplingParameters()).Decision); + + // balance restored + clock.Advance(TimeSpan.FromMilliseconds(900)); + Assert.Equal(SamplingDecision.RecordAndSample, sampler.ShouldSample(Utils.CreateSamplingParameters()).Decision); + } +} diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs index 57391ce932..eafc974c00 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs @@ -97,7 +97,137 @@ public void TestUpdateRulesRemovesOlderRule() Assert.Equal("Default", rulesCache.RuleAppliers[0].RuleName); } - // TODO: Add tests for matching sampling rules once the reservoir and fixed rate samplers are added. + [Fact] + public void TestShouldSampleMatchesExactRule() + { + var clock = new TestClock(); + var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) + { + RuleAppliers = new List() + { + { new SamplingRuleApplier("clientId", clock, this.CreateRule("ruleWillMatch", 1, 0.0, 1), new Statistics()) }, // higher priority rule will sample + { new SamplingRuleApplier("clientId", clock, this.CreateRule("ruleWillNotMatch", 0, 0.0, 2), new Statistics()) }, // this rule will not sample + }, + }; + + // the rule will sample by borrowing from reservoir + Assert.Equal(SamplingDecision.RecordAndSample, rulesCache.ShouldSample(default).Decision); + + var statistics = rulesCache.Snapshot(clock.Now()); + Assert.Equal(2, statistics.Count); + Assert.Equal("ruleWillMatch", statistics[0].RuleName); + Assert.Equal(1, statistics[0].RequestCount); + Assert.Equal(1, statistics[0].SampledCount); + Assert.Equal(1, statistics[0].BorrowCount); + Assert.Equal("ruleWillNotMatch", statistics[1].RuleName); + Assert.Equal(0, statistics[1].RequestCount); + Assert.Equal(0, statistics[1].SampledCount); + Assert.Equal(0, statistics[1].BorrowCount); + } + + [Fact] + public void TestFallbackSamplerMatchesWhenNoRules() + { + var clock = new TestClock(); + var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) + { + RuleAppliers = new List(), + }; + + // the fallback sampler will not sample + Assert.Equal(SamplingDecision.Drop, rulesCache.ShouldSample(default).Decision); + } + + [Fact] + public void TestUpdateTargets() + { + var clock = new TestClock(); + var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) + { + RuleAppliers = new List() + { + { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule1", 1, 0.0, 1), new Statistics()) }, // this rule will sample 1 req/sec + { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule2", 0, 0.0, 2), new Statistics()) }, + }, + }; + + Assert.Equal(SamplingDecision.RecordAndSample, rulesCache.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, rulesCache.ShouldSample(default).Decision); + + // update targets + var targetForRule1 = new SamplingTargetDocument() + { + FixedRate = 0.0, + Interval = 0, + ReservoirQuota = 2, + ReservoirQuotaTTL = clock.ToDouble(clock.Now().AddMinutes(5)), + RuleName = "rule1", + }; + var targetForRule2 = new SamplingTargetDocument() + { + FixedRate = 0.0, + Interval = 0, + ReservoirQuota = 0, + ReservoirQuotaTTL = clock.ToDouble(clock.Now().AddMinutes(5)), + RuleName = "rule2", + }; + + var targets = new Dictionary() + { + { "rule1", targetForRule1 }, + { "rule2", targetForRule2 }, + }; + + rulesCache.UpdateTargets(targets); + + // now rule1 will sample 2 req/sec + Assert.Equal(SamplingDecision.RecordAndSample, rulesCache.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.RecordAndSample, rulesCache.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, rulesCache.ShouldSample(default).Decision); + } + + [Fact] + public void TestNextTargetFetchTime() + { + var clock = new TestClock(); + var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) + { + RuleAppliers = new List() + { + { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule1", 1, 0.0, 1), new Statistics()) }, + { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule2", 0, 0.0, 2), new Statistics()) }, + }, + }; + + // update targets + var targetForRule1 = new SamplingTargetDocument() + { + FixedRate = 0.0, + Interval = 10, // next target poll after 10s + ReservoirQuota = 2, + ReservoirQuotaTTL = clock.ToDouble(clock.Now().Add(TimeSpan.FromMinutes(5))), + RuleName = "rule1", + }; + var targetForRule2 = new SamplingTargetDocument() + { + FixedRate = 0.0, + Interval = 5, // next target poll after 5s + ReservoirQuota = 0, + ReservoirQuotaTTL = clock.ToDouble(clock.Now().Add(TimeSpan.FromMinutes(5))), + RuleName = "rule2", + }; + + var targets = new Dictionary() + { + { "rule1", targetForRule1 }, + { "rule2", targetForRule2 }, + }; + + rulesCache.UpdateTargets(targets); + + // next target will be fetched after 5s + Assert.Equal(clock.Now().AddSeconds(5), rulesCache.NextTargetFetchTime()); + } private SamplingRule CreateDefaultRule(int reservoirSize, double fixedRate) { diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs index b62fc93c41..34ae66df43 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -14,7 +14,9 @@ // limitations under the License. // +using System; using System.Collections.Generic; +using OpenTelemetry.Trace; using Xunit; namespace OpenTelemetry.Sampler.AWS.Tests; @@ -217,5 +219,207 @@ public void TestAttributeMatchingWithLessActivityTags() Assert.False(applier.Matches(Utils.CreateSamplingParametersWithTags(activityTags), Utils.CreateResource("myServiceName", "aws_ecs"))); } - // TODO: Add more test cases for ShouldSample once the sampling logic is added. + // fixed rate is 1.0 and reservoir is 0 + [Fact] + public void TestFixedRateAlwaysSample() + { + TestClock clock = new TestClock(); + SamplingRule rule = new SamplingRule( + "rule1", + 1, + 1.0, // fixed rate + 0, // reservoir + "*", + "*", + "*", + "*", + "*", + "*", + 1, + new Dictionary()); + + var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); + + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + + // test if the snapshot was correctly captured + var statistics = applier.Snapshot(clock.Now()); + Assert.Equal("clientId", statistics.ClientID); + Assert.Equal("rule1", statistics.RuleName); + Assert.Equal(clock.ToDouble(clock.Now()), statistics.Timestamp); + Assert.Equal(1, statistics.RequestCount); + Assert.Equal(1, statistics.SampledCount); + Assert.Equal(0, statistics.BorrowCount); + + // reset statistics + statistics = applier.Snapshot(clock.Now()); + Assert.Equal(0, statistics.RequestCount); + Assert.Equal(0, statistics.SampledCount); + Assert.Equal(0, statistics.BorrowCount); + } + + // fixed rate is 0.0 and reservoir is 0 + [Fact] + public void TestFixedRateNeverSample() + { + TestClock clock = new TestClock(); + SamplingRule rule = new SamplingRule( + "rule1", + 1, + 0.0, // fixed rate + 0, // reservoir + "*", + "*", + "*", + "*", + "*", + "*", + 1, + new Dictionary()); + + var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); + + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + + // test if the snapshot was correctly captured + var statistics = applier.Snapshot(clock.Now()); + Assert.Equal("clientId", statistics.ClientID); + Assert.Equal("rule1", statistics.RuleName); + Assert.Equal(clock.ToDouble(clock.Now()), statistics.Timestamp); + Assert.Equal(1, statistics.RequestCount); + Assert.Equal(0, statistics.SampledCount); + Assert.Equal(0, statistics.BorrowCount); + } + + [Fact] + public void TestBorrowFromReservoir() + { + TestClock clock = new TestClock(); + SamplingRule rule = new SamplingRule( + "rule1", + 1, + 0.0, // fixed rate + 100, // reservoir + "*", + "*", + "*", + "*", + "*", + "*", + 1, + new Dictionary()); + + var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); + + // sampled by borrowing + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + + // can only borrow 1 req/sec + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + + // test if the snapshot was correctly captured + var statistics = applier.Snapshot(clock.Now()); + Assert.Equal("clientId", statistics.ClientID); + Assert.Equal("rule1", statistics.RuleName); + Assert.Equal(clock.ToDouble(clock.Now()), statistics.Timestamp); + Assert.Equal(2, statistics.RequestCount); + Assert.Equal(1, statistics.SampledCount); + Assert.Equal(1, statistics.BorrowCount); + } + + [Fact] + public void TestWithTarget() + { + TestClock clock = new TestClock(); + SamplingRule rule = new SamplingRule( + "rule1", + 1, + 0.0, // fixed rate + 100, // reservoir + "*", + "*", + "*", + "*", + "*", + "*", + 1, + new Dictionary()); + + var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); + + // no target assigned yet. so borrow 1 from reseroir every second + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + clock.Advance(TimeSpan.FromSeconds(1)); + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + + // get the target + SamplingTargetDocument target = new SamplingTargetDocument() + { + FixedRate = 0.0, + Interval = 10, + ReservoirQuota = 2, + ReservoirQuotaTTL = clock.ToDouble(clock.Now().Add(TimeSpan.FromSeconds(10))), + RuleName = "rule1", + }; + + applier = applier.WithTarget(target, clock.Now()); + + // 2 req/sec quota + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + } + + [Fact] + public void TestWithTargetWithoutQuota() + { + TestClock clock = new TestClock(); + SamplingRule rule = new SamplingRule( + "rule1", + 1, + 0.0, // fixed rate + 100, // reservoir + "*", + "*", + "*", + "*", + "*", + "*", + 1, + new Dictionary()); + + var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); + + // no target assigned yet. so borrow 1 from reseroir every second + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + clock.Advance(TimeSpan.FromSeconds(1)); + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); + + var statistics = applier.Snapshot(clock.Now()); + Assert.Equal(4, statistics.RequestCount); + Assert.Equal(2, statistics.SampledCount); + Assert.Equal(2, statistics.BorrowCount); + + // get the target + SamplingTargetDocument target = new SamplingTargetDocument() + { + FixedRate = 1.0, + Interval = 10, + ReservoirQuota = null, + ReservoirQuotaTTL = null, + RuleName = "rule1", + }; + applier = applier.WithTarget(target, clock.Now()); + + // no reservoir, sample using fixed rate (100% sample) + Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); + statistics = applier.Snapshot(clock.Now()); + Assert.Equal(1, statistics.RequestCount); + Assert.Equal(1, statistics.SampledCount); + Assert.Equal(0, statistics.BorrowCount); + } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs index d5a1babd46..b415200872 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs @@ -23,6 +23,22 @@ namespace OpenTelemetry.Sampler.AWS.Tests; internal static class Utils { + internal static SamplingParameters CreateSamplingParameters() + { + return CreateSamplingParametersWithTags(new Dictionary()); + } + + internal static SamplingParameters CreateSamplingParametersWithRootContext() + { + return new SamplingParameters( + default, + ActivityTraceId.CreateRandom(), + "myActivityName", + ActivityKind.Server, + null, + null); + } + internal static SamplingParameters CreateSamplingParametersWithTags(Dictionary tags) { ActivityTraceId traceId = ActivityTraceId.CreateRandom(); From 9fab3ed0b212b092c3b4dfafb748a35516dcbc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 31 May 2023 00:14:54 +0200 Subject: [PATCH 0715/1499] [ResourceDetectors.AWS] Release as .NET 6 instead of NET Standard 2.0 (#1177) --- .../PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../AWSECSResourceDetector.cs | 6 +- .../AWSEKSResourceDetector.cs | 9 ++- .../Http/Handler.cs | 14 ++-- .../ServerCertificateValidationProvider.cs | 55 +++++++------- ...OpenTelemetry.ResourceDetectors.AWS.csproj | 12 +-- ...erverCertificateValidationProviderTests.cs | 76 +++++++++++-------- ...lemetry.ResourceDetectors.AWS.Tests.csproj | 1 + 9 files changed, 92 insertions(+), 81 deletions(-) rename src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index b7de0f6e82..5e59597d3e 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -14,6 +14,7 @@ // limitations under the License. // +#if !NETFRAMEWORK using System; using System.Collections.Generic; using System.Net.Http; @@ -195,8 +196,8 @@ internal static List> ExtractMetadataV4ResourceAttr { while (!streamReader.EndOfStream) { - var trimmedLine = streamReader.ReadLine().Trim(); - if (trimmedLine.Length > 64) + var trimmedLine = streamReader.ReadLine()?.Trim(); + if (trimmedLine?.Length > 64) { containerId = trimmedLine.Substring(trimmedLine.Length - 64); return containerId; @@ -212,3 +213,4 @@ internal static bool IsECSProcess() return Environment.GetEnvironmentVariable(AWSECSMetadataURLKey) != null || Environment.GetEnvironmentVariable(AWSECSMetadataURLV4Key) != null; } } +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs index 4f4faf4e77..81e3d6ba4c 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System; using System.Collections.Generic; using System.Net.Http; @@ -85,7 +87,7 @@ internal static List> ExtractResourceAttributes(str { while (!streamReader.EndOfStream) { - stringBuilder.Append(streamReader.ReadLine().Trim()); + stringBuilder.Append(streamReader.ReadLine()?.Trim()); } } @@ -109,8 +111,8 @@ internal static List> ExtractResourceAttributes(str { while (!streamReader.EndOfStream) { - var trimmedLine = streamReader.ReadLine().Trim(); - if (trimmedLine.Length > 64) + var trimmedLine = streamReader.ReadLine()?.Trim(); + if (trimmedLine?.Length > 64) { return trimmedLine.Substring(trimmedLine.Length - 64); } @@ -165,3 +167,4 @@ private static string GetEKSClusterInfo(string credentials, HttpClientHandler? h return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; } } +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs index 27b89b2e2b..0b2b1cf262 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System; using System.Net.Http; @@ -25,24 +27,19 @@ internal class Handler { try { - ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile); - if (!serverCertificateValidationProvider.IsCertificateLoaded ?? false) + if (serverCertificateValidationProvider == null) { AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); return null; } - if (serverCertificateValidationProvider.ValidationCallback == null) - { - return null; - } - var clientHandler = new HttpClientHandler(); clientHandler.ServerCertificateCustomValidationCallback = (sender, x509Certificate2, x509Chain, sslPolicyErrors) => - serverCertificateValidationProvider.ValidationCallback(null, x509Certificate2, x509Chain, sslPolicyErrors); + serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors); return clientHandler; } catch (Exception ex) @@ -53,3 +50,4 @@ internal class Handler return null; } } +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs index 5f26f4f064..535e67efda 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#if !NETFRAMEWORK + using System; using System.IO; using System.Linq; @@ -24,43 +26,30 @@ namespace OpenTelemetry.ResourceDetectors.AWS.Http; internal class ServerCertificateValidationProvider { - private static readonly ServerCertificateValidationProvider InvalidProvider = new(null); - - private readonly X509Certificate2Collection? trustedCertificates; + private readonly X509Certificate2Collection trustedCertificates; - private ServerCertificateValidationProvider(X509Certificate2Collection? trustedCertificates) + private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates) { - if (trustedCertificates == null) - { - this.trustedCertificates = null; - this.ValidationCallback = null; - this.IsCertificateLoaded = false; - return; - } - this.trustedCertificates = trustedCertificates; - this.ValidationCallback = (sender, cert, chain, errors) => - this.ValidateCertificate(new X509Certificate2(cert), chain, errors); - this.IsCertificateLoaded = true; + this.ValidationCallback = (_, cert, chain, errors) => + this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors); } - public bool? IsCertificateLoaded { get; } - - public RemoteCertificateValidationCallback? ValidationCallback { get; } + public RemoteCertificateValidationCallback ValidationCallback { get; } - public static ServerCertificateValidationProvider FromCertificateFile(string certificateFile) + public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile) { if (!File.Exists(certificateFile)) { AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); - return InvalidProvider; + return null; } var trustedCertificates = new X509Certificate2Collection(); if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile)) { AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); - return InvalidProvider; + return null; } return new ServerCertificateValidationProvider(trustedCertificates); @@ -90,7 +79,7 @@ private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collec { foreach (var certificate in collection) { - if (Enumerable.SequenceEqual(chainElement.Certificate.GetPublicKey(), certificate.GetPublicKey())) + if (chainElement.Certificate.GetPublicKey().SequenceEqual(certificate.GetPublicKey())) { return true; } @@ -100,7 +89,7 @@ private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collec return false; } - private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPolicyErrors errors) + private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors) { var isSslPolicyPassed = errors == SslPolicyErrors.None || errors == SslPolicyErrors.RemoteCertificateChainErrors; @@ -117,6 +106,18 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli } } + if (chain == null) + { + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null."); + return false; + } + + if (cert == null) + { + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null."); + return false; + } + chain.ChainPolicy.ExtraStore.AddRange(this.trustedCertificates); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; @@ -149,12 +150,9 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli } var trustCertificates = string.Empty; - if (this.trustedCertificates != null) + foreach (var trustCertificate in this.trustedCertificates) { - foreach (var trustCertificate in this.trustedCertificates) - { - trustCertificates += " " + trustCertificate.Subject; - } + trustCertificates += " " + trustCertificate.Subject; } AWSResourcesEventSource.Log.FailedToValidateCertificate( @@ -165,3 +163,4 @@ private bool ValidateCertificate(X509Certificate2 cert, X509Chain chain, SslPoli return isSslPolicyPassed && isValidChain && isTrusted; } } +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj index a4ec9726b9..c2278435cf 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -2,7 +2,7 @@ - netstandard2.0 + net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. ResourceDetectors.AWS- @@ -12,17 +12,9 @@ - - - - - - - - - + diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index 7f69902b6c..04da229c89 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -16,8 +16,8 @@ #if !NETFRAMEWORK -using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; +using Moq; using OpenTelemetry.ResourceDetectors.AWS.Http; using Xunit; @@ -25,46 +25,62 @@ namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; public class ServerCertificateValidationProviderTests { - private const string INVALIDCRTNAME = "invalidcert"; + private const string InvalidCertificateName = "invalidcert"; [Fact] public void TestValidCertificate() { - // This test fails on Linux in netcoreapp3.1, but passes in net6.0 and net7.0. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - using (CertificateUploader certificateUploader = new CertificateUploader()) - { - certificateUploader.Create(); - - // Loads the certificate to the trusted collection from the file - ServerCertificateValidationProvider serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); - - // Validates if the certificate loaded into the trusted collection. - Assert.True(serverCertificateValidationProvider.IsCertificateLoaded); - - var certificate = new X509Certificate2(certificateUploader.FilePath); - X509Chain chain = new X509Chain(); - chain.Build(certificate); - - // validates if certificate is valid - Assert.NotNull(serverCertificateValidationProvider); - Assert.NotNull(serverCertificateValidationProvider.ValidationCallback); - Assert.True(serverCertificateValidationProvider.ValidationCallback(null, certificate, chain, System.Net.Security.SslPolicyErrors.None)); - } - } + using CertificateUploader certificateUploader = new CertificateUploader(); + certificateUploader.Create(); + + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + + Assert.NotNull(serverCertificateValidationProvider); + + var certificate = new X509Certificate2(certificateUploader.FilePath); + X509Chain chain = new X509Chain(); + chain.Build(certificate); + + // validates if certificate is valid + Assert.NotNull(serverCertificateValidationProvider); + Assert.NotNull(serverCertificateValidationProvider.ValidationCallback); + Assert.True(serverCertificateValidationProvider.ValidationCallback(this, certificate, chain, System.Net.Security.SslPolicyErrors.None)); } [Fact] public void TestInValidCertificate() { - // Loads the certificate to the trusted collection from the file ServerCertificateValidationProvider serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(INVALIDCRTNAME); + ServerCertificateValidationProvider.FromCertificateFile(InvalidCertificateName); + + Assert.Null(serverCertificateValidationProvider); + } + + [Fact] + public void TestTestCallbackWithNullCertificate() + { + using var certificateUploader = new CertificateUploader(); + certificateUploader.Create(); + + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + + Assert.NotNull(serverCertificateValidationProvider); + Assert.False(serverCertificateValidationProvider.ValidationCallback(this, null, Mock.Of(), default)); + } + + [Fact] + public void TestCallbackWithNullChain() + { + using var certificateUploader = new CertificateUploader(); + certificateUploader.Create(); + + ServerCertificateValidationProvider serverCertificateValidationProvider = + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); - // Validates if the certificate file loaded. - Assert.False(serverCertificateValidationProvider.IsCertificateLoaded); + Assert.NotNull(serverCertificateValidationProvider); + Assert.False(serverCertificateValidationProvider.ValidationCallback(this, Mock.Of(), null, default)); } } diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj index 061f4214ac..12b3750bb0 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj @@ -10,6 +10,7 @@ + all From 81364e6cb3e5e1ec7301ecf0b73b3c465780475f Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Wed, 31 May 2023 12:17:15 +1000 Subject: [PATCH 0716/1499] add support for abstract domain sockets in OpenTelemetry.Exporter.Geneva (#1199) --- .../CHANGELOG.md | 2 ++ .../Internal/ConnectionStringBuilder.cs | 19 ++++++++++++++++++- .../ConnectionStringBuilderTests.cs | 5 +++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 0647e6f08a..29c213c717 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,8 @@ * TldLogExporter to export `SpanId` value in `ext_dt_spanId` field instead of `TraceId` value. ([#1184](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1184)) +* Add support for abstract domain sockets. + ([#1199](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1199)) ## 1.5.0-alpha.3 diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index d34d91f337..695f5496d6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -132,12 +132,29 @@ public TransportProtocol Protocol } } + /// + /// Replace first charater of string if it matches with with . + /// + /// String to be updated. + /// Old character to be replaced. + /// New character to be replaced with. + /// Updated string. + internal static string ReplaceFirstChar(string str, char oldChar, char newChar) + { + if (str.Length > 0 && str[0] == oldChar) + { + return $"{newChar}{str.Substring(1)}"; + } + + return str; + } + public string ParseUnixDomainSocketPath() { try { var endpoint = new Uri(this.Endpoint); - return endpoint.AbsolutePath; + return ReplaceFirstChar(endpoint.AbsolutePath, '@', '\0'); } catch (UriFormatException ex) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 35473e893e..01a7044a0a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -104,6 +104,11 @@ public void ConnectionStringBuilder_Endpoint_UnixDomainSocketPath() builder = new ConnectionStringBuilder("EtwSession=OpenTelemetry"); Assert.Throws(() => _ = builder.ParseUnixDomainSocketPath()); + + builder = new ConnectionStringBuilder("Endpoint=unix:@/var/run/default_fluent.socket"); + Assert.Equal("unix:@/var/run/default_fluent.socket", builder.Endpoint); + Assert.Equal(TransportProtocol.Unix, builder.Protocol); + Assert.Equal("\0/var/run/default_fluent.socket", builder.ParseUnixDomainSocketPath()); } [Fact] From eb2b6b020456217fb2765e2b70732cfa3bf3859d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 31 May 2023 10:17:46 -0700 Subject: [PATCH 0717/1499] [Sampler.AWS] Fix unit test (#1213) --- test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index ce59cad264..5e9766163e 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -74,7 +74,6 @@ public void TestSamplerUpdateAndSample() // the sampler will use fallback sampler until rules are fetched. Assert.Equal(SamplingDecision.RecordAndSample, this.DoSample(sampler, "cat-service")); - Assert.Equal(SamplingDecision.Drop, this.DoSample(sampler, "cat-service")); // GetSamplingRules mock response mockServer From 65179351177e457b8b83be3bdd0b0e9a5751ca11 Mon Sep 17 00:00:00 2001 From: Christopher Warrington Date: Fri, 2 Jun 2023 10:14:20 -0700 Subject: [PATCH 0718/1499] [Geneva.Logs] Refine CustomFields documentation (#1216) --- src/OpenTelemetry.Exporter.Geneva/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 0faf04b64a..ebd5b8dce6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -95,6 +95,9 @@ On Windows the connection string has the format `EtwSession={ETW session}`. A list of fields which should be stored as individual table columns. +* If null, all fields will be stored as individual columns. +* If non-null, only those fields named in the list will be stored as individual columns. + #### `PrepopulatedFields` (optional) This is a collection of fields that will be applied to all the Logs and Traces From 0b903448c32eb5bb19dcbfd112a3cbdc30dd5c52 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:35:52 -0700 Subject: [PATCH 0719/1499] [Exporter.Geneva] Update OTel SDK prerelease version (#1210) --- build/Common.props | 2 +- .../CHANGELOG.md | 7 +++ .../GenevaExporterHelperExtensions.cs | 20 ++++----- .../Metrics/GenevaMetricExporterExtensions.cs | 17 +++---- .../MsgPackExporter/MsgPackLogExporter.cs | 3 ++ .../TLDExporter/TldLogExporter.cs | 4 ++ .../GenevaLogExporterTests.cs | 44 +++++++------------ .../GenevaTraceExporterTests.cs | 10 ++--- 8 files changed, 53 insertions(+), 54 deletions(-) diff --git a/build/Common.props b/build/Common.props index 07c8eaae50..56d5b202c8 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,7 +35,7 @@ [3.3.3] [1.1.1,2.0) [1.4.0,2.0) - [1.5.0-alpha.1] + [1.5.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 29c213c717..146061ec97 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,12 +2,19 @@ ## Unreleased +* Fix an issue with getting sanitized category name in pass-through table name + mapping cases for `TldLogExporter`. + ([#1175](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1175)) + * TldLogExporter to export `SpanId` value in `ext_dt_spanId` field instead of `TraceId` value. ([#1184](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1184)) * Add support for abstract domain sockets. ([#1199](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1199)) +* Update OTel SDK version to `1.5.0-rc.1`. + ([#1210](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1210)) + ## 1.5.0-alpha.3 Released 2023-Apr-19 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 50de95692b..266c1b11e4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -15,6 +15,7 @@ // using System; +using System.Diagnostics; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -26,34 +27,31 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu { Guard.ThrowIfNull(builder); - if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + return builder.AddProcessor(sp => { - return deferredTracerProviderBuilder.Configure((sp, builder) => - { - AddGenevaTraceExporter(builder, sp.GetOptions(), configure); - }); - } + var exporterOptions = sp.GetOptions(); - return AddGenevaTraceExporter(builder, new GenevaExporterOptions(), configure); + return BuildGenevaTraceExporter(exporterOptions, configure); + }); } - private static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, GenevaExporterOptions options, Action configure) + private static BaseProcessor BuildGenevaTraceExporter(GenevaExporterOptions options, Action configure) { configure?.Invoke(options); var exporter = new GenevaTraceExporter(options); if (exporter.IsUsingUnixDomainSocket) { var batchOptions = new BatchExportActivityProcessorOptions(); - return builder.AddProcessor(new BatchActivityExportProcessor( + return new BatchActivityExportProcessor( exporter, batchOptions.MaxQueueSize, batchOptions.ScheduledDelayMilliseconds, batchOptions.ExporterTimeoutMilliseconds, - batchOptions.MaxExportBatchSize)); + batchOptions.MaxExportBatchSize); } else { - return builder.AddProcessor(new ReentrantActivityExportProcessor(exporter)); + return new ReentrantActivityExportProcessor(exporter); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index d2f37a5ee0..67da1c315c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -32,21 +32,18 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui { Guard.ThrowIfNull(builder); - if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + return builder.AddReader(sp => { - return deferredMeterProviderBuilder.Configure((sp, builder) => - { - AddGenevaMetricExporter(builder, sp.GetOptions(), configure); - }); - } + var exporterOptions = sp.GetOptions(); - return AddGenevaMetricExporter(builder, new GenevaMetricExporterOptions(), configure); + return BuildGenevaMetricExporter(exporterOptions, configure); + }); } - private static MeterProviderBuilder AddGenevaMetricExporter(MeterProviderBuilder builder, GenevaMetricExporterOptions options, Action configure = null) + private static MetricReader BuildGenevaMetricExporter(GenevaMetricExporterOptions options, Action configure = null) { configure?.Invoke(options); - return builder.AddReader(new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) - { TemporalityPreference = MetricReaderTemporalityPreference.Delta }); + return new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) + { TemporalityPreference = MetricReaderTemporalityPreference.Delta }; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 2c353b8337..cb09ae3862 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -138,6 +138,8 @@ internal bool IsUsingUnixDomainSocket internal int SerializeLogRecord(LogRecord logRecord) { + // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 +#pragma warning disable 0618 IReadOnlyList> listKvp; if (logRecord.State == null) { @@ -150,6 +152,7 @@ internal int SerializeLogRecord(LogRecord logRecord) // Attempt to see if State could be ROL_KVP. listKvp = logRecord.State as IReadOnlyList>; } +#pragma warning restore 0618 var buffer = m_buffer.Value; if (buffer == null) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 2e1a1d1cf1..2842458d55 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -187,6 +187,9 @@ public void Dispose() internal void SerializeLogRecord(LogRecord logRecord) { IReadOnlyList> listKvp; + + // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 +#pragma warning disable 0618 if (logRecord.State == null) { // When State is null, OTel SDK guarantees StateValues is populated @@ -198,6 +201,7 @@ internal void SerializeLogRecord(LogRecord logRecord) // Attempt to see if State could be ROL_KVP. listKvp = logRecord.State as IReadOnlyList>; } +#pragma warning restore 0618 // Structured log. // 2 scenarios. diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index aba31bb007..cd3554260e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -569,14 +569,9 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) _ = exporter.SerializeLogRecord(logRecordList[0]); object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var body = GetField(fluentdData, "body"); - if (includeFormattedMessage) - { - Assert.Equal("Formatted Message", body); - } - else - { - Assert.Null(body); - } + + // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` + Assert.Equal("Formatted Message", body); Assert.Equal("Value1", GetField(fluentdData, "Key1")); Assert.Equal("Value2", GetField(fluentdData, "Key2")); @@ -599,14 +594,9 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); - if (includeFormattedMessage) - { - Assert.Equal("Formatted Message", body); - } - else - { - Assert.Null(body); - } + + // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` + Assert.Equal("Formatted Message", body); // ARRANGE logRecordList.Clear(); @@ -627,8 +617,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); - // Formatter is null, hence body is always null - Assert.Null(body); + // Even though Formatter is null, body is populated with the state + Assert.Equal("somestringasdata", body); // ARRANGE logRecordList.Clear(); @@ -654,15 +644,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) body = GetField(fluentdData, "body"); - // Only populate body if FormattedMessage is enabled - if (includeFormattedMessage) - { - Assert.Equal("Example formatted message.", body); - } - else - { - Assert.Null(body); - } + // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` + Assert.Equal("Example formatted message.", body); } finally { @@ -1376,6 +1359,9 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter bool isUnstructuredLog = true; IReadOnlyList> stateKeyValuePairList; + + // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 +#pragma warning disable 0618 if (logRecord.State == null) { stateKeyValuePairList = logRecord.StateValues; @@ -1384,6 +1370,7 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter { stateKeyValuePairList = logRecord.State as IReadOnlyList>; } +#pragma warning restore 0618 if (stateKeyValuePairList != null) { @@ -1392,10 +1379,13 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter if (isUnstructuredLog) { + // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 +#pragma warning disable 0618 if (logRecord.State != null) { Assert.Equal(logRecord.State.ToString(), mapping["body"]); } +#pragma warning restore 0618 else { Assert.Equal(stateKeyValuePairList[0].Value, mapping["body"]); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 0ca2f0b373..cb7c61447a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -174,13 +174,13 @@ public void GenevaTraceExporter_Success_Windows() var source = new ActivitySource(sourceName); using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) { - parent?.SetTag("http.method", "GET"); - parent?.SetTag("http.url", "https://localhost/wiki/Rabbit"); + parent.SetTag("http.method", "GET"); + parent.SetTag("http.url", "https://localhost/wiki/Rabbit"); using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) { - child?.SetTag("http.method", "GET"); - child?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); - child?.SetTag("http.status_code", 404); + child.SetTag("http.method", "GET"); + child.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + child.SetTag("http.status_code", 404); } parent?.SetTag("http.status_code", 200); From 3f26435208253a0108afb70eabff4839da521d4f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:55:02 -0700 Subject: [PATCH 0720/1499] [Exporter.Geneva] Update CHANGELOG for 1.5.0-rc.1 (#1217) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 146061ec97..693592d177 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.0-rc.1 + +Released 2023-Jun-05 + * Fix an issue with getting sanitized category name in pass-through table name mapping cases for `TldLogExporter`. ([#1175](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1175)) From 24545cdf988a95d914a42418e8c0ec5d1caaf4cd Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 5 Jun 2023 15:34:59 -0700 Subject: [PATCH 0721/1499] [Instrumentation.Runtime] Update CHANGELOG for 1.4.0 release (#1214) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index de8698354f..59d0e690a3 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## 1.4.0 + +Released 2023-Jun-01 + +* Bumped the version to `1.4.0` to keep it in sync with the release versions of + `OpenTelemetry.API`. This makes it more intuitive for the users to figure out + what version of core packages would work with a given version of this package. + ## 1.1.0-rc.2 Released 2023-Feb-27 From ac90598825cf6188e2d9aa29c597eeda21c8ddd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 6 Jun 2023 22:33:02 +0200 Subject: [PATCH 0722/1499] Fix NU1604 for Examples.InfluxDB (#1221) --- examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj index acb83f28cf..f81e86dc4c 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -9,7 +9,7 @@ - + From e0d9e1e3170d8c72c1630199c9369f0951dd06ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 6 Jun 2023 22:58:29 +0200 Subject: [PATCH 0723/1499] Bump OpenTelemetry to 1.5.0 (#1220) --- build/Common.props | 2 +- examples/AspNet/Examples.AspNet.csproj | 2 +- .../process-instrumentation/process-instrumentation.csproj | 2 +- .../runtime-instrumentation/runtime-instrumentation.csproj | 2 +- src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md | 2 ++ src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 3 +++ src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 ++-- .../OpenTelemetry.Exporter.OneCollector.csproj | 2 +- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++-- .../OpenTelemetry.Extensions.csproj | 2 +- .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 5 ++++- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 6 ++++-- src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 3 +++ .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 4 ++-- 26 files changed, 60 insertions(+), 21 deletions(-) diff --git a/build/Common.props b/build/Common.props index 56d5b202c8..56041e80cc 100644 --- a/build/Common.props +++ b/build/Common.props @@ -34,7 +34,7 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.4.0,2.0) + [1.5.0,2.0) [1.5.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index d7d8ac9dc1..a8a47cbb92 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -84,7 +84,7 @@ - + diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj index 727523e7b5..d464f2f3b0 100644 --- a/examples/process-instrumentation/process-instrumentation.csproj +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index 971a331c3d..89ec4225f9 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index e3cc1d02e0..d478e85f5b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Updates to 1.5.0 of OpenTelemetry SDK. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random instance instead of recreating with ThreadLocal ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 116da71e91..d77403da39 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updates to 1.5.0 of OpenTelemetry SDK. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-alpha.1 Released 2023-May-18 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index ecb16daf01..bdac13a24c 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel SDK version to `1.4.0`. - ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) +* Update OTel SDK version to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 2990eb9ae4..1e28454478 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 1e420b07aa..24b24882a3 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel SDK version to `1.4.0`. - ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Update OTel SDK version to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index a8f69a0230..f2ad80b879 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 96c4445b19..171866a9de 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-rc9.8 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index d3add35586..4e21b155b6 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased +* Updates to 1.5.0 of OpenTelemetry SDK. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-beta.1 Released 2023-Mar-30 -- Initial release +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 4bfcb84e5d..2618057616 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.5.0 + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-beta.4 Released 2023-Mar-06 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index e6428d823d..35853ee185 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OTel SDK package version to 1.5.0 + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-beta.6 Released 2023-Mar-13 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 6df60b7a5b..e16597e215 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.4.0. - ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Update OpenTelemetry.Api to 1.5.0. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) ## 1.0.0-alpha.2 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 967f858177..d694f46d6a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel API version to `1.4.0`. - ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Update OTel API version to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Removes `AddHangfireInstrumentation` method with default configure default parameter. ([#1129](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1129)) * Support Hangfire `1.8`. diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 03de56197c..a71cac01b0 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Update OTel API version to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Removes `AddMySqlDataInstrumentation` method with default configure parameter. ([#930](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/930)) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index f9b1a72736..a2d4862520 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OpenTelemetry SDK to 1.4.0 - ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) +* Updated OpenTelemetry SDK to 1.5.0 + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Removes `AddOwinInstrumentation` method with default configure parameter. ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 490331cba4..65c5ed3f74 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.5.0 + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 0.5.0-beta.2 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 6efa30b017..b074f674e2 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry.Api to 1.5.0. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-alpha.2 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 59d0e690a3..ae00bc3dbf 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.5.0 + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.4.0 Released 2023-Jun-01 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index dd61aafd97..ce15a5ce62 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel API version to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-rc9.9 Released 2023-May-25 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 2a6588a8c4..4ecc7bba6a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel SDK version to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-rc.9 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index d5cad43209..d77fccd1b8 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,14 +2,16 @@ ## Unreleased +* Updates to 1.5.0 of OpenTelemetry SDK. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Added Azure VM resource detector. -([#1182](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1182)) + ([#1182](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1182)) ## 1.0.0-alpha.1 Released 2023-Apr-19 * Add AppService resource detector. -([#989](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/989)) + ([#989](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/989)) For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 09cff2b9b3..071218cb33 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updates to 1.5.0 of OpenTelemetry SDK. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-beta.3 Released 2023-Apr-7 diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 48538d1d58..02e2134a9b 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -18,8 +18,8 @@ - - + + From 966727e8c9d2bba8b7f1dfb4639a5a7f57813e99 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Tue, 6 Jun 2023 15:50:41 -0700 Subject: [PATCH 0724/1499] [Instrumentation.Runtime] Update CHANGELOG for 1.5.0 (#1222) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index ae00bc3dbf..97ed41a722 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.0 + +Released 2023-Jun-06 + * Update OpenTelemetry API to 1.5.0 ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) From 698e70a58f4a8e329933a83425de3e2fc2fb9daa Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Tue, 6 Jun 2023 18:33:29 -0700 Subject: [PATCH 0725/1499] [Exporter.Geneva] Add named options support for GenevaTraceExporter and GenevaMetricExporter (#1218) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 5 ++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 7 ++- .../netstandard2.0/PublicAPI.Unshipped.txt | 5 ++ .../CHANGELOG.md | 10 ++++ .../GenevaExporterHelperExtensions.cs | 27 ++++++++++- .../Internal/ServiceProviderExtensions.cs | 46 ------------------- .../Metrics/GenevaMetricExporterExtensions.cs | 31 ++++++++++++- .../GenevaMetricExporterTests.cs | 44 ++++++++++++++++++ .../GenevaTraceExporterTests.cs | 43 +++++++++++++++++ 9 files changed, 168 insertions(+), 50 deletions(-) delete mode 100644 src/OpenTelemetry.Exporter.Geneva/Internal/ServiceProviderExtensions.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt index 1fd2dcd539..db58b7a99f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt @@ -3,3 +3,8 @@ OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenT OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt index 4ca0ea2c19..db58b7a99f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -2,4 +2,9 @@ OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void \ No newline at end of file +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 1fd2dcd539..db58b7a99f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -3,3 +3,8 @@ OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenT OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +*REMOVED*static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 693592d177..be1bc1cd30 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +* Add named options support for `GenevaTraceExporter` and + `GenevaMetricExporter`. + ([#1218](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1218)) + +* Add a new overload for `AddGenevaMetricExporter` without any parameters to + avoid warning + [RS0026](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md#rs0026-do-not-add-multiple-public-overloads-with-optional-parameters). + ([#1218](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1218)) + ## 1.5.0-rc.1 Released 2023-Jun-05 @@ -13,6 +22,7 @@ Released 2023-Jun-05 * TldLogExporter to export `SpanId` value in `ext_dt_spanId` field instead of `TraceId` value. ([#1184](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1184)) + * Add support for abstract domain sockets. ([#1199](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1199)) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 266c1b11e4..c050b34c3b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -16,6 +16,8 @@ using System; using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -23,13 +25,36 @@ namespace OpenTelemetry.Exporter.Geneva; public static class GenevaExporterHelperExtensions { + /// + /// Adds to the . + /// + /// builder to use. + /// Exporter configuration options. + /// The instance of to chain the calls. public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) + => AddGenevaTraceExporter(builder, name: null, configure); + + /// + /// Adds to the . + /// + /// builder to use. + /// /// Name which is used when retrieving options. + /// Exporter configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, string name, Action configure) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } + return builder.AddProcessor(sp => { - var exporterOptions = sp.GetOptions(); + var exporterOptions = sp.GetRequiredService>().Get(name); return BuildGenevaTraceExporter(exporterOptions, configure); }); diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ServiceProviderExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ServiceProviderExtensions.cs deleted file mode 100644 index 9175001b9f..0000000000 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ServiceProviderExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#if NET462_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER -using Microsoft.Extensions.Options; -#endif - -namespace System; - -/// -/// Extension methods for OpenTelemetry dependency injection support. -/// -internal static class ServiceProviderExtensions -{ - /// - /// Get options from the supplied . - /// - /// Options type. - /// . - /// Options instance. - public static T GetOptions(this IServiceProvider serviceProvider) - where T : class, new() - { -#if NET462_OR_GREATER || NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1_OR_GREATER - IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); - - // Note: options could be null if user never invoked services.AddOptions(). - return options?.Value ?? new T(); -#else - return new T(); -#endif - } -} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 67da1c315c..4933ad7a62 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -15,6 +15,8 @@ // using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -26,15 +28,40 @@ public static class GenevaMetricExporterExtensions /// Adds to the . /// /// builder to use. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder) + => AddGenevaMetricExporter(builder, name: null, configure: null); + + /// + /// Adds to the . + /// + /// builder to use. + /// Exporter configuration options. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure) + => AddGenevaMetricExporter(builder, name: null, configure); + + /// + /// Adds to the . + /// + /// builder to use. + /// /// Name which is used when retrieving options. /// Exporter configuration options. /// The instance of to chain the calls. - public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure = null) + public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, string name, Action configure) { Guard.ThrowIfNull(builder); + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } + return builder.AddReader(sp => { - var exporterOptions = sp.GetOptions(); + var exporterOptions = sp.GetRequiredService>().Get(name); return BuildGenevaMetricExporter(exporterOptions, configure); }); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 2054179466..f9b3ead921 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -26,7 +26,9 @@ using System.Runtime.InteropServices; using System.Threading.Tasks; using Kaitai; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; using Xunit; using static OpenTelemetry.Exporter.Geneva.Tests.MetricsContract; @@ -873,6 +875,48 @@ public void SuccessfulSerializationWithCustomAccountAndNamespace() } } + [Fact] + public void AddGenevaMetricExporterNamedOptionsSupport() + { + string connectionString; + string connectionStringForNamedOptions; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + connectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + connectionStringForNamedOptions = "Account=OTelMonitoringAccount-NamedOptions;Namespace=OTelMetricNamespace-NamedOptions"; + } + else + { + var path = GenerateTempFilePath(); + connectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + connectionStringForNamedOptions = $"Endpoint=unix:{path};Account=OTelMonitoringAccount-NamedOptions;Namespace=OTelMetricNamespace-NamedOptions"; + } + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => + { + services.Configure(options => + { + options.ConnectionString = connectionString; + }); + services.Configure("ExporterWithNamedOptions", options => + { + options.ConnectionString = connectionStringForNamedOptions; + }); + }) + .AddGenevaMetricExporter(options => + { + // ConnectionString for the options is already set in `IServiceCollection Configure` calls above + Assert.Equal(connectionString, options.ConnectionString); + }) + .AddGenevaMetricExporter("ExporterWithNamedOptions", options => + { + // ConnectionString for the named options is already set in `IServiceCollection Configure` calls above + Assert.Equal(connectionStringForNamedOptions, options.ConnectionString); + }) + .Build(); + } + private static string GenerateTempFilePath() { while (true) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index cb7c61447a..7d9dbde3d0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -24,6 +24,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Trace; using Xunit; @@ -514,6 +515,48 @@ public void TLDTraceExporter_Success_Windows() } } + [Fact] + public void AddGenevaTraceExporterNamedOptionsSupport() + { + string connectionString; + string connectionStringForNamedOptions; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + connectionString = "EtwSession=OpenTelemetry"; + connectionStringForNamedOptions = "EtwSession=OpenTelemetry-NamedOptions"; + } + else + { + var path = GetRandomFilePath(); + connectionString = "Endpoint=unix:" + path; + connectionStringForNamedOptions = "Endpoint=unix:" + path + "NamedOptions"; + } + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(options => + { + options.ConnectionString = connectionString; + }); + services.Configure("ExporterWithNamedOptions", options => + { + options.ConnectionString = connectionStringForNamedOptions; + }); + }) + .AddGenevaTraceExporter(options => + { + // ConnectionString for the options is already set in `IServiceCollection Configure` calls above + Assert.Equal(connectionString, options.ConnectionString); + }) + .AddGenevaTraceExporter("ExporterWithNamedOptions", options => + { + // ConnectionString for the named options is already set in `IServiceCollection Configure` calls above + Assert.Equal(connectionStringForNamedOptions, options.ConnectionString); + }) + .Build(); + } + private static string GetRandomFilePath() { while (true) From 89ab58e0de8dfba5ea0b1431e1176ef310684647 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Thu, 8 Jun 2023 15:28:08 -0700 Subject: [PATCH 0726/1499] [Exporter.Geneva] Update EventSource implmentation of GenevaMetricExporter (#1225) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 5 +++++ .../Metrics/GenevaMetricExporter.cs | 2 +- .../Metrics/Transport/MetricEtwDataTransport.cs | 9 ++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index be1bc1cd30..d4d8ce95b3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -11,6 +11,11 @@ [RS0026](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md#rs0026-do-not-add-multiple-public-overloads-with-optional-parameters). ([#1218](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1218)) +* Fix the issue of running into the `ArgumentException`: `An instance of + EventSource with Guid edc24920-e004-40f6-a8e1-0e6e48f39d84 already exists.` + when using multiple instances of `GenevaMetricExporter`. + ([#1225](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1225)) + ## 1.5.0-rc.1 Released 2023-Jun-05 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index ccac1bddfa..6cf233a685 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -87,7 +87,7 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) case TransportProtocol.Unspecified: if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - this.metricDataTransport = new MetricEtwDataTransport(); + this.metricDataTransport = MetricEtwDataTransport.Shared; break; } else diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 9d825ce249..0b0498b38f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -24,7 +24,14 @@ internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport { private readonly int fixedPayloadEndIndex; - public MetricEtwDataTransport() + static MetricEtwDataTransport() + { + Shared = new(); + } + + public static readonly MetricEtwDataTransport Shared; + + private MetricEtwDataTransport() { unsafe { From 9fe038bbaf065124447e75999b4f03ea903a2bf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 9 Jun 2023 06:38:49 +0200 Subject: [PATCH 0727/1499] Releases with OTel SDK/API 1.5.0 (#1223) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 8 ++++++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ 9 files changed, 40 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 171866a9de..bfb6288753 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.9 + +Released 2023-Jun-09 + * Update `OpenTelemetry.Api` to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 12cca59058..93680f1418 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## 1.0.0-rc9.9 + +Released 2023-Jun-09 + +* Release together with `OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule` + due to update `OpenTelemetry.Api` to `1.5.0`. + ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + ## 1.0.0-rc9.8 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 35853ee185..85d11d800c 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.7 + +Released 2023-Jun-09 + * Updated OTel SDK package version to 1.5.0 ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index a71cac01b0..aca6077d87 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.7 + +Released 2023-Jun-09 + * Update OTel API version to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Removes `AddMySqlDataInstrumentation` method with default configure parameter. diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 65c5ed3f74..b6709bb926 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.5.0-beta.3 + +Released 2023-Jun-09 + * Update OpenTelemetry API to 1.5.0 ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index b074f674e2..a420cd9281 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.3 + +Released 2023-Jun-09 + * Update OpenTelemetry.Api to 1.5.0. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index ce15a5ce62..8639478d93 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.10 + +Released 2023-Jun-09 + * Update OTel API version to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 4ecc7bba6a..5b947d541e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.10 + +Released 2023-Jun-09 + * Update OTel SDK version to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 071218cb33..a7091cd0ab 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2023-Jun-09 + * Updates to 1.5.0 of OpenTelemetry SDK. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) From 1c109ba8f1de1cdecf66b837a35ac562587c8703 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:23:33 -0700 Subject: [PATCH 0728/1499] [Sampler.AWS] Skip flaky unit test (#1229) --- .../OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index 5e9766163e..652165e0ab 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -58,7 +58,7 @@ public void TestSamplerWithDefaults() Assert.NotNull(sampler.Client); } - [Fact] + [Fact(Skip = "Flaky test. Related issue: https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1219")] public void TestSamplerUpdateAndSample() { // setup mock server From 182e70e274ad9af0b47c2c6869b36b51ed8bafa3 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 9 Jun 2023 11:56:43 -0700 Subject: [PATCH 0729/1499] [Exporter.Geneva] Remove EventSource attribute from EtwDataTransport (#1228) --- .../MsgPackExporter/Transport/EtwDataTransport.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index 38e42a3e01..1204fe6ee3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -19,8 +19,7 @@ namespace OpenTelemetry.Exporter.Geneva; -[EventSource(Name = "OpenTelemetry")] -internal class EtwEventSource : EventSource +internal sealed class EtwEventSource : EventSource { public EtwEventSource(string providerName) : base(providerName, EventSourceSettings.EtwManifestEventFormat) @@ -50,7 +49,7 @@ public unsafe void SendEvent(int eventId, byte[] data, int size) } } -internal class EtwDataTransport : IDataTransport, IDisposable +internal sealed class EtwDataTransport : IDataTransport, IDisposable { public EtwDataTransport(string providerName) { @@ -71,21 +70,13 @@ public bool IsEnabled() private bool m_disposed; public void Dispose() - { - this.Dispose(true); - } - - protected virtual void Dispose(bool disposing) { if (this.m_disposed) { return; } - if (disposing) - { - this.m_eventSource.Dispose(); - } + this.m_eventSource.Dispose(); this.m_disposed = true; } From cd8eedcc9b1c2199e8977b139e606bfa64a18927 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Sun, 11 Jun 2023 21:44:42 -0700 Subject: [PATCH 0730/1499] [Exporter.Geneva] Mark internal classes sealed (#1233) --- .../External/TraceLoggingDynamic.cs | 2 +- .../Internal/ConnectionStringBuilder.cs | 2 +- .../Internal/ReentrantActivityExportProcessor.cs | 2 +- .../MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs | 2 +- .../MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs index 0f7654ee8d..c5d46a6bbf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs +++ b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs @@ -651,7 +651,7 @@ public static extern int EventActivityIdControl( /// responsible for caching objects such that only one thread uses a particular /// instance of EventBuilder at any one time. /// -internal class EventBuilder +internal sealed class EventBuilder { private enum InType : byte { diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 695f5496d6..2b82ad3e50 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -31,7 +31,7 @@ internal enum TransportProtocol Unspecified, } -internal class ConnectionStringBuilder +internal sealed class ConnectionStringBuilder { private readonly Dictionary _parts = new Dictionary(StringComparer.Ordinal); diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs index 80c1522186..b1785bbefa 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Exporter.Geneva; // we can get rid of this class. // This is currently only used in ETW export, where we know // that the underlying system is safe under concurrent calls. -internal class ReentrantActivityExportProcessor : ReentrantExportProcessor +internal sealed class ReentrantActivityExportProcessor : ReentrantExportProcessor { public ReentrantActivityExportProcessor(BaseExporter exporter) : base(exporter) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs index 0490dcc70b..aea5c7049e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs @@ -20,7 +20,7 @@ namespace OpenTelemetry.Exporter.Geneva; -internal class UnixDomainSocketDataTransport : IDataTransport, IDisposable +internal sealed class UnixDomainSocketDataTransport : IDataTransport, IDisposable { public const int DefaultTimeoutMilliseconds = 15000; private readonly EndPoint unixEndpoint; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs index 63e37360b7..df6f9c1d62 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs @@ -22,7 +22,7 @@ namespace OpenTelemetry.Exporter.Geneva; -internal class UnixDomainSocketEndPoint : EndPoint +internal sealed class UnixDomainSocketEndPoint : EndPoint { // sockaddr_un.sun_path at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html, -1 for terminator private const int MaximumNativePathLength = 92 - 1; From e91dd84fd30da0084dd4da1cffbb2d4eb7d37145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 13 Jun 2023 06:56:35 +0200 Subject: [PATCH 0731/1499] Release packages with tag containing -rc9. as prerelease (#1231) --- .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 4 ++-- .github/workflows/package-Instrumentation.AspNet.yml | 4 ++-- .../workflows/package-Instrumentation.StackExchangeRedis.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 67e2e0f61d..888f0e3c9e 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -55,13 +55,13 @@ jobs: nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 748fe3d5ee..ffaac9cd77 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -55,13 +55,13 @@ jobs: nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index 54b38de3cd..f2a8b8a278 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -55,13 +55,13 @@ jobs: nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} + if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 06b9a286a6ab2af5257ce26b5dcb6fac56112f96 Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:14:44 +0200 Subject: [PATCH 0732/1499] [Instrumentation.AWSLambda] Request release of 1.1.0-beta.3 (#1224) --- src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index fb136f3eb6..a139fe55e3 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.3 + +Released 2023-Jun-13 + * Add HTTP server span attributes for API Gateway triggers ([#626](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/626)) * Removes `AddAWSLambdaConfigurations` method with default configure parameter. From dbfeaea9b192a4e3577d12ba3e10b764262bf4e4 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 14 Jun 2023 15:26:34 -0700 Subject: [PATCH 0733/1499] Mark internal and private classes sealed (#1236) --- .../MsgPackExporter/MsgPackLogExporter.cs | 2 +- src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs | 2 +- .../ActivityHelper.cs | 2 +- src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs | 2 +- .../ProcessInstrumentationOptions.cs | 2 +- src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs | 2 +- .../DirectorySizeTracker.cs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index cb09ae3862..be37e18b1e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -504,7 +504,7 @@ public void Dispose() } }; - private class SerializationDataForScopes + private sealed class SerializationDataForScopes { public bool HasEnvProperties; public ushort EnvPropertiesCount; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 2842458d55..19fda3648d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -530,7 +530,7 @@ private static string GetSanitizedCategoryName(string categoryName) } }; - private class SerializationDataForScopes + private sealed class SerializationDataForScopes { public byte HasEnvProperties; public byte PartCFieldsCountFromState; diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index 5c510f7c44..7ef463ec8d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -215,7 +215,7 @@ internal static void RestoreContextIfNeeded(HttpContext context) } } - internal class ContextHolder + internal sealed class ContextHolder { public Activity Activity; public object Baggage; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs index 53fa1720da..60d9f51a02 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Instrumentation.AspNet; /// /// Asp.Net Requests instrumentation. /// -internal class AspNetMetrics : IDisposable +internal sealed class AspNetMetrics : IDisposable { internal static readonly AssemblyName AssemblyName = typeof(HttpInMetricsListener).Assembly.GetName(); internal static readonly string InstrumentationName = AssemblyName.Name; diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs index f5d5fd1a7a..2f168f0e07 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs @@ -19,6 +19,6 @@ namespace OpenTelemetry.Instrumentation.Process; /// /// Options to define the process metrics. /// -internal class ProcessInstrumentationOptions +internal sealed class ProcessInstrumentationOptions { } diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 68ac758b88..eb730de55b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -28,7 +28,7 @@ namespace OpenTelemetry.Instrumentation.Runtime; /// /// .NET runtime instrumentation. /// -internal class RuntimeMetrics +internal sealed class RuntimeMetrics { internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); internal static readonly Meter MeterInstance = new(AssemblyName.Name!, AssemblyName.Version?.ToString()); diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs index 7d942ec7e9..034b108bb1 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; /// /// Tracks the available storage in a specified directory. /// -internal class DirectorySizeTracker +internal sealed class DirectorySizeTracker { private readonly long maxSizeInBytes; private readonly string path; From d3d9ab460c3e45896c1fad5a0dcccad64a7a8f6c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:36:20 -0700 Subject: [PATCH 0734/1499] [Exporter.Geneva] Update OTel SDK version to 1.5.0 and remove Exemplars support (#1238) --- .../CHANGELOG.md | 7 ++++++ .../Metrics/GenevaMetricExporter.cs | 16 ++++-------- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 4 --- .../GenevaMetricExporterTests.cs | 25 ++++++++----------- 5 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index d4d8ce95b3..7f7c5eac11 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.5.0`. + ([#1238](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1238)) + +* Removed support for exporting `Exemplars`. This would be added back in the + `1.6.*` prerelease versions right after `1.5.0` stable version is released. + ([#1238](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1238)) + * Add named options support for `GenevaTraceExporter` and `GenevaMetricExporter`. ([#1218](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1218)) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 6cf233a685..8da5adb605 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -122,7 +122,7 @@ public override ExportResult Export(in Batch batch) { try { - var exemplars = metricPoint.GetExemplars(); + // var exemplars = metricPoint.GetExemplars(); switch (metric.MetricType) { @@ -136,7 +136,6 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp metricPoint.Tags, metricData, - exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -156,7 +155,6 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -176,7 +174,6 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -194,7 +191,6 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -211,7 +207,6 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -237,7 +232,6 @@ public override ExportResult Export(in Batch batch) count, min, max, - exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -301,7 +295,6 @@ internal unsafe ushort SerializeMetricWithTLV( long timestamp, in ReadOnlyTagCollection tags, MetricData value, - Exemplar[] exemplars, out string monitoringAccount, out string metricNamespace) { @@ -328,7 +321,7 @@ internal unsafe ushort SerializeMetricWithTLV( out monitoringAccount, out metricNamespace); - SerializeExemplars(exemplars, this.buffer, ref bufferIndex); + // SerializeExemplars(exemplars, this.buffer, ref bufferIndex); SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -361,7 +354,6 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( uint count, double min, double max, - Exemplar[] exemplars, out string monitoringAccount, out string metricNamespace) { @@ -388,7 +380,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( out monitoringAccount, out metricNamespace); - SerializeExemplars(exemplars, this.buffer, ref bufferIndex); + // SerializeExemplars(exemplars, this.buffer, ref bufferIndex); SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -433,6 +425,7 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); } + /* Commenting out Exemplar related code as it's removed from `1.5.0` stable version of OpenTelemetry SDK [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) { @@ -548,6 +541,7 @@ private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, re var exemplarLength = bufferIndex - bufferIndexForLength + 1; MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); } + */ [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 93599774e7..e9ab3a2a3c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -14,7 +14,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 976ae3d584..d41fbcd08e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -566,7 +566,6 @@ public void SerializeCounterMetricItemWith3Dimensions() this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, - Array.Empty(), out _, out _); } @@ -580,7 +579,6 @@ public void SerializeCounterMetricItemWith4Dimensions() this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, - Array.Empty(), out _, out _); } @@ -609,7 +607,6 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramCountWith3Dimensions, this.histogramMinWith3Dimensions, this.histogramMaxWith3Dimensions, - Array.Empty(), out _, out _); } @@ -626,7 +623,6 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramCountWith4Dimensions, this.histogramMinWith4Dimensions, this.histogramMaxWith4Dimensions, - Array.Empty(), out _, out _); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index f9b3ead921..6ff8011b97 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -196,14 +196,13 @@ public void SuccessfulExportOnLinux() var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; - var exemplars = metricPoint.GetExemplars(); + // var exemplars = metricPoint.GetExemplars(); var bodyLength = exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -354,7 +353,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars if (hasExemplars) { - meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); + // meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); } if (hasFilteredTagsForExemplars) @@ -949,7 +948,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - var exemplars = metricPoint.GetExemplars(); + + // var exemplars = metricPoint.GetExemplars(); List fields = null; @@ -964,7 +964,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -990,7 +989,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1018,7 +1016,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1046,7 +1043,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1081,7 +1077,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, count, min, max, - exemplars, out _, out _); @@ -1120,6 +1115,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(bodyLength, data.LenBody); } + /* if (exemplars.Length > 0) { var validExemplars = exemplars.Where(exemplar => exemplar.Timestamp != default).ToList(); @@ -1141,6 +1137,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, AssertExemplarFilteredTagSerialization(expectedExemplar, serializedExemplar); } } + */ // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); @@ -1213,6 +1210,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(dimensionsCount, dimensions.NumDimensions); } + /* private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExemplar, SingleExemplar serializedExemplar) { var serializedExemplarBody = serializedExemplar.Body; @@ -1262,6 +1260,7 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem } } } + */ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter exporter) { @@ -1269,7 +1268,8 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - var exemplars = metricPoint.GetExemplars(); + + // var exemplars = metricPoint.GetExemplars(); UserdataV2 result = null; if (metricType == MetricType.LongSum) @@ -1282,7 +1282,6 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1301,7 +1300,6 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1322,7 +1320,6 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1343,7 +1340,6 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, - exemplars, out _, out _); @@ -1371,7 +1367,6 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter count, min, max, - exemplars, out _, out _); From 287d7b4bcba05eaf1ba9de14f7cb7be03bb68326 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 14 Jun 2023 17:53:34 -0700 Subject: [PATCH 0735/1499] [Exporter.Geneva] Update CHANGELOG for 1.5.0 (#1237) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 7f7c5eac11..8410c7f777 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## 1.5.0 + +Released 2023-Jun-14 + +* **Important Note:** Starting `1.5.0` version, `GenevaExporter` uses a newer + format for exporting metrics. Please use `>= v2.2.2023.316.006` version of the + MetricsExtension if you are using the metric exporter. + * Update OpenTelemetry SDK version to `1.5.0`. ([#1238](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1238)) From 7dcd6980a115010e1d4e7ed01dd73ae8762266bf Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Thu, 15 Jun 2023 20:28:11 +0200 Subject: [PATCH 0736/1499] [OpenTelemetry.Instrumentation.AWSLambda]: update README according to the recent code changes. (#1234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Neumüller --- .../README.md | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index 28adbb4bb6..a41913b46d 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -15,17 +15,44 @@ Add `AddAWSLambdaConfigurations()` to `TracerProvider`. ```csharp TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() // add other instrumentations - .AddAWSLambdaConfigurations() + .AddAWSLambdaConfigurations(options => options.DisableAwsXRayContextExtraction = true) .Build(); ``` +### AWSLambdaInstrumentationOptions + +`AWSLambdaInstrumentationOptions` contains various properties to configure +AWS lambda instrumentation: + +* [`DisableAwsXRayContextExtraction`](/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs) +* [`SetParentFromBatch`](/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs) + ## Instrumentation +`AWSLambdaWrapper` contains tracing methods covering different types of +function handler method signatures. `AWSLambdaWrapper.Trace()` and +`AWSLambdaWrapper.TraceAsync()` are used for wrapping synchronous +and asynchronous function handlers respectively. The `ActivityContext parentContext` +parameter is optional and used to pass a custom parent context. If the parent +is not passed explicitly then it's either extracted from the +input parameter or uses AWS X-Ray headers if AWS X-Ray context extraction is +enabled (see configuration property `DisableAwsXRayContextExtraction`). +The sequence of the parent extraction: +`explicit parent` -> `parent from input parameter` -> `AWS X-Ray headers` -> `default` +The parent extraction is supported for the input types listed in the table below: + +| Type | Parent extraction source | +|------|--------------------------| +| `APIGatewayProxyRequest, APIGatewayHttpApiV2ProxyRequest` | HTTP headers of the request | +| `SQSEvent` | Attributes of the last `SQSMessage` (if `SetParentFromMessageBatch` is `true`) | +| `SNSEvent` | Attributes of the last `SNSRecord` | + ### Lambda Function -1. Create a wrapper function with the same signature as the original Lambda function. -Call `AWSLambdaWrapper.Trace()` API and pass `TracerProvider`, original Lambda function -and its inputs as parameters. +1. Create a wrapper function with the same signature as the original Lambda +function but an added ILambdaContext parameter if it was not already present. +Call `AWSLambdaWrapper.Trace()` or `AWSLambdaWrapper.TraceAsync()` API and pass +`TracerProvider`, original Lambda function and its parameters. 2. Set the wrapper function as the Lambda handler input. @@ -48,14 +75,14 @@ public string OriginalFunctionHandler(JObject input, ILambdaContext context) For using base classes from package [Amazon.Lambda.AspNetCoreServer](https://github.com/aws/aws-lambda-dotnet/tree/master/Libraries/src/Amazon.Lambda.AspNetCoreServer#amazonlambdaaspnetcoreserver), override the `FunctionHandlerAsync` function in `LambdaEntryPoint.cs` file. Call -`AWSLambdaWrapper.Trace()` API and pass `TracerProvider`, original Lambda function +`AWSLambdaWrapper.TraceAsync()` API and pass `TracerProvider`, original Lambda function and its inputs as parameters. Below is an example if using `APIGatewayProxyFunction` as base class. ```csharp public override async Task FunctionHandlerAsync( APIGatewayProxyRequest request, ILambdaContext lambdaContext) -=> await AWSLambdaWrapper.Trace(tracerProvider, base.FunctionHandlerAsync, +=> await AWSLambdaWrapper.TraceAsync(tracerProvider, base.FunctionHandlerAsync, request, lambdaContext); ``` @@ -75,7 +102,7 @@ public class Function .AddHttpClientInstrumentation() .AddAWSInstrumentation() .AddOtlpExporter() - .AddAWSLambdaConfigurations() + .AddAWSLambdaConfigurations(options => options.DisableAwsXRayContextExtraction = true) .Build(); } From 326d071b61a13aca92286733c934f8d5c186ee2b Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 16 Jun 2023 00:43:43 -0700 Subject: [PATCH 0737/1499] [Instrumentation.Runtime] Add a metric for total paused duration in GC for .NET 7 and greater versions (#1239) --- .../CHANGELOG.md | 4 ++++ .../README.md | 16 ++++++++++++++++ .../RuntimeMetrics.cs | 14 +++++++++++++- .../RuntimeMetricsTests.cs | 3 +++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 97ed41a722..81ff30c13d 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Add a metric `process.runtime.dotnet.gc.duration` for total paused duration in + GC for .NET 7 and greater versions + ([#1239](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1239)) + ## 1.5.0 Released 2023-Jun-06 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 79734bfc79..20ff2da435 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -176,6 +176,22 @@ The API used to retrieve the value is: * [GCGenerationInfo.FragmentationAfterBytes Property](https://docs.microsoft.com/dotnet/api/system.gcgenerationinfo.fragmentationafterbytes) Gets the fragmentation in bytes on exit from the reported collection. +#### process.runtime.dotnet.**gc.duration** + +The total amount of time paused in GC since the process start. + +> **Note** +> This metric is only available when targeting .NET 7 or later. + +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------|-------------------|------------|------------------|------------------| +| `ns` | ObservableCounter | `Int64` | No Attributes | N/A | + +The API used to retrieve the value is: + +* [GC.GetTotalPauseDuration](https://learn.microsoft.com/dotnet/api/system.gc.gettotalpauseduration) + Gets the total amount of time paused in GC since the beginning of the process. + ### JIT Compiler related metrics These metrics are only available when targeting .NET6 or later. diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index eb730de55b..bdbd4f2821 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -120,9 +120,9 @@ static RuntimeMetrics() description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); } - // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 if (Environment.Version.Major >= 7) { + // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 MeterInstance.CreateObservableUpDownCounter( "process.runtime.dotnet.gc.heap.fragmentation.size", () => @@ -144,6 +144,18 @@ static RuntimeMetrics() }, unit: "bytes", description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + + // GC.GetTotalPauseDuration() is not available until .NET 7. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1163 + var mi = typeof(GC).GetMethod("GetTotalPauseDuration", BindingFlags.Public | BindingFlags.Static); + var getTotalPauseDuration = mi?.CreateDelegate>(); + if (getTotalPauseDuration != null) + { + MeterInstance.CreateObservableCounter( + "process.runtime.dotnet.gc.duration", + () => getTotalPauseDuration().Ticks * NanosecondsPerTick, + unit: "ns", + description: "The total amount of time paused in GC since the process start."); + } } MeterInstance.CreateObservableCounter( diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 602d35e5bf..b935e0c7d5 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -94,6 +94,9 @@ public void GcMetricsTest() { var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); Assert.NotNull(gcHeapFragmentationSizeMetric); + + var gcDurationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.duration"); + Assert.NotNull(gcDurationMetric); } #endif } From 68e60dbd51b11d81e9dce4a279b841b4761f5ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Abdurrahman=20Alp=20K=C3=B6ken?= Date: Fri, 16 Jun 2023 21:13:02 +0300 Subject: [PATCH 0738/1499] [Instrumentation.EntityFrameworkCore] Add Filter public API to enable filtering (#1203) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 4 + .../EntityFrameworkInstrumentationOptions.cs | 21 +++ .../EntityFrameworkDiagnosticListener.cs | 22 +++ ...tityFrameworkInstrumentationEventSource.cs | 21 +++ .../README.md | 24 ++++ .../EntityFrameworkDiagnosticListenerTests.cs | 126 ++++++++++++++++++ 7 files changed, 220 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e1de3a6e74..79d38853ff 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +1,7 @@ OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EntityFrameworkInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.get -> bool OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.get -> bool diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 85d11d800c..bfebdc306c 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added `Filter` public API on `EntityFrameworkInstrumentationOptions` to + enable filtering of instrumentation. + ([#1203](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1203)) + ## 1.0.0-beta.7 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 722221306f..82a7f36cd1 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -44,4 +44,25 @@ public class EntityFrameworkInstrumentationOptions /// : db command to allow access to command. /// public Action EnrichWithIDbCommand { get; set; } + + /// + /// Gets or sets a filter function that determines whether or not to + /// collect telemetry about a command from a particular provider. + /// + /// + /// Notes: + /// + /// The first parameter passed to the filter function is the provider name. + /// The second parameter passed to the filter function is from which additional + /// information can be extracted. + /// The return value for the filter: + /// + /// If filter returns , the command is + /// collected. + /// If filter returns or throws an + /// exception, the command is NOT collected. + /// + /// + /// + public Func Filter { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 1740e012c6..0e9cc1e622 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -179,6 +179,28 @@ public override void OnCustom(string name, Activity activity, object payload) { var command = this.commandFetcher.Fetch(payload); + try + { + var dbContext = this.dbContextFetcher.Fetch(payload); + var dbContextDatabase = this.dbContextDatabaseFetcher.Fetch(dbContext); + var providerName = this.providerNameFetcher.Fetch(dbContextDatabase); + + if (command is IDbCommand typedCommand && this.options.Filter?.Invoke(providerName, typedCommand) == false) + { + EntityFrameworkInstrumentationEventSource.Log.CommandIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + } + catch (Exception ex) + { + EntityFrameworkInstrumentationEventSource.Log.CommandFilterException(ex); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + if (this.commandTypeFetcher.Fetch(command) is CommandType commandType) { var commandText = this.commandTextFetcher.Fetch(command); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 520c3063a3..4736821a16 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -43,6 +43,15 @@ public void EnrichmentException(string eventName, Exception ex) } } + [NonEvent] + public void CommandFilterException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.CommandFilterException(ex.ToInvariantString()); + } + } + [Event(1, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) { @@ -75,4 +84,16 @@ public void EnrichmentException(string eventName, string exception) this.WriteEvent(5, eventName, exception); } } + + [Event(6, Message = "Command is filtered out. Activity {0}", Level = EventLevel.Verbose)] + public void CommandIsFilteredOut(string activityName) + { + this.WriteEvent(6, activityName); + } + + [Event(7, Message = "Command filter threw exception. Command will not be collected. Exception {0}.", Level = EventLevel.Error)] + public void CommandFilterException(string exception) + { + this.WriteEvent(7, exception); + } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index 48a3cd970b..aaca89c2ce 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -112,6 +112,30 @@ services.AddOpenTelemetry() .AddConsoleExporter()); ``` +### Filter + +This option can be used to filter out activities based on the provider name and +the properties of the db command object being instrumented +using a `Func`. The function receives a provider name +and an instance of the db command and should return `true` +if the telemetry is to be collected, and `false` if it should not. + +The following code snippet shows how to use `Filter` to collect traces +for stored procedures only. + +```csharp +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddEntityFrameworkCoreInstrumentation(options => + { + options.Filter = (providerName, command) => + { + return command.CommandType == CommandType.StoredProcedure; + }; + }) + .AddConsoleExporter()); +``` + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 02897938a7..bd8daf0c1f 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -131,6 +131,132 @@ public void EntityFrameworkContextExceptionEventsInstrumentedTest() VerifyActivityData(activity, isError: true); } + [Fact] + public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByDbCommand() + { + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation(options => + { + options.Filter = (providerName, command) => + { + return !command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); + }; + }).Build(); + + using (var context = new ItemsContext(this.contextOptions)) + { + _ = context.Set().OrderBy(e => e.Name).ToList(); + } + + Assert.Equal(2, activityProcessor.Invocations.Count); + + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.False(activity.IsAllDataRequested); + Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.None)); + } + + [Fact] + public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByDbCommand() + { + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation(options => + { + options.Filter = (providerName, command) => + { + return command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); + }; + }).Build(); + + using (var context = new ItemsContext(this.contextOptions)) + { + _ = context.Set().OrderBy(e => e.Name).ToList(); + } + + Assert.Equal(3, activityProcessor.Invocations.Count); + + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.True(activity.IsAllDataRequested); + Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); + } + + [Theory] + [InlineData("Microsoft.EntityFrameworkCore.SqlServer")] + [InlineData("Microsoft.EntityFrameworkCore.Cosmos")] + [InlineData("Devart.Data.SQLite.EFCore")] + [InlineData("MySql.Data.EntityFrameworkCore")] + [InlineData("Pomelo.EntityFrameworkCore.MySql")] + [InlineData("Devart.Data.MySql.EFCore")] + [InlineData("Npgsql.EntityFrameworkCore.PostgreSQL")] + [InlineData("Devart.Data.PostgreSql.EFCore")] + [InlineData("Oracle.EntityFrameworkCore")] + [InlineData("Devart.Data.Oracle.EFCore")] + [InlineData("Microsoft.EntityFrameworkCore.InMemory")] + [InlineData("FirebirdSql.EntityFrameworkCore.Firebird")] + [InlineData("FileContextCore")] + [InlineData("EntityFrameworkCore.SqlServerCompact35")] + [InlineData("EntityFrameworkCore.SqlServerCompact40")] + [InlineData("EntityFrameworkCore.OpenEdge")] + [InlineData("EntityFrameworkCore.Jet")] + [InlineData("Google.Cloud.EntityFrameworkCore.Spanner")] + [InlineData("Teradata.EntityFrameworkCore")] + public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByProviderName(string provider) + { + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation(options => + { + options.Filter = (providerName, command) => + { + return providerName.Equals(provider, StringComparison.OrdinalIgnoreCase); + }; + }).Build(); + + using (var context = new ItemsContext(this.contextOptions)) + { + _ = context.Set().OrderBy(e => e.Name).ToList(); + } + + Assert.Equal(2, activityProcessor.Invocations.Count); + + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + + Assert.False(activity.IsAllDataRequested); + Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.None)); + } + + [Fact] + public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByProviderName() + { + var activityProcessor = new Mock>(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddProcessor(activityProcessor.Object) + .AddEntityFrameworkCoreInstrumentation(options => + { + options.Filter = (providerName, command) => + { + return providerName.Equals("Microsoft.EntityFrameworkCore.Sqlite", StringComparison.OrdinalIgnoreCase); + }; + }).Build(); + + using (var context = new ItemsContext(this.contextOptions)) + { + _ = context.Set().OrderBy(e => e.Name).ToList(); + } + + Assert.Equal(3, activityProcessor.Invocations.Count); + + var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.True(activity.IsAllDataRequested); + Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); + } + public void Dispose() => this.connection.Dispose(); private static DbConnection CreateInMemoryDatabase() From 78d2016999459f1d9763e77d73b4346f5aa12dad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 16 Jun 2023 20:47:44 +0200 Subject: [PATCH 0739/1499] [Instrumentation.AWSLambda] Tests - Supported versions of .NET (#1240) --- .../AWSLambdaWrapperTests.cs | 1 + .../Implementation/AWSLambdaHttpUtilsTests.cs | 1 + .../Implementation/AWSMessagingUtilsTests.cs | 13 +++++++++++-- ...Telemetry.Instrumentation.AWSLambda.Tests.csproj | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index b05b34c12a..ac42826f3c 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -28,6 +28,7 @@ namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; +[Collection("TracerProviderDependent")] public class AWSLambdaWrapperTests { private const string TraceId = "5759e988bd862e3fe1be46a994272793"; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 4f7a548c5a..95cb609358 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -25,6 +25,7 @@ namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation; +[Collection("TracerProviderDependent")] public class AWSLambdaHttpUtilsTests { [Fact] diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs index aba531493b..f51e40e404 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -26,18 +27,26 @@ namespace OpenTelemetry.Instrumentation.AWSLambda.Tests.Implementation; -public class AWSMessagingUtilsTests +[Collection("TracerProviderDependent")] +public class AWSMessagingUtilsTests : IDisposable { private const string TraceId = "0af7651916cd43dd8448eb211c80319c"; private const string SpanId1 = "b9c7c989f97918e1"; private const string SpanId2 = "b9c7c989f97918e2"; + private readonly TracerProvider tracerProvider; + public AWSMessagingUtilsTests() { - var tracerProvider = Sdk.CreateTracerProviderBuilder() + this.tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); } + public void Dispose() + { + this.tracerProvider.Dispose(); + } + [Fact] public void ExtractParentContext_SetParentFromMessageBatchIsDisabled_ParentIsNotSet() { diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 681bd2ba2f..95fbba74b5 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -2,7 +2,7 @@ Unit test project of OpenTelemetry instrumentation for AWS Lambda - netcoreapp3.1 + net7.0;net6.0 true true From 37b1e45e4a9a88316992c89b3b927d56580694cc Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Tue, 20 Jun 2023 11:02:15 +0200 Subject: [PATCH 0740/1499] [Exporter.InfluxDB] Add support for Resources attributes (#1241) --- .../CHANGELOG.md | 3 + .../IMetricsWriter.cs | 3 +- .../InfluxDBMetricsExporter.cs | 2 +- .../PointDataExtensions.cs | 16 +++++ .../TelegrafPrometheusWriterV1.cs | 10 ++- .../TelegrafPrometheusWriterV2.cs | 10 ++- .../InfluxDBMetricsExporterTests.cs | 67 ++++++++++++------- .../MeterProviderBuilderTestExtensions.cs | 32 +++++++++ 8 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index d77403da39..7f0b00c285 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Support for Resource attributes in OpenTelemetry.Exporter.InfluxDB, allowing + resource attributes to be passed as InfluxDB tags. + ([#1241](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1241)) * Updates to 1.5.0 of OpenTelemetry SDK. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs index 1f33751489..ade42aee09 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs @@ -16,10 +16,11 @@ using InfluxDB.Client; using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; namespace OpenTelemetry.Exporter.InfluxDB; internal interface IMetricsWriter { - void Write(Metric metric, WriteApi writeApi); + void Write(Metric metric, Resource resource, WriteApi writeApi); } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs index 0390d351ab..ccb1727bd9 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs @@ -50,7 +50,7 @@ public override ExportResult Export(in Batch batch) { foreach (var metric in batch) { - this.writer.Write(metric, this.writeApi); + this.writer.Write(metric, this.ParentProvider?.GetResource(), this.writeApi); } return ExportResult.Success; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs index b849a9db68..e139873afd 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System.Collections.Generic; using InfluxDB.Client.Writes; namespace OpenTelemetry.Exporter.InfluxDB; @@ -29,4 +30,19 @@ public static PointData Tags(this PointData pointData, ReadOnlyTagCollection tag return pointData; } + + public static PointData Tags(this PointData pointData, IEnumerable> tags) + { + if (tags == null) + { + return pointData; + } + + foreach (var tag in tags) + { + pointData = pointData.Tag(tag.Key, tag.Value.ToString()); + } + + return pointData; + } } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs index e7c80a55c1..42fd45900a 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs @@ -19,12 +19,13 @@ using InfluxDB.Client.Api.Domain; using InfluxDB.Client.Writes; using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; namespace OpenTelemetry.Exporter.InfluxDB; internal sealed class TelegrafPrometheusWriterV1 : IMetricsWriter { - public void Write(Metric metric, WriteApi writeApi) + public void Write(Metric metric, Resource resource, WriteApi writeApi) { var measurement = metric.Name; @@ -38,6 +39,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field("gauge", dataPoint.GetGaugeLastValueLong()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -53,6 +55,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field("gauge", dataPoint.GetGaugeLastValueDouble()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -68,6 +71,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field("counter", dataPoint.GetSumLong()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -83,6 +87,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field("counter", dataPoint.GetSumDouble()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -98,6 +103,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field("gauge", dataPoint.GetSumLong()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -113,6 +119,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field("gauge", dataPoint.GetSumDouble()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -128,6 +135,7 @@ public void Write(Metric metric, WriteApi writeApi) .Field("count", dataPoint.GetHistogramCount()) .Field("sum", dataPoint.GetHistogramSum()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); if (dataPoint.TryGetHistogramMinMaxValues(out double min, out double max)) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs index 5350d7eb0b..b57760ef30 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs @@ -19,12 +19,13 @@ using InfluxDB.Client.Api.Domain; using InfluxDB.Client.Writes; using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; namespace OpenTelemetry.Exporter.InfluxDB; internal sealed class TelegrafPrometheusWriterV2 : IMetricsWriter { - public void Write(Metric metric, WriteApi writeApi) + public void Write(Metric metric, Resource resource, WriteApi writeApi) { var measurement = "prometheus"; var metricName = metric.Name; @@ -39,6 +40,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field(metricName, metricPoint.GetGaugeLastValueLong()) .Tags(metricPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -54,6 +56,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field(metricName, metricPoint.GetGaugeLastValueDouble()) .Tags(metricPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -69,6 +72,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field(metricName, metricPoint.GetSumLong()) .Tags(metricPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -84,6 +88,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field(metricName, metricPoint.GetSumDouble()) .Tags(metricPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -99,6 +104,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field(metricName, dataPoint.GetSumLong()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -114,6 +120,7 @@ public void Write(Metric metric, WriteApi writeApi) .Measurement(measurement) .Field(metricName, dataPoint.GetSumDouble()) .Tags(dataPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); writeApi.WritePoint(pointData); } @@ -127,6 +134,7 @@ public void Write(Metric metric, WriteApi writeApi) var basePoint = PointData .Measurement(measurement) .Tags(metricPoint.Tags) + .Tags(resource?.Attributes) .Timestamp(metricPoint.EndTime.UtcDateTime, WritePrecision.Ns); var headPoint = basePoint diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs index 4c62c0a7f8..785af2ed32 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -17,6 +17,7 @@ using System.Diagnostics.Metrics; using OpenTelemetry.Exporter.InfluxDB.Tests.Utils; using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; using Xunit; namespace OpenTelemetry.Exporter.InfluxDB.Tests; @@ -36,6 +37,7 @@ public void ExportIntGaugeMetric(MetricsSchema metricsSchema, string measurement using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -61,9 +63,7 @@ public void ExportIntGaugeMetric(MetricsSchema metricsSchema, string measurement Assert.Equal(1, dataPoint.Fields.Count); AssertUtils.HasField(valueKey, 42L, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -81,6 +81,7 @@ public void ExportDoubleGaugeMetric(MetricsSchema metricsSchema, string measurem using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -106,9 +107,7 @@ public void ExportDoubleGaugeMetric(MetricsSchema metricsSchema, string measurem Assert.Equal(1, dataPoint.Fields.Count); AssertUtils.HasField(valueKey, 55.42D, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -126,6 +125,7 @@ public void ExportIntSumMetric(MetricsSchema metricsSchema, string measurement, using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -149,9 +149,7 @@ public void ExportIntSumMetric(MetricsSchema metricsSchema, string measurement, Assert.Equal(1, dataPoint.Fields.Count); AssertUtils.HasField(valueKey, 100L, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -169,6 +167,7 @@ public void ExportDoubleSumMetric(MetricsSchema metricsSchema, string measuremen using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -192,9 +191,7 @@ public void ExportDoubleSumMetric(MetricsSchema metricsSchema, string measuremen Assert.Equal(1, dataPoint.Fields.Count); AssertUtils.HasField(valueKey, 12.59D, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -212,6 +209,7 @@ public void ExportNonMonotonicIntSumMetric(MetricsSchema metricsSchema, string m using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -236,9 +234,7 @@ public void ExportNonMonotonicIntSumMetric(MetricsSchema metricsSchema, string m Assert.Equal(1, dataPoint.Fields.Count); AssertUtils.HasField(valueKey, -50L, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -256,6 +252,7 @@ public void ExportNonMonotonicDoubleSumMetric(MetricsSchema metricsSchema, strin using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -280,9 +277,7 @@ public void ExportNonMonotonicDoubleSumMetric(MetricsSchema metricsSchema, strin Assert.Equal(1, dataPoint.Fields.Count); AssertUtils.HasField(valueKey, -50.11D, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -303,6 +298,7 @@ public void ExportHistogramMetricWhenTelegrafPrometheusV1MetricsSchemaUsed() Boundaries = new[] { 10D, 20D, 100D, 200D }, RecordMinMax = true, }) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.WithDefaultTestConfiguration(); @@ -337,9 +333,7 @@ public void ExportHistogramMetricWhenTelegrafPrometheusV1MetricsSchemaUsed() AssertUtils.HasField("200.00", 1L, dataPoint.Fields); AssertUtils.HasField("+Inf", 1L, dataPoint.Fields); - Assert.Equal(2, dataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, dataPoint.Tags); + AssertTags(dataPoint); Assert.InRange(dataPoint.Timestamp, before, after); } @@ -395,6 +389,7 @@ public void ExportHistogramMetricWhenTelegrafPrometheusV2MetricsSchemaUsed() Boundaries = new[] { 10D, 20D, 100D, 200D }, RecordMinMax = true, }) + .ConfigureDefaultTestResource() .AddInfluxDBMetricsExporter(options => { options.Endpoint = influxServerEndpoint; @@ -422,9 +417,8 @@ public void ExportHistogramMetricWhenTelegrafPrometheusV2MetricsSchemaUsed() AssertUtils.HasField("histogram_metric_sum", 550D, headDataPoint.Fields); AssertUtils.HasField("histogram_metric_min", 50D, headDataPoint.Fields); AssertUtils.HasField("histogram_metric_max", 250D, headDataPoint.Fields); - Assert.Equal(2, headDataPoint.Tags.Count); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 0, headDataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 1, headDataPoint.Tags); + + AssertTags(headDataPoint); Assert.InRange(headDataPoint.Timestamp, before, after); AssertBucketDataPoint(influxServer.ReadPoint(), "10.00", 0); @@ -438,8 +432,15 @@ static void AssertBucketDataPoint(PointData dataPoint, string bound, long count) Assert.Equal("prometheus", dataPoint.Measurement); AssertUtils.HasField("histogram_metric_bucket", count, dataPoint.Fields); AssertUtils.HasTag("le", bound, 0, dataPoint.Tags); - AssertUtils.HasTag("tag_key_1", "tag_value_1", 1, dataPoint.Tags); - AssertUtils.HasTag("tag_key_2", "tag_value_2", 2, dataPoint.Tags); + AssertUtils.HasTag("service.instance.id", "my-service-id", 1, dataPoint.Tags); + AssertUtils.HasTag("service.name", "my-service", 2, dataPoint.Tags); + AssertUtils.HasTag("service.namespace", "my-service-namespace", 3, dataPoint.Tags); + AssertUtils.HasTag("service.version", "1.0", 4, dataPoint.Tags); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 5, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 6, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.language", "dotnet", 7, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.name", "opentelemetry", 8, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.version", "1.5.0", 9, dataPoint.Tags); } } @@ -477,4 +478,18 @@ public void ExportHistogramMetricWithoutMinMaxFieldsWhenTelegrafPrometheusV2Metr Assert.DoesNotContain("histogram_metric_min", pointData.Fields); Assert.DoesNotContain("histogram_metric_max", pointData.Fields); } + + private static void AssertTags(PointData dataPoint) + { + Assert.Equal(9, dataPoint.Tags.Count); + AssertUtils.HasTag("service.instance.id", "my-service-id", 0, dataPoint.Tags); + AssertUtils.HasTag("service.name", "my-service", 1, dataPoint.Tags); + AssertUtils.HasTag("service.namespace", "my-service-namespace", 2, dataPoint.Tags); + AssertUtils.HasTag("service.version", "1.0", 3, dataPoint.Tags); + AssertUtils.HasTag("tag_key_1", "tag_value_1", 4, dataPoint.Tags); + AssertUtils.HasTag("tag_key_2", "tag_value_2", 5, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.language", "dotnet", 6, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.name", "opentelemetry", 7, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.version", "1.5.0", 8, dataPoint.Tags); + } } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs new file mode 100644 index 0000000000..0b695a8d70 --- /dev/null +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs @@ -0,0 +1,32 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; + +public static class MeterProviderBuilderTestExtensions +{ + public static MeterProviderBuilder ConfigureDefaultTestResource(this MeterProviderBuilder meterProviderBuilder) + { + return meterProviderBuilder.ConfigureResource(builder => builder.AddService( + serviceName: "my-service", + serviceNamespace: "my-service-namespace", + serviceVersion: "1.0", + serviceInstanceId: "my-service-id")); + } +} From 0de8b8a2755b1c5079d369aa63203184703c00c8 Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Tue, 20 Jun 2023 13:19:01 +0200 Subject: [PATCH 0741/1499] [Exporter.InfluxDB] Update CHANGELOG for 1.0.0-alpha.2 release (#1246) --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 7f0b00c285..35d1ea63a3 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.2 + +Released 2023-Jun-20 + * Support for Resource attributes in OpenTelemetry.Exporter.InfluxDB, allowing resource attributes to be passed as InfluxDB tags. ([#1241](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1241)) From 3d69bfc5c3c66137ca4e30e05c2002569c65ec83 Mon Sep 17 00:00:00 2001 From: Martijn Bodeman <11424653+skwasjer@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:16:22 +0200 Subject: [PATCH 0742/1499] [Instrumentation.Hangfire] Update CHANGELOG for 1.5.0-beta.1 release (#1249) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index d694f46d6a..71b7d991d8 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.0-beta.1 + +Released 2023-Jun-23 + * Update OTel API version to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Removes `AddHangfireInstrumentation` method with default configure default parameter. From eedc92a9bc2682064c0ae5c3fda5b03209d35b57 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Tue, 27 Jun 2023 07:38:40 -0700 Subject: [PATCH 0743/1499] Remove company info from emeritus (#1254) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 59896c989d..d7a0adb7bd 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,8 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb [Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): -* [Prashant Srivastava](https://github.com/srprash), AWS -* [Sergey Kanzhelev](https://github.com/SergeyKanzhelev), Google +* [Prashant Srivastava](https://github.com/srprash) +* [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) Even though, anybody can contribute, there are benefits of being a member of our community. See to the [community membership From 73a4ca63e8e9fe9ac7ee46068a030412b6dad259 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 28 Jun 2023 21:35:39 -0700 Subject: [PATCH 0744/1499] Bump OpenTelemetry to 1.5.1 (#1255) --- NuGet.config | 2 +- build/Common.props | 2 +- .../process-instrumentation.csproj | 2 +- .../runtime-instrumentation.csproj | 2 +- .../CHANGELOG.md | 8 +++---- .../CHANGELOG.md | 19 ++++++++------- .../MsgPackExporter/MsgPackLogExporter.cs | 4 +--- .../TLDExporter/TldLogExporter.cs | 4 +--- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 8 +++---- .../CHANGELOG.md | 3 +++ .../LogRecordCommonSchemaJsonSerializer.cs | 6 ++--- ...OpenTelemetry.Exporter.OneCollector.csproj | 2 +- .../README.md | 1 - .../CHANGELOG.md | 12 +++++----- src/OpenTelemetry.Extensions/CHANGELOG.md | 3 +++ .../ActivityEventAttachingLogProcessor.cs | 6 ++--- .../OpenTelemetry.Extensions.csproj | 2 +- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 10 ++++---- .../CHANGELOG.md | 9 +++++--- .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 2 +- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 5 +++- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 13 +++++++---- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 3 +++ .../InfluxDBMetricsExporterTests.cs | 23 ++++++++++++++++--- ...ecordCommonSchemaJsonHttpPostBenchmarks.cs | 2 +- ...ogRecordCommonSchemaJsonSerializerTests.cs | 22 +++++++++++++----- ...ActivityEventAttachingLogProcessorTests.cs | 19 ++++----------- 40 files changed, 148 insertions(+), 89 deletions(-) diff --git a/NuGet.config b/NuGet.config index 51a4cc1590..1374d3c7f9 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,7 +3,7 @@ - diff --git a/build/Common.props b/build/Common.props index 56041e80cc..d40e0893ce 100644 --- a/build/Common.props +++ b/build/Common.props @@ -34,7 +34,7 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.5.0,2.0) + [1.5.1,2.0) [1.5.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj index d464f2f3b0..5316d175bc 100644 --- a/examples/process-instrumentation/process-instrumentation.csproj +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index 89ec4225f9..2aa4271dbc 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md index d478e85f5b..d65af8032b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.5.0 of OpenTelemetry SDK. - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Updates to 1.5.1 of OpenTelemetry SDK. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) * Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random instance instead of recreating with ThreadLocal ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) @@ -11,8 +11,6 @@ ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) * Replaced Newtonsoft.Json dependency with System.Text.Json ([#1092](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1092)) -* Updated OTel SDK package version to 1.3.1 - ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) * Enhancement - AWSECSResourceDetector - Implement `aws.{ecs.*,log.*}` resource attributes with data from ECS Metadata endpoint v4 ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) @@ -43,7 +41,7 @@ Released 2022-May-18 Released 2021-Sep-20 * Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) -* Updated OTel SDK package version to 1.1.0 +* Updated OpenTelemetry SDK package version to 1.1.0 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) ## 1.0.1 diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 8410c7f777..107e0c393b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.5.0 Released 2023-Jun-14 @@ -46,7 +49,7 @@ Released 2023-Jun-05 * Add support for abstract domain sockets. ([#1199](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1199)) -* Update OTel SDK version to `1.5.0-rc.1`. +* Update OpenTelemetry SDK version to `1.5.0-rc.1`. ([#1210](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1210)) ## 1.5.0-alpha.3 @@ -106,7 +109,7 @@ Released 2023-Mar-13 the connection. ([#935](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/935)) -* Update OTel SDK version to `1.5.0-alpha.1`. +* Update OpenTelemetry SDK version to `1.5.0-alpha.1`. * Update GenevaMetricExporter to use TLV format serialization. * Add support for exporting exemplars. ([#1069](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1069)) @@ -239,9 +242,9 @@ Released 2022-Oct-17 It will also not support string values that contain non-ASCII characters. [646](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/646) -* Update OTel SDK version to `1.4.0-beta.2`. Add support for exporting Histogram - Min and Max. If the histogram does not contain min and max, the exporter - exports both the values as zero. +* Update OpenTelemetry SDK version to `1.4.0-beta.2`. Add support for exporting + Histogram Min and Max. If the histogram does not contain min and max, + the exporter exports both the values as zero. [#704](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/704) ## 1.4.0-beta.1 @@ -263,7 +266,7 @@ Released 2022-Jul-28 `GenevaMetricExporter`. [397](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/397) -* Update OTel SDK version to `1.3.0`. +* Update OpenTelemetry SDK version to `1.3.0`. [427](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/427) * Remove support for .NET Framework 4.6.1. The minimum .NET Framework version @@ -337,7 +340,7 @@ NuGet. [303](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/303) is the PR that introduced this bug to GenevaMetricExporterExtensions.cs -* Update OTel SDK version to `1.2.0`. +* Update OpenTelemetry SDK version to `1.2.0`. [319](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/319) ## 1.2.4 Broken @@ -357,5 +360,5 @@ special casing "{OriginalFormat}" only. had a single KeyValuePair. [295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/295) -* Update OTel SDK version to `1.2.0-rc5`. +* Update OpenTelemetry SDK version to `1.2.0-rc5`. [308](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/308) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index be37e18b1e..302e032612 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -141,10 +141,8 @@ internal int SerializeLogRecord(LogRecord logRecord) // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 #pragma warning disable 0618 IReadOnlyList> listKvp; - if (logRecord.State == null) + if (logRecord.StateValues != null) { - // When State is null, OTel SDK guarantees StateValues is populated - // TODO: Debug.Assert? listKvp = logRecord.StateValues; } else diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 19fda3648d..37f623d2d1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -190,10 +190,8 @@ internal void SerializeLogRecord(LogRecord logRecord) // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 #pragma warning disable 0618 - if (logRecord.State == null) + if (logRecord.StateValues != null) { - // When State is null, OTel SDK guarantees StateValues is populated - // TODO: Debug.Assert? listKvp = logRecord.StateValues; } else diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 35d1ea63a3..95c765fdf0 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updates to 1.5.1 of OpenTelemetry SDK. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-alpha.2 Released 2023-Jun-20 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index bdac13a24c..79c46ad70e 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel SDK version to `1.5.0`. - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) @@ -14,7 +14,7 @@ Released 2023-Feb-21 * Fixes issue in span serialization process introduced in 1.0.2 version. ([#979](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/979)) -* Update OTel SDK version to `1.3.2`. +* Update OpenTelemetry SDK version to `1.3.2`. ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) ## 1.0.2 @@ -35,7 +35,7 @@ Released 2022-Nov-02 [376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/376) * Application is crashing if environment variables are not defined [385](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/385) -* Update OTel SDK version to `1.3.1`. +* Update OpenTelemetry SDK version to `1.3.1`. ([#749](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/749)) ## 1.0.0 diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 4de8d3d852..c8af278389 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -18,6 +18,9 @@ non-zero on `LogRecord`s. ([#1127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1127)) +* Update OpenTelemetry to 1.5.1 + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 0.1.0-alpha.2 Released 2023-Mar-6 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 2d202236b7..9ca6abf692 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -133,11 +133,11 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C string? body = null; - if (item.StateValues != null) + if (item.Attributes != null) { - for (int i = 0; i < item.StateValues.Count; i++) + for (int i = 0; i < item.Attributes.Count; i++) { - var attribute = item.StateValues[i]; + var attribute = item.Attributes[i]; if (string.IsNullOrEmpty(attribute.Key)) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 1e28454478..2990eb9ae4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index 009de85089..a0f7e85042 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -23,7 +23,6 @@ dotnet add package --prerelease OpenTelemetry.Exporter.OneCollector using var logFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(builder => { - builder.ParseStateValues = true; builder.IncludeScopes = true; builder.AddOneCollectorExporter("InstrumentationKey=instrumentation-key-here"); })); diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 24b24882a3..1bc55d3b9c 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel SDK version to `1.5.0`. - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) ## 1.0.0-beta.4 @@ -12,14 +12,14 @@ Released 2022-Dec-07 * Fix the issue of incorrect handling of null attributes. ([#566](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/566)) * Support for Google Cloud Dependencies up to 3.x.x - and OTel SDK package to 1.3.1 + and OpenTelemetry SDK package to 1.3.1 ([#794](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/794)) ## 1.0.0-beta.3 Released 2022-Jul-22 -* Updated OTel SDK package version to 1.2.0 +* Updated OpenTelemetry SDK package version to 1.2.0 * Updated minimum full framework support to net462 * Update Google.Cloud.Monitoring.V3 2.1.0 -> 2.6.0 * Update Google.Cloud.Monitoring.V3 2.0.0 -> 2.3.0 @@ -43,10 +43,10 @@ Released 2022-Jul-22 ## 1.0.0-beta1 -* Update OTel SDK package version to 1.1.0 +* Update OpenTelemetry SDK package version to 1.1.0 * Log exceptions when failing to export data to stackdriver ## Initial Release -* Updated OTel SDK package version to 1.1.0-beta1 +* Updated OpenTelemetry SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 0e618d7a3d..d082f2fbd7 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -5,6 +5,9 @@ * Add LogToActivityEventConversionOptions.Filter callback ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-beta.4 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index 33e8b2f887..249df72fcd 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -78,17 +78,17 @@ public override void OnEnd(LogRecord data) data.ForEachScope(ProcessScope, new State(tags, this)); - if (data.StateValues != null) + if (data.Attributes != null) { try { - this.options.StateConverter?.Invoke(tags, data.StateValues); + this.options.StateConverter?.Invoke(tags, data.Attributes); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { - OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing state of type [{data.State?.GetType().FullName}]", ex); + OpenTelemetryExtensionsEventSource.Log.LogProcessorException($"Processing attributes for LogRecord with CategoryName [{data.CategoryName}]", ex); } } diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index f2ad80b879..a8f69a0230 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index bfb6288753..5ef11fa761 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-rc9.9 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 4e21b155b6..2bbc9b4fb9 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.5.0 of OpenTelemetry SDK. - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Updates to 1.5.1 of OpenTelemetry SDK. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 2618057616..30f981b720 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,14 +2,14 @@ ## Unreleased -* Updated OTel SDK package version to 1.5.0 - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Updated OpenTelemetry SDK package version to 1.5.1 + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) ## 1.0.0-beta.4 Released 2023-Mar-06 -* Updated OTel SDK package version to 1.4.0 +* Updated OpenTelemetry SDK package version to 1.4.0 ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) * Update minimum full framework support to net462 * Requests that get an HTTP status code of 404 are not marked as an error span status @@ -42,10 +42,10 @@ Released 2023-Mar-06 Released 2021-June-17 -* Updated OTel SDK package version to 1.1.0-beta4 +* Updated OpenTelemetry SDK package version to 1.1.0-beta4 ([#136](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/136)) ## Initial Release -* Updated OTel SDK package version to 1.1.0-beta1 +* Updated OpenTelemetry SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index bfebdc306c..a19e674118 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -6,11 +6,14 @@ enable filtering of instrumentation. ([#1203](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1203)) +* Updated OpenTelemetry SDK package version to 1.5.1 + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-beta.7 Released 2023-Jun-09 -* Updated OTel SDK package version to 1.5.0 +* Updated OpenTelemetry SDK package version to 1.5.0 ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) ## 1.0.0-beta.6 @@ -26,14 +29,14 @@ Released 2023-Mar-13 Released 2023-Feb-27 -* Updated OTel SDK package version to 1.4.0 +* Updated OpenTelemetry SDK package version to 1.4.0 ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) ## 1.0.0-beta.4 Released 2023-Jan-25 -* Updated OTel SDK package version to 1.3.2 +* Updated OpenTelemetry SDK package version to 1.3.2 ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) * Update the `ActivitySource` name used to the assembly name: diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index e16597e215..e07a22939c 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.5.0. - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Update OpenTelemetry.Api to 1.5.1. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) ## 1.0.0-alpha.2 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 7b162124b5..828d6ce0ca 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -26,7 +26,7 @@ ## 1.0.0-beta3 -* Updated OTel SDK package version to 1.1.0-beta1 +* Updated OpenTelemetry SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) * Do NOT mutate incoming call headers, copy them before propagation diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 71b7d991d8..460fcc9780 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel API version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.5.0-beta.1 Released 2023-Jun-23 diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md index 4a55dca400..115be4a506 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md @@ -23,10 +23,10 @@ Released 2021-June-17 -* Updated OTel SDK package version to 1.1.0-beta4 +* Updated OpenTelemetry SDK package version to 1.1.0-beta4 ([#136](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/136)) ## Initial Release -* Updated OTel SDK package version to 1.1.0-beta1 +* Updated OpenTelemetry SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index aca6077d87..064e4d1035 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel API version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-beta.7 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index a2d4862520..d93af5b3fe 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OpenTelemetry SDK to 1.5.0 - ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) +* Updated OpenTelemetry SDK to 1.5.1 + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) * Removes `AddOwinInstrumentation` method with default configure parameter. ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index b6709bb926..da1fa454c7 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.5.1 + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 0.5.0-beta.3 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index a420cd9281..d4fbd92dba 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry.Api to 1.5.1. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-alpha.3 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 81ff30c13d..5e4e262ef3 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -6,6 +6,9 @@ GC for .NET 7 and greater versions ([#1239](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1239)) +* Update OpenTelemetry API to 1.5.1 + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.5.0 Released 2023-Jun-06 @@ -138,7 +141,7 @@ which are not .NET Runtime specific. ## 0.2.0-alpha.1 -* Updated OTel SDK package version to 1.3.0 +* Updated OpenTelemetry SDK package version to 1.3.0 ([#411](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/411)) * Fix some bugs in Runtime metrics ([#409](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/409)) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 8639478d93..bc017b3ad3 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OTel API version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-rc9.10 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 5b947d541e..296dc08e6c 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,18 +2,21 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-rc.10 Released 2023-Jun-09 -* Update OTel SDK version to `1.5.0`. +* Update OpenTelemetry SDK version to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) ## 1.0.0-rc.9 Released 2023-Feb-27 -* Update OTel SDK version to `1.4.0`. +* Update OpenTelemetry SDK version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) * Removes `AddWcfInstrumentation` method with default configure parameter. ([#928](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/928)) @@ -22,7 +25,7 @@ Released 2023-Feb-27 Released 2022-Dec-28 -* Update OTel SDK version to `1.3.1`. +* Update OpenTelemetry SDK version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) * Change value `rpc.system` from `wcf` to `dotnet_wcf`. ([#837](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/837)) @@ -31,7 +34,7 @@ Released 2022-Dec-28 Released 2022-Aug-23 -* Updated OTel SDK package version to 1.3.0 +* Updated OpenTelemetry SDK package version to 1.3.0 ([#569](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/569)) * Changed activity source name from `OpenTelemetry.WCF` to `OpenTelemetry.Instrumentation.Wcf` @@ -100,7 +103,7 @@ Released 2021-Sep-13 Released 2021-Jun-16 -* Updated OTel SDK package version to 1.1.0-beta1 +* Updated OpenTelemetry SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) * Added enricher for WCF activity diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index c3c3cc2a72..0422bb85ce 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -5,3 +5,6 @@ * Initial release. Previously it was part of `OpenTelemetry.Contrib.Extensions.AWSXRay` package. ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) + +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index a7091cd0ab..3e786badce 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updates to 1.5.1 of OpenTelemetry SDK. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + ## 1.0.0-beta.4 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index b50bb6dbc1..18cbfef88b 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -7,3 +7,6 @@ Initial release of `OpenTelemetry.Sampler.AWS`. * Feature - AWSXRayRemoteSampler - Add support for AWS X-Ray remote sampling ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091), [#1124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1124)) + +* Update OpenTelemetry SDK version to `1.5.1`. + ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs index 785af2ed32..b2109dd2a8 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -15,15 +15,32 @@ // using System.Diagnostics.Metrics; +using System.Reflection; using OpenTelemetry.Exporter.InfluxDB.Tests.Utils; using OpenTelemetry.Metrics; -using OpenTelemetry.Resources; using Xunit; namespace OpenTelemetry.Exporter.InfluxDB.Tests; public class InfluxDBMetricsExporterTests { + private static readonly string OpenTelemetrySdkVersion; + +#pragma warning disable CA1810 // Initialize reference type static fields inline + static InfluxDBMetricsExporterTests() +#pragma warning restore CA1810 // Initialize reference type static fields inline + { + var sdkVersion = typeof(Sdk).Assembly.GetCustomAttribute()?.Version; + if (sdkVersion != null) + { + OpenTelemetrySdkVersion = Version.Parse(sdkVersion).ToString(3); + } + else + { + OpenTelemetrySdkVersion = "0.0.0"; + } + } + [Theory] [InlineData(MetricsSchema.TelegrafPrometheusV1, "test-gauge", "gauge")] [InlineData(MetricsSchema.TelegrafPrometheusV2, "prometheus", "test-gauge")] @@ -440,7 +457,7 @@ static void AssertBucketDataPoint(PointData dataPoint, string bound, long count) AssertUtils.HasTag("tag_key_2", "tag_value_2", 6, dataPoint.Tags); AssertUtils.HasTag("telemetry.sdk.language", "dotnet", 7, dataPoint.Tags); AssertUtils.HasTag("telemetry.sdk.name", "opentelemetry", 8, dataPoint.Tags); - AssertUtils.HasTag("telemetry.sdk.version", "1.5.0", 9, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.version", OpenTelemetrySdkVersion, 9, dataPoint.Tags); } } @@ -490,6 +507,6 @@ private static void AssertTags(PointData dataPoint) AssertUtils.HasTag("tag_key_2", "tag_value_2", 5, dataPoint.Tags); AssertUtils.HasTag("telemetry.sdk.language", "dotnet", 6, dataPoint.Tags); AssertUtils.HasTag("telemetry.sdk.name", "opentelemetry", 7, dataPoint.Tags); - AssertUtils.HasTag("telemetry.sdk.version", "1.5.0", 8, dataPoint.Tags); + AssertUtils.HasTag("telemetry.sdk.version", OpenTelemetrySdkVersion, 8, dataPoint.Tags); } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index 1fc6e46c24..05762f02a2 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -114,7 +114,7 @@ private static LogRecord CreateLogRecord(int index) logRecord.EventId = new EventId(1); } - logRecord.StateValues = new List> + logRecord.Attributes = new List> { new KeyValuePair("userId", 18), new KeyValuePair("greeting", "hello world"), diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index a42e14d2db..80a1894ada 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -114,7 +114,7 @@ public void LogRecordOriginalFormatBodyJsonTest() { string json = GetLogRecordJson(1, (index, logRecord) => { - logRecord.StateValues = new List> { new KeyValuePair("{OriginalFormat}", "hello world") }; + logRecord.Attributes = new List> { new KeyValuePair("{OriginalFormat}", "hello world") }; logRecord.FormattedMessage = "goodbye world"; }); @@ -173,7 +173,7 @@ public void LogRecordStateValuesJsonTest() { string json = GetLogRecordJson(1, (index, logRecord) => { - logRecord.StateValues = new List> { new KeyValuePair("stateKey1", "stateValue1"), new KeyValuePair("stateKey2", "stateValue2") }; + logRecord.Attributes = new List> { new KeyValuePair("stateKey1", "stateValue1"), new KeyValuePair("stateKey2", "stateValue2") }; }); Assert.Equal( @@ -238,7 +238,7 @@ public void LogRecordExtensionsJsonTest() 1, (index, logRecord) => { - logRecord.StateValues = new List> { new KeyValuePair("ext.state.field", "stateValue1") }; + logRecord.Attributes = new List> { new KeyValuePair("ext.state.field", "stateValue1") }; }, resource, scopeProvider); @@ -272,10 +272,20 @@ private static string GetLogRecordJson( if (scopeProvider != null) { - var setScopeProviderMethod = typeof(LogRecord).GetProperty("ScopeProvider", BindingFlags.Instance | BindingFlags.NonPublic)?.SetMethod - ?? throw new InvalidOperationException("LogRecord.ScopeProvider.Set could not be found reflectively."); + var logRecordILoggerDataType = typeof(LogRecord).Assembly.GetType("OpenTelemetry.Logs.LogRecord+LogRecordILoggerData") + ?? throw new InvalidOperationException("OpenTelemetry.Logs.LogRecord+LogRecordILoggerData could not be found reflectively."); - setScopeProviderMethod.Invoke(logRecord, new object[] { scopeProvider }); + var iLoggerDataField = typeof(LogRecord).GetField("ILoggerData", BindingFlags.Instance | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("LogRecord.ILoggerData could not be found reflectively."); + + var scopeProviderField = logRecordILoggerDataType.GetField("ScopeProvider", BindingFlags.Instance | BindingFlags.Public) + ?? throw new InvalidOperationException("LogRecordILoggerData.ScopeProvider could not be found reflectively."); + + var iLoggerData = iLoggerDataField.GetValue(logRecord); + + scopeProviderField.SetValue(iLoggerData, scopeProvider); + + iLoggerDataField.SetValue(logRecord, iLoggerData); } writeLogRecordCallback(i, logRecord); diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index e0a787ba73..c5cd3af1c1 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -55,15 +55,14 @@ public void Dispose() [Theory] [InlineData(true)] [InlineData(false)] - [InlineData(true, 18, true, true, true)] - [InlineData(true, 0, false, false, true, true)] - [InlineData(true, 18, true, true, true, false, true)] - [InlineData(true, 0, false, false, true, true, true)] + [InlineData(true, 18, true, true)] + [InlineData(true, 0, false, true, true)] + [InlineData(true, 18, true, true, false, true)] + [InlineData(true, 0, false, true, true, true)] public void AttachLogsToActivityEventTest( bool sampled, int eventId = 0, bool includeFormattedMessage = false, - bool parseStateValues = false, bool includeScopes = false, bool recordException = false, bool? filter = null) @@ -76,7 +75,6 @@ public void AttachLogsToActivityEventTest( { options.IncludeScopes = includeScopes; options.IncludeFormattedMessage = includeFormattedMessage; - options.ParseStateValues = parseStateValues; options.AttachLogsToActivityEvent(x => { x.Filter = filter switch @@ -142,14 +140,7 @@ public void AttachLogsToActivityEventTest( Assert.DoesNotContain(tags, kvp => kvp.Key == nameof(LogRecord.FormattedMessage)); } - if (parseStateValues) - { - Assert.Equal(8, tags["state.UserId"]); - } - else - { - Assert.DoesNotContain(tags, kvp => kvp.Key == "state.UserId"); - } + Assert.Equal(8, tags["state.UserId"]); if (includeScopes) { From 59cc8cbc1311a44ea4bc63ab4f0c94ca10d7dbea Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 29 Jun 2023 15:42:15 -0700 Subject: [PATCH 0745/1499] [Exporter.Geneva] Update CHANGELOG for 1.5.1 (#1256) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 107e0c393b..9b1b05df86 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.1 + +Released 2023-Jun-29 + * Update OpenTelemetry SDK version to `1.5.1`. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) From 4d7e692ecc50a01f6cef76ef9ea61ac738b000df Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 29 Jun 2023 16:11:43 -0700 Subject: [PATCH 0746/1499] [Exporter.OneCollector] Update CHANGELOG for 1.5.1-rc.1 (#1257) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index c8af278389..fc6890ea8c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.1-rc.1 + +Released 2023-Jun-29 + * Added support for sending common schema extensions using `ext.[name].[field]` syntax. ([#1073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1073)) From 13c14fcc24ffe9f3fd0cbe3485d6755037cb2d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 5 Jul 2023 20:52:43 +0200 Subject: [PATCH 0747/1499] Nuget badges in readme.md (#1259) --- CONTRIBUTING.md | 4 ++-- src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md | 3 +++ src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md | 3 +++ src/OpenTelemetry.Exporter.Geneva/README.md | 4 ++-- src/OpenTelemetry.Exporter.InfluxDB/README.md | 4 ++-- src/OpenTelemetry.Exporter.Instana/README.md | 4 ++-- src/OpenTelemetry.Exporter.OneCollector/README.md | 4 ++-- src/OpenTelemetry.Exporter.Stackdriver/README.md | 4 ++-- src/OpenTelemetry.Extensions.AzureMonitor/README.md | 4 ++-- src/OpenTelemetry.Extensions.Enrichment/README.md | 4 ++-- src/OpenTelemetry.Extensions/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.AWSLambda/README.md | 3 +++ .../README.md | 4 ++-- src/OpenTelemetry.Instrumentation.AspNet/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Cassandra/README.md | 3 +++ .../README.md | 4 ++-- .../README.md | 4 ++-- src/OpenTelemetry.Instrumentation.EventCounters/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.GrpcCore/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Hangfire/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.MassTransit/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.MySqlData/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Owin/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Process/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Quartz/README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Runtime/README.md | 4 ++-- .../README.md | 4 ++-- src/OpenTelemetry.Instrumentation.Wcf/README.md | 4 ++-- src/OpenTelemetry.PersistentStorage.Abstractions/README.md | 4 ++-- src/OpenTelemetry.PersistentStorage.FileSystem/README.md | 4 ++-- src/OpenTelemetry.ResourceDetectors.AWS/README.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Azure/README.md | 4 ++-- src/OpenTelemetry.ResourceDetectors.Container/README.md | 3 +++ src/OpenTelemetry.Sampler.AWS/README.md | 4 ++-- 34 files changed, 74 insertions(+), 56 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68de883fc0..b0b6b283b7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -255,6 +255,6 @@ the main branch. The workflow file should be named as package. You can use the below snippet for reference: ```md -[![NuGet](https://img.shields.io/nuget/v/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) -[![NuGet](https://img.shields.io/nuget/dt/{your_package_name}.svg)](https://www.nuget.org/packages/{your_package_name}) +[![NuGet version badge](https://img.shields.io/nuget/v/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) +[![NuGet download count badge](https://img.shields.io/nuget/dt/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) ``` diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md index 25faacb78e..21a9ef7a76 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md +++ b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md @@ -1,5 +1,8 @@ # Tracing with AWS Distro for OpenTelemetry .Net SDK +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Extensions.AWSXRay)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Extensions.AWSXRay) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Contrib.Extensions.AWSXRay)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Extensions.AWSXRay) + If you want to send the traces to AWS X-Ray, you can do so by using AWS Distro with the OpenTelemetry SDK. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md b/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md index 1f877d727f..63cf30a491 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md +++ b/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md @@ -1,5 +1,8 @@ # AWS SDK client instrumentation for OpenTelemetry +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.AWS) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Contrib.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.AWS) + Download the `OpenTelemetry.Contrib.Instrumentation.AWS` package: ```shell diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index ebd5b8dce6..f5e1417b80 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -1,7 +1,7 @@ # Geneva Exporter for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) The Geneva Exporter exports telemetry to [Event Tracing for Windows (ETW)](https://docs.microsoft.com/windows/win32/etw/about-event-tracing) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/README.md b/src/OpenTelemetry.Exporter.InfluxDB/README.md index 550a380c6d..4bedc318bb 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/README.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/README.md @@ -1,7 +1,7 @@ # InfluxDB Exporter for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.InfluxDB.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.InfluxDB.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) The InfluxDB exporter converts OpenTelemetry metrics into the InfluxDB model following the [OpenTelemetry->InfluxDB conversion schema](https://github.com/influxdata/influxdb-observability/blob/main/docs/index.md). diff --git a/src/OpenTelemetry.Exporter.Instana/README.md b/src/OpenTelemetry.Exporter.Instana/README.md index f9a3afd5af..5e4646da5c 100644 --- a/src/OpenTelemetry.Exporter.Instana/README.md +++ b/src/OpenTelemetry.Exporter.Instana/README.md @@ -1,7 +1,7 @@ # Instana Exporter for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Instana.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) The Instana Exporter exports telemetry to Instana backend. diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index a0f7e85042..fa9612ac9c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -1,7 +1,7 @@ # OneCollector Exporter for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) > **Warning** > This is an early preview version breaking changes should be expected. diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 69d6a3fcbf..a967edfe63 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -1,7 +1,7 @@ # Stackdriver Exporter for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Stackdriver.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Stackdriver.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) **NOTE: This exporter is not affiliated with or officially supported by Google.** diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/README.md b/src/OpenTelemetry.Extensions.AzureMonitor/README.md index 240aa20b5c..225b1fa9af 100644 --- a/src/OpenTelemetry.Extensions.AzureMonitor/README.md +++ b/src/OpenTelemetry.Extensions.AzureMonitor/README.md @@ -1,7 +1,7 @@ # Application Insights Sampler for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AzureMonitor.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.AzureMonitor.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AzureMonitor)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.AzureMonitor)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) The ```Application Insights Sampler``` should be utilized when compatibility with Application Insights SDKs is desired, as it diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index 312a71775e..048c3826c5 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -1,7 +1,7 @@ # OpenTelemetry .NET SDK telemetry enrichment framework -[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Enrichment.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.Enrichment.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) Contains OpenTelemetry .NET SDK telemetry enrichment framework which is used for enrichment of traces. diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index f58476e242..2111fe4f43 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -1,7 +1,7 @@ # OpenTelemetry .NET SDK preview features and extensions -[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.svg)](https://www.nuget.org/packages/OpenTelemetry.Extensions) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) Contains useful features and extensions to the OpenTelemetry .NET SDK that are not part of the official OpenTelemetry specification but might be added in the diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index a41913b46d..cf72816a6a 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -1,5 +1,8 @@ # AWS OTel .NET SDK for Lambda +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) + This repo contains SDK to instrument Lambda handler to create incoming span. ## Installation diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index af2173796b..9de87bd45c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -1,7 +1,7 @@ # ASP.NET Telemetry HttpModule for OpenTelemetry -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) The ASP.NET Telemetry HttpModule enables distributed tracing of incoming ASP.NET requests using the OpenTelemetry API. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index a16fa6a76d..bdeb5cf728 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -1,7 +1,7 @@ # ASP.NET Instrumentation for OpenTelemetry -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index c8612dad6a..7ab0e77cc3 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -1,5 +1,8 @@ # Cassandra Instrumentation for OpenTelemetry +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) + This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), which instruments [CassandraCSharpDriver](https://github.com/datastax/csharp-driver) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 95934edaf5..dab6a9a2d2 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -2,8 +2,8 @@ ## NEST/Elasticsearch.Net -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ElasticsearchClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ElasticsearchClient)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index aaca89c2ce..9d04c7deaa 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -1,7 +1,7 @@ # EntityFrameworkCore Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EntityFrameworkCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index 1be4d33fab..5c6b710803 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -1,7 +1,7 @@ # EventCounters Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EventCounters.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md index 73be2ba56d..e2c8554568 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -1,7 +1,7 @@ # gRPC Core-based Client and Server Interceptors for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) Adds OpenTelemetry instrumentation for gRPC Core-based client and server calls. diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index ec0f79a22b..72392c219b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -1,7 +1,7 @@ # Hangfire Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Hangfire.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Hangfire.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md index 159adc9558..b46e315a88 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -1,7 +1,7 @@ # MassTransit Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.MassTransit.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.MassTransit.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.MassTransit)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.MassTransit)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MassTransit) Automatically instruments [DiagnosticSource](https://masstransit-project.com/advanced/monitoring/diagnostic-source.html) diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index 02f0fcf9e9..e9bfb9a907 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -1,7 +1,7 @@ # MySqlData Instrumentation for OpenTelemetry -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.MySqlData.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.MySqlData.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.MySqlData)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.MySqlData)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.MySqlData) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index 80b82a750b..a5172d1b49 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -1,7 +1,7 @@ # OWIN Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Owin.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 83686c293b..5b8d52e277 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -1,7 +1,7 @@ # Process Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Process.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Process.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 06653ecda6..84618541ea 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -1,7 +1,7 @@ # QuartzNET Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) Automatically instruments the Quartz jobs from [Quartz](https://www.nuget.org/packages/Quartz/). diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 20ff2da435..5ffc84e490 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -1,7 +1,7 @@ # Runtime Instrumentation for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Runtime.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index d5ccbcc3de..4784ef3175 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -1,7 +1,7 @@ # StackExchange.Redis Instrumentation for OpenTelemetry -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.StackExchangeRedis.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.StackExchangeRedis.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 9389335bd8..117b2092fa 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -1,7 +1,7 @@ # WCF Instrumentation for OpenTelemetry .NET -[![nuget](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) -[![nuget](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Wcf.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) Instruments WCF clients and/or services using implementations of `IClientMessageInspector` and `IDispatchMessageInspector` respectively. diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 203dee2780..8a14ca569d 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -1,7 +1,7 @@ # Persistent Storage Abstractions -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.Abstractions.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) This package includes APIs which can be extended by exporter owners to implement persistent storage. diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index e77c011d73..205c049ddc 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -1,7 +1,7 @@ # Persistent Storage file based implementation -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem.svg)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) This package provides an implementation of [persistent-storage-abstractions](../OpenTelemetry.PersistentStorage.Abstractions/README.md#Persistent-Storage-Abstractions) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/README.md b/src/OpenTelemetry.ResourceDetectors.AWS/README.md index 525cbb75f4..1ea07982f0 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/README.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/README.md @@ -1,5 +1,8 @@ # AWS Resource Detectors +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.AWS)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.AWS) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.AWS)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.AWS) + ## Getting Started You need to install the diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index e2cd8b8b0c..60b36e3a1f 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -1,7 +1,7 @@ # Resource Detectors for Azure cloud environments -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Azure.svg)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Azure.svg)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Azure)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Azure)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) This package contains [Resource Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/README.md b/src/OpenTelemetry.ResourceDetectors.Container/README.md index 3c6f251b42..af03c25d22 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/README.md @@ -1,5 +1,8 @@ # Container Resource Detectors +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Container)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Container) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Container)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Container) + ## Getting Started You need to install the diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md index 0ed8bb6d43..8dc2b4b023 100644 --- a/src/OpenTelemetry.Sampler.AWS/README.md +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -1,7 +1,7 @@ # AWS X-Ray Remote Sampler -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Sampler.AWS.svg)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Sampler.AWS.svg)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) This package provides a sampler which can get sampling configurations from AWS X-Ray to make sampling decisions. From e602753ab1a170053c7290c0486717b2177051bf Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Mon, 10 Jul 2023 13:22:17 -0700 Subject: [PATCH 0748/1499] [EventCounters] fix deadlock (#1260) --- .../CHANGELOG.md | 6 ++++++ .../EventCountersMetrics.cs | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index e07a22939c..99474301c4 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Added a static constructor to ensure `EventCountersInstrumentationEventSource` +got initialized when `EventCountersMetrics` was accessed for the first time to +prevent potential deadlock; +e.g.: . + ([#1260](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1260)) + * Update OpenTelemetry.Api to 1.5.1. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index d39b8dd44b..d2a4d15ba1 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -40,6 +40,14 @@ internal sealed class EventCountersMetrics : EventListener private readonly ConcurrentDictionary<(string, string), double> values = new(); private bool isDisposed; + static EventCountersMetrics() + { + // Ensure EventCountersInstrumentationEventSource got initialized when the class was accessed for the first time + // to prevent potential deadlock: + // https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1024. + _ = EventCountersInstrumentationEventSource.Log; + } + /// /// Initializes a new instance of the class. /// From 81ffe7d443e238511aaeacbf0faf9d14caebd88c Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Tue, 11 Jul 2023 14:25:38 -0700 Subject: [PATCH 0749/1499] [Instrumentation.EventCounters] Release EventCounters instrumentation version 1.5.1-alpha.1 (#1262) --- .../CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 99474301c4..3d916e40a1 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,15 @@ ## Unreleased +## 1.5.1-alpha.1 + +Released 2023-Jul-11 + +* Bumped the package version to `1.5.1-alpha.1` to keep its major and minor + version in sync with that of the core packages. This would make it more + intuitive for users to figure out what version of core packages would work + with a given version of this package. + * Added a static constructor to ensure `EventCountersInstrumentationEventSource` got initialized when `EventCountersMetrics` was accessed for the first time to prevent potential deadlock; From 6514ec7cefe36631e3eb0f8756fc52b1ff154422 Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:09:29 +0200 Subject: [PATCH 0750/1499] [OpenTelemetry.Instrumentation.AWSLambda]: consider two sources when setting http.method and http.target: original request and request context. (#1261) --- .../Implementation/AWSLambdaHttpUtils.cs | 5 ++-- .../Implementation/AWSLambdaHttpUtilsTests.cs | 26 ++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index 0982d20c9b..2e2d7747e4 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -44,8 +44,9 @@ internal static IEnumerable> GetHttpTags(TI { case APIGatewayProxyRequest request: httpScheme = AWSLambdaUtils.GetHeaderValues(request, HeaderXForwardedProto)?.LastOrDefault(); - httpTarget = string.Concat(request.RequestContext?.Path ?? string.Empty, GetQueryString(request)); - httpMethod = request.HttpMethod; + var path = request.RequestContext?.Path ?? request.Path ?? string.Empty; + httpTarget = string.Concat(path, GetQueryString(request)); + httpMethod = request.RequestContext?.HttpMethod ?? request.HttpMethod; var hostHeader = AWSLambdaUtils.GetHeaderValues(request, HeaderHost)?.LastOrDefault(); (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeader); break; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 95cb609358..3861ec8414 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -38,13 +38,13 @@ public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() { "X-Forwarded-Proto", new List { "https" } }, { "Host", new List { "localhost:1234" } }, }, - HttpMethod = "GET", MultiValueQueryStringParameters = new Dictionary> { { "q1", new[] { "value1" } }, }, RequestContext = new APIGatewayProxyRequest.ProxyRequestContext { + HttpMethod = "GET", Path = "/path/test", }, }; @@ -63,6 +63,30 @@ public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() AssertTags(expectedTags, actualTags); } + [Fact] + public void GetHttpTags_APIGatewayProxyRequestWithEmptyContext_ReturnsTagsFromRequest() + { + var request = new APIGatewayProxyRequest + { + MultiValueQueryStringParameters = new Dictionary> + { + { "q1", new[] { "value1" } }, + }, + HttpMethod = "POST", + Path = "/path/test", + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.method", "POST" }, + { "http.target", "/path/test?q1=value1" }, + }; + + AssertTags(expectedTags, actualTags); + } + [Fact] public void GetHttpTags_APIGatewayProxyRequestWithMultiValueHeader_UsesLastValue() { From 810e381e6df6471f8cfb4c51af4e6e55a990ddaf Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 12 Jul 2023 17:05:14 -0700 Subject: [PATCH 0751/1499] [Exporter.Geneva] Add Exemplar support back (#1264) --- build/Common.props | 2 +- .../CHANGELOG.md | 6 +++++ .../Metrics/GenevaMetricExporter.cs | 16 +++++++++---- .../MsgPackExporter/MsgPackLogExporter.cs | 4 ++++ .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../TLDExporter/TldLogExporter.cs | 5 ++++ .../Exporter/MetricExporterBenchmarks.cs | 4 ++++ .../GenevaLogExporterTests.cs | 4 ++++ .../GenevaMetricExporterTests.cs | 23 ++++++++++++------- 9 files changed, 51 insertions(+), 15 deletions(-) diff --git a/build/Common.props b/build/Common.props index d40e0893ce..168c874a81 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,7 +35,7 @@ [3.3.3] [1.1.1,2.0) [1.5.1,2.0) - [1.5.0-rc.1] + [1.6.0-alpha.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.435,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 9b1b05df86..20f471d705 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.6.0-alpha.1`. + ([#1264](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1264)) + +* Add back support for exporting `Exemplar`. + ([#1264](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1264)) + ## 1.5.1 Released 2023-Jun-29 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 8da5adb605..6cf233a685 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -122,7 +122,7 @@ public override ExportResult Export(in Batch batch) { try { - // var exemplars = metricPoint.GetExemplars(); + var exemplars = metricPoint.GetExemplars(); switch (metric.MetricType) { @@ -136,6 +136,7 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp metricPoint.Tags, metricData, + exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -155,6 +156,7 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -174,6 +176,7 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -191,6 +194,7 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -207,6 +211,7 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -232,6 +237,7 @@ public override ExportResult Export(in Batch batch) count, min, max, + exemplars, out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -295,6 +301,7 @@ internal unsafe ushort SerializeMetricWithTLV( long timestamp, in ReadOnlyTagCollection tags, MetricData value, + Exemplar[] exemplars, out string monitoringAccount, out string metricNamespace) { @@ -321,7 +328,7 @@ internal unsafe ushort SerializeMetricWithTLV( out monitoringAccount, out metricNamespace); - // SerializeExemplars(exemplars, this.buffer, ref bufferIndex); + SerializeExemplars(exemplars, this.buffer, ref bufferIndex); SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -354,6 +361,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( uint count, double min, double max, + Exemplar[] exemplars, out string monitoringAccount, out string metricNamespace) { @@ -380,7 +388,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( out monitoringAccount, out metricNamespace); - // SerializeExemplars(exemplars, this.buffer, ref bufferIndex); + SerializeExemplars(exemplars, this.buffer, ref bufferIndex); SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -425,7 +433,6 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); } - /* Commenting out Exemplar related code as it's removed from `1.5.0` stable version of OpenTelemetry SDK [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) { @@ -541,7 +548,6 @@ private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, re var exemplarLength = bufferIndex - bufferIndexForLength + 1; MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); } - */ [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 302e032612..9dcb291b18 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -245,7 +245,11 @@ internal int SerializeLogRecord(LogRecord logRecord) } // Part B + + // `LogRecord.LogLevel` was marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4568 +#pragma warning disable 0618 var logLevel = logRecord.LogLevel; +#pragma warning restore 0618 cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityText"); cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logLevels[(int)logLevel]); diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index e9ab3a2a3c..93599774e7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 37f623d2d1..46cc2cefb0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -293,7 +293,12 @@ internal void SerializeLogRecord(LogRecord logRecord) byte partBFieldsCount = 4; var partBFieldsCountPatch = eb.AddStruct("PartB", partBFieldsCount); // We at least have three fields in Part B: _typeName, severityText, severityNumber, name eb.AddCountedString("_typeName", "Log"); + + // `LogRecord.LogLevel` was marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4568 +#pragma warning disable 0618 var logLevel = logRecord.LogLevel; +#pragma warning restore 0618 + eb.AddCountedString("severityText", logLevels[(int)logLevel]); eb.AddUInt8("severityNumber", GetSeverityNumber(logLevel)); eb.AddCountedAnsiString("name", categoryName, Encoding.UTF8); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index d41fbcd08e..976ae3d584 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -566,6 +566,7 @@ public void SerializeCounterMetricItemWith3Dimensions() this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, + Array.Empty(), out _, out _); } @@ -579,6 +580,7 @@ public void SerializeCounterMetricItemWith4Dimensions() this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, + Array.Empty(), out _, out _); } @@ -607,6 +609,7 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramCountWith3Dimensions, this.histogramMinWith3Dimensions, this.histogramMaxWith3Dimensions, + Array.Empty(), out _, out _); } @@ -623,6 +626,7 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramCountWith4Dimensions, this.histogramMinWith4Dimensions, this.histogramMaxWith4Dimensions, + Array.Empty(), out _, out _); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index cd3554260e..e2b5f5d8f8 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1352,8 +1352,12 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter } // Part B fields + + // `LogRecord.LogLevel` was marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4568 +#pragma warning disable 0618 Assert.Equal(logRecord.LogLevel.ToString(), mapping["severityText"]); Assert.Equal((byte)(((int)logRecord.LogLevel * 4) + 1), mapping["severityNumber"]); +#pragma warning restore 0618 Assert.Equal(logRecord.CategoryName, mapping["name"]); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 6ff8011b97..cb67c04142 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -196,13 +196,14 @@ public void SuccessfulExportOnLinux() var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; - // var exemplars = metricPoint.GetExemplars(); + var exemplars = metricPoint.GetExemplars(); var bodyLength = exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -353,7 +354,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars if (hasExemplars) { - // meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); + meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); } if (hasFilteredTagsForExemplars) @@ -949,7 +950,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - // var exemplars = metricPoint.GetExemplars(); + var exemplars = metricPoint.GetExemplars(); List fields = null; @@ -964,6 +965,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -989,6 +991,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1016,6 +1019,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1043,6 +1047,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1077,6 +1082,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, count, min, max, + exemplars, out _, out _); @@ -1115,7 +1121,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(bodyLength, data.LenBody); } - /* if (exemplars.Length > 0) { var validExemplars = exemplars.Where(exemplar => exemplar.Timestamp != default).ToList(); @@ -1137,7 +1142,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, AssertExemplarFilteredTagSerialization(expectedExemplar, serializedExemplar); } } - */ // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); @@ -1210,7 +1214,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(dimensionsCount, dimensions.NumDimensions); } - /* private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExemplar, SingleExemplar serializedExemplar) { var serializedExemplarBody = serializedExemplar.Body; @@ -1260,7 +1263,6 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem } } } - */ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter exporter) { @@ -1269,7 +1271,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - // var exemplars = metricPoint.GetExemplars(); + var exemplars = metricPoint.GetExemplars(); UserdataV2 result = null; if (metricType == MetricType.LongSum) @@ -1282,6 +1284,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1300,6 +1303,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1320,6 +1324,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1340,6 +1345,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, + exemplars, out _, out _); @@ -1367,6 +1373,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter count, min, max, + exemplars, out _, out _); From 7776ae51f3cc211469de4cfd7c3155f30265526e Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 12 Jul 2023 17:29:06 -0700 Subject: [PATCH 0752/1499] [Exporter.Geneva] Update CHANGELOG for 1.6.0-alpha.1 (#1265) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 20f471d705..7809971cac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-alpha.1 + +Released 2023-Jul-12 + * Update OpenTelemetry SDK version to `1.6.0-alpha.1`. ([#1264](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1264)) From e2489e9b865a2dadaa8a7ea2aef58a95314ede1f Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 14 Jul 2023 16:02:43 -0700 Subject: [PATCH 0753/1499] Remove Extensions.AzureMonitor (#1244) --- .../comp_extensions_azuremonitor.md | 41 ------- .github/component_owners.yml | 6 - .../package-Extensions.AzureMonitor.yml | 67 ---------- opentelemetry-dotnet-contrib.sln | 20 +-- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net462/PublicAPI.Unshipped.txt | 7 -- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 7 -- .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 7 -- .../ApplicationInsightsSampler.cs | 114 ------------------ .../ApplicationInsightsSamplerOptions.cs | 30 ----- .../CHANGELOG.md | 43 ------- ...enTelemetry.Extensions.AzureMonitor.csproj | 21 ---- .../README.md | 30 ----- .../ApplicationInsightsSamplerTests.cs | 94 --------------- ...metry.Extensions.AzureMonitor.Tests.csproj | 24 ---- 17 files changed, 3 insertions(+), 511 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md delete mode 100644 .github/workflows/package-Extensions.AzureMonitor.yml delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj delete mode 100644 src/OpenTelemetry.Extensions.AzureMonitor/README.md delete mode 100644 test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs delete mode 100644 test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md b/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md deleted file mode 100644 index ced841fd38..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_extensions_azuremonitor.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Extensions.AzureMonitor -about: Issue with OpenTelemetry.Extensions.AzureMonitor -labels: comp:extensions.azuremonitor ---- - -# Issue with OpenTelemetry.Extensions.AzureMonitor - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 95df28fb23..1b5c18d9f6 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -26,9 +26,6 @@ components: - SergeyKanzhelev src/OpenTelemetry.Extensions/: - codeblanch - src/OpenTelemetry.Extensions.AzureMonitor/: - - rajkumar-rangaraj - - vishweshbankwar src/OpenTelemetry.Extensions.Enrichment/: - xakep139 src/OpenTelemetry.PersistentStorage.Abstractions/: @@ -111,9 +108,6 @@ components: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: - codeblanch - test/OpenTelemetry.Extensions.AzureMonitor.Tests/: - - rajkumar-rangaraj - - vishweshbankwar test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: diff --git a/.github/workflows/package-Extensions.AzureMonitor.yml b/.github/workflows/package-Extensions.AzureMonitor.yml deleted file mode 100644 index c79ea529bc..0000000000 --- a/.github/workflows/package-Extensions.AzureMonitor.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Pack OpenTelemetry.Extensions.AzureMonitor - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'Extensions.AzureMonitor-*' # trigger when we create a tag with prefix "Extensions.AzureMonitor-" - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - permissions: - contents: write - env: - PROJECT: OpenTelemetry.Extensions.AzureMonitor - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # fetching all - - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions.AzureMonitor has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index eb25c80b53..040f18b316 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -146,10 +146,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{970B604C-C57F-4767-A080-67976E69F76E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor", "src\OpenTelemetry.Extensions.AzureMonitor\OpenTelemetry.Extensions.AzureMonitor.csproj", "{426D8AE8-EC39-48EA-AC66-1BF84C4CE529}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AzureMonitor.Tests", "test\OpenTelemetry.Extensions.AzureMonitor.Tests\OpenTelemetry.Extensions.AzureMonitor.Tests.csproj", "{47ABABE1-62CC-4655-AA95-352F4DC20C96}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" @@ -288,13 +284,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS.Tests", "test\OpenTelemetry.ResourceDetectors.AWS.Tests\OpenTelemetry.ResourceDetectors.AWS.Tests.csproj", "{DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.InfluxDB", "src\OpenTelemetry.Exporter.InfluxDB\OpenTelemetry.Exporter.InfluxDB.csproj", "{FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.InfluxDB", "src\OpenTelemetry.Exporter.InfluxDB\OpenTelemetry.Exporter.InfluxDB.csproj", "{FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Exporter.InfluxDB.Tests", "test\OpenTelemetry.Exporter.InfluxDB.Tests\OpenTelemetry.Exporter.InfluxDB.Tests.csproj", "{4847A991-D0C3-4421-B0D3-EA189959E639}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.InfluxDB.Tests", "test\OpenTelemetry.Exporter.InfluxDB.Tests\OpenTelemetry.Exporter.InfluxDB.Tests.csproj", "{4847A991-D0C3-4421-B0D3-EA189959E639}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InfluxDB", "InfluxDB", "{2D354354-BAFB-490B-A26F-6A16A52A1A45}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.InfluxDB", "examples\InfluxDB\Examples.InfluxDB\Examples.InfluxDB.csproj", "{B4951583-D432-4E87-85CF-498FDD6A35E6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.InfluxDB", "examples\InfluxDB\Examples.InfluxDB\Examples.InfluxDB.csproj", "{B4951583-D432-4E87-85CF-498FDD6A35E6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -378,14 +374,6 @@ Global {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.Build.0 = Debug|Any CPU {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.ActiveCfg = Release|Any CPU {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.Build.0 = Release|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Debug|Any CPU.Build.0 = Debug|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.ActiveCfg = Release|Any CPU - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529}.Release|Any CPU.Build.0 = Release|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47ABABE1-62CC-4655-AA95-352F4DC20C96}.Release|Any CPU.Build.0 = Release|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -652,8 +640,6 @@ Global {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {426D8AE8-EC39-48EA-AC66-1BF84C4CE529} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {47ABABE1-62CC-4655-AA95-352F4DC20C96} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index 05811804ba..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,7 +0,0 @@ -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions! options) -> void -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.ApplicationInsightsSamplerOptions() -> void -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.get -> float -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.set -> void -override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 05811804ba..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,7 +0,0 @@ -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions! options) -> void -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.ApplicationInsightsSamplerOptions() -> void -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.get -> float -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.set -> void -override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 05811804ba..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,7 +0,0 @@ -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ApplicationInsightsSampler(OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions! options) -> void -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.ApplicationInsightsSamplerOptions() -> void -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.get -> float -OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSamplerOptions.SamplingRatio.set -> void -override OpenTelemetry.Extensions.AzureMonitor.ApplicationInsightsSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs deleted file mode 100644 index e1501d439d..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSampler.cs +++ /dev/null @@ -1,114 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -using System; -using System.Collections.Generic; -using OpenTelemetry.Internal; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Extensions.AzureMonitor; - -/// -/// Sample configurable for OpenTelemetry exporters for compatibility -/// with Application Insight SDKs. -/// -public class ApplicationInsightsSampler : Sampler -{ - private static readonly SamplingResult RecordOnlySamplingResult = new(SamplingDecision.RecordOnly); - private readonly SamplingResult recordAndSampleSamplingResult; - private readonly float samplingRatio; - - /// - /// Initializes a new instance of the class. - /// - /// - /// for configuring the ApplicationInsightsSampler. - /// - public ApplicationInsightsSampler(ApplicationInsightsSamplerOptions options) - { - Guard.ThrowIfNull(options); - - // Ensure passed ratio is between 0 and 1, inclusive - Guard.ThrowIfOutOfRange((double)options.SamplingRatio, min: 0.0, max: 1.0); - - this.samplingRatio = options.SamplingRatio; - this.Description = "ApplicationInsightsSampler{" + options.SamplingRatio + "}"; - var sampleRate = (float)Math.Round(options.SamplingRatio * 100); - this.recordAndSampleSamplingResult = new SamplingResult( - SamplingDecision.RecordAndSample, - new Dictionary - { - { "sampleRate", sampleRate }, - }); - } - - /// - /// Computational method using the DJB2 Hash algorithm to decide whether to sample - /// a given telemetry item, based on its Trace Id. - /// - /// Parameters of telemetry item used to make sampling decision. - /// Returns whether or not we should sample telemetry in the form of a class. - public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) - { - if (this.samplingRatio == 0) - { - return RecordOnlySamplingResult; - } - - if (this.samplingRatio == 1) - { - return this.recordAndSampleSamplingResult; - } - - double sampleScore = DJB2SampleScore(samplingParameters.TraceId.ToHexString().ToUpperInvariant()); - - if (sampleScore < this.samplingRatio) - { - return this.recordAndSampleSamplingResult; - } - else - { - return RecordOnlySamplingResult; - } - } - - private static double DJB2SampleScore(string traceIdHex) - { - // Calculate DJB2 hash code from hex-converted TraceId - int hash = 5381; - - for (int i = 0; i < traceIdHex.Length; i++) - { - unchecked - { - hash = (hash << 5) + hash + (int)traceIdHex[i]; - } - } - - // Take the absolute value of the hash - if (hash == int.MinValue) - { - hash = int.MaxValue; - } - else - { - hash = Math.Abs(hash); - } - - // Divide by MaxValue for value between 0 and 1 for sampling score - double samplingScore = (double)hash / int.MaxValue; - return samplingScore; - } -} diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs b/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs deleted file mode 100644 index f33fc66f8b..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/ApplicationInsightsSamplerOptions.cs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Extensions.AzureMonitor; - -/// -/// Options for configuring an to customize -/// its sampling behavior. -/// -public class ApplicationInsightsSamplerOptions -{ - /// - /// Gets or sets the ratio of telemetry items to be sampled. The value must be between 0.0F and 1.0F, inclusive. - /// For example, specifying 0.4 means that 40% of traces are sampled and 60% are dropped. - /// - public float SamplingRatio { get; set; } -} diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md b/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md deleted file mode 100644 index bcc4a71014..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/CHANGELOG.md +++ /dev/null @@ -1,43 +0,0 @@ -# Changelog - -## Unreleased - -## 1.0.0-beta.4 - -Released 2023-May-05 - -* Updated `ApplicationInsightsSampler` constructor to accept - `ApplicationInsightsSamplerOptions` instead of a float `samplingRatio`, and - introduced `ApplicationInsightsSamplerOptions` for Dependency Injection - support. - -## 1.0.0-beta.3 - -Released 2023-Feb-07 - -* Sampler will now return `RecordOnly` SamplingResult when the telemetry is -sampled instead of `Drop`. This will result in `Activity` to be created always -and populated with all information such as tag, events etc. This is done in -order to allow metrics collection from the generated activities. - -> **Note** -> This change will have no impact on the overall sampling behavior, -but may have additional performance overhead from creating more activities. -([#933](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/933)) - -## 1.0.0-beta.2 - -Released 2022-Sept-12 - -* Replaced TargetFrameworks from `net461` and `net6.0` to `netstandard2.0` and - `net462`. - ([#633](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/633)) -* Changed `sampleRate` attribute type to `float`. - ([#633](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/633)) - -## 1.0.0-beta.1 - -Released 2022-Sept-12 - -* Add "sampleRate" to `SamplingResult`. - ([#623](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/623)) diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj b/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj deleted file mode 100644 index fe20b5c2f7..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/OpenTelemetry.Extensions.AzureMonitor.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - - netstandard2.0 - $(TargetFrameworks);net462 - net6.0;$(TargetFrameworks) - Extensions.AzureMonitor- - true - enable - - - - - - - - - - - diff --git a/src/OpenTelemetry.Extensions.AzureMonitor/README.md b/src/OpenTelemetry.Extensions.AzureMonitor/README.md deleted file mode 100644 index 225b1fa9af..0000000000 --- a/src/OpenTelemetry.Extensions.AzureMonitor/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Application Insights Sampler for OpenTelemetry .NET - -[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AzureMonitor)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.AzureMonitor)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AzureMonitor) - -The ```Application Insights Sampler``` should be utilized when -compatibility with Application Insights SDKs is desired, as it -implements the same hash algorithm when deciding to sample telemetry. - -## Installation - -```shell -dotnet add package OpenTelemetry.Extensions.AzureMonitor -``` - -## Usage - -You can configure the `ApplicationInsightsSampler` with the following example. -In this example the `samplingRatio` has been set to `0.4F`. -This means 40% of traces are sampled and the remaining 60% will be dropped. - -```csharp -using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new ApplicationInsightsSampler(0.4F)) - .Build(); -``` - -## References - -* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs deleted file mode 100644 index b4e8fa607a..0000000000 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/ApplicationInsightsSamplerTests.cs +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Diagnostics; - -using OpenTelemetry.Trace; -using Xunit; - -namespace OpenTelemetry.Extensions.AzureMonitor.Tests; - -public class ApplicationInsightsSamplerTests -{ - [Fact] - public void VerifyHashAlgorithmCorrectness() - { - byte[] testBytes1 = new byte[] // hex string: 8fffffffffffffff0000000000000000 - { - 0x8F, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - 0, 0, 0, 0, - 0, 0, 0, 0, - }; - byte[] testBytes2 = new byte[] // hex string: 0f1f2f3f4f5f6f7f8f9fafbfcfdfefff - { - 0x0F, 0x1F, 0x2F, 0x3F, - 0x4F, 0x5F, 0x6F, 0x7F, - 0x8F, 0x9F, 0xAF, 0xBF, - 0xCF, 0xDF, 0xEF, 0xFF, - }; - ActivityTraceId testId1 = ActivityTraceId.CreateFromBytes(testBytes1); - ActivityTraceId testId2 = ActivityTraceId.CreateFromBytes(testBytes2); - - ActivityContext parentContext = default; - SamplingParameters testParams1 = new SamplingParameters(parentContext, testId1, "TestActivity", ActivityKind.Internal); - SamplingParameters testParams2 = new SamplingParameters(parentContext, testId2, "TestActivity", ActivityKind.Internal); - - // Verify sample ratio: 0 - ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0 }); - Assert.Equal(SamplingDecision.RecordOnly, zeroSampler.ShouldSample(testParams1).Decision); - Assert.Equal(SamplingDecision.RecordOnly, zeroSampler.ShouldSample(testParams2).Decision); - - // Verify sample ratio: 1 - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 1 }); - Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams1).Decision); - Assert.Equal(SamplingDecision.RecordAndSample, oneSampler.ShouldSample(testParams2).Decision); - - // Verify sample ratio: 0.5. - // This is below the sample score for testId2, but strict enough to drop testId1 - ApplicationInsightsSampler ratioSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0.5f }); - Assert.Equal(SamplingDecision.RecordOnly, ratioSampler.ShouldSample(testParams1).Decision); - Assert.Equal(SamplingDecision.RecordAndSample, ratioSampler.ShouldSample(testParams2).Decision); - } - - [Fact] - public void ApplicationInsightsSamplerGoodArgs() - { - ApplicationInsightsSampler pointFiveSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0.5f }); - Assert.NotNull(pointFiveSampler); - - ApplicationInsightsSampler zeroSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0f }); - Assert.NotNull(zeroSampler); - - ApplicationInsightsSampler oneSampler = new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 1f }); - Assert.NotNull(oneSampler); - } - - [Fact] - public void ApplicationInsightsSamplerBadArgs() - { - Assert.Throws(() => new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = -2f })); - Assert.Throws(() => new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 2f })); - } - - [Fact] - public void GetDescriptionMatchesSpec() - { - var expectedDescription = "ApplicationInsightsSampler{0.5}"; - Assert.Equal(expectedDescription, new ApplicationInsightsSampler(new ApplicationInsightsSamplerOptions { SamplingRatio = 0.5f }).Description); - } -} diff --git a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj b/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj deleted file mode 100644 index e2b1efa2e7..0000000000 --- a/test/OpenTelemetry.Extensions.AzureMonitor.Tests/OpenTelemetry.Extensions.AzureMonitor.Tests.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - net7.0;net6.0 - enable - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - From 7a3e6e44517fe1cdb04ffef0cb566dc147085ede Mon Sep 17 00:00:00 2001 From: Soheil Alizadeh Date: Thu, 20 Jul 2023 07:10:43 +0200 Subject: [PATCH 0754/1499] Add Produced Metrics by Cassandra (#1267) --- .../README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index 7ab0e77cc3..ec66e079c8 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -74,6 +74,18 @@ var cluster = new Builder() .Build(); ``` +## List of metrics produced + +| Name | Instrument Type | Unit | Description | +|-------|-----------------|------|-------------| +| `cassandra.cql-requests` | Histogram | `ms` | Measures the duration of Cassandra CQL requests from the client's perspective. | +| `cassandra.bytes-sent` | Histogram | `bytes` | Measures the amount of bytes sent by the client to Cassandra. | +| `cassandra.bytes-received` | Histogram | `bytes` | Measures the amount of bytes received by the client from Cassandra. | +| `cassandra.cql-messages` | Histogram | `ms` | Measures the duration of CQL messages from the client's perspective. | +| `cassandra.connected-nodes` | Gauge | `nodes` | Represents the number of nodes in Cassandra to which the client is connected. | +| `cassandra.pool.open-connections` | Gauge | `connections` | Represents the number of open connections from the client to Cassandra. | +| `cassandra.pool.in-flight` | Gauge | `requests` | Represents the number of in-flight requests from the client to Cassandra. | + ## References * [OpenTelemetry Project](https://opentelemetry.io/) From 5c6ac6899b3e19ed5a2c42916b906ce8a61118d1 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 20 Jul 2023 16:56:34 -0700 Subject: [PATCH 0755/1499] [OpenTelemetry.ResourceDetectors.Azure] Update Azure detector resource semantics. (#1272) --- .../AppServiceResourceDetector.cs | 52 ++++++++++++++----- .../AzureVMResourceDetector.cs | 39 +++++++------- .../AzureVmMetadataResponse.cs | 42 +++++++-------- .../CHANGELOG.md | 16 ++++++ .../ResourceAttributeConstants.cs | 36 +++++-------- src/Shared/ResourceSemanticConventions.cs | 9 +++- .../AzureResourceDetectorTests.cs | 51 +++++++++++------- 7 files changed, 150 insertions(+), 95 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index 277756f7cb..113a81f526 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -28,14 +28,11 @@ public sealed class AppServiceResourceDetector : IResourceDetector { internal static readonly IReadOnlyDictionary AppServiceResourceAttributes = new Dictionary { - [ResourceAttributeConstants.AppServiceSiteName] = ResourceAttributeConstants.AppServiceSiteNameEnvVar, - [ResourceSemanticConventions.AttributeServiceName] = ResourceAttributeConstants.AppServiceSiteNameEnvVar, - [ResourceSemanticConventions.AttributeServiceInstance] = ResourceAttributeConstants.AppServiceInstanceIdEnvVar, - [ResourceAttributeConstants.AppServiceSlotName] = ResourceAttributeConstants.AppServiceSlotNameEnvVar, - [ResourceAttributeConstants.AppServiceStamp] = ResourceAttributeConstants.AppServiceStampNameEnvVar, - [ResourceAttributeConstants.AppServiceHost] = ResourceAttributeConstants.AppServiceHostNameEnvVar, - [ResourceAttributeConstants.AppServiceOwner] = ResourceAttributeConstants.AppServiceOwnerNameEnvVar, - [ResourceAttributeConstants.AppServiceResourceGroup] = ResourceAttributeConstants.AppServiceResourceGroupEnvVar, + { ResourceSemanticConventions.AttributeCloudRegion, ResourceAttributeConstants.AppServiceRegionNameEnvVar }, + { ResourceSemanticConventions.AttributeDeploymentEnvironment, ResourceAttributeConstants.AppServiceSlotNameEnvVar }, + { ResourceSemanticConventions.AttributeHostId, ResourceAttributeConstants.AppServiceHostNameEnvVar }, + { ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AppServiceInstanceIdEnvVar }, + { ResourceAttributeConstants.AzureAppServiceStamp, ResourceAttributeConstants.AppServiceStampNameEnvVar }, }; /// @@ -45,12 +42,27 @@ public Resource Detect() try { - foreach (var kvp in AppServiceResourceAttributes) + var websiteSiteName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceSiteNameEnvVar); + + if (websiteSiteName != null) { - var attributeValue = Environment.GetEnvironmentVariable(kvp.Value); - if (attributeValue != null) + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, websiteSiteName)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureAppServicePlatformValue)); + + var azureResourceUri = GetAzureResourceURI(websiteSiteName); + if (azureResourceUri != null) { - attributeList.Add(new KeyValuePair(kvp.Key, attributeValue)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudResourceId, azureResourceUri)); + } + + foreach (var kvp in AppServiceResourceAttributes) + { + var attributeValue = Environment.GetEnvironmentVariable(kvp.Value); + if (attributeValue != null) + { + attributeList.Add(new KeyValuePair(kvp.Key, attributeValue)); + } } } } @@ -62,4 +74,20 @@ public Resource Detect() return new Resource(attributeList); } + + private static string? GetAzureResourceURI(string websiteSiteName) + { + string websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); + string websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty; + + int idx = websiteOwnerName.IndexOf('+'); + string subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName; + + if (string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId)) + { + return null; + } + + return $"/subscriptions/{subscriptionId}/resourceGroups/{websiteResourceGroup}/providers/Microsoft.Web/sites/{websiteSiteName}"; + } } diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs index f5f702de74..1a8fc97ce4 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs @@ -27,42 +27,43 @@ public sealed class AzureVMResourceDetector : IResourceDetector { internal static readonly IReadOnlyCollection ExpectedAzureAmsFields = new string[] { - ResourceAttributeConstants.AzureVmId, - ResourceAttributeConstants.AzureVmLocation, - ResourceAttributeConstants.AzureVmName, - ResourceAttributeConstants.AzureVmOsType, - ResourceAttributeConstants.AzureVmResourceGroup, - ResourceAttributeConstants.AzureVmResourceId, - ResourceAttributeConstants.AzureVmSku, - ResourceAttributeConstants.AzureVmVersion, - ResourceAttributeConstants.AzureVmSize, ResourceAttributeConstants.AzureVmScaleSetName, - ResourceAttributeConstants.AzureVmSubscriptionId, + ResourceAttributeConstants.AzureVmSku, + ResourceSemanticConventions.AttributeCloudPlatform, + ResourceSemanticConventions.AttributeCloudProvider, + ResourceSemanticConventions.AttributeCloudRegion, + ResourceSemanticConventions.AttributeCloudResourceId, + ResourceSemanticConventions.AttributeHostId, + ResourceSemanticConventions.AttributeHostName, + ResourceSemanticConventions.AttributeHostType, + ResourceSemanticConventions.AttributeOsType, + ResourceSemanticConventions.AttributeOsVersion, ResourceSemanticConventions.AttributeServiceInstance, }; /// public Resource Detect() { - List>? attributeList = null; try { var vmMetaDataResponse = AzureVmMetaDataRequestor.GetAzureVmMetaDataResponse(); - if (vmMetaDataResponse != null) + if (vmMetaDataResponse == null) { - attributeList = new List>(ExpectedAzureAmsFields.Count); - foreach (var field in ExpectedAzureAmsFields) - { - attributeList.Add(new KeyValuePair(field, vmMetaDataResponse.GetValueForField(field))); - } + return Resource.Empty; } + + var attributeList = new List>(ExpectedAzureAmsFields.Count); + foreach (var field in ExpectedAzureAmsFields) + { + attributeList.Add(new KeyValuePair(field, vmMetaDataResponse.GetValueForField(field))); + } + + return new Resource(attributeList); } catch { // TODO: log exception. return Resource.Empty; } - - return attributeList == null ? Resource.Empty : new Resource(attributeList); } } diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs index 41a2c1bc2f..385818649a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs @@ -58,40 +58,40 @@ internal string GetValueForField(string fieldName) string? amsValue = null; switch (fieldName) { - case "azInst_osType": - amsValue = this.OsType; - break; - case "azInst_location": - amsValue = this.Location; + case ResourceSemanticConventions.AttributeCloudPlatform: + amsValue = ResourceAttributeConstants.AzureVmCloudPlatformValue; break; - case "azInst_name": - amsValue = this.Name; + case ResourceSemanticConventions.AttributeCloudProvider: + amsValue = ResourceAttributeConstants.AzureCloudProviderValue; break; - case "azInst_sku": - amsValue = this.Sku; + case ResourceSemanticConventions.AttributeCloudRegion: + amsValue = this.Location; break; - case "azInst_version": - amsValue = this.Version; + case ResourceSemanticConventions.AttributeCloudResourceId: + amsValue = this.ResourceId; break; - case "azInst_vmId": + case ResourceSemanticConventions.AttributeHostId: case ResourceSemanticConventions.AttributeServiceInstance: amsValue = this.VmId; break; - case "azInst_vmSize": - amsValue = this.VmSize; + case ResourceSemanticConventions.AttributeHostName: + amsValue = this.Name; break; - case "azInst_subscriptionId": - amsValue = this.SubscriptionId; + case ResourceSemanticConventions.AttributeHostType: + amsValue = this.VmSize; break; - case "azInst_resourceId": - amsValue = this.ResourceId; + case ResourceSemanticConventions.AttributeOsType: + amsValue = this.OsType; break; - case "azInst_resourceGroupName": - amsValue = this.ResourceGroupName; + case ResourceSemanticConventions.AttributeOsVersion: + amsValue = this.Version; break; - case "azInst_vmScaleSetName": + case ResourceAttributeConstants.AzureVmScaleSetName: amsValue = this.VmScaleSetName; break; + case ResourceAttributeConstants.AzureVmSku: + amsValue = this.Sku; + break; } amsValue ??= string.Empty; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index d77fccd1b8..de99f6ec09 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,22 @@ ## Unreleased +* For Azure VM Resource Detector: + ([#1272](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1272/files)) + * **Updated attributes**: `azInst_vmId` to `host.id`, `azInst_location` to + `cloud.region`, `azInst_name` to `host.name`, `azInst_osType` to `os.type`, + `azInst_resourceId` to `cloud.resource_id`, `azInst_sku` to `azure.vm.sku`, + `azInst_version` to `os.version`, `azInst_vmSize` to `host.type`, + `azInst_vmScaleSetName` to `azure.vm.scaleset.name`. + * **Added attributes**: `cloud.provider` and `cloud.platform`. + * **Removed attributes**: `azInst_resourceGroupName`, `azInst_subscriptionId`. +* For Azure App Service: + ([#1272](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1272/files)) + * **Updated attributes**: `appSrv_wsHost` to `host.id`, `appSrv_SlotName` to + `deployment.environment`, `appSrv_wsStamp` to `azure.app.service.stamp`. + * **Added attributes**: `cloud.resource_id`, `cloud.provider`, + `cloud.platform`, `cloud.region`. + * **Removed attribute**: `appSrv_ResourceGroup`. * Updates to 1.5.0 of OpenTelemetry SDK. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) * Added Azure VM resource detector. diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs index 299046fe60..5e5cc95ec2 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs @@ -15,35 +15,27 @@ // namespace OpenTelemetry.ResourceDetectors.Azure; -internal class ResourceAttributeConstants +internal sealed class ResourceAttributeConstants { // AppService resource attributes - internal const string AppServiceSiteName = "appSrv_SiteName"; - internal const string AppServiceSlotName = "appSrv_SlotName"; - internal const string AppServiceStamp = "appSrv_wsStamp"; - internal const string AppServiceHost = "appSrv_wsHost"; - internal const string AppServiceOwner = "appSrv_wsOwner"; - internal const string AppServiceResourceGroup = "appSrv_ResourceGroup"; + internal const string AzureAppServiceStamp = "azure.app.service.stamp"; // Azure VM resource attributes - internal const string AzureVmId = "azInst_vmId"; - internal const string AzureVmLocation = "azInst_location"; - internal const string AzureVmName = "azInst_name"; - internal const string AzureVmOsType = "azInst_osType"; - internal const string AzureVmResourceGroup = "azInst_resourceGroupName"; - internal const string AzureVmResourceId = "azInst_resourceId"; - internal const string AzureVmSku = "azInst_sku"; - internal const string AzureVmVersion = "azInst_version"; - internal const string AzureVmSize = "azInst_vmSize"; - internal const string AzureVmScaleSetName = "azInst_vmScaleSetName"; - internal const string AzureVmSubscriptionId = "azInst_subscriptionId"; + internal const string AzureVmScaleSetName = "azure.vm.scaleset.name"; + internal const string AzureVmSku = "azure.vm.sku"; // AppService environment variables - internal const string AppServiceSiteNameEnvVar = "WEBSITE_SITE_NAME"; - internal const string AppServiceInstanceIdEnvVar = "WEBSITE_INSTANCE_ID"; - internal const string AppServiceSlotNameEnvVar = "WEBSITE_SLOT_NAME"; - internal const string AppServiceStampNameEnvVar = "WEBSITE_HOME_STAMPNAME"; internal const string AppServiceHostNameEnvVar = "WEBSITE_HOSTNAME"; + internal const string AppServiceInstanceIdEnvVar = "WEBSITE_INSTANCE_ID"; internal const string AppServiceOwnerNameEnvVar = "WEBSITE_OWNER_NAME"; + internal const string AppServiceRegionNameEnvVar = "REGION_NAME"; internal const string AppServiceResourceGroupEnvVar = "WEBSITE_RESOURCE_GROUP"; + internal const string AppServiceSiteNameEnvVar = "WEBSITE_SITE_NAME"; + internal const string AppServiceSlotNameEnvVar = "WEBSITE_SLOT_NAME"; + internal const string AppServiceStampNameEnvVar = "WEBSITE_HOME_STAMPNAME"; + + // Azure resource attributes constant values + internal const string AzureAppServicePlatformValue = "azure_app_service"; + internal const string AzureCloudProviderValue = "azure"; + internal const string AzureVmCloudPlatformValue = "azure_vm"; } diff --git a/src/Shared/ResourceSemanticConventions.cs b/src/Shared/ResourceSemanticConventions.cs index 3d0adc5073..a6a8c9a72c 100644 --- a/src/Shared/ResourceSemanticConventions.cs +++ b/src/Shared/ResourceSemanticConventions.cs @@ -56,9 +56,16 @@ internal static class ResourceSemanticConventions public const string AttributeProcessCommandLine = "process.command_line"; public const string AttributeProcessUsername = "process.username"; - public const string AttributeCloudProvider = "cloud.provider"; public const string AttributeCloudAccount = "cloud.account.id"; + public const string AttributeCloudPlatform = "cloud.platform"; + public const string AttributeCloudProvider = "cloud.provider"; public const string AttributeCloudRegion = "cloud.region"; + public const string AttributeCloudResourceId = "cloud.resource_id"; public const string AttributeCloudZone = "cloud.zone"; public const string AttributeComponent = "component"; + + public const string AttributeOsType = "os.type"; + public const string AttributeOsVersion = "os.version"; + + public const string AttributeDeploymentEnvironment = "deployment.environment"; } diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index 03c04a34da..1fc402d3e4 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -39,8 +39,10 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); } - // Special case for service.name and appSrv_SiteName attribute - Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceSiteNameEnvVar, "ServiceName"); + // Special case for service.name and resource uri attribute + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceSiteNameEnvVar, "sitename"); + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar, "testResourceGroup"); + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar, "testtestSubscriptionId+testResourceGroup-websiteOwnerName"); } catch { @@ -49,14 +51,12 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() var resource = ResourceBuilder.CreateEmpty().AddDetector(new AppServiceResourceDetector()).Build(); Assert.NotNull(resource); + var expectedResourceUri = "/subscriptions/testtestSubscriptionId/resourceGroups/testResourceGroup/providers/Microsoft.Web/sites/sitename"; + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeCloudResourceId, expectedResourceUri), resource.Attributes); + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "sitename"), resource.Attributes); + foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) { - if (kvp.Value == ResourceAttributeConstants.AppServiceSiteNameEnvVar) - { - Assert.Contains(new KeyValuePair(kvp.Key, "ServiceName"), resource.Attributes); - continue; - } - Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); } } @@ -69,31 +69,42 @@ public void TestAzureVmResourceDetector() return new AzureVmMetadataResponse() { // using values same as key for test. - VmId = ResourceAttributeConstants.AzureVmId, - Location = ResourceAttributeConstants.AzureVmLocation, - Name = ResourceAttributeConstants.AzureVmName, - OsType = ResourceAttributeConstants.AzureVmOsType, - ResourceGroupName = ResourceAttributeConstants.AzureVmResourceGroup, - ResourceId = ResourceAttributeConstants.AzureVmResourceId, + VmId = ResourceSemanticConventions.AttributeHostId, + Location = ResourceSemanticConventions.AttributeCloudRegion, + Name = ResourceSemanticConventions.AttributeHostName, + OsType = ResourceSemanticConventions.AttributeOsType, + ResourceId = ResourceSemanticConventions.AttributeCloudResourceId, Sku = ResourceAttributeConstants.AzureVmSku, - Version = ResourceAttributeConstants.AzureVmVersion, - VmSize = ResourceAttributeConstants.AzureVmSize, + Version = ResourceSemanticConventions.AttributeOsVersion, + VmSize = ResourceSemanticConventions.AttributeHostType, VmScaleSetName = ResourceAttributeConstants.AzureVmScaleSetName, - SubscriptionId = ResourceAttributeConstants.AzureVmSubscriptionId, }; }; var resource = ResourceBuilder.CreateEmpty().AddDetector(new AzureVMResourceDetector()).Build(); Assert.NotNull(resource); + foreach (var field in AzureVMResourceDetector.ExpectedAzureAmsFields) { + KeyValuePair expectedValue; if (field == ResourceSemanticConventions.AttributeServiceInstance) { - Assert.Contains(new KeyValuePair(field, ResourceAttributeConstants.AzureVmId), resource.Attributes); - continue; + expectedValue = new KeyValuePair(field, ResourceSemanticConventions.AttributeHostId); + } + else if (field == ResourceSemanticConventions.AttributeCloudPlatform) + { + expectedValue = new KeyValuePair(field, ResourceAttributeConstants.AzureVmCloudPlatformValue); + } + else if (field == ResourceSemanticConventions.AttributeCloudProvider) + { + expectedValue = new KeyValuePair(field, ResourceAttributeConstants.AzureCloudProviderValue); + } + else + { + expectedValue = new KeyValuePair(field, field); } - Assert.Contains(new KeyValuePair(field, field), resource.Attributes); + Assert.Contains(expectedValue, resource.Attributes); } } From b0079f76a9c7fe3db79393b6679c25a6a1516a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Neum=C3=BCller?= Date: Mon, 24 Jul 2023 09:46:48 +0200 Subject: [PATCH 0756/1499] Instrumentation.AWSLambda: Upgrade & explicitly depend on Newtonsoft.Json (#1273) --- .../CHANGELOG.md | 13 ++++++ ...Telemetry.Instrumentation.AWSLambda.csproj | 1 + .../Implementation/AWSMessagingUtilsTests.cs | 41 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index a139fe55e3..7fec9a4d46 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,19 @@ ## Unreleased +* Add explicit dependency on Newtonsoft.Json, upgrading the minimum version. + + This resolves a warning that some dependency analyzers may produce where this + package would transitively depend on a vulnerable version of Newtonsoft.Json + through [Amazon.Lambda.APIGatewayEvents][]. + + This also avoids a potential issue where the instrumentation would try to call + a Newtonsoft.Json function when no other package nor the app itself depends on + Newtonsoft.Json, since the transitive dependency would be ignored unless using + application were compiled against a TargetFramework older than Core 3.1. + +[Amazon.Lambda.APIGatewayEvents]: https://www.nuget.org/packages/Amazon.Lambda.APIGatewayEvents/2.4.1#dependencies-body-tab + ## 1.1.0-beta.3 Released 2023-Jun-13 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 4853e9dbd6..932a8fd69f 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -14,6 +14,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs index f51e40e404..770a4036e6 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -72,6 +72,47 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF Assert.Equal(2, links.Count()); } + [Fact] + public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetFromSnsMessage() + { + AWSMessagingUtils.SetParentFromMessageBatch = true; + var sqsEvent = new SQSEvent + { + Records = new List + { + new SQSMessage + { + MessageAttributes = new(), + +#pragma warning disable format // dotnet-format butchers the raw string & all following code (use dotnet format instead?) + Body = /*lang=json,strict*/ """ + { + "Type" : "Notification", + "MessageId" : "f91f7f8e-77cc-51e7-ad08-231055044066", + "TopicArn" : "arn:aws:sqs:us-east-1:123456789012:foo-bar-test-queue", + "Subject" : "testsub", + "Message" : "{\"This JSON string\": \"is in the SNS body\"}", + "Timestamp" : "2023-03-29T11:27:04.056Z", + "SignatureVersion" : "1", + "Signature" : "base64string/redacted", + "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-1234567abc123def1234567890123467.pem", + "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sqs:us-east-1:123456789012:foo-bar-test-queue:123abcde-1234-1abc-1234-123456abcdef", + "MessageAttributes" : { + "traceparent" : {"Type":"String","Value":"00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-00"} + } + } + """, + }, + }, + }; + + (PropagationContext parentContext, IEnumerable links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + + Assert.NotEqual(default, parentContext); + Assert.Equal(SpanId1, parentContext.ActivityContext.SpanId.ToHexString()); + Assert.Single(links); + } + private static SQSEvent CreateSqsEventWithMessages(string[] spans) { var @event = new SQSEvent { Records = new List() }; From 5c2ef4fa3fc8c5c8810f6c428b1270a75b047191 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 24 Jul 2023 18:16:52 -0700 Subject: [PATCH 0757/1499] [ResourceDetectors.Azure] update changelog and readme (#1277) --- .../CHANGELOG.md | 4 +- .../README.md | 56 +++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index de99f6ec09..475d395c7e 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog -## Unreleased +## 1.0.0-beta.1 + +Released 2023-Jul-24 * For Azure VM Resource Detector: ([#1272](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1272/files)) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 60b36e3a1f..347303b360 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -13,11 +13,12 @@ for applications running in Azure environment. dotnet add package --prerelease OpenTelemetry.ResourceDetectors.Azure ``` -## Appservice Resource Detector +## App Service Resource Detector -Adds resource attributes for the applications running in Appservice. The -following example shows how to add `AppServiceResourceDetector` to -`TracerProvider` configuration: +Adds resource attributes for the applications running in Azure App Service. +The following example shows how to add `AppServiceResourceDetector` to +`TracerProvider` configuration, but this can be added to logs and metrics +as well. ```csharp using OpenTelemetry; @@ -31,3 +32,50 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddDetector(new AppServiceResourceDetector())) .Build(); ``` + +| Attributes recorded by AppServiceResourceDetector | +|---------------------------------------------------| +| azure.app.service.stamp | +| cloud.provider | +| cloud.platform | +| cloud.resource_id | +| cloud.region | +| deployment.environment | +| host.id | +| service.instance.id | +| service.name | + +## VM Resource Detector + +Adds resource attributes for the applications running in an Azure virtual machine. +The following example shows how to add `AzureVMResourceDetector` to +`TracerProvider` configuration, but this can be added to logs and metrics +as well. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.Azure; +using OpenTelemetry.Resources; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .SetResourceBuilder(ResourceBuilder + .CreateDefault() + .AddDetector(new AzureVMResourceDetector())) + .Build(); +``` + +| Attributes recorded by AzureVMResourceDetector | +|------------------------------------------------| +| azure.vm.scaleset.name | +| azure.vm.sku | +| cloud.platform | +| cloud.provider | +| cloud.region | +| cloud.resource_id | +| host.id | +| host.name | +| host.type | +| os.type | +| os.version | +| service.instance.id | From aca67642ea746c927c5dda7473c128d184b129b7 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 24 Jul 2023 19:06:35 -0700 Subject: [PATCH 0758/1499] [ResourceDetectors.Azure] Add unreleased section (#1278) --- src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 475d395c7e..6e1f046f32 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## Unreleased + ## 1.0.0-beta.1 Released 2023-Jul-24 From 16334cb10128420fe7745b29630fc6687ca01095 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Wed, 26 Jul 2023 10:33:39 -0700 Subject: [PATCH 0759/1499] [ResourceDetectors.Azure] update readme to use `ConfigureResource` (#1280) --- src/OpenTelemetry.ResourceDetectors.Azure/README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 347303b360..3cd6321bb2 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -27,9 +27,7 @@ using OpenTelemetry.Resources; var tracerProvider = Sdk.CreateTracerProviderBuilder() // other configurations - .SetResourceBuilder(ResourceBuilder - .CreateDefault() - .AddDetector(new AppServiceResourceDetector())) + .ConfigureResource(resource => resource.AddDetector(new AppServiceResourceDetector())) .Build(); ``` @@ -59,9 +57,7 @@ using OpenTelemetry.Resources; var tracerProvider = Sdk.CreateTracerProviderBuilder() // other configurations - .SetResourceBuilder(ResourceBuilder - .CreateDefault() - .AddDetector(new AzureVMResourceDetector())) + .ConfigureResource(resource => resource.AddDetector(new AzureVMResourceDetector())) .Build(); ``` From 17a517c933501fd657dfcea871ffb9a2ff39aa57 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 26 Jul 2023 13:44:37 -0700 Subject: [PATCH 0760/1499] Downgrade `system.text.json` OpenTelemetry.ResourceDetectors.Azure (#1279) --- src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 7 +++++++ .../OpenTelemetry.ResourceDetectors.Azure.csproj | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 6e1f046f32..42290fcc37 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2023-Jul-26 + +* Downgraded minimum required version for `System.Text.Json` to `4.7.2`. + ([#1279](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1279)) + ## 1.0.0-beta.1 Released 2023-Jul-24 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index 5ddc90d943..885c72ec9c 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -10,7 +10,7 @@ - + From b515cc7302d31ddb500769181da5021fcb23861a Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Wed, 26 Jul 2023 15:23:23 -0700 Subject: [PATCH 0761/1499] [OpenTelemetry.ResourceDetectors.Azure] Update Readme for Azure App Service and VM Resource Detector (#1281) --- .../README.md | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 3cd6321bb2..4cf2660f6e 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -31,17 +31,17 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -| Attributes recorded by AppServiceResourceDetector | -|---------------------------------------------------| -| azure.app.service.stamp | -| cloud.provider | -| cloud.platform | -| cloud.resource_id | -| cloud.region | -| deployment.environment | -| host.id | -| service.instance.id | -| service.name | +| Attribute | Description | +|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| azure.app.service.stamp | The specific "stamp" cluster within Azure where the App Service is running, e.g., "waws-prod-sn1-001". | +| cloud.provider | The cloud service provider. In this context, it's always "azure". | +| cloud.platform | The cloud platform. Here, it's always "azure_app_service". | +| cloud.resource_id | The Azure Resource Manager URI uniquely identifying the Azure App Service. Typically in the format "/subscriptions/{subscriptionId}/resourceGroups/{groupName}/providers/Microsoft.Web/sites/{siteName}". | +| cloud.region | The Azure region where the App Service is hosted, e.g., "East US", "West Europe", etc. | +| deployment.environment | The deployment slot where the Azure App Service is running, such as "staging", "production", etc. | +| host.id | The primary hostname for the app, excluding any custom hostnames. | +| service.instance.id | The specific instance of the Azure App Service, useful in a scaled-out configuration. | +| service.name | The name of the Azure App Service. | | ## VM Resource Detector @@ -61,17 +61,17 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -| Attributes recorded by AzureVMResourceDetector | -|------------------------------------------------| -| azure.vm.scaleset.name | -| azure.vm.sku | -| cloud.platform | -| cloud.provider | -| cloud.region | -| cloud.resource_id | -| host.id | -| host.name | -| host.type | -| os.type | -| os.version | -| service.instance.id | +| Attribute | Description | +|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| azure.vm.scaleset.name | The name of the Virtual Machine Scale Set if the VM is part of one. | +| azure.vm.sku | The SKU of the Azure Virtual Machine's operating system. For instance, for a VM running Windows Server 2019 Datacenter edition, this value would be "2019-Datacenter". | +| cloud.platform | The cloud platform, which is always set to "azure" in this context. | +| cloud.provider | The cloud service provider, which is always set to "azure_vm" in this context. | +| cloud.region | The Azure region where the Virtual Machine is hosted, such as "East US", "West Europe", etc. | +| cloud.resource_id | The Azure Resource Manager URI uniquely identifying the Azure Virtual Machine. It typically follows this format: "/subscriptions/{subscriptionId}/resourceGroups/{groupName}/providers/Microsoft.Compute/virtualMachines/{vmName}". | +| host.id | A unique identifier for the VM host, for instance, "02aab8a4-74ef-476e-8182-f6d2ba4166a6". | +| host.name | The name of the host machine. | +| host.type | The size of the VM instance, for example, "Standard_D2s_v3". | +| os.type | The type of operating system running on the VM, such as "Linux" or "Windows". | +| os.version | The version of the operating system running on the VM. | +| service.instance.id | An identifier for a specific instance of the service running on the Azure VM, for example, "02aab8a4-74ef-476e-8182-f6d2ba4166a6". | From bcb632d0869d6f32fc8312ce44dc92851474418e Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Thu, 27 Jul 2023 11:33:02 +0200 Subject: [PATCH 0762/1499] Rename package: [OpenTelemetry.Contrib.Instrumentation.AWS] to [OpenTelemetry.Instrumentation.AWS] (#1275) --- .../comp_contrib_instrumentation_aws.md | 8 +++---- .github/component_owners.yml | 24 +++++++++---------- .../workflows/package-Instrumentation.AWS.yml | 4 ++-- opentelemetry-dotnet-contrib.sln | 4 ++-- .../.publicApi/net462/PublicAPI.Shipped.txt | 7 ------ .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 --- .../netstandard2.0/PublicAPI.Shipped.txt | 7 ------ .../netstandard2.0/PublicAPI.Unshipped.txt | 3 --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 8 +++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 8 +++++++ .../AWSClientInstrumentationOptions.cs | 2 +- .../AssemblyInfo.cs | 2 +- .../CHANGELOG.md | 6 +++-- .../AWSClientsInstrumentation.cs | 2 +- .../Implementation/AWSMessagingUtils.cs | 2 +- .../Implementation/AWSSemanticConventions.cs | 2 +- .../Implementation/AWSServiceHelper.cs | 2 +- .../Implementation/AWSServiceType.cs | 2 +- .../AWSTracingPipelineCustomizer.cs | 2 +- .../AWSTracingPipelineHandler.cs | 2 +- .../Implementation/SnsRequestContextHelper.cs | 2 +- .../Implementation/SqsRequestContextHelper.cs | 2 +- .../Implementation/Utils.cs | 2 +- .../OpenTelemetry.Instrumentation.AWS.csproj} | 0 .../README.md | 8 +++---- .../TracerProviderBuilderExtensions.cs | 4 ++-- .../RequestContextHelperTests.cs | 4 ++-- .../Implementation/TestsHelper.cs | 4 ++-- ...elemetry.Instrumentation.AWS.Tests.csproj} | 4 ++-- .../TestAWSClientInstrumentation.cs | 3 ++- .../Tools/CustomResponses.cs | 2 +- .../Tools/CustomWebResponse.cs | 2 +- .../Tools/HttpResponseMessageBody.cs | 2 +- .../Tools/MockHttpRequest.cs | 2 +- .../Tools/MockHttpRequestFactory.cs | 2 +- .../Tools/MockWebResponse.cs | 2 +- .../Tools/TestAmazonDynamoDBClient.cs | 2 +- .../Tools/Utils.cs | 2 +- 40 files changed, 76 insertions(+), 75 deletions(-) delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/AWSClientInstrumentationOptions.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/AssemblyInfo.cs (63%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/CHANGELOG.md (78%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSClientsInstrumentation.cs (93%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSMessagingUtils.cs (94%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSSemanticConventions.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSServiceHelper.cs (96%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSServiceType.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSTracingPipelineCustomizer.cs (95%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/AWSTracingPipelineHandler.cs (99%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/SnsRequestContextHelper.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/SqsRequestContextHelper.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/Implementation/Utils.cs (97%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj => OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj} (100%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/README.md (68%) rename src/{OpenTelemetry.Contrib.Instrumentation.AWS => OpenTelemetry.Instrumentation.AWS}/TracerProviderBuilderExtensions.cs (95%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Implementation/RequestContextHelperTests.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Implementation/TestsHelper.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj => OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj} (88%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/TestAWSClientInstrumentation.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/CustomResponses.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/CustomWebResponse.cs (98%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/HttpResponseMessageBody.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/MockHttpRequest.cs (99%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/MockHttpRequestFactory.cs (97%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/MockWebResponse.cs (99%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/TestAmazonDynamoDBClient.cs (94%) rename test/{OpenTelemetry.Contrib.Instrumentation.AWS.Tests => OpenTelemetry.Instrumentation.AWS.Tests}/Tools/Utils.cs (97%) diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md index caf78e5996..f3ec2922ad 100644 --- a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md +++ b/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md @@ -1,10 +1,10 @@ --- -name: OpenTelemetry.Contrib.Instrumentation.AWS -about: Issue with OpenTelemetry.Contrib.Instrumentation.AWS -labels: comp:contrib.instrumentation.aws +name: OpenTelemetry.Instrumentation.AWS +about: Issue with OpenTelemetry.Instrumentation.AWS +labels: comp:instrumentation.aws --- -# Issue with OpenTelemetry.Contrib.Instrumentation.AWS +# Issue with OpenTelemetry.Instrumentation.AWS List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 1b5c18d9f6..4841c948b2 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -6,9 +6,6 @@ components: src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - srprash - atshaw43 - src/OpenTelemetry.Contrib.Instrumentation.AWS/: - - srprash - - atshaw43 src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch @@ -28,10 +25,9 @@ components: - codeblanch src/OpenTelemetry.Extensions.Enrichment/: - xakep139 - src/OpenTelemetry.PersistentStorage.Abstractions/: - - vishweshbankwar - src/OpenTelemetry.PersistentStorage.FileSystem/: - - vishweshbankwar + src/OpenTelemetry.Instrumentation.AWS/: + - srprash + - atshaw43 src/OpenTelemetry.Instrumentation.AWSLambda/: - rypdal - Oberon00 @@ -59,6 +55,10 @@ components: - xiang17 src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch + src/OpenTelemetry.PersistentStorage.Abstractions/: + - vishweshbankwar + src/OpenTelemetry.PersistentStorage.FileSystem/: + - vishweshbankwar src/OpenTelemetry.ResourceDetectors.AWS/: - srprash - atshaw43 @@ -73,9 +73,6 @@ components: test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - srprash - atshaw43 - test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/: - - srprash - - atshaw43 test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch @@ -110,8 +107,9 @@ components: - codeblanch test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 - test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: - - vishweshbankwar + test/OpenTelemetry.Instrumentation.AWS.Tests/: + - srprash + - atshaw43 test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: - rypdal - Oberon00 @@ -137,6 +135,8 @@ components: - xiang17 test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch + test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: + - vishweshbankwar test/OpenTelemetry.ResourceDetectors.AWS.Tests/: - srprash - atshaw43 diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index 61db291d20..c8bdd9068a 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Instrumentation.AWS +name: Pack OpenTelemetry.Instrumentation.AWS on: workflow_dispatch: @@ -17,7 +17,7 @@ jobs: permissions: contents: write env: - PROJECT: OpenTelemetry.Contrib.Instrumentation.AWS + PROJECT: OpenTelemetry.Instrumentation.AWS strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 040f18b316..9de655cacd 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -115,9 +115,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Exten EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay.Tests", "test\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj", "{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS", "src\OpenTelemetry.Contrib.Instrumentation.AWS\OpenTelemetry.Contrib.Instrumentation.AWS.csproj", "{970673DA-F308-4960-A58D-ECCEA44CEF6B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AWS", "src\OpenTelemetry.Instrumentation.AWS\OpenTelemetry.Instrumentation.AWS.csproj", "{970673DA-F308-4960-A58D-ECCEA44CEF6B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Instrumentation.AWS.Tests", "test\OpenTelemetry.Contrib.Instrumentation.AWS.Tests\OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj", "{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AWS.Tests", "test\OpenTelemetry.Instrumentation.AWS.Tests\OpenTelemetry.Instrumentation.AWS.Tests.csproj", "{CAB66B50-DAB6-49B8-83F9-6CCF520C4A36}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Wcf.Tests", "test\OpenTelemetry.Instrumentation.Wcf.Tests\OpenTelemetry.Instrumentation.Wcf.Tests.csproj", "{76BAB24F-85DB-4FCE-89D0-EFB4185004C9}" EndProject diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index b9b90d106a..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1,7 +0,0 @@ -#nullable enable -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index fb419c1de8..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -*REMOVED*static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 3906c385a7..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,7 +0,0 @@ -#nullable enable -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool -OpenTelemetry.Contrib.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index fb419c1de8..0000000000 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -*REMOVED*static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..1362c26ff9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +#nullable enable +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..1362c26ff9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +#nullable enable +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs index b2cc6eda64..26a2f23bf7 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AWSClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.AWS; +namespace OpenTelemetry.Instrumentation.AWS; /// /// Options for AWS client instrumentation. diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs similarity index 63% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs rename to src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs index cc2b4852ad..20214c63cb 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs @@ -16,4 +16,4 @@ using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Instrumentation.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md similarity index 78% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md rename to src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 31cde222a7..e091c42157 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -1,7 +1,9 @@ -# Changelog - OpenTelemetry.Contrib.Instrumentation.AWS +# Changelog - OpenTelemetry.Instrumentation.AWS ## Unreleased +* BREAKING (renaming): renamed `OpenTelemetry.Contrib.Instrumentation.AWS` to `OpenTelemetry.Instrumentation.AWS` + ([#1275](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1275)) * Raised the minimum .NET version to `net462` ([#1095](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1095)) * Removes `AddAWSInstrumentation` method with default configure default parameter. @@ -27,4 +29,4 @@ project. The release targets v1.0.1 of the [OpenTelemetry.Contrib.Extensions.AWSXRay](https://www.nuget.org/packages/OpenTelemetry.Contrib.Extensions.AWSXRay/) For more details, please refer to the -[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md) +[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AWS/README.md) diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs similarity index 93% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs index 24de661b95..fcf76b66d2 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs @@ -16,7 +16,7 @@ using Amazon.Runtime.Internal; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSClientsInstrumentation { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs similarity index 94% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs index d723743c3a..d2eaf8d0d6 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs @@ -17,7 +17,7 @@ using System.Collections.Generic; using OpenTelemetry.Context.Propagation; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal static class AWSMessagingUtils { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index b61cff81e5..cdcfedb829 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal static class AWSSemanticConventions { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs similarity index 96% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index 8c11883331..5b34950512 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -17,7 +17,7 @@ using System.Collections.Generic; using Amazon.Runtime; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSServiceHelper { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs index 750fab7b23..b73e4186b3 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSServiceType.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs @@ -16,7 +16,7 @@ using System; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSServiceType { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index c7693d729a..b786b30600 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -18,7 +18,7 @@ using Amazon.Runtime; using Amazon.Runtime.Internal; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 47ce566498..2c11c425d9 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -25,7 +25,7 @@ using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSTracingPipelineHandler : PipelineHandler { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs index 5b8b09da87..f0400363a4 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs @@ -20,7 +20,7 @@ using Amazon.Runtime.Internal; using Amazon.SimpleNotificationService.Model; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class SnsRequestContextHelper { // SQS/SNS message attributes collection size limit according to diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs index aad44cd023..c242b98400 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs @@ -20,7 +20,7 @@ using Amazon.Runtime.Internal; using Amazon.SQS.Model; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class SqsRequestContextHelper { // SQS/SNS message attributes collection size limit according to diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs rename to src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs index 45f44990fa..cfe932fa50 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs @@ -18,7 +18,7 @@ using System.Collections.Generic; using System.Diagnostics; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class Utils { diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj similarity index 100% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/OpenTelemetry.Contrib.Instrumentation.AWS.csproj rename to src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md b/src/OpenTelemetry.Instrumentation.AWS/README.md similarity index 68% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md rename to src/OpenTelemetry.Instrumentation.AWS/README.md index 63cf30a491..4579d3d72e 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/README.md +++ b/src/OpenTelemetry.Instrumentation.AWS/README.md @@ -1,12 +1,12 @@ # AWS SDK client instrumentation for OpenTelemetry -[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.AWS) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Contrib.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Instrumentation.AWS) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) -Download the `OpenTelemetry.Contrib.Instrumentation.AWS` package: +Download the `OpenTelemetry.Instrumentation.AWS` package: ```shell -dotnet add package OpenTelemetry.Contrib.Instrumentation.AWS +dotnet add package OpenTelemetry.Instrumentation.AWS ``` Add the AWSXRayIdGenerator and AWSInstrumentation diff --git a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs similarity index 95% rename from src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index 32bcbfe2ba..e7f31fc770 100644 --- a/src/OpenTelemetry.Contrib.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -15,8 +15,8 @@ // using System; -using OpenTelemetry.Contrib.Instrumentation.AWS; -using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +using OpenTelemetry.Instrumentation.AWS; +using OpenTelemetry.Instrumentation.AWS.Implementation; using OpenTelemetry.Internal; namespace OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs index 41426d2a61..b06bd12bec 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -21,11 +21,11 @@ using Amazon.Runtime.Internal; using Moq; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +using OpenTelemetry.Instrumentation.AWS.Implementation; using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Implementation; public class RequestContextHelperTests { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index d2d8107015..b1dcd3e782 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -18,12 +18,12 @@ using System.Collections.Generic; using Amazon.Runtime; using Amazon.Runtime.Internal; -using OpenTelemetry.Contrib.Instrumentation.AWS.Implementation; +using OpenTelemetry.Instrumentation.AWS.Implementation; using Xunit; using SNS = Amazon.SimpleNotificationService.Model; using SQS = Amazon.SQS.Model; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests.Implementation; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Implementation; internal static class TestsHelper { internal static Action>? CreateAddAttributesAction(string serviceType, IRequestContext context) diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj similarity index 88% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj rename to test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 8173c3ff18..12bed49ef2 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/OpenTelemetry.Contrib.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -1,7 +1,7 @@ - Unit test project for AWS client instrumentation for OpenTelemetry + Unit test project for AWS client instrumentation for OpenTelemetry. netcoreapp3.1 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) @@ -21,7 +21,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 148e61acce..2bca456c94 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -25,10 +25,11 @@ using Amazon.SQS; using Amazon.SQS.Model; using Moq; +using OpenTelemetry.Instrumentation.AWS.Tests.Tools; using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests; public class TestAWSClientInstrumentation { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index d4889e9fbd..e29faa82df 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -30,7 +30,7 @@ #endif using Amazon.Util; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal static class CustomResponses { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs similarity index 98% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index d1dc94d124..d8546852d2 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -22,7 +22,7 @@ using System.Net.Http.Headers; using Amazon.Runtime.Internal.Transform; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal class CustomWebResponse : IWebResponseData { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index 80f6d26bfa..8d1f66d5a8 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -20,7 +20,7 @@ using System.Threading.Tasks; using Amazon.Runtime.Internal.Transform; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal class HttpResponseMessageBody : IHttpResponseBody { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs similarity index 99% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index 29c0ceeb26..fee082681a 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -28,7 +28,7 @@ using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Transform; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; #if NETFRAMEWORK internal class MockHttpRequest : IHttpRequest { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index 8fffae1b0e..03d63c41f4 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -23,7 +23,7 @@ #endif using Amazon.Runtime; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; #if NETFRAMEWORK internal class MockHttpRequestFactory : IHttpRequestFactory { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs similarity index 99% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 56439d0aa2..89c4206bf8 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -25,7 +25,7 @@ #endif using System.Reflection; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal class MockWebResponse { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs similarity index 94% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs index 5085ca5f25..c22998167c 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs @@ -18,7 +18,7 @@ using Amazon.DynamoDBv2; using Amazon.Runtime; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal class TestAmazonDynamoDBClient : AmazonDynamoDBClient { diff --git a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs rename to test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs index e24e6899f3..764dd090bc 100644 --- a/test/OpenTelemetry.Contrib.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -21,7 +21,7 @@ using System.Linq; using System.Reflection; -namespace OpenTelemetry.Contrib.Instrumentation.AWS.Tests; +namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal static class Utils { From aac6b67878b7561b85da19c00ecb7f2f67f78ca4 Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Thu, 27 Jul 2023 12:39:49 +0200 Subject: [PATCH 0763/1499] Rename package: [OpenTelemetry.Contrib.Extensions.AWSXRay] to [OpenTelemetry.Extensions.AWS] (#1232) --- ...ions_awsxray.md => comp_extensions_aws.md} | 8 ++--- ...ion_aws.md => comp_instrumentation_aws.md} | 0 ...a.md => comp_instrumentation_awslambda.md} | 0 .github/component_owners.yml | 12 ++++---- ...AWSXRay.yml => package-Extensions.AWS.yml} | 6 ++-- opentelemetry-dotnet-contrib.sln | 4 +-- .../.publicApi/net462/PublicAPI.Unshipped.txt | 9 ------ .../netstandard2.0/PublicAPI.Shipped.txt | 29 ------------------- .../netstandard2.0/PublicAPI.Unshipped.txt | 19 ------------ .../.publicApi/net462/PublicAPI.Shipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 9 ++++++ .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 9 ++++++ .../AWSXRayEventSource.cs | 2 +- .../AWSXRayIdGenerator.cs | 6 ++-- .../AssemblyInfo.cs | 4 +-- .../CHANGELOG.md | 7 +++-- .../OpenTelemetry.Extensions.AWS.csproj} | 5 ++-- .../README.md | 6 ++-- .../Trace/AWSXRayPropagator.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- .../AWSXRayIdGeneratorTests.cs} | 6 ++-- .../AssemblyInfo.cs | 0 ...OpenTelemetry.Extensions.AWS.Tests.csproj} | 2 +- .../Trace/AWSXRayPropagatorTests.cs} | 8 ++--- 25 files changed, 61 insertions(+), 95 deletions(-) rename .github/ISSUE_TEMPLATE/{comp_contrib_extensions_awsxray.md => comp_extensions_aws.md} (82%) rename .github/ISSUE_TEMPLATE/{comp_contrib_instrumentation_aws.md => comp_instrumentation_aws.md} (100%) rename .github/ISSUE_TEMPLATE/{comp_contrib_instrumentation_awslambda.md => comp_instrumentation_awslambda.md} (100%) rename .github/workflows/{package-Extensions.AWSXRay.yml => package-Extensions.AWS.yml} (91%) delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/.publicApi/net462/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/AWSXRayEventSource.cs (97%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/AWSXRayIdGenerator.cs (97%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/AssemblyInfo.cs (60%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/CHANGELOG.md (90%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj => OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj} (77%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/README.md (89%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/Trace/AWSXRayPropagator.cs (99%) rename src/{OpenTelemetry.Contrib.Extensions.AWSXRay => OpenTelemetry.Extensions.AWS}/TracerProviderBuilderExtensions.cs (97%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs => OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs} (96%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests => OpenTelemetry.Extensions.AWS.Tests}/AssemblyInfo.cs (100%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj => OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj} (88%) rename test/{OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs => OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs} (97%) diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md b/.github/ISSUE_TEMPLATE/comp_extensions_aws.md similarity index 82% rename from .github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md rename to .github/ISSUE_TEMPLATE/comp_extensions_aws.md index 52699a97ff..112dbf18df 100644 --- a/.github/ISSUE_TEMPLATE/comp_contrib_extensions_awsxray.md +++ b/.github/ISSUE_TEMPLATE/comp_extensions_aws.md @@ -1,10 +1,10 @@ --- -name: OpenTelemetry.Contrib.Extensions.AWSXRay -about: Issue with OpenTelemetry.Contrib.Extensions.AWSXRay -labels: comp:contrib.extensions.awsxray +name: OpenTelemetry.Extensions.AWS +about: Issue with OpenTelemetry.Extensions.AWS +labels: comp:extensions.aws --- -# Issue with OpenTelemetry.Contrib.Extensions.AWSXRay +# Issue with OpenTelemetry.Extensions.AWS List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aws.md similarity index 100% rename from .github/ISSUE_TEMPLATE/comp_contrib_instrumentation_aws.md rename to .github/ISSUE_TEMPLATE/comp_instrumentation_aws.md diff --git a/.github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_awslambda.md similarity index 100% rename from .github/ISSUE_TEMPLATE/comp_contrib_instrumentation_awslambda.md rename to .github/ISSUE_TEMPLATE/comp_instrumentation_awslambda.md diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 4841c948b2..9017e7cb89 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -3,9 +3,6 @@ # Each component identified by its path prefix has a list of users # Please add the entries in alphabetically sorted order components: - src/OpenTelemetry.Contrib.Extensions.AWSXRay/: - - srprash - - atshaw43 src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch @@ -23,6 +20,9 @@ components: - SergeyKanzhelev src/OpenTelemetry.Extensions/: - codeblanch + src/OpenTelemetry.Extensions.AWS/: + - srprash + - atshaw43 src/OpenTelemetry.Extensions.Enrichment/: - xakep139 src/OpenTelemetry.Instrumentation.AWS/: @@ -70,9 +70,6 @@ components: src/OpenTelemetry.Sampler.AWS/: - srprash - atshaw43 - test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/: - - srprash - - atshaw43 test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch @@ -105,6 +102,9 @@ components: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: - codeblanch + test/OpenTelemetry.Extensions.AWS.Tests/: + - srprash + - atshaw43 test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 test/OpenTelemetry.Instrumentation.AWS.Tests/: diff --git a/.github/workflows/package-Extensions.AWSXRay.yml b/.github/workflows/package-Extensions.AWS.yml similarity index 91% rename from .github/workflows/package-Extensions.AWSXRay.yml rename to .github/workflows/package-Extensions.AWS.yml index dd177767be..0fc49d3e51 100644 --- a/.github/workflows/package-Extensions.AWSXRay.yml +++ b/.github/workflows/package-Extensions.AWS.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Contrib.Extensions.AWSXRay +name: Pack OpenTelemetry.Extensions.AWS on: workflow_dispatch: @@ -9,7 +9,7 @@ on: default: 'warning' push: tags: - - 'Extensions.AWSXRay-*' # trigger when we create a tag with prefix "Extensions.AWSXRay-" + - 'Extensions.AWS-*' # trigger when we create a tag with prefix "Extensions.AWS-" jobs: build-test-pack: @@ -17,7 +17,7 @@ jobs: permissions: contents: write env: - PROJECT: OpenTelemetry.Contrib.Extensions.AWSXRay + PROJECT: OpenTelemetry.Extensions.AWS strategy: matrix: diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 9de655cacd..7bd927de27 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -111,9 +111,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Client.NetFram EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Server.NetFramework", "examples\wcf\server-netframework\Examples.Wcf.Server.NetFramework.csproj", "{E205AA70-36BD-461D-8B87-909ED1BCA721}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay", "src\OpenTelemetry.Contrib.Extensions.AWSXRay\OpenTelemetry.Contrib.Extensions.AWSXRay.csproj", "{D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AWS", "src\OpenTelemetry.Extensions.AWS\OpenTelemetry.Extensions.AWS.csproj", "{D8C9AD2A-5C6A-46F5-A216-3D67E6C0FA94}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Extensions.AWSXRay.Tests", "test\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests\OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj", "{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.AWS.Tests", "test\OpenTelemetry.Extensions.AWS.Tests\OpenTelemetry.Extensions.AWS.Tests.csproj", "{9CE513AC-CFC5-4DD1-9F16-8719EDCE9BF9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AWS", "src\OpenTelemetry.Instrumentation.AWS\OpenTelemetry.Instrumentation.AWS.csproj", "{970673DA-F308-4960-A58D-ECCEA44CEF6B}" EndProject diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index 94d28c0a6e..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,9 +0,0 @@ -OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator -OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator -OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 724b124e9b..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,29 +0,0 @@ -#nullable enable -OpenTelemetry.Contrib.Extensions.AWSXRay.AWSXRayIdGenerator -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.AWSECSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.AWSLambdaResourceDetector() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils -OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void -OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator -OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! -override OpenTelemetry.Contrib.Extensions.AWSXRay.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 639ff112a6..0000000000 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,19 +0,0 @@ -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEBSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEC2ResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.AWSECSResourceDetector() -> void -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSECSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSEKSResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.AWSLambdaResourceDetector() -> void -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.AWSLambdaResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.IResourceDetector.Detect() -> System.Collections.Generic.IEnumerable>? -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils -*REMOVED*OpenTelemetry.Contrib.Extensions.AWSXRay.Resources.ResourceDetectorUtils.ResourceDetectorUtils() -> void diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a7a1588b77 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator +OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator +OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a7a1588b77 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,9 @@ +OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator +OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator +OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs rename to src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs index 1dff10cda4..5421a5f7c3 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs @@ -18,7 +18,7 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay; +namespace OpenTelemetry.Extensions.AWS; [EventSource(Name = "OpenTelemetry-AWS-XRay")] internal class AWSXRayEventSource : EventSource diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs rename to src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs index 7741963524..0f3b6d6a3a 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs @@ -21,7 +21,7 @@ using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay; +namespace OpenTelemetry.Extensions.AWS; /// /// Generate AWS X-Ray compatible trace id and replace the trace id of root activity. @@ -48,7 +48,7 @@ internal static void ReplaceTraceId(Sampler? sampler = null) { if (string.IsNullOrEmpty(activity.ParentId)) { - var awsXRayTraceId = GenerateAWSXRayCompatiableTraceId(); + var awsXRayTraceId = GenerateAWSXRayCompatibleTraceId(); // TODO: Apply API to directly modify trace id once .NET runtime publicizes it. activity.SetParentId(awsXRayTraceId, default, activity.ActivityTraceFlags); @@ -69,7 +69,7 @@ internal static void ReplaceTraceId(Sampler? sampler = null) ActivitySource.AddActivityListener(awsXRayActivityListener); } - internal static ActivityTraceId GenerateAWSXRayCompatiableTraceId() + internal static ActivityTraceId GenerateAWSXRayCompatibleTraceId() { var epoch = (int)DateTime.UtcNow.ToUnixTimeSeconds(); // first 8 digit as time stamp diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs similarity index 60% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs rename to src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs index d5ed93f820..5c51b1ac1a 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs @@ -17,7 +17,7 @@ using System.Runtime.CompilerServices; #if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Extensions.AWSXRay.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else -[assembly: InternalsVisibleTo("OpenTelemetry.Contrib.Extensions.AWSXRay.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Extensions.AWS.Tests")] #endif diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md similarity index 90% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md rename to src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index d65af8032b..cf35f2b9bc 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -1,7 +1,10 @@ -# Changelog - OpenTelemetry.Contrib.Extensions.AWSXRay +# Changelog - OpenTelemetry.Extensions.AWS ## Unreleased +* Rename package from `OpenTelemetry.Contrib.Extensions.AWSXRay` + to `OpenTelemetry.Extensions.AWS` + ([#1232](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1232)) * Updates to 1.5.1 of OpenTelemetry SDK. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) * Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random @@ -41,7 +44,7 @@ Released 2022-May-18 Released 2021-Sep-20 * Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) -* Updated OpenTelemetry SDK package version to 1.1.0 +* Updated OTel SDK package version to 1.1.0 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) ## 1.0.1 diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj similarity index 77% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj rename to src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index 797ef8aca7..9ba1117ac4 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/OpenTelemetry.Contrib.Extensions.AWSXRay.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -1,8 +1,9 @@ - netstandard2.0;$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry extensions for AWS X-Ray. + netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry extensions for AWS. Extensions.AWSXRay- enable true diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md b/src/OpenTelemetry.Extensions.AWS/README.md similarity index 89% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md rename to src/OpenTelemetry.Extensions.AWS/README.md index 21a9ef7a76..6822096863 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md +++ b/src/OpenTelemetry.Extensions.AWS/README.md @@ -10,13 +10,13 @@ by using AWS Distro with the OpenTelemetry SDK. The OpenTelemetry SDK generates traces with W3C random ID which X-Ray backend doesn't currently support. You need to install the -`OpenTelemetry.Contrib.Extensions.AWSXRay` to be able to use the +`OpenTelemetry.Extensions.AWS` to be able to use the AWS X-Ray id generator which generates X-Ray compatible trace IDs. If you plan to call another application instrumented with AWS X-Ray SDK, you'll need to configure the AWS X-Ray propagator as well. ```shell -dotnet add package OpenTelemetry.Contrib.Extensions.AWSXRay +dotnet add package OpenTelemetry.Extensions.AWS ``` ## Usage @@ -29,7 +29,7 @@ very beginning when creating `TracerProvider`. ```csharp using OpenTelemetry; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Extensions.AWS.Trace; using OpenTelemetry.Trace; var tracerProvider = Sdk.CreateTracerProviderBuilder() diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs similarity index 99% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs rename to src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs index 73ae58c161..26cdc51200 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs @@ -23,7 +23,7 @@ using System.Text; using OpenTelemetry.Context.Propagation; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +namespace OpenTelemetry.Extensions.AWS.Trace; /// /// Propagator for AWS X-Ray. See https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader. diff --git a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs similarity index 97% rename from src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs rename to src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs index 7257b70fb0..4cedad468b 100644 --- a/src/OpenTelemetry.Contrib.Extensions.AWSXRay/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs @@ -14,7 +14,7 @@ // limitations under the License. // -using OpenTelemetry.Contrib.Extensions.AWSXRay; +using OpenTelemetry.Extensions.AWS; using OpenTelemetry.Internal; namespace OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs similarity index 96% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs rename to test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs index ff779da30d..087c80aa72 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/TestAWSXRayIdGenerator.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,9 +19,9 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests; +namespace OpenTelemetry.Extensions.AWS.Tests; -public class TestAWSXRayIdGenerator +public class AWSXRayIdGeneratorTests { [Fact] public void TestGenerateTraceIdForRootNode() diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/AssemblyInfo.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AssemblyInfo.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/AssemblyInfo.cs rename to test/OpenTelemetry.Extensions.AWS.Tests/AssemblyInfo.cs diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj similarity index 88% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj rename to test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 908d078099..73a3269b37 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs similarity index 97% rename from test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs rename to test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs index b3a6b4aa35..565dd88746 100644 --- a/test/OpenTelemetry.Contrib.Extensions.AWSXRay.Tests/Trace/TestAWSXRayPropagator.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,12 +18,12 @@ using System.Collections.Generic; using System.Diagnostics; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Extensions.AWS.Trace; using Xunit; -namespace OpenTelemetry.Contrib.Extensions.AWSXRay.Tests; +namespace OpenTelemetry.Extensions.AWS.Tests; -public class TestAWSXRayPropagator +public class AWSXRayPropagatorTests { private const string AWSXRayTraceHeaderKey = "X-Amzn-Trace-Id"; private const string TraceId = "5759e988bd862e3fe1be46a994272793"; From e96f03de4a6ea1bea81d9d4ed997662bcd025685 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Thu, 27 Jul 2023 16:21:59 -0700 Subject: [PATCH 0764/1499] [OpenTelemetry.ResourceDetectors.Azure] Fix Readme bug - Swap cloud.platform and cloud.provider value for Azure VM Resource detector (#1284) --- src/OpenTelemetry.ResourceDetectors.Azure/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 4cf2660f6e..b779b421fb 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -34,8 +34,8 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() | Attribute | Description | |-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | azure.app.service.stamp | The specific "stamp" cluster within Azure where the App Service is running, e.g., "waws-prod-sn1-001". | -| cloud.provider | The cloud service provider. In this context, it's always "azure". | | cloud.platform | The cloud platform. Here, it's always "azure_app_service". | +| cloud.provider | The cloud service provider. In this context, it's always "azure". | | cloud.resource_id | The Azure Resource Manager URI uniquely identifying the Azure App Service. Typically in the format "/subscriptions/{subscriptionId}/resourceGroups/{groupName}/providers/Microsoft.Web/sites/{siteName}". | | cloud.region | The Azure region where the App Service is hosted, e.g., "East US", "West Europe", etc. | | deployment.environment | The deployment slot where the Azure App Service is running, such as "staging", "production", etc. | @@ -65,8 +65,8 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() |--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | azure.vm.scaleset.name | The name of the Virtual Machine Scale Set if the VM is part of one. | | azure.vm.sku | The SKU of the Azure Virtual Machine's operating system. For instance, for a VM running Windows Server 2019 Datacenter edition, this value would be "2019-Datacenter". | -| cloud.platform | The cloud platform, which is always set to "azure" in this context. | -| cloud.provider | The cloud service provider, which is always set to "azure_vm" in this context. | +| cloud.platform | The cloud platform, which is always set to "azure_vm" in this context. | +| cloud.provider | The cloud service provider, which is always set to "azure" in this context. | | cloud.region | The Azure region where the Virtual Machine is hosted, such as "East US", "West Europe", etc. | | cloud.resource_id | The Azure Resource Manager URI uniquely identifying the Azure Virtual Machine. It typically follows this format: "/subscriptions/{subscriptionId}/resourceGroups/{groupName}/providers/Microsoft.Compute/virtualMachines/{vmName}". | | host.id | A unique identifier for the VM host, for instance, "02aab8a4-74ef-476e-8182-f6d2ba4166a6". | From 6d05fb77996437842e262c536d8429bbe773a1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 28 Jul 2023 02:13:11 +0200 Subject: [PATCH 0765/1499] Add Copyrights for libraries (#1282) --- build/Common.prod.props | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Common.prod.props b/build/Common.prod.props index 8e00384709..f6cf6b8c54 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -8,6 +8,7 @@ Apache-2.0 opentelemetry-icon-color.png OpenTelemetry authors + Copyright The OpenTelemetry Authors true $(MSBuildThisFileDirectory)/OpenTelemetryContrib.prod.ruleset $(NoWarn),1573,1712 From 6352ed21d96ffdf20bb27af0b57970a266c92e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 28 Jul 2023 07:22:37 +0200 Subject: [PATCH 0766/1499] [Instrumentation.AWS] tests against net6.0 (#1283) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 2 +- .../OpenTelemetry.Instrumentation.AWS.csproj | 3 ++- .../OpenTelemetry.Instrumentation.AWS.Tests.csproj | 2 +- .../Tools/CustomWebResponse.cs | 14 ++++++-------- .../Tools/MockHttpRequest.cs | 4 ++-- .../Tools/Utils.cs | 2 +- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index e091c42157..6ad749ae64 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -4,7 +4,7 @@ * BREAKING (renaming): renamed `OpenTelemetry.Contrib.Instrumentation.AWS` to `OpenTelemetry.Instrumentation.AWS` ([#1275](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1275)) -* Raised the minimum .NET version to `net462` +* Raised the minimum .NET Framework version to `net462` ([#1095](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1095)) * Removes `AddAWSInstrumentation` method with default configure default parameter. ([#1117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1117)) diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index 31fd85a320..b9f79ab96e 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -2,7 +2,8 @@ - netstandard2.0;$(NetFrameworkMinimumSupportedVersion) + netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) AWS client instrumentation for OpenTelemetry .NET Instrumentation.AWS- enable diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 12bed49ef2..8a16e01d8e 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for AWS client instrumentation for OpenTelemetry. - netcoreapp3.1 + net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) enable diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index d8546852d2..b0c79d23e3 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -28,7 +28,7 @@ internal class CustomWebResponse : IWebResponseData { private HttpResponseMessageBody response; private string[]? headerNames; - private Dictionary? headers; + private Dictionary? headers; private HashSet? headerNamesSet; public CustomWebResponse(HttpResponseMessage response) @@ -64,10 +64,9 @@ public static IWebResponseData GenerateWebResponse(HttpResponseMessage response) return new CustomWebResponse(response); } - public string GetHeaderValue(string headerName) + public string? GetHeaderValue(string headerName) { - string? headerValue; - if (this.headers != null && this.headers.TryGetValue(headerName, out headerValue)) + if (this.headers != null && this.headers.TryGetValue(headerName, out var headerValue)) { return headerValue; } @@ -88,7 +87,7 @@ public bool IsHeaderPresent(string headerName) private void CopyHeaderValues(HttpResponseMessage response) { List headerNames = new List(); - this.headers = new Dictionary(10, StringComparer.OrdinalIgnoreCase); + this.headers = new Dictionary(10, StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair> kvp in response.Headers) { @@ -114,10 +113,9 @@ private void CopyHeaderValues(HttpResponseMessage response) this.headerNamesSet = new HashSet(this.headerNames, StringComparer.OrdinalIgnoreCase); } - private string GetFirstHeaderValue(HttpHeaders headers, string key) + private string? GetFirstHeaderValue(HttpHeaders headers, string key) { - IEnumerable? headerValues = null; - if (headers.TryGetValues(key, out headerValues)) + if (headers.TryGetValues(key, out var headerValues)) { return headerValues.FirstOrDefault(); } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index fee082681a..b4da75a7d4 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -202,7 +202,7 @@ public HttpContent GetRequestContent() this.IsGetRequestContentCalled = true; try { - return new HttpRequestMessage().Content; + return new HttpRequestMessage().Content!; } catch (AggregateException e) { @@ -212,7 +212,7 @@ public HttpContent GetRequestContent() public Task GetRequestContentAsync() { - return Task.FromResult(new HttpRequestMessage().Content); + return Task.FromResult(new HttpRequestMessage().Content!); } public IWebResponseData GetResponse() diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs index 764dd090bc..1c4bc1348f 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -60,7 +60,7 @@ public static string GetResourceText(string resourceName) public static string FindResourceName(string partialName) { #pragma warning disable CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf' - return FindResourceName(s => s.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) >= 0).SingleOrDefault(); + return FindResourceName(s => s.IndexOf(partialName, StringComparison.OrdinalIgnoreCase) >= 0).Single(); #pragma warning restore CA2249 // Consider using 'string.Contains' instead of 'string.IndexOf' } From 7720945b47c9be721222c49468be326ea7024d6b Mon Sep 17 00:00:00 2001 From: Will Rogers Date: Fri, 28 Jul 2023 01:47:45 -0400 Subject: [PATCH 0767/1499] [Extensions.AWS] Add net6.0 target framework, optimize AWSXRayIdGenerator (#1096) --- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 11 +++ .../AWSXRayIdGenerator.cs | 3 +- .../AWSXRayIdGenerator.net6.cs | 71 +++++++++++++++++++ src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 3 + .../OpenTelemetry.Extensions.AWS.csproj | 2 +- .../Trace/AWSXRayPropagator.cs | 4 +- .../TracerProviderBuilderExtensions.cs | 10 +++ .../AWSXRayIdGeneratorTests.cs | 9 +++ 9 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..70b757cca5 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,11 @@ +OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator +OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator +OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void +static OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator.ReplaceTraceId() -> void +static OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator.ReplaceTraceId(OpenTelemetry.Trace.Sampler! sampler) -> void +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs index 0f3b6d6a3a..a1d657fcae 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs @@ -14,6 +14,7 @@ // limitations under the License. // +#if !NET6_0_OR_GREATER using System; using System.Diagnostics; using System.Globalization; @@ -50,7 +51,6 @@ internal static void ReplaceTraceId(Sampler? sampler = null) { var awsXRayTraceId = GenerateAWSXRayCompatibleTraceId(); - // TODO: Apply API to directly modify trace id once .NET runtime publicizes it. activity.SetParentId(awsXRayTraceId, default, activity.ActivityTraceFlags); // When not using instrumented library and creating root activity using ActivitySource.StartActivity(), @@ -197,3 +197,4 @@ private static ActivitySamplingResult ComputeRootActivitySamplingResult( return ActivitySamplingResult.PropagationData; } } +#endif diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs new file mode 100644 index 0000000000..c927280235 --- /dev/null +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs @@ -0,0 +1,71 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NET6_0_OR_GREATER +using System; +using System.Buffers.Binary; +using System.Diagnostics; +using System.Security.Cryptography; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Extensions.AWS; + +/// +/// Generate AWS X-Ray compatible trace IDs. +/// See https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids. +/// +public static class AWSXRayIdGenerator +{ + /// + /// Sets to . + /// + public static void ReplaceTraceId() + { + Activity.TraceIdGenerator = GenerateAWSXRayCompatibleTraceId; + } + + /// + /// Sets to . + /// + /// Unused. (See deprecation message.) + [Obsolete($"When targeting .NET 6.0 or later, the X-Ray ID generator does not need to update the sampling decision. Use ${nameof(ReplaceTraceId)}() instead.")] + public static void ReplaceTraceId(Sampler sampler) + { + ReplaceTraceId(); + } + + /// + /// Generates an AWS X-Ray compatible trace ID. + /// + /// + /// An whose first 4 bytes are the big-endian unix timestamp (in seconds) and whose + /// remaining 12 bytes are randomly generated. + /// + internal static ActivityTraceId GenerateAWSXRayCompatibleTraceId() + { + Span buffer = stackalloc byte[16]; + + // intentionally truncating to 4 bytes because AWS X-Ray requires 8 hex characters + var seconds = (uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + _ = BinaryPrimitives.TryWriteUInt32BigEndian(buffer, seconds); + + // fill the rest of the buffer with random bytes + RandomNumberGenerator.Fill(buffer.Slice(4, 12)); + + return ActivityTraceId.CreateFromBytes(buffer); + } +} +#endif diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index cf35f2b9bc..33257a2e83 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -21,6 +21,9 @@ supporting ResourceBuilderExtensions extension, and migrate all detectors to implement OpenTelemetry.Resources.IResourceDetector ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) +* Add a `net6.0` build with optimized trace ID generation using the new + `Activity.TraceIdGenerator` API. + ([#1096](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1096)) * Drop support for `AWSLambdaResourceDetector`. AWS Lambda Resources are detected by `OpenTelemetry.Instrumentation.AWSLambda` package diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index 9ba1117ac4..86a64ddf2f 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + net6.0;netstandard2.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Extensions.AWSXRay- diff --git a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs index 26cdc51200..a79e282514 100644 --- a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs @@ -306,9 +306,9 @@ internal static string ToXRayTraceIdFormat(string traceId) sb.Append(Version); sb.Append(TraceIdDelimiter); - sb.Append(traceId.Substring(0, EpochHexDigits)); + sb.Append(traceId, 0, EpochHexDigits); sb.Append(TraceIdDelimiter); - sb.Append(traceId.Substring(EpochHexDigits)); + sb.Append(traceId, EpochHexDigits, traceId.Length - EpochHexDigits); return sb.ToString(); } diff --git a/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs index 4cedad468b..e960d3e335 100644 --- a/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs @@ -37,6 +37,15 @@ public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder bu return builder; } +#if NET6_0_OR_GREATER + /// + /// Replace the trace id of root activity. + /// + /// being configured. + /// Unused. (See deprecation message.) + /// The instance of . + [System.Obsolete($"When targeting .NET 6.0 or later, the X-Ray ID generator does not need to update the sampling decision. Use ${nameof(AddXRayTraceId)} instead.")] +#else /// /// 1. Replace the trace id of root activity. /// 2. Update the sampling decision for root activity when it's created through ActivitySource.StartActivity(). @@ -44,6 +53,7 @@ public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder bu /// being configured. /// being used. /// The instance of . +#endif public static TracerProviderBuilder AddXRayTraceIdWithSampler(this TracerProviderBuilder builder, Sampler sampler) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs index 087c80aa72..2c076a348c 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs @@ -36,7 +36,12 @@ public void TestGenerateTraceIdForRootNode() activity.Start(); Assert.NotEqual(originalTraceId, activity.TraceId); +#if NET6_0_OR_GREATER + // the net6.0 version of AWSXRayIdGenerator uses Activity.TraceIdGenerator, which does not change the parent ID + Assert.Equal(originalParentSpanId, activity.ParentSpanId); +#else Assert.NotEqual(originalParentSpanId, activity.ParentSpanId); +#endif Assert.Equal("0000000000000000", activity.ParentSpanId.ToHexString()); Assert.Equal(originalTraceFlag, activity.ActivityTraceFlags); } @@ -81,11 +86,13 @@ public void TestGenerateTraceIdForNonRootNodeNotSampled() [Fact] public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSamplerOn() { +#pragma warning disable CS0618 // Type or member is obsolete using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceIdWithSampler(new TraceIdRatioBasedSampler(1.0)) .AddSource("TestTraceIdBasedSamplerOn") .SetSampler(new TraceIdRatioBasedSampler(1.0)) .Build()) +#pragma warning restore CS0618 // Type or member is obsolete { using (var activitySource = new ActivitySource("TestTraceIdBasedSamplerOn")) { @@ -100,11 +107,13 @@ public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSam [Fact] public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSamplerOff() { +#pragma warning disable CS0618 // Type or member is obsolete using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceIdWithSampler(new TraceIdRatioBasedSampler(0.0)) .AddSource("TestTraceIdBasedSamplerOff") .SetSampler(new TraceIdRatioBasedSampler(0.0)) .Build()) +#pragma warning restore CS0618 // Type or member is obsolete { using (var activitySource = new ActivitySource("TestTraceIdBasedSamplerOff")) { From 672db90aabef46cee0eca50d62f722c32297442e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 1 Aug 2023 20:27:36 +0200 Subject: [PATCH 0768/1499] Drop netcoreapp3.1 from CI & update testing framework in Instrumentation.GrpcCore to net6.0 (#1287) --- .github/workflows/ci-Instrumentation.Process.yml | 5 ----- .github/workflows/ci-md.yml | 2 +- .github/workflows/ci.yml | 7 +------ .github/workflows/integration-md.yml | 2 +- .github/workflows/integration.yml | 2 +- build/docker-compose.netcoreapp3.1.yml | 9 --------- opentelemetry-dotnet-contrib.sln | 1 - .../ClientTracingInterceptorOptions.cs | 2 +- .../FoobarService.cs | 2 +- .../GrpcCoreClientInterceptorTests.cs | 11 +++++++---- .../GrpcCoreServerInterceptorTests.cs | 2 +- .../InterceptorActivityListener.cs | 2 +- ...penTelemetry.Instrumentation.GrpcCore.Tests.csproj | 6 +++--- .../proto/foobar.proto | 6 +++--- 14 files changed, 21 insertions(+), 38 deletions(-) delete mode 100644 build/docker-compose.netcoreapp3.1.yml diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index 206594fad6..0d42111c65 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -21,11 +21,6 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Install .NET 3.1 SDK - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '3.1.x' - - name: Install .NET 7 SDK uses: actions/setup-dotnet@v3.2.0 with: diff --git a/.github/workflows/ci-md.yml b/.github/workflows/ci-md.yml index 6a3744f18e..862dec8659 100644 --- a/.github/workflows/ci-md.yml +++ b/.github/workflows/ci-md.yml @@ -20,7 +20,7 @@ jobs: strategy: matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, netcoreapp3.1, net6.0, net7.0 ] + version: [ net462, net6.0, net7.0 ] exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a89029349b..269d4dc8a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, netcoreapp3.1, net6.0, net7.0 ] + version: [ net462, net6.0, net7.0 ] exclude: - os: ubuntu-latest version: net462 @@ -26,11 +26,6 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Install .NET 3.1 SDK - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '3.1.x' - - name: Install .NET 7 SDK uses: actions/setup-dotnet@v3.2.0 with: diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index a248d6ccb0..66a9949582 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - version: [netcoreapp3.1,net6.0,net7.0] + version: [net6.0,net7.0] steps: - run: 'echo "No build required"' diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 77ca42fb6d..e6e376aad3 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - version: [netcoreapp3.1,net6.0,net7.0] + version: [net6.0,net7.0] steps: - uses: actions/checkout@v3 diff --git a/build/docker-compose.netcoreapp3.1.yml b/build/docker-compose.netcoreapp3.1.yml deleted file mode 100644 index ce7102f66c..0000000000 --- a/build/docker-compose.netcoreapp3.1.yml +++ /dev/null @@ -1,9 +0,0 @@ -version: '3.7' - -services: - tests: - build: - args: - PUBLISH_FRAMEWORK: netcoreapp3.1 - TEST_SDK_VERSION: 3.1 - BUILD_SDK_VERSION: 7.0 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7bd927de27..bbaebdd629 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -74,7 +74,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\debug.snk = build\debug.snk 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.netcoreapp3.1.yml = build\docker-compose.netcoreapp3.1.yml build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 79b23e9320..a7a8a4b10d 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -35,7 +35,7 @@ public class ClientTracingInterceptorOptions public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; /// - /// Gets or sets a custom identfier used during unit testing. + /// Gets or sets a custom identifier used during unit testing. /// internal Guid ActivityIdentifierValue { get; set; } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 7bb3af2851..dd830d6f85 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -23,7 +23,7 @@ using Grpc.Core; using Grpc.Core.Interceptors; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test; +namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; /// /// Test implementation of foobar. diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 53e8b810f0..2267ae99dd 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -25,7 +25,7 @@ using OpenTelemetry.Context.Propagation; using Xunit; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test; +namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; /// /// Grpc Core client interceptor tests. @@ -333,7 +333,7 @@ internal static void ValidateCommonActivityTags( // TagObjects contain non string values // Tags contains only string values Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcSystem && (string)t.Value == "grpc"); - Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcService && (string)t.Value == "OpenTelemetry.Instrumentation.GrpcCore.Test.Foobar"); + Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcService && (string)t.Value == "OpenTelemetry.Instrumentation.GrpcCore.Tests.Foobar"); Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcMethod); Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcGrpcStatusCode && (int)t.Value == (int)expectedStatusCode); @@ -435,8 +435,11 @@ private static async Task TestHandlerSuccess(Func /// Grpc Core server interceptor tests. diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index 662f013ec5..b3aca77c7b 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -18,7 +18,7 @@ using System.Diagnostics; using System.Linq; -namespace OpenTelemetry.Instrumentation.GrpcCore.Test; +namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; /// /// This class listens for a single Activity created by the Grpc Core interceptors. diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index d759e09e21..76ffd2ebd3 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -1,7 +1,7 @@ - + - netcoreapp3.1 + net6.0 @@ -14,7 +14,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto index 635c0383d9..18508211cd 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/proto/foobar.proto @@ -1,5 +1,5 @@ -syntax = "proto3"; -package OpenTelemetry.Instrumentation.GrpcCore.Test; +syntax = "proto3"; +package OpenTelemetry.Instrumentation.GrpcCore.Tests; service Foobar { rpc Unary (FoobarRequest) returns (FoobarResponse) {} @@ -14,4 +14,4 @@ message FoobarRequest { message FoobarResponse { string message = 1; -} \ No newline at end of file +} From e0eeb0a21ed9039381fdbf84871e0fb01f37613a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 2 Aug 2023 07:07:14 +0200 Subject: [PATCH 0769/1499] [Extensions.AWS, ResourceDetectors.AWS] Release 1.3.0-beta.1 (#1285) --- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Extensions.AWS.csproj | 2 +- src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 33257a2e83..123106331e 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.3.0-beta.1 + +Released 2023-Aug-02 + * Rename package from `OpenTelemetry.Contrib.Extensions.AWSXRay` to `OpenTelemetry.Extensions.AWS` ([#1232](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1232)) diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index 86a64ddf2f..9f6f6adb14 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -4,7 +4,7 @@ net6.0;netstandard2.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. - Extensions.AWSXRay- + Extensions.AWS- enable true diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 0422bb85ce..bbc803c488 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.3.0-beta.1 + +Released 2023-Aug-02 + * Initial release. Previously it was part of `OpenTelemetry.Contrib.Extensions.AWSXRay` package. ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) From 1b7cda5dd4c58158431a5828e801fdadf001c352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 2 Aug 2023 20:33:11 +0200 Subject: [PATCH 0770/1499] Bump common dependencies (#1290) --- build/Common.nonprod.props | 10 +++++----- build/Common.props | 6 +++--- .../TLDExporter/TldTraceExporter.cs | 1 + .../OpenTelemetry.Extensions.csproj | 2 +- .../Implementation/SnsRequestContextHelper.cs | 1 + .../Implementation/SqsRequestContextHelper.cs | 1 + .../AzureVmMetadataResponse.cs | 1 + .../ResourceAttributeConstants.cs | 1 + src/OpenTelemetry.Sampler.AWS/RateLimiter.cs | 1 + src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs | 1 + .../InfluxDBMetricsExporterTests.cs | 12 ++++++------ .../Implementation/TestsHelper.cs | 1 + .../Tools/MockHttpRequest.cs | 1 + .../Tools/MockHttpRequestFactory.cs | 1 + .../MySqlDataTests.cs | 2 +- ...penTelemetry.ResourceDetectors.Azure.Tests.csproj | 2 +- 16 files changed, 27 insertions(+), 17 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 2d2b21bb27..f5d7e68499 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -20,17 +20,17 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [0.13.5,0.14) + [0.13.6,0.14) [3.2.0,4.0.0) [2.3.1,3.0) [5.0.0,7.0) - [17.5.0,18.0) + [17.6.3,18.0) [4.18.4,5.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) - [2.4.5,3.0) - [2.4.2,3.0) - [1.5.21,2.0) + [2.5.0,3.0) + [2.5.0,3.0) + [1.5.32,2.0) diff --git a/build/Common.props b/build/Common.props index 168c874a81..33f16d0985 100644 --- a/build/Common.props +++ b/build/Common.props @@ -26,8 +26,8 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [4.2.0,5.0) - [17.5.0] + [4.3.0,5.0) + [17.6.3] [2.1.0,5.0) [3.1.0,) [1.0.3,2.0) @@ -38,7 +38,7 @@ [1.6.0-alpha.1] [2.1.58,3.0) [3.16.0,4.0) - [1.2.0-beta.435,2.0) + [1.2.0-beta.507,2.0) [4.3.4,) 4.7.0 [6.0.0,) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index 4c482cf890..dba4c41cdd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -24,6 +24,7 @@ using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva.TldExporter; + internal sealed class TldTraceExporter : TldExporter, IDisposable { // TODO: Is using a single ThreadLocal a better idea? diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index a8f69a0230..a012e9da7f 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -2,7 +2,7 @@ - netstandard2.0;net462; + netstandard2.0;net462 net6.0;$(TargetFrameworks) true OpenTelemetry .NET SDK preview features and extensions diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs index f0400363a4..2e4d58461a 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs @@ -21,6 +21,7 @@ using Amazon.SimpleNotificationService.Model; namespace OpenTelemetry.Instrumentation.AWS.Implementation; + internal class SnsRequestContextHelper { // SQS/SNS message attributes collection size limit according to diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs index c242b98400..3b0b110246 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs @@ -21,6 +21,7 @@ using Amazon.SQS.Model; namespace OpenTelemetry.Instrumentation.AWS.Implementation; + internal class SqsRequestContextHelper { // SQS/SNS message attributes collection size limit according to diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs index 385818649a..7dd118a6fc 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs @@ -18,6 +18,7 @@ using OpenTelemetry.Trace; namespace OpenTelemetry.ResourceDetectors.Azure; + internal sealed class AzureVmMetadataResponse { [JsonPropertyName("location")] diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs index 5e5cc95ec2..4b85409779 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs @@ -15,6 +15,7 @@ // namespace OpenTelemetry.ResourceDetectors.Azure; + internal sealed class ResourceAttributeConstants { // AppService resource attributes diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs index aba7ea134d..91d9f52dae 100644 --- a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs +++ b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs @@ -17,6 +17,7 @@ using System.Threading; namespace OpenTelemetry.Sampler.AWS; + internal sealed class RateLimiter { private readonly Clock clock; diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs b/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs index 2a315787c7..37d904f526 100644 --- a/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs @@ -17,6 +17,7 @@ using OpenTelemetry.Trace; namespace OpenTelemetry.Sampler.AWS; + internal class RateLimitingSampler : Trace.Sampler { private readonly RateLimiter limiter; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs index b2109dd2a8..c65d10534b 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -77,7 +77,7 @@ public void ExportIntGaugeMetric(MetricsSchema metricsSchema, string measurement var dataPoint = influxServer.ReadPoint(); Assert.Equal(measurement, dataPoint.Measurement); - Assert.Equal(1, dataPoint.Fields.Count); + Assert.Single(dataPoint.Fields); AssertUtils.HasField(valueKey, 42L, dataPoint.Fields); AssertTags(dataPoint); @@ -121,7 +121,7 @@ public void ExportDoubleGaugeMetric(MetricsSchema metricsSchema, string measurem var dataPoint = influxServer.ReadPoint(); Assert.Equal(measurement, dataPoint.Measurement); - Assert.Equal(1, dataPoint.Fields.Count); + Assert.Single(dataPoint.Fields); AssertUtils.HasField(valueKey, 55.42D, dataPoint.Fields); AssertTags(dataPoint); @@ -163,7 +163,7 @@ public void ExportIntSumMetric(MetricsSchema metricsSchema, string measurement, var dataPoint = influxServer.ReadPoint(); Assert.Equal(measurement, dataPoint.Measurement); - Assert.Equal(1, dataPoint.Fields.Count); + Assert.Single(dataPoint.Fields); AssertUtils.HasField(valueKey, 100L, dataPoint.Fields); AssertTags(dataPoint); @@ -205,7 +205,7 @@ public void ExportDoubleSumMetric(MetricsSchema metricsSchema, string measuremen var dataPoint = influxServer.ReadPoint(); Assert.Equal(measurement, dataPoint.Measurement); - Assert.Equal(1, dataPoint.Fields.Count); + Assert.Single(dataPoint.Fields); AssertUtils.HasField(valueKey, 12.59D, dataPoint.Fields); AssertTags(dataPoint); @@ -248,7 +248,7 @@ public void ExportNonMonotonicIntSumMetric(MetricsSchema metricsSchema, string m var dataPoint = influxServer.ReadPoint(); Assert.Equal(measurement, dataPoint.Measurement); - Assert.Equal(1, dataPoint.Fields.Count); + Assert.Single(dataPoint.Fields); AssertUtils.HasField(valueKey, -50L, dataPoint.Fields); AssertTags(dataPoint); @@ -291,7 +291,7 @@ public void ExportNonMonotonicDoubleSumMetric(MetricsSchema metricsSchema, strin var dataPoint = influxServer.ReadPoint(); Assert.Equal(measurement, dataPoint.Measurement); - Assert.Equal(1, dataPoint.Fields.Count); + Assert.Single(dataPoint.Fields); AssertUtils.HasField(valueKey, -50.11D, dataPoint.Fields); AssertTags(dataPoint); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index b1dcd3e782..e0d057cfe8 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -24,6 +24,7 @@ using SQS = Amazon.SQS.Model; namespace OpenTelemetry.Instrumentation.AWS.Tests.Implementation; + internal static class TestsHelper { internal static Action>? CreateAddAttributesAction(string serviceType, IRequestContext context) diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index b4da75a7d4..9d1a693f4b 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -29,6 +29,7 @@ using Amazon.Runtime.Internal.Transform; namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; + #if NETFRAMEWORK internal class MockHttpRequest : IHttpRequest { diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index 03d63c41f4..00b833994b 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -24,6 +24,7 @@ using Amazon.Runtime; namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; + #if NETFRAMEWORK internal class MockHttpRequestFactory : IHttpRequestFactory { diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs index af3c489051..c1330db29a 100644 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs @@ -105,7 +105,7 @@ public void UnknownMySqlTraceEventType(MySqlTraceEventType eventType) ConnStr, 10); - Assert.Equal(1, activityProcessor.Invocations.Count); + Assert.Single(activityProcessor.Invocations); } private static void VerifyActivityData( diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj index feec95205c..97f3e5715f 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0; + net7.0;net6.0 $(TargetFrameworks);net462 From 36a97120a9d9c976c72c11d5c1a9643e02ee7324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 3 Aug 2023 06:50:12 +0200 Subject: [PATCH 0771/1499] [Instrumentation.AWS] Update dependency to OpenTelemetry.Extensions.AWS (#1288) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 2 ++ .../Implementation/AWSTracingPipelineHandler.cs | 2 +- .../OpenTelemetry.Instrumentation.AWS.csproj | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 6ad749ae64..89b8e888ff 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -11,6 +11,8 @@ * Global propagator is now used to inject into sent SQS and SNS message attributes (in addition to X-Ray propagation). ([#1051](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1051)) +* Change dependency from `OpenTelemetry.Contrib.Extensions.AWSXRay` to `OpenTelemetry.Extensions.AWS` + ([#1288](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1288)) ## 1.0.2 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 2c11c425d9..51c970d0dc 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -22,7 +22,7 @@ using Amazon.Runtime.Internal; using Amazon.Util; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Extensions.AWS.Trace; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index b9f79ab96e..0e7ed6969d 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -13,7 +13,7 @@ - + From 2e15a8af63b3d1bb50a03a1dc5f4b40ba66e25a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 3 Aug 2023 08:38:31 +0200 Subject: [PATCH 0772/1499] [Instrumentation.AWSLambda] Update dependency to OpenTelemetry.Extensions.AWS (#1289) --- .../CHANGELOG.md | 2 ++ .../AWSLambdaResourceDetector.cs | 19 ++++++++++--------- .../Implementation/AWSLambdaUtils.cs | 2 +- ...Telemetry.Instrumentation.AWSLambda.csproj | 3 +-- .../TracerProviderBuilderExtensions.cs | 6 +----- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 7fec9a4d46..8226fee49d 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Change dependency from `OpenTelemetry.Contrib.Extensions.AWSXRay` to `OpenTelemetry.Extensions.AWS` + ([#1289](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1289)) * Add explicit dependency on Newtonsoft.Json, upgrading the minimum version. This resolves a warning that some dependency analyzers may produce where this diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs index 34a3cf144c..c6b384f694 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs @@ -15,25 +15,26 @@ // using System.Collections.Generic; +using OpenTelemetry.Resources; namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; -internal static class AWSLambdaResourceDetector +internal sealed class AWSLambdaResourceDetector : IResourceDetector { /// /// Detect the resource attributes for AWS Lambda. /// - /// List of resource attributes pairs. - internal static IEnumerable> Detect() + /// Detected resource. + public Resource Detect() { - var resourceAttributes = new List>() + var resourceAttributes = new List> { - new KeyValuePair(AWSLambdaSemanticConventions.AttributeCloudProvider, AWSLambdaUtils.GetCloudProvider()), - new KeyValuePair(AWSLambdaSemanticConventions.AttributeCloudRegion, AWSLambdaUtils.GetAWSRegion()), - new KeyValuePair(AWSLambdaSemanticConventions.AttributeFaasName, AWSLambdaUtils.GetFunctionName()), - new KeyValuePair(AWSLambdaSemanticConventions.AttributeFaasVersion, AWSLambdaUtils.GetFunctionVersion()), + new(AWSLambdaSemanticConventions.AttributeCloudProvider, AWSLambdaUtils.GetCloudProvider()), + new(AWSLambdaSemanticConventions.AttributeCloudRegion, AWSLambdaUtils.GetAWSRegion()), + new(AWSLambdaSemanticConventions.AttributeFaasName, AWSLambdaUtils.GetFunctionName()), + new(AWSLambdaSemanticConventions.AttributeFaasVersion, AWSLambdaUtils.GetFunctionVersion()), }; - return resourceAttributes; + return new Resource(resourceAttributes); } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 234b86fb62..d9bebaf5f2 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -23,7 +23,7 @@ using Amazon.Lambda.SNSEvents; using Amazon.Lambda.SQSEvents; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Contrib.Extensions.AWSXRay.Trace; +using OpenTelemetry.Extensions.AWS.Trace; namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 932a8fd69f..be934118fc 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -12,8 +12,7 @@ - - + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index e543c9dc94..d02312e536 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -17,7 +17,6 @@ using System; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Internal; -using OpenTelemetry.Resources; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWSLambda; @@ -54,10 +53,7 @@ public static TracerProviderBuilder AddAWSLambdaConfigurations( AWSMessagingUtils.SetParentFromMessageBatch = options.SetParentFromBatch; builder.AddSource(AWSLambdaWrapper.ActivitySourceName); - builder.SetResourceBuilder(ResourceBuilder - .CreateEmpty() - .AddTelemetrySdk() - .AddAttributes(AWSLambdaResourceDetector.Detect())); + builder.ConfigureResource(x => x.AddDetector(new AWSLambdaResourceDetector())); return builder; } From ef2d9a9ca5e586f093f71577ace6a9d6f488e0ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 3 Aug 2023 18:38:03 +0200 Subject: [PATCH 0773/1499] Bump coverlet.collector from 3.2.0 to 6.0.0 (#1291) --- build/Common.nonprod.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index f5d7e68499..5fcb3187f5 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -21,7 +21,7 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [0.13.6,0.14) - [3.2.0,4.0.0) + [6.0.0,7.0.0) [2.3.1,3.0) [5.0.0,7.0) [17.6.3,18.0) From 0307f6edfb1134cbd34be33c95c004c1206e7227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 3 Aug 2023 23:19:00 +0200 Subject: [PATCH 0774/1499] [Exporter.Stackdriver] Documentation - remove reference to metric exporter (#1286) --- src/OpenTelemetry.Exporter.Stackdriver/README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index a967edfe63..9f68e6ef9f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -47,15 +47,6 @@ using (tracer.StartActiveSpan("/getuser", out TelemetrySpan span)) } ``` -## Metrics - -```csharp -var metricExporter = new StackdriverExporter( - "YOUR-GOOGLE-PROJECT-ID", - Stats.ViewManager); -metricExporter.Start(); -``` - ## References * [stackdriver-trace-setup](https://cloud.google.com/trace/docs/setup/) From abe16691eabcf17ad03938052898896a59f9dd57 Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:51:48 +0200 Subject: [PATCH 0775/1499] Instrumentation.AWSLambda 1.2.0-beta.1 release (#1292) --- .../CHANGELOG.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 8226fee49d..123a910d83 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,8 +2,16 @@ ## Unreleased -* Change dependency from `OpenTelemetry.Contrib.Extensions.AWSXRay` to `OpenTelemetry.Extensions.AWS` - ([#1289](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1289)) +## 1.2.0-beta.1 + +Released 2023-Aug-07 + +* BREAKING: `AddAWSLambdaConfigurations` no longer removes all existing + resource attributes +* BREAKING: Change dependency from `OpenTelemetry.Contrib.Extensions.AWSXRay` + to `OpenTelemetry.Extensions.AWS` + ([#1289](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1289)). + This now requires at least OpenTelemetry 1.5.1. * Add explicit dependency on Newtonsoft.Json, upgrading the minimum version. This resolves a warning that some dependency analyzers may produce where this From f56ae3ba67c36ed19d4a846f2544c3293be7aded Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Mon, 7 Aug 2023 11:53:06 +0200 Subject: [PATCH 0776/1499] Instrumentation.AWS 1.1.0-beta.1 release (#1294) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 89b8e888ff..e6f0c540dc 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.1 + +Released 2023-Aug-07 + * BREAKING (renaming): renamed `OpenTelemetry.Contrib.Instrumentation.AWS` to `OpenTelemetry.Instrumentation.AWS` ([#1275](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1275)) * Raised the minimum .NET Framework version to `net462` From 11a786c1a375c037675db292bf78764e0e6704fb Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 7 Aug 2023 15:52:09 -0700 Subject: [PATCH 0777/1499] [OneCollectorExporter] Release 1.5.1 stable (#1299) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 45 +++++++++++++++++++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 45 ------------------- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 45 +++++++++++++++++++ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 45 ------------------- .../.publicApi/net7.0/PublicAPI.Shipped.txt | 45 +++++++++++++++++++ .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 45 ------------------- .../netstandard2.0/PublicAPI.Shipped.txt | 45 +++++++++++++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 45 ------------------- .../netstandard2.1/PublicAPI.Shipped.txt | 45 +++++++++++++++++++ .../netstandard2.1/PublicAPI.Unshipped.txt | 45 ------------------- .../CHANGELOG.md | 4 ++ .../README.md | 5 +-- 12 files changed, 230 insertions(+), 229 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt index 7dc5c58110..f0571ebcdb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt @@ -1 +1,46 @@ #nullable enable +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index 427f6f8f5f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,45 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt index 7dc5c58110..f0571ebcdb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -1 +1,46 @@ #nullable enable +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index 427f6f8f5f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,45 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt index 7dc5c58110..f0571ebcdb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt @@ -1 +1,46 @@ #nullable enable +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index 427f6f8f5f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -1,45 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 7dc5c58110..f0571ebcdb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1 +1,46 @@ #nullable enable +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 427f6f8f5f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,45 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt index 7dc5c58110..f0571ebcdb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt @@ -1 +1,46 @@ #nullable enable +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions +override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 427f6f8f5f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,45 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index fc6890ea8c..16336d48da 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.1 + +Released 2023-Aug-07 + ## 1.5.1-rc.1 Released 2023-Jun-29 diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index fa9612ac9c..9d9622d130 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -3,9 +3,6 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) -> **Warning** -> This is an early preview version breaking changes should be expected. - The OneCollectorExporter is designed for Microsoft products to send data to public-facing end-points which route to Microsoft's internal data pipeline. It is not meant to be used outside of Microsoft products and is open sourced to @@ -14,7 +11,7 @@ demonstrate best practices and to be transparent about what is being collected. ## Installation ```shell -dotnet add package --prerelease OpenTelemetry.Exporter.OneCollector +dotnet add package OpenTelemetry.Exporter.OneCollector ``` ## Basic usage From b0e0828e015293326051eff7fbe1515155ba44c5 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 7 Aug 2023 18:26:24 -0700 Subject: [PATCH 0778/1499] Suppress http calls for outgoing metadata request (#1297) --- .../AzureVMResourceDetector.cs | 3 +++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs index 1a8fc97ce4..f68394622d 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs @@ -46,6 +46,9 @@ public Resource Detect() { try { + // Prevents the http operations from being instrumented. + using var scope = SuppressInstrumentationScope.Begin(); + var vmMetaDataResponse = AzureVmMetaDataRequestor.GetAzureVmMetaDataResponse(); if (vmMetaDataResponse == null) { diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 42290fcc37..e6d6b70e0e 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Suppress instrumentation for outgoing http call made to metadata service + during `Detect()`. + ([#1297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1297)) + ## 1.0.0-beta.2 Released 2023-Jul-26 From cff9c0e0b7bcb860015cbf6d889992a96467263f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 9 Aug 2023 15:42:19 -0700 Subject: [PATCH 0779/1499] Bump SDK version (#1301) --- .github/workflows/ci.yml | 6 ++---- .github/workflows/dotnet-core-cov.yml | 6 ++---- .github/workflows/dotnet-format.yml | 6 ++---- .github/workflows/package-Exporter.Geneva.yml | 5 ++--- .github/workflows/package-Exporter.InfluxDB.yml | 5 ++--- .github/workflows/package-Exporter.Instana.yml | 5 ++--- .github/workflows/package-Exporter.OneCollector.yml | 5 ++--- .github/workflows/package-Exporter.Stackdriver.yml | 5 ++--- .github/workflows/package-Extensions.AWS.yml | 5 ++--- .github/workflows/package-Extensions.Enrichment.yml | 5 ++--- .github/workflows/package-Extensions.yml | 5 ++--- .github/workflows/package-Instrumentation.AWS.yml | 5 ++--- .github/workflows/package-Instrumentation.AWSLambda.yml | 5 ++--- .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 5 ++--- .github/workflows/package-Instrumentation.AspNet.yml | 5 ++--- .github/workflows/package-Instrumentation.Cassandra.yml | 5 ++--- .../workflows/package-Instrumentation.Elasticsearch.yml | 5 ++--- .../package-Instrumentation.EntityFrameworkCore.yml | 5 ++--- .../workflows/package-Instrumentation.EventCounters.yml | 5 ++--- .github/workflows/package-Instrumentation.GrpcCore.yml | 5 ++--- .github/workflows/package-Instrumentation.Hangfire.yml | 5 ++--- .github/workflows/package-Instrumentation.MySqlData.yml | 5 ++--- .github/workflows/package-Instrumentation.Owin.yml | 5 ++--- .github/workflows/package-Instrumentation.Process.yml | 5 ++--- .github/workflows/package-Instrumentation.Quartz.yml | 5 ++--- .github/workflows/package-Instrumentation.Runtime.yml | 5 ++--- .../package-Instrumentation.StackExchangeRedis.yml | 7 +++---- .github/workflows/package-Instrumentation.Wcf.yml | 5 ++--- .../workflows/package-PersistentStorage.Abstractions.yml | 5 ++--- .github/workflows/package-PersistentStorage.FileSystem.yml | 5 ++--- .github/workflows/package-ResourceDetectors.AWS.yml | 5 ++--- .github/workflows/package-ResourceDetectors.Azure.yml | 5 ++--- .github/workflows/package-ResourceDetectors.Container.yml | 5 ++--- .github/workflows/package-Sampler.AWS.yml | 5 ++--- build/Common.props | 1 + global.json | 2 +- .../TestAWSClientInstrumentation.cs | 2 ++ .../RedisProfilerEntryToActivityConverterTests.cs | 2 ++ test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs | 5 ----- test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs | 2 +- 40 files changed, 76 insertions(+), 113 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 269d4dc8a1..d575ad7245 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,10 +26,8 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index be6b24e964..fe8c9e2e84 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -24,10 +24,8 @@ jobs: with: fetch-depth: 0 # fetching all - - name: Setup .NET 7.0 - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 45f9c26166..3f49401a03 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -20,10 +20,8 @@ jobs: - name: check out code uses: actions/checkout@v3 - - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install format tool run: dotnet tool install -g dotnet-format diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index 44111dca8b..77a5cca48d 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml index fcceeaa2cf..2d969e87b9 100644 --- a/.github/workflows/package-Exporter.InfluxDB.yml +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index 71168712b3..70e7f06838 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml index 910bdaa0a2..a6fc9ccc80 100644 --- a/.github/workflows/package-Exporter.OneCollector.yml +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index 399dc1f707..bf15aa38d1 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.AWS.yml b/.github/workflows/package-Extensions.AWS.yml index 0fc49d3e51..801f15dc66 100644 --- a/.github/workflows/package-Extensions.AWS.yml +++ b/.github/workflows/package-Extensions.AWS.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml index ebcd7b80a1..c504dc24e0 100644 --- a/.github/workflows/package-Extensions.Enrichment.yml +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index 3efc67ad40..c18c2cfe6b 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index c8bdd9068a..a212b3de13 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 8043daf093..b1d1f35124 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 888f0e3c9e..26027d7566 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index ffaac9cd77..b082a8707c 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml index bc43454401..d67c4d3506 100644 --- a/.github/workflows/package-Instrumentation.Cassandra.yml +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -26,9 +26,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 927fdf59ea..74f81be176 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index 154369efd3..e3d64c5641 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index b5baf9ff3b..cd3f25bd9a 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index 04e6174c5a..23b198fbe3 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index d27017c7bd..1b7d1ad31c 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml index 97252dc255..9431b441c7 100644 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ b/.github/workflows/package-Instrumentation.MySqlData.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3' - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index 0361835651..84b617d4c6 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index ffc2e8d456..c9a71950d5 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 36c7ec098e..24b6d29c84 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index b717dd6f0e..21b20ded16 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index f2a8b8a278..aa2efffe4e 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.Instrumentation.StackExchangeRedis +Profilername: Pack OpenTelemetry.Instrumentation.StackExchangeRedis on: workflow_dispatch: @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 35bed0e435..823368e89e 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-PersistentStorage.Abstractions.yml b/.github/workflows/package-PersistentStorage.Abstractions.yml index 327c47d364..b757cb4416 100644 --- a/.github/workflows/package-PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-PersistentStorage.Abstractions.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-PersistentStorage.FileSystem.yml b/.github/workflows/package-PersistentStorage.FileSystem.yml index 0a6dd92858..09bee39744 100644 --- a/.github/workflows/package-PersistentStorage.FileSystem.yml +++ b/.github/workflows/package-PersistentStorage.FileSystem.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml index e9c4c8e286..6c68853329 100644 --- a/.github/workflows/package-ResourceDetectors.AWS.yml +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml index fc467ad5ce..87607aaaf1 100644 --- a/.github/workflows/package-ResourceDetectors.Azure.yml +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-ResourceDetectors.Container.yml b/.github/workflows/package-ResourceDetectors.Container.yml index 2065f874c1..1bf1f5765b 100644 --- a/.github/workflows/package-ResourceDetectors.Container.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml index 04619fbb07..6f82f2c6cd 100644 --- a/.github/workflows/package-Sampler.AWS.yml +++ b/.github/workflows/package-Sampler.AWS.yml @@ -28,9 +28,8 @@ jobs: with: fetch-depth: 0 # fetching all - - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/build/Common.props b/build/Common.props index 33f16d0985..641130c4cb 100644 --- a/build/Common.props +++ b/build/Common.props @@ -9,6 +9,7 @@ net462 net6.0 netstandard2.0 + true latest-All diff --git a/global.json b/global.json index 0f417661e6..aeb8ae7b1e 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestFeature", - "version": "7.0.101" + "version": "7.0.400" } } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 2bca456c94..96dddf36c8 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -17,7 +17,9 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +#if !NETFRAMEWORK using System.Threading.Tasks; +#endif using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index f92bf20aaa..dcec655941 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -17,7 +17,9 @@ using System; using System.Diagnostics; using System.Net; +#if !NETFRAMEWORK using System.Net.Sockets; +#endif using Moq; using OpenTelemetry.Tests; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index 2de7500de5..a5444b3b9a 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -15,11 +15,6 @@ // using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace OpenTelemetry.Sampler.AWS.Tests; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs index 4ac5fb4aa9..446cb4af6e 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Sampler.AWS.Tests; /// /// This class is a .Net port of the original Java implementation. /// This class was taken from Jaeger java client. -/// https://github.com/jaegertracing/jaeger-client-java/blob/master/jaeger-core/src/test/java/io/jaegertracing/internal/utils/RateLimiterTest.java +/// https://github.com/jaegertracing/jaeger-client-java/blob/master/jaeger-core/src/test/java/io/jaegertracing/internal/utils/RateLimiterTest.java. /// public class TestRateLimiter { From 888fa691d16cddc9477ba5b2be30d65380a84012 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 9 Aug 2023 19:17:54 -0700 Subject: [PATCH 0780/1499] Fix StackExchangeRedis workflow (#1303) --- .../workflows/package-Instrumentation.StackExchangeRedis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index aa2efffe4e..6a66f78e01 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -1,4 +1,4 @@ -Profilername: Pack OpenTelemetry.Instrumentation.StackExchangeRedis +name: Pack OpenTelemetry.Instrumentation.StackExchangeRedis on: workflow_dispatch: From c49d0e8aab877438ce0fda3ab5d015dcb6ae963a Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 9 Aug 2023 19:56:42 -0700 Subject: [PATCH 0781/1499] [AOT] Added AotCompatibility testApp and added CI to test AOT compatibility. (#1296) --- .github/workflows/ci-aot.yml | 30 ++++++++++++++ build/test-aot-compatibility.ps1 | 40 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 9 +++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 18 +++++++++ .../Program.cs | 19 +++++++++ 5 files changed, 116 insertions(+) create mode 100644 .github/workflows/ci-aot.yml create mode 100644 build/test-aot-compatibility.ps1 create mode 100644 test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj create mode 100644 test/OpenTelemetry.AotCompatibility.TestApp/Program.cs diff --git a/.github/workflows/ci-aot.yml b/.github/workflows/ci-aot.yml new file mode 100644 index 0000000000..f1a2aabdcc --- /dev/null +++ b/.github/workflows/ci-aot.yml @@ -0,0 +1,30 @@ +name: Publish AOTCompatibility testApp + +on: + push: + branches: [ 'main*' ] + paths: + - 'src/OpenTelemetry.Instrumentation.Runtime/**' + - '!src/OpenTelemetry.Instrumentation.Runtime/README.md' + pull_request: + branches: [ 'main*' ] + paths: + - 'src/OpenTelemetry.Instrumentation.Runtime/**' + - '!src/OpenTelemetry.Instrumentation.Runtime/README.md' + +jobs: + aot-test: + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + os: [ ubuntu-latest ] + version: [ net7.0 ] + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + + - name: publish AOT testApp, assert static analysis warning count, and run the app + shell: pwsh + run: .\build\test-aot-compatibility.ps1 ${{ matrix.version }} + diff --git a/build/test-aot-compatibility.ps1 b/build/test-aot-compatibility.ps1 new file mode 100644 index 0000000000..13539f9965 --- /dev/null +++ b/build/test-aot-compatibility.ps1 @@ -0,0 +1,40 @@ +param([string]$targetNetFramework) + +$rootDirectory = Split-Path $PSScriptRoot -Parent +$publishOutput = dotnet publish $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj -nodeReuse:false /p:UseSharedCompilation=false + +$actualWarningCount = 0 + +foreach ($line in $($publishOutput -split "`r`n")) +{ + if ($line -like "*analysis warning IL*") + { + Write-Host $line + $actualWarningCount += 1 + } +} + +Write-Host "Actual warning count is:", $actualWarningCount +$expectedWarningCount = 0 + +pushd $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/bin/Debug/$targetNetFramework/linux-x64 + +Write-Host "Executing test App..." +./OpenTelemetry.AotCompatibility.TestApp +Write-Host "Finished executing test App" + +if ($LastExitCode -ne 0) +{ + Write-Host "There was an error while executing AotCompatibility Test App. LastExitCode is:", $LastExitCode +} + +popd + +$testPassed = 0 +if ($actualWarningCount -ne $expectedWarningCount) +{ + $testPassed = 1 + Write-Host "Actual warning count:", actualWarningCount, "is not as expected. Expected warning count is:", $expectedWarningCount +} + +Exit $testPassed diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index bbaebdd629..b5b014d575 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -27,6 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml .github\workflows\ci.yml = .github\workflows\ci.yml + .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml @@ -79,6 +80,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset build\sanitycheck.py = build\sanitycheck.py build\stylecop.json = build\stylecop.json + build\test-aot-compatibility = build\test-aot-compatibility.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0112BD4F-B7A6-4E43-AB23-B6E961E27A49}" @@ -291,6 +293,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InfluxDB", "InfluxDB", "{2D EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.InfluxDB", "examples\InfluxDB\Examples.InfluxDB\Examples.InfluxDB.csproj", "{B4951583-D432-4E87-85CF-498FDD6A35E6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.AotCompatibility.TestApp", "test\OpenTelemetry.AotCompatibility.TestApp\OpenTelemetry.AotCompatibility.TestApp.csproj", "{31937862-0C88-41C0-AFD6-F97A7BF803A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -609,6 +613,10 @@ Global {B4951583-D432-4E87-85CF-498FDD6A35E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4951583-D432-4E87-85CF-498FDD6A35E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4951583-D432-4E87-85CF-498FDD6A35E6}.Release|Any CPU.Build.0 = Release|Any CPU + {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -703,6 +711,7 @@ Global {4847A991-D0C3-4421-B0D3-EA189959E639} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2D354354-BAFB-490B-A26F-6A16A52A1A45} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} + {31937862-0C88-41C0-AFD6-F97A7BF803A9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj new file mode 100644 index 0000000000..5371c43f24 --- /dev/null +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -0,0 +1,18 @@ + + + + Exe + net7.0 + true + false + true + + + + + + + + + + diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs b/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs new file mode 100644 index 0000000000..f41534aada --- /dev/null +++ b/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs @@ -0,0 +1,19 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; + +Console.WriteLine("Hello, World!"); From 01378f48b400c0e224f48b9c5c307c41cd5fa218 Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Thu, 10 Aug 2023 09:28:52 +0200 Subject: [PATCH 0782/1499] [Instrumentation.AWSLambda] Enable nullable (#1295) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 13 ++++---- .../AWSLambdaWrapper.cs | 32 +++++++++++-------- .../CHANGELOG.md | 8 +++++ .../Implementation/AWSLambdaHttpUtils.cs | 25 +++++++++------ .../Implementation/AWSLambdaUtils.cs | 19 ++++------- .../Implementation/AWSMessagingUtils.cs | 21 ++++++------ .../Implementation/CommonExtensions.cs | 4 +-- ...Telemetry.Instrumentation.AWSLambda.csproj | 1 + .../TracerProviderBuilderExtensions.cs | 2 +- .../AWSLambdaWrapperTests.cs | 20 ++++++------ .../Implementation/AWSLambdaHttpUtilsTests.cs | 17 +++++++--- .../Implementation/AWSMessagingUtilsTests.cs | 16 +++++----- ...try.Instrumentation.AWSLambda.Tests.csproj | 1 + .../SampleLambdaContext.cs | 10 +++--- 14 files changed, 108 insertions(+), 81 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index d5ed4319ec..74efa0b2d7 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,3 +1,4 @@ +#nullable enable OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.AWSLambdaInstrumentationOptions() -> void OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.DisableAwsXRayContextExtraction.get -> bool @@ -6,9 +7,9 @@ OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.SetParen OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaInstrumentationOptions.SetParentFromBatch.set -> void OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions -static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> TResult -static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Action lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void -static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func> lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task -static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider tracerProvider, System.Func lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task -static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider? tracerProvider, System.Func! lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext! context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> TResult +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.Trace(OpenTelemetry.Trace.TracerProvider? tracerProvider, System.Action! lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext! context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> void +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider? tracerProvider, System.Func!>! lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext! context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task! +static OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper.TraceAsync(OpenTelemetry.Trace.TracerProvider? tracerProvider, System.Func! lambdaHandler, TInput input, Amazon.Lambda.Core.ILambdaContext! context, System.Diagnostics.ActivityContext parentContext = default(System.Diagnostics.ActivityContext)) -> System.Threading.Tasks.Task! +static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Instrumentation.AWSLambda.TracerProviderBuilderExtensions.AddAWSLambdaConfigurations(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 937ad3f9aa..0390cc2c4f 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -65,13 +65,14 @@ public static class AWSLambdaWrapper /// /// Instance of output result. public static TResult Trace( - TracerProvider tracerProvider, + TracerProvider? tracerProvider, Func lambdaHandler, TInput input, ILambdaContext context, ActivityContext parentContext = default) { Guard.ThrowIfNull(lambdaHandler); + return TraceInternal(tracerProvider, lambdaHandler, input, context, parentContext); } @@ -90,7 +91,7 @@ public static TResult Trace( /// unless X-Ray propagation is disabled in the configuration for this wrapper. /// public static void Trace( - TracerProvider tracerProvider, + TracerProvider? tracerProvider, Action lambdaHandler, TInput input, ILambdaContext context, @@ -98,7 +99,7 @@ public static void Trace( { Guard.ThrowIfNull(lambdaHandler); - object Handler(TInput input, ILambdaContext context) + object? Handler(TInput input, ILambdaContext context) { lambdaHandler(input, context); return null; @@ -123,7 +124,7 @@ object Handler(TInput input, ILambdaContext context) /// /// Task. public static Task TraceAsync( - TracerProvider tracerProvider, + TracerProvider? tracerProvider, Func lambdaHandler, TInput input, ILambdaContext context, @@ -131,7 +132,7 @@ public static Task TraceAsync( { Guard.ThrowIfNull(lambdaHandler); - async Task Handler(TInput input, ILambdaContext context) + async Task Handler(TInput input, ILambdaContext context) { await lambdaHandler(input, context).ConfigureAwait(false); return null; @@ -157,21 +158,22 @@ async Task Handler(TInput input, ILambdaContext context) /// /// Task of result. public static Task TraceAsync( - TracerProvider tracerProvider, + TracerProvider? tracerProvider, Func> lambdaHandler, TInput input, ILambdaContext context, ActivityContext parentContext = default) { Guard.ThrowIfNull(lambdaHandler); + return TraceInternalAsync(tracerProvider, lambdaHandler, input, context, parentContext); } #pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters - internal static Activity OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) + internal static Activity? OnFunctionStart(TInput input, ILambdaContext context, ActivityContext parentContext = default) { - IEnumerable links = null; + IEnumerable? links = null; if (parentContext == default) { (parentContext, links) = AWSLambdaUtils.ExtractParentContext(input); @@ -186,12 +188,12 @@ internal static Activity OnFunctionStart(TInput input, ILambdaContext co // We assume that functionTags and httpTags have no intersection. var activityName = AWSLambdaUtils.GetFunctionName(context) ?? "AWS Lambda Invoke"; - var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, functionTags.Concat(httpTags), links); + var activity = AWSLambdaActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext, functionTags.Concat(httpTags)!, links); return activity; } - private static void OnFunctionStop(Activity activity, TracerProvider tracerProvider) + private static void OnFunctionStop(Activity? activity, TracerProvider? tracerProvider) { activity?.Stop(); @@ -199,7 +201,7 @@ private static void OnFunctionStop(Activity activity, TracerProvider tracerProvi tracerProvider?.ForceFlush(); } - private static void OnException(Activity activity, Exception exception) + private static void OnException(Activity? activity, Exception exception) { if (activity != null) { @@ -212,12 +214,14 @@ private static void OnException(Activity activity, Exception exception) } private static TResult TraceInternal( - TracerProvider tracerProvider, + TracerProvider? tracerProvider, Func handler, TInput input, ILambdaContext context, ActivityContext parentContext = default) { + Guard.ThrowIfNull(context); + var activity = OnFunctionStart(input, context, parentContext); try { @@ -238,12 +242,14 @@ private static TResult TraceInternal( } private static async Task TraceInternalAsync( - TracerProvider tracerProvider, + TracerProvider? tracerProvider, Func> handlerAsync, TInput input, ILambdaContext context, ActivityContext parentContext = default) { + Guard.ThrowIfNull(context); + var activity = OnFunctionStart(input, context, parentContext); try { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 123a910d83..527ae83f3c 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* BREAKING: `ILambdaContext context` argument of all tracing methods of + `OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper` was annotated as non-nullable. +* Enabled null state analysis for `OpenTelemetry.Instrumentation.AWSLambda`. + The interface will now contain attributes for null-state static analysis. + If null state analysis is enabled in your depending project, you may encounter + new warnings. + ([#1295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1295)) + ## 1.2.0-beta.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index 2e2d7747e4..dc1d068658 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -34,10 +34,10 @@ internal static IEnumerable> GetHttpTags(TI { var tags = new List>(); - string httpScheme = null; - string httpTarget = null; - string httpMethod = null; - string hostName = null; + string? httpScheme = null; + string? httpTarget = null; + string? httpMethod = null; + string? hostName = null; int? hostPort = null; switch (input) @@ -57,6 +57,8 @@ internal static IEnumerable> GetHttpTags(TI var hostHeaderV2 = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderHost)?.LastOrDefault(); (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeaderV2); break; + default: + return tags; } tags.AddTagIfNotNull(SemanticConventions.AttributeHttpScheme, httpScheme); @@ -68,8 +70,13 @@ internal static IEnumerable> GetHttpTags(TI return tags; } - internal static void SetHttpTagsFromResult(Activity activity, object result) + internal static void SetHttpTagsFromResult(Activity? activity, object? result) { + if (activity == null || result == null) + { + return; + } + switch (result) { case APIGatewayProxyResponse response: @@ -81,7 +88,7 @@ internal static void SetHttpTagsFromResult(Activity activity, object result) } } - internal static string GetQueryString(APIGatewayProxyRequest request) + internal static string? GetQueryString(APIGatewayProxyRequest request) { if (request.MultiValueQueryStringParameters == null) { @@ -107,10 +114,10 @@ internal static string GetQueryString(APIGatewayProxyRequest request) return queryString.ToString(); } - internal static string GetQueryString(APIGatewayHttpApiV2ProxyRequest request) => + internal static string? GetQueryString(APIGatewayHttpApiV2ProxyRequest request) => string.IsNullOrEmpty(request.RawQueryString) ? string.Empty : "?" + request.RawQueryString; - internal static (string Host, int? Port) GetHostAndPort(string httpScheme, string hostHeader) + internal static (string? Host, int? Port) GetHostAndPort(string? httpScheme, string? hostHeader) { if (hostHeader == null) { @@ -131,6 +138,6 @@ internal static (string Host, int? Port) GetHostAndPort(string httpScheme, strin } } - private static int? GetDefaultPort(string httpScheme) => + private static int? GetDefaultPort(string? httpScheme) => httpScheme == "https" ? 443 : httpScheme == "http" ? 80 : null; } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index d9bebaf5f2..4cc53fee43 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -65,10 +65,10 @@ internal static ActivityContext GetXRayParentContext() return activityContext; } - internal static (ActivityContext ParentContext, IEnumerable Links) ExtractParentContext(TInput input) + internal static (ActivityContext ParentContext, IEnumerable? Links) ExtractParentContext(TInput input) { PropagationContext parentContext = default; - IEnumerable links = null; + IEnumerable? links = null; switch (input) { case APIGatewayProxyRequest apiGatewayProxyRequest: @@ -104,7 +104,7 @@ internal static string GetAWSRegion() return Environment.GetEnvironmentVariable(AWSRegion); } - internal static string GetFunctionName(ILambdaContext context = null) + internal static string GetFunctionName(ILambdaContext? context = null) { return context?.FunctionName ?? Environment.GetEnvironmentVariable(FunctionName); } @@ -127,11 +127,6 @@ internal static IEnumerable> GetFunctionTags> GetFunctionTags GetHeaderValues(APIGatewayProxyRequest request, string name) + internal static IEnumerable? GetHeaderValues(APIGatewayProxyRequest request, string name) { var multiValueHeader = request.MultiValueHeaders?.GetValueByKeyIgnoringCase(name); if (multiValueHeader != null) @@ -165,7 +160,7 @@ internal static IEnumerable GetHeaderValues(APIGatewayProxyRequest reque return headerValue != null ? new[] { headerValue } : null; } - internal static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) + internal static IEnumerable? GetHeaderValues(APIGatewayHttpApiV2ProxyRequest request, string name) { var headerValue = GetHeaderValue(request, name); @@ -173,10 +168,10 @@ internal static IEnumerable GetHeaderValues(APIGatewayHttpApiV2ProxyRequ return headerValue?.Split(','); } - private static string GetHeaderValue(APIGatewayHttpApiV2ProxyRequest request, string name) => + private static string? GetHeaderValue(APIGatewayHttpApiV2ProxyRequest request, string name) => request.Headers?.GetValueByKeyIgnoringCase(name); - private static string GetAccountId(string functionArn) + private static string? GetAccountId(string functionArn) { // The fifth item of function arn: https://github.com/open-telemetry/opentelemetry-specification/blob/86aeab1e0a7e6c67be09c7f15ff25063ee6d2b5c/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#all-triggers // Function arn format - arn:aws:lambda:::function: diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs index 05f28caacf..3353391c74 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -38,7 +38,7 @@ internal class AWSMessagingUtils /// internal static bool SetParentFromMessageBatch { get; set; } - internal static (PropagationContext ParentContext, IEnumerable Links) ExtractParentContext(SQSEvent sqsEvent) + internal static (PropagationContext ParentContext, IEnumerable? Links) ExtractParentContext(SQSEvent sqsEvent) { if (sqsEvent?.Records == null) { @@ -74,11 +74,8 @@ internal static PropagationContext ExtractParentContext(SQSEvent.SQSMessage sqsM { // SQS subscribed to SNS topic with raw delivery disabled case, i.e. SNS record serialized into SQS body. // https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html - SNSEvent.SNSMessage snsMessage = GetSnsMessage(sqsMessage); - if (snsMessage != null) - { - parentContext = ExtractParentContext(snsMessage); - } + SNSEvent.SNSMessage? snsMessage = GetSnsMessage(sqsMessage); + parentContext = ExtractParentContext(snsMessage); } return parentContext; @@ -92,21 +89,21 @@ internal static PropagationContext ExtractParentContext(SNSEvent snsEvent) return ExtractParentContext(record); } - internal static PropagationContext ExtractParentContext(SNSEvent.SNSRecord record) + internal static PropagationContext ExtractParentContext(SNSEvent.SNSRecord? record) { return (record?.Sns?.MessageAttributes != null) ? Propagators.DefaultTextMapPropagator.Extract(default, record.Sns.MessageAttributes, SnsMessageAttributeGetter) : default; } - internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage message) + internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage? message) { return (message?.MessageAttributes != null) ? Propagators.DefaultTextMapPropagator.Extract(default, message.MessageAttributes, SnsMessageAttributeGetter) : default; } - private static IEnumerable SqsMessageAttributeGetter(IDictionary attributes, string attributeName) + private static IEnumerable? SqsMessageAttributeGetter(IDictionary attributes, string attributeName) { if (!attributes.TryGetValue(attributeName, out var attribute)) { @@ -118,7 +115,7 @@ private static IEnumerable SqsMessageAttributeGetter(IDictionary SnsMessageAttributeGetter(IDictionary attributes, string attributeName) + private static IEnumerable? SnsMessageAttributeGetter(IDictionary attributes, string attributeName) { if (!attributes.TryGetValue(attributeName, out var attribute)) { @@ -137,9 +134,9 @@ private static IEnumerable SnsMessageAttributeGetter(IDictionary> tags, string tagName, object tagValue) + internal static void AddTagIfNotNull(this List> tags, string tagName, object? tagValue) { if (tagValue != null) { @@ -29,7 +29,7 @@ internal static void AddTagIfNotNull(this List> tag } } - internal static T GetValueByKeyIgnoringCase(this IDictionary dict, string key) + internal static T? GetValueByKeyIgnoringCase(this IDictionary dict, string key) { // TODO: there may be opportunities for performance improvements of this method. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index be934118fc..179471dc3f 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -5,6 +5,7 @@ AWS Lambda tracing wrapper for OpenTelemetry .NET $(PackageTags);AWS Lambda Instrumentation.AWSLambda- + enable diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index d02312e536..42e5d733bf 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -42,7 +42,7 @@ public static TracerProviderBuilder AddAWSLambdaConfigurations(this TracerProvid /// The instance of to chain the calls. public static TracerProviderBuilder AddAWSLambdaConfigurations( this TracerProviderBuilder builder, - Action configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index ac42826f3c..dbb34edc8c 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -58,7 +58,7 @@ public void TraceSyncWithInputAndReturn(bool setCustomParent) using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .AddProcessor(processor.Object) - .Build()) + .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); @@ -84,7 +84,7 @@ public void TraceSyncWithInputAndNoReturn(bool setCustomParent) using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .AddProcessor(processor.Object) - .Build()) + .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); @@ -110,7 +110,7 @@ public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .AddProcessor(processor.Object) - .Build()) + .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; var result = await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndReturn, "TestStream", this.sampleLambdaContext, parentContext); @@ -136,7 +136,7 @@ public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .AddProcessor(processor.Object) - .Build()) + .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; await AWSLambdaWrapper.TraceAsync(tracerProvider, this.sampleHandlers.SampleHandlerAsyncInputAndNoReturn, "TestStream", this.sampleLambdaContext, parentContext); @@ -162,7 +162,7 @@ public void TestLambdaHandlerException(bool setCustomParent) using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .AddProcessor(processor.Object) - .Build()) + .Build()!) { try { @@ -195,7 +195,7 @@ public void TestLambdaHandlerNotSampled() using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .AddProcessor(processor.Object) - .Build()) + .Build()!) { var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); var resource = tracerProvider.GetResource(); @@ -214,7 +214,7 @@ public void OnFunctionStart_NoParent_ActivityCreated() { Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", null); - Activity activity = null; + Activity? activity = null; using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() .Build()) @@ -229,7 +229,7 @@ public void OnFunctionStart_NoParent_ActivityCreated() public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_ActivityCreated() { Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", $"Root=1-5759e988-bd862e3fe1be46a994272793;Parent={XRayParentId};Sampled=0"); - Activity activity = null; + Activity? activity = null; using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) @@ -261,8 +261,10 @@ private void AssertSpanProperties(Activity activity, string parentId) Assert.Matches(@"^\d+(\.\d+){3}$", activity.Source.Version); } - private void AssertResourceAttributes(Resource resource) + private void AssertResourceAttributes(Resource? resource) { + Assert.NotNull(resource); + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); Assert.Equal("aws", resourceAttributes[AWSLambdaSemanticConventions.AttributeCloudProvider]); Assert.Equal("us-east-1", resourceAttributes[AWSLambdaSemanticConventions.AttributeCloudRegion]); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 3861ec8414..5b1ed55399 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -195,7 +195,12 @@ public void SetHttpTagsFromResult_APIGatewayProxyResponse_SetsCorrectTags() { { "http.status_code", 200 }, }; - AssertTags(expectedTags, activity.TagObjects); + + Assert.NotNull(activity); + + var actualTags = activity.TagObjects + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value!)); + AssertTags(expectedTags, actualTags); } [Fact] @@ -221,7 +226,11 @@ public void SetHttpTagsFromResult_APIGatewayHttpApiV2ProxyResponse_SetsCorrectTa { { "http.status_code", 200 }, }; - AssertTags(expectedTags, activity.TagObjects); + + var actualTags = activity?.TagObjects + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value ?? new object())); + + AssertTags(expectedTags, actualTags); } [Theory] @@ -280,14 +289,14 @@ public void GetQueryString_APIGatewayHttpApiV2ProxyRequest_CorrectQueryString(st Assert.Equal(expectedQueryString, queryString); } - private static void AssertTags(IReadOnlyDictionary expectedTags, IEnumerable> actualTags) + private static void AssertTags(IReadOnlyDictionary expectedTags, IEnumerable>? actualTags) where TActualValue : class { Assert.NotNull(actualTags); Assert.Equal(expectedTags.Count, actualTags.Count()); foreach (var tag in expectedTags) { - Assert.Contains(new KeyValuePair(tag.Key, tag.Value as TActualValue), actualTags); + Assert.Contains(new KeyValuePair(tag.Key, (TActualValue)tag.Value), actualTags); } } } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs index 770a4036e6..2123f9f72a 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -34,7 +34,7 @@ public class AWSMessagingUtilsTests : IDisposable private const string SpanId1 = "b9c7c989f97918e1"; private const string SpanId2 = "b9c7c989f97918e2"; - private readonly TracerProvider tracerProvider; + private readonly TracerProvider? tracerProvider; public AWSMessagingUtilsTests() { @@ -44,7 +44,7 @@ public AWSMessagingUtilsTests() public void Dispose() { - this.tracerProvider.Dispose(); + this.tracerProvider?.Dispose(); } [Fact] @@ -53,10 +53,10 @@ public void ExtractParentContext_SetParentFromMessageBatchIsDisabled_ParentIsNot AWSMessagingUtils.SetParentFromMessageBatch = false; var sqsEvent = CreateSqsEventWithMessages(new[] { SpanId1, SpanId2 }); - (PropagationContext parentContext, IEnumerable links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + (PropagationContext parentContext, IEnumerable? links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); Assert.Equal(default, parentContext); - Assert.Equal(2, links.Count()); + Assert.Equal(2, links!.Count()); } [Fact] @@ -65,11 +65,11 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF AWSMessagingUtils.SetParentFromMessageBatch = true; var sqsEvent = CreateSqsEventWithMessages(new[] { SpanId1, SpanId2 }); - (PropagationContext parentContext, IEnumerable links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + (PropagationContext parentContext, IEnumerable? links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); Assert.NotEqual(default, parentContext); Assert.Equal(SpanId2, parentContext.ActivityContext.SpanId.ToHexString()); - Assert.Equal(2, links.Count()); + Assert.Equal(2, links?.Count()); } [Fact] @@ -106,11 +106,11 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF }, }; - (PropagationContext parentContext, IEnumerable links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + (PropagationContext parentContext, IEnumerable? links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); Assert.NotEqual(default, parentContext); Assert.Equal(SpanId1, parentContext.ActivityContext.SpanId.ToHexString()); - Assert.Single(links); + Assert.Single(links!); } private static SQSEvent CreateSqsEventWithMessages(string[] spans) diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 95fbba74b5..f2d50fcda4 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -5,6 +5,7 @@ net7.0;net6.0 true true + enable diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index 8b77918a75..2ad2ac4da4 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -23,21 +23,21 @@ public class SampleLambdaContext : ILambdaContext { public string AwsRequestId { get; } = "testrequestid"; - public IClientContext ClientContext { get; } + public IClientContext? ClientContext { get; } public string FunctionName { get; } = "testfunction"; public string FunctionVersion { get; } = "latest"; - public ICognitoIdentity Identity { get; } + public ICognitoIdentity? Identity { get; } public string InvokedFunctionArn { get; } = "arn:aws:lambda:us-east-1:111111111111:function:testfunction"; - public ILambdaLogger Logger { get; } + public ILambdaLogger? Logger { get; } - public string LogGroupName { get; } + public string? LogGroupName { get; } - public string LogStreamName { get; } + public string? LogStreamName { get; } public int MemoryLimitInMB { get; } From e4cb523a4a3592e1a1adf30f3596025bfd8978e3 Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Thu, 10 Aug 2023 22:39:59 -0600 Subject: [PATCH 0783/1499] Convert WCF client instrumentation to a BindingElement (#1247) --- .../CHANGELOG.md | 2 + .../AsyncResultWithTelemetryState.cs | 49 ++ .../ClientChannelInstrumentation.cs | 176 +++++++ .../Implementation/InstrumentedChannel.cs | 35 ++ .../InstrumentedChannelFactory.cs | 35 ++ .../InstrumentedCommunicationObject.cs | 100 ++++ .../InstrumentedDuplexSessionChannel.cs | 188 +++++++ ...InstrumentedDuplexSessionChannelFactory.cs | 44 ++ .../InstrumentedRequestChannel.cs | 114 +++++ .../InstrumentedRequestChannelFactory.cs | 41 ++ .../Implementation/RequestTelemetryState.cs | 27 + .../RequestTelemetryStateTracker.cs | 171 +++++++ .../Implementation/TelemetryBindingElement.cs | 71 +++ .../TelemetryContextMessageProperty.cs | 26 + .../README.md | 40 +- .../TelemetryClientMessageInspector.cs | 144 +----- .../TelemetryContractBehaviorAttribute.cs | 13 +- .../TelemetryEndpointBehavior.cs | 32 +- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 3 +- ...=> TelemetryBindingElementForHttpTests.cs} | 140 +++++- ...elemetryBindingElementForTcpTests.netfx.cs | 475 ++++++++++++++++++ ...DownstreamInstrumentationBindingElement.cs | 41 ++ .../Tools/DownstreamInstrumentationChannel.cs | 73 +++ ...DownstreamInstrumentationChannelFactory.cs | 36 ++ ...wnstreamInstrumentationEndpointBehavior.cs | 43 ++ .../DownstreamInstrumentationExtensions.cs | 25 + .../WCF/IServiceContract.cs | 9 + .../WCF/Service.netfx.cs | 18 + .../WCF/ServiceClient.cs | 9 + 29 files changed, 1988 insertions(+), 192 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs rename test/OpenTelemetry.Instrumentation.Wcf.Tests/{TelemetryClientMessageInspectorTests.cs => TelemetryBindingElementForHttpTests.cs} (67%) create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 296dc08e6c..04c6289406 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.5.1`. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Client instrumentation implementation moved to lower-level `BindingElement`. + ([#1247](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1247)) ## 1.0.0-rc.10 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs new file mode 100644 index 0000000000..f9239359b5 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs @@ -0,0 +1,49 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Threading; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal sealed class AsyncResultWithTelemetryState : IAsyncResult +{ + public AsyncResultWithTelemetryState(IAsyncResult inner, RequestTelemetryState telemetryState) + { + this.Inner = inner; + this.TelemetryState = telemetryState; + } + + public IAsyncResult Inner { get; } + + public RequestTelemetryState TelemetryState { get; } + + object IAsyncResult.AsyncState => this.Inner.AsyncState; + + WaitHandle IAsyncResult.AsyncWaitHandle => this.Inner.AsyncWaitHandle; + + bool IAsyncResult.CompletedSynchronously => this.Inner.CompletedSynchronously; + + bool IAsyncResult.IsCompleted => this.Inner.IsCompleted; + + public static AsyncCallback GetAsyncCallback(AsyncCallback innerCallback, RequestTelemetryState telemetryState) + { + return (IAsyncResult ar) => + { + innerCallback(new AsyncResultWithTelemetryState(ar, telemetryState)); + }; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs new file mode 100644 index 0000000000..8ad977925d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -0,0 +1,176 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.ServiceModel.Channels; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal static class ClientChannelInstrumentation +{ + public static RequestTelemetryState BeforeSendRequest(Message request, Uri remoteChannelAddress) + { + if (!ShouldInstrumentRequest(request)) + { + return new RequestTelemetryState { SuppressionScope = SuppressDownstreamInstrumentation() }; + } + + Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + WcfInstrumentationActivitySource.OutgoingRequestActivityName, + ActivityKind.Client); + IDisposable suppressionScope = SuppressDownstreamInstrumentation(); + + if (activity != null) + { + var action = string.Empty; + if (!string.IsNullOrEmpty(request.Headers.Action)) + { + action = request.Headers.Action; + activity.DisplayName = action; + } + + Propagators.DefaultTextMapPropagator.Inject( + new PropagationContext(activity.Context, Baggage.Current), + request, + WcfInstrumentationActivitySource.MessageHeaderValueSetter); + + if (activity.IsAllDataRequested) + { + activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); + + var actionMetadata = GetActionMetadata(request, action); + activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); + activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); + + if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) + { + activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); + } + + var remoteAddressUri = request.Headers.To ?? remoteChannelAddress; + if (remoteAddressUri != null) + { + activity.SetTag(WcfInstrumentationConstants.NetPeerNameTag, remoteAddressUri.Host); + activity.SetTag(WcfInstrumentationConstants.NetPeerPortTag, remoteAddressUri.Port); + activity.SetTag(WcfInstrumentationConstants.WcfChannelSchemeTag, remoteAddressUri.Scheme); + activity.SetTag(WcfInstrumentationConstants.WcfChannelPathTag, remoteAddressUri.LocalPath); + } + + if (request.Properties.Via != null) + { + activity.SetTag(WcfInstrumentationConstants.SoapViaTag, request.Properties.Via.ToString()); + } + + try + { + WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendRequest, request); + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + return new RequestTelemetryState + { + SuppressionScope = suppressionScope, + Activity = activity, + }; + } + + public static void AfterRequestCompleted(Message reply, RequestTelemetryState state) + { + Guard.ThrowIfNull(state); + + state.SuppressionScope?.Dispose(); + + if (state.Activity is Activity activity) + { + if (activity.IsAllDataRequested) + { + if (reply == null || reply.IsFault) + { + activity.SetStatus(Status.Error); + } + + if (reply != null) + { + activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); + try + { + WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveReply, reply); + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + activity.Stop(); + } + } + + private static IDisposable SuppressDownstreamInstrumentation() + { + return WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false + ? SuppressInstrumentationScope.Begin() + : null; + } + + private static ActionMetadata GetActionMetadata(Message request, string action) + { + ActionMetadata actionMetadata = null; + if (request.Properties.TryGetValue(TelemetryContextMessageProperty.Name, out object telemetryContextProperty)) + { + var actionMappings = (telemetryContextProperty as TelemetryContextMessageProperty)?.ActionMappings; + if (actionMappings != null && actionMappings.TryGetValue(action, out ActionMetadata metadata)) + { + actionMetadata = metadata; + } + } + + return actionMetadata != null ? actionMetadata : new ActionMetadata + { + ContractName = null, + OperationName = action, + }; + } + + private static bool ShouldInstrumentRequest(Message request) + { + try + { + if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.OutgoingRequestFilter?.Invoke(request) == false) + { + WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); + return false; + } + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.RequestFilterException(ex); + return false; + } + + return true; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs new file mode 100644 index 0000000000..46cd58e734 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class InstrumentedChannel : InstrumentedCommunicationObject, IChannel +{ + public InstrumentedChannel(IChannel inner) + : base(inner) + { + } + + protected new IChannel Inner { get => (IChannel)base.Inner; } + + T IChannel.GetProperty() + where T : class + { + return this.Inner.GetProperty(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs new file mode 100644 index 0000000000..c5ae5a68f5 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs @@ -0,0 +1,35 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class InstrumentedChannelFactory : InstrumentedCommunicationObject, IChannelFactory +{ + public InstrumentedChannelFactory(IChannelFactory inner) + : base(inner) + { + } + + protected new IChannelFactory Inner { get => (IChannelFactory)base.Inner; } + + T IChannelFactory.GetProperty() + where T : class + { + return this.Inner.GetProperty(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs new file mode 100644 index 0000000000..d3d3ba9d28 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs @@ -0,0 +1,100 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class InstrumentedCommunicationObject : ICommunicationObject +{ + public InstrumentedCommunicationObject(ICommunicationObject inner) + { + this.Inner = inner; + } + + event EventHandler ICommunicationObject.Closed { add => this.Inner.Closed += value; remove => this.Inner.Closed -= value; } + + event EventHandler ICommunicationObject.Closing { add => this.Inner.Closing += value; remove => this.Inner.Closing -= value; } + + event EventHandler ICommunicationObject.Faulted { add => this.Inner.Faulted += value; remove => this.Inner.Faulted -= value; } + + event EventHandler ICommunicationObject.Opened { add => this.Inner.Opened += value; remove => this.Inner.Opened -= value; } + + event EventHandler ICommunicationObject.Opening { add => this.Inner.Opening += value; remove => this.Inner.Opening -= value; } + + CommunicationState ICommunicationObject.State + { + get { return this.Inner.State; } + } + + protected ICommunicationObject Inner { get; } + + void ICommunicationObject.Abort() + { + this.Inner.Abort(); + } + + IAsyncResult ICommunicationObject.BeginClose(TimeSpan timeout, AsyncCallback callback, object state) + { + return this.Inner.BeginClose(timeout, callback, state); + } + + IAsyncResult ICommunicationObject.BeginClose(AsyncCallback callback, object state) + { + return this.Inner.BeginClose(callback, state); + } + + IAsyncResult ICommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, object state) + { + return this.Inner.BeginOpen(timeout, callback, state); + } + + IAsyncResult ICommunicationObject.BeginOpen(AsyncCallback callback, object state) + { + return this.Inner.BeginOpen(callback, state); + } + + void ICommunicationObject.Close(TimeSpan timeout) + { + this.Inner.Close(timeout); + } + + void ICommunicationObject.Close() + { + this.Inner.Close(); + } + + void ICommunicationObject.EndClose(IAsyncResult result) + { + this.Inner.EndClose(result); + } + + void ICommunicationObject.EndOpen(IAsyncResult result) + { + this.Inner.EndOpen(result); + } + + void ICommunicationObject.Open(TimeSpan timeout) + { + this.Inner.Open(timeout); + } + + void ICommunicationObject.Open() + { + this.Inner.Open(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs new file mode 100644 index 0000000000..ed9f1af144 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs @@ -0,0 +1,188 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.Threading; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal sealed class InstrumentedDuplexSessionChannel : InstrumentedChannel, IDuplexSessionChannel +{ + private readonly TimeSpan telemetryTimeout; + + public InstrumentedDuplexSessionChannel(IDuplexSessionChannel inner, TimeSpan telemetryTimeout) + : base(inner) + { + this.telemetryTimeout = telemetryTimeout; + } + + public EndpointAddress LocalAddress => this.Inner.LocalAddress; + + public EndpointAddress RemoteAddress => this.Inner.RemoteAddress; + + public Uri Via => this.Inner.Via; + + public IDuplexSession Session => this.Inner.Session; + + private new IDuplexSessionChannel Inner { get => (IDuplexSessionChannel)base.Inner; } + + public void Send(Message message) + { + this.SendInternal(message, this.telemetryTimeout, _ => this.Inner.Send(message)); + } + + public void Send(Message message, TimeSpan timeout) + { + this.SendInternal(message, timeout, _ => this.Inner.Send(message, timeout)); + } + + public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state) + { + return this.SendInternal(message, this.telemetryTimeout, (cb, s) => this.Inner.BeginSend(message, cb, s), callback, state); + } + + public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state) + { + return this.SendInternal(message, timeout, (cb, s) => this.Inner.BeginSend(message, timeout, cb, s), callback, state); + } + + public void EndSend(IAsyncResult result) + { + var asyncResult = (AsyncResultWithTelemetryState)result; + try + { + this.Inner.EndSend(asyncResult.Inner); + } + catch (Exception) + { + ClientChannelInstrumentation.AfterRequestCompleted(null, asyncResult.TelemetryState); + throw; + } + } + + public Message Receive() + { + var message = this.Inner.Receive(); + HandleReceivedMessage(message); + return message; + } + + public Message Receive(TimeSpan timeout) + { + var message = this.Inner.Receive(timeout); + HandleReceivedMessage(message); + return message; + } + + public IAsyncResult BeginReceive(AsyncCallback callback, object state) + { + return this.Inner.BeginReceive(callback, state); + } + + public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state) + { + return this.Inner.BeginReceive(timeout, callback, state); + } + + public Message EndReceive(IAsyncResult result) + { + var message = this.Inner.EndReceive(result); + HandleReceivedMessage(message); + return message; + } + + public bool TryReceive(TimeSpan timeout, out Message message) + { + var returnValue = this.Inner.TryReceive(timeout, out message); + HandleReceivedMessage(message); + return returnValue; + } + + public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state) + { + return this.Inner.BeginTryReceive(timeout, callback, state); + } + + public bool EndTryReceive(IAsyncResult result, out Message message) + { + var returnValue = this.Inner.EndTryReceive(result, out message); + HandleReceivedMessage(message); + return returnValue; + } + + public bool WaitForMessage(TimeSpan timeout) + { + return this.Inner.WaitForMessage(timeout); + } + + public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state) + { + return this.Inner.BeginWaitForMessage(timeout, callback, state); + } + + public bool EndWaitForMessage(IAsyncResult result) + { + return this.Inner.EndWaitForMessage(result); + } + + private static void HandleReceivedMessage(Message message) + { + var telemetryState = RequestTelemetryStateTracker.PopTelemetryState(message); + if (telemetryState != null) + { + ClientChannelInstrumentation.AfterRequestCompleted(message, telemetryState); + } + } + + private static void OnTelemetryStateTimedOut(RequestTelemetryState telemetryState) + { + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + } + + private IAsyncResult SendInternal(Message message, TimeSpan timeout, Func executeSend, AsyncCallback callback, object state) + { + IAsyncResult result = null; + this.SendInternal(message, timeout, telemetryState => + { + var asyncCallback = AsyncResultWithTelemetryState.GetAsyncCallback(callback, telemetryState); + result = new AsyncResultWithTelemetryState(executeSend(asyncCallback, state), telemetryState); + }); + return result; + } + + private void SendInternal(Message message, TimeSpan timeout, Action executeSend) + { + RequestTelemetryState telemetryState = null; + ContextCallback executeInChildContext = _ => + { + telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, this.RemoteAddress?.Uri); + RequestTelemetryStateTracker.PushTelemetryState(message, telemetryState, timeout, OnTelemetryStateTimedOut); + executeSend(telemetryState); + }; + + try + { + ExecutionContext.Run(ExecutionContext.Capture(), executeInChildContext, null); + } + catch (Exception) + { + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + throw; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs new file mode 100644 index 0000000000..a26ef79256 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class InstrumentedDuplexSessionChannelFactory : InstrumentedChannelFactory, IChannelFactory +{ + private TimeSpan telemetryTimeOut; + + public InstrumentedDuplexSessionChannelFactory(IChannelFactory inner, TimeSpan telemetryTimeOut) + : base(inner) + { + this.telemetryTimeOut = telemetryTimeOut; + } + + private new IChannelFactory Inner { get => (IChannelFactory)base.Inner; } + + IDuplexSessionChannel IChannelFactory.CreateChannel(EndpointAddress to) + { + return new InstrumentedDuplexSessionChannel(this.Inner.CreateChannel(to), this.telemetryTimeOut); + } + + IDuplexSessionChannel IChannelFactory.CreateChannel(EndpointAddress to, Uri via) + { + return new InstrumentedDuplexSessionChannel(this.Inner.CreateChannel(to, via), this.telemetryTimeOut); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs new file mode 100644 index 0000000000..16615cdda0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs @@ -0,0 +1,114 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.Threading; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal sealed class InstrumentedRequestChannel : InstrumentedChannel, IRequestChannel +{ + public InstrumentedRequestChannel(IRequestChannel inner) + : base(inner) + { + } + + EndpointAddress IRequestChannel.RemoteAddress => this.Inner.RemoteAddress; + + Uri IRequestChannel.Via => this.Inner.Via; + + private new IRequestChannel Inner { get => (IRequestChannel)base.Inner; } + + Message IRequestChannel.Request(Message message) + { + var telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, ((IRequestChannel)this).RemoteAddress?.Uri); + Message reply; + try + { + reply = this.Inner.Request(message); + } + catch (Exception) + { + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + throw; + } + + ClientChannelInstrumentation.AfterRequestCompleted(reply, telemetryState); + return reply; + } + + Message IRequestChannel.Request(Message message, TimeSpan timeout) + { + var telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, ((IRequestChannel)this).RemoteAddress?.Uri); + Message reply; + try + { + reply = this.Inner.Request(message, timeout); + } + catch (Exception) + { + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + throw; + } + + ClientChannelInstrumentation.AfterRequestCompleted(reply, telemetryState); + return reply; + } + + IAsyncResult IRequestChannel.BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state) + { + return this.InternalBeginRequest(message, (cb, s) => this.Inner.BeginRequest(message, timeout, cb, s), callback, state); + } + + IAsyncResult IRequestChannel.BeginRequest(Message message, AsyncCallback callback, object state) + { + return this.InternalBeginRequest(message, (cb, s) => this.Inner.BeginRequest(message, cb, s), callback, state); + } + + Message IRequestChannel.EndRequest(IAsyncResult result) + { + var asyncResult = (AsyncResultWithTelemetryState)result; + Message reply; + try + { + reply = this.Inner.EndRequest(asyncResult.Inner); + } + catch (Exception) + { + ClientChannelInstrumentation.AfterRequestCompleted(null, asyncResult.TelemetryState); + throw; + } + + ClientChannelInstrumentation.AfterRequestCompleted(reply, asyncResult.TelemetryState); + return reply; + } + + private IAsyncResult InternalBeginRequest(Message message, Func beginRequestDelegate, AsyncCallback callback, object state) + { + IAsyncResult result = null; + ContextCallback executeInChildContext = _ => + { + var telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, ((IRequestChannel)this).RemoteAddress?.Uri); + var asyncCallback = AsyncResultWithTelemetryState.GetAsyncCallback(callback, telemetryState); + result = new AsyncResultWithTelemetryState(beginRequestDelegate(asyncCallback, state), telemetryState); + }; + + ExecutionContext.Run(ExecutionContext.Capture(), executeInChildContext, null); + return result; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs new file mode 100644 index 0000000000..2470bd3f27 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs @@ -0,0 +1,41 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class InstrumentedRequestChannelFactory : InstrumentedChannelFactory, IChannelFactory +{ + public InstrumentedRequestChannelFactory(IChannelFactory inner) + : base(inner) + { + } + + private new IChannelFactory Inner { get => (IChannelFactory)base.Inner; } + + IRequestChannel IChannelFactory.CreateChannel(EndpointAddress to, Uri via) + { + return new InstrumentedRequestChannel(this.Inner.CreateChannel(to, via)); + } + + IRequestChannel IChannelFactory.CreateChannel(EndpointAddress to) + { + return new InstrumentedRequestChannel(this.Inner.CreateChannel(to)); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs new file mode 100644 index 0000000000..cedbe860d6 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs @@ -0,0 +1,27 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal sealed class RequestTelemetryState +{ + public IDisposable SuppressionScope { get; set; } + + public Activity Activity { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs new file mode 100644 index 0000000000..278f078e79 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs @@ -0,0 +1,171 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.ServiceModel.Channels; +using System.Threading; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal static class RequestTelemetryStateTracker +{ + private static readonly Dictionary OutstandingRequestStates = new Dictionary(); + private static readonly SortedSet TimeoutQueue = new SortedSet(); + private static readonly object Sync = new object(); + private static readonly Timer Timer = new Timer(OnTimer); + private static long currentTimerDueAt = Timeout.Infinite; + + public static void PushTelemetryState(Message request, RequestTelemetryState telemetryState, TimeSpan timeout, Action timeoutCallback) + { + var messageId = request?.Headers.MessageId?.ToString(); + if (messageId != null) + { + var expiresAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + (long)timeout.TotalMilliseconds; + var timeoutProps = new EntryTimeoutProperties(messageId, expiresAt, timeoutCallback); + var entry = new Entry(telemetryState, timeoutProps); + lock (Sync) + { + OutstandingRequestStates.Add(messageId, entry); + TimeoutQueue.Add(timeoutProps); + SetTimerEarlierIfNeeded(expiresAt); + } + } + } + + public static RequestTelemetryState PopTelemetryState(Message reply) + { + var relatesTo = reply?.Headers.RelatesTo?.ToString(); + return relatesTo == null ? null : PopTelemetryState(relatesTo); + } + + private static RequestTelemetryState PopTelemetryState(string messageId) + { + lock (Sync) + { + if (OutstandingRequestStates.TryGetValue(messageId, out var entry)) + { + OutstandingRequestStates.Remove(messageId); + TimeoutQueue.Remove(entry.TimeoutProperties); + } + + return entry?.State; + } + } + + private static void OnTimer(object state) + { + List> timedOutEntries = null; + lock (Sync) + { + var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + EntryTimeoutProperties nextToExpire = null; + foreach (var entryTimeoutProps in TimeoutQueue) + { + if (entryTimeoutProps.ExpiresAt <= now) + { + if (timedOutEntries == null) + { + timedOutEntries = new List>(); + } + + timedOutEntries.Add(new(entryTimeoutProps, OutstandingRequestStates[entryTimeoutProps.MessageId])); + } + else + { + nextToExpire = entryTimeoutProps; + break; + } + } + + foreach (var entry in timedOutEntries ?? Enumerable.Empty>()) + { + OutstandingRequestStates.Remove(entry.Item1.MessageId); + TimeoutQueue.Remove(entry.Item1); + } + + // when there's no more outstanding requests we set time timer to infinite, effectively disabling it until another request arrives + var nextExpiry = nextToExpire?.ExpiresAt ?? Timeout.Infinite; + SetTimer(nextExpiry); + } + + timedOutEntries?.ForEach(entry => entry.Item1.TimeoutCallback(entry.Item2.State)); + } + + private static void SetTimerEarlierIfNeeded(long dueAt) + { + if (currentTimerDueAt == Timeout.Infinite || currentTimerDueAt > dueAt) + { + SetTimer(dueAt); + } + } + + private static void SetTimer(long dueAt) + { + long dueIn; + if (dueAt == Timeout.Infinite) + { + dueIn = Timeout.Infinite; + } + else + { + var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + dueIn = Math.Max(0, dueAt - now) + 50; // add 50ms here because the timer is not precise and often fires just a bit early + } + + Timer.Change(dueIn, Timeout.Infinite); + currentTimerDueAt = dueAt; + } + + private class Entry + { + public readonly RequestTelemetryState State; + public readonly EntryTimeoutProperties TimeoutProperties; + + public Entry(RequestTelemetryState state, EntryTimeoutProperties timeoutProperties) + { + this.State = state; + this.TimeoutProperties = timeoutProperties; + } + } + + private class EntryTimeoutProperties : IComparable + { + public readonly string MessageId; + public readonly long ExpiresAt; + public readonly Action TimeoutCallback; + + public EntryTimeoutProperties(string messageId, long expiresAt, Action timeoutCallback) + { + this.MessageId = messageId; + this.ExpiresAt = expiresAt; + this.TimeoutCallback = timeoutCallback; + } + + public int CompareTo(object obj) + { + var other = (EntryTimeoutProperties)obj; + var result = this.ExpiresAt.CompareTo(other.ExpiresAt); + if (result == 0) + { + result = string.Compare(this.MessageId, other.MessageId, StringComparison.Ordinal); + } + + return result; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs new file mode 100644 index 0000000000..7cf336c10f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs @@ -0,0 +1,71 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel.Channels; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +/// +/// A that can be used to instrument WCF clients. +/// +internal sealed class TelemetryBindingElement : BindingElement +{ + /// + public override IChannelFactory BuildChannelFactory(BindingContext context) + { + Guard.ThrowIfNull(context); + + if (typeof(TChannel) == typeof(IRequestChannel)) + { + return (IChannelFactory)new InstrumentedRequestChannelFactory(context.BuildInnerChannelFactory()); + } + + if (typeof(TChannel) == typeof(IDuplexSessionChannel)) + { + return (IChannelFactory)new InstrumentedDuplexSessionChannelFactory(context.BuildInnerChannelFactory(), context.Binding.SendTimeout); + } + + throw new NotSupportedException(); + } + + /// + public override bool CanBuildChannelFactory(BindingContext context) + { + Guard.ThrowIfNull(context); + + var supportedByInstrumentation = + typeof(TChannel) == typeof(IRequestChannel) || + typeof(TChannel) == typeof(IDuplexSessionChannel); + + return supportedByInstrumentation && base.CanBuildChannelFactory(context); + } + + /// + public override BindingElement Clone() + { + return new TelemetryBindingElement(); + } + + /// + public override T GetProperty(BindingContext context) + { + Guard.ThrowIfNull(context); + + return context.GetInnerProperty(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs new file mode 100644 index 0000000000..df4d4a4006 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs @@ -0,0 +1,26 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Collections.Generic; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal sealed class TelemetryContextMessageProperty +{ + public const string Name = "OpenTelemetry.Instrumentation.Wcf.Implementation.TelemetryContextMessageProperty"; + + public IDictionary ActionMappings { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 117b2092fa..e235bf33b4 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -3,8 +3,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) -Instruments WCF clients and/or services using implementations of -`IClientMessageInspector` and `IDispatchMessageInspector` respectively. +Instruments WCF clients and/or services. ## Installation @@ -50,8 +49,8 @@ using var openTelemetry = Sdk.CreateTracerProviderBuilder() ## WCF Client Configuration (.NET Framework) -Add the `IClientMessageInspector` instrumentation via a behavior extension on -the clients you want to instrument: +Configure the `TelemetryEndpointBehaviorExtensionElement` on the clients +you want to instrument: ```xml @@ -89,8 +88,7 @@ folder. ## WCF Client Configuration (.NET Core) -Add the `IClientMessageInspector` instrumentation as an endpoint behavior on the -clients you want to instrument: +Add the `TelemetryEndpointBehavior` extension to the clients you want to instrument: ```csharp StatusServiceClient client = new StatusServiceClient(binding, remoteAddress); @@ -194,10 +192,9 @@ instrument: ## WCF Programmatic Configuration Server and/or Client (.NET Framework + .NET Core) -To add `IDispatchMessageInspector` for servers (.NET Framework only) and/or -`IClientMessageInspector` for clients (.NET Framework & .NET Core) -programmatically, use the `TelemetryContractBehaviorAttribute` on the service -contracts you want to instrument: +To programmatically add instrumentation for servers (.NET Framework only) and/or +for clients (.NET Framework & .NET Core), use the `TelemetryContractBehaviorAttribute` +on the service contracts you want to instrument: ```csharp [ServiceContract( @@ -212,29 +209,6 @@ contracts you want to instrument: } ``` -## Known issues - -WCF library does not provide any extension points to handle exception thrown on -communication (e.g. EndpointNotFoundException). Because of that in case of such -an event the `Activity` will not be stopped correctly. This can be handled in -an application code by catching the exception and stopping the `Activity` manually. - -```csharp - StatusResponse? response = null; - try - { - response = await client.PingAsync(statusRequest).ConfigureAwait(false); - } - catch (Exception) - { - var activity = Activity.Current; - if (activity != null && activity.Source.Name.Contains("OpenTelemetry.Instrumentation.Wcf")) - { - activity.Stop(); - } - } -``` - ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs index f34646629f..a745f56f13 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs @@ -14,16 +14,12 @@ // limitations under the License. // -using System; using System.Collections.Generic; -using System.Diagnostics; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; -using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Internal; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Wcf; @@ -45,148 +41,16 @@ internal TelemetryClientMessageInspector(IDictionary act public object BeforeSendRequest(ref Message request, IClientChannel channel) { Guard.ThrowIfNull(request); - Guard.ThrowIfNull(channel); - try + request.Properties.Add(TelemetryContextMessageProperty.Name, new TelemetryContextMessageProperty() { - if (WcfInstrumentationActivitySource.Options == null || WcfInstrumentationActivitySource.Options.OutgoingRequestFilter?.Invoke(request) == false) - { - WcfInstrumentationEventSource.Log.RequestIsFilteredOut(); - return new State - { - SuppressionScope = SuppressDownstreamInstrumentation(), - }; - } - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.RequestFilterException(ex); - return new State - { - SuppressionScope = SuppressDownstreamInstrumentation(), - }; - } - - Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( - WcfInstrumentationActivitySource.OutgoingRequestActivityName, - ActivityKind.Client); - IDisposable suppressionScope = SuppressDownstreamInstrumentation(); - - if (activity != null) - { - string action; - if (!string.IsNullOrEmpty(request.Headers.Action)) - { - action = request.Headers.Action; - activity.DisplayName = action; - } - else - { - action = string.Empty; - } - - Propagators.DefaultTextMapPropagator.Inject( - new PropagationContext(activity.Context, Baggage.Current), - request, - WcfInstrumentationActivitySource.MessageHeaderValueSetter); - - if (activity.IsAllDataRequested) - { - activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); - - if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) - { - actionMetadata = new ActionMetadata - { - ContractName = null, - OperationName = action, - }; - } - - activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); - activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); - - if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) - { - activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); - } - - var remoteAddressUri = request.Headers.To ?? channel.RemoteAddress?.Uri; - if (remoteAddressUri != null) - { - activity.SetTag(WcfInstrumentationConstants.NetPeerNameTag, remoteAddressUri.Host); - activity.SetTag(WcfInstrumentationConstants.NetPeerPortTag, remoteAddressUri.Port); - activity.SetTag(WcfInstrumentationConstants.WcfChannelSchemeTag, remoteAddressUri.Scheme); - activity.SetTag(WcfInstrumentationConstants.WcfChannelPathTag, remoteAddressUri.LocalPath); - } - - if (request.Properties.Via != null) - { - activity.SetTag(WcfInstrumentationConstants.SoapViaTag, request.Properties.Via.ToString()); - } - - try - { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendRequest, request); - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.EnrichmentException(ex); - } - } - } - - return new State - { - SuppressionScope = suppressionScope, - Activity = activity, - }; + ActionMappings = this.actionMappings, + }); + return null; } /// public void AfterReceiveReply(ref Message reply, object correlationState) { - Guard.ThrowIfNull(reply); - Guard.ThrowIfNull(correlationState); - - State state = (State)correlationState; - - state.SuppressionScope?.Dispose(); - - if (state.Activity is Activity activity) - { - if (activity.IsAllDataRequested) - { - if (reply.IsFault) - { - activity.SetStatus(Status.Error); - } - - activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); - try - { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveReply, reply); - } - catch (Exception ex) - { - WcfInstrumentationEventSource.Log.EnrichmentException(ex); - } - } - - activity.Stop(); - } - } - - private static IDisposable SuppressDownstreamInstrumentation() - { - return WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false - ? SuppressInstrumentationScope.Begin() - : null; - } - - private class State - { - public IDisposable SuppressionScope; - public Activity Activity; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 7669d457b6..3faf31b076 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -21,18 +21,19 @@ using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; + #if NETFRAMEWORK /// /// An to add the -/// to service operations -/// and to client operations -/// programmatically. +/// to service operations, +/// and and +/// TelemetryBindingElement to client operations programmatically. /// #else /// /// An to add the -/// to client operations -/// programmatically. +/// and +/// TelemetryBindingElement to client operations programmatically. /// #endif [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] @@ -47,7 +48,9 @@ public void AddBindingParameters(ContractDescription contractDescription, Servic public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) { Guard.ThrowIfNull(clientRuntime); + Guard.ThrowIfNull(endpoint); TelemetryEndpointBehavior.ApplyClientBehaviorToClientRuntime(clientRuntime); + TelemetryEndpointBehavior.ApplyBindingElementToServiceEndpoint(endpoint); } /// diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index 7b13fb0c93..d5acfd17e8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -16,22 +16,24 @@ using System; using System.Collections.Generic; +using System.Linq; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; #if NETFRAMEWORK /// /// An implementation which adds the to client endpoints and the +/// cref="TelemetryBindingElement"/> to client endpoints and the /// to service endpoints. /// #else /// /// An implementation which adds the to client endpoints. +/// cref="TelemetryBindingElement"/> to client endpoints. /// #endif public class TelemetryEndpointBehavior : IEndpointBehavior @@ -44,8 +46,10 @@ public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterColle /// public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { + Guard.ThrowIfNull(endpoint); Guard.ThrowIfNull(clientRuntime); ApplyClientBehaviorToClientRuntime(clientRuntime); + ApplyBindingElementToServiceEndpoint(endpoint); } /// @@ -62,8 +66,32 @@ public void Validate(ServiceEndpoint endpoint) { } + internal static void ApplyBindingElementToServiceEndpoint(ServiceEndpoint endpoint) + { +#if NETFRAMEWORK + if (endpoint.IsSystemEndpoint) + { + return; + } +#endif + + if (endpoint.Binding is CustomBinding customBinding && customBinding.Elements.Find() != null) + { + return; + } + + var newBinding = new CustomBinding(endpoint.Binding); + newBinding.Elements.Insert(0, new TelemetryBindingElement()); + endpoint.Binding = newBinding; + } + internal static void ApplyClientBehaviorToClientRuntime(ClientRuntime clientRuntime) { + if (clientRuntime.ClientMessageInspectors.Any(cmi => cmi is TelemetryClientMessageInspector)) + { + return; + } + var actionMappings = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var clientOperation in clientRuntime.ClientOperations) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index dbf214f264..4dd73e88be 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -20,14 +20,15 @@ + + - diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs similarity index 67% rename from test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs rename to test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs index 555e1c2623..ffaf94d687 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryClientMessageInspectorTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,19 +24,20 @@ using System.ServiceModel.Channels; using System.Threading; using System.Threading.Tasks; +using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; using Xunit; namespace OpenTelemetry.Instrumentation.Wcf.Tests; [Collection("WCF")] -public class TelemetryClientMessageInspectorTests : IDisposable +public class TelemetryBindingElementForHttpTests : IDisposable { private readonly Uri serviceBaseUri; private readonly HttpListener listener; private readonly EventWaitHandle initializationHandle; - public TelemetryClientMessageInspectorTests() + public TelemetryBindingElementForHttpTests() { Random random = new Random(); var retryCount = 5; @@ -102,6 +103,10 @@ async void Listener() { writer.Write(@"RSP: Hello Open Telemetry!"); } + else if (request.Contains("ExecuteSynchronous")) + { + writer.Write(@"RSP: Hello Open Telemetry!"); + } else { writer.Write(@"RSP: Hello Open Telemetry!"); @@ -152,11 +157,6 @@ public async Task OutgoingRequestInstrumentationTest( bool enrichmentException = false, bool emptyOrNullAction = false) { -#if NETFRAMEWORK - const string OutgoingHttpOperationName = "OpenTelemetry.Instrumentation.Http.HttpWebRequest.HttpRequestOut"; -#else - const string OutgoingHttpOperationName = "System.Net.Http.HttpRequestOut"; -#endif List stoppedActivities = new List(); var builder = Sdk.CreateTracerProviderBuilder() @@ -194,7 +194,7 @@ public async Task OutgoingRequestInstrumentationTest( options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; options.SetSoapMessageVersion = includeVersion; }) - .AddHttpClientInstrumentation(); // <- Added to test SuppressDownstreamInstrumentation. + .AddDownstreamInstrumentation(); } TracerProvider tracerProvider = builder.Build(); @@ -204,6 +204,7 @@ public async Task OutgoingRequestInstrumentationTest( new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { + client.Endpoint.EndpointBehaviors.Add(new DownstreamInstrumentationEndpointBehavior()); client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); if (emptyOrNullAction) @@ -248,12 +249,12 @@ await client.ExecuteAsync( if (filter) { Assert.Single(stoppedActivities); - Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); + Assert.Equal("DownstreamInstrumentation", stoppedActivities[0].OperationName); } else { Assert.Equal(2, stoppedActivities.Count); - Assert.Equal(OutgoingHttpOperationName, stoppedActivities[0].OperationName); + Assert.Equal("DownstreamInstrumentation", stoppedActivities[0].OperationName); Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); } } @@ -306,4 +307,121 @@ await client.ExecuteAsync( Assert.Empty(stoppedActivities); } } + + [Fact] + public async void ActivitiesHaveCorrectParentTest() + { + var testSource = new ActivitySource("TestSource"); + + var stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource("TestSource") + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + ServiceClient client = new ServiceClient( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + + using (var parentActivity = testSource.StartActivity("ParentActivity")) + { + client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + var firstAsyncCall = client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + await client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + await firstAsyncCall; + } + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + testSource.Dispose(); + WcfInstrumentationActivitySource.Options = null; + } + + Assert.Equal(5, stoppedActivities.Count); + Assert.All(stoppedActivities, activity => Assert.Equal(stoppedActivities[0].TraceId, activity.TraceId)); + var parent = stoppedActivities.Single(activity => activity.Parent == null); + Assert.All( + stoppedActivities.Where(activity => activity != parent), + activity => Assert.Equal(parent.SpanId, activity.ParentSpanId)); + } + + [Fact] + public async void ErrorsAreHandledProperlyTest() + { + var testSource = new ActivitySource("TestSource"); + + var stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource("TestSource") + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + ServiceClient client = new ServiceClient( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + ServiceClient clientBadUrl = new ServiceClient( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(new Uri("http://localhost:1/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + clientBadUrl.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + + using (var parentActivity = testSource.StartActivity("ParentActivity")) + { + Assert.ThrowsAny(() => client.ErrorSynchronous()); + await Assert.ThrowsAnyAsync(client.ErrorAsync); + Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + await Assert.ThrowsAnyAsync(() => clientBadUrl.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + } + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + if (clientBadUrl.State == CommunicationState.Faulted) + { + clientBadUrl.Abort(); + } + else + { + clientBadUrl.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + testSource.Dispose(); + WcfInstrumentationActivitySource.Options = null; + } + + Assert.Equal(5, stoppedActivities.Count); + Assert.All(stoppedActivities, activity => Assert.Equal(stoppedActivities[0].TraceId, activity.TraceId)); + var parent = stoppedActivities.Single(activity => activity.Parent == null); + var children = stoppedActivities.Where(activity => activity != parent); + Assert.All(children, activity => Assert.Equal(parent.SpanId, activity.ParentSpanId)); + } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs new file mode 100644 index 0000000000..5a0366747d --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs @@ -0,0 +1,475 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.Threading.Tasks; +using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; +using OpenTelemetry.Trace; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[Collection("WCF")] +public class TelemetryBindingElementForTcpTests : IDisposable +{ + private readonly ITestOutputHelper output; + private readonly Uri serviceBaseUri; + private readonly ServiceHost serviceHost; + + public TelemetryBindingElementForTcpTests(ITestOutputHelper outputHelper) + { + this.output = outputHelper; + + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) + { + try + { + this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); + this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); + var endpoint = this.serviceHost.AddServiceEndpoint( + typeof(IServiceContract), + new NetTcpBinding(SecurityMode.None), + "/Service"); + this.serviceHost.Open(); + break; + } + catch (Exception ex) + { + this.output.WriteLine(ex.ToString()); + if (this.serviceHost.State == CommunicationState.Faulted) + { + this.serviceHost.Abort(); + } + else + { + this.serviceHost.Close(); + } + + this.serviceHost = null; + retryCount--; + } + } + + if (this.serviceHost == null) + { + throw new InvalidOperationException("ServiceHost could not be started."); + } + } + + public void Dispose() + { + this.serviceHost?.Close(); + } + + [Theory] + [InlineData(true, false)] + [InlineData(true, true)] + [InlineData(true, false, false)] + [InlineData(false)] + [InlineData(true, false, true, true)] + [InlineData(true, false, true, true, true)] + [InlineData(true, false, true, true, true, true)] + [InlineData(true, false, true, true, true, true, true)] + public async Task OutgoingRequestInstrumentationTest( + bool instrument, + bool filter = false, + bool suppressDownstreamInstrumentation = true, + bool includeVersion = false, + bool enrich = false, + bool enrichmentException = false, + bool emptyOrNullAction = false) + { + List stoppedActivities = new List(); + + var builder = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities); + + if (instrument) + { + builder + .AddWcfInstrumentation(options => + { + if (enrich) + { + if (!enrichmentException) + { + options.Enrich = (activity, eventName, message) => + { + switch (eventName) + { + case WcfEnrichEventNames.BeforeSendRequest: + activity.SetTag("client.beforesendrequest", WcfEnrichEventNames.BeforeSendRequest); + break; + case WcfEnrichEventNames.AfterReceiveReply: + activity.SetTag("client.afterreceivereply", WcfEnrichEventNames.AfterReceiveReply); + break; + } + }; + } + else + { + options.Enrich = (activity, eventName, message) => throw new Exception("Error while enriching activity"); + } + } + + options.OutgoingRequestFilter = (Message m) => !filter; + options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; + options.SetSoapMessageVersion = includeVersion; + }) + .AddDownstreamInstrumentation(); + } + + TracerProvider tracerProvider = builder.Build(); + + var client = new ServiceClient( + new NetTcpBinding(SecurityMode.None), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new DownstreamInstrumentationEndpointBehavior()); + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + + if (emptyOrNullAction) + { + await client.ExecuteWithEmptyActionNameAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } + else + { + await client.ExecuteAsync( + new ServiceRequest + { + Payload = "Hello Open Telemetry!", + }).ConfigureAwait(false); + } + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + + WcfInstrumentationActivitySource.Options = null; + } + + if (instrument) + { + if (!suppressDownstreamInstrumentation) + { + Assert.NotEmpty(stoppedActivities); + if (filter) + { + Assert.Single(stoppedActivities); + Assert.Equal("DownstreamInstrumentation", stoppedActivities[0].OperationName); + } + else + { + Assert.Equal(2, stoppedActivities.Count); + Assert.Equal("DownstreamInstrumentation", stoppedActivities[0].OperationName); + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); + } + } + else + { + if (!filter) + { + Assert.NotEmpty(stoppedActivities); + Assert.Single(stoppedActivities); + + Activity activity = stoppedActivities[0]; + + if (emptyOrNullAction) + { + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.DisplayName); + Assert.Equal("ExecuteWithEmptyActionName", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + } + else + { + Assert.Equal("http://opentelemetry.io/Service/Execute", activity.DisplayName); + Assert.Equal("Execute", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); + } + + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, activity.OperationName); + Assert.Equal(WcfInstrumentationConstants.WcfSystemValue, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcSystemTag).Value); + Assert.Equal("http://opentelemetry.io/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcServiceTag).Value); + Assert.Equal(this.serviceBaseUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerNameTag).Value); + Assert.Equal(this.serviceBaseUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.NetPeerPortTag).Value); + Assert.Equal("net.tcp", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelSchemeTag).Value); + Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); + if (includeVersion) + { + var value = activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value.ToString(); + Assert.Matches("""Soap.* \(http.*\) Addressing.* \(http.*\)""", value); + } + + if (enrich && !enrichmentException) + { + Assert.Equal(WcfEnrichEventNames.BeforeSendRequest, activity.TagObjects.Single(t => t.Key == "client.beforesendrequest").Value); + Assert.Equal(WcfEnrichEventNames.AfterReceiveReply, activity.TagObjects.Single(t => t.Key == "client.afterreceivereply").Value); + } + } + else + { + Assert.Empty(stoppedActivities); + } + } + } + else + { + Assert.Empty(stoppedActivities); + } + } + + [Fact] + public async void ActivitiesHaveCorrectParentTest() + { + var testSource = new ActivitySource("TestSource"); + + var stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource("TestSource") + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + var client = new ServiceClient( + new NetTcpBinding(SecurityMode.None), + new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + + using (var parentActivity = testSource.StartActivity("ParentActivity")) + { + client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + var firstAsyncCall = client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + await client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + await firstAsyncCall; + } + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + testSource.Dispose(); + WcfInstrumentationActivitySource.Options = null; + } + + Assert.Equal(5, stoppedActivities.Count); + Assert.All(stoppedActivities, activity => Assert.Equal(stoppedActivities[0].TraceId, activity.TraceId)); + var parent = stoppedActivities.Single(activity => activity.Parent == null); + Assert.All( + stoppedActivities.Where(activity => activity != parent), + activity => Assert.Equal(parent.SpanId, activity.ParentSpanId)); + } + + [Fact] + public async void ErrorsAreHandledProperlyTest() + { + var testSource = new ActivitySource("TestSource"); + + var stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource("TestSource") + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + var client = new ServiceClient(new NetTcpBinding(SecurityMode.None), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + var client2 = new ServiceClient(new NetTcpBinding(SecurityMode.None), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + var clientBadUrl = new ServiceClient(new NetTcpBinding(SecurityMode.None), new EndpointAddress(new Uri("net.tcp://localhost:1/Service"))); + var clientBadUrl2 = new ServiceClient(new NetTcpBinding(SecurityMode.None), new EndpointAddress(new Uri("net.tcp://localhost:1/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + client2.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + clientBadUrl.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + clientBadUrl2.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + + using (var parentActivity = testSource.StartActivity("ParentActivity")) + { + Assert.ThrowsAny(() => client.ErrorSynchronous()); + + // weird corner case: if an async call is made as the first hit (before the client is opened) the + // async execution context gets lost somewhere in WCF internals, so we'll explicitly open it first + client2.Open(); + await Assert.ThrowsAnyAsync(client2.ErrorAsync); + Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + await Assert.ThrowsAnyAsync(() => clientBadUrl2.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + } + } + finally + { + Action closeClient = client => + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + }; + closeClient(client); + closeClient(client2); + closeClient(clientBadUrl); + closeClient(clientBadUrl2); + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + testSource.Dispose(); + WcfInstrumentationActivitySource.Options = null; + } + + // this is 3 instead of 5 because the clientBadUrl calls fail during Open(), before the activity is created + Assert.Equal(3, stoppedActivities.Count); + Assert.All(stoppedActivities, activity => Assert.Equal(stoppedActivities[0].TraceId, activity.TraceId)); + var parent = stoppedActivities.Single(activity => activity.Parent == null); + var children = stoppedActivities.Where(activity => activity != parent); + Assert.All(children, activity => Assert.Equal(parent.SpanId, activity.ParentSpanId)); + } + + [Fact] + public async void OrphanedTelemetryTimesOut() + { + var stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + var binding = new NetTcpBinding(SecurityMode.None); + binding.SendTimeout = TimeSpan.FromMilliseconds(1000); + var client = new ServiceClient(binding, new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new DownstreamInstrumentationEndpointBehavior()); + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + DownstreamInstrumentationChannel.FailNextReceive(); + await Assert.ThrowsAnyAsync(() => client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + + for (var i = 0; i < 50; i++) + { + if (stoppedActivities.Count > 0) + { + break; + } + + await Task.Delay(100); + } + + Assert.Single(stoppedActivities); + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + WcfInstrumentationActivitySource.Options = null; + } + } + + [Fact] + public async void DynamicTimeoutValuesAreRespected() + { + var stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + var binding = new NetTcpBinding(SecurityMode.None); + binding.SendTimeout = TimeSpan.FromMilliseconds(15000); + var client = new ServiceClient(binding, new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new DownstreamInstrumentationEndpointBehavior()); + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + client.InnerChannel.OperationTimeout = TimeSpan.FromMilliseconds(1000); + DownstreamInstrumentationChannel.FailNextReceive(); + await Assert.ThrowsAnyAsync(() => client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + + var startedWaiting = DateTime.UtcNow; + for (var i = 0; i < 200; i++) + { + if (stoppedActivities.Count > 0) + { + break; + } + + await Task.Delay(100); + } + + Assert.True(DateTime.UtcNow - startedWaiting < TimeSpan.FromSeconds(10)); + Assert.Single(stoppedActivities); + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + WcfInstrumentationActivitySource.Options = null; + } + } +} +#endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs new file mode 100644 index 0000000000..5abaae0a97 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs @@ -0,0 +1,41 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Reflection; +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +public class DownstreamInstrumentationBindingElement : BindingElement +{ + public override BindingElement Clone() + { + return new DownstreamInstrumentationBindingElement(); + } + + public override T GetProperty(BindingContext context) + { + return context.GetInnerProperty(); + } + + public override IChannelFactory BuildChannelFactory(BindingContext context) + { + var proxy = DispatchProxy.Create, DownstreamInstrumentationChannelFactory>() + as DownstreamInstrumentationChannelFactory; + proxy.Target = base.BuildChannelFactory(context); + return (IChannelFactory)proxy; + } +} diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs new file mode 100644 index 0000000000..da8b20cdfd --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs @@ -0,0 +1,73 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +public class DownstreamInstrumentationChannel : DispatchProxy +{ + public const string DownstreamInstrumentationSourceName = "DownstreamInstrumentationSource"; + private static readonly ActivitySource DownstreamInstrumentationSource = new ActivitySource(DownstreamInstrumentationSourceName); + private static bool failNextReceive; + + private object Target { get; set; } + + public static TChannel Create(TChannel target) + { + var proxy = Create() as DownstreamInstrumentationChannel; + proxy.Target = target; + return (TChannel)(object)proxy; + } + + public static void FailNextReceive(bool shouldFail = true) + { + failNextReceive = shouldFail; + } + + protected override object Invoke(MethodInfo targetMethod, object[] args) + { + var toInstrument = new[] + { + nameof(IRequestChannel.Request), + nameof(IRequestChannel.BeginRequest), + nameof(IOutputChannel.Send), + nameof(IOutputChannel.BeginSend), + }; + + using var activity = toInstrument.Contains(targetMethod.Name) ? DownstreamInstrumentationSource.StartActivity("DownstreamInstrumentation") : null; + + var receiveMethods = new[] + { + nameof(IInputChannel.Receive), + nameof(IInputChannel.BeginReceive), + nameof(IInputChannel.TryReceive), + nameof(IInputChannel.BeginTryReceive), + }; + + if (failNextReceive && receiveMethods.Contains(targetMethod.Name)) + { + failNextReceive = false; + throw new Exception(); + } + + return targetMethod.Invoke(this.Target, args); + } +} diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs new file mode 100644 index 0000000000..768bea1531 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs @@ -0,0 +1,36 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Reflection; +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +public class DownstreamInstrumentationChannelFactory : DispatchProxy +{ + public IChannelFactory Target { get; set; } + + protected override object Invoke(MethodInfo targetMethod, object[] args) + { + var returnValue = targetMethod.Invoke(this.Target, args); + if (targetMethod.Name == nameof(IChannelFactory.CreateChannel)) + { + return DownstreamInstrumentationChannel.Create((TChannel)returnValue); + } + + return returnValue; + } +} diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs new file mode 100644 index 0000000000..81a3c6dd35 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs @@ -0,0 +1,43 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +public class DownstreamInstrumentationEndpointBehavior : IEndpointBehavior +{ + public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) + { + } + + public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) + { + var newBinding = new CustomBinding(endpoint.Binding); + newBinding.Elements.Insert(0, new DownstreamInstrumentationBindingElement()); + endpoint.Binding = newBinding; + } + + public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) + { + } + + public void Validate(ServiceEndpoint endpoint) + { + } +} diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs new file mode 100644 index 0000000000..3b0e5defff --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs @@ -0,0 +1,25 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; + +public static class DownstreamInstrumentationExtensions +{ + public static TracerProviderBuilder AddDownstreamInstrumentation(this TracerProviderBuilder builder) => + builder.AddSource(DownstreamInstrumentationChannel.DownstreamInstrumentationSourceName); +} diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 5dbee33438..c99e765a86 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -25,9 +25,18 @@ public interface IServiceContract [OperationContract] Task ExecuteAsync(ServiceRequest request); + [OperationContract] + ServiceResponse ExecuteSynchronous(ServiceRequest request); + [OperationContract(Action = "")] Task ExecuteWithEmptyActionNameAsync(ServiceRequest request); [OperationContract(IsOneWay = true)] void ExecuteWithOneWay(ServiceRequest request); + + [OperationContract] + void ErrorSynchronous(); + + [OperationContract] + Task ErrorAsync(); } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 3cecbe1cb9..1807014e13 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -28,6 +28,16 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; Name = "Service")] public class Service : IServiceContract { + public Task ErrorAsync() + { + throw new System.Exception(); + } + + public void ErrorSynchronous() + { + throw new System.Exception(); + } + public Task ExecuteAsync(ServiceRequest request) { return Task.FromResult( @@ -37,6 +47,14 @@ public Task ExecuteAsync(ServiceRequest request) }); } + public ServiceResponse ExecuteSynchronous(ServiceRequest request) + { + return new ServiceResponse + { + Payload = $"RSP: {request.Payload}", + }; + } + public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) { return Task.FromResult( diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index 7381b135fc..c7a0eca6d9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -30,9 +30,18 @@ public ServiceClient(Binding binding, EndpointAddress remoteAddress) public Task ExecuteAsync(ServiceRequest request) => this.Channel.ExecuteAsync(request); + public ServiceResponse ExecuteSynchronous(ServiceRequest request) + => this.Channel.ExecuteSynchronous(request); + public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) => this.Channel.ExecuteWithEmptyActionNameAsync(request); public void ExecuteWithOneWay(ServiceRequest request) => this.Channel.ExecuteWithOneWay(request); + + public Task ErrorAsync() + => this.Channel.ErrorAsync(); + + public void ErrorSynchronous() + => this.Channel.ErrorSynchronous(); } From 7db8a8ada032b5e9e5d947c89c7cd6d4980825ba Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 14 Aug 2023 14:52:11 -0700 Subject: [PATCH 0784/1499] [wcf] 1.0.0-rc.11 release (#1308) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 04c6289406..dbc3e2ef3e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.11 + +Released 2023-Aug-14 + * Update OpenTelemetry SDK version to `1.5.1`. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) * Client instrumentation implementation moved to lower-level `BindingElement`. From 304a1c35ae12329418a60d04669eea07827074c3 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 15 Aug 2023 13:29:31 -0700 Subject: [PATCH 0785/1499] Update CONTRIBUTING.md to add guidance on supporting for .NET versions (#1293) --- CONTRIBUTING.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0b6b283b7..f14ea99a0a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -258,3 +258,17 @@ the main branch. The workflow file should be named as [![NuGet version badge](https://img.shields.io/nuget/v/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) [![NuGet download count badge](https://img.shields.io/nuget/dt/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) ``` + +### Guidance for components on supporting target frameworks + +* SHOULD support the [.NET + versions](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main#supported-net-versions) + which are supported by the OpenTelemetry main repo packages. +* MUST document the target frameworks supported in the main README.md file. +* MUST NOT support out-of-support .NET runtimes (e.g.: `.NET Framework 4.5.2`, + `.NET Core 2.1` etc). CI checks in this repository will not be run against out + of support versions. +* Whenever a .NET version reaches end of support, components MUST drop support + for it as well. Note: This change does not require major version bump. For + reference see + [this](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3351). From cb5b2193ef9cacc0b9ef699e085022577551bf85 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 15 Aug 2023 22:39:46 -0700 Subject: [PATCH 0786/1499] [ResourceDetector.Azure] Avoid multiple outgoing requests for AzureVMResourceDetector (#1307) --- .../AzureVMResourceDetector.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs index f68394622d..1308e81d42 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs @@ -41,18 +41,27 @@ public sealed class AzureVMResourceDetector : IResourceDetector ResourceSemanticConventions.AttributeServiceInstance, }; + private static Resource? vmResource; + /// public Resource Detect() { try { + if (vmResource != null) + { + return vmResource; + } + // Prevents the http operations from being instrumented. using var scope = SuppressInstrumentationScope.Begin(); var vmMetaDataResponse = AzureVmMetaDataRequestor.GetAzureVmMetaDataResponse(); if (vmMetaDataResponse == null) { - return Resource.Empty; + vmResource = Resource.Empty; + + return vmResource; } var attributeList = new List>(ExpectedAzureAmsFields.Count); @@ -61,12 +70,14 @@ public Resource Detect() attributeList.Add(new KeyValuePair(field, vmMetaDataResponse.GetValueForField(field))); } - return new Resource(attributeList); + vmResource = new Resource(attributeList); } catch { // TODO: log exception. - return Resource.Empty; + vmResource = Resource.Empty; } + + return vmResource; } } From 78598baf6f00d411539be599ed6a53b03bbeb70c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 18 Aug 2023 12:09:34 -0700 Subject: [PATCH 0787/1499] Update directives to remove netcoreapp3.1 (#1310) --- .../RuntimeInstrumentationOptions.cs | 6 +-- ....Instrumentation.StackExchangeRedis.csproj | 1 - src/Shared/Guard.cs | 2 +- src/Shared/ServiceProviderExtensions.cs | 46 ------------------- .../RuntimeInstrumentationOptionsTests.cs | 12 +---- .../RuntimeMetricsTests.cs | 2 +- 6 files changed, 6 insertions(+), 63 deletions(-) delete mode 100644 src/Shared/ServiceProviderExtensions.cs diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs index bb22d5243c..6af9681b3e 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs @@ -34,7 +34,7 @@ public class RuntimeInstrumentationOptions public bool? JitEnabled { get; set; } #endif - #if NETCOREAPP3_1_OR_GREATER + #if NET6_0_OR_GREATER /// /// Gets or sets a value indicating whether threading metrics should be collected. /// @@ -58,7 +58,7 @@ public class RuntimeInstrumentationOptions #if NET6_0_OR_GREATER && this.JitEnabled == null #endif - #if NETCOREAPP3_1_OR_GREATER + #if NET6_0_OR_GREATER && this.ThreadingEnabled == null #endif && this.AssembliesEnabled == null @@ -76,7 +76,7 @@ public class RuntimeInstrumentationOptions internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; #endif - #if NETCOREAPP3_1_OR_GREATER + #if NET6_0_OR_GREATER /// /// Gets a value indicating whether threading metrics is enabled. /// diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 36b3af1092..a82272a763 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index 0015ea41f4..b5415c4482 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -51,7 +51,7 @@ public CallerArgumentExpressionAttribute(string parameterName) } #endif -#if !NETCOREAPP3_0_OR_GREATER && !NETSTANDARD2_1_OR_GREATER +#if !NET6_0_OR_GREATER && !NETSTANDARD2_1_OR_GREATER namespace System.Diagnostics.CodeAnalysis { /// Specifies that an output is not even if diff --git a/src/Shared/ServiceProviderExtensions.cs b/src/Shared/ServiceProviderExtensions.cs deleted file mode 100644 index dbfc46ea62..0000000000 --- a/src/Shared/ServiceProviderExtensions.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER -using Microsoft.Extensions.Options; -#endif - -namespace System; - -/// -/// Extension methods for OpenTelemetry dependency injection support. -/// -internal static class ServiceProviderExtensions -{ - /// - /// Get options from the supplied . - /// - /// Options type. - /// . - /// Options instance. - public static T GetOptions(this IServiceProvider serviceProvider) - where T : class, new() - { -#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER - IOptions options = (IOptions)serviceProvider.GetService(typeof(IOptions)); - - // Note: options could be null if user never invoked services.AddOptions(). - return options?.Value ?? new T(); -#else - return new T(); -#endif - } -} diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs index bd133de24e..fbb1944954 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs @@ -27,8 +27,6 @@ public void Enable_All_If_Nothing_Was_Defined() Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER Assert.True(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER Assert.True(options.IsThreadingEnabled); #endif Assert.True(options.IsAssembliesEnabled); @@ -43,8 +41,6 @@ public void Enable_Gc_Only() Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER Assert.False(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif Assert.False(options.IsAssembliesEnabled); @@ -65,16 +61,14 @@ public void Enable_Jit_Only() } #endif - #if NETCOREAPP3_1_OR_GREATER + #if NET6_0_OR_GREATER [Fact] public void Enable_Threading_Only() { var options = new RuntimeInstrumentationOptions { ThreadingEnabled = true }; Assert.False(options.IsGcEnabled); - #if NET6_0_OR_GREATER Assert.False(options.IsJitEnabled); - #endif Assert.True(options.IsThreadingEnabled); Assert.False(options.IsAssembliesEnabled); Assert.False(options.IsAllEnabled); @@ -89,8 +83,6 @@ public void Enable_Assemblies_Only() Assert.False(options.IsGcEnabled); #if NET6_0_OR_GREATER Assert.False(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif Assert.True(options.IsAssembliesEnabled); @@ -105,8 +97,6 @@ public void Enable_Multiple() Assert.True(options.IsGcEnabled); #if NET6_0_OR_GREATER Assert.False(options.IsJitEnabled); - #endif - #if NETCOREAPP3_1_OR_GREATER Assert.False(options.IsThreadingEnabled); #endif Assert.True(options.IsAssembliesEnabled); diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index b935e0c7d5..dc35543ecf 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -17,7 +17,7 @@ using System; using System.Collections.Generic; using System.Linq; -#if NETCOREAPP3_1_OR_GREATER +#if NET6_0_OR_GREATER using System.Threading; using System.Threading.Tasks; #endif From 12aa6c6fe606cf8b8e28d0ae0339eaea25133662 Mon Sep 17 00:00:00 2001 From: moonheart Date: Tue, 22 Aug 2023 02:11:43 +0800 Subject: [PATCH 0788/1499] [Instrumentation.MysqlData] deprecate package + remove code (#1317) --- .../comp_instrumentation_mysqldata.md | 41 --- .github/component_owners.yml | 4 - .../package-Instrumentation.MySqlData.yml | 66 ---- opentelemetry-dotnet-contrib.sln | 15 - .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 11 - .../AssemblyInfo.cs | 23 -- .../CHANGELOG.md | 6 +- .../MySqlActivitySourceHelper.cs | 45 --- .../MySqlDataInstrumentation.cs | 290 ------------------ .../MySqlDataInstrumentationEventSource.cs | 46 --- .../MySqlDataInstrumentationOptions.cs | 46 --- .../MySqlDataTraceCommand.cs | 29 -- ...Telemetry.Instrumentation.MySqlData.csproj | 22 -- .../README.md | 12 + .../TracerProviderBuilderExtensions.cs | 56 ---- .../MySqlDataTests.cs | 222 -------------- ...try.Instrumentation.MySqlData.Tests.csproj | 31 -- 18 files changed, 15 insertions(+), 951 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md delete mode 100644 .github/workflows/package-Instrumentation.MySqlData.yml delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj delete mode 100644 src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs delete mode 100644 test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs delete mode 100644 test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md deleted file mode 100644 index 654ca953e3..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_mysqldata.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.MySqlData -about: Issue with OpenTelemetry.Instrumentation.MySqlData -labels: comp:instrumentation.mysqldata ---- - -# Issue with OpenTelemetry.Instrumentation.MySqlData - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 9017e7cb89..785de6af2f 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -42,8 +42,6 @@ components: - pcwiese src/OpenTelemetry.Instrumentation.Hangfire/: - fred2u - src/OpenTelemetry.Instrumentation.MySqlData/: - - moonheart src/OpenTelemetry.Instrumentation.Owin/: - codeblanch src/OpenTelemetry.Instrumentation.Process/: @@ -124,8 +122,6 @@ components: - pcwiese test/OpenTelemetry.Instrumentation.Hangfire.Tests/: - fred2u - test/OpenTelemetry.Instrumentation.MySqlData.Tests/: - - moonheart test/OpenTelemetry.Instrumentation.Owin.Tests/: - codeblanch test/OpenTelemetry.Instrumentation.Quartz.Tests/: diff --git a/.github/workflows/package-Instrumentation.MySqlData.yml b/.github/workflows/package-Instrumentation.MySqlData.yml deleted file mode 100644 index 9431b441c7..0000000000 --- a/.github/workflows/package-Instrumentation.MySqlData.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Pack OpenTelemetry.Instrumentation.MySqlData - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'Instrumentation.MySqlData-*' # trigger when we create a tag with prefix "Instrumentation.MySqlData-" - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - permissions: - contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.MySqlData - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3' - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index b5b014d575..23bc86e68e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -55,7 +55,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml - .github\workflows\package-Instrumentation.MySqlData.yml = .github\workflows\package-Instrumentation.MySqlData.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml @@ -147,10 +146,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ElasticsearchClient.Tests", "test\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests\OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj", "{970B604C-C57F-4767-A080-67976E69F76E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData", "src\OpenTelemetry.Instrumentation.MySqlData\OpenTelemetry.Instrumentation.MySqlData.csproj", "{A1D82008-81D4-4CC5-AA8E-04357F6AA06C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.MySqlData.Tests", "test\OpenTelemetry.Instrumentation.MySqlData.Tests\OpenTelemetry.Instrumentation.MySqlData.Tests.csproj", "{662A00CA-B152-40D4-B9A4-6061490B8B3D}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore", "src\OpenTelemetry.Instrumentation.EntityFrameworkCore\OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj", "{D4468444-69EF-4BF3-B13F-61F4AB728813}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests", "test\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests\OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj", "{A1F7FA66-C83D-485D-90FE-71C4018971D4}" @@ -377,14 +372,6 @@ Global {970B604C-C57F-4767-A080-67976E69F76E}.Debug|Any CPU.Build.0 = Debug|Any CPU {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.ActiveCfg = Release|Any CPU {970B604C-C57F-4767-A080-67976E69F76E}.Release|Any CPU.Build.0 = Release|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C}.Release|Any CPU.Build.0 = Release|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {662A00CA-B152-40D4-B9A4-6061490B8B3D}.Release|Any CPU.Build.0 = Release|Any CPU {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D4468444-69EF-4BF3-B13F-61F4AB728813}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4468444-69EF-4BF3-B13F-61F4AB728813}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -647,8 +634,6 @@ Global {8DABC11A-624E-4554-ACA4-D5B80146B9C6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {96F5B85B-402B-4DFB-AF31-33D5A2EBE35B} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {970B604C-C57F-4767-A080-67976E69F76E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {A1D82008-81D4-4CC5-AA8E-04357F6AA06C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {662A00CA-B152-40D4-B9A4-6061490B8B3D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D4468444-69EF-4BF3-B13F-61F4AB728813} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A1F7FA66-C83D-485D-90FE-71C4018971D4} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {D0B694E4-AAE4-492F-ACCB-3D913A874780} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index ab0a45b98a..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,11 +0,0 @@ -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.EnableConnectionLevelAttributes.get -> bool -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.EnableConnectionLevelAttributes.set -> void -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.MySqlDataInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.RecordException.get -> bool -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.get -> bool -OpenTelemetry.Instrumentation.MySqlData.MySqlDataInstrumentationOptions.SetDbStatement.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddMySqlDataInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs deleted file mode 100644 index 766e46cb93..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/AssemblyInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MySqlData.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.MySqlData.Tests")] -#endif diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md index 064e4d1035..e4d4e86e36 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/CHANGELOG.md @@ -1,9 +1,9 @@ # Changelog -## Unreleased +## Deprecated -* Update OTel API version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* This package is deprecated. Please check [README.md](README.md#deprecated) + for more details. ## 1.0.0-beta.7 diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs deleted file mode 100644 index 96a7648d55..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlActivitySourceHelper.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Instrumentation.MySqlData; - -/// -/// Helper class to hold common properties used by MySqlDataDiagnosticListener. -/// -internal class MySqlActivitySourceHelper -{ - public const string MysqlDatabaseSystemName = "mysql"; - - public static readonly AssemblyName AssemblyName = typeof(MySqlActivitySourceHelper).Assembly.GetName(); - public static readonly string ActivitySourceName = AssemblyName.Name; - public static readonly string ActivityName = ActivitySourceName + ".Execute"; - - public static readonly IEnumerable> CreationTags = new[] - { - new KeyValuePair(SemanticConventions.AttributeDbSystem, MysqlDatabaseSystemName), - }; - - private static readonly Version Version = typeof(MySqlActivitySourceHelper).Assembly.GetName().Version; -#pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before ActivitySource otherwise null ref exception is thrown. - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); -#pragma warning restore SA1202 // Elements should be ordered by access -} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs deleted file mode 100644 index 75d5d87814..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentation.cs +++ /dev/null @@ -1,290 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Globalization; -using System.Linq.Expressions; -using System.Reflection; -using MySql.Data.MySqlClient; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Instrumentation.MySqlData; - -/// -/// MySql.Data instrumentation. -/// -internal class MySqlDataInstrumentation : DefaultTraceListener -{ - private readonly ConcurrentDictionary dbConn = new(); - - private readonly MySqlDataInstrumentationOptions options; - - private readonly Func? builderFactory; - - public MySqlDataInstrumentation(MySqlDataInstrumentationOptions? options = null) - { - this.options = options ?? new MySqlDataInstrumentationOptions(); - MySqlTrace.Listeners.Clear(); - MySqlTrace.Listeners.Add(this); - MySqlTrace.Switch.Level = SourceLevels.Information; - - // Mysql.Data removed `MySql.Data.MySqlClient.MySqlTrace.QueryAnalysisEnabled` since 8.0.31 so we need to set this using reflection. - var queryAnalysisEnabled = - typeof(MySqlTrace).GetProperty("QueryAnalysisEnabled", BindingFlags.Public | BindingFlags.Static); - if (queryAnalysisEnabled != null) - { - queryAnalysisEnabled.SetValue(null, true); - } - - // Mysql.Data add optional param `isAnalyzed` to MySqlConnectionStringBuilder constructor since 8.0.32 - var ctor = typeof(MySqlConnectionStringBuilder).GetConstructor(new[] { typeof(string), typeof(bool) }); - if (ctor == null) - { - ctor = typeof(MySqlConnectionStringBuilder).GetConstructor(new[] { typeof(string) }); - if (ctor == null) - { - MySqlDataInstrumentationEventSource.Log.ErrorInitialize( - "Failed to get proper MySqlConnectionStringBuilder constructor, maybe unsupported Mysql.Data version. Connection Level Details will not be available.", - string.Empty); - return; - } - - var p1 = Expression.Parameter(typeof(string), "connectionString"); - var newExpression = Expression.New(ctor, p1); - var func = Expression.Lambda>(newExpression, p1).Compile(); - this.builderFactory = s => func(s); - } - else - { - var p1 = Expression.Parameter(typeof(string)); - var p2 = Expression.Parameter(typeof(bool)); - var newExpression = Expression.New(ctor, p1, p2); - var func = Expression.Lambda>(newExpression, p1, p2).Compile(); - this.builderFactory = s => func(s, false); - } - } - - /// - public override void TraceEvent( - TraceEventCache eventCache, - string source, - TraceEventType eventType, - int id, - string format, - params object[] args) - { - try - { - switch ((MySqlTraceEventType)id) - { - case MySqlTraceEventType.ConnectionOpened: - // args: [driverId, connStr, threadId] - if (this.builderFactory != null) - { - var driverId = (long)args[0]; - var connStr = args[1].ToString(); - this.dbConn[driverId] = this.builderFactory(connStr); - } - - break; - case MySqlTraceEventType.ConnectionClosed: - break; - case MySqlTraceEventType.QueryOpened: - // args: [driverId, threadId, cmdText] - this.BeforeExecuteCommand(this.GetCommand(args[0], args[2])); - break; - case MySqlTraceEventType.ResultOpened: - break; - case MySqlTraceEventType.ResultClosed: - break; - case MySqlTraceEventType.QueryClosed: - // args: [driverId] - AfterExecuteCommand(); - break; - case MySqlTraceEventType.StatementPrepared: - break; - case MySqlTraceEventType.StatementExecuted: - break; - case MySqlTraceEventType.StatementClosed: - break; - case MySqlTraceEventType.NonQuery: - break; - case MySqlTraceEventType.UsageAdvisorWarning: - break; - case MySqlTraceEventType.Warning: - break; - case MySqlTraceEventType.Error: - // args: [driverId, exNumber, exMessage] - this.ErrorExecuteCommand(GetMySqlErrorException(args[2])); - break; - case MySqlTraceEventType.QueryNormalized: - // Should use QueryNormalized event when it exists. Because cmdText in QueryOpened event is incomplete when cmdText.length>300 - // args: [driverId, threadId, normalized_query] - this.OverwriteDbStatement(this.GetCommand(args[0], args[2])); - break; - default: - MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(id, string.Format(CultureInfo.InvariantCulture, format, args)); - break; - } - } - catch (Exception e) - { - MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(id, string.Format(CultureInfo.InvariantCulture, format, args), e.ToString()); - } - } - - private static Exception GetMySqlErrorException(object errorMsg) - { -#pragma warning disable CA2201 // Do not raise reserved exception types - return new Exception(errorMsg?.ToString()); -#pragma warning restore CA2201 // Do not raise reserved exception types - } - - private static void AfterExecuteCommand() - { - var activity = Activity.Current; - if (activity == null) - { - return; - } - - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } - - activity.Stop(); - } - - private void BeforeExecuteCommand(MySqlDataTraceCommand command) - { - var activity = MySqlActivitySourceHelper.ActivitySource.StartActivity( - MySqlActivitySourceHelper.ActivityName, - ActivityKind.Client, - Activity.Current?.Context ?? default, - MySqlActivitySourceHelper.CreationTags); - if (activity == null) - { - return; - } - - if (activity.IsAllDataRequested) - { - if (this.options.SetDbStatement) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); - } - - if (command.ConnectionStringBuilder != null) - { - activity.DisplayName = command.ConnectionStringBuilder.Database; - activity.SetTag(SemanticConventions.AttributeDbName, command.ConnectionStringBuilder.Database); - - this.AddConnectionLevelDetailsToActivity(command.ConnectionStringBuilder, activity); - } - } - } - - private void OverwriteDbStatement(MySqlDataTraceCommand command) - { - var activity = Activity.Current; - if (activity == null) - { - return; - } - - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } - - if (activity.IsAllDataRequested) - { - if (this.options.SetDbStatement) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, command.SqlText); - } - } - } - - private void ErrorExecuteCommand(Exception exception) - { - var activity = Activity.Current; - if (activity == null) - { - return; - } - - if (activity.Source != MySqlActivitySourceHelper.ActivitySource) - { - return; - } - - try - { - if (activity.IsAllDataRequested) - { - activity.SetStatus(Status.Error.WithDescription(exception.Message)); - if (this.options.RecordException) - { - activity.RecordException(exception); - } - } - } - finally - { - activity.Stop(); - } - } - - private MySqlDataTraceCommand GetCommand(object driverIdObj, object? cmd) - { - var command = new MySqlDataTraceCommand(); - if (this.dbConn.TryGetValue((long)driverIdObj, out var database)) - { - command.ConnectionStringBuilder = database; - } - - command.SqlText = cmd == null ? string.Empty : cmd.ToString(); - return command; - } - - private void AddConnectionLevelDetailsToActivity(MySqlConnectionStringBuilder dataSource, Activity sqlActivity) - { - if (!this.options.EnableConnectionLevelAttributes) - { - sqlActivity.SetTag(SemanticConventions.AttributePeerService, dataSource.Server); - } - else - { - var uriHostNameType = Uri.CheckHostName(dataSource.Server); - - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - sqlActivity.SetTag(SemanticConventions.AttributeNetPeerIp, dataSource.Server); - } - else - { - sqlActivity.SetTag(SemanticConventions.AttributeNetPeerName, dataSource.Server); - } - - sqlActivity.SetTag(SemanticConventions.AttributeNetPeerPort, dataSource.Port); - sqlActivity.SetTag(SemanticConventions.AttributeDbUser, dataSource.UserID); - } - } -} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs deleted file mode 100644 index d2721d4375..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationEventSource.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Diagnostics.Tracing; - -namespace OpenTelemetry.Instrumentation.MySqlData; - -/// -/// EventSource events emitted from the project. -/// -[EventSource(Name = "OpenTelemetry-Instrumentation-MySqlData")] -internal class MySqlDataInstrumentationEventSource : EventSource -{ - public static readonly MySqlDataInstrumentationEventSource Log = new MySqlDataInstrumentationEventSource(); - - [Event(1, Message = "Unknown MySqlTraceEventType: {0}, Message {1}", Level = EventLevel.Error)] - public void UnknownMySqlTraceEventType(int mysqlEventId, string message) - { - this.WriteEvent(1, mysqlEventId, message); - } - - [Event(2, Message = "Error while processing trace event, MySqlTraceEventType: {0}, Message {1}, Exception: {2}", Level = EventLevel.Error)] - public void ErrorTraceEvent(int mysqlEventId, string message, string exception) - { - this.WriteEvent(1, mysqlEventId, message, exception); - } - - [Event(3, Message = "Error while initializing MySqlDataInstrumentation, Message {0}, Exception: {1}", Level = EventLevel.Warning)] - public void ErrorInitialize(string message, string exception) - { - this.WriteEvent(1, message, exception); - } -} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs deleted file mode 100644 index fc1afcc288..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataInstrumentationOptions.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Instrumentation.MySqlData; - -/// -/// Options for . -/// -public class MySqlDataInstrumentationOptions -{ - /// - /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. Default value: False. - /// - /// - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. - /// - public bool RecordException { get; set; } - - /// - /// Gets or sets a value indicating whether or not the should add the text as the tag. Default value: False. - /// - public bool SetDbStatement { get; set; } - - /// - /// Gets or sets a value indicating whether or not the should parse the DataSource on a SqlConnection into server name, instance name, and/or port connection-level attribute tags. Default value: False. - /// - /// - /// The default behavior is to set the MySqlConnection DataSource as the tag. If enabled, MySqlConnection DataSource will be parsed and the server name will be sent as the or tag, the instance name will be sent as the tag, and the port will be sent as the tag if it is not 1433 (the default port). - /// - public bool EnableConnectionLevelAttributes { get; set; } -} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs b/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs deleted file mode 100644 index 9cb857725c..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/MySqlDataTraceCommand.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using MySql.Data.MySqlClient; - -namespace OpenTelemetry.Instrumentation.MySqlData; - -/// -/// Information of current executing command. -/// -internal class MySqlDataTraceCommand -{ - public MySqlConnectionStringBuilder? ConnectionStringBuilder { get; set; } - - public string SqlText { get; set; } = string.Empty; -} diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj b/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj deleted file mode 100644 index 2c721cafb6..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/OpenTelemetry.Instrumentation.MySqlData.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - netstandard2.0 - OpenTelemetry instrumentation for MySql.Data - $(PackageTags);distributed-tracing;MySql.Data - Instrumentation.MySqlData- - enable - - - - - - - - - - - - - - diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index e9bfb9a907..d7f45e09f8 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -8,6 +8,18 @@ This is an which instruments [MySql.Data](https://www.nuget.org/packages/MySql.Data) and collects telemetry about database operations. +## Deprecated + +> **NOTE that this only works with Mysql.Data v8.0.32 (and earlier, where supported)**. +> Mysql.Data v8.1.0 and later have built-in direct support for Open Telemetry +> via `ActivitySource`. + +To instrument Mysql.Data v8.1.0+ you need to configure the OpenTelemetry SDK +to listen to the `ActivitySource` used by the library by calling +`AddSource("connector-net")` on the `TracerProviderBuilder`. Alternatively, +you can add the nuget package [MySQL.Data.OpenTelemetry](https://www.nuget.org/packages/MySql.Data.OpenTelemetry) +and call extension method `AddConnectorNet()` on the `TracerProviderBuilder`. + ## Steps to enable OpenTelemetry.Instrumentation.MySqlData ### Step 1: Install Package diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs deleted file mode 100644 index ac4e5d2550..0000000000 --- a/src/OpenTelemetry.Instrumentation.MySqlData/TracerProviderBuilderExtensions.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using OpenTelemetry.Instrumentation.MySqlData; -using OpenTelemetry.Internal; - -namespace OpenTelemetry.Trace; - -/// -/// Extension methods to simplify registering of dependency instrumentation. -/// -public static class TracerProviderBuilderExtensions -{ - /// - /// Enables SqlClient instrumentation. - /// - /// being configured. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddMySqlDataInstrumentation(this TracerProviderBuilder builder) => - AddMySqlDataInstrumentation(builder, configure: null); - - /// - /// Enables SqlClient instrumentation. - /// - /// being configured. - /// SqlClient configuration options. - /// The instance of to chain the calls. - public static TracerProviderBuilder AddMySqlDataInstrumentation( - this TracerProviderBuilder builder, - Action? configure) - { - Guard.ThrowIfNull(builder); - - var sqlOptions = new MySqlDataInstrumentationOptions(); - configure?.Invoke(sqlOptions); - - builder.AddInstrumentation(() => new MySqlDataInstrumentation(sqlOptions)); - builder.AddSource(MySqlActivitySourceHelper.ActivitySourceName); - - return builder; - } -} diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs deleted file mode 100644 index c1330db29a..0000000000 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/MySqlDataTests.cs +++ /dev/null @@ -1,222 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Diagnostics; -using System.Linq; -using Moq; -using MySql.Data.MySqlClient; -using OpenTelemetry.Tests; -using OpenTelemetry.Trace; -using Xunit; - -namespace OpenTelemetry.Instrumentation.MySqlData.Tests; - -public class MySqlDataTests -{ - private const string ConnStr = "database=mysql;server=127.0.0.1;user id=root;password=123456;port=3306;pooling=False"; - - [Theory] - [InlineData("select 1/1", true, true, true, false)] - [InlineData("select 1/1", true, true, false, false)] - [InlineData("selext 1/1", true, true, true, true)] - public void SuccessTraceEventTest( - string commandText, - bool setDbStatement = false, - bool recordException = false, - bool enableConnectionLevelAttributes = false, - bool isFailure = false) - { - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddMySqlDataInstrumentation(options => - { - options.SetDbStatement = setDbStatement; - options.RecordException = recordException; - options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; - }) - .Build(); - - var traceListener = (TraceListener)Assert.Single(MySqlTrace.Listeners)!; - - ExecuteSuccessQuery(traceListener, commandText, isFailure); - - Assert.Equal(3, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - VerifyActivityData(commandText, setDbStatement, recordException, enableConnectionLevelAttributes, isFailure, activity); - } - - [Fact] - public void MySqlDataInstrumentationEventSource_test() - { - MySqlDataInstrumentationEventSource.Log.UnknownMySqlTraceEventType(15, "UnknownMySqlTraceEventType"); - MySqlDataInstrumentationEventSource.Log.ErrorTraceEvent(1, "ErrorTraceEvent", "ErrorTraceEvent exception"); - } - - [Theory] - [InlineData(MySqlTraceEventType.ConnectionClosed)] - [InlineData(MySqlTraceEventType.ResultOpened)] - [InlineData(MySqlTraceEventType.ResultClosed)] - [InlineData(MySqlTraceEventType.StatementPrepared)] - [InlineData(MySqlTraceEventType.StatementExecuted)] - [InlineData(MySqlTraceEventType.StatementClosed)] - [InlineData(MySqlTraceEventType.NonQuery)] - [InlineData(MySqlTraceEventType.UsageAdvisorWarning)] - [InlineData(MySqlTraceEventType.Warning)] - [InlineData(MySqlTraceEventType.QueryNormalized)] - [InlineData((MySqlTraceEventType)0)] - public void UnknownMySqlTraceEventType(MySqlTraceEventType eventType) - { - var activityProcessor = new Mock>(); - var sampler = new TestSampler(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) - .SetSampler(sampler) - .AddMySqlDataInstrumentation() - .Build(); - - var traceListener = (TraceListener?)Assert.Single(MySqlTrace.Listeners); - - traceListener?.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - (int)eventType, - "{0}: Connection Opened: connection string = '{1}'", - 1L, - ConnStr, - 10); - - Assert.Single(activityProcessor.Invocations); - } - - private static void VerifyActivityData( - string commandText, - bool setDbStatement, - bool recordException, - bool enableConnectionLevelAttributes, - bool isFailure, - Activity activity) - { - if (!isFailure) - { - Assert.Equal(Status.Unset, activity.GetStatus()); - } - else - { - var status = activity.GetStatus(); - Assert.Equal(Status.Error.StatusCode, status.StatusCode); - Assert.NotNull(status.Description); - - if (recordException) - { - var events = activity.Events.ToList(); - Assert.Single(events); - - Assert.Equal(SemanticConventions.AttributeExceptionEventName, events[0].Name); - } - else - { - Assert.Empty(activity.Events); - } - } - - Assert.Equal("mysql", activity.GetTagValue(SemanticConventions.AttributeDbName)); - - if (setDbStatement) - { - Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } - else - { - Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } - - var dataSource = new MySqlConnectionStringBuilder(ConnStr).Server; - - if (!enableConnectionLevelAttributes) - { - Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributePeerService)); - } - else - { - var uriHostNameType = Uri.CheckHostName(dataSource); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributeNetPeerIp)); - } - else - { - Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); - } - } - } - - private static void ExecuteSuccessQuery(TraceListener listener, string query, bool isFailure) - { - // Connection opened - listener.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - 1, - "{0}: Connection Opened: connection string = '{1}'", - 1L, - ConnStr, - 10); - - // Query opened - listener.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - 3, - "{0}: Query Opened: {2}", - 1L, - 9, - query); - - if (isFailure) - { - // Query error - listener.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - 13, - "{0}: Error encountered attempting to open result: Number={1}, Message={2}", - 1L, - 1064, - "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'selext 1/1' at line 1"); - } - else - { - // Query closed - listener.TraceEvent( - new TraceEventCache(), - "mysql", - TraceEventType.Information, - 6, - "{0}: Query Closed", - 1L); - } - } -} diff --git a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj b/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj deleted file mode 100644 index cc1be05fd1..0000000000 --- a/test/OpenTelemetry.Instrumentation.MySqlData.Tests/OpenTelemetry.Instrumentation.MySqlData.Tests.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - net7.0;net6.0 - true - enable - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - - - - From 9aec56accc393cf01291970e4c1c66f3909a927b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 22 Aug 2023 14:45:52 -0700 Subject: [PATCH 0789/1499] Add conditional compilation to make copying easier to otlp (#1320) --- .../PersistentBlob.cs | 4 ++++ .../PersistentBlobProvider.cs | 4 ++++ .../PersistentStorageAbstractionsEventSource.cs | 4 ++++ .../FileBlob.cs | 5 +++++ .../FileBlobProvider.cs | 9 +++++++++ .../PersistentStorageEventSource.cs | 4 ++++ 6 files changed, 30 insertions(+) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs index 7b01fff629..490eb94969 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs @@ -22,7 +22,11 @@ namespace OpenTelemetry.PersistentStorage.Abstractions; /// /// Represents a persistent blob. /// +#if BUILDING_INTERNAL_PERSISTENT_STORAGE +internal abstract class PersistentBlob +#else public abstract class PersistentBlob +#endif { /// /// Attempts to read the content from the blob. diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs index a6adcec637..ad21dba7de 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -24,7 +24,11 @@ namespace OpenTelemetry.PersistentStorage.Abstractions; /// /// Represents persistent blob provider. /// +#if BUILDING_INTERNAL_PERSISTENT_STORAGE +internal abstract class PersistentBlobProvider +#else public abstract class PersistentBlobProvider +#endif { /// /// Attempts to create a new blob with the provided data and lease it. diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs index 7c0d1d2861..ca43ef59cb 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -24,7 +24,11 @@ namespace OpenTelemetry.PersistentStorage.Abstractions; internal sealed class PersistentStorageAbstractionsEventSource : EventSource { public static PersistentStorageAbstractionsEventSource Log = new PersistentStorageAbstractionsEventSource(); +#if BUILDING_INTERNAL_PERSISTENT_STORAGE + private const string EventSourceName = "OpenTelemetry-PersistentStorage-Abstractions-Otlp"; +#else private const string EventSourceName = "OpenTelemetry-PersistentStorage-Abstractions"; +#endif [NonEvent] public void PersistentStorageAbstractionsException(string className, string message, Exception ex) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs index b3e2258afc..0ac49adede 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs @@ -26,7 +26,12 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; /// The allows to save a blob /// in file storage. /// + +#if BUILDING_INTERNAL_PERSISTENT_STORAGE +internal sealed class FileBlob : PersistentBlob +#else public class FileBlob : PersistentBlob +#endif { private readonly DirectorySizeTracker? directorySizeTracker; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index 2b6d053aad..e24ecc7a4b 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -29,7 +29,12 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; /// Persistent file storage allows to save data /// as blobs in file storage. /// + +#if BUILDING_INTERNAL_PERSISTENT_STORAGE +internal sealed class FileBlobProvider : PersistentBlobProvider, IDisposable +#else public class FileBlobProvider : PersistentBlobProvider, IDisposable +#endif { internal readonly string DirectoryPath; private readonly DirectorySizeTracker directorySizeTracker; @@ -110,7 +115,11 @@ public void Dispose() GC.SuppressFinalize(this); } +#if BUILDING_INTERNAL_PERSISTENT_STORAGE + private void Dispose(bool disposing) +#else protected virtual void Dispose(bool disposing) +#endif { if (!this.disposedValue) { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs index 8ba898fae6..791344a2d9 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs @@ -24,7 +24,11 @@ namespace OpenTelemetry.PersistentStorage.FileSystem; internal sealed class PersistentStorageEventSource : EventSource { public static PersistentStorageEventSource Log = new PersistentStorageEventSource(); +#if BUILDING_INTERNAL_PERSISTENT_STORAGE + private const string EventSourceName = "OpenTelemetry-PersistentStorage-FileSystem-Otlp"; +#else private const string EventSourceName = "OpenTelemetry-PersistentStorage-FileSystem"; +#endif [NonEvent] public void CouldNotReadFileBlob(string filePath, Exception ex) From 58607b7cdeb15207027a6fa4ca56e7fac897bda4 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 22 Aug 2023 16:00:03 -0700 Subject: [PATCH 0790/1499] [persistent storage] IsSpaceAvailable doc follow-up (#1319) --- .../DirectorySizeTracker.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs index 034b108bb1..222616cc01 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs @@ -40,6 +40,17 @@ public DirectorySizeTracker(long maxSizeInBytes, string path) public void FileRemoved(long fileSizeInBytes) => Interlocked.Add(ref this.directoryCurrentSizeInBytes, fileSizeInBytes * -1); + /// + /// Checks if the space is available for new blob. + /// + /// + /// This method is not thread safe and may give false positives/negatives. + /// False positive is ok because the file write will eventually fail. + /// False negative is ok as the file write can be retried if needed. + /// This is done in order to avoid acquiring lock while writing/deleting the blobs. + /// + /// Size of blob to be written. + /// True if space is available else false. public bool IsSpaceAvailable(out long currentSizeInBytes) { currentSizeInBytes = Interlocked.Read(ref this.directoryCurrentSizeInBytes); From fc4dc0db018d3b8df8977daf880eff57290d37f9 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 24 Aug 2023 15:10:39 -0700 Subject: [PATCH 0791/1499] [OneCollectorExporter] Failed transmission callback (#1309) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 + .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../netstandard2.1/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 4 + .../Transports/HttpJsonPostTransport.cs | 70 ++++++++++++++-- .../Internal/Transports/ITransport.cs | 4 +- .../OneCollectorExporter.cs | 29 ++++++- ...rterPayloadTransmittedCallbackArguments.cs | 26 +++++- .../HttpJsonPostTransportTests.cs | 80 +++++++++++++++++-- .../WriteDirectlyToTransportSinkTests.cs | 2 +- 12 files changed, 206 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index e69de29bb2..ebfc0b119f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index e69de29bb2..73417f39e7 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index e69de29bb2..ebfc0b119f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..ebfc0b119f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index e69de29bb2..ebfc0b119f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 16336d48da..a1852a68e2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added support for receiving tranmission failures via the + `RegisterPayloadTransmittedCallback` API. + ([#1309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1309)) + ## 1.5.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index a65af89c19..1e3698f6b1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -27,7 +27,8 @@ internal sealed class HttpJsonPostTransport : ITransport, IDisposable private static readonly string SdkVersion = $"OTel-{Environment.OSVersion.Platform}-.net-{typeof(OneCollectorExporter<>).Assembly.GetName()?.Version?.ToString() ?? "0.0.0"}"; private static readonly string UserAgent = $".NET/{Environment.Version} HttpClient"; - private readonly CallbackManager payloadTransmittedCallbacks = new(); + private readonly CallbackManager payloadTransmittedSuccessCallbacks = new(); + private readonly CallbackManager payloadTransmittedFailureCallbacks = new(); private readonly Uri endpoint; private readonly string instrumentationKey; private readonly OneCollectorExporterHttpTransportCompressionType compressionType; @@ -56,15 +57,25 @@ public HttpJsonPostTransport( public void Dispose() { - this.payloadTransmittedCallbacks.Dispose(); + this.payloadTransmittedSuccessCallbacks.Dispose(); + this.payloadTransmittedFailureCallbacks.Dispose(); this.buffer?.Dispose(); } - public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback) + public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback, bool includeFailures) { Guard.ThrowIfNull(callback); - return this.payloadTransmittedCallbacks.Add(callback); + var successRegistration = this.payloadTransmittedSuccessCallbacks.Add(callback); + + if (!includeFailures) + { + return successRegistration; + } + + var failureRegistration = this.payloadTransmittedFailureCallbacks.Add(callback); + + return new TranmissionCallbackWrapper(successRegistration, failureRegistration); } public bool Send(in TransportSendRequest sendRequest) @@ -112,13 +123,14 @@ public bool Send(in TransportSendRequest sendRequest) OneCollectorExporterEventSource.Log.WriteTransportDataSentEventIfEnabled(sendRequest.ItemType, sendRequest.NumberOfItems, this.Description); - var root = this.payloadTransmittedCallbacks.Root; + var root = this.payloadTransmittedSuccessCallbacks.Root; if (root != null) { this.InvokePayloadTransmittedCallbacks( root, streamStartingPosition, - in sendRequest); + in sendRequest, + succeeded: true); } return true; @@ -135,6 +147,16 @@ public bool Send(in TransportSendRequest sendRequest) collectorErrors, errorDetails); + var root = this.payloadTransmittedFailureCallbacks.Root; + if (root != null) + { + this.InvokePayloadTransmittedCallbacks( + root, + streamStartingPosition, + in sendRequest, + succeeded: false); + } + return false; } } @@ -142,6 +164,16 @@ public bool Send(in TransportSendRequest sendRequest) { OneCollectorExporterEventSource.Log.WriteTransportExceptionThrownEventIfEnabled(this.Description, ex); + var root = this.payloadTransmittedFailureCallbacks.Root; + if (root != null) + { + this.InvokePayloadTransmittedCallbacks( + root, + streamStartingPosition, + in sendRequest, + succeeded: false); + } + return false; } } @@ -185,7 +217,8 @@ private HttpContent BuildRequestContent(Stream stream) private void InvokePayloadTransmittedCallbacks( OneCollectorExporterPayloadTransmittedCallbackAction callback, long streamStartingPosition, - in TransportSendRequest sendRequest) + in TransportSendRequest sendRequest, + bool succeeded) { var stream = sendRequest.ItemStream; @@ -200,7 +233,8 @@ private void InvokePayloadTransmittedCallbacks( sendRequest.ItemSerializationFormat, stream, OneCollectorExporterTransportProtocolType.HttpJsonPost, - this.endpoint)); + this.endpoint, + succeeded)); } catch (Exception ex) { @@ -212,6 +246,26 @@ private void InvokePayloadTransmittedCallbacks( } } + private sealed class TranmissionCallbackWrapper : IDisposable + { + private readonly IDisposable successRegistration; + private readonly IDisposable failureRegistration; + + public TranmissionCallbackWrapper( + IDisposable successRegistration, + IDisposable failureRegistration) + { + this.successRegistration = successRegistration; + this.failureRegistration = failureRegistration; + } + + public void Dispose() + { + this.successRegistration.Dispose(); + this.failureRegistration.Dispose(); + } + } + private sealed class NonDisposingStreamContent : HttpContent { #pragma warning disable CA2213 // Disposable fields should be disposed diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs index 4abed07d5b..9637100c80 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs @@ -22,5 +22,7 @@ internal interface ITransport bool Send(in TransportSendRequest sendRequest); - IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback); + IDisposable RegisterPayloadTransmittedCallback( + OneCollectorExporterPayloadTransmittedCallbackAction callback, + bool includeFailures); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs index b9c1fff210..336146a27e 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs @@ -66,8 +66,15 @@ public sealed override ExportResult Export(in Batch batch) /// /// Register a callback action that will be triggered any time a payload is - /// transmitted by the exporter. + /// successfully transmitted by the exporter. /// + /// + /// Success or failure of a transmission depends on the transport being + /// used. In the case of HTTP transport, success is driven by the HTTP + /// response status code (anything in the 200-range indicates success) and + /// any other result (connection failure, timeout, non-200 response code, + /// etc.) is considered a failure. + /// /// . /// if no transport is tied to the exporter @@ -75,7 +82,25 @@ public sealed override ExportResult Export(in Batch batch) /// Call on the returned instance to /// cancel the registration. public IDisposable? RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback) - => this.sink.Transport?.RegisterPayloadTransmittedCallback(callback); + => this.RegisterPayloadTransmittedCallback(callback, includeFailures: false); + + /// + /// Register a callback action that will be triggered any time a payload is + /// transmitted by the exporter. + /// + /// + /// . + /// Specify to receive + /// callbacks when transmission fails. See + /// for details about how a success or failure is determined. + /// if no transport is tied to the exporter + /// or an representing the registered callback. + /// Call on the returned instance to + /// cancel the registration. + public IDisposable? RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback, bool includeFailures) + => this.sink.Transport?.RegisterPayloadTransmittedCallback(callback, includeFailures); /// protected override void Dispose(bool disposing) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs index 2f720c4c5e..9f663f5790 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs @@ -39,7 +39,8 @@ internal OneCollectorExporterPayloadTransmittedCallbackArguments( OneCollectorExporterSerializationFormatType payloadSerializationFormat, Stream payloadStream, OneCollectorExporterTransportProtocolType transportProtocol, - Uri transportEndpoint) + Uri transportEndpoint, + bool succeeded) { Debug.Assert(payloadStream != null, "payload stream was null"); Debug.Assert(payloadStream!.CanSeek, "payload stream was not seekable"); @@ -49,6 +50,7 @@ internal OneCollectorExporterPayloadTransmittedCallbackArguments( this.payloadStream = payloadStream; this.TransportProtocol = transportProtocol; this.TransportEndpoint = transportEndpoint!; + this.Succeeded = succeeded; } /// @@ -61,6 +63,28 @@ internal OneCollectorExporterPayloadTransmittedCallbackArguments( /// public Uri TransportEndpoint { get; } + /// + /// Gets a value indicating whether or not the payload transmission was successful. + /// + /// + /// Notes: + /// + /// + /// A value indicates a request was fully transmitted + /// and acknowledged. + /// + /// + /// A value indicates a request did NOT fully + /// transmit or an acknowledgement was NOT received. Data may have been + /// partially or fully transmitted in this case. + /// + /// + /// + /// + /// + /// + public bool Succeeded { get; } + /// /// Gets the payload serialization format. /// diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index c48fb38cc5..736ef9a848 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -102,6 +102,8 @@ public void RegisterPayloadTransmittedCallbackTest() * 1) Exisiting callback fires again and is verified. Then we remove the callback. * 2) Verifies callback is NOT attached and NOT fired. * 3) Callback is attached again and verified to fire. Then we remove the callback. + * 4) Tests the callback on a failed message with includeFailures: false. + * 5) Tests the callback on a failed message with includeFailures: true. */ RunHttpServerTest( @@ -122,6 +124,7 @@ public void RegisterPayloadTransmittedCallbackTest() Assert.True(string.IsNullOrWhiteSpace(req.Headers["Content-Encoding"])); Assert.Equal(request, Encoding.ASCII.GetString(body.ToArray())); }, + shouldTestFailFunc: (iteration) => iteration == 4 || iteration == 5, testStartingAction: (iteration, transport) => { switch (iteration) @@ -129,7 +132,7 @@ public void RegisterPayloadTransmittedCallbackTest() case 0: case 3: Assert.Null(callbackRegistration); - callbackRegistration = transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted); + callbackRegistration = transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted, includeFailures: false); break; case 1: Assert.NotNull(callbackRegistration); @@ -137,6 +140,14 @@ public void RegisterPayloadTransmittedCallbackTest() case 2: Assert.Null(callbackRegistration); break; + case 4: + Assert.Null(callbackRegistration); + callbackRegistration = transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted, includeFailures: false); + break; + case 5: + Assert.Null(callbackRegistration); + callbackRegistration = transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted, includeFailures: true); + break; } }, testFinishedAction: (iteration, transport) => @@ -149,8 +160,18 @@ public void RegisterPayloadTransmittedCallbackTest() break; case 1: case 3: + case 4: + case 5: Assert.NotNull(callbackRegistration); - Assert.True(callbackFired); + if (iteration == 4) + { + Assert.False(callbackFired); + } + else + { + Assert.True(callbackFired); + } + callbackRegistration.Dispose(); callbackRegistration = null; break; @@ -163,9 +184,9 @@ public void RegisterPayloadTransmittedCallbackTest() callbackFired = false; lastCompletedIteration = iteration; }, - testIterations: 4); + testIterations: 6); - Assert.Equal(3, lastCompletedIteration); + Assert.Equal(5, lastCompletedIteration); void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallbackArguments arguments) { @@ -178,6 +199,48 @@ void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallbackArgum Assert.Equal(OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream, arguments.PayloadSerializationFormat); Assert.Equal(OneCollectorExporterTransportProtocolType.HttpJsonPost, arguments.TransportProtocol); Assert.NotNull(arguments.TransportEndpoint); + if (lastCompletedIteration == 4) + { + Assert.False(arguments.Succeeded); + } + else + { + Assert.True(arguments.Succeeded); + } + } + } + + [Fact] + public void RegisterPayloadTransmittedCallbackConnectionFailureTest() + { + using var httpClient = new HttpClient(); + + using var transport = new HttpJsonPostTransport( + "instrumentation-key", + new("http://localhost:0"), + OneCollectorExporterHttpTransportCompressionType.Deflate, + new HttpClientWrapper(httpClient)); + + transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted, includeFailures: true); + + bool callbackFired = false; + + var result = transport.Send( + new TransportSendRequest + { + ItemStream = new MemoryStream(Encoding.ASCII.GetBytes("{\"key1\":\"value1\"}")), + ItemSerializationFormat = OneCollectorExporterSerializationFormatType.CommonSchemaV4JsonStream, + ItemType = "TestRequest", + NumberOfItems = 1, + }); + + Assert.False(result); + + Assert.True(callbackFired); + + void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallbackArguments arguments) + { + callbackFired = true; } } @@ -197,16 +260,19 @@ private static void RunHttpServerTest( Action assertRequestAction, int numberOfItemsInRequestBody = 1, int testIterations = 1, + Func? shouldTestFailFunc = null, Action? testStartingAction = null, Action? testFinishedAction = null) { + shouldTestFailFunc ??= static iteration => false; + bool failTest = false; bool requestReceivedAndAsserted = false; Exception? testException = null; using var testServer = TestHttpServer.RunServer( context => { - context.Response.StatusCode = 200; + context.Response.StatusCode = failTest ? 400 : 200; using MemoryStream requestBody = new MemoryStream(); @@ -241,6 +307,8 @@ private static void RunHttpServerTest( for (int i = 0; i < testIterations; i++) { + failTest = shouldTestFailFunc(i); + testStartingAction?.Invoke(i, transport); using var requestBodyStream = new MemoryStream(requestBodyBytes); @@ -259,7 +327,7 @@ private static void RunHttpServerTest( throw testException; } - Assert.True(result); + Assert.NotEqual(failTest, result); Assert.True(requestReceivedAndAsserted); testFinishedAction?.Invoke(i, transport); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs index d519fcf658..44f983d04d 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -165,7 +165,7 @@ private sealed class TestTransport : ITransport public List ExportedData { get; } = new(); - public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback) + public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback, bool includeFailures) { throw new NotImplementedException(); } From 94f154222f3ee89fb2ebd3b7a3f4ef2b03272937 Mon Sep 17 00:00:00 2001 From: Krzysztof Porebski Date: Fri, 25 Aug 2023 10:06:03 +0200 Subject: [PATCH 0792/1499] OpenTelemetry.Exporter.InfluxDB nullable support (#1314) --- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 11 ++++++----- .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 11 ++++++----- src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs | 2 +- .../InfluxDBExporterExtensions.cs | 2 +- .../InfluxDBMetricsExporterOptions.cs | 8 ++++---- .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 + .../PointDataExtensions.cs | 2 +- .../TelegrafPrometheusWriterV1.cs | 2 +- .../TelegrafPrometheusWriterV2.cs | 2 +- 11 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt index 7f0ab9edcf..458d0ea807 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,20 +1,21 @@ +#nullable enable OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.set -> void OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.MetricsSchema.None = 0 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV1 = 1 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV2 = 2 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Metrics.InfluxDBExporterExtensions -static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file +static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 7f0ab9edcf..b54682ec56 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,20 +1,21 @@ +#nullable enable OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string? OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.set -> void OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.MetricsSchema.None = 0 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV1 = 1 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV2 = 2 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Metrics.InfluxDBExporterExtensions -static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder \ No newline at end of file +static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs index ade42aee09..31ed4f0393 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs @@ -22,5 +22,5 @@ namespace OpenTelemetry.Exporter.InfluxDB; internal interface IMetricsWriter { - void Write(Metric metric, Resource resource, WriteApi writeApi); + void Write(Metric metric, Resource? resource, WriteApi writeApi); } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs index 653df5ec48..3bf2ecaaff 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs @@ -39,7 +39,7 @@ public static MeterProviderBuilder AddInfluxDBMetricsExporter(this MeterProvider var options = new InfluxDBMetricsExporterOptions(); configure.Invoke(options); - var influxDbClientOptions = new InfluxDBClientOptions(options.Endpoint.ToString()); + var influxDbClientOptions = new InfluxDBClientOptions(options.Endpoint?.ToString()); if (!string.IsNullOrWhiteSpace(options.Bucket)) { influxDbClientOptions.Bucket = options.Bucket; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs index f0bf2e3011..c7408cf705 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs @@ -26,22 +26,22 @@ public class InfluxDBMetricsExporterOptions /// /// Gets or sets HTTP/S destination for line protocol. /// - public Uri Endpoint { get; set; } + public Uri? Endpoint { get; set; } /// /// Gets or sets name of InfluxDB organization that owns the destination bucket. /// - public string Org { get; set; } + public string? Org { get; set; } /// /// Gets or sets the name of InfluxDB bucket to which signals will be written. /// - public string Bucket { get; set; } + public string? Bucket { get; set; } /// /// Gets or sets the authentication token for InfluxDB. /// - public string Token { get; set; } + public string? Token { get; set; } /// /// Gets or sets the chosen metrics schema to write. diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index 8a3103c39c..c7929025cb 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -9,6 +9,7 @@ Exporter.InfluxDB- true true + enable diff --git a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs index e139873afd..d407910f5c 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs @@ -31,7 +31,7 @@ public static PointData Tags(this PointData pointData, ReadOnlyTagCollection tag return pointData; } - public static PointData Tags(this PointData pointData, IEnumerable> tags) + public static PointData Tags(this PointData pointData, IEnumerable>? tags) { if (tags == null) { diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs index 42fd45900a..b72e08910d 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Exporter.InfluxDB; internal sealed class TelegrafPrometheusWriterV1 : IMetricsWriter { - public void Write(Metric metric, Resource resource, WriteApi writeApi) + public void Write(Metric metric, Resource? resource, WriteApi writeApi) { var measurement = metric.Name; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs index b57760ef30..4c9221acd8 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Exporter.InfluxDB; internal sealed class TelegrafPrometheusWriterV2 : IMetricsWriter { - public void Write(Metric metric, Resource resource, WriteApi writeApi) + public void Write(Metric metric, Resource? resource, WriteApi writeApi) { var measurement = "prometheus"; var metricName = metric.Name; From e0ea358b5e81e1602afdcd436fb953c5a7af9af0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 25 Aug 2023 09:59:30 -0700 Subject: [PATCH 0793/1499] [OneCollectorExporter] Add LogRecord.Body support (#1321) --- .../CHANGELOG.md | 9 +++++ .../LogRecordCommonSchemaJsonSerializer.cs | 33 +++++++++++++++---- ...ogRecordCommonSchemaJsonSerializerTests.cs | 18 ++++++++-- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index a1852a68e2..cad40dcf22 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -6,6 +6,15 @@ `RegisterPayloadTransmittedCallback` API. ([#1309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1309)) +* Added support for sending `LogRecord.Body` as common schema `body` if + `{OriginalFormat}` key is not found. + ([#1321](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1321)) + +* Added support for sending `LogRecord.FormattedMessage` (if set) as common + schema `formattedMessage` if it differs from the detected template (either + `{OriginalFormat}` key or `LogRecord.Body`). + ([#1321](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1321)) + ## 1.5.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 9ca6abf692..7c4f80351d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -28,6 +28,7 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText SeverityTextProperty = JsonEncodedText.Encode("severityText"); private static readonly JsonEncodedText SeverityNumberProperty = JsonEncodedText.Encode("severityNumber"); private static readonly JsonEncodedText BodyProperty = JsonEncodedText.Encode("body"); + private static readonly JsonEncodedText FormattedMessageProperty = JsonEncodedText.Encode("formattedMessage"); private static readonly JsonEncodedText DistributedTraceExtensionProperty = JsonEncodedText.Encode("dt"); private static readonly JsonEncodedText DistributedTraceExtensionTraceIdProperty = JsonEncodedText.Encode("traceId"); private static readonly JsonEncodedText DistributedTraceExtensionSpanIdProperty = JsonEncodedText.Encode("spanId"); @@ -131,7 +132,7 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C writer.WriteString(SeverityTextProperty, LogLevelToSeverityTextMappings[logLevel]); writer.WriteNumber(SeverityNumberProperty, LogLevelToSeverityNumberMappings[logLevel]); - string? body = null; + string? originalFormat = null; if (item.Attributes != null) { @@ -146,7 +147,7 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C if (attribute.Key == "{OriginalFormat}") { - body = attribute.Value as string; + originalFormat = attribute.Value as string; continue; } @@ -160,13 +161,29 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C } } - if (!string.IsNullOrEmpty(body)) + var hasBody = false; + + if (!string.IsNullOrEmpty(originalFormat)) + { + writer.WriteString(BodyProperty, originalFormat); + hasBody = true; + } + else if (!string.IsNullOrEmpty(item.Body)) { - writer.WriteString(BodyProperty, body); + writer.WriteString(BodyProperty, item.Body); + hasBody = true; } else if (!string.IsNullOrEmpty(item.FormattedMessage)) { writer.WriteString(BodyProperty, item.FormattedMessage); + writer.WriteString(FormattedMessageProperty, item.FormattedMessage); + } + + if (hasBody + && !string.IsNullOrEmpty(item.FormattedMessage) + && item.Body != item.FormattedMessage) + { + writer.WriteString(FormattedMessageProperty, item.FormattedMessage); } SerializeResourceToJsonInsideCurrentObject(resource, serializationState); @@ -184,8 +201,9 @@ private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter w { var hasTraceContext = item.TraceId != default; var hasException = item.Exception != null; + var hasExtensions = serializationState.ExtensionAttributeCount > 0; - if (!hasTraceContext && !hasException && serializationState.ExtensionAttributeCount <= 0) + if (!hasTraceContext && !hasException && !hasExtensions) { return; } @@ -215,7 +233,10 @@ private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter w writer.WriteEndObject(); } - serializationState.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: false); + if (hasExtensions) + { + serializationState.SerializeExtensionPropertiesToJson(writeExtensionObjectEnvelope: false); + } writer.WriteEndObject(); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 80a1894ada..cabe61439a 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -119,7 +119,21 @@ public void LogRecordOriginalFormatBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\"}}}}\n", + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\",\"formattedMessage\":\"goodbye world\"}}}}\n", + json); + } + + [Fact] + public void LogRecordBodyJsonTest() + { + string json = GetLogRecordJson(1, (index, logRecord) => + { + logRecord.Body = "hello world"; + logRecord.FormattedMessage = "goodbye world"; + }); + + Assert.Equal( + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\",\"formattedMessage\":\"goodbye world\"}}}}\n", json); } @@ -132,7 +146,7 @@ public void LogRecordFormattedMessageBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"goodbye world\"}}}}\n", + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"goodbye world\",\"formattedMessage\":\"goodbye world\"}}}}\n", json); } From 34b632309949baa768241198e830657282d0ca7a Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 25 Aug 2023 15:11:17 -0500 Subject: [PATCH 0794/1499] Add EventCounters to AotCompatibility.Test (#1322) --- .github/workflows/ci-aot.yml | 4 ++++ .../OpenTelemetry.AotCompatibility.TestApp.csproj | 1 + 2 files changed, 5 insertions(+) diff --git a/.github/workflows/ci-aot.yml b/.github/workflows/ci-aot.yml index f1a2aabdcc..00c208ab69 100644 --- a/.github/workflows/ci-aot.yml +++ b/.github/workflows/ci-aot.yml @@ -6,11 +6,15 @@ on: paths: - 'src/OpenTelemetry.Instrumentation.Runtime/**' - '!src/OpenTelemetry.Instrumentation.Runtime/README.md' + - 'src/OpenTelemetry.Instrumentation.EventCounters/**' + - '!src/OpenTelemetry.Instrumentation.EventCounters/README.md' pull_request: branches: [ 'main*' ] paths: - 'src/OpenTelemetry.Instrumentation.Runtime/**' - '!src/OpenTelemetry.Instrumentation.Runtime/README.md' + - 'src/OpenTelemetry.Instrumentation.EventCounters/**' + - '!src/OpenTelemetry.Instrumentation.EventCounters/README.md' jobs: aot-test: diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 5371c43f24..58b7242edb 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -10,6 +10,7 @@ + From e085dc25e72902352d05f37fa8e0545cdc646037 Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Fri, 25 Aug 2023 15:20:32 -0600 Subject: [PATCH 0795/1499] Increase reliability of WCF HTTP tests (#1326) --- .../TelemetryBindingElementForHttpTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs index ffaf94d687..d85a9b42ea 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs @@ -254,8 +254,8 @@ await client.ExecuteAsync( else { Assert.Equal(2, stoppedActivities.Count); - Assert.Equal("DownstreamInstrumentation", stoppedActivities[0].OperationName); - Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); + Assert.NotNull(stoppedActivities.SingleOrDefault(activity => activity.OperationName == "DownstreamInstrumentation")); + Assert.NotNull(stoppedActivities.SingleOrDefault(activity => activity.OperationName == WcfInstrumentationActivitySource.OutgoingRequestActivityName)); } } else From ed3615b85c2e0024df287133811ce6fb3ff335cb Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 25 Aug 2023 16:54:48 -0700 Subject: [PATCH 0796/1499] [Exporter.Geneva] Add build time constant for experimental features (#1328) --- .../Common.GenevaExporter.props | 9 ++++++ .../Metrics/GenevaMetricExporter.cs | 24 +++++++++++++++ .../OpenTelemetry.Exporter.Geneva.csproj | 3 +- .../Exporter/MetricExporterBenchmarks.cs | 8 +++++ ...Telemetry.Exporter.Geneva.Benchmark.csproj | 1 + .../GenevaMetricExporterTests.cs | 30 +++++++++++++++++++ ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 + 7 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props new file mode 100644 index 0000000000..78181066e1 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -0,0 +1,9 @@ + + + $(OpenTelemetryCoreLatestPrereleaseVersion) + + + + $(DefineConstants);EXPOSE_EXPERIMENTAL_FEATURES + + diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 6cf233a685..0b26fe0615 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -122,7 +122,9 @@ public override ExportResult Export(in Batch batch) { try { +#if EXPOSE_EXPERIMENTAL_FEATURES var exemplars = metricPoint.GetExemplars(); +#endif switch (metric.MetricType) { @@ -136,7 +138,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -156,7 +160,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -176,7 +182,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -194,7 +202,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -211,7 +221,9 @@ public override ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -237,7 +249,9 @@ public override ExportResult Export(in Batch batch) count, min, max, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -301,7 +315,9 @@ internal unsafe ushort SerializeMetricWithTLV( long timestamp, in ReadOnlyTagCollection tags, MetricData value, +#if EXPOSE_EXPERIMENTAL_FEATURES Exemplar[] exemplars, +#endif out string monitoringAccount, out string metricNamespace) { @@ -328,7 +344,9 @@ internal unsafe ushort SerializeMetricWithTLV( out monitoringAccount, out metricNamespace); +#if EXPOSE_EXPERIMENTAL_FEATURES SerializeExemplars(exemplars, this.buffer, ref bufferIndex); +#endif SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -361,7 +379,9 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( uint count, double min, double max, +#if EXPOSE_EXPERIMENTAL_FEATURES Exemplar[] exemplars, +#endif out string monitoringAccount, out string metricNamespace) { @@ -388,7 +408,9 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( out monitoringAccount, out metricNamespace); +#if EXPOSE_EXPERIMENTAL_FEATURES SerializeExemplars(exemplars, this.buffer, ref bufferIndex); +#endif SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -433,6 +455,7 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); } +#if EXPOSE_EXPERIMENTAL_FEATURES [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) { @@ -548,6 +571,7 @@ private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, re var exemplarLength = bufferIndex - bufferIndexForLength + 1; MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); } +#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 93599774e7..cc864470ac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -1,4 +1,5 @@ + true @@ -14,7 +15,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 976ae3d584..0cc988cb85 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -566,7 +566,9 @@ public void SerializeCounterMetricItemWith3Dimensions() this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, +#if EXPOSE_EXPERIMENTAL_FEATURES Array.Empty(), +#endif out _, out _); } @@ -580,7 +582,9 @@ public void SerializeCounterMetricItemWith4Dimensions() this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, +#if EXPOSE_EXPERIMENTAL_FEATURES Array.Empty(), +#endif out _, out _); } @@ -609,7 +613,9 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramCountWith3Dimensions, this.histogramMinWith3Dimensions, this.histogramMaxWith3Dimensions, +#if EXPOSE_EXPERIMENTAL_FEATURES Array.Empty(), +#endif out _, out _); } @@ -626,7 +632,9 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramCountWith4Dimensions, this.histogramMinWith4Dimensions, this.histogramMaxWith4Dimensions, +#if EXPOSE_EXPERIMENTAL_FEATURES Array.Empty(), +#endif out _, out _); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index fd73af1422..2491b9ddf9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -1,4 +1,5 @@ + Exe diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index cb67c04142..74675312fb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -196,14 +196,18 @@ public void SuccessfulExportOnLinux() var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; +#if EXPOSE_EXPERIMENTAL_FEATURES var exemplars = metricPoint.GetExemplars(); +#endif var bodyLength = exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -950,7 +954,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; +#if EXPOSE_EXPERIMENTAL_FEATURES var exemplars = metricPoint.GetExemplars(); +#endif List fields = null; @@ -965,7 +971,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -991,7 +999,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1019,7 +1029,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1047,7 +1059,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1082,7 +1096,9 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, count, min, max, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1121,6 +1137,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(bodyLength, data.LenBody); } +#if EXPOSE_EXPERIMENTAL_FEATURES if (exemplars.Length > 0) { var validExemplars = exemplars.Where(exemplar => exemplar.Timestamp != default).ToList(); @@ -1142,6 +1159,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, AssertExemplarFilteredTagSerialization(expectedExemplar, serializedExemplar); } } +#endif // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); @@ -1214,6 +1232,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(dimensionsCount, dimensions.NumDimensions); } +#if EXPOSE_EXPERIMENTAL_FEATURES private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExemplar, SingleExemplar serializedExemplar) { var serializedExemplarBody = serializedExemplar.Body; @@ -1263,6 +1282,7 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem } } } +#endif private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter exporter) { @@ -1284,7 +1304,9 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1303,7 +1325,9 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1324,7 +1348,9 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1345,7 +1371,9 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); @@ -1373,7 +1401,9 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter count, min, max, +#if EXPOSE_EXPERIMENTAL_FEATURES exemplars, +#endif out _, out _); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 71e8440a75..fb3bd9656a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -1,4 +1,5 @@ + Unit test project for Geneva Exporters for OpenTelemetry From 6bace87f3bcd73f84b27be779c73ab9128da0c2b Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 25 Aug 2023 19:56:44 -0700 Subject: [PATCH 0797/1499] [Exporter.Geneva] Update OTel SDK version to 1.6.0-rc.1 (#1329) --- build/Common.props | 2 +- opentelemetry-dotnet-contrib.sln | 7 ++++--- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build/Common.props b/build/Common.props index 641130c4cb..0ad217d7e2 100644 --- a/build/Common.props +++ b/build/Common.props @@ -36,7 +36,7 @@ [3.3.3] [1.1.1,2.0) [1.5.1,2.0) - [1.6.0-alpha.1] + [1.6.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 23bc86e68e..bb629ad26a 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -25,9 +25,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml + .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml .github\workflows\ci.yml = .github\workflows\ci.yml - .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml @@ -77,9 +77,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset + build\process-codecoverage.ps1 = build\process-codecoverage.ps1 build\sanitycheck.py = build\sanitycheck.py build\stylecop.json = build\stylecop.json - build\test-aot-compatibility = build\test-aot-compatibility.ps1 + build\test-aot-compatibility.ps1 = build\test-aot-compatibility.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0112BD4F-B7A6-4E43-AB23-B6E961E27A49}" @@ -288,7 +289,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "InfluxDB", "InfluxDB", "{2D EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.InfluxDB", "examples\InfluxDB\Examples.InfluxDB\Examples.InfluxDB.csproj", "{B4951583-D432-4E87-85CF-498FDD6A35E6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.AotCompatibility.TestApp", "test\OpenTelemetry.AotCompatibility.TestApp\OpenTelemetry.AotCompatibility.TestApp.csproj", "{31937862-0C88-41C0-AFD6-F97A7BF803A9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.AotCompatibility.TestApp", "test\OpenTelemetry.AotCompatibility.TestApp\OpenTelemetry.AotCompatibility.TestApp.csproj", "{31937862-0C88-41C0-AFD6-F97A7BF803A9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 7809971cac..2e2f6807d1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.6.0-rc.1`. + ([#1329](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1329)) + ## 1.6.0-alpha.1 Released 2023-Jul-12 From 0007108b6ebe8431596a496f5b0460efbd7bc1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 28 Aug 2023 13:18:19 +0200 Subject: [PATCH 0798/1499] [Instrumentation.Quartz] Nullable (#1316) --- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 12 ++--- .../QuartzDiagnosticListener.cs | 12 +++-- ...penTelemetry.Instrumentation.Quartz.csproj | 1 + .../QuartzInstrumentationOptions.cs | 2 +- .../TraceProviderBuilderExtensions.cs | 2 +- ...emetry.Instrumentation.Quartz.Tests.csproj | 45 ++++++++++--------- 7 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 39e5f8f8b3..687857d91e 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,15 +1,15 @@ -const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Execute = "Quartz.Job.Execute" -> string -const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Veto = "Quartz.Job.Veto" -> string +const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Execute = "Quartz.Job.Execute" -> string! +const OpenTelemetry.Instrumentation.Quartz.OperationName.Job.Veto = "Quartz.Job.Veto" -> string! OpenTelemetry.Instrumentation.Quartz.OperationName OpenTelemetry.Instrumentation.Quartz.OperationName.Job OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.QuartzInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet +OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.get -> System.Collections.Generic.HashSet! OpenTelemetry.Instrumentation.Quartz.QuartzInstrumentationOptions.TracedOperations.set -> void OpenTelemetry.Trace.TraceProviderBuilderExtensions -static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TraceProviderBuilderExtensions.AddQuartzInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 6e38ee2f7f..896c246e45 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -61,7 +61,10 @@ public override void OnStartActivity(Activity activity, object payload) try { this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); - this.options.Enrich?.Invoke(activity, "OnStartActivity", jobDetails); + if (jobDetails != null) + { + this.options.Enrich?.Invoke(activity, "OnStartActivity", jobDetails); + } } catch (Exception ex) { @@ -77,7 +80,10 @@ public override void OnStopActivity(Activity activity, object payload) try { this.JobDetailsPropertyFetcher.TryFetch(payload, out var jobDetails); - this.options.Enrich?.Invoke(activity, "OnStopActivity", jobDetails); + if (jobDetails != null) + { + this.options.Enrich?.Invoke(activity, "OnStopActivity", jobDetails); + } } catch (Exception ex) { @@ -135,7 +141,7 @@ private static ActivityKind GetActivityKind(Activity activity) }; } - private static string GetTag(IEnumerable> tags, string tagName) + private static string? GetTag(IEnumerable> tags, string tagName) { var tag = tags.SingleOrDefault(kv => kv.Key == tagName); return tag.Value; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index c794f15c85..9681602645 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -6,6 +6,7 @@ true netstandard2.0 true + enable diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index 4e726f3f72..59d5341d40 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -43,7 +43,7 @@ public class QuartzInstrumentationOptions /// object: the raw object from which additional information can be extracted to enrich the activity. /// The type of this object depends on the event, which is given by the above parameter. /// - public Action Enrich { get; set; } + public Action? Enrich { get; set; } /// /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index 9461dcc585..07001935a9 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -43,7 +43,7 @@ public static TracerProviderBuilder AddQuartzInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddQuartzInstrumentation( this TracerProviderBuilder builder, - Action configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index a722caeee5..98c388681c 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -1,27 +1,28 @@ - - Unit test project for OpenTelemetry Quartz.NET instrumentation - net7.0;net6.0 - $(TargetFrameworks);net472 - true - + + Unit test project for OpenTelemetry Quartz.NET instrumentation + net7.0;net6.0 + $(TargetFrameworks);net472 + true + enable + - - - - - - - - - all - runtime; build; native; contentfiles; analyzers - - - + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + - - - + + + From 4a54aad260ffbe4ef46ac80c0e40a753eb792c9d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 28 Aug 2023 14:20:48 -0700 Subject: [PATCH 0799/1499] [Exporter.Geneva] Update CHANGELOG for 1.6.0-rc.1 release (#1332) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 2e2f6807d1..decb1da578 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-rc.1 + +Released 2023-Aug-28 + * Update OpenTelemetry SDK version to `1.6.0-rc.1`. ([#1329](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1329)) From c043884e2a163f8ee133e5b5c87ff4b7f630f00c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 28 Aug 2023 17:42:31 -0700 Subject: [PATCH 0800/1499] [PersistentStorage.Abstractions] and [PersistentStorage.FileSystem] Prepare 1.0.0 release (#1323) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 20 +++++++++++++++++++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 20 ------------------- .../netstandard2.0/PublicAPI.Shipped.txt | 20 +++++++++++++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 20 ------------------- .../CHANGELOG.md | 4 +++- .../README.md | 6 ------ .../.publicApi/net462/PublicAPI.Shipped.txt | 16 +++++++++++++++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 15 -------------- .../netstandard2.0/PublicAPI.Shipped.txt | 15 ++++++++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 15 -------------- .../CHANGELOG.md | 4 +++- .../README.md | 2 +- 12 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt index 7dc5c58110..db7fb2d358 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt @@ -1 +1,21 @@ #nullable enable +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt index 9e3f0feda4..e69de29bb2 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,20 +0,0 @@ -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 7dc5c58110..db7fb2d358 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1 +1,21 @@ #nullable enable +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 9e3f0feda4..e69de29bb2 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,20 +0,0 @@ -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool \ No newline at end of file diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md index a319aa4597..154f82e53f 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog -## Unreleased +## 1.0.0 + +Released 2023-Aug-28 ## 1.0.0-beta.2 diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 8a14ca569d..c0698b9dc3 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -5,9 +5,3 @@ This package includes APIs which can be extended by exporter owners to implement persistent storage. - -## Installation - -```shell -dotnet add package --prerelease OpenTelemetry.PersistentStorage.Abstractions -``` diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt index 7dc5c58110..96618dfb5b 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt @@ -1 +1,17 @@ #nullable enable +OpenTelemetry.PersistentStorage.FileSystem.FileBlob +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void + diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt index a3ca421004..e69de29bb2 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,15 +0,0 @@ -OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 7dc5c58110..c1d68fa289 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -1 +1,16 @@ #nullable enable +OpenTelemetry.PersistentStorage.FileSystem.FileBlob +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void +OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool +virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index a3ca421004..e69de29bb2 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,15 +0,0 @@ -OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index e50ba87d19..b4be7dcdc7 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog - OpenTelemetry.PersistentStorage.FileSystem -## Unreleased +## 1.0.0 + +Released 2023-Aug-28 ## 1.0.0-beta.2 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index 205c049ddc..ee0a542a67 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -11,7 +11,7 @@ exporters to improve the reliability of data delivery. ## Installation ```shell -dotnet add package --prerelease OpenTelemetry.PersistentStorage.FileSystem +dotnet add package OpenTelemetry.PersistentStorage.FileSystem ``` ## Basic Usage From 13f9058851cf0b2320e9534bc55ab9a324d61b78 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 28 Aug 2023 19:16:29 -0700 Subject: [PATCH 0801/1499] [PersistentStorage.FileSystem] Update PersistentStorage FileSystem csproj (#1333) --- opentelemetry-dotnet-contrib.sln | 4 ++-- .../OpenTelemetry.PersistentStorage.FileSystem.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index bb629ad26a..7afe8b2a4d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -42,8 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.AzureMonitor.yml = .github\workflows\package-Extensions.AzureMonitor.yml .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml - .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml = .github\workflows\package-Extensions.PersistentStorage.Abstractions.yml - .github\workflows\package-Extensions.PersistentStorage.yml = .github\workflows\package-Extensions.PersistentStorage.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml @@ -61,6 +59,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml + .github\workflows\package-PersistentStorage.Abstractions.yml = .github\workflows\package-PersistentStorage.Abstractions.yml + .github\workflows\package-PersistentStorage.FileSystem.yml = .github\workflows\package-PersistentStorage.FileSystem.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml EndProjectSection diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 7dffd68dec..d4bb9a5912 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -18,7 +18,7 @@ - + From ed2df8f10c6f550c244ff27de79e01a04811cada Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:54:14 -0600 Subject: [PATCH 0802/1499] [wcf] Add support for non-SOAP based payloads (#1251) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- examples/wcf/client-netframework/App.config | 5 + examples/wcf/client-netframework/Program.cs | 1 + examples/wcf/server-netframework/App.config | 9 +- .../wcf/shared/Examples.Wcf.Shared.csproj | 3 +- examples/wcf/shared/IStatusServiceContract.cs | 6 + .../CHANGELOG.md | 3 + .../HttpRequestMessagePropertyWrapper.cs | 120 +++++++++++++ .../Implementation/TelemetryMessageHeader.cs | 69 ++++++++ .../TelemetryPropagationReader.cs | 107 ++++++++++++ .../TelemetryPropagationWriter.cs | 111 ++++++++++++ .../WcfInstrumentationActivitySource.cs | 21 ++- .../WcfInstrumentationEventSource.cs | 16 ++ .../OpenTelemetry.Instrumentation.Wcf.csproj | 1 + .../README.md | 6 + ...Telemetry.Instrumentation.Wcf.Tests.csproj | 1 + .../TelemetryPropagationTests.netfx.cs | 160 ++++++++++++++++++ 16 files changed, 625 insertions(+), 14 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs diff --git a/examples/wcf/client-netframework/App.config b/examples/wcf/client-netframework/App.config index 3eb6ad106e..49b2186221 100644 --- a/examples/wcf/client-netframework/App.config +++ b/examples/wcf/client-netframework/App.config @@ -11,6 +11,10 @@ + + + + @@ -28,6 +32,7 @@ + diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index dddbedcf1e..891f8ccb40 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -35,6 +35,7 @@ public static async Task Main() await CallService("StatusService_Http").ConfigureAwait(false); await CallService("StatusService_Tcp").ConfigureAwait(false); + await CallService("StatusService_Rest").ConfigureAwait(false); Console.WriteLine("Press enter to exit."); Console.ReadLine(); diff --git a/examples/wcf/server-netframework/App.config b/examples/wcf/server-netframework/App.config index b79c6504be..c7fbe650bf 100644 --- a/examples/wcf/server-netframework/App.config +++ b/examples/wcf/server-netframework/App.config @@ -1,4 +1,4 @@ - + @@ -11,6 +11,10 @@ + + + + @@ -27,8 +31,9 @@ - + + diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index e4e7f643f8..265744f7ed 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -1,4 +1,4 @@ - + @@ -7,6 +7,7 @@ + diff --git a/examples/wcf/shared/IStatusServiceContract.cs b/examples/wcf/shared/IStatusServiceContract.cs index 0c620e9472..35e4045566 100644 --- a/examples/wcf/shared/IStatusServiceContract.cs +++ b/examples/wcf/shared/IStatusServiceContract.cs @@ -15,6 +15,9 @@ // using System.ServiceModel; +#if NETFRAMEWORK +using System.ServiceModel.Web; +#endif using System.Threading.Tasks; namespace Examples.Wcf; @@ -22,6 +25,9 @@ namespace Examples.Wcf; [ServiceContract(Namespace = "http://opentelemetry.io/", Name = "StatusService", SessionMode = SessionMode.Allowed)] public interface IStatusServiceContract { +#if NETFRAMEWORK + [WebInvoke] +#endif [OperationContract] Task PingAsync(StatusRequest request); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index dbc3e2ef3e..d3110ba797 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added support for non-SOAP requests. + ([#1251](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1251)) + ## 1.0.0-rc.11 Released 2023-Aug-14 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs new file mode 100644 index 0000000000..2205acbae2 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs @@ -0,0 +1,120 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Diagnostics; +using System.Net; +using System.Reflection; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +/// +/// This is a reflection-based wrapper around the HttpRequestMessageProperty class. It is done this way so we don't need to +/// have an explicit reference to System.ServiceModel.Http.dll. If the consuming application has a reference to +/// System.ServiceModel.Http.dll then the HttpRequestMessageProperty class will be available (IsHttpFunctionalityEnabled == true). +/// If the consuming application does not have a reference to System.ServiceModel.Http.dll then all http-related functionality +/// will be disabled (IsHttpFunctionalityEnabled == false). +/// +internal static class HttpRequestMessagePropertyWrapper +{ + private static readonly ReflectedInfo ReflectedValues = Initialize(); + + public static bool IsHttpFunctionalityEnabled => ReflectedValues != null; + + public static string Name + { + get + { + AssertHttpEnabled(); + return ReflectedValues.Name; + } + } + + public static object CreateNew() + { + AssertHttpEnabled(); + return Activator.CreateInstance(ReflectedValues.Type); + } + + public static WebHeaderCollection GetHeaders(object httpRequestMessageProperty) + { + AssertHttpEnabled(); + AssertIsFrameworkMessageProperty(httpRequestMessageProperty); + return ReflectedValues.HeadersFetcher.Fetch(httpRequestMessageProperty); + } + + private static ReflectedInfo Initialize() + { + Type type = null; + try + { + type = Type.GetType( + "System.ServiceModel.Channels.HttpRequestMessageProperty, System.ServiceModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", + true); + + var headersProp = type.GetProperty("Headers", BindingFlags.Public | BindingFlags.Instance, null, typeof(WebHeaderCollection), Array.Empty(), null); + if (headersProp == null) + { + throw new NotSupportedException("HttpRequestMessageProperty.Headers property not found"); + } + + var nameProp = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static, null, typeof(string), Array.Empty(), null); + if (nameProp == null) + { + throw new NotSupportedException("HttpRequestMessageProperty.Name property not found"); + } + + return new ReflectedInfo + { + Type = type, + Name = (string)nameProp.GetValue(null), + HeadersFetcher = new PropertyFetcher("Headers"), + }; + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.HttpServiceModelReflectionFailedToBind(ex, type?.Assembly); + } + + return null; + } + + [Conditional("DEBUG")] + private static void AssertHttpEnabled() + { + if (!IsHttpFunctionalityEnabled) + { + throw new InvalidOperationException("Http functionality is not enabled, check IsHttpFunctionalityEnabled before calling this method"); + } + } + + [Conditional("DEBUG")] + private static void AssertIsFrameworkMessageProperty(object httpRequestMessageProperty) + { + AssertHttpEnabled(); + if (httpRequestMessageProperty == null || !httpRequestMessageProperty.GetType().Equals(ReflectedValues.Type)) + { + throw new ArgumentException("Object must be of type HttpRequestMessageProperty"); + } + } + + private sealed class ReflectedInfo + { + public Type Type; + public string Name; + public PropertyFetcher HeadersFetcher; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs new file mode 100644 index 0000000000..2abcbd5955 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs @@ -0,0 +1,69 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.ServiceModel.Channels; +using System.Xml; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class TelemetryMessageHeader : MessageHeader +{ + private const string NAMESPACE = "https://www.w3.org/TR/trace-context/"; + private string name; + private string value; + + private TelemetryMessageHeader(string name, string value) + { + this.name = name; + this.value = value; + } + + public override string Name => this.name; + + public string Value => this.value; + + public override string Namespace => NAMESPACE; + + public static TelemetryMessageHeader CreateHeader(string name, string value) + { + return new TelemetryMessageHeader(name, value); + } + + public static TelemetryMessageHeader FindHeader(string name, MessageHeaders allHeaders) + { + try + { + var headerIndex = allHeaders.FindHeader(name, NAMESPACE); + if (headerIndex < 0) + { + return null; + } + + using var reader = allHeaders.GetReaderAtHeader(headerIndex); + reader.Read(); + return new TelemetryMessageHeader(name, reader.ReadContentAsString()); + } + catch (XmlException) + { + return null; + } + } + + protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) + { + writer.WriteString(this.value); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs new file mode 100644 index 0000000000..c537e8f453 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs @@ -0,0 +1,107 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.ServiceModel.Channels; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +/// +/// Pre-defined PropagationReader callbacks. +/// +internal static class TelemetryPropagationReader +{ + private static readonly Func> DefaultReader = Compose(HttpRequestHeaders, SoapMessageHeaders); + + /// + /// Reads the values from the SOAP message headers. If the message is not a SOAP message it returns null. + /// + /// The incoming to read trace context from. + /// The header name being requested. + /// An enumerable of all the values for the requested header, or null if the requested header was not present on the request. + public static IEnumerable SoapMessageHeaders(Message request, string name) + { + Guard.ThrowIfNull(request); + Guard.ThrowIfNull(name); + + if (request.Version == MessageVersion.None) + { + return null; + } + + var header = TelemetryMessageHeader.FindHeader(name, request.Headers); + return header == null ? null : new[] { header.Value }; + } + + /// + /// Reads the values from the incoming HTTP request headers. If the message was not made via an HTTP request it returns null. + /// + /// The incoming to read trace context from. + /// The header name being requested. + /// An enumerable of all the values for the requested header, or null if the requested header was not present on the request. + public static IEnumerable HttpRequestHeaders(Message request, string name) + { + Guard.ThrowIfNull(request); + Guard.ThrowIfNull(name); + + if (!HttpRequestMessagePropertyWrapper.IsHttpFunctionalityEnabled || !request.Properties.TryGetValue(HttpRequestMessagePropertyWrapper.Name, out var prop)) + { + return null; + } + + var value = HttpRequestMessagePropertyWrapper.GetHeaders(prop)[name]; + return value == null ? null : new[] { value }; + } + + /// + /// Reads the values from the incoming HTTP request headers and falls back to SOAP message headers if not found on the HTTP request. + /// + /// The incoming to read trace context from. + /// The header name being requested. + /// An enumerable of all the values for the requested header, or null if the requested header was not present on the request. + public static IEnumerable Default(Message request, string name) + { + return DefaultReader(request, name); + } + + /// + /// Compose multiple PropagationReader callbacks into a single callback. The callbacks + /// are called sequentially and the first one to return a non-null value wins. + /// + /// The callbacks to compose into a single callback. + /// The composed callback. + public static Func> Compose(params Func>[] callbacks) + { + Guard.ThrowIfNull(callbacks); + Array.ForEach(callbacks, cb => Guard.ThrowIfNull(cb)); + + return (Message request, string name) => + { + foreach (var reader in callbacks) + { + var values = reader(request, name); + if (values != null) + { + return values; + } + } + + return null; + }; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs new file mode 100644 index 0000000000..63772789bf --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs @@ -0,0 +1,111 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.ServiceModel.Channels; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +/// +/// Pre-defined PropagationWriter callbacks. +/// +internal static class TelemetryPropagationWriter +{ + /// + /// Writes the values to SOAP message headers. If the message is not a SOAP message it does nothing. + /// + /// The outgoing request (carrier) to write trace context to. + /// The header name being written. + /// The header value to write. + public static void SoapMessageHeaders(Message request, string name, string value) + { + Guard.ThrowIfNull(request); + Guard.ThrowIfNull(name); + Guard.ThrowIfNull(value); + + if (request.Version == MessageVersion.None) + { + return; + } + + request.Headers.Add(TelemetryMessageHeader.CreateHeader(name, value)); + } + + /// + /// Writes the values to outgoing HTTP request headers. If the message is not ultimately transmitted via HTTP these will be ignored. + /// + /// The outgoing request (carrier) to write trace context to. + /// The header name being written. + /// The header value to write. + public static void HttpRequestHeaders(Message request, string name, string value) + { + Guard.ThrowIfNull(request); + Guard.ThrowIfNull(name); + Guard.ThrowIfNull(value); + + if (!HttpRequestMessagePropertyWrapper.IsHttpFunctionalityEnabled) + { + return; + } + + object prop; + if (!request.Properties.TryGetValue(HttpRequestMessagePropertyWrapper.Name, out prop)) + { + prop = HttpRequestMessagePropertyWrapper.CreateNew(); + request.Properties.Add(HttpRequestMessagePropertyWrapper.Name, prop); + } + + HttpRequestMessagePropertyWrapper.GetHeaders(prop)[name] = value; + } + + /// + /// Writes values to both SOAP message headers and outgoing HTTP request headers when suppressing downstream instrumentation. + /// When not suppressing downstream instrumentation it is assumed the transport will be propagating the context itself, so + /// only SOAP message headers are written. + /// + /// The outgoing request (carrier) to write trace context to. + /// The header name being written. + /// The header value to write. + public static void Default(Message request, string name, string value) + { + SoapMessageHeaders(request, name, value); + if (WcfInstrumentationActivitySource.Options.SuppressDownstreamInstrumentation) + { + HttpRequestHeaders(request, name, value); + } + } + + /// + /// Compose multiple PropagationWriter callbacks into a single callback. All callbacks + /// are executed to allow for propagating the context in multiple ways. + /// + /// The callbacks to compose into a single callback. + /// The composed callback. + public static Action Compose(params Action[] callbacks) + { + Guard.ThrowIfNull(callbacks); + Array.ForEach(callbacks, cb => Guard.ThrowIfNull(cb)); + + return (Message request, string name, string value) => + { + foreach (var writer in callbacks) + { + writer(request, name, value); + } + }; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index ca92becf65..9f56acde72 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -19,6 +19,7 @@ using System.Diagnostics; using System.Reflection; using System.ServiceModel.Channels; +using OpenTelemetry.Instrumentation.Wcf.Implementation; namespace OpenTelemetry.Instrumentation.Wcf; @@ -36,17 +37,15 @@ internal static class WcfInstrumentationActivitySource public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); - public static Func> MessageHeaderValuesGetter { get; } - = (request, name) => - { - var headerIndex = request.Headers.FindHeader(name, "https://www.w3.org/TR/trace-context/"); - return headerIndex < 0 - ? null - : new[] { request.Headers.GetHeader(headerIndex) }; - }; + public static WcfInstrumentationOptions Options { get; set; } - public static Action MessageHeaderValueSetter { get; } - = (request, name, value) => request.Headers.Add(MessageHeader.CreateHeader(name, "https://www.w3.org/TR/trace-context/", value, false)); + public static IEnumerable MessageHeaderValuesGetter(Message request, string name) + { + return TelemetryPropagationReader.Default(request, name); + } - public static WcfInstrumentationOptions Options { get; set; } + public static void MessageHeaderValueSetter(Message request, string name, string value) + { + TelemetryPropagationWriter.Default(request, name, value); + } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index bd23a2e9c6..201884ea21 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -61,10 +61,26 @@ public void EnrichmentException(string exception) this.WriteEvent(EventIds.EnrichmentException, exception); } + [NonEvent] + public void HttpServiceModelReflectionFailedToBind(Exception exception, System.Reflection.Assembly assembly) + { + if (this.IsEnabled(EventLevel.Verbose, (EventKeywords)(-1))) + { + this.HttpServiceModelReflectionFailedToBind(exception.ToInvariantString(), assembly?.FullName); + } + } + + [Event(EventIds.HttpServiceModelReflectionFailedToBind, Message = "Failed to bind to System.ServiceModel.Http. Exception {0}. Assembly {1}.", Level = EventLevel.Verbose)] + public void HttpServiceModelReflectionFailedToBind(string exception, string assembly) + { + this.WriteEvent(EventIds.HttpServiceModelReflectionFailedToBind, exception, assembly); + } + private class EventIds { public const int RequestIsFilteredOut = 1; public const int RequestFilterException = 2; public const int EnrichmentException = 3; + public const int HttpServiceModelReflectionFailedToBind = 4; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 7b01ca3fb1..7d8b688310 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -24,6 +24,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index e235bf33b4..cade5daae7 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -5,6 +5,12 @@ Instruments WCF clients and/or services. +The following configurations are verified to work with this instrumentation. +Other configurations may work as well but have not been tested. + +* SOAP and JSON payloads on HTTP/HTTPS transport +* SOAP payloads on Net.TCP transport + ## Installation Add the OpenTelemetry.Instrumentation.Wcf package via NuGet. diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 4dd73e88be..9adb7330ea 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -20,6 +20,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs new file mode 100644 index 0000000000..89e3d49f60 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs @@ -0,0 +1,160 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.Threading.Tasks; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[Collection("WCF")] +public class TelemetryPropagationTests : IDisposable +{ + private readonly Uri serviceBaseUriTcp; + private readonly Uri serviceBaseUriHttp; + private readonly ServiceHost serviceHost; + + public TelemetryPropagationTests() + { + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) + { + try + { + this.serviceBaseUriTcp = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); + this.serviceBaseUriHttp = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); + this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUriTcp, this.serviceBaseUriHttp); + var tcpEndpoint = this.serviceHost.AddServiceEndpoint(typeof(IServiceContract), new NetTcpBinding(), "/tcp"); + tcpEndpoint.Behaviors.Add(new TelemetryEndpointBehavior()); + var httpEndpoint = this.serviceHost.AddServiceEndpoint(typeof(IServiceContract), new BasicHttpBinding(), "/http"); + httpEndpoint.Behaviors.Add(new TelemetryEndpointBehavior()); + var restEndpoint = this.serviceHost.AddServiceEndpoint(typeof(IServiceContract), new WebHttpBinding(), "/rest"); + restEndpoint.Behaviors.Add(new TelemetryEndpointBehavior()); + restEndpoint.Behaviors.Add(new WebHttpBehavior()); + this.serviceHost.Open(); + break; + } + catch (Exception) + { + if (this.serviceHost.State == CommunicationState.Faulted) + { + this.serviceHost.Abort(); + } + else + { + this.serviceHost.Close(); + } + + this.serviceHost = null; + retryCount--; + } + } + + if (this.serviceHost == null) + { + throw new InvalidOperationException("ServiceHost could not be started."); + } + } + + public void Dispose() + { + this.serviceHost?.Close(); + } + + [Theory] + [InlineData("tcp")] + [InlineData("http")] + [InlineData("rest")] + [InlineData("http", false, true)] + [InlineData("tcp", false, true)] + [InlineData("rest", false, false)] + public async Task TelemetryContextPropagatesTest( + string endpoint, + bool suppressDownstreamInstrumenation = true, + bool shouldPropagate = true) + { + var stoppedActivities = new List(); + using var activityListener = new ActivityListener + { + ShouldListenTo = activitySource => true, + ActivityStopped = stoppedActivities.Add, + }; + ActivitySource.AddActivityListener(activityListener); + + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddWcfInstrumentation(options => options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumenation) + .Build(); + + var serviceBase = endpoint == "tcp" ? this.serviceBaseUriTcp : this.serviceBaseUriHttp; + Binding binding = endpoint switch + { + "tcp" => new NetTcpBinding(), + "http" => new BasicHttpBinding(), + "rest" => new WebHttpBinding(), + _ => throw new ArgumentException("Invalid endpoint type", nameof(endpoint)), + }; + ServiceClient client = new ServiceClient(binding, new EndpointAddress(new Uri(serviceBase, $"/{endpoint}"))); + try + { + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + if (endpoint == "rest") + { + client.Endpoint.EndpointBehaviors.Add(new WebHttpBehavior()); + } + + await client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + + WcfInstrumentationActivitySource.Options = null; + } + + Assert.Equal(2, stoppedActivities.Count); + if (shouldPropagate) + { + var clientSpan = stoppedActivities.Single(activity => activity.ParentId == null); + var serverSpan = stoppedActivities.Single(activity => activity.ParentId == clientSpan.Id); + Assert.Equal(clientSpan.TraceId, serverSpan.TraceId); + } + else + { + Assert.All(stoppedActivities, activity => Assert.Null(activity.ParentId)); + Assert.NotEqual(stoppedActivities[0].TraceId, stoppedActivities[1].TraceId); + } + } +} +#endif From 10ffaad3f25d69de88e6a1830b385ec9fa4c9edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Wed, 30 Aug 2023 09:27:14 +0200 Subject: [PATCH 0803/1499] [wcf]1.0.0-rc.12 release (#1337) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index d3110ba797..32365feb95 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.12 + +Released 2023-Aug-30 + * Added support for non-SOAP requests. ([#1251](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1251)) From 75d7622d931abe5834435d01a1fc0a01c3af15a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Sep 2023 19:49:51 -0700 Subject: [PATCH 0804/1499] Bump actions/checkout from 3 to 4 (#1340) --- .github/workflows/ci-Instrumentation.Process.yml | 2 +- .github/workflows/ci-aot.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/dotnet-core-cov.yml | 2 +- .github/workflows/dotnet-format.yml | 2 +- .github/workflows/integration.yml | 2 +- .github/workflows/markdownlint.yml | 2 +- .github/workflows/package-Exporter.Geneva.yml | 2 +- .github/workflows/package-Exporter.InfluxDB.yml | 2 +- .github/workflows/package-Exporter.Instana.yml | 2 +- .github/workflows/package-Exporter.OneCollector.yml | 2 +- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWS.yml | 2 +- .github/workflows/package-Extensions.Enrichment.yml | 2 +- .github/workflows/package-Extensions.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .../package-Instrumentation.AspNet.TelemetryHttpModule.yml | 2 +- .github/workflows/package-Instrumentation.AspNet.yml | 2 +- .github/workflows/package-Instrumentation.Cassandra.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.EventCounters.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.Hangfire.yml | 2 +- .github/workflows/package-Instrumentation.Owin.yml | 2 +- .github/workflows/package-Instrumentation.Process.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-Instrumentation.Runtime.yml | 2 +- .../workflows/package-Instrumentation.StackExchangeRedis.yml | 2 +- .github/workflows/package-Instrumentation.Wcf.yml | 2 +- .github/workflows/package-PersistentStorage.Abstractions.yml | 2 +- .github/workflows/package-PersistentStorage.FileSystem.yml | 2 +- .github/workflows/package-ResourceDetectors.AWS.yml | 2 +- .github/workflows/package-ResourceDetectors.Azure.yml | 2 +- .github/workflows/package-ResourceDetectors.Container.yml | 2 +- .github/workflows/package-Sampler.AWS.yml | 2 +- .github/workflows/sanitycheck.yml | 4 ++-- 39 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index 0d42111c65..bd0b9bb5cf 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -19,7 +19,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install .NET 7 SDK uses: actions/setup-dotnet@v3.2.0 diff --git a/.github/workflows/ci-aot.yml b/.github/workflows/ci-aot.yml index 00c208ab69..ff44f35e24 100644 --- a/.github/workflows/ci-aot.yml +++ b/.github/workflows/ci-aot.yml @@ -26,7 +26,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: publish AOT testApp, assert static analysis warning count, and run the app shell: pwsh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d575ad7245..93d5d72a49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup dotnet uses: actions/setup-dotnet@v3 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 23e5e346df..0b466885dd 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,7 +33,7 @@ jobs: disk-root: "D:" - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml index fe8c9e2e84..388ac5730f 100644 --- a/.github/workflows/dotnet-core-cov.yml +++ b/.github/workflows/dotnet-core-cov.yml @@ -20,7 +20,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 3f49401a03..48876d69ba 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -18,7 +18,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup dotnet uses: actions/setup-dotnet@v3 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index e6e376aad3..b11a2b163c 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -18,7 +18,7 @@ jobs: matrix: version: [net6.0,net7.0] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Run redis docker-compose.integration run: docker-compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 9a94093b16..736387a7d5 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -16,7 +16,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v4 - name: install markdownlint-cli run: sudo npm install -g markdownlint-cli diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index 77a5cca48d..af95b2db72 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml index 2d969e87b9..d6cc3a5ea8 100644 --- a/.github/workflows/package-Exporter.InfluxDB.yml +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index 70e7f06838..e19def6a13 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml index a6fc9ccc80..7d36af02c3 100644 --- a/.github/workflows/package-Exporter.OneCollector.yml +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index bf15aa38d1..d06d20db13 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Extensions.AWS.yml b/.github/workflows/package-Extensions.AWS.yml index 801f15dc66..ba4665e374 100644 --- a/.github/workflows/package-Extensions.AWS.yml +++ b/.github/workflows/package-Extensions.AWS.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml index c504dc24e0..ba987e95a8 100644 --- a/.github/workflows/package-Extensions.Enrichment.yml +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index c18c2cfe6b..d068014306 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index a212b3de13..7713f418c8 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index b1d1f35124..42f43fd54a 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml index 26027d7566..6cdd46856c 100644 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index b082a8707c..1b90c4dfec 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml index d67c4d3506..78a506eaed 100644 --- a/.github/workflows/package-Instrumentation.Cassandra.yml +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -22,7 +22,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 74f81be176..2d3055ed4c 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index e3d64c5641..bca4670daf 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index cd3f25bd9a..22d285eed9 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index 23b198fbe3..cbcf9070bd 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index 1b7d1ad31c..0f09a193ef 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index 84b617d4c6..57a27988b5 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index c9a71950d5..83e444bd4a 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 24b6d29c84..955a496db4 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index 21b20ded16..c06446fb53 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index 6a66f78e01..2c4b4a1f22 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index 823368e89e..b7856c08c5 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-PersistentStorage.Abstractions.yml b/.github/workflows/package-PersistentStorage.Abstractions.yml index b757cb4416..3c0c1d2d68 100644 --- a/.github/workflows/package-PersistentStorage.Abstractions.yml +++ b/.github/workflows/package-PersistentStorage.Abstractions.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-PersistentStorage.FileSystem.yml b/.github/workflows/package-PersistentStorage.FileSystem.yml index 09bee39744..1de7b01c48 100644 --- a/.github/workflows/package-PersistentStorage.FileSystem.yml +++ b/.github/workflows/package-PersistentStorage.FileSystem.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml index 6c68853329..de0e775736 100644 --- a/.github/workflows/package-ResourceDetectors.AWS.yml +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml index 87607aaaf1..58e58d7d1c 100644 --- a/.github/workflows/package-ResourceDetectors.Azure.yml +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-ResourceDetectors.Container.yml b/.github/workflows/package-ResourceDetectors.Container.yml index 1bf1f5765b..0b680c62e9 100644 --- a/.github/workflows/package-ResourceDetectors.Container.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml index 6f82f2c6cd..1c55a193d9 100644 --- a/.github/workflows/package-Sampler.AWS.yml +++ b/.github/workflows/package-Sampler.AWS.yml @@ -24,7 +24,7 @@ jobs: os: [windows-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 # fetching all diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index a9e718d77d..6cf97382ae 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -12,7 +12,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: install misspell run: | @@ -27,7 +27,7 @@ jobs: steps: - name: check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: detect non-ASCII encoding and trailing space run: python3 ./build/sanitycheck.py From ae05c9161a3a0f694112e09029d675bde6729499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 5 Sep 2023 20:27:51 +0200 Subject: [PATCH 0805/1499] Sample.AWS.Tests - nullable (#1304) --- .../AWSXRayRemoteSamplerBuilder.cs | 9 +--- .../SamplingRuleApplier.cs | 2 +- .../OpenTelemetry.Sampler.AWS.Tests.csproj | 1 + .../TestAWSXRayRemoteSampler.cs | 6 +-- .../TestAWSXRaySamplerClient.cs | 22 +++++----- .../TestClock.cs | 4 +- .../TestMatcher.cs | 22 +++++----- .../TestRateLimiter.cs | 2 +- .../TestRulesCache.cs | 42 +++++++++---------- .../TestSamplingRuleApplier.cs | 22 +++++----- test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs | 21 +++------- 11 files changed, 69 insertions(+), 84 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs index 0aa3aa32d8..4c8497ede1 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs @@ -62,7 +62,7 @@ public AWSXRayRemoteSamplerBuilder SetPollingInterval(TimeSpan pollingInterval) /// /// Sets the endpoint for the TCP proxy to connect to. This is the address to the port on the - /// OpenTelemetry Collector configured for proxying X-Ray sampling requests.If unset, defaults to + /// OpenTelemetry Collector configured for proxying X-Ray sampling requests. If unset, defaults to /// . /// /// the endpoint for the TCP proxy. @@ -90,12 +90,7 @@ public AWSXRayRemoteSampler Build() // Should not be exposed to public. internal AWSXRayRemoteSamplerBuilder SetClock(Clock clock) { - if (clock == null) - { - throw new ArgumentNullException(nameof(clock)); - } - - this.clock = clock; + this.clock = clock ?? throw new ArgumentNullException(nameof(clock)); return this; } diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index 56cc0f0443..3450c30577 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -24,7 +24,7 @@ namespace OpenTelemetry.Sampler.AWS; internal class SamplingRuleApplier { - public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Statistics statistics) + public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Statistics? statistics) { this.ClientId = clientId; this.Clock = clock; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index e0fb3a51f5..59ebd9591e 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -3,6 +3,7 @@ net7.0;net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index 652165e0ab..aab1148cdc 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -68,7 +68,7 @@ public void TestSamplerUpdateAndSample() // create sampler AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) .SetPollingInterval(TimeSpan.FromMilliseconds(10)) - .SetEndpoint(mockServer.Url) + .SetEndpoint(mockServer.Url!) .SetClock(clock) .Build(); @@ -117,9 +117,9 @@ private SamplingDecision DoSample(Trace.Sampler sampler, string serviceName) ActivityTraceId.CreateRandom(), "myActivityName", ActivityKind.Server, - new List>() + new List> { - new KeyValuePair("test", serviceName), + new("test", serviceName), }, null); diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs index fa78d9a108..863024a6cd 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -26,14 +26,14 @@ namespace OpenTelemetry.Sampler.AWS.Tests; public class TestAWSXRaySamplerClient : IDisposable { - private WireMockServer mockServer; + private readonly WireMockServer mockServer; - private AWSXRaySamplerClient client; + private readonly AWSXRaySamplerClient client; public TestAWSXRaySamplerClient() { this.mockServer = WireMockServer.Start(); - this.client = new AWSXRaySamplerClient(this.mockServer.Url); + this.client = new AWSXRaySamplerClient(this.mockServer.Url!); } public void Dispose() @@ -116,23 +116,23 @@ public void TestGetSamplingTargets() this.CreateResponse("/SamplingTargets", "Data/GetSamplingTargetsResponse.json"); - var request = new GetSamplingTargetsRequest(new List() + var request = new GetSamplingTargetsRequest(new List { - new SamplingStatisticsDocument( + new( "clientId", "rule1", 100, 50, 10, clock.ToDouble(clock.Now())), - new SamplingStatisticsDocument( + new( "clientId", "rule2", 200, 100, 20, clock.ToDouble(clock.Now())), - new SamplingStatisticsDocument( + new( "clientId", "rule3", 20, @@ -144,7 +144,7 @@ public void TestGetSamplingTargets() var responseTask = this.client.GetSamplingTargets(request); responseTask.Wait(); - GetSamplingTargetsResponse targetsResponse = responseTask.Result; + GetSamplingTargetsResponse targetsResponse = responseTask.Result!; Assert.Equal(2, targetsResponse.SamplingTargetDocuments.Count); Assert.Single(targetsResponse.UnprocessedStatistics); @@ -175,9 +175,9 @@ public void TestGetSamplingTargetsWithMalformed() .RespondWith( Response.Create().WithStatusCode(200).WithHeader("Content-Type", "application/json").WithBody("notJson")); - var request = new GetSamplingTargetsRequest(new List() + var request = new GetSamplingTargetsRequest(new List { - new SamplingStatisticsDocument( + new( "clientId", "rule1", 100, @@ -189,7 +189,7 @@ public void TestGetSamplingTargetsWithMalformed() var responseTask = this.client.GetSamplingTargets(request); responseTask.Wait(); - GetSamplingTargetsResponse targetsResponse = responseTask.Result; + GetSamplingTargetsResponse? targetsResponse = responseTask.Result; Assert.Null(targetsResponse); } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index a5444b3b9a..806f714578 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -20,7 +20,7 @@ namespace OpenTelemetry.Sampler.AWS.Tests; internal class TestClock : Clock { - private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private static readonly DateTime EpochStart = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private DateTime nowTime; public TestClock() @@ -55,7 +55,7 @@ public override double ToDouble(DateTime dateTime) return timestamp; } - // Advnaces the clock by a given time span. + // Advances the clock by a given time span. public void Advance(TimeSpan time) { this.nowTime = this.nowTime.Add(time); diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs index 3c320f2d81..671810abd2 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs @@ -48,14 +48,14 @@ public void TestWildcardDoesNotMatch(string input, string pattern) [Fact] public void TestAttributeMatching() { - var tags = new List>() + var tags = new List> { - new KeyValuePair("dog", "bark"), - new KeyValuePair("cat", "meow"), - new KeyValuePair("cow", "mooo"), + new("dog", "bark"), + new("cat", "meow"), + new("cow", "mooo"), }; - var ruleAttributes = new Dictionary() + var ruleAttributes = new Dictionary { { "dog", "bar?" }, { "cow", "mooo" }, @@ -67,11 +67,11 @@ public void TestAttributeMatching() [Fact] public void TestAttributeMatchingWithoutRuleAttributes() { - var tags = new List>() + var tags = new List> { - new KeyValuePair("dog", "bark"), - new KeyValuePair("cat", "meow"), - new KeyValuePair("cow", "mooo"), + new("dog", "bark"), + new("cat", "meow"), + new("cow", "mooo"), }; var ruleAttributes = new Dictionary(); @@ -82,13 +82,13 @@ public void TestAttributeMatchingWithoutRuleAttributes() [Fact] public void TestAttributeMatchingWithoutSpanTags() { - var ruleAttributes = new Dictionary() + var ruleAttributes = new Dictionary { { "dog", "bar?" }, { "cow", "mooo" }, }; - Assert.False(Matcher.AttributeMatch(new List>(), ruleAttributes)); + Assert.False(Matcher.AttributeMatch(new List>(), ruleAttributes)); Assert.False(Matcher.AttributeMatch(null, ruleAttributes)); } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs index 446cb4af6e..a0c60c7d29 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs @@ -137,7 +137,7 @@ public async Task TestRateLimiterConcurrencyAsync() TestClock clock = new TestClock(); RateLimiter limiter = new RateLimiter(1, numWorkers * creditsPerWorker, clock); int count = 0; - List tasks = new List(numWorkers); + List tasks = new(numWorkers); for (int w = 0; w < numWorkers; ++w) { diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs index eafc974c00..fbfa0fb250 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs @@ -42,7 +42,7 @@ public void TestUpdateRules() // set up rules cache with a default rule var defaultRule = this.CreateDefaultRule(1, 0.05); - var stats = new Statistics() + var stats = new Statistics { RequestCount = 10, SampleCount = 5, @@ -51,9 +51,9 @@ public void TestUpdateRules() var cache = new RulesCache(clock, "test", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) { - RuleAppliers = new List() + RuleAppliers = new List { - { new SamplingRuleApplier("testId", clock, defaultRule, stats) }, + { new("testId", clock, defaultRule, stats) }, }, }; @@ -80,10 +80,10 @@ public void TestUpdateRulesRemovesOlderRule() // set up rule cache with 2 rules var rulesCache = new RulesCache(clock, "test", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) { - RuleAppliers = new List() + RuleAppliers = new List { - { new SamplingRuleApplier("testId", clock, this.CreateDefaultRule(1, 0.05), null) }, - { new SamplingRuleApplier("testId", clock, this.CreateRule("Rule1", 5, 0.20, 1), null) }, + { new("testId", clock, this.CreateDefaultRule(1, 0.05), null) }, + { new("testId", clock, this.CreateRule("Rule1", 5, 0.20, 1), null) }, }, }; @@ -103,10 +103,10 @@ public void TestShouldSampleMatchesExactRule() var clock = new TestClock(); var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) { - RuleAppliers = new List() + RuleAppliers = new List { - { new SamplingRuleApplier("clientId", clock, this.CreateRule("ruleWillMatch", 1, 0.0, 1), new Statistics()) }, // higher priority rule will sample - { new SamplingRuleApplier("clientId", clock, this.CreateRule("ruleWillNotMatch", 0, 0.0, 2), new Statistics()) }, // this rule will not sample + { new("clientId", clock, this.CreateRule("ruleWillMatch", 1, 0.0, 1), new Statistics()) }, // higher priority rule will sample + { new("clientId", clock, this.CreateRule("ruleWillNotMatch", 0, 0.0, 2), new Statistics()) }, // this rule will not sample }, }; @@ -144,10 +144,10 @@ public void TestUpdateTargets() var clock = new TestClock(); var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) { - RuleAppliers = new List() + RuleAppliers = new List { - { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule1", 1, 0.0, 1), new Statistics()) }, // this rule will sample 1 req/sec - { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule2", 0, 0.0, 2), new Statistics()) }, + { new("clientId", clock, this.CreateRule("rule1", 1, 0.0, 1), new Statistics()) }, // this rule will sample 1 req/sec + { new("clientId", clock, this.CreateRule("rule2", 0, 0.0, 2), new Statistics()) }, }, }; @@ -155,7 +155,7 @@ public void TestUpdateTargets() Assert.Equal(SamplingDecision.Drop, rulesCache.ShouldSample(default).Decision); // update targets - var targetForRule1 = new SamplingTargetDocument() + var targetForRule1 = new SamplingTargetDocument { FixedRate = 0.0, Interval = 0, @@ -163,7 +163,7 @@ public void TestUpdateTargets() ReservoirQuotaTTL = clock.ToDouble(clock.Now().AddMinutes(5)), RuleName = "rule1", }; - var targetForRule2 = new SamplingTargetDocument() + var targetForRule2 = new SamplingTargetDocument { FixedRate = 0.0, Interval = 0, @@ -172,7 +172,7 @@ public void TestUpdateTargets() RuleName = "rule2", }; - var targets = new Dictionary() + var targets = new Dictionary { { "rule1", targetForRule1 }, { "rule2", targetForRule2 }, @@ -192,15 +192,15 @@ public void TestNextTargetFetchTime() var clock = new TestClock(); var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) { - RuleAppliers = new List() + RuleAppliers = new List { - { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule1", 1, 0.0, 1), new Statistics()) }, - { new SamplingRuleApplier("clientId", clock, this.CreateRule("rule2", 0, 0.0, 2), new Statistics()) }, + { new("clientId", clock, this.CreateRule("rule1", 1, 0.0, 1), new Statistics()) }, + { new("clientId", clock, this.CreateRule("rule2", 0, 0.0, 2), new Statistics()) }, }, }; // update targets - var targetForRule1 = new SamplingTargetDocument() + var targetForRule1 = new SamplingTargetDocument { FixedRate = 0.0, Interval = 10, // next target poll after 10s @@ -208,7 +208,7 @@ public void TestNextTargetFetchTime() ReservoirQuotaTTL = clock.ToDouble(clock.Now().Add(TimeSpan.FromMinutes(5))), RuleName = "rule1", }; - var targetForRule2 = new SamplingTargetDocument() + var targetForRule2 = new SamplingTargetDocument { FixedRate = 0.0, Interval = 5, // next target poll after 5s @@ -217,7 +217,7 @@ public void TestNextTargetFetchTime() RuleName = "rule2", }; - var targets = new Dictionary() + var targets = new Dictionary { { "rule1", targetForRule1 }, { "rule2", targetForRule2 }, diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs index 34ae66df43..35128b85e3 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -40,7 +40,7 @@ public void TestRuleMatchesWithAllAttributes() version: 1, attributes: new Dictionary()); - var activityTags = new Dictionary() + var activityTags = new Dictionary { { "http.host", "localhost" }, { "http.method", "GET" }, @@ -69,7 +69,7 @@ public void TestRuleMatchesWithWildcardAttributes() version: 1, attributes: new Dictionary()); - var activityTags = new Dictionary() + var activityTags = new Dictionary { { "http.host", "localhost" }, { "http.method", "GET" }, @@ -143,7 +143,7 @@ public void TestRuleMatchesWithHttpTarget() version: 1, attributes: new Dictionary()); - var activityTags = new Dictionary() + var activityTags = new Dictionary { { "http.target", "/helloworld" }, }; @@ -155,7 +155,7 @@ public void TestRuleMatchesWithHttpTarget() [Fact] public void TestAttributeMatching() { - var ruleAttributes = new Dictionary() + var ruleAttributes = new Dictionary { { "dog", "bark" }, { "cat", "meow" }, @@ -175,7 +175,7 @@ public void TestAttributeMatching() version: 1, attributes: ruleAttributes); - var activityTags = new Dictionary() + var activityTags = new Dictionary { { "http.target", "/helloworld" }, { "dog", "bark" }, @@ -189,7 +189,7 @@ public void TestAttributeMatching() [Fact] public void TestAttributeMatchingWithLessActivityTags() { - var ruleAttributes = new Dictionary() + var ruleAttributes = new Dictionary { { "dog", "bark" }, { "cat", "meow" }, @@ -209,7 +209,7 @@ public void TestAttributeMatchingWithLessActivityTags() version: 1, attributes: ruleAttributes); - var activityTags = new Dictionary() + var activityTags = new Dictionary { { "http.target", "/helloworld" }, { "dog", "bark" }, @@ -347,7 +347,7 @@ public void TestWithTarget() var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); - // no target assigned yet. so borrow 1 from reseroir every second + // no target assigned yet. so borrow 1 from reservoir every second Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); clock.Advance(TimeSpan.FromSeconds(1)); @@ -355,7 +355,7 @@ public void TestWithTarget() Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); // get the target - SamplingTargetDocument target = new SamplingTargetDocument() + SamplingTargetDocument target = new SamplingTargetDocument { FixedRate = 0.0, Interval = 10, @@ -392,7 +392,7 @@ public void TestWithTargetWithoutQuota() var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); - // no target assigned yet. so borrow 1 from reseroir every second + // no target assigned yet. so borrow 1 from reservoir every second Assert.Equal(SamplingDecision.RecordAndSample, applier.ShouldSample(default).Decision); Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); clock.Advance(TimeSpan.FromSeconds(1)); @@ -405,7 +405,7 @@ public void TestWithTargetWithoutQuota() Assert.Equal(2, statistics.BorrowCount); // get the target - SamplingTargetDocument target = new SamplingTargetDocument() + SamplingTargetDocument target = new SamplingTargetDocument { FixedRate = 1.0, Interval = 10, diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs index b415200872..12e00e2ff2 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs @@ -28,17 +28,6 @@ internal static SamplingParameters CreateSamplingParameters() return CreateSamplingParametersWithTags(new Dictionary()); } - internal static SamplingParameters CreateSamplingParametersWithRootContext() - { - return new SamplingParameters( - default, - ActivityTraceId.CreateRandom(), - "myActivityName", - ActivityKind.Server, - null, - null); - } - internal static SamplingParameters CreateSamplingParametersWithTags(Dictionary tags) { ActivityTraceId traceId = ActivityTraceId.CreateRandom(); @@ -47,11 +36,11 @@ internal static SamplingParameters CreateSamplingParametersWithTags(Dictionary>(); + var tagList = new List>(); foreach (var tag in tags) { - tagList.Add(new KeyValuePair(tag.Key, tag.Value)); + tagList.Add(new KeyValuePair(tag.Key, tag.Value)); } return new SamplingParameters( @@ -65,10 +54,10 @@ internal static SamplingParameters CreateSamplingParametersWithTags(Dictionary>() + var resourceAttributes = new List> { - new KeyValuePair("service.name", serviceName), - new KeyValuePair("cloud.platform", cloudPlatform), + new("service.name", serviceName), + new("cloud.platform", cloudPlatform), }; return ResourceBuilder.CreateEmpty().AddAttributes(resourceAttributes).Build(); From 7990f06855e949dbfaeb881e6e9fa0c9198e839a Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 6 Sep 2023 19:11:33 -0700 Subject: [PATCH 0806/1499] [Instrumentation.Runtime] Release Runtime instrumentation version 1.5.1 (#1343) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 5e4e262ef3..b00428601e 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.5.1 + +Released 2023-Sep-06 + * Add a metric `process.runtime.dotnet.gc.duration` for total paused duration in GC for .NET 7 and greater versions ([#1239](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1239)) From ebc40a0326cdddb07337413eef2a2b4cb00231fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 7 Sep 2023 20:18:48 +0200 Subject: [PATCH 0807/1499] Bump OTel SDK/API to 1.6.0 (#1344) --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 3 +++ src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 2 ++ .../OpenTelemetry.Instrumentation.GrpcCore.csproj | 2 +- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 2 ++ src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 ++-- 25 files changed, 54 insertions(+), 32 deletions(-) diff --git a/build/Common.props b/build/Common.props index 0ad217d7e2..23c26c4c70 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,7 +35,7 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.5.1,2.0) + [1.6.0,2.0) [1.6.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 95c765fdf0..6648363039 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.5.1 of OpenTelemetry SDK. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Updates to 1.6.0 of OpenTelemetry SDK. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-alpha.2 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 79c46ad70e..fc9fe6fc35 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index cad40dcf22..ab3c6dee3c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry to 1.6.0 + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + * Added support for receiving tranmission failures via the `RegisterPayloadTransmittedCallback` API. ([#1309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1309)) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 1bc55d3b9c..8625decb38 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 123106331e..24187e865d 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updates to 1.6.0 of OpenTelemetry SDK. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + ## 1.3.0-beta.1 Released 2023-Aug-02 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index d082f2fbd7..e4c18b64f4 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -5,8 +5,8 @@ * Add LogToActivityEventConversionOptions.Filter callback ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) -* Update OpenTelemetry SDK version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 5ef11fa761..4435c22bc6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update `OpenTelemetry.Api` to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update `OpenTelemetry.Api` to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-rc9.9 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 2bbc9b4fb9..36ef3e4e21 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.5.1 of OpenTelemetry SDK. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Updates to 1.6.0 of OpenTelemetry SDK. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 30f981b720..fad5bc76af 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OpenTelemetry SDK package version to 1.5.1 - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Updated OpenTelemetry SDK package version to 1.6.0 + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index a19e674118..c6b9ff81d9 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -6,8 +6,8 @@ enable filtering of instrumentation. ([#1203](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1203)) -* Updated OpenTelemetry SDK package version to 1.5.1 - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Updated OpenTelemetry SDK package version to 1.6.0 + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.7 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 3d916e40a1..0feb5d5842 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry.Api to 1.6.0. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + ## 1.5.1-alpha.1 Released 2023-Jul-11 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 828d6ce0ca..9780b5871e 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -4,6 +4,8 @@ * Make the context propagation extraction case insensitive. ([#483](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/483)) +* Update OpenTelemetry.Api to 1.6.0. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index f00e38357f..8111db001c 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 460fcc9780..b27c06cc11 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel API version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OTel API version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.5.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index d93af5b3fe..6fcb6bdf0d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OpenTelemetry SDK to 1.5.1 - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Updated OpenTelemetry SDK to 1.6.0 + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Removes `AddOwinInstrumentation` method with default configure parameter. ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index da1fa454c7..fc435aeb3b 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry API to 1.5.1 - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OpenTelemetry API to 1.6.0 + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 0.5.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index d4fbd92dba..b31ff113c4 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.5.1. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OpenTelemetry.Api to 1.6.0. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-alpha.3 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index b00428601e..49cae6d79f 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry API to 1.6.0 + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + ## 1.5.1 Released 2023-Sep-06 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index bc017b3ad3..46ccedfb32 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OTel API version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OTel API version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-rc9.10 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 32365feb95..a73132691d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + ## 1.0.0-rc.12 Released 2023-Aug-30 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index bbc803c488..737f247228 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + ## 1.3.0-beta.1 Released 2023-Aug-02 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index e6d6b70e0e..7b86d73bf1 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Updates to 1.6.0 of OpenTelemetry SDK. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Suppress instrumentation for outgoing http call made to metadata service during `Detect()`. ([#1297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1297)) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 3e786badce..76f6218b5a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.5.1 of OpenTelemetry SDK. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Updates to 1.6.0 of OpenTelemetry SDK. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 18cbfef88b..36a41a1816 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -8,5 +8,5 @@ Initial release of `OpenTelemetry.Sampler.AWS`. ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091), [#1124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1124)) -* Update OpenTelemetry SDK version to `1.5.1`. - ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) From a5a584eded58230330f131cd15df453ac1da6e08 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 7 Sep 2023 11:41:35 -0700 Subject: [PATCH 0808/1499] [repo+ci] Use SDK dotnet format in CI (#1339) --- .github/workflows/dotnet-format.yml | 10 +- build/Common.prod.props | 1 - build/Common.props | 4 +- build/Common.targets | 4 - examples/AspNet/App_Start/RouteConfig.cs | 21 ++-- examples/AspNet/Controllers/HomeController.cs | 2 + .../Controllers/WeatherForecastController.cs | 32 +++-- examples/AspNet/Examples.AspNet.csproj | 76 +++--------- examples/AspNet/Global.asax.cs | 12 +- examples/AspNet/Properties/AssemblyInfo.cs | 28 ----- .../AspNet/Properties/launchSettings.json | 18 +++ examples/AspNet/Web.config | 114 +++++++++--------- examples/Directory.Build.props | 1 + opentelemetry-dotnet-contrib.sln | 7 ++ .../OpenTelemetry.Exporter.Geneva.csproj | 1 - .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 - ...OpenTelemetry.Exporter.OneCollector.csproj | 1 - .../OpenTelemetry.Extensions.csproj | 1 - ...metry.Instrumentation.EventCounters.csproj | 1 - .../OpenTelemetry.Instrumentation.Owin.csproj | 1 - ...enTelemetry.Instrumentation.Process.csproj | 1 - ...enTelemetry.Instrumentation.Runtime.csproj | 1 - ....Instrumentation.StackExchangeRedis.csproj | 1 - ...etry.PersistentStorage.Abstractions.csproj | 1 - ...enTelemetry.ResourceDetectors.Azure.csproj | 1 - .../AWSXRaySamplerClient.cs | 4 +- src/Shared/ExceptionExtensions.cs | 12 +- ...enTelemetry.Exporter.InfluxDB.Tests.csproj | 1 - ...ry.Exporter.OneCollector.Benchmarks.csproj | 1 - ...lemetry.Exporter.OneCollector.Tests.csproj | 1 - 30 files changed, 160 insertions(+), 200 deletions(-) create mode 100644 examples/AspNet/Properties/launchSettings.json diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index 48876d69ba..f9886e9f5e 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -23,8 +23,12 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v3 - - name: Install format tool - run: dotnet tool install -g dotnet-format + - name: Install dependencies + run: dotnet restore + + - name: Protobuf compile + run: dotnet build -t:Protobuf_Compile --no-restore + continue-on-error: true # Note: Projects without Grpc.Tools won't have the Protobuf_Compile target which generates an error - name: dotnet format - run: dotnet-format --folder --check + run: dotnet format opentelemetry-dotnet-contrib.sln --no-restore --verify-no-changes diff --git a/build/Common.prod.props b/build/Common.prod.props index f6cf6b8c54..45b492423b 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -13,7 +13,6 @@ $(MSBuildThisFileDirectory)/OpenTelemetryContrib.prod.ruleset $(NoWarn),1573,1712 $(Build_ArtifactStagingDirectory) - true Observability;OpenTelemetry;Monitoring;Telemetry diff --git a/build/Common.props b/build/Common.props index 23c26c4c70..f08449f33b 100644 --- a/build/Common.props +++ b/build/Common.props @@ -1,6 +1,6 @@ - 11.0 + latest true $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName) $(MSBuildThisFileDirectory)debug.snk @@ -10,7 +10,7 @@ net6.0 netstandard2.0 true - latest-All + latest-all diff --git a/build/Common.targets b/build/Common.targets index 556dd88d22..faf2349bae 100644 --- a/build/Common.targets +++ b/build/Common.targets @@ -1,7 +1,3 @@ - - latest-all - - diff --git a/examples/AspNet/App_Start/RouteConfig.cs b/examples/AspNet/App_Start/RouteConfig.cs index e1c6ae4df1..80575537f6 100644 --- a/examples/AspNet/App_Start/RouteConfig.cs +++ b/examples/AspNet/App_Start/RouteConfig.cs @@ -17,20 +17,19 @@ using System.Web.Mvc; using System.Web.Routing; -namespace Examples.AspNet +namespace Examples.AspNet; + +public class RouteConfig { - public class RouteConfig + public static void RegisterRoutes(RouteCollection routes) { - public static void RegisterRoutes(RouteCollection routes) - { - routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - routes.MapMvcAttributeRoutes(); + routes.MapMvcAttributeRoutes(); - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{id}", - defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }); - } + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }); } } diff --git a/examples/AspNet/Controllers/HomeController.cs b/examples/AspNet/Controllers/HomeController.cs index e8dd81a468..029e323ff0 100644 --- a/examples/AspNet/Controllers/HomeController.cs +++ b/examples/AspNet/Controllers/HomeController.cs @@ -21,11 +21,13 @@ namespace Examples.AspNet.Controllers; public class HomeController : Controller { // For testing traditional routing. Ex: https://localhost:XXXX/ + [HttpGet] public ActionResult Index() { return this.View(); } + [HttpGet] [Route("about_attr_route/{customerId}")] // For testing attribute routing. Ex: https://localhost:XXXX/about_attr_route public ActionResult About(int? customerId) { diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index 107c9e2bdf..1aa7e0870b 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -57,7 +57,7 @@ public async Task> Get(int customerId) { if (customerId < 0) { - throw new ArgumentException(); + throw new ArgumentOutOfRangeException(nameof(customerId), "CustomerId should be 0 or greater."); } // Making http calls here to serve as an example of @@ -141,7 +141,7 @@ private static async Task RequestGoogleHomPageViaHttpClient() { using var request = new HttpClient(); - using var response = await request.GetAsync("http://www.google.com").ConfigureAwait(false); + using var response = await request.GetAsync(new Uri("http://www.google.com")).ConfigureAwait(false); response.EnsureSuccessStatusCode(); } @@ -149,7 +149,7 @@ private static async Task RequestGoogleHomPageViaHttpClient() // Test dependency collection via legacy HttpWebRequest sync. private static void RequestGoogleHomPageViaHttpWebRequestLegacySync() { - var request = WebRequest.Create("http://www.google.com/?sync"); + var request = WebRequest.Create(new Uri("http://www.google.com/?sync")); using var response = request.GetResponse(); } @@ -157,7 +157,7 @@ private static void RequestGoogleHomPageViaHttpWebRequestLegacySync() // Test dependency collection via legacy HttpWebRequest async. private static async Task RequestGoogleHomPageViaHttpWebRequestLegacyAsync() { - var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); + var request = (HttpWebRequest)WebRequest.Create(new Uri("http://www.google.com/?async")); using var response = await request.GetResponseAsync().ConfigureAwait(false); } @@ -165,7 +165,7 @@ private static async Task RequestGoogleHomPageViaHttpWebRequestLegacyAsync() // Test dependency collection via legacy HttpWebRequest IAsyncResult. private static void RequestGoogleHomPageViaHttpWebRequestLegacyAsyncResult() { - var request = (HttpWebRequest)WebRequest.Create($"http://www.google.com/?async"); + var request = (HttpWebRequest)WebRequest.Create(new Uri("http://www.google.com/?async")); var asyncResult = request.BeginGetResponse(null, null); @@ -181,7 +181,9 @@ private async Task RequestInvalidViaHttpClient() // This request is not available over SSL and will throw a handshake exception. - using var response = await request.GetAsync(this.Url.Content("~/subroute/10").Replace("http", "https")).ConfigureAwait(false); + var requestUri = this.GenerateContentRequestUri("~/subroute/10", uri => uri.Replace("http", "https")); + + using var response = await request.GetAsync(requestUri).ConfigureAwait(false); Debug.Fail("Unreachable"); } @@ -197,7 +199,8 @@ private async Task RequestValidThatReturnsFailedViaHttpClient() // This request will return a 500 error because customerId should be >= 0; - using var response = await request.GetAsync(this.Url.Content("~/subroute/-1")).ConfigureAwait(false); + using var response = await request.GetAsync( + this.GenerateContentRequestUri("~/subroute/-1")).ConfigureAwait(false); Debug.Assert(response.StatusCode == HttpStatusCode.InternalServerError, "response.StatusCode is InternalServerError"); } @@ -209,8 +212,21 @@ private async Task RequestValidThatSpawnsSubSpansViaHttpClient() // This request will return successfully and cause a bunch of sub-spans; - using var response = await request.GetAsync(this.Url.Content("~/subroute/10")).ConfigureAwait(false); + using var response = await request.GetAsync( + this.GenerateContentRequestUri("~/subroute/10")).ConfigureAwait(false); response.EnsureSuccessStatusCode(); } + + private Uri GenerateContentRequestUri(string path, Func transform = null) + { + var rawUri = this.Url.Content(path); + + if (transform != null) + { + rawUri = transform(rawUri); + } + + return new(rawUri); + } } diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index a8a47cbb92..9443447544 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -1,46 +1,19 @@ - - + + - PackageReference - Debug - AnyCPU - - - 2.0 - {9A4E3A68-904B-4835-A3C8-F664B73098DB} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + net48 Library - Properties - OpenTelemetry.Exporter.AspNet - OpenTelemetry.Exporter.AspNet - v4.8 - true - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - true - pdbonly - true bin\ - TRACE - prompt - 4 + false + false + web.config + false + + + + + @@ -87,16 +60,13 @@ - - {582b70b5-0067-4d9a-abf2-623f502be9a9} - OpenTelemetry.Instrumentation.AspNet - + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + @@ -109,22 +79,4 @@ $(BuildDependsOn) SkipBuildWithoutVisualStudio - - - - - True - True - 0 - / - http://localhost:56171/ - False - False - - - False - - - - diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index 8250029c0d..3724b36df0 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -40,15 +40,15 @@ protected void Application_Start() .AddAspNetInstrumentation() .AddHttpClientInstrumentation(); - switch (ConfigurationManager.AppSettings["UseExporter"].ToLowerInvariant()) + switch (ConfigurationManager.AppSettings["UseExporter"].ToUpperInvariant()) { - case "zipkin": + case "ZIPKIN": builder.AddZipkinExporter(zipkinOptions => { zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]); }); break; - case "otlp": + case "OTLP": builder.AddOtlpExporter(otlpOptions => { otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); @@ -68,15 +68,15 @@ protected void Application_Start() var meterBuilder = Sdk.CreateMeterProviderBuilder() .AddAspNetInstrumentation(); - switch (ConfigurationManager.AppSettings["UseMetricsExporter"].ToLowerInvariant()) + switch (ConfigurationManager.AppSettings["UseMetricsExporter"].ToUpperInvariant()) { - case "otlp": + case "OTLP": meterBuilder.AddOtlpExporter(otlpOptions => { otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); }); break; - case "prometheus": + case "PROMETHEUS": meterBuilder.AddPrometheusHttpListener(); break; default: diff --git a/examples/AspNet/Properties/AssemblyInfo.cs b/examples/AspNet/Properties/AssemblyInfo.cs index 7dd41a41ac..81534e43a0 100644 --- a/examples/AspNet/Properties/AssemblyInfo.cs +++ b/examples/AspNet/Properties/AssemblyInfo.cs @@ -14,37 +14,9 @@ // limitations under the License. // -using System.Reflection; using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Examples.AspNet")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Examples.AspNet")] -[assembly: AssemblyCopyright("Copyright @ 2020")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("9a4e3a68-904b-4835-a3c8-f664b73098db")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/examples/AspNet/Properties/launchSettings.json b/examples/AspNet/Properties/launchSettings.json new file mode 100644 index 0000000000..9b068c43bb --- /dev/null +++ b/examples/AspNet/Properties/launchSettings.json @@ -0,0 +1,18 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:23307" + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index 9eebb5c685..936a551d10 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -1,58 +1,62 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/Directory.Build.props b/examples/Directory.Build.props index 1927158094..a55fcdde66 100644 --- a/examples/Directory.Build.props +++ b/examples/Directory.Build.props @@ -1,3 +1,4 @@ + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7afe8b2a4d..888c1a7765 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -291,6 +291,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.InfluxDB", "exampl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.AotCompatibility.TestApp", "test\OpenTelemetry.AotCompatibility.TestApp\OpenTelemetry.AotCompatibility.TestApp.csproj", "{31937862-0C88-41C0-AFD6-F97A7BF803A9}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B30F5FD-3309-49CB-9CAD-D3372FAFD796}" + ProjectSection(SolutionItems) = preProject + examples\Directory.Build.props = examples\Directory.Build.props + examples\Directory.Build.targets = examples\Directory.Build.targets + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -698,6 +704,7 @@ Global {2D354354-BAFB-490B-A26F-6A16A52A1A45} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} {31937862-0C88-41C0-AFD6-F97A7BF803A9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index cc864470ac..2561adb134 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -10,7 +10,6 @@ net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- - true true diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index c7929025cb..8a19e95c12 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -7,7 +7,6 @@ $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) Exporter.InfluxDB- - true true enable diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 2990eb9ae4..ec8132aeab 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -8,7 +8,6 @@ $(TargetFrameworks);net462 Exporter.OneCollector- enable - true true true diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index a012e9da7f..83d1393c8a 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -8,7 +8,6 @@ OpenTelemetry .NET SDK preview features and extensions Extensions- enable - true diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index a92edeb866..8195194ba8 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -4,7 +4,6 @@ OpenTelemetry Metrics instrumentation for Dotnet EventCounters $(PackageTags);metrics;eventcounters Instrumentation.EventCounters- - true enable diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 47748d2105..3467fd245a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -5,7 +5,6 @@ OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- - true diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index 49e32f3588..bf9335784d 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -4,7 +4,6 @@ dotnet process instrumentation for OpenTelemetry .NET $(PackageTags);process Instrumentation.Process- - true enable diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 06adbebe66..7d61ac0091 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,7 +5,6 @@ dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- - true enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index a82272a763..f03d885358 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -8,7 +8,6 @@ true Instrumentation.StackExchangeRedis- enable - true true diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index bd71e8127b..e3b9ef0fd6 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -10,7 +10,6 @@ PersistentStorage.Abstractions- $(NoWarn),1591 enable - true diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index 885c72ec9c..23795f6b4d 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -4,7 +4,6 @@ OpenTelemetry Resource Detectors for Azure cloud environments $(PackageTags);ResourceDetector ResourceDetectors.Azure- - true enable diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index 64b7649e8f..c89822cf8f 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -69,7 +69,7 @@ public async Task> GetSamplingRules() catch (Exception ex) { AWSSamplerEventSource.Log.FailedToDeserializeResponse( - nameof(AWSXRaySamplerClient.GetSamplingRules), + nameof(this.GetSamplingRules), ex.Message); } } @@ -98,7 +98,7 @@ public async Task> GetSamplingRules() catch (Exception ex) { AWSSamplerEventSource.Log.FailedToDeserializeResponse( - nameof(AWSXRaySamplerClient.GetSamplingTargets), + nameof(this.GetSamplingTargets), ex.Message); } diff --git a/src/Shared/ExceptionExtensions.cs b/src/Shared/ExceptionExtensions.cs index dea6a61c66..722d91aa75 100644 --- a/src/Shared/ExceptionExtensions.cs +++ b/src/Shared/ExceptionExtensions.cs @@ -16,7 +16,11 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled don't need System or System.Threading +using System; using System.Globalization; +using System.Threading; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Internal; @@ -28,18 +32,18 @@ internal static class ExceptionExtensions /// /// Exception to convert to string. /// Exception as string with no culture. - public static string ToInvariantString(this System.Exception exception) + public static string ToInvariantString(this Exception exception) { - var originalUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; + var originalUICulture = Thread.CurrentThread.CurrentUICulture; try { - System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; + Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; return exception.ToString(); } finally { - System.Threading.Thread.CurrentThread.CurrentUICulture = originalUICulture; + Thread.CurrentThread.CurrentUICulture = originalUICulture; } } } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 2f1e775e66..516a7a1156 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -6,7 +6,6 @@ $(NetMinimumSupportedVersion) $(TargetFrameworks);net48;net472;net471;net47;net462 enable - true true diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index 8e257e1321..c2e9b87580 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -7,7 +7,6 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 enable - true true diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index be7e96512f..8247c5e82d 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -6,7 +6,6 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 enable - true true From 895a9c7626ecad59b84d5886a5b82c547a209d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 8 Sep 2023 06:29:19 +0200 Subject: [PATCH 0809/1499] Nullable for ASP.NET instrumentation projects (#1336) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 16 ++++----- .../ActivityHelper.cs | 35 ++++++++----------- .../AspNetTelemetryEventSource.cs | 20 +++++------ ...entation.AspNet.TelemetryHttpModule.csproj | 1 + .../TelemetryHttpModule.cs | 4 +-- .../TelemetryHttpModuleOptions.cs | 6 ++-- .../.publicApi/net462/PublicAPI.Shipped.txt | 2 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 10 +++--- .../AspNetInstrumentationOptions.cs | 4 +-- .../Implementation/HttpInListener.cs | 4 +-- ...penTelemetry.Instrumentation.AspNet.csproj | 1 + .../TracerProviderBuilderExtensions.cs | 2 +- .../EventSourceTestHelper.cs | 7 ++-- .../InMemoryEventListener.cs | 2 ++ .../TestEventListener.cs | 8 +++-- .../ActivityHelperTest.cs | 34 +++++++++--------- .../HttpContextHelper.cs | 6 ++-- ...on.AspNet.TelemetryHttpModule.Tests.csproj | 1 + .../WebConfigTransformTest.cs | 2 +- .../WebConfigWithLocationTagTransformTest.cs | 2 +- .../BasicTests.cs | 4 +-- .../HttpInListenerTests.cs | 21 +++-------- .../HttpInMetricsListenerTests.cs | 4 +-- ...emetry.Instrumentation.AspNet.Tests.csproj | 1 + 25 files changed, 96 insertions(+), 102 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt index 367f7a1e6e..21ec8b6507 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,16 +1,16 @@ -const OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.AspNetActivityName = "Microsoft.AspNet.HttpReqIn" -> string -const OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry" -> string +const OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.AspNetActivityName = "Microsoft.AspNet.HttpReqIn" -> string! +const OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.AspNetSourceName = "OpenTelemetry.Instrumentation.AspNet.Telemetry" -> string! OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Dispose() -> void -OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Init(System.Web.HttpApplication context) -> void +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Init(System.Web.HttpApplication! context) -> void OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.TelemetryHttpModule() -> void OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions -OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnExceptionCallback.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnExceptionCallback.get -> System.Action? OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnExceptionCallback.set -> void -OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStartedCallback.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStartedCallback.get -> System.Action? OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStartedCallback.set -> void -OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStoppedCallback.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStoppedCallback.get -> System.Action? OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.OnRequestStoppedCallback.set -> void -OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.TextMapPropagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator +OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.TextMapPropagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator! OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions.TextMapPropagator.set -> void -static OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Options.get -> OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions +static OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Options.get -> OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions! diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index 7ef463ec8d..d76929ec0c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -50,10 +50,8 @@ internal static class ActivityHelper /// langword="null"/> if 1) start has not been called or 2) start was /// called but sampling decided not to create an instance. /// if start has been called. - public static bool HasStarted(HttpContext context, out Activity aspNetActivity) + public static bool HasStarted(HttpContext context, out Activity? aspNetActivity) { - Debug.Assert(context != null, "Context is null."); - object itemValue = context.Items[ContextKey]; if (itemValue is ContextHolder contextHolder) { @@ -72,13 +70,11 @@ public static bool HasStarted(HttpContext context, out Activity aspNetActivity) /// . /// Callback action. /// New root activity. - public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action onRequestStartedCallback) + public static Activity? StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action? onRequestStartedCallback) { - Debug.Assert(context != null, "Context is null."); - PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); - Activity activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext); + Activity? activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext); if (activity != null) { @@ -86,11 +82,11 @@ public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, { Baggage.Current = propagationContext.Baggage; - context.Items[ContextKey] = new ContextHolder { Activity = activity, Baggage = RuntimeContext.GetValue(BaggageSlotName) }; + context.Items[ContextKey] = new ContextHolder(activity, RuntimeContext.GetValue(BaggageSlotName)); } else { - context.Items[ContextKey] = new ContextHolder { Activity = activity }; + context.Items[ContextKey] = new ContextHolder(activity); } try @@ -120,10 +116,8 @@ public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, /// . /// Callback action. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activity aspNetActivity, HttpContext context, Action onRequestStoppedCallback) + public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activity? aspNetActivity, HttpContext context, Action? onRequestStoppedCallback) { - Debug.Assert(context != null, "Context is null."); - if (aspNetActivity == null) { Debug.Assert(context.Items[ContextKey] == StartedButNotSampledObj, "Context item is not StartedButNotSampledObj."); @@ -150,7 +144,7 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnStopped", callbackEx); } - AspNetTelemetryEventSource.Log.ActivityStopped(currentActivity); + AspNetTelemetryEventSource.Log.ActivityStopped(aspNetActivity); if (textMapPropagator is not TraceContextPropagator) { @@ -171,11 +165,8 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ /// . /// Callback action. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteActivityException(Activity aspNetActivity, HttpContext context, Exception exception, Action onExceptionCallback) + public static void WriteActivityException(Activity? aspNetActivity, HttpContext context, Exception exception, Action? onExceptionCallback) { - Debug.Assert(context != null, "Context is null."); - Debug.Assert(exception != null, "Exception is null."); - if (aspNetActivity != null) { try @@ -201,8 +192,6 @@ public static void WriteActivityException(Activity aspNetActivity, HttpContext c [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void RestoreContextIfNeeded(HttpContext context) { - Debug.Assert(context != null, "Context is null."); - if (context.Items[ContextKey] is ContextHolder contextHolder && Activity.Current != contextHolder.Activity) { Activity.Current = contextHolder.Activity; @@ -218,6 +207,12 @@ internal static void RestoreContextIfNeeded(HttpContext context) internal sealed class ContextHolder { public Activity Activity; - public object Baggage; + public object? Baggage; + + public ContextHolder(Activity activity, object? baggage = null) + { + this.Activity = activity; + this.Baggage = baggage; + } } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs index 78f6cdb02c..5b82fb5eda 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs @@ -37,7 +37,7 @@ public void ActivityStarted(Activity activity) { if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) { - this.ActivityStarted(activity?.Id); + this.ActivityStarted(activity.Id); } } @@ -46,7 +46,7 @@ public void ActivityStopped(Activity activity) { if (this.IsEnabled(EventLevel.Verbose, EventKeywords.All)) { - this.ActivityStopped(activity?.Id); + this.ActivityStopped(activity.Id); } } @@ -55,7 +55,7 @@ public void ActivityRestored(Activity activity) { if (this.IsEnabled(EventLevel.Informational, EventKeywords.All)) { - this.ActivityRestored(activity?.Id); + this.ActivityRestored(activity.Id); } } @@ -64,7 +64,7 @@ public void ActivityException(Activity activity, Exception ex) { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.ActivityException(activity?.Id, ex.ToInvariantString()); + this.ActivityException(activity.Id, ex.ToInvariantString()); } } @@ -73,7 +73,7 @@ public void CallbackException(Activity activity, string eventName, Exception ex) { if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) { - this.CallbackException(activity?.Id, eventName, ex.ToInvariantString()); + this.CallbackException(activity.Id, eventName, ex.ToInvariantString()); } } @@ -84,19 +84,19 @@ public void TraceCallback(string callback) } [Event(2, Message = "Activity started, Id='{0}'", Level = EventLevel.Verbose)] - public void ActivityStarted(string id) + public void ActivityStarted(string? id) { this.WriteEvent(2, id); } [Event(3, Message = "Activity stopped, Id='{0}'", Level = EventLevel.Verbose)] - public void ActivityStopped(string id) + public void ActivityStopped(string? id) { this.WriteEvent(3, id); } [Event(4, Message = "Activity restored, Id='{0}'", Level = EventLevel.Informational)] - public void ActivityRestored(string id) + public void ActivityRestored(string? id) { this.WriteEvent(4, id); } @@ -108,13 +108,13 @@ public void OnExecuteRequestStepInvocationError(string error) } [Event(6, Message = "Activity exception, Id='{0}': {1}", Level = EventLevel.Error)] - public void ActivityException(string id, string ex) + public void ActivityException(string? id, string ex) { this.WriteEvent(6, id, ex); } [Event(7, Message = "Callback exception, Id='{0}', Name='{1}': {2}", Level = EventLevel.Error)] - public void CallbackException(string id, string eventName, string ex) + public void CallbackException(string? id, string eventName, string ex) { this.WriteEvent(7, id, eventName, ex); } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 395a6adc25..95a86afd97 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -6,6 +6,7 @@ A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI Instrumentation.AspNet.TelemetryHttpModule- + enable diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index 2ad4514574..ed23433fff 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -98,7 +98,7 @@ private void Application_EndRequest(object sender, EventArgs e) var context = ((HttpApplication)sender).Context; - if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) + if (!ActivityHelper.HasStarted(context, out Activity? aspNetActivity)) { // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. @@ -133,7 +133,7 @@ private void Application_Error(object sender, EventArgs e) var exception = context.Error; if (exception != null) { - if (!ActivityHelper.HasStarted(context, out Activity aspNetActivity)) + if (!ActivityHelper.HasStarted(context, out Activity? aspNetActivity)) { aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs index 00be9abcae..d71f8d19e2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs @@ -51,16 +51,16 @@ public TextMapPropagator TextMapPropagator /// /// Gets or sets a callback action to be fired when a request is started. /// - public Action OnRequestStartedCallback { get; set; } + public Action? OnRequestStartedCallback { get; set; } /// /// Gets or sets a callback action to be fired when a request is stopped. /// - public Action OnRequestStoppedCallback { get; set; } + public Action? OnRequestStoppedCallback { get; set; } /// /// Gets or sets a callback action to be fired when an unhandled /// exception is thrown processing a request. /// - public Action OnExceptionCallback { get; set; } + public Action? OnExceptionCallback { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt index 5f282702bb..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt @@ -1 +1 @@ - \ No newline at end of file +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt index 9b53ae2ee5..b2fd0825bd 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,13 +1,13 @@ OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.AspNetInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.get -> System.Func? OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs index 50ded07c2c..f2c486e2d5 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs @@ -39,7 +39,7 @@ public class AspNetInstrumentationOptions /// exception the request is filtered out (NOT collected). /// /// - public Func Filter { get; set; } + public Func? Filter { get; set; } /// /// Gets or sets an action to enrich an Activity. @@ -50,7 +50,7 @@ public class AspNetInstrumentationOptions /// object: the raw object from which additional information can be extracted to enrich the activity. /// The type of this object depends on the event, which is given by the above parameter. /// - public Action Enrich { get; set; } + public Action? Enrich { get; set; } /// /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index a8c1ddb9a4..09d1783253 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -135,7 +135,7 @@ private void OnStopActivity(Activity activity, HttpContext context) var routeData = context.Request.RequestContext.RouteData; - string template = null; + string? template = null; if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) { // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. @@ -157,7 +157,7 @@ private void OnStopActivity(Activity activity, HttpContext context) if (!string.IsNullOrEmpty(template)) { // Override the name that was previously set to the path part of URL. - activity.DisplayName = template; + activity.DisplayName = template!; activity.SetTag(SemanticConventions.AttributeHttpRoute, template); } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 3072fd37da..ac57a8259f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -7,6 +7,7 @@ $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true Instrumentation.AspNet- + enable diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs index eec9f981cf..3394dcc287 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -41,7 +41,7 @@ public static TracerProviderBuilder AddAspNetInstrumentation(this TracerProvider /// The instance of to chain the calls. public static TracerProviderBuilder AddAspNetInstrumentation( this TracerProviderBuilder builder, - Action configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs index 2c9f2f9578..3b93d7d67a 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics.Tracing; @@ -42,9 +44,7 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn object[] eventArguments = GenerateEventArguments(eventMethod); eventMethod.Invoke(eventSource, eventArguments); - EventWrittenEventArgs actualEvent = null; - - actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); + var actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); VerifyEventId(eventMethod, actualEvent); VerifyEventLevel(eventMethod, actualEvent); @@ -115,6 +115,7 @@ private static void VerifyEventMessage(MethodInfo eventMethod, EventWrittenEvent } private static void AssertEqual(string methodName, T expected, T actual) + where T : notnull { if (!expected.Equals(actual)) { diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs index 0799387e56..4e4f6683d0 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System.Collections.Concurrent; using System.Diagnostics.Tracing; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs index 7bd3d7fc36..a63680a5bb 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs @@ -14,6 +14,8 @@ // limitations under the License. // +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics.Tracing; @@ -49,7 +51,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; } @@ -90,8 +92,8 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) /// The event source that was created. protected override void OnEventSourceCreated(EventSource eventSource) { - // Check for null because this method is called by the base class constror before we can initialize it - Action callback = this.OnOnEventSourceCreated; + // Check for null because this method is called by the base class constructor before we can initialize it + Action? callback = this.OnOnEventSourceCreated; callback?.Invoke(eventSource); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index f491020cd4..5b229b3fb2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -35,7 +35,7 @@ public class ActivityHelperTest : IDisposable private const string BaggageInHeader = "TestKey1=123,TestKey2=456,TestKey1=789"; private const string TestActivityName = "Activity.Test"; private readonly TextMapPropagator noopTextMapPropagator = new NoopTextMapPropagator(); - private ActivityListener activitySourceListener; + private ActivityListener? activitySourceListener; public void Dispose() { @@ -47,7 +47,7 @@ public void Has_Started_Returns_Correctly() { var context = HttpContextHelper.GetFakeHttpContext(); - bool result = ActivityHelper.HasStarted(context, out Activity aspNetActivity); + bool result = ActivityHelper.HasStarted(context, out Activity? aspNetActivity); Assert.False(result); Assert.Null(aspNetActivity); @@ -60,7 +60,7 @@ public void Has_Started_Returns_Correctly() Assert.Null(aspNetActivity); Activity activity = new Activity(TestActivityName); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = activity }; + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder(activity); result = ActivityHelper.HasStarted(context, out aspNetActivity); @@ -74,7 +74,7 @@ public async Task Can_Restore_Activity() { this.EnableListener(); var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; rootActivity.AddTag("k1", "v1"); rootActivity.AddTag("k2", "v2"); @@ -107,7 +107,7 @@ public async Task Can_Restore_Baggage() }; var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null)!; rootActivity.AddTag("k1", "v1"); rootActivity.AddTag("k2", "v2"); @@ -146,7 +146,7 @@ public void Can_Stop_Lost_Activity() Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); }); var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; rootActivity.AddTag("k1", "v1"); rootActivity.AddTag("k2", "v2"); @@ -174,7 +174,7 @@ public void Do_Not_Restore_Activity_When_It_Is_Not_Lost() var root = new Activity("root").Start(); var context = HttpContextHelper.GetFakeHttpContext(); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = root }; + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder(root); ActivityHelper.RestoreContextIfNeeded(context); @@ -187,7 +187,7 @@ public void Can_Stop_Activity_Without_AspNetListener_Enabled() var context = HttpContextHelper.GetFakeHttpContext(); var rootActivity = new Activity(TestActivityName); rootActivity.Start(); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder(rootActivity); Thread.Sleep(100); ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); @@ -202,7 +202,7 @@ public void Can_Stop_Activity_With_AspNetListener_Enabled() var context = HttpContextHelper.GetFakeHttpContext(); var rootActivity = new Activity(TestActivityName); rootActivity.Start(); - context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder { Activity = rootActivity }; + context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder(rootActivity); Thread.Sleep(100); this.EnableListener(); ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, null); @@ -217,7 +217,7 @@ public void Can_Stop_Root_Activity_With_All_Children() { this.EnableListener(); var context = HttpContextHelper.GetFakeHttpContext(); - using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; var child = new Activity("child").Start(); new Activity("grandchild").Start(); @@ -251,7 +251,7 @@ public async Task Can_Stop_Root_Activity_If_It_Is_Broken() { this.EnableListener(); var context = HttpContextHelper.GetFakeHttpContext(); - using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; new Activity("child").Start(); for (int i = 0; i < 2; i++) @@ -259,7 +259,7 @@ public async Task Can_Stop_Root_Activity_If_It_Is_Broken() await Task.Run(() => { // when we enter this method, Current is 'child' activity - Activity.Current.Stop(); + Activity.Current!.Stop(); // here Current is 'parent', but only in this execution context }); @@ -281,7 +281,7 @@ public void Stop_Root_Activity_With_129_Nesting_Depth() { this.EnableListener(); var context = HttpContextHelper.GetFakeHttpContext(); - using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null); + using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; for (int i = 0; i < 129; i++) { @@ -447,7 +447,7 @@ public void Fire_Exception_Events() Assert.Equal(1, callbacksFired); } - private void EnableListener(Action onStarted = null, Action onStopped = null, Func onSample = null) + private void EnableListener(Action? onStarted = null, Action? onStopped = null, Func? onSample = null) { Debug.Assert(this.activitySourceListener == null, "Cannot attach multiple listeners in tests."); @@ -512,7 +512,7 @@ private class TestHttpContext : HttpContextBase { private readonly Hashtable items; - public TestHttpContext(Exception error = null) + public TestHttpContext(Exception? error = null) { this.Server = new TestHttpServerUtility(this); this.items = new Hashtable(); @@ -524,14 +524,14 @@ public TestHttpContext(Exception error = null) /// public override IDictionary Items => this.items; - public override Exception Error { get; } + public override Exception? Error { get; } public override HttpServerUtilityBase Server { get; } } private class NoopTextMapPropagator : TextMapPropagator { - public override ISet Fields => null; + public override ISet? Fields => null; public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs index b39a654aa9..cfb810f497 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -25,7 +25,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; internal class HttpContextHelper { - public static HttpContext GetFakeHttpContext(string page = "/page", string query = "", IDictionary headers = null) + public static HttpContext GetFakeHttpContext(string page = "/page", string query = "", IDictionary? headers = null) { Thread.GetDomain().SetData(".appPath", string.Empty); Thread.GetDomain().SetData(".appVPath", string.Empty); @@ -36,7 +36,7 @@ public static HttpContext GetFakeHttpContext(string page = "/page", string query return context; } - public static HttpContextBase GetFakeHttpContextBase(string page = "/page", string query = "", IDictionary headers = null) + public static HttpContextBase GetFakeHttpContextBase(string page = "/page", string query = "", IDictionary? headers = null) { var context = GetFakeHttpContext(page, query, headers); return new HttpContextWrapper(context); @@ -46,7 +46,7 @@ private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest { private readonly IDictionary headers; - public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary headers) + public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary? headers) : base(page, query, output) { if (headers != null) diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index c68c2175a8..343bc3c447 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -3,6 +3,7 @@ Unit test project for ASP.NET HttpModule $(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs index e64c93868d..52a4ec2a39 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs @@ -384,7 +384,7 @@ private void VerifyTransformation(string expectedConfigContent, XDocument transf private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) { XDocument result; - Stream stream = null; + Stream? stream = null; try { stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs index 7e39fc8ee4..9d7b28ec39 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -414,7 +414,7 @@ private void VerifyTransformation(string expectedConfigContent, XDocument transf private XDocument ApplyTransformation(string originalConfiguration, string transformationResourceName) { XDocument result; - Stream stream = null; + Stream? stream = null; try { stream = typeof(WebConfigTransformTest).Assembly.GetManifestResourceStream(transformationResourceName); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs index 431f52f995..1a0ba83dc4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs @@ -25,7 +25,7 @@ public class BasicTests [Fact] public void AddAspNetInstrumentation_BadArgs() { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddAspNetInstrumentation()); + TracerProviderBuilder? builder = null; + Assert.Throws(() => builder!.AddAspNetInstrumentation()); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 70d477c627..3cb163eed8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -55,10 +55,9 @@ public void AspNetRequestsAreCollectedSuccessfully( int routeType, string routeTemplate, bool setStatusToErrorInEnrich = false, - string filter = null, + string? filter = null, bool recordException = false) { - IDisposable tracerProvider = null; RouteData routeData; switch (routeType) { @@ -93,16 +92,6 @@ public void AspNetRequestsAreCollectedSuccessfully( throw new NotSupportedException(); } - var workerRequest = new Mock(); - workerRequest.Setup(wr => wr.GetKnownRequestHeader(It.IsAny())).Returns(i => - { - return i switch - { - 39 => "Test", // User-Agent - _ => null, - }; - }); - HttpContext.Current = new HttpContext( new HttpRequest(string.Empty, url, string.Empty) { @@ -113,17 +102,17 @@ public void AspNetRequestsAreCollectedSuccessfully( }, new HttpResponse(new StringWriter())); - typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, workerRequest.Object); + typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, Mock.Of()); List exportedItems = new List(16); Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); - using (tracerProvider = Sdk.CreateTracerProviderBuilder() + using (Sdk.CreateTracerProviderBuilder() .AddAspNetInstrumentation((options) => { options.Filter = httpContext => { - Assert.True(Activity.Current.IsAllDataRequested); + Assert.True(Activity.Current!.IsAllDataRequested); if (string.IsNullOrEmpty(filter)) { return true; @@ -153,7 +142,7 @@ public void AspNetRequestsAreCollectedSuccessfully( Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); } - Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current.OperationName); + Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current!.OperationName); if (recordException) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index 8ba1903aa2..cd458aad73 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -79,9 +79,9 @@ public void HttpDurationMetricIsEmitted() Assert.Equal(duration, sum); Assert.Equal(3, metricPoints[0].Tags.Count); - string httpMethod = null; + string? httpMethod = null; int httpStatusCode = 0; - string httpScheme = null; + string? httpScheme = null; foreach (var tag in metricPoints[0].Tags) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index f59b1e785e..66d205fa8f 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -3,6 +3,7 @@ Unit test project for OpenTelemetry ASP.NET instrumentation $(NetFrameworkMinimumSupportedVersion) + enable From c4784de26bc6c061dc87a79189e6bedc90c2cdc6 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 8 Sep 2023 15:56:39 -0700 Subject: [PATCH 0810/1499] [Exporter.Geneva] Update OTel SDK version and CHANGELOG for 1.6.0 release (#1346) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 +++++++ .../Common.GenevaExporter.props | 2 +- .../GenevaMetricExporterTests.cs | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index decb1da578..58df50d08c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.6.0 + +Released 2023-Sep-09 + +* Update OpenTelemetry SDK version to `1.6.0`. + ([#1346](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1346)) + ## 1.6.0-rc.1 Released 2023-Aug-28 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 78181066e1..5570a7a1fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestPrereleaseVersion) + $(OpenTelemetryCoreLatestVersion) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 74675312fb..cf6b224834 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -358,7 +358,9 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars if (hasExemplars) { +#if EXPOSE_EXPERIMENTAL_FEATURES meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); +#endif } if (hasFilteredTagsForExemplars) @@ -1291,7 +1293,10 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; +#if EXPOSE_EXPERIMENTAL_FEATURES var exemplars = metricPoint.GetExemplars(); +#endif + UserdataV2 result = null; if (metricType == MetricType.LongSum) From 630667b412b7db4b3298384c99a403b3963ab543 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sun, 10 Sep 2023 21:30:16 -0700 Subject: [PATCH 0811/1499] [onecollector] Remove ext.dt.traceFlags (#1345) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ .../Serialization/LogRecordCommonSchemaJsonSerializer.cs | 8 ++++++-- .../LogRecordCommonSchemaJsonSerializerTests.cs | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index ab3c6dee3c..8b7b8b531b 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -18,6 +18,10 @@ `{OriginalFormat}` key or `LogRecord.Body`). ([#1321](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1321)) +* Removed `traceFlags` from the common schema `dt` (Distributed Tracing) + extension because it is not currently supported by the OneCollector service. + ([#1345](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1345)) + ## 1.5.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 7c4f80351d..515ac6d4c1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -32,7 +32,6 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText DistributedTraceExtensionProperty = JsonEncodedText.Encode("dt"); private static readonly JsonEncodedText DistributedTraceExtensionTraceIdProperty = JsonEncodedText.Encode("traceId"); private static readonly JsonEncodedText DistributedTraceExtensionSpanIdProperty = JsonEncodedText.Encode("spanId"); - private static readonly JsonEncodedText DistributedTraceExtensionTraceFlagsProperty = JsonEncodedText.Encode("traceFlags"); private static readonly JsonEncodedText ExceptionExtensionProperty = JsonEncodedText.Encode("ex"); private static readonly JsonEncodedText ExceptionExtensionTypeProperty = JsonEncodedText.Encode("type"); private static readonly JsonEncodedText ExceptionExtensionMessageProperty = JsonEncodedText.Encode("msg"); @@ -215,7 +214,12 @@ private void SerializeExtensionPropertiesToJson(LogRecord item, Utf8JsonWriter w writer.WriteStartObject(DistributedTraceExtensionProperty); writer.WriteString(DistributedTraceExtensionTraceIdProperty, item.TraceId.ToHexString()); writer.WriteString(DistributedTraceExtensionSpanIdProperty, item.SpanId.ToHexString()); - writer.WriteNumber(DistributedTraceExtensionTraceFlagsProperty, (int)item.TraceFlags); + /* + * Note: OneCollector does not currently support traceFlags. See: + * https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1313 + * + * writer.WriteNumber(DistributedTraceExtensionTraceFlagsProperty, (int)item.TraceFlags); + */ writer.WriteEndObject(); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index cabe61439a..22386f8a10 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -209,7 +209,7 @@ public void LogRecordTraceContextJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}},\"ext\":{{\"dt\":{{\"traceId\":\"{traceId}\",\"spanId\":\"{spanId}\",\"traceFlags\":1}}}}}}\n", + $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}},\"ext\":{{\"dt\":{{\"traceId\":\"{traceId}\",\"spanId\":\"{spanId}\"}}}}}}\n", json); } From 6f916314228fdeedfd751947cd59f1eb07091d69 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 14 Sep 2023 16:21:52 -0700 Subject: [PATCH 0812/1499] [OneCollector] Integration tests prep (#1348) --- .../ci-Exporter.OneCollector-Integration.yml | 57 +++++++++++++++++++ .../OpenTelemetry.Exporter.OneCollector.proj | 27 +++++++++ opentelemetry-dotnet-contrib.sln | 10 +++- 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-Exporter.OneCollector-Integration.yml create mode 100644 build/Projects/OpenTelemetry.Exporter.OneCollector.proj diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml new file mode 100644 index 0000000000..fe720463a2 --- /dev/null +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -0,0 +1,57 @@ +name: Integration Build OpenTelemetry.Exporter.OneCollector + +permissions: + contents: read + +on: + pull_request_target: # Allows secret access from forks see: https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/#improvements-for-public-repository-forks + branches: [ 'main*', 'exporter*' ] + paths: + - '*/OpenTelemetry.Exporter.OneCollector*/**' + - 'build/**' + - '!**.md' + +env: + PROJECT: OpenTelemetry.Exporter.OneCollector + +jobs: + authorize: + environment: # Run external PRs from forks on the "external"" environment which requires approval + ${{ github.event_name == 'pull_request_target' && + github.event.pull_request.head.repo.full_name != github.repository && + 'external' || 'internal' }} + runs-on: ubuntu-latest + steps: + - run: echo ✓ + + build-integration-test: + needs: authorize + + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + os: [ windows-latest, ubuntu-latest ] + version: [ net462, net6.0, net7.0 ] + exclude: + - os: ubuntu-latest + version: net462 + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha || github.ref }} # Run on the fork branch once approved + + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + + - name: dotnet restore build/Projects/${{env.PROJECT}}.proj + run: dotnet restore build/Projects/${{env.PROJECT}}.proj + + - name: dotnet build build/Projects/${{env.PROJECT}}.proj + run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore + + - name: dotnet test test/${{env.PROJECT}}.Tests + run: dotnet test test/${{env.PROJECT}}.Tests --filter CategoryName=OneCollectorIntegrationTests --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" + env: + OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY: ${{ secrets.OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY }} diff --git a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj new file mode 100644 index 0000000000..e821e8f5e0 --- /dev/null +++ b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj @@ -0,0 +1,27 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 888c1a7765..26a25d4d9f 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml + .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml + .github\workflows\ci-Instrumentation.Process.yml = .github\workflows\ci-Instrumentation.Process.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml .github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml @@ -205,7 +207,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNet", "AspNet", "{2B6D0764-5E66-423A-9943-B3A72FF181EA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.AspNet", "examples\AspNet\Examples.AspNet.csproj", "{9A4E3A68-904B-4835-A3C8-F664B73098DB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.AspNet", "examples\AspNet\Examples.AspNet.csproj", "{9A4E3A68-904B-4835-A3C8-F664B73098DB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "runtime-instrumentation", "examples\runtime-instrumentation\runtime-instrumentation.csproj", "{9FF9B46A-AD93-4B3F-92DA-6FDCC98FEA91}" EndProject @@ -297,6 +299,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B examples\Directory.Build.targets = examples\Directory.Build.targets EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{D1D1B96A-77E5-443E-8B5C-93D6CE5F5337}" + ProjectSection(SolutionItems) = preProject + build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -705,6 +712,7 @@ Global {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} {31937862-0C88-41C0-AFD6-F97A7BF803A9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {D1D1B96A-77E5-443E-8B5C-93D6CE5F5337} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From 2960a9defbe35ae14acc3b0b00983d09b186d61a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 15 Sep 2023 06:51:32 +0200 Subject: [PATCH 0813/1499] Nullable by default (#1349) --- build/Common.props | 1 + examples/AspNet/Examples.AspNet.csproj | 1 + .../Examples.InfluxDB.csproj | 1 - .../Examples.Enrichment.csproj | 1 - .../Examples.EventCounters.csproj | 1 - .../Examples.GrpcCore.AspNetCore.csproj | 1 + examples/owin/Examples.Owin.csproj | 1 + .../process-instrumentation.csproj | 1 - .../Examples.StackExchangeRedis.csproj | 1 - .../runtime-instrumentation.csproj | 1 - .../wcf/shared/Examples.Wcf.Shared.csproj | 1 + .../OpenTelemetry.Exporter.Geneva.csproj | 1 + .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 - .../OpenTelemetry.Exporter.Instana.csproj | 1 + ...OpenTelemetry.Exporter.OneCollector.csproj | 1 - .../OpenTelemetry.Exporter.Stackdriver.csproj | 1 - .../OpenTelemetry.Extensions.AWS.csproj | 1 - ...OpenTelemetry.Extensions.Enrichment.csproj | 1 - .../OpenTelemetry.Extensions.csproj | 1 - .../OpenTelemetry.Instrumentation.AWS.csproj | 1 - ...Telemetry.Instrumentation.AWSLambda.csproj | 1 - ...entation.AspNet.TelemetryHttpModule.csproj | 1 - ...penTelemetry.Instrumentation.AspNet.csproj | 1 - ...Telemetry.Instrumentation.Cassandra.csproj | 1 - ...Instrumentation.ElasticsearchClient.csproj | 1 + ...Instrumentation.EntityFrameworkCore.csproj | 1 + ...metry.Instrumentation.EventCounters.csproj | 1 - ...nTelemetry.Instrumentation.GrpcCore.csproj | 3 +- ...nTelemetry.Instrumentation.Hangfire.csproj | 1 + .../OpenTelemetry.Instrumentation.Owin.csproj | 1 + ...enTelemetry.Instrumentation.Process.csproj | 1 - ...penTelemetry.Instrumentation.Quartz.csproj | 1 - ...enTelemetry.Instrumentation.Runtime.csproj | 1 - ....Instrumentation.StackExchangeRedis.csproj | 1 - .../OpenTelemetry.Instrumentation.Wcf.csproj | 1 + ...etry.PersistentStorage.Abstractions.csproj | 1 - ...emetry.PersistentStorage.FileSystem.csproj | 1 - ...OpenTelemetry.ResourceDetectors.AWS.csproj | 1 - ...enTelemetry.ResourceDetectors.Azure.csproj | 1 - ...lemetry.ResourceDetectors.Container.csproj | 1 - .../OpenTelemetry.Sampler.AWS.csproj | 1 - ...Telemetry.Exporter.Geneva.Benchmark.csproj | 1 + ...penTelemetry.Exporter.Geneva.Stress.csproj | 1 + ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 + ...enTelemetry.Exporter.InfluxDB.Tests.csproj | 1 - ...penTelemetry.Exporter.Instana.Tests.csproj | 1 + ...ry.Exporter.OneCollector.Benchmarks.csproj | 1 - ...lemetry.Exporter.OneCollector.Tests.csproj | 1 - ...elemetry.Exporter.Stackdriver.Tests.csproj | 1 - ...lemetry.Extensions.Enrichment.Tests.csproj | 1 + .../OpenTelemetry.Extensions.Tests.csproj | 1 + ...Telemetry.Instrumentation.AWS.Tests.csproj | 1 - ...try.Instrumentation.AWSLambda.Tests.csproj | 1 - ...on.AspNet.TelemetryHttpModule.Tests.csproj | 1 - ...emetry.Instrumentation.AspNet.Tests.csproj | 1 - ...try.Instrumentation.Cassandra.Tests.csproj | 1 - ...mentation.ElasticsearchClient.Tests.csproj | 1 + ...mentation.EntityFrameworkCore.Tests.csproj | 1 + ...Instrumentation.EventCounters.Tests.csproj | 1 + ...etry.Instrumentation.GrpcCore.Tests.csproj | 1 + ...elemetry.Instrumentation.Owin.Tests.csproj | 1 + ...metry.Instrumentation.Process.Tests.csproj | 1 - ...emetry.Instrumentation.Quartz.Tests.csproj | 1 - ...metry.Instrumentation.Runtime.Tests.csproj | 1 - ...umentation.StackExchangeRedis.Tests.csproj | 1 + ...Telemetry.Instrumentation.Wcf.Tests.csproj | 1 + ....PersistentStorage.FileSystem.Tests.csproj | 1 - .../AWSECSResourceDetectorTests.cs | 2 +- ...erverCertificateValidationProviderTests.cs | 8 +- .../ContainerResourceDetectorTests.cs | 158 ++++++++---------- .../OpenTelemetry.Sampler.AWS.Tests.csproj | 1 - 71 files changed, 103 insertions(+), 135 deletions(-) diff --git a/build/Common.props b/build/Common.props index f08449f33b..84556f1c15 100644 --- a/build/Common.props +++ b/build/Common.props @@ -11,6 +11,7 @@ netstandard2.0 true latest-all + enable diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 9443447544..124834cd10 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -8,6 +8,7 @@ false web.config false + disable diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj index f81e86dc4c..474a3c5601 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -4,7 +4,6 @@ Exe net7.0 enable - enable Examples.InfluxDB diff --git a/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj b/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj index 0729f1a64b..b3b1885099 100644 --- a/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj +++ b/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj @@ -3,7 +3,6 @@ Exe net6.0 - enable diff --git a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj index 29ed2fe979..3cca08e4b8 100644 --- a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj +++ b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj @@ -4,7 +4,6 @@ Exe net6.0 enable - enable diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 8053b78dba..17f9f6cb76 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -2,6 +2,7 @@ net6.0 + disable diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index 228382acc7..8026fa8ae6 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -3,6 +3,7 @@ Exe net462 + disable diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj index 5316d175bc..6bfd042d9f 100644 --- a/examples/process-instrumentation/process-instrumentation.csproj +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -3,7 +3,6 @@ Exe net6.0 enable - enable diff --git a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj index b4770eaf60..020e4c48c1 100644 --- a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj +++ b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj @@ -4,7 +4,6 @@ Exe net6.0 enable - enable diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index 2aa4271dbc..5cd0c50b61 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -3,7 +3,6 @@ net6.0 Exe enable - enable diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index 265744f7ed..fa00098a8c 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -3,6 +3,7 @@ netstandard2.0;net462 + disable diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 2561adb134..d17c1b3ee3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -11,6 +11,7 @@ $(TargetFrameworks);net462 Exporter.Geneva- true + disable diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index 8a19e95c12..eed0b38f43 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -8,7 +8,6 @@ $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) Exporter.InfluxDB- true - enable diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 6afb43a629..aa210ce942 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -7,6 +7,7 @@ Instana .NET Exporter for OpenTelemetry Exporter.Instana- true + disable diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index ec8132aeab..131227e781 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -7,7 +7,6 @@ net7.0;net6.0;netstandard2.1;netstandard2.0 $(TargetFrameworks);net462 Exporter.OneCollector- - enable true true diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 515cde9d2a..025d4ddd29 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -6,7 +6,6 @@ $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- true - enable diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index 9f6f6adb14..ce76f33559 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -5,7 +5,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Extensions.AWS- - enable true diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index ffab6b1f36..a21b4f78d3 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -5,7 +5,6 @@ OpenTelemetry .NET SDK telemetry enrichment. $(NoWarn),CS1591 Extensions.Enrichment- - enable latest-all diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 83d1393c8a..e05f2a585e 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -7,7 +7,6 @@ true OpenTelemetry .NET SDK preview features and extensions Extensions- - enable diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index 0e7ed6969d..45935518a7 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -6,7 +6,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) AWS client instrumentation for OpenTelemetry .NET Instrumentation.AWS- - enable diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 179471dc3f..be934118fc 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -5,7 +5,6 @@ AWS Lambda tracing wrapper for OpenTelemetry .NET $(PackageTags);AWS Lambda Instrumentation.AWSLambda- - enable diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 95a86afd97..395a6adc25 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -6,7 +6,6 @@ A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI Instrumentation.AspNet.TelemetryHttpModule- - enable diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index ac57a8259f..3072fd37da 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -7,7 +7,6 @@ $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true Instrumentation.AspNet- - enable diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index fb51ba0d92..c1e28dd741 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -5,7 +5,6 @@ OpenTelemetry Cassandra Instrumentation $(PackageTags);Cassandra;CassandraCSharpDriver Instrumentation.Cassandra- - enable diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 167a22babb..4e66b4fe4c 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -7,6 +7,7 @@ Instrumentation.ElasticsearchClient- true true + disable diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 96eaf37e4f..3906fcc898 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -6,6 +6,7 @@ Instrumentation.EntityFrameworkCore- true true + disable diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 8195194ba8..8b7a31dc0d 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -4,7 +4,6 @@ OpenTelemetry Metrics instrumentation for Dotnet EventCounters $(PackageTags);metrics;eventcounters Instrumentation.EventCounters- - enable diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 8111db001c..756d4d0521 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -1,9 +1,10 @@ - + netstandard2.0 .NET gRPC Core based client and server interceptors for OpenTelemetry. $(PackageTags);gRPC Core;interceptors Instrumentation.GrpcCore- + disable diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 772177dc9f..28c8985714 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -5,6 +5,7 @@ $(PackageTags);Hangfire Instrumentation.Hangfire- false + disable diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 3467fd245a..87bf615700 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -5,6 +5,7 @@ OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- + disable diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index bf9335784d..4bd00f576a 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -4,7 +4,6 @@ dotnet process instrumentation for OpenTelemetry .NET $(PackageTags);process Instrumentation.Process- - enable diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 9681602645..c794f15c85 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -6,7 +6,6 @@ true netstandard2.0 true - enable diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 7d61ac0091..7438ef8ed5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,7 +5,6 @@ dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- - enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index f03d885358..86ff3d66c6 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -7,7 +7,6 @@ true true Instrumentation.StackExchangeRedis- - enable true diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 7d8b688310..069714297b 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -7,6 +7,7 @@ OpenTelemetry instrumentation for WCF $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- + disable diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index e3b9ef0fd6..5b9da7344f 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -9,7 +9,6 @@ OpenTelemetry Persistent Storage Abstractions PersistentStorage.Abstractions- $(NoWarn),1591 - enable diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index d4bb9a5912..8c098a6873 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -12,7 +12,6 @@ $(NoWarn),1591 - enable diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj index c2278435cf..bf14fa2ce6 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -6,7 +6,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. ResourceDetectors.AWS- - enable true diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index 23795f6b4d..6e922d0e3c 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -4,7 +4,6 @@ OpenTelemetry Resource Detectors for Azure cloud environments $(PackageTags);ResourceDetector ResourceDetectors.Azure- - enable diff --git a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj index ff5eb95467..43eb3d6322 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj @@ -4,7 +4,6 @@ netstandard2.0;net462 OpenTelemetry Extensions - Container Resource Detector from Container environment. ResourceDetectors.Container- - enable true diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index 8427c7659c..155b7ab301 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -5,7 +5,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry remote sampler for AWS X-Ray. Sampler.AWS- - enable diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 2491b9ddf9..ea8a9bfe63 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -7,6 +7,7 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 + disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 3aec212cfe..db069a17f0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -6,6 +6,7 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1308,SA1201 + disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index fb3bd9656a..c3933d601a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -7,6 +7,7 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 + disable diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 516a7a1156..77f722d9ed 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -5,7 +5,6 @@ $(NetMinimumSupportedVersion) $(TargetFrameworks);net48;net472;net471;net47;net462 - enable true diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index c374a737ea..9327ebdc7d 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 true + disable diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index c2e9b87580..81feba070e 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -6,7 +6,6 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 - enable true diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 8247c5e82d..e2a610d9f9 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -5,7 +5,6 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 - enable true diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index bb8e66d5b6..52327d652c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -4,7 +4,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 02e2134a9b..bb5034a279 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -4,6 +4,7 @@ Unit test project for OpenTelemetry .NET SDK telemetry enrichment. $(NetFrameworkMinimumSupportedVersion) + disable diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 53aa232c25..5c804515d1 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -4,6 +4,7 @@ Unit test project for OpenTelemetry .NET SDK preview features and extensions net7.0;net6.0 + disable diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 8a16e01d8e..45403f5832 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -5,7 +5,6 @@ net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index f2d50fcda4..95fbba74b5 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -5,7 +5,6 @@ net7.0;net6.0 true true - enable diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index 343bc3c447..c68c2175a8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -3,7 +3,6 @@ Unit test project for ASP.NET HttpModule $(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 66d205fa8f..f59b1e785e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -3,7 +3,6 @@ Unit test project for OpenTelemetry ASP.NET instrumentation $(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 3cc4e5c4d0..95016b6ae9 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -3,7 +3,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 592864c354..8ef955caa2 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0 true + disable diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index d98e5a9248..d5a316695c 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -3,6 +3,7 @@ Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation net7.0;net6.0 + disable diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 81177f9a06..c7a95c7e4a 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -4,6 +4,7 @@ net7.0;net6.0 true + disable diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 76ffd2ebd3..103afee76e 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -2,6 +2,7 @@ net6.0 + disable diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index 9187f57329..cef5be2a1d 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -3,6 +3,7 @@ Unit test project for OpenTelemetry OWIN instrumentation $(NetFrameworkMinimumSupportedVersion) + disable diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index a7c36d8081..a391effc6c 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -4,7 +4,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 98c388681c..3844899e19 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -5,7 +5,6 @@ net7.0;net6.0 $(TargetFrameworks);net472 true - enable diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index bd78af628a..8555b84cb5 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -4,7 +4,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index b59e09db8a..77f29289fb 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -5,6 +5,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 $(TARGET_FRAMEWORK) + disable diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 9adb7330ea..3aa11db7b8 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -5,6 +5,7 @@ net7.0;net6.0 $(TargetFrameworks);net462 + disable diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 4e658387ac..76d872a709 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -4,7 +4,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs index 02832a6edf..816505a9e5 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs @@ -167,7 +167,7 @@ public MockEcsMetadataEndpoint(string containerJsonPath, string taskJsonPath) }).Build(); this.server.Start(); - this.Address = new Uri(this.server.ServerFeatures.Get().Addresses.First()); + this.Address = new Uri(this.server.ServerFeatures.Get()!.Addresses.First()); } public async ValueTask DisposeAsync() diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index 04da229c89..266d5f6579 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -33,7 +33,7 @@ public void TestValidCertificate() using CertificateUploader certificateUploader = new CertificateUploader(); certificateUploader.Create(); - ServerCertificateValidationProvider serverCertificateValidationProvider = + var serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); Assert.NotNull(serverCertificateValidationProvider); @@ -51,7 +51,7 @@ public void TestValidCertificate() [Fact] public void TestInValidCertificate() { - ServerCertificateValidationProvider serverCertificateValidationProvider = + var serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(InvalidCertificateName); Assert.Null(serverCertificateValidationProvider); @@ -63,7 +63,7 @@ public void TestTestCallbackWithNullCertificate() using var certificateUploader = new CertificateUploader(); certificateUploader.Create(); - ServerCertificateValidationProvider serverCertificateValidationProvider = + var serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); Assert.NotNull(serverCertificateValidationProvider); @@ -76,7 +76,7 @@ public void TestCallbackWithNullChain() using var certificateUploader = new CertificateUploader(); certificateUploader.Create(); - ServerCertificateValidationProvider serverCertificateValidationProvider = + var serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); Assert.NotNull(serverCertificateValidationProvider); diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs index 18740e0226..b7dca6d38d 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs @@ -26,96 +26,72 @@ public class ContainerResourceDetectorTests { private readonly List testValidCasesV1 = new() { - new TestCase - { - Name = "cgroupv1 with prefix", - Line = "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff", - ExpectedContainerId = "e2cc29debdf85dde404998aa128997a819ff", - CgroupVersion = ContainerResourceDetector.ParseMode.V1, - }, - new TestCase - { - Name = "cgroupv1 with suffix", - Line = "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", - ExpectedContainerId = "ac679f8a8319c8cf7d38e1adf263bc08d23", - CgroupVersion = ContainerResourceDetector.ParseMode.V1, - }, - new TestCase - { - Name = "cgroupv1 with prefix and suffix", - Line = "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", - ExpectedContainerId = "dc679f8a8319c8cf7d38e1adf263bc08d23", - CgroupVersion = ContainerResourceDetector.ParseMode.V1, - }, - new TestCase - { - Name = "cgroupv1 with container Id", - Line = "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", - ExpectedContainerId = "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", - CgroupVersion = ContainerResourceDetector.ParseMode.V1, - }, + new( + name: "cgroupv1 with prefix", + line: "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff", + expectedContainerId: "e2cc29debdf85dde404998aa128997a819ff", + cgroupVersion: ContainerResourceDetector.ParseMode.V1), + new( + name: "cgroupv1 with suffix", + line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", + expectedContainerId: "ac679f8a8319c8cf7d38e1adf263bc08d23", + cgroupVersion: ContainerResourceDetector.ParseMode.V1), + new( + name: "cgroupv1 with prefix and suffix", + line: "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", + expectedContainerId: "dc679f8a8319c8cf7d38e1adf263bc08d23", + cgroupVersion: ContainerResourceDetector.ParseMode.V1), + new( + name: "cgroupv1 with container Id", + line: "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + expectedContainerId: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + cgroupVersion: ContainerResourceDetector.ParseMode.V1), }; private readonly List testValidCasesV2 = new() { - new TestCase - { - Name = "cgroupv2 with container Id", - Line = "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356/hostname", - ExpectedContainerId = "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, - new TestCase - { - Name = "cgroupv2 with full line", - Line = "473 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", - ExpectedContainerId = "dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, - new TestCase - { - Name = "cgroupv2 with minikube containerd mountinfo", - Line = "1537 1517 8:1 /var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", - ExpectedContainerId = "fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, - new TestCase - { - Name = "cgroupv2 with minikube docker mountinfo", - Line = "2327 2307 8:1 /var/lib/docker/containers/a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", - ExpectedContainerId = "a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, - new TestCase - { - Name = "cgroupv2 with minikube docker mountinfo2", - Line = "929 920 254:1 /docker/volumes/minikube/_data/lib/docker/containers/0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", - ExpectedContainerId = "0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, - new TestCase - { - Name = "cgroupv2 with podman mountinfo", - Line = "1096 1088 0:104 /containers/overlay-containers/1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=813800k,nr_inodes=203450,mode=700,uid=1000,gid=1000", - ExpectedContainerId = "1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, + new( + name: "cgroupv2 with container Id", + line: "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356/hostname", + expectedContainerId: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), + new( + name: "cgroupv2 with full line", + line: "473 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", + expectedContainerId: "dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), + new( + name: "cgroupv2 with minikube containerd mountinfo", + line: "1537 1517 8:1 /var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", + expectedContainerId: "fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), + new( + name: "cgroupv2 with minikube docker mountinfo", + line: "2327 2307 8:1 /var/lib/docker/containers/a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", + expectedContainerId: "a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), + new( + name: "cgroupv2 with minikube docker mountinfo2", + line: "929 920 254:1 /docker/volumes/minikube/_data/lib/docker/containers/0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", + expectedContainerId: "0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), + new( + name: "cgroupv2 with podman mountinfo", + line: "1096 1088 0:104 /containers/overlay-containers/1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=813800k,nr_inodes=203450,mode=700,uid=1000,gid=1000", + expectedContainerId: "1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), }; private readonly List testInvalidCases = new() { - new TestCase - { - Name = "Invalid cgroupv1 line", - Line = "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", - CgroupVersion = ContainerResourceDetector.ParseMode.V1, - }, - new TestCase - { - Name = "Invalid hex cgroupv2 line (contains a z)", - Line = "13:name=systemd:/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3fz9320f4402ae6/hostname", - CgroupVersion = ContainerResourceDetector.ParseMode.V2, - }, + new( + name: "Invalid cgroupv1 line", + line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", + cgroupVersion: ContainerResourceDetector.ParseMode.V1), + new( + name: "Invalid hex cgroupv2 line (contains a z)", + line: "13:name=systemd:/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3fz9320f4402ae6/hostname", + cgroupVersion: ContainerResourceDetector.ParseMode.V2), }; [Fact] @@ -175,17 +151,25 @@ public void TestInvalidContainer() private static string GetContainerId(Resource resource) { var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - return resourceAttributes[ContainerSemanticConventions.AttributeContainerId]?.ToString(); + return resourceAttributes[ContainerSemanticConventions.AttributeContainerId].ToString()!; } private sealed class TestCase { - public string Name { get; set; } + public TestCase(string name, string line, ContainerResourceDetector.ParseMode cgroupVersion, string? expectedContainerId = null) + { + this.Name = name; + this.Line = line; + this.ExpectedContainerId = expectedContainerId; + this.CgroupVersion = cgroupVersion; + } + + public string Name { get; } - public string Line { get; set; } + public string Line { get; } - public string ExpectedContainerId { get; set; } + public string? ExpectedContainerId { get; } - public ContainerResourceDetector.ParseMode CgroupVersion { get; set; } + public ContainerResourceDetector.ParseMode CgroupVersion { get; } } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 59ebd9591e..e0fb3a51f5 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -3,7 +3,6 @@ net7.0;net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable From b3c7ae771f77a8661db996a3e2b8e91e3242b281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Sat, 16 Sep 2023 02:15:01 +0200 Subject: [PATCH 0814/1499] Nullable Examples.AspNet (#1353) --- .../AspNet/Controllers/WeatherForecastController.cs | 12 +++++------- examples/AspNet/Examples.AspNet.csproj | 1 - examples/AspNet/Global.asax.cs | 4 ++-- examples/AspNet/Models/WeatherForecast.cs | 13 +++++++++---- .../AspNet/SuppressInstrumentationHttpModule.cs | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index 1aa7e0870b..5ef863576d 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -127,12 +127,10 @@ public async Task PostData() private static IEnumerable GetWeatherForecast() { var rng = new Random(); - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = rng.Next(-20, 55), - Summary = Summaries[rng.Next(Summaries.Length)], - }) + return Enumerable.Range(1, 5).Select(index => new WeatherForecast( + date: DateTime.Now.AddDays(index), + temperatureC: rng.Next(-20, 55), + summary: Summaries[rng.Next(Summaries.Length)])) .ToArray(); } @@ -218,7 +216,7 @@ private async Task RequestValidThatSpawnsSubSpansViaHttpClient() response.EnsureSuccessStatusCode(); } - private Uri GenerateContentRequestUri(string path, Func transform = null) + private Uri GenerateContentRequestUri(string path, Func? transform = null) { var rawUri = this.Url.Content(path); diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 124834cd10..9443447544 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -8,7 +8,6 @@ false web.config false - disable diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index 3724b36df0..e8318035b9 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -31,8 +31,8 @@ namespace Examples.AspNet; public class WebApiApplication : HttpApplication #pragma warning restore SA1649 // File name should match first type name { - private IDisposable tracerProvider; - private IDisposable meterProvider; + private IDisposable? tracerProvider; + private IDisposable? meterProvider; protected void Application_Start() { diff --git a/examples/AspNet/Models/WeatherForecast.cs b/examples/AspNet/Models/WeatherForecast.cs index d4585e88ff..4e4384bbef 100644 --- a/examples/AspNet/Models/WeatherForecast.cs +++ b/examples/AspNet/Models/WeatherForecast.cs @@ -20,11 +20,16 @@ namespace Examples.AspNet.Models; public class WeatherForecast { - public DateTime Date { get; set; } + public WeatherForecast(DateTime date, int temperatureC, string summary) + { + this.Date = date; + this.TemperatureC = temperatureC; + this.Summary = summary; + } - public int TemperatureC { get; set; } + public DateTime Date { get; } - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); + public int TemperatureC { get; } - public string Summary { get; set; } + public string Summary { get; } } diff --git a/examples/AspNet/SuppressInstrumentationHttpModule.cs b/examples/AspNet/SuppressInstrumentationHttpModule.cs index ce0d0ae246..bd31841d77 100644 --- a/examples/AspNet/SuppressInstrumentationHttpModule.cs +++ b/examples/AspNet/SuppressInstrumentationHttpModule.cs @@ -28,7 +28,7 @@ namespace Examples.AspNet; /// public class SuppressInstrumentationHttpModule : IHttpModule { - private IDisposable suppressionScope; + private IDisposable? suppressionScope; public void Init(HttpApplication context) { From e5c597eb2543ee64cc14f33376de671c7af96d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 18 Sep 2023 07:41:30 +0200 Subject: [PATCH 0815/1499] Nullable Hangfire (#1352) --- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 6 +++--- .../HangfireInstrumentationOptions.cs | 2 +- ...ngfireInstrumentationJobFilterAttribute.cs | 19 ++++++++----------- ...nTelemetry.Instrumentation.Hangfire.csproj | 1 - .../TracerProviderBuilderExtensions.cs | 2 +- .../TestJob.cs | 1 - 7 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 61a9676a20..56d4740243 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,9 +1,9 @@ OpenTelemetry.Trace.HangfireInstrumentationOptions -OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.get -> System.Func +OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.get -> System.Func! OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.set -> void OpenTelemetry.Trace.HangfireInstrumentationOptions.HangfireInstrumentationOptions() -> void OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs index d08bd5a4f7..e732f2a66c 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs @@ -21,7 +21,7 @@ namespace OpenTelemetry.Trace; /// -/// Options for hangfire jobs instrumentation. +/// Options for Hangfire jobs instrumentation. /// public class HangfireInstrumentationOptions { diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index dbddf6abf2..b161bfe284 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -15,30 +15,28 @@ // using System; -using Hangfire; - -namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; - using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using global::Hangfire.Client; -using global::Hangfire.Common; -using global::Hangfire.Server; +using Hangfire.Client; +using Hangfire.Common; +using Hangfire.Server; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Trace; +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; + internal sealed class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter { private readonly HangfireInstrumentationOptions options; +#pragma warning disable CA1019 // Define accessors for attribute arguments public HangfireInstrumentationJobFilterAttribute(HangfireInstrumentationOptions options) +#pragma warning restore CA1019 // Define accessors for attribute arguments { this.options = options; } - public HangfireInstrumentationOptions Options { get; } - public void OnPerforming(PerformingContext performingContext) { // Short-circuit if nobody is listening @@ -61,8 +59,7 @@ public void OnPerforming(PerformingContext performingContext) if (activity != null) { - Func displayNameFunc = - this.options.DisplayNameFunc ?? HangfireInstrumentation.DefaultDisplayNameFunc; + var displayNameFunc = this.options.DisplayNameFunc; activity.DisplayName = displayNameFunc(performingContext.BackgroundJob); diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 28c8985714..772177dc9f 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -5,7 +5,6 @@ $(PackageTags);Hangfire Instrumentation.Hangfire- false - disable diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index 551edf445a..6624cb9a4a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -42,7 +42,7 @@ public static TracerProviderBuilder AddHangfireInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddHangfireInstrumentation( this TracerProviderBuilder builder, - Action configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs index 604383d23d..411209af71 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -22,7 +22,6 @@ public class TestJob { public void Execute() { - return; } public void ThrowException() From 8ff2bde4906f4bd842bafb12aa9b9d023c9f7586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 18 Sep 2023 20:49:54 +0200 Subject: [PATCH 0816/1499] Nullable examples (#1357) --- .../Controllers/WeatherForecastController.cs | 10 ++++------ .../Examples.GrpcCore.AspNetCore.csproj | 3 +-- .../Examples.GrpcCore.AspNetCore/WeatherForecast.cs | 13 +++++++++---- examples/owin/Controllers/TestController.cs | 2 +- examples/owin/Examples.Owin.csproj | 1 - examples/wcf/client-core/Program.cs | 6 +----- examples/wcf/client-netframework/Program.cs | 6 +----- examples/wcf/shared/Examples.Wcf.Shared.csproj | 1 - examples/wcf/shared/StatusRequest.cs | 5 +++++ 9 files changed, 22 insertions(+), 25 deletions(-) diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index 69ceb10bcb..8ab3b4b7b1 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -45,12 +45,10 @@ public async Task> Get() var echoResponse = await echoCall.ResponseAsync.ConfigureAwait(false); var rng = new Random(); - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = rng.Next(-20, 55), - Summary = Summaries[rng.Next(Summaries.Length)], - }) + return Enumerable.Range(1, 5).Select(index => new WeatherForecast( + date: DateTime.Now.AddDays(index), + temperatureC: rng.Next(-20, 55), + summary: Summaries[rng.Next(Summaries.Length)])) .ToArray(); } } diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 17f9f6cb76..9d942db505 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -2,13 +2,12 @@ net6.0 - disable - + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index f840e9cfce..6836928dc0 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -20,11 +20,16 @@ namespace Examples.GrpcCore.AspNetCore; public class WeatherForecast { - public DateTime Date { get; set; } + public WeatherForecast(DateTime date, int temperatureC, string summary) + { + this.Date = date; + this.TemperatureC = temperatureC; + this.Summary = summary; + } - public int TemperatureC { get; set; } + public DateTime Date { get; } - public int TemperatureF => 32 + (int)(this.TemperatureC / 0.5556); + public int TemperatureC { get; } - public string Summary { get; set; } + public string Summary { get; } } diff --git a/examples/owin/Controllers/TestController.cs b/examples/owin/Controllers/TestController.cs index c47aa92312..4441175d4a 100644 --- a/examples/owin/Controllers/TestController.cs +++ b/examples/owin/Controllers/TestController.cs @@ -21,7 +21,7 @@ namespace Examples.Owin.Controllers; public class TestController : ApiController { // GET api/test/{id} - public string Get(string id = null) + public string Get(string? id = null) { return $"id:{id}"; } diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index 8026fa8ae6..228382acc7 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -3,7 +3,6 @@ Exe net462 - disable diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 96504c1f0c..71a68aae83 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -64,11 +64,7 @@ private static async Task CallService(Binding binding, EndpointAddress remoteAdd { await client.OpenAsync().ConfigureAwait(false); - var response = await client.PingAsync( - new StatusRequest - { - Status = Guid.NewGuid().ToString("N"), - }).ConfigureAwait(false); + var response = await client.PingAsync(new StatusRequest(Guid.NewGuid().ToString("N"))).ConfigureAwait(false); Console.WriteLine($"Server returned: {response?.ServerTime}"); } diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index 891f8ccb40..38334d7b0a 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -51,11 +51,7 @@ private static async Task CallService(string name) { await client.OpenAsync().ConfigureAwait(false); - var response = await client.PingAsync( - new StatusRequest - { - Status = Guid.NewGuid().ToString("N"), - }).ConfigureAwait(false); + var response = await client.PingAsync(new StatusRequest(Guid.NewGuid().ToString("N"))).ConfigureAwait(false); Console.WriteLine($"Server returned: {response?.ServerTime}"); } diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index fa00098a8c..265744f7ed 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -3,7 +3,6 @@ netstandard2.0;net462 - disable diff --git a/examples/wcf/shared/StatusRequest.cs b/examples/wcf/shared/StatusRequest.cs index 701b1f3bee..b9ea0bac27 100644 --- a/examples/wcf/shared/StatusRequest.cs +++ b/examples/wcf/shared/StatusRequest.cs @@ -21,6 +21,11 @@ namespace Examples.Wcf; [DataContract] public class StatusRequest { + public StatusRequest(string status) + { + this.Status = status; + } + [DataMember] public string Status { get; set; } } From f83790ca1392b1bc5119019b0240fc3d6c8159d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 18 Sep 2023 21:55:52 +0200 Subject: [PATCH 0817/1499] [Instrumentation.ElasticsearchClient] Execute tests on .NET Fx 4.6.2 (#1356) --- .../OpenTelemetry.Instrumentation.ElasticsearchClient.csproj | 3 ++- ...nTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 4e66b4fe4c..3777bb7516 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -1,7 +1,8 @@ - netstandard2.0;net462 + netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Elasticsearch instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 8ef955caa2..d380a9ce76 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,8 +1,9 @@ - + Unit test project for OpenTelemetry Elasticsearch client instrumentation net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) true disable From f6f3e241ed59e4f33850d73b4e9a1cd402e90a31 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 18 Sep 2023 16:16:24 -0700 Subject: [PATCH 0818/1499] [ResourceDetectors.Azure] Update AzureVmMetaDataRequestor [Add timeout for HttpClient] (#1358) --- .../AzureVmMetaDataRequestor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs index 4bbb36ab03..d6a163d874 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs @@ -28,7 +28,7 @@ internal static class AzureVmMetaDataRequestor public static AzureVmMetadataResponse? GetAzureVmMetaDataResponseDefault() { - using var httpClient = new HttpClient(); + using var httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) }; httpClient.DefaultRequestHeaders.Add("Metadata", "True"); var res = httpClient.GetStringAsync(AzureVmMetadataEndpointURL).ConfigureAwait(false).GetAwaiter().GetResult(); From 48a1b383e77442508a4ff73873e434f5e040dffc Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 18 Sep 2023 21:50:28 -0700 Subject: [PATCH 0819/1499] [ResourceDetectors.Azure] Update CHANGELOG.md - Request for release (#1359) --- src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 7b86d73bf1..a3e55208f4 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## 1.0.0-beta.3 + +Released 2023-Sep-19 + +* Configured the `HttpClient` used for making the call to metadata service to + use a `Timeout` to `2` seconds. This is to improve the start-up time of + applications not running on Azure VMs. + ([#1358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1358)) * Updates to 1.6.0 of OpenTelemetry SDK. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Suppress instrumentation for outgoing http call made to metadata service From 7b68f6e52a91ca282b8d38fcaba9a20da427e726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 20 Sep 2023 00:30:05 +0200 Subject: [PATCH 0820/1499] Nullable OpenTelemetry.Instrumentation.EventCounters.Tests (#1360) --- .../EventCountersMetricsTests.cs | 23 +++++++------------ ...Instrumentation.EventCounters.Tests.csproj | 1 - 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 3476430c35..f68d3121b0 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -41,7 +41,7 @@ public void EventCounter() options.AddEventSources(source.Name); }) .AddInMemoryExporter(metricItems) - .Build(); + .Build()!; // Act counter.WriteMetric(1997.0202); @@ -67,7 +67,7 @@ public void IncrementingEventCounter() options.AddEventSources(source.Name); }) .AddInMemoryExporter(metricItems) - .Build(); + .Build()!; // Act incCounter.Increment(1); @@ -96,7 +96,7 @@ public void PollingCounter() options.AddEventSources(source.Name); }) .AddInMemoryExporter(metricItems) - .Build(); + .Build()!; // Act var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName: "ec.c.poll-c"); @@ -122,7 +122,7 @@ public void IncrementingPollingCounter() options.AddEventSources(source.Name); }) .AddInMemoryExporter(metricItems) - .Build(); + .Build()!; // Act var metric = AwaitExport(meterProvider, metricItems, expectedInstrumentName: "ec.d.inc-poll-c"); @@ -133,13 +133,6 @@ public void IncrementingPollingCounter() Assert.Equal(1, GetActualValue(metric)); } - [Fact] - public void ThrowExceptionWhenBuilderIsNull() - { - MeterProviderBuilder builder = null; - Assert.Throws(() => builder.AddEventCountersInstrumentation()); - } - [Fact] public void ThrowExceptionForUnsupportedEventSources() { @@ -177,7 +170,7 @@ public void EventSourceNameShortening(string sourceName, string eventName, strin options.AddEventSources(source.Name); }) .AddInMemoryExporter(metricItems) - .Build(); + .Build()!; // Act connections.Increment(1); @@ -235,16 +228,16 @@ private static double GetActualValue(Metric metric) return sum; } - private static Metric AwaitExport(MeterProvider meterProvider, List exportedItems, string expectedInstrumentName) + private static Metric? AwaitExport(MeterProvider meterProvider, List exportedItems, string expectedInstrumentName) { - Metric metric = null; + Metric? metric = null; SpinWait.SpinUntil( () => { Thread.Sleep(100); meterProvider.ForceFlush(); - metric = exportedItems.Where(x => x.Name == expectedInstrumentName).FirstOrDefault(); + metric = exportedItems.FirstOrDefault(x => x.Name == expectedInstrumentName); return metric != null; }, 10_000); diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index c7a95c7e4a..81177f9a06 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -4,7 +4,6 @@ net7.0;net6.0 true - disable From 71655cebf4862bb06ff23e55068a7ff667b0fed4 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 19 Sep 2023 15:52:25 -0700 Subject: [PATCH 0821/1499] [OneCollectorExporter] Perf improvements (#1361) --- .../CHANGELOG.md | 7 +++ .../Internal/ExtensionFieldInformation.cs | 29 +++++++++++++ .../ExtensionFieldInformationManager.cs | 43 +++++++++++-------- .../CommonSchemaJsonSerializationHelper.cs | 23 ++++++++++ .../CommonSchemaJsonSerializationState.cs | 33 ++++++++++---- ...ommonSchemaJsonSerializationHelperTests.cs | 7 ++- ...CommonSchemaJsonSerializationStateTests.cs | 6 +-- .../ExtensionFieldInformationManagerTests.cs | 14 ++++-- ...ogRecordCommonSchemaJsonSerializerTests.cs | 38 ++++++++-------- 9 files changed, 149 insertions(+), 51 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 8b7b8b531b..cab0a366f9 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -22,6 +22,13 @@ extension because it is not currently supported by the OneCollector service. ([#1345](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1345)) +* Added dedicated handling for `IReadOnlyList>` + types during serialization to improve performance. + ([#1361](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1361)) + +* Added caching of extension property UTF8 JSON strings to improve performance. + ([#1361](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1361)) + ## 1.5.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs new file mode 100644 index 0000000000..596c2943d9 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs @@ -0,0 +1,29 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Text.Json; + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class ExtensionFieldInformation +{ + public string? ExtensionName; + public JsonEncodedText EncodedExtensionName; + public string? FieldName; + public JsonEncodedText EncodedFieldName; + + public bool IsValid => this.ExtensionName != null; +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs index f2a92b62d1..98bd8dd745 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs @@ -16,6 +16,10 @@ using System.Collections; using System.Diagnostics; +#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using System.Text.Json; namespace OpenTelemetry.Exporter.OneCollector; @@ -28,9 +32,14 @@ internal sealed class ExtensionFieldInformationManager public int CountOfCachedExtensionFields => this.fieldInformationCache.Count; - public bool TryResolveExtensionFieldInformation(string fullFieldName, out (string ExtensionName, string FieldName) resolvedFieldInformation) + public bool TryResolveExtensionFieldInformation( + string fullFieldName, +#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER + [NotNullWhen(true)] +#endif + out ExtensionFieldInformation? resolvedFieldInformation) { - if (this.fieldInformationCache[fullFieldName] is not FieldInformation fieldInformation) + if (this.fieldInformationCache[fullFieldName] is not ExtensionFieldInformation fieldInformation) { fieldInformation = this.ResolveExtensionFieldInformationRare(fullFieldName); } @@ -41,39 +50,44 @@ public bool TryResolveExtensionFieldInformation(string fullFieldName, out (strin return false; } - resolvedFieldInformation = new(fieldInformation.ExtensionName!, fieldInformation.FieldName!); + resolvedFieldInformation = fieldInformation; return true; } - private static FieldInformation BuildFieldInformation(string fullFieldName) + private static ExtensionFieldInformation BuildFieldInformation(string fullFieldName) { Debug.Assert(fullFieldName.Length >= 4, "fullFieldName length was invalid"); Debug.Assert(fullFieldName.StartsWith("ext.", StringComparison.OrdinalIgnoreCase), "fullFieldName did not start with 'ext.'"); - var extensionName = fullFieldName.AsSpan().Slice(4); + var extensionName = fullFieldName.AsSpan().Slice(4).TrimEnd(); var locationOfDot = extensionName.IndexOf('.'); if (locationOfDot <= 0) { return new(); } - var fieldName = extensionName.Slice(locationOfDot + 1); + var fieldName = extensionName.Slice(locationOfDot + 1).TrimStart(); if (fieldName.Length <= 0) { return new(); } - extensionName = extensionName.Slice(0, locationOfDot); + extensionName = extensionName.Slice(0, locationOfDot).TrimEnd(); + if (extensionName.Length <= 0) + { + return new(); + } - return new FieldInformation + return new ExtensionFieldInformation { ExtensionName = extensionName.ToString(), + EncodedExtensionName = JsonEncodedText.Encode(extensionName), FieldName = fieldName.ToString(), - IsValid = true, + EncodedFieldName = JsonEncodedText.Encode(fieldName), }; } - private FieldInformation ResolveExtensionFieldInformationRare(string fullFieldName) + private ExtensionFieldInformation ResolveExtensionFieldInformationRare(string fullFieldName) { if (this.fieldInformationCache.Count >= MaxNumberOfCachedFieldInformations) { @@ -82,7 +96,7 @@ private FieldInformation ResolveExtensionFieldInformationRare(string fullFieldNa lock (this.fieldInformationCache) { - if (this.fieldInformationCache[fullFieldName] is not FieldInformation fieldInformation) + if (this.fieldInformationCache[fullFieldName] is not ExtensionFieldInformation fieldInformation) { fieldInformation = BuildFieldInformation(fullFieldName); if (this.fieldInformationCache.Count < MaxNumberOfCachedFieldInformations) @@ -94,11 +108,4 @@ private FieldInformation ResolveExtensionFieldInformationRare(string fullFieldNa return fieldInformation; } } - - private sealed class FieldInformation - { - public string? ExtensionName; - public string? FieldName; - public bool IsValid; - } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index dd687a15b3..fa015b281c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -158,6 +158,10 @@ public static void SerializeValueToJson(object? value, Utf8JsonWriter writer) SerializeArrayValueToJson(v, writer); return; + case IReadOnlyList> v: + SerializeMapValueToJson(v, writer); + return; + case IEnumerable> v: SerializeMapValueToJson(v, writer); return; @@ -180,6 +184,25 @@ private static void SerializeArrayValueToJson(Array value, Utf8JsonWriter writer writer.WriteEndArray(); } + private static void SerializeMapValueToJson(IReadOnlyList> value, Utf8JsonWriter writer) + { + writer.WriteStartObject(); + + for (int i = 0; i < value.Count; i++) + { + var element = value[i]; + + if (string.IsNullOrEmpty(element.Key)) + { + continue; + } + + SerializeKeyValueToJson(element.Key, element.Value, writer); + } + + writer.WriteEndObject(); + } + private static void SerializeMapValueToJson(IEnumerable> value, Utf8JsonWriter writer) { writer.WriteStartObject(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs index 52b992aaa1..cc464979fe 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System.Diagnostics; #if NET6_0_OR_GREATER using System.Runtime.InteropServices; #endif @@ -26,7 +27,7 @@ internal sealed class CommonSchemaJsonSerializationState public const int MaxNumberOfExtensionKeys = 64; public const int MaxNumberOfExtensionValuesPerKey = 16; private readonly Dictionary keys = new(4, StringComparer.OrdinalIgnoreCase); - private readonly List> allValues = new(16); + private readonly List> allValues = new(16); private string itemType; private int nextKeysToAllValuesLookupIndex; private KeyValueLookup[] keysToAllValuesLookup = new KeyValueLookup[4]; @@ -47,12 +48,17 @@ public void AddExtensionAttribute(KeyValuePair attribute) { if (!ExtensionFieldInformationManager.SharedCache.TryResolveExtensionFieldInformation( attribute.Key, - out (string ExtensionName, string FieldName) fieldInformation)) + out var fieldInformation)) { OneCollectorExporterEventSource.Log.AttributeDropped(this.itemType, attribute.Key, "Invalid extension field name"); return; } + Debug.Assert(fieldInformation?.ExtensionName != null, "fieldInformation.ExtensionName was null"); + Debug.Assert(fieldInformation?.EncodedExtensionName.EncodedUtf8Bytes.Length > 0, "fieldInformation.EncodedExtensionName was empty"); + Debug.Assert(fieldInformation?.FieldName != null, "fieldInformation.FieldName was null"); + Debug.Assert(fieldInformation?.EncodedFieldName.EncodedUtf8Bytes.Length > 0, "fieldInformation.EncodedFieldName was empty"); + #if NET6_0_OR_GREATER ref var lookupIndex = ref CollectionsMarshal.GetValueRefOrAddDefault(this.keys, fieldInformation.ExtensionName, out var existed); if (!existed) @@ -60,10 +66,10 @@ public void AddExtensionAttribute(KeyValuePair attribute) this.AssignNewExtensionToLookupIndex(ref lookupIndex); } #else - if (!this.keys.TryGetValue(fieldInformation.ExtensionName, out int lookupIndex)) + if (!this.keys.TryGetValue(fieldInformation!.ExtensionName!, out int lookupIndex)) { this.AssignNewExtensionToLookupIndex(ref lookupIndex); - this.keys[fieldInformation.ExtensionName] = lookupIndex; + this.keys[fieldInformation.ExtensionName!] = lookupIndex; } #endif @@ -82,7 +88,7 @@ public void AddExtensionAttribute(KeyValuePair attribute) } int index = this.allValues.Count; - this.allValues.Add(new KeyValuePair(fieldInformation.FieldName, attribute.Value)); + this.allValues.Add(new KeyValuePair(fieldInformation, attribute.Value)); unsafe { @@ -107,7 +113,7 @@ public void SerializeExtensionPropertiesToJson(bool writeExtensionObjectEnvelope foreach (var extensionPropertyKey in this.keys) { - writer.WriteStartObject(extensionPropertyKey.Key); + var wroteStartObject = false; ref KeyValueLookup keyLookup = ref this.keysToAllValuesLookup[extensionPropertyKey.Value]; @@ -120,12 +126,23 @@ public void SerializeExtensionPropertiesToJson(bool writeExtensionObjectEnvelope #else var attribute = allValues[keyLookup.ValueIndicies[i]]; #endif + var fieldInformation = attribute.Key; + + if (!wroteStartObject) + { + writer.WriteStartObject(fieldInformation.EncodedExtensionName); + wroteStartObject = true; + } - CommonSchemaJsonSerializationHelper.SerializeKeyValueToJson(attribute.Key, attribute.Value, writer); + writer.WritePropertyName(fieldInformation.EncodedFieldName); + CommonSchemaJsonSerializationHelper.SerializeValueToJson(attribute.Value, writer); } } - writer.WriteEndObject(); + if (wroteStartObject) + { + writer.WriteEndObject(); + } } if (writeExtensionObjectEnvelope) diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs index cb7673710b..ab3adfc7c6 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -82,8 +82,11 @@ public void SerializeComplexValueToJsonTest() var array = new[] { 0, 1, 18 }; this.SerializeValueToJsonTest(array, "[0,1,18]"); - var map = new List> { new KeyValuePair("key1", "value1") }; - this.SerializeValueToJsonTest(map, "{\"key1\":\"value1\"}"); + var listMap = new List> { new KeyValuePair("key1", "value1") }; + this.SerializeValueToJsonTest(listMap, "{\"key1\":\"value1\"}"); + + var dictMap = new Dictionary { ["key1"] = "value1" }; + this.SerializeValueToJsonTest(dictMap, "{\"key1\":\"value1\"}"); var typeWithToString = new TypeWithToString(); this.SerializeValueToJsonTest(typeWithToString, "\"Hello world\""); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs index 0363ca3996..37a50d3f6d 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs @@ -50,7 +50,7 @@ public void AddExtensionAttributeTest() var json = Encoding.UTF8.GetString(stream.ToArray()); Assert.Equal( - "{\"ext\":{\"something\":{\"field1\":1,\"field2\":2,\"field3\":3,\"field4\":6},\"food\":{\"field1\":4,\"field2\":5}}}", + """{"ext":{"something":{"field1":1,"field2":2,"field3":3,"field4":6},"food":{"field1":4,"field2":5}}}""", json); stream.SetLength(0); @@ -74,7 +74,7 @@ public void AddExtensionAttributeTest() json = Encoding.UTF8.GetString(stream.ToArray()); Assert.Equal( - "{\"ext\":{\"something\":{\"field1\":1},\"food\":{\"field1\":1}}}", + """{"ext":{"something":{"field1":1},"food":{"field1":1}}}""", json); } @@ -102,7 +102,7 @@ public void AddExtensionAttributeDuplicatesTest() var json = Encoding.UTF8.GetString(stream.ToArray()); Assert.Equal( - "{\"ext\":{\"something\":{\"field1\":1,\"field1\":2}}}", + """{"ext":{"something":{"field1":1,"field1":2}}}""", json); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs index e2b0de5890..fa07ae22c8 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs @@ -28,6 +28,7 @@ public void FieldInformationIsCachedTest() var result = extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something.fieldName1", out var fieldInformation); Assert.True(result); + Assert.NotNull(fieldInformation); Assert.Equal("something", fieldInformation.ExtensionName); Assert.Equal("fieldName1", fieldInformation.FieldName); @@ -38,6 +39,7 @@ public void FieldInformationIsCachedTest() Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); Assert.True(result); + Assert.NotNull(fieldInformation); Assert.Equal("something", fieldInformation.ExtensionName); Assert.Equal("fieldName1", fieldInformation.FieldName); @@ -46,6 +48,7 @@ public void FieldInformationIsCachedTest() Assert.Equal(2, extensionFieldInformationManager.CountOfCachedExtensionFields); Assert.True(result); + Assert.NotNull(fieldInformation); Assert.Equal("something", fieldInformation.ExtensionName); Assert.Equal("field.Name2", fieldInformation.FieldName); } @@ -54,19 +57,23 @@ public void FieldInformationIsCachedTest() public void InvalidFieldNamesIgnoredTest() { var extensionFieldInformationManager = new ExtensionFieldInformationManager(); - Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.", out _)); Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); - Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.", out _)); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("EXT.", out _)); Assert.Equal(1, extensionFieldInformationManager.CountOfCachedExtensionFields); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext..", out _)); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext. .", out _)); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext..field", out _)); Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something", out _)); Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something.", out _)); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.SOMETHING.", out _)); + Assert.False(extensionFieldInformationManager.TryResolveExtensionFieldInformation("ext.something. ", out _)); - Assert.Equal(3, extensionFieldInformationManager.CountOfCachedExtensionFields); + Assert.Equal(7, extensionFieldInformationManager.CountOfCachedExtensionFields); } [Fact] @@ -81,6 +88,7 @@ public void FieldInformationCacheLimitTest() var result = extensionFieldInformationManager.TryResolveExtensionFieldInformation($"ext.something.{fieldName}", out var fieldInformation); Assert.True(result); + Assert.NotNull(fieldInformation); Assert.Equal("something", fieldInformation.ExtensionName); Assert.Equal(fieldName, fieldInformation.FieldName); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 22386f8a10..5642b73b19 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -32,7 +32,7 @@ public void EmptyLogRecordJsonTest() string json = GetLogRecordJson(1, (index, logRecord) => { }); Assert.Equal( - "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n", json); } @@ -42,8 +42,8 @@ public void MultipleEmptyLogRecordJsonTest() string json = GetLogRecordJson(2, (index, logRecord) => { }); Assert.Equal( - "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n" - + "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n" + + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n", json); } @@ -63,7 +63,7 @@ public void LogRecordLogLevelJsonTest(LogLevel logLevel, string severityText, in }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"{severityText}\",\"severityNumber\":{severityNumber}}}}}\n", + $$$"""{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"{{{severityText}}}","severityNumber":{{{severityNumber}}}}}""" + "\n", json); } @@ -79,7 +79,7 @@ public void LogRecordCategoryNameAndEventNameJsonTest(string categoryName, strin }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"{categoryName}.{eventName ?? "Name"}\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}}}}\n", + $$$"""{"ver":"4.0","name":"{{{categoryName}}}.{{{eventName ?? "Name"}}}","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n", json); } @@ -92,7 +92,7 @@ public void LogRecordEventIdJsonTest() }); Assert.Equal( - "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"eventId\":18,\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"eventId":18,"severityText":"Trace","severityNumber":1}}""" + "\n", json); } @@ -105,7 +105,7 @@ public void LogRecordTimestampJsonTest() }); Assert.Equal( - "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2023-01-18T10:18:00Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2023-01-18T10:18:00Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n", json); } @@ -119,7 +119,7 @@ public void LogRecordOriginalFormatBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\",\"formattedMessage\":\"goodbye world\"}}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"body":"hello world","formattedMessage":"goodbye world"}}""" + "\n", json); } @@ -133,7 +133,7 @@ public void LogRecordBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"hello world\",\"formattedMessage\":\"goodbye world\"}}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"body":"hello world","formattedMessage":"goodbye world"}}""" + "\n", json); } @@ -146,7 +146,7 @@ public void LogRecordFormattedMessageBodyJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"body\":\"goodbye world\",\"formattedMessage\":\"goodbye world\"}}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"body":"goodbye world","formattedMessage":"goodbye world"}}""" + "\n", json); } @@ -164,7 +164,7 @@ public void LogRecordResourceJsonTest() string json = GetLogRecordJson(1, (index, logRecord) => { }, resource); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"resourceKey1\":\"resourceValue1\",\"resourceKey2\":\"resourceValue2\"}}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"resourceKey1":"resourceValue1","resourceKey2":"resourceValue2"}}""" + "\n", json); } @@ -178,7 +178,7 @@ public void LogRecordScopesJsonTest() string json = GetLogRecordJson(1, (index, logRecord) => { }, scopeProvider: scopeProvider); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"scope1Key1\":\"scope1Value1\",\"scope1Key2\":\"scope1Value2\",\"scope2Key1\":\"scope2Value1\"}}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"scope1Key1":"scope1Value1","scope1Key2":"scope1Value2","scope2Key1":"scope2Value1"}}""" + "\n", json); } @@ -191,7 +191,7 @@ public void LogRecordStateValuesJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1,\"stateKey1\":\"stateValue1\",\"stateKey2\":\"stateValue2\"}}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"stateKey1":"stateValue1","stateKey2":"stateValue2"}}""" + "\n", json); } @@ -209,7 +209,9 @@ public void LogRecordTraceContextJsonTest() }); Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}},\"ext\":{{\"dt\":{{\"traceId\":\"{traceId}\",\"spanId\":\"{spanId}\"}}}}}}\n", + $$$$""" + {"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1},"ext":{"dt":{"traceId":"{{{{traceId}}}}","spanId":"{{{{spanId}}}}"}}} + """ + "\n", json); } @@ -227,11 +229,13 @@ public void LogRecordExceptionJsonTest(bool includeStackTraceAsString) includeStackTraceAsString: includeStackTraceAsString); var stackJson = includeStackTraceAsString - ? $",\"stack\":\"System.InvalidOperationException: Operation is not valid due to the current state of the object.\"" + ? ",\"stack\":\"System.InvalidOperationException: Operation is not valid due to the current state of the object.\"" : string.Empty; Assert.Equal( - $"{{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{{\"severityText\":\"Trace\",\"severityNumber\":1}},\"ext\":{{\"ex\":{{\"type\":\"System.InvalidOperationException\",\"msg\":\"Operation is not valid due to the current state of the object.\"{stackJson}}}}}}}\n", + $$$$""" + {"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1},"ext":{"ex":{"type":"System.InvalidOperationException","msg":"Operation is not valid due to the current state of the object."{{{{stackJson}}}}}}} + """ + "\n", json); } @@ -258,7 +262,7 @@ public void LogRecordExtensionsJsonTest() scopeProvider); Assert.Equal( - "{\"ver\":\"4.0\",\"name\":\"Namespace.Name\",\"time\":\"2032-01-18T10:11:12Z\",\"iKey\":\"o:tenant-token\",\"data\":{\"severityText\":\"Trace\",\"severityNumber\":1},\"ext\":{\"state\":{\"field\":\"stateValue1\"},\"resource\":{\"field\":\"resourceValue1\"},\"scope\":{\"field\":\"scopeValue1\"}}}\n", + """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1},"ext":{"state":{"field":"stateValue1"},"resource":{"field":"resourceValue1"},"scope":{"field":"scopeValue1"}}}""" + "\n", json); } From 49365fc57c3feb7b4480d3bd09255403b420612d Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Tue, 19 Sep 2023 21:28:00 -0400 Subject: [PATCH 0822/1499] OWIN HTTP server metrics (#1335) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 2 + .../Implementation/DiagnosticsMiddleware.cs | 36 ++++++- .../OwinInstrumentationMetrics.cs | 31 ++++++ ...mentationMeterProviderBuilderExtensions.cs | 40 +++++++ .../README.md | 28 ++++- src/Shared/SemanticConventions.cs | 6 ++ .../DiagnosticsMiddlewareTests.cs | 100 ++++++++++++++++-- 8 files changed, 232 insertions(+), 13 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs create mode 100644 src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt index 23c619652b..761ae2d2ff 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt @@ -9,8 +9,10 @@ OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.OwinInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Metrics.OwinInstrumentationMeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions Owin.AppBuilderExtensions +static OpenTelemetry.Metrics.OwinInstrumentationMeterProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static Owin.AppBuilderExtensions.UseOpenTelemetry(this Owin.IAppBuilder appBuilder) -> Owin.IAppBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 6fcb6bdf0d..ec16d15b46 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -6,6 +6,8 @@ ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Removes `AddOwinInstrumentation` method with default configure parameter. ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) +* Adds HTTP server metrics via `AddOwinInstrumentation` extension method on `MeterProviderBuilder` + ([#1335](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1335)) ## 1.0.0-rc.3 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 1d0bd2ba8f..85b041bd24 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -21,6 +21,7 @@ using System.Threading.Tasks; using Microsoft.Owin; using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.Owin.Implementation; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Owin; @@ -46,15 +47,23 @@ public DiagnosticsMiddleware(OwinMiddleware next) /// public override async Task Invoke(IOwinContext owinContext) { + long startTimestamp = -1; + try { BeginRequest(owinContext); + + if (OwinInstrumentationMetrics.HttpServerDuration.Enabled && !owinContext.Environment.ContainsKey(ContextKey)) + { + startTimestamp = Stopwatch.GetTimestamp(); + } + await this.Next.Invoke(owinContext).ConfigureAwait(false); - RequestEnd(owinContext, null); + RequestEnd(owinContext, null, startTimestamp); } catch (Exception ex) { - RequestEnd(owinContext, ex); + RequestEnd(owinContext, ex, startTimestamp); throw; } } @@ -151,7 +160,7 @@ private static void BeginRequest(IOwinContext owinContext) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void RequestEnd(IOwinContext owinContext, Exception exception) + private static void RequestEnd(IOwinContext owinContext, Exception exception, long startTimestamp) { if (owinContext.Environment.TryGetValue(ContextKey, out object context) && context is Activity activity) @@ -199,11 +208,32 @@ private static void RequestEnd(IOwinContext owinContext, Exception exception) activity.Stop(); + if (OwinInstrumentationMetrics.HttpServerDuration.Enabled) + { + OwinInstrumentationMetrics.HttpServerDuration.Record( + activity.Duration.TotalSeconds, + new(SemanticConventions.AttributeHttpRequestMethod, owinContext.Request.Method), + new(SemanticConventions.AttributeUrlScheme, owinContext.Request.Scheme), + new(SemanticConventions.AttributeHttpResponseStatusCode, owinContext.Response.StatusCode)); + } + if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) { Baggage.Current = default; } } + else if (OwinInstrumentationMetrics.HttpServerDuration.Enabled) + { + var endTimestamp = Stopwatch.GetTimestamp(); + var duration = endTimestamp - startTimestamp; + var durationS = duration / Stopwatch.Frequency; + + OwinInstrumentationMetrics.HttpServerDuration.Record( + durationS, + new(SemanticConventions.AttributeHttpRequestMethod, owinContext.Request.Method), + new(SemanticConventions.AttributeUrlScheme, owinContext.Request.Scheme), + new(SemanticConventions.AttributeHttpResponseStatusCode, owinContext.Response.StatusCode)); + } } /// diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs new file mode 100644 index 0000000000..b19e7a47f2 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -0,0 +1,31 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics.Metrics; +using System.Reflection; + +namespace OpenTelemetry.Instrumentation.Owin.Implementation; + +internal static class OwinInstrumentationMetrics +{ + internal static readonly AssemblyName AssemblyName = typeof(OwinInstrumentationMetrics).Assembly.GetName(); + + public static string MeterName => AssemblyName.Name; + + public static Meter Instance => new Meter(MeterName, AssemblyName.Version.ToString()); + + public static Histogram HttpServerDuration => Instance.CreateHistogram("http.server.request.duration", "s", "Measures the duration of inbound HTTP requests."); +} diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..fc6a0408f4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs @@ -0,0 +1,40 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using OpenTelemetry.Instrumentation.Owin.Implementation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of OWIN request instrumentation. +/// +public static class OwinInstrumentationMeterProviderBuilderExtensions +{ + /// + /// Enables the incoming requests automatic data collection for OWIN. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddOwinInstrumentation( + this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + + builder.AddMeter(OwinInstrumentationMetrics.MeterName); + return builder; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index a5172d1b49..efc1d3d5e3 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -38,7 +38,9 @@ done before any other middleware registrations. }); ``` -### Step 3: Configure OpenTelemetry TracerProvider +### Step 3: Enable OWIN Instrumentation at application startup + +#### Configure OpenTelemetry TracerProvider Call the `AddOwinInstrumentation` `TracerProviderBuilder` extension to register OpenTelemetry instrumentation which listens to the OWIN diagnostic events. @@ -51,6 +53,30 @@ OpenTelemetry instrumentation which listens to the OWIN diagnostic events. .Build(); ``` +#### Configure OpenTelemetry MeterProvider + +Call the `AddOwinInstrumentation` `MeterProviderBuilder` extension to register +OpenTelemetry instrumentation which generates request duration metrics for OWIN requests. + +The metric implemention does not rely on tracing, and will generate metrics +even if tracing is disabled. + +```csharp + using var openTelemetry = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("Owin-Example")) + .AddOwinInstrumentation() + .AddConsoleExporter() + .Build(); +``` + +The instrumentation is implemented based on [metrics semantic +conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration). +Currently, the instrumentation supports the following metric. + +| Name | Instrument Type | Unit | Description | +|-------|-----------------|------|-------------| +| `http.server.request.duration` | Histogram | `s` | Measures the duration of inbound HTTP requests. | + ## Customize OWIN span names The OpenTelemetry OWIN instrumentation will create spans with very generic names diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index ab5aca7023..e4040c6b11 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -108,5 +108,11 @@ internal static class SemanticConventions public const string AttributeExceptionType = "exception.type"; public const string AttributeExceptionMessage = "exception.message"; public const string AttributeExceptionStacktrace = "exception.stacktrace"; + + // v1.21.0 + // https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-metrics.md#http-server + public const string AttributeHttpRequestMethod = "http.request.method"; // replaces: "http.method" (AttributeHttpMethod) + public const string AttributeHttpResponseStatusCode = "http.response.status_code"; // replaces: "http.status_code" (AttributeHttpStatusCode) + public const string AttributeUrlScheme = "url.scheme"; // replaces: "http.scheme" (AttributeHttpScheme) #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 4d90b5073b..1caa391c1f 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -24,6 +24,8 @@ using System.Web.Http; using Microsoft.Owin; using Microsoft.Owin.Hosting; +using OpenTelemetry.Instrumentation.Owin.Implementation; +using OpenTelemetry.Metrics; using OpenTelemetry.Trace; using Owin; using Xunit; @@ -106,15 +108,28 @@ public void Dispose() } [Theory] - [InlineData(true, false)] - [InlineData(true, true)] - [InlineData(false)] + [InlineData(true, false, false)] [InlineData(true, false, true)] - [InlineData(true, false, true, true)] - [InlineData(true, false, false, false, true)] - [InlineData(true, false, false, false, true, true)] + [InlineData(true, false, false, true)] + [InlineData(true, false, false, true, true)] + [InlineData(true, false, false, false, false, true)] + [InlineData(true, false, false, false, false, true, true)] + [InlineData(true, true, false)] + [InlineData(true, true, true)] + [InlineData(true, true, false, true)] + [InlineData(true, true, false, true, true)] + [InlineData(true, true, false, false, false, true)] + [InlineData(true, true, false, false, false, true, true)] + [InlineData(false, true, false)] + [InlineData(false, true, true)] + [InlineData(false, true, false, true)] + [InlineData(false, true, false, true, true)] + [InlineData(false, true, false, false, false, true)] + [InlineData(false, true, false, false, false, true, true)] + [InlineData(false, false)] public async Task OutgoingRequestInstrumentationTest( - bool instrument, + bool instrumentTraces, + bool instrumentMetrics, bool filter = false, bool enrich = false, bool enrichmentException = false, @@ -122,11 +137,14 @@ public async Task OutgoingRequestInstrumentationTest( bool recordException = false) { List stoppedActivities = new List(); + List exportedMetrics = new List(); var builder = Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(stoppedActivities); + var meterBuilder = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(exportedMetrics); - if (instrument) + if (instrumentTraces) { builder .AddOwinInstrumentation(options => @@ -159,7 +177,13 @@ public async Task OutgoingRequestInstrumentationTest( }); } + if (instrumentMetrics) + { + meterBuilder.AddOwinInstrumentation(); + } + using TracerProvider tracerProvider = builder.Build(); + using MeterProvider meterProvider = meterBuilder.Build(); using HttpClient client = new HttpClient(); @@ -177,7 +201,7 @@ Owin has finished to inspect the activity status. */ Assert.True(this.requestCompleteHandle.WaitOne(3000)); - if (instrument) + if (instrumentTraces) { if (!filter) { @@ -222,5 +246,63 @@ Owin has finished to inspect the activity status. */ { Assert.Empty(stoppedActivities); } + + if (instrumentMetrics) + { + meterProvider.Dispose(); + var metric = exportedMetrics[0]; + var metricPoints = this.GetMetricPoints(metric); + var metricPoint = Assert.Single(metricPoints); + + Assert.Equal(OwinInstrumentationMetrics.MeterName, metric.MeterName); + Assert.Equal("http.server.request.duration", metric.Name); + Assert.Equal(MetricType.Histogram, metric.MetricType); + Assert.Equal(1, metricPoint.GetHistogramCount()); + Assert.Equal(3, metricPoint.Tags.Count); + + foreach (var tag in metricPoint.Tags) + { + switch (tag.Key) + { + case SemanticConventions.AttributeHttpMethod: + Assert.Equal("GET", tag.Value); + break; + case SemanticConventions.AttributeHttpScheme: + Assert.Equal(requestUri.Scheme, tag.Value); + break; + case SemanticConventions.AttributeHttpStatusCode: + Assert.Equal(generateRemoteException ? 500 : 200, tag.Value); + break; + } + } + } + else + { + Assert.Empty(exportedMetrics); + } + + if (instrumentMetrics && instrumentTraces && !filter) + { + var metric = Assert.Single(exportedMetrics); + var activity = Assert.Single(stoppedActivities); + var metricPoints = this.GetMetricPoints(metric); + var metricPoint = Assert.Single(metricPoints); + + // metric value and span duration should match + // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-metrics.md#metric-httpserverrequestduration + Assert.Equal(activity.Duration.TotalSeconds, metricPoint.GetHistogramSum()); + } + } + + private List GetMetricPoints(Metric metric) + { + List metricPoints = new(); + + foreach (var metricPoint in metric.GetMetricPoints()) + { + metricPoints.Add(metricPoint); + } + + return metricPoints; } } From bd71b460e01ac0a7c080598983bb8de01383a186 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 20 Sep 2023 09:45:44 -0700 Subject: [PATCH 0823/1499] [repo] Dedicated workflows for Instrumentation.Process & Exporter.OneCollector (#1355) Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .github/codecov.yml | 25 +++++++- .../workflows/ci-Exporter.OneCollector.yml | 57 +++++++++++++++++++ .../workflows/ci-Instrumentation.Process.yml | 54 +++++++++++++----- .github/workflows/ci-aot.yml | 7 --- .github/workflows/ci.yml | 36 ++++++++++-- .github/workflows/dotnet-core-cov.yml | 53 ----------------- .github/workflows/dotnet-format.yml | 5 -- .github/workflows/integration-md.yml | 4 -- .github/workflows/integration.yml | 4 -- .github/workflows/markdownlint.yml | 4 -- .github/workflows/sanitycheck.yml | 2 - build/Common.nonprod.props | 9 ++- build/Common.props | 2 - build/process-codecoverage.ps1 | 12 ---- opentelemetry-dotnet-contrib.sln | 6 +- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 12 +--- ...enTelemetry.Exporter.InfluxDB.Tests.csproj | 6 +- ...penTelemetry.Exporter.Instana.Tests.csproj | 8 +-- ...lemetry.Exporter.OneCollector.Tests.csproj | 6 +- ...elemetry.Exporter.Stackdriver.Tests.csproj | 6 +- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 6 +- ...lemetry.Extensions.Enrichment.Tests.csproj | 6 +- .../OpenTelemetry.Extensions.Tests.csproj | 6 +- ...Telemetry.Instrumentation.AWS.Tests.csproj | 6 +- ...try.Instrumentation.AWSLambda.Tests.csproj | 6 +- ...on.AspNet.TelemetryHttpModule.Tests.csproj | 9 ++- ...emetry.Instrumentation.AspNet.Tests.csproj | 6 +- ...try.Instrumentation.Cassandra.Tests.csproj | 6 +- ...mentation.ElasticsearchClient.Tests.csproj | 6 +- ...mentation.EntityFrameworkCore.Tests.csproj | 6 +- ...Instrumentation.EventCounters.Tests.csproj | 7 +-- ...etry.Instrumentation.GrpcCore.Tests.csproj | 7 +-- ...etry.Instrumentation.Hangfire.Tests.csproj | 6 +- ...elemetry.Instrumentation.Owin.Tests.csproj | 6 +- ...metry.Instrumentation.Process.Tests.csproj | 7 +-- ...emetry.Instrumentation.Quartz.Tests.csproj | 6 +- ...metry.Instrumentation.Runtime.Tests.csproj | 7 +-- ...umentation.StackExchangeRedis.Tests.csproj | 6 +- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 6 +- ....PersistentStorage.FileSystem.Tests.csproj | 6 +- ...lemetry.ResourceDetectors.AWS.Tests.csproj | 6 +- ...metry.ResourceDetectors.Azure.Tests.csproj | 8 +-- ...y.ResourceDetectors.Container.Tests.csproj | 6 +- .../OpenTelemetry.Sampler.AWS.Tests.csproj | 6 +- 44 files changed, 194 insertions(+), 277 deletions(-) create mode 100644 .github/workflows/ci-Exporter.OneCollector.yml delete mode 100644 .github/workflows/dotnet-core-cov.yml delete mode 100644 build/process-codecoverage.ps1 diff --git a/.github/codecov.yml b/.github/codecov.yml index df54634a71..bf6b155120 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -23,6 +23,25 @@ comment: require_changes: no ignore: - - "**.md" - - "src/OpenTelemetry.Contrib.Shared" # copied from main OTel project and has code coverage there - - "test/**/*" + - "**/*.md" + - "src/Shared" # copied from main OTel project and has code coverage there + - "test" + - "examples" + - "build" + +flags: + unittests: + carryforward: true + paths: + - src + + unittests-Exporter.OneCollector: + carryforward: true + paths: + - src/OpenTelemetry.Exporter.OneCollector + + unittests-Instrumentation.Process: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Process + diff --git a/.github/workflows/ci-Exporter.OneCollector.yml b/.github/workflows/ci-Exporter.OneCollector.yml new file mode 100644 index 0000000000..7af1185e2c --- /dev/null +++ b/.github/workflows/ci-Exporter.OneCollector.yml @@ -0,0 +1,57 @@ +name: Build OpenTelemetry.Exporter.OneCollector + +on: + pull_request: + branches: [ 'main*', 'exporter*' ] + paths: + - '*/OpenTelemetry.Exporter.OneCollector*/**' + - 'build/**' + - '!**.md' + +env: + PROJECT: OpenTelemetry.Exporter.OneCollector + +jobs: + build-test: + + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + os: [ windows-latest, ubuntu-latest ] + version: [ net462, net6.0, net7.0 ] + exclude: + - os: ubuntu-latest + version: net462 + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + + - name: dotnet restore build/Projects/${{env.PROJECT}}.proj + run: dotnet restore build/Projects/${{env.PROJECT}}.proj + + - name: dotnet build build/Projects/${{env.PROJECT}}.proj + run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore + + - name: dotnet test test/${{env.PROJECT}}.Tests + run: dotnet test test/${{env.PROJECT}}.Tests --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + + - name: Install coverage tool + run: dotnet tool install -g dotnet-coverage + + - name: Merging test results + run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + + - uses: codecov/codecov-action@v3.1.4 + continue-on-error: true # Note: Don't fail for upload failures + env: + OS: ${{ matrix.os }} + TFM: ${{ matrix.version }} + with: + file: TestResults/Cobertura.xml + env_vars: OS,TFM + flags: unittests-Exporter.OneCollector + name: Code Coverage for Exporter.OneCollector on [${{ matrix.os }}.${{ matrix.version }}] diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index bd0b9bb5cf..d0db0b9c39 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -1,33 +1,57 @@ -name: Instrumentation.Process +name: Build OpenTelemetry.Instrumentation.Process on: pull_request: - branches: [ 'main*' ] + branches: [ 'main*', 'instrumentation*' ] paths: - - 'src/OpenTelemetry.Instrumentation.Process/**' - - 'test/OpenTelemetry.Instrumentation.Process.Tests/**' + - '*/OpenTelemetry.Instrumentation.Process*/**' + - 'build/**' + - '!**.md' env: - COMPONENT_NAME: OpenTelemetry.Instrumentation.Process + PROJECT: OpenTelemetry.Instrumentation.Process jobs: - unit-test: + build-test: + strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - os: [ ubuntu-latest, windows-latest ] + os: [ windows-latest, ubuntu-latest ] + version: [ net462, net6.0, net7.0 ] + exclude: + - os: ubuntu-latest + version: net462 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Install .NET 7 SDK - uses: actions/setup-dotnet@v3.2.0 - with: - dotnet-version: '7.0.x' + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + + - name: dotnet restore test/${{ env.PROJECT }}.Tests + run: dotnet restore test/${{ env.PROJECT }}.Tests + + - name: dotnet build test/${{ env.PROJECT }}.Tests + run: dotnet build test/${{ env.PROJECT }}.Tests --configuration Release --no-restore - - name: Build - run: dotnet build --configuration Release test/${{ env.COMPONENT_NAME }}.Tests/${{ env.COMPONENT_NAME }}.Tests.csproj + - name: dotnet test test/${{ env.PROJECT }}.Tests + run: dotnet test test/${{ env.PROJECT }}.Tests --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - - name: Test - run: dotnet test test/${{ env.COMPONENT_NAME }}.Tests/bin/Release/**/${{ env.COMPONENT_NAME }}.Tests.dll --logger:"console;verbosity=detailed" + - name: Install coverage tool + run: dotnet tool install -g dotnet-coverage + + - name: Merging test results + run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + + - uses: codecov/codecov-action@v3.1.4 + continue-on-error: true # Note: Don't fail for upload failures + env: + OS: ${{ matrix.os }} + TFM: ${{ matrix.version }} + with: + file: TestResults/Cobertura.xml + env_vars: OS,TFM + flags: unittests-Instrumentation.Process + name: Code Coverage for Instrumentation.Process on [${{ matrix.os }}.${{ matrix.version }}] diff --git a/.github/workflows/ci-aot.yml b/.github/workflows/ci-aot.yml index ff44f35e24..676e4ccfff 100644 --- a/.github/workflows/ci-aot.yml +++ b/.github/workflows/ci-aot.yml @@ -1,13 +1,6 @@ name: Publish AOTCompatibility testApp on: - push: - branches: [ 'main*' ] - paths: - - 'src/OpenTelemetry.Instrumentation.Runtime/**' - - '!src/OpenTelemetry.Instrumentation.Runtime/README.md' - - 'src/OpenTelemetry.Instrumentation.EventCounters/**' - - '!src/OpenTelemetry.Instrumentation.EventCounters/README.md' pull_request: branches: [ 'main*' ] paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93d5d72a49..a67fa19e3c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,14 +1,12 @@ name: Build on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.md' pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' + - '*/OpenTelemetry.Instrumentation.Process*/**' + - '*/OpenTelemetry.Exporter.OneCollector*/**' jobs: build-test: @@ -29,11 +27,37 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v3 - - name: Install dependencies + - name: Restore run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Test ${{ matrix.version }} - run: dotnet test **/bin/**/${{ matrix.version }}/*.Tests.dll --logger:"console;verbosity=detailed" + shell: pwsh + run: | + $projects = Get-ChildItem ` + -Path test/*.Tests/*.csproj ` + -Exclude OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj + + ForEach ($project in $projects) + { + dotnet test $project.FullName --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + } + + - name: Install coverage tool + run: dotnet tool install -g dotnet-coverage + + - name: Merging test results + run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + + - uses: codecov/codecov-action@v3.1.4 + continue-on-error: true # Note: Don't fail for upload failures + env: + OS: ${{ matrix.os }} + TFM: ${{ matrix.version }} + with: + file: TestResults/Cobertura.xml + env_vars: OS,TFM + flags: unittests + name: Code Coverage for solution on [${{ matrix.os }}.${{ matrix.version }}] diff --git a/.github/workflows/dotnet-core-cov.yml b/.github/workflows/dotnet-core-cov.yml deleted file mode 100644 index 388ac5730f..0000000000 --- a/.github/workflows/dotnet-core-cov.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Code Coverage - -on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.md' - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.md' - -jobs: - build-test-report: - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore - - - name: dotnet build - run: dotnet build --configuration Release --no-restore - - - name: dotnet test - run: dotnet test --collect:"Code Coverage" --results-directory:"TestResults" --configuration Release --no-build -- RunConfiguration.DisableAppDomain=true - - - name: Process code coverage - run: .\build\process-codecoverage.ps1 - shell: powershell - - - name: Install report tool - run: dotnet tool install -g dotnet-reportgenerator-globaltool - - - name: Merging test results - run: reportgenerator -reports:TestResults/**/*.xml -targetdir:TestResults -reporttypes:Cobertura - - - uses: codecov/codecov-action@v3.1.4 - with: - file: TestResults/Cobertura.xml - env_vars: OS - name: Code Coverage for ${{ matrix.os }} diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index f9886e9f5e..a74d0b8b66 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -1,11 +1,6 @@ name: dotnet format on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.cs' - - '.editorconfig' pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml index 66a9949582..915c8e70cb 100644 --- a/.github/workflows/integration-md.yml +++ b/.github/workflows/integration-md.yml @@ -1,10 +1,6 @@ name: Integration Tests on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.md' pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index b11a2b163c..da281d5359 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -1,10 +1,6 @@ name: Integration Tests on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.md' pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 736387a7d5..b7a318dbb8 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -1,10 +1,6 @@ name: markdownlint on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.md' pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths: diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 6cf97382ae..67676f3b6c 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -1,8 +1,6 @@ name: sanitycheck on: - push: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 5fcb3187f5..b82f905d82 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -21,16 +21,19 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [0.13.6,0.14) - [6.0.0,7.0.0) [2.3.1,3.0) [5.0.0,7.0) - [17.6.3,18.0) + [17.7.2,18.0) [4.18.4,5.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) [2.5.0,3.0) [2.5.0,3.0) [1.5.32,2.0) - + + + + + diff --git a/build/Common.props b/build/Common.props index 84556f1c15..7ed5728f63 100644 --- a/build/Common.props +++ b/build/Common.props @@ -29,7 +29,6 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [4.3.0,5.0) - [17.6.3] [2.1.0,5.0) [3.1.0,) [1.0.3,2.0) @@ -53,7 +52,6 @@ - diff --git a/build/process-codecoverage.ps1 b/build/process-codecoverage.ps1 deleted file mode 100644 index ff0bdf6d8f..0000000000 --- a/build/process-codecoverage.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -[xml]$commonProps = Get-Content -Path $PSScriptRoot\Common.props -$microsoftCodeCoveragePkgVer = [string]$commonProps.Project.PropertyGroup.MicrosoftCodeCoveragePkgVer # This is collected in the format: "[16.10.0]" -$microsoftCodeCoveragePkgVer = $microsoftCodeCoveragePkgVer.Trim(); -$microsoftCodeCoveragePkgVer = $microsoftCodeCoveragePkgVer.SubString(1, $microsoftCodeCoveragePkgVer.Length - 2) # Removing square brackets -$files = Get-ChildItem "TestResults" -Filter "*.coverage" -Recurse -Write-Host $env:USERPROFILE -foreach ($file in $files) -{ - $command = $env:USERPROFILE+ '\.nuget\packages\microsoft.codecoverage\' + $microsoftCodeCoveragePkgVer + '\build\netstandard2.0\CodeCoverage\CodeCoverage.exe analyze /output:' + $file.DirectoryName + '\' + $file.Name + '.xml '+ $file.FullName - Write-Host $command - Invoke-Expression $command -} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 26a25d4d9f..9bea2b5871 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -9,6 +9,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{07AA0F83-22F6-4B8C-921D-029D3384CB17}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + CODEOWNERS = CODEOWNERS CONTRIBUTING.md = CONTRIBUTING.md global.json = global.json NuGet.config = NuGet.config @@ -18,8 +19,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A06E14B-DD2F-4536-9D2E-F708C0C43555}" ProjectSection(SolutionItems) = preProject - CODEOWNERS = CODEOWNERS + .github\codecov.yml = .github\codecov.yml .github\component_owners.yml = .github\component_owners.yml + .github\dependabot.yml = .github\dependabot.yml + .github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" @@ -27,6 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml + .github\workflows\ci-Exporter.OneCollector.yml = .github\workflows\ci-Exporter.OneCollector.yml .github\workflows\ci-Instrumentation.Process.yml = .github\workflows\ci-Instrumentation.Process.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml .github\workflows\ci.yml = .github\workflows\ci.yml diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index c3933d601a..0bfa4aa284 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -11,25 +11,17 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + + diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 77f722d9ed..0a8afbb0b4 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -9,12 +9,8 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 9327ebdc7d..8894e13e55 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -8,18 +8,14 @@ - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index e2a610d9f9..e63fc170e3 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -9,12 +9,8 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 52327d652c..caf7104c03 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -11,14 +11,10 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 73a3269b37..7a272b6e5c 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -6,13 +6,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index bb5034a279..ea02e4ed0b 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -8,12 +8,8 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 5c804515d1..f337a44e1e 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -8,13 +8,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 45403f5832..2995cb98a4 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -8,14 +8,10 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 95fbba74b5..6e716a4a7a 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -8,13 +8,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index c68c2175a8..8be1376e77 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -7,14 +7,13 @@ - + + + - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index f59b1e785e..ac0591b22c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -6,14 +6,10 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 95016b6ae9..717529ac0a 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -7,15 +7,11 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index d380a9ce76..f86a5a1482 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -9,14 +9,10 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index d5a316695c..6efa9fde6f 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -15,13 +15,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 81177f9a06..3bed24dd3e 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -7,14 +7,9 @@ - - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 103afee76e..aa506d3a03 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -5,14 +5,9 @@ disable - - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 7da4e0ba0f..8b951ec26c 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -9,13 +9,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index cef5be2a1d..2b113bd700 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -7,12 +7,8 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index a391effc6c..50bb75e806 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -7,14 +7,9 @@ - - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 3844899e19..81596ee50a 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -9,15 +9,11 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 8555b84cb5..ff5d8c5322 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -7,14 +7,9 @@ - - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 77f29289fb..dfa8a0ba02 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -19,14 +19,10 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 3aa11db7b8..32a62abd6c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -9,13 +9,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 76d872a709..f3b6f2bb07 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -7,12 +7,8 @@ - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj index 12b3750bb0..0bfd267363 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj @@ -9,13 +9,9 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj index 97f3e5715f..034ad49ca2 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj @@ -1,4 +1,4 @@ - + @@ -7,12 +7,8 @@ - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj index 6c4811cb1f..ff9dc21b7b 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj @@ -9,12 +9,8 @@ - - - all - runtime; build; native; contentfiles; analyzers - + diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index e0fb3a51f5..24f730fd7b 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -6,12 +6,8 @@ - - - all - runtime; build; native; contentfiles; analyzers - + From d3fd7f4f2553f1ffd752d94f9a060dfa09681627 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 20 Sep 2023 10:46:56 -0700 Subject: [PATCH 0824/1499] [onecollector] Add integration tests (#1347) --- .../package-Exporter.OneCollector.yml | 18 +- opentelemetry-dotnet-contrib.sln | 5 +- .../EventSourceTestHelper.cs | 18 +- .../OpenTelemetry.Contrib.Tests.Shared.csproj | 2 +- .../SkipUnlessEnvVarFoundFactAttribute.cs | 22 +- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 11 +- .../OneCollectorIntegrationTests.cs | 316 ++++++++++++++++++ ...lemetry.Exporter.OneCollector.Tests.csproj | 2 + 8 files changed, 367 insertions(+), 27 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml index 7d36af02c3..216cfe1bbb 100644 --- a/.github/workflows/package-Exporter.OneCollector.yml +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -31,17 +31,19 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v3 - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} + - name: dotnet restore build/Projects/${{env.PROJECT}}.proj + run: dotnet restore build/Projects/${{env.PROJECT}}.proj - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true + - name: dotnet build build/Projects/${{env.PROJECT}}.proj + run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore -p:Deterministic=true - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests + - name: dotnet test test/${{env.PROJECT}}.Tests + run: dotnet test test/${{env.PROJECT}}.Tests --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" + env: + OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY: ${{ secrets.OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY }} - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build + - name: dotnet pack build/Projects/${{env.PROJECT}}.proj + run: dotnet pack build/Projects/${{env.PROJECT}}.proj --configuration Release --no-build --no-restore - name: Publish Artifacts uses: actions/upload-artifact@v3 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 9bea2b5871..18622206c3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -83,7 +83,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset - build\process-codecoverage.ps1 = build\process-codecoverage.ps1 build\sanitycheck.py = build\sanitycheck.py build\stylecop.json = build\stylecop.json build\test-aot-compatibility.ps1 = build\test-aot-compatibility.ps1 @@ -303,7 +302,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B examples\Directory.Build.targets = examples\Directory.Build.targets EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{D1D1B96A-77E5-443E-8B5C-93D6CE5F5337}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{048509D6-FB49-4B84-832A-90E55520B97B}" ProjectSection(SolutionItems) = preProject build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj EndProjectSection @@ -716,7 +715,7 @@ Global {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} {31937862-0C88-41C0-AFD6-F97A7BF803A9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {D1D1B96A-77E5-443E-8B5C-93D6CE5F5337} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs index 3b93d7d67a..740782be5e 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -56,7 +56,9 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn } catch (Exception e) { - var name = eventMethod.DeclaringType.Name + "." + eventMethod.Name; + var name = eventMethod.DeclaringType == null + ? eventMethod.Name + : eventMethod.DeclaringType.Name + "." + eventMethod.Name; throw new Exception("Method '" + name + "' is implemented incorrectly.", e); } @@ -87,7 +89,8 @@ private static object GenerateArgument(ParameterInfo parameter) if (parameter.ParameterType.IsValueType) { - return Activator.CreateInstance(parameter.ParameterType); + return Activator.CreateInstance(parameter.ParameterType) + ?? throw new NotSupportedException($"Could not create an instance of the '{parameter.ParameterType}' type."); } throw new NotSupportedException("Complex types are not supported"); @@ -108,9 +111,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() ?? Array.Empty()); + AssertEqual(nameof(VerifyEventMessage), expectedMessage, actualMessage); } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj index 32de4e5218..6c18cec2b5 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj +++ b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + netstandard2.0;net462;net6.0 false diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs index afb6cd8318..4d22828bda 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -14,26 +14,34 @@ // limitations under the License. // +#pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled will see warnings on using System + +#nullable enable + using System; using Xunit; namespace OpenTelemetry.Tests; -#nullable enable -internal class SkipUnlessEnvVarFoundFactAttribute : FactAttribute +internal sealed class SkipUnlessEnvVarFoundFactAttribute : FactAttribute { public SkipUnlessEnvVarFoundFactAttribute(string environmentVariable) { - var environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariable, EnvironmentVariableTarget.Process)!; - - if (string.IsNullOrEmpty(environmentVariableValue)) + if (string.IsNullOrEmpty(GetEnvironmentVariable(environmentVariable))) { - environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariable, EnvironmentVariableTarget.Machine); + this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; } + } + + public static string? GetEnvironmentVariable(string environmentVariableName) + { + var environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); if (string.IsNullOrEmpty(environmentVariableValue)) { - this.Skip = $"Skipped because {environmentVariable} environment variable was not configured."; + environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Machine); } + + return environmentVariableValue; } } diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 34b96ceae4..17ea6d220d 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -13,12 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. // + +#pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled will see warnings on using System + +#nullable enable + using System; using Xunit; namespace OpenTelemetry.Tests; -internal class SkipUnlessEnvVarFoundTheoryAttribute : TheoryAttribute +internal sealed class SkipUnlessEnvVarFoundTheoryAttribute : TheoryAttribute { public SkipUnlessEnvVarFoundTheoryAttribute(string environmentVariable) { @@ -28,9 +33,9 @@ public SkipUnlessEnvVarFoundTheoryAttribute(string environmentVariable) } } - public static string GetEnvironmentVariable(string environmentVariableName) + public static string? GetEnvironmentVariable(string environmentVariableName) { - string environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); + var environmentVariableValue = Environment.GetEnvironmentVariable(environmentVariableName, EnvironmentVariableTarget.Process); if (string.IsNullOrEmpty(environmentVariableValue)) { diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs new file mode 100644 index 0000000000..3993f6bd5c --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs @@ -0,0 +1,316 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Internal; +using OpenTelemetry.Logs; +using OpenTelemetry.Resources; +using OpenTelemetry.Tests; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +[Trait("CategoryName", "OneCollectorIntegrationTests")] +public class OneCollectorIntegrationTests +{ + private const string OneCollectorInstrumentationKeyEnvName = "OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY"; + private readonly ITestOutputHelper testOutputHelper; + + public OneCollectorIntegrationTests(ITestOutputHelper output) + { + this.testOutputHelper = output; + } + + [SkipUnlessEnvVarFoundFact(OneCollectorInstrumentationKeyEnvName)] + public void LogWithEventIdAndNameIntegrationTest() + { + this.RunIntegrationTest( + logger => + { + logger.LogInformation( + new EventId(18, "MyEvent"), + "Hello world"); + }, + out var succeeded, + out var actualJson); + + Assert.True(succeeded); + Assert.NotNull(actualJson); + + AssertActualJson( + actualJson, + root => + { + Assert.Equal($"{nameof(OneCollectorIntegrationTests)}.MyEvent", root.GetProperty("name").GetString()); + }, + data => + { + Assert.Equal("Information", data.GetProperty("severityText").GetString()); + Assert.Equal(9, data.GetProperty("severityNumber").GetInt32()); + Assert.Equal("Hello world", data.GetProperty("body").GetString()); + Assert.Equal(18, data.GetProperty("eventId").GetInt32()); + }); + } + + [SkipUnlessEnvVarFoundFact(OneCollectorInstrumentationKeyEnvName)] + public void LogWithEventNameOnlyIntegrationTest() + { + this.RunIntegrationTest( + logger => + { + logger.LogInformation( + new EventId(0, "MyEvent"), + "Hello world"); + }, + out var succeeded, + out var actualJson); + + Assert.True(succeeded); + Assert.NotNull(actualJson); + + AssertActualJson( + actualJson, + root => + { + Assert.Equal($"{nameof(OneCollectorIntegrationTests)}.MyEvent", root.GetProperty("name").GetString()); + }, + data => + { + Assert.Equal("Information", data.GetProperty("severityText").GetString()); + Assert.Equal(9, data.GetProperty("severityNumber").GetInt32()); + Assert.Equal("Hello world", data.GetProperty("body").GetString()); + AssertPropertyDoesNotExist(data, "eventId"); + }); + } + + [SkipUnlessEnvVarFoundFact(OneCollectorInstrumentationKeyEnvName)] + public void LogWithDataIntegrationTest() + { + this.RunIntegrationTest( + logger => + { + logger.LogInformation("Hello world {StructuredData}", "Goodbye world"); + }, + out var succeeded, + out var actualJson); + + Assert.True(succeeded); + Assert.NotNull(actualJson); + + AssertActualJson( + actualJson, + root => + { + Assert.Equal($"{nameof(OneCollectorIntegrationTests)}.Log", root.GetProperty("name").GetString()); + }, + data => + { + Assert.Equal("Information", data.GetProperty("severityText").GetString()); + Assert.Equal(9, data.GetProperty("severityNumber").GetInt32()); + Assert.Equal("Hello world {StructuredData}", data.GetProperty("body").GetString()); + Assert.Equal("Goodbye world", data.GetProperty("StructuredData").GetString()); + }); + } + + [SkipUnlessEnvVarFoundTheory(OneCollectorInstrumentationKeyEnvName)] + [InlineData(false)] + [InlineData(true)] + public void LogWithExceptionIntegrationTest(bool includeStackTrace) + { + var ex = new Exception("Test exception"); + + this.RunIntegrationTest( + logger => + { + logger.LogInformation(ex, "Hello world"); + }, + out var succeeded, + out var actualJson, + configureBuilderAction: builder => builder + .ConfigureSerializationOptions(options => options.ExceptionStackTraceHandling = includeStackTrace + ? OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString + : OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore)); + + // TODO: Switch this to true. OneCollector doesn't currently support + // ext.ex (Exception Extension) but it should soon. + Assert.False(succeeded); + Assert.NotNull(actualJson); + + AssertActualJson( + actualJson, + root => + { + Assert.Equal($"{nameof(OneCollectorIntegrationTests)}.Log", root.GetProperty("name").GetString()); + }, + data => + { + Assert.Equal("Information", data.GetProperty("severityText").GetString()); + Assert.Equal(9, data.GetProperty("severityNumber").GetInt32()); + Assert.Equal("Hello world", data.GetProperty("body").GetString()); + }, + extensions => + { + var exceptionExtension = extensions.GetProperty("ex"); + + var type = exceptionExtension.GetProperty("type").GetString(); + var msg = exceptionExtension.GetProperty("msg").GetString(); + + Assert.Equal(ex.GetType().FullName, type); + Assert.Equal(ex.Message, msg); + + if (!includeStackTrace) + { + AssertPropertyDoesNotExist(exceptionExtension, "stack"); + } + else + { + var stack = exceptionExtension.GetProperty("stack").GetString(); + + Assert.Equal(ex.ToInvariantString(), stack); + } + }); + } + + [SkipUnlessEnvVarFoundFact(OneCollectorInstrumentationKeyEnvName)] + public void LogWithActivityIntegrationTest() + { + using var activity = new Activity("TestOperation"); + activity.Start(); + + this.RunIntegrationTest( + logger => + { + logger.LogInformation("Hello world"); + }, + out var succeeded, + out var actualJson); + + Assert.True(succeeded); + Assert.NotNull(actualJson); + + AssertActualJson( + actualJson, + root => + { + Assert.Equal($"{nameof(OneCollectorIntegrationTests)}.Log", root.GetProperty("name").GetString()); + }, + data => + { + Assert.Equal("Information", data.GetProperty("severityText").GetString()); + Assert.Equal(9, data.GetProperty("severityNumber").GetInt32()); + Assert.Equal("Hello world", data.GetProperty("body").GetString()); + }, + extensions => + { + var distributedTraceExtension = extensions.GetProperty("dt"); + + var traceId = distributedTraceExtension.GetProperty("traceId").GetString(); + var spanId = distributedTraceExtension.GetProperty("spanId").GetString(); + + Assert.Equal(activity.TraceId.ToHexString(), traceId); + Assert.Equal(activity.SpanId.ToHexString(), spanId); + }); + } + + private static void AssertActualJson( + string actualJson, + Action assertRootElement, + Action assertDataElement, + Action? assertExtensionElement = null) + { + var document = JsonDocument.Parse(actualJson); + + var rootElement = document.RootElement; + + Assert.Equal("4.0", rootElement.GetProperty("ver").GetString()); + Assert.True(!string.IsNullOrWhiteSpace(rootElement.GetProperty("time").GetString())); + Assert.True(!string.IsNullOrWhiteSpace(rootElement.GetProperty("iKey").GetString())); + + assertRootElement(rootElement); + + var data = rootElement.GetProperty("data"); + + assertDataElement(data); + + if (assertExtensionElement != null) + { + var extensions = rootElement.GetProperty("ext"); + + assertExtensionElement(extensions); + } + else + { + AssertPropertyDoesNotExist(rootElement, "ext"); + } + } + + private static void AssertPropertyDoesNotExist(JsonElement element, string propertyName) + { + if (element.TryGetProperty(propertyName, out _)) + { + Assert.Fail($"Property '{propertyName}' was found in JSON"); + } + } + + private void RunIntegrationTest( + Action testAction, + out bool succeeded, + out string? actualJson, + Action? configureOptionsAction = null, + Action? configureBuilderAction = null) + { + var innerSucceeded = false; + string? innerActualJson = null; + + using (var loggerFactory = LoggerFactory.Create(logging => logging + .AddOpenTelemetry(options => + { + options + .SetResourceBuilder(ResourceBuilder.CreateEmpty()) + .AddOneCollectorExporter(builder => + { + builder.SetConnectionString($"InstrumentationKey={Environment.GetEnvironmentVariable(OneCollectorInstrumentationKeyEnvName)}"); + + builder.ConfigureExporter(e => e.RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction, includeFailures: true)); + + configureBuilderAction?.Invoke(builder); + }); + + configureOptionsAction?.Invoke(options); + }))) + { + testAction(loggerFactory.CreateLogger(nameof(OneCollectorIntegrationTests))); + } + + succeeded = innerSucceeded; + actualJson = innerActualJson; + + this.testOutputHelper.WriteLine($"ActualJson: {actualJson}"); + + void OneCollectorExporterPayloadTransmittedCallbackAction( + in OneCollectorExporterPayloadTransmittedCallbackArguments args) + { + innerSucceeded = args.Succeeded; + using var memoryStream = new MemoryStream(); + args.CopyPayloadToStream(memoryStream); + innerActualJson = Encoding.UTF8.GetString(memoryStream.ToArray()); + } + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index e63fc170e3..7870b2458d 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -20,6 +20,8 @@ + + From d4d77ec286546668da3356e1102cb90e684933c3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 20 Sep 2023 10:53:55 -0700 Subject: [PATCH 0825/1499] [OneCollector] 1.6.0-beta.1 release (#1364) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index cab0a366f9..46d31e859c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-beta.1 + +Released 2023-Sep-20 + * Update OpenTelemetry to 1.6.0 ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) From b923963d9e17b1ce61b2f532454cb783d2cb0c90 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 20 Sep 2023 11:10:20 -0700 Subject: [PATCH 0826/1499] [repo] Move xunit references for test projects into props (#1363) Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- build/Common.nonprod.props | 8 ++++++-- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 9 --------- .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 3 --- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 2 -- .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 3 --- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 3 --- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 3 --- .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 6 ------ .../OpenTelemetry.Extensions.Tests.csproj | 6 ------ .../OpenTelemetry.Instrumentation.AWS.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj | 3 --- ...strumentation.AspNet.TelemetryHttpModule.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.AspNet.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.Cassandra.Tests.csproj | 3 --- ...etry.Instrumentation.ElasticsearchClient.Tests.csproj | 4 ---- ...etry.Instrumentation.EntityFrameworkCore.Tests.csproj | 3 --- ...nTelemetry.Instrumentation.EventCounters.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj | 7 ++++--- .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.Owin.Tests.csproj | 6 ------ .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 3 --- ...metry.Instrumentation.StackExchangeRedis.Tests.csproj | 3 --- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 4 +--- ...enTelemetry.PersistentStorage.FileSystem.Tests.csproj | 5 ----- .../OpenTelemetry.ResourceDetectors.AWS.Tests.csproj | 5 ++--- .../OpenTelemetry.ResourceDetectors.Azure.Tests.csproj | 6 +----- ...penTelemetry.ResourceDetectors.Container.Tests.csproj | 6 ------ .../OpenTelemetry.Sampler.AWS.Tests.csproj | 3 --- 30 files changed, 14 insertions(+), 111 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index b82f905d82..df9574bca7 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -32,8 +32,12 @@ [1.5.32,2.0) - - + + + + + + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 0bfa4aa284..bfffacbcc4 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -16,15 +16,6 @@ - - - - - - - - - diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 0a8afbb0b4..87bf79f2a0 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -9,10 +9,7 @@ - - - diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 8894e13e55..585b0cf1da 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -9,8 +9,6 @@ - - diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 7870b2458d..67ad9a00f3 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -9,10 +9,7 @@ - - - diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index caf7104c03..d0cd829938 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -13,8 +13,5 @@ - - - diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 7a272b6e5c..75526609ef 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -6,10 +6,7 @@ - - - diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index ea02e4ed0b..e0814e4c98 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -7,12 +7,6 @@ disable - - - - - - diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index f337a44e1e..3b61643e38 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -9,12 +9,6 @@ - - - - - - diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 2995cb98a4..f646ccf58e 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -8,11 +8,8 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 6e716a4a7a..38af282d51 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -8,10 +8,7 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index 8be1376e77..88d63d331b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -12,9 +12,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index ac0591b22c..382363406d 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -8,9 +8,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 717529ac0a..965d9f2ce6 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -9,11 +9,8 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index f86a5a1482..7b69af190b 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -11,10 +11,6 @@ - - - - diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 6efa9fde6f..ac4831069b 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -16,9 +16,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 3bed24dd3e..32a467c3b6 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -8,9 +8,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index aa506d3a03..38995ee86f 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -4,18 +4,19 @@ net6.0 disable + - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 8b951ec26c..199b37903a 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -10,9 +10,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index 2b113bd700..1ef3fee142 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -6,12 +6,6 @@ disable - - - - - - diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 50bb75e806..6b4c458df2 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -8,9 +8,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 81596ee50a..856abb3bba 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -12,9 +12,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index ff5d8c5322..495a08704c 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -8,9 +8,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index dfa8a0ba02..e6f92d872f 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -21,9 +21,6 @@ - - - diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 32a62abd6c..15fd623005 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -10,9 +10,6 @@ - - - @@ -33,4 +30,5 @@ + diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index f3b6f2bb07..5c4dd8508c 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -6,11 +6,6 @@ $(TargetFrameworks);net462 - - - - - diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj index 0bfd267363..269f3a5b8a 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj @@ -10,9 +10,6 @@ - - - @@ -35,6 +32,7 @@ + PreserveNewest @@ -46,4 +44,5 @@ PreserveNewest + diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj index 034ad49ca2..a908c45e6f 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj @@ -6,12 +6,8 @@ $(TargetFrameworks);net462 - - - - - + diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj index ff9dc21b7b..6977c6ecbe 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj @@ -8,12 +8,6 @@ enable - - - - - - diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 24f730fd7b..29b2484d01 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -6,9 +6,6 @@ - - - From 21a9bc3871548651e312814c96583c53f9fa7ef6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 20 Sep 2023 11:42:07 -0700 Subject: [PATCH 0827/1499] [repo] Add dedicated CI for Geneva Exporter (#1365) --- .github/codecov.yml | 5 ++ .github/workflows/ci-Exporter.Geneva.yml | 57 +++++++++++++++++++ .github/workflows/ci.yml | 3 +- .../OpenTelemetry.Exporter.Geneva.proj | 28 +++++++++ opentelemetry-dotnet-contrib.sln | 2 + 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-Exporter.Geneva.yml create mode 100644 build/Projects/OpenTelemetry.Exporter.Geneva.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index bf6b155120..e28e1f2fce 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -35,6 +35,11 @@ flags: paths: - src + unittests-Exporter.Geneva: + carryforward: true + paths: + - src/OpenTelemetry.Exporter.Geneva + unittests-Exporter.OneCollector: carryforward: true paths: diff --git a/.github/workflows/ci-Exporter.Geneva.yml b/.github/workflows/ci-Exporter.Geneva.yml new file mode 100644 index 0000000000..7e99774c4c --- /dev/null +++ b/.github/workflows/ci-Exporter.Geneva.yml @@ -0,0 +1,57 @@ +name: Build OpenTelemetry.Exporter.Geneva + +on: + pull_request: + branches: [ 'main*', 'exporter*' ] + paths: + - '*/OpenTelemetry.Exporter.Geneva*/**' + - 'build/**' + - '!**.md' + +env: + PROJECT: OpenTelemetry.Exporter.Geneva + +jobs: + build-test: + + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + os: [ windows-latest, ubuntu-latest ] + version: [ net462, net6.0, net7.0 ] + exclude: + - os: ubuntu-latest + version: net462 + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + + - name: dotnet restore build/Projects/${{env.PROJECT}}.proj + run: dotnet restore build/Projects/${{env.PROJECT}}.proj + + - name: dotnet build build/Projects/${{env.PROJECT}}.proj + run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore + + - name: dotnet test test/${{env.PROJECT}}.Tests + run: dotnet test test/${{env.PROJECT}}.Tests --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + + - name: Install coverage tool + run: dotnet tool install -g dotnet-coverage + + - name: Merging test results + run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + + - uses: codecov/codecov-action@v3.1.4 + continue-on-error: true # Note: Don't fail for upload failures + env: + OS: ${{ matrix.os }} + TFM: ${{ matrix.version }} + with: + file: TestResults/Cobertura.xml + env_vars: OS,TFM + flags: unittests-Exporter.Geneva + name: Code Coverage for Exporter.Geneva on [${{ matrix.os }}.${{ matrix.version }}] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a67fa19e3c..f0985545b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,7 @@ on: paths-ignore: - '**.md' - '*/OpenTelemetry.Instrumentation.Process*/**' + - '*/OpenTelemetry.Exporter.Geneva*/**' - '*/OpenTelemetry.Exporter.OneCollector*/**' jobs: @@ -38,7 +39,7 @@ jobs: run: | $projects = Get-ChildItem ` -Path test/*.Tests/*.csproj ` - -Exclude OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj + -Exclude OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Exporter.Geneva.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj ForEach ($project in $projects) { diff --git a/build/Projects/OpenTelemetry.Exporter.Geneva.proj b/build/Projects/OpenTelemetry.Exporter.Geneva.proj new file mode 100644 index 0000000000..dc1e79aafa --- /dev/null +++ b/build/Projects/OpenTelemetry.Exporter.Geneva.proj @@ -0,0 +1,28 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 18622206c3..da36821074 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -29,6 +29,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml + .github\workflows\ci-Exporter.Geneva.yml = .github\workflows\ci-Exporter.Geneva.yml .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml .github\workflows\ci-Exporter.OneCollector.yml = .github\workflows\ci-Exporter.OneCollector.yml .github\workflows\ci-Instrumentation.Process.yml = .github\workflows\ci-Instrumentation.Process.yml @@ -304,6 +305,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{048509D6-FB49-4B84-832A-90E55520B97B}" ProjectSection(SolutionItems) = preProject + build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj EndProjectSection EndProject From f1d19398539145fbd2621a86e31a5a2c033f95e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 20 Sep 2023 22:26:48 +0200 Subject: [PATCH 0828/1499] Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource being created (#1362) --- build/Common.props | 10 ++-- .../CHANGELOG.md | 3 + .../ElasticsearchClientInstrumentation.cs | 2 +- ...ElasticsearchInstrumentationEventSource.cs | 17 +++++- ...Instrumentation.ElasticsearchClient.csproj | 1 + .../CHANGELOG.md | 4 ++ .../EntityFrameworkInstrumentation.cs | 3 +- ...tityFrameworkInstrumentationEventSource.cs | 2 +- ...Instrumentation.EntityFrameworkCore.csproj | 1 + .../CHANGELOG.md | 3 + .../QuartzInstrumentationEventSource.cs | 15 +++++ ...penTelemetry.Instrumentation.Quartz.csproj | 1 + .../QuartzJobInstrumentation.cs | 3 +- src/Shared/DiagnosticSourceListener.cs | 7 ++- src/Shared/DiagnosticSourceSubscriber.cs | 16 +++--- src/Shared/InstrumentationEventSource.cs | 55 ------------------- 16 files changed, 70 insertions(+), 73 deletions(-) delete mode 100644 src/Shared/InstrumentationEventSource.cs diff --git a/build/Common.props b/build/Common.props index 7ed5728f63..e57d37e80c 100644 --- a/build/Common.props +++ b/build/Common.props @@ -60,10 +60,6 @@ - - - - @@ -71,6 +67,12 @@ + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index fad5bc76af..d063132527 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource + being created + ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) * Updated OpenTelemetry SDK package version to 1.6.0 ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs index 42d4241f73..a1269567c5 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs @@ -31,7 +31,7 @@ internal class ElasticsearchClientInstrumentation : IDisposable /// Configuration options for Elasticsearch client instrumentation. public ElasticsearchClientInstrumentation(ElasticsearchClientInstrumentationOptions options) { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new ElasticsearchRequestPipelineDiagnosticListener(options), null); + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new ElasticsearchRequestPipelineDiagnosticListener(options), null, ElasticsearchInstrumentationEventSource.Log.UnknownErrorProcessingEvent); this.diagnosticSourceSubscriber.Subscribe(); } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs index ecbc51ad4a..757eb90ce9 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs @@ -26,7 +26,7 @@ namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; [EventSource(Name = "OpenTelemetry-Instrumentation-Elasticsearch")] internal class ElasticsearchInstrumentationEventSource : EventSource { - public static ElasticsearchInstrumentationEventSource Log = new ElasticsearchInstrumentationEventSource(); + public static ElasticsearchInstrumentationEventSource Log = new(); [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] public void NullPayload(string handlerName, string eventName) @@ -48,4 +48,19 @@ public void EnrichmentException(string exception) { this.WriteEvent(2, exception); } + + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) + { + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); + } + } + + [Event(3, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(3, handlerName, eventName, ex); + } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 3777bb7516..63005a2e97 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -8,6 +8,7 @@ Instrumentation.ElasticsearchClient- true true + true disable diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index c6b9ff81d9..e2e2bbc727 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -9,6 +9,10 @@ * Updated OpenTelemetry SDK package version to 1.6.0 ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource + being created + ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) + ## 1.0.0-beta.7 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 5f2a439188..30181f72b1 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -28,7 +28,8 @@ public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions opti this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( name => new EntityFrameworkDiagnosticListener(name, options), listener => listener.Name == EntityFrameworkDiagnosticListener.DiagnosticSourceName, - null); + null, + EntityFrameworkInstrumentationEventSource.Log.UnknownErrorProcessingEvent); this.diagnosticSourceSubscriber.Subscribe(); } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 4736821a16..bb4960791e 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -23,7 +23,7 @@ namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; [EventSource(Name = "OpenTelemetry-Instrumentation-EntityFrameworkCore")] internal class EntityFrameworkInstrumentationEventSource : EventSource { - public static EntityFrameworkInstrumentationEventSource Log = new EntityFrameworkInstrumentationEventSource(); + public static EntityFrameworkInstrumentationEventSource Log = new(); [NonEvent] public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 3906fcc898..a15af04bf1 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -6,6 +6,7 @@ Instrumentation.EntityFrameworkCore- true true + true disable diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index b31ff113c4..4676dee4af 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource + being created + ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) * Update OpenTelemetry.Api to 1.6.0. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs index a0e0d26293..03a88401fd 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -54,4 +54,19 @@ public void EnrichmentException(string exception) { this.WriteEvent(3, exception); } + + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) + { + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); + } + } + + [Event(4, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(4, handlerName, eventName, ex); + } } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index c794f15c85..49c2b03d7d 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -6,6 +6,7 @@ true netstandard2.0 true + true diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs index 2ab0ca89d6..d33e6692bb 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs @@ -34,7 +34,8 @@ public QuartzJobInstrumentation(QuartzInstrumentationOptions options) this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( name => new QuartzDiagnosticListener(name, options), listener => listener.Name == QuartzDiagnosticListenerName, - null); + null, + QuartzInstrumentationEventSource.Log.UnknownErrorProcessingEvent); this.diagnosticSourceSubscriber.Subscribe(); } diff --git a/src/Shared/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs index 38a6ee2410..3c16815cc7 100644 --- a/src/Shared/DiagnosticSourceListener.cs +++ b/src/Shared/DiagnosticSourceListener.cs @@ -29,11 +29,14 @@ internal sealed class DiagnosticSourceListener : IObserver logUnknownException; + + public DiagnosticSourceListener(ListenerHandler handler, Action logUnknownException) { Guard.ThrowIfNull(handler); this.handler = handler; + this.logUnknownException = logUnknownException; } public void OnCompleted() @@ -72,7 +75,7 @@ public void OnNext(KeyValuePair value) } catch (Exception ex) { - InstrumentationEventSource.Log.UnknownErrorProcessingEvent(this.handler?.SourceName, value.Key, ex); + this.logUnknownException?.Invoke(this.handler?.SourceName, value.Key, ex); } } } diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index 5435b90a3f..c0d931652f 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -26,28 +26,29 @@ namespace OpenTelemetry.Instrumentation; -#pragma warning disable CA1812 internal sealed class DiagnosticSourceSubscriber : IDisposable, IObserver -#pragma warning restore CA1812 { + private readonly List listenerSubscriptions; private readonly Func handlerFactory; private readonly Func diagnosticSourceFilter; private readonly Func isEnabledFilter; + private readonly Action logUnknownException; private long disposed; private IDisposable allSourcesSubscription; - private List listenerSubscriptions; public DiagnosticSourceSubscriber( ListenerHandler handler, - Func isEnabledFilter) - : this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter) + Func isEnabledFilter, + Action logUnknownException) + : this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter, logUnknownException) { } public DiagnosticSourceSubscriber( Func handlerFactory, Func diagnosticSourceFilter, - Func isEnabledFilter) + Func isEnabledFilter, + Action logUnknownException) { Guard.ThrowIfNull(handlerFactory); @@ -55,6 +56,7 @@ public DiagnosticSourceSubscriber( this.handlerFactory = handlerFactory; this.diagnosticSourceFilter = diagnosticSourceFilter; this.isEnabledFilter = isEnabledFilter; + this.logUnknownException = logUnknownException; } public void Subscribe() @@ -71,7 +73,7 @@ public void OnNext(DiagnosticListener value) this.diagnosticSourceFilter(value)) { var handler = this.handlerFactory(value.Name); - var listener = new DiagnosticSourceListener(handler); + var listener = new DiagnosticSourceListener(handler, this.logUnknownException); var subscription = this.isEnabledFilter == null ? value.Subscribe(listener) : value.Subscribe(listener, this.isEnabledFilter); diff --git a/src/Shared/InstrumentationEventSource.cs b/src/Shared/InstrumentationEventSource.cs deleted file mode 100644 index 4321679472..0000000000 --- a/src/Shared/InstrumentationEventSource.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#nullable disable - -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System; -using System.Diagnostics.Tracing; -using OpenTelemetry.Internal; -#pragma warning restore IDE0005 // Using directive is unnecessary. - -namespace OpenTelemetry.Instrumentation; - -/// -/// EventSource events emitted from the project. -/// -[EventSource(Name = "OpenTelemetry-Instrumentation")] -internal sealed class InstrumentationEventSource : EventSource -{ - public static InstrumentationEventSource Log = new InstrumentationEventSource(); - - [Event(1, Message = "Current Activity is NULL in the '{0}' callback. Activity will not be recorded.", Level = EventLevel.Warning)] - public void NullActivity(string eventName) - { - this.WriteEvent(1, eventName); - } - - [NonEvent] - public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) - { - if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1))) - { - this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); - } - } - - [Event(2, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] - public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) - { - this.WriteEvent(2, handlerName, eventName, ex); - } -} From 5cb78d496de5e47b0d3cc4da4142128cb95b8f71 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 22 Sep 2023 10:09:33 -0700 Subject: [PATCH 0829/1499] [repo] Use reusable workflows for build & package processing (#1368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/workflows/Component.BuildTest.yml | 61 +++++++++++++++++++ .github/workflows/Component.Package.yml | 60 ++++++++++++++++++ .github/workflows/ci-Exporter.Geneva.yml | 51 ++-------------- .../workflows/ci-Exporter.OneCollector.yml | 51 ++-------------- .../workflows/ci-Instrumentation.Process.yml | 50 ++------------- .github/workflows/package-Exporter.Geneva.yml | 55 ++--------------- .../package-Exporter.OneCollector.yml | 57 ++--------------- .../package-Instrumentation.Process.yml | 55 ++--------------- ...OpenTelemetry.Instrumentation.Process.proj | 26 ++++++++ opentelemetry-dotnet-contrib.sln | 3 + 10 files changed, 180 insertions(+), 289 deletions(-) create mode 100644 .github/workflows/Component.BuildTest.yml create mode 100644 .github/workflows/Component.Package.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.Process.proj diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml new file mode 100644 index 0000000000..b257db5d1d --- /dev/null +++ b/.github/workflows/Component.BuildTest.yml @@ -0,0 +1,61 @@ +name: Build Component + +on: + workflow_call: + inputs: + project-name: + required: true + type: string + code-cov-name: + required: true + type: string + code-cov-prefix: + default: 'unittests' + required: false + type: string + +jobs: + build-test: + + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + os: [ windows-latest, ubuntu-latest ] + version: [ net462, net6.0, net7.0 ] + exclude: + - os: ubuntu-latest + version: net462 + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + + - name: dotnet restore build/Projects/${{ inputs.project-name }}.proj + run: dotnet restore build/Projects/${{ inputs.project-name }}.proj + + - name: dotnet build build/Projects/${{ inputs.project-name }}.proj + run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore + + - name: dotnet test test/${{ inputs.project-name }}.Tests + run: dotnet test test/${{ inputs.project-name }}.Tests --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + + - name: Install coverage tool + run: dotnet tool install -g dotnet-coverage + + - name: Merging test results + run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + + - name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} + uses: codecov/codecov-action@v3.1.4 + continue-on-error: true # Note: Don't fail for upload failures + env: + OS: ${{ matrix.os }} + TFM: ${{ matrix.version }} + with: + file: TestResults/Cobertura.xml + env_vars: OS,TFM + flags: ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} + name: Code Coverage for ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} on [${{ matrix.os }}.${{ matrix.version }}] diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml new file mode 100644 index 0000000000..86fbccca33 --- /dev/null +++ b/.github/workflows/Component.Package.yml @@ -0,0 +1,60 @@ +name: Pack Component + +on: + workflow_call: + inputs: + project-name: + required: true + type: string + +jobs: + build-test-pack: + permissions: + contents: write + + strategy: + matrix: + os: [windows-latest] + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # fetching all + + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + + - name: dotnet restore build/Projects/${{ inputs.project-name }}.proj + run: dotnet restore build/Projects/${{ inputs.project-name }}.proj + + - name: dotnet build build/Projects/${{ inputs.project-name }}.proj + run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore -p:Deterministic=true + + - name: dotnet test test/${{ inputs.project-name }}.Tests + run: dotnet test test/${{ inputs.project-name }}.Tests --configuration Release --no-restore --no-build + + - name: dotnet pack build/Projects/${{ inputs.project-name }}.proj + run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-build --no-restore + + - name: Publish Artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.project-name }}-packages + path: '**/${{ inputs.project-name }}/bin/**/*.*nupkg' + + - name: Publish Nuget + run: | + nuget push **/${{ inputs.project-name }}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + + - name: Create GitHub Prerelease + if: ${{ (contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{ inputs.project-name }}/CHANGELOG.md) for details." --prerelease + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create GitHub Release + if: ${{ !(contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc')) }} + run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{ inputs.project-name }}/CHANGELOG.md) for details." --latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci-Exporter.Geneva.yml b/.github/workflows/ci-Exporter.Geneva.yml index 7e99774c4c..f847305179 100644 --- a/.github/workflows/ci-Exporter.Geneva.yml +++ b/.github/workflows/ci-Exporter.Geneva.yml @@ -8,50 +8,9 @@ on: - 'build/**' - '!**.md' -env: - PROJECT: OpenTelemetry.Exporter.Geneva - jobs: - build-test: - - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] - exclude: - - os: ubuntu-latest - version: net462 - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: dotnet restore build/Projects/${{env.PROJECT}}.proj - run: dotnet restore build/Projects/${{env.PROJECT}}.proj - - - name: dotnet build build/Projects/${{env.PROJECT}}.proj - run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore - - - name: dotnet test test/${{env.PROJECT}}.Tests - run: dotnet test test/${{env.PROJECT}}.Tests --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - - - name: Install coverage tool - run: dotnet tool install -g dotnet-coverage - - - name: Merging test results - run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - - - uses: codecov/codecov-action@v3.1.4 - continue-on-error: true # Note: Don't fail for upload failures - env: - OS: ${{ matrix.os }} - TFM: ${{ matrix.version }} - with: - file: TestResults/Cobertura.xml - env_vars: OS,TFM - flags: unittests-Exporter.Geneva - name: Code Coverage for Exporter.Geneva on [${{ matrix.os }}.${{ matrix.version }}] + call-build-test: + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Exporter.Geneva + code-cov-name: Exporter.Geneva diff --git a/.github/workflows/ci-Exporter.OneCollector.yml b/.github/workflows/ci-Exporter.OneCollector.yml index 7af1185e2c..d652649d63 100644 --- a/.github/workflows/ci-Exporter.OneCollector.yml +++ b/.github/workflows/ci-Exporter.OneCollector.yml @@ -8,50 +8,9 @@ on: - 'build/**' - '!**.md' -env: - PROJECT: OpenTelemetry.Exporter.OneCollector - jobs: - build-test: - - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] - exclude: - - os: ubuntu-latest - version: net462 - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: dotnet restore build/Projects/${{env.PROJECT}}.proj - run: dotnet restore build/Projects/${{env.PROJECT}}.proj - - - name: dotnet build build/Projects/${{env.PROJECT}}.proj - run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore - - - name: dotnet test test/${{env.PROJECT}}.Tests - run: dotnet test test/${{env.PROJECT}}.Tests --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - - - name: Install coverage tool - run: dotnet tool install -g dotnet-coverage - - - name: Merging test results - run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - - - uses: codecov/codecov-action@v3.1.4 - continue-on-error: true # Note: Don't fail for upload failures - env: - OS: ${{ matrix.os }} - TFM: ${{ matrix.version }} - with: - file: TestResults/Cobertura.xml - env_vars: OS,TFM - flags: unittests-Exporter.OneCollector - name: Code Coverage for Exporter.OneCollector on [${{ matrix.os }}.${{ matrix.version }}] + call-build-test: + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Exporter.OneCollector + code-cov-name: Exporter.OneCollector diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index d0db0b9c39..63c394e1aa 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -8,50 +8,10 @@ on: - 'build/**' - '!**.md' -env: - PROJECT: OpenTelemetry.Instrumentation.Process - jobs: - build-test: - - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] - exclude: - - os: ubuntu-latest - version: net462 - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: dotnet restore test/${{ env.PROJECT }}.Tests - run: dotnet restore test/${{ env.PROJECT }}.Tests - - - name: dotnet build test/${{ env.PROJECT }}.Tests - run: dotnet build test/${{ env.PROJECT }}.Tests --configuration Release --no-restore - - - name: dotnet test test/${{ env.PROJECT }}.Tests - run: dotnet test test/${{ env.PROJECT }}.Tests --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - - - name: Install coverage tool - run: dotnet tool install -g dotnet-coverage - - - name: Merging test results - run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage + call-build-test: + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Process + code-cov-name: Instrumentation.Process - - uses: codecov/codecov-action@v3.1.4 - continue-on-error: true # Note: Don't fail for upload failures - env: - OS: ${{ matrix.os }} - TFM: ${{ matrix.version }} - with: - file: TestResults/Cobertura.xml - env_vars: OS,TFM - flags: unittests-Instrumentation.Process - name: Code Coverage for Instrumentation.Process on [${{ matrix.os }}.${{ matrix.version }}] diff --git a/.github/workflows/package-Exporter.Geneva.yml b/.github/workflows/package-Exporter.Geneva.yml index af95b2db72..48cbe29db8 100644 --- a/.github/workflows/package-Exporter.Geneva.yml +++ b/.github/workflows/package-Exporter.Geneva.yml @@ -12,55 +12,10 @@ on: - 'Exporter.Geneva-*' # trigger when we create a tag with prefix "Exporter.Geneva-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Exporter.Geneva - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Exporter.Geneva + secrets: inherit diff --git a/.github/workflows/package-Exporter.OneCollector.yml b/.github/workflows/package-Exporter.OneCollector.yml index 216cfe1bbb..c347c44a89 100644 --- a/.github/workflows/package-Exporter.OneCollector.yml +++ b/.github/workflows/package-Exporter.OneCollector.yml @@ -12,57 +12,10 @@ on: - 'Exporter.OneCollector-*' # trigger when we create a tag with prefix "Exporter.OneCollector-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Exporter.OneCollector - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: dotnet restore build/Projects/${{env.PROJECT}}.proj - run: dotnet restore build/Projects/${{env.PROJECT}}.proj - - - name: dotnet build build/Projects/${{env.PROJECT}}.proj - run: dotnet build build/Projects/${{env.PROJECT}}.proj --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test test/${{env.PROJECT}}.Tests - run: dotnet test test/${{env.PROJECT}}.Tests --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" - env: - OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY: ${{ secrets.OTEL_ONECOLLECTOR_INSTRUMENTATION_KEY }} - - - name: dotnet pack build/Projects/${{env.PROJECT}}.proj - run: dotnet pack build/Projects/${{env.PROJECT}}.proj --configuration Release --no-build --no-restore - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Exporter.OneCollector + secrets: inherit diff --git a/.github/workflows/package-Instrumentation.Process.yml b/.github/workflows/package-Instrumentation.Process.yml index 83e444bd4a..413157463f 100644 --- a/.github/workflows/package-Instrumentation.Process.yml +++ b/.github/workflows/package-Instrumentation.Process.yml @@ -12,55 +12,10 @@ on: - 'Instrumentation.Process-*' # trigger when we create a tag with prefix "Instrumentation.Process-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.Process - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.Process + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Instrumentation.Process.proj b/build/Projects/OpenTelemetry.Instrumentation.Process.proj new file mode 100644 index 0000000000..11f52d18e7 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.Process.proj @@ -0,0 +1,26 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index da36821074..de4e8a202c 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -36,7 +36,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\ci-md.yml = .github\workflows\ci-md.yml .github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml + .github\workflows\Component.Package.yml = .github\workflows\Component.Package.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml + .github\workflows\Component.BuildTest.yml = .github\workflows\Component.BuildTest.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\integration-md.yml = .github\workflows\integration-md.yml @@ -307,6 +309,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 ProjectSection(SolutionItems) = preProject build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj + build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj EndProjectSection EndProject Global From 5782da17af6292be22910705882bd6f5edb10efb Mon Sep 17 00:00:00 2001 From: Julian Dominguez Date: Fri, 22 Sep 2023 14:45:08 -0300 Subject: [PATCH 0830/1499] Allow overriding the Part B "name" field value in GenevaLogExporter (#1367) Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 3 + .../MsgPackExporter/MsgPackLogExporter.cs | 23 ++- .../TLDExporter/TldLogExporter.cs | 23 ++- .../GenevaLogExporterTests.cs | 136 ++++++++++++++++++ 4 files changed, 178 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 58df50d08c..be3ad3c9f5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Allow overriding the Part B "name" field value in GenevaLogExporter. + ([#1367](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1367)) + ## 1.6.0 Released 2023-Sep-09 diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 9dcb291b18..6542e00320 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -259,12 +259,9 @@ internal int SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.SerializeUInt8(buffer, cursor, GetSeverityNumber(logLevel)); cntFields += 1; - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, categoryName); - cntFields += 1; - bool hasEnvProperties = false; bool bodyPopulated = false; + bool namePopulated = false; for (int i = 0; i < listKvp?.Count; i++) { var entry = listKvp[i]; @@ -285,6 +282,17 @@ internal int SerializeLogRecord(LogRecord logRecord) if (entry.Value != null) { // null is not supported. + if (string.Equals(entry.Key, "name", StringComparison.Ordinal)) + { + if (!(entry.Value is string)) + { + // name must be string according to Part B in Common Schema. Skip serializing this field otherwise + continue; + } + + namePopulated = true; + } + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); cursor = MessagePackSerializer.Serialize(buffer, cursor, entry.Value); cntFields += 1; @@ -297,6 +305,13 @@ internal int SerializeLogRecord(LogRecord logRecord) } } + if (!namePopulated) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "name"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, categoryName); + cntFields += 1; + } + if (!bodyPopulated && logRecord.FormattedMessage != null) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "body"); diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 46cc2cefb0..5e01f79c8b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -301,7 +301,6 @@ internal void SerializeLogRecord(LogRecord logRecord) eb.AddCountedString("severityText", logLevels[(int)logLevel]); eb.AddUInt8("severityNumber", GetSeverityNumber(logLevel)); - eb.AddCountedAnsiString("name", categoryName, Encoding.UTF8); var eventId = logRecord.EventId; if (eventId != default) @@ -312,6 +311,7 @@ internal void SerializeLogRecord(LogRecord logRecord) byte hasEnvProperties = 0; bool bodyPopulated = false; + bool namePopulated = false; byte partCFieldsCountFromState = 0; var kvpArrayForPartCFields = partCFields.Value; @@ -342,8 +342,20 @@ internal void SerializeLogRecord(LogRecord logRecord) if (entry.Value != null) { // null is not supported. - kvpArrayForPartCFields[partCFieldsCountFromState] = new(entry.Key, entry.Value); - partCFieldsCountFromState++; + if (string.Equals(entry.Key, "name", StringComparison.Ordinal)) + { + if (entry.Value is string nameValue) + { + // name must be string according to Part B in Common Schema. Skip serializing this field otherwise + eb.AddCountedAnsiString("name", nameValue, Encoding.UTF8); + namePopulated = true; + } + } + else + { + kvpArrayForPartCFields[partCFieldsCountFromState] = new(entry.Key, entry.Value); + partCFieldsCountFromState++; + } } } else @@ -366,6 +378,11 @@ internal void SerializeLogRecord(LogRecord logRecord) } } + if (!namePopulated) + { + eb.AddCountedAnsiString("name", categoryName, Encoding.UTF8); + } + if (!bodyPopulated && logRecord.FormattedMessage != null) { eb.AddCountedAnsiString("body", logRecord.FormattedMessage, Encoding.UTF8); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index e2b5f5d8f8..4c5da2e30f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1132,6 +1132,142 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod } } + [Theory] + [InlineData(false, false, "Custom name")] + [InlineData(false, false, "")] + [InlineData(false, false, null)] + [InlineData(false, false, 12345)] + [InlineData(true, false, "Custom name")] + [InlineData(true, true, "Custom name")] + [InlineData(true, true, 12345)] + [InlineData(true, false, 12345)] + public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCustomFields, object customNameValue) + { + // ARRANGE + string path = string.Empty; + Socket server = null; + var logRecordList = new List(); + try + { + var exporterOptions = new GenevaExporterOptions(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + exporterOptions.ConnectionString = "EtwSession=OpenTelemetry"; + } + else + { + path = GenerateTempFilePath(); + exporterOptions.ConnectionString = "Endpoint=unix:" + path; + var endpoint = new UnixDomainSocketEndPoint(path); + server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + } + + if (hasCustomFields) + { + if (hasNameInCustomFields) + { + exporterOptions.CustomFields = new string[] { "name", "Key1" }; + } + else + { + exporterOptions.CustomFields = new string[] { "Key1" }; + } + } + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => + { + options.ConnectionString = exporterOptions.ConnectionString; + options.CustomFields = exporterOptions.CustomFields; + }); + options.AddInMemoryExporter(logRecordList); + })); + + // Create a test exporter to get MessagePack byte data to validate if the data was serialized correctly. + using var exporter = new MsgPackLogExporter(exporterOptions); + + // Emit a LogRecord and grab a copy of the LogRecord from the collection passed to InMemoryExporter + var logger = loggerFactory.CreateLogger(); + + // ACT + // This is treated as structured logging as the state can be converted to IReadOnlyList> + + var state = new List>() + { + new KeyValuePair("Key1", "Value1"), + new KeyValuePair("Key2", "Value2"), + }; + + if (customNameValue != null) + { + state.Add(new KeyValuePair("name", customNameValue)); + } + + logger.Log( + LogLevel.Information, + default, + state, + null, + null); + + // VALIDATE + Assert.Single(logRecordList); + var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + _ = exporter.SerializeLogRecord(logRecordList[0]); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + var signal = (fluentdData as object[])[0] as string; + var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; + var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; + var actualNameValue = mapping["name"]; + + if (!hasCustomFields || hasNameInCustomFields) + { + if (customNameValue is string stringNameValue) + { + Assert.Equal(stringNameValue, actualNameValue); + } + else + { + Assert.Equal(typeof(GenevaLogExporterTests).FullName, actualNameValue); + } + } + else + { + Assert.Equal(typeof(GenevaLogExporterTests).FullName, actualNameValue); + if (customNameValue != null) + { + var envProperties = mapping["env_properties"] as Dictionary; + if (customNameValue is int customNameNumber) + { + Assert.Equal(Convert.ToInt32(envProperties["name"]), customNameNumber); + } + else + { + Assert.Equal((string)envProperties["name"], (string)customNameValue); + } + } + } + + logRecordList.Clear(); + } + finally + { + server?.Dispose(); + try + { + File.Delete(path); + } + catch + { + } + } + } + [Fact] public void SerializationTestForEventId() { From 91152f9101d5031ff1fab649248966a78ba9ffa1 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 22 Sep 2023 12:49:05 -0700 Subject: [PATCH 0831/1499] [repo] Add dedicated CI for WCF Instrumentation (#1371) --- .github/codecov.yml | 5 ++ .github/workflows/ci-Instrumentation.Wcf.yml | 17 ++++++ .github/workflows/ci.yml | 9 ++- .../workflows/package-Instrumentation.Wcf.yml | 57 ++----------------- .../OpenTelemetry.Instrumentation.Wcf.proj | 26 +++++++++ opentelemetry-dotnet-contrib.sln | 4 +- 6 files changed, 64 insertions(+), 54 deletions(-) create mode 100644 .github/workflows/ci-Instrumentation.Wcf.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.Wcf.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index e28e1f2fce..6025fa0bd3 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -50,3 +50,8 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Process + unittests-Instrumentation.Wcf: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Wcf + diff --git a/.github/workflows/ci-Instrumentation.Wcf.yml b/.github/workflows/ci-Instrumentation.Wcf.yml new file mode 100644 index 0000000000..536553886e --- /dev/null +++ b/.github/workflows/ci-Instrumentation.Wcf.yml @@ -0,0 +1,17 @@ +name: Build OpenTelemetry.Instrumentation.Wcf + +on: + pull_request: + branches: [ 'main*', 'instrumentation*' ] + paths: + - '*/OpenTelemetry.Instrumentation.Wcf*/**' + - 'build/**' + - '!**.md' + +jobs: + call-build-test: + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Wcf + code-cov-name: Instrumentation.Wcf + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0985545b1..b6aeec9df1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,9 +5,10 @@ on: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] paths-ignore: - '**.md' - - '*/OpenTelemetry.Instrumentation.Process*/**' - '*/OpenTelemetry.Exporter.Geneva*/**' - '*/OpenTelemetry.Exporter.OneCollector*/**' + - '*/OpenTelemetry.Instrumentation.Process*/**' + - '*/OpenTelemetry.Instrumentation.Wcf*/**' jobs: build-test: @@ -39,7 +40,11 @@ jobs: run: | $projects = Get-ChildItem ` -Path test/*.Tests/*.csproj ` - -Exclude OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Exporter.Geneva.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj + -Exclude ` + OpenTelemetry.Exporter.Geneva.Tests.csproj, + OpenTelemetry.Exporter.OneCollector.Tests.csproj, + OpenTelemetry.Instrumentation.Process.Tests.csproj, + OpenTelemetry.Instrumentation.Wcf.Tests.csproj ForEach ($project in $projects) { diff --git a/.github/workflows/package-Instrumentation.Wcf.yml b/.github/workflows/package-Instrumentation.Wcf.yml index b7856c08c5..9bda5c8fce 100644 --- a/.github/workflows/package-Instrumentation.Wcf.yml +++ b/.github/workflows/package-Instrumentation.Wcf.yml @@ -9,58 +9,13 @@ on: default: 'warning' push: tags: - - 'Instrumentation.Wcf-*' + - 'Instrumentation.Wcf-*' # trigger when we create a tag with prefix "Instrumentation.Wcf-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.Wcf - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.Wcf + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj new file mode 100644 index 0000000000..98e1d0cd03 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj @@ -0,0 +1,26 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index de4e8a202c..f6eccb2168 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -33,12 +33,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml .github\workflows\ci-Exporter.OneCollector.yml = .github\workflows\ci-Exporter.OneCollector.yml .github\workflows\ci-Instrumentation.Process.yml = .github\workflows\ci-Instrumentation.Process.yml + .github\workflows\ci-Instrumentation.Wcf.yml = .github\workflows\ci-Instrumentation.Wcf.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.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 .github\workflows\Component.Package.yml = .github\workflows\Component.Package.yml .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml - .github\workflows\Component.BuildTest.yml = .github\workflows\Component.BuildTest.yml .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\integration-md.yml = .github\workflows\integration-md.yml @@ -310,6 +311,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj + build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj EndProjectSection EndProject Global From 85ee94ca4a55099b1ac8a0552bcec15e01e12729 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 22 Sep 2023 12:57:29 -0700 Subject: [PATCH 0832/1499] [geneva] CHANGELOG update for GenevaExporter 1.7.0-alpha.1 release (#1372) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index be3ad3c9f5..22fc9fc349 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0-alpha.1 + +Released 2023-Sep-22 + * Allow overriding the Part B "name" field value in GenevaLogExporter. ([#1367](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1367)) From 5a34738c47e847c8cad8af2027209abf0de4d72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 25 Sep 2023 06:46:24 +0200 Subject: [PATCH 0833/1499] Fix AWSEBSResourceDetector on Linux (#1350) --- .../AWSEBSResourceDetector.cs | 6 +++--- src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs index 00d53eb3fe..4307fae7d4 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs @@ -16,7 +16,7 @@ using System; using System.Collections.Generic; -#if NETSTANDARD +#if NET6_0_OR_GREATER using System.Runtime.InteropServices; #endif using OpenTelemetry.ResourceDetectors.AWS.Models; @@ -30,7 +30,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; public class AWSEBSResourceDetector : IResourceDetector { private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; -#if NETSTANDARD +#if NET6_0_OR_GREATER private const string AWSEBSMetadataLinuxFilePath = "/var/elasticbeanstalk/xray/environment.conf"; #endif @@ -43,7 +43,7 @@ public Resource Detect() try { string? filePath; -#if NETSTANDARD +#if NET6_0_OR_GREATER if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { filePath = AWSEBSMetadataWindowsFilePath; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 737f247228..6a94208117 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Fix AWS EBS Resource Detector working on linux. + ([#1350](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1350)) ## 1.3.0-beta.1 From f6e73590c132c713941b9224b5d273155ed9e8d8 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 25 Sep 2023 00:47:48 -0700 Subject: [PATCH 0834/1499] [repo] Add dedicated CI for Owin Instrumentation (#1373) --- .github/codecov.yml | 5 ++ .github/workflows/Component.BuildTest.yml | 12 +++- .github/workflows/ci-Exporter.Geneva.yml | 1 + .../ci-Exporter.OneCollector-Integration.yml | 1 + .../workflows/ci-Exporter.OneCollector.yml | 1 + .github/workflows/ci-Instrumentation.Owin.yml | 20 +++++++ .../workflows/ci-Instrumentation.Process.yml | 1 + .github/workflows/ci-Instrumentation.Wcf.yml | 1 + .github/workflows/ci.yml | 2 + .../package-Instrumentation.Owin.yml | 57 ++----------------- .../OpenTelemetry.Instrumentation.Owin.proj | 26 +++++++++ opentelemetry-dotnet-contrib.sln | 2 + 12 files changed, 76 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/ci-Instrumentation.Owin.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.Owin.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index 6025fa0bd3..c613d3e4eb 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -45,6 +45,11 @@ flags: paths: - src/OpenTelemetry.Exporter.OneCollector + unittests-Instrumentation.Owin: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Owin + unittests-Instrumentation.Process: carryforward: true paths: diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index b257db5d1d..1166b216bc 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -13,6 +13,14 @@ on: default: 'unittests' required: false type: string + os-list: + default: '[ "windows-latest", "ubuntu-latest" ]' + required: false + type: string + tfm-list: + default: '[ "net462", "net6.0", "net7.0" ]' + required: false + type: string jobs: build-test: @@ -20,8 +28,8 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] + os: ${{ fromJSON(inputs.os-list) }} + version: ${{ fromJSON(inputs.tfm-list) }} exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/ci-Exporter.Geneva.yml b/.github/workflows/ci-Exporter.Geneva.yml index f847305179..70193059e1 100644 --- a/.github/workflows/ci-Exporter.Geneva.yml +++ b/.github/workflows/ci-Exporter.Geneva.yml @@ -5,6 +5,7 @@ on: branches: [ 'main*', 'exporter*' ] paths: - '*/OpenTelemetry.Exporter.Geneva*/**' + - 'src/Shared/**' - 'build/**' - '!**.md' diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index fe720463a2..616e7e1096 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -8,6 +8,7 @@ on: branches: [ 'main*', 'exporter*' ] paths: - '*/OpenTelemetry.Exporter.OneCollector*/**' + - 'src/Shared/**' - 'build/**' - '!**.md' diff --git a/.github/workflows/ci-Exporter.OneCollector.yml b/.github/workflows/ci-Exporter.OneCollector.yml index d652649d63..76a40905ff 100644 --- a/.github/workflows/ci-Exporter.OneCollector.yml +++ b/.github/workflows/ci-Exporter.OneCollector.yml @@ -5,6 +5,7 @@ on: branches: [ 'main*', 'exporter*' ] paths: - '*/OpenTelemetry.Exporter.OneCollector*/**' + - 'src/Shared/**' - 'build/**' - '!**.md' diff --git a/.github/workflows/ci-Instrumentation.Owin.yml b/.github/workflows/ci-Instrumentation.Owin.yml new file mode 100644 index 0000000000..225f917df9 --- /dev/null +++ b/.github/workflows/ci-Instrumentation.Owin.yml @@ -0,0 +1,20 @@ +name: Build OpenTelemetry.Instrumentation.Owin + +on: + pull_request: + branches: [ 'main*', 'instrumentation*' ] + paths: + - '*/OpenTelemetry.Instrumentation.Owin*/**' + - 'src/Shared/**' + - 'build/**' + - '!**.md' + +jobs: + call-build-test: + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Owin + code-cov-name: Instrumentation.Owin + os-list: '[ "windows-latest" ]' + tfm-list: '[ "net462" ]' + diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml index 63c394e1aa..677ef47fb3 100644 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ b/.github/workflows/ci-Instrumentation.Process.yml @@ -5,6 +5,7 @@ on: branches: [ 'main*', 'instrumentation*' ] paths: - '*/OpenTelemetry.Instrumentation.Process*/**' + - 'src/Shared/**' - 'build/**' - '!**.md' diff --git a/.github/workflows/ci-Instrumentation.Wcf.yml b/.github/workflows/ci-Instrumentation.Wcf.yml index 536553886e..a0738b856e 100644 --- a/.github/workflows/ci-Instrumentation.Wcf.yml +++ b/.github/workflows/ci-Instrumentation.Wcf.yml @@ -5,6 +5,7 @@ on: branches: [ 'main*', 'instrumentation*' ] paths: - '*/OpenTelemetry.Instrumentation.Wcf*/**' + - 'src/Shared/**' - 'build/**' - '!**.md' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6aeec9df1..2975f4ff9d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ on: - '**.md' - '*/OpenTelemetry.Exporter.Geneva*/**' - '*/OpenTelemetry.Exporter.OneCollector*/**' + - '*/OpenTelemetry.Instrumentation.Owin*/**' - '*/OpenTelemetry.Instrumentation.Process*/**' - '*/OpenTelemetry.Instrumentation.Wcf*/**' @@ -43,6 +44,7 @@ jobs: -Exclude ` OpenTelemetry.Exporter.Geneva.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj, + OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Instrumentation.Wcf.Tests.csproj diff --git a/.github/workflows/package-Instrumentation.Owin.yml b/.github/workflows/package-Instrumentation.Owin.yml index 57a27988b5..a8b30e1f21 100644 --- a/.github/workflows/package-Instrumentation.Owin.yml +++ b/.github/workflows/package-Instrumentation.Owin.yml @@ -9,58 +9,13 @@ on: default: 'warning' push: tags: - - 'Instrumentation.Owin-*' + - 'Instrumentation.Owin-*' # trigger when we create a tag with prefix "Instrumentation.Owin-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.Owin - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.Owin + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj new file mode 100644 index 0000000000..94116c5810 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj @@ -0,0 +1,26 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f6eccb2168..9784de114d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -32,6 +32,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\ci-Exporter.Geneva.yml = .github\workflows\ci-Exporter.Geneva.yml .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml .github\workflows\ci-Exporter.OneCollector.yml = .github\workflows\ci-Exporter.OneCollector.yml + .github\workflows\ci-Instrumentation.Owin.yml = .github\workflows\ci-Instrumentation.Owin.yml .github\workflows\ci-Instrumentation.Process.yml = .github\workflows\ci-Instrumentation.Process.yml .github\workflows\ci-Instrumentation.Wcf.yml = .github\workflows\ci-Instrumentation.Wcf.yml .github\workflows\ci-md.yml = .github\workflows\ci-md.yml @@ -310,6 +311,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 ProjectSection(SolutionItems) = preProject build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj + build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj EndProjectSection From fec6a637f976a1e1114941e4975e423c80f08449 Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:45:57 -0600 Subject: [PATCH 0835/1499] [wcf] Add AspNet parent span correction (#1342) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- examples/wcf/client-core/Program.cs | 22 +- examples/wcf/client-core/appsettings.json | 8 +- examples/wcf/client-netframework/App.config | 6 +- .../Examples.Wcf.Client.NetFramework.csproj | 1 + examples/wcf/client-netframework/Program.cs | 15 +- ...Examples.Wcf.Server.AspNetFramework.csproj | 74 +++++ .../wcf/server-aspnetframework/Global.asax | 1 + .../wcf/server-aspnetframework/Global.asax.cs | 67 +++++ .../Properties/launchSettings.json | 18 ++ .../server-aspnetframework/StatusService.svc | 1 + .../StatusService.svc.cs | 32 +++ .../server-aspnetframework/Web.Debug.config | 30 ++ .../server-aspnetframework/Web.Release.config | 31 ++ .../wcf/server-aspnetframework/Web.config | 266 ++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 7 + .../CHANGELOG.md | 2 + .../AspNetParentSpanCorrector.cs | 151 ++++++++++ .../WcfInstrumentationEventSource.cs | 16 ++ .../TracerProviderBuilderExtensions.cs | 4 + .../AspNetParentSpanCorrectorTests.netfx.cs | 65 +++++ ...Telemetry.Instrumentation.Wcf.Tests.csproj | 1 + 21 files changed, 805 insertions(+), 13 deletions(-) create mode 100644 examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj create mode 100644 examples/wcf/server-aspnetframework/Global.asax create mode 100644 examples/wcf/server-aspnetframework/Global.asax.cs create mode 100644 examples/wcf/server-aspnetframework/Properties/launchSettings.json create mode 100644 examples/wcf/server-aspnetframework/StatusService.svc create mode 100644 examples/wcf/server-aspnetframework/StatusService.svc.cs create mode 100644 examples/wcf/server-aspnetframework/Web.Debug.config create mode 100644 examples/wcf/server-aspnetframework/Web.Release.config create mode 100644 examples/wcf/server-aspnetframework/Web.config create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 71a68aae83..71cc37ec5d 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -42,12 +42,22 @@ public static async Task Main() .AddZipkinExporter() .Build(); - await CallService( - new BasicHttpBinding(BasicHttpSecurityMode.None), - new EndpointAddress(config.GetSection("Service").GetValue("HttpAddress"))).ConfigureAwait(false); - await CallService( - new NetTcpBinding(SecurityMode.None), - new EndpointAddress(config.GetSection("Service").GetValue("TcpAddress"))).ConfigureAwait(false); + switch (config.GetValue("Server")!.ToUpperInvariant()) + { + case "ASPNET": + await CallService( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(config.GetSection("Service").GetValue("AspNetAddress"))).ConfigureAwait(false); + break; + default: + await CallService( + new BasicHttpBinding(BasicHttpSecurityMode.None), + new EndpointAddress(config.GetSection("Service").GetValue("HttpAddress"))).ConfigureAwait(false); + await CallService( + new NetTcpBinding(SecurityMode.None), + new EndpointAddress(config.GetSection("Service").GetValue("TcpAddress"))).ConfigureAwait(false); + break; + } Console.WriteLine("Press enter to exit."); Console.ReadLine(); diff --git a/examples/wcf/client-core/appsettings.json b/examples/wcf/client-core/appsettings.json index a468e204fb..20ad770bad 100644 --- a/examples/wcf/client-core/appsettings.json +++ b/examples/wcf/client-core/appsettings.json @@ -1,6 +1,8 @@ -{ +{ + "Server": "self-hosted", "Service": { "HttpAddress": "http://localhost:9009/Telemetry", - "TcpAddress": "net.tcp://localhost:9090/Telemetry" + "TcpAddress": "net.tcp://localhost:9090/Telemetry", + "AspNetAddress": "http://localhost:61494/StatusService.svc" } -} \ No newline at end of file +} diff --git a/examples/wcf/client-netframework/App.config b/examples/wcf/client-netframework/App.config index 49b2186221..e6e12aaa03 100644 --- a/examples/wcf/client-netframework/App.config +++ b/examples/wcf/client-netframework/App.config @@ -1,5 +1,8 @@ - + + + + @@ -33,6 +36,7 @@ + diff --git a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj index 2e846ea19e..cdf07abc4b 100644 --- a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj +++ b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj @@ -18,6 +18,7 @@ + diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index 38334d7b0a..ee699a507a 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -15,6 +15,7 @@ // using System; +using System.Configuration; using System.ServiceModel; using System.Threading.Tasks; using OpenTelemetry; @@ -33,9 +34,17 @@ public static async Task Main() .AddZipkinExporter() .Build(); - await CallService("StatusService_Http").ConfigureAwait(false); - await CallService("StatusService_Tcp").ConfigureAwait(false); - await CallService("StatusService_Rest").ConfigureAwait(false); + switch (ConfigurationManager.AppSettings["Server"].ToUpperInvariant()) + { + case "ASPNET": + await CallService("StatusService_AspNet").ConfigureAwait(false); + break; + default: + await CallService("StatusService_Http").ConfigureAwait(false); + await CallService("StatusService_Tcp").ConfigureAwait(false); + await CallService("StatusService_Rest").ConfigureAwait(false); + break; + } Console.WriteLine("Press enter to exit."); Console.ReadLine(); diff --git a/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj b/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj new file mode 100644 index 0000000000..c4efc4eceb --- /dev/null +++ b/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj @@ -0,0 +1,74 @@ + + + + net462 + Library + bin\ + false + false + web.config + false + + + + + + + + + + + + + + + + + + + + + Global.asax + + + StatusService.svc + + + + + Web.config + + + Web.config + + + + + + + + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + $(BuildDependsOn) + SkipBuildWithoutVisualStudio + + diff --git a/examples/wcf/server-aspnetframework/Global.asax b/examples/wcf/server-aspnetframework/Global.asax new file mode 100644 index 0000000000..7041acc60d --- /dev/null +++ b/examples/wcf/server-aspnetframework/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="Examples.Wcf.Server.AspNetFramework.WebApiApplication" Language="C#" %> \ No newline at end of file diff --git a/examples/wcf/server-aspnetframework/Global.asax.cs b/examples/wcf/server-aspnetframework/Global.asax.cs new file mode 100644 index 0000000000..692259cc99 --- /dev/null +++ b/examples/wcf/server-aspnetframework/Global.asax.cs @@ -0,0 +1,67 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Configuration; +using System.Web; +using OpenTelemetry; +using OpenTelemetry.Exporter; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace Examples.Wcf.Server.AspNetFramework; + +#pragma warning disable SA1649 // File name should match first type name +public class WebApiApplication : HttpApplication +#pragma warning restore SA1649 // File name should match first type name +{ + private IDisposable? tracerProvider; + + protected void Application_Start() + { + var builder = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddService("Wcf-AspNetServer")) + .AddAspNetInstrumentation() + .AddWcfInstrumentation(); + + switch (ConfigurationManager.AppSettings["UseExporter"].ToUpperInvariant()) + { + case "ZIPKIN": + builder.AddZipkinExporter(zipkinOptions => + { + zipkinOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["ZipkinEndpoint"]); + }); + break; + case "OTLP": + builder.AddOtlpExporter(otlpOptions => + { + otlpOptions.Endpoint = new Uri(ConfigurationManager.AppSettings["OtlpEndpoint"]); + }); + break; + default: + builder.AddConsoleExporter(options => options.Targets = ConsoleExporterOutputTargets.Debug); + break; + } + + this.tracerProvider = builder.Build(); + } + + protected void Application_End() + { + this.tracerProvider?.Dispose(); + } +} diff --git a/examples/wcf/server-aspnetframework/Properties/launchSettings.json b/examples/wcf/server-aspnetframework/Properties/launchSettings.json new file mode 100644 index 0000000000..de6793e474 --- /dev/null +++ b/examples/wcf/server-aspnetframework/Properties/launchSettings.json @@ -0,0 +1,18 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:61494" + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/examples/wcf/server-aspnetframework/StatusService.svc b/examples/wcf/server-aspnetframework/StatusService.svc new file mode 100644 index 0000000000..6197043ec9 --- /dev/null +++ b/examples/wcf/server-aspnetframework/StatusService.svc @@ -0,0 +1 @@ +<%@ ServiceHost Language="C#" Debug="true" Service="Examples.Wcf.Server.AspNetFramework.StatusService" CodeBehind="StatusService.svc.cs" %> diff --git a/examples/wcf/server-aspnetframework/StatusService.svc.cs b/examples/wcf/server-aspnetframework/StatusService.svc.cs new file mode 100644 index 0000000000..e09a817b82 --- /dev/null +++ b/examples/wcf/server-aspnetframework/StatusService.svc.cs @@ -0,0 +1,32 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Threading.Tasks; + +namespace Examples.Wcf.Server.AspNetFramework; + +public class StatusService : IStatusServiceContract +{ + public Task PingAsync(StatusRequest request) + { + return Task.FromResult( + new StatusResponse + { + ServerTime = DateTimeOffset.UtcNow, + }); + } +} diff --git a/examples/wcf/server-aspnetframework/Web.Debug.config b/examples/wcf/server-aspnetframework/Web.Debug.config new file mode 100644 index 0000000000..104f153f93 --- /dev/null +++ b/examples/wcf/server-aspnetframework/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/examples/wcf/server-aspnetframework/Web.Release.config b/examples/wcf/server-aspnetframework/Web.Release.config new file mode 100644 index 0000000000..63c58428af --- /dev/null +++ b/examples/wcf/server-aspnetframework/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/examples/wcf/server-aspnetframework/Web.config b/examples/wcf/server-aspnetframework/Web.config new file mode 100644 index 0000000000..97259f8cc7 --- /dev/null +++ b/examples/wcf/server-aspnetframework/Web.config @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 9784de114d..c250a011cc 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -301,6 +301,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.InfluxDB", "exampl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.AotCompatibility.TestApp", "test\OpenTelemetry.AotCompatibility.TestApp\OpenTelemetry.AotCompatibility.TestApp.csproj", "{31937862-0C88-41C0-AFD6-F97A7BF803A9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.Wcf.Server.AspNetFramework", "examples\wcf\server-aspnetframework\Examples.Wcf.Server.AspNetFramework.csproj", "{23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B30F5FD-3309-49CB-9CAD-D3372FAFD796}" ProjectSection(SolutionItems) = preProject examples\Directory.Build.props = examples\Directory.Build.props @@ -630,6 +632,10 @@ Global {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Debug|Any CPU.Build.0 = Debug|Any CPU {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Release|Any CPU.ActiveCfg = Release|Any CPU {31937862-0C88-41C0-AFD6-F97A7BF803A9}.Release|Any CPU.Build.0 = Release|Any CPU + {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -724,6 +730,7 @@ Global {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} {31937862-0C88-41C0-AFD6-F97A7BF803A9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index a73132691d..ed16c6bdd0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Fixed span hierarchy when hosted in ASP.NET + ([#1342](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1342)) ## 1.0.0-rc.12 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs new file mode 100644 index 0000000000..99c9a8e9e3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs @@ -0,0 +1,151 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK +using System; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Linq.Expressions; +using System.Reflection; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +/// +/// When WCF is hosted in ASP.NET and the ASP.NET telemetry instrumentation is installed, the execution context does not flow from ASP.NET into WCF +/// so the span which is created by ASP.NET is not visible to WCF. When OpenTelemetry.Instrumentation.Wcf then creates its own span it uses the parent +/// which is passed from the caller. This results in the ASP.NET span and the WCF span being siblings off the same parent when, really, the WCF span +/// should actually be a child of the ASP.NET (transport) span. This class corrects that behavior so the generated spans are correctly parented. +/// +/// The way it does that is it hooks into the ASP.NET telemetry and rewrites the incoming request headers to reflect the ASP.NET parent (so, as far +/// as WCF is concerned, it appears like the ASP.NET parent span was sent from the caller). It does this all via reflection to avoid having explicit +/// dependencies on System.Web and OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule. This way this behavior is only enabled if the consumer +/// also has the ASP.NET instrumentation installed. +/// +internal static class AspNetParentSpanCorrector +{ + private const string TelemetryHttpModuleTypeName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule"; + private const string TelemetryHttpModuleOptionsTypeName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule"; + + private static readonly ReflectedInfo ReflectedValues = Initialize(); + private static readonly PropertyFetcher RequestFetcher = new PropertyFetcher("Request"); + private static readonly PropertyFetcher HeadersFetcher = new PropertyFetcher("Headers"); + private static bool isRegistered; + + public static void Register() + { + if (!isRegistered && ReflectedValues != null) + { + ReflectedValues.SubscribeToOnRequestStartedCallback(); + isRegistered = true; + } + } + + private static void OnRequestStarted(Activity activity, object context) + { + var request = RequestFetcher.Fetch(context); + var headers = HeadersFetcher.Fetch(request); + + ReflectedValues.SetHeadersReadOnly(headers, false); + try + { + ReflectedValues.GetTelemetryHttpModulePropagator().Inject( + new PropagationContext(activity.Context, Baggage.Current), + headers, + (headers, name, value) => headers[name] = value); + } + finally + { + ReflectedValues.SetHeadersReadOnly(headers, true); + } + } + + private static ReflectedInfo Initialize() + { + try + { + var isReadOnlyProp = typeof(NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); + if (isReadOnlyProp == null) + { + throw new NotSupportedException("NameValueCollection.IsReadOnly property not found"); + } + + var setHeadersReadOnly = (Action)isReadOnlyProp.SetMethod.CreateDelegate(typeof(Action)); + + return new ReflectedInfo + { + SetHeadersReadOnly = setHeadersReadOnly, + GetTelemetryHttpModulePropagator = GenerateGetPropagatorLambda(), + SubscribeToOnRequestStartedCallback = GenerateSubscribeLambda(), + }; + } + catch (Exception ex) + { + WcfInstrumentationEventSource.Log.AspNetReflectionFailedToBind(ex); + } + + return null; + } + + private static Func GenerateGetPropagatorLambda() + { + // this method generates this lambda: + // () => TelemetryHttpModule.Options.TextMapPropagator + + var telemetryHttpModuleType = Type.GetType(TelemetryHttpModuleTypeName, true); + var options = Expression.Property(null, telemetryHttpModuleType, "Options"); + var propertyReferenceExpression = Expression.Property(options, "TextMapPropagator"); + return (Func)Expression.Lambda(propertyReferenceExpression).Compile(); + } + + private static Func GenerateSubscribeLambda() + { + // this method effectively generates this lambda: + // () => TelemetryHttpModule.Options.OnRequestStartedCallback += OnRequestStarted + // technically it generates this: + // () => TelemetryHttpModule.Options.OnRequestStartedCallback = + // (Action)addOurCallbackToDelegate(TelemetryHttpModule.Options.OnRequestStartedCallback); + + var telemetryHttpModuleType = Type.GetType(TelemetryHttpModuleTypeName, true); + var telemetryHttpModuleOptionsType = Type.GetType(TelemetryHttpModuleOptionsTypeName, true); + var onRequestStartedProp = telemetryHttpModuleOptionsType.GetProperty("OnRequestStartedCallback"); + if (onRequestStartedProp == null) + { + throw new NotSupportedException("TelemetryHttpModuleOptions.OnRequestStartedCallback property not found"); + } + + Func addOurCallbackToDelegate = (existingCallback) => + { + var myCallback = OnRequestStarted; + var myCallbackProperlyTyped = Delegate.CreateDelegate(onRequestStartedProp.PropertyType, myCallback.Target, myCallback.Method); + return Delegate.Combine(existingCallback, myCallbackProperlyTyped); + }; + + var options = Expression.Property(null, telemetryHttpModuleType, "Options"); + var callbackProperty = Expression.Property(options, onRequestStartedProp); + var combinedDelegate = Expression.Call(Expression.Constant(addOurCallbackToDelegate.Target), addOurCallbackToDelegate.Method, callbackProperty); + var subscribeExpression = Expression.Assign(callbackProperty, Expression.Convert(combinedDelegate, onRequestStartedProp.PropertyType)); + return (Func)Expression.Lambda(subscribeExpression).Compile(); + } + + private sealed class ReflectedInfo + { + public Action SetHeadersReadOnly; + public Func GetTelemetryHttpModulePropagator; + public Func SubscribeToOnRequestStartedCallback; + } +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index 201884ea21..87e7a5a43e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -76,11 +76,27 @@ public void HttpServiceModelReflectionFailedToBind(string exception, string asse this.WriteEvent(EventIds.HttpServiceModelReflectionFailedToBind, exception, assembly); } + [NonEvent] + public void AspNetReflectionFailedToBind(Exception exception) + { + if (this.IsEnabled(EventLevel.Verbose, (EventKeywords)(-1))) + { + this.AspNetReflectionFailedToBind(exception.ToInvariantString()); + } + } + + [Event(EventIds.AspNetReflectionFailedToBind, Message = "Failed to bind to ASP.NET instrumentation. Exception {0}.", Level = EventLevel.Verbose)] + public void AspNetReflectionFailedToBind(string exception) + { + this.WriteEvent(EventIds.AspNetReflectionFailedToBind, exception); + } + private class EventIds { public const int RequestIsFilteredOut = 1; public const int RequestFilterException = 2; public const int EnrichmentException = 3; public const int HttpServiceModelReflectionFailedToBind = 4; + public const int AspNetReflectionFailedToBind = 5; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index 6093fcd5b0..7ba6e224d0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -53,6 +53,10 @@ public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBui WcfInstrumentationActivitySource.Options = options; +#if NETFRAMEWORK + Instrumentation.Wcf.Implementation.AspNetParentSpanCorrector.Register(); +#endif + return builder.AddSource(WcfInstrumentationActivitySource.ActivitySourceName); } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs new file mode 100644 index 0000000000..22f671e14d --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs @@ -0,0 +1,65 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NETFRAMEWORK +using System.Collections.Specialized; +using System.Diagnostics; +using System.Reflection; +using OpenTelemetry.Instrumentation.Wcf.Implementation; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Wcf.Tests; + +[Collection("WCF")] +public class AspNetParentSpanCorrectorTests +{ + [Fact] + public void IncomingRequestHeadersAreOverwrittenWithAspNetParent() + { + var testSource = new ActivitySource("TestSource"); + using var provider = Sdk.CreateTracerProviderBuilder() + .AddSource("TestSource") + .AddWcfInstrumentation() + .Build(); + + var reflectedValues = typeof(AspNetParentSpanCorrector).GetField("ReflectedValues", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); + Assert.False(reflectedValues == null, "The reflection-based bind to OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule failed. The AspNet telemetry has likely changed, and this assembly needs to be updated to match"); + + using (var aspNetActivity = testSource.StartActivity("AspNetActivity")) + { + var context = new FakeHttpContext(); + + var method = typeof(AspNetParentSpanCorrector).GetMethod("OnRequestStarted", BindingFlags.Static | BindingFlags.NonPublic); + method.Invoke(null, new object[] { aspNetActivity, context }); + + var headerVal = context.Request.Headers["traceparent"]; + Assert.Contains(aspNetActivity.TraceId.ToString(), headerVal); + Assert.Contains(aspNetActivity.SpanId.ToString(), headerVal); + } + } + + private class FakeHttpContext + { + public FakeRequest Request { get; } = new FakeRequest(); + } + + private class FakeRequest + { + public NameValueCollection Headers { get; } = new NameValueCollection(); + } +} +#endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 15fd623005..a3ac7aa816 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -16,6 +16,7 @@ + From 8c2ae31f951d70c2660e7b3f885d5da620a844d4 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Thu, 28 Sep 2023 00:33:40 -0400 Subject: [PATCH 0836/1499] Improve OWIN server metric precision (#1377) --- .../Implementation/DiagnosticsMiddleware.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 85b041bd24..525a76395a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -226,7 +226,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception exception, lo { var endTimestamp = Stopwatch.GetTimestamp(); var duration = endTimestamp - startTimestamp; - var durationS = duration / Stopwatch.Frequency; + var durationS = duration / (double)Stopwatch.Frequency; OwinInstrumentationMetrics.HttpServerDuration.Record( durationS, From 4c5d6468804a1547ad8673e8a6116c938ec76ed8 Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Mon, 2 Oct 2023 11:28:46 -0600 Subject: [PATCH 0837/1499] [wcf] Streamline the exposed public interface (breaking change) (#1376) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 6 ------ .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 3 --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ .../{ => Implementation}/TelemetryClientMessageInspector.cs | 5 ++--- .../TelemetryDispatchMessageInspector.cs | 5 ++--- .../TelemetryContractBehaviorAttribute.cs | 1 + .../TelemetryServiceBehavior.cs | 3 +-- 7 files changed, 9 insertions(+), 17 deletions(-) rename src/OpenTelemetry.Instrumentation.Wcf/{ => Implementation}/TelemetryClientMessageInspector.cs (91%) rename src/OpenTelemetry.Instrumentation.Wcf/{ => Implementation}/TelemetryDispatchMessageInspector.cs (97%) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt index 30bb5ab1fe..40e7077997 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt @@ -2,18 +2,12 @@ const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveRequest = "AfterReceiveRequest" -> string const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendReply = "BeforeSendReply" -> string const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string -OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector -OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) -> object OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.TelemetryContractBehaviorAttribute() -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryDispatchMessageInspector -OpenTelemetry.Instrumentation.Wcf.TelemetryDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) -> object -OpenTelemetry.Instrumentation.Wcf.TelemetryDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 63b7e2ee2f..ae0ce795bf 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,8 +1,5 @@ const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string -OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector -OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryClientMessageInspector.BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel) -> object OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index ed16c6bdd0..6decc57d49 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -6,6 +6,9 @@ ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Fixed span hierarchy when hosted in ASP.NET ([#1342](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1342)) +* **Breaking Change** `TelemetryClientMessageInspector` and `TelemetryDispatchMessageInspector` + changed from public to internal + ([#1376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1376)) ## 1.0.0-rc.12 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs similarity index 91% rename from src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs index a745f56f13..8b27e9c36e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs @@ -18,15 +18,14 @@ using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; -using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Internal; -namespace OpenTelemetry.Instrumentation.Wcf; +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; /// /// An implementation which adds telemetry to outgoing requests. /// -public class TelemetryClientMessageInspector : IClientMessageInspector +internal class TelemetryClientMessageInspector : IClientMessageInspector { private readonly IDictionary actionMappings; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs similarity index 97% rename from src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs index 476676a534..b3a1043fab 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs @@ -22,16 +22,15 @@ using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.Wcf; +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; /// /// An implementation which adds telemetry to incoming requests. /// -public class TelemetryDispatchMessageInspector : IDispatchMessageInspector +internal class TelemetryDispatchMessageInspector : IDispatchMessageInspector { private readonly IDictionary actionMappings; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 3faf31b076..1d3aff89bb 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -18,6 +18,7 @@ using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; +using OpenTelemetry.Instrumentation.Wcf.Implementation; using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs index 4a63fc87c3..b60d922b9c 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -23,8 +23,7 @@ namespace OpenTelemetry.Instrumentation.Wcf; /// -/// An implementation to add the -/// to service operations. +/// An implementation to add the telemetry to service operations. /// public class TelemetryServiceBehavior : IServiceBehavior { From 897e0d5454441963421d15fbc14b7f214d85814e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 3 Oct 2023 09:51:54 -0700 Subject: [PATCH 0838/1499] [repo] CI improvements (#1383) --- .github/codecov.yml | 13 +- .github/workflows/ci-Exporter.Geneva.yml | 17 -- .../workflows/ci-Exporter.OneCollector.yml | 17 -- .github/workflows/ci-Instrumentation.Owin.yml | 20 --- .../workflows/ci-Instrumentation.Process.yml | 18 -- .github/workflows/ci-Instrumentation.Wcf.yml | 18 -- .github/workflows/ci-md.yml | 29 ---- .github/workflows/ci.yml | 162 +++++++++++++++++- .github/workflows/dotnet-format-md.yml | 22 --- .github/workflows/dotnet-format.yml | 12 +- .github/workflows/integration-md.yml | 18 -- .github/workflows/integration.yml | 9 +- .github/workflows/markdownlint.yml | 9 +- ...age-Instrumentation.StackExchangeRedis.yml | 57 +----- .github/workflows/sanitycheck.yml | 9 +- .../OpenTelemetry.Instrumentation.Owin.proj | 1 + ...OpenTelemetry.Instrumentation.Process.proj | 1 + ...ry.Instrumentation.StackExchangeRedis.proj | 27 +++ .../OpenTelemetry.Instrumentation.Wcf.proj | 1 + opentelemetry-dotnet-contrib.sln | 14 +- 20 files changed, 216 insertions(+), 258 deletions(-) delete mode 100644 .github/workflows/ci-Exporter.Geneva.yml delete mode 100644 .github/workflows/ci-Exporter.OneCollector.yml delete mode 100644 .github/workflows/ci-Instrumentation.Owin.yml delete mode 100644 .github/workflows/ci-Instrumentation.Process.yml delete mode 100644 .github/workflows/ci-Instrumentation.Wcf.yml delete mode 100644 .github/workflows/ci-md.yml delete mode 100644 .github/workflows/dotnet-format-md.yml delete mode 100644 .github/workflows/integration-md.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index c613d3e4eb..ca71c9e68f 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -23,14 +23,16 @@ comment: require_changes: no ignore: - - "**/*.md" - - "src/Shared" # copied from main OTel project and has code coverage there + - "**.md" + - "src/Shared" # copied from main OTel project and has code coverage there - "test" - "examples" - "build" + - ".github" + - ".vscode" flags: - unittests: + unittests-Solution: carryforward: true paths: - src @@ -55,6 +57,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Process + unittests-Instrumentation.StackExchangeRedis: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.StackExchangeRedis + unittests-Instrumentation.Wcf: carryforward: true paths: diff --git a/.github/workflows/ci-Exporter.Geneva.yml b/.github/workflows/ci-Exporter.Geneva.yml deleted file mode 100644 index 70193059e1..0000000000 --- a/.github/workflows/ci-Exporter.Geneva.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Build OpenTelemetry.Exporter.Geneva - -on: - pull_request: - branches: [ 'main*', 'exporter*' ] - paths: - - '*/OpenTelemetry.Exporter.Geneva*/**' - - 'src/Shared/**' - - 'build/**' - - '!**.md' - -jobs: - call-build-test: - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: OpenTelemetry.Exporter.Geneva - code-cov-name: Exporter.Geneva diff --git a/.github/workflows/ci-Exporter.OneCollector.yml b/.github/workflows/ci-Exporter.OneCollector.yml deleted file mode 100644 index 76a40905ff..0000000000 --- a/.github/workflows/ci-Exporter.OneCollector.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Build OpenTelemetry.Exporter.OneCollector - -on: - pull_request: - branches: [ 'main*', 'exporter*' ] - paths: - - '*/OpenTelemetry.Exporter.OneCollector*/**' - - 'src/Shared/**' - - 'build/**' - - '!**.md' - -jobs: - call-build-test: - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: OpenTelemetry.Exporter.OneCollector - code-cov-name: Exporter.OneCollector diff --git a/.github/workflows/ci-Instrumentation.Owin.yml b/.github/workflows/ci-Instrumentation.Owin.yml deleted file mode 100644 index 225f917df9..0000000000 --- a/.github/workflows/ci-Instrumentation.Owin.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Build OpenTelemetry.Instrumentation.Owin - -on: - pull_request: - branches: [ 'main*', 'instrumentation*' ] - paths: - - '*/OpenTelemetry.Instrumentation.Owin*/**' - - 'src/Shared/**' - - 'build/**' - - '!**.md' - -jobs: - call-build-test: - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: OpenTelemetry.Instrumentation.Owin - code-cov-name: Instrumentation.Owin - os-list: '[ "windows-latest" ]' - tfm-list: '[ "net462" ]' - diff --git a/.github/workflows/ci-Instrumentation.Process.yml b/.github/workflows/ci-Instrumentation.Process.yml deleted file mode 100644 index 677ef47fb3..0000000000 --- a/.github/workflows/ci-Instrumentation.Process.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Build OpenTelemetry.Instrumentation.Process - -on: - pull_request: - branches: [ 'main*', 'instrumentation*' ] - paths: - - '*/OpenTelemetry.Instrumentation.Process*/**' - - 'src/Shared/**' - - 'build/**' - - '!**.md' - -jobs: - call-build-test: - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: OpenTelemetry.Instrumentation.Process - code-cov-name: Instrumentation.Process - diff --git a/.github/workflows/ci-Instrumentation.Wcf.yml b/.github/workflows/ci-Instrumentation.Wcf.yml deleted file mode 100644 index a0738b856e..0000000000 --- a/.github/workflows/ci-Instrumentation.Wcf.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Build OpenTelemetry.Instrumentation.Wcf - -on: - pull_request: - branches: [ 'main*', 'instrumentation*' ] - paths: - - '*/OpenTelemetry.Instrumentation.Wcf*/**' - - 'src/Shared/**' - - 'build/**' - - '!**.md' - -jobs: - call-build-test: - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: OpenTelemetry.Instrumentation.Wcf - code-cov-name: Instrumentation.Wcf - diff --git a/.github/workflows/ci-md.yml b/.github/workflows/ci-md.yml deleted file mode 100644 index 862dec8659..0000000000 --- a/.github/workflows/ci-md.yml +++ /dev/null @@ -1,29 +0,0 @@ -# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions -# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks - -# Description: This workflow exists to unblock documentation-only PRs. - -# IMPORTANT: This workflow MUST use the same 'name' as the non -md workflow. - -name: Build - -on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.md' - -jobs: - build-test: - runs-on: ubuntu-latest - - strategy: - matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] - exclude: - - os: ubuntu-latest - version: net462 - - steps: - - run: 'echo "No build required"' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2975f4ff9d..da84e0f53e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,16 +3,139 @@ name: Build on: pull_request: branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.md' - - '*/OpenTelemetry.Exporter.Geneva*/**' - - '*/OpenTelemetry.Exporter.OneCollector*/**' - - '*/OpenTelemetry.Instrumentation.Owin*/**' - - '*/OpenTelemetry.Instrumentation.Process*/**' - - '*/OpenTelemetry.Instrumentation.Wcf*/**' jobs: - build-test: + lint-misspell-sanitycheck: + uses: ./.github/workflows/sanitycheck.yml + + detect-changes: + runs-on: windows-latest + outputs: + changes: ${{ steps.changes.outputs.changes }} + steps: + - uses: dorny/paths-filter@v2 + id: changes + with: + filters: | + md: [ '**.md' ] + build: ['build/**'] + shared: ['src/Shared/**'] + code: ['**.cs', '.editorconfig'] + geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**.md'] + onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**.md'] + owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**.md'] + process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**.md'] + redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**.md'] + wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**.md'] + solution: [ + 'src/**', + 'test/**', + 'examples/**', + '!*/OpenTelemetry.Exporter.Geneva*/**', + '!*/OpenTelemetry.Exporter.OneCollector*/**', + '!*/OpenTelemetry.Instrumentation.Owin*/**', + '!examples/owin/**', + '!*/OpenTelemetry.Instrumentation.Process*/**', + '!examples/process-instrumentation/**', + '!*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', + '!examples/redis/**', + '!*/OpenTelemetry.Instrumentation.Wcf*/**', + '!examples/wcf/**', + '!**.md' + ] + + lint-md: + needs: detect-changes + if: contains(needs.detect-changes.outputs.changes, 'md') + uses: ./.github/workflows/markdownlint.yml + + lint-dotnet-format: + needs: detect-changes + if: contains(needs.detect-changes.outputs.changes, 'code') + uses: ./.github/workflows/dotnet-format.yml + + build-test-geneva: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'geneva') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Exporter.Geneva + code-cov-name: Exporter.Geneva + + build-test-onecollector: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'onecollector') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Exporter.OneCollector + code-cov-name: Exporter.OneCollector + + build-test-owin: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'owin') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Owin + code-cov-name: Instrumentation.Owin + os-list: '[ "windows-latest" ]' + tfm-list: '[ "net462" ]' + + build-test-process: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'process') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Process + code-cov-name: Instrumentation.Process + + build-test-redis: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'redis') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.StackExchangeRedis + code-cov-name: Instrumentation.StackExchangeRedis + + build-test-redis-integration: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'redis') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/integration.yml + + build-test-wcf: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'wcf') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Wcf + code-cov-name: Instrumentation.Wcf + + build-test-solution: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'solution') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails @@ -46,6 +169,7 @@ jobs: OpenTelemetry.Exporter.OneCollector.Tests.csproj, OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, + OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, OpenTelemetry.Instrumentation.Wcf.Tests.csproj ForEach ($project in $projects) @@ -67,5 +191,25 @@ jobs: with: file: TestResults/Cobertura.xml env_vars: OS,TFM - flags: unittests + flags: unittests-Solution name: Code Coverage for solution on [${{ matrix.os }}.${{ matrix.version }}] + + build-test: + needs: [ + lint-misspell-sanitycheck, + detect-changes, + lint-md, + lint-dotnet-format, + build-test-geneva, + build-test-onecollector, + build-test-owin, + build-test-process, + build-test-redis, + build-test-redis-integration, + build-test-wcf, + build-test-solution + ] + if: always() && !cancelled() && !contains(needs.*.result, 'failure') + runs-on: windows-latest + steps: + - run: echo 'build complete ✓' diff --git a/.github/workflows/dotnet-format-md.yml b/.github/workflows/dotnet-format-md.yml deleted file mode 100644 index 6c2d279ca0..0000000000 --- a/.github/workflows/dotnet-format-md.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Syntax: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions -# See also: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks - -# Description: This workflow exists to unblock documentation-only PRs. - -# IMPORTANT: This workflow MUST use the same 'name' and 'matrix' as the non -md workflow. - -name: dotnet format - -on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.cs' - - '.editorconfig' - -jobs: - check-format: - runs-on: ubuntu-latest - - steps: - - run: 'echo "No build required"' diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index a74d0b8b66..f0cdc8ba33 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -1,14 +1,10 @@ -name: dotnet format +name: Lint - dotnet format on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.cs' - - '.editorconfig' + workflow_call: jobs: - check-format: + run-dotnet-format: runs-on: windows-latest steps: @@ -18,7 +14,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v3 - - name: Install dependencies + - name: dotnet restore run: dotnet restore - name: Protobuf compile diff --git a/.github/workflows/integration-md.yml b/.github/workflows/integration-md.yml deleted file mode 100644 index 915c8e70cb..0000000000 --- a/.github/workflows/integration-md.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Integration Tests - -on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.md' - -jobs: - redis-test: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - version: [net6.0,net7.0] - steps: - - run: 'echo "No build required"' - diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index da281d5359..050da674c3 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -1,13 +1,10 @@ -name: Integration Tests +name: Integration Build OpenTelemetry.Instrumentation.StackExchangeRedis on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths-ignore: - - '**.md' + workflow_call: jobs: - redis-test: + redis-integration-test: runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index b7a318dbb8..b50664ef0b 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -1,13 +1,10 @@ -name: markdownlint +name: Lint - Markdown on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] - paths: - - '**.md' + workflow_call: jobs: - build: + run-markdownlint: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml index 2c4b4a1f22..becfc4be09 100644 --- a/.github/workflows/package-Instrumentation.StackExchangeRedis.yml +++ b/.github/workflows/package-Instrumentation.StackExchangeRedis.yml @@ -9,58 +9,13 @@ on: default: 'warning' push: tags: - - 'Instrumentation.StackExchangeRedis-*' + - 'Instrumentation.StackExchangeRedis-*' # trigger when we create a tag with prefix "Instrumentation.StackExchangeRedis-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.StackExchangeRedis - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.StackExchangeRedis + secrets: inherit diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 67676f3b6c..899677db69 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -1,11 +1,10 @@ -name: sanitycheck +name: Lint - Spelling & Encoding on: - pull_request: - branches: [ 'main*', 'instrumentation*', 'exporter*', 'extensions*' ] + workflow_call: jobs: - misspell: + run-misspell: runs-on: ubuntu-latest steps: @@ -20,7 +19,7 @@ jobs: - name: run misspell run: ./bin/misspell -error . - encoding: + run-sanitycheck: runs-on: ubuntu-latest steps: diff --git a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj index 94116c5810..5169a696f0 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj @@ -7,6 +7,7 @@ + diff --git a/build/Projects/OpenTelemetry.Instrumentation.Process.proj b/build/Projects/OpenTelemetry.Instrumentation.Process.proj index 11f52d18e7..50a89c4933 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Process.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Process.proj @@ -7,6 +7,7 @@ + diff --git a/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj b/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj new file mode 100644 index 0000000000..3e4dad9e44 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj @@ -0,0 +1,27 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj index 98e1d0cd03..dba436da80 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj @@ -7,6 +7,7 @@ + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index c250a011cc..94d0778bca 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -29,21 +29,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml - .github\workflows\ci-Exporter.Geneva.yml = .github\workflows\ci-Exporter.Geneva.yml .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml - .github\workflows\ci-Exporter.OneCollector.yml = .github\workflows\ci-Exporter.OneCollector.yml - .github\workflows\ci-Instrumentation.Owin.yml = .github\workflows\ci-Instrumentation.Owin.yml - .github\workflows\ci-Instrumentation.Process.yml = .github\workflows\ci-Instrumentation.Process.yml - .github\workflows\ci-Instrumentation.Wcf.yml = .github\workflows\ci-Instrumentation.Wcf.yml - .github\workflows\ci-md.yml = .github\workflows\ci-md.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 .github\workflows\Component.Package.yml = .github\workflows\Component.Package.yml - .github\workflows\dotnet-core-cov.yml = .github\workflows\dotnet-core-cov.yml - .github\workflows\dotnet-format-md.yml = .github\workflows\dotnet-format-md.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml - .github\workflows\integration-md.yml = .github\workflows\integration-md.yml .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml @@ -301,7 +292,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.InfluxDB", "exampl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.AotCompatibility.TestApp", "test\OpenTelemetry.AotCompatibility.TestApp\OpenTelemetry.AotCompatibility.TestApp.csproj", "{31937862-0C88-41C0-AFD6-F97A7BF803A9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Examples.Wcf.Server.AspNetFramework", "examples\wcf\server-aspnetframework\Examples.Wcf.Server.AspNetFramework.csproj", "{23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.Wcf.Server.AspNetFramework", "examples\wcf\server-aspnetframework\Examples.Wcf.Server.AspNetFramework.csproj", "{23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B30F5FD-3309-49CB-9CAD-D3372FAFD796}" ProjectSection(SolutionItems) = preProject @@ -315,6 +306,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj + build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj EndProjectSection EndProject @@ -729,8 +721,8 @@ Global {2D354354-BAFB-490B-A26F-6A16A52A1A45} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {B4951583-D432-4E87-85CF-498FDD6A35E6} = {2D354354-BAFB-490B-A26F-6A16A52A1A45} {31937862-0C88-41C0-AFD6-F97A7BF803A9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} + {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution From 5f45bc6d662ba20b87cb6b48831599905f7d7d77 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 3 Oct 2023 13:43:25 -0700 Subject: [PATCH 0839/1499] [repo] CI improvement tweaks (#1384) --- .github/workflows/ci.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index da84e0f53e..f26727a29d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,20 +13,20 @@ jobs: outputs: changes: ${{ steps.changes.outputs.changes }} steps: - - uses: dorny/paths-filter@v2 + - uses: AurorNZ/paths-filter@v3 id: changes with: filters: | md: [ '**.md' ] - build: ['build/**'] + build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*'] shared: ['src/Shared/**'] code: ['**.cs', '.editorconfig'] - geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**.md'] - onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**.md'] - owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**.md'] - process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**.md'] - redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**.md'] - wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**.md'] + geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] + onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] + owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] + process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] + redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] + wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] solution: [ 'src/**', 'test/**', @@ -41,7 +41,7 @@ jobs: '!examples/redis/**', '!*/OpenTelemetry.Instrumentation.Wcf*/**', '!examples/wcf/**', - '!**.md' + '!**/*.md' ] lint-md: From 2529398f30b964240239e130749659fe33db466c Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Thu, 5 Oct 2023 12:03:44 -0600 Subject: [PATCH 0840/1499] Add WCF support for IRequestSessionChannel and IDuplexChannel (#1374) --- .../CHANGELOG.md | 2 + .../Implementation/InstrumentedChannel.cs | 13 +- .../InstrumentedChannelFactory.cs | 34 +++- .../InstrumentedChannelFactoryBase.cs | 34 ++++ .../InstrumentedCommunicationObject.cs | 7 +- ...hannel.cs => InstrumentedDuplexChannel.cs} | 10 +- ...InstrumentedDuplexSessionChannelFactory.cs | 44 ----- .../InstrumentedRequestChannel.cs | 4 +- .../InstrumentedRequestChannelFactory.cs | 41 ----- .../Implementation/TelemetryBindingElement.cs | 15 +- .../README.md | 3 + ...Telemetry.Instrumentation.Wcf.Tests.csproj | 5 + ...elemetryBindingElementForTcpTests.netfx.cs | 164 +++++++++++++----- .../certificate.pfx | Bin 0 -> 2627 bytes 14 files changed, 216 insertions(+), 160 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs rename src/OpenTelemetry.Instrumentation.Wcf/Implementation/{InstrumentedDuplexSessionChannel.cs => InstrumentedDuplexChannel.cs} (93%) delete mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs delete mode 100644 src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs create mode 100644 test/OpenTelemetry.Instrumentation.Wcf.Tests/certificate.pfx diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 6decc57d49..f60493308d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -9,6 +9,8 @@ * **Breaking Change** `TelemetryClientMessageInspector` and `TelemetryDispatchMessageInspector` changed from public to internal ([#1376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1376)) +* Added support for `IRequestSessionChannel` and `IDuplexChannel` channel shapes + ([#1374](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1374)) ## 1.0.0-rc.12 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs index 46cd58e734..c7fd6e5db2 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs @@ -18,18 +18,17 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; -internal class InstrumentedChannel : InstrumentedCommunicationObject, IChannel +internal class InstrumentedChannel : InstrumentedCommunicationObject, IChannel + where T : IChannel { - public InstrumentedChannel(IChannel inner) + public InstrumentedChannel(T inner) : base(inner) { } - protected new IChannel Inner { get => (IChannel)base.Inner; } - - T IChannel.GetProperty() - where T : class + TProperty IChannel.GetProperty() + where TProperty : class { - return this.Inner.GetProperty(); + return this.Inner.GetProperty(); } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs index c5ae5a68f5..2985c3a763 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs @@ -14,22 +14,44 @@ // limitations under the License. // +using System; +using System.ServiceModel; using System.ServiceModel.Channels; namespace OpenTelemetry.Instrumentation.Wcf.Implementation; -internal class InstrumentedChannelFactory : InstrumentedCommunicationObject, IChannelFactory +internal sealed class InstrumentedChannelFactory : InstrumentedChannelFactoryBase>, IChannelFactory { - public InstrumentedChannelFactory(IChannelFactory inner) + private readonly CustomBinding binding; + + public InstrumentedChannelFactory(IChannelFactory inner, CustomBinding binding) : base(inner) { + this.binding = binding; + } + + TChannel IChannelFactory.CreateChannel(EndpointAddress to, Uri via) + { + return this.WrapChannel(this.Inner.CreateChannel(to, via)); } - protected new IChannelFactory Inner { get => (IChannelFactory)base.Inner; } + TChannel IChannelFactory.CreateChannel(EndpointAddress to) + { + return this.WrapChannel(this.Inner.CreateChannel(to)); + } - T IChannelFactory.GetProperty() - where T : class + private TChannel WrapChannel(TChannel innerChannel) { - return this.Inner.GetProperty(); + if (typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel)) + { + return (TChannel)(IRequestChannel)new InstrumentedRequestChannel((IRequestChannel)innerChannel); + } + + if (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel)) + { + return (TChannel)(IDuplexChannel)new InstrumentedDuplexChannel((IDuplexChannel)innerChannel, this.binding.SendTimeout); + } + + throw new NotImplementedException(); } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs new file mode 100644 index 0000000000..8aea53040a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.ServiceModel.Channels; + +namespace OpenTelemetry.Instrumentation.Wcf.Implementation; + +internal class InstrumentedChannelFactoryBase : InstrumentedCommunicationObject, IChannelFactory + where T : IChannelFactory +{ + public InstrumentedChannelFactoryBase(T inner) + : base(inner) + { + } + + TProperty IChannelFactory.GetProperty() + where TProperty : class + { + return this.Inner.GetProperty(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs index d3d3ba9d28..656cbc8612 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs @@ -19,9 +19,10 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; -internal class InstrumentedCommunicationObject : ICommunicationObject +internal class InstrumentedCommunicationObject : ICommunicationObject + where T : ICommunicationObject { - public InstrumentedCommunicationObject(ICommunicationObject inner) + public InstrumentedCommunicationObject(T inner) { this.Inner = inner; } @@ -41,7 +42,7 @@ CommunicationState ICommunicationObject.State get { return this.Inner.State; } } - protected ICommunicationObject Inner { get; } + protected T Inner { get; } void ICommunicationObject.Abort() { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs similarity index 93% rename from src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs rename to src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs index ed9f1af144..fc6886bed1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,11 +21,11 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; -internal sealed class InstrumentedDuplexSessionChannel : InstrumentedChannel, IDuplexSessionChannel +internal sealed class InstrumentedDuplexChannel : InstrumentedChannel, IDuplexSessionChannel { private readonly TimeSpan telemetryTimeout; - public InstrumentedDuplexSessionChannel(IDuplexSessionChannel inner, TimeSpan telemetryTimeout) + public InstrumentedDuplexChannel(IDuplexChannel inner, TimeSpan telemetryTimeout) : base(inner) { this.telemetryTimeout = telemetryTimeout; @@ -37,9 +37,7 @@ public InstrumentedDuplexSessionChannel(IDuplexSessionChannel inner, TimeSpan te public Uri Via => this.Inner.Via; - public IDuplexSession Session => this.Inner.Session; - - private new IDuplexSessionChannel Inner { get => (IDuplexSessionChannel)base.Inner; } + public IDuplexSession Session => ((IDuplexSessionChannel)this.Inner).Session; public void Send(Message message) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs deleted file mode 100644 index a26ef79256..0000000000 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexSessionChannelFactory.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.ServiceModel; -using System.ServiceModel.Channels; - -namespace OpenTelemetry.Instrumentation.Wcf.Implementation; - -internal class InstrumentedDuplexSessionChannelFactory : InstrumentedChannelFactory, IChannelFactory -{ - private TimeSpan telemetryTimeOut; - - public InstrumentedDuplexSessionChannelFactory(IChannelFactory inner, TimeSpan telemetryTimeOut) - : base(inner) - { - this.telemetryTimeOut = telemetryTimeOut; - } - - private new IChannelFactory Inner { get => (IChannelFactory)base.Inner; } - - IDuplexSessionChannel IChannelFactory.CreateChannel(EndpointAddress to) - { - return new InstrumentedDuplexSessionChannel(this.Inner.CreateChannel(to), this.telemetryTimeOut); - } - - IDuplexSessionChannel IChannelFactory.CreateChannel(EndpointAddress to, Uri via) - { - return new InstrumentedDuplexSessionChannel(this.Inner.CreateChannel(to, via), this.telemetryTimeOut); - } -} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs index 16615cdda0..b8c2e9f29c 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs @@ -21,7 +21,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; -internal sealed class InstrumentedRequestChannel : InstrumentedChannel, IRequestChannel +internal sealed class InstrumentedRequestChannel : InstrumentedChannel, IRequestSessionChannel { public InstrumentedRequestChannel(IRequestChannel inner) : base(inner) @@ -32,7 +32,7 @@ public InstrumentedRequestChannel(IRequestChannel inner) Uri IRequestChannel.Via => this.Inner.Via; - private new IRequestChannel Inner { get => (IRequestChannel)base.Inner; } + IOutputSession ISessionChannel.Session => ((ISessionChannel)this.Inner).Session; Message IRequestChannel.Request(Message message) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs deleted file mode 100644 index 2470bd3f27..0000000000 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannelFactory.cs +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.ServiceModel; -using System.ServiceModel.Channels; - -namespace OpenTelemetry.Instrumentation.Wcf.Implementation; - -internal class InstrumentedRequestChannelFactory : InstrumentedChannelFactory, IChannelFactory -{ - public InstrumentedRequestChannelFactory(IChannelFactory inner) - : base(inner) - { - } - - private new IChannelFactory Inner { get => (IChannelFactory)base.Inner; } - - IRequestChannel IChannelFactory.CreateChannel(EndpointAddress to, Uri via) - { - return new InstrumentedRequestChannel(this.Inner.CreateChannel(to, via)); - } - - IRequestChannel IChannelFactory.CreateChannel(EndpointAddress to) - { - return new InstrumentedRequestChannel(this.Inner.CreateChannel(to)); - } -} diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs index 7cf336c10f..b3a5eb2b89 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs @@ -14,7 +14,6 @@ // limitations under the License. // -using System; using System.ServiceModel.Channels; using OpenTelemetry.Internal; @@ -30,17 +29,7 @@ public override IChannelFactory BuildChannelFactory(BindingC { Guard.ThrowIfNull(context); - if (typeof(TChannel) == typeof(IRequestChannel)) - { - return (IChannelFactory)new InstrumentedRequestChannelFactory(context.BuildInnerChannelFactory()); - } - - if (typeof(TChannel) == typeof(IDuplexSessionChannel)) - { - return (IChannelFactory)new InstrumentedDuplexSessionChannelFactory(context.BuildInnerChannelFactory(), context.Binding.SendTimeout); - } - - throw new NotSupportedException(); + return new InstrumentedChannelFactory(context.BuildInnerChannelFactory(), context.Binding); } /// @@ -50,6 +39,8 @@ public override bool CanBuildChannelFactory(BindingContext context) var supportedByInstrumentation = typeof(TChannel) == typeof(IRequestChannel) || + typeof(TChannel) == typeof(IRequestSessionChannel) || + typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel); return supportedByInstrumentation && base.CanBuildChannelFactory(context); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index cade5daae7..92828eb97e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -10,6 +10,9 @@ Other configurations may work as well but have not been tested. * SOAP and JSON payloads on HTTP/HTTPS transport * SOAP payloads on Net.TCP transport + * Encrypted and unencrypted transports + * Streamed and buffered transfer modes + * Signed and unsigned messages ## Installation diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index a3ac7aa816..914e358ede 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -8,11 +8,16 @@ disable + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs index 5a0366747d..2205af0c61 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs @@ -18,9 +18,14 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; using System.ServiceModel; using System.ServiceModel.Channels; +using System.ServiceModel.Security; using System.Threading.Tasks; using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; @@ -39,43 +44,8 @@ public class TelemetryBindingElementForTcpTests : IDisposable public TelemetryBindingElementForTcpTests(ITestOutputHelper outputHelper) { this.output = outputHelper; - - Random random = new Random(); - var retryCount = 5; - while (retryCount > 0) - { - try - { - this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); - this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); - var endpoint = this.serviceHost.AddServiceEndpoint( - typeof(IServiceContract), - new NetTcpBinding(SecurityMode.None), - "/Service"); - this.serviceHost.Open(); - break; - } - catch (Exception ex) - { - this.output.WriteLine(ex.ToString()); - if (this.serviceHost.State == CommunicationState.Faulted) - { - this.serviceHost.Abort(); - } - else - { - this.serviceHost.Close(); - } - - this.serviceHost = null; - retryCount--; - } - } - - if (this.serviceHost == null) - { - throw new InvalidOperationException("ServiceHost could not be started."); - } + this.serviceHost = this.CreateServiceHost(new NetTcpBinding(SecurityMode.None), null); + this.serviceBaseUri = this.serviceHost.BaseAddresses[0]; } public void Dispose() @@ -198,8 +168,8 @@ await client.ExecuteAsync( else { Assert.Equal(2, stoppedActivities.Count); - Assert.Equal("DownstreamInstrumentation", stoppedActivities[0].OperationName); - Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[1].OperationName); + Assert.NotNull(stoppedActivities.SingleOrDefault(activity => activity.OperationName == "DownstreamInstrumentation")); + Assert.NotNull(stoppedActivities.SingleOrDefault(activity => activity.OperationName == WcfInstrumentationActivitySource.OutgoingRequestActivityName)); } } else @@ -471,5 +441,121 @@ public async void DynamicTimeoutValuesAreRespected() WcfInstrumentationActivitySource.Options = null; } } + + [Fact] + public void StreamedTransferWithTransportSecurityWithMessageCredentialWorks() + { + // this config combination is unique because it uses an IRequestSessionChannel, + // where other NetTcp configs use IDuplexChannel + + List stoppedActivities = new List(); + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities) + .AddWcfInstrumentation() + .Build(); + + var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential); + binding.TransferMode = TransferMode.Streamed; + binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign; + binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; + var host = this.CreateServiceHost(binding, LoadCertificate()); + ServiceClient client = null; + try + { + client = new ServiceClient(binding, new EndpointAddress(new Uri(host.BaseAddresses[0], "/Service"))); + client.ClientCredentials.ClientCertificate.Certificate = LoadCertificate(); + + // never do this in production code, this insecure and for testing only + client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; + client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); + client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + } + finally + { + if (client.State == CommunicationState.Faulted) + { + client.Abort(); + } + else + { + client.Close(); + } + + host.Close(); + + tracerProvider.Shutdown(); + tracerProvider.Dispose(); + + WcfInstrumentationActivitySource.Options = null; + } + + Assert.NotEmpty(stoppedActivities); + Assert.Equal(WcfInstrumentationActivitySource.OutgoingRequestActivityName, stoppedActivities[0].OperationName); + Assert.Equal("http://opentelemetry.io/Service/ExecuteSynchronous", stoppedActivities[0].DisplayName); + } + + private static X509Certificate2 LoadCertificate() + { + // The certificate shouldn't ever need to be regenerated, but if it does + // for some reason these are the commands used to generate it: + // openssl genrsa -out otel.key 2048 + // openssl req -x509 -sha256 -key otel.key -out otel.pem -days 1 -subj "/C=CA/ST=ST/O=OpenTelemetry/CN=localhost" + // openssl pkcs12 -export -inkey otel.key -in otel.pem -out certificate.pfx -password pass: + + var resourceName = "OpenTelemetry.Instrumentation.Wcf.Tests.certificate.pfx"; + using var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); + using var memoryStream = new MemoryStream(); + resourceStream.CopyTo(memoryStream); + return new X509Certificate2(memoryStream.ToArray()); + } + + private ServiceHost CreateServiceHost(NetTcpBinding binding, X509Certificate2 cert) + { + ServiceHost serviceHost = null; + Random random = new Random(); + var retryCount = 5; + while (retryCount > 0) + { + try + { + var baseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); + serviceHost = new ServiceHost(new Service(), baseUri); + if (cert != null) + { + serviceHost.Credentials.ServiceCertificate.Certificate = cert; + } + + var endpoint = serviceHost.AddServiceEndpoint( + typeof(IServiceContract), + binding, + "/Service"); + + serviceHost.Open(); + break; + } + catch (Exception ex) + { + this.output.WriteLine(ex.ToString()); + if (serviceHost?.State == CommunicationState.Faulted) + { + serviceHost.Abort(); + } + else + { + serviceHost?.Close(); + } + + serviceHost = null; + retryCount--; + } + } + + if (serviceHost == null) + { + throw new InvalidOperationException("ServiceHost could not be started."); + } + + return serviceHost; + } } #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/certificate.pfx b/test/OpenTelemetry.Instrumentation.Wcf.Tests/certificate.pfx new file mode 100644 index 0000000000000000000000000000000000000000..28ff83933d2fb03c9ee159579d318146231cc00c GIT binary patch literal 2627 zcmai$XEYlM8^?(R5wo?fJ)*r@b!4NR%e@9lB5Rkc;P7(Vw|AAN$l(NpWVRajzS z?)NaJ9jZEFrsd||dc>ad@J1bkK z^80zppJFSu$sP52dhdySVTXZr>SkT;8bZSjTYe=PHz3liNh&j6K$Cs#aEcbZ!*u>v z*E8xgek)AU)53QGUp^Y*xTUu#w?dM+ddVq5)U3$G+U)b@-;MC#Sur16cts$59%?VE z@@X_`)#RLG9FaAi&0>~&oMkNo_nO1y<@Kkzaa=?;s7Je1C1Wlzk=={WJ_quOe|;C?X`9bi{oU4K{2<4&4ZT z=ss|9+{(5YCX;R>t_Is_w7|Ls1PGbkJuNNm@xnCH0^i6o$uZ1-9e3w4yu99Ujg98b z+bipspMASCz|raxto}7cX5CwGH<*vNU%xD2^O2}r48km^iH)F9@!Z3d zPdvW9S=+Zc{ipBD@@nl%@F^40an75Ot;or$zB=zk^|lNftkG9=fay9cOGd0Jzjbr3 zxGyg$oquzoHlRZ%6s<+84kjprqVFqpkdy1gquZA^MhRJfn$eVBS@g@YDDM{y?U;`T zI^h@fnzuII^nj~d6zY1YQM6&?5J1)OcquzazhzUK&+74ba{nQ}2OqZD&kreZI}vT( zp33EUQ#_g}iDMtco?a>#&bJ?$p2j@ri$0=i?yHf?aiwWT`|&PYi&Z-`it;Rrd~seI z#UlQe+;UES=;E>5^rZ}RoVm$Z38n=GyyMM}&muhunBICIyonz>(XcI*FV+Ih_*Cvy zUYUd5mYe8zWZ0kWFBC~OJw0bYQ;?j*PwG8S6_zF`+)^Hap+M;0e)vZ?pl~1x6nusQ z&dQGw@;?``vd{z0Ld7#E|NjJIe#zsz&SIYL{}l}7ssm0}yRtXKH<@l)GrkLm0*<}| z`2MVX@t5cGj~|UaV@8NI?>3ST$hL;OTY@%MZhpV1ra0!|dor(~e$hRvr^ST)1gE1q zRz!_%2>4=oq+vEjyv&pAcBu7MVYMN4?1KM33TD@tpEek3KdOL)ahUy$ zbX(hM%$DvUm5LF}_Hzp3R~e6JO$||vrD%K`-yjsNcO=?!a!PGLJ*lh4_llZWp9RlEg&L8zx+^jY+fb&I}^42=K&fzC_A$7kYl_&S%mgLCLAlMhqha z(|IG}GQK2ijGd?d04${`4~DoGj5^o3tEeySJ??~@8_xJ#p@tj|bghePf}yxRjD(MX z*atqyrQp6OxIrgPt>&Ry%f}B&u87AYJ`cUK&MYsw_mGEEhul&Ee-~$3Wr9}9HT~_6xEqUtCLhbXI zhknb`D;`h$5aOb7d;W!7p*=%=iA=F`E4HPIw2FmJgM~h7+a0;gS4;CHOSQ4)5omJ2 zWzskpQ5+bb)lvP_P{OWAeA6c8)xa=&;onBScaj2)ofF!gJ>Q`Uzgf>aIV7#u%r?Cw z1smj>IiY3s-4wckldj$)dCgVVm6{lb*NiAgguv!3!LB@RvnTV~5P#KExDOGTsT(gi zRIC$cKKBX#R!GJ>@}OpaH$Unew5aTAVv&d-afi{P8qw(UfN=8qu}Tz@*rfL3-ldHK zY+L3%uIVivmLwaE+y+y*qW+cR^PSUm+ZQ;n_-gGCPq0ACkNEC5_oVtX*F@*?vh;jt zTkPs-P6e4&&RVA~)u+z%$1qbfwp7q-JuBnER4cweY2gz^*kjIjrY2Y!48wFlTZ@-f zINDJ_(%UQ=^4~R#tZo+E6#6(pzE#hO@5wPynYclT{(`(p1ah$*eK=RiuC=d zXbnk23~YRxd)4N}qx_>v^!(GRH6wPs&0iK`VFdQ{yV}=JCk~js^ps;fDdlRUh;oY( zZO1KL^8|(hXUn=H(EwRF11S^)Y0~Em;Z#i_r#DJHv~{h(^aM@`sK9I0MQE1J(9xlT zQYDu)mrB1GhW>A&%oU+M8Mkf>>ma={{JbzPa;iA`+A-IXk;U(LWZgg+b-->Bef_eCGQP-R3 zl$#xRoW?$SyD4g7TShH*vQNLSw@2yMZc`&9o$pZ{#v(GIIB>;ZB9ay*O$%<*40`yC z{YbwH^hW`{{5;`3>`_t*Aq7+Q>w_w3Mio8H>xR9sAR9gLG zXEe7Ww(Jy6op%d`>B1CYY`@ Date: Mon, 9 Oct 2023 06:51:52 +0200 Subject: [PATCH 0841/1499] Nullable for tests-projects with already handled projects (#1370) --- ...lemetry.Extensions.Enrichment.Tests.csproj | 1 - ...etryEnrichmentProviderBuilderExtensions.cs | 4 +++ ...ichmentServiceCollectionExtensionsTests.cs | 12 +++++-- ...ActivityEventAttachingLogProcessorTests.cs | 17 ++++++---- .../OpenTelemetry.Extensions.Tests.csproj | 1 - .../Trace/AutoFlushActivityProcessorTests.cs | 3 ++ ...isProfilerEntryToActivityConverterTests.cs | 10 +++++- ...umentation.StackExchangeRedis.Tests.csproj | 1 - ...kExchangeRedisCallsInstrumentationTests.cs | 32 +++++++------------ 9 files changed, 49 insertions(+), 32 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index e0814e4c98..3b73750d9c 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -4,7 +4,6 @@ Unit test project for OpenTelemetry .NET SDK telemetry enrichment. $(NetFrameworkMinimumSupportedVersion) - disable diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs index 032105b732..3c96a9dc5e 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs @@ -41,6 +41,7 @@ public void AddTraceEnricherOfTRegistersEnricher() using var source = new ActivitySource(SourceName); using (var activity = source.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); @@ -70,6 +71,7 @@ public void AddTraceEnricherRegistersEnricher() using (var activity = source1.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); @@ -104,6 +106,7 @@ public void AddTraceEnricherActionRegistersEnricher() using (var activity = source1.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); @@ -133,6 +136,7 @@ public void AddTraceEnricherFactoryRegistersEnricher() using (var activity = source1.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs index 96b4ac80d5..1ed3a1256e 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs @@ -54,10 +54,15 @@ public async Task AddTraceEnricherOfTRegistersEnricher() using var source = new ActivitySource(SourceName); using (var activity = source.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); - Assert.Equal(1, (enrichers[0] as MyTraceEnricher).TimesCalled); - Assert.Equal(1, (enrichers[1] as MyTraceEnricher2).TimesCalled); + var myTraceEnricher = enrichers[0] as MyTraceEnricher; + var myTraceEnricher2 = enrichers[1] as MyTraceEnricher2; + Assert.NotNull(myTraceEnricher); + Assert.NotNull(myTraceEnricher2); + Assert.Equal(1, myTraceEnricher.TimesCalled); + Assert.Equal(1, myTraceEnricher2.TimesCalled); Assert.Single(exportedItems); @@ -97,6 +102,7 @@ public async Task AddTraceEnricherRegistersEnricher() using var source = new ActivitySource(SourceName); using (var activity = source.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); @@ -139,6 +145,7 @@ public async Task AddTraceEnricherActionRegistersEnricher() using (var activity = source1.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); @@ -177,6 +184,7 @@ public async Task AddTraceEnricherFactoryRegistersEnricher() using var source = new ActivitySource(SourceName); using (var activity = source.StartActivity(SourceName)) { + Assert.NotNull(activity); activity.Stop(); Assert.Single(exportedItems); diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index c5cd3af1c1..79cf07fbf5 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -89,16 +89,18 @@ public void AttachLogsToActivityEventTest( }); ILogger logger = loggerFactory.CreateLogger(); - Activity activity = this.activitySource.StartActivity("Test"); + Activity? activity = this.activitySource.StartActivity("Test"); + Assert.NotNull(activity); using IDisposable scope = logger.BeginScope("{NodeId}", 99); logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); - Activity innerActivity = null; + Activity? innerActivity = null; if (recordException) { innerActivity = this.activitySource.StartActivity("InnerTest"); + Assert.NotNull(innerActivity); using IDisposable innerScope = logger.BeginScope("{RequestId}", "1234"); @@ -116,7 +118,7 @@ public void AttachLogsToActivityEventTest( Assert.NotNull(logEvent); Assert.Equal("log", logEvent.Value.Name); - Dictionary tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + Dictionary? tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(tags); Assert.Equal("OpenTelemetry.Extensions.Tests.ActivityEventAttachingLogProcessorTests", tags[nameof(LogRecord.CategoryName)]); @@ -153,12 +155,13 @@ public void AttachLogsToActivityEventTest( if (recordException) { + Assert.NotNull(innerActivity); ActivityEvent? exLogEvent = innerActivity.Events.FirstOrDefault(); Assert.NotNull(exLogEvent); Assert.Equal("log", exLogEvent.Value.Name); - Dictionary exLogTags = exLogEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + Dictionary? exLogTags = exLogEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(exLogTags); Assert.Equal(99, exLogTags["scope[0].NodeId"]); @@ -169,7 +172,7 @@ public void AttachLogsToActivityEventTest( Assert.NotNull(exEvent); Assert.Equal("exception", exEvent.Value.Name); - Dictionary exTags = exEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + Dictionary? exTags = exEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(exTags); Assert.Equal("System.InvalidOperationException", exTags["exception.type"]); @@ -218,7 +221,8 @@ public void AttachLogsToActivityEventTest_Filter( }); ILogger logger = loggerFactory.CreateLogger(); - Activity activity = this.activitySource.StartActivity("Test"); + Activity? activity = this.activitySource.StartActivity("Test"); + Assert.NotNull(activity); using IDisposable scope = logger.BeginScope("{NodeId}", 99); @@ -227,6 +231,7 @@ public void AttachLogsToActivityEventTest_Filter( if (recordException) { var innerActivity = this.activitySource.StartActivity("InnerTest"); + Assert.NotNull(innerActivity); using IDisposable innerScope = logger.BeginScope("{RequestId}", "1234"); diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 3b61643e38..aac58b1b7b 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -4,7 +4,6 @@ Unit test project for OpenTelemetry .NET SDK preview features and extensions net7.0;net6.0 - disable diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index 4f279c4410..18a58a6add 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -40,6 +40,7 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMat using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Server); + Assert.NotNull(activity); activity.Stop(); mockExporting.Protected().Verify("OnForceFlush", Times.Once(), 5_000); @@ -59,6 +60,7 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNon using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Client); + Assert.NotNull(activity); activity.Stop(); mockExporting.Protected().Verify("OnForceFlush", Times.Never(), It.IsAny()); @@ -78,6 +80,7 @@ public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() using var source = new ActivitySource(sourceName); using var activity = source.StartActivity("name", ActivityKind.Server); + Assert.NotNull(activity); activity.Stop(); mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index dcec655941..84aa7076a4 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -47,7 +47,7 @@ public RedisProfilerEntryToActivityConverterTests() this.tracerProvider = Sdk.CreateTracerProviderBuilder() .AddRedisInstrumentation(this.connection) - .Build(); + .Build()!; } public void Dispose() @@ -67,6 +67,7 @@ public void ProfilerCommandToActivity_UsesCommandAsName() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.Equal("SET", result.DisplayName); } @@ -80,6 +81,7 @@ public void ProfilerCommandToActivity_UsesTimestampAsStartTime() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.Equal(now, result.StartTimeUtc); } @@ -92,6 +94,7 @@ public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbSystem)); Assert.Equal("redis", result.GetTagValue(SemanticConventions.AttributeDbSystem)); } @@ -106,6 +109,7 @@ public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbStatement)); Assert.Equal("SET", result.GetTagValue(SemanticConventions.AttributeDbStatement)); } @@ -122,6 +126,7 @@ public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.NotNull(result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); } @@ -140,6 +145,7 @@ public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); Assert.Equal($"{address}.0.0.0", result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); @@ -158,6 +164,7 @@ public void ProfilerCommandToActivity_UsesDnsEndPointAsEndPoint() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerName)); Assert.Equal(dnsEndPoint.Host, result.GetTagValue(SemanticConventions.AttributeNetPeerName)); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerPort)); @@ -176,6 +183,7 @@ public void ProfilerCommandToActivity_UsesOtherEndPointAsEndPoint() var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributePeerService)); Assert.Equal(unixEndPoint.ToString(), result.GetTagValue(SemanticConventions.AttributePeerService)); } diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index e6f92d872f..54185af2cd 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -5,7 +5,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 $(TARGET_FRAMEWORK) - disable diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index c3b40c7050..4ac9568f8c 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -41,7 +41,7 @@ To use Docker... */ private const string RedisEndPointEnvVarName = "OTEL_REDISENDPOINT"; - private static readonly string RedisEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(RedisEndPointEnvVarName); + private static readonly string? RedisEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(RedisEndPointEnvVarName); [Trait("CategoryName", "RedisIntegrationTests")] [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] @@ -108,7 +108,7 @@ public void SuccessfulCommandTest(string value) }; connectionOptions.EndPoints.Add(RedisEndPoint); - IConnectionMultiplexer connection = null; + IConnectionMultiplexer? connection = null; var activityProcessor = new Mock>(); var sampler = new TestSampler(); using (Sdk.CreateTracerProviderBuilder() @@ -162,7 +162,7 @@ public async void ProfilerSessionUsesTheSameDefault() var profilerFactory = instrumentation.GetProfilerSessionsFactory(); var first = profilerFactory(); var second = profilerFactory(); - ProfilingSession third = null; + ProfilingSession? third = null; await Task.Delay(1).ContinueWith((t) => { third = profilerFactory(); }); Assert.Equal(first, second); Assert.Equal(second, third); @@ -173,7 +173,7 @@ public async void ProfilerSessionUsesTheSameDefault() [InlineData("value1")] public void CanEnrichActivityFromCommand(string value) { - StackExchangeRedisInstrumentation instrumentation = null; + StackExchangeRedisInstrumentation? instrumentation = null; var connectionOptions = new ConfigurationOptions { @@ -248,13 +248,12 @@ public void CheckCacheIsFlushedProperly() // get an initial profiler from root activity Activity.Current = rootActivity; - ProfilingSession profiler0 = profilerFactory(); + ProfilingSession? profiler0 = profilerFactory(); // expect different result from synchronous child activity - ProfilingSession profiler1; using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) { - profiler1 = profilerFactory(); + var profiler1 = profilerFactory(); Assert.NotSame(profiler0, profiler1); } @@ -288,10 +287,10 @@ public async Task ProfilerSessionsHandleMultipleSpans() // get an initial profiler from root activity Activity.Current = rootActivity; - ProfilingSession profiler0 = profilerFactory(); + ProfilingSession? profiler0 = profilerFactory(); // expect different result from synchronous child activity - ProfilingSession profiler1; + ProfilingSession? profiler1; using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) { profiler1 = profilerFactory(); @@ -306,7 +305,7 @@ public async Task ProfilerSessionsHandleMultipleSpans() // lose async context on purpose await Task.Delay(100).ConfigureAwait(false); - ProfilingSession profiler2 = profilerFactory(); + ProfilingSession? profiler2 = profilerFactory(); Assert.NotSame(profiler0, profiler2); Assert.NotSame(profiler1, profiler2); } @@ -314,17 +313,10 @@ public async Task ProfilerSessionsHandleMultipleSpans() Activity.Current = rootActivity; // ensure same result back in root activity - ProfilingSession profiles3 = profilerFactory(); + ProfilingSession? profiles3 = profilerFactory(); Assert.Same(profiler0, profiles3); } - [Fact] - public void StackExchangeRedis_BadArgs() - { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddRedisInstrumentation(connection: null)); - } - [Fact] public void StackExchangeRedis_DependencyInjection_Success() { @@ -360,7 +352,7 @@ public void StackExchangeRedis_DependencyInjection_Success() [Fact] public void StackExchangeRedis_StackExchangeRedisInstrumentation_Test() { - StackExchangeRedisInstrumentation instrumentation = null; + StackExchangeRedisInstrumentation? instrumentation = null; var connectionOptions = new ConfigurationOptions { @@ -456,6 +448,6 @@ private static void VerifySamplingParameters(SamplingParameters samplingParamete Assert.Contains( samplingParameters.Tags, kvp => kvp.Key == SemanticConventions.AttributeDbSystem - && (string)kvp.Value == "redis"); + && (string?)kvp.Value == "redis"); } } From 7d0524fd6b261ad7a59facb62b6d4e600bca3050 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 10 Oct 2023 13:11:15 -0700 Subject: [PATCH 0842/1499] [onecollector] Update CHANGELOG for 1.6.0-rc.1 release (#1389) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 46d31e859c..932097b2b6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-rc.1 + +Released 2023-Oct-10 + ## 1.6.0-beta.1 Released 2023-Sep-20 From 0e3495ad51c90488620b4667f6062df55c79f626 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 10 Oct 2023 21:44:29 -0700 Subject: [PATCH 0843/1499] [repo] Add dedicated CI for AspNet projects (#1386) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/codecov.yml | 6 ++ .github/workflows/Component.Package.yml | 70 ++++++++++++++----- .github/workflows/ci.yml | 17 +++++ ...rumentation.AspNet.TelemetryHttpModule.yml | 66 ----------------- .../package-Instrumentation.AspNet.yml | 60 +++------------- .../OpenTelemetry.Instrumentation.AspNet.proj | 30 ++++++++ opentelemetry-dotnet-contrib.sln | 1 - ...entation.AspNet.TelemetryHttpModule.csproj | 2 +- 8 files changed, 117 insertions(+), 135 deletions(-) delete mode 100644 .github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.AspNet.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index ca71c9e68f..a6e4f68057 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -47,6 +47,12 @@ flags: paths: - src/OpenTelemetry.Exporter.OneCollector + unittests-Instrumentation.AspNet: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.AspNet + - src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + unittests-Instrumentation.Owin: carryforward: true paths: diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml index 86fbccca33..65dd5afa5f 100644 --- a/.github/workflows/Component.Package.yml +++ b/.github/workflows/Component.Package.yml @@ -6,17 +6,18 @@ on: project-name: required: true type: string + release-name: + required: false + type: string + default: '' jobs: build-test-pack: permissions: contents: write - strategy: - matrix: - os: [windows-latest] + runs-on: windows-latest - runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 with: @@ -40,21 +41,58 @@ jobs: - name: Publish Artifacts uses: actions/upload-artifact@v3 with: - name: ${{ inputs.project-name }}-packages - path: '**/${{ inputs.project-name }}/bin/**/*.*nupkg' + name: ${{ inputs.project-name }}.proj-packages + path: 'src/*/bin/Release/*.*nupkg' - - name: Publish Nuget + - name: Publish NuGets run: | - nuget push **/${{ inputs.project-name }}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{ inputs.project-name }}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + nuget push src/*/bin/Release/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{ inputs.project-name }}/CHANGELOG.md) for details." --latest + shell: pwsh + run: | + $packages = (Get-ChildItem -Path src/*/bin/Release/*.nupkg).Name + + $notes = '' + $firstPackageVersion = '' + + foreach ($package in $packages) + { + $match = [regex]::Match($package, '(.*)\.(\d+\.\d+\.\d+.*?)\.nupkg') + $packageName = $match.Groups[1].Value + $packageVersion = $match.Groups[2].Value + + if ($firstPackageVersion -eq '') + { + $firstPackageVersion = $packageVersion + } + + $notes += + @" + * NuGet: [$packageName v$packageVersion](https://www.nuget.org/packages/$packageName/$packageVersion) + + See [CHANGELOG](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/src/$packageName/CHANGELOG.md) for details. + + "@ + } + + $releaseName = '${{ inputs.release-name || inputs.project-name }}' + + if ($firstPackageVersion -contains '-alpha' -or $firstPackageVersion -contains '-beta' -or $firstPackageVersion -contains '-rc') + { + gh release create ${{ github.ref_name }} ` + --title "$releaseName v$firstPackageVersion" ` + --verify-tag ` + --notes "$notes" ` + --prerelease + } + else + { + gh release create ${{ github.ref_name }} ` + --title "$releaseName v$firstPackageVersion" ` + --verify-tag ` + --notes "$notes" ` + --latest + } env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f26727a29d..8b1572e8db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*'] shared: ['src/Shared/**'] code: ['**.cs', '.editorconfig'] + aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] @@ -54,6 +55,19 @@ jobs: if: contains(needs.detect-changes.outputs.changes, 'code') uses: ./.github/workflows/dotnet-format.yml + build-test-aspnet: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'aspnet') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.AspNet + code-cov-name: Instrumentation.AspNet + os-list: '[ "windows-latest" ]' + tfm-list: '[ "net462" ]' + build-test-geneva: needs: detect-changes if: | @@ -167,6 +181,8 @@ jobs: -Exclude ` OpenTelemetry.Exporter.Geneva.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj, + OpenTelemetry.Instrumentation.AspNet.Tests.csproj, + OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, @@ -200,6 +216,7 @@ jobs: detect-changes, lint-md, lint-dotnet-format, + build-test-aspnet, build-test-geneva, build-test-onecollector, build-test-owin, diff --git a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml b/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml deleted file mode 100644 index 6cdd46856c..0000000000 --- a/.github/workflows/package-Instrumentation.AspNet.TelemetryHttpModule.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Pack OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'Instrumentation.AspNet.TelemetryHttpModule-*' - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - permissions: - contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-Instrumentation.AspNet.yml b/.github/workflows/package-Instrumentation.AspNet.yml index 1b90c4dfec..a0aa4af8bc 100644 --- a/.github/workflows/package-Instrumentation.AspNet.yml +++ b/.github/workflows/package-Instrumentation.AspNet.yml @@ -1,5 +1,7 @@ name: Pack OpenTelemetry.Instrumentation.AspNet +# Note: This releases OpenTelemetry.Instrumentation.AspNet & OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + on: workflow_dispatch: inputs: @@ -9,58 +11,14 @@ on: default: 'warning' push: tags: - - 'Instrumentation.AspNet-*' + - 'Instrumentation.AspNet-*' # trigger when we create a tag with prefix "Instrumentation.AspNet-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.AspNet - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.') || contains(github.ref_name, '-rc9.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.AspNet + release-name: 'OpenTelemetry Asp.Net Instrumentation Packages' + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj new file mode 100644 index 0000000000..a88fcf404a --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj @@ -0,0 +1,30 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 94d0778bca..11feb31592 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -45,7 +45,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Extensions.AzureMonitor.yml = .github\workflows\package-Extensions.AzureMonitor.yml .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml - .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml = .github\workflows\package-Instrumentation.AspNet.TelemetryHttpModule.yml .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 395a6adc25..002e2ffad7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -5,7 +5,7 @@ true A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI - Instrumentation.AspNet.TelemetryHttpModule- + Instrumentation.AspNet- From 66c74acca7a84882d77ba41513b46cf7b7b0ff27 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 11 Oct 2023 09:04:58 -0700 Subject: [PATCH 0844/1499] [repo] Use project files for tests in dedicated CI flows (#1390) --- .github/workflows/Component.BuildTest.yml | 4 ++-- .github/workflows/Component.Package.yml | 6 +++--- build/Projects/OpenTelemetry.Exporter.Geneva.proj | 6 ++++++ build/Projects/OpenTelemetry.Exporter.OneCollector.proj | 6 ++++++ build/Projects/OpenTelemetry.Instrumentation.AspNet.proj | 6 ++++++ build/Projects/OpenTelemetry.Instrumentation.Owin.proj | 6 ++++++ build/Projects/OpenTelemetry.Instrumentation.Process.proj | 6 ++++++ .../OpenTelemetry.Instrumentation.StackExchangeRedis.proj | 6 ++++++ build/Projects/OpenTelemetry.Instrumentation.Wcf.proj | 6 ++++++ opentelemetry-dotnet-contrib.sln | 1 + 10 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 1166b216bc..84b6b81565 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -47,8 +47,8 @@ jobs: - name: dotnet build build/Projects/${{ inputs.project-name }}.proj run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore - - name: dotnet test test/${{ inputs.project-name }}.Tests - run: dotnet test test/${{ inputs.project-name }}.Tests --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + - name: dotnet test build/Projects/${{ inputs.project-name }}.proj + run: dotnet test build/Projects/${{ inputs.project-name }}.proj --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - name: Install coverage tool run: dotnet tool install -g dotnet-coverage diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml index 65dd5afa5f..d20fa50754 100644 --- a/.github/workflows/Component.Package.yml +++ b/.github/workflows/Component.Package.yml @@ -32,11 +32,11 @@ jobs: - name: dotnet build build/Projects/${{ inputs.project-name }}.proj run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore -p:Deterministic=true - - name: dotnet test test/${{ inputs.project-name }}.Tests - run: dotnet test test/${{ inputs.project-name }}.Tests --configuration Release --no-restore --no-build + - name: dotnet test build/Projects/${{ inputs.project-name }}.proj + run: dotnet test build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build - name: dotnet pack build/Projects/${{ inputs.project-name }}.proj - run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-build --no-restore + run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build - name: Publish Artifacts uses: actions/upload-artifact@v3 diff --git a/build/Projects/OpenTelemetry.Exporter.Geneva.proj b/build/Projects/OpenTelemetry.Exporter.Geneva.proj index dc1e79aafa..2d51435254 100644 --- a/build/Projects/OpenTelemetry.Exporter.Geneva.proj +++ b/build/Projects/OpenTelemetry.Exporter.Geneva.proj @@ -11,6 +11,8 @@ + + @@ -25,4 +27,8 @@ + + + + diff --git a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj index e821e8f5e0..534e3e326d 100644 --- a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj +++ b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj @@ -10,6 +10,8 @@ + + @@ -24,4 +26,8 @@ + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj index a88fcf404a..42b4f215b3 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj @@ -13,6 +13,8 @@ + + @@ -27,4 +29,8 @@ + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj index 5169a696f0..4742b9765f 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj @@ -10,6 +10,8 @@ + + @@ -24,4 +26,8 @@ + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.Process.proj b/build/Projects/OpenTelemetry.Instrumentation.Process.proj index 50a89c4933..2eb64b6afd 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Process.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Process.proj @@ -10,6 +10,8 @@ + + @@ -24,4 +26,8 @@ + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj b/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj index 3e4dad9e44..051686d22a 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj @@ -10,6 +10,8 @@ + + @@ -24,4 +26,8 @@ + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj index dba436da80..515f7ca280 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj @@ -10,6 +10,8 @@ + + @@ -24,4 +26,8 @@ + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 11feb31592..a5a5ab61c6 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -303,6 +303,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 ProjectSection(SolutionItems) = preProject build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj + build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj From 2fd5e52528ccedfe62a560e1bb97b7efa94c83ec Mon Sep 17 00:00:00 2001 From: Christoffer Hjalmarsson Date: Thu, 12 Oct 2023 03:34:30 +0200 Subject: [PATCH 0845/1499] [Instrumentation.AspNet] Fix activity being closed before processing completes (#1388) --- .../ActivityHelper.cs | 3 +- .../CHANGELOG.md | 4 ++ .../CHANGELOG.md | 5 +++ .../ActivityHelperTest.cs | 39 +++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index d76929ec0c..569409aa3f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -131,8 +131,6 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ Debug.Assert(context.Items[ContextKey] is ContextHolder, "Context item is not an ContextHolder instance."); var currentActivity = Activity.Current; - - aspNetActivity.Stop(); context.Items[ContextKey] = null; try @@ -144,6 +142,7 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ AspNetTelemetryEventSource.Log.CallbackException(aspNetActivity, "OnStopped", callbackEx); } + aspNetActivity.Stop(); AspNetTelemetryEventSource.Log.ActivityStopped(aspNetActivity); if (textMapPropagator is not TraceContextPropagator) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 4435c22bc6..e03d655ca2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fixed an issue where activities were stopped incorrectly before processing completed. + Activity processor's `OnEnd` will now happen after `AspNetInstrumentationOptions.Enrich`. + ([#1388](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1388)) + * Update `OpenTelemetry.Api` to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 93680f1418..91a0895bb2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Release together with `OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule`. + Fixed an issue where activities were stopped incorrectly before processing completed. + Activity processor's `OnEnd` will now happen after `AspNetInstrumentationOptions.Enrich`. + ([#1388](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1388)) + ## 1.0.0-rc9.9 Released 2023-Jun-09 diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index 5b229b3fb2..b5d8216e6a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -447,6 +447,45 @@ public void Fire_Exception_Events() Assert.Equal(1, callbacksFired); } + [Fact] + public void Should_Handle_Activity_Events_In_Correct_Order() + { + var eventOrder = new List(); + const string ActivityOnStarted = "ActivityOnStarted"; + const string ActivityOnStopped = "ActivityOnStarted"; + const string OnStartCallback = "OnStartCallback"; + const string OnStopCallback = "OnStopCallback"; + + this.EnableListener(_ => eventOrder.Add(ActivityOnStarted), _ => eventOrder.Add(ActivityOnStopped)); + + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, (_, _) => eventOrder.Add(OnStartCallback)); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, (_, _) => eventOrder.Add(OnStopCallback)); + + var expectedOrder = new List() + { + ActivityOnStarted, + OnStartCallback, + OnStopCallback, + ActivityOnStopped, + }; + + Assert.Equal(expectedOrder, eventOrder); + } + + [Fact] + public void Should_Not_Pass_Stopped_Activity_To_Callbacks() + { + this.EnableListener(); + + var wasStopped = false; + var context = HttpContextHelper.GetFakeHttpContext(); + using var rootActivity = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, (activity, _) => wasStopped = activity.IsStopped || wasStopped); + ActivityHelper.StopAspNetActivity(this.noopTextMapPropagator, rootActivity, context, (activity, _) => wasStopped = activity.IsStopped || wasStopped); + + Assert.False(wasStopped); + } + private void EnableListener(Action? onStarted = null, Action? onStopped = null, Func? onSample = null) { Debug.Assert(this.activitySourceListener == null, "Cannot attach multiple listeners in tests."); From 387960ebcaaa878d5c5e005aba516268dace1f93 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 11 Oct 2023 22:48:41 -0700 Subject: [PATCH 0846/1499] [Instrumentation.AspNet] Update CHANGELOG for 1.6.0-beta.1 release (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index e03d655ca2..abd8552d4e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-beta.1 + +Released 2023-Oct-11 + * Fixed an issue where activities were stopped incorrectly before processing completed. Activity processor's `OnEnd` will now happen after `AspNetInstrumentationOptions.Enrich`. ([#1388](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1388)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 91a0895bb2..ea5d2bd227 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,10 +2,18 @@ ## Unreleased -* Release together with `OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule`. - Fixed an issue where activities were stopped incorrectly before processing completed. - Activity processor's `OnEnd` will now happen after `AspNetInstrumentationOptions.Enrich`. - ([#1388](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1388)) +## 1.6.0-beta.1 + +Released 2023-Oct-11 + +* Updated `OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule` dependency + to `1.6.0-beta.1` which brings in the following changes.: + + * Fixed an issue where activities were stopped incorrectly before processing completed. + Activity processor's `OnEnd` will now happen after `AspNetInstrumentationOptions.Enrich`. + ([#1388](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1388)) + * Update `OpenTelemetry.Api` to `1.6.0`. + ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) ## 1.0.0-rc9.9 From 1463c753e54c250791f61c256528771ef3833f1f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 12 Oct 2023 10:23:47 -0700 Subject: [PATCH 0847/1499] [repo] Fix a bug in the package workflow causing github release tagging issues (#1395) --- .github/workflows/Component.Package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml index d20fa50754..1a6e247999 100644 --- a/.github/workflows/Component.Package.yml +++ b/.github/workflows/Component.Package.yml @@ -78,7 +78,7 @@ jobs: $releaseName = '${{ inputs.release-name || inputs.project-name }}' - if ($firstPackageVersion -contains '-alpha' -or $firstPackageVersion -contains '-beta' -or $firstPackageVersion -contains '-rc') + if ($firstPackageVersion -match '-alpha' -or $firstPackageVersion -match '-beta' -or $firstPackageVersion -match '-rc') { gh release create ${{ github.ref_name }} ` --title "$releaseName v$firstPackageVersion" ` From 3b85729ed991bd60c6408e23d55615bcd9be9d6f Mon Sep 17 00:00:00 2001 From: Isaac Hili <18428880+isaachili@users.noreply.github.com> Date: Fri, 13 Oct 2023 08:35:58 +0200 Subject: [PATCH 0848/1499] Export metrics to InfluxDB at a configurable interval (#1394) --- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 ++ .../netstandard2.0/PublicAPI.Unshipped.txt | 2 ++ src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 2 ++ .../InfluxDBExporterExtensions.cs | 2 +- .../InfluxDBMetricsExporterOptions.cs | 16 ++++++++++++++++ 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt index 458d0ea807..8318f20350 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -7,6 +7,8 @@ OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> v OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricExportIntervalMilliseconds.get -> int +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricExportIntervalMilliseconds.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string? diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index b54682ec56..eec1ac3ac7 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -7,6 +7,8 @@ OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> v OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricExportIntervalMilliseconds.get -> int +OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricExportIntervalMilliseconds.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string? diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 6648363039..6deddc2a63 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -4,6 +4,8 @@ * Updates to 1.6.0 of OpenTelemetry SDK. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Support for a configurable export interval in OpenTelemetry.Exporter.InfluxDB. + ([#1394](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1394)) ## 1.0.0-alpha.2 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs index 3bf2ecaaff..1d4a61e893 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs @@ -62,7 +62,7 @@ public static MeterProviderBuilder AddInfluxDBMetricsExporter(this MeterProvider }); var metricsWriter = CreateMetricsWriter(options.MetricsSchema); var exporter = new InfluxDBMetricsExporter(metricsWriter, influxDbClient, writeApi); - return new PeriodicExportingMetricReader(exporter) + return new PeriodicExportingMetricReader(exporter, options.MetricExportIntervalMilliseconds) { TemporalityPreference = MetricReaderTemporalityPreference.Cumulative, }; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs index c7408cf705..f31e3c0161 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs @@ -15,6 +15,7 @@ // using System; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.InfluxDB; @@ -23,6 +24,8 @@ namespace OpenTelemetry.Exporter.InfluxDB; /// public class InfluxDBMetricsExporterOptions { + private int metricExportIntervalMilliseconds = 60000; + /// /// Gets or sets HTTP/S destination for line protocol. /// @@ -52,4 +55,17 @@ public class InfluxDBMetricsExporterOptions /// Gets or sets the time to wait at most (milliseconds) with the write. /// public int FlushInterval { get; set; } = 1000; + + /// + /// Gets or sets the metric export interval in milliseconds. The default value is 60000. + /// + public int MetricExportIntervalMilliseconds + { + get => this.metricExportIntervalMilliseconds; + set + { + Guard.ThrowIfOutOfRange(value, min: 1000); + this.metricExportIntervalMilliseconds = value; + } + } } From 2a9ade7e9e12489ad9ecdb980d5e725932b759ea Mon Sep 17 00:00:00 2001 From: Isaac Hili <18428880+isaachili@users.noreply.github.com> Date: Fri, 13 Oct 2023 10:42:55 +0200 Subject: [PATCH 0849/1499] [Exporter.InfluxDB] Update CHANGELOG for 1.0.0-alpha.3 release (#1398) --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 6deddc2a63..6fb6853f03 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.3 + +Released 2023-Oct-13 + * Updates to 1.6.0 of OpenTelemetry SDK. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Support for a configurable export interval in OpenTelemetry.Exporter.InfluxDB. From 0f431e4ee0703716e7ac3d3e3b5d8dcb24594b9c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:11:30 -0700 Subject: [PATCH 0850/1499] [Exporter.Geneva][TLD] Fix serialization bug when there are no Part C fields (#1396) --- .../CHANGELOG.md | 4 +++ .../TLDExporter/TldLogExporter.cs | 28 +++++++++++-------- .../TLDExporter/TldTraceExporter.cs | 24 +++++++++------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 22fc9fc349..4e7fe41e3a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fix serialization bug in `TldTraceExporter` and `TldLogExporter` when there + are no Part C fields. + ([#1396](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1396)) + ## 1.7.0-alpha.1 Released 2023-Sep-22 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 5e01f79c8b..4ba7a2a465 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -411,22 +411,26 @@ internal void SerializeLogRecord(LogRecord logRecord) partCFieldsCountFromState = dataForScopes.PartCFieldsCountFromState; int partCFieldsCount = partCFieldsCountFromState + hasEnvProperties; // We at least have these many fields in Part C - var partCFieldsCountPatch = eb.AddStruct("PartC", (byte)partCFieldsCount); - for (int i = 0; i < partCFieldsCountFromState; i++) + if (partCFieldsCount > 0) { - Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); - } + var partCFieldsCountPatch = eb.AddStruct("PartC", (byte)partCFieldsCount); - if (hasEnvProperties == 1) - { - // Get all "other" fields and collapse them into single field - // named "env_properties". - var serializedEnvPropertiesStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(envPropertiesList, out var count); - eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); - } + for (int i = 0; i < partCFieldsCountFromState; i++) + { + Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); + } - eb.SetStructFieldCount(partCFieldsCountPatch, (byte)partCFieldsCount); + if (hasEnvProperties == 1) + { + // Get all "other" fields and collapse them into single field + // named "env_properties". + var serializedEnvPropertiesStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(envPropertiesList, out var count); + eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); + } + + eb.SetStructFieldCount(partCFieldsCountPatch, (byte)partCFieldsCount); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index dba4c41cdd..8c732019ea 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -332,20 +332,24 @@ internal void SerializeActivity(Activity activity) eb.SetStructFieldCount(partBFieldsCountPatch, partBFieldsCount); var partCFieldsCount = partCFieldsCountFromTags + hasEnvProperties; - eb.AddStruct("PartC", (byte)partCFieldsCount); - for (int i = 0; i < partCFieldsCountFromTags; i++) + if (partCFieldsCount > 0) { - Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); - } + eb.AddStruct("PartC", (byte)partCFieldsCount); - if (hasEnvProperties == 1) - { - // Get all "other" fields and collapse them into single field - // named "env_properties". + for (int i = 0; i < partCFieldsCountFromTags; i++) + { + Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); + } - var serializedEnvPropertiesStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(envPropertiesList, out var count); - eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); + if (hasEnvProperties == 1) + { + // Get all "other" fields and collapse them into single field + // named "env_properties". + + var serializedEnvPropertiesStringAsBytes = JsonSerializer.SerializeKeyValuePairsListAsBytes(envPropertiesList, out var count); + eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); + } } } } From 4db5ac689e2a5e5cf761d3df65d049829358af21 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 13 Oct 2023 23:05:19 -0700 Subject: [PATCH 0851/1499] [repo] Add dedicated CI for persistent storage projects (#1397) --- .github/codecov.yml | 5 ++ .github/workflows/ci.yml | 20 +++++- ...package-PersistentStorage.Abstractions.yml | 63 ------------------ .../package-PersistentStorage.FileSystem.yml | 66 ------------------- .../workflows/package-PersistentStorage.yml | 24 +++++++ .../OpenTelemetry.PersistentStorage.proj | 34 ++++++++++ opentelemetry-dotnet-contrib.sln | 4 +- ...etry.PersistentStorage.Abstractions.csproj | 2 +- ...emetry.PersistentStorage.FileSystem.csproj | 7 +- 9 files changed, 90 insertions(+), 135 deletions(-) delete mode 100644 .github/workflows/package-PersistentStorage.Abstractions.yml delete mode 100644 .github/workflows/package-PersistentStorage.FileSystem.yml create mode 100644 .github/workflows/package-PersistentStorage.yml create mode 100644 build/Projects/OpenTelemetry.PersistentStorage.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index a6e4f68057..a48a5abbd9 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -73,3 +73,8 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Wcf + unittests-PersistentStorage: + carryforward: true + paths: + - src/OpenTelemetry.PersistentStorage.Abstractions + - src/OpenTelemetry.PersistentStorage.FileSystem diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b1572e8db..4e4f6d1689 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,7 @@ jobs: geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] + persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] @@ -32,10 +33,13 @@ jobs: 'src/**', 'test/**', 'examples/**', + '!*/OpenTelemetry.Instrumentation.AspNet*/**', + '!examples/AspNet/**', '!*/OpenTelemetry.Exporter.Geneva*/**', '!*/OpenTelemetry.Exporter.OneCollector*/**', '!*/OpenTelemetry.Instrumentation.Owin*/**', '!examples/owin/**', + '!*/OpenTelemetry.PersistentStorage*/**', '!*/OpenTelemetry.Instrumentation.Process*/**', '!examples/process-instrumentation/**', '!*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', @@ -103,6 +107,17 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' + build-test-persistentstorage: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'persistentstorage') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.PersistentStorage + code-cov-name: PersistentStorage + build-test-process: needs: detect-changes if: | @@ -186,7 +201,9 @@ jobs: OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, - OpenTelemetry.Instrumentation.Wcf.Tests.csproj + OpenTelemetry.Instrumentation.Wcf.Tests.csproj, + OpenTelemetry.PersistentStorage.Abstractions.csproj, + OpenTelemetry.PersistentStorage.FileSystem.csproj ForEach ($project in $projects) { @@ -220,6 +237,7 @@ jobs: build-test-geneva, build-test-onecollector, build-test-owin, + build-test-persistentstorage, build-test-process, build-test-redis, build-test-redis-integration, diff --git a/.github/workflows/package-PersistentStorage.Abstractions.yml b/.github/workflows/package-PersistentStorage.Abstractions.yml deleted file mode 100644 index 3c0c1d2d68..0000000000 --- a/.github/workflows/package-PersistentStorage.Abstractions.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: Pack OpenTelemetry.PersistentStorage.Abstractions - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'PersistentStorage.Abstractions-*' # trigger when we create a tag with prefix "PersistentStorage.Abstractions-" - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - permissions: - contents: write - env: - PROJECT: OpenTelemetry.PersistentStorage.Abstractions - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.PersistentStorage.Abstractions has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-PersistentStorage.FileSystem.yml b/.github/workflows/package-PersistentStorage.FileSystem.yml deleted file mode 100644 index 1de7b01c48..0000000000 --- a/.github/workflows/package-PersistentStorage.FileSystem.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Pack OpenTelemetry.PersistentStorage.FileSystem - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'PersistentStorage.FileSystem-*' # trigger when we create a tag with prefix "PersistentStorage.FileSystem-" - -jobs: - build-test-pack: - runs-on: ${{ matrix.os }} - permissions: - contents: write - env: - PROJECT: OpenTelemetry.PersistentStorage.FileSystem - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.PersistentStorage.FileSystem has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/package-PersistentStorage.yml b/.github/workflows/package-PersistentStorage.yml new file mode 100644 index 0000000000..12e7fa6c61 --- /dev/null +++ b/.github/workflows/package-PersistentStorage.yml @@ -0,0 +1,24 @@ +name: Pack OpenTelemetry.PersistentStorage + +# Note: This releases OpenTelemetry.PersistentStorage.Abstractions & OpenTelemetry.PersistentStorage.FileSystem + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'PersistentStorage-*' # trigger when we create a tag with prefix "PersistentStorage-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.PersistentStorage + release-name: 'OpenTelemetry Persistent Storage Packages' + secrets: inherit diff --git a/build/Projects/OpenTelemetry.PersistentStorage.proj b/build/Projects/OpenTelemetry.PersistentStorage.proj new file mode 100644 index 0000000000..714e728846 --- /dev/null +++ b/build/Projects/OpenTelemetry.PersistentStorage.proj @@ -0,0 +1,34 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a5a5ab61c6..f038533620 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -60,9 +60,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml - .github\workflows\package-PersistentStorage.Abstractions.yml = .github\workflows\package-PersistentStorage.Abstractions.yml - .github\workflows\package-PersistentStorage.FileSystem.yml = .github\workflows\package-PersistentStorage.FileSystem.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml + .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml .github\workflows\stale.yml = .github\workflows\stale.yml EndProjectSection EndProject @@ -308,6 +307,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj + build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj EndProjectSection EndProject Global diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index 5b9da7344f..98d3da7e26 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -7,7 +7,7 @@ net6.0;$(TargetFrameworks) true OpenTelemetry Persistent Storage Abstractions - PersistentStorage.Abstractions- + PersistentStorage- $(NoWarn),1591 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 8c098a6873..8e8b12199d 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -7,17 +7,20 @@ net6.0;$(TargetFrameworks) true OpenTelemetry Persistent Storage - PersistentStorage.FileSystem- + PersistentStorage- $(NoWarn),1591 + + + + - From 33ec689d5444a6488f7c39c3ef6729c009d780f2 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 18 Oct 2023 17:09:19 -0700 Subject: [PATCH 0852/1499] [Exporter.Geneva] Update mapping for http tags (#1402) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ .../MsgPackExporter/MsgPackTraceExporter.cs | 3 +++ .../TLDExporter/TldTraceExporter.cs | 3 +++ 3 files changed, 10 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 4e7fe41e3a..5ca46c4425 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Update Part B mapping to add Http related tags based on the new Semantic + Conventions. + ([#1402](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1402)) + * Fix serialization bug in `TldTraceExporter` and `TldLogExporter` when there are no Part C fields. ([#1396](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1396)) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 605bc5f170..2a8ad9efb5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -410,8 +410,11 @@ public void Dispose() ["db.statement"] = "dbStatement", ["http.method"] = "httpMethod", + ["http.request.method"] = "httpMethod", ["http.url"] = "httpUrl", + ["url.full"] = "httpUrl", ["http.status_code"] = "httpStatusCode", + ["http.response.status_code"] = "httpStatusCode", ["messaging.system"] = "messagingSystem", ["messaging.destination"] = "messagingDestination", diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index 8c732019ea..f7338114b5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -41,8 +41,11 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable ["db.statement"] = "dbStatement", ["http.method"] = "httpMethod", + ["http.request.method"] = "httpMethod", ["http.url"] = "httpUrl", + ["url.full"] = "httpUrl", ["http.status_code"] = "httpStatusCode", + ["http.response.status_code"] = "httpStatusCode", ["messaging.system"] = "messagingSystem", ["messaging.destination"] = "messagingDestination", From dc572137a43c90bd4baccbb8a34d7a74d06e9dcc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 18 Oct 2023 22:23:33 -0700 Subject: [PATCH 0853/1499] [repo] Add dedicated CI for OpenTelemetry.Extensions (#1403) --- .github/codecov.yml | 5 ++ .github/workflows/ci.yml | 15 +++++ .github/workflows/package-Extensions.yml | 55 ++----------------- build/Projects/OpenTelemetry.Extensions.proj | 32 +++++++++++ opentelemetry-dotnet-contrib.sln | 3 +- .../OpenTelemetry.Extensions.csproj | 4 +- .../OpenTelemetry.Extensions.Tests.csproj | 1 + 7 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 build/Projects/OpenTelemetry.Extensions.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index a48a5abbd9..8f6f7ee367 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -47,6 +47,11 @@ flags: paths: - src/OpenTelemetry.Exporter.OneCollector + unittests-Extensions: + carryforward: true + paths: + - src/OpenTelemetry.Extensions + unittests-Instrumentation.AspNet: carryforward: true paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e4f6d1689..6f39867a53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,7 @@ jobs: shared: ['src/Shared/**'] code: ['**.cs', '.editorconfig'] aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] + extensions: ['*/OpenTelemetry.Extensions*/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] @@ -35,6 +36,7 @@ jobs: 'examples/**', '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', + '!*/OpenTelemetry.Extensions*/**', '!*/OpenTelemetry.Exporter.Geneva*/**', '!*/OpenTelemetry.Exporter.OneCollector*/**', '!*/OpenTelemetry.Instrumentation.Owin*/**', @@ -72,6 +74,17 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' + build-test-extensions: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'extensions') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Extensions + code-cov-name: Extensions + build-test-geneva: needs: detect-changes if: | @@ -196,6 +209,7 @@ jobs: -Exclude ` OpenTelemetry.Exporter.Geneva.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj, + OpenTelemetry.Extensions.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, OpenTelemetry.Instrumentation.Owin.Tests.csproj, @@ -234,6 +248,7 @@ jobs: lint-md, lint-dotnet-format, build-test-aspnet, + build-test-extensions, build-test-geneva, build-test-onecollector, build-test-owin, diff --git a/.github/workflows/package-Extensions.yml b/.github/workflows/package-Extensions.yml index d068014306..5c91779a9d 100644 --- a/.github/workflows/package-Extensions.yml +++ b/.github/workflows/package-Extensions.yml @@ -12,55 +12,10 @@ on: - 'Extensions-*' # trigger when we create a tag with prefix "Extensions-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Extensions - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release #--no-build <- OpenTelemetry.Extensions has a conditional net6.0 target which causes dotnet pack to break when -no-build is used (for some reason) - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Extensions + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Extensions.proj b/build/Projects/OpenTelemetry.Extensions.proj new file mode 100644 index 0000000000..eb57800c45 --- /dev/null +++ b/build/Projects/OpenTelemetry.Extensions.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f038533620..d92d59d3c2 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -60,8 +60,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml - .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml + .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml EndProjectSection EndProject @@ -302,6 +302,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 ProjectSection(SolutionItems) = preProject build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj + build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index e05f2a585e..1d85d7270d 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -2,8 +2,8 @@ - netstandard2.0;net462 - net6.0;$(TargetFrameworks) + net6.0;netstandard2.0 + $(TargetFrameworks);net462 true OpenTelemetry .NET SDK preview features and extensions Extensions- diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index aac58b1b7b..7604a758f1 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -4,6 +4,7 @@ Unit test project for OpenTelemetry .NET SDK preview features and extensions net7.0;net6.0 + $(TargetFrameworks);net462 From 60dc97b930811fb26c8021e31d8ef97bb2460d7e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 19 Oct 2023 22:59:59 -0700 Subject: [PATCH 0854/1499] [repo] Add dedicated CI for EventCounters and Runtime instrumentation projects (#1404) --- .github/codecov.yml | 10 ++++ .github/workflows/ci.yml | 58 ++++++++++++++++--- .../package-Instrumentation.EventCounters.yml | 55 ++---------------- .../package-Instrumentation.Runtime.yml | 55 ++---------------- .../{ci-aot.yml => verifyaotcompat.yml} | 13 ++--- ...lemetry.Instrumentation.EventCounters.proj | 33 +++++++++++ ...OpenTelemetry.Instrumentation.Runtime.proj | 33 +++++++++++ opentelemetry-dotnet-contrib.sln | 4 +- 8 files changed, 142 insertions(+), 119 deletions(-) rename .github/workflows/{ci-aot.yml => verifyaotcompat.yml} (56%) create mode 100644 build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj create mode 100644 build/Projects/OpenTelemetry.Instrumentation.Runtime.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index 8f6f7ee367..4b0f135946 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -58,6 +58,11 @@ flags: - src/OpenTelemetry.Instrumentation.AspNet - src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + unittests-Instrumentation.EventCounters: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.EventCounters + unittests-Instrumentation.Owin: carryforward: true paths: @@ -68,6 +73,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Process + unittests-Instrumentation.Runtime: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Runtime + unittests-Instrumentation.StackExchangeRedis: carryforward: true paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f39867a53..9ae7ba4c30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,9 @@ jobs: build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*'] shared: ['src/Shared/**'] code: ['**.cs', '.editorconfig'] + aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] + eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions*/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] @@ -29,13 +31,17 @@ jobs: persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] + runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] solution: [ 'src/**', 'test/**', 'examples/**', + '!test/OpenTelemetry.AotCompatibility.TestApp/**', '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', + '!*/OpenTelemetry.Instrumentation.EventCounters*/**', + '!examples/event-counters/**', '!*/OpenTelemetry.Extensions*/**', '!*/OpenTelemetry.Exporter.Geneva*/**', '!*/OpenTelemetry.Exporter.OneCollector*/**', @@ -46,6 +52,8 @@ jobs: '!examples/process-instrumentation/**', '!*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', '!examples/redis/**', + '!*/OpenTelemetry.Instrumentation.Runtime*/**', + '!examples/runtime-instrumentation/**', '!*/OpenTelemetry.Instrumentation.Wcf*/**', '!examples/wcf/**', '!**/*.md' @@ -74,6 +82,18 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' + build-test-eventcounters: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'eventcounters') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.EventCounters + code-cov-name: Instrumentation.EventCounters + tfm-list: '[ "net6.0", "net7.0" ]' + build-test-extensions: needs: detect-changes if: | @@ -161,6 +181,17 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/integration.yml + build-test-runtime: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'runtime') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Runtime + code-cov-name: Instrumentation.Runtime + build-test-wcf: needs: detect-changes if: | @@ -195,13 +226,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v3 - - name: Restore - run: dotnet restore - - - name: Build - run: dotnet build --configuration Release --no-restore - - - name: Test ${{ matrix.version }} + - name: Restore, Build, & Test ${{ matrix.version }} shell: pwsh run: | $projects = Get-ChildItem ` @@ -212,8 +237,10 @@ jobs: OpenTelemetry.Extensions.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, + OpenTelemetry.Instrumentation.EventCounters.Tests.csproj, OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, + OpenTelemetry.Instrumentation.Runtime.Tests.csproj, OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.Abstractions.csproj, @@ -221,7 +248,7 @@ jobs: ForEach ($project in $projects) { - dotnet test $project.FullName --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + dotnet test $project.FullName --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true } - name: Install coverage tool @@ -241,6 +268,16 @@ jobs: flags: unittests-Solution name: Code Coverage for solution on [${{ matrix.os }}.${{ matrix.version }}] + verify-aot-compat: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'eventcounters') + || contains(needs.detect-changes.outputs.changes, 'runtime') + || contains(needs.detect-changes.outputs.changes, 'aottestapp') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/verifyaotcompat.yml + build-test: needs: [ lint-misspell-sanitycheck, @@ -248,6 +285,7 @@ jobs: lint-md, lint-dotnet-format, build-test-aspnet, + build-test-eventcounters, build-test-extensions, build-test-geneva, build-test-onecollector, @@ -256,8 +294,10 @@ jobs: build-test-process, build-test-redis, build-test-redis-integration, + build-test-runtime, build-test-wcf, - build-test-solution + build-test-solution, + verify-aot-compat ] if: always() && !cancelled() && !contains(needs.*.result, 'failure') runs-on: windows-latest diff --git a/.github/workflows/package-Instrumentation.EventCounters.yml b/.github/workflows/package-Instrumentation.EventCounters.yml index 22d285eed9..0d31ed5664 100644 --- a/.github/workflows/package-Instrumentation.EventCounters.yml +++ b/.github/workflows/package-Instrumentation.EventCounters.yml @@ -12,55 +12,10 @@ on: - 'Instrumentation.EventCounters-*' # trigger when we create a tag with prefix "Instrumentation.EventCounters-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.EventCounters - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.EventCounters + secrets: inherit diff --git a/.github/workflows/package-Instrumentation.Runtime.yml b/.github/workflows/package-Instrumentation.Runtime.yml index c06446fb53..7dee5caf36 100644 --- a/.github/workflows/package-Instrumentation.Runtime.yml +++ b/.github/workflows/package-Instrumentation.Runtime.yml @@ -12,55 +12,10 @@ on: - 'Instrumentation.Runtime-*' # trigger when we create a tag with prefix "Instrumentation.Runtime-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.Instrumentation.Runtime - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.Runtime + secrets: inherit diff --git a/.github/workflows/ci-aot.yml b/.github/workflows/verifyaotcompat.yml similarity index 56% rename from .github/workflows/ci-aot.yml rename to .github/workflows/verifyaotcompat.yml index 676e4ccfff..cf8425ed89 100644 --- a/.github/workflows/ci-aot.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -1,16 +1,11 @@ -name: Publish AOTCompatibility testApp +name: Publish & Verify AOT Compatibility on: - pull_request: - branches: [ 'main*' ] - paths: - - 'src/OpenTelemetry.Instrumentation.Runtime/**' - - '!src/OpenTelemetry.Instrumentation.Runtime/README.md' - - 'src/OpenTelemetry.Instrumentation.EventCounters/**' - - '!src/OpenTelemetry.Instrumentation.EventCounters/README.md' + workflow_call: jobs: - aot-test: + run-verify-aot-compat: + strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: diff --git a/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj b/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj new file mode 100644 index 0000000000..28db30bced --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj @@ -0,0 +1,33 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj b/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj new file mode 100644 index 0000000000..b57a3a224c --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj @@ -0,0 +1,33 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index d92d59d3c2..e194a73c78 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -28,7 +28,6 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" ProjectSection(SolutionItems) = preProject .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml - .github\workflows\ci-aot.yml = .github\workflows\ci-aot.yml .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml .github\workflows\ci.yml = .github\workflows\ci.yml .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml @@ -63,6 +62,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml + .github\workflows\verifyaotcompat.yml = .github\workflows\verifyaotcompat.yml EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE-3FA8-4FE0-823A-FD365EAC78AF}" @@ -304,8 +304,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj + build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj + build\Projects\OpenTelemetry.Instrumentation.Runtime.proj = build\Projects\OpenTelemetry.Instrumentation.Runtime.proj build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj From a9ee9c4e36f535807acd05ad09339bcb651681be Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 23 Oct 2023 09:29:09 -0700 Subject: [PATCH 0855/1499] [repo] Add dedicated CI for the OpenTelemetry.ResourceDetectors.Azure project (#1406) --- .github/codecov.yml | 5 ++ .github/workflows/ci.yml | 19 ++++++- .../package-ResourceDetectors.Azure.yml | 55 ++----------------- ...OpenTelemetry.ResourceDetectors.Azure.proj | 32 +++++++++++ opentelemetry-dotnet-contrib.sln | 2 + 5 files changed, 61 insertions(+), 52 deletions(-) create mode 100644 build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index 4b0f135946..25a4fe986f 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -93,3 +93,8 @@ flags: paths: - src/OpenTelemetry.PersistentStorage.Abstractions - src/OpenTelemetry.PersistentStorage.FileSystem + + unittests-ResourceDetectors.Azure: + carryforward: true + paths: + - src/OpenTelemetry.ResourceDetectors.Azure diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ae7ba4c30..edbfc5d276 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,7 @@ jobs: code: ['**.cs', '.editorconfig'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] + azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions*/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] @@ -40,6 +41,7 @@ jobs: '!test/OpenTelemetry.AotCompatibility.TestApp/**', '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', + '!*/OpenTelemetry.ResourceDetectors.Azure*/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions*/**', @@ -82,6 +84,17 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' + build-test-azure: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'azure') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.ResourceDetectors.Azure + code-cov-name: ResourceDetectors.Azure + build-test-eventcounters: needs: detect-changes if: | @@ -243,8 +256,8 @@ jobs: OpenTelemetry.Instrumentation.Runtime.Tests.csproj, OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, OpenTelemetry.Instrumentation.Wcf.Tests.csproj, - OpenTelemetry.PersistentStorage.Abstractions.csproj, - OpenTelemetry.PersistentStorage.FileSystem.csproj + OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, + OpenTelemetry.ResourceDetectors.Azure.Tests.csproj ForEach ($project in $projects) { @@ -273,6 +286,7 @@ jobs: if: | contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') + || contains(needs.detect-changes.outputs.changes, 'azure') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') @@ -285,6 +299,7 @@ jobs: lint-md, lint-dotnet-format, build-test-aspnet, + build-test-azure, build-test-eventcounters, build-test-extensions, build-test-geneva, diff --git a/.github/workflows/package-ResourceDetectors.Azure.yml b/.github/workflows/package-ResourceDetectors.Azure.yml index 58e58d7d1c..2918b0f4ab 100644 --- a/.github/workflows/package-ResourceDetectors.Azure.yml +++ b/.github/workflows/package-ResourceDetectors.Azure.yml @@ -12,55 +12,10 @@ on: - 'ResourceDetectors.Azure-*' # trigger when we create a tag with prefix "ResourceDetectors.Azure-" jobs: - build-test-pack: - runs-on: ${{ matrix.os }} + call-build-test-pack: permissions: contents: write - env: - PROJECT: OpenTelemetry.ResourceDetectors.Azure - - strategy: - matrix: - os: [windows-latest] - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetching all - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - - - name: Install dependencies - run: dotnet restore src/${{env.PROJECT}} - - - name: dotnet build ${{env.PROJECT}} - run: dotnet build src/${{env.PROJECT}} --configuration Release --no-restore -p:Deterministic=true - - - name: dotnet test ${{env.PROJECT}} - run: dotnet test test/${{env.PROJECT}}.Tests - - - name: dotnet pack ${{env.PROJECT}} - run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - - - name: Publish Artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{env.PROJECT}}-packages - path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' - - - name: Publish Nuget - run: | - nuget push **/${{env.PROJECT}}/bin/**/*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} - - - name: Create GitHub Prerelease - if: ${{ (contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --prerelease - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release - if: ${{ !(contains(github.ref_name, '-alpha.') || contains(github.ref_name, '-beta.') || contains(github.ref_name, '-rc.')) }} - run: gh release create ${{ github.ref_name }} --title ${{ github.ref_name }} --verify-tag --notes "See [CHANGELOG](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/${{ github.ref_name }}/src/${{env.PROJECT}}/CHANGELOG.md) for details." --latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.ResourceDetectors.Azure + secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj new file mode 100644 index 0000000000..149ae576c5 --- /dev/null +++ b/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e194a73c78..6435228624 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -60,6 +60,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml + .github\workflows\package-ResourceDetectors.Azure.yml = .github\workflows\package-ResourceDetectors.Azure.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml .github\workflows\verifyaotcompat.yml = .github\workflows\verifyaotcompat.yml @@ -311,6 +312,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj + build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj EndProjectSection EndProject Global From 25a45adb05fe46e1bd496814a7729b1bb1e6de6a Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Mon, 23 Oct 2023 19:33:44 -0700 Subject: [PATCH 0856/1499] [ResourceDetector.Azure] add support for AOT/Trimming (#1405) --- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 6 ++++ .../AppServiceResourceDetector.cs | 4 +-- .../AzureVmMetaDataRequestor.cs | 6 +++- .../CHANGELOG.md | 3 ++ ...enTelemetry.ResourceDetectors.Azure.csproj | 2 +- .../SourceGenerationContext.cs | 34 +++++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + 8 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..00226a19b1 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector +OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.AzureVMResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index 113a81f526..1be89789d2 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -77,10 +77,10 @@ public Resource Detect() private static string? GetAzureResourceURI(string websiteSiteName) { - string websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); + string? websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); string websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty; - int idx = websiteOwnerName.IndexOf('+'); + int idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal); string subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName; if (string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId)) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs index d6a163d874..c5d3aa6a06 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs @@ -31,11 +31,15 @@ internal static class AzureVmMetaDataRequestor using var httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) }; httpClient.DefaultRequestHeaders.Add("Metadata", "True"); - var res = httpClient.GetStringAsync(AzureVmMetadataEndpointURL).ConfigureAwait(false).GetAwaiter().GetResult(); + var res = httpClient.GetStringAsync(new Uri(AzureVmMetadataEndpointURL)).ConfigureAwait(false).GetAwaiter().GetResult(); if (res != null) { +#if NET6_0_OR_GREATER + return JsonSerializer.Deserialize(res, SourceGenerationContext.Default.AzureVmMetadataResponse); +#else return JsonSerializer.Deserialize(res); +#endif } return null; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index a3e55208f4..201ed431e9 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added NET6 target framework to support Trimming. + ([#1405](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1405)) + ## 1.0.0-beta.3 Released 2023-Sep-19 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index 6e922d0e3c..d066155384 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + net6.0;netstandard2.0 OpenTelemetry Resource Detectors for Azure cloud environments $(PackageTags);ResourceDetector ResourceDetectors.Azure- diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs b/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs new file mode 100644 index 0000000000..1aa65851e9 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if NET6_0_OR_GREATER +using System.Text.Json.Serialization; + +namespace OpenTelemetry.ResourceDetectors.Azure; + +/// +/// "Source Generation" is feature added to System.Text.Json in .NET 6.0. +/// This is a performance optimization that avoids runtime reflection when performing serialization. +/// Serialization metadata will be computed at compile-time and included in the assembly. +/// . +/// . +/// . +/// +[JsonSerializable(typeof(AzureVmMetadataResponse))] +internal sealed partial class SourceGenerationContext : JsonSerializerContext +{ +} +#endif diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 58b7242edb..e2d902bd70 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -11,6 +11,7 @@ + From 92a5f16ca071a350433aff5a3c2b657ff14ca1db Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Tue, 24 Oct 2023 12:11:58 +0300 Subject: [PATCH 0857/1499] Release OpenTelemetry.Instrumentation.EntityFrameworkCore v1.0.0-beta.8 (#1409) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index e2e2bbc727..9105a6b124 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.8 + +Released 2023-Oct-24 + * Added `Filter` public API on `EntityFrameworkInstrumentationOptions` to enable filtering of instrumentation. ([#1203](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1203)) From 81f52cbc9c8a7c782e8b352685f155bf3b4dc56e Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Tue, 24 Oct 2023 12:21:02 +0300 Subject: [PATCH 0858/1499] Release OpenTelemetry.Instrumentation.ElasticsearchClient v1.0.0-beta.5 (#1408) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index d063132527..37108607bd 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2023-Oct-24 + * Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource being created ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) From 4f9c9b388d8f7e4d46de285d12bd37e9aa1cddf2 Mon Sep 17 00:00:00 2001 From: Yun-Ting Lin Date: Wed, 25 Oct 2023 17:05:20 -0700 Subject: [PATCH 0859/1499] [OneCollector] 1.6.0 release (#1412) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 932097b2b6..453fbeb992 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0 + +Released 2023-Oct-25 + ## 1.6.0-rc.1 Released 2023-Oct-10 From cc812fff9678ab477f907931301216b8ee8750cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BC=9F?= <305542043@qq.com> Date: Thu, 26 Oct 2023 12:30:00 +0800 Subject: [PATCH 0860/1499] Update Elastic.Clients.Elasticsearch ActivitySource name (#1411) --- src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index dab6a9a2d2..7d66b4b72c 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -113,6 +113,8 @@ that deprecates `NEST/Elasticsearch.Net`, brings native support for OpenTelemetry. To instrument it you need to configure the OpenTelemetry SDK to listen to the `ActivitySource` used by the library by calling `AddSource("Elastic.Clients.Elasticsearch.ElasticsearchClient")` +(Elastic.Clients.Elasticsearch version < 8.10.0) or `AddSource("Elastic.Transport")` +(Elastic.Clients.Elasticsearch version >= 8.10.0) on the `TracerProviderBuilder`. ## References From 9dacf3e236fcec04224c59e4ffa4d076c6d8f614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 27 Oct 2023 21:48:16 +0200 Subject: [PATCH 0861/1499] [Instrumentation.Wcf] Release 1.0.0-rc.13 (#1413) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index f60493308d..fd35609cca 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.13 + +Released 2023-Oct-30 + * Update OpenTelemetry SDK version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Fixed span hierarchy when hosted in ASP.NET From 6a3d264105de8182f98bf9b038180432ac994c24 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 31 Oct 2023 11:29:39 -0500 Subject: [PATCH 0862/1499] Fix AOT warnings in StackExchangeRedis (#1415) --- .github/workflows/ci.yml | 1 + .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 22 ++ .../CHANGELOG.md | 3 + .../RedisProfilerEntryToActivityConverter.cs | 67 +++-- ....Instrumentation.StackExchangeRedis.csproj | 5 +- ...kExchangeRedisConnectionInstrumentation.cs | 6 +- src/Shared/PropertyFetcher.AOT.cs | 237 ++++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + 9 files changed, 323 insertions(+), 20 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/Shared/PropertyFetcher.AOT.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edbfc5d276..8b12146178 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -289,6 +289,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'azure') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'redis') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/verifyaotcompat.yml diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..c76bae94e0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,22 @@ +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(string! name, StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.Dispose() -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.get -> System.Action? +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.get -> System.TimeSpan +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.set -> void +OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.StackExchangeRedisInstrumentationOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 46ccedfb32..774ebf09e3 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -5,6 +5,9 @@ * Update OTel API version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Add `net6.0` target framework and make library AOT and trimming compatible + ([#1415](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1415)) + ## 1.0.0-rc9.10 Released 2023-Jun-09 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 00dc74295e..3c34c5bf98 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -20,16 +20,21 @@ using System.Reflection.Emit; using OpenTelemetry.Trace; using StackExchange.Redis.Profiling; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +#endif namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; internal static class RedisProfilerEntryToActivityConverter { + private const string ScriptEvalMessageTypeName = "StackExchange.Redis.RedisDatabase+ScriptEvalMessage"; + private static readonly Lazy> MessageDataGetter = new(() => { - var redisAssembly = typeof(IProfiledCommand).Assembly; - Type profiledCommandType = redisAssembly.GetType("StackExchange.Redis.Profiling.ProfiledCommand"); - Type scriptMessageType = redisAssembly.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage"); + Type profiledCommandType = Type.GetType("StackExchange.Redis.Profiling.ProfiledCommand, StackExchange.Redis", throwOnError: true)!; + Type scriptMessageType = Type.GetType(ScriptEvalMessageTypeName + ", StackExchange.Redis", throwOnError: true)!; var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); var scriptDelegate = CreateFieldGetter(scriptMessageType, "script", BindingFlags.NonPublic | BindingFlags.Instance); @@ -59,12 +64,27 @@ internal static class RedisProfilerEntryToActivityConverter script = scriptDelegate?.Invoke(message); } - if (commandAndKeyFetcher.TryFetch(message, out var value)) + if (GetCommandAndKey(commandAndKeyFetcher, message, out var value)) { return (value, script); } return (null, script); + +#if NET6_0_OR_GREATER + [DynamicDependency("CommandAndKey", ScriptEvalMessageTypeName, "StackExchange.Redis")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The CommandAndKey property is preserved by the above DynamicDependency")] +#endif + static bool GetCommandAndKey( + PropertyFetcher commandAndKeyFetcher, + object message, +#if NET6_0_OR_GREATER + [NotNullWhen(true)] +#endif + out string? value) + { + return commandAndKeyFetcher.TryFetch(message, out value); + } }); }); @@ -186,20 +206,37 @@ public static void DrainSession(Activity? parentActivity, IEnumerable - private static Func? CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) + private static Func? CreateFieldGetter( +#if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] +#endif + Type classType, + string fieldName, + BindingFlags flags) { - FieldInfo field = classType.GetField(fieldName, flags); + FieldInfo? field = classType.GetField(fieldName, flags); if (field != null) { - string methodName = classType.FullName + ".get_" + field.Name; - DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); - ILGenerator generator = getterMethod.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Castclass, classType); - generator.Emit(OpCodes.Ldfld, field); - generator.Emit(OpCodes.Ret); - - return (Func)getterMethod.CreateDelegate(typeof(Func)); +#if NET6_0_OR_GREATER + if (RuntimeFeature.IsDynamicCodeSupported) +#endif + { + string methodName = classType.FullName + ".get_" + field.Name; + DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); + ILGenerator generator = getterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, classType); + generator.Emit(OpCodes.Ldfld, field); + generator.Emit(OpCodes.Ret); + + return (Func)getterMethod.CreateDelegate(typeof(Func)); + } +#if NET6_0_OR_GREATER + else + { + return obj => (TField?)field.GetValue(obj); + } +#endif } return null; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 86ff3d66c6..353a227c63 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -1,10 +1,9 @@ - netstandard2.0;net462 + net6.0;netstandard2.0;net462 StackExchange.Redis instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;Redis;StackExchange.Redis - true true Instrumentation.StackExchangeRedis- true @@ -12,6 +11,8 @@ + + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs index f1a4a9e528..5d93294c0f 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs @@ -31,9 +31,9 @@ internal sealed class StackExchangeRedisConnectionInstrumentation : IDisposable { internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; internal const string RedisFlagsKeyName = "db.redis.flags"; - internal static readonly string ActivitySourceName = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Name; + internal static readonly string ActivitySourceName = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Name!; internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - internal static readonly Version Version = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Version; + internal static readonly Version Version = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Version!; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); internal static readonly IEnumerable> CreationTags = new[] { @@ -137,7 +137,7 @@ internal void Flush() } } - private void DrainEntries(object state) + private void DrainEntries(object? state) { while (true) { diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs new file mode 100644 index 0000000000..e617720f3c --- /dev/null +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -0,0 +1,237 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#nullable disable + +// NOTE: This version of PropertyFetcher is AOT-compatible. +// Usages of the non-AOT-compatible version can be moved over to this one when they need to support AOT/trimming. +// Copied from https://github.com/open-telemetry/opentelemetry-dotnet/blob/86a6ba0b7f7ed1f5e84e5a6610e640989cd3ae9f/src/Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs#L30 + +#nullable enable + +#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using System.Reflection; + +namespace OpenTelemetry.Instrumentation; + +/// +/// PropertyFetcher fetches a property from an object. +/// +/// The type of the property being fetched. +internal sealed class PropertyFetcher +{ +#if NET6_0_OR_GREATER + private const string TrimCompatibilityMessage = "PropertyFetcher is used to access properties on objects dynamically by design and cannot be made trim compatible."; +#endif + private readonly string propertyName; + private PropertyFetch? innerFetcher; + + /// + /// Initializes a new instance of the class. + /// + /// Property name to fetch. + public PropertyFetcher(string propertyName) + { + this.propertyName = propertyName; + } + + public int NumberOfInnerFetchers => this.innerFetcher == null + ? 0 + : 1 + this.innerFetcher.NumberOfInnerFetchers; + + /// + /// Try to fetch the property from the object. + /// + /// Object to be fetched. + /// Fetched value. + /// if the property was fetched. +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(TrimCompatibilityMessage)] +#endif + public bool TryFetch( +#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER + [NotNullWhen(true)] +#endif + object? obj, + out T? value) + { + var innerFetcher = this.innerFetcher; + if (innerFetcher is null) + { + return TryFetchRare(obj, this.propertyName, ref this.innerFetcher, out value); + } + + return innerFetcher.TryFetch(obj, out value); + } + +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(TrimCompatibilityMessage)] +#endif + private static bool TryFetchRare(object? obj, string propertyName, ref PropertyFetch? destination, out T? value) + { + if (obj is null) + { + value = default; + return false; + } + + var fetcher = PropertyFetch.Create(obj.GetType().GetTypeInfo(), propertyName); + + if (fetcher is null) + { + value = default; + return false; + } + + destination = fetcher; + + return fetcher.TryFetch(obj, out value); + } + + // see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(TrimCompatibilityMessage)] +#endif + private abstract class PropertyFetch + { + public abstract int NumberOfInnerFetchers { get; } + + public static PropertyFetch? Create(TypeInfo type, string propertyName) + { + var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, propertyName, StringComparison.OrdinalIgnoreCase)) ?? type.GetProperty(propertyName); + return CreateFetcherForProperty(property); + + static PropertyFetch? CreateFetcherForProperty(PropertyInfo? propertyInfo) + { + if (propertyInfo == null || !typeof(T).IsAssignableFrom(propertyInfo.PropertyType)) + { + // returns null and wait for a valid payload to arrive. + return null; + } + + var declaringType = propertyInfo.DeclaringType; + if (declaringType!.IsValueType) + { + throw new NotSupportedException( + $"Type: {declaringType.FullName} is a value type. PropertyFetcher can only operate on reference payload types."); + } + + if (declaringType == typeof(object)) + { + // TODO: REMOVE this if branch when .NET 7 is out of support. + // This branch is never executed and is only needed for .NET 7 AOT-compiler at trimming stage; i.e., + // this is not needed in .NET 8, because the compiler is improved and call into MakeGenericMethod will be AOT-compatible. + // It is used to force the AOT compiler to create an instantiation of the method with a reference type. + // The code for that instantiation can then be reused at runtime to create instantiation over any other reference. + return CreateInstantiated(propertyInfo); + } + else + { + return DynamicInstantiationHelper(declaringType, propertyInfo); + } + + // Separated as a local function to be able to target the suppression to just this call. + // IL3050 was generated here because of the call to MakeGenericType, which is problematic in AOT if one of the type parameters is a value type; + // because the compiler might need to generate code specific to that type. + // If the type parameter is a reference type, there will be no problem; because the generated code can be shared among all reference type instantiations. +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "The code guarantees that all the generic parameters are reference types.")] +#endif + static PropertyFetch? DynamicInstantiationHelper(Type declaringType, PropertyInfo propertyInfo) + { + return (PropertyFetch?)typeof(PropertyFetch) + .GetMethod(nameof(CreateInstantiated), BindingFlags.NonPublic | BindingFlags.Static)! + .MakeGenericMethod(declaringType) // This is validated in the earlier call chain to be a reference type. + .Invoke(null, new object[] { propertyInfo })!; + } + } + } + + public abstract bool TryFetch( +#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER + [NotNullWhen(true)] +#endif + object? obj, + out T? value); + + // Goal: make PropertyFetcher AOT-compatible. + // AOT compiler can't guarantee correctness when call into MakeGenericType or MakeGenericMethod + // if one of the generic parameters is a value type (reference types are OK.) + // For PropertyFetcher, the decision was made to only support reference type payloads, i.e.: + // the object from which to get the property value MUST be a reference type. + // Create generics with the declared object type as a generic parameter is OK, but we need the return type + // of the property to be a value type (on top of reference types.) + // Normally, we would have a helper class like `PropertyFetchInstantiated` that takes 2 generic parameters, + // the declared object type, and the type of the property value. + // But that would mean calling MakeGenericType, with value type parameters which AOT won't support. + // + // As a workaround, Generic instantiation was split into: + // 1. The object type comes from the PropertyFetcher generic parameter. + // Compiler supports it even if it is a value type; the type is known statically during compilation + // since PropertyFetcher is used with it. + // 2. Then, the declared object type is passed as a generic parameter to a generic method on PropertyFetcher (or nested type.) + // Therefore, calling into MakeGenericMethod will only require specifying one parameter - the declared object type. + // The declared object type is guaranteed to be a reference type (throw on value type.) Thus, MakeGenericMethod is AOT compatible. + private static PropertyFetch CreateInstantiated(PropertyInfo propertyInfo) + where TDeclaredObject : class + => new PropertyFetchInstantiated(propertyInfo); + +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(TrimCompatibilityMessage)] +#endif + private sealed class PropertyFetchInstantiated : PropertyFetch + where TDeclaredObject : class + { + private readonly string propertyName; + private readonly Func propertyFetch; + private PropertyFetch? innerFetcher; + + public PropertyFetchInstantiated(PropertyInfo property) + { + this.propertyName = property.Name; + this.propertyFetch = (Func)property.GetMethod!.CreateDelegate(typeof(Func)); + } + + public override int NumberOfInnerFetchers => this.innerFetcher == null + ? 0 + : 1 + this.innerFetcher.NumberOfInnerFetchers; + + public override bool TryFetch( +#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER + [NotNullWhen(true)] +#endif + object? obj, + out T? value) + { + if (obj is TDeclaredObject o) + { + value = this.propertyFetch(o); + return true; + } + + var innerFetcher = this.innerFetcher; + if (innerFetcher is null) + { + return TryFetchRare(obj, this.propertyName, ref this.innerFetcher, out value); + } + + return innerFetcher.TryFetch(obj, out value); + } + } + } +} diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index e2d902bd70..cf45ad25eb 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -11,6 +11,7 @@ + From 4c5197f9bf88f23269cd42c0c86b76269ad5d195 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Tue, 31 Oct 2023 09:40:54 -0700 Subject: [PATCH 0863/1499] [Instrumentation.StackExchangeRedis] Update CHANGELOG for 1.0.0-rc9.11 (#1419) --- .../CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 774ebf09e3..c45bf08a64 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,7 +2,11 @@ ## Unreleased -* Update OTel API version to `1.6.0`. +## 1.0.0-rc9.11 + +Released 2023-Oct-31 + +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Add `net6.0` target framework and make library AOT and trimming compatible @@ -12,7 +16,7 @@ Released 2023-Jun-09 -* Update OTel API version to `1.5.0`. +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.5.0`. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) ## 1.0.0-rc9.9 From e85c1e3fa5139389144f29838d07983a2a2bb08a Mon Sep 17 00:00:00 2001 From: Thomas Bolon Date: Tue, 31 Oct 2023 21:38:55 +0100 Subject: [PATCH 0864/1499] Add missing Binding Redirect for Examples.AspNet project (#1418) Co-authored-by: Cijo Thomas --- examples/AspNet/Web.config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index 936a551d10..12073fe2c3 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -57,6 +57,10 @@ + + + + From 28906fb5c7abbee0728d352d103a0c0efae04bf9 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 31 Oct 2023 20:19:43 -0500 Subject: [PATCH 0865/1499] Fix up Redis trimming annotations (#1420) --- .../CHANGELOG.md | 3 +++ .../Implementation/RedisProfilerEntryToActivityConverter.cs | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index c45bf08a64..bbab8572f4 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix an issue in the trimming annotations to refer to the correct Type + ([#1420](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1420)) + ## 1.0.0-rc9.11 Released 2023-Oct-31 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 3c34c5bf98..aef136e3e7 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -29,12 +29,10 @@ namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; internal static class RedisProfilerEntryToActivityConverter { - private const string ScriptEvalMessageTypeName = "StackExchange.Redis.RedisDatabase+ScriptEvalMessage"; - private static readonly Lazy> MessageDataGetter = new(() => { Type profiledCommandType = Type.GetType("StackExchange.Redis.Profiling.ProfiledCommand, StackExchange.Redis", throwOnError: true)!; - Type scriptMessageType = Type.GetType(ScriptEvalMessageTypeName + ", StackExchange.Redis", throwOnError: true)!; + Type scriptMessageType = Type.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage, StackExchange.Redis", throwOnError: true)!; var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); var scriptDelegate = CreateFieldGetter(scriptMessageType, "script", BindingFlags.NonPublic | BindingFlags.Instance); @@ -72,7 +70,7 @@ internal static class RedisProfilerEntryToActivityConverter return (null, script); #if NET6_0_OR_GREATER - [DynamicDependency("CommandAndKey", ScriptEvalMessageTypeName, "StackExchange.Redis")] + [DynamicDependency("CommandAndKey", "StackExchange.Redis.Message", "StackExchange.Redis")] [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The CommandAndKey property is preserved by the above DynamicDependency")] #endif static bool GetCommandAndKey( From 4986ccbd666a6f7adf969658114448d1431a365b Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 1 Nov 2023 11:49:08 -0700 Subject: [PATCH 0866/1499] [Instrumentation.StackExchangeRedis] Update CHANGELOG for 1.0.0-rc9.12 (#1421) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index bbab8572f4..26bae0ac4a 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.12 + +Released 2023-Nov-01 + * Fix an issue in the trimming annotations to refer to the correct Type ([#1420](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1420)) From 2f29ddb0a423407589234716c866de2276917bf6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 1 Nov 2023 12:06:19 -0700 Subject: [PATCH 0867/1499] [aot] Added a note in aot test app to also update ci when being modified (#1422) --- .../OpenTelemetry.AotCompatibility.TestApp.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index cf45ad25eb..a3516672cc 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -9,6 +9,10 @@ + From a372bc065452a7c13bcc69a021e842be440cce13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 2 Nov 2023 21:53:39 +0100 Subject: [PATCH 0868/1499] Nullable Instrumentation.EntityFrameworkCore (#1366) --- build/Common.props | 8 +++- ...searchRequestPipelineDiagnosticListener.cs | 2 + ...Instrumentation.ElasticsearchClient.csproj | 2 + .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 10 ++--- .../EntityFrameworkInstrumentation.cs | 2 +- .../EntityFrameworkInstrumentationOptions.cs | 4 +- .../EntityFrameworkDiagnosticListener.cs | 26 ++++++------- ...tityFrameworkInstrumentationEventSource.cs | 6 --- ...Instrumentation.EntityFrameworkCore.csproj | 1 - .../TracerProviderBuilderExtensions.cs | 6 +-- .../OpenTelemetry.Instrumentation.Owin.csproj | 2 +- .../QuartzDiagnosticListener.cs | 9 +++-- ...penTelemetry.Instrumentation.Quartz.csproj | 1 + src/Shared/DiagnosticSourceListener.cs | 8 ++-- src/Shared/DiagnosticSourceSubscriber.cs | 10 ++--- src/Shared/ListenerHandler.cs | 13 ++++--- .../EntityFrameworkDiagnosticListenerTests.cs | 38 ++++++++----------- ...mentation.EntityFrameworkCore.Tests.csproj | 1 - 19 files changed, 76 insertions(+), 74 deletions(-) diff --git a/build/Common.props b/build/Common.props index e57d37e80c..6505e4712b 100644 --- a/build/Common.props +++ b/build/Common.props @@ -59,14 +59,20 @@ - + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 75a2803600..37d54912ba 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -24,6 +24,7 @@ using System.Text; using System.Text.Json; using System.Text.RegularExpressions; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; @@ -67,6 +68,7 @@ public override void OnStartActivity(Activity activity, object payload) return; } + Guard.ThrowIfNull(activity); if (activity.IsAllDataRequested) { var uri = this.uriFetcher.Fetch(payload); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 63005a2e97..86bf2da20b 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -9,6 +9,8 @@ true true true + true + true disable diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 79d38853ff..fdae0869f7 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,14 +1,14 @@ OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EntityFrameworkInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.Filter.get -> System.Func? OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.get -> bool OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.get -> bool OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.SetDbStatementForText.set -> void -OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.get -> System.Action +OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.get -> System.Action? OpenTelemetry.Instrumentation.EntityFrameworkCore.EntityFrameworkInstrumentationOptions.EnrichWithIDbCommand.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddEntityFrameworkCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 30181f72b1..2b544c9c03 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -23,7 +23,7 @@ internal class EntityFrameworkInstrumentation : IDisposable { private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions options) + public EntityFrameworkInstrumentation(EntityFrameworkInstrumentationOptions? options) { this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( name => new EntityFrameworkDiagnosticListener(name, options), diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 82a7f36cd1..264bbd20c8 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -43,7 +43,7 @@ public class EntityFrameworkInstrumentationOptions /// : the activity being enriched. /// : db command to allow access to command. /// - public Action EnrichWithIDbCommand { get; set; } + public Action? EnrichWithIDbCommand { get; set; } /// /// Gets or sets a filter function that determines whether or not to @@ -64,5 +64,5 @@ public class EntityFrameworkInstrumentationOptions /// /// /// - public Func Filter { get; set; } + public Func? Filter { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 0e9cc1e622..5a1ba2f6bb 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -40,23 +40,23 @@ internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler private static readonly Version Version = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Version; #pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before SqlClientActivitySource otherwise null ref exception is thrown. - internal static readonly ActivitySource SqlClientActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource SqlClientActivitySource = new(ActivitySourceName, Version.ToString()); #pragma warning restore SA1202 // Elements should be ordered by access - private readonly PropertyFetcher commandFetcher = new PropertyFetcher("Command"); - private readonly PropertyFetcher connectionFetcher = new PropertyFetcher("Connection"); - private readonly PropertyFetcher dbContextFetcher = new PropertyFetcher("Context"); - private readonly PropertyFetcher dbContextDatabaseFetcher = new PropertyFetcher("Database"); - private readonly PropertyFetcher providerNameFetcher = new PropertyFetcher("ProviderName"); - private readonly PropertyFetcher dataSourceFetcher = new PropertyFetcher("DataSource"); - private readonly PropertyFetcher databaseFetcher = new PropertyFetcher("Database"); - private readonly PropertyFetcher commandTypeFetcher = new PropertyFetcher("CommandType"); - private readonly PropertyFetcher commandTextFetcher = new PropertyFetcher("CommandText"); - private readonly PropertyFetcher exceptionFetcher = new PropertyFetcher("Exception"); + private readonly PropertyFetcher commandFetcher = new("Command"); + private readonly PropertyFetcher connectionFetcher = new("Connection"); + private readonly PropertyFetcher dbContextFetcher = new("Context"); + private readonly PropertyFetcher dbContextDatabaseFetcher = new("Database"); + private readonly PropertyFetcher providerNameFetcher = new("ProviderName"); + private readonly PropertyFetcher dataSourceFetcher = new("DataSource"); + private readonly PropertyFetcher databaseFetcher = new("Database"); + private readonly PropertyFetcher commandTypeFetcher = new("CommandType"); + private readonly PropertyFetcher commandTextFetcher = new("CommandText"); + private readonly PropertyFetcher exceptionFetcher = new("Exception"); private readonly EntityFrameworkInstrumentationOptions options; - public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstrumentationOptions options) + public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstrumentationOptions? options) : base(sourceName) { this.options = options ?? new EntityFrameworkInstrumentationOptions(); @@ -64,7 +64,7 @@ public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstr public override bool SupportsNullActivity => true; - public override void OnCustom(string name, Activity activity, object payload) + public override void OnCustom(string name, Activity? activity, object? payload) { switch (name) { diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index bb4960791e..b132094cf6 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -70,12 +70,6 @@ public void NullPayload(string handlerName, string eventName) this.WriteEvent(3, handlerName, eventName); } - [Event(4, Message = "Payload is invalid in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] - public void InvalidPayload(string handlerName, string eventName) - { - this.WriteEvent(4, handlerName, eventName); - } - [Event(5, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] public void EnrichmentException(string eventName, string exception) { diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index a15af04bf1..b603317770 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -7,7 +7,6 @@ true true true - disable diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 2240cb090c..3a429a0bca 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -45,7 +45,7 @@ public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( this TracerProviderBuilder builder, - Action configure) => + Action? configure) => AddEntityFrameworkCoreInstrumentation(builder, name: null, configure); /// @@ -57,8 +57,8 @@ public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddEntityFrameworkCoreInstrumentation( this TracerProviderBuilder builder, - string name, - Action configure) + string? name, + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 87bf615700..dc1911a21c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -5,12 +5,12 @@ OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- + true disable - diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 896c246e45..b8eb5a1c64 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -42,8 +42,9 @@ public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions this.options = options; } - public override void OnStartActivity(Activity activity, object payload) + public override void OnStartActivity(Activity? activity, object? payload) { + Guard.ThrowIfNull(activity); if (activity.IsAllDataRequested) { if (!this.options.TracedOperations.Contains(activity.OperationName)) @@ -73,8 +74,9 @@ public override void OnStartActivity(Activity activity, object payload) } } - public override void OnStopActivity(Activity activity, object payload) + public override void OnStopActivity(Activity? activity, object? payload) { + Guard.ThrowIfNull(activity); if (activity.IsAllDataRequested) { try @@ -92,8 +94,9 @@ public override void OnStopActivity(Activity activity, object payload) } } - public override void OnException(Activity activity, object payload) + public override void OnException(Activity? activity, object? payload) { + Guard.ThrowIfNull(activity); if (activity.IsAllDataRequested) { var exc = payload as Exception; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 49c2b03d7d..2f957f3a2a 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -7,6 +7,7 @@ netstandard2.0 true true + true diff --git a/src/Shared/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs index 3c16815cc7..7facd8d529 100644 --- a/src/Shared/DiagnosticSourceListener.cs +++ b/src/Shared/DiagnosticSourceListener.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#nullable disable +#nullable enable #pragma warning disable IDE0005 // Using directive is unnecessary. using System; @@ -25,7 +25,7 @@ namespace OpenTelemetry.Instrumentation; -internal sealed class DiagnosticSourceListener : IObserver> +internal sealed class DiagnosticSourceListener : IObserver> { private readonly ListenerHandler handler; @@ -47,7 +47,7 @@ public void OnError(Exception error) { } - public void OnNext(KeyValuePair value) + public void OnNext(KeyValuePair value) { if (!this.handler.SupportsNullActivity && Activity.Current == null) { @@ -75,7 +75,7 @@ public void OnNext(KeyValuePair value) } catch (Exception ex) { - this.logUnknownException?.Invoke(this.handler?.SourceName, value.Key, ex); + this.logUnknownException?.Invoke(this.handler.SourceName, value.Key, ex); } } } diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index c0d931652f..22ff829380 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -14,7 +14,7 @@ // limitations under the License. // -#nullable disable +#nullable enable #pragma warning disable IDE0005 // Using directive is unnecessary. using System; @@ -31,14 +31,14 @@ internal sealed class DiagnosticSourceSubscriber : IDisposable, IObserver listenerSubscriptions; private readonly Func handlerFactory; private readonly Func diagnosticSourceFilter; - private readonly Func isEnabledFilter; + private readonly Func? isEnabledFilter; private readonly Action logUnknownException; private long disposed; - private IDisposable allSourcesSubscription; + private IDisposable? allSourcesSubscription; public DiagnosticSourceSubscriber( ListenerHandler handler, - Func isEnabledFilter, + Func isEnabledFilter, Action logUnknownException) : this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter, logUnknownException) { @@ -47,7 +47,7 @@ public DiagnosticSourceSubscriber( public DiagnosticSourceSubscriber( Func handlerFactory, Func diagnosticSourceFilter, - Func isEnabledFilter, + Func? isEnabledFilter, Action logUnknownException) { Guard.ThrowIfNull(handlerFactory); diff --git a/src/Shared/ListenerHandler.cs b/src/Shared/ListenerHandler.cs index e19a5ff7ab..ff96f005f7 100644 --- a/src/Shared/ListenerHandler.cs +++ b/src/Shared/ListenerHandler.cs @@ -13,6 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. // + +#nullable enable + using System.Diagnostics; namespace OpenTelemetry.Instrumentation; @@ -26,7 +29,7 @@ internal abstract class ListenerHandler /// Initializes a new instance of the class. /// /// The name of the . - public ListenerHandler(string sourceName) + protected ListenerHandler(string sourceName) { this.SourceName = sourceName; } @@ -46,7 +49,7 @@ public ListenerHandler(string sourceName) /// /// The to be started. /// An object that represent the value being passed as a payload for the event. - public virtual void OnStartActivity(Activity activity, object payload) + public virtual void OnStartActivity(Activity? activity, object? payload) { } @@ -55,7 +58,7 @@ public virtual void OnStartActivity(Activity activity, object payload) /// /// The to be stopped. /// An object that represent the value being passed as a payload for the event. - public virtual void OnStopActivity(Activity activity, object payload) + public virtual void OnStopActivity(Activity? activity, object? payload) { } @@ -64,7 +67,7 @@ public virtual void OnStopActivity(Activity activity, object payload) /// /// The . /// An object that represent the value being passed as a payload for the event. - public virtual void OnException(Activity activity, object payload) + public virtual void OnException(Activity? activity, object? payload) { } @@ -74,7 +77,7 @@ public virtual void OnException(Activity activity, object payload) /// Custom name. /// The to be processed. /// An object that represent the value being passed as a payload for the event. - public virtual void OnCustom(string name, Activity activity, object payload) + public virtual void OnCustom(string name, Activity? activity, object? payload) { } } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index bd8daf0c1f..fe1f86cbe4 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -40,7 +40,7 @@ public EntityFrameworkDiagnosticListenerTests() .UseSqlite(CreateInMemoryDatabase()) .Options; - this.connection = RelationalOptionsExtension.Extract(this.contextOptions).Connection; + this.connection = RelationalOptionsExtension.Extract(this.contextOptions).Connection!; this.Seed(); } @@ -121,6 +121,7 @@ public void EntityFrameworkContextExceptionEventsInstrumentedTest() } catch { + // intentional empty catch } } @@ -139,10 +140,7 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByDbCommand() .AddProcessor(activityProcessor.Object) .AddEntityFrameworkCoreInstrumentation(options => { - options.Filter = (providerName, command) => - { - return !command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); - }; + options.Filter = (_, command) => !command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); }).Build(); using (var context = new ItemsContext(this.contextOptions)) @@ -166,10 +164,7 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByDbCommand() .AddProcessor(activityProcessor.Object) .AddEntityFrameworkCoreInstrumentation(options => { - options.Filter = (providerName, command) => - { - return command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); - }; + options.Filter = (_, command) => command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); }).Build(); using (var context = new ItemsContext(this.contextOptions)) @@ -212,10 +207,7 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByProviderName(st .AddProcessor(activityProcessor.Object) .AddEntityFrameworkCoreInstrumentation(options => { - options.Filter = (providerName, command) => - { - return providerName.Equals(provider, StringComparison.OrdinalIgnoreCase); - }; + options.Filter = (providerName, _) => providerName != null && providerName.Equals(provider, StringComparison.OrdinalIgnoreCase); }).Build(); using (var context = new ItemsContext(this.contextOptions)) @@ -239,10 +231,7 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByProviderName() .AddProcessor(activityProcessor.Object) .AddEntityFrameworkCoreInstrumentation(options => { - options.Filter = (providerName, command) => - { - return providerName.Equals("Microsoft.EntityFrameworkCore.Sqlite", StringComparison.OrdinalIgnoreCase); - }; + options.Filter = (providerName, _) => providerName != null && providerName.Equals("Microsoft.EntityFrameworkCore.Sqlite", StringComparison.OrdinalIgnoreCase); }).Build(); using (var context = new ItemsContext(this.contextOptions)) @@ -268,7 +257,7 @@ private static DbConnection CreateInMemoryDatabase() return connection; } - private static void VerifyActivityData(Activity activity, bool isError = false, string altDisplayName = null) + private static void VerifyActivityData(Activity activity, bool isError = false, string? altDisplayName = null) { Assert.Equal(altDisplayName ?? "main", activity.DisplayName); @@ -301,11 +290,11 @@ private void Seed() context.Database.EnsureDeleted(); context.Database.EnsureCreated(); - var one = new Item { Name = "ItemOne" }; + var one = new Item("ItemOne"); - var two = new Item { Name = "ItemTwo" }; + var two = new Item("ItemTwo"); - var three = new Item { Name = "ItemThree" }; + var three = new Item("ItemThree"); context.AddRange(one, two, three); @@ -314,9 +303,12 @@ private void Seed() private class Item { - public int Id { get; set; } + public Item(string name) + { + this.Name = name; + } - public string Name { get; set; } + public string Name { get; } } private class ItemsContext : DbContext diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index ac4831069b..c2143ac23b 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -3,7 +3,6 @@ Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation net7.0;net6.0 - disable From 157412c482ff857449b8c02978bc42256f30fd66 Mon Sep 17 00:00:00 2001 From: Chris Redekop <32752154+repl-chris@users.noreply.github.com> Date: Fri, 3 Nov 2023 19:46:42 -0600 Subject: [PATCH 0869/1499] Nullable for WCF instrumentation (#1354) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 48 ++++++------- .../netstandard2.0/PublicAPI.Shipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 30 ++++----- .../Implementation/ActionMetadata.cs | 8 ++- .../AspNetParentSpanCorrector.cs | 23 ++++--- .../ClientChannelInstrumentation.cs | 24 +++---- .../HttpRequestMessagePropertyWrapper.cs | 31 +++++---- .../InstrumentedChannelFactory.cs | 7 +- .../InstrumentedDuplexChannel.cs | 49 +++++++++++--- .../InstrumentedRequestChannel.cs | 23 +++++-- .../Implementation/RequestTelemetryState.cs | 4 +- .../RequestTelemetryStateTracker.cs | 8 +-- .../TelemetryClientMessageInspector.cs | 10 ++- .../TelemetryContextMessageProperty.cs | 5 ++ .../TelemetryDispatchMessageInspector.cs | 16 ++--- .../Implementation/TelemetryMessageHeader.cs | 2 +- .../TelemetryPropagationReader.cs | 10 +-- .../TelemetryPropagationWriter.cs | 2 +- .../WcfInstrumentationActivitySource.cs | 4 +- .../WcfInstrumentationEventSource.cs | 4 +- .../OpenTelemetry.Instrumentation.Wcf.csproj | 1 - .../TelemetryEndpointBehavior.cs | 16 ++--- .../TracerProviderBuilderExtensions.cs | 2 +- .../WcfInstrumentationOptions.cs | 6 +- .../AspNetParentSpanCorrectorTests.netfx.cs | 2 +- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 1 - .../TelemetryBindingElementForHttpTests.cs | 65 +++++++++--------- ...elemetryBindingElementForTcpTests.netfx.cs | 67 +++++++++---------- ...InspectorForOneWayOperationsTests.netfx.cs | 25 ++++--- ...etryDispatchMessageInspectorTests.netfx.cs | 35 +++++----- .../TelemetryPropagationTests.netfx.cs | 29 ++++---- ...DownstreamInstrumentationBindingElement.cs | 3 +- .../Tools/DownstreamInstrumentationChannel.cs | 11 +-- ...DownstreamInstrumentationChannelFactory.cs | 9 +-- .../WCF/Service.netfx.cs | 18 ++--- .../WCF/ServiceRequest.cs | 5 ++ .../WCF/ServiceResponse.cs | 5 ++ 38 files changed, 336 insertions(+), 274 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt index 40e7077997..8b2bbfdba2 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,35 +1,35 @@ -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveRequest = "AfterReceiveRequest" -> string -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendReply = "BeforeSendReply" -> string -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string! +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveRequest = "AfterReceiveRequest" -> string! +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendReply = "BeforeSendReply" -> string! +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string! OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.ClientRuntime! clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.DispatchRuntime! dispatchRuntime) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.TelemetryContractBehaviorAttribute() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.ClientRuntime! clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher! endpointDispatcher) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.TelemetryEndpointBehavior() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint! endpoint) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.TelemetryEndpointBehaviorExtensionElement() -> void OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior -OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceDescription! serviceDescription, System.ServiceModel.ServiceHostBase! serviceHostBase, System.Collections.ObjectModel.Collection! endpoints, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceDescription! serviceDescription, System.ServiceModel.ServiceHostBase! serviceHostBase) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.TelemetryServiceBehavior() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.Validate(System.ServiceModel.Description.ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.Validate(System.ServiceModel.Description.ServiceDescription! serviceDescription, System.ServiceModel.ServiceHostBase! serviceHostBase) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.TelemetryServiceBehaviorExtensionElement() -> void OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.get -> bool OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.set -> void @@ -37,9 +37,9 @@ OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamIn OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.WcfInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.BehaviorType.get -> System.Type -override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.CreateBehavior() -> object -override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.BehaviorType.get -> System.Type -override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.CreateBehavior() -> object -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.BehaviorType.get -> System.Type! +override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.CreateBehavior() -> object! +override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.BehaviorType.get -> System.Type! +override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.CreateBehavior() -> object! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index ae0ce795bf..2d11286dca 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,24 +1,24 @@ -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string! +const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string! OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.ClientRuntime! clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.DispatchRuntime! dispatchRuntime) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.TelemetryContractBehaviorAttribute() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription contractDescription, System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.ClientRuntime! clientRuntime) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher! endpointDispatcher) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.TelemetryEndpointBehavior() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint endpoint) -> void +OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint! endpoint) -> void OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.get -> bool OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.set -> void @@ -26,5 +26,5 @@ OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamIn OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.WcfInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs index e4bc90e78b..91670619e8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs @@ -18,7 +18,13 @@ namespace OpenTelemetry.Instrumentation.Wcf; internal sealed class ActionMetadata { - public string ContractName { get; set; } + public ActionMetadata(string? contractName, string operationName) + { + this.ContractName = contractName; + this.OperationName = operationName; + } + + public string? ContractName { get; set; } public string OperationName { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs index 99c9a8e9e3..c4f1d0c8ea 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs @@ -40,7 +40,7 @@ internal static class AspNetParentSpanCorrector private const string TelemetryHttpModuleTypeName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule"; private const string TelemetryHttpModuleOptionsTypeName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule"; - private static readonly ReflectedInfo ReflectedValues = Initialize(); + private static readonly ReflectedInfo? ReflectedValues = Initialize(); private static readonly PropertyFetcher RequestFetcher = new PropertyFetcher("Request"); private static readonly PropertyFetcher HeadersFetcher = new PropertyFetcher("Headers"); private static bool isRegistered; @@ -59,7 +59,7 @@ private static void OnRequestStarted(Activity activity, object context) var request = RequestFetcher.Fetch(context); var headers = HeadersFetcher.Fetch(request); - ReflectedValues.SetHeadersReadOnly(headers, false); + ReflectedValues!.SetHeadersReadOnly(headers, false); try { ReflectedValues.GetTelemetryHttpModulePropagator().Inject( @@ -73,7 +73,7 @@ private static void OnRequestStarted(Activity activity, object context) } } - private static ReflectedInfo Initialize() + private static ReflectedInfo? Initialize() { try { @@ -85,12 +85,7 @@ private static ReflectedInfo Initialize() var setHeadersReadOnly = (Action)isReadOnlyProp.SetMethod.CreateDelegate(typeof(Action)); - return new ReflectedInfo - { - SetHeadersReadOnly = setHeadersReadOnly, - GetTelemetryHttpModulePropagator = GenerateGetPropagatorLambda(), - SubscribeToOnRequestStartedCallback = GenerateSubscribeLambda(), - }; + return new ReflectedInfo(setHeadersReadOnly, GenerateGetPropagatorLambda(), GenerateSubscribeLambda()); } catch (Exception ex) { @@ -146,6 +141,16 @@ private sealed class ReflectedInfo public Action SetHeadersReadOnly; public Func GetTelemetryHttpModulePropagator; public Func SubscribeToOnRequestStartedCallback; + + public ReflectedInfo( + Action setHeadersReadOnly, + Func getTelemetryHttpModulePropagator, + Func subscribeToOnRequestStartedCallback) + { + this.SetHeadersReadOnly = setHeadersReadOnly; + this.GetTelemetryHttpModulePropagator = getTelemetryHttpModulePropagator; + this.SubscribeToOnRequestStartedCallback = subscribeToOnRequestStartedCallback; + } } } #endif diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index 8ad977925d..8c4668069a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -25,17 +25,17 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; internal static class ClientChannelInstrumentation { - public static RequestTelemetryState BeforeSendRequest(Message request, Uri remoteChannelAddress) + public static RequestTelemetryState BeforeSendRequest(Message request, Uri? remoteChannelAddress) { if (!ShouldInstrumentRequest(request)) { return new RequestTelemetryState { SuppressionScope = SuppressDownstreamInstrumentation() }; } - Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + Activity? activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( WcfInstrumentationActivitySource.OutgoingRequestActivityName, ActivityKind.Client); - IDisposable suppressionScope = SuppressDownstreamInstrumentation(); + IDisposable? suppressionScope = SuppressDownstreamInstrumentation(); if (activity != null) { @@ -59,7 +59,7 @@ public static RequestTelemetryState BeforeSendRequest(Message request, Uri remot activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); activity.SetTag(WcfInstrumentationConstants.RpcMethodTag, actionMetadata.OperationName); - if (WcfInstrumentationActivitySource.Options.SetSoapMessageVersion) + if (WcfInstrumentationActivitySource.Options!.SetSoapMessageVersion) { activity.SetTag(WcfInstrumentationConstants.SoapMessageVersionTag, request.Version.ToString()); } @@ -96,7 +96,7 @@ public static RequestTelemetryState BeforeSendRequest(Message request, Uri remot }; } - public static void AfterRequestCompleted(Message reply, RequestTelemetryState state) + public static void AfterRequestCompleted(Message? reply, RequestTelemetryState state) { Guard.ThrowIfNull(state); @@ -116,7 +116,7 @@ public static void AfterRequestCompleted(Message reply, RequestTelemetryState st activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); try { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveReply, reply); + WcfInstrumentationActivitySource.Options!.Enrich?.Invoke(activity, WcfEnrichEventNames.AfterReceiveReply, reply); } catch (Exception ex) { @@ -129,7 +129,7 @@ public static void AfterRequestCompleted(Message reply, RequestTelemetryState st } } - private static IDisposable SuppressDownstreamInstrumentation() + private static IDisposable? SuppressDownstreamInstrumentation() { return WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false ? SuppressInstrumentationScope.Begin() @@ -138,7 +138,7 @@ private static IDisposable SuppressDownstreamInstrumentation() private static ActionMetadata GetActionMetadata(Message request, string action) { - ActionMetadata actionMetadata = null; + ActionMetadata? actionMetadata = null; if (request.Properties.TryGetValue(TelemetryContextMessageProperty.Name, out object telemetryContextProperty)) { var actionMappings = (telemetryContextProperty as TelemetryContextMessageProperty)?.ActionMappings; @@ -148,11 +148,9 @@ private static ActionMetadata GetActionMetadata(Message request, string action) } } - return actionMetadata != null ? actionMetadata : new ActionMetadata - { - ContractName = null, - OperationName = action, - }; + return actionMetadata != null ? actionMetadata : new ActionMetadata( + contractName: null, + operationName: action); } private static bool ShouldInstrumentRequest(Message request) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs index 2205acbae2..e14a06c258 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs @@ -30,7 +30,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; /// internal static class HttpRequestMessagePropertyWrapper { - private static readonly ReflectedInfo ReflectedValues = Initialize(); + private static readonly ReflectedInfo? ReflectedValues = Initialize(); public static bool IsHttpFunctionalityEnabled => ReflectedValues != null; @@ -39,26 +39,26 @@ public static string Name get { AssertHttpEnabled(); - return ReflectedValues.Name; + return ReflectedValues!.Name; } } public static object CreateNew() { AssertHttpEnabled(); - return Activator.CreateInstance(ReflectedValues.Type); + return Activator.CreateInstance(ReflectedValues!.Type); } public static WebHeaderCollection GetHeaders(object httpRequestMessageProperty) { AssertHttpEnabled(); AssertIsFrameworkMessageProperty(httpRequestMessageProperty); - return ReflectedValues.HeadersFetcher.Fetch(httpRequestMessageProperty); + return ReflectedValues!.HeadersFetcher.Fetch(httpRequestMessageProperty); } - private static ReflectedInfo Initialize() + private static ReflectedInfo? Initialize() { - Type type = null; + Type? type = null; try { type = Type.GetType( @@ -77,12 +77,10 @@ private static ReflectedInfo Initialize() throw new NotSupportedException("HttpRequestMessageProperty.Name property not found"); } - return new ReflectedInfo - { - Type = type, - Name = (string)nameProp.GetValue(null), - HeadersFetcher = new PropertyFetcher("Headers"), - }; + return new ReflectedInfo( + type: type, + name: (string)nameProp.GetValue(null), + headersFetcher: new PropertyFetcher("Headers")); } catch (Exception ex) { @@ -105,7 +103,7 @@ private static void AssertHttpEnabled() private static void AssertIsFrameworkMessageProperty(object httpRequestMessageProperty) { AssertHttpEnabled(); - if (httpRequestMessageProperty == null || !httpRequestMessageProperty.GetType().Equals(ReflectedValues.Type)) + if (httpRequestMessageProperty == null || !httpRequestMessageProperty.GetType().Equals(ReflectedValues!.Type)) { throw new ArgumentException("Object must be of type HttpRequestMessageProperty"); } @@ -116,5 +114,12 @@ private sealed class ReflectedInfo public Type Type; public string Name; public PropertyFetcher HeadersFetcher; + + public ReflectedInfo(Type type, string name, PropertyFetcher headersFetcher) + { + this.Type = type; + this.Name = name; + this.HeadersFetcher = headersFetcher; + } } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs index 2985c3a763..e45fe3e832 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs @@ -17,6 +17,7 @@ using System; using System.ServiceModel; using System.ServiceModel.Channels; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf.Implementation; @@ -42,14 +43,16 @@ TChannel IChannelFactory.CreateChannel(EndpointAddress to) private TChannel WrapChannel(TChannel innerChannel) { + Guard.ThrowIfNull(innerChannel); + if (typeof(TChannel) == typeof(IRequestChannel) || typeof(TChannel) == typeof(IRequestSessionChannel)) { - return (TChannel)(IRequestChannel)new InstrumentedRequestChannel((IRequestChannel)innerChannel); + return (TChannel)(IRequestChannel)new InstrumentedRequestChannel((IRequestChannel)innerChannel!); } if (typeof(TChannel) == typeof(IDuplexChannel) || typeof(TChannel) == typeof(IDuplexSessionChannel)) { - return (TChannel)(IDuplexChannel)new InstrumentedDuplexChannel((IDuplexChannel)innerChannel, this.binding.SendTimeout); + return (TChannel)(IDuplexChannel)new InstrumentedDuplexChannel((IDuplexChannel)innerChannel!, this.binding.SendTimeout); } throw new NotImplementedException(); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs index fc6886bed1..6ff53917c6 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs @@ -18,6 +18,7 @@ using System.ServiceModel; using System.ServiceModel.Channels; using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf.Implementation; @@ -41,26 +42,38 @@ public InstrumentedDuplexChannel(IDuplexChannel inner, TimeSpan telemetryTimeout public void Send(Message message) { + Guard.ThrowIfNull(message); + this.SendInternal(message, this.telemetryTimeout, _ => this.Inner.Send(message)); } public void Send(Message message, TimeSpan timeout) { + Guard.ThrowIfNull(message); + this.SendInternal(message, timeout, _ => this.Inner.Send(message, timeout)); } - public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state) + public IAsyncResult BeginSend(Message message, AsyncCallback callback, object? state) { + Guard.ThrowIfNull(message); + Guard.ThrowIfNull(callback); + return this.SendInternal(message, this.telemetryTimeout, (cb, s) => this.Inner.BeginSend(message, cb, s), callback, state); } - public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state) + public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object? state) { + Guard.ThrowIfNull(message); + Guard.ThrowIfNull(callback); + return this.SendInternal(message, timeout, (cb, s) => this.Inner.BeginSend(message, timeout, cb, s), callback, state); } public void EndSend(IAsyncResult result) { + Guard.ThrowIfNull(result); + var asyncResult = (AsyncResultWithTelemetryState)result; try { @@ -87,18 +100,24 @@ public Message Receive(TimeSpan timeout) return message; } - public IAsyncResult BeginReceive(AsyncCallback callback, object state) + public IAsyncResult BeginReceive(AsyncCallback callback, object? state) { + Guard.ThrowIfNull(callback); + return this.Inner.BeginReceive(callback, state); } - public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state) + public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object? state) { + Guard.ThrowIfNull(callback); + return this.Inner.BeginReceive(timeout, callback, state); } public Message EndReceive(IAsyncResult result) { + Guard.ThrowIfNull(result); + var message = this.Inner.EndReceive(result); HandleReceivedMessage(message); return message; @@ -111,13 +130,17 @@ public bool TryReceive(TimeSpan timeout, out Message message) return returnValue; } - public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state) + public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object? state) { + Guard.ThrowIfNull(callback); + return this.Inner.BeginTryReceive(timeout, callback, state); } public bool EndTryReceive(IAsyncResult result, out Message message) { + Guard.ThrowIfNull(result); + var returnValue = this.Inner.EndTryReceive(result, out message); HandleReceivedMessage(message); return returnValue; @@ -128,13 +151,17 @@ public bool WaitForMessage(TimeSpan timeout) return this.Inner.WaitForMessage(timeout); } - public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state) + public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object? state) { + Guard.ThrowIfNull(callback); + return this.Inner.BeginWaitForMessage(timeout, callback, state); } public bool EndWaitForMessage(IAsyncResult result) { + Guard.ThrowIfNull(result); + return this.Inner.EndWaitForMessage(result); } @@ -152,20 +179,20 @@ private static void OnTelemetryStateTimedOut(RequestTelemetryState telemetryStat ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); } - private IAsyncResult SendInternal(Message message, TimeSpan timeout, Func executeSend, AsyncCallback callback, object state) + private IAsyncResult SendInternal(Message message, TimeSpan timeout, Func executeSend, AsyncCallback callback, object? state) { - IAsyncResult result = null; + IAsyncResult? result = null; this.SendInternal(message, timeout, telemetryState => { var asyncCallback = AsyncResultWithTelemetryState.GetAsyncCallback(callback, telemetryState); result = new AsyncResultWithTelemetryState(executeSend(asyncCallback, state), telemetryState); }); - return result; + return result!; } private void SendInternal(Message message, TimeSpan timeout, Action executeSend) { - RequestTelemetryState telemetryState = null; + RequestTelemetryState? telemetryState = null; ContextCallback executeInChildContext = _ => { telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, this.RemoteAddress?.Uri); @@ -179,7 +206,7 @@ private void SendInternal(Message message, TimeSpan timeout, Action this.Inner.BeginRequest(message, timeout, cb, s), callback, state); } - IAsyncResult IRequestChannel.BeginRequest(Message message, AsyncCallback callback, object state) + IAsyncResult IRequestChannel.BeginRequest(Message message, AsyncCallback callback, object? state) { + Guard.ThrowIfNull(message); + Guard.ThrowIfNull(callback); + return this.InternalBeginRequest(message, (cb, s) => this.Inner.BeginRequest(message, cb, s), callback, state); } Message IRequestChannel.EndRequest(IAsyncResult result) { + Guard.ThrowIfNull(result); + var asyncResult = (AsyncResultWithTelemetryState)result; Message reply; try @@ -98,9 +111,9 @@ Message IRequestChannel.EndRequest(IAsyncResult result) return reply; } - private IAsyncResult InternalBeginRequest(Message message, Func beginRequestDelegate, AsyncCallback callback, object state) + private IAsyncResult InternalBeginRequest(Message message, Func beginRequestDelegate, AsyncCallback callback, object? state) { - IAsyncResult result = null; + IAsyncResult? result = null; ContextCallback executeInChildContext = _ => { var telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, ((IRequestChannel)this).RemoteAddress?.Uri); @@ -109,6 +122,6 @@ private IAsyncResult InternalBeginRequest(Message message, Func> timedOutEntries = null; + List>? timedOutEntries = null; lock (Sync) { var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - EntryTimeoutProperties nextToExpire = null; + EntryTimeoutProperties? nextToExpire = null; foreach (var entryTimeoutProps in TimeoutQueue) { if (entryTimeoutProps.ExpiresAt <= now) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs index 8b27e9c36e..ded05f325d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs @@ -37,19 +37,17 @@ internal TelemetryClientMessageInspector(IDictionary act } /// - public object BeforeSendRequest(ref Message request, IClientChannel channel) + public object? BeforeSendRequest(ref Message request, IClientChannel channel) { Guard.ThrowIfNull(request); - request.Properties.Add(TelemetryContextMessageProperty.Name, new TelemetryContextMessageProperty() - { - ActionMappings = this.actionMappings, - }); + request.Properties.Add(TelemetryContextMessageProperty.Name, new TelemetryContextMessageProperty( + actionMappings: this.actionMappings)); return null; } /// - public void AfterReceiveReply(ref Message reply, object correlationState) + public void AfterReceiveReply(ref Message reply, object? correlationState) { } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs index df4d4a4006..538f0da7f4 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs @@ -22,5 +22,10 @@ internal sealed class TelemetryContextMessageProperty { public const string Name = "OpenTelemetry.Instrumentation.Wcf.Implementation.TelemetryContextMessageProperty"; + public TelemetryContextMessageProperty(IDictionary actionMappings) + { + this.ActionMappings = actionMappings; + } + public IDictionary ActionMappings { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs index b3a1043fab..a26ba69720 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs @@ -42,7 +42,7 @@ internal TelemetryDispatchMessageInspector(IDictionary a } /// - public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) + public object? AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { Guard.ThrowIfNull(request); Guard.ThrowIfNull(channel); @@ -64,7 +64,7 @@ public object AfterReceiveRequest(ref Message request, IClientChannel channel, I var textMapPropagator = Propagators.DefaultTextMapPropagator; var ctx = textMapPropagator.Extract(default, request, WcfInstrumentationActivitySource.MessageHeaderValuesGetter); - Activity activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + Activity? activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( WcfInstrumentationActivitySource.IncomingRequestActivityName, ActivityKind.Server, ctx.ActivityContext); @@ -88,11 +88,9 @@ public object AfterReceiveRequest(ref Message request, IClientChannel channel, I if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) { - actionMetadata = new ActionMetadata - { - ContractName = null, - OperationName = action, - }; + actionMetadata = new ActionMetadata( + contractName: null, + operationName: action); } activity.SetTag(WcfInstrumentationConstants.RpcServiceTag, actionMetadata.ContractName); @@ -132,7 +130,7 @@ public object AfterReceiveRequest(ref Message request, IClientChannel channel, I } /// - public void BeforeSendReply(ref Message reply, object correlationState) + public void BeforeSendReply(ref Message reply, object? correlationState) { if (correlationState is Activity activity) { @@ -146,7 +144,7 @@ public void BeforeSendReply(ref Message reply, object correlationState) activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); try { - WcfInstrumentationActivitySource.Options.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendReply, reply); + WcfInstrumentationActivitySource.Options!.Enrich?.Invoke(activity, WcfEnrichEventNames.BeforeSendReply, reply); } catch (Exception ex) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs index 2abcbd5955..0d2cd08e72 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs @@ -42,7 +42,7 @@ public static TelemetryMessageHeader CreateHeader(string name, string value) return new TelemetryMessageHeader(name, value); } - public static TelemetryMessageHeader FindHeader(string name, MessageHeaders allHeaders) + public static TelemetryMessageHeader? FindHeader(string name, MessageHeaders allHeaders) { try { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs index c537e8f453..fbc0101e06 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs @@ -26,7 +26,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; /// internal static class TelemetryPropagationReader { - private static readonly Func> DefaultReader = Compose(HttpRequestHeaders, SoapMessageHeaders); + private static readonly Func?> DefaultReader = Compose(HttpRequestHeaders, SoapMessageHeaders); /// /// Reads the values from the SOAP message headers. If the message is not a SOAP message it returns null. @@ -34,7 +34,7 @@ internal static class TelemetryPropagationReader /// The incoming to read trace context from. /// The header name being requested. /// An enumerable of all the values for the requested header, or null if the requested header was not present on the request. - public static IEnumerable SoapMessageHeaders(Message request, string name) + public static IEnumerable? SoapMessageHeaders(Message request, string name) { Guard.ThrowIfNull(request); Guard.ThrowIfNull(name); @@ -54,7 +54,7 @@ public static IEnumerable SoapMessageHeaders(Message request, string nam /// The incoming to read trace context from. /// The header name being requested. /// An enumerable of all the values for the requested header, or null if the requested header was not present on the request. - public static IEnumerable HttpRequestHeaders(Message request, string name) + public static IEnumerable? HttpRequestHeaders(Message request, string name) { Guard.ThrowIfNull(request); Guard.ThrowIfNull(name); @@ -74,7 +74,7 @@ public static IEnumerable HttpRequestHeaders(Message request, string nam /// The incoming to read trace context from. /// The header name being requested. /// An enumerable of all the values for the requested header, or null if the requested header was not present on the request. - public static IEnumerable Default(Message request, string name) + public static IEnumerable? Default(Message request, string name) { return DefaultReader(request, name); } @@ -85,7 +85,7 @@ public static IEnumerable Default(Message request, string name) /// /// The callbacks to compose into a single callback. /// The composed callback. - public static Func> Compose(params Func>[] callbacks) + public static Func?> Compose(params Func?>[] callbacks) { Guard.ThrowIfNull(callbacks); Array.ForEach(callbacks, cb => Guard.ThrowIfNull(cb)); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs index 63772789bf..3da6e48686 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs @@ -83,7 +83,7 @@ public static void HttpRequestHeaders(Message request, string name, string value public static void Default(Message request, string name, string value) { SoapMessageHeaders(request, name, value); - if (WcfInstrumentationActivitySource.Options.SuppressDownstreamInstrumentation) + if (WcfInstrumentationActivitySource.Options?.SuppressDownstreamInstrumentation ?? false) { HttpRequestHeaders(request, name, value); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index 9f56acde72..b934387d01 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -37,9 +37,9 @@ internal static class WcfInstrumentationActivitySource public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); - public static WcfInstrumentationOptions Options { get; set; } + public static WcfInstrumentationOptions? Options { get; set; } - public static IEnumerable MessageHeaderValuesGetter(Message request, string name) + public static IEnumerable? MessageHeaderValuesGetter(Message request, string name) { return TelemetryPropagationReader.Default(request, name); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index 87e7a5a43e..24cace7703 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -62,7 +62,7 @@ public void EnrichmentException(string exception) } [NonEvent] - public void HttpServiceModelReflectionFailedToBind(Exception exception, System.Reflection.Assembly assembly) + public void HttpServiceModelReflectionFailedToBind(Exception exception, System.Reflection.Assembly? assembly) { if (this.IsEnabled(EventLevel.Verbose, (EventKeywords)(-1))) { @@ -71,7 +71,7 @@ public void HttpServiceModelReflectionFailedToBind(Exception exception, System.R } [Event(EventIds.HttpServiceModelReflectionFailedToBind, Message = "Failed to bind to System.ServiceModel.Http. Exception {0}. Assembly {1}.", Level = EventLevel.Verbose)] - public void HttpServiceModelReflectionFailedToBind(string exception, string assembly) + public void HttpServiceModelReflectionFailedToBind(string exception, string? assembly) { this.WriteEvent(EventIds.HttpServiceModelReflectionFailedToBind, exception, assembly); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 069714297b..7d8b688310 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -7,7 +7,6 @@ OpenTelemetry instrumentation for WCF $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- - disable diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index d5acfd17e8..1dd52c3a7d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -96,11 +96,9 @@ internal static void ApplyClientBehaviorToClientRuntime(ClientRuntime clientRunt foreach (var clientOperation in clientRuntime.ClientOperations) { - actionMappings[clientOperation.Action] = new ActionMetadata - { - ContractName = $"{clientRuntime.ContractNamespace}{clientRuntime.ContractName}", - OperationName = clientOperation.Name, - }; + actionMappings[clientOperation.Action] = new ActionMetadata( + contractName: $"{clientRuntime.ContractNamespace}{clientRuntime.ContractName}", + operationName: clientOperation.Name); } clientRuntime.ClientMessageInspectors.Add(new TelemetryClientMessageInspector(actionMappings)); @@ -113,11 +111,9 @@ internal static void ApplyDispatchBehaviorToEndpoint(EndpointDispatcher endpoint foreach (var dispatchOperation in endpointDispatcher.DispatchRuntime.Operations) { - actionMappings[dispatchOperation.Action] = new ActionMetadata - { - ContractName = $"{endpointDispatcher.ContractNamespace}{endpointDispatcher.ContractName}", - OperationName = dispatchOperation.Name, - }; + actionMappings[dispatchOperation.Action] = new ActionMetadata( + contractName: $"{endpointDispatcher.ContractNamespace}{endpointDispatcher.ContractName}", + operationName: dispatchOperation.Name); } endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new TelemetryDispatchMessageInspector(actionMappings)); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index 7ba6e224d0..4cac3b1bb7 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -39,7 +39,7 @@ public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBui /// being configured. /// Wcf configuration options. /// The instance of to chain the calls. - public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action configure) + public static TracerProviderBuilder AddWcfInstrumentation(this TracerProviderBuilder builder, Action? configure) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs index 83cca12ecd..17b6b2c8f9 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs @@ -35,7 +35,7 @@ public class WcfInstrumentationOptions /// object: the raw from which additional information can be extracted to enrich the activity. /// /// - public Action Enrich { get; set; } + public Action? Enrich { get; set; } /// /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. @@ -43,7 +43,7 @@ public class WcfInstrumentationOptions /// If Filter returns true, the request is collected. /// If Filter returns false or throw exception, the request is filtered out. /// - public Func IncomingRequestFilter { get; set; } + public Func? IncomingRequestFilter { get; set; } /// /// Gets or sets a Filter function to filter instrumentation for requests on a per request basis. @@ -51,7 +51,7 @@ public class WcfInstrumentationOptions /// If Filter returns true, the request is collected. /// If Filter returns false or throw exception, the request is filtered out. /// - public Func OutgoingRequestFilter { get; set; } + public Func? OutgoingRequestFilter { get; set; } /// /// Gets or sets a value indicating whether down stream instrumentation (HttpClient) is suppressed (disabled). Default value: True. diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs index 22f671e14d..6d450e2aca 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs @@ -39,7 +39,7 @@ public void IncomingRequestHeadersAreOverwrittenWithAspNetParent() var reflectedValues = typeof(AspNetParentSpanCorrector).GetField("ReflectedValues", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); Assert.False(reflectedValues == null, "The reflection-based bind to OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule failed. The AspNet telemetry has likely changed, and this assembly needs to be updated to match"); - using (var aspNetActivity = testSource.StartActivity("AspNetActivity")) + using (var aspNetActivity = testSource.StartActivity("AspNetActivity")!) { var context = new FakeHttpContext(); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 914e358ede..53393978d8 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -5,7 +5,6 @@ net7.0;net6.0 $(TargetFrameworks);net462 - disable diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs index d85a9b42ea..9555c64121 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs @@ -35,47 +35,48 @@ public class TelemetryBindingElementForHttpTests : IDisposable { private readonly Uri serviceBaseUri; private readonly HttpListener listener; - private readonly EventWaitHandle initializationHandle; public TelemetryBindingElementForHttpTests() { Random random = new Random(); var retryCount = 5; + HttpListener? createdListener = null; while (retryCount > 0) { try { this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); - this.listener = new HttpListener(); - this.listener.Prefixes.Add(this.serviceBaseUri.OriginalString); - this.listener.Start(); + createdListener = new HttpListener(); + createdListener.Prefixes.Add(this.serviceBaseUri.OriginalString); + createdListener.Start(); break; } catch { - this.listener.Close(); - this.listener = null; + createdListener?.Close(); + createdListener = null; retryCount--; } } - if (this.listener == null) + if (createdListener == null || this.serviceBaseUri == null) { throw new InvalidOperationException("HttpListener could not be started."); } - this.initializationHandle = new EventWaitHandle(false, EventResetMode.ManualReset); + this.listener = createdListener; + var initializationHandle = new EventWaitHandle(false, EventResetMode.ManualReset); try { Listener(); - this.initializationHandle.WaitOne(); + initializationHandle.WaitOne(); } finally { - this.initializationHandle.Dispose(); - this.initializationHandle = null; + initializationHandle.Dispose(); + initializationHandle = null; } async void Listener() @@ -86,7 +87,7 @@ async void Listener() { var ctxTask = this.listener.GetContextAsync(); - this.initializationHandle?.Set(); + initializationHandle?.Set(); var ctx = await ctxTask.ConfigureAwait(false); @@ -197,7 +198,7 @@ public async Task OutgoingRequestInstrumentationTest( .AddDownstreamInstrumentation(); } - TracerProvider tracerProvider = builder.Build(); + TracerProvider? tracerProvider = builder.Build(); ServiceClient client = new ServiceClient( new BasicHttpBinding(BasicHttpSecurityMode.None), @@ -210,18 +211,16 @@ public async Task OutgoingRequestInstrumentationTest( if (emptyOrNullAction) { await client.ExecuteWithEmptyActionNameAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + new ServiceRequest( + payload: "Hello Open Telemetry!")) + .ConfigureAwait(false); } else { await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + new ServiceRequest( + payload: "Hello Open Telemetry!")) + .ConfigureAwait(false); } } finally @@ -235,8 +234,8 @@ await client.ExecuteAsync( client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } @@ -329,10 +328,10 @@ public async void ActivitiesHaveCorrectParentTest() using (var parentActivity = testSource.StartActivity("ParentActivity")) { - client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); - client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); - var firstAsyncCall = client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); - await client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + var firstAsyncCall = client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); + await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); await firstAsyncCall; } } @@ -347,8 +346,8 @@ public async void ActivitiesHaveCorrectParentTest() client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); testSource.Dispose(); WcfInstrumentationActivitySource.Options = null; } @@ -388,8 +387,8 @@ public async void ErrorsAreHandledProperlyTest() { Assert.ThrowsAny(() => client.ErrorSynchronous()); await Assert.ThrowsAnyAsync(client.ErrorAsync); - Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" })); - await Assert.ThrowsAnyAsync(() => clientBadUrl.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!"))); + await Assert.ThrowsAnyAsync(() => clientBadUrl.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); } } finally @@ -412,8 +411,8 @@ public async void ErrorsAreHandledProperlyTest() clientBadUrl.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); testSource.Dispose(); WcfInstrumentationActivitySource.Options = null; } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs index 2205af0c61..a795fb1046 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs @@ -111,7 +111,7 @@ public async Task OutgoingRequestInstrumentationTest( .AddDownstreamInstrumentation(); } - TracerProvider tracerProvider = builder.Build(); + TracerProvider? tracerProvider = builder.Build(); var client = new ServiceClient( new NetTcpBinding(SecurityMode.None), @@ -124,18 +124,16 @@ public async Task OutgoingRequestInstrumentationTest( if (emptyOrNullAction) { await client.ExecuteWithEmptyActionNameAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + new ServiceRequest( + payload: "Hello Open Telemetry!")) + .ConfigureAwait(false); } else { await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + new ServiceRequest( + payload: "Hello Open Telemetry!")) + .ConfigureAwait(false); } } finally @@ -149,8 +147,8 @@ await client.ExecuteAsync( client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } @@ -201,7 +199,7 @@ await client.ExecuteAsync( Assert.Equal("/Service", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.WcfChannelPathTag).Value); if (includeVersion) { - var value = activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value.ToString(); + var value = activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value!.ToString(); Assert.Matches("""Soap.* \(http.*\) Addressing.* \(http.*\)""", value); } @@ -244,10 +242,10 @@ public async void ActivitiesHaveCorrectParentTest() using (var parentActivity = testSource.StartActivity("ParentActivity")) { - client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); - client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); - var firstAsyncCall = client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); - await client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + var firstAsyncCall = client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); + await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); await firstAsyncCall; } } @@ -262,8 +260,8 @@ public async void ActivitiesHaveCorrectParentTest() client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); testSource.Dispose(); WcfInstrumentationActivitySource.Options = null; } @@ -307,8 +305,8 @@ public async void ErrorsAreHandledProperlyTest() // async execution context gets lost somewhere in WCF internals, so we'll explicitly open it first client2.Open(); await Assert.ThrowsAnyAsync(client2.ErrorAsync); - Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" })); - await Assert.ThrowsAnyAsync(() => clientBadUrl2.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!"))); + await Assert.ThrowsAnyAsync(() => clientBadUrl2.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); } } finally @@ -329,8 +327,8 @@ public async void ErrorsAreHandledProperlyTest() closeClient(clientBadUrl); closeClient(clientBadUrl2); - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); testSource.Dispose(); WcfInstrumentationActivitySource.Options = null; } @@ -360,7 +358,7 @@ public async void OrphanedTelemetryTimesOut() client.Endpoint.EndpointBehaviors.Add(new DownstreamInstrumentationEndpointBehavior()); client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); DownstreamInstrumentationChannel.FailNextReceive(); - await Assert.ThrowsAnyAsync(() => client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + await Assert.ThrowsAnyAsync(() => client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); for (var i = 0; i < 50; i++) { @@ -385,8 +383,8 @@ public async void OrphanedTelemetryTimesOut() client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } } @@ -409,7 +407,7 @@ public async void DynamicTimeoutValuesAreRespected() client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); client.InnerChannel.OperationTimeout = TimeSpan.FromMilliseconds(1000); DownstreamInstrumentationChannel.FailNextReceive(); - await Assert.ThrowsAnyAsync(() => client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" })); + await Assert.ThrowsAnyAsync(() => client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); var startedWaiting = DateTime.UtcNow; for (var i = 0; i < 200; i++) @@ -436,8 +434,8 @@ public async void DynamicTimeoutValuesAreRespected() client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } } @@ -459,16 +457,15 @@ public void StreamedTransferWithTransportSecurityWithMessageCredentialWorks() binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign; binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; var host = this.CreateServiceHost(binding, LoadCertificate()); - ServiceClient client = null; + ServiceClient client = new ServiceClient(binding, new EndpointAddress(new Uri(host.BaseAddresses[0], "/Service"))); try { - client = new ServiceClient(binding, new EndpointAddress(new Uri(host.BaseAddresses[0], "/Service"))); client.ClientCredentials.ClientCertificate.Certificate = LoadCertificate(); // never do this in production code, this insecure and for testing only client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - client.ExecuteSynchronous(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); } finally { @@ -483,8 +480,8 @@ public void StreamedTransferWithTransportSecurityWithMessageCredentialWorks() host.Close(); - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } @@ -509,9 +506,9 @@ private static X509Certificate2 LoadCertificate() return new X509Certificate2(memoryStream.ToArray()); } - private ServiceHost CreateServiceHost(NetTcpBinding binding, X509Certificate2 cert) + private ServiceHost CreateServiceHost(NetTcpBinding binding, X509Certificate2? cert) { - ServiceHost serviceHost = null; + ServiceHost? serviceHost = null; Random random = new Random(); var retryCount = 5; while (retryCount > 0) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index 8dd1ec1bb9..349fb7bf8e 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -44,47 +44,50 @@ public TelemetryDispatchMessageInspectorForOneWayOperationsTests(ITestOutputHelp Random random = new Random(); var retryCount = 5; + ServiceHost? createdHost = null; while (retryCount > 0) { try { this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); - this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); + createdHost = new ServiceHost(new Service(), this.serviceBaseUri); - var endpoint = this.serviceHost.AddServiceEndpoint( + var endpoint = createdHost.AddServiceEndpoint( typeof(IServiceContract), new NetTcpBinding(), "/Service"); endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); - this.serviceHost.Description.Behaviors.Add( + createdHost.Description.Behaviors.Add( new ErrorHandlerServiceBehavior(this.thrownExceptionsHandle, ex => this.thrownExceptions.Add(ex))); - this.serviceHost.Open(); + createdHost.Open(); break; } catch (Exception ex) { this.output.WriteLine(ex.ToString()); - if (this.serviceHost.State == CommunicationState.Faulted) + if (createdHost?.State == CommunicationState.Faulted) { - this.serviceHost.Abort(); + createdHost.Abort(); } else { - this.serviceHost.Close(); + createdHost?.Close(); } - this.serviceHost = null; + createdHost = null; retryCount--; } } - if (this.serviceHost == null) + if (createdHost == null || this.serviceBaseUri == null) { throw new InvalidOperationException("ServiceHost could not be started."); } + + this.serviceHost = createdHost; } public void Dispose() @@ -105,7 +108,7 @@ public void IncomingRequestOneWayOperationInstrumentationTest() }; ActivitySource.AddActivityListener(activityListener); - TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + TracerProvider? tracerProvider = Sdk.CreateTracerProviderBuilder() .AddWcfInstrumentation() .Build(); @@ -115,7 +118,7 @@ public void IncomingRequestOneWayOperationInstrumentationTest() try { - client.ExecuteWithOneWay(new ServiceRequest()); + client.ExecuteWithOneWay(new ServiceRequest(payload: "Hello Open Telemetry!")); this.thrownExceptionsHandle.WaitOne(3000); } finally diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index c6776c9f82..2991ca7316 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -41,41 +41,44 @@ public TelemetryDispatchMessageInspectorTests(ITestOutputHelper outputHelper) Random random = new Random(); var retryCount = 5; + ServiceHost? createdHost = null; while (retryCount > 0) { try { this.serviceBaseUri = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); - this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUri); - var endpoint = this.serviceHost.AddServiceEndpoint( + createdHost = new ServiceHost(new Service(), this.serviceBaseUri); + var endpoint = createdHost.AddServiceEndpoint( typeof(IServiceContract), new NetTcpBinding(), "/Service"); endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); - this.serviceHost.Open(); + createdHost.Open(); break; } catch (Exception ex) { this.output.WriteLine(ex.ToString()); - if (this.serviceHost.State == CommunicationState.Faulted) + if (createdHost?.State == CommunicationState.Faulted) { - this.serviceHost.Abort(); + createdHost.Abort(); } else { - this.serviceHost.Close(); + createdHost?.Close(); } - this.serviceHost = null; + createdHost = null; retryCount--; } } - if (this.serviceHost == null) + if (createdHost == null || this.serviceBaseUri == null) { throw new InvalidOperationException("ServiceHost could not be started."); } + + this.serviceHost = createdHost; } public void Dispose() @@ -109,7 +112,7 @@ public async Task IncomingRequestInstrumentationTest( ActivitySource.AddActivityListener(activityListener); - TracerProvider tracerProvider = null; + TracerProvider? tracerProvider = null; if (instrument) { tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -162,18 +165,16 @@ public async Task IncomingRequestInstrumentationTest( if (emptyOrNullAction) { await client.ExecuteWithEmptyActionNameAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + new ServiceRequest( + payload: "Hello Open Telemetry!")) + .ConfigureAwait(false); } else { await client.ExecuteAsync( - new ServiceRequest - { - Payload = "Hello Open Telemetry!", - }).ConfigureAwait(false); + new ServiceRequest( + payload: "Hello Open Telemetry!")) + .ConfigureAwait(false); } } finally diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs index 89e3d49f60..6029269d0f 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs @@ -39,43 +39,46 @@ public TelemetryPropagationTests() { Random random = new Random(); var retryCount = 5; + ServiceHost? createdHost = null; while (retryCount > 0) { try { this.serviceBaseUriTcp = new Uri($"net.tcp://localhost:{random.Next(2000, 5000)}/"); this.serviceBaseUriHttp = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); - this.serviceHost = new ServiceHost(new Service(), this.serviceBaseUriTcp, this.serviceBaseUriHttp); - var tcpEndpoint = this.serviceHost.AddServiceEndpoint(typeof(IServiceContract), new NetTcpBinding(), "/tcp"); + createdHost = new ServiceHost(new Service(), this.serviceBaseUriTcp, this.serviceBaseUriHttp); + var tcpEndpoint = createdHost.AddServiceEndpoint(typeof(IServiceContract), new NetTcpBinding(), "/tcp"); tcpEndpoint.Behaviors.Add(new TelemetryEndpointBehavior()); - var httpEndpoint = this.serviceHost.AddServiceEndpoint(typeof(IServiceContract), new BasicHttpBinding(), "/http"); + var httpEndpoint = createdHost.AddServiceEndpoint(typeof(IServiceContract), new BasicHttpBinding(), "/http"); httpEndpoint.Behaviors.Add(new TelemetryEndpointBehavior()); - var restEndpoint = this.serviceHost.AddServiceEndpoint(typeof(IServiceContract), new WebHttpBinding(), "/rest"); + var restEndpoint = createdHost.AddServiceEndpoint(typeof(IServiceContract), new WebHttpBinding(), "/rest"); restEndpoint.Behaviors.Add(new TelemetryEndpointBehavior()); restEndpoint.Behaviors.Add(new WebHttpBehavior()); - this.serviceHost.Open(); + createdHost.Open(); break; } catch (Exception) { - if (this.serviceHost.State == CommunicationState.Faulted) + if (createdHost?.State == CommunicationState.Faulted) { - this.serviceHost.Abort(); + createdHost.Abort(); } else { - this.serviceHost.Close(); + createdHost?.Close(); } - this.serviceHost = null; + createdHost = null; retryCount--; } } - if (this.serviceHost == null) + if (createdHost == null || this.serviceBaseUriTcp == null || this.serviceBaseUriHttp == null) { throw new InvalidOperationException("ServiceHost could not be started."); } + + this.serviceHost = createdHost; } public void Dispose() @@ -124,7 +127,7 @@ public async Task TelemetryContextPropagatesTest( client.Endpoint.EndpointBehaviors.Add(new WebHttpBehavior()); } - await client.ExecuteAsync(new ServiceRequest { Payload = "Hello Open Telemetry!" }); + await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); } finally { @@ -137,8 +140,8 @@ public async Task TelemetryContextPropagatesTest( client.Close(); } - tracerProvider.Shutdown(); - tracerProvider.Dispose(); + tracerProvider?.Shutdown(); + tracerProvider?.Dispose(); WcfInstrumentationActivitySource.Options = null; } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs index 5abaae0a97..51822f534a 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs @@ -33,8 +33,7 @@ public override T GetProperty(BindingContext context) public override IChannelFactory BuildChannelFactory(BindingContext context) { - var proxy = DispatchProxy.Create, DownstreamInstrumentationChannelFactory>() - as DownstreamInstrumentationChannelFactory; + var proxy = (DownstreamInstrumentationChannelFactory)DispatchProxy.Create, DownstreamInstrumentationChannelFactory>(); proxy.Target = base.BuildChannelFactory(context); return (IChannelFactory)proxy; } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs index da8b20cdfd..0eb05eeb8f 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs @@ -28,11 +28,12 @@ public class DownstreamInstrumentationChannel : DispatchProxy private static readonly ActivitySource DownstreamInstrumentationSource = new ActivitySource(DownstreamInstrumentationSourceName); private static bool failNextReceive; - private object Target { get; set; } + private object? Target { get; set; } public static TChannel Create(TChannel target) + where TChannel : notnull { - var proxy = Create() as DownstreamInstrumentationChannel; + var proxy = (DownstreamInstrumentationChannel)(object)Create(); proxy.Target = target; return (TChannel)(object)proxy; } @@ -42,7 +43,7 @@ public static void FailNextReceive(bool shouldFail = true) failNextReceive = shouldFail; } - protected override object Invoke(MethodInfo targetMethod, object[] args) + protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) { var toInstrument = new[] { @@ -52,7 +53,7 @@ protected override object Invoke(MethodInfo targetMethod, object[] args) nameof(IOutputChannel.BeginSend), }; - using var activity = toInstrument.Contains(targetMethod.Name) ? DownstreamInstrumentationSource.StartActivity("DownstreamInstrumentation") : null; + using var activity = toInstrument.Contains(targetMethod!.Name) ? DownstreamInstrumentationSource.StartActivity("DownstreamInstrumentation") : null; var receiveMethods = new[] { @@ -62,7 +63,7 @@ protected override object Invoke(MethodInfo targetMethod, object[] args) nameof(IInputChannel.BeginTryReceive), }; - if (failNextReceive && receiveMethods.Contains(targetMethod.Name)) + if (failNextReceive && receiveMethods.Contains(targetMethod!.Name)) { failNextReceive = false; throw new Exception(); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs index 768bea1531..9cdb78e58f 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs @@ -20,15 +20,16 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; public class DownstreamInstrumentationChannelFactory : DispatchProxy + where TChannel : notnull { - public IChannelFactory Target { get; set; } + public IChannelFactory? Target { get; set; } - protected override object Invoke(MethodInfo targetMethod, object[] args) + protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) { - var returnValue = targetMethod.Invoke(this.Target, args); + var returnValue = targetMethod!.Invoke(this.Target, args); if (targetMethod.Name == nameof(IChannelFactory.CreateChannel)) { - return DownstreamInstrumentationChannel.Create((TChannel)returnValue); + return DownstreamInstrumentationChannel.Create((TChannel)returnValue!); } return returnValue; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 1807014e13..9cc1493135 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -41,27 +41,21 @@ public void ErrorSynchronous() public Task ExecuteAsync(ServiceRequest request) { return Task.FromResult( - new ServiceResponse - { - Payload = $"RSP: {request.Payload}", - }); + new ServiceResponse( + payload: $"RSP: {request.Payload}")); } public ServiceResponse ExecuteSynchronous(ServiceRequest request) { - return new ServiceResponse - { - Payload = $"RSP: {request.Payload}", - }; + return new ServiceResponse( + payload: $"RSP: {request.Payload}"); } public Task ExecuteWithEmptyActionNameAsync(ServiceRequest request) { return Task.FromResult( - new ServiceResponse - { - Payload = $"RSP: {request.Payload}", - }); + new ServiceResponse( + payload: $"RSP: {request.Payload}")); } public void ExecuteWithOneWay(ServiceRequest request) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index 6e7ffcb3b6..b262522e6c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -21,6 +21,11 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [DataContract] public class ServiceRequest { + public ServiceRequest(string payload) + { + this.Payload = payload; + } + [DataMember] public string Payload { get; set; } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index b076c64f7a..5a61c80ec0 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -21,6 +21,11 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [DataContract] public class ServiceResponse { + public ServiceResponse(string payload) + { + this.Payload = payload; + } + [DataMember] public string Payload { get; set; } } From 57a311cd02d8fc785f3cdd53efab323a9843a438 Mon Sep 17 00:00:00 2001 From: Christoffer Hjalmarsson Date: Mon, 6 Nov 2023 06:32:24 +0100 Subject: [PATCH 0870/1499] [Instrumentation.AspNet] Fix metric http.server.duration always being zero (#1425) Co-authored-by: Vishwesh Bankwar --- .../ActivityHelper.cs | 7 +++++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ .../HttpInMetricsListenerTests.cs | 3 +++ 3 files changed, 14 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index 569409aa3f..fadcd4b7fa 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -133,6 +133,13 @@ public static void StopAspNetActivity(TextMapPropagator textMapPropagator, Activ var currentActivity = Activity.Current; context.Items[ContextKey] = null; + // Make sure that the activity has a proper end time before onRequestStoppedCallback is called. + // Note that the activity must not be stopped before the callback is called. + if (aspNetActivity.Duration == TimeSpan.Zero) + { + aspNetActivity.SetEndTime(DateTime.UtcNow); + } + try { onRequestStoppedCallback?.Invoke(aspNetActivity, context); diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index ea5d2bd227..a12e1d0aa2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fixed an issue that caused `http.server.duration` metric value to always be set + to `0`. The issue exists in `1.6.0-beta.1` version. + ([#1425](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1425)) + ## 1.6.0-beta.1 Released 2023-Oct-11 diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index cd458aad73..a1cf7c1c24 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using System.IO; +using System.Threading; using System.Web; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Metrics; @@ -56,6 +57,7 @@ public void HttpDurationMetricIsEmitted() .Build(); var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + Thread.Sleep(1); // Make sure duration is always greater than 0 to avoid flakiness. ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); meterProvider.ForceFlush(); @@ -77,6 +79,7 @@ public void HttpDurationMetricIsEmitted() Assert.Equal("http.server.duration", exportedItems[0].Name); Assert.Equal(1L, count); Assert.Equal(duration, sum); + Assert.True(duration > 0, "Metric duration should be set."); Assert.Equal(3, metricPoints[0].Tags.Count); string? httpMethod = null; From 4c1c089a95446ca45be5c71eb834723c5735a21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Mon, 6 Nov 2023 08:38:04 +0100 Subject: [PATCH 0871/1499] [Instrumentation.AspNet] Update CHANGELOG for 1.6.0-beta.2 release (#1427) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index abd8552d4e..a300bf0c1b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-beta.2 + +Released 2023-Nov-06 + ## 1.6.0-beta.1 Released 2023-Oct-11 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index a12e1d0aa2..747cc01b3f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-beta.2 + +Released 2023-Nov-06 + * Fixed an issue that caused `http.server.duration` metric value to always be set to `0`. The issue exists in `1.6.0-beta.1` version. ([#1425](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1425)) From 4565ff1908c6f301ca3363215466e05f15e1642c Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 6 Nov 2023 21:52:58 -0800 Subject: [PATCH 0872/1499] [Exporter.Geneva][TLD] Fix serialization issue (#1424) --- .../CHANGELOG.md | 4 +++ .../TLDExporter/JsonSerializer.cs | 34 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 5ca46c4425..2a1d2d86cf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -10,6 +10,10 @@ are no Part C fields. ([#1396](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1396)) +* Fix a serialization issue for `TldTraceExporter` and `TldLogExporter` when any + non-primitive types have to be serialized for `env_properties`. + ([#1424](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1424)) + ## 1.7.0-alpha.1 Released 2023-Sep-22 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index e80c8477c2..a545b28025 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -104,6 +104,22 @@ public static int SerializeString(byte[] buffer, int cursor, string value) return cursor; } +#if NET6_0_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeString(byte[] buffer, int cursor, ReadOnlySpan value) + { + if (value.IsEmpty) + { + return SerializeNull(buffer, cursor); + } + + buffer[cursor++] = ASCII_QUOTATION_MARK; + cursor = WriteString(buffer, cursor, value); + buffer[cursor++] = ASCII_QUOTATION_MARK; + return cursor; + } +#endif + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SerializeArray(T[] array) { @@ -316,18 +332,30 @@ public static int Serialize(byte[] buffer, int cursor, object obj) return SerializeMap(buffer, cursor, v); case object[] v: return SerializeArray(buffer, cursor, v); + #if NET6_0_OR_GREATER case ISpanFormattable v: tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; if (v.TryFormat(tmp, out charsWritten, default, CultureInfo.InvariantCulture)) { - return WriteString(buffer, cursor, tmp.Slice(0, charsWritten)); + return SerializeString(buffer, cursor, tmp.Slice(0, charsWritten)); } goto default; #endif + default: - return SerializeString(buffer, cursor, $"ERROR: type {obj.GetType().FullName} is not supported"); + string repr; + try + { + repr = Convert.ToString(obj, CultureInfo.InvariantCulture); + } + catch + { + repr = $"ERROR: type {obj.GetType().FullName} is not supported"; + } + + return SerializeString(buffer, cursor, repr); } } @@ -400,7 +428,7 @@ private static int WriteString(byte[] buffer, int cursor, string value) #if NET6_0_OR_GREATER [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int WriteString(byte[] buffer, int cursor, Span value) + private static int WriteString(byte[] buffer, int cursor, ReadOnlySpan value) { for (int i = 0; i < value.Length; i++) { From c6301174130f4364ab9638c76d3bfc1ae5c857dc Mon Sep 17 00:00:00 2001 From: Christoffer Hjalmarsson Date: Wed, 8 Nov 2023 20:02:01 +0100 Subject: [PATCH 0873/1499] [Instrumentation.AspNet] Add metric enrich functionality (#1407) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 8 +- .../AspNetMetrics.cs | 5 +- .../AspNetMetricsInstrumentationOptions.cs | 38 ++++++++ .../CHANGELOG.md | 6 ++ .../Implementation/HttpInMetricsListener.cs | 16 +++- .../MeterProviderBuilderExtensions.cs | 18 +++- .../README.md | 32 ++++++- .../HttpInListenerTests.cs | 44 +-------- .../HttpInMetricsListenerTests.cs | 96 +++++++++++++------ .../RouteTestHelper.cs | 72 ++++++++++++++ 10 files changed, 255 insertions(+), 80 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt index b2fd0825bd..2f57288e06 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions +OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.AspNetInstrumentationOptions() -> void OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.set -> void @@ -6,8 +6,14 @@ OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.get -> OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions +OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.AspNetMetricsInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.Enrich.get -> OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.EnrichFunc? +OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.EnrichFunc OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs index 60d9f51a02..fccbf77437 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -37,10 +37,11 @@ internal sealed class AspNetMetrics : IDisposable /// /// Initializes a new instance of the class. /// - public AspNetMetrics() + /// The metrics configuration options. + public AspNetMetrics(AspNetMetricsInstrumentationOptions options) { this.meter = new Meter(InstrumentationName, InstrumentationVersion); - this.httpInMetricsListener = new HttpInMetricsListener(this.meter); + this.httpInMetricsListener = new HttpInMetricsListener(this.meter, options); } /// diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs new file mode 100644 index 0000000000..c93b3a9c26 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs @@ -0,0 +1,38 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; +using System.Web; + +namespace OpenTelemetry.Instrumentation.AspNet; + +/// +/// Options for metric instrumentation. +/// +public sealed class AspNetMetricsInstrumentationOptions +{ + /// + /// Delegate for enrichment of recorded metric with additional tags. + /// + /// : the HttpContext object. Both Request and Response are available. + /// : List of current tags. You can add additional tags to this list. + public delegate void EnrichFunc(HttpContext context, ref TagList tags); + + /// + /// Gets or sets an function to enrich a recorded metric with additional custom tags. + /// + public EnrichFunc? Enrich { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 747cc01b3f..113da505ea 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Added enrich functionality to metric instrumentation + ([#1407](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1407)). + + * New overload of `AddAspNetInstrumentation` now accepts a configuration delegate. + * The `Enrich` can be used to add additional metric attributes. + ## 1.6.0-beta.2 Released 2023-Nov-06 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index eeda8049f4..8ce43d5675 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -25,11 +25,13 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation; internal sealed class HttpInMetricsListener : IDisposable { private readonly Histogram httpServerDuration; + private readonly AspNetMetricsInstrumentationOptions options; - public HttpInMetricsListener(Meter meter) + public HttpInMetricsListener(Meter meter, AspNetMetricsInstrumentationOptions options) { this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "Measures the duration of inbound HTTP requests."); TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; + this.options = options; } public void Dispose() @@ -48,6 +50,18 @@ private void OnStopActivity(Activity activity, HttpContext context) { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode }, }; + if (this.options.Enrich is not null) + { + try + { + this.options.Enrich(context, ref tags); + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.EnrichmentException(nameof(HttpInMetricsListener), ex); + } + } + this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs index 2b2b6cf3cc..f69f013a7c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs @@ -14,6 +14,7 @@ // limitations under the License. // +using System; using OpenTelemetry.Instrumentation.AspNet; using OpenTelemetry.Internal; @@ -29,12 +30,25 @@ public static class MeterProviderBuilderExtensions /// /// being configured. /// The instance of to chain the calls. + public static MeterProviderBuilder AddAspNetInstrumentation(this MeterProviderBuilder builder) => + AddAspNetInstrumentation(builder, configure: null); + + /// + /// Enables the incoming requests automatic data collection for ASP.NET. + /// + /// being configured. + /// Callback action for configuring . + /// The instance of to chain the calls. public static MeterProviderBuilder AddAspNetInstrumentation( - this MeterProviderBuilder builder) + this MeterProviderBuilder builder, + Action? configure) { Guard.ThrowIfNull(builder); + var options = new AspNetMetricsInstrumentationOptions(); + configure?.Invoke(options); + builder.AddMeter(AspNetMetrics.InstrumentationName); - return builder.AddInstrumentation(() => new AspNetMetrics()); + return builder.AddInstrumentation(() => new AspNetMetrics(options)); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index bdeb5cf728..7bae983e19 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -128,13 +128,13 @@ Currently, the instrumentation supports the following metric. |-------|-----------------|------|-------------| | `http.server.duration` | Histogram | `ms` | Measures the duration of inbound HTTP requests. | -## Advanced configuration +## Advanced trace configuration This instrumentation can be configured to change the default behavior by using `AspNetInstrumentationOptions`, which allows configuring `Filter` as explained below. -### Filter +### Trace Filter This instrumentation by default collects all the incoming http requests. It allows filtering of requests by using the `Filter` function in @@ -162,7 +162,7 @@ instrumentation. OpenTelemetry has a concept of a [Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling), and the `Filter` option does the filtering *before* the Sampler is invoked. -### Enrich +### Trace Enrich This option allows one to enrich the activity with additional information from the raw `HttpRequest`, `HttpResponse` objects. The `Enrich` action is called @@ -208,6 +208,32 @@ This instrumentation automatically sets Activity Status to Error if an unhandled exception is thrown. Additionally, `RecordException` feature may be turned on, to store the exception to the Activity itself as ActivityEvent. +## Advanced metric configuration + +This instrumentation can be configured to change the default behavior by using +`AspNetMetricsInstrumentationOptions` as explained below. + +### Metric Enrich + +This option allows one to enrich the metric with additional information from +the `HttpContext`. The `Enrich` action is always called unless the metric was +filtered. The callback allows for modifying the tag list. If the callback +throws an exception the metric will still be recorded. + +```csharp +this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetInstrumentation(options => options.Enrich = + (HttpContext context, ref TagList tags) => + { + // Add request content type to the metric tags. + if (!string.IsNullOrEmpty(context.Request.ContentType)) + { + tags.Add("custom.content.type", context.Request.ContentType); + } + }) + .Build(); +``` + ## References * [ASP.NET](https://dotnet.microsoft.com/apps/aspnet) diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 3cb163eed8..3022963248 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -58,49 +58,7 @@ public void AspNetRequestsAreCollectedSuccessfully( string? filter = null, bool recordException = false) { - RouteData routeData; - switch (routeType) - { - case 0: // WebForm, no route data. - routeData = new RouteData(); - break; - case 1: // Traditional MVC. - case 2: // Attribute routing MVC. - case 3: // Traditional WebAPI. - routeData = new RouteData() - { - Route = new Route(routeTemplate, null), - }; - break; - case 4: // Attribute routing WebAPI. - routeData = new RouteData(); - var value = new[] - { - new - { - Route = new - { - RouteTemplate = routeTemplate, - }, - }, - }; - routeData.Values.Add( - "MS_SubRoutes", - value); - break; - default: - throw new NotSupportedException(); - } - - HttpContext.Current = new HttpContext( - new HttpRequest(string.Empty, url, string.Empty) - { - RequestContext = new RequestContext() - { - RouteData = routeData, - }, - }, - new HttpResponse(new StringWriter())); + HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, Mock.Of()); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index a1cf7c1c24..05a158b9e3 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -14,8 +14,9 @@ // limitations under the License. // +using System; using System.Collections.Generic; -using System.IO; +using System.Diagnostics; using System.Threading; using System.Web; using OpenTelemetry.Context.Propagation; @@ -27,14 +28,28 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class HttpInMetricsListenerTests { - [Fact] - public void HttpDurationMetricIsEmitted() + [Theory] + [InlineData("http://localhost/", 0, null, null, "http")] + [InlineData("https://localhost/", 0, null, null, "https")] + [InlineData("http://localhost/api/value", 0, null, null, "http")] + [InlineData("http://localhost/api/value", 1, "{controller}/{action}", null, "http")] + [InlineData("http://localhost/api/value", 2, "{controller}/{action}", null, "http")] + [InlineData("http://localhost/api/value", 3, "{controller}/{action}", null, "http")] + [InlineData("http://localhost/api/value", 4, "{controller}/{action}", null, "http")] + [InlineData("http://localhost:8080/api/value", 0, null, null, "http")] + [InlineData("http://localhost:8080/api/value", 1, "{controller}/{action}", null, "http")] + [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", "enrich", "http")] + [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", "throw", "http")] + [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", null, "http")] + public void AspNetMetricTagsAreCollectedSuccessfully( + string url, + int routeType, + string routeTemplate, + string enrichMode, + string expectedScheme) { - string url = "http://localhost/api/value"; double duration = 0; - HttpContext.Current = new HttpContext( - new HttpRequest(string.Empty, url, string.Empty), - new HttpResponse(new StringWriter())); + HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); // This is to enable activity creation // as it is created using ActivitySource inside TelemetryHttpModule @@ -52,7 +67,21 @@ public void HttpDurationMetricIsEmitted() var exportedItems = new List(); using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddAspNetInstrumentation() + .AddAspNetInstrumentation(options => + { + options.Enrich += (HttpContext context, ref TagList tags) => + { + if (enrichMode == "throw") + { + throw new Exception("Enrich exception"); + } + + if (enrichMode == "enrich") + { + tags.Add("enriched", "true"); + } + }; + }) .AddInMemoryExporter(exportedItems) .Build(); @@ -62,6 +91,8 @@ public void HttpDurationMetricIsEmitted() meterProvider.ForceFlush(); + Assert.Single(exportedItems); + var metricPoints = new List(); foreach (var p in exportedItems[0].GetMetricPoints()) { @@ -81,34 +112,43 @@ public void HttpDurationMetricIsEmitted() Assert.Equal(duration, sum); Assert.True(duration > 0, "Metric duration should be set."); - Assert.Equal(3, metricPoints[0].Tags.Count); - string? httpMethod = null; - int httpStatusCode = 0; - string? httpScheme = null; + var expectedTagCount = 3; + if (enrichMode == "enrich") + { + expectedTagCount++; + } + + Assert.Equal(expectedTagCount, metricPoints[0].Tags.Count); + Dictionary tags = new(metricPoint.Tags.Count); + foreach (var tag in metricPoint.Tags) + { + tags.Add(tag.Key, tag.Value); + } - foreach (var tag in metricPoints[0].Tags) + if (enrichMode == "enrich") { - if (tag.Key == SemanticConventions.AttributeHttpMethod) - { - httpMethod = (string)tag.Value; - continue; - } + ExpectTag("true", "enriched"); + } + + ExpectTag("GET", SemanticConventions.AttributeHttpMethod); + ExpectTag(200, SemanticConventions.AttributeHttpStatusCode); + ExpectTag(expectedScheme, SemanticConventions.AttributeHttpScheme); - if (tag.Key == SemanticConventions.AttributeHttpStatusCode) + void ExpectTag(T? expected, string tagName) + { + if (expected is null) { - httpStatusCode = (int)tag.Value; - continue; + Assert.DoesNotContain(tagName, tags.Keys); + return; } - if (tag.Key == SemanticConventions.AttributeHttpScheme) + if (tags.TryGetValue(tagName, out var value)) { - httpScheme = (string)tag.Value; - continue; + Assert.Equal(expected, (T?)value); + return; } - } - Assert.Equal("GET", httpMethod); - Assert.Equal(200, httpStatusCode); - Assert.Equal("http", httpScheme); + Assert.Fail($"Expected tag with key {tagName} not found."); + } } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs new file mode 100644 index 0000000000..4440d64f5a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs @@ -0,0 +1,72 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.IO; +using System.Web; +using System.Web.Routing; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +internal static class RouteTestHelper +{ + public static HttpContext BuildHttpContext(string url, int routeType, string routeTemplate) + { + RouteData routeData; + switch (routeType) + { + case 0: // WebForm, no route data. + routeData = new RouteData(); + break; + case 1: // Traditional MVC. + case 2: // Attribute routing MVC. + case 3: // Traditional WebAPI. + routeData = new RouteData() + { + Route = new Route(routeTemplate, null), + }; + break; + case 4: // Attribute routing WebAPI. + routeData = new RouteData(); + var value = new[] + { + new + { + Route = new + { + RouteTemplate = routeTemplate, + }, + }, + }; + routeData.Values.Add( + "MS_SubRoutes", + value); + break; + default: + throw new NotSupportedException(); + } + + var request = new HttpRequest(string.Empty, url, string.Empty) + { + RequestContext = new RequestContext() + { + RouteData = routeData, + }, + }; + + return new HttpContext(request, new HttpResponse(new StringWriter())); + } +} From ab6398b4155bcd09424520f2e7aebdb0354f43b1 Mon Sep 17 00:00:00 2001 From: Darius Letterman Date: Tue, 14 Nov 2023 18:33:53 +0100 Subject: [PATCH 0874/1499] Trace enrichment framework prep for net8.0 (#1401) --- .../enrichment/Examples.Enrichment/Program.cs | 3 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 25 +++++------ .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 25 +++++------ .../.publicApi/net7.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 18 ++++++++ .../netstandard2.0/PublicAPI.Unshipped.txt | 25 +++++------ .../BaseEnricher.cs | 26 ----------- .../TraceEnrichmentActions.cs} | 10 ++--- .../TraceEnrichmentProcessor.cs | 14 +++++- ...OpenTelemetry.Extensions.Enrichment.csproj | 4 +- .../README.md | 2 +- .../Trace/TraceEnricher.cs | 44 +++++++++++++++++++ .../{ => Trace}/TraceEnrichmentBag.cs | 2 +- .../TraceEnricher.cs | 24 ---------- ...aceEnrichmentProviderBuilderExtensions.cs} | 8 ++-- ...eEnrichmentServiceCollectionExtensions.cs} | 10 ++--- .../MyTraceEnricher.cs | 4 +- .../MyTraceEnricher2.cs | 4 +- ...lemetry.Extensions.Enrichment.Tests.csproj | 3 +- 19 files changed, 138 insertions(+), 114 deletions(-) create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs rename src/OpenTelemetry.Extensions.Enrichment/{EnrichmentActions.cs => Internal/TraceEnrichmentActions.cs} (77%) rename src/OpenTelemetry.Extensions.Enrichment/{ => Internal}/TraceEnrichmentProcessor.cs (81%) create mode 100644 src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs rename src/OpenTelemetry.Extensions.Enrichment/{ => Trace}/TraceEnrichmentBag.cs (96%) delete mode 100644 src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs rename src/OpenTelemetry.Extensions.Enrichment/{OpenTelemetryEnrichmentProviderBuilderExtensions.cs => TraceEnrichmentProviderBuilderExtensions.cs} (93%) rename src/OpenTelemetry.Extensions.Enrichment/{OpenTelemetryEnrichmentServiceCollectionExtensions.cs => TraceEnrichmentServiceCollectionExtensions.cs} (92%) diff --git a/examples/enrichment/Examples.Enrichment/Program.cs b/examples/enrichment/Examples.Enrichment/Program.cs index 3d7b2e7cad..c0c54fd01e 100644 --- a/examples/enrichment/Examples.Enrichment/Program.cs +++ b/examples/enrichment/Examples.Enrichment/Program.cs @@ -38,11 +38,12 @@ public static void Main() .AddSource("MyCompany.MyProduct.MyLibrary") // Register an enricher class. - // Important: AddTraceEnricher() must be called before any exporeters. + // Important: AddTraceEnricher() must be called before any exporters. .AddTraceEnricher() // Add Console exporter to see the output of this example. .AddConsoleExporter() + .Build(); // Create an Activity and add some tags to it. diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt index 21468d4cd0..a037573dcc 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,19 +1,18 @@ -abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(in T enrichmentBag) -> void -Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions -OpenTelemetry.Extensions.Enrichment.BaseEnricher -OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void -OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions +abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void +Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions OpenTelemetry.Extensions.Enrichment.TraceEnricher OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt index 21468d4cd0..a037573dcc 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,19 +1,18 @@ -abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(in T enrichmentBag) -> void -Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions -OpenTelemetry.Extensions.Enrichment.BaseEnricher -OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void -OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions +abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void +Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions OpenTelemetry.Extensions.Enrichment.TraceEnricher OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a037573dcc --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -0,0 +1,18 @@ +abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void +Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions +OpenTelemetry.Extensions.Enrichment.TraceEnricher +OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 21468d4cd0..a037573dcc 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,19 +1,18 @@ -abstract OpenTelemetry.Extensions.Enrichment.BaseEnricher.Enrich(in T enrichmentBag) -> void -Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions -OpenTelemetry.Extensions.Enrichment.BaseEnricher -OpenTelemetry.Extensions.Enrichment.BaseEnricher.BaseEnricher() -> void -OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions +abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void +Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions OpenTelemetry.Extensions.Enrichment.TraceEnricher OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.OpenTelemetryEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.OpenTelemetryEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs deleted file mode 100644 index 4c9db69956..0000000000 --- a/src/OpenTelemetry.Extensions.Enrichment/BaseEnricher.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Extensions.Enrichment; - -public abstract class BaseEnricher -{ - protected BaseEnricher() - { - } - - public abstract void Enrich(in T enrichmentBag); -} diff --git a/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs similarity index 77% rename from src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs rename to src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs index f83c2dec3b..b682aab1b6 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/EnrichmentActions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,21 +21,21 @@ namespace OpenTelemetry.Extensions.Enrichment; #pragma warning disable CA1812 // Class is instantiated through dependency injection -internal sealed class EnrichmentActions : TraceEnricher +internal sealed class TraceEnrichmentActions : TraceEnricher #pragma warning restore CA1812 // Class is instantiated through dependency injection { private readonly Action[] actions; - public EnrichmentActions(IEnumerable> actions) + public TraceEnrichmentActions(IEnumerable> actions) { this.actions = actions.ToArray(); } - public override void Enrich(in TraceEnrichmentBag enrichmentBag) + public override void Enrich(in TraceEnrichmentBag bag) { for (int i = 0; i < this.actions.Length; i++) { - this.actions[i].Invoke(enrichmentBag); + this.actions[i].Invoke(bag); } } } diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs similarity index 81% rename from src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs rename to src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs index 5dc9628baa..30506f8c5d 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProcessor.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs @@ -31,13 +31,23 @@ public TraceEnrichmentProcessor(IEnumerable traceEnrichers) this.traceEnrichers = traceEnrichers.ToArray(); } + public override void OnStart(Activity activity) + { + var bag = new TraceEnrichmentBag(activity); + + foreach (var enricher in this.traceEnrichers) + { + enricher.EnrichOnActivityStart(bag); + } + } + public override void OnEnd(Activity activity) { - var propertyBag = new TraceEnrichmentBag(activity); + var bag = new TraceEnrichmentBag(activity); foreach (var enricher in this.traceEnrichers) { - enricher.Enrich(propertyBag); + enricher.Enrich(bag); } } } diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index a21b4f78d3..2ee7f8c703 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -1,7 +1,9 @@ - $(NetFrameworkMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) + + net7.0;net6.0;$(NetStandardMinimumSupportedVersion) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry .NET SDK telemetry enrichment. $(NoWarn),CS1591 Extensions.Enrichment- diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index 048c3826c5..17a7a77719 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -40,7 +40,7 @@ dotnet add package OpenTelemetry.Extensions.Enrichment --prerelease Create your custom enricher class that inherits from the `TraceEnricher` class and override the `public abstract void Enrich(in TraceEnrichmentBag bag)` method. -Optionally, inject other services you enricher class depends on: +Optionally, inject other services your enricher class depends on: ```csharp internal sealed class MyTraceEnricher : TraceEnricher diff --git a/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs new file mode 100644 index 0000000000..5f93b1b43d --- /dev/null +++ b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Diagnostics; + +namespace OpenTelemetry.Extensions.Enrichment; + +/// +/// Interface for implementing enrichers for traces. +/// +public abstract class TraceEnricher +{ + protected TraceEnricher() + { + } + + /// + /// Enrich trace with additional tags when an is stopped. + /// + /// object to be used to add the required tags to enrich the traces. + public abstract void Enrich(in TraceEnrichmentBag bag); + + /// + /// Enrich trace with additional tags when an is started. + /// + /// object to be used to add the required tags to enrich the traces. + public virtual void EnrichOnActivityStart(in TraceEnrichmentBag bag) + { + // default implementation: noop + } +} diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs similarity index 96% rename from src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs rename to src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs index 2b01eaadd9..79ee8773c2 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentBag.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs @@ -31,6 +31,6 @@ public TraceEnrichmentBag(Activity activity) public void Add(string key, object? value) { - this.activity.SetTag(key, value); + this.activity.AddTag(key, value); } } diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs deleted file mode 100644 index 6bd8c6b520..0000000000 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnricher.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.Extensions.Enrichment; - -public abstract class TraceEnricher : BaseEnricher -{ - protected TraceEnricher() - { - } -} diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs similarity index 93% rename from src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs rename to src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs index e4c05b4ece..987fbc1797 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,9 +22,9 @@ namespace OpenTelemetry.Extensions.Enrichment; /// -/// Extension methods to register telemery enrichers. +/// Extension methods to register telemetry enrichers. /// -public static class OpenTelemetryEnrichmentProviderBuilderExtensions +public static class TraceEnrichmentProviderBuilderExtensions { /// /// Adds trace enricher. @@ -68,7 +68,7 @@ public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder /// Adds trace enricher. /// /// being configured. - /// The delegate to enrich traces. + /// The delegate to enrich traces. /// Thrown when the or is . /// The instance of to chain the calls. /// diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs similarity index 92% rename from src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs rename to src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs index 4738a2940e..cf79a3c914 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetryEnrichmentServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,9 +24,9 @@ namespace Microsoft.Extensions.DependencyInjection; /// -/// Extension methods to register telemery enrichers. +/// Extension methods to register telemetry enrichers. /// -public static class OpenTelemetryEnrichmentServiceCollectionExtensions +public static class TraceEnrichmentServiceCollectionExtensions { /// /// Adds trace enricher. @@ -72,7 +72,7 @@ public static IServiceCollection AddTraceEnricher(this IServiceCollection servic /// Adds trace enricher. /// /// being configured. - /// The delegate to enrich traces. + /// The delegate to enrich traces. /// Thrown when the or is . /// The instance of to chain the calls. /// @@ -83,7 +83,7 @@ public static IServiceCollection AddTraceEnricher(this IServiceCollection servic Guard.ThrowIfNull(services); Guard.ThrowIfNull(enrichmentAction); - services.TryAddSingleton(); + services.TryAddSingleton(); return services .TryAddEnrichment() diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs index 35a4c8fe3d..3cf9308ac4 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs @@ -22,8 +22,8 @@ internal class MyTraceEnricher : TraceEnricher public int TimesCalled { get; private set; } - public override void Enrich(in TraceEnrichmentBag enrichmentBag) + public override void Enrich(in TraceEnrichmentBag bag) { - enrichmentBag.Add(Key, ++this.TimesCalled); + bag.Add(Key, ++this.TimesCalled); } } diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs index fd50a9d61b..740f2e3857 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs @@ -22,8 +22,8 @@ internal class MyTraceEnricher2 : TraceEnricher public int TimesCalled { get; private set; } - public override void Enrich(in TraceEnrichmentBag enrichmentBag) + public override void Enrich(in TraceEnrichmentBag bag) { - enrichmentBag.Add(Key, ++this.TimesCalled); + bag.Add(Key, ++this.TimesCalled); } } diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 3b73750d9c..60e65e091c 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -3,7 +3,8 @@ Unit test project for OpenTelemetry .NET SDK telemetry enrichment. - $(NetFrameworkMinimumSupportedVersion) + net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 39224da6bcf89f0b0fc58431349916e4d663b622 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Wed, 22 Nov 2023 00:31:26 +0200 Subject: [PATCH 0875/1499] Fix ActivityTraceFlags assertion (#1441) --- .../EntityFrameworkDiagnosticListenerTests.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index fe1f86cbe4..2d8f653c64 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -153,7 +153,7 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByDbCommand() var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; Assert.False(activity.IsAllDataRequested); - Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.None)); + Assert.False(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); } [Fact] @@ -220,7 +220,7 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByProviderName(st var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; Assert.False(activity.IsAllDataRequested); - Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.None)); + Assert.False(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); } [Fact] @@ -323,9 +323,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity( b => { - b.Property("Id"); - b.HasKey("Id"); b.Property(e => e.Name); + b.HasKey("Name"); }); } } From 5167fbe0e2934895d32034cb2cb75cc44e3ec6c3 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:22:48 -0800 Subject: [PATCH 0876/1499] Updates for .NET 8 code analysis - Part 1 (#1443) --- .../Internal/ConnectionStringBuilder.cs | 2 +- .../Metrics/GenevaMetricExporterExtensions.cs | 2 +- .../MsgPackExporter/MsgPackTraceExporter.cs | 6 +++--- .../TLDExporter/TldLogExporter.cs | 4 ++-- .../TLDExporter/TldTraceExporter.cs | 4 ++-- .../Internal/CallbackManager.cs | 4 ++++ .../Internal/Transports/HttpJsonPostTransport.cs | 2 +- .../Logs/OneCollectorLogExportProcessorBuilder.cs | 4 +++- .../OpenTelemetry.Exporter.OneCollector.csproj | 4 ++++ .../FileBlobProvider.cs | 2 +- .../AppServiceResourceDetector.cs | 4 ++++ src/Shared/PropertyFetcher.AOT.cs | 2 +- .../EventSourceTestHelper.cs | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../GenevaMetricExporterTests.cs | 2 ++ .../GenevaTraceExporterTests.cs | 2 ++ .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 - .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 4 ++++ .../ProcessMetricsTests.cs | 6 ++++-- 19 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 2b82ad3e50..3b26ba9676 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -104,7 +104,7 @@ public TransportProtocol Protocol if (this._parts.ContainsKey(nameof(this.EtwSession))) { _ = this._parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var privatePreviewEnableTraceLoggingDynamic); - if (privatePreviewEnableTraceLoggingDynamic != null && privatePreviewEnableTraceLoggingDynamic.ToUpperInvariant() == bool.TrueString.ToUpperInvariant()) + if (privatePreviewEnableTraceLoggingDynamic != null && privatePreviewEnableTraceLoggingDynamic.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) { return TransportProtocol.EtwTld; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 4933ad7a62..028f38d651 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -67,7 +67,7 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui }); } - private static MetricReader BuildGenevaMetricExporter(GenevaMetricExporterOptions options, Action configure = null) + private static PeriodicExportingMetricReader BuildGenevaMetricExporter(GenevaMetricExporterOptions options, Action configure = null) { configure?.Invoke(options); return new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 2a8ad9efb5..5b97abc8f3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -403,7 +403,7 @@ public void Dispose() private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary + private static readonly Dictionary CS40_PART_B_MAPPING = new Dictionary { ["db.system"] = "dbSystem", ["db.name"] = "dbName", @@ -435,9 +435,9 @@ public void Dispose() private readonly IDataTransport m_dataTransport; - private readonly IReadOnlyDictionary m_customFields; + private readonly Dictionary m_customFields; - private readonly IReadOnlyDictionary m_dedicatedFields; + private readonly Dictionary m_dedicatedFields; private bool isDisposed; } diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 4ba7a2a465..31d696bda6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -46,8 +46,8 @@ internal sealed class TldLogExporter : TldExporter, IDisposable private readonly byte partAFieldsCount = 1; // At least one field: time private readonly bool shouldPassThruTableMappings; private readonly string defaultEventName = "Log"; - private readonly IReadOnlyDictionary customFields; - private readonly IReadOnlyDictionary tableMappings; + private readonly Dictionary customFields; + private readonly Dictionary tableMappings; private readonly Tuple repeatedPartAFields; private readonly ExceptionStackExportMode exceptionStackExportMode; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index f7338114b5..472a8e1757 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -34,7 +34,7 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - private static readonly IReadOnlyDictionary CS40_PART_B_MAPPING = new Dictionary + private static readonly Dictionary CS40_PART_B_MAPPING = new Dictionary { ["db.system"] = "dbSystem", ["db.name"] = "dbName", @@ -54,7 +54,7 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable private readonly string partAName = "Span"; private readonly byte partAFieldsCount = 3; // At least three fields: time, ext_dt_traceId, ext_dt_spanId - private readonly IReadOnlyDictionary m_customFields; + private readonly Dictionary m_customFields; private readonly Tuple repeatedPartAFields; private readonly EventProvider eventProvider; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs index a545bce80a..40c5e17465 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs @@ -33,10 +33,14 @@ public IDisposable Add(T callback) lock (this.lockObject) { +#if NET7_0_OR_GREATER + ObjectDisposedException.ThrowIf(this.disposed, nameof(CallbackManager)); +#else if (this.disposed) { throw new ObjectDisposedException(nameof(CallbackManager)); } +#endif this.root = (T)Delegate.Combine(this.root, callback); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index 1e3698f6b1..4df899a238 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -178,7 +178,7 @@ public bool Send(in TransportSendRequest sendRequest) } } - private HttpContent BuildRequestContent(Stream stream) + private NonDisposingStreamContent BuildRequestContent(Stream stream) { switch (this.compressionType) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs index 841bdcdeca..28528d8297 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs @@ -202,7 +202,9 @@ internal BaseProcessor BuildProcessor() private OneCollectorExporter BuildExporter() { +#pragma warning disable CA2000 // Dispose objects before losing scope var exporter = new OneCollectorExporter(this.CreateSink()); +#pragma warning restore CA2000 // Dispose objects before losing scope try { @@ -222,7 +224,7 @@ private OneCollectorExporter BuildExporter() return exporter; } - private ISink CreateSink() + private WriteDirectlyToTransportSink CreateSink() { this.exporterOptions.Validate(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 131227e781..e3b1d699cd 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -16,6 +16,10 @@ + + + + diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index e24ecc7a4b..dc0b7a154a 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -202,7 +202,7 @@ private bool CheckStorageSize() return true; } - private PersistentBlob? CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) + private FileBlob? CreateFileBlob(byte[] buffer, int leasePeriodMilliseconds = 0) { if (!this.CheckStorageSize()) { diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index 1be89789d2..797aa8eb36 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -80,7 +80,11 @@ public Resource Detect() string? websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); string websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty; +#if NET6_0_OR_GREATER + int idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal); +#else int idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal); +#endif string subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName; if (string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId)) diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index e617720f3c..25cc264df6 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -187,7 +187,7 @@ public abstract bool TryFetch( // 2. Then, the declared object type is passed as a generic parameter to a generic method on PropertyFetcher (or nested type.) // Therefore, calling into MakeGenericMethod will only require specifying one parameter - the declared object type. // The declared object type is guaranteed to be a reference type (throw on value type.) Thus, MakeGenericMethod is AOT compatible. - private static PropertyFetch CreateInstantiated(PropertyInfo propertyInfo) + private static PropertyFetchInstantiated CreateInstantiated(PropertyInfo propertyInfo) where TDeclaredObject : class => new PropertyFetchInstantiated(propertyInfo); diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs index 740782be5e..f330fcab7f 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -145,6 +145,6 @@ private static EventAttribute GetEventAttribute(MethodInfo eventMethod) private static IEnumerable GetEventMethods(EventSource eventSource) { MethodInfo[] methods = eventSource.GetType().GetMethods(); - return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Any()); + return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Length != 0); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index ea8a9bfe63..415e6cb8a0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -12,8 +12,8 @@ + - diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index cf6b224834..0ec3ab0018 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -34,6 +34,7 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; +#pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array public class GenevaMetricExporterTests { [Fact] @@ -1421,3 +1422,4 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter return result; } } +#pragma warning restore CA1861 // // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 7d9dbde3d0..f79e4fb278 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -509,7 +509,9 @@ public void TLDTraceExporter_Success_Windows() { activity?.SetTag("foo", 1); activity?.SetTag("bar", "Hello, World!"); +#pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array activity?.SetTag("baz", new int[] { 1, 2, 3 }); +#pragma warning restore CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array activity?.SetStatus(ActivityStatusCode.Ok); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index bfffacbcc4..df2ddc2b8c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -16,7 +16,6 @@ - diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 67ad9a00f3..74ac99546d 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -16,6 +16,10 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 0ba48f3151..819e634f94 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -94,11 +94,13 @@ public void CpuTimeMetricsAreCaptured() { foreach (var tag in points.Current.Tags) { - if (tag.Key == "state" && tag.Value.ToString() == "user") + Assert.NotNull(tag.Value); + + if (tag.Key == "state" && tag.Value!.ToString() == "user") { userTimeCaptured = true; } - else if (tag.Key == "state" && tag.Value.ToString() == "system") + else if (tag.Key == "state" && tag.Value!.ToString() == "system") { systemTimeCaptured = true; } From 669f8b7fb92a14b901690db5beddf3f8e00aee6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 27 Nov 2023 10:55:18 +0100 Subject: [PATCH 0877/1499] Resource detector - ProcessRuntime --- .../comp_resourcedetectors_processruntime.md | 41 ++++++++++++++++ .github/codecov.yml | 5 ++ .github/component_owners.yml | 6 +++ .github/workflows/ci.yml | 16 +++++++ ...ckage-ResourceDetectors.ProcessRuntime.yml | 21 +++++++++ ...etry.ResourceDetectors.ProcessRuntime.proj | 32 +++++++++++++ opentelemetry-dotnet-contrib.sln | 15 ++++++ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 ++ .../AssemblyInfo.cs | 23 +++++++++ .../CHANGELOG.md | 6 +++ ...ry.ResourceDetectors.ProcessRuntime.csproj | 12 +++++ .../ProcessRuntimeDetector.cs | 47 +++++++++++++++++++ .../ProcessRuntimeSemanticConventions.cs | 24 ++++++++++ .../README.md | 42 +++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + ...ourceDetectors.ProcessRuntime.Tests.csproj | 14 ++++++ .../ProcessRuntimeDetectorTests.cs | 45 ++++++++++++++++++ 20 files changed, 358 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md create mode 100644 .github/workflows/package-ResourceDetectors.ProcessRuntime.yml create mode 100644 build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md create mode 100644 test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj create mode 100644 test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md new file mode 100644 index 0000000000..260e428834 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.ResourceDetectors.ProcessRuntime +about: OpenTelemetry.ResourceDetectors.ProcessRuntime +labels: comp:resourcedetectors.processruntime +--- + +# Issue with OpenTelemetry.ResourceDetectors.ProcessRuntime + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 25a4fe986f..28e08db161 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -98,3 +98,8 @@ flags: carryforward: true paths: - src/OpenTelemetry.ResourceDetectors.Azure + + unittests-ResourceDetectors.ProcessRuntime: + carryforward: true + paths: + - src/OpenTelemetry.ResourceDetectors.ProcessRuntime diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 785de6af2f..ba09d34efb 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -65,6 +65,9 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev + src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: + - Kielek + - lachmatt src/OpenTelemetry.Sampler.AWS/: - srprash - atshaw43 @@ -141,6 +144,9 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev + test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: + - Kielek + - lachmatt test/OpenTelemetry.Sampler.AWS.Tests/: - srprash - atshaw43 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b12146178..c1c3998bf8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] + processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] @@ -42,6 +43,7 @@ jobs: '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', + '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions*/**', @@ -175,6 +177,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Process code-cov-name: Instrumentation.Process + build-test-processruntime: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'processruntime') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime + code-cov-name: ResourceDetectors.ProcessRuntime + build-test-redis: needs: detect-changes if: | @@ -258,6 +271,7 @@ jobs: OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj + OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj ForEach ($project in $projects) { @@ -287,6 +301,7 @@ jobs: contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') || contains(needs.detect-changes.outputs.changes, 'azure') + || contains(needs.detect-changes.outputs.changes, 'processruntime') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'redis') @@ -308,6 +323,7 @@ jobs: build-test-owin, build-test-persistentstorage, build-test-process, + build-test-processruntime, build-test-redis, build-test-redis-integration, build-test-runtime, diff --git a/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml b/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml new file mode 100644 index 0000000000..9a27442a8c --- /dev/null +++ b/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.ResourceDetectors.ProcessRuntime + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'ResourceDetectors.ProcessRuntime-*' # trigger when we create a tag with prefix "ResourceDetectors.ProcessRuntime-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime + secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj new file mode 100644 index 0000000000..c3d9bb68a4 --- /dev/null +++ b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6435228624..704aecbde9 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -313,8 +313,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj + build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime", "src\OpenTelemetry.ResourceDetectors.ProcessRuntime\OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests", "test\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -633,6 +638,14 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.Build.0 = Release|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.Build.0 = Release|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -729,6 +742,8 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a4c8a74d8a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a4c8a74d8a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs new file mode 100644 index 0000000000..fd4de980dc --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md new file mode 100644 index 0000000000..a8bf4cb7aa --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## Unreleased + +* Initial release of `OpenTelemetry.ResourceDetectors.ProcessRuntime` project +[1449](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1449) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj new file mode 100644 index 0000000000..6b927b2a3f --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj @@ -0,0 +1,12 @@ + + + + net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Extensions - Process Runtime Resource Detector from .NET runtime. + ResourceDetectors.ProcessRuntime- + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs new file mode 100644 index 0000000000..c326abb3f0 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs @@ -0,0 +1,47 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using OpenTelemetry.ResourceDetectors.Container; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.ResourceDetectors.ProcessRuntime; + +/// +/// Process runtime detector. +/// +public class ProcessRuntimeDetector : IResourceDetector +{ + /// + /// Detects the resource attributes from .NET runtime. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + return new Resource(new List>(3) + { + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription, RuntimeInformation.FrameworkDescription), +#if NETFRAMEWORK + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName, ".NET Framework"), +#else + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName, ".NET"), +#endif + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion, Environment.Version.ToString()), + }); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs new file mode 100644 index 0000000000..f423065c19 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs @@ -0,0 +1,24 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.ResourceDetectors.Container; + +internal static class ProcessRuntimeSemanticConventions +{ + public const string AttributeProcessRuntimeDescription = "process.runtime.description"; + public const string AttributeProcessRuntimeName = "process.runtime.name"; + public const string AttributeProcessRuntimeVersion = "process.runtime.version"; +} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md new file mode 100644 index 0000000000..cf2e7971fe --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md @@ -0,0 +1,42 @@ +# Container Resource Detectors + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) + +## Getting Started + +You need to install the +`OpenTelemetry.ResourceDetectors.ProcessRuntime` to be able to use the +Process Runtime Resource Detectors. It `process.runtime.description`, `process.runtime.name`, +and `process.runtime.version` from .NET runtime. + +```shell +dotnet add package OpenTelemetry.ResourceDetectors.ProcessRuntime --prerelease +``` + +## Usage + +You can configure Container resource detector to +the `TracerProvider` with the following example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.Container; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .SetResourceBuilder(ResourceBuilder + .CreateEmpty() + .AddDetector(new ProcessRuntimeDetector())) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **ProcessRuntimeDetector**: `process.runtime.description`, `process.runtime.name`, + and `process.runtime.version`. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index a3516672cc..1fc7d8dc89 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -17,6 +17,7 @@ + diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj new file mode 100644 index 0000000000..8e7a853bc6 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj @@ -0,0 +1,14 @@ + + + + Unit test project for Process Runtime Detector for OpenTelemetry + + net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs new file mode 100644 index 0000000000..2c1e23e4fc --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs @@ -0,0 +1,45 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Linq; +using OpenTelemetry.ResourceDetectors.Container; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests; + +public class ProcessRuntimeDetectorTests +{ + [Fact] + public void TestProcessRuntimeAttributes() + { + var resource = ResourceBuilder.CreateEmpty().AddDetector(new ProcessRuntimeDetector()).Build(); + + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + + Assert.Equal(3, resourceAttributes.Count); + +#if NETFRAMEWORK + Assert.Matches(@"^\.NET Framework \d+\.\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription]); + Assert.Equal(".NET Framework", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName]); + Assert.Matches(@"^\d+\.\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion]); +#else + Assert.Matches(@"^\.NET \d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription]); + Assert.Equal(".NET", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName]); + Assert.Matches(@"^\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion]); +#endif + } +} From c3a4f335f5a1f4fc784d44cc99b5bf44e872a66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 27 Nov 2023 10:58:31 +0100 Subject: [PATCH 0878/1499] Revert "Resource detector - ProcessRuntime" This reverts commit 669f8b7fb92a14b901690db5beddf3f8e00aee6f. --- .../comp_resourcedetectors_processruntime.md | 41 ---------------- .github/codecov.yml | 5 -- .github/component_owners.yml | 6 --- .github/workflows/ci.yml | 16 ------- ...ckage-ResourceDetectors.ProcessRuntime.yml | 21 --------- ...etry.ResourceDetectors.ProcessRuntime.proj | 32 ------------- opentelemetry-dotnet-contrib.sln | 15 ------ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 -- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 -- .../AssemblyInfo.cs | 23 --------- .../CHANGELOG.md | 6 --- ...ry.ResourceDetectors.ProcessRuntime.csproj | 12 ----- .../ProcessRuntimeDetector.cs | 47 ------------------- .../ProcessRuntimeSemanticConventions.cs | 24 ---------- .../README.md | 42 ----------------- ...nTelemetry.AotCompatibility.TestApp.csproj | 1 - ...ourceDetectors.ProcessRuntime.Tests.csproj | 14 ------ .../ProcessRuntimeDetectorTests.cs | 45 ------------------ 20 files changed, 358 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md delete mode 100644 .github/workflows/package-ResourceDetectors.ProcessRuntime.yml delete mode 100644 build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md delete mode 100644 test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj delete mode 100644 test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md deleted file mode 100644 index 260e428834..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.ProcessRuntime -about: OpenTelemetry.ResourceDetectors.ProcessRuntime -labels: comp:resourcedetectors.processruntime ---- - -# Issue with OpenTelemetry.ResourceDetectors.ProcessRuntime - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 28e08db161..25a4fe986f 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -98,8 +98,3 @@ flags: carryforward: true paths: - src/OpenTelemetry.ResourceDetectors.Azure - - unittests-ResourceDetectors.ProcessRuntime: - carryforward: true - paths: - - src/OpenTelemetry.ResourceDetectors.ProcessRuntime diff --git a/.github/component_owners.yml b/.github/component_owners.yml index ba09d34efb..785de6af2f 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -65,9 +65,6 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev - src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: - - Kielek - - lachmatt src/OpenTelemetry.Sampler.AWS/: - srprash - atshaw43 @@ -144,9 +141,6 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev - test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: - - Kielek - - lachmatt test/OpenTelemetry.Sampler.AWS.Tests/: - srprash - atshaw43 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1c3998bf8..8b12146178 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,6 @@ jobs: owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] - processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] @@ -43,7 +42,6 @@ jobs: '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', - '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions*/**', @@ -177,17 +175,6 @@ jobs: project-name: OpenTelemetry.Instrumentation.Process code-cov-name: Instrumentation.Process - build-test-processruntime: - needs: detect-changes - if: | - contains(needs.detect-changes.outputs.changes, 'processruntime') - || contains(needs.detect-changes.outputs.changes, 'build') - || contains(needs.detect-changes.outputs.changes, 'shared') - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime - code-cov-name: ResourceDetectors.ProcessRuntime - build-test-redis: needs: detect-changes if: | @@ -271,7 +258,6 @@ jobs: OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj - OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj ForEach ($project in $projects) { @@ -301,7 +287,6 @@ jobs: contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') || contains(needs.detect-changes.outputs.changes, 'azure') - || contains(needs.detect-changes.outputs.changes, 'processruntime') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'redis') @@ -323,7 +308,6 @@ jobs: build-test-owin, build-test-persistentstorage, build-test-process, - build-test-processruntime, build-test-redis, build-test-redis-integration, build-test-runtime, diff --git a/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml b/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml deleted file mode 100644 index 9a27442a8c..0000000000 --- a/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Pack OpenTelemetry.ResourceDetectors.ProcessRuntime - -on: - workflow_dispatch: - inputs: - logLevel: - description: 'Log level' - required: true - default: 'warning' - push: - tags: - - 'ResourceDetectors.ProcessRuntime-*' # trigger when we create a tag with prefix "ResourceDetectors.ProcessRuntime-" - -jobs: - call-build-test-pack: - permissions: - contents: write - uses: ./.github/workflows/Component.Package.yml - with: - project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime - secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj deleted file mode 100644 index c3d9bb68a4..0000000000 --- a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj +++ /dev/null @@ -1,32 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 704aecbde9..6435228624 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -313,13 +313,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj - build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime", "src\OpenTelemetry.ResourceDetectors.ProcessRuntime\OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests", "test\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -638,14 +633,6 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.Build.0 = Release|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.Build.0 = Release|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -742,8 +729,6 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index a4c8a74d8a..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a4c8a74d8a..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs deleted file mode 100644 index fd4de980dc..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests")] -#endif diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md deleted file mode 100644 index a8bf4cb7aa..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ /dev/null @@ -1,6 +0,0 @@ -# Changelog - -## Unreleased - -* Initial release of `OpenTelemetry.ResourceDetectors.ProcessRuntime` project -[1449](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1449) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj deleted file mode 100644 index 6b927b2a3f..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - net6.0 - $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry Extensions - Process Runtime Resource Detector from .NET runtime. - ResourceDetectors.ProcessRuntime- - - - - - diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs deleted file mode 100644 index c326abb3f0..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using OpenTelemetry.ResourceDetectors.Container; -using OpenTelemetry.Resources; - -namespace OpenTelemetry.ResourceDetectors.ProcessRuntime; - -/// -/// Process runtime detector. -/// -public class ProcessRuntimeDetector : IResourceDetector -{ - /// - /// Detects the resource attributes from .NET runtime. - /// - /// Resource with key-value pairs of resource attributes. - public Resource Detect() - { - return new Resource(new List>(3) - { - new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription, RuntimeInformation.FrameworkDescription), -#if NETFRAMEWORK - new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName, ".NET Framework"), -#else - new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName, ".NET"), -#endif - new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion, Environment.Version.ToString()), - }); - } -} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs deleted file mode 100644 index f423065c19..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -namespace OpenTelemetry.ResourceDetectors.Container; - -internal static class ProcessRuntimeSemanticConventions -{ - public const string AttributeProcessRuntimeDescription = "process.runtime.description"; - public const string AttributeProcessRuntimeName = "process.runtime.name"; - public const string AttributeProcessRuntimeVersion = "process.runtime.version"; -} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md deleted file mode 100644 index cf2e7971fe..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Container Resource Detectors - -[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) - -## Getting Started - -You need to install the -`OpenTelemetry.ResourceDetectors.ProcessRuntime` to be able to use the -Process Runtime Resource Detectors. It `process.runtime.description`, `process.runtime.name`, -and `process.runtime.version` from .NET runtime. - -```shell -dotnet add package OpenTelemetry.ResourceDetectors.ProcessRuntime --prerelease -``` - -## Usage - -You can configure Container resource detector to -the `TracerProvider` with the following example below. - -```csharp -using OpenTelemetry; -using OpenTelemetry.ResourceDetectors.Container; - -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .SetResourceBuilder(ResourceBuilder - .CreateEmpty() - .AddDetector(new ProcessRuntimeDetector())) - .Build(); -``` - -The resource detectors will record the following metadata based on where -your application is running: - -- **ProcessRuntimeDetector**: `process.runtime.description`, `process.runtime.name`, - and `process.runtime.version`. - -## References - -- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 1fc7d8dc89..a3516672cc 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -17,7 +17,6 @@ - diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj deleted file mode 100644 index 8e7a853bc6..0000000000 --- a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - Unit test project for Process Runtime Detector for OpenTelemetry - - net7.0;net6.0 - $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - - - - - - - diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs deleted file mode 100644 index 2c1e23e4fc..0000000000 --- a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -using System.Linq; -using OpenTelemetry.ResourceDetectors.Container; -using OpenTelemetry.Resources; -using Xunit; - -namespace OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests; - -public class ProcessRuntimeDetectorTests -{ - [Fact] - public void TestProcessRuntimeAttributes() - { - var resource = ResourceBuilder.CreateEmpty().AddDetector(new ProcessRuntimeDetector()).Build(); - - var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); - - Assert.Equal(3, resourceAttributes.Count); - -#if NETFRAMEWORK - Assert.Matches(@"^\.NET Framework \d+\.\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription]); - Assert.Equal(".NET Framework", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName]); - Assert.Matches(@"^\d+\.\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion]); -#else - Assert.Matches(@"^\.NET \d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription]); - Assert.Equal(".NET", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName]); - Assert.Matches(@"^\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion]); -#endif - } -} From f97fbe621ea561d8b7ea3f928de1cd13c1e49abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 29 Nov 2023 00:10:18 +0100 Subject: [PATCH 0879/1499] Martin Thwaites - triager (#1444) --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index d7a0adb7bd..ec824a8a1e 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,14 @@ who can help with reviews and code approval. However, as individual components are developed by numerous contributors, approvers and maintainers are not expected to directly contribute to every component. +Triagers +([@open-telemetry/dotnet-contrib-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-triagers)): + +* [Martin Thwaites](https://github.com/martinjt), Honeycomb + +*Find more about the triager role in [community +repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager).* + Approvers ([@open-telemetry/dotnet-contrib-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers)): From 425ce6613c5b388b3d4cbde19c69cebbb61618d6 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:46:57 -0800 Subject: [PATCH 0880/1499] Updates for .NET 8 code analysis - Part 2 (#1446) --- .github/workflows/integration.yml | 2 +- build/docker-compose.net6.0.yml | 4 ++-- build/docker-compose.net7.0.yml | 4 ++-- build/docker-compose.net8.0.yml | 9 +++++++++ examples/AspNet/Global.asax.cs | 4 ++-- examples/wcf/server-aspnetframework/Global.asax.cs | 2 +- global.json | 2 +- opentelemetry-dotnet-contrib.sln | 1 + .../Internal/Transports/HttpJsonPostTransport.cs | 3 +++ .../Internal/Transports/IHttpClient.cs | 4 ++++ .../Logs/OneCollectorLogExportProcessorBuilder.cs | 3 +++ .../TracerProviderBuilderExtensions.cs | 4 ++++ .../Implementation/AWSLambdaHttpUtils.cs | 2 ++ .../HangfireInstrumentationJobFilterAttribute.cs | 4 ++-- .../AWSECSResourceDetector.cs | 2 ++ .../InfluxDBMetricsExporterTests.cs | 5 +++-- .../Utils/LineProtocolParser.cs | 2 ++ .../LogRecordCommonSchemaJsonHttpPostBenchmarks.cs | 3 +++ .../HttpJsonPostTransportTests.cs | 3 +++ .../Tools/MockWebResponse.cs | 4 +++- .../Implementation/AWSLambdaHttpUtilsTests.cs | 6 ++++++ .../EntityFrameworkDiagnosticListenerTests.cs | 2 +- .../Dockerfile | 6 +++--- .../RedisProfilerEntryToActivityConverterTests.cs | 2 +- ...metry.Instrumentation.StackExchangeRedis.Tests.csproj | 2 +- .../StackExchangeRedisCallsInstrumentationTests.cs | 4 ++-- .../AWSECSResourceDetectorTests.cs | 4 ++++ 27 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 build/docker-compose.net8.0.yml diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 050da674c3..17fc8a9da9 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - version: [net6.0,net7.0] + version: [net6.0, net7.0, net8.0] steps: - uses: actions/checkout@v4 diff --git a/build/docker-compose.net6.0.yml b/build/docker-compose.net6.0.yml index 0d59259753..099f100727 100644 --- a/build/docker-compose.net6.0.yml +++ b/build/docker-compose.net6.0.yml @@ -5,5 +5,5 @@ services: build: args: PUBLISH_FRAMEWORK: net6.0 - TEST_SDK_VERSION: 6.0 - BUILD_SDK_VERSION: 7.0 + TEST_SDK_VERSION: "6.0" + BUILD_SDK_VERSION: "8.0" diff --git a/build/docker-compose.net7.0.yml b/build/docker-compose.net7.0.yml index d79fa366bb..48a2589cda 100644 --- a/build/docker-compose.net7.0.yml +++ b/build/docker-compose.net7.0.yml @@ -5,5 +5,5 @@ services: build: args: PUBLISH_FRAMEWORK: net7.0 - TEST_SDK_VERSION: 7.0 - BUILD_SDK_VERSION: 7.0 + TEST_SDK_VERSION: "7.0" + BUILD_SDK_VERSION: "8.0" diff --git a/build/docker-compose.net8.0.yml b/build/docker-compose.net8.0.yml new file mode 100644 index 0000000000..a5ac999e43 --- /dev/null +++ b/build/docker-compose.net8.0.yml @@ -0,0 +1,9 @@ +version: '3.7' + +services: + tests: + build: + args: + PUBLISH_FRAMEWORK: net8.0 + TEST_SDK_VERSION: "8.0" + BUILD_SDK_VERSION: "8.0" diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index e8318035b9..ba77e849f4 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -31,8 +31,8 @@ namespace Examples.AspNet; public class WebApiApplication : HttpApplication #pragma warning restore SA1649 // File name should match first type name { - private IDisposable? tracerProvider; - private IDisposable? meterProvider; + private TracerProvider? tracerProvider; + private MeterProvider? meterProvider; protected void Application_Start() { diff --git a/examples/wcf/server-aspnetframework/Global.asax.cs b/examples/wcf/server-aspnetframework/Global.asax.cs index 692259cc99..0546cd33fb 100644 --- a/examples/wcf/server-aspnetframework/Global.asax.cs +++ b/examples/wcf/server-aspnetframework/Global.asax.cs @@ -29,7 +29,7 @@ namespace Examples.Wcf.Server.AspNetFramework; public class WebApiApplication : HttpApplication #pragma warning restore SA1649 // File name should match first type name { - private IDisposable? tracerProvider; + private TracerProvider? tracerProvider; protected void Application_Start() { diff --git a/global.json b/global.json index aeb8ae7b1e..0aca8b1293 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestFeature", - "version": "7.0.400" + "version": "8.0.100" } } diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6435228624..e58e0c5f4c 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -75,6 +75,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\debug.snk = build\debug.snk 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\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index 4df899a238..c9754c1752 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -17,6 +17,9 @@ using System.Diagnostics; using System.IO.Compression; using System.Net; +#if NETFRAMEWORK +using System.Net.Http; +#endif using System.Net.Http.Headers; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs index 66dff2933b..ec344e7826 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs @@ -14,6 +14,10 @@ // limitations under the License. // +#if NETFRAMEWORK +using System.Net.Http; +#endif + namespace OpenTelemetry.Exporter.OneCollector; internal interface IHttpClient diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs index 28528d8297..99d9b23398 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs @@ -14,6 +14,9 @@ // limitations under the License. // +#if NETFRAMEWORK +using System.Net.Http; +#endif using Microsoft.Extensions.Configuration; using OpenTelemetry.Exporter.OneCollector; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index a21b3af4d8..f105c9243b 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -47,10 +47,14 @@ public static TracerProviderBuilder AddAutoFlushActivityProcessor( Func predicate, int timeoutMilliseconds = 10000) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(builder); +#else if (builder == null) { throw new ArgumentNullException(nameof(builder)); } +#endif #pragma warning disable CA2000 // Dispose objects before losing scope return builder.AddProcessor(new AutoFlushActivityProcessor(predicate, timeoutMilliseconds)); diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index dc1d068658..d0633e2979 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -124,7 +124,9 @@ internal static (string? Host, int? Port) GetHostAndPort(string? httpScheme, str return (null, null); } +#pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array var hostAndPort = hostHeader.Split(new char[] { ':' }, 2); +#pragma warning restore CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array if (hostAndPort.Length > 1) { var host = hostAndPort[0]; diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index b161bfe284..3312ec136b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -76,12 +76,12 @@ public void OnPerforming(PerformingContext performingContext) public void OnPerformed(PerformedContext performedContext) { // Short-circuit if nobody is listening - if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.ContainsKey(HangfireInstrumentationConstants.ActivityKey)) + if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.TryGetValue(HangfireInstrumentationConstants.ActivityKey, out var value)) { return; } - if (performedContext.Items[HangfireInstrumentationConstants.ActivityKey] is Activity activity) + if (value is Activity activity) { if (performedContext.Exception != null) { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index 5e59597d3e..2784b94c47 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -106,7 +106,9 @@ internal static List> ExtractMetadataV4ResourceAttr if (!clusterArn.StartsWith("arn:", StringComparison.Ordinal)) { +#pragma warning disable CA1865 // Use string.LastIndexOf(char) instead of string.LastIndexOf(string) when you have string with a single char var baseArn = containerArn.Substring(containerArn.LastIndexOf(":", StringComparison.Ordinal)); +#pragma warning restore CA1865 // Use string.LastIndexOf(char) instead of string.LastIndexOf(string) when you have string with a single char clusterArn = $"{baseArn}:cluster/{clusterArn}"; } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs index c65d10534b..d2b6ff6332 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -25,6 +25,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests; public class InfluxDBMetricsExporterTests { private static readonly string OpenTelemetrySdkVersion; + private static readonly double[] TestBoundaries = new[] { 10D, 20D, 100D, 200D }; #pragma warning disable CA1810 // Initialize reference type static fields inline static InfluxDBMetricsExporterTests() @@ -312,7 +313,7 @@ public void ExportHistogramMetricWhenTelegrafPrometheusV1MetricsSchemaUsed() .AddMeter(meter.Name) .AddView("histogram_metric", new ExplicitBucketHistogramConfiguration { - Boundaries = new[] { 10D, 20D, 100D, 200D }, + Boundaries = TestBoundaries, RecordMinMax = true, }) .ConfigureDefaultTestResource() @@ -403,7 +404,7 @@ public void ExportHistogramMetricWhenTelegrafPrometheusV2MetricsSchemaUsed() .AddMeter(meter.Name) .AddView("histogram_metric", new ExplicitBucketHistogramConfiguration { - Boundaries = new[] { 10D, 20D, 100D, 200D }, + Boundaries = TestBoundaries, RecordMinMax = true, }) .ConfigureDefaultTestResource() diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs index 97764fbbdf..bca009a4f1 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs @@ -75,11 +75,13 @@ private static object ParseFieldValue(string fieldValue) return boolValue; } +#pragma warning disable CA1865 // Use char overload if (fieldValue.EndsWith("i", StringComparison.Ordinal) && long.TryParse(fieldValue.AsSpan(0, fieldValue.Length - 1).ToString(), out long intValue)) { return intValue; } +#pragma warning restore CA1865 // Use char overload if (double.TryParse(fieldValue, NumberStyles.Float, CultureInfo.InvariantCulture, out double doubleValue)) { diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index 05762f02a2..21c2c60ead 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -16,6 +16,9 @@ using System.Diagnostics; using System.Net; +#if NETFRAMEWORK +using System.Net.Http; +#endif using System.Reflection; using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index 736ef9a848..25f535d6e8 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -16,6 +16,9 @@ using System.IO.Compression; using System.Net; +#if NETFRAMEWORK +using System.Net.Http; +#endif using System.Text; using OpenTelemetry.Tests; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 89c4206bf8..7f89215775 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -115,7 +115,7 @@ public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary< } } - httpResponseMessage.StatusCode = statusCode; + httpResponseMessage!.StatusCode = statusCode; string dummyJson = "{\"key1\":\"value1\"}"; httpResponseMessage.Content = new StringContent(body ?? dummyJson); // Content should be in Json format else we get exception from downstream unmarshalling return httpResponseMessage; @@ -152,7 +152,9 @@ public static HttpResponse ParseRawReponse(string rawResponse) break; } +#pragma warning disable CA1865 // Use char overload var index = currentLine.IndexOf(":", StringComparison.Ordinal); +#pragma warning restore CA1865 // Use char overload if (index != -1) { var headerKey = currentLine.Substring(0, index); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 5b1ed55399..8b89ded1e0 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -40,7 +40,9 @@ public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() }, MultiValueQueryStringParameters = new Dictionary> { +#pragma warning disable CA1861 // Avoid constant arrays as arguments { "q1", new[] { "value1" } }, +#pragma warning restore CA1861 // Avoid constant arrays as arguments }, RequestContext = new APIGatewayProxyRequest.ProxyRequestContext { @@ -70,7 +72,9 @@ public void GetHttpTags_APIGatewayProxyRequestWithEmptyContext_ReturnsTagsFromRe { MultiValueQueryStringParameters = new Dictionary> { +#pragma warning disable CA1861 // Avoid constant arrays as arguments { "q1", new[] { "value1" } }, +#pragma warning restore CA1861 // Avoid constant arrays as arguments }, HttpMethod = "POST", Path = "/path/test", @@ -251,11 +255,13 @@ public void GetHostAndPort_HostHeader_ReturnsCorrectHostAndPort(string httpSchem [Theory] [InlineData(null, "")] +#pragma warning disable CA1861 // Avoid constant arrays as arguments [InlineData(new string[] { }, "")] [InlineData(new[] { "value1" }, "?name=value1")] [InlineData(new[] { "value$a" }, "?name=value%24a")] [InlineData(new[] { "value 1" }, "?name=value+1")] [InlineData(new[] { "value1", "value2" }, "?name=value1&name=value2")] +#pragma warning restore CA1861 // Avoid constant arrays as arguments public void GetQueryString_APIGatewayProxyRequest_CorrectQueryString(IList values, string expectedQueryString) { var request = new APIGatewayProxyRequest(); diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 2d8f653c64..e162527a20 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -248,7 +248,7 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByProviderName() public void Dispose() => this.connection.Dispose(); - private static DbConnection CreateInMemoryDatabase() + private static SqliteConnection CreateInMemoryDatabase() { var connection = new SqliteConnection("Filename=:memory:"); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile index 945e7a4d9d..a8f86395df 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile @@ -2,12 +2,12 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile . -ARG BUILD_SDK_VERSION=7.0 -ARG TEST_SDK_VERSION=7.0 +ARG BUILD_SDK_VERSION=8.0 +ARG TEST_SDK_VERSION=8.0 FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build ARG PUBLISH_CONFIGURATION=Release -ARG PUBLISH_FRAMEWORK=net7.0 +ARG PUBLISH_FRAMEWORK=net8.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index 84aa7076a4..65df35d8d6 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -33,7 +33,7 @@ namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; public class RedisProfilerEntryToActivityConverterTests : IDisposable { private readonly ConnectionMultiplexer connection; - private readonly IDisposable tracerProvider; + private readonly TracerProvider tracerProvider; public RedisProfilerEntryToActivityConverterTests() { diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 54185af2cd..71970f56c2 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry StackExchangeRedis instrumentation - net7.0;net6.0 + net8.0;net7.0;net6.0 $(TargetFrameworks);net462 $(TARGET_FRAMEWORK) diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 4ac9568f8c..d80d1a0f47 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -108,13 +108,13 @@ public void SuccessfulCommandTest(string value) }; connectionOptions.EndPoints.Add(RedisEndPoint); - IConnectionMultiplexer? connection = null; + ConnectionMultiplexer? connection = null; var activityProcessor = new Mock>(); var sampler = new TestSampler(); using (Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => { - services.TryAddSingleton(sp => + services.TryAddSingleton(sp => { return connection = ConnectionMultiplexer.Connect(connectionOptions); }); diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs index 816505a9e5..16e1c5602a 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs @@ -91,10 +91,12 @@ public async void TestEcsMetadataV4Ec2() Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskFamily], "curltest"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskRevision], "26"); +#pragma warning disable CA1861 // Avoid constant arrays as arguments Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/metadata" }); Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata" }); Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/8f03e41243824aea923aca126495f665" }); Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665" }); +#pragma warning restore CA1861 // Avoid constant arrays as arguments } } @@ -117,10 +119,12 @@ public async void TestEcsMetadataV4Fargate() Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskFamily], "curltest"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskRevision], "3"); +#pragma warning disable CA1861 // Avoid constant arrays as arguments Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupNames], new string[] { "/ecs/containerlogs" }); Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogGroupArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs" }); Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamNames], new string[] { "ecs/curl/cd189a933e5849daa93386466019ab50" }); Assert.NotStrictEqual(resourceAttributes[AWSSemanticConventions.AttributeLogStreamArns], new string[] { "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/containerlogs:log-stream:ecs/curl/cd189a933e5849daa93386466019ab50" }); +#pragma warning restore CA1861 // Avoid constant arrays as arguments } } From 78e43b180756e60b965bd17c06c7aeda19bccf4f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:41:04 -0800 Subject: [PATCH 0881/1499] Update the latest prerelease version of OpenTelemetry SDK (#1437) --- build/Common.props | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 1 - .../GenevaMetricExporterTests.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/build/Common.props b/build/Common.props index 6505e4712b..336a0f6a70 100644 --- a/build/Common.props +++ b/build/Common.props @@ -36,7 +36,7 @@ [3.3.3] [1.1.1,2.0) [1.6.0,2.0) - [1.6.0-rc.1] + [1.7.0-alpha.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 415e6cb8a0..a02e9403d5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -12,7 +12,6 @@ - diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 0ec3ab0018..7f70ab47c9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -300,7 +300,7 @@ public void DisableMetricNameValidationTest(bool disableMetricNameValidation) .AddInMemoryExporter(exportedMetrics) .Build()) { - var counter = meter.CreateCounter("count/invalid"); + var counter = meter.CreateCounter("count+invalid"); counter.Add(1); } From 2c3d5d314195faba775245f71544e8bcd3619ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 1 Dec 2023 19:50:48 +0100 Subject: [PATCH 0882/1499] Resource detector - ProcessRuntime (#1449) --- .../comp_resourcedetectors_processruntime.md | 41 ++++++ .github/codecov.yml | 5 + .github/component_owners.yml | 6 + .github/workflows/ci.yml | 18 ++- ...ckage-ResourceDetectors.ProcessRuntime.yml | 21 +++ ...etry.ResourceDetectors.ProcessRuntime.proj | 32 +++++ opentelemetry-dotnet-contrib.sln | 23 ++++ .../README.md | 8 +- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 + .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 + .../AssemblyInfo.cs | 23 ++++ .../CHANGELOG.md | 6 + ...ry.ResourceDetectors.ProcessRuntime.csproj | 12 ++ .../ProcessRuntimeDetector.cs | 123 ++++++++++++++++++ .../ProcessRuntimeSemanticConventions.cs | 24 ++++ .../README.md | 40 ++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + ...y.ResourceDetectors.Container.Tests.csproj | 2 +- ...ourceDetectors.ProcessRuntime.Tests.csproj | 14 ++ .../ProcessRuntimeDetectorTests.cs | 44 +++++++ 22 files changed, 444 insertions(+), 7 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md create mode 100644 .github/workflows/package-ResourceDetectors.ProcessRuntime.yml create mode 100644 build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md create mode 100644 test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj create mode 100644 test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md new file mode 100644 index 0000000000..260e428834 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.ResourceDetectors.ProcessRuntime +about: OpenTelemetry.ResourceDetectors.ProcessRuntime +labels: comp:resourcedetectors.processruntime +--- + +# Issue with OpenTelemetry.ResourceDetectors.ProcessRuntime + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 25a4fe986f..28e08db161 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -98,3 +98,8 @@ flags: carryforward: true paths: - src/OpenTelemetry.ResourceDetectors.Azure + + unittests-ResourceDetectors.ProcessRuntime: + carryforward: true + paths: + - src/OpenTelemetry.ResourceDetectors.ProcessRuntime diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 785de6af2f..ba09d34efb 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -65,6 +65,9 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev + src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: + - Kielek + - lachmatt src/OpenTelemetry.Sampler.AWS/: - srprash - atshaw43 @@ -141,6 +144,9 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev + test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: + - Kielek + - lachmatt test/OpenTelemetry.Sampler.AWS.Tests/: - srprash - atshaw43 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b12146178..fee10bd637 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] + processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] @@ -42,6 +43,7 @@ jobs: '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', + '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions*/**', @@ -175,6 +177,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Process code-cov-name: Instrumentation.Process + build-test-processruntime: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'processruntime') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime + code-cov-name: ResourceDetectors.ProcessRuntime + build-test-redis: needs: detect-changes if: | @@ -257,7 +270,8 @@ jobs: OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, - OpenTelemetry.ResourceDetectors.Azure.Tests.csproj + OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, + OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj ForEach ($project in $projects) { @@ -287,6 +301,7 @@ jobs: contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') || contains(needs.detect-changes.outputs.changes, 'azure') + || contains(needs.detect-changes.outputs.changes, 'processruntime') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'redis') @@ -308,6 +323,7 @@ jobs: build-test-owin, build-test-persistentstorage, build-test-process, + build-test-processruntime, build-test-redis, build-test-redis-integration, build-test-runtime, diff --git a/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml b/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml new file mode 100644 index 0000000000..9a27442a8c --- /dev/null +++ b/.github/workflows/package-ResourceDetectors.ProcessRuntime.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.ResourceDetectors.ProcessRuntime + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'ResourceDetectors.ProcessRuntime-*' # trigger when we create a tag with prefix "ResourceDetectors.ProcessRuntime-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime + secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj new file mode 100644 index 0000000000..c3d9bb68a4 --- /dev/null +++ b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e58e0c5f4c..1c749e3975 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -37,16 +37,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml + .github\workflows\package-Exporter.InfluxDB.yml = .github\workflows\package-Exporter.InfluxDB.yml .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml .github\workflows\package-Exporter.OneCollector.yml = .github\workflows\package-Exporter.OneCollector.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml + .github\workflows\package-Extensions.AWS.yml = .github\workflows\package-Extensions.AWS.yml .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml .github\workflows\package-Extensions.AzureMonitor.yml = .github\workflows\package-Extensions.AzureMonitor.yml .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml + .github\workflows\package-Extensions.Enrichment.yml = .github\workflows\package-Extensions.Enrichment.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml + .github\workflows\package-Instrumentation.Cassandra.yml = .github\workflows\package-Instrumentation.Cassandra.yml .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml @@ -60,7 +64,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml + .github\workflows\package-ResourceDetectors.AWS.yml = .github\workflows\package-ResourceDetectors.AWS.yml .github\workflows\package-ResourceDetectors.Azure.yml = .github\workflows\package-ResourceDetectors.Azure.yml + .github\workflows\package-ResourceDetectors.Container.yml = .github\workflows\package-ResourceDetectors.Container.yml + .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml + .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml .github\workflows\verifyaotcompat.yml = .github\workflows\verifyaotcompat.yml @@ -314,8 +322,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj + build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime", "src\OpenTelemetry.ResourceDetectors.ProcessRuntime\OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests", "test\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -634,6 +647,14 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.Build.0 = Release|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.Build.0 = Release|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -730,6 +751,8 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.Container/README.md b/src/OpenTelemetry.ResourceDetectors.Container/README.md index af03c25d22..4cbfd046c0 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/README.md @@ -6,9 +6,8 @@ ## Getting Started You need to install the -`OpenTelemetry.ResourceDetectors.Container` to be able to use the -Container Resource Detectors. It detects container.id from -Container environment. +`OpenTelemetry.ResourceDetectors.Container` package to be able to use the +Container Resource Detectors. ```shell dotnet add package OpenTelemetry.ResourceDetectors.Container --prerelease @@ -25,8 +24,7 @@ using OpenTelemetry.ResourceDetectors.Container; var tracerProvider = Sdk.CreateTracerProviderBuilder() // other configurations - .SetResourceBuilder(ResourceBuilder - .CreateEmpty() + .ConfigureResource(resource => resource .AddDetector(new ContainerResourceDetector())) .Build(); ``` diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a4c8a74d8a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a4c8a74d8a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs new file mode 100644 index 0000000000..fd4de980dc --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md new file mode 100644 index 0000000000..a8bf4cb7aa --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## Unreleased + +* Initial release of `OpenTelemetry.ResourceDetectors.ProcessRuntime` project +[1449](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1449) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj new file mode 100644 index 0000000000..5bb3fc7f40 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj @@ -0,0 +1,12 @@ + + + + net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Extensions - Process Runtime Resource Detector for .NET runtime. + ResourceDetectors.ProcessRuntime- + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs new file mode 100644 index 0000000000..c0119b5fa4 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs @@ -0,0 +1,123 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#if !NETFRAMEWORK +using System; +#endif +using System.Collections.Generic; +using System.Runtime.InteropServices; +#if NETFRAMEWORK +using Microsoft.Win32; +#endif +using OpenTelemetry.Resources; + +namespace OpenTelemetry.ResourceDetectors.ProcessRuntime; + +/// +/// Process runtime detector. +/// +public class ProcessRuntimeDetector : IResourceDetector +{ + /// + /// Detects the resource attributes from .NET runtime. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + var frameworkDescription = RuntimeInformation.FrameworkDescription; + string netRuntimeName; +#if NETFRAMEWORK + string? netFrameworkVersion = GetNetFrameworkVersionFromRegistry(); +#endif + + var lastSpace = frameworkDescription.LastIndexOf(' '); + if (lastSpace != -1) + { + // sample result '.NET Framework 4.8.9195.0' + netRuntimeName = frameworkDescription.Substring(0, lastSpace); +#if NETFRAMEWORK + netFrameworkVersion ??= frameworkDescription.Substring(lastSpace + 1); +#endif + } + else + { + // do not expect to be here, all checked implementation has common FrameworkDescription format - '{Name With Optional Spaces} {Version}' + netRuntimeName = "unknown"; +#if NETFRAMEWORK + netFrameworkVersion ??= "unknown"; +#endif + } + + return new Resource(new List>(3) + { + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription, frameworkDescription), + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName, netRuntimeName), +#if NETFRAMEWORK + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion, netFrameworkVersion), +#else + new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion, Environment.Version.ToString()), +#endif + }); + } + +#if NETFRAMEWORK + private static string? GetNetFrameworkVersionFromRegistry() + { + try + { + const string subKey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"; + using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); + using var ndpKey = baseKey.OpenSubKey(subKey); + + if (ndpKey?.GetValue("Release") != null) + { + return CheckFor45PlusVersion((int)ndpKey.GetValue("Release")); + } + + return null; + } + catch + { + return null; + } + } + + // Checking the version using >= enables forward compatibility. + private static string? CheckFor45PlusVersion(int releaseKey) + { + return releaseKey switch + { + >= 533320 => "4.8.1", + >= 528040 => "4.8", + >= 461808 => "4.7.2", + >= 461308 => "4.7.1", + >= 460798 => "4.7", + >= 394802 => "4.6.2", + + // Following versions are deprecated + // >= 394254 => "4.6.1", + // >= 393295 => "4.6", + // >= 379893 => "4.5.2", + // >= 378675 => "4.5.1", + // >= 378389 => "4.5", + + // This code should never execute. A non-null release key should mean + // that 4.5 or later is installed. + _ => null, + }; + } +#endif +} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs new file mode 100644 index 0000000000..affe9b6f24 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs @@ -0,0 +1,24 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace OpenTelemetry.ResourceDetectors.ProcessRuntime; + +internal static class ProcessRuntimeSemanticConventions +{ + public const string AttributeProcessRuntimeDescription = "process.runtime.description"; + public const string AttributeProcessRuntimeName = "process.runtime.name"; + public const string AttributeProcessRuntimeVersion = "process.runtime.version"; +} diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md new file mode 100644 index 0000000000..7a47e6c122 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md @@ -0,0 +1,40 @@ +# Process Runtime Resource Detectors + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) + +## Getting Started + +You need to install the +`OpenTelemetry.ResourceDetectors.ProcessRuntime` package to be able to use the +Process Runtime Resource Detectors. + +```shell +dotnet add package OpenTelemetry.ResourceDetectors.ProcessRuntime --prerelease +``` + +## Usage + +You can configure Process Runtime resource detector to +the `TracerProvider` with the following example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.ProcessRuntime; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .ConfigureResource(resource => resource + .AddDetector(new ProcessRuntimeDetector())) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **ProcessRuntimeDetector**: `process.runtime.description`, `process.runtime.name`, + and `process.runtime.version`. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index a3516672cc..1fc7d8dc89 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -17,6 +17,7 @@ + diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj index 6977c6ecbe..38ad42b36a 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj new file mode 100644 index 0000000000..e7fc8e6837 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj @@ -0,0 +1,14 @@ + + + + Unit test project for Process Runtime Detector for OpenTelemetry + + net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs new file mode 100644 index 0000000000..b3fc9255b1 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs @@ -0,0 +1,44 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Linq; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests; + +public class ProcessRuntimeDetectorTests +{ + [Fact] + public void TestProcessRuntimeAttributes() + { + var resource = ResourceBuilder.CreateEmpty().AddDetector(new ProcessRuntimeDetector()).Build(); + + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + + Assert.Equal(3, resourceAttributes.Count); + +#if NETFRAMEWORK + Assert.Matches(@"^\.NET Framework \d+\.\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription]); + Assert.Equal(".NET Framework", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName]); + Assert.Matches(@"^4.[1-9](.[1-2])?$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion]); +#else + Assert.Matches(@"^\.NET \d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription]); + Assert.Equal(".NET", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName]); + Assert.Matches(@"^\d+\.\d+\.\d+$", resourceAttributes[ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion]); +#endif + } +} From 1a9559d9d7c4d5ad1ca3693ed00b28a35ab46be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 1 Dec 2023 21:26:13 +0100 Subject: [PATCH 0883/1499] [Instrumentation.GrpcCore] Update minimal Google.Protobuf to 3.15.0 (#1456) --- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 2 ++ .../OpenTelemetry.Instrumentation.GrpcCore.csproj | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 9780b5871e..4a7693ac6d 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -6,6 +6,8 @@ ([#483](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/483)) * Update OpenTelemetry.Api to 1.6.0. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update minimal supported version of `Google.Protobuf` to `3.15.0`. + ([#1456](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1456)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 756d4d0521..d352de48ba 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -7,7 +7,7 @@ disable - + From c6c2f235cfb29520cb9a198bfc610f8e4f0d9571 Mon Sep 17 00:00:00 2001 From: Norm Johanson Date: Fri, 1 Dec 2023 12:38:04 -0800 Subject: [PATCH 0884/1499] [Instrumentation.AWS] Update AWS SDK references (#1454) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.AWS.csproj | 6 +++--- .../OpenTelemetry.Instrumentation.AWS.Tests.csproj | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index e6f0c540dc..d13b15cba4 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated dependency on AWS .NET SDK to version 3.7.100. + ([#1454](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1454)) + ## 1.1.0-beta.1 Released 2023-Aug-07 diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index 45935518a7..183fa0c839 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index f646ccf58e..09568991f7 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -8,7 +8,7 @@ - + From f0f8e1c65d37d1735655d9b59f4b787cf2991730 Mon Sep 17 00:00:00 2001 From: Norm Johanson Date: Fri, 1 Dec 2023 18:45:22 -0800 Subject: [PATCH 0885/1499] Request to release OpenTelemetry.Instrumentation.AWS package (#1459) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index d13b15cba4..a078cca882 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.2 + +Released 2023-Dec-01 + * Updated dependency on AWS .NET SDK to version 3.7.100. ([#1454](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1454)) From c913735d5dba31a2906957680ded8f4f953eb7e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Dec 2023 07:31:58 +0100 Subject: [PATCH 0886/1499] [ResourceDetectors.ProcessRuntime] Release 0.1.0-alpha.1 (#1460) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md index a8bf4cb7aa..88b9ab59c6 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -2,5 +2,9 @@ ## Unreleased +## 0.1.0-alpha.1 + +Released 2023-Dec-04 + * Initial release of `OpenTelemetry.ResourceDetectors.ProcessRuntime` project [1449](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1449) From 5ee0518c7aae68ab4a74b1345103e58b29586e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Dec 2023 09:20:19 +0100 Subject: [PATCH 0887/1499] [ResourceDetector.ProcessRuntime] - fix shields.io image (#1461) --- src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md index 7a47e6c122..7d0027b42c 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md @@ -1,7 +1,7 @@ # Process Runtime Resource Detectors [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) ## Getting Started From 17264f0f8b7dab3baa54f4aaa2449c7575611655 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 15:56:08 -0800 Subject: [PATCH 0888/1499] Bump actions/setup-dotnet from 3 to 4 (#1462) --- .github/workflows/Component.BuildTest.yml | 2 +- .github/workflows/Component.Package.yml | 2 +- .github/workflows/ci-Exporter.OneCollector-Integration.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/dotnet-format.yml | 2 +- .github/workflows/package-Exporter.InfluxDB.yml | 2 +- .github/workflows/package-Exporter.Instana.yml | 2 +- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWS.yml | 2 +- .github/workflows/package-Extensions.Enrichment.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .github/workflows/package-Instrumentation.Cassandra.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.Hangfire.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-ResourceDetectors.AWS.yml | 2 +- .github/workflows/package-ResourceDetectors.Container.yml | 2 +- .github/workflows/package-Sampler.AWS.yml | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 84b6b81565..9c923b4ff3 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -39,7 +39,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: dotnet restore build/Projects/${{ inputs.project-name }}.proj run: dotnet restore build/Projects/${{ inputs.project-name }}.proj diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml index 1a6e247999..c8dd4705ab 100644 --- a/.github/workflows/Component.Package.yml +++ b/.github/workflows/Component.Package.yml @@ -24,7 +24,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: dotnet restore build/Projects/${{ inputs.project-name }}.proj run: dotnet restore build/Projects/${{ inputs.project-name }}.proj diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index 616e7e1096..f12f32031a 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -44,7 +44,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha || github.ref }} # Run on the fork branch once approved - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: dotnet restore build/Projects/${{env.PROJECT}}.proj run: dotnet restore build/Projects/${{env.PROJECT}}.proj diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fee10bd637..cdb7e423c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -250,7 +250,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Restore, Build, & Test ${{ matrix.version }} shell: pwsh diff --git a/.github/workflows/dotnet-format.yml b/.github/workflows/dotnet-format.yml index f0cdc8ba33..f6a2cc59f8 100644 --- a/.github/workflows/dotnet-format.yml +++ b/.github/workflows/dotnet-format.yml @@ -12,7 +12,7 @@ jobs: uses: actions/checkout@v4 - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: dotnet restore run: dotnet restore diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml index d6cc3a5ea8..000d041b39 100644 --- a/.github/workflows/package-Exporter.InfluxDB.yml +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index e19def6a13..a5e52af5cc 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index d06d20db13..a750ed217f 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.AWS.yml b/.github/workflows/package-Extensions.AWS.yml index ba4665e374..6262eb167f 100644 --- a/.github/workflows/package-Extensions.AWS.yml +++ b/.github/workflows/package-Extensions.AWS.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml index ba987e95a8..7f62f243a0 100644 --- a/.github/workflows/package-Extensions.Enrichment.yml +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index 7713f418c8..b347ee89d9 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index 42f43fd54a..a667ed8f24 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml index 78a506eaed..9f3f677554 100644 --- a/.github/workflows/package-Instrumentation.Cassandra.yml +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index 2d3055ed4c..d5c99760b8 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index bca4670daf..a4d182225d 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index cbcf9070bd..4da86113e9 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index 0f09a193ef..a32ce2625f 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index 955a496db4..c943d53c9f 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml index de0e775736..c9e5c97f32 100644 --- a/.github/workflows/package-ResourceDetectors.AWS.yml +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-ResourceDetectors.Container.yml b/.github/workflows/package-ResourceDetectors.Container.yml index 0b680c62e9..425d29453e 100644 --- a/.github/workflows/package-ResourceDetectors.Container.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml index 1c55a193d9..3b17a7a3c9 100644 --- a/.github/workflows/package-Sampler.AWS.yml +++ b/.github/workflows/package-Sampler.AWS.yml @@ -29,7 +29,7 @@ jobs: fetch-depth: 0 # fetching all - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - name: Install dependencies run: dotnet restore src/${{env.PROJECT}} From cfebb97ccb7df3c838a7fc452bd0fb30f1ad1089 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Tue, 5 Dec 2023 09:12:06 +0200 Subject: [PATCH 0889/1499] [Instrumenation.Hangfire] Add options support to hangfire instrumentation (#1442) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + .../CHANGELOG.md | 5 ++ .../Implementation/HangfireInstrumentation.cs | 15 +++-- ...nTelemetry.Instrumentation.Hangfire.csproj | 3 +- .../README.md | 23 +++++++ .../TracerProviderBuilderExtensions.cs | 35 ++++++++-- .../DependencyInjectionConfigTests.cs | 65 +++++++++++++++++++ ...etry.Instrumentation.Hangfire.Tests.csproj | 1 + 8 files changed, 136 insertions(+), 12 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 56d4740243..eaa7631d77 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -6,4 +6,5 @@ OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index b27c06cc11..e41410d31e 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -5,6 +5,11 @@ * Update OTel API version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Added overloads which accept a name to the `TracerProviderBuilder` + `HangfireInstrumentationOptions` extension to allow for more fine-grained + options management + ([#1442](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1442)) + ## 1.5.0-beta.1 Released 2023-Jun-23 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index c58d8d1c91..2c03735dea 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -14,15 +14,15 @@ // limitations under the License. // -using Hangfire; - -namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; - using System; using System.Diagnostics; using System.Reflection; +using Hangfire; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; -internal static class HangfireInstrumentation +internal sealed class HangfireInstrumentation { /// /// The assembly name. @@ -49,4 +49,9 @@ internal static class HangfireInstrumentation /// internal static readonly Func DefaultDisplayNameFunc = backgroundJob => $"JOB {backgroundJob.Job.Type.Name}.{backgroundJob.Job.Method.Name}"; + + public HangfireInstrumentation(HangfireInstrumentationOptions options) + { + GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute(options)); + } } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 772177dc9f..e38c79a9ab 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -8,7 +8,8 @@ - + + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index 72392c219b..03ebe5ddf1 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -56,6 +56,29 @@ the `ConfigureServices` of your `Startup` class. Refer to [example](https://gith For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to [example](../../examples/AspNet/Global.asax.cs). +## Advanced configuration + +When used with +[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md), +all configurations to `HangfireInstrumentationOptions` +can be done in the `ConfigureServices` method of your applications `Startup` +class as shown below. + +```csharp +// Configure +services.Configure(options => +{ + options.DisplayNameFunc = job => $"JOB {job.Id}"; + options.Filter = job => job.Id == "Filter this job"; + options.RecordException = true; +}); + +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddHangfireInstrumentation() + .AddConsoleExporter()); +``` + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index 6624cb9a4a..742b37a61d 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -14,12 +14,14 @@ // limitations under the License. // -namespace OpenTelemetry.Trace; - using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.Hangfire.Implementation; using OpenTelemetry.Internal; +namespace OpenTelemetry.Trace; + /// /// Extension methods to simplify registering of Hangfire job instrumentation. /// @@ -32,7 +34,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddHangfireInstrumentation( this TracerProviderBuilder builder) => - AddHangfireInstrumentation(builder, configure: null); + AddHangfireInstrumentation(builder, name: null, configure: null); /// /// Adds Hangfire instrumentation to the tracer provider. @@ -42,14 +44,35 @@ public static TracerProviderBuilder AddHangfireInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddHangfireInstrumentation( this TracerProviderBuilder builder, + Action? configure) => + AddHangfireInstrumentation(builder, name: null, configure); + + /// + /// Adds Hangfire instrumentation to the tracer provider. + /// + /// being configured. + /// Name which is used when retrieving options. + /// configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHangfireInstrumentation( + this TracerProviderBuilder builder, + string? name, Action? configure) { Guard.ThrowIfNull(builder); - var options = new HangfireInstrumentationOptions(); - configure?.Invoke(options); + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } - Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute(options)); + builder.AddInstrumentation(sp => + { + var options = sp.GetRequiredService>().Get(name); + return new HangfireInstrumentation(options); + }); return builder.AddSource(HangfireInstrumentation.ActivitySourceName); } diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs new file mode 100644 index 0000000000..4e36e09ea0 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs @@ -0,0 +1,65 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Hangfire.Tests; + +public class DependencyInjectionConfigTests +{ + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public async Task TestTracingOptionsDiConfig(string name) + { + bool optionsPickedFromDi = false; + + var services = new ServiceCollection(); + + services + .Configure(name, _ => optionsPickedFromDi = true) + .AddOpenTelemetry() + .WithTracing(builder => + builder.AddHangfireInstrumentation(name, configure: null)); + + var sp = services.BuildServiceProvider(); + + try + { + foreach (var hostedService in sp.GetServices()) + { + await hostedService.StartAsync(CancellationToken.None); + } + + Assert.True(optionsPickedFromDi); + } + finally + { + foreach (var hostedService in sp.GetServices().Reverse()) + { + await hostedService.StopAsync(CancellationToken.None); + } + + await sp.DisposeAsync(); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 199b37903a..08292d09b1 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -10,6 +10,7 @@ + From c3747734e1f2630599e82258f313aa51ec949e54 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 4 Dec 2023 23:20:23 -0800 Subject: [PATCH 0890/1499] [repo] Update CI workflows for .NET 8 (#1458) --- .github/workflows/Component.BuildTest.yml | 2 +- .../workflows/ci-Exporter.OneCollector-Integration.yml | 2 +- .github/workflows/ci.yml | 4 ++-- .github/workflows/verifyaotcompat.yml | 2 +- build/Common.nonprod.props | 1 + build/test-aot-compatibility.ps1 | 2 +- .../OpenTelemetry.AotCompatibility.TestApp.csproj | 2 +- .../OpenTelemetry.Contrib.Tests.Shared.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmark.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.Tests.csproj | 2 +- ...penTelemetry.Instrumentation.AWSLambda.Tests.csproj | 2 +- ...penTelemetry.Instrumentation.Cassandra.Tests.csproj | 2 +- ...ry.Instrumentation.ElasticsearchClient.Tests.csproj | 2 +- ...ry.Instrumentation.EntityFrameworkCore.Tests.csproj | 10 +++++++--- ...elemetry.Instrumentation.EventCounters.Tests.csproj | 2 +- ...OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 2 +- .../RedisProfilerEntryToActivityConverterTests.cs | 5 +++++ ...try.Instrumentation.StackExchangeRedis.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 2 +- ...Telemetry.PersistentStorage.FileSystem.Tests.csproj | 2 +- .../OpenTelemetry.ResourceDetectors.AWS.Tests.csproj | 2 +- .../OpenTelemetry.ResourceDetectors.Azure.Tests.csproj | 2 +- ...nTelemetry.ResourceDetectors.Container.Tests.csproj | 2 +- ...metry.ResourceDetectors.ProcessRuntime.Tests.csproj | 2 +- .../OpenTelemetry.Sampler.AWS.Tests.csproj | 2 +- 35 files changed, 46 insertions(+), 36 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 9c923b4ff3..f77172249e 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -18,7 +18,7 @@ on: required: false type: string tfm-list: - default: '[ "net462", "net6.0", "net7.0" ]' + default: '[ "net462", "net6.0", "net7.0", "net8.0" ]' required: false type: string diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index f12f32031a..d17505c261 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -32,7 +32,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] + version: [ net462, net6.0, net7.0, net8.0 ] exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdb7e423c7..5360bcc91a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,7 +107,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.EventCounters code-cov-name: Instrumentation.EventCounters - tfm-list: '[ "net6.0", "net7.0" ]' + tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' build-test-extensions: needs: detect-changes @@ -240,7 +240,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0 ] + version: [ net462, net6.0, net7.0, net8.0 ] exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/verifyaotcompat.yml b/.github/workflows/verifyaotcompat.yml index cf8425ed89..c437c70c9c 100644 --- a/.github/workflows/verifyaotcompat.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -10,7 +10,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ ubuntu-latest ] - version: [ net7.0 ] + version: [ net8.0 ] runs-on: ${{ matrix.os }} steps: diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index df9574bca7..0c0a43c776 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -27,6 +27,7 @@ [4.18.4,5.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) + net8.0;net7.0;net6.0 [2.5.0,3.0) [2.5.0,3.0) [1.5.32,2.0) diff --git a/build/test-aot-compatibility.ps1 b/build/test-aot-compatibility.ps1 index 13539f9965..ff400b667b 100644 --- a/build/test-aot-compatibility.ps1 +++ b/build/test-aot-compatibility.ps1 @@ -17,7 +17,7 @@ foreach ($line in $($publishOutput -split "`r`n")) Write-Host "Actual warning count is:", $actualWarningCount $expectedWarningCount = 0 -pushd $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/bin/Debug/$targetNetFramework/linux-x64 +pushd $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/bin/Release/$targetNetFramework/linux-x64 Write-Host "Executing test App..." ./OpenTelemetry.AotCompatibility.TestApp diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 1fc7d8dc89..56e661f052 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 true false true diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj index 6c18cec2b5..d6e2eeff92 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj +++ b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net462;net6.0 + netstandard2.0;net462;net6.0;net8.0 false diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index a02e9403d5..b6260babc9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -4,7 +4,7 @@ Exe - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index db069a17f0..00273f8729 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -3,7 +3,7 @@ Exe - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1308,SA1201 disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index df2ddc2b8c..4b9642aab0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -4,7 +4,7 @@ Unit test project for Geneva Exporters for OpenTelemetry - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 disable diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 585b0cf1da..b043f5f018 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -1,7 +1,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 true disable diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 74ac99546d..9d385b58b5 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for OpenTelemetry .NET OneCollectorExporter. - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 true diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index d0cd829938..136af0b70d 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for Stackdriver Exporter for OpenTelemetry - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 75526609ef..5654e72ae1 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -1,7 +1,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 60e65e091c..84863e9115 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for OpenTelemetry .NET SDK telemetry enrichment. - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 7604a758f1..de5d53c8f6 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for OpenTelemetry .NET SDK preview features and extensions - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 38af282d51..52c31daf70 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -2,7 +2,7 @@ Unit test project of OpenTelemetry instrumentation for AWS Lambda - net7.0;net6.0 + $(SupportedNetTargets) true true diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 965d9f2ce6..c43e9fa441 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -1,7 +1,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 7b69af190b..3247babb27 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry Elasticsearch client instrumentation - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) true disable diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index c2143ac23b..6188f39899 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -2,15 +2,19 @@ Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - net7.0;net6.0 + $(SupportedNetTargets) + + + + - + - + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index 32a467c3b6..b26b644b8a 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) true diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 08292d09b1..bb9244d155 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry Hangfire instrumentation - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 false diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 6b4c458df2..0f5351f3c3 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 856abb3bba..7a505404b8 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry Quartz.NET instrumentation - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net472 true diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 495a08704c..4e2b6b51e5 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index 65df35d8d6..b2edab72f2 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -128,7 +128,12 @@ public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() Assert.NotNull(result); Assert.NotNull(result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); + +#if NET8_0 + Assert.Equal("FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); +#else Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); +#endif } [Fact] diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 71970f56c2..79be12b83f 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry StackExchangeRedis instrumentation - net8.0;net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 $(TARGET_FRAMEWORK) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 53393978d8..1c0d57c992 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for OpenTelemetry WCF instrumentation - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 5c4dd8508c..3d69fb68ae 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj index 269f3a5b8a..8f55ce9b57 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for AWS Detector for OpenTelemetry - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) enable diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj index a908c45e6f..5b0ce4fae2 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj index 38ad42b36a..67da77b288 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for Container Detector for OpenTelemetry - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 enable diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj index e7fc8e6837..c71327eb11 100644 --- a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj @@ -3,7 +3,7 @@ Unit test project for Process Runtime Detector for OpenTelemetry - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 29b2484d01..6892d723eb 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -1,7 +1,7 @@ - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From ec811d88ea0005197db151abc282e00cf8a20b19 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:12:36 -0800 Subject: [PATCH 0891/1499] [Exporter.Geneva] Add net8.0 target for GenevaExporter (#1463) --- build/Common.nonprod.props | 2 +- build/Common.props | 2 +- .../.publicApi/net462/PublicAPI.Shipped.txt | 10 +++- .../.publicApi/net462/PublicAPI.Unshipped.txt | 10 ---- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 10 +++- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 10 ---- .../.publicApi/net8.0/PublicAPI.Shipped.txt | 51 +++++++++++++++++++ .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 10 +++- .../netstandard2.0/PublicAPI.Unshipped.txt | 10 ---- .../CHANGELOG.md | 10 ++++ .../Common.GenevaExporter.props | 2 +- .../OpenTelemetry.Exporter.Geneva.csproj | 3 +- .../TLDExporter/UncheckedASCIIEncoding.cs | 8 +++ .../README.md | 2 +- 15 files changed, 102 insertions(+), 38 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Unshipped.txt diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 0c0a43c776..fece09322f 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -20,7 +20,7 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [0.13.6,0.14) + [0.13.10,0.14) [2.3.1,3.0) [5.0.0,7.0) [17.7.2,18.0) diff --git a/build/Common.props b/build/Common.props index 336a0f6a70..22a2dd71fb 100644 --- a/build/Common.props +++ b/build/Common.props @@ -36,7 +36,7 @@ [3.3.3] [1.1.1,2.0) [1.6.0,2.0) - [1.7.0-alpha.1] + [1.7.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt index 37648818db..33a8b061ff 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt @@ -2,6 +2,9 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -12,6 +15,8 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.C OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void @@ -39,5 +44,8 @@ override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTeleme override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt index db58b7a99f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,10 +0,0 @@ -OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -*REMOVED*static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt index 37648818db..33a8b061ff 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -2,6 +2,9 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -12,6 +15,8 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.C OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void @@ -39,5 +44,8 @@ override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTeleme override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt index db58b7a99f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,10 +0,0 @@ -OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -*REMOVED*static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..33a8b061ff --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt @@ -0,0 +1,51 @@ +Microsoft.Extensions.Logging.GenevaLoggingExtensions +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void +OpenTelemetry.Exporter.Geneva.GenevaLogExporter +OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt index 37648818db..33a8b061ff 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt @@ -2,6 +2,9 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -12,6 +15,8 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.C OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void @@ -39,5 +44,8 @@ override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTeleme override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index db58b7a99f..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,10 +0,0 @@ -OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -*REMOVED*static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 2a1d2d86cf..72340f827d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0-rc.1 + +Released 2023-Dec-05 + * Update Part B mapping to add Http related tags based on the new Semantic Conventions. ([#1402](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1402)) @@ -14,6 +18,12 @@ non-primitive types have to be serialized for `env_properties`. ([#1424](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1424)) +* Add `net8.0` target. + ([#1329](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1329)) + +* Update OpenTelemetry SDK version to `1.7.0-rc.1`. + ([#1329](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1329)) + ## 1.7.0-alpha.1 Released 2023-Sep-22 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 5570a7a1fe..78181066e1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestVersion) + $(OpenTelemetryCoreLatestPrereleaseVersion) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index d17c1b3ee3..434af490f2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -7,7 +7,7 @@ OpenTelemetry Authors $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 - net6.0;netstandard2.0 + net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- true @@ -16,6 +16,7 @@ + diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs index b42d324a66..95d2186d5b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -89,10 +89,14 @@ public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, public override unsafe int GetBytes(char* charPtr, int charCount, byte* bytePtr, int byteCount) { +#if NET8_0_OR_GREATER + ArgumentOutOfRangeException.ThrowIfLessThan(byteCount, charCount); +#else if (byteCount < charCount) { throw new ArgumentOutOfRangeException(nameof(byteCount)); } +#endif for (int i = 0; i < charCount; i += 1) { @@ -104,10 +108,14 @@ public override unsafe int GetBytes(char* charPtr, int charCount, byte* bytePtr, public override unsafe int GetChars(byte* bytePtr, int byteCount, char* charPtr, int charCount) { +#if NET8_0_OR_GREATER + ArgumentOutOfRangeException.ThrowIfLessThan(charCount, byteCount); +#else if (charCount < byteCount) { throw new ArgumentOutOfRangeException(nameof(charCount)); } +#endif for (int i = 0; i < byteCount; i += 1) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md b/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md index 51535d27ae..d19d5e7f54 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md @@ -4,7 +4,7 @@ Navigate to `./test/OpenTelemetry.Exporter.Geneva.Benchmark` directory and run the following command: ```sh -dotnet run -c Release -f net7.0 -- -m +dotnet run -c Release -f net8.0 -- -m `` Then choose the benchmark class that you want to run by entering the required From b7d62131a06cb8914a94aba9b3c45b6de77ec30d Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:23:16 -0800 Subject: [PATCH 0892/1499] [Exporter.Geneva] Update Benchmark results (#1464) --- .../Exporter/LogExporterBenchmarks.cs | 36 +++++++------- .../Exporter/MetricExporterBenchmarks.cs | 48 +++++++++---------- .../Exporter/SerializationBenchmarks.cs | 30 ++++++------ .../Exporter/TLDLogExporterBenchmarks.cs | 20 ++++---- .../Exporter/TLDTraceExporterBenchmarks.cs | 20 ++++---- .../Exporter/TraceExporterBenchmarks.cs | 18 +++---- 6 files changed, 86 insertions(+), 86 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 18ba6d0dbf..5df8f4a1fc 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -20,25 +20,25 @@ using OpenTelemetry.Logs; /* -BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - - -| Method | IncludeFormattedMessage | Mean | Error | StdDev | Gen0 | Allocated | -|-------------------------- |------------------------ |-----------:|---------:|---------:|-------:|----------:| -| LoggerWithMessageTemplate | False | 1,221.9 ns | 17.52 ns | 15.53 ns | 0.0153 | 104 B | -| LoggerWithDirectLoggerAPI | False | 1,109.6 ns | 22.14 ns | 34.47 ns | 0.0381 | 240 B | -| LoggerWithSourceGenerator | False | 1,117.7 ns | 9.94 ns | 7.76 ns | 0.0095 | 64 B | -| SerializeLogRecord | False | 560.0 ns | 2.87 ns | 2.40 ns | - | - | -| Export | False | 891.0 ns | 17.06 ns | 32.05 ns | - | - | -| LoggerWithMessageTemplate | True | 1,243.7 ns | 24.79 ns | 35.55 ns | 0.0153 | 104 B | -| LoggerWithDirectLoggerAPI | True | 1,090.8 ns | 12.85 ns | 10.04 ns | 0.0381 | 240 B | -| LoggerWithSourceGenerator | True | 1,186.1 ns | 23.58 ns | 45.99 ns | 0.0095 | 64 B | -| SerializeLogRecord | True | 564.8 ns | 5.20 ns | 4.06 ns | - | - | -| Export | True | 874.5 ns | 17.38 ns | 24.37 ns | - | - | +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + + +| Method | IncludeFormattedMessage | Mean | Error | StdDev | Median | Gen0 | Allocated | +|-------------------------- |------------------------ |-----------:|---------:|---------:|-----------:|-------:|----------:| +| LoggerWithMessageTemplate | False | 1,119.7 ns | 22.42 ns | 29.15 ns | 1,110.3 ns | 0.0153 | 104 B | +| LoggerWithDirectLoggerAPI | False | 1,358.0 ns | 26.31 ns | 33.28 ns | 1,346.6 ns | 0.0496 | 320 B | +| LoggerWithSourceGenerator | False | 1,132.1 ns | 22.30 ns | 18.62 ns | 1,133.8 ns | 0.0095 | 64 B | +| SerializeLogRecord | False | 455.0 ns | 6.39 ns | 5.97 ns | 454.3 ns | - | - | +| Export | False | 1,005.3 ns | 19.99 ns | 36.55 ns | 998.9 ns | - | - | +| LoggerWithMessageTemplate | True | 1,153.7 ns | 16.13 ns | 14.30 ns | 1,153.6 ns | 0.0153 | 104 B | +| LoggerWithDirectLoggerAPI | True | 1,342.0 ns | 26.39 ns | 29.33 ns | 1,335.7 ns | 0.0496 | 320 B | +| LoggerWithSourceGenerator | True | 1,182.3 ns | 22.21 ns | 19.69 ns | 1,181.2 ns | 0.0095 | 64 B | +| SerializeLogRecord | True | 455.6 ns | 8.28 ns | 15.56 ns | 450.5 ns | - | - | +| Export | True | 971.7 ns | 19.47 ns | 44.75 ns | 947.5 ns | - | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 0cc988cb85..3ae26c253b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -23,31 +23,31 @@ using OpenTelemetry.Metrics; /* -BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.23424.1000) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.203 - [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 - - -| Method | Mean | Error | StdDev | Allocated | -|--------------------------------------------------------- |----------:|---------:|---------:|----------:| -| InstrumentWithNoListener3Dimensions | 66.17 ns | 0.316 ns | 0.296 ns | - | -| InstrumentWithNoListener4Dimensions | 112.15 ns | 0.540 ns | 0.478 ns | - | -| InstrumentWithWithListener3Dimensions | 70.17 ns | 0.110 ns | 0.097 ns | - | -| InstrumentWithWithListener4Dimensions | 114.77 ns | 0.343 ns | 0.304 ns | - | -| InstrumentWithWithDummyReader3Dimensions | 192.32 ns | 0.369 ns | 0.288 ns | - | -| InstrumentWithWithDummyReader4Dimensions | 261.23 ns | 3.515 ns | 2.745 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 198.50 ns | 1.153 ns | 1.022 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 261.38 ns | 1.856 ns | 1.736 ns | - | -| SerializeCounterMetricItemWith3Dimensions | 215.62 ns | 0.759 ns | 0.673 ns | - | -| SerializeCounterMetricItemWith4Dimensions | 241.33 ns | 0.466 ns | 0.364 ns | - | -| ExportCounterMetricItemWith3Dimensions | 257.88 ns | 0.572 ns | 0.507 ns | - | -| ExportCounterMetricItemWith4Dimensions | 285.43 ns | 1.300 ns | 1.216 ns | - | -| SerializeHistogramMetricItemWith3Dimensions | 380.58 ns | 6.226 ns | 5.823 ns | - | -| SerializeHistogramMetricItemWith4Dimensions | 404.64 ns | 3.981 ns | 3.723 ns | - | -| ExportHistogramMetricItemWith3Dimensions | 438.35 ns | 2.442 ns | 2.040 ns | - | -| ExportHistogramMetricItemWith4Dimensions | 477.16 ns | 2.555 ns | 2.133 ns | - | +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + + +| Method | Mean | Error | StdDev | Allocated | +|--------------------------------------------------------- |----------:|----------:|----------:|----------:| +| InstrumentWithNoListener3Dimensions | 23.83 ns | 0.080 ns | 0.075 ns | - | +| InstrumentWithNoListener4Dimensions | 56.71 ns | 0.730 ns | 0.647 ns | - | +| InstrumentWithWithListener3Dimensions | 24.46 ns | 0.257 ns | 0.215 ns | - | +| InstrumentWithWithListener4Dimensions | 59.02 ns | 0.501 ns | 0.444 ns | - | +| InstrumentWithWithDummyReader3Dimensions | 139.70 ns | 1.189 ns | 1.113 ns | - | +| InstrumentWithWithDummyReader4Dimensions | 184.76 ns | 2.012 ns | 1.680 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 135.76 ns | 0.995 ns | 0.831 ns | - | +| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 193.14 ns | 1.507 ns | 1.336 ns | - | +| SerializeCounterMetricItemWith3Dimensions | 165.27 ns | 1.000 ns | 0.887 ns | - | +| SerializeCounterMetricItemWith4Dimensions | 191.13 ns | 1.201 ns | 1.003 ns | - | +| ExportCounterMetricItemWith3Dimensions | 657.63 ns | 13.019 ns | 13.369 ns | - | +| ExportCounterMetricItemWith4Dimensions | 682.76 ns | 13.598 ns | 32.318 ns | - | +| SerializeHistogramMetricItemWith3Dimensions | 285.39 ns | 4.195 ns | 3.503 ns | - | +| SerializeHistogramMetricItemWith4Dimensions | 303.15 ns | 3.834 ns | 3.587 ns | - | +| ExportHistogramMetricItemWith3Dimensions | 803.90 ns | 14.753 ns | 36.465 ns | - | +| ExportHistogramMetricItemWith4Dimensions | 810.62 ns | 14.445 ns | 11.278 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs index 938e9c4933..eb7b96082d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs @@ -21,25 +21,25 @@ using OpenTelemetry.Exporter.Geneva.TldExporter; /* -BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Allocated | +| Method | Mean | Error | StdDev | Allocated | |------------------------------- |----------:|----------:|----------:|----------:| -| TLD_SerializeUInt8 | 22.483 ns | 0.0216 ns | 0.0202 ns | - | -| MsgPack_SerializeUInt8 | 7.360 ns | 0.0135 ns | 0.0127 ns | - | -| TLD_SerializeAsciiString | 31.141 ns | 0.0210 ns | 0.0176 ns | - | -| MsgPack_SerializeAsciiString | 19.580 ns | 0.0412 ns | 0.0385 ns | - | -| TLD_SerializeUnicodeSubString | 41.064 ns | 0.0708 ns | 0.0662 ns | - | -| TLD_SerializeUnicodeString | 41.889 ns | 0.0927 ns | 0.0868 ns | - | -| MsgPack_SerializeUnicodeString | 21.806 ns | 0.0281 ns | 0.0249 ns | - | -| TLD_SerializeDateTime | 45.321 ns | 0.1321 ns | 0.1235 ns | - | -| MsgPack_SerializeDateTime | 30.667 ns | 0.0401 ns | 0.0356 ns | - | -| TLD_Reset | 12.739 ns | 0.0351 ns | 0.0328 ns | - | +| TLD_SerializeUInt8 | 16.721 ns | 0.1541 ns | 0.1441 ns | - | +| MsgPack_SerializeUInt8 | 7.470 ns | 0.0854 ns | 0.0799 ns | - | +| TLD_SerializeAsciiString | 25.828 ns | 0.3779 ns | 0.3535 ns | - | +| MsgPack_SerializeAsciiString | 16.779 ns | 0.0421 ns | 0.0328 ns | - | +| TLD_SerializeUnicodeSubString | 35.224 ns | 0.2928 ns | 0.2596 ns | - | +| TLD_SerializeUnicodeString | 33.503 ns | 0.3786 ns | 0.3541 ns | - | +| MsgPack_SerializeUnicodeString | 19.173 ns | 0.1042 ns | 0.0924 ns | - | +| TLD_SerializeDateTime | 36.896 ns | 0.2391 ns | 0.2119 ns | - | +| MsgPack_SerializeDateTime | 30.335 ns | 0.1765 ns | 0.1651 ns | - | +| TLD_Reset | 7.856 ns | 0.0453 ns | 0.0379 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs index 013933e35d..c81d01468e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs @@ -22,19 +22,19 @@ using OpenTelemetry.Trace; /* -BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Allocated | -|--------------------------- |---------:|--------:|--------:|----------:| -| MsgPack_SerializeLogRecord | 560.9 ns | 2.92 ns | 2.44 ns | - | -| TLD_SerializeLogRecord | 357.5 ns | 1.01 ns | 0.89 ns | - | -| MsgPack_ExportLogRecord | 957.2 ns | 3.47 ns | 3.25 ns | - | -| TLD_ExportLogRecord | 732.0 ns | 2.04 ns | 1.71 ns | - | +| Method | Mean | Error | StdDev | Allocated | +|--------------------------- |-----------:|---------:|---------:|----------:| +| MsgPack_SerializeLogRecord | 441.4 ns | 3.19 ns | 2.99 ns | - | +| TLD_SerializeLogRecord | 263.5 ns | 2.93 ns | 2.75 ns | - | +| MsgPack_ExportLogRecord | 1,039.3 ns | 20.55 ns | 46.81 ns | - | +| TLD_ExportLogRecord | 890.5 ns | 17.48 ns | 25.07 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs index 1e6bebef8f..1fe4fbd9cd 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs @@ -21,19 +21,19 @@ using OpenTelemetry.Trace; /* -BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Allocated | -|-------------------------- |---------:|--------:|--------:|----------:| -| MsgPack_SerializeActivity | 300.3 ns | 1.14 ns | 1.07 ns | - | -| TLD_SerializeActivity | 371.0 ns | 0.70 ns | 0.66 ns | - | -| MsgPack_ExportActivity | 680.2 ns | 1.73 ns | 1.62 ns | - | -| TLD_ExportActivity | 729.5 ns | 4.78 ns | 4.24 ns | - | +| Method | Mean | Error | StdDev | Allocated | +|-------------------------- |---------:|---------:|---------:|----------:| +| MsgPack_SerializeActivity | 266.4 ns | 3.84 ns | 3.59 ns | - | +| TLD_SerializeActivity | 298.9 ns | 1.99 ns | 1.66 ns | - | +| MsgPack_ExportActivity | 787.3 ns | 15.70 ns | 31.71 ns | - | +| TLD_ExportActivity | 878.6 ns | 9.84 ns | 9.20 ns | - | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index c55fdee970..168d45ed02 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -20,18 +20,18 @@ using OpenTelemetry.Trace; /* -BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963) +BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 +.NET SDK 8.0.100 + [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 -| Method | Mean | Error | StdDev | Median | Gen0 | Allocated | -|--------------------------------- |---------:|---------:|---------:|---------:|-------:|----------:| -| ExportActivity | 566.3 ns | 3.13 ns | 2.44 ns | 565.9 ns | - | - | -| SerializeActivity | 313.3 ns | 1.71 ns | 1.60 ns | 313.0 ns | - | - | -| CreateActivityWithGenevaExporter | 940.5 ns | 18.77 ns | 54.14 ns | 911.4 ns | 0.0648 | 416 B | +| Method | Mean | Error | StdDev | Gen0 | Allocated | +|--------------------------------- |-----------:|---------:|---------:|-------:|----------:| +| ExportActivity | 847.1 ns | 16.34 ns | 22.36 ns | - | - | +| SerializeActivity | 261.5 ns | 2.91 ns | 2.58 ns | - | - | +| CreateActivityWithGenevaExporter | 1,066.0 ns | 20.98 ns | 56.35 ns | 0.0648 | 416 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; From d1e46beeb38125d4a5ef9f379cd68594a6344eb0 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Thu, 7 Dec 2023 18:39:44 +0100 Subject: [PATCH 0893/1499] Remove Moq from Exporter.Stackdriver.Tests (#1466) Co-authored-by: Cijo Thomas --- .../Properties/AssemblyInfo.cs | 3 -- ...elemetry.Exporter.Stackdriver.Tests.csproj | 1 - .../StackdriverExporterTests.cs | 27 ++++----------- .../TestTraceServiceClient.cs | 34 +++++++++++++++++++ 4 files changed, 40 insertions(+), 25 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs index 6c14f10f6f..addfc2e221 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs @@ -17,18 +17,15 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Stackdriver.Tests" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED internal static class AssemblyInfo { public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; - public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; } #else internal static class AssemblyInfo { public const string PublicKey = ""; - public const string MoqPublicKey = ""; } #endif diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 136af0b70d..b527a67cf2 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -11,7 +11,6 @@ - diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 3c9a7fb4d0..b8be55e226 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -18,15 +18,9 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using Google.Api.Gax.Grpc; -using Google.Cloud.Trace.V2; -using Grpc.Core; -using Moq; using OpenTelemetry.Resources; using OpenTelemetry.Trace; - using Xunit; -using Status = Grpc.Core.Status; namespace OpenTelemetry.Exporter.Stackdriver.Tests; @@ -89,12 +83,8 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); - var traceClientMock = new Mock(MockBehavior.Strict); - traceClientMock.Setup(x => - x.BatchWriteSpans(It.IsAny(), It.IsAny())) - .Throws(new RpcException(Status.DefaultCancelled)) - .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); - var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); + var traceClient = new TestTraceServiceClient(throwException: true); + var activityExporter = new StackdriverTraceExporter("test", traceClient); var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); @@ -106,7 +96,7 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() processor.Shutdown(); - var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); + var batch = new Batch([.. exportedItems], exportedItems.Count); RunTest(batch); void RunTest(Batch batch) @@ -119,7 +109,6 @@ void RunTest(Batch batch) Assert.Null(exception); Assert.StrictEqual(ExportResult.Failure, result); - traceClientMock.VerifyAll(); } [Fact] @@ -130,11 +119,8 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); - var traceClientMock = new Mock(MockBehavior.Strict); - traceClientMock.Setup(x => - x.BatchWriteSpans(It.IsAny(), It.IsAny())) - .Verifiable($"{nameof(TraceServiceClient.BatchWriteSpans)} was never called"); - var activityExporter = new StackdriverTraceExporter("test", traceClientMock.Object); + var traceClient = new TestTraceServiceClient(throwException: false); + var activityExporter = new StackdriverTraceExporter("test", traceClient); var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); @@ -146,7 +132,7 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() processor.Shutdown(); - var batch = new Batch(exportedItems.ToArray(), exportedItems.Count); + var batch = new Batch([.. exportedItems], exportedItems.Count); RunTest(batch); void RunTest(Batch batch) @@ -159,7 +145,6 @@ void RunTest(Batch batch) Assert.Null(exception); Assert.StrictEqual(ExportResult.Success, result); - traceClientMock.VerifyAll(); } internal static Activity CreateTestActivity( diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs new file mode 100644 index 0000000000..95f1eb3c56 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs @@ -0,0 +1,34 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Google.Api.Gax.Grpc; +using Google.Cloud.Trace.V2; +using Grpc.Core; + +namespace OpenTelemetry.Exporter.Stackdriver.Tests; + +internal class TestTraceServiceClient(bool throwException) : TraceServiceClient +{ + private readonly bool throwException = throwException; + + public override void BatchWriteSpans(BatchWriteSpansRequest request, CallSettings callSettings) + { + if (this.throwException) + { + throw new RpcException(Status.DefaultCancelled); + } + } +} From 752e7b1c76db53d5a20f79fa0db6d8234bfcb0fc Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Thu, 7 Dec 2023 13:57:41 -0800 Subject: [PATCH 0894/1499] Simplify copyright disclaimer (#1473) --- build/stylecop.json | 4 ++-- examples/AspNet/App_Start/RouteConfig.cs | 15 +-------------- examples/AspNet/App_Start/WebApiConfig.cs | 15 +-------------- examples/AspNet/Controllers/HomeController.cs | 15 +-------------- .../Controllers/WeatherForecastController.cs | 15 +-------------- examples/AspNet/Global.asax.cs | 15 +-------------- examples/AspNet/Models/WeatherForecast.cs | 15 +-------------- examples/AspNet/Properties/AssemblyInfo.cs | 15 +-------------- .../AspNet/SuppressInstrumentationHttpModule.cs | 15 +-------------- examples/InfluxDB/Examples.InfluxDB/Program.cs | 15 +-------------- .../enrichment/Examples.Enrichment/IMyService.cs | 15 +-------------- .../enrichment/Examples.Enrichment/MyService.cs | 15 +-------------- .../Examples.Enrichment/MyTraceEnricher.cs | 15 +-------------- .../enrichment/Examples.Enrichment/Program.cs | 15 +-------------- .../Examples.EventCounters/Program.cs | 15 +-------------- .../Controllers/WeatherForecastController.cs | 15 +-------------- .../Examples.GrpcCore.AspNetCore/EchoService.cs | 15 +-------------- .../Examples.GrpcCore.AspNetCore/Program.cs | 15 +-------------- .../Examples.GrpcCore.AspNetCore/Startup.cs | 15 +-------------- .../WeatherForecast.cs | 15 +-------------- examples/owin/Controllers/TestController.cs | 15 +-------------- examples/owin/Program.cs | 15 +-------------- examples/process-instrumentation/Program.cs | 15 +-------------- .../redis/Examples.StackExchangeRedis/Program.cs | 15 +-------------- examples/runtime-instrumentation/Program.cs | 15 +-------------- examples/wcf/client-core/Program.cs | 15 +-------------- examples/wcf/client-core/StatusServiceClient.cs | 15 +-------------- examples/wcf/client-netframework/Program.cs | 15 +-------------- .../client-netframework/StatusServiceClient.cs | 15 +-------------- .../wcf/server-aspnetframework/Global.asax.cs | 15 +-------------- .../server-aspnetframework/StatusService.svc.cs | 15 +-------------- examples/wcf/server-netframework/Program.cs | 15 +-------------- .../wcf/server-netframework/StatusService.cs | 15 +-------------- examples/wcf/shared/IStatusServiceContract.cs | 15 +-------------- examples/wcf/shared/StatusRequest.cs | 15 +-------------- examples/wcf/shared/StatusResponse.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../EventNameExportMode.cs | 15 +-------------- .../ExceptionStackExportMode.cs | 15 +-------------- .../GenevaBaseExporter.cs | 15 +-------------- .../GenevaExporterHelperExtensions.cs | 15 +-------------- .../GenevaExporterOptions.cs | 15 +-------------- .../GenevaLogExporter.cs | 15 +-------------- .../GenevaLoggingExtensions.cs | 15 +-------------- .../GenevaTraceExporter.cs | 15 +-------------- .../Internal/ConnectionStringBuilder.cs | 15 +-------------- .../Internal/ExporterEventSource.cs | 15 +-------------- .../Internal/ReentrantActivityExportProcessor.cs | 15 +-------------- .../Internal/ReentrantExportProcessor.cs | 15 +-------------- .../Internal/Schema.cs | 15 +-------------- .../Internal/TableNameSerializer.cs | 15 +-------------- .../Metrics/GenevaMetricExporter.cs | 15 +-------------- .../Metrics/GenevaMetricExporterExtensions.cs | 15 +-------------- .../Metrics/GenevaMetricExporterOptions.cs | 15 +-------------- .../Metrics/MetricSerializer.cs | 15 +-------------- .../Metrics/Transport/IMetricDataTransport.cs | 15 +-------------- .../Metrics/Transport/MetricEtwDataTransport.cs | 15 +-------------- .../Metrics/Transport/MetricUnixDataTransport.cs | 15 +-------------- .../MsgPackExporter/MessagePackSerializer.cs | 15 +-------------- .../MsgPackExporter/MsgPackExporter.cs | 15 +-------------- .../MsgPackExporter/MsgPackLogExporter.cs | 15 +-------------- .../MsgPackExporter/MsgPackTraceExporter.cs | 15 +-------------- .../Transport/EtwDataTransport.cs | 15 +-------------- .../MsgPackExporter/Transport/IDataTransport.cs | 15 +-------------- .../Transport/UnixDomainSocketDataTransport.cs | 15 +-------------- .../Transport/UnixDomainSocketEndPoint.cs | 15 +-------------- .../TLDExporter/JsonSerializer.cs | 15 +-------------- .../TLDExporter/TldExporter.cs | 15 +-------------- .../TLDExporter/TldLogExporter.cs | 15 +-------------- .../TLDExporter/TldTraceExporter.cs | 15 +-------------- .../TLDExporter/UncheckedASCIIEncoding.cs | 15 +-------------- .../IMetricsWriter.cs | 15 +-------------- .../InfluxDBEventSource.cs | 15 +-------------- .../InfluxDBExporterExtensions.cs | 15 +-------------- .../InfluxDBMetricsExporter.cs | 15 +-------------- .../InfluxDBMetricsExporterOptions.cs | 15 +-------------- .../MetricsSchema.cs | 15 +-------------- .../PointDataExtensions.cs | 15 +-------------- .../TelegrafPrometheusWriterV1.cs | 15 +-------------- .../TelegrafPrometheusWriterV2.cs | 15 +-------------- .../IInstanaExporterHelper.cs | 15 +-------------- .../Implementation/ISpanSender.cs | 15 +-------------- .../Implementation/InstanaExporterEventSource.cs | 15 +-------------- .../Implementation/InstanaSpan.cs | 15 +-------------- .../Implementation/InstanaSpanFactory.cs | 16 ++-------------- .../Implementation/InstanaSpanSerializer.cs | 15 +-------------- .../Implementation/InstanaSpanTransformInfo.cs | 15 +-------------- .../Processors/ActivityProcessorBase.cs | 15 +-------------- .../Processors/DefaultActivityProcessor.cs | 15 +-------------- .../Processors/ErrorActivityProcessor.cs | 15 +-------------- .../Processors/EventsActivityProcessor.cs | 15 +-------------- .../Processors/IActivityProcessor.cs | 15 +-------------- .../Processors/TagsActivityProcessor.cs | 15 +-------------- .../Implementation/SpanSender.cs | 16 ++-------------- .../Implementation/Transport.cs | 15 +-------------- .../InstanaExporter.cs | 15 +-------------- .../InstanaExporterConstants.cs | 15 +-------------- .../InstanaExporterHelper.cs | 15 +-------------- .../Properties/AssemblyInfo.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../Internal/CallbackManager.cs | 15 +-------------- .../Internal/ConnectionStringParser.cs | 15 +-------------- .../Internal/EventNameManager.cs | 15 +-------------- .../Internal/ExtensionFieldInformation.cs | 15 +-------------- .../Internal/ExtensionFieldInformationManager.cs | 15 +-------------- .../Internal/OneCollectorExporterEventSource.cs | 15 +-------------- .../Serialization/BatchSerializationResult.cs | 15 +-------------- .../CommonSchemaJsonSerializationHelper.cs | 15 +-------------- .../CommonSchemaJsonSerializationState.cs | 15 +-------------- .../Serialization/CommonSchemaJsonSerializer.cs | 15 +-------------- .../Internal/Serialization/ISerializer.cs | 15 +-------------- .../LogRecordCommonSchemaJsonSerializer.cs | 15 +-------------- .../Internal/Sinks/ISink.cs | 15 +-------------- .../Sinks/WriteDirectlyToTransportSink.cs | 15 +-------------- .../Internal/ThreadStorageHelper.cs | 15 +-------------- .../Internal/Transports/HttpJsonPostTransport.cs | 15 +-------------- .../Internal/Transports/IHttpClient.cs | 15 +-------------- .../Internal/Transports/ITransport.cs | 15 +-------------- .../Internal/Transports/TransportSendRequest.cs | 15 +-------------- .../OneCollectorLogExportProcessorBuilder.cs | 15 +-------------- .../Logs/OneCollectorLogExporterOptions.cs | 15 +-------------- ...neCollectorLogExporterSerializationOptions.cs | 15 +-------------- ...lectorOpenTelemetryLoggerOptionsExtensions.cs | 15 +-------------- .../OneCollectorExporter.cs | 15 +-------------- ...lectorExporterHttpTransportCompressionType.cs | 15 +-------------- .../OneCollectorExporterOptions.cs | 15 +-------------- ...xporterPayloadTransmittedCallbackArguments.cs | 15 +-------------- ...rializationExceptionStackTraceHandlingType.cs | 15 +-------------- ...neCollectorExporterSerializationFormatType.cs | 15 +-------------- .../OneCollectorExporterTransportOptions.cs | 15 +-------------- .../OneCollectorExporterTransportProtocolType.cs | 15 +-------------- .../OneCollectorExporterValidationException.cs | 15 +-------------- .../Implementation/ActivityExtensions.cs | 15 +-------------- .../Implementation/Constants.cs | 15 +-------------- .../ExporterStackdriverEventSource.cs | 15 +-------------- .../Implementation/GoogleCloudResourceUtils.cs | 15 +-------------- .../StackdriverStatsConfiguration.cs | 15 +-------------- .../Properties/AssemblyInfo.cs | 15 +-------------- .../StackdriverTraceExporter.cs | 16 ++-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../Utils/CommonUtils.cs | 15 +-------------- .../AWSXRayEventSource.cs | 15 +-------------- .../AWSXRayIdGenerator.cs | 15 +-------------- .../AWSXRayIdGenerator.net6.cs | 15 +-------------- src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs | 15 +-------------- .../Trace/AWSXRayPropagator.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../Internal/TraceEnrichmentActions.cs | 15 +-------------- .../Internal/TraceEnrichmentProcessor.cs | 15 +-------------- .../Trace/TraceEnricher.cs | 15 +-------------- .../Trace/TraceEnrichmentBag.cs | 15 +-------------- .../TraceEnrichmentProviderBuilderExtensions.cs | 15 +-------------- ...TraceEnrichmentServiceCollectionExtensions.cs | 15 +-------------- src/OpenTelemetry.Extensions/AssemblyInfo.cs | 15 +-------------- .../ActivityEventAttachingLogProcessor.cs | 15 +-------------- .../Internal/DefaultLogStateConverter.cs | 15 +-------------- .../OpenTelemetryExtensionsEventSource.cs | 15 +-------------- .../Logs/LogToActivityEventConversionOptions.cs | 15 +-------------- .../Logs/OpenTelemetryLoggingExtensions.cs | 15 +-------------- .../Trace/AutoFlushActivityProcessor.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../AWSClientInstrumentationOptions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../Implementation/AWSClientsInstrumentation.cs | 15 +-------------- .../Implementation/AWSMessagingUtils.cs | 15 +-------------- .../Implementation/AWSSemanticConventions.cs | 15 +-------------- .../Implementation/AWSServiceHelper.cs | 15 +-------------- .../Implementation/AWSServiceType.cs | 15 +-------------- .../AWSTracingPipelineCustomizer.cs | 15 +-------------- .../Implementation/AWSTracingPipelineHandler.cs | 15 +-------------- .../Implementation/SnsRequestContextHelper.cs | 15 +-------------- .../Implementation/SqsRequestContextHelper.cs | 15 +-------------- .../Implementation/Utils.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../AWSLambdaInstrumentationOptions.cs | 15 +-------------- .../AWSLambdaWrapper.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../Implementation/AWSLambdaHttpUtils.cs | 15 +-------------- .../Implementation/AWSLambdaResourceDetector.cs | 15 +-------------- .../AWSLambdaSemanticConventions.cs | 15 +-------------- .../Implementation/AWSLambdaUtils.cs | 15 +-------------- .../Implementation/AWSMessagingUtils.cs | 15 +-------------- .../Implementation/CommonExtensions.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../ActivityHelper.cs | 15 +-------------- .../AspNetTelemetryEventSource.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../TelemetryHttpModule.cs | 15 +-------------- .../TelemetryHttpModuleOptions.cs | 15 +-------------- .../AspNetInstrumentation.cs | 15 +-------------- .../AspNetInstrumentationOptions.cs | 15 +-------------- .../AspNetMetrics.cs | 15 +-------------- .../AspNetMetricsInstrumentationOptions.cs | 15 +-------------- .../AssemblyInfo.cs | 16 ++-------------- .../AspNetInstrumentationEventSource.cs | 15 +-------------- .../Implementation/HttpInListener.cs | 15 +-------------- .../Implementation/HttpInMetricsListener.cs | 15 +-------------- .../MeterProviderBuilderExtensions.cs | 15 +-------------- .../SpanHelper.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../CassandraBuilderExtensions.cs | 15 +-------------- .../CassandraDriverMetricsProvider.cs | 15 +-------------- .../CassandraMeter.cs | 15 +-------------- .../DriverCounter.cs | 15 +-------------- .../DriverGauge.cs | 15 +-------------- .../DriverMeter.cs | 15 +-------------- .../DriverTimer.cs | 15 +-------------- .../MeterProviderBuilderExtensions.cs | 15 +-------------- .../ElasticsearchClientInstrumentation.cs | 16 ++-------------- .../ElasticsearchClientInstrumentationOptions.cs | 15 +-------------- .../ElasticsearchInstrumentationEventSource.cs | 15 +-------------- ...ticsearchRequestPipelineDiagnosticListener.cs | 16 ++-------------- .../Properties/AssemblyInfo.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../EntityFrameworkInstrumentation.cs | 15 +-------------- .../EntityFrameworkInstrumentationOptions.cs | 15 +-------------- .../EntityFrameworkDiagnosticListener.cs | 15 +-------------- .../EntityFrameworkInstrumentationEventSource.cs | 15 +-------------- .../Properties/AssemblyInfo.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../EventCountersInstrumentationEventSource.cs | 15 +-------------- .../EventCountersInstrumentationOptions.cs | 15 +-------------- .../EventCountersMetrics.cs | 15 +-------------- .../MeterProviderBuilderExtensions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../AsyncStreamReaderProxy.cs | 15 +-------------- .../ClientStreamWriterProxy.cs | 15 +-------------- .../ClientTracingInterceptor.cs | 15 +-------------- .../ClientTracingInterceptorOptions.cs | 15 +-------------- .../Extensions.cs | 15 +-------------- .../GrpcCoreInstrumentation.cs | 15 +-------------- .../RpcScope.cs | 15 +-------------- .../SemanticConventions.cs | 15 +-------------- .../ServerStreamWriterProxy.cs | 15 +-------------- .../ServerTracingInterceptor.cs | 15 +-------------- .../ServerTracingInterceptorOptions.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../HangfireInstrumentationOptions.cs | 15 +-------------- .../Implementation/HangfireInstrumentation.cs | 15 +-------------- .../HangfireInstrumentationConstants.cs | 15 +-------------- .../HangfireInstrumentationJobFilterAttribute.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../AppBuilderExtensions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../Implementation/DiagnosticsMiddleware.cs | 15 +-------------- .../OwinInstrumentationActivitySource.cs | 15 +-------------- .../OwinInstrumentationEventSource.cs | 15 +-------------- .../Implementation/OwinInstrumentationMetrics.cs | 15 +-------------- .../OwinEnrichEventType.cs | 15 +-------------- ...trumentationMeterProviderBuilderExtensions.cs | 15 +-------------- .../OwinInstrumentationOptions.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../MeterProviderBuilderExtensions.cs | 15 +-------------- .../ProcessInstrumentationOptions.cs | 15 +-------------- .../ProcessMetrics.cs | 15 +-------------- .../Implementation/QuartzDiagnosticListener.cs | 15 +-------------- .../QuartzInstrumentationEventSource.cs | 15 +-------------- .../Implementation/TagName.cs | 15 +-------------- .../OperationName.cs | 15 +-------------- .../Properties/AssemblyInfo.cs | 16 ++-------------- .../QuartzInstrumentationOptions.cs | 15 +-------------- .../QuartzJobInstrumentation.cs | 15 +-------------- .../TraceProviderBuilderExtensions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../MeterProviderBuilderExtensions.cs | 15 +-------------- .../RuntimeInstrumentationOptions.cs | 15 +-------------- .../RuntimeMetrics.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../RedisProfilerEntryToActivityConverter.cs | 15 +-------------- ...tackExchangeRedisConnectionInstrumentation.cs | 15 +-------------- .../StackExchangeRedisInstrumentation.cs | 15 +-------------- .../StackExchangeRedisInstrumentationOptions.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../AssemblyInfo.cs | 16 ++-------------- .../Implementation/ActionMetadata.cs | 15 +-------------- .../Implementation/AspNetParentSpanCorrector.cs | 15 +-------------- .../AsyncResultWithTelemetryState.cs | 15 +-------------- .../ClientChannelInstrumentation.cs | 15 +-------------- .../HttpRequestMessagePropertyWrapper.cs | 15 +-------------- .../Implementation/InstrumentedChannel.cs | 15 +-------------- .../Implementation/InstrumentedChannelFactory.cs | 15 +-------------- .../InstrumentedChannelFactoryBase.cs | 15 +-------------- .../InstrumentedCommunicationObject.cs | 15 +-------------- .../Implementation/InstrumentedDuplexChannel.cs | 15 +-------------- .../Implementation/InstrumentedRequestChannel.cs | 15 +-------------- .../Implementation/RequestTelemetryState.cs | 15 +-------------- .../RequestTelemetryStateTracker.cs | 15 +-------------- .../Implementation/TelemetryBindingElement.cs | 15 +-------------- .../TelemetryClientMessageInspector.cs | 15 +-------------- .../TelemetryContextMessageProperty.cs | 15 +-------------- .../TelemetryDispatchMessageInspector.cs | 15 +-------------- .../Implementation/TelemetryMessageHeader.cs | 15 +-------------- .../Implementation/TelemetryPropagationReader.cs | 15 +-------------- .../Implementation/TelemetryPropagationWriter.cs | 15 +-------------- .../WcfInstrumentationActivitySource.cs | 15 +-------------- .../WcfInstrumentationConstants.cs | 15 +-------------- .../WcfInstrumentationEventSource.cs | 15 +-------------- .../TelemetryContractBehaviorAttribute.cs | 15 +-------------- .../TelemetryEndpointBehavior.cs | 15 +-------------- .../TelemetryEndpointBehaviorExtensionElement.cs | 15 +-------------- .../TelemetryServiceBehavior.cs | 15 +-------------- .../TelemetryServiceBehaviorExtensionElement.cs | 15 +-------------- .../TracerProviderBuilderExtensions.cs | 15 +-------------- .../WcfEnrichEventNames.cs | 15 +-------------- .../WcfInstrumentationOptions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../PersistentBlob.cs | 15 +-------------- .../PersistentBlobProvider.cs | 15 +-------------- .../PersistentStorageAbstractionsEventSource.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../DirectorySizeTracker.cs | 15 +-------------- .../FileBlob.cs | 15 +-------------- .../FileBlobProvider.cs | 15 +-------------- .../PersistentStorageEventSource.cs | 15 +-------------- .../PersistentStorageHelper.cs | 15 +-------------- .../AWSEBSResourceDetector.cs | 15 +-------------- .../AWSEC2ResourceDetector.cs | 15 +-------------- .../AWSECSResourceDetector.cs | 15 +-------------- .../AWSEKSResourceDetector.cs | 15 +-------------- .../AWSResourcesEventSource.cs | 15 +-------------- .../AWSSemanticConventions.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../Http/Handler.cs | 15 +-------------- .../Http/ServerCertificateValidationProvider.cs | 15 +-------------- .../Models/AWSEBSMetadataModel.cs | 15 +-------------- .../Models/AWSEC2IdentityDocumentModel.cs | 15 +-------------- .../Models/AWSEKSClusterDataModel.cs | 15 +-------------- .../Models/AWSEKSClusterInformationModel.cs | 15 +-------------- .../ResourceDetectorUtils.cs | 15 +-------------- .../AppServiceResourceDetector.cs | 15 +-------------- .../AssemblyInfo.cs | 16 ++-------------- .../AzureVMResourceDetector.cs | 15 +-------------- .../AzureVmMetaDataRequestor.cs | 15 +-------------- .../AzureVmMetadataResponse.cs | 15 +-------------- .../ResourceAttributeConstants.cs | 15 +-------------- .../SourceGenerationContext.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../ContainerExtensionsEventSource.cs | 15 +-------------- .../ContainerResourceDetector.cs | 15 +-------------- .../ContainerSemanticConventions.cs | 15 +-------------- .../Utils/EncodingUtils.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../ProcessRuntimeDetector.cs | 15 +-------------- .../ProcessRuntimeSemanticConventions.cs | 15 +-------------- .../AWSSamplerEventSource.cs | 15 +-------------- .../AWSXRayRemoteSampler.cs | 15 +-------------- .../AWSXRayRemoteSamplerBuilder.cs | 15 +-------------- .../AWSXRaySamplerClient.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs | 16 ++-------------- src/OpenTelemetry.Sampler.AWS/Clock.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs | 15 +-------------- .../GetSamplingRulesResponse.cs | 15 +-------------- .../GetSamplingTargetsRequest.cs | 15 +-------------- .../GetSamplingTargetsResponse.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/Matcher.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/RateLimiter.cs | 15 +-------------- .../RateLimitingSampler.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/SamplingRule.cs | 15 +-------------- .../SamplingRuleApplier.cs | 15 +-------------- .../SamplingRuleRecord.cs | 15 +-------------- .../SamplingStatisticsDocument.cs | 15 +-------------- .../SamplingTargetDocument.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/Statistics.cs | 15 +-------------- src/OpenTelemetry.Sampler.AWS/SystemClock.cs | 15 +-------------- .../UnprocessedStatistic.cs | 15 +-------------- src/Shared/ActivityInstrumentationHelper.cs | 15 +-------------- src/Shared/DiagnosticSourceListener.cs | 15 +-------------- src/Shared/DiagnosticSourceSubscriber.cs | 15 +-------------- src/Shared/ExceptionExtensions.cs | 15 +-------------- src/Shared/Guard.cs | 15 +-------------- src/Shared/IsExternalInit.cs | 15 +-------------- src/Shared/ListenerHandler.cs | 15 +-------------- src/Shared/MultiTypePropertyFetcher.cs | 15 +-------------- src/Shared/NullableAttributes.cs | 15 +-------------- src/Shared/PropertyFetcher.AOT.cs | 15 +-------------- src/Shared/PropertyFetcher.cs | 15 +-------------- src/Shared/ResourceSemanticConventions.cs | 15 +-------------- src/Shared/SemanticConventions.cs | 15 +-------------- src/Shared/SpanAttributeConstants.cs | 15 +-------------- src/Shared/SpanHelper.cs | 15 +-------------- .../Program.cs | 15 +-------------- .../ActivityHelperExtensions.cs | 15 +-------------- .../EventSourceTestHelper.cs | 15 +-------------- .../InMemoryEventListener.cs | 15 +-------------- .../SkipUnlessEnvVarFoundFactAttribute.cs | 15 +-------------- .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 15 +-------------- .../TestActivityExportProcessor.cs | 15 +-------------- .../TestActivityProcessor.cs | 15 +-------------- .../TestEventListener.cs | 15 +-------------- .../TestHttpServer.cs | 15 +-------------- .../TestSampler.cs | 15 +-------------- .../Exporter/Food.cs | 15 +-------------- .../Exporter/LogExporterBenchmarks.cs | 15 +-------------- .../Exporter/MetricExporterBenchmarks.cs | 15 +-------------- .../Exporter/SerializationBenchmarks.cs | 15 +-------------- .../Exporter/TLDLogExporterBenchmarks.cs | 15 +-------------- .../Exporter/TLDTraceExporterBenchmarks.cs | 15 +-------------- .../Exporter/TraceExporterBenchmarks.cs | 15 +-------------- .../Program.cs | 15 +-------------- .../DummyServer.cs | 15 +-------------- .../Program.cs | 15 +-------------- .../ConnectionStringBuilderTests.cs | 15 +-------------- .../GenevaLogExporterTests.cs | 15 +-------------- .../GenevaMetricExporterOptionsTests.cs | 15 +-------------- .../GenevaMetricExporterTests.cs | 15 +-------------- .../GenevaTraceExporterTests.cs | 15 +-------------- .../JsonSerializerTests.cs | 15 +-------------- .../LogSerializationTests.cs | 15 +-------------- .../MessagePackSerializerTests.cs | 15 +-------------- .../TableNameSerializerTests.cs | 15 +-------------- .../UnixDomainSocketDataTransportTests.cs | 15 +-------------- .../UnixDomainSocketEndPointTests.cs | 15 +-------------- .../InfluxDBMetricsExporterTests.cs | 15 +-------------- .../Utils/AssertUtils.cs | 15 +-------------- .../Utils/InfluxDBFakeServer.cs | 15 +-------------- ...fluxDBMetricsExporterOptionsTestExtensions.cs | 15 +-------------- .../Utils/LineProtocolParser.cs | 15 +-------------- .../Utils/MeterProviderBuilderTestExtensions.cs | 15 +-------------- .../Utils/PointData.cs | 15 +-------------- .../InstanaExporterTests.cs | 15 +-------------- .../InstanaSpanFactoryTests.cs | 15 +-------------- .../InstanaSpanSerializerTests.cs | 15 +-------------- .../InstanaSpanTest.cs | 15 +-------------- .../Processors/DefaultActivityProcessorTests.cs | 15 +-------------- .../Processors/ErrorActivityProcessorTests.cs | 15 +-------------- .../Processors/EventsActivityProcessorTests.cs | 15 +-------------- .../Processors/TagsActivityProcessorTests.cs | 15 +-------------- ...ogRecordCommonSchemaJsonHttpPostBenchmarks.cs | 15 +-------------- .../Program.cs | 15 +-------------- .../CommonSchemaJsonSerializationHelperTests.cs | 15 +-------------- .../CommonSchemaJsonSerializationStateTests.cs | 15 +-------------- .../ConnectionStringParserTests.cs | 15 +-------------- .../EventNameManagerTests.cs | 15 +-------------- .../ExtensionFieldInformationManagerTests.cs | 15 +-------------- .../HttpJsonPostTransportTests.cs | 15 +-------------- .../LogRecordCommonSchemaJsonSerializerTests.cs | 15 +-------------- .../OneCollectorIntegrationTests.cs | 15 +-------------- ...rOpenTelemetryLoggerOptionsExtensionsTests.cs | 15 +-------------- .../WriteDirectlyToTransportSinkTests.cs | 15 +-------------- .../StackdriverStatsConfigurationTests.cs | 15 +-------------- .../StackdriverExporterTests.cs | 15 +-------------- .../TestActivityProcessor.cs | 15 +-------------- .../TestTraceServiceClient.cs | 15 +-------------- .../AWSXRayIdGeneratorTests.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../Trace/AWSXRayPropagatorTests.cs | 15 +-------------- .../MyTraceEnricher.cs | 15 +-------------- .../MyTraceEnricher2.cs | 15 +-------------- ...lemetryEnrichmentProviderBuilderExtensions.cs | 15 +-------------- ...EnrichmentServiceCollectionExtensionsTests.cs | 15 +-------------- .../ActivityEventAttachingLogProcessorTests.cs | 15 +-------------- .../Trace/AutoFlushActivityProcessorTests.cs | 15 +-------------- .../Implementation/RequestContextHelperTests.cs | 15 +-------------- .../Implementation/TestsHelper.cs | 15 +-------------- .../TestAWSClientInstrumentation.cs | 15 +-------------- .../Tools/CustomResponses.cs | 15 +-------------- .../Tools/CustomWebResponse.cs | 15 +-------------- .../Tools/HttpResponseMessageBody.cs | 15 +-------------- .../Tools/MockHttpRequest.cs | 15 +-------------- .../Tools/MockHttpRequestFactory.cs | 15 +-------------- .../Tools/MockWebResponse.cs | 15 +-------------- .../Tools/TestAmazonDynamoDBClient.cs | 15 +-------------- .../Tools/Utils.cs | 15 +-------------- .../AWSLambdaWrapperTests.cs | 15 +-------------- .../Implementation/AWSLambdaHttpUtilsTests.cs | 15 +-------------- .../Implementation/AWSMessagingUtilsTests.cs | 15 +-------------- .../Implementation/CommonExtensionsTests.cs | 15 +-------------- .../SampleHandlers.cs | 15 +-------------- .../SampleLambdaContext.cs | 15 +-------------- .../ActivityHelperTest.cs | 15 +-------------- .../HttpContextHelper.cs | 15 +-------------- .../WebConfigTransformTest.cs | 15 +-------------- .../WebConfigWithLocationTagTransformTest.cs | 15 +-------------- .../AssemblyInfo.cs | 15 +-------------- .../BasicTests.cs | 15 +-------------- .../EventSourceTest.cs | 15 +-------------- .../HttpInListenerTests.cs | 15 +-------------- .../HttpInMetricsListenerTests.cs | 15 +-------------- .../RouteTestHelper.cs | 15 +-------------- .../BooksEntity.cs | 15 +-------------- .../CassandraInstrumentationTests.cs | 15 +-------------- .../Customer.cs | 15 +-------------- .../DependencyInjectionConfigTests.cs | 15 +-------------- .../ElasticsearchClientTests.cs | 16 ++-------------- .../InMemoryConnectionWithDownstreamActivity.cs | 15 +-------------- .../DependencyInjectionConfigTests.cs | 15 +-------------- .../EntityFrameworkDiagnosticListenerTests.cs | 15 +-------------- .../EventCountersMetricsTests.cs | 15 +-------------- .../FoobarService.cs | 15 +-------------- .../GrpcCoreClientInterceptorTests.cs | 15 +-------------- .../GrpcCoreServerInterceptorTests.cs | 15 +-------------- .../InterceptorActivityListener.cs | 15 +-------------- .../DependencyInjectionConfigTests.cs | 15 +-------------- .../HangfireFixture.cs | 15 +-------------- ...fireInstrumentationJobFilterAttributeTests.cs | 15 +-------------- .../TestJob.cs | 15 +-------------- .../Controllers/TestController.cs | 15 +-------------- .../DiagnosticsMiddlewareTests.cs | 15 +-------------- .../ProcessMetricsTests.cs | 15 +-------------- .../QuartzDiagnosticListenerTests.cs | 15 +-------------- .../TestJob.cs | 15 +-------------- .../TestJobExecutionExceptionJob.cs | 15 +-------------- .../RuntimeInstrumentationOptionsTests.cs | 15 +-------------- .../RuntimeMetricsTests.cs | 15 +-------------- ...RedisProfilerEntryToActivityConverterTests.cs | 15 +-------------- ...tackExchangeRedisCallsInstrumentationTests.cs | 15 +-------------- .../AspNetParentSpanCorrectorTests.netfx.cs | 15 +-------------- .../TelemetryBindingElementForHttpTests.cs | 15 +-------------- .../TelemetryBindingElementForTcpTests.netfx.cs | 15 +-------------- ...ageInspectorForOneWayOperationsTests.netfx.cs | 15 +-------------- ...lemetryDispatchMessageInspectorTests.netfx.cs | 15 +-------------- .../TelemetryPropagationTests.netfx.cs | 15 +-------------- .../DownstreamInstrumentationBindingElement.cs | 15 +-------------- .../Tools/DownstreamInstrumentationChannel.cs | 15 +-------------- .../DownstreamInstrumentationChannelFactory.cs | 15 +-------------- .../DownstreamInstrumentationEndpointBehavior.cs | 15 +-------------- .../Tools/DownstreamInstrumentationExtensions.cs | 15 +-------------- .../Tools/ErrorHandler.netfx.cs | 15 +-------------- .../Tools/ErrorHandlerServiceBehavior.netfx.cs | 15 +-------------- .../WCF/IServiceContract.cs | 15 +-------------- .../WCF/Service.netfx.cs | 15 +-------------- .../WCF/ServiceClient.cs | 15 +-------------- .../WCF/ServiceRequest.cs | 15 +-------------- .../WCF/ServiceResponse.cs | 15 +-------------- .../DirectorySizeTrackerTests.cs | 15 +-------------- .../FileBlobProviderTests.cs | 15 +-------------- .../FileBlobTests.cs | 15 +-------------- .../AWSEBSResourceDetectorTests.cs | 15 +-------------- .../AWSEC2ResourceDetectorTests.cs | 15 +-------------- .../AWSECSResourceDetectorTests.cs | 15 +-------------- .../AWSEKSResourceDetectorTests.cs | 15 +-------------- .../Http/CertificateUploader.cs | 15 +-------------- .../Http/HandlerTests.cs | 15 +-------------- .../ServerCertificateValidationProviderTests.cs | 15 +-------------- .../SampleAWSEBSMetadataModel.cs | 15 +-------------- .../SampleAWSEC2IdentityDocumentModel.cs | 15 +-------------- .../AzureResourceDetectorTests.cs | 15 +-------------- .../ContainerResourceDetectorTests.cs | 15 +-------------- .../TempFile.cs | 15 +-------------- .../ProcessRuntimeDetectorTests.cs | 15 +-------------- .../TestAWSXRayRemoteSampler.cs | 15 +-------------- .../TestAWSXRaySamplerClient.cs | 15 +-------------- .../OpenTelemetry.Sampler.AWS.Tests/TestClock.cs | 15 +-------------- .../TestMatcher.cs | 15 +-------------- .../TestRateLimiter.cs | 15 +-------------- .../TestRateLimitingSampler.cs | 15 +-------------- .../TestRulesCache.cs | 15 +-------------- .../TestSamplingRuleApplier.cs | 15 +-------------- test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs | 15 +-------------- 552 files changed, 564 insertions(+), 7716 deletions(-) diff --git a/build/stylecop.json b/build/stylecop.json index 064a1ef5a7..6d32e9d35e 100644 --- a/build/stylecop.json +++ b/build/stylecop.json @@ -2,8 +2,8 @@ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", "settings": { "documentationRules": { - "companyName": "OpenTelemetry Authors", - "copyrightText": "Copyright The OpenTelemetry Authors\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License." + "copyrightText": "Copyright The OpenTelemetry Authors\nSPDX-License-Identifier: Apache-2.0", + "xmlHeader": false }, "orderingRules": { "usingDirectivesPlacement": "outsideNamespace" diff --git a/examples/AspNet/App_Start/RouteConfig.cs b/examples/AspNet/App_Start/RouteConfig.cs index 80575537f6..907613936c 100644 --- a/examples/AspNet/App_Start/RouteConfig.cs +++ b/examples/AspNet/App_Start/RouteConfig.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Web.Mvc; using System.Web.Routing; diff --git a/examples/AspNet/App_Start/WebApiConfig.cs b/examples/AspNet/App_Start/WebApiConfig.cs index 9827495525..b7c84bec0c 100644 --- a/examples/AspNet/App_Start/WebApiConfig.cs +++ b/examples/AspNet/App_Start/WebApiConfig.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Net.Http.Formatting; using System.Web.Http; diff --git a/examples/AspNet/Controllers/HomeController.cs b/examples/AspNet/Controllers/HomeController.cs index 029e323ff0..8407bb673f 100644 --- a/examples/AspNet/Controllers/HomeController.cs +++ b/examples/AspNet/Controllers/HomeController.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Web.Mvc; diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index 5ef863576d..3d4516d12c 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index ba77e849f4..015ac54af2 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Configuration; diff --git a/examples/AspNet/Models/WeatherForecast.cs b/examples/AspNet/Models/WeatherForecast.cs index 4e4384bbef..afdc107657 100644 --- a/examples/AspNet/Models/WeatherForecast.cs +++ b/examples/AspNet/Models/WeatherForecast.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/examples/AspNet/Properties/AssemblyInfo.cs b/examples/AspNet/Properties/AssemblyInfo.cs index 81534e43a0..832faca648 100644 --- a/examples/AspNet/Properties/AssemblyInfo.cs +++ b/examples/AspNet/Properties/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.InteropServices; diff --git a/examples/AspNet/SuppressInstrumentationHttpModule.cs b/examples/AspNet/SuppressInstrumentationHttpModule.cs index bd31841d77..2b05a1cc59 100644 --- a/examples/AspNet/SuppressInstrumentationHttpModule.cs +++ b/examples/AspNet/SuppressInstrumentationHttpModule.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Web; diff --git a/examples/InfluxDB/Examples.InfluxDB/Program.cs b/examples/InfluxDB/Examples.InfluxDB/Program.cs index c9f496f963..e38c8b6a73 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Program.cs +++ b/examples/InfluxDB/Examples.InfluxDB/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry; using OpenTelemetry.Exporter.InfluxDB; diff --git a/examples/enrichment/Examples.Enrichment/IMyService.cs b/examples/enrichment/Examples.Enrichment/IMyService.cs index 9e3a2ab789..977ecb8bd0 100644 --- a/examples/enrichment/Examples.Enrichment/IMyService.cs +++ b/examples/enrichment/Examples.Enrichment/IMyService.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace Examples.Enrichment; diff --git a/examples/enrichment/Examples.Enrichment/MyService.cs b/examples/enrichment/Examples.Enrichment/MyService.cs index 3e4071d1f8..00d0212505 100644 --- a/examples/enrichment/Examples.Enrichment/MyService.cs +++ b/examples/enrichment/Examples.Enrichment/MyService.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs b/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs index 496639c3f2..0f4febee2f 100644 --- a/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs +++ b/examples/enrichment/Examples.Enrichment/MyTraceEnricher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Extensions.Enrichment; diff --git a/examples/enrichment/Examples.Enrichment/Program.cs b/examples/enrichment/Examples.Enrichment/Program.cs index c0c54fd01e..c1f3c81a79 100644 --- a/examples/enrichment/Examples.Enrichment/Program.cs +++ b/examples/enrichment/Examples.Enrichment/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; diff --git a/examples/event-counters/Examples.EventCounters/Program.cs b/examples/event-counters/Examples.EventCounters/Program.cs index fc98de6fbb..f2935c15c4 100644 --- a/examples/event-counters/Examples.EventCounters/Program.cs +++ b/examples/event-counters/Examples.EventCounters/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; using OpenTelemetry; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index 8ab3b4b7b1..5570c6f07c 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs index 46c9269931..4efeb0b45a 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Threading.Tasks; using Grpc.Core; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs index f9b834c954..f4eddbaecf 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index 0f61e44bc6..0957ec35c9 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Threading; using System.Threading.Tasks; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index 6836928dc0..5742858f1f 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/examples/owin/Controllers/TestController.cs b/examples/owin/Controllers/TestController.cs index 4441175d4a..6c18aa8309 100644 --- a/examples/owin/Controllers/TestController.cs +++ b/examples/owin/Controllers/TestController.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Web.Http; diff --git a/examples/owin/Program.cs b/examples/owin/Program.cs index 2267c5399c..f1fb1fd2ad 100644 --- a/examples/owin/Program.cs +++ b/examples/owin/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/examples/process-instrumentation/Program.cs b/examples/process-instrumentation/Program.cs index 789a591454..e1d9b832eb 100644 --- a/examples/process-instrumentation/Program.cs +++ b/examples/process-instrumentation/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry; using OpenTelemetry.Metrics; diff --git a/examples/redis/Examples.StackExchangeRedis/Program.cs b/examples/redis/Examples.StackExchangeRedis/Program.cs index e395b698b5..7cd9bba90a 100644 --- a/examples/redis/Examples.StackExchangeRedis/Program.cs +++ b/examples/redis/Examples.StackExchangeRedis/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry; using OpenTelemetry.Trace; diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index 9131aa652c..8c8612d0fc 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry; using OpenTelemetry.Metrics; diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 71cc37ec5d..857112700f 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/examples/wcf/client-core/StatusServiceClient.cs b/examples/wcf/client-core/StatusServiceClient.cs index ac8e4a2301..9fbbc4ade5 100644 --- a/examples/wcf/client-core/StatusServiceClient.cs +++ b/examples/wcf/client-core/StatusServiceClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; using System.ServiceModel.Channels; diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index ee699a507a..340417f7bb 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Configuration; diff --git a/examples/wcf/client-netframework/StatusServiceClient.cs b/examples/wcf/client-netframework/StatusServiceClient.cs index b7c28e21e5..45f20c54d6 100644 --- a/examples/wcf/client-netframework/StatusServiceClient.cs +++ b/examples/wcf/client-netframework/StatusServiceClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; using System.Threading.Tasks; diff --git a/examples/wcf/server-aspnetframework/Global.asax.cs b/examples/wcf/server-aspnetframework/Global.asax.cs index 0546cd33fb..fbf6e5e51d 100644 --- a/examples/wcf/server-aspnetframework/Global.asax.cs +++ b/examples/wcf/server-aspnetframework/Global.asax.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Configuration; diff --git a/examples/wcf/server-aspnetframework/StatusService.svc.cs b/examples/wcf/server-aspnetframework/StatusService.svc.cs index e09a817b82..a44cf6c018 100644 --- a/examples/wcf/server-aspnetframework/StatusService.svc.cs +++ b/examples/wcf/server-aspnetframework/StatusService.svc.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Threading.Tasks; diff --git a/examples/wcf/server-netframework/Program.cs b/examples/wcf/server-netframework/Program.cs index a2a230b5fd..9031736e40 100644 --- a/examples/wcf/server-netframework/Program.cs +++ b/examples/wcf/server-netframework/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel; diff --git a/examples/wcf/server-netframework/StatusService.cs b/examples/wcf/server-netframework/StatusService.cs index e173d122a3..d5307343a0 100644 --- a/examples/wcf/server-netframework/StatusService.cs +++ b/examples/wcf/server-netframework/StatusService.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel; diff --git a/examples/wcf/shared/IStatusServiceContract.cs b/examples/wcf/shared/IStatusServiceContract.cs index 35e4045566..f7d632d6b5 100644 --- a/examples/wcf/shared/IStatusServiceContract.cs +++ b/examples/wcf/shared/IStatusServiceContract.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; #if NETFRAMEWORK diff --git a/examples/wcf/shared/StatusRequest.cs b/examples/wcf/shared/StatusRequest.cs index b9ea0bac27..45e74f0de1 100644 --- a/examples/wcf/shared/StatusRequest.cs +++ b/examples/wcf/shared/StatusRequest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.Serialization; diff --git a/examples/wcf/shared/StatusResponse.cs b/examples/wcf/shared/StatusResponse.cs index 1207917842..b6fcdc85de 100644 --- a/examples/wcf/shared/StatusResponse.cs +++ b/examples/wcf/shared/StatusResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.Serialization; diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs index 67a0e79c89..8487e73f48 100644 --- a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs index 7e9e18528f..12f768b1c4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs index 6cad7899a6..2c00fd9c7e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index d38c76267a..946b6425b6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index c050b34c3b..cc913f5ef0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 82cdb3a3ac..9069182880 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 1633971d68..723817929e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.InteropServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 38f7c480da..908038e053 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index e19a9f9a87..d79a064bc5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 3b26ba9676..a51bc216c3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 91cf275805..3993493c73 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs index b1785bbefa..fff9eebf9c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index 0806440867..b9575f2a8f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Linq.Expressions; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs index b5cf8429c4..b665743364 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index f22ff8336b..c23ff0ee9f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 0b26fe0615..a7ab27898d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 028f38d651..545adff15b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Microsoft.Extensions.DependencyInjection; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index 2132e5ef95..c2df90cc37 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs index 31322ec28a..e0355bae34 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs index 112a05bf65..970f8f0bf6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 0b0498b38f..f83b10d9ee 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs index c042db0a60..98d12a22f7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index 6d8ed0bb9c..62424f5693 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; #if NET6_0_OR_GREATER diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs index f825c033a0..191e26b200 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 6542e00320..5c453d2cf2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 5b97abc8f3..39bd3ea578 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index 1204fe6ee3..65d43a3384 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs index 200f04ac1b..9641ee757d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs index aea5c7049e..024380127c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Net; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs index df6f9c1d62..ef00b48764 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Net; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index a545b28025..ca5f4e6d96 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs index 331c0e12f9..4891c5266e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 31d696bda6..7015d34722 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index 472a8e1757..c9ae119f69 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs index 95d2186d5b..c7fdbb9967 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Text; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs index 31ed4f0393..d74a6b5cb5 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/IMetricsWriter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using InfluxDB.Client; using OpenTelemetry.Metrics; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs index 61de60ad9b..36ba1b3410 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs index 1d4a61e893..dd461973be 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using InfluxDB.Client; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs index ccb1727bd9..0b2e827783 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using InfluxDB.Client; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs index f31e3c0161..35448f01b3 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs b/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs index 4c52417c60..6f80bbb2dc 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/MetricsSchema.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.InfluxDB; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs index d407910f5c..45ab06c1e0 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using InfluxDB.Client.Writes; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs index b72e08910d..078e64916e 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Globalization; using InfluxDB.Client; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs index 4c9221acd8..df2a25e0fa 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Globalization; using InfluxDB.Client; diff --git a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs index e2045e1932..2d234b33d3 100644 --- a/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs +++ b/src/OpenTelemetry.Exporter.Instana/IInstanaExporterHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs index 3cc30898d1..2d6f1ccf26 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/ISpanSender.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Instana.Implementation; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs index 1d797a2bda..69ca3e04e9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaExporterEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs index 4bee9a0549..9778cf9b2a 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs index 5f9c1b70ff..855a104625 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Collections.Generic; namespace OpenTelemetry.Exporter.Instana.Implementation; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index c6f45e4f43..15c08e51b5 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs index 6ca12066cd..24df872045 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Instana.Implementation; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs index 0f0f02b923..16a327cb4a 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs index d1a6b566d0..690ae30f57 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs index 5d5fc3a95d..50b4b19fcd 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Threading.Tasks; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs index c4b4f6ae31..cd7eceaf63 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs index 81052f6da6..b812d4bc55 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Threading.Tasks; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs index af1e53dd64..3a1c10d59e 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index 6b4f89e390..e433e79ff9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Collections.Concurrent; using System.Threading.Tasks; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index 5d067e8837..e990d88d93 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Concurrent; diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index ca3583ea26..0cb2ea11b9 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs index a427353318..3d2dcdfca9 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterConstants.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Instana; diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs index bdfe5de79a..346b925444 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporterHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs index fea138bbd7..18dfea566b 100644 --- a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs index e1c94fe726..6d883f5870 100644 --- a/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Instana/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs index 43c488ffc0..34093fc974 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs index 40c5e17465..dd342b779f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs index 9ed57f0bef..da9c35457c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs index e290f6cfa7..0b56f8f8d4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs index 596c2943d9..94657b99ec 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs index 98bd8dd745..97a3735b0c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index 8cfefcbe63..7813989c9a 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs index 5072dc6418..265c5d4ff5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 // Note: StyleCop doesn't understand the C#11 "required" modifier yet. Remove // this in the future once StyleCop is updated. See: diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index fa015b281c..982cab47b3 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Globalization; using System.Text.Json; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs index cc464979fe..b7c69c8db6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; #if NET6_0_OR_GREATER diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs index 585994b438..47da925984 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Text.Json; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs index 1b2669aeeb..f282c923c0 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 515ac6d4c1..6edcaba58b 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Text.Json; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs index e404f1f548..5a8ff85778 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/ISink.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs index 3f228dba0b..4ecf6a94ed 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK || NETSTANDARD2_0 using System.Buffers; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs index 3a1968c9af..18c17c0779 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ThreadStorageHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index c9754c1752..6585c0916a 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.IO.Compression; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs index ec344e7826..0bb175b248 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System.Net.Http; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs index 9637100c80..5afc5bf3e5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/ITransport.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.OneCollector; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs index 7490be62a2..1656f21f6b 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 // Note: StyleCop doesn't understand the C#11 "required" modifier yet. Remove // this in the future once StyleCop is updated. See: diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs index 99d9b23398..659a56e5c7 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System.Net.Http; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index 9be886af87..a64e7c76d9 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs index 8230b30d9e..f2947272fe 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterSerializationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Logs; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs index 120c1b2739..1b4287def2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorOpenTelemetryLoggerOptionsExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.Configuration; using OpenTelemetry.Exporter.OneCollector; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs index 336146a27e..d0b9e6cfb5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Internal; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs index 067e3e241a..e047670a43 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterHttpTransportCompressionType.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.OneCollector; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs index 8ea82c4caf..2150a1cc9d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ComponentModel.DataAnnotations; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs index 9f663f5790..accce3b3c4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterPayloadTransmittedCallbackArguments.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs index 5f230c00fd..32cd43f851 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationExceptionStackTraceHandlingType.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.OneCollector; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs index e9f42365cb..ab49509a21 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterSerializationFormatType.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.OneCollector; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs index 5f1759f3ce..6f818948a5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ComponentModel.DataAnnotations; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs index 51a55c1777..b7b36b04c3 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportProtocolType.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.OneCollector; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs index 717c4abd6e..5e86e02cd5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.Serialization; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 36aa1f032f..ecf996f6a5 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs index ee3797181e..9a642cdda6 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/Constants.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.Stackdriver.Implementation; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs index 818383e680..f6157e4575 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ExporterStackdriverEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs index 2dfb3e0270..9b012c3b6d 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/GoogleCloudResourceUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs index 8d436432a5..111ce5a768 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/StackdriverStatsConfiguration.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Google.Api; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs index addfc2e221..577b5afaaa 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Properties/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 22d3b57418..c71127eafb 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs index e96e34b8cb..eeea072dbf 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Exporter.Stackdriver; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs index ef9067fc54..f820150fae 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs index 5421a5f7c3..36901d478a 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs index a1d657fcae..a85d9560f5 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NET6_0_OR_GREATER using System; diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs index c927280235..787f952bf9 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NET6_0_OR_GREATER using System; diff --git a/src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs index 5c51b1ac1a..6a1b59aee4 100644 --- a/src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions.AWS/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs index a79e282514..5d3084f096 100644 --- a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs index e960d3e335..8a1a23e00e 100644 --- a/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Extensions.AWS; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs index b682aab1b6..cf6ddf335a 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs index 30506f8c5d..e77fd7723f 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs index 5f93b1b43d..6c47fb4c54 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnricher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs index 79ee8773c2..dfc3d86da1 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Trace/TraceEnrichmentBag.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs index 987fbc1797..8596ce52ad 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Microsoft.Extensions.DependencyInjection; diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs index cf79a3c914..9a20e64e6a 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Linq; diff --git a/src/OpenTelemetry.Extensions/AssemblyInfo.cs b/src/OpenTelemetry.Extensions/AssemblyInfo.cs index 11bfd5a202..f598806af3 100644 --- a/src/OpenTelemetry.Extensions/AssemblyInfo.cs +++ b/src/OpenTelemetry.Extensions/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index 249df72fcd..3ee84a53f9 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index 2f887ff53f..aca7fe4301 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index 1b199c2832..0e56043645 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs index fa79214378..e24760018f 100644 --- a/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs +++ b/src/OpenTelemetry.Extensions/Logs/LogToActivityEventConversionOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index 3adf9de5c1..1d0ae3a831 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs index 5a1827916c..ad582c8777 100644 --- a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs +++ b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index f105c9243b..d64fb7c5cd 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs index 26a2f23bf7..3d729b7c06 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.AWS; diff --git a/src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs index 20214c63cb..c985a86a5a 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs index fcf76b66d2..bf253fafde 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSClientsInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Amazon.Runtime.Internal; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs index d2eaf8d0d6..5d8fb79d56 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSMessagingUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index cdcfedb829..dc5bbda9ad 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.AWS.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index 5b34950512..e940ba2f39 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using Amazon.Runtime; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs index b73e4186b3..23c73b344a 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index b786b30600..d91bd8caf7 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Amazon.Runtime; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 51c970d0dc..4ec869eedb 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs index 2e4d58461a..9a5eba3b8f 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Linq; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs index 3b0b110246..33feb38172 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Linq; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs index cfe932fa50..a01fe129c4 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index e7f31fc770..d522d4231f 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.AWS; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs index 8930b25a49..df3f8befc6 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.AWSLambda; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 0390cc2c4f..223a529417 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs index 573a6e313a..9bfa12f9ef 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index d0633e2979..d777339d37 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs index c6b384f694..4446468214 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs index a5bb50bcef..79185bcf60 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 4cc53fee43..adcb083eb7 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs index 3353391c74..8d6a205f7d 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs index cfddd75eb9..5a55bd5ced 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/CommonExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs index 42e5d733bf..19ef943819 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index fadcd4b7fa..6ad9f989af 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs index 5b82fb5eda..19b01e6726 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AspNetTelemetryEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs index 5f10011c2f..16f09c26bb 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index ed23433fff..020f8705d6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs index d71f8d19e2..67ccffa777 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModuleOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs index fd274fb947..380b945d94 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.AspNet.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs index f2c486e2d5..21fb7fa442 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs index fccbf77437..be7b92e110 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Metrics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs index c93b3a9c26..e048e22990 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Web; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs index 0f14529a44..7926c0564e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AssemblyInfo.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Runtime.CompilerServices; #if SIGNED diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs index 9d3d6ab35c..167e616253 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index 09d1783253..bcca75907c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index 8ce43d5675..8428e8d8d5 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs index f69f013a7c..3ac3dbdac6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.AspNet; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs index 14e6bc4e2c..984620cc25 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs index 3394dcc287..5df6ae2d43 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.AspNet; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs index c695b5dc43..c24e12c1ef 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Cassandra; using Cassandra.Metrics; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs index 61f18c904e..aa0420e2f5 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraDriverMetricsProvider.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Cassandra.Metrics; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs index 7d48a76c99..d2e13177c6 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs index b7d21a9e25..b418428479 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverCounter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; using Cassandra.Metrics.Abstractions; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs index 91da2e0f99..8e2e2c8f4c 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Metrics; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs index e565d75834..d11eb11052 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverMeter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; using Cassandra.Metrics.Abstractions; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs index abc04027e5..473f450198 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverTimer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; using Cassandra.Metrics.Abstractions; diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs index 3597d89cfd..215f572153 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/MeterProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Instrumentation.Cassandra; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs index a1269567c5..509ecb6e18 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentation.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System; using OpenTelemetry.Instrumentation.ElasticsearchClient.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index 6030bc4a80..dcb91ef5c1 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs index 757eb90ce9..a9f78c9e79 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 37d54912ba..088b5ac32c 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System; using System.Collections.Concurrent; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs index c9569e0a55..640c51d53c 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Properties/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index 8933b157f4..c809d5aa7c 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Microsoft.Extensions.DependencyInjection; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 2b544c9c03..26574973eb 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 264bbd20c8..eb16fad1fd 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Data; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 5a1ba2f6bb..d53a1edefc 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Data; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index b132094cf6..91840a1501 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs index e35b4a6565..7e447d9e97 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Properties/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index 3a429a0bca..a40d6885c1 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Microsoft.Extensions.DependencyInjection; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs index a05b4e8d11..55e7a422e6 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs index ecf08249fd..caea7a6ae0 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index d2a4d15ba1..460cd1b286 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Concurrent; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index 669d70a341..fe804a8dee 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.EventCounters; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs index f40f68ad0a..c5569309c5 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index d440730f74..0b67d80637 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Threading; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index b010e47724..7cc0219ef1 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Threading.Tasks; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index b1ea6d2a72..3742a3e5a7 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index a7a8a4b10d..e97af9772a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs index ff4ee15c88..7dee524966 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index 0c7a6a80c0..7375ee27f3 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index d5c8c6d882..6a05450b31 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs index 3746e3fb60..a7ba26b373 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.GrpcCore; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index f6c69776b2..781fafe430 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Threading.Tasks; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index 919dd8a0da..89aebd97e1 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index 3b982d0c08..c158b15da5 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs index 3ab16404c2..67ab4e9701 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Instrumentation.GrpcCore; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs index e732f2a66c..447c3bc902 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Hangfire; diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index 2c03735dea..163f4c235a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs index 9ef7f77858..ad99b0bf3f 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationConstants.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 3312ec136b..03c12fc944 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs index 742b37a61d..4c9d5c7147 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Microsoft.Extensions.DependencyInjection; diff --git a/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs index b0f0a095c5..5da9285075 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AppBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using OpenTelemetry.Instrumentation.Owin; diff --git a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs index b1a23d9f66..c099854855 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 525a76395a..de1e5af64c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index dcf20a8cb5..7537360628 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index be5229504e..1ac5514375 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs index b19e7a47f2..e984eb8c9c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; using System.Reflection; diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs index e2066bd396..a7b6a6d52a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinEnrichEventType.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs index fc6a0408f4..01ea374ba4 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationMeterProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Instrumentation.Owin.Implementation; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index a8d7206376..3c1ba76356 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index 9a3e39835f..6fe62ea930 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.Owin; diff --git a/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs index dfc38d71b6..ac49604063 100644 --- a/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index 11ce49531a..7aede241ca 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Instrumentation.Process; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs index 2f168f0e07..28a54b6d7c 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Process; diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 222eccaf8f..78856ef4a3 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index b8eb5a1c64..9b30de1c1a 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs index 03a88401fd..306a4f16dd 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs index 9adff0e9be..d6307b0a38 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/TagName.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Quartz.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs index 4a1e6ed492..3b60d83050 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/OperationName.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Quartz; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs index 1dc6256128..7ee636521e 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Properties/AssemblyInfo.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Runtime.CompilerServices; #if SIGNED diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index 59d5341d40..a7b099ca4b 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs index d33e6692bb..4ae531dd04 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.Quartz.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index 07001935a9..dcb980eec9 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.Quartz; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs index fd9413b83e..699ae92124 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 1baf6ef0da..d73997022d 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.Runtime; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs index 6af9681b3e..6c1b2c43da 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Runtime; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index bdbd4f2821..33d9a42bef 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs index b5227c02e1..c6326279b7 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index aef136e3e7..0d13c2d13d 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Net; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs index 5d93294c0f..255ebc0b30 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Concurrent; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs index cd8fdbb3f1..4436a42df4 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.Options; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs index 71a317e756..1e18d25fa5 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index 842b3053c7..ccd7391b21 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs index dfba65b372..ed999de2d0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/AssemblyInfo.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Runtime.CompilerServices; #if SIGNED diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs index 91670619e8..478e41d2eb 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ActionMetadata.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Wcf; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs index c4f1d0c8ea..f223171a63 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs index f9239359b5..8c361b00f7 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Threading; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index 8c4668069a..b356185613 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs index e14a06c258..5f090a040e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs index c7fd6e5db2..fb48262afd 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel.Channels; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs index e45fe3e832..434592a865 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactory.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs index 8aea53040a..9d75369385 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedChannelFactoryBase.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel.Channels; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs index 656cbc8612..5b1a77b560 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs index 6ff53917c6..df4e3fa77b 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs index 6befeeb77b..6886fbe61b 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs index 08516a9a6c..b13039a396 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryState.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs index 73d947ca88..9000da7d37 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs index b3a5eb2b89..cd2903ffa0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryBindingElement.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel.Channels; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs index ded05f325d..d1316c1015 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryClientMessageInspector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.ServiceModel; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs index 538f0da7f4..7099abc494 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryContextMessageProperty.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs index a26ba69720..272096d3c7 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs index 0d2cd08e72..14b56ca30f 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel.Channels; using System.Xml; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs index fbc0101e06..6e970cdbaa 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationReader.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs index 3da6e48686..88bb28c2a2 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryPropagationWriter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel.Channels; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index b934387d01..07b43edf24 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs index 6749eed88d..c14c9fe954 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationConstants.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Wcf; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index 24cace7703..1ac7a91743 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs index 1d3aff89bb..c0b0670819 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryContractBehaviorAttribute.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.ServiceModel.Channels; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs index 1dd52c3a7d..f88d662500 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehavior.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs index c2bd78c1a0..adfdbb9911 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryEndpointBehaviorExtensionElement.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs index b60d922b9c..dfd1710910 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehavior.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System.ServiceModel; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs index 90fb6794af..a512e0644a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TelemetryServiceBehaviorExtensionElement.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs index 4cac3b1bb7..357551b51e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/TracerProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Instrumentation.Wcf; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs index 02b1dbe0e9..4178e45304 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfEnrichEventNames.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Wcf; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs index 17b6b2c8f9..f6a8f30178 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs index 11bfd5a202..f598806af3 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs index 490eb94969..12f60c8fc0 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlob.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.CodeAnalysis; diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs index ad21dba7de..0a687cf57d 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs index ca43ef59cb..a60add2d84 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentStorageAbstractionsEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs index 7ce6e038aa..6f645eafca 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs index 222616cc01..11b377006b 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs index 0ac49adede..7511ecabf0 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.CodeAnalysis; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index dc0b7a154a..f8d6c92d11 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs index 791344a2d9..178021be6c 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs index 60d31fd4e7..a5bd04f473 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Globalization; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs index 4307fae7d4..cf8705c17e 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs index 954cfdf060..6b2272e09c 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index 2784b94c47..aed3403dc4 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK using System; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs index 81e3d6ba4c..2848e95a66 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs index b1f28aa6fc..83b8151a44 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs index b84ce97b17..87b0262b8d 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.ResourceDetectors.AWS; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs index ab546998b6..85c339d6bd 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs index 0b2b1cf262..5e709733b1 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs index 535e67efda..1538215391 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs index a52c3b1526..a806fb8f69 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs index 666289cb13..bc88556a5b 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.ResourceDetectors.AWS.Models; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs index 2345a7ded0..7dfaeed930 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs index 1a9839b6a9..7a9e6f9bac 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.ResourceDetectors.AWS.Models; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs index a54203e6b0..4ec1c3a586 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs index 797aa8eb36..16bf46890a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs index 1b065a4d99..fdeff3214a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Runtime.CompilerServices; #if SIGNED diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs index 1308e81d42..2ecbb76a02 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs index c5d3aa6a06..ba3ca54877 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Net.Http; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs index 7dd118a6fc..09791edfba 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs index 4b85409779..6597a021fd 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.ResourceDetectors.Azure; diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs b/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs index 1aa65851e9..dd603e363f 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/SourceGenerationContext.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NET6_0_OR_GREATER using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs index 874cf880ac..4f64462bda 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs index 7525df7c27..2eac9e80b2 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerExtensionsEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs index c0acba8b91..3b34d794b3 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs index 2400ecc61b..16684f40da 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerSemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.ResourceDetectors.Container; diff --git a/src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs b/src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs index eb258ef92f..7540c14554 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/Utils/EncodingUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Linq; diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs index fd4de980dc..6f887cadae 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs index c0119b5fa4..38cfb3315e 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK using System; diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs index affe9b6f24..42239f02cf 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeSemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.ResourceDetectors.ProcessRuntime; diff --git a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs index de9bfe5f04..d7eb533244 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSSamplerEventSource.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs index 179de0ec3b..19a9da8734 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs index 4c8497ede1..2a6e0f94d9 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index c89822cf8f..b911038376 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs index c13fb204d6..b4485a3333 100644 --- a/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs +++ b/src/OpenTelemetry.Sampler.AWS/AssemblyInfo.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Runtime.CompilerServices; #if SIGNED diff --git a/src/OpenTelemetry.Sampler.AWS/Clock.cs b/src/OpenTelemetry.Sampler.AWS/Clock.cs index 1043e4aa36..b50e9c51dc 100644 --- a/src/OpenTelemetry.Sampler.AWS/Clock.cs +++ b/src/OpenTelemetry.Sampler.AWS/Clock.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs index 72d756b322..bf92a8ec97 100644 --- a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs index 2d6234c12a..44d1dd2743 100644 --- a/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs index f7bafb0921..d24c96bd51 100644 --- a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs index 1490e5e6d7..7ec53f577b 100644 --- a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.Sampler.AWS/Matcher.cs b/src/OpenTelemetry.Sampler.AWS/Matcher.cs index e135293e9f..a70c30fbe4 100644 --- a/src/OpenTelemetry.Sampler.AWS/Matcher.cs +++ b/src/OpenTelemetry.Sampler.AWS/Matcher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs index 91d9f52dae..540fc8a491 100644 --- a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs +++ b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Threading; diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs b/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs index 37d904f526..d54cc744f5 100644 --- a/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/RateLimitingSampler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs index 3e8efce9c3..3af0a34d75 100644 --- a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs index c4907675b5..e84d3ce22e 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index 3450c30577..9d9df706fa 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Linq; diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs index 0387908054..a4e28c274d 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleRecord.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs b/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs index f452808e95..454969f293 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingStatisticsDocument.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs b/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs index 3fa7091b73..9745548423 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingTargetDocument.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; diff --git a/src/OpenTelemetry.Sampler.AWS/Statistics.cs b/src/OpenTelemetry.Sampler.AWS/Statistics.cs index e278aab772..2b209eff7e 100644 --- a/src/OpenTelemetry.Sampler.AWS/Statistics.cs +++ b/src/OpenTelemetry.Sampler.AWS/Statistics.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Sampler.AWS; diff --git a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs index 4f23ae6704..fa0e5a2d9f 100644 --- a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs +++ b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs b/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs index 9b03449b2f..fac304856f 100644 --- a/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs +++ b/src/OpenTelemetry.Sampler.AWS/UnprocessedStatistic.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text.Json.Serialization; diff --git a/src/Shared/ActivityInstrumentationHelper.cs b/src/Shared/ActivityInstrumentationHelper.cs index 1c2f97ce70..cf7b926dcd 100644 --- a/src/Shared/ActivityInstrumentationHelper.cs +++ b/src/Shared/ActivityInstrumentationHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable disable diff --git a/src/Shared/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs index 7facd8d529..db48fc0418 100644 --- a/src/Shared/DiagnosticSourceListener.cs +++ b/src/Shared/DiagnosticSourceListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index 22ff829380..3e2cc66609 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/src/Shared/ExceptionExtensions.cs b/src/Shared/ExceptionExtensions.cs index 722d91aa75..1f1e906a11 100644 --- a/src/Shared/ExceptionExtensions.cs +++ b/src/Shared/ExceptionExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index b5415c4482..3222a307b3 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/src/Shared/IsExternalInit.cs b/src/Shared/IsExternalInit.cs index c0809ffb0e..2afeaf2d6d 100644 --- a/src/Shared/IsExternalInit.cs +++ b/src/Shared/IsExternalInit.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER namespace System.Runtime.CompilerServices; diff --git a/src/Shared/ListenerHandler.cs b/src/Shared/ListenerHandler.cs index ff96f005f7..33a80a1dc6 100644 --- a/src/Shared/ListenerHandler.cs +++ b/src/Shared/ListenerHandler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/src/Shared/MultiTypePropertyFetcher.cs b/src/Shared/MultiTypePropertyFetcher.cs index 4c8fb3fb0c..696a7bd7ad 100644 --- a/src/Shared/MultiTypePropertyFetcher.cs +++ b/src/Shared/MultiTypePropertyFetcher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable disable diff --git a/src/Shared/NullableAttributes.cs b/src/Shared/NullableAttributes.cs index 78bcfeab9a..c471bbe613 100644 --- a/src/Shared/NullableAttributes.cs +++ b/src/Shared/NullableAttributes.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 // Source: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index 25cc264df6..8b3acfd21f 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable disable diff --git a/src/Shared/PropertyFetcher.cs b/src/Shared/PropertyFetcher.cs index 4549699132..7f75d22e7c 100644 --- a/src/Shared/PropertyFetcher.cs +++ b/src/Shared/PropertyFetcher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable disable diff --git a/src/Shared/ResourceSemanticConventions.cs b/src/Shared/ResourceSemanticConventions.cs index a6a8c9a72c..4b4aa6a9ea 100644 --- a/src/Shared/ResourceSemanticConventions.cs +++ b/src/Shared/ResourceSemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Trace; diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index e4040c6b11..9129802570 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Trace; diff --git a/src/Shared/SpanAttributeConstants.cs b/src/Shared/SpanAttributeConstants.cs index 56d107fb80..4d0f6dfa53 100644 --- a/src/Shared/SpanAttributeConstants.cs +++ b/src/Shared/SpanAttributeConstants.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Trace; diff --git a/src/Shared/SpanHelper.cs b/src/Shared/SpanHelper.cs index f7bb9880ff..51d6bb4acb 100644 --- a/src/Shared/SpanHelper.cs +++ b/src/Shared/SpanHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs b/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs index f41534aada..97c967e3aa 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs +++ b/test/OpenTelemetry.AotCompatibility.TestApp/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs b/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs index af79715a55..a1df29f725 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs index f330fcab7f..ced10b60e9 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs index 4e4f6683d0..d0f9fcdc95 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs index 4d22828bda..a15ed037d0 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled will see warnings on using System diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 17ea6d220d..453e80aa8b 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled will see warnings on using System diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs index d063109fca..7a3d9e08a7 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs index 1bc05b08fe..f4ab71afa4 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs index a63680a5bb..d0a102d9d2 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs index 96fafa8fcf..f5924c57e8 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 // Note: When implicit usings are enabled in a project this file will generate // warnings/errors without this suppression. diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs index a275d8d97c..8bee1c8e66 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs index 5c553eb788..73447b95f7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.Logging; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs index 5df8f4a1fc..65ec109add 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using BenchmarkDotNet.Attributes; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 3ae26c253b..15fdb58f00 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs index eb7b96082d..15c08c7d62 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Text; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs index c81d01468e..98aa2a9a71 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using BenchmarkDotNet.Attributes; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs index 1fe4fbd9cd..33d37bf4be 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs index 168d45ed02..5030b79ef3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs index ac7b7f625e..16ccf0abca 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using BenchmarkDotNet.Running; diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index 4137778264..91bed2fc54 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index d528e19fd4..0569d33408 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index 01a7044a0a..62bb2c17c3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 4c5da2e30f..321eaae6c6 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index 737e27bc1d..910bbdcbeb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 7f70ab47c9..2a254a1490 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index f79e4fb278..8cdaa67dfb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs index 906b011d9b..8530dadafa 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index 54e1522223..167234cb87 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 5c6b3fd55e..c27f94b2d2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs index 399c49584e..3a01eb71a2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Text; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 4332125d8a..a13e62608e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index fe023e36b9..1768b03e8e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Net; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs index d2b6ff6332..5528c0bb32 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; using System.Reflection; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs index 8c40e2b3d4..3c8d12c4ca 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Xunit; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs index 076f9f19f2..595b733949 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Concurrent; using System.Net; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs index 67ddb93541..c3d84543eb 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs index bca009a4f1..4116cd9d6d 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Globalization; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs index 0b695a8d70..1df7fa1bc8 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Metrics; using OpenTelemetry.Resources; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs index c48e2a06c8..9c159e0c9e 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index 0381a473e1..f661e5cef7 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs index f6fd0b3945..3e1e14f773 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Exporter.Instana.Implementation; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index a5b3385244..bb56142871 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.IO; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index 7f8a4d6b06..3e426a591a 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs index 5318918f64..6eaf8dca56 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Threading.Tasks; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs index c09aca7a2f..a27a7f1c52 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Threading.Tasks; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index 4fda20fe75..e9bfc68a48 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #nullable enable diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs index c07c4f12ef..e1acfefb61 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Threading.Tasks; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index 21c2c60ead..7900174973 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Net; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs index 85eef601f1..a2419ef4ee 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/Program.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using BenchmarkDotNet.Running; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs index ab3adfc7c6..8e93368f0b 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text; using System.Text.Json; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs index 37a50d3f6d..06694d1d46 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text; using System.Text.Json; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs index a4ebace172..797cc7f8db 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/ConnectionStringParserTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Xunit; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs index a9d9d8683c..e61360d03f 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections; using System.Text; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs index fa07ae22c8..1229a65179 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Xunit; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index 25f535d6e8..c2ca28a517 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.IO.Compression; using System.Net; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 5642b73b19..ca9bc789b4 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Reflection; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs index 3993f6bd5c..ef7557b529 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorIntegrationTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Text; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs index e157ff08f1..c0cf3497a4 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorOpenTelemetryLoggerOptionsExtensionsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs index 44f983d04d..229e7b8de3 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Text; using OpenTelemetry.Resources; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs index 0d90e90a44..32d7f56352 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Exporter.Stackdriver.Implementation; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index b8be55e226..1c583ef7f2 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index 477140520c..603aea8406 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs index 95f1eb3c56..e71310a487 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Google.Api.Gax.Grpc; using Google.Cloud.Trace.V2; diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs index 2c076a348c..0359482ec3 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/AssemblyInfo.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AssemblyInfo.cs index 15a0b20209..109f28b5f3 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/AssemblyInfo.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Xunit; diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs index 565dd88746..b73736ab3b 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs index 3cf9308ac4..6ebb1b48c6 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Extensions.Enrichment.Tests; diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs index 740f2e3857..b6776c779f 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/MyTraceEnricher2.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Extensions.Enrichment.Tests; diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs index 3c96a9dc5e..804266db42 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs index 1ed3a1256e..61701c1ddb 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 79cf07fbf5..183e59049a 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index 18a58a6add..a18f108d05 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs index b06bd12bec..da5aa38b75 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index e0d057cfe8..3248b3c7d5 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 96dddf36c8..da14b1d019 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index e29faa82df..ab01696ddf 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index b0c79d23e3..c07364329f 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index 8d1f66d5a8..70a02cfe6d 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index 9d1a693f4b..e342f08d33 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index 00b833994b..b021814915 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; #if NETFRAMEWORK diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 7f89215775..80f62d0251 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs index c22998167c..d4c07a0c1c 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/TestAmazonDynamoDBClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Amazon; using Amazon.DynamoDBv2; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs index 1c4bc1348f..7977399179 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index dbb34edc8c..bd7769873e 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 8b89ded1e0..e4bfc5e8bf 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs index 2123f9f72a..43e6fb8d75 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs index 05b38aa56f..3f00ed79ad 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Linq; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index ca9e32ad40..591278fd6e 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Threading.Tasks; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index 2ad2ac4da4..6dc9c9311d 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Amazon.Lambda.Core; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index b5d8216e6a..3a60303dba 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs index cfb810f497..2d4c258eba 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Globalization; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs index 52a4ec2a39..e814d05620 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.IO; using System.Xml.Linq; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs index 9d7b28ec39..aaa625d24a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.IO; using System.Xml.Linq; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs index 15a0b20209..109f28b5f3 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/AssemblyInfo.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs index 1a0ba83dc4..ac5a5360b8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs index 9c90b8ebee..659e835ec3 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/EventSourceTest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Instrumentation.AspNet.Implementation; using OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 3022963248..2e1cd02e4c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index 05a158b9e3..37515d66dc 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs index 4440d64f5a..318d815572 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs index 201df1a6a7..194b2f6972 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Cassandra.Mapping.Attributes; diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs index fc56ad0ef5..51db99e961 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs index fa4ef971e2..369171f5f4 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs index 0205eb1729..6a0775b7f1 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Linq; using System.Threading; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index d873f5fa49..d4370f6ceb 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -1,18 +1,6 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 + using System.Diagnostics; using System.Linq; using System.Text; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs index 8e0b39ef99..201557db3d 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; using System.Threading; diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs index 2832d20da8..ba4b859459 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Linq; using System.Threading; diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index e162527a20..54983d7474 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Data; diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index f68d3121b0..7e6b379d71 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index dd830d6f85..5d762ff3e9 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 2267ae99dd..771eacf1d1 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 13f6f21c50..0e4fba47ba 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index b3aca77c7b..0c43a7e003 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs index 4e36e09ea0..fdfd9488b4 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Linq; using System.Threading; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs index 4c33bb8166..34155407c9 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using Hangfire; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index c1d6ff13b8..39a21b8322 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs index 411209af71..38e6342a6a 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs index 0b9a044ef2..bf7f20b9ae 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Web.Http; diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 1caa391c1f..fa89a01b00 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 819e634f94..a0c829d5d3 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Linq; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 10a3e9ff76..0afc34e73f 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs index 563ee5a834..027ea461cf 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs index bfc2484519..182d8387d6 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Threading.Tasks; using Quartz; diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs index fbb1944954..8b0ab4311f 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 namespace OpenTelemetry.Instrumentation.Runtime.Tests; diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index dc35543ecf..25d8c9278e 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index b2edab72f2..fea0cd30ed 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index d80d1a0f47..a1f1cd6c6e 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs index 6d450e2aca..d1f22c38b8 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System.Collections.Specialized; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs index 9555c64121..c5f48d326c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs index a795fb1046..f2b2a2612c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index 349fb7bf8e..ff10a2a196 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index 2991ca7316..6d11e9eb35 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs index 6029269d0f..57df14f307 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs index 51822f534a..8d52c63e3c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Reflection; using System.ServiceModel.Channels; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs index 0eb05eeb8f..a3aa58c2e4 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs index 9cdb78e58f..41870371b9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Reflection; using System.ServiceModel.Channels; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs index 81a3c6dd35..20c8417239 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel.Channels; using System.ServiceModel.Description; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs index 3b0e5defff..958af96d95 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs index afe5f9e201..2a223d1967 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs index 85af0db661..9c5df1ef11 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index c99e765a86..9764bc69be 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; using System.Threading.Tasks; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 9cc1493135..5b11e79f33 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK using System.ServiceModel; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index c7a0eca6d9..e63d66c906 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; using System.ServiceModel.Channels; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index b262522e6c..c41027301b 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.Serialization; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index 5a61c80ec0..d26066edc6 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Runtime.Serialization; diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs index d349e4107a..77547a8a30 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.IO; using Xunit; diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index 036b321aa4..cc202def9f 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs index 8c6aeb938b..aee14a6c67 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs index 82a6337d84..69822cf28b 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Linq; using Xunit; diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs index e3a5444e58..14c5a5981a 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Linq; using Xunit; diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs index 16e1c5602a..d73363746b 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs index 643a468c97..d5b7dac37b 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs index 1a791bf2e3..8c5a35aedd 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/CertificateUploader.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs index 4a08e6ee05..b7c16d64ca 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index 266d5f6579..9bf5e15a5d 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs index d3a7e3efca..90470886ce 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEBSMetadataModel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.ResourceDetectors.AWS.Models; diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs index b2cefe849a..4e44a4e717 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/SampleAWSEC2IdentityDocumentModel.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.ResourceDetectors.AWS.Models; diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index 1fc402d3e4..7f6f806100 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs index b7dca6d38d..6ed321e0b1 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/ContainerResourceDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.IO; diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs b/test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs index 64c66fe657..1c39f6c073 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/TempFile.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.IO; diff --git a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs index b3fc9255b1..66757886de 100644 --- a/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Linq; using OpenTelemetry.Resources; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index aab1148cdc..4734b966cc 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs index 863024a6cd..bbec7fefec 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index 806f714578..d773ed6b9e 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs index 671810abd2..9c70983e7c 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using Xunit; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs index a0c60c7d29..fe598c733d 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs index 9335667956..1832280e0f 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs index fbfa0fb250..541c5daae7 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs index 35128b85e3..725eabb8f9 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs index 12e00e2ff2..c46a4c7d45 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs @@ -1,18 +1,5 @@ -// // Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +// SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; using System.Diagnostics; From 2fd118941fe5207d2302ad823a9b8e72107360aa Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Thu, 7 Dec 2023 15:00:07 -0800 Subject: [PATCH 0895/1499] [repo] Fix CI for Extensions.* projects (#1472) --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5360bcc91a..59eb715305 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] - extensions: ['*/OpenTelemetry.Extensions*/**', '!**/*.md'] + extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] @@ -46,7 +46,8 @@ jobs: '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', - '!*/OpenTelemetry.Extensions*/**', + '!*/OpenTelemetry.Extensions/**', + '!*/OpenTelemetry.Extensions.Tests/**', '!*/OpenTelemetry.Exporter.Geneva*/**', '!*/OpenTelemetry.Exporter.OneCollector*/**', '!*/OpenTelemetry.Instrumentation.Owin*/**', From 02dde490e29a9ec12d1d680467aaab9a2e3400c5 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 00:13:32 +0100 Subject: [PATCH 0896/1499] Remove Moq from Extensions.AWS.Tests (#1469) --- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 5654e72ae1..68f248e657 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -5,10 +5,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - - - - From 5789848f76ac1ca2e586364333b94f70b6d2e247 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 15:44:20 -0800 Subject: [PATCH 0897/1499] Bump actions/stale from 8 to 9 (#1474) --- .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 e299eaf3a8..9111144a58 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: stale-pr-message: 'This PR was marked stale due to lack of activity. It will be closed in 7 days.' close-pr-message: 'Closed as inactive. Feel free to reopen if this PR is still being worked on.' From fbd09bf47581e13ee741cb27172cbecb0afc47d4 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 08:51:51 +0100 Subject: [PATCH 0898/1499] Remove Moq from Instrumentation.AspNet.Tests (#1471) --- .../TestTextMapPropagator.cs | 26 +++++ .../HttpInListenerTests.cs | 46 ++++----- ...emetry.Instrumentation.AspNet.Tests.csproj | 3 +- .../TestHttpWorkerRequest.cs | 95 +++++++++++++++++++ 4 files changed, 140 insertions(+), 30 deletions(-) create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs new file mode 100644 index 0000000000..12609962a1 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using OpenTelemetry.Context.Propagation; + +namespace OpenTelemetry.Tests; + +internal class TestTextMapPropagator : TextMapPropagator +{ + public Action? Extracted { get; set; } + + public override ISet Fields => throw new NotImplementedException(); + + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + { + this.Extracted?.Invoke(); + return context; + } + + public override void Inject(PropagationContext context, T carrier, Action setter) + { + throw new NotImplementedException(); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 2e1cd02e4c..9959d372ab 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -9,7 +9,6 @@ using System.Reflection; using System.Web; using System.Web.Routing; -using Moq; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.AspNet.Implementation; using OpenTelemetry.Tests; @@ -47,7 +46,7 @@ public void AspNetRequestsAreCollectedSuccessfully( { HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); - typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, Mock.Of()); + typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, new TestHttpWorkerRequest()); List exportedItems = new List(16); @@ -192,20 +191,17 @@ public void ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision sampli new HttpResponse(new StringWriter())); bool isPropagatorCalled = false; - var propagator = new Mock(); - propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) - .Returns(() => - { - isPropagatorCalled = true; - return default; - }); + var propagator = new TestTextMapPropagator + { + Extracted = () => isPropagatorCalled = true, + }; - var activityProcessor = new Mock>(); - Sdk.SetDefaultTextMapPropagator(propagator.Object); + var activityProcessor = new TestActivityProcessor(); + Sdk.SetDefaultTextMapPropagator(propagator); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .SetSampler(new TestSampler(samplingDecision)) .AddAspNetInstrumentation() - .AddProcessor(activityProcessor.Object).Build()) + .AddProcessor(activityProcessor).Build()) { var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); @@ -228,17 +224,14 @@ public void ExtractContextIrrespectiveOfTheFilterApplied() new HttpResponse(new StringWriter())); bool isPropagatorCalled = false; - var propagator = new Mock(); - propagator.Setup(m => m.Extract(It.IsAny(), It.IsAny(), It.IsAny>>())) - .Returns(() => - { - isPropagatorCalled = true; - return default; - }); + var propagator = new TestTextMapPropagator + { + Extracted = () => isPropagatorCalled = true, + }; bool isFilterCalled = false; - var activityProcessor = new Mock>(); - Sdk.SetDefaultTextMapPropagator(propagator.Object); + var activityProcessor = new TestActivityProcessor(); + Sdk.SetDefaultTextMapPropagator(propagator); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetInstrumentation(options => { @@ -248,7 +241,7 @@ public void ExtractContextIrrespectiveOfTheFilterApplied() return false; }; }) - .AddProcessor(activityProcessor.Object).Build()) + .AddProcessor(activityProcessor).Build()) { var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); @@ -286,14 +279,9 @@ void EnrichAction(Activity activity, string method, object obj) return EnrichAction; } - private class TestSampler : Sampler + private class TestSampler(SamplingDecision samplingDecision) : Sampler { - private readonly SamplingDecision samplingDecision; - - public TestSampler(SamplingDecision samplingDecision) - { - this.samplingDecision = samplingDecision; - } + private readonly SamplingDecision samplingDecision = samplingDecision; public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 382363406d..a040ac447c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -6,7 +6,6 @@ - @@ -22,7 +21,9 @@ + + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs new file mode 100644 index 0000000000..c9b1bb5058 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs @@ -0,0 +1,95 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Web; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +internal class TestHttpWorkerRequest : HttpWorkerRequest +{ + public override void EndOfRequest() + { + throw new NotImplementedException(); + } + + public override void FlushResponse(bool finalFlush) + { + throw new NotImplementedException(); + } + + public override string GetHttpVerbName() + { + throw new NotImplementedException(); + } + + public override string GetHttpVersion() + { + throw new NotImplementedException(); + } + + public override string GetLocalAddress() + { + throw new NotImplementedException(); + } + + public override int GetLocalPort() + { + throw new NotImplementedException(); + } + + public override string GetQueryString() + { + throw new NotImplementedException(); + } + + public override string GetRawUrl() + { + throw new NotImplementedException(); + } + + public override string GetRemoteAddress() + { + throw new NotImplementedException(); + } + + public override int GetRemotePort() + { + throw new NotImplementedException(); + } + + public override string GetUriPath() + { + throw new NotImplementedException(); + } + + public override void SendKnownResponseHeader(int index, string value) + { + throw new NotImplementedException(); + } + + public override void SendResponseFromFile(string filename, long offset, long length) + { + throw new NotImplementedException(); + } + + public override void SendResponseFromFile(IntPtr handle, long offset, long length) + { + throw new NotImplementedException(); + } + + public override void SendResponseFromMemory(byte[] data, int length) + { + throw new NotImplementedException(); + } + + public override void SendStatus(int statusCode, string statusDescription) + { + throw new NotImplementedException(); + } + + public override void SendUnknownResponseHeader(string name, string value) + { + throw new NotImplementedException(); + } +} From fbfd66495359a88738bc0f5611bc7728c568ce5a Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 09:48:26 +0100 Subject: [PATCH 0899/1499] Remove Moq from Instrumentation.Cassandra.Tests (#1477) --- .../OpenTelemetry.Instrumentation.Cassandra.Tests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index c43e9fa441..2b8f6f953d 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -7,7 +7,6 @@ - From bf4c252ba701840113782d8875f2872614e7bca5 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 19:05:26 +0100 Subject: [PATCH 0900/1499] Remove Moq from Extensions.Tests (#1470) Co-authored-by: Cijo Thomas --- .../OpenTelemetry.Extensions.Tests.csproj | 5 +++- .../Trace/AutoFlushActivityProcessorTests.cs | 23 +++++++++---------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index de5d53c8f6..393df0e152 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -8,7 +8,6 @@ - @@ -16,4 +15,8 @@ + + + + diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index a18f108d05..7009420a97 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -4,8 +4,7 @@ using System; using System.Diagnostics; using System.Runtime.CompilerServices; -using Moq; -using Moq.Protected; +using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; @@ -13,14 +12,14 @@ namespace OpenTelemetry.Extensions.Tests.Trace; public class AutoFlushActivityProcessorTests { - [Fact(Skip = "Unstable")] + [Fact] public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMatchingSpan_Flush() { - var mockExporting = new Mock>(); + var activityProcessor = new TestActivityProcessor(); var sourceName = GetTestMethodName(); using var provider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(mockExporting.Object) + .AddProcessor(activityProcessor) .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000) .AddSource(sourceName) .Build(); @@ -30,17 +29,17 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndMat Assert.NotNull(activity); activity.Stop(); - mockExporting.Protected().Verify("OnForceFlush", Times.Once(), 5_000); + Assert.True(activityProcessor.ForceFlushCalled); } [Fact] public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNonMatchingSpan_DoesNothing() { - var mockExporting = new Mock>(); + var activityProcessor = new TestActivityProcessor(); var sourceName = GetTestMethodName(); using var provider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(mockExporting.Object) + .AddProcessor(activityProcessor) .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer)) .AddSource(sourceName) .Build(); @@ -50,17 +49,17 @@ public void AutoFlushActivityProcessor_FlushAfterLocalServerSideRootSpans_EndNon Assert.NotNull(activity); activity.Stop(); - mockExporting.Protected().Verify("OnForceFlush", Times.Never(), It.IsAny()); + Assert.False(activityProcessor.ForceFlushCalled); } [Fact] public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() { - var mockExporting = new Mock>(); + var activityProcessor = new TestActivityProcessor(); var sourceName = GetTestMethodName(); using var provider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(mockExporting.Object) + .AddProcessor(activityProcessor) .AddAutoFlushActivityProcessor(_ => throw new Exception("Predicate throws an exception.")) .AddSource(sourceName) .Build(); @@ -70,7 +69,7 @@ public void AutoFlushActivityProcessor_PredicateThrows_DoesNothing() Assert.NotNull(activity); activity.Stop(); - mockExporting.Protected().Verify("OnForceFlush", Times.Never(), 5_000); + Assert.False(activityProcessor.ForceFlushCalled); } private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") From a09f795f907c5153556b3d330840501d3fa3e47b Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 19:21:16 +0100 Subject: [PATCH 0901/1499] Remove Moq from Exporter.Instana.Tests (#1465) Co-authored-by: Cijo Thomas --- .../Properties/AssemblyInfo.cs | 3 - .../InstanaExporterTests.cs | 81 +++++++------------ ...penTelemetry.Exporter.Instana.Tests.csproj | 1 - .../TestActivityProcessor.cs | 20 +++++ .../TestInstanaExporterHelper.cs | 23 ++++++ .../TestSpanSender.cs | 17 ++++ 6 files changed, 89 insertions(+), 56 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs create mode 100644 test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs diff --git a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs index 18dfea566b..58a9dd4fd1 100644 --- a/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Properties/AssemblyInfo.cs @@ -4,18 +4,15 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Instana.Tests" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED internal static class AssemblyInfo { public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898"; - public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; } #else internal static class AssemblyInfo { public const string PublicKey = ""; - public const string MoqPublicKey = ""; } #endif diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index f661e5cef7..5f705fef55 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -1,44 +1,36 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; -using System.Threading.Tasks; -using Moq; using OpenTelemetry.Exporter.Instana.Implementation; -using OpenTelemetry.Exporter.Instana.Implementation.Processors; -using OpenTelemetry.Resources; using Xunit; namespace OpenTelemetry.Exporter.Instana.Tests; public class InstanaExporterTests { - private readonly Mock instanaExporterHelperMock = new Mock(MockBehavior.Strict); - private readonly Mock activityProcessorMock = new Mock(MockBehavior.Strict); - private readonly Mock spanSenderMock = new Mock(MockBehavior.Strict); + private readonly TestInstanaExporterHelper instanaExporterHelper = new(); + private readonly TestActivityProcessor activityProcessor = new(); + private readonly TestSpanSender spanSender = new(); private InstanaSpan instanaSpan; private InstanaExporter instanaExporter; [Fact] public void Export() { - this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) - .Returns(() => Task.CompletedTask); + this.instanaExporterHelper.Attributes.Clear(); + this.instanaExporterHelper.Attributes.Add("service.name", "serviceName"); + this.instanaExporterHelper.Attributes.Add("service.instance.id", "serviceInstanceId"); + this.instanaExporterHelper.Attributes.Add("process.pid", "processPid"); + this.instanaExporterHelper.Attributes.Add("host.id", "hostId"); - this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); - this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) - .Returns(new Resource(new Dictionary() - { - { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, - { "process.pid", "processPid" }, { "host.id", "hostId" }, - })); + this.spanSender.OnEnqueue = span => this.CloneSpan(span); - this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); - - this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); - this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; - this.instanaExporter.SpanSender = this.spanSenderMock.Object; + this.instanaExporter = new InstanaExporter(this.activityProcessor) + { + InstanaExporterHelper = this.instanaExporterHelper, + SpanSender = this.spanSender, + }; Activity activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); @@ -48,8 +40,6 @@ public void Export() Batch batch = new Batch(activities, activities.Length); var result = this.instanaExporter.Export(in batch); - this.VerifyAllMocks(); - Assert.Equal(ExportResult.Success, result); Assert.NotNull(this.instanaSpan); Assert.Equal("processPid", this.instanaSpan.F.E); @@ -62,22 +52,18 @@ public void Export() [Fact] public void Export_ProcessPidDoesNotExistButServiceIdExists() { - this.activityProcessorMock.Setup(x => x.ProcessAsync(It.IsAny(), It.IsAny())) - .Returns(() => Task.CompletedTask); + this.instanaExporterHelper.Attributes.Clear(); + this.instanaExporterHelper.Attributes.Add("service.name", "serviceName"); + this.instanaExporterHelper.Attributes.Add("service.instance.id", "serviceInstanceId"); + this.instanaExporterHelper.Attributes.Add("host.id", "hostId"); - this.instanaExporterHelperMock.Setup(x => x.IsWindows()).Returns(false); - this.instanaExporterHelperMock.Setup(x => x.GetParentProviderResource(It.IsAny>())) - .Returns(new Resource(new Dictionary() - { - { "service.name", "serviceName" }, { "service.instance.id", "serviceInstanceId" }, - { "host.id", "hostId" }, - })); + this.spanSender.OnEnqueue = span => this.CloneSpan(span); - this.spanSenderMock.Setup(x => x.Enqueue(It.Is(y => this.CloneSpan(y)))); - - this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); - this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; - this.instanaExporter.SpanSender = this.spanSenderMock.Object; + this.instanaExporter = new InstanaExporter(this.activityProcessor) + { + InstanaExporterHelper = this.instanaExporterHelper, + SpanSender = this.spanSender, + }; Activity activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); @@ -86,8 +72,6 @@ public void Export_ProcessPidDoesNotExistButServiceIdExists() Batch batch = new Batch(activities, activities.Length); var result = this.instanaExporter.Export(in batch); - this.VerifyAllMocks(); - Assert.Equal(ExportResult.Success, result); Assert.NotNull(this.instanaSpan); Assert.Equal("serviceInstanceId", this.instanaSpan.F.E); @@ -99,9 +83,11 @@ public void Export_ProcessPidDoesNotExistButServiceIdExists() [Fact] public void Export_ExporterIsShotDown() { - this.instanaExporter = new InstanaExporter(activityProcessor: this.activityProcessorMock.Object); - this.instanaExporter.InstanaExporterHelper = this.instanaExporterHelperMock.Object; - this.instanaExporter.SpanSender = this.spanSenderMock.Object; + this.instanaExporter = new InstanaExporter(this.activityProcessor) + { + InstanaExporterHelper = this.instanaExporterHelper, + SpanSender = this.spanSender, + }; Activity activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); @@ -112,8 +98,6 @@ public void Export_ExporterIsShotDown() Batch batch = new Batch(activities, activities.Length); var result = this.instanaExporter.Export(in batch); - this.VerifyAllMocks(); - Assert.Equal(ExportResult.Failure, result); Assert.Null(this.instanaSpan); } @@ -123,11 +107,4 @@ private bool CloneSpan(InstanaSpan span) this.instanaSpan = span; return true; } - - private void VerifyAllMocks() - { - this.instanaExporterHelperMock.VerifyAll(); - this.activityProcessorMock.VerifyAll(); - this.spanSenderMock.VerifyAll(); - } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index b043f5f018..689b764d11 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -8,7 +8,6 @@ - diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs new file mode 100644 index 0000000000..da660e8c08 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using OpenTelemetry.Exporter.Instana.Implementation; +using OpenTelemetry.Exporter.Instana.Implementation.Processors; + +namespace OpenTelemetry.Exporter.Instana.Tests; + +internal class TestActivityProcessor : IActivityProcessor +{ + public IActivityProcessor NextProcessor { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) + { + return Task.CompletedTask; + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs new file mode 100644 index 0000000000..e6fb2fb69b --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using System.Diagnostics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Instana.Tests; + +internal class TestInstanaExporterHelper : IInstanaExporterHelper +{ + public Dictionary Attributes { get; } = new(); + + public Resource GetParentProviderResource(BaseExporter otelExporter) + { + return new Resource(this.Attributes); + } + + public bool IsWindows() + { + return false; + } +} diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs new file mode 100644 index 0000000000..054dea7235 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using OpenTelemetry.Exporter.Instana.Implementation; + +namespace OpenTelemetry.Exporter.Instana.Tests; + +internal class TestSpanSender : ISpanSender +{ + public Action OnEnqueue { get; set; } + + public void Enqueue(InstanaSpan instanaSpan) + { + this.OnEnqueue?.Invoke(instanaSpan); + } +} From 46a188f13c1faf1c10775cc4e69bbfaadb32f78d Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 20:36:27 +0100 Subject: [PATCH 0902/1499] Remove Moq from Instrumentation.Wcf.Tests (#1482) --- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 1c0d57c992..f95d11bd98 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -11,10 +11,6 @@ - - - - From cf9180ecfe237afec253ca6d13f9a5c83abec51d Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 20:47:20 +0100 Subject: [PATCH 0903/1499] Remove Moq from Instrumentation.Quartz.Tests (#1480) --- ...emetry.Instrumentation.Quartz.Tests.csproj | 2 +- .../QuartzDiagnosticListenerTests.cs | 49 +++++++++---------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 7a505404b8..d8b0c23530 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -9,8 +9,8 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 0afc34e73f..98e4b03631 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -7,7 +7,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Moq; using OpenTelemetry.Trace; using Quartz; using Xunit; @@ -30,11 +29,11 @@ public async Task Should_Create_Activity() Barrier barrier = new Barrier(2); List jobExecTimestamps = new List(); - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) .AddQuartzInstrumentation() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .Build(); var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); schedulerConfig.UseDefaultThreadPool(x => x.MaxConcurrency = 10); @@ -65,8 +64,8 @@ public async Task Should_Create_Activity() await scheduler.Shutdown(true); // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; Assert.Contains("execute ", activity.DisplayName); Assert.Equal("Quartz.Job.Execute", activity.OperationName); @@ -83,7 +82,7 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() Barrier barrier = new Barrier(2); List jobExecTimestamps = new List(); - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -99,7 +98,7 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() } } }) - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .Build(); var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); @@ -132,8 +131,8 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() await scheduler.Shutdown(true); // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; Assert.Equal("Quartz.Job.Execute", activity.OperationName); Assert.Equal(ActivityKind.Internal, activity.Kind); @@ -150,13 +149,13 @@ public async Task Should_Record_Exception_When_Record_Exception_Enabled() Barrier barrier = new Barrier(2); List jobExecTimestamps = new List(); - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) .AddQuartzInstrumentation(q => q.RecordException = true) - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .Build(); var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); @@ -189,8 +188,8 @@ public async Task Should_Record_Exception_When_Record_Exception_Enabled() await scheduler.Shutdown(true); // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; Assert.Equal("exception", activity.Events.First().Name); Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); @@ -204,7 +203,7 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri Barrier barrier = new Barrier(2); List jobExecTimestamps = new List(); - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -223,7 +222,7 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri } }; }) - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .Build(); var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); @@ -256,8 +255,8 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri await scheduler.Shutdown(true); // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); @@ -271,7 +270,7 @@ public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() Barrier barrier = new Barrier(2); List jobExecTimestamps = new List(); - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) .AddQuartzInstrumentation(q => @@ -285,7 +284,7 @@ public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() } }; }) - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .Build(); var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); @@ -318,8 +317,8 @@ public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() await scheduler.Shutdown(true); // Assert - Assert.Equal(3, activityProcessor.Invocations.Count); - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; Assert.Equal("exception", activity.Events.First().Name); Assert.Equal("Quartz.JobExecutionException", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionType)).Value); Assert.Equal("Catch me if you can!", activity.Events.First().Tags.SingleOrDefault(t => t.Key.Equals(SemanticConventions.AttributeExceptionMessage)).Value); @@ -332,7 +331,7 @@ public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present Barrier barrier = new Barrier(2); List jobExecTimestamps = new List(); - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -340,7 +339,7 @@ public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present { q.TracedOperations = new HashSet(); }) - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .Build(); var schedulerConfig = SchedulerBuilder.Create("AUTO", "Scheduler"); @@ -373,8 +372,6 @@ public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present await scheduler.Shutdown(true); // Assert - var activities = activityProcessor.Invocations.SelectMany(i => i.Arguments.OfType()) - .Where(a => a.IsAllDataRequested); - Assert.Empty(activities); + Assert.Empty(exportedItems); } } From 2ba2ddd0481b0351877ef960bb5d13d2fb42f571 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 21:09:17 +0100 Subject: [PATCH 0904/1499] Remove Moq from Instrumentation.ElasticsearchClient.Tests (#1478) --- .../ElasticsearchClientTests.cs | 150 +++++++----------- ...mentation.ElasticsearchClient.Tests.csproj | 2 +- 2 files changed, 57 insertions(+), 95 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index d4370f6ceb..8507a98adf 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -1,12 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Elasticsearch.Net; -using Moq; using Nest; using OpenTelemetry.Resources; using OpenTelemetry.Tests; @@ -27,7 +27,7 @@ public ElasticsearchClientTests() public async Task CanCaptureGetById() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -37,7 +37,7 @@ public async Task CanCaptureGetById() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var getResponse = await client.GetAsync("123"); @@ -49,12 +49,9 @@ public async Task CanCaptureGetById() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Single(exportedItems); - var searchActivity = activities[0]; + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -82,7 +79,7 @@ public async Task CanCaptureGetById() public async Task CanCaptureGetByIdNotFound() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -92,7 +89,7 @@ public async Task CanCaptureGetByIdNotFound() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var getResponse = await client.GetAsync("123"); @@ -104,12 +101,9 @@ public async Task CanCaptureGetByIdNotFound() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); + Assert.Single(exportedItems); - var searchActivity = activities[0]; + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -137,7 +131,7 @@ public async Task CanCaptureGetByIdNotFound() public async Task CanCaptureSearchCall() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -147,7 +141,7 @@ public async Task CanCaptureSearchCall() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -159,12 +153,8 @@ public async Task CanCaptureSearchCall() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -372,7 +362,7 @@ public async Task CanDropSearchCall() public async Task CanCaptureSearchCallWithDebugMode() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -382,7 +372,7 @@ public async Task CanCaptureSearchCallWithDebugMode() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -394,12 +384,8 @@ public async Task CanCaptureSearchCallWithDebugMode() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -427,7 +413,7 @@ public async Task CanCaptureSearchCallWithDebugMode() public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -437,7 +423,7 @@ public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation(o => o.ParseAndFormatRequest = true) .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -449,12 +435,8 @@ public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -497,7 +479,7 @@ public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() public async Task CanCaptureSearchCallWithoutDebugMode() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -507,7 +489,7 @@ public async Task CanCaptureSearchCallWithoutDebugMode() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation(o => o.ParseAndFormatRequest = true) .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -519,12 +501,8 @@ public async Task CanCaptureSearchCallWithoutDebugMode() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -552,7 +530,7 @@ public async Task CanCaptureSearchCallWithoutDebugMode() public async Task CanCaptureMultipleIndiceSearchCall() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -562,7 +540,7 @@ public async Task CanCaptureMultipleIndiceSearchCall() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -574,12 +552,8 @@ public async Task CanCaptureMultipleIndiceSearchCall() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -607,7 +581,7 @@ public async Task CanCaptureMultipleIndiceSearchCall() public async Task CanCaptureElasticsearchClientException() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -618,7 +592,7 @@ public async Task CanCaptureElasticsearchClientException() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -630,12 +604,8 @@ public async Task CanCaptureElasticsearchClientException() Assert.NotEmpty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -664,7 +634,7 @@ public async Task CanCaptureElasticsearchClientException() public async Task CanCaptureCatRequest() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -674,7 +644,7 @@ public async Task CanCaptureCatRequest() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var getResponse = await client.Cat.IndicesAsync(); @@ -686,12 +656,8 @@ public async Task CanCaptureCatRequest() Assert.Empty(failed); } - // SetParentProvider, OnStart, OnEnd, OnShutdown, Dispose - Assert.Equal(5, processor.Invocations.Count); - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; Assert.Equal(parent.TraceId, searchActivity.Context.TraceId); Assert.Equal(parent.SpanId, searchActivity.ParentSpanId); @@ -719,7 +685,7 @@ public async Task CanCaptureCatRequest() public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -729,7 +695,7 @@ public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { using var scope = SuppressInstrumentationScope.Begin(); @@ -743,11 +709,7 @@ public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() } // Since instrumentation is suppressed, activity is not emitted - Assert.Equal(3, processor.Invocations.Count); // SetParentProvider + OnShutdown + Dispose - - // Processor.OnStart and Processor.OnEnd are not called - Assert.DoesNotContain(processor.Invocations, invo => invo.Method.Name == nameof(processor.Object.OnStart)); - Assert.DoesNotContain(processor.Invocations, invo => invo.Method.Name == nameof(processor.Object.OnEnd)); + Assert.Empty(exportedItems); } [Theory] @@ -757,7 +719,11 @@ public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecision, bool isActivityExpected) { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + bool startActivityCalled = false; + bool endActivityCalled = false; + var processor = new TestActivityProcessor( + activity => startActivityCalled = true, + activity => endActivityCalled = true); var parent = new Activity("parent").Start(); @@ -767,7 +733,7 @@ public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecis .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddProcessor(processor) .Build()) { var getResponse = await client.GetAsync("123"); @@ -779,15 +745,15 @@ public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecis Assert.Empty(failed); } - Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnStart))); - Assert.Equal(isActivityExpected, processor.Invocations.Any(invo => invo.Method.Name == nameof(processor.Object.OnEnd))); + Assert.Equal(isActivityExpected, startActivityCalled); + Assert.Equal(isActivityExpected, endActivityCalled); } [Fact] public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -797,7 +763,7 @@ public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation(o => o.SetDbStatementForRequest = false) .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -809,10 +775,8 @@ public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() Assert.Empty(failed); } - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); Assert.Null(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); @@ -822,7 +786,7 @@ public async Task DbStatementIsNotDisplayedWhenSetDbStatementForRequestIsFalse() public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDefaultValue() { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -832,7 +796,7 @@ public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDe .SetSampler(new AlwaysOnSampler()) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); @@ -844,10 +808,8 @@ public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDe Assert.Empty(failed); } - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.Single(activities); - - var searchActivity = activities[0]; + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); Assert.NotNull(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 3247babb27..aae7ec64e9 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -9,8 +9,8 @@ - + From 707d9c086bbdeb9832a41c5235b1733fc5f33138 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Fri, 8 Dec 2023 23:59:28 +0100 Subject: [PATCH 0905/1499] Remove Moq from Instrumentation.GrpcCore.Tests (#1468) Co-authored-by: Cijo Thomas --- .../AssemblyInfo.cs | 3 -- .../TestTextMapPropagator.cs | 8 ++- .../GrpcCoreClientInterceptorTests.cs | 49 ++++++++----------- ...etry.Instrumentation.GrpcCore.Tests.csproj | 5 +- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs index c5569309c5..85348bc891 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AssemblyInfo.cs @@ -4,18 +4,15 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.GrpcCore.Tests" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED internal static class AssemblyInfo { public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; - public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; } #else internal static class AssemblyInfo { public const string PublicKey = ""; - public const string MoqPublicKey = ""; } #endif diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs index 12609962a1..5362b89fbd 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs @@ -9,6 +9,8 @@ namespace OpenTelemetry.Tests; internal class TestTextMapPropagator : TextMapPropagator { + public Action>? OnInject { get; set; } + public Action? Extracted { get; set; } public override ISet Fields => throw new NotImplementedException(); @@ -21,6 +23,10 @@ public override PropagationContext Extract(PropagationContext context, T carr public override void Inject(PropagationContext context, T carrier, Action setter) { - throw new NotImplementedException(); + var newAction = new Action((c, k, v) => setter(c, k, v)); + this.OnInject?.Invoke( + context, + carrier, + new Action((c, k, v) => setter((T)c, k, v))); } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 771eacf1d1..c665abdf5a 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -8,8 +8,8 @@ using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; -using Moq; using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Tests; using Xunit; namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; @@ -365,40 +365,33 @@ static void ValidateCommonEventAttributes(ActivityEvent activityEvent) /// A Task. private static async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata) { - var mockPropagator = new Mock(); + var propagator = new TestTextMapPropagator(); PropagationContext capturedPropagationContext = default; Metadata capturedCarrier = null; var propagatorCalled = 0; var originalMetadataCount = additionalMetadata.Count; - mockPropagator - .Setup( - x => x.Inject( - It.IsAny(), - It.IsAny(), - It.IsAny>())) - .Callback>( - (propagation, carrier, setter) => - { - propagatorCalled++; - capturedPropagationContext = propagation; - capturedCarrier = carrier; - - // Make sure the original metadata make it through - if (additionalMetadata != null) - { - Assert.Equal(capturedCarrier, additionalMetadata); - } - - // Call the actual setter to ensure it updates the carrier. - // It doesn't matter what we put in - setter(capturedCarrier, "bar", "baz"); - }); + propagator.OnInject = (propagation, carrier, setter) => + { + propagatorCalled++; + capturedPropagationContext = propagation; + capturedCarrier = (Metadata)carrier; + + // Make sure the original metadata make it through + if (additionalMetadata != null) + { + Assert.Equal(capturedCarrier, additionalMetadata); + } + + // Call the actual setter to ensure it updates the carrier. + // It doesn't matter what we put in + setter(capturedCarrier, "bar", "baz"); + }; using var server = FoobarService.Start(); var interceptorOptions = new ClientTracingInterceptorOptions { - Propagator = mockPropagator.Object, + Propagator = propagator, RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid(), }; @@ -485,8 +478,8 @@ private static async Task TestHandlerFailure( new ClientTracingInterceptor(clientInterceptorOptions), new List { - new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), - new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), + new(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), + new(FoobarService.RequestHeaderErrorDescription, "fubar"), }); using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 38995ee86f..5053e55075 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -6,7 +6,6 @@ - @@ -19,4 +18,8 @@ + + + + From 7567a9fc38af4c679709fd5aa2848b9902a7012c Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Sat, 9 Dec 2023 01:54:55 +0100 Subject: [PATCH 0906/1499] Remove Moq from Instrumentation.EntityFrameworkCore.Tests (#1479) --- .../EntityFrameworkDiagnosticListenerTests.cs | 68 ++++++++----------- ...mentation.EntityFrameworkCore.Tests.csproj | 2 +- 2 files changed, 28 insertions(+), 42 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 54983d7474..0f6c7fc0e6 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Diagnostics; @@ -9,7 +10,6 @@ using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Moq; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; using OpenTelemetry.Trace; using Xunit; @@ -35,9 +35,9 @@ public EntityFrameworkDiagnosticListenerTests() [Fact] public void EntityFrameworkContextEventsInstrumentedTest() { - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation().Build(); using (var context = new ItemsContext(this.contextOptions)) @@ -50,9 +50,8 @@ public void EntityFrameworkContextEventsInstrumentedTest() Assert.Equal("ItemTwo", items[2].Name); } - Assert.Equal(3, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; VerifyActivityData(activity); } @@ -60,10 +59,10 @@ public void EntityFrameworkContextEventsInstrumentedTest() [Fact] public void EntityFrameworkEnrichDisplayNameWithEnrichWithIDbCommand() { - var activityProcessor = new Mock>(); + var exportedItems = new List(); var expectedDisplayName = "Text main"; using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation(options => { options.EnrichWithIDbCommand = (activity1, command) => @@ -84,9 +83,8 @@ public void EntityFrameworkEnrichDisplayNameWithEnrichWithIDbCommand() Assert.Equal("ItemTwo", items[2].Name); } - Assert.Equal(3, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; VerifyActivityData(activity, altDisplayName: $"{expectedDisplayName}"); } @@ -94,9 +92,9 @@ public void EntityFrameworkEnrichDisplayNameWithEnrichWithIDbCommand() [Fact] public void EntityFrameworkContextExceptionEventsInstrumentedTest() { - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation() .Build(); @@ -112,9 +110,8 @@ public void EntityFrameworkContextExceptionEventsInstrumentedTest() } } - Assert.Equal(3, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; VerifyActivityData(activity, isError: true); } @@ -122,9 +119,9 @@ public void EntityFrameworkContextExceptionEventsInstrumentedTest() [Fact] public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByDbCommand() { - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation(options => { options.Filter = (_, command) => !command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); @@ -135,20 +132,15 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByDbCommand() _ = context.Set().OrderBy(e => e.Name).ToList(); } - Assert.Equal(2, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - Assert.False(activity.IsAllDataRequested); - Assert.False(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); + Assert.Empty(exportedItems); } [Fact] public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByDbCommand() { - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation(options => { options.Filter = (_, command) => command.CommandText.Contains("Item", StringComparison.OrdinalIgnoreCase); @@ -159,9 +151,8 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByDbCommand() _ = context.Set().OrderBy(e => e.Name).ToList(); } - Assert.Equal(3, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; + Assert.Single(exportedItems); + var activity = exportedItems[0]; Assert.True(activity.IsAllDataRequested); Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); @@ -189,9 +180,9 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByDbCommand() [InlineData("Teradata.EntityFrameworkCore")] public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByProviderName(string provider) { - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation(options => { options.Filter = (providerName, _) => providerName != null && providerName.Equals(provider, StringComparison.OrdinalIgnoreCase); @@ -202,20 +193,15 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalseByProviderName(st _ = context.Set().OrderBy(e => e.Name).ToList(); } - Assert.Equal(2, activityProcessor.Invocations.Count); - - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - - Assert.False(activity.IsAllDataRequested); - Assert.False(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); + Assert.Empty(exportedItems); } [Fact] public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByProviderName() { - var activityProcessor = new Mock>(); + var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .AddEntityFrameworkCoreInstrumentation(options => { options.Filter = (providerName, _) => providerName != null && providerName.Equals("Microsoft.EntityFrameworkCore.Sqlite", StringComparison.OrdinalIgnoreCase); @@ -226,9 +212,9 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrueByProviderName() _ = context.Set().OrderBy(e => e.Name).ToList(); } - Assert.Equal(3, activityProcessor.Invocations.Count); + Assert.Single(exportedItems); + var activity = exportedItems[0]; - var activity = (Activity)activityProcessor.Invocations[1].Arguments[0]; Assert.True(activity.IsAllDataRequested); Assert.True(activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 6188f39899..4f1645e594 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -18,7 +18,7 @@ - + From 03ba33e11c91f5ba2be8d1111b42d3652537b371 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Sat, 9 Dec 2023 02:10:16 +0100 Subject: [PATCH 0907/1499] Remove Moq from Instrumentation.AWSLambda.Tests (#1476) --- .../AWSLambdaWrapperTests.cs | 62 ++++++++----------- .../Implementation/AWSLambdaHttpUtilsTests.cs | 5 -- ...try.Instrumentation.AWSLambda.Tests.csproj | 4 +- 3 files changed, 28 insertions(+), 43 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index bd7769873e..dd014dbe39 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -2,11 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using Amazon.Lambda.Core; -using Moq; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Resources; using OpenTelemetry.Tests; @@ -40,11 +39,11 @@ public AWSLambdaWrapperTests() [InlineData(true)] public void TraceSyncWithInputAndReturn(bool setCustomParent) { - var processor = new Mock>(); + var exportedItems = new List(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; @@ -53,10 +52,9 @@ public void TraceSyncWithInputAndReturn(bool setCustomParent) this.AssertResourceAttributes(resource); } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + Assert.Single(exportedItems); - var activity = (Activity)processor.Invocations[1].Arguments[0]; + var activity = exportedItems[0]; this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } @@ -66,11 +64,11 @@ public void TraceSyncWithInputAndReturn(bool setCustomParent) [InlineData(true)] public void TraceSyncWithInputAndNoReturn(bool setCustomParent) { - var processor = new Mock>(); + var exportedItems = new List(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; @@ -79,10 +77,9 @@ public void TraceSyncWithInputAndNoReturn(bool setCustomParent) this.AssertResourceAttributes(resource); } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + Assert.Single(exportedItems); - var activity = (Activity)processor.Invocations[1].Arguments[0]; + var activity = exportedItems[0]; this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } @@ -92,11 +89,11 @@ public void TraceSyncWithInputAndNoReturn(bool setCustomParent) [InlineData(true)] public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) { - var processor = new Mock>(); + var exportedItems = new List(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; @@ -105,10 +102,9 @@ public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) this.AssertResourceAttributes(resource); } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + Assert.Single(exportedItems); - var activity = (Activity)processor.Invocations[1].Arguments[0]; + var activity = exportedItems[0]; this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } @@ -118,11 +114,11 @@ public async Task TraceAsyncWithInputAndReturn(bool setCustomParent) [InlineData(true)] public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) { - var processor = new Mock>(); + var exportedItems = new List(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()!) { var parentContext = setCustomParent ? CreateParentContext() : default; @@ -131,10 +127,9 @@ public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) this.AssertResourceAttributes(resource); } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + Assert.Single(exportedItems); - var activity = (Activity)processor.Invocations[1].Arguments[0]; + var activity = exportedItems[0]; this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); } @@ -144,11 +139,11 @@ public async Task TraceAsyncWithInputAndNoReturn(bool setCustomParent) [InlineData(true)] public void TestLambdaHandlerException(bool setCustomParent) { - var processor = new Mock>(); + var exportedItems = new List(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()!) { try @@ -163,10 +158,9 @@ public void TestLambdaHandlerException(bool setCustomParent) } } - // SetParentProvider -> OnStart -> OnEnd -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(6, processor.Invocations.Count); + Assert.Single(exportedItems); - var activity = (Activity)processor.Invocations[1].Arguments[0]; + var activity = exportedItems[0]; this.AssertSpanProperties(activity, setCustomParent ? CustomParentId : XRayParentId); this.AssertSpanAttributes(activity); this.AssertSpanException(activity); @@ -177,11 +171,11 @@ public void TestLambdaHandlerNotSampled() { Environment.SetEnvironmentVariable("_X_AMZN_TRACE_ID", "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0"); - var processor = new Mock>(); + var exportedItems = new List(); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAWSLambdaConfigurations() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()!) { var result = AWSLambdaWrapper.Trace(tracerProvider, this.sampleHandlers.SampleHandlerSyncInputAndReturn, "TestStream", this.sampleLambdaContext); @@ -189,11 +183,7 @@ public void TestLambdaHandlerNotSampled() this.AssertResourceAttributes(resource); } - // SetParentProvider -> OnForceFlush -> OnShutdown -> Dispose - Assert.Equal(4, processor.Invocations.Count); - - var activities = processor.Invocations.Where(i => i.Method.Name == "OnEnd").Select(i => i.Arguments[0]).Cast().ToArray(); - Assert.True(activities.Length == 0); + Assert.Empty(exportedItems); } [Fact] @@ -206,7 +196,7 @@ public void OnFunctionStart_NoParent_ActivityCreated() .AddAWSLambdaConfigurations() .Build()) { - activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); } Assert.NotNull(activity); @@ -222,7 +212,7 @@ public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_Activit .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) .Build()) { - activity = AWSLambdaWrapper.OnFunctionStart("test-input", new Mock().Object); + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); } Assert.NotNull(activity); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index e4bfc5e8bf..ec2ff58713 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Linq; using Amazon.Lambda.APIGatewayEvents; -using Moq; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Trace; using Xunit; @@ -170,10 +169,8 @@ public void SetHttpTagsFromResult_APIGatewayProxyResponse_SetsCorrectTags() { StatusCode = 200, }; - var activityProcessor = new Mock>(); using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) .AddSource("TestActivitySource") .Build(); @@ -201,10 +198,8 @@ public void SetHttpTagsFromResult_APIGatewayHttpApiV2ProxyResponse_SetsCorrectTa { StatusCode = 200, }; - var activityProcessor = new Mock>(); using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) .AddSource("TestActivitySource") .Build(); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 52c31daf70..800954d217 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -8,11 +8,11 @@ - + - + From d4b739af30b067918429bc3cabfd6ec5d0723ddd Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Sat, 9 Dec 2023 02:43:52 +0100 Subject: [PATCH 0908/1499] Remove Moq from Instrumentation.AWS.Tests (#1475) --- .../RequestContextHelperTests.cs | 71 ++++------ ...Telemetry.Instrumentation.AWS.Tests.csproj | 2 +- .../TestAWSClientInstrumentation.cs | 67 +++++----- .../TestRequest.cs | 123 ++++++++++++++++++ .../TestRequestContext.cs | 62 +++++++++ 5 files changed, 239 insertions(+), 86 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs create mode 100644 test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs index da5aa38b75..47466b52a5 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using Amazon.Runtime; using Amazon.Runtime.Internal; -using Moq; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.AWS.Implementation; using OpenTelemetry.Trace; @@ -35,18 +34,12 @@ public void AddAttributes_ParametersCollectionSizeReachesLimit_TraceDataNotInjec var parameters = new ParameterCollection(); parameters.AddStringParameters(serviceType, originalRequest); - var request = new Mock(); - request.Setup(x => x.ParameterCollection) - .Returns(parameters); + var request = new TestRequest(parameters); - var context = new Mock(); - context.Setup(x => x.OriginalRequest) - .Returns(originalRequest); - context.Setup(x => x.Request) - .Returns(request.Object); + var context = new TestRequestContext(originalRequest, request); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); - addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); + addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); Assert.Equal(30, parameters.Count); } @@ -58,25 +51,18 @@ public void AddAttributes_ParametersCollection_TraceDataInjected(string serviceT { var expectedParameters = new List>() { - new KeyValuePair("traceparent", $"00-{TraceId}-{ParentId}-00"), - new KeyValuePair("tracestate", "trace-state"), + new("traceparent", $"00-{TraceId}-{ParentId}-00"), + new("tracestate", "trace-state"), }; AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 0); var parameters = new ParameterCollection(); - var request = new Mock(); - request.Setup(x => x.ParameterCollection) - .Returns(parameters); + var request = new TestRequest(parameters); + var context = new TestRequestContext(originalRequest, request); - var context = new Mock(); - context.Setup(x => x.OriginalRequest) - .Returns(originalRequest); - context.Setup(x => x.Request) - .Returns(request.Object); - - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); - addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); + addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); } @@ -88,27 +74,21 @@ public void AddAttributes_ParametersCollectionWithCustomParameter_TraceDataInjec { var expectedParameters = new List>() { - new KeyValuePair("name1", "value1"), - new KeyValuePair("traceparent", $"00-{TraceId}-{ParentId}-00"), - new KeyValuePair("tracestate", "trace-state"), + new("name1", "value1"), + new("traceparent", $"00-{TraceId}-{ParentId}-00"), + new("tracestate", "trace-state"), }; AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 1); var parameters = new ParameterCollection(); parameters.AddStringParameters(serviceType, originalRequest); - var request = new Mock(); - request.Setup(x => x.ParameterCollection) - .Returns(parameters); + var request = new TestRequest(parameters); - var context = new Mock(); - context.Setup(x => x.OriginalRequest) - .Returns(originalRequest); - context.Setup(x => x.Request) - .Returns(request.Object); + var context = new TestRequestContext(originalRequest, request); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); - addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); + addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); } @@ -124,7 +104,7 @@ public void AddAttributes_ParametersCollectionWithTraceParent_TraceStateNotInjec var expectedParameters = new List>() { - new KeyValuePair("traceparent", $"00-{TraceId}-{ParentId}-00"), + new("traceparent", $"00-{TraceId}-{ParentId}-00"), }; AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 0); @@ -133,18 +113,11 @@ public void AddAttributes_ParametersCollectionWithTraceParent_TraceStateNotInjec var parameters = new ParameterCollection(); parameters.AddStringParameters(serviceType, originalRequest); - var request = new Mock(); - request.Setup(x => x.ParameterCollection) - .Returns(parameters); - - var context = new Mock(); - context.Setup(x => x.OriginalRequest) - .Returns(originalRequest); - context.Setup(x => x.Request) - .Returns(request.Object); + var request = new TestRequest(parameters); + var context = new TestRequestContext(originalRequest, request); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context.Object); - addAttributes?.Invoke(context.Object, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); + addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 09568991f7..35d0dbb926 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index da14b1d019..ccc87f9941 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -13,7 +13,6 @@ using Amazon.Runtime; using Amazon.SQS; using Amazon.SQS.Model; -using Moq; using OpenTelemetry.Instrumentation.AWS.Tests.Tools; using OpenTelemetry.Trace; using Xunit; @@ -25,7 +24,7 @@ public class TestAWSClientInstrumentation [Fact] public void TestDDBScanSuccessful() { - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -33,26 +32,25 @@ public void TestDDBScanSuccessful() .SetSampler(new AlwaysOnSampler()) .AddXRayTraceId() .AddAWSInstrumentation() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; CustomResponses.SetResponse(ddb, null, requestId, true); - var scan_request = new ScanRequest(); - - scan_request.TableName = "SampleProduct"; - scan_request.AttributesToGet = new List() { "Id", "Name" }; + var scan_request = new ScanRequest + { + TableName = "SampleProduct", + AttributesToGet = new List { "Id", "Name" }, + }; #if NETFRAMEWORK ddb.Scan(scan_request); #else ddb.ScanAsync(scan_request).Wait(); #endif - var count = processor.Invocations.Count; - - Assert.Equal(3, count); + Assert.Single(exportedItems); - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + Activity awssdk_activity = exportedItems[0]; this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); @@ -65,7 +63,7 @@ public void TestDDBScanSuccessful() [Fact] public void TestDDBSubtypeScanSuccessful() { - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -73,26 +71,25 @@ public void TestDDBSubtypeScanSuccessful() .SetSampler(new AlwaysOnSampler()) .AddXRayTraceId() .AddAWSInstrumentation() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var ddb = new TestAmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; CustomResponses.SetResponse(ddb, null, requestId, true); - var scan_request = new ScanRequest(); - - scan_request.TableName = "SampleProduct"; - scan_request.AttributesToGet = new List() { "Id", "Name" }; + var scan_request = new ScanRequest + { + TableName = "SampleProduct", + AttributesToGet = new List() { "Id", "Name" }, + }; #if NETFRAMEWORK ddb.Scan(scan_request); #else ddb.ScanAsync(scan_request).Wait(); #endif - var count = processor.Invocations.Count; + Assert.Single(exportedItems); - Assert.Equal(3, count); - - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + Activity awssdk_activity = exportedItems[0]; this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); @@ -109,7 +106,7 @@ public void TestDDBScanUnsuccessful() public async Task TestDDBScanUnsuccessful() #endif { - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -117,7 +114,7 @@ public async Task TestDDBScanUnsuccessful() .SetSampler(new AlwaysOnSampler()) .AddXRayTraceId() .AddAWSInstrumentation() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); @@ -126,10 +123,11 @@ public async Task TestDDBScanUnsuccessful() amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; amazonServiceException.RequestId = requestId; CustomResponses.SetResponse(ddb, (request) => { throw amazonServiceException; }); - var scan_request = new ScanRequest(); - - scan_request.TableName = "SampleProduct"; - scan_request.AttributesToGet = new List() { "Id", "Name" }; + var scan_request = new ScanRequest + { + TableName = "SampleProduct", + AttributesToGet = new List() { "Id", "Name" }, + }; try { @@ -141,10 +139,9 @@ public async Task TestDDBScanUnsuccessful() } catch (AmazonServiceException) { - var count = processor.Invocations.Count; - Assert.Equal(3, count); + Assert.Single(exportedItems); - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + Activity awssdk_activity = exportedItems[0]; this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); @@ -159,7 +156,7 @@ public async Task TestDDBScanUnsuccessful() [Fact] public void TestSQSSendMessageSuccessful() { - var processor = new Mock>(); + var exportedItems = new List(); var parent = new Activity("parent").Start(); @@ -167,7 +164,7 @@ public void TestSQSSendMessageSuccessful() .AddXRayTraceId() .SetSampler(new AlwaysOnSampler()) .AddAWSInstrumentation() - .AddProcessor(processor.Object) + .AddInMemoryExporter(exportedItems) .Build()) { var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); @@ -183,10 +180,8 @@ public void TestSQSSendMessageSuccessful() #else sqs.SendMessageAsync(send_msg_req).Wait(); #endif - - var count = processor.Invocations.Count; - Assert.Equal(3, count); - Activity awssdk_activity = (Activity)processor.Invocations[2].Arguments[0]; + Assert.Single(exportedItems); + Activity awssdk_activity = exportedItems[0]; this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateSqsActivityTags(awssdk_activity); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs new file mode 100644 index 0000000000..5eb4cbfa2b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs @@ -0,0 +1,123 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using System.IO; +using Amazon; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using Amazon.Runtime.Internal.Auth; + +namespace OpenTelemetry.Instrumentation.AWS.Tests; + +internal class TestRequest(ParameterCollection parameters) : IRequest +{ + private readonly ParameterCollection parameters = parameters; + + public string RequestName => throw new NotImplementedException(); + + public IDictionary Headers => throw new NotImplementedException(); + + public bool UseQueryString { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public IDictionary Parameters => throw new NotImplementedException(); + + public ParameterCollection ParameterCollection => this.parameters; + + public IDictionary SubResources => throw new NotImplementedException(); + + public string HttpMethod { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Uri Endpoint { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string ResourcePath { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public IDictionary PathResources => throw new NotImplementedException(); + + public int MarshallerVersion { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public byte[] Content { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool SetContentFromParameters { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Stream ContentStream { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public long OriginalStreamPosition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string OverrideSigningServiceName { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string ServiceName => throw new NotImplementedException(); + + public AmazonWebServiceRequest OriginalRequest => throw new NotImplementedException(); + + public RegionEndpoint AlternateEndpoint { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string HostPrefix { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool Suppress404Exceptions { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public AWS4SigningResult AWS4SignerResult { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool? DisablePayloadSigning { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public AWS4aSigningResult AWS4aSignerResult { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool UseChunkEncoding { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string CanonicalResourcePrefix { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool UseSigV4 { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public SignatureVersion SignatureVersion { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string AuthenticationRegion { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string DeterminedSigningRegion { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public CoreChecksumAlgorithm SelectedChecksum { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public IDictionary TrailingHeaders => throw new NotImplementedException(); + + public bool UseDoubleEncoding { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public void AddPathResource(string key, string value) + { + throw new NotImplementedException(); + } + + public void AddSubResource(string subResource) + { + throw new NotImplementedException(); + } + + public void AddSubResource(string subResource, string value) + { + throw new NotImplementedException(); + } + + public string ComputeContentStreamHash() + { + throw new NotImplementedException(); + } + + public string GetHeaderValue(string headerName) + { + throw new NotImplementedException(); + } + + public bool HasRequestBody() + { + throw new NotImplementedException(); + } + + public bool IsRequestStreamRewindable() + { + throw new NotImplementedException(); + } + + public bool MayContainRequestBody() + { + throw new NotImplementedException(); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs new file mode 100644 index 0000000000..965c3e30e9 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs @@ -0,0 +1,62 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Threading; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using Amazon.Runtime.Internal.Auth; +using Amazon.Runtime.Internal.Transform; +using Amazon.Runtime.Internal.Util; + +namespace OpenTelemetry.Instrumentation.AWS.Tests; + +internal class TestRequestContext(AmazonWebServiceRequest originalRequest, IRequest request) : IRequestContext +{ + private readonly AmazonWebServiceRequest originalRequest = originalRequest; + private IRequest request = request; + + public AmazonWebServiceRequest OriginalRequest => this.originalRequest; + + public string RequestName => throw new NotImplementedException(); + + public IMarshaller Marshaller => throw new NotImplementedException(); + + public ResponseUnmarshaller Unmarshaller => throw new NotImplementedException(); + + public InvokeOptionsBase Options => throw new NotImplementedException(); + + public RequestMetrics Metrics => throw new NotImplementedException(); + + public AbstractAWSSigner Signer => throw new NotImplementedException(); + + public IClientConfig ClientConfig => throw new NotImplementedException(); + + public ImmutableCredentials ImmutableCredentials { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public IRequest Request { get => this.request; set => this.request = value; } + + public bool IsSigned { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public bool IsAsync => throw new NotImplementedException(); + + public int Retries { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public CapacityManager.CapacityType LastCapacityType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int EndpointDiscoveryRetries { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public CancellationToken CancellationToken => throw new NotImplementedException(); + + public MonitoringAPICallAttempt CSMCallAttempt { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public MonitoringAPICallEvent CSMCallEvent { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public IServiceMetadata ServiceMetaData => throw new NotImplementedException(); + + public bool CSMEnabled => throw new NotImplementedException(); + + public bool IsLastExceptionRetryable { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public Guid InvocationId => throw new NotImplementedException(); +} From 8e8995f2db5322c630fc7dc9862952b7825d562e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 11 Dec 2023 07:07:50 +0100 Subject: [PATCH 0909/1499] Local build fixes (#1484) --- examples/AspNet/Controllers/WeatherForecastController.cs | 2 +- .../OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index 3d4516d12c..7f5652d193 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -111,7 +111,7 @@ public async Task PostData() return result; } - private static IEnumerable GetWeatherForecast() + private static WeatherForecast[] GetWeatherForecast() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast( diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs index 5362b89fbd..6ed59ae804 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System; using System.Collections.Generic; using OpenTelemetry.Context.Propagation; From 5efd368788185c4e697542f977ee5ad6818a1bb5 Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Mon, 11 Dec 2023 07:17:10 +0100 Subject: [PATCH 0910/1499] Remove Moq from ResourceDetectors.AWS.Tests (#1483) --- .../Http/ServerCertificateValidationProviderTests.cs | 7 +++---- .../OpenTelemetry.ResourceDetectors.AWS.Tests.csproj | 4 ---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index 9bf5e15a5d..008107b52e 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -4,7 +4,6 @@ #if !NETFRAMEWORK using System.Security.Cryptography.X509Certificates; -using Moq; using OpenTelemetry.ResourceDetectors.AWS.Http; using Xunit; @@ -12,7 +11,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; public class ServerCertificateValidationProviderTests { - private const string InvalidCertificateName = "invalidcert"; + private const string InvalidCertificateName = "invalidCert"; [Fact] public void TestValidCertificate() @@ -54,7 +53,7 @@ public void TestTestCallbackWithNullCertificate() ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); Assert.NotNull(serverCertificateValidationProvider); - Assert.False(serverCertificateValidationProvider.ValidationCallback(this, null, Mock.Of(), default)); + Assert.False(serverCertificateValidationProvider.ValidationCallback(this, null, new X509Chain(), default)); } [Fact] @@ -67,7 +66,7 @@ public void TestCallbackWithNullChain() ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); Assert.NotNull(serverCertificateValidationProvider); - Assert.False(serverCertificateValidationProvider.ValidationCallback(this, Mock.Of(), null, default)); + Assert.False(serverCertificateValidationProvider.ValidationCallback(this, new X509Certificate2(certificateUploader.FilePath), null, default)); } } diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj index 8f55ce9b57..95a6483545 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj @@ -8,10 +8,6 @@ enable - - - - From dc70f4286b17be49fa28cee44f2860bcc17e6e0d Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Mon, 11 Dec 2023 19:35:24 +0100 Subject: [PATCH 0911/1499] Remove Moq from Instrumentation.StackExchangeRedis.Tests (#1481) --- ...isProfilerEntryToActivityConverterTests.cs | 52 +++++++------------ ...umentation.StackExchangeRedis.Tests.csproj | 4 +- ...kExchangeRedisCallsInstrumentationTests.cs | 44 +++++++--------- .../TestProfiledCommand.cs | 52 +++++++++++++++++++ 4 files changed, 91 insertions(+), 61 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index fea0cd30ed..a6fd35baef 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -4,14 +4,14 @@ using System; using System.Diagnostics; using System.Net; +using OpenTelemetry.Instrumentation.StackExchangeRedis.Tests; + #if !NETFRAMEWORK using System.Net.Sockets; #endif -using Moq; using OpenTelemetry.Tests; using OpenTelemetry.Trace; using StackExchange.Redis; -using StackExchange.Redis.Profiling; using Xunit; namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; @@ -48,11 +48,9 @@ public void Dispose() public void ProfilerCommandToActivity_UsesCommandAsName() { var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.Command).Returns("SET"); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.Equal("SET", result.DisplayName); @@ -63,10 +61,9 @@ public void ProfilerCommandToActivity_UsesTimestampAsStartTime() { var now = DateTimeOffset.Now; var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(now.DateTime); + var profiledCommand = new TestProfiledCommand(now.DateTime); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.Equal(now, result.StartTimeUtc); @@ -76,10 +73,9 @@ public void ProfilerCommandToActivity_UsesTimestampAsStartTime() public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() { var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbSystem)); @@ -90,11 +86,9 @@ public void ProfilerCommandToActivity_SetsDbTypeAttributeAsRedis() public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() { var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.Command).Returns("SET"); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeDbStatement)); @@ -105,13 +99,9 @@ public void ProfilerCommandToActivity_UsesCommandAsDbStatementAttribute() public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() { var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - var expectedFlags = CommandFlags.FireAndForget | - CommandFlags.NoRedirect; - profiledCommand.Setup(m => m.Flags).Returns(expectedFlags); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow, CommandFlags.FireAndForget | CommandFlags.NoRedirect); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.NotNull(result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); @@ -131,11 +121,9 @@ public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() var activity = new Activity("redis-profiler"); IPEndPoint ipLocalEndPoint = new IPEndPoint(address, port); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.EndPoint).Returns(ipLocalEndPoint); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow, ipLocalEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerIp)); @@ -150,11 +138,9 @@ public void ProfilerCommandToActivity_UsesDnsEndPointAsEndPoint() var dnsEndPoint = new DnsEndPoint("https://opentelemetry.io/", 443); var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.EndPoint).Returns(dnsEndPoint); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow, dnsEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributeNetPeerName)); @@ -169,11 +155,9 @@ public void ProfilerCommandToActivity_UsesOtherEndPointAsEndPoint() { var unixEndPoint = new UnixDomainSocketEndPoint("https://opentelemetry.io/"); var activity = new Activity("redis-profiler"); - var profiledCommand = new Mock(); - profiledCommand.Setup(m => m.CommandCreated).Returns(DateTime.UtcNow); - profiledCommand.Setup(m => m.EndPoint).Returns(unixEndPoint); + var profiledCommand = new TestProfiledCommand(DateTime.UtcNow, unixEndPoint); - var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand.Object, new StackExchangeRedisInstrumentationOptions()); + var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); Assert.NotNull(result); Assert.NotNull(result.GetTagValue(SemanticConventions.AttributePeerService)); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 79be12b83f..8f0ae3aee8 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -10,7 +10,7 @@ - + @@ -18,8 +18,8 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index a1f1cd6c6e..0055b8be5d 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -2,12 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using Moq; using OpenTelemetry.Tests; using OpenTelemetry.Trace; using StackExchange.Redis; @@ -45,10 +45,10 @@ public void SuccessfulCommandTestWithKey(string value) var db = connection.GetDatabase(); db.KeyDelete("key1"); - var activityProcessor = new Mock>(); + var exportedItems = new List(); var sampler = new TestSampler(); using (Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .SetSampler(sampler) .AddRedisInstrumentation(connection, c => c.SetVerboseDatabaseStatements = true) .Build()) @@ -72,15 +72,14 @@ public void SuccessfulCommandTestWithKey(string value) // Disposing SDK should flush the Redis profiling session immediately. - Assert.Equal(11, activityProcessor.Invocations.Count); + Assert.Equal(4, exportedItems.Count); - var scriptActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - Assert.Equal("EVAL", scriptActivity.DisplayName); - Assert.Equal("EVAL redis.call('set', ARGV[1], ARGV[2])", scriptActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); + Assert.Equal("EVAL", exportedItems[0].DisplayName); + Assert.Equal("EVAL redis.call('set', ARGV[1], ARGV[2])", exportedItems[0].GetTagValue(SemanticConventions.AttributeDbStatement)); - VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], true); - VerifyActivityData((Activity)activityProcessor.Invocations[5].Arguments[0], true, connection.GetEndPoints()[0], true); - VerifyActivityData((Activity)activityProcessor.Invocations[7].Arguments[0], false, connection.GetEndPoints()[0], true); + VerifyActivityData(exportedItems[1], false, connection.GetEndPoints()[0], true); + VerifyActivityData(exportedItems[2], true, connection.GetEndPoints()[0], true); + VerifyActivityData(exportedItems[3], false, connection.GetEndPoints()[0], true); VerifySamplingParameters(sampler.LatestSamplingParameters); } @@ -96,7 +95,7 @@ public void SuccessfulCommandTest(string value) connectionOptions.EndPoints.Add(RedisEndPoint); ConnectionMultiplexer? connection = null; - var activityProcessor = new Mock>(); + var exportedItems = new List(); var sampler = new TestSampler(); using (Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => @@ -106,7 +105,7 @@ public void SuccessfulCommandTest(string value) return connection = ConnectionMultiplexer.Connect(connectionOptions); }); }) - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .SetSampler(sampler) .AddRedisInstrumentation(c => c.SetVerboseDatabaseStatements = false) .Build()) @@ -127,10 +126,10 @@ public void SuccessfulCommandTest(string value) // Disposing SDK should flush the Redis profiling session immediately. - Assert.Equal(7, activityProcessor.Invocations.Count); + Assert.Equal(2, exportedItems.Count); - VerifyActivityData((Activity)activityProcessor.Invocations[1].Arguments[0], true, connection.GetEndPoints()[0], false); - VerifyActivityData((Activity)activityProcessor.Invocations[3].Arguments[0], false, connection.GetEndPoints()[0], false); + VerifyActivityData(exportedItems[0], true, connection.GetEndPoints()[0], false); + VerifyActivityData(exportedItems[1], false, connection.GetEndPoints()[0], false); VerifySamplingParameters(sampler.LatestSamplingParameters); } @@ -169,11 +168,11 @@ public void CanEnrichActivityFromCommand(string value) connectionOptions.EndPoints.Add(RedisEndPoint); using var connection = ConnectionMultiplexer.Connect(connectionOptions); - var activityProcessor = new Mock>(); + var exportedItems = new List(); var sampler = new TestSampler(); var builder = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) + .AddInMemoryExporter(exportedItems) .SetSampler(sampler) .AddRedisInstrumentation(c => c.Enrich = (activity, command) => { @@ -204,12 +203,10 @@ public void CanEnrichActivityFromCommand(string value) // Disposing SDK should flush the Redis profiling session immediately. - Assert.Equal(7, activityProcessor.Invocations.Count); + Assert.Equal(2, exportedItems.Count); - var setActivity = (Activity)activityProcessor.Invocations[1].Arguments[0]; - Assert.Equal(true, setActivity.GetTagValue("is_fast")); - var getActivity = (Activity)activityProcessor.Invocations[3].Arguments[0]; - Assert.Equal(true, getActivity.GetTagValue("is_fast")); + Assert.Equal(true, exportedItems[0].GetTagValue("is_fast")); + Assert.Equal(true, exportedItems[1].GetTagValue("is_fast")); } [Fact] @@ -348,12 +345,9 @@ public void StackExchangeRedis_StackExchangeRedisInstrumentation_Test() connectionOptions.EndPoints.Add("localhost"); using var connection = ConnectionMultiplexer.Connect(connectionOptions); - - var activityProcessor = new Mock>(); var sampler = new TestSampler(); var builder = Sdk.CreateTracerProviderBuilder() - .AddProcessor(activityProcessor.Object) .SetSampler(sampler) .AddRedisInstrumentation(c => c.Enrich = (activity, command) => { diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs new file mode 100644 index 0000000000..8831c04e62 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs @@ -0,0 +1,52 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Net; +using StackExchange.Redis; +using StackExchange.Redis.Profiling; + +namespace OpenTelemetry.Instrumentation.StackExchangeRedis.Tests; + +internal class TestProfiledCommand(DateTime commandCreated) : IProfiledCommand +{ + private readonly DateTime commandCreated = commandCreated; + private readonly CommandFlags flags = CommandFlags.None; + private readonly EndPoint endPoint = new IPEndPoint(0, 0); + + public TestProfiledCommand(DateTime commandCreated, CommandFlags flags) + : this(commandCreated) + { + this.flags = flags; + } + + public TestProfiledCommand(DateTime commandCreated, EndPoint endpoint) + : this(commandCreated) + { + this.endPoint = endpoint; + } + + public EndPoint EndPoint => this.endPoint; + + public int Db => 0; + + public string Command => "SET"; + + public CommandFlags Flags => this.flags; + + public DateTime CommandCreated => this.commandCreated; + + public TimeSpan CreationToEnqueued => default; + + public TimeSpan EnqueuedToSending => default; + + public TimeSpan SentToResponse => default; + + public TimeSpan ResponseToCompletion => default; + + public TimeSpan ElapsedTime => default; + + public IProfiledCommand RetransmissionOf => throw new NotImplementedException(); + + public RetransmissionReasonType? RetransmissionReason => throw new NotImplementedException(); +} From 8f2f11071af3d562c13fd187428173f3e2af7b04 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:54:01 -0800 Subject: [PATCH 0912/1499] Update OTel SDK version to 1.7.0 (#1486) --- build/Common.nonprod.props | 1 - build/Common.props | 2 +- .../wcf/client-core/Examples.Wcf.Client.DotNet.csproj | 4 ++-- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ .../Common.GenevaExporter.props | 2 +- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 3 +++ src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 ++-- .../OpenTelemetry.Exporter.Instana.csproj | 6 +++++- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 3 +++ src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Extensions/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ ...enTelemetry.Instrumentation.ElasticsearchClient.csproj | 4 ++++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 5 +++-- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 4 ++-- .../OpenTelemetry.ResourceDetectors.AWS.csproj | 4 ++++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 2 ++ .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ .../OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj | 1 + src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 ++-- .../LogRecordCommonSchemaJsonHttpPostBenchmarks.cs | 2 +- .../LogRecordCommonSchemaJsonSerializerTests.cs | 2 +- .../ActivityEventAttachingLogProcessorTests.cs | 8 ++++---- .../OpenTelemetry.Extensions.Tests.csproj | 4 ---- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 1 - 38 files changed, 84 insertions(+), 45 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index fece09322f..05a82c657d 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -22,7 +22,6 @@ --> [0.13.10,0.14) [2.3.1,3.0) - [5.0.0,7.0) [17.7.2,18.0) [4.18.4,5.0) $(OpenTelemetryCoreLatestVersion) diff --git a/build/Common.props b/build/Common.props index 22a2dd71fb..b0dc596895 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,7 +35,7 @@ [4.2.2,5.0) [3.3.3] [1.1.1,2.0) - [1.6.0,2.0) + [1.7.0,2.0) [1.7.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index 3fa7c8ea19..1da3e3ade7 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 72340f827d..546cdf92b3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.7.0-rc.1 Released 2023-Dec-05 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 78181066e1..5570a7a1fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestPrereleaseVersion) + $(OpenTelemetryCoreLatestVersion) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 6fb6853f03..3912bad5a3 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.0.0-alpha.3 Released 2023-Oct-13 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index fc9fe6fc35..8e227d4ed6 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.6.0`. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index aa210ce942..6bf7265650 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -2,7 +2,7 @@ - netstandard2.0;net462 + netstandard2.0;$(NetFrameworkMinimumSupportedVersion) Instana Tracing APM Instana .NET Exporter for OpenTelemetry Exporter.Instana- @@ -14,4 +14,8 @@ + + + + diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 453fbeb992..ae8f6ce8cf 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.6.0 Released 2023-Oct-25 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 8625decb38..fbc1d739ec 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.6.0`. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 24187e865d..b56695232f 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.6.0 of OpenTelemetry SDK. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index e4c18b64f4..6493396250 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -5,8 +5,8 @@ * Add LogToActivityEventConversionOptions.Filter callback ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) -* Update OpenTelemetry SDK version to `1.6.0`. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index a300bf0c1b..b97a02b1ea 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.6.0-beta.2 Released 2023-Nov-06 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 36ef3e4e21..111be2ef79 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.6.0 of OpenTelemetry SDK. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 37108607bd..4dd3a9b1e0 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.0.0-beta.5 Released 2023-Oct-24 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 86bf2da20b..1f56188df9 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -18,6 +18,10 @@ + + + + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 9105a6b124..c4b3f7c62d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.0.0-beta.8 Released 2023-Oct-24 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 0feb5d5842..aac23e50b6 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry.Api to 1.6.0. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.5.1-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 4a7693ac6d..f0e42313cd 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -8,6 +8,8 @@ ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Update minimal supported version of `Google.Protobuf` to `3.15.0`. ([#1456](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1456)) +* Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index e41410d31e..6d24250490 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,8 +2,9 @@ ## Unreleased -* Update OTel API version to `1.6.0`. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.7.0`. + * Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Added overloads which accept a name to the `TracerProviderBuilder` `HangfireInstrumentationOptions` extension to allow for more fine-grained diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index ec16d15b46..b818af9fb5 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updated OpenTelemetry SDK to 1.6.0 - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Updated OpenTelemetry SDK to 1.7.0. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Removes `AddOwinInstrumentation` method with default configure parameter. ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) * Adds HTTP server metrics via `AddOwinInstrumentation` extension method on `MeterProviderBuilder` diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index fc435aeb3b..d315d69808 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry API to 1.6.0 - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 0.5.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 4676dee4af..a520c719c8 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -5,8 +5,8 @@ * Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource being created ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) -* Update OpenTelemetry.Api to 1.6.0. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-alpha.3 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 49cae6d79f..b541c75950 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry API to 1.6.0 - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update `OpenTelemetry.Api` to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.5.1 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 26bae0ac4a..d452bbc308 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.0.0-rc9.12 Released 2023-Nov-01 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index fd35609cca..1bce6c18eb 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 1.0.0-rc.13 Released 2023-Oct-30 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 6a94208117..85684ae331 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.6.0`. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Fix AWS EBS Resource Detector working on linux. ([#1350](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1350)) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj index bf14fa2ce6..b5ad0ad470 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 201ed431e9..f0642f5d18 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -4,6 +4,8 @@ * Added NET6 target framework to support Trimming. ([#1405](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1405)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-beta.3 diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 76f6218b5a..993cf0424a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates to 1.6.0 of OpenTelemetry SDK. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md index 88b9ab59c6..221c846b0b 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + ## 0.1.0-alpha.1 Released 2023-Dec-04 diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj index 5bb3fc7f40..546004afde 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj @@ -8,5 +8,6 @@ + diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 36a41a1816..a28f47d696 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -8,5 +8,5 @@ Initial release of `OpenTelemetry.Sampler.AWS`. ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091), [#1124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1124)) -* Update OpenTelemetry SDK version to `1.6.0`. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index 7900174973..51643933c0 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -176,7 +176,7 @@ public void ForEachScope(Action callback, TState state) } } - public IDisposable Push(object state) + public IDisposable Push(object? state) { throw new NotImplementedException(); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index ca9bc789b4..d706e6355e 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -326,7 +326,7 @@ public void ForEachScope(Action callback, TState state) } } - public IDisposable Push(object state) + public IDisposable Push(object? state) { throw new NotImplementedException(); } diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 183e59049a..54874eb090 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -79,7 +79,7 @@ public void AttachLogsToActivityEventTest( Activity? activity = this.activitySource.StartActivity("Test"); Assert.NotNull(activity); - using IDisposable scope = logger.BeginScope("{NodeId}", 99); + using IDisposable? scope = logger.BeginScope("{NodeId}", 99); logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); @@ -89,7 +89,7 @@ public void AttachLogsToActivityEventTest( innerActivity = this.activitySource.StartActivity("InnerTest"); Assert.NotNull(innerActivity); - using IDisposable innerScope = logger.BeginScope("{RequestId}", "1234"); + using IDisposable? innerScope = logger.BeginScope("{RequestId}", "1234"); logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); @@ -211,7 +211,7 @@ public void AttachLogsToActivityEventTest_Filter( Activity? activity = this.activitySource.StartActivity("Test"); Assert.NotNull(activity); - using IDisposable scope = logger.BeginScope("{NodeId}", 99); + using IDisposable? scope = logger.BeginScope("{NodeId}", 99); logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); @@ -220,7 +220,7 @@ public void AttachLogsToActivityEventTest_Filter( var innerActivity = this.activitySource.StartActivity("InnerTest"); Assert.NotNull(innerActivity); - using IDisposable innerScope = logger.BeginScope("{RequestId}", "1234"); + using IDisposable? innerScope = logger.BeginScope("{RequestId}", "1234"); logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 393df0e152..aa1088457d 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -7,10 +7,6 @@ $(TargetFrameworks);net462 - - - - diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index d8b0c23530..a9171bb47f 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -8,7 +8,6 @@ - From a60dc5a54a599ceefd629aef2f0c97ee17f49072 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:54:35 -0800 Subject: [PATCH 0913/1499] [Exporter.Geneva] Update CHANGELOG for 1.7.0 (#1489) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 546cdf92b3..bcbbc3f0bb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0 + +Released 2023-Dec-11 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) From 4640cba7a3839fe6304c6e0ebff66755ccc53927 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 11 Dec 2023 16:29:16 -0800 Subject: [PATCH 0914/1499] Fix build errors (#1488) --- .../PointDataExtensions.cs | 2 +- .../OpenTelemetry.Exporter.Instana.csproj | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs index 45ab06c1e0..7896fb1ecc 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/PointDataExtensions.cs @@ -12,7 +12,7 @@ public static PointData Tags(this PointData pointData, ReadOnlyTagCollection tag { foreach (var tag in tags) { - pointData = pointData.Tag(tag.Key, tag.Value.ToString()); + pointData = pointData.Tag(tag.Key, tag.Value?.ToString()); } return pointData; diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 6bf7265650..a3a126f1d8 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -12,10 +12,16 @@ - - - + + From 3b0c4721328b600ac50eefad2c2e80ead473504b Mon Sep 17 00:00:00 2001 From: Christoffer Hjalmarsson Date: Tue, 12 Dec 2023 03:11:09 +0100 Subject: [PATCH 0915/1499] [Instrumentation.AspNet] Update semantic conventions for metrics (#1429) --- .../CHANGELOG.md | 26 +++++++ .../Implementation/HttpInListener.cs | 25 +------ .../Implementation/HttpInMetricsListener.cs | 47 +++++++++++-- .../Implementation/HttpRequestRouteHelper.cs | 48 +++++++++++++ .../Implementation/RequestMethodHelper.cs | 49 +++++++++++++ src/Shared/SemanticConventions.cs | 6 ++ .../HttpInMetricsListenerTests.cs | 70 ++++++++++++++----- .../RequestMethodHelperTests.cs | 57 +++++++++++++++ 8 files changed, 279 insertions(+), 49 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 113da505ea..72f35abe2b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -8,6 +8,32 @@ * New overload of `AddAspNetInstrumentation` now accepts a configuration delegate. * The `Enrich` can be used to add additional metric attributes. +* BREAKING: HTTP server metrics now follow stable + [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-server) + ([#1429](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1429)). + + * New metric: `http.server.request.duration` + * Unit: `s` (seconds) + * Histogram Buckets: `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` + * Old metric: `http.server.duration` + * Unit: `ms` (milliseconds) + * Histogram Buckets: `0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, + 5000, 7500, 10000` + + Note that the bucket changes are part of the 1.7.0-rc.1 release of the + `OpenTelemetry` SDK. + + The following metric attributes has been added: + + * `http.request.method` (previously `http.method`) + * `http.response.status_code` (previously `http.status_code`) + * `url.scheme` (previously `http.scheme`) + * `server.address` + * `server.port` + * `network.protocol.version` (`1.1`, `2`, `3`) + * `http.route` + ## 1.6.0-beta.2 Released 2023-Nov-06 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index bcca75907c..e0f2e1688f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; using System.Web; -using System.Web.Routing; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -13,8 +12,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation; internal sealed class HttpInListener : IDisposable { - private readonly PropertyFetcher routeFetcher = new("Route"); - private readonly PropertyFetcher routeTemplateFetcher = new("RouteTemplate"); + private readonly HttpRequestRouteHelper routeHelper = new(); private readonly AspNetInstrumentationOptions options; public HttpInListener(AspNetInstrumentationOptions options) @@ -120,26 +118,7 @@ private void OnStopActivity(Activity activity, HttpContext context) activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); } - var routeData = context.Request.RequestContext.RouteData; - - string? template = null; - if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) - { - // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. - - if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1) - { - var subRouteData = attributeRouting.GetValue(0); - - _ = this.routeFetcher.TryFetch(subRouteData, out var route); - _ = this.routeTemplateFetcher.TryFetch(route, out template); - } - } - else if (routeData.Route is Route route) - { - // MVC + WebAPI traditional routing & MVC attribute routing flow here. - template = route.Url; - } + var template = this.routeHelper.GetRouteTemplate(context.Request); if (!string.IsNullOrEmpty(template)) { diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index 8428e8d8d5..93afb6ddc1 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -11,12 +11,17 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation; internal sealed class HttpInMetricsListener : IDisposable { + private readonly HttpRequestRouteHelper routeHelper = new(); + private readonly RequestMethodHelper requestMethodHelper = new(); private readonly Histogram httpServerDuration; private readonly AspNetMetricsInstrumentationOptions options; public HttpInMetricsListener(Meter meter, AspNetMetricsInstrumentationOptions options) { - this.httpServerDuration = meter.CreateHistogram("http.server.duration", "ms", "Measures the duration of inbound HTTP requests."); + this.httpServerDuration = meter.CreateHistogram( + "http.server.request.duration", + unit: "s", + description: "Measures the duration of inbound HTTP requests."); TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; this.options = options; } @@ -26,17 +31,45 @@ public void Dispose() TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; } + private static string GetHttpProtocolVersion(HttpRequest request) + { + var protocol = request.ServerVariables["SERVER_PROTOCOL"]; + return protocol switch + { + "HTTP/1.1" => "1.1", + "HTTP/2" => "2", + "HTTP/3" => "3", + _ => protocol, + }; + } + private void OnStopActivity(Activity activity, HttpContext context) { - // TODO: This is just a minimal set of attributes. See the spec for additional attributes: - // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#http-server + var request = context.Request; + var url = request.Url; var tags = new TagList { - { SemanticConventions.AttributeHttpMethod, context.Request.HttpMethod }, - { SemanticConventions.AttributeHttpScheme, context.Request.Url.Scheme }, - { SemanticConventions.AttributeHttpStatusCode, context.Response.StatusCode }, + { SemanticConventions.AttributeServerAddress, url.Host }, + { SemanticConventions.AttributeServerPort, url.Port }, + { SemanticConventions.AttributeUrlScheme, url.Scheme }, + { SemanticConventions.AttributeHttpResponseStatusCode, context.Response.StatusCode }, }; + var normalizedMethod = this.requestMethodHelper.GetNormalizedHttpMethod(request.HttpMethod); + tags.Add(SemanticConventions.AttributeHttpRequestMethod, normalizedMethod); + + var protocolVersion = GetHttpProtocolVersion(request); + if (!string.IsNullOrEmpty(protocolVersion)) + { + tags.Add(SemanticConventions.AttributeNetworkProtocolVersion, protocolVersion); + } + + var template = this.routeHelper.GetRouteTemplate(request); + if (!string.IsNullOrEmpty(template)) + { + tags.Add(SemanticConventions.AttributeHttpRoute, template); + } + if (this.options.Enrich is not null) { try @@ -49,6 +82,6 @@ private void OnStopActivity(Activity activity, HttpContext context) } } - this.httpServerDuration.Record(activity.Duration.TotalMilliseconds, tags); + this.httpServerDuration.Record(activity.Duration.TotalSeconds, tags); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs new file mode 100644 index 0000000000..e37034918b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Web; +using System.Web.Routing; + +namespace OpenTelemetry.Instrumentation.AspNet.Implementation; + +/// +/// Helper class for processing http requests. +/// +internal sealed class HttpRequestRouteHelper +{ + private readonly PropertyFetcher routeFetcher = new("Route"); + private readonly PropertyFetcher routeTemplateFetcher = new("RouteTemplate"); + + /// + /// Extracts the route template from the . + /// + /// The being processed. + /// The route template or . + internal string? GetRouteTemplate(HttpRequest request) + { + var routeData = request.RequestContext.RouteData; + + string? template = null; + if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) + { + // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. + + if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1) + { + var subRouteData = attributeRouting.GetValue(0); + + _ = this.routeFetcher.TryFetch(subRouteData, out var route); + _ = this.routeTemplateFetcher.TryFetch(route, out template); + } + } + else if (routeData.Route is Route route) + { + // MVC + WebAPI traditional routing & MVC attribute routing flow here. + template = route.Url; + } + + return template; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs new file mode 100644 index 0000000000..3d7c5d4183 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenTelemetry.Instrumentation.AspNet.Implementation; + +internal sealed class RequestMethodHelper +{ + private const string KnownHttpMethodsEnvironmentVariable = "OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS"; + + // The value "_OTHER" is used for non-standard HTTP methods. + // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes + private const string OtherHttpMethod = "_OTHER"; + + private static readonly char[] SplitChars = new[] { ',' }; + + // List of known HTTP methods as per spec. + private readonly Dictionary knownHttpMethods; + + public RequestMethodHelper() + { + var suppliedKnownMethods = Environment.GetEnvironmentVariable(KnownHttpMethodsEnvironmentVariable) + ?.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries); + this.knownHttpMethods = suppliedKnownMethods?.Length > 0 + ? suppliedKnownMethods.ToDictionary(x => x, x => x, StringComparer.OrdinalIgnoreCase) + : new(StringComparer.OrdinalIgnoreCase) + { + ["GET"] = "GET", + ["POST"] = "POST", + ["PUT"] = "PUT", + ["DELETE"] = "DELETE", + ["HEAD"] = "HEAD", + ["OPTIONS"] = "OPTIONS", + ["TRACE"] = "TRACE", + ["PATCH"] = "PATCH", + ["CONNECT"] = "CONNECT", + }; + } + + public string GetNormalizedHttpMethod(string method) + { + return this.knownHttpMethods.TryGetValue(method, out var normalizedMethod) + ? normalizedMethod + : OtherHttpMethod; + } +} diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 9129802570..202d4b4eef 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -101,5 +101,11 @@ internal static class SemanticConventions public const string AttributeHttpRequestMethod = "http.request.method"; // replaces: "http.method" (AttributeHttpMethod) public const string AttributeHttpResponseStatusCode = "http.response.status_code"; // replaces: "http.status_code" (AttributeHttpStatusCode) public const string AttributeUrlScheme = "url.scheme"; // replaces: "http.scheme" (AttributeHttpScheme) + + // v1.23.0 + // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-server + public const string AttributeNetworkProtocolVersion = "network.protocol.version"; // replaces: "http.flavor" (AttributeHttpFlavor) + public const string AttributeServerAddress = "server.address"; // replaces: "net.host.name" (AttributeNetHostName) + public const string AttributeServerPort = "server.port"; // replaces: "net.host.port" (AttributeNetHostPort) #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index 37515d66dc..eb418eb263 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -16,27 +16,33 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class HttpInMetricsListenerTests { [Theory] - [InlineData("http://localhost/", 0, null, null, "http")] - [InlineData("https://localhost/", 0, null, null, "https")] - [InlineData("http://localhost/api/value", 0, null, null, "http")] - [InlineData("http://localhost/api/value", 1, "{controller}/{action}", null, "http")] - [InlineData("http://localhost/api/value", 2, "{controller}/{action}", null, "http")] - [InlineData("http://localhost/api/value", 3, "{controller}/{action}", null, "http")] - [InlineData("http://localhost/api/value", 4, "{controller}/{action}", null, "http")] - [InlineData("http://localhost:8080/api/value", 0, null, null, "http")] - [InlineData("http://localhost:8080/api/value", 1, "{controller}/{action}", null, "http")] - [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", "enrich", "http")] - [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", "throw", "http")] - [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", null, "http")] + [InlineData("http://localhost/", 0, null, null, "http", "localhost", null, 80, 200)] + [InlineData("https://localhost/", 0, null, null, "https", "localhost", null, 443, 200)] + [InlineData("http://localhost/api/value", 0, null, null, "http", "localhost", null, 80, 200)] + [InlineData("http://localhost/api/value", 1, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 200)] + [InlineData("http://localhost/api/value", 2, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 201)] + [InlineData("http://localhost/api/value", 3, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 200)] + [InlineData("http://localhost/api/value", 4, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 200)] + [InlineData("http://localhost/api/value", 1, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 500)] + [InlineData("http://localhost:8080/api/value", 0, null, null, "http", "localhost", null, 8080, 200)] + [InlineData("http://localhost:8080/api/value", 1, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 8080, 200)] + [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", "enrich", "http", "localhost", "{controller}/{action}", 8080, 200)] + [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", "throw", "http", "localhost", "{controller}/{action}", 8080, 200)] + [InlineData("http://localhost:8080/api/value", 3, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 8080, 200)] public void AspNetMetricTagsAreCollectedSuccessfully( string url, int routeType, string routeTemplate, string enrichMode, - string expectedScheme) + string expectedScheme, + string expectedHost, + string expectedRoute, + int? expectedPort, + int expectedStatus) { double duration = 0; HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); + HttpContext.Current.Response.StatusCode = expectedStatus; // This is to enable activity creation // as it is created using ActivitySource inside TelemetryHttpModule @@ -47,7 +53,7 @@ public void AspNetMetricTagsAreCollectedSuccessfully( { if (eventName.Equals("OnStopActivity")) { - duration = activity.Duration.TotalMilliseconds; + duration = activity.Duration.TotalSeconds; } }) .Build(); @@ -94,12 +100,19 @@ public void AspNetMetricTagsAreCollectedSuccessfully( var sum = metricPoint.GetHistogramSum(); Assert.Equal(MetricType.Histogram, exportedItems[0].MetricType); - Assert.Equal("http.server.duration", exportedItems[0].Name); + Assert.Equal("http.server.request.duration", exportedItems[0].Name); + Assert.Equal("s", exportedItems[0].Unit); Assert.Equal(1L, count); Assert.Equal(duration, sum); Assert.True(duration > 0, "Metric duration should be set."); - var expectedTagCount = 3; + var expectedTagCount = 5; + + if (!string.IsNullOrEmpty(expectedRoute)) + { + expectedTagCount++; + } + if (enrichMode == "enrich") { expectedTagCount++; @@ -117,9 +130,28 @@ public void AspNetMetricTagsAreCollectedSuccessfully( ExpectTag("true", "enriched"); } - ExpectTag("GET", SemanticConventions.AttributeHttpMethod); - ExpectTag(200, SemanticConventions.AttributeHttpStatusCode); - ExpectTag(expectedScheme, SemanticConventions.AttributeHttpScheme); + // Do not use constants from SemanticConventions here in order to detect mistakes. + // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-server + // Unable to check for "network.protocol.version" because we can't set server variables due to the accessibility + // of the ServerVariables property. + ExpectTag("GET", "http.request.method"); + ExpectTag(expectedStatus, "http.response.status_code"); + ExpectTag(expectedRoute, "http.route"); + ExpectTag(expectedHost, "server.address"); + ExpectTag(expectedPort, "server.port"); + ExpectTag(expectedScheme, "url.scheme"); + + // Inspect histogram bucket boundaries. + var histogramBuckets = metricPoint.GetHistogramBuckets(); + var histogramBounds = new List(); + foreach (var t in histogramBuckets) + { + histogramBounds.Add(t.ExplicitBound); + } + + Assert.Equal( + expected: new List { 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, double.PositiveInfinity }, + actual: histogramBounds); void ExpectTag(T? expected, string tagName) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs new file mode 100644 index 0000000000..fd0312f187 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs @@ -0,0 +1,57 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using OpenTelemetry.Instrumentation.AspNet.Implementation; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNet.Tests; + +public class RequestMethodHelperTests : IDisposable +{ + [Theory] + [InlineData("GET", "GET")] + [InlineData("POST", "POST")] + [InlineData("PUT", "PUT")] + [InlineData("DELETE", "DELETE")] + [InlineData("HEAD", "HEAD")] + [InlineData("OPTIONS", "OPTIONS")] + [InlineData("TRACE", "TRACE")] + [InlineData("PATCH", "PATCH")] + [InlineData("CONNECT", "CONNECT")] + [InlineData("get", "GET")] + [InlineData("invalid", "_OTHER")] + public void MethodMappingWorksForKnownMethods(string method, string expected) + { + var requestHelper = new RequestMethodHelper(); + var actual = requestHelper.GetNormalizedHttpMethod(method); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData("GET", "GET")] + [InlineData("POST", "POST")] + [InlineData("PUT", "_OTHER")] + [InlineData("DELETE", "_OTHER")] + [InlineData("HEAD", "_OTHER")] + [InlineData("OPTIONS", "_OTHER")] + [InlineData("TRACE", "_OTHER")] + [InlineData("PATCH", "_OTHER")] + [InlineData("CONNECT", "_OTHER")] + [InlineData("get", "GET")] + [InlineData("post", "POST")] + [InlineData("invalid", "_OTHER")] + public void MethodMappingWorksForEnvironmentVariables(string method, string expected) + { + Environment.SetEnvironmentVariable("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", "GET,POST"); + var requestHelper = new RequestMethodHelper(); + var actual = requestHelper.GetNormalizedHttpMethod(method); + Assert.Equal(expected, actual); + } + + public void Dispose() + { + // Clean up after tests that set environment variables. + Environment.SetEnvironmentVariable("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", null); + } +} From fb693359f0d91619b904f55bf1a3eed16958610a Mon Sep 17 00:00:00 2001 From: Nils Gruson Date: Tue, 12 Dec 2023 07:29:06 +0100 Subject: [PATCH 0916/1499] Moq cleanup (#1490) --- build/Common.nonprod.props | 1 - .../AssemblyInfo.cs | 3 --- src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs | 3 --- 3 files changed, 7 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 05a82c657d..13ad885f38 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -23,7 +23,6 @@ [0.13.10,0.14) [2.3.1,3.0) [17.7.2,18.0) - [4.18.4,5.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net7.0;net6.0 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs index c6326279b7..cfa09d112a 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/AssemblyInfo.cs @@ -4,18 +4,15 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED internal static class AssemblyInfo { public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; - public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; } #else internal static class AssemblyInfo { public const string PublicKey = ""; - public const string MoqPublicKey = ""; } #endif diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs index 6f645eafca..7f48d3cfc5 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/AssemblyInfo.cs @@ -4,18 +4,15 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OpenTelemetry.PersistentStorage.FileSystem.Tests" + AssemblyInfo.PublicKey)] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2" + AssemblyInfo.MoqPublicKey)] #if SIGNED internal static class AssemblyInfo { public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; - public const string MoqPublicKey = ", PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7"; } #else internal static class AssemblyInfo { public const string PublicKey = ""; - public const string MoqPublicKey = ""; } #endif From 18e54f35c13ed8a908986321d867cc103b40f9d0 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 12 Dec 2023 16:25:37 -0800 Subject: [PATCH 0917/1499] [repo] Fix the solution build in CI to fail if errors are thrown (#1487) --- .github/workflows/ci.yml | 12 ++++++++++++ build/Common.nonprod.props | 15 +++++++++++++++ build/Common.props | 1 + examples/AspNet/Web.config | 14 +++++++++++++- .../OpenTelemetry.Exporter.Instana.csproj | 2 +- .../OpenTelemetry.Exporter.Stackdriver.csproj | 1 + ...Telemetry.Exporter.Stackdriver.Tests.csproj | 18 ++++++++++++++++++ .../AWSXRayIdGeneratorTests.cs | 5 ----- 8 files changed, 61 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59eb715305..67e3c9a685 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -274,9 +274,21 @@ jobs: OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj + $failedProjects = @() + ForEach ($project in $projects) { dotnet test $project.FullName --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + + if ($LASTEXITCODE -ne 0) + { + $failedProjects = $failedProjects + $project + } + } + + if ($failedProjects.Count -gt 0) + { + throw "dotnet test failed on '$failedProjects' project(s)" } - name: Install coverage tool diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 13ad885f38..a9c9468210 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -39,4 +39,19 @@ + + + + <_SkipTests>true + false + + + + + diff --git a/build/Common.props b/build/Common.props index b0dc596895..f246020949 100644 --- a/build/Common.props +++ b/build/Common.props @@ -21,6 +21,7 @@ true + true diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index 12073fe2c3..5dd986c90a 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -33,6 +33,18 @@ + + + + + + + + + + + + @@ -59,7 +71,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index a3a126f1d8..5e81f1fac0 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -21,7 +21,7 @@ --> - + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 025d4ddd29..e338015745 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -7,6 +7,7 @@ Exporter.Stackdriver- true + diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index b527a67cf2..ab94de47f5 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -12,5 +12,23 @@ + + + + + + + + + $(PkgSystem_Net_Http)\lib\net46\System.Net.Http.dll + True + diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs index 0359482ec3..bb4ec1bcd5 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs @@ -23,12 +23,7 @@ public void TestGenerateTraceIdForRootNode() activity.Start(); Assert.NotEqual(originalTraceId, activity.TraceId); -#if NET6_0_OR_GREATER - // the net6.0 version of AWSXRayIdGenerator uses Activity.TraceIdGenerator, which does not change the parent ID Assert.Equal(originalParentSpanId, activity.ParentSpanId); -#else - Assert.NotEqual(originalParentSpanId, activity.ParentSpanId); -#endif Assert.Equal("0000000000000000", activity.ParentSpanId.ToHexString()); Assert.Equal(originalTraceFlag, activity.ActivityTraceFlags); } From 97bd0ae7a1963185db65006f9c79e882d65bff75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 11:41:30 -0800 Subject: [PATCH 0918/1499] Bump github/codeql-action from 2 to 3 (#1494) --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0b466885dd..07744cc446 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -37,7 +37,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -48,7 +48,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -62,4 +62,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From 06b8bb79ed9752e23319b7147e1d9796988941eb Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Thu, 14 Dec 2023 05:22:37 +0200 Subject: [PATCH 0919/1499] Add Filter to HangfireInstrumentationOptions (#1440) --- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 3 + .../HangfireInstrumentationOptions.cs | 21 ++++- ...ngfireInstrumentationJobFilterAttribute.cs | 16 ++++ .../README.md | 77 ++++++++++++++++++- ...eInstrumentationJobFilterAttributeTests.cs | 37 +++++++++ .../ProcessorMock.cs | 28 +++++++ 7 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index eaa7631d77..7c2225b43f 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,8 @@ OpenTelemetry.Trace.HangfireInstrumentationOptions OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.get -> System.Func! OpenTelemetry.Trace.HangfireInstrumentationOptions.DisplayNameFunc.set -> void +OpenTelemetry.Trace.HangfireInstrumentationOptions.Filter.get -> System.Func? +OpenTelemetry.Trace.HangfireInstrumentationOptions.Filter.set -> void OpenTelemetry.Trace.HangfireInstrumentationOptions.HangfireInstrumentationOptions() -> void OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 6d24250490..432396546e 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -11,6 +11,9 @@ options management ([#1442](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1442)) +* Add Filter to HangfireInstrumentationOptions. + ([#1440](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1440)) + ## 1.5.0-beta.1 Released 2023-Jun-23 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs index 447c3bc902..baec4e1dba 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/HangfireInstrumentationOptions.cs @@ -16,7 +16,7 @@ public class HangfireInstrumentationOptions /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. /// /// - /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. + /// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md. /// public bool RecordException { get; set; } @@ -27,4 +27,23 @@ public class HangfireInstrumentationOptions /// Defaults to {backgroundJob.Job.Type.Name}.{backgroundJob.Job.Method.Name}. /// public Func DisplayNameFunc { get; set; } = HangfireInstrumentation.DefaultDisplayNameFunc; + + /// + /// Gets or sets a filter function that determines whether or not to + /// collect telemetry about the the being executed. + /// + /// + /// Notes: + /// + /// The first parameter passed to the filter function is being executed. + /// The return value for the filter: + /// + /// If filter returns , the command is + /// collected. + /// If filter returns or throws an + /// exception, the command is NOT collected. + /// + /// + /// + public Func? Filter { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 03c12fc944..a222ae4bb8 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -52,6 +52,22 @@ public void OnPerforming(PerformingContext performingContext) if (activity.IsAllDataRequested) { + try + { + if (this.options.Filter?.Invoke(performingContext.BackgroundJob) == false) + { + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + } + catch (Exception) + { + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + activity.SetTag(HangfireInstrumentationConstants.JobIdTag, performingContext.BackgroundJob.Id); activity.SetTag(HangfireInstrumentationConstants.JobCreatedAtTag, performingContext.BackgroundJob.CreatedAt.ToString("O")); } diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index 03ebe5ddf1..fec0182421 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -42,7 +42,8 @@ public class Program { public static void Main(string[] args) { - using var tracerProvider = Sdk.CreateTracerProviderBuilder() + using var tracerProvider = Sdk + .CreateTracerProviderBuilder() .AddHangfireInstrumentation() .AddConsoleExporter() .Build(); @@ -58,6 +59,22 @@ For an ASP.NET application, adding instrumentation is typically done in the ## Advanced configuration +This instrumentation can be configured to change the default behavior by using +`HangfireInstrumentationOptions`. + +```csharp +using var tracerProvider = Sdk + .CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => + { + options.DisplayNameFunc = job => $"JOB {job.Id}"; + options.Filter = job => job.Id == "Filter this job"; + options.RecordException = true; + }) + .AddConsoleExporter() + .Build(); +``` + When used with [`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md), all configurations to `HangfireInstrumentationOptions` @@ -79,6 +96,64 @@ services.AddOpenTelemetry() .AddConsoleExporter()); ``` +### RecordException + +Configures a value indicating whether the exception will be recorded as +ActivityEvent or not. See +[Semantic Conventions for Exceptions on Spans](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md) + +```csharp +using var tracerProvider = Sdk + .CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => + { + options.RecordException = true; + }) + .AddConsoleExporter() + .Build(); +``` + +### DisplayNameFunc + +This option allows changing activity display name. + +```C# +using var tracerProvider = Sdk + .CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => + { + options.DisplayNameFunc = job => $"JOB {job.Id}"; + }) + .AddConsoleExporter() + .Build(); +``` + +If not configured the default is + +```C# +$"JOB {BackgroundJob.Job.Type.Name}.{BackgroundJob.Job.Method.Name}" +``` + +### Filter + +This option can be used to filter out activities based on the `BackgroundJob` +being executed. The `Filter` function should return `true` if the telemetry is +to be collected, and `false` if it should not. + +The following code snippet shows how to use `Filter` to filter out traces for +job with a specified job id. + +```csharp +using var tracerProvider = Sdk + .CreateTracerProviderBuilder() + .AddHangfireInstrumentation(options => + { + options.Filter = job => job.Id == "Filter this job"; + }) + .AddConsoleExporter() + .Build(); +``` + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index 39a21b8322..08e7d3cc6c 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -136,6 +136,43 @@ public async Task Should_Create_Activity_With_Custom_DisplayName() Assert.Equal(ActivityKind.Internal, activity.Kind); } + [Theory] + [InlineData("null", true)] + [InlineData("true", true)] + [InlineData("false", false)] + [InlineData("throw", false)] + public async Task Should_Respect_Filter_Option(string filter, bool shouldRecord) + { + // Arrange + Action configure = filter switch + { + "null" => options => options.Filter = null, + "true" => options => options.Filter = _ => true, + "false" => options => options.Filter = _ => false, + "throw" => options => options.Filter = _ => throw new Exception("Filter throws exception"), + _ => throw new ArgumentOutOfRangeException(nameof(filter), filter, "Unexpected value"), + }; + + var processedItems = new List(); + var activityProcessor = new ProcessorMock(onStart: processedItems.Add); + + using var tel = Sdk.CreateTracerProviderBuilder() + .AddHangfireInstrumentation(configure) + .AddProcessor(activityProcessor) + .Build(); + + // Act + var jobId = BackgroundJob.Enqueue(x => x.Execute()); + await this.WaitJobProcessedAsync(jobId, 5); + + // Assert + Assert.Single(processedItems); + var activity = processedItems.First(); + + Assert.Equal(shouldRecord, activity.IsAllDataRequested); + Assert.Equal(shouldRecord, activity.ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); + } + private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) { var timeout = DateTime.Now.AddSeconds(timeToWaitInSeconds); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs new file mode 100644 index 0000000000..6c556045de --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; + +namespace OpenTelemetry.Instrumentation.Hangfire.Tests; + +public class ProcessorMock : BaseProcessor +{ + private readonly Action? onStart; + private readonly Action? onEnd; + + public ProcessorMock(Action? onStart = null, Action? onEnd = null) + { + this.onStart = onStart; + this.onEnd = onEnd; + } + + public override void OnStart(T data) + { + this.onStart?.Invoke(data); + } + + public override void OnEnd(T data) + { + this.onEnd?.Invoke(data); + } +} From 4da4cf8d7f9cdec08b6ec2575f87bfb845026ad9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:42:15 +0100 Subject: [PATCH 0920/1499] Bump actions/upload-artifact from 3 to 4 (#1496) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/Component.Package.yml | 2 +- .github/workflows/package-Exporter.InfluxDB.yml | 2 +- .github/workflows/package-Exporter.Instana.yml | 2 +- .github/workflows/package-Exporter.Stackdriver.yml | 2 +- .github/workflows/package-Extensions.AWS.yml | 2 +- .github/workflows/package-Extensions.Enrichment.yml | 2 +- .github/workflows/package-Instrumentation.AWS.yml | 2 +- .github/workflows/package-Instrumentation.AWSLambda.yml | 2 +- .github/workflows/package-Instrumentation.Cassandra.yml | 2 +- .github/workflows/package-Instrumentation.Elasticsearch.yml | 2 +- .../workflows/package-Instrumentation.EntityFrameworkCore.yml | 2 +- .github/workflows/package-Instrumentation.GrpcCore.yml | 2 +- .github/workflows/package-Instrumentation.Hangfire.yml | 2 +- .github/workflows/package-Instrumentation.Quartz.yml | 2 +- .github/workflows/package-ResourceDetectors.AWS.yml | 2 +- .github/workflows/package-ResourceDetectors.Container.yml | 2 +- .github/workflows/package-Sampler.AWS.yml | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml index c8dd4705ab..29678a018e 100644 --- a/.github/workflows/Component.Package.yml +++ b/.github/workflows/Component.Package.yml @@ -39,7 +39,7 @@ jobs: run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.project-name }}.proj-packages path: 'src/*/bin/Release/*.*nupkg' diff --git a/.github/workflows/package-Exporter.InfluxDB.yml b/.github/workflows/package-Exporter.InfluxDB.yml index 000d041b39..a4e7b29281 100644 --- a/.github/workflows/package-Exporter.InfluxDB.yml +++ b/.github/workflows/package-Exporter.InfluxDB.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Exporter.Instana.yml b/.github/workflows/package-Exporter.Instana.yml index a5e52af5cc..542fa4c932 100644 --- a/.github/workflows/package-Exporter.Instana.yml +++ b/.github/workflows/package-Exporter.Instana.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Exporter.Stackdriver.yml b/.github/workflows/package-Exporter.Stackdriver.yml index a750ed217f..e4c2239d91 100644 --- a/.github/workflows/package-Exporter.Stackdriver.yml +++ b/.github/workflows/package-Exporter.Stackdriver.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Extensions.AWS.yml b/.github/workflows/package-Extensions.AWS.yml index 6262eb167f..4ec2ba376e 100644 --- a/.github/workflows/package-Extensions.AWS.yml +++ b/.github/workflows/package-Extensions.AWS.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Extensions.Enrichment.yml b/.github/workflows/package-Extensions.Enrichment.yml index 7f62f243a0..2b1ab8a93b 100644 --- a/.github/workflows/package-Extensions.Enrichment.yml +++ b/.github/workflows/package-Extensions.Enrichment.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.AWS.yml b/.github/workflows/package-Instrumentation.AWS.yml index b347ee89d9..d47e0881ca 100644 --- a/.github/workflows/package-Instrumentation.AWS.yml +++ b/.github/workflows/package-Instrumentation.AWS.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.AWSLambda.yml b/.github/workflows/package-Instrumentation.AWSLambda.yml index a667ed8f24..e0b1c5d1d5 100644 --- a/.github/workflows/package-Instrumentation.AWSLambda.yml +++ b/.github/workflows/package-Instrumentation.AWSLambda.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Cassandra.yml b/.github/workflows/package-Instrumentation.Cassandra.yml index 9f3f677554..e8cdd809dd 100644 --- a/.github/workflows/package-Instrumentation.Cassandra.yml +++ b/.github/workflows/package-Instrumentation.Cassandra.yml @@ -42,7 +42,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Elasticsearch.yml b/.github/workflows/package-Instrumentation.Elasticsearch.yml index d5c99760b8..3abf5e599b 100644 --- a/.github/workflows/package-Instrumentation.Elasticsearch.yml +++ b/.github/workflows/package-Instrumentation.Elasticsearch.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml index a4d182225d..58a8a406e7 100644 --- a/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml +++ b/.github/workflows/package-Instrumentation.EntityFrameworkCore.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.GrpcCore.yml b/.github/workflows/package-Instrumentation.GrpcCore.yml index 4da86113e9..577ff3dc0a 100644 --- a/.github/workflows/package-Instrumentation.GrpcCore.yml +++ b/.github/workflows/package-Instrumentation.GrpcCore.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Hangfire.yml b/.github/workflows/package-Instrumentation.Hangfire.yml index a32ce2625f..b748502d4c 100644 --- a/.github/workflows/package-Instrumentation.Hangfire.yml +++ b/.github/workflows/package-Instrumentation.Hangfire.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Instrumentation.Quartz.yml b/.github/workflows/package-Instrumentation.Quartz.yml index c943d53c9f..264481a864 100644 --- a/.github/workflows/package-Instrumentation.Quartz.yml +++ b/.github/workflows/package-Instrumentation.Quartz.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-ResourceDetectors.AWS.yml b/.github/workflows/package-ResourceDetectors.AWS.yml index c9e5c97f32..5faf143022 100644 --- a/.github/workflows/package-ResourceDetectors.AWS.yml +++ b/.github/workflows/package-ResourceDetectors.AWS.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-ResourceDetectors.Container.yml b/.github/workflows/package-ResourceDetectors.Container.yml index 425d29453e..33e072fbc5 100644 --- a/.github/workflows/package-ResourceDetectors.Container.yml +++ b/.github/workflows/package-ResourceDetectors.Container.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' diff --git a/.github/workflows/package-Sampler.AWS.yml b/.github/workflows/package-Sampler.AWS.yml index 3b17a7a3c9..f08de2ee1d 100644 --- a/.github/workflows/package-Sampler.AWS.yml +++ b/.github/workflows/package-Sampler.AWS.yml @@ -44,7 +44,7 @@ jobs: run: dotnet pack src/${{env.PROJECT}} --configuration Release --no-build - name: Publish Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{env.PROJECT}}-packages path: '**/${{env.PROJECT}}/bin/**/*.*nupkg' From e42f6cdda1120e7630aa69e0ab7e8560feddba31 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Fri, 15 Dec 2023 16:40:11 -0800 Subject: [PATCH 0921/1499] Add Vishwesh as maintainer (#1499) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ec824a8a1e..c718ad4372 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Maintainers * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk * [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft +* [Vishwesh Bankwar](https://github.com/vishweshbankwar), Microsoft *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* From b7bf1171acbde323a42526a162a8c597f203e24f Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:01:50 -0800 Subject: [PATCH 0922/1499] [Exporter.Geneva] Use HashSet instead of Dictionary (#1501) --- .../MsgPackExporter/MsgPackLogExporter.cs | 14 ++++---- .../MsgPackExporter/MsgPackTraceExporter.cs | 32 ++++++++++--------- .../TLDExporter/TldLogExporter.cs | 10 +++--- .../TLDExporter/TldTraceExporter.cs | 13 ++++---- .../GenevaTraceExporterTests.cs | 8 ++--- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 5c453d2cf2..e4ba33044a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -25,7 +25,7 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private readonly bool m_shouldExportEventName; private readonly TableNameSerializer m_tableNameSerializer; - private readonly Dictionary m_customFields; + private readonly HashSet m_customFields; private readonly Dictionary m_prepopulatedFields; private readonly ExceptionStackExportMode m_exportExceptionStack; private readonly List m_prepopulatedFieldKeys; @@ -83,10 +83,10 @@ public MsgPackLogExporter(GenevaExporterOptions options) // TODO: Validate custom fields (reserved name? etc). if (options.CustomFields != null) { - var customFields = new Dictionary(StringComparer.Ordinal); + var customFields = new HashSet(StringComparer.Ordinal); foreach (var name in options.CustomFields) { - customFields[name] = true; + customFields.Add(name); } this.m_customFields = customFields; @@ -263,7 +263,7 @@ internal int SerializeLogRecord(LogRecord logRecord) bodyPopulated = true; continue; } - else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + else if (this.m_customFields == null || this.m_customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. if (entry.Value != null) @@ -340,7 +340,7 @@ internal int SerializeLogRecord(LogRecord logRecord) for (int i = 0; i < listKvp.Count; i++) { var entry = listKvp[i]; - if (entry.Key == "{OriginalFormat}" || this.m_customFields.ContainsKey(entry.Key)) + if (entry.Key == "{OriginalFormat}" || this.m_customFields.Contains(entry.Key)) { continue; } @@ -470,7 +470,7 @@ public void Dispose() continue; } - if (customFields == null || customFields.ContainsKey(scopeItem.Key)) + if (customFields == null || customFields.Contains(scopeItem.Key)) { if (scopeItem.Value != null) { @@ -499,7 +499,7 @@ public void Dispose() continue; } - if (!customFields.ContainsKey(scopeItem.Key)) + if (!customFields.Contains(scopeItem.Key)) { stateData.Cursor = MessagePackSerializer.SerializeUnicodeString(stateData.Buffer, stateData.Cursor, scopeItem.Key); stateData.Cursor = MessagePackSerializer.Serialize(stateData.Buffer, stateData.Cursor, scopeItem.Value); diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 39bd3ea578..18432bc13b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -48,33 +48,35 @@ public MsgPackTraceExporter(GenevaExporterOptions options) // TODO: Validate custom fields (reserved name? etc). if (options.CustomFields != null) { - var customFields = new Dictionary(StringComparer.Ordinal); - var dedicatedFields = new Dictionary(StringComparer.Ordinal); + var customFields = new HashSet(StringComparer.Ordinal); + var dedicatedFields = new HashSet(StringComparer.Ordinal); // Seed customFields with Span PartB - customFields["azureResourceProvider"] = true; - dedicatedFields["azureResourceProvider"] = true; + customFields.Add("azureResourceProvider"); + dedicatedFields.Add("azureResourceProvider"); + foreach (var name in CS40_PART_B_MAPPING.Values) { - customFields[name] = true; - dedicatedFields[name] = true; + customFields.Add(name); + dedicatedFields.Add(name); } foreach (var name in options.CustomFields) { - customFields[name] = true; - dedicatedFields[name] = true; + customFields.Add(name); + dedicatedFields.Add(name); } this.m_customFields = customFields; foreach (var name in CS40_PART_B_MAPPING.Keys) { - dedicatedFields[name] = true; + dedicatedFields.Add(name); } - dedicatedFields["otel.status_code"] = true; - dedicatedFields["otel.status_description"] = true; + dedicatedFields.Add("otel.status_code"); + dedicatedFields.Add("otel.status_description"); + this.m_dedicatedFields = dedicatedFields; } @@ -286,7 +288,7 @@ internal int SerializeActivity(Activity activity) statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } - else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + else if (this.m_customFields == null || this.m_customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); @@ -313,7 +315,7 @@ internal int SerializeActivity(Activity activity) foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision - if (this.m_dedicatedFields.ContainsKey(entry.Key)) + if (this.m_dedicatedFields.Contains(entry.Key)) { continue; } @@ -422,9 +424,9 @@ public void Dispose() private readonly IDataTransport m_dataTransport; - private readonly Dictionary m_customFields; + private readonly HashSet m_customFields; - private readonly Dictionary m_dedicatedFields; + private readonly HashSet m_dedicatedFields; private bool isDisposed; } diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 7015d34722..7e9c6f72a5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -33,7 +33,7 @@ internal sealed class TldLogExporter : TldExporter, IDisposable private readonly byte partAFieldsCount = 1; // At least one field: time private readonly bool shouldPassThruTableMappings; private readonly string defaultEventName = "Log"; - private readonly Dictionary customFields; + private readonly HashSet customFields; private readonly Dictionary tableMappings; private readonly Tuple repeatedPartAFields; private readonly ExceptionStackExportMode exceptionStackExportMode; @@ -81,10 +81,10 @@ public TldLogExporter(GenevaExporterOptions options) // TODO: Validate custom fields (reserved name? etc). if (options.CustomFields != null) { - var customFields = new Dictionary(StringComparer.Ordinal); + var customFields = new HashSet(StringComparer.Ordinal); foreach (var name in options.CustomFields) { - customFields[name] = true; + customFields.Add(name); } this.customFields = customFields; @@ -323,7 +323,7 @@ internal void SerializeLogRecord(LogRecord logRecord) bodyPopulated = true; continue; } - else if (this.customFields == null || this.customFields.ContainsKey(entry.Key)) + else if (this.customFields == null || this.customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. if (entry.Value != null) @@ -513,7 +513,7 @@ private static string GetSanitizedCategoryName(string categoryName) continue; } - if (customFields == null || customFields.ContainsKey(scopeItem.Key)) + if (customFields == null || customFields.Contains(scopeItem.Key)) { if (scopeItem.Value != null) { diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index c9ae119f69..b5967affd7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -41,7 +41,7 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable private readonly string partAName = "Span"; private readonly byte partAFieldsCount = 3; // At least three fields: time, ext_dt_traceId, ext_dt_spanId - private readonly Dictionary m_customFields; + private readonly HashSet m_customFields; private readonly Tuple repeatedPartAFields; private readonly EventProvider eventProvider; @@ -65,18 +65,19 @@ public TldTraceExporter(GenevaExporterOptions options) // TODO: Validate custom fields (reserved name? etc). if (options.CustomFields != null) { - var customFields = new Dictionary(StringComparer.Ordinal); + var customFields = new HashSet(StringComparer.Ordinal); // Seed customFields with Span PartB - customFields["azureResourceProvider"] = true; + customFields.Add("azureResourceProvider"); + foreach (var name in CS40_PART_B_MAPPING.Values) { - customFields[name] = true; + customFields.Add(name); } foreach (var name in options.CustomFields) { - customFields[name] = true; + customFields.Add(name); } this.m_customFields = customFields; @@ -268,7 +269,7 @@ internal void SerializeActivity(Activity activity) statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } - else if (this.m_customFields == null || this.m_customFields.ContainsKey(entry.Key)) + else if (this.m_customFields == null || this.m_customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. kvpArrayForPartCFields[partCFieldsCountFromTags] = new(entry.Key, entry.Value); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 8cdaa67dfb..50604e777e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -239,7 +239,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, } using var exporter = new MsgPackTraceExporter(exporterOptions); - var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as IReadOnlyDictionary; + var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as HashSet; var CS40_PART_B_MAPPING = typeof(MsgPackTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; var m_buffer = typeof(MsgPackTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; @@ -563,7 +563,7 @@ private static string GetTestMethodName([CallerMemberName] string callingMethodN return callingMethodName; } - private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, IReadOnlyDictionary dedicatedFields, Action> customChecksForActivity) + private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, HashSet dedicatedFields, Action> customChecksForActivity) { /* Fluentd Forward Mode: [ @@ -697,8 +697,8 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO } else { - // If CustomFields are proivded, dedicatedFields will be populated - if (exporterOptions.CustomFields == null || dedicatedFields.TryGetValue(tag.Key, out _)) + // If CustomFields are provided, dedicatedFields will be populated + if (exporterOptions.CustomFields == null || dedicatedFields.Contains(tag.Key)) { Assert.Equal(tag.Value.ToString(), mapping[tag.Key].ToString()); } From b9abf08e244d1c233e05db35fface7dc278c6984 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Tue, 19 Dec 2023 21:11:30 +0200 Subject: [PATCH 0923/1499] Hangfire: Downgrade OpenTelemetry.Api.ProviderBuilderExtensions to 1.6.0 to avoid MS.Extensions.* v8 dependencies (#1502) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 6 +++--- .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 432396546e..5fbd109eed 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,9 +2,9 @@ ## Unreleased -* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.7.0`. - * Update `OpenTelemetry.Api` to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.6.0`. + * Update `OpenTelemetry.Api` to `1.6.0`. + ([#1502](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1502)) * Added overloads which accept a name to the `TracerProviderBuilder` `HangfireInstrumentationOptions` extension to allow for more fine-grained diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index e38c79a9ab..e6407f03f7 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -9,7 +9,7 @@ - + From c558c1736613d59aa3e76900b9bcdb09dc04bbe4 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Wed, 20 Dec 2023 07:20:53 +0200 Subject: [PATCH 0924/1499] Release OpenTelemetry.Instrumentation.Hangfire 1.6.0-beta.1 (#1503) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 5fbd109eed..a83398b952 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.6.0-beta.1 + +Released 2023-Dec-20 + * Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.6.0`. * Update `OpenTelemetry.Api` to `1.6.0`. ([#1502](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1502)) From 856177945f5f278a1aec14ea47f48652f5fc8508 Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Wed, 20 Dec 2023 09:54:25 +0200 Subject: [PATCH 0925/1499] Hangfire - Upgrade OTel to 1.7.0 (#1508) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index a83398b952..204bb8bc26 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.7.0`. + * Update `OpenTelemetry.Api` to `1.7.0`. + ([#1508](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1508)) + ## 1.6.0-beta.1 Released 2023-Dec-20 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index e6407f03f7..e38c79a9ab 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -9,7 +9,7 @@ - + From 9efa51738fc78e0025d53b8e3a02e1c64516d66f Mon Sep 17 00:00:00 2001 From: Zack Richardson Date: Wed, 20 Dec 2023 00:56:19 -0800 Subject: [PATCH 0926/1499] [Instrumentation.AspNet] Update CHANGELOG for 1.7.0-beta.1 release (#1505) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index b97a02b1ea..ef49bd4e4c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0-beta.1 + +Released 2023-Dec-20 + * Update `OpenTelemetry.Api` to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 72f35abe2b..f58e6394ad 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0-beta.1 + +Released 2023-Dec-20 + * Added enrich functionality to metric instrumentation ([#1407](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1407)). From dda7b8285b7db317715af3cac1de89f3e8c91e2b Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 20 Dec 2023 08:17:20 -0800 Subject: [PATCH 0927/1499] [Exporter.Geneva] Perf improvement on .NET 8 (#1504) Co-authored-by: Cijo Thomas --- .../MsgPackExporter/MsgPackExporter.cs | 11 +++++++- .../MsgPackExporter/MsgPackLogExporter.cs | 18 +++++++++++++ .../MsgPackExporter/MsgPackTraceExporter.cs | 25 ++++++++++++++++++- .../GenevaTraceExporterTests.cs | 11 +++++++- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs index 191e26b200..581a07dcd3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs @@ -2,13 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif using System.Collections.Generic; namespace OpenTelemetry.Exporter.Geneva; internal abstract class MsgPackExporter { - internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = new Dictionary + internal static readonly IReadOnlyDictionary PART_A_MAPPING_DICTIONARY = new Dictionary { // Part A [Schema.V40.PartA.IKey] = "env_iKey", @@ -30,6 +33,12 @@ internal abstract class MsgPackExporter [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", }; +#if NET8_0_OR_GREATER + internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = PART_A_MAPPING_DICTIONARY.ToFrozenDictionary(); +#else + internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = PART_A_MAPPING_DICTIONARY; +#endif + protected static int AddPartAField(byte[] buffer, int cursor, string name, object value) { if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index e4ba33044a..07d54e7355 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; @@ -25,8 +28,15 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private readonly bool m_shouldExportEventName; private readonly TableNameSerializer m_tableNameSerializer; + +#if NET8_0_OR_GREATER + private readonly FrozenSet m_customFields; + private readonly FrozenDictionary m_prepopulatedFields; +#else private readonly HashSet m_customFields; private readonly Dictionary m_prepopulatedFields; +#endif + private readonly ExceptionStackExportMode m_exportExceptionStack; private readonly List m_prepopulatedFieldKeys; private readonly byte[] m_bufferEpilogue; @@ -77,7 +87,11 @@ public MsgPackLogExporter(GenevaExporterOptions options) this.m_prepopulatedFieldKeys.Add(kv.Key); } +#if NET8_0_OR_GREATER + this.m_prepopulatedFields = tempPrepopulatedFields.ToFrozenDictionary(StringComparer.Ordinal); +#else this.m_prepopulatedFields = tempPrepopulatedFields; +#endif } // TODO: Validate custom fields (reserved name? etc). @@ -89,7 +103,11 @@ public MsgPackLogExporter(GenevaExporterOptions options) customFields.Add(name); } +#if NET8_0_OR_GREATER + this.m_customFields = customFields.ToFrozenSet(StringComparer.Ordinal); +#else this.m_customFields = customFields; +#endif } var buffer = new byte[BUFFER_SIZE]; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 18432bc13b..5a429e39c4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -67,7 +70,11 @@ public MsgPackTraceExporter(GenevaExporterOptions options) dedicatedFields.Add(name); } +#if NET8_0_OR_GREATER + this.m_customFields = customFields.ToFrozenSet(StringComparer.Ordinal); +#else this.m_customFields = customFields; +#endif foreach (var name in CS40_PART_B_MAPPING.Keys) { @@ -77,7 +84,11 @@ public MsgPackTraceExporter(GenevaExporterOptions options) dedicatedFields.Add("otel.status_code"); dedicatedFields.Add("otel.status_description"); +#if NET8_0_OR_GREATER + this.m_dedicatedFields = dedicatedFields.ToFrozenSet(StringComparer.Ordinal); +#else this.m_dedicatedFields = dedicatedFields; +#endif } var buffer = new byte[BUFFER_SIZE]; @@ -392,7 +403,7 @@ public void Dispose() private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - private static readonly Dictionary CS40_PART_B_MAPPING = new Dictionary + private static readonly Dictionary CS40_PART_B_MAPPING_DICTIONARY = new() { ["db.system"] = "dbSystem", ["db.name"] = "dbName", @@ -410,6 +421,12 @@ public void Dispose() ["messaging.url"] = "messagingUrl", }; +#if NET8_0_OR_GREATER + private static readonly FrozenDictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY.ToFrozenDictionary(); +#else + private static readonly Dictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY; +#endif + private readonly ThreadLocal m_buffer = new(() => null); private readonly byte[] m_bufferPrologue; @@ -424,9 +441,15 @@ public void Dispose() private readonly IDataTransport m_dataTransport; +#if NET8_0_OR_GREATER + private readonly FrozenSet m_customFields; + + private readonly FrozenSet m_dedicatedFields; +#else private readonly HashSet m_customFields; private readonly HashSet m_dedicatedFields; +#endif private bool isDisposed; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 50604e777e..5b2cd4a528 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -239,7 +242,11 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, } using var exporter = new MsgPackTraceExporter(exporterOptions); +#if NET8_0_OR_GREATER + var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as FrozenSet; +#else var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as HashSet; +#endif var CS40_PART_B_MAPPING = typeof(MsgPackTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; var m_buffer = typeof(MsgPackTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; @@ -563,7 +570,9 @@ private static string GetTestMethodName([CallerMemberName] string callingMethodN return callingMethodName; } - private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, HashSet dedicatedFields, Action> customChecksForActivity) +#pragma warning disable CA1859 // Use concrete types when possible for improved performance + private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterOptions, object fluentdData, Activity activity, IReadOnlyDictionary CS40_PART_B_MAPPING, ISet dedicatedFields, Action> customChecksForActivity) +#pragma warning restore CA1859 // Use concrete types when possible for improved performance { /* Fluentd Forward Mode: [ From d971004afd9b65f00e12a945472bd5a1e3642792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 21 Dec 2023 06:31:10 +0100 Subject: [PATCH 0928/1499] ResourceDetectors - Process (#1506) --- .../comp_resourcedetectors_process.md | 41 ++++++++++++++++++ .github/codecov.yml | 5 +++ .github/component_owners.yml | 6 +++ .github/workflows/ci.yml | 22 +++++++++- .../package-ResourceDetectors.Process.yml | 21 +++++++++ ...enTelemetry.ResourceDetectors.Process.proj | 32 ++++++++++++++ opentelemetry-dotnet-contrib.sln | 16 +++++++ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 ++ .../AssemblyInfo.cs | 10 +++++ .../CHANGELOG.md | 6 +++ ...Telemetry.ResourceDetectors.Process.csproj | 12 ++++++ .../ProcessDetector.cs | 32 ++++++++++++++ .../ProcessSemanticConventions.cs | 9 ++++ .../README.md | 43 +++++++++++++++++++ .../ProcessRuntimeDetector.cs | 2 +- .../README.md | 4 ++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + ...try.ResourceDetectors.Process.Tests.csproj | 14 ++++++ .../ProcessDetectorTests.cs | 23 ++++++++++ 22 files changed, 304 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md create mode 100644 .github/workflows/package-ResourceDetectors.Process.yml create mode 100644 build/Projects/OpenTelemetry.ResourceDetectors.Process.proj create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Process/README.md create mode 100644 test/OpenTelemetry.ResourceDetectors.Process.Tests/OpenTelemetry.ResourceDetectors.Process.Tests.csproj create mode 100644 test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md new file mode 100644 index 0000000000..b085c90e45 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.ResourceDetectors.Process +about: OpenTelemetry.ResourceDetectors.Process +labels: comp:resourcedetectors.process +--- + +# Issue with OpenTelemetry.ResourceDetectors.Process + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 28e08db161..9e592ee5fe 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -99,6 +99,11 @@ flags: paths: - src/OpenTelemetry.ResourceDetectors.Azure + unittests-ResourceDetectors.Process: + carryforward: true + paths: + - src/OpenTelemetry.ResourceDetectors.Process + unittests-ResourceDetectors.ProcessRuntime: carryforward: true paths: diff --git a/.github/component_owners.yml b/.github/component_owners.yml index ba09d34efb..0477e2a34d 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -65,6 +65,9 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev + src/OpenTelemetry.ResourceDetectors.Process/: + - Kielek + - lachmatt src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: - Kielek - lachmatt @@ -144,6 +147,9 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev + test/OpenTelemetry.ResourceDetectors.Process.Tests/: + - Kielek + - lachmatt test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: - Kielek - lachmatt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67e3c9a685..58b0d167e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,8 @@ jobs: owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] - processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', '!**/*.md'] + processdetector: ['*/OpenTelemetry.ResourceDetectors.Process/**', '*/OpenTelemetry.ResourceDetectors.Process.Tests/**', '!**/*.md'] + processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', '*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] @@ -43,7 +44,10 @@ jobs: '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', - '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime*/**', + '!*/OpenTelemetry.ResourceDetectors.Process/**', + '!*/OpenTelemetry.ResourceDetectors.Process.Tests/**', + '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', + '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions/**', @@ -178,6 +182,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Process code-cov-name: Instrumentation.Process + build-test-processdetector: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'processdetector') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.ResourceDetectors.Process + code-cov-name: ResourceDetectors.Process + build-test-processruntime: needs: detect-changes if: | @@ -272,6 +287,7 @@ jobs: OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, + OpenTelemetry.ResourceDetectors.Process.Tests.csproj, OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj $failedProjects = @() @@ -314,6 +330,7 @@ jobs: contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') || contains(needs.detect-changes.outputs.changes, 'azure') + || contains(needs.detect-changes.outputs.changes, 'processdetector') || contains(needs.detect-changes.outputs.changes, 'processruntime') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') @@ -336,6 +353,7 @@ jobs: build-test-owin, build-test-persistentstorage, build-test-process, + build-test-processdetector, build-test-processruntime, build-test-redis, build-test-redis-integration, diff --git a/.github/workflows/package-ResourceDetectors.Process.yml b/.github/workflows/package-ResourceDetectors.Process.yml new file mode 100644 index 0000000000..874054383d --- /dev/null +++ b/.github/workflows/package-ResourceDetectors.Process.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.ResourceDetectors.Process + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'ResourceDetectors.Process-*' # trigger when we create a tag with prefix "ResourceDetectors.Process-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.ResourceDetectors.Process + secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Process.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Process.proj new file mode 100644 index 0000000000..032a74930c --- /dev/null +++ b/build/Projects/OpenTelemetry.ResourceDetectors.Process.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 1c749e3975..807e8f14d4 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -67,6 +67,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-ResourceDetectors.AWS.yml = .github\workflows\package-ResourceDetectors.AWS.yml .github\workflows\package-ResourceDetectors.Azure.yml = .github\workflows\package-ResourceDetectors.Azure.yml .github\workflows\package-ResourceDetectors.Container.yml = .github\workflows\package-ResourceDetectors.Container.yml + .github\workflows\package-ResourceDetectors.Process.yml = .github\workflows\package-ResourceDetectors.Process.yml .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml @@ -322,6 +323,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj + build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj EndProjectSection EndProject @@ -329,6 +331,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests", "test\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Process", "src\OpenTelemetry.ResourceDetectors.Process\OpenTelemetry.ResourceDetectors.Process.csproj", "{A5FCDD8F-20FF-4657-804E-707EAD4FE31D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Process.Tests", "test\OpenTelemetry.ResourceDetectors.Process.Tests\OpenTelemetry.ResourceDetectors.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -655,6 +661,14 @@ Global {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.Build.0 = Release|Any CPU + {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Release|Any CPU.Build.0 = Release|Any CPU + {A5EF701C-439E-407F-8BB4-394166000C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5EF701C-439E-407F-8BB4-394166000C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -753,6 +767,8 @@ Global {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..536c6eae3b --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Process.ProcessDetector +OpenTelemetry.ResourceDetectors.Process.ProcessDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Process.ProcessDetector.ProcessDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..536c6eae3b --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Process.ProcessDetector +OpenTelemetry.ResourceDetectors.Process.ProcessDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Process.ProcessDetector.ProcessDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs new file mode 100644 index 0000000000..221b668c6c --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Process.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Process.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md new file mode 100644 index 0000000000..72ccecd211 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## Unreleased + +* Initial release of `OpenTelemetry.ResourceDetectors.Process` project +[1506](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1506) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj b/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj new file mode 100644 index 0000000000..f0a4b7beda --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj @@ -0,0 +1,12 @@ + + + + net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Extensions - Process Resource Detector. + ResourceDetectors.Process- + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs b/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs new file mode 100644 index 0000000000..1fc900576f --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System; +#endif +using System.Collections.Generic; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.ResourceDetectors.Process; + +/// +/// Process detector. +/// +public sealed class ProcessDetector : IResourceDetector +{ + /// + /// Detects the resource attributes for process. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + return new Resource(new List>(1) + { +#if NET6_0_OR_GREATER + new(ProcessSemanticConventions.AttributeProcessPid, Environment.ProcessId), +#else + new(ProcessSemanticConventions.AttributeProcessPid, System.Diagnostics.Process.GetCurrentProcess().Id), +#endif + }); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs new file mode 100644 index 0000000000..26ff48b894 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs @@ -0,0 +1,9 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.ResourceDetectors.Process; + +internal static class ProcessSemanticConventions +{ + public const string AttributeProcessPid = "process.pid"; +} diff --git a/src/OpenTelemetry.ResourceDetectors.Process/README.md b/src/OpenTelemetry.ResourceDetectors.Process/README.md new file mode 100644 index 0000000000..d191c6732e --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Process/README.md @@ -0,0 +1,43 @@ +# Process Resource Detectors + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Process)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Process) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Process)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Process) + +> [!IMPORTANT] +> Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/process.md#process). +> These resources can be changed without prior notification. + +## Getting Started + +You need to install the +`OpenTelemetry.ResourceDetectors.Process` package to be able to use the +Process Runtime Resource Detectors. + +```shell +dotnet add package OpenTelemetry.ResourceDetectors.Process --prerelease +``` + +## Usage + +You can configure Process Runtime resource detector to +the `TracerProvider` with the following example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.Process; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .ConfigureResource(resource => resource + .AddDetector(new ProcessDetector())) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **ProcessDetector**: `process.pid`. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs index 38cfb3315e..bef33a9fc5 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/ProcessRuntimeDetector.cs @@ -16,7 +16,7 @@ namespace OpenTelemetry.ResourceDetectors.ProcessRuntime; /// /// Process runtime detector. /// -public class ProcessRuntimeDetector : IResourceDetector +public sealed class ProcessRuntimeDetector : IResourceDetector { /// /// Detects the resource attributes from .NET runtime. diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md index 7d0027b42c..6a5d589413 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/README.md @@ -3,6 +3,10 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.ProcessRuntime) +> [!IMPORTANT] +> Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/process.md#process-runtimes). +> These resources can be changed without prior notification. + ## Getting Started You need to install the diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 56e661f052..9381dad406 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -17,6 +17,7 @@ + diff --git a/test/OpenTelemetry.ResourceDetectors.Process.Tests/OpenTelemetry.ResourceDetectors.Process.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Process.Tests/OpenTelemetry.ResourceDetectors.Process.Tests.csproj new file mode 100644 index 0000000000..06565fd592 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Process.Tests/OpenTelemetry.ResourceDetectors.Process.Tests.csproj @@ -0,0 +1,14 @@ + + + + Unit test project for Process Detector for OpenTelemetry + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + diff --git a/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs new file mode 100644 index 0000000000..98c3ade236 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Linq; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.ResourceDetectors.Process.Tests; + +public class ProcessDetectorTests +{ + [Fact] + public void TestProcessAttributes() + { + var resource = ResourceBuilder.CreateEmpty().AddDetector(new ProcessDetector()).Build(); + + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); + + Assert.Single(resourceAttributes); + + Assert.IsType(resourceAttributes[ProcessSemanticConventions.AttributeProcessPid]); + } +} From a6ef05ad305bc83c4f576e2952d688fa68041df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 21 Dec 2023 06:59:01 +0100 Subject: [PATCH 0929/1499] ResourceDetectors - Host (#1507) --- .../comp_resourcedetectors_host.md | 41 ++++++++++++++++++ .github/codecov.yml | 5 +++ .github/component_owners.yml | 6 +++ .github/workflows/ci.yml | 16 +++++++ .../package-ResourceDetectors.Host.yml | 21 +++++++++ .../OpenTelemetry.ResourceDetectors.Host.proj | 32 ++++++++++++++ opentelemetry-dotnet-contrib.sln | 16 +++++++ .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 3 ++ .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 ++ .../AssemblyInfo.cs | 10 +++++ .../CHANGELOG.md | 6 +++ .../HostDetector.cs | 35 +++++++++++++++ .../HostSemanticConventions.cs | 9 ++++ ...penTelemetry.ResourceDetectors.Host.csproj | 12 ++++++ .../README.md | 43 +++++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + .../HostDetectorTests.cs | 23 ++++++++++ ...emetry.ResourceDetectors.Host.Tests.csproj | 14 ++++++ 20 files changed, 298 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md create mode 100644 .github/workflows/package-ResourceDetectors.Host.yml create mode 100644 build/Projects/OpenTelemetry.ResourceDetectors.Host.proj create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/README.md create mode 100644 test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs create mode 100644 test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md new file mode 100644 index 0000000000..757b18890a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.ResourceDetectors.Host +about: OpenTelemetry.ResourceDetectors.Host +labels: comp:resourcedetectors.host +--- + +# Issue with OpenTelemetry.ResourceDetectors.Host + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 9e592ee5fe..74701f6a61 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -99,6 +99,11 @@ flags: paths: - src/OpenTelemetry.ResourceDetectors.Azure + unittests-ResourceDetectors.Host: + carryforward: true + paths: + - src/OpenTelemetry.ResourceDetectors.Host + unittests-ResourceDetectors.Process: carryforward: true paths: diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 0477e2a34d..8dc58d03f2 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -65,6 +65,9 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev + src/OpenTelemetry.ResourceDetectors.Host/: + - Kielek + - lachmatt src/OpenTelemetry.ResourceDetectors.Process/: - Kielek - lachmatt @@ -147,6 +150,9 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev + test/OpenTelemetry.ResourceDetectors.Host.Tests/: + - Kielek + - lachmatt test/OpenTelemetry.ResourceDetectors.Process.Tests/: - Kielek - lachmatt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58b0d167e8..813abdb5a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,6 +27,7 @@ jobs: eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] + host: ['*/OpenTelemetry.ResourceDetectors.Host*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] @@ -44,6 +45,7 @@ jobs: '!*/OpenTelemetry.Instrumentation.AspNet*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', + '!*/OpenTelemetry.ResourceDetectors.Host*/**', '!*/OpenTelemetry.ResourceDetectors.Process/**', '!*/OpenTelemetry.ResourceDetectors.Process.Tests/**', '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', @@ -136,6 +138,17 @@ jobs: project-name: OpenTelemetry.Exporter.Geneva code-cov-name: Exporter.Geneva + build-test-host: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'host') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.ResourceDetectors.Host + code-cov-name: ResourceDetectors.Host + build-test-onecollector: needs: detect-changes if: | @@ -287,6 +300,7 @@ jobs: OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, + OpenTelemetry.ResourceDetectors.Host.Tests.csproj, OpenTelemetry.ResourceDetectors.Process.Tests.csproj, OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj @@ -330,6 +344,7 @@ jobs: contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') || contains(needs.detect-changes.outputs.changes, 'azure') + || contains(needs.detect-changes.outputs.changes, 'host') || contains(needs.detect-changes.outputs.changes, 'processdetector') || contains(needs.detect-changes.outputs.changes, 'processruntime') || contains(needs.detect-changes.outputs.changes, 'aottestapp') @@ -349,6 +364,7 @@ jobs: build-test-eventcounters, build-test-extensions, build-test-geneva, + build-test-host, build-test-onecollector, build-test-owin, build-test-persistentstorage, diff --git a/.github/workflows/package-ResourceDetectors.Host.yml b/.github/workflows/package-ResourceDetectors.Host.yml new file mode 100644 index 0000000000..92ddd4905a --- /dev/null +++ b/.github/workflows/package-ResourceDetectors.Host.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.ResourceDetectors.Host + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'ResourceDetectors.Host-*' # trigger when we create a tag with prefix "ResourceDetectors.Host-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.ResourceDetectors.Host + secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj new file mode 100644 index 0000000000..b3e56c12b0 --- /dev/null +++ b/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 807e8f14d4..09fac45779 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -67,6 +67,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-ResourceDetectors.AWS.yml = .github\workflows\package-ResourceDetectors.AWS.yml .github\workflows\package-ResourceDetectors.Azure.yml = .github\workflows\package-ResourceDetectors.Azure.yml .github\workflows\package-ResourceDetectors.Container.yml = .github\workflows\package-ResourceDetectors.Container.yml + .github\workflows\package-ResourceDetectors.Host.yml = .github\workflows\package-ResourceDetectors.Host.yml .github\workflows\package-ResourceDetectors.Process.yml = .github\workflows\package-ResourceDetectors.Process.yml .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml @@ -323,6 +324,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj + build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj EndProjectSection @@ -335,6 +337,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Process.Tests", "test\OpenTelemetry.ResourceDetectors.Process.Tests\OpenTelemetry.ResourceDetectors.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host", "src\OpenTelemetry.ResourceDetectors.Host\OpenTelemetry.ResourceDetectors.Host.csproj", "{033CA8D4-1529-413A-B244-07958D5F9A48}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host.Tests", "test\OpenTelemetry.ResourceDetectors.Host.Tests\OpenTelemetry.ResourceDetectors.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -669,6 +675,14 @@ Global {A5EF701C-439E-407F-8BB4-394166000C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.Build.0 = Release|Any CPU + {033CA8D4-1529-413A-B244-07958D5F9A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {033CA8D4-1529-413A-B244-07958D5F9A48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {033CA8D4-1529-413A-B244-07958D5F9A48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {033CA8D4-1529-413A-B244-07958D5F9A48}.Release|Any CPU.Build.0 = Release|Any CPU + {36271347-2055-438E-9659-B71542A17A73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36271347-2055-438E-9659-B71542A17A73}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36271347-2055-438E-9659-B71542A17A73}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36271347-2055-438E-9659-B71542A17A73}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -769,6 +783,8 @@ Global {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..ab46f0419f --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Host.HostDetector +OpenTelemetry.ResourceDetectors.Host.HostDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Host.HostDetector.HostDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..ab46f0419f --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.ResourceDetectors.Host.HostDetector +OpenTelemetry.ResourceDetectors.Host.HostDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Host.HostDetector.HostDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs new file mode 100644 index 0000000000..d290537dd9 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Host.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Host.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md new file mode 100644 index 0000000000..138dbd9e89 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +## Unreleased + +* Initial release of `OpenTelemetry.ResourceDetectors.Host` project +[1507](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1507) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs b/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs new file mode 100644 index 0000000000..1f6f38a508 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs @@ -0,0 +1,35 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.ResourceDetectors.Host; + +/// +/// Host detector. +/// +public sealed class HostDetector : IResourceDetector +{ + /// + /// Detects the resource attributes from host. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + try + { + return new Resource(new List>(1) + { + new(HostSemanticConventions.AttributeHostName, Environment.MachineName), + }); + } + catch (InvalidOperationException) + { + // TODO replace comment by logging mechanism. Tracked under https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1514 + } + + return Resource.Empty; + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs new file mode 100644 index 0000000000..18b2d01023 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs @@ -0,0 +1,9 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.ResourceDetectors.Host; + +internal static class HostSemanticConventions +{ + public const string AttributeHostName = "host.name"; +} diff --git a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj new file mode 100644 index 0000000000..0b695e722a --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj @@ -0,0 +1,12 @@ + + + + net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Extensions - Host Resource Detector. + ResourceDetectors.Host- + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.Host/README.md b/src/OpenTelemetry.ResourceDetectors.Host/README.md new file mode 100644 index 0000000000..f0eabc6496 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/README.md @@ -0,0 +1,43 @@ +# Host Resource Detectors + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Host)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Host) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Host)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Host) + +> [!IMPORTANT] +> Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/host.md). +> These resources can be changed without prior notification. + +## Getting Started + +You need to install the +`OpenTelemetry.ResourceDetectors.Host` package to be able to use the +Host Resource Detectors. + +```shell +dotnet add package OpenTelemetry.ResourceDetectors.Host --prerelease +``` + +## Usage + +You can configure Host resource detector to +the `TracerProvider` with the following example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.Host; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .ConfigureResource(resource => resource + .AddDetector(new HostDetector())) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **HostDetector**: `host.name`. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 9381dad406..f2e95fd1b0 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -17,6 +17,7 @@ + diff --git a/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs new file mode 100644 index 0000000000..e6e494f6ab --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Linq; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.ResourceDetectors.Host.Tests; + +public class HostDetectorTests +{ + [Fact] + public void TestHostAttributes() + { + var resource = ResourceBuilder.CreateEmpty().AddDetector(new HostDetector()).Build(); + + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + + Assert.Single(resourceAttributes); + + Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostName]); + } +} diff --git a/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj new file mode 100644 index 0000000000..23db48b06d --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj @@ -0,0 +1,14 @@ + + + + Unit test project for Host Detector for OpenTelemetry + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + From d51542c137391aabe378301d270fc20643fcc35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Thu, 21 Dec 2023 07:44:34 +0100 Subject: [PATCH 0930/1499] [detectors] host and process detectors 0.1.0-alpha.1 release (#1517) --- src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index 138dbd9e89..d88d40043b 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -2,5 +2,9 @@ ## Unreleased +## 0.1.0-alpha.1 + +Released 2023-Dec-21 + * Initial release of `OpenTelemetry.ResourceDetectors.Host` project [1507](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1507) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index 72ccecd211..b2c6600d36 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -2,5 +2,9 @@ ## Unreleased +## 0.1.0-alpha.1 + +Released 2023-Dec-21 + * Initial release of `OpenTelemetry.ResourceDetectors.Process` project [1506](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1506) From 6bb57e25b284ed500981a91afa6156c8ed0fa4d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 21 Dec 2023 19:27:54 +0100 Subject: [PATCH 0931/1499] Bump OTel to 1.7.0 for ResourceDetectors Host and Process (#1518) --- src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md | 5 ++++- .../OpenTelemetry.ResourceDetectors.Host.csproj | 2 +- src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 5 ++++- .../OpenTelemetry.ResourceDetectors.Process.csproj | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index d88d40043b..3d7707398e 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -2,9 +2,12 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1518](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1518)) + ## 0.1.0-alpha.1 Released 2023-Dec-21 * Initial release of `OpenTelemetry.ResourceDetectors.Host` project -[1507](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1507) + [1507](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1507) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj index 0b695e722a..c17b08a57e 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj @@ -7,6 +7,6 @@ ResourceDetectors.Host- - + diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index b2c6600d36..7a58255ffc 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -2,9 +2,12 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.7.0`. + ([#1518](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1518)) + ## 0.1.0-alpha.1 Released 2023-Dec-21 * Initial release of `OpenTelemetry.ResourceDetectors.Process` project -[1506](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1506) + [1506](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1506) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj b/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj index f0a4b7beda..3de24bbdee 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj @@ -7,6 +7,6 @@ ResourceDetectors.Process- - + From 53d73f47dbae0bc8f25e1df93f5e52808ad3e766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20T=C3=B3foli?= Date: Tue, 2 Jan 2024 06:10:00 -0300 Subject: [PATCH 0932/1499] [Instrumentation.AWSLambda] Complements documentation about DisableAwsXRayContextExtraction property. (#1512) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Neumüller --- src/OpenTelemetry.Instrumentation.AWSLambda/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index cf72816a6a..0d131fd109 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -40,6 +40,13 @@ parameter is optional and used to pass a custom parent context. If the parent is not passed explicitly then it's either extracted from the input parameter or uses AWS X-Ray headers if AWS X-Ray context extraction is enabled (see configuration property `DisableAwsXRayContextExtraction`). + +> **Note** +> If tracing is required when AWS X-Ray is disabled, +> the `DisableAwsXRayContextExtraction` property needs to be set to `true`. +> This will instruct the instrumentation to ignore the "not sampled" +> trace header automatically sent when AWS X-Ray is disabled. + The sequence of the parent extraction: `explicit parent` -> `parent from input parameter` -> `AWS X-Ray headers` -> `default` The parent extraction is supported for the input types listed in the table below: From db0aa3d60f9552e204cfefb10f4462f04ffe0ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 3 Jan 2024 19:44:06 +0100 Subject: [PATCH 0933/1499] Releases with OTel 1.7.0 (#1522) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ 11 files changed, 44 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index c4b3f7c62d..77d8c86da5 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.9 + +Released 2024-Jan-03 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index d315d69808..4c0323672c 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.5.0-beta.4 + +Released 2024-Jan-03 + * Update `OpenTelemetry.Api` to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index a520c719c8..4a0c7d3953 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.1 + +Released 2024-Jan-03 + * Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource being created ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index b541c75950..764a282f86 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0 + +Released 2024-Jan-03 + * Update `OpenTelemetry.Api` to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index d452bbc308..bafdd8ea82 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.13 + +Released 2024-Jan-03 + * Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 1bce6c18eb..fd874bca39 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.14 + +Released 2024-Jan-03 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index f0642f5d18..9959deb5fb 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.4 + +Released 2024-Jan-03 + * Added NET6 target framework to support Trimming. ([#1405](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1405)) * Update OpenTelemetry SDK version to `1.7.0`. diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 993cf0424a..8ab1829c4a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2024-Jan-03 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index 3d7707398e..8df506a5ae 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.2 + +Released 2024-Jan-03 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1518](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1518)) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index 7a58255ffc..c67f34e3af 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.2 + +Released 2024-Jan-03 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1518](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1518)) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md index 221c846b0b..6d5a78c1e5 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.2 + +Released 2024-Jan-03 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) From 4743db9cd30721d57e771eecb6ae2e269bff8cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 Jan 2024 18:15:36 +0100 Subject: [PATCH 0934/1499] [repo] Sync .editorconfig with main repository (#1525) --- .editorconfig | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index 1d890883f0..f5e1e40677 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,6 +13,12 @@ trim_trailing_whitespace = true [*.{cs,cshtml,htm,html,md,py,sln,xml}] indent_size = 4 +############################### +# Copyright header # +############################### +[*.cs] +file_header_template = Copyright The OpenTelemetry Authors\nSPDX-License-Identifier: Apache-2.0 + ############################### # .NET Coding Conventions # ############################### @@ -34,7 +40,7 @@ csharp_indent_switch_labels = true csharp_indent_labels = flush_left # Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion +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 # this. preferences @@ -106,6 +112,7 @@ csharp_style_prefer_index_operator = false:none 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 # Space preferences csharp_space_after_cast = false @@ -141,7 +148,9 @@ dotnet_diagnostic.IDE0002.severity = warning # IDE0005: Remove unnecessary import dotnet_diagnostic.IDE0005.severity = warning -csharp_style_namespace_declarations = file_scoped:warning + +# RS0041: Public members should not use oblivious types +dotnet_diagnostic.RS0041.severity = suggestion [obj/**.cs] [**/External/**.cs] @@ -149,3 +158,6 @@ generated_code = true [*.csproj] indent_size = 2 + +[*.cshtml.cs] +dotnet_diagnostic.SA1649.severity = none From 3cf5dbfb5fc385fdc0599354b6cd1195fb4da077 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 12 Jan 2024 04:39:46 +0100 Subject: [PATCH 0935/1499] Documentation - use new markdown syntax for Notes (#1521) --- examples/wcf/README.md | 2 +- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- src/OpenTelemetry.Extensions.Enrichment/README.md | 2 +- .../README.md | 2 +- .../README.md | 2 +- src/OpenTelemetry.Instrumentation.AspNet/README.md | 2 +- .../README.md | 3 ++- .../README.md | 5 +++-- .../CHANGELOG.md | 2 +- .../README.md | 3 ++- .../README.md | 14 +++++++------- .../README.md | 2 +- 12 files changed, 22 insertions(+), 19 deletions(-) diff --git a/examples/wcf/README.md b/examples/wcf/README.md index c496b5d3a2..d7a76af748 100644 --- a/examples/wcf/README.md +++ b/examples/wcf/README.md @@ -20,7 +20,7 @@ Project structure: admin privileges. For details see: [Configuring HTTP and HTTPS](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/configuring-http-and-https). - > **Note** +> [!NOTE] > There is no .NET Core server example because only the client libraries for WCF are available on .NET Core / .NET 5. diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index f5e1417b80..1f5d673963 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -113,7 +113,7 @@ The default table name used for Traces is `Span`. To change the table name for Traces add an entry with the key `Span` and set the value to the desired custom table name. -> **Note** +> [!NOTE] > Only a single table name is supported for Traces. ##### Log table name mappings diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index 17a7a77719..0dd4a266e5 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -102,7 +102,7 @@ public void ConfigureServices(IServiceCollection services) } ``` -> **Note** +> [!NOTE] > The `AddTraceEnricher()` method call should be done *before* registering exporter related Activity processors. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index 0d131fd109..dd9ab32d5e 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -41,7 +41,7 @@ is not passed explicitly then it's either extracted from the input parameter or uses AWS X-Ray headers if AWS X-Ray context extraction is enabled (see configuration property `DisableAwsXRayContextExtraction`). -> **Note** +> [!NOTE] > If tracing is required when AWS X-Ray is disabled, > the `DisableAwsXRayContextExtraction` property needs to be set to `true`. > This will instruct the instrumentation to ignore the "not sampled" diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index 9de87bd45c..2d64278ddf 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -120,7 +120,7 @@ TelemetryHttpModuleOptions.TextMapPropagator = new CompositeTextMapPropagator( }); ``` -> **Note** +> [!NOTE] > When using the `OpenTelemetry.Instrumentation.AspNet` `TelemetryHttpModuleOptions.TextMapPropagator` is automatically initialized to the SDK default propagator (`Propagators.DefaultTextMapPropagator`) which by diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 7bae983e19..7bac6bba39 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -8,7 +8,7 @@ Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main which instruments [ASP.NET](https://docs.microsoft.com/aspnet/overview) and collect metrics and traces about incoming web requests. -> **Note** +> [!NOTE] > This component is based on the OpenTelemetry semantic conventions for [metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) and diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md index b46e315a88..2183728485 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -9,7 +9,8 @@ events emitted by [MassTransit](https://masstransit-project.com/) library. ## Deprecated -> **NOTE that this only works with MassTransit v7 (and earlier, where supported)**. +> [!IMPORTANT] +> **This only works with MassTransit v7 (and earlier, where supported)**. > MassTransit v8.0.0 and later have built-in direct support for Open Telemetry > via `ActivitySource`. diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index d7f45e09f8..6671c3ba39 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -10,7 +10,8 @@ and collects telemetry about database operations. ## Deprecated -> **NOTE that this only works with Mysql.Data v8.0.32 (and earlier, where supported)**. +> [!IMPORTANT] +> **This only works with Mysql.Data v8.0.32 (and earlier, where supported)**. > Mysql.Data v8.1.0 and later have built-in direct support for Open Telemetry > via `ActivitySource`. @@ -64,7 +65,7 @@ the `ConfigureServices` of your `Startup` class. Refer to documentation for For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). -> **Note** +> [!NOTE] > If you are using `Mysql.Data` 8.0.31 or later, please add option `Logging=true` in your connection string to enable tracing. See issue #691 for details. diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 4c0323672c..2015d6bcce 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -27,7 +27,7 @@ Released 2023-Feb-27 Released 2023-Feb-17 -> **Note** +> [!NOTE] > The version number was lowered from 1.0.0 to 0.5.0 to better reflect the experimental state of Opentelemetry process metrics specification status. Packages that were older than this release will be delisted to avoid confusion. diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 5b8d52e277..4482da3983 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -123,7 +123,8 @@ The number of processors (CPU cores) available to the current process. The API used to retrieve the value is [System.Environment.ProcessorCount](https://learn.microsoft.com/dotnet/api/system.environment.processorcount). -> **Note** This metric is under +> [!NOTE] +> This metric is under > [discussion](https://github.com/open-telemetry/opentelemetry-specification/issues/3200) and not part of the [Process Metrics Spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 5ffc84e490..aa0b0fbd63 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -48,7 +48,7 @@ to the application. Number of garbage collections that have occurred since process start. -> **Note** +> [!NOTE] > .NET uses a [generational GC](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#generations) which divides the heap into different generations numbered 0, 1, and 2. In each collection the GC decides which generation to search for reclaimable memory, @@ -102,7 +102,7 @@ Count of bytes allocated on the managed GC heap since the process start. .NET objects are allocated from this heap. Object allocations from unmanaged languages such as C/C++ do not use this heap. -> **Note** +> [!NOTE] > This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | @@ -124,7 +124,7 @@ objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred. -> **Note** +> [!NOTE] > This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | @@ -142,7 +142,7 @@ The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred. -> **Note** +> [!NOTE] > This metric is only available when targeting .NET 6 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | @@ -164,7 +164,7 @@ The API used to retrieve the value is: The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred. -> **Note** +> [!NOTE] > This metric is only available when targeting .NET 7 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | @@ -180,7 +180,7 @@ The API used to retrieve the value is: The total amount of time paused in GC since the process start. -> **Note** +> [!NOTE] > This metric is only available when targeting .NET 7 or later. | Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | @@ -327,7 +327,7 @@ Count of exceptions that have been thrown in managed code, since the observation started. The value will be unavailable until an exception has been thrown after OpenTelemetry.Instrumentation.Runtime initialization. -> **Note** +> [!NOTE] > The value is tracked by incrementing a counter whenever an AppDomain.FirstChanceException event occurs. The observation starts when the Runtime instrumentation library is initialized, so the value will be unavailable until an exception has been diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index 4784ef3175..32fe81436c 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -9,7 +9,7 @@ which instruments [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis/) and collects traces about outgoing calls to Redis. -> **Note** +> [!NOTE] > This component is based on the OpenTelemetry semantic conventions for [traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). These conventions are From 08805febb82fcfabd98211e749d14c487aa5bb97 Mon Sep 17 00:00:00 2001 From: Stanislav Perekrestov Date: Fri, 12 Jan 2024 06:34:28 +0100 Subject: [PATCH 0936/1499] [Exporter.StackDriver] Add net8 and net6 TFM support and update Google Cloud libraries (#1414) (#1497) --- .../PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../.publicApi/net8.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 23 +++++++++++++++++++ .../CHANGELOG.md | 7 ++++++ .../Implementation/ActivityExtensions.cs | 2 +- .../OpenTelemetry.Exporter.Stackdriver.csproj | 6 ++--- .../StackdriverTraceExporter.cs | 2 +- .../Utils/CommonUtils.cs | 6 ++--- 9 files changed, 38 insertions(+), 9 deletions(-) rename src/OpenTelemetry.Exporter.Stackdriver/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.Stackdriver/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Unshipped.txt (100%) create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Stackdriver/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..f09de33268 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt @@ -0,0 +1,23 @@ +OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential? +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string? +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource? +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string? +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void +OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter +OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string! projectId) -> void +OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string? projectId) -> Google.Api.MonitoredResource! +static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string? +static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration! +static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable! source, int size) -> System.Collections.Generic.IEnumerable!>! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string! projectId) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index fbc1d739ec..c0e283e684 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -4,6 +4,13 @@ * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Add support of a native "gRPC for .NET" for apps targeting .NET 6.0 or later. + ([#1414](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1414)) + 1. Add support net8.0, net6.0 as target frameworks. + 2. Remove support of netstandard2.0. + 3. Update Google Cloud libraries: + 1. Google.Cloud.Monitoring.V3 2.6.0 -> 3.4.0 + 2. Google.Cloud.Trace.V2 2.3.0 -> 3.3.0 ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index ecf996f6a5..7e44d7a302 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -46,7 +46,7 @@ public static Span ToSpan(this Activity activity, string projectId) EndTime = activity.StartTimeUtc.Add(activity.Duration).ToTimestamp(), ChildSpanCount = null, }; - if (activity.ParentSpanId != null) + if (activity.ParentSpanId != default) { var parentSpanId = activity.ParentSpanId.ToHexString(); if (!string.IsNullOrEmpty(parentSpanId)) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index e338015745..1fe5991dbd 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net462 + net8.0;net6.0;net462 Stackdriver .NET Exporter for OpenTelemetry. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- @@ -9,8 +9,8 @@ - - + + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index c71127eafb..eed13a4e15 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -41,7 +41,7 @@ static StackdriverTraceExporter() try { - OpenTelemetryExporterVersion = Assembly.GetCallingAssembly().GetName().Version.ToString(); + OpenTelemetryExporterVersion = Assembly.GetCallingAssembly().GetName().Version!.ToString(); } catch (Exception) { diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs index f820150fae..c5e070c81e 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Utils/CommonUtils.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; +using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Stackdriver.Utils; @@ -19,10 +20,7 @@ public static class CommonUtils /// . public static IEnumerable> Partition(this IEnumerable source, int size) { - if (source == null) - { - throw new System.ArgumentNullException(nameof(source)); - } + Guard.ThrowIfNull(source); using var enumerator = source.GetEnumerator(); while (enumerator.MoveNext()) From 7f97be5f4dc1c5bba896691548b536cd01dccd90 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Fri, 12 Jan 2024 11:59:08 -0800 Subject: [PATCH 0937/1499] Minor docs fix (#1532) --- src/OpenTelemetry.Exporter.Geneva/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 1f5d673963..11a4f50fb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -56,7 +56,8 @@ provider, including the OpenTelemetry provider. `OpenTelemetry` is the for `OpenTelemetryLoggerProvider`, that may be used when configuring filtering rules. -**NOTE:** _Some application types (e.g. [ASP.NET +> [!NOTE] +> Some application types (e.g. [ASP.NET Core](https://docs.microsoft.com/aspnet/core/fundamentals/logging/#configure-logging-1)) have default logging settings. Please review them to make sure `OpenTelemetryLoggingProvider` is configured to receive Logs of appropriate From 7fc9ee6a939ea46a68261d0438efbbecc4ac0d16 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Sat, 13 Jan 2024 06:36:50 -0800 Subject: [PATCH 0938/1499] Minor docs improvement for Geneva Exporter (#1533) --- src/OpenTelemetry.Exporter.Geneva/README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 11a4f50fb2..270fcb92ba 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -22,13 +22,6 @@ Therefore, each type of telemetry **must be** enabled separately. ### Enable Logs -Install the latest stable version of -[`Microsoft.Extensions.Logging`](https://www.nuget.org/packages/Microsoft.Extensions.Logging/) - -```shell -dotnet add package Microsoft.Extensions.Logging -``` - This snippet shows how to configure the Geneva Exporter for Logs ```csharp From f06191f40989d32ee8b3c9fb3fd961caf550cf42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 19 Jan 2024 01:18:05 +0100 Subject: [PATCH 0939/1499] [ResourceDetectors.AWS] mark class as sealed (#1510) Co-authored-by: Cijo Thomas --- .../AWSEBSResourceDetector.cs | 2 +- .../AWSEC2ResourceDetector.cs | 2 +- .../AWSECSResourceDetector.cs | 2 +- .../AWSEKSResourceDetector.cs | 2 +- .../AWSResourcesEventSource.cs | 2 +- src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 2 ++ .../ResourceDetectorUtils.cs | 4 +--- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs index cf8705c17e..5bd0a07b2d 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs @@ -14,7 +14,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running in AWS ElasticBeanstalk environment. /// -public class AWSEBSResourceDetector : IResourceDetector +public sealed class AWSEBSResourceDetector : IResourceDetector { private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; #if NET6_0_OR_GREATER diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs index 6b2272e09c..615f44ab0f 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs @@ -11,7 +11,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running on AWS EC2 instance. /// -public class AWSEC2ResourceDetector : IResourceDetector +public sealed class AWSEC2ResourceDetector : IResourceDetector { private const string AWSEC2MetadataTokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"; private const string AWSEC2MetadataTokenHeader = "X-aws-ec2-metadata-token"; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index aed3403dc4..eb8ee5b328 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -14,7 +14,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running in AWS ECS. /// -public class AWSECSResourceDetector : IResourceDetector +public sealed class AWSECSResourceDetector : IResourceDetector { private const string AWSECSMetadataPath = "/proc/self/cgroup"; private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs index 2848e95a66..82e4ea0170 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs @@ -16,7 +16,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Resource detector for application running in AWS EKS. /// -public class AWSEKSResourceDetector : IResourceDetector +public sealed class AWSEKSResourceDetector : IResourceDetector { private const string AWSEKSCertificatePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; private const string AWSEKSCredentialPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs index 83b8151a44..4238241190 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs @@ -8,7 +8,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; [EventSource(Name = "OpenTelemetry-ResourceDetectors-AWS")] -internal class AWSResourcesEventSource : EventSource +internal sealed class AWSResourcesEventSource : EventSource { public static AWSResourcesEventSource Log = new(); diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 85684ae331..20b95715c6 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -6,6 +6,8 @@ ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Fix AWS EBS Resource Detector working on linux. ([#1350](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1350)) +* BREAKING: All Resource Detector classes marked as `sealed`. + ([#1510](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1510)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs index 4ec1c3a586..6b3a76815c 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs @@ -14,9 +14,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; /// /// Class for resource detector utils. /// -#pragma warning disable CA1052 -internal class ResourceDetectorUtils -#pragma warning restore CA1052 +internal static class ResourceDetectorUtils { private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); From 8a89a69445a1f89917a6a159e895b9267c7cc925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 19 Jan 2024 16:21:02 +0100 Subject: [PATCH 0940/1499] ASP.NET and OWIN Instrumentations - fix description for `http.server.request.duration` metric (#1538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Łach --- src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 3 +++ .../Implementation/HttpInMetricsListener.cs | 2 +- src/OpenTelemetry.Instrumentation.AspNet/README.md | 2 +- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 2 ++ .../Implementation/OwinInstrumentationMetrics.cs | 2 +- src/OpenTelemetry.Instrumentation.Owin/README.md | 2 +- 6 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index f58e6394ad..245eb9612b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix description for `http.server.request.duration` metric. + ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) + ## 1.7.0-beta.1 Released 2023-Dec-20 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index 93afb6ddc1..9200911cb9 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -21,7 +21,7 @@ public HttpInMetricsListener(Meter meter, AspNetMetricsInstrumentationOptions op this.httpServerDuration = meter.CreateHistogram( "http.server.request.duration", unit: "s", - description: "Measures the duration of inbound HTTP requests."); + description: "Duration of HTTP server requests."); TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; this.options = options; } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 7bac6bba39..e33ae97dc6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -126,7 +126,7 @@ Currently, the instrumentation supports the following metric. | Name | Instrument Type | Unit | Description | |-------|-----------------|------|-------------| -| `http.server.duration` | Histogram | `ms` | Measures the duration of inbound HTTP requests. | +| `http.server.request.duration` | Histogram | `s` | Duration of HTTP server requests. | ## Advanced trace configuration diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index b818af9fb5..bbf1bd73d9 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -8,6 +8,8 @@ ([#929](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/929)) * Adds HTTP server metrics via `AddOwinInstrumentation` extension method on `MeterProviderBuilder` ([#1335](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1335)) +* Fix description for `http.server.request.duration` metric. + ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) ## 1.0.0-rc.3 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs index e984eb8c9c..a1d2f5a0a5 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -14,5 +14,5 @@ internal static class OwinInstrumentationMetrics public static Meter Instance => new Meter(MeterName, AssemblyName.Version.ToString()); - public static Histogram HttpServerDuration => Instance.CreateHistogram("http.server.request.duration", "s", "Measures the duration of inbound HTTP requests."); + public static Histogram HttpServerDuration => Instance.CreateHistogram("http.server.request.duration", "s", "Duration of HTTP server requests."); } diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index efc1d3d5e3..31afb50349 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -75,7 +75,7 @@ Currently, the instrumentation supports the following metric. | Name | Instrument Type | Unit | Description | |-------|-----------------|------|-------------| -| `http.server.request.duration` | Histogram | `s` | Measures the duration of inbound HTTP requests. | +| `http.server.request.duration` | Histogram | `s` | Duration of HTTP server requests. | ## Customize OWIN span names From 75a7f38243ab350e59916006f8f7bc9e729cda40 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 22 Jan 2024 16:28:25 +0000 Subject: [PATCH 0941/1499] [Instrumentation.AWS] Bump minimal AWS SDKs to 3.7.300 (#1542) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.AWS.csproj | 6 +++--- .../OpenTelemetry.Instrumentation.AWS.Tests.csproj | 2 +- .../TestAWSClientInstrumentation.cs | 3 +-- .../TestRequest.cs | 8 ++++++++ .../TestRequestContext.cs | 6 ++++-- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index a078cca882..a1c1add753 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated dependency on AWS .NET SDK to version 3.7.300. + ([#1542](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1542)) + ## 1.1.0-beta.2 Released 2023-Dec-01 diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index 183fa0c839..b473eb7bbf 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 35d0dbb926..56b20ac4a8 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index ccc87f9941..c4f81f779e 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -169,8 +169,7 @@ public void TestSQSSendMessageSuccessful() { var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; - string dummyResponse = "\n" + - "SomeDummyResponse"; + string dummyResponse = "{}"; CustomResponses.SetResponse(sqs, dummyResponse, requestId, true); var send_msg_req = new SendMessageRequest(); send_msg_req.QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue"; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs index 5eb4cbfa2b..2aa3d0a634 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs @@ -6,8 +6,10 @@ using System.IO; using Amazon; using Amazon.Runtime; +using Amazon.Runtime.Endpoints; using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Auth; +using Amazon.Runtime.Internal.Util; namespace OpenTelemetry.Instrumentation.AWS.Tests; @@ -81,6 +83,12 @@ internal class TestRequest(ParameterCollection parameters) : IRequest public bool UseDoubleEncoding { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public IPropertyBag EndpointAttributes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public CompressionEncodingAlgorithm CompressionAlgorithm { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public ChecksumData ChecksumData { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public void AddPathResource(string key, string value) { throw new NotImplementedException(); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs index 965c3e30e9..208f0def71 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using System.Collections.Generic; using System.Threading; using Amazon.Runtime; using Amazon.Runtime.Internal; @@ -13,10 +14,9 @@ namespace OpenTelemetry.Instrumentation.AWS.Tests; internal class TestRequestContext(AmazonWebServiceRequest originalRequest, IRequest request) : IRequestContext { - private readonly AmazonWebServiceRequest originalRequest = originalRequest; private IRequest request = request; - public AmazonWebServiceRequest OriginalRequest => this.originalRequest; + public AmazonWebServiceRequest OriginalRequest { get; set; } = originalRequest; public string RequestName => throw new NotImplementedException(); @@ -59,4 +59,6 @@ internal class TestRequestContext(AmazonWebServiceRequest originalRequest, IRequ public bool IsLastExceptionRetryable { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public Guid InvocationId => throw new NotImplementedException(); + + public IDictionary ContextAttributes { get; } = new Dictionary(); } From b21a0f9890c678ef5a3d0e7b83a503aad2a55678 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 22 Jan 2024 19:19:01 +0000 Subject: [PATCH 0942/1499] [Instrumentation.AWSLambda] Update to net6.0 (#1545) --- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../AWSLambdaWrapper.cs | 10 +++------- .../CHANGELOG.md | 2 ++ .../AWSLambdaResourceDetector.cs | 20 +++++++++++++++---- .../Implementation/AWSLambdaUtils.cs | 6 +++--- .../Implementation/AWSMessagingUtils.cs | 4 ++-- ...Telemetry.Instrumentation.AWSLambda.csproj | 2 +- 9 files changed, 28 insertions(+), 17 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Shipped.txt rename src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/{netstandard2.0 => net6.0}/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 223a529417..3102659426 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Threading.Tasks; @@ -20,13 +19,10 @@ namespace OpenTelemetry.Instrumentation.AWSLambda; /// public static class AWSLambdaWrapper { - private static readonly AssemblyName AssemblyName = typeof(AWSLambdaWrapper).Assembly.GetName(); + internal const string ActivitySourceName = "OpenTelemetry.Instrumentation.AWSLambda"; - [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Initialization order.")] - internal static readonly string ActivitySourceName = AssemblyName.Name; - - private static readonly Version Version = AssemblyName.Version; - private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, Version.ToString()); + private static readonly string Version = typeof(AWSLambdaWrapper).Assembly.GetCustomAttribute()!.InformationalVersion.Split('+')[0]; + private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, Version); /// /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 527ae83f3c..81fa0799b1 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -9,6 +9,8 @@ If null state analysis is enabled in your depending project, you may encounter new warnings. ([#1295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1295)) +* BREAKING: Target `net6.0` instead of `netstandard2.0` + ([#1545](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1545)) ## 1.2.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs index 4446468214..5e8ba32490 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaResourceDetector.cs @@ -14,14 +14,26 @@ internal sealed class AWSLambdaResourceDetector : IResourceDetector /// Detected resource. public Resource Detect() { - var resourceAttributes = new List> + var resourceAttributes = new List>(4) { new(AWSLambdaSemanticConventions.AttributeCloudProvider, AWSLambdaUtils.GetCloudProvider()), - new(AWSLambdaSemanticConventions.AttributeCloudRegion, AWSLambdaUtils.GetAWSRegion()), - new(AWSLambdaSemanticConventions.AttributeFaasName, AWSLambdaUtils.GetFunctionName()), - new(AWSLambdaSemanticConventions.AttributeFaasVersion, AWSLambdaUtils.GetFunctionVersion()), }; + if (AWSLambdaUtils.GetAWSRegion() is { } region) + { + resourceAttributes.Add(new(AWSLambdaSemanticConventions.AttributeCloudRegion, region)); + } + + if (AWSLambdaUtils.GetFunctionName() is { } functionName) + { + resourceAttributes.Add(new(AWSLambdaSemanticConventions.AttributeFaasName, functionName)); + } + + if (AWSLambdaUtils.GetFunctionVersion() is { } functionVersion) + { + resourceAttributes.Add(new(AWSLambdaSemanticConventions.AttributeFaasVersion, functionVersion)); + } + return new Resource(resourceAttributes); } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index adcb083eb7..eccbbc2ca8 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -86,17 +86,17 @@ internal static string GetCloudProvider() return CloudProvider; } - internal static string GetAWSRegion() + internal static string? GetAWSRegion() { return Environment.GetEnvironmentVariable(AWSRegion); } - internal static string GetFunctionName(ILambdaContext? context = null) + internal static string? GetFunctionName(ILambdaContext? context = null) { return context?.FunctionName ?? Environment.GetEnvironmentVariable(FunctionName); } - internal static string GetFunctionVersion() + internal static string? GetFunctionVersion() { return Environment.GetEnvironmentVariable(FunctionVersion); } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs index 8d6a205f7d..0202903329 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -127,8 +127,8 @@ internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage? mes var body = sqsMessage.Body; if (body != null && - body.TrimStart().StartsWith("{", StringComparison.Ordinal) && - body.Contains(SnsMessageAttributes)) + body.TrimStart().StartsWith('{') && + body.Contains(SnsMessageAttributes, StringComparison.Ordinal)) { try { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index be934118fc..0f519fc865 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + net6.0 AWS Lambda tracing wrapper for OpenTelemetry .NET $(PackageTags);AWS Lambda Instrumentation.AWSLambda- From 397e9f8a2eba6fa2c72afac2d394a8698e4114cf Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 23 Jan 2024 00:03:14 +0000 Subject: [PATCH 0943/1499] Extend AoT support (#1541) Co-authored-by: Cijo Thomas --- .github/workflows/ci.yml | 7 ++++++ .../CHANGELOG.md | 5 ++++ ...raceEnrichmentProviderBuilderExtensions.cs | 7 ++++++ ...ceEnrichmentServiceCollectionExtensions.cs | 7 ++++++ .../AWSEBSResourceDetector.cs | 4 ++++ .../AWSEC2ResourceDetector.cs | 4 ++++ .../AWSEKSResourceDetector.cs | 4 ++++ .../CHANGELOG.md | 2 ++ .../Models/AWSEC2IdentityDocumentModel.cs | 7 ++++++ .../Models/AWSEKSClusterDataModel.cs | 2 +- .../Models/AWSEKSClusterInformationModel.cs | 5 +++- .../ResourceDetectorUtils.cs | 20 ++++++++++++++++ .../SourceGenerationContext.cs | 24 +++++++++++++++++++ .../AWSXRaySamplerClient.cs | 21 ++++++++++++++-- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 3 +++ .../GetSamplingRulesResponse.cs | 2 +- .../GetSamplingTargetsRequest.cs | 2 +- .../GetSamplingTargetsResponse.cs | 2 +- .../SourceGenerationContext.cs | 23 ++++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 6 +++++ 20 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/SourceGenerationContext.cs create mode 100644 src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 813abdb5a8..c5dc47e66f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,8 +21,10 @@ jobs: build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*'] shared: ['src/Shared/**'] code: ['**.cs', '.editorconfig'] + aot: ['src/OpenTelemetry.Extensions.Enrichment/**'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] + aws: ['*/OpenTelemetry.*.AWS*/**', '!**/*.md'] azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] @@ -35,6 +37,7 @@ jobs: processdetector: ['*/OpenTelemetry.ResourceDetectors.Process/**', '*/OpenTelemetry.ResourceDetectors.Process.Tests/**', '!**/*.md'] processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', '*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] + resourcedetectors: ['*/OpenTelemetry.ResourceDetectors.*/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] solution: [ @@ -343,10 +346,14 @@ jobs: if: | contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') + || contains(needs.detect-changes.outputs.changes, 'aws') || contains(needs.detect-changes.outputs.changes, 'azure') + || contains(needs.detect-changes.outputs.changes, 'extensions') || contains(needs.detect-changes.outputs.changes, 'host') || contains(needs.detect-changes.outputs.changes, 'processdetector') || contains(needs.detect-changes.outputs.changes, 'processruntime') + || contains(needs.detect-changes.outputs.changes, 'resourcedetectors') + || contains(needs.detect-changes.outputs.changes, 'aot') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'redis') diff --git a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md index 825c32f0d0..642075cb3f 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md @@ -1 +1,6 @@ # Changelog + +## Unreleased + +* Make Extensions.Enrichment AoT compatible. + ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs index 8596ce52ad..d0f412ed06 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -23,7 +26,11 @@ public static class TraceEnrichmentProviderBuilderExtensions /// /// Add this enricher *before* exporter related Activity processors. /// +#if NET6_0_OR_GREATER + public static TracerProviderBuilder AddTraceEnricher<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(this TracerProviderBuilder builder) +#else public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder builder) +#endif where T : TraceEnricher { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs index 9a20e64e6a..b78210a488 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif using System.Linq; using Microsoft.Extensions.DependencyInjection.Extensions; using OpenTelemetry.Extensions.Enrichment; @@ -25,7 +28,11 @@ public static class TraceEnrichmentServiceCollectionExtensions /// /// Add this enricher *before* exporter related Activity processors. /// +#if NET6_0_OR_GREATER + public static IServiceCollection AddTraceEnricher<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(this IServiceCollection services) +#else public static IServiceCollection AddTraceEnricher(this IServiceCollection services) +#endif where T : TraceEnricher { Guard.ThrowIfNull(services); diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs index 5bd0a07b2d..442ffe406c 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs @@ -87,6 +87,10 @@ internal static List> ExtractResourceAttributes(AWS internal static AWSEBSMetadataModel? GetEBSMetadata(string filePath) { +#if NET6_0_OR_GREATER + return ResourceDetectorUtils.DeserializeFromFile(filePath, SourceGenerationContext.Default.AWSEBSMetadataModel); +#else return ResourceDetectorUtils.DeserializeFromFile(filePath); +#endif } } diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs index 615f44ab0f..dc75368995 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs @@ -83,7 +83,11 @@ internal static List> ExtractResourceAttributes(AWS internal static AWSEC2IdentityDocumentModel? DeserializeResponse(string response) { +#if NET6_0_OR_GREATER + return ResourceDetectorUtils.DeserializeFromString(response, SourceGenerationContext.Default.AWSEC2IdentityDocumentModel); +#else return ResourceDetectorUtils.DeserializeFromString(response); +#endif } private static string GetAWSEC2Token() diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs index 82e4ea0170..a1c560da08 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs @@ -116,7 +116,11 @@ internal static List> ExtractResourceAttributes(str internal static AWSEKSClusterInformationModel? DeserializeResponse(string response) { +#if NET6_0_OR_GREATER + return ResourceDetectorUtils.DeserializeFromString(response, SourceGenerationContext.Default.AWSEKSClusterInformationModel); +#else return ResourceDetectorUtils.DeserializeFromString(response); +#endif } private static string? GetEKSClusterName(string credentials, HttpClientHandler? httpClientHandler) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 20b95715c6..d8e4dd31be 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -8,6 +8,8 @@ ([#1350](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1350)) * BREAKING: All Resource Detector classes marked as `sealed`. ([#1510](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1510)) +* Make OpenTelemetry.ResourceDetectors.AWS native AoT compatible. + ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs index bc88556a5b..4bd2f4dfef 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs @@ -1,17 +1,24 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Text.Json.Serialization; + namespace OpenTelemetry.ResourceDetectors.AWS.Models; internal class AWSEC2IdentityDocumentModel { + [JsonPropertyName("accountId")] public string? AccountId { get; set; } + [JsonPropertyName("availabilityZone")] public string? AvailabilityZone { get; set; } + [JsonPropertyName("region")] public string? Region { get; set; } + [JsonPropertyName("instanceId")] public string? InstanceId { get; set; } + [JsonPropertyName("instanceType")] public string? InstanceType { get; set; } } diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs index 7dfaeed930..0284548085 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS.Models; -internal class AWSEKSClusterDataModel +internal sealed class AWSEKSClusterDataModel { [JsonPropertyName("cluster.name")] public string? ClusterName { get; set; } diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs index 7a9e6f9bac..b732eb7795 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs @@ -1,9 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Text.Json.Serialization; + namespace OpenTelemetry.ResourceDetectors.AWS.Models; -internal class AWSEKSClusterInformationModel +internal sealed class AWSEKSClusterInformationModel { + [JsonPropertyName("data")] public AWSEKSClusterDataModel? Data { get; set; } } diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs index 6b3a76815c..331f8d86dd 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/ResourceDetectorUtils.cs @@ -7,6 +7,9 @@ using System.Net.Http; using System.Text; using System.Text.Json; +#if !NETFRAMEWORK +using System.Text.Json.Serialization.Metadata; +#endif using System.Threading.Tasks; namespace OpenTelemetry.ResourceDetectors.AWS; @@ -16,7 +19,9 @@ namespace OpenTelemetry.ResourceDetectors.AWS; /// internal static class ResourceDetectorUtils { +#if !NET6_0_OR_GREATER private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); +#endif internal static async Task SendOutRequest(string url, string method, KeyValuePair? header, HttpClientHandler? handler = null) { @@ -40,6 +45,20 @@ internal static async Task SendOutRequest(string url, string method, Key } } +#if NET6_0_OR_GREATER + internal static T? DeserializeFromFile(string filePath, JsonTypeInfo jsonTypeInfo) + { + using (var stream = GetStream(filePath)) + { + return JsonSerializer.Deserialize(stream, jsonTypeInfo); + } + } + + internal static T? DeserializeFromString(string json, JsonTypeInfo jsonTypeInfo) + { + return JsonSerializer.Deserialize(json, jsonTypeInfo); + } +#else internal static T? DeserializeFromFile(string filePath) { using (var stream = GetStream(filePath)) @@ -52,6 +71,7 @@ internal static async Task SendOutRequest(string url, string method, Key { return JsonSerializer.Deserialize(json, JsonSerializerOptions); } +#endif internal static Stream GetStream(string filePath) { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/SourceGenerationContext.cs b/src/OpenTelemetry.ResourceDetectors.AWS/SourceGenerationContext.cs new file mode 100644 index 0000000000..003f5b1d5d --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.AWS/SourceGenerationContext.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System.Text.Json.Serialization; +using OpenTelemetry.ResourceDetectors.AWS.Models; + +namespace OpenTelemetry.ResourceDetectors.AWS; + +/// +/// "Source Generation" is feature added to System.Text.Json in .NET 6.0. +/// This is a performance optimization that avoids runtime reflection when performing serialization. +/// Serialization metadata will be computed at compile-time and included in the assembly. +/// . +/// . +/// . +/// +[JsonSerializable(typeof(AWSEBSMetadataModel))] +[JsonSerializable(typeof(AWSEC2IdentityDocumentModel))] +[JsonSerializable(typeof(AWSEKSClusterInformationModel))] +internal sealed partial class SourceGenerationContext : JsonSerializerContext +{ +} +#endif diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index b911038376..0b16ac5a89 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -38,7 +38,13 @@ public async Task> GetSamplingRules() try { - GetSamplingRulesResponse? getSamplingRulesResponse = JsonSerializer.Deserialize(responseJson); + GetSamplingRulesResponse? getSamplingRulesResponse = JsonSerializer +#if NET6_0_OR_GREATER + .Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingRulesResponse); +#else + .Deserialize(responseJson); +#endif + if (getSamplingRulesResponse is not null) { if (getSamplingRulesResponse.SamplingRuleRecords is not null) @@ -66,7 +72,14 @@ public async Task> GetSamplingRules() public async Task GetSamplingTargets(GetSamplingTargetsRequest getSamplingTargetsRequest) { - var content = new StringContent(JsonSerializer.Serialize(getSamplingTargetsRequest), Encoding.UTF8, this.jsonContentType); + var json = JsonSerializer +#if NET6_0_OR_GREATER + .Serialize(getSamplingTargetsRequest, SourceGenerationContext.Default.GetSamplingTargetsRequest); +#else + .Serialize(getSamplingTargetsRequest); +#endif + + var content = new StringContent(json, Encoding.UTF8, this.jsonContentType); using var request = new HttpRequestMessage(HttpMethod.Post, this.getSamplingTargetsEndpoint) { @@ -78,7 +91,11 @@ public async Task> GetSamplingRules() try { GetSamplingTargetsResponse? getSamplingTargetsResponse = JsonSerializer +#if NET6_0_OR_GREATER + .Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingTargetsResponse); +#else .Deserialize(responseJson); +#endif return getSamplingTargetsResponse; } diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index a28f47d696..0d912d6711 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -10,3 +10,6 @@ Initial release of `OpenTelemetry.Sampler.AWS`. * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + +* Make OpenTelemetry.Sampler.AWS native AoT compatible. + ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs index 44d1dd2743..e43a88c1ac 100644 --- a/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Sampler.AWS; -internal class GetSamplingRulesResponse +internal sealed class GetSamplingRulesResponse { [JsonPropertyName("NextToken")] public string? NextToken { get; set; } diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs index d24c96bd51..9702995e91 100644 --- a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Sampler.AWS; -internal class GetSamplingTargetsRequest +internal sealed class GetSamplingTargetsRequest { public GetSamplingTargetsRequest(List documents) { diff --git a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs index 7ec53f577b..772d37dca0 100644 --- a/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs +++ b/src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Sampler.AWS; -internal class GetSamplingTargetsResponse +internal sealed class GetSamplingTargetsResponse { public GetSamplingTargetsResponse( double lastRuleModification, diff --git a/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs b/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs new file mode 100644 index 0000000000..239c7dcfcc --- /dev/null +++ b/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Sampler.AWS; + +/// +/// "Source Generation" is feature added to System.Text.Json in .NET 6.0. +/// This is a performance optimization that avoids runtime reflection when performing serialization. +/// Serialization metadata will be computed at compile-time and included in the assembly. +/// . +/// . +/// . +/// +[JsonSerializable(typeof(GetSamplingRulesResponse))] +[JsonSerializable(typeof(GetSamplingTargetsRequest))] +[JsonSerializable(typeof(GetSamplingTargetsResponse))] +internal sealed partial class SourceGenerationContext : JsonSerializerContext +{ +} +#endif diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index f2e95fd1b0..911c7baf57 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -13,13 +13,19 @@ When adding projects here please also update the verify-aot-compat job in .github\workflows\ci.yml so that it runs for the project being added. --> + + + + + + From fffb5714f2e1f125a23974939e22d0e9e24933ff Mon Sep 17 00:00:00 2001 From: anoopbabu29 <32779456+anoopbabu29@users.noreply.github.com> Date: Wed, 24 Jan 2024 10:36:15 -0500 Subject: [PATCH 0944/1499] ResourceDetectors.Container: Removing Support for .NET Framework 4.6.2 (#1536) --- .../.publicApi/{net462 => net6.0}/PublicAPI.Shipped.txt | 0 .../.publicApi/{net462 => net6.0}/PublicAPI.Unshipped.txt | 0 .../.publicApi/netstandard2.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/netstandard2.0/PublicAPI.Unshipped.txt | 3 --- src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 4 ++++ .../ContainerResourceDetector.cs | 2 +- .../OpenTelemetry.ResourceDetectors.Container.csproj | 2 +- .../OpenTelemetry.ResourceDetectors.Container.Tests.csproj | 1 - 8 files changed, 6 insertions(+), 7 deletions(-) rename src/OpenTelemetry.ResourceDetectors.Container/.publicApi/{net462 => net6.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.Container/.publicApi/{net462 => net6.0}/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 9da4e0d8d8..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector -OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector.ContainerResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Container.ContainerResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 8ab1829c4a..e6bbe5c616 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* **Breaking** Changed target framework from .NET Standard 2.0 + to .NET 6.0. It drops support for .NET Framework. + ([#1536](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1536)) + ## 1.0.0-beta.5 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs index 3b34d794b3..ec7d1705d3 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Container/ContainerResourceDetector.cs @@ -156,7 +156,7 @@ private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex { containerId = GetIdFromLineV1(line); } - else if (cgroupVersion == ParseMode.V2 && line.Contains(Hostname)) + else if (cgroupVersion == ParseMode.V2 && line.Contains(Hostname, StringComparison.Ordinal)) { containerId = GetIdFromLineV2(line); } diff --git a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj index 43eb3d6322..c4800a5350 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net462 + $(NetMinimumSupportedVersion) OpenTelemetry Extensions - Container Resource Detector from Container environment. ResourceDetectors.Container- true diff --git a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj index 67da77b288..6b11db9474 100644 --- a/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Container.Tests/OpenTelemetry.ResourceDetectors.Container.Tests.csproj @@ -4,7 +4,6 @@ Unit test project for Container Detector for OpenTelemetry $(SupportedNetTargets) - $(TargetFrameworks);net462 enable From 6f064e125453e31777294b9fea80dc5c7b5bbe8c Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Wed, 24 Jan 2024 16:01:46 +0000 Subject: [PATCH 0945/1499] [Instrumentation.AWSLambda] Fix AoT warnings (#1544) --- .../CHANGELOG.md | 4 ++++ .../Implementation/AWSMessagingUtils.cs | 4 ++-- ...Telemetry.Instrumentation.AWSLambda.csproj | 9 ++++----- .../SourceGenerationContext.cs | 20 +++++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 4 ++-- 5 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/SourceGenerationContext.cs diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 81fa0799b1..3b7f744f0b 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -11,6 +11,10 @@ ([#1295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1295)) * BREAKING: Target `net6.0` instead of `netstandard2.0` ([#1545](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1545)) +* Add support for native AoT. + `Amazon.Lambda.*` NuGet package dependencies have been upgraded, see package + dependencies for details. + ([#1544](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1544)) ## 1.2.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs index 0202903329..51663ffb88 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -5,9 +5,9 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Text.Json; using Amazon.Lambda.SNSEvents; using Amazon.Lambda.SQSEvents; -using Newtonsoft.Json; using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; @@ -132,7 +132,7 @@ internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage? mes { try { - snsMessage = JsonConvert.DeserializeObject(body); + snsMessage = JsonSerializer.Deserialize(body, SourceGenerationContext.Default.SNSMessage); } catch (Exception) { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 0f519fc865..994ba449a7 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -8,12 +8,11 @@ - - - - + + + + - diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/SourceGenerationContext.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/SourceGenerationContext.cs new file mode 100644 index 0000000000..312add0f92 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/SourceGenerationContext.cs @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Text.Json.Serialization; +using Amazon.Lambda.SNSEvents; + +namespace OpenTelemetry.Instrumentation.AWSLambda; + +/// +/// "Source Generation" is feature added to System.Text.Json in .NET 6.0. +/// This is a performance optimization that avoids runtime reflection when performing serialization. +/// Serialization metadata will be computed at compile-time and included in the assembly. +/// . +/// . +/// . +/// +[JsonSerializable(typeof(SNSEvent.SNSMessage))] +internal sealed partial class SourceGenerationContext : JsonSerializerContext +{ +} diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 911c7baf57..0a8744bb88 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -14,10 +14,10 @@ .github\workflows\ci.yml so that it runs for the project being added. --> - - + + From 94ab73f42e44a7525d3581d1bbfb84ef26050088 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:52:18 -0800 Subject: [PATCH 0946/1499] Bump codecov/codecov-action from 3.1.4 to 3.1.5 (#1549) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/Component.BuildTest.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index f77172249e..147099b048 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -57,7 +57,7 @@ jobs: run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} - uses: codecov/codecov-action@v3.1.4 + uses: codecov/codecov-action@v3.1.5 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5dc47e66f..ce503aa978 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -330,7 +330,7 @@ jobs: - name: Merging test results run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - - uses: codecov/codecov-action@v3.1.4 + - uses: codecov/codecov-action@v3.1.5 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} From a8f7bb810d44f0c3c9a1a92ebe5516701d2443df Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 26 Jan 2024 11:25:14 +0000 Subject: [PATCH 0947/1499] [Instrumentation.AWS] Support .NET 6 and resolve AoT warning (#1547) --- .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 8 +++++ .../CHANGELOG.md | 4 +++ .../AWSTracingPipelineHandler.cs | 32 +++++++++++++------ .../OpenTelemetry.Instrumentation.AWS.csproj | 2 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + 6 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..1362c26ff9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +#nullable enable +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index a1c1add753..b64dfe884f 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -4,6 +4,10 @@ * Updated dependency on AWS .NET SDK to version 3.7.300. ([#1542](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1542)) +* Add target for `net6.0`. + ([#1547](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1547)) +* Add support for native AoT. + ([#1547](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1547)) ## 1.1.0-beta.2 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 4ec869eedb..2383c9f8ba 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -14,17 +14,17 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; -internal class AWSTracingPipelineHandler : PipelineHandler +internal sealed class AWSTracingPipelineHandler : PipelineHandler { internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; - private static readonly AWSXRayPropagator AwsPropagator = new AWSXRayPropagator(); + private static readonly AWSXRayPropagator AwsPropagator = new(); private static readonly Action, string, string> Setter = (carrier, name, value) => { carrier[name] = value; }; - private static readonly ActivitySource AWSSDKActivitySource = new ActivitySource(ActivitySourceName); + private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName); private readonly AWSClientInstrumentationOptions options; @@ -128,20 +128,34 @@ private static void ProcessException(Activity activity, Exception ex) } } +#if NET6_0_OR_GREATER + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) { - if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out string parameter)) + if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out var parameter)) { AmazonWebServiceRequest request = requestContext.OriginalRequest; - var property = request.GetType().GetProperty(parameter); - if (property != null) + try { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out string attribute)) + var property = request.GetType().GetProperty(parameter); + if (property != null) { - activity.SetTag(attribute, property.GetValue(request)); + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(request)); + } } } + catch (Exception) + { + // Guard against any reflection-related exceptions when running in AoT. + // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + } } if (AWSServiceType.IsDynamoDbService(service)) @@ -176,7 +190,7 @@ private static string FetchRequestId(IRequestContext requestContext, IResponseCo else { var request_headers = requestContext.Request.Headers; - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amzn-RequestId", out string req_id)) + if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amzn-RequestId", out var req_id)) { request_id = req_id; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index b473eb7bbf..6d0c8c9a86 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -2,7 +2,7 @@ - netstandard2.0 + net6.0;netstandard2.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) AWS client instrumentation for OpenTelemetry .NET Instrumentation.AWS- diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 0a8744bb88..7c7ca3a5dc 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -15,6 +15,7 @@ --> + From d1f27774358835e17d49abf48d05083d84023b0a Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Fri, 26 Jan 2024 19:11:38 +0000 Subject: [PATCH 0948/1499] Release native AoT fixes for AWS packages (#1551) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index b64dfe884f..ea157ffcf4 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.3 + +Released 2024-Jan-26 + * Updated dependency on AWS .NET SDK to version 3.7.300. ([#1542](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1542)) * Add target for `net6.0`. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 3b7f744f0b..10f59f5d28 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.3.0-beta.1 + +Released 2024-Jan-26 + * BREAKING: `ILambdaContext context` argument of all tracing methods of `OpenTelemetry.Instrumentation.AWSLambda.AWSLambdaWrapper` was annotated as non-nullable. * Enabled null state analysis for `OpenTelemetry.Instrumentation.AWSLambda`. diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index d8e4dd31be..8c8ebe3e34 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.4.0-beta.1 + +Released 2024-Jan-26 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Fix AWS EBS Resource Detector working on linux. From 20fd899c97114b804e1302f750796925e863bcac Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 30 Jan 2024 14:38:47 +0000 Subject: [PATCH 0949/1499] Fix markdown lint warning (#1554) --- src/OpenTelemetry.ResourceDetectors.Azure/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index b779b421fb..5b7158f457 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -41,7 +41,7 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() | deployment.environment | The deployment slot where the Azure App Service is running, such as "staging", "production", etc. | | host.id | The primary hostname for the app, excluding any custom hostnames. | | service.instance.id | The specific instance of the Azure App Service, useful in a scaled-out configuration. | -| service.name | The name of the Azure App Service. | | +| service.name | The name of the Azure App Service. | ## VM Resource Detector From 2e398458919bffbfe576eb21711770a480b131a6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 30 Jan 2024 10:59:53 -0800 Subject: [PATCH 0950/1499] [repo-ci] Sync-up with changes made in the main repo (#1555) --- .github/workflows/ci.yml | 14 +++++++++----- .github/workflows/markdownlint.yml | 9 +++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce503aa978..e33c5dd839 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,14 +13,14 @@ jobs: outputs: changes: ${{ steps.changes.outputs.changes }} steps: - - uses: AurorNZ/paths-filter@v3 + - uses: AurorNZ/paths-filter@v4 id: changes with: filters: | md: [ '**.md' ] - build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*'] + build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*', '**/*.targets', '**/*.props'] shared: ['src/Shared/**'] - code: ['**.cs', '.editorconfig'] + code: ['**.cs', '**.csproj', '.editorconfig'] aot: ['src/OpenTelemetry.Extensions.Enrichment/**'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] @@ -75,12 +75,16 @@ jobs: lint-md: needs: detect-changes - if: contains(needs.detect-changes.outputs.changes, 'md') + if: | + contains(needs.detect-changes.outputs.changes, 'md') + || contains(needs.detect-changes.outputs.changes, 'build') uses: ./.github/workflows/markdownlint.yml lint-dotnet-format: needs: detect-changes - if: contains(needs.detect-changes.outputs.changes, 'code') + if: | + contains(needs.detect-changes.outputs.changes, 'code') + || contains(needs.detect-changes.outputs.changes, 'build') uses: ./.github/workflows/dotnet-format.yml build-test-aspnet: diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index b50664ef0b..ef872cad51 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -11,8 +11,9 @@ jobs: - name: check out code uses: actions/checkout@v4 - - name: install markdownlint-cli - run: sudo npm install -g markdownlint-cli - - name: run markdownlint - run: markdownlint . + uses: DavidAnson/markdownlint-cli2-action@v14.0.0 + with: + globs: | + **/*.md + !.github/**/*.md From 7cc83255615711fab9279ec3a9501262508de0b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 06:34:52 +0100 Subject: [PATCH 0951/1499] Bump codecov/codecov-action from 3.1.5 to 3.1.6 (#1557) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/Component.BuildTest.yml | 2 +- .github/workflows/ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 147099b048..890fcf8118 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -57,7 +57,7 @@ jobs: run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} - uses: codecov/codecov-action@v3.1.5 + uses: codecov/codecov-action@v3.1.6 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e33c5dd839..81c0aaae7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -334,7 +334,7 @@ jobs: - name: Merging test results run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - - uses: codecov/codecov-action@v3.1.5 + - uses: codecov/codecov-action@v3.1.6 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} From 331262deaa135bf31587d6666a297d9fdfc2a3e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 06:43:23 +0100 Subject: [PATCH 0952/1499] Bump DavidAnson/markdownlint-cli2-action from 14.0.0 to 15.0.0 (#1556) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/markdownlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index ef872cad51..864a8a6c7a 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -12,7 +12,7 @@ jobs: uses: actions/checkout@v4 - name: run markdownlint - uses: DavidAnson/markdownlint-cli2-action@v14.0.0 + uses: DavidAnson/markdownlint-cli2-action@v15.0.0 with: globs: | **/*.md From b71fc5e8fce5188d0e11803d6fb33232d7598545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 31 Jan 2024 08:19:43 +0100 Subject: [PATCH 0953/1499] [ResourceDetector.Host] Log exception when cannot detect host.name (#1553) --- .../HostDetector.cs | 5 ++-- .../HostResourceEventSource.cs | 29 +++++++++++++++++++ ...penTelemetry.ResourceDetectors.Host.csproj | 1 + 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs b/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs index 1f6f38a508..146c6c6a76 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs @@ -25,9 +25,10 @@ public Resource Detect() new(HostSemanticConventions.AttributeHostName, Environment.MachineName), }); } - catch (InvalidOperationException) + catch (InvalidOperationException ex) { - // TODO replace comment by logging mechanism. Tracked under https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1514 + // Handling InvalidOperationException due to https://learn.microsoft.com/en-us/dotnet/api/system.environment.machinename#exceptions + HostResourceEventSource.Log.ResourceAttributesExtractException(nameof(HostDetector), ex); } return Resource.Empty; diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs b/src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs new file mode 100644 index 0000000000..e7d0509c68 --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.ResourceDetectors.Host; + +[EventSource(Name = "OpenTelemetry-ResourceDetectors-Host")] +internal class HostResourceEventSource : EventSource +{ + public static HostResourceEventSource Log = new(); + + [NonEvent] + public void ResourceAttributesExtractException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) + { + this.FailedToExtractResourceAttributes(format, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] + public void FailedToExtractResourceAttributes(string format, string exception) + { + this.WriteEvent(3, format, exception); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj index c17b08a57e..8f80566203 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj @@ -5,6 +5,7 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - Host Resource Detector. ResourceDetectors.Host- + true From a066abbcc131590c6d767235ea96ea55df94b024 Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Thu, 1 Feb 2024 06:47:10 +0100 Subject: [PATCH 0954/1499] [ResourceDetectors.AWS] Implement support for some cloud.* attributes in AWS ECS detector (#1552) --- .../AWSEC2ResourceDetector.cs | 2 +- .../AWSECSResourceDetector.cs | 15 ++++++++++++++- .../AWSSemanticConventions.cs | 2 +- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.AWS/README.md | 7 +++++-- .../AWSEC2ResourceDetectorTests.cs | 2 +- .../AWSECSResourceDetectorTests.cs | 6 ++++++ 7 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs index dc75368995..ce5e0bfffc 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs @@ -59,7 +59,7 @@ internal static List> ExtractResourceAttributes(AWS if (identity.AvailabilityZone != null) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailableZone, identity.AvailabilityZone)); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailabilityZone, identity.AvailabilityZone)); } if (identity.InstanceId != null) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index eb8ee5b328..8f91909529 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -105,6 +105,11 @@ internal static List> ExtractMetadataV4ResourceAttr new KeyValuePair(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn), }; + if (taskResponse.RootElement.TryGetProperty("AvailabilityZone", out var availabilityZoneElement) && availabilityZoneElement.ValueKind == JsonValueKind.String) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudAvailabilityZone, availabilityZoneElement.GetString()!)); + } + if (!taskResponse.RootElement.TryGetProperty("LaunchType", out var launchTypeElement)) { launchTypeElement = default; @@ -128,7 +133,15 @@ internal static List> ExtractMetadataV4ResourceAttr if (taskResponse.RootElement.TryGetProperty("TaskARN", out var taskArnElement) && taskArnElement.ValueKind == JsonValueKind.String) { - resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskArn, taskArnElement.GetString()!)); + var taskArn = taskArnElement.GetString()!; + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeEcsTaskArn, taskArn)); + + var arnParts = taskArn.Split(':'); + if (arnParts.Length > 5) + { + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudAccountID, arnParts[4])); + resourceAttributes.Add(new KeyValuePair(AWSSemanticConventions.AttributeCloudRegion, arnParts[3])); + } } if (taskResponse.RootElement.TryGetProperty("Family", out var familyElement) && familyElement.ValueKind == JsonValueKind.String) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs index 87b0262b8d..f8539f67fa 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.ResourceDetectors.AWS; internal static class AWSSemanticConventions { public const string AttributeCloudAccountID = "cloud.account.id"; - public const string AttributeCloudAvailableZone = "cloud.availability_zone"; + public const string AttributeCloudAvailabilityZone = "cloud.availability_zone"; public const string AttributeCloudPlatform = "cloud.platform"; public const string AttributeCloudProvider = "cloud.provider"; public const string AttributeCloudRegion = "cloud.region"; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 8c8ebe3e34..5d34286e6f 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Implement support for cloud.{account.id,availability_zone,region} attributes in + AWS ECS detector. + ([#1552](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1552)) + ## 1.4.0-beta.1 Released 2024-Jan-26 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/README.md b/src/OpenTelemetry.ResourceDetectors.AWS/README.md index 1ea07982f0..3d47727b1b 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/README.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/README.md @@ -37,10 +37,13 @@ The resource detectors will record the following metadata based on where your application is running: - **AWSEC2ResourceDetector**: cloud provider, cloud platform, account id, -cloud available zone, host id, host type, aws region, host name. +cloud availability zone, host id, host type, aws region, host name. - **AWSEBSResourceDetector**: cloud provider, cloud platform, service name, service namespace, instance id, service version. -- **AWSECSResourceDetector**: cloud provider, cloud platform, container id. +- **AWSECSResourceDetector**: cloud provider, cloud platform, account id, +cloud availability zone, cloud region, container id, cluster arn, task arn, +task family, task revision, launch type, container arn, log group names, +log group ids, log stream names, log stream ids. - **AWSEKSResourceDetector**: cloud provider, cloud platform, cluster name, container id. diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs index 14c5a5981a..a30cb1549e 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs @@ -24,7 +24,7 @@ public void TestExtractResourceAttributes() Assert.Equal("aws", resourceAttributes[AWSSemanticConventions.AttributeCloudProvider]); Assert.Equal("aws_ec2", resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform]); Assert.Equal("Test account id", resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID]); - Assert.Equal("Test availability zone", resourceAttributes[AWSSemanticConventions.AttributeCloudAvailableZone]); + Assert.Equal("Test availability zone", resourceAttributes[AWSSemanticConventions.AttributeCloudAvailabilityZone]); Assert.Equal("Test instance id", resourceAttributes[AWSSemanticConventions.AttributeHostID]); Assert.Equal("Test instance type", resourceAttributes[AWSSemanticConventions.AttributeHostType]); Assert.Equal("Test aws region", resourceAttributes[AWSSemanticConventions.AttributeCloudRegion]); diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs index d73363746b..a47e560888 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs @@ -73,6 +73,9 @@ public async void TestEcsMetadataV4Ec2() Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudProvider], "aws"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID], "111122223333"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2d"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudRegion], "us-west-2"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsLaunchtype], "ec2"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"); @@ -101,6 +104,9 @@ public async void TestEcsMetadataV4Fargate() Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudProvider], "aws"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudPlatform], "aws_ecs"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID], "111122223333"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2a"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudRegion], "us-west-2"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsLaunchtype], "fargate"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3"); From 184ac6fbe39bc055997a5bdcc770c5a443efc853 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 1 Feb 2024 16:54:23 -0800 Subject: [PATCH 0955/1499] Bump codecov/codecov-action from 3.1.5 to 4.0.1 (#1561) --- .github/workflows/Component.BuildTest.yml | 4 +++- .github/workflows/ci.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 890fcf8118..a73765ca62 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -57,13 +57,15 @@ jobs: run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} - uses: codecov/codecov-action@v3.1.6 + uses: codecov/codecov-action@v4 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} TFM: ${{ matrix.version }} + token: ${{ secrets.CODECOV_TOKEN }} with: file: TestResults/Cobertura.xml env_vars: OS,TFM flags: ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} name: Code Coverage for ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} on [${{ matrix.os }}.${{ matrix.version }}] + codecov_yml_path: .github/codecov.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81c0aaae7a..634dca703b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -334,16 +334,18 @@ jobs: - name: Merging test results run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - - uses: codecov/codecov-action@v3.1.6 + - uses: codecov/codecov-action@v4 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} TFM: ${{ matrix.version }} + token: ${{ secrets.CODECOV_TOKEN }} with: file: TestResults/Cobertura.xml env_vars: OS,TFM flags: unittests-Solution name: Code Coverage for solution on [${{ matrix.os }}.${{ matrix.version }}] + codecov_yml_path: .github/codecov.yml verify-aot-compat: needs: detect-changes From 8f72b7589b5515f5d9136b15bb3e06cc33883243 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Fri, 2 Feb 2024 10:33:14 -0800 Subject: [PATCH 0956/1499] [Exporter.Geneva] Skip dispose for ETW singleton of GenevaMetricExporter (#1537) --- .../CHANGELOG.md | 4 +++ .../Metrics/GenevaMetricExporter.cs | 9 ++++-- .../Transport/MetricEtwDataTransport.cs | 27 +++++++++++++---- .../Transport/MetricUnixDataTransport.cs | 2 +- .../TLDExporter/TldLogExporter.cs | 2 +- .../TLDExporter/TldTraceExporter.cs | 2 +- .../GenevaMetricExporterTests.cs | 29 +++++++++++++++++++ 7 files changed, 64 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index bcbbc3f0bb..efa145b755 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fix a bug in `GenevaMetricExporter` where the `MetricEtwDataTransport` singleton + is disposed. + ([#1537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1537)) + ## 1.7.0 Released 2023-Dec-11 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index a7ab27898d..9383e80330 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -74,7 +74,7 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) case TransportProtocol.Unspecified: if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - this.metricDataTransport = MetricEtwDataTransport.Shared; + this.metricDataTransport = MetricEtwDataTransport.Instance; break; } else @@ -268,7 +268,12 @@ protected override void Dispose(bool disposing) { try { - this.metricDataTransport?.Dispose(); + // The ETW data transport singleton on Windows should NOT be disposed. + // On Linux, Unix Domain Socket is used and should be disposed. + if (this.metricDataTransport != MetricEtwDataTransport.Instance) + { + this.metricDataTransport.Dispose(); + } } catch (Exception ex) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index f83b10d9ee..61c06fa52d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -10,13 +10,9 @@ namespace OpenTelemetry.Exporter.Geneva; internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport { private readonly int fixedPayloadEndIndex; + private bool isDisposed; - static MetricEtwDataTransport() - { - Shared = new(); - } - - public static readonly MetricEtwDataTransport Shared; + public static MetricEtwDataTransport Instance { get; private set; } = new(); private MetricEtwDataTransport() { @@ -57,4 +53,23 @@ private void ExternallyAggregatedDoubleDistributionMetric() private void TLVMetricEvent() { } + + protected override void Dispose(bool disposing) + { + if (this.isDisposed) + { + return; + } + + if (disposing) + { + // No managed resources to release. + // The singleton instance is kept alive for the lifetime of the application. + // Set the instance to null so that future calls to the singleton property can fail explicitly. + Instance = null; + } + + this.isDisposed = true; + base.Dispose(disposing); + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs index 98d12a22f7..6ae7704ae1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs @@ -33,7 +33,7 @@ public void Dispose() return; } - this.udsDataTransport?.Dispose(); + this.udsDataTransport.Dispose(); this.isDisposed = true; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 7e9c6f72a5..318cb02092 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -160,7 +160,7 @@ public void Dispose() try { // DO NOT Dispose eventBuilder, keyValuePairs, and partCFields as they are static - this.eventProvider?.Dispose(); + this.eventProvider.Dispose(); this.serializationData?.Dispose(); } catch (Exception ex) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index b5967affd7..95e4d15b82 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -153,7 +153,7 @@ public void Dispose() try { // DO NOT Dispose eventBuilder, keyValuePairs, and partCFields as they are static - this.eventProvider?.Dispose(); + this.eventProvider.Dispose(); } catch (Exception ex) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 2a254a1490..05043cd8f3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -251,6 +251,35 @@ public void SuccessfulExportOnLinux() } } + [Fact] + public void MultipleCallsOnWindowsReusesSingletonEtwDataTransport() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + var singleton = MetricEtwDataTransport.Instance; + this.EmitMetrics("one"); + Assert.Equal(singleton, MetricEtwDataTransport.Instance); + this.EmitMetrics("two"); + Assert.Equal(singleton, MetricEtwDataTransport.Instance); + } + } + + private void EmitMetrics(string attempt) + { + using var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() + .AddMeter("*") + .AddGenevaMetricExporter(x => + { + x.MetricExportIntervalMilliseconds = 1000; + x.ConnectionString = "Account=OTelGeneva;Namespace=MeteringSample"; + }) + .Build(); + + using var meter = new Meter("MeterName", "0.0.1"); + var counter = meter.CreateCounter("counter_" + attempt); + counter.Add(1); + } + [Theory] [InlineData(true)] [InlineData(false)] From b73db3014964b4173a71b342dbc38923fadbe2fb Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 2 Feb 2024 15:31:49 -0800 Subject: [PATCH 0957/1499] [geneva] Add guidance for configuring options using services retrieved from DI (#1563) Co-authored-by: Reiley Yang --- src/OpenTelemetry.Exporter.Geneva/README.md | 71 ++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 270fcb92ba..4bb7870c14 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -157,7 +157,7 @@ values. * `ILogger`: This is marked as pass-through ("*") so it will be sanitized as "MyPartnerProductThing" table name -##### Pass-through table name mapping rules +###### Pass-through table name mapping rules When "pass-through" mapping is enabled for a given log message the runtime [category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) @@ -171,6 +171,57 @@ value will be converted into a valid table name. * Only the first 50 valid characters will be used. +#### How to configure GenevaExporterOptions using dependency injection + +##### Tracing + +> [!NOTE] +> In this example named options ('GenevaTracing') are used. This is because + `GenevaExporterOptions` is shared by both logging & tracing. In a future + version named options will also be supported in logging so it is recommended + to use named options now for tracing in order to future-proof this code. + +```csharp +// Step 1: Turn on tracing and register GenevaTraceExporter. +builder.Services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddGenevaTraceExporter( + "GenevaTracing", // Tell GenevaTraceExporter to retrieve options using the 'GenevaTracing' name + _ => { })); + +// Step 2: Use Options API to configure GenevaExporterOptions using services +// retrieved from the dependency injection container +builder.Services + .AddOptions("GenevaTracing") // Register options with the 'GenevaTracing' name + .Configure((exporterOptions, configuration) => + { + exporterOptions.ConnectionString = configuration.GetValue("OpenTelemetry:Tracing:GenevaConnectionString") + ?? throw new InvalidOperationException("GenevaConnectionString was not found in application configuration"); + }); +``` + +##### Logging + +```csharp +// Step 1: Turn on logging. +builder.Logging.AddOpenTelemetry(); + +// Step 2: Use Options API to configure OpenTelemetryLoggerOptions using +// services retrieved from the dependency injection container +builder.Services + .AddOptions() + .Configure((loggerOptions, configuration) => + { + // Add GenevaLogExporter and configure GenevaExporterOptions using + // services retrieved from the dependency injection container + loggerOptions.AddGenevaLogExporter(exporterOptions => + { + exporterOptions.ConnectionString = configuration.GetValue("OpenTelemetry:Logging:GenevaConnectionString") + ?? throw new InvalidOperationException("GenevaConnectionString was not found in application configuration"); + }); + }); +``` + ### Enable Metrics This snippet shows how to configure the Geneva Exporter for Metrics @@ -214,6 +265,24 @@ is 20000 milliseconds. This is a collection of the dimensions that will be applied to _every_ metric exported by the exporter. +#### How to configure GenevaMetricExporterOptions using dependency injection + +```csharp +// Step 1: Turn on metrics and register GenevaMetricExporter. +builder.Services.AddOpenTelemetry() + .WithMetrics(builder => builder.AddGenevaMetricExporter()); + +// Step 2: Use Options API to configure GenevaMetricExporterOptions using +// services retrieved from the dependency injection container +builder.Services + .AddOptions() + .Configure((exporterOptions, configuration) => + { + exporterOptions.ConnectionString = configuration.GetValue("OpenTelemetry:Metrics:GenevaConnectionString") + ?? throw new InvalidOperationException("GenevaConnectionString was not found in application configuration"); + }); +``` + ## Troubleshooting Before digging into a problem, check if you hit a known issue by looking at the From 410ddc62a4795c627c3e5e931b87d419f11f5152 Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Mon, 5 Feb 2024 05:36:41 +0000 Subject: [PATCH 0958/1499] Fix native AoT test scripts (#1540) --- .github/workflows/verifyaotcompat.yml | 3 +-- build/test-aot-compatibility.ps1 | 17 +++++++++++++---- ...penTelemetry.AotCompatibility.TestApp.csproj | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/verifyaotcompat.yml b/.github/workflows/verifyaotcompat.yml index c437c70c9c..1a6cc014c7 100644 --- a/.github/workflows/verifyaotcompat.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - os: [ ubuntu-latest ] + os: [ ubuntu-latest, windows-latest ] version: [ net8.0 ] runs-on: ${{ matrix.os }} @@ -19,4 +19,3 @@ jobs: - name: publish AOT testApp, assert static analysis warning count, and run the app shell: pwsh run: .\build\test-aot-compatibility.ps1 ${{ matrix.version }} - diff --git a/build/test-aot-compatibility.ps1 b/build/test-aot-compatibility.ps1 index ff400b667b..5abe054bec 100644 --- a/build/test-aot-compatibility.ps1 +++ b/build/test-aot-compatibility.ps1 @@ -7,7 +7,7 @@ $actualWarningCount = 0 foreach ($line in $($publishOutput -split "`r`n")) { - if ($line -like "*analysis warning IL*") + if (($line -like "*analysis warning IL*") -or ($line -like "*analysis error IL*")) { Write-Host $line $actualWarningCount += 1 @@ -17,10 +17,19 @@ foreach ($line in $($publishOutput -split "`r`n")) Write-Host "Actual warning count is:", $actualWarningCount $expectedWarningCount = 0 -pushd $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/bin/Release/$targetNetFramework/linux-x64 +if ($LastExitCode -ne 0) +{ + Write-Host "There was an error while publishing AotCompatibility Test App. LastExitCode is:", $LastExitCode + Write-Host $publishOutput +} + +$runtime = $IsWindows ? "win-x64" : ($IsMacOS ? "macos-x64" : "linux-x64") +$app = $IsWindows ? "./OpenTelemetry.AotCompatibility.TestApp.exe" : "./OpenTelemetry.AotCompatibility.TestApp" + +Push-Location $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/bin/Release/$targetNetFramework/$runtime Write-Host "Executing test App..." -./OpenTelemetry.AotCompatibility.TestApp +$app Write-Host "Finished executing test App" if ($LastExitCode -ne 0) @@ -28,7 +37,7 @@ if ($LastExitCode -ne 0) Write-Host "There was an error while executing AotCompatibility Test App. LastExitCode is:", $LastExitCode } -popd +Pop-Location $testPassed = 0 if ($actualWarningCount -ne $expectedWarningCount) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 7c7ca3a5dc..f982a95588 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -3,7 +3,7 @@ Exe net8.0 - true + true false true @@ -11,7 +11,7 @@ From cc7eb70fac77de32e723e549a07720652e397adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 5 Feb 2024 06:45:30 +0100 Subject: [PATCH 0959/1499] [Instrumentation.EntityFrameworkCore] Stop emitting db.statement_type attribute (#1559) --- .../CHANGELOG.md | 3 +++ .../Implementation/EntityFrameworkDiagnosticListener.cs | 3 --- src/Shared/SpanAttributeConstants.cs | 1 - .../EntityFrameworkDiagnosticListenerTests.cs | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 77d8c86da5..155c2bd5c3 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* **Breaking Change**: Stop emitting `db.statement_type` attribute. + ([#1559](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1559)) + ## 1.0.0-beta.9 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index d53a1edefc..b0392ff40d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -194,7 +194,6 @@ public override void OnCustom(string name, Activity? activity, object? payload) switch (commandType) { case CommandType.StoredProcedure: - activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.StoredProcedure)); if (this.options.SetDbStatementForStoredProcedure) { activity.AddTag(AttributeDbStatement, commandText); @@ -203,7 +202,6 @@ public override void OnCustom(string name, Activity? activity, object? payload) break; case CommandType.Text: - activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.Text)); if (this.options.SetDbStatementForText) { activity.AddTag(AttributeDbStatement, commandText); @@ -212,7 +210,6 @@ public override void OnCustom(string name, Activity? activity, object? payload) break; case CommandType.TableDirect: - activity.AddTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.TableDirect)); break; } } diff --git a/src/Shared/SpanAttributeConstants.cs b/src/Shared/SpanAttributeConstants.cs index 4d0f6dfa53..9c21fb3bf2 100644 --- a/src/Shared/SpanAttributeConstants.cs +++ b/src/Shared/SpanAttributeConstants.cs @@ -11,7 +11,6 @@ internal static class SpanAttributeConstants #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public const string StatusCodeKey = "otel.status_code"; public const string StatusDescriptionKey = "otel.status_description"; - public const string DatabaseStatementTypeKey = "db.statement_type"; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 0f6c7fc0e6..80a72fa847 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -241,7 +241,6 @@ private static void VerifyActivityData(Activity activity, bool isError = false, Assert.DoesNotContain(activity.Tags, t => t.Key == EntityFrameworkDiagnosticListener.AttributePeerService); Assert.Equal(altDisplayName ?? "main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); - Assert.Equal(CommandType.Text.ToString(), activity.Tags.FirstOrDefault(t => t.Key == SpanAttributeConstants.DatabaseStatementTypeKey).Value); if (!isError) { From 468f4aede7d16b6e853246815e39da6135f35cf5 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 5 Feb 2024 09:20:45 -0800 Subject: [PATCH 0960/1499] [ResourceDetectors.Azure] Azure Container Apps Resource Detector (#1565) Co-authored-by: Vishwesh Bankwar --- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 + .../netstandard2.0/PublicAPI.Unshipped.txt | 3 + .../AzureContainerAppsResourceDetector.cs | 55 +++++++++++++++++++ .../CHANGELOG.md | 5 ++ .../ResourceAttributeConstants.cs | 6 ++ .../AzureResourceDetectorTests.cs | 32 +++++++++++ 6 files changed, 104 insertions(+) create mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt index 00226a19b1..742d5f3fed 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,6 +1,9 @@ OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector +OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.AzureContainerAppsResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.AzureVMResourceDetector() -> void OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 00226a19b1..742d5f3fed 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,6 +1,9 @@ OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! +OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector +OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.AzureContainerAppsResourceDetector() -> void +OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.AzureVMResourceDetector() -> void OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs new file mode 100644 index 0000000000..a9129630dd --- /dev/null +++ b/src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using OpenTelemetry.Resources; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.ResourceDetectors.Azure; + +/// +/// Resource detector for Azure Container Apps environment. +/// +public sealed class AzureContainerAppsResourceDetector : IResourceDetector +{ + internal static readonly IReadOnlyDictionary AzureContainerResourceAttributes = new Dictionary + { + { ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar }, + { ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppsRevisionEnvVar }, + }; + + /// + public Resource Detect() + { + List> attributeList = new(); + + try + { + var containerAppName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar); + + if (containerAppName != null) + { + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, containerAppName)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureContainerAppsPlatformValue)); + + foreach (var kvp in AzureContainerResourceAttributes) + { + var attributeValue = Environment.GetEnvironmentVariable(kvp.Value); + if (attributeValue != null) + { + attributeList.Add(new KeyValuePair(kvp.Key, attributeValue)); + } + } + } + } + catch + { + // TODO: log exception. + return Resource.Empty; + } + + return new Resource(attributeList); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 9959deb5fb..c50444b123 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added Azure Container Apps Resource Detector to generate attributes: + `service.name`, `service.version`, `service.instance.id`, `cloud.provider` and + `cloud.platform`. + ([#1565](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1565)) + ## 1.0.0-beta.4 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs index 6597a021fd..4cbb552f7d 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs +++ b/src/OpenTelemetry.ResourceDetectors.Azure/ResourceAttributeConstants.cs @@ -22,8 +22,14 @@ internal sealed class ResourceAttributeConstants internal const string AppServiceSlotNameEnvVar = "WEBSITE_SLOT_NAME"; internal const string AppServiceStampNameEnvVar = "WEBSITE_HOME_STAMPNAME"; + // Azure Container Apps environment variables + internal const string AzureContainerAppsNameEnvVar = "CONTAINER_APP_NAME"; + internal const string AzureContainerAppsReplicaNameEnvVar = "CONTAINER_APP_REPLICA_NAME"; + internal const string AzureContainerAppsRevisionEnvVar = "CONTAINER_APP_REVISION"; + // Azure resource attributes constant values internal const string AzureAppServicePlatformValue = "azure_app_service"; internal const string AzureCloudProviderValue = "azure"; internal const string AzureVmCloudPlatformValue = "azure_vm"; + internal const string AzureContainerAppsPlatformValue = "azure_container_apps"; } diff --git a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs index 7f6f806100..91fd9c374c 100644 --- a/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Azure.Tests/AzureResourceDetectorTests.cs @@ -95,11 +95,43 @@ public void TestAzureVmResourceDetector() } } + [Fact] + public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes() + { + try + { + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes) + { + Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); + } + + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar, "containerAppName"); + } + catch + { + } + + var resource = ResourceBuilder.CreateEmpty().AddDetector(new AzureContainerAppsResourceDetector()).Build(); + Assert.NotNull(resource); + + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppName"), resource.Attributes); + + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes) + { + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + } + } + public void Dispose() { foreach (var kvp in AppServiceResourceDetector.AppServiceResourceAttributes) { Environment.SetEnvironmentVariable(kvp.Value, null); } + + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes) + { + Environment.SetEnvironmentVariable(kvp.Value, null); + } } } From 8e3057ed82143abc9e4aaaf6d5d36e0a531b98c7 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 5 Feb 2024 10:25:35 -0800 Subject: [PATCH 0961/1499] [wcf] Security fix: GHSA-vh55-786g-wjwj (#1566) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 8 ++++++++ .../OpenTelemetry.Instrumentation.Wcf.csproj | 1 + 2 files changed, 9 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index fd874bca39..cc0fa1b82d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* Fixed [GHSA-vh55-786g-wjwj](https://github.com/advisories/GHSA-vh55-786g-wjwj) + by bumping the + [System.Security.Cryptography.Xml](https://www.nuget.org/packages/System.Security.Cryptography.Xml) + package version to `4.7.1` (dependency chain: + `OpenTelemetry.Instrumentation.Wcf` -> `System.ServiceModel.Primitives` -> + `System.Private.ServiceModel` -> `System.Security.Cryptography.Xml`). + ([#1566](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1566)) + ## 1.0.0-rc.14 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 7d8b688310..25be49ab72 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -19,6 +19,7 @@ + From 9919348b8d69e07c637601872d39163aa00e0149 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 10:38:13 -0800 Subject: [PATCH 0962/1499] Bump al-cheb/configure-pagefile-action from 1.3 to 1.4 (#1564) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 07744cc446..78a76af786 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -26,7 +26,7 @@ jobs: steps: - name: configure Pagefile - uses: al-cheb/configure-pagefile-action@v1.3 + uses: al-cheb/configure-pagefile-action@v1.4 with: minimum-size: 8GB maximum-size: 32GB From 9832096f33783e2488176d804ae457d10318a6c5 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Mon, 5 Feb 2024 15:00:37 -0800 Subject: [PATCH 0963/1499] [AzureResourceDetector] Update Readme for ACA and ChangeLog for 1.0.0-beta.5 release (#1567) --- .../CHANGELOG.md | 4 +++ .../README.md | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index c50444b123..56b0d0cd62 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2024-Feb-05 + * Added Azure Container Apps Resource Detector to generate attributes: `service.name`, `service.version`, `service.instance.id`, `cloud.provider` and `cloud.platform`. diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 5b7158f457..91095ec2af 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -75,3 +75,29 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() | os.type | The type of operating system running on the VM, such as "Linux" or "Windows". | | os.version | The version of the operating system running on the VM. | | service.instance.id | An identifier for a specific instance of the service running on the Azure VM, for example, "02aab8a4-74ef-476e-8182-f6d2ba4166a6". | + +## Azure Container Apps Resource Detector + +Adds resource attributes for the applications running in Azure Container Apps. +The following example shows how to add `AzureContainerAppsResourceDetector` to +`TracerProvider` configuration, but this can be added to logs and metrics as +well. + +```csharp +using OpenTelemetry; +using OpenTelemetry.ResourceDetectors.Azure; +using OpenTelemetry.Resources; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .ConfigureResource(resource => resource.AddDetector(new AzureContainerAppsResourceDetector())) + .Build(); +``` + +| Attribute | Description | +|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| cloud.platform | The cloud platform. Here, it's always "azure_container_apps". | +| cloud.provider | The cloud service provider. In this context, it's always "azure". | +| service.instance.id | Represents the specific instance ID of Azure Container Apps, useful in scaled-out configurations. | +| service.name | The name of the Azure Container Apps. | +| service.version | The current revision or version of Azure Container Apps. | From cd77d0d5b89e4db9f4e56d3646524800b577b5ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 7 Feb 2024 17:09:42 +0100 Subject: [PATCH 0964/1499] Release AspNet, EFCore instrumentation and Container Resource detector (#1573) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index ef49bd4e4c..faad349ed4 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0-beta.2 + +Released 2024-Feb-07 + ## 1.7.0-beta.1 Released 2023-Dec-20 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 245eb9612b..4a2f513a6f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.7.0-beta.2 + +Released 2024-Feb-07 + * Fix description for `http.server.request.duration` metric. ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 155c2bd5c3..6e00e3a425 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.10 + +Released 2024-Feb-07 + * **Breaking Change**: Stop emitting `db.statement_type` attribute. ([#1559](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1559)) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index e6bbe5c616..bd60feed2b 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.6 + +Released 2024-Feb-07 + * **Breaking** Changed target framework from .NET Standard 2.0 to .NET 6.0. It drops support for .NET Framework. ([#1536](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1536)) From 76213459b969811d5970964281e95f56e71bdc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 7 Feb 2024 18:11:41 +0100 Subject: [PATCH 0965/1499] [Instrumentation.Wcf] Release 1.0.0-rc.15 (#1574) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index cc0fa1b82d..36fee98fcb 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.15 + +Released 2024-Feb-07 + * Fixed [GHSA-vh55-786g-wjwj](https://github.com/advisories/GHSA-vh55-786g-wjwj) by bumping the [System.Security.Cryptography.Xml](https://www.nuget.org/packages/System.Security.Cryptography.Xml) From e7239a13b7a2315c93c11ef486decba523dfc52e Mon Sep 17 00:00:00 2001 From: anoopbabu29 <32779456+anoopbabu29@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:58:01 -0500 Subject: [PATCH 0966/1499] Minor adjustment to the AWS event source (#1571) Co-authored-by: Vishwesh Bankwar Co-authored-by: Cijo Thomas --- .../AWSResourcesEventSource.cs | 4 ++-- .../Http/ServerCertificateValidationProvider.cs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs index 4238241190..e34bb70909 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs @@ -24,12 +24,12 @@ public void ResourceAttributesExtractException(string format, Exception ex) [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] public void FailedToExtractResourceAttributes(string format, string exception) { - this.WriteEvent(3, format, exception); + this.WriteEvent(1, format, exception); } [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] public void FailedToValidateCertificate(string format, string error) { - this.WriteEvent(4, format, error); + this.WriteEvent(2, format, error); } } diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs index 1538215391..da13c70014 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs @@ -84,24 +84,24 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo { if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNotAvailable"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNotAvailable occurred"); } if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate due to RemoteCertificateNameMismatch"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNameMismatch occurred"); } } if (chain == null) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate chain is null."); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate chain is null."); return false; } if (cert == null) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to validate certificate. Certificate is null."); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate is null."); return false; } @@ -123,7 +123,7 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo } } - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), $"Failed to validate certificate due to {chainErrors}"); + AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), chainErrors); } // check if at least one certificate in the chain is in our trust list From 89ff089bf07fe8576e7cf2027a020a305537ad91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 7 Feb 2024 22:05:22 +0100 Subject: [PATCH 0967/1499] [Instrumentation.EntityFrameworkCore] Improve changelog (#1575) Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 6e00e3a425..8b03c4e272 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -7,6 +7,7 @@ Released 2024-Feb-07 * **Breaking Change**: Stop emitting `db.statement_type` attribute. + This attribute never was part of the [semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md#call-level-attributes). ([#1559](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1559)) ## 1.0.0-beta.9 From 2cc336f639cf65d3b229500f765577aa8761c060 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 12 Feb 2024 23:55:42 +0200 Subject: [PATCH 0968/1499] Align ResolveSpanStatusForHttpStatusCode implementation with main repo (#1577) --- src/Shared/SpanHelper.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Shared/SpanHelper.cs b/src/Shared/SpanHelper.cs index 51d6bb4acb..9cd0503e8c 100644 --- a/src/Shared/SpanHelper.cs +++ b/src/Shared/SpanHelper.cs @@ -40,12 +40,13 @@ public static Status ResolveSpanStatusForHttpStatusCode(int httpStatusCode) /// Resolved span for the Http status code. public static Status ResolveSpanStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) { - var upperBound = kind == ActivityKind.Client ? 399 : 499; - if (httpStatusCode >= 100 && httpStatusCode <= upperBound) + var lowerBound = kind == ActivityKind.Client ? 400 : 500; + var upperBound = 599; + if (httpStatusCode >= lowerBound && httpStatusCode <= upperBound) { - return Status.Unset; + return Status.Error; } - return Status.Error; + return Status.Unset; } } From da14596fd7328fd05135ceb5bbaa6b85da597105 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Feb 2024 13:09:08 -0800 Subject: [PATCH 0969/1499] [repo] CodeQL workflow tweaks (#1581) --- .github/workflows/codeql-analysis.yml | 29 +++++---------------------- opentelemetry-dotnet-contrib.proj | 12 +++++++++-- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 78a76af786..1ca6a8e383 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -7,7 +7,7 @@ name: "CodeQL" on: schedule: - - cron: '0 0 * * *' # once in a day at 00:00 + - cron: '0 0 * * *' # once in a day at 00:00 workflow_dispatch: jobs: @@ -18,11 +18,7 @@ jobs: strategy: fail-fast: false matrix: - # Override automatic language detection by changing the below list - # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] language: ['csharp'] - # Learn more... - # https://docs.github.com/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection steps: - name: configure Pagefile @@ -35,31 +31,16 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release + - name: dotnet pack opentelemetry-dotnet-contrib.proj + run: dotnet pack opentelemetry-dotnet-contrib.proj --configuration Release - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 diff --git a/opentelemetry-dotnet-contrib.proj b/opentelemetry-dotnet-contrib.proj index db5061764e..4bf9697cd7 100644 --- a/opentelemetry-dotnet-contrib.proj +++ b/opentelemetry-dotnet-contrib.proj @@ -2,16 +2,24 @@ - + - + + + + + + + + + From bba43f4e1e8d428fcd7ffd28506b03669ba16059 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 14 Feb 2024 15:18:20 -0800 Subject: [PATCH 0970/1499] [aspnet-examples] Fix security warnings coming from config files (#1582) --- examples/AspNet/Views/Web.config | 5 +++++ examples/AspNet/Web.config | 5 +++++ examples/wcf/server-aspnetframework/Web.config | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/examples/AspNet/Views/Web.config b/examples/AspNet/Views/Web.config index b9508f1106..e8fc796ede 100644 --- a/examples/AspNet/Views/Web.config +++ b/examples/AspNet/Views/Web.config @@ -25,6 +25,11 @@ + + + + + diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index 5dd986c90a..5dd32873b1 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -15,6 +15,11 @@ + + + + + diff --git a/examples/wcf/server-aspnetframework/Web.config b/examples/wcf/server-aspnetframework/Web.config index 97259f8cc7..999a674e80 100644 --- a/examples/wcf/server-aspnetframework/Web.config +++ b/examples/wcf/server-aspnetframework/Web.config @@ -30,10 +30,14 @@ + + + + + - From 2f3a6949a4dd2ebbcd774ad5c9f0e5df382d2414 Mon Sep 17 00:00:00 2001 From: Stanislav Perekrestov Date: Thu, 15 Feb 2024 20:49:14 +0100 Subject: [PATCH 0971/1499] [OpenTelemetry.Exporter.Stackdriver] Release 1.0.0-beta.5 (#1579) (#1580) Co-authored-by: Vishwesh Bankwar --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index c0e283e684..068b3880b8 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2024-Feb-15 + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Add support of a native "gRPC for .NET" for apps targeting .NET 6.0 or later. From bfe42e205b9e0703254a165da962d161e4d5d453 Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Thu, 22 Feb 2024 12:30:08 -0800 Subject: [PATCH 0972/1499] bugfix: AWS SQS MD5 Hash Mismatch (#1572) --- .../CHANGELOG.md | 3 + .../AWSPropagatorPipelineHandler.cs | 68 +++++++++++++++ .../Implementation/AWSServiceHelper.cs | 2 +- .../Implementation/AWSServiceType.cs | 4 +- .../AWSTracingPipelineCustomizer.cs | 15 +++- .../AWSTracingPipelineHandler.cs | 39 ++++----- .../Implementation/SnsRequestContextHelper.cs | 20 +---- .../Implementation/SqsRequestContextHelper.cs | 20 +---- .../TracerProviderBuilderExtensions.cs | 2 +- .../RequestContextHelperTests.cs | 87 ++++++++++--------- .../Implementation/TestsHelper.cs | 30 ++++--- .../TestAWSClientInstrumentation.cs | 5 +- .../TestRequest.cs | 9 +- 13 files changed, 184 insertions(+), 120 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index ea157ffcf4..f5c9d98b94 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* BREAKING: Switched AWSServiceName tag to use ServiceId instead of ServiceName + ([#1572](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1572)) + ## 1.1.0-beta.3 Released 2024-Jan-26 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs new file mode 100644 index 0000000000..3f6ade4fd1 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Extensions.AWS.Trace; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation; + +/// +/// Uses to inject the current Activity Context and +/// Baggage into the outgoing AWS SDK Request. +/// +/// Must execute after the AWS SDK has marshalled (ie serialized) +/// the outgoing request object so that it can work with the 's +/// . +/// +internal class AWSPropagatorPipelineHandler : PipelineHandler +{ + private static readonly AWSXRayPropagator AwsPropagator = new(); + + private static readonly Action, string, string> Setter = (carrier, name, value) => + { + carrier[name] = value; + }; + + /// + /// Rely on the the for retrieving the current + /// context. + /// + private readonly AWSTracingPipelineHandler tracingPipelineHandler; + + public AWSPropagatorPipelineHandler(AWSTracingPipelineHandler tracingPipelineHandler) + { + this.tracingPipelineHandler = tracingPipelineHandler; + } + + public override void InvokeSync(IExecutionContext executionContext) + { + this.ProcessBeginRequest(executionContext); + + base.InvokeSync(executionContext); + } + + public override async Task InvokeAsync(IExecutionContext executionContext) + { + this.ProcessBeginRequest(executionContext); + + return await base.InvokeAsync(executionContext).ConfigureAwait(false); + } + + private void ProcessBeginRequest(IExecutionContext executionContext) + { + if (this.tracingPipelineHandler.Activity == null) + { + return; + } + + AwsPropagator.Inject( + new PropagationContext(this.tracingPipelineHandler.Activity.Context, Baggage.Current), + executionContext.RequestContext.Request.Headers, + Setter); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index e940ba2f39..59661d6e4e 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -21,7 +21,7 @@ internal class AWSServiceHelper }; internal static string GetAWSServiceName(IRequestContext requestContext) - => Utils.RemoveAmazonPrefixFromServiceName(requestContext.Request.ServiceName); + => Utils.RemoveAmazonPrefixFromServiceName(requestContext.ServiceMetaData.ServiceId); internal static string GetAWSOperationName(IRequestContext requestContext) { diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs index 23c73b344a..07ccd22a36 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs @@ -7,9 +7,9 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSServiceType { - internal const string DynamoDbService = "DynamoDBv2"; + internal const string DynamoDbService = "DynamoDB"; internal const string SQSService = "SQS"; - internal const string SNSService = "SimpleNotificationService"; // SNS + internal const string SNSService = "SNS"; internal static bool IsDynamoDbService(string service) => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index d91bd8caf7..2a9538bb6c 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -7,6 +7,10 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; +/// +/// Wires and +/// into the AWS so they can inject trace headers and wrap sdk calls in spans. +/// internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer { private readonly AWSClientInstrumentationOptions options; @@ -31,6 +35,15 @@ public void Customize(Type serviceClientType, RuntimePipeline pipeline) return; } - pipeline.AddHandlerBefore(new AWSTracingPipelineHandler(this.options)); + var tracingPipelineHandler = new AWSTracingPipelineHandler(this.options); + var propagatingPipelineHandler = new AWSPropagatorPipelineHandler(tracingPipelineHandler); + + // AWSTracingPipelineHandler must execute early in the AWS SDK pipeline + // in order to manipulate outgoing requests objects before they are marshalled (ie serialized). + pipeline.AddHandlerBefore(tracingPipelineHandler); + + // AWSPropagatorPipelineHandler executes after the AWS SDK has marshalled (ie serialized) + // the outgoing request object so that it can work with the request's Headers + pipeline.AddHandlerBefore(propagatingPipelineHandler); } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 2383c9f8ba..fe4dfc3636 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -2,28 +2,27 @@ // SPDX-License-Identifier: Apache-2.0 using System; -using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using Amazon.Runtime; using Amazon.Runtime.Internal; using Amazon.Util; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Extensions.AWS.Trace; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation; +/// +/// Wraps the outgoing AWS SDK Request in a Span and adds additional AWS specific Tags. +/// Depending on the target AWS Service, additional request specific information may be injected as well. +/// +/// This must execute early in the AWS SDK pipeline +/// in order to manipulate outgoing requests objects before they are marshalled (ie serialized). +/// internal sealed class AWSTracingPipelineHandler : PipelineHandler { internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; - private static readonly AWSXRayPropagator AwsPropagator = new(); - private static readonly Action, string, string> Setter = (carrier, name, value) => - { - carrier[name] = value; - }; - private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName); private readonly AWSClientInstrumentationOptions options; @@ -33,27 +32,29 @@ public AWSTracingPipelineHandler(AWSClientInstrumentationOptions options) this.options = options; } + public Activity? Activity { get; private set; } + public override void InvokeSync(IExecutionContext executionContext) { - var activity = this.ProcessBeginRequest(executionContext); + this.Activity = this.ProcessBeginRequest(executionContext); try { base.InvokeSync(executionContext); } catch (Exception ex) { - if (activity != null) + if (this.Activity != null) { - ProcessException(activity, ex); + ProcessException(this.Activity, ex); } throw; } finally { - if (activity != null) + if (this.Activity != null) { - ProcessEndRequest(executionContext, activity); + ProcessEndRequest(executionContext, this.Activity); } } } @@ -62,25 +63,25 @@ public override async Task InvokeAsync(IExecutionContext executionContext) { T? ret = null; - var activity = this.ProcessBeginRequest(executionContext); + this.Activity = this.ProcessBeginRequest(executionContext); try { ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); } catch (Exception ex) { - if (activity != null) + if (this.Activity != null) { - ProcessException(activity, ex); + ProcessException(this.Activity, ex); } throw; } finally { - if (activity != null) + if (this.Activity != null) { - ProcessEndRequest(executionContext, activity); + ProcessEndRequest(executionContext, this.Activity); } } @@ -241,8 +242,6 @@ private static string FetchRequestId(IRequestContext requestContext, IResponseCo AddRequestSpecificInformation(activity, requestContext, service); } - AwsPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), requestContext.Request.Headers, Setter); - return activity; } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs index 9a5eba3b8f..163e3b03af 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using Amazon.Runtime; -using Amazon.Runtime.Internal; using Amazon.SimpleNotificationService.Model; namespace OpenTelemetry.Instrumentation.AWS.Implementation; @@ -18,9 +17,8 @@ internal class SnsRequestContextHelper internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary attributes) { - var parameters = context.Request?.ParameterCollection; var originalRequest = context.OriginalRequest as PublishRequest; - if (originalRequest?.MessageAttributes == null || parameters == null) + if (originalRequest?.MessageAttributes == null) { return; } @@ -38,23 +36,9 @@ internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary< return; } - int nextAttributeIndex = attributesCount + 1; foreach (var param in attributes) { - AddAttribute(parameters, originalRequest, param.Key, param.Value, nextAttributeIndex); - nextAttributeIndex++; + originalRequest.MessageAttributes[param.Key] = new MessageAttributeValue { DataType = "String", StringValue = param.Value }; } } - - private static void AddAttribute(ParameterCollection parameters, PublishRequest originalRequest, string name, string value, int attributeIndex) - { - var prefix = "MessageAttributes.entry." + attributeIndex; - parameters.Add(prefix + ".Name", name); - parameters.Add(prefix + ".Value.DataType", "String"); - parameters.Add(prefix + ".Value.StringValue", value); - - // Add injected attributes to the original request as well. - // This dictionary must be in sync with parameters collection to pass through the MD5 hash matching check. - originalRequest.MessageAttributes.Add(name, new MessageAttributeValue { DataType = "String", StringValue = value }); - } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs index 33feb38172..534a120e90 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; using Amazon.Runtime; -using Amazon.Runtime.Internal; using Amazon.SQS.Model; namespace OpenTelemetry.Instrumentation.AWS.Implementation; @@ -18,9 +17,8 @@ internal class SqsRequestContextHelper internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary attributes) { - var parameters = context.Request?.ParameterCollection; var originalRequest = context.OriginalRequest as SendMessageRequest; - if (originalRequest?.MessageAttributes == null || parameters == null) + if (originalRequest?.MessageAttributes == null) { return; } @@ -38,23 +36,9 @@ internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary< return; } - int nextAttributeIndex = attributesCount + 1; foreach (var param in attributes) { - AddAttribute(parameters, originalRequest, param.Key, param.Value, nextAttributeIndex); - nextAttributeIndex++; + originalRequest.MessageAttributes[param.Key] = new MessageAttributeValue { DataType = "String", StringValue = param.Value }; } } - - private static void AddAttribute(ParameterCollection parameters, SendMessageRequest originalRequest, string name, string value, int attributeIndex) - { - var prefix = "MessageAttribute." + attributeIndex; - parameters.Add(prefix + ".Name", name); - parameters.Add(prefix + ".Value.DataType", "String"); - parameters.Add(prefix + ".Value.StringValue", value); - - // Add injected attributes to the original request as well. - // This dictionary must be in sync with parameters collection to pass through the MD5 hash matching check. - originalRequest.MessageAttributes.Add(name, new MessageAttributeValue { DataType = "String", StringValue = value }); - } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index d522d4231f..c9e5c26cdd 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -37,7 +37,7 @@ public static TracerProviderBuilder AddAWSInstrumentation( configure?.Invoke(awsClientOptions); _ = new AWSClientsInstrumentation(awsClientOptions); - builder.AddSource("Amazon.AWS.AWSClientInstrumentation"); + builder.AddSource(AWSTracingPipelineHandler.ActivitySourceName); return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs index 47466b52a5..6f8336633b 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -4,12 +4,13 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using Amazon.Runtime; using Amazon.Runtime.Internal; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.AWS.Implementation; using OpenTelemetry.Trace; using Xunit; +using SNS = Amazon.SimpleNotificationService.Model; +using SQS = Amazon.SQS.Model; namespace OpenTelemetry.Instrumentation.AWS.Tests.Implementation; @@ -30,7 +31,7 @@ public RequestContextHelperTests() [InlineData(AWSServiceType.SNSService)] public void AddAttributes_ParametersCollectionSizeReachesLimit_TraceDataNotInjected(string serviceType) { - AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 10); + var originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 10); var parameters = new ParameterCollection(); parameters.AddStringParameters(serviceType, originalRequest); @@ -44,82 +45,82 @@ public void AddAttributes_ParametersCollectionSizeReachesLimit_TraceDataNotInjec Assert.Equal(30, parameters.Count); } - [Theory] - [InlineData(AWSServiceType.SQSService)] - [InlineData(AWSServiceType.SNSService)] - public void AddAttributes_ParametersCollection_TraceDataInjected(string serviceType) + [Fact] + public void SQS_AddAttributes_MessageAttributes_TraceDataInjected() { - var expectedParameters = new List>() + var expectedParameters = new List> { new("traceparent", $"00-{TraceId}-{ParentId}-00"), new("tracestate", "trace-state"), }; - AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 0); - var parameters = new ParameterCollection(); + var originalRequest = new SQS.SendMessageRequest(); - var request = new TestRequest(parameters); - var context = new TestRequestContext(originalRequest, request); + var context = new TestRequestContext(originalRequest, new TestRequest()); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); - addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + SqsRequestContextHelper.AddAttributes(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); - TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); + TestsHelper.AssertMessageParameters(expectedParameters, originalRequest); } - [Theory] - [InlineData(AWSServiceType.SQSService)] - [InlineData(AWSServiceType.SNSService)] - public void AddAttributes_ParametersCollectionWithCustomParameter_TraceDataInjected(string serviceType) + [Fact] + public void SNS_AddAttributes_MessageAttributes_TraceDataInjected() { - var expectedParameters = new List>() + var expectedParameters = new List> { - new("name1", "value1"), new("traceparent", $"00-{TraceId}-{ParentId}-00"), new("tracestate", "trace-state"), }; - AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 1); - var parameters = new ParameterCollection(); - parameters.AddStringParameters(serviceType, originalRequest); - - var request = new TestRequest(parameters); + var originalRequest = new SNS.PublishRequest(); - var context = new TestRequestContext(originalRequest, request); + var context = new TestRequestContext(originalRequest, new TestRequest()); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); - addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + SnsRequestContextHelper.AddAttributes(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); - TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); + TestsHelper.AssertMessageParameters(expectedParameters, originalRequest); } - [Theory] - [InlineData(AWSServiceType.SQSService)] - [InlineData(AWSServiceType.SNSService)] - public void AddAttributes_ParametersCollectionWithTraceParent_TraceStateNotInjected(string serviceType) + [Fact] + public void SQS_AddAttributes_MessageAttributesWithTraceParent_TraceStateNotInjected() { // This test just checks the common implementation logic: // if at least one attribute is already present the whole injection is skipped. // We just use default trace propagator as an example which injects only traceparent and tracestate. - var expectedParameters = new List>() + var expectedParameters = new List> { new("traceparent", $"00-{TraceId}-{ParentId}-00"), }; - AmazonWebServiceRequest originalRequest = TestsHelper.CreateOriginalRequest(serviceType, 0); - originalRequest.AddAttribute("traceparent", $"00-{TraceId}-{ParentId}-00"); + var originalRequest = new SQS.SendMessageRequest(); - var parameters = new ParameterCollection(); - parameters.AddStringParameters(serviceType, originalRequest); + var context = new TestRequestContext(originalRequest, new TestRequest()); - var request = new TestRequest(parameters); - var context = new TestRequestContext(originalRequest, request); + SqsRequestContextHelper.AddAttributes(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); - addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); + TestsHelper.AssertMessageParameters(expectedParameters, originalRequest); + } + + [Fact] + public void SNS_AddAttributes_MessageAttributesWithTraceParent_TraceStateNotInjected() + { + // This test just checks the common implementation logic: + // if at least one attribute is already present the whole injection is skipped. + // We just use default trace propagator as an example which injects only traceparent and tracestate. + + var expectedParameters = new List> + { + new("traceparent", $"00-{TraceId}-{ParentId}-00"), + }; + + var originalRequest = new SNS.PublishRequest(); + + var context = new TestRequestContext(originalRequest, new TestRequest()); + + SnsRequestContextHelper.AddAttributes(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); - TestsHelper.AssertStringParameters(serviceType, expectedParameters, parameters); + TestsHelper.AssertMessageParameters(expectedParameters, originalRequest); } private static PropagationContext CreatePropagationContext() diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index 3248b3c7d5..b6fd78aab0 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -14,6 +14,12 @@ namespace OpenTelemetry.Instrumentation.AWS.Tests.Implementation; internal static class TestsHelper { + /// + /// Returns either or + /// depending on . + /// + /// This is meant to mimic thee logic in . + /// internal static Action>? CreateAddAttributesAction(string serviceType, IRequestContext context) { return serviceType switch @@ -96,23 +102,23 @@ internal static void AddStringParameters(this ParameterCollection parameters, st } } - internal static void AssertStringParameters(string serviceType, List> expectedParameters, ParameterCollection parameters) + internal static void AssertMessageParameters(List> expectedParameters, SQS.SendMessageRequest request) { - Assert.Equal(expectedParameters.Count * 3, parameters.Count); - - for (int i = 0; i < expectedParameters.Count; i++) + foreach (var kvp in expectedParameters) { - var prefix = $"{GetNamePrefix(serviceType)}.{i + 1}"; - static string? Value(ParameterValue p) => (p as StringParameterValue)?.Value; + Assert.True(request.MessageAttributes.ContainsKey(kvp.Key)); - Assert.True(parameters.ContainsKey($"{prefix}.Name")); - Assert.Equal(expectedParameters[i].Key, Value(parameters[$"{prefix}.Name"])); + Assert.Equal(kvp.Value, request.MessageAttributes[kvp.Key].StringValue); + } + } - Assert.True(parameters.ContainsKey($"{prefix}.Value.DataType")); - Assert.Equal("String", Value(parameters[$"{prefix}.Value.DataType"])); + internal static void AssertMessageParameters(List> expectedParameters, SNS.PublishRequest request) + { + foreach (var kvp in expectedParameters) + { + Assert.True(request.MessageAttributes.ContainsKey(kvp.Key)); - Assert.True(parameters.ContainsKey($"{prefix}.Value.StringValue")); - Assert.Equal(expectedParameters[i].Value, Value(parameters[$"{prefix}.Value.StringValue"])); + Assert.Equal(kvp.Value, request.MessageAttributes[kvp.Key].StringValue); } } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index c4f81f779e..81340c5764 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -174,6 +174,7 @@ public void TestSQSSendMessageSuccessful() var send_msg_req = new SendMessageRequest(); send_msg_req.QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue"; send_msg_req.MessageBody = "Hello from OT"; + send_msg_req.MessageAttributes.Add("Custom", new MessageAttributeValue { StringValue = "Value", DataType = "String" }); #if NETFRAMEWORK sqs.SendMessage(send_msg_req); #else @@ -198,8 +199,8 @@ private void ValidateAWSActivity(Activity aws_activity, Activity parent) private void ValidateDynamoActivityTags(Activity ddb_activity) { - Assert.Equal("DynamoDBv2.Scan", ddb_activity.DisplayName); - Assert.Equal("DynamoDBv2", Utils.GetTagValue(ddb_activity, "aws.service")); + Assert.Equal("DynamoDB.Scan", ddb_activity.DisplayName); + Assert.Equal("DynamoDB", Utils.GetTagValue(ddb_activity, "aws.service")); Assert.Equal("Scan", Utils.GetTagValue(ddb_activity, "aws.operation")); Assert.Equal("us-east-1", Utils.GetTagValue(ddb_activity, "aws.region")); Assert.Equal("SampleProduct", Utils.GetTagValue(ddb_activity, "aws.table_name")); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs index 2aa3d0a634..a177693858 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs @@ -13,9 +13,14 @@ namespace OpenTelemetry.Instrumentation.AWS.Tests; -internal class TestRequest(ParameterCollection parameters) : IRequest +internal class TestRequest : IRequest { - private readonly ParameterCollection parameters = parameters; + private readonly ParameterCollection parameters; + + public TestRequest(ParameterCollection? parameters = null) + { + this.parameters = parameters ?? new ParameterCollection(); + } public string RequestName => throw new NotImplementedException(); From de135415f5de21c0a565f3fb3b0570484e7a2bae Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 22 Feb 2024 19:02:15 -0800 Subject: [PATCH 0973/1499] [Exporter.Geneva] Refactor metric exporter (#1587) Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .../Metrics/GenevaMetricExporter.cs | 722 +---------------- .../Metrics/TlvMetricExporter.cs | 745 ++++++++++++++++++ .../Exporter/MetricExporterBenchmarks.cs | 23 +- .../GenevaMetricExporterTests.cs | 43 +- 4 files changed, 791 insertions(+), 742 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 9383e80330..ec69b96d63 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -2,13 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; -using System.Collections.Generic; -using System.Globalization; using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; using System.Text.RegularExpressions; +using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -16,7 +12,7 @@ namespace OpenTelemetry.Exporter.Geneva; public class GenevaMetricExporter : BaseExporter { - private const int BufferSize = 65360; // the maximum ETW payload (inclusive) + internal const int BufferSize = 65360; // the maximum ETW payload (inclusive) internal const int MaxDimensionNameSize = 256; @@ -26,21 +22,11 @@ public class GenevaMetricExporter : BaseExporter internal const string DimensionKeyForCustomMetricsNamespace = "_microsoft_metrics_namespace"; - private readonly ushort prepopulatedDimensionsCount; + private readonly TlvMetricExporter exporter; - private readonly int fixedPayloadStartIndex; + private delegate ExportResult ExportMetricsFunc(in Batch batch); - private readonly IMetricDataTransport metricDataTransport; - - private readonly List serializedPrepopulatedDimensionsKeys; - - private readonly List serializedPrepopulatedDimensionsValues; - - private readonly byte[] buffer = new byte[BufferSize]; - - private readonly string defaultMonitoringAccount; - - private readonly string defaultMetricNamespace; + private readonly ExportMetricsFunc exportMetrics; private bool isDisposed; @@ -49,212 +35,18 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) Guard.ThrowIfNull(options); Guard.ThrowIfNullOrWhitespace(options.ConnectionString); - var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - this.defaultMonitoringAccount = connectionStringBuilder.Account; - this.defaultMetricNamespace = connectionStringBuilder.Namespace; - - if (options.PrepopulatedMetricDimensions != null) - { - this.prepopulatedDimensionsCount = (ushort)options.PrepopulatedMetricDimensions.Count; - this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(options.PrepopulatedMetricDimensions.Keys); - this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(options.PrepopulatedMetricDimensions.Values); - } - - switch (connectionStringBuilder.Protocol) - { - case TransportProtocol.Unix: - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new ArgumentException("Unix domain socket should not be used on Windows."); - } - - var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); - break; - case TransportProtocol.Unspecified: - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - this.metricDataTransport = MetricEtwDataTransport.Instance; - break; - } - else - { - throw new ArgumentException("Endpoint not specified"); - } - - default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); - } + // TODO: parse connection string to check if otlp protobuf format is enabled. + // and then enable either TLV Exporter or Protobuf based exporter. + var tlvMetricsExporter = new TlvMetricExporter(options); - unsafe - { - this.fixedPayloadStartIndex = sizeof(BinaryHeader); - } + this.exportMetrics = tlvMetricsExporter.Export; - if (connectionStringBuilder.DisableMetricNameValidation) - { - DisableOpenTelemetrySdkMetricNameValidation(); - } + this.exporter = tlvMetricsExporter; } public override ExportResult Export(in Batch batch) { - string monitoringAccount = this.defaultMonitoringAccount; - string metricNamespace = this.defaultMetricNamespace; - - var result = ExportResult.Success; - foreach (var metric in batch) - { - foreach (ref readonly var metricPoint in metric.GetMetricPoints()) - { - try - { -#if EXPOSE_EXPERIMENTAL_FEATURES - var exemplars = metricPoint.GetExemplars(); -#endif - - switch (metric.MetricType) - { - case MetricType.LongSum: - { - var ulongSum = Convert.ToUInt64(metricPoint.GetSumLong()); - var metricData = new MetricData { UInt64Value = ulongSum }; - var bodyLength = this.SerializeMetricWithTLV( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp - metricPoint.Tags, - metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES - exemplars, -#endif - out monitoringAccount, - out metricNamespace); - this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); - break; - } - - // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` - case MetricType.LongGauge: - { - // potential for minor precision loss implicitly going from long->double - // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions - var doubleSum = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); - var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetricWithTLV( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES - exemplars, -#endif - out monitoringAccount, - out metricNamespace); - this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); - break; - } - - // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` - case MetricType.LongSumNonMonotonic: - { - // potential for minor precision loss implicitly going from long->double - // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions - var doubleSum = Convert.ToDouble(metricPoint.GetSumLong()); - var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetricWithTLV( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES - exemplars, -#endif - out monitoringAccount, - out metricNamespace); - this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); - break; - } - - case MetricType.DoubleSum: - case MetricType.DoubleSumNonMonotonic: - { - var doubleSum = metricPoint.GetSumDouble(); - var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetricWithTLV( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES - exemplars, -#endif - out monitoringAccount, - out metricNamespace); - this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); - break; - } - - case MetricType.DoubleGauge: - { - var doubleSum = metricPoint.GetGaugeLastValueDouble(); - var metricData = new MetricData { DoubleValue = doubleSum }; - var bodyLength = this.SerializeMetricWithTLV( - MetricEventType.DoubleMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES - exemplars, -#endif - out monitoringAccount, - out metricNamespace); - this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); - break; - } - - case MetricType.Histogram: - { - var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); - var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) - { - min = 0; - max = 0; - } - - var bodyLength = this.SerializeHistogramMetricWithTLV( - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricPoint.GetHistogramBuckets(), - sum, - count, - min, - max, -#if EXPOSE_EXPERIMENTAL_FEATURES - exemplars, -#endif - out monitoringAccount, - out metricNamespace); - this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); - break; - } - } - } - catch (Exception ex) - { - ExporterEventSource.Log.FailedToSendMetricData(monitoringAccount, metricNamespace, metric.Name, ex); // TODO: preallocate exception or no exception - result = ExportResult.Failure; - } - } - } - - return result; + return this.exportMetrics(batch); } protected override void Dispose(bool disposing) @@ -266,19 +58,7 @@ protected override void Dispose(bool disposing) if (disposing) { - try - { - // The ETW data transport singleton on Windows should NOT be disposed. - // On Linux, Unix Domain Socket is used and should be disposed. - if (this.metricDataTransport != MetricEtwDataTransport.Instance) - { - this.metricDataTransport.Dispose(); - } - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("GenevaMetricExporter Dispose failed.", ex); - } + this.exporter.Dispose(); } this.isDisposed = true; @@ -300,482 +80,4 @@ internal static void DisableOpenTelemetrySdkMetricNameValidation() { GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, new Regex(".*", RegexOptions.Compiled)); } - - internal unsafe ushort SerializeMetricWithTLV( - MetricEventType eventType, - string metricName, - long timestamp, - in ReadOnlyTagCollection tags, - MetricData value, -#if EXPOSE_EXPERIMENTAL_FEATURES - Exemplar[] exemplars, -#endif - out string monitoringAccount, - out string metricNamespace) - { - ushort bodyLength; - try - { - // The buffer format is as follows: - // -- BinaryHeader - // -- Sequence of payload types - - // Leave enough space for the header - var bufferIndex = sizeof(BinaryHeader); - - SerializeMetricName(metricName, this.buffer, ref bufferIndex); - - SerializeNonHistogramMetricData(eventType, value, timestamp, this.buffer, ref bufferIndex); - - // Serializes metric dimensions and also gets the custom account name and metric namespace - // if specified by adding custom tags: _microsoft_metrics_namespace and _microsoft_metrics_namespace - this.SerializeDimensionsAndGetCustomAccountNamespace( - tags, - this.buffer, - ref bufferIndex, - out monitoringAccount, - out metricNamespace); - -#if EXPOSE_EXPERIMENTAL_FEATURES - SerializeExemplars(exemplars, this.buffer, ref bufferIndex); -#endif - - SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); - - SerializeMetricNamespace(metricNamespace, this.buffer, ref bufferIndex); - - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.buffer) - { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)MetricEventType.TLV; - ptr->BodyLength = bodyLength; - } - } - finally - { - } - - return bodyLength; - } - - internal unsafe ushort SerializeHistogramMetricWithTLV( - string metricName, - long timestamp, - in ReadOnlyTagCollection tags, - HistogramBuckets buckets, - double sum, - uint count, - double min, - double max, -#if EXPOSE_EXPERIMENTAL_FEATURES - Exemplar[] exemplars, -#endif - out string monitoringAccount, - out string metricNamespace) - { - ushort bodyLength; - try - { - // The buffer format is as follows: - // -- BinaryHeader - // -- Sequence of payload types - - // Leave enough space for the header - var bufferIndex = sizeof(BinaryHeader); - - SerializeMetricName(metricName, this.buffer, ref bufferIndex); - - SerializeHistogramMetricData(buckets, sum, count, min, max, timestamp, this.buffer, ref bufferIndex); - - // Serializes metric dimensions and also gets the custom account name and metric namespace - // if specified by adding custom tags: _microsoft_metrics_namespace and _microsoft_metrics_namespace - this.SerializeDimensionsAndGetCustomAccountNamespace( - tags, - this.buffer, - ref bufferIndex, - out monitoringAccount, - out metricNamespace); - -#if EXPOSE_EXPERIMENTAL_FEATURES - SerializeExemplars(exemplars, this.buffer, ref bufferIndex); -#endif - - SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); - - SerializeMetricNamespace(metricNamespace, this.buffer, ref bufferIndex); - - // Write the final size of the payload - bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); - - // Copy in the final structures to the front - fixed (byte* bufferBytes = this.buffer) - { - var ptr = (BinaryHeader*)bufferBytes; - ptr->EventId = (ushort)MetricEventType.TLV; - ptr->BodyLength = bodyLength; - } - } - finally - { - } - - return bodyLength; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeMetricName(string metricName, byte[] buffer, ref int bufferIndex) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.MetricName); - MetricSerializer.SerializeString(buffer, ref bufferIndex, metricName); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeMetricNamespace(string metricNamespace, byte[] buffer, ref int bufferIndex) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Namespace); - MetricSerializer.SerializeString(buffer, ref bufferIndex, metricNamespace); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeMonitoringAccount(string monitoringAccount, byte[] buffer, ref int bufferIndex) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.AccountName); - MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); - } - -#if EXPOSE_EXPERIMENTAL_FEATURES - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) - { - if (exemplars.Length > 0) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Exemplars); - - // Get a placeholder to add the payloadType length - var payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version - - // TODO: Avoid this additional enumeration - var exemplarsCount = 0; - foreach (var exemplar in exemplars) - { - if (exemplar.Timestamp != default) - { - exemplarsCount++; - } - } - - MetricSerializer.SerializeInt32AsBase128(buffer, ref bufferIndex, exemplarsCount); - - foreach (var exemplar in exemplars) - { - if (exemplar.Timestamp != default) - { - SerializeSingleExmeplar(exemplar, buffer, ref bufferIndex); - } - } - - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, ref int bufferIndex) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version - - var bufferIndexForLength = bufferIndex; - bufferIndex++; - - var bufferIndexForFlags = bufferIndex; - bufferIndex++; - - var flags = ExemplarFlags.IsTimestampAvailable; // we only serialize exemplars with Timestamp != default - - // TODO: Update the code when Exemplars support long values - var value = exemplar.DoubleValue; - - // Check if the double value is actually a whole number that can be serialized as a long instead - var valueAsLong = (long)value; - bool isWholeNumber = valueAsLong == value; - if (isWholeNumber) - { - flags |= ExemplarFlags.IsMetricValueDoubleStoredAsLong; - MetricSerializer.SerializeInt64AsBase128(buffer, ref bufferIndex, valueAsLong); // serialize long value - } - else - { - MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value); // serialize double value - } - - var bufferIndexForNumberOfLabels = bufferIndex; - MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // serialize zero as the count of labels; this would be updated later if the exemplar has labels - byte numberOfLabels = 0; - - // Convert exemplar timestamp to unix nanoseconds - var unixNanoSeconds = DateTime.FromFileTimeUtc(exemplar.Timestamp.ToFileTime()) - .ToUniversalTime() - .Subtract(new DateTime(1970, 1, 1)) - .TotalMilliseconds * 1000000; - - MetricSerializer.SerializeInt64(buffer, ref bufferIndex, (long)unixNanoSeconds); // serialize timestamp - - if (exemplar.TraceId.HasValue) - { - Span traceIdBytes = stackalloc byte[16]; - exemplar.TraceId.Value.CopyTo(traceIdBytes); - MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, traceIdBytes, traceIdBytes.Length); // serialize traceId - - flags |= ExemplarFlags.TraceIdExists; - } - - if (exemplar.SpanId.HasValue) - { - Span spanIdBytes = stackalloc byte[8]; - exemplar.SpanId.Value.CopyTo(spanIdBytes); - MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, spanIdBytes, spanIdBytes.Length); // serialize spanId - - flags |= ExemplarFlags.SpanIdExists; - } - - bool hasLabels = exemplar.FilteredTags != null && exemplar.FilteredTags.Count > 0; - if (hasLabels) - { - foreach (var tag in exemplar.FilteredTags) - { - MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, tag.Key); - MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); - numberOfLabels++; - } - - MetricSerializer.SerializeByte(buffer, ref bufferIndexForNumberOfLabels, numberOfLabels); - } - - MetricSerializer.SerializeByte(buffer, ref bufferIndexForFlags, (byte)flags); - - var exemplarLength = bufferIndex - bufferIndexForLength + 1; - MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); - } -#endif - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) - { - var payloadType = eventType == MetricEventType.ULongMetric ? PayloadType.ULongMetric : PayloadType.DoubleMetric; - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)payloadType); - - // Get a placeholder to add the payloadType length - int payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp - - if (payloadType == PayloadType.ULongMetric) - { - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, value.UInt64Value); - } - else - { - MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value.DoubleValue); - } - - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeHistogramMetricData(HistogramBuckets buckets, double sum, uint count, double min, double max, long timestamp, byte[] buffer, ref int bufferIndex) - { - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.ExternallyAggregatedULongDistributionMetric); - - // Get a placeholder to add the payloadType length - int payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - // Serialize sum, count, min, and max - MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, count); // histogram count - MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, 0); // padding - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(sum)); // histogram sum - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(min)); // histogram min - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(max)); // histogram max - - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); - - // Serialize histogram buckets as value-count pairs - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.HistogramULongValueCountPairs); - - // Get a placeholder to add the payloadType length - payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - // Get a placeholder to add the number of value-count pairs added - // with value being the bucket boundary and count being the respective count - - var itemsWrittenIndex = bufferIndex; - MetricSerializer.SerializeUInt16(buffer, ref bufferIndex, 0); - - // Bucket values - ushort bucketCount = 0; - double lastExplicitBound = default; - foreach (var bucket in buckets) - { - if (bucket.BucketCount > 0) - { - SerializeHistogramBucketWithTLV(bucket, buffer, ref bufferIndex, lastExplicitBound); - bucketCount++; - } - - lastExplicitBound = bucket.ExplicitBound; - } - - // Write the number of items in distribution emitted and reset back to end. - MetricSerializer.SerializeUInt16(buffer, ref itemsWrittenIndex, bucketCount); - - payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, byte[] buffer, ref int bufferIndex, double lastExplicitBound) - { - if (bucket.ExplicitBound != double.PositiveInfinity) - { - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); - } - else - { - // The bucket to catch the overflows is one greater than the last bound provided - MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); - } - - MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagCollection tags, byte[] buffer, ref int bufferIndex, out string monitoringAccount, out string metricNamespace) - { - monitoringAccount = this.defaultMonitoringAccount; - metricNamespace = this.defaultMetricNamespace; - - MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Dimensions); - - // Get a placeholder to add the payloadType length - var payloadTypeStartIndex = bufferIndex; - bufferIndex += 2; - - // Get a placeholder to add dimensions count later - var bufferIndexForDimensionsCount = bufferIndex; - bufferIndex += 2; - - ushort dimensionsWritten = 0; - - // Serialize PrepopulatedDimensions keys - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); - } - - if (this.prepopulatedDimensionsCount > 0) - { - dimensionsWritten += this.prepopulatedDimensionsCount; - } - - int reservedTags = 0; - - // Serialize MetricPoint Dimension keys - foreach (var tag in tags) - { - if (tag.Key.Length > MaxDimensionNameSize) - { - // TODO: Data Validation - } - - if (tag.Key.Equals(DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) || - tag.Key.Equals(DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase)) - { - reservedTags++; - continue; - } - - MetricSerializer.SerializeString(buffer, ref bufferIndex, tag.Key); - } - - dimensionsWritten += (ushort)(tags.Count - reservedTags); - - // Serialize PrepopulatedDimensions values - for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) - { - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); - } - - // Serialize MetricPoint Dimension values - foreach (var tag in tags) - { - if (tag.Key.Equals(DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsAccount) - { - if (!string.IsNullOrWhiteSpace(metricsAccount)) - { - monitoringAccount = metricsAccount; - } - - continue; - } - - if (tag.Key.Equals(DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsNamespace) - { - if (!string.IsNullOrWhiteSpace(metricsNamespace)) - { - metricNamespace = metricsNamespace; - } - - continue; - } - - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > MaxDimensionValueSize) - { - // TODO: Data Validation - } - - MetricSerializer.SerializeString(buffer, ref bufferIndex, dimensionValue); - } - - // Backfill the number of dimensions written - MetricSerializer.SerializeUInt16(buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); - - var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); - MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); - } - - private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) - { - var serializedKeys = new List(this.prepopulatedDimensionsCount); - foreach (var key in keys) - { - serializedKeys.Add(Encoding.UTF8.GetBytes(key)); - } - - return serializedKeys; - } - - private List SerializePrepopulatedDimensionsValues(IEnumerable values) - { - var serializedValues = new List(this.prepopulatedDimensionsCount); - foreach (var value in values) - { - var valueAsString = Convert.ToString(value, CultureInfo.InvariantCulture); - serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); - } - - return serializedValues; - } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs new file mode 100644 index 0000000000..89d1dbb5a8 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -0,0 +1,745 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.Geneva.Metrics; + +internal sealed class TlvMetricExporter : IDisposable +{ + private readonly ushort prepopulatedDimensionsCount; + + private readonly int fixedPayloadStartIndex; + + private readonly IMetricDataTransport metricDataTransport; + + private readonly List serializedPrepopulatedDimensionsKeys; + + private readonly List serializedPrepopulatedDimensionsValues; + + private readonly byte[] buffer = new byte[GenevaMetricExporter.BufferSize]; + + private readonly string defaultMonitoringAccount; + + private readonly string defaultMetricNamespace; + + private bool isDisposed; + + internal TlvMetricExporter(GenevaMetricExporterOptions options) + { + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + this.defaultMonitoringAccount = connectionStringBuilder.Account; + this.defaultMetricNamespace = connectionStringBuilder.Namespace; + + if (options.PrepopulatedMetricDimensions != null) + { + this.prepopulatedDimensionsCount = (ushort)options.PrepopulatedMetricDimensions.Count; + this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(options.PrepopulatedMetricDimensions.Keys); + this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(options.PrepopulatedMetricDimensions.Values); + } + + switch (connectionStringBuilder.Protocol) + { + case TransportProtocol.Unix: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); + break; + case TransportProtocol.Unspecified: + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + this.metricDataTransport = MetricEtwDataTransport.Instance; + break; + } + else + { + throw new ArgumentException("Endpoint not specified"); + } + + default: + throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + } + + unsafe + { + this.fixedPayloadStartIndex = sizeof(BinaryHeader); + } + + if (connectionStringBuilder.DisableMetricNameValidation) + { + GenevaMetricExporter.DisableOpenTelemetrySdkMetricNameValidation(); + } + } + + internal ExportResult Export(in Batch batch) + { + string monitoringAccount = this.defaultMonitoringAccount; + string metricNamespace = this.defaultMetricNamespace; + + var result = ExportResult.Success; + foreach (var metric in batch) + { + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) + { + try + { +#if EXPOSE_EXPERIMENTAL_FEATURES + var exemplars = metricPoint.GetExemplars(); +#endif + + switch (metric.MetricType) + { + case MetricType.LongSum: + { + var ulongSum = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = ulongSum }; + var bodyLength = this.SerializeMetricWithTLV( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp + metricPoint.Tags, + metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES + exemplars, +#endif + out monitoringAccount, + out metricNamespace); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); + break; + } + + // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` + case MetricType.LongGauge: + { + // potential for minor precision loss implicitly going from long->double + // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions + var doubleSum = Convert.ToDouble(metricPoint.GetGaugeLastValueLong()); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES + exemplars, +#endif + out monitoringAccount, + out metricNamespace); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); + break; + } + + // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` + case MetricType.LongSumNonMonotonic: + { + // potential for minor precision loss implicitly going from long->double + // see: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions + var doubleSum = Convert.ToDouble(metricPoint.GetSumLong()); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES + exemplars, +#endif + out monitoringAccount, + out metricNamespace); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); + break; + } + + case MetricType.DoubleSum: + case MetricType.DoubleSumNonMonotonic: + { + var doubleSum = metricPoint.GetSumDouble(); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES + exemplars, +#endif + out monitoringAccount, + out metricNamespace); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); + break; + } + + case MetricType.DoubleGauge: + { + var doubleSum = metricPoint.GetGaugeLastValueDouble(); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetricWithTLV( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, +#if EXPOSE_EXPERIMENTAL_FEATURES + exemplars, +#endif + out monitoringAccount, + out metricNamespace); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); + break; + } + + case MetricType.Histogram: + { + var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); + var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); + if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + min = 0; + max = 0; + } + + var bodyLength = this.SerializeHistogramMetricWithTLV( + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricPoint.GetHistogramBuckets(), + sum, + count, + min, + max, +#if EXPOSE_EXPERIMENTAL_FEATURES + exemplars, +#endif + out monitoringAccount, + out metricNamespace); + this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); + break; + } + } + } + catch (Exception ex) + { + ExporterEventSource.Log.FailedToSendMetricData(monitoringAccount, metricNamespace, metric.Name, ex); // TODO: preallocate exception or no exception + result = ExportResult.Failure; + } + } + } + + return result; + } + + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + try + { + // The ETW data transport singleton on Windows should NOT be disposed. + // On Linux, Unix Domain Socket is used and should be disposed. + if (this.metricDataTransport != MetricEtwDataTransport.Instance) + { + this.metricDataTransport.Dispose(); + } + + this.isDisposed = true; + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("TlvMetricExporter Dispose failed.", ex); + } + } + + internal unsafe ushort SerializeMetricWithTLV( + MetricEventType eventType, + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + MetricData value, +#if EXPOSE_EXPERIMENTAL_FEATURES + Exemplar[] exemplars, +#endif + out string monitoringAccount, + out string metricNamespace) + { + ushort bodyLength; + try + { + // The buffer format is as follows: + // -- BinaryHeader + // -- Sequence of payload types + + // Leave enough space for the header + var bufferIndex = sizeof(BinaryHeader); + + SerializeMetricName(metricName, this.buffer, ref bufferIndex); + + SerializeNonHistogramMetricData(eventType, value, timestamp, this.buffer, ref bufferIndex); + + // Serializes metric dimensions and also gets the custom account name and metric namespace + // if specified by adding custom tags: _microsoft_metrics_namespace and _microsoft_metrics_namespace + this.SerializeDimensionsAndGetCustomAccountNamespace( + tags, + this.buffer, + ref bufferIndex, + out monitoringAccount, + out metricNamespace); + +#if EXPOSE_EXPERIMENTAL_FEATURES + SerializeExemplars(exemplars, this.buffer, ref bufferIndex); +#endif + + SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); + + SerializeMetricNamespace(metricNamespace, this.buffer, ref bufferIndex); + + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.buffer) + { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.TLV; + ptr->BodyLength = bodyLength; + } + } + finally + { + } + + return bodyLength; + } + + internal unsafe ushort SerializeHistogramMetricWithTLV( + string metricName, + long timestamp, + in ReadOnlyTagCollection tags, + HistogramBuckets buckets, + double sum, + uint count, + double min, + double max, +#if EXPOSE_EXPERIMENTAL_FEATURES + Exemplar[] exemplars, +#endif + out string monitoringAccount, + out string metricNamespace) + { + ushort bodyLength; + try + { + // The buffer format is as follows: + // -- BinaryHeader + // -- Sequence of payload types + + // Leave enough space for the header + var bufferIndex = sizeof(BinaryHeader); + + SerializeMetricName(metricName, this.buffer, ref bufferIndex); + + SerializeHistogramMetricData(buckets, sum, count, min, max, timestamp, this.buffer, ref bufferIndex); + + // Serializes metric dimensions and also gets the custom account name and metric namespace + // if specified by adding custom tags: _microsoft_metrics_namespace and _microsoft_metrics_namespace + this.SerializeDimensionsAndGetCustomAccountNamespace( + tags, + this.buffer, + ref bufferIndex, + out monitoringAccount, + out metricNamespace); + +#if EXPOSE_EXPERIMENTAL_FEATURES + SerializeExemplars(exemplars, this.buffer, ref bufferIndex); +#endif + + SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); + + SerializeMetricNamespace(metricNamespace, this.buffer, ref bufferIndex); + + // Write the final size of the payload + bodyLength = (ushort)(bufferIndex - this.fixedPayloadStartIndex); + + // Copy in the final structures to the front + fixed (byte* bufferBytes = this.buffer) + { + var ptr = (BinaryHeader*)bufferBytes; + ptr->EventId = (ushort)MetricEventType.TLV; + ptr->BodyLength = bodyLength; + } + } + finally + { + } + + return bodyLength; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMetricName(string metricName, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.MetricName); + MetricSerializer.SerializeString(buffer, ref bufferIndex, metricName); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMetricNamespace(string metricNamespace, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Namespace); + MetricSerializer.SerializeString(buffer, ref bufferIndex, metricNamespace); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeMonitoringAccount(string monitoringAccount, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.AccountName); + MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); + } + +#if EXPOSE_EXPERIMENTAL_FEATURES + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) + { + if (exemplars.Length > 0) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Exemplars); + + // Get a placeholder to add the payloadType length + var payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version + + // TODO: Avoid this additional enumeration + var exemplarsCount = 0; + foreach (var exemplar in exemplars) + { + if (exemplar.Timestamp != default) + { + exemplarsCount++; + } + } + + MetricSerializer.SerializeInt32AsBase128(buffer, ref bufferIndex, exemplarsCount); + + foreach (var exemplar in exemplars) + { + if (exemplar.Timestamp != default) + { + SerializeSingleExmeplar(exemplar, buffer, ref bufferIndex); + } + } + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version + + var bufferIndexForLength = bufferIndex; + bufferIndex++; + + var bufferIndexForFlags = bufferIndex; + bufferIndex++; + + var flags = ExemplarFlags.IsTimestampAvailable; // we only serialize exemplars with Timestamp != default + + // TODO: Update the code when Exemplars support long values + var value = exemplar.DoubleValue; + + // Check if the double value is actually a whole number that can be serialized as a long instead + var valueAsLong = (long)value; + bool isWholeNumber = valueAsLong == value; + if (isWholeNumber) + { + flags |= ExemplarFlags.IsMetricValueDoubleStoredAsLong; + MetricSerializer.SerializeInt64AsBase128(buffer, ref bufferIndex, valueAsLong); // serialize long value + } + else + { + MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value); // serialize double value + } + + var bufferIndexForNumberOfLabels = bufferIndex; + MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // serialize zero as the count of labels; this would be updated later if the exemplar has labels + byte numberOfLabels = 0; + + // Convert exemplar timestamp to unix nanoseconds + var unixNanoSeconds = DateTime.FromFileTimeUtc(exemplar.Timestamp.ToFileTime()) + .ToUniversalTime() + .Subtract(new DateTime(1970, 1, 1)) + .TotalMilliseconds * 1000000; + + MetricSerializer.SerializeInt64(buffer, ref bufferIndex, (long)unixNanoSeconds); // serialize timestamp + + if (exemplar.TraceId.HasValue) + { + Span traceIdBytes = stackalloc byte[16]; + exemplar.TraceId.Value.CopyTo(traceIdBytes); + MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, traceIdBytes, traceIdBytes.Length); // serialize traceId + + flags |= ExemplarFlags.TraceIdExists; + } + + if (exemplar.SpanId.HasValue) + { + Span spanIdBytes = stackalloc byte[8]; + exemplar.SpanId.Value.CopyTo(spanIdBytes); + MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, spanIdBytes, spanIdBytes.Length); // serialize spanId + + flags |= ExemplarFlags.SpanIdExists; + } + + bool hasLabels = exemplar.FilteredTags != null && exemplar.FilteredTags.Count > 0; + if (hasLabels) + { + foreach (var tag in exemplar.FilteredTags) + { + MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, tag.Key); + MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); + numberOfLabels++; + } + + MetricSerializer.SerializeByte(buffer, ref bufferIndexForNumberOfLabels, numberOfLabels); + } + + MetricSerializer.SerializeByte(buffer, ref bufferIndexForFlags, (byte)flags); + + var exemplarLength = bufferIndex - bufferIndexForLength + 1; + MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); + } +#endif + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) + { + var payloadType = eventType == MetricEventType.ULongMetric ? PayloadType.ULongMetric : PayloadType.DoubleMetric; + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)payloadType); + + // Get a placeholder to add the payloadType length + int payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp + + if (payloadType == PayloadType.ULongMetric) + { + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, value.UInt64Value); + } + else + { + MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value.DoubleValue); + } + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeHistogramMetricData(HistogramBuckets buckets, double sum, uint count, double min, double max, long timestamp, byte[] buffer, ref int bufferIndex) + { + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.ExternallyAggregatedULongDistributionMetric); + + // Get a placeholder to add the payloadType length + int payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Serialize sum, count, min, and max + MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, count); // histogram count + MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, 0); // padding + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(sum)); // histogram sum + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(min)); // histogram min + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(max)); // histogram max + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + + // Serialize histogram buckets as value-count pairs + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.HistogramULongValueCountPairs); + + // Get a placeholder to add the payloadType length + payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add the number of value-count pairs added + // with value being the bucket boundary and count being the respective count + + var itemsWrittenIndex = bufferIndex; + MetricSerializer.SerializeUInt16(buffer, ref bufferIndex, 0); + + // Bucket values + ushort bucketCount = 0; + double lastExplicitBound = default; + foreach (var bucket in buckets) + { + if (bucket.BucketCount > 0) + { + SerializeHistogramBucketWithTLV(bucket, buffer, ref bufferIndex, lastExplicitBound); + bucketCount++; + } + + lastExplicitBound = bucket.ExplicitBound; + } + + // Write the number of items in distribution emitted and reset back to end. + MetricSerializer.SerializeUInt16(buffer, ref itemsWrittenIndex, bucketCount); + + payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, byte[] buffer, ref int bufferIndex, double lastExplicitBound) + { + if (bucket.ExplicitBound != double.PositiveInfinity) + { + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(bucket.ExplicitBound)); + } + else + { + // The bucket to catch the overflows is one greater than the last bound provided + MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, Convert.ToUInt64(lastExplicitBound + 1)); + } + + MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagCollection tags, byte[] buffer, ref int bufferIndex, out string monitoringAccount, out string metricNamespace) + { + monitoringAccount = this.defaultMonitoringAccount; + metricNamespace = this.defaultMetricNamespace; + + MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Dimensions); + + // Get a placeholder to add the payloadType length + var payloadTypeStartIndex = bufferIndex; + bufferIndex += 2; + + // Get a placeholder to add dimensions count later + var bufferIndexForDimensionsCount = bufferIndex; + bufferIndex += 2; + + ushort dimensionsWritten = 0; + + // Serialize PrepopulatedDimensions keys + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + } + + if (this.prepopulatedDimensionsCount > 0) + { + dimensionsWritten += this.prepopulatedDimensionsCount; + } + + int reservedTags = 0; + + // Serialize MetricPoint Dimension keys + foreach (var tag in tags) + { + if (tag.Key.Length > GenevaMetricExporter.MaxDimensionNameSize) + { + // TODO: Data Validation + } + + if (tag.Key.Equals(GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) || + tag.Key.Equals(GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase)) + { + reservedTags++; + continue; + } + + MetricSerializer.SerializeString(buffer, ref bufferIndex, tag.Key); + } + + dimensionsWritten += (ushort)(tags.Count - reservedTags); + + // Serialize PrepopulatedDimensions values + for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) + { + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + } + + // Serialize MetricPoint Dimension values + foreach (var tag in tags) + { + if (tag.Key.Equals(GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsAccount) + { + if (!string.IsNullOrWhiteSpace(metricsAccount)) + { + monitoringAccount = metricsAccount; + } + + continue; + } + + if (tag.Key.Equals(GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, StringComparison.OrdinalIgnoreCase) && tag.Value is string metricsNamespace) + { + if (!string.IsNullOrWhiteSpace(metricsNamespace)) + { + metricNamespace = metricsNamespace; + } + + continue; + } + + var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); + if (dimensionValue.Length > GenevaMetricExporter.MaxDimensionValueSize) + { + // TODO: Data Validation + } + + MetricSerializer.SerializeString(buffer, ref bufferIndex, dimensionValue); + } + + // Backfill the number of dimensions written + MetricSerializer.SerializeUInt16(buffer, ref bufferIndexForDimensionsCount, dimensionsWritten); + + var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); + MetricSerializer.SerializeUInt16(buffer, ref payloadTypeStartIndex, payloadTypeLength); + } + + private List SerializePrepopulatedDimensionsKeys(IEnumerable keys) + { + var serializedKeys = new List(this.prepopulatedDimensionsCount); + foreach (var key in keys) + { + serializedKeys.Add(Encoding.UTF8.GetBytes(key)); + } + + return serializedKeys; + } + + private List SerializePrepopulatedDimensionsValues(IEnumerable values) + { + var serializedValues = new List(this.prepopulatedDimensionsCount); + foreach (var value in values) + { + var valueAsString = Convert.ToString(value, CultureInfo.InvariantCulture); + serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); + } + + return serializedValues; + } +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 15fdb58f00..d887503aa9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -7,6 +7,7 @@ using System.Diagnostics.Metrics; using System.Threading; using BenchmarkDotNet.Attributes; +using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Metrics; /* @@ -79,7 +80,7 @@ public class MetricExporterBenchmarks private MeterProvider meterProviderForCounterBatchWith4Dimensions; private MeterProvider meterProviderForHistogramBatchWith3Dimensions; private MeterProvider meterProviderForHistogramBatchWith4Dimensions; - private GenevaMetricExporter exporter; + private TlvMetricExporter tlvMetricsExporter; private ThreadLocal random = new ThreadLocal(() => new Random()); private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported @@ -94,7 +95,7 @@ public void Setup() this.counterWithGenevaMetricExporter = this.meterWithGenevaMetricExporter.CreateCounter("counter"); var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - this.exporter = new GenevaMetricExporter(exporterOptions); + this.tlvMetricsExporter = new TlvMetricExporter(exporterOptions); this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); this.counterMetricPointWith4Dimensions = this.GenerateCounterMetricItemWith4Dimensions(out this.counterMetricDataWith4Dimensions); @@ -445,7 +446,7 @@ public void Cleanup() this.meterProviderForCounterBatchWith4Dimensions?.Dispose(); this.meterProviderForHistogramBatchWith3Dimensions?.Dispose(); this.meterProviderForHistogramBatchWith4Dimensions?.Dispose(); - this.exporter?.Dispose(); + this.tlvMetricsExporter?.Dispose(); } [Benchmark] @@ -547,7 +548,7 @@ public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() [Benchmark] public void SerializeCounterMetricItemWith3Dimensions() { - this.exporter.SerializeMetricWithTLV( + this.tlvMetricsExporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith3Dimensions.Name, this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), @@ -563,7 +564,7 @@ public void SerializeCounterMetricItemWith3Dimensions() [Benchmark] public void SerializeCounterMetricItemWith4Dimensions() { - this.exporter.SerializeMetricWithTLV( + this.tlvMetricsExporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith4Dimensions.Name, this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), @@ -579,19 +580,19 @@ public void SerializeCounterMetricItemWith4Dimensions() [Benchmark] public void ExportCounterMetricItemWith3Dimensions() { - this.exporter.Export(this.counterMetricBatchWith3Dimensions); + this.tlvMetricsExporter.Export(this.counterMetricBatchWith3Dimensions); } [Benchmark] public void ExportCounterMetricItemWith4Dimensions() { - this.exporter.Export(this.counterMetricBatchWith4Dimensions); + this.tlvMetricsExporter.Export(this.counterMetricBatchWith4Dimensions); } [Benchmark] public void SerializeHistogramMetricItemWith3Dimensions() { - this.exporter.SerializeHistogramMetricWithTLV( + this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith3Dimensions.Name, this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), this.histogramMetricPointWith3Dimensions.Tags, @@ -610,7 +611,7 @@ public void SerializeHistogramMetricItemWith3Dimensions() [Benchmark] public void SerializeHistogramMetricItemWith4Dimensions() { - this.exporter.SerializeHistogramMetricWithTLV( + this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith4Dimensions.Name, this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), this.histogramMetricPointWith4Dimensions.Tags, @@ -629,13 +630,13 @@ public void SerializeHistogramMetricItemWith4Dimensions() [Benchmark] public void ExportHistogramMetricItemWith3Dimensions() { - this.exporter.Export(this.histogramMetricBatchWith3Dimensions); + this.tlvMetricsExporter.Export(this.histogramMetricBatchWith3Dimensions); } [Benchmark] public void ExportHistogramMetricItemWith4Dimensions() { - this.exporter.Export(this.histogramMetricBatchWith4Dimensions); + this.tlvMetricsExporter.Export(this.histogramMetricBatchWith4Dimensions); } private class DummyReader : BaseExportingMetricReader diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 05043cd8f3..5051f53e90 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -14,6 +14,7 @@ using System.Threading.Tasks; using Kaitai; using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; using Xunit; @@ -66,9 +67,9 @@ public void ParseConnectionStringCorrectly() server.Listen(1); } - using var exporter = new GenevaMetricExporter(exporterOptions); - var monitoringAccount = typeof(GenevaMetricExporter).GetField("defaultMonitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; - var metricNamespace = typeof(GenevaMetricExporter).GetField("defaultMetricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + using var exporter = new TlvMetricExporter(exporterOptions); + var monitoringAccount = typeof(TlvMetricExporter).GetField("defaultMonitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; + var metricNamespace = typeof(TlvMetricExporter).GetField("defaultMetricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; Assert.Equal("OTelMonitoringAccount", monitoringAccount); Assert.Equal("OTelMetricNamespace", metricNamespace); } @@ -159,7 +160,7 @@ public void SuccessfulExportOnLinux() // Create a test exporter to get byte data for validation of the data received via Socket. var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - using var exporter = new GenevaMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(exporterOptions); // Emit a metric and grab a copy of internal buffer for validation. counter.Add( @@ -206,7 +207,7 @@ public void SuccessfulExportOnLinux() var receivedData = new byte[1024]; int receivedDataSize = serverSocket.Receive(receivedData); - var fixedPayloadLength = (int)typeof(GenevaMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); + var fixedPayloadLength = (int)typeof(TlvMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); // The whole payload is sent to the Unix Domain Socket // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload @@ -518,7 +519,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars ["cloud.roleVer"] = "9.0.15289.2", }; - using var exporter = new GenevaMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(exporterOptions); inMemoryReader.Collect(); @@ -740,7 +741,7 @@ public void SuccessfulSerializationWithTLVWithViews() ["cloud.roleVer"] = "9.0.15289.2", }; - using var exporter = new GenevaMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(exporterOptions); inMemoryReader.Collect(); @@ -858,7 +859,7 @@ public void SuccessfulSerializationWithCustomAccountAndNamespace() ["cloud.roleVer"] = "9.0.15289.2", }; - using var exporter = new GenevaMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(exporterOptions); inMemoryReader.Collect(); @@ -899,7 +900,7 @@ public void SuccessfulSerializationWithCustomAccountAndNamespace() } [Fact] - public void AddGenevaMetricExporterNamedOptionsSupport() + public void AddTlvMetricsExporterNamedOptionsSupport() { string connectionString; string connectionStringForNamedOptions; @@ -966,7 +967,7 @@ private static void AssertHistogramBucketSerialization(HistogramBucket bucket, H Assert.Equal(bucket.BucketCount, valueCountPairs.Columns[listIterator].Count); } - private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, GenevaMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) + private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, TlvMetricExporter exporter, GenevaMetricExporterOptions exporterOptions) { var metricType = metric.MetricType; var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); @@ -996,7 +997,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); var userData = data.Body as UserdataV2; @@ -1024,7 +1025,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); var userData = data.Body as UserdataV2; @@ -1054,7 +1055,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); var userData = data.Body as UserdataV2; @@ -1084,7 +1085,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); var userData = data.Body as UserdataV2; @@ -1121,7 +1122,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); var userData = data.Body as UserdataV2; @@ -1303,7 +1304,7 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem } #endif - private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter exporter) + private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exporter) { var metricType = metric.MetricType; var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); @@ -1332,7 +1333,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); result = data.Body as UserdataV2; @@ -1353,7 +1354,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); result = data.Body as UserdataV2; @@ -1376,7 +1377,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); result = data.Body as UserdataV2; @@ -1399,7 +1400,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); result = data.Body as UserdataV2; @@ -1429,7 +1430,7 @@ private static UserdataV2 GetSerializedData(Metric metric, GenevaMetricExporter out _, out _); - var buffer = typeof(GenevaMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var buffer = typeof(TlvMetricExporter).GetField("buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; var stream = new KaitaiStream(buffer); var data = new MetricsContract(stream); result = data.Body as UserdataV2; From 1bd305b31e8a8fe3d6c43bca3a678601ab9a5364 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 27 Feb 2024 03:42:51 -0800 Subject: [PATCH 0974/1499] Editorial fix to make it easy to find maintainers (#1591) --- README.md | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c718ad4372..96a9d413e9 100644 --- a/README.md +++ b/README.md @@ -17,30 +17,34 @@ guidelines](./CONTRIBUTING.md). ## Support -This repository is maintained by [.NET Contrib -maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers) -team and [.NET Contrib -approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers) -who can help with reviews and code approval. However, as individual components -are developed by numerous contributors, approvers and maintainers are not -expected to directly contribute to every component. +This repository is maintained by [.NET Contrib maintainers](#maintainers) team +and [.NET Contrib approvers](#approvers) who can help with reviews and code +approval. However, as individual components are developed by numerous +contributors, approvers and maintainers are not expected to directly contribute +to every component. The list of owners for each component can be found +[here](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/component_owners.yml). -Triagers -([@open-telemetry/dotnet-contrib-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-triagers)): +### Triagers + +[@open-telemetry/dotnet-contrib-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-triagers): * [Martin Thwaites](https://github.com/martinjt), Honeycomb *Find more about the triager role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager).* -Approvers -([@open-telemetry/dotnet-contrib-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers)): +### Approvers + +[@open-telemetry/dotnet-contrib-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers): + +The are no approvers today. *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).* -Maintainers -([@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)): +### Maintainers + +[@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers): * [Alan West](https://github.com/alanwest), New Relic * [Cijo Thomas](https://github.com/cijothomas), Microsoft @@ -52,8 +56,9 @@ Maintainers *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* -[Emeritus -Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): +### Emeritus + +[Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): * [Prashant Srivastava](https://github.com/srprash) * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) From b26a36bb0fcbbba641b41469cef49bc537478c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 27 Feb 2024 17:05:36 +0100 Subject: [PATCH 0975/1499] [doc] add link to triager requierments (#1594) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 96a9d413e9..2f219da1d7 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,8 @@ community. See to the [community membership document](https://github.com/open-telemetry/community/blob/master/community-membership.md) on how to become a [**Member**](https://github.com/open-telemetry/community/blob/master/community-membership.md#member), -[**Approver**](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver) +[**Triager**](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager), +[**Approver**](https://github.com/open-telemetry/community/blob/master/community-membership.md#approver), and [**Maintainer**](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer). From 41ac9f4ca21aeb141d8916fd65393cfc8c23e578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 28 Feb 2024 20:36:55 +0100 Subject: [PATCH 0976/1499] Cleanup shared references (#1595) --- build/Common.props | 28 ------------------- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 - .../OpenTelemetry.Exporter.Instana.csproj | 5 +++- ...OpenTelemetry.Exporter.OneCollector.csproj | 2 +- .../OpenTelemetry.Exporter.Stackdriver.csproj | 2 +- .../OpenTelemetry.Extensions.AWS.csproj | 2 +- .../OpenTelemetry.Extensions.csproj | 2 +- ...entation.AspNet.TelemetryHttpModule.csproj | 2 +- ...penTelemetry.Instrumentation.AspNet.csproj | 6 ++-- ...Instrumentation.ElasticsearchClient.csproj | 11 +++++--- ...Instrumentation.EntityFrameworkCore.csproj | 8 ++++-- .../OpenTelemetry.Instrumentation.Owin.csproj | 4 +-- ...penTelemetry.Instrumentation.Quartz.csproj | 10 ++++--- ....Instrumentation.StackExchangeRedis.csproj | 1 - .../OpenTelemetry.Instrumentation.Wcf.csproj | 2 +- ...etry.PersistentStorage.Abstractions.csproj | 2 +- ...emetry.PersistentStorage.FileSystem.csproj | 2 +- ...OpenTelemetry.ResourceDetectors.AWS.csproj | 2 +- ...lemetry.ResourceDetectors.Container.csproj | 5 +++- ...penTelemetry.ResourceDetectors.Host.csproj | 5 +++- ...try.Instrumentation.AWSLambda.Tests.csproj | 3 +- ...mentation.ElasticsearchClient.Tests.csproj | 4 ++- ...mentation.EntityFrameworkCore.Tests.csproj | 3 ++ ...Instrumentation.EventCounters.Tests.csproj | 1 - ...emetry.Instrumentation.Quartz.Tests.csproj | 6 +++- 26 files changed, 57 insertions(+), 64 deletions(-) diff --git a/build/Common.props b/build/Common.props index f246020949..c7182d8a0d 100644 --- a/build/Common.props +++ b/build/Common.props @@ -55,35 +55,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 434af490f2..ba2dfbb4fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -10,7 +10,6 @@ net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- - true disable @@ -20,6 +19,7 @@ + diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index eed0b38f43..726cee834d 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -7,7 +7,6 @@ $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) Exporter.InfluxDB- - true diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 5e81f1fac0..f7ec063307 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -6,7 +6,6 @@ Instana Tracing APM Instana .NET Exporter for OpenTelemetry Exporter.Instana- - true disable @@ -24,4 +23,8 @@ + + + + diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index e3b1d699cd..e83ba75596 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -8,7 +8,6 @@ $(TargetFrameworks);net462 Exporter.OneCollector- true - true @@ -21,6 +20,7 @@ + diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 1fe5991dbd..c2bcdefe0c 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -5,7 +5,6 @@ Stackdriver .NET Exporter for OpenTelemetry. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- - true @@ -15,6 +14,7 @@ + diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index ce76f33559..d19543b384 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -5,7 +5,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Extensions.AWS- - true @@ -18,6 +17,7 @@ + diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index 1d85d7270d..de7b293fba 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -4,12 +4,12 @@ net6.0;netstandard2.0 $(TargetFrameworks);net462 - true OpenTelemetry .NET SDK preview features and extensions Extensions- + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 002e2ffad7..9010b97bd8 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -2,13 +2,13 @@ $(NetFrameworkMinimumSupportedVersion) - true A module that instruments incoming request with System.Diagnostics.Activity and notifies listeners with DiagnosticsSource. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI Instrumentation.AspNet- + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 3072fd37da..47240258be 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -2,7 +2,6 @@ $(NetFrameworkMinimumSupportedVersion) - true ASP.NET instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true @@ -14,9 +13,10 @@ - - + + + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 1f56188df9..0480587d23 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -6,10 +6,6 @@ Elasticsearch instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- - true - true - true - true true disable @@ -23,6 +19,13 @@ + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index b603317770..e54a6f1181 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -4,9 +4,6 @@ Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.EntityFrameworkCore- - true - true - true @@ -15,7 +12,12 @@ + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index dc1911a21c..e38d6b2d24 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -1,7 +1,6 @@ $(NetFrameworkMinimumSupportedVersion) - true OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- @@ -10,8 +9,9 @@ - + + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 2f957f3a2a..3c9323bb94 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -3,17 +3,19 @@ OpenTelemetry Quartz.NET Instrumentation $(PackageTags);distributed-tracing Instrumentation.Quartz- - true netstandard2.0 - true - true - true + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 353a227c63..4f392d1142 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -4,7 +4,6 @@ net6.0;netstandard2.0;net462 StackExchange.Redis instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;Redis;StackExchange.Redis - true Instrumentation.StackExchangeRedis- true diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 25be49ab72..3abd889cdf 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -3,7 +3,6 @@ netstandard2.0;net462 - true OpenTelemetry instrumentation for WCF $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- @@ -24,6 +23,7 @@ + diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index 98d3da7e26..c73f4c883f 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -5,13 +5,13 @@ netstandard2.0 $(TargetFrameworks);net462 net6.0;$(TargetFrameworks) - true OpenTelemetry Persistent Storage Abstractions PersistentStorage- $(NoWarn),1591 + diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 8e8b12199d..00a144671b 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -5,7 +5,6 @@ netstandard2.0 $(TargetFrameworks);net462 net6.0;$(TargetFrameworks) - true OpenTelemetry Persistent Storage PersistentStorage- @@ -19,6 +18,7 @@ + diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj index b5ad0ad470..41b1f8673a 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -6,7 +6,6 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. ResourceDetectors.AWS- - true @@ -22,6 +21,7 @@ + diff --git a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj index c4800a5350..c77f1af5e6 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj @@ -4,9 +4,12 @@ $(NetMinimumSupportedVersion) OpenTelemetry Extensions - Container Resource Detector from Container environment. ResourceDetectors.Container- - true + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj index 8f80566203..dbafb88169 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj @@ -5,9 +5,12 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - Host Resource Detector. ResourceDetectors.Host- - true + + + + diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 800954d217..d8c85549f4 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -3,8 +3,6 @@ Unit test project of OpenTelemetry instrumentation for AWS Lambda $(SupportedNetTargets) - true - true @@ -17,6 +15,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index aae7ec64e9..8ae7952754 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - true disable @@ -20,6 +19,9 @@ + + + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 4f1645e594..0eea99c2ce 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -29,4 +29,7 @@ + + + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index b26b644b8a..a22694028b 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -3,7 +3,6 @@ $(SupportedNetTargets) - true diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index a9171bb47f..8c95aaccc7 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -4,7 +4,6 @@ Unit test project for OpenTelemetry Quartz.NET instrumentation $(SupportedNetTargets) $(TargetFrameworks);net472 - true @@ -16,4 +15,9 @@ + + + + + From 1e237fe69973a055f83580d073c4f8b1e211049e Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Fri, 1 Mar 2024 11:02:19 -0800 Subject: [PATCH 0977/1499] Add ppittle as AWS component co-owner (#1598) --- .github/component_owners.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 8dc58d03f2..7a978f4db3 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -23,14 +23,17 @@ components: src/OpenTelemetry.Extensions.AWS/: - srprash - atshaw43 + - ppittle src/OpenTelemetry.Extensions.Enrichment/: - xakep139 src/OpenTelemetry.Instrumentation.AWS/: - srprash - atshaw43 + - ppittle src/OpenTelemetry.Instrumentation.AWSLambda/: - rypdal - Oberon00 + - ppittle src/OpenTelemetry.Instrumentation.Cassandra/: - xsoheilalizadeh src/OpenTelemetry.Instrumentation.ElasticsearchClient/: @@ -60,6 +63,7 @@ components: src/OpenTelemetry.ResourceDetectors.AWS/: - srprash - atshaw43 + - ppittle src/OpenTelemetry.ResourceDetectors.Azure/: - rajkumar-rangaraj - vishweshbankwar @@ -77,6 +81,7 @@ components: src/OpenTelemetry.Sampler.AWS/: - srprash - atshaw43 + - ppittle test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas - codeblanch @@ -112,6 +117,7 @@ components: test/OpenTelemetry.Extensions.AWS.Tests/: - srprash - atshaw43 + - ppittle test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 test/OpenTelemetry.Instrumentation.AWS.Tests/: @@ -120,6 +126,7 @@ components: test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: - rypdal - Oberon00 + - ppittle test/OpenTelemetry.Instrumentation.Cassandra.Tests/: - xsoheilalizadeh test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: @@ -145,6 +152,7 @@ components: test/OpenTelemetry.ResourceDetectors.AWS.Tests/: - srprash - atshaw43 + - ppittle test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - rajkumar-rangaraj - vishweshbankwar @@ -162,3 +170,4 @@ components: test/OpenTelemetry.Sampler.AWS.Tests/: - srprash - atshaw43 + - ppittle From b3cb1af7a14f84d6022d1f8026c7e90ba71a84a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 1 Mar 2024 21:04:44 +0100 Subject: [PATCH 0978/1499] Unify SpanHelper class (#1597) Co-authored-by: Vishwesh Bankwar --- build/Common.props | 4 --- ...penTelemetry.Instrumentation.AspNet.csproj | 1 + .../SpanHelper.cs | 30 ----------------- .../CHANGELOG.md | 2 ++ ...searchRequestPipelineDiagnosticListener.cs | 2 +- ...Instrumentation.ElasticsearchClient.csproj | 2 +- .../CHANGELOG.md | 2 ++ .../Implementation/DiagnosticsMiddleware.cs | 2 +- .../OpenTelemetry.Instrumentation.Owin.csproj | 2 +- src/Shared/SpanHelper.cs | 33 ++++--------------- 10 files changed, 15 insertions(+), 65 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs diff --git a/build/Common.props b/build/Common.props index c7182d8a0d..fb49fbfaec 100644 --- a/build/Common.props +++ b/build/Common.props @@ -54,8 +54,4 @@ - - - - diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 47240258be..319cb9d2df 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -17,6 +17,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs deleted file mode 100644 index 984620cc25..0000000000 --- a/src/OpenTelemetry.Instrumentation.AspNet/SpanHelper.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Diagnostics; - -namespace OpenTelemetry.Instrumentation.AspNet; - -/// -/// A collection of helper methods to be used when building spans. -/// -internal static class SpanHelper -{ - /// - /// Helper method that populates Activity Status from http status code according - /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. - /// - /// The span kind. - /// Http status code. - /// Resolved span for the Http status code. - public static ActivityStatusCode ResolveActivityStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) - { - var upperBound = kind == ActivityKind.Client ? 399 : 499; - if (httpStatusCode >= 100 && httpStatusCode <= upperBound) - { - return ActivityStatusCode.Unset; - } - - return ActivityStatusCode.Error; - } -} diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 4dd3a9b1e0..0d9f9ad44d 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Span status is set based on [semantic convention for client spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status). + ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 088b5ac32c..62c67ff332 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -124,7 +124,7 @@ public override void OnStopActivity(Activity activity, object payload) if (activity.IsAllDataRequested) { var statusCode = this.httpStatusFetcher.Fetch(payload); - activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(statusCode.GetValueOrDefault())); + activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, statusCode.GetValueOrDefault())); if (statusCode.HasValue) { diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 0480587d23..e955860579 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -6,7 +6,6 @@ Elasticsearch instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- - true disable @@ -27,5 +26,6 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index bbf1bd73d9..71b49ffaa7 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -10,6 +10,8 @@ ([#1335](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1335)) * Fix description for `http.server.request.duration` metric. ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) +* Span status is set based on [semantic convention for server spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status). + ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) ## 1.0.0-rc.3 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index de1e5af64c..9c15a7c40c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -172,7 +172,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception exception, lo } else if (activity.GetStatus().StatusCode == StatusCode.Unset) { - activity.SetStatus(SpanHelper.ResolveSpanStatusForHttpStatusCode(response.StatusCode)); + activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); } activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index e38d6b2d24..19e66285f7 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -4,7 +4,6 @@ OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- - true disable @@ -12,6 +11,7 @@ + diff --git a/src/Shared/SpanHelper.cs b/src/Shared/SpanHelper.cs index 9cd0503e8c..cff27b1f98 100644 --- a/src/Shared/SpanHelper.cs +++ b/src/Shared/SpanHelper.cs @@ -11,42 +11,21 @@ namespace OpenTelemetry.Trace; internal static class SpanHelper { /// - /// Helper method that populates span properties from http status code according - /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. - /// - /// Http status code. - /// Resolved span for the Http status code. - public static Status ResolveSpanStatusForHttpStatusCode(int httpStatusCode) - { - if (httpStatusCode >= 100 && httpStatusCode <= 399) - { - return Status.Unset; - } - - if (httpStatusCode == 404) - { - return Status.Unset; - } - - return Status.Error; - } - - /// - /// Helper method that populates span properties from http status code according - /// to https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status. + /// Helper method that populates Activity Status from http status code according + /// to https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status. /// /// The span kind. /// Http status code. - /// Resolved span for the Http status code. - public static Status ResolveSpanStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) + /// Resolved span for the Http status code. + public static ActivityStatusCode ResolveActivityStatusForHttpStatusCode(ActivityKind kind, int httpStatusCode) { var lowerBound = kind == ActivityKind.Client ? 400 : 500; var upperBound = 599; if (httpStatusCode >= lowerBound && httpStatusCode <= upperBound) { - return Status.Error; + return ActivityStatusCode.Error; } - return Status.Unset; + return ActivityStatusCode.Unset; } } From f7f8195e95b3b00a49a64400ba9dd835a3c7af51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 6 Mar 2024 06:40:29 +0100 Subject: [PATCH 0979/1499] [Instrumentation.AspNet, Instrumentation.Quartz] Use new PropertyFetcher (#1600) --- .../OpenTelemetry.Instrumentation.AspNet.csproj | 2 +- .../OpenTelemetry.Instrumentation.Quartz.csproj | 2 +- src/Shared/PropertyFetcher.AOT.cs | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 319cb9d2df..5fa9821675 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -15,7 +15,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 3c9323bb94..36421febf6 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -16,6 +16,6 @@ - + diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index 8b3acfd21f..a4f522263d 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -9,10 +9,14 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. #if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #endif +using System; +using System.Linq; using System.Reflection; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; From 268989e3c2334d5abf866a62cb7e92083fd273c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 6 Mar 2024 17:49:19 +0100 Subject: [PATCH 0980/1499] Bump internal dependencies (#1603) --- build/Common.nonprod.props | 6 +++--- build/Common.props | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index a9c9468210..627f240521 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -20,15 +20,15 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [0.13.10,0.14) + [0.13.12,0.14) [2.3.1,3.0) - [17.7.2,18.0) + [17.9.0,18.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net7.0;net6.0 [2.5.0,3.0) [2.5.0,3.0) - [1.5.32,2.0) + [1.5.48,2.0) diff --git a/build/Common.props b/build/Common.props index fb49fbfaec..6cfd2c3362 100644 --- a/build/Common.props +++ b/build/Common.props @@ -34,8 +34,8 @@ [3.1.0,) [1.0.3,2.0) [4.2.2,5.0) - [3.3.3] - [1.1.1,2.0) + [3.3.4] + [8.0.0,9.0) [1.7.0,2.0) [1.7.0-rc.1] [2.1.58,3.0) From 78d075c552d55a82560aa27a7e5a92f4e01e3c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 7 Mar 2024 18:02:51 +0100 Subject: [PATCH 0981/1499] [Instrumentation.AspNet] Rename options class to AspNetTraceInstrumentationOptions (#1604) --- .../.publicApi/net462/PublicAPI.Unshipped.txt | 18 +++++++++--------- .../AspNetInstrumentation.cs | 2 +- ...cs => AspNetTraceInstrumentationOptions.cs} | 2 +- .../CHANGELOG.md | 4 ++++ .../Implementation/HttpInListener.cs | 4 ++-- .../README.md | 4 ++-- .../TracerProviderBuilderExtensions.cs | 4 ++-- 7 files changed, 21 insertions(+), 17 deletions(-) rename src/OpenTelemetry.Instrumentation.AspNet/{AspNetInstrumentationOptions.cs => AspNetTraceInstrumentationOptions.cs} (97%) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt index 2f57288e06..3572fe9e04 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,19 +1,19 @@ -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.AspNetInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.get -> System.Func? -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.Filter.set -> void -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.get -> bool -OpenTelemetry.Instrumentation.AspNet.AspNetInstrumentationOptions.RecordException.set -> void OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.AspNetMetricsInstrumentationOptions() -> void OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.Enrich.get -> OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.EnrichFunc? OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.EnrichFunc +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.AspNetTraceInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Enrich.get -> System.Action? +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Filter.get -> System.Func? +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Filter.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.RecordException.set -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs index 380b945d94..b457461c30 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentation.cs @@ -17,7 +17,7 @@ internal sealed class AspNetInstrumentation : IDisposable /// Initializes a new instance of the class. /// /// Configuration options for ASP.NET instrumentation. - public AspNetInstrumentation(AspNetInstrumentationOptions options) + public AspNetInstrumentation(AspNetTraceInstrumentationOptions options) { this.httpInListener = new HttpInListener(options); } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs similarity index 97% rename from src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs rename to src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs index 21fb7fa442..809e1453e0 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs @@ -10,7 +10,7 @@ namespace OpenTelemetry.Instrumentation.AspNet; /// /// Options for ASP.NET instrumentation. /// -public class AspNetInstrumentationOptions +public class AspNetTraceInstrumentationOptions { /// /// Gets or sets a filter callback function that determines on a per diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 4a2f513a6f..e173fc4809 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* **Breaking Change**: Renamed `AspNetInstrumentationOptions` to + `AspNetTraceInstrumentationOptions`. + ([#1604](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1604)) + ## 1.7.0-beta.2 Released 2024-Feb-07 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index e0f2e1688f..ca9dd387a9 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -13,9 +13,9 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation; internal sealed class HttpInListener : IDisposable { private readonly HttpRequestRouteHelper routeHelper = new(); - private readonly AspNetInstrumentationOptions options; + private readonly AspNetTraceInstrumentationOptions options; - public HttpInListener(AspNetInstrumentationOptions options) + public HttpInListener(AspNetTraceInstrumentationOptions options) { Guard.ThrowIfNull(options); diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index e33ae97dc6..c3746b9028 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -131,14 +131,14 @@ Currently, the instrumentation supports the following metric. ## Advanced trace configuration This instrumentation can be configured to change the default behavior by using -`AspNetInstrumentationOptions`, which allows configuring `Filter` as explained +`AspNetTraceInstrumentationOptions`, which allows configuring `Filter` as explained below. ### Trace Filter This instrumentation by default collects all the incoming http requests. It allows filtering of requests by using the `Filter` function in -`AspNetInstrumentationOptions`. This defines the condition for allowable +`AspNetTraceInstrumentationOptions`. This defines the condition for allowable requests. The Filter receives the `HttpContext` of the incoming request, and does not collect telemetry about the request if the Filter returns false or throws exception. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs index 5df6ae2d43..dd2b8b413c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -28,11 +28,11 @@ public static TracerProviderBuilder AddAspNetInstrumentation(this TracerProvider /// The instance of to chain the calls. public static TracerProviderBuilder AddAspNetInstrumentation( this TracerProviderBuilder builder, - Action? configure) + Action? configure) { Guard.ThrowIfNull(builder); - var aspnetOptions = new AspNetInstrumentationOptions(); + var aspnetOptions = new AspNetTraceInstrumentationOptions(); configure?.Invoke(aspnetOptions); builder.AddInstrumentation(() => new AspNetInstrumentation(aspnetOptions)); From b66c3f854231c69c6c18c4a0fdcb6d44a7294f1a Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Mon, 11 Mar 2024 07:16:32 +0100 Subject: [PATCH 0982/1499] [ResourceDetectors.AWS] Implement support for some cloud.resource_id attribute in AWS ECS detector (#1576) --- .../AWSECSResourceDetector.cs | 1 + .../AWSSemanticConventions.cs | 1 + src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 2 ++ src/OpenTelemetry.ResourceDetectors.AWS/README.md | 6 +++--- .../AWSECSResourceDetectorTests.cs | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs index 8f91909529..709c56560d 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs @@ -101,6 +101,7 @@ internal static List> ExtractMetadataV4ResourceAttr var resourceAttributes = new List>() { + new KeyValuePair(AWSSemanticConventions.AttributeCloudResourceId, containerArn), new KeyValuePair(AWSSemanticConventions.AttributeEcsContainerArn, containerArn), new KeyValuePair(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn), }; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs index f8539f67fa..850e6f4a44 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs @@ -10,6 +10,7 @@ internal static class AWSSemanticConventions public const string AttributeCloudPlatform = "cloud.platform"; public const string AttributeCloudProvider = "cloud.provider"; public const string AttributeCloudRegion = "cloud.region"; + public const string AttributeCloudResourceId = "cloud.resource_id"; public const string AttributeContainerID = "container.id"; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 5d34286e6f..82ad697131 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -5,6 +5,8 @@ * Implement support for cloud.{account.id,availability_zone,region} attributes in AWS ECS detector. ([#1552](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1552)) +* Implement support for `cloud.resource_id` attribute in AWS ECS detector. + ([#1576](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1576)) ## 1.4.0-beta.1 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/README.md b/src/OpenTelemetry.ResourceDetectors.AWS/README.md index 3d47727b1b..f5317a52b3 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/README.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/README.md @@ -40,9 +40,9 @@ your application is running: cloud availability zone, host id, host type, aws region, host name. - **AWSEBSResourceDetector**: cloud provider, cloud platform, service name, service namespace, instance id, service version. -- **AWSECSResourceDetector**: cloud provider, cloud platform, account id, -cloud availability zone, cloud region, container id, cluster arn, task arn, -task family, task revision, launch type, container arn, log group names, +- **AWSECSResourceDetector**: cloud provider, cloud platform, cloud resource id, +account id, cloud availability zone, cloud region, container id, cluster arn, +task arn, task family, task revision, launch type, container arn, log group names, log group ids, log stream names, log stream ids. - **AWSEKSResourceDetector**: cloud provider, cloud platform, cluster name, container id. diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs index a47e560888..476c5ecb5d 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs @@ -76,6 +76,7 @@ public async void TestEcsMetadataV4Ec2() Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID], "111122223333"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2d"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudRegion], "us-west-2"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudResourceId], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsLaunchtype], "ec2"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/158d1c8083dd49d6b527399fd6414f5c"); @@ -107,6 +108,7 @@ public async void TestEcsMetadataV4Fargate() Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAccountID], "111122223333"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudAvailabilityZone], "us-west-2a"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudRegion], "us-west-2"); + Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeCloudResourceId], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsContainerArn], "arn:aws:ecs:us-west-2:111122223333:container/05966557-f16c-49cb-9352-24b3a0dcd0e1"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsLaunchtype], "fargate"); Assert.Equal(resourceAttributes[AWSSemanticConventions.AttributeEcsTaskArn], "arn:aws:ecs:us-west-2:111122223333:task/default/e9028f8d5d8e4f258373e7b93ce9a3c3"); From 609565ce653527e550bc3254f429d8f04344f860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 12 Mar 2024 18:30:44 +0100 Subject: [PATCH 0983/1499] [ResourceDetector.Process] support process.owner attribute (#1608) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Robert Pająk Co-authored-by: Vishwesh Bankwar --- src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 3 +++ .../ProcessDetector.cs | 5 ++--- .../ProcessSemanticConventions.cs | 1 + src/OpenTelemetry.ResourceDetectors.Process/README.md | 2 +- .../ProcessDetectorTests.cs | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index c67f34e3af..a186213b41 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added `process.owner` attribute. + ([#1608](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1608)) + ## 0.1.0-alpha.2 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs b/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs index 1fc900576f..c02f3b5739 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Process/ProcessDetector.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER using System; -#endif using System.Collections.Generic; using OpenTelemetry.Resources; @@ -20,8 +18,9 @@ public sealed class ProcessDetector : IResourceDetector /// Resource with key-value pairs of resource attributes. public Resource Detect() { - return new Resource(new List>(1) + return new Resource(new List>(2) { + new(ProcessSemanticConventions.AttributeProcessOwner, Environment.UserName), #if NET6_0_OR_GREATER new(ProcessSemanticConventions.AttributeProcessPid, Environment.ProcessId), #else diff --git a/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs index 26ff48b894..bb18021653 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.Process/ProcessSemanticConventions.cs @@ -5,5 +5,6 @@ namespace OpenTelemetry.ResourceDetectors.Process; internal static class ProcessSemanticConventions { + public const string AttributeProcessOwner = "process.owner"; public const string AttributeProcessPid = "process.pid"; } diff --git a/src/OpenTelemetry.ResourceDetectors.Process/README.md b/src/OpenTelemetry.ResourceDetectors.Process/README.md index d191c6732e..e334acf3c1 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/README.md @@ -36,7 +36,7 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() The resource detectors will record the following metadata based on where your application is running: -- **ProcessDetector**: `process.pid`. +- **ProcessDetector**: `process.owner`, `process.pid`. ## References diff --git a/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs index 98c3ade236..1ffa15bfe0 100644 --- a/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Process.Tests/ProcessDetectorTests.cs @@ -16,8 +16,9 @@ public void TestProcessAttributes() var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); - Assert.Single(resourceAttributes); + Assert.Equal(2, resourceAttributes.Count); + Assert.IsType(resourceAttributes[ProcessSemanticConventions.AttributeProcessOwner]); Assert.IsType(resourceAttributes[ProcessSemanticConventions.AttributeProcessPid]); } } From 01c225798cefa2fe89637b78815c0a6a0c6b4c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 13 Mar 2024 23:30:50 +0100 Subject: [PATCH 0984/1499] [Instrumentation.Owin] Nullable (#1601) --- .../.publicApi/net462/PublicAPI.Shipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 12 ++++++------ .../Implementation/DiagnosticsMiddleware.cs | 10 +++++----- .../OwinInstrumentationActivitySource.cs | 4 ++-- .../OpenTelemetry.Instrumentation.Owin.csproj | 1 - .../OwinInstrumentationOptions.cs | 4 ++-- .../TracerProviderBuilderExtensions.cs | 2 +- .../Controllers/TestController.cs | 2 +- .../DiagnosticsMiddlewareTests.cs | 8 ++++---- .../OpenTelemetry.Instrumentation.Owin.Tests.csproj | 1 - 10 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt index 761ae2d2ff..0d125870ad 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt @@ -2,9 +2,9 @@ OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType.BeginRequest = 0 -> OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType.EndRequest = 1 -> OpenTelemetry.Instrumentation.Owin.OwinEnrichEventType OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions -OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Filter.get -> System.Func? OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.OwinInstrumentationOptions() -> void OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.get -> bool @@ -12,7 +12,7 @@ OpenTelemetry.Instrumentation.Owin.OwinInstrumentationOptions.RecordException.se OpenTelemetry.Metrics.OwinInstrumentationMeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions Owin.AppBuilderExtensions -static OpenTelemetry.Metrics.OwinInstrumentationMeterProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static Owin.AppBuilderExtensions.UseOpenTelemetry(this Owin.IAppBuilder appBuilder) -> Owin.IAppBuilder \ No newline at end of file +static OpenTelemetry.Metrics.OwinInstrumentationMeterProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddOwinInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static Owin.AppBuilderExtensions.UseOpenTelemetry(this Owin.IAppBuilder! appBuilder) -> Owin.IAppBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 9c15a7c40c..6b435ef87b 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -77,7 +77,7 @@ private static void BeginRequest(IOwinContext owinContext) var textMapPropagator = Propagators.DefaultTextMapPropagator; var ctx = textMapPropagator.Extract(default, owinContext.Request, OwinRequestHeaderValuesGetter); - Activity activity = OwinInstrumentationActivitySource.ActivitySource.StartActivity( + Activity? activity = OwinInstrumentationActivitySource.ActivitySource.StartActivity( OwinInstrumentationActivitySource.IncomingRequestActivityName, ActivityKind.Server, ctx.ActivityContext); @@ -123,7 +123,7 @@ private static void BeginRequest(IOwinContext owinContext) try { - OwinInstrumentationActivitySource.Options.Enrich?.Invoke( + OwinInstrumentationActivitySource.Options?.Enrich?.Invoke( activity, OwinEnrichEventType.BeginRequest, owinContext, @@ -147,7 +147,7 @@ private static void BeginRequest(IOwinContext owinContext) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void RequestEnd(IOwinContext owinContext, Exception exception, long startTimestamp) + private static void RequestEnd(IOwinContext owinContext, Exception? exception, long startTimestamp) { if (owinContext.Environment.TryGetValue(ContextKey, out object context) && context is Activity activity) @@ -165,7 +165,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception exception, lo { activity.SetStatus(Status.Error); - if (OwinInstrumentationActivitySource.Options.RecordException) + if (OwinInstrumentationActivitySource.Options != null && OwinInstrumentationActivitySource.Options.RecordException) { activity.RecordException(exception); } @@ -179,7 +179,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception exception, lo try { - OwinInstrumentationActivitySource.Options.Enrich?.Invoke( + OwinInstrumentationActivitySource.Options?.Enrich?.Invoke( activity, OwinEnrichEventType.EndRequest, owinContext, diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index 7537360628..319d337db7 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -15,7 +15,7 @@ internal static class OwinInstrumentationActivitySource private static readonly Version Version = AssemblyName.Version; - public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); + public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, Version.ToString()); - public static OwinInstrumentationOptions Options { get; set; } + public static OwinInstrumentationOptions? Options { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 19e66285f7..7e5c9223a6 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -4,7 +4,6 @@ OpenTelemetry instrumentation for OWIN $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- - disable diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index 3c1ba76356..57f98e812d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -18,12 +18,12 @@ public class OwinInstrumentationOptions /// If Filter returns true, the request is collected. /// If Filter returns false or throw exception, the request is filtered out. /// - public Func Filter { get; set; } + public Func? Filter { get; set; } /// /// Gets or sets an action to enrich the created by the instrumentation. /// - public Action Enrich { get; set; } + public Action? Enrich { get; set; } /// /// Gets or sets a value indicating whether the exception will be recorded as or not. diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index 6fe62ea930..ca55244d23 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -28,7 +28,7 @@ public static TracerProviderBuilder AddOwinInstrumentation(this TracerProviderBu /// The instance of to chain the calls. public static TracerProviderBuilder AddOwinInstrumentation( this TracerProviderBuilder builder, - Action configure) + Action? configure) { Guard.ThrowIfNull(builder); diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs index bf7f20b9ae..d6d9145462 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/Controllers/TestController.cs @@ -8,7 +8,7 @@ namespace OpenTelemetry.Instrumentation.Owin.Tests.Controllers; public class TestController : ApiController { // GET api/test/{id} - public string Get(string id = null) + public string Get(string? id = null) { return $"id:{id}"; } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index fa89a01b00..d2111ab468 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -22,19 +22,18 @@ namespace OpenTelemetry.Instrumentation.Owin.Tests; public class DiagnosticsMiddlewareTests : IDisposable { private readonly Uri serviceBaseUri; - private readonly IDisposable listener; + private readonly IDisposable? listener; private readonly EventWaitHandle requestCompleteHandle = new(false, EventResetMode.AutoReset); public DiagnosticsMiddlewareTests() { Random random = new Random(); var retryCount = 5; - while (retryCount > 0) + do { + this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); try { - this.serviceBaseUri = new Uri($"http://localhost:{random.Next(2000, 5000)}/"); - this.listener = WebApp.Start( this.serviceBaseUri.ToString(), appBuilder => @@ -81,6 +80,7 @@ public DiagnosticsMiddlewareTests() retryCount--; } } + while (retryCount > 0); if (this.listener == null) { diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index 1ef3fee142..e61f3950e7 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -3,7 +3,6 @@ Unit test project for OpenTelemetry OWIN instrumentation $(NetFrameworkMinimumSupportedVersion) - disable From 27a973b3cf862bf1b742146f1a6937251657980e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 14 Mar 2024 06:36:53 +0100 Subject: [PATCH 0985/1499] [Instrumentation.AspNet] metrics - remove server attributes (#1606) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Łach --- .../AspNetMetricsInstrumentationOptions.cs | 5 +++++ .../CHANGELOG.md | 3 +++ .../Implementation/HttpInMetricsListener.cs | 8 ++++++-- .../HttpInMetricsListenerTests.cs | 16 +++++++++++++--- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs index e048e22990..e475f160b8 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetricsInstrumentationOptions.cs @@ -22,4 +22,9 @@ public sealed class AspNetMetricsInstrumentationOptions /// Gets or sets an function to enrich a recorded metric with additional custom tags. /// public EnrichFunc? Enrich { get; set; } + + /// + /// Gets or sets a value indicating whether emit server.address and server.port attributes. + /// + internal bool EnableServerAttributesForRequestDuration { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index e173fc4809..f92eda8790 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -5,6 +5,9 @@ * **Breaking Change**: Renamed `AspNetInstrumentationOptions` to `AspNetTraceInstrumentationOptions`. ([#1604](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1604)) +* **Breaking Change**: `server.address` and `server.port` no longer added + for `http.server.request.duration` metric. + ([#1606](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1606)) ## 1.7.0-beta.2 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index 9200911cb9..3607f4a465 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -49,12 +49,16 @@ private void OnStopActivity(Activity activity, HttpContext context) var url = request.Url; var tags = new TagList { - { SemanticConventions.AttributeServerAddress, url.Host }, - { SemanticConventions.AttributeServerPort, url.Port }, { SemanticConventions.AttributeUrlScheme, url.Scheme }, { SemanticConventions.AttributeHttpResponseStatusCode, context.Response.StatusCode }, }; + if (this.options.EnableServerAttributesForRequestDuration) + { + tags.Add(SemanticConventions.AttributeServerAddress, url.Host); + tags.Add(SemanticConventions.AttributeServerPort, url.Port); + } + var normalizedMethod = this.requestMethodHelper.GetNormalizedHttpMethod(request.HttpMethod); tags.Add(SemanticConventions.AttributeHttpRequestMethod, normalizedMethod); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index eb418eb263..b5c6ddf904 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -17,7 +17,9 @@ public class HttpInMetricsListenerTests { [Theory] [InlineData("http://localhost/", 0, null, null, "http", "localhost", null, 80, 200)] + [InlineData("http://localhost/", 0, null, null, "http", null, null, null, 200, false)] [InlineData("https://localhost/", 0, null, null, "https", "localhost", null, 443, 200)] + [InlineData("https://localhost/", 0, null, null, "https", null, null, null, 200, false)] [InlineData("http://localhost/api/value", 0, null, null, "http", "localhost", null, 80, 200)] [InlineData("http://localhost/api/value", 1, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 200)] [InlineData("http://localhost/api/value", 2, "{controller}/{action}", null, "http", "localhost", "{controller}/{action}", 80, 201)] @@ -35,10 +37,11 @@ public void AspNetMetricTagsAreCollectedSuccessfully( string routeTemplate, string enrichMode, string expectedScheme, - string expectedHost, + string? expectedHost, string expectedRoute, int? expectedPort, - int expectedStatus) + int expectedStatus, + bool enableServerAttributesForRequestDuration = true) { double duration = 0; HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); @@ -62,6 +65,8 @@ public void AspNetMetricTagsAreCollectedSuccessfully( using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddAspNetInstrumentation(options => { + options.EnableServerAttributesForRequestDuration = enableServerAttributesForRequestDuration; + options.Enrich += (HttpContext context, ref TagList tags) => { if (enrichMode == "throw") @@ -106,7 +111,12 @@ public void AspNetMetricTagsAreCollectedSuccessfully( Assert.Equal(duration, sum); Assert.True(duration > 0, "Metric duration should be set."); - var expectedTagCount = 5; + var expectedTagCount = 3; + + if (enableServerAttributesForRequestDuration) + { + expectedTagCount += 2; + } if (!string.IsNullOrEmpty(expectedRoute)) { From 3496293400fff756ff5b934a62b6afac5c67f96e Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Thu, 14 Mar 2024 22:27:20 -0700 Subject: [PATCH 0986/1499] [PersistantStorage] fix event source throws `System.FormatException` (#1613) --- opentelemetry-dotnet-contrib.sln | 7 +++++++ .../AssemblyInfo.cs | 15 +++++++++++++++ .../CHANGELOG.md | 5 +++++ .../PersistentStorageEventSource.cs | 2 +- .../EventSourceTests.cs | 16 ++++++++++++++++ ...PersistentStorage.Abstractions.Tests.csproj | 18 ++++++++++++++++++ .../EventSourceTests.cs | 16 ++++++++++++++++ ...y.PersistentStorage.FileSystem.Tests.csproj | 5 +++++ 8 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 test/OpenTelemetry.PersistentStorage.Abstractions.Tests/EventSourceTests.cs create mode 100644 test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj create mode 100644 test/OpenTelemetry.PersistentStorage.FileSystem.Tests/EventSourceTests.cs diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 09fac45779..6f4bc45249 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -341,6 +341,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host.Tests", "test\OpenTelemetry.ResourceDetectors.Host.Tests\OpenTelemetry.ResourceDetectors.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.PersistentStorage.Abstractions.Tests", "test\OpenTelemetry.PersistentStorage.Abstractions.Tests\OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj", "{7AD707F9-DC6D-430A-8834-D5DCD517BF6E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -683,6 +685,10 @@ Global {36271347-2055-438E-9659-B71542A17A73}.Debug|Any CPU.Build.0 = Debug|Any CPU {36271347-2055-438E-9659-B71542A17A73}.Release|Any CPU.ActiveCfg = Release|Any CPU {36271347-2055-438E-9659-B71542A17A73}.Release|Any CPU.Build.0 = Release|Any CPU + {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -785,6 +791,7 @@ Global {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs index f598806af3..9bda103541 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/AssemblyInfo.cs @@ -2,5 +2,20 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] + +[assembly: InternalsVisibleTo("OpenTelemetry.PersistentStorage.Abstractions.Tests" + AssemblyInfo.PublicKey)] + +#if SIGNED +internal static class AssemblyInfo +{ + public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; +} +#else +internal static class AssemblyInfo +{ + public const string PublicKey = ""; +} +#endif diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index b4be7dcdc7..14a7d7600b 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog - OpenTelemetry.PersistentStorage.FileSystem +## Unrealeased + +* Fix `System.FormatException` thrown by `PersistentStorageEventSource`. + [#1613](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1613) + ## 1.0.0 Released 2023-Aug-28 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs index 178021be6c..881b54261e 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageEventSource.cs @@ -146,7 +146,7 @@ public void CouldNotRemoveExpiredLease(string srcFilePath, string destFilePath, this.WriteEvent(8, srcFilePath, destFilePath, ex); } - [Event(9, Message = "{0}: Error Message: {1}. Exception: {3}", Level = EventLevel.Error)] + [Event(9, Message = "{0}: Error Message: {1}. Exception: {2}", Level = EventLevel.Error)] public void PersistentStorageException(string className, string message, string ex) { this.WriteEvent(9, className, message, ex); diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/EventSourceTests.cs b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/EventSourceTests.cs new file mode 100644 index 0000000000..51b75b0d26 --- /dev/null +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/EventSourceTests.cs @@ -0,0 +1,16 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.PersistentStorage.Abstractions.Tests; + +public class EventSourceTests +{ + [Fact] + public void EventSourceTest_PersistentStorageEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(PersistentStorageAbstractionsEventSource.Log); + } +} diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj new file mode 100644 index 0000000000..faea9a07ba --- /dev/null +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj @@ -0,0 +1,18 @@ + + + + + $(SupportedNetTargets) + $(TargetFrameworks);net462 + + + + + + + + + + + + diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/EventSourceTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/EventSourceTests.cs new file mode 100644 index 0000000000..020796e929 --- /dev/null +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/EventSourceTests.cs @@ -0,0 +1,16 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; + +public class EventSourceTests +{ + [Fact] + public void EventSourceTest_PersistentStorageEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(PersistentStorageEventSource.Log); + } +} diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 3d69fb68ae..dd08c02094 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -10,4 +10,9 @@ + + + + + From 219e41848a810479c2024c2e48b8cb7ae3a5d3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 15 Mar 2024 20:10:53 +0100 Subject: [PATCH 0987/1499] [Instrumentation.Redis] Fix and modernize example (#1612) --- .../Examples.StackExchangeRedis.csproj | 4 +- .../Examples.StackExchangeRedis/Program.cs | 50 ++++++++----------- .../Examples.StackExchangeRedis/README.md | 48 ++++++++++-------- 3 files changed, 50 insertions(+), 52 deletions(-) diff --git a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj index 020e4c48c1..c1ce1cc246 100644 --- a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj +++ b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj @@ -2,12 +2,12 @@ Exe - net6.0 + net8.0 enable - + diff --git a/examples/redis/Examples.StackExchangeRedis/Program.cs b/examples/redis/Examples.StackExchangeRedis/Program.cs index 7cd9bba90a..de2f5af9b3 100644 --- a/examples/redis/Examples.StackExchangeRedis/Program.cs +++ b/examples/redis/Examples.StackExchangeRedis/Program.cs @@ -5,35 +5,29 @@ using OpenTelemetry.Trace; using StackExchange.Redis; -public class Program -{ - public static void Main() - { - // Prerequisite: - /* - * Setup redis service inside local docker. - * docker run --name opentelemetry-redis-test -d -p 6379:6379 redis - */ +// Prerequisite: +/* + * Setup redis service inside local docker. + * docker run --name opentelemetry-redis-test -d -p 6379:6379 redis + */ - // connect to the redis server. The default port 6379 will be used. - var connection = ConnectionMultiplexer.Connect("localhost"); +// connect to the redis server. The default port 6379 will be used. +var connection = ConnectionMultiplexer.Connect("localhost"); - // Configure exporter to export traces to Zipkin - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddConsoleExporter() - .AddRedisInstrumentation(connection, options => - { - // changing flush interval from 10s to 5s - options.FlushInterval = TimeSpan.FromSeconds(5); - }) - .Build(); +// Configure exporter to export traces to Zipkin +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddConsoleExporter() + .AddRedisInstrumentation(connection, options => + { + // changing flush interval from 10s to 5s + options.FlushInterval = TimeSpan.FromSeconds(5); + }) + .Build(); - // select a database (by default, DB = 0) - var db = connection.GetDatabase(); - db.StringSet("key", "value " + DateTime.Now.ToLongDateString()); - Thread.Sleep(1000); +// select a database (by default, DB = 0) +var db = connection.GetDatabase(); +db.StringSet("key", "value " + DateTime.Now.ToLongDateString()); +Thread.Sleep(1000); - // run a command, in this case a GET - var myVal = db.StringGet("key"); - } -} +// run a command, in this case a GET +var myVal = db.StringGet("key"); diff --git a/examples/redis/Examples.StackExchangeRedis/README.md b/examples/redis/Examples.StackExchangeRedis/README.md index ced8f7944b..d8217b3975 100644 --- a/examples/redis/Examples.StackExchangeRedis/README.md +++ b/examples/redis/Examples.StackExchangeRedis/README.md @@ -7,14 +7,14 @@ this application (please look at the prerequisite for running the application in [Program.cs](./Program.cs): ```text -Activity.TraceId: f1a47baec558ebb97e57a6fb7d029a29 -Activity.SpanId: d0abf2503ad3d1b6 -Activity.TraceFlags: Recorded +Activity.TraceId: ebf13ff051d73072f87d07ebf08d5f26 +Activity.SpanId: 326c619dbda12231 +Activity.TraceFlags: Recorded Activity.ActivitySourceName: OpenTelemetry.Instrumentation.StackExchangeRedis -Activity.DisplayName: SET -Activity.Kind: Client -Activity.StartTime: 2022-06-06T22:17:40.8927802Z -Activity.Duration: 00:00:00.0237767 +Activity.DisplayName: SET +Activity.Kind: Client +Activity.StartTime: 2024-03-14T09:35:28.1473251Z +Activity.Duration: 00:00:00.0050600 Activity.Tags: db.system: redis db.redis.flags: DemandMaster @@ -22,22 +22,24 @@ Activity.Tags: net.peer.name: localhost net.peer.port: 6379 db.redis.database_index: 0 - StatusCode : UNSET Activity.Events: - Enqueued [6/6/2022 10:17:40 PM +00:00] - Sent [6/6/2022 10:17:40 PM +00:00] - ResponseReceived [6/6/2022 10:17:40 PM +00:00] + Enqueued [3/14/2024 9:35:28 AM +00:00] + Sent [3/14/2024 9:35:28 AM +00:00] + ResponseReceived [3/14/2024 9:35:28 AM +00:00] Resource associated with Activity: + telemetry.sdk.name: opentelemetry + telemetry.sdk.language: dotnet + telemetry.sdk.version: 1.7.0 service.name: unknown_service:Examples.StackExchangeRedis -Activity.TraceId: 0db37d796826693e23b17e3b082356a4 -Activity.SpanId: cd01d518b8b5cfa2 -Activity.TraceFlags: Recorded +Activity.TraceId: 1824275fc972c4f0f3180a175ba38acc +Activity.SpanId: 734196993db5b8dd +Activity.TraceFlags: Recorded Activity.ActivitySourceName: OpenTelemetry.Instrumentation.StackExchangeRedis -Activity.DisplayName: GET -Activity.Kind: Client -Activity.StartTime: 2022-06-06T22:17:41.9223474Z -Activity.Duration: 00:00:00.0067062 +Activity.DisplayName: GET +Activity.Kind: Client +Activity.StartTime: 2024-03-14T09:35:29.1575041Z +Activity.Duration: 00:00:00.0031683 Activity.Tags: db.system: redis db.redis.flags: None @@ -45,11 +47,13 @@ Activity.Tags: net.peer.name: localhost net.peer.port: 6379 db.redis.database_index: 0 - StatusCode : UNSET Activity.Events: - Enqueued [6/6/2022 10:17:41 PM +00:00] - Sent [6/6/2022 10:17:41 PM +00:00] - ResponseReceived [6/6/2022 10:17:41 PM +00:00] + Enqueued [3/14/2024 9:35:29 AM +00:00] + Sent [3/14/2024 9:35:29 AM +00:00] + ResponseReceived [3/14/2024 9:35:29 AM +00:00] Resource associated with Activity: + telemetry.sdk.name: opentelemetry + telemetry.sdk.language: dotnet + telemetry.sdk.version: 1.7.0 service.name: unknown_service:Examples.StackExchangeRedis ``` From 41c0a2d310c1dbbb880fe35641f524d6ba1bf3a6 Mon Sep 17 00:00:00 2001 From: Gunnar Liljas Date: Wed, 20 Mar 2024 21:21:02 +0100 Subject: [PATCH 0988/1499] [Instrumentation.Owin] Release 1.0.0-rc.4 (#1620) --- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 71b49ffaa7..a550c6f6a8 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.4 + +Released 2024-Mar-20 + * Updated OpenTelemetry SDK to 1.7.0. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Removes `AddOwinInstrumentation` method with default configure parameter. From ac4fe159fe56e189ec81eab1383dac2fe058ec77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 25 Mar 2024 18:32:00 +0100 Subject: [PATCH 0989/1499] [Instrumentation.AspNet] Spans - semantic convention v1.24.0 (#1607) --- .../CHANGELOG.md | 17 +++- .../Implementation/HttpInListener.cs | 62 +++++++----- .../Implementation/HttpInMetricsListener.cs | 18 +--- ...stMethodHelper.cs => RequestDataHelper.cs} | 34 ++++++- src/Shared/SemanticConventions.cs | 5 + .../HttpInListenerTests.cs | 94 +++++++++---------- .../HttpInMetricsListenerTests.cs | 2 +- ...lperTests.cs => RequestDataHelperTests.cs} | 17 +++- .../RouteTestHelper.cs | 8 +- .../TestHttpWorkerRequest.cs | 18 +++- 10 files changed, 170 insertions(+), 105 deletions(-) rename src/OpenTelemetry.Instrumentation.AspNet/Implementation/{RequestMethodHelper.cs => RequestDataHelper.cs} (62%) rename test/OpenTelemetry.Instrumentation.AspNet.Tests/{RequestMethodHelperTests.cs => RequestDataHelperTests.cs} (77%) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index f92eda8790..a5c732e472 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -8,6 +8,21 @@ * **Breaking Change**: `server.address` and `server.port` no longer added for `http.server.request.duration` metric. ([#1606](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1606)) +* **Breaking change** Spans names and attributes + will be set as per [HTTP semantic convention v1.24.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md): + * span names follows: `{HTTP method} [route name if available]` pattern + * `error.type` added when exception occurred while processing request, + * `http.request.method` replaces `http.method`, + * `http.request.method_original` added when `http.request.method` is not in + canonical form, + * `http.response.status_code` replaces `http.status_code`, + * `network.protocol.version` added with HTTP version value, + * `server.address` and `server.port` replace `http.host`, + * `url.path` replaces `http.target`, + * `url.query` added when query url part is not empty, + * `url.scheme` added with `http` or `https` value, + * `user_agent.original` replaces `http.user_agent`. + ([#1607](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1607)) ## 1.7.0-beta.2 @@ -96,7 +111,7 @@ Released 2022-Nov-28 Released 2022-Sep-28 -* Migrate to native Activity `Status` and `StatusDesciption`. +* Migrate to native Activity `Status` and `StatusDescription`. ([#651](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/651)) ## 1.0.0-rc9.5 (source code moved to contrib repo) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index ca9dd387a9..0337c56eaa 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -14,6 +14,7 @@ internal sealed class HttpInListener : IDisposable { private readonly HttpRequestRouteHelper routeHelper = new(); private readonly AspNetTraceInstrumentationOptions options; + private readonly RequestDataHelper requestDataHelper = new(); public HttpInListener(AspNetTraceInstrumentationOptions options) { @@ -35,16 +36,6 @@ public void Dispose() TelemetryHttpModule.Options.OnExceptionCallback -= this.OnException; } - /// - /// Gets the OpenTelemetry standard uri tag value for a span based on its request . - /// - /// . - /// Span uri value. - private static string GetUriTagValueFromRequestUri(Uri uri) - { - return string.IsNullOrEmpty(uri.UserInfo) ? uri.ToString() : string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); - } - private void OnStartActivity(Activity activity, HttpContext context) { if (activity.IsAllDataRequested) @@ -76,23 +67,45 @@ private void OnStartActivity(Activity activity, HttpContext context) var request = context.Request; var requestValues = request.Unvalidated; - // see the spec https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md - var path = requestValues.Path; - activity.DisplayName = path; + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md + var originalHttpMethod = request.HttpMethod; + var normalizedHttpMethod = this.requestDataHelper.GetNormalizedHttpMethod(originalHttpMethod); + activity.DisplayName = normalizedHttpMethod == "_OTHER" ? "HTTP" : normalizedHttpMethod; + + var url = request.Url; + activity.SetTag(SemanticConventions.AttributeServerAddress, url.Host); + activity.SetTag(SemanticConventions.AttributeServerPort, url.Port); + activity.SetTag(SemanticConventions.AttributeUrlScheme, url.Scheme); - if (request.Url.Port == 80 || request.Url.Port == 443) + this.requestDataHelper.SetHttpMethodTag(activity, originalHttpMethod); + + var protocolVersion = RequestDataHelper.GetHttpProtocolVersion(request); + if (!string.IsNullOrEmpty(protocolVersion)) { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, protocolVersion); } - else + + activity.SetTag(SemanticConventions.AttributeUrlPath, requestValues.Path); + + // TODO url.query should be sanitized + var query = url.Query; + if (!string.IsNullOrEmpty(query)) { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Url.Host + ":" + request.Url.Port); + if (query.StartsWith("?", StringComparison.InvariantCulture)) + { + activity.SetTag(SemanticConventions.AttributeUrlQuery, query.Substring(1)); + } + else + { + activity.SetTag(SemanticConventions.AttributeUrlQuery, query); + } } - activity.SetTag(SemanticConventions.AttributeHttpMethod, request.HttpMethod); - activity.SetTag(SemanticConventions.AttributeHttpTarget, path); - activity.SetTag(SemanticConventions.AttributeHttpUserAgent, request.UserAgent); - activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Url)); + var userAgent = request.UserAgent; + if (!string.IsNullOrEmpty(userAgent)) + { + activity.SetTag(SemanticConventions.AttributeUserAgentOriginal, userAgent); + } try { @@ -111,7 +124,7 @@ private void OnStopActivity(Activity activity, HttpContext context) { var response = context.Response; - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, response.StatusCode); if (activity.Status == ActivityStatusCode.Unset) { @@ -122,8 +135,8 @@ private void OnStopActivity(Activity activity, HttpContext context) if (!string.IsNullOrEmpty(template)) { - // Override the name that was previously set to the path part of URL. - activity.DisplayName = template!; + // Override the name that was previously set to the normalized HTTP method/HTTP + activity.DisplayName = $"{activity.DisplayName} {template!}"; activity.SetTag(SemanticConventions.AttributeHttpRoute, template); } @@ -148,6 +161,7 @@ private void OnException(Activity activity, HttpContext context, Exception excep } activity.SetStatus(ActivityStatusCode.Error, exception.Message); + activity.SetTag(SemanticConventions.AttributeErrorType, exception.GetType().FullName); try { diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index 3607f4a465..d1687d9d66 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -12,7 +12,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation; internal sealed class HttpInMetricsListener : IDisposable { private readonly HttpRequestRouteHelper routeHelper = new(); - private readonly RequestMethodHelper requestMethodHelper = new(); + private readonly RequestDataHelper requestDataHelper = new(); private readonly Histogram httpServerDuration; private readonly AspNetMetricsInstrumentationOptions options; @@ -31,18 +31,6 @@ public void Dispose() TelemetryHttpModule.Options.OnRequestStoppedCallback -= this.OnStopActivity; } - private static string GetHttpProtocolVersion(HttpRequest request) - { - var protocol = request.ServerVariables["SERVER_PROTOCOL"]; - return protocol switch - { - "HTTP/1.1" => "1.1", - "HTTP/2" => "2", - "HTTP/3" => "3", - _ => protocol, - }; - } - private void OnStopActivity(Activity activity, HttpContext context) { var request = context.Request; @@ -59,10 +47,10 @@ private void OnStopActivity(Activity activity, HttpContext context) tags.Add(SemanticConventions.AttributeServerPort, url.Port); } - var normalizedMethod = this.requestMethodHelper.GetNormalizedHttpMethod(request.HttpMethod); + var normalizedMethod = this.requestDataHelper.GetNormalizedHttpMethod(request.HttpMethod); tags.Add(SemanticConventions.AttributeHttpRequestMethod, normalizedMethod); - var protocolVersion = GetHttpProtocolVersion(request); + var protocolVersion = RequestDataHelper.GetHttpProtocolVersion(request); if (!string.IsNullOrEmpty(protocolVersion)) { tags.Add(SemanticConventions.AttributeNetworkProtocolVersion, protocolVersion); diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelper.cs similarity index 62% rename from src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs rename to src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelper.cs index 3d7c5d4183..ef5a346f98 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestMethodHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelper.cs @@ -3,11 +3,14 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Web; +using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AspNet.Implementation; -internal sealed class RequestMethodHelper +internal sealed class RequestDataHelper { private const string KnownHttpMethodsEnvironmentVariable = "OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS"; @@ -20,7 +23,7 @@ internal sealed class RequestMethodHelper // List of known HTTP methods as per spec. private readonly Dictionary knownHttpMethods; - public RequestMethodHelper() + public RequestDataHelper() { var suppliedKnownMethods = Environment.GetEnvironmentVariable(KnownHttpMethodsEnvironmentVariable) ?.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries); @@ -40,10 +43,37 @@ public RequestMethodHelper() }; } + public static string GetHttpProtocolVersion(HttpRequest request) + { + return GetHttpProtocolVersion(request.ServerVariables["SERVER_PROTOCOL"]); + } + + public void SetHttpMethodTag(Activity activity, string originalHttpMethod) + { + var normalizedHttpMethod = this.GetNormalizedHttpMethod(originalHttpMethod); + activity.SetTag(SemanticConventions.AttributeHttpRequestMethod, normalizedHttpMethod); + + if (originalHttpMethod != normalizedHttpMethod) + { + activity.SetTag(SemanticConventions.AttributeHttpRequestMethodOriginal, originalHttpMethod); + } + } + public string GetNormalizedHttpMethod(string method) { return this.knownHttpMethods.TryGetValue(method, out var normalizedMethod) ? normalizedMethod : OtherHttpMethod; } + + internal static string GetHttpProtocolVersion(string protocol) + { + return protocol switch + { + "HTTP/1.1" => "1.1", + "HTTP/2" => "2", + "HTTP/3" => "3", + _ => protocol, + }; + } } diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 202d4b4eef..0d9fe00f87 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -95,17 +95,22 @@ internal static class SemanticConventions public const string AttributeExceptionType = "exception.type"; public const string AttributeExceptionMessage = "exception.message"; public const string AttributeExceptionStacktrace = "exception.stacktrace"; + public const string AttributeErrorType = "error.type"; // v1.21.0 // https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-metrics.md#http-server public const string AttributeHttpRequestMethod = "http.request.method"; // replaces: "http.method" (AttributeHttpMethod) + public const string AttributeHttpRequestMethodOriginal = "http.request.method_original"; public const string AttributeHttpResponseStatusCode = "http.response.status_code"; // replaces: "http.status_code" (AttributeHttpStatusCode) public const string AttributeUrlScheme = "url.scheme"; // replaces: "http.scheme" (AttributeHttpScheme) + public const string AttributeUrlPath = "url.path"; // replaces: "http.target" (AttributeHttpTarget) + public const string AttributeUrlQuery = "url.query"; // replaces: "http.target" (AttributeHttpTarget) // v1.23.0 // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-server public const string AttributeNetworkProtocolVersion = "network.protocol.version"; // replaces: "http.flavor" (AttributeHttpFlavor) public const string AttributeServerAddress = "server.address"; // replaces: "net.host.name" (AttributeNetHostName) public const string AttributeServerPort = "server.port"; // replaces: "net.host.port" (AttributeNetHostPort) + public const string AttributeUserAgentOriginal = "user_agent.original"; // replaces: http.user_agent (AttributeHttpUserAgent) #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 9959d372ab..4b832aa6d6 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -20,31 +20,40 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class HttpInListenerTests { [Theory] - [InlineData("http://localhost/", "http://localhost/", 0, null)] - [InlineData("http://localhost/", "http://localhost/", 0, null, true)] - [InlineData("https://localhost/", "https://localhost/", 0, null)] - [InlineData("https://localhost/", "https://user:pass@localhost/", 0, null)] // Test URL sanitization - [InlineData("http://localhost:443/", "http://localhost:443/", 0, null)] // Test http over 443 - [InlineData("https://localhost:80/", "https://localhost:80/", 0, null)] // Test https over 80 - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", 0, null)] // Test complex URL sanitization - [InlineData("http://localhost:80/Index", "http://localhost:80/Index", 1, "{controller}/{action}/{id}")] - [InlineData("https://localhost:443/about_attr_route/10", "https://localhost:443/about_attr_route/10", 2, "about_attr_route/{customerId}")] - [InlineData("http://localhost:1880/api/weatherforecast", "http://localhost:1880/api/weatherforecast", 3, "api/{controller}/{id}")] - [InlineData("https://localhost:1843/subroute/10", "https://localhost:1843/subroute/10", 4, "subroute/{customerId}")] - [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "/api/value")] // Request will be filtered - [InlineData("http://localhost/api/value", "http://localhost/api/value", 0, null, false, "{ThrowException}")] // Filter user code will throw an exception - [InlineData("http://localhost/", "http://localhost/", 0, null, false, null, true)] // Test RecordException option + [InlineData("http://localhost/", "http", "/", null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("https://localhost/", "https", "/", null, "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null, "HTTP")] + [InlineData("https://user:pass@localhost/", "https", "/", null, "localhost", 443, "GeT", "GET", "GeT", 0, null, "GET")] // Test URL sanitization + [InlineData("http://localhost:443/", "http", "/", null, "localhost", 443, "GET", "GET", null, 0, null, "GET")] // Test http over 443 + [InlineData("https://localhost:80/", "https", "/", null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test https over 80 + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL + [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization + [InlineData("http://localhost:80/Index", "http", "/Index", null, "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}", "GET {controller}/{action}/{id}")] + [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] + [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] + [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")] + [InlineData("http://localhost/api/value", "http", "/api/value", null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered + [InlineData("http://localhost/api/value", "http", "/api/value", null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception + [InlineData("http://localhost/", "http", "/", null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option public void AspNetRequestsAreCollectedSuccessfully( - string expectedUrl, string url, + string expectedUrlScheme, + string expectedUrlPath, + string expectedUrlQuery, + string expectedHost, + int expectedPort, + string requestMethod, + string expectedRequestMethod, + string? expectedOriginalRequestMethod, int routeType, - string routeTemplate, + string? routeTemplate, + string expectedName, bool setStatusToErrorInEnrich = false, string? filter = null, - bool recordException = false) + bool recordException = false, + string? expectedErrorType = null) { - HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); + HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate, requestMethod); typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, new TestHttpWorkerRequest()); @@ -109,44 +118,24 @@ public void AspNetRequestsAreCollectedSuccessfully( Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); Assert.NotEqual(TimeSpan.Zero, span.Duration); - Assert.Equal(routeTemplate ?? HttpContext.Current.Request.Path, span.DisplayName); + Assert.Equal(expectedName, span.DisplayName); Assert.Equal(ActivityKind.Server, span.Kind); Assert.True(span.Duration != TimeSpan.Zero); - Assert.Equal(200, span.GetTagValue(SemanticConventions.AttributeHttpStatusCode)); + Assert.Equal(200, span.GetTagValue("http.response.status_code")); - var expectedUri = new Uri(expectedUrl); - var actualUrl = span.GetTagValue(SemanticConventions.AttributeHttpUrl); + Assert.Equal(expectedHost, span.GetTagValue("server.address")); + Assert.Equal(expectedPort, span.GetTagValue("server.port")); - Assert.Equal(expectedUri.ToString(), actualUrl); + Assert.Equal(expectedRequestMethod, span.GetTagValue("http.request.method")); + Assert.Equal(expectedOriginalRequestMethod, span.GetTagValue("http.request.method_original")); + Assert.Equal("FakeHTTP/123", span.GetTagValue("network.protocol.version")); - // Url strips 80 or 443 if the scheme matches. - if ((expectedUri.Port == 80 && expectedUri.Scheme == "http") || (expectedUri.Port == 443 && expectedUri.Scheme == "https")) - { - Assert.DoesNotContain($":{expectedUri.Port}", actualUrl as string); - } - else - { - Assert.Contains($":{expectedUri.Port}", actualUrl as string); - } - - // Host includes port if it isn't 80 or 443. - if (expectedUri.Port is 80 or 443) - { - Assert.Equal( - expectedUri.Host, - span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); - } - else - { - Assert.Equal( - $"{expectedUri.Host}:{expectedUri.Port}", - span.GetTagValue(SemanticConventions.AttributeHttpHost) as string); - } - - Assert.Equal(HttpContext.Current.Request.HttpMethod, span.GetTagValue(SemanticConventions.AttributeHttpMethod) as string); - Assert.Equal(HttpContext.Current.Request.Path, span.GetTagValue(SemanticConventions.AttributeHttpTarget) as string); - Assert.Equal(HttpContext.Current.Request.UserAgent, span.GetTagValue(SemanticConventions.AttributeHttpUserAgent) as string); + Assert.Equal(expectedUrlPath, span.GetTagValue("url.path")); + Assert.Equal(expectedUrlQuery, span.GetTagValue("url.query")); + Assert.Equal(expectedUrlScheme, span.GetTagValue("url.scheme")); + Assert.Equal("Custom User Agent v1.2.3", span.GetTagValue("user_agent.original")); + Assert.Equal(expectedErrorType, span.GetTagValue("error.type")); if (recordException) { @@ -271,7 +260,8 @@ void EnrichAction(Activity activity, string method, object obj) break; - default: + case "OnException": + Assert.True(obj is Exception); break; } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index b5c6ddf904..8c39fb7db4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -44,7 +44,7 @@ public void AspNetMetricTagsAreCollectedSuccessfully( bool enableServerAttributesForRequestDuration = true) { double duration = 0; - HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate); + HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate, "GET"); HttpContext.Current.Response.StatusCode = expectedStatus; // This is to enable activity creation diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs similarity index 77% rename from test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs rename to test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs index fd0312f187..e1beb3a377 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestMethodHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; -public class RequestMethodHelperTests : IDisposable +public class RequestDataHelperTests : IDisposable { [Theory] [InlineData("GET", "GET")] @@ -23,7 +23,7 @@ public class RequestMethodHelperTests : IDisposable [InlineData("invalid", "_OTHER")] public void MethodMappingWorksForKnownMethods(string method, string expected) { - var requestHelper = new RequestMethodHelper(); + var requestHelper = new RequestDataHelper(); var actual = requestHelper.GetNormalizedHttpMethod(method); Assert.Equal(expected, actual); } @@ -44,11 +44,22 @@ public void MethodMappingWorksForKnownMethods(string method, string expected) public void MethodMappingWorksForEnvironmentVariables(string method, string expected) { Environment.SetEnvironmentVariable("OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS", "GET,POST"); - var requestHelper = new RequestMethodHelper(); + var requestHelper = new RequestDataHelper(); var actual = requestHelper.GetNormalizedHttpMethod(method); Assert.Equal(expected, actual); } + [Theory] + [InlineData("HTTP/1.1", "1.1")] + [InlineData("HTTP/2", "2")] + [InlineData("HTTP/3", "3")] + [InlineData("Unknown", "Unknown")] + public void MappingProtocolToVersion(string protocolVersion, string expected) + { + var actual = RequestDataHelper.GetHttpProtocolVersion(protocolVersion); + Assert.Equal(expected, actual); + } + public void Dispose() { // Clean up after tests that set environment variables. diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs index 318d815572..fcebc17d5b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs @@ -10,7 +10,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; internal static class RouteTestHelper { - public static HttpContext BuildHttpContext(string url, int routeType, string routeTemplate) + public static HttpContext BuildHttpContext(string url, int routeType, string? routeTemplate, string requestMethod) { RouteData routeData; switch (routeType) @@ -21,7 +21,7 @@ public static HttpContext BuildHttpContext(string url, int routeType, string rou case 1: // Traditional MVC. case 2: // Attribute routing MVC. case 3: // Traditional WebAPI. - routeData = new RouteData() + routeData = new RouteData { Route = new Route(routeTemplate, null), }; @@ -48,12 +48,14 @@ public static HttpContext BuildHttpContext(string url, int routeType, string rou var request = new HttpRequest(string.Empty, url, string.Empty) { - RequestContext = new RequestContext() + RequestContext = new RequestContext { RouteData = routeData, }, }; + typeof(HttpRequest).GetField("_httpMethod", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(request, requestMethod); + return new HttpContext(request, new HttpResponse(new StringWriter())); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs index c9b1bb5058..7230af6a91 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs @@ -8,6 +8,16 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; internal class TestHttpWorkerRequest : HttpWorkerRequest { + public override string GetKnownRequestHeader(int index) + { + if (index == 39) + { + return "Custom User Agent v1.2.3"; + } + + return base.GetKnownRequestHeader(index); + } + public override void EndOfRequest() { throw new NotImplementedException(); @@ -25,17 +35,17 @@ public override string GetHttpVerbName() public override string GetHttpVersion() { - throw new NotImplementedException(); + return "FakeHTTP/123"; } public override string GetLocalAddress() { - throw new NotImplementedException(); + return "fake-local-address"; // avoid throwing exception } public override int GetLocalPort() { - throw new NotImplementedException(); + return 1234; // avoid throwing exception } public override string GetQueryString() @@ -50,7 +60,7 @@ public override string GetRawUrl() public override string GetRemoteAddress() { - throw new NotImplementedException(); + return "fake-remote-address"; // avoid throwing exception } public override int GetRemotePort() From 02be4277e8c30c0927d45fb0cb7fd03036add144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 25 Mar 2024 21:55:39 +0100 Subject: [PATCH 0990/1499] Cleanup solution file - shared folder (#1623) --- opentelemetry-dotnet-contrib.sln | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6f4bc45249..98d6bb18aa 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -275,15 +275,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\DiagnosticSourceSubscriber.cs = src\Shared\DiagnosticSourceSubscriber.cs src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs src\Shared\Guard.cs = src\Shared\Guard.cs - src\Shared\InstrumentationEventSource.cs = src\Shared\InstrumentationEventSource.cs src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs src\Shared\ListenerHandler.cs = src\Shared\ListenerHandler.cs src\Shared\MultiTypePropertyFetcher.cs = src\Shared\MultiTypePropertyFetcher.cs src\Shared\NullableAttributes.cs = src\Shared\NullableAttributes.cs src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs + src\Shared\PropertyFetcher.AOT.cs = src\Shared\PropertyFetcher.AOT.cs src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs - src\Shared\ServiceProviderExtensions.cs = src\Shared\ServiceProviderExtensions.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs EndProjectSection From 19af5fb08264cb100e946e34855abab91dd99ed1 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 25 Mar 2024 14:15:20 -0700 Subject: [PATCH 0991/1499] [Exporter.Geneva] Add otlp protobuf metric exporter (#1596) Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .editorconfig | 4 + .../Internal/ConnectionStringBuilder.cs | 6 + .../Metrics/GenevaMetricExporter.cs | 28 +- .../OtlpProtobuf/FieldNumberConstants.cs | 136 ++++ .../OtlpProtobufMetricExporter.cs | 51 ++ .../OtlpProtobuf/OtlpProtobufSerializer.cs | 391 ++++++++++ .../OtlpProtobuf/ProtobufSerializerHelper.cs | 177 +++++ .../Metrics/OtlpProtobuf/TimestampHelpers.cs | 20 + .../Metrics/OtlpProtobuf/WireType.cs | 47 ++ .../Metrics/TlvMetricExporter.cs | 11 +- .../Metrics/Transport/IMetricDataTransport.cs | 9 + .../Transport/MetricEtwDataTransport.cs | 24 + .../Transport/MetricUnixDataTransport.cs | 5 + .../Exporter/MetricExporterBenchmarks.cs | 3 +- .../GenevaMetricExporterTests.cs | 10 +- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 11 +- .../OtlpProtobufMetricExporterTests.cs | 265 +++++++ .../metrics/v1/metrics_service.proto | 79 ++ .../proto/common/v1/common.proto | 81 +++ .../proto/metrics/v1/metrics.proto | 676 ++++++++++++++++++ .../proto/resource/v1/resource.proto | 37 + 21 files changed, 2052 insertions(+), 19 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/collector/metrics/v1/metrics_service.proto create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/common/v1/common.proto create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/metrics/v1/metrics.proto create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/resource/v1/resource.proto diff --git a/.editorconfig b/.editorconfig index f5e1e40677..42cb1f628d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -156,6 +156,10 @@ dotnet_diagnostic.RS0041.severity = suggestion [**/External/**.cs] generated_code = true +# Skip check for .cs files generated by proto +[**/proto/**.cs] +dotnet_diagnostic.SA1518.severity = none + [*.csproj] indent_size = 2 diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index a51bc216c3..e6310df376 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -75,6 +75,12 @@ public string PrivatePreviewEnableTraceLoggingDynamic set => this._parts[nameof(this.PrivatePreviewEnableTraceLoggingDynamic)] = value; } + public string PrivatePreviewOtlpProtobufMetricExporter + { + get => this._parts.TryGetValue(nameof(this.PrivatePreviewOtlpProtobufMetricExporter), out var value) ? value : null; + set => this._parts[nameof(this.PrivatePreviewOtlpProtobufMetricExporter)] = value; + } + public string Endpoint { get => this.ThrowIfNotExists(nameof(this.Endpoint)); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index ec69b96d63..fa0c601afe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -7,6 +7,7 @@ using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; namespace OpenTelemetry.Exporter.Geneva; @@ -22,7 +23,7 @@ public class GenevaMetricExporter : BaseExporter internal const string DimensionKeyForCustomMetricsNamespace = "_microsoft_metrics_namespace"; - private readonly TlvMetricExporter exporter; + private readonly IDisposable exporter; private delegate ExportResult ExportMetricsFunc(in Batch batch); @@ -30,18 +31,33 @@ public class GenevaMetricExporter : BaseExporter private bool isDisposed; + private Resource resource; + + internal Resource Resource => this.resource ??= this.ParentProvider.GetResource(); + public GenevaMetricExporter(GenevaMetricExporterOptions options) { Guard.ThrowIfNull(options); Guard.ThrowIfNullOrWhitespace(options.ConnectionString); - // TODO: parse connection string to check if otlp protobuf format is enabled. - // and then enable either TLV Exporter or Protobuf based exporter. - var tlvMetricsExporter = new TlvMetricExporter(options); + var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - this.exportMetrics = tlvMetricsExporter.Export; + if (connectionStringBuilder.PrivatePreviewOtlpProtobufMetricExporter != null && connectionStringBuilder.PrivatePreviewOtlpProtobufMetricExporter.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + { + var otlpProtobufExporter = new OtlpProtobufMetricExporter(() => { return this.Resource; }); - this.exporter = tlvMetricsExporter; + this.exporter = otlpProtobufExporter; + + this.exportMetrics = otlpProtobufExporter.Export; + } + else + { + var tlvMetricsExporter = new TlvMetricExporter(connectionStringBuilder, options.PrepopulatedMetricDimensions); + + this.exportMetrics = tlvMetricsExporter.Export; + + this.exporter = tlvMetricsExporter; + } } public override ExportResult Export(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs new file mode 100644 index 0000000000..a3c88ac8d6 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs @@ -0,0 +1,136 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Exporter.Geneva; + +/// +/// Defines field number constants for fields defined in +/// https://github.com/open-telemetry/opentelemetry-proto/blob/v1.1.0/opentelemetry/proto/metrics/v1/metrics.proto. +/// +internal static class FieldNumberConstants +{ + // MetricsData + internal const int MetricsData_resource_metrics = 1; + + // Resource + internal const int Resource_attributes = 1; + + // ResourceMetrics + internal const int ResourceMetrics_resource = 1; + internal const int ResourceMetrics_scope_metrics = 2; + internal const int ResourceMetrics_schema_url = 3; + + // ScopeMetrics + internal const int ScopeMetrics_scope = 1; + internal const int ScopeMetrics_metrics = 2; + internal const int ScopeMetrics_schema_url = 3; + + // Metric + internal const int Metric_name = 1; + internal const int Metric_description = 2; + internal const int Metric_unit = 3; + internal const int Metric_gauge = 5; + internal const int Metric_sum = 7; + internal const int Metric_histogram = 9; + internal const int Metric_exponential_histogram = 10; + internal const int Metric_summary = 11; + + // Sum + internal const int Sum_data_points = 1; + internal const int Sum_aggregation_temporality = 2; + internal const int Sum_is_monotonic = 3; + + // Gauge + internal const int Gauge_data_points = 1; + + // Histogram + internal const int Histogram_data_points = 1; + internal const int Histogram_aggregation_temporality = 2; + + // ExponentialHistogram + internal const int ExponentialHistogram_data_points = 1; + internal const int ExponentialHistogram_aggregation_temporality = 2; + + // NumberDataPoint + internal const int NumberDataPoint_attributes = 7; + internal const int NumberDataPoint_start_time_unix_nano = 2; + internal const int NumberDataPoint_time_unix_nano = 3; + internal const int NumberDataPoint_as_int = 6; + internal const int NumberDataPoint_as_double = 4; + internal const int NumberDataPoint_exemplars = 5; + internal const int NumberDataPoint_flags = 8; + + // HistogramDataPoint + internal const int HistogramDataPoint_attributes = 9; + internal const int HistogramDataPoint_start_time_unix_nano = 2; + internal const int HistogramDataPoint_time_unix_nano = 3; + internal const int HistogramDataPoint_count = 4; + internal const int HistogramDataPoint_sum = 5; + internal const int HistogramDataPoint_bucket_counts = 6; + internal const int HistogramDataPoint_explicit_bounds = 7; + internal const int HistogramDataPoint_exemplars = 8; + internal const int HistogramDataPoint_flags = 10; + internal const int HistogramDataPoint_min = 11; + internal const int HistogramDataPoint_max = 12; + + // 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; + + // ArrayValue + internal const int ArrayValue_values = 1; + + // KeyValueList + internal const int KeyValueList_values = 1; + + // KeyValue + internal const int KeyValue_key = 1; + internal const int KeyValue_value = 2; + + // InstrumentationScope + internal const int InstrumentationScope_name = 1; + internal const int InstrumentationScope_version = 2; + internal const int InstrumentationScope_attributes = 3; + internal const int InstrumentationScope_dropped_attributes_count = 4; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static int GetMetricTypeFieldNumber(MetricType metricType) + { + switch (metricType) + { + case MetricType.LongSum: + case MetricType.LongSumNonMonotonic: + case MetricType.DoubleSum: + case MetricType.DoubleSumNonMonotonic: + { + return 7; + } + + case MetricType.DoubleGauge: + case MetricType.LongGauge: + { + return 5; + } + + case MetricType.Histogram: + { + return 9; + } + + case MetricType.ExponentialHistogram: + { + return 10; + } + } + + return 0; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs new file mode 100644 index 0000000000..c487d2a0ea --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Runtime.InteropServices; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Geneva; + +internal sealed class OtlpProtobufMetricExporter : IDisposable +{ + private readonly byte[] buffer = new byte[GenevaMetricExporter.BufferSize]; + + private readonly OtlpProtobufSerializer otlpProtobufSerializer; + + private readonly Func getResource; + + public OtlpProtobufMetricExporter(Func getResource) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Temporary until we add support for user_events. + throw new NotSupportedException("Exporting data in protobuf format is not supported on Linux."); + } + + this.getResource = getResource; + this.otlpProtobufSerializer = new OtlpProtobufSerializer(MetricEtwDataTransport.Instance); + } + + public ExportResult Export(in Batch batch) + { + var result = ExportResult.Success; + + try + { + this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.getResource(), batch); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("Failed to export metrics batch", ex); + result = ExportResult.Failure; + } + + return result; + } + + public void Dispose() + { + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs new file mode 100644 index 0000000000..89a48ebce5 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -0,0 +1,391 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using System.Globalization; +using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Geneva; + +internal sealed class OtlpProtobufSerializer +{ + private const int TagAndLengthSize = 4; + + private readonly Dictionary> scopeMetrics = new(); + + private int resourceMetricTagAndLengthIndex; + + private int scopeMetricsTagAndLengthIndex; + + private int metricTagAndLengthIndex; + + private int instrumentTagAndLengthIndex; + + private int metricPointTagAndLengthIndex; + + private int resourceMetricValueIndex; + + private int scopeMetricsValueIndex; + + private int metricValueIndex; + + private int instrumentValueIndex; + + private int metricPointValueIndex; + + internal IMetricDataTransport MetricDataTransport; + + public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport) + { + this.MetricDataTransport = metricDataTransport; + } + + internal void SerializeAndSendMetrics(byte[] buffer, Resource resource, in Batch metricBatch) + { + foreach (var metric in metricBatch) + { + if (this.scopeMetrics.TryGetValue(metric.MeterName, out var metricList)) + { + metricList.Add(metric); + } + else + { + var newList = new List() { metric }; + this.scopeMetrics[metric.MeterName] = newList; + } + } + + // Serialize + this.SerializeResourceMetrics(buffer, resource); + + this.ClearScopeMetrics(); + } + + internal void ClearScopeMetrics() + { + foreach (var entry in this.scopeMetrics) + { + entry.Value.Clear(); + } + } + + internal void SerializeResourceMetrics(byte[] buffer, Resource resource) + { + int cursor = 0; + + this.resourceMetricTagAndLengthIndex = cursor; + + this.resourceMetricValueIndex = cursor + TagAndLengthSize; + + cursor = this.resourceMetricValueIndex; + + // Serialize Resource + // TODO: Avoid serializing it multiple times. + SerializeResource(buffer, ref cursor, resource); + + // TODO: Serialize schema_url field + + // Serialize ScopeMetrics field + this.scopeMetricsTagAndLengthIndex = cursor; + this.scopeMetricsValueIndex = cursor + TagAndLengthSize; + foreach (KeyValuePair> entry in this.scopeMetrics) + { + if (entry.Value.Count > 0) + { + // Reset cursor to write new scopeMetric + cursor = this.scopeMetricsValueIndex; + + try + { + // Serialize this meter/scope + this.SerializeScopeMetrics(buffer, ref cursor, entry.Key, entry.Value); + } + catch + { + // TODO: log exception. + } + } + } + } + + internal void SerializeScopeMetrics(byte[] buffer, ref int cursor, string scopeName, List metrics) + { + // Serialize scope information + // TODO: Avoid serializing for each export. + SerializeInstrumentationScope(buffer, ref cursor, scopeName, metrics[0].MeterTags); + + this.metricTagAndLengthIndex = cursor; + this.metricValueIndex = cursor + TagAndLengthSize; + foreach (Metric metric in metrics) + { + // Reset cursor to write new metric + cursor = this.metricValueIndex; + + // Serialize metrics for the meter/scope + try + { + this.SerializeMetric(buffer, ref cursor, metric); + } + catch + { + // TODO: log exception. + } + } + + // TODO: Serialize schema_url field. + } + + private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) + { + WriteInstrumentDetails(buffer, ref cursor, metric); + + this.instrumentTagAndLengthIndex = cursor; + this.instrumentValueIndex = cursor + TagAndLengthSize; + switch (metric.MetricType) + { + case MetricType.LongSum: + case MetricType.LongSumNonMonotonic: + { + cursor = this.instrumentValueIndex; + + // Write isMonotonic tag + ProtobufSerializerHelper.WriteBoolWithTag(buffer, ref cursor, FieldNumberConstants.Sum_is_monotonic, metric.MetricType == MetricType.LongSum); + + // Write aggregationTemporality tag + ProtobufSerializerHelper.WriteEnumWithTag(buffer, ref cursor, FieldNumberConstants.Sum_aggregation_temporality, metric.Temporality == AggregationTemporality.Cumulative ? 2 : 1); + + this.metricPointTagAndLengthIndex = cursor; + this.metricPointValueIndex = cursor + TagAndLengthSize; + foreach (var metricPoint in metric.GetMetricPoints()) + { + try + { + // Reset cursor to write new metricPoint + cursor = this.metricPointValueIndex; + + // Casting to ulong is ok here as the bit representation for long versus ulong will be the same + // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) + var sum = (ulong)metricPoint.GetSumLong(); + + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_int, sum); + + var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_start_time_unix_nano, startTime); + + var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_time_unix_nano, endTime); + + SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.NumberDataPoint_attributes); + + // TODO: exemplars. + + var metricPointStartPosition = this.metricPointTagAndLengthIndex; + + // Write numberdatapoint {Repeated field} + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.Sum_data_points, WireType.LEN); + + // Finish writing current batch + this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); + + // Send metricPoint + this.SendMetricPoint(buffer, ref cursor); + } + catch + { + // TODO: log exception. + } + } + + break; + } + + case MetricType.DoubleSum: + case MetricType.DoubleSumNonMonotonic: + { + // TODO + break; + } + + case MetricType.LongGauge: + { + // TODO + break; + } + + case MetricType.DoubleGauge: + { + // TODO + break; + } + + case MetricType.Histogram: + { + // TODO + break; + } + + case MetricType.ExponentialHistogram: + { + // TODO + break; + } + } + } + + private void WriteIndividualMessageTagsAndLength(byte[] buffer, ref int cursor, MetricType metricType) + { + var instrumentIndex = this.instrumentTagAndLengthIndex; + + var metricIndex = this.metricTagAndLengthIndex; + + var scopeMetricsIndex = this.scopeMetricsTagAndLengthIndex; + + var resourceMetricIndex = this.resourceMetricTagAndLengthIndex; + + // Write instrument tag and length + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref instrumentIndex, cursor - this.instrumentValueIndex, FieldNumberConstants.GetMetricTypeFieldNumber(metricType), WireType.LEN); + + // Write metric tag and length + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricIndex, cursor - this.metricValueIndex, FieldNumberConstants.ScopeMetrics_metrics, WireType.LEN); + + // Write scope tag and length + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref scopeMetricsIndex, cursor - this.scopeMetricsValueIndex, FieldNumberConstants.ResourceMetrics_scope_metrics, WireType.LEN); + + // Write resource metric tag and length + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref resourceMetricIndex, cursor - this.resourceMetricValueIndex, FieldNumberConstants.ResourceMetrics_resource, WireType.LEN); + } + + private void SendMetricPoint(byte[] buffer, ref int cursor) + { + // TODO: Extend this for user_events. + this.MetricDataTransport.SendOtlpProtobufEvent(buffer, cursor); + } + + internal static void WriteInstrumentDetails(byte[] buffer, ref int cursor, Metric metric) + { + // Write metric name + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_name, metric.Name); + + // Write metric description + if (metric.Description != null) + { + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_description, metric.Description); + } + + // Write metric unit + if (metric.Unit != null) + { + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_unit, metric.Unit); + } + } + + internal static void SerializeInstrumentationScope(byte[] buffer, ref int cursor, string name, IEnumerable> meterTags) + { + int tagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int valueIndex = cursor; + + // Write name + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.InstrumentationScope_name, name); + + SerializeTags(buffer, ref cursor, meterTags, FieldNumberConstants.InstrumentationScope_attributes); + + // Write instrumentation Scope Tag + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref tagAndLengthIndex, cursor - valueIndex, FieldNumberConstants.ScopeMetrics_scope, WireType.LEN); + } + + private static void SerializeTags(byte[] buffer, ref int cursor, IEnumerable> attributes, int fieldNumber) + { + if (attributes != null) + { + foreach (var tag in attributes) + { + if (tag.Value != null) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, fieldNumber); + } + } + } + } + + private static void SerializeResource(byte[] buffer, ref int cursor, Resource resource) + { + if (resource != Resource.Empty) + { + int tagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int valueIndex = cursor; + + SerializeTags(buffer, ref cursor, resource.Attributes, FieldNumberConstants.Resource_attributes); + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref tagAndLengthIndex, cursor - valueIndex, FieldNumberConstants.ResourceMetrics_resource, WireType.LEN); + } + } + + internal static void SerializeTags(byte[] buffer, ref int cursor, ReadOnlyTagCollection tags, int fieldNumber) + { + foreach (var tag in tags) + { + if (tag.Value != null) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, fieldNumber); + } + } + } + + internal static void SerializeTag(byte[] buffer, ref int cursor, string key, object value, int fieldNumber) + { + try + { + // TODO : Check if calculating the length in advance could be more efficient in this case. + // That way we wouldn't have to leave the fixed length space. + int keyValueTagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int keyValueIndex = cursor; + + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.KeyValue_key, key); + + int anyValueTagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int anyValueIndex = cursor; + + switch (value) + { + case char: + case string: + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); + break; + case bool b: + ProtobufSerializerHelper.WriteBoolWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_bool_value, (bool)value); + break; + case byte: + case sbyte: + case short: + case ushort: + case int: + case uint: + case long: + case ulong: + ProtobufSerializerHelper.WriteInt64WithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_int_value, (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture)); + break; + case float: + case double: + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_double_value, Convert.ToDouble(value, CultureInfo.InvariantCulture)); + break; + default: + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); + break; + + // TODO: Handle array type. + } + + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref anyValueTagAndLengthIndex, cursor - anyValueIndex, FieldNumberConstants.KeyValue_value, WireType.LEN); + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref keyValueTagAndLengthIndex, cursor - keyValueIndex, fieldNumber, WireType.LEN); + } + catch + { + // TODO: log exception. + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs new file mode 100644 index 0000000000..41e59c2ff8 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -0,0 +1,177 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Buffers.Binary; +using System.Runtime.CompilerServices; +using System.Text; + +namespace OpenTelemetry.Exporter.Geneva; + +internal static class ProtobufSerializerHelper +{ + private const int Fixed64Size = 8; + + internal static Encoding Utf8Encoding => Encoding.UTF8; + + private const ulong Ulong128 = 128; + + private const uint Uint128 = 128; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteStringTag(byte[] buffer, ref int cursor, int fieldNumber, string value) + { + int stringSize = Utf8Encoding.GetByteCount(value); + + WriteTag(buffer, ref cursor, fieldNumber, WireType.LEN); + + WriteLength(buffer, ref cursor, stringSize); + + _ = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, cursor); + + cursor += stringSize; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteEnumWithTag(byte[] buffer, ref int cursor, int fieldNumber, int value) + { + WriteTag(buffer, ref cursor, fieldNumber, WireType.VARINT); + + // Assuming 1 byte which matches the intended use. + buffer[cursor++] = (byte)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteBoolWithTag(byte[] buffer, ref int cursor, int fieldNumber, bool value) + { + WriteTag(buffer, ref cursor, fieldNumber, WireType.VARINT); + buffer[cursor++] = value ? (byte)1 : (byte)0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteFixed64WithTag(byte[] buffer, ref int cursor, int fieldNumber, ulong value) + { + WriteTag(buffer, ref cursor, fieldNumber, WireType.I64); + WriteFixed64LittleEndianFormat(buffer, ref cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteInt64WithTag(byte[] buffer, ref int cursor, int fieldNumber, ulong value) + { + WriteTag(buffer, ref cursor, fieldNumber, WireType.VARINT); + WriteVarint64(buffer, ref cursor, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteDoubleWithTag(byte[] buffer, ref int cursor, int fieldNumber, double value) + { + WriteTag(buffer, ref cursor, fieldNumber, WireType.I64); + WriteFixed64LittleEndianFormat(buffer, ref cursor, (ulong)BitConverter.DoubleToInt64Bits(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteLengthCustom(byte[] buffer, ref int cursor, int length) + { + WriteVarintCustom(buffer, ref cursor, (uint)length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteLength(byte[] buffer, ref int cursor, int length) + { + WriteVarint32(buffer, ref cursor, (uint)length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteVarintCustom(byte[] buffer, ref int cursor, uint value) + { + int index = 0; + + // Loop until all 7 bits from the integer value have been encoded + while (value > 0) + { + byte chunk = (byte)(value & 0x7F); // Extract the least significant 7 bits + value >>= 7; // Right shift the value by 7 bits to process the next chunk + + // If there are more bits to encode, set the most significant bit to 1 + if (index < 3) + { + chunk |= 0x80; + } + + buffer[cursor++] = chunk; // Store the encoded chunk + index++; + } + + // If fewer than 3 bytes were used, pad with zeros + while (index < 2) + { + buffer[cursor++] = 0x80; + index++; + } + + while (index < 3) + { + buffer[cursor++] = 0x00; + index++; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteVarint32(byte[] buffer, ref int cursor, uint value) + { + while (value >= Uint128) + { + buffer[cursor++] = (byte)(0x80 | (value & 0x7F)); + value >>= 7; + } + + buffer[cursor++] = (byte)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteVarint64(byte[] buffer, ref int cursor, ulong value) + { + while (value >= Ulong128) + { + buffer[cursor++] = (byte)(0x80 | (value & 0x7F)); + value >>= 7; + } + + buffer[cursor++] = (byte)value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteTag(byte[] buffer, ref int cursor, int fieldNumber, WireType type) + { + WriteVarint32(buffer, ref cursor, GetTagValue(fieldNumber, type)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteTagAndLengthPrefix(byte[] buffer, ref int cursor, int contentLength, int fieldNumber, WireType type) + { + WriteTag(buffer, ref cursor, fieldNumber, type); + WriteLengthCustom(buffer, ref cursor, contentLength); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteFixed64LittleEndianFormat(byte[] buffer, ref int cursor, ulong value) + { + if (cursor < buffer.Length) + { + Span span = new Span(buffer, cursor, Fixed64Size); + + BinaryPrimitives.WriteUInt64LittleEndian(span, value); + + cursor += Fixed64Size; + } + else + { + // TODO: handle insufficient space. + } + } + + internal static uint GetTagValue(int fieldNumber, WireType wireType) + { + return ((uint)(fieldNumber << 3)) | (uint)wireType; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs new file mode 100644 index 0000000000..92f8cc395e --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; + +namespace OpenTelemetry.Exporter.Geneva; + +/// +/// Helpers to convert .NET time related types to the timestamp used in OTLP. +/// +internal static class TimestampHelpers +{ + private const long NanosecondsPerTick = 100; + private const long UnixEpochTicks = 621355968000000000; // = DateTimeOffset.FromUnixTimeMilliseconds(0).Ticks + + internal static long ToUnixTimeNanoseconds(this DateTimeOffset dto) + { + return (dto.Ticks - UnixEpochTicks) * NanosecondsPerTick; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs new file mode 100644 index 0000000000..af5b2b297b --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Exporter.Geneva; + +/// +/// Wire types within protobuf encoding. +/// https://protobuf.dev/programming-guides/encoding/#structure. +/// +internal enum WireType : 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. + /// (Deperecated). + /// + 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.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 89d1dbb5a8..2e25728b59 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -31,17 +31,16 @@ internal sealed class TlvMetricExporter : IDisposable private bool isDisposed; - internal TlvMetricExporter(GenevaMetricExporterOptions options) + internal TlvMetricExporter(ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) { - var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); this.defaultMonitoringAccount = connectionStringBuilder.Account; this.defaultMetricNamespace = connectionStringBuilder.Namespace; - if (options.PrepopulatedMetricDimensions != null) + if (prepopulatedMetricDimensions != null) { - this.prepopulatedDimensionsCount = (ushort)options.PrepopulatedMetricDimensions.Count; - this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(options.PrepopulatedMetricDimensions.Keys); - this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(options.PrepopulatedMetricDimensions.Values); + this.prepopulatedDimensionsCount = (ushort)prepopulatedMetricDimensions.Count; + this.serializedPrepopulatedDimensionsKeys = this.SerializePrepopulatedDimensionsKeys(prepopulatedMetricDimensions.Keys); + this.serializedPrepopulatedDimensionsValues = this.SerializePrepopulatedDimensionsValues(prepopulatedMetricDimensions.Values); } switch (connectionStringBuilder.Protocol) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs index 970f8f0bf6..8b2be9ecee 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs @@ -17,4 +17,13 @@ void Send( MetricEventType eventType, byte[] body, int size); + + /// + /// Writes a standard metric event containing only a single value. + /// + /// The byte array containing the serialized data. + /// Length of the payload (fixed + variable). + void SendOtlpProtobufEvent( + byte[] body, + int size); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 61c06fa52d..559d1d8b1f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -9,6 +9,7 @@ namespace OpenTelemetry.Exporter.Geneva; [EventSource(Name = "OpenTelemetryGenevaMetricExporter", Guid = "{edc24920-e004-40f6-a8e1-0e6e48f39d84}")] internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport { + private const int OtlpProtobufMetricEventId = 81; private readonly int fixedPayloadEndIndex; private bool isDisposed; @@ -34,6 +35,29 @@ public unsafe void Send(MetricEventType eventType, byte[] data, int size) } } + [NonEvent] + public unsafe void SendOtlpProtobufEvent(byte[] data, int size) + { + if (this.IsEnabled()) + { + EventData* descr = stackalloc EventData[1]; + if (data != null && data.Length != 0) + { + fixed (byte* blob = data) + { + descr[0].DataPointer = (IntPtr)blob; + descr[0].Size = size; + this.WriteEventCore(OtlpProtobufMetricEventId, 1, descr); + } + } + } + } + + [Event(OtlpProtobufMetricEventId)] + private void OtlpProtobufEvent() + { + } + [Event((int)MetricEventType.ULongMetric)] private void ULongMetricEvent() { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs index 6ae7704ae1..863a6f5542 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs @@ -36,4 +36,9 @@ public void Dispose() this.udsDataTransport.Dispose(); this.isDisposed = true; } + + public void SendOtlpProtobufEvent(byte[] body, int size) + { + throw new System.NotImplementedException(); + } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index d887503aa9..0a83a5b527 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -95,7 +95,8 @@ public void Setup() this.counterWithGenevaMetricExporter = this.meterWithGenevaMetricExporter.CreateCounter("counter"); var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - this.tlvMetricsExporter = new TlvMetricExporter(exporterOptions); + var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); + this.tlvMetricsExporter = new TlvMetricExporter(connectionStringBuilder, exporterOptions.PrepopulatedMetricDimensions); this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); this.counterMetricPointWith4Dimensions = this.GenerateCounterMetricItemWith4Dimensions(out this.counterMetricDataWith4Dimensions); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 5051f53e90..5524e51a14 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -67,7 +67,7 @@ public void ParseConnectionStringCorrectly() server.Listen(1); } - using var exporter = new TlvMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); var monitoringAccount = typeof(TlvMetricExporter).GetField("defaultMonitoringAccount", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; var metricNamespace = typeof(TlvMetricExporter).GetField("defaultMetricNamespace", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as string; Assert.Equal("OTelMonitoringAccount", monitoringAccount); @@ -160,7 +160,7 @@ public void SuccessfulExportOnLinux() // Create a test exporter to get byte data for validation of the data received via Socket. var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - using var exporter = new TlvMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); // Emit a metric and grab a copy of internal buffer for validation. counter.Add( @@ -519,7 +519,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars ["cloud.roleVer"] = "9.0.15289.2", }; - using var exporter = new TlvMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); inMemoryReader.Collect(); @@ -741,7 +741,7 @@ public void SuccessfulSerializationWithTLVWithViews() ["cloud.roleVer"] = "9.0.15289.2", }; - using var exporter = new TlvMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); inMemoryReader.Collect(); @@ -859,7 +859,7 @@ public void SuccessfulSerializationWithCustomAccountAndNamespace() ["cloud.roleVer"] = "9.0.15289.2", }; - using var exporter = new TlvMetricExporter(exporterOptions); + using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); inMemoryReader.Collect(); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 4b9642aab0..8b1cb2b1a4 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -1,5 +1,5 @@ - + Unit test project for Geneva Exporters for OpenTelemetry @@ -11,6 +11,9 @@ + + + |Gauge, Sum, Histogram, Summary, ... | +// +------------+ +------------------------------------+ +// +// Data [One of Gauge, Sum, Histogram, Summary, ...] +// +-----------+ +// |... | // Metadata about the Data. +// |points |--+ +// +-----------+ | +// | +---------------------------+ +// | |DataPoint 1 | +// v |+------+------+ +------+ | +// +-----+ ||label |label |...|label | | +// | 1 |-->||value1|value2|...|valueN| | +// +-----+ |+------+------+ +------+ | +// | . | |+-----+ | +// | . | ||value| | +// | . | |+-----+ | +// | . | +---------------------------+ +// | . | . +// | . | . +// | . | . +// | . | +---------------------------+ +// | . | |DataPoint M | +// +-----+ |+------+------+ +------+ | +// | M |-->||label |label |...|label | | +// +-----+ ||value1|value2|...|valueN| | +// |+------+------+ +------+ | +// |+-----+ | +// ||value| | +// |+-----+ | +// +---------------------------+ +// +// Each distinct type of DataPoint represents the output of a specific +// aggregation function, the result of applying the DataPoint's +// associated function of to one or more measurements. +// +// All DataPoint types have three common fields: +// - Attributes includes key-value pairs associated with the data point +// - TimeUnixNano is required, set to the end time of the aggregation +// - StartTimeUnixNano is optional, but strongly encouraged for DataPoints +// having an AggregationTemporality field, as discussed below. +// +// Both TimeUnixNano and StartTimeUnixNano values are expressed as +// UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970. +// +// # TimeUnixNano +// +// This field is required, having consistent interpretation across +// DataPoint types. TimeUnixNano is the moment corresponding to when +// the data point's aggregate value was captured. +// +// Data points with the 0 value for TimeUnixNano SHOULD be rejected +// by consumers. +// +// # StartTimeUnixNano +// +// StartTimeUnixNano in general allows detecting when a sequence of +// observations is unbroken. This field indicates to consumers the +// start time for points with cumulative and delta +// AggregationTemporality, and it should be included whenever possible +// to support correct rate calculation. Although it may be omitted +// when the start time is truly unknown, setting StartTimeUnixNano is +// strongly encouraged. +message Metric { + reserved 4, 6, 8; + + // name of the metric, including its DNS name prefix. It must be unique. + string name = 1; + + // description of the metric, which can be used in documentation. + string description = 2; + + // unit in which the metric value is reported. Follows the format + // described by http://unitsofmeasure.org/ucum.html. + string unit = 3; + + // Data determines the aggregation type (if any) of the metric, what is the + // reported value type for the data points, as well as the relatationship to + // the time interval over which they are reported. + oneof data { + Gauge gauge = 5; + Sum sum = 7; + Histogram histogram = 9; + ExponentialHistogram exponential_histogram = 10; + Summary summary = 11; + } +} + +// Gauge represents the type of a scalar metric that always exports the +// "current value" for every data point. It should be used for an "unknown" +// aggregation. +// +// A Gauge does not support different aggregation temporalities. Given the +// aggregation is unknown, points cannot be combined using the same +// aggregation, regardless of aggregation temporalities. Therefore, +// AggregationTemporality is not included. Consequently, this also means +// "StartTimeUnixNano" is ignored for all data points. +message Gauge { + repeated NumberDataPoint data_points = 1; +} + +// Sum represents the type of a scalar metric that is calculated as a sum of all +// reported measurements over a time interval. +message Sum { + repeated NumberDataPoint data_points = 1; + + // aggregation_temporality describes if the aggregator reports delta changes + // since last report time, or cumulative changes since a fixed start time. + AggregationTemporality aggregation_temporality = 2; + + // If "true" means that the sum is monotonic. + bool is_monotonic = 3; +} + +// Histogram represents the type of a metric that is calculated by aggregating +// as a Histogram of all reported measurements over a time interval. +message Histogram { + repeated HistogramDataPoint data_points = 1; + + // aggregation_temporality describes if the aggregator reports delta changes + // since last report time, or cumulative changes since a fixed start time. + AggregationTemporality aggregation_temporality = 2; +} + +// ExponentialHistogram represents the type of a metric that is calculated by aggregating +// as a ExponentialHistogram of all reported double measurements over a time interval. +message ExponentialHistogram { + repeated ExponentialHistogramDataPoint data_points = 1; + + // aggregation_temporality describes if the aggregator reports delta changes + // since last report time, or cumulative changes since a fixed start time. + AggregationTemporality aggregation_temporality = 2; +} + +// Summary metric data are used to convey quantile summaries, +// a Prometheus (see: https://prometheus.io/docs/concepts/metric_types/#summary) +// and OpenMetrics (see: https://github.com/OpenObservability/OpenMetrics/blob/4dbf6075567ab43296eed941037c12951faafb92/protos/prometheus.proto#L45) +// data type. These data points cannot always be merged in a meaningful way. +// While they can be useful in some applications, histogram data points are +// recommended for new applications. +message Summary { + repeated SummaryDataPoint data_points = 1; +} + +// AggregationTemporality defines how a metric aggregator reports aggregated +// values. It describes how those values relate to the time interval over +// which they are aggregated. +enum AggregationTemporality { + // UNSPECIFIED is the default AggregationTemporality, it MUST not be used. + AGGREGATION_TEMPORALITY_UNSPECIFIED = 0; + + // DELTA is an AggregationTemporality for a metric aggregator which reports + // changes since last report time. Successive metrics contain aggregation of + // values from continuous and non-overlapping intervals. + // + // The values for a DELTA metric are based only on the time interval + // associated with one measurement cycle. There is no dependency on + // previous measurements like is the case for CUMULATIVE metrics. + // + // For example, consider a system measuring the number of requests that + // it receives and reports the sum of these requests every second as a + // DELTA metric: + // + // 1. The system starts receiving at time=t_0. + // 2. A request is received, the system measures 1 request. + // 3. A request is received, the system measures 1 request. + // 4. A request is received, the system measures 1 request. + // 5. The 1 second collection cycle ends. A metric is exported for the + // number of requests received over the interval of time t_0 to + // t_0+1 with a value of 3. + // 6. A request is received, the system measures 1 request. + // 7. A request is received, the system measures 1 request. + // 8. The 1 second collection cycle ends. A metric is exported for the + // number of requests received over the interval of time t_0+1 to + // t_0+2 with a value of 2. + AGGREGATION_TEMPORALITY_DELTA = 1; + + // CUMULATIVE is an AggregationTemporality for a metric aggregator which + // reports changes since a fixed start time. This means that current values + // of a CUMULATIVE metric depend on all previous measurements since the + // start time. Because of this, the sender is required to retain this state + // in some form. If this state is lost or invalidated, the CUMULATIVE metric + // values MUST be reset and a new fixed start time following the last + // reported measurement time sent MUST be used. + // + // For example, consider a system measuring the number of requests that + // it receives and reports the sum of these requests every second as a + // CUMULATIVE metric: + // + // 1. The system starts receiving at time=t_0. + // 2. A request is received, the system measures 1 request. + // 3. A request is received, the system measures 1 request. + // 4. A request is received, the system measures 1 request. + // 5. The 1 second collection cycle ends. A metric is exported for the + // number of requests received over the interval of time t_0 to + // t_0+1 with a value of 3. + // 6. A request is received, the system measures 1 request. + // 7. A request is received, the system measures 1 request. + // 8. The 1 second collection cycle ends. A metric is exported for the + // number of requests received over the interval of time t_0 to + // t_0+2 with a value of 5. + // 9. The system experiences a fault and loses state. + // 10. The system recovers and resumes receiving at time=t_1. + // 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. + // + // Note: Even though, when reporting changes since last report time, using + // CUMULATIVE is valid, it is not recommended. This may cause problems for + // systems that do not use start_time to determine when the aggregation + // value was reset (e.g. Prometheus). + AGGREGATION_TEMPORALITY_CUMULATIVE = 2; +} + +// DataPointFlags is defined as a protobuf 'uint32' type and is to be used as a +// bit-field representing 32 distinct boolean flags. Each flag defined in this +// enum is a bit-mask. To test the presence of a single flag in the flags of +// a data point, for example, use an expression like: +// +// (point.flags & DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK) == DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK +// +enum DataPointFlags { + // The zero value for the enum. Should not be used for comparisons. + // Instead use bitwise "and" with the appropriate mask as shown above. + DATA_POINT_FLAGS_DO_NOT_USE = 0; + + // This DataPoint is valid but has no recorded value. This value + // SHOULD be used to reflect explicitly missing data in a series, as + // for an equivalent to the Prometheus "staleness marker". + DATA_POINT_FLAGS_NO_RECORDED_VALUE_MASK = 1; + + // Bits 2-31 are reserved for future use. +} + +// NumberDataPoint is a single data point in a timeseries that describes the +// time-varying scalar value of a metric. +message NumberDataPoint { + reserved 1; + + // The set of key/value pairs that uniquely identify the timeseries from + // where this point belongs. The list may be empty (may contain 0 elements). + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue attributes = 7; + + // StartTimeUnixNano is optional but strongly encouraged, see the + // the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 start_time_unix_nano = 2; + + // TimeUnixNano is required, see the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 time_unix_nano = 3; + + // The value itself. A point is considered invalid when one of the recognized + // value fields is not present inside this oneof. + oneof value { + double as_double = 4; + sfixed64 as_int = 6; + } + + // (Optional) List of exemplars collected from + // measurements that were used to form the data point + repeated Exemplar exemplars = 5; + + // Flags that apply to this specific data point. See DataPointFlags + // for the available flags and their meaning. + uint32 flags = 8; +} + +// HistogramDataPoint is a single data point in a timeseries that describes the +// time-varying values of a Histogram. A Histogram contains summary statistics +// for a population of values, it may optionally contain the distribution of +// those values across a set of buckets. +// +// If the histogram contains the distribution of values, then both +// "explicit_bounds" and "bucket counts" fields must be defined. +// If the histogram does not contain the distribution of values, then both +// "explicit_bounds" and "bucket_counts" must be omitted and only "count" and +// "sum" are known. +message HistogramDataPoint { + reserved 1; + + // The set of key/value pairs that uniquely identify the timeseries from + // where this point belongs. The list may be empty (may contain 0 elements). + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue attributes = 9; + + // StartTimeUnixNano is optional but strongly encouraged, see the + // the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 start_time_unix_nano = 2; + + // TimeUnixNano is required, see the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 time_unix_nano = 3; + + // count is the number of values in the population. Must be non-negative. This + // value must be equal to the sum of the "count" fields in buckets if a + // histogram is provided. + fixed64 count = 4; + + // sum of the values in the population. If count is zero then this field + // must be zero. + // + // Note: Sum should only be filled out when measuring non-negative discrete + // events, and is assumed to be monotonic over the values of these events. + // Negative events *can* be recorded, but sum should not be filled out when + // doing so. This is specifically to enforce compatibility w/ OpenMetrics, + // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram + optional double sum = 5; + + // bucket_counts is an optional field contains the count values of histogram + // for each bucket. + // + // The sum of the bucket_counts must equal the value in the count field. + // + // The number of elements in bucket_counts array must be by one greater than + // the number of elements in explicit_bounds array. + repeated fixed64 bucket_counts = 6; + + // explicit_bounds specifies buckets with explicitly defined bounds for values. + // + // The boundaries for bucket at index i are: + // + // (-infinity, explicit_bounds[i]] for i == 0 + // (explicit_bounds[i-1], explicit_bounds[i]] for 0 < i < size(explicit_bounds) + // (explicit_bounds[i-1], +infinity) for i == size(explicit_bounds) + // + // The values in the explicit_bounds array must be strictly increasing. + // + // Histogram buckets are inclusive of their upper boundary, except the last + // bucket where the boundary is at infinity. This format is intentionally + // compatible with the OpenMetrics histogram definition. + repeated double explicit_bounds = 7; + + // (Optional) List of exemplars collected from + // measurements that were used to form the data point + repeated Exemplar exemplars = 8; + + // Flags that apply to this specific data point. See DataPointFlags + // for the available flags and their meaning. + uint32 flags = 10; + + // min is the minimum value over (start_time, end_time]. + optional double min = 11; + + // max is the maximum value over (start_time, end_time]. + optional double max = 12; +} + +// ExponentialHistogramDataPoint is a single data point in a timeseries that describes the +// time-varying values of a ExponentialHistogram of double values. A ExponentialHistogram contains +// summary statistics for a population of values, it may optionally contain the +// distribution of those values across a set of buckets. +// +message ExponentialHistogramDataPoint { + // The set of key/value pairs that uniquely identify the timeseries from + // where this point belongs. The list may be empty (may contain 0 elements). + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue attributes = 1; + + // StartTimeUnixNano is optional but strongly encouraged, see the + // the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 start_time_unix_nano = 2; + + // TimeUnixNano is required, see the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 time_unix_nano = 3; + + // count is the number of values in the population. Must be + // non-negative. This value must be equal to the sum of the "bucket_counts" + // values in the positive and negative Buckets plus the "zero_count" field. + fixed64 count = 4; + + // sum of the values in the population. If count is zero then this field + // must be zero. + // + // Note: Sum should only be filled out when measuring non-negative discrete + // events, and is assumed to be monotonic over the values of these events. + // Negative events *can* be recorded, but sum should not be filled out when + // doing so. This is specifically to enforce compatibility w/ OpenMetrics, + // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram + optional double sum = 5; + + // scale describes the resolution of the histogram. Boundaries are + // located at powers of the base, where: + // + // base = (2^(2^-scale)) + // + // The histogram bucket identified by `index`, a signed integer, + // contains values that are greater than (base^index) and + // less than or equal to (base^(index+1)). + // + // The positive and negative ranges of the histogram are expressed + // separately. Negative values are mapped by their absolute value + // into the negative range using the same scale as the positive range. + // + // scale is not restricted by the protocol, as the permissible + // values depend on the range of the data. + sint32 scale = 6; + + // zero_count is the count of values that are either exactly zero or + // within the region considered zero by the instrumentation at the + // tolerated degree of precision. This bucket stores values that + // cannot be expressed using the standard exponential formula as + // well as values that have been rounded to zero. + // + // Implementations MAY consider the zero bucket to have probability + // mass equal to (zero_count / count). + fixed64 zero_count = 7; + + // positive carries the positive range of exponential bucket counts. + Buckets positive = 8; + + // negative carries the negative range of exponential bucket counts. + Buckets negative = 9; + + // Buckets are a set of bucket counts, encoded in a contiguous array + // of counts. + message Buckets { + // Offset is the bucket index of the first entry in the bucket_counts array. + // + // Note: This uses a varint encoding as a simple form of compression. + sint32 offset = 1; + + // bucket_counts is an array of count values, where bucket_counts[i] carries + // the count of the bucket at index (offset+i). bucket_counts[i] is the count + // of values greater than base^(offset+i) and less than or equal to + // base^(offset+i+1). + // + // Note: By contrast, the explicit HistogramDataPoint uses + // fixed64. This field is expected to have many buckets, + // especially zeros, so uint64 has been selected to ensure + // varint encoding. + repeated uint64 bucket_counts = 2; + } + + // Flags that apply to this specific data point. See DataPointFlags + // for the available flags and their meaning. + uint32 flags = 10; + + // (Optional) List of exemplars collected from + // measurements that were used to form the data point + repeated Exemplar exemplars = 11; + + // min is the minimum value over (start_time, end_time]. + optional double min = 12; + + // max is the maximum value over (start_time, end_time]. + optional double max = 13; + + // ZeroThreshold may be optionally set to convey the width of the zero + // region. Where the zero region is defined as the closed interval + // [-ZeroThreshold, ZeroThreshold]. + // When ZeroThreshold is 0, zero count bucket stores values that cannot be + // expressed using the standard exponential formula as well as values that + // have been rounded to zero. + double zero_threshold = 14; +} + +// SummaryDataPoint is a single data point in a timeseries that describes the +// time-varying values of a Summary metric. +message SummaryDataPoint { + reserved 1; + + // The set of key/value pairs that uniquely identify the timeseries from + // where this point belongs. The list may be empty (may contain 0 elements). + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue attributes = 7; + + // StartTimeUnixNano is optional but strongly encouraged, see the + // the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 start_time_unix_nano = 2; + + // TimeUnixNano is required, see the detailed comments above Metric. + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 time_unix_nano = 3; + + // count is the number of values in the population. Must be non-negative. + fixed64 count = 4; + + // sum of the values in the population. If count is zero then this field + // must be zero. + // + // Note: Sum should only be filled out when measuring non-negative discrete + // events, and is assumed to be monotonic over the values of these events. + // Negative events *can* be recorded, but sum should not be filled out when + // doing so. This is specifically to enforce compatibility w/ OpenMetrics, + // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#summary + double sum = 5; + + // Represents the value at a given quantile of a distribution. + // + // To record Min and Max values following conventions are used: + // - The 1.0 quantile is equivalent to the maximum value observed. + // - The 0.0 quantile is equivalent to the minimum value observed. + // + // See the following issue for more context: + // https://github.com/open-telemetry/opentelemetry-proto/issues/125 + message ValueAtQuantile { + // The quantile of a distribution. Must be in the interval + // [0.0, 1.0]. + double quantile = 1; + + // The value at the given quantile of a distribution. + // + // Quantile values must NOT be negative. + double value = 2; + } + + // (Optional) list of values at different quantiles of the distribution calculated + // from the current snapshot. The quantiles must be strictly increasing. + repeated ValueAtQuantile quantile_values = 6; + + // Flags that apply to this specific data point. See DataPointFlags + // for the available flags and their meaning. + uint32 flags = 8; +} + +// A representation of an exemplar, which is a sample input measurement. +// Exemplars also hold information about the environment when the measurement +// was recorded, for example the span and trace ID of the active span when the +// exemplar was recorded. +message Exemplar { + reserved 1; + + // The set of key/value pairs that were filtered out by the aggregator, but + // recorded alongside the original measurement. Only key/value pairs that were + // filtered out by the aggregator should be included + repeated opentelemetry.proto.common.v1.KeyValue filtered_attributes = 7; + + // time_unix_nano is the exact time when this exemplar was recorded + // + // Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January + // 1970. + fixed64 time_unix_nano = 2; + + // The value of the measurement that was recorded. An exemplar is + // considered invalid when one of the recognized value fields is not present + // inside this oneof. + oneof value { + double as_double = 3; + sfixed64 as_int = 6; + } + + // (Optional) Span ID of the exemplar trace. + // span_id may be missing if the measurement is not recorded inside a trace + // or if the trace is not sampled. + bytes span_id = 4; + + // (Optional) Trace ID of the exemplar trace. + // trace_id may be missing if the measurement is not recorded inside a trace + // or if the trace is not sampled. + bytes trace_id = 5; +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/resource/v1/resource.proto b/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/resource/v1/resource.proto new file mode 100644 index 0000000000..6637560bc3 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/resource/v1/resource.proto @@ -0,0 +1,37 @@ +// Copyright 2019, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package opentelemetry.proto.resource.v1; + +import "opentelemetry/proto/common/v1/common.proto"; + +option csharp_namespace = "OpenTelemetry.Proto.Resource.V1"; +option java_multiple_files = true; +option java_package = "io.opentelemetry.proto.resource.v1"; +option java_outer_classname = "ResourceProto"; +option go_package = "go.opentelemetry.io/proto/otlp/resource/v1"; + +// Resource information. +message Resource { + // Set of attributes that describe the resource. + // Attribute keys MUST be unique (it is not allowed to have more than one + // attribute with the same key). + repeated opentelemetry.proto.common.v1.KeyValue attributes = 1; + + // dropped_attributes_count is the number of dropped attributes. If the value is 0, then + // no attributes were dropped. + uint32 dropped_attributes_count = 2; +} From 67d46c32e62a500fc3f43b66d740ca37f0b99434 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 27 Mar 2024 00:46:21 -0500 Subject: [PATCH 0992/1499] Suppress AOT analyzer warning in Redis instrumentation (#1625) --- .../Implementation/RedisProfilerEntryToActivityConverter.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 0d13c2d13d..9052b95031 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -207,7 +207,10 @@ public static void DrainSession(Activity? parentActivity, IEnumerable Date: Wed, 27 Mar 2024 11:13:05 -0700 Subject: [PATCH 0993/1499] [Exporter.Geneva] [otlp format] Add double counter support (#1626) --- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 49 +++++++- .../OtlpProtobufMetricExporterTests.cs | 118 +++++++++++------- 2 files changed, 124 insertions(+), 43 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 89a48ebce5..1a197469ab 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -204,7 +204,54 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) case MetricType.DoubleSum: case MetricType.DoubleSumNonMonotonic: { - // TODO + cursor = this.instrumentValueIndex; + + // Write isMonotonic tag + ProtobufSerializerHelper.WriteBoolWithTag(buffer, ref cursor, FieldNumberConstants.Sum_is_monotonic, metric.MetricType == MetricType.DoubleSum); + + // Write aggregationTemporality tag + ProtobufSerializerHelper.WriteEnumWithTag(buffer, ref cursor, FieldNumberConstants.Sum_aggregation_temporality, metric.Temporality == AggregationTemporality.Cumulative ? 2 : 1); + + this.metricPointTagAndLengthIndex = cursor; + this.metricPointValueIndex = cursor + TagAndLengthSize; + foreach (var metricPoint in metric.GetMetricPoints()) + { + try + { + // Reset cursor to write new metricPoint + cursor = this.metricPointValueIndex; + + var sum = metricPoint.GetSumDouble(); + + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_double, sum); + + var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_start_time_unix_nano, startTime); + + var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_time_unix_nano, endTime); + + SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.NumberDataPoint_attributes); + + // TODO: exemplars. + + var metricPointStartPosition = this.metricPointTagAndLengthIndex; + + // Write numberdatapoint {Repeated field} + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.Sum_data_points, WireType.LEN); + + // Finish writing current batch + this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); + + // Send metricPoint + this.SendMetricPoint(buffer, ref cursor); + } + catch + { + // TODO: log exception. + } + } + break; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 69a03348eb..295ded46e4 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -19,12 +19,14 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; public class OtlpProtobufMetricExporterTests { [Theory] - [InlineData(123)] - [InlineData(-123)] - public void LongCounterSerializationSingleMetricPoint(long value) + [InlineData("longcounter", 123L, null)] + [InlineData("doublecounter", null, 123.45)] + [InlineData("longcounter", -123L, null)] + [InlineData("doublecounter", null, -123.45)] + public void CounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue) { - using var meter = new Meter(nameof(this.LongCounterSerializationSingleMetricPoint), "0.0.1"); - var longCounter = meter.CreateCounter("longCounter"); + using var meter = new Meter(nameof(this.CounterSerializationSingleMetricPoint), "0.0.1"); + var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { @@ -35,11 +37,20 @@ public void LongCounterSerializationSingleMetricPoint(long value) .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); using var meterProvider = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) - .AddMeter(nameof(this.LongCounterSerializationSingleMetricPoint)) + .AddMeter(nameof(this.CounterSerializationSingleMetricPoint)) .AddReader(inMemoryReader) - .Build(); + .Build(); - longCounter.Add(value, new("tag1", "value1"), new("tag2", "value2")); + if (longValue != null) + { + var counter = meter.CreateCounter(instrumentName); + counter.Add(longValue.Value, new("tag1", "value1"), new("tag2", "value2")); + } + else + { + var counter = meter.CreateCounter(instrumentName); + counter.Add(doubleValue.Value, new("tag1", "value1"), new("tag2", "value2")); + } meterProvider.ForceFlush(); @@ -72,7 +83,7 @@ public void LongCounterSerializationSingleMetricPoint(long value) var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; - Assert.Equal(longCounter.Name, metric.Name); + Assert.Equal(instrumentName, metric.Name); Assert.NotNull(metric.Sum); @@ -84,25 +95,35 @@ public void LongCounterSerializationSingleMetricPoint(long value) var dataPoint = metric.Sum.DataPoints[0]; - Assert.Equal(value, dataPoint.AsInt); + if (longValue != null) + { + Assert.Equal(longValue, dataPoint.AsInt); + } + else + { + Assert.Equal(doubleValue, dataPoint.AsDouble); + } // Assert time var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - Assert.Equal((ulong)TimestampHelpers.ToUnixTimeNanoseconds(metricPoint.StartTime), dataPoint.StartTimeUnixNano); + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); - Assert.Equal((ulong)TimestampHelpers.ToUnixTimeNanoseconds(metricPoint.EndTime), dataPoint.TimeUnixNano); + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); } - [Fact] - public void LongCounterSerializationMultipleMetricPoints() + [Theory] + [InlineData("longcounter", new long[] { 10, 20, 30 }, null)] + [InlineData("longcounter", new long[] { -10, 2, -30 }, null)] + [InlineData("doublecounter", null, new double[] { 10.20, 2, 30.65 })] + [InlineData("doublecounter", null, new double[] { -10.20, 2, -30.65 })] + public void CounterSerializationMultipleMetricPoints(string instrumentName, long[] longValues, double[] doubleValues) { - using var meter = new Meter(nameof(this.LongCounterSerializationMultipleMetricPoints), "0.0.1"); - var longCounter = meter.CreateCounter("longCounter"); + using var meter = new Meter(nameof(this.CounterSerializationMultipleMetricPoints), "0.0.1"); var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { @@ -110,31 +131,39 @@ public void LongCounterSerializationMultipleMetricPoints() }; using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter(nameof(this.LongCounterSerializationMultipleMetricPoints)) + .AddMeter(nameof(this.CounterSerializationMultipleMetricPoints)) .AddReader(inMemoryReader) .Build(); - TagList[] tags = new TagList[3]; - - tags[0].Add(new("tag1", "value1")); - tags[0].Add(new("tag2", "value2")); - - tags[1].Add(new("tag1", "value1")); - tags[1].Add(new("tag2", "value2")); - tags[1].Add(new("tag3", "value3")); + int expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; + TagList[] tags = new TagList[expectedMetricPoints]; - tags[2].Add(new("tag1", "value1")); - tags[2].Add(new("tag2", "value2")); - tags[2].Add(new("tag3", "value3")); - tags[2].Add(new("tag4", "value4")); - - longCounter.Add(62, tags[0]); + for (int i = 0; i < tags.Length; i++) + { + for (int j = 1; j <= (i + 1); j++) + { + tags[i].Add(new("tag" + j, "value" + j)); + } + } - longCounter.Add(62, tags[0]); + if (longValues != null) + { + var counter = meter.CreateCounter(instrumentName); - longCounter.Add(124, tags[1]); + for (int i = 0; i < longValues.Length; i++) + { + counter.Add(longValues[i], tags[i]); + } + } + else + { + var counter = meter.CreateCounter(instrumentName); - longCounter.Add(124, tags[2]); + for (int i = 0; i < doubleValues.Length; i++) + { + counter.Add(doubleValues[i], tags[i]); + } + } meterProvider.ForceFlush(); @@ -145,14 +174,12 @@ public void LongCounterSerializationMultipleMetricPoints() otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); - // 3 unique measurements. - var exportedItemsCount = testTransport.ExportedItems.Count; - Assert.Equal(3, exportedItemsCount); + Assert.Equal(expectedMetricPoints, testTransport.ExportedItems.Count); // For asserting time var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); - for (int i = 0; i < exportedItemsCount; i++) + for (int i = 0; i < expectedMetricPoints; i++) { var request = new OtlpCollector.ExportMetricsServiceRequest(); @@ -170,7 +197,7 @@ public void LongCounterSerializationMultipleMetricPoints() var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; - Assert.Equal(longCounter.Name, metric.Name); + Assert.Equal(instrumentName, metric.Name); Assert.NotNull(metric.Sum); @@ -182,14 +209,21 @@ public void LongCounterSerializationMultipleMetricPoints() var dataPoint = metric.Sum.DataPoints[0]; - Assert.Equal(124, dataPoint.AsInt); + if (longValues != null) + { + Assert.Equal(longValues[i], dataPoint.AsInt); + } + else + { + Assert.Equal(doubleValues[i], dataPoint.AsDouble); + } metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - Assert.Equal((ulong)TimestampHelpers.ToUnixTimeNanoseconds(metricPoint.StartTime), dataPoint.StartTimeUnixNano); + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); - Assert.Equal((ulong)TimestampHelpers.ToUnixTimeNanoseconds(metricPoint.EndTime), dataPoint.TimeUnixNano); + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); AssertOtlpAttributes(tags[i], dataPoint.Attributes); } From 8f21a9819e7950e0d2629c17b7c8cb6faaa444e3 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 28 Mar 2024 17:33:55 -0700 Subject: [PATCH 0994/1499] [Exporter.Geneva][otlp protobuf] Add test for updown counter (#1628) --- .../OtlpProtobufMetricExporterTests.cs | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 295ded46e4..cfffe18359 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -229,6 +229,217 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long } } + [Theory] + [InlineData("updownlongcounter", 123L, null)] + [InlineData("updowndoublecounter", null, 123.45)] + [InlineData("updownlongcounter", -123L, null)] + [InlineData("updowndoublecounter", null, -123.45)] + public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue) + { + using var meter = new Meter(nameof(this.UpdownCounterSerializationSingleMetricPoint), "0.0.1"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() + .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(resourceBuilder) + .AddMeter(nameof(this.UpdownCounterSerializationSingleMetricPoint)) + .AddReader(inMemoryReader) + .Build(); + + if (longValue != null) + { + var counter = meter.CreateUpDownCounter(instrumentName); + counter.Add(longValue.Value, new("tag1", "value1"), new("tag2", "value2")); + } + else + { + var counter = meter.CreateUpDownCounter(instrumentName); + counter.Add(doubleValue.Value, new("tag1", "value1"), new("tag2", "value2")); + } + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Single(testTransport.ExportedItems); + + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[0]); + + Assert.Single(request.ResourceMetrics); + + Assert.NotNull(request.ResourceMetrics[0].Resource); + + AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal(instrumentName, metric.Name); + + Assert.NotNull(metric.Sum); + + Assert.Equal(2, (int)metric.Sum.AggregationTemporality); + + Assert.False(metric.Sum.IsMonotonic); + + Assert.Single(metric.Sum.DataPoints); + + var dataPoint = metric.Sum.DataPoints[0]; + + if (longValue != null) + { + Assert.Equal(longValue, dataPoint.AsInt); + } + else + { + Assert.Equal(doubleValue, dataPoint.AsDouble); + } + + // Assert time + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + } + + [Theory] + [InlineData("updownlongcounter", new long[] { 10, 20, 30 }, null)] + [InlineData("updownlongcounter", new long[] { 10, -2, 30 }, null)] + [InlineData("updowndoublecounter", null, new double[] { 10.20, 2, 30.65 })] + [InlineData("updowndoublecounter", null, new double[] { -10.20, 2, -30.65 })] + public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName, long[] longValues, double[] doubleValues) + { + using var meter = new Meter(nameof(this.UpdownCounterSerializationMultipleMetricPoints), "0.0.1"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(nameof(this.UpdownCounterSerializationMultipleMetricPoints)) + .AddReader(inMemoryReader) + .Build(); + + int expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; + TagList[] tags = new TagList[expectedMetricPoints]; + + for (int i = 0; i < tags.Length; i++) + { + for (int j = 1; j <= (i + 1); j++) + { + tags[i].Add(new("tag" + j, "value" + j)); + } + } + + if (longValues != null) + { + var counter = meter.CreateUpDownCounter(instrumentName); + + for (int i = 0; i < longValues.Length; i++) + { + counter.Add(longValues[i], tags[i]); + } + } + else + { + var counter = meter.CreateUpDownCounter(instrumentName); + + for (int i = 0; i < doubleValues.Length; i++) + { + counter.Add(doubleValues[i], tags[i]); + } + } + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Equal(expectedMetricPoints, testTransport.ExportedItems.Count); + + // For asserting time + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + + for (int i = 0; i < expectedMetricPoints; i++) + { + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[i]); + + Assert.Single(request.ResourceMetrics); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal(instrumentName, metric.Name); + + Assert.NotNull(metric.Sum); + + Assert.Equal(2, (int)metric.Sum.AggregationTemporality); + + Assert.False(metric.Sum.IsMonotonic); + + Assert.Single(metric.Sum.DataPoints); + + var dataPoint = metric.Sum.DataPoints[0]; + + if (longValues != null) + { + Assert.Equal(longValues[i], dataPoint.AsInt); + } + else + { + Assert.Equal(doubleValues[i], dataPoint.AsDouble); + } + + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + AssertOtlpAttributes(tags[i], dataPoint.Attributes); + } + } + internal static void AssertOtlpAttributes( IEnumerable> expected, RepeatedField actual) From bbfd7bde3e1f9aa637d655dea9f6765b09d87607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 29 Mar 2024 21:00:41 +0100 Subject: [PATCH 0995/1499] Bump MinVer to 5.0.0 (#1633) --- build/Common.props | 2 +- .../AWSLambdaWrapperTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/Common.props b/build/Common.props index 6cfd2c3362..c2daf1cef8 100644 --- a/build/Common.props +++ b/build/Common.props @@ -29,7 +29,7 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [4.3.0,5.0) + [5.0.0,6.0) [2.1.0,5.0) [3.1.0,) [1.0.3,2.0) diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index dd014dbe39..90b9d26388 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -234,8 +234,8 @@ private void AssertSpanProperties(Activity activity, string parentId) Assert.Equal("testfunction", activity.DisplayName); Assert.Equal("OpenTelemetry.Instrumentation.AWSLambda", activity.Source.Name); - // Version should consist of four decimals separated by dots. - Assert.Matches(@"^\d+(\.\d+){3}$", activity.Source.Version); + // Version should consist of 3 decimals separated by dots followed by optional pre-release suffix + Assert.Matches(@"^\d+(\.\d+){2}(-.+)?$", activity.Source.Version); } private void AssertResourceAttributes(Resource? resource) From 0bb07c03ee9bf1897dd6297491659b9ed8358d2a Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 29 Mar 2024 16:48:48 -0700 Subject: [PATCH 0996/1499] [Exporter.Geneva][otlp protobuf] Add histogram support (#1629) --- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 64 ++++- .../OtlpProtobufMetricExporterTests.cs | 226 ++++++++++++++++++ 2 files changed, 289 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 1a197469ab..92333efc8e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -269,7 +269,69 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) case MetricType.Histogram: { - // TODO + cursor = this.instrumentValueIndex; + + // Write aggregationTemporality tag + ProtobufSerializerHelper.WriteEnumWithTag(buffer, ref cursor, FieldNumberConstants.Histogram_aggregation_temporality, metric.Temporality == AggregationTemporality.Cumulative ? 2 : 1); + + this.metricPointTagAndLengthIndex = cursor; + this.metricPointValueIndex = cursor + TagAndLengthSize; + foreach (var metricPoint in metric.GetMetricPoints()) + { + try + { + // Reset cursor to write new metricPoint + cursor = this.metricPointValueIndex; + + var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_start_time_unix_nano, startTime); + + var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_time_unix_nano, endTime); + + SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.HistogramDataPoint_attributes); + + var count = (ulong)metricPoint.GetHistogramCount(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_count, count); + + var sum = metricPoint.GetHistogramSum(); + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_sum, sum); + + if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_min, min); + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_max, max); + } + + foreach (var histogramMeasurement in metricPoint.GetHistogramBuckets()) + { + var bucketCount = (ulong)histogramMeasurement.BucketCount; + + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_bucket_counts, bucketCount); + if (histogramMeasurement.ExplicitBound != double.PositiveInfinity) + { + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_explicit_bounds, histogramMeasurement.ExplicitBound); + } + } + + // TODO: exemplars. + + var metricPointStartPosition = this.metricPointTagAndLengthIndex; + + // Write numberdatapoint {Repeated field} + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.Histogram_data_points, WireType.LEN); + + // Finish writing current batch + this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); + + // Send metricPoint + this.SendMetricPoint(buffer, ref cursor); + } + catch + { + } + } + break; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index cfffe18359..125b905bc5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -440,6 +440,232 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName } } + [Theory] + [InlineData(123.45)] + [InlineData(-123.45)] + public void HistogramSerializationSingleMetricPoint(double doubleValue) + { + using var meter = new Meter(nameof(this.HistogramSerializationSingleMetricPoint), "0.0.1"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() + .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(resourceBuilder) + .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) + .AddReader(inMemoryReader) + .Build(); + + var histogram = meter.CreateHistogram("TestHistogram"); + histogram.Record(doubleValue, new("tag1", "value1"), new("tag2", "value2")); + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Single(testTransport.ExportedItems); + + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[0]); + + Assert.Single(request.ResourceMetrics); + + Assert.NotNull(request.ResourceMetrics[0].Resource); + + AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal("TestHistogram", metric.Name); + + Assert.NotNull(metric.Histogram); + + Assert.Equal(1, (int)metric.Histogram.AggregationTemporality); + + Assert.Single(metric.Histogram.DataPoints); + + var dataPoint = metric.Histogram.DataPoints[0]; + + Assert.Equal(doubleValue, dataPoint.Sum); + + Assert.Equal(doubleValue, dataPoint.Max); + + Assert.Equal(doubleValue, dataPoint.Min); + + // Assert time + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + int bucketCountIndex = 0; + int explicitBoundCountIndex = 0; + + foreach (var histogramMeasurement in metricPoint.GetHistogramBuckets()) + { + var bucketCount = (ulong)histogramMeasurement.BucketCount; + + Assert.Equal(bucketCount, dataPoint.BucketCounts[bucketCountIndex]); + + if (histogramMeasurement.ExplicitBound != double.PositiveInfinity) + { + Assert.Equal(histogramMeasurement.ExplicitBound, dataPoint.ExplicitBounds[explicitBoundCountIndex]); + explicitBoundCountIndex++; + } + + bucketCountIndex++; + } + + Assert.Equal(bucketCountIndex, dataPoint.BucketCounts.Count); + + Assert.Equal(explicitBoundCountIndex, dataPoint.ExplicitBounds.Count); + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + } + + [Theory] + [InlineData(new[] { -123.45, 23, .05, 100 })] + public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) + { + using var meter = new Meter(nameof(this.HistogramSerializationSingleMetricPoint), "0.0.1"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() + .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(resourceBuilder) + .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) + .AddReader(inMemoryReader) + .Build(); + + var histogram = meter.CreateHistogram("TestHistogram"); + + int expectedMetricPointCount = doubleValues.Length; + + TagList[] tags = new TagList[expectedMetricPointCount]; + + for (int i = 0; i < tags.Length; i++) + { + for (int j = 1; j <= (i + 1); j++) + { + tags[i].Add(new("tag" + j, "value" + j)); + } + } + + for (int i = 0; i < expectedMetricPointCount; i++) + { + histogram.Record(doubleValues[i], tags[i]); + } + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Equal(expectedMetricPointCount, testTransport.ExportedItems.Count); + + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + + for (int i = 0; i < expectedMetricPointCount; i++) + { + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[i]); + + Assert.NotNull(request.ResourceMetrics[0].Resource); + + AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal("TestHistogram", metric.Name); + + Assert.NotNull(metric.Histogram); + + Assert.Equal(1, (int)metric.Histogram.AggregationTemporality); + + Assert.Single(metric.Histogram.DataPoints); + + var dataPoint = metric.Histogram.DataPoints[0]; + + Assert.Equal(doubleValues[i], dataPoint.Sum); + + Assert.Equal(doubleValues[i], dataPoint.Max); + + Assert.Equal(doubleValues[i], dataPoint.Min); + + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + int bucketCountIndex = 0; + int explicitBoundCountIndex = 0; + + foreach (var histogramMeasurement in metricPoint.GetHistogramBuckets()) + { + var bucketCount = (ulong)histogramMeasurement.BucketCount; + + Assert.Equal(bucketCount, dataPoint.BucketCounts[bucketCountIndex]); + + if (histogramMeasurement.ExplicitBound != double.PositiveInfinity) + { + Assert.Equal(histogramMeasurement.ExplicitBound, dataPoint.ExplicitBounds[explicitBoundCountIndex]); + explicitBoundCountIndex++; + } + + bucketCountIndex++; + } + + Assert.Equal(bucketCountIndex, dataPoint.BucketCounts.Count); + + Assert.Equal(explicitBoundCountIndex, dataPoint.ExplicitBounds.Count); + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + AssertOtlpAttributes(tags[i], dataPoint.Attributes); + } + } + internal static void AssertOtlpAttributes( IEnumerable> expected, RepeatedField actual) From 11f5c2ccb5e618698b88cbc37d4a142ad8d25052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 2 Apr 2024 07:12:10 +0200 Subject: [PATCH 0997/1499] Instrumentation spans and metrcis - set ActivitySource/Meter.Version to NuGet package version (#1624) --- opentelemetry-dotnet-contrib.sln | 1 + src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 2 ++ .../Implementation/AWSTracingPipelineHandler.cs | 2 +- .../OpenTelemetry.Instrumentation.AWS.csproj | 1 + .../AWSLambdaWrapper.cs | 4 +--- .../OpenTelemetry.Instrumentation.AWSLambda.csproj | 1 + .../ActivityHelper.cs | 2 +- .../CHANGELOG.md | 3 +++ ...strumentation.AspNet.TelemetryHttpModule.csproj | 1 + .../AspNetMetrics.cs | 2 +- .../CHANGELOG.md | 2 ++ .../OpenTelemetry.Instrumentation.AspNet.csproj | 1 + .../CHANGELOG.md | 2 ++ .../CassandraMeter.cs | 2 +- .../OpenTelemetry.Instrumentation.Cassandra.csproj | 1 + .../CHANGELOG.md | 2 ++ ...asticsearchRequestPipelineDiagnosticListener.cs | 3 +-- ...etry.Instrumentation.ElasticsearchClient.csproj | 1 + .../CHANGELOG.md | 2 ++ .../EntityFrameworkDiagnosticListener.cs | 3 +-- ...etry.Instrumentation.EntityFrameworkCore.csproj | 1 + .../CHANGELOG.md | 2 ++ .../EventCountersMetrics.cs | 2 +- ...nTelemetry.Instrumentation.EventCounters.csproj | 1 + .../CHANGELOG.md | 2 ++ .../GrpcCoreInstrumentation.cs | 8 +------- .../OpenTelemetry.Instrumentation.GrpcCore.csproj | 1 + .../CHANGELOG.md | 2 ++ .../Implementation/HangfireInstrumentation.cs | 7 +------ .../OpenTelemetry.Instrumentation.Hangfire.csproj | 1 + .../CHANGELOG.md | 3 +++ .../OwinInstrumentationActivitySource.cs | 5 +---- .../Implementation/OwinInstrumentationMetrics.cs | 2 +- .../OpenTelemetry.Instrumentation.Owin.csproj | 1 + .../CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.Process.csproj | 1 + .../ProcessMetrics.cs | 2 +- .../CHANGELOG.md | 3 +++ .../Implementation/QuartzDiagnosticListener.cs | 3 +-- .../OpenTelemetry.Instrumentation.Quartz.csproj | 1 + .../CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.Runtime.csproj | 1 + .../RuntimeMetrics.cs | 2 +- .../CHANGELOG.md | 2 ++ ...metry.Instrumentation.StackExchangeRedis.csproj | 1 + .../StackExchangeRedisConnectionInstrumentation.cs | 3 +-- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ .../WcfInstrumentationActivitySource.cs | 5 +---- .../OpenTelemetry.Instrumentation.Wcf.csproj | 1 + src/Shared/SignalVersionHelper.cs | 14 ++++++++++++++ 50 files changed, 84 insertions(+), 40 deletions(-) create mode 100644 src/Shared/SignalVersionHelper.cs diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 98d6bb18aa..7f3a0f099b 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -283,6 +283,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\PropertyFetcher.AOT.cs = src\Shared\PropertyFetcher.AOT.cs src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs + src\Shared\SignalVersionHelper.cs = src\Shared\SignalVersionHelper.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs EndProjectSection diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index f5c9d98b94..14192e241a 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -4,6 +4,8 @@ * BREAKING: Switched AWSServiceName tag to use ServiceId instead of ServiceName ([#1572](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1572)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.1.0-beta.3 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index fe4dfc3636..5f33b8e8b0 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -23,7 +23,7 @@ internal sealed class AWSTracingPipelineHandler : PipelineHandler { internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; - private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName); + private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); private readonly AWSClientInstrumentationOptions options; diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index 6d0c8c9a86..c5b953d028 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -16,6 +16,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 3102659426..ee244cf95e 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using Amazon.Lambda.Core; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; @@ -21,8 +20,7 @@ public static class AWSLambdaWrapper { internal const string ActivitySourceName = "OpenTelemetry.Instrumentation.AWSLambda"; - private static readonly string Version = typeof(AWSLambdaWrapper).Assembly.GetCustomAttribute()!.InformationalVersion.Split('+')[0]; - private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, Version); + private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); /// /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 994ba449a7..fe7540cd53 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -16,6 +16,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index 6ad9f989af..ffc7a5996e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -26,7 +26,7 @@ internal static class ActivityHelper private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); private static readonly ActivitySource AspNetSource = new( TelemetryHttpModule.AspNetSourceName, - typeof(ActivityHelper).Assembly.GetName().Version.ToString()); + SignalVersionHelper.GetVersion()); /// /// Try to get the started for the running + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs index be7b92e110..09fda21770 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -15,7 +15,7 @@ internal sealed class AspNetMetrics : IDisposable { internal static readonly AssemblyName AssemblyName = typeof(HttpInMetricsListener).Assembly.GetName(); internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + internal static readonly string InstrumentationVersion = SignalVersionHelper.GetVersion(); private readonly Meter meter; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index a5c732e472..5d5be1fa39 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -23,6 +23,8 @@ * `url.scheme` added with `http` or `https` value, * `user_agent.original` replaces `http.user_agent`. ([#1607](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1607)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.7.0-beta.2 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 5fa9821675..19b8e9cf79 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -13,6 +13,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 111be2ef79..e74fc26843 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs index d2e13177c6..f00ce0e5cf 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs @@ -7,5 +7,5 @@ namespace OpenTelemetry.Instrumentation.Cassandra; internal static class CassandraMeter { - public static Meter Instance => new Meter(typeof(CassandraMeter).Assembly.GetName().Name); + public static Meter Instance => new Meter(typeof(CassandraMeter).Assembly.GetName().Name, SignalVersionHelper.GetVersion()); } diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index c1e28dd741..b07e4e94e7 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -13,6 +13,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 0d9f9ad44d..3b17d1abf3 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -6,6 +6,8 @@ ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) * Span status is set based on [semantic convention for client spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status). ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 62c67ff332..7d1ecd5a07 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -25,8 +25,7 @@ internal class ElasticsearchRequestPipelineDiagnosticListener : ListenerHandler internal static readonly AssemblyName AssemblyName = typeof(ElasticsearchRequestPipelineDiagnosticListener).Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); private static readonly Regex ParseRequest = new Regex(@"\n# Request:\r?\n(\{.*)\n# Response", RegexOptions.Compiled | RegexOptions.Singleline); private static readonly ConcurrentDictionary MethodNameCache = new ConcurrentDictionary(); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index e955860579..d648bb5535 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -18,6 +18,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 8b03c4e272..eadf4bcdf5 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -9,6 +9,8 @@ Released 2024-Feb-07 * **Breaking Change**: Stop emitting `db.statement_type` attribute. This attribute never was part of the [semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md#call-level-attributes). ([#1559](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1559)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-beta.9 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index b0392ff40d..942f7d07d3 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -25,9 +25,8 @@ internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler internal static readonly string ActivitySourceName = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Name; internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - private static readonly Version Version = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Version; #pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before SqlClientActivitySource otherwise null ref exception is thrown. - internal static readonly ActivitySource SqlClientActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource SqlClientActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); #pragma warning restore SA1202 // Elements should be ordered by access private readonly PropertyFetcher commandFetcher = new("Command"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index e54a6f1181..2479b7c28e 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -12,6 +12,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index aac23e50b6..aa901d7827 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -4,6 +4,8 @@ * Update `OpenTelemetry.Api` to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* `Meter.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.5.1-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index 460cd1b286..56171fe9ee 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.Instrumentation.EventCounters; /// internal sealed class EventCountersMetrics : EventListener { - internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, typeof(EventCountersMetrics).Assembly.GetName().Version.ToString()); + internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, SignalVersionHelper.GetVersion()); private const string Prefix = "ec"; private const int MaxInstrumentNameLength = 63; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 8b7a31dc0d..0dfdd36174 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -10,6 +10,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index f0e42313cd..928c9793fc 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -10,6 +10,8 @@ ([#1456](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1456)) * Update `OpenTelemetry.Api` to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index 7375ee27f3..825369d487 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using System.Reflection; @@ -22,13 +21,8 @@ internal static class GrpcCoreInstrumentation /// internal static readonly string ActivitySourceName = AssemblyName.Name; - /// - /// The version. - /// - internal static readonly Version Version = AssemblyName.Version; - /// /// The activity source. /// - internal static readonly ActivitySource ActivitySource = new ActivitySource(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index d352de48ba..df6379af1d 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -13,6 +13,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 204bb8bc26..5712291ad5 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -5,6 +5,8 @@ * Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.7.0`. * Update `OpenTelemetry.Api` to `1.7.0`. ([#1508](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1508)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.6.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index 163f4c235a..6f955aa3b1 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -21,15 +21,10 @@ internal sealed class HangfireInstrumentation /// internal static readonly string ActivitySourceName = AssemblyName.Name; - /// - /// The version. - /// - internal static readonly Version Version = AssemblyName.Version; - /// /// The activity source. /// - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); /// /// The default display name delegate. diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index e38c79a9ab..0d6d8e7a46 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -12,6 +12,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index a550c6f6a8..61f7cae216 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* `ActivitySource.Version` and `Meter.Version` are set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + ## 1.0.0-rc.4 Released 2024-Mar-20 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index 319d337db7..f0571be8b4 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using System.Reflection; @@ -13,9 +12,7 @@ internal static class OwinInstrumentationActivitySource internal static readonly string ActivitySourceName = AssemblyName.Name; internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; - private static readonly Version Version = AssemblyName.Version; - - public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, Version.ToString()); + public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, SignalVersionHelper.GetVersion()); public static OwinInstrumentationOptions? Options { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs index a1d2f5a0a5..09671a1317 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -12,7 +12,7 @@ internal static class OwinInstrumentationMetrics public static string MeterName => AssemblyName.Name; - public static Meter Instance => new Meter(MeterName, AssemblyName.Version.ToString()); + public static Meter Instance => new(MeterName, SignalVersionHelper.GetVersion()); public static Histogram HttpServerDuration => Instance.CreateHistogram("http.server.request.duration", "s", "Duration of HTTP server requests."); } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 7e5c9223a6..5b611bb4b9 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -7,6 +7,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 2015d6bcce..475b4308f0 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* `Meter.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + ## 0.5.0-beta.4 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index 4bd00f576a..54a0ab562c 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -11,6 +11,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 78856ef4a3..9046a51fad 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -16,7 +16,7 @@ internal sealed class ProcessMetrics internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); internal static readonly string MeterName = AssemblyName.Name; - private static readonly Meter MeterInstance = new(MeterName, AssemblyName.Version.ToString()); + private static readonly Meter MeterInstance = new(MeterName, SignalVersionHelper.GetVersion()); static ProcessMetrics() { diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 4a0c7d3953..56cff01e61 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + ## 1.0.0-beta.1 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 9b30de1c1a..ecbb82d05b 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -15,8 +15,7 @@ internal sealed class QuartzDiagnosticListener : ListenerHandler { internal static readonly AssemblyName AssemblyName = typeof(QuartzDiagnosticListener).Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); internal readonly PropertyFetcher JobDetailsPropertyFetcher = new("JobDetail"); private readonly QuartzInstrumentationOptions options; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 36421febf6..417e467db6 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -10,6 +10,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 764a282f86..2fe7c93aa1 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* `Meter.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + ## 1.7.0 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 7438ef8ed5..74fd5a74ff 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -12,6 +12,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 33d9a42bef..21bb5b17d8 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -18,7 +18,7 @@ namespace OpenTelemetry.Instrumentation.Runtime; internal sealed class RuntimeMetrics { internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); - internal static readonly Meter MeterInstance = new(AssemblyName.Name!, AssemblyName.Version?.ToString()); + internal static readonly Meter MeterInstance = new(AssemblyName.Name!, SignalVersionHelper.GetVersion()); #if NET6_0_OR_GREATER private const long NanosecondsPerTick = 100; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index bafdd8ea82..2b24bf8240 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -8,6 +8,8 @@ Released 2024-Jan-03 * Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-rc9.12 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 4f392d1142..410cdbabef 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -9,6 +9,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs index 255ebc0b30..7bdc34ee2d 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs @@ -20,8 +20,7 @@ internal sealed class StackExchangeRedisConnectionInstrumentation : IDisposable internal const string RedisFlagsKeyName = "db.redis.flags"; internal static readonly string ActivitySourceName = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Name!; internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - internal static readonly Version Version = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Version!; - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); internal static readonly IEnumerable> CreationTags = new[] { new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 36fee98fcb..7bc1c844e2 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + ## 1.0.0-rc.15 Released 2024-Feb-07 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index 07b43edf24..f51cc8d7df 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; @@ -20,9 +19,7 @@ internal static class WcfInstrumentationActivitySource internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; internal static readonly string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; - private static readonly Version Version = AssemblyName.Version; - - public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Version.ToString()); + public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, SignalVersionHelper.GetVersion()); public static WcfInstrumentationOptions? Options { get; set; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 3abd889cdf..9ea3f6aa2b 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -23,6 +23,7 @@ + diff --git a/src/Shared/SignalVersionHelper.cs b/src/Shared/SignalVersionHelper.cs new file mode 100644 index 0000000000..37f65ba600 --- /dev/null +++ b/src/Shared/SignalVersionHelper.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Reflection; + +namespace OpenTelemetry.Instrumentation; + +internal static class SignalVersionHelper +{ + public static string GetVersion() + { + return typeof(T).Assembly.GetCustomAttribute()!.InformationalVersion.Split('+')[0]; + } +} From fb7cdba2c0c682a62c6a1a70c9c7279205a865ab Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 2 Apr 2024 16:07:16 -0700 Subject: [PATCH 0998/1499] [Exporter.Geneva][otlp protobuf] Add support for Gauge (#1634) --- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 124 +++++++--- .../OtlpProtobufMetricExporterTests.cs | 227 +++++++++++++++++- 2 files changed, 313 insertions(+), 38 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 92333efc8e..f6a124d25c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -165,26 +165,9 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // Reset cursor to write new metricPoint cursor = this.metricPointValueIndex; - // Casting to ulong is ok here as the bit representation for long versus ulong will be the same - // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) - var sum = (ulong)metricPoint.GetSumLong(); + var sum = metricPoint.GetSumLong(); - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_int, sum); - - var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_start_time_unix_nano, startTime); - - var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_time_unix_nano, endTime); - - SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.NumberDataPoint_attributes); - - // TODO: exemplars. - - var metricPointStartPosition = this.metricPointTagAndLengthIndex; - - // Write numberdatapoint {Repeated field} - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.Sum_data_points, WireType.LEN); + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Sum_data_points, metricPoint, sum); // Finish writing current batch this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); @@ -223,22 +206,39 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var sum = metricPoint.GetSumDouble(); - ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_double, sum); + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Sum_data_points, metricPoint, sum); - var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_start_time_unix_nano, startTime); + // Finish writing current batch + this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); - var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_time_unix_nano, endTime); + // Send metricPoint + this.SendMetricPoint(buffer, ref cursor); + } + catch + { + // TODO: log exception. + } + } - SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.NumberDataPoint_attributes); + break; + } - // TODO: exemplars. + case MetricType.LongGauge: + { + cursor = this.instrumentValueIndex; - var metricPointStartPosition = this.metricPointTagAndLengthIndex; + this.metricPointTagAndLengthIndex = cursor; + this.metricPointValueIndex = cursor + TagAndLengthSize; + foreach (var metricPoint in metric.GetMetricPoints()) + { + try + { + // Reset cursor to write new metricPoint + cursor = this.metricPointValueIndex; - // Write numberdatapoint {Repeated field} - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.Sum_data_points, WireType.LEN); + var lastValue = metricPoint.GetGaugeLastValueLong(); + + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Gauge_data_points, metricPoint, lastValue); // Finish writing current batch this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); @@ -255,15 +255,35 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) break; } - case MetricType.LongGauge: - { - // TODO - break; - } - case MetricType.DoubleGauge: { - // TODO + cursor = this.instrumentValueIndex; + + this.metricPointTagAndLengthIndex = cursor; + this.metricPointValueIndex = cursor + TagAndLengthSize; + foreach (var metricPoint in metric.GetMetricPoints()) + { + try + { + // Reset cursor to write new metricPoint + cursor = this.metricPointValueIndex; + + var lastValue = metricPoint.GetGaugeLastValueDouble(); + + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Gauge_data_points, metricPoint, lastValue); + + // Finish writing current batch + this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); + + // Send metricPoint + this.SendMetricPoint(buffer, ref cursor); + } + catch + { + // TODO: log exception. + } + } + break; } @@ -318,7 +338,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var metricPointStartPosition = this.metricPointTagAndLengthIndex; - // Write numberdatapoint {Repeated field} + // Write histogramdatapoint {Repeated field} ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.Histogram_data_points, WireType.LEN); // Finish writing current batch @@ -329,6 +349,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) } catch { + // TODO: log exception. } } @@ -343,6 +364,35 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) } } + private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNumber, MetricPoint metricPoint, T value) + { + if (typeof(T) == typeof(long)) + { + // Casting to ulong is ok here as the bit representation for long versus ulong will be the same + // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_int, (ulong)(long)(object)value); + } + else if (typeof(T) == typeof(double)) + { + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_double, (double)(object)value); + } + + var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_start_time_unix_nano, startTime); + + var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_time_unix_nano, endTime); + + SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.NumberDataPoint_attributes); + + // TODO: exemplars. + + var metricPointStartPosition = this.metricPointTagAndLengthIndex; + + // Write numberdatapoint {Repeated field} + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, fieldNumber, WireType.LEN); + } + private void WriteIndividualMessageTagsAndLength(byte[] buffer, ref int cursor, MetricType metricType) { var instrumentIndex = this.instrumentTagAndLengthIndex; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 125b905bc5..101c8b67dc 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -563,7 +563,7 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) .AddReader(inMemoryReader) - .Build(); + .Build(); var histogram = meter.CreateHistogram("TestHistogram"); @@ -666,6 +666,231 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) } } + [Theory] + [InlineData("longGauge", 123L, null)] + [InlineData("doubleGauge", null, 123.45)] + [InlineData("longGauge", -123L, null)] + [InlineData("doubleGauge", null, -123.45)] + public void GaugeSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue) + { + using var meter = new Meter(nameof(this.GaugeSerializationSingleMetricPoint), "0.0.1"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() + .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(resourceBuilder) + .AddMeter(nameof(this.GaugeSerializationSingleMetricPoint)) + .AddReader(inMemoryReader) + .Build(); + + if (longValue.HasValue) + { + meter.CreateObservableGauge( + instrumentName, + () => new List>() + { + new(longValue.Value, new("tag1", "value1"), new("tag2", "value2")), + }); + } + else + { + meter.CreateObservableGauge( + instrumentName, + () => new List>() + { + new(doubleValue.Value, new("tag1", "value1"), new("tag2", "value2")), + }); + } + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Single(testTransport.ExportedItems); + + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[0]); + + Assert.Single(request.ResourceMetrics); + + Assert.NotNull(request.ResourceMetrics[0].Resource); + + AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal(instrumentName, metric.Name); + + Assert.NotNull(metric.Gauge); + + Assert.Single(metric.Gauge.DataPoints); + + var dataPoint = metric.Gauge.DataPoints[0]; + + if (longValue.HasValue) + { + Assert.Equal(longValue.Value, dataPoint.AsInt); + } + else + { + Assert.Equal(doubleValue.Value, dataPoint.AsDouble); + } + + // Assert time + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + } + + [Theory] + [InlineData("longGauge", new long[] { 10, 20, 30 }, null)] + [InlineData("longGauge", new long[] { -10, 2, -30 }, null)] + [InlineData("doubleGauge", null, new double[] { 10.20, 2, 30.65 })] + [InlineData("doubleGauge", null, new double[] { -10.20, 2, -30.65 })] + public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] longValues, double[] doubleValues) + { + using var meter = new Meter(nameof(this.GaugeSerializationMultipleMetricPoints), "0.0.1"); + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(nameof(this.GaugeSerializationMultipleMetricPoints)) + .AddReader(inMemoryReader) + .Build(); + + int expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; + TagList[] tags = new TagList[expectedMetricPoints]; + + for (int i = 0; i < tags.Length; i++) + { + for (int j = 1; j <= (i + 1); j++) + { + tags[i].Add(new("tag" + j, "value" + j)); + } + } + + if (longValues != null) + { + var counter = meter.CreateCounter(instrumentName); + + meter.CreateObservableGauge( + instrumentName, + () => + { + List> list = new List>(); + for (int i = 0; i < longValues.Length; i++) + { + list.Add(new(longValues[i], tags[i])); + } + + return list; + }); + } + else + { + meter.CreateObservableGauge( + instrumentName, + () => + { + List> list = new List>(); + for (int i = 0; i < doubleValues.Length; i++) + { + list.Add(new(doubleValues[i], tags[i])); + } + + return list; + }); + } + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Equal(expectedMetricPoints, testTransport.ExportedItems.Count); + + // For asserting time + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + + for (int i = 0; i < expectedMetricPoints; i++) + { + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[i]); + + Assert.Single(request.ResourceMetrics); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal(instrumentName, metric.Name); + + Assert.NotNull(metric.Gauge); + + Assert.Single(metric.Gauge.DataPoints); + + var dataPoint = metric.Gauge.DataPoints[0]; + + if (longValues != null) + { + Assert.Equal(longValues[i], dataPoint.AsInt); + } + else + { + Assert.Equal(doubleValues[i], dataPoint.AsDouble); + } + + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + AssertOtlpAttributes(tags[i], dataPoint.Attributes); + } + } + internal static void AssertOtlpAttributes( IEnumerable> expected, RepeatedField actual) From 18d616d0faa45aa92732dce9c5e7016ac329bfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 3 Apr 2024 19:52:55 +0200 Subject: [PATCH 0999/1499] Bump OpenTelemetry to 1.8.0 (#1635) --- build/Common.props | 4 ++-- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Extensions/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 6 ++---- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 6 +++--- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 2 ++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 2 ++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 2 ++ .../CHANGELOG.md | 2 ++ src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 2 ++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 2 ++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 ++-- 29 files changed, 67 insertions(+), 27 deletions(-) diff --git a/build/Common.props b/build/Common.props index c2daf1cef8..7fb650cad6 100644 --- a/build/Common.props +++ b/build/Common.props @@ -36,8 +36,8 @@ [4.2.2,5.0) [3.3.4] [8.0.0,9.0) - [1.7.0,2.0) - [1.7.0-rc.1] + [1.8.0,2.0) + [1.8.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index efa145b755..9ec3ce8421 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,6 +6,9 @@ is disposed. ([#1537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1537)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 1.7.0 Released 2023-Dec-11 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 3912bad5a3..c8e51b26d7 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.0.0-alpha.3 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 8e227d4ed6..cea99f2b9d 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index ae8f6ce8cf..c0cb3f6bfb 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.6.0 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 068b3880b8..a1b05e99c8 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 1.0.0-beta.5 Released 2024-Feb-15 diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index b56695232f..93e9b54b7c 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 6493396250..9f05100c20 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -5,8 +5,8 @@ * Add LogToActivityEventConversionOptions.Filter callback ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 020c8f7943..ae8660236e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -4,6 +4,8 @@ * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.7.0-beta.2 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index e74fc26843..bf4120624c 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 3b17d1abf3..e9f9242c3a 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * Span status is set based on [semantic convention for client spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status). ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) * `ActivitySource.Version` is set to NuGet package version. diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index eadf4bcdf5..75da20c91e 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 1.0.0-beta.10 Released 2024-Feb-07 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index aa901d7827..0bf1e9130a 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update `OpenTelemetry.Api` to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 928c9793fc..c82d672bcf 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -4,12 +4,10 @@ * Make the context propagation extraction case insensitive. ([#483](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/483)) -* Update OpenTelemetry.Api to 1.6.0. - ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) * Update minimal supported version of `Google.Protobuf` to `3.15.0`. ([#1456](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1456)) -* Update `OpenTelemetry.Api` to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 5712291ad5..78e9b2aa36 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,9 +2,9 @@ ## Unreleased -* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.7.0`. - * Update `OpenTelemetry.Api` to `1.7.0`. - ([#1508](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1508)) +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.0`. + * Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 61f7cae216..4ffd5330c9 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -4,6 +4,8 @@ * `ActivitySource.Version` and `Meter.Version` are set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Updated OpenTelemetry SDK to 1.8.0. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.0.0-rc.4 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 475b4308f0..cca7b40369 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -4,6 +4,8 @@ * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 0.5.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 56cff01e61..b9d9aac68c 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -4,6 +4,8 @@ * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 2fe7c93aa1..02a18d2c88 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -4,6 +4,8 @@ * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api` to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.7.0 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 2b24bf8240..b200adb6ff 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 1.0.0-rc9.13 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 7bc1c844e2..6cb9e4a45b 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -4,6 +4,8 @@ * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.0.0-rc.15 diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md index 154f82e53f..a58aa4c877 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## Unreleased + ## 1.0.0 Released 2023-Aug-28 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index 82ad697131..b3e0ded97e 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -7,6 +7,8 @@ ([#1552](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1552)) * Implement support for `cloud.resource_id` attribute in AWS ECS detector. ([#1576](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1576)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 1.4.0-beta.1 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 56b0d0cd62..a201aacdc8 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 1.0.0-beta.5 Released 2024-Feb-05 diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index bd60feed2b..94adcc640f 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 1.0.0-beta.6 Released 2024-Feb-07 diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index 8df506a5ae..e3fca2df82 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 0.1.0-alpha.2 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index a186213b41..d15330a6ee 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -4,6 +4,8 @@ * Added `process.owner` attribute. ([#1608](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1608)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) ## 0.1.0-alpha.2 diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md index 6d5a78c1e5..fd789011b1 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + ## 0.1.0-alpha.2 Released 2024-Jan-03 diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 0d912d6711..6ef51f3a3a 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -8,8 +8,8 @@ Initial release of `OpenTelemetry.Sampler.AWS`. ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091), [#1124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1124)) -* Update OpenTelemetry SDK version to `1.7.0`. - ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) +* Update OpenTelemetry SDK version to `1.8.0`. + ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * Make OpenTelemetry.Sampler.AWS native AoT compatible. ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) From 76d9844b5b941d6eb2b527dc01e06a84e85f2fd7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 4 Apr 2024 16:04:08 -0700 Subject: [PATCH 1000/1499] Exporter.Geneva][otlp protobuf] Add benchmarks (#1637) --- .../Exporter/MetricExporterBenchmarks.cs | 140 ++++++++++++++---- 1 file changed, 115 insertions(+), 25 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 0a83a5b527..1184d4ae0d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -9,33 +9,44 @@ using BenchmarkDotNet.Attributes; using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Metrics; +using OpenTelemetry.Resources; /* -BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) -Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores -.NET SDK 8.0.100 - [Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 - DefaultJob : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2 - - -| Method | Mean | Error | StdDev | Allocated | -|--------------------------------------------------------- |----------:|----------:|----------:|----------:| -| InstrumentWithNoListener3Dimensions | 23.83 ns | 0.080 ns | 0.075 ns | - | -| InstrumentWithNoListener4Dimensions | 56.71 ns | 0.730 ns | 0.647 ns | - | -| InstrumentWithWithListener3Dimensions | 24.46 ns | 0.257 ns | 0.215 ns | - | -| InstrumentWithWithListener4Dimensions | 59.02 ns | 0.501 ns | 0.444 ns | - | -| InstrumentWithWithDummyReader3Dimensions | 139.70 ns | 1.189 ns | 1.113 ns | - | -| InstrumentWithWithDummyReader4Dimensions | 184.76 ns | 2.012 ns | 1.680 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 135.76 ns | 0.995 ns | 0.831 ns | - | -| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 193.14 ns | 1.507 ns | 1.336 ns | - | -| SerializeCounterMetricItemWith3Dimensions | 165.27 ns | 1.000 ns | 0.887 ns | - | -| SerializeCounterMetricItemWith4Dimensions | 191.13 ns | 1.201 ns | 1.003 ns | - | -| ExportCounterMetricItemWith3Dimensions | 657.63 ns | 13.019 ns | 13.369 ns | - | -| ExportCounterMetricItemWith4Dimensions | 682.76 ns | 13.598 ns | 32.318 ns | - | -| SerializeHistogramMetricItemWith3Dimensions | 285.39 ns | 4.195 ns | 3.503 ns | - | -| SerializeHistogramMetricItemWith4Dimensions | 303.15 ns | 3.834 ns | 3.587 ns | - | -| ExportHistogramMetricItemWith3Dimensions | 803.90 ns | 14.753 ns | 36.465 ns | - | -| ExportHistogramMetricItemWith4Dimensions | 810.62 ns | 14.445 ns | 11.278 ns | - | +// * Summary * + +BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3296/23H2/2023Update/SunValley3) +13th Gen Intel Core i9-13900H, 1 CPU, 20 logical and 14 physical cores +.NET SDK 8.0.202 + [Host] : .NET 8.0.3 (8.0.324.11423), X64 RyuJIT AVX2 + DefaultJob : .NET 8.0.3 (8.0.324.11423), X64 RyuJIT AVX2 + + +| Method | Mean | Error | StdDev | Gen0 | Allocated | +|--------------------------------------------------------- |----------:|---------:|---------:|-------:|----------:| +| InstrumentWithNoListener3Dimensions | 13.22 ns | 0.035 ns | 0.033 ns | - | - | +| InstrumentWithNoListener4Dimensions | 31.12 ns | 0.386 ns | 0.361 ns | - | - | +| InstrumentWithWithListener3Dimensions | 13.69 ns | 0.036 ns | 0.034 ns | - | - | +| InstrumentWithWithListener4Dimensions | 30.90 ns | 0.276 ns | 0.258 ns | - | - | +| InstrumentWithWithDummyReader3Dimensions | 66.19 ns | 0.473 ns | 0.442 ns | - | - | +| InstrumentWithWithDummyReader4Dimensions | 94.12 ns | 1.274 ns | 1.191 ns | - | - | +| InstrumentWithWithGenevaCounterMetricExporter3Dimensions | 68.57 ns | 0.489 ns | 0.457 ns | - | - | +| InstrumentWithWithGenevaCounterMetricExporter4Dimensions | 94.61 ns | 0.672 ns | 0.595 ns | - | - | +| SerializeCounterMetricItemWith3Dimensions | 84.15 ns | 0.660 ns | 0.585 ns | - | - | +| SerializeCounterMetricItemWith4Dimensions | 94.97 ns | 1.129 ns | 1.056 ns | - | - | +| ExportCounterMetricItemWith3Dimensions | 236.62 ns | 2.071 ns | 1.836 ns | - | - | +| ExportCounterMetricItemWith4Dimensions | 254.66 ns | 2.884 ns | 2.697 ns | - | - | +| SerializeHistogramMetricItemWith3Dimensions | 142.76 ns | 2.709 ns | 2.534 ns | - | - | +| SerializeHistogramMetricItemWith4Dimensions | 156.16 ns | 2.884 ns | 2.698 ns | - | - | +| ExportHistogramMetricItemWith3Dimensions | 329.75 ns | 3.602 ns | 3.369 ns | - | - | +| ExportHistogramMetricItemWith4Dimensions | 325.98 ns | 6.001 ns | 5.614 ns | - | - | +| SerializeCounterMetricItemWith3Dimensions_Otlp | 227.27 ns | 3.010 ns | 2.815 ns | 0.0038 | 48 B | +| SerializeCounterMetricItemWith4Dimensions_Otlp | 260.18 ns | 5.151 ns | 6.131 ns | 0.0038 | 48 B | +| ExportCounterMetricItemWith3Dimensions_Otlp | 407.64 ns | 4.364 ns | 3.868 ns | 0.0038 | 48 B | +| ExportCounterMetricItemWith4Dimensions_Otlp | 435.45 ns | 8.376 ns | 8.226 ns | 0.0038 | 48 B | +| SerializeHistogramMetricItemWith3Dimensions_Otlp | 261.77 ns | 5.108 ns | 5.883 ns | 0.0038 | 48 B | +| SerializeHistogramMetricItemWith4Dimensions_Otlp | 285.66 ns | 5.285 ns | 5.191 ns | 0.0038 | 48 B | +| ExportHistogramMetricItemWith3Dimensions_Otlp | 489.10 ns | 9.641 ns | 9.901 ns | 0.0038 | 48 B | +| ExportHistogramMetricItemWith4Dimensions_Otlp | 513.72 ns | 7.481 ns | 6.998 ns | 0.0038 | 48 B | */ namespace OpenTelemetry.Exporter.Geneva.Benchmark; @@ -81,6 +92,10 @@ public class MetricExporterBenchmarks private MeterProvider meterProviderForHistogramBatchWith3Dimensions; private MeterProvider meterProviderForHistogramBatchWith4Dimensions; private TlvMetricExporter tlvMetricsExporter; + private OtlpProtobufMetricExporter otlpProtobufMetricExporter; + private OtlpProtobufSerializer otlpProtobufSerializer; + private Resource resource; + private byte[] buffer; private ThreadLocal random = new ThreadLocal(() => new Random()); private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported @@ -98,6 +113,15 @@ public void Setup() var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); this.tlvMetricsExporter = new TlvMetricExporter(connectionStringBuilder, exporterOptions.PrepopulatedMetricDimensions); + // Using test transport here with noop to benchmark just the serialization part. + this.otlpProtobufSerializer = new OtlpProtobufSerializer(new TestTransport()); + + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() + .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + this.resource = resourceBuilder.Build(); + this.otlpProtobufMetricExporter = new OtlpProtobufMetricExporter(() => { return this.resource; }); + this.buffer = new byte[GenevaMetricExporter.BufferSize]; + this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); this.counterMetricPointWith4Dimensions = this.GenerateCounterMetricItemWith4Dimensions(out this.counterMetricDataWith4Dimensions); @@ -448,6 +472,7 @@ public void Cleanup() this.meterProviderForHistogramBatchWith3Dimensions?.Dispose(); this.meterProviderForHistogramBatchWith4Dimensions?.Dispose(); this.tlvMetricsExporter?.Dispose(); + this.otlpProtobufMetricExporter?.Dispose(); } [Benchmark] @@ -640,6 +665,54 @@ public void ExportHistogramMetricItemWith4Dimensions() this.tlvMetricsExporter.Export(this.histogramMetricBatchWith4Dimensions); } + [Benchmark] + public void SerializeCounterMetricItemWith3Dimensions_Otlp() + { + this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.counterMetricBatchWith3Dimensions); + } + + [Benchmark] + public void SerializeCounterMetricItemWith4Dimensions_Otlp() + { + this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.counterMetricBatchWith4Dimensions); + } + + [Benchmark] + public void ExportCounterMetricItemWith3Dimensions_Otlp() + { + this.otlpProtobufMetricExporter.Export(this.counterMetricBatchWith3Dimensions); + } + + [Benchmark] + public void ExportCounterMetricItemWith4Dimensions_Otlp() + { + this.otlpProtobufMetricExporter.Export(this.counterMetricBatchWith4Dimensions); + } + + [Benchmark] + public void SerializeHistogramMetricItemWith3Dimensions_Otlp() + { + this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.histogramMetricBatchWith3Dimensions); + } + + [Benchmark] + public void SerializeHistogramMetricItemWith4Dimensions_Otlp() + { + this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.histogramMetricBatchWith4Dimensions); + } + + [Benchmark] + public void ExportHistogramMetricItemWith3Dimensions_Otlp() + { + this.otlpProtobufMetricExporter.Export(this.histogramMetricBatchWith3Dimensions); + } + + [Benchmark] + public void ExportHistogramMetricItemWith4Dimensions_Otlp() + { + this.otlpProtobufMetricExporter.Export(this.histogramMetricBatchWith4Dimensions); + } + private class DummyReader : BaseExportingMetricReader { public DummyReader(BaseExporter exporter) @@ -666,4 +739,21 @@ public override ExportResult Export(in Batch batch) return ExportResult.Success; } } + + private class TestTransport : IMetricDataTransport + { + public void SendOtlpProtobufEvent(byte[] body, int size) + { + // Drop + } + + public void Send(MetricEventType eventType, byte[] body, int size) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + } + } } From 0077901c858bc46e2b7e4e9a33c26949b06939ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 5 Apr 2024 06:50:08 +0200 Subject: [PATCH 1001/1499] Releases with OTel 1.8.0 (#1636) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 8 ++++++-- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md | 4 ++++ src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 4 ++++ 13 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index ae8660236e..b1c1f42a50 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0-beta.1 + +Released 2024-Apr-05 + * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Update `OpenTelemetry.Api` to `1.8.0`. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 5d5be1fa39..679198547b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0-beta.1 + +Released 2024-Apr-05 + * **Breaking Change**: Renamed `AspNetInstrumentationOptions` to `AspNetTraceInstrumentationOptions`. ([#1604](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1604)) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 75da20c91e..46907d6b65 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.11 + +Released 2024-Apr-05 + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index cca7b40369..dd8fbcffd9 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.5.0-beta.5 + +Released 2024-Apr-05 + * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Update `OpenTelemetry.Api` to `1.8.0`. diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index b9d9aac68c..b0f15815a5 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2024-Apr-05 + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Update `OpenTelemetry.Api` to `1.8.0`. diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 02a18d2c88..3e6d864f53 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0 + +Released 2024-Apr-05 + * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Update `OpenTelemetry.Api` to `1.8.0`. diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index b200adb6ff..74c6012b96 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,8 +2,14 @@ ## Unreleased +## 1.0.0-rc9.14 + +Released 2024-Apr-05 + * Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* `ActivitySource.Version` is set to NuGet package version. + ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-rc9.13 @@ -11,8 +17,6 @@ Released 2024-Jan-03 * Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) -* `ActivitySource.Version` is set to NuGet package version. - ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) ## 1.0.0-rc9.12 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 6cb9e4a45b..7901c76c35 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.16 + +Released 2024-Apr-05 + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Update OpenTelemetry SDK version to `1.8.0`. diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index a201aacdc8..6a74ed5007 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.6 + +Released 2024-Apr-05 + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 94adcc640f..1010a7b8ee 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.7 + +Released 2024-Apr-05 + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index e3fca2df82..a5fbae79df 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.3 + +Released 2024-Apr-05 + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index d15330a6ee..2c3d08dcfc 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.3 + +Released 2024-Apr-05 + * Added `process.owner` attribute. ([#1608](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1608)) * Update OpenTelemetry SDK version to `1.8.0`. diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md index fd789011b1..031ff73234 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.3 + +Released 2024-Apr-05 + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) From 295200e1d39b446b7e795851ace253634a992ba4 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 8 Apr 2024 12:55:15 -0700 Subject: [PATCH 1002/1499] Exporter.Geneva][OTLP protobuf] Add tests for different data types (#1639) --- .../OtlpProtobufMetricExporterTests.cs | 83 ++++++++++++++++--- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 101c8b67dc..1f7cb30b92 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -18,6 +18,50 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; public class OtlpProtobufMetricExporterTests { + public TagList TagList; + + public OtlpProtobufMetricExporterTests() + { + this.TagList = default; + + bool boolValue = true; + double doubleValue = 23.45; + int intValue = 29; + long longValue = 345; + double negativeDoubleValue = -23.45; + int negativeIntValue = -29; + long negativeLongValue = -97; + sbyte negativeSbyteValue = sbyte.MinValue; + short negativeShortValue = -12; + sbyte sByteValue = sbyte.MaxValue; + short shortValue = short.MaxValue; + string stringValueAscii = "TestString"; + string stringValueMixAsciiAndUnicode = "\u0418TestString"; + string stringValueUnicode = "\u0418"; + uint uintValue = uint.MaxValue; + ulong ulongValue = 1234; + ushort ushortValue = ushort.MaxValue; + + // Keep the keys in sorted order, Sdk outputs them in sorted order. + this.TagList.Add(new("boolKey", boolValue)); + this.TagList.Add(new("doubleKey", doubleValue)); + this.TagList.Add(new("intKey", intValue)); + this.TagList.Add(new("longKey", longValue)); + this.TagList.Add(new("negativeDoubleKey", negativeDoubleValue)); + this.TagList.Add(new("negativeIntKey", negativeIntValue)); + this.TagList.Add(new("negativeLongKey", negativeLongValue)); + this.TagList.Add(new("negativeSbyteKey", negativeSbyteValue)); + this.TagList.Add(new("negativeShortKey", negativeShortValue)); + this.TagList.Add(new("sByteKey", sByteValue)); + this.TagList.Add(new("shortKey", shortValue)); + this.TagList.Add(new("stringValueAsciiKey", stringValueAscii)); + this.TagList.Add(new("stringValueMixAsciiAndUnicodeKey", stringValueMixAsciiAndUnicode)); + this.TagList.Add(new("stringValueUnicodeKey", stringValueUnicode)); + this.TagList.Add(new("uintKey", uintValue)); + this.TagList.Add(new("ulongKey", ulongValue)); + this.TagList.Add(new("ushortKey", ushortValue)); + } + [Theory] [InlineData("longcounter", 123L, null)] [InlineData("doublecounter", null, 123.45)] @@ -44,12 +88,12 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l if (longValue != null) { var counter = meter.CreateCounter(instrumentName); - counter.Add(longValue.Value, new("tag1", "value1"), new("tag2", "value2")); + counter.Add(longValue.Value, this.TagList); } else { var counter = meter.CreateCounter(instrumentName); - counter.Add(doubleValue.Value, new("tag1", "value1"), new("tag2", "value2")); + counter.Add(doubleValue.Value, this.TagList); } meterProvider.ForceFlush(); @@ -113,7 +157,7 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } [Theory] @@ -255,12 +299,12 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l if (longValue != null) { var counter = meter.CreateUpDownCounter(instrumentName); - counter.Add(longValue.Value, new("tag1", "value1"), new("tag2", "value2")); + counter.Add(longValue.Value, this.TagList); } else { var counter = meter.CreateUpDownCounter(instrumentName); - counter.Add(doubleValue.Value, new("tag1", "value1"), new("tag2", "value2")); + counter.Add(doubleValue.Value, this.TagList); } meterProvider.ForceFlush(); @@ -324,7 +368,7 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } [Theory] @@ -462,7 +506,7 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue) .Build(); var histogram = meter.CreateHistogram("TestHistogram"); - histogram.Record(doubleValue, new("tag1", "value1"), new("tag2", "value2")); + histogram.Record(doubleValue, this.TagList); meterProvider.ForceFlush(); @@ -542,7 +586,7 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue) Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } [Theory] @@ -695,7 +739,7 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon instrumentName, () => new List>() { - new(longValue.Value, new("tag1", "value1"), new("tag2", "value2")), + new(longValue.Value, this.TagList), }); } else @@ -704,7 +748,7 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon instrumentName, () => new List>() { - new(doubleValue.Value, new("tag1", "value1"), new("tag2", "value2")), + new(doubleValue.Value, this.TagList), }); } @@ -765,7 +809,7 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes([new("tag1", "value1"), new("tag2", "value2")], dataPoint.Attributes); + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } [Theory] @@ -902,8 +946,6 @@ internal static void AssertOtlpAttributes( { var current = expectedAttributes[i].Value; - // This is a side effect of writing data in buffer from end to beginning - // Elements are in reverse order. Assert.Equal(expectedAttributes[i].Key, actual[i].Key); Assert.Equal(expectedAttributes[i].Key, actual[i].Key); AssertOtlpAttributeValue(current, actual[i].Value); @@ -932,6 +974,21 @@ private static void AssertOtlpAttributeValue(object expected, OtlpCommon.AnyValu case int i: Assert.Equal(i, actual.IntValue); break; + case uint u: + Assert.Equal(u, actual.IntValue); + break; + case ushort us: + Assert.Equal(us, actual.IntValue); + break; + case short s: + Assert.Equal(s, actual.IntValue); + break; + case ulong ul: + Assert.Equal(ul, (ulong)actual.IntValue); + break; + case sbyte sb: + Assert.Equal(sb, actual.IntValue); + break; default: Assert.Equal(expected.ToString(), actual.StringValue); break; From 6734f72dc0286f2077ebbc86c71fc0ad068a2f62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 16:46:22 -0700 Subject: [PATCH 1003/1499] Bump DavidAnson/markdownlint-cli2-action from 15.0.0 to 16.0.0 (#1642) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/markdownlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 864a8a6c7a..2ae611dae5 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -12,7 +12,7 @@ jobs: uses: actions/checkout@v4 - name: run markdownlint - uses: DavidAnson/markdownlint-cli2-action@v15.0.0 + uses: DavidAnson/markdownlint-cli2-action@v16.0.0 with: globs: | **/*.md From b2d54afce7344cfe12d4de0b44ea2c90783bab6d Mon Sep 17 00:00:00 2001 From: Shyam Saraswati Date: Fri, 12 Apr 2024 14:42:41 +1000 Subject: [PATCH 1004/1499] Request to release OpenTelemetry.Instrumentation.AWS package (#1645) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 14192e241a..d1433f2e15 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.4 + +Released 2024-Apr-12 + * BREAKING: Switched AWSServiceName tag to use ServiceId instead of ServiceName ([#1572](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1572)) * `ActivitySource.Version` is set to NuGet package version. From 44c8576ef1290d9fbb6fbbdc973ae1b344afb4c2 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Fri, 12 Apr 2024 05:50:45 -0400 Subject: [PATCH 1005/1499] [ResourceDetector.Host] Add host.id for non-containerized systems (#1631) --- .../CHANGELOG.md | 4 + .../HostDetector.cs | 164 +++++++++++++++++- .../HostSemanticConventions.cs | 1 + .../README.md | 2 +- .../HostDetectorTests.cs | 105 ++++++++++- ...emetry.ResourceDetectors.Host.Tests.csproj | 9 + .../Samples/etc_machineid | 1 + .../Samples/etc_var_dbus_machineid | 1 + 8 files changed, 283 insertions(+), 4 deletions(-) create mode 100644 test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_machineid create mode 100644 test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_var_dbus_machineid diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index a5fbae79df..bb4526451f 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Adds support for `host.id` resource attribute on non-containerized systems. +`host.id` will be set per [semantic convention rules](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/host.md) + ([#1631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1631)) + ## 0.1.0-alpha.3 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs b/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs index 146c6c6a76..705be6ee0a 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs @@ -3,6 +3,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using Microsoft.Win32; using OpenTelemetry.Resources; namespace OpenTelemetry.ResourceDetectors.Host; @@ -12,6 +16,40 @@ namespace OpenTelemetry.ResourceDetectors.Host; /// public sealed class HostDetector : IResourceDetector { + private const string ETCMACHINEID = "/etc/machine-id"; + private const string ETCVARDBUSMACHINEID = "/var/lib/dbus/machine-id"; + private readonly PlatformID platformId; + private readonly Func> getFilePaths; + private readonly Func getMacOsMachineId; + private readonly Func getWindowsMachineId; + + /// + /// Initializes a new instance of the class. + /// + public HostDetector() + : this( + Environment.OSVersion.Platform, + GetFilePaths, + GetMachineIdMacOs, + GetMachineIdWindows) + { + } + + /// + /// Initializes a new instance of the class for testing. + /// + /// Target platform ID. + /// Function to get Linux file paths to probe. + /// Function to get MacOS machine ID. + /// Function to get Windows machine ID. + internal HostDetector(PlatformID platformId, Func> getFilePaths, Func getMacOsMachineId, Func getWindowsMachineId) + { + this.platformId = platformId; + this.getFilePaths = getFilePaths ?? throw new ArgumentNullException(nameof(getFilePaths)); + this.getMacOsMachineId = getMacOsMachineId ?? throw new ArgumentNullException(nameof(getMacOsMachineId)); + this.getWindowsMachineId = getWindowsMachineId ?? throw new ArgumentNullException(nameof(getWindowsMachineId)); + } + /// /// Detects the resource attributes from host. /// @@ -20,10 +58,18 @@ public Resource Detect() { try { - return new Resource(new List>(1) + var attributes = new List>(2) { new(HostSemanticConventions.AttributeHostName, Environment.MachineName), - }); + }; + var machineId = this.GetMachineId(); + + if (machineId != null && !string.IsNullOrEmpty(machineId)) + { + attributes.Add(new(HostSemanticConventions.AttributeHostId, machineId)); + } + + return new Resource(attributes); } catch (InvalidOperationException ex) { @@ -33,4 +79,118 @@ public Resource Detect() return Resource.Empty; } + + internal static string? ParseMacOsOutput(string? output) + { + if (output == null || string.IsNullOrEmpty(output)) + { + return null; + } + + var lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + + foreach (var line in lines) + { +#if NETFRAMEWORK + if (line.IndexOf("IOPlatformUUID", StringComparison.OrdinalIgnoreCase) >= 0) +#else + if (line.Contains("IOPlatformUUID", StringComparison.OrdinalIgnoreCase)) +#endif + { + var parts = line.Split('"'); + + if (parts.Length > 3) + { + return parts[3]; + } + } + } + + return null; + } + + private static IEnumerable GetFilePaths() + { + yield return ETCMACHINEID; + yield return ETCVARDBUSMACHINEID; + } + + private static string? GetMachineIdMacOs() + { + try + { + var startInfo = new ProcessStartInfo + { + FileName = "sh", + Arguments = "ioreg -rd1 -c IOPlatformExpertDevice", + UseShellExecute = false, + CreateNoWindow = true, + RedirectStandardOutput = true, + }; + + var sb = new StringBuilder(); + using var process = Process.Start(startInfo); + process?.WaitForExit(); + sb.Append(process?.StandardOutput.ReadToEnd()); + return sb.ToString(); + } + catch (Exception ex) + { + HostResourceEventSource.Log.ResourceAttributesExtractException(nameof(HostDetector), ex); + } + + return null; + } + +#pragma warning disable CA1416 + // stylecop wants this protected by System.OperatingSystem.IsWindows + // this type only exists in .NET 5+ + private static string? GetMachineIdWindows() + { + try + { + using var subKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography", false); + return subKey?.GetValue("MachineGuid") as string ?? null; + } + catch (Exception ex) + { + HostResourceEventSource.Log.ResourceAttributesExtractException(nameof(HostDetector), ex); + } + + return null; + } +#pragma warning restore CA1416 + + private string? GetMachineId() + { + return this.platformId switch + { + PlatformID.Unix => this.GetMachineIdLinux(), + PlatformID.MacOSX => ParseMacOsOutput(this.getMacOsMachineId()), + PlatformID.Win32NT => this.getWindowsMachineId(), + _ => null, + }; + } + + private string? GetMachineIdLinux() + { + var paths = this.getFilePaths(); + + foreach (var path in paths) + { + if (File.Exists(path)) + { + try + { + return File.ReadAllText(path).Trim(); + } + catch (Exception ex) + { + HostResourceEventSource.Log.ResourceAttributesExtractException(nameof(HostDetector), ex); + } + } + } + + return null; + } } diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs b/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs index 18b2d01023..209cfb9808 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs +++ b/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs @@ -6,4 +6,5 @@ namespace OpenTelemetry.ResourceDetectors.Host; internal static class HostSemanticConventions { public const string AttributeHostName = "host.name"; + public const string AttributeHostId = "host.id"; } diff --git a/src/OpenTelemetry.ResourceDetectors.Host/README.md b/src/OpenTelemetry.ResourceDetectors.Host/README.md index f0eabc6496..11a1a04973 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/README.md @@ -36,7 +36,7 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() The resource detectors will record the following metadata based on where your application is running: -- **HostDetector**: `host.name`. +- **HostDetector**: `host.id` (when running on non-containerized systems), `host.name`. ## References diff --git a/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs b/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs index e6e494f6ab..16fdcec60b 100644 --- a/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.Host.Tests/HostDetectorTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System; +using System.Collections.Generic; using System.Linq; using OpenTelemetry.Resources; using Xunit; @@ -9,6 +11,38 @@ namespace OpenTelemetry.ResourceDetectors.Host.Tests; public class HostDetectorTests { + private const string MacOSMachineIdOutput = @"+-o J293AP + ""AAPL,phandle"" = <01000000> + ""serial-number"" = <432123465233514651303544000000000000000000000000000000$ + ""IOBusyInterest"" = ""IOCommand is not serializable"" + ""target-type"" = <""J293""> + ""platform-name"" = <743831303300000000000000000000000000000000000000000000$ + ""secure-root-prefix"" = <""md""> + ""name"" = <""device-tree""> + ""region-info"" = <4c4c2f41000000000000000000000000000000000000000000000000$ + ""manufacturer"" = <""Apple Inc.""> + ""compatible"" = <""J293AP"",""MacBookPro17,1"",""AppleARM""> + ""config-number"" = <000000000000000000000000000000000000000000000000000000$ + ""IOPlatformSerialNumber"" = ""A01BC3QFQ05D"" + ""regulatory-model-number"" = <41323333380000000000000000000000000000000000$ + ""time-stamp"" = <""Mon Jun 27 20:12:10 PDT 2022""> + ""clock-frequency"" = <00366e01> + ""model"" = <""MacBookPro17,1""> + ""mlb-serial-number"" = <432123413230363030455151384c4c314a0000000000000000$ + ""model-number"" = <4d59443832000000000000000000000000000000000000000000000$ + ""IONWInterrupts"" = ""IONWInterrupts"" + ""model-config"" = <""SUNWAY;MoPED=0x803914B08BE6C5AF0E6C990D7D8240DA4CAC2FF$ + ""device_type"" = <""bootrom""> + ""#size-cells"" = <02000000> + ""IOPlatformUUID"" = ""1AB2345C-03E4-57D4-A375-1234D48DE123"" + }"; + + private static readonly IEnumerable ETCMACHINEID = new[] { "Samples/etc_machineid" }; + private static readonly IEnumerable ETCVARDBUSMACHINEID = new[] { "Samples/etc_var_dbus_machineid" }; + [Fact] public void TestHostAttributes() { @@ -16,8 +50,77 @@ public void TestHostAttributes() var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); - Assert.Single(resourceAttributes); + Assert.Equal(2, resourceAttributes.Count); Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostName]); + Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); + } + + [Fact] + public void TestHostMachineIdLinux() + { + var combos = new[] + { + (Enumerable.Empty(), null), + (ETCMACHINEID, "etc_machineid"), + (ETCVARDBUSMACHINEID, "etc_var_dbus_machineid"), + (Enumerable.Concat(ETCMACHINEID, ETCVARDBUSMACHINEID), "etc_machineid"), + }; + + foreach (var (path, expected) in combos) + { + var detector = new HostDetector( + PlatformID.Unix, + () => path, + () => throw new Exception("should not be called"), + () => throw new Exception("should not be called")); + var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + + if (string.IsNullOrEmpty(expected)) + { + Assert.False(resourceAttributes.ContainsKey(HostSemanticConventions.AttributeHostId)); + } + else + { + Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); + Assert.Equal(expected, resourceAttributes[HostSemanticConventions.AttributeHostId]); + } + } + } + + [Fact] + public void TestHostMachineIdMacOs() + { + var detector = new HostDetector( + PlatformID.MacOSX, + () => Enumerable.Empty(), + () => MacOSMachineIdOutput, + () => throw new Exception("should not be called")); + var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); + Assert.Equal("1AB2345C-03E4-57D4-A375-1234D48DE123", resourceAttributes[HostSemanticConventions.AttributeHostId]); + } + + [Fact] + public void TestParseMacOsOutput() + { + var id = HostDetector.ParseMacOsOutput(MacOSMachineIdOutput); + Assert.Equal("1AB2345C-03E4-57D4-A375-1234D48DE123", id); + } + + [Fact] + public void TestHostMachineIdWindows() + { + var detector = new HostDetector( + PlatformID.Win32NT, + () => Enumerable.Empty(), + () => throw new Exception("should not be called"), + () => "windows-machine-id"); + var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); + Assert.Equal("windows-machine-id", resourceAttributes[HostSemanticConventions.AttributeHostId]); } } diff --git a/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj b/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj index 23db48b06d..eefd21a835 100644 --- a/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj +++ b/test/OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj @@ -11,4 +11,13 @@ + + + PreserveNewest + + + PreserveNewest + + + diff --git a/test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_machineid b/test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_machineid new file mode 100644 index 0000000000..033e610b97 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_machineid @@ -0,0 +1 @@ +etc_machineid diff --git a/test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_var_dbus_machineid b/test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_var_dbus_machineid new file mode 100644 index 0000000000..713c4b8b2a --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.Host.Tests/Samples/etc_var_dbus_machineid @@ -0,0 +1 @@ +etc_var_dbus_machineid From aae94e3bfbdf02171a3a3e631358b4170962080c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 12 Apr 2024 20:07:07 +0200 Subject: [PATCH 1006/1499] [Instrumentation.Process] Adjust metrics and attributes to Sem. Conv. 1.25.0 (#1643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Łach --- .../CHANGELOG.md | 7 +++++++ .../ProcessMetrics.cs | 12 ++++++------ src/OpenTelemetry.Instrumentation.Process/README.md | 10 +++++----- .../ProcessMetricsTests.cs | 12 ++++++------ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index dd8fbcffd9..e0e0b59e5e 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +* Following changes related to [Semantic Convention v1.25.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/system/process-metrics.md) + * `process.cpu.time` metric attribute renamed from `state` to `process.cpu.state`, + * Metric descriptions fixed for `process.memory.usage` and `process.memory.virtual`, + * Metric `process.threads` renamed to `process.thread.count` + (its unit changed from `{threads}` to `{thread}`). + ([#1643](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1643)) + ## 0.5.0-beta.5 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 9046a51fad..a597cbc9fe 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -27,7 +27,7 @@ static ProcessMetrics() return Diagnostics.Process.GetCurrentProcess().WorkingSet64; }, unit: "By", - description: "The amount of physical memory allocated for this process."); + description: "The amount of physical memory in use."); MeterInstance.CreateObservableUpDownCounter( "process.memory.virtual", @@ -36,7 +36,7 @@ static ProcessMetrics() return Diagnostics.Process.GetCurrentProcess().VirtualMemorySize64; }, unit: "By", - description: "The amount of committed virtual memory for this process."); + description: "The amount of committed virtual memory."); MeterInstance.CreateObservableCounter( "process.cpu.time", @@ -45,8 +45,8 @@ static ProcessMetrics() var process = Diagnostics.Process.GetCurrentProcess(); return new[] { - new Measurement(process.UserProcessorTime.TotalSeconds, new KeyValuePair("state", "user")), - new Measurement(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("state", "system")), + new Measurement(process.UserProcessorTime.TotalSeconds, new KeyValuePair("process.cpu.state", "user")), + new Measurement(process.PrivilegedProcessorTime.TotalSeconds, new KeyValuePair("process.cpu.state", "system")), }; }, unit: "s", @@ -62,12 +62,12 @@ static ProcessMetrics() description: "The number of processors (CPU cores) available to the current process."); MeterInstance.CreateObservableUpDownCounter( - "process.threads", + "process.thread.count", () => { return Diagnostics.Process.GetCurrentProcess().Threads.Count; }, - unit: "{threads}", + unit: "{thread}", description: "Process threads count."); } diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 4482da3983..2f390a4245 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -100,9 +100,9 @@ process. Total CPU seconds broken down by states. -| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | -|-------|-------------------|------------|------------------|------------------| -| `s` | ObservableCounter | `Double` | state | user, system | +| Units | Instrument Type | Value Type | Attribute Key(s) | Attribute Values | +|-------|-------------------|------------|-------------------|------------------| +| `s` | ObservableCounter | `Double` | process.cpu.state | user, system | The APIs used to retrieve the values are: @@ -130,13 +130,13 @@ and not part of the [Process Metrics Spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md) at this time. -### process.threads +### process.thread.count Process threads count. | Units | Instrument Type | Value Type | |------------|-------------------------|------------| -| `{threads}`| ObservableUpDownCounter | `Int32` | +| `{thread}` | ObservableUpDownCounter | `Int32` | The API used to retrieve the value is: diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index a0c829d5d3..c766a13ec2 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -83,11 +83,11 @@ public void CpuTimeMetricsAreCaptured() { Assert.NotNull(tag.Value); - if (tag.Key == "state" && tag.Value!.ToString() == "user") + if (tag.Key == "process.cpu.state" && tag.Value!.ToString() == "user") { userTimeCaptured = true; } - else if (tag.Key == "state" && tag.Value!.ToString() == "system") + else if (tag.Key == "process.cpu.state" && tag.Value!.ToString() == "system") { systemTimeCaptured = true; } @@ -133,7 +133,7 @@ public void ProcessMetricsAreCapturedWhenTasksOverlap() Task.WaitAll(tasks.ToArray()); - Assert.True(exportedItemsA.Count == 5); + Assert.Equal(5, exportedItemsA.Count); var physicalMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetricA); var virtualMemoryMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.memory.virtual"); @@ -142,10 +142,10 @@ public void ProcessMetricsAreCapturedWhenTasksOverlap() Assert.NotNull(cpuTimeMetricA); var processorCountMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.cpu.count"); Assert.NotNull(processorCountMetricA); - var threadMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.threads"); + var threadMetricA = exportedItemsA.FirstOrDefault(i => i.Name == "process.thread.count"); Assert.NotNull(threadMetricA); - Assert.True(exportedItemsB.Count == 5); + Assert.Equal(5, exportedItemsB.Count); var physicalMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.usage"); Assert.NotNull(physicalMemoryMetricB); var virtualMemoryMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.memory.virtual"); @@ -154,7 +154,7 @@ public void ProcessMetricsAreCapturedWhenTasksOverlap() Assert.NotNull(cpuTimeMetricB); var processorCountMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.cpu.count"); Assert.NotNull(processorCountMetricB); - var threadMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.threads"); + var threadMetricB = exportedItemsB.FirstOrDefault(i => i.Name == "process.thread.count"); Assert.NotNull(threadMetricB); } From bc2f02672304e22445be95bdd1a2d19ff09cd675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 12 Apr 2024 20:28:07 +0200 Subject: [PATCH 1007/1499] Sync Shared/AssemblyVersionExtensions with main repository (#1646) --- opentelemetry-dotnet-contrib.sln | 2 +- .../AWSTracingPipelineHandler.cs | 3 +- .../OpenTelemetry.Instrumentation.AWS.csproj | 2 +- .../AWSLambdaWrapper.cs | 2 +- ...Telemetry.Instrumentation.AWSLambda.csproj | 2 +- .../ActivityHelper.cs | 3 +- ...entation.AspNet.TelemetryHttpModule.csproj | 2 +- .../AspNetMetrics.cs | 6 ++- ...penTelemetry.Instrumentation.AspNet.csproj | 2 +- .../CassandraMeter.cs | 9 ++++- ...Telemetry.Instrumentation.Cassandra.csproj | 2 +- ...searchRequestPipelineDiagnosticListener.cs | 5 ++- ...Instrumentation.ElasticsearchClient.csproj | 2 +- .../EntityFrameworkDiagnosticListener.cs | 10 ++--- ...Instrumentation.EntityFrameworkCore.csproj | 2 +- .../EventCountersMetrics.cs | 8 +++- ...metry.Instrumentation.EventCounters.csproj | 2 +- .../GrpcCoreInstrumentation.cs | 10 ++++- ...nTelemetry.Instrumentation.GrpcCore.csproj | 2 +- .../Implementation/HangfireInstrumentation.cs | 10 ++++- ...nTelemetry.Instrumentation.Hangfire.csproj | 2 +- .../OwinInstrumentationActivitySource.cs | 6 ++- .../OwinInstrumentationMetrics.cs | 6 ++- .../OpenTelemetry.Instrumentation.Owin.csproj | 2 +- ...enTelemetry.Instrumentation.Process.csproj | 2 +- .../ProcessMetrics.cs | 6 ++- .../QuartzDiagnosticListener.cs | 5 ++- ...penTelemetry.Instrumentation.Quartz.csproj | 2 +- ...enTelemetry.Instrumentation.Runtime.csproj | 2 +- .../RuntimeMetrics.cs | 6 ++- ....Instrumentation.StackExchangeRedis.csproj | 2 +- ...kExchangeRedisConnectionInstrumentation.cs | 6 ++- .../WcfInstrumentationActivitySource.cs | 6 ++- .../OpenTelemetry.Instrumentation.Wcf.csproj | 2 +- src/Shared/AssemblyVersionExtensions.cs | 38 +++++++++++++++++++ src/Shared/SignalVersionHelper.cs | 14 ------- 36 files changed, 129 insertions(+), 64 deletions(-) create mode 100644 src/Shared/AssemblyVersionExtensions.cs delete mode 100644 src/Shared/SignalVersionHelper.cs diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7f3a0f099b..776f0dbc0c 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -271,6 +271,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8EEC-9E75-4FEA-AFCF-363DD33FF0B9}" ProjectSection(SolutionItems) = preProject src\Shared\ActivityInstrumentationHelper.cs = src\Shared\ActivityInstrumentationHelper.cs + src\Shared\AssemblyVersionExtensions.cs = src\Shared\AssemblyVersionExtensions.cs src\Shared\DiagnosticSourceListener.cs = src\Shared\DiagnosticSourceListener.cs src\Shared\DiagnosticSourceSubscriber.cs = src\Shared\DiagnosticSourceSubscriber.cs src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs @@ -283,7 +284,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\PropertyFetcher.AOT.cs = src\Shared\PropertyFetcher.AOT.cs src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs - src\Shared\SignalVersionHelper.cs = src\Shared\SignalVersionHelper.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs EndProjectSection diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 5f33b8e8b0..84cbc01490 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -8,6 +8,7 @@ using Amazon.Runtime.Internal; using Amazon.Util; using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation; @@ -23,7 +24,7 @@ internal sealed class AWSTracingPipelineHandler : PipelineHandler { internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; - private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName, typeof(AWSTracingPipelineHandler).Assembly.GetPackageVersion()); private readonly AWSClientInstrumentationOptions options; diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index c5b953d028..a3901a9267 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index ee244cf95e..11194d8e70 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -20,7 +20,7 @@ public static class AWSLambdaWrapper { internal const string ActivitySourceName = "OpenTelemetry.Instrumentation.AWSLambda"; - private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, typeof(AWSLambdaWrapper).Assembly.GetPackageVersion()); /// /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index fe7540cd53..9d02ff7d9a 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index ffc7a5996e..14b56663e7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -8,6 +8,7 @@ using System.Web; using OpenTelemetry.Context; using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.AspNet; @@ -26,7 +27,7 @@ internal static class ActivityHelper private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); private static readonly ActivitySource AspNetSource = new( TelemetryHttpModule.AspNetSourceName, - SignalVersionHelper.GetVersion()); + typeof(ActivityHelper).Assembly.GetPackageVersion()); /// /// Try to get the started for the running - + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs index 09fda21770..a7a1d0bd2b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetMetrics.cs @@ -5,6 +5,7 @@ using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Instrumentation.AspNet.Implementation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.AspNet; @@ -13,9 +14,10 @@ namespace OpenTelemetry.Instrumentation.AspNet; /// internal sealed class AspNetMetrics : IDisposable { - internal static readonly AssemblyName AssemblyName = typeof(HttpInMetricsListener).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(HttpInMetricsListener).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = SignalVersionHelper.GetVersion(); + internal static readonly string InstrumentationVersion = Assembly.GetPackageVersion(); private readonly Meter meter; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 19b8e9cf79..cd8d81f1fe 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs index f00ce0e5cf..0a9bf3c11f 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CassandraMeter.cs @@ -2,10 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Metrics; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Cassandra; internal static class CassandraMeter { - public static Meter Instance => new Meter(typeof(CassandraMeter).Assembly.GetName().Name, SignalVersionHelper.GetVersion()); + static CassandraMeter() + { + var assembly = typeof(CassandraMeter).Assembly; + Instance = new Meter(assembly.GetName().Name, assembly.GetPackageVersion()); + } + + public static Meter Instance { get; } } diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index b07e4e94e7..0ee2a7fc1b 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 7d1ecd5a07..facca350b5 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -23,9 +23,10 @@ internal class ElasticsearchRequestPipelineDiagnosticListener : ListenerHandler internal const string ExceptionCustomPropertyName = "OTel.Elasticsearch.Exception"; internal const string AttributeDbMethod = "db.method"; - internal static readonly AssemblyName AssemblyName = typeof(ElasticsearchRequestPipelineDiagnosticListener).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(ElasticsearchRequestPipelineDiagnosticListener).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); private static readonly Regex ParseRequest = new Regex(@"\n# Request:\r?\n(\{.*)\n# Response", RegexOptions.Compiled | RegexOptions.Singleline); private static readonly ConcurrentDictionary MethodNameCache = new ConcurrentDictionary(); diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index d648bb5535..1d378439e9 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 942f7d07d3..3bc5ee2039 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -4,6 +4,8 @@ using System; using System.Data; using System.Diagnostics; +using System.Reflection; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; @@ -22,12 +24,10 @@ internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler internal const string AttributeDbName = "db.name"; internal const string AttributeDbStatement = "db.statement"; - internal static readonly string ActivitySourceName = typeof(EntityFrameworkDiagnosticListener).Assembly.GetName().Name; + internal static readonly Assembly Assembly = typeof(EntityFrameworkDiagnosticListener).Assembly; + internal static readonly string ActivitySourceName = Assembly.GetName().Name; internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - -#pragma warning disable SA1202 // Elements should be ordered by access <- In this case, Version MUST come before SqlClientActivitySource otherwise null ref exception is thrown. - internal static readonly ActivitySource SqlClientActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); -#pragma warning restore SA1202 // Elements should be ordered by access + internal static readonly ActivitySource SqlClientActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); private readonly PropertyFetcher commandFetcher = new("Command"); private readonly PropertyFetcher connectionFetcher = new("Connection"); diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 2479b7c28e..42ecb2f1d1 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index 56171fe9ee..72e4da73b4 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -7,6 +7,7 @@ using System.Diagnostics.Metrics; using System.Diagnostics.Tracing; using System.Globalization; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.EventCounters; @@ -15,8 +16,6 @@ namespace OpenTelemetry.Instrumentation.EventCounters; /// internal sealed class EventCountersMetrics : EventListener { - internal static readonly Meter MeterInstance = new(typeof(EventCountersMetrics).Assembly.GetName().Name, SignalVersionHelper.GetVersion()); - private const string Prefix = "ec"; private const int MaxInstrumentNameLength = 63; @@ -33,6 +32,9 @@ static EventCountersMetrics() // to prevent potential deadlock: // https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1024. _ = EventCountersInstrumentationEventSource.Log; + + var assembly = typeof(EventCountersMetrics).Assembly; + MeterInstance = new Meter(assembly.GetName().Name, assembly.GetPackageVersion()); } /// @@ -58,6 +60,8 @@ public EventCountersMetrics(EventCountersInstrumentationOptions options) } } + internal static Meter MeterInstance { get; } + /// public override void Dispose() { diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 0dfdd36174..c5bd8c38e9 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index 825369d487..a3a627133a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Reflection; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -11,10 +12,15 @@ namespace OpenTelemetry.Instrumentation.GrpcCore; /// internal static class GrpcCoreInstrumentation { + /// + /// The assembly. + /// + internal static readonly Assembly Assembly = typeof(GrpcCoreInstrumentation).Assembly; + /// /// The assembly name. /// - internal static readonly AssemblyName AssemblyName = typeof(GrpcCoreInstrumentation).Assembly.GetName(); + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); /// /// The activity source name. @@ -24,5 +30,5 @@ internal static class GrpcCoreInstrumentation /// /// The activity source. /// - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index df6379af1d..99bb69af12 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs index 6f955aa3b1..d5064ea008 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentation.cs @@ -5,16 +5,22 @@ using System.Diagnostics; using System.Reflection; using Hangfire; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Hangfire.Implementation; internal sealed class HangfireInstrumentation { + /// + /// The assembly. + /// + internal static readonly Assembly Assembly = typeof(HangfireInstrumentation).Assembly; + /// /// The assembly name. /// - internal static readonly AssemblyName AssemblyName = typeof(HangfireInstrumentation).Assembly.GetName(); + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); /// /// The activity source name. @@ -24,7 +30,7 @@ internal sealed class HangfireInstrumentation /// /// The activity source. /// - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); /// /// The default display name delegate. diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 0d6d8e7a46..05f3aa1298 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs index f0571be8b4..bd0d5b4cba 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationActivitySource.cs @@ -3,16 +3,18 @@ using System.Diagnostics; using System.Reflection; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Owin; internal static class OwinInstrumentationActivitySource { - internal static readonly AssemblyName AssemblyName = typeof(OwinInstrumentationActivitySource).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(OwinInstrumentationActivitySource).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; - public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, Assembly.GetPackageVersion()); public static OwinInstrumentationOptions? Options { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs index 09671a1317..0df90fc72d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -3,16 +3,18 @@ using System.Diagnostics.Metrics; using System.Reflection; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Owin.Implementation; internal static class OwinInstrumentationMetrics { - internal static readonly AssemblyName AssemblyName = typeof(OwinInstrumentationMetrics).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(OwinInstrumentationMetrics).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); public static string MeterName => AssemblyName.Name; - public static Meter Instance => new(MeterName, SignalVersionHelper.GetVersion()); + public static Meter Instance => new(MeterName, Assembly.GetPackageVersion()); public static Histogram HttpServerDuration => Instance.CreateHistogram("http.server.request.duration", "s", "Duration of HTTP server requests."); } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 5b611bb4b9..94e9dd8358 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index 54a0ab562c..abbc684703 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index a597cbc9fe..a85a00edc8 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -7,16 +7,18 @@ using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; +using OpenTelemetry.Internal; using Diagnostics = System.Diagnostics; namespace OpenTelemetry.Instrumentation.Process; internal sealed class ProcessMetrics { - internal static readonly AssemblyName AssemblyName = typeof(ProcessMetrics).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(ProcessMetrics).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string MeterName = AssemblyName.Name; - private static readonly Meter MeterInstance = new(MeterName, SignalVersionHelper.GetVersion()); + private static readonly Meter MeterInstance = new(MeterName, Assembly.GetPackageVersion()); static ProcessMetrics() { diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index ecbb82d05b..0a0d9d34f3 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -13,9 +13,10 @@ namespace OpenTelemetry.Instrumentation.Quartz.Implementation; internal sealed class QuartzDiagnosticListener : ListenerHandler { - internal static readonly AssemblyName AssemblyName = typeof(QuartzDiagnosticListener).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(QuartzDiagnosticListener).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); internal readonly PropertyFetcher JobDetailsPropertyFetcher = new("JobDetail"); private readonly QuartzInstrumentationOptions options; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 417e467db6..591d4158ac 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 74fd5a74ff..45aa106e5b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 21bb5b17d8..4fb23bf5ff 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; +using OpenTelemetry.Internal; #if NET6_0_OR_GREATER using System.Threading; using JitInfo = System.Runtime.JitInfo; @@ -17,8 +18,9 @@ namespace OpenTelemetry.Instrumentation.Runtime; /// internal sealed class RuntimeMetrics { - internal static readonly AssemblyName AssemblyName = typeof(RuntimeMetrics).Assembly.GetName(); - internal static readonly Meter MeterInstance = new(AssemblyName.Name!, SignalVersionHelper.GetVersion()); + internal static readonly Assembly Assembly = typeof(RuntimeMetrics).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); + internal static readonly Meter MeterInstance = new(AssemblyName.Name!, Assembly.GetPackageVersion()); #if NET6_0_OR_GREATER private const long NanosecondsPerTick = 100; diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 410cdbabef..cec66dcf2a 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs index 7bdc34ee2d..08711711b7 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Diagnostics; +using System.Reflection; using OpenTelemetry.Instrumentation.StackExchangeRedis.Implementation; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -18,9 +19,10 @@ internal sealed class StackExchangeRedisConnectionInstrumentation : IDisposable { internal const string RedisDatabaseIndexKeyName = "db.redis.database_index"; internal const string RedisFlagsKeyName = "db.redis.flags"; - internal static readonly string ActivitySourceName = typeof(StackExchangeRedisConnectionInstrumentation).Assembly.GetName().Name!; + internal static readonly Assembly Assembly = typeof(StackExchangeRedisConnectionInstrumentation).Assembly; + internal static readonly string ActivitySourceName = Assembly.GetName().Name!; internal static readonly string ActivityName = ActivitySourceName + ".Execute"; - internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); internal static readonly IEnumerable> CreationTags = new[] { new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs index f51cc8d7df..32af8b94e0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationActivitySource.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.ServiceModel.Channels; using OpenTelemetry.Instrumentation.Wcf.Implementation; +using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Wcf; @@ -14,12 +15,13 @@ namespace OpenTelemetry.Instrumentation.Wcf; /// internal static class WcfInstrumentationActivitySource { - internal static readonly AssemblyName AssemblyName = typeof(WcfInstrumentationActivitySource).Assembly.GetName(); + internal static readonly Assembly Assembly = typeof(WcfInstrumentationActivitySource).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string ActivitySourceName = AssemblyName.Name; internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; internal static readonly string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; - public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, SignalVersionHelper.GetVersion()); + public static ActivitySource ActivitySource { get; } = new(ActivitySourceName, Assembly.GetPackageVersion()); public static WcfInstrumentationOptions? Options { get; set; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 9ea3f6aa2b..32a99948f9 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -23,7 +23,7 @@ - + diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs new file mode 100644 index 0000000000..dd147d21e0 --- /dev/null +++ b/src/Shared/AssemblyVersionExtensions.cs @@ -0,0 +1,38 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +#pragma warning disable IDE0005 // Using directive is unnecessary. +using System; +using System.Diagnostics; +using System.Reflection; +#pragma warning restore IDE0005 // Using directive is unnecessary. + +namespace OpenTelemetry.Internal; + +internal static class AssemblyVersionExtensions +{ + public static string GetPackageVersion(this Assembly assembly) + { + // MinVer https://github.com/adamralph/minver?tab=readme-ov-file#version-numbers + // together with Microsoft.SourceLink.GitHub https://github.com/dotnet/sourcelink + // fills AssemblyInformationalVersionAttribute by + // {majorVersion}.{minorVersion}.{patchVersion}.{pre-release label}.{pre-release version}.{gitHeight}+{Git SHA of current commit} + // Ex: 1.5.0-alpha.1.40+807f703e1b4d9874a92bd86d9f2d4ebe5b5d52e4 + // 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"); + +#if NET6_0_OR_GREATER + var indexOfPlusSign = informationalVersion!.IndexOf('+', StringComparison.Ordinal); +#else + var indexOfPlusSign = informationalVersion!.IndexOf('+'); +#endif + return indexOfPlusSign > 0 + ? informationalVersion.Substring(0, indexOfPlusSign) + : informationalVersion; + } +} diff --git a/src/Shared/SignalVersionHelper.cs b/src/Shared/SignalVersionHelper.cs deleted file mode 100644 index 37f65ba600..0000000000 --- a/src/Shared/SignalVersionHelper.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Reflection; - -namespace OpenTelemetry.Instrumentation; - -internal static class SignalVersionHelper -{ - public static string GetVersion() - { - return typeof(T).Assembly.GetCustomAttribute()!.InformationalVersion.Split('+')[0]; - } -} From 323e7e640887b81269f79fccb9af523f2f18c1e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 08:04:32 +0200 Subject: [PATCH 1008/1499] Bump OpenTelemetry.Instrumentation.AspNetCore from 1.5.1-beta.1 to 1.8.1 in /examples/grpc.core/Examples.GrpcCore.AspNetCore (#1649) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../Examples.GrpcCore.AspNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 9d942db505..101df6a51d 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -7,7 +7,7 @@ - + From 30857727a7432e4d3cc7cb3cd619b9ed44cd231a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:53:28 +0200 Subject: [PATCH 1009/1499] Bump non-core OTel packages in /examples/AspNet (#1647) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz --- examples/AspNet/Examples.AspNet.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 9443447544..849bb81664 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -53,11 +53,11 @@ - + - + From 113e5b82b06b4cb9da232f3f27547591d98d38f6 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 17 Apr 2024 11:52:24 -0700 Subject: [PATCH 1010/1499] [Instrumentation.AspNet][Instrumentation.Owin] Redact query parameters (#1656) --- opentelemetry-dotnet-contrib.sln | 3 +- .../AspNetTraceInstrumentationOptions.cs | 32 +++ .../CHANGELOG.md | 12 +- .../AspNetInstrumentationEventSource.cs | 15 ++ .../Implementation/HttpInListener.cs | 10 +- ...penTelemetry.Instrumentation.AspNet.csproj | 1 + .../CHANGELOG.md | 12 +- .../Implementation/DiagnosticsMiddleware.cs | 13 +- .../OwinInstrumentationEventSource.cs | 16 ++ .../OpenTelemetry.Instrumentation.Owin.csproj | 1 + .../OwinInstrumentationOptions.cs | 31 +++ src/Shared/RedactionHelper.cs | 59 +++++ .../HttpInListenerTests.cs | 205 ++++++++++-------- .../DiagnosticsMiddlewareTests.cs | 57 +++++ 14 files changed, 356 insertions(+), 111 deletions(-) create mode 100644 src/Shared/RedactionHelper.cs diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 776f0dbc0c..1e884823d6 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -280,8 +280,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\ListenerHandler.cs = src\Shared\ListenerHandler.cs src\Shared\MultiTypePropertyFetcher.cs = src\Shared\MultiTypePropertyFetcher.cs src\Shared\NullableAttributes.cs = src\Shared\NullableAttributes.cs - src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs src\Shared\PropertyFetcher.AOT.cs = src\Shared\PropertyFetcher.AOT.cs + src\Shared\PropertyFetcher.cs = src\Shared\PropertyFetcher.cs + src\Shared\RedactionHelper.cs = src\Shared\RedactionHelper.cs src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs index 809e1453e0..f5ec023288 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.Web; +using OpenTelemetry.Instrumentation.AspNet.Implementation; namespace OpenTelemetry.Instrumentation.AspNet; @@ -12,6 +13,27 @@ namespace OpenTelemetry.Instrumentation.AspNet; /// public class AspNetTraceInstrumentationOptions { + private const string DisableQueryRedactionEnvVar = "OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION"; + + /// + /// Initializes a new instance of the class. + /// + public AspNetTraceInstrumentationOptions() + { + try + { + var disableQueryRedaction = Environment.GetEnvironmentVariable(DisableQueryRedactionEnvVar); + if (disableQueryRedaction != null && disableQueryRedaction.Equals("true", StringComparison.OrdinalIgnoreCase)) + { + this.DisableUrlQueryRedaction = true; + } + } + catch (Exception ex) + { + AspNetInstrumentationEventSource.Log.FailedToReadEnvironmentVariable(DisableQueryRedactionEnvVar, ex); + } + } + /// /// Gets or sets a filter callback function that determines on a per /// request basis whether or not to collect telemetry. @@ -46,4 +68,14 @@ public class AspNetTraceInstrumentationOptions /// See: . /// public bool RecordException { get; set; } + + /// + /// Gets or sets a value indicating whether the url query value should be redacted or not. + /// + /// + /// The query parameter values are redacted with value set as Redacted. + /// e.g. `?key1=value1` is set as `?key1=Redacted`. + /// The redaction can be disabled by setting this property to . + /// + internal bool DisableUrlQueryRedaction { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 679198547b..0fcaeef82d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -1,6 +1,16 @@ # Changelog -## Unreleased +## 1.8.0-beta.2 + +Released 2024-Apr-17 + +* **Breaking Change**: Fixed tracing instrumentation so that by default any + values detected in the query string component of requests are replaced with + the text `Redacted` when building the `url.query` attribute. For example, + `?key1=value1&key2=value2` becomes `?key1=Redacted&key2=Redacted`. You can + disable this redaction by setting the environment variable + `OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION` to `true`. + ([#1656](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1656)) ## 1.8.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs index 167e616253..7e118e74ef 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs @@ -33,6 +33,15 @@ public void EnrichmentException(string eventName, Exception ex) } } + [NonEvent] + public void FailedToReadEnvironmentVariable(string envVarName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(envVarName, ex.ToInvariantString()); + } + } + [Event(1, Message = "Request is filtered out and will not be collected. Operation='{0}'", Level = EventLevel.Verbose)] public void RequestIsFilteredOut(string operationName) { @@ -50,4 +59,10 @@ public void EnrichmentException(string eventName, string exception) { this.WriteEvent(3, eventName, exception); } + + [Event(4, Message = "Failed to read environment variable='{0}': {1}", Level = EventLevel.Error)] + public void FailedToReadEnvironmentVariable(string envVarName, string exception) + { + this.WriteEvent(4, envVarName, exception); + } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index 0337c56eaa..5879be98be 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -91,14 +91,8 @@ private void OnStartActivity(Activity activity, HttpContext context) var query = url.Query; if (!string.IsNullOrEmpty(query)) { - if (query.StartsWith("?", StringComparison.InvariantCulture)) - { - activity.SetTag(SemanticConventions.AttributeUrlQuery, query.Substring(1)); - } - else - { - activity.SetTag(SemanticConventions.AttributeUrlQuery, query); - } + var queryString = query.StartsWith("?", StringComparison.InvariantCulture) ? query.Substring(1) : query; + activity.SetTag(SemanticConventions.AttributeUrlQuery, this.options.DisableUrlQueryRedaction ? queryString : RedactionHelper.GetRedactedQueryString(queryString)); } var userAgent = request.UserAgent; diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index cd8d81f1fe..25b0a759d8 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -17,6 +17,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 4ffd5330c9..92f8480061 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -1,6 +1,16 @@ # Changelog -## Unreleased +## 1.0.0-rc.5 + +Released 2024-Apr-17 + +* **Breaking Change**: Fixed tracing instrumentation so that by default any + values detected in the query string component of requests are replaced with + the text `Redacted` when building the `http.url` tag. For example, + `?key1=value1&key2=value2` becomes `?key1=Redacted&key2=Redacted`. You can + disable this redaction by setting the environment variable + `OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION` to `true`. + ([#1656](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1656)) * `ActivitySource.Version` and `Meter.Version` are set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 6b435ef87b..1efc1ee464 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -9,6 +9,7 @@ using Microsoft.Owin; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Owin.Implementation; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Owin; @@ -114,7 +115,7 @@ private static void BeginRequest(IOwinContext owinContext) activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); activity.SetTag(SemanticConventions.AttributeHttpTarget, request.Uri.AbsolutePath); - activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Uri)); + activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Uri, OwinInstrumentationActivitySource.Options.DisableUrlQueryRedaction)); if (request.Headers.TryGetValue("User-Agent", out string[] userAgent) && userAgent.Length > 0) { @@ -228,13 +229,15 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l /// /// . /// Span uri value. - private static string GetUriTagValueFromRequestUri(Uri uri) + private static string GetUriTagValueFromRequestUri(Uri uri, bool disableQueryRedaction) { - if (string.IsNullOrEmpty(uri.UserInfo)) + if (string.IsNullOrEmpty(uri.UserInfo) && disableQueryRedaction) { - return uri.ToString(); + return uri.OriginalString; } - return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.PathAndQuery, uri.Fragment); + var query = disableQueryRedaction ? uri.Query : RedactionHelper.GetRedactedQueryString(uri.Query); + + return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.AbsolutePath, query, uri.Fragment); } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index 1ac5514375..1f5f35ca9a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -45,16 +45,32 @@ public void EnrichmentException(Exception exception) } } + [NonEvent] + public void FailedToReadEnvironmentVariable(string envVarName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.FailedToReadEnvironmentVariable(envVarName, ex.ToInvariantString()); + } + } + [Event(EventIds.EnrichmentException, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] public void EnrichmentException(string exception) { this.WriteEvent(EventIds.EnrichmentException, exception); } + [Event(EventIds.FailedToReadEnvironmentVariable, Message = "Failed to read environment variable='{0}': {1}", Level = EventLevel.Error)] + public void FailedToReadEnvironmentVariable(string envVarName, string exception) + { + this.WriteEvent(4, envVarName, exception); + } + private class EventIds { public const int RequestIsFilteredOut = 1; public const int RequestFilterException = 2; public const int EnrichmentException = 3; + public const int FailedToReadEnvironmentVariable = 4; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 94e9dd8358..9773878f10 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -10,6 +10,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index 57f98e812d..e17a0c3bfd 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -12,6 +12,27 @@ namespace OpenTelemetry.Instrumentation.Owin; /// public class OwinInstrumentationOptions { + private const string DisableQueryRedactionEnvVar = "OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION"; + + /// + /// Initializes a new instance of the class. + /// + public OwinInstrumentationOptions() + { + try + { + var disableQueryRedaction = Environment.GetEnvironmentVariable(DisableQueryRedactionEnvVar); + if (disableQueryRedaction != null && disableQueryRedaction.Equals("true", StringComparison.OrdinalIgnoreCase)) + { + this.DisableUrlQueryRedaction = true; + } + } + catch (Exception ex) + { + OwinInstrumentationEventSource.Log.FailedToReadEnvironmentVariable(DisableQueryRedactionEnvVar, ex); + } + } + /// /// Gets or sets a Filter function that determines whether or not to collect telemetry about requests on a per request basis. /// The Filter gets the , and should return a boolean. @@ -32,4 +53,14 @@ public class OwinInstrumentationOptions /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md. /// public bool RecordException { get; set; } + + /// + /// Gets or sets a value indicating whether the url query value should be redacted or not. + /// + /// + /// The query parameter values are redacted with value set as Redacted. + /// e.g. `?key1=value1` is set as `?key1=Redacted`. + /// The redaction can be disabled by setting this property to . + /// + internal bool DisableUrlQueryRedaction { get; set; } } diff --git a/src/Shared/RedactionHelper.cs b/src/Shared/RedactionHelper.cs new file mode 100644 index 0000000000..cc6e34c7ea --- /dev/null +++ b/src/Shared/RedactionHelper.cs @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Text; + +namespace OpenTelemetry.Internal; + +internal sealed class RedactionHelper +{ + private const string RedactedText = "Redacted"; + + public static string? GetRedactedQueryString(string query) + { + int length = query.Length; + int index = 0; + + // Preallocate some size to avoid re-sizing multiple times. + // Since the size will increase, allocating twice as much. + // TODO: Check to see if we can borrow from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/System/Text/ValueStringBuilder.cs + // to improve perf. + StringBuilder queryBuilder = new(2 * length); + while (index < query.Length) + { + // Check if the character is = for redacting value. + if (query[index] == '=') + { + // Append = + queryBuilder.Append('='); + index++; + + // Append redactedText in place of original value. + queryBuilder.Append(RedactedText); + + // Move until end of this key/value pair. + while (index < length && query[index] != '&') + { + index++; + } + + // End of key/value. + if (index < length && query[index] == '&') + { + queryBuilder.Append(query[index]); + } + } + else + { + // Keep adding to the result + queryBuilder.Append(query[index]); + } + + index++; + } + + return queryBuilder.ToString(); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 4b832aa6d6..4359a3b9b8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -20,26 +20,29 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class HttpInListenerTests { [Theory] - [InlineData("http://localhost/", "http", "/", null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] - [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] - [InlineData("https://localhost/", "https", "/", null, "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null, "HTTP")] - [InlineData("https://user:pass@localhost/", "https", "/", null, "localhost", 443, "GeT", "GET", "GeT", 0, null, "GET")] // Test URL sanitization - [InlineData("http://localhost:443/", "http", "/", null, "localhost", 443, "GET", "GET", null, 0, null, "GET")] // Test http over 443 - [InlineData("https://localhost:80/", "https", "/", null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test https over 80 - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL - [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization - [InlineData("http://localhost:80/Index", "http", "/Index", null, "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}", "GET {controller}/{action}/{id}")] - [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] - [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] - [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")] - [InlineData("http://localhost/api/value", "http", "/api/value", null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered - [InlineData("http://localhost/api/value", "http", "/api/value", null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception - [InlineData("http://localhost/", "http", "/", null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option + [InlineData("http://localhost/", "http", "/", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", true, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=Redacted&baz=Redacted", false, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("https://localhost/", "https", "/", null, true, "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null, "HTTP")] + [InlineData("https://user:pass@localhost/", "https", "/", null, true, "localhost", 443, "GeT", "GET", "GeT", 0, null, "GET")] // Test URL sanitization + [InlineData("http://localhost:443/", "http", "/", null, true, "localhost", 443, "GET", "GET", null, 0, null, "GET")] // Test http over 443 + [InlineData("https://localhost:80/", "https", "/", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test https over 80 + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=Redacted&q2=Redacted", false, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL + [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization + [InlineData("http://localhost:80/Index", "http", "/Index", null, true, "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}", "GET {controller}/{action}/{id}")] + [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, true, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] + [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, true, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] + [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, true, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")] + [InlineData("http://localhost/api/value", "http", "/api/value", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered + [InlineData("http://localhost/api/value", "http", "/api/value", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception + [InlineData("http://localhost/", "http", "/", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option public void AspNetRequestsAreCollectedSuccessfully( string url, string expectedUrlScheme, string expectedUrlPath, string expectedUrlQuery, + bool disableQueryRedaction, string expectedHost, int expectedPort, string requestMethod, @@ -53,113 +56,125 @@ public void AspNetRequestsAreCollectedSuccessfully( bool recordException = false, string? expectedErrorType = null) { - HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate, requestMethod); + try + { + if (disableQueryRedaction) + { + Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION", "true"); + } - typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, new TestHttpWorkerRequest()); + HttpContext.Current = RouteTestHelper.BuildHttpContext(url, routeType, routeTemplate, requestMethod); - List exportedItems = new List(16); + typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, new TestHttpWorkerRequest()); - Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); - using (Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation((options) => - { - options.Filter = httpContext => - { - Assert.True(Activity.Current!.IsAllDataRequested); - if (string.IsNullOrEmpty(filter)) - { - return true; - } + List exportedItems = new List(16); - if (filter == "{ThrowException}") + Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); + using (Sdk.CreateTracerProviderBuilder() + .AddAspNetInstrumentation((options) => + { + options.Filter = httpContext => { - throw new InvalidOperationException(); - } + Assert.True(Activity.Current!.IsAllDataRequested); + if (string.IsNullOrEmpty(filter)) + { + return true; + } + + if (filter == "{ThrowException}") + { + throw new InvalidOperationException(); + } + + return httpContext.Request.Path != filter; + }; + + options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? ActivityStatusCode.Error : default); + + options.RecordException = recordException; + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); - return httpContext.Request.Path != filter; - }; + var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); - options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? ActivityStatusCode.Error : default); + if (filter == "{ThrowException}") + { + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); + } - options.RecordException = recordException; - }) - .AddInMemoryExporter(exportedItems) - .Build()) - { - using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); + Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current!.OperationName); - var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); + if (recordException) + { + ActivityHelper.WriteActivityException(activity, HttpContext.Current, new InvalidOperationException(), TelemetryHttpModule.Options.OnExceptionCallback); + } - if (filter == "{ThrowException}") - { - Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); + ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); } - Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current!.OperationName); - - if (recordException) + if (HttpContext.Current.Request.Path == filter || filter == "{ThrowException}") { - ActivityHelper.WriteActivityException(activity, HttpContext.Current, new InvalidOperationException(), TelemetryHttpModule.Options.OnExceptionCallback); + Assert.Empty(exportedItems); + return; } - ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); - } - - if (HttpContext.Current.Request.Path == filter || filter == "{ThrowException}") - { - Assert.Empty(exportedItems); - return; - } + Assert.Single(exportedItems); - Assert.Single(exportedItems); + Activity span = exportedItems[0]; - Activity span = exportedItems[0]; + Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); + Assert.NotEqual(TimeSpan.Zero, span.Duration); - Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); - Assert.NotEqual(TimeSpan.Zero, span.Duration); + Assert.Equal(expectedName, span.DisplayName); + Assert.Equal(ActivityKind.Server, span.Kind); + Assert.True(span.Duration != TimeSpan.Zero); - Assert.Equal(expectedName, span.DisplayName); - Assert.Equal(ActivityKind.Server, span.Kind); - Assert.True(span.Duration != TimeSpan.Zero); + Assert.Equal(200, span.GetTagValue("http.response.status_code")); - Assert.Equal(200, span.GetTagValue("http.response.status_code")); + Assert.Equal(expectedHost, span.GetTagValue("server.address")); + Assert.Equal(expectedPort, span.GetTagValue("server.port")); - Assert.Equal(expectedHost, span.GetTagValue("server.address")); - Assert.Equal(expectedPort, span.GetTagValue("server.port")); + Assert.Equal(expectedRequestMethod, span.GetTagValue("http.request.method")); + Assert.Equal(expectedOriginalRequestMethod, span.GetTagValue("http.request.method_original")); + Assert.Equal("FakeHTTP/123", span.GetTagValue("network.protocol.version")); - Assert.Equal(expectedRequestMethod, span.GetTagValue("http.request.method")); - Assert.Equal(expectedOriginalRequestMethod, span.GetTagValue("http.request.method_original")); - Assert.Equal("FakeHTTP/123", span.GetTagValue("network.protocol.version")); + Assert.Equal(expectedUrlPath, span.GetTagValue("url.path")); + Assert.Equal(expectedUrlQuery, span.GetTagValue("url.query")); + Assert.Equal(expectedUrlScheme, span.GetTagValue("url.scheme")); + Assert.Equal("Custom User Agent v1.2.3", span.GetTagValue("user_agent.original")); + Assert.Equal(expectedErrorType, span.GetTagValue("error.type")); - Assert.Equal(expectedUrlPath, span.GetTagValue("url.path")); - Assert.Equal(expectedUrlQuery, span.GetTagValue("url.query")); - Assert.Equal(expectedUrlScheme, span.GetTagValue("url.scheme")); - Assert.Equal("Custom User Agent v1.2.3", span.GetTagValue("user_agent.original")); - Assert.Equal(expectedErrorType, span.GetTagValue("error.type")); + if (recordException) + { + var status = span.Status; + Assert.Equal(ActivityStatusCode.Error, span.Status); + Assert.Equal("Operation is not valid due to the current state of the object.", span.StatusDescription); + } + else if (setStatusToErrorInEnrich) + { + // This validates that users can override the + // status in Enrich. + Assert.Equal(ActivityStatusCode.Error, span.Status); - if (recordException) - { - var status = span.Status; - Assert.Equal(ActivityStatusCode.Error, span.Status); - Assert.Equal("Operation is not valid due to the current state of the object.", span.StatusDescription); - } - else if (setStatusToErrorInEnrich) - { - // This validates that users can override the - // status in Enrich. - Assert.Equal(ActivityStatusCode.Error, span.Status); + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.True(string.IsNullOrEmpty(span.StatusDescription)); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, span.Status); - // Instrumentation is not expected to set status description - // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode - Assert.True(string.IsNullOrEmpty(span.StatusDescription)); + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.True(string.IsNullOrEmpty(span.StatusDescription)); + } } - else + finally { - Assert.Equal(ActivityStatusCode.Unset, span.Status); - - // Instrumentation is not expected to set status description - // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode - Assert.True(string.IsNullOrEmpty(span.StatusDescription)); + Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION", null); } } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index d2111ab468..71e57081a1 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -281,6 +281,63 @@ Owin has finished to inspect the activity status. */ } } + [Theory] + [InlineData("path?a=b&c=d", "path?a=Redacted&c=Redacted", false)] + [InlineData("path?a=b&c=d", "path?a=b&c=d", true)] + public async Task QueryParametersAreRedacted(string actualPath, string expectedPath, bool disableQueryRedaction) + { + try + { + if (disableQueryRedaction) + { + Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", "true"); + } + + List stoppedActivities = new List(); + + var builder = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(stoppedActivities) + .AddOwinInstrumentation() + .Build(); + + using HttpClient client = new HttpClient(); + + Uri requestUri = new Uri($"{this.serviceBaseUri}{actualPath}"); + Uri expectedRequestUri = new Uri($"{this.serviceBaseUri}{expectedPath}"); + + this.requestCompleteHandle.Reset(); + + try + { + using var response = await client.GetAsync(requestUri).ConfigureAwait(false); + } + catch + { + } + + /* Note: This code will continue executing as soon as the response + is available but Owin could still be working. We need to wait until + Owin has finished to inspect the activity status. */ + + Assert.True(this.requestCompleteHandle.WaitOne(3000)); + + Assert.NotEmpty(stoppedActivities); + Assert.Single(stoppedActivities); + + Activity activity = stoppedActivities[0]; + Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); + + Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); + Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); + Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); + Assert.Equal(expectedRequestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); + } + finally + { + Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", null); + } + } + private List GetMetricPoints(Metric metric) { List metricPoints = new(); From 48805ec3f16390ce38d5caf2defd904ce3a2fb25 Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Thu, 18 Apr 2024 08:17:53 -0700 Subject: [PATCH 1011/1499] Move Utkarsh to Emeritus Maintainer (#1658) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f219da1d7..18f92c8d95 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb * [Cijo Thomas](https://github.com/cijothomas), Microsoft * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk -* [Utkarsh Umesan Pillai](https://github.com/utpilla), Microsoft * [Vishwesh Bankwar](https://github.com/vishweshbankwar), Microsoft *Find more about the maintainer role in [community @@ -62,6 +61,7 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb * [Prashant Srivastava](https://github.com/srprash) * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) +* [Utkarsh Umesan Pillai](https://github.com/utpilla) Even though, anybody can contribute, there are benefits of being a member of our community. See to the [community membership From 45301ba3dce3299ecade85cb0cb34e1137efdd1b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 18 Apr 2024 10:31:37 -0700 Subject: [PATCH 1012/1499] [Exporter.Geneva][Otlp protobuf] Add PrepopulatedMetricDimensions and Account/Namespace support (#1644) --- .../Metrics/GenevaMetricExporter.cs | 5 +- .../OtlpProtobufMetricExporter.cs | 6 +- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 80 ++++++- .../Exporter/MetricExporterBenchmarks.cs | 4 +- .../OtlpProtobufMetricExporterTests.cs | 225 ++++++++++++++---- 5 files changed, 271 insertions(+), 49 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index fa0c601afe..85cb80cf53 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -44,7 +44,10 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) if (connectionStringBuilder.PrivatePreviewOtlpProtobufMetricExporter != null && connectionStringBuilder.PrivatePreviewOtlpProtobufMetricExporter.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) { - var otlpProtobufExporter = new OtlpProtobufMetricExporter(() => { return this.Resource; }); + var otlpProtobufExporter = new OtlpProtobufMetricExporter( + () => { return this.Resource; }, + connectionStringBuilder, + options.PrepopulatedMetricDimensions); this.exporter = otlpProtobufExporter; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index c487d2a0ea..1d14586a99 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -16,7 +17,7 @@ internal sealed class OtlpProtobufMetricExporter : IDisposable private readonly Func getResource; - public OtlpProtobufMetricExporter(Func getResource) + public OtlpProtobufMetricExporter(Func getResource, ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -25,7 +26,8 @@ public OtlpProtobufMetricExporter(Func getResource) } this.getResource = getResource; - this.otlpProtobufSerializer = new OtlpProtobufSerializer(MetricEtwDataTransport.Instance); + + this.otlpProtobufSerializer = new OtlpProtobufSerializer(MetricEtwDataTransport.Instance, connectionStringBuilder, prepopulatedMetricDimensions); } public ExportResult Export(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index f6a124d25c..d7360df42f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -15,6 +15,18 @@ internal sealed class OtlpProtobufSerializer private readonly Dictionary> scopeMetrics = new(); + private readonly string metricNamespace; + + private readonly string metricAccount; + + private readonly byte[] prepopulatedNumberDataPointAttributes; + + private readonly int prepopulatedNumberDataPointAttributesLength; + + private readonly byte[] prepopulatedHistogramDataPointAttributes; + + private readonly int prepopulatedHistogramDataPointAttributesLength; + private int resourceMetricTagAndLengthIndex; private int scopeMetricsTagAndLengthIndex; @@ -37,9 +49,47 @@ internal sealed class OtlpProtobufSerializer internal IMetricDataTransport MetricDataTransport; - public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport) + public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) { this.MetricDataTransport = metricDataTransport; + + // Taking a arbitrary number here for writing attributes. + byte[] temp = new byte[20000]; + if (prepopulatedMetricDimensions != null) + { + // Initialize numberDataPoint attributes. + int cursor = 0; + SerializeTags(temp, ref cursor, prepopulatedMetricDimensions, FieldNumberConstants.NumberDataPoint_attributes); + this.prepopulatedNumberDataPointAttributes = new byte[cursor]; + Array.Copy(temp, this.prepopulatedNumberDataPointAttributes, cursor); + this.prepopulatedNumberDataPointAttributesLength = cursor; + + // Initialize histogramDataPoint attributes. + cursor = 0; + SerializeTags(temp, ref cursor, prepopulatedMetricDimensions, FieldNumberConstants.HistogramDataPoint_attributes); + this.prepopulatedHistogramDataPointAttributes = new byte[cursor]; + Array.Copy(temp, this.prepopulatedHistogramDataPointAttributes, cursor); + this.prepopulatedHistogramDataPointAttributesLength = cursor; + + // TODO: exponential histogram. + } + + try + { + if (connectionStringBuilder != null && connectionStringBuilder.Namespace != null) + { + this.metricNamespace = connectionStringBuilder.Namespace; + } + + if (connectionStringBuilder != null && connectionStringBuilder.Account != null) + { + this.metricAccount = connectionStringBuilder.Account; + } + } + catch + { + // TODO: add log. + } } internal void SerializeAndSendMetrics(byte[] buffer, Resource resource, in Batch metricBatch) @@ -83,7 +133,7 @@ internal void SerializeResourceMetrics(byte[] buffer, Resource resource) // Serialize Resource // TODO: Avoid serializing it multiple times. - SerializeResource(buffer, ref cursor, resource); + this.SerializeResource(buffer, ref cursor, resource); // TODO: Serialize schema_url field @@ -311,6 +361,12 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.HistogramDataPoint_attributes); + if (this.prepopulatedHistogramDataPointAttributes != null) + { + Array.Copy(this.prepopulatedHistogramDataPointAttributes, 0, buffer, cursor, this.prepopulatedHistogramDataPointAttributesLength); + cursor += this.prepopulatedHistogramDataPointAttributesLength; + } + var count = (ulong)metricPoint.GetHistogramCount(); ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_count, count); @@ -385,6 +441,12 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.NumberDataPoint_attributes); + if (this.prepopulatedNumberDataPointAttributes != null) + { + Array.Copy(this.prepopulatedNumberDataPointAttributes, 0, buffer, cursor, this.prepopulatedHistogramDataPointAttributesLength); + cursor += this.prepopulatedNumberDataPointAttributesLength; + } + // TODO: exemplars. var metricPointStartPosition = this.metricPointTagAndLengthIndex; @@ -469,7 +531,7 @@ private static void SerializeTags(byte[] buffer, ref int cursor, IEnumerable("TestResourceKey", "TestResourceValue") }); this.resource = resourceBuilder.Build(); - this.otlpProtobufMetricExporter = new OtlpProtobufMetricExporter(() => { return this.resource; }); + this.otlpProtobufMetricExporter = new OtlpProtobufMetricExporter(() => { return this.resource; }, null, null); this.buffer = new byte[GenevaMetricExporter.BufferSize]; this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 1f7cb30b92..0e54efa6c5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -20,6 +20,15 @@ public class OtlpProtobufMetricExporterTests { public TagList TagList; + public TagList TagListWithPrepopulatedDimensions; + + private static readonly Dictionary prepopulatedMetricDimensions = new Dictionary + { + { "Dim1", 1 }, + { "Dim2", 2 }, + { "Dim3", 3 }, + }; + public OtlpProtobufMetricExporterTests() { this.TagList = default; @@ -63,11 +72,23 @@ public OtlpProtobufMetricExporterTests() } [Theory] - [InlineData("longcounter", 123L, null)] - [InlineData("doublecounter", null, 123.45)] - [InlineData("longcounter", -123L, null)] - [InlineData("doublecounter", null, -123.45)] - public void CounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue) + [InlineData("longcounter", 123L, null, true, true)] + [InlineData("longcounter", 123L, null, true, false)] + [InlineData("longcounter", 123L, null, false, true)] + [InlineData("longcounter", 123L, null, false, false)] + [InlineData("doublecounter", null, 123.45, true, true)] + [InlineData("doublecounter", null, 123.45, true, false)] + [InlineData("doublecounter", null, 123.45, false, true)] + [InlineData("doublecounter", null, 123.45, false, false)] + [InlineData("longcounter", -123L, null, true, true)] + [InlineData("longcounter", -123L, null, true, false)] + [InlineData("longcounter", -123L, null, false, true)] + [InlineData("longcounter", -123L, null, false, false)] + [InlineData("doublecounter", null, -123.45, true, true)] + [InlineData("doublecounter", null, -123.45, true, false)] + [InlineData("doublecounter", null, -123.45, false, true)] + [InlineData("doublecounter", null, -123.45, false, false)] + public void CounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace) { using var meter = new Meter(nameof(this.CounterSerializationSingleMetricPoint), "0.0.1"); @@ -77,8 +98,23 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; + Dictionary resourceAttributes = new Dictionary + { + { "TestResourceKey", "TestResourceValue" }, + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, + }; + + string expectedAccount = "TestAccount"; + string expectedNamespace = "TestNameSpace"; + Dictionary accountAndNamespace = new Dictionary + { + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, + }; + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() - .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + .AddAttributes(resourceAttributes); using var meterProvider = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.CounterSerializationSingleMetricPoint)) @@ -101,7 +137,10 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + + ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); + + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -115,7 +154,7 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l Assert.NotNull(request.ResourceMetrics[0].Resource); - AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + AssertOtlpAttributes(addAccountAndNamespace ? resourceAttributes.Concat(accountAndNamespace) : resourceAttributes, request.ResourceMetrics[0].Resource.Attributes); Assert.Single(request.ResourceMetrics[0].ScopeMetrics); @@ -157,7 +196,14 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + if (addPrepopulatedDimensions) + { + AssertOtlpAttributes(this.TagList.Concat(prepopulatedMetricDimensions), dataPoint.Attributes); + } + else + { + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + } } [Theory] @@ -214,7 +260,7 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -274,11 +320,23 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long } [Theory] - [InlineData("updownlongcounter", 123L, null)] - [InlineData("updowndoublecounter", null, 123.45)] - [InlineData("updownlongcounter", -123L, null)] - [InlineData("updowndoublecounter", null, -123.45)] - public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue) + [InlineData("updownlongcounter", 123L, null, true, true)] + [InlineData("updownlongcounter", 123L, null, true, false)] + [InlineData("updownlongcounter", 123L, null, false, true)] + [InlineData("updownlongcounter", 123L, null, false, false)] + [InlineData("updowndoublecounter", null, 123.45, true, true)] + [InlineData("updowndoublecounter", null, 123.45, true, false)] + [InlineData("updowndoublecounter", null, 123.45, false, true)] + [InlineData("updowndoublecounter", null, 123.45, false, false)] + [InlineData("updownlongcounter", -123L, null, true, true)] + [InlineData("updownlongcounter", -123L, null, true, false)] + [InlineData("updownlongcounter", -123L, null, false, true)] + [InlineData("updownlongcounter", -123L, null, false, false)] + [InlineData("updowndoublecounter", null, -123.45, true, true)] + [InlineData("updowndoublecounter", null, -123.45, true, false)] + [InlineData("updowndoublecounter", null, -123.45, false, true)] + [InlineData("updowndoublecounter", null, -123.45, false, false)] + public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace) { using var meter = new Meter(nameof(this.UpdownCounterSerializationSingleMetricPoint), "0.0.1"); @@ -288,8 +346,23 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; + Dictionary resourceAttributes = new Dictionary + { + { "TestResourceKey", "TestResourceValue" }, + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, + }; + + string expectedAccount = "TestAccount"; + string expectedNamespace = "TestNameSpace"; + Dictionary accountAndNamespace = new Dictionary + { + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, + }; + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() - .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + .AddAttributes(resourceAttributes); using var meterProvider = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.UpdownCounterSerializationSingleMetricPoint)) @@ -312,7 +385,8 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -326,7 +400,7 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l Assert.NotNull(request.ResourceMetrics[0].Resource); - AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + AssertOtlpAttributes(addAccountAndNamespace ? resourceAttributes.Concat(accountAndNamespace) : resourceAttributes, request.ResourceMetrics[0].Resource.Attributes); Assert.Single(request.ResourceMetrics[0].ScopeMetrics); @@ -368,7 +442,14 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + if (addPrepopulatedDimensions) + { + AssertOtlpAttributes(this.TagList.Concat(prepopulatedMetricDimensions), dataPoint.Attributes); + } + else + { + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + } } [Theory] @@ -425,7 +506,7 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -485,9 +566,15 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName } [Theory] - [InlineData(123.45)] - [InlineData(-123.45)] - public void HistogramSerializationSingleMetricPoint(double doubleValue) + [InlineData(123.45, true, true)] + [InlineData(123.45, true, false)] + [InlineData(123.45, false, true)] + [InlineData(123.45, false, false)] + [InlineData(-123.45, true, true)] + [InlineData(-123.45, true, false)] + [InlineData(-123.45, false, true)] + [InlineData(-123.45, false, false)] + public void HistogramSerializationSingleMetricPoint(double doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace) { using var meter = new Meter(nameof(this.HistogramSerializationSingleMetricPoint), "0.0.1"); @@ -497,8 +584,23 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue) TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; + Dictionary resourceAttributes = new Dictionary + { + { "TestResourceKey", "TestResourceValue" }, + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, + }; + + string expectedAccount = "TestAccount"; + string expectedNamespace = "TestNameSpace"; + Dictionary accountAndNamespace = new Dictionary + { + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, + }; + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() - .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + .AddAttributes(resourceAttributes); using var meterProvider = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) @@ -513,7 +615,8 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue) var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -527,7 +630,7 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue) Assert.NotNull(request.ResourceMetrics[0].Resource); - AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + AssertOtlpAttributes(addAccountAndNamespace ? resourceAttributes.Concat(accountAndNamespace) : resourceAttributes, request.ResourceMetrics[0].Resource.Attributes); Assert.Single(request.ResourceMetrics[0].ScopeMetrics); @@ -586,7 +689,14 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue) Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + if (addPrepopulatedDimensions) + { + AssertOtlpAttributes(this.TagList.Concat(prepopulatedMetricDimensions), dataPoint.Attributes); + } + else + { + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + } } [Theory] @@ -633,7 +743,7 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -711,11 +821,23 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) } [Theory] - [InlineData("longGauge", 123L, null)] - [InlineData("doubleGauge", null, 123.45)] - [InlineData("longGauge", -123L, null)] - [InlineData("doubleGauge", null, -123.45)] - public void GaugeSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue) + [InlineData("longGuage", 123L, null, true, true)] + [InlineData("longGuage", 123L, null, true, false)] + [InlineData("longGuage", 123L, null, false, true)] + [InlineData("longGuage", 123L, null, false, false)] + [InlineData("doubleGuage", null, 123.45, true, true)] + [InlineData("doubleGuage", null, 123.45, true, false)] + [InlineData("doubleGuage", null, 123.45, false, true)] + [InlineData("doubleGuage", null, 123.45, false, false)] + [InlineData("longGuage", -123L, null, true, true)] + [InlineData("longGuage", -123L, null, true, false)] + [InlineData("longGuage", -123L, null, false, true)] + [InlineData("longGuage", -123L, null, false, false)] + [InlineData("doubleGuage", null, -123.45, true, true)] + [InlineData("doubleGuage", null, -123.45, true, false)] + [InlineData("doubleGuage", null, -123.45, false, true)] + [InlineData("doubleGuage", null, -123.45, false, false)] + public void GaugeSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace) { using var meter = new Meter(nameof(this.GaugeSerializationSingleMetricPoint), "0.0.1"); @@ -725,8 +847,23 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; + Dictionary resourceAttributes = new Dictionary + { + { "TestResourceKey", "TestResourceValue" }, + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, + }; + + string expectedAccount = "TestAccount"; + string expectedNamespace = "TestNameSpace"; + Dictionary accountAndNamespace = new Dictionary + { + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, + }; + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() - .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + .AddAttributes(resourceAttributes); using var meterProvider = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.GaugeSerializationSingleMetricPoint)) @@ -757,7 +894,8 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -771,7 +909,7 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon Assert.NotNull(request.ResourceMetrics[0].Resource); - AssertOtlpAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")], request.ResourceMetrics[0].Resource.Attributes); + AssertOtlpAttributes(addAccountAndNamespace ? resourceAttributes.Concat(accountAndNamespace) : resourceAttributes, request.ResourceMetrics[0].Resource.Attributes); Assert.Single(request.ResourceMetrics[0].ScopeMetrics); @@ -809,7 +947,14 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); - AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + if (addPrepopulatedDimensions) + { + AssertOtlpAttributes(this.TagList.Concat(prepopulatedMetricDimensions), dataPoint.Attributes); + } + else + { + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + } } [Theory] @@ -880,7 +1025,7 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -940,7 +1085,6 @@ internal static void AssertOtlpAttributes( RepeatedField actual) { var expectedAttributes = expected.ToList(); - int expectedSize = 0; int expectedAttributesCount = expectedAttributes.Count; for (int i = 0; i < expectedAttributesCount; i++) { @@ -949,10 +1093,9 @@ internal static void AssertOtlpAttributes( Assert.Equal(expectedAttributes[i].Key, actual[i].Key); Assert.Equal(expectedAttributes[i].Key, actual[i].Key); AssertOtlpAttributeValue(current, actual[i].Value); - expectedSize++; } - Assert.Equal(expectedSize, actual.Count); + Assert.Equal(expectedAttributesCount, actual.Count); } private static void AssertOtlpAttributeValue(object expected, OtlpCommon.AnyValue actual) From 4b09cf600efa18c0eced3c1ec18436f41994e5c7 Mon Sep 17 00:00:00 2001 From: Stanislav Perekrestov Date: Thu, 18 Apr 2024 20:25:27 +0200 Subject: [PATCH 1013/1499] [Exporter.Stackdriver] Fixes the case when Activity/ActivityLink has several Tags with the same key (#1660) --- .../CHANGELOG.md | 3 + .../Implementation/ActivityExtensions.cs | 26 +++---- .../ActivityExtensionsTest.cs | 71 +++++++++++++++++++ 3 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index a1b05e99c8..dcc0a9aa09 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -4,6 +4,9 @@ * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Fixes an issue when Activity/ActivityLink tags contain duplicate tag keys + that lead to ArgumentException. + ([#1660](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1660)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 7e44d7a302..ac50447e2a 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -67,15 +67,12 @@ public static Span ToSpan(this Activity activity, string projectId) // Span Attributes if (activity.Tags != null) { - span.Attributes = new Span.Types.Attributes + span.Attributes = new Span.Types.Attributes(); + var attrMap = span.Attributes.AttributeMap; + foreach (var att in activity.Tags) { - AttributeMap = - { - activity.Tags.ToDictionary( - s => s.Key, - s => s.Value.ToAttributeValue()), - }, - }; + attrMap[att.Key] = att.Value.ToAttributeValue(); + } } // StackDriver uses different labels that are used to categorize spans @@ -102,15 +99,12 @@ public static Span.Types.Link ToLink(this ActivityLink link) if (link.Tags != null) { - ret.Attributes = new Span.Types.Attributes + ret.Attributes = new Span.Types.Attributes(); + var attrMap = ret.Attributes.AttributeMap; + foreach (var att in link.Tags) { - AttributeMap = - { - link.Tags.ToDictionary( - att => att.Key, - att => att.Value?.ToAttributeValue()), - }, - }; + attrMap[att.Key] = att.Value.ToAttributeValue(); + } } return ret; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs new file mode 100644 index 0000000000..0efd380492 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs @@ -0,0 +1,71 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using OpenTelemetry.Exporter.Stackdriver.Implementation; +using Xunit; + +namespace OpenTelemetry.Exporter.Stackdriver.Tests; + +public class ActivityExtensionsTest +{ + static ActivityExtensionsTest() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + Activity.ForceDefaultIdFormat = true; + + var listener = new ActivityListener + { + ShouldListenTo = _ => true, + Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllData, + }; + + ActivitySource.AddActivityListener(listener); + } + + [Fact] + public void ActivityExtensions_Export_Duplicate_Activity_Tag_Key() + { + var activity = new Activity("Test"); + activity.SetStartTime(activity.StartTimeUtc.ToUniversalTime()); + + activity.AddTag("key", "value"); + activity.AddTag("key2", "value2"); + activity.AddTag("key2", "value3"); + + var span = activity.ToSpan("project1"); + Assert.True(span.Attributes.AttributeMap.Count == 2); + Assert.True(span.Attributes.AttributeMap["key2"].StringValue.Value == "value3"); + } + + [Fact] + public void ActivityExtensions_Export_Duplicate_ActivityLink_Tag_Key() + { + var traceId = ActivityTraceId.CreateRandom(); + var spanId1 = ActivitySpanId.CreateRandom(); + var spanId2 = ActivitySpanId.CreateRandom(); + + ActivityContext context1 = new ActivityContext(traceId, spanId1, ActivityTraceFlags.Recorded, isRemote: true); + ActivityContext context2 = new ActivityContext(traceId, spanId2, ActivityTraceFlags.Recorded, isRemote: true); + + KeyValuePair[] dupTags = new[] + { + new KeyValuePair("key1", "value1"), + new KeyValuePair("key2", "value2"), + new KeyValuePair("key1", "value3"), + }; + ActivityLink link1 = new ActivityLink(context1, tags: new ActivityTagsCollection(dupTags)); + ActivityLink link2 = new ActivityLink(context2); + + var links = new List { link1, link2 }; + + using var source = new ActivitySource("TestActivitySource"); + using var activity = source.StartActivity("NewActivityWithLinks", ActivityKind.Internal, parentContext: default, links: links); + + var span = activity?.ToSpan("project1"); + Assert.True((span?.Links.Link.Count ?? 0) == 2); + Assert.True(span?.Links.Link.First().Attributes.AttributeMap["key1"].StringValue.Value == "value3"); + } +} From 79542dcb57958abab8cb44f95aa32710d63208ea Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 18 Apr 2024 17:36:50 -0700 Subject: [PATCH 1014/1499] [Exporter.Geneva][Otlp protobuf] Add logging for serialization exception (#1661) --- .../Internal/ExporterEventSource.cs | 17 ++++++ .../OtlpProtobufMetricExporter.cs | 8 +-- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 53 +++++++++---------- .../OtlpProtobufMetricExporterTests.cs | 1 - 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 3993493c73..693885f918 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -15,6 +15,7 @@ internal sealed class ExporterEventSource : EventSource private const int EVENT_ID_LOG = 2; // Failed to send Log private const int EVENT_ID_METRIC = 3; // Failed to send Metric private const int EVENT_ID_ERROR = 4; // Other common exporter exceptions + private const int EVENT_ID_OTLP_PROTOBUF_METRIC = 5; // Failed to serialize metric [NonEvent] public void FailedToSendTraceData(Exception ex) @@ -63,6 +64,16 @@ public void ExporterException(string message, Exception ex) } } + [NonEvent] + public void FailedToSerializeMetric(string metricName, Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + // TODO: Do not hit ETW size limit even for external library exception stack. + this.FailedToSerializeMetric(metricName, ex.ToInvariantString()); + } + } + [Event(EVENT_ID_TRACE, Message = "Exporter failed to send trace data. Exception: {0}", Level = EventLevel.Error)] public void FailedToSendTraceData(string error) { @@ -86,4 +97,10 @@ public void ExporterException(string message, string error) { this.WriteEvent(EVENT_ID_ERROR, message, error); } + + [Event(EVENT_ID_OTLP_PROTOBUF_METRIC, Message = "Failed to serialize '{0}' metric, Exception: {1}", Level = EventLevel.Error)] + public void FailedToSerializeMetric(string metricName, string error) + { + this.WriteEvent(EVENT_ID_OTLP_PROTOBUF_METRIC, metricName, error); + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index 1d14586a99..54d3b14cdb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -32,19 +32,15 @@ public OtlpProtobufMetricExporter(Func getResource, ConnectionStringBu public ExportResult Export(in Batch batch) { - var result = ExportResult.Success; - try { - this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.getResource(), batch); + return this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.getResource(), batch); } catch (Exception ex) { ExporterEventSource.Log.ExporterException("Failed to export metrics batch", ex); - result = ExportResult.Failure; + return ExportResult.Failure; } - - return result; } public void Dispose() diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index d7360df42f..37cee1a24c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -47,6 +47,8 @@ internal sealed class OtlpProtobufSerializer private int metricPointValueIndex; + private ExportResult metricExportResult; + internal IMetricDataTransport MetricDataTransport; public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) @@ -92,8 +94,10 @@ public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, Connecti } } - internal void SerializeAndSendMetrics(byte[] buffer, Resource resource, in Batch metricBatch) + internal ExportResult SerializeAndSendMetrics(byte[] buffer, Resource resource, in Batch metricBatch) { + this.metricExportResult = ExportResult.Success; + foreach (var metric in metricBatch) { if (this.scopeMetrics.TryGetValue(metric.MeterName, out var metricList)) @@ -111,6 +115,8 @@ internal void SerializeAndSendMetrics(byte[] buffer, Resource resource, in Batch this.SerializeResourceMetrics(buffer, resource); this.ClearScopeMetrics(); + + return this.metricExportResult; } internal void ClearScopeMetrics() @@ -147,15 +153,8 @@ internal void SerializeResourceMetrics(byte[] buffer, Resource resource) // Reset cursor to write new scopeMetric cursor = this.scopeMetricsValueIndex; - try - { - // Serialize this meter/scope - this.SerializeScopeMetrics(buffer, ref cursor, entry.Key, entry.Value); - } - catch - { - // TODO: log exception. - } + // Serialize this meter/scope + this.SerializeScopeMetrics(buffer, ref cursor, entry.Key, entry.Value); } } } @@ -174,14 +173,7 @@ internal void SerializeScopeMetrics(byte[] buffer, ref int cursor, string scopeN cursor = this.metricValueIndex; // Serialize metrics for the meter/scope - try - { - this.SerializeMetric(buffer, ref cursor, metric); - } - catch - { - // TODO: log exception. - } + this.SerializeMetric(buffer, ref cursor, metric); } // TODO: Serialize schema_url field. @@ -225,9 +217,10 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // Send metricPoint this.SendMetricPoint(buffer, ref cursor); } - catch + catch (Exception ex) { - // TODO: log exception. + this.metricExportResult = ExportResult.Failure; + ExporterEventSource.Log.FailedToSerializeMetric(metric.Name, ex); } } @@ -264,9 +257,10 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // Send metricPoint this.SendMetricPoint(buffer, ref cursor); } - catch + catch (Exception ex) { - // TODO: log exception. + this.metricExportResult = ExportResult.Failure; + ExporterEventSource.Log.FailedToSerializeMetric(metric.Name, ex); } } @@ -296,9 +290,10 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // Send metricPoint this.SendMetricPoint(buffer, ref cursor); } - catch + catch (Exception ex) { - // TODO: log exception. + this.metricExportResult = ExportResult.Failure; + ExporterEventSource.Log.FailedToSerializeMetric(metric.Name, ex); } } @@ -328,9 +323,10 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // Send metricPoint this.SendMetricPoint(buffer, ref cursor); } - catch + catch (Exception ex) { - // TODO: log exception. + this.metricExportResult = ExportResult.Failure; + ExporterEventSource.Log.FailedToSerializeMetric(metric.Name, ex); } } @@ -403,9 +399,10 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // Send metricPoint this.SendMetricPoint(buffer, ref cursor); } - catch + catch (Exception ex) { - // TODO: log exception. + this.metricExportResult = ExportResult.Failure; + ExporterEventSource.Log.FailedToSerializeMetric(metric.Name, ex); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 0e54efa6c5..3635a8ee99 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -1090,7 +1090,6 @@ internal static void AssertOtlpAttributes( { var current = expectedAttributes[i].Value; - Assert.Equal(expectedAttributes[i].Key, actual[i].Key); Assert.Equal(expectedAttributes[i].Key, actual[i].Key); AssertOtlpAttributeValue(current, actual[i].Value); } From baa4a5efc0f760407a3865fa9e7aee61427b7bfb Mon Sep 17 00:00:00 2001 From: Gunnar Liljas Date: Fri, 19 Apr 2024 10:58:14 +0200 Subject: [PATCH 1015/1499] [Instrumentation.OWIN] Bugfix - make Meter and Histogram as a singletons (#1655) --- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 6 ++++++ .../Implementation/OwinInstrumentationMetrics.cs | 9 +++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 92f8480061..3142198e00 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +* Massive memory leak in OwinInstrumentationMetrics addressed. + Made both Meter and Histogram singletons. + ([#1655](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1655)) + ## 1.0.0-rc.5 Released 2024-Apr-17 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs index 0df90fc72d..e5d2280194 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -11,10 +11,7 @@ internal static class OwinInstrumentationMetrics { internal static readonly Assembly Assembly = typeof(OwinInstrumentationMetrics).Assembly; internal static readonly AssemblyName AssemblyName = Assembly.GetName(); - - public static string MeterName => AssemblyName.Name; - - public static Meter Instance => new(MeterName, Assembly.GetPackageVersion()); - - public static Histogram HttpServerDuration => Instance.CreateHistogram("http.server.request.duration", "s", "Duration of HTTP server requests."); + internal static readonly string MeterName = AssemblyName.Name; + internal static readonly Meter Instance = new(MeterName, Assembly.GetPackageVersion()); + internal static readonly Histogram HttpServerDuration = Instance.CreateHistogram("http.server.request.duration", "s", "Duration of HTTP server requests."); } From 6d35c6e513b4fd8299d94569e1e9c8b9e043e032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 19 Apr 2024 12:16:15 +0200 Subject: [PATCH 1016/1499] [Instrumentation.OWIN] Release 1.0.0-rc.6 (#1665) --- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 3142198e00..e97469274a 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.6 + +Released 2024-Apr-19 + * Massive memory leak in OwinInstrumentationMetrics addressed. Made both Meter and Histogram singletons. ([#1655](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1655)) @@ -17,7 +21,6 @@ Released 2024-Apr-17 disable this redaction by setting the environment variable `OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION` to `true`. ([#1656](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1656)) - * `ActivitySource.Version` and `Meter.Version` are set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Updated OpenTelemetry SDK to 1.8.0. From 9e7a1ee90bd76c7b1eb479752108077223ed14c7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 19 Apr 2024 11:56:29 -0700 Subject: [PATCH 1017/1499] [Exporter.Geneva][Otlp protobuf] Rename private preview option (#1667) --- .../Internal/ConnectionStringBuilder.cs | 6 +++--- .../Metrics/GenevaMetricExporter.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index e6310df376..b007e5f4ab 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -75,10 +75,10 @@ public string PrivatePreviewEnableTraceLoggingDynamic set => this._parts[nameof(this.PrivatePreviewEnableTraceLoggingDynamic)] = value; } - public string PrivatePreviewOtlpProtobufMetricExporter + public string PrivatePreviewEnableOtlpProtobufEncoding { - get => this._parts.TryGetValue(nameof(this.PrivatePreviewOtlpProtobufMetricExporter), out var value) ? value : null; - set => this._parts[nameof(this.PrivatePreviewOtlpProtobufMetricExporter)] = value; + get => this._parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) ? value : null; + set => this._parts[nameof(this.PrivatePreviewEnableOtlpProtobufEncoding)] = value; } public string Endpoint diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 85cb80cf53..a80d96d1fd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -42,7 +42,7 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); - if (connectionStringBuilder.PrivatePreviewOtlpProtobufMetricExporter != null && connectionStringBuilder.PrivatePreviewOtlpProtobufMetricExporter.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + if (connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding != null && connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) { var otlpProtobufExporter = new OtlpProtobufMetricExporter( () => { return this.Resource; }, From 972cc66a43ff3616722f1c27d3feac95d35ca19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 19 Apr 2024 22:30:44 +0200 Subject: [PATCH 1018/1499] Sync Shared/ActivityInstrumentationHelper (#1663) --- src/Shared/ActivityInstrumentationHelper.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/Shared/ActivityInstrumentationHelper.cs b/src/Shared/ActivityInstrumentationHelper.cs index cf7b926dcd..31418f1642 100644 --- a/src/Shared/ActivityInstrumentationHelper.cs +++ b/src/Shared/ActivityInstrumentationHelper.cs @@ -6,7 +6,6 @@ #pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Diagnostics; -using System.Linq.Expressions; #pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Instrumentation; @@ -18,17 +17,13 @@ internal static class ActivityInstrumentationHelper private static Action CreateActivitySourceSetter() { - ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance"); - ParameterExpression propertyValue = Expression.Parameter(typeof(ActivitySource), "propertyValue"); - var body = Expression.Assign(Expression.Property(instance, "Source"), propertyValue); - return Expression.Lambda>(body, instance, propertyValue).Compile(); + return (Action)typeof(Activity).GetProperty("Source") + .SetMethod.CreateDelegate(typeof(Action)); } private static Action CreateActivityKindSetter() { - ParameterExpression instance = Expression.Parameter(typeof(Activity), "instance"); - ParameterExpression propertyValue = Expression.Parameter(typeof(ActivityKind), "propertyValue"); - var body = Expression.Assign(Expression.Property(instance, "Kind"), propertyValue); - return Expression.Lambda>(body, instance, propertyValue).Compile(); + return (Action)typeof(Activity).GetProperty("Kind") + .SetMethod.CreateDelegate(typeof(Action)); } } From 6263dc5489f9aefc67e522a1cd1bef7991c4c3bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 19 Apr 2024 22:39:56 +0200 Subject: [PATCH 1019/1499] Sync Shared listeners (#1664) --- ...searchRequestPipelineDiagnosticListener.cs | 197 ++++++++++-------- .../EntityFrameworkDiagnosticListener.cs | 4 +- .../QuartzDiagnosticListener.cs | 80 ++++--- src/Shared/DiagnosticSourceListener.cs | 21 +- src/Shared/DiagnosticSourceSubscriber.cs | 8 +- src/Shared/ListenerHandler.cs | 36 +--- 6 files changed, 172 insertions(+), 174 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index facca350b5..e706dcf14a 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -46,7 +46,111 @@ public ElasticsearchRequestPipelineDiagnosticListener(ElasticsearchClientInstrum this.options = options; } - public override void OnStartActivity(Activity activity, object payload) + public override void OnEventWritten(string name, object payload) + { + var activity = Activity.Current; + Guard.ThrowIfNull(activity); + switch (name) + { + case "CallElasticsearch.Start": + this.OnStartActivity(activity, payload); + break; + case "CallElasticsearch.Stop": + this.OnStopActivity(activity, payload); + break; + } + } + + private static string GetDisplayName(Activity activity, object method, string elasticType = null) + { + switch (activity.OperationName) + { + case "Ping": + return "Elasticsearch Ping"; + case "CallElasticsearch" when method != null: + { + var methodName = MethodNameCache.GetOrAdd(method, $"Elasticsearch {method}"); + if (elasticType == null) + { + return methodName; + } + + return $"{methodName} {elasticType}"; + } + + default: + return "Elasticsearch"; + } + } + + private static string GetElasticIndex(Uri uri) + { + // first segment is always / + if (uri.Segments.Length < 2) + { + return null; + } + + // operations starting with _ are not indices (_cat, _search, etc) + if (uri.Segments[1].StartsWith("_", StringComparison.Ordinal)) + { + return null; + } + + var elasticType = Uri.UnescapeDataString(uri.Segments[1]); + + // multiple indices used, return null to avoid high cardinality + if (elasticType.Contains(',')) + { + return null; + } + + if (elasticType.EndsWith("/", StringComparison.Ordinal)) + { + elasticType = elasticType.Substring(0, elasticType.Length - 1); + } + + return elasticType; + } + + private string ParseAndFormatRequest(string debugInformation) + { + if (!this.options.ParseAndFormatRequest) + { + return debugInformation; + } + + var request = ParseRequest.Match(debugInformation); + if (request.Success) + { + string body = request.Groups[1]?.Value?.Trim(); + if (body == null) + { + return debugInformation; + } + + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(body)); + if (!JsonDocument.TryParseValue(ref reader, out var doc)) + { + return debugInformation; + } + + using (doc) + using (var stream = new MemoryStream()) + { + using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); + doc.WriteTo(writer); + writer.Flush(); + body = Encoding.UTF8.GetString(stream.ToArray()); + } + + return body; + } + + return debugInformation; + } + + private void OnStartActivity(Activity activity, object payload) { // By this time, samplers have already run and // activity.IsAllDataRequested populated accordingly. @@ -119,7 +223,7 @@ public override void OnStartActivity(Activity activity, object payload) } } - public override void OnStopActivity(Activity activity, object payload) + private void OnStopActivity(Activity activity, object payload) { if (activity.IsAllDataRequested) { @@ -190,93 +294,4 @@ public override void OnStopActivity(Activity activity, object payload) } } } - - private static string GetDisplayName(Activity activity, object method, string elasticType = null) - { - switch (activity.OperationName) - { - case "Ping": - return "Elasticsearch Ping"; - case "CallElasticsearch" when method != null: - { - var methodName = MethodNameCache.GetOrAdd(method, $"Elasticsearch {method}"); - if (elasticType == null) - { - return methodName; - } - - return $"{methodName} {elasticType}"; - } - - default: - return "Elasticsearch"; - } - } - - private static string GetElasticIndex(Uri uri) - { - // first segment is always / - if (uri.Segments.Length < 2) - { - return null; - } - - // operations starting with _ are not indices (_cat, _search, etc) - if (uri.Segments[1].StartsWith("_", StringComparison.Ordinal)) - { - return null; - } - - var elasticType = Uri.UnescapeDataString(uri.Segments[1]); - - // multiple indices used, return null to avoid high cardinality - if (elasticType.Contains(',')) - { - return null; - } - - if (elasticType.EndsWith("/", StringComparison.Ordinal)) - { - elasticType = elasticType.Substring(0, elasticType.Length - 1); - } - - return elasticType; - } - - private string ParseAndFormatRequest(string debugInformation) - { - if (!this.options.ParseAndFormatRequest) - { - return debugInformation; - } - - var request = ParseRequest.Match(debugInformation); - if (request.Success) - { - string body = request.Groups[1]?.Value?.Trim(); - if (body == null) - { - return debugInformation; - } - - var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(body)); - if (!JsonDocument.TryParseValue(ref reader, out var doc)) - { - return debugInformation; - } - - using (doc) - using (var stream = new MemoryStream()) - { - using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); - doc.WriteTo(writer); - writer.Flush(); - body = Encoding.UTF8.GetString(stream.ToArray()); - } - - return body; - } - - return debugInformation; - } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 3bc5ee2039..9168ef9e39 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -50,8 +50,10 @@ public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstr public override bool SupportsNullActivity => true; - public override void OnCustom(string name, Activity? activity, object? payload) + public override void OnEventWritten(string name, object? payload) { + Activity? activity = Activity.Current; + switch (name) { case EntityFrameworkCoreCommandCreated: diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 0a0d9d34f3..8c448f67b5 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -29,9 +29,55 @@ public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions this.options = options; } - public override void OnStartActivity(Activity? activity, object? payload) + public override void OnEventWritten(string name, object? payload) { + Activity? activity = Activity.Current; Guard.ThrowIfNull(activity); + switch (name) + { + case "Quartz.Job.Execute.Start": + case "Quartz.Job.Veto.Start": + this.OnStartActivity(activity, payload); + break; + case "Quartz.Job.Execute.Stop": + case "Quartz.Job.Veto.Stop": + this.OnStopActivity(activity, payload); + break; + case "Quartz.Job.Execute.Exception": + case "Quartz.Job.Veto.Exception": + this.OnException(activity, payload); + break; + } + } + + private static string GetDisplayName(Activity activity) + { + return activity.OperationName switch + { + OperationName.Job.Execute => $"execute {GetTag(activity.Tags, TagName.JobName)}", + OperationName.Job.Veto => $"veto {GetTag(activity.Tags, TagName.JobName)}", + _ => activity.DisplayName, + }; + } + + private static ActivityKind GetActivityKind(Activity activity) + { + return activity.OperationName switch + { + OperationName.Job.Execute => ActivityKind.Internal, + OperationName.Job.Veto => ActivityKind.Internal, + _ => activity.Kind, + }; + } + + private static string? GetTag(IEnumerable> tags, string tagName) + { + var tag = tags.SingleOrDefault(kv => kv.Key == tagName); + return tag.Value; + } + + private void OnStartActivity(Activity activity, object? payload) + { if (activity.IsAllDataRequested) { if (!this.options.TracedOperations.Contains(activity.OperationName)) @@ -61,9 +107,8 @@ public override void OnStartActivity(Activity? activity, object? payload) } } - public override void OnStopActivity(Activity? activity, object? payload) + private void OnStopActivity(Activity activity, object? payload) { - Guard.ThrowIfNull(activity); if (activity.IsAllDataRequested) { try @@ -81,9 +126,8 @@ public override void OnStopActivity(Activity? activity, object? payload) } } - public override void OnException(Activity? activity, object? payload) + private void OnException(Activity activity, object? payload) { - Guard.ThrowIfNull(activity); if (activity.IsAllDataRequested) { var exc = payload as Exception; @@ -110,30 +154,4 @@ public override void OnException(Activity? activity, object? payload) } } } - - private static string GetDisplayName(Activity activity) - { - return activity.OperationName switch - { - OperationName.Job.Execute => $"execute {GetTag(activity.Tags, TagName.JobName)}", - OperationName.Job.Veto => $"veto {GetTag(activity.Tags, TagName.JobName)}", - _ => activity.DisplayName, - }; - } - - private static ActivityKind GetActivityKind(Activity activity) - { - return activity.OperationName switch - { - OperationName.Job.Execute => ActivityKind.Internal, - OperationName.Job.Veto => ActivityKind.Internal, - _ => activity.Kind, - }; - } - - private static string? GetTag(IEnumerable> tags, string tagName) - { - var tag = tags.SingleOrDefault(kv => kv.Key == tagName); - return tag.Value; - } } diff --git a/src/Shared/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs index db48fc0418..45368a2ee2 100644 --- a/src/Shared/DiagnosticSourceListener.cs +++ b/src/Shared/DiagnosticSourceListener.cs @@ -16,9 +16,9 @@ internal sealed class DiagnosticSourceListener : IObserver logUnknownException; + private readonly Action? logUnknownException; - public DiagnosticSourceListener(ListenerHandler handler, Action logUnknownException) + public DiagnosticSourceListener(ListenerHandler handler, Action? logUnknownException) { Guard.ThrowIfNull(handler); @@ -43,22 +43,7 @@ public void OnNext(KeyValuePair value) try { - if (value.Key.EndsWith("Start", StringComparison.Ordinal)) - { - this.handler.OnStartActivity(Activity.Current, value.Value); - } - else if (value.Key.EndsWith("Stop", StringComparison.Ordinal)) - { - this.handler.OnStopActivity(Activity.Current, value.Value); - } - else if (value.Key.EndsWith("Exception", StringComparison.Ordinal)) - { - this.handler.OnException(Activity.Current, value.Value); - } - else - { - this.handler.OnCustom(value.Key, Activity.Current, value.Value); - } + this.handler.OnEventWritten(value.Key, value.Value); } catch (Exception ex) { diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index 3e2cc66609..626fa46c89 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -25,7 +25,7 @@ internal sealed class DiagnosticSourceSubscriber : IDisposable, IObserver isEnabledFilter, + Func? isEnabledFilter, Action logUnknownException) : this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter, logUnknownException) { @@ -82,6 +82,12 @@ public void OnError(Exception error) /// public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) { if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 1) { diff --git a/src/Shared/ListenerHandler.cs b/src/Shared/ListenerHandler.cs index 33a80a1dc6..299146eb74 100644 --- a/src/Shared/ListenerHandler.cs +++ b/src/Shared/ListenerHandler.cs @@ -1,10 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; +#nullable enable + namespace OpenTelemetry.Instrumentation; /// @@ -16,7 +16,7 @@ internal abstract class ListenerHandler /// Initializes a new instance of the class. /// /// The name of the . - protected ListenerHandler(string sourceName) + public ListenerHandler(string sourceName) { this.SourceName = sourceName; } @@ -31,40 +31,12 @@ protected ListenerHandler(string sourceName) /// public virtual bool SupportsNullActivity { get; } - /// - /// Method called for an event with the suffix 'Start'. - /// - /// The to be started. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnStartActivity(Activity? activity, object? payload) - { - } - - /// - /// Method called for an event with the suffix 'Stop'. - /// - /// The to be stopped. - /// An object that represent the value being passed as a payload for the event. - public virtual void OnStopActivity(Activity? activity, object? payload) - { - } - - /// - /// Method called for an event with the suffix 'Exception'. - /// - /// The . - /// An object that represent the value being passed as a payload for the event. - public virtual void OnException(Activity? activity, object? payload) - { - } - /// /// Method called for an event which does not have 'Start', 'Stop' or 'Exception' as suffix. /// /// Custom name. - /// The to be processed. /// An object that represent the value being passed as a payload for the event. - public virtual void OnCustom(string name, Activity? activity, object? payload) + public virtual void OnEventWritten(string name, object? payload) { } } From ab7bdabacb8907b1745ecdc2ee7544a681989e6c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 19 Apr 2024 15:37:20 -0700 Subject: [PATCH 1020/1499] Disable metric name validation for otlp format (#1669) --- .../Metrics/GenevaMetricExporter.cs | 5 +++++ .../Metrics/TlvMetricExporter.cs | 5 ----- .../GenevaMetricExporterTests.cs | 12 +++++++----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index a80d96d1fd..f5f3b30800 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -42,6 +42,11 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); + if (connectionStringBuilder.DisableMetricNameValidation) + { + DisableOpenTelemetrySdkMetricNameValidation(); + } + if (connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding != null && connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) { var otlpProtobufExporter = new OtlpProtobufMetricExporter( diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 2e25728b59..00eaf87708 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -73,11 +73,6 @@ internal TlvMetricExporter(ConnectionStringBuilder connectionStringBuilder, IRea { this.fixedPayloadStartIndex = sizeof(BinaryHeader); } - - if (connectionStringBuilder.DisableMetricNameValidation) - { - GenevaMetricExporter.DisableOpenTelemetrySdkMetricNameValidation(); - } } internal ExportResult Export(in Batch batch) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 5524e51a14..6d220f4d2f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -282,9 +282,11 @@ private void EmitMetrics(string attempt) } [Theory] - [InlineData(true)] - [InlineData(false)] - public void DisableMetricNameValidationTest(bool disableMetricNameValidation) + [InlineData(true, false)] + [InlineData(false, false)] + [InlineData(true, true)] + [InlineData(false, true)] + public void DisableMetricNameValidationTest(bool disableMetricNameValidation, bool enableOtlpProtobufexporter) { var instrumentNameRegexProperty = GenevaMetricExporter.GetOpenTelemetryInstrumentNameRegexProperty(); var initialInstrumentNameRegexValue = instrumentNameRegexProperty.GetValue(null); @@ -301,12 +303,12 @@ public void DisableMetricNameValidationTest(bool disableMetricNameValidation) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation};PrivatePreviewOtlpProtobufMetricExporter={enableOtlpProtobufexporter}"; } else { var path = GenerateTempFilePath(); - options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation};PrivatePreviewOtlpProtobufMetricExporter={enableOtlpProtobufexporter}"; var endpoint = new UnixDomainSocketEndPoint(path); server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); From 4ffcf2fae5822107a996ee36e2fe7a6ceba06f7c Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 19 Apr 2024 18:26:58 -0500 Subject: [PATCH 1021/1499] [OneCollectorExporter] Resolve AOT warnings in OpenTelemetry.Exporter.OneCollector (#1670) Co-authored-by: Mikel Blanchard --- .github/workflows/ci.yml | 1 + build/Common.props | 1 + src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 3 +++ .../Internal/OneCollectorExporterEventSource.cs | 12 ++++++++++++ .../OpenTelemetry.Exporter.OneCollector.csproj | 8 ++++++++ .../OpenTelemetry.AotCompatibility.TestApp.csproj | 1 + 6 files changed, 26 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 634dca703b..14e4b23cca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -362,6 +362,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'aot') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'onecollector') || contains(needs.detect-changes.outputs.changes, 'redis') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/verifyaotcompat.yml diff --git a/build/Common.props b/build/Common.props index 7fb650cad6..55231330b9 100644 --- a/build/Common.props +++ b/build/Common.props @@ -30,6 +30,7 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [5.0.0,6.0) + [8.0.1,) [2.1.0,5.0) [3.1.0,) [1.0.3,2.0) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index c0cb3f6bfb..a273bb5c99 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Native AOT compatibility. + ([#1670](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1670)) + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index 7813989c9a..9543edb200 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; using OpenTelemetry.Internal; @@ -76,12 +79,18 @@ public void ExportExceptionThrown(string itemType, string exception) } [Event(2, Message = "Sent '{0}' batch of {1} item(s) to '{2}' transport.", Level = EventLevel.Informational)] +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] +#endif public void TransportDataSent(string itemType, int numberOfRecords, string transportDescription) { this.WriteEvent(2, itemType, numberOfRecords, transportDescription); } [Event(3, Message = "Wrote '{0}' batch of {1} item(s) to '{2}' sink.", Level = EventLevel.Informational)] +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] +#endif public void SinkDataWritten(string itemType, int numberOfRecords, string sinkDescription) { this.WriteEvent(3, itemType, numberOfRecords, sinkDescription); @@ -100,6 +109,9 @@ public void TransportExceptionThrown(string transportType, string exception) } [Event(6, Message = "Error response received by '{0}' transport. StatusCode: {1}, ErrorMessage: '{2}', ErrorDetails: '{3}'", Level = EventLevel.Error)] +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] +#endif public void HttpTransportErrorResponseReceived(string transportType, int statusCode, string errorMessage, string errorDetails) { this.WriteEvent(6, transportType, statusCode, errorMessage, errorDetails); diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index e83ba75596..8fb04b0100 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -8,11 +8,19 @@ $(TargetFrameworks);net462 Exporter.OneCollector- true + true + + $(NoWarn);SYSLIB1100;SYSLIB1101 + diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index f982a95588..58c82396da 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -13,6 +13,7 @@ When adding projects here please also update the verify-aot-compat job in .github\workflows\ci.yml so that it runs for the project(s) being added. --> + From 312cd76a98f6326ca7ddf30eb9541e495aa18556 Mon Sep 17 00:00:00 2001 From: Stanislav Perekrestov Date: Mon, 22 Apr 2024 06:39:35 +0200 Subject: [PATCH 1022/1499] exports service.name to StackDriver if the value is present in an instance of OpenTelemetry.Resources.Resource (#1653) --- .../CHANGELOG.md | 5 ++ .../Implementation/ResourceExtensions.cs | 39 +++++++++++++ .../ResourceSemanticConventions.cs | 10 ++++ .../StackdriverTraceExporter.cs | 10 +++- .../ResourceExtensionsTests.cs | 55 +++++++++++++++++++ .../StackdriverExporterTests.cs | 23 ++++++++ .../TestTraceServiceClient.cs | 5 ++ 7 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceExtensions.cs create mode 100644 src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceSemanticConventions.cs create mode 100644 test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index dcc0a9aa09..b32b511b3f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -7,6 +7,11 @@ * Fixes an issue when Activity/ActivityLink tags contain duplicate tag keys that lead to ArgumentException. ([#1660](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1660)) +* Annotates trace information with `service.name` attribute + if it's present in the resource tags. Please use + `services.ConfigureResource(r => r.AddService("my-service", "1.0.0"))` + to add the service name and version. + ([#1653](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1653)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceExtensions.cs new file mode 100644 index 0000000000..e26e68fbb6 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceExtensions.cs @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using Google.Cloud.Trace.V2; +using OpenTelemetry.Resources; + +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +internal static class ResourceExtensions +{ + private static readonly HashSet ExportableResourceNames = + [ + ResourceSemanticConventions.AttributeServiceName, + ResourceSemanticConventions.AttributeServiceVersion + ]; + + /// + /// Adds resource attributes to the span. + /// + /// Google Cloud Trace Span to be annotated. + /// + /// The Resource contains attributes such as "service.name" that provide metadata about the service being traced. + /// These attributes are used to annotate the Google Cloud Trace Span, enhancing the trace data available in the Google + /// Trace Explorer UI. + /// + public static void AnnotateWith(this Span span, Resource resource) + { + span.Attributes ??= new Span.Types.Attributes(); + foreach (var attr in resource.Attributes) + { + var attributeMap = span.Attributes.AttributeMap; + if (ExportableResourceNames.Contains(attr.Key) && !attributeMap.ContainsKey(attr.Key)) + { + attributeMap.Add(attr.Key, attr.Value.ToAttributeValue()); + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceSemanticConventions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceSemanticConventions.cs new file mode 100644 index 0000000000..b9b1b59a39 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ResourceSemanticConventions.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Exporter.Stackdriver.Implementation; + +internal class ResourceSemanticConventions +{ + public const string AttributeServiceName = "service.name"; + public const string AttributeServiceVersion = "service.version"; +} diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index eed13a4e15..a940f6e312 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -10,6 +10,7 @@ using Google.Cloud.Trace.V2; using Grpc.Core; using OpenTelemetry.Exporter.Stackdriver.Implementation; +using OpenTelemetry.Resources; namespace OpenTelemetry.Exporter.Stackdriver; @@ -93,12 +94,19 @@ public override ExportResult Export(in Batch batch) ProjectName = this.googleCloudProjectId, }; + Resource? resource = this.ParentProvider?.GetResource(); foreach (var activity in batch) { // It should never happen that the time has no correct kind, only if OpenTelemetry is used incorrectly. if (activity.StartTimeUtc.Kind == DateTimeKind.Utc) { - batchSpansRequest.Spans.Add(activity.ToSpan(this.googleCloudProjectId.ProjectId)); + Span span = activity.ToSpan(this.googleCloudProjectId.ProjectId); + if (resource != null) + { + span.AnnotateWith(resource); + } + + batchSpansRequest.Spans.Add(span); } } diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs new file mode 100644 index 0000000000..651c69a009 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using Google.Cloud.Trace.V2; +using OpenTelemetry.Exporter.Stackdriver.Implementation; +using OpenTelemetry.Resources; +using Xunit; + +namespace OpenTelemetry.Exporter.Stackdriver.Tests; + +public class ResourceExtensionsTests +{ + [Fact] + public void Enriches_Span_Attributes_With_Service_Name() + { + const string serviceName = "some service name"; + const string serviceVersion = "2.3.4"; + var resource = new Resource(new Dictionary + { + ["key1"] = "value1", + ["key2"] = "value2", + [ResourceSemanticConventions.AttributeServiceName] = serviceName, + [ResourceSemanticConventions.AttributeServiceVersion] = serviceVersion, + }); + + var span = new Span(); + span.AnnotateWith(resource); + Assert.Contains(span.Attributes.AttributeMap, kvp => + kvp.Key == ResourceSemanticConventions.AttributeServiceName && + kvp.Value.StringValue.Value == serviceName); + + Assert.Contains(span.Attributes.AttributeMap, kvp => + kvp.Key == ResourceSemanticConventions.AttributeServiceVersion && + kvp.Value.StringValue.Value == serviceVersion); + } + + [Fact] + public void Otel_Resource_Has_No_Service_Name() + { + var resource = new Resource(new Dictionary { ["key1"] = "value1", ["key2"] = "value2" }); + + var span = new Span(); + span.AnnotateWith(resource); + } + + [Fact] + public void Enriches_Span_Attributes_When_Attribute_Already_In_Span() + { + var span = new Span { Attributes = new Span.Types.Attributes() }; + span.Attributes.AttributeMap.Add(ResourceSemanticConventions.AttributeServiceName, "world".ToAttributeValue()); + var resource = new Resource(new Dictionary { [ResourceSemanticConventions.AttributeServiceName] = "world" }); + span.AnnotateWith(resource); + } +} diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 1c583ef7f2..7c6a921d2c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using OpenTelemetry.Exporter.Stackdriver.Implementation; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Xunit; @@ -62,6 +63,28 @@ public void StackdriverExporter_CustomActivityProcessor() Assert.True(endCalled); } + [Fact] + public void StackdriverExporter_WithServiceNameMetadata() + { + const string ActivitySourceName = "stackdriver.test"; + + var traceClient = new TestTraceServiceClient(throwException: false); + var activityExporter = new StackdriverTraceExporter("test_project", traceClient); + + var openTelemetrySdk = Sdk.CreateTracerProviderBuilder() + .AddSource(ActivitySourceName) + .ConfigureResource(r => r.AddService("test-service", "2.3.4")) + .AddProcessor(new BatchActivityExportProcessor(activityExporter)) + .Build(); + + using var source = new ActivitySource(ActivitySourceName); + var activity = source.StartActivity("Test Activity"); + activity?.Stop(); + openTelemetrySdk.ForceFlush(); + Assert.True(traceClient.Spans.Count > 0); + Assert.True(traceClient.Spans.All(s => s.Attributes.AttributeMap.ContainsKey(ResourceSemanticConventions.AttributeServiceName))); + } + [Fact] public void StackdriverExporter_TraceClientThrows_ExportResultFailure() { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs index e71310a487..c7122424ab 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Generic; using Google.Api.Gax.Grpc; using Google.Cloud.Trace.V2; using Grpc.Core; @@ -11,11 +12,15 @@ internal class TestTraceServiceClient(bool throwException) : TraceServiceClient { private readonly bool throwException = throwException; + public List Spans { get; } = new List(); + public override void BatchWriteSpans(BatchWriteSpansRequest request, CallSettings callSettings) { if (this.throwException) { throw new RpcException(Status.DefaultCancelled); } + + this.Spans.AddRange(request.Spans); } } From 2e17816033ad14ba25474d245db17797efc470cc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sun, 21 Apr 2024 21:50:26 -0700 Subject: [PATCH 1023/1499] [repo] Port public api file improvements from the main repo (#1671) --- build/Common.prod.props | 17 ++++++++++++----- build/Common.props | 2 +- .../.publicApi/net462/PublicAPI.Unshipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 ++- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + .../netstandard2.1/PublicAPI.Unshipped.txt | 1 + .../.publicApi/net462/PublicAPI.Unshipped.txt | 1 + 8 files changed, 20 insertions(+), 7 deletions(-) diff --git a/build/Common.prod.props b/build/Common.prod.props index 45b492423b..3661b1c333 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -52,12 +52,19 @@ true - - - - - + + + + + + + + + + diff --git a/build/Common.props b/build/Common.props index 55231330b9..4334900d5e 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,7 +35,7 @@ [3.1.0,) [1.0.3,2.0) [4.2.2,5.0) - [3.3.4] + [3.11.0-beta1.23525.2] [8.0.0,9.0) [1.8.0,2.0) [1.8.0-rc.1] diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt index ebfc0b119f..dc36291b53 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool +virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt index 73417f39e7..dc36291b53 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool \ No newline at end of file +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool +virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt index ebfc0b119f..dc36291b53 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool +virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index ebfc0b119f..dc36291b53 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool +virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index ebfc0b119f..dc36291b53 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool +virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt index 3572fe9e04..ab28fe9ed9 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt @@ -17,3 +17,4 @@ static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumenta static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAspNetInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.EnrichFunc.Invoke(System.Web.HttpContext! context, ref System.Diagnostics.TagList tags) -> void From 448d9e29a2eb87a10bffd3f259cea4d20329944c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 22 Apr 2024 01:16:17 -0700 Subject: [PATCH 1024/1499] Upgrade OpenTelemetry SDK to 1.8.1 (#1668) --- build/Common.props | 2 +- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.Instana/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Extensions/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 4 ++-- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 6 +++--- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md | 4 ++-- src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md | 3 +++ src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md | 2 ++ src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 6 +++--- 28 files changed, 69 insertions(+), 31 deletions(-) diff --git a/build/Common.props b/build/Common.props index 4334900d5e..358fe0ba41 100644 --- a/build/Common.props +++ b/build/Common.props @@ -37,7 +37,7 @@ [4.2.2,5.0) [3.11.0-beta1.23525.2] [8.0.0,9.0) - [1.8.0,2.0) + [1.8.1,2.0) [1.8.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 9ec3ce8421..9ee7790475 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,8 +6,8 @@ is disposed. ([#1537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1537)) -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.7.0 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index c8e51b26d7..cd581033a3 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Updates OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.0.0-alpha.3 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index cea99f2b9d..1ecd8030b1 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -2,11 +2,11 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.0.3 diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index a273bb5c99..7417e84d68 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -5,8 +5,8 @@ * Native AOT compatibility. ([#1670](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1670)) -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.6.0 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index b32b511b3f..aefeda1a1c 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,11 +2,11 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * Fixes an issue when Activity/ActivityLink tags contain duplicate tag keys that lead to ArgumentException. ([#1660](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1660)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) * Annotates trace information with `service.name` attribute if it's present in the resource tags. Please use `services.ConfigureResource(r => r.AddService("my-service", "1.0.0"))` diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 93e9b54b7c..4dfb89f237 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 9f05100c20..83e698517d 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -5,8 +5,8 @@ * Add LogToActivityEventConversionOptions.Filter callback ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.0.0-beta.4 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index b1c1f42a50..102e86b315 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.8.0-beta.1 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index bf4120624c..db0a98ed36 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,10 +2,10 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index e9f9242c3a..f38801644e 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -2,12 +2,12 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * Span status is set based on [semantic convention for client spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status). ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 46907d6b65..0d736121d2 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-beta.11 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 0bf1e9130a..5e93613509 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -2,10 +2,10 @@ ## Unreleased -* Update `OpenTelemetry.Api` to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.5.1-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index c82d672bcf..7c0dfb63fe 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -6,10 +6,10 @@ ([#483](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/483)) * Update minimal supported version of `Google.Protobuf` to `3.15.0`. ([#1456](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1456)) -* Update `OpenTelemetry.Api` to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 78e9b2aa36..2aacd745b6 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,11 +2,11 @@ ## Unreleased -* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.0`. - * Update `OpenTelemetry.Api` to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. + * Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.6.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index e97469274a..62f21e4d3d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry SDK to 1.8.1. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-rc.6 Released 2024-Apr-19 diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index e0e0b59e5e..a92010eb69 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -9,6 +9,9 @@ (its unit changed from `{threads}` to `{thread}`). ([#1643](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1643)) +* Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 0.5.0-beta.5 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index b0f15815a5..13e7c7ee9c 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-beta.2 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 3e6d864f53..c1559e448b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.8.0 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 74c6012b96..848b28bc53 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-rc9.14 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 7901c76c35..edd0b206a6 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-rc.16 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md index b3e0ded97e..b2e7f28f2e 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md @@ -7,8 +7,8 @@ ([#1552](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1552)) * Implement support for `cloud.resource_id` attribute in AWS ECS detector. ([#1576](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1576)) -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 1.4.0-beta.1 diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md index 6a74ed5007..7c9eaf83ea 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-beta.6 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md index 1010a7b8ee..c02fca6bb9 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 1.0.0-beta.7 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md index bb4526451f..729c7e61d6 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md @@ -5,6 +5,8 @@ * Adds support for `host.id` resource attribute on non-containerized systems. `host.id` will be set per [semantic convention rules](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/host.md) ([#1631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1631)) +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) ## 0.1.0-alpha.3 diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md index 2c3d08dcfc..88b52267a6 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 0.1.0-alpha.3 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md index 031ff73234..bea8688334 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + ## 0.1.0-alpha.3 Released 2024-Apr-05 diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 6ef51f3a3a..6ba90ca9e3 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -8,8 +8,8 @@ Initial release of `OpenTelemetry.Sampler.AWS`. ([#1091](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1091), [#1124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1124)) -* Update OpenTelemetry SDK version to `1.8.0`. - ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) - * Make OpenTelemetry.Sampler.AWS native AoT compatible. ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) + +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) From 86aa6c8e16b569bd30b3062e3bbff28eb87b143a Mon Sep 17 00:00:00 2001 From: Stanislav Perekrestov Date: Mon, 22 Apr 2024 10:18:19 +0200 Subject: [PATCH 1025/1499] [Exporter.Stackdriver] Release 1.0.0-beta.6 (#1674) --- src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index aefeda1a1c..5d912749ed 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.6 + +Released 2024-Apr-22 + * Fixes an issue when Activity/ActivityLink tags contain duplicate tag keys that lead to ArgumentException. ([#1660](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1660)) From 36bd03399611f16d497b0914947dcbd35cab1de2 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 22 Apr 2024 10:14:17 -0700 Subject: [PATCH 1026/1499] [onecollector] Reduce the amount of public api files in project (#1675) --- .../{net462 => }/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 46 ------------------- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 -- .../.publicApi/net7.0/PublicAPI.Shipped.txt | 46 ------------------- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 3 -- .../netstandard2.0/PublicAPI.Shipped.txt | 46 ------------------- .../netstandard2.0/PublicAPI.Unshipped.txt | 3 -- .../netstandard2.1/PublicAPI.Shipped.txt | 46 ------------------- .../netstandard2.1/PublicAPI.Unshipped.txt | 3 -- 10 files changed, 196 deletions(-) rename src/OpenTelemetry.Exporter.OneCollector/.publicApi/{net462 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.OneCollector/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.OneCollector/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index f0571ebcdb..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,46 +0,0 @@ -#nullable enable -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index dc36291b53..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool -virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt deleted file mode 100644 index f0571ebcdb..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,46 +0,0 @@ -#nullable enable -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt deleted file mode 100644 index dc36291b53..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool -virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index f0571ebcdb..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,46 +0,0 @@ -#nullable enable -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index dc36291b53..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool -virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt deleted file mode 100644 index f0571ebcdb..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Shipped.txt +++ /dev/null @@ -1,46 +0,0 @@ -#nullable enable -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.TransportOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString = 1 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.get -> System.Uri! -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.ExceptionStackTraceHandling.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions.OneCollectorLogExporterSerializationOptions() -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureBatchOptions(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureExporter(System.Action!>! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions -override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt deleted file mode 100644 index dc36291b53..0000000000 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool -virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void From d0fa1f08a2986b76f86e1de441280e840ca6c502 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 22 Apr 2024 11:31:45 -0700 Subject: [PATCH 1027/1499] [genevaexporter] Reduce the amount of public api files in project (#1676) --- .../{net462 => }/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 51 ------------------- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 0 .../.publicApi/net8.0/PublicAPI.Shipped.txt | 51 ------------------- .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 51 ------------------- .../netstandard2.0/PublicAPI.Unshipped.txt | 0 8 files changed, 153 deletions(-) rename src/OpenTelemetry.Exporter.Geneva/.publicApi/{net462 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.Geneva/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Geneva/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 33a8b061ff..0000000000 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,51 +0,0 @@ -Microsoft.Extensions.Logging.GenevaLoggingExtensions -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void -OpenTelemetry.Exporter.Geneva.GenevaLogExporter -OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt deleted file mode 100644 index 33a8b061ff..0000000000 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,51 +0,0 @@ -Microsoft.Extensions.Logging.GenevaLoggingExtensions -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void -OpenTelemetry.Exporter.Geneva.GenevaLogExporter -OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/net8.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 33a8b061ff..0000000000 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,51 +0,0 @@ -Microsoft.Extensions.Logging.GenevaLoggingExtensions -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void -OpenTelemetry.Exporter.Geneva.GenevaLogExporter -OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 From 5204eb715c712725cd0e5d0988a5405621460dcf Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 22 Apr 2024 11:39:27 -0700 Subject: [PATCH 1028/1499] [wcf] Reduce the amount of public api files in project (#1677) --- .../PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 30 ------------------- 3 files changed, 30 deletions(-) rename src/OpenTelemetry.Instrumentation.Wcf/.publicApi/{netstandard2.0 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Wcf/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Wcf/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt index 8b2bbfdba2..f36d3a92c1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,19 +1,5 @@ -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveReply = "AfterReceiveReply" -> string! const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.AfterReceiveRequest = "AfterReceiveRequest" -> string! const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendReply = "BeforeSendReply" -> string! -const OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames.BeforeSendRequest = "BeforeSendRequest" -> string! -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.AddBindingParameters(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyClientBehavior(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.ClientRuntime! clientRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.ApplyDispatchBehavior(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.DispatchRuntime! dispatchRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.TelemetryContractBehaviorAttribute() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryContractBehaviorAttribute.Validate(System.ServiceModel.Description.ContractDescription! contractDescription, System.ServiceModel.Description.ServiceEndpoint! endpoint) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.AddBindingParameters(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Channels.BindingParameterCollection! bindingParameters) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyClientBehavior(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.ClientRuntime! clientRuntime) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceEndpoint! endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher! endpointDispatcher) -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.TelemetryEndpointBehavior() -> void -OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehavior.Validate(System.ServiceModel.Description.ServiceEndpoint! endpoint) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.TelemetryEndpointBehaviorExtensionElement() -> void OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior @@ -23,23 +9,7 @@ OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.TelemetryServiceBehav OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehavior.Validate(System.ServiceModel.Description.ServiceDescription! serviceDescription, System.ServiceModel.ServiceHostBase! serviceHostBase) -> void OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.TelemetryServiceBehaviorExtensionElement() -> void -OpenTelemetry.Instrumentation.Wcf.WcfEnrichEventNames -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.get -> System.Func? -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func? -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.get -> bool -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void -OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.WcfInstrumentationOptions() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.BehaviorType.get -> System.Type! override OpenTelemetry.Instrumentation.Wcf.TelemetryEndpointBehaviorExtensionElement.CreateBehavior() -> object! override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.BehaviorType.get -> System.Type! override OpenTelemetry.Instrumentation.Wcf.TelemetryServiceBehaviorExtensionElement.CreateBehavior() -> object! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddWcfInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! From 41207ddd8e49cc5baa05bd332f26d0a4e518f16d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 22 Apr 2024 13:12:16 -0700 Subject: [PATCH 1029/1499] [OneCollector] Update public api files for things released stable in 1.6.0 (#1679) --- .../.publicApi/PublicAPI.Shipped.txt | 3 +++ .../.publicApi/PublicAPI.Unshipped.txt | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt index f0571ebcdb..305d07d5a8 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt @@ -1,6 +1,7 @@ #nullable enable OpenTelemetry.Exporter.OneCollector.OneCollectorExporter OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void @@ -10,6 +11,7 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallba OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.CopyPayloadToStream(System.IO.Stream! destination) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.OneCollectorExporterPayloadTransmittedCallbackArguments() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.PayloadSizeInBytes.get -> long +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.TransportEndpoint.get -> System.Uri! OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore = 0 -> OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType @@ -44,3 +46,4 @@ static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOn static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt index dc36291b53..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt @@ -1,3 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments.Succeeded.get -> bool -virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void From 6d6082b4c15758ec455ad269a82bc0dfef7e8216 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 22 Apr 2024 13:47:28 -0700 Subject: [PATCH 1030/1499] [onecollector] Update CHANGELOG for 1.8.0 release (#1681) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 7417e84d68..6781b8e445 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0 + +Released 2024-Apr-22 + * Native AOT compatibility. ([#1670](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1670)) From d1a7283f1259ddbfe8311fba4bb3819960665c72 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 22 Apr 2024 17:00:17 -0500 Subject: [PATCH 1031/1499] [Exporter.Geneva] Resolve AOT warnings in OpenTelemetry.Exporter.Geneva (#1666) Co-authored-by: Vishwesh Bankwar --- .github/workflows/ci.yml | 1 + src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 3 +++ .../Metrics/GenevaMetricExporter.cs | 18 +++++++++++++++--- .../Transport/MetricEtwDataTransport.cs | 9 +++++++++ .../Transport/EtwDataTransport.cs | 6 ++++++ ...enTelemetry.AotCompatibility.TestApp.csproj | 2 ++ 6 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14e4b23cca..150c7017dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -362,6 +362,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'aot') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'geneva') || contains(needs.detect-changes.outputs.changes, 'onecollector') || contains(needs.detect-changes.outputs.changes, 'redis') || contains(needs.detect-changes.outputs.changes, 'shared') diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 9ee7790475..4b34ca8b2e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Native AOT compatibility. + ([#1666](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1666)) + * Fix a bug in `GenevaMetricExporter` where the `MetricEtwDataTransport` singleton is disposed. ([#1537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1537)) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index f5f3b30800..b2fff46bf6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -11,7 +11,10 @@ namespace OpenTelemetry.Exporter.Geneva; -public class GenevaMetricExporter : BaseExporter +/// +/// An exporter for Geneva metrics. +/// +public partial class GenevaMetricExporter : BaseExporter { internal const int BufferSize = 65360; // the maximum ETW payload (inclusive) @@ -23,6 +26,8 @@ public class GenevaMetricExporter : BaseExporter internal const string DimensionKeyForCustomMetricsNamespace = "_microsoft_metrics_namespace"; + private const string DisableRegexPattern = ".*"; + private readonly IDisposable exporter; private delegate ExportResult ExportMetricsFunc(in Batch batch); @@ -91,7 +96,7 @@ protected override void Dispose(bool disposing) internal static PropertyInfo GetOpenTelemetryInstrumentNameRegexProperty() { - var meterProviderBuilderSdkType = typeof(Sdk).Assembly.GetType("OpenTelemetry.Metrics.MeterProviderBuilderSdk", throwOnError: false) + var meterProviderBuilderSdkType = Type.GetType("OpenTelemetry.Metrics.MeterProviderBuilderSdk, OpenTelemetry", throwOnError: false) ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk type could not be found reflectively."); var instrumentNameRegexProperty = meterProviderBuilderSdkType.GetProperty("InstrumentNameRegex", BindingFlags.Public | BindingFlags.Static) @@ -102,6 +107,13 @@ internal static PropertyInfo GetOpenTelemetryInstrumentNameRegexProperty() internal static void DisableOpenTelemetrySdkMetricNameValidation() { - GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, new Regex(".*", RegexOptions.Compiled)); + GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, GetDisableRegexPattern()); } + +#if NET7_0_OR_GREATER + [GeneratedRegex(DisableRegexPattern)] + private static partial Regex GetDisableRegexPattern(); +#else + private static Regex GetDisableRegexPattern() => new(DisableRegexPattern, RegexOptions.Compiled); +#endif } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 559d1d8b1f..e3a0065df3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif using System.Diagnostics.Tracing; namespace OpenTelemetry.Exporter.Geneva; @@ -24,6 +27,9 @@ private MetricEtwDataTransport() } [NonEvent] +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] +#endif public unsafe void Send(MetricEventType eventType, byte[] data, int size) { var eventDataPtr = stackalloc EventData[1]; @@ -36,6 +42,9 @@ public unsafe void Send(MetricEventType eventType, byte[] data, int size) } [NonEvent] +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] +#endif public unsafe void SendOtlpProtobufEvent(byte[] data, int size) { if (this.IsEnabled()) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index 65d43a3384..b17403699a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -2,6 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif using System.Diagnostics.Tracing; namespace OpenTelemetry.Exporter.Geneva; @@ -24,6 +27,9 @@ public void InformationalEvent() } [NonEvent] +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] +#endif public unsafe void SendEvent(int eventId, byte[] data, int size) { EventData* dataDesc = stackalloc EventData[1]; diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 58c82396da..2e29e2d52c 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -5,6 +5,7 @@ net8.0 true false + true true @@ -13,6 +14,7 @@ When adding projects here please also update the verify-aot-compat job in .github\workflows\ci.yml so that it runs for the project(s) being added. --> + From 99f4fb18852a4bb67f135b3ed4e884f6bef56a89 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Tue, 23 Apr 2024 11:06:10 +0000 Subject: [PATCH 1032/1499] Move existing ServerCertificateValidationHandler to Shared (#1640) --- opentelemetry-dotnet-contrib.sln | 3 ++ .../AWSEKSResourceDetector.cs | 3 +- .../AWSResourcesEventSource.cs | 36 +++++++++++++++---- ...OpenTelemetry.ResourceDetectors.AWS.csproj | 3 ++ ...IServerCertificateValidationEventSource.cs | 17 +++++++++ .../ServerCertificateValidationHandler.cs} | 23 ++++++------ .../ServerCertificateValidationProvider.cs | 29 +++++++-------- ...pServerCertificateValidationEventSource.cs | 27 ++++++++++++++ ...erverCertificateValidationHandlerTests.cs} | 7 ++-- ...erverCertificateValidationProviderTests.cs | 9 +++-- 10 files changed, 115 insertions(+), 42 deletions(-) create mode 100644 src/Shared/IServerCertificateValidationEventSource.cs rename src/{OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs => Shared/ServerCertificateValidationHandler.cs} (52%) rename src/{OpenTelemetry.ResourceDetectors.AWS/Http => Shared}/ServerCertificateValidationProvider.cs (75%) create mode 100644 test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/NoopServerCertificateValidationEventSource.cs rename test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/{HandlerTests.cs => ServerCertificateValidationHandlerTests.cs} (65%) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 1e884823d6..e2de239aec 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -276,6 +276,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\DiagnosticSourceSubscriber.cs = src\Shared\DiagnosticSourceSubscriber.cs src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs src\Shared\Guard.cs = src\Shared\Guard.cs + src\Shared\IServerCertificateValidationEventSource.cs = src\Shared\IServerCertificateValidationEventSource.cs src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs src\Shared\ListenerHandler.cs = src\Shared\ListenerHandler.cs src\Shared\MultiTypePropertyFetcher.cs = src\Shared\MultiTypePropertyFetcher.cs @@ -285,6 +286,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\RedactionHelper.cs = src\Shared\RedactionHelper.cs src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs src\Shared\SemanticConventions.cs = src\Shared\SemanticConventions.cs + src\Shared\ServerCertificateValidationHandler.cs = src\Shared\ServerCertificateValidationHandler.cs + src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs EndProjectSection diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs index a1c560da08..c8a616f2b7 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Net.Http; using System.Text; -using OpenTelemetry.ResourceDetectors.AWS.Http; using OpenTelemetry.ResourceDetectors.AWS.Models; using OpenTelemetry.Resources; @@ -31,7 +30,7 @@ public sealed class AWSEKSResourceDetector : IResourceDetector public Resource Detect() { var credentials = GetEKSCredentials(AWSEKSCredentialPath); - using var httpClientHandler = Handler.Create(AWSEKSCertificatePath); + using var httpClientHandler = ServerCertificateValidationHandler.Create(AWSEKSCertificatePath, AWSResourcesEventSource.Log); if (credentials == null || !IsEKSProcess(credentials, httpClientHandler)) { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs index e34bb70909..b956947a95 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs +++ b/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs @@ -8,10 +8,16 @@ namespace OpenTelemetry.ResourceDetectors.AWS; [EventSource(Name = "OpenTelemetry-ResourceDetectors-AWS")] -internal sealed class AWSResourcesEventSource : EventSource +internal sealed class AWSResourcesEventSource : EventSource, IServerCertificateValidationEventSource { public static AWSResourcesEventSource Log = new(); + private const int EventIdFailedToExtractAttributes = 1; + private const int EventIdFailedToValidateCertificate = 2; + private const int EventIdFailedToCreateHttpHandler = 3; + private const int EventIdFailedCertificateFileNotExists = 4; + private const int EventIdFailedToLoadCertificateInStorage = 5; + [NonEvent] public void ResourceAttributesExtractException(string format, Exception ex) { @@ -21,15 +27,33 @@ public void ResourceAttributesExtractException(string format, Exception ex) } } - [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] + [Event(EventIdFailedToExtractAttributes, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] public void FailedToExtractResourceAttributes(string format, string exception) { - this.WriteEvent(1, format, exception); + this.WriteEvent(EventIdFailedToExtractAttributes, format, exception); + } + + [Event(EventIdFailedToValidateCertificate, Message = "Failed to validate certificate. Details: '{0}'", Level = EventLevel.Warning)] + public void FailedToValidateCertificate(string error) + { + this.WriteEvent(EventIdFailedToValidateCertificate, error); + } + + [Event(EventIdFailedToCreateHttpHandler, Message = "Failed to create HTTP handler. Exception: '{0}'", Level = EventLevel.Warning)] + public void FailedToCreateHttpHandler(Exception exception) + { + this.WriteEvent(EventIdFailedToCreateHttpHandler, exception.ToInvariantString()); + } + + [Event(EventIdFailedCertificateFileNotExists, Message = "Certificate file does not exist. File: '{0}'", Level = EventLevel.Warning)] + public void CertificateFileDoesNotExist(string filename) + { + this.WriteEvent(EventIdFailedCertificateFileNotExists, filename); } - [Event(2, Message = "Failed to validate certificate in format: '{0}', error: '{1}'.", Level = EventLevel.Warning)] - public void FailedToValidateCertificate(string format, string error) + [Event(EventIdFailedToLoadCertificateInStorage, Message = "Failed to load certificate in trusted storage. File: '{0}'", Level = EventLevel.Warning)] + public void FailedToLoadCertificateInTrustedStorage(string filename) { - this.WriteEvent(2, format, error); + this.WriteEvent(EventIdFailedToLoadCertificateInStorage, filename); } } diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj index 41b1f8673a..0cec692434 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -23,6 +23,9 @@ + + + diff --git a/src/Shared/IServerCertificateValidationEventSource.cs b/src/Shared/IServerCertificateValidationEventSource.cs new file mode 100644 index 0000000000..abca33b5aa --- /dev/null +++ b/src/Shared/IServerCertificateValidationEventSource.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; + +namespace OpenTelemetry.ResourceDetectors; + +internal interface IServerCertificateValidationEventSource +{ + public void FailedToValidateCertificate(string error); + + public void FailedToCreateHttpHandler(Exception exception); + + public void CertificateFileDoesNotExist(string filename); + + public void FailedToLoadCertificateInTrustedStorage(string filename); +} diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs b/src/Shared/ServerCertificateValidationHandler.cs similarity index 52% rename from src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs rename to src/Shared/ServerCertificateValidationHandler.cs index 5e709733b1..de55e39a2c 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/Handler.cs +++ b/src/Shared/ServerCertificateValidationHandler.cs @@ -6,35 +6,36 @@ using System; using System.Net.Http; -namespace OpenTelemetry.ResourceDetectors.AWS.Http; +namespace OpenTelemetry.ResourceDetectors; -internal class Handler +internal static class ServerCertificateValidationHandler { - public static HttpClientHandler? Create(string certificateFile) + public static HttpClientHandler? Create(string certificateFile, IServerCertificateValidationEventSource log) { try { - ServerCertificateValidationProvider? serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateFile); + ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile, log); if (serverCertificateValidationProvider == null) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(Handler), "Failed to Load the certificate file into trusted collection"); - return null; + return new HttpClientHandler(); } - var clientHandler = new HttpClientHandler(); - clientHandler.ServerCertificateCustomValidationCallback = + var clientHandler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (sender, x509Certificate2, x509Chain, sslPolicyErrors) => - serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors); + serverCertificateValidationProvider.ValidationCallback(sender, x509Certificate2, x509Chain, sslPolicyErrors), + }; return clientHandler; } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(Handler)} : Failed to create HttpClientHandler", ex); + log.FailedToCreateHttpHandler(ex); } return null; } } + #endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs b/src/Shared/ServerCertificateValidationProvider.cs similarity index 75% rename from src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs rename to src/Shared/ServerCertificateValidationProvider.cs index da13c70014..6591100e95 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Http/ServerCertificateValidationProvider.cs +++ b/src/Shared/ServerCertificateValidationProvider.cs @@ -9,37 +9,39 @@ using System.Net.Security; using System.Security.Cryptography.X509Certificates; -namespace OpenTelemetry.ResourceDetectors.AWS.Http; +namespace OpenTelemetry.ResourceDetectors; internal class ServerCertificateValidationProvider { private readonly X509Certificate2Collection trustedCertificates; + private readonly IServerCertificateValidationEventSource log; - private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates) + private ServerCertificateValidationProvider(X509Certificate2Collection trustedCertificates, IServerCertificateValidationEventSource log) { this.trustedCertificates = trustedCertificates; this.ValidationCallback = (_, cert, chain, errors) => this.ValidateCertificate(cert != null ? new X509Certificate2(cert) : null, chain, errors); + this.log = log; } public RemoteCertificateValidationCallback ValidationCallback { get; } - public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile) + public static ServerCertificateValidationProvider? FromCertificateFile(string certificateFile, IServerCertificateValidationEventSource log) { if (!File.Exists(certificateFile)) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate File does not exist"); + log.CertificateFileDoesNotExist(certificateFile); return null; } var trustedCertificates = new X509Certificate2Collection(); if (!LoadCertificateToTrustedCollection(trustedCertificates, certificateFile)) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Failed to load certificate in trusted collection"); + log.FailedToLoadCertificateInTrustedStorage(certificateFile); return null; } - return new ServerCertificateValidationProvider(trustedCertificates); + return new ServerCertificateValidationProvider(trustedCertificates, log); } private static bool LoadCertificateToTrustedCollection(X509Certificate2Collection collection, string certFileName) @@ -84,24 +86,24 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo { if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNotAvailable occurred"); + this.log.FailedToValidateCertificate("SslPolicyError RemoteCertificateNotAvailable occurred"); } if ((errors | SslPolicyErrors.RemoteCertificateNameMismatch) == errors) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "SslPolicyError RemoteCertificateNameMismatch occurred"); + this.log.FailedToValidateCertificate("SslPolicyError RemoteCertificateNameMismatch occurred"); } } if (chain == null) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate chain is null."); + this.log.FailedToValidateCertificate("Certificate chain is null."); return false; } if (cert == null) { - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), "Certificate is null."); + this.log.FailedToValidateCertificate("Certificate is null."); return false; } @@ -123,7 +125,7 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo } } - AWSResourcesEventSource.Log.FailedToValidateCertificate(nameof(ServerCertificateValidationProvider), chainErrors); + this.log.FailedToValidateCertificate(chainErrors); } // check if at least one certificate in the chain is in our trust list @@ -142,12 +144,11 @@ private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPo trustCertificates += " " + trustCertificate.Subject; } - AWSResourcesEventSource.Log.FailedToValidateCertificate( - nameof(ServerCertificateValidationProvider), - $"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}"); + this.log.FailedToValidateCertificate($"Server Certificates Chain cannot be trusted. The chain doesn't match with the Trusted Certificates provided. Server Certificates:{serverCertificates}. Trusted Certificates:{trustCertificates}"); } return isSslPolicyPassed && isValidChain && isTrusted; } } + #endif diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/NoopServerCertificateValidationEventSource.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/NoopServerCertificateValidationEventSource.cs new file mode 100644 index 0000000000..2aa5db8fb9 --- /dev/null +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/NoopServerCertificateValidationEventSource.cs @@ -0,0 +1,27 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; + +namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; + +internal sealed class NoopServerCertificateValidationEventSource : IServerCertificateValidationEventSource +{ + public static NoopServerCertificateValidationEventSource Instance { get; } = new NoopServerCertificateValidationEventSource(); + + public void FailedToValidateCertificate(string error) + { + } + + public void FailedToCreateHttpHandler(Exception exception) + { + } + + public void CertificateFileDoesNotExist(string filename) + { + } + + public void FailedToLoadCertificateInTrustedStorage(string filename) + { + } +} diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs similarity index 65% rename from test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs rename to test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs index b7c16d64ca..5c77a6c00d 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/HandlerTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs @@ -3,12 +3,11 @@ #if !NETFRAMEWORK -using OpenTelemetry.ResourceDetectors.AWS.Http; using Xunit; namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; -public class HandlerTests +public class ServerCertificateValidationHandlerTests { private const string INVALIDCRTNAME = "invalidcert"; @@ -20,7 +19,7 @@ public void TestValidHandler() certificateUploader.Create(); // Validates if the handler created. - Assert.NotNull(Handler.Create(certificateUploader.FilePath)); + Assert.NotNull(ServerCertificateValidationHandler.Create(certificateUploader.FilePath, NoopServerCertificateValidationEventSource.Instance)); } } @@ -28,7 +27,7 @@ public void TestValidHandler() public void TestInValidHandler() { // Validates if the handler created if no certificate is loaded into the trusted collection - Assert.Null(Handler.Create(INVALIDCRTNAME)); + Assert.NotNull(ServerCertificateValidationHandler.Create(INVALIDCRTNAME, NoopServerCertificateValidationEventSource.Instance)); } } diff --git a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index 008107b52e..21adccc11a 100644 --- a/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.ResourceDetectors.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -4,7 +4,6 @@ #if !NETFRAMEWORK using System.Security.Cryptography.X509Certificates; -using OpenTelemetry.ResourceDetectors.AWS.Http; using Xunit; namespace OpenTelemetry.ResourceDetectors.AWS.Tests.Http; @@ -20,7 +19,7 @@ public void TestValidCertificate() certificateUploader.Create(); var serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath, NoopServerCertificateValidationEventSource.Instance); Assert.NotNull(serverCertificateValidationProvider); @@ -38,7 +37,7 @@ public void TestValidCertificate() public void TestInValidCertificate() { var serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(InvalidCertificateName); + ServerCertificateValidationProvider.FromCertificateFile(InvalidCertificateName, NoopServerCertificateValidationEventSource.Instance); Assert.Null(serverCertificateValidationProvider); } @@ -50,7 +49,7 @@ public void TestTestCallbackWithNullCertificate() certificateUploader.Create(); var serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath, NoopServerCertificateValidationEventSource.Instance); Assert.NotNull(serverCertificateValidationProvider); Assert.False(serverCertificateValidationProvider.ValidationCallback(this, null, new X509Chain(), default)); @@ -63,7 +62,7 @@ public void TestCallbackWithNullChain() certificateUploader.Create(); var serverCertificateValidationProvider = - ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath); + ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath, NoopServerCertificateValidationEventSource.Instance); Assert.NotNull(serverCertificateValidationProvider); Assert.False(serverCertificateValidationProvider.ValidationCallback(this, new X509Certificate2(certificateUploader.FilePath), null, default)); From 10ff408de8634c87b8ad8d4ba6161a30d0245991 Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Tue, 23 Apr 2024 21:25:44 +0100 Subject: [PATCH 1033/1499] [Sampler.AWS] Use DateTimeOffset to beter handle timezones. (#1682) --- .../AWSXRayRemoteSampler.cs | 4 ++-- src/OpenTelemetry.Sampler.AWS/Clock.cs | 6 +++--- src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 8 ++++---- .../SamplingRuleApplier.cs | 16 ++++++++-------- src/OpenTelemetry.Sampler.AWS/SystemClock.cs | 10 +++++----- .../OpenTelemetry.Sampler.AWS.Tests/TestClock.cs | 6 +++--- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs index 19a9da8734..fba71ba652 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -156,7 +156,7 @@ private async void GetAndUpdateTargets(object? state) if (response.LastRuleModification > 0) { - DateTime lastRuleModificationTime = this.Clock.ToDateTime(response.LastRuleModification); + var lastRuleModificationTime = this.Clock.ToDateTime(response.LastRuleModification); if (lastRuleModificationTime > this.RulesCache.GetUpdatedAt()) { @@ -167,7 +167,7 @@ private async void GetAndUpdateTargets(object? state) } // schedule next target poll - DateTime nextTargetFetchTime = this.RulesCache.NextTargetFetchTime(); + var nextTargetFetchTime = this.RulesCache.NextTargetFetchTime(); TimeSpan nextTargetFetchInterval = nextTargetFetchTime.Subtract(this.Clock.Now()); if (nextTargetFetchInterval < TimeSpan.Zero) { diff --git a/src/OpenTelemetry.Sampler.AWS/Clock.cs b/src/OpenTelemetry.Sampler.AWS/Clock.cs index b50e9c51dc..5ad9e4dca6 100644 --- a/src/OpenTelemetry.Sampler.AWS/Clock.cs +++ b/src/OpenTelemetry.Sampler.AWS/Clock.cs @@ -13,11 +13,11 @@ public static Clock GetDefault() return SystemClock.GetInstance(); } - public abstract DateTime Now(); + public abstract DateTimeOffset Now(); public abstract long NowInMilliSeconds(); - public abstract DateTime ToDateTime(double seconds); + public abstract DateTimeOffset ToDateTime(double seconds); - public abstract double ToDouble(DateTime dateTime); + public abstract double ToDouble(DateTimeOffset dateTime); } diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs index 3af0a34d75..2f215b0ce3 100644 --- a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -37,7 +37,7 @@ public RulesCache(Clock clock, string clientId, Resource resource, Trace.Sampler internal List RuleAppliers { get; set; } - internal DateTime UpdatedAt { get; set; } + internal DateTimeOffset UpdatedAt { get; set; } public bool Expired() { @@ -96,7 +96,7 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters) return this.FallbackSampler.ShouldSample(in samplingParameters); } - public List Snapshot(DateTime now) + public List Snapshot(DateTimeOffset now) { List snapshots = new List(); foreach (var ruleApplier in this.RuleAppliers) @@ -135,7 +135,7 @@ public void UpdateTargets(Dictionary targets) } } - public DateTime NextTargetFetchTime() + public DateTimeOffset NextTargetFetchTime() { var defaultPollingTime = this.Clock.Now().AddSeconds(AWSXRayRemoteSampler.DefaultTargetInterval.TotalSeconds); @@ -162,7 +162,7 @@ public void Dispose() GC.SuppressFinalize(this); } - internal DateTime GetUpdatedAt() + internal DateTimeOffset GetUpdatedAt() { this.rwLock.EnterReadLock(); try diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index 9d9df706fa..32bbae4ed1 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -50,8 +50,8 @@ private SamplingRuleApplier( Trace.Sampler fixedRateSampler, bool borrowing, Statistics statistics, - DateTime reservoirEndTime, - DateTime nextSnapshotTime) + DateTimeOffset reservoirEndTime, + DateTimeOffset nextSnapshotTime) { this.ClientId = clientId; this.Rule = rule; @@ -81,9 +81,9 @@ private SamplingRuleApplier( internal bool Borrowing { get; set; } - internal DateTime ReservoirEndTime { get; set; } + internal DateTimeOffset ReservoirEndTime { get; set; } - internal DateTime NextSnapshotTime { get; set; } + internal DateTimeOffset NextSnapshotTime { get; set; } // check if this rule applier matches the request public bool Matches(SamplingParameters samplingParameters, Resource resource) @@ -179,7 +179,7 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters) } // take the snapshot and reset the statistics. - public SamplingStatisticsDocument Snapshot(DateTime now) + public SamplingStatisticsDocument Snapshot(DateTimeOffset now) { double timestamp = this.Clock.ToDouble(now); @@ -198,14 +198,14 @@ public SamplingStatisticsDocument Snapshot(DateTime now) return statiscticsDocument; } - public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTime now) + public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOffset now) { Trace.Sampler newFixedRateSampler = target.FixedRate != null ? new ParentBasedSampler(new TraceIdRatioBasedSampler(target.FixedRate.Value)) : this.FixedRateSampler; Trace.Sampler newReservoirSampler = new AlwaysOffSampler(); - DateTime newReservoirEndTime = DateTime.MaxValue; + DateTimeOffset newReservoirEndTime = DateTimeOffset.MaxValue; if (target.ReservoirQuota != null && target.ReservoirQuotaTTL != null) { if (target.ReservoirQuota > 0) @@ -220,7 +220,7 @@ public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTime no newReservoirEndTime = this.Clock.ToDateTime(target.ReservoirQuotaTTL.Value); } - DateTime newNextSnapshotTime = target.Interval != null + DateTimeOffset newNextSnapshotTime = target.Interval != null ? now.AddSeconds(target.Interval.Value) : now.Add(AWSXRayRemoteSampler.DefaultTargetInterval); diff --git a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs index fa0e5a2d9f..f337ac8f70 100644 --- a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs +++ b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs @@ -10,7 +10,7 @@ internal class SystemClock : Clock { private static readonly SystemClock Instance = new SystemClock(); - private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private static readonly DateTimeOffset EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private SystemClock() { @@ -21,9 +21,9 @@ public static Clock GetInstance() return Instance; } - public override DateTime Now() + public override DateTimeOffset Now() { - return DateTime.UtcNow; + return DateTimeOffset.UtcNow; } public override long NowInMilliSeconds() @@ -31,12 +31,12 @@ public override long NowInMilliSeconds() return (long)this.Now().ToUniversalTime().Subtract(EpochStart).TotalMilliseconds; } - public override DateTime ToDateTime(double seconds) + public override DateTimeOffset ToDateTime(double seconds) { return EpochStart.AddSeconds(seconds); } - public override double ToDouble(DateTime dateTime) + public override double ToDouble(DateTimeOffset dateTime) { var current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index d773ed6b9e..c012a1827c 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -20,7 +20,7 @@ public TestClock(DateTime time) this.nowTime = time; } - public override DateTime Now() + public override DateTimeOffset Now() { return this.nowTime; } @@ -30,12 +30,12 @@ public override long NowInMilliSeconds() return (long)this.nowTime.ToUniversalTime().Subtract(EpochStart).TotalMilliseconds; } - public override DateTime ToDateTime(double seconds) + public override DateTimeOffset ToDateTime(double seconds) { return EpochStart.AddSeconds(seconds); } - public override double ToDouble(DateTime dateTime) + public override double ToDouble(DateTimeOffset dateTime) { TimeSpan current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; From 8cce1c7ac57b50342fd07eb572cf9ffa1d2dda68 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 23 Apr 2024 14:14:55 -0700 Subject: [PATCH 1034/1499] [Exporter.Geneva] Add changelog for OTLP protobuf metric exporter. (#1678) Co-authored-by: Reiley Yang --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 14 +++++++++++--- src/OpenTelemetry.Exporter.Geneva/README.md | 15 +++++++++++++++ .../GenevaMetricExporterTests.cs | 12 +++++++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 4b34ca8b2e..0815d060ee 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,9 +2,6 @@ ## Unreleased -* Native AOT compatibility. - ([#1666](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1666)) - * Fix a bug in `GenevaMetricExporter` where the `MetricEtwDataTransport` singleton is disposed. ([#1537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1537)) @@ -12,6 +9,17 @@ * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Add OTLP protobuf encoding support for metric exporter in Windows + environment. Use `PrivatePreviewEnableOtlpProtobufEncoding=true` in the + connection string to opt-in. + ([#1596](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1596), + [#1626](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1626), + [#1629](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1629), + [#1634](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1634)) + +* Native AOT compatibility. + ([#1666](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1666)) + ## 1.7.0 Released 2023-Dec-11 diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 4bb7870c14..44e6c27e91 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -255,6 +255,21 @@ On Linux provide an `Endpoint` in addition to the `Account` and `Namespace`. For example: `Endpoint=unix:{UDS Path};Account={MetricAccount};Namespace={MetricNamespace}`. +Set `PrivatePreviewEnableOtlpProtobufEncoding=true` to opt-in to the +experimental feature for changing the underlying serialization format to binary +protobuf following the schema defined in [OTLP +specification](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.1.0/opentelemetry/proto/metrics/v1/metrics.proto). + +> [!NOTE] + > `PrivatePreviewEnableOtlpProtobufEncoding` is currently + > only supported in Windows environment. Exporting + > [Exemplar](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar) + > and + > [ExponentialHistogram](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#exponentialhistogram) + > are not supported for now. + > ([#1685](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1685), + > [#1378](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1378)). + #### `MetricExportIntervalMilliseconds` (optional) Set the exporter's periodic time interval to export Metrics. The default value diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 6d220f4d2f..e21a60bed7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -286,7 +286,7 @@ private void EmitMetrics(string attempt) [InlineData(false, false)] [InlineData(true, true)] [InlineData(false, true)] - public void DisableMetricNameValidationTest(bool disableMetricNameValidation, bool enableOtlpProtobufexporter) + public void DisableMetricNameValidationTest(bool disableMetricNameValidation, bool enableOtlpProtobufEncoding) { var instrumentNameRegexProperty = GenevaMetricExporter.GetOpenTelemetryInstrumentNameRegexProperty(); var initialInstrumentNameRegexValue = instrumentNameRegexProperty.GetValue(null); @@ -303,12 +303,18 @@ public void DisableMetricNameValidationTest(bool disableMetricNameValidation, bo { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation};PrivatePreviewOtlpProtobufMetricExporter={enableOtlpProtobufexporter}"; + options.ConnectionString = $"Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; + + if (enableOtlpProtobufEncoding) + { + options.ConnectionString += $";PrivatePreviewEnableOtlpProtobufEncoding={enableOtlpProtobufEncoding}"; + } } else { + // TODO: extend test for enableOtlpProtobufEncoding to linux when the support is added. var path = GenerateTempFilePath(); - options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation};PrivatePreviewOtlpProtobufMetricExporter={enableOtlpProtobufexporter}"; + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace;DisableMetricNameValidation={disableMetricNameValidation}"; var endpoint = new UnixDomainSocketEndPoint(path); server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); From 87d1bd47c6a897aebb7d427bd11ba8bc7a326d43 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 23 Apr 2024 14:53:21 -0700 Subject: [PATCH 1035/1499] [Exporter.Geneva] Prepare release 1.8.0-beta.1 (#1686) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 0815d060ee..f6ab99ec94 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0-beta.1 + +Released 2023-Apr-23 + * Fix a bug in `GenevaMetricExporter` where the `MetricEtwDataTransport` singleton is disposed. ([#1537](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1537)) From e857280c3d5749163b94ddbdcb312bdd8438cb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 24 Apr 2024 06:48:48 +0200 Subject: [PATCH 1036/1499] [Instrumentation.SqlClient] Move package from main repository (#1673) --- .../comp_instrumentation_sqlclient.md | 41 ++ .github/codecov.yml | 7 +- .github/workflows/ci.yml | 16 + .../package-Instrumentation.SqlClient.yml | 21 + build/Common.props | 1 + ...enTelemetry.Instrumentation.SqlClient.proj | 32 ++ opentelemetry-dotnet-contrib.sln | 19 +- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 18 + .../AssemblyInfo.cs | 10 + .../CHANGELOG.md | 274 ++++++++++ .../Implementation/SqlActivitySourceHelper.cs | 29 ++ .../SqlClientDiagnosticListener.cs | 204 ++++++++ .../SqlClientInstrumentationEventSource.cs | 85 ++++ .../SqlEventSourceListener.netfx.cs | 191 +++++++ ...Telemetry.Instrumentation.SqlClient.csproj | 39 ++ .../README.md | 276 +++++++++++ .../SqlClientInstrumentation.cs | 70 +++ .../SqlClientTraceInstrumentationOptions.cs | 302 +++++++++++ .../TracerProviderBuilderExtensions.cs | 81 +++ src/Shared/SemanticConventions.cs | 5 + ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + .../EnabledOnDockerPlatformTheoryAttribute.cs | 76 +++ .../EventSourceTestHelper.cs | 2 + .../OpenTelemetry.Contrib.Tests.Shared.csproj | 3 +- .../TestEventListener.cs | 2 + .../TestSampler.cs | 2 + .../EventSourceTest.cs | 17 + ...try.Instrumentation.SqlClient.Tests.csproj | 31 ++ .../SqlClientIntegrationTests.cs | 118 +++++ .../SqlClientTests.cs | 468 ++++++++++++++++++ ...lClientTraceInstrumentationOptionsTests.cs | 93 ++++ .../SqlEventSourceTests.netfx.cs | 371 ++++++++++++++ 33 files changed, 2900 insertions(+), 5 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md create mode 100644 .github/workflows/package-Instrumentation.SqlClient.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/README.md create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/EnabledOnDockerPlatformTheoryAttribute.cs create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/EventSourceTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md new file mode 100644 index 0000000000..c74e59ca99 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.SqlClient +about: Issue with OpenTelemetry.Instrumentation.SqlClient +labels: comp:instrumentation.sqlclient +--- + +# Issue with OpenTelemetry.Instrumentation.SqlClient + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 74701f6a61..c38a11945c 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -78,12 +78,17 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Runtime + unittests-Instrumentation.SqlClient: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.SqlClient + unittests-Instrumentation.StackExchangeRedis: carryforward: true paths: - src/OpenTelemetry.Instrumentation.StackExchangeRedis - unittests-Instrumentation.Wcf: + unittests-Instrumentation.Wcf: carryforward: true paths: - src/OpenTelemetry.Instrumentation.Wcf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 150c7017dc..417259c488 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,7 @@ jobs: redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] resourcedetectors: ['*/OpenTelemetry.ResourceDetectors.*/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] + sqlclient: ['*/OpenTelemetry.Instrumentation.SqlClient*/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] solution: [ 'src/**', @@ -64,6 +65,7 @@ jobs: '!*/OpenTelemetry.PersistentStorage*/**', '!*/OpenTelemetry.Instrumentation.Process*/**', '!examples/process-instrumentation/**', + '!*/OpenTelemetry.Instrumentation.SqlClient*/**', '!*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', '!examples/redis/**', '!*/OpenTelemetry.Instrumentation.Runtime*/**', @@ -254,6 +256,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Runtime code-cov-name: Instrumentation.Runtime + build-test-sqlclient: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'sqlclient') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.SqlClient + code-cov-name: Instrumentation.SqlClient + build-test-wcf: needs: detect-changes if: | @@ -303,6 +316,7 @@ jobs: OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Instrumentation.Runtime.Tests.csproj, + OpenTelemetry.Instrumentation.SqlClient.Tests.csproj, OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, @@ -365,6 +379,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'geneva') || contains(needs.detect-changes.outputs.changes, 'onecollector') || contains(needs.detect-changes.outputs.changes, 'redis') + || contains(needs.detect-changes.outputs.changes, 'sqlclient') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/verifyaotcompat.yml @@ -389,6 +404,7 @@ jobs: build-test-redis, build-test-redis-integration, build-test-runtime, + build-test-sqlclient, build-test-wcf, build-test-solution, verify-aot-compat diff --git a/.github/workflows/package-Instrumentation.SqlClient.yml b/.github/workflows/package-Instrumentation.SqlClient.yml new file mode 100644 index 0000000000..1226183035 --- /dev/null +++ b/.github/workflows/package-Instrumentation.SqlClient.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.Instrumentation.SqlClient + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.SqlClient-*' # trigger when we create a tag with prefix "Instrumentation.SqlClient-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.SqlClient + secrets: inherit diff --git a/build/Common.props b/build/Common.props index 358fe0ba41..343b061a6a 100644 --- a/build/Common.props +++ b/build/Common.props @@ -33,6 +33,7 @@ [8.0.1,) [2.1.0,5.0) [3.1.0,) + 8.0.0 [1.0.3,2.0) [4.2.2,5.0) [3.11.0-beta1.23525.2] diff --git a/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj b/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj new file mode 100644 index 0000000000..3cde77cdda --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e2de239aec..6d755deb10 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -42,9 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Exporter.OneCollector.yml = .github\workflows\package-Exporter.OneCollector.yml .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml .github\workflows\package-Extensions.AWS.yml = .github\workflows\package-Extensions.AWS.yml - .github\workflows\package-Extensions.AWSXRay.yml = .github\workflows\package-Extensions.AWSXRay.yml - .github\workflows\package-Extensions.AzureMonitor.yml = .github\workflows\package-Extensions.AzureMonitor.yml - .github\workflows\package-Extensions.Docker.yml = .github\workflows\package-Extensions.Docker.yml .github\workflows\package-Extensions.Enrichment.yml = .github\workflows\package-Extensions.Enrichment.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml @@ -61,6 +58,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml + .github\workflows\package-Instrumentation.SqlClient.yml = .github\workflows\package-Instrumentation.SqlClient.yml .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml @@ -324,6 +322,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.Runtime.proj = build\Projects\OpenTelemetry.Instrumentation.Runtime.proj + build\Projects\OpenTelemetry.Instrumentation.SqlClient.proj = build\Projects\OpenTelemetry.Instrumentation.SqlClient.proj build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj @@ -347,6 +346,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.PersistentStorage.Abstractions.Tests", "test\OpenTelemetry.PersistentStorage.Abstractions.Tests\OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj", "{7AD707F9-DC6D-430A-8834-D5DCD517BF6E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.SqlClient", "src\OpenTelemetry.Instrumentation.SqlClient\OpenTelemetry.Instrumentation.SqlClient.csproj", "{737D1A9E-5A1A-4F4F-830B-E98ED100994C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.SqlClient.Tests", "test\OpenTelemetry.Instrumentation.SqlClient.Tests\OpenTelemetry.Instrumentation.SqlClient.Tests.csproj", "{9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -693,6 +696,14 @@ Global {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Release|Any CPU.ActiveCfg = Release|Any CPU {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Release|Any CPU.Build.0 = Release|Any CPU + {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Release|Any CPU.Build.0 = Release|Any CPU + {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -796,6 +807,8 @@ Global {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {737D1A9E-5A1A-4F4F-830B-E98ED100994C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..82f785235c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,18 @@ +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.EnableConnectionLevelAttributes.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.EnableConnectionLevelAttributes.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForStoredProcedure.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SqlClientTraceInstrumentationOptions() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.SqlClient/AssemblyInfo.cs new file mode 100644 index 0000000000..70e3c273ab --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.SqlClient.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.SqlClient.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md new file mode 100644 index 0000000000..d6ac6ff546 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -0,0 +1,274 @@ +# Changelog + +## Unreleased + +* `ActivitySource.Version` is set to NuGet package version. + ([#5498](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5498)) +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. + * Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +## 1.8.0-beta.1 + +Released 2024-Apr-04 + +## 1.7.0-beta.1 + +Released 2024-Feb-09 + +* Removed support for the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable + which toggled the use of the new conventions for the + [server, client, and shared network attributes](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/attributes.md#server-client-and-shared-network-attributes). + Now that this suite of attributes are stable, this instrumentation will only + emit the new attributes. + ([#5270](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5270)) +* **Breaking Change**: Renamed `SqlClientInstrumentationOptions` to + `SqlClientTraceInstrumentationOptions`. + ([#5285](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5285)) +* **Breaking Change**: Stop emitting `db.statement_type` attribute. + This attribute was never a part of the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md#call-level-attributes). + ([#5301](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5301)) + +## 1.6.0-beta.3 + +Released 2023-Nov-17 + +* Updated `Microsoft.Extensions.Configuration` and + `Microsoft.Extensions.Options` package version to `8.0.0`. + ([#5051](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5051)) + +## 1.6.0-beta.2 + +Released 2023-Oct-26 + +## 1.5.1-beta.1 + +Released 2023-Jul-20 + +* The new network semantic conventions can be opted in to by setting + the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a + transition period for users to experiment with the new semantic conventions + and adapt as necessary. The environment variable supports the following + values: + * `http` - emit the new, frozen (proposed for stable) networking + attributes, and stop emitting the old experimental networking + attributes that the instrumentation emitted previously. + * `http/dup` - emit both the old and the frozen (proposed for stable) + networking attributes, allowing for a more seamless transition. + * The default behavior (in the absence of one of these values) is to continue + emitting the same network semantic conventions that were emitted in + `1.5.0-beta.1`. + * Note: this option will eventually be removed after the new + network semantic conventions are marked stable. Refer to the + specification for more information regarding the new network + semantic conventions for + [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/database/database-spans.md). + ([#4644](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4644)) + +## 1.5.0-beta.1 + +Released 2023-Jun-05 + +* Bumped the package version to `1.5.0-beta.1` to keep its major and minor + version in sync with that of the core packages. This would make it more + intuitive for users to figure out what version of core packages would work + with a given version of this package. The pre-release identifier has also been + changed from `rc` to `beta` as we believe this more accurately reflects the + status of this package. We believe the `rc` identifier will be more + appropriate as semantic conventions reach stability. + +## 1.0.0-rc9.14 + +Released 2023-Feb-24 + +* Updated OpenTelemetry.Api.ProviderBuilderExtensions dependency to 1.4.0 + +## 1.4.0-rc9.13 + +Released 2023-Feb-10 + +## 1.0.0-rc9.12 + +Released 2023-Feb-01 + +## 1.0.0-rc9.11 + +Released 2023-Jan-09 + +## 1.0.0-rc9.10 + +Released 2022-Dec-12 + +* **Breaking change**: The same API is now exposed for `net462` and + `netstandard2.0` targets. `SetDbStatement` has been removed. Use + `SetDbStatementForText` to capture command text and stored procedure names on + .NET Framework. Note: `Enrich`, `Filter`, `RecordException`, and + `SetDbStatementForStoredProcedure` options are NOT supported on .NET + Framework. + ([#3900](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3900)) + +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddSqlClientInstrumentation` extension to allow for more fine-grained options + management + ([#3994](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3994)) + +## 1.0.0-rc9.9 + +Released 2022-Nov-07 + +## 1.0.0-rc9.8 + +Released 2022-Oct-17 + +* Use `Activity.Status` and `Activity.StatusDescription` properties instead of + `OpenTelemetry.Trace.Status` and `OpenTelemetry.Trace.Status.Description` + respectively to set activity status. + ([#3118](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3118)) + ([#3751](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3751)) +* Add support for Filter option for non .NET Framework Targets + ([#3743](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3743)) + +## 1.0.0-rc9.7 + +Released 2022-Sep-29 + +## 1.0.0-rc9.6 + +Released 2022-Aug-18 + +## 1.0.0-rc9.5 + +Released 2022-Aug-02 + +* Update the `ActivitySource.Name` from "OpenTelemetry.SqlClient" to + "OpenTelemetry.Instrumentation.SqlClient". + ([#3435](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3435)) + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +* Removes .NET Framework 4.6.1. The minimum .NET Framework version supported is + .NET 4.6.2. + ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +* Removes .NET Framework 4.5.2 support. The minimum .NET Framework version + supported is .NET 4.6.1. + ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138)) + +## 1.0.0-rc7 + +Released 2021-Jul-12 + +## 1.0.0-rc6 + +Released 2021-Jun-25 + +## 1.0.0-rc5 + +Released 2021-Jun-09 + +## 1.0.0-rc4 + +Released 2021-Apr-23 + +* Instrumentation modified to depend only on the API. +* Activities are now created with the `db.system` attribute set for usage during + sampling. + ([#1979](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1979)) + +## 1.0.0-rc3 + +Released 2021-Mar-19 + +## 1.0.0-rc2 + +Released 2021-Jan-29 + +* Microsoft.Data.SqlClient v2.0.0 and higher is now properly instrumented on + .NET Framework. + ([#1599](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1599)) +* SqlClientInstrumentationOptions API changes: `SetStoredProcedureCommandName` + and `SetTextCommandContent` have been renamed to + `SetDbStatementForStoredProcedure` and `SetDbStatementForText`. They are now + only available on .NET Core. On .NET Framework they are replaced by a single + `SetDbStatement` property. +* On .NET Framework, "db.statement_type" attribute is no longer set for + activities created by the instrumentation. +* New setting on SqlClientInstrumentationOptions on .NET Core: `RecordException` + can be set to instruct the instrumentation to record SqlExceptions as Activity + [events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md). + ([#1592](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1592)) + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +* SqlInstrumentation sets ActivitySource to activities created outside + ActivitySource. + ([#1515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1515/)) + +## 0.8.0-beta.1 + +Released 2020-Nov-5 + +## 0.7.0-beta.1 + +Released 2020-Oct-16 + +* Instrumentation no longer store raw objects like `object` in + Activity.CustomProperty. To enrich activity, use the Enrich action on the + instrumentation. + ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) +* Span Status is populated as per new spec + ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) + +## 0.6.0-beta.1 + +Released 2020-Sep-15 + +## 0.5.0-beta.2 + +Released 2020-08-28 + +* .NET Core SqlClient instrumentation will now add the raw Command object to the + Activity it creates + ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099)) +* Renamed from `AddSqlClientDependencyInstrumentation` to + `AddSqlClientInstrumentation` + +## 0.4.0-beta.2 + +Released 2020-07-24 + +* First beta release + +## 0.3.0-beta + +Released 2020-07-23 + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs new file mode 100644 index 0000000000..ea6080bafd --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Reflection; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.SqlClient.Implementation; + +/// +/// Helper class to hold common properties used by both SqlClientDiagnosticListener on .NET Core +/// and SqlEventSourceListener on .NET Framework. +/// +internal sealed class SqlActivitySourceHelper +{ + public const string MicrosoftSqlServerDatabaseSystemName = "mssql"; + + public static readonly Assembly Assembly = typeof(SqlActivitySourceHelper).Assembly; + public static readonly AssemblyName AssemblyName = Assembly.GetName(); + public static readonly string ActivitySourceName = AssemblyName.Name; + public static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); + public static readonly string ActivityName = ActivitySourceName + ".Execute"; + + public static readonly IEnumerable> CreationTags = new[] + { + new KeyValuePair(SemanticConventions.AttributeDbSystem, MicrosoftSqlServerDatabaseSystemName), + }; +} diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs new file mode 100644 index 0000000000..589ae603f7 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -0,0 +1,204 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NETFRAMEWORK +using System.Data; +using System.Diagnostics; +using OpenTelemetry.Trace; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + +namespace OpenTelemetry.Instrumentation.SqlClient.Implementation; + +#if NET6_0_OR_GREATER +[RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] +#endif +internal sealed class SqlClientDiagnosticListener : ListenerHandler +{ + public const string SqlDataBeforeExecuteCommand = "System.Data.SqlClient.WriteCommandBefore"; + public const string SqlMicrosoftBeforeExecuteCommand = "Microsoft.Data.SqlClient.WriteCommandBefore"; + + public const string SqlDataAfterExecuteCommand = "System.Data.SqlClient.WriteCommandAfter"; + public const string SqlMicrosoftAfterExecuteCommand = "Microsoft.Data.SqlClient.WriteCommandAfter"; + + public const string SqlDataWriteCommandError = "System.Data.SqlClient.WriteCommandError"; + public const string SqlMicrosoftWriteCommandError = "Microsoft.Data.SqlClient.WriteCommandError"; + + private readonly PropertyFetcher commandFetcher = new("Command"); + private readonly PropertyFetcher connectionFetcher = new("Connection"); + private readonly PropertyFetcher dataSourceFetcher = new("DataSource"); + private readonly PropertyFetcher databaseFetcher = new("Database"); + private readonly PropertyFetcher commandTypeFetcher = new("CommandType"); + private readonly PropertyFetcher commandTextFetcher = new("CommandText"); + private readonly PropertyFetcher exceptionFetcher = new("Exception"); + private readonly SqlClientTraceInstrumentationOptions options; + + public SqlClientDiagnosticListener(string sourceName, SqlClientTraceInstrumentationOptions options) + : base(sourceName) + { + this.options = options ?? new SqlClientTraceInstrumentationOptions(); + } + + public override bool SupportsNullActivity => true; + + public override void OnEventWritten(string name, object payload) + { + var activity = Activity.Current; + switch (name) + { + case SqlDataBeforeExecuteCommand: + case SqlMicrosoftBeforeExecuteCommand: + { + // SqlClient does not create an Activity. So the activity coming in here will be null or the root span. + activity = SqlActivitySourceHelper.ActivitySource.StartActivity( + SqlActivitySourceHelper.ActivityName, + ActivityKind.Client, + default(ActivityContext), + SqlActivitySourceHelper.CreationTags); + + if (activity == null) + { + // There is no listener or it decided not to sample the current request. + return; + } + + _ = this.commandFetcher.TryFetch(payload, out var command); + if (command == null) + { + SqlClientInstrumentationEventSource.Log.NullPayload(nameof(SqlClientDiagnosticListener), name); + activity.Stop(); + return; + } + + if (activity.IsAllDataRequested) + { + try + { + if (this.options.Filter?.Invoke(command) == false) + { + SqlClientInstrumentationEventSource.Log.CommandIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + } + catch (Exception ex) + { + SqlClientInstrumentationEventSource.Log.CommandFilterException(ex); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + + _ = this.connectionFetcher.TryFetch(command, out var connection); + _ = this.databaseFetcher.TryFetch(connection, out var database); + + activity.DisplayName = (string)database; + + _ = this.dataSourceFetcher.TryFetch(connection, out var dataSource); + _ = this.commandTextFetcher.TryFetch(command, out var commandText); + + activity.SetTag(SemanticConventions.AttributeDbName, (string)database); + + this.options.AddConnectionLevelDetailsToActivity((string)dataSource, activity); + + if (this.commandTypeFetcher.TryFetch(command, out CommandType commandType)) + { + switch (commandType) + { + case CommandType.StoredProcedure: + if (this.options.SetDbStatementForStoredProcedure) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, (string)commandText); + } + + break; + + case CommandType.Text: + if (this.options.SetDbStatementForText) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, (string)commandText); + } + + break; + + case CommandType.TableDirect: + break; + } + } + + try + { + this.options.Enrich?.Invoke(activity, "OnCustom", command); + } + catch (Exception ex) + { + SqlClientInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + break; + case SqlDataAfterExecuteCommand: + case SqlMicrosoftAfterExecuteCommand: + { + if (activity == null) + { + SqlClientInstrumentationEventSource.Log.NullActivity(name); + return; + } + + if (activity.Source != SqlActivitySourceHelper.ActivitySource) + { + return; + } + + activity.Stop(); + } + + break; + case SqlDataWriteCommandError: + case SqlMicrosoftWriteCommandError: + { + if (activity == null) + { + SqlClientInstrumentationEventSource.Log.NullActivity(name); + return; + } + + if (activity.Source != SqlActivitySourceHelper.ActivitySource) + { + return; + } + + try + { + if (activity.IsAllDataRequested) + { + if (this.exceptionFetcher.TryFetch(payload, out Exception exception) && exception != null) + { + activity.SetStatus(ActivityStatusCode.Error, exception.Message); + + if (this.options.RecordException) + { + activity.RecordException(exception); + } + } + else + { + SqlClientInstrumentationEventSource.Log.NullPayload(nameof(SqlClientDiagnosticListener), name); + } + } + } + finally + { + activity.Stop(); + } + } + + break; + } + } +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientInstrumentationEventSource.cs new file mode 100644 index 0000000000..ccd86471d7 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientInstrumentationEventSource.cs @@ -0,0 +1,85 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.SqlClient.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-SqlClient")] +internal sealed class SqlClientInstrumentationEventSource : EventSource +{ + public static SqlClientInstrumentationEventSource Log = new(); + + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(1, handlerName, eventName, ex); + } + + [Event(2, Message = "Current Activity is NULL in the '{0}' callback. Span will not be recorded.", Level = EventLevel.Warning)] + public void NullActivity(string eventName) + { + this.WriteEvent(2, eventName); + } + + [Event(3, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(3, handlerName, eventName); + } + + [Event(4, Message = "Payload is invalid in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void InvalidPayload(string handlerName, string eventName) + { + this.WriteEvent(4, handlerName, eventName); + } + + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(ex.ToInvariantString()); + } + } + + [Event(5, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(5, exception); + } + + [Event(6, Message = "Command is filtered out. Activity {0}", Level = EventLevel.Verbose)] + public void CommandIsFilteredOut(string activityName) + { + this.WriteEvent(6, activityName); + } + + [NonEvent] + public void CommandFilterException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.CommandFilterException(ex.ToInvariantString()); + } + } + + [Event(7, Message = "Command filter threw exception. Command will not be collected. Exception {0}.", Level = EventLevel.Error)] + public void CommandFilterException(string exception) + { + this.WriteEvent(7, exception); + } +} diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs new file mode 100644 index 0000000000..111e4878d3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -0,0 +1,191 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Diagnostics; +using System.Diagnostics.Tracing; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.SqlClient.Implementation; + +/// +/// On .NET Framework, neither System.Data.SqlClient nor Microsoft.Data.SqlClient emit DiagnosticSource events. +/// Instead they use EventSource: +/// For System.Data.SqlClient see: reference source. +/// For Microsoft.Data.SqlClient see: SqlClientEventSource. +/// +/// We hook into these event sources and process their BeginExecute/EndExecute events. +/// +/// +/// Note that before version 2.0.0, Microsoft.Data.SqlClient used +/// "Microsoft-AdoNet-SystemData" (same as System.Data.SqlClient), but since +/// 2.0.0 has switched to "Microsoft.Data.SqlClient.EventSource". +/// +internal sealed class SqlEventSourceListener : EventListener +{ + internal const string AdoNetEventSourceName = "Microsoft-AdoNet-SystemData"; + internal const string MdsEventSourceName = "Microsoft.Data.SqlClient.EventSource"; + + internal const int BeginExecuteEventId = 1; + internal const int EndExecuteEventId = 2; + + private readonly SqlClientTraceInstrumentationOptions options; + private EventSource adoNetEventSource; + private EventSource mdsEventSource; + + public SqlEventSourceListener(SqlClientTraceInstrumentationOptions options = null) + { + this.options = options ?? new SqlClientTraceInstrumentationOptions(); + } + + public override void Dispose() + { + if (this.adoNetEventSource != null) + { + this.DisableEvents(this.adoNetEventSource); + } + + if (this.mdsEventSource != null) + { + this.DisableEvents(this.mdsEventSource); + } + + base.Dispose(); + } + + protected override void OnEventSourceCreated(EventSource eventSource) + { + if (eventSource?.Name.StartsWith(AdoNetEventSourceName, StringComparison.Ordinal) == true) + { + this.adoNetEventSource = eventSource; + this.EnableEvents(eventSource, EventLevel.Informational, EventKeywords.All); + } + else if (eventSource?.Name.StartsWith(MdsEventSourceName, StringComparison.Ordinal) == true) + { + this.mdsEventSource = eventSource; + this.EnableEvents(eventSource, EventLevel.Informational, EventKeywords.All); + } + + base.OnEventSourceCreated(eventSource); + } + + protected override void OnEventWritten(EventWrittenEventArgs eventData) + { + try + { + if (eventData.EventId == BeginExecuteEventId) + { + this.OnBeginExecute(eventData); + } + else if (eventData.EventId == EndExecuteEventId) + { + this.OnEndExecute(eventData); + } + } + catch (Exception exc) + { + SqlClientInstrumentationEventSource.Log.UnknownErrorProcessingEvent(nameof(SqlEventSourceListener), nameof(this.OnEventWritten), exc); + } + } + + private void OnBeginExecute(EventWrittenEventArgs eventData) + { + /* + Expected payload: + [0] -> ObjectId + [1] -> DataSource + [2] -> Database + [3] -> CommandText + + Note: + - For "Microsoft-AdoNet-SystemData" v1.0: [3] CommandText = CommandType == CommandType.StoredProcedure ? CommandText : string.Empty; (so it is set for only StoredProcedure command types) + (https://github.com/dotnet/SqlClient/blob/v1.0.19239.1/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs#L6369) + - For "Microsoft-AdoNet-SystemData" v1.1: [3] CommandText = sqlCommand.CommandText (so it is set for all command types) + (https://github.com/dotnet/SqlClient/blob/v1.1.0/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs#L7459) + - For "Microsoft.Data.SqlClient.EventSource" v2.0+: [3] CommandText = sqlCommand.CommandText (so it is set for all command types). + (https://github.com/dotnet/SqlClient/blob/f4568ce68da21db3fe88c0e72e1287368aaa1dc8/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs#L6641) + */ + + if ((eventData?.Payload?.Count ?? 0) < 4) + { + SqlClientInstrumentationEventSource.Log.InvalidPayload(nameof(SqlEventSourceListener), nameof(this.OnBeginExecute)); + return; + } + + var activity = SqlActivitySourceHelper.ActivitySource.StartActivity( + SqlActivitySourceHelper.ActivityName, + ActivityKind.Client, + default(ActivityContext), + SqlActivitySourceHelper.CreationTags); + + if (activity == null) + { + // There is no listener or it decided not to sample the current request. + return; + } + + string databaseName = (string)eventData.Payload[2]; + + activity.DisplayName = databaseName; + + if (activity.IsAllDataRequested) + { + activity.SetTag(SemanticConventions.AttributeDbName, databaseName); + + this.options.AddConnectionLevelDetailsToActivity((string)eventData.Payload[1], activity); + + string commandText = (string)eventData.Payload[3]; + if (!string.IsNullOrEmpty(commandText) && this.options.SetDbStatementForText) + { + activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); + } + } + } + + private void OnEndExecute(EventWrittenEventArgs eventData) + { + /* + Expected payload: + [0] -> ObjectId + [1] -> CompositeState bitmask (0b001 -> successFlag, 0b010 -> isSqlExceptionFlag , 0b100 -> synchronousFlag) + [2] -> SqlExceptionNumber + */ + + if ((eventData?.Payload?.Count ?? 0) < 3) + { + SqlClientInstrumentationEventSource.Log.InvalidPayload(nameof(SqlEventSourceListener), nameof(this.OnEndExecute)); + return; + } + + var activity = Activity.Current; + if (activity?.Source != SqlActivitySourceHelper.ActivitySource) + { + return; + } + + try + { + if (activity.IsAllDataRequested) + { + int compositeState = (int)eventData.Payload[1]; + if ((compositeState & 0b001) != 0b001) + { + if ((compositeState & 0b010) == 0b010) + { + var errorText = $"SqlExceptionNumber {eventData.Payload[2]} thrown."; + activity.SetStatus(ActivityStatusCode.Error, errorText); + } + else + { + activity.SetStatus(ActivityStatusCode.Error, "Unknown Sql failure."); + } + } + } + } + finally + { + activity.Stop(); + } + } +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj new file mode 100644 index 0000000000..bddef25ac1 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -0,0 +1,39 @@ + + + + net8.0;net6.0;netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + SqlClient instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing + Instrumentation.SqlClient- + + enable + + disable + + + + + true + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md new file mode 100644 index 0000000000..1df0435250 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -0,0 +1,276 @@ +# SqlClient Instrumentation for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments +[Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient) +and +[System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient) +and collects traces about database operations. + +> [!WARNING] +> Instrumentation is not working with `Microsoft.Data.SqlClient` v3.* due to +the [issue](https://github.com/dotnet/SqlClient/pull/1258). It was fixed in 4.0 +and later. + +> [!CAUTION] +> This component is based on the OpenTelemetry semantic conventions for +[traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md). +These conventions are +[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), +and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +Until a [stable +version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be breaking changes. You can track the progress from +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). + +## Steps to enable OpenTelemetry.Instrumentation.SqlClient + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.SqlClient`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package --prerelease OpenTelemetry.Instrumentation.SqlClient +``` + +### Step 2: Enable SqlClient Instrumentation at application startup + +SqlClient instrumentation must be enabled at application startup. + +The following example demonstrates adding SqlClient instrumentation to a console +application. This example also sets up the OpenTelemetry Console exporter, which +requires adding the package +[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +For an ASP.NET Core application, adding instrumentation is typically done in the +`ConfigureServices` of your `Startup` class. Refer to documentation for +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). + +For an ASP.NET application, adding instrumentation is typically done in the +`Global.asax.cs`. Refer to the documentation for +[OpenTelemetry.Instrumentation.AspNet](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md). + +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`SqlClientTraceInstrumentationOptions`. + +### Capturing database statements + +The `SqlClientTraceInstrumentationOptions` class exposes two properties that can +be used to configure how the +[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) +attribute is captured upon execution of a query but the behavior depends on the +runtime used. + +#### .NET and .NET Core + +On .NET and .NET Core, two properties are available: +`SetDbStatementForStoredProcedure` and `SetDbStatementForText`. These properties +control capturing of `CommandType.StoredProcedure` and `CommandType.Text` +respectively. + +`SetDbStatementForStoredProcedure` is _true_ by default and will set +[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) +attribute to the stored procedure command name. + +`SetDbStatementForText` is _false_ by default (to prevent accidental capture of +sensitive data that might be part of the SQL statement text). When set to +`true`, the instrumentation will set +[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) +attribute to the text of the SQL command being executed. + +To disable capturing stored procedure commands use configuration like below. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + options => options.SetDbStatementForStoredProcedure = false) + .AddConsoleExporter() + .Build(); +``` + +To enable capturing of `sqlCommand.CommandText` for `CommandType.Text` use the +following configuration. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + options => options.SetDbStatementForText = true) + .AddConsoleExporter() + .Build(); +``` + +#### .NET Framework + +On .NET Framework, the `SetDbStatementForText` property controls whether or not +this instrumentation will set the +[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) +attribute to the text of the `SqlCommand` being executed. This could either be +the name of a stored procedure (when `CommandType.StoredProcedure` is used) or +the full text of a `CommandType.Text` query. `SetDbStatementForStoredProcedure` +is ignored because on .NET Framework there is no way to determine the type of +command being executed. + +Since `CommandType.Text` might contain sensitive data, all SQL capturing is +_disabled_ by default to protect against accidentally sending full query text to +a telemetry backend. If you are only using stored procedures or have no +sensitive data in your `sqlCommand.CommandText`, you can enable SQL capturing +using the options like below: + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + options => options.SetDbStatementForText = true) + .AddConsoleExporter() + .Build(); +``` + +> [!NOTE] +> When using the built-in `System.Data.SqlClient` only stored procedure +command names will ever be captured. When using the `Microsoft.Data.SqlClient` +NuGet package (v1.1+) stored procedure command names, full query text, and other +command text will be captured. + +### EnableConnectionLevelAttributes + +> [!NOTE] +> EnableConnectionLevelAttributes is supported on all runtimes. + +By default, `EnabledConnectionLevelAttributes` is disabled and this +instrumentation sets the `peer.service` attribute to the +[`DataSource`](https://docs.microsoft.com/dotnet/api/system.data.common.dbconnection.datasource) +property of the connection. If `EnabledConnectionLevelAttributes` is enabled, +the `DataSource` will be parsed and the server name will be sent as the +`net.peer.name` or `net.peer.ip` attribute, the instance name will be sent as +the `db.mssql.instance_name` attribute, and the port will be sent as the +`net.peer.port` attribute if it is not 1433 (the default port). + +The following example shows how to use `EnableConnectionLevelAttributes`. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + options => options.EnableConnectionLevelAttributes = true) + .AddConsoleExporter() + .Build(); +``` + +### Enrich + +> [!NOTE] +> Enrich is supported on .NET and .NET Core runtimes only. + +This option can be used to enrich the activity with additional information from +the raw `SqlCommand` object. The `Enrich` action is called only when +`activity.IsAllDataRequested` is `true`. It contains the activity itself (which +can be enriched), the name of the event, and the actual raw object. + +Currently there is only one event name reported, "OnCustom". The actual object +is `Microsoft.Data.SqlClient.SqlCommand` for `Microsoft.Data.SqlClient` and +`System.Data.SqlClient.SqlCommand` for `System.Data.SqlClient`. + +The following code snippet shows how to add additional tags using `Enrich`. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation(opt => opt.Enrich + = (activity, eventName, rawObject) => + { + if (eventName.Equals("OnCustom")) + { + if (rawObject is SqlCommand cmd) + { + activity.SetTag("db.commandTimeout", cmd.CommandTimeout); + } + }; + }) + .Build(); +``` + +[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the +general extensibility point to add additional properties to any activity. The +`Enrich` option is specific to this instrumentation, and is provided to get +access to `SqlCommand` object. + +### RecordException + +> [!NOTE] +> RecordException is supported on .NET and .NET Core runtimes only. + +This option can be set to instruct the instrumentation to record SqlExceptions +as Activity +[events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md). + +The default value is `false` and can be changed by the code like below. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + options => options.RecordException = true) + .AddConsoleExporter() + .Build(); +``` + +### Filter + +> [!NOTE] +> Filter is supported on .NET and .NET Core runtimes only. + +This option can be used to filter out activities based on the properties of the +`SqlCommand` object being instrumented using a `Func`. The +function receives an instance of the raw `SqlCommand` and should return `true` +if the telemetry is to be collected, and `false` if it should not. The parameter +of the Func delegate is of type `object` and needs to be cast to the appropriate +type of `SqlCommand`, either `Microsoft.Data.SqlClient.SqlCommand` or +`System.Data.SqlClient.SqlCommand`. The example below filters out all commands +that are not stored procedures. + +```csharp +using var traceProvider = Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + opt => + { + opt.Filter = cmd => + { + if (cmd is SqlCommand command) + { + return command.CommandType == CommandType.StoredProcedure; + } + + return false; + }; + }) + .AddConsoleExporter() + .Build(); +{ +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) + +* [OpenTelemetry semantic conventions for database + calls](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs new file mode 100644 index 0000000000..9b4230a460 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs @@ -0,0 +1,70 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using OpenTelemetry.Instrumentation.SqlClient.Implementation; + +namespace OpenTelemetry.Instrumentation.SqlClient; + +/// +/// SqlClient instrumentation. +/// +internal sealed class SqlClientInstrumentation : IDisposable +{ + internal const string SqlClientDiagnosticListenerName = "SqlClientDiagnosticListener"; +#if NET6_0_OR_GREATER + internal const string SqlClientTrimmingUnsupportedMessage = "Trimming is not yet supported with SqlClient instrumentation."; +#endif +#if NETFRAMEWORK + private readonly SqlEventSourceListener sqlEventSourceListener; +#else + private static readonly HashSet DiagnosticSourceEvents = new() + { + "System.Data.SqlClient.WriteCommandBefore", + "Microsoft.Data.SqlClient.WriteCommandBefore", + "System.Data.SqlClient.WriteCommandAfter", + "Microsoft.Data.SqlClient.WriteCommandAfter", + "System.Data.SqlClient.WriteCommandError", + "Microsoft.Data.SqlClient.WriteCommandError", + }; + + private readonly Func isEnabled = (eventName, _, _) + => DiagnosticSourceEvents.Contains(eventName); + + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; +#endif + + /// + /// Initializes a new instance of the class. + /// + /// Configuration options for sql instrumentation. +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] +#endif + public SqlClientInstrumentation( + SqlClientTraceInstrumentationOptions options = null) + { +#if NETFRAMEWORK + this.sqlEventSourceListener = new SqlEventSourceListener(options); +#else + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( + name => new SqlClientDiagnosticListener(name, options), + listener => listener.Name == SqlClientDiagnosticListenerName, + this.isEnabled, + SqlClientInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + this.diagnosticSourceSubscriber.Subscribe(); +#endif + } + + /// + public void Dispose() + { +#if NETFRAMEWORK + this.sqlEventSourceListener?.Dispose(); +#else + this.diagnosticSourceSubscriber?.Dispose(); +#endif + } +} diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs new file mode 100644 index 0000000000..3dec363163 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs @@ -0,0 +1,302 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Concurrent; +using System.Data; +using System.Diagnostics; +using System.Text.RegularExpressions; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.SqlClient; + +/// +/// Options for . +/// +/// +/// For help and examples see: . +/// +public class SqlClientTraceInstrumentationOptions +{ + /* + * Match... + * protocol[ ]:[ ]serverName + * serverName + * serverName[ ]\[ ]instanceName + * serverName[ ],[ ]port + * serverName[ ]\[ ]instanceName[ ],[ ]port + * + * [ ] can be any number of white-space, SQL allows it for some reason. + * + * Optional "protocol" can be "tcp", "lpc" (shared memory), or "np" (named pipes). See: + * https://docs.microsoft.com/troubleshoot/sql/connect/use-server-name-parameter-connection-string, and + * https://docs.microsoft.com/dotnet/api/system.data.sqlclient.sqlconnection.connectionstring?view=dotnet-plat-ext-5.0 + * + * In case of named pipes the Data Source string can take form of: + * np:serverName\instanceName, or + * np:\\serverName\pipe\pipeName, or + * np:\\serverName\pipe\MSSQL$instanceName\pipeName - in this case a separate regex (see NamedPipeRegex below) + * is used to extract instanceName + */ + private static readonly Regex DataSourceRegex = new("^(.*\\s*:\\s*\\\\{0,2})?(.*?)\\s*(?:[\\\\,]|$)\\s*(.*?)\\s*(?:,|$)\\s*(.*)$", RegexOptions.Compiled); + + /// + /// In a Data Source string like "np:\\serverName\pipe\MSSQL$instanceName\pipeName" match the + /// "pipe\MSSQL$instanceName" segment to extract instanceName if it is available. + /// + /// + /// + /// + private static readonly Regex NamedPipeRegex = new("pipe\\\\MSSQL\\$(.*?)\\\\", RegexOptions.Compiled); + + private static readonly ConcurrentDictionary ConnectionDetailCache = new(StringComparer.OrdinalIgnoreCase); + + /// + /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default + /// value: . + /// + /// + /// SetDbStatementForStoredProcedure is only supported on .NET + /// and .NET Core runtimes. + /// + public bool SetDbStatementForStoredProcedure { get; set; } = true; + + /// + /// Gets or sets a value indicating whether or not the should add the text of commands as + /// the tag. + /// Default value: . + /// + /// + /// + /// WARNING: SetDbStatementForText will capture the raw + /// CommandText. Make sure your CommandText property never + /// contains any sensitive data. + /// + /// SetDbStatementForText is supported on all runtimes. + /// + /// On .NET and .NET Core SetDbStatementForText only applies to + /// SqlCommands with . + /// On .NET Framework SetDbStatementForText applies to all + /// SqlCommands regardless of . + /// + /// When using System.Data.SqlClient use + /// SetDbStatementForText to capture StoredProcedure command + /// names. + /// When using Microsoft.Data.SqlClient use + /// SetDbStatementForText to capture Text, StoredProcedure, and all + /// other command text. + /// + /// + /// + /// + public bool SetDbStatementForText { get; set; } + + /// + /// Gets or sets a value indicating whether or not the should parse the DataSource on a + /// SqlConnection into server name, instance name, and/or port + /// connection-level attribute tags. Default value: . + /// + /// + /// + /// EnableConnectionLevelAttributes is supported on all runtimes. + /// + /// + /// The default behavior is to set the SqlConnection DataSource as the tag. + /// If enabled, SqlConnection DataSource will be parsed and the server name will be sent as the + /// or tag, + /// the instance name will be sent as the tag, + /// and the port will be sent as the tag if it is not 1433 (the default port). + /// + /// + public bool EnableConnectionLevelAttributes { get; set; } + + /// + /// Gets or sets an action to enrich an with the + /// raw SqlCommand object. + /// + /// + /// Enrich is only executed on .NET and .NET Core + /// runtimes. + /// The parameters passed to the enrich action are: + /// + /// The being enriched. + /// The name of the event. Currently only "OnCustom" is + /// used but more events may be added in the future. + /// The raw SqlCommand object from which additional + /// information can be extracted to enrich the . + /// + /// + public Action Enrich { get; set; } + + /// + /// Gets or sets a filter function that determines whether or not to + /// collect telemetry about a command. + /// + /// + /// Filter is only executed on .NET and .NET Core + /// runtimes. + /// Notes: + /// + /// The first parameter passed to the filter function is the raw + /// SqlCommand object for the command being executed. + /// The return value for the filter function is interpreted as: + /// + /// If filter returns , the command is + /// collected. + /// If filter returns or throws an + /// exception the command is NOT collected. + /// + /// + /// + public Func Filter { get; set; } + + /// + /// Gets or sets a value indicating whether the exception will be + /// recorded as or not. Default value: . + /// + /// + /// RecordException is only supported on .NET and .NET Core + /// runtimes. + /// For specification details see: . + /// + public bool RecordException { get; set; } + + internal static SqlConnectionDetails ParseDataSource(string dataSource) + { + Match match = DataSourceRegex.Match(dataSource); + + string serverHostName = match.Groups[2].Value; + string serverIpAddress = null; + + string instanceName; + + var uriHostNameType = Uri.CheckHostName(serverHostName); + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + { + serverIpAddress = serverHostName; + serverHostName = null; + } + + string maybeProtocol = match.Groups[1].Value; + bool isNamedPipe = maybeProtocol.Length > 0 && + maybeProtocol.StartsWith("np", StringComparison.OrdinalIgnoreCase); + + if (isNamedPipe) + { + string pipeName = match.Groups[3].Value; + if (pipeName.Length > 0) + { + var namedInstancePipeMatch = NamedPipeRegex.Match(pipeName); + if (namedInstancePipeMatch.Success) + { + instanceName = namedInstancePipeMatch.Groups[1].Value; + return new SqlConnectionDetails + { + ServerHostName = serverHostName, + ServerIpAddress = serverIpAddress, + InstanceName = instanceName, + Port = null, + }; + } + } + + return new SqlConnectionDetails + { + ServerHostName = serverHostName, + ServerIpAddress = serverIpAddress, + InstanceName = null, + Port = null, + }; + } + + string port; + if (match.Groups[4].Length > 0) + { + instanceName = match.Groups[3].Value; + port = match.Groups[4].Value; + if (port == "1433") + { + port = null; + } + } + else if (int.TryParse(match.Groups[3].Value, out int parsedPort)) + { + port = parsedPort == 1433 ? null : match.Groups[3].Value; + instanceName = null; + } + else + { + instanceName = match.Groups[3].Value; + + if (string.IsNullOrEmpty(instanceName)) + { + instanceName = null; + } + + port = null; + } + + return new SqlConnectionDetails + { + ServerHostName = serverHostName, + ServerIpAddress = serverIpAddress, + InstanceName = instanceName, + Port = port, + }; + } + + internal void AddConnectionLevelDetailsToActivity(string dataSource, Activity sqlActivity) + { + if (!this.EnableConnectionLevelAttributes) + { + sqlActivity.SetTag(SemanticConventions.AttributePeerService, dataSource); + } + else + { + if (!ConnectionDetailCache.TryGetValue(dataSource, out SqlConnectionDetails connectionDetails)) + { + connectionDetails = ParseDataSource(dataSource); + ConnectionDetailCache.TryAdd(dataSource, connectionDetails); + } + + if (!string.IsNullOrEmpty(connectionDetails.InstanceName)) + { + sqlActivity.SetTag(SemanticConventions.AttributeDbMsSqlInstanceName, connectionDetails.InstanceName); + } + + if (!string.IsNullOrEmpty(connectionDetails.ServerHostName)) + { + sqlActivity.SetTag(SemanticConventions.AttributeServerAddress, connectionDetails.ServerHostName); + } + else + { + sqlActivity.SetTag(SemanticConventions.AttributeServerSocketAddress, connectionDetails.ServerIpAddress); + } + + if (!string.IsNullOrEmpty(connectionDetails.Port)) + { + // TODO: Should we continue to emit this if the default port (1433) is being used? + sqlActivity.SetTag(SemanticConventions.AttributeServerPort, connectionDetails.Port); + } + } + } + + internal sealed class SqlConnectionDetails + { + public string ServerHostName { get; set; } + + public string ServerIpAddress { get; set; } + + public string InstanceName { get; set; } + + public string Port { get; set; } + } +} diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..9634759bcc --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs @@ -0,0 +1,81 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.SqlClient; +using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class TracerProviderBuilderExtensions +{ + /// + /// Enables SqlClient instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] +#endif + public static TracerProviderBuilder AddSqlClientInstrumentation(this TracerProviderBuilder builder) + => AddSqlClientInstrumentation(builder, name: null, configureSqlClientTraceInstrumentationOptions: null); + + /// + /// Enables SqlClient instrumentation. + /// + /// being configured. + /// Callback action for configuring . + /// The instance of to chain the calls. +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] +#endif + public static TracerProviderBuilder AddSqlClientInstrumentation( + this TracerProviderBuilder builder, + Action configureSqlClientTraceInstrumentationOptions) + => AddSqlClientInstrumentation(builder, name: null, configureSqlClientTraceInstrumentationOptions); + + /// + /// Enables SqlClient instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. +#if NET6_0_OR_GREATER + [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] +#endif + + public static TracerProviderBuilder AddSqlClientInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configureSqlClientTraceInstrumentationOptions) + { + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; + + if (configureSqlClientTraceInstrumentationOptions != null) + { + builder.ConfigureServices(services => services.Configure(name, configureSqlClientTraceInstrumentationOptions)); + } + + builder.AddInstrumentation(sp => + { + var sqlOptions = sp.GetRequiredService>().Get(name); + + return new SqlClientInstrumentation(sqlOptions); + }); + + builder.AddSource(SqlActivitySourceHelper.ActivitySourceName); + + return builder; + } +} diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 0d9fe00f87..6c70b8c54c 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -103,12 +103,17 @@ internal static class SemanticConventions public const string AttributeHttpRequestMethodOriginal = "http.request.method_original"; public const string AttributeHttpResponseStatusCode = "http.response.status_code"; // replaces: "http.status_code" (AttributeHttpStatusCode) public const string AttributeUrlScheme = "url.scheme"; // replaces: "http.scheme" (AttributeHttpScheme) + public const string AttributeUrlFull = "url.full"; // replaces: "http.url" (AttributeHttpUrl) public const string AttributeUrlPath = "url.path"; // replaces: "http.target" (AttributeHttpTarget) public const string AttributeUrlQuery = "url.query"; // replaces: "http.target" (AttributeHttpTarget) + public const string AttributeServerSocketAddress = "server.socket.address"; // replaces: "net.peer.ip" (AttributeNetPeerIp) // v1.23.0 // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md#http-server + public const string AttributeClientAddress = "client.address"; + public const string AttributeClientPort = "client.port"; public const string AttributeNetworkProtocolVersion = "network.protocol.version"; // replaces: "http.flavor" (AttributeHttpFlavor) + public const string AttributeNetworkProtocolName = "network.protocol.name"; public const string AttributeServerAddress = "server.address"; // replaces: "net.host.name" (AttributeNetHostName) public const string AttributeServerPort = "server.port"; // replaces: "net.host.port" (AttributeNetHostPort) public const string AttributeUserAgentOriginal = "user_agent.original"; // replaces: http.user_agent (AttributeHttpUserAgent) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 2e29e2d52c..1b5143a588 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -22,6 +22,7 @@ + diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EnabledOnDockerPlatformTheoryAttribute.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EnabledOnDockerPlatformTheoryAttribute.cs new file mode 100644 index 0000000000..ef96054645 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EnabledOnDockerPlatformTheoryAttribute.cs @@ -0,0 +1,76 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma warning disable IDE0005 // Using directive is unnecessary.using System; +using System; +using System.Diagnostics; +using System.Text; +using Xunit; +#pragma warning restore IDE0005 // Using directive is unnecessary. + +namespace OpenTelemetry.Tests; + +/// +/// This skips tests if the required Docker engine is not available. +/// +internal class EnabledOnDockerPlatformTheoryAttribute : TheoryAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public EnabledOnDockerPlatformTheoryAttribute(DockerPlatform dockerPlatform) + { + const string executable = "docker"; + + var stdout = new StringBuilder(); + var stderr = new StringBuilder(); + + void AppendStdout(object sender, DataReceivedEventArgs e) => stdout.Append(e.Data); + void AppendStderr(object sender, DataReceivedEventArgs e) => stderr.Append(e.Data); + + var processStartInfo = new ProcessStartInfo(); + processStartInfo.FileName = executable; + processStartInfo.Arguments = string.Join(" ", "version", "--format '{{.Server.Os}}'"); + processStartInfo.RedirectStandardOutput = true; + processStartInfo.RedirectStandardError = true; + processStartInfo.UseShellExecute = false; + + var process = new Process(); + process.StartInfo = processStartInfo; + process.OutputDataReceived += AppendStdout; + process.ErrorDataReceived += AppendStderr; + + try + { + process.Start(); + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + process.WaitForExit(); + } + finally + { + process.OutputDataReceived -= AppendStdout; + process.ErrorDataReceived -= AppendStderr; + } + + if (0.Equals(process.ExitCode) && stdout.ToString().IndexOf(dockerPlatform.ToString(), StringComparison.OrdinalIgnoreCase) > 0) + { + return; + } + + this.Skip = $"The Docker {dockerPlatform} engine is not available."; + } + + public enum DockerPlatform + { + /// + /// Docker Linux engine. + /// + Linux, + + /// + /// Docker Windows engine. + /// + Windows, + } +} diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs index ced10b60e9..b7a88fa1af 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs @@ -3,12 +3,14 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Collections.Generic; using System.Diagnostics.Tracing; using System.Globalization; using System.Linq; using System.Reflection; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj index d6e2eeff92..78b3d66688 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj +++ b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj @@ -1,7 +1,8 @@ - netstandard2.0;net462;net6.0;net8.0 + net8.0;net6.0 + $(TargetFrameworks);net462 false diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs index d0a102d9d2..57182d6232 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs @@ -3,10 +3,12 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Collections.Generic; using System.Diagnostics.Tracing; using System.Threading; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs index 8bee1c8e66..90c3e769c7 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs @@ -3,8 +3,10 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using OpenTelemetry.Trace; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/EventSourceTest.cs new file mode 100644 index 0000000000..27a4886967 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/EventSourceTest.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public class EventSourceTest +{ + [Fact] + public void EventSourceTest_SqlClientInstrumentationEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(SqlClientInstrumentationEventSource.Log); + } +} diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj new file mode 100644 index 0000000000..4d979780d9 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -0,0 +1,31 @@ + + + Unit test project for OpenTelemetry SqlClient instrumentations + net8.0;net7.0;net6.0 + $(TargetFrameworks);net462 + enable + + disable + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs new file mode 100644 index 0000000000..9b77fe5deb --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -0,0 +1,118 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Data; +using System.Diagnostics; +using System.Runtime.InteropServices; +using DotNet.Testcontainers.Containers; +using Microsoft.Data.SqlClient; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Testcontainers.MsSql; +using Testcontainers.SqlEdge; +using Xunit; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public sealed class SqlClientIntegrationTests : IAsyncLifetime +{ + // The Microsoft SQL Server Docker image is not compatible with ARM devices, such as Macs with Apple Silicon. + private readonly IContainer databaseContainer = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? new SqlEdgeBuilder().Build() : new MsSqlBuilder().Build(); + + public Task InitializeAsync() + { + return this.databaseContainer.StartAsync(); + } + + public Task DisposeAsync() + { + return this.databaseContainer.DisposeAsync().AsTask(); + } + + [Trait("CategoryName", "SqlIntegrationTests")] + [EnabledOnDockerPlatformTheory(EnabledOnDockerPlatformTheoryAttribute.DockerPlatform.Linux)] + [InlineData(CommandType.Text, "select 1/1", false)] + [InlineData(CommandType.Text, "select 1/1", false, true)] + [InlineData(CommandType.Text, "select 1/0", false, false, true)] + [InlineData(CommandType.Text, "select 1/0", false, false, true, false, false)] + [InlineData(CommandType.Text, "select 1/0", false, false, true, true, false)] + [InlineData(CommandType.StoredProcedure, "sp_who", false)] + [InlineData(CommandType.StoredProcedure, "sp_who", true)] + public void SuccessfulCommandTest( + CommandType commandType, + string commandText, + bool captureStoredProcedureCommandName, + bool captureTextCommandContent = false, + bool isFailure = false, + bool recordException = false, + bool shouldEnrich = true) + { +#if NETFRAMEWORK + // Disable things not available on netfx + recordException = false; + shouldEnrich = false; +#endif + + var sampler = new TestSampler(); + var activities = new List(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(sampler) + .AddInMemoryExporter(activities) + .AddSqlClientInstrumentation(options => + { +#if !NETFRAMEWORK + options.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName; + options.SetDbStatementForText = captureTextCommandContent; +#else + options.SetDbStatementForText = captureStoredProcedureCommandName || captureTextCommandContent; +#endif + options.RecordException = recordException; + if (shouldEnrich) + { + options.Enrich = SqlClientTests.ActivityEnrichment; + } + }) + .Build(); + + using SqlConnection sqlConnection = new SqlConnection(this.GetConnectionString()); + + sqlConnection.Open(); + + string dataSource = sqlConnection.DataSource; + + sqlConnection.ChangeDatabase("master"); +#pragma warning disable CA2100 + using SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection) +#pragma warning restore CA2100 + { + CommandType = commandType, + }; + + try + { + sqlCommand.ExecuteNonQuery(); + } + catch + { + } + + Assert.Single(activities); + var activity = activities[0]; + + SqlClientTests.VerifyActivityData(commandType, commandText, captureStoredProcedureCommandName, captureTextCommandContent, isFailure, recordException, shouldEnrich, dataSource, activity); + SqlClientTests.VerifySamplingParameters(sampler.LatestSamplingParameters); + } + + private string GetConnectionString() + { + switch (this.databaseContainer) + { + case SqlEdgeContainer container: + return container.GetConnectionString(); + case MsSqlContainer container: + return container.GetConnectionString(); + default: + throw new InvalidOperationException($"Container type ${this.databaseContainer.GetType().Name} not supported."); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs new file mode 100644 index 0000000000..6dd7e7e3fb --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -0,0 +1,468 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Data; +using System.Diagnostics; +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public class SqlClientTests : IDisposable +{ +#if !NETFRAMEWORK + private const string TestConnectionString = "Data Source=(localdb)\\MSSQLLocalDB;Database=master"; +#endif + + private readonly FakeSqlClientDiagnosticSource fakeSqlClientDiagnosticSource; + + public SqlClientTests() + { + this.fakeSqlClientDiagnosticSource = new FakeSqlClientDiagnosticSource(); + } + + public void Dispose() + { + this.fakeSqlClientDiagnosticSource.Dispose(); + GC.SuppressFinalize(this); + } + + [Fact] + public void SqlClient_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddSqlClientInstrumentation()); + } + + [Fact] + public void SqlClient_NamedOptions() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Instrumentation2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddSqlClientInstrumentation() + .AddSqlClientInstrumentation("Instrumentation2", configureSqlClientTraceInstrumentationOptions: null) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + + // DiagnosticListener-based instrumentation is only available on .NET Core +#if !NETFRAMEWORK + [Theory] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, false)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, false)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, false)] + public void SqlClientCallsAreCollectedSuccessfully( + string beforeCommand, + string afterCommand, + CommandType commandType, + string commandText, + bool captureStoredProcedureCommandName, + bool captureTextCommandContent, + bool shouldEnrich = true) + { + using var sqlConnection = new SqlConnection(TestConnectionString); + using var sqlCommand = sqlConnection.CreateCommand(); + + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + (opt) => + { + opt.SetDbStatementForText = captureTextCommandContent; + opt.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName; + if (shouldEnrich) + { + opt.Enrich = ActivityEnrichment; + } + }) + .AddInMemoryExporter(activities) + .Build()) + { + var operationId = Guid.NewGuid(); + sqlCommand.CommandType = commandType; +#pragma warning disable CA2100 + sqlCommand.CommandText = commandText; +#pragma warning restore CA2100 + + var beforeExecuteEventData = new + { + OperationId = operationId, + Command = sqlCommand, + Timestamp = (long?)1000000L, + }; + + this.fakeSqlClientDiagnosticSource.Write( + beforeCommand, + beforeExecuteEventData); + + var afterExecuteEventData = new + { + OperationId = operationId, + Command = sqlCommand, + Timestamp = 2000000L, + }; + + this.fakeSqlClientDiagnosticSource.Write( + afterCommand, + afterExecuteEventData); + } + + Assert.Single(activities); + var activity = activities[0]; + + VerifyActivityData( + sqlCommand.CommandType, + sqlCommand.CommandText, + captureStoredProcedureCommandName, + captureTextCommandContent, + false, + false, + shouldEnrich, + sqlConnection.DataSource, + activity); + } + + [Theory] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataWriteCommandError)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataWriteCommandError, false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataWriteCommandError, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError, false)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError, false, true)] + public void SqlClientErrorsAreCollectedSuccessfully(string beforeCommand, string errorCommand, bool shouldEnrich = true, bool recordException = false) + { + using var sqlConnection = new SqlConnection(TestConnectionString); + using var sqlCommand = sqlConnection.CreateCommand(); + + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation(options => + { + options.RecordException = recordException; + if (shouldEnrich) + { + options.Enrich = ActivityEnrichment; + } + }) + .AddInMemoryExporter(activities) + .Build()) + { + var operationId = Guid.NewGuid(); + sqlCommand.CommandText = "SP_GetOrders"; + sqlCommand.CommandType = CommandType.StoredProcedure; + + var beforeExecuteEventData = new + { + OperationId = operationId, + Command = sqlCommand, + Timestamp = (long?)1000000L, + }; + + this.fakeSqlClientDiagnosticSource.Write( + beforeCommand, + beforeExecuteEventData); + + var commandErrorEventData = new + { + OperationId = operationId, + Command = sqlCommand, + Exception = new Exception("Boom!"), + Timestamp = 2000000L, + }; + + this.fakeSqlClientDiagnosticSource.Write( + errorCommand, + commandErrorEventData); + } + + Assert.Single(activities); + var activity = activities[0]; + + VerifyActivityData( + sqlCommand.CommandType, + sqlCommand.CommandText, + true, + false, + true, + recordException, + shouldEnrich, + sqlConnection.DataSource, + activity); + } + + [Theory] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand)] + public void SqlClientCreatesActivityWithDbSystem( + string beforeCommand) + { + using var sqlConnection = new SqlConnection(TestConnectionString); + using var sqlCommand = sqlConnection.CreateCommand(); + + var sampler = new TestSampler + { + SamplingAction = _ => new SamplingResult(SamplingDecision.Drop), + }; + using (Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation() + .SetSampler(sampler) + .Build()) + { + this.fakeSqlClientDiagnosticSource.Write(beforeCommand, new { }); + } + + VerifySamplingParameters(sampler.LatestSamplingParameters); + } + + [Fact] + public void ShouldCollectTelemetryWhenFilterEvaluatesToTrue() + { + var activities = this.RunCommandWithFilter( + cmd => + { + cmd.CommandText = "select 2"; + }, + cmd => + { + if (cmd is SqlCommand command) + { + return command.CommandText == "select 2"; + } + + return true; + }); + + Assert.Single(activities); + Assert.True(activities[0].IsAllDataRequested); + Assert.True(activities[0].ActivityTraceFlags.HasFlag(ActivityTraceFlags.Recorded)); + } + + [Fact] + public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalse() + { + var activities = this.RunCommandWithFilter( + cmd => + { + cmd.CommandText = "select 1"; + }, + cmd => + { + if (cmd is SqlCommand command) + { + return command.CommandText == "select 2"; + } + + return true; + }); + + Assert.Empty(activities); + } + + [Fact] + public void ShouldNotCollectTelemetryAndShouldNotPropagateExceptionWhenFilterThrowsException() + { + var activities = this.RunCommandWithFilter( + cmd => + { + cmd.CommandText = "select 1"; + }, + cmd => throw new InvalidOperationException("foobar")); + + Assert.Empty(activities); + } +#endif + + internal static void VerifyActivityData( + CommandType commandType, + string commandText, + bool captureStoredProcedureCommandName, + bool captureTextCommandContent, + bool isFailure, + bool recordException, + bool shouldEnrich, + string dataSource, + Activity activity) + { + Assert.Equal("master", activity.DisplayName); + Assert.Equal(ActivityKind.Client, activity.Kind); + + if (!isFailure) + { + Assert.Equal(ActivityStatusCode.Unset, activity.Status); + } + else + { + var status = activity.GetStatus(); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.NotNull(activity.StatusDescription); + + if (recordException) + { + var events = activity.Events.ToList(); + Assert.Single(events); + + Assert.Equal(SemanticConventions.AttributeExceptionEventName, events[0].Name); + } + else + { + Assert.Empty(activity.Events); + } + } + + if (shouldEnrich) + { + Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enriched")); + Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enriched").FirstOrDefault().Value); + } + else + { + Assert.Empty(activity.Tags.Where(tag => tag.Key == "enriched")); + } + + Assert.Equal(SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName, activity.GetTagValue(SemanticConventions.AttributeDbSystem)); + Assert.Equal("master", activity.GetTagValue(SemanticConventions.AttributeDbName)); + + switch (commandType) + { + case CommandType.StoredProcedure: + if (captureStoredProcedureCommandName) + { + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + else + { + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + + break; + + case CommandType.Text: + if (captureTextCommandContent) + { + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + else + { + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + + break; + } + + Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributePeerService)); + } + + internal static void VerifySamplingParameters(SamplingParameters samplingParameters) + { + Assert.NotNull(samplingParameters.Tags); + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeDbSystem + && (string)kvp.Value == SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName); + } + + internal static void ActivityEnrichment(Activity activity, string method, object obj) + { + activity.SetTag("enriched", "yes"); + + switch (method) + { + case "OnCustom": + Assert.True(obj is SqlCommand); + break; + + default: + break; + } + } + +#if !NETFRAMEWORK + private Activity[] RunCommandWithFilter( + Action sqlCommandSetup, + Func filter) + { + using var sqlConnection = new SqlConnection(TestConnectionString); + using var sqlCommand = sqlConnection.CreateCommand(); + + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation( + options => + { + options.Filter = filter; + }) + .AddInMemoryExporter(activities) + .Build()) + { + var operationId = Guid.NewGuid(); + sqlCommandSetup(sqlCommand); + + var beforeExecuteEventData = new + { + OperationId = operationId, + Command = sqlCommand, + Timestamp = (long?)1000000L, + }; + + this.fakeSqlClientDiagnosticSource.Write( + SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, + beforeExecuteEventData); + + var afterExecuteEventData = new + { + OperationId = operationId, + Command = sqlCommand, + Timestamp = 2000000L, + }; + + this.fakeSqlClientDiagnosticSource.Write( + SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, + afterExecuteEventData); + } + + return activities.ToArray(); + } +#endif + + private class FakeSqlClientDiagnosticSource : IDisposable + { + private readonly DiagnosticListener listener; + + public FakeSqlClientDiagnosticSource() + { + this.listener = new DiagnosticListener(SqlClientInstrumentation.SqlClientDiagnosticListenerName); + } + + public void Write(string name, object value) + { + if (this.listener.IsEnabled(name)) + { + this.listener.Write(name, value); + } + } + + public void Dispose() + { + this.listener.Dispose(); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs new file mode 100644 index 0000000000..306804929c --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs @@ -0,0 +1,93 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public class SqlClientTraceInstrumentationOptionsTests +{ + static SqlClientTraceInstrumentationOptionsTests() + { + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + Activity.ForceDefaultIdFormat = true; + + var listener = new ActivityListener + { + ShouldListenTo = _ => true, + Sample = (ref ActivityCreationOptions options) => ActivitySamplingResult.AllData, + }; + + ActivitySource.AddActivityListener(listener); + } + + [Theory] + [InlineData("localhost", "localhost", null, null, null)] + [InlineData("127.0.0.1", null, "127.0.0.1", null, null)] + [InlineData("127.0.0.1,1433", null, "127.0.0.1", null, null)] + [InlineData("127.0.0.1, 1818", null, "127.0.0.1", null, "1818")] + [InlineData("127.0.0.1 \\ instanceName", null, "127.0.0.1", "instanceName", null)] + [InlineData("127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", "1818")] + [InlineData("tcp:127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", "1818")] + [InlineData("tcp:localhost", "localhost", null, null, null)] + [InlineData("tcp : localhost", "localhost", null, null, null)] + [InlineData("np : localhost", "localhost", null, null, null)] + [InlineData("lpc:localhost", "localhost", null, null, null)] + [InlineData("np:\\\\localhost\\pipe\\sql\\query", "localhost", null, null, null)] + [InlineData("np : \\\\localhost\\pipe\\sql\\query", "localhost", null, null, null)] + [InlineData("np:\\\\localhost\\pipe\\MSSQL$instanceName\\sql\\query", "localhost", null, "instanceName", null)] + public void ParseDataSourceTests( + string dataSource, + string expectedServerHostName, + string expectedServerIpAddress, + string expectedInstanceName, + string expectedPort) + { + var sqlConnectionDetails = SqlClientTraceInstrumentationOptions.ParseDataSource(dataSource); + + Assert.NotNull(sqlConnectionDetails); + Assert.Equal(expectedServerHostName, sqlConnectionDetails.ServerHostName); + Assert.Equal(expectedServerIpAddress, sqlConnectionDetails.ServerIpAddress); + Assert.Equal(expectedInstanceName, sqlConnectionDetails.InstanceName); + Assert.Equal(expectedPort, sqlConnectionDetails.Port); + } + + [Theory] + [InlineData(true, "localhost", "localhost", null, null, null)] + [InlineData(true, "127.0.0.1,1433", null, "127.0.0.1", null, null)] + [InlineData(true, "127.0.0.1,1434", null, "127.0.0.1", null, "1434")] + [InlineData(true, "127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", "1818")] + [InlineData(false, "localhost", "localhost", null, null, null)] + public void SqlClientTraceInstrumentationOptions_EnableConnectionLevelAttributes( + bool enableConnectionLevelAttributes, + string dataSource, + string expectedServerHostName, + string expectedServerIpAddress, + string expectedInstanceName, + string expectedPort) + { + var source = new ActivitySource("sql-client-instrumentation"); + var activity = source.StartActivity("Test Sql Activity"); + var options = new SqlClientTraceInstrumentationOptions() + { + EnableConnectionLevelAttributes = enableConnectionLevelAttributes, + }; + options.AddConnectionLevelDetailsToActivity(dataSource, activity); + + if (!enableConnectionLevelAttributes) + { + Assert.Equal(expectedServerHostName, activity.GetTagValue(SemanticConventions.AttributePeerService)); + } + else + { + Assert.Equal(expectedServerHostName, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + } + + Assert.Equal(expectedServerIpAddress, activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress)); + Assert.Equal(expectedInstanceName, activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); + Assert.Equal(expectedPort, activity.GetTagValue(SemanticConventions.AttributeServerPort)); + } +} diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs new file mode 100644 index 0000000000..1f48748e28 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -0,0 +1,371 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Data; +using System.Data.SqlClient; +using System.Diagnostics; +using System.Diagnostics.Tracing; +using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public class SqlEventSourceTests +{ + /* + To run the integration tests, set the OTEL_SQLCONNECTIONSTRING machine-level environment variable to a valid Sql Server connection string. + + To use Docker... + 1) Run: docker run -d --name sql2019 -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=Pass@word" -p 5433:1433 mcr.microsoft.com/mssql/server:2019-latest + 2) Set OTEL_SQLCONNECTIONSTRING as: Data Source=127.0.0.1,5433; User ID=sa; Password=Pass@word + */ + + private const string SqlConnectionStringEnvVarName = "OTEL_SQLCONNECTIONSTRING"; + private static readonly string SqlConnectionString = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(SqlConnectionStringEnvVarName); + + [Trait("CategoryName", "SqlIntegrationTests")] + [SkipUnlessEnvVarFoundTheory(SqlConnectionStringEnvVarName)] + [InlineData(CommandType.Text, "select 1/1", false)] + [InlineData(CommandType.Text, "select 1/0", false, true)] + [InlineData(CommandType.StoredProcedure, "sp_who", false)] + [InlineData(CommandType.StoredProcedure, "sp_who", true)] + public async Task SuccessfulCommandTest(CommandType commandType, string commandText, bool captureText, bool isFailure = false) + { + var exportedItems = new List(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddSqlClientInstrumentation(options => + { + options.SetDbStatementForText = captureText; + }) + .Build(); + + using SqlConnection sqlConnection = new SqlConnection(SqlConnectionString); + + await sqlConnection.OpenAsync(); + + string dataSource = sqlConnection.DataSource; + + sqlConnection.ChangeDatabase("master"); + +#pragma warning disable CA2100 + using SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection) +#pragma warning restore CA2100 + { + CommandType = commandType, + }; + + try + { + await sqlCommand.ExecuteNonQueryAsync(); + } + catch + { + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + VerifyActivityData(commandText, captureText, isFailure, dataSource, activity); + } + + [Theory] + [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/1", false)] + [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/0", false, true)] + [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", false)] + [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true)] + [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/1", false)] + [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/0", false, true)] + [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", false)] + [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true)] + public void EventSourceFakeTests( + Type eventSourceType, + CommandType commandType, + string commandText, + bool captureText, + bool isFailure = false, + int sqlExceptionNumber = 0, + bool enableConnectionLevelAttributes = false) + { + using IFakeBehavingSqlEventSource fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + + var exportedItems = new List(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddSqlClientInstrumentation(options => + { + options.SetDbStatementForText = captureText; + options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; + }) + .Build(); + + int objectId = Guid.NewGuid().GetHashCode(); + + fakeSqlEventSource.WriteBeginExecuteEvent(objectId, "127.0.0.1", "master", commandType == CommandType.StoredProcedure ? commandText : string.Empty); + + // success is stored in the first bit in compositeState 0b001 + int successFlag = !isFailure ? 1 : 0; + + // isSqlException is stored in the second bit in compositeState 0b010 + int isSqlExceptionFlag = sqlExceptionNumber > 0 ? 2 : 0; + + // synchronous state is stored in the third bit in compositeState 0b100 + int synchronousFlag = false ? 4 : 0; + + int compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; + + fakeSqlEventSource.WriteEndExecuteEvent(objectId, compositeState, sqlExceptionNumber); + shutdownSignal.Dispose(); + Assert.Single(exportedItems); + + var activity = exportedItems[0]; + + VerifyActivityData(commandText, captureText, isFailure, "127.0.0.1", activity, enableConnectionLevelAttributes); + } + + [Theory] + [InlineData(typeof(FakeMisbehavingAdoNetSqlEventSource))] + [InlineData(typeof(FakeMisbehavingMdsSqlEventSource))] + public void EventSourceFakeUnknownEventWithNullPayloadTest(Type eventSourceType) + { + using IFakeMisbehavingSqlEventSource fakeSqlEventSource = (IFakeMisbehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + + var exportedItems = new List(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddSqlClientInstrumentation() + .Build(); + + fakeSqlEventSource.WriteUnknownEventWithNullPayload(); + + shutdownSignal.Dispose(); + + Assert.Empty(exportedItems); + } + + [Theory] + [InlineData(typeof(FakeMisbehavingAdoNetSqlEventSource))] + [InlineData(typeof(FakeMisbehavingMdsSqlEventSource))] + public void EventSourceFakeInvalidPayloadTest(Type eventSourceType) + { + using IFakeMisbehavingSqlEventSource fakeSqlEventSource = (IFakeMisbehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + + var exportedItems = new List(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddSqlClientInstrumentation() + .Build(); + + fakeSqlEventSource.WriteBeginExecuteEvent("arg1"); + + fakeSqlEventSource.WriteEndExecuteEvent("arg1", "arg2", "arg3", "arg4"); + shutdownSignal.Dispose(); + + Assert.Empty(exportedItems); + } + + [Theory] + [InlineData(typeof(FakeBehavingAdoNetSqlEventSource))] + [InlineData(typeof(FakeBehavingMdsSqlEventSource))] + public void DefaultCaptureTextFalse(Type eventSourceType) + { + using IFakeBehavingSqlEventSource fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + + var exportedItems = new List(); + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddSqlClientInstrumentation() + .Build(); + + int objectId = Guid.NewGuid().GetHashCode(); + + const string commandText = "TestCommandTest"; + fakeSqlEventSource.WriteBeginExecuteEvent(objectId, "127.0.0.1", "master", commandText); + + // success is stored in the first bit in compositeState 0b001 + int successFlag = 1; + + // isSqlException is stored in the second bit in compositeState 0b010 + int isSqlExceptionFlag = 2; + + // synchronous state is stored in the third bit in compositeState 0b100 + int synchronousFlag = 4; + + int compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; + + fakeSqlEventSource.WriteEndExecuteEvent(objectId, compositeState, 0); + shutdownSignal.Dispose(); + Assert.Single(exportedItems); + + var activity = exportedItems[0]; + + const bool captureText = false; + VerifyActivityData(commandText, captureText, false, "127.0.0.1", activity, false); + } + + private static void VerifyActivityData( + string commandText, + bool captureText, + bool isFailure, + string dataSource, + Activity activity, + bool enableConnectionLevelAttributes = false) + { + Assert.Equal("master", activity.DisplayName); + Assert.Equal(ActivityKind.Client, activity.Kind); + Assert.Equal(SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName, activity.GetTagValue(SemanticConventions.AttributeDbSystem)); + + if (!enableConnectionLevelAttributes) + { + Assert.Equal(dataSource, activity.GetTagValue(SemanticConventions.AttributePeerService)); + } + else + { + var connectionDetails = SqlClientTraceInstrumentationOptions.ParseDataSource(dataSource); + + if (!string.IsNullOrEmpty(connectionDetails.ServerHostName)) + { + Assert.Equal(connectionDetails.ServerHostName, activity.GetTagValue(SemanticConventions.AttributeNetPeerName)); + } + else + { + Assert.Equal(connectionDetails.ServerIpAddress, activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress)); + } + + if (!string.IsNullOrEmpty(connectionDetails.InstanceName)) + { + Assert.Equal(connectionDetails.InstanceName, activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); + } + + if (!string.IsNullOrEmpty(connectionDetails.Port)) + { + Assert.Equal(connectionDetails.Port, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + } + } + + Assert.Equal("master", activity.GetTagValue(SemanticConventions.AttributeDbName)); + + if (captureText) + { + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + else + { + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); + } + + if (!isFailure) + { + Assert.Equal(ActivityStatusCode.Unset, activity.Status); + } + else + { + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.NotNull(activity.StatusDescription); + } + } + +#pragma warning disable SA1201 // Elements should appear in the correct order + + // Helper interface to be able to have single test method for multiple EventSources, want to keep it close to the event sources themselves. + private interface IFakeBehavingSqlEventSource : IDisposable +#pragma warning restore SA1201 // Elements should appear in the correct order + { + void WriteBeginExecuteEvent(int objectId, string dataSource, string databaseName, string commandText); + + void WriteEndExecuteEvent(int objectId, int compositeState, int sqlExceptionNumber); + } + + private interface IFakeMisbehavingSqlEventSource : IDisposable + { + void WriteBeginExecuteEvent(string arg1); + + void WriteEndExecuteEvent(string arg1, string arg2, string arg3, string arg4); + + void WriteUnknownEventWithNullPayload(); + } + + [EventSource(Name = SqlEventSourceListener.AdoNetEventSourceName + "-FakeFriendly")] + private class FakeBehavingAdoNetSqlEventSource : EventSource, IFakeBehavingSqlEventSource + { + [Event(SqlEventSourceListener.BeginExecuteEventId)] + public void WriteBeginExecuteEvent(int objectId, string dataSource, string databaseName, string commandText) + { + this.WriteEvent(SqlEventSourceListener.BeginExecuteEventId, objectId, dataSource, databaseName, commandText); + } + + [Event(SqlEventSourceListener.EndExecuteEventId)] + public void WriteEndExecuteEvent(int objectId, int compositeState, int sqlExceptionNumber) + { + this.WriteEvent(SqlEventSourceListener.EndExecuteEventId, objectId, compositeState, sqlExceptionNumber); + } + } + + [EventSource(Name = SqlEventSourceListener.MdsEventSourceName + "-FakeFriendly")] + private class FakeBehavingMdsSqlEventSource : EventSource, IFakeBehavingSqlEventSource + { + [Event(SqlEventSourceListener.BeginExecuteEventId)] + public void WriteBeginExecuteEvent(int objectId, string dataSource, string databaseName, string commandText) + { + this.WriteEvent(SqlEventSourceListener.BeginExecuteEventId, objectId, dataSource, databaseName, commandText); + } + + [Event(SqlEventSourceListener.EndExecuteEventId)] + public void WriteEndExecuteEvent(int objectId, int compositeState, int sqlExceptionNumber) + { + this.WriteEvent(SqlEventSourceListener.EndExecuteEventId, objectId, compositeState, sqlExceptionNumber); + } + } + + [EventSource(Name = SqlEventSourceListener.AdoNetEventSourceName + "-FakeEvil")] + private class FakeMisbehavingAdoNetSqlEventSource : EventSource, IFakeMisbehavingSqlEventSource + { + [Event(SqlEventSourceListener.BeginExecuteEventId)] + public void WriteBeginExecuteEvent(string arg1) + { + this.WriteEvent(SqlEventSourceListener.BeginExecuteEventId, arg1); + } + + [Event(SqlEventSourceListener.EndExecuteEventId)] + public void WriteEndExecuteEvent(string arg1, string arg2, string arg3, string arg4) + { + this.WriteEvent(SqlEventSourceListener.EndExecuteEventId, arg1, arg2, arg3, arg4); + } + + [Event(3)] + public void WriteUnknownEventWithNullPayload() + { + object[] args = null; + + this.WriteEvent(3, args); + } + } + + [EventSource(Name = SqlEventSourceListener.MdsEventSourceName + "-FakeEvil")] + private class FakeMisbehavingMdsSqlEventSource : EventSource, IFakeMisbehavingSqlEventSource + { + [Event(SqlEventSourceListener.BeginExecuteEventId)] + public void WriteBeginExecuteEvent(string arg1) + { + this.WriteEvent(SqlEventSourceListener.BeginExecuteEventId, arg1); + } + + [Event(SqlEventSourceListener.EndExecuteEventId)] + public void WriteEndExecuteEvent(string arg1, string arg2, string arg3, string arg4) + { + this.WriteEvent(SqlEventSourceListener.EndExecuteEventId, arg1, arg2, arg3, arg4); + } + + [Event(3)] + public void WriteUnknownEventWithNullPayload() + { + object[] args = null; + + this.WriteEvent(3, args); + } + } +} +#endif From dc7be37862e4669638bb9df42db83794cbb667d7 Mon Sep 17 00:00:00 2001 From: Aleksandr Golenkevich Date: Wed, 24 Apr 2024 23:54:39 +0900 Subject: [PATCH 1037/1499] [Instrumentation.ElasticsearchClient] Fix sensitive data in url.full (former db.url) tag (#1684) --- opentelemetry-dotnet-contrib.sln | 1 + .../CHANGELOG.md | 3 ++ ...searchRequestPipelineDiagnosticListener.cs | 5 ++- ...Instrumentation.ElasticsearchClient.csproj | 1 + src/Shared/SemanticConventions.cs | 1 - src/Shared/UriHelper.cs | 27 ++++++++++++++ .../ElasticsearchClientTests.cs | 37 +++++++++++++++++++ 7 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 src/Shared/UriHelper.cs diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6d755deb10..c6ba36f8b1 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -288,6 +288,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs + src\Shared\UriHelper.cs = src\Shared\UriHelper.cs EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS", "src\OpenTelemetry.ResourceDetectors.AWS\OpenTelemetry.ResourceDetectors.AWS.csproj", "{71BABAC0-E299-48BF-93E2-C11C3840B037}" diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index f38801644e..7fb2da394c 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -8,6 +8,9 @@ ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Replace `db.url` attribute with `url.full` to comply with [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/database/elasticsearch.md#attributes). + Redact `username` and `password` part of the `url.full`. + ([#1684](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1684)) ## 1.0.0-beta.5 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index e706dcf14a..af907e627d 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -171,6 +171,9 @@ private void OnStartActivity(Activity activity, object payload) return; } + // remove sensitive information like user and password information + uri = UriHelper.ScrubUserInfo(uri); + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); @@ -210,7 +213,7 @@ private void OnStartActivity(Activity activity, object payload) activity.SetTag(AttributeDbMethod, method.ToString()); } - activity.SetTag(SemanticConventions.AttributeDbUrl, uri.OriginalString); + activity.SetTag(SemanticConventions.AttributeUrlFull, uri.OriginalString); try { diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 1d378439e9..fd3972389a 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -28,5 +28,6 @@ + diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 6c70b8c54c..2fa0c8144c 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -53,7 +53,6 @@ internal static class SemanticConventions public const string AttributeDbStatement = "db.statement"; public const string AttributeDbOperation = "db.operation"; public const string AttributeDbInstance = "db.instance"; - public const string AttributeDbUrl = "db.url"; public const string AttributeDbCassandraKeyspace = "db.cassandra.keyspace"; public const string AttributeDbHBaseNamespace = "db.hbase.namespace"; public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; diff --git a/src/Shared/UriHelper.cs b/src/Shared/UriHelper.cs new file mode 100644 index 0000000000..bccd1a96e0 --- /dev/null +++ b/src/Shared/UriHelper.cs @@ -0,0 +1,27 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; + +namespace OpenTelemetry.Trace; + +internal static class UriHelper +{ + private const string RedactedText = "REDACTED"; + + public static Uri ScrubUserInfo(Uri uri) + { + var uriBuilder = new UriBuilder(uri); + if (!string.IsNullOrEmpty(uriBuilder.UserName)) + { + uriBuilder.UserName = RedactedText; + } + + if (!string.IsNullOrEmpty(uriBuilder.Password)) + { + uriBuilder.Password = RedactedText; + } + + return uriBuilder.Uri; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 8507a98adf..f9db99cbcb 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -814,4 +815,40 @@ public async Task DbStatementIsDisplayedWhenSetDbStatementForRequestIsUsingTheDe var tags = searchActivity.Tags.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); Assert.NotNull(searchActivity.GetTagValue(SemanticConventions.AttributeDbStatement)); } + + [Fact] + public async Task ShouldRemoveSensitiveInformation() + { + var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); + var exportedItems = new List(); + + var sensitiveConnectionString = new Uri($"http://sensitiveUsername:sensitivePassword@localhost:9200"); + + var client = new ElasticClient(new ConnectionSettings( + new SingleNodeConnectionPool(sensitiveConnectionString), new InMemoryConnection()).DefaultIndex("customer")); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddElasticsearchClientInstrumentation(o => o.SetDbStatementForRequest = false) + .SetResourceBuilder(expectedResource) + .AddInMemoryExporter(exportedItems) + .Build()) + { + var searchResponse = await client.SearchAsync(s => s.Query(q => q.Bool(b => b.Must(m => m.Term(f => f.Id, "123"))))); + Assert.NotNull(searchResponse); + Assert.True(searchResponse.ApiCall.Success); + Assert.NotEmpty(searchResponse.ApiCall.AuditTrail); + + var failed = searchResponse.ApiCall.AuditTrail.Where(a => a.Event == AuditEvent.BadResponse); + Assert.Empty(failed); + } + + Assert.Single(exportedItems); + var searchActivity = exportedItems[0]; + + string dbUrl = (string)searchActivity.GetTagValue(SemanticConventions.AttributeUrlFull); + + Assert.DoesNotContain("sensitive", dbUrl); + Assert.Contains("REDACTED:REDACTED", dbUrl); + } } From 4e682255a04325d8a3de6e3fb23229f735d95fd0 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 24 Apr 2024 18:28:20 +0000 Subject: [PATCH 1038/1499] [repo] Move OpenTelemetry.SemanticConventions project from main repo (#1672) Co-authored-by: Mikel Blanchard --- .../comp_semanticconventions.md | 41 + .github/codecov.yml | 7 +- .github/workflows/Component.BuildTest.yml | 4 +- .github/workflows/ci.yml | 14 + .../workflows/package-SemanticConventions.yml | 21 + .../OpenTelemetry.SemanticConventions.proj | 29 + opentelemetry-dotnet-contrib.sln | 11 +- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 946 ++++++++++++++++++ .../Attributes/AndroidAttributes.cs | 50 + .../Attributes/AspnetcoreAttributes.cs | 119 +++ .../Attributes/AwsAttributes.cs | 306 ++++++ .../Attributes/BrowserAttributes.cs | 49 + .../Attributes/ClientAttributes.cs | 32 + .../Attributes/CloudAttributes.cs | 259 +++++ .../Attributes/CloudeventsAttributes.cs | 41 + .../Attributes/CodeAttributes.cs | 46 + .../Attributes/ContainerAttributes.cs | 114 +++ .../Attributes/DbAttributes.cs | 611 +++++++++++ .../Attributes/DeploymentAttributes.cs | 30 + .../Attributes/DestinationAttributes.cs | 29 + .../Attributes/DeviceAttributes.cs | 48 + .../Attributes/DiskAttributes.cs | 37 + .../Attributes/DnsAttributes.cs | 24 + .../Attributes/EnduserAttributes.cs | 31 + .../Attributes/ErrorAttributes.cs | 43 + .../Attributes/EventAttributes.cs | 24 + .../Attributes/ExceptionAttributes.cs | 50 + .../Attributes/FaasAttributes.cs | 223 +++++ .../Attributes/FeatureFlagAttributes.cs | 39 + .../Attributes/FileAttributes.cs | 44 + .../Attributes/GcpAttributes.cs | 36 + .../Attributes/GraphqlAttributes.cs | 55 + .../Attributes/HerokuAttributes.cs | 31 + .../Attributes/HostAttributes.cs | 146 +++ .../Attributes/HttpAttributes.cs | 265 +++++ .../Attributes/IosAttributes.cs | 55 + .../Attributes/JvmAttributes.cs | 115 +++ .../Attributes/K8sAttributes.cs | 155 +++ .../Attributes/LogAttributes.cs | 66 ++ .../Attributes/MessageAttributes.cs | 55 + .../Attributes/MessagingAttributes.cs | 390 ++++++++ .../Attributes/NetAttributes.cs | 146 +++ .../Attributes/NetworkAttributes.cs | 305 ++++++ .../Attributes/OciAttributes.cs | 25 + .../Attributes/OpentracingAttributes.cs | 40 + .../Attributes/OsAttributes.cs | 102 ++ .../Attributes/OtelAttributes.cs | 64 ++ .../Attributes/OtherAttributes.cs | 37 + .../Attributes/PeerAttributes.cs | 21 + .../Attributes/PoolAttributes.cs | 21 + .../Attributes/ProcessAttributes.cs | 139 +++ .../Attributes/RpcAttributes.cs | 307 ++++++ .../Attributes/ServerAttributes.cs | 32 + .../Attributes/ServiceAttributes.cs | 62 ++ .../Attributes/SessionAttributes.cs | 26 + .../Attributes/SignalrAttributes.cs | 68 ++ .../Attributes/SourceAttributes.cs | 29 + .../Attributes/SystemAttributes.cs | 382 +++++++ .../Attributes/TelemetryAttributes.cs | 119 +++ .../Attributes/ThreadAttributes.cs | 26 + .../Attributes/TlsAttributes.cs | 180 ++++ .../Attributes/UrlAttributes.cs | 106 ++ .../Attributes/UserAgentAttributes.cs | 37 + .../Attributes/WebengineAttributes.cs | 31 + .../CHANGELOG.md | 9 + .../OpenTelemetry.SemanticConventions.csproj | 11 + .../README.md | 34 + .../scripts/.gitignore | 1 + .../scripts/generate.ps1 | 29 + .../scripts/generate.sh | 32 + .../SemanticConventionsAttributes.cs.j2 | 65 ++ 72 files changed, 7174 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_semanticconventions.md create mode 100644 .github/workflows/package-SemanticConventions.yml create mode 100644 build/Projects/OpenTelemetry.SemanticConventions.proj create mode 100644 src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/CHANGELOG.md create mode 100644 src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj create mode 100644 src/OpenTelemetry.SemanticConventions/README.md create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/.gitignore create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/generate.sh create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 diff --git a/.github/ISSUE_TEMPLATE/comp_semanticconventions.md b/.github/ISSUE_TEMPLATE/comp_semanticconventions.md new file mode 100644 index 0000000000..fbcd20f363 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_semanticconventions.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.SemanticConventions +about: Issue with OpenTelemetry.SemanticConventions +labels: comp:semanticconvention +--- + +# Issue with OpenTelemetry.SemanticConventions + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index c38a11945c..927d2de317 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -88,7 +88,7 @@ flags: paths: - src/OpenTelemetry.Instrumentation.StackExchangeRedis - unittests-Instrumentation.Wcf: + unittests-Instrumentation.Wcf: carryforward: true paths: - src/OpenTelemetry.Instrumentation.Wcf @@ -118,3 +118,8 @@ flags: carryforward: true paths: - src/OpenTelemetry.ResourceDetectors.ProcessRuntime + + unittests-SemanticConventions: + carryforward: true + paths: + - src/OpenTelemetry.SemanticConventions diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index a73765ca62..02a2a6fb55 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -54,9 +54,11 @@ 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 + if: ${{ hashFiles('./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 }} + if: ${{ hashFiles('./TestResults/Cobertura.xml') != '' }} uses: codecov/codecov-action@v4 continue-on-error: true # Note: Don't fail for upload failures env: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 417259c488..5ba1a08d59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,6 +39,7 @@ jobs: redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] resourcedetectors: ['*/OpenTelemetry.ResourceDetectors.*/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] + semanticconventions: ['*/OpenTelemetry.SemanticConventions*/**', '!**/*.md'] sqlclient: ['*/OpenTelemetry.Instrumentation.SqlClient*/**', '!**/*.md'] wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] solution: [ @@ -70,6 +71,7 @@ jobs: '!examples/redis/**', '!*/OpenTelemetry.Instrumentation.Runtime*/**', '!examples/runtime-instrumentation/**', + '!*/OpenTelemetry.SemanticConventions*/**', '!*/OpenTelemetry.Instrumentation.Wcf*/**', '!examples/wcf/**', '!**/*.md' @@ -256,6 +258,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Runtime code-cov-name: Instrumentation.Runtime + build-test-semanticconventions: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'semanticconventions') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.SemanticConventions + code-cov-name: SemanticConventions + build-test-sqlclient: needs: detect-changes if: | @@ -404,6 +417,7 @@ jobs: build-test-redis, build-test-redis-integration, build-test-runtime, + build-test-semanticconventions, build-test-sqlclient, build-test-wcf, build-test-solution, diff --git a/.github/workflows/package-SemanticConventions.yml b/.github/workflows/package-SemanticConventions.yml new file mode 100644 index 0000000000..0e2427a80a --- /dev/null +++ b/.github/workflows/package-SemanticConventions.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.SemanticConventions + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'SemanticConventions-*' # trigger when we create a tag with prefix "SemanticConventions-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.SemanticConventions + secrets: inherit diff --git a/build/Projects/OpenTelemetry.SemanticConventions.proj b/build/Projects/OpenTelemetry.SemanticConventions.proj new file mode 100644 index 0000000000..91d459a156 --- /dev/null +++ b/build/Projects/OpenTelemetry.SemanticConventions.proj @@ -0,0 +1,29 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index c6ba36f8b1..0bf1ae3bae 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 15.0.26124.0 @@ -69,6 +69,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-ResourceDetectors.Process.yml = .github\workflows\package-ResourceDetectors.Process.yml .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml + .github\workflows\package-SemanticConventions.yml = .github\workflows\package-SemanticConventions.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml .github\workflows\verifyaotcompat.yml = .github\workflows\verifyaotcompat.yml @@ -331,6 +332,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj + build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime", "src\OpenTelemetry.ResourceDetectors.ProcessRuntime\OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" @@ -351,6 +353,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentati EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.SqlClient.Tests", "test\OpenTelemetry.Instrumentation.SqlClient.Tests\OpenTelemetry.Instrumentation.SqlClient.Tests.csproj", "{9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.SemanticConventions", "src\OpenTelemetry.SemanticConventions\OpenTelemetry.SemanticConventions.csproj", "{BC1959E3-164E-42AE-AE1C-DE2E3046E27C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -705,6 +709,10 @@ Global {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}.Release|Any CPU.Build.0 = Release|Any CPU + {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -810,6 +818,7 @@ Global {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {737D1A9E-5A1A-4F4F-830B-E98ED100994C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {BC1959E3-164E-42AE-AE1C-DE2E3046E27C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..f88e9e126f --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,946 @@ +const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Background = "background" -> string +const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Created = "created" -> string +const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Foreground = "foreground" -> string +const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidOsApiLevel = "android.os.api_level" -> string +const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidState = "android.state" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Aborted = "aborted" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Handled = "handled" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Skipped = "skipped" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Unhandled = "unhandled" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.Acquired = "acquired" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.EndpointLimiter = "endpoint_limiter" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.GlobalLimiter = "global_limiter" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.RequestCanceled = "request_canceled" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues.Failure = "failure" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues.Success = "success" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreDiagnosticsExceptionResult = "aspnetcore.diagnostics.exception.result" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreDiagnosticsHandlerType = "aspnetcore.diagnostics.handler.type" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRateLimitingPolicy = "aspnetcore.rate_limiting.policy" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRateLimitingResult = "aspnetcore.rate_limiting.result" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRequestIsUnhandled = "aspnetcore.request.is_unhandled" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRoutingIsFallback = "aspnetcore.routing.is_fallback" -> string +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRoutingMatchStatus = "aspnetcore.routing.match_status" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbAttributeDefinitions = "aws.dynamodb.attribute_definitions" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbCount = "aws.dynamodb.count" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbGlobalSecondaryIndexes = "aws.dynamodb.global_secondary_indexes" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbGlobalSecondaryIndexUpdates = "aws.dynamodb.global_secondary_index_updates" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbIndexName = "aws.dynamodb.index_name" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbItemCollectionMetrics = "aws.dynamodb.item_collection_metrics" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbLimit = "aws.dynamodb.limit" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbLocalSecondaryIndexes = "aws.dynamodb.local_secondary_indexes" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProjection = "aws.dynamodb.projection" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProvisionedReadCapacity = "aws.dynamodb.provisioned_read_capacity" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProvisionedWriteCapacity = "aws.dynamodb.provisioned_write_capacity" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbScanForward = "aws.dynamodb.scan_forward" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbScannedCount = "aws.dynamodb.scanned_count" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbSegment = "aws.dynamodb.segment" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbSelect = "aws.dynamodb.select" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTableCount = "aws.dynamodb.table_count" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTableNames = "aws.dynamodb.table_names" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTotalSegments = "aws.dynamodb.total_segments" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsClusterArn = "aws.ecs.cluster.arn" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsContainerArn = "aws.ecs.container.arn" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsLaunchtype = "aws.ecs.launchtype" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskArn = "aws.ecs.task.arn" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskFamily = "aws.ecs.task.family" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskId = "aws.ecs.task.id" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskRevision = "aws.ecs.task.revision" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEksClusterArn = "aws.eks.cluster.arn" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLambdaInvokedArn = "aws.lambda.invoked_arn" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogGroupArns = "aws.log.group.arns" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogGroupNames = "aws.log.group.names" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogStreamArns = "aws.log.stream.arns" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogStreamNames = "aws.log.stream.names" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsRequestId = "aws.request_id" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Bucket = "aws.s3.bucket" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3CopySource = "aws.s3.copy_source" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Delete = "aws.s3.delete" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Key = "aws.s3.key" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3PartNumber = "aws.s3.part_number" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3UploadId = "aws.s3.upload_id" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Ec2 = "ec2" -> string +const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Fargate = "fargate" -> string +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserBrands = "browser.brands" -> string +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserLanguage = "browser.language" -> string +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserMobile = "browser.mobile" -> string +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserPlatform = "browser.platform" -> string +const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientAddress = "client.address" -> string +const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientPort = "client.port" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAccountId = "cloud.account.id" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAvailabilityZone = "cloud.availability_zone" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudPlatform = "cloud.platform" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudProvider = "cloud.provider" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudRegion = "cloud.region" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudResourceId = "cloud.resource_id" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudEcs = "alibaba_cloud_ecs" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudFc = "alibaba_cloud_fc" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudOpenshift = "alibaba_cloud_openshift" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsAppRunner = "aws_app_runner" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEc2 = "aws_ec2" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEcs = "aws_ecs" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEks = "aws_eks" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsElasticBeanstalk = "aws_elastic_beanstalk" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsLambda = "aws_lambda" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsOpenshift = "aws_openshift" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureAks = "azure_aks" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureAppService = "azure_app_service" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureContainerApps = "azure_container_apps" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureContainerInstances = "azure_container_instances" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureFunctions = "azure_functions" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureOpenshift = "azure_openshift" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureVm = "azure_vm" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpAppEngine = "gcp_app_engine" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpBareMetalSolution = "gcp_bare_metal_solution" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpCloudFunctions = "gcp_cloud_functions" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpCloudRun = "gcp_cloud_run" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpComputeEngine = "gcp_compute_engine" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpKubernetesEngine = "gcp_kubernetes_engine" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpOpenshift = "gcp_openshift" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.IbmCloudOpenshift = "ibm_cloud_openshift" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudCvm = "tencent_cloud_cvm" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudEks = "tencent_cloud_eks" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudScf = "tencent_cloud_scf" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.AlibabaCloud = "alibaba_cloud" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Aws = "aws" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Azure = "azure" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Gcp = "gcp" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Heroku = "heroku" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.IbmCloud = "ibm_cloud" -> string +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.TencentCloud = "tencent_cloud" -> string +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventId = "cloudevents.event_id" -> string +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSource = "cloudevents.event_source" -> string +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version" -> string +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSubject = "cloudevents.event_subject" -> string +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventType = "cloudevents.event_type" -> string +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeColumn = "code.column" -> string +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFilepath = "code.filepath" -> string +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFunction = "code.function" -> string +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeLineno = "code.lineno" -> string +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeNamespace = "code.namespace" -> string +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeStacktrace = "code.stacktrace" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommand = "container.command" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandArgs = "container.command_args" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandLine = "container.command_line" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCpuState = "container.cpu.state" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerId = "container.id" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageId = "container.image.id" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageName = "container.image.name" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageRepoDigests = "container.image.repo_digests" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageTags = "container.image.tags" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerLabel = "container.label" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerLabels = "container.labels" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerName = "container.name" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerRuntime = "container.runtime" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.Kernel = "kernel" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.System = "system" -> string +const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.User = "user" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraIdempotence = "db.cassandra.idempotence" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraPageSize = "db.cassandra.page_size" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraTable = "db.cassandra.table" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbConnectionString = "db.connection_string" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbClientId = "db.cosmosdb.client_id" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbContainer = "db.cosmosdb.container" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchNodeName = "db.elasticsearch.node.name" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchPathParts = "db.elasticsearch.path_parts" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbInstanceId = "db.instance.id" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbJdbcDriverClassname = "db.jdbc.driver_classname" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMongodbCollection = "db.mongodb.collection" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMssqlInstanceName = "db.mssql.instance_name" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbName = "db.name" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperation = "db.operation" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbRedisDatabaseIndex = "db.redis.database_index" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSqlTable = "db.sql.table" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbStatement = "db.statement" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSystem = "db.system" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbUser = "db.user" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.All = "all" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Any = "any" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.EachQuorum = "each_quorum" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalOne = "local_one" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalQuorum = "local_quorum" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalSerial = "local_serial" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.One = "one" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Quorum = "quorum" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Serial = "serial" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Three = "three" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Two = "two" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Direct = "direct" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Gateway = "gateway" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "Batch" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Create = "Create" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Delete = "Delete" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Execute = "Execute" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ExecuteJavascript = "ExecuteJavaScript" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Head = "Head" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.HeadFeed = "HeadFeed" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Invalid = "Invalid" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Patch = "Patch" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Query = "Query" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.QueryPlan = "QueryPlan" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Read = "Read" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ReadFeed = "ReadFeed" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Replace = "Replace" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Upsert = "Upsert" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Adabas = "adabas" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cache = "cache" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cassandra = "cassandra" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Clickhouse = "clickhouse" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cloudscape = "cloudscape" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cockroachdb = "cockroachdb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Coldfusion = "coldfusion" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cosmosdb = "cosmosdb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Couchbase = "couchbase" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Couchdb = "couchdb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Db2 = "db2" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Derby = "derby" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Dynamodb = "dynamodb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Edb = "edb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Elasticsearch = "elasticsearch" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Filemaker = "filemaker" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Firebird = "firebird" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Firstsql = "firstsql" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Geode = "geode" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.H2 = "h2" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hanadb = "hanadb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hbase = "hbase" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hive = "hive" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hsqldb = "hsqldb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Informix = "informix" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Ingres = "ingres" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Instantdb = "instantdb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Interbase = "interbase" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mariadb = "mariadb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Maxdb = "maxdb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Memcached = "memcached" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mongodb = "mongodb" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mssql = "mssql" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mssqlcompact = "mssqlcompact" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mysql = "mysql" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Neo4j = "neo4j" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Netezza = "netezza" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Opensearch = "opensearch" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Oracle = "oracle" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.OtherSql = "other_sql" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Pervasive = "pervasive" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Pointbase = "pointbase" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Postgresql = "postgresql" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Progress = "progress" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Redis = "redis" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Redshift = "redshift" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Spanner = "spanner" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Sqlite = "sqlite" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Sybase = "sybase" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Teradata = "teradata" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Trino = "trino" -> string +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Vertica = "vertica" -> string +const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentEnvironment = "deployment.environment" -> string +const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationAddress = "destination.address" -> string +const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationPort = "destination.port" -> string +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceId = "device.id" -> string +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceManufacturer = "device.manufacturer" -> string +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceModelIdentifier = "device.model.identifier" -> string +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceModelName = "device.model.name" -> string +const OpenTelemetry.SemanticConventions.DiskAttributes.AttributeDiskIoDirection = "disk.io.direction" -> string +const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Read = "read" -> string +const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Write = "write" -> string +const OpenTelemetry.SemanticConventions.DnsAttributes.AttributeDnsQuestionName = "dns.question.name" -> string +const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserId = "enduser.id" -> string +const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserRole = "enduser.role" -> string +const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserScope = "enduser.scope" -> string +const OpenTelemetry.SemanticConventions.ErrorAttributes.AttributeErrorType = "error.type" -> string +const OpenTelemetry.SemanticConventions.ErrorAttributes.ErrorTypeValues.Other = "_OTHER" -> string +const OpenTelemetry.SemanticConventions.EventAttributes.AttributeEventName = "event.name" -> string +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionEscaped = "exception.escaped" -> string +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionMessage = "exception.message" -> string +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionStacktrace = "exception.stacktrace" -> string +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionType = "exception.type" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasColdstart = "faas.coldstart" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasCron = "faas.cron" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentCollection = "faas.document.collection" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentName = "faas.document.name" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentOperation = "faas.document.operation" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentTime = "faas.document.time" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInstance = "faas.instance" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvocationId = "faas.invocation_id" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedName = "faas.invoked_name" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedProvider = "faas.invoked_provider" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedRegion = "faas.invoked_region" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasMaxMemory = "faas.max_memory" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasName = "faas.name" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasTime = "faas.time" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasTrigger = "faas.trigger" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasVersion = "faas.version" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Delete = "delete" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Edit = "edit" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Insert = "insert" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.AlibabaCloud = "alibaba_cloud" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Aws = "aws" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Azure = "azure" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Gcp = "gcp" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.TencentCloud = "tencent_cloud" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Datasource = "datasource" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Http = "http" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Other = "other" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Pubsub = "pubsub" -> string +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Timer = "timer" -> string +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagKey = "feature_flag.key" -> string +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagProviderName = "feature_flag.provider_name" -> string +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagVariant = "feature_flag.variant" -> string +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileDirectory = "file.directory" -> string +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileExtension = "file.extension" -> string +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileName = "file.name" -> string +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFilePath = "file.path" -> string +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileSize = "file.size" -> string +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution" -> string +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index" -> string +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname" -> string +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceName = "gcp.gce.instance.name" -> string +const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlDocument = "graphql.document" -> string +const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationName = "graphql.operation.name" -> string +const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationType = "graphql.operation.type" -> string +const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Mutation = "mutation" -> string +const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Query = "query" -> string +const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Subscription = "subscription" -> string +const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuAppId = "heroku.app.id" -> string +const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuReleaseCommit = "heroku.release.commit" -> string +const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostArch = "host.arch" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuCacheL2Size = "host.cpu.cache.l2.size" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuFamily = "host.cpu.family" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuModelId = "host.cpu.model.id" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuModelName = "host.cpu.model.name" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuStepping = "host.cpu.stepping" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuVendorId = "host.cpu.vendor.id" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostId = "host.id" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageId = "host.image.id" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageName = "host.image.name" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageVersion = "host.image.version" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostIp = "host.ip" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostMac = "host.mac" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostName = "host.name" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostType = "host.type" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Amd64 = "amd64" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Arm32 = "arm32" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Arm64 = "arm64" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ia64 = "ia64" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ppc32 = "ppc32" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ppc64 = "ppc64" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.S390x = "s390x" -> string +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.X86 = "x86" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpConnectionState = "http.connection.state" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpFlavor = "http.flavor" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpMethod = "http.method" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestBodySize = "http.request.body.size" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestContentLength = "http.request_content_length" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestHeader = "http.request.header" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestMethod = "http.request.method" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestMethodOriginal = "http.request.method_original" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestResendCount = "http.request.resend_count" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestSize = "http.request.size" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseBodySize = "http.response.body.size" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseContentLength = "http.response_content_length" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseHeader = "http.response.header" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseSize = "http.response.size" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseStatusCode = "http.response.status_code" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRoute = "http.route" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpScheme = "http.scheme" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpStatusCode = "http.status_code" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpTarget = "http.target" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpUrl = "http.url" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpUserAgent = "http.user_agent" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues.Active = "active" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues.Idle = "idle" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http10 = "1.0" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http11 = "1.1" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http20 = "2.0" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http30 = "3.0" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Quic = "QUIC" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Spdy = "SPDY" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Connect = "CONNECT" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Delete = "DELETE" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Get = "GET" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Head = "HEAD" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Options = "OPTIONS" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Other = "_OTHER" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Patch = "PATCH" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Post = "POST" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Put = "PUT" -> string +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Trace = "TRACE" -> string +const OpenTelemetry.SemanticConventions.IosAttributes.AttributeIosState = "ios.state" -> string +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Active = "active" -> string +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Background = "background" -> string +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Foreground = "foreground" -> string +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Inactive = "inactive" -> string +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Terminate = "terminate" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmBufferPoolName = "jvm.buffer.pool.name" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmGcAction = "jvm.gc.action" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmGcName = "jvm.gc.name" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmMemoryPoolName = "jvm.memory.pool.name" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmMemoryType = "jvm.memory.type" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmThreadDaemon = "jvm.thread.daemon" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmThreadState = "jvm.thread.state" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues.Heap = "heap" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues.NonHeap = "non_heap" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Blocked = "blocked" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.New = "new" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Runnable = "runnable" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Terminated = "terminated" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.TimedWaiting = "timed_waiting" -> string +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Waiting = "waiting" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sClusterName = "k8s.cluster.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sClusterUid = "k8s.cluster.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerName = "k8s.container.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerRestartCount = "k8s.container.restart_count" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sCronjobName = "k8s.cronjob.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sCronjobUid = "k8s.cronjob.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDaemonsetName = "k8s.daemonset.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDaemonsetUid = "k8s.daemonset.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDeploymentName = "k8s.deployment.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDeploymentUid = "k8s.deployment.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sJobName = "k8s.job.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sJobUid = "k8s.job.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNamespaceName = "k8s.namespace.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNodeName = "k8s.node.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNodeUid = "k8s.node.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodAnnotation = "k8s.pod.annotation" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodLabel = "k8s.pod.label" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodLabels = "k8s.pod.labels" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodName = "k8s.pod.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodUid = "k8s.pod.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetName = "k8s.replicaset.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetUid = "k8s.replicaset.uid" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetName = "k8s.statefulset.name" -> string +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetUid = "k8s.statefulset.uid" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileName = "log.file.name" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileNameResolved = "log.file.name_resolved" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePath = "log.file.path" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePathResolved = "log.file.path_resolved" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogIostream = "log.iostream" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogRecordUid = "log.record.uid" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stderr = "stderr" -> string +const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stdout = "stdout" -> string +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageCompressedSize = "message.compressed_size" -> string +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageId = "message.id" -> string +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageType = "message.type" -> string +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageUncompressedSize = "message.uncompressed_size" -> string +const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Received = "RECEIVED" -> string +const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Sent = "SENT" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingBatchMessageCount = "messaging.batch.message_count" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingClientId = "messaging.client_id" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationName = "messaging.destination.name" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishName = "messaging.destination_publish.name" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemplate = "messaging.destination.template" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemporary = "messaging.destination.temporary" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsMessageEnqueuedTime = "messaging.eventhubs.message.enqueued_time" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageBodySize = "messaging.message.body.size" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageConversationId = "messaging.message.conversation_id" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageId = "messaging.message.id" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingOperation = "messaging.operation" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRabbitmqDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqConsumptionModel = "messaging.rocketmq.consumption_model" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageDelayTimeLevel = "messaging.rocketmq.message.delay_time_level" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageDeliveryTimestamp = "messaging.rocketmq.message.delivery_timestamp" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageType = "messaging.rocketmq.message.type" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusDispositionStatus = "messaging.servicebus.disposition_status" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageDeliveryCount = "messaging.servicebus.message.delivery_count" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingSystem = "messaging.system" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Create = "create" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Deliver = "process" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Publish = "publish" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Receive = "receive" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Settle = "settle" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Broadcasting = "broadcasting" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Clustering = "clustering" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Delay = "delay" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Fifo = "fifo" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Normal = "normal" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Transaction = "transaction" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Abandon = "abandon" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Complete = "complete" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.DeadLetter = "dead_letter" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Defer = "defer" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Activemq = "activemq" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.AwsSqs = "aws_sqs" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Eventgrid = "eventgrid" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Eventhubs = "eventhubs" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.GcpPubsub = "gcp_pubsub" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Jms = "jms" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Kafka = "kafka" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rabbitmq = "rabbitmq" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rocketmq = "rocketmq" -> string +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Servicebus = "servicebus" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostName = "net.host.name" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostPort = "net.host.port" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerName = "net.peer.name" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerPort = "net.peer.port" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetProtocolName = "net.protocol.name" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetProtocolVersion = "net.protocol.version" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockFamily = "net.sock.family" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockHostAddr = "net.sock.host.addr" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockHostPort = "net.sock.host.port" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerAddr = "net.sock.peer.addr" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerName = "net.sock.peer.name" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerPort = "net.sock.peer.port" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetTransport = "net.transport" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Inet = "inet" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Inet6 = "inet6" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Unix = "unix" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Inproc = "inproc" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.IpTcp = "ip_tcp" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.IpUdp = "ip_udp" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Other = "other" -> string +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Pipe = "pipe" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierIcc = "network.carrier.icc" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierMcc = "network.carrier.mcc" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierMnc = "network.carrier.mnc" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierName = "network.carrier.name" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionSubtype = "network.connection.subtype" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionType = "network.connection.type" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkIoDirection = "network.io.direction" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalAddress = "network.local.address" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalPort = "network.local.port" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkPeerAddress = "network.peer.address" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkPeerPort = "network.peer.port" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkProtocolName = "network.protocol.name" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkProtocolVersion = "network.protocol.version" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkTransport = "network.transport" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkType = "network.type" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Cdma = "cdma" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Cdma20001xrtt = "cdma2000_1xrtt" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Edge = "edge" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Ehrpd = "ehrpd" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Evdo0 = "evdo_0" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.EvdoA = "evdo_a" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.EvdoB = "evdo_b" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Gprs = "gprs" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Gsm = "gsm" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hsdpa = "hsdpa" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hspa = "hspa" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hspap = "hspap" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hsupa = "hsupa" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Iden = "iden" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Iwlan = "iwlan" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Lte = "lte" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.LteCa = "lte_ca" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Nr = "nr" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Nrnsa = "nrnsa" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.TdScdma = "td_scdma" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Umts = "umts" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Cell = "cell" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Unavailable = "unavailable" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Unknown = "unknown" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Wifi = "wifi" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Wired = "wired" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Receive = "receive" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Transmit = "transmit" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Pipe = "pipe" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Tcp = "tcp" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Udp = "udp" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Unix = "unix" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv4 = "ipv4" -> string +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv6 = "ipv6" -> string +const OpenTelemetry.SemanticConventions.OciAttributes.AttributeOciManifestDigest = "oci.manifest.digest" -> string +const OpenTelemetry.SemanticConventions.OpentracingAttributes.AttributeOpentracingRefType = "opentracing.ref_type" -> string +const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.ChildOf = "child_of" -> string +const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.FollowsFrom = "follows_from" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsBuildId = "os.build_id" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsDescription = "os.description" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsName = "os.name" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsType = "os.type" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsVersion = "os.version" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Aix = "aix" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Darwin = "darwin" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Dragonflybsd = "dragonflybsd" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Freebsd = "freebsd" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Hpux = "hpux" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Linux = "linux" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Netbsd = "netbsd" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Openbsd = "openbsd" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Solaris = "solaris" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Windows = "windows" -> string +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.ZOs = "z_os" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelLibraryName = "otel.library.name" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelLibraryVersion = "otel.library.version" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelScopeName = "otel.scope.name" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelScopeVersion = "otel.scope.version" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelStatusCode = "otel.status_code" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelStatusDescription = "otel.status_description" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues.Error = "ERROR" -> string +const OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues.Ok = "OK" -> string +const OpenTelemetry.SemanticConventions.OtherAttributes.AttributeState = "state" -> string +const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Idle = "idle" -> string +const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Used = "used" -> string +const OpenTelemetry.SemanticConventions.PeerAttributes.AttributePeerService = "peer.service" -> string +const OpenTelemetry.SemanticConventions.PoolAttributes.AttributePoolName = "pool.name" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommand = "process.command" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandArgs = "process.command_args" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandLine = "process.command_line" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessContextSwitchType = "process.context_switch_type" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCpuState = "process.cpu.state" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableName = "process.executable.name" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutablePath = "process.executable.path" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessOwner = "process.owner" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPagingFaultType = "process.paging.fault_type" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessParentPid = "process.parent_pid" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPid = "process.pid" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeDescription = "process.runtime.description" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeName = "process.runtime.name" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeVersion = "process.runtime.version" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Involuntary = "involuntary" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Voluntary = "voluntary" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.System = "system" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.User = "user" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.Wait = "wait" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Major = "major" -> string +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Minor = "minor" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcRequestMetadata = "rpc.connect_rpc.request.metadata" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcResponseMetadata = "rpc.connect_rpc.response.metadata" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcRequestMetadata = "rpc.grpc.request.metadata" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcResponseMetadata = "rpc.grpc.response.metadata" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcStatusCode = "rpc.grpc.status_code" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcRequestId = "rpc.jsonrpc.request_id" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcVersion = "rpc.jsonrpc.version" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMethod = "rpc.method" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcService = "rpc.service" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcSystem = "rpc.system" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Aborted = "aborted" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.AlreadyExists = "already_exists" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Cancelled = "cancelled" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.DataLoss = "data_loss" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.DeadlineExceeded = "deadline_exceeded" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.FailedPrecondition = "failed_precondition" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Internal = "internal" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.InvalidArgument = "invalid_argument" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.NotFound = "not_found" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.OutOfRange = "out_of_range" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.PermissionDenied = "permission_denied" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.ResourceExhausted = "resource_exhausted" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unauthenticated = "unauthenticated" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unavailable = "unavailable" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unimplemented = "unimplemented" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unknown = "unknown" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Aborted = 10 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.AlreadyExists = 6 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Cancelled = 1 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.DataLoss = 15 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.DeadlineExceeded = 4 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.FailedPrecondition = 9 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Internal = 13 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.InvalidArgument = 3 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.NotFound = 5 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Ok = 0 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.OutOfRange = 11 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.PermissionDenied = 7 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.ResourceExhausted = 8 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unauthenticated = 16 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unavailable = 14 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unimplemented = 12 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unknown = 2 -> int +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.ApacheDubbo = "apache_dubbo" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.ConnectRpc = "connect_rpc" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.DotnetWcf = "dotnet_wcf" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.Grpc = "grpc" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.JavaRmi = "java_rmi" -> string +const OpenTelemetry.SemanticConventions.ServerAttributes.AttributeServerAddress = "server.address" -> string +const OpenTelemetry.SemanticConventions.ServerAttributes.AttributeServerPort = "server.port" -> string +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceInstanceId = "service.instance.id" -> string +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceName = "service.name" -> string +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceNamespace = "service.namespace" -> string +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceVersion = "service.version" -> string +const OpenTelemetry.SemanticConventions.SessionAttributes.AttributeSessionId = "session.id" -> string +const OpenTelemetry.SemanticConventions.SessionAttributes.AttributeSessionPreviousId = "session.previous_id" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.AttributeSignalrConnectionStatus = "signalr.connection.status" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.AttributeSignalrTransport = "signalr.transport" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.AppShutdown = "app_shutdown" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.NormalClosure = "normal_closure" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.Timeout = "timeout" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.LongPolling = "long_polling" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.ServerSentEvents = "server_sent_events" -> string +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.WebSockets = "web_sockets" -> string +const OpenTelemetry.SemanticConventions.SourceAttributes.AttributeSourceAddress = "source.address" -> string +const OpenTelemetry.SemanticConventions.SourceAttributes.AttributeSourcePort = "source.port" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemCpuLogicalNumber = "system.cpu.logical_number" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemCpuState = "system.cpu.state" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemDevice = "system.device" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemMode = "system.filesystem.mode" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemMountpoint = "system.filesystem.mountpoint" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemState = "system.filesystem.state" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemType = "system.filesystem.type" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemMemoryState = "system.memory.state" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemNetworkState = "system.network.state" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingDirection = "system.paging.direction" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingState = "system.paging.state" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingType = "system.paging.type" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemProcessesStatus = "system.processes.status" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemProcessStatus = "system.process.status" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Idle = "idle" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Interrupt = "interrupt" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Iowait = "iowait" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Nice = "nice" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Steal = "steal" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.System = "system" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.User = "user" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Free = "free" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Reserved = "reserved" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Used = "used" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Exfat = "exfat" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Ext4 = "ext4" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Fat32 = "fat32" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Hfsplus = "hfsplus" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Ntfs = "ntfs" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Refs = "refs" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Buffers = "buffers" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Cached = "cached" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Free = "free" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Shared = "shared" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Used = "used" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Close = "close" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.CloseWait = "close_wait" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Closing = "closing" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Delete = "delete" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Established = "established" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.FinWait1 = "fin_wait_1" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.FinWait2 = "fin_wait_2" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.LastAck = "last_ack" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Listen = "listen" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.SynRecv = "syn_recv" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.SynSent = "syn_sent" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.TimeWait = "time_wait" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues.In = "in" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues.Out = "out" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues.Free = "free" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues.Used = "used" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues.Major = "major" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues.Minor = "minor" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Defunct = "defunct" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Running = "running" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Sleeping = "sleeping" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Stopped = "stopped" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Defunct = "defunct" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Running = "running" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Sleeping = "sleeping" -> string +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Stopped = "stopped" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetryDistroName = "telemetry.distro.name" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetryDistroVersion = "telemetry.distro.version" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkLanguage = "telemetry.sdk.language" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkName = "telemetry.sdk.name" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkVersion = "telemetry.sdk.version" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Cpp = "cpp" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Dotnet = "dotnet" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Erlang = "erlang" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Go = "go" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Java = "java" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Nodejs = "nodejs" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Php = "php" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Python = "python" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Ruby = "ruby" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Rust = "rust" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Swift = "swift" -> string +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Webjs = "webjs" -> string +const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadId = "thread.id" -> string +const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadName = "thread.name" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCipher = "tls.cipher" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientCertificate = "tls.client.certificate" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientCertificateChain = "tls.client.certificate_chain" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashMd5 = "tls.client.hash.md5" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashSha1 = "tls.client.hash.sha1" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashSha256 = "tls.client.hash.sha256" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientIssuer = "tls.client.issuer" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientJa3 = "tls.client.ja3" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientNotAfter = "tls.client.not_after" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientNotBefore = "tls.client.not_before" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientServerName = "tls.client.server_name" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientSubject = "tls.client.subject" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientSupportedCiphers = "tls.client.supported_ciphers" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCurve = "tls.curve" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsEstablished = "tls.established" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsNextProtocol = "tls.next_protocol" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsProtocolName = "tls.protocol.name" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsProtocolVersion = "tls.protocol.version" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsResumed = "tls.resumed" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerCertificate = "tls.server.certificate" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerCertificateChain = "tls.server.certificate_chain" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashMd5 = "tls.server.hash.md5" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashSha1 = "tls.server.hash.sha1" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashSha256 = "tls.server.hash.sha256" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerIssuer = "tls.server.issuer" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerJa3s = "tls.server.ja3s" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerNotAfter = "tls.server.not_after" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerNotBefore = "tls.server.not_before" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerSubject = "tls.server.subject" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues.Ssl = "ssl" -> string +const OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues.Tls = "tls" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlDomain = "url.domain" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlExtension = "url.extension" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlFragment = "url.fragment" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlFull = "url.full" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlOriginal = "url.original" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlPath = "url.path" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlPort = "url.port" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlQuery = "url.query" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlRegisteredDomain = "url.registered_domain" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlScheme = "url.scheme" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlSubdomain = "url.subdomain" -> string +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTopLevelDomain = "url.top_level_domain" -> string +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentName = "user_agent.name" -> string +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentOriginal = "user_agent.original" -> string +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentVersion = "user_agent.version" -> string +const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineDescription = "webengine.description" -> string +const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineName = "webengine.name" -> string +const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineVersion = "webengine.version" -> string +OpenTelemetry.SemanticConventions.AndroidAttributes +OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues +OpenTelemetry.SemanticConventions.AspnetcoreAttributes +OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues +OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues +OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues +OpenTelemetry.SemanticConventions.AwsAttributes +OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues +OpenTelemetry.SemanticConventions.BrowserAttributes +OpenTelemetry.SemanticConventions.ClientAttributes +OpenTelemetry.SemanticConventions.CloudAttributes +OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues +OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues +OpenTelemetry.SemanticConventions.CloudeventsAttributes +OpenTelemetry.SemanticConventions.CodeAttributes +OpenTelemetry.SemanticConventions.ContainerAttributes +OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues +OpenTelemetry.SemanticConventions.DbAttributes +OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues +OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues +OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues +OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues +OpenTelemetry.SemanticConventions.DeploymentAttributes +OpenTelemetry.SemanticConventions.DestinationAttributes +OpenTelemetry.SemanticConventions.DeviceAttributes +OpenTelemetry.SemanticConventions.DiskAttributes +OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues +OpenTelemetry.SemanticConventions.DnsAttributes +OpenTelemetry.SemanticConventions.EnduserAttributes +OpenTelemetry.SemanticConventions.ErrorAttributes +OpenTelemetry.SemanticConventions.ErrorAttributes.ErrorTypeValues +OpenTelemetry.SemanticConventions.EventAttributes +OpenTelemetry.SemanticConventions.ExceptionAttributes +OpenTelemetry.SemanticConventions.FaasAttributes +OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues +OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues +OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues +OpenTelemetry.SemanticConventions.FeatureFlagAttributes +OpenTelemetry.SemanticConventions.FileAttributes +OpenTelemetry.SemanticConventions.GcpAttributes +OpenTelemetry.SemanticConventions.GraphqlAttributes +OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues +OpenTelemetry.SemanticConventions.HerokuAttributes +OpenTelemetry.SemanticConventions.HostAttributes +OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues +OpenTelemetry.SemanticConventions.HttpAttributes +OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues +OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues +OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues +OpenTelemetry.SemanticConventions.IosAttributes +OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues +OpenTelemetry.SemanticConventions.JvmAttributes +OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues +OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues +OpenTelemetry.SemanticConventions.K8sAttributes +OpenTelemetry.SemanticConventions.LogAttributes +OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues +OpenTelemetry.SemanticConventions.MessageAttributes +OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues +OpenTelemetry.SemanticConventions.MessagingAttributes +OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues +OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues +OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues +OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues +OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues +OpenTelemetry.SemanticConventions.NetAttributes +OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues +OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues +OpenTelemetry.SemanticConventions.NetworkAttributes +OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues +OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues +OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues +OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues +OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues +OpenTelemetry.SemanticConventions.OciAttributes +OpenTelemetry.SemanticConventions.OpentracingAttributes +OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues +OpenTelemetry.SemanticConventions.OsAttributes +OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues +OpenTelemetry.SemanticConventions.OtelAttributes +OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues +OpenTelemetry.SemanticConventions.OtherAttributes +OpenTelemetry.SemanticConventions.OtherAttributes.StateValues +OpenTelemetry.SemanticConventions.PeerAttributes +OpenTelemetry.SemanticConventions.PoolAttributes +OpenTelemetry.SemanticConventions.ProcessAttributes +OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues +OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues +OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues +OpenTelemetry.SemanticConventions.RpcAttributes +OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues +OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues +OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues +OpenTelemetry.SemanticConventions.ServerAttributes +OpenTelemetry.SemanticConventions.ServiceAttributes +OpenTelemetry.SemanticConventions.SessionAttributes +OpenTelemetry.SemanticConventions.SignalrAttributes +OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues +OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues +OpenTelemetry.SemanticConventions.SourceAttributes +OpenTelemetry.SemanticConventions.SystemAttributes +OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues +OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues +OpenTelemetry.SemanticConventions.TelemetryAttributes +OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues +OpenTelemetry.SemanticConventions.ThreadAttributes +OpenTelemetry.SemanticConventions.TlsAttributes +OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues +OpenTelemetry.SemanticConventions.UrlAttributes +OpenTelemetry.SemanticConventions.UserAgentAttributes +OpenTelemetry.SemanticConventions.WebengineAttributes \ No newline at end of file diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs new file mode 100644 index 0000000000..d03c767675 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class AndroidAttributes +{ + /// + /// Uniquely identifies the framework API revision offered by a version (os.version) of the android operating system. More information can be found here. + /// + public const string AttributeAndroidOsApiLevel = "android.os.api_level"; + + /// + /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// + /// + /// The Android lifecycle states are defined in Activity lifecycle callbacks, and from which the OS identifiers are derived. + /// + public const string AttributeAndroidState = "android.state"; + + /// + /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// + public static class AndroidStateValues + { + /// + /// Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. + /// + public const string Created = "created"; + + /// + /// Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. + /// + public const string Background = "background"; + + /// + /// Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. + /// + public const string Foreground = "foreground"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs new file mode 100644 index 0000000000..cb436aacbb --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs @@ -0,0 +1,119 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class AspnetcoreAttributes +{ + /// + /// ASP.NET Core exception middleware handling result. + /// + public const string AttributeAspnetcoreDiagnosticsExceptionResult = "aspnetcore.diagnostics.exception.result"; + + /// + /// Full type name of the IExceptionHandler implementation that handled the exception. + /// + public const string AttributeAspnetcoreDiagnosticsHandlerType = "aspnetcore.diagnostics.handler.type"; + + /// + /// Rate limiting policy name. + /// + public const string AttributeAspnetcoreRateLimitingPolicy = "aspnetcore.rate_limiting.policy"; + + /// + /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason. + /// + public const string AttributeAspnetcoreRateLimitingResult = "aspnetcore.rate_limiting.result"; + + /// + /// Flag indicating if request was handled by the application pipeline. + /// + public const string AttributeAspnetcoreRequestIsUnhandled = "aspnetcore.request.is_unhandled"; + + /// + /// A value that indicates whether the matched route is a fallback route. + /// + public const string AttributeAspnetcoreRoutingIsFallback = "aspnetcore.routing.is_fallback"; + + /// + /// Match result - success or failure. + /// + public const string AttributeAspnetcoreRoutingMatchStatus = "aspnetcore.routing.match_status"; + + /// + /// ASP.NET Core exception middleware handling result. + /// + public static class AspnetcoreDiagnosticsExceptionResultValues + { + /// + /// Exception was handled by the exception handling middleware. + /// + public const string Handled = "handled"; + + /// + /// Exception was not handled by the exception handling middleware. + /// + public const string Unhandled = "unhandled"; + + /// + /// Exception handling was skipped because the response had started. + /// + public const string Skipped = "skipped"; + + /// + /// Exception handling didn't run because the request was aborted. + /// + public const string Aborted = "aborted"; + } + + /// + /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason. + /// + public static class AspnetcoreRateLimitingResultValues + { + /// + /// Lease was acquired. + /// + public const string Acquired = "acquired"; + + /// + /// Lease request was rejected by the endpoint limiter. + /// + public const string EndpointLimiter = "endpoint_limiter"; + + /// + /// Lease request was rejected by the global limiter. + /// + public const string GlobalLimiter = "global_limiter"; + + /// + /// Lease request was canceled. + /// + public const string RequestCanceled = "request_canceled"; + } + + /// + /// Match result - success or failure. + /// + public static class AspnetcoreRoutingMatchStatusValues + { + /// + /// Match succeeded. + /// + public const string Success = "success"; + + /// + /// Match failed. + /// + public const string Failure = "failure"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs new file mode 100644 index 0000000000..fcaad1e8a7 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs @@ -0,0 +1,306 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class AwsAttributes +{ + /// + /// The JSON-serialized value of each item in the AttributeDefinitions request field. + /// + public const string AttributeAwsDynamodbAttributeDefinitions = "aws.dynamodb.attribute_definitions"; + + /// + /// The value of the AttributesToGet request parameter. + /// + public const string AttributeAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get"; + + /// + /// The value of the ConsistentRead request parameter. + /// + public const string AttributeAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read"; + + /// + /// The JSON-serialized value of each item in the ConsumedCapacity response field. + /// + public const string AttributeAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity"; + + /// + /// The value of the Count response parameter. + /// + public const string AttributeAwsDynamodbCount = "aws.dynamodb.count"; + + /// + /// The value of the ExclusiveStartTableName request parameter. + /// + public const string AttributeAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table"; + + /// + /// The JSON-serialized value of each item in the GlobalSecondaryIndexUpdates request field. + /// + public const string AttributeAwsDynamodbGlobalSecondaryIndexUpdates = "aws.dynamodb.global_secondary_index_updates"; + + /// + /// The JSON-serialized value of each item of the GlobalSecondaryIndexes request field. + /// + public const string AttributeAwsDynamodbGlobalSecondaryIndexes = "aws.dynamodb.global_secondary_indexes"; + + /// + /// The value of the IndexName request parameter. + /// + public const string AttributeAwsDynamodbIndexName = "aws.dynamodb.index_name"; + + /// + /// The JSON-serialized value of the ItemCollectionMetrics response field. + /// + public const string AttributeAwsDynamodbItemCollectionMetrics = "aws.dynamodb.item_collection_metrics"; + + /// + /// The value of the Limit request parameter. + /// + public const string AttributeAwsDynamodbLimit = "aws.dynamodb.limit"; + + /// + /// The JSON-serialized value of each item of the LocalSecondaryIndexes request field. + /// + public const string AttributeAwsDynamodbLocalSecondaryIndexes = "aws.dynamodb.local_secondary_indexes"; + + /// + /// The value of the ProjectionExpression request parameter. + /// + public const string AttributeAwsDynamodbProjection = "aws.dynamodb.projection"; + + /// + /// The value of the ProvisionedThroughput.ReadCapacityUnits request parameter. + /// + public const string AttributeAwsDynamodbProvisionedReadCapacity = "aws.dynamodb.provisioned_read_capacity"; + + /// + /// The value of the ProvisionedThroughput.WriteCapacityUnits request parameter. + /// + public const string AttributeAwsDynamodbProvisionedWriteCapacity = "aws.dynamodb.provisioned_write_capacity"; + + /// + /// The value of the ScanIndexForward request parameter. + /// + public const string AttributeAwsDynamodbScanForward = "aws.dynamodb.scan_forward"; + + /// + /// The value of the ScannedCount response parameter. + /// + public const string AttributeAwsDynamodbScannedCount = "aws.dynamodb.scanned_count"; + + /// + /// The value of the Segment request parameter. + /// + public const string AttributeAwsDynamodbSegment = "aws.dynamodb.segment"; + + /// + /// The value of the Select request parameter. + /// + public const string AttributeAwsDynamodbSelect = "aws.dynamodb.select"; + + /// + /// The number of items in the TableNames response parameter. + /// + public const string AttributeAwsDynamodbTableCount = "aws.dynamodb.table_count"; + + /// + /// The keys in the RequestItems object field. + /// + public const string AttributeAwsDynamodbTableNames = "aws.dynamodb.table_names"; + + /// + /// The value of the TotalSegments request parameter. + /// + public const string AttributeAwsDynamodbTotalSegments = "aws.dynamodb.total_segments"; + + /// + /// The ARN of an ECS cluster. + /// + public const string AttributeAwsEcsClusterArn = "aws.ecs.cluster.arn"; + + /// + /// The Amazon Resource Name (ARN) of an ECS container instance. + /// + public const string AttributeAwsEcsContainerArn = "aws.ecs.container.arn"; + + /// + /// The launch type for an ECS task. + /// + public const string AttributeAwsEcsLaunchtype = "aws.ecs.launchtype"; + + /// + /// The ARN of a running ECS task. + /// + public const string AttributeAwsEcsTaskArn = "aws.ecs.task.arn"; + + /// + /// The family name of the ECS task definition used to create the ECS task. + /// + public const string AttributeAwsEcsTaskFamily = "aws.ecs.task.family"; + + /// + /// The ID of a running ECS task. The ID MUST be extracted from task.arn. + /// + public const string AttributeAwsEcsTaskId = "aws.ecs.task.id"; + + /// + /// The revision for the task definition used to create the ECS task. + /// + public const string AttributeAwsEcsTaskRevision = "aws.ecs.task.revision"; + + /// + /// The ARN of an EKS cluster. + /// + public const string AttributeAwsEksClusterArn = "aws.eks.cluster.arn"; + + /// + /// The full invoked ARN as provided on the Context passed to the function (Lambda-Runtime-Invoked-Function-Arn header on the /runtime/invocation/next applicable). + /// + /// + /// This may be different from cloud.resource_id if an alias is involved. + /// + public const string AttributeAwsLambdaInvokedArn = "aws.lambda.invoked_arn"; + + /// + /// The Amazon Resource Name(s) (ARN) of the AWS log group(s). + /// + /// + /// See the log group ARN format documentation. + /// + public const string AttributeAwsLogGroupArns = "aws.log.group.arns"; + + /// + /// The name(s) of the AWS log group(s) an application is writing to. + /// + /// + /// Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. + /// + public const string AttributeAwsLogGroupNames = "aws.log.group.names"; + + /// + /// The ARN(s) of the AWS log stream(s). + /// + /// + /// See the log stream ARN format documentation. One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + /// + public const string AttributeAwsLogStreamArns = "aws.log.stream.arns"; + + /// + /// The name(s) of the AWS log stream(s) an application is writing to. + /// + public const string AttributeAwsLogStreamNames = "aws.log.stream.names"; + + /// + /// The AWS request ID as returned in the response headers x-amz-request-id or x-amz-requestid. + /// + public const string AttributeAwsRequestId = "aws.request_id"; + + /// + /// The S3 bucket name the request refers to. Corresponds to the --bucket parameter of the S3 API operations. + /// + /// + /// The bucket attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. + /// This applies to almost all S3 operations except list-buckets. + /// + public const string AttributeAwsS3Bucket = "aws.s3.bucket"; + + /// + /// The source object (in the form bucket/key) for the copy operation. + /// + /// + /// The copy_source attribute applies to S3 copy operations and corresponds to the --copy-source parameter + /// of the copy-object operation within the S3 API. + /// This applies in particular to the following operations:. + /// + public const string AttributeAwsS3CopySource = "aws.s3.copy_source"; + + /// + /// The delete request container that specifies the objects to be deleted. + /// + /// + /// The delete attribute is only applicable to the delete-object operation. + /// The delete attribute corresponds to the --delete parameter of the + /// delete-objects operation within the S3 API. + /// + public const string AttributeAwsS3Delete = "aws.s3.delete"; + + /// + /// The S3 object key the request refers to. Corresponds to the --key parameter of the S3 API operations. + /// + /// + /// The key attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. + /// This applies in particular to the following operations:. + /// + public const string AttributeAwsS3Key = "aws.s3.key"; + + /// + /// The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. + /// + /// + /// The part_number attribute is only applicable to the upload-part + /// and upload-part-copy operations. + /// The part_number attribute corresponds to the --part-number parameter of the + /// upload-part operation within the S3 API. + /// + public const string AttributeAwsS3PartNumber = "aws.s3.part_number"; + + /// + /// Upload ID that identifies the multipart upload. + /// + /// + /// The upload_id attribute applies to S3 multipart-upload operations and corresponds to the --upload-id parameter + /// of the S3 API multipart operations. + /// This applies in particular to the following operations:. + /// + public const string AttributeAwsS3UploadId = "aws.s3.upload_id"; + + /// + /// The launch type for an ECS task. + /// + public static class AwsEcsLaunchtypeValues + { + /// + /// ec2. + /// + public const string Ec2 = "ec2"; + + /// + /// fargate. + /// + public const string Fargate = "fargate"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs new file mode 100644 index 0000000000..b4d81c70b5 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class BrowserAttributes +{ + /// + /// Array of brand name and version separated by a space. + /// + /// + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.brands). + /// + public const string AttributeBrowserBrands = "browser.brands"; + + /// + /// Preferred language of the user using the browser. + /// + /// + /// This value is intended to be taken from the Navigator API navigator.language. + /// + public const string AttributeBrowserLanguage = "browser.language"; + + /// + /// A boolean that is true if the browser is running on a mobile device. + /// + /// + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.mobile). If unavailable, this attribute SHOULD be left unset. + /// + public const string AttributeBrowserMobile = "browser.mobile"; + + /// + /// The platform on which the browser is running. + /// + /// + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.platform). If unavailable, the legacy navigator.platform API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. + /// The list of possible values is defined in the W3C User-Agent Client Hints specification. Note that some (but not all) of these values can overlap with values in the os.type and os.name attributes. However, for consistency, the values in the browser.platform attribute should capture the exact value that the user agent provides. + /// + public const string AttributeBrowserPlatform = "browser.platform"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs new file mode 100644 index 0000000000..724e0bd156 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ClientAttributes +{ + /// + /// Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// + /// + /// When observed from the server side, and when communicating through an intermediary, client.address SHOULD represent the client address behind any intermediaries, for example proxies, if it&#39;s available. + /// + public const string AttributeClientAddress = "client.address"; + + /// + /// Client port number. + /// + /// + /// When observed from the server side, and when communicating through an intermediary, client.port SHOULD represent the client port behind any intermediaries, for example proxies, if it&#39;s available. + /// + public const string AttributeClientPort = "client.port"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs new file mode 100644 index 0000000000..a85e786392 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs @@ -0,0 +1,259 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class CloudAttributes +{ + /// + /// The cloud account ID the resource is assigned to. + /// + public const string AttributeCloudAccountId = "cloud.account.id"; + + /// + /// Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. + /// + /// + /// Availability zones are called &#34;zones&#34; on Alibaba Cloud and Google Cloud. + /// + public const string AttributeCloudAvailabilityZone = "cloud.availability_zone"; + + /// + /// The cloud platform in use. + /// + /// + /// The prefix of the service SHOULD match the one specified in cloud.provider. + /// + public const string AttributeCloudPlatform = "cloud.platform"; + + /// + /// Name of the cloud provider. + /// + public const string AttributeCloudProvider = "cloud.provider"; + + /// + /// The geographical region the resource is running. + /// + /// + /// Refer to your provider&#39;s docs to see the available regions, for example Alibaba Cloud regions, AWS regions, Azure regions, Google Cloud regions, or Tencent Cloud regions. + /// + public const string AttributeCloudRegion = "cloud.region"; + + /// + /// Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on AWS, a fully qualified resource ID on Azure, a full resource name on GCP). + /// + /// + /// On some cloud providers, it may not be possible to determine the full ID at startup, + /// so it may be necessary to set cloud.resource_id as a span attribute instead.The exact value to use for cloud.resource_id depends on the cloud provider. + /// The following well-known definitions MUST be used if you set this attribute and they apply:
    + ///
  • AWS Lambda: The function ARN. + /// Take care not to use the &#34;invoked ARN&#34; directly but replace any + /// alias suffix + /// with the resolved function version, as the same runtime instance may be invokable with + /// multiple different aliases.
  • + ///
  • GCP: The URI of the resource
  • + ///
  • Azure: The Fully Qualified Resource ID of the invoked function, + /// not the function app, having the form + /// /subscriptions/<SUBSCIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>. + /// This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + /// a TracerProvider
  • + ///
. + ///
+ public const string AttributeCloudResourceId = "cloud.resource_id"; + + /// + /// The cloud platform in use. + /// + public static class CloudPlatformValues + { + /// + /// Alibaba Cloud Elastic Compute Service. + /// + public const string AlibabaCloudEcs = "alibaba_cloud_ecs"; + + /// + /// Alibaba Cloud Function Compute. + /// + public const string AlibabaCloudFc = "alibaba_cloud_fc"; + + /// + /// Red Hat OpenShift on Alibaba Cloud. + /// + public const string AlibabaCloudOpenshift = "alibaba_cloud_openshift"; + + /// + /// AWS Elastic Compute Cloud. + /// + public const string AwsEc2 = "aws_ec2"; + + /// + /// AWS Elastic Container Service. + /// + public const string AwsEcs = "aws_ecs"; + + /// + /// AWS Elastic Kubernetes Service. + /// + public const string AwsEks = "aws_eks"; + + /// + /// AWS Lambda. + /// + public const string AwsLambda = "aws_lambda"; + + /// + /// AWS Elastic Beanstalk. + /// + public const string AwsElasticBeanstalk = "aws_elastic_beanstalk"; + + /// + /// AWS App Runner. + /// + public const string AwsAppRunner = "aws_app_runner"; + + /// + /// Red Hat OpenShift on AWS (ROSA). + /// + public const string AwsOpenshift = "aws_openshift"; + + /// + /// Azure Virtual Machines. + /// + public const string AzureVm = "azure_vm"; + + /// + /// Azure Container Apps. + /// + public const string AzureContainerApps = "azure_container_apps"; + + /// + /// Azure Container Instances. + /// + public const string AzureContainerInstances = "azure_container_instances"; + + /// + /// Azure Kubernetes Service. + /// + public const string AzureAks = "azure_aks"; + + /// + /// Azure Functions. + /// + public const string AzureFunctions = "azure_functions"; + + /// + /// Azure App Service. + /// + public const string AzureAppService = "azure_app_service"; + + /// + /// Azure Red Hat OpenShift. + /// + public const string AzureOpenshift = "azure_openshift"; + + /// + /// Google Bare Metal Solution (BMS). + /// + public const string GcpBareMetalSolution = "gcp_bare_metal_solution"; + + /// + /// Google Cloud Compute Engine (GCE). + /// + public const string GcpComputeEngine = "gcp_compute_engine"; + + /// + /// Google Cloud Run. + /// + public const string GcpCloudRun = "gcp_cloud_run"; + + /// + /// Google Cloud Kubernetes Engine (GKE). + /// + public const string GcpKubernetesEngine = "gcp_kubernetes_engine"; + + /// + /// Google Cloud Functions (GCF). + /// + public const string GcpCloudFunctions = "gcp_cloud_functions"; + + /// + /// Google Cloud App Engine (GAE). + /// + public const string GcpAppEngine = "gcp_app_engine"; + + /// + /// Red Hat OpenShift on Google Cloud. + /// + public const string GcpOpenshift = "gcp_openshift"; + + /// + /// Red Hat OpenShift on IBM Cloud. + /// + public const string IbmCloudOpenshift = "ibm_cloud_openshift"; + + /// + /// Tencent Cloud Cloud Virtual Machine (CVM). + /// + public const string TencentCloudCvm = "tencent_cloud_cvm"; + + /// + /// Tencent Cloud Elastic Kubernetes Service (EKS). + /// + public const string TencentCloudEks = "tencent_cloud_eks"; + + /// + /// Tencent Cloud Serverless Cloud Function (SCF). + /// + public const string TencentCloudScf = "tencent_cloud_scf"; + } + + /// + /// Name of the cloud provider. + /// + public static class CloudProviderValues + { + /// + /// Alibaba Cloud. + /// + public const string AlibabaCloud = "alibaba_cloud"; + + /// + /// Amazon Web Services. + /// + public const string Aws = "aws"; + + /// + /// Microsoft Azure. + /// + public const string Azure = "azure"; + + /// + /// Google Cloud Platform. + /// + public const string Gcp = "gcp"; + + /// + /// Heroku Platform as a Service. + /// + public const string Heroku = "heroku"; + + /// + /// IBM Cloud. + /// + public const string IbmCloud = "ibm_cloud"; + + /// + /// Tencent Cloud. + /// + public const string TencentCloud = "tencent_cloud"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs new file mode 100644 index 0000000000..17114d24a0 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class CloudeventsAttributes +{ + /// + /// The event_id uniquely identifies the event. + /// + public const string AttributeCloudeventsEventId = "cloudevents.event_id"; + + /// + /// The source identifies the context in which an event happened. + /// + public const string AttributeCloudeventsEventSource = "cloudevents.event_source"; + + /// + /// The version of the CloudEvents specification which the event uses. + /// + public const string AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version"; + + /// + /// The subject of the event in the context of the event producer (identified by source). + /// + public const string AttributeCloudeventsEventSubject = "cloudevents.event_subject"; + + /// + /// The event_type contains a value describing the type of event related to the originating occurrence. + /// + public const string AttributeCloudeventsEventType = "cloudevents.event_type"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs new file mode 100644 index 0000000000..ebe40ae35c --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs @@ -0,0 +1,46 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class CodeAttributes +{ + /// + /// The column number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function. + /// + public const string AttributeCodeColumn = "code.column"; + + /// + /// The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). + /// + public const string AttributeCodeFilepath = "code.filepath"; + + /// + /// The method or function name, or equivalent (usually rightmost part of the code unit's name). + /// + public const string AttributeCodeFunction = "code.function"; + + /// + /// The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function. + /// + public const string AttributeCodeLineno = "code.lineno"; + + /// + /// The "namespace" within which code.function is defined. Usually the qualified class or module name, such that code.namespace + some separator + code.function form a unique identifier for the code unit. + /// + public const string AttributeCodeNamespace = "code.namespace"; + + /// + /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. + /// + public const string AttributeCodeStacktrace = "code.stacktrace"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs new file mode 100644 index 0000000000..53f6b930b9 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs @@ -0,0 +1,114 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ContainerAttributes +{ + /// + /// The command used to run the container (i.e. the command name). + /// + /// + /// If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + /// + public const string AttributeContainerCommand = "container.command"; + + /// + /// All the command arguments (including the command/executable itself) run by the container. [2]. + /// + public const string AttributeContainerCommandArgs = "container.command_args"; + + /// + /// The full command run by the container as a single string representing the full command. [2]. + /// + public const string AttributeContainerCommandLine = "container.command_line"; + + /// + /// The CPU state for this data point. + /// + public const string AttributeContainerCpuState = "container.cpu.state"; + + /// + /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated. + /// + public const string AttributeContainerId = "container.id"; + + /// + /// Runtime specific image identifier. Usually a hash algorithm followed by a UUID. + /// + /// + /// Docker defines a sha256 of the image id; container.image.id corresponds to the Image field from the Docker container inspect API endpoint. + /// K8s defines a link to the container registry repository with digest "imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625". + /// The ID is assinged by the container runtime and can vary in different environments. Consider using oci.manifest.digest if it is important to identify the same image in different environments/runtimes. + /// + public const string AttributeContainerImageId = "container.image.id"; + + /// + /// Name of the image the container was built on. + /// + public const string AttributeContainerImageName = "container.image.name"; + + /// + /// Repo digests of the container image as provided by the container runtime. + /// + /// + /// Docker and CRI report those under the RepoDigests field. + /// + public const string AttributeContainerImageRepoDigests = "container.image.repo_digests"; + + /// + /// Container image tags. An example can be found in Docker Image Inspect. Should be only the section of the full name for example from registry.example.com/my-org/my-image:. + /// + public const string AttributeContainerImageTags = "container.image.tags"; + + /// + /// Container labels, being the label name, the value being the label value. + /// + public const string AttributeContainerLabel = "container.label"; + + /// + /// Deprecated, use container.label instead. + /// + [Obsolete("Replaced by `container.label`")] + public const string AttributeContainerLabels = "container.labels"; + + /// + /// Container name used by container runtime. + /// + public const string AttributeContainerName = "container.name"; + + /// + /// The container runtime managing this container. + /// + public const string AttributeContainerRuntime = "container.runtime"; + + /// + /// The CPU state for this data point. + /// + public static class ContainerCpuStateValues + { + /// + /// When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). + /// + public const string User = "user"; + + /// + /// When CPU is used by the system (host OS). + /// + public const string System = "system"; + + /// + /// When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). + /// + public const string Kernel = "kernel"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs new file mode 100644 index 0000000000..ffdbf56873 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs @@ -0,0 +1,611 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DbAttributes +{ + /// + /// The consistency level of the query. Based on consistency values from CQL. + /// + public const string AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level"; + + /// + /// The data center of the coordinating node for a query. + /// + public const string AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc"; + + /// + /// The ID of the coordinating node for a query. + /// + public const string AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id"; + + /// + /// Whether or not the query is idempotent. + /// + public const string AttributeDbCassandraIdempotence = "db.cassandra.idempotence"; + + /// + /// The fetch size used for paging, i.e. how many rows will be returned at once. + /// + public const string AttributeDbCassandraPageSize = "db.cassandra.page_size"; + + /// + /// The number of times a query was speculatively executed. Not set or 0 if the query was not executed speculatively. + /// + public const string AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count"; + + /// + /// The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + /// + /// + /// This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of db.statement just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + /// + public const string AttributeDbCassandraTable = "db.cassandra.table"; + + /// + /// Deprecated, use server.address, server.port attributes instead. + /// + [Obsolete("Replaced by `server.address` and `server.port`.")] + public const string AttributeDbConnectionString = "db.connection_string"; + + /// + /// Unique Cosmos client instance id. + /// + public const string AttributeDbCosmosdbClientId = "db.cosmosdb.client_id"; + + /// + /// Cosmos client connection mode. + /// + public const string AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode"; + + /// + /// Cosmos DB container name. + /// + public const string AttributeDbCosmosdbContainer = "db.cosmosdb.container"; + + /// + /// CosmosDB Operation Type. + /// + public const string AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type"; + + /// + /// RU consumed for that operation. + /// + public const string AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge"; + + /// + /// Request payload size in bytes. + /// + public const string AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length"; + + /// + /// Cosmos DB status code. + /// + public const string AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code"; + + /// + /// Cosmos DB sub status code. + /// + public const string AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code"; + + /// + /// Represents the identifier of an Elasticsearch cluster. + /// + public const string AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name"; + + /// + /// Deprecated, use db.instance.id instead. + /// + [Obsolete("Replaced by `db.instance.id`")] + public const string AttributeDbElasticsearchNodeName = "db.elasticsearch.node.name"; + + /// + /// A dynamic value in the url path. + /// + /// + /// Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format db.elasticsearch.path_parts.<key>, where <key> is the url path part name. The implementation SHOULD reference the elasticsearch schema in order to map the path part values to their names. + /// + public const string AttributeDbElasticsearchPathParts = "db.elasticsearch.path_parts"; + + /// + /// An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like select @@hostname. + /// + public const string AttributeDbInstanceId = "db.instance.id"; + + /// + /// Removed, no replacement at this time. + /// + [Obsolete("Removed as not used")] + public const string AttributeDbJdbcDriverClassname = "db.jdbc.driver_classname"; + + /// + /// The MongoDB collection being accessed within the database stated in db.name. + /// + public const string AttributeDbMongodbCollection = "db.mongodb.collection"; + + /// + /// The Microsoft SQL Server instance name connecting to. This name is used to determine the port of a named instance. + /// + /// + /// If setting a db.mssql.instance_name, server.port is no longer required (but still recommended if non-standard). + /// + public const string AttributeDbMssqlInstanceName = "db.mssql.instance_name"; + + /// + /// This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). + /// + /// + /// In some SQL databases, the database name to be used is called &#34;schema name&#34;. In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). + /// + public const string AttributeDbName = "db.name"; + + /// + /// The name of the operation being executed, e.g. the MongoDB command name such as findAndModify, or the SQL keyword. + /// + /// + /// When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of db.statement just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. + /// + public const string AttributeDbOperation = "db.operation"; + + /// + /// The index of the database being accessed as used in the SELECT command, provided as an integer. To be used instead of the generic db.name attribute. + /// + public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; + + /// + /// The name of the primary table that the operation is acting upon, including the database name (if applicable). + /// + /// + /// It is not recommended to attempt any client-side parsing of db.statement just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + /// + public const string AttributeDbSqlTable = "db.sql.table"; + + /// + /// The database statement being executed. + /// + public const string AttributeDbStatement = "db.statement"; + + /// + /// An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + /// + public const string AttributeDbSystem = "db.system"; + + /// + /// Username for accessing the database. + /// + public const string AttributeDbUser = "db.user"; + + /// + /// The consistency level of the query. Based on consistency values from CQL. + /// + public static class DbCassandraConsistencyLevelValues + { + /// + /// all. + /// + public const string All = "all"; + + /// + /// each_quorum. + /// + public const string EachQuorum = "each_quorum"; + + /// + /// quorum. + /// + public const string Quorum = "quorum"; + + /// + /// local_quorum. + /// + public const string LocalQuorum = "local_quorum"; + + /// + /// one. + /// + public const string One = "one"; + + /// + /// two. + /// + public const string Two = "two"; + + /// + /// three. + /// + public const string Three = "three"; + + /// + /// local_one. + /// + public const string LocalOne = "local_one"; + + /// + /// any. + /// + public const string Any = "any"; + + /// + /// serial. + /// + public const string Serial = "serial"; + + /// + /// local_serial. + /// + public const string LocalSerial = "local_serial"; + } + + /// + /// Cosmos client connection mode. + /// + public static class DbCosmosdbConnectionModeValues + { + /// + /// Gateway (HTTP) connections mode. + /// + public const string Gateway = "gateway"; + + /// + /// Direct connection. + /// + public const string Direct = "direct"; + } + + /// + /// CosmosDB Operation Type. + /// + public static class DbCosmosdbOperationTypeValues + { + /// + /// invalid. + /// + public const string Invalid = "Invalid"; + + /// + /// create. + /// + public const string Create = "Create"; + + /// + /// patch. + /// + public const string Patch = "Patch"; + + /// + /// read. + /// + public const string Read = "Read"; + + /// + /// read_feed. + /// + public const string ReadFeed = "ReadFeed"; + + /// + /// delete. + /// + public const string Delete = "Delete"; + + /// + /// replace. + /// + public const string Replace = "Replace"; + + /// + /// execute. + /// + public const string Execute = "Execute"; + + /// + /// query. + /// + public const string Query = "Query"; + + /// + /// head. + /// + public const string Head = "Head"; + + /// + /// head_feed. + /// + public const string HeadFeed = "HeadFeed"; + + /// + /// upsert. + /// + public const string Upsert = "Upsert"; + + /// + /// batch. + /// + public const string Batch = "Batch"; + + /// + /// query_plan. + /// + public const string QueryPlan = "QueryPlan"; + + /// + /// execute_javascript. + /// + public const string ExecuteJavascript = "ExecuteJavaScript"; + } + + /// + /// An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + /// + public static class DbSystemValues + { + /// + /// Some other SQL database. Fallback only. See notes. + /// + public const string OtherSql = "other_sql"; + + /// + /// Microsoft SQL Server. + /// + public const string Mssql = "mssql"; + + /// + /// Microsoft SQL Server Compact. + /// + public const string Mssqlcompact = "mssqlcompact"; + + /// + /// MySQL. + /// + public const string Mysql = "mysql"; + + /// + /// Oracle Database. + /// + public const string Oracle = "oracle"; + + /// + /// IBM Db2. + /// + public const string Db2 = "db2"; + + /// + /// PostgreSQL. + /// + public const string Postgresql = "postgresql"; + + /// + /// Amazon Redshift. + /// + public const string Redshift = "redshift"; + + /// + /// Apache Hive. + /// + public const string Hive = "hive"; + + /// + /// Cloudscape. + /// + public const string Cloudscape = "cloudscape"; + + /// + /// HyperSQL DataBase. + /// + public const string Hsqldb = "hsqldb"; + + /// + /// Progress Database. + /// + public const string Progress = "progress"; + + /// + /// SAP MaxDB. + /// + public const string Maxdb = "maxdb"; + + /// + /// SAP HANA. + /// + public const string Hanadb = "hanadb"; + + /// + /// Ingres. + /// + public const string Ingres = "ingres"; + + /// + /// FirstSQL. + /// + public const string Firstsql = "firstsql"; + + /// + /// EnterpriseDB. + /// + public const string Edb = "edb"; + + /// + /// InterSystems Caché. + /// + public const string Cache = "cache"; + + /// + /// Adabas (Adaptable Database System). + /// + public const string Adabas = "adabas"; + + /// + /// Firebird. + /// + public const string Firebird = "firebird"; + + /// + /// Apache Derby. + /// + public const string Derby = "derby"; + + /// + /// FileMaker. + /// + public const string Filemaker = "filemaker"; + + /// + /// Informix. + /// + public const string Informix = "informix"; + + /// + /// InstantDB. + /// + public const string Instantdb = "instantdb"; + + /// + /// InterBase. + /// + public const string Interbase = "interbase"; + + /// + /// MariaDB. + /// + public const string Mariadb = "mariadb"; + + /// + /// Netezza. + /// + public const string Netezza = "netezza"; + + /// + /// Pervasive PSQL. + /// + public const string Pervasive = "pervasive"; + + /// + /// PointBase. + /// + public const string Pointbase = "pointbase"; + + /// + /// SQLite. + /// + public const string Sqlite = "sqlite"; + + /// + /// Sybase. + /// + public const string Sybase = "sybase"; + + /// + /// Teradata. + /// + public const string Teradata = "teradata"; + + /// + /// Vertica. + /// + public const string Vertica = "vertica"; + + /// + /// H2. + /// + public const string H2 = "h2"; + + /// + /// ColdFusion IMQ. + /// + public const string Coldfusion = "coldfusion"; + + /// + /// Apache Cassandra. + /// + public const string Cassandra = "cassandra"; + + /// + /// Apache HBase. + /// + public const string Hbase = "hbase"; + + /// + /// MongoDB. + /// + public const string Mongodb = "mongodb"; + + /// + /// Redis. + /// + public const string Redis = "redis"; + + /// + /// Couchbase. + /// + public const string Couchbase = "couchbase"; + + /// + /// CouchDB. + /// + public const string Couchdb = "couchdb"; + + /// + /// Microsoft Azure Cosmos DB. + /// + public const string Cosmosdb = "cosmosdb"; + + /// + /// Amazon DynamoDB. + /// + public const string Dynamodb = "dynamodb"; + + /// + /// Neo4j. + /// + public const string Neo4j = "neo4j"; + + /// + /// Apache Geode. + /// + public const string Geode = "geode"; + + /// + /// Elasticsearch. + /// + public const string Elasticsearch = "elasticsearch"; + + /// + /// Memcached. + /// + public const string Memcached = "memcached"; + + /// + /// CockroachDB. + /// + public const string Cockroachdb = "cockroachdb"; + + /// + /// OpenSearch. + /// + public const string Opensearch = "opensearch"; + + /// + /// ClickHouse. + /// + public const string Clickhouse = "clickhouse"; + + /// + /// Cloud Spanner. + /// + public const string Spanner = "spanner"; + + /// + /// Trino. + /// + public const string Trino = "trino"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs new file mode 100644 index 0000000000..38312d89a3 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DeploymentAttributes +{ + /// + /// Name of the deployment environment (aka deployment tier). + /// + /// + /// deployment.environment does not affect the uniqueness constraints defined through + /// the service.namespace, service.name and service.instance.id resource attributes. + /// This implies that resources carrying the following attribute combinations MUST be + /// considered to be identifying the same service:
    + ///
  • service.name=frontend, deployment.environment=production
  • + ///
  • service.name=frontend, deployment.environment=staging
  • + ///
. + ///
+ public const string AttributeDeploymentEnvironment = "deployment.environment"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs new file mode 100644 index 0000000000..08d9e7f480 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DestinationAttributes +{ + /// + /// Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// + /// + /// When observed from the source side, and when communicating through an intermediary, destination.address SHOULD represent the destination address behind any intermediaries, for example proxies, if it&#39;s available. + /// + public const string AttributeDestinationAddress = "destination.address"; + + /// + /// Destination port number. + /// + public const string AttributeDestinationPort = "destination.port"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs new file mode 100644 index 0000000000..9ea1ebc4fb --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DeviceAttributes +{ + /// + /// A unique identifier representing the device. + /// + /// + /// The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the vendor identifier. On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found here on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. + /// + public const string AttributeDeviceId = "device.id"; + + /// + /// The name of the device manufacturer. + /// + /// + /// The Android OS provides this field via Build. iOS apps SHOULD hardcode the value Apple. + /// + public const string AttributeDeviceManufacturer = "device.manufacturer"; + + /// + /// The model identifier for the device. + /// + /// + /// It&#39;s recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. + /// + public const string AttributeDeviceModelIdentifier = "device.model.identifier"; + + /// + /// The marketing name for the device model. + /// + /// + /// It&#39;s recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. + /// + public const string AttributeDeviceModelName = "device.model.name"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs new file mode 100644 index 0000000000..efa5cb59ce --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DiskAttributes +{ + /// + /// The disk IO operation direction. + /// + public const string AttributeDiskIoDirection = "disk.io.direction"; + + /// + /// The disk IO operation direction. + /// + public static class DiskIoDirectionValues + { + /// + /// read. + /// + public const string Read = "read"; + + /// + /// write. + /// + public const string Write = "write"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs new file mode 100644 index 0000000000..c7db90e746 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DnsAttributes +{ + /// + /// The name being queried. + /// + /// + /// If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. + /// + public const string AttributeDnsQuestionName = "dns.question.name"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs new file mode 100644 index 0000000000..cdee87e966 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class EnduserAttributes +{ + /// + /// Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. + /// + public const string AttributeEnduserId = "enduser.id"; + + /// + /// Actual/assumed role the client is making the request under extracted from token or application security context. + /// + public const string AttributeEnduserRole = "enduser.role"; + + /// + /// Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an OAuth 2.0 Access Token or an attribute value in a SAML 2.0 Assertion. + /// + public const string AttributeEnduserScope = "enduser.scope"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs new file mode 100644 index 0000000000..4793805994 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs @@ -0,0 +1,43 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ErrorAttributes +{ + /// + /// Describes a class of error the operation ended with. + /// + /// + /// The error.type SHOULD be predictable and SHOULD have low cardinality. + /// Instrumentations SHOULD document the list of errors they report.The cardinality of error.type within one instrumentation library SHOULD be low. + /// Telemetry consumers that aggregate data from multiple instrumentation libraries and applications + /// should be prepared for error.type to have high cardinality at query time when no + /// additional filters are applied.If the operation has completed successfully, instrumentations SHOULD NOT set error.type.If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), + /// it&#39;s RECOMMENDED to:
    + ///
  • Use a domain-specific attribute
  • + ///
  • Set error.type to capture all errors, regardless of whether they are defined within the domain-specific set or not
  • + ///
. + ///
+ public const string AttributeErrorType = "error.type"; + + /// + /// Describes a class of error the operation ended with. + /// + public static class ErrorTypeValues + { + /// + /// A fallback error value to be used when the instrumentation doesn't define a custom value. + /// + public const string Other = "_OTHER"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs new file mode 100644 index 0000000000..7def01aeaa --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class EventAttributes +{ + /// + /// Identifies the class / type of event. + /// + /// + /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. + /// + public const string AttributeEventName = "event.name"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs new file mode 100644 index 0000000000..9b26f61d88 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ExceptionAttributes +{ + /// + /// SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. + /// + /// + /// An exception is considered to have escaped (or left) the scope of a span, + /// if that span is ended while the exception is still logically &#34;in flight&#34;. + /// This may be actually &#34;in flight&#34; in some languages (e.g. if the exception + /// is passed to a Context manager&#39;s __exit__ method in Python) but will + /// usually be caught at the point of recording the exception in most languages.It is usually not possible to determine at the point where an exception is thrown + /// whether it will escape the scope of a span. + /// However, it is trivial to know that an exception + /// will escape, if one checks for an active exception just before ending the span, + /// as done in the example for recording span exceptions.It follows that an exception may still escape the scope of the span + /// even if the exception.escaped attribute was not set or set to false, + /// since the event might have been recorded at a time where it was not + /// clear whether the exception will escape. + /// + public const string AttributeExceptionEscaped = "exception.escaped"; + + /// + /// The exception message. + /// + public const string AttributeExceptionMessage = "exception.message"; + + /// + /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. + /// + public const string AttributeExceptionStacktrace = "exception.stacktrace"; + + /// + /// The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. + /// + public const string AttributeExceptionType = "exception.type"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs new file mode 100644 index 0000000000..bf4ff8d157 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs @@ -0,0 +1,223 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class FaasAttributes +{ + /// + /// A boolean that is true if the serverless function is executed for the first time (aka cold-start). + /// + public const string AttributeFaasColdstart = "faas.coldstart"; + + /// + /// A string containing the schedule period as Cron Expression. + /// + public const string AttributeFaasCron = "faas.cron"; + + /// + /// The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. + /// + public const string AttributeFaasDocumentCollection = "faas.document.collection"; + + /// + /// The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. + /// + public const string AttributeFaasDocumentName = "faas.document.name"; + + /// + /// Describes the type of the operation that was performed on the data. + /// + public const string AttributeFaasDocumentOperation = "faas.document.operation"; + + /// + /// A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC. + /// + public const string AttributeFaasDocumentTime = "faas.document.time"; + + /// + /// The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. + /// + /// + ///
    + ///
  • AWS Lambda: Use the (full) log stream name
  • + ///
. + ///
+ public const string AttributeFaasInstance = "faas.instance"; + + /// + /// The invocation ID of the current function invocation. + /// + public const string AttributeFaasInvocationId = "faas.invocation_id"; + + /// + /// The name of the invoked function. + /// + /// + /// SHOULD be equal to the faas.name resource attribute of the invoked function. + /// + public const string AttributeFaasInvokedName = "faas.invoked_name"; + + /// + /// The cloud provider of the invoked function. + /// + /// + /// SHOULD be equal to the cloud.provider resource attribute of the invoked function. + /// + public const string AttributeFaasInvokedProvider = "faas.invoked_provider"; + + /// + /// The cloud region of the invoked function. + /// + /// + /// SHOULD be equal to the cloud.region resource attribute of the invoked function. + /// + public const string AttributeFaasInvokedRegion = "faas.invoked_region"; + + /// + /// The amount of memory available to the serverless function converted to Bytes. + /// + /// + /// It&#39;s recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE provides this information (which must be multiplied by 1,048,576). + /// + public const string AttributeFaasMaxMemory = "faas.max_memory"; + + /// + /// The name of the single function that this runtime instance executes. + /// + /// + /// This is the name of the function as configured/deployed on the FaaS + /// platform and is usually different from the name of the callback + /// function (which may be stored in the + /// code.namespace/code.function + /// span attributes).For some cloud providers, the above definition is ambiguous. The following + /// definition of function name MUST be used for this attribute + /// (and consequently the span name) for the listed cloud providers/products:
    + ///
  • Azure: The full name <FUNCAPP>/<FUNC>, i.e., function app name + /// followed by a forward slash followed by the function name (this form + /// can also be seen in the resource JSON for the function). + /// This means that a span attribute MUST be used, as an Azure function + /// app can host multiple functions that would usually share + /// a TracerProvider (see also the cloud.resource_id attribute)
  • + ///
. + ///
+ public const string AttributeFaasName = "faas.name"; + + /// + /// A string containing the function invocation time in the ISO 8601 format expressed in UTC. + /// + public const string AttributeFaasTime = "faas.time"; + + /// + /// Type of the trigger which caused this function invocation. + /// + public const string AttributeFaasTrigger = "faas.trigger"; + + /// + /// The immutable version of the function being executed. + /// + /// + /// Depending on the cloud provider and platform, use:
    + ///
  • AWS Lambda: The function version + /// (an integer represented as a decimal string).
  • + ///
  • Google Cloud Run (Services): The revision + /// (i.e., the function name plus the revision suffix).
  • + ///
  • Google Cloud Functions: The value of the + /// K_REVISION environment variable.
  • + ///
  • Azure Functions: Not applicable. Do not set this attribute
  • + ///
. + ///
+ public const string AttributeFaasVersion = "faas.version"; + + /// + /// Describes the type of the operation that was performed on the data. + /// + public static class FaasDocumentOperationValues + { + /// + /// When a new object is created. + /// + public const string Insert = "insert"; + + /// + /// When an object is modified. + /// + public const string Edit = "edit"; + + /// + /// When an object is deleted. + /// + public const string Delete = "delete"; + } + + /// + /// The cloud provider of the invoked function. + /// + public static class FaasInvokedProviderValues + { + /// + /// Alibaba Cloud. + /// + public const string AlibabaCloud = "alibaba_cloud"; + + /// + /// Amazon Web Services. + /// + public const string Aws = "aws"; + + /// + /// Microsoft Azure. + /// + public const string Azure = "azure"; + + /// + /// Google Cloud Platform. + /// + public const string Gcp = "gcp"; + + /// + /// Tencent Cloud. + /// + public const string TencentCloud = "tencent_cloud"; + } + + /// + /// Type of the trigger which caused this function invocation. + /// + public static class FaasTriggerValues + { + /// + /// A response to some data source operation such as a database or filesystem read/write. + /// + public const string Datasource = "datasource"; + + /// + /// To provide an answer to an inbound HTTP request. + /// + public const string Http = "http"; + + /// + /// A function is set to be executed when messages are sent to a messaging system. + /// + public const string Pubsub = "pubsub"; + + /// + /// A function is scheduled to be executed regularly. + /// + public const string Timer = "timer"; + + /// + /// If none of the others apply. + /// + public const string Other = "other"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs new file mode 100644 index 0000000000..31c3a7c683 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class FeatureFlagAttributes +{ + /// + /// The unique identifier of the feature flag. + /// + public const string AttributeFeatureFlagKey = "feature_flag.key"; + + /// + /// The name of the service provider that performs the flag evaluation. + /// + public const string AttributeFeatureFlagProviderName = "feature_flag.provider_name"; + + /// + /// SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. + /// + /// + /// A semantic identifier, commonly referred to as a variant, provides a means + /// for referring to a value without including the value itself. This can + /// provide additional context for understanding the meaning behind a value. + /// For example, the variant red maybe be used for the value #c05543.A stringified version of the value can be used in situations where a + /// semantic identifier is unavailable. String representation of the value + /// should be determined by the implementer. + /// + public const string AttributeFeatureFlagVariant = "feature_flag.variant"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs new file mode 100644 index 0000000000..e0d80da3d4 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class FileAttributes +{ + /// + /// Directory where the file is located. It should include the drive letter, when appropriate. + /// + public const string AttributeFileDirectory = "file.directory"; + + /// + /// File extension, excluding the leading dot. + /// + /// + /// When the file name has multiple extensions (example.tar.gz), only the last one should be captured (&#34;gz&#34;, not &#34;tar.gz&#34;). + /// + public const string AttributeFileExtension = "file.extension"; + + /// + /// Name of the file including the extension, without the directory. + /// + public const string AttributeFileName = "file.name"; + + /// + /// Full path to the file, including the file name. It should include the drive letter, when appropriate. + /// + public const string AttributeFilePath = "file.path"; + + /// + /// File size in bytes. + /// + public const string AttributeFileSize = "file.size"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs new file mode 100644 index 0000000000..d22ebdd455 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class GcpAttributes +{ + /// + /// The name of the Cloud Run execution being run for the Job, as set by the CLOUD_RUN_EXECUTION environment variable. + /// + public const string AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution"; + + /// + /// The index for a task within an execution as provided by the CLOUD_RUN_TASK_INDEX environment variable. + /// + public const string AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index"; + + /// + /// The hostname of a GCE instance. This is the full value of the default or custom hostname. + /// + public const string AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname"; + + /// + /// The instance name of a GCE instance. This is the value provided by host.name, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the default internal DNS name. + /// + public const string AttributeGcpGceInstanceName = "gcp.gce.instance.name"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs new file mode 100644 index 0000000000..d41a88d9c6 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class GraphqlAttributes +{ + /// + /// The GraphQL document being executed. + /// + /// + /// The value may be sanitized to exclude sensitive information. + /// + public const string AttributeGraphqlDocument = "graphql.document"; + + /// + /// The name of the operation being executed. + /// + public const string AttributeGraphqlOperationName = "graphql.operation.name"; + + /// + /// The type of the operation being executed. + /// + public const string AttributeGraphqlOperationType = "graphql.operation.type"; + + /// + /// The type of the operation being executed. + /// + public static class GraphqlOperationTypeValues + { + /// + /// GraphQL query. + /// + public const string Query = "query"; + + /// + /// GraphQL mutation. + /// + public const string Mutation = "mutation"; + + /// + /// GraphQL subscription. + /// + public const string Subscription = "subscription"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs new file mode 100644 index 0000000000..0a4f498019 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class HerokuAttributes +{ + /// + /// Unique identifier for the application. + /// + public const string AttributeHerokuAppId = "heroku.app.id"; + + /// + /// Commit hash for the current release. + /// + public const string AttributeHerokuReleaseCommit = "heroku.release.commit"; + + /// + /// Time and date the release was created. + /// + public const string AttributeHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs new file mode 100644 index 0000000000..c80d817bde --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs @@ -0,0 +1,146 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class HostAttributes +{ + /// + /// The CPU architecture the host system is running on. + /// + public const string AttributeHostArch = "host.arch"; + + /// + /// The amount of level 2 memory cache available to the processor (in Bytes). + /// + public const string AttributeHostCpuCacheL2Size = "host.cpu.cache.l2.size"; + + /// + /// Family or generation of the CPU. + /// + public const string AttributeHostCpuFamily = "host.cpu.family"; + + /// + /// Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. + /// + public const string AttributeHostCpuModelId = "host.cpu.model.id"; + + /// + /// Model designation of the processor. + /// + public const string AttributeHostCpuModelName = "host.cpu.model.name"; + + /// + /// Stepping or core revisions. + /// + public const string AttributeHostCpuStepping = "host.cpu.stepping"; + + /// + /// Processor manufacturer identifier. A maximum 12-character string. + /// + /// + /// CPUID command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. + /// + public const string AttributeHostCpuVendorId = "host.cpu.vendor.id"; + + /// + /// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the machine-id. See the table below for the sources to use to determine the machine-id based on operating system. + /// + public const string AttributeHostId = "host.id"; + + /// + /// VM image ID or host OS image ID. For Cloud, this value is from the provider. + /// + public const string AttributeHostImageId = "host.image.id"; + + /// + /// Name of the VM image or OS install the host was instantiated from. + /// + public const string AttributeHostImageName = "host.image.name"; + + /// + /// The version string of the VM image or host OS as defined in Version Attributes. + /// + public const string AttributeHostImageVersion = "host.image.version"; + + /// + /// Available IP addresses of the host, excluding loopback interfaces. + /// + /// + /// IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the RFC 5952 format. + /// + public const string AttributeHostIp = "host.ip"; + + /// + /// Available MAC addresses of the host, excluding loopback interfaces. + /// + /// + /// MAC Addresses MUST be represented in IEEE RA hexadecimal form: as hyphen-separated octets in uppercase hexadecimal form from most to least significant. + /// + public const string AttributeHostMac = "host.mac"; + + /// + /// Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. + /// + public const string AttributeHostName = "host.name"; + + /// + /// Type of host. For Cloud, this must be the machine type. + /// + public const string AttributeHostType = "host.type"; + + /// + /// The CPU architecture the host system is running on. + /// + public static class HostArchValues + { + /// + /// AMD64. + /// + public const string Amd64 = "amd64"; + + /// + /// ARM32. + /// + public const string Arm32 = "arm32"; + + /// + /// ARM64. + /// + public const string Arm64 = "arm64"; + + /// + /// Itanium. + /// + public const string Ia64 = "ia64"; + + /// + /// 32-bit PowerPC. + /// + public const string Ppc32 = "ppc32"; + + /// + /// 64-bit PowerPC. + /// + public const string Ppc64 = "ppc64"; + + /// + /// IBM z/Architecture. + /// + public const string S390x = "s390x"; + + /// + /// 32-bit x86. + /// + public const string X86 = "x86"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs new file mode 100644 index 0000000000..e84a5b8bf7 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs @@ -0,0 +1,265 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class HttpAttributes +{ + /// + /// State of the HTTP connection in the HTTP connection pool. + /// + public const string AttributeHttpConnectionState = "http.connection.state"; + + /// + /// Deprecated, use network.protocol.name instead. + /// + [Obsolete("Replaced by `network.protocol.name`")] + public const string AttributeHttpFlavor = "http.flavor"; + + /// + /// Deprecated, use http.request.method instead. + /// + [Obsolete("Replaced by `http.request.method`")] + public const string AttributeHttpMethod = "http.method"; + + /// + /// The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size. + /// + public const string AttributeHttpRequestBodySize = "http.request.body.size"; + + /// + /// HTTP request headers, being the normalized HTTP Header name (lowercase), the value being the header values. + /// + /// + /// Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// The User-Agent header is already captured in the user_agent.original attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + /// + public const string AttributeHttpRequestHeader = "http.request.header"; + + /// + /// HTTP request method. + /// + /// + /// HTTP request method value SHOULD be &#34;known&#34; to the instrumentation. + /// By default, this convention defines &#34;known&#34; methods as the ones listed in RFC9110 + /// and the PATCH method defined in RFC5789.If the HTTP request method is not known to instrumentation, it MUST set the http.request.method attribute to _OTHER.If the HTTP instrumentation could end up converting valid HTTP request methods to _OTHER, then it MUST provide a way to override + /// the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named + /// OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods + /// (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).HTTP method names are case-sensitive and http.request.method attribute value MUST match a known HTTP method name exactly. + /// Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. + /// Tracing instrumentations that do so, MUST also set http.request.method_original to the original value. + /// + public const string AttributeHttpRequestMethod = "http.request.method"; + + /// + /// Original HTTP method sent by the client in the request line. + /// + public const string AttributeHttpRequestMethodOriginal = "http.request.method_original"; + + /// + /// The ordinal number of request resending attempt (for any reason, including redirects). + /// + /// + /// The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). + /// + public const string AttributeHttpRequestResendCount = "http.request.resend_count"; + + /// + /// The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. + /// + public const string AttributeHttpRequestSize = "http.request.size"; + + /// + /// Deprecated, use http.request.header.content-length instead. + /// + [Obsolete("Replaced by `http.request.header.content-length`")] + public const string AttributeHttpRequestContentLength = "http.request_content_length"; + + /// + /// The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size. + /// + public const string AttributeHttpResponseBodySize = "http.response.body.size"; + + /// + /// HTTP response headers, being the normalized HTTP Header name (lowercase), the value being the header values. + /// + /// + /// Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + /// + public const string AttributeHttpResponseHeader = "http.response.header"; + + /// + /// The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. + /// + public const string AttributeHttpResponseSize = "http.response.size"; + + /// + /// HTTP response status code. + /// + public const string AttributeHttpResponseStatusCode = "http.response.status_code"; + + /// + /// Deprecated, use http.response.header.content-length instead. + /// + [Obsolete("Replaced by `http.response.header.content-length`")] + public const string AttributeHttpResponseContentLength = "http.response_content_length"; + + /// + /// The matched route, that is, the path template in the format used by the respective server framework. + /// + /// + /// MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. + /// SHOULD include the application root if there is one. + /// + public const string AttributeHttpRoute = "http.route"; + + /// + /// Deprecated, use url.scheme instead. + /// + [Obsolete("Replaced by `url.scheme` instead")] + public const string AttributeHttpScheme = "http.scheme"; + + /// + /// Deprecated, use http.response.status_code instead. + /// + [Obsolete("Replaced by `http.response.status_code`")] + public const string AttributeHttpStatusCode = "http.status_code"; + + /// + /// Deprecated, use url.path and url.query instead. + /// + [Obsolete("Split to `url.path` and `url.query")] + public const string AttributeHttpTarget = "http.target"; + + /// + /// Deprecated, use url.full instead. + /// + [Obsolete("Replaced by `url.full`")] + public const string AttributeHttpUrl = "http.url"; + + /// + /// Deprecated, use user_agent.original instead. + /// + [Obsolete("Replaced by `user_agent.original`")] + public const string AttributeHttpUserAgent = "http.user_agent"; + + /// + /// State of the HTTP connection in the HTTP connection pool. + /// + public static class HttpConnectionStateValues + { + /// + /// active state. + /// + public const string Active = "active"; + + /// + /// idle state. + /// + public const string Idle = "idle"; + } + + /// + /// Deprecated, use network.protocol.name instead. + /// + public static class HttpFlavorValues + { + /// + /// HTTP/1.0. + /// + public const string Http10 = "1.0"; + + /// + /// HTTP/1.1. + /// + public const string Http11 = "1.1"; + + /// + /// HTTP/2. + /// + public const string Http20 = "2.0"; + + /// + /// HTTP/3. + /// + public const string Http30 = "3.0"; + + /// + /// SPDY protocol. + /// + public const string Spdy = "SPDY"; + + /// + /// QUIC protocol. + /// + public const string Quic = "QUIC"; + } + + /// + /// HTTP request method. + /// + public static class HttpRequestMethodValues + { + /// + /// CONNECT method. + /// + public const string Connect = "CONNECT"; + + /// + /// DELETE method. + /// + public const string Delete = "DELETE"; + + /// + /// GET method. + /// + public const string Get = "GET"; + + /// + /// HEAD method. + /// + public const string Head = "HEAD"; + + /// + /// OPTIONS method. + /// + public const string Options = "OPTIONS"; + + /// + /// PATCH method. + /// + public const string Patch = "PATCH"; + + /// + /// POST method. + /// + public const string Post = "POST"; + + /// + /// PUT method. + /// + public const string Put = "PUT"; + + /// + /// TRACE method. + /// + public const string Trace = "TRACE"; + + /// + /// Any HTTP method that the instrumentation has no prior knowledge of. + /// + public const string Other = "_OTHER"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs new file mode 100644 index 0000000000..0ba843170d --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class IosAttributes +{ + /// + /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// + /// + /// The iOS lifecycle states are defined in the UIApplicationDelegate documentation, and from which the OS terminology column values are derived. + /// + public const string AttributeIosState = "ios.state"; + + /// + /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// + public static class IosStateValues + { + /// + /// The app has become active. Associated with UIKit notification applicationDidBecomeActive. + /// + public const string Active = "active"; + + /// + /// The app is now inactive. Associated with UIKit notification applicationWillResignActive. + /// + public const string Inactive = "inactive"; + + /// + /// The app is now in the background. This value is associated with UIKit notification applicationDidEnterBackground. + /// + public const string Background = "background"; + + /// + /// The app is now in the foreground. This value is associated with UIKit notification applicationWillEnterForeground. + /// + public const string Foreground = "foreground"; + + /// + /// The app is about to terminate. Associated with UIKit notification applicationWillTerminate. + /// + public const string Terminate = "terminate"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs new file mode 100644 index 0000000000..74ba9d1983 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs @@ -0,0 +1,115 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class JvmAttributes +{ + /// + /// Name of the buffer pool. + /// + /// + /// Pool names are generally obtained via BufferPoolMXBean#getName(). + /// + public const string AttributeJvmBufferPoolName = "jvm.buffer.pool.name"; + + /// + /// Name of the garbage collector action. + /// + /// + /// Garbage collector action is generally obtained via GarbageCollectionNotificationInfo#getGcAction(). + /// + public const string AttributeJvmGcAction = "jvm.gc.action"; + + /// + /// Name of the garbage collector. + /// + /// + /// Garbage collector name is generally obtained via GarbageCollectionNotificationInfo#getGcName(). + /// + public const string AttributeJvmGcName = "jvm.gc.name"; + + /// + /// Name of the memory pool. + /// + /// + /// Pool names are generally obtained via MemoryPoolMXBean#getName(). + /// + public const string AttributeJvmMemoryPoolName = "jvm.memory.pool.name"; + + /// + /// The type of memory. + /// + public const string AttributeJvmMemoryType = "jvm.memory.type"; + + /// + /// Whether the thread is daemon or not. + /// + public const string AttributeJvmThreadDaemon = "jvm.thread.daemon"; + + /// + /// State of the thread. + /// + public const string AttributeJvmThreadState = "jvm.thread.state"; + + /// + /// The type of memory. + /// + public static class JvmMemoryTypeValues + { + /// + /// Heap memory. + /// + public const string Heap = "heap"; + + /// + /// Non-heap memory. + /// + public const string NonHeap = "non_heap"; + } + + /// + /// State of the thread. + /// + public static class JvmThreadStateValues + { + /// + /// A thread that has not yet started is in this state. + /// + public const string New = "new"; + + /// + /// A thread executing in the Java virtual machine is in this state. + /// + public const string Runnable = "runnable"; + + /// + /// A thread that is blocked waiting for a monitor lock is in this state. + /// + public const string Blocked = "blocked"; + + /// + /// A thread that is waiting indefinitely for another thread to perform a particular action is in this state. + /// + public const string Waiting = "waiting"; + + /// + /// A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. + /// + public const string TimedWaiting = "timed_waiting"; + + /// + /// A thread that has exited is in this state. + /// + public const string Terminated = "terminated"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs new file mode 100644 index 0000000000..614ce06d72 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs @@ -0,0 +1,155 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class K8sAttributes +{ + /// + /// The name of the cluster. + /// + public const string AttributeK8sClusterName = "k8s.cluster.name"; + + /// + /// A pseudo-ID for the cluster, set to the UID of the kube-system namespace. + /// + /// + /// K8s doesn&#39;t have support for obtaining a cluster ID. If this is ever + /// added, we will recommend collecting the k8s.cluster.uid through the + /// official APIs. In the meantime, we are able to use the uid of the + /// kube-system namespace as a proxy for cluster ID. Read on for the + /// rationale.Every object created in a K8s cluster is assigned a distinct UID. The + /// kube-system namespace is used by Kubernetes itself and will exist + /// for the lifetime of the cluster. Using the uid of the kube-system + /// namespace is a reasonable proxy for the K8s ClusterID as it will only + /// change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are + /// UUIDs as standardized by + /// ISO/IEC 9834-8 and ITU-T X.667. + /// Which states:&gt; If generated according to one of the mechanisms defined in Rec. + /// ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be + /// different from all other UUIDs generated before 3603 A.D., or is + /// extremely likely to be different (depending on the mechanism chosen).Therefore, UIDs between clusters should be extremely unlikely to + /// conflict. + /// + public const string AttributeK8sClusterUid = "k8s.cluster.uid"; + + /// + /// The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (container.name). + /// + public const string AttributeK8sContainerName = "k8s.container.name"; + + /// + /// Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. + /// + public const string AttributeK8sContainerRestartCount = "k8s.container.restart_count"; + + /// + /// The name of the CronJob. + /// + public const string AttributeK8sCronjobName = "k8s.cronjob.name"; + + /// + /// The UID of the CronJob. + /// + public const string AttributeK8sCronjobUid = "k8s.cronjob.uid"; + + /// + /// The name of the DaemonSet. + /// + public const string AttributeK8sDaemonsetName = "k8s.daemonset.name"; + + /// + /// The UID of the DaemonSet. + /// + public const string AttributeK8sDaemonsetUid = "k8s.daemonset.uid"; + + /// + /// The name of the Deployment. + /// + public const string AttributeK8sDeploymentName = "k8s.deployment.name"; + + /// + /// The UID of the Deployment. + /// + public const string AttributeK8sDeploymentUid = "k8s.deployment.uid"; + + /// + /// The name of the Job. + /// + public const string AttributeK8sJobName = "k8s.job.name"; + + /// + /// The UID of the Job. + /// + public const string AttributeK8sJobUid = "k8s.job.uid"; + + /// + /// The name of the namespace that the pod is running in. + /// + public const string AttributeK8sNamespaceName = "k8s.namespace.name"; + + /// + /// The name of the Node. + /// + public const string AttributeK8sNodeName = "k8s.node.name"; + + /// + /// The UID of the Node. + /// + public const string AttributeK8sNodeUid = "k8s.node.uid"; + + /// + /// The annotation key-value pairs placed on the Pod, the being the annotation name, the value being the annotation value. + /// + public const string AttributeK8sPodAnnotation = "k8s.pod.annotation"; + + /// + /// The label key-value pairs placed on the Pod, the being the label name, the value being the label value. + /// + public const string AttributeK8sPodLabel = "k8s.pod.label"; + + /// + /// Deprecated, use k8s.pod.label instead. + /// + [Obsolete("Replaced by `k8s.pod.label`")] + public const string AttributeK8sPodLabels = "k8s.pod.labels"; + + /// + /// The name of the Pod. + /// + public const string AttributeK8sPodName = "k8s.pod.name"; + + /// + /// The UID of the Pod. + /// + public const string AttributeK8sPodUid = "k8s.pod.uid"; + + /// + /// The name of the ReplicaSet. + /// + public const string AttributeK8sReplicasetName = "k8s.replicaset.name"; + + /// + /// The UID of the ReplicaSet. + /// + public const string AttributeK8sReplicasetUid = "k8s.replicaset.uid"; + + /// + /// The name of the StatefulSet. + /// + public const string AttributeK8sStatefulsetName = "k8s.statefulset.name"; + + /// + /// The UID of the StatefulSet. + /// + public const string AttributeK8sStatefulsetUid = "k8s.statefulset.uid"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs new file mode 100644 index 0000000000..a314e0deb4 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs @@ -0,0 +1,66 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class LogAttributes +{ + /// + /// The basename of the file. + /// + public const string AttributeLogFileName = "log.file.name"; + + /// + /// The basename of the file, with symlinks resolved. + /// + public const string AttributeLogFileNameResolved = "log.file.name_resolved"; + + /// + /// The full path to the file. + /// + public const string AttributeLogFilePath = "log.file.path"; + + /// + /// The full path to the file, with symlinks resolved. + /// + public const string AttributeLogFilePathResolved = "log.file.path_resolved"; + + /// + /// The stream associated with the log. See below for a list of well-known values. + /// + public const string AttributeLogIostream = "log.iostream"; + + /// + /// A unique identifier for the Log Record. + /// + /// + /// If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. + /// The id MAY be an Universally Unique Lexicographically Sortable Identifier (ULID), but other identifiers (e.g. UUID) may be used as needed. + /// + public const string AttributeLogRecordUid = "log.record.uid"; + + /// + /// The stream associated with the log. See below for a list of well-known values. + /// + public static class LogIostreamValues + { + /// + /// Logs from stdout stream. + /// + public const string Stdout = "stdout"; + + /// + /// Events from stderr stream. + /// + public const string Stderr = "stderr"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs new file mode 100644 index 0000000000..5014c3b41d --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class MessageAttributes +{ + /// + /// Compressed size of the message in bytes. + /// + public const string AttributeMessageCompressedSize = "message.compressed_size"; + + /// + /// MUST be calculated as two different counters starting from 1 one for sent messages and one for received message. + /// + /// + /// This way we guarantee that the values will be consistent between different implementations. + /// + public const string AttributeMessageId = "message.id"; + + /// + /// Whether this is a received or sent message. + /// + public const string AttributeMessageType = "message.type"; + + /// + /// Uncompressed size of the message in bytes. + /// + public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; + + /// + /// Whether this is a received or sent message. + /// + public static class MessageTypeValues + { + /// + /// sent. + /// + public const string Sent = "SENT"; + + /// + /// received. + /// + public const string Received = "RECEIVED"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs new file mode 100644 index 0000000000..22c391ac2a --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs @@ -0,0 +1,390 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class MessagingAttributes +{ + /// + /// The number of messages sent, received, or processed in the scope of the batching operation. + /// + /// + /// Instrumentations SHOULD NOT set messaging.batch.message_count on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use messaging.batch.message_count for batching APIs and SHOULD NOT use it for single-message APIs. + /// + public const string AttributeMessagingBatchMessageCount = "messaging.batch.message_count"; + + /// + /// A unique identifier for the client that consumes or produces a message. + /// + public const string AttributeMessagingClientId = "messaging.client_id"; + + /// + /// A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). + /// + public const string AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous"; + + /// + /// The message destination name. + /// + /// + /// Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If + /// the broker doesn&#39;t have such notion, the destination name SHOULD uniquely identify the broker. + /// + public const string AttributeMessagingDestinationName = "messaging.destination.name"; + + /// + /// The identifier of the partition messages are sent to or received from, unique within the messaging.destination.name. + /// + public const string AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id"; + + /// + /// Low cardinality representation of the messaging destination name. + /// + /// + /// Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + /// + public const string AttributeMessagingDestinationTemplate = "messaging.destination.template"; + + /// + /// A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. + /// + public const string AttributeMessagingDestinationTemporary = "messaging.destination.temporary"; + + /// + /// A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). + /// + public const string AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous"; + + /// + /// The name of the original destination the message was published to. + /// + /// + /// The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If + /// the broker doesn&#39;t have such notion, the original destination name SHOULD uniquely identify the broker. + /// + public const string AttributeMessagingDestinationPublishName = "messaging.destination_publish.name"; + + /// + /// The name of the consumer group the event consumer is associated with. + /// + public const string AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group"; + + /// + /// The UTC epoch seconds at which the message has been accepted and stored in the entity. + /// + public const string AttributeMessagingEventhubsMessageEnqueuedTime = "messaging.eventhubs.message.enqueued_time"; + + /// + /// The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. + /// + public const string AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key"; + + /// + /// Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. + /// + public const string AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; + + /// + /// "Deprecated, use messaging.destination.partition.id instead.". + /// + [Obsolete("Replaced by `messaging.destination.partition.id`")] + public const string AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition"; + + /// + /// Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from messaging.message.id in that they're not unique. If the key is null, the attribute MUST NOT be set. + /// + /// + /// If the key type is not string, it&#39;s string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don&#39;t include its value. + /// + public const string AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key"; + + /// + /// The offset of a record in the corresponding Kafka partition. + /// + public const string AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; + + /// + /// A boolean that is true if the message is a tombstone. + /// + public const string AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone"; + + /// + /// The size of the message body in bytes. + /// + /// + /// This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed + /// body size should be used. + /// + public const string AttributeMessagingMessageBodySize = "messaging.message.body.size"; + + /// + /// The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". + /// + public const string AttributeMessagingMessageConversationId = "messaging.message.conversation_id"; + + /// + /// The size of the message body and metadata in bytes. + /// + /// + /// This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed + /// size should be used. + /// + public const string AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size"; + + /// + /// A value used by the messaging system as an identifier for the message, represented as a string. + /// + public const string AttributeMessagingMessageId = "messaging.message.id"; + + /// + /// A string identifying the kind of messaging operation. + /// + /// + /// If a custom value is used, it MUST be of low cardinality. + /// + public const string AttributeMessagingOperation = "messaging.operation"; + + /// + /// RabbitMQ message routing key. + /// + public const string AttributeMessagingRabbitmqDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key"; + + /// + /// RabbitMQ message delivery tag. + /// + public const string AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag"; + + /// + /// Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. + /// + public const string AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group"; + + /// + /// Model of message consumption. This only applies to consumer spans. + /// + public const string AttributeMessagingRocketmqConsumptionModel = "messaging.rocketmq.consumption_model"; + + /// + /// The delay time level for delay message, which determines the message delay time. + /// + public const string AttributeMessagingRocketmqMessageDelayTimeLevel = "messaging.rocketmq.message.delay_time_level"; + + /// + /// The timestamp in milliseconds that the delay message is expected to be delivered to consumer. + /// + public const string AttributeMessagingRocketmqMessageDeliveryTimestamp = "messaging.rocketmq.message.delivery_timestamp"; + + /// + /// It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. + /// + public const string AttributeMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group"; + + /// + /// Key(s) of message, another way to mark message besides message id. + /// + public const string AttributeMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys"; + + /// + /// The secondary classifier of message besides topic. + /// + public const string AttributeMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag"; + + /// + /// Type of message. + /// + public const string AttributeMessagingRocketmqMessageType = "messaging.rocketmq.message.type"; + + /// + /// Namespace of RocketMQ resources, resources in different namespaces are individual. + /// + public const string AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; + + /// + /// The name of the subscription in the topic messages are received from. + /// + public const string AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name"; + + /// + /// Describes the settlement type. + /// + public const string AttributeMessagingServicebusDispositionStatus = "messaging.servicebus.disposition_status"; + + /// + /// Number of deliveries that have been attempted for this message. + /// + public const string AttributeMessagingServicebusMessageDeliveryCount = "messaging.servicebus.message.delivery_count"; + + /// + /// The UTC epoch seconds at which the message has been accepted and stored in the entity. + /// + public const string AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time"; + + /// + /// An identifier for the messaging system being used. See below for a list of well-known identifiers. + /// + public const string AttributeMessagingSystem = "messaging.system"; + + /// + /// A string identifying the kind of messaging operation. + /// + public static class MessagingOperationValues + { + /// + /// One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. + /// + public const string Publish = "publish"; + + /// + /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. + /// + public const string Create = "create"; + + /// + /// One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. + /// + public const string Receive = "receive"; + + /// + /// One or more messages are delivered to or processed by a consumer. + /// + public const string Deliver = "process"; + + /// + /// One or more messages are settled. + /// + public const string Settle = "settle"; + } + + /// + /// Model of message consumption. This only applies to consumer spans. + /// + public static class MessagingRocketmqConsumptionModelValues + { + /// + /// Clustering consumption model. + /// + public const string Clustering = "clustering"; + + /// + /// Broadcasting consumption model. + /// + public const string Broadcasting = "broadcasting"; + } + + /// + /// Type of message. + /// + public static class MessagingRocketmqMessageTypeValues + { + /// + /// Normal message. + /// + public const string Normal = "normal"; + + /// + /// FIFO message. + /// + public const string Fifo = "fifo"; + + /// + /// Delay message. + /// + public const string Delay = "delay"; + + /// + /// Transaction message. + /// + public const string Transaction = "transaction"; + } + + /// + /// Describes the settlement type. + /// + public static class MessagingServicebusDispositionStatusValues + { + /// + /// Message is completed. + /// + public const string Complete = "complete"; + + /// + /// Message is abandoned. + /// + public const string Abandon = "abandon"; + + /// + /// Message is sent to dead letter queue. + /// + public const string DeadLetter = "dead_letter"; + + /// + /// Message is deferred. + /// + public const string Defer = "defer"; + } + + /// + /// An identifier for the messaging system being used. See below for a list of well-known identifiers. + /// + public static class MessagingSystemValues + { + /// + /// Apache ActiveMQ. + /// + public const string Activemq = "activemq"; + + /// + /// Amazon Simple Queue Service (SQS). + /// + public const string AwsSqs = "aws_sqs"; + + /// + /// Azure Event Grid. + /// + public const string Eventgrid = "eventgrid"; + + /// + /// Azure Event Hubs. + /// + public const string Eventhubs = "eventhubs"; + + /// + /// Azure Service Bus. + /// + public const string Servicebus = "servicebus"; + + /// + /// Google Cloud Pub/Sub. + /// + public const string GcpPubsub = "gcp_pubsub"; + + /// + /// Java Message Service. + /// + public const string Jms = "jms"; + + /// + /// Apache Kafka. + /// + public const string Kafka = "kafka"; + + /// + /// RabbitMQ. + /// + public const string Rabbitmq = "rabbitmq"; + + /// + /// Apache RocketMQ. + /// + public const string Rocketmq = "rocketmq"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs new file mode 100644 index 0000000000..70ea82c16e --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs @@ -0,0 +1,146 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class NetAttributes +{ + /// + /// Deprecated, use server.address. + /// + [Obsolete("Replaced by `server.address`")] + public const string AttributeNetHostName = "net.host.name"; + + /// + /// Deprecated, use server.port. + /// + [Obsolete("Replaced by `server.port`")] + public const string AttributeNetHostPort = "net.host.port"; + + /// + /// Deprecated, use server.address on client spans and client.address on server spans. + /// + [Obsolete("Replaced by `server.address` on client spans and `client.address` on server spans")] + public const string AttributeNetPeerName = "net.peer.name"; + + /// + /// Deprecated, use server.port on client spans and client.port on server spans. + /// + [Obsolete("Replaced by `server.port` on client spans and `client.port` on server spans")] + public const string AttributeNetPeerPort = "net.peer.port"; + + /// + /// Deprecated, use network.protocol.name. + /// + [Obsolete("Replaced by `network.protocol.name`")] + public const string AttributeNetProtocolName = "net.protocol.name"; + + /// + /// Deprecated, use network.protocol.version. + /// + [Obsolete("Replaced by `network.protocol.version`")] + public const string AttributeNetProtocolVersion = "net.protocol.version"; + + /// + /// Deprecated, use network.transport and network.type. + /// + [Obsolete("Split to `network.transport` and `network.type`")] + public const string AttributeNetSockFamily = "net.sock.family"; + + /// + /// Deprecated, use network.local.address. + /// + [Obsolete("Replaced by `network.local.address`")] + public const string AttributeNetSockHostAddr = "net.sock.host.addr"; + + /// + /// Deprecated, use network.local.port. + /// + [Obsolete("Replaced by `network.local.port`")] + public const string AttributeNetSockHostPort = "net.sock.host.port"; + + /// + /// Deprecated, use network.peer.address. + /// + [Obsolete("Replaced by `network.peer.address`")] + public const string AttributeNetSockPeerAddr = "net.sock.peer.addr"; + + /// + /// Deprecated, no replacement at this time. + /// + [Obsolete("Removed")] + public const string AttributeNetSockPeerName = "net.sock.peer.name"; + + /// + /// Deprecated, use network.peer.port. + /// + [Obsolete("Replaced by `network.peer.port`")] + public const string AttributeNetSockPeerPort = "net.sock.peer.port"; + + /// + /// Deprecated, use network.transport. + /// + [Obsolete("Replaced by `network.transport`")] + public const string AttributeNetTransport = "net.transport"; + + /// + /// Deprecated, use network.transport and network.type. + /// + public static class NetSockFamilyValues + { + /// + /// IPv4 address. + /// + public const string Inet = "inet"; + + /// + /// IPv6 address. + /// + public const string Inet6 = "inet6"; + + /// + /// Unix domain socket path. + /// + public const string Unix = "unix"; + } + + /// + /// Deprecated, use network.transport. + /// + public static class NetTransportValues + { + /// + /// ip_tcp. + /// + public const string IpTcp = "ip_tcp"; + + /// + /// ip_udp. + /// + public const string IpUdp = "ip_udp"; + + /// + /// Named or anonymous pipe. + /// + public const string Pipe = "pipe"; + + /// + /// In-process communication. + /// + public const string Inproc = "inproc"; + + /// + /// Something else (non IP-based). + /// + public const string Other = "other"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs new file mode 100644 index 0000000000..77e6914a6c --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs @@ -0,0 +1,305 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class NetworkAttributes +{ + /// + /// The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + /// + public const string AttributeNetworkCarrierIcc = "network.carrier.icc"; + + /// + /// The mobile carrier country code. + /// + public const string AttributeNetworkCarrierMcc = "network.carrier.mcc"; + + /// + /// The mobile carrier network code. + /// + public const string AttributeNetworkCarrierMnc = "network.carrier.mnc"; + + /// + /// The name of the mobile carrier. + /// + public const string AttributeNetworkCarrierName = "network.carrier.name"; + + /// + /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. + /// + public const string AttributeNetworkConnectionSubtype = "network.connection.subtype"; + + /// + /// The internet connection type. + /// + public const string AttributeNetworkConnectionType = "network.connection.type"; + + /// + /// The network IO operation direction. + /// + public const string AttributeNetworkIoDirection = "network.io.direction"; + + /// + /// Local address of the network connection - IP address or Unix domain socket name. + /// + public const string AttributeNetworkLocalAddress = "network.local.address"; + + /// + /// Local port number of the network connection. + /// + public const string AttributeNetworkLocalPort = "network.local.port"; + + /// + /// Peer address of the network connection - IP address or Unix domain socket name. + /// + public const string AttributeNetworkPeerAddress = "network.peer.address"; + + /// + /// Peer port number of the network connection. + /// + public const string AttributeNetworkPeerPort = "network.peer.port"; + + /// + /// OSI application layer or non-OSI equivalent. + /// + /// + /// The value SHOULD be normalized to lowercase. + /// + public const string AttributeNetworkProtocolName = "network.protocol.name"; + + /// + /// The actual version of the protocol used for network communication. + /// + /// + /// If protocol version is subject to negotiation (for example using ALPN), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. + /// + public const string AttributeNetworkProtocolVersion = "network.protocol.version"; + + /// + /// OSI transport layer or inter-process communication method. + /// + /// + /// The value SHOULD be normalized to lowercase.Consider always setting the transport when setting a port number, since + /// a port number is ambiguous without knowing the transport. For example + /// different processes could be listening on TCP port 12345 and UDP port 12345. + /// + public const string AttributeNetworkTransport = "network.transport"; + + /// + /// OSI network layer or non-OSI equivalent. + /// + /// + /// The value SHOULD be normalized to lowercase. + /// + public const string AttributeNetworkType = "network.type"; + + /// + /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. + /// + public static class NetworkConnectionSubtypeValues + { + /// + /// GPRS. + /// + public const string Gprs = "gprs"; + + /// + /// EDGE. + /// + public const string Edge = "edge"; + + /// + /// UMTS. + /// + public const string Umts = "umts"; + + /// + /// CDMA. + /// + public const string Cdma = "cdma"; + + /// + /// EVDO Rel. 0. + /// + public const string Evdo0 = "evdo_0"; + + /// + /// EVDO Rev. A. + /// + public const string EvdoA = "evdo_a"; + + /// + /// CDMA2000 1XRTT. + /// + public const string Cdma20001xrtt = "cdma2000_1xrtt"; + + /// + /// HSDPA. + /// + public const string Hsdpa = "hsdpa"; + + /// + /// HSUPA. + /// + public const string Hsupa = "hsupa"; + + /// + /// HSPA. + /// + public const string Hspa = "hspa"; + + /// + /// IDEN. + /// + public const string Iden = "iden"; + + /// + /// EVDO Rev. B. + /// + public const string EvdoB = "evdo_b"; + + /// + /// LTE. + /// + public const string Lte = "lte"; + + /// + /// EHRPD. + /// + public const string Ehrpd = "ehrpd"; + + /// + /// HSPAP. + /// + public const string Hspap = "hspap"; + + /// + /// GSM. + /// + public const string Gsm = "gsm"; + + /// + /// TD-SCDMA. + /// + public const string TdScdma = "td_scdma"; + + /// + /// IWLAN. + /// + public const string Iwlan = "iwlan"; + + /// + /// 5G NR (New Radio). + /// + public const string Nr = "nr"; + + /// + /// 5G NRNSA (New Radio Non-Standalone). + /// + public const string Nrnsa = "nrnsa"; + + /// + /// LTE CA. + /// + public const string LteCa = "lte_ca"; + } + + /// + /// The internet connection type. + /// + public static class NetworkConnectionTypeValues + { + /// + /// wifi. + /// + public const string Wifi = "wifi"; + + /// + /// wired. + /// + public const string Wired = "wired"; + + /// + /// cell. + /// + public const string Cell = "cell"; + + /// + /// unavailable. + /// + public const string Unavailable = "unavailable"; + + /// + /// unknown. + /// + public const string Unknown = "unknown"; + } + + /// + /// The network IO operation direction. + /// + public static class NetworkIoDirectionValues + { + /// + /// transmit. + /// + public const string Transmit = "transmit"; + + /// + /// receive. + /// + public const string Receive = "receive"; + } + + /// + /// OSI transport layer or inter-process communication method. + /// + public static class NetworkTransportValues + { + /// + /// TCP. + /// + public const string Tcp = "tcp"; + + /// + /// UDP. + /// + public const string Udp = "udp"; + + /// + /// Named or anonymous pipe. + /// + public const string Pipe = "pipe"; + + /// + /// Unix domain socket. + /// + public const string Unix = "unix"; + } + + /// + /// OSI network layer or non-OSI equivalent. + /// + public static class NetworkTypeValues + { + /// + /// IPv4. + /// + public const string Ipv4 = "ipv4"; + + /// + /// IPv6. + /// + public const string Ipv6 = "ipv6"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs new file mode 100644 index 0000000000..7168299a0e --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs @@ -0,0 +1,25 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class OciAttributes +{ + /// + /// The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. + /// + /// + /// Follows OCI Image Manifest Specification, and specifically the Digest property. + /// An example can be found in Example Image Manifest. + /// + public const string AttributeOciManifestDigest = "oci.manifest.digest"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs new file mode 100644 index 0000000000..fbad4c94c8 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class OpentracingAttributes +{ + /// + /// Parent-child Reference type. + /// + /// + /// The causal relationship between a child Span and a parent Span. + /// + public const string AttributeOpentracingRefType = "opentracing.ref_type"; + + /// + /// Parent-child Reference type. + /// + public static class OpentracingRefTypeValues + { + /// + /// The parent Span depends on the child Span in some capacity. + /// + public const string ChildOf = "child_of"; + + /// + /// The parent Span doesn't depend in any way on the result of the child Span. + /// + public const string FollowsFrom = "follows_from"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs new file mode 100644 index 0000000000..fd9e81d555 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs @@ -0,0 +1,102 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class OsAttributes +{ + /// + /// Unique identifier for a particular build or compilation of the operating system. + /// + public const string AttributeOsBuildId = "os.build_id"; + + /// + /// Human readable (not intended to be parsed) OS version information, like e.g. reported by ver or lsb_release -a commands. + /// + public const string AttributeOsDescription = "os.description"; + + /// + /// Human readable operating system name. + /// + public const string AttributeOsName = "os.name"; + + /// + /// The operating system type. + /// + public const string AttributeOsType = "os.type"; + + /// + /// The version string of the operating system as defined in Version Attributes. + /// + public const string AttributeOsVersion = "os.version"; + + /// + /// The operating system type. + /// + public static class OsTypeValues + { + /// + /// Microsoft Windows. + /// + public const string Windows = "windows"; + + /// + /// Linux. + /// + public const string Linux = "linux"; + + /// + /// Apple Darwin. + /// + public const string Darwin = "darwin"; + + /// + /// FreeBSD. + /// + public const string Freebsd = "freebsd"; + + /// + /// NetBSD. + /// + public const string Netbsd = "netbsd"; + + /// + /// OpenBSD. + /// + public const string Openbsd = "openbsd"; + + /// + /// DragonFly BSD. + /// + public const string Dragonflybsd = "dragonflybsd"; + + /// + /// HP-UX (Hewlett Packard Unix). + /// + public const string Hpux = "hpux"; + + /// + /// AIX (Advanced Interactive eXecutive). + /// + public const string Aix = "aix"; + + /// + /// SunOS, Oracle Solaris. + /// + public const string Solaris = "solaris"; + + /// + /// IBM z/OS. + /// + public const string ZOs = "z_os"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs new file mode 100644 index 0000000000..03c76f69ae --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs @@ -0,0 +1,64 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class OtelAttributes +{ + /// + /// None. + /// + [Obsolete("use the `otel.scope.name` attribute")] + public const string AttributeOtelLibraryName = "otel.library.name"; + + /// + /// None. + /// + [Obsolete("use the `otel.scope.version` attribute")] + public const string AttributeOtelLibraryVersion = "otel.library.version"; + + /// + /// The name of the instrumentation scope - (InstrumentationScope.Name in OTLP). + /// + public const string AttributeOtelScopeName = "otel.scope.name"; + + /// + /// The version of the instrumentation scope - (InstrumentationScope.Version in OTLP). + /// + public const string AttributeOtelScopeVersion = "otel.scope.version"; + + /// + /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + /// + public const string AttributeOtelStatusCode = "otel.status_code"; + + /// + /// Description of the Status if it has a value, otherwise not set. + /// + public const string AttributeOtelStatusDescription = "otel.status_description"; + + /// + /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + /// + public static class OtelStatusCodeValues + { + /// + /// The operation has been validated by an Application developer or Operator to have completed successfully. + /// + public const string Ok = "OK"; + + /// + /// The operation contains an error. + /// + public const string Error = "ERROR"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs new file mode 100644 index 0000000000..e489e2a8e0 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class OtherAttributes +{ + /// + /// The state of a connection in the pool. + /// + public const string AttributeState = "state"; + + /// + /// The state of a connection in the pool. + /// + public static class StateValues + { + /// + /// idle. + /// + public const string Idle = "idle"; + + /// + /// used. + /// + public const string Used = "used"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs new file mode 100644 index 0000000000..d186722a12 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class PeerAttributes +{ + /// + /// The service.name of the remote service. SHOULD be equal to the actual service.name resource attribute of the remote service if any. + /// + public const string AttributePeerService = "peer.service"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs new file mode 100644 index 0000000000..3e8f9d2dd6 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class PoolAttributes +{ + /// + /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of server.address and server.port attributes formatted as server.address:server.port. + /// + public const string AttributePoolName = "pool.name"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs new file mode 100644 index 0000000000..4c9870fdd6 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs @@ -0,0 +1,139 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ProcessAttributes +{ + /// + /// The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in proc/[pid]/cmdline. On Windows, can be set to the first parameter extracted from GetCommandLineW. + /// + public const string AttributeProcessCommand = "process.command"; + + /// + /// All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from proc/[pid]/cmdline. For libc-based executables, this would be the full argv vector passed to main. + /// + public const string AttributeProcessCommandArgs = "process.command_args"; + + /// + /// The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of GetCommandLineW. Do not set this if you have to assemble it just for monitoring; use process.command_args instead. + /// + public const string AttributeProcessCommandLine = "process.command_line"; + + /// + /// Specifies whether the context switches for this data point were voluntary or involuntary. + /// + public const string AttributeProcessContextSwitchType = "process.context_switch_type"; + + /// + /// The CPU state for this data point. A process SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// + public const string AttributeProcessCpuState = "process.cpu.state"; + + /// + /// The name of the process executable. On Linux based systems, can be set to the Name in proc/[pid]/status. On Windows, can be set to the base name of GetProcessImageFileNameW. + /// + public const string AttributeProcessExecutableName = "process.executable.name"; + + /// + /// The full path to the process executable. On Linux based systems, can be set to the target of proc/[pid]/exe. On Windows, can be set to the result of GetProcessImageFileNameW. + /// + public const string AttributeProcessExecutablePath = "process.executable.path"; + + /// + /// The username of the user that owns the process. + /// + public const string AttributeProcessOwner = "process.owner"; + + /// + /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults. + /// + public const string AttributeProcessPagingFaultType = "process.paging.fault_type"; + + /// + /// Parent Process identifier (PPID). + /// + public const string AttributeProcessParentPid = "process.parent_pid"; + + /// + /// Process identifier (PID). + /// + public const string AttributeProcessPid = "process.pid"; + + /// + /// An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. + /// + public const string AttributeProcessRuntimeDescription = "process.runtime.description"; + + /// + /// The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. + /// + public const string AttributeProcessRuntimeName = "process.runtime.name"; + + /// + /// The version of the runtime of this process, as returned by the runtime without modification. + /// + public const string AttributeProcessRuntimeVersion = "process.runtime.version"; + + /// + /// Specifies whether the context switches for this data point were voluntary or involuntary. + /// + public static class ProcessContextSwitchTypeValues + { + /// + /// voluntary. + /// + public const string Voluntary = "voluntary"; + + /// + /// involuntary. + /// + public const string Involuntary = "involuntary"; + } + + /// + /// The CPU state for this data point. A process SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// + public static class ProcessCpuStateValues + { + /// + /// system. + /// + public const string System = "system"; + + /// + /// user. + /// + public const string User = "user"; + + /// + /// wait. + /// + public const string Wait = "wait"; + } + + /// + /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults. + /// + public static class ProcessPagingFaultTypeValues + { + /// + /// major. + /// + public const string Major = "major"; + + /// + /// minor. + /// + public const string Minor = "minor"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs new file mode 100644 index 0000000000..40f96ac2f9 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs @@ -0,0 +1,307 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class RpcAttributes +{ + /// + /// The error codes of the Connect request. Error codes are always string values. + /// + public const string AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code"; + + /// + /// Connect request metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values. + /// + /// + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// + public const string AttributeRpcConnectRpcRequestMetadata = "rpc.connect_rpc.request.metadata"; + + /// + /// Connect response metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values. + /// + /// + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// + public const string AttributeRpcConnectRpcResponseMetadata = "rpc.connect_rpc.response.metadata"; + + /// + /// gRPC request metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values. + /// + /// + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// + public const string AttributeRpcGrpcRequestMetadata = "rpc.grpc.request.metadata"; + + /// + /// gRPC response metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values. + /// + /// + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// + public const string AttributeRpcGrpcResponseMetadata = "rpc.grpc.response.metadata"; + + /// + /// The numeric status code of the gRPC request. + /// + public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; + + /// + /// error.code property of response if it is an error response. + /// + public const string AttributeRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code"; + + /// + /// error.message property of response if it is an error response. + /// + public const string AttributeRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message"; + + /// + /// id property of request or response. Since protocol allows id to be int, string, null or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of null value. Omit entirely if this is a notification. + /// + public const string AttributeRpcJsonrpcRequestId = "rpc.jsonrpc.request_id"; + + /// + /// Protocol version as in jsonrpc property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. + /// + public const string AttributeRpcJsonrpcVersion = "rpc.jsonrpc.version"; + + /// + /// The name of the (logical) method being called, must be equal to the $method part in the span name. + /// + /// + /// This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The code.function attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + /// + public const string AttributeRpcMethod = "rpc.method"; + + /// + /// The full (logical) name of the service being called, including its package name, if applicable. + /// + /// + /// This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The code.namespace attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + /// + public const string AttributeRpcService = "rpc.service"; + + /// + /// A string identifying the remoting system. See below for a list of well-known identifiers. + /// + public const string AttributeRpcSystem = "rpc.system"; + + /// + /// The error codes of the Connect request. Error codes are always string values. + /// + public static class RpcConnectRpcErrorCodeValues + { + /// + /// cancelled. + /// + public const string Cancelled = "cancelled"; + + /// + /// unknown. + /// + public const string Unknown = "unknown"; + + /// + /// invalid_argument. + /// + public const string InvalidArgument = "invalid_argument"; + + /// + /// deadline_exceeded. + /// + public const string DeadlineExceeded = "deadline_exceeded"; + + /// + /// not_found. + /// + public const string NotFound = "not_found"; + + /// + /// already_exists. + /// + public const string AlreadyExists = "already_exists"; + + /// + /// permission_denied. + /// + public const string PermissionDenied = "permission_denied"; + + /// + /// resource_exhausted. + /// + public const string ResourceExhausted = "resource_exhausted"; + + /// + /// failed_precondition. + /// + public const string FailedPrecondition = "failed_precondition"; + + /// + /// aborted. + /// + public const string Aborted = "aborted"; + + /// + /// out_of_range. + /// + public const string OutOfRange = "out_of_range"; + + /// + /// unimplemented. + /// + public const string Unimplemented = "unimplemented"; + + /// + /// internal. + /// + public const string Internal = "internal"; + + /// + /// unavailable. + /// + public const string Unavailable = "unavailable"; + + /// + /// data_loss. + /// + public const string DataLoss = "data_loss"; + + /// + /// unauthenticated. + /// + public const string Unauthenticated = "unauthenticated"; + } + + /// + /// The numeric status code of the gRPC request. + /// + public static class RpcGrpcStatusCodeValues + { + /// + /// OK. + /// + public const int Ok = 0; + + /// + /// CANCELLED. + /// + public const int Cancelled = 1; + + /// + /// UNKNOWN. + /// + public const int Unknown = 2; + + /// + /// INVALID_ARGUMENT. + /// + public const int InvalidArgument = 3; + + /// + /// DEADLINE_EXCEEDED. + /// + public const int DeadlineExceeded = 4; + + /// + /// NOT_FOUND. + /// + public const int NotFound = 5; + + /// + /// ALREADY_EXISTS. + /// + public const int AlreadyExists = 6; + + /// + /// PERMISSION_DENIED. + /// + public const int PermissionDenied = 7; + + /// + /// RESOURCE_EXHAUSTED. + /// + public const int ResourceExhausted = 8; + + /// + /// FAILED_PRECONDITION. + /// + public const int FailedPrecondition = 9; + + /// + /// ABORTED. + /// + public const int Aborted = 10; + + /// + /// OUT_OF_RANGE. + /// + public const int OutOfRange = 11; + + /// + /// UNIMPLEMENTED. + /// + public const int Unimplemented = 12; + + /// + /// INTERNAL. + /// + public const int Internal = 13; + + /// + /// UNAVAILABLE. + /// + public const int Unavailable = 14; + + /// + /// DATA_LOSS. + /// + public const int DataLoss = 15; + + /// + /// UNAUTHENTICATED. + /// + public const int Unauthenticated = 16; + } + + /// + /// A string identifying the remoting system. See below for a list of well-known identifiers. + /// + public static class RpcSystemValues + { + /// + /// gRPC. + /// + public const string Grpc = "grpc"; + + /// + /// Java RMI. + /// + public const string JavaRmi = "java_rmi"; + + /// + /// .NET WCF. + /// + public const string DotnetWcf = "dotnet_wcf"; + + /// + /// Apache Dubbo. + /// + public const string ApacheDubbo = "apache_dubbo"; + + /// + /// Connect RPC. + /// + public const string ConnectRpc = "connect_rpc"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs new file mode 100644 index 0000000000..b31282b237 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ServerAttributes +{ + /// + /// Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// + /// + /// When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it&#39;s available. + /// + public const string AttributeServerAddress = "server.address"; + + /// + /// Server port number. + /// + /// + /// When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it&#39;s available. + /// + public const string AttributeServerPort = "server.port"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs new file mode 100644 index 0000000000..b2dfc48164 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs @@ -0,0 +1,62 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ServiceAttributes +{ + /// + /// The string ID of the service instance. + /// + /// + /// MUST be unique for each instance of the same service.namespace,service.name pair (in other words + /// service.namespace,service.name,service.instance.id triplet MUST be globally unique). The ID helps to + /// distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled + /// service).Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 RFC + /// 4122 UUID, but are free to use an inherent unique ID as the source of + /// this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and + /// SHOULD use the following UUID as the namespace: 4d63009a-8d0f-11ee-aad7-4c796ed8e320.UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is + /// needed. Similar to what can be seen in the man page for the + /// /etc/machine-id file, the underlying + /// data, such as pod name and namespace should be treated as confidential, being the user&#39;s choice to expose it + /// or not via another resource attribute.For applications running behind an application server (like unicorn), we do not recommend using one identifier + /// for all processes participating in the application. Instead, it&#39;s recommended each division (e.g. a worker + /// thread in unicorn) to have its own instance.id.It&#39;s not recommended for a Collector to set service.instance.id if it can&#39;t unambiguously determine the + /// service instance that is generating that telemetry. For instance, creating an UUID based on pod.name will + /// likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. + /// However, Collectors can set the service.instance.id if they can unambiguously determine the service instance + /// for that telemetry. This is typically the case for scraping receivers, as they know the target address and + /// port. + /// + public const string AttributeServiceInstanceId = "service.instance.id"; + + /// + /// Logical name of the service. + /// + /// + /// MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to unknown_service: concatenated with process.executable.name, e.g. unknown_service:bash. If process.executable.name is not available, the value MUST be set to unknown_service. + /// + public const string AttributeServiceName = "service.name"; + + /// + /// A namespace for service.name. + /// + /// + /// A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. service.name is expected to be unique within the same namespace. If service.namespace is not specified in the Resource then service.name is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. + /// + public const string AttributeServiceNamespace = "service.namespace"; + + /// + /// The version string of the service API or implementation. The format is not defined by these conventions. + /// + public const string AttributeServiceVersion = "service.version"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs new file mode 100644 index 0000000000..7f6ff71fdb --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class SessionAttributes +{ + /// + /// A unique id to identify a session. + /// + public const string AttributeSessionId = "session.id"; + + /// + /// The previous session.id for this user, when known. + /// + public const string AttributeSessionPreviousId = "session.previous_id"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs new file mode 100644 index 0000000000..dd937d7004 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class SignalrAttributes +{ + /// + /// SignalR HTTP connection closure status. + /// + public const string AttributeSignalrConnectionStatus = "signalr.connection.status"; + + /// + /// SignalR transport type. + /// + public const string AttributeSignalrTransport = "signalr.transport"; + + /// + /// SignalR HTTP connection closure status. + /// + public static class SignalrConnectionStatusValues + { + /// + /// The connection was closed normally. + /// + public const string NormalClosure = "normal_closure"; + + /// + /// The connection was closed due to a timeout. + /// + public const string Timeout = "timeout"; + + /// + /// The connection was closed because the app is shutting down. + /// + public const string AppShutdown = "app_shutdown"; + } + + /// + /// SignalR transport type. + /// + public static class SignalrTransportValues + { + /// + /// ServerSentEvents protocol. + /// + public const string ServerSentEvents = "server_sent_events"; + + /// + /// LongPolling protocol. + /// + public const string LongPolling = "long_polling"; + + /// + /// WebSockets protocol. + /// + public const string WebSockets = "web_sockets"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs new file mode 100644 index 0000000000..5c24ee0440 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class SourceAttributes +{ + /// + /// Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// + /// + /// When observed from the destination side, and when communicating through an intermediary, source.address SHOULD represent the source address behind any intermediaries, for example proxies, if it&#39;s available. + /// + public const string AttributeSourceAddress = "source.address"; + + /// + /// Source port number. + /// + public const string AttributeSourcePort = "source.port"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs new file mode 100644 index 0000000000..3270d58b22 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs @@ -0,0 +1,382 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class SystemAttributes +{ + /// + /// The logical CPU number [0..n-1]. + /// + public const string AttributeSystemCpuLogicalNumber = "system.cpu.logical_number"; + + /// + /// The CPU state for this data point. A system's CPU SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// + public const string AttributeSystemCpuState = "system.cpu.state"; + + /// + /// The device identifier. + /// + public const string AttributeSystemDevice = "system.device"; + + /// + /// The filesystem mode. + /// + public const string AttributeSystemFilesystemMode = "system.filesystem.mode"; + + /// + /// The filesystem mount path. + /// + public const string AttributeSystemFilesystemMountpoint = "system.filesystem.mountpoint"; + + /// + /// The filesystem state. + /// + public const string AttributeSystemFilesystemState = "system.filesystem.state"; + + /// + /// The filesystem type. + /// + public const string AttributeSystemFilesystemType = "system.filesystem.type"; + + /// + /// The memory state. + /// + public const string AttributeSystemMemoryState = "system.memory.state"; + + /// + /// A stateless protocol MUST NOT set this attribute. + /// + public const string AttributeSystemNetworkState = "system.network.state"; + + /// + /// The paging access direction. + /// + public const string AttributeSystemPagingDirection = "system.paging.direction"; + + /// + /// The memory paging state. + /// + public const string AttributeSystemPagingState = "system.paging.state"; + + /// + /// The memory paging type. + /// + public const string AttributeSystemPagingType = "system.paging.type"; + + /// + /// The process state, e.g., Linux Process State Codes. + /// + public const string AttributeSystemProcessStatus = "system.process.status"; + + /// + /// Deprecated, use system.process.status instead. + /// + [Obsolete("Replaced by `system.process.status`")] + public const string AttributeSystemProcessesStatus = "system.processes.status"; + + /// + /// The CPU state for this data point. A system's CPU SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// + public static class SystemCpuStateValues + { + /// + /// user. + /// + public const string User = "user"; + + /// + /// system. + /// + public const string System = "system"; + + /// + /// nice. + /// + public const string Nice = "nice"; + + /// + /// idle. + /// + public const string Idle = "idle"; + + /// + /// iowait. + /// + public const string Iowait = "iowait"; + + /// + /// interrupt. + /// + public const string Interrupt = "interrupt"; + + /// + /// steal. + /// + public const string Steal = "steal"; + } + + /// + /// The filesystem state. + /// + public static class SystemFilesystemStateValues + { + /// + /// used. + /// + public const string Used = "used"; + + /// + /// free. + /// + public const string Free = "free"; + + /// + /// reserved. + /// + public const string Reserved = "reserved"; + } + + /// + /// The filesystem type. + /// + public static class SystemFilesystemTypeValues + { + /// + /// fat32. + /// + public const string Fat32 = "fat32"; + + /// + /// exfat. + /// + public const string Exfat = "exfat"; + + /// + /// ntfs. + /// + public const string Ntfs = "ntfs"; + + /// + /// refs. + /// + public const string Refs = "refs"; + + /// + /// hfsplus. + /// + public const string Hfsplus = "hfsplus"; + + /// + /// ext4. + /// + public const string Ext4 = "ext4"; + } + + /// + /// The memory state. + /// + public static class SystemMemoryStateValues + { + /// + /// used. + /// + public const string Used = "used"; + + /// + /// free. + /// + public const string Free = "free"; + + /// + /// shared. + /// + public const string Shared = "shared"; + + /// + /// buffers. + /// + public const string Buffers = "buffers"; + + /// + /// cached. + /// + public const string Cached = "cached"; + } + + /// + /// A stateless protocol MUST NOT set this attribute. + /// + public static class SystemNetworkStateValues + { + /// + /// close. + /// + public const string Close = "close"; + + /// + /// close_wait. + /// + public const string CloseWait = "close_wait"; + + /// + /// closing. + /// + public const string Closing = "closing"; + + /// + /// delete. + /// + public const string Delete = "delete"; + + /// + /// established. + /// + public const string Established = "established"; + + /// + /// fin_wait_1. + /// + public const string FinWait1 = "fin_wait_1"; + + /// + /// fin_wait_2. + /// + public const string FinWait2 = "fin_wait_2"; + + /// + /// last_ack. + /// + public const string LastAck = "last_ack"; + + /// + /// listen. + /// + public const string Listen = "listen"; + + /// + /// syn_recv. + /// + public const string SynRecv = "syn_recv"; + + /// + /// syn_sent. + /// + public const string SynSent = "syn_sent"; + + /// + /// time_wait. + /// + public const string TimeWait = "time_wait"; + } + + /// + /// The paging access direction. + /// + public static class SystemPagingDirectionValues + { + /// + /// in. + /// + public const string In = "in"; + + /// + /// out. + /// + public const string Out = "out"; + } + + /// + /// The memory paging state. + /// + public static class SystemPagingStateValues + { + /// + /// used. + /// + public const string Used = "used"; + + /// + /// free. + /// + public const string Free = "free"; + } + + /// + /// The memory paging type. + /// + public static class SystemPagingTypeValues + { + /// + /// major. + /// + public const string Major = "major"; + + /// + /// minor. + /// + public const string Minor = "minor"; + } + + /// + /// The process state, e.g., Linux Process State Codes. + /// + public static class SystemProcessStatusValues + { + /// + /// running. + /// + public const string Running = "running"; + + /// + /// sleeping. + /// + public const string Sleeping = "sleeping"; + + /// + /// stopped. + /// + public const string Stopped = "stopped"; + + /// + /// defunct. + /// + public const string Defunct = "defunct"; + } + + /// + /// Deprecated, use system.process.status instead. + /// + public static class SystemProcessesStatusValues + { + /// + /// running. + /// + public const string Running = "running"; + + /// + /// sleeping. + /// + public const string Sleeping = "sleeping"; + + /// + /// stopped. + /// + public const string Stopped = "stopped"; + + /// + /// defunct. + /// + public const string Defunct = "defunct"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs new file mode 100644 index 0000000000..f08ca9fd85 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs @@ -0,0 +1,119 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class TelemetryAttributes +{ + /// + /// The name of the auto instrumentation agent or distribution, if used. + /// + /// + /// Official auto instrumentation agents and distributions SHOULD set the telemetry.distro.name attribute to + /// a string starting with opentelemetry-, e.g. opentelemetry-java-instrumentation. + /// + public const string AttributeTelemetryDistroName = "telemetry.distro.name"; + + /// + /// The version string of the auto instrumentation agent or distribution, if used. + /// + public const string AttributeTelemetryDistroVersion = "telemetry.distro.version"; + + /// + /// The language of the telemetry SDK. + /// + public const string AttributeTelemetrySdkLanguage = "telemetry.sdk.language"; + + /// + /// The name of the telemetry SDK as defined above. + /// + /// + /// The OpenTelemetry SDK MUST set the telemetry.sdk.name attribute to opentelemetry. + /// If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the + /// telemetry.sdk.name attribute to the fully-qualified class or module name of this SDK&#39;s main entry point + /// or another suitable identifier depending on the language. + /// The identifier opentelemetry is reserved and MUST NOT be used in this case. + /// All custom identifiers SHOULD be stable across different versions of an implementation. + /// + public const string AttributeTelemetrySdkName = "telemetry.sdk.name"; + + /// + /// The version string of the telemetry SDK. + /// + public const string AttributeTelemetrySdkVersion = "telemetry.sdk.version"; + + /// + /// The language of the telemetry SDK. + /// + public static class TelemetrySdkLanguageValues + { + /// + /// cpp. + /// + public const string Cpp = "cpp"; + + /// + /// dotnet. + /// + public const string Dotnet = "dotnet"; + + /// + /// erlang. + /// + public const string Erlang = "erlang"; + + /// + /// go. + /// + public const string Go = "go"; + + /// + /// java. + /// + public const string Java = "java"; + + /// + /// nodejs. + /// + public const string Nodejs = "nodejs"; + + /// + /// php. + /// + public const string Php = "php"; + + /// + /// python. + /// + public const string Python = "python"; + + /// + /// ruby. + /// + public const string Ruby = "ruby"; + + /// + /// rust. + /// + public const string Rust = "rust"; + + /// + /// swift. + /// + public const string Swift = "swift"; + + /// + /// webjs. + /// + public const string Webjs = "webjs"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs new file mode 100644 index 0000000000..82eb2c18ee --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ThreadAttributes +{ + /// + /// Current "managed" thread ID (as opposed to OS thread ID). + /// + public const string AttributeThreadId = "thread.id"; + + /// + /// Current thread name. + /// + public const string AttributeThreadName = "thread.name"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs new file mode 100644 index 0000000000..fbcac49fea --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs @@ -0,0 +1,180 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class TlsAttributes +{ + /// + /// String indicating the cipher used during the current connection. + /// + /// + /// The values allowed for tls.cipher MUST be one of the Descriptions of the registered TLS Cipher Suits. + /// + public const string AttributeTlsCipher = "tls.cipher"; + + /// + /// PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of client.certificate_chain since this value also exists in that list. + /// + public const string AttributeTlsClientCertificate = "tls.client.certificate"; + + /// + /// Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of client.certificate since that value should be the first certificate in the chain. + /// + public const string AttributeTlsClientCertificateChain = "tls.client.certificate_chain"; + + /// + /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// + public const string AttributeTlsClientHashMd5 = "tls.client.hash.md5"; + + /// + /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// + public const string AttributeTlsClientHashSha1 = "tls.client.hash.sha1"; + + /// + /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// + public const string AttributeTlsClientHashSha256 = "tls.client.hash.sha256"; + + /// + /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client. + /// + public const string AttributeTlsClientIssuer = "tls.client.issuer"; + + /// + /// A hash that identifies clients based on how they perform an SSL/TLS handshake. + /// + public const string AttributeTlsClientJa3 = "tls.client.ja3"; + + /// + /// Date/Time indicating when client certificate is no longer considered valid. + /// + public const string AttributeTlsClientNotAfter = "tls.client.not_after"; + + /// + /// Date/Time indicating when client certificate is first considered valid. + /// + public const string AttributeTlsClientNotBefore = "tls.client.not_before"; + + /// + /// Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. + /// + public const string AttributeTlsClientServerName = "tls.client.server_name"; + + /// + /// Distinguished name of subject of the x.509 certificate presented by the client. + /// + public const string AttributeTlsClientSubject = "tls.client.subject"; + + /// + /// Array of ciphers offered by the client during the client hello. + /// + public const string AttributeTlsClientSupportedCiphers = "tls.client.supported_ciphers"; + + /// + /// String indicating the curve used for the given cipher, when applicable. + /// + public const string AttributeTlsCurve = "tls.curve"; + + /// + /// Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. + /// + public const string AttributeTlsEstablished = "tls.established"; + + /// + /// String indicating the protocol being tunneled. Per the values in the IANA registry, this string should be lower case. + /// + public const string AttributeTlsNextProtocol = "tls.next_protocol"; + + /// + /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version. + /// + public const string AttributeTlsProtocolName = "tls.protocol.name"; + + /// + /// Numeric part of the version parsed from the original string of the negotiated SSL/TLS protocol version. + /// + public const string AttributeTlsProtocolVersion = "tls.protocol.version"; + + /// + /// Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. + /// + public const string AttributeTlsResumed = "tls.resumed"; + + /// + /// PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of server.certificate_chain since this value also exists in that list. + /// + public const string AttributeTlsServerCertificate = "tls.server.certificate"; + + /// + /// Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of server.certificate since that value should be the first certificate in the chain. + /// + public const string AttributeTlsServerCertificateChain = "tls.server.certificate_chain"; + + /// + /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// + public const string AttributeTlsServerHashMd5 = "tls.server.hash.md5"; + + /// + /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// + public const string AttributeTlsServerHashSha1 = "tls.server.hash.sha1"; + + /// + /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// + public const string AttributeTlsServerHashSha256 = "tls.server.hash.sha256"; + + /// + /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client. + /// + public const string AttributeTlsServerIssuer = "tls.server.issuer"; + + /// + /// A hash that identifies servers based on how they perform an SSL/TLS handshake. + /// + public const string AttributeTlsServerJa3s = "tls.server.ja3s"; + + /// + /// Date/Time indicating when server certificate is no longer considered valid. + /// + public const string AttributeTlsServerNotAfter = "tls.server.not_after"; + + /// + /// Date/Time indicating when server certificate is first considered valid. + /// + public const string AttributeTlsServerNotBefore = "tls.server.not_before"; + + /// + /// Distinguished name of subject of the x.509 certificate presented by the server. + /// + public const string AttributeTlsServerSubject = "tls.server.subject"; + + /// + /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version. + /// + public static class TlsProtocolNameValues + { + /// + /// ssl. + /// + public const string Ssl = "ssl"; + + /// + /// tls. + /// + public const string Tls = "tls"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs new file mode 100644 index 0000000000..7471d882e5 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs @@ -0,0 +1,106 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class UrlAttributes +{ + /// + /// Domain extracted from the url.full, such as "opentelemetry.io". + /// + /// + /// In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a literal IPv6 address enclosed by [ and ], the [ and ] characters should also be captured in the domain field. + /// + public const string AttributeUrlDomain = "url.domain"; + + /// + /// The file extension extracted from the url.full, excluding the leading dot. + /// + /// + /// The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions example.tar.gz, only the last one should be captured gz, not tar.gz. + /// + public const string AttributeUrlExtension = "url.extension"; + + /// + /// The URI fragment component. + /// + public const string AttributeUrlFragment = "url.fragment"; + + /// + /// Absolute URL describing a network resource according to RFC3986. + /// + /// + /// For network calls, URL usually has scheme://host[:port][path][?query][#fragment] format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. + /// url.full MUST NOT contain credentials passed via URL in form of https://username:password@www.example.com/. In such case username and password SHOULD be redacted and attribute&#39;s value SHOULD be https://REDACTED:REDACTED@www.example.com/. + /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it. + /// + public const string AttributeUrlFull = "url.full"; + + /// + /// Unmodified original URL as seen in the event source. + /// + /// + /// In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. + /// url.original might contain credentials passed via URL in form of https://username:password@www.example.com/. In such case password and username SHOULD NOT be redacted and attribute&#39;s value SHOULD remain the same. + /// + public const string AttributeUrlOriginal = "url.original"; + + /// + /// The URI path component. + /// + /// + /// Sensitive content provided in url.path SHOULD be scrubbed when instrumentations can identify it. + /// + public const string AttributeUrlPath = "url.path"; + + /// + /// Port extracted from the url.full. + /// + public const string AttributeUrlPort = "url.port"; + + /// + /// The URI query component. + /// + /// + /// Sensitive content provided in url.query SHOULD be scrubbed when instrumentations can identify it. + /// + public const string AttributeUrlQuery = "url.query"; + + /// + /// The highest registered url domain, stripped of the subdomain. + /// + /// + /// This value can be determined precisely with the public suffix list. For example, the registered domain for foo.example.com is example.com. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as co.uk. + /// + public const string AttributeUrlRegisteredDomain = "url.registered_domain"; + + /// + /// The URI scheme component identifying the used protocol. + /// + public const string AttributeUrlScheme = "url.scheme"; + + /// + /// The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. + /// + /// + /// The subdomain portion of www.east.mydomain.co.uk is east. If the domain has multiple levels of subdomain, such as sub2.sub1.example.com, the subdomain field should contain sub2.sub1, with no trailing period. + /// + public const string AttributeUrlSubdomain = "url.subdomain"; + + /// + /// The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is com. + /// + /// + /// This value can be determined precisely with the public suffix list. + /// + public const string AttributeUrlTopLevelDomain = "url.top_level_domain"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs new file mode 100644 index 0000000000..86c35643f2 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class UserAgentAttributes +{ + /// + /// Name of the user-agent extracted from original. Usually refers to the browser's name. + /// + /// + /// Example of extracting browser&#39;s name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant name SHOULD be selected. In such a scenario it should align with user_agent.version. + /// + public const string AttributeUserAgentName = "user_agent.name"; + + /// + /// Value of the HTTP User-Agent header sent by the client. + /// + public const string AttributeUserAgentOriginal = "user_agent.original"; + + /// + /// Version of the user-agent extracted from original. Usually refers to the browser's version. + /// + /// + /// Example of extracting browser&#39;s version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant version SHOULD be selected. In such a scenario it should align with user_agent.name. + /// + public const string AttributeUserAgentVersion = "user_agent.version"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs new file mode 100644 index 0000000000..1a3d5ca741 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class WebengineAttributes +{ + /// + /// Additional description of the web engine (e.g. detailed version and edition information). + /// + public const string AttributeWebengineDescription = "webengine.description"; + + /// + /// The name of the web engine. + /// + public const string AttributeWebengineName = "webengine.name"; + + /// + /// The version of the web engine. + /// + public const string AttributeWebengineVersion = "webengine.version"; +} diff --git a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md new file mode 100644 index 0000000000..49e8b99e72 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## Unreleased + +* Updated to `1.25.0` release of OpenTelemetry Semantic Conventions. + ([#1672](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1672)) + +* Moved from `https://github.com/open-telemetry/opentelemetry-dotnet/` to + `https://github.com/open-telemetry/opentelemetry-dotnet-contrib/`. diff --git a/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj b/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj new file mode 100644 index 0000000000..fe387d70e4 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + OpenTelemetry Semantic Conventions + $(PackageTags);semantic-conventions + SemanticConventions- + false + + + diff --git a/src/OpenTelemetry.SemanticConventions/README.md b/src/OpenTelemetry.SemanticConventions/README.md new file mode 100644 index 0000000000..5c68066ab0 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/README.md @@ -0,0 +1,34 @@ +# Semantic Conventions for OpenTelemetry .NET + +This project contains the generated code for the [Semantic Conventions](https://github.com/open-telemetry/semantic-conventions) +defined by the OpenTelemetry specification. + +## Installation + +```shell +dotnet add package OpenTelemetry.SemanticConventions --prerelease +``` + +## Generating the files + +This project uses the +[Semantic Convention Generator](https://github.com/open-telemetry/build-tools/blob/main/semantic-conventions/README.md). +The folder `scripts` at the top level of the project contains the template +and the script files used in the process. + +To generate the code files, run: + +```shell +./scripts/generate.sh +``` + +Or, with PowerShell: + +```shell +./scripts/generate.ps1 +``` + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) +* [Build tools](https://github.com/open-telemetry/build-tools) diff --git a/src/OpenTelemetry.SemanticConventions/scripts/.gitignore b/src/OpenTelemetry.SemanticConventions/scripts/.gitignore new file mode 100644 index 0000000000..dfd65b8051 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/.gitignore @@ -0,0 +1 @@ +semantic-conventions/ diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 new file mode 100644 index 0000000000..81d03e27f3 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 @@ -0,0 +1,29 @@ +$SCRIPT_DIR = $PSScriptRoot +$ROOT_DIR = "${SCRIPT_DIR}/../" + +# freeze the spec version to make SemanticAttributes generation reproducible +$SPEC_VERSION = "1.25.0" +$GENERATOR_VERSION = "latest" + +Set-Location $SCRIPT_DIR + +Remove-Item -r -fo semantic-conventions +mkdir semantic-conventions +Set-Location semantic-conventions + +git init +git remote add origin https://github.com/open-telemetry/semantic-conventions.git +git fetch origin v$SPEC_VERSION +git reset --hard FETCH_HEAD +Set-Location ${SCRIPT_DIR} + +docker run --rm ` + -v ${SCRIPT_DIR}/semantic-conventions/model:/source ` + -v ${SCRIPT_DIR}/templates:/templates ` + -v ${ROOT_DIR}/Attributes:/output ` + otel/semconvgen:$GENERATOR_VERSION ` + -f /source code ` + --template /templates/SemanticConventionsAttributes.cs.j2 ` + --output "/output/{{pascal_prefix}}Attributes.cs" ` + --trim-whitespace ` + --file-per-group root_namespace diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh new file mode 100644 index 0000000000..a60fdb1a26 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="${SCRIPT_DIR}/../" + +# freeze the spec version to make SemanticAttributes generation reproducible +SPEC_VERSION=1.25.0 +GENERATOR_VERSION=latest + +cd ${SCRIPT_DIR} + +rm -rf semantic-conventions || true +mkdir semantic-conventions +cd semantic-conventions + +git init +git remote add origin https://github.com/open-telemetry/semantic-conventions.git +git fetch origin "v$SPEC_VERSION" +git reset --hard FETCH_HEAD +cd ${SCRIPT_DIR} + +docker run --rm \ + -v ${SCRIPT_DIR}/semantic-conventions/model:/source \ + -v ${SCRIPT_DIR}/templates:/templates \ + -v ${ROOT_DIR}/Attributes:/output \ + otel/semconvgen:$GENERATOR_VERSION \ + -f /source code \ + --template /templates/SemanticConventionsAttributes.cs.j2 \ + --output /output/{{pascal_prefix}}Attributes.cs \ + --trim-whitespace \ + --file-per-group root_namespace diff --git a/src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 b/src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 new file mode 100644 index 0000000000..1c2e139a73 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 @@ -0,0 +1,65 @@ +{%- macro format_remarks(text) -%} +{%- set notes = '\n /// '.join(text.splitlines()).encode('ascii', 'xmlcharrefreplace').decode() -%} +{{notes}} +{%- endmacro -%} + +{%- macro format_xml_doc(text) -%} +{%- set escaped = text.encode('ascii', 'xmlcharrefreplace').decode() -%} + {%- if not escaped.endswith('.')-%} + {{escaped + '.'}} + {%- else -%} + {{escaped}} + {%- endif -%} +{%- endmacro -%} + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from scripts{{template}} + +#pragma warning disable CS1570 // XML comment has badly formed XML + +using System; + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class {{ root_namespace | to_camelcase(True) }}Attributes +{ +{% for attribute in attributes_and_templates %} +{% if not loop.first %}{{"\n"}}{% endif %} + /// + /// {{format_xml_doc(attribute.brief | render_markdown(code="{0}", paragraph="{0}"))}} + /// +{% if attribute.note %} + /// + /// {{format_remarks(attribute.note | to_doc_brief | escape | render_markdown(code="{0}", paragraph="{0}"))}}. + /// +{% endif %} +{% if attribute.deprecated %} + [Obsolete("{{attribute.deprecated | to_doc_brief | replace('"', "")}}")] +{% endif %} + public const string Attribute{{attribute.fqn | replace("-","_") | to_camelcase(True)}} = "{{attribute.fqn}}"; +{% endfor %} +{% for attribute in enum_attributes %} +{% set class_name = attribute.fqn | to_camelcase(True) ~ "Values" %} +{% set type = attribute.attr_type.enum_type %} + + /// + /// {{format_xml_doc(attribute.brief | render_markdown(code="{0}", paragraph="{0}"))}} + /// + public static class {{class_name}} + { + {% for member in attribute.attr_type.members %} + /// + /// {{format_xml_doc(member.brief | render_markdown(code="{0}", paragraph="{0}"))}} + /// + public const {{ type }} {{ member.member_id | to_camelcase(True) }} = {{ attribute | print_member_value(member) }}; + {% if not loop.last %}{{"\n"}}{% endif %} + {% endfor %} + } +{% endfor %} +} + From c34b5cd08ca9b81f04a85a0503984d7e479c4e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 24 Apr 2024 21:51:49 +0200 Subject: [PATCH 1039/1499] [Instrumentation.Geneva] CHANGELOG.md - typo fix (#1690) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f6ab99ec94..dad858f00d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -4,7 +4,7 @@ ## 1.8.0-beta.1 -Released 2023-Apr-23 +Released 2024-Apr-23 * Fix a bug in `GenevaMetricExporter` where the `MetricEtwDataTransport` singleton is disposed. From 6d5939508f382b63e4ccced7cfd49dc548c9ffe4 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Wed, 24 Apr 2024 21:34:56 -0700 Subject: [PATCH 1040/1499] [Instrumentation.SqlClient] nullable enable (#1687) --- .../.publicApi/PublicAPI.Unshipped.txt | 11 +++++---- .../Implementation/SqlActivitySourceHelper.cs | 6 ++--- .../SqlClientDiagnosticListener.cs | 23 +++++++++++-------- .../SqlEventSourceListener.netfx.cs | 12 +++++----- ...Telemetry.Instrumentation.SqlClient.csproj | 2 -- .../SqlClientInstrumentation.cs | 4 ++-- .../SqlClientTraceInstrumentationOptions.cs | 22 +++++++++--------- .../TracerProviderBuilderExtensions.cs | 4 ++-- ...try.Instrumentation.SqlClient.Tests.csproj | 2 -- .../SqlClientTests.cs | 5 ++-- ...lClientTraceInstrumentationOptionsTests.cs | 17 +++++++------- .../SqlEventSourceTests.netfx.cs | 7 +++--- 12 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt index 82f785235c..bc00a1d8c2 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt @@ -1,9 +1,10 @@ +#nullable enable OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.EnableConnectionLevelAttributes.get -> bool OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.EnableConnectionLevelAttributes.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.get -> System.Func? OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.RecordException.set -> void @@ -13,6 +14,6 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Set OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SqlClientTraceInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index ea6080bafd..f089caf08d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -18,12 +18,12 @@ internal sealed class SqlActivitySourceHelper public static readonly Assembly Assembly = typeof(SqlActivitySourceHelper).Assembly; public static readonly AssemblyName AssemblyName = Assembly.GetName(); - public static readonly string ActivitySourceName = AssemblyName.Name; + public static readonly string ActivitySourceName = AssemblyName.Name!; public static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); public static readonly string ActivityName = ActivitySourceName + ".Execute"; - public static readonly IEnumerable> CreationTags = new[] + public static readonly IEnumerable> CreationTags = new[] { - new KeyValuePair(SemanticConventions.AttributeDbSystem, MicrosoftSqlServerDatabaseSystemName), + new KeyValuePair(SemanticConventions.AttributeDbSystem, MicrosoftSqlServerDatabaseSystemName), }; } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 589ae603f7..bf3b77c599 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -34,7 +34,7 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler private readonly PropertyFetcher exceptionFetcher = new("Exception"); private readonly SqlClientTraceInstrumentationOptions options; - public SqlClientDiagnosticListener(string sourceName, SqlClientTraceInstrumentationOptions options) + public SqlClientDiagnosticListener(string sourceName, SqlClientTraceInstrumentationOptions? options) : base(sourceName) { this.options = options ?? new SqlClientTraceInstrumentationOptions(); @@ -42,7 +42,7 @@ public SqlClientDiagnosticListener(string sourceName, SqlClientTraceInstrumentat public override bool SupportsNullActivity => true; - public override void OnEventWritten(string name, object payload) + public override void OnEventWritten(string name, object? payload) { var activity = Activity.Current; switch (name) @@ -94,14 +94,19 @@ public override void OnEventWritten(string name, object payload) _ = this.connectionFetcher.TryFetch(command, out var connection); _ = this.databaseFetcher.TryFetch(connection, out var database); - activity.DisplayName = (string)database; + if (database != null) + { + activity.DisplayName = (string)database; + activity.SetTag(SemanticConventions.AttributeDbName, database); + } _ = this.dataSourceFetcher.TryFetch(connection, out var dataSource); _ = this.commandTextFetcher.TryFetch(command, out var commandText); - activity.SetTag(SemanticConventions.AttributeDbName, (string)database); - - this.options.AddConnectionLevelDetailsToActivity((string)dataSource, activity); + if (dataSource != null) + { + this.options.AddConnectionLevelDetailsToActivity((string)dataSource, activity); + } if (this.commandTypeFetcher.TryFetch(command, out CommandType commandType)) { @@ -110,7 +115,7 @@ public override void OnEventWritten(string name, object payload) case CommandType.StoredProcedure: if (this.options.SetDbStatementForStoredProcedure) { - activity.SetTag(SemanticConventions.AttributeDbStatement, (string)commandText); + activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); } break; @@ -118,7 +123,7 @@ public override void OnEventWritten(string name, object payload) case CommandType.Text: if (this.options.SetDbStatementForText) { - activity.SetTag(SemanticConventions.AttributeDbStatement, (string)commandText); + activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); } break; @@ -176,7 +181,7 @@ public override void OnEventWritten(string name, object payload) { if (activity.IsAllDataRequested) { - if (this.exceptionFetcher.TryFetch(payload, out Exception exception) && exception != null) + if (this.exceptionFetcher.TryFetch(payload, out Exception? exception) && exception != null) { activity.SetStatus(ActivityStatusCode.Error, exception.Message); diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index 111e4878d3..40c3c056a8 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -30,10 +30,10 @@ internal sealed class SqlEventSourceListener : EventListener internal const int EndExecuteEventId = 2; private readonly SqlClientTraceInstrumentationOptions options; - private EventSource adoNetEventSource; - private EventSource mdsEventSource; + private EventSource? adoNetEventSource; + private EventSource? mdsEventSource; - public SqlEventSourceListener(SqlClientTraceInstrumentationOptions options = null) + public SqlEventSourceListener(SqlClientTraceInstrumentationOptions? options = null) { this.options = options ?? new SqlClientTraceInstrumentationOptions(); } @@ -106,7 +106,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) (https://github.com/dotnet/SqlClient/blob/f4568ce68da21db3fe88c0e72e1287368aaa1dc8/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs#L6641) */ - if ((eventData?.Payload?.Count ?? 0) < 4) + if (eventData.Payload.Count < 4) { SqlClientInstrumentationEventSource.Log.InvalidPayload(nameof(SqlEventSourceListener), nameof(this.OnBeginExecute)); return; @@ -124,7 +124,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) return; } - string databaseName = (string)eventData.Payload[2]; + string? databaseName = (string)eventData.Payload[2]; activity.DisplayName = databaseName; @@ -151,7 +151,7 @@ private void OnEndExecute(EventWrittenEventArgs eventData) [2] -> SqlExceptionNumber */ - if ((eventData?.Payload?.Count ?? 0) < 3) + if (eventData.Payload.Count < 3) { SqlClientInstrumentationEventSource.Log.InvalidPayload(nameof(SqlEventSourceListener), nameof(this.OnEndExecute)); return; diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index bddef25ac1..b2c24ef68f 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -8,8 +8,6 @@ Instrumentation.SqlClient- enable - - disable - disable diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 6dd7e7e3fb..d4adc75169 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -34,8 +34,8 @@ public void Dispose() [Fact] public void SqlClient_BadArgs() { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddSqlClientInstrumentation()); + TracerProviderBuilder? builder = null; + Assert.Throws(() => builder!.AddSqlClientInstrumentation()); } [Fact] @@ -377,6 +377,7 @@ internal static void VerifySamplingParameters(SamplingParameters samplingParamet Assert.Contains( samplingParameters.Tags, kvp => kvp.Key == SemanticConventions.AttributeDbSystem + && kvp.Value != null && (string)kvp.Value == SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName); } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs index 306804929c..e729190d8c 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs @@ -41,10 +41,10 @@ static SqlClientTraceInstrumentationOptionsTests() [InlineData("np:\\\\localhost\\pipe\\MSSQL$instanceName\\sql\\query", "localhost", null, "instanceName", null)] public void ParseDataSourceTests( string dataSource, - string expectedServerHostName, - string expectedServerIpAddress, - string expectedInstanceName, - string expectedPort) + string? expectedServerHostName, + string? expectedServerIpAddress, + string? expectedInstanceName, + string? expectedPort) { var sqlConnectionDetails = SqlClientTraceInstrumentationOptions.ParseDataSource(dataSource); @@ -64,13 +64,14 @@ public void ParseDataSourceTests( public void SqlClientTraceInstrumentationOptions_EnableConnectionLevelAttributes( bool enableConnectionLevelAttributes, string dataSource, - string expectedServerHostName, - string expectedServerIpAddress, - string expectedInstanceName, - string expectedPort) + string? expectedServerHostName, + string? expectedServerIpAddress, + string? expectedInstanceName, + string? expectedPort) { var source = new ActivitySource("sql-client-instrumentation"); var activity = source.StartActivity("Test Sql Activity"); + Assert.NotNull(activity); var options = new SqlClientTraceInstrumentationOptions() { EnableConnectionLevelAttributes = enableConnectionLevelAttributes, diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index 1f48748e28..60e20b880a 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -24,7 +24,7 @@ To use Docker... */ private const string SqlConnectionStringEnvVarName = "OTEL_SQLCONNECTIONSTRING"; - private static readonly string SqlConnectionString = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(SqlConnectionStringEnvVarName); + private static readonly string? SqlConnectionString = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(SqlConnectionStringEnvVarName); [Trait("CategoryName", "SqlIntegrationTests")] [SkipUnlessEnvVarFoundTheory(SqlConnectionStringEnvVarName)] @@ -43,6 +43,7 @@ public async Task SuccessfulCommandTest(CommandType commandType, string commandT }) .Build(); + Assert.NotNull(SqlConnectionString); using SqlConnection sqlConnection = new SqlConnection(SqlConnectionString); await sqlConnection.OpenAsync(); @@ -338,7 +339,7 @@ public void WriteEndExecuteEvent(string arg1, string arg2, string arg3, string a [Event(3)] public void WriteUnknownEventWithNullPayload() { - object[] args = null; + object[]? args = null; this.WriteEvent(3, args); } @@ -362,7 +363,7 @@ public void WriteEndExecuteEvent(string arg1, string arg2, string arg3, string a [Event(3)] public void WriteUnknownEventWithNullPayload() { - object[] args = null; + object[]? args = null; this.WriteEvent(3, args); } From df77cbb75ebd1df71072b7a67982d2a364e7e09f Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 25 Apr 2024 17:56:19 -0700 Subject: [PATCH 1041/1499] [Exporter.Geneva] Update exemplars with latest SDK changes (#1689) Co-authored-by: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> --- .../CHANGELOG.md | 3 + .../Common.GenevaExporter.props | 2 +- .../Metrics/TlvMetricExporter.cs | 61 ++++++++----------- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 20 ++++-- .../GenevaMetricExporterTests.cs | 47 ++++++++------ ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- 7 files changed, 77 insertions(+), 60 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index dad858f00d..9113ce3932 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update OpenTelemetry SDK version to `1.8.0-rc.1`. + ([#1689](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1689)) + ## 1.8.0-beta.1 Released 2024-Apr-23 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 5570a7a1fe..1673f7ab45 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestVersion) + 1.8.0-rc.1 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 00eaf87708..f81d11a4d5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -88,7 +88,7 @@ internal ExportResult Export(in Batch batch) try { #if EXPOSE_EXPERIMENTAL_FEATURES - var exemplars = metricPoint.GetExemplars(); + metricPoint.TryGetExemplars(out var exemplars); #endif switch (metric.MetricType) @@ -266,7 +266,7 @@ internal unsafe ushort SerializeMetricWithTLV( in ReadOnlyTagCollection tags, MetricData value, #if EXPOSE_EXPERIMENTAL_FEATURES - Exemplar[] exemplars, + ReadOnlyExemplarCollection exemplars, #endif out string monitoringAccount, out string metricNamespace) @@ -330,7 +330,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( double min, double max, #if EXPOSE_EXPERIMENTAL_FEATURES - Exemplar[] exemplars, + ReadOnlyExemplarCollection exemplars, #endif out string monitoringAccount, out string metricNamespace) @@ -407,9 +407,15 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] #if EXPOSE_EXPERIMENTAL_FEATURES [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref int bufferIndex) + private static void SerializeExemplars(in ReadOnlyExemplarCollection exemplars, byte[] buffer, ref int bufferIndex) { - if (exemplars.Length > 0) + var exemplarsCount = 0; + foreach (ref readonly var exemplar in exemplars) + { + exemplarsCount++; + } + + if (exemplarsCount > 0) { MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.Exemplars); @@ -419,24 +425,11 @@ private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version - // TODO: Avoid this additional enumeration - var exemplarsCount = 0; - foreach (var exemplar in exemplars) - { - if (exemplar.Timestamp != default) - { - exemplarsCount++; - } - } - MetricSerializer.SerializeInt32AsBase128(buffer, ref bufferIndex, exemplarsCount); - foreach (var exemplar in exemplars) + foreach (ref readonly var exemplar in exemplars) { - if (exemplar.Timestamp != default) - { - SerializeSingleExmeplar(exemplar, buffer, ref bufferIndex); - } + SerializeSingleExemplar(exemplar, buffer, ref bufferIndex); } var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); @@ -445,7 +438,7 @@ private static void SerializeExemplars(Exemplar[] exemplars, byte[] buffer, ref } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, ref int bufferIndex) + private static void SerializeSingleExemplar(Exemplar exemplar, byte[] buffer, ref int bufferIndex) { MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version @@ -475,7 +468,6 @@ private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, re var bufferIndexForNumberOfLabels = bufferIndex; MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // serialize zero as the count of labels; this would be updated later if the exemplar has labels - byte numberOfLabels = 0; // Convert exemplar timestamp to unix nanoseconds var unixNanoSeconds = DateTime.FromFileTimeUtc(exemplar.Timestamp.ToFileTime()) @@ -485,34 +477,35 @@ private static void SerializeSingleExmeplar(Exemplar exemplar, byte[] buffer, re MetricSerializer.SerializeInt64(buffer, ref bufferIndex, (long)unixNanoSeconds); // serialize timestamp - if (exemplar.TraceId.HasValue) + if (exemplar.TraceId != default) { Span traceIdBytes = stackalloc byte[16]; - exemplar.TraceId.Value.CopyTo(traceIdBytes); + exemplar.TraceId.CopyTo(traceIdBytes); MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, traceIdBytes, traceIdBytes.Length); // serialize traceId flags |= ExemplarFlags.TraceIdExists; } - if (exemplar.SpanId.HasValue) + if (exemplar.SpanId != default) { Span spanIdBytes = stackalloc byte[8]; - exemplar.SpanId.Value.CopyTo(spanIdBytes); + exemplar.SpanId.CopyTo(spanIdBytes); MetricSerializer.SerializeSpanOfBytes(buffer, ref bufferIndex, spanIdBytes, spanIdBytes.Length); // serialize spanId flags |= ExemplarFlags.SpanIdExists; } - bool hasLabels = exemplar.FilteredTags != null && exemplar.FilteredTags.Count > 0; - if (hasLabels) + byte numberOfLabels = 0; + + foreach (var tag in exemplar.FilteredTags) { - foreach (var tag in exemplar.FilteredTags) - { - MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, tag.Key); - MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); - numberOfLabels++; - } + MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, tag.Key); + MetricSerializer.SerializeBase128String(buffer, ref bufferIndex, Convert.ToString(tag.Value, CultureInfo.InvariantCulture)); + numberOfLabels++; + } + if (numberOfLabels > 0) + { MetricSerializer.SerializeByte(buffer, ref bufferIndexForNumberOfLabels, numberOfLabels); } diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index ba2dfbb4fe..2894f56807 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,7 +5,7 @@ true An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors - $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649 + $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649,OTEL1002 net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index 0edc7f4747..f05d5eca12 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -574,6 +574,9 @@ public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() [Benchmark] public void SerializeCounterMetricItemWith3Dimensions() { +#if EXPOSE_EXPERIMENTAL_FEATURES + this.counterMetricPointWith3Dimensions.TryGetExemplars(out var exemplars); +#endif this.tlvMetricsExporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith3Dimensions.Name, @@ -581,7 +584,7 @@ public void SerializeCounterMetricItemWith3Dimensions() this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES - Array.Empty(), + exemplars, #endif out _, out _); @@ -590,6 +593,9 @@ public void SerializeCounterMetricItemWith3Dimensions() [Benchmark] public void SerializeCounterMetricItemWith4Dimensions() { +#if EXPOSE_EXPERIMENTAL_FEATURES + this.counterMetricPointWith4Dimensions.TryGetExemplars(out var exemplars); +#endif this.tlvMetricsExporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith4Dimensions.Name, @@ -597,7 +603,7 @@ public void SerializeCounterMetricItemWith4Dimensions() this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES - Array.Empty(), + exemplars, #endif out _, out _); @@ -618,6 +624,9 @@ public void ExportCounterMetricItemWith4Dimensions() [Benchmark] public void SerializeHistogramMetricItemWith3Dimensions() { +#if EXPOSE_EXPERIMENTAL_FEATURES + this.histogramMetricPointWith3Dimensions.TryGetExemplars(out var exemplars); +#endif this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith3Dimensions.Name, this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), @@ -628,7 +637,7 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramMinWith3Dimensions, this.histogramMaxWith3Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES - Array.Empty(), + exemplars, #endif out _, out _); @@ -637,6 +646,9 @@ public void SerializeHistogramMetricItemWith3Dimensions() [Benchmark] public void SerializeHistogramMetricItemWith4Dimensions() { +#if EXPOSE_EXPERIMENTAL_FEATURES + this.histogramMetricPointWith4Dimensions.TryGetExemplars(out var exemplars); +#endif this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith4Dimensions.Name, this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), @@ -647,7 +659,7 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramMinWith4Dimensions, this.histogramMaxWith4Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES - Array.Empty(), + exemplars, #endif out _, out _); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index e21a60bed7..714920f7e0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -186,7 +186,7 @@ public void SuccessfulExportOnLinux() var metricData = new MetricData { UInt64Value = metricDataValue }; #if EXPOSE_EXPERIMENTAL_FEATURES - var exemplars = metricPoint.GetExemplars(); + metricPoint.TryGetExemplars(out var exemplars); #endif var bodyLength = exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, @@ -385,7 +385,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars if (hasExemplars) { #if EXPOSE_EXPERIMENTAL_FEATURES - meterProviderBuilder.SetExemplarFilter(new AlwaysOnExemplarFilter()); + meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); #endif } @@ -983,7 +983,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, var metricPoint = metricPointsEnumerator.Current; #if EXPOSE_EXPERIMENTAL_FEATURES - var exemplars = metricPoint.GetExemplars(); + metricPoint.TryGetExemplars(out var exemplars); #endif List fields = null; @@ -1166,10 +1166,15 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, } #if EXPOSE_EXPERIMENTAL_FEATURES - if (exemplars.Length > 0) + List validExemplars = new List(); + + foreach (var exemplar in exemplars) { - var validExemplars = exemplars.Where(exemplar => exemplar.Timestamp != default).ToList(); + validExemplars.Add(exemplar); + } + if (validExemplars.Count > 0) + { var exemplarsPayload = fields.FirstOrDefault(field => field.Type == PayloadTypes.Exemplars).Value as Exemplars; var singleExemplarList = exemplarsPayload.ExemplarList; @@ -1278,37 +1283,41 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem Assert.Equal((ulong)expectedUnixNanoSeconds, serializedExemplarBody.TimeUnixNano); - if (expectedExemplar.TraceId.HasValue) + if (expectedExemplar.TraceId != default) { var traceIdBytes = new byte[16]; - expectedExemplar.TraceId.Value.CopyTo(traceIdBytes); + expectedExemplar.TraceId.CopyTo(traceIdBytes); Assert.Equal(16, serializedExemplarBody.TraceId.Length); Assert.True(traceIdBytes.SequenceEqual(serializedExemplarBody.TraceId)); } - if (expectedExemplar.SpanId.HasValue) + if (expectedExemplar.SpanId != default) { var spanIdBytes = new byte[8]; - expectedExemplar.SpanId.Value.CopyTo(spanIdBytes); + expectedExemplar.SpanId.CopyTo(spanIdBytes); Assert.Equal(8, serializedExemplarBody.SpanId.Length); Assert.True(spanIdBytes.SequenceEqual(serializedExemplarBody.SpanId)); } - if (expectedExemplar.FilteredTags != null && expectedExemplar.FilteredTags.Count > 0) + int filteredTagsActualCount = serializedExemplarBody.NumberOfLabels; + int filteredTagsExpectedCount = 0; + int filteredTagsActualIndex = 0; + + foreach (var tag in expectedExemplar.FilteredTags) { - Assert.Equal(expectedExemplar.FilteredTags.Count, serializedExemplarBody.NumberOfLabels); + var expectedFilteredTag = tag; + var serializedFilteredTag = serializedExemplarBody.Labels[filteredTagsActualIndex]; - for (int i = 0; i < expectedExemplar.FilteredTags.Count; i++) - { - var expectedFilteredTag = expectedExemplar.FilteredTags[i]; - var serializedFilteredTag = serializedExemplarBody.Labels[i]; + Assert.Equal(expectedFilteredTag.Key, serializedFilteredTag.Name.Value); + Assert.Equal(expectedFilteredTag.Value, serializedFilteredTag.Value.Value); - Assert.Equal(expectedFilteredTag.Key, serializedFilteredTag.Name.Value); - Assert.Equal(expectedFilteredTag.Value, serializedFilteredTag.Value.Value); - } + filteredTagsActualIndex++; + filteredTagsExpectedCount++; } + + Assert.Equal(filteredTagsExpectedCount, filteredTagsActualCount); } #endif @@ -1320,7 +1329,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp var metricPoint = metricPointsEnumerator.Current; #if EXPOSE_EXPERIMENTAL_FEATURES - var exemplars = metricPoint.GetExemplars(); + metricPoint.TryGetExemplars(out var exemplars); #endif UserdataV2 result = null; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 8b1cb2b1a4..2377d030b7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -6,7 +6,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 - $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 + $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202,OTEL1002 disable From fb5342c5301eefa98ccad80f27d8504d59bc4fd6 Mon Sep 17 00:00:00 2001 From: Mike Goldsmith Date: Fri, 26 Apr 2024 15:28:07 +0100 Subject: [PATCH 1042/1499] [OpenTelemetry.Extensions] Add baggage Activity processor (#1659) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cijo Thomas Co-authored-by: Piotr Kiełkowicz --- .github/component_owners.yml | 2 ++ .../.publicApi/net462/PublicAPI.Unshipped.txt | 1 + .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 1 + .../netstandard2.0/PublicAPI.Unshipped.txt | 1 + src/OpenTelemetry.Extensions/CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/README.md | 15 +++++++++++++ .../Trace/BaggageActivityProcessor.cs | 21 +++++++++++++++++++ .../TracerProviderBuilderExtensions.cs | 16 ++++++++++++++ 8 files changed, 60 insertions(+) create mode 100644 src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 7a978f4db3..73aba2c284 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -20,6 +20,7 @@ components: - SergeyKanzhelev src/OpenTelemetry.Extensions/: - codeblanch + - mikegoldsmith src/OpenTelemetry.Extensions.AWS/: - srprash - atshaw43 @@ -114,6 +115,7 @@ components: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: - codeblanch + - mikegoldsmith test/OpenTelemetry.Extensions.AWS.Tests/: - srprash - atshaw43 diff --git a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt index 02a765cd0b..4b388d9972 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt @@ -11,3 +11,4 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> voi OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt index 02a765cd0b..4b388d9972 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -11,3 +11,4 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> voi OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 02a765cd0b..4b388d9972 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -11,3 +11,4 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> voi OpenTelemetry.Trace.TracerProviderBuilderExtensions static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 83e698517d..4c4d011360 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -8,6 +8,9 @@ * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Add Baggage Activity Processor. + ([#1659](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1659)) + ## 1.0.0-beta.4 Released 2023-Feb-27 diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index 2111fe4f43..8e4ca16c64 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -37,3 +37,18 @@ public static TracerProviderBuilder AddMyExporter(this TracerProviderBuilder bui .AddAutoFlushActivityProcessor(a => a.Parent == null && (a.Kind == ActivityKind.Server || a.Kind == ActivityKind.Consumer), 5000); } ``` + +### BaggageActivityProcessor + +The BaggageActivityProcessor reads entries stored in Baggage from the current `Baggage` +and adds the baggage keys and values to the `Activity` as tags (attributes) on start. + +Add this activity processor to a tracer provider. + +Example of adding BaggageActivityProcessor to `TracerProvider`: + +```cs +var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor() + .Build(); +``` diff --git a/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs new file mode 100644 index 0000000000..23d08dec76 --- /dev/null +++ b/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; + +namespace OpenTelemetry.Trace; + +/// +/// Activity processor that adds fields to every new span. +/// +internal sealed class BaggageActivityProcessor : BaseProcessor +{ + /// + public override void OnStart(Activity activity) + { + foreach (var entry in Baggage.Current) + { + activity.SetTag(entry.Key, entry.Value); + } + } +} diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index d64fb7c5cd..5034cb11e7 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.Threading; +using OpenTelemetry.Internal; namespace OpenTelemetry.Trace; @@ -45,6 +46,21 @@ public static TracerProviderBuilder AddAutoFlushActivityProcessor( #pragma warning disable CA2000 // Dispose objects before losing scope return builder.AddProcessor(new AutoFlushActivityProcessor(predicate, timeoutMilliseconds)); +#pragma warning restore CA2000 // Dispose objects before losing scope + } + + /// + /// Adds the to the . + /// + /// to add the to. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddBaggageActivityProcessor( + this TracerProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + +#pragma warning disable CA2000 // Dispose objects before losing scope + return builder.AddProcessor(new BaggageActivityProcessor()); #pragma warning restore CA2000 // Dispose objects before losing scope } } From 59b5c3b20d4f721eaf73141f3667fe9aa837551c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 26 Apr 2024 21:08:54 +0200 Subject: [PATCH 1043/1499] [Instrumentation.Http] Move package from main repository (#1694) --- .../comp_instrumentation_http.md | 41 + .github/codecov.yml | 5 + .github/workflows/ci.yml | 16 + .../package-Instrumentation.Http.yml | 21 + build/Common.props | 1 + .../OpenTelemetry.Instrumentation.Http.proj | 33 + opentelemetry-dotnet-contrib.sln | 33 +- .../Implementation/HttpInListener.cs | 7 +- .../Implementation/HttpInMetricsListener.cs | 3 +- .../RequestDataHelperExtensions.cs | 15 + ...penTelemetry.Instrumentation.AspNet.csproj | 1 + .../.publicApi/PublicAPI.Shipped.txt | 24 + .../.publicApi/PublicAPI.Unshipped.txt | 0 .../AssemblyInfo.cs | 10 + .../CHANGELOG.md | 550 ++++++++ .../HttpClientInstrumentation.cs | 63 + ...mentationMeterProviderBuilderExtensions.cs | 51 + ...entationTracerProviderBuilderExtensions.cs | 106 ++ .../HttpClientMetrics.cs | 41 + .../HttpClientTraceInstrumentationOptions.cs | 195 +++ .../HttpRequestMessageContextPropagation.cs | 17 + .../HttpHandlerDiagnosticListener.cs | 340 +++++ .../HttpHandlerMetricsDiagnosticListener.cs | 168 +++ .../HttpInstrumentationEventSource.cs | 115 ++ .../Implementation/HttpTagHelper.cs | 32 + .../HttpWebRequestActivitySource.netfx.cs | 1200 +++++++++++++++++ .../Implementation/TelemetryHelper.cs | 45 + .../OpenTelemetry.Instrumentation.Http.csproj | 41 + .../README.md | 362 +++++ .../IConfigurationExtensionsLogger.cs | 11 + .../OpenTelemetryConfigurationExtensions.cs | 136 ++ ...vironmentVariablesConfigurationProvider.cs | 85 ++ ...EnvironmentVariablesConfigurationSource.cs | 29 + .../EnvironmentVariablesExtensions.cs | 52 + .../Options/DelegatingOptionsFactory.cs | 120 ++ ...tionsFactoryServiceCollectionExtensions.cs | 83 ++ src/Shared/Options/SingletonOptionsManager.cs | 47 + .../RequestDataHelper.cs | 47 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + .../CustomTextMapPropagator.cs | 55 + .../RequestDataHelperTests.cs | 21 +- .../HttpClientInstrumentationBenchmarks.cs | 167 +++ ...etry.Instrumentation.Http.Benchmark.csproj | 21 + .../Program.cs | 11 + .../README.md | 11 + .../EventSourceTest.cs | 17 + .../HttpClientTests.Basic.cs | 820 +++++++++++ .../HttpClientTests.cs | 503 +++++++ .../HttpOutTestCase.cs | 33 + .../HttpTestData.cs | 44 + ...HttpWebRequestActivitySourceTests.netfx.cs | 879 ++++++++++++ .../HttpWebRequestTests.Basic.cs | 363 +++++ .../HttpWebRequestTests.cs | 189 +++ ...elemetry.Instrumentation.Http.Tests.csproj | 42 + .../RetryHandler.cs | 40 + .../http-out-test-cases.json | 340 +++++ 56 files changed, 7685 insertions(+), 18 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_http.md create mode 100644 .github/workflows/package-Instrumentation.Http.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.Http.proj create mode 100644 src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelperExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.Http/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationTracerProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/Implementation/HttpInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj create mode 100644 src/OpenTelemetry.Instrumentation.Http/README.md create mode 100644 src/Shared/Configuration/IConfigurationExtensionsLogger.cs create mode 100644 src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs create mode 100644 src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs create mode 100644 src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs create mode 100644 src/Shared/EnvironmentVariables/EnvironmentVariablesExtensions.cs create mode 100644 src/Shared/Options/DelegatingOptionsFactory.cs create mode 100644 src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs create mode 100644 src/Shared/Options/SingletonOptionsManager.cs rename src/{OpenTelemetry.Instrumentation.AspNet/Implementation => Shared}/RequestDataHelper.cs (62%) create mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/CustomTextMapPropagator.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Benchmark/OpenTelemetry.Instrumentation.Http.Benchmark.csproj create mode 100644 test/OpenTelemetry.Instrumentation.Http.Benchmark/Program.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/EventSourceTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs create mode 100644 test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_http.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_http.md new file mode 100644 index 0000000000..42121d655b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_http.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.Http +about: Issue with OpenTelemetry.Instrumentation.Http +labels: comp:instrumentation.http +--- + +# Issue with OpenTelemetry.Instrumentation.Http + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 927d2de317..027a50a663 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -63,6 +63,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.EventCounters + unittests-Instrumentation.Http: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Http + unittests-Instrumentation.Owin: carryforward: true paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ba1a08d59..d789293259 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] host: ['*/OpenTelemetry.ResourceDetectors.Host*/**', '!**/*.md'] + http: ['*/OpenTelemetry.Instrumentation.Http*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] @@ -64,6 +65,7 @@ jobs: '!*/OpenTelemetry.Instrumentation.Owin*/**', '!examples/owin/**', '!*/OpenTelemetry.PersistentStorage*/**', + '!*/OpenTelemetry.Instrumentation.Http*/**', '!*/OpenTelemetry.Instrumentation.Process*/**', '!examples/process-instrumentation/**', '!*/OpenTelemetry.Instrumentation.SqlClient*/**', @@ -160,6 +162,17 @@ jobs: project-name: OpenTelemetry.ResourceDetectors.Host code-cov-name: ResourceDetectors.Host + build-test-http: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'http') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.Http + code-cov-name: Instrumentation.Http + build-test-onecollector: needs: detect-changes if: | @@ -326,6 +339,7 @@ jobs: OpenTelemetry.Instrumentation.AspNet.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, OpenTelemetry.Instrumentation.EventCounters.Tests.csproj, + OpenTelemetry.Instrumentation.Http.Tests.csproj, OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, OpenTelemetry.Instrumentation.Runtime.Tests.csproj, @@ -383,6 +397,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'azure') || contains(needs.detect-changes.outputs.changes, 'extensions') || contains(needs.detect-changes.outputs.changes, 'host') + || contains(needs.detect-changes.outputs.changes, 'http') || contains(needs.detect-changes.outputs.changes, 'processdetector') || contains(needs.detect-changes.outputs.changes, 'processruntime') || contains(needs.detect-changes.outputs.changes, 'resourcedetectors') @@ -408,6 +423,7 @@ jobs: build-test-extensions, build-test-geneva, build-test-host, + build-test-http, build-test-onecollector, build-test-owin, build-test-persistentstorage, diff --git a/.github/workflows/package-Instrumentation.Http.yml b/.github/workflows/package-Instrumentation.Http.yml new file mode 100644 index 0000000000..b480e74189 --- /dev/null +++ b/.github/workflows/package-Instrumentation.Http.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.Instrumentation.Http + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.Http-*' # trigger when we create a tag with prefix "Instrumentation.Http-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.Http + secrets: inherit diff --git a/build/Common.props b/build/Common.props index 343b061a6a..a6d4b3c4d0 100644 --- a/build/Common.props +++ b/build/Common.props @@ -32,6 +32,7 @@ [5.0.0,6.0) [8.0.1,) [2.1.0,5.0) + 8.0.0 [3.1.0,) 8.0.0 [1.0.3,2.0) diff --git a/build/Projects/OpenTelemetry.Instrumentation.Http.proj b/build/Projects/OpenTelemetry.Instrumentation.Http.proj new file mode 100644 index 0000000000..2e8b444448 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.Http.proj @@ -0,0 +1,33 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 0bf1ae3bae..a49632c03c 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31912.275 MinimumVisualStudioVersion = 15.0.26124.0 @@ -53,6 +53,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml + .github\workflows\package-Instrumentation.Http.yml = .github\workflows\package-Instrumentation.Http.yml .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml @@ -321,6 +322,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj + build\Projects\OpenTelemetry.Instrumentation.Http.proj = build\Projects\OpenTelemetry.Instrumentation.Http.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.Runtime.proj = build\Projects\OpenTelemetry.Instrumentation.Runtime.proj @@ -347,13 +349,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host.Tests", "test\OpenTelemetry.ResourceDetectors.Host.Tests\OpenTelemetry.ResourceDetectors.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.PersistentStorage.Abstractions.Tests", "test\OpenTelemetry.PersistentStorage.Abstractions.Tests\OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj", "{7AD707F9-DC6D-430A-8834-D5DCD517BF6E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.Abstractions.Tests", "test\OpenTelemetry.PersistentStorage.Abstractions.Tests\OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj", "{7AD707F9-DC6D-430A-8834-D5DCD517BF6E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.SqlClient", "src\OpenTelemetry.Instrumentation.SqlClient\OpenTelemetry.Instrumentation.SqlClient.csproj", "{737D1A9E-5A1A-4F4F-830B-E98ED100994C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.SqlClient", "src\OpenTelemetry.Instrumentation.SqlClient\OpenTelemetry.Instrumentation.SqlClient.csproj", "{737D1A9E-5A1A-4F4F-830B-E98ED100994C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.Instrumentation.SqlClient.Tests", "test\OpenTelemetry.Instrumentation.SqlClient.Tests\OpenTelemetry.Instrumentation.SqlClient.Tests.csproj", "{9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.SqlClient.Tests", "test\OpenTelemetry.Instrumentation.SqlClient.Tests\OpenTelemetry.Instrumentation.SqlClient.Tests.csproj", "{9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.SemanticConventions", "src\OpenTelemetry.SemanticConventions\OpenTelemetry.SemanticConventions.csproj", "{BC1959E3-164E-42AE-AE1C-DE2E3046E27C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.SemanticConventions", "src\OpenTelemetry.SemanticConventions\OpenTelemetry.SemanticConventions.csproj", "{BC1959E3-164E-42AE-AE1C-DE2E3046E27C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http", "src\OpenTelemetry.Instrumentation.Http\OpenTelemetry.Instrumentation.Http.csproj", "{BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http.Tests", "test\OpenTelemetry.Instrumentation.Http.Tests\OpenTelemetry.Instrumentation.Http.Tests.csproj", "{7371E920-ECD0-403A-A009-7A1A301D9763}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http.Benchmark", "test\OpenTelemetry.Instrumentation.Http.Benchmark\OpenTelemetry.Instrumentation.Http.Benchmark.csproj", "{1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -713,6 +721,18 @@ Global {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Release|Any CPU.ActiveCfg = Release|Any CPU {BC1959E3-164E-42AE-AE1C-DE2E3046E27C}.Release|Any CPU.Build.0 = Release|Any CPU + {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1}.Release|Any CPU.Build.0 = Release|Any CPU + {7371E920-ECD0-403A-A009-7A1A301D9763}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7371E920-ECD0-403A-A009-7A1A301D9763}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7371E920-ECD0-403A-A009-7A1A301D9763}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7371E920-ECD0-403A-A009-7A1A301D9763}.Release|Any CPU.Build.0 = Release|Any CPU + {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -819,6 +839,9 @@ Global {737D1A9E-5A1A-4F4F-830B-E98ED100994C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {BC1959E3-164E-42AE-AE1C-DE2E3046E27C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {7371E920-ECD0-403A-A009-7A1A301D9763} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index 5879be98be..af6780f665 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -69,8 +69,7 @@ private void OnStartActivity(Activity activity, HttpContext context) // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md var originalHttpMethod = request.HttpMethod; - var normalizedHttpMethod = this.requestDataHelper.GetNormalizedHttpMethod(originalHttpMethod); - activity.DisplayName = normalizedHttpMethod == "_OTHER" ? "HTTP" : normalizedHttpMethod; + this.requestDataHelper.SetActivityDisplayName(activity, originalHttpMethod); var url = request.Url; activity.SetTag(SemanticConventions.AttributeServerAddress, url.Host); @@ -79,7 +78,7 @@ private void OnStartActivity(Activity activity, HttpContext context) this.requestDataHelper.SetHttpMethodTag(activity, originalHttpMethod); - var protocolVersion = RequestDataHelper.GetHttpProtocolVersion(request); + var protocolVersion = RequestDataHelperExtensions.GetHttpProtocolVersion(request); if (!string.IsNullOrEmpty(protocolVersion)) { activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, protocolVersion); @@ -130,7 +129,7 @@ private void OnStopActivity(Activity activity, HttpContext context) if (!string.IsNullOrEmpty(template)) { // Override the name that was previously set to the normalized HTTP method/HTTP - activity.DisplayName = $"{activity.DisplayName} {template!}"; + this.requestDataHelper.SetActivityDisplayName(activity, context.Request.HttpMethod, template); activity.SetTag(SemanticConventions.AttributeHttpRoute, template); } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index d1687d9d66..b50ce09959 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Diagnostics.Metrics; using System.Web; +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AspNet.Implementation; @@ -50,7 +51,7 @@ private void OnStopActivity(Activity activity, HttpContext context) var normalizedMethod = this.requestDataHelper.GetNormalizedHttpMethod(request.HttpMethod); tags.Add(SemanticConventions.AttributeHttpRequestMethod, normalizedMethod); - var protocolVersion = RequestDataHelper.GetHttpProtocolVersion(request); + var protocolVersion = RequestDataHelperExtensions.GetHttpProtocolVersion(request); if (!string.IsNullOrEmpty(protocolVersion)) { tags.Add(SemanticConventions.AttributeNetworkProtocolVersion, protocolVersion); diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelperExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelperExtensions.cs new file mode 100644 index 0000000000..08aaf6f661 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelperExtensions.cs @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Web; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.AspNet.Implementation; + +internal static class RequestDataHelperExtensions +{ + public static string GetHttpProtocolVersion(HttpRequest request) + { + return RequestDataHelper.GetHttpProtocolVersion(request.ServerVariables["SERVER_PROTOCOL"]); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 25b0a759d8..8f52b1f0af 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -17,6 +17,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..a082f2c5be --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1,24 @@ +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpWebRequest.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpWebRequest.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpWebResponse.get -> System.Action +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.EnrichWithHttpWebResponse.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.FilterHttpRequestMessage.get -> System.Func +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.FilterHttpRequestMessage.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.FilterHttpWebRequest.get -> System.Func +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.FilterHttpWebRequest.set -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.HttpClientTraceInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Metrics.HttpClientInstrumentationMeterProviderBuilderExtensions +OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions +static OpenTelemetry.Metrics.HttpClientInstrumentationMeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureHttpClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.Http/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Http/AssemblyInfo.cs new file mode 100644 index 0000000000..d1d2362bb3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Http.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.Http.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md new file mode 100644 index 0000000000..77769b799c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -0,0 +1,550 @@ +# Changelog + +## Unreleased + +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. + * Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +## 1.8.1 + +Released 2024-Apr-12 + +* **Breaking Change**: Fixed tracing instrumentation so that by default any + values detected in the query string component of requests are replaced with + the text `Redacted` when building the `url.full` tag. For example, + `?key1=value1&key2=value2` becomes `?key1=Redacted&key2=Redacted`. You can + disable this redaction by setting the environment variable + `OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION` to `true`. + ([#5532](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5532)) + +## 1.8.0 + +Released 2024-Apr-04 + +* Fixed an issue for spans when `server.port` attribute was not set with + `server.address` when it has default values (`80` for `HTTP` and + `443` for `HTTPS` protocol). + ([#5419](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5419)) + +* Fixed an issue where the `http.request.method_original` attribute was not set + on activity. Now, when `http.request.method` is set and the original method + is converted to its canonical form (e.g., `Get` is converted to `GET`), + the original value `Get` will be stored in `http.request.method_original`. + The attribute is not set on .NET Framework for non canonical form of `CONNECT`, + `GET`, `HEAD`, `PUT`, and `POST`. HTTP Client is converting these values + to canonical form. + ([#5471](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5471)) + +## 1.7.1 + +Released 2024-Feb-09 + +* .NET Framework - fix description for `http.client.request.duration` metric. + ([#5234](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5234)) + +## 1.7.0 + +Released 2023-Dec-13 + +## 1.6.0 - First stable release of this library + +Released 2023-Dec-13 + +## 1.6.0-rc.1 + +Released 2023-Dec-01 + +* Removed support for `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. The + library will now emit only the + [stable](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http) + semantic conventions. + ([#5068](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5068)) + +* Update activity DisplayName as per the specification. + ([#5078](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5078)) + +* Removed reference to `OpenTelemetry` package. This is a **breaking change** + for users relying on + [SuppressDownstreamInstrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient#suppressdownstreaminstrumentation) + option in `OpenTelemetry.Instrumentation.GrpcNetClient`. For details, check + out this + [issue](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092). + ([#5077](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5077)) + +* **Breaking Change**: Renamed `HttpClientInstrumentationOptions` to + `HttpClientTraceInstrumentationOptions`. + ([#5109](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5109)) + +* **Breaking Change**: Removed `http.user_agent` tag from HttpClient activity. + ([#5110](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5110)) + +* `HttpWebRequest` : Introduced additional values for `error.type` tag on + activity and `http.client.request.duration` metric. + ([#5111](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5111)) + +## 1.6.0-beta.3 + +Released 2023-Nov-17 + +* Removed the Activity Status Description that was being set during + exceptions. Activity Status will continue to be reported as `Error`. + This is a **breaking change**. `EnrichWithException` can be leveraged + to restore this behavior. + ([#5025](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5025)) + +* Updated `http.request.method` to match specification guidelines. + * For activity, if the method does not belong to one of the [known + values](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-spans.md#:~:text=http.request.method%20has%20the%20following%20list%20of%20well%2Dknown%20values) + then the request method will be set on an additional tag + `http.request.method.original` and `http.request.method` will be set to + `_OTHER`. + * For metrics, if the original method does not belong to one of the [known + values](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-spans.md#:~:text=http.request.method%20has%20the%20following%20list%20of%20well%2Dknown%20values) + then `http.request.method` on `http.client.request.duration` metric will be + set to `_OTHER` + + `http.request.method` is set on `http.client.request.duration` metric or + activity when `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable is set to + `http` or `http/dup`. + ([#5003](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5003)) + +* An additional attribute `error.type` will be added to activity and + `http.client.request.duration` metric in case of failed requests as per the + [specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes). + + Users moving to `net8.0` or newer frameworks from lower versions will see + difference in values in case of an exception. `net8.0` or newer frameworks add + the ability to further drill down the exceptions to a specific type through + [HttpRequestError](https://learn.microsoft.com/dotnet/api/system.net.http.httprequesterror?view=net-8.0) + enum. For lower versions, the individual types will be rolled in to a single + type. This could be a **breaking change** if alerts are set based on the values. + + The attribute will only be added when `OTEL_SEMCONV_STABILITY_OPT_IN` + environment variable is set to `http` or `http/dup`. + + ([#5005](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5005)) + ([#5034](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5034)) + +* Fixed `network.protocol.version` attribute values to match the specification. + ([#5006](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5006)) + +* Set `network.protocol.version` value using the protocol version on the + received response. If the request fails without response, then + `network.protocol.version` attribute will not be set on Activity and + `http.client.request.duration` metric. + ([#5043](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5043)) + +## 1.6.0-beta.2 + +Released 2023-Oct-26 + +* Introduced a new metric for `HttpClient`, `http.client.request.duration` + measured in seconds. The OTel SDK (starting with version 1.6.0) + [applies custom histogram buckets](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4820) + for this metric to comply with the + [Semantic Convention for Http Metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md). + This new metric is only available for users who opt-in to the new + semantic convention by configuring the `OTEL_SEMCONV_STABILITY_OPT_IN` + environment variable to either `http` (to emit only the new metric) or + `http/dup` (to emit both the new and old metrics). + ([#4870](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4870)) + + * New metric: `http.client.request.duration` + * Unit: `s` (seconds) + * Histogram Buckets: `0, 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` + * Old metric: `http.client.duration` + * Unit: `ms` (milliseconds) + * Histogram Buckets: `0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, + 5000, 7500, 10000` + + Note: The older `http.client.duration` metric and + `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable will eventually be + removed after the HTTP semantic conventions are marked stable. At which time + this instrumentation can publish a stable release. Refer to the specification + for more information regarding the new HTTP semantic conventions: + * [http-spans](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-spans.md) + * [http-metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md) + +* Added support for publishing `http.client.duration` & + `http.client.request.duration` metrics on .NET Framework for `HttpWebRequest`. + ([#4870](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4870)) + +* Following `HttpClient` metrics will now be enabled by default when targeting + `.NET8.0` framework or newer. + + * **Meter** : `System.Net.Http` + * `http.client.request.duration` + * `http.client.active_requests` + * `http.client.open_connections` + * `http.client.connection.duration` + * `http.client.request.time_in_queue` + + * **Meter** : `System.Net.NameResolution` + * `dns.lookups.duration` + + For details about each individual metric check [System.Net metrics + docs + page](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-system-net). + + **NOTES**: + * When targeting `.NET8.0` framework or newer, `http.client.request.duration` metric + will only follow + [v1.22.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-metrics.md#metric-httpclientrequestduration) + semantic conventions specification. Ability to switch behavior to older + conventions using `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable is + not available. + * Users can opt-out of metrics that are not required using + [views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#drop-an-instrument). + + ([#4931](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4931)) + +* Added `url.scheme` attribute to `http.client.request.duration` metric. The + metric will be emitted when `OTEL_SEMCONV_STABILITY_OPT_IN` environment + variable is set to `http` or `http/dup`. + ([#4989](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4989)) + +* Updated description for `http.client.request.duration` metrics to match spec + definition. + ([#4990](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4990)) + +* `dns.lookups.duration` metric is renamed to `dns.lookup.duration`. This change + impacts only users on `.NET8.0` or newer framework. + ([#5049](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5049)) + +## 1.5.1-beta.1 + +Released 2023-Jul-20 + +* The new HTTP and network semantic conventions can be opted in to by setting + the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a + transition period for users to experiment with the new semantic conventions + and adapt as necessary. The environment variable supports the following + values: + * `http` - emit the new, frozen (proposed for stable) HTTP and networking + attributes, and stop emitting the old experimental HTTP and networking + attributes that the instrumentation emitted previously. + * `http/dup` - emit both the old and the frozen (proposed for stable) HTTP + and networking attributes, allowing for a more seamless transition. + * The default behavior (in the absence of one of these values) is to continue + emitting the same HTTP and network semantic conventions that were emitted in + `1.5.0-beta.1`. + * Note: this option will eventually be removed after the new HTTP and + network semantic conventions are marked stable. At which time this + instrumentation can receive a stable release, and the old HTTP and + network semantic conventions will no longer be supported. Refer to the + specification for more information regarding the new HTTP and network + semantic conventions for both + [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md) + and + [metrics](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-metrics.md). + ([#4538](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4538), + [#4639](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4639)) + +## 1.5.0-beta.1 + +Released 2023-Jun-05 + +* Bumped the package version to `1.5.0-beta.1` to keep its major and minor + version in sync with that of the core packages. This would make it more + intuitive for users to figure out what version of core packages would work + with a given version of this package. The pre-release identifier has also been + changed from `rc` to `beta` as we believe this more accurately reflects the + status of this package. We believe the `rc` identifier will be more + appropriate as semantic conventions reach stability. + +* Fixed an issue of missing `http.client.duration` metric data in case of + network failures (when response is not available). + ([#4098](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4098)) + +* Improve perf by avoiding boxing of common status codes values. + ([#4361](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4361), + [#4363](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4363)) + +## 1.0.0-rc9.14 + +Released 2023-Feb-24 + +* Updated OTel SDK dependency to 1.4.0 + +## 1.4.0-rc9.13 + +Released 2023-Feb-10 + +## 1.0.0-rc9.12 + +Released 2023-Feb-01 + +## 1.0.0-rc9.11 + +Released 2023-Jan-09 + +## 1.0.0-rc9.10 + +Released 2022-Dec-12 + +* Added `net.peer.name` and `net.peer.port` as dimensions on + `http.client.duration` metric. + ([#3907](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3907)) + +* **Breaking change** `http.host` will no longer be populated on activity. + `net.peer.name` and `net.peer.port` attributes will be populated instead. + ([#3832](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3832)) + +## 1.0.0-rc9.9 + +Released 2022-Nov-07 + +* Added back `netstandard2.0` target. + ([#3787](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3787)) + +* **Breaking change**: The `Enrich` callback option has been removed. For better + usability, it has been replaced by three separate options: In case of + `HttpClient` the new options are `EnrichWithHttpRequestMessage`, + `EnrichWithHttpResponseMessage` and `EnrichWithException` and in case of + `HttpWebRequest` the new options are `EnrichWithHttpWebRequest`, + `EnrichWithHttpWebResponse` and `EnrichWithException`. Previously, the single + `Enrich` callback required the consumer to detect which event triggered the + callback to be invoked (e.g., request start, response end, or an exception) + and then cast the object received to the appropriate type: + `HttpRequestMessage`, `HttpResponsemessage`, or `Exception` in case of + `HttpClient` and `HttpWebRequest`,`HttpWebResponse` and `Exception` in case of + `HttpWebRequest`. The separate callbacks make it clear what event triggers + them and there is no longer the need to cast the argument to the expected + type. + ([#3792](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3792)) + +* Fixed an issue which prevented custom propagators from being called on .NET 7+ + runtimes for non-sampled outgoing `HttpClient` spans. + ([#3828](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3828)) + +* **Breaking change**: The same API is now exposed for `net462` and + `netstandard2.0` targets. The `Filter` property on options is now exposed as + `FilterHttpRequestMessage` (called for .NET & .NET Core) and + `FilterHttpWebRequest` (called for .NET Framework). + ([#3793](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3793)) + +## 1.0.0-rc9.8 + +Released 2022-Oct-17 + +* In case of .NET Core, additional spans created during retries will now be +exported. +([[#3729](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3729)]) + +## 1.0.0-rc9.7 + +Released 2022-Sep-29 + +* Dropped `netstandard2.0` target and added `net6.0`. .NET 5 reached EOL + in May 2022 and .NET Core 3.1 reaches EOL in December 2022. End of support + dates for .NET are published + [here](https://dotnet.microsoft.com/download/dotnet). + The instrumentation for HttpClient now requires .NET 6 or later. + This does not affect applications targeting .NET Framework. + ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664)) + +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddHttpClientInstrumentation` extension to allow for more fine-grained + options management + ([#3664](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3664), + [#3667](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3667)) + +## 1.0.0-rc9.6 + +Released 2022-Aug-18 + +* Updated to use Activity native support from `System.Diagnostics.DiagnosticSource` + to set activity status. + ([#3118](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3118)) + ([#3555](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3555)) + +* Changed activity source name from `OpenTelemetry.HttpWebRequest` + to `OpenTelemetry.Instrumentation.Http.HttpWebRequest` for `HttpWebRequest`s + and from `OpenTelemetry.Instrumentation.Http` + to `OpenTelemetry.Instrumentation.Http.HttpClient` for `HttpClient`. + ([#3515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3515)) + +## 1.0.0-rc9.5 + +Released 2022-Aug-02 + +* Added `http.scheme` tag to tracing instrumentation. + ([#3464](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3464)) + +* [Breaking] Removes `SetHttpFlavor` option. "http.flavor" is + now always automatically populated. + To remove this tag, set "http.flavor" to null using `ActivityProcessor`. + ([#3380](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3380)) + +* Fix `Enrich` not getting invoked when SocketException due to HostNotFound + occurs. + ([#3407](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3407)) + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +* Removes .NET Framework 4.6.1. The minimum .NET Framework + version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +* Updated `TracerProviderBuilderExtensions.AddHttpClientInstrumentation` to support + `IDeferredTracerProviderBuilder` and `IOptions` + ([#3051](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3051)) + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +* Fixed an issue with `Filter` and `Enrich` callbacks not firing under certain + conditions when gRPC is used + ([#2698](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2698)) + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +* Removes .NET Framework 4.5.2 support. The minimum .NET Framework + version supported is .NET 4.6.1. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2138)) + +* `HttpClient` instances created before `AddHttpClientInstrumentation` is called + on .NET Framework will now also be instrumented + ([#2364](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2364)) + +## 1.0.0-rc7 + +Released 2021-Jul-12 + +## 1.0.0-rc6 + +Released 2021-Jun-25 + +## 1.0.0-rc5 + +Released 2021-Jun-09 + +## 1.0.0-rc4 + +Released 2021-Apr-23 + +* Sanitize `http.url` attribute. + ([#1961](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1961)) +* Added `RecordException` to HttpClientInstrumentationOptions and + HttpWebRequestInstrumentationOptions which allows Exception to be reported as + ActivityEvent. +* Update `AddHttpClientInstrumentation` extension method for .NET Framework to + use only use `HttpWebRequestInstrumentationOptions` + ([#1982](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1982)) + +## 1.0.0-rc3 + +Released 2021-Mar-19 + +* Leverages added AddLegacySource API from OpenTelemetry SDK to trigger Samplers + and ActivityProcessors. Samplers, ActivityProcessor.OnStart will now get the + Activity before any enrichment done by the instrumentation. + ([#1836](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1836)) +* Performance optimization by leveraging sampling decision and short circuiting + activity enrichment. + ([#1894](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1894)) + +## 1.0.0-rc2 + +Released 2021-Jan-29 + +* `otel.status_description` tag will no longer be set to the http status + description/reason phrase for outgoing http spans. + ([#1579](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1579)) + +* Moved the DiagnosticListener filtering logic from HttpClientInstrumentation + ctor to OnStartActivity method of HttpHandlerDiagnosticListener.cs; Updated + the logic of OnStartActivity to inject propagation data into Headers for + filtered out events as well. + ([#1707](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1707)) + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +* HttpInstrumentation sets ActivitySource to activities created outside + ActivitySource. + ([#1515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1515/)) + +## 0.8.0-beta.1 + +Released 2020-Nov-5 + +* Instrumentation for `HttpWebRequest` no longer store raw objects like + `HttpWebRequest` in Activity.CustomProperty. To enrich activity, use the + Enrich action on the instrumentation. + ([#1407](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1407)) +* Renamed TextMapPropagator to TraceContextPropagator, CompositePropagator to + CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and + changed from interface to abstract class. + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Propagators.DefaultTextMapPropagator will be used as the default Propagator + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) +* Removed Propagator from Instrumentation Options. Instrumentation now always + respect the Propagator.DefaultTextMapPropagator. + ([#1448](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1448)) + +## 0.7.0-beta.1 + +Released 2020-Oct-16 + +* Instrumentation no longer store raw objects like `HttpRequestMessage` in + Activity.CustomProperty. To enrich activity, use the Enrich action on the + instrumentation. + ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) +* Span Status is populated as per new spec + ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) + +## 0.6.0-beta.1 + +Released 2020-Sep-15 + +## 0.5.0-beta.2 + +Released 2020-08-28 + +* Rename FilterFunc to Filter. + +* HttpClient/HttpWebRequest instrumentation will now add the raw Request, + Response, and/or Exception objects to the Activity it creates + ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099)) +* Changed the default propagation to support W3C Baggage + ([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048)) + * The default ITextFormat is now `CompositePropagator(TraceContextFormat, + BaggageFormat)`. Outgoing Http request will now send Baggage using the [W3C + Baggage](https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md) + header. Previously Baggage was sent using the `Correlation-Context` header, + which is now outdated. +* Removed `AddHttpInstrumentation` and `AddHttpWebRequestInstrumentation` (.NET + Framework) `TracerProviderBuilderExtensions`. `AddHttpClientInstrumentation` + will now register `HttpClient` instrumentation on .NET Core and `HttpClient` + + `HttpWebRequest` instrumentation on .NET Framework. +* Renamed `ITextPropagator` to `IPropagator` + ([#1190](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1190)) + +## 0.3.0-beta + +Released 2020-07-23 + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs new file mode 100644 index 0000000000..80a84bb57c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs @@ -0,0 +1,63 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.Http.Implementation; + +namespace OpenTelemetry.Instrumentation.Http; + +/// +/// HttpClient instrumentation. +/// +internal sealed class HttpClientInstrumentation : IDisposable +{ + private static readonly HashSet ExcludedDiagnosticSourceEventsNet7OrGreater = new() + { + "System.Net.Http.Request", + "System.Net.Http.Response", + "System.Net.Http.HttpRequestOut", + }; + + private static readonly HashSet ExcludedDiagnosticSourceEvents = new() + { + "System.Net.Http.Request", + "System.Net.Http.Response", + }; + + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + private readonly Func isEnabled = (eventName, _, _) + => !ExcludedDiagnosticSourceEvents.Contains(eventName); + + private readonly Func isEnabledNet7OrGreater = (eventName, _, _) + => !ExcludedDiagnosticSourceEventsNet7OrGreater.Contains(eventName); + + /// + /// Initializes a new instance of the class. + /// + /// Configuration options for HTTP client instrumentation. + public HttpClientInstrumentation(HttpClientTraceInstrumentationOptions options) + { + // For .NET7.0 activity will be created using activitySource. + // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs + // However, in case when activity creation returns null (due to sampling) + // the framework will fall back to creating activity anyways due to active diagnostic source listener + // To prevent this, isEnabled is implemented which will return false always + // so that the sampler's decision is respected. + if (HttpHandlerDiagnosticListener.IsNet7OrGreater) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpHandlerDiagnosticListener(options), this.isEnabledNet7OrGreater, HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + } + else + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpHandlerDiagnosticListener(options), this.isEnabled, HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + } + + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..2694208968 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NET8_0_OR_GREATER +#if !NETFRAMEWORK +using OpenTelemetry.Instrumentation.Http; +#endif +using OpenTelemetry.Instrumentation.Http.Implementation; +#endif + +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of HttpClient instrumentation. +/// +public static class HttpClientInstrumentationMeterProviderBuilderExtensions +{ + /// + /// Enables HttpClient instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddHttpClientInstrumentation( + this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + +#if NET8_0_OR_GREATER + return builder + .AddMeter("System.Net.Http") + .AddMeter("System.Net.NameResolution"); +#else + // Note: Warm-up the status code and method mapping. + _ = TelemetryHelper.BoxedStatusCodes; + _ = HttpTagHelper.RequestDataHelper; + +#if NETFRAMEWORK + builder.AddMeter(HttpWebRequestActivitySource.MeterName); +#else + builder.AddMeter(HttpHandlerMetricsDiagnosticListener.MeterName); + +#pragma warning disable CA2000 // Dispose objects before losing scope + builder.AddInstrumentation(new HttpClientMetrics()); +#pragma warning restore CA2000 // Dispose objects before losing scope +#endif + return builder; +#endif + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationTracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationTracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..4a06b88f7c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationTracerProviderBuilderExtensions.cs @@ -0,0 +1,106 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.Http; +using OpenTelemetry.Instrumentation.Http.Implementation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of HttpClient instrumentation. +/// +public static class HttpClientInstrumentationTracerProviderBuilderExtensions +{ + /// + /// Enables HttpClient instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation(this TracerProviderBuilder builder) + => AddHttpClientInstrumentation(builder, name: null, configureHttpClientTraceInstrumentationOptions: null); + + /// + /// Enables HttpClient instrumentation. + /// + /// being configured. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation( + this TracerProviderBuilder builder, + Action configureHttpClientTraceInstrumentationOptions) + => AddHttpClientInstrumentation(builder, name: null, configureHttpClientTraceInstrumentationOptions); + + /// + /// Enables HttpClient instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddHttpClientInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configureHttpClientTraceInstrumentationOptions) + { + Guard.ThrowIfNull(builder); + + // Note: Warm-up the status code and method mapping. + _ = TelemetryHelper.BoxedStatusCodes; + _ = HttpTagHelper.RequestDataHelper; + + name ??= Options.DefaultName; + + builder.ConfigureServices(services => + { + if (configureHttpClientTraceInstrumentationOptions != null) + { + services.Configure(name, configureHttpClientTraceInstrumentationOptions); + } + + services.RegisterOptionsFactory(configuration => new HttpClientTraceInstrumentationOptions(configuration)); + }); + +#if NETFRAMEWORK + builder.AddSource(HttpWebRequestActivitySource.ActivitySourceName); + + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + deferredTracerProviderBuilder.Configure((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name); + + HttpWebRequestActivitySource.TracingOptions = options; + }); + } +#else + AddHttpClientInstrumentationSource(builder); + + builder.AddInstrumentation(sp => + { + var options = sp.GetRequiredService>().Get(name); + + return new HttpClientInstrumentation(options); + }); +#endif + return builder; + } + +#if !NETFRAMEWORK + internal static void AddHttpClientInstrumentationSource( + this TracerProviderBuilder builder) + { + if (HttpHandlerDiagnosticListener.IsNet7OrGreater) + { + builder.AddSource(HttpHandlerDiagnosticListener.HttpClientActivitySourceName); + } + else + { + builder.AddSource(HttpHandlerDiagnosticListener.ActivitySourceName); + builder.AddLegacySource("System.Net.Http.HttpRequestOut"); + } + } +#endif +} diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs new file mode 100644 index 0000000000..f3773ed8fd --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.Http.Implementation; + +namespace OpenTelemetry.Instrumentation.Http; + +/// +/// HttpClient instrumentation. +/// +internal sealed class HttpClientMetrics : IDisposable +{ + private static readonly HashSet ExcludedDiagnosticSourceEvents = new() + { + "System.Net.Http.Request", + "System.Net.Http.Response", + }; + + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + private readonly Func isEnabled = (activityName, obj1, obj2) + => !ExcludedDiagnosticSourceEvents.Contains(activityName); + + /// + /// Initializes a new instance of the class. + /// + public HttpClientMetrics() + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( + new HttpHandlerMetricsDiagnosticListener("HttpHandlerDiagnosticListener"), + this.isEnabled, + HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs new file mode 100644 index 0000000000..a5fbec23cd --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs @@ -0,0 +1,195 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Net; +using System.Runtime.CompilerServices; +#if NETFRAMEWORK +using System.Net.Http; +#endif +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Instrumentation.Http.Implementation; + +namespace OpenTelemetry.Instrumentation.Http; + +/// +/// Options for HttpClient instrumentation. +/// +public class HttpClientTraceInstrumentationOptions +{ + /// + /// Initializes a new instance of the class. + /// + public HttpClientTraceInstrumentationOptions() + : this(new ConfigurationBuilder().AddEnvironmentVariables().Build()) + { + } + + internal HttpClientTraceInstrumentationOptions(IConfiguration configuration) + { + Debug.Assert(configuration != null, "configuration was null"); + + if (configuration.TryGetBoolValue( + HttpInstrumentationEventSource.Log, + "OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION", + out var disableUrlQueryRedaction)) + { + this.DisableUrlQueryRedaction = disableUrlQueryRedaction; + } + } + + /// + /// Gets or sets a filter function that determines whether or not to + /// collect telemetry on a per request basis. + /// + /// + /// FilterHttpRequestMessage is only executed on .NET and .NET + /// Core runtimes. and on .NET and .NET Core are both implemented + /// using . + /// Notes: + /// + /// The return value for the filter function is interpreted as: + /// + /// If filter returns , the request is + /// collected. + /// If filter returns or throws an + /// exception the request is NOT collected. + /// + /// + /// + public Func FilterHttpRequestMessage { get; set; } + + /// + /// Gets or sets an action to enrich an with . + /// + /// + /// EnrichWithHttpRequestMessage is only executed on .NET and .NET + /// Core runtimes. and on .NET and .NET Core are both implemented + /// using . + /// + public Action EnrichWithHttpRequestMessage { get; set; } + + /// + /// Gets or sets an action to enrich an with . + /// + /// + /// EnrichWithHttpResponseMessage is only executed on .NET and .NET + /// Core runtimes. and on .NET and .NET Core are both implemented + /// using . + /// + public Action EnrichWithHttpResponseMessage { get; set; } + + /// + /// Gets or sets an action to enrich an with . + /// + /// + /// EnrichWithException is called for all runtimes. + /// + public Action EnrichWithException { get; set; } + + /// + /// Gets or sets a filter function that determines whether or not to + /// collect telemetry on a per request basis. + /// + /// + /// FilterHttpWebRequest is only executed on .NET Framework + /// runtimes. and + /// on .NET Framework are both implemented using . + /// Notes: + /// + /// The return value for the filter function is interpreted as: + /// + /// If filter returns , the request is + /// collected. + /// If filter returns or throws an + /// exception the request is NOT collected. + /// + /// + /// + public Func FilterHttpWebRequest { get; set; } + + /// + /// Gets or sets an action to enrich an with . + /// + /// + /// EnrichWithHttpWebRequest is only executed on .NET Framework + /// runtimes. and + /// on .NET Framework are both implemented using . + /// + public Action EnrichWithHttpWebRequest { get; set; } + + /// + /// Gets or sets an action to enrich an with . + /// + /// + /// EnrichWithHttpWebResponse is only executed on .NET Framework + /// runtimes. and + /// on .NET Framework are both implemented using . + /// + public Action EnrichWithHttpWebResponse { get; set; } + + /// + /// Gets or sets a value indicating whether exception will be recorded + /// as an or not. Default value: . + /// + /// + /// RecordException is supported on all runtimes. + /// For specification details see: . + /// + public bool RecordException { get; set; } + + /// + /// Gets or sets a value indicating whether the url query value should be redacted or not. + /// + /// + /// The query parameter values are redacted with value set as Redacted. + /// e.g. `?key1=value1` is set as `?key1=Redacted`. + /// The redaction can be disabled by setting this property to . + /// + internal bool DisableUrlQueryRedaction { get; set; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal bool EventFilterHttpRequestMessage(string activityName, object arg1) + { + try + { + return + this.FilterHttpRequestMessage == null || + !TryParseHttpRequestMessage(activityName, arg1, out HttpRequestMessage requestMessage) || + this.FilterHttpRequestMessage(requestMessage); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.RequestFilterException(ex); + return false; + } + } + + internal bool EventFilterHttpWebRequest(HttpWebRequest request) + { + try + { + return this.FilterHttpWebRequest?.Invoke(request) ?? true; + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.RequestFilterException(ex); + return false; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryParseHttpRequestMessage(string activityName, object arg1, out HttpRequestMessage requestMessage) + { + return (requestMessage = arg1 as HttpRequestMessage) != null && activityName == "System.Net.Http.HttpRequestOut"; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs b/src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs new file mode 100644 index 0000000000..91d2a5c18a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Net.Http; +#endif + +namespace OpenTelemetry.Instrumentation.Http; + +internal static class HttpRequestMessageContextPropagation +{ + internal static Action HeaderValueSetter => (request, name, value) => + { + request.Headers.Remove(name); + request.Headers.Add(name, value); + }; +} diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs new file mode 100644 index 0000000000..61147eafc4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -0,0 +1,340 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +#if NETFRAMEWORK +using System.Net.Http; +#endif +using System.Reflection; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Http.Implementation; + +internal sealed class HttpHandlerDiagnosticListener : ListenerHandler +{ +#if !NETFRAMEWORK + internal const string HttpClientActivitySourceName = "System.Net.Http"; +#endif + + internal static readonly AssemblyName AssemblyName = typeof(HttpHandlerDiagnosticListener).Assembly.GetName(); + internal static readonly bool IsNet7OrGreater = InitializeIsNet7OrGreater(); + + // https://github.com/dotnet/runtime/blob/7d034ddbbbe1f2f40c264b323b3ed3d6b3d45e9a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L19 + internal static readonly string ActivitySourceName = AssemblyName.Name + ".HttpClient"; + internal static readonly Version Version = AssemblyName.Version; + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + + private const string OnStartEvent = "System.Net.Http.HttpRequestOut.Start"; + private const string OnStopEvent = "System.Net.Http.HttpRequestOut.Stop"; + private const string OnUnhandledExceptionEvent = "System.Net.Http.Exception"; + + private static readonly PropertyFetcher StartRequestFetcher = new("Request"); + private static readonly PropertyFetcher StopResponseFetcher = new("Response"); + private static readonly PropertyFetcher StopExceptionFetcher = new("Exception"); + private static readonly PropertyFetcher StopRequestStatusFetcher = new("RequestTaskStatus"); + private readonly HttpClientTraceInstrumentationOptions options; + + public HttpHandlerDiagnosticListener(HttpClientTraceInstrumentationOptions options) + : base("HttpHandlerDiagnosticListener") + { + this.options = options; + } + + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnStartEvent: + { + this.OnStartActivity(Activity.Current, payload); + } + + break; + case OnStopEvent: + { + this.OnStopActivity(Activity.Current, payload); + } + + break; + case OnUnhandledExceptionEvent: + { + this.OnException(Activity.Current, payload); + } + + break; + } + } + + public void OnStartActivity(Activity activity, object payload) + { + // The overall flow of what HttpClient library does is as below: + // Activity.Start() + // DiagnosticSource.WriteEvent("Start", payload) + // DiagnosticSource.WriteEvent("Stop", payload) + // Activity.Stop() + + // This method is in the WriteEvent("Start", payload) path. + // By this time, samplers have already run and + // activity.IsAllDataRequested populated accordingly. + + if (!TryFetchRequest(payload, out HttpRequestMessage request)) + { + HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnStartActivity)); + return; + } + + // Propagate context irrespective of sampling decision + var textMapPropagator = Propagators.DefaultTextMapPropagator; + if (textMapPropagator is not TraceContextPropagator) + { + textMapPropagator.Inject(new PropagationContext(activity.Context, Baggage.Current), request, HttpRequestMessageContextPropagation.HeaderValueSetter); + } + + // For .NET7.0 or higher versions, activity is created using activity source. + // However the framework will fallback to creating activity if the sampler's decision is to drop and there is a active diagnostic listener. + // To prevent processing such activities we first check the source name to confirm if it was created using + // activity source or not. + if (IsNet7OrGreater && string.IsNullOrEmpty(activity.Source.Name)) + { + activity.IsAllDataRequested = false; + } + + // enrich Activity from payload only if sampling decision + // is favorable. + if (activity.IsAllDataRequested) + { + try + { + if (this.options.EventFilterHttpRequestMessage(activity.OperationName, request) == false) + { + HttpInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.RequestFilterException(ex); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + + HttpTagHelper.RequestDataHelper.SetActivityDisplayName(activity, request.Method.Method); + + if (!IsNet7OrGreater) + { + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); + } + + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md + HttpTagHelper.RequestDataHelper.SetHttpMethodTag(activity, request.Method.Method); + + activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); + activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + + activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri, this.options.DisableUrlQueryRedaction)); + + try + { + this.options.EnrichWithHttpRequestMessage?.Invoke(activity, request); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] +#endif + static bool TryFetchRequest(object payload, out HttpRequestMessage request) + { + if (!StartRequestFetcher.TryFetch(payload, out request) || request == null) + { + return false; + } + + return true; + } + } + + public void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + var requestTaskStatus = GetRequestStatus(payload); + + ActivityStatusCode currentStatusCode = activity.Status; + if (requestTaskStatus != TaskStatus.RanToCompletion) + { + if (requestTaskStatus == TaskStatus.Canceled) + { + if (currentStatusCode == ActivityStatusCode.Unset) + { + activity.SetStatus(ActivityStatusCode.Error); + } + } + else if (requestTaskStatus != TaskStatus.Faulted) + { + if (currentStatusCode == ActivityStatusCode.Unset) + { + // Faults are handled in OnException and should already have a span.Status of Error w/ Description. + activity.SetStatus(ActivityStatusCode.Error); + } + } + } + + if (TryFetchResponse(payload, out HttpResponseMessage response)) + { + if (currentStatusCode == ActivityStatusCode.Unset) + { + activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, (int)response.StatusCode)); + } + + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(response.Version)); + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode)); + if (activity.Status == ActivityStatusCode.Error) + { + activity.SetTag(SemanticConventions.AttributeErrorType, TelemetryHelper.GetStatusCodeString(response.StatusCode)); + } + + try + { + this.options.EnrichWithHttpResponseMessage?.Invoke(activity, response); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] +#endif + static TaskStatus GetRequestStatus(object payload) + { + // requestTaskStatus (type is TaskStatus) is a non-nullable enum so we don't need to have a null check here. + // See: https://github.com/dotnet/runtime/blob/79c021d65c280020246d1035b0e87ae36f2d36a9/src/libraries/System.Net.Http/src/HttpDiagnosticsGuide.md?plain=1#L69 + _ = StopRequestStatusFetcher.TryFetch(payload, out var requestTaskStatus); + + return requestTaskStatus; + } + } + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] +#endif + static bool TryFetchResponse(object payload, out HttpResponseMessage response) + { + if (StopResponseFetcher.TryFetch(payload, out response) && response != null) + { + return true; + } + + return false; + } + } + + public void OnException(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + if (!TryFetchException(payload, out Exception exc)) + { + HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnException)); + return; + } + + activity.SetTag(SemanticConventions.AttributeErrorType, GetErrorType(exc)); + + if (this.options.RecordException) + { + activity.RecordException(exc); + } + + if (exc is HttpRequestException) + { + activity.SetStatus(ActivityStatusCode.Error); + } + + try + { + this.options.EnrichWithException?.Invoke(activity, exc); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] +#endif + static bool TryFetchException(object payload, out Exception exc) + { + if (!StopExceptionFetcher.TryFetch(payload, out exc) || exc == null) + { + return false; + } + + return true; + } + } + + private static string GetErrorType(Exception exc) + { +#if NET8_0_OR_GREATER + // For net8.0 and above exception type can be found using HttpRequestError. + // https://learn.microsoft.com/dotnet/api/system.net.http.httprequesterror?view=net-8.0 + if (exc is HttpRequestException httpRequestException) + { + return httpRequestException.HttpRequestError switch + { + HttpRequestError.NameResolutionError => "name_resolution_error", + HttpRequestError.ConnectionError => "connection_error", + HttpRequestError.SecureConnectionError => "secure_connection_error", + HttpRequestError.HttpProtocolError => "http_protocol_error", + HttpRequestError.ExtendedConnectNotSupported => "extended_connect_not_supported", + HttpRequestError.VersionNegotiationError => "version_negotiation_error", + HttpRequestError.UserAuthenticationError => "user_authentication_error", + HttpRequestError.ProxyTunnelError => "proxy_tunnel_error", + HttpRequestError.InvalidResponse => "invalid_response", + HttpRequestError.ResponseEnded => "response_ended", + HttpRequestError.ConfigurationLimitExceeded => "configuration_limit_exceeded", + + // Fall back to the exception type name in case of HttpRequestError.Unknown + _ => exc.GetType().FullName, + }; + } +#endif + return exc.GetType().FullName; + } + + private static bool InitializeIsNet7OrGreater() + { + try + { + return typeof(HttpClient).Assembly.GetName().Version.Major >= 7; + } + catch (Exception) + { + return false; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs new file mode 100644 index 0000000000..eb781dbd97 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs @@ -0,0 +1,168 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using System.Diagnostics.Metrics; +#if NETFRAMEWORK +using System.Net.Http; +#endif +using System.Reflection; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Http.Implementation; + +internal sealed class HttpHandlerMetricsDiagnosticListener : ListenerHandler +{ + internal const string OnStopEvent = "System.Net.Http.HttpRequestOut.Stop"; + + internal static readonly AssemblyName AssemblyName = typeof(HttpClientMetrics).Assembly.GetName(); + internal static readonly string MeterName = AssemblyName.Name; + internal static readonly string MeterVersion = AssemblyName.Version.ToString(); + internal static readonly Meter Meter = new(MeterName, MeterVersion); + private const string OnUnhandledExceptionEvent = "System.Net.Http.Exception"; + private static readonly Histogram HttpClientRequestDuration = Meter.CreateHistogram("http.client.request.duration", "s", "Duration of HTTP client requests."); + + private static readonly PropertyFetcher StopRequestFetcher = new("Request"); + private static readonly PropertyFetcher StopResponseFetcher = new("Response"); + private static readonly PropertyFetcher StopExceptionFetcher = new("Exception"); + private static readonly PropertyFetcher RequestFetcher = new("Request"); +#if NET6_0_OR_GREATER + private static readonly HttpRequestOptionsKey HttpRequestOptionsErrorKey = new(SemanticConventions.AttributeErrorType); +#endif + + public HttpHandlerMetricsDiagnosticListener(string name) + : base(name) + { + } + + public static void OnStopEventWritten(Activity activity, object payload) + { + if (TryFetchRequest(payload, out HttpRequestMessage request)) + { + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md + TagList tags = default; + + var httpMethod = HttpTagHelper.RequestDataHelper.GetNormalizedHttpMethod(request.Method.Method); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); + + tags.Add(new KeyValuePair(SemanticConventions.AttributeServerAddress, request.RequestUri.Host)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, request.RequestUri.Scheme)); + + if (!request.RequestUri.IsDefaultPort) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeServerPort, request.RequestUri.Port)); + } + + if (TryFetchResponse(payload, out HttpResponseMessage response)) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(response.Version))); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode))); + + // Set error.type to status code for failed requests + // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes + if (SpanHelper.ResolveActivityStatusForHttpStatusCode(ActivityKind.Client, (int)response.StatusCode) == ActivityStatusCode.Error) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, TelemetryHelper.GetStatusCodeString(response.StatusCode))); + } + } + + if (response == null) + { +#if !NET6_0_OR_GREATER + request.Properties.TryGetValue(SemanticConventions.AttributeErrorType, out var errorType); +#else + request.Options.TryGetValue(HttpRequestOptionsErrorKey, out var errorType); +#endif + + // Set error.type to exception type if response was not received. + // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes + if (errorType != null) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, errorType)); + } + } + + // We are relying here on HttpClient library to set duration before writing the stop event. + // https://github.com/dotnet/runtime/blob/90603686d314147017c8bbe1fa8965776ce607d0/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L178 + // TODO: Follow up with .NET team if we can continue to rely on this behavior. + HttpClientRequestDuration.Record(activity.Duration.TotalSeconds, tags); + } + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] +#endif + static bool TryFetchRequest(object payload, out HttpRequestMessage request) => + StopRequestFetcher.TryFetch(payload, out request) && request != null; + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] +#endif + static bool TryFetchResponse(object payload, out HttpResponseMessage response) => + StopResponseFetcher.TryFetch(payload, out response) && response != null; + } + + public static void OnExceptionEventWritten(Activity activity, object payload) + { + if (!TryFetchException(payload, out Exception exc) || !TryFetchRequest(payload, out HttpRequestMessage request)) + { + HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerMetricsDiagnosticListener), nameof(OnExceptionEventWritten)); + return; + } + +#if !NET6_0_OR_GREATER + request.Properties.Add(SemanticConventions.AttributeErrorType, exc.GetType().FullName); +#else + request.Options.Set(HttpRequestOptionsErrorKey, exc.GetType().FullName); +#endif + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] +#endif + static bool TryFetchException(object payload, out Exception exc) + { + if (!StopExceptionFetcher.TryFetch(payload, out exc) || exc == null) + { + return false; + } + + return true; + } + + // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. + // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] +#endif + static bool TryFetchRequest(object payload, out HttpRequestMessage request) + { + if (!RequestFetcher.TryFetch(payload, out request) || request == null) + { + return false; + } + + return true; + } + } + + public override void OnEventWritten(string name, object payload) + { + if (name == OnStopEvent) + { + OnStopEventWritten(Activity.Current, payload); + } + else if (name == OnUnhandledExceptionEvent) + { + OnExceptionEventWritten(Activity.Current, payload); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpInstrumentationEventSource.cs new file mode 100644 index 0000000000..4f04f9b667 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpInstrumentationEventSource.cs @@ -0,0 +1,115 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics.Tracing; +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Http.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-Http")] +internal sealed class HttpInstrumentationEventSource : EventSource, IConfigurationExtensionsLogger +{ + public static HttpInstrumentationEventSource Log = new(); + + [NonEvent] + public void FailedProcessResult(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.FailedProcessResult(ex.ToInvariantString()); + } + } + + [NonEvent] + public void RequestFilterException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.RequestFilterException(ex.ToInvariantString()); + } + } + + [NonEvent] + public void ExceptionInitializingInstrumentation(string instrumentationType, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.ExceptionInitializingInstrumentation(instrumentationType, ex.ToInvariantString()); + } + } + + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Failed to process result: '{0}'", Level = EventLevel.Error)] + public void FailedProcessResult(string ex) + { + this.WriteEvent(1, ex); + } + + [Event(2, Message = "Error initializing instrumentation type {0}. Exception : {1}", Level = EventLevel.Error)] + public void ExceptionInitializingInstrumentation(string instrumentationType, string ex) + { + this.WriteEvent(2, instrumentationType, ex); + } + + [Event(3, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(3, handlerName, eventName); + } + + [Event(4, Message = "Filter threw exception. Request will not be collected. Exception {0}.", Level = EventLevel.Error)] + public void RequestFilterException(string exception) + { + this.WriteEvent(4, exception); + } + + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(ex.ToInvariantString()); + } + } + + [Event(5, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(5, exception); + } + + [Event(6, Message = "Request is filtered out.", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut(string eventName) + { + this.WriteEvent(6, eventName); + } + + [Event(7, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(7, handlerName, eventName, ex); + } + + [Event(8, Message = "Configuration key '{0}' has an invalid value: '{1}'", Level = EventLevel.Warning)] + public void InvalidConfigurationValue(string key, string value) + { + this.WriteEvent(8, key, value); + } + + void IConfigurationExtensionsLogger.LogInvalidConfigurationValue(string key, string value) + { + this.InvalidConfigurationValue(key, value); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs new file mode 100644 index 0000000000..79815cf576 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpTagHelper.cs @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.Http.Implementation; + +/// +/// A collection of helper methods to be used when building Http activities. +/// +internal static class HttpTagHelper +{ + internal static readonly RequestDataHelper RequestDataHelper = new(); + + /// + /// Gets the OpenTelemetry standard uri tag value for a span based on its request . + /// + /// . + /// Indicates whether query parameter should be redacted or not. + /// Span uri value. + public static string GetUriTagValueFromRequestUri(Uri uri, bool disableQueryRedaction) + { + if (string.IsNullOrEmpty(uri.UserInfo) && disableQueryRedaction) + { + return uri.OriginalString; + } + + var query = disableQueryRedaction ? uri.Query : RedactionHelper.GetRedactedQueryString(uri.Query); + + return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.AbsolutePath, query, uri.Fragment); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs new file mode 100644 index 0000000000..f1f98f4de3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -0,0 +1,1200 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Collections; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using System.Net; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.Http.Implementation; + +/// +/// Hooks into the class reflectively and writes diagnostic events as requests are processed. +/// +/// +/// Inspired from the System.Diagnostics.DiagnosticSource.HttpHandlerDiagnosticListener class which has some bugs and feature gaps. +/// See https://github.com/dotnet/runtime/pull/33732 for details. +/// +internal static class HttpWebRequestActivitySource +{ + internal static readonly AssemblyName AssemblyName = typeof(HttpWebRequestActivitySource).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name + ".HttpWebRequest"; + internal static readonly string ActivityName = ActivitySourceName + ".HttpRequestOut"; + internal static readonly string MeterName = AssemblyName.Name; + + internal static readonly Func> HttpWebRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); + internal static readonly Action HttpWebRequestHeaderValuesSetter = (request, name, value) => request.Headers.Add(name, value); + + private static readonly string Version = AssemblyName.Version.ToString(); + private static readonly ActivitySource WebRequestActivitySource = new(ActivitySourceName, Version); + private static readonly Meter WebRequestMeter = new(MeterName, Version); + private static readonly Histogram HttpClientRequestDuration = WebRequestMeter.CreateHistogram("http.client.request.duration", "s", "Duration of HTTP client requests."); + + private static HttpClientTraceInstrumentationOptions tracingOptions; + + // Fields for reflection + private static FieldInfo connectionGroupListField; + private static Type connectionGroupType; + private static FieldInfo connectionListField; + private static Type connectionType; + private static FieldInfo writeListField; + private static Func writeAResultAccessor; + private static Func readAResultAccessor; + + // LazyAsyncResult & ContextAwareResult + private static Func asyncCallbackAccessor; + private static Action asyncCallbackModifier; + private static Func asyncStateAccessor; + private static Action asyncStateModifier; + private static Func endCalledAccessor; + private static Func resultAccessor; + private static Func isContextAwareResultChecker; + + // HttpWebResponse + private static Func httpWebResponseCtor; + private static Func uriAccessor; + private static Func verbAccessor; + private static Func mediaTypeAccessor; + private static Func usesProxySemanticsAccessor; + private static Func coreResponseDataAccessor; + private static Func isWebSocketResponseAccessor; + private static Func connectionGroupNameAccessor; + + static HttpWebRequestActivitySource() + { + try + { + PrepareReflectionObjects(); + PerformInjection(); + + TracingOptions = new HttpClientTraceInstrumentationOptions(); + } + catch (Exception ex) + { + // If anything went wrong, just no-op. Write an event so at least we can find out. + HttpInstrumentationEventSource.Log.ExceptionInitializingInstrumentation(typeof(HttpWebRequestActivitySource).FullName, ex); + } + } + + internal static HttpClientTraceInstrumentationOptions TracingOptions + { + get => tracingOptions; + set + { + tracingOptions = value; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, Activity activity) + { + HttpTagHelper.RequestDataHelper.SetActivityDisplayName(activity, request.Method); + + if (activity.IsAllDataRequested) + { + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md + HttpTagHelper.RequestDataHelper.SetHttpMethodTag(activity, request.Method); + + activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); + activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + + activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri, tracingOptions.DisableUrlQueryRedaction)); + + try + { + TracingOptions.EnrichWithHttpWebRequest?.Invoke(activity, request); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AddResponseTags(HttpWebResponse response, Activity activity) + { + Debug.Assert(activity != null, "Activity must not be null"); + + if (activity.IsAllDataRequested) + { + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(response.ProtocolVersion)); + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode)); + + try + { + TracingOptions.EnrichWithHttpWebResponse?.Invoke(activity, response); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static string GetErrorType(Exception exception) + { + if (exception is WebException wexc) + { + // TODO: consider other Status values from + // https://learn.microsoft.com/dotnet/api/system.net.webexceptionstatus?view=netframework-4.6.2 + return wexc.Status switch + { + WebExceptionStatus.NameResolutionFailure => "name_resolution_failure", + WebExceptionStatus.ConnectFailure => "connect_failure", + WebExceptionStatus.ReceiveFailure => "receive_failure", + WebExceptionStatus.SendFailure => "send_failure", + WebExceptionStatus.PipelineFailure => "pipeline_failure", + WebExceptionStatus.RequestCanceled => "request_cancelled", + WebExceptionStatus.ProtocolError => "protocol_error", + WebExceptionStatus.ConnectionClosed => "connection_closed", + WebExceptionStatus.TrustFailure => "trust_failure", + WebExceptionStatus.SecureChannelFailure => "secure_channel_failure", + WebExceptionStatus.ServerProtocolViolation => "server_protocol_violation", + WebExceptionStatus.KeepAliveFailure => "keep_alive_failure", + WebExceptionStatus.Timeout => "timeout", + WebExceptionStatus.ProxyNameResolutionFailure => "proxy_name_resolution_failure", + WebExceptionStatus.MessageLengthLimitExceeded => "message_length_limit_exceeded", + WebExceptionStatus.RequestProhibitedByCachePolicy => "request_prohibited_by_cache_policy", + WebExceptionStatus.RequestProhibitedByProxy => "request_prohibited_by_proxy", + _ => wexc.GetType().FullName, + }; + } + + return exception.GetType().FullName; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AddExceptionEvent(Exception exception, Activity activity) + { + Debug.Assert(activity != null, "Activity must not be null"); + + if (!activity.IsAllDataRequested) + { + return; + } + + if (TracingOptions.RecordException) + { + activity.RecordException(exception); + } + + try + { + TracingOptions.EnrichWithException?.Invoke(activity, exception); + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void InstrumentRequest(HttpWebRequest request, ActivityContext activityContext) + => Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(activityContext, Baggage.Current), request, HttpWebRequestHeaderValuesSetter); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsRequestInstrumented(HttpWebRequest request) + => Propagators.DefaultTextMapPropagator.Extract(default, request, HttpWebRequestHeaderValuesGetter) != default; + + private static void ProcessRequest(HttpWebRequest request) + { + // There are subscribers to the ActivitySource and no user-provided filter is + // filtering this request. + var enableTracing = WebRequestActivitySource.HasListeners() + && TracingOptions.EventFilterHttpWebRequest(request); + + if (!enableTracing && !HttpClientRequestDuration.Enabled) + { + // Tracing and metrics are not enabled, so we can skip generating signals + // Propagation must still be done in such cases, to allow + // downstream services to continue from parent context, if any. + // Eg: Parent could be the Asp.Net activity. + InstrumentRequest(request, Activity.Current?.Context ?? default); + return; + } + + if (IsRequestInstrumented(request)) + { + // This request was instrumented by previous + // ProcessRequest, such is the case with redirect responses where the same request is sent again. + return; + } + + Activity activity = enableTracing + ? WebRequestActivitySource.StartActivity(ActivityName, ActivityKind.Client) + : null; + + var activityContext = Activity.Current?.Context ?? default; + + // Propagation must still be done in all cases, to allow + // downstream services to continue from parent context, if any. + // Eg: Parent could be the Asp.Net activity. + InstrumentRequest(request, activityContext); + + IAsyncResult asyncContext = writeAResultAccessor(request); + if (asyncContext != null) + { + // Flow here is for [Begin]GetRequestStream[Async]. + + AsyncCallbackWrapper callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext), Stopwatch.GetTimestamp()); + asyncCallbackModifier(asyncContext, callback.AsyncCallback); + } + else + { + // Flow here is for [Begin]GetResponse[Async] without a prior call to [Begin]GetRequestStream[Async]. + + asyncContext = readAResultAccessor(request); + AsyncCallbackWrapper callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext), Stopwatch.GetTimestamp()); + asyncCallbackModifier(asyncContext, callback.AsyncCallback); + } + + if (activity != null) + { + AddRequestTagsAndInstrumentRequest(request, activity); + } + } + + private static void HookOrProcessResult(HttpWebRequest request) + { + IAsyncResult writeAsyncContext = writeAResultAccessor(request); + if (writeAsyncContext == null || asyncCallbackAccessor(writeAsyncContext)?.Target is not AsyncCallbackWrapper writeAsyncContextCallback) + { + // If we already hooked into the read result during ProcessRequest or we hooked up after the fact already we don't need to do anything here. + return; + } + + // If we got here it means the user called [Begin]GetRequestStream[Async] and we have to hook the read result after the fact. + + IAsyncResult readAsyncContext = readAResultAccessor(request); + if (readAsyncContext == null) + { + // We're still trying to establish the connection (no read has started). + return; + } + + // Clear our saved callback so we know not to process again. + asyncCallbackModifier(writeAsyncContext, null); + + if (endCalledAccessor.Invoke(readAsyncContext) || readAsyncContext.CompletedSynchronously) + { + // We need to process the result directly because the read callback has already fired. Force a copy because response has likely already been disposed. + ProcessResult(readAsyncContext, null, writeAsyncContextCallback.Activity, resultAccessor(readAsyncContext), true, request, writeAsyncContextCallback.StartTimestamp); + return; + } + + // Hook into the result callback if it hasn't already fired. + AsyncCallbackWrapper callback = new AsyncCallbackWrapper(writeAsyncContextCallback.Request, writeAsyncContextCallback.Activity, asyncCallbackAccessor(readAsyncContext), Stopwatch.GetTimestamp()); + asyncCallbackModifier(readAsyncContext, callback.AsyncCallback); + } + + private static void ProcessResult(IAsyncResult asyncResult, AsyncCallback asyncCallback, Activity activity, object result, bool forceResponseCopy, HttpWebRequest request, long startTimestamp) + { + HttpStatusCode? httpStatusCode = null; + string errorType = null; + Version protocolVersion = null; + ActivityStatusCode activityStatus = ActivityStatusCode.Unset; + + // Activity may be null if we are not tracing in these cases: + // 1. No listeners + // 2. Request was filtered out + // 3. Request was not sampled + // We could be executing on a different thread now so restore the activity if needed. + if (activity != null && Activity.Current != activity) + { + Activity.Current = activity; + } + + try + { + if (result is Exception ex) + { + errorType = GetErrorType(ex); + if (ex is WebException wexc && wexc.Response is HttpWebResponse response) + { + httpStatusCode = response.StatusCode; + protocolVersion = response.ProtocolVersion; + activityStatus = SpanHelper.ResolveActivityStatusForHttpStatusCode(ActivityKind.Client, (int)response.StatusCode); + if (activityStatus == ActivityStatusCode.Error) + { + // override the errorType to statusCode for failures. + errorType = TelemetryHelper.GetStatusCodeString(response.StatusCode); + } + + if (activity != null) + { + AddResponseTags(response, activity); + AddExceptionEvent(ex, activity); + } + } + else + { + activityStatus = ActivityStatusCode.Error; + if (activity != null) + { + AddExceptionEvent(ex, activity); + } + } + } + else + { + HttpWebResponse response = (HttpWebResponse)result; + + if (forceResponseCopy || (asyncCallback == null && isContextAwareResultChecker(asyncResult))) + { + // For async calls (where asyncResult is ContextAwareResult)... + // If no callback was set assume the user is manually calling BeginGetResponse & EndGetResponse + // in which case they could dispose the HttpWebResponse before our listeners have a chance to work with it. + // Disposed HttpWebResponse throws when accessing properties, so let's make a copy of the data to ensure that doesn't happen. + + HttpWebResponse responseCopy = httpWebResponseCtor( + new object[] + { + uriAccessor(response), verbAccessor(response), coreResponseDataAccessor(response), mediaTypeAccessor(response), + usesProxySemanticsAccessor(response), DecompressionMethods.None, + isWebSocketResponseAccessor(response), connectionGroupNameAccessor(response), + }); + + if (activity != null) + { + AddResponseTags(responseCopy, activity); + } + + httpStatusCode = responseCopy.StatusCode; + protocolVersion = responseCopy.ProtocolVersion; + } + else + { + if (activity != null) + { + AddResponseTags(response, activity); + } + + httpStatusCode = response.StatusCode; + protocolVersion = response.ProtocolVersion; + } + + activityStatus = SpanHelper.ResolveActivityStatusForHttpStatusCode(ActivityKind.Client, (int)httpStatusCode.Value); + + if (activityStatus == ActivityStatusCode.Error) + { + // set the errorType to statusCode for failures. + errorType = TelemetryHelper.GetStatusCodeString(httpStatusCode.Value); + } + } + } + catch (Exception ex) + { + HttpInstrumentationEventSource.Log.FailedProcessResult(ex); + } + + if (activity != null && activity.IsAllDataRequested) + { + activity.SetStatus(activityStatus); + if (errorType != null) + { + activity.SetTag(SemanticConventions.AttributeErrorType, errorType); + } + } + + activity?.Stop(); + + if (HttpClientRequestDuration.Enabled) + { + double durationS; + if (activity != null) + { + durationS = activity.Duration.TotalSeconds; + } + else + { + var endTimestamp = Stopwatch.GetTimestamp(); + durationS = (endTimestamp - startTimestamp) / (double)Stopwatch.Frequency; + } + + TagList tags = default; + + var httpMethod = HttpTagHelper.RequestDataHelper.GetNormalizedHttpMethod(request.Method); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); + + tags.Add(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); + tags.Add(SemanticConventions.AttributeUrlScheme, request.RequestUri.Scheme); + if (protocolVersion != null) + { + tags.Add(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(protocolVersion)); + } + + if (!request.RequestUri.IsDefaultPort) + { + tags.Add(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + } + + if (httpStatusCode.HasValue) + { + tags.Add(SemanticConventions.AttributeHttpResponseStatusCode, (int)httpStatusCode.Value); + } + + if (errorType != null) + { + tags.Add(SemanticConventions.AttributeErrorType, errorType); + } + + HttpClientRequestDuration.Record(durationS, tags); + } + } + + private static void PrepareReflectionObjects() + { + // At any point, if the operation failed, it should just throw. The caller should catch all exceptions and swallow. + + Type servicePointType = typeof(ServicePoint); + Assembly systemNetHttpAssembly = servicePointType.Assembly; + connectionGroupListField = servicePointType.GetField("m_ConnectionGroupList", BindingFlags.Instance | BindingFlags.NonPublic); + connectionGroupType = systemNetHttpAssembly?.GetType("System.Net.ConnectionGroup"); + connectionListField = connectionGroupType?.GetField("m_ConnectionList", BindingFlags.Instance | BindingFlags.NonPublic); + connectionType = systemNetHttpAssembly?.GetType("System.Net.Connection"); + writeListField = connectionType?.GetField("m_WriteList", BindingFlags.Instance | BindingFlags.NonPublic); + + writeAResultAccessor = CreateFieldGetter(typeof(HttpWebRequest), "_WriteAResult", BindingFlags.NonPublic | BindingFlags.Instance); + readAResultAccessor = CreateFieldGetter(typeof(HttpWebRequest), "_ReadAResult", BindingFlags.NonPublic | BindingFlags.Instance); + + // Double checking to make sure we have all the pieces initialized + if (connectionGroupListField == null || + connectionGroupType == null || + connectionListField == null || + connectionType == null || + writeListField == null || +#pragma warning disable CA1508 // https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1693 + writeAResultAccessor == null || + readAResultAccessor == null || +#pragma warning restore CA1508 // https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1693 + !PrepareAsyncResultReflectionObjects(systemNetHttpAssembly) || + !PrepareHttpWebResponseReflectionObjects(systemNetHttpAssembly)) + { + // If anything went wrong here, just return false. There is nothing we can do. + throw new InvalidOperationException("Unable to initialize all required reflection objects"); + } + } + + private static bool PrepareAsyncResultReflectionObjects(Assembly systemNetHttpAssembly) + { + Type lazyAsyncResultType = systemNetHttpAssembly?.GetType("System.Net.LazyAsyncResult"); + if (lazyAsyncResultType != null) + { + asyncCallbackAccessor = CreateFieldGetter(lazyAsyncResultType, "m_AsyncCallback", BindingFlags.NonPublic | BindingFlags.Instance); + asyncCallbackModifier = CreateFieldSetter(lazyAsyncResultType, "m_AsyncCallback", BindingFlags.NonPublic | BindingFlags.Instance); + asyncStateAccessor = CreateFieldGetter(lazyAsyncResultType, "m_AsyncState", BindingFlags.NonPublic | BindingFlags.Instance); + asyncStateModifier = CreateFieldSetter(lazyAsyncResultType, "m_AsyncState", BindingFlags.NonPublic | BindingFlags.Instance); + endCalledAccessor = CreateFieldGetter(lazyAsyncResultType, "m_EndCalled", BindingFlags.NonPublic | BindingFlags.Instance); + resultAccessor = CreateFieldGetter(lazyAsyncResultType, "m_Result", BindingFlags.NonPublic | BindingFlags.Instance); + } + + Type contextAwareResultType = systemNetHttpAssembly?.GetType("System.Net.ContextAwareResult"); + if (contextAwareResultType != null) + { + isContextAwareResultChecker = CreateTypeChecker(contextAwareResultType); + } + + return asyncCallbackAccessor != null + && asyncCallbackModifier != null + && asyncStateAccessor != null + && asyncStateModifier != null + && endCalledAccessor != null + && resultAccessor != null + && isContextAwareResultChecker != null; + } + + private static bool PrepareHttpWebResponseReflectionObjects(Assembly systemNetHttpAssembly) + { + Type knownHttpVerbType = systemNetHttpAssembly?.GetType("System.Net.KnownHttpVerb"); + Type coreResponseData = systemNetHttpAssembly?.GetType("System.Net.CoreResponseData"); + + if (knownHttpVerbType != null && coreResponseData != null) + { + var constructorParameterTypes = new Type[] + { + typeof(Uri), knownHttpVerbType, coreResponseData, typeof(string), + typeof(bool), typeof(DecompressionMethods), + typeof(bool), typeof(string), + }; + + ConstructorInfo ctor = typeof(HttpWebResponse).GetConstructor( + BindingFlags.NonPublic | BindingFlags.Instance, + null, + constructorParameterTypes, + null); + + if (ctor != null) + { + httpWebResponseCtor = CreateTypeInstance(ctor); + } + } + + uriAccessor = CreateFieldGetter("m_Uri", BindingFlags.NonPublic | BindingFlags.Instance); + verbAccessor = CreateFieldGetter("m_Verb", BindingFlags.NonPublic | BindingFlags.Instance); + mediaTypeAccessor = CreateFieldGetter("m_MediaType", BindingFlags.NonPublic | BindingFlags.Instance); + usesProxySemanticsAccessor = CreateFieldGetter("m_UsesProxySemantics", BindingFlags.NonPublic | BindingFlags.Instance); + coreResponseDataAccessor = CreateFieldGetter("m_CoreResponseData", BindingFlags.NonPublic | BindingFlags.Instance); + isWebSocketResponseAccessor = CreateFieldGetter("m_IsWebSocketResponse", BindingFlags.NonPublic | BindingFlags.Instance); + connectionGroupNameAccessor = CreateFieldGetter("m_ConnectionGroupName", BindingFlags.NonPublic | BindingFlags.Instance); + + return httpWebResponseCtor != null +#pragma warning disable CA1508 // https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1693 + && uriAccessor != null + && verbAccessor != null + && mediaTypeAccessor != null + && usesProxySemanticsAccessor != null + && coreResponseDataAccessor != null + && isWebSocketResponseAccessor != null + && connectionGroupNameAccessor != null; +#pragma warning restore CA1508 // https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1693 + } + + private static void PerformInjection() + { + FieldInfo servicePointTableField = typeof(ServicePointManager).GetField("s_ServicePointTable", BindingFlags.Static | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("Unable to access the ServicePointTable field"); + + Hashtable originalTable = servicePointTableField.GetValue(null) as Hashtable; + ServicePointHashtable newTable = new ServicePointHashtable(originalTable ?? new Hashtable()); + + foreach (DictionaryEntry existingServicePoint in originalTable) + { + HookServicePoint(existingServicePoint.Value); + } + + servicePointTableField.SetValue(null, newTable); + } + + private static void HookServicePoint(object value) + { + if (value is WeakReference weakRef + && weakRef.IsAlive + && weakRef.Target is ServicePoint servicePoint) + { + // Replace the ConnectionGroup hashtable inside this ServicePoint object, + // which allows us to intercept each new ConnectionGroup object added under + // this ServicePoint. + Hashtable originalTable = connectionGroupListField.GetValue(servicePoint) as Hashtable; + ConnectionGroupHashtable newTable = new ConnectionGroupHashtable(originalTable ?? new Hashtable()); + + foreach (DictionaryEntry existingConnectionGroup in originalTable) + { + HookConnectionGroup(existingConnectionGroup.Value); + } + + connectionGroupListField.SetValue(servicePoint, newTable); + } + } + + private static void HookConnectionGroup(object value) + { + if (connectionGroupType.IsInstanceOfType(value)) + { + // Replace the Connection arraylist inside this ConnectionGroup object, + // which allows us to intercept each new Connection object added under + // this ConnectionGroup. + ArrayList originalArrayList = connectionListField.GetValue(value) as ArrayList; + ConnectionArrayList newArrayList = new ConnectionArrayList(originalArrayList ?? new ArrayList()); + + foreach (object connection in originalArrayList) + { + HookConnection(connection); + } + + connectionListField.SetValue(value, newArrayList); + } + } + + private static void HookConnection(object value) + { + if (connectionType.IsInstanceOfType(value)) + { + // Replace the HttpWebRequest arraylist inside this Connection object, + // which allows us to intercept each new HttpWebRequest object added under + // this Connection. + ArrayList originalArrayList = writeListField.GetValue(value) as ArrayList; + HttpWebRequestArrayList newArrayList = new HttpWebRequestArrayList(originalArrayList ?? new ArrayList()); + + writeListField.SetValue(value, newArrayList); + } + } + + private static Func CreateFieldGetter(string fieldName, BindingFlags flags) + where TClass : class + { + FieldInfo field = typeof(TClass).GetField(fieldName, flags); + if (field != null) + { + string methodName = field.ReflectedType.FullName + ".get_" + field.Name; + DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(TClass) }, true); + ILGenerator generator = getterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Ldfld, field); + generator.Emit(OpCodes.Ret); + return (Func)getterMethod.CreateDelegate(typeof(Func)); + } + + return null; + } + + /// + /// Creates getter for a field defined in private or internal type + /// represented with classType variable. + /// + private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) + { + FieldInfo field = classType.GetField(fieldName, flags); + if (field != null) + { + string methodName = classType.FullName + ".get_" + field.Name; + DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); + ILGenerator generator = getterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, classType); + generator.Emit(OpCodes.Ldfld, field); + generator.Emit(OpCodes.Ret); + + return (Func)getterMethod.CreateDelegate(typeof(Func)); + } + + return null; + } + + /// + /// Creates setter for a field defined in private or internal type + /// represented with classType variable. + /// + private static Action CreateFieldSetter(Type classType, string fieldName, BindingFlags flags) + { + FieldInfo field = classType.GetField(fieldName, flags); + if (field != null) + { + string methodName = classType.FullName + ".set_" + field.Name; + DynamicMethod setterMethod = new DynamicMethod(methodName, null, new[] { typeof(object), typeof(TField) }, true); + ILGenerator generator = setterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Castclass, classType); + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Stfld, field); + generator.Emit(OpCodes.Ret); + + return (Action)setterMethod.CreateDelegate(typeof(Action)); + } + + return null; + } + + /// + /// Creates an "is" method for the private or internal type. + /// + private static Func CreateTypeChecker(Type classType) + { + string methodName = classType.FullName + ".typeCheck"; + DynamicMethod setterMethod = new DynamicMethod(methodName, typeof(bool), new[] { typeof(object) }, true); + ILGenerator generator = setterMethod.GetILGenerator(); + generator.Emit(OpCodes.Ldarg_0); + generator.Emit(OpCodes.Isinst, classType); + generator.Emit(OpCodes.Ldnull); + generator.Emit(OpCodes.Cgt_Un); + generator.Emit(OpCodes.Ret); + + return (Func)setterMethod.CreateDelegate(typeof(Func)); + } + + /// + /// Creates an instance of T using a private or internal ctor. + /// + private static Func CreateTypeInstance(ConstructorInfo constructorInfo) + { + Type classType = typeof(T); + string methodName = classType.FullName + ".ctor"; + DynamicMethod setterMethod = new DynamicMethod(methodName, classType, new Type[] { typeof(object[]) }, true); + ILGenerator generator = setterMethod.GetILGenerator(); + + ParameterInfo[] ctorParams = constructorInfo.GetParameters(); + for (int i = 0; i < ctorParams.Length; i++) + { + generator.Emit(OpCodes.Ldarg_0); + switch (i) + { + case 0: generator.Emit(OpCodes.Ldc_I4_0); break; + case 1: generator.Emit(OpCodes.Ldc_I4_1); break; + case 2: generator.Emit(OpCodes.Ldc_I4_2); break; + case 3: generator.Emit(OpCodes.Ldc_I4_3); break; + case 4: generator.Emit(OpCodes.Ldc_I4_4); break; + case 5: generator.Emit(OpCodes.Ldc_I4_5); break; + case 6: generator.Emit(OpCodes.Ldc_I4_6); break; + case 7: generator.Emit(OpCodes.Ldc_I4_7); break; + case 8: generator.Emit(OpCodes.Ldc_I4_8); break; + default: generator.Emit(OpCodes.Ldc_I4, i); break; + } + + generator.Emit(OpCodes.Ldelem_Ref); + Type paramType = ctorParams[i].ParameterType; + generator.Emit(paramType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, paramType); + } + + generator.Emit(OpCodes.Newobj, constructorInfo); + generator.Emit(OpCodes.Ret); + + return (Func)setterMethod.CreateDelegate(typeof(Func)); + } + + private class HashtableWrapper : Hashtable, IEnumerable + { + private readonly Hashtable table; + + internal HashtableWrapper(Hashtable table) + : base() + { + this.table = table; + } + + public override int Count => this.table.Count; + + public override bool IsReadOnly => this.table.IsReadOnly; + + public override bool IsFixedSize => this.table.IsFixedSize; + + public override bool IsSynchronized => this.table.IsSynchronized; + + public override object SyncRoot => this.table.SyncRoot; + + public override ICollection Keys => this.table.Keys; + + public override ICollection Values => this.table.Values; + + public override object this[object key] + { + get => this.table[key]; + set => this.table[key] = value; + } + + public override void Add(object key, object value) + { + this.table.Add(key, value); + } + + public override void Clear() + { + this.table.Clear(); + } + + public override bool Contains(object key) + { + return this.table.Contains(key); + } + + public override bool ContainsKey(object key) + { + return this.table.ContainsKey(key); + } + + public override bool ContainsValue(object key) + { + return this.table.ContainsValue(key); + } + + public override void CopyTo(Array array, int arrayIndex) + { + this.table.CopyTo(array, arrayIndex); + } + + public override object Clone() + { + return new HashtableWrapper((Hashtable)this.table.Clone()); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.table.GetEnumerator(); + } + + public override IDictionaryEnumerator GetEnumerator() + { + return this.table.GetEnumerator(); + } + + public override void Remove(object key) + { + this.table.Remove(key); + } + } + + /// + /// Helper class used for ServicePointManager.s_ServicePointTable. The goal here is to + /// intercept each new ServicePoint object being added to ServicePointManager.s_ServicePointTable + /// and replace its ConnectionGroupList hashtable field. + /// + private sealed class ServicePointHashtable : HashtableWrapper + { + public ServicePointHashtable(Hashtable table) + : base(table) + { + } + + public override object this[object key] + { + get => base[key]; + set + { + HookServicePoint(value); + base[key] = value; + } + } + } + + /// + /// Helper class used for ServicePoint.m_ConnectionGroupList. The goal here is to + /// intercept each new ConnectionGroup object being added to ServicePoint.m_ConnectionGroupList + /// and replace its m_ConnectionList arraylist field. + /// + private sealed class ConnectionGroupHashtable : HashtableWrapper + { + public ConnectionGroupHashtable(Hashtable table) + : base(table) + { + } + + public override object this[object key] + { + get => base[key]; + set + { + HookConnectionGroup(value); + base[key] = value; + } + } + } + + /// + /// Helper class used to wrap the array list object. This class itself doesn't actually + /// have the array elements, but rather access another array list that's given at + /// construction time. + /// + private class ArrayListWrapper : ArrayList + { + private ArrayList list; + + internal ArrayListWrapper(ArrayList list) + : base() + { + this.list = list; + } + + public override int Capacity + { + get => this.list.Capacity; + set => this.list.Capacity = value; + } + + public override int Count => this.list.Count; + + public override bool IsReadOnly => this.list.IsReadOnly; + + public override bool IsFixedSize => this.list.IsFixedSize; + + public override bool IsSynchronized => this.list.IsSynchronized; + + public override object SyncRoot => this.list.SyncRoot; + + public override object this[int index] + { + get => this.list[index]; + set => this.list[index] = value; + } + + public override int Add(object value) + { + return this.list.Add(value); + } + + public override void AddRange(ICollection c) + { + this.list.AddRange(c); + } + + public override int BinarySearch(object value) + { + return this.list.BinarySearch(value); + } + + public override int BinarySearch(object value, IComparer comparer) + { + return this.list.BinarySearch(value, comparer); + } + + public override int BinarySearch(int index, int count, object value, IComparer comparer) + { + return this.list.BinarySearch(index, count, value, comparer); + } + + public override void Clear() + { + this.list.Clear(); + } + + public override object Clone() + { + return new ArrayListWrapper((ArrayList)this.list.Clone()); + } + + public override bool Contains(object item) + { + return this.list.Contains(item); + } + + public override void CopyTo(Array array) + { + this.list.CopyTo(array); + } + + public override void CopyTo(Array array, int index) + { + this.list.CopyTo(array, index); + } + + public override void CopyTo(int index, Array array, int arrayIndex, int count) + { + this.list.CopyTo(index, array, arrayIndex, count); + } + + public override IEnumerator GetEnumerator() + { + return this.list.GetEnumerator(); + } + + public override IEnumerator GetEnumerator(int index, int count) + { + return this.list.GetEnumerator(index, count); + } + + public override int IndexOf(object value) + { + return this.list.IndexOf(value); + } + + public override int IndexOf(object value, int startIndex) + { + return this.list.IndexOf(value, startIndex); + } + + public override int IndexOf(object value, int startIndex, int count) + { + return this.list.IndexOf(value, startIndex, count); + } + + public override void Insert(int index, object value) + { + this.list.Insert(index, value); + } + + public override void InsertRange(int index, ICollection c) + { + this.list.InsertRange(index, c); + } + + public override int LastIndexOf(object value) + { + return this.list.LastIndexOf(value); + } + + public override int LastIndexOf(object value, int startIndex) + { + return this.list.LastIndexOf(value, startIndex); + } + + public override int LastIndexOf(object value, int startIndex, int count) + { + return this.list.LastIndexOf(value, startIndex, count); + } + + public override void Remove(object value) + { + this.list.Remove(value); + } + + public override void RemoveAt(int index) + { + this.list.RemoveAt(index); + } + + public override void RemoveRange(int index, int count) + { + this.list.RemoveRange(index, count); + } + + public override void Reverse(int index, int count) + { + this.list.Reverse(index, count); + } + + public override void SetRange(int index, ICollection c) + { + this.list.SetRange(index, c); + } + + public override ArrayList GetRange(int index, int count) + { + return this.list.GetRange(index, count); + } + + public override void Sort() + { + this.list.Sort(); + } + + public override void Sort(IComparer comparer) + { + this.list.Sort(comparer); + } + + public override void Sort(int index, int count, IComparer comparer) + { + this.list.Sort(index, count, comparer); + } + + public override object[] ToArray() + { + return this.list.ToArray(); + } + + public override Array ToArray(Type type) + { + return this.list.ToArray(type); + } + + public override void TrimToSize() + { + this.list.TrimToSize(); + } + + public ArrayList Swap() + { + ArrayList old = this.list; + this.list = new ArrayList(old.Capacity); + return old; + } + } + + /// + /// Helper class used for ConnectionGroup.m_ConnectionList. The goal here is to + /// intercept each new Connection object being added to ConnectionGroup.m_ConnectionList + /// and replace its m_WriteList arraylist field. + /// + private sealed class ConnectionArrayList : ArrayListWrapper + { + public ConnectionArrayList(ArrayList list) + : base(list) + { + } + + public override int Add(object value) + { + HookConnection(value); + return base.Add(value); + } + } + + /// + /// Helper class used for Connection.m_WriteList. The goal here is to + /// intercept all new HttpWebRequest objects being added to Connection.m_WriteList + /// and notify the listener about the HttpWebRequest that's about to send a request. + /// It also intercepts all HttpWebRequest objects that are about to get removed from + /// Connection.m_WriteList as they have completed the request. + /// + private sealed class HttpWebRequestArrayList : ArrayListWrapper + { + public HttpWebRequestArrayList(ArrayList list) + : base(list) + { + } + + public override int Add(object value) + { + // Add before firing events so if some user code cancels/aborts the request it will be found in the outstanding list. + int index = base.Add(value); + + if (value is HttpWebRequest request) + { + ProcessRequest(request); + } + + return index; + } + + public override void RemoveAt(int index) + { + object request = this[index]; + + base.RemoveAt(index); + + if (request is HttpWebRequest webRequest) + { + HookOrProcessResult(webRequest); + } + } + + public override void Clear() + { + ArrayList oldList = this.Swap(); + for (int i = 0; i < oldList.Count; i++) + { + if (oldList[i] is HttpWebRequest request) + { + HookOrProcessResult(request); + } + } + } + } + + /// + /// A closure object so our state is available when our callback executes. + /// + private sealed class AsyncCallbackWrapper + { + public AsyncCallbackWrapper(HttpWebRequest request, Activity activity, AsyncCallback originalCallback, long startTimestamp) + { + this.Request = request; + this.Activity = activity; + this.OriginalCallback = originalCallback; + this.StartTimestamp = startTimestamp; + } + + public HttpWebRequest Request { get; } + + public Activity Activity { get; } + + public AsyncCallback OriginalCallback { get; } + + public long StartTimestamp { get; } + + public void AsyncCallback(IAsyncResult asyncResult) + { + object result = resultAccessor(asyncResult); + if (result is Exception || result is HttpWebResponse) + { + ProcessResult( + asyncResult, + this.OriginalCallback, + this.Activity, + result, + forceResponseCopy: false, + this.Request, + this.StartTimestamp); + } + + this.OriginalCallback?.Invoke(asyncResult); + } + } +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs new file mode 100644 index 0000000000..49bd111f4e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs @@ -0,0 +1,45 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Globalization; +using System.Net; + +namespace OpenTelemetry.Instrumentation.Http.Implementation; + +internal static class TelemetryHelper +{ + public static readonly (object, string)[] BoxedStatusCodes = InitializeBoxedStatusCodes(); + + public static object GetBoxedStatusCode(HttpStatusCode statusCode) + { + int intStatusCode = (int)statusCode; + if (intStatusCode >= 100 && intStatusCode < 600) + { + return BoxedStatusCodes[intStatusCode - 100].Item1; + } + + return statusCode; + } + + public static string GetStatusCodeString(HttpStatusCode statusCode) + { + int intStatusCode = (int)statusCode; + if (intStatusCode >= 100 && intStatusCode < 600) + { + return BoxedStatusCodes[intStatusCode - 100].Item2; + } + + return statusCode.ToString(); + } + + private static (object, string)[] InitializeBoxedStatusCodes() + { + var boxedStatusCodes = new (object, string)[500]; + for (int i = 0, c = 100; i < boxedStatusCodes.Length; i++, c++) + { + boxedStatusCodes[i] = (c, c.ToString(CultureInfo.InvariantCulture)); + } + + return boxedStatusCodes; + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj new file mode 100644 index 0000000000..66a1c2ecb0 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -0,0 +1,41 @@ + + + + net8.0;net6.0;netstandard2.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Http instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing + Instrumentation.Http- + 1.8.1 + + enable + + disable + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md new file mode 100644 index 0000000000..b3fec4ebe4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -0,0 +1,362 @@ +# HttpClient and HttpWebRequest instrumentation for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments +[System.Net.Http.HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient) +and +[System.Net.HttpWebRequest](https://docs.microsoft.com/dotnet/api/system.net.httpwebrequest) +and collects metrics and traces about outgoing HTTP requests. + +This component is based on the +[v1.23](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http) +of http semantic conventions. For details on the default set of attributes that +are added, checkout [Traces](#traces) and [Metrics](#metrics) sections below. + +## Steps to enable OpenTelemetry.Instrumentation.Http + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.Http`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.Http +``` + +### Step 2: Enable HTTP Instrumentation at application startup + +HTTP instrumentation must be enabled at application startup. + +#### Traces + +The following example demonstrates adding `HttpClient` instrumentation with the +extension method `.AddHttpClientInstrumentation()` on `TracerProviderBuilder` to +a console application. This example also sets up the OpenTelemetry Console +Exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +Following list of attributes are added by default on activity. See +[http-spans](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http/http-spans.md) +for more details about each individual attribute: + +* `error.type` +* `http.request.method` +* `http.request.method_original` +* `http.response.status_code` +* `network.protocol.version` +* `server.address` +* `server.port` +* `url.full` - By default, the values in the query component of the url are + replaced with the text `Redacted`. For example, `?key1=value1&key2=value2` + becomes `?key1=Redacted&key2=Redacted`. You can disable this redaction by + setting the environment variable + `OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION` to `true`. + +[Enrich Api](#enrich-httpclient-api) can be used if any additional attributes are +required on activity. + +#### Metrics + +The following example demonstrates adding `HttpClient` instrumentation with the +extension method `.AddHttpClientInstrumentation()` on `MeterProviderBuilder` to +a console application. This example also sets up the OpenTelemetry Console +Exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Metrics; + +public class Program +{ + public static void Main(string[] args) + { + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddHttpClientInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +Refer to this [example](../../examples/AspNetCore/Program.cs) to see how to +enable this instrumentation in an ASP.NET core application. + +Refer to this +[example](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md) +to see how to enable this instrumentation in an ASP.NET application. + +Following list of attributes are added by default on +`http.client.request.duration` metric. See +[http-metrics](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http/http-metrics.md) +for more details about each individual attribute. `.NET8.0` and above supports +additional metrics, see [list of metrics produced](#list-of-metrics-produced) for +more details. + +* `error.type` +* `http.request.method` +* `http.response.status_code` +* `network.protocol.version` +* `server.address` +* `server.port` +* `url.scheme` + +#### List of metrics produced + +When the application targets `NETFRAMEWORK`, `.NET6.0` or `.NET7.0`, the +instrumentation emits the following metric: + +| Name | Details | +|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| `http.client.request.duration` | [Specification](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md#metric-httpclientrequestduration) | + +Starting from `.NET8.0`, metrics instrumentation is natively implemented, and +the HttpClient library has incorporated support for [built-in +metrics](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-system-net) +following the OpenTelemetry semantic conventions. The library includes additional +metrics beyond those defined in the +[specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md), +covering additional scenarios for HttpClient users. When the application targets +`.NET8.0` and newer versions, the instrumentation library automatically enables +all `built-in` metrics by default. + +Note that the `AddHttpClientInstrumentation()` extension simplifies the process +of enabling all built-in metrics via a single line of code. Alternatively, for +more granular control over emitted metrics, you can utilize the `AddMeter()` +extension on `MeterProviderBuilder` for meters listed in +[built-in-metrics-system-net](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-system-net). +Using `AddMeter()` for metrics activation eliminates the need to take dependency +on the instrumentation library package and calling +`AddHttpClientInstrumentation()`. + +If you utilize `AddHttpClientInstrumentation()` and wish to exclude unnecessary +metrics, you can utilize +[Views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#drop-an-instrument) +to achieve this. + +> [!NOTE] +> There is no difference in features or emitted metrics when enabling metrics +using `AddMeter()` or `AddHttpClientInstrumentation()` on `.NET8.0` and newer +versions. + +> [!NOTE] +> The `http.client.request.duration` metric is emitted in `seconds` as per the +semantic convention. While the convention [recommends using custom histogram +buckets](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md) +, this feature is not yet available via .NET Metrics API. A +[workaround](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4820) +has been included in OTel SDK starting version `1.6.0` which applies recommended +buckets by default for `http.client.request.duration`. This applies to all +targeted frameworks. + +## Advanced configuration + +### Tracing + +This instrumentation can be configured to change the default behavior by using +`HttpClientTraceInstrumentationOptions`. It is important to note that there are +differences between .NET Framework and newer .NET/.NET Core runtimes which +govern what options are used. On .NET Framework, `HttpClient` uses the +`HttpWebRequest` API. On .NET & .NET Core, `HttpWebRequest` uses the +`HttpClient` API. As such, depending on the runtime, only one half of the +"filter" & "enrich" options are used. + +#### .NET & .NET Core + +##### Filter HttpClient API + +This instrumentation by default collects all the outgoing HTTP requests. It +allows filtering of requests by using the `FilterHttpRequestMessage` function +option. This defines the condition for allowable requests. The filter function +receives the request object (`HttpRequestMessage`) representing the outgoing +request and does not collect telemetry about the request if the filter function +returns `false` or throws an exception. + +The following code snippet shows how to use `FilterHttpRequestMessage` to only +allow GET requests. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation( + // Note: Only called on .NET & .NET Core runtimes. + (options) => options.FilterHttpRequestMessage = + (httpRequestMessage) => + { + // Example: Only collect telemetry about HTTP GET requests. + return httpRequestMessage.Method.Equals(HttpMethod.Get); + }) + .AddConsoleExporter() + .Build(); +``` + +It is important to note that this `FilterHttpRequestMessage` option is specific +to this instrumentation. OpenTelemetry has a concept of a +[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling), +and the `FilterHttpRequestMessage` option does the filtering *after* the Sampler +is invoked. + +##### Enrich HttpClient API + +This instrumentation library provides options that can be used to +enrich the activity with additional information. These actions are called +only when `activity.IsAllDataRequested` is `true`. It contains the activity +itself (which can be enriched) and the actual raw object. + +`HttpClientTraceInstrumentationOptions` provides 3 enrich options: +`EnrichWithHttpRequestMessage`, `EnrichWithHttpResponseMessage` and +`EnrichWithException`. These are based on the raw object that is passed in to +the action to enrich the activity. + +Example: + +```csharp +using System.Net.Http; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation((options) => + { + // Note: Only called on .NET & .NET Core runtimes. + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => + { + activity.SetTag("requestVersion", httpRequestMessage.Version); + }; + // Note: Only called on .NET & .NET Core runtimes. + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => + { + activity.SetTag("responseVersion", httpResponseMessage.Version); + }; + // Note: Called for all runtimes. + options.EnrichWithException = (activity, exception) => + { + activity.SetTag("stackTrace", exception.StackTrace); + }; + }) + .Build(); +``` + +#### .NET Framework + +##### Filter HttpWebRequest API + +This instrumentation by default collects all the outgoing HTTP requests. It +allows filtering of requests by using the `FilterHttpWebRequest` function +option. This defines the condition for allowable requests. The filter function +receives the request object (`HttpWebRequest`) representing the outgoing request +and does not collect telemetry about the request if the filter function returns +`false` or throws an exception. + +The following code snippet shows how to use `FilterHttpWebRequest` to only allow +GET requests. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation( + // Note: Only called on .NET Framework. + (options) => options.FilterHttpWebRequest = + (httpWebRequest) => + { + // Example: Only collect telemetry about HTTP GET requests. + return httpWebRequest.Method.Equals(HttpMethod.Get.Method); + }) + .AddConsoleExporter() + .Build(); +``` + +It is important to note that this `FilterHttpWebRequest` option is specific to +this instrumentation. OpenTelemetry has a concept of a +[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling), +and the `FilterHttpWebRequest` option does the filtering *after* the Sampler is +invoked. + +##### Enrich HttpWebRequest API + +This instrumentation library provides options that can be used to +enrich the activity with additional information. These actions are called +only when `activity.IsAllDataRequested` is `true`. It contains the activity +itself (which can be enriched) and the actual raw object. + +`HttpClientTraceInstrumentationOptions` provides 3 enrich options: +`EnrichWithHttpWebRequest`, `EnrichWithHttpWebResponse` and +`EnrichWithException`. These are based on the raw object that is passed in to +the action to enrich the activity. + +Example: + +```csharp +using System.Net; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation((options) => + { + // Note: Only called on .NET Framework. + options.EnrichWithHttpWebRequest = (activity, httpWebRequest) => + { + activity.SetTag("requestVersion", httpWebRequest.Version); + }; + // Note: Only called on .NET Framework. + options.EnrichWithHttpWebResponse = (activity, httpWebResponse) => + { + activity.SetTag("responseVersion", httpWebResponse.Version); + }; + // Note: Called for all runtimes. + options.EnrichWithException = (activity, exception) => + { + activity.SetTag("stackTrace", exception.StackTrace); + }; + }) + .Build(); +``` + +[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the +general extensibility point to add additional properties to any activity. The +`Enrich` option is specific to this instrumentation, and is provided to get +access to raw request, response, and exception objects. + +#### RecordException + +This instrumentation automatically sets Activity Status to Error if the Http +StatusCode is >= 400. Additionally, `RecordException` feature may be turned on, +to store the exception to the Activity itself as ActivityEvent. + +## Activity duration and http.client.request.duration metric calculation + +`Activity.Duration` and `http.client.request.duration` values represents the +time the underlying client handler takes to complete the request. Completing the +request includes the time up to reading response headers from the network +stream. It doesn't include the time spent reading the response body. + +## Troubleshooting + +This component uses an +[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) +with the name "OpenTelemetry-Instrumentation-Http" for its internal logging. +Please refer to [SDK +troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on +seeing these internal logs. + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/Shared/Configuration/IConfigurationExtensionsLogger.cs b/src/Shared/Configuration/IConfigurationExtensionsLogger.cs new file mode 100644 index 0000000000..0835cf6ff8 --- /dev/null +++ b/src/Shared/Configuration/IConfigurationExtensionsLogger.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +namespace Microsoft.Extensions.Configuration; + +internal interface IConfigurationExtensionsLogger +{ + void LogInvalidConfigurationValue(string key, string value); +} diff --git a/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs b/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs new file mode 100644 index 0000000000..c61377cb19 --- /dev/null +++ b/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs @@ -0,0 +1,136 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Diagnostics; +#if !NETFRAMEWORK && !NETSTANDARD2_0 +using System.Diagnostics.CodeAnalysis; +#endif +using System.Globalization; + +namespace Microsoft.Extensions.Configuration; + +internal static class OpenTelemetryConfigurationExtensions +{ + public delegate bool TryParseFunc( + string value, +#if !NETFRAMEWORK && !NETSTANDARD2_0 + [NotNullWhen(true)] +#endif + out T? parsedValue); + + public static bool TryGetStringValue( + this IConfiguration configuration, + string key, +#if !NETFRAMEWORK && !NETSTANDARD2_0 + [NotNullWhen(true)] +#endif + out string? value) + { + Debug.Assert(configuration != null, "configuration was null"); + + value = configuration![key]; + + return !string.IsNullOrWhiteSpace(value); + } + + public static bool TryGetUriValue( + this IConfiguration configuration, + IConfigurationExtensionsLogger logger, + string key, +#if !NETFRAMEWORK && !NETSTANDARD2_0 + [NotNullWhen(true)] +#endif + out Uri? value) + { + Debug.Assert(logger != null, "logger was null"); + + if (!configuration.TryGetStringValue(key, out var stringValue)) + { + value = null; + return false; + } + + if (!Uri.TryCreate(stringValue, UriKind.Absolute, out value)) + { + logger!.LogInvalidConfigurationValue(key, stringValue!); + return false; + } + + return true; + } + + public static bool TryGetIntValue( + this IConfiguration configuration, + IConfigurationExtensionsLogger logger, + string key, + out int value) + { + Debug.Assert(logger != null, "logger was null"); + + if (!configuration.TryGetStringValue(key, out var stringValue)) + { + value = default; + return false; + } + + if (!int.TryParse(stringValue, NumberStyles.None, CultureInfo.InvariantCulture, out value)) + { + logger!.LogInvalidConfigurationValue(key, stringValue!); + return false; + } + + return true; + } + + public static bool TryGetBoolValue( + this IConfiguration configuration, + IConfigurationExtensionsLogger logger, + string key, + out bool value) + { + Debug.Assert(logger != null, "logger was null"); + + if (!configuration.TryGetStringValue(key, out var stringValue)) + { + value = default; + return false; + } + + if (!bool.TryParse(stringValue, out value)) + { + logger!.LogInvalidConfigurationValue(key, stringValue!); + return false; + } + + return true; + } + + public static bool TryGetValue( + this IConfiguration configuration, + IConfigurationExtensionsLogger logger, + string key, + TryParseFunc tryParseFunc, +#if !NETFRAMEWORK && !NETSTANDARD2_0 + [NotNullWhen(true)] +#endif + out T? value) + { + Debug.Assert(logger != null, "logger was null"); + + if (!configuration.TryGetStringValue(key, out var stringValue)) + { + value = default; + return false; + } + + if (!tryParseFunc(stringValue!, out value)) + { + logger!.LogInvalidConfigurationValue(key, stringValue!); + return false; + } + + return true; + } +} diff --git a/src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs b/src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs new file mode 100644 index 0000000000..8d58d64180 --- /dev/null +++ b/src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationProvider.cs @@ -0,0 +1,85 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Extensions.Configuration.EnvironmentVariables +{ + /// + /// An environment variable based . + /// + internal sealed class EnvironmentVariablesConfigurationProvider : ConfigurationProvider + { + private readonly string _prefix; + private readonly string _normalizedPrefix; + + /// + /// Initializes a new instance. + /// + public EnvironmentVariablesConfigurationProvider() + { + _prefix = string.Empty; + _normalizedPrefix = string.Empty; + } + + /// + /// Initializes a new instance with the specified prefix. + /// + /// A prefix used to filter the environment variables. + public EnvironmentVariablesConfigurationProvider(string? prefix) + { + _prefix = prefix ?? string.Empty; + _normalizedPrefix = Normalize(_prefix); + } + + /// + /// Loads the environment variables. + /// + public override void Load() => + Load(Environment.GetEnvironmentVariables()); + + /// + /// Generates a string representing this provider name and relevant details. + /// + /// The configuration name. + public override string ToString() + => $"{GetType().Name} Prefix: '{_prefix}'"; + + internal void Load(IDictionary envVariables) + { + var data = new Dictionary(StringComparer.OrdinalIgnoreCase); + + IDictionaryEnumerator e = envVariables.GetEnumerator(); + try + { + while (e.MoveNext()) + { + string key = (string)e.Entry.Key; + string? value = (string?)e.Entry.Value; + AddIfNormalizedKeyMatchesPrefix(data, Normalize(key), value); + } + } + finally + { + (e as IDisposable)?.Dispose(); + } + + Data = data; + } + + private void AddIfNormalizedKeyMatchesPrefix(Dictionary data, string normalizedKey, string? value) + { + if (normalizedKey.StartsWith(_normalizedPrefix, StringComparison.OrdinalIgnoreCase)) + { + data[normalizedKey.Substring(_normalizedPrefix.Length)] = value; + } + } + + private static string Normalize(string key) => key.Replace("__", ConfigurationPath.KeyDelimiter); + } +} diff --git a/src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs b/src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs new file mode 100644 index 0000000000..2785b21747 --- /dev/null +++ b/src/Shared/EnvironmentVariables/EnvironmentVariablesConfigurationSource.cs @@ -0,0 +1,29 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +namespace Microsoft.Extensions.Configuration.EnvironmentVariables +{ + /// + /// Represents environment variables as an . + /// + internal sealed class EnvironmentVariablesConfigurationSource : IConfigurationSource + { + /// + /// A prefix used to filter environment variables. + /// + public string? Prefix { get; set; } + + /// + /// Builds the for this source. + /// + /// The . + /// A + public IConfigurationProvider Build(IConfigurationBuilder builder) + { + return new EnvironmentVariablesConfigurationProvider(Prefix); + } + } +} diff --git a/src/Shared/EnvironmentVariables/EnvironmentVariablesExtensions.cs b/src/Shared/EnvironmentVariables/EnvironmentVariablesExtensions.cs new file mode 100644 index 0000000000..5b97e90ce7 --- /dev/null +++ b/src/Shared/EnvironmentVariables/EnvironmentVariablesExtensions.cs @@ -0,0 +1,52 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#nullable enable + +using System; +using Microsoft.Extensions.Configuration.EnvironmentVariables; + +namespace Microsoft.Extensions.Configuration +{ + /// + /// Extension methods for registering with . + /// + internal static class EnvironmentVariablesExtensions + { + /// + /// Adds an that reads configuration values from environment variables. + /// + /// The to add to. + /// The . + public static IConfigurationBuilder AddEnvironmentVariables(this IConfigurationBuilder configurationBuilder) + { + configurationBuilder.Add(new EnvironmentVariablesConfigurationSource()); + return configurationBuilder; + } + + /// + /// Adds an that reads configuration values from environment variables + /// with a specified prefix. + /// + /// The to add to. + /// The prefix that environment variable names must start with. The prefix will be removed from the environment variable names. + /// The . + public static IConfigurationBuilder AddEnvironmentVariables( + this IConfigurationBuilder configurationBuilder, + string? prefix) + { + configurationBuilder.Add(new EnvironmentVariablesConfigurationSource { Prefix = prefix }); + return configurationBuilder; + } + + /// + /// Adds an that reads configuration values from environment variables. + /// + /// The to add to. + /// Configures the source. + /// The . + public static IConfigurationBuilder AddEnvironmentVariables(this IConfigurationBuilder builder, Action? configureSource) + => builder.Add(configureSource); + } +} diff --git a/src/Shared/Options/DelegatingOptionsFactory.cs b/src/Shared/Options/DelegatingOptionsFactory.cs new file mode 100644 index 0000000000..1b8fe62188 --- /dev/null +++ b/src/Shared/Options/DelegatingOptionsFactory.cs @@ -0,0 +1,120 @@ +// (Turns off StyleCop analysis in this file.) +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/* + Note: This class was copied from + https://github.com/dotnet/runtime/blob/e13e7388dedc6672381e61592c2e74385fe781a5/src/libraries/Microsoft.Extensions.Options/src/OptionsFactory.cs + and then modified to have delegate features needed by the SDK. In the future if + we take a dependency on Microsoft.Extensions.Options v5.0.0 (or greater), much + of this can be removed in favor of the "CreateInstance" API added in 5: + https://learn.microsoft.com/dotnet/api/microsoft.extensions.options.optionsfactory-1.createinstance?view=dotnet-plat-ext-5.0. + See https://github.com/open-telemetry/opentelemetry-dotnet/pull/4093 for an + example of how that works. +*/ + +#nullable enable + +using System.Diagnostics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Options; + +/// +/// Implementation of . +/// +/// The type of options being requested. +#if NET6_0_OR_GREATER +internal sealed class DelegatingOptionsFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : +#else +internal sealed class DelegatingOptionsFactory : +#endif + IOptionsFactory + where TOptions : class +{ + private readonly Func optionsFactoryFunc; + private readonly IConfiguration configuration; + private readonly IConfigureOptions[] _setups; + private readonly IPostConfigureOptions[] _postConfigures; + private readonly IValidateOptions[] _validations; + + /// + /// Initializes a new instance with the specified options configurations. + /// + /// Factory delegate used to create instances. + /// . + /// The configuration actions to run. + /// The initialization actions to run. + /// The validations to run. + public DelegatingOptionsFactory( + Func optionsFactoryFunc, + IConfiguration configuration, + IEnumerable> setups, + IEnumerable> postConfigures, + IEnumerable> validations) + { + // The default DI container uses arrays under the covers. Take advantage of this knowledge + // by checking for an array and enumerate over that, so we don't need to allocate an enumerator. + // When it isn't already an array, convert it to one, but don't use System.Linq to avoid pulling Linq in to + // small trimmed applications. + + Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); + Debug.Assert(configuration != null, "configuration was null"); + + this.optionsFactoryFunc = optionsFactoryFunc!; + this.configuration = configuration!; + _setups = setups as IConfigureOptions[] ?? new List>(setups).ToArray(); + _postConfigures = postConfigures as IPostConfigureOptions[] ?? new List>(postConfigures).ToArray(); + _validations = validations as IValidateOptions[] ?? new List>(validations).ToArray(); + } + + /// + /// Returns a configured instance with the given . + /// + /// The name of the instance to create. + /// The created instance with the given . + /// One or more return failed when validating the instance been created. + /// The does not have a public parameterless constructor or is . + public TOptions Create(string name) + { + TOptions options = this.optionsFactoryFunc(this.configuration, name); + + foreach (IConfigureOptions setup in _setups) + { + if (setup is IConfigureNamedOptions namedSetup) + { + namedSetup.Configure(name, options); + } + else if (name == Options.DefaultName) + { + setup.Configure(options); + } + } + foreach (IPostConfigureOptions post in _postConfigures) + { + post.PostConfigure(name, options); + } + + if (_validations.Length > 0) + { + var failures = new List(); + foreach (IValidateOptions validate in _validations) + { + ValidateOptionsResult result = validate.Validate(name, options); + if (result is not null && result.Failed) + { + failures.AddRange(result.Failures); + } + } + if (failures.Count > 0) + { + throw new OptionsValidationException(name, typeof(TOptions), failures); + } + } + + return options; + } +} diff --git a/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs new file mode 100644 index 0000000000..69c7b6c3b6 --- /dev/null +++ b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs @@ -0,0 +1,83 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Diagnostics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; + +namespace Microsoft.Extensions.DependencyInjection; + +internal static class DelegatingOptionsFactoryServiceCollectionExtensions +{ +#if NET6_0_OR_GREATER + public static IServiceCollection RegisterOptionsFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( +#else + public static IServiceCollection RegisterOptionsFactory( +#endif + this IServiceCollection services, + Func optionsFactoryFunc) + where T : class + { + Debug.Assert(services != null, "services was null"); + Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); + + services!.TryAddSingleton>(sp => + { + return new DelegatingOptionsFactory( + (c, n) => optionsFactoryFunc!(c), + sp.GetRequiredService(), + sp.GetServices>(), + sp.GetServices>(), + sp.GetServices>()); + }); + + return services!; + } + +#if NET6_0_OR_GREATER + public static IServiceCollection RegisterOptionsFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( +#else + public static IServiceCollection RegisterOptionsFactory( +#endif + this IServiceCollection services, + Func optionsFactoryFunc) + where T : class + { + Debug.Assert(services != null, "services was null"); + Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); + + services!.TryAddSingleton>(sp => + { + return new DelegatingOptionsFactory( + (c, n) => optionsFactoryFunc!(sp, c, n), + sp.GetRequiredService(), + sp.GetServices>(), + sp.GetServices>(), + sp.GetServices>()); + }); + + return services!; + } + +#if NET6_0_OR_GREATER + public static IServiceCollection DisableOptionsReloading<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( +#else + public static IServiceCollection DisableOptionsReloading( +#endif + this IServiceCollection services) + where T : class + { + Debug.Assert(services != null, "services was null"); + + services!.TryAddSingleton, SingletonOptionsManager>(); + services!.TryAddScoped, SingletonOptionsManager>(); + + return services!; + } +} diff --git a/src/Shared/Options/SingletonOptionsManager.cs b/src/Shared/Options/SingletonOptionsManager.cs new file mode 100644 index 0000000000..c1807183e3 --- /dev/null +++ b/src/Shared/Options/SingletonOptionsManager.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + +namespace Microsoft.Extensions.Options; + +#if NET6_0_OR_GREATER +internal sealed class SingletonOptionsManager<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : IOptionsMonitor, IOptionsSnapshot +#else +internal sealed class SingletonOptionsManager : IOptionsMonitor, IOptionsSnapshot +#endif + where TOptions : class +{ + private readonly TOptions instance; + + public SingletonOptionsManager(IOptions options) + { + this.instance = options.Value; + } + + public TOptions CurrentValue => this.instance; + + public TOptions Value => this.instance; + + public TOptions Get(string? name) => this.instance; + + public IDisposable? OnChange(Action listener) + => NoopChangeNotification.Instance; + + private sealed class NoopChangeNotification : IDisposable + { + private NoopChangeNotification() + { + } + + public static NoopChangeNotification Instance { get; } = new(); + + public void Dispose() + { + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelper.cs b/src/Shared/RequestDataHelper.cs similarity index 62% rename from src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelper.cs rename to src/Shared/RequestDataHelper.cs index ef5a346f98..2325165a70 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/RequestDataHelper.cs +++ b/src/Shared/RequestDataHelper.cs @@ -1,14 +1,21 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Web; using OpenTelemetry.Trace; +#pragma warning restore IDE0005 // Using directive is unnecessary. -namespace OpenTelemetry.Instrumentation.AspNet.Implementation; +namespace OpenTelemetry.Internal; internal sealed class RequestDataHelper { @@ -20,14 +27,17 @@ internal sealed class RequestDataHelper private static readonly char[] SplitChars = new[] { ',' }; - // List of known HTTP methods as per spec. +#if NET8_0_OR_GREATER + private readonly FrozenDictionary knownHttpMethods; +#else private readonly Dictionary knownHttpMethods; +#endif public RequestDataHelper() { var suppliedKnownMethods = Environment.GetEnvironmentVariable(KnownHttpMethodsEnvironmentVariable) ?.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries); - this.knownHttpMethods = suppliedKnownMethods?.Length > 0 + var knownMethodSet = suppliedKnownMethods?.Length > 0 ? suppliedKnownMethods.ToDictionary(x => x, x => x, StringComparer.OrdinalIgnoreCase) : new(StringComparer.OrdinalIgnoreCase) { @@ -41,11 +51,12 @@ public RequestDataHelper() ["PATCH"] = "PATCH", ["CONNECT"] = "CONNECT", }; - } - public static string GetHttpProtocolVersion(HttpRequest request) - { - return GetHttpProtocolVersion(request.ServerVariables["SERVER_PROTOCOL"]); +#if NET8_0_OR_GREATER + this.knownHttpMethods = knownMethodSet.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase); +#else + this.knownHttpMethods = knownMethodSet; +#endif } public void SetHttpMethodTag(Activity activity, string originalHttpMethod) @@ -66,6 +77,28 @@ public string GetNormalizedHttpMethod(string method) : OtherHttpMethod; } + public void SetActivityDisplayName(Activity activity, string originalHttpMethod, string? httpRoute = null) + { + // https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#name + + var normalizedHttpMethod = this.GetNormalizedHttpMethod(originalHttpMethod); + var namePrefix = normalizedHttpMethod == "_OTHER" ? "HTTP" : normalizedHttpMethod; + + activity.DisplayName = string.IsNullOrEmpty(httpRoute) ? namePrefix : $"{namePrefix} {httpRoute}"; + } + + internal static string GetHttpProtocolVersion(Version httpVersion) + { + return httpVersion switch + { + { Major: 1, Minor: 0 } => "1.0", + { Major: 1, Minor: 1 } => "1.1", + { Major: 2, Minor: 0 } => "2", + { Major: 3, Minor: 0 } => "3", + _ => httpVersion.ToString(), + }; + } + internal static string GetHttpProtocolVersion(string protocol) { return protocol switch diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 1b5143a588..9c68f55714 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -21,6 +21,7 @@ + diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/CustomTextMapPropagator.cs b/test/OpenTelemetry.Contrib.Tests.Shared/CustomTextMapPropagator.cs new file mode 100644 index 0000000000..b331baeb4b --- /dev/null +++ b/test/OpenTelemetry.Contrib.Tests.Shared/CustomTextMapPropagator.cs @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +#pragma warning disable IDE0005 // Using directive is unnecessary. +using System; +using System.Collections.Generic; +using System.Diagnostics; +using OpenTelemetry.Context.Propagation; +#pragma warning restore IDE0005 // Using directive is unnecessary. + +namespace OpenTelemetry.Tests; + +internal sealed class CustomTextMapPropagator : TextMapPropagator +{ + 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 default; + } + + 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); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs index e1beb3a377..5d4c7cbf89 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs @@ -2,13 +2,24 @@ // SPDX-License-Identifier: Apache-2.0 using System; -using OpenTelemetry.Instrumentation.AspNet.Implementation; +using System.Collections.Generic; +using OpenTelemetry.Internal; using Xunit; namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class RequestDataHelperTests : IDisposable { + public static IEnumerable MappingVersionProtocolToVersionData => + new List + { + new object[] { new Version(1, 0), "1.0" }, + new object[] { new Version(1, 1), "1.1" }, + new object[] { new Version(2, 0), "2" }, + new object[] { new Version(3, 0), "3" }, + new object[] { new Version(7, 6, 5), "7.6.5" }, + }; + [Theory] [InlineData("GET", "GET")] [InlineData("POST", "POST")] @@ -60,6 +71,14 @@ public void MappingProtocolToVersion(string protocolVersion, string expected) Assert.Equal(expected, actual); } + [Theory] + [MemberData(nameof(MappingVersionProtocolToVersionData))] + public void MappingVersionProtocolToVersion(Version protocolVersion, string expected) + { + var actual = RequestDataHelper.GetHttpProtocolVersion(protocolVersion); + Assert.Equal(expected, actual); + } + public void Dispose() { // Clean up after tests that set environment variables. diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs new file mode 100644 index 0000000000..7651010ada --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs @@ -0,0 +1,167 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +/* +BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2) +Intel Core i7-8850H CPU 2.60GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +.NET SDK=7.0.302 + [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 + + +| Method | EnableInstrumentation | Mean | Error | StdDev | Gen0 | Allocated | +|------------------ |---------------------- |---------:|--------:|--------:|-------:|----------:| +| HttpClientRequest | None | 161.0 us | 1.27 us | 0.99 us | 0.4883 | 2.45 KB | +| HttpClientRequest | Traces | 173.1 us | 1.65 us | 1.54 us | 0.4883 | 4.26 KB | +| HttpClientRequest | Metrics | 165.8 us | 1.33 us | 1.18 us | 0.7324 | 3.66 KB | +| HttpClientRequest | Traces, Metrics | 175.6 us | 1.96 us | 1.83 us | 0.4883 | 4.28 KB | +*/ + +namespace OpenTelemetry.Instrumentation.Http.Benchmark.Instrumentation; + +public class HttpClientInstrumentationBenchmarks +{ + private static readonly Uri Url = new("http://localhost:5000"); + + private HttpClient httpClient; + private WebApplication app; + private TracerProvider tracerProvider; + private MeterProvider meterProvider; + + [Flags] + public enum EnableInstrumentationOption + { + /// + /// Instrumentation is not enabled for any signal. + /// + None = 0, + + /// + /// Instrumentation is enabled only for Traces. + /// + Traces = 1, + + /// + /// Instrumentation is enabled only for Metrics. + /// + Metrics = 2, + } + + [Params(0, 1, 2, 3)] + public EnableInstrumentationOption EnableInstrumentation { get; set; } + + [GlobalSetup(Target = nameof(HttpClientRequest))] + public void HttpClientRequestGlobalSetup() + { + if (this.EnableInstrumentation == EnableInstrumentationOption.None) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .Build(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + var exportedItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems, metricReaderOptions => + { + metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1000; + }) + .Build(); + } + else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && + this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .Build(); + + var exportedItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems, metricReaderOptions => + { + metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1000; + }) + .Build(); + } + } + + [GlobalCleanup(Target = nameof(HttpClientRequest))] + public void HttpClientRequestGlobalCleanup() + { + if (this.EnableInstrumentation == EnableInstrumentationOption.None) + { + this.httpClient.Dispose(); +#pragma warning disable CA2012 // Use ValueTasks correctly + this.app.DisposeAsync().GetAwaiter().GetResult(); +#pragma warning restore CA2012 // Use ValueTasks correctly + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) + { + this.httpClient.Dispose(); +#pragma warning disable CA2012 // Use ValueTasks correctly + this.app.DisposeAsync().GetAwaiter().GetResult(); +#pragma warning restore CA2012 // Use ValueTasks correctly + this.tracerProvider.Dispose(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) + { + this.httpClient.Dispose(); +#pragma warning disable CA2012 // Use ValueTasks correctly + this.app.DisposeAsync().GetAwaiter().GetResult(); +#pragma warning restore CA2012 // Use ValueTasks correctly + this.meterProvider.Dispose(); + } + else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && + this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) + { + this.httpClient.Dispose(); +#pragma warning disable CA2012 // Use ValueTasks correctly + this.app.DisposeAsync().GetAwaiter().GetResult(); +#pragma warning restore CA2012 // Use ValueTasks correctly + this.tracerProvider.Dispose(); + this.meterProvider.Dispose(); + } + } + + [Benchmark] + public async Task HttpClientRequest() + { + var httpResponse = await this.httpClient.GetAsync(Url).ConfigureAwait(false); + httpResponse.EnsureSuccessStatusCode(); + } + + private void StartWebApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + var app = builder.Build(); + app.MapGet("/", async context => await context.Response.WriteAsync($"Hello World!")); + app.RunAsync(); + + this.app = app; + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/OpenTelemetry.Instrumentation.Http.Benchmark.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmark/OpenTelemetry.Instrumentation.Http.Benchmark.csproj new file mode 100644 index 0000000000..ff8d777e89 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmark/OpenTelemetry.Instrumentation.Http.Benchmark.csproj @@ -0,0 +1,21 @@ + + + Exe + + $(SupportedNetTargets) + enable + disable + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/Program.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmark/Program.cs new file mode 100644 index 0000000000..a639f15c91 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmark/Program.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Running; + +namespace OpenTelemetry.Instrumentation.Http.Benchmark; + +internal class Program +{ + private static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md b/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md new file mode 100644 index 0000000000..b855fb74fd --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md @@ -0,0 +1,11 @@ +# OpenTelemetry GenevaExporter Benchmarks + +Navigate to `./test/OpenTelemetry.Instrumentation.Http.Benchmark` directory and run +the following command: + +```sh +dotnet run -c Release -f net8.0 -- -m +`` + +Then choose the benchmark class that you want to run by entering the required +option number from the list of options shown on the Console window. diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/EventSourceTest.cs new file mode 100644 index 0000000000..0673de7555 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/EventSourceTest.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.Http.Implementation; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +public class EventSourceTest +{ + [Fact] + public void EventSourceTest_HttpInstrumentationEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(HttpInstrumentationEventSource.Log); + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs new file mode 100644 index 0000000000..f3610c23e4 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -0,0 +1,820 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.Extensions.Configuration; + +#if NETFRAMEWORK +using System.Net.Http; + +#endif +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.Http.Implementation; +using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +public partial class HttpClientTests : IDisposable +{ + private readonly ITestOutputHelper output; + private readonly IDisposable serverLifeTime; + private readonly string host; + private readonly int port; + private readonly string url; + + public HttpClientTests(ITestOutputHelper output) + { + this.output = output; + + this.serverLifeTime = TestHttpServer.RunServer( + (ctx) => + { + string traceparent = ctx.Request.Headers["traceparent"]; + string custom_traceparent = ctx.Request.Headers["custom_traceparent"]; + if ((ctx.Request.Headers["contextRequired"] == null + || bool.Parse(ctx.Request.Headers["contextRequired"])) + && + (string.IsNullOrWhiteSpace(traceparent) + && string.IsNullOrWhiteSpace(custom_traceparent))) + { + ctx.Response.StatusCode = 500; + ctx.Response.StatusDescription = "Missing trace context"; + } + else if (ctx.Request.Url.PathAndQuery.Contains("500")) + { + ctx.Response.StatusCode = 500; + } + else if (ctx.Request.Url.PathAndQuery.Contains("redirect")) + { + ctx.Response.RedirectLocation = "/"; + ctx.Response.StatusCode = 302; + } + else if (ctx.Request.Headers["responseCode"] != null) + { + ctx.Response.StatusCode = int.Parse(ctx.Request.Headers["responseCode"]); + } + else + { + ctx.Response.StatusCode = 200; + } + + ctx.Response.OutputStream.Close(); + }, + out var host, + out var port); + + this.host = host; + this.port = port; + this.url = $"http://{host}:{port}/"; + + this.output.WriteLine($"HttpServer started: {this.url}"); + } + + [Fact] + public void AddHttpClientInstrumentation_NamedOptions() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Instrumentation2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddHttpClientInstrumentation() + .AddHttpClientInstrumentation("Instrumentation2", configureHttpClientTraceInstrumentationOptions: null) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + + [Fact] + public void AddHttpClientInstrumentation_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddHttpClientInstrumentation()); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task InjectsHeadersAsync(bool shouldEnrich) + { + var exportedItems = new List(); + + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod("GET"), + }; + + using var parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + parent.TraceStateString = "k1=v1,k2=v2"; + parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; + + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => + { + if (shouldEnrich) + { + o.EnrichWithHttpWebRequest = (activity, httpWebRequest) => + { + activity.SetTag("enrichedWithHttpWebRequest", "yes"); + }; + + o.EnrichWithHttpWebResponse = (activity, httpWebResponse) => + { + activity.SetTag("enrichedWithHttpWebResponse", "yes"); + }; + + o.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => + { + activity.SetTag("enrichedWithHttpRequestMessage", "yes"); + }; + + o.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => + { + activity.SetTag("enrichedWithHttpResponseMessage", "yes"); + }; + } + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var c = new HttpClient(); + await c.SendAsync(request); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(ActivityKind.Client, activity.Kind); + Assert.Equal(parent.TraceId, activity.Context.TraceId); + Assert.Equal(parent.SpanId, activity.ParentSpanId); + Assert.NotEqual(parent.SpanId, activity.Context.SpanId); + Assert.NotEqual(default, activity.Context.SpanId); + +#if NETFRAMEWORK + // Note: On .NET Framework a HttpWebRequest is created and enriched + // not the HttpRequestMessage passed to HttpClient. + Assert.Empty(request.Headers); +#else + Assert.True(request.Headers.TryGetValues("traceparent", out var traceparents)); + Assert.True(request.Headers.TryGetValues("tracestate", out var tracestates)); + Assert.Single(traceparents); + Assert.Single(tracestates); + + Assert.Equal($"00-{activity.Context.TraceId}-{activity.Context.SpanId}-01", traceparents.Single()); + Assert.Equal("k1=v1,k2=v2", tracestates.Single()); +#endif + +#if NETFRAMEWORK + if (shouldEnrich) + { + Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpWebRequest").FirstOrDefault().Value); + Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpWebResponse").FirstOrDefault().Value); + } + else + { + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpWebRequest"); + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpWebResponse"); + } + + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpRequestMessage"); + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpResponseMessage"); +#else + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpWebRequest"); + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpWebResponse"); + + if (shouldEnrich) + { + Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpRequestMessage").FirstOrDefault().Value); + Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpResponseMessage").FirstOrDefault().Value); + } + else + { + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpRequestMessage"); + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enrichedWithHttpResponseMessage"); + } +#endif + } + + [Fact] + public async Task InjectsHeadersAsync_CustomFormat() + { + var propagator = new CustomTextMapPropagator(); + propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + + var exportedItems = new List(); + + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod("GET"), + }; + + using var parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + parent.TraceStateString = "k1=v1,k2=v2"; + parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; + + Sdk.SetDefaultTextMapPropagator(propagator); + + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var c = new HttpClient(); + await c.SendAsync(request); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(ActivityKind.Client, activity.Kind); + Assert.Equal(parent.TraceId, activity.Context.TraceId); + Assert.Equal(parent.SpanId, activity.ParentSpanId); + Assert.NotEqual(parent.SpanId, activity.Context.SpanId); + Assert.NotEqual(default, activity.Context.SpanId); + +#if NETFRAMEWORK + // Note: On .NET Framework a HttpWebRequest is created and enriched + // not the HttpRequestMessage passed to HttpClient. + Assert.Empty(request.Headers); +#else + Assert.True(request.Headers.TryGetValues("custom_traceParent", out var traceParents)); + Assert.True(request.Headers.TryGetValues("custom_traceState", out var traceStates)); + Assert.Single(traceParents); + Assert.Single(traceStates); + + Assert.Equal($"00/{activity.Context.TraceId}/{activity.Context.SpanId}/01", traceParents.Single()); + Assert.Equal("k1=v1,k2=v2", traceStates.Single()); +#endif + + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + public async Task RespectsSuppress() + { + try + { + var propagator = new CustomTextMapPropagator(); + propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + + var exportedItems = new List(); + + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod("GET"), + }; + + using var parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + parent.TraceStateString = "k1=v1,k2=v2"; + parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; + + Sdk.SetDefaultTextMapPropagator(propagator); + + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var c = new HttpClient(); + using (SuppressInstrumentationScope.Begin()) + { + await c.SendAsync(request); + } + } + + // If suppressed, activity is not emitted and + // propagation is also not performed. + Assert.Empty(exportedItems); + Assert.False(request.Headers.Contains("custom_traceParent")); + Assert.False(request.Headers.Contains("custom_traceState")); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + [Fact] + public async Task ExportsSpansCreatedForRetries() + { + var exportedItems = new List(); + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod("GET"), + }; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + int maxRetries = 3; + using var clientHandler = new HttpClientHandler(); + using var retryHandler = new RetryHandler(clientHandler, maxRetries); + using var httpClient = new HttpClient(retryHandler); + await httpClient.SendAsync(request); + + // number of exported spans should be 3(maxRetries) + Assert.Equal(maxRetries, exportedItems.Count); + + var spanid1 = exportedItems[0].SpanId; + var spanid2 = exportedItems[1].SpanId; + var spanid3 = exportedItems[2].SpanId; + + // Validate span ids are different + Assert.NotEqual(spanid1, spanid2); + Assert.NotEqual(spanid3, spanid1); + Assert.NotEqual(spanid2, spanid3); + } + + [Theory] + [InlineData("CONNECT", "CONNECT", null)] + [InlineData("DELETE", "DELETE", null)] + [InlineData("GET", "GET", null)] + [InlineData("PUT", "PUT", null)] + [InlineData("HEAD", "HEAD", null)] + [InlineData("OPTIONS", "OPTIONS", null)] + [InlineData("PATCH", "PATCH", null)] + [InlineData("POST", "POST", null)] + [InlineData("TRACE", "TRACE", null)] + [InlineData("Delete", "DELETE", "Delete")] +#if NETFRAMEWORK + [InlineData("Connect", "CONNECT", null)]// HTTP Client converts Connect to its canonical form (Connect). Expected original method is null. + [InlineData("Get", "GET", null)] // HTTP Client converts Get to its canonical form (GET). Expected original method is null. + [InlineData("Put", "PUT", null)] // HTTP Client converts Put to its canonical form (PUT). Expected original method is null. + [InlineData("Head", "HEAD", null)] // HTTP Client converts Head to its canonical form (HEAD). Expected original method is null. + [InlineData("Post", "POST", null)] // HTTP Client converts Post to its canonical form (POST). Expected original method is null. +#else + [InlineData("Connect", "CONNECT", "Connect")] + [InlineData("Get", "GET", "Get")] + [InlineData("Put", "PUT", "Put")] + [InlineData("Head", "HEAD", "Head")] + [InlineData("Post", "POST", "Post")] +#endif + [InlineData("Options", "OPTIONS", "Options")] + [InlineData("Patch", "PATCH", "Patch")] + [InlineData("Trace", "TRACE", "Trace")] + [InlineData("CUSTOM", "_OTHER", "CUSTOM")] + public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMethod, string expectedMethod, string expectedOriginalMethod) + { + var exportedItems = new List(); + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod(originalMethod), + }; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + using var httpClient = new HttpClient(); + + try + { + await httpClient.SendAsync(request); + } + catch + { + // ignore error. + } + + Assert.Single(exportedItems); + + var activity = exportedItems[0]; + + if (originalMethod.Equals(expectedMethod, StringComparison.OrdinalIgnoreCase)) + { + Assert.Equal(expectedMethod, activity.DisplayName); + } + else + { + Assert.Equal("HTTP", activity.DisplayName); + } + + Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); + Assert.Equal(expectedOriginalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal)); + } + + [Theory] + [InlineData("CONNECT", "CONNECT")] + [InlineData("DELETE", "DELETE")] + [InlineData("GET", "GET")] + [InlineData("PUT", "PUT")] + [InlineData("HEAD", "HEAD")] + [InlineData("OPTIONS", "OPTIONS")] + [InlineData("PATCH", "PATCH")] + [InlineData("Get", "GET")] + [InlineData("POST", "POST")] + [InlineData("TRACE", "TRACE")] + [InlineData("Trace", "TRACE")] + [InlineData("CUSTOM", "_OTHER")] + public async Task HttpRequestMethodIsSetonRequestDurationMetricAsPerSpec(string originalMethod, string expectedMethod) + { + var metricItems = new List(); + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod(originalMethod), + }; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(metricItems) + .Build(); + + using var httpClient = new HttpClient(); + + try + { + await httpClient.SendAsync(request); + } + catch + { + // ignore error. + } + + meterProvider.Dispose(); + + var metric = metricItems.FirstOrDefault(m => m.Name == "http.client.request.duration"); + + Assert.NotNull(metric); + + var metricPoints = new List(); + foreach (var p in metric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + Assert.Single(metricPoints); + var mp = metricPoints[0]; + + // Inspect Metric Attributes + var attributes = new Dictionary(); + foreach (var tag in mp.Tags) + { + attributes[tag.Key] = tag.Value; + } + + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == expectedMethod); + + Assert.DoesNotContain(attributes, t => t.Key == SemanticConventions.AttributeHttpRequestMethodOriginal); + } + + [Fact] + public async Task RedirectTest() + { + var exportedItems = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var c = new HttpClient(); + await c.GetAsync(new Uri($"{this.url}redirect")); + } + +#if NETFRAMEWORK + // Note: HttpWebRequest automatically handles redirects and reuses + // the same instance which is patched reflectively. There isn't a + // good way to produce two spans when redirecting that we have + // found. For now, this is not supported. + + Assert.Single(exportedItems); + Assert.Contains(exportedItems[0].TagObjects, t => t.Key == "http.response.status_code" && (int)t.Value == 200); +#else + Assert.Equal(2, exportedItems.Count); + Assert.Contains(exportedItems[0].TagObjects, t => t.Key == "http.response.status_code" && (int)t.Value == 302); + Assert.Contains(exportedItems[1].TagObjects, t => t.Key == "http.response.status_code" && (int)t.Value == 200); +#endif + } + + [Fact] + public async void RequestNotCollectedWhenInstrumentationFilterApplied() + { + var exportedItems = new List(); + + bool httpWebRequestFilterApplied = false; + bool httpRequestMessageFilterApplied = false; + + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation( + opt => + { + opt.FilterHttpWebRequest = (req) => + { + httpWebRequestFilterApplied = true; + return !req.RequestUri.OriginalString.Contains(this.url); + }; + opt.FilterHttpRequestMessage = (req) => + { + httpRequestMessageFilterApplied = true; + return !req.RequestUri.OriginalString.Contains(this.url); + }; + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var c = new HttpClient(); + await c.GetAsync(new Uri(this.url)); + } + +#if NETFRAMEWORK + Assert.True(httpWebRequestFilterApplied); + Assert.False(httpRequestMessageFilterApplied); +#else + Assert.False(httpWebRequestFilterApplied); + Assert.True(httpRequestMessageFilterApplied); +#endif + + Assert.Empty(exportedItems); + } + + [Fact] + public async void RequestNotCollectedWhenInstrumentationFilterThrowsException() + { + var exportedItems = new List(); + + using (Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation( + (opt) => + { + opt.FilterHttpWebRequest = (req) => throw new Exception("From InstrumentationFilter"); + opt.FilterHttpRequestMessage = (req) => throw new Exception("From InstrumentationFilter"); + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var c = new HttpClient(); + using var inMemoryEventListener = new InMemoryEventListener(HttpInstrumentationEventSource.Log); + await c.GetAsync(new Uri(this.url)); + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 4)); + } + + Assert.Empty(exportedItems); + } + + [Fact] + public async Task ReportsExceptionEventForNetworkFailuresWithGetAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetAsync(new Uri("https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/")); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + } + + [Fact] + public async Task DoesNotReportExceptionEventOnErrorResponseWithGetAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetAsync(new Uri($"{this.url}500")); + } + catch + { + exceptionThrown = true; + } + + // Exception is not thrown and not collected as event + Assert.False(exceptionThrown); + Assert.Empty(exportedItems[0].Events); + } + + [Fact] + public async Task DoesNotReportExceptionEventOnErrorResponseWithGetStringAsync() + { + var exportedItems = new List(); + bool exceptionThrown = false; + using var request = new HttpRequestMessage + { + RequestUri = new Uri($"{this.url}500"), + Method = new HttpMethod("GET"), + }; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetStringAsync(new Uri($"{this.url}500")); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and not collected as event + Assert.True(exceptionThrown); + Assert.Empty(exportedItems[0].Events); + } + + [Theory] + [InlineData("?a", "?a", false)] + [InlineData("?a=bdjdjh", "?a=Redacted", false)] + [InlineData("?a=b&", "?a=Redacted&", false)] + [InlineData("?c=b&", "?c=Redacted&", false)] + [InlineData("?c=a", "?c=Redacted", false)] + [InlineData("?a=b&c", "?a=Redacted&c", false)] + [InlineData("?a=b&c=1123456&", "?a=Redacted&c=Redacted&", false)] + [InlineData("?a=b&c=1&a1", "?a=Redacted&c=Redacted&a1", false)] + [InlineData("?a=ghgjgj&c=1deedd&a1=", "?a=Redacted&c=Redacted&a1=Redacted", false)] + [InlineData("?a=b&c=11&a1=&", "?a=Redacted&c=Redacted&a1=Redacted&", false)] + [InlineData("?c&c&c&", "?c&c&c&", false)] + [InlineData("?a&a&a&a", "?a&a&a&a", false)] + [InlineData("?&&&&&&&", "?&&&&&&&", false)] + [InlineData("?c", "?c", false)] + [InlineData("?a", "?a", true)] + [InlineData("?a=bdfdfdf", "?a=bdfdfdf", true)] + [InlineData("?a=b&", "?a=b&", true)] + [InlineData("?c=b&", "?c=b&", true)] + [InlineData("?c=a", "?c=a", true)] + [InlineData("?a=b&c", "?a=b&c", true)] + [InlineData("?a=b&c=111111&", "?a=b&c=111111&", true)] + [InlineData("?a=b&c=1&a1", "?a=b&c=1&a1", true)] + [InlineData("?a=b&c=1&a1=", "?a=b&c=1&a1=", true)] + [InlineData("?a=b123&c=11&a1=&", "?a=b123&c=11&a1=&", true)] + [InlineData("?c&c&c&", "?c&c&c&", true)] + [InlineData("?a&a&a&a", "?a&a&a&a", true)] + [InlineData("?&&&&&&&", "?&&&&&&&", true)] + [InlineData("?c", "?c", true)] + [InlineData("?c=%26&", "?c=Redacted&", false)] + public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQuery, bool disableQueryRedaction) + { + var exportedItems = new List(); + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { ["OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION"] = disableQueryRedaction.ToString() }) + .Build(); + + // Arrange + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + using var c = new HttpClient(); + try + { + await c.GetStringAsync(new Uri($"{this.url}path{urlQuery}")); + } + catch + { + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + var expectedUrl = $"{this.url}path{expectedUrlQuery}"; + Assert.Equal(expectedUrl, activity.GetTagValue(SemanticConventions.AttributeUrlFull)); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) + { + ActivityContext parentContext = default; + ActivityContext contextFromPropagator = default; + + var propagator = new CustomTextMapPropagator + { + Injected = (context) => contextFromPropagator = context.ActivityContext, + }; + propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + + var exportedItems = new List(); + + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .SetSampler(sample ? new ParentBasedSampler(new AlwaysOnSampler()) : new AlwaysOffSampler()) + .Build()) + { + var previousDefaultTextMapPropagator = Propagators.DefaultTextMapPropagator; + Sdk.SetDefaultTextMapPropagator(propagator); + + Activity parent = null; + if (createParentActivity) + { + parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + + parent.TraceStateString = "k1=v1,k2=v2"; + parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; + + parentContext = parent.Context; + } + + using var request = new HttpRequestMessage + { + RequestUri = new Uri(this.url), + Method = new HttpMethod("GET"), + }; + + using var c = new HttpClient(); + await c.SendAsync(request); + + parent?.Stop(); + + Sdk.SetDefaultTextMapPropagator(previousDefaultTextMapPropagator); + } + + if (!sample) + { + Assert.Empty(exportedItems); + } + else + { + Assert.Single(exportedItems); + } + + // Make sure custom propagator was called. + Assert.True(contextFromPropagator != default); + if (sample) + { + Assert.Equal(contextFromPropagator, exportedItems[0].Context); + } + +#if NETFRAMEWORK + if (!sample && createParentActivity) + { + Assert.Equal(parentContext.TraceId, contextFromPropagator.TraceId); + Assert.Equal(parentContext.SpanId, contextFromPropagator.SpanId); + } +#endif + } + + public void Dispose() + { + this.serverLifeTime?.Dispose(); + this.output.WriteLine($"HttpServer stopped: {this.url}"); + Activity.Current = null; + GC.SuppressFinalize(this); + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs new file mode 100644 index 0000000000..97d15fd75c --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -0,0 +1,503 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +#if NETFRAMEWORK +using System.Net.Http; +#endif +#if !NET8_0_OR_GREATER +using System.Globalization; +using System.Reflection; +using System.Text.Json; +#endif +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +[Collection("Http")] +public partial class HttpClientTests +{ + public static readonly IEnumerable TestData = HttpTestData.ReadTestCases(); + +#if !NET8_0_OR_GREATER + private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; +#endif + + [Theory] + [MemberData(nameof(TestData))] + public async Task HttpOutCallsAreCollectedSuccessfullyTracesAndMetricsSemanticConventionsAsync(HttpOutTestCase tc) + { + await HttpOutCallsAreCollectedSuccessfullyBodyAsync( + this.host, + this.port, + tc, + enableTracing: true, + enableMetrics: true); + } + + [Theory] + [MemberData(nameof(TestData))] + public async Task HttpOutCallsAreCollectedSuccessfullyMetricsOnlyAsync(HttpOutTestCase tc) + { + await HttpOutCallsAreCollectedSuccessfullyBodyAsync( + this.host, + this.port, + tc, + enableTracing: false, + enableMetrics: true); + } + + [Theory] + [MemberData(nameof(TestData))] + public async Task HttpOutCallsAreCollectedSuccessfullyTracesOnlyAsync(HttpOutTestCase tc) + { + await HttpOutCallsAreCollectedSuccessfullyBodyAsync( + this.host, + this.port, + tc, + enableTracing: true, + enableMetrics: false); + } + + [Theory] + [MemberData(nameof(TestData))] + public async Task HttpOutCallsAreCollectedSuccessfullyNoSignalsAsync(HttpOutTestCase tc) + { + await HttpOutCallsAreCollectedSuccessfullyBodyAsync( + this.host, + this.port, + tc, + enableTracing: false, + enableMetrics: false); + } + +#if !NET8_0_OR_GREATER + [Fact] + public async Task DebugIndividualTestAsync() + { + var input = JsonSerializer.Deserialize( + @" + [ + { + ""name"": ""Response code: 399"", + ""method"": ""GET"", + ""url"": ""http://{host}:{port}/"", + ""responseCode"": 399, + ""responseExpected"": true, + ""spanName"": ""GET"", + ""spanStatus"": ""Unset"", + ""spanKind"": ""Client"", + ""spanAttributes"": { + ""url.scheme"": ""http"", + ""http.request.method"": ""GET"", + ""server.address"": ""{host}"", + ""server.port"": ""{port}"", + ""http.response.status_code"": ""399"", + ""network.protocol.version"": ""{flavor}"", + ""url.full"": ""http://{host}:{port}/"" + } + } + ] + ", + JsonSerializerOptions); + + var t = (Task)this.GetType().InvokeMember(nameof(this.HttpOutCallsAreCollectedSuccessfullyTracesAndMetricsSemanticConventionsAsync), BindingFlags.InvokeMethod, null, this, HttpTestData.GetArgumentsFromTestCaseObject(input).First(), CultureInfo.InvariantCulture); + await t; + } +#endif + + [Fact] + public async Task CheckEnrichmentWhenSampling() + { + await CheckEnrichment(new AlwaysOffSampler(), false, this.url); + await CheckEnrichment(new AlwaysOnSampler(), true, this.url); + } + +#if NET8_0_OR_GREATER + [Theory] + [MemberData(nameof(TestData))] + public async Task ValidateNet8MetricsAsync(HttpOutTestCase tc) + { + var metrics = new List(); + var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(metrics) + .Build(); + + var testUrl = HttpTestData.NormalizeValues(tc.Url, this.host, this.port); + + try + { + using var c = new HttpClient(); + using var request = new HttpRequestMessage + { + RequestUri = new Uri(testUrl), + Method = new HttpMethod(tc.Method), + }; + + request.Headers.Add("contextRequired", "false"); + request.Headers.Add("responseCode", (tc.ResponseCode == 0 ? 200 : tc.ResponseCode).ToString()); + await c.SendAsync(request); + } + catch (Exception) + { + // test case can intentionally send request that will result in exception + } + finally + { + meterProvider.Dispose(); + } + + var requestMetrics = metrics + .Where(metric => + metric.Name == "http.client.request.duration" || + metric.Name == "http.client.active_requests" || + metric.Name == "http.client.request.time_in_queue" || + metric.Name == "http.client.connection.duration" || + metric.Name == "http.client.open_connections" || + metric.Name == "dns.lookup.duration") + .ToArray(); + + if (tc.ResponseExpected) + { + Assert.Equal(6, requestMetrics.Length); + } + else + { + // http.client.connection.duration and http.client.open_connections will not be emitted. + Assert.Equal(4, requestMetrics.Length); + } + } +#endif + + private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( + string host, + int port, + HttpOutTestCase tc, + bool enableTracing, + bool enableMetrics) + { + bool enrichWithHttpWebRequestCalled = false; + bool enrichWithHttpWebResponseCalled = false; + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + bool enrichWithExceptionCalled = false; + + var testUrl = HttpTestData.NormalizeValues(tc.Url, host, port); + + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder(); + + if (enableMetrics) + { + meterProviderBuilder + .AddHttpClientInstrumentation(); + } + + var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder(); + + if (enableTracing) + { + tracerProviderBuilder + .AddHttpClientInstrumentation((opt) => + { + opt.EnrichWithHttpWebRequest = (activity, httpRequestMessage) => { enrichWithHttpWebRequestCalled = true; }; + opt.EnrichWithHttpWebResponse = (activity, httpResponseMessage) => { enrichWithHttpWebResponseCalled = true; }; + opt.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + opt.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + opt.EnrichWithException = (activity, exception) => { enrichWithExceptionCalled = true; }; + opt.RecordException = tc.RecordException ?? false; + }); + } + + var metrics = new List(); + var activities = new List(); + + var meterProvider = meterProviderBuilder + .AddInMemoryExporter(metrics) + .Build(); + + var tracerProvider = tracerProviderBuilder + .AddInMemoryExporter(activities) + .Build(); + + try + { + using var c = new HttpClient(); + using var request = new HttpRequestMessage + { + RequestUri = new Uri(testUrl), + Method = new HttpMethod(tc.Method), + }; + + if (tc.Headers != null) + { + foreach (var header in tc.Headers) + { + request.Headers.Add(header.Key, header.Value); + } + } + + request.Headers.Add("contextRequired", "false"); + request.Headers.Add("responseCode", (tc.ResponseCode == 0 ? 200 : tc.ResponseCode).ToString()); + + await c.SendAsync(request); + } + catch (Exception) + { + // test case can intentionally send request that will result in exception + } + finally + { + tracerProvider.Dispose(); + meterProvider.Dispose(); + } + + var requestMetrics = metrics + .Where(metric => metric.Name == "http.client.request.duration") + .ToArray(); + + var normalizedAttributesTestCase = tc.SpanAttributes.ToDictionary(x => x.Key, x => HttpTestData.NormalizeValues(x.Value, host, port)); + + if (!enableTracing) + { + Assert.Empty(activities); + } + else + { + var activity = Assert.Single(activities); + + Assert.Equal(ActivityKind.Client, activity.Kind); + Assert.Equal(tc.SpanName, activity.DisplayName); + +#if NETFRAMEWORK + Assert.True(enrichWithHttpWebRequestCalled); + Assert.False(enrichWithHttpRequestMessageCalled); + if (tc.ResponseExpected) + { + Assert.True(enrichWithHttpWebResponseCalled); + Assert.False(enrichWithHttpResponseMessageCalled); + } +#else + Assert.False(enrichWithHttpWebRequestCalled); + Assert.True(enrichWithHttpRequestMessageCalled); + if (tc.ResponseExpected) + { + Assert.False(enrichWithHttpWebResponseCalled); + Assert.True(enrichWithHttpResponseMessageCalled); + } +#endif + + // Assert.Equal(tc.SpanStatus, d[span.Status.CanonicalCode]); + Assert.Equal(tc.SpanStatus, activity.Status.ToString()); + Assert.Null(activity.StatusDescription); + + var normalizedAttributes = activity.TagObjects.Where(kv => !kv.Key.StartsWith("otel.", StringComparison.Ordinal)).ToDictionary(x => x.Key, x => x.Value.ToString()); + + int numberOfTags = activity.Status == ActivityStatusCode.Error ? 5 : 4; + + var expectedAttributeCount = numberOfTags + (tc.ResponseExpected ? 2 : 0); + + Assert.Equal(expectedAttributeCount, normalizedAttributes.Count); + + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeUrlFull && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlFull]); + if (tc.ResponseExpected) + { + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + + if (tc.ResponseCode >= 400) + { + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + } + } + else + { + Assert.DoesNotContain(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode); + Assert.DoesNotContain(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion); + +#if NET8_0_OR_GREATER + // we are using fake address so it will be "name_resolution_error" + // TODO: test other error types. + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_error"); +#elif NETFRAMEWORK + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_failure"); +#else + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "System.Net.Http.HttpRequestException"); +#endif + } + + if (tc.RecordException.HasValue && tc.RecordException.Value) + { + Assert.Single(activity.Events.Where(evt => evt.Name.Equals("exception"))); + Assert.True(enrichWithExceptionCalled); + } + } + + if (!enableMetrics) + { + Assert.Empty(requestMetrics); + } + else + { + Assert.Single(requestMetrics); + + var metric = requestMetrics.FirstOrDefault(m => m.Name == "http.client.request.duration"); + Assert.NotNull(metric); + Assert.Equal("s", metric.Unit); + Assert.True(metric.MetricType == MetricType.Histogram); + + var metricPoints = new List(); + foreach (var p in metric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + Assert.Single(metricPoints); + var metricPoint = metricPoints[0]; + + var count = metricPoint.GetHistogramCount(); + var sum = metricPoint.GetHistogramSum(); + + Assert.Equal(1L, count); + + if (enableTracing) + { + var activity = Assert.Single(activities); +#if !NET8_0_OR_GREATER + Assert.Equal(activity.Duration.TotalSeconds, sum); +#endif + } + else + { + Assert.True(sum > 0); + } + + // Inspect Metric Attributes + var attributes = new Dictionary(); + foreach (var tag in metricPoint.Tags) + { + attributes[tag.Key] = tag.Value; + } + + var numberOfTags = 4; + if (tc.ResponseExpected) + { + var expectedStatusCode = int.Parse(normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + numberOfTags = (expectedStatusCode >= 400) ? 5 : 4; // error.type extra tag + } + else + { + numberOfTags = 5; // error.type would be extra + } + + var expectedAttributeCount = numberOfTags + (tc.ResponseExpected ? 2 : 0); // responsecode + protocolversion + + Assert.Equal(expectedAttributeCount, attributes.Count); + + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeUrlScheme && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlScheme]); + + if (tc.ResponseExpected) + { + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + + if (tc.ResponseCode >= 400) + { + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + } + } + else + { + Assert.DoesNotContain(attributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion); + Assert.DoesNotContain(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode); + +#if NET8_0_OR_GREATER + // we are using fake address so it will be "name_resolution_error" + // TODO: test other error types. + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_error"); +#elif NETFRAMEWORK + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_failure"); + +#else + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "System.Net.Http.HttpRequestException"); +#endif + } + + // Inspect Histogram Bounds + var histogramBuckets = metricPoint.GetHistogramBuckets(); + var histogramBounds = new List(); + foreach (var t in histogramBuckets) + { + histogramBounds.Add(t.ExplicitBound); + } + + // TODO: Remove the check for the older bounds once 1.7.0 is released. This is a temporary fix for instrumentation libraries CI workflow. + + var expectedHistogramBoundsOld = new List { 0, 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, double.PositiveInfinity }; + var expectedHistogramBoundsNew = new List { 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, double.PositiveInfinity }; + + var histogramBoundsMatchCorrectly = Enumerable.SequenceEqual(expectedHistogramBoundsOld, histogramBounds) || + Enumerable.SequenceEqual(expectedHistogramBoundsNew, histogramBounds); + + Assert.True(histogramBoundsMatchCorrectly); + } + } + + private static async Task CheckEnrichment(Sampler sampler, bool enrichExpected, string url) + { + bool enrichWithHttpWebRequestCalled = false; + bool enrichWithHttpWebResponseCalled = false; + + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(sampler) + .AddHttpClientInstrumentation(options => + { + options.EnrichWithHttpWebRequest = (activity, httpRequestMessage) => { enrichWithHttpWebRequestCalled = true; }; + options.EnrichWithHttpWebResponse = (activity, httpResponseMessage) => { enrichWithHttpWebResponseCalled = true; }; + + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + }) + .Build()) + { + using var c = new HttpClient(); + using var r = await c.GetAsync(new Uri(url)); + } + + if (enrichExpected) + { +#if NETFRAMEWORK + Assert.True(enrichWithHttpWebRequestCalled); + Assert.True(enrichWithHttpWebResponseCalled); + + Assert.False(enrichWithHttpRequestMessageCalled); + Assert.False(enrichWithHttpResponseMessageCalled); +#else + Assert.False(enrichWithHttpWebRequestCalled); + Assert.False(enrichWithHttpWebResponseCalled); + + Assert.True(enrichWithHttpRequestMessageCalled); + Assert.True(enrichWithHttpResponseMessageCalled); +#endif + } + else + { + Assert.False(enrichWithHttpWebRequestCalled); + Assert.False(enrichWithHttpWebResponseCalled); + + Assert.False(enrichWithHttpRequestMessageCalled); + Assert.False(enrichWithHttpResponseMessageCalled); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs new file mode 100644 index 0000000000..45ffe0e6bf --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs @@ -0,0 +1,33 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +public class HttpOutTestCase +{ + public string Name { get; set; } + + public string Method { get; set; } + +#pragma warning disable CA1056 + public string Url { get; set; } +#pragma warning restore CA1056 + +#pragma warning disable CA2227 + public Dictionary Headers { get; set; } +#pragma warning restore CA2227 + + public int ResponseCode { get; set; } + + public string SpanName { get; set; } + + public bool ResponseExpected { get; set; } + + public bool? RecordException { get; set; } + + public string SpanStatus { get; set; } + +#pragma warning disable CA2227 + public Dictionary SpanAttributes { get; set; } +#pragma warning restore CA2227 +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs new file mode 100644 index 0000000000..14b5b96f6c --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Reflection; +using System.Text.Json; + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +public static class HttpTestData +{ + private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + public static IEnumerable ReadTestCases() + { + var assembly = Assembly.GetExecutingAssembly(); + var input = JsonSerializer.Deserialize( + assembly.GetManifestResourceStream("OpenTelemetry.Instrumentation.Http.Tests.http-out-test-cases.json"), + JsonSerializerOptions); + return GetArgumentsFromTestCaseObject(input); + } + + public static IEnumerable GetArgumentsFromTestCaseObject(IEnumerable input) + { + var result = new List(); + + foreach (var testCase in input) + { + result.Add(new object[] + { + testCase, + }); + } + + return result; + } + + public static string NormalizeValues(string value, string host, int port) + { + return value + .Replace("{host}", host) + .Replace("{port}", port.ToString()) + .Replace("{flavor}", "1.1"); + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs new file mode 100644 index 0000000000..bc86339834 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs @@ -0,0 +1,879 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Collections.Concurrent; +using System.Diagnostics; +using System.Net; +using System.Net.Http; +using OpenTelemetry.Instrumentation.Http.Implementation; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +[Collection("Http")] +public class HttpWebRequestActivitySourceTests : IDisposable +{ + private static bool validateBaggage; + private readonly IDisposable testServer; + private readonly string testServerHost; + private readonly int testServerPort; + private readonly string netPeerName; + private readonly int netPeerPort; + + static HttpWebRequestActivitySourceTests() + { + HttpClientTraceInstrumentationOptions options = new() + { + EnrichWithHttpWebRequest = (activity, httpWebRequest) => + { + VerifyHeaders(httpWebRequest); + + if (validateBaggage) + { + ValidateBaggage(httpWebRequest); + } + }, + + DisableUrlQueryRedaction = true, + }; + + HttpWebRequestActivitySource.TracingOptions = options; + + _ = Sdk.SuppressInstrumentation; + } + + public HttpWebRequestActivitySourceTests() + { + Assert.Null(Activity.Current); + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + Activity.ForceDefaultIdFormat = false; + + this.testServer = TestHttpServer.RunServer( + ctx => ProcessServerRequest(ctx), + out this.testServerHost, + out this.testServerPort); + + this.netPeerName = this.testServerHost; + this.netPeerPort = this.testServerPort; + + void ProcessServerRequest(HttpListenerContext context) + { + string redirects = context.Request.QueryString["redirects"]; + if (!string.IsNullOrWhiteSpace(redirects) && int.TryParse(redirects, out int parsedRedirects) && parsedRedirects > 0) + { + context.Response.Redirect(this.BuildRequestUrl(queryString: $"redirects={--parsedRedirects}")); + context.Response.OutputStream.Close(); + return; + } + + string responseContent; + if (context.Request.QueryString["skipRequestContent"] == null) + { + using StreamReader readStream = new StreamReader(context.Request.InputStream); + + responseContent = readStream.ReadToEnd(); + } + else + { + responseContent = $"{{\"Id\":\"{Guid.NewGuid()}\"}}"; + } + + string responseCode = context.Request.QueryString["responseCode"]; + if (!string.IsNullOrWhiteSpace(responseCode)) + { + context.Response.StatusCode = int.Parse(responseCode); + } + else + { + context.Response.StatusCode = 200; + } + + if (context.Response.StatusCode != 204) + { + using StreamWriter writeStream = new StreamWriter(context.Response.OutputStream); + + writeStream.Write(responseContent); + } + else + { + context.Response.OutputStream.Close(); + } + } + } + + public void Dispose() + { + this.testServer.Dispose(); + } + + /// + /// A simple test to make sure the Http Diagnostic Source is added into the list of DiagnosticListeners. + /// + [Fact] + public void TestHttpDiagnosticListenerIsRegistered() + { + bool listenerFound = false; + using ActivityListener activityListener = new ActivityListener + { + ShouldListenTo = activitySource => + { + if (activitySource.Name == HttpWebRequestActivitySource.ActivitySourceName) + { + listenerFound = true; + return true; + } + + return false; + }, + }; + ActivitySource.AddActivityListener(activityListener); + Assert.True(listenerFound, "The Http Diagnostic Listener didn't get added to the AllListeners list."); + } + + /// + /// A simple test to make sure the Http Diagnostic Source is initialized properly after we subscribed to it, using + /// the subscribe overload with just the observer argument. + /// + [Fact] + public async Task TestReflectInitializationViaSubscription() + { + using var eventRecords = new ActivitySourceRecorder(); + + // Send a random Http request to generate some events + using (var client = new HttpClient()) + { + (await client.GetAsync(new Uri(this.BuildRequestUrl()))).Dispose(); + } + + // Just make sure some events are written, to confirm we successfully subscribed to it. + // We should have exactly one Start and one Stop event + Assert.Equal(2, eventRecords.Records.Count); + } + + /// + /// Test to make sure we get both request and response events. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + [InlineData("POST", "skipRequestContent=1")] + public async Task TestBasicReceiveAndResponseEvents(string method, string queryString = null) + { + var url = this.BuildRequestUrl(queryString: queryString); + + using var eventRecords = new ActivitySourceRecorder(); + + // Send a random Http request to generate some events + using (var client = new HttpClient()) + { + (method == "GET" + ? await client.GetAsync(new Uri(url)) + : await client.PostAsync(new Uri(url), new StringContent("hello world"))).Dispose(); + } + + // We should have exactly one Start and one Stop event + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + // Check to make sure: The first record must be a request, the next record must be a response. + Activity activity = AssertFirstEventWasStart(eventRecords); + + VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out var stopEvent)); + Assert.Equal("Stop", stopEvent.Key); + + VerifyActivityStopTags(200, activity); + } + + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestBasicReceiveAndResponseEventsWithoutSampling(string method) + { + using var eventRecords = new ActivitySourceRecorder(activitySamplingResult: ActivitySamplingResult.None); + + // Send a random Http request to generate some events + using (var client = new HttpClient()) + { + (method == "GET" + ? await client.GetAsync(new Uri(this.BuildRequestUrl())) + : await client.PostAsync(new Uri(this.BuildRequestUrl()), new StringContent("hello world"))).Dispose(); + } + + // There should be no events because we turned off sampling. + Assert.Empty(eventRecords.Records); + } + + [Theory] + [InlineData("GET", 0)] + [InlineData("GET", 1)] + [InlineData("GET", 2)] + [InlineData("GET", 3)] + [InlineData("POST", 0)] + [InlineData("POST", 1)] + [InlineData("POST", 2)] + [InlineData("POST", 3)] + public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int mode) + { + string url = this.BuildRequestUrl(); + + using var eventRecords = new ActivitySourceRecorder(); + + // Send a random Http request to generate some events + var webRequest = (HttpWebRequest)WebRequest.Create(new Uri(url)); + + if (method == "POST") + { + webRequest.Method = method; + + Stream stream = null; + switch (mode) + { + case 0: + stream = webRequest.GetRequestStream(); + break; + case 1: + stream = await webRequest.GetRequestStreamAsync(); + break; + case 2: + { + object state = new object(); + using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); + IAsyncResult asyncResult = webRequest.BeginGetRequestStream( + ar => + { + Assert.Equal(state, ar.AsyncState); + handle.Set(); + }, + state); + stream = webRequest.EndGetRequestStream(asyncResult); + if (!handle.WaitOne(TimeSpan.FromSeconds(30))) + { + throw new InvalidOperationException(); + } + + handle.Dispose(); + } + + break; + case 3: + { + using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); + object state = new object(); + webRequest.BeginGetRequestStream( + ar => + { + stream = webRequest.EndGetRequestStream(ar); + Assert.Equal(state, ar.AsyncState); + handle.Set(); + }, + state); + if (!handle.WaitOne(TimeSpan.FromSeconds(30))) + { + throw new InvalidOperationException(); + } + + handle.Dispose(); + } + + break; + default: + throw new NotSupportedException(); + } + + Assert.NotNull(stream); + + using StreamWriter writer = new StreamWriter(stream); + + writer.WriteLine("hello world"); + } + + WebResponse webResponse = null; + switch (mode) + { + case 0: + webResponse = webRequest.GetResponse(); + break; + case 1: + webResponse = await webRequest.GetResponseAsync(); + break; + case 2: + { + object state = new object(); + using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); + IAsyncResult asyncResult = webRequest.BeginGetResponse( + ar => + { + Assert.Equal(state, ar.AsyncState); + handle.Set(); + }, + state); + webResponse = webRequest.EndGetResponse(asyncResult); + if (!handle.WaitOne(TimeSpan.FromSeconds(30))) + { + throw new InvalidOperationException(); + } + + handle.Dispose(); + } + + break; + case 3: + { + using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); + object state = new object(); + webRequest.BeginGetResponse( + ar => + { + webResponse = webRequest.EndGetResponse(ar); + Assert.Equal(state, ar.AsyncState); + handle.Set(); + }, + state); + if (!handle.WaitOne(TimeSpan.FromSeconds(30))) + { + throw new InvalidOperationException(); + } + + handle.Dispose(); + } + + break; + default: + throw new NotSupportedException(); + } + + Assert.NotNull(webResponse); + + using StreamReader reader = new StreamReader(webResponse.GetResponseStream()); + + reader.ReadToEnd(); // Make sure response is not disposed. + + // We should have exactly one Start and one Stop event + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + // Check to make sure: The first record must be a request, the next record must be a response. + Activity activity = AssertFirstEventWasStart(eventRecords); + + VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out var stopEvent)); + Assert.Equal("Stop", stopEvent.Key); + + VerifyActivityStopTags(200, activity); + } + + [Fact] + public async Task TestTraceStateAndBaggage() + { + try + { + using var eventRecords = new ActivitySourceRecorder(); + + using var parent = new Activity("w3c activity"); + parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom()); + parent.TraceStateString = "some=state"; + parent.Start(); + + Baggage.SetBaggage("k", "v"); + + // Send a random Http request to generate some events + using (var client = new HttpClient()) + { + (await client.GetAsync(new Uri(this.BuildRequestUrl()))).Dispose(); + } + + parent.Stop(); + + Assert.Equal(2, eventRecords.Records.Count); + + // Check to make sure: The first record must be a request, the next record must be a response. + _ = AssertFirstEventWasStart(eventRecords); + } + finally + { + this.CleanUpActivity(); + } + } + + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task DoNotInjectTraceParentWhenPresent(string method) + { + try + { + using var eventRecords = new ActivitySourceRecorder(); + + // Send a random Http request to generate some events + using (var client = new HttpClient()) + using (var request = new HttpRequestMessage(HttpMethod.Get, this.BuildRequestUrl())) + { + request.Headers.Add("traceparent", "00-abcdef0123456789abcdef0123456789-abcdef0123456789-01"); + + if (method == "GET") + { + request.Method = HttpMethod.Get; + } + else + { + request.Method = HttpMethod.Post; + request.Content = new StringContent("hello world"); + } + + (await client.SendAsync(request)).Dispose(); + } + + // No events are sent. + Assert.Empty(eventRecords.Records); + } + finally + { + this.CleanUpActivity(); + } + } + + /// + /// Test to make sure we get both request and response events. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestResponseWithoutContentEvents(string method) + { + string url = this.BuildRequestUrl(queryString: "responseCode=204"); + + using var eventRecords = new ActivitySourceRecorder(); + + // Send a random Http request to generate some events + using (var client = new HttpClient()) + { + using HttpResponseMessage response = method == "GET" + ? await client.GetAsync(new Uri(url)) + : await client.PostAsync(new Uri(url), new StringContent("hello world")); + } + + // We should have exactly one Start and one Stop event + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + // Check to make sure: The first record must be a request, the next record must be a response. + Activity activity = AssertFirstEventWasStart(eventRecords); + + VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out var stopEvent)); + Assert.Equal("Stop", stopEvent.Key); + + VerifyActivityStopTags(204, activity); + } + + /// + /// Test that if request is redirected, it gets only one Start and one Stop event. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestRedirectedRequest(string method) + { + using var eventRecords = new ActivitySourceRecorder(); + + using (var client = new HttpClient()) + { + using HttpResponseMessage response = method == "GET" + ? await client.GetAsync(new Uri(this.BuildRequestUrl(queryString: "redirects=10"))) + : await client.PostAsync(new Uri(this.BuildRequestUrl(queryString: "redirects=10")), new StringContent("hello world")); + } + + // We should have exactly one Start and one Stop event + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + } + + /// + /// Test exception in request processing: exception should have expected type/status and now be swallowed by reflection hook. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestRequestWithException(string method) + { + string host = Guid.NewGuid().ToString() + ".com"; + string url = method == "GET" + ? $"http://{host}" + : $"http://{host}"; + + using var eventRecords = new ActivitySourceRecorder(); + + var ex = await Assert.ThrowsAsync(() => + { + return method == "GET" + ? new HttpClient().GetAsync(new Uri(url)) + : new HttpClient().PostAsync(new Uri(url), new StringContent("hello world")); + }); + + // check that request failed because of the wrong domain name and not because of reflection + var webException = (WebException)ex.InnerException; + Assert.NotNull(webException); + Assert.True(webException.Status == WebExceptionStatus.NameResolutionFailure); + + // We should have one Start event and one Stop event with an exception. + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + // Check to make sure: The first record must be a request, the next record must be an exception. + Activity activity = AssertFirstEventWasStart(eventRecords); + VerifyActivityStartTags(host, null, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.Equal("Stop", exceptionEvent.Key); + + Assert.True(activity.Status != ActivityStatusCode.Unset); + Assert.Null(activity.StatusDescription); + } + + /// + /// Test request cancellation: reflection hook does not throw. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestCanceledRequest(string method) + { + string url = this.BuildRequestUrl(); + + CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + using var eventRecords = new ActivitySourceRecorder(_ => { cts.Cancel(); }); + + using (var client = new HttpClient()) + { + var ex = await Assert.ThrowsAnyAsync(() => + { + return method == "GET" + ? client.GetAsync(new Uri(url), cts.Token) + : client.PostAsync(new Uri(url), new StringContent("hello world"), cts.Token); + }); + Assert.True(ex is TaskCanceledException || ex is WebException); + } + + // We should have one Start event and one Stop event with an exception. + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + Activity activity = AssertFirstEventWasStart(eventRecords); + VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.Equal("Stop", exceptionEvent.Key); + + Assert.True(exceptionEvent.Value.Status != ActivityStatusCode.Unset); + Assert.True(exceptionEvent.Value.StatusDescription == null); + } + + /// + /// Test request connection exception: reflection hook does not throw. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestSecureTransportFailureRequest(string method) + { + string url = "https://expired.badssl.com/"; + + using var eventRecords = new ActivitySourceRecorder(); + + using (var client = new HttpClient()) + { + var ex = await Assert.ThrowsAnyAsync(() => + { + // https://expired.badssl.com/ has an expired certificate. + return method == "GET" + ? client.GetAsync(new Uri(url)) + : client.PostAsync(new Uri(url), new StringContent("hello world")); + }); + Assert.True(ex is HttpRequestException); + } + + // We should have one Start event and one Stop event with an exception. + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + Activity activity = AssertFirstEventWasStart(eventRecords); + VerifyActivityStartTags("expired.badssl.com", null, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.Equal("Stop", exceptionEvent.Key); + + Assert.True(exceptionEvent.Value.Status != ActivityStatusCode.Unset); + Assert.Null(exceptionEvent.Value.StatusDescription); + } + + /// + /// Test request connection retry: reflection hook does not throw. + /// + [Theory] + [InlineData("GET")] + [InlineData("POST")] + public async Task TestSecureTransportRetryFailureRequest(string method) + { + // This test sends an https request to an endpoint only set up for http. + // It should retry. What we want to test for is 1 start, 1 exception event even + // though multiple are actually sent. + + string url = this.BuildRequestUrl(useHttps: true); + + using var eventRecords = new ActivitySourceRecorder(); + + using (var client = new HttpClient()) + { + var ex = await Assert.ThrowsAnyAsync(() => + { + return method == "GET" + ? client.GetAsync(new Uri(url)) + : client.PostAsync(new Uri(url), new StringContent("hello world")); + }); + Assert.True(ex is HttpRequestException); + } + + // We should have one Start event and one Stop event with an exception. + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + Activity activity = AssertFirstEventWasStart(eventRecords); + VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); + + Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.Equal("Stop", exceptionEvent.Key); + + Assert.True(exceptionEvent.Value.Status != ActivityStatusCode.Unset); + Assert.Null(exceptionEvent.Value.StatusDescription); + } + + [Fact] + public async Task TestInvalidBaggage() + { + validateBaggage = true; + Baggage + .SetBaggage("key", "value") + .SetBaggage("bad/key", "value") + .SetBaggage("goodkey", "bad/value"); + + using var eventRecords = new ActivitySourceRecorder(); + + using (var client = new HttpClient()) + { + (await client.GetAsync(new Uri(this.BuildRequestUrl()))).Dispose(); + } + + Assert.Equal(2, eventRecords.Records.Count); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); + + validateBaggage = false; + } + + /// + /// Test to make sure every event record has the right dynamic properties. + /// + [Fact] + public async Task TestMultipleConcurrentRequests() + { + ServicePointManager.DefaultConnectionLimit = int.MaxValue; + using var parentActivity = new Activity("parent").Start(); + using var eventRecords = new ActivitySourceRecorder(); + + Dictionary> requestData = new Dictionary>(); + for (int i = 0; i < 10; i++) + { + Uri uriWithRedirect = new Uri(this.BuildRequestUrl(queryString: $"q={i}&redirects=3")); + + requestData[uriWithRedirect] = null; + } + + // Issue all requests simultaneously + using var httpClient = new HttpClient(); + Dictionary> tasks = new Dictionary>(); + + CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + foreach (var url in requestData.Keys) + { + tasks.Add(url, httpClient.GetAsync(url, cts.Token)); + } + + // wait up to 10 sec for all requests and suppress exceptions + await Task.WhenAll(tasks.Select(t => t.Value).ToArray()).ContinueWith(async tt => + { + foreach (var task in tasks) + { + (await task.Value)?.Dispose(); + } + }); + + // Examine the result. Make sure we got all successful requests. + + // Just make sure some events are written, to confirm we successfully subscribed to it. We should have + // exactly 1 Start event per request and exactly 1 Stop event per response (if request succeeded) + var successfulTasks = tasks.Where(t => t.Value.Status == TaskStatus.RanToCompletion); + + Assert.Equal(tasks.Count, eventRecords.Records.Count(rec => rec.Key == "Start")); + Assert.Equal(successfulTasks.Count(), eventRecords.Records.Count(rec => rec.Key == "Stop")); + + // Check to make sure: We have a WebRequest and a WebResponse for each successful request + foreach (var pair in eventRecords.Records) + { + Activity activity = pair.Value; + + Assert.True( + pair.Key == "Start" || + pair.Key == "Stop", + "An unexpected event of name " + pair.Key + "was received"); + } + } + + private static Activity AssertFirstEventWasStart(ActivitySourceRecorder eventRecords) + { + Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair startEvent)); + Assert.Equal("Start", startEvent.Key); + return startEvent.Value; + } + + private static void VerifyHeaders(HttpWebRequest startRequest) + { + var tracestate = startRequest.Headers["tracestate"]; + Assert.Equal("some=state", tracestate); + + var baggage = startRequest.Headers["baggage"]; + Assert.Equal("k=v", baggage); + + var traceparent = startRequest.Headers["traceparent"]; + Assert.NotNull(traceparent); + Assert.Matches("^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$", traceparent); + } + + private static void VerifyActivityStartTags(string netPeerName, int? netPeerPort, string method, string url, Activity activity) + { + Assert.NotNull(activity.TagObjects); + Assert.Equal(method, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); + if (netPeerPort != null) + { + Assert.Equal(netPeerPort, activity.GetTagValue(SemanticConventions.AttributeServerPort)); + } + + Assert.Equal(netPeerName, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + + Assert.Equal(url, activity.GetTagValue(SemanticConventions.AttributeUrlFull)); + } + + private static void VerifyActivityStopTags(int statusCode, Activity activity) + { + Assert.Equal(statusCode, activity.GetTagValue(SemanticConventions.AttributeHttpResponseStatusCode)); + } + + private static void ActivityEnrichment(Activity activity, string method, object obj) + { + switch (method) + { + case "OnStartActivity": + Assert.True(obj is HttpWebRequest); + VerifyHeaders(obj as HttpWebRequest); + + if (validateBaggage) + { + ValidateBaggage(obj as HttpWebRequest); + } + + break; + + case "OnStopActivity": + Assert.True(obj is HttpWebResponse); + break; + + case "OnException": + Assert.True(obj is Exception); + break; + + default: + break; + } + } + + private static void ValidateBaggage(HttpWebRequest request) + { + string[] baggage = request.Headers["baggage"].Split(','); + + Assert.Equal(3, baggage.Length); + Assert.Contains("key=value", baggage); + Assert.Contains("bad%2Fkey=value", baggage); + Assert.Contains("goodkey=bad%2Fvalue", baggage); + } + + private string BuildRequestUrl(bool useHttps = false, string path = "echo", string queryString = null) + { + return $"{(useHttps ? "https" : "http")}://{this.testServerHost}:{this.testServerPort}/{path}{(string.IsNullOrWhiteSpace(queryString) ? string.Empty : $"?{queryString}")}"; + } + + private void CleanUpActivity() + { + while (Activity.Current != null) + { + Activity.Current.Stop(); + } + } + + /// + /// is a helper class for recording events. + /// + private class ActivitySourceRecorder : IDisposable + { + private readonly Action> onEvent; + private readonly ActivityListener activityListener; + + public ActivitySourceRecorder(Action> onEvent = null, ActivitySamplingResult activitySamplingResult = ActivitySamplingResult.AllDataAndRecorded) + { + this.activityListener = new ActivityListener + { + ShouldListenTo = (activitySource) => activitySource.Name == HttpWebRequestActivitySource.ActivitySourceName, + ActivityStarted = this.ActivityStarted, + ActivityStopped = this.ActivityStopped, + Sample = (ref ActivityCreationOptions options) => activitySamplingResult, + }; + + ActivitySource.AddActivityListener(this.activityListener); + + this.onEvent = onEvent; + } + + public ConcurrentQueue> Records { get; } = new ConcurrentQueue>(); + + public void Dispose() + { + this.activityListener.Dispose(); + } + + public void ActivityStarted(Activity activity) => this.Record("Start", activity); + + public void ActivityStopped(Activity activity) => this.Record("Stop", activity); + + private void Record(string eventName, Activity activity) + { + var record = new KeyValuePair(eventName, activity); + + this.Records.Enqueue(record); + this.onEvent?.Invoke(record); + } + } +} +#endif diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs new file mode 100644 index 0000000000..3d9bb790d8 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs @@ -0,0 +1,363 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Net; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.Http.Implementation; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +#pragma warning disable SYSLIB0014 // Type or member is obsolete + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +public partial class HttpWebRequestTests : IDisposable +{ + private readonly IDisposable serverLifeTime; + private readonly string url; + + public HttpWebRequestTests() + { + Assert.Null(Activity.Current); + Activity.DefaultIdFormat = ActivityIdFormat.W3C; + Activity.ForceDefaultIdFormat = false; + + this.serverLifeTime = TestHttpServer.RunServer( + (ctx) => + { + if (string.IsNullOrWhiteSpace(ctx.Request.Headers["traceparent"]) + && string.IsNullOrWhiteSpace(ctx.Request.Headers["custom_traceparent"]) + && ctx.Request.QueryString["bypassHeaderCheck"] != "true") + { + ctx.Response.StatusCode = 500; + ctx.Response.StatusDescription = "Missing trace context"; + } + else if (ctx.Request.Url.PathAndQuery.Contains("500")) + { + ctx.Response.StatusCode = 500; + } + else + { + ctx.Response.StatusCode = 200; + } + + ctx.Response.OutputStream.Close(); + }, + out var host, + out var port); + + this.url = $"http://{host}:{port}/"; + } + + public void Dispose() + { + this.serverLifeTime?.Dispose(); + } + + [Fact] + public async Task BacksOffIfAlreadyInstrumented() + { + var exportedItems = new List(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddHttpClientInstrumentation() + .Build(); + + var request = (HttpWebRequest)WebRequest.Create(new Uri(this.url)); + + request.Method = "GET"; + + request.Headers.Add("traceparent", "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"); + + using var response = await request.GetResponseAsync(); + +#if NETFRAMEWORK + Assert.Empty(exportedItems); +#else + Assert.Single(exportedItems); +#endif + } + + [Fact] + public async Task RequestNotCollectedWhenInstrumentationFilterApplied() + { + bool httpWebRequestFilterApplied = false; + bool httpRequestMessageFilterApplied = false; + + var exportedItems = new List(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddHttpClientInstrumentation( + options => + { + options.FilterHttpWebRequest = (req) => + { + httpWebRequestFilterApplied = true; + return !req.RequestUri.OriginalString.Contains(this.url); + }; + options.FilterHttpRequestMessage = (req) => + { + httpRequestMessageFilterApplied = true; + return !req.RequestUri.OriginalString.Contains(this.url); + }; + }) + .Build(); + + var request = (HttpWebRequest)WebRequest.Create(new Uri($"{this.url}?bypassHeaderCheck=true")); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + +#if NETFRAMEWORK + Assert.True(httpWebRequestFilterApplied); + Assert.False(httpRequestMessageFilterApplied); +#else + Assert.False(httpWebRequestFilterApplied); + Assert.True(httpRequestMessageFilterApplied); +#endif + + Assert.Empty(exportedItems); + } + + [Fact] + public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() + { + var exportedItems = new List(); + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddHttpClientInstrumentation( + c => + { + c.FilterHttpWebRequest = (req) => throw new Exception("From Instrumentation filter"); + c.FilterHttpRequestMessage = (req) => throw new Exception("From Instrumentation filter"); + }) + .Build(); + + using (var inMemoryEventListener = new InMemoryEventListener(HttpInstrumentationEventSource.Log)) + { + var request = (HttpWebRequest)WebRequest.Create(new Uri($"{this.url}?bypassHeaderCheck=true")); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 4)); + } + + Assert.Empty(exportedItems); + } + + [Fact] + public async Task InjectsHeadersAsync() + { + var exportedItems = new List(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddHttpClientInstrumentation() + .Build(); + + var request = (HttpWebRequest)WebRequest.Create(new Uri(this.url)); + + request.Method = "GET"; + + using var parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + parent.TraceStateString = "k1=v1,k2=v2"; + parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; + + using var response = await request.GetResponseAsync(); + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(parent.TraceId, activity.Context.TraceId); + Assert.Equal(parent.SpanId, activity.ParentSpanId); + Assert.NotEqual(parent.SpanId, activity.Context.SpanId); + Assert.NotEqual(default, activity.Context.SpanId); + +#if NETFRAMEWORK + string traceparent = request.Headers.Get("traceparent"); + string tracestate = request.Headers.Get("tracestate"); + + Assert.Equal($"00-{activity.Context.TraceId}-{activity.Context.SpanId}-01", traceparent); + Assert.Equal("k1=v1,k2=v2", tracestate); +#else + // Note: On .NET HttpRequestMessage is created and enriched + // not the HttpWebRequest that was executed. + Assert.Empty(request.Headers); +#endif + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) + { + ActivityContext parentContext = default; + ActivityContext contextFromPropagator = default; + + var propagator = new CustomTextMapPropagator + { + Injected = (PropagationContext context) => contextFromPropagator = context.ActivityContext, + }; + propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + + var exportedItems = new List(); + + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .SetSampler(sample ? new ParentBasedSampler(new AlwaysOnSampler()) : new AlwaysOffSampler()) + .Build()) + { + var previousDefaultTextMapPropagator = Propagators.DefaultTextMapPropagator; + Sdk.SetDefaultTextMapPropagator(propagator); + + Activity parent = null; + if (createParentActivity) + { + parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + + parent.TraceStateString = "k1=v1,k2=v2"; + parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; + + parentContext = parent.Context; + } + + var request = (HttpWebRequest)WebRequest.Create(new Uri(this.url)); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + + parent?.Stop(); + + Sdk.SetDefaultTextMapPropagator(previousDefaultTextMapPropagator); + } + + if (!sample) + { + Assert.Empty(exportedItems); + } + else + { + Assert.Single(exportedItems); + } + + Assert.True(contextFromPropagator != default); + if (sample) + { + Assert.Equal(contextFromPropagator, exportedItems[0].Context); + } + +#if NETFRAMEWORK + if (!sample && createParentActivity) + { + Assert.Equal(parentContext.TraceId, contextFromPropagator.TraceId); + Assert.Equal(parentContext.SpanId, contextFromPropagator.SpanId); + } +#endif + } + + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public void AddHttpClientInstrumentationUsesOptionsApi(string name) + { + name ??= Options.DefaultName; + + int configurationDelegateInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(name, o => configurationDelegateInvocations++); + }) + .AddHttpClientInstrumentation(name, options => + { + Assert.IsType(options); + }) + .Build(); + + Assert.Equal(1, configurationDelegateInvocations); + } + + [Fact] + public async Task ReportsExceptionEventForNetworkFailures() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + try + { + var request = (HttpWebRequest)WebRequest.Create(new Uri("https://sdlfaldfjalkdfjlkajdflkajlsdjf.sdlkjafsdjfalfadslkf.com/")); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + } + catch + { + exceptionThrown = true; + } + + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + } + + [Fact] + public async Task ReportsExceptionEventOnErrorResponse() + { + var exportedItems = new List(); + bool exceptionThrown = false; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation(o => o.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + + try + { + var request = (HttpWebRequest)WebRequest.Create(new Uri($"{this.url}500")); + + request.Method = "GET"; + + using var response = await request.GetResponseAsync(); + } + catch + { + exceptionThrown = true; + } + +#if NETFRAMEWORK + // Exception is thrown and collected as event + Assert.True(exceptionThrown); + Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); +#else + // Note: On .NET Core exceptions through HttpWebRequest do not + // trigger exception events they just throw: + // https://github.com/dotnet/runtime/blob/cc5ba0994d6e8a6f5e4a63d1c921a68eda4350e8/src/libraries/System.Net.Requests/src/System/Net/HttpWebRequest.cs#L1371 + Assert.True(exceptionThrown); + Assert.DoesNotContain(exportedItems[0].Events, evt => evt.Name.Equals("exception")); +#endif + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs new file mode 100644 index 0000000000..abae3baf6f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs @@ -0,0 +1,189 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Net; +using System.Text.Json; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +#pragma warning disable SYSLIB0014 // Type or member is obsolete + +namespace OpenTelemetry.Instrumentation.Http.Tests; + +[Collection("Http")] +public partial class HttpWebRequestTests +{ + private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + public static IEnumerable TestData => HttpTestData.ReadTestCases(); + + [Theory] + [MemberData(nameof(TestData))] + public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) + { + using var serverLifeTime = TestHttpServer.RunServer( + (ctx) => + { + ctx.Response.StatusCode = tc.ResponseCode == 0 ? 200 : tc.ResponseCode; + ctx.Response.OutputStream.Close(); + }, + out var host, + out var port); + + bool enrichWithHttpWebRequestCalled = false; + bool enrichWithHttpWebResponseCalled = false; + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + bool enrichWithExceptionCalled = false; + + var exportedItems = new List(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddHttpClientInstrumentation(options => + { + options.EnrichWithHttpWebRequest = (activity, httpWebRequest) => { enrichWithHttpWebRequestCalled = true; }; + options.EnrichWithHttpWebResponse = (activity, httpWebResponse) => { enrichWithHttpWebResponseCalled = true; }; + options.EnrichWithHttpRequestMessage = (activity, request) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (activity, response) => { enrichWithHttpResponseMessageCalled = true; }; + options.EnrichWithException = (activity, exception) => { enrichWithExceptionCalled = true; }; + options.RecordException = tc.RecordException ?? false; + }) + .Build(); + + tc.Url = HttpTestData.NormalizeValues(tc.Url, host, port); + + try + { + var request = (HttpWebRequest)WebRequest.Create(new Uri(tc.Url)); + + request.Method = tc.Method; + + if (tc.Headers != null) + { + foreach (var header in tc.Headers) + { + request.Headers.Add(header.Key, header.Value); + } + } + + request.ContentLength = 0; + + using var response = (HttpWebResponse)request.GetResponse(); + + using var streamReader = new StreamReader(response.GetResponseStream()); + streamReader.ReadToEnd(); + } + catch (Exception) + { + // test case can intentionally send request that will result in exception + tc.ResponseExpected = false; + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + ValidateHttpWebRequestActivity(activity); + Assert.Equal(tc.SpanName, activity.DisplayName); + + tc.SpanAttributes = tc.SpanAttributes.ToDictionary( + x => x.Key, + x => + { + if (x.Key == "network.protocol.version") + { + return "1.1"; + } + + return HttpTestData.NormalizeValues(x.Value, host, port); + }); + + foreach (KeyValuePair tag in activity.TagObjects) + { + var tagValue = tag.Value.ToString(); + + if (!tc.SpanAttributes.TryGetValue(tag.Key, out string value)) + { + if (tag.Key == SpanAttributeConstants.StatusCodeKey) + { + Assert.Equal(tc.SpanStatus, tagValue); + continue; + } + + if (tag.Key == SpanAttributeConstants.StatusDescriptionKey) + { + Assert.Null(tagValue); + continue; + } + + if (tag.Key == SemanticConventions.AttributeErrorType) + { + // TODO: Add validation for error.type in test cases. + continue; + } + + Assert.Fail($"Tag {tag.Key} was not found in test data."); + } + + Assert.Equal(value, tagValue); + } + +#if NETFRAMEWORK + Assert.True(enrichWithHttpWebRequestCalled); + Assert.False(enrichWithHttpRequestMessageCalled); + if (tc.ResponseExpected) + { + Assert.True(enrichWithHttpWebResponseCalled); + Assert.False(enrichWithHttpResponseMessageCalled); + } +#else + Assert.False(enrichWithHttpWebRequestCalled); + Assert.True(enrichWithHttpRequestMessageCalled); + if (tc.ResponseExpected) + { + Assert.False(enrichWithHttpWebResponseCalled); + Assert.True(enrichWithHttpResponseMessageCalled); + } +#endif + + if (tc.RecordException.HasValue && tc.RecordException.Value) + { + Assert.Single(activity.Events.Where(evt => evt.Name.Equals("exception"))); + Assert.True(enrichWithExceptionCalled); + } + } + + [Fact] + public void DebugIndividualTest() + { + var input = JsonSerializer.Deserialize( + @" + { + ""name"": ""Http version attribute populated"", + ""method"": ""GET"", + ""url"": ""http://{host}:{port}/"", + ""responseCode"": 200, + ""spanName"": ""GET"", + ""spanStatus"": ""UNSET"", + ""spanKind"": ""Client"", + ""setHttpFlavor"": true, + ""spanAttributes"": { + ""url.scheme"": ""http"", + ""http.request.method"": ""GET"", + ""server.address"": ""{host}"", + ""server.port"": ""{port}"", + ""network.protocol.version"": ""1.1"", + ""http.response.status_code"": ""200"", + ""url.full"": ""http://{host}:{port}/"" + } + } + ", + JsonSerializerOptions); + this.HttpOutCallsAreCollectedSuccessfully(input); + } + + private static void ValidateHttpWebRequestActivity(Activity activityToValidate) + { + Assert.Equal(ActivityKind.Client, activityToValidate.Kind); + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj new file mode 100644 index 0000000000..8c103d0899 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -0,0 +1,42 @@ + + + Unit test project for OpenTelemetry HTTP instrumentations + net8.0;net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + enable + + disable + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs new file mode 100644 index 0000000000..d1a977b7e8 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Net.Http; +#endif + +namespace OpenTelemetry.Tests; + +public class RetryHandler : DelegatingHandler +{ + private readonly int maxRetries; + + public RetryHandler(HttpMessageHandler innerHandler, int maxRetries) + : base(innerHandler) + { + this.maxRetries = maxRetries; + } + + protected override async Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken) + { + HttpResponseMessage response = null; + for (int i = 0; i < this.maxRetries; i++) + { + response?.Dispose(); + + try + { + response = await base.SendAsync(request, cancellationToken); + } + catch + { + } + } + + return response; + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json b/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json new file mode 100644 index 0000000000..489b96ee4a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/http-out-test-cases.json @@ -0,0 +1,340 @@ +[ + { + "name": "Successful GET call to localhost", + "method": "GET", + "url": "http://{host}:{port}/", + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Successfully POST call to localhost", + "method": "POST", + "url": "http://{host}:{port}/", + "spanName": "POST", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "POST", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Name is populated as a path", + "method": "GET", + "url": "http://{host}:{port}/path/to/resource/", + "responseCode": 200, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/path/to/resource/" + } + }, + { + "name": "URL with fragment", + "method": "GET", + "url": "http://{host}:{port}/path/to/resource#fragment", + "responseCode": 200, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/path/to/resource#fragment" + } + }, + { + "name": "url.full must not contain username nor password", + "method": "GET", + "url": "http://username:password@{host}:{port}/path/to/resource#fragment", + "responseCode": 200, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/path/to/resource#fragment" + } + }, + { + "name": "Call that cannot resolve DNS will be reported as error span", + "method": "GET", + "url": "http://sdlfaldfjalkdfjlkajdflkajlsdjf:{port}/", + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": false, + "recordException": false, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "sdlfaldfjalkdfjlkajdflkajlsdjf", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "url.full": "http://sdlfaldfjalkdfjlkajdflkajlsdjf:{port}/" + } + }, + { + "name": "Call that cannot resolve DNS will be reported as error span. And Records exception", + "method": "GET", + "url": "http://sdlfaldfjalkdfjlkajdflkajlsdjf:{port}/", + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": false, + "recordException": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "sdlfaldfjalkdfjlkajdflkajlsdjf", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "url.full": "http://sdlfaldfjalkdfjlkajdflkajlsdjf:{port}/" + } + }, + { + "name": "Response code: 199. This test case is not possible to implement on some platforms as they don't allow to return this status code. Keeping this test case for visibility, but it actually simply a fallback into 200 test case", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 200, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 200", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 200, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 399", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 399, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "399", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 400", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 400, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "400", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 401", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 401, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "401", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 403", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 403, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "403", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 404", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 404, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "404", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 429", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 429, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "429", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 501", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 501, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "501", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 503", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 503, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "503", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Response code: 504", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 504, + "spanName": "GET", + "spanStatus": "Error", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "504", + "url.full": "http://{host}:{port}/" + } + }, + { + "name": "Http version attribute populated", + "method": "GET", + "url": "http://{host}:{port}/", + "responseCode": 200, + "spanName": "GET", + "spanStatus": "Unset", + "responseExpected": true, + "spanAttributes": { + "url.scheme": "http", + "http.request.method": "GET", + "server.address": "{host}", + "server.port": "{port}", + "network.protocol.version": "{flavor}", + "http.response.status_code": "200", + "url.full": "http://{host}:{port}/" + } + } +] From 9d4b5f102269f883f15974c35e0676aa2186779d Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 26 Apr 2024 15:48:50 -0700 Subject: [PATCH 1044/1499] [Exporter.Geneva] Fix exemplar value serialization for TLV serialization format (#1698) --- .../Metrics/TlvMetricExporter.cs | 34 ++++++++++--------- .../Exporter/MetricExporterBenchmarks.cs | 4 +++ .../GenevaMetricExporterTests.cs | 14 ++++++++ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index f81d11a4d5..b25eb9e05e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -90,8 +90,8 @@ internal ExportResult Export(in Batch batch) #if EXPOSE_EXPERIMENTAL_FEATURES metricPoint.TryGetExemplars(out var exemplars); #endif - - switch (metric.MetricType) + var metricType = metric.MetricType; + switch (metricType) { case MetricType.LongSum: { @@ -104,6 +104,7 @@ internal ExportResult Export(in Batch batch) metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out monitoringAccount, @@ -126,6 +127,7 @@ internal ExportResult Export(in Batch batch) metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out monitoringAccount, @@ -148,6 +150,7 @@ internal ExportResult Export(in Batch batch) metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out monitoringAccount, @@ -168,6 +171,7 @@ internal ExportResult Export(in Batch batch) metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out monitoringAccount, @@ -187,6 +191,7 @@ internal ExportResult Export(in Batch batch) metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out monitoringAccount, @@ -215,6 +220,7 @@ internal ExportResult Export(in Batch batch) min, max, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out monitoringAccount, @@ -266,6 +272,7 @@ internal unsafe ushort SerializeMetricWithTLV( in ReadOnlyTagCollection tags, MetricData value, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType metricType, ReadOnlyExemplarCollection exemplars, #endif out string monitoringAccount, @@ -295,7 +302,7 @@ internal unsafe ushort SerializeMetricWithTLV( out metricNamespace); #if EXPOSE_EXPERIMENTAL_FEATURES - SerializeExemplars(exemplars, this.buffer, ref bufferIndex); + SerializeExemplars(exemplars, metricType, this.buffer, ref bufferIndex); #endif SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -330,6 +337,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( double min, double max, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType metricType, ReadOnlyExemplarCollection exemplars, #endif out string monitoringAccount, @@ -359,7 +367,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( out metricNamespace); #if EXPOSE_EXPERIMENTAL_FEATURES - SerializeExemplars(exemplars, this.buffer, ref bufferIndex); + SerializeExemplars(exemplars, metricType, this.buffer, ref bufferIndex); #endif SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -407,7 +415,7 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] #if EXPOSE_EXPERIMENTAL_FEATURES [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeExemplars(in ReadOnlyExemplarCollection exemplars, byte[] buffer, ref int bufferIndex) + private static void SerializeExemplars(in ReadOnlyExemplarCollection exemplars, MetricType metricType, byte[] buffer, ref int bufferIndex) { var exemplarsCount = 0; foreach (ref readonly var exemplar in exemplars) @@ -429,7 +437,7 @@ private static void SerializeExemplars(in ReadOnlyExemplarCollection exemplars, foreach (ref readonly var exemplar in exemplars) { - SerializeSingleExemplar(exemplar, buffer, ref bufferIndex); + SerializeSingleExemplar(exemplar, metricType, buffer, ref bufferIndex); } var payloadTypeLength = (ushort)(bufferIndex - payloadTypeStartIndex - 2); @@ -438,7 +446,7 @@ private static void SerializeExemplars(in ReadOnlyExemplarCollection exemplars, } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SerializeSingleExemplar(Exemplar exemplar, byte[] buffer, ref int bufferIndex) + private static void SerializeSingleExemplar(Exemplar exemplar, MetricType metricType, byte[] buffer, ref int bufferIndex) { MetricSerializer.SerializeByte(buffer, ref bufferIndex, 0); // version @@ -450,20 +458,14 @@ private static void SerializeSingleExemplar(Exemplar exemplar, byte[] buffer, re var flags = ExemplarFlags.IsTimestampAvailable; // we only serialize exemplars with Timestamp != default - // TODO: Update the code when Exemplars support long values - var value = exemplar.DoubleValue; - - // Check if the double value is actually a whole number that can be serialized as a long instead - var valueAsLong = (long)value; - bool isWholeNumber = valueAsLong == value; - if (isWholeNumber) + if (metricType.IsLong()) { flags |= ExemplarFlags.IsMetricValueDoubleStoredAsLong; - MetricSerializer.SerializeInt64AsBase128(buffer, ref bufferIndex, valueAsLong); // serialize long value + MetricSerializer.SerializeInt64AsBase128(buffer, ref bufferIndex, exemplar.LongValue); // serialize long value } else { - MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, value); // serialize double value + MetricSerializer.SerializeFloat64(buffer, ref bufferIndex, exemplar.DoubleValue); // serialize double value } var bufferIndexForNumberOfLabels = bufferIndex; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs index f05d5eca12..d50a2b7ae0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs @@ -584,6 +584,7 @@ public void SerializeCounterMetricItemWith3Dimensions() this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType.LongSum, exemplars, #endif out _, @@ -603,6 +604,7 @@ public void SerializeCounterMetricItemWith4Dimensions() this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType.LongSum, exemplars, #endif out _, @@ -637,6 +639,7 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramMinWith3Dimensions, this.histogramMaxWith3Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType.Histogram, exemplars, #endif out _, @@ -659,6 +662,7 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramMinWith4Dimensions, this.histogramMaxWith4Dimensions, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType.Histogram, exemplars, #endif out _, diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 714920f7e0..4afcd08d47 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -195,6 +195,7 @@ public void SuccessfulExportOnLinux() metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + MetricType.LongSum, exemplars, #endif out _, @@ -1000,6 +1001,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1028,6 +1030,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1058,6 +1061,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1088,6 +1092,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1125,6 +1130,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, min, max, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1276,6 +1282,9 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem .TotalMilliseconds * 1000000; // TODO: Test for exemplar values stored as long + // Ideally we could assert the long on serializedExemplarBody.Value.ValueAsVlq + // But the result returned by it is not correct so skipping the long check for now. + // TODO: follow up to see if this is a bug in KaitaiStruct.Runtime.CSharp. if (!serializedExemplarBody.Value.IsDoubleStoredAsLong) { Assert.Equal(expectedExemplar.DoubleValue, serializedExemplarBody.Value.ValueAsDouble); @@ -1345,6 +1354,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1366,6 +1376,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1389,6 +1400,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1412,6 +1424,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.Tags, metricData, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, @@ -1442,6 +1455,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp min, max, #if EXPOSE_EXPERIMENTAL_FEATURES + metricType, exemplars, #endif out _, From 6d349c412fdffb1b542662e30d47f9d3b7337198 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 2 May 2024 14:06:36 -0700 Subject: [PATCH 1045/1499] [Exporter.Geneva] Release prep 1.8.0-rc.1 (#1697) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 9113ce3932..03533c9b0a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -1,12 +1,17 @@ # Changelog -## Unreleased +## 1.8.0-rc.1 + +Released 2024-May-02 * Update OpenTelemetry SDK version to `1.8.0-rc.1`. ([#1689](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1689)) ## 1.8.0-beta.1 +**(This version has been unlisted due to incorrect dependency on stable sdk +version 1.8.1 that prevents ability to use exemplars)** + Released 2024-Apr-23 * Fix a bug in `GenevaMetricExporter` where the `MetricEtwDataTransport` singleton From 6aed975f113ecf3c7994f0a519669e660c8974a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 6 May 2024 22:54:37 +0200 Subject: [PATCH 1046/1499] [Instrumentation.GrpcNetClient] Move package from main repository (#1704) --- .../comp_instrumentation_grpcnetclient.md | 41 ++ .github/codecov.yml | 5 + .github/workflows/ci.yml | 16 + .../package-Instrumentation.GrpcNetClient.yml | 21 + ...lemetry.Instrumentation.GrpcNetClient.proj | 32 ++ opentelemetry-dotnet-contrib.sln | 16 + .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 12 + .../AssemblyInfo.cs | 10 + .../CHANGELOG.md | 266 +++++++++++ .../GrpcClientInstrumentation.cs | 30 ++ .../GrpcClientTraceInstrumentationOptions.cs | 35 ++ .../GrpcTagHelper.cs | 76 +++ .../GrpcClientDiagnosticListener.cs | 201 ++++++++ .../GrpcInstrumentationEventSource.cs | 52 +++ ...metry.Instrumentation.GrpcNetClient.csproj | 40 ++ .../README.md | 140 ++++++ .../StatusCanonicalCode.cs | 135 ++++++ .../TracerProviderBuilderExtensions.cs | 68 +++ .../OpenTelemetry.Instrumentation.Http.csproj | 1 + .../Shared}/ActivityHelperExtensions.cs | 2 +- src/Shared/AssemblyVersionExtensions.cs | 2 +- .../HttpRequestMessageContextPropagation.cs | 2 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + .../TestActivityExportProcessor.cs | 2 + .../AWSLambdaWrapperTests.cs | 1 - ...try.Instrumentation.AWSLambda.Tests.csproj | 2 +- ...emetry.Instrumentation.AspNet.Tests.csproj | 2 +- ...mentation.ElasticsearchClient.Tests.csproj | 2 +- .../EventSourceTest.cs | 17 + .../GrpcServer.cs | 90 ++++ .../GrpcTagHelperTests.cs | 66 +++ .../GrpcTestHelpers/ClientTestHelpers.cs | 76 +++ .../GrpcTestHelpers/ResponseUtils.cs | 76 +++ .../GrpcTestHelpers/TestHttpMessageHandler.cs | 41 ++ .../GrpcTestHelpers/TrailingHeadersHelpers.cs | 47 ++ .../GrpcTests.client.cs | 441 ++++++++++++++++++ .../GrpcTests.server.cs | 205 ++++++++ ...Instrumentation.GrpcNetClient.Tests.csproj | 43 ++ .../Proto/greet.proto | 35 ++ .../Services/GreeterService.cs | 39 ++ ...elemetry.Instrumentation.Http.Tests.csproj | 2 +- ...try.Instrumentation.SqlClient.Tests.csproj | 2 +- .../SqlClientTests.cs | 2 + ...lClientTraceInstrumentationOptionsTests.cs | 1 - ...isProfilerEntryToActivityConverterTests.cs | 1 - ...umentation.StackExchangeRedis.Tests.csproj | 2 +- 47 files changed, 2387 insertions(+), 12 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md create mode 100644 .github/workflows/package-Instrumentation.GrpcNetClient.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs create mode 100644 src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs rename {test/OpenTelemetry.Contrib.Tests.Shared => src/Shared}/ActivityHelperExtensions.cs (93%) rename src/{OpenTelemetry.Instrumentation.Http => Shared}/HttpRequestMessageContextPropagation.cs (89%) create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/EventSourceTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ResponseUtils.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Proto/greet.proto create mode 100644 test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md new file mode 100644 index 0000000000..fb38e35552 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.GrpcNetClient +about: Issue with OpenTelemetry.Instrumentation.GrpcNetClient +labels: comp:instrumentation.grpcnetclient +--- + +# Issue with OpenTelemetry.Instrumentation.GrpcNetClient + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 027a50a663..3198fe49bb 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -68,6 +68,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Http + unittests-Instrumentation.GrpcNetClient: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.GrpcNetClient + unittests-Instrumentation.Owin: carryforward: true paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d789293259..1e01fa622b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,7 @@ jobs: eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] + grpcnetclient: ['*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', '!**/*.md'] host: ['*/OpenTelemetry.ResourceDetectors.Host*/**', '!**/*.md'] http: ['*/OpenTelemetry.Instrumentation.Http*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] @@ -65,6 +66,7 @@ jobs: '!*/OpenTelemetry.Instrumentation.Owin*/**', '!examples/owin/**', '!*/OpenTelemetry.PersistentStorage*/**', + '!*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', '!*/OpenTelemetry.Instrumentation.Http*/**', '!*/OpenTelemetry.Instrumentation.Process*/**', '!examples/process-instrumentation/**', @@ -151,6 +153,17 @@ jobs: project-name: OpenTelemetry.Exporter.Geneva code-cov-name: Exporter.Geneva + build-test-grpcnetclient: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'grpcnetclient') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.GrpcNetClient + code-cov-name: Instrumentation.GrpcNetClient + build-test-host: needs: detect-changes if: | @@ -339,6 +352,7 @@ jobs: OpenTelemetry.Instrumentation.AspNet.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, OpenTelemetry.Instrumentation.EventCounters.Tests.csproj, + OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj, OpenTelemetry.Instrumentation.Http.Tests.csproj, OpenTelemetry.Instrumentation.Owin.Tests.csproj, OpenTelemetry.Instrumentation.Process.Tests.csproj, @@ -396,6 +410,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'aws') || contains(needs.detect-changes.outputs.changes, 'azure') || contains(needs.detect-changes.outputs.changes, 'extensions') + || contains(needs.detect-changes.outputs.changes, 'grpcnetclient') || contains(needs.detect-changes.outputs.changes, 'host') || contains(needs.detect-changes.outputs.changes, 'http') || contains(needs.detect-changes.outputs.changes, 'processdetector') @@ -422,6 +437,7 @@ jobs: build-test-eventcounters, build-test-extensions, build-test-geneva, + build-test-grpcnetclient, build-test-host, build-test-http, build-test-onecollector, diff --git a/.github/workflows/package-Instrumentation.GrpcNetClient.yml b/.github/workflows/package-Instrumentation.GrpcNetClient.yml new file mode 100644 index 0000000000..3d5410499d --- /dev/null +++ b/.github/workflows/package-Instrumentation.GrpcNetClient.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.Instrumentation.GrpcNetClient + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.GrpcNetClient-*' # trigger when we create a tag with prefix "Instrumentation.GrpcNetClient-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.GrpcNetClient + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj b/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj new file mode 100644 index 0000000000..86cbf25ef5 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a49632c03c..1830e85346 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -52,6 +52,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml + .github\workflows\package-Instrumentation.GrpcNetClient.yml = .github\workflows\package-Instrumentation.GrpcNetClient.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml .github\workflows\package-Instrumentation.Http.yml = .github\workflows\package-Instrumentation.Http.yml .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml @@ -322,6 +323,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj + build\Projects\OpenTelemetry.Instrumentation.GrpcNetClient.proj = build\Projects\OpenTelemetry.Instrumentation.GrpcNetClient.proj build\Projects\OpenTelemetry.Instrumentation.Http.proj = build\Projects\OpenTelemetry.Instrumentation.Http.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj @@ -363,6 +365,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http.Benchmark", "test\OpenTelemetry.Instrumentation.Http.Benchmark\OpenTelemetry.Instrumentation.Http.Benchmark.csproj", "{1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcNetClient", "src\OpenTelemetry.Instrumentation.GrpcNetClient\OpenTelemetry.Instrumentation.GrpcNetClient.csproj", "{0156E342-CE63-46F5-992D-691A7CCB50F8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcNetClient.Tests", "test\OpenTelemetry.Instrumentation.GrpcNetClient.Tests\OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj", "{2E1A5759-1431-4724-8885-3E9447FBF617}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -733,6 +739,14 @@ Global {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Debug|Any CPU.Build.0 = Debug|Any CPU {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.ActiveCfg = Release|Any CPU {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.Build.0 = Release|Any CPU + {0156E342-CE63-46F5-992D-691A7CCB50F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0156E342-CE63-46F5-992D-691A7CCB50F8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0156E342-CE63-46F5-992D-691A7CCB50F8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0156E342-CE63-46F5-992D-691A7CCB50F8}.Release|Any CPU.Build.0 = Release|Any CPU + {2E1A5759-1431-4724-8885-3E9447FBF617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E1A5759-1431-4724-8885-3E9447FBF617}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E1A5759-1431-4724-8885-3E9447FBF617}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E1A5759-1431-4724-8885-3E9447FBF617}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -842,6 +856,8 @@ Global {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {7371E920-ECD0-403A-A009-7A1A301D9763} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {0156E342-CE63-46F5-992D-691A7CCB50F8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2E1A5759-1431-4724-8885-3E9447FBF617} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..32e717dc82 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,12 @@ +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.set -> void +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.set -> void +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.GrpcClientTraceInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/AssemblyInfo.cs new file mode 100644 index 0000000000..cd07ce49a2 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.GrpcNetClient.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.GrpcNetClient.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md new file mode 100644 index 0000000000..a7d27f0e5b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -0,0 +1,266 @@ +# Changelog + +## Unreleased + +* `ActivitySource.Version` is set to NuGet package version. + ([#5498](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5498)) +* Update `OpenTelemetry` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +## 1.8.0-beta.1 + +Released 2024-Apr-04 + +## 1.7.0-beta.1 + +Released 2024-Feb-09 + +* **Breaking Change**: + Please be advised that the + [SuppressDownstreamInstrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient#suppressdownstreaminstrumentation) + option no longer works when used in conjunction with the + `OpenTelemetry.Instrumentation.Http` package version `1.6.0` or greater. + This is not a result of a change in the `OpenTelemetry.Instrumentation.GrpcNetClient` + package therefore this also affects versions prior to this release. See this + [issue](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092) + for details and workaround. +* Removed support for the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable + which toggled the use of the new conventions for the + [server, client, and shared network attributes](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/general/attributes.md#server-client-and-shared-network-attributes). + Now that this suite of attributes are stable, this instrumentation will only + emit the new attributes. + ([#5259](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5259)) +* **Breaking Change**: Renamed `GrpcClientInstrumentationOptions` to + `GrpcClientTraceInstrumentationOptions`. + ([#5272](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5272)) + +## 1.6.0-beta.3 + +Released 2023-Nov-17 + +## 1.6.0-beta.2 + +Released 2023-Oct-26 + +## 1.5.1-beta.1 + +Released 2023-Jul-20 + +* The new network semantic conventions can be opted in to by setting + the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a + transition period for users to experiment with the new semantic conventions + and adapt as necessary. The environment variable supports the following + values: + * `http` - emit the new, frozen (proposed for stable) networking + attributes, and stop emitting the old experimental networking + attributes that the instrumentation emitted previously. + * `http/dup` - emit both the old and the frozen (proposed for stable) + networking attributes, allowing for a more seamless transition. + * The default behavior (in the absence of one of these values) is to continue + emitting the same network semantic conventions that were emitted in + `1.5.0-beta.1`. + * Note: this option will eventually be removed after the new + network semantic conventions are marked stable. Refer to the + specification for more information regarding the new network + semantic conventions for + [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/rpc/rpc-spans.md). + ([#4658](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4658)) + +## 1.5.0-beta.1 + +Released 2023-Jun-05 + +* Bumped the package version to `1.5.0-beta.1` to keep its major and minor + version in sync with that of the core packages. This would make it more + intuitive for users to figure out what version of core packages would work + with a given version of this package. The pre-release identifier has also been + changed from `rc` to `beta` as we believe this more accurately reflects the + status of this package. We believe the `rc` identifier will be more + appropriate as semantic conventions reach stability. + +## 1.0.0-rc9.14 + +Released 2023-Feb-24 + +* Updated OTel SDK dependency to 1.4.0 + +## 1.4.0-rc9.13 + +Released 2023-Feb-10 + +## 1.0.0-rc9.12 + +Released 2023-Feb-01 + +## 1.0.0-rc9.11 + +Released 2023-Jan-09 + +## 1.0.0-rc9.10 + +Released 2022-Dec-12 + +## 1.0.0-rc9.9 + +Released 2022-Nov-07 + + **Breaking change** The `Enrich` callback option has been removed. For better + usability, it has been replaced by two separate options: + `EnrichWithHttpRequestMessage`and `EnrichWithHttpResponseMessage`. Previously, + the single `Enrich` callback required the consumer to detect which event + triggered the callback to be invoked (e.g., request start or response end) and + then cast the object received to the appropriate type: `HttpRequestMessage` + and `HttpResponseMessage`. The separate callbacks make it clear what event + triggers them and there is no longer the need to cast the argument to the + expected type. + ([#3804](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3804)) + +## 1.0.0-rc9.8 + +Released 2022-Oct-17 + +## 1.0.0-rc9.7 + +Released 2022-Sep-29 + +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddGrpcClientInstrumentation` extension to allow for more fine-grained + options management + ([#3665](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3665)) + +## 1.0.0-rc9.6 + +Released 2022-Aug-18 + +* Updated to use Activity native support from `System.Diagnostics.DiagnosticSource` + to set activity status. + ([#3118](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3118)) + ([#3569](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3569)) + +## 1.0.0-rc9.5 + +Released 2022-Aug-02 + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 + +* Add `netstandard2.0` target enabling the Grpc.Net.Client instrumentation to + be consumed by .NET Framework applications. + ([#3105](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3105)) + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +## 1.0.0-rc7 + +Released 2021-Jul-12 + +## 1.0.0-rc6 + +Released 2021-Jun-25 + +## 1.0.0-rc5 + +Released 2021-Jun-09 + +## 1.0.0-rc4 + +Released 2021-Apr-23 + +## 1.0.0-rc3 + +Released 2021-Mar-19 + +* Leverages added AddLegacySource API from OpenTelemetry SDK to trigger Samplers + and ActivityProcessors. Samplers, ActivityProcessor.OnStart will now get the + Activity before any enrichment done by the instrumentation. + ([#1836](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1836)) +* Performance optimization by leveraging sampling decision and short circuiting + activity enrichment. + ([#1903](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1904)) + +## 1.0.0-rc2 + +Released 2021-Jan-29 + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +* Add context propagation, when SuppressDownstreamInstrumentation is enabled. + [#1464](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1464) +* GrpcNetClientInstrumentation sets ActivitySource to activities created outside + ActivitySource. + ([#1515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1515/)) + +## 0.8.0-beta.1 + +Released 2020-Nov-5 + +## 0.7.0-beta.1 + +Released 2020-Oct-16 + +* Instrumentation no longer store raw objects like `HttpRequestMessage` in + Activity.CustomProperty. To enrich activity, use the Enrich action on the + instrumentation. + ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) +* Span Status is populated as per new spec + ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) + +## 0.6.0-beta.1 + +Released 2020-Sep-15 + +* The `grpc.method` and `grpc.status_code` attributes added by the library are + removed from the span. The information from these attributes is contained in + other attributes that follow the conventions of OpenTelemetry. + ([#1260](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1260)) + +## 0.5.0-beta.2 + +Released 2020-08-28 + +* NuGet package renamed to OpenTelemetry.Instrumentation.GrpcNetClient to more + clearly indicate that this package is specifically for gRPC client + instrumentation. The package was previously named + OpenTelemetry.Instrumentation.Grpc. + ([#1136](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1136)) +* Grpc.Net.Client Instrumentation automatically populates HttpRequest in + Activity custom property + ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099)) + ([#1128](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1128)) + +## 0.4.0-beta.2 + +Released 2020-07-24 + +* First beta release + +## 0.3.0-beta + +Released 2020-07-23 + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs new file mode 100644 index 0000000000..961ddc1774 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; + +namespace OpenTelemetry.Instrumentation.GrpcNetClient; + +/// +/// GrpcClient instrumentation. +/// +internal sealed class GrpcClientInstrumentation : IDisposable +{ + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + /// + /// Initializes a new instance of the class. + /// + /// Configuration options for Grpc client instrumentation. + public GrpcClientInstrumentation(GrpcClientTraceInstrumentationOptions options = null) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new GrpcClientDiagnosticListener(options), isEnabledFilter: null, GrpcInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber.Dispose(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs new file mode 100644 index 0000000000..b4cd871980 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs @@ -0,0 +1,35 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; + +namespace OpenTelemetry.Instrumentation.GrpcNetClient; + +/// +/// Options for GrpcClient instrumentation. +/// +public class GrpcClientTraceInstrumentationOptions +{ + /// + /// Gets or sets a value indicating whether down stream instrumentation is suppressed (disabled). + /// + public bool SuppressDownstreamInstrumentation { get; set; } + + /// + /// Gets or sets an action to enrich the Activity with . + /// + /// + /// : the activity being enriched. + /// object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithHttpRequestMessage { get; set; } + + /// + /// Gets or sets an action to enrich an Activity with . + /// + /// + /// : the activity being enriched. + /// object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithHttpResponseMessage { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs new file mode 100644 index 0000000000..836beb226a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs @@ -0,0 +1,76 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Text.RegularExpressions; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.GrpcNetClient; + +internal static class GrpcTagHelper +{ + public const string RpcSystemGrpc = "grpc"; + + // The Grpc.Net.Client library adds its own tags to the activity. + // These tags are used to source the tags added by the OpenTelemetry instrumentation. + public const string GrpcMethodTagName = "grpc.method"; + public const string GrpcStatusCodeTagName = "grpc.status_code"; + + private static readonly Regex GrpcMethodRegex = new(@"^/?(?.*)/(?.*)$", RegexOptions.Compiled); + + public static string GetGrpcMethodFromActivity(Activity activity) + { + return activity.GetTagValue(GrpcMethodTagName) as string; + } + + public static bool TryGetGrpcStatusCodeFromActivity(Activity activity, out int statusCode) + { + statusCode = -1; + var grpcStatusCodeTag = activity.GetTagValue(GrpcStatusCodeTagName); + if (grpcStatusCodeTag == null) + { + return false; + } + + return int.TryParse(grpcStatusCodeTag as string, out statusCode); + } + + public static bool TryParseRpcServiceAndRpcMethod(string grpcMethod, out string rpcService, out string rpcMethod) + { + var match = GrpcMethodRegex.Match(grpcMethod); + if (match.Success) + { + rpcService = match.Groups["service"].Value; + rpcMethod = match.Groups["method"].Value; + return true; + } + else + { + rpcService = string.Empty; + rpcMethod = string.Empty; + return false; + } + } + + /// + /// Helper method that populates span properties from RPC status code according + /// to https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/grpc.md#grpc-attributes. + /// + /// RPC status code. + /// Resolved span for the Grpc status code. + public static ActivityStatusCode ResolveSpanStatusForGrpcStatusCode(int statusCode) + { + var status = ActivityStatusCode.Error; + + if (typeof(StatusCanonicalCode).IsEnumDefined(statusCode)) + { + status = ((StatusCanonicalCode)statusCode) switch + { + StatusCanonicalCode.Ok => ActivityStatusCode.Unset, + _ => ActivityStatusCode.Error, + }; + } + + return status; + } +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs new file mode 100644 index 0000000000..99e5e89e02 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs @@ -0,0 +1,201 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using System.Reflection; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; + +internal sealed class GrpcClientDiagnosticListener : ListenerHandler +{ + internal static readonly Assembly Assembly = typeof(GrpcClientDiagnosticListener).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly string Version = Assembly.GetPackageVersion(); + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version); + + private const string OnStartEvent = "Grpc.Net.Client.GrpcOut.Start"; + private const string OnStopEvent = "Grpc.Net.Client.GrpcOut.Stop"; + + private static readonly PropertyFetcher StartRequestFetcher = new("Request"); + private static readonly PropertyFetcher StopResponseFetcher = new("Response"); + + private readonly GrpcClientTraceInstrumentationOptions options; + + public GrpcClientDiagnosticListener(GrpcClientTraceInstrumentationOptions options) + : base("Grpc.Net.Client") + { + this.options = options; + } + + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnStartEvent: + { + this.OnStartActivity(Activity.Current, payload); + } + + break; + case OnStopEvent: + { + this.OnStopActivity(Activity.Current, payload); + } + + break; + } + } + + public void OnStartActivity(Activity activity, object payload) + { + // The overall flow of what GrpcClient library does is as below: + // Activity.Start() + // DiagnosticSource.WriteEvent("Start", payload) + // DiagnosticSource.WriteEvent("Stop", payload) + // Activity.Stop() + + // This method is in the WriteEvent("Start", payload) path. + // By this time, samplers have already run and + // activity.IsAllDataRequested populated accordingly. + + if (Sdk.SuppressInstrumentation) + { + return; + } + + // Ensure context propagation irrespective of sampling decision + if (!TryFetchRequest(payload, out HttpRequestMessage request)) + { + GrpcInstrumentationEventSource.Log.NullPayload(nameof(GrpcClientDiagnosticListener), nameof(this.OnStartActivity)); + return; + } + + if (this.options.SuppressDownstreamInstrumentation) + { + SuppressInstrumentationScope.Enter(); + + // If we are suppressing downstream instrumentation then inject + // context here. Grpc.Net.Client uses HttpClient, so + // SuppressDownstreamInstrumentation means that the + // OpenTelemetry instrumentation for HttpClient will not be + // invoked. + + // Note that HttpClient natively generates its own activity and + // propagates W3C trace context headers regardless of whether + // OpenTelemetry HttpClient instrumentation is invoked. + // Therefore, injecting here preserves more intuitive span + // parenting - i.e., the entry point span of a downstream + // service would be parented to the span generated by + // Grpc.Net.Client rather than the span generated natively by + // HttpClient. Injecting here also ensures that baggage is + // propagated to downstream services. + // Injecting context here also ensures that the configured + // propagator is used, as HttpClient by itself will only + // do TraceContext propagation. + var textMapPropagator = Propagators.DefaultTextMapPropagator; + textMapPropagator.Inject( + new PropagationContext(activity.Context, Baggage.Current), + request, + HttpRequestMessageContextPropagation.HeaderValueSetter); + } + + if (activity.IsAllDataRequested) + { + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); + + var grpcMethod = GrpcTagHelper.GetGrpcMethodFromActivity(activity); + + activity.DisplayName = grpcMethod?.Trim('/'); + + activity.SetTag(SemanticConventions.AttributeRpcSystem, GrpcTagHelper.RpcSystemGrpc); + + if (GrpcTagHelper.TryParseRpcServiceAndRpcMethod(grpcMethod, out var rpcService, out var rpcMethod)) + { + activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); + activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + + // Remove the grpc.method tag added by the gRPC .NET library + activity.SetTag(GrpcTagHelper.GrpcMethodTagName, null); + } + + var uriHostNameType = Uri.CheckHostName(request.RequestUri.Host); + + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + { + activity.SetTag(SemanticConventions.AttributeServerSocketAddress, request.RequestUri.Host); + } + else + { + activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); + } + + activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + + try + { + this.options.EnrichWithHttpRequestMessage?.Invoke(activity, request); + } + catch (Exception ex) + { + GrpcInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + + // See https://github.com/grpc/grpc-dotnet/blob/ff1a07b90c498f259e6d9f4a50cdad7c89ecd3c0/src/Grpc.Net.Client/Internal/GrpcCall.cs#L1180-L1183 + // this makes sure that top-level properties on the payload object are always preserved. +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] +#endif + static bool TryFetchRequest(object payload, out HttpRequestMessage request) + => StartRequestFetcher.TryFetch(payload, out request) && request != null; + } + + public void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + if (validConversion) + { + if (activity.Status == ActivityStatusCode.Unset) + { + activity.SetStatus(GrpcTagHelper.ResolveSpanStatusForGrpcStatusCode(status)); + } + + // setting rpc.grpc.status_code + activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, status); + } + + // Remove the grpc.status_code tag added by the gRPC .NET library + activity.SetTag(GrpcTagHelper.GrpcStatusCodeTagName, null); + + if (TryFetchResponse(payload, out HttpResponseMessage response)) + { + try + { + this.options.EnrichWithHttpResponseMessage?.Invoke(activity, response); + } + catch (Exception ex) + { + GrpcInstrumentationEventSource.Log.EnrichmentException(ex); + } + } + } + + // See https://github.com/grpc/grpc-dotnet/blob/ff1a07b90c498f259e6d9f4a50cdad7c89ecd3c0/src/Grpc.Net.Client/Internal/GrpcCall.cs#L1180-L1183 + // this makes sure that top-level properties on the payload object are always preserved. +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] +#endif + static bool TryFetchResponse(object payload, out HttpResponseMessage response) + => StopResponseFetcher.TryFetch(payload, out response) && response != null; + } +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcInstrumentationEventSource.cs new file mode 100644 index 0000000000..0bfbd38076 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcInstrumentationEventSource.cs @@ -0,0 +1,52 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-Grpc")] +internal sealed class GrpcInstrumentationEventSource : EventSource +{ + public static GrpcInstrumentationEventSource Log = new(); + + [Event(1, Message = "Payload is NULL in event '{1}' from handler '{0}', span will not be recorded.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName) + { + this.WriteEvent(1, handlerName, eventName); + } + + [NonEvent] + public void EnrichmentException(Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(ex.ToInvariantString()); + } + } + + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); + } + } + + [Event(2, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] + public void EnrichmentException(string exception) + { + this.WriteEvent(2, exception); + } + + [Event(3, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(3, handlerName, eventName, ex); + } +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj new file mode 100644 index 0000000000..f2c3bfdbb3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -0,0 +1,40 @@ + + + + net8.0;net6.0;netstandard2.1;netstandard2.0 + gRPC for .NET client instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing + Instrumentation.GrpcNetClient- + + enable + + disable + + + + + true + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md new file mode 100644 index 0000000000..eb6bdd12d9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md @@ -0,0 +1,140 @@ +# Grpc.Net.Client Instrumentation for OpenTelemetry + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) + +This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) +which instruments [Grpc.Net.Client](https://www.nuget.org/packages/Grpc.Net.Client) +and collects traces about outgoing gRPC requests. + +> [!CAUTION] +> This component is based on the OpenTelemetry semantic conventions for +[traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md). +These conventions are +[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), +and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +Until a [stable +version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be breaking changes. You can track the progress from +[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). + +## Supported .NET Versions + +This package targets +[`NETSTANDARD2.1`](https://docs.microsoft.com/dotnet/standard/net-standard#net-implementation-support) +and hence can be used in any .NET versions implementing `NETSTANDARD2.1`. + +## Steps to enable OpenTelemetry.Instrumentation.GrpcNetClient + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.GrpcNetClient`](https://www.nuget.org/packages/opentelemetry.instrumentation.grpcnetclient) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package --prerelease OpenTelemetry.Instrumentation.GrpcNetClient +``` + +### Step 2: Enable Grpc.Net.Client Instrumentation at application startup + +Grpc.Net.Client instrumentation must be enabled at application startup. + +The following example demonstrates adding Grpc.Net.Client instrumentation to a +console application. This example also sets up the OpenTelemetry Console +exporter and adds instrumentation for HttpClient, which requires adding the +packages +[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +and +[`OpenTelemetry.Instrumentation.Http`](../OpenTelemetry.Instrumentation.Http/README.md) +to the application. As Grpc.Net.Client uses HttpClient underneath, it is +recommended to enable HttpClient instrumentation as well to ensure proper +context propagation. This would cause an activity being produced for both a gRPC +call and its underlying HTTP call. This behavior can be +[configured](#suppressdownstreaminstrumentation). + +```csharp +using OpenTelemetry.Trace; + +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddGrpcClientInstrumentation() + .AddHttpClientInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +For an ASP.NET Core application, adding instrumentation is typically done in +the `ConfigureServices` of your `Startup` class. Refer to documentation for +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). + +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`GrpcClientInstrumentationOptions`. + +### SuppressDownstreamInstrumentation + +> [!CAUTION] +> `SuppressDownstreamInstrumentation` no longer works when used in conjunction +with the `OpenTelemetry.Instrumentation.Http` package version `1.6.0` and greater. +This option may change or even be removed in a future release. + +This option prevents downstream instrumentation from being invoked. +Grpc.Net.Client is built on top of HttpClient. When instrumentation for both +libraries is enabled, `SuppressDownstreamInstrumentation` prevents the +HttpClient instrumentation from generating an additional activity. Additionally, +since HttpClient instrumentation is normally responsible for propagating context +(ActivityContext and Baggage), Grpc.Net.Client instrumentation propagates +context when `SuppressDownstreamInstrumentation` is enabled. + +The following example shows how to use `SuppressDownstreamInstrumentation`. + +```csharp +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddGrpcClientInstrumentation( + opt => opt.SuppressDownstreamInstrumentation = true) + .AddHttpClientInstrumentation() + .Build(); +``` + +### Enrich + +This instrumentation library provides `EnrichWithHttpRequestMessage` and +`EnrichWithHttpResponseMessage` options that can be used to enrich the activity +with additional information from the raw `HttpRequestMessage` and +`HttpResponseMessage` objects respectively. These actions are called only when +`activity.IsAllDataRequested` is `true`. It contains the activity itself (which +can be enriched), the name of the event, and the actual raw object. The +following code snippet shows how to add additional tags using these options. + +```csharp +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddGrpcClientInstrumentation(options => + { + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => + { + activity.SetTag("requestVersion", httpRequestMessage.Version); + }; + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => + { + activity.SetTag("responseVersion", httpResponseMessage.Version); + }; + }); +``` + +[Processor](../../docs/trace/extending-the-sdk/README.md#processor), +is the general extensibility point to add additional properties to any activity. +The `Enrich` option is specific to this instrumentation, and is provided to +get access to `HttpRequest` and `HttpResponse`. + +## References + +* [gRPC for .NET](https://github.com/grpc/grpc-dotnet) +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs new file mode 100644 index 0000000000..4ddb1ec16c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs @@ -0,0 +1,135 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.GrpcNetClient; + +/// +/// Canonical result code of span execution. +/// +/// +/// This follows the standard GRPC codes. +/// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md. +/// +internal enum StatusCanonicalCode +{ + /// + /// The operation completed successfully. + /// + Ok = 0, + + /// + /// The operation was cancelled (typically by the caller). + /// + Cancelled = 1, + + /// + /// Unknown error. An example of where this error may be returned is if a Status value received + /// from another address space belongs to an error-space that is not known in this address space. + /// Also errors raised by APIs that do not return enough error information may be converted to + /// this error. + /// + Unknown = 2, + + /// + /// Client specified an invalid argument. Note that this differs from FAILED_PRECONDITION. + /// INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the + /// system (e.g., a malformed file name). + /// + InvalidArgument = 3, + + /// + /// Deadline expired before operation could complete. For operations that change the state of the + /// system, this error may be returned even if the operation has completed successfully. For + /// example, a successful response from a server could have been delayed long enough for the + /// deadline to expire. + /// + DeadlineExceeded = 4, + + /// + /// Some requested entity (e.g., file or directory) was not found. + /// + NotFound = 5, + + /// + /// Some entity that we attempted to create (e.g., file or directory) already exists. + /// + AlreadyExists = 6, + + /// + /// The caller does not have permission to execute the specified operation. PERMISSION_DENIED + /// must not be used for rejections caused by exhausting some resource (use RESOURCE_EXHAUSTED + /// instead for those errors). PERMISSION_DENIED must not be used if the caller cannot be + /// identified (use UNAUTHENTICATED instead for those errors). + /// + PermissionDenied = 7, + + /// + /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system + /// is out of space. + /// + ResourceExhausted = 8, + + /// + /// Operation was rejected because the system is not in a state required for the operation's + /// execution. For example, directory to be deleted may be non-empty, an rmdir operation is + /// applied to a non-directory, etc. + /// A litmus test that may help a service implementor in deciding between FAILED_PRECONDITION, + /// ABORTED, and UNAVAILABLE: (a) Use UNAVAILABLE if the client can retry just the failing call. + /// (b) Use ABORTED if the client should retry at a higher-level (e.g., restarting a + /// read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client should not retry until + /// the system state has been explicitly fixed. E.g., if an "rmdir" fails because the directory + /// is non-empty, FAILED_PRECONDITION should be returned since the client should not retry unless + /// they have first fixed up the directory by deleting files from it. + /// + FailedPrecondition = 9, + + /// + /// The operation was aborted, typically due to a concurrency issue like sequencer check + /// failures, transaction aborts, etc. + /// + Aborted = 10, + + /// + /// Operation was attempted past the valid range. E.g., seeking or reading past end of file. + /// + /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed if the system + /// state changes. For example, a 32-bit file system will generate INVALID_ARGUMENT if asked to + /// read at an offset that is not in the range [0,2^32-1], but it will generate OUT_OF_RANGE if + /// asked to read from an offset past the current file size. + /// + /// There is a fair bit of overlap between FAILED_PRECONDITION and OUT_OF_RANGE. We recommend + /// using OUT_OF_RANGE (the more specific error) when it applies so that callers who are + /// iterating through a space can easily look for an OUT_OF_RANGE error to detect when they are + /// done. + /// + OutOfRange = 11, + + /// + /// Operation is not implemented or not supported/enabled in this service. + /// + Unimplemented = 12, + + /// + /// Internal errors. Means some invariants expected by underlying system has been broken. If you + /// see one of these errors, something is very broken. + /// + Internal = 13, + + /// + /// The service is currently unavailable. This is a most likely a transient condition and may be + /// corrected by retrying with a backoff. + /// + /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE. + /// + Unavailable = 14, + + /// + /// Unrecoverable data loss or corruption. + /// + DataLoss = 15, + + /// + /// The request does not have valid authentication credentials for the operation. + /// + Unauthenticated = 16, +} diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..aa87988869 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/TracerProviderBuilderExtensions.cs @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.GrpcNetClient; +using OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of gRPC client +/// instrumentation. +/// +public static class TracerProviderBuilderExtensions +{ + /// + /// Enables gRPC client instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcClientInstrumentation(this TracerProviderBuilder builder) + => AddGrpcClientInstrumentation(builder, name: null, configure: null); + + /// + /// Enables gRPC client instrumentation. + /// + /// being configured. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcClientInstrumentation( + this TracerProviderBuilder builder, + Action configure) + => AddGrpcClientInstrumentation(builder, name: null, configure); + + /// + /// Enables gRPC client instrumentation. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddGrpcClientInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configure) + { + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; + + if (configure != null) + { + builder.ConfigureServices(services => services.Configure(name, configure)); + } + + builder.AddSource(GrpcClientDiagnosticListener.ActivitySourceName); + builder.AddLegacySource("Grpc.Net.Client.GrpcOut"); + + return builder.AddInstrumentation(sp => + { + var options = sp.GetRequiredService>().Get(name); + + return new GrpcClientInstrumentation(options); + }); + } +} diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index 66a1c2ecb0..d64d96feb9 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -19,6 +19,7 @@ + diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs b/src/Shared/ActivityHelperExtensions.cs similarity index 93% rename from test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs rename to src/Shared/ActivityHelperExtensions.cs index a1df29f725..6a85d45527 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/ActivityHelperExtensions.cs +++ b/src/Shared/ActivityHelperExtensions.cs @@ -5,7 +5,7 @@ using System.Diagnostics; -namespace OpenTelemetry.Tests; +namespace OpenTelemetry.Trace; internal static class ActivityHelperExtensions { diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs index dd147d21e0..1ae08c8d15 100644 --- a/src/Shared/AssemblyVersionExtensions.cs +++ b/src/Shared/AssemblyVersionExtensions.cs @@ -26,7 +26,7 @@ public static string GetPackageVersion(this Assembly assembly) var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly"); -#if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER var indexOfPlusSign = informationalVersion!.IndexOf('+', StringComparison.Ordinal); #else var indexOfPlusSign = informationalVersion!.IndexOf('+'); diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs b/src/Shared/HttpRequestMessageContextPropagation.cs similarity index 89% rename from src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs rename to src/Shared/HttpRequestMessageContextPropagation.cs index 91d2a5c18a..2e81f52e64 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpRequestMessageContextPropagation.cs +++ b/src/Shared/HttpRequestMessageContextPropagation.cs @@ -5,7 +5,7 @@ using System.Net.Http; #endif -namespace OpenTelemetry.Instrumentation.Http; +namespace OpenTelemetry.Instrumentation; internal static class HttpRequestMessageContextPropagation { diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 9c68f55714..934b0d638c 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -21,6 +21,7 @@ + diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs index 7a3d9e08a7..898c9be4dc 100644 --- a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs +++ b/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs @@ -3,7 +3,9 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. using System.Collections.Generic; +#pragma warning restore IDE0005 // Using directive is unnecessary. using System.Diagnostics; namespace OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 90b9d26388..e41bdf2ee7 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Resources; -using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index d8c85549f4..91a0bb9a75 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index a040ac447c..38b9d15dce 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 8ae7952754..df940472e4 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/EventSourceTest.cs new file mode 100644 index 0000000000..66db176677 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/EventSourceTest.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests; + +public class EventSourceTest +{ + [Fact] + public void EventSourceTest_GrpcInstrumentationEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(GrpcInstrumentationEventSource.Log); + } +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs new file mode 100644 index 0000000000..08fa9e8c7b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NETFRAMEWORK +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Core; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests; + +public class GrpcServer : IDisposable + where TService : class +{ + private static readonly Random GlobalRandom = new(); + + private readonly IHost host; + + public GrpcServer() + { + // Allows gRPC client to call insecure gRPC services + // https://docs.microsoft.com/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.1#call-insecure-grpc-services-with-net-core-client + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); + + this.Port = 0; + + var retryCount = 5; + while (retryCount > 0) + { + try + { + this.Port = GlobalRandom.Next(2000, 5000); + this.host = this.CreateServer(); + this.host.StartAsync().GetAwaiter().GetResult(); + break; + } + catch (IOException) + { + retryCount--; + this.host.Dispose(); + } + } + } + + public int Port { get; } + + public void Dispose() + { + this.host.StopAsync(TimeSpan.FromSeconds(5)).GetAwaiter().GetResult(); + this.host.Dispose(); + GC.SuppressFinalize(this); + } + + private IHost CreateServer() + { + var hostBuilder = Host.CreateDefaultBuilder() + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder + .ConfigureKestrel(options => + { + // Setup a HTTP/2 endpoint without TLS. + options.ListenLocalhost(this.Port, o => o.Protocols = HttpProtocols.Http2); + }) + .UseStartup(); + }); + + return hostBuilder.Build(); + } + + private class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddGrpc(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGrpcService(); + }); + } + } +} +#endif diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs new file mode 100644 index 0000000000..fbb1928117 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs @@ -0,0 +1,66 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using OpenTelemetry.Instrumentation.GrpcNetClient; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests; + +public class GrpcTagHelperTests +{ + [Fact] + public void GrpcTagHelper_GetGrpcMethodFromActivity() + { + var grpcMethod = "/some.service/somemethod"; + using var activity = new Activity("operationName"); + activity.SetTag(GrpcTagHelper.GrpcMethodTagName, grpcMethod); + + var result = GrpcTagHelper.GetGrpcMethodFromActivity(activity); + + Assert.Equal(grpcMethod, result); + } + + [Theory] + [InlineData("Package.Service/Method", true, "Package.Service", "Method")] + [InlineData("/Package.Service/Method", true, "Package.Service", "Method")] + [InlineData("/ServiceWithNoPackage/Method", true, "ServiceWithNoPackage", "Method")] + [InlineData("/Some.Package.Service/Method", true, "Some.Package.Service", "Method")] + [InlineData("Invalid", false, "", "")] + public void GrpcTagHelper_TryParseRpcServiceAndRpcMethod(string grpcMethod, bool isSuccess, string expectedRpcService, string expectedRpcMethod) + { + var success = GrpcTagHelper.TryParseRpcServiceAndRpcMethod(grpcMethod, out var rpcService, out var rpcMethod); + + Assert.Equal(isSuccess, success); + Assert.Equal(expectedRpcService, rpcService); + Assert.Equal(expectedRpcMethod, rpcMethod); + } + + [Fact] + public void GrpcTagHelper_GetGrpcStatusCodeFromActivity() + { + using var activity = new Activity("operationName"); + activity.SetTag(GrpcTagHelper.GrpcStatusCodeTagName, "0"); + + bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + Assert.True(validConversion); + + var statusCode = GrpcTagHelper.ResolveSpanStatusForGrpcStatusCode(status); + activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, status); + + Assert.Equal(ActivityStatusCode.Unset, statusCode); + Assert.Equal(status, activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + } + + [Fact] + public void GrpcTagHelper_GetGrpcStatusCodeFromEmptyActivity() + { + using var activity = new Activity("operationName"); + + bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + Assert.False(validConversion); + Assert.Equal(-1, status); + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + } +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs new file mode 100644 index 0000000000..27c8b5a374 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs @@ -0,0 +1,76 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Net.Http; +#endif +using System.Net.Http.Headers; +using Google.Protobuf; +using Grpc.Net.Compression; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests.GrpcTestHelpers; + +internal static class ClientTestHelpers +{ + public static HttpClient CreateTestClient(Func> sendAsync, Uri baseAddress = null) + { + var handler = TestHttpMessageHandler.Create(sendAsync); + var httpClient = new HttpClient(handler); + httpClient.BaseAddress = baseAddress ?? new Uri("https://localhost"); + + return httpClient; + } + + public static Task CreateResponseContent(TResponse response, ICompressionProvider compressionProvider = null) + where TResponse : IMessage + { + return CreateResponseContentCore(new[] { response }, compressionProvider); + } + + public static async Task WriteResponseAsync(Stream ms, TResponse response, ICompressionProvider compressionProvider) + where TResponse : IMessage + { + var compress = false; + + byte[] data; + if (compressionProvider != null) + { + compress = true; + + var output = new MemoryStream(); + var compressionStream = compressionProvider.CreateCompressionStream(output, System.IO.Compression.CompressionLevel.Fastest); + var compressedData = response.ToByteArray(); + + compressionStream.Write(compressedData, 0, compressedData.Length); + compressionStream.Flush(); + compressionStream.Dispose(); + data = output.ToArray(); + } + else + { + data = response.ToByteArray(); + } + + await ResponseUtils.WriteHeaderAsync(ms, data.Length, compress, CancellationToken.None); +#if NET5_0_OR_GREATER + await ms.WriteAsync(data); +#else + await ms.WriteAsync(data, 0, data.Length); +#endif + } + + private static async Task CreateResponseContentCore(TResponse[] responses, ICompressionProvider compressionProvider) + where TResponse : IMessage + { + var ms = new MemoryStream(); + foreach (var response in responses) + { + await WriteResponseAsync(ms, response, compressionProvider); + } + + ms.Seek(0, SeekOrigin.Begin); + var streamContent = new StreamContent(ms); + streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/grpc"); + return streamContent; + } +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ResponseUtils.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ResponseUtils.cs new file mode 100644 index 0000000000..01180ebf54 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ResponseUtils.cs @@ -0,0 +1,76 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Buffers.Binary; +using System.Diagnostics; +using System.Net; +#if NETFRAMEWORK +using System.Net.Http; +#endif +using System.Net.Http.Headers; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests.GrpcTestHelpers; + +internal static class ResponseUtils +{ + internal const string MessageEncodingHeader = "grpc-encoding"; + internal const string IdentityGrpcEncoding = "identity"; + internal const string StatusTrailer = "grpc-status"; + internal static readonly MediaTypeHeaderValue GrpcContentTypeHeaderValue = new MediaTypeHeaderValue("application/grpc"); + internal static readonly Version ProtocolVersion = new Version(2, 0); + private const int MessageDelimiterSize = 4; // how many bytes it takes to encode "Message-Length" + private const int HeaderSize = MessageDelimiterSize + 1; // message length + compression flag + + public static HttpResponseMessage CreateResponse( + HttpStatusCode statusCode, + HttpContent payload, + global::Grpc.Core.StatusCode? grpcStatusCode = global::Grpc.Core.StatusCode.OK) + { + payload.Headers.ContentType = GrpcContentTypeHeaderValue; + + var message = new HttpResponseMessage(statusCode) + { + Content = payload, + Version = ProtocolVersion, + }; + + message.RequestMessage = new HttpRequestMessage(); +#if NETFRAMEWORK + message.RequestMessage.Properties[TrailingHeadersHelpers.ResponseTrailersKey] = new ResponseTrailers(); +#endif + message.Headers.Add(MessageEncodingHeader, IdentityGrpcEncoding); + + if (grpcStatusCode != null) + { + message.TrailingHeaders().Add(StatusTrailer, grpcStatusCode.Value.ToString("D")); + } + + return message; + } + + public static Task WriteHeaderAsync(Stream stream, int length, bool compress, CancellationToken cancellationToken) + { + var headerData = new byte[HeaderSize]; + + // Compression flag + headerData[0] = compress ? (byte)1 : (byte)0; + + // Message length + EncodeMessageLength(length, headerData.AsSpan(1)); + + return stream.WriteAsync(headerData, 0, headerData.Length, cancellationToken); + } + + private static void EncodeMessageLength(int messageLength, Span destination) + { + Debug.Assert(destination.Length >= MessageDelimiterSize, "Buffer too small to encode message length."); + + BinaryPrimitives.WriteUInt32BigEndian(destination, (uint)messageLength); + } + +#if NETFRAMEWORK + private class ResponseTrailers : HttpHeaders + { + } +#endif +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs new file mode 100644 index 0000000000..4f1837ce70 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Net.Http; +#endif + +namespace OpenTelemetry.Instrumentation.Grpc.Tests.GrpcTestHelpers; + +public class TestHttpMessageHandler : HttpMessageHandler +{ + private readonly Func> sendAsync; + + public TestHttpMessageHandler(Func> sendAsync) + { + this.sendAsync = sendAsync; + } + + public static TestHttpMessageHandler Create(Func> sendAsync) + { + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + return new TestHttpMessageHandler(async (request, cancellationToken) => + { + using var registration = cancellationToken.Register(() => tcs.TrySetCanceled()); + + var result = await Task.WhenAny(sendAsync(request), tcs.Task); + return await result; + }); + } + + public static TestHttpMessageHandler Create(Func> sendAsync) + { + return new TestHttpMessageHandler(sendAsync); + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + return this.sendAsync(request, cancellationToken); + } +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs new file mode 100644 index 0000000000..22e6e37eb4 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NETFRAMEWORK +using System.Net.Http; +#endif +using System.Net.Http.Headers; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests.GrpcTestHelpers; + +internal static class TrailingHeadersHelpers +{ + public const string ResponseTrailersKey = "__ResponseTrailers"; + + public static HttpHeaders TrailingHeaders(this HttpResponseMessage responseMessage) + { +#if !NETFRAMEWORK + return responseMessage.TrailingHeaders; +#else + if (responseMessage.RequestMessage.Properties.TryGetValue(ResponseTrailersKey, out var headers) && + headers is HttpHeaders httpHeaders) + { + return httpHeaders; + } + + // App targets .NET Standard 2.0 and the handler hasn't set trailers + // in RequestMessage.Properties with known key. Return empty collection. + // Client call will likely fail because it is unable to get a grpc-status. + return ResponseTrailers.Empty; +#endif + } + +#if NETFRAMEWORK + public static void EnsureTrailingHeaders(this HttpResponseMessage responseMessage) + { + if (!responseMessage.RequestMessage.Properties.ContainsKey(ResponseTrailersKey)) + { + responseMessage.RequestMessage.Properties[ResponseTrailersKey] = new ResponseTrailers(); + } + } + + private class ResponseTrailers : HttpHeaders + { + public static readonly ResponseTrailers Empty = new ResponseTrailers(); + } +#endif +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs new file mode 100644 index 0000000000..f06eb5a6fc --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs @@ -0,0 +1,441 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Net; +using Greet; +#if !NETFRAMEWORK +using Grpc.Core; +#endif +using Grpc.Net.Client; +using Microsoft.Extensions.DependencyInjection; +#if !NETFRAMEWORK +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Tests; +#endif +using OpenTelemetry.Instrumentation.Grpc.Tests.GrpcTestHelpers; +using OpenTelemetry.Instrumentation.GrpcNetClient; +using OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; +using OpenTelemetry.Trace; +using Xunit; +using Status = OpenTelemetry.Trace.Status; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests; + +public partial class GrpcTests +{ + [Theory] + [InlineData("http://localhost")] + [InlineData("http://localhost", false)] + [InlineData("http://127.0.0.1")] + [InlineData("http://127.0.0.1", false)] + [InlineData("http://[::1]")] + [InlineData("http://[::1]", false)] + public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress, bool shouldEnrich = true) + { + bool enrichWithHttpRequestMessageCalled = false; + bool enrichWithHttpResponseMessageCalled = false; + + var uri = new Uri($"{baseAddress}:1234"); + var uriHostNameType = Uri.CheckHostName(uri.Host); + + using var httpClient = ClientTestHelpers.CreateTestClient(async request => + { + var streamContent = await ClientTestHelpers.CreateResponseContent(new HelloReply()); + var response = ResponseUtils.CreateResponse(HttpStatusCode.OK, streamContent, grpcStatusCode: global::Grpc.Core.StatusCode.OK); + response.TrailingHeaders().Add("grpc-message", "value"); + return response; + }); + + var exportedItems = new List(); + + using var parent = new Activity("parent") + .SetIdFormat(ActivityIdFormat.W3C) + .Start(); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddGrpcClientInstrumentation(options => + { + if (shouldEnrich) + { + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + } + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + var channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions + { + HttpClient = httpClient, + }); + var client = new Greeter.GreeterClient(channel); + var rs = client.SayHello(new HelloRequest()); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + ValidateGrpcActivity(activity); + Assert.Equal(parent.TraceId, activity.Context.TraceId); + Assert.Equal(parent.SpanId, activity.ParentSpanId); + Assert.NotEqual(parent.SpanId, activity.Context.SpanId); + Assert.NotEqual(default, activity.Context.SpanId); + + Assert.Equal($"greet.Greeter/SayHello", activity.DisplayName); + Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem)); + Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService)); + Assert.Equal("SayHello", activity.GetTagValue(SemanticConventions.AttributeRpcMethod)); + + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + { + Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress)); + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + } + else + { + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress)); + Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + } + + Assert.Equal(uri.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort)); + Assert.Equal(Status.Unset, activity.GetStatus()); + + // Tags added by the library then removed from the instrumentation + Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName)); + Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); + Assert.Equal(0, activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + + if (shouldEnrich) + { + Assert.True(enrichWithHttpRequestMessageCalled); + Assert.True(enrichWithHttpResponseMessageCalled); + } + } + +#if NET6_0_OR_GREATER + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GrpcAndHttpClientInstrumentationIsInvoked(bool shouldEnrich) + { + var uri = new Uri($"http://localhost:{this.server.Port}"); + var exportedItems = new List(); + + using var parent = new Activity("parent") + .Start(); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddGrpcClientInstrumentation(options => + { + if (shouldEnrich) + { + options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => + { + activity.SetTag("enrichedWithHttpRequestMessage", "yes"); + }; + + options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => + { + activity.SetTag("enrichedWithHttpResponseMessage", "yes"); + }; + } + }) + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + // With net5, based on the grpc changes, the quantity of default activities changed. + // TODO: This is a workaround. https://github.com/open-telemetry/opentelemetry-dotnet/issues/1490 + using var channel = GrpcChannel.ForAddress(uri, new GrpcChannelOptions() + { + HttpClient = new HttpClient(), + }); + + var client = new Greeter.GreeterClient(channel); + var rs = client.SayHello(new HelloRequest()); + } + + Assert.Equal(2, exportedItems.Count); + var httpSpan = exportedItems.Single(activity => activity.OperationName == OperationNameHttpOut); + var grpcSpan = exportedItems.Single(activity => activity.OperationName == OperationNameGrpcOut); + + ValidateGrpcActivity(grpcSpan); + Assert.Equal($"greet.Greeter/SayHello", grpcSpan.DisplayName); + Assert.Equal(0, grpcSpan.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + Assert.Equal("POST", httpSpan.DisplayName); + Assert.Equal(grpcSpan.SpanId, httpSpan.ParentSpanId); + + if (shouldEnrich) + { + Assert.Single(grpcSpan.Tags, tag => tag.Key == "enrichedWithHttpRequestMessage" && tag.Value == "yes"); + Assert.Single(grpcSpan.Tags, tag => tag.Key == "enrichedWithHttpResponseMessage" && tag.Value == "yes"); + } + else + { + Assert.Empty(grpcSpan.Tags.Where(tag => tag.Key == "enrichedWithHttpRequestMessage")); + Assert.Empty(grpcSpan.Tags.Where(tag => tag.Key == "enrichedWithHttpResponseMessage")); + } + } + + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + public void GrpcAndHttpClientInstrumentationWithSuppressInstrumentation() + { + var uri = new Uri($"http://localhost:{this.server.Port}"); + var exportedItems = new List(); + + using var parent = new Activity("parent") + .Start(); + + using (Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddGrpcClientInstrumentation(o => o.SuppressDownstreamInstrumentation = true) + .AddHttpClientInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + Parallel.ForEach( + new int[4], + new ParallelOptions + { + MaxDegreeOfParallelism = 4, + }, + (value) => + { + var channel = GrpcChannel.ForAddress(uri); + var client = new Greeter.GreeterClient(channel); + var rs = client.SayHello(new HelloRequest()); + }); + } + + Assert.Equal(4, exportedItems.Count); + var grpcSpan1 = exportedItems[0]; + var grpcSpan2 = exportedItems[1]; + var grpcSpan3 = exportedItems[2]; + var grpcSpan4 = exportedItems[3]; + + ValidateGrpcActivity(grpcSpan1); + Assert.Equal($"greet.Greeter/SayHello", grpcSpan1.DisplayName); + Assert.Equal(0, grpcSpan1.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + + ValidateGrpcActivity(grpcSpan2); + Assert.Equal($"greet.Greeter/SayHello", grpcSpan2.DisplayName); + Assert.Equal(0, grpcSpan2.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + + ValidateGrpcActivity(grpcSpan3); + Assert.Equal($"greet.Greeter/SayHello", grpcSpan3.DisplayName); + Assert.Equal(0, grpcSpan3.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + + ValidateGrpcActivity(grpcSpan4); + Assert.Equal($"greet.Greeter/SayHello", grpcSpan4.DisplayName); + Assert.Equal(0, grpcSpan4.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + } + + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + public void GrpcPropagatesContextWithSuppressInstrumentationOptionSetToTrue() + { + try + { + var uri = new Uri($"http://localhost:{this.server.Port}"); + var exportedItems = new List(); + + using var source = new ActivitySource("test-source"); + + var propagator = new CustomTextMapPropagator(); + propagator.InjectValues.Add("customField", context => "customValue"); + + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + propagator, + })); + + using (Sdk.CreateTracerProviderBuilder() + .AddSource("test-source") + .AddGrpcClientInstrumentation(o => + { + o.SuppressDownstreamInstrumentation = true; + }) + .AddHttpClientInstrumentation() + .AddAspNetCoreInstrumentation(options => + { + options.EnrichWithHttpRequest = (activity, request) => + { + activity.SetCustomProperty("customField", request.Headers["customField"].ToString()); + }; + }) // Instrumenting the server side as well + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var activity = source.StartActivity("parent"); + Assert.NotNull(activity); + var channel = GrpcChannel.ForAddress(uri); + var client = new Greeter.GreeterClient(channel); + var rs = client.SayHello(new HelloRequest()); + } + + var serverActivity = exportedItems.Single(activity => activity.OperationName == OperationNameHttpRequestIn); + var clientActivity = exportedItems.Single(activity => activity.OperationName == OperationNameGrpcOut); + + Assert.Equal($"greet.Greeter/SayHello", clientActivity.DisplayName); + Assert.Equal($"POST /greet.Greeter/SayHello", serverActivity.DisplayName); + Assert.Equal(clientActivity.TraceId, serverActivity.TraceId); + Assert.Equal(clientActivity.SpanId, serverActivity.ParentSpanId); + Assert.Equal(0, clientActivity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + Assert.Equal("customValue", serverActivity.GetCustomProperty("customField") as string); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + [Fact] + public void GrpcDoesNotPropagateContextWithSuppressInstrumentationOptionSetToFalse() + { + try + { + var uri = new Uri($"http://localhost:{this.server.Port}"); + var exportedItems = new List(); + using var source = new ActivitySource("test-source"); + + bool isPropagatorCalled = false; + var propagator = new CustomTextMapPropagator + { + Injected = (context) => isPropagatorCalled = true, + }; + + Sdk.SetDefaultTextMapPropagator(propagator); + + var headers = new Metadata(); + + using (Sdk.CreateTracerProviderBuilder() + .AddSource("test-source") + .AddGrpcClientInstrumentation(o => + { + o.SuppressDownstreamInstrumentation = false; + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var activity = source.StartActivity("parent"); + var channel = GrpcChannel.ForAddress(uri); + var client = new Greeter.GreeterClient(channel); + var rs = client.SayHello(new HelloRequest(), headers); + } + + Assert.Equal(2, exportedItems.Count); + + var parentActivity = exportedItems.Single(activity => activity.OperationName == "parent"); + var clientActivity = exportedItems.Single(activity => activity.OperationName == OperationNameGrpcOut); + + Assert.Equal(clientActivity.ParentSpanId, parentActivity.SpanId); + + // Propagator is not called + Assert.False(isPropagatorCalled); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + public void GrpcClientInstrumentationRespectsSdkSuppressInstrumentation() + { + try + { + var uri = new Uri($"http://localhost:{this.server.Port}"); + var exportedItems = new List(); + + using var source = new ActivitySource("test-source"); + + bool isPropagatorCalled = false; + var propagator = new CustomTextMapPropagator(); + propagator.Injected = (context) => isPropagatorCalled = true; + + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + propagator, + })); + + using (Sdk.CreateTracerProviderBuilder() + .AddSource("test-source") + .AddGrpcClientInstrumentation(o => + { + o.SuppressDownstreamInstrumentation = true; + }) + .AddInMemoryExporter(exportedItems) + .Build()) + { + using var activity = source.StartActivity("parent"); + using (SuppressInstrumentationScope.Begin()) + { + var channel = GrpcChannel.ForAddress(uri); + var client = new Greeter.GreeterClient(channel); + var rs = client.SayHello(new HelloRequest()); + } + } + + // If suppressed, activity is not emitted and + // propagation is also not performed. + Assert.Single(exportedItems); + Assert.False(isPropagatorCalled); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } +#endif + + [Fact] + public void AddGrpcClientInstrumentationNamedOptionsSupported() + { + int defaultExporterOptionsConfigureOptionsInvocations = 0; + int namedExporterOptionsConfigureOptionsInvocations = 0; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + + services.Configure("Instrumentation2", o => namedExporterOptionsConfigureOptionsInvocations++); + }) + .AddGrpcClientInstrumentation() + .AddGrpcClientInstrumentation("Instrumentation2", configure: null) + .Build(); + + Assert.Equal(1, defaultExporterOptionsConfigureOptionsInvocations); + Assert.Equal(1, namedExporterOptionsConfigureOptionsInvocations); + } + + [Fact] + public void Grpc_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddGrpcClientInstrumentation()); + } + + private static void ValidateGrpcActivity(Activity activityToValidate) + { + Assert.Equal(GrpcClientDiagnosticListener.ActivitySourceName, activityToValidate.Source.Name); + Assert.Equal(GrpcClientDiagnosticListener.Version, activityToValidate.Source.Version); + Assert.Equal(ActivityKind.Client, activityToValidate.Kind); + } +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs new file mode 100644 index 0000000000..1c397a27ab --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs @@ -0,0 +1,205 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System.Diagnostics; +using System.Net; +using Greet; +using Grpc.Core; +using Grpc.Net.Client; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.Grpc.Services.Tests; +using OpenTelemetry.Instrumentation.GrpcNetClient; +using OpenTelemetry.Trace; +using Xunit; +using Status = OpenTelemetry.Trace.Status; + +namespace OpenTelemetry.Instrumentation.Grpc.Tests; + +public partial class GrpcTests : IDisposable +{ + private const string OperationNameHttpRequestIn = "Microsoft.AspNetCore.Hosting.HttpRequestIn"; + private const string OperationNameGrpcOut = "Grpc.Net.Client.GrpcOut"; + private const string OperationNameHttpOut = "System.Net.Http.HttpRequestOut"; + + private readonly GrpcServer server; + + public GrpcTests() + { + this.server = new GrpcServer(); + } + + [Theory] + [InlineData(null)] + [InlineData("true")] + [InlineData("false")] + [InlineData("True")] + [InlineData("False")] + public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(string enableGrpcAspNetCoreSupport) + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION"] = enableGrpcAspNetCoreSupport, + }) + .Build(); + + var exportedItems = new List(); + using var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var clientLoopbackAddresses = new[] { IPAddress.Loopback.ToString(), IPAddress.IPv6Loopback.ToString() }; + var uri = new Uri($"http://localhost:{this.server.Port}"); + + using var channel = GrpcChannel.ForAddress(uri); + var client = new Greeter.GreeterClient(channel); + var returnMsg = client.SayHello(new HelloRequest()).Message; + Assert.False(string.IsNullOrEmpty(returnMsg)); + + WaitForExporterToReceiveItems(exportedItems, 1); + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(ActivityKind.Server, activity.Kind); + + if (enableGrpcAspNetCoreSupport != null && enableGrpcAspNetCoreSupport.Equals("true", StringComparison.OrdinalIgnoreCase)) + { + Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem)); + Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService)); + Assert.Equal("SayHello", activity.GetTagValue(SemanticConventions.AttributeRpcMethod)); + Assert.Contains(activity.GetTagValue(SemanticConventions.AttributeClientAddress), clientLoopbackAddresses); + Assert.NotEqual(0, activity.GetTagValue(SemanticConventions.AttributeClientPort)); + Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName)); + Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); + Assert.Equal(0, activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + } + else + { + Assert.NotNull(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName)); + Assert.NotNull(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); + } + + Assert.Equal(Status.Unset, activity.GetStatus()); + + // The following are http.* attributes that are also included on the span for the gRPC invocation. + Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + Assert.Equal(this.server.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort)); + Assert.Equal("POST", activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); + Assert.Equal("http", activity.GetTagValue(SemanticConventions.AttributeUrlScheme)); + Assert.Equal("/greet.Greeter/SayHello", activity.GetTagValue(SemanticConventions.AttributeUrlPath)); + Assert.Equal("2", activity.GetTagValue(SemanticConventions.AttributeNetworkProtocolVersion)); + Assert.StartsWith("grpc-dotnet", activity.GetTagValue(SemanticConventions.AttributeUserAgentOriginal) as string); + } + +#if NET6_0_OR_GREATER + [Theory(Skip = "Skipping for .NET 6 and higher due to bug #3023")] +#endif + [InlineData(null)] + [InlineData("true")] + [InlineData("false")] + [InlineData("True")] + [InlineData("False")] + public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewActivity(string enableGrpcAspNetCoreSupport) + { + try + { + // B3Propagator along with the headers passed to the client.SayHello ensure that the instrumentation creates a sibling activity + Sdk.SetDefaultTextMapPropagator(new Extensions.Propagators.B3Propagator()); + var exportedItems = new List(); + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION"] = enableGrpcAspNetCoreSupport, + }) + .Build(); + + using var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var clientLoopbackAddresses = new[] { IPAddress.Loopback.ToString(), IPAddress.IPv6Loopback.ToString() }; + var uri = new Uri($"http://localhost:{this.server.Port}"); + + using var channel = GrpcChannel.ForAddress(uri); + var client = new Greeter.GreeterClient(channel); + var headers = new Metadata + { + { "traceparent", "00-120dc44db5b736468afb112197b0dbd3-5dfbdf27ec544544-01" }, + { "x-b3-traceid", "120dc44db5b736468afb112197b0dbd3" }, + { "x-b3-spanid", "b0966f651b9e0126" }, + { "x-b3-sampled", "1" }, + }; + client.SayHello(new HelloRequest(), headers); + + WaitForExporterToReceiveItems(exportedItems, 1); + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(ActivityKind.Server, activity.Kind); + + if (enableGrpcAspNetCoreSupport != null && enableGrpcAspNetCoreSupport.Equals("true", StringComparison.OrdinalIgnoreCase)) + { + Assert.Equal("grpc", activity.GetTagValue(SemanticConventions.AttributeRpcSystem)); + Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService)); + Assert.Equal("SayHello", activity.GetTagValue(SemanticConventions.AttributeRpcMethod)); + Assert.Contains(activity.GetTagValue(SemanticConventions.AttributeNetPeerIp), clientLoopbackAddresses); + Assert.NotEqual(0, activity.GetTagValue(SemanticConventions.AttributeNetPeerPort)); + Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName)); + Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); + Assert.Equal(0, activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); + } + else + { + Assert.NotNull(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName)); + Assert.NotNull(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); + } + + Assert.Equal(Status.Unset, activity.GetStatus()); + + // The following are http.* attributes that are also included on the span for the gRPC invocation. + Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeNetHostName)); + Assert.Equal(this.server.Port, activity.GetTagValue(SemanticConventions.AttributeNetHostPort)); + Assert.Equal("POST", activity.GetTagValue(SemanticConventions.AttributeHttpMethod)); + Assert.Equal("/greet.Greeter/SayHello", activity.GetTagValue(SemanticConventions.AttributeHttpTarget)); + Assert.Equal($"http://localhost:{this.server.Port}/greet.Greeter/SayHello", activity.GetTagValue(SemanticConventions.AttributeHttpUrl)); + Assert.StartsWith("grpc-dotnet", activity.GetTagValue(SemanticConventions.AttributeHttpUserAgent) as string); + } + finally + { + // Set the SDK to use the default propagator for other unit tests + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + public void Dispose() + { + this.server.Dispose(); + GC.SuppressFinalize(this); + } + + private static void WaitForExporterToReceiveItems(List itemsReceived, int itemCount) + { + // We need to let End callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the End callback to complete + Assert.True(SpinWait.SpinUntil( + () => + { + Thread.Sleep(10); + return itemsReceived.Count >= itemCount; + }, + TimeSpan.FromSeconds(1))); + } +} +#endif diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj new file mode 100644 index 0000000000..568b59d173 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -0,0 +1,43 @@ + + + Unit test project for OpenTelemetry Grpc for .NET instrumentation + net8.0;net7.0;net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + $(NoWarn),CS8981 + enable + + disable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Proto/greet.proto b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Proto/greet.proto new file mode 100644 index 0000000000..7945286d36 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Proto/greet.proto @@ -0,0 +1,35 @@ +// Copyright 2019 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package greet; + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc SayHellos (HelloRequest) returns (stream HelloReply); +} + +service SecondGreeter { + rpc SayHello (HelloRequest) returns (HelloReply); + rpc SayHellos (HelloRequest) returns (stream HelloReply); +} + +message HelloRequest { + string name = 1; +} + +message HelloReply { + string message = 1; +} diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs new file mode 100644 index 0000000000..f2f7b4c1aa --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Greet; +using Grpc.Core; +using Microsoft.Extensions.Logging; + +namespace OpenTelemetry.Instrumentation.Grpc.Services.Tests; + +public class GreeterService : Greeter.GreeterBase +{ + private readonly ILogger logger; + + public GreeterService(ILoggerFactory loggerFactory) + { + this.logger = loggerFactory.CreateLogger(); + } + + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + this.logger.LogInformation("Sending hello to {Name}", request.Name); + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + + public override async Task SayHellos(HelloRequest request, IServerStreamWriter responseStream, ServerCallContext context) + { + var i = 0; + while (!context.CancellationToken.IsCancellationRequested) + { + var message = $"How are you {request.Name}? {++i}"; + this.logger.LogInformation("Sending greeting {Message}.", message); + + await responseStream.WriteAsync(new HelloReply { Message = message }); + + // Gotta look busy + await Task.Delay(1000); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 8c103d0899..9c004bf25d 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 7f500d5cce..e9f24130cf 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index d4adc75169..25d0252557 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -6,7 +6,9 @@ using Microsoft.Data.SqlClient; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Instrumentation.SqlClient.Implementation; +#if !NETFRAMEWORK using OpenTelemetry.Tests; +#endif using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs index e729190d8c..1387a27577 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTraceInstrumentationOptionsTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index a6fd35baef..c737a8abd6 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -9,7 +9,6 @@ #if !NETFRAMEWORK using System.Net.Sockets; #endif -using OpenTelemetry.Tests; using OpenTelemetry.Trace; using StackExchange.Redis; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 8f0ae3aee8..efcb055383 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -8,7 +8,7 @@ - + From 1d20bf70ebc6809f3e401d4cc5c72e8fe7f6581f Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 7 May 2024 15:08:14 -0700 Subject: [PATCH 1047/1499] [Exporter.Geneva] Add exemplar support for otlp protobuf format (#1703) --- .../CHANGELOG.md | 7 + .../OtlpProtobuf/FieldNumberConstants.cs | 8 + .../OtlpProtobuf/OtlpProtobufSerializer.cs | 74 +++- .../OtlpProtobufMetricExporterTests.cs | 323 ++++++++++++++++-- 4 files changed, 373 insertions(+), 39 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 03533c9b0a..a6c66a1d42 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +* **Experimental (pre-release builds only)**: Add support for exporting + exemplars when OTLP protobuf encoding is enabled via + `PrivatePreviewEnableOtlpProtobufEncoding=true` in the connection string. + ([#1703](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1703)) + ## 1.8.0-rc.1 Released 2024-May-02 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs index a3c88ac8d6..885044ec76 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs @@ -101,6 +101,14 @@ internal static class FieldNumberConstants internal const int InstrumentationScope_attributes = 3; internal const int InstrumentationScope_dropped_attributes_count = 4; + // Exemplar + internal const int Exemplar_attributes = 7; + internal const int Exemplar_time_unix_nano = 2; + internal const int Exemplar_as_double = 3; + internal const int Exemplar_as_int = 6; + internal const int Exemplar_span_id = 4; + internal const int Exemplar_trace_id = 5; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int GetMetricTypeFieldNumber(MetricType metricType) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 37cee1a24c..d836afb309 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -386,7 +386,15 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) } } - // TODO: exemplars. +#if EXPOSE_EXPERIMENTAL_FEATURES + if (metricPoint.TryGetExemplars(out var exemplars)) + { + foreach (ref readonly var exemplar in exemplars) + { + this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.HistogramDataPoint_exemplars); + } + } +#endif var metricPointStartPosition = this.metricPointTagAndLengthIndex; @@ -444,7 +452,22 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum cursor += this.prepopulatedNumberDataPointAttributesLength; } - // TODO: exemplars. +#if EXPOSE_EXPERIMENTAL_FEATURES + if (metricPoint.TryGetExemplars(out var exemplars)) + { + foreach (ref readonly var exemplar in exemplars) + { + if (typeof(T) == typeof(long)) + { + this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.LongValue, FieldNumberConstants.NumberDataPoint_exemplars); + } + else if (typeof(T) == typeof(double)) + { + this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.NumberDataPoint_exemplars); + } + } + } +#endif var metricPointStartPosition = this.metricPointTagAndLengthIndex; @@ -452,6 +475,53 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, fieldNumber, WireType.LEN); } +#if EXPOSE_EXPERIMENTAL_FEATURES + private void SerializeExemplar(byte[] buffer, ref int cursor, in Exemplar exemplar, T value, int fieldNumber) + { + int exemplarTagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int valueIndex = cursor; + + this.SerializeExemplarTags(buffer, ref cursor, exemplar.FilteredTags); + + if (typeof(T) == typeof(long)) + { + // Casting to ulong is ok here as the bit representation for long versus ulong will be the same + // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_int, (ulong)(long)(object)value); + } + else if (typeof(T) == typeof(double)) + { + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_double, (double)(object)value); + } + + var time = (ulong)exemplar.Timestamp.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_time_unix_nano, time); + + if (exemplar.SpanId != default) + { + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref cursor, 16, FieldNumberConstants.Exemplar_trace_id, WireType.LEN); + var traceBytes = new Span(buffer, cursor, 16); + exemplar.TraceId.CopyTo(traceBytes); + cursor += 16; + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref cursor, 8, FieldNumberConstants.Exemplar_span_id, WireType.LEN); + var spanBytes = new Span(buffer, cursor, 8); + exemplar.SpanId.CopyTo(spanBytes); + cursor += 8; + } + + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref exemplarTagAndLengthIndex, cursor - valueIndex, fieldNumber, WireType.LEN); + } + + private void SerializeExemplarTags(byte[] buffer, ref int cursor, ReadOnlyFilteredTagCollection tags) + { + foreach (var tag in tags) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, FieldNumberConstants.Exemplar_attributes); + } + } +#endif + private void WriteIndividualMessageTagsAndLength(byte[] buffer, ref int cursor, MetricType metricType) { var instrumentIndex = this.instrumentTagAndLengthIndex; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 3635a8ee99..6fbef258de 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -10,6 +10,7 @@ using Google.Protobuf.Collections; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; +using OpenTelemetry.Trace; using Xunit; using OtlpCollector = OpenTelemetry.Proto.Collector.Metrics.V1; using OtlpCommon = OpenTelemetry.Proto.Common.V1; @@ -29,6 +30,29 @@ public class OtlpProtobufMetricExporterTests { "Dim3", 3 }, }; + private static readonly string[] TagKeys = new[] + { + "boolKey", + "doubleKey", + "intKey", + "longKey", + "negativeDoubleKey", + "negativeIntKey", + "negativeLongKey", + "negativeSbyteKey", + "negativeShortKey", + "sByteKey", + "shortKey", + "stringValueAsciiKey", + "stringValueMixAsciiAndUnicodeKey", + "stringValueUnicodeKey", + "uintKey", + "ulongKey", + "ushortKey", + }; + + private TagList exemplarTagList; + public OtlpProtobufMetricExporterTests() { this.TagList = default; @@ -69,27 +93,86 @@ public OtlpProtobufMetricExporterTests() this.TagList.Add(new("uintKey", uintValue)); this.TagList.Add(new("ulongKey", ulongValue)); this.TagList.Add(new("ushortKey", ushortValue)); + + this.exemplarTagList = this.TagList; + this.exemplarTagList.Add(new("zfilteredKey1", "zfilteredValue1")); } [Theory] - [InlineData("longcounter", 123L, null, true, true)] - [InlineData("longcounter", 123L, null, true, false)] - [InlineData("longcounter", 123L, null, false, true)] - [InlineData("longcounter", 123L, null, false, false)] - [InlineData("doublecounter", null, 123.45, true, true)] - [InlineData("doublecounter", null, 123.45, true, false)] - [InlineData("doublecounter", null, 123.45, false, true)] - [InlineData("doublecounter", null, 123.45, false, false)] - [InlineData("longcounter", -123L, null, true, true)] - [InlineData("longcounter", -123L, null, true, false)] - [InlineData("longcounter", -123L, null, false, true)] - [InlineData("longcounter", -123L, null, false, false)] - [InlineData("doublecounter", null, -123.45, true, true)] - [InlineData("doublecounter", null, -123.45, true, false)] - [InlineData("doublecounter", null, -123.45, false, true)] - [InlineData("doublecounter", null, -123.45, false, false)] - public void CounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace) + [InlineData("longcounter", 123L, null, true, true, true, true)] + [InlineData("longcounter", 123L, null, true, true, true, false)] + [InlineData("longcounter", 123L, null, true, true, false, true)] + [InlineData("longcounter", 123L, null, true, true, false, false)] + [InlineData("longcounter", 123L, null, true, false, true, true)] + [InlineData("longcounter", 123L, null, true, false, true, false)] + [InlineData("longcounter", 123L, null, true, false, false, true)] + [InlineData("longcounter", 123L, null, true, false, false, false)] + [InlineData("longcounter", 123L, null, false, true, true, true)] + [InlineData("longcounter", 123L, null, false, true, true, false)] + [InlineData("longcounter", 123L, null, false, true, false, true)] + [InlineData("longcounter", 123L, null, false, true, false, false)] + [InlineData("longcounter", 123L, null, false, false, true, true)] + [InlineData("longcounter", 123L, null, false, false, true, false)] + [InlineData("longcounter", 123L, null, false, false, false, true)] + [InlineData("longcounter", 123L, null, false, false, false, false)] + [InlineData("doublecounter", null, 123.45, true, true, true, true)] + [InlineData("doublecounter", null, 123.45, true, true, true, false)] + [InlineData("doublecounter", null, 123.45, true, true, false, true)] + [InlineData("doublecounter", null, 123.45, true, true, false, false)] + [InlineData("doublecounter", null, 123.45, true, false, true, true)] + [InlineData("doublecounter", null, 123.45, true, false, true, false)] + [InlineData("doublecounter", null, 123.45, true, false, false, true)] + [InlineData("doublecounter", null, 123.45, true, false, false, false)] + [InlineData("doublecounter", null, 123.45, false, true, true, true)] + [InlineData("doublecounter", null, 123.45, false, true, true, false)] + [InlineData("doublecounter", null, 123.45, false, true, false, true)] + [InlineData("doublecounter", null, 123.45, false, true, false, false)] + [InlineData("doublecounter", null, 123.45, false, false, true, true)] + [InlineData("doublecounter", null, 123.45, false, false, true, false)] + [InlineData("doublecounter", null, 123.45, false, false, false, true)] + [InlineData("doublecounter", null, 123.45, false, false, false, false)] + [InlineData("longcounter", -123L, null, true, true, true, true)] + [InlineData("longcounter", -123L, null, true, true, true, false)] + [InlineData("longcounter", -123L, null, true, true, false, true)] + [InlineData("longcounter", -123L, null, true, true, false, false)] + [InlineData("longcounter", -123L, null, true, false, true, true)] + [InlineData("longcounter", -123L, null, true, false, true, false)] + [InlineData("longcounter", -123L, null, true, false, false, true)] + [InlineData("longcounter", -123L, null, true, false, false, false)] + [InlineData("longcounter", -123L, null, false, true, true, true)] + [InlineData("longcounter", -123L, null, false, true, true, false)] + [InlineData("longcounter", -123L, null, false, true, false, true)] + [InlineData("longcounter", -123L, null, false, true, false, false)] + [InlineData("longcounter", -123L, null, false, false, true, true)] + [InlineData("longcounter", -123L, null, false, false, true, false)] + [InlineData("longcounter", -123L, null, false, false, false, true)] + [InlineData("longcounter", -123L, null, false, false, false, false)] + [InlineData("doublecounter", null, -123.45, true, true, true, true)] + [InlineData("doublecounter", null, -123.45, true, true, true, false)] + [InlineData("doublecounter", null, -123.45, true, true, false, true)] + [InlineData("doublecounter", null, -123.45, true, true, false, false)] + [InlineData("doublecounter", null, -123.45, true, false, true, true)] + [InlineData("doublecounter", null, -123.45, true, false, true, false)] + [InlineData("doublecounter", null, -123.45, true, false, false, true)] + [InlineData("doublecounter", null, -123.45, true, false, false, false)] + [InlineData("doublecounter", null, -123.45, false, true, true, true)] + [InlineData("doublecounter", null, -123.45, false, true, true, false)] + [InlineData("doublecounter", null, -123.45, false, true, false, true)] + [InlineData("doublecounter", null, -123.45, false, true, false, false)] + [InlineData("doublecounter", null, -123.45, false, false, true, true)] + [InlineData("doublecounter", null, -123.45, false, false, true, false)] + [InlineData("doublecounter", null, -123.45, false, false, false, true)] + [InlineData("doublecounter", null, -123.45, false, false, false, false)] + public void CounterSerializationSingleMetricPoint(string instrumentName, long? longValue, double? doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace, bool isExemplarsEnabled, bool isTracingEnabled) { + Activity activity = null; + + if (isTracingEnabled) + { + activity = new Activity("Custom Activity"); + activity.Start(); + } + using var meter = new Meter(nameof(this.CounterSerializationSingleMetricPoint), "0.0.1"); var exportedItems = new List(); @@ -115,21 +198,43 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l var resourceBuilder = ResourceBuilder.CreateDefault().Clear() .AddAttributes(resourceAttributes); - using var meterProvider = Sdk.CreateMeterProviderBuilder() + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.CounterSerializationSingleMetricPoint)) - .AddReader(inMemoryReader) - .Build(); + .AddReader(inMemoryReader); + if (isExemplarsEnabled) + { +#if EXPOSE_EXPERIMENTAL_FEATURES + meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); + meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = TagKeys }); +#endif + } + + var meterProvider = meterProviderBuilder.Build(); if (longValue != null) { var counter = meter.CreateCounter(instrumentName); - counter.Add(longValue.Value, this.TagList); + if (isExemplarsEnabled) + { + counter.Add(longValue.Value, this.exemplarTagList); + } + else + { + counter.Add(longValue.Value, this.TagList); + } } else { var counter = meter.CreateCounter(instrumentName); - counter.Add(doubleValue.Value, this.TagList); + if (isExemplarsEnabled) + { + counter.Add(doubleValue.Value, this.exemplarTagList); + } + else + { + counter.Add(doubleValue.Value, this.TagList); + } } meterProvider.ForceFlush(); @@ -196,6 +301,58 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); +#if EXPOSE_EXPERIMENTAL_FEATURES + if (isExemplarsEnabled) + { + Assert.Single(dataPoint.Exemplars); + + var exemplar = dataPoint.Exemplars[0]; + + metricPoint.TryGetExemplars(out var exemplars); + + var exemplarsEnumerator = exemplars.GetEnumerator(); + + exemplarsEnumerator.MoveNext(); + + var actualExemplar = exemplarsEnumerator.Current; + + Assert.Equal((ulong)actualExemplar.Timestamp.ToUnixTimeNanoseconds(), exemplar.TimeUnixNano); + + if (longValue != null) + { + Assert.Equal(longValue.Value, exemplar.AsInt); + } + else + { + Assert.Equal(doubleValue.Value, exemplar.AsDouble); + } + + if (isTracingEnabled) + { + var spanIdBytes = new byte[8]; + activity.SpanId.CopyTo(spanIdBytes); + + Assert.True(spanIdBytes.SequenceEqual(exemplar.SpanId)); + + var traceIdBytes = new byte[16]; + activity.TraceId.CopyTo(traceIdBytes); + + Assert.True(traceIdBytes.SequenceEqual(exemplar.TraceId)); + } + else + { + Assert.Equal(ByteString.Empty, exemplar.SpanId); + Assert.Equal(ByteString.Empty, exemplar.TraceId); + } + + AssertOtlpAttributes([new KeyValuePair("zfilteredKey1", "zfilteredValue1")], exemplar.FilteredAttributes); + } + else + { + Assert.Empty(dataPoint.Exemplars); + } +#endif + if (addPrepopulatedDimensions) { AssertOtlpAttributes(this.TagList.Concat(prepopulatedMetricDimensions), dataPoint.Attributes); @@ -566,16 +723,48 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName } [Theory] - [InlineData(123.45, true, true)] - [InlineData(123.45, true, false)] - [InlineData(123.45, false, true)] - [InlineData(123.45, false, false)] - [InlineData(-123.45, true, true)] - [InlineData(-123.45, true, false)] - [InlineData(-123.45, false, true)] - [InlineData(-123.45, false, false)] - public void HistogramSerializationSingleMetricPoint(double doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace) + [InlineData(123.45, true, true, true, true)] + [InlineData(123.45, true, true, true, false)] + [InlineData(123.45, true, true, false, true)] + [InlineData(123.45, true, true, false, false)] + [InlineData(123.45, true, false, true, true)] + [InlineData(123.45, true, false, true, false)] + [InlineData(123.45, true, false, false, true)] + [InlineData(123.45, true, false, false, false)] + [InlineData(123.45, false, true, true, true)] + [InlineData(123.45, false, true, true, false)] + [InlineData(123.45, false, true, false, true)] + [InlineData(123.45, false, true, false, false)] + [InlineData(123.45, false, false, true, true)] + [InlineData(123.45, false, false, true, false)] + [InlineData(123.45, false, false, false, true)] + [InlineData(123.45, false, false, false, false)] + [InlineData(-123.45, true, true, true, true)] + [InlineData(-123.45, true, true, true, false)] + [InlineData(-123.45, true, true, false, true)] + [InlineData(-123.45, true, true, false, false)] + [InlineData(-123.45, true, false, true, true)] + [InlineData(-123.45, true, false, true, false)] + [InlineData(-123.45, true, false, false, true)] + [InlineData(-123.45, true, false, false, false)] + [InlineData(-123.45, false, true, true, true)] + [InlineData(-123.45, false, true, true, false)] + [InlineData(-123.45, false, true, false, true)] + [InlineData(-123.45, false, true, false, false)] + [InlineData(-123.45, false, false, true, true)] + [InlineData(-123.45, false, false, true, false)] + [InlineData(-123.45, false, false, false, true)] + [InlineData(-123.45, false, false, false, false)] + public void HistogramSerializationSingleMetricPoint(double doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace, bool isExemplarsEnabled, bool isTracingEnabled) { + Activity activity = null; + + if (isTracingEnabled) + { + activity = new Activity("Custom Activity"); + activity.Start(); + } + using var meter = new Meter(nameof(this.HistogramSerializationSingleMetricPoint), "0.0.1"); var exportedItems = new List(); @@ -601,14 +790,29 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add var resourceBuilder = ResourceBuilder.CreateDefault().Clear() .AddAttributes(resourceAttributes); - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .SetResourceBuilder(resourceBuilder) - .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) - .AddReader(inMemoryReader) - .Build(); + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(resourceBuilder) + .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) + .AddReader(inMemoryReader); + if (isExemplarsEnabled) + { +#if EXPOSE_EXPERIMENTAL_FEATURES + meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); + meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = TagKeys }); +#endif + } + + var meterProvider = meterProviderBuilder.Build(); var histogram = meter.CreateHistogram("TestHistogram"); - histogram.Record(doubleValue, this.TagList); + if (isExemplarsEnabled) + { + histogram.Record(doubleValue, this.exemplarTagList); + } + else + { + histogram.Record(doubleValue, this.TagList); + } meterProvider.ForceFlush(); @@ -697,6 +901,51 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add { AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } + +#if EXPOSE_EXPERIMENTAL_FEATURES + if (isExemplarsEnabled) + { + Assert.Single(dataPoint.Exemplars); + + var exemplar = dataPoint.Exemplars[0]; + + metricPoint.TryGetExemplars(out var exemplars); + + var exemplarsEnumerator = exemplars.GetEnumerator(); + + exemplarsEnumerator.MoveNext(); + + var actualExemplar = exemplarsEnumerator.Current; + + Assert.Equal((ulong)actualExemplar.Timestamp.ToUnixTimeNanoseconds(), exemplar.TimeUnixNano); + + Assert.Equal(doubleValue, exemplar.AsDouble); + + if (isTracingEnabled) + { + var spanIdBytes = new byte[8]; + activity.SpanId.CopyTo(spanIdBytes); + + Assert.True(spanIdBytes.SequenceEqual(exemplar.SpanId)); + + var traceIdBytes = new byte[16]; + activity.TraceId.CopyTo(traceIdBytes); + + Assert.True(traceIdBytes.SequenceEqual(exemplar.TraceId)); + } + else + { + Assert.Equal(ByteString.Empty, exemplar.SpanId); + Assert.Equal(ByteString.Empty, exemplar.TraceId); + } + + AssertOtlpAttributes([new KeyValuePair("zfilteredKey1", "zfilteredValue1")], exemplar.FilteredAttributes); + } + else + { + Assert.Empty(dataPoint.Exemplars); + } +#endif } [Theory] From 4c6474259ccb08a41eb45ea6424243d4d2c707db Mon Sep 17 00:00:00 2001 From: Mike Goldsmith Date: Wed, 8 May 2024 15:07:06 +0100 Subject: [PATCH 1048/1499] Release v1.0.0-beta.5 of OpenTelemetry.Extensions package (#1708) --- src/OpenTelemetry.Extensions/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 4c4d011360..c71f4d8029 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.5 + +Released 2024-May-08 + * Add LogToActivityEventConversionOptions.Filter callback ([#1059](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1059)) From 4fe7355f8f27d3c557cd8885c6f13b2c580c0d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 9 May 2024 01:27:11 +0200 Subject: [PATCH 1049/1499] [Instrumentation.AspNetCore] Move package from main repository (#1707) --- .../comp_instrumentation_aspnetcore.md | 41 + .github/codecov.yml | 5 + .github/workflows/ci.yml | 21 +- .../package-Instrumentation.AspNetCore.yml | 21 + ...nTelemetry.Instrumentation.AspNetCore.proj | 35 + opentelemetry-dotnet-contrib.sln | 30 + .../.publicApi/PublicAPI.Shipped.txt | 18 + .../.publicApi/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../AspNetCoreInstrumentation.cs | 38 + ...mentationMeterProviderBuilderExtensions.cs | 54 + ...entationTracerProviderBuilderExtensions.cs | 125 ++ .../AspNetCoreMetrics.cs | 41 + .../AspNetCoreTraceInstrumentationOptions.cs | 115 ++ .../AssemblyInfo.cs | 10 + .../CHANGELOG.md | 644 +++++++++ .../AspNetCoreInstrumentationEventSource.cs | 94 ++ .../Implementation/HttpInListener.cs | 399 ++++++ .../Implementation/HttpInMetricsListener.cs | 128 ++ .../Implementation/TelemetryHelper.cs | 33 + ...elemetry.Instrumentation.AspNetCore.csproj | 52 + .../README.md | 331 +++++ src/Shared/ActivityHelperExtensions.cs | 43 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + .../AspNetCoreInstrumentationBenchmarks.cs | 186 +++ .../AspNetCoreInstrumentationNewBenchmarks.cs | 207 +++ ...nstrumentation.AspNetCore.Benchmark.csproj | 21 + .../Program.cs | 11 + .../README.md | 11 + .../BasicTests.cs | 1272 +++++++++++++++++ .../DependencyInjectionConfigTests.cs | 54 + .../EventSourceTest.cs | 17 + ...stsCollectionsIsAccordingToTheSpecTests.cs | 172 +++ .../MetricTests.cs | 418 ++++++ ...ry.Instrumentation.AspNetCore.Tests.csproj | 48 + .../RouteTests/README.md | 204 +++ .../RouteTests/README.net6.0.md | 612 ++++++++ .../RouteTests/README.net7.0.md | 654 +++++++++ .../RouteTests/README.net8.0.md | 654 +++++++++ .../RouteTests/RoutingTestCases.cs | 45 + .../RouteTests/RoutingTestCases.json | 211 +++ .../RouteTests/RoutingTestFixture.cs | 115 ++ .../RouteTests/RoutingTestResult.cs | 33 + .../RouteTests/RoutingTests.cs | 140 ++ .../TestApplication/ActionDescriptorInfo.cs | 52 + .../Controllers/AnotherAreaController.cs | 14 + .../ControllerForMyAreaController.cs | 16 + .../ControllerActionDescriptorInfo.cs | 26 + .../Controllers/AttributeRouteController.cs | 23 + .../ConventionalRouteController.cs | 17 + .../PageActionDescriptorInfo.cs | 26 + .../TestApplication/Pages/Index.cshtml | 2 + .../Pages/PageThatThrowsException.cshtml | 4 + .../RouteTests/TestApplication/RouteInfo.cs | 60 + .../RouteInfoDiagnosticObserver.cs | 110 ++ .../TestApplication/TestApplicationFactory.cs | 199 +++ .../TestApplication/wwwroot/js/site.js | 4 + .../RouteTests/TestCase.cs | 32 + .../README.md | 2 +- test/TestApp.AspNetCore/ActivityMiddleware.cs | 31 + test/TestApp.AspNetCore/CallbackMiddleware.cs | 24 + .../Controllers/ChildActivityController.cs | 47 + .../Controllers/ErrorController.cs | 17 + .../Controllers/ValuesController.cs | 42 + .../Filters/ExceptionFilter1.cs | 14 + .../Filters/ExceptionFilter2.cs | 14 + test/TestApp.AspNetCore/Program.cs | 54 + .../Properties/launchSettings.json | 12 + .../TestActivityMiddleware.cs | 17 + .../TestApp.AspNetCore.csproj | 13 + .../TestCallbackMiddleware.cs | 12 + test/TestApp.AspNetCore/TestMiddleware.cs | 24 + .../appsettings.Development.json | 8 + test/TestApp.AspNetCore/appsettings.json | 9 + 75 files changed, 8284 insertions(+), 5 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md create mode 100644 .github/workflows/package-Instrumentation.AspNetCore.yml create mode 100644 build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/README.md create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EventSourceTest.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net6.0.md create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net8.0.md create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.json create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/AnotherArea/Controllers/AnotherAreaController.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/MyArea/Controllers/ControllerForMyAreaController.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/Index.cshtml create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/PageThatThrowsException.cshtml create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/wwwroot/js/site.js create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs create mode 100644 test/TestApp.AspNetCore/ActivityMiddleware.cs create mode 100644 test/TestApp.AspNetCore/CallbackMiddleware.cs create mode 100644 test/TestApp.AspNetCore/Controllers/ChildActivityController.cs create mode 100644 test/TestApp.AspNetCore/Controllers/ErrorController.cs create mode 100644 test/TestApp.AspNetCore/Controllers/ValuesController.cs create mode 100644 test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs create mode 100644 test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs create mode 100644 test/TestApp.AspNetCore/Program.cs create mode 100644 test/TestApp.AspNetCore/Properties/launchSettings.json create mode 100644 test/TestApp.AspNetCore/TestActivityMiddleware.cs create mode 100644 test/TestApp.AspNetCore/TestApp.AspNetCore.csproj create mode 100644 test/TestApp.AspNetCore/TestCallbackMiddleware.cs create mode 100644 test/TestApp.AspNetCore/TestMiddleware.cs create mode 100644 test/TestApp.AspNetCore/appsettings.Development.json create mode 100644 test/TestApp.AspNetCore/appsettings.json diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md new file mode 100644 index 0000000000..bd5d9c2550 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md @@ -0,0 +1,41 @@ +--- +name: OpenTelemetry.Instrumentation.AspNetCore +about: Issue with OpenTelemetry.Instrumentation.AspNetCore +labels: comp:instrumentation.aspnetcore +--- + +# Issue with OpenTelemetry.Instrumentation.AspNetCore + +List of [all OpenTelemetry NuGet +packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are +using (e.g. `OpenTelemetry 1.3.2`): + +* TBD + +Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can +find this information from the `*.csproj` file): + +* TBD + +**Is this a feature request or a bug?** + +* [ ] Feature Request +* [ ] Bug + +**What is the expected behavior?** + +What do you expect to see? + +**What is the actual behavior?** + +What did you see instead? If you are reporting a bug, create a self-contained +project using the template of your choice and apply the minimum required code to +result in the issue you're observing. We will close this issue if: + +* The repro project you share with us is complex. We can't investigate custom + projects, so don't point us to such, please. +* If we can not reproduce the behavior you're reporting. + +## Additional Context + +Add any other context about the feature request here. diff --git a/.github/codecov.yml b/.github/codecov.yml index 3198fe49bb..93c6e5eb08 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -58,6 +58,11 @@ flags: - src/OpenTelemetry.Instrumentation.AspNet - src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + unittests-Instrumentation.AspNetCore: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.AspNetCore + unittests-Instrumentation.EventCounters: carryforward: true paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e01fa622b..a6e0614a40 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,8 @@ jobs: code: ['**.cs', '**.csproj', '.editorconfig'] aot: ['src/OpenTelemetry.Extensions.Enrichment/**'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] - aspnet: ['*/OpenTelemetry.Instrumentation.AspNet*/**', 'examples/AspNet/**', '!**/*.md'] + aspnet: ['*/OpenTelemetry.Instrumentation.AspNet.*/**', 'examples/AspNet/**', '!**/*.md'] + aspnetcore: ['*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!**/*.md'] aws: ['*/OpenTelemetry.*.AWS*/**', '!**/*.md'] azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] @@ -49,7 +50,8 @@ jobs: 'test/**', 'examples/**', '!test/OpenTelemetry.AotCompatibility.TestApp/**', - '!*/OpenTelemetry.Instrumentation.AspNet*/**', + '!*/OpenTelemetry.Instrumentation.AspNet.*/**', + '!*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', '!*/OpenTelemetry.ResourceDetectors.Host*/**', @@ -108,6 +110,18 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' + build-test-aspnetcore: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'aspnetcore') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Instrumentation.AspNetCore + code-cov-name: Instrumentation.AspNetCore + tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' + build-test-azure: needs: detect-changes if: | @@ -351,6 +365,7 @@ jobs: OpenTelemetry.Extensions.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.Tests.csproj, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, + OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj, OpenTelemetry.Instrumentation.EventCounters.Tests.csproj, OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj, OpenTelemetry.Instrumentation.Http.Tests.csproj, @@ -407,6 +422,7 @@ jobs: if: | contains(needs.detect-changes.outputs.changes, 'eventcounters') || contains(needs.detect-changes.outputs.changes, 'runtime') + || contains(needs.detect-changes.outputs.changes, 'aspnetcore') || contains(needs.detect-changes.outputs.changes, 'aws') || contains(needs.detect-changes.outputs.changes, 'azure') || contains(needs.detect-changes.outputs.changes, 'extensions') @@ -433,6 +449,7 @@ jobs: lint-md, lint-dotnet-format, build-test-aspnet, + build-test-aspnetcore, build-test-azure, build-test-eventcounters, build-test-extensions, diff --git a/.github/workflows/package-Instrumentation.AspNetCore.yml b/.github/workflows/package-Instrumentation.AspNetCore.yml new file mode 100644 index 0000000000..9861c3a06d --- /dev/null +++ b/.github/workflows/package-Instrumentation.AspNetCore.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.Instrumentation.AspNetCore + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Instrumentation.AspNetCore-*' # trigger when we create a tag with prefix "Instrumentation.AspNetCore-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Instrumentation.AspNetCore + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj new file mode 100644 index 0000000000..0e86e80ccf --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj @@ -0,0 +1,35 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 1830e85346..0809cbac97 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -45,6 +45,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Extensions.Enrichment.yml = .github\workflows\package-Extensions.Enrichment.yml .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml + .github\workflows\package-Instrumentation.AspNetCore.yml = .github\workflows\package-Instrumentation.AspNetCore.yml .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml .github\workflows\package-Instrumentation.Cassandra.yml = .github\workflows\package-Instrumentation.Cassandra.yml @@ -322,6 +323,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj + build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj = build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj build\Projects\OpenTelemetry.Instrumentation.GrpcNetClient.proj = build\Projects\OpenTelemetry.Instrumentation.GrpcNetClient.proj build\Projects\OpenTelemetry.Instrumentation.Http.proj = build\Projects\OpenTelemetry.Instrumentation.Http.proj @@ -369,6 +371,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcNetClient.Tests", "test\OpenTelemetry.Instrumentation.GrpcNetClient.Tests\OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj", "{2E1A5759-1431-4724-8885-3E9447FBF617}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore", "src\OpenTelemetry.Instrumentation.AspNetCore\OpenTelemetry.Instrumentation.AspNetCore.csproj", "{A8FF0DEB-F371-42FC-8A53-A8C25FE408FC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore.Tests", "test\OpenTelemetry.Instrumentation.AspNetCore.Tests\OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj", "{917AEC46-816C-4E05-913E-F0F44C24C437}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore", "test\TestApp.AspNetCore\TestApp.AspNetCore.csproj", "{1E743561-B1D4-4100-B6AD-1FD25FA8659B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore.Benchmark", "test\OpenTelemetry.Instrumentation.AspNetCore.Benchmark\OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj", "{92CD1B60-74B8-4E6E-9E7F-83AC3C792980}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -747,6 +757,22 @@ Global {2E1A5759-1431-4724-8885-3E9447FBF617}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E1A5759-1431-4724-8885-3E9447FBF617}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E1A5759-1431-4724-8885-3E9447FBF617}.Release|Any CPU.Build.0 = Release|Any CPU + {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC}.Release|Any CPU.Build.0 = Release|Any CPU + {917AEC46-816C-4E05-913E-F0F44C24C437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {917AEC46-816C-4E05-913E-F0F44C24C437}.Debug|Any CPU.Build.0 = Debug|Any CPU + {917AEC46-816C-4E05-913E-F0F44C24C437}.Release|Any CPU.ActiveCfg = Release|Any CPU + {917AEC46-816C-4E05-913E-F0F44C24C437}.Release|Any CPU.Build.0 = Release|Any CPU + {1E743561-B1D4-4100-B6AD-1FD25FA8659B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E743561-B1D4-4100-B6AD-1FD25FA8659B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E743561-B1D4-4100-B6AD-1FD25FA8659B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E743561-B1D4-4100-B6AD-1FD25FA8659B}.Release|Any CPU.Build.0 = Release|Any CPU + {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -858,6 +884,10 @@ Global {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {0156E342-CE63-46F5-992D-691A7CCB50F8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2E1A5759-1431-4724-8885-3E9447FBF617} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {917AEC46-816C-4E05-913E-F0F44C24C437} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {1E743561-B1D4-4100-B6AD-1FD25FA8659B} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {92CD1B60-74B8-4E6E-9E7F-83AC3C792980} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..fc47928891 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1,18 @@ +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.AspNetCoreTraceInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpRequest.get -> System.Action +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpRequest.set -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpResponse.get -> System.Action +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpResponse.set -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.Filter.set -> void +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.RecordException.set -> void +OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions +OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions +static OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs new file mode 100644 index 0000000000..d309679262 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs @@ -0,0 +1,38 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +namespace OpenTelemetry.Instrumentation.AspNetCore; + +/// +/// Asp.Net Core Requests instrumentation. +/// +internal sealed class AspNetCoreInstrumentation : IDisposable +{ + private static readonly HashSet DiagnosticSourceEvents = new() + { + "Microsoft.AspNetCore.Hosting.HttpRequestIn", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", + "Microsoft.AspNetCore.Diagnostics.UnhandledException", + "Microsoft.AspNetCore.Hosting.UnhandledException", + }; + + private readonly Func isEnabled = (eventName, _, _) + => DiagnosticSourceEvents.Contains(eventName); + + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + public AspNetCoreInstrumentation(HttpInListener httpInListener) + { + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(httpInListener, this.isEnabled, AspNetCoreInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..a9d7ef7c8a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NET8_0_OR_GREATER +using OpenTelemetry.Instrumentation.AspNetCore; +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; +#endif +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of ASP.NET Core request instrumentation. +/// +public static class AspNetCoreInstrumentationMeterProviderBuilderExtensions +{ + /// + /// Enables the incoming requests automatic data collection for ASP.NET Core. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddAspNetCoreInstrumentation( + this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + +#if NET8_0_OR_GREATER + return builder.ConfigureMeters(); +#else + // Note: Warm-up the status code and method mapping. + _ = TelemetryHelper.BoxedStatusCodes; + _ = TelemetryHelper.RequestDataHelper; + + builder.AddMeter(HttpInMetricsListener.InstrumentationName); + +#pragma warning disable CA2000 + builder.AddInstrumentation(new AspNetCoreMetrics()); +#pragma warning restore CA2000 + + return builder; +#endif + } + + internal static MeterProviderBuilder ConfigureMeters(this MeterProviderBuilder builder) + { + return builder + .AddMeter("Microsoft.AspNetCore.Hosting") + .AddMeter("Microsoft.AspNetCore.Server.Kestrel") + .AddMeter("Microsoft.AspNetCore.Http.Connections") + .AddMeter("Microsoft.AspNetCore.Routing") + .AddMeter("Microsoft.AspNetCore.Diagnostics") + .AddMeter("Microsoft.AspNetCore.RateLimiting"); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..00fa0d9435 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs @@ -0,0 +1,125 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.AspNetCore; +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of ASP.NET Core request instrumentation. +/// +public static class AspNetCoreInstrumentationTracerProviderBuilderExtensions +{ + /// + /// Enables the incoming requests automatic data collection for ASP.NET Core. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetCoreInstrumentation(this TracerProviderBuilder builder) + => AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreTraceInstrumentationOptions: null); + + /// + /// Enables the incoming requests automatic data collection for ASP.NET Core. + /// + /// being configured. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetCoreInstrumentation( + this TracerProviderBuilder builder, + Action configureAspNetCoreTraceInstrumentationOptions) + => AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreTraceInstrumentationOptions); + + /// + /// Enables the incoming requests automatic data collection for ASP.NET Core. + /// + /// being configured. + /// Name which is used when retrieving options. + /// Callback action for configuring . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddAspNetCoreInstrumentation( + this TracerProviderBuilder builder, + string name, + Action configureAspNetCoreTraceInstrumentationOptions) + { + Guard.ThrowIfNull(builder); + + // Note: Warm-up the status code and method mapping. + _ = TelemetryHelper.BoxedStatusCodes; + _ = TelemetryHelper.RequestDataHelper; + + name ??= Options.DefaultName; + + builder.ConfigureServices(services => + { + if (configureAspNetCoreTraceInstrumentationOptions != null) + { + services.Configure(name, configureAspNetCoreTraceInstrumentationOptions); + } + + services.RegisterOptionsFactory(configuration => new AspNetCoreTraceInstrumentationOptions(configuration)); + }); + + if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder) + { + deferredTracerProviderBuilder.Configure((sp, builder) => + { + AddAspNetCoreInstrumentationSources(builder, sp); + }); + } + + return builder.AddInstrumentation(sp => + { + var options = sp.GetRequiredService>().Get(name); + + return new AspNetCoreInstrumentation( + new HttpInListener(options)); + }); + } + + // Note: This is used by unit tests. + internal static TracerProviderBuilder AddAspNetCoreInstrumentation( + this TracerProviderBuilder builder, + HttpInListener listener) + { + builder.AddAspNetCoreInstrumentationSources(); + +#pragma warning disable CA2000 + return builder.AddInstrumentation( + new AspNetCoreInstrumentation(listener)); +#pragma warning restore CA2000 + } + + private static void AddAspNetCoreInstrumentationSources( + this TracerProviderBuilder builder, + IServiceProvider serviceProvider = null) + { + // For .NET7.0 onwards activity will be created using activitySource. + // https://github.com/dotnet/aspnetcore/blob/bf3352f2422bf16fa3ca49021f0e31961ce525eb/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L327 + // For .NET6.0 and below, we will continue to use legacy way. + if (HttpInListener.Net7OrGreater) + { + // TODO: Check with .NET team to see if this can be prevented + // as this allows user to override the ActivitySource. + var activitySourceService = serviceProvider?.GetService(); + if (activitySourceService != null) + { + builder.AddSource(activitySourceService.Name); + } + else + { + // For users not using hosting package? + builder.AddSource(HttpInListener.AspNetCoreActivitySourceName); + } + } + else + { + builder.AddSource(HttpInListener.ActivitySourceName); + builder.AddLegacySource(HttpInListener.ActivityOperationName); // for the activities created by AspNetCore + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs new file mode 100644 index 0000000000..a819d561a9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NET8_0_OR_GREATER +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +namespace OpenTelemetry.Instrumentation.AspNetCore; + +/// +/// Asp.Net Core Requests instrumentation. +/// +internal sealed class AspNetCoreMetrics : IDisposable +{ + private static readonly HashSet DiagnosticSourceEvents = new() + { + "Microsoft.AspNetCore.Hosting.HttpRequestIn", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", + "Microsoft.AspNetCore.Diagnostics.UnhandledException", + "Microsoft.AspNetCore.Hosting.UnhandledException", + }; + + private readonly Func isEnabled = (eventName, _, _) + => DiagnosticSourceEvents.Contains(eventName); + + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + internal AspNetCoreMetrics() + { + var metricsListener = new HttpInMetricsListener("Microsoft.AspNetCore"); + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(metricsListener, this.isEnabled, AspNetCoreInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs new file mode 100644 index 0000000000..f5ffb7962f --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs @@ -0,0 +1,115 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +namespace OpenTelemetry.Instrumentation.AspNetCore; + +/// +/// Options for requests instrumentation. +/// +public class AspNetCoreTraceInstrumentationOptions +{ + /// + /// Initializes a new instance of the class. + /// + public AspNetCoreTraceInstrumentationOptions() + : this(new ConfigurationBuilder().AddEnvironmentVariables().Build()) + { + } + + internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration) + { + Debug.Assert(configuration != null, "configuration was null"); + + if (configuration.TryGetBoolValue( + AspNetCoreInstrumentationEventSource.Log, + "OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION", + out var enableGrpcInstrumentation)) + { + this.EnableGrpcAspNetCoreSupport = enableGrpcInstrumentation; + } + + if (configuration.TryGetBoolValue( + AspNetCoreInstrumentationEventSource.Log, + "OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION", + out var disableUrlQueryRedaction)) + { + this.DisableUrlQueryRedaction = disableUrlQueryRedaction; + } + } + + /// + /// Gets or sets a filter function that determines whether or not to + /// collect telemetry on a per request basis. + /// + /// + /// Notes: + /// + /// The return value for the filter function is interpreted as: + /// + /// If filter returns , the request is + /// collected. + /// If filter returns or throws an + /// exception the request is NOT collected. + /// + /// + /// + public Func Filter { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the HttpRequest object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithHttpRequest { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the HttpResponse object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithHttpResponse { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the Exception object from which additional information can be extracted to enrich the activity. + /// + public Action EnrichWithException { get; set; } + + /// + /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. + /// + /// + /// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md. + /// + public bool RecordException { get; set; } + + /// + /// Gets or sets a value indicating whether RPC attributes are added to an Activity when using Grpc.AspNetCore. + /// + /// + /// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md. + /// + internal bool EnableGrpcAspNetCoreSupport { get; set; } + + /// + /// Gets or sets a value indicating whether the url query value should be redacted or not. + /// + /// + /// The query parameter values are redacted with value set as Redacted. + /// e.g. `?key1=value1` is set as `?key1=Redacted`. + /// The redaction can be disabled by setting this property to . + /// + internal bool DisableUrlQueryRedaction { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AssemblyInfo.cs new file mode 100644 index 0000000000..2cd1a339fd --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNetCore.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.AspNetCore.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md new file mode 100644 index 0000000000..2b31a759e3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -0,0 +1,644 @@ +# Changelog + +## Unreleased + +* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. + * Update `OpenTelemetry.Api` to `1.8.1`. + ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +## 1.8.1 + +Released 2024-Apr-12 + +* **Breaking Change**: Fixed tracing instrumentation so that by default any + values detected in the query string component of requests are replaced with + the text `Redacted` when building the `url.query` tag. For example, + `?key1=value1&key2=value2` becomes `?key1=Redacted&key2=Redacted`. You can + disable this redaction by setting the environment variable + `OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION` to `true`. + ([#5532](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5532)) + +## 1.8.0 + +Released 2024-Apr-04 + +* Fixed an issue for spans when `server.port` attribute was not set with + `server.address` when it has default values (`80` for `HTTP` and + `443` for `HTTPS` protocol). + ([#5419](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5419)) + +* Fixed an issue where the `http.request.method_original` attribute was not set + on activity. Now, when `http.request.method` is set and the original method + is converted to its canonical form (e.g., `Get` is converted to `GET`), + the original value `Get` will be stored in `http.request.method_original`. + ([#5471](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5471)) + +* Fixed the name of spans that have `http.request.method` attribute set to `_OTHER`. + The span name will be set as `HTTP {http.route}` as per the [specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#name). + ([#5484](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5484)) + +## 1.7.1 + +Released 2024-Feb-09 + +* Fixed issue + [#4466](https://github.com/open-telemetry/opentelemetry-dotnet/issues/4466) + where the activity instance returned by `Activity.Current` was different than + instance obtained from `IHttpActivityFeature.Activity`. + ([#5136](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5136)) + +* Fixed an issue where the `http.route` attribute was not set on either the + `Activity` or `http.server.request.duration` metric generated from a + request when an exception handling middleware is invoked. One caveat is that + this fix does not address the problem for the `http.server.request.duration` + metric when running ASP.NET Core 8. ASP.NET Core 8 contains an equivalent fix + which should ship in version 8.0.2 + (see: [dotnet/aspnetcore#52652](https://github.com/dotnet/aspnetcore/pull/52652)). + ([#5135](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5135)) + +* Fixes scenario when the `net6.0` target of this library is loaded into a + .NET 7+ process and the instrumentation does not behave as expected. This + is an unusual scenario that does not affect users consuming this package + normally. This fix is primarily to support the + [opentelemetry-dotnet-instrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5252) + project. + ([#5252](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5252)) + +## 1.7.0 + +Released 2023-Dec-13 + +## 1.6.0 - First stable release of this library + +Released 2023-Dec-13 + +* Re-introduced support for gRPC instrumentation as an opt-in experimental + feature. From now onwards, gRPC can be enabled by setting + `OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION` flag to + `True`. `OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION` can + be set as an environment variable or via IConfiguration. The change is + introduced in order to support stable release of `http` instrumentation. + Semantic conventions for RPC is still + [experimental](https://github.com/open-telemetry/semantic-conventions/tree/main/docs/rpc) + and hence the package will only support it as an opt-in experimental feature. + Note that the support was removed in `1.6.0-rc.1` version of the package and + versions released before `1.6.0-rc.1` had gRPC instrumentation enabled by + default. + ([#5130](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5130)) + +## 1.6.0-rc.1 + +Released 2023-Dec-01 + +* Removed support for `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. The + library will now emit only the + [stable](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http) + semantic conventions. + ([#5066](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5066)) + +* Removed `netstandard2.1` target. + ([#5094](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5094)) + +* Removed support for grpc instrumentation to unblock stable release of http + instrumentation. For details, see issue + [#5098](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5098) + ([#5097](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5097)) + +* **Breaking Change** : Renamed `AspNetCoreInstrumentationOptions` to + `AspNetCoreTraceInstrumentationOptions`. + ([#5108](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5108)) + +## 1.6.0-beta.3 + +Released 2023-Nov-17 + +* Removed the Activity Status Description that was being set during + exceptions. Activity Status will continue to be reported as `Error`. + This is a **breaking change**. `EnrichWithException` can be leveraged + to restore this behavior. + ([#5025](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5025)) + +* Updated `http.request.method` to match specification guidelines. + * For activity, if the method does not belong to one of the [known + values](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-spans.md#:~:text=http.request.method%20has%20the%20following%20list%20of%20well%2Dknown%20values) + then the request method will be set on an additional tag + `http.request.method.original` and `http.request.method` will be set to + `_OTHER`. + * For metrics, if the original method does not belong to one of the [known + values](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-spans.md#:~:text=http.request.method%20has%20the%20following%20list%20of%20well%2Dknown%20values) + then `http.request.method` on `http.server.request.duration` metric will be + set to `_OTHER` + + `http.request.method` is set on `http.server.request.duration` metric or + activity when `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable is set to + `http` or `http/dup`. + ([#5001](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5001)) + +* An additional attribute `error.type` will be added to activity and +`http.server.request.duration` metric when the request results in unhandled +exception. The attribute value will be set to full name of exception type. + + The attribute will only be added when `OTEL_SEMCONV_STABILITY_OPT_IN` + environment variable is set to `http` or `http/dup`. + ([#4986](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4986)) + +* Fixed `network.protocol.version` attribute values to match the specification. + ([#5007](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5007)) + +* Calls to `/metrics` will now be included in the `http.server.request.duration` + metric. This change may affect Prometheus pull scenario if the Prometheus + server sends request to the scraping endpoint that contains `/metrics` in + path. + ([#5044](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5044)) + +* Fixes the `http.route` attribute for scenarios in which it was + previously missing or incorrect. Additionally, the `http.route` attribute + is now the same for both the metric and `Activity` emitted for a request. + Lastly, the `Activity.DisplayName` has been adjusted to have the format + `{http.request.method} {http.route}` to conform with [the specification](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#name). + There remain scenarios when using conventional routing or Razor pages where + `http.route` is still incorrect. See [#5056](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5056) + and [#5057](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5057) + for more details. + ([#5026](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5026)) + +* Removed `network.protocol.name` from `http.server.request.duration` metric as + per spec. + ([#5049](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5049)) + +## 1.6.0-beta.2 + +Released 2023-Oct-26 + +* Introduced a new metric, `http.server.request.duration` measured in seconds. + The OTel SDK (starting with version 1.6.0) + [applies custom histogram buckets](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4820) + for this metric to comply with the + [Semantic Convention for Http Metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md). + This new metric is only available for users who opt-in to the new + semantic convention by configuring the `OTEL_SEMCONV_STABILITY_OPT_IN` + environment variable to either `http` (to emit only the new metric) or + `http/dup` (to emit both the new and old metrics). + ([#4802](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4802)) + * New metric: `http.server.request.duration` + * Unit: `s` (seconds) + * Histogram Buckets: `0, 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` + * Old metric: `http.server.duration` + * Unit: `ms` (milliseconds) + * Histogram Buckets: `0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, + 5000, 7500, 10000` + + Note: the older `http.server.duration` metric and + `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable will eventually be + removed after the HTTP semantic conventions are marked stable. + At which time this instrumentation can publish a stable release. Refer to + the specification for more information regarding the new HTTP semantic + conventions for both + [spans](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-spans.md) + and + [metrics](https://github.com/open-telemetry/semantic-conventions/blob/2bad9afad58fbd6b33cc683d1ad1f006e35e4a5d/docs/http/http-metrics.md). + +* Following metrics will now be enabled by default when targeting `.NET8.0` or + newer framework: + + * **Meter** : `Microsoft.AspNetCore.Hosting` + * `http.server.request.duration` + * `http.server.active_requests` + + * **Meter** : `Microsoft.AspNetCore.Server.Kestrel` + * `kestrel.active_connections` + * `kestrel.connection.duration` + * `kestrel.rejected_connections` + * `kestrel.queued_connections` + * `kestrel.queued_requests` + * `kestrel.upgraded_connections` + * `kestrel.tls_handshake.duration` + * `kestrel.active_tls_handshakes` + + * **Meter** : `Microsoft.AspNetCore.Http.Connections` + * `signalr.server.connection.duration` + * `signalr.server.active_connections` + + * **Meter** : `Microsoft.AspNetCore.Routing` + * `aspnetcore.routing.match_attempts` + + * **Meter** : `Microsoft.AspNetCore.Diagnostics` + * `aspnetcore.diagnostics.exceptions` + + * **Meter** : `Microsoft.AspNetCore.RateLimiting` + * `aspnetcore.rate_limiting.active_request_leases` + * `aspnetcore.rate_limiting.request_lease.duration` + * `aspnetcore.rate_limiting.queued_requests` + * `aspnetcore.rate_limiting.request.time_in_queue` + * `aspnetcore.rate_limiting.requests` + + For details about each individual metric check [ASP.NET Core + docs + page](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-aspnetcore). + + **NOTES**: + * When targeting `.NET8.0` framework or newer, `http.server.request.duration` metric + will only follow + [v1.22.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.22.0/docs/http/http-metrics.md#metric-httpclientrequestduration) + semantic conventions specification. Ability to switch behavior to older + conventions using `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable is + not available. + * Users can opt-out of metrics that are not required using + [views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#drop-an-instrument). + + ([#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934)) + +* Added `network.protocol.name` dimension to `http.server.request.duration` +metric. This change only affects users setting `OTEL_SEMCONV_STABILITY_OPT_IN` +to `http` or `http/dup`. +([#4934](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4934)) + +* **Breaking**: Removed `Enrich` and `Filter` support for **metrics** + instrumentation. With this change, `AspNetCoreMetricsInstrumentationOptions` + is no longer available. + ([#4981](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4981)) + + * `Enrich` migration: + + An enrichment API for the `http.server.request.duration` metric is available + inside AspNetCore for users targeting .NET 8.0 (or newer). For details see: + [Enrich the ASP.NET Core request + metric](https://learn.microsoft.com/aspnet/core/log-mon/metrics/metrics?view=aspnetcore-8.0#enrich-the-aspnet-core-request-metric). + + * `Filter` migration: + + There is no comparable filter mechanism currently available for any .NET + version. Please [share your + feedback](https://github.com/open-telemetry/opentelemetry-dotnet/issues/4982) + if you are impacted by this feature gap. + + > **Note** + > The [View API](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#select-specific-tags) + may be used to drop dimensions. + +* Updated description for `http.server.request.duration` metrics to match spec + definition. + ([#4990](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4990)) + +## 1.5.1-beta.1 + +Released 2023-Jul-20 + +* The new HTTP and network semantic conventions can be opted in to by setting + the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a + transition period for users to experiment with the new semantic conventions + and adapt as necessary. The environment variable supports the following + values: + * `http` - emit the new, frozen (proposed for stable) HTTP and networking + attributes, and stop emitting the old experimental HTTP and networking + attributes that the instrumentation emitted previously. + * `http/dup` - emit both the old and the frozen (proposed for stable) HTTP + and networking attributes, allowing for a more seamless transition. + * The default behavior (in the absence of one of these values) is to continue + emitting the same HTTP and network semantic conventions that were emitted in + `1.5.0-beta.1`. + * Note: this option will eventually be removed after the new HTTP and + network semantic conventions are marked stable. At which time this + instrumentation can receive a stable release, and the old HTTP and + network semantic conventions will no longer be supported. Refer to the + specification for more information regarding the new HTTP and network + semantic conventions for both + [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md) + and + [metrics](https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-metrics.md). + ([#4537](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4537), + [#4606](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4606), + [#4660](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4660)) + +* Fixed an issue affecting NET 7.0+. If custom propagation is being used + and tags are added to an Activity during sampling then that Activity would be dropped. + ([#4637](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4637)) + +## 1.5.0-beta.1 + +Released 2023-Jun-05 + +* Bumped the package version to `1.5.0-beta.1` to keep its major and minor + version in sync with that of the core packages. This would make it more + intuitive for users to figure out what version of core packages would work + with a given version of this package. The pre-release identifier has also been + changed from `rc` to `beta` as we believe this more accurately reflects the + status of this package. We believe the `rc` identifier will be more + appropriate as semantic conventions reach stability. + +* Fix issue where baggage gets cleared when the ASP.NET Core Activity + is stopped. The instrumentation no longer clears baggage. One problem + this caused was that it prevented Activity processors from accessing baggage + during their `OnEnd` call. +([#4274](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4274)) + +* Added direct reference to `System.Text.Encodings.Web` with minimum version of +`4.7.2` due to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377). +This impacts target frameworks `netstandard2.0` and `netstandard2.1` which has a +reference to `Microsoft.AspNetCore.Http.Abstractions` that depends on +`System.Text.Encodings.Web` >= 4.5.0. +([#4399](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4399)) + +* Improve perf by avoiding boxing of common status codes values. + ([#4360](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4360), + [#4363](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4363)) + +## 1.0.0-rc9.14 + +Released 2023-Feb-24 + +* Updated OTel SDK dependency to 1.4.0 + +## 1.4.0-rc9.13 + +Released 2023-Feb-10 + +## 1.0.0-rc9.12 + +Released 2023-Feb-01 + +## 1.0.0-rc9.11 + +Released 2023-Jan-09 + +## 1.0.0-rc9.10 + +Released 2022-Dec-12 + +* **Users migrating from version `1.0.0-rc9.9` will see the following breaking + changes:** + * Updated `http.status_code` dimension type from string to int for + `http.server.duration` metric. + ([#3930](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3930)) + * `http.host` will no longer be populated on `http.server.duration` metric. + `net.host.name` and `net.host.port` attributes will be populated instead. +([#3928](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3928)) + + * The `http.server.duration` metric's `http.target` attribute is replaced with +`http.route` attribute. +([#3903](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3903)) + + * `http.host` will no longer be populated on activity. `net.host.name` and + `net.host.port` attributes will be populated instead. + ([#3858](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3858)) + +* Extension method `AddAspNetCoreInstrumentation` on `MeterProviderBuilder` now + supports `AspNetCoreMetricsInstrumentationOptions`. This option class exposes + configuration properties for metric filtering and tag enrichment. + ([#3948](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3948), + [#3982](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3982)) + +## 1.0.0-rc9.9 + +Released 2022-Nov-07 + +* **Breaking change** The `Enrich` callback option has been removed. + For better usability, it has been replaced by three separate options: + `EnrichWithHttpRequest`, `EnrichWithHttpResponse` and `EnrichWithException`. + Previously, the single `Enrich` callback required the consumer to detect + which event triggered the callback to be invoked (e.g., request start, + response end, or an exception) and then cast the object received to the + appropriate type: `HttpRequest`, `HttpResponse`, or `Exception`. The separate + callbacks make it clear what event triggers them and there is no longer the + need to cast the argument to the expected type. + ([#3749](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3749)) + +* Added back `netstandard2.0` and `netstandard2.1` targets. +([#3755](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3755)) + +## 1.0.0-rc9.8 + +Released 2022-Oct-17 + +## 1.0.0-rc9.7 + +Released 2022-Sep-29 + +* Performance improvement (Reduced memory allocation) - Updated DiagnosticSource +event subscription to specific set of events. +([#3519](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3519)) + +* Added overloads which accept a name to the `TracerProviderBuilder` + `AddAspNetCoreInstrumentation` extension to allow for more fine-grained + options management + ([#3661](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3661)) + +* Fix issue where when an application has an ExceptionFilter, the exception data + wouldn't be collected. + ([#3475](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3475)) + +## 1.0.0-rc9.6 + +Released 2022-Aug-18 + +* Removed `netstandard2.0` and `netstandard2.1` targets. .NET 5 reached EOL + in May 2022 and .NET Core 3.1 reaches EOL in December 2022. End of support + dates for .NET are published + [here](https://dotnet.microsoft.com/download/dotnet). The + instrumentation for ASP.NET Core now requires .NET 6 or later. + ([#3567](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3567)) + +* Fixed an issue where activity started within middleware was modified by + instrumentation library. + ([#3498](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3498)) + +* Updated to use Activity native support from + `System.Diagnostics.DiagnosticSource` to set activity status. + ([#3118](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3118)) + ([#3555](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3555)) + +## 1.0.0-rc9.5 + +Released 2022-Aug-02 + +* Fix Remote IP Address - NULL reference exception. + ([#3481](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3481)) +* Metrics instrumentation to correctly populate `http.flavor` tag. + (1.1 instead of HTTP/1.1 etc.) + ([#3379](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3379)) +* Tracing instrumentation to populate `http.flavor` tag. + ([#3372](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3372)) +* Tracing instrumentation to populate `http.scheme` tag. + ([#3392](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3392)) + +## 1.0.0-rc9.4 + +Released 2022-Jun-03 + +* Added additional metric dimensions. + ([#3247](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3247)) +* Removes net5.0 target as .NET 5.0 is going out + of support. The package keeps netstandard2.1 target, so it + can still be used with .NET5.0 apps. + ([#3147](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3147)) + +## 1.0.0-rc9.3 + +Released 2022-Apr-15 + +## 1.0.0-rc9.2 + +Released 2022-Apr-12 + +## 1.0.0-rc9.1 + +Released 2022-Mar-30 + +* Fix: Http server span status is now unset for `400`-`499`. + ([#2904](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2904)) +* Fix: drop direct reference of the `Microsoft.AspNetCore.Http.Features` from + net5 & net6 targets (already part of the FrameworkReference since the net5). + ([#2860](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2860)) +* Reduce allocations calculating the http.url tag. + ([#2947](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2947)) + +## 1.0.0-rc10 (broken. use 1.0.0-rc9.1 and newer) + +Released 2022-Mar-04 + +## 1.0.0-rc9 + +Released 2022-Feb-02 + +## 1.0.0-rc8 + +Released 2021-Oct-08 + +* Replaced `http.path` tag on activity with `http.target`. + ([#2266](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2266)) + +## 1.0.0-rc7 + +Released 2021-Jul-12 + +## 1.0.0-rc6 + +Released 2021-Jun-25 + +## 1.0.0-rc5 + +Released 2021-Jun-09 + +* Fixes bug + [#1740](https://github.com/open-telemetry/opentelemetry-dotnet/issues/1740): + Instrumentation.AspNetCore for gRPC services omits ALL rpc.* attributes under + certain conditions + ([#1879](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1879)) + +## 1.0.0-rc4 + +Released 2021-Apr-23 + +* When using OpenTelemetry.Extensions.Hosting you can now bind + `AspNetCoreInstrumentationOptions` from DI. + ([#1997](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1997)) + +## 1.0.0-rc3 + +Released 2021-Mar-19 + +* Leverages added AddLegacySource API from OpenTelemetry SDK to trigger Samplers + and ActivityProcessors. Samplers, ActivityProcessor.OnStart will now get the + Activity before any enrichment done by the instrumentation. + ([#1836](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1836)) +* Performance optimization by leveraging sampling decision and short circuiting + activity enrichment. `Filter` and `Enrich` are now only called if + `activity.IsAllDataRequested` is `true` + ([#1899](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1899)) + +## 1.0.0-rc2 + +Released 2021-Jan-29 + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +* AspNetCoreInstrumentation sets ActivitySource to activities created outside + ActivitySource. + ([#1515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1515/)) +* For gRPC invocations, leading forward slash is trimmed from span name in order + to conform to the specification. + ([#1551](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1551)) + +## 0.8.0-beta.1 + +Released 2020-Nov-5 + +* Record `Exception` in AspNetCore instrumentation based on `RecordException` in + `AspNetCoreInstrumentationOptions` + ([#1408](https://github.com/open-telemetry/opentelemetry-dotnet/issues/1408)) +* Added configuration option `EnableGrpcAspNetCoreSupport` to enable or disable + support for adding OpenTelemetry RPC attributes when using + [Grpc.AspNetCore](https://www.nuget.org/packages/Grpc.AspNetCore/). This + option is enabled by default. + ([#1423](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1423)) +* Renamed TextMapPropagator to TraceContextPropagator, CompositePropagator to + CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and + changed from interface to abstract class. + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) +* Propagators.DefaultTextMapPropagator will be used as the default Propagator + ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) +* Removed Propagator from Instrumentation Options. Instrumentation now always + respect the Propagator.DefaultTextMapPropagator. + ([#1448](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1448)) + +## 0.7.0-beta.1 + +Released 2020-Oct-16 + +* Instrumentation no longer store raw objects like `HttpRequest` in + Activity.CustomProperty. To enrich activity, use the Enrich action on the + instrumentation. + ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) +* Span Status is populated as per new spec + ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) + +## 0.6.0-beta.1 + +Released 2020-Sep-15 + +* For gRPC invocations, the `grpc.method` and `grpc.status_code` attributes + added by the library are removed from the span. The information from these + attributes is contained in other attributes that follow the conventions of + OpenTelemetry. + ([#1260](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1260)) + +## 0.5.0-beta.2 + +Released 2020-08-28 + +* Added Filter public API on AspNetCoreInstrumentationOptions to allow filtering + of instrumentation based on HttpContext. + +* Asp.Net Core Instrumentation automatically populates HttpRequest, HttpResponse + in Activity custom property + +* Changed the default propagation to support W3C Baggage + ([#1048](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1048)) + * The default ITextFormat is now `CompositePropagator(TraceContextFormat, + BaggageFormat)`. Baggage sent via the [W3C + Baggage](https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md) + header will now be parsed and set on incoming Http spans. +* Introduced support for Grpc.AspNetCore (#803). + * Attributes are added to gRPC invocations: `rpc.system`, `rpc.service`, + `rpc.method`. These attributes are added to an existing span generated by + the instrumentation. This is unlike the instrumentation for client-side gRPC + calls where one span is created for the gRPC call and a separate span is + created for the underlying HTTP call in the event both gRPC and HTTP + instrumentation are enabled. +* Renamed `ITextPropagator` to `IPropagator` + ([#1190](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1190)) + +## 0.4.0-beta.2 + +Released 2020-07-24 + +* First beta release + +## 0.3.0-beta + +Released 2020-07-23 + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs new file mode 100644 index 0000000000..cafd0141d9 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs @@ -0,0 +1,94 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using System.Diagnostics.Tracing; +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +/// +/// EventSource events emitted from the project. +/// +[EventSource(Name = "OpenTelemetry-Instrumentation-AspNetCore")] +internal sealed class AspNetCoreInstrumentationEventSource : EventSource, IConfigurationExtensionsLogger +{ + public static AspNetCoreInstrumentationEventSource Log = new(); + + [NonEvent] + public void RequestFilterException(string handlerName, string eventName, string operationName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.RequestFilterException(handlerName, eventName, operationName, ex.ToInvariantString()); + } + } + + [NonEvent] + public void EnrichmentException(string handlerName, string eventName, string operationName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.EnrichmentException(handlerName, eventName, operationName, ex.ToInvariantString()); + } + } + + [NonEvent] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, Exception ex) + { + if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + this.UnknownErrorProcessingEvent(handlerName, eventName, ex.ToInvariantString()); + } + } + + [Event(1, Message = "Payload is NULL, span will not be recorded. HandlerName: '{0}', EventName: '{1}', OperationName: '{2}'.", Level = EventLevel.Warning)] + public void NullPayload(string handlerName, string eventName, string operationName) + { + this.WriteEvent(1, handlerName, eventName, operationName); + } + + [Event(2, Message = "Request is filtered out. HandlerName: '{0}', EventName: '{1}', OperationName: '{2}'.", Level = EventLevel.Verbose)] + public void RequestIsFilteredOut(string handlerName, string eventName, string operationName) + { + this.WriteEvent(2, handlerName, eventName, operationName); + } + +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] +#endif + [Event(3, Message = "Filter threw exception, request will not be collected. HandlerName: '{0}', EventName: '{1}', OperationName: '{2}', Exception: {3}.", Level = EventLevel.Error)] + public void RequestFilterException(string handlerName, string eventName, string operationName, string exception) + { + this.WriteEvent(3, handlerName, eventName, operationName, exception); + } + +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] +#endif + [Event(4, Message = "Enrich threw exception. HandlerName: '{0}', EventName: '{1}', OperationName: '{2}', Exception: {3}.", Level = EventLevel.Warning)] + public void EnrichmentException(string handlerName, string eventName, string operationName, string exception) + { + this.WriteEvent(4, handlerName, eventName, operationName, exception); + } + + [Event(5, Message = "Unknown error processing event '{1}' from handler '{0}', Exception: {2}", Level = EventLevel.Error)] + public void UnknownErrorProcessingEvent(string handlerName, string eventName, string ex) + { + this.WriteEvent(5, handlerName, eventName, ex); + } + + [Event(6, Message = "Configuration key '{0}' has an invalid value: '{1}'", Level = EventLevel.Warning)] + public void InvalidConfigurationValue(string key, string value) + { + this.WriteEvent(6, key, value); + } + + void IConfigurationExtensionsLogger.LogInvalidConfigurationValue(string key, string value) + { + this.InvalidConfigurationValue(key, value); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs new file mode 100644 index 0000000000..89e8c1e278 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -0,0 +1,399 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif +using System.Reflection; +using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Http; +#if !NETSTANDARD +using Microsoft.AspNetCore.Diagnostics; +using Microsoft.AspNetCore.Routing; +#endif +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.GrpcNetClient; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +internal class HttpInListener : ListenerHandler +{ + internal const string ActivityOperationName = "Microsoft.AspNetCore.Hosting.HttpRequestIn"; + internal const string OnStartEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start"; + internal const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; + internal const string OnUnhandledHostingExceptionEvent = "Microsoft.AspNetCore.Hosting.UnhandledException"; + internal const string OnUnHandledDiagnosticsExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException"; + + // https://github.com/dotnet/aspnetcore/blob/8d6554e655b64da75b71e0e20d6db54a3ba8d2fb/src/Hosting/Hosting/src/GenericHost/GenericWebHostBuilder.cs#L85 + internal const string AspNetCoreActivitySourceName = "Microsoft.AspNetCore"; + + internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly Version Version = AssemblyName.Version; + internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); + internal static readonly bool Net7OrGreater = Environment.Version.Major >= 7; + + private const string DiagnosticSourceName = "Microsoft.AspNetCore"; + + private static readonly Func> HttpRequestHeaderValuesGetter = (request, name) => + { + if (request.Headers.TryGetValue(name, out var value)) + { + // This causes allocation as the `StringValues` struct has to be casted to an `IEnumerable` object. + return value; + } + + return Enumerable.Empty(); + }; + + private static readonly PropertyFetcher ExceptionPropertyFetcher = new("Exception"); + + private readonly AspNetCoreTraceInstrumentationOptions options; + + public HttpInListener(AspNetCoreTraceInstrumentationOptions options) + : base(DiagnosticSourceName) + { + Guard.ThrowIfNull(options); + + this.options = options; + } + + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnStartEvent: + { + this.OnStartActivity(Activity.Current, payload); + } + + break; + case OnStopEvent: + { + this.OnStopActivity(Activity.Current, payload); + } + + break; + case OnUnhandledHostingExceptionEvent: + case OnUnHandledDiagnosticsExceptionEvent: + { + this.OnException(Activity.Current, payload); + } + + break; + } + } + + public void OnStartActivity(Activity activity, object payload) + { + // The overall flow of what AspNetCore library does is as below: + // Activity.Start() + // DiagnosticSource.WriteEvent("Start", payload) + // DiagnosticSource.WriteEvent("Stop", payload) + // Activity.Stop() + + // This method is in the WriteEvent("Start", payload) path. + // By this time, samplers have already run and + // activity.IsAllDataRequested populated accordingly. + + var context = payload as HttpContext; + if (context == null) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName); + return; + } + + // Ensure context extraction irrespective of sampling decision + var request = context.Request; + var textMapPropagator = Propagators.DefaultTextMapPropagator; + if (textMapPropagator is not TraceContextPropagator) + { + var ctx = textMapPropagator.Extract(default, request, HttpRequestHeaderValuesGetter); + if (ctx.ActivityContext.IsValid() + && !((ctx.ActivityContext.TraceId == activity.TraceId) + && (ctx.ActivityContext.SpanId == activity.ParentSpanId) + && (ctx.ActivityContext.TraceState == activity.TraceStateString))) + { + // Create a new activity with its parent set from the extracted context. + // This makes the new activity as a "sibling" of the activity created by + // Asp.Net Core. + Activity newOne; + if (Net7OrGreater) + { + // For NET7.0 onwards activity is created using ActivitySource so, + // we will use the source of the activity to create the new one. + newOne = activity.Source.CreateActivity(ActivityOperationName, ActivityKind.Server, ctx.ActivityContext); + } + else + { +#pragma warning disable CA2000 + newOne = new Activity(ActivityOperationName); +#pragma warning restore CA2000 + newOne.SetParentId(ctx.ActivityContext.TraceId, ctx.ActivityContext.SpanId, ctx.ActivityContext.TraceFlags); + } + + newOne.TraceStateString = ctx.ActivityContext.TraceState; + + newOne.SetTag("IsCreatedByInstrumentation", bool.TrueString); + + // Starting the new activity make it the Activity.Current one. + newOne.Start(); + + // Set IsAllDataRequested to false for the activity created by the framework to only export the sibling activity and not the framework activity + activity.IsAllDataRequested = false; + activity = newOne; + } + + Baggage.Current = ctx.Baggage; + } + + // enrich Activity from payload only if sampling decision + // is favorable. + if (activity.IsAllDataRequested) + { + try + { + if (this.options.Filter?.Invoke(context) == false) + { + AspNetCoreInstrumentationEventSource.Log.RequestIsFilteredOut(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + } + catch (Exception ex) + { + AspNetCoreInstrumentationEventSource.Log.RequestFilterException(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName, ex); + activity.IsAllDataRequested = false; + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + return; + } + + if (!Net7OrGreater) + { + ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource); + ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Server); + } + + var path = (request.PathBase.HasValue || request.Path.HasValue) ? (request.PathBase + request.Path).ToString() : "/"; + TelemetryHelper.RequestDataHelper.SetActivityDisplayName(activity, request.Method); + + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md + + if (request.Host.HasValue) + { + activity.SetTag(SemanticConventions.AttributeServerAddress, request.Host.Host); + + if (request.Host.Port.HasValue) + { + activity.SetTag(SemanticConventions.AttributeServerPort, request.Host.Port.Value); + } + } + + if (request.QueryString.HasValue) + { + if (this.options.DisableUrlQueryRedaction) + { + activity.SetTag(SemanticConventions.AttributeUrlQuery, request.QueryString.Value); + } + else + { + activity.SetTag(SemanticConventions.AttributeUrlQuery, RedactionHelper.GetRedactedQueryString(request.QueryString.Value)); + } + } + + TelemetryHelper.RequestDataHelper.SetHttpMethodTag(activity, request.Method); + + activity.SetTag(SemanticConventions.AttributeUrlScheme, request.Scheme); + activity.SetTag(SemanticConventions.AttributeUrlPath, path); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(request.Protocol)); + + if (request.Headers.TryGetValue("User-Agent", out var values)) + { + var userAgent = values.Count > 0 ? values[0] : null; + if (!string.IsNullOrEmpty(userAgent)) + { + activity.SetTag(SemanticConventions.AttributeUserAgentOriginal, userAgent); + } + } + + try + { + this.options.EnrichWithHttpRequest?.Invoke(activity, request); + } + catch (Exception ex) + { + AspNetCoreInstrumentationEventSource.Log.EnrichmentException(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName, ex); + } + } + } + + public void OnStopActivity(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + HttpContext context = payload as HttpContext; + if (context == null) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStopActivity), activity.OperationName); + return; + } + + var response = context.Response; + +#if !NETSTANDARD + var routePattern = (context.Features.Get()?.Endpoint as RouteEndpoint ?? + context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; + if (!string.IsNullOrEmpty(routePattern)) + { + TelemetryHelper.RequestDataHelper.SetActivityDisplayName(activity, context.Request.Method, routePattern); + activity.SetTag(SemanticConventions.AttributeHttpRoute, routePattern); + } +#endif + + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode)); + + if (this.options.EnableGrpcAspNetCoreSupport && TryGetGrpcMethod(activity, out var grpcMethod)) + { + AddGrpcAttributes(activity, grpcMethod, context); + } + + if (activity.Status == ActivityStatusCode.Unset) + { + activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); + } + + try + { + this.options.EnrichWithHttpResponse?.Invoke(activity, response); + } + catch (Exception ex) + { + AspNetCoreInstrumentationEventSource.Log.EnrichmentException(nameof(HttpInListener), nameof(this.OnStopActivity), activity.OperationName, ex); + } + } + + object tagValue; + if (Net7OrGreater) + { + tagValue = activity.GetTagValue("IsCreatedByInstrumentation"); + } + else + { + _ = activity.TryCheckFirstTag("IsCreatedByInstrumentation", out tagValue); + } + + if (ReferenceEquals(tagValue, bool.TrueString)) + { + // If instrumentation started a new Activity, it must + // be stopped here. + activity.SetTag("IsCreatedByInstrumentation", null); + activity.Stop(); + + // After the activity.Stop() code, Activity.Current becomes null. + // If Asp.Net Core uses Activity.Current?.Stop() - it'll not stop the activity + // it created. + // Currently Asp.Net core does not use Activity.Current, instead it stores a + // reference to its activity, and calls .Stop on it. + + // TODO: Should we still restore Activity.Current here? + // If yes, then we need to store the asp.net core activity inside + // the one created by the instrumentation. + // And retrieve it here, and set it to Current. + } + } + + public void OnException(Activity activity, object payload) + { + if (activity.IsAllDataRequested) + { + // We need to use reflection here as the payload type is not a defined public type. + if (!TryFetchException(payload, out Exception exc)) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnException), activity.OperationName); + return; + } + + activity.SetTag(SemanticConventions.AttributeErrorType, exc.GetType().FullName); + + if (this.options.RecordException) + { + activity.RecordException(exc); + } + + activity.SetStatus(ActivityStatusCode.Error); + + try + { + this.options.EnrichWithException?.Invoke(activity, exc); + } + catch (Exception ex) + { + AspNetCoreInstrumentationEventSource.Log.EnrichmentException(nameof(HttpInListener), nameof(this.OnException), activity.OperationName, ex); + } + } + + // See https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L252 + // and https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddlewareImpl.cs#L174 + // this makes sure that top-level properties on the payload object are always preserved. +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] +#endif + static bool TryFetchException(object payload, out Exception exc) + => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryGetGrpcMethod(Activity activity, out string grpcMethod) + { + grpcMethod = GrpcTagHelper.GetGrpcMethodFromActivity(activity); + return !string.IsNullOrEmpty(grpcMethod); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AddGrpcAttributes(Activity activity, string grpcMethod, HttpContext context) + { + // The RPC semantic conventions indicate the span name + // should not have a leading forward slash. + // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md#span-name + activity.DisplayName = grpcMethod.TrimStart('/'); + + activity.SetTag(SemanticConventions.AttributeRpcSystem, GrpcTagHelper.RpcSystemGrpc); + + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/rpc/rpc-spans.md + + if (context.Connection.RemoteIpAddress != null) + { + activity.SetTag(SemanticConventions.AttributeClientAddress, context.Connection.RemoteIpAddress.ToString()); + } + + activity.SetTag(SemanticConventions.AttributeClientPort, context.Connection.RemotePort); + + bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + if (validConversion) + { + activity.SetStatus(GrpcTagHelper.ResolveSpanStatusForGrpcStatusCode(status)); + } + + if (GrpcTagHelper.TryParseRpcServiceAndRpcMethod(grpcMethod, out var rpcService, out var rpcMethod)) + { + activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); + activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + + // Remove the grpc.method tag added by the gRPC .NET library + activity.SetTag(GrpcTagHelper.GrpcMethodTagName, null); + + // Remove the grpc.status_code tag added by the gRPC .NET library + activity.SetTag(GrpcTagHelper.GrpcStatusCodeTagName, null); + + if (validConversion) + { + // setting rpc.grpc.status_code + activity.SetTag(SemanticConventions.AttributeRpcGrpcStatusCode, status); + } + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs new file mode 100644 index 0000000000..cf9682d1fa --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -0,0 +1,128 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Diagnostics.Metrics; +using System.Reflection; +using Microsoft.AspNetCore.Http; +using OpenTelemetry.Internal; + +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Diagnostics; +using Microsoft.AspNetCore.Routing; +#endif +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +internal sealed class HttpInMetricsListener : ListenerHandler +{ + internal const string HttpServerRequestDurationMetricName = "http.server.request.duration"; + + internal const string OnUnhandledHostingExceptionEvent = "Microsoft.AspNetCore.Hosting.UnhandledException"; + internal const string OnUnhandledDiagnosticsExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException"; + + internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name; + internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + internal static readonly Meter Meter = new(InstrumentationName, InstrumentationVersion); + + private const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; + + private static readonly PropertyFetcher ExceptionPropertyFetcher = new("Exception"); + private static readonly PropertyFetcher HttpContextPropertyFetcher = new("HttpContext"); + private static readonly object ErrorTypeHttpContextItemsKey = new(); + + private static readonly Histogram HttpServerRequestDuration = Meter.CreateHistogram(HttpServerRequestDurationMetricName, "s", "Duration of HTTP server requests."); + + internal HttpInMetricsListener(string name) + : base(name) + { + } + + public static void OnExceptionEventWritten(string name, object payload) + { + // We need to use reflection here as the payload type is not a defined public type. + if (!TryFetchException(payload, out Exception exc) || !TryFetchHttpContext(payload, out HttpContext ctx)) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnExceptionEventWritten), HttpServerRequestDurationMetricName); + return; + } + + ctx.Items.Add(ErrorTypeHttpContextItemsKey, exc.GetType().FullName); + + // See https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L252 + // and https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddlewareImpl.cs#L174 + // this makes sure that top-level properties on the payload object are always preserved. +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] +#endif + static bool TryFetchException(object payload, out Exception exc) + => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; +#if NET6_0_OR_GREATER + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] +#endif + static bool TryFetchHttpContext(object payload, out HttpContext ctx) + => HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; + } + + public static void OnStopEventWritten(string name, object payload) + { + var context = payload as HttpContext; + if (context == null) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnStopEventWritten), HttpServerRequestDurationMetricName); + return; + } + + TagList tags = default; + + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md + tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(context.Request.Protocol))); + tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(context.Response.StatusCode))); + + var httpMethod = TelemetryHelper.RequestDataHelper.GetNormalizedHttpMethod(context.Request.Method); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); + +#if NET6_0_OR_GREATER + // Check the exception handler feature first in case the endpoint was overwritten + var route = (context.Features.Get()?.Endpoint as RouteEndpoint ?? + context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; + if (!string.IsNullOrEmpty(route)) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRoute, route)); + } +#endif + if (context.Items.TryGetValue(ErrorTypeHttpContextItemsKey, out var errorType)) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, errorType)); + } + + // We are relying here on ASP.NET Core to set duration before writing the stop event. + // https://github.com/dotnet/aspnetcore/blob/d6fa351048617ae1c8b47493ba1abbe94c3a24cf/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L449 + // TODO: Follow up with .NET team if we can continue to rely on this behavior. + HttpServerRequestDuration.Record(Activity.Current.Duration.TotalSeconds, tags); + } + + public override void OnEventWritten(string name, object payload) + { + switch (name) + { + case OnUnhandledDiagnosticsExceptionEvent: + case OnUnhandledHostingExceptionEvent: + { + OnExceptionEventWritten(name, payload); + } + + break; + case OnStopEvent: + { + OnStopEventWritten(name, payload); + } + + break; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs new file mode 100644 index 0000000000..4e8cd55524 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs @@ -0,0 +1,33 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +internal static class TelemetryHelper +{ + public static readonly object[] BoxedStatusCodes = InitializeBoxedStatusCodes(); + internal static readonly RequestDataHelper RequestDataHelper = new(); + + public static object GetBoxedStatusCode(int statusCode) + { + if (statusCode >= 100 && statusCode < 600) + { + return BoxedStatusCodes[statusCode - 100]; + } + + return statusCode; + } + + private static object[] InitializeBoxedStatusCodes() + { + var boxedStatusCodes = new object[500]; + for (int i = 0, c = 100; i < boxedStatusCodes.Length; i++, c++) + { + boxedStatusCodes[i] = c; + } + + return boxedStatusCodes; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj new file mode 100644 index 0000000000..c415de0ab1 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -0,0 +1,52 @@ + + + + net8.0;net7.0;net6.0;netstandard2.0 + ASP.NET Core instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing;AspNetCore + Instrumentation.AspNetCore- + 1.8.1 + + enable + + disable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md new file mode 100644 index 0000000000..f8ef36ef2d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -0,0 +1,331 @@ +# ASP.NET Core Instrumentation for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) + +This is an [Instrumentation +Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), +which instruments [ASP.NET Core](https://docs.microsoft.com/aspnet/core) and +collect metrics and traces about incoming web requests. This instrumentation +also collects traces from incoming gRPC requests using +[Grpc.AspNetCore](https://www.nuget.org/packages/Grpc.AspNetCore). +Instrumentation support for gRPC server requests is supported via an +[experimental](#experimental-support-for-grpc-requests) feature flag. + +This component is based on the +[v1.23](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http) +of http semantic conventions. For details on the default set of attributes that +are added, checkout [Traces](#traces) and [Metrics](#metrics) sections below. + +## Steps to enable OpenTelemetry.Instrumentation.AspNetCore + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.AspNetCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.AspNetCore +``` + +### Step 2: Enable ASP.NET Core Instrumentation at application startup + +ASP.NET Core instrumentation must be enabled at application startup. This is +typically done in the `ConfigureServices` of your `Startup` class. Both examples +below enables OpenTelemetry by calling `AddOpenTelemetry()` on `IServiceCollection`. + This extension method requires adding the package +[`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md) +to the application. This ensures instrumentations are disposed when the host +is shutdown. + +#### Traces + +The following example demonstrates adding ASP.NET Core instrumentation with the +extension method `WithTracing()` on `OpenTelemetryBuilder`. +then extension method `AddAspNetCoreInstrumentation()` on `TracerProviderBuilder` +to the application. This example also sets up the Console Exporter, +which requires adding the package [`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Trace; + +public void ConfigureServices(IServiceCollection services) +{ + services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation() + .AddConsoleExporter()); +} +``` + +Following list of attributes are added by default on activity. See +[http-spans](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http/http-spans.md) +for more details about each individual attribute: + +* `error.type` +* `http.request.method` +* `http.request.method_original` +* `http.response.status_code` +* `http.route` +* `network.protocol.version` +* `user_agent.original` +* `server.address` +* `server.port` +* `url.path` +* `url.query` - By default, the values in the query component are replaced with + the text `Redacted`. For example, `?key1=value1&key2=value2` becomes + `?key1=Redacted&key2=Redacted`. You can disable this redaction by setting the + environment variable + `OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION` to `true`. +* `url.scheme` + +[Enrich Api](#enrich) can be used if any additional attributes are +required on activity. + +#### Metrics + +The following example demonstrates adding ASP.NET Core instrumentation with the +extension method `WithMetrics()` on `OpenTelemetryBuilder` +then extension method `AddAspNetCoreInstrumentation()` on `MeterProviderBuilder` +to the application. This example also sets up the Console Exporter, +which requires adding the package [`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Metrics; + +public void ConfigureServices(IServiceCollection services) +{ + services.AddOpenTelemetry() + .WithMetrics(builder => builder + .AddAspNetCoreInstrumentation() + .AddConsoleExporter()); +} +``` + +Following list of attributes are added by default on +`http.server.request.duration` metric. See +[http-metrics](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http/http-metrics.md) +for more details about each individual attribute. `.NET8.0` and above supports +additional metrics, see [list of metrics produced](#list-of-metrics-produced) for +more details. + +* `error.type` +* `http.response.status_code` +* `http.request.method` +* `http.route` +* `network.protocol.version` +* `url.scheme` + +#### List of metrics produced + +When the application targets `.NET6.0` or `.NET7.0`, the instrumentation emits +the following metric: + +| Name | Details | +|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| `http.server.request.duration` | [Specification](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md#metric-httpserverrequestduration) | + +Starting from `.NET8.0`, metrics instrumentation is natively implemented, and +the ASP.NET Core library has incorporated support for [built-in +metrics](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-aspnetcore) +following the OpenTelemetry semantic conventions. The library includes additional +metrics beyond those defined in the +[specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md), +covering additional scenarios for ASP.NET Core users. When the application +targets `.NET8.0` and newer versions, the instrumentation library automatically +enables all `built-in` metrics by default. + +Note that the `AddAspNetCoreInstrumentation()` extension simplifies the process +of enabling all built-in metrics via a single line of code. Alternatively, for +more granular control over emitted metrics, you can utilize the `AddMeter()` +extension on `MeterProviderBuilder` for meters listed in +[built-in-metrics-aspnetcore](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-aspnetcore). +Using `AddMeter()` for metrics activation eliminates the need to take dependency +on the instrumentation library package and calling +`AddAspNetCoreInstrumentation()`. + +If you utilize `AddAspNetCoreInstrumentation()` and wish to exclude unnecessary +metrics, you can utilize +[Views](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#drop-an-instrument) +to achieve this. + +> [!NOTE] +> There is no difference in features or emitted metrics when enabling metrics +using `AddMeter()` or `AddAspNetCoreInstrumentation()` on `.NET8.0` and newer +versions. + +> [!NOTE] +> The `http.server.request.duration` metric is emitted in `seconds` as per the +semantic convention. While the convention [recommends using custom histogram +buckets](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md) +, this feature is not yet available via .NET Metrics API. A +[workaround](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4820) +has been included in OTel SDK starting version `1.6.0` which applies recommended +buckets by default for `http.server.request.duration`. This applies to all +targeted frameworks. + +## Advanced configuration + +### Tracing + +This instrumentation can be configured to change the default behavior by using +`AspNetCoreTraceInstrumentationOptions`, which allows adding [`Filter`](#filter), +[`Enrich`](#enrich) as explained below. + +// TODO: This section could be refined. +When used with +[`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md), +all configurations to `AspNetCoreTraceInstrumentationOptions` can be done in the +`ConfigureServices` +method of you applications `Startup` class as shown below. + +```csharp +// Configure +services.Configure(options => +{ + options.Filter = (httpContext) => + { + // only collect telemetry about HTTP GET requests + return httpContext.Request.Method.Equals("GET"); + }; +}); + +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation() + .AddConsoleExporter()); +``` + +#### Filter + +This instrumentation by default collects all the incoming http requests. It +allows filtering of requests by using the `Filter` function in +`AspNetCoreTraceInstrumentationOptions`. This defines the condition for allowable +requests. The Filter receives the `HttpContext` of the incoming +request, and does not collect telemetry about the request if the Filter +returns false or throws exception. + +The following code snippet shows how to use `Filter` to only allow GET +requests. + +```csharp +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation((options) => options.Filter = httpContext => + { + // only collect telemetry about HTTP GET requests + return httpContext.Request.Method.Equals("GET"); + }) + .AddConsoleExporter()); +``` + +It is important to note that this `Filter` option is specific to this +instrumentation. OpenTelemetry has a concept of a +[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling), +and the `Filter` option does the filtering *after* the Sampler is invoked. + +#### Enrich + +This instrumentation library provides `EnrichWithHttpRequest`, +`EnrichWithHttpResponse` and `EnrichWithException` options that can be used to +enrich the activity with additional information from the raw `HttpRequest`, +`HttpResponse` and `Exception` objects respectively. These actions are called +only when `activity.IsAllDataRequested` is `true`. It contains the activity +itself (which can be enriched) and the actual raw object. + +The following code snippet shows how to enrich the activity using all 3 +different options. + +```csharp +services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation(o => + { + o.EnrichWithHttpRequest = (activity, httpRequest) => + { + activity.SetTag("requestProtocol", httpRequest.Protocol); + }; + o.EnrichWithHttpResponse = (activity, httpResponse) => + { + activity.SetTag("responseLength", httpResponse.ContentLength); + }; + o.EnrichWithException = (activity, exception) => + { + activity.SetTag("exceptionType", exception.GetType().ToString()); + }; + })); +``` + +[Processor](../../docs/trace/extending-the-sdk/README.md#processor), +is the general extensibility point to add additional properties to any activity. +The `Enrich` option is specific to this instrumentation, and is provided to +get access to `HttpRequest` and `HttpResponse`. + +#### RecordException + +This instrumentation automatically sets Activity Status to Error if an unhandled +exception is thrown. Additionally, `RecordException` feature may be turned on, +to store the exception to the Activity itself as ActivityEvent. + +## Activity duration and http.server.request.duration metric calculation + +`Activity.Duration` and `http.server.request.duration` values represents the +time used to handle an inbound HTTP request as measured at the hosting layer of +ASP.NET Core. The time measurement starts once the underlying web host has: + +* Sufficiently parsed the HTTP request headers on the inbound network stream to + identify the new request. +* Initialized the context data structures such as the + [HttpContext](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.http.httpcontext). + +The time ends when: + +* The ASP.NET Core handler pipeline is finished executing. +* All response data has been sent. +* The context data structures for the request are being disposed. + +## Experimental support for gRPC requests + +gRPC instrumentation can be enabled by setting +`OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION` flag to +`True`. The flag can be set as an environment variable or via IConfiguration as +shown below. + +```csharp +var appBuilder = WebApplication.CreateBuilder(args); + +appBuilder.Configuration.AddInMemoryCollection( + new Dictionary + { + ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION"] = "true", + }); + +appBuilder.Services.AddOpenTelemetry() + .WithTracing(tracing => tracing + .AddAspNetCoreInstrumentation()); +``` + + Semantic conventions for RPC are still + [experimental](https://github.com/open-telemetry/semantic-conventions/tree/main/docs/rpc) + and hence the instrumentation only offers it as an experimental feature. + +## Troubleshooting + +This component uses an +[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) +with the name "OpenTelemetry-Instrumentation-AspNetCore" for its internal +logging. Please refer to [SDK +troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on +seeing these internal logs. + +## References + +* [Introduction to ASP.NET + Core](https://docs.microsoft.com/aspnet/core/introduction-to-aspnet-core) +* [gRPC services using ASP.NET Core](https://docs.microsoft.com/aspnet/core/grpc/aspnetcore) +* [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/Shared/ActivityHelperExtensions.cs b/src/Shared/ActivityHelperExtensions.cs index 6a85d45527..7425c97edc 100644 --- a/src/Shared/ActivityHelperExtensions.cs +++ b/src/Shared/ActivityHelperExtensions.cs @@ -4,14 +4,24 @@ #nullable enable using System.Diagnostics; +using System.Runtime.CompilerServices; namespace OpenTelemetry.Trace; internal static class ActivityHelperExtensions { - public static object? GetTagValue(this Activity activity, string tagName) + /// + /// Gets the value of a specific tag on an . + /// + /// Activity instance. + /// Case-sensitive tag name to retrieve. + /// Tag value or null if a match was not found. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static object? GetTagValue(this Activity activity, string? tagName) { - foreach (var tag in activity.TagObjects) + Debug.Assert(activity != null, "Activity should not be null"); + + foreach (ref readonly var tag in activity!.EnumerateTagObjects()) { if (tag.Key == tagName) { @@ -21,4 +31,33 @@ internal static class ActivityHelperExtensions return null; } + + /// + /// Checks if the user provided tag name is the first tag of the and retrieves the tag value. + /// + /// Activity instance. + /// Tag name. + /// Tag value. + /// if the first tag of the supplied Activity matches the user provide tag name. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryCheckFirstTag(this Activity activity, string tagName, out object? tagValue) + { + Debug.Assert(activity != null, "Activity should not be null"); + + var enumerator = activity!.EnumerateTagObjects(); + + if (enumerator.MoveNext()) + { + ref readonly var tag = ref enumerator.Current; + + if (tag.Key == tagName) + { + tagValue = tag.Value; + return true; + } + } + + tagValue = null; + return false; + } } diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 934b0d638c..169dbd0936 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -18,6 +18,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs new file mode 100644 index 0000000000..1175922312 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -0,0 +1,186 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +/* +BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1702/22H2/2022Update/SunValley2) +Intel Core i7-8850H CPU 2.60GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +.NET SDK=7.0.203 + [Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2 + + +| Method | EnableInstrumentation | Mean | Error | StdDev | Gen0 | Allocated | +|--------------------------- |---------------------- |---------:|--------:|--------:|-------:|----------:| +| GetRequestForAspNetCoreApp | None | 136.8 us | 1.56 us | 1.46 us | 0.4883 | 2.45 KB | +| GetRequestForAspNetCoreApp | Traces | 148.1 us | 0.88 us | 0.82 us | 0.7324 | 3.57 KB | +| GetRequestForAspNetCoreApp | Metrics | 144.4 us | 1.16 us | 1.08 us | 0.4883 | 2.92 KB | +| GetRequestForAspNetCoreApp | Traces, Metrics | 163.0 us | 1.60 us | 1.49 us | 0.7324 | 3.63 KB | + +Allocation details for .NET 7: + +// Traces +* Activity creation + `Activity.Start()` = 416 B +* Casting of the struct `Microsoft.Extensions.Primitives.StringValues` to `IEnumerable` by `HttpRequestHeaderValuesGetter` + - `TraceContextPropagator.Extract` = 24 B + - `BaggageContextPropagator.Extract` = 24 B +* String creation for `HttpRequest.HostString.Host` = 40 B +* `Activity.TagsLinkedList` (this is allocated on the first Activity.SetTag call) = 40 B +* Boxing of `Port` number when adding it as a tag = 24 B +* String creation in `GetUri` method for adding the http url tag = 66 B +* Setting `Baggage` (Setting AsyncLocal values causes allocation) + - `BaggageHolder` creation = 24 B + - `System.Threading.AsyncLocalValueMap.TwoElementAsyncLocalValueMap` = 48 B + - `System.Threading.ExecutionContext` = 40 B +* `DiagNode>` + - This is allocated eight times for the eight tags that are added = 8 * 40 = 320 B +* `Activity.Stop()` trying to set `Activity.Current` (This happens because of setting another AsyncLocal variable which is `Baggage` + - System.Threading.AsyncLocalValueMap.OneElementAsyncLocalValueMap = 32 B + - System.Threading.ExecutionContext = 40 B + +Baseline = 2.45 KB +With Traces = 2.45 + (1138 / 1024) = 2.45 + 1.12 = 3.57 KB + + +// Metrics +* Activity creation + `Activity.Start()` = 416 B +* Boxing of `Port` number when adding it as a tag = 24 B +* String creation for `HttpRequest.HostString.Host` = 40 B + +Baseline = 2.45 KB +With Metrics = 2.45 + (416 + 40 + 24) / 1024 = 2.45 + 0.47 = 2.92 KB + +// With Traces and Metrics + +Baseline = 2.45 KB +With Traces and Metrics = Baseline + With Traces + (With Metrics - (Activity creation + `Acitivity.Stop()`)) (they use the same activity) + = 2.45 + (1138 + 64) / 1024 = 2.45 + 1.17 = ~3.63KB +*/ + +namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; + +public class AspNetCoreInstrumentationBenchmarks +{ + private HttpClient httpClient; + private WebApplication app; + private TracerProvider tracerProvider; + private MeterProvider meterProvider; + + [Flags] + public enum EnableInstrumentationOption + { + /// + /// Instrumentation is not enabled for any signal. + /// + None = 0, + + /// + /// Instrumentation is enbled only for Traces. + /// + Traces = 1, + + /// + /// Instrumentation is enbled only for Metrics. + /// + Metrics = 2, + } + + [Params(0, 1, 2, 3)] + public EnableInstrumentationOption EnableInstrumentation { get; set; } + + [GlobalSetup(Target = nameof(GetRequestForAspNetCoreApp))] + public void GetRequestForAspNetCoreAppGlobalSetup() + { + if (this.EnableInstrumentation == EnableInstrumentationOption.None) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .Build(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .Build(); + } + else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && + this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .Build(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .Build(); + } + } + + [GlobalCleanup(Target = nameof(GetRequestForAspNetCoreApp))] + public async Task GetRequestForAspNetCoreAppGlobalCleanup() + { + if (this.EnableInstrumentation == EnableInstrumentationOption.None) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.tracerProvider.Dispose(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.meterProvider.Dispose(); + } + else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && + this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.tracerProvider.Dispose(); + this.meterProvider.Dispose(); + } + } + + [Benchmark] + public async Task GetRequestForAspNetCoreApp() + { + var httpResponse = await this.httpClient.GetAsync(new Uri("http://localhost:5000")).ConfigureAwait(false); + httpResponse.EnsureSuccessStatusCode(); + } + + private void StartWebApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + var app = builder.Build(); + app.MapGet("/", async context => await context.Response.WriteAsync($"Hello World!")); + app.RunAsync(); + + this.app = app; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs new file mode 100644 index 0000000000..9ed7771cd0 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs @@ -0,0 +1,207 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +/* +// * Summary * + +BenchmarkDotNet=v0.13.5, OS=Windows 11 (10.0.22621.1992/22H2/2022Update/SunValley2), VM=Hyper-V +AMD EPYC 7763, 1 CPU, 16 logical and 8 physical cores +.NET SDK=7.0.306 + [Host] : .NET 7.0.9 (7.0.923.32018), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.9 (7.0.923.32018), X64 RyuJIT AVX2 + + +| Method | EnableInstrumentation | Mean | Error | StdDev | Allocated | +|--------------------------- |---------------------- |---------:|--------:|--------:|----------:| +| GetRequestForAspNetCoreApp | None | 150.7 us | 1.68 us | 1.57 us | 2.45 KB | +| GetRequestForAspNetCoreApp | Traces | 156.6 us | 3.12 us | 6.37 us | 3.46 KB | +| GetRequestForAspNetCoreApp | Metrics | 148.8 us | 2.87 us | 2.69 us | 2.92 KB | +| GetRequestForAspNetCoreApp | Traces, Metrics | 164.0 us | 3.19 us | 6.22 us | 3.52 KB | + +Allocation details for .NET 7: + +// Traces +* Activity creation + `Activity.Start()` = 416 B +* Casting of the struct `Microsoft.Extensions.Primitives.StringValues` to `IEnumerable` by `HttpRequestHeaderValuesGetter` + - `TraceContextPropagator.Extract` = 24 B + - `BaggageContextPropagator.Extract` = 24 B +* String creation for `HttpRequest.HostString.Host` = 40 B +* `Activity.TagsLinkedList` (this is allocated on the first Activity.SetTag call) = 40 B +* Boxing of `Port` number when adding it as a tag = 24 B +* Setting `Baggage` (Setting AsyncLocal values causes allocation) + - `BaggageHolder` creation = 24 B + - `System.Threading.AsyncLocalValueMap.TwoElementAsyncLocalValueMap` = 48 B + - `System.Threading.ExecutionContext` = 40 B +* `DiagNode>` + - This is allocated seven times for the seven (eight if query string is available) tags that are added = 7 * 40 = 280 B +* `Activity.Stop()` trying to set `Activity.Current` (This happens because of setting another AsyncLocal variable which is `Baggage` + - System.Threading.AsyncLocalValueMap.OneElementAsyncLocalValueMap = 32 B + - System.Threading.ExecutionContext = 40 B + +Baseline = 2.45 KB +With Traces = 2.45 + (1032 / 1024) = 2.45 + 1.01 = 3.46 KB + + +// Metrics +* Activity creation + `Activity.Start()` = 416 B +* Boxing of `Port` number when adding it as a tag = 24 B +* String creation for `HttpRequest.HostString.Host` = 40 B + +Baseline = 2.45 KB +With Metrics = 2.45 + (416 + 40 + 24) / 1024 = 2.45 + 0.47 = 2.92 KB + +// With Traces and Metrics + +Baseline = 2.45 KB +With Traces and Metrics = Baseline + With Traces + (With Metrics - (Activity creation + `Acitivity.Stop()`)) (they use the same activity) + = 2.45 + (1032 + 64) / 1024 = 2.45 + 1.07 = ~3.52KB +*/ +namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; + +public class AspNetCoreInstrumentationNewBenchmarks +{ + private HttpClient httpClient; + private WebApplication app; + private TracerProvider tracerProvider; + private MeterProvider meterProvider; + + [Flags] + public enum EnableInstrumentationOption + { + /// + /// Instrumentation is not enabled for any signal. + /// + None = 0, + + /// + /// Instrumentation is enbled only for Traces. + /// + Traces = 1, + + /// + /// Instrumentation is enbled only for Metrics. + /// + Metrics = 2, + } + + [Params(0, 1, 2, 3)] + public EnableInstrumentationOption EnableInstrumentation { get; set; } + + [GlobalSetup(Target = nameof(GetRequestForAspNetCoreApp))] + public void GetRequestForAspNetCoreAppGlobalSetup() + { + KeyValuePair[] config = new KeyValuePair[] { new KeyValuePair("OTEL_SEMCONV_STABILITY_OPT_IN", "http") }; + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(config) + .Build(); + + if (this.EnableInstrumentation == EnableInstrumentationOption.None) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .Build(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + var exportedItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems, metricReaderOptions => + { + metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1000; + }) + .Build(); + } + else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && + this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) + { + this.StartWebApplication(); + this.httpClient = new HttpClient(); + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .Build(); + + var exportedItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems, metricReaderOptions => + { + metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1000; + }) + .Build(); + } + } + + [GlobalCleanup(Target = nameof(GetRequestForAspNetCoreApp))] + public async Task GetRequestForAspNetCoreAppGlobalCleanup() + { + if (this.EnableInstrumentation == EnableInstrumentationOption.None) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.tracerProvider.Dispose(); + } + else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.meterProvider.Dispose(); + } + else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && + this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) + { + this.httpClient.Dispose(); + await this.app.DisposeAsync(); + this.tracerProvider.Dispose(); + this.meterProvider.Dispose(); + } + } + + [Benchmark] + public async Task GetRequestForAspNetCoreApp() + { + var httpResponse = await this.httpClient.GetAsync(new Uri("http://localhost:5000")).ConfigureAwait(false); + httpResponse.EnsureSuccessStatusCode(); + } + + private void StartWebApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + var app = builder.Build(); + app.MapGet("/", async context => await context.Response.WriteAsync($"Hello World!")); + app.RunAsync(); + + this.app = app; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj new file mode 100644 index 0000000000..84fe25b212 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj @@ -0,0 +1,21 @@ + + + Exe + + $(SupportedNetTargets) + enable + disable + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs new file mode 100644 index 0000000000..612690cb98 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using BenchmarkDotNet.Running; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark; + +internal class Program +{ + private static void Main(string[] args) => BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md new file mode 100644 index 0000000000..075e40772c --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md @@ -0,0 +1,11 @@ +# OpenTelemetry ASP.NET Core Instrumentation Benchmarks + +Navigate to `./test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark` directory +and run the following command: + +```sh +dotnet run -c Release -f net8.0 -- -m +`` + +Then choose the benchmark class that you want to run by entering the required +option number from the list of options shown on the Console window. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs new file mode 100644 index 0000000000..5590a2fb3e --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -0,0 +1,1272 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using TestApp.AspNetCore; +using TestApp.AspNetCore.Filters; +using Xunit; +using Uri = System.Uri; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Tests; + +// See https://github.com/aspnet/Docs/tree/master/aspnetcore/test/integration-tests/samples/2.x/IntegrationTestsSample +[Collection("AspNetCore")] +public sealed class BasicTests + : IClassFixture>, IDisposable +{ + private readonly WebApplicationFactory factory; + private TracerProvider tracerProvider; + + public BasicTests(WebApplicationFactory factory) + { + this.factory = factory; + } + + [Fact] + public void AddAspNetCoreInstrumentation_BadArgs() + { + TracerProviderBuilder builder = null; + Assert.Throws(() => builder.AddAspNetCoreInstrumentation()); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task StatusIsUnsetOn200Response(bool disableLogging) + { + var exportedItems = new List(); + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + if (disableLogging) + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + } + }) + .CreateClient()) + { + // Act + using var response = await client.GetAsync(new Uri("/api/values", UriKind.Relative)); + + // Assert + response.EnsureSuccessStatusCode(); // Status Code 200-299 + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(200, activity.GetTagValue(SemanticConventions.AttributeHttpResponseStatusCode)); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); + ValidateAspNetCoreActivity(activity, "/api/values"); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task SuccessfulTemplateControllerCallGeneratesASpan(bool shouldEnrich) + { + var exportedItems = new List(); + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation(options => + { + if (shouldEnrich) + { + options.EnrichWithHttpRequest = (activity, request) => { activity.SetTag("enrichedOnStart", "yes"); }; + options.EnrichWithHttpResponse = (activity, response) => { activity.SetTag("enrichedOnStop", "yes"); }; + } + }) + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + // Act + using var response = await client.GetAsync(new Uri("/api/values", UriKind.Relative)); + + // Assert + response.EnsureSuccessStatusCode(); // Status Code 200-299 + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + if (shouldEnrich) + { + Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enrichedOnStart" && tag.Value == "yes")); + Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enrichedOnStop" && tag.Value == "yes")); + } + + ValidateAspNetCoreActivity(activity, "/api/values"); + } + + [Fact] + public async Task SuccessfulTemplateControllerCallUsesParentContext() + { + var exportedItems = new List(); + var expectedTraceId = ActivityTraceId.CreateRandom(); + var expectedSpanId = ActivitySpanId.CreateRandom(); + + // Arrange + using (var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + }); + + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + })) + { + using var client = testFactory.CreateClient(); + var request = new HttpRequestMessage(HttpMethod.Get, "/api/values/2"); + request.Headers.Add("traceparent", $"00-{expectedTraceId}-{expectedSpanId}-01"); + + // Act + var response = await client.SendAsync(request); + + // Assert + response.EnsureSuccessStatusCode(); // Status Code 200-299 + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", activity.OperationName); + + Assert.Equal(expectedTraceId, activity.Context.TraceId); + Assert.Equal(expectedSpanId, activity.ParentSpanId); + + ValidateAspNetCoreActivity(activity, "/api/values/2"); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public async Task CustomPropagator(bool addSampler) + { + try + { + var exportedItems = new List(); + var expectedTraceId = ActivityTraceId.CreateRandom(); + var expectedSpanId = ActivitySpanId.CreateRandom(); + + var propagator = new CustomTextMapPropagator + { + TraceId = expectedTraceId, + SpanId = expectedSpanId, + }; + + // Arrange + using (var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => + { + Sdk.SetDefaultTextMapPropagator(propagator); + var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder(); + + if (addSampler) + { + tracerProviderBuilder + .SetSampler(new TestSampler(SamplingDecision.RecordAndSample, new Dictionary { { "SomeTag", "SomeKey" }, })); + } + + this.tracerProvider = tracerProviderBuilder + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + }); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + })) + { + using var client = testFactory.CreateClient(); + using var response = await client.GetAsync(new Uri("/api/values/2", UriKind.Relative)); + response.EnsureSuccessStatusCode(); // Status Code 200-299 + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.True(activity.Duration != TimeSpan.Zero); + + Assert.Equal(expectedTraceId, activity.Context.TraceId); + Assert.Equal(expectedSpanId, activity.ParentSpanId); + + ValidateAspNetCoreActivity(activity, "/api/values/2"); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + [Fact] + public async Task RequestNotCollectedWhenFilterIsApplied() + { + var exportedItems = new List(); + + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation((opt) => opt.Filter = (ctx) => ctx.Request.Path != "/api/values/2") + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using (var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + })) + { + using var client = testFactory.CreateClient(); + + // Act + using var response1 = await client.GetAsync(new Uri("/api/values", UriKind.Relative)); + using var response2 = await client.GetAsync(new Uri("/api/values/2", UriKind.Relative)); + + // Assert + response1.EnsureSuccessStatusCode(); // Status Code 200-299 + response2.EnsureSuccessStatusCode(); // Status Code 200-299 + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + ValidateAspNetCoreActivity(activity, "/api/values"); + } + + [Fact] + public async Task RequestNotCollectedWhenFilterThrowException() + { + var exportedItems = new List(); + + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation((opt) => opt.Filter = (ctx) => + { + if (ctx.Request.Path == "/api/values/2") + { + throw new Exception("from InstrumentationFilter"); + } + else + { + return true; + } + }) + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using (var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + })) + { + using var client = testFactory.CreateClient(); + + // Act + using (var inMemoryEventListener = new InMemoryEventListener(AspNetCoreInstrumentationEventSource.Log)) + { + using var response1 = await client.GetAsync(new Uri("/api/values", UriKind.Relative)); + using var response2 = await client.GetAsync(new Uri("/api/values/2", UriKind.Relative)); + + response1.EnsureSuccessStatusCode(); // Status Code 200-299 + response2.EnsureSuccessStatusCode(); // Status Code 200-299 + Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 3)); + } + + WaitForActivityExport(exportedItems, 1); + } + + // As InstrumentationFilter threw, we continue as if the + // InstrumentationFilter did not exist. + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + ValidateAspNetCoreActivity(activity, "/api/values"); + } + + [Theory] + [InlineData(SamplingDecision.Drop)] + [InlineData(SamplingDecision.RecordOnly)] + [InlineData(SamplingDecision.RecordAndSample)] + public async Task ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision samplingDecision) + { + try + { + var expectedTraceId = ActivityTraceId.CreateRandom(); + var expectedParentSpanId = ActivitySpanId.CreateRandom(); + var expectedTraceState = "rojo=1,congo=2"; + var activityContext = new ActivityContext(expectedTraceId, expectedParentSpanId, ActivityTraceFlags.Recorded, expectedTraceState, true); + var expectedBaggage = Baggage.SetBaggage("key1", "value1").SetBaggage("key2", "value2"); + Sdk.SetDefaultTextMapPropagator(new ExtractOnlyPropagator(activityContext, expectedBaggage)); + + // Arrange + using var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => { this.tracerProvider = Sdk.CreateTracerProviderBuilder().SetSampler(new TestSampler(samplingDecision)).AddAspNetCoreInstrumentation().Build(); }); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }); + using var client = testFactory.CreateClient(); + + // Test TraceContext Propagation + var request = new HttpRequestMessage(HttpMethod.Get, "/api/GetChildActivityTraceContext"); + var response = await client.SendAsync(request); + var childActivityTraceContext = JsonSerializer.Deserialize>(await response.Content.ReadAsStringAsync()); + + response.EnsureSuccessStatusCode(); + + Assert.Equal(expectedTraceId.ToString(), childActivityTraceContext["TraceId"]); + Assert.Equal(expectedTraceState, childActivityTraceContext["TraceState"]); + Assert.NotEqual(expectedParentSpanId.ToString(), childActivityTraceContext["ParentSpanId"]); // there is a new activity created in instrumentation therefore the ParentSpanId is different that what is provided in the headers + + // Test Baggage Context Propagation + request = new HttpRequestMessage(HttpMethod.Get, "/api/GetChildActivityBaggageContext"); + + response = await client.SendAsync(request); + var childActivityBaggageContext = JsonSerializer.Deserialize>(await response.Content.ReadAsStringAsync()); + + response.EnsureSuccessStatusCode(); + + Assert.Single(childActivityBaggageContext, item => item.Key == "key1" && item.Value == "value1"); + Assert.Single(childActivityBaggageContext, item => item.Key == "key2" && item.Value == "value2"); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + [Fact] + public async Task ExtractContextIrrespectiveOfTheFilterApplied() + { + try + { + var expectedTraceId = ActivityTraceId.CreateRandom(); + var expectedParentSpanId = ActivitySpanId.CreateRandom(); + var expectedTraceState = "rojo=1,congo=2"; + var activityContext = new ActivityContext(expectedTraceId, expectedParentSpanId, ActivityTraceFlags.Recorded, expectedTraceState); + var expectedBaggage = Baggage.SetBaggage("key1", "value1").SetBaggage("key2", "value2"); + Sdk.SetDefaultTextMapPropagator(new ExtractOnlyPropagator(activityContext, expectedBaggage)); + + // Arrange + bool isFilterCalled = false; + using var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation(options => + { + options.Filter = context => + { + isFilterCalled = true; + return false; + }; + }) + .Build(); + }); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }); + using var client = testFactory.CreateClient(); + + // Test TraceContext Propagation + var request = new HttpRequestMessage(HttpMethod.Get, "/api/GetChildActivityTraceContext"); + var response = await client.SendAsync(request); + + // Ensure that filter was called + Assert.True(isFilterCalled); + + var childActivityTraceContext = JsonSerializer.Deserialize>(await response.Content.ReadAsStringAsync()); + + response.EnsureSuccessStatusCode(); + + Assert.Equal(expectedTraceId.ToString(), childActivityTraceContext["TraceId"]); + Assert.Equal(expectedTraceState, childActivityTraceContext["TraceState"]); + Assert.NotEqual(expectedParentSpanId.ToString(), childActivityTraceContext["ParentSpanId"]); // there is a new activity created in instrumentation therefore the ParentSpanId is different that what is provided in the headers + + // Test Baggage Context Propagation + request = new HttpRequestMessage(HttpMethod.Get, "/api/GetChildActivityBaggageContext"); + + response = await client.SendAsync(request); + var childActivityBaggageContext = JsonSerializer.Deserialize>(await response.Content.ReadAsStringAsync()); + + response.EnsureSuccessStatusCode(); + + Assert.Single(childActivityBaggageContext, item => item.Key == "key1" && item.Value == "value1"); + Assert.Single(childActivityBaggageContext, item => item.Key == "key2" && item.Value == "value2"); + } + finally + { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] + { + new TraceContextPropagator(), + new BaggagePropagator(), + })); + } + } + + [Fact] + public async Task BaggageIsNotClearedWhenActivityStopped() + { + int? baggageCountAfterStart = null; + int? baggageCountAfterStop = null; + using EventWaitHandle stopSignal = new EventWaitHandle(false, EventResetMode.ManualReset); + + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation( + new TestHttpInListener(new AspNetCoreTraceInstrumentationOptions()) + { + OnEventWrittenCallback = (name, payload) => + { + switch (name) + { + case HttpInListener.OnStartEvent: + { + baggageCountAfterStart = Baggage.Current.Count; + } + + break; + case HttpInListener.OnStopEvent: + { + baggageCountAfterStop = Baggage.Current.Count; + stopSignal.Set(); + } + + break; + } + }, + }) + .Build(); + } + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + using var request = new HttpRequestMessage(HttpMethod.Get, "/api/values"); + + request.Headers.TryAddWithoutValidation("baggage", "TestKey1=123,TestKey2=456"); + + // Act + using var response = await client.SendAsync(request); + } + + stopSignal.WaitOne(5000); + + // Assert + Assert.NotNull(baggageCountAfterStart); + Assert.Equal(2, baggageCountAfterStart); + Assert.NotNull(baggageCountAfterStop); + Assert.Equal(2, baggageCountAfterStop); + } + + [Theory] + [InlineData(SamplingDecision.Drop, false, false)] + [InlineData(SamplingDecision.RecordOnly, true, true)] + [InlineData(SamplingDecision.RecordAndSample, true, true)] + public async Task FilterAndEnrichAreOnlyCalledWhenSampled(SamplingDecision samplingDecision, bool shouldFilterBeCalled, bool shouldEnrichBeCalled) + { + bool filterCalled = false; + bool enrichWithHttpRequestCalled = false; + bool enrichWithHttpResponseCalled = false; + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new TestSampler(samplingDecision)) + .AddAspNetCoreInstrumentation(options => + { + options.Filter = (context) => + { + filterCalled = true; + return true; + }; + options.EnrichWithHttpRequest = (activity, request) => + { + enrichWithHttpRequestCalled = true; + }; + options.EnrichWithHttpResponse = (activity, request) => + { + enrichWithHttpResponseCalled = true; + }; + }) + .Build(); + } + + // Arrange + using var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient(); + + // Act + using var response = await client.GetAsync(new Uri("/api/values", UriKind.Relative)); + + // Assert + Assert.Equal(shouldFilterBeCalled, filterCalled); + Assert.Equal(shouldEnrichBeCalled, enrichWithHttpRequestCalled); + Assert.Equal(shouldEnrichBeCalled, enrichWithHttpResponseCalled); + } + + [Fact] + public async Task ActivitiesStartedInMiddlewareShouldNotBeUpdated() + { + var exportedItems = new List(); + + var activitySourceName = "TestMiddlewareActivitySource"; + var activityName = "TestMiddlewareActivity"; + + void ConfigureTestServices(IServiceCollection services) + { + services.AddSingleton(new TestTestActivityMiddleware(activitySourceName, activityName)); + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddSource(activitySourceName) + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + using var response = await client.GetAsync(new Uri("/api/values/2", UriKind.Relative)); + response.EnsureSuccessStatusCode(); + WaitForActivityExport(exportedItems, 2); + } + + Assert.Equal(2, exportedItems.Count); + + var middlewareActivity = exportedItems[0]; + + var aspnetcoreframeworkactivity = exportedItems[1]; + + // Middleware activity name should not be changed + Assert.Equal(ActivityKind.Internal, middlewareActivity.Kind); + Assert.Equal(activityName, middlewareActivity.OperationName); + Assert.Equal(activityName, middlewareActivity.DisplayName); + + // tag http.method should be added on activity started by asp.net core + Assert.Equal("GET", aspnetcoreframeworkactivity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod) as string); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", aspnetcoreframeworkactivity.OperationName); + } + + [Theory] + [InlineData("CONNECT", "CONNECT", null, "CONNECT")] + [InlineData("DELETE", "DELETE", null, "DELETE")] + [InlineData("GET", "GET", null, "GET")] + [InlineData("PUT", "PUT", null, "PUT")] + [InlineData("HEAD", "HEAD", null, "HEAD")] + [InlineData("OPTIONS", "OPTIONS", null, "OPTIONS")] + [InlineData("PATCH", "PATCH", null, "PATCH")] + [InlineData("Get", "GET", "Get", "GET")] + [InlineData("POST", "POST", null, "POST")] + [InlineData("TRACE", "TRACE", null, "TRACE")] + [InlineData("CUSTOM", "_OTHER", "CUSTOM", "HTTP")] + public async Task HttpRequestMethodAndActivityDisplayIsSetAsPerSpec(string originalMethod, string expectedMethod, string expectedOriginalMethod, string expectedDisplayName) + { + var exportedItems = new List(); + + void ConfigureTestServices(IServiceCollection services) + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + } + + // Arrange + using var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient(); + + var message = new HttpRequestMessage(); + + message.Method = new HttpMethod(originalMethod); + + try + { + using var response = await client.SendAsync(message); + response.EnsureSuccessStatusCode(); + } + catch + { + // ignore error. + } + + WaitForActivityExport(exportedItems, 1); + + Assert.Single(exportedItems); + + var activity = exportedItems[0]; + + Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); + Assert.Equal(expectedOriginalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal)); + Assert.Equal(expectedDisplayName, activity.DisplayName); + } + + [Fact] + public async Task ActivitiesStartedInMiddlewareBySettingHostActivityToNullShouldNotBeUpdated() + { + var exportedItems = new List(); + + var activitySourceName = "TestMiddlewareActivitySource"; + var activityName = "TestMiddlewareActivity"; + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices((IServiceCollection services) => + { + services.AddSingleton(new TestNullHostActivityMiddlewareImpl(activitySourceName, activityName)); + services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation() + .AddSource(activitySourceName) + .AddInMemoryExporter(exportedItems)); + }); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + using var response = await client.GetAsync(new Uri("/api/values/2", UriKind.Relative)); + response.EnsureSuccessStatusCode(); + WaitForActivityExport(exportedItems, 2); + } + + Assert.Equal(2, exportedItems.Count); + + var middlewareActivity = exportedItems[0]; + + var aspnetcoreframeworkactivity = exportedItems[1]; + + // Middleware activity name should not be changed + Assert.Equal(ActivityKind.Internal, middlewareActivity.Kind); + Assert.Equal(activityName, middlewareActivity.OperationName); + Assert.Equal(activityName, middlewareActivity.DisplayName); + + // tag http.method should be added on activity started by asp.net core + Assert.Equal("GET", aspnetcoreframeworkactivity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod) as string); + Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", aspnetcoreframeworkactivity.OperationName); + } + +#if NET7_0_OR_GREATER + [Fact] + public async Task UserRegisteredActivitySourceIsUsedForActivityCreationByAspNetCore() + { + var exportedItems = new List(); + void ConfigureTestServices(IServiceCollection services) + { + services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems)); + + // Register ActivitySource here so that it will be used + // by ASP.NET Core to create activities + // https://github.com/dotnet/aspnetcore/blob/0e5cbf447d329a1e7d69932c3decd1c70a00fbba/src/Hosting/Hosting/src/Internal/WebHost.cs#L152 + services.AddSingleton(sp => new ActivitySource("UserRegisteredActivitySource")); + } + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(ConfigureTestServices); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + // Act + using var response = await client.GetAsync(new Uri("/api/values", UriKind.Relative)); + + // Assert + response.EnsureSuccessStatusCode(); // Status Code 200-299 + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal("UserRegisteredActivitySource", activity.Source.Name); + } +#endif + + [Theory] + [InlineData(1)] + [InlineData(2)] + public async Task ShouldExportActivityWithOneOrMoreExceptionFilters(int mode) + { + var exportedItems = new List(); + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices( + (s) => this.ConfigureExceptionFilters(s, mode, ref exportedItems)); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + // Act + using var response = await client.GetAsync(new Uri("/api/error", UriKind.Relative)); + + WaitForActivityExport(exportedItems, 1); + } + + // Assert + AssertException(exportedItems); + } + + [Fact] + public async Task DiagnosticSourceCallbacksAreReceivedOnlyForSubscribedEvents() + { + int numberOfUnSubscribedEvents = 0; + int numberofSubscribedEvents = 0; + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation( + new TestHttpInListener(new AspNetCoreTraceInstrumentationOptions()) + { + OnEventWrittenCallback = (name, payload) => + { + switch (name) + { + case HttpInListener.OnStartEvent: + { + numberofSubscribedEvents++; + } + + break; + case HttpInListener.OnStopEvent: + { + numberofSubscribedEvents++; + } + + break; + default: + { + numberOfUnSubscribedEvents++; + } + + break; + } + }, + }) + .Build(); + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + using var request = new HttpRequestMessage(HttpMethod.Get, "/api/values"); + + // Act + using var response = await client.SendAsync(request); + } + + Assert.Equal(0, numberOfUnSubscribedEvents); + Assert.Equal(2, numberofSubscribedEvents); + } + + [Fact] + public async Task DiagnosticSourceExceptionCallbackIsReceivedForUnHandledException() + { + int numberOfUnSubscribedEvents = 0; + int numberofSubscribedEvents = 0; + int numberOfExceptionCallbacks = 0; + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation( + new TestHttpInListener(new AspNetCoreTraceInstrumentationOptions()) + { + OnEventWrittenCallback = (name, payload) => + { + switch (name) + { + case HttpInListener.OnStartEvent: + { + numberofSubscribedEvents++; + } + + break; + case HttpInListener.OnStopEvent: + { + numberofSubscribedEvents++; + } + + break; + + // TODO: Add test case for validating name for both the types + // of exception event. + case HttpInListener.OnUnhandledHostingExceptionEvent: + case HttpInListener.OnUnHandledDiagnosticsExceptionEvent: + { + numberofSubscribedEvents++; + numberOfExceptionCallbacks++; + } + + break; + default: + { + numberOfUnSubscribedEvents++; + } + + break; + } + }, + }) + .Build(); + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + try + { + using var request = new HttpRequestMessage(HttpMethod.Get, "/api/error"); + + // Act + using var response = await client.SendAsync(request); + } + catch + { + // ignore exception + } + } + + Assert.Equal(1, numberOfExceptionCallbacks); + Assert.Equal(0, numberOfUnSubscribedEvents); + Assert.Equal(3, numberofSubscribedEvents); + } + + [Fact] + public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHandledInMiddleware() + { + int numberOfUnSubscribedEvents = 0; + int numberOfSubscribedEvents = 0; + int numberOfExceptionCallbacks = 0; + bool exceptionHandled = false; + + // configure SDK + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation( + new TestHttpInListener(new AspNetCoreTraceInstrumentationOptions()) + { + OnEventWrittenCallback = (name, payload) => + { + switch (name) + { + case HttpInListener.OnStartEvent: + { + numberOfSubscribedEvents++; + } + + break; + case HttpInListener.OnStopEvent: + { + numberOfSubscribedEvents++; + } + + break; + + // TODO: Add test case for validating name for both the types + // of exception event. + case HttpInListener.OnUnhandledHostingExceptionEvent: + case HttpInListener.OnUnHandledDiagnosticsExceptionEvent: + { + numberOfSubscribedEvents++; + numberOfExceptionCallbacks++; + } + + break; + default: + { + numberOfUnSubscribedEvents++; + } + + break; + } + }, + }) + .Build(); + + TestMiddleware.Create(builder => builder + .UseExceptionHandler(handler => + handler.Run(async (ctx) => + { + exceptionHandled = true; + await ctx.Response.WriteAsync("handled"); + }))); + + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + try + { + using var request = new HttpRequestMessage(HttpMethod.Get, "/api/error"); + using var response = await client.SendAsync(request); + } + catch + { + // ignore exception + } + } + + Assert.Equal(0, numberOfExceptionCallbacks); + Assert.Equal(0, numberOfUnSubscribedEvents); + Assert.Equal(2, numberOfSubscribedEvents); + Assert.True(exceptionHandled); + } + + [Fact] + public async Task NoSiblingActivityCreatedWhenTraceFlagsNone() + { + using var localTracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddAspNetCoreInstrumentation() + .Build(); + + using var testFactory = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => + { + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .Build(); + }); + + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }); + using var client = testFactory.CreateClient(); + var request = new HttpRequestMessage(HttpMethod.Get, "/api/GetActivityEquality"); + var traceId = ActivityTraceId.CreateRandom(); + var spanId = ActivitySpanId.CreateRandom(); + request.Headers.Add("traceparent", $"00-{traceId}-{spanId}-00"); + + var response = await client.SendAsync(request); + var result = bool.Parse(await response.Content.ReadAsStringAsync()); + + Assert.True(response.IsSuccessStatusCode); + + // Confirm that Activity.Current and IHttpActivityFeature activity are same + Assert.True(result); + } + + [Theory] + [InlineData("?a", "?a", false)] + [InlineData("?a=bdjdjh", "?a=Redacted", false)] + [InlineData("?a=b&", "?a=Redacted&", false)] + [InlineData("?c=b&", "?c=Redacted&", false)] + [InlineData("?c=a", "?c=Redacted", false)] + [InlineData("?a=b&c", "?a=Redacted&c", false)] + [InlineData("?a=b&c=1123456&", "?a=Redacted&c=Redacted&", false)] + [InlineData("?a=b&c=1&a1", "?a=Redacted&c=Redacted&a1", false)] + [InlineData("?a=ghgjgj&c=1deedd&a1=", "?a=Redacted&c=Redacted&a1=Redacted", false)] + [InlineData("?a=b&c=11&a1=&", "?a=Redacted&c=Redacted&a1=Redacted&", false)] + [InlineData("?c&c&c&", "?c&c&c&", false)] + [InlineData("?a&a&a&a", "?a&a&a&a", false)] + [InlineData("?&&&&&&&", "?&&&&&&&", false)] + [InlineData("?c", "?c", false)] + [InlineData("?a", "?a", true)] + [InlineData("?a=bdfdfdf", "?a=bdfdfdf", true)] + [InlineData("?a=b&", "?a=b&", true)] + [InlineData("?c=b&", "?c=b&", true)] + [InlineData("?c=a", "?c=a", true)] + [InlineData("?a=b&c", "?a=b&c", true)] + [InlineData("?a=b&c=111111&", "?a=b&c=111111&", true)] + [InlineData("?a=b&c=1&a1", "?a=b&c=1&a1", true)] + [InlineData("?a=b&c=1&a1=", "?a=b&c=1&a1=", true)] + [InlineData("?a=b123&c=11&a1=&", "?a=b123&c=11&a1=&", true)] + [InlineData("?c&c&c&", "?c&c&c&", true)] + [InlineData("?a&a&a&a", "?a&a&a&a", true)] + [InlineData("?&&&&&&&", "?&&&&&&&", true)] + [InlineData("?c", "?c", true)] + [InlineData("?c=%26&", "?c=Redacted&", false)] + public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQuery, bool disableQueryRedaction) + { + var exportedItems = new List(); + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION"] = disableQueryRedaction.ToString() }) + .Build(); + + var path = "/api/values" + urlQuery; + + // Arrange + using var traceprovider = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => services.AddSingleton(configuration)) + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + try + { + using var response = await client.GetAsync(new Uri(path, UriKind.Relative)); + } + catch (Exception) + { + // ignore errors + } + + WaitForActivityExport(exportedItems, 1); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(expectedUrlQuery, activity.GetTagValue(SemanticConventions.AttributeUrlQuery)); + } + + public void Dispose() + { + this.tracerProvider?.Dispose(); + } + + private static void WaitForActivityExport(List exportedItems, int count) + { + // We need to let End callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the End callback to complete + Assert.True(SpinWait.SpinUntil( + () => + { + Thread.Sleep(10); + return exportedItems.Count >= count; + }, + TimeSpan.FromSeconds(1))); + } + + private static void ValidateAspNetCoreActivity(Activity activityToValidate, string expectedHttpPath) + { + Assert.Equal(ActivityKind.Server, activityToValidate.Kind); +#if NET7_0_OR_GREATER + Assert.Equal(HttpInListener.AspNetCoreActivitySourceName, activityToValidate.Source.Name); + Assert.Empty(activityToValidate.Source.Version); +#else + Assert.Equal(HttpInListener.ActivitySourceName, activityToValidate.Source.Name); + Assert.Equal(HttpInListener.Version.ToString(), activityToValidate.Source.Version); +#endif + Assert.Equal(expectedHttpPath, activityToValidate.GetTagValue(SemanticConventions.AttributeUrlPath) as string); + } + + private static void AssertException(List exportedItems) + { + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + var exMessage = "something's wrong!"; + Assert.Single(activity.Events); + Assert.Equal("System.Exception", activity.Events.First().Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionType).Value); + Assert.Equal(exMessage, activity.Events.First().Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionMessage).Value); + + ValidateAspNetCoreActivity(activity, "/api/error"); + } + + private void ConfigureExceptionFilters(IServiceCollection services, int mode, ref List exportedItems) + { + switch (mode) + { + case 1: + services.AddMvc(x => x.Filters.Add()); + break; + case 2: + services.AddMvc(x => x.Filters.Add()); + services.AddMvc(x => x.Filters.Add()); + break; + default: + break; + } + + this.tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation(x => x.RecordException = true) + .AddInMemoryExporter(exportedItems) + .Build(); + } + + private class ExtractOnlyPropagator(ActivityContext activityContext, Baggage baggage) : TextMapPropagator + { + private readonly ActivityContext activityContext = activityContext; + private readonly Baggage baggage = baggage; + + public override ISet Fields => throw new NotImplementedException(); + + public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + { + return new PropagationContext(this.activityContext, this.baggage); + } + + public override void Inject(PropagationContext context, T carrier, Action setter) + { + throw new NotImplementedException(); + } + } + + private class TestSampler(SamplingDecision samplingDecision, IEnumerable> attributes = null) : Sampler + { + private readonly SamplingDecision samplingDecision = samplingDecision; + private readonly IEnumerable> attributes = attributes; + + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + return new SamplingResult(this.samplingDecision, this.attributes); + } + } + + private class TestHttpInListener(AspNetCoreTraceInstrumentationOptions options) : HttpInListener(options) + { + public Action OnEventWrittenCallback; + + public override void OnEventWritten(string name, object payload) + { + base.OnEventWritten(name, payload); + + this.OnEventWrittenCallback?.Invoke(name, payload); + } + } + + private class TestNullHostActivityMiddlewareImpl(string activitySourceName, string activityName) : TestActivityMiddleware + { + private readonly ActivitySource activitySource = new(activitySourceName); + private readonly string activityName = activityName; + private Activity activity; + + public override void PreProcess(HttpContext context) + { + // Setting the host activity i.e. activity started by asp.net core + // to null here will have no impact on middleware activity. + // This also means that asp.net core activity will not be found + // during OnEventWritten event. + Activity.Current = null; + this.activity = this.activitySource.StartActivity(this.activityName); + } + + public override void PostProcess(HttpContext context) + { + this.activity?.Stop(); + } + } + + private class TestTestActivityMiddleware(string activitySourceName, string activityName) : TestActivityMiddleware + { + private readonly ActivitySource activitySource = new(activitySourceName); + private readonly string activityName = activityName; + private Activity activity; + + public override void PreProcess(HttpContext context) + { + this.activity = this.activitySource.StartActivity(this.activityName); + } + + public override void PostProcess(HttpContext context) + { + this.activity?.Stop(); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs new file mode 100644 index 0000000000..a877d060a3 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Tests; + +[Collection("AspNetCore")] +public class DependencyInjectionConfigTests + : IClassFixture> +{ + private readonly WebApplicationFactory factory; + + public DependencyInjectionConfigTests(WebApplicationFactory factory) + { + this.factory = factory; + } + + [Theory] + [InlineData(null)] + [InlineData("CustomName")] + public void TestTracingOptionsDIConfig(string name) + { + name ??= Options.DefaultName; + + bool optionsPickedFromDI = false; + void ConfigureTestServices(IServiceCollection services) + { + services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation(name, configureAspNetCoreTraceInstrumentationOptions: null)); + + services.Configure(name, options => + { + optionsPickedFromDI = true; + }); + } + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + builder.ConfigureTestServices(ConfigureTestServices)) + .CreateClient()) + { + } + + Assert.True(optionsPickedFromDI); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EventSourceTest.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EventSourceTest.cs new file mode 100644 index 0000000000..5bae1e25f4 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/EventSourceTest.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Tests; + +public class EventSourceTest +{ + [Fact] + public void EventSourceTest_AspNetCoreInstrumentationEventSource() + { + EventSourceTestHelper.MethodsAreImplementedConsistentlyWithTheirAttributes(AspNetCoreInstrumentationEventSource.Log); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs new file mode 100644 index 0000000000..f6bc29a386 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs @@ -0,0 +1,172 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Trace; +using TestApp.AspNetCore; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Tests; + +[Collection("AspNetCore")] +public class IncomingRequestsCollectionsIsAccordingToTheSpecTests + : IClassFixture> +{ + private readonly WebApplicationFactory factory; + + public IncomingRequestsCollectionsIsAccordingToTheSpecTests(WebApplicationFactory factory) + { + this.factory = factory; + } + + [Theory] + [InlineData("/api/values", null, "user-agent", 200, null)] + [InlineData("/api/values", null, null, 200, null)] + [InlineData("/api/exception", null, null, 503, null)] + [InlineData("/api/exception", null, null, 503, null, true)] + public async Task SuccessfulTemplateControllerCallGeneratesASpan_New( + string urlPath, + string query, + string userAgent, + int statusCode, + string reasonPhrase, + bool recordException = false) + { + var exportedItems = new List(); + + // Arrange + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices((IServiceCollection services) => + { + services.AddSingleton(new ExceptionTestCallbackMiddleware(statusCode, reasonPhrase)); + services.AddOpenTelemetry() + .WithTracing(builder => builder + .AddAspNetCoreInstrumentation(options => + { + options.RecordException = recordException; + }) + .AddInMemoryExporter(exportedItems)); + }); + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + try + { + if (!string.IsNullOrEmpty(userAgent)) + { + client.DefaultRequestHeaders.Add("User-Agent", userAgent); + } + + // Act + var path = urlPath; + if (query != null) + { + path += query; + } + + using var response = await client.GetAsync(new Uri(path, UriKind.Relative)); + } + catch (Exception) + { + // ignore errors + } + + for (var i = 0; i < 10; i++) + { + if (exportedItems.Count == 1) + { + break; + } + + // We need to let End callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the End callback to complete + await Task.Delay(TimeSpan.FromSeconds(1)); + } + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + Assert.Equal(ActivityKind.Server, activity.Kind); + Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + Assert.Equal("GET", activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); + Assert.Equal("1.1", activity.GetTagValue(SemanticConventions.AttributeNetworkProtocolVersion)); + Assert.Equal("http", activity.GetTagValue(SemanticConventions.AttributeUrlScheme)); + Assert.Equal(urlPath, activity.GetTagValue(SemanticConventions.AttributeUrlPath)); + Assert.Equal(query, activity.GetTagValue(SemanticConventions.AttributeUrlQuery)); + Assert.Equal(statusCode, activity.GetTagValue(SemanticConventions.AttributeHttpResponseStatusCode)); + + if (statusCode == 503) + { + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Equal("System.Exception", activity.GetTagValue(SemanticConventions.AttributeErrorType)); + } + else + { + Assert.Equal(ActivityStatusCode.Unset, activity.Status); + } + + // Instrumentation is not expected to set status description + // as the reason can be inferred from SemanticConventions.AttributeHttpStatusCode + Assert.Null(activity.StatusDescription); + + if (recordException) + { + Assert.Single(activity.Events); + Assert.Equal("exception", activity.Events.First().Name); + } + + ValidateTagValue(activity, SemanticConventions.AttributeUserAgentOriginal, userAgent); + + activity.Dispose(); + } + + private static void ValidateTagValue(Activity activity, string attribute, string expectedValue) + { + if (string.IsNullOrEmpty(expectedValue)) + { + Assert.Null(activity.GetTagValue(attribute)); + } + else + { + Assert.Equal(expectedValue, activity.GetTagValue(attribute)); + } + } + + internal class ExceptionTestCallbackMiddleware : TestCallbackMiddleware + { + private readonly int statusCode; + private readonly string reasonPhrase; + + public ExceptionTestCallbackMiddleware(int statusCode, string reasonPhrase) + { + this.statusCode = statusCode; + this.reasonPhrase = reasonPhrase; + } + + public override async Task ProcessAsync(HttpContext context) + { + context.Response.StatusCode = this.statusCode; + context.Response.HttpContext.Features.Get().ReasonPhrase = this.reasonPhrase; + await context.Response.WriteAsync("empty"); + + if (context.Request.Path.Value.EndsWith("exception", StringComparison.Ordinal)) + { + throw new Exception("exception description"); + } + + return false; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs new file mode 100644 index 0000000000..21743e0faf --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -0,0 +1,418 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET8_0_OR_GREATER +using System.Threading.RateLimiting; +using Microsoft.AspNetCore.Builder; +#endif +using Microsoft.AspNetCore.Hosting; +#if NET8_0_OR_GREATER +using Microsoft.AspNetCore.Http; +#endif +using Microsoft.AspNetCore.Mvc.Testing; +#if NET8_0_OR_GREATER +using Microsoft.AspNetCore.RateLimiting; +#endif +#if NET8_0_OR_GREATER +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +#endif +using Microsoft.Extensions.Logging; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Tests; + +[Collection("AspNetCore")] +public class MetricTests(WebApplicationFactory factory) + : IClassFixture>, IDisposable +{ + private readonly WebApplicationFactory factory = factory; + private MeterProvider meterProvider; + + [Fact] + public void AddAspNetCoreInstrumentation_BadArgs() + { + MeterProviderBuilder builder = null; + Assert.Throws(builder.AddAspNetCoreInstrumentation); + } + +#if NET8_0_OR_GREATER + [Fact] + public async Task ValidateNet8MetricsAsync() + { + var exportedItems = new List(); + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var builder = WebApplication.CreateBuilder(); + builder.WebHost.UseUrls("http://*:0"); + var app = builder.Build(); + + app.MapGet("/", () => "Hello"); + + _ = app.RunAsync(); + + var url = app.Urls.ToArray()[0]; + var portNumber = url.Substring(url.LastIndexOf(':') + 1); + + using var client = new HttpClient(); + var res = await client.GetAsync(new Uri($"http://localhost:{portNumber}/")); + Assert.True(res.IsSuccessStatusCode); + + // We need to let metric callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the callbacks to complete + await Task.Delay(TimeSpan.FromSeconds(1)); + + this.meterProvider.Dispose(); + + var requestDurationMetric = exportedItems + .Count(item => item.Name == "http.server.request.duration"); + + var activeRequestsMetric = exportedItems. + Count(item => item.Name == "http.server.active_requests"); + + var routeMatchingMetric = exportedItems. + Count(item => item.Name == "aspnetcore.routing.match_attempts"); + + var kestrelActiveConnectionsMetric = exportedItems. + Count(item => item.Name == "kestrel.active_connections"); + + var kestrelQueuedConnectionMetric = exportedItems. + Count(item => item.Name == "kestrel.queued_connections"); + + Assert.Equal(1, requestDurationMetric); + Assert.Equal(1, activeRequestsMetric); + Assert.Equal(1, routeMatchingMetric); + Assert.Equal(1, kestrelActiveConnectionsMetric); + Assert.Equal(1, kestrelQueuedConnectionMetric); + + // TODO + // kestrel.queued_requests + // kestrel.upgraded_connections + // kestrel.rejected_connections + // kestrel.tls_handshake.duration + // kestrel.active_tls_handshakes + + await app.DisposeAsync(); + } + + [Fact] + public async Task ValidateNet8RateLimitingMetricsAsync() + { + var exportedItems = new List(); + + void ConfigureTestServices(IServiceCollection services) + { + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + services.AddRateLimiter(_ => _ + .AddFixedWindowLimiter(policyName: "fixed", options => + { + options.PermitLimit = 4; + options.Window = TimeSpan.FromSeconds(12); + options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; + options.QueueLimit = 2; + })); + } + + var builder = WebApplication.CreateBuilder(); + builder.WebHost.UseUrls("http://*:0"); + ConfigureTestServices(builder.Services); + + builder.Logging.ClearProviders(); + var app = builder.Build(); + + app.UseRateLimiter(); + + static string GetTicks() => (DateTime.Now.Ticks & 0x11111).ToString("00000"); + + app.MapGet("/", () => Results.Ok($"Hello {GetTicks()}")) + .RequireRateLimiting("fixed"); + + _ = app.RunAsync(); + + var url = app.Urls.ToArray()[0]; + var portNumber = url.Substring(url.LastIndexOf(':') + 1); + + using var client = new HttpClient(); + var res = await client.GetAsync(new Uri($"http://localhost:{portNumber}/")); + Assert.NotNull(res); + + // We need to let metric callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the callbacks to complete + await Task.Delay(TimeSpan.FromSeconds(1)); + + this.meterProvider.Dispose(); + + var activeRequestLeasesMetric = exportedItems + .Where(item => item.Name == "aspnetcore.rate_limiting.active_request_leases") + .ToArray(); + + var requestLeaseDurationMetric = exportedItems. + Where(item => item.Name == "aspnetcore.rate_limiting.request_lease.duration") + .ToArray(); + + var limitingRequestsMetric = exportedItems. + Where(item => item.Name == "aspnetcore.rate_limiting.requests") + .ToArray(); + + Assert.Single(activeRequestLeasesMetric); + Assert.Single(requestLeaseDurationMetric); + Assert.Single(limitingRequestsMetric); + + // TODO + // aspnetcore.rate_limiting.request.time_in_queue + // aspnetcore.rate_limiting.queued_requests + + await app.DisposeAsync(); + } +#endif + + [Theory] + [InlineData("/api/values/2", "api/Values/{id}", null, 200)] + [InlineData("/api/Error", "api/Error", "System.Exception", 500)] + public async Task RequestMetricIsCaptured(string api, string expectedRoute, string expectedErrorType, int expectedStatusCode) + { + var metricItems = new List(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(metricItems) + .Build(); + + using (var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient()) + { + try + { + using var response = await client.GetAsync(new Uri(api, UriKind.Relative)); + response.EnsureSuccessStatusCode(); + } + catch + { + // ignore error. + } + } + + // We need to let End callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the End callback to complete + await Task.Delay(TimeSpan.FromSeconds(1)); + + this.meterProvider.Dispose(); + + var requestMetrics = metricItems + .Where(item => item.Name == "http.server.request.duration") + .ToArray(); + + var metric = Assert.Single(requestMetrics); + + Assert.Equal("s", metric.Unit); + var metricPoints = GetMetricPoints(metric); + Assert.Single(metricPoints); + + AssertMetricPoints( + metricPoints: metricPoints, + expectedRoutes: new List { expectedRoute }, + expectedErrorType, + expectedStatusCode, + expectedTagsCount: expectedErrorType == null ? 5 : 6); + } + + [Theory] + [InlineData("CONNECT", "CONNECT")] + [InlineData("DELETE", "DELETE")] + [InlineData("GET", "GET")] + [InlineData("PUT", "PUT")] + [InlineData("HEAD", "HEAD")] + [InlineData("OPTIONS", "OPTIONS")] + [InlineData("PATCH", "PATCH")] + [InlineData("Get", "GET")] + [InlineData("POST", "POST")] + [InlineData("TRACE", "TRACE")] + [InlineData("CUSTOM", "_OTHER")] + public async Task HttpRequestMethodIsCapturedAsPerSpec(string originalMethod, string expectedMethod) + { + var metricItems = new List(); + + this.meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(metricItems) + .Build(); + + using var client = this.factory + .WithWebHostBuilder(builder => + { + builder.ConfigureLogging(loggingBuilder => loggingBuilder.ClearProviders()); + }) + .CreateClient(); + + var message = new HttpRequestMessage(); + message.Method = new HttpMethod(originalMethod); + + try + { + using var response = await client.SendAsync(message); + } + catch + { + // ignore error. + } + + // We need to let End callback execute as it is executed AFTER response was returned. + // In unit tests environment there may be a lot of parallel unit tests executed, so + // giving some breezing room for the End callback to complete + await Task.Delay(TimeSpan.FromSeconds(1)); + + this.meterProvider.Dispose(); + + var requestMetrics = metricItems + .Where(item => item.Name == "http.server.request.duration") + .ToArray(); + + var metric = Assert.Single(requestMetrics); + + Assert.Equal("s", metric.Unit); + var metricPoints = GetMetricPoints(metric); + Assert.Single(metricPoints); + + var mp = metricPoints[0]; + + // Inspect Metric Attributes + var attributes = new Dictionary(); + foreach (var tag in mp.Tags) + { + attributes[tag.Key] = tag.Value; + } + + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == expectedMethod); + + Assert.DoesNotContain(attributes, t => t.Key == SemanticConventions.AttributeHttpRequestMethodOriginal); + } + + public void Dispose() + { + this.meterProvider?.Dispose(); + GC.SuppressFinalize(this); + } + + private static List GetMetricPoints(Metric metric) + { + Assert.NotNull(metric); + Assert.True(metric.MetricType == MetricType.Histogram); + var metricPoints = new List(); + foreach (var p in metric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + return metricPoints; + } + + private static void AssertMetricPoints( + List metricPoints, + List expectedRoutes, + string expectedErrorType, + int expectedStatusCode, + int expectedTagsCount) + { + // Assert that one MetricPoint exists for each ExpectedRoute + foreach (var expectedRoute in expectedRoutes) + { + MetricPoint? metricPoint = null; + + foreach (var mp in metricPoints) + { + foreach (var tag in mp.Tags) + { + if (tag.Key == SemanticConventions.AttributeHttpRoute && tag.Value.ToString() == expectedRoute) + { + metricPoint = mp; + } + } + } + + if (metricPoint.HasValue) + { + AssertMetricPoint(metricPoint.Value, expectedStatusCode, expectedRoute, expectedErrorType, expectedTagsCount); + } + else + { + Assert.Fail($"A metric for route '{expectedRoute}' was not found"); + } + } + } + + private static void AssertMetricPoint( + MetricPoint metricPoint, + int expectedStatusCode, + string expectedRoute, + string expectedErrorType, + int expectedTagsCount) + { + var count = metricPoint.GetHistogramCount(); + var sum = metricPoint.GetHistogramSum(); + + Assert.Equal(1L, count); + Assert.True(sum > 0); + + var attributes = new KeyValuePair[metricPoint.Tags.Count]; + int i = 0; + foreach (var tag in metricPoint.Tags) + { + attributes[i++] = tag; + } + + // Inspect Attributes + Assert.Equal(expectedTagsCount, attributes.Length); + + var method = new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, "GET"); + var scheme = new KeyValuePair(SemanticConventions.AttributeUrlScheme, "http"); + var statusCode = new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, expectedStatusCode); + var flavor = new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, "1.1"); + var route = new KeyValuePair(SemanticConventions.AttributeHttpRoute, expectedRoute); + Assert.Contains(method, attributes); + Assert.Contains(scheme, attributes); + Assert.Contains(statusCode, attributes); + Assert.Contains(flavor, attributes); + Assert.Contains(route, attributes); + + if (expectedErrorType != null) + { + var errorType = new KeyValuePair(SemanticConventions.AttributeErrorType, expectedErrorType); + + Assert.Contains(errorType, attributes); + } + + // Inspect Histogram Bounds + var histogramBuckets = metricPoint.GetHistogramBuckets(); + var histogramBounds = new List(); + foreach (var t in histogramBuckets) + { + histogramBounds.Add(t.ExplicitBound); + } + + // TODO: Remove the check for the older bounds once 1.7.0 is released. This is a temporary fix for instrumentation libraries CI workflow. + + var expectedHistogramBoundsOld = new List { 0, 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, double.PositiveInfinity }; + var expectedHistogramBoundsNew = new List { 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, double.PositiveInfinity }; + + var histogramBoundsMatchCorrectly = Enumerable.SequenceEqual(expectedHistogramBoundsOld, histogramBounds) || + Enumerable.SequenceEqual(expectedHistogramBoundsNew, histogramBounds); + + Assert.True(histogramBoundsMatchCorrectly); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj new file mode 100644 index 0000000000..4371b4f6ab --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -0,0 +1,48 @@ + + + Unit test project for OpenTelemetry ASP.NET Core instrumentation + net8.0;net7.0;net6.0 + enable + + disable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RoutingTestCases.json + Always + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md new file mode 100644 index 0000000000..38ae9f93fd --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md @@ -0,0 +1,204 @@ +# ASP.NET Core `http.route` tests + +This folder contains a test suite that validates the instrumentation produces +the expected `http.route` attribute on both the activity and metric it emits. +When available, the `http.route` is also a required component of the +`Activity.DisplayName`. + +The test suite covers a variety of different routing scenarios available for +ASP.NET Core: + +* [Conventional routing](https://learn.microsoft.com/aspnet/core/mvc/controllers/routing#conventional-routing) +* [Conventional routing using areas](https://learn.microsoft.com/aspnet/core/mvc/controllers/routing#areas) +* [Attribute routing](https://learn.microsoft.com/aspnet/core/mvc/controllers/routing#attribute-routing-for-rest-apis) +* [Razor pages](https://learn.microsoft.com/aspnet/core/razor-pages/razor-pages-conventions) +* [Minimal APIs](https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis/route-handlers) + +The individual test cases are defined in RoutingTestCases.json. + +The test suite is unique in that, when run, it generates README files for each +target framework which aids in documenting how the instrumentation behaves for +each test case. These files are source-controlled, so if the behavior of the +instrumentation changes, the README files will be updated to reflect the change. + +* [.NET 6](./README.net6.0.md) +* [.NET 7](./README.net7.0.md) +* [.NET 8](./README.net8.0.md) + +For each test case a request is made to an ASP.NET Core application with a +particular routing configuration. ASP.NET Core offers a +[variety of APIs](#aspnet-core-apis-for-retrieving-route-information) for +retrieving the route information of a given request. The README files include +detailed information documenting the route information available using the +various APIs in each test case. For example, here is the detailed result +generated for a test case: + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "/ConventionalRoute/ActionWithStringParameter/2", + "ActivityHttpRoute": "", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +> [!NOTE] +> The test result currently includes an `IdealHttpRoute` property. This is +> temporary, and is meant to drive a conversation to determine the best way +> for generating the `http.route` attribute under different routing scenarios. +> In the example above, the path invoked is +> `/ConventionalRoute/ActionWithStringParameter/2?num=3`. Currently, we see +> that the `http.route` attribute on the metric emitted is +> `{controller=ConventionalRoute}/{action=Default}/{id?}` which was derived +> using `RoutePattern.RawText`. This is not ideal +> because the route template does not include the actual action that was +> invoked `ActionWithStringParameter`. The invoked action could be derived +> using either the `ControllerActionDescriptor` +> or `HttpContext.GetRouteData()`. + +## ASP.NET Core APIs for retrieving route information + +Included below are short snippets illustrating the use of the various +APIs available for retrieving route information. + +### Retrieving the route template + +The route template can be obtained from `HttpContext` by retrieving the +`RouteEndpoint` using the following two APIs. + +For attribute routing and minimal API scenarios, using the route template alone +is sufficient for deriving `http.route` in all test cases. + +The route template does not well describe the `http.route` in conventional +routing and some Razor page scenarios. + +#### [RoutePattern.RawText](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.routing.patterns.routepattern.rawtext) + +```csharp +(httpContext.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; +``` + +#### [IRouteDiagnosticsMetadata.Route](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.http.metadata.iroutediagnosticsmetadata.route) + +This API was introduced in .NET 8. + +```csharp +httpContext.GetEndpoint()?.Metadata.GetMetadata()?.Route; +``` + +### RouteData + +`RouteData` can be retrieved from `HttpContext` using the `GetRouteData()` +extension method. The values obtained from `RouteData` identify the controller/ +action or Razor page invoked by the request. + +#### [HttpContext.GetRouteData()](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.routing.routinghttpcontextextensions.getroutedata) + +```csharp +foreach (var value in httpContext.GetRouteData().Values) +{ + Console.WriteLine($"{value.Key} = {value.Value?.ToString()}"); +} +``` + +For example, the above code produces something like: + +```text +controller = ConventionalRoute +action = ActionWithStringParameter +id = 2 +``` + +### Information from the ActionDescriptor + +For requests that invoke an action or Razor page, the `ActionDescriptor` can +be used to access route information. + +#### [AttributeRouteInfo.Template](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.routing.attributerouteinfo.template) + +The `AttributeRouteInfo.Template` is equivalent to using +[other APIs for retrieving the route template](#retrieving-the-route-template) +when using attribute routing. For conventional routing and Razor pages it will +be `null`. + +```csharp +actionDescriptor.AttributeRouteInfo?.Template; +``` + +#### [ControllerActionDescriptor](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.controllers.controlleractiondescriptor) + +For requests that invoke an action on a controller, the `ActionDescriptor` +will be of type `ControllerActionDescriptor` which includes the controller and +action name. + +```csharp +(actionDescriptor as ControllerActionDescriptor)?.ControllerName; +(actionDescriptor as ControllerActionDescriptor)?.ActionName; +``` + +#### [PageActionDescriptor](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.razorpages.pageactiondescriptor) + +For requests that invoke a Razor page, the `ActionDescriptor` +will be of type `PageActionDescriptor` which includes the path to the invoked +page. + +```csharp +(actionDescriptor as PageActionDescriptor)?.RelativePath; +(actionDescriptor as PageActionDescriptor)?.ViewEnginePath; +``` + +#### [Parameters](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.mvc.abstractions.actiondescriptor.parameters#microsoft-aspnetcore-mvc-abstractions-actiondescriptor-parameters) + +The `ActionDescriptor.Parameters` property is interesting because it describes +the actual parameters (type and name) of an invoked action method. Some APM +products use `ActionDescriptor.Parameters` to more precisely describe the +method an endpoint invokes since not all parameters may be present in the +route template. + +Consider the following action method: + +```csharp +public IActionResult SomeActionMethod(string id, int num) { ... } +``` + +Using conventional routing assuming a default route template +`{controller=ConventionalRoute}/{action=Default}/{id?}`, the `SomeActionMethod` +may match this route template. The route template describes the `id` parameter +but not the `num` parameter. + +```csharp +foreach (var parameter in actionDescriptor.Parameters) +{ + Console.WriteLine($"{parameter.Name}"); +} +``` + +The above code produces: + +```text +id +num +``` diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net6.0.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net6.0.md new file mode 100644 index 0000000000..6582c75715 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net6.0.md @@ -0,0 +1,612 @@ +# Test results for ASP.NET Core 6 + +| http.route | App | Test Name | +| - | - | - | +| :broken_heart: | ConventionalRouting | [Root path](#conventionalrouting-root-path) | +| :broken_heart: | ConventionalRouting | [Non-default action with route parameter and query string](#conventionalrouting-non-default-action-with-route-parameter-and-query-string) | +| :broken_heart: | ConventionalRouting | [Non-default action with query string](#conventionalrouting-non-default-action-with-query-string) | +| :green_heart: | ConventionalRouting | [Not Found (404)](#conventionalrouting-not-found-404) | +| :green_heart: | ConventionalRouting | [Route template with parameter constraint](#conventionalrouting-route-template-with-parameter-constraint) | +| :green_heart: | ConventionalRouting | [Path that does not match parameter constraint](#conventionalrouting-path-that-does-not-match-parameter-constraint) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, default controller/action](#conventionalrouting-area-using-areaexists-default-controlleraction) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, non-default action](#conventionalrouting-area-using-areaexists-non-default-action) | +| :broken_heart: | ConventionalRouting | [Area w/o `area:exists`, default controller/action](#conventionalrouting-area-wo-areaexists-default-controlleraction) | +| :green_heart: | AttributeRouting | [Default action](#attributerouting-default-action) | +| :green_heart: | AttributeRouting | [Action without parameter](#attributerouting-action-without-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter](#attributerouting-action-with-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter before action name in template](#attributerouting-action-with-parameter-before-action-name-in-template) | +| :green_heart: | AttributeRouting | [Action invoked resulting in 400 Bad Request](#attributerouting-action-invoked-resulting-in-400-bad-request) | +| :broken_heart: | RazorPages | [Root path](#razorpages-root-path) | +| :broken_heart: | RazorPages | [Index page](#razorpages-index-page) | +| :broken_heart: | RazorPages | [Throws exception](#razorpages-throws-exception) | +| :green_heart: | RazorPages | [Static content](#razorpages-static-content) | +| :green_heart: | MinimalApi | [Action without parameter](#minimalapi-action-without-parameter) | +| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) | +| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) | + +## ConventionalRouting: Root path + +```json +{ + "IdealHttpRoute": "ConventionalRoute/Default/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "Default" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with route parameter and query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Not Found (404) + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/NotFound", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Route template with parameter constraint + +```json +{ + "IdealHttpRoute": "SomePath/{id}/{num:int}", + "ActivityDisplayName": "GET SomePath/{id}/{num:int}", + "ActivityHttpRoute": "SomePath/{id}/{num:int}", + "MetricHttpRoute": "SomePath/{id}/{num:int}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/2", + "RoutePattern.RawText": "SomePath/{id}/{num:int}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "SomeString", + "num": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Path that does not match parameter constraint + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/NotAnInt", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Area using `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/Default/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "action": "Default", + "area": "MyArea" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area using `area:exists`, non-default action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/NonDefault/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea/ControllerForMyArea/NonDefault", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "area": "MyArea", + "action": "NonDefault" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "NonDefault" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area w/o `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "SomePrefix/AnotherArea/Index/{id?}", + "ActivityDisplayName": "GET SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "ActivityHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "MetricHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePrefix", + "RoutePattern.RawText": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "area": "AnotherArea", + "controller": "AnotherArea", + "action": "Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AnotherArea", + "ActionName": "Index" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Default action + +```json +{ + "IdealHttpRoute": "AttributeRoute", + "ActivityDisplayName": "GET AttributeRoute", + "ActivityHttpRoute": "AttributeRoute", + "MetricHttpRoute": "AttributeRoute", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute", + "RoutePattern.RawText": "AttributeRoute", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action without parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get", + "ActivityDisplayName": "GET AttributeRoute/Get", + "ActivityHttpRoute": "AttributeRoute/Get", + "MetricHttpRoute": "AttributeRoute/Get", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get", + "RoutePattern.RawText": "AttributeRoute/Get", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get/{id}", + "ActivityDisplayName": "GET AttributeRoute/Get/{id}", + "ActivityHttpRoute": "AttributeRoute/Get/{id}", + "MetricHttpRoute": "AttributeRoute/Get/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get/12", + "RoutePattern.RawText": "AttributeRoute/Get/{id}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get/{id}", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter before action name in template + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/12/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action invoked resulting in 400 Bad Request + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/NotAnInt/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "NotAnInt" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## RazorPages: Root path + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Index page + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET Index", + "ActivityHttpRoute": "Index", + "MetricHttpRoute": "Index", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Index", + "RoutePattern.RawText": "Index", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "Index", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Throws exception + +```json +{ + "IdealHttpRoute": "/PageThatThrowsException", + "ActivityDisplayName": "GET PageThatThrowsException", + "ActivityHttpRoute": "PageThatThrowsException", + "MetricHttpRoute": "PageThatThrowsException", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/PageThatThrowsException", + "RoutePattern.RawText": "PageThatThrowsException", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "page": "/PageThatThrowsException" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "PageThatThrowsException", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/PageThatThrowsException.cshtml", + "ViewEnginePath": "/PageThatThrowsException" + } + } + } +} +``` + +## RazorPages: Static content + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/js/site.js", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi", + "ActivityDisplayName": "GET /MinimalApi", + "ActivityHttpRoute": "/MinimalApi", + "MetricHttpRoute": "/MinimalApi", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi", + "RoutePattern.RawText": "/MinimalApi", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi/{id}", + "ActivityDisplayName": "GET /MinimalApi/{id}", + "ActivityHttpRoute": "/MinimalApi/{id}", + "MetricHttpRoute": "/MinimalApi/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi/123", + "RoutePattern.RawText": "/MinimalApi/{id}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## ExceptionMiddleware: Exception Handled by Exception Handler Middleware + +```json +{ + "IdealHttpRoute": "/Exception", + "ActivityDisplayName": "GET /Exception", + "ActivityHttpRoute": "/Exception", + "MetricHttpRoute": "/Exception", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Exception", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md new file mode 100644 index 0000000000..49d8224155 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md @@ -0,0 +1,654 @@ +# Test results for ASP.NET Core 7 + +| http.route | App | Test Name | +| - | - | - | +| :broken_heart: | ConventionalRouting | [Root path](#conventionalrouting-root-path) | +| :broken_heart: | ConventionalRouting | [Non-default action with route parameter and query string](#conventionalrouting-non-default-action-with-route-parameter-and-query-string) | +| :broken_heart: | ConventionalRouting | [Non-default action with query string](#conventionalrouting-non-default-action-with-query-string) | +| :green_heart: | ConventionalRouting | [Not Found (404)](#conventionalrouting-not-found-404) | +| :green_heart: | ConventionalRouting | [Route template with parameter constraint](#conventionalrouting-route-template-with-parameter-constraint) | +| :green_heart: | ConventionalRouting | [Path that does not match parameter constraint](#conventionalrouting-path-that-does-not-match-parameter-constraint) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, default controller/action](#conventionalrouting-area-using-areaexists-default-controlleraction) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, non-default action](#conventionalrouting-area-using-areaexists-non-default-action) | +| :broken_heart: | ConventionalRouting | [Area w/o `area:exists`, default controller/action](#conventionalrouting-area-wo-areaexists-default-controlleraction) | +| :green_heart: | AttributeRouting | [Default action](#attributerouting-default-action) | +| :green_heart: | AttributeRouting | [Action without parameter](#attributerouting-action-without-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter](#attributerouting-action-with-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter before action name in template](#attributerouting-action-with-parameter-before-action-name-in-template) | +| :green_heart: | AttributeRouting | [Action invoked resulting in 400 Bad Request](#attributerouting-action-invoked-resulting-in-400-bad-request) | +| :broken_heart: | RazorPages | [Root path](#razorpages-root-path) | +| :broken_heart: | RazorPages | [Index page](#razorpages-index-page) | +| :broken_heart: | RazorPages | [Throws exception](#razorpages-throws-exception) | +| :green_heart: | RazorPages | [Static content](#razorpages-static-content) | +| :green_heart: | MinimalApi | [Action without parameter](#minimalapi-action-without-parameter) | +| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) | +| :green_heart: | MinimalApi | [Action without parameter (MapGroup)](#minimalapi-action-without-parameter-mapgroup) | +| :green_heart: | MinimalApi | [Action with parameter (MapGroup)](#minimalapi-action-with-parameter-mapgroup) | +| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) | + +## ConventionalRouting: Root path + +```json +{ + "IdealHttpRoute": "ConventionalRoute/Default/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "Default" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with route parameter and query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Not Found (404) + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/NotFound", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Route template with parameter constraint + +```json +{ + "IdealHttpRoute": "SomePath/{id}/{num:int}", + "ActivityDisplayName": "GET SomePath/{id}/{num:int}", + "ActivityHttpRoute": "SomePath/{id}/{num:int}", + "MetricHttpRoute": "SomePath/{id}/{num:int}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/2", + "RoutePattern.RawText": "SomePath/{id}/{num:int}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "SomeString", + "num": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Path that does not match parameter constraint + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/NotAnInt", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Area using `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/Default/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "action": "Default", + "area": "MyArea" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area using `area:exists`, non-default action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/NonDefault/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea/ControllerForMyArea/NonDefault", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "area": "MyArea", + "action": "NonDefault" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "NonDefault" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area w/o `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "SomePrefix/AnotherArea/Index/{id?}", + "ActivityDisplayName": "GET SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "ActivityHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "MetricHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePrefix", + "RoutePattern.RawText": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "area": "AnotherArea", + "controller": "AnotherArea", + "action": "Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AnotherArea", + "ActionName": "Index" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Default action + +```json +{ + "IdealHttpRoute": "AttributeRoute", + "ActivityDisplayName": "GET AttributeRoute", + "ActivityHttpRoute": "AttributeRoute", + "MetricHttpRoute": "AttributeRoute", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute", + "RoutePattern.RawText": "AttributeRoute", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action without parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get", + "ActivityDisplayName": "GET AttributeRoute/Get", + "ActivityHttpRoute": "AttributeRoute/Get", + "MetricHttpRoute": "AttributeRoute/Get", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get", + "RoutePattern.RawText": "AttributeRoute/Get", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get/{id}", + "ActivityDisplayName": "GET AttributeRoute/Get/{id}", + "ActivityHttpRoute": "AttributeRoute/Get/{id}", + "MetricHttpRoute": "AttributeRoute/Get/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get/12", + "RoutePattern.RawText": "AttributeRoute/Get/{id}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get/{id}", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter before action name in template + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/12/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action invoked resulting in 400 Bad Request + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/NotAnInt/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "NotAnInt" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## RazorPages: Root path + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Index page + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET Index", + "ActivityHttpRoute": "Index", + "MetricHttpRoute": "Index", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Index", + "RoutePattern.RawText": "Index", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "Index", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Throws exception + +```json +{ + "IdealHttpRoute": "/PageThatThrowsException", + "ActivityDisplayName": "GET PageThatThrowsException", + "ActivityHttpRoute": "PageThatThrowsException", + "MetricHttpRoute": "PageThatThrowsException", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/PageThatThrowsException", + "RoutePattern.RawText": "PageThatThrowsException", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "page": "/PageThatThrowsException" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "PageThatThrowsException", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/PageThatThrowsException.cshtml", + "ViewEnginePath": "/PageThatThrowsException" + } + } + } +} +``` + +## RazorPages: Static content + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/js/site.js", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi", + "ActivityDisplayName": "GET /MinimalApi", + "ActivityHttpRoute": "/MinimalApi", + "MetricHttpRoute": "/MinimalApi", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi", + "RoutePattern.RawText": "/MinimalApi", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi/{id}", + "ActivityDisplayName": "GET /MinimalApi/{id}", + "ActivityHttpRoute": "/MinimalApi/{id}", + "MetricHttpRoute": "/MinimalApi/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi/123", + "RoutePattern.RawText": "/MinimalApi/{id}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter (MapGroup) + +```json +{ + "IdealHttpRoute": "/MinimalApiUsingMapGroup/", + "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/", + "ActivityHttpRoute": "/MinimalApiUsingMapGroup/", + "MetricHttpRoute": "/MinimalApiUsingMapGroup/", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApiUsingMapGroup", + "RoutePattern.RawText": "/MinimalApiUsingMapGroup/", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter (MapGroup) + +```json +{ + "IdealHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/{id}", + "ActivityHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "MetricHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApiUsingMapGroup/123", + "RoutePattern.RawText": "/MinimalApiUsingMapGroup/{id}", + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## ExceptionMiddleware: Exception Handled by Exception Handler Middleware + +```json +{ + "IdealHttpRoute": "/Exception", + "ActivityDisplayName": "GET /Exception", + "ActivityHttpRoute": "/Exception", + "MetricHttpRoute": "/Exception", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Exception", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net8.0.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net8.0.md new file mode 100644 index 0000000000..40b63a1ca4 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net8.0.md @@ -0,0 +1,654 @@ +# Test results for ASP.NET Core 8 + +| http.route | App | Test Name | +| - | - | - | +| :broken_heart: | ConventionalRouting | [Root path](#conventionalrouting-root-path) | +| :broken_heart: | ConventionalRouting | [Non-default action with route parameter and query string](#conventionalrouting-non-default-action-with-route-parameter-and-query-string) | +| :broken_heart: | ConventionalRouting | [Non-default action with query string](#conventionalrouting-non-default-action-with-query-string) | +| :green_heart: | ConventionalRouting | [Not Found (404)](#conventionalrouting-not-found-404) | +| :green_heart: | ConventionalRouting | [Route template with parameter constraint](#conventionalrouting-route-template-with-parameter-constraint) | +| :green_heart: | ConventionalRouting | [Path that does not match parameter constraint](#conventionalrouting-path-that-does-not-match-parameter-constraint) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, default controller/action](#conventionalrouting-area-using-areaexists-default-controlleraction) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, non-default action](#conventionalrouting-area-using-areaexists-non-default-action) | +| :broken_heart: | ConventionalRouting | [Area w/o `area:exists`, default controller/action](#conventionalrouting-area-wo-areaexists-default-controlleraction) | +| :green_heart: | AttributeRouting | [Default action](#attributerouting-default-action) | +| :green_heart: | AttributeRouting | [Action without parameter](#attributerouting-action-without-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter](#attributerouting-action-with-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter before action name in template](#attributerouting-action-with-parameter-before-action-name-in-template) | +| :green_heart: | AttributeRouting | [Action invoked resulting in 400 Bad Request](#attributerouting-action-invoked-resulting-in-400-bad-request) | +| :broken_heart: | RazorPages | [Root path](#razorpages-root-path) | +| :broken_heart: | RazorPages | [Index page](#razorpages-index-page) | +| :broken_heart: | RazorPages | [Throws exception](#razorpages-throws-exception) | +| :green_heart: | RazorPages | [Static content](#razorpages-static-content) | +| :green_heart: | MinimalApi | [Action without parameter](#minimalapi-action-without-parameter) | +| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) | +| :green_heart: | MinimalApi | [Action without parameter (MapGroup)](#minimalapi-action-without-parameter-mapgroup) | +| :green_heart: | MinimalApi | [Action with parameter (MapGroup)](#minimalapi-action-with-parameter-mapgroup) | +| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) | + +## ConventionalRouting: Root path + +```json +{ + "IdealHttpRoute": "ConventionalRoute/Default/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "Default" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with route parameter and query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Not Found (404) + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/NotFound", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Route template with parameter constraint + +```json +{ + "IdealHttpRoute": "SomePath/{id}/{num:int}", + "ActivityDisplayName": "GET SomePath/{id}/{num:int}", + "ActivityHttpRoute": "SomePath/{id}/{num:int}", + "MetricHttpRoute": "SomePath/{id}/{num:int}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/2", + "RoutePattern.RawText": "SomePath/{id}/{num:int}", + "IRouteDiagnosticsMetadata.Route": "SomePath/{id}/{num:int}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "SomeString", + "num": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Path that does not match parameter constraint + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/NotAnInt", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Area using `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/Default/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "action": "Default", + "area": "MyArea" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area using `area:exists`, non-default action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/NonDefault/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea/ControllerForMyArea/NonDefault", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "area": "MyArea", + "action": "NonDefault" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "NonDefault" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area w/o `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "SomePrefix/AnotherArea/Index/{id?}", + "ActivityDisplayName": "GET SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "ActivityHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "MetricHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePrefix", + "RoutePattern.RawText": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "IRouteDiagnosticsMetadata.Route": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "HttpContext.GetRouteData()": { + "area": "AnotherArea", + "controller": "AnotherArea", + "action": "Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AnotherArea", + "ActionName": "Index" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Default action + +```json +{ + "IdealHttpRoute": "AttributeRoute", + "ActivityDisplayName": "GET AttributeRoute", + "ActivityHttpRoute": "AttributeRoute", + "MetricHttpRoute": "AttributeRoute", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute", + "RoutePattern.RawText": "AttributeRoute", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute", + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action without parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get", + "ActivityDisplayName": "GET AttributeRoute/Get", + "ActivityHttpRoute": "AttributeRoute/Get", + "MetricHttpRoute": "AttributeRoute/Get", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get", + "RoutePattern.RawText": "AttributeRoute/Get", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/Get", + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get/{id}", + "ActivityDisplayName": "GET AttributeRoute/Get/{id}", + "ActivityHttpRoute": "AttributeRoute/Get/{id}", + "MetricHttpRoute": "AttributeRoute/Get/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get/12", + "RoutePattern.RawText": "AttributeRoute/Get/{id}", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/Get/{id}", + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get/{id}", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter before action name in template + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/12/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action invoked resulting in 400 Bad Request + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/NotAnInt/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "NotAnInt" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## RazorPages: Root path + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "", + "IRouteDiagnosticsMetadata.Route": "", + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Index page + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET Index", + "ActivityHttpRoute": "Index", + "MetricHttpRoute": "Index", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Index", + "RoutePattern.RawText": "Index", + "IRouteDiagnosticsMetadata.Route": "Index", + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "Index", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Throws exception + +```json +{ + "IdealHttpRoute": "/PageThatThrowsException", + "ActivityDisplayName": "GET PageThatThrowsException", + "ActivityHttpRoute": "PageThatThrowsException", + "MetricHttpRoute": "PageThatThrowsException", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/PageThatThrowsException", + "RoutePattern.RawText": "PageThatThrowsException", + "IRouteDiagnosticsMetadata.Route": "PageThatThrowsException", + "HttpContext.GetRouteData()": { + "page": "/PageThatThrowsException" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "PageThatThrowsException", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/PageThatThrowsException.cshtml", + "ViewEnginePath": "/PageThatThrowsException" + } + } + } +} +``` + +## RazorPages: Static content + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/js/site.js", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi", + "ActivityDisplayName": "GET /MinimalApi", + "ActivityHttpRoute": "/MinimalApi", + "MetricHttpRoute": "/MinimalApi", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi", + "RoutePattern.RawText": "/MinimalApi", + "IRouteDiagnosticsMetadata.Route": "/MinimalApi", + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi/{id}", + "ActivityDisplayName": "GET /MinimalApi/{id}", + "ActivityHttpRoute": "/MinimalApi/{id}", + "MetricHttpRoute": "/MinimalApi/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi/123", + "RoutePattern.RawText": "/MinimalApi/{id}", + "IRouteDiagnosticsMetadata.Route": "/MinimalApi/{id}", + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter (MapGroup) + +```json +{ + "IdealHttpRoute": "/MinimalApiUsingMapGroup/", + "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/", + "ActivityHttpRoute": "/MinimalApiUsingMapGroup/", + "MetricHttpRoute": "/MinimalApiUsingMapGroup/", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApiUsingMapGroup", + "RoutePattern.RawText": "/MinimalApiUsingMapGroup/", + "IRouteDiagnosticsMetadata.Route": "/MinimalApiUsingMapGroup/", + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter (MapGroup) + +```json +{ + "IdealHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/{id}", + "ActivityHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "MetricHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApiUsingMapGroup/123", + "RoutePattern.RawText": "/MinimalApiUsingMapGroup/{id}", + "IRouteDiagnosticsMetadata.Route": "/MinimalApiUsingMapGroup/{id}", + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## ExceptionMiddleware: Exception Handled by Exception Handler Middleware + +```json +{ + "IdealHttpRoute": "/Exception", + "ActivityDisplayName": "GET /Exception", + "ActivityHttpRoute": "/Exception", + "MetricHttpRoute": "/Exception", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Exception", + "RoutePattern.RawText": "/Exception", + "IRouteDiagnosticsMetadata.Route": "/Exception", + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs new file mode 100644 index 0000000000..44d0e84e43 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs @@ -0,0 +1,45 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace RouteTests; + +public static class RoutingTestCases +{ + private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + Converters = { new JsonStringEnumConverter() }, + }; + + public static IEnumerable GetTestCases() + { + var assembly = Assembly.GetExecutingAssembly(); + var input = JsonSerializer.Deserialize( + assembly.GetManifestResourceStream("RoutingTestCases.json")!, + JsonSerializerOptions); + return GetArgumentsFromTestCaseObject(input!); + } + + private static List GetArgumentsFromTestCaseObject(IEnumerable input) + { + var result = new List(); + + foreach (var testCase in input) + { + if (testCase.MinimumDotnetVersion.HasValue && Environment.Version.Major < testCase.MinimumDotnetVersion.Value) + { + continue; + } + + result.Add(new object[] { testCase }); + } + + return result; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.json b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.json new file mode 100644 index 0000000000..2d1fa584ee --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.json @@ -0,0 +1,211 @@ +[ + { + "name": "Root path", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/", + "expectedStatusCode": 200, + "currentHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "expectedHttpRoute": "ConventionalRoute/Default/{id?}" + }, + { + "name": "Non-default action with route parameter and query string", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", + "expectedStatusCode": 200, + "currentHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "expectedHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}" + }, + { + "name": "Non-default action with query string", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/ConventionalRoute/ActionWithStringParameter?num=3", + "expectedStatusCode": 200, + "currentHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "expectedHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}" + }, + { + "name": "Not Found (404)", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/ConventionalRoute/NotFound", + "expectedStatusCode": 404, + "currentHttpRoute": null, + "expectedHttpRoute": "" + }, + { + "name": "Route template with parameter constraint", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/SomePath/SomeString/2", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "SomePath/{id}/{num:int}" + }, + { + "name": "Path that does not match parameter constraint", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/SomePath/SomeString/NotAnInt", + "expectedStatusCode": 404, + "currentHttpRoute": null, + "expectedHttpRoute": "" + }, + { + "name": "Area using `area:exists`, default controller/action", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/MyArea", + "expectedStatusCode": 200, + "currentHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "expectedHttpRoute": "{area:exists}/ControllerForMyArea/Default/{id?}" + }, + { + "name": "Area using `area:exists`, non-default action", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/MyArea/ControllerForMyArea/NonDefault", + "expectedStatusCode": 200, + "currentHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "expectedHttpRoute": "{area:exists}/ControllerForMyArea/NonDefault/{id?}" + }, + { + "name": "Area w/o `area:exists`, default controller/action", + "testApplicationScenario": "ConventionalRouting", + "httpMethod": "GET", + "path": "/SomePrefix", + "expectedStatusCode": 200, + "currentHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "expectedHttpRoute": "SomePrefix/AnotherArea/Index/{id?}" + }, + { + "name": "Default action", + "testApplicationScenario": "AttributeRouting", + "httpMethod": "GET", + "path": "/AttributeRoute", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "AttributeRoute" + }, + { + "name": "Action without parameter", + "testApplicationScenario": "AttributeRouting", + "httpMethod": "GET", + "path": "/AttributeRoute/Get", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "AttributeRoute/Get" + }, + { + "name": "Action with parameter", + "testApplicationScenario": "AttributeRouting", + "httpMethod": "GET", + "path": "/AttributeRoute/Get/12", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "AttributeRoute/Get/{id}" + }, + { + "name": "Action with parameter before action name in template", + "testApplicationScenario": "AttributeRouting", + "httpMethod": "GET", + "path": "/AttributeRoute/12/GetWithActionNameInDifferentSpotInTemplate", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate" + }, + { + "name": "Action invoked resulting in 400 Bad Request", + "testApplicationScenario": "AttributeRouting", + "httpMethod": "GET", + "path": "/AttributeRoute/NotAnInt/GetWithActionNameInDifferentSpotInTemplate", + "expectedStatusCode": 400, + "currentHttpRoute": null, + "expectedHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate" + }, + { + "name": "Root path", + "testApplicationScenario": "RazorPages", + "httpMethod": "GET", + "path": "/", + "expectedStatusCode": 200, + "currentHttpRoute": "", + "expectedHttpRoute": "/Index" + }, + { + "name": "Index page", + "testApplicationScenario": "RazorPages", + "httpMethod": "GET", + "path": "/Index", + "expectedStatusCode": 200, + "currentHttpRoute": "Index", + "expectedHttpRoute": "/Index" + }, + { + "name": "Throws exception", + "testApplicationScenario": "RazorPages", + "httpMethod": "GET", + "path": "/PageThatThrowsException", + "expectedStatusCode": 500, + "currentHttpRoute": "PageThatThrowsException", + "expectedHttpRoute": "/PageThatThrowsException" + }, + { + "name": "Static content", + "testApplicationScenario": "RazorPages", + "httpMethod": "GET", + "path": "/js/site.js", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "" + }, + { + "name": "Action without parameter", + "testApplicationScenario": "MinimalApi", + "httpMethod": "GET", + "path": "/MinimalApi", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "/MinimalApi" + }, + { + "name": "Action with parameter", + "testApplicationScenario": "MinimalApi", + "httpMethod": "GET", + "path": "/MinimalApi/123", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "/MinimalApi/{id}" + }, + { + "name": "Action without parameter (MapGroup)", + "minimumDotnetVersion": 7, + "testApplicationScenario": "MinimalApi", + "httpMethod": "GET", + "path": "/MinimalApiUsingMapGroup", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "/MinimalApiUsingMapGroup/" + }, + { + "name": "Action with parameter (MapGroup)", + "minimumDotnetVersion": 7, + "testApplicationScenario": "MinimalApi", + "httpMethod": "GET", + "path": "/MinimalApiUsingMapGroup/123", + "expectedStatusCode": 200, + "currentHttpRoute": null, + "expectedHttpRoute": "/MinimalApiUsingMapGroup/{id}" + }, + { + "name": "Exception Handled by Exception Handler Middleware", + "testApplicationScenario": "ExceptionMiddleware", + "httpMethod": "GET", + "path": "/Exception", + "expectedStatusCode": 500, + "currentHttpRoute": null, + "expectedHttpRoute": "/Exception" + } +] diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs new file mode 100644 index 0000000000..40d6d51209 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs @@ -0,0 +1,115 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Globalization; +using System.Text; +using Microsoft.AspNetCore.Builder; +using RouteTests.TestApplication; +using Xunit; + +namespace RouteTests; + +public class RoutingTestFixture : IAsyncLifetime +{ + private static readonly HttpClient HttpClient = new(); + private readonly Dictionary apps = new(); + private readonly RouteInfoDiagnosticObserver diagnostics = new(); + private readonly List testResults = new(); + + public RoutingTestFixture() + { + foreach (var scenario in Enum.GetValues()) + { + var app = TestApplicationFactory.CreateApplication(scenario); + if (app != null) + { + this.apps.Add(scenario, app); + } + } + + foreach (var app in this.apps) + { + app.Value.RunAsync(); + } + } + + public Task InitializeAsync() + { + return Task.CompletedTask; + } + + public async Task DisposeAsync() + { + foreach (var app in this.apps) + { + await app.Value.DisposeAsync(); + } + + HttpClient.Dispose(); + this.diagnostics.Dispose(); + + this.GenerateReadme(); + } + + public async Task MakeRequest(TestApplicationScenario scenario, string path) + { + var app = this.apps[scenario]; + var baseUrl = app.Urls.First(); + var url = $"{baseUrl}{path}"; + await HttpClient.GetAsync(new Uri(url)); + } + + public void AddTestResult(RoutingTestResult result) + { + this.testResults.Add(result); + } + + private void GenerateReadme() + { + var sb = new StringBuilder(); + sb.AppendLine($"# Test results for ASP.NET Core {Environment.Version.Major}"); + sb.AppendLine(); + sb.AppendLine("| http.route | App | Test Name |"); + sb.AppendLine("| - | - | - |"); + + for (var i = 0; i < this.testResults.Count; ++i) + { + var result = this.testResults[i]; + var emoji = result.TestCase.CurrentHttpRoute == null ? ":green_heart:" : ":broken_heart:"; + sb.AppendLine($"| {emoji} | {result.TestCase.TestApplicationScenario} | [{result.TestCase.Name}]({GenerateLinkFragment(result.TestCase.TestApplicationScenario, result.TestCase.Name)}) |"); + } + + for (var i = 0; i < this.testResults.Count; ++i) + { + var result = this.testResults[i]; + sb.AppendLine(); + sb.AppendLine($"## {result.TestCase.TestApplicationScenario}: {result.TestCase.Name}"); + sb.AppendLine(); + sb.AppendLine("```json"); + sb.AppendLine(result.ToString()); + sb.AppendLine("```"); + } + + var readmeFileName = $"README.net{Environment.Version.Major}.0.md"; + File.WriteAllText(Path.Combine("..", "..", "..", "RouteTests", readmeFileName), sb.ToString()); + + // Generates a link fragment that should comply with markdownlint rule MD051 + // https://github.com/DavidAnson/markdownlint/blob/main/doc/md051.md + static string GenerateLinkFragment(TestApplicationScenario scenario, string name) + { + var chars = name.ToCharArray() + .Where(c => (!char.IsPunctuation(c) && c != '`') || c == '-') + .Select(c => c switch + { + '-' => '-', + ' ' => '-', + _ => char.ToLower(c, CultureInfo.InvariantCulture), + }) + .ToArray(); + + return $"#{scenario.ToString().ToLower(CultureInfo.CurrentCulture)}-{new string(chars)}"; + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs new file mode 100644 index 0000000000..f1df77ba10 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs @@ -0,0 +1,33 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Text.Json; +using System.Text.Json.Serialization; +using RouteTests.TestApplication; + +namespace RouteTests; + +public class RoutingTestResult +{ + private static readonly JsonSerializerOptions JsonSerializerOptions = new() { WriteIndented = true }; + + public string? IdealHttpRoute { get; set; } + + public string ActivityDisplayName { get; set; } = string.Empty; + + public string? ActivityHttpRoute { get; set; } + + public string? MetricHttpRoute { get; set; } + + public RouteInfo RouteInfo { get; set; } = new RouteInfo(); + + [JsonIgnore] + public TestCase TestCase { get; set; } = new TestCase(); + + public override string ToString() + { + return JsonSerializer.Serialize(this, JsonSerializerOptions); + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs new file mode 100644 index 0000000000..e140a3bb60 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs @@ -0,0 +1,140 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Diagnostics; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using RouteTests.TestApplication; +using Xunit; + +namespace RouteTests; + +[Collection("AspNetCore")] +public class RoutingTests : IClassFixture +{ + private const string HttpStatusCode = "http.response.status_code"; + private const string HttpMethod = "http.request.method"; + private const string HttpRoute = "http.route"; + + private readonly RoutingTestFixture fixture; + private readonly List exportedActivities = new(); + private readonly List exportedMetrics = new(); + + public RoutingTests(RoutingTestFixture fixture) + { + this.fixture = fixture; + } + + public static IEnumerable TestData => RoutingTestCases.GetTestCases(); + + [Theory] + [MemberData(nameof(TestData))] + public async Task TestHttpRoute(TestCase testCase) + { + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(this.exportedActivities) + .Build()!; + + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAspNetCoreInstrumentation() + .AddInMemoryExporter(this.exportedMetrics) + .Build()!; + + await this.fixture.MakeRequest(testCase.TestApplicationScenario, testCase.Path); + + for (var i = 0; i < 10; i++) + { + if (this.exportedActivities.Count > 0) + { + break; + } + + await Task.Delay(TimeSpan.FromSeconds(1)); + } + + meterProvider.ForceFlush(); + + var durationMetric = this.exportedMetrics.Single(x => x.Name == "http.server.request.duration" || x.Name == "http.server.duration"); + var metricPoints = new List(); + foreach (var mp in durationMetric.GetMetricPoints()) + { + metricPoints.Add(mp); + } + + var activity = Assert.Single(this.exportedActivities); + var metricPoint = Assert.Single(metricPoints); + + GetTagsFromActivity(activity, out var activityHttpStatusCode, out var activityHttpMethod, out var activityHttpRoute); + GetTagsFromMetricPoint(Environment.Version.Major < 8, metricPoint, out var metricHttpStatusCode, out var metricHttpMethod, out var metricHttpRoute); + + Assert.Equal(testCase.ExpectedStatusCode, activityHttpStatusCode); + Assert.Equal(testCase.ExpectedStatusCode, metricHttpStatusCode); + Assert.Equal(testCase.HttpMethod, activityHttpMethod); + Assert.Equal(testCase.HttpMethod, metricHttpMethod); + + // TODO: The CurrentHttpRoute property will go away. It They only serve to capture status quo. + // If CurrentHttpRoute is null, then that means we already conform to the correct behavior. + var expectedHttpRoute = testCase.CurrentHttpRoute != null ? testCase.CurrentHttpRoute : testCase.ExpectedHttpRoute; + Assert.Equal(expectedHttpRoute, activityHttpRoute); + Assert.Equal(expectedHttpRoute, metricHttpRoute); + + // Activity.DisplayName should be a combination of http.method + http.route attributes, see: + // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#name + var expectedActivityDisplayName = string.IsNullOrEmpty(expectedHttpRoute) + ? testCase.HttpMethod + : $"{testCase.HttpMethod} {expectedHttpRoute}"; + + Assert.Equal(expectedActivityDisplayName, activity.DisplayName); + + var testResult = new RoutingTestResult + { + IdealHttpRoute = testCase.ExpectedHttpRoute, + ActivityDisplayName = activity.DisplayName, + ActivityHttpRoute = activityHttpRoute, + MetricHttpRoute = metricHttpRoute, + TestCase = testCase, + RouteInfo = RouteInfo.Current, + }; + + this.fixture.AddTestResult(testResult); + } + + private static void GetTagsFromActivity(Activity activity, out int httpStatusCode, out string httpMethod, out string? httpRoute) + { + var expectedStatusCodeKey = HttpStatusCode; + var expectedHttpMethodKey = HttpMethod; + httpStatusCode = Convert.ToInt32(activity.GetTagItem(expectedStatusCodeKey)); + httpMethod = (activity.GetTagItem(expectedHttpMethodKey) as string)!; + httpRoute = activity.GetTagItem(HttpRoute) as string ?? string.Empty; + } + + private static void GetTagsFromMetricPoint(bool useLegacyConventions, MetricPoint metricPoint, out int httpStatusCode, out string httpMethod, out string? httpRoute) + { + var expectedStatusCodeKey = HttpStatusCode; + var expectedHttpMethodKey = HttpMethod; + + httpStatusCode = 0; + httpMethod = string.Empty; + httpRoute = string.Empty; + + foreach (var tag in metricPoint.Tags) + { + if (tag.Key.Equals(expectedStatusCodeKey)) + { + httpStatusCode = Convert.ToInt32(tag.Value); + } + else if (tag.Key.Equals(expectedHttpMethodKey)) + { + httpMethod = (tag.Value as string)!; + } + else if (tag.Key.Equals(HttpRoute)) + { + httpRoute = tag.Value as string; + } + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs new file mode 100644 index 0000000000..20fc1f281b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs @@ -0,0 +1,52 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace RouteTests.TestApplication; + +public class ActionDescriptorInfo +{ + public ActionDescriptorInfo() + { + } + + public ActionDescriptorInfo(ActionDescriptor actionDescriptor) + { + this.AttributeRouteInfo = actionDescriptor.AttributeRouteInfo?.Template; + + this.ActionParameters = new List(); + foreach (var item in actionDescriptor.Parameters) + { + this.ActionParameters.Add(item.Name); + } + + if (actionDescriptor is PageActionDescriptor pad) + { + this.PageActionDescriptorSummary = new PageActionDescriptorInfo(pad.RelativePath, pad.ViewEnginePath); + } + + if (actionDescriptor is ControllerActionDescriptor cad) + { + this.ControllerActionDescriptorSummary = new ControllerActionDescriptorInfo(cad.ControllerName, cad.ActionName); + } + } + + [JsonPropertyName("AttributeRouteInfo.Template")] + public string? AttributeRouteInfo { get; set; } + + [JsonPropertyName("Parameters")] +#pragma warning disable CA2227 + public IList? ActionParameters { get; set; } +#pragma warning restore CA2227 + + [JsonPropertyName("ControllerActionDescriptor")] + public ControllerActionDescriptorInfo? ControllerActionDescriptorSummary { get; set; } + + [JsonPropertyName("PageActionDescriptor")] + public PageActionDescriptorInfo? PageActionDescriptorSummary { get; set; } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/AnotherArea/Controllers/AnotherAreaController.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/AnotherArea/Controllers/AnotherAreaController.cs new file mode 100644 index 0000000000..7754255edf --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/AnotherArea/Controllers/AnotherAreaController.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable disable + +using Microsoft.AspNetCore.Mvc; + +namespace RouteTests.Controllers; + +[Area("AnotherArea")] +public class AnotherAreaController : Controller +{ + public IActionResult Index() => this.Ok(); +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/MyArea/Controllers/ControllerForMyAreaController.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/MyArea/Controllers/ControllerForMyAreaController.cs new file mode 100644 index 0000000000..762f4a95e8 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Areas/MyArea/Controllers/ControllerForMyAreaController.cs @@ -0,0 +1,16 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable disable + +using Microsoft.AspNetCore.Mvc; + +namespace RouteTests.Controllers; + +[Area("MyArea")] +public class ControllerForMyAreaController : Controller +{ + public IActionResult Default() => this.Ok(); + + public IActionResult NonDefault() => this.Ok(); +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs new file mode 100644 index 0000000000..ae5ef6b907 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable +using System.Text.Json.Serialization; + +namespace RouteTests.TestApplication; + +public class ControllerActionDescriptorInfo +{ + public ControllerActionDescriptorInfo() + { + } + + public ControllerActionDescriptorInfo(string controllerName, string actionName) + { + this.ControllerActionDescriptorControllerName = controllerName; + this.ControllerActionDescriptorActionName = actionName; + } + + [JsonPropertyName("ControllerName")] + public string ControllerActionDescriptorControllerName { get; set; } = string.Empty; + + [JsonPropertyName("ActionName")] + public string ControllerActionDescriptorActionName { get; set; } = string.Empty; +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs new file mode 100644 index 0000000000..b1e5783b0a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable disable + +using Microsoft.AspNetCore.Mvc; + +namespace RouteTests.Controllers; + +[ApiController] +[Route("[controller]")] +public class AttributeRouteController : ControllerBase +{ + [HttpGet] + [HttpGet("[action]")] + public IActionResult Get() => this.Ok(); + + [HttpGet("[action]/{id}")] + public IActionResult Get(int id) => this.Ok(); + + [HttpGet("{id}/[action]")] + public IActionResult GetWithActionNameInDifferentSpotInTemplate(int id) => this.Ok(); +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs new file mode 100644 index 0000000000..977ee36a13 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable disable + +using Microsoft.AspNetCore.Mvc; + +namespace RouteTests.Controllers; + +public class ConventionalRouteController : Controller +{ + public IActionResult Default() => this.Ok(); + + public IActionResult ActionWithParameter(int id) => this.Ok(); + + public IActionResult ActionWithStringParameter(string id, int num) => this.Ok(); +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs new file mode 100644 index 0000000000..dda48ae462 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable +using System.Text.Json.Serialization; + +namespace RouteTests.TestApplication; + +public class PageActionDescriptorInfo +{ + public PageActionDescriptorInfo() + { + } + + public PageActionDescriptorInfo(string relativePath, string viewEnginePath) + { + this.PageActionDescriptorRelativePath = relativePath; + this.PageActionDescriptorViewEnginePath = viewEnginePath; + } + + [JsonPropertyName("RelativePath")] + public string PageActionDescriptorRelativePath { get; set; } = string.Empty; + + [JsonPropertyName("ViewEnginePath")] + public string PageActionDescriptorViewEnginePath { get; set; } = string.Empty; +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/Index.cshtml b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/Index.cshtml new file mode 100644 index 0000000000..51c350f956 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/Index.cshtml @@ -0,0 +1,2 @@ +@page +Hello, OpenTelemetry! diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/PageThatThrowsException.cshtml b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/PageThatThrowsException.cshtml new file mode 100644 index 0000000000..cf6ac0d5b8 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Pages/PageThatThrowsException.cshtml @@ -0,0 +1,4 @@ +@page +@{ + throw new Exception("Oops."); +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs new file mode 100644 index 0000000000..08433fc666 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Http; +#if NET8_0_OR_GREATER +using Microsoft.AspNetCore.Http.Metadata; +#endif +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Routing; + +namespace RouteTests.TestApplication; + +public class RouteInfo +{ + public static RouteInfo Current { get; set; } = new(); + + public string? HttpMethod { get; set; } + + public string? Path { get; set; } + + [JsonPropertyName("RoutePattern.RawText")] + public string? RawText { get; set; } + + [JsonPropertyName("IRouteDiagnosticsMetadata.Route")] + public string? RouteDiagnosticMetadata { get; set; } + + [JsonPropertyName("HttpContext.GetRouteData()")] +#pragma warning disable CA2227 + public IDictionary? RouteData { get; set; } +#pragma warning restore CA2227 + + public ActionDescriptorInfo? ActionDescriptor { get; set; } + + public void SetValues(HttpContext context) + { + this.HttpMethod = context.Request.Method; + this.Path = $"{context.Request.Path}{context.Request.QueryString}"; + var endpoint = context.GetEndpoint(); + this.RawText = (endpoint as RouteEndpoint)?.RoutePattern.RawText; +#if NET8_0_OR_GREATER + this.RouteDiagnosticMetadata = endpoint?.Metadata.GetMetadata()?.Route; +#endif + this.RouteData = new Dictionary(); + foreach (var value in context.GetRouteData().Values) + { + this.RouteData[value.Key] = value.Value?.ToString(); + } + } + + public void SetValues(ActionDescriptor actionDescriptor) + { + if (this.ActionDescriptor == null) + { + this.ActionDescriptor = new ActionDescriptorInfo(actionDescriptor); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs new file mode 100644 index 0000000000..3b3feb59e1 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs @@ -0,0 +1,110 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Diagnostics; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Diagnostics; + +namespace RouteTests.TestApplication; + +/// +/// This observer captures all the available route information for a request. +/// This route information is used for generating a README file for analyzing +/// what information is available in different scenarios. +/// +internal sealed class RouteInfoDiagnosticObserver : IDisposable, IObserver, IObserver> +{ + internal const string OnStartEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start"; + internal const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; + internal const string OnMvcBeforeActionEvent = "Microsoft.AspNetCore.Mvc.BeforeAction"; + + private readonly List listenerSubscriptions = new(); + private IDisposable? allSourcesSubscription; + private long disposed; + + public RouteInfoDiagnosticObserver() + { + this.allSourcesSubscription = DiagnosticListener.AllListeners.Subscribe(this); + } + + public void OnNext(DiagnosticListener value) + { + if (value.Name == "Microsoft.AspNetCore") + { + var subscription = value.Subscribe(this); + + lock (this.listenerSubscriptions) + { + this.listenerSubscriptions.Add(subscription); + } + } + } + + public void OnNext(KeyValuePair value) + { + HttpContext? context; + BeforeActionEventData? actionMethodEventData; + RouteInfo? info; + + switch (value.Key) + { + case OnStartEvent: + context = value.Value as HttpContext; + Debug.Assert(context != null, "HttpContext was null"); + info = new RouteInfo(); + info.SetValues(context); + RouteInfo.Current = info; + break; + case OnMvcBeforeActionEvent: + actionMethodEventData = value.Value as BeforeActionEventData; + Debug.Assert(actionMethodEventData != null, $"expected {nameof(BeforeActionEventData)}"); + RouteInfo.Current.SetValues(actionMethodEventData.HttpContext); + RouteInfo.Current.SetValues(actionMethodEventData.ActionDescriptor); + break; + case OnStopEvent: + context = value.Value as HttpContext; + Debug.Assert(context != null, "HttpContext was null"); + RouteInfo.Current.SetValues(context); + break; + default: + break; + } + } + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 1) + { + return; + } + + lock (this.listenerSubscriptions) + { + foreach (var listenerSubscription in this.listenerSubscriptions) + { + listenerSubscription?.Dispose(); + } + + this.listenerSubscriptions.Clear(); + } + + this.allSourcesSubscription?.Dispose(); + this.allSourcesSubscription = null; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs new file mode 100644 index 0000000000..b030ab7f42 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs @@ -0,0 +1,199 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Diagnostics; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; + +namespace RouteTests.TestApplication; + +public enum TestApplicationScenario +{ + /// + /// An application that uses conventional routing. + /// + ConventionalRouting, + + /// + /// An application that uses attribute routing. + /// + AttributeRouting, + + /// + /// A Minimal API application. + /// + MinimalApi, + + /// + /// An Razor Pages application. + /// + RazorPages, + + /// + /// Application with Exception Handling Middleware. + /// + ExceptionMiddleware, +} + +internal class TestApplicationFactory +{ + private static readonly string AspNetCoreTestsPath = new FileInfo(typeof(RoutingTests)!.Assembly!.Location)!.Directory!.Parent!.Parent!.Parent!.FullName; + private static readonly string ContentRootPath = Path.Combine(AspNetCoreTestsPath, "RouteTests", "TestApplication"); + + public static WebApplication? CreateApplication(TestApplicationScenario config) + { + Debug.Assert(Directory.Exists(ContentRootPath), $"Cannot find ContentRootPath: {ContentRootPath}"); + switch (config) + { + case TestApplicationScenario.ConventionalRouting: + return CreateConventionalRoutingApplication(); + case TestApplicationScenario.AttributeRouting: + return CreateAttributeRoutingApplication(); + case TestApplicationScenario.MinimalApi: + return CreateMinimalApiApplication(); + case TestApplicationScenario.RazorPages: + return CreateRazorPagesApplication(); + case TestApplicationScenario.ExceptionMiddleware: + return CreateExceptionHandlerApplication(); + default: + throw new ArgumentException($"Invalid {nameof(TestApplicationScenario)}"); + } + } + + private static WebApplication CreateConventionalRoutingApplication() + { + var builder = WebApplication.CreateBuilder(new WebApplicationOptions { ContentRootPath = ContentRootPath }); + builder.Logging.ClearProviders(); + + builder.Services + .AddControllersWithViews() + .AddApplicationPart(typeof(RoutingTests).Assembly); + + var app = builder.Build(); + app.Urls.Clear(); + app.Urls.Add("http://[::1]:0"); + app.UseStaticFiles(); + app.UseRouting(); + + app.MapAreaControllerRoute( + name: "AnotherArea", + areaName: "AnotherArea", + pattern: "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}"); + + app.MapControllerRoute( + name: "MyArea", + pattern: "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}"); + + app.MapControllerRoute( + name: "FixedRouteWithConstraints", + pattern: "SomePath/{id}/{num:int}", + defaults: new { controller = "ConventionalRoute", action = "ActionWithStringParameter" }); + + app.MapControllerRoute( + name: "default", + pattern: "{controller=ConventionalRoute}/{action=Default}/{id?}"); + + return app; + } + + private static WebApplication CreateAttributeRoutingApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + + builder.Services + .AddControllers() + .AddApplicationPart(typeof(RoutingTests).Assembly); + + var app = builder.Build(); + app.Urls.Clear(); + app.Urls.Add("http://[::1]:0"); + app.MapControllers(); + + return app; + } + + private static WebApplication CreateMinimalApiApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + + var app = builder.Build(); + app.Urls.Clear(); + app.Urls.Add("http://[::1]:0"); + + app.MapGet("/MinimalApi", () => Results.Ok()); + app.MapGet("/MinimalApi/{id}", (int id) => Results.Ok()); + +#if NET7_0_OR_GREATER + var api = app.MapGroup("/MinimalApiUsingMapGroup"); + api.MapGet("/", () => Results.Ok()); + api.MapGet("/{id}", (int id) => Results.Ok()); +#endif + + return app; + } + + private static WebApplication CreateRazorPagesApplication() + { + var builder = WebApplication.CreateBuilder(new WebApplicationOptions { ContentRootPath = ContentRootPath }); + builder.Logging.ClearProviders(); + + builder.Services + .AddRazorPages() + .AddRazorRuntimeCompilation(options => + { + options.FileProviders.Add(new PhysicalFileProvider(ContentRootPath)); + }) + .AddApplicationPart(typeof(RoutingTests).Assembly); + + var app = builder.Build(); + app.Urls.Clear(); + app.Urls.Add("http://[::1]:0"); + app.UseStaticFiles(); + app.UseRouting(); + app.MapRazorPages(); + + return app; + } + + private static WebApplication CreateExceptionHandlerApplication() + { + var builder = WebApplication.CreateBuilder(); + builder.Logging.ClearProviders(); + + var app = builder.Build(); + + app.UseExceptionHandler(exceptionHandlerApp => + { + exceptionHandlerApp.Run(async context => + { + context.Response.StatusCode = StatusCodes.Status500InternalServerError; + var exceptionHandlerPathFeature = context.Features.Get(); + await context.Response.WriteAsync(exceptionHandlerPathFeature?.Error.Message ?? "An exception was thrown."); + }); + }); + + app.Urls.Clear(); + app.Urls.Add("http://[::1]:0"); + + // TODO: Remove this condition once ASP.NET Core 8.0.2. + // Currently, .NET 8 has a different behavior than .NET 6 and 7. + // This is because ASP.NET Core 8+ has native metric instrumentation. + // When ASP.NET Core 8.0.2 is released then its behavior will align with .NET 6/7. + // See: https://github.com/dotnet/aspnetcore/issues/52648#issuecomment-1853432776 +#if !NET8_0_OR_GREATER + app.MapGet("/Exception", (ctx) => throw new ApplicationException()); +#else + app.MapGet("/Exception", () => Results.Content(content: "Error", contentType: null, contentEncoding: null, statusCode: 500)); +#endif + + return app; + } +} diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/wwwroot/js/site.js b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/wwwroot/js/site.js new file mode 100644 index 0000000000..0937657353 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/wwwroot/js/site.js @@ -0,0 +1,4 @@ +// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification +// for details on configuring this project to bundle and minify static web assets. + +// Write your JavaScript code. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs new file mode 100644 index 0000000000..36710fe4a9 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable +using RouteTests.TestApplication; + +namespace RouteTests; + +public class TestCase +{ + public string Name { get; set; } = string.Empty; + + public int? MinimumDotnetVersion { get; set; } + + public TestApplicationScenario TestApplicationScenario { get; set; } + + public string? HttpMethod { get; set; } + + public string Path { get; set; } = string.Empty; + + public int ExpectedStatusCode { get; set; } + + public string? ExpectedHttpRoute { get; set; } + + public string? CurrentHttpRoute { get; set; } + + public override string ToString() + { + // This is used by Visual Studio's test runner to identify the test case. + return $"{this.TestApplicationScenario}: {this.Name}"; + } +} diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md b/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md index b855fb74fd..2cc3e82fbc 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md @@ -1,4 +1,4 @@ -# OpenTelemetry GenevaExporter Benchmarks +# OpenTelemetry HTTP Instrumentation Benchmarks Navigate to `./test/OpenTelemetry.Instrumentation.Http.Benchmark` directory and run the following command: diff --git a/test/TestApp.AspNetCore/ActivityMiddleware.cs b/test/TestApp.AspNetCore/ActivityMiddleware.cs new file mode 100644 index 0000000000..99f70a5aa3 --- /dev/null +++ b/test/TestApp.AspNetCore/ActivityMiddleware.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace TestApp.AspNetCore; + +internal class ActivityMiddleware +{ + private readonly TestActivityMiddleware testActivityMiddleware; + private readonly RequestDelegate next; + + public ActivityMiddleware(RequestDelegate next, TestActivityMiddleware testActivityMiddleware) + { + this.next = next; + this.testActivityMiddleware = testActivityMiddleware; + } + + public async Task InvokeAsync(HttpContext context) + { + if (this.testActivityMiddleware != null) + { + this.testActivityMiddleware.PreProcess(context); + } + + await this.next(context); + + if (this.testActivityMiddleware != null) + { + this.testActivityMiddleware.PostProcess(context); + } + } +} diff --git a/test/TestApp.AspNetCore/CallbackMiddleware.cs b/test/TestApp.AspNetCore/CallbackMiddleware.cs new file mode 100644 index 0000000000..9ee236845d --- /dev/null +++ b/test/TestApp.AspNetCore/CallbackMiddleware.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace TestApp.AspNetCore; + +public class CallbackMiddleware +{ + private readonly TestCallbackMiddleware testCallbackMiddleware; + private readonly RequestDelegate next; + + public CallbackMiddleware(RequestDelegate next, TestCallbackMiddleware testCallbackMiddleware) + { + this.next = next; + this.testCallbackMiddleware = testCallbackMiddleware; + } + + public async Task InvokeAsync(HttpContext context) + { + if (this.testCallbackMiddleware == null || await this.testCallbackMiddleware.ProcessAsync(context)) + { + await this.next(context); + } + } +} diff --git a/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs b/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs new file mode 100644 index 0000000000..b55927000f --- /dev/null +++ b/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.AspNetCore.Mvc; +using OpenTelemetry; + +namespace TestApp.AspNetCore.Controllers; + +public class ChildActivityController : Controller +{ + [HttpGet] + [Route("api/GetChildActivityTraceContext")] + public Dictionary GetChildActivityTraceContext() + { + var result = new Dictionary(); + var activity = new Activity("ActivityInsideHttpRequest"); + activity.Start(); + result["TraceId"] = activity.Context.TraceId.ToString(); + result["ParentSpanId"] = activity.ParentSpanId.ToString(); + if (activity.Context.TraceState != null) + { + result["TraceState"] = activity.Context.TraceState; + } + + activity.Stop(); + return result; + } + + [HttpGet] + [Route("api/GetChildActivityBaggageContext")] + public IReadOnlyDictionary GetChildActivityBaggageContext() + { + var result = Baggage.Current.GetBaggage(); + return result; + } + + [HttpGet] + [Route("api/GetActivityEquality")] + public bool GetActivityEquality() + { + var activity = this.HttpContext.Features.Get()?.Activity; + var equal = Activity.Current == activity; + return equal; + } +} diff --git a/test/TestApp.AspNetCore/Controllers/ErrorController.cs b/test/TestApp.AspNetCore/Controllers/ErrorController.cs new file mode 100644 index 0000000000..24c904cfe9 --- /dev/null +++ b/test/TestApp.AspNetCore/Controllers/ErrorController.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.AspNetCore.Mvc; + +namespace TestApp.AspNetCore.Controllers; + +[Route("api/[controller]")] +public class ErrorController : Controller +{ + // GET api/error + [HttpGet] + public string Get() + { + throw new Exception("something's wrong!"); + } +} diff --git a/test/TestApp.AspNetCore/Controllers/ValuesController.cs b/test/TestApp.AspNetCore/Controllers/ValuesController.cs new file mode 100644 index 0000000000..27a9ab0d2d --- /dev/null +++ b/test/TestApp.AspNetCore/Controllers/ValuesController.cs @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.AspNetCore.Mvc; + +namespace TestApp.AspNetCore.Controllers; + +[Route("api/[controller]")] +public class ValuesController : Controller +{ + // GET api/values + [HttpGet] + public IEnumerable Get() + { + return new string[] { "value1", "value2" }; + } + + // GET api/values/5 + [HttpGet("{id}")] + public string Get(int id) + { + return "value"; + } + + // POST api/values + [HttpPost] + public void Post([FromBody] string value) + { + } + + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } +} diff --git a/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs b/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs new file mode 100644 index 0000000000..1f05886069 --- /dev/null +++ b/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.AspNetCore.Mvc.Filters; + +namespace TestApp.AspNetCore.Filters; + +public class ExceptionFilter1 : IExceptionFilter +{ + public void OnException(ExceptionContext context) + { + // test the behaviour when an application has two ExceptionFilters defined + } +} diff --git a/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs b/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs new file mode 100644 index 0000000000..fc81905c65 --- /dev/null +++ b/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.AspNetCore.Mvc.Filters; + +namespace TestApp.AspNetCore.Filters; + +public class ExceptionFilter2 : IExceptionFilter +{ + public void OnException(ExceptionContext context) + { + // test the behaviour when an application has two ExceptionFilters defined + } +} diff --git a/test/TestApp.AspNetCore/Program.cs b/test/TestApp.AspNetCore/Program.cs new file mode 100644 index 0000000000..5cbe2b5e3a --- /dev/null +++ b/test/TestApp.AspNetCore/Program.cs @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using TestApp.AspNetCore; + +public class Program +{ + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + + builder.Services.AddControllers(); + + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + + builder.Services.AddSwaggerGen(); + + builder.Services.AddMvc(); + + builder.Services.AddSingleton(); + + builder.Services.AddSingleton( + new TestCallbackMiddleware()); + + builder.Services.AddSingleton( + new TestActivityMiddleware()); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + app.MapControllers(); + + app.UseMiddleware(); + + app.UseMiddleware(); + + app.AddTestMiddleware(); + + app.Run(); + } +} diff --git a/test/TestApp.AspNetCore/Properties/launchSettings.json b/test/TestApp.AspNetCore/Properties/launchSettings.json new file mode 100644 index 0000000000..f627182e41 --- /dev/null +++ b/test/TestApp.AspNetCore/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "TestApp.AspNetCore": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:58211;http://localhost:58212" + } + } +} \ No newline at end of file diff --git a/test/TestApp.AspNetCore/TestActivityMiddleware.cs b/test/TestApp.AspNetCore/TestActivityMiddleware.cs new file mode 100644 index 0000000000..be1e2e5a1e --- /dev/null +++ b/test/TestApp.AspNetCore/TestActivityMiddleware.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace TestApp.AspNetCore; + +public class TestActivityMiddleware +{ + public virtual void PreProcess(HttpContext context) + { + // Do nothing + } + + public virtual void PostProcess(HttpContext context) + { + // Do nothing + } +} diff --git a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj new file mode 100644 index 0000000000..ce4a4b6852 --- /dev/null +++ b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj @@ -0,0 +1,13 @@ + + + + net8.0;net7.0;net6.0 + enable + + + + + + + + diff --git a/test/TestApp.AspNetCore/TestCallbackMiddleware.cs b/test/TestApp.AspNetCore/TestCallbackMiddleware.cs new file mode 100644 index 0000000000..ba11577ff0 --- /dev/null +++ b/test/TestApp.AspNetCore/TestCallbackMiddleware.cs @@ -0,0 +1,12 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace TestApp.AspNetCore; + +public class TestCallbackMiddleware +{ + public virtual async Task ProcessAsync(HttpContext context) + { + return await Task.FromResult(true); + } +} diff --git a/test/TestApp.AspNetCore/TestMiddleware.cs b/test/TestApp.AspNetCore/TestMiddleware.cs new file mode 100644 index 0000000000..39acf58db3 --- /dev/null +++ b/test/TestApp.AspNetCore/TestMiddleware.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace TestApp.AspNetCore; + +public static class TestMiddleware +{ + private static readonly AsyncLocal?> Current = new(); + + public static IApplicationBuilder AddTestMiddleware(this IApplicationBuilder builder) + { + if (Current.Value is { } configure) + { + configure(builder); + } + + return builder; + } + + public static void Create(Action action) + { + Current.Value = action; + } +} diff --git a/test/TestApp.AspNetCore/appsettings.Development.json b/test/TestApp.AspNetCore/appsettings.Development.json new file mode 100644 index 0000000000..0c208ae918 --- /dev/null +++ b/test/TestApp.AspNetCore/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/test/TestApp.AspNetCore/appsettings.json b/test/TestApp.AspNetCore/appsettings.json new file mode 100644 index 0000000000..10f68b8c8b --- /dev/null +++ b/test/TestApp.AspNetCore/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} From 46b27bc0b222756d8cfefd83ad167fcd2c2e2cc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 9 May 2024 19:00:34 +0200 Subject: [PATCH 1050/1499] Cleanup publicApi files (#1711) --- .../{net6.0 => }/PublicAPI.Shipped.txt | 0 .../{net6.0 => }/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 23 ------------------- .../{net462 => }/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 2 -- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 23 ------------------- .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 23 ------------------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 9 -------- .../netstandard2.0/PublicAPI.Unshipped.txt | 9 -------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 18 --------------- .../.publicApi/net7.0/PublicAPI.Unshipped.txt | 18 --------------- .../netstandard2.0/PublicAPI.Unshipped.txt | 18 --------------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 14 ----------- .../netstandard2.0/PublicAPI.Unshipped.txt | 14 ----------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 8 ------- .../netstandard2.0/PublicAPI.Unshipped.txt | 8 ------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net6.0 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../netstandard2.0/PublicAPI.Unshipped.txt | 16 ------------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../.publicApi}/PublicAPI.Shipped.txt | 0 .../PublicAPI.Unshipped.txt | 0 .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../{net462 => }/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 4 ---- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 4 ---- .../netstandard2.0/PublicAPI.Shipped.txt | 4 ---- .../netstandard2.0/PublicAPI.Unshipped.txt | 4 ---- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 22 ------------------ .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 22 ------------------ .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net6.0 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 21 ----------------- .../.publicApi/net462/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Shipped.txt | 21 ----------------- .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../{net462 => }/PublicAPI.Shipped.txt | 0 .../.publicApi}/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 15 ------------ .../netstandard2.0/PublicAPI.Shipped.txt | 16 ------------- .../netstandard2.0/PublicAPI.Unshipped.txt | 0 .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 6 ----- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net6.0 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 9 -------- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net6.0 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 --- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 --- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 3 --- .../.publicApi}/PublicAPI.Shipped.txt | 0 .../{net462 => }/PublicAPI.Unshipped.txt | 0 .../.publicApi/net462/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Shipped.txt | 1 - .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 9 -------- .../netstandard2.0/PublicAPI.Shipped.txt | 1 - .../netstandard2.0/PublicAPI.Unshipped.txt | 9 -------- 120 files changed, 400 deletions(-) rename src/OpenTelemetry.Exporter.InfluxDB/.publicApi/{net6.0 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.InfluxDB/.publicApi/{net6.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/OpenTelemetry.Exporter.Instana/.publicApi/{net462 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.Instana/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename src/{OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0 => OpenTelemetry.Exporter.Stackdriver/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Exporter.Stackdriver/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Exporter.Stackdriver/.publicApi/net462 => OpenTelemetry.Extensions.AWS/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Extensions.AWS/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0 => OpenTelemetry.Extensions.Enrichment/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Extensions.Enrichment/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0 => OpenTelemetry.Extensions/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Extensions/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0 => OpenTelemetry.Instrumentation.AWS/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.AWS/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.Enrichment/.publicApi/net462 => OpenTelemetry.Instrumentation.AWSLambda/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/{net6.0 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0 => OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0 => OpenTelemetry.Instrumentation.AspNet/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.AspNet/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/{netstandard2.0 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0 => OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0 => OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Extensions/.publicApi/net462 => OpenTelemetry.Instrumentation.EventCounters/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462 => OpenTelemetry.Instrumentation.GrpcCore/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename src/{OpenTelemetry.Extensions/.publicApi/net6.0 => OpenTelemetry.Instrumentation.Hangfire/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Extensions/.publicApi/netstandard2.0 => OpenTelemetry.Instrumentation.Owin/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Owin/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) rename src/{OpenTelemetry.Instrumentation.AWS/.publicApi/net462 => OpenTelemetry.Instrumentation.Process/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Process/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename src/{OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0 => OpenTelemetry.Instrumentation.Quartz/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Quartz/.publicApi/{netstandard2.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename src/OpenTelemetry.Instrumentation.Runtime/.publicApi/{net462 => }/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.Runtime/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0 => OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0 => OpenTelemetry.PersistentStorage.Abstractions/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/{net6.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/{net462 => }/PublicAPI.Shipped.txt (100%) rename src/{OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0 => OpenTelemetry.PersistentStorage.FileSystem/.publicApi}/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Extensions.AWS/.publicApi/net462 => OpenTelemetry.ResourceDetectors.AWS/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt rename src/{OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462 => OpenTelemetry.ResourceDetectors.Azure/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/{net6.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Instrumentation.AspNet/.publicApi/net462 => OpenTelemetry.ResourceDetectors.Container/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.Container/.publicApi/{net6.0 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Shipped.txt rename src/{OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0 => OpenTelemetry.ResourceDetectors.Host/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.Host/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0 => OpenTelemetry.ResourceDetectors.Process/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.Process/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0 => OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.Instrumentation.Owin/.publicApi/net462 => OpenTelemetry.Sampler.AWS/.publicApi}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Sampler.AWS/.publicApi/{net462 => }/PublicAPI.Unshipped.txt (100%) delete mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt delete mode 100644 src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.InfluxDB/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.InfluxDB/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.InfluxDB/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index eec1ac3ac7..0000000000 --- a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,23 +0,0 @@ -#nullable enable -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.get -> string? -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Bucket.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.get -> System.Uri? -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Endpoint.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.get -> int -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.FlushInterval.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.InfluxDBMetricsExporterOptions() -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricExportIntervalMilliseconds.get -> int -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricExportIntervalMilliseconds.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.get -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.MetricsSchema.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.get -> string? -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Org.set -> void -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.get -> string? -OpenTelemetry.Exporter.InfluxDB.InfluxDBMetricsExporterOptions.Token.set -> void -OpenTelemetry.Exporter.InfluxDB.MetricsSchema -OpenTelemetry.Exporter.InfluxDB.MetricsSchema.None = 0 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema -OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV1 = 1 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema -OpenTelemetry.Exporter.InfluxDB.MetricsSchema.TelegrafPrometheusV2 = 2 -> OpenTelemetry.Exporter.InfluxDB.MetricsSchema -OpenTelemetry.Metrics.InfluxDBExporterExtensions -static OpenTelemetry.Metrics.InfluxDBExporterExtensions.AddInfluxDBMetricsExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Instana/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 5b4e5bba7a..0000000000 --- a/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,2 +0,0 @@ -OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions -static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder options) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.InfluxDB/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Stackdriver/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Stackdriver/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index f09de33268..0000000000 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,23 +0,0 @@ -OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void -OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter -OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string! projectId) -> void -OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils -OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string? projectId) -> Google.Api.MonitoredResource! -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string? -static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration! -static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable! source, int size) -> System.Collections.Generic.IEnumerable!>! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string! projectId) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt deleted file mode 100644 index f09de33268..0000000000 --- a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,23 +0,0 @@ -OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.get -> System.TimeSpan -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ExportInterval.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.get -> Google.Apis.Auth.OAuth2.GoogleCredential? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.GoogleCredential.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.get -> string? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MetricNamePrefix.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.get -> Google.Api.MonitoredResource? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.MonitoredResource.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.get -> string? -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.ProjectId.set -> void -OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.StackdriverStatsConfiguration() -> void -OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter -OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.StackdriverTraceExporter(string! projectId) -> void -OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils -OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Exporter.Stackdriver.StackdriverTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetDefaultResource(string? projectId) -> Google.Api.MonitoredResource! -static OpenTelemetry.Exporter.Stackdriver.Implementation.GoogleCloudResourceUtils.GetProjectId() -> string? -static OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration.Default.get -> OpenTelemetry.Exporter.Stackdriver.Implementation.StackdriverStatsConfiguration! -static OpenTelemetry.Exporter.Stackdriver.Utils.CommonUtils.Partition(this System.Collections.Generic.IEnumerable! source, int size) -> System.Collections.Generic.IEnumerable!>! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.UseStackdriverExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string! projectId) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt index 7dc5c58110..e69de29bb2 100644 --- a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt index 70b757cca5..d7180ec895 100644 --- a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,11 +1,2 @@ -OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator -OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator -OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void static OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator.ReplaceTraceId() -> void static OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator.ReplaceTraceId(OpenTelemetry.Trace.Sampler! sampler) -> void -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a7a1588b77..0000000000 --- a/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,9 +0,0 @@ -OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator -OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator -OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceIdWithSampler(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Trace.Sampler! sampler) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions.Enrichment/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions.Enrichment/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a037573dcc..0000000000 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,18 +0,0 @@ -abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void -Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions -OpenTelemetry.Extensions.Enrichment.TraceEnricher -OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a037573dcc..0000000000 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,18 +0,0 @@ -abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void -Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions -OpenTelemetry.Extensions.Enrichment.TraceEnricher -OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a037573dcc..0000000000 --- a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,18 +0,0 @@ -abstract OpenTelemetry.Extensions.Enrichment.TraceEnricher.Enrich(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void -Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions -OpenTelemetry.Extensions.Enrichment.TraceEnricher -OpenTelemetry.Extensions.Enrichment.TraceEnricher.TraceEnricher() -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.Add(string! key, object? value) -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag() -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag.TraceEnrichmentBag(System.Diagnostics.Activity! activity) -> void -OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! enrichmentAction) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Func! enricherImplementationFactory) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Microsoft.Extensions.DependencyInjection.TraceEnrichmentServiceCollectionExtensions.AddTraceEnricher(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Extensions.Enrichment.TraceEnricher! enricher) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! enrichmentAction) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! enricherImplementationFactory) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Extensions.Enrichment.TraceEnrichmentProviderBuilderExtensions.AddTraceEnricher(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -virtual OpenTelemetry.Extensions.Enrichment.TraceEnricher.EnrichOnActivityStart(in OpenTelemetry.Extensions.Enrichment.TraceEnrichmentBag bag) -> void diff --git a/src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Stackdriver/.publicApi/net8.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 4b388d9972..0000000000 --- a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,14 +0,0 @@ -#nullable enable -Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions -OpenTelemetry.Logs.LogToActivityEventConversionOptions -OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.get -> System.Func? -OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! -OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 4b388d9972..0000000000 --- a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,14 +0,0 @@ -#nullable enable -Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions -OpenTelemetry.Logs.LogToActivityEventConversionOptions -OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.get -> System.Func? -OpenTelemetry.Logs.LogToActivityEventConversionOptions.Filter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.LogToActivityEventConversionOptions() -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> System.Action! -OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! -OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 1362c26ff9..0000000000 --- a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,8 +0,0 @@ -#nullable enable -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 1362c26ff9..0000000000 --- a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,8 +0,0 @@ -#nullable enable -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool -OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Enrichment/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Enrichment/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Enrichment/.publicApi/net7.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Cassandra/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 95461d9b80..0000000000 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,16 +0,0 @@ -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ElasticsearchClientInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.get -> System.Action -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.get -> int -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.set -> void -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ParseAndFormatRequest.get -> bool -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ParseAndFormatRequest.set -> void -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SetDbStatementForRequest.get -> bool -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SetDbStatementForRequest.set -> void -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.Enrichment/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Owin/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Owin/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Owin/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWS/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Process/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Process/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Instrumentation.Process/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Quartz/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Quartz/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Instrumentation.Quartz/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 4f1e7e604f..0000000000 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index b9754cf55f..0000000000 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,4 +0,0 @@ -#nullable enable -*REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 4f1e7e604f..0000000000 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,4 +0,0 @@ -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions -OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void -OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index b9754cf55f..0000000000 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,4 +0,0 @@ -#nullable enable -*REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index c76bae94e0..0000000000 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,22 +0,0 @@ -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(string! name, StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.Dispose() -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.get -> System.TimeSpan -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.StackExchangeRedisInstrumentationOptions() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index c76bae94e0..0000000000 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,22 +0,0 @@ -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.AddConnection(string! name, StackExchange.Redis.IConnectionMultiplexer! connection) -> System.IDisposable! -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentation.Dispose() -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.EnrichActivityWithTimingEvents.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.get -> System.TimeSpan -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.FlushInterval.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.get -> bool -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.SetVerboseDatabaseStatements.set -> void -OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.StackExchangeRedisInstrumentationOptions() -> void -OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AWSLambda/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index db7fb2d358..0000000000 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1,21 +0,0 @@ -#nullable enable -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index db7fb2d358..0000000000 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,21 +0,0 @@ -#nullable enable -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryDelete() -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryRead(out byte[]? buffer) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -abstract OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.PersistentBlob() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryDelete() -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryLease(int leasePeriodMilliseconds) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryRead(out byte[]? buffer) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob.TryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.GetBlobs() -> System.Collections.Generic.IEnumerable! -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.PersistentBlobProvider() -> void -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -OpenTelemetry.PersistentStorage.Abstractions.PersistentBlobProvider.TryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.Abstractions/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Instana/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net462/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a3ca421004..0000000000 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,15 +0,0 @@ -OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index c1d68fa289..0000000000 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1,16 +0,0 @@ -#nullable enable -OpenTelemetry.PersistentStorage.FileSystem.FileBlob -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FileBlob(string! fullPath) -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlob.FullPath.get -> string! -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose() -> void -OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.FileBlobProvider(string! path, long maxSizeInBytes = 52428800, int maintenancePeriodInMilliseconds = 120000, long retentionPeriodInMilliseconds = 172800000, int writeTimeoutInMilliseconds = 60000) -> void -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryDelete() -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryLease(int leasePeriodMilliseconds) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryRead(out byte[]? buffer) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlob.OnTryWrite(byte[]! buffer, int leasePeriodMilliseconds = 0) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnGetBlobs() -> System.Collections.Generic.IEnumerable! -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, int leasePeriodMilliseconds, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryCreateBlob(byte[]! buffer, out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -override OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.OnTryGetBlob(out OpenTelemetry.PersistentStorage.Abstractions.PersistentBlob? blob) -> bool -virtual OpenTelemetry.PersistentStorage.FileSystem.FileBlobProvider.Dispose(bool disposing) -> void diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.PersistentStorage.FileSystem/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.AWS/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 815c92006a..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable \ No newline at end of file diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt index 7dc5c58110..e69de29bb2 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt index 4a0f8f92ce..2ac5b3257b 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -1,9 +1,3 @@ -OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector -OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector -OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector.AWSECSResourceDetector() -> void OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 742d5f3fed..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,9 +0,0 @@ -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector -OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.AzureContainerAppsResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector -OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.AzureVMResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.AspNet/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Container/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.Container/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Container/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.EntityFrameworkCore/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index ab46f0419f..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.Host.HostDetector -OpenTelemetry.ResourceDetectors.Host.HostDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Host.HostDetector.HostDetector() -> void diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.EventCounters/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 536c6eae3b..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.Process.ProcessDetector -OpenTelemetry.ResourceDetectors.Process.ProcessDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Process.ProcessDetector.ProcessDetector() -> void diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Hangfire/.publicApi/netstandard2.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index a4c8a74d8a..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Instrumentation.Owin/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/net462/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 063bdbf96d..0000000000 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,9 +0,0 @@ -#nullable enable -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Dispose() -> void -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler! -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! -override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult -static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder(OpenTelemetry.Resources.Resource! resource) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt deleted file mode 100644 index 7dc5c58110..0000000000 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 063bdbf96d..0000000000 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,9 +0,0 @@ -#nullable enable -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Dispose() -> void -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler! -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! -override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult -static OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Builder(OpenTelemetry.Resources.Resource! resource) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! From 707f57556f476d1acc8f7049baaa72dd9cb18161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 10 May 2024 06:32:58 +0200 Subject: [PATCH 1051/1499] [repo] Enable package validation (#1710) Co-authored-by: Mikel Blanchard --- .github/workflows/Component.BuildTest.yml | 8 ++++- .github/workflows/Component.Package.yml | 6 ++-- build/Common.prod.props | 21 ++++++++++-- build/RELEASING.md | 3 ++ .../OpenTelemetry.Exporter.Geneva.csproj | 1 + .../OpenTelemetry.Exporter.InfluxDB.csproj | 6 ++++ .../OpenTelemetry.Exporter.Instana.csproj | 1 + ...OpenTelemetry.Exporter.OneCollector.csproj | 1 + .../OpenTelemetry.Exporter.Stackdriver.csproj | 6 ++++ .../OpenTelemetry.Extensions.AWS.csproj | 6 ++++ ...OpenTelemetry.Extensions.Enrichment.csproj | 6 ++++ .../OpenTelemetry.Extensions.csproj | 6 ++++ .../OpenTelemetry.Instrumentation.AWS.csproj | 6 ++++ ...Telemetry.Instrumentation.AWSLambda.csproj | 6 ++++ ...entation.AspNet.TelemetryHttpModule.csproj | 6 ++++ ...penTelemetry.Instrumentation.AspNet.csproj | 6 ++++ ...Telemetry.Instrumentation.Cassandra.csproj | 6 ++++ ...Instrumentation.ElasticsearchClient.csproj | 7 ++++ ...Instrumentation.EntityFrameworkCore.csproj | 6 ++++ ...metry.Instrumentation.EventCounters.csproj | 33 +++++++++++------- ...nTelemetry.Instrumentation.GrpcCore.csproj | 7 ++++ ...metry.Instrumentation.GrpcNetClient.csproj | 2 +- ...nTelemetry.Instrumentation.Hangfire.csproj | 7 ++++ .../OpenTelemetry.Instrumentation.Owin.csproj | 6 ++++ ...enTelemetry.Instrumentation.Process.csproj | 6 ++++ ...penTelemetry.Instrumentation.Quartz.csproj | 7 ++++ ...enTelemetry.Instrumentation.Runtime.csproj | 1 + ...Telemetry.Instrumentation.SqlClient.csproj | 2 +- ....Instrumentation.StackExchangeRedis.csproj | 6 ++++ .../OpenTelemetry.Instrumentation.Wcf.csproj | 6 ++++ ...etry.PersistentStorage.Abstractions.csproj | 2 +- ...emetry.PersistentStorage.FileSystem.csproj | 2 +- ...OpenTelemetry.ResourceDetectors.AWS.csproj | 6 ++++ ...enTelemetry.ResourceDetectors.Azure.csproj | 34 +++++++++++-------- ...lemetry.ResourceDetectors.Container.csproj | 7 ++++ ...penTelemetry.ResourceDetectors.Host.csproj | 7 ++++ ...Telemetry.ResourceDetectors.Process.csproj | 7 ++++ ...ry.ResourceDetectors.ProcessRuntime.csproj | 7 ++++ .../OpenTelemetry.Sampler.AWS.csproj | 6 ++++ .../OpenTelemetry.SemanticConventions.csproj | 5 +++ 40 files changed, 243 insertions(+), 37 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 02a2a6fb55..fb3aba0caa 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -37,12 +37,14 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 # fetching all, to be able to calculate package version - name: Setup dotnet uses: actions/setup-dotnet@v4 - name: dotnet restore build/Projects/${{ inputs.project-name }}.proj - run: dotnet restore build/Projects/${{ inputs.project-name }}.proj + run: dotnet restore build/Projects/${{ inputs.project-name }}.proj -p:EnablePackageValidation=true - name: dotnet build build/Projects/${{ inputs.project-name }}.proj run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore @@ -50,6 +52,10 @@ jobs: - name: dotnet test build/Projects/${{ inputs.project-name }}.proj run: dotnet test build/Projects/${{ inputs.project-name }}.proj --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + - name: dotnet pack build/Projects/${{ inputs.project-name }}.proj + if: ${{ matrix.os == 'windows-latest' }} + run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build -p:EnablePackageValidation=true + - name: Install coverage tool run: dotnet tool install -g dotnet-coverage diff --git a/.github/workflows/Component.Package.yml b/.github/workflows/Component.Package.yml index 29678a018e..49defb23f0 100644 --- a/.github/workflows/Component.Package.yml +++ b/.github/workflows/Component.Package.yml @@ -27,16 +27,16 @@ jobs: uses: actions/setup-dotnet@v4 - name: dotnet restore build/Projects/${{ inputs.project-name }}.proj - run: dotnet restore build/Projects/${{ inputs.project-name }}.proj + run: dotnet restore build/Projects/${{ inputs.project-name }}.proj -p:EnablePackageValidation=true - name: dotnet build build/Projects/${{ inputs.project-name }}.proj - run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore -p:Deterministic=true + run: dotnet build build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} - name: dotnet test build/Projects/${{ inputs.project-name }}.proj run: dotnet test build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build - name: dotnet pack build/Projects/${{ inputs.project-name }}.proj - run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build + run: dotnet pack build/Projects/${{ inputs.project-name }}.proj --configuration Release --no-restore --no-build -p:EnablePackageValidation=true - name: Publish Artifacts uses: actions/upload-artifact@v4 diff --git a/build/Common.prod.props b/build/Common.prod.props index 3661b1c333..52db728344 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -15,6 +15,7 @@ $(Build_ArtifactStagingDirectory) Observability;OpenTelemetry;Monitoring;Telemetry + false @@ -28,13 +29,23 @@ + - 0 - $(MinVerVersion.Split(`.`)[3]) + $(BuildNumber) + 0 $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(RevisionNumber) $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(RevisionNumber) $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(RevisionNumber) + + + @@ -52,6 +63,12 @@ true + + + + diff --git a/build/RELEASING.md b/build/RELEASING.md index 476d75c824..87136190ee 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -75,3 +75,6 @@ release page. successfully published to nuget.org under OpenTelemetry owner. 4. Validate that the new version was published in GitHub. + +5. If you released stable package, update `PackageValidationBaselineVersion` + in corresponding `csproj` file. diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 2894f56807..d7a2d15ed3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -10,6 +10,7 @@ net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- + 1.7.0 disable diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index 726cee834d..f1c7da1493 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -9,6 +9,12 @@ Exporter.InfluxDB- + + + true + + diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index f7ec063307..474df77b09 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -6,6 +6,7 @@ Instana Tracing APM Instana .NET Exporter for OpenTelemetry Exporter.Instana- + 1.0.3 disable diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 8fb04b0100..8aceaff990 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -15,6 +15,7 @@ this at the call site but there is a bug. This could possibly be cleaned up in the future (hopefully .NET 9) see https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 + 1.8.0 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index c2bcdefe0c..a4f5b0c32b 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -7,6 +7,12 @@ Exporter.Stackdriver- + + + true + + diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index d19543b384..4a75e2ed21 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -7,6 +7,12 @@ Extensions.AWS- + + + true + + diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index 2ee7f8c703..03e48e6f70 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -10,6 +10,12 @@ latest-all + + + true + + diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index de7b293fba..b204e085c8 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -8,6 +8,12 @@ Extensions- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index a3901a9267..5fc1c3b55a 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -8,6 +8,12 @@ Instrumentation.AWS- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 9d02ff7d9a..ebd0158ede 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -7,6 +7,12 @@ Instrumentation.AWSLambda- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 03ca33733e..01cfa35bb3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -7,6 +7,12 @@ Instrumentation.AspNet- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 8f52b1f0af..8900c31bf7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -8,6 +8,12 @@ Instrumentation.AspNet- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index 0ee2a7fc1b..6e6b111314 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -7,6 +7,12 @@ Instrumentation.Cassandra- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index fd3972389a..30383291e8 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -8,6 +8,13 @@ Instrumentation.ElasticsearchClient- disable + + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 42ecb2f1d1..c7cc580799 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -6,6 +6,12 @@ Instrumentation.EntityFrameworkCore- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index c5bd8c38e9..5b6d47e2c1 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -1,16 +1,23 @@ - - netstandard2.0 - OpenTelemetry Metrics instrumentation for Dotnet EventCounters - $(PackageTags);metrics;eventcounters - Instrumentation.EventCounters- - - - - + + netstandard2.0 + OpenTelemetry Metrics instrumentation for Dotnet EventCounters + $(PackageTags);metrics;eventcounters + Instrumentation.EventCounters- + - - - - + + + true + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 99bb69af12..7801f29915 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -6,6 +6,13 @@ Instrumentation.GrpcCore- disable + + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index f2c3bfdbb3..7622c13bec 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -12,7 +12,7 @@ + Remove this property once we have released a stable version and add PackageValidationBaselineVersion property.--> true diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 05f3aa1298..ad5280d28c 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -6,6 +6,13 @@ Instrumentation.Hangfire- false + + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 9773878f10..b2aae6f9b7 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -6,6 +6,12 @@ Instrumentation.Owin- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index abbc684703..f71ebcf4bf 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -6,6 +6,12 @@ Instrumentation.Process- + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 591d4158ac..05d43a3384 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -5,6 +5,13 @@ Instrumentation.Quartz- netstandard2.0 + + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 45aa106e5b..c5c5997d06 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,6 +5,7 @@ dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- + 1.8.0 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index b2c24ef68f..7c6211b265 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -11,7 +11,7 @@ + Remove this property once we have released a stable version and add PackageValidationBaselineVersion property.--> true diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index cec66dcf2a..53c2f8edcf 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -8,6 +8,12 @@ true + + + true + + diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 32a99948f9..7376dc4e12 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -8,6 +8,12 @@ Instrumentation.Wcf- + + + true + + diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index c73f4c883f..e2c02a33b8 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -4,9 +4,9 @@ netstandard2.0 $(TargetFrameworks);net462 - net6.0;$(TargetFrameworks) OpenTelemetry Persistent Storage Abstractions PersistentStorage- + 1.0.0 $(NoWarn),1591 diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index 00a144671b..fe8baa3a91 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -4,9 +4,9 @@ netstandard2.0 $(TargetFrameworks);net462 - net6.0;$(TargetFrameworks) OpenTelemetry Persistent Storage PersistentStorage- + 1.0.0 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj index 0cec692434..b8d2ea3cd7 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj @@ -8,6 +8,12 @@ ResourceDetectors.AWS- + + + true + + diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj index d066155384..d615446585 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj @@ -1,18 +1,24 @@ - - net6.0;netstandard2.0 - OpenTelemetry Resource Detectors for Azure cloud environments - $(PackageTags);ResourceDetector - ResourceDetectors.Azure- - + + net6.0;netstandard2.0 + OpenTelemetry Resource Detectors for Azure cloud environments + $(PackageTags);ResourceDetector + ResourceDetectors.Azure- + - - - - + + + true + - - - - + + + + + + + + + diff --git a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj index c77f1af5e6..d06e87c519 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Container/OpenTelemetry.ResourceDetectors.Container.csproj @@ -5,6 +5,13 @@ OpenTelemetry Extensions - Container Resource Detector from Container environment. ResourceDetectors.Container- + + + + true + + diff --git a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj index dbafb88169..bc95741131 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj @@ -6,6 +6,13 @@ OpenTelemetry Extensions - Host Resource Detector. ResourceDetectors.Host- + + + + true + + diff --git a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj b/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj index 3de24bbdee..73da91d636 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj +++ b/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj @@ -6,6 +6,13 @@ OpenTelemetry Extensions - Process Resource Detector. ResourceDetectors.Process- + + + + true + + diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj index 546004afde..613ed57702 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj +++ b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj @@ -6,6 +6,13 @@ OpenTelemetry Extensions - Process Runtime Resource Detector for .NET runtime. ResourceDetectors.ProcessRuntime- + + + + true + + diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index 155b7ab301..8811644f38 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -7,6 +7,12 @@ Sampler.AWS- + + + true + + diff --git a/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj b/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj index fe387d70e4..7b5c96cd86 100644 --- a/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj +++ b/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj @@ -8,4 +8,9 @@ false + + + true + From 0eb824d48199754d72210aeed66a17830001e342 Mon Sep 17 00:00:00 2001 From: Will Rogers Date: Fri, 10 May 2024 14:35:46 -0400 Subject: [PATCH 1052/1499] [Extensions.AWS] Remove NuGet reference to System.Net.Http (#1713) --- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 2 ++ .../OpenTelemetry.Extensions.AWS.csproj | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 4dfb89f237..87a842cabd 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Remove NuGet reference to `System.Net.Http` + ([#1713](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1713)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index 4a75e2ed21..253518e82b 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -15,7 +15,6 @@ - From b8f2d2c2915dba269edb61f7bd4cccdb2a1fc457 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Sun, 12 May 2024 22:26:10 -0700 Subject: [PATCH 1053/1499] Simplify issue templates and automatically assign component labels (#1716) Co-authored-by: Cijo Thomas --- .github/ISSUE_TEMPLATE/bug_report.yml | 113 ++++++++++++++++++ .../ISSUE_TEMPLATE/comp_exporter_geneva.md | 41 ------- .../ISSUE_TEMPLATE/comp_exporter_influxdb.md | 41 ------- .../ISSUE_TEMPLATE/comp_exporter_instana.md | 41 ------- .../comp_exporter_onecollector.md | 54 --------- .../comp_exporter_stackdriver.md | 41 ------- .github/ISSUE_TEMPLATE/comp_extensions.md | 41 ------- .github/ISSUE_TEMPLATE/comp_extensions_aws.md | 41 ------- .../comp_extensions_enrichment.md | 54 --------- .../comp_instrumentation_aspnet.md | 41 ------- ...trumentation_aspnet.telemetryhttpmodule.md | 41 ------- .../comp_instrumentation_aspnetcore.md | 41 ------- .../comp_instrumentation_aws.md | 41 ------- .../comp_instrumentation_awslambda.md | 41 ------- .../comp_instrumentation_cassandra.md | 41 ------- ...omp_instrumentation_elasticsearchclient.md | 41 ------- ...omp_instrumentation_entityframeworkcore.md | 41 ------- .../comp_instrumentation_eventcounters.md | 41 ------- .../comp_instrumentation_grpccore.md | 41 ------- .../comp_instrumentation_grpcnetclient.md | 41 ------- .../comp_instrumentation_hangfire.md | 41 ------- .../comp_instrumentation_http.md | 41 ------- .../comp_instrumentation_owin.md | 41 ------- .../comp_instrumentation_process.md | 41 ------- .../comp_instrumentation_quartz.md | 41 ------- .../comp_instrumentation_runtime.md | 41 ------- .../comp_instrumentation_sqlclient.md | 41 ------- ...comp_instrumentation_stackexchangeredis.md | 41 ------- .../comp_instrumentation_wcf.md | 41 ------- .../comp_persistentstorage.abstractions.md | 41 ------- .../comp_persistentstorage_filesystem.md | 41 ------- .../comp_resourcedetectors_aws.md | 41 ------- .../comp_resourcedetectors_azure.md | 41 ------- .../comp_resourcedetectors_container.md | 41 ------- .../comp_resourcedetectors_host.md | 41 ------- .../comp_resourcedetectors_process.md | 41 ------- .../comp_resourcedetectors_processruntime.md | 41 ------- .github/ISSUE_TEMPLATE/comp_sampler_aws.md | 41 ------- .../comp_semanticconventions.md | 41 ------- .github/ISSUE_TEMPLATE/feature_request.yml | 82 +++++++++++++ .github/ISSUE_TEMPLATE/miscellaneous.md | 15 --- .github/workflows/add-labels.yml | 25 ++++ CONTRIBUTING.md | 6 +- build/add-labels.ps1 | 12 ++ 44 files changed, 235 insertions(+), 1602 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_geneva.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_influxdb.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_instana.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_onecollector.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_extensions.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_aws.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_extensions_enrichment.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_aws.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_awslambda.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_http.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_owin.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_process.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_sampler_aws.md delete mode 100644 .github/ISSUE_TEMPLATE/comp_semanticconventions.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml delete mode 100644 .github/ISSUE_TEMPLATE/miscellaneous.md create mode 100644 .github/workflows/add-labels.yml create mode 100644 build/add-labels.ps1 diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..8b9c393599 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,113 @@ +name: Bug report +description: Create a report to help us improve +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down the bug as quickly as possible. + + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-dotnet/issues?q=is%3Aissue+is%3Aopen+label%3Abug) to see if an existing issue covers the bug. + + - type: dropdown + id: component + attributes: + label: Component + description: Which component does this bug report concern? + multiple: false + options: + - OpenTelemetry.Exporter.Geneva + - OpenTelemetry.Exporter.InfluxDB + - OpenTelemetry.Exporter.Instana + - OpenTelemetry.Exporter.OneCollector + - OpenTelemetry.Exporter.Stackdriver + - OpenTelemetry.Extensions + - OpenTelemetry.Extensions.AWS + - OpenTelemetry.Extensions.Enrichment + - OpenTelemetry.Instrumentation.AspNet + - OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + - OpenTelemetry.Instrumentation.AspNetCore + - OpenTelemetry.Instrumentation.AWS + - OpenTelemetry.Instrumentation.AWSLambda + - OpenTelemetry.Instrumentation.Cassandra + - OpenTelemetry.Instrumentation.ElasticsearchClient + - OpenTelemetry.Instrumentation.EntityFrameworkCore + - OpenTelemetry.Instrumentation.EventCounters + - OpenTelemetry.Instrumentation.GrpcCore + - OpenTelemetry.Instrumentation.GrpcNetClient + - OpenTelemetry.Instrumentation.Hangfire + - OpenTelemetry.Instrumentation.Http + - OpenTelemetry.Instrumentation.MassTransit + - OpenTelemetry.Instrumentation.MySqlData + - OpenTelemetry.Instrumentation.Owin + - OpenTelemetry.Instrumentation.Process + - OpenTelemetry.Instrumentation.Quartz + - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.SqlClient + - OpenTelemetry.Instrumentation.StackExchangeRedis + - OpenTelemetry.Instrumentation.Wcf + - OpenTelemetry.PersistentStorage.Abstractions + - OpenTelemetry.PersistentStorage.FileSystem + - OpenTelemetry.ResourceDetectors.AWS + - OpenTelemetry.ResourceDetectors.Azure + - OpenTelemetry.ResourceDetectors.Container + - OpenTelemetry.ResourceDetectors.Host + - OpenTelemetry.ResourceDetectors.Process + - OpenTelemetry.ResourceDetectors.ProcessRuntime + - OpenTelemetry.Sampler.AWS + - OpenTelemetry.SemanticConventions + validations: + required: true + + - type: textarea + attributes: + label: Package Version + description: List of [all OpenTelemetry NuGet packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are using (e.g. `OpenTelemetry 1.0.2`) + value: | + | Package Name | Version | + | ------------------------------------- | ------- | + | OpenTelemetry.Api | 1.8.0 | + | OpenTelemetry | 1.8.0 | + | TBD | TBD | + validations: + required: true + + - 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) + validations: + required: true + + - type: textarea + attributes: + label: Description + description: What happened? Please provide as much detail as you reasonably can. + validations: + required: true + + - type: textarea + attributes: + label: Steps to Reproduce + description: Provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). We will close the issue if the repro project you share with us is complex or we cannot reproduce the behavior you are reporting. We cannot investigate custom projects, so don't point us to such, please. + validations: + required: true + + - type: textarea + attributes: + label: Expected Result + description: What did you expect to see? + validations: + required: true + + - type: textarea + attributes: + label: Actual Result + description: What did you see instead? + validations: + required: true + + - type: textarea + attributes: + label: Additional Context + description: Any additional information you think may be relevant to this issue. diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md b/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md deleted file mode 100644 index 70bcdb9d2c..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_exporter_geneva.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Exporter.Geneva -about: Issue with OpenTelemetry.Exporter.Geneva -labels: comp:exporter.geneva ---- - -# Issue with OpenTelemetry.Exporter.Geneva - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_influxdb.md b/.github/ISSUE_TEMPLATE/comp_exporter_influxdb.md deleted file mode 100644 index 94ae00bab7..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_exporter_influxdb.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Exporter.InfluxDB -about: Issue with OpenTelemetry.Exporter.InfluxDB -labels: comp:exporter.influxdb ---- - -# Issue with OpenTelemetry.Exporter.InfluxDB - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_instana.md b/.github/ISSUE_TEMPLATE/comp_exporter_instana.md deleted file mode 100644 index 38c3cd5674..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_exporter_instana.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Exporter.Instana -about: Issue with OpenTelemetry.Exporter.Instana -labels: comp:exporter.instana ---- - -# Issue with OpenTelemetry.Exporter.Instana - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_onecollector.md b/.github/ISSUE_TEMPLATE/comp_exporter_onecollector.md deleted file mode 100644 index a18b837921..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_exporter_onecollector.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: OpenTelemetry.Exporter.OneCollector -about: Issue with OpenTelemetry.Exporter.OneCollector -labels: comp:exporter.onecollector ---- - -# Issue with OpenTelemetry.Exporter.OneCollector - -**What type of request is this?** - -* [ ] Feature Request -* [ ] Bug -* [ ] Question - -## Request Details - -**What are the OpenTelemetry packages and versions you are using?** - -_List [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.4.0`)._ - -**What environment are you using?** - -_Please include the runtime versions (e.g. `net462`, `net48`, `net6.0`, `net7.0` -etc.), OS details (e.g.Windows, Linux, etc.), architecture (e.g. 32bit, 64bit, -etc.), and anything else important (e.g. IIS, container, etc.)._ - -**What is the expected behavior?** - -_Describe what you expected to see._ - -**What is the actual behavior?** - -_Describe what you saw instead._ - -**What are the steps to reproduce the issue?** - -_Describe how to reproduce the issue._ - -If you are reporting a non-obvious bug, please create a self-contained project -and apply the minimum required code to result in the issue you're observing. - -We will close this issue if: - -* The repro project you share with us is too complex. We can't investigate - custom projects please try to keep it to just what is needed to demonstrate - the issue. - -* We can't reproduce the behavior you're reporting. - -## Additional Context - -_Include any other context about the bug or feature request here._ diff --git a/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md b/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md deleted file mode 100644 index c520aed3c7..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_exporter_stackdriver.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Exporter.Stackdriver -about: Issue with OpenTelemetry.Exporter.Stackdriver -labels: comp:exporter.stackdriver ---- - -# Issue with OpenTelemetry.Exporter.Stackdriver - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_extensions.md b/.github/ISSUE_TEMPLATE/comp_extensions.md deleted file mode 100644 index d79ed71aeb..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_extensions.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Extensions -about: Issue with OpenTelemetry.Extensions -labels: comp:extensions ---- - -# Issue with OpenTelemetry.Extensions - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_aws.md b/.github/ISSUE_TEMPLATE/comp_extensions_aws.md deleted file mode 100644 index 112dbf18df..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_extensions_aws.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Extensions.AWS -about: Issue with OpenTelemetry.Extensions.AWS -labels: comp:extensions.aws ---- - -# Issue with OpenTelemetry.Extensions.AWS - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_extensions_enrichment.md b/.github/ISSUE_TEMPLATE/comp_extensions_enrichment.md deleted file mode 100644 index 4e10dc3c77..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_extensions_enrichment.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: OpenTelemetry.Extensions.Enrichment -about: Issue with OpenTelemetry.Extensions.Enrichment -labels: comp:extensions.enrichment ---- - -# Issue with OpenTelemetry.Extensions.Enrichment - -**What type of request is this?** - -* [ ] Feature Request -* [ ] Bug -* [ ] Question - -## Request Details - -**What are the OpenTelemetry packages and versions you are using?** - -_List [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.4.0`)._ - -**What environment are you using?** - -_Please include the runtime versions (e.g. `net462`, `net48`, `net6.0`, `net7.0` -etc.), OS details (e.g.Windows, Linux, etc.), architecture (e.g. 32bit, 64bit, -etc.), and anything else important (e.g. IIS, container, etc.)._ - -**What is the expected behavior?** - -_Describe what you expected to see._ - -**What is the actual behavior?** - -_Describe what you saw instead._ - -**What are the steps to reproduce the issue?** - -_Describe how to reproduce the issue._ - -If you are reporting a non-obvious bug, please create a self-contained project -and apply the minimum required code to result in the issue you're observing. - -We will close this issue if: - -* The repro project you share with us is too complex. We can't investigate - custom projects please try to keep it to just what is needed to demonstrate - the issue. - -* We can't reproduce the behavior you're reporting. - -## Additional Context - -_Include any other context about the bug or feature request here._ diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md deleted file mode 100644 index 9942824b40..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.AspNet -about: Issue with OpenTelemetry.Instrumentation.AspNet -labels: comp:instrumentation.aspnet ---- - -# Issue with OpenTelemetry.Instrumentation.AspNet - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md deleted file mode 100644 index d9cefb6957..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnet.telemetryhttpmodule.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule -about: Issue with OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule -labels: comp:instrumentation.aspnet.telemetryhttpmodule ---- - -# Issue with OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md deleted file mode 100644 index bd5d9c2550..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_aspnetcore.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.AspNetCore -about: Issue with OpenTelemetry.Instrumentation.AspNetCore -labels: comp:instrumentation.aspnetcore ---- - -# Issue with OpenTelemetry.Instrumentation.AspNetCore - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_aws.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_aws.md deleted file mode 100644 index f3ec2922ad..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_aws.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.AWS -about: Issue with OpenTelemetry.Instrumentation.AWS -labels: comp:instrumentation.aws ---- - -# Issue with OpenTelemetry.Instrumentation.AWS - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_awslambda.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_awslambda.md deleted file mode 100644 index fd37e8dcfc..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_awslambda.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.AWSLambda -about: Issue with OpenTelemetry.Instrumentation.AWSLambda -labels: comp:instrumentation.awslambda ---- - -# Issue with OpenTelemetry.Instrumentation.AWSLambda - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md deleted file mode 100644 index aeedc67310..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_cassandra.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Cassandra -about: Issue with OpenTelemetry.Instrumentation.Cassandra -labels: comp:instrumentation.cassandra ---- - -# Issue with OpenTelemetry.Instrumentation.Cassandra - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md deleted file mode 100644 index d110e42ea6..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_elasticsearchclient.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.ElasticsearchClient -about: Issue with OpenTelemetry.Instrumentation.ElasticsearchClient -labels: comp:instrumentation.elasticsearchclient ---- - -# Issue with OpenTelemetry.Instrumentation.ElasticsearchClient - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md deleted file mode 100644 index 8b4ad4e9e3..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_entityframeworkcore.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.EntityFrameworkCore -about: Issue with OpenTelemetry.Instrumentation.EntityFrameworkCore -labels: comp:instrumentation.entityframeworkcore ---- - -# Issue with OpenTelemetry.Instrumentation.EntityFrameworkCore - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md deleted file mode 100644 index 5d65375dca..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_eventcounters.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.EventCounters -about: Issue with OpenTelemetry.Instrumentation.EventCounters -labels: comp:instrumentation.eventcounters ---- - -# Issue with OpenTelemetry.Instrumentation.EventCounters - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md deleted file mode 100644 index bdcdbc37dd..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpccore.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.GrpcCore -about: Issue with OpenTelemetry.Instrumentation.GrpcCore -labels: comp:instrumentation.grpccore ---- - -# Issue with OpenTelemetry.Instrumentation.GrpcCore - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md deleted file mode 100644 index fb38e35552..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_grpcnetclient.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.GrpcNetClient -about: Issue with OpenTelemetry.Instrumentation.GrpcNetClient -labels: comp:instrumentation.grpcnetclient ---- - -# Issue with OpenTelemetry.Instrumentation.GrpcNetClient - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md deleted file mode 100644 index c5efb1c3b2..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_hangfire.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Hangfire -about: Issue with OpenTelemetry.Instrumentation.Hangfire -labels: comp:instrumentation.hangfire ---- - -# Issue with OpenTelemetry.Instrumentation.Hangfire - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_http.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_http.md deleted file mode 100644 index 42121d655b..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_http.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Http -about: Issue with OpenTelemetry.Instrumentation.Http -labels: comp:instrumentation.http ---- - -# Issue with OpenTelemetry.Instrumentation.Http - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md deleted file mode 100644 index 4267fc8ecd..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_owin.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Owin -about: Issue with OpenTelemetry.Instrumentation.Owin -labels: comp:instrumentation.owin ---- - -# Issue with OpenTelemetry.Instrumentation.Owin - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md deleted file mode 100644 index 0c26529198..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_process.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Process -about: Issue with OpenTelemetry.Instrumentation.Process -labels: comp:instrumentation.process ---- - -# Issue with OpenTelemetry.Instrumentation.Process - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md deleted file mode 100644 index 628792e62d..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_quartz.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Quartz -about: Issue with OpenTelemetry.Instrumentation.Quartz -labels: comp:instrumentation.quartz ---- - -# Issue with OpenTelemetry.Instrumentation.Quartz - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md deleted file mode 100644 index ae104dbc81..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_runtime.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Runtime -about: Issue with OpenTelemetry.Instrumentation.Runtime -labels: comp:instrumentation.runtime ---- - -# Issue with OpenTelemetry.Instrumentation.Runtime - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md deleted file mode 100644 index c74e59ca99..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_sqlclient.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.SqlClient -about: Issue with OpenTelemetry.Instrumentation.SqlClient -labels: comp:instrumentation.sqlclient ---- - -# Issue with OpenTelemetry.Instrumentation.SqlClient - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md deleted file mode 100644 index 38eb69e5f5..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_stackexchangeredis.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.StackExchangeRedis -about: Issue with OpenTelemetry.Instrumentation.StackExchangeRedis -labels: comp:instrumentation.stackexchangeredis ---- - -# Issue with OpenTelemetry.Instrumentation.StackExchangeRedis - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md b/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md deleted file mode 100644 index d447cc420e..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_instrumentation_wcf.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Instrumentation.Wcf -about: Issue with OpenTelemetry.Instrumentation.Wcf -labels: comp:instrumentation.wcf ---- - -# Issue with OpenTelemetry.Instrumentation.Wcf - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md b/.github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md deleted file mode 100644 index 4f5d588e66..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_persistentstorage.abstractions.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.PersistentStorage.Abstractions -about: Issue with OpenTelemetry.PersistentStorage.Abstractions -labels: comp:persistentstorage.abstractions ---- - -# Issue with OpenTelemetry.PersistentStorage.Abstractions - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md b/.github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md deleted file mode 100644 index 20aec1fc5d..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_persistentstorage_filesystem.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.PersistentStorage.FileSystem -about: Issue with OpenTelemetry.PersistentStorage.FileSystem -labels: comp:persistentstorage.filesystem ---- - -# Issue with PersistentStorage.FileSystem - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md deleted file mode 100644 index 06df0a1b1d..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_aws.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.AWS -about: Issue with OpenTelemetry.ResourceDetectors.AWS -labels: comp:resourcedetectors.aws ---- - -# Issue with OpenTelemetry.ResourceDetectors.AWS - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md deleted file mode 100644 index 35c64b3841..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_azure.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.Azure -about: OpenTelemetry.ResourceDetectors.Azure -labels: comp:resourcedetectors.azure ---- - -# Issue with OpenTelemetry.ResourceDetectors.Azure - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md deleted file mode 100644 index 2a2d04bd8e..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_container.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.Container -about: Issue with OpenTelemetry.ResourceDetectors.Container -labels: comp:resourcedetectors.container ---- - -# Issue with OpenTelemetry.ResourceDetectors.Container - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md deleted file mode 100644 index 757b18890a..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_host.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.Host -about: OpenTelemetry.ResourceDetectors.Host -labels: comp:resourcedetectors.host ---- - -# Issue with OpenTelemetry.ResourceDetectors.Host - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md deleted file mode 100644 index b085c90e45..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_process.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.Process -about: OpenTelemetry.ResourceDetectors.Process -labels: comp:resourcedetectors.process ---- - -# Issue with OpenTelemetry.ResourceDetectors.Process - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md b/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md deleted file mode 100644 index 260e428834..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_resourcedetectors_processruntime.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.ResourceDetectors.ProcessRuntime -about: OpenTelemetry.ResourceDetectors.ProcessRuntime -labels: comp:resourcedetectors.processruntime ---- - -# Issue with OpenTelemetry.ResourceDetectors.ProcessRuntime - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_sampler_aws.md b/.github/ISSUE_TEMPLATE/comp_sampler_aws.md deleted file mode 100644 index 80463dcf30..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_sampler_aws.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.Sampler.AWS -about: Issue with OpenTelemetry.Sampler.AWS -labels: comp:sampler.aws ---- - -# Issue with OpenTelemetry.Sampler.AWS - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/comp_semanticconventions.md b/.github/ISSUE_TEMPLATE/comp_semanticconventions.md deleted file mode 100644 index fbcd20f363..0000000000 --- a/.github/ISSUE_TEMPLATE/comp_semanticconventions.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: OpenTelemetry.SemanticConventions -about: Issue with OpenTelemetry.SemanticConventions -labels: comp:semanticconvention ---- - -# Issue with OpenTelemetry.SemanticConventions - -List of [all OpenTelemetry NuGet -packages](https://www.nuget.org/profiles/OpenTelemetry) and version that you are -using (e.g. `OpenTelemetry 1.3.2`): - -* TBD - -Runtime version (e.g. `net462`, `net48`, `net6.0`, `net7.0` etc. You can -find this information from the `*.csproj` file): - -* TBD - -**Is this a feature request or a bug?** - -* [ ] Feature Request -* [ ] Bug - -**What is the expected behavior?** - -What do you expect to see? - -**What is the actual behavior?** - -What did you see instead? If you are reporting a bug, create a self-contained -project using the template of your choice and apply the minimum required code to -result in the issue you're observing. We will close this issue if: - -* The repro project you share with us is complex. We can't investigate custom - projects, so don't point us to such, please. -* If we can not reproduce the behavior you're reporting. - -## Additional Context - -Add any other context about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..9fecb78998 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,82 @@ +name: Feature request +description: Suggest an idea for this project +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this feature request! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down your request as quickly as possible. + + Before opening a feature request, consider whether the feature should/could be implemented in the [other OpenTelemetry client libraries](https://github.com/open-telemetry/). If so, please [open an issue on opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/issues/new) first. + + - type: dropdown + id: component + attributes: + label: Component + description: Which component does this feature request concern? + multiple: false + options: + - OpenTelemetry.Exporter.Geneva + - OpenTelemetry.Exporter.InfluxDB + - OpenTelemetry.Exporter.Instana + - OpenTelemetry.Exporter.OneCollector + - OpenTelemetry.Exporter.Stackdriver + - OpenTelemetry.Extensions + - OpenTelemetry.Extensions.AWS + - OpenTelemetry.Extensions.Enrichment + - OpenTelemetry.Instrumentation.AspNet + - OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + - OpenTelemetry.Instrumentation.AspNetCore + - OpenTelemetry.Instrumentation.AWS + - OpenTelemetry.Instrumentation.AWSLambda + - OpenTelemetry.Instrumentation.Cassandra + - OpenTelemetry.Instrumentation.ElasticsearchClient + - OpenTelemetry.Instrumentation.EntityFrameworkCore + - OpenTelemetry.Instrumentation.EventCounters + - OpenTelemetry.Instrumentation.GrpcCore + - OpenTelemetry.Instrumentation.GrpcNetClient + - OpenTelemetry.Instrumentation.Hangfire + - OpenTelemetry.Instrumentation.Http + - OpenTelemetry.Instrumentation.MassTransit + - OpenTelemetry.Instrumentation.MySqlData + - OpenTelemetry.Instrumentation.Owin + - OpenTelemetry.Instrumentation.Process + - OpenTelemetry.Instrumentation.Quartz + - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.SqlClient + - OpenTelemetry.Instrumentation.StackExchangeRedis + - OpenTelemetry.Instrumentation.Wcf + - OpenTelemetry.PersistentStorage.Abstractions + - OpenTelemetry.PersistentStorage.FileSystem + - OpenTelemetry.ResourceDetectors.AWS + - OpenTelemetry.ResourceDetectors.Azure + - OpenTelemetry.ResourceDetectors.Container + - OpenTelemetry.ResourceDetectors.Host + - OpenTelemetry.ResourceDetectors.Process + - OpenTelemetry.ResourceDetectors.ProcessRuntime + - OpenTelemetry.Sampler.AWS + - OpenTelemetry.SemanticConventions + + - type: textarea + attributes: + label: Is your feature request related to a problem? + description: If so, provide a concise description of the problem. + + - type: textarea + attributes: + label: What is the expected behavior? + description: Describe the solution you would like. + validations: + required: true + + - type: textarea + attributes: + label: Which alternative solutions or features have you considered? + description: Describe alternatives you've considered. + validations: + required: true + + - type: textarea + attributes: + label: Additional context + description: Any additional information you think may be relevant to this feature request. diff --git a/.github/ISSUE_TEMPLATE/miscellaneous.md b/.github/ISSUE_TEMPLATE/miscellaneous.md deleted file mode 100644 index d48762effb..0000000000 --- a/.github/ISSUE_TEMPLATE/miscellaneous.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: Miscellaneous (anything else) -about: Issue that does not fit into other categories ---- - -# Issue that does not fit into other categories - -**What are you trying to achieve?** - -What do you expect to see? - -**Additional context.** - -Add any other context about the problem here. If you followed an existing -documentation, please share the link to it. diff --git a/.github/workflows/add-labels.yml b/.github/workflows/add-labels.yml new file mode 100644 index 0000000000..a1e8409b60 --- /dev/null +++ b/.github/workflows/add-labels.yml @@ -0,0 +1,25 @@ +name: 'Add labels for component found in bug issue descriptions' +on: + issues: + types: [opened] + +permissions: + issues: write + +jobs: + add-labels: + if: ${{ !github.event.issue.pull_request }} + + runs-on: ubuntu-latest + steps: + - name: check out code + uses: actions/checkout@v4 + + - name: Add labels for component found in bug issue descriptions + shell: pwsh + run: | + .\build\add-labels.ps1 -issueNumber $env:ISSUE_NUMBER -issueBody $env:ISSUE_BODY + env: + GH_TOKEN: ${{ github.token }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + ISSUE_BODY: ${{ github.event.issue.body }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f14ea99a0a..5dabc31e12 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -244,9 +244,9 @@ the main branch. The workflow file should be named as [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L18) with "OpenTelemetry.Instrumentation.FooBar". -* Add an issue template in your PR. You can follow the existing issue templates, - e.g. [comp_extensions](./.github/ISSUE_TEMPLATE/comp_extensions.md). The - maintainer will help to create a new ["comp:" +* Add your component name to the [issue + templates](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/.github/ISSUE_TEMPLATE/) + in your PR. The maintainer will help to create a new ["comp:" label](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/labels?q=comp%3A) once the PR is merged. diff --git a/build/add-labels.ps1 b/build/add-labels.ps1 new file mode 100644 index 0000000000..7d72236c11 --- /dev/null +++ b/build/add-labels.ps1 @@ -0,0 +1,12 @@ +param( + [Parameter(Mandatory=$true)][int]$issueNumber, + [Parameter(Mandatory=$true)][string]$issueBody +) + +$match = [regex]::Match($issueBody, '^[#]+ Component\s*OpenTelemetry\.((?:.|\w+)+)') +if ($match.Success -eq $false) +{ + Return +} + +gh issue edit $issueNumber --add-label $("comp:" + $match.Groups[1].Value.ToLower()) From 87747dcf3a5c4a6765875755c6d78262e36c0fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 13 May 2024 18:24:06 +0200 Subject: [PATCH 1054/1499] [Examples.AspNet] Update dependencies (#1719) --- examples/AspNet/Examples.AspNet.csproj | 6 +++--- examples/AspNet/Views/Web.config | 4 ++-- examples/AspNet/Web.config | 8 ++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 849bb81664..75126f63ed 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -49,9 +49,9 @@ - - - + + + diff --git a/examples/AspNet/Views/Web.config b/examples/AspNet/Views/Web.config index e8fc796ede..03996333d2 100644 --- a/examples/AspNet/Views/Web.config +++ b/examples/AspNet/Views/Web.config @@ -9,7 +9,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index 5dd32873b1..e143e102d4 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -42,6 +42,10 @@ + + + + @@ -50,6 +54,10 @@ + + + + From 2d8a0cace87cd120525de8422d6ccf0a8a004833 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 13 May 2024 13:45:26 -0700 Subject: [PATCH 1055/1499] [Exporter.Geneva] Add exponential histogram support for otlp protobuf format (#1705) --- .../CHANGELOG.md | 5 + .../OtlpProtobuf/FieldNumberConstants.cs | 20 ++ .../OtlpProtobuf/OtlpProtobufSerializer.cs | 101 ++++++- .../OtlpProtobuf/ProtobufSerializerHelper.cs | 9 + .../OtlpProtobufMetricExporterTests.cs | 255 ++++++++++++++++++ 5 files changed, 388 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index a6c66a1d42..f0f84871d9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -7,6 +7,11 @@ `PrivatePreviewEnableOtlpProtobufEncoding=true` in the connection string. ([#1703](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1703)) +* Add support for exporting + exponential histograms when OTLP protobuf encoding is enabled via + `PrivatePreviewEnableOtlpProtobufEncoding=true` in the connection string. + ([#1705](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1705)) + ## 1.8.0-rc.1 Released 2024-May-02 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs index 885044ec76..65d8738ef4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs @@ -76,6 +76,26 @@ internal static class FieldNumberConstants internal const int HistogramDataPoint_min = 11; internal const int HistogramDataPoint_max = 12; + // ExponentialHistogramDataPoint + internal const int ExponentialHistogramDataPoint_attributes = 1; + internal const int ExponentialHistogramDataPoint_start_time_unix_nano = 2; + internal const int ExponentialHistogramDataPoint_time_unix_nano = 3; + internal const int ExponentialHistogramDataPoint_count = 4; + internal const int ExponentialHistogramDataPoint_sum = 5; + internal const int ExponentialHistogramDataPoint_scale = 6; + internal const int ExponentialHistogramDataPoint_zero_count = 7; + internal const int ExponentialHistogramDataPoint_positive = 8; + internal const int ExponentialHistogramDataPoint_negative = 9; + internal const int ExponentialHistogramDataPoint_flags = 10; + internal const int ExponentialHistogramDataPoint_exemplars = 11; + internal const int ExponentialHistogramDataPoint_min = 12; + internal const int ExponentialHistogramDataPoint_max = 13; + internal const int ExponentialHistogramDataPoint_zero_threshold = 14; + + // Buckets + internal const int Bucket_offset = 1; + internal const int Bucket_bucket_counts = 2; + // AnyValue internal const int AnyValue_string_value = 1; internal const int AnyValue_bool_value = 2; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index d836afb309..203be4d72f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -27,6 +27,10 @@ internal sealed class OtlpProtobufSerializer private readonly int prepopulatedHistogramDataPointAttributesLength; + private readonly byte[] prepopulatedExponentialHistogramDataPointAttributes; + + private readonly int prepopulatedExponentialHistogramDataPointAttributesLength; + private int resourceMetricTagAndLengthIndex; private int scopeMetricsTagAndLengthIndex; @@ -73,7 +77,11 @@ public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, Connecti Array.Copy(temp, this.prepopulatedHistogramDataPointAttributes, cursor); this.prepopulatedHistogramDataPointAttributesLength = cursor; - // TODO: exponential histogram. + cursor = 0; + SerializeTags(temp, ref cursor, prepopulatedMetricDimensions, FieldNumberConstants.ExponentialHistogramDataPoint_attributes); + this.prepopulatedExponentialHistogramDataPointAttributes = new byte[cursor]; + Array.Copy(temp, this.prepopulatedExponentialHistogramDataPointAttributes, cursor); + this.prepopulatedExponentialHistogramDataPointAttributesLength = cursor; } try @@ -419,7 +427,96 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) case MetricType.ExponentialHistogram: { - // TODO + cursor = this.instrumentValueIndex; + + // Write aggregationTemporality tag + ProtobufSerializerHelper.WriteEnumWithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogram_aggregation_temporality, metric.Temporality == AggregationTemporality.Cumulative ? 2 : 1); + + this.metricPointTagAndLengthIndex = cursor; + this.metricPointValueIndex = cursor + TagAndLengthSize; + + foreach (var metricPoint in metric.GetMetricPoints()) + { + try + { + // Reset cursor to write new metricPoint + cursor = this.metricPointValueIndex; + + var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_start_time_unix_nano, startTime); + + var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_time_unix_nano, endTime); + + SerializeTags(buffer, ref cursor, metricPoint.Tags, FieldNumberConstants.ExponentialHistogramDataPoint_attributes); + + if (this.prepopulatedExponentialHistogramDataPointAttributes != null) + { + Array.Copy(this.prepopulatedExponentialHistogramDataPointAttributes, 0, buffer, cursor, this.prepopulatedExponentialHistogramDataPointAttributesLength); + cursor += this.prepopulatedExponentialHistogramDataPointAttributesLength; + } + + var sum = metricPoint.GetHistogramSum(); + + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_sum, sum); + + var count = (ulong)metricPoint.GetHistogramCount(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_count, count); + + if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + { + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_min, min); + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_max, max); + } + + var exponentialHistogramData = metricPoint.GetExponentialHistogramData(); + + ProtobufSerializerHelper.WriteSInt32WithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_scale, exponentialHistogramData.Scale); + + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_zero_count, (ulong)exponentialHistogramData.ZeroCount); + + var positiveBucketIndex = cursor; + cursor += TagAndLengthSize; + var positiveBucketValueIndex = cursor; + + ProtobufSerializerHelper.WriteSInt32WithTag(buffer, ref cursor, FieldNumberConstants.Bucket_offset, exponentialHistogramData.PositiveBuckets.Offset); + + foreach (var bucketCount in exponentialHistogramData.PositiveBuckets) + { + ProtobufSerializerHelper.WriteInt64WithTag(buffer, ref cursor, FieldNumberConstants.Bucket_bucket_counts, (ulong)bucketCount); + } + + // write Bucket + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref positiveBucketIndex, cursor - positiveBucketValueIndex, FieldNumberConstants.ExponentialHistogramDataPoint_positive, WireType.LEN); + +#if EXPOSE_EXPERIMENTAL_FEATURES + if (metricPoint.TryGetExemplars(out var exemplars)) + { + foreach (ref readonly var exemplar in exemplars) + { + this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.ExponentialHistogramDataPoint_exemplars); + } + } +#endif + + var metricPointStartPosition = this.metricPointTagAndLengthIndex; + + // Write exponentialhistogramdatapoint {Repeated field} + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, FieldNumberConstants.ExponentialHistogram_data_points, WireType.LEN); + + // Finish writing current batch + this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); + + // Send metricPoint + this.SendMetricPoint(buffer, ref cursor); + } + catch (Exception ex) + { + this.metricExportResult = ExportResult.Failure; + ExporterEventSource.Log.FailedToSerializeMetric(metric.Name, ex); + } + } + break; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs index 41e59c2ff8..f9eb43ddc1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -62,6 +62,15 @@ internal static void WriteInt64WithTag(byte[] buffer, ref int cursor, int fieldN WriteVarint64(buffer, ref cursor, value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void WriteSInt32WithTag(byte[] buffer, ref int cursor, int fieldNumber, int value) + { + WriteTag(buffer, ref cursor, fieldNumber, WireType.VARINT); + + // https://protobuf.dev/programming-guides/encoding/#signed-ints + WriteVarint32(buffer, ref cursor, (uint)((value << 1) ^ (value >> 31))); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void WriteDoubleWithTag(byte[] buffer, ref int cursor, int fieldNumber, double value) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 6fbef258de..63d47cf648 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -1329,6 +1329,261 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] } } + [Theory] + [InlineData(123.45, true, true, true, true)] + [InlineData(123.45, true, true, true, false)] + [InlineData(123.45, true, true, false, true)] + [InlineData(123.45, true, true, false, false)] + [InlineData(123.45, true, false, true, true)] + [InlineData(123.45, true, false, true, false)] + [InlineData(123.45, true, false, false, true)] + [InlineData(123.45, true, false, false, false)] + [InlineData(123.45, false, true, true, true)] + [InlineData(123.45, false, true, true, false)] + [InlineData(123.45, false, true, false, true)] + [InlineData(123.45, false, true, false, false)] + [InlineData(123.45, false, false, true, true)] + [InlineData(123.45, false, false, true, false)] + [InlineData(123.45, false, false, false, true)] + [InlineData(123.45, false, false, false, false)] + [InlineData(-123.45, true, true, true, true)] + [InlineData(-123.45, true, true, true, false)] + [InlineData(-123.45, true, true, false, true)] + [InlineData(-123.45, true, true, false, false)] + [InlineData(-123.45, true, false, true, true)] + [InlineData(-123.45, true, false, true, false)] + [InlineData(-123.45, true, false, false, true)] + [InlineData(-123.45, true, false, false, false)] + [InlineData(-123.45, false, true, true, true)] + [InlineData(-123.45, false, true, true, false)] + [InlineData(-123.45, false, true, false, true)] + [InlineData(-123.45, false, true, false, false)] + [InlineData(-123.45, false, false, true, true)] + [InlineData(-123.45, false, false, true, false)] + [InlineData(-123.45, false, false, false, true)] + [InlineData(-123.45, false, false, false, false)] + public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleValue, bool addPrepopulatedDimensions, bool addAccountAndNamespace, bool isExemplarsEnabled, bool isTracingEnabled) + { + Activity activity = null; + + if (isTracingEnabled) + { + activity = new Activity("Custom Activity"); + activity.Start(); + } + + using var meter = new Meter(nameof(this.ExponentialHistogramSerializationSingleMetricPoint), "0.0.1"); + + var exportedItems = new List(); + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; + + Dictionary resourceAttributes = new Dictionary + { + { "TestResourceKey", "TestResourceValue" }, + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, + }; + + string expectedAccount = "TestAccount"; + string expectedNamespace = "TestNameSpace"; + Dictionary accountAndNamespace = new Dictionary + { + { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, + { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, + }; + + var resourceBuilder = ResourceBuilder.CreateDefault().Clear() + .AddAttributes(resourceAttributes); + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder() + .SetResourceBuilder(resourceBuilder) + .AddMeter(nameof(this.ExponentialHistogramSerializationSingleMetricPoint)) + .AddReader(inMemoryReader); + + if (isExemplarsEnabled) + { +#if EXPOSE_EXPERIMENTAL_FEATURES + meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); +#endif + } + + meterProviderBuilder.AddView(instrument => + { +#if EXPOSE_EXPERIMENTAL_FEATURES + return new Base2ExponentialBucketHistogramConfiguration() { TagKeys = TagKeys }; +#else + return new Base2ExponentialBucketHistogramConfiguration(); +#endif + }); + + var meterProvider = meterProviderBuilder.Build(); + + var instrumentName = "doubleExponentialHistogram"; + var histogram = meter.CreateHistogram(instrumentName); + + if (isExemplarsEnabled) + { + histogram.Record(doubleValue.Value, this.exemplarTagList); + histogram.Record(0, this.exemplarTagList); + } + else + { + histogram.Record(doubleValue.Value, this.TagList); + histogram.Record(0, this.TagList); + } + + meterProvider.ForceFlush(); + + var buffer = new byte[65360]; + + var testTransport = new TestTransport(); + + ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); + var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); + + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + + Assert.Single(testTransport.ExportedItems); + + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + request.MergeFrom(testTransport.ExportedItems[0]); + + Assert.Single(request.ResourceMetrics); + + Assert.NotNull(request.ResourceMetrics[0].Resource); + + AssertOtlpAttributes(addAccountAndNamespace ? resourceAttributes.Concat(accountAndNamespace) : resourceAttributes, request.ResourceMetrics[0].Resource.Attributes); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics); + + var scope = request.ResourceMetrics[0].ScopeMetrics[0]; + + Assert.Equal(meter.Name, scope.Scope.Name); + + Assert.Single(request.ResourceMetrics[0].ScopeMetrics[0].Metrics); + + var metric = request.ResourceMetrics[0].ScopeMetrics[0].Metrics[0]; + + Assert.Equal(instrumentName, metric.Name); + + Assert.NotNull(metric.ExponentialHistogram); + + Assert.Single(metric.ExponentialHistogram.DataPoints); + + var dataPoint = metric.ExponentialHistogram.DataPoints[0]; + + // Assert time + var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + + Assert.Equal((ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(), dataPoint.StartTimeUnixNano); + Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); + + Assert.Equal(20, dataPoint.Scale); + Assert.Equal(1UL, dataPoint.ZeroCount); + if (doubleValue > 0) + { + Assert.Equal(2UL, dataPoint.Count); + } + else + { + Assert.Equal(1UL, dataPoint.Count); + } + + if (doubleValue > 0) + { + Assert.Equal(doubleValue, dataPoint.Max); + Assert.Equal(0, dataPoint.Min); + Assert.Equal(doubleValue, dataPoint.Sum); + Assert.Null(dataPoint.Negative); + Assert.True(dataPoint.Positive.Offset > 0); + Assert.Single(dataPoint.Positive.BucketCounts); + Assert.Equal(1UL, dataPoint.Positive.BucketCounts[0]); + } + else + { + Assert.Equal(0, dataPoint.Min); + Assert.Equal(0, dataPoint.Max); + Assert.Equal(0, dataPoint.Sum); + Assert.Null(dataPoint.Negative); + Assert.True(dataPoint.Positive.Offset == 0); + Assert.Empty(dataPoint.Positive.BucketCounts); + } + + if (addPrepopulatedDimensions) + { + AssertOtlpAttributes(this.TagList.Concat(prepopulatedMetricDimensions), dataPoint.Attributes); + } + else + { + AssertOtlpAttributes(this.TagList, dataPoint.Attributes); + } + +#if EXPOSE_EXPERIMENTAL_FEATURES + if (isExemplarsEnabled) + { + // Exemplars are only emitted for positive/0 values. + if (doubleValue.Value > 0) + { + Assert.Equal(2, dataPoint.Exemplars.Count); + } + else + { + Assert.Single(dataPoint.Exemplars); + } + + metricPoint.TryGetExemplars(out var exemplars); + + var exemplarsEnumerator = exemplars.GetEnumerator(); + + double[] exemplarValues = doubleValue.Value > 0 ? new double[] { doubleValue.Value, 0 } : new double[] { 0 }; + + int exemplarValuesIndex = 0; + + foreach (var exemplar in dataPoint.Exemplars) + { + exemplarsEnumerator.MoveNext(); + + var actualExemplar = exemplarsEnumerator.Current; + + Assert.Equal((ulong)actualExemplar.Timestamp.ToUnixTimeNanoseconds(), exemplar.TimeUnixNano); + + Assert.Equal(exemplarValues[exemplarValuesIndex], exemplar.AsDouble); + + if (isTracingEnabled) + { + var spanIdBytes = new byte[8]; + activity.SpanId.CopyTo(spanIdBytes); + + Assert.True(spanIdBytes.SequenceEqual(exemplar.SpanId)); + + var traceIdBytes = new byte[16]; + activity.TraceId.CopyTo(traceIdBytes); + + Assert.True(traceIdBytes.SequenceEqual(exemplar.TraceId)); + } + else + { + Assert.Equal(ByteString.Empty, exemplar.SpanId); + Assert.Equal(ByteString.Empty, exemplar.TraceId); + } + + AssertOtlpAttributes([new KeyValuePair("zfilteredKey1", "zfilteredValue1")], exemplar.FilteredAttributes); + + exemplarValuesIndex++; + } + } + else + { + Assert.Empty(dataPoint.Exemplars); + } +#endif + } + internal static void AssertOtlpAttributes( IEnumerable> expected, RepeatedField actual) From 205e8db96bbadee8f938b0d5edef934a5ff3be61 Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 13 May 2024 14:09:39 -0700 Subject: [PATCH 1056/1499] [repo] nit: fix url (#1722) --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 8b9c393599..229f08131b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -7,7 +7,7 @@ body: value: | Thanks for taking the time to fill out this bug report! Please make sure to fill out the entire form below, providing as much context as you can in order to help us triage and track down the bug as quickly as possible. - Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-dotnet/issues?q=is%3Aissue+is%3Aopen+label%3Abug) to see if an existing issue covers the bug. + Before filing a bug, please be sure you have searched through [existing bugs](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues?q=is%3Aissue+is%3Aopen+label%3Abug) to see if an existing issue covers the bug. - type: dropdown id: component From de38aecbabc195fbbb29a5078b0b66513638ac9c Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 13 May 2024 15:08:16 -0700 Subject: [PATCH 1057/1499] [Exporter.Geneva] Prepare release 1.8.0-rc.2 (#1721) --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f0f84871d9..f2f741fbcd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0-rc.2 + +Released 2024-May-13 + * **Experimental (pre-release builds only)**: Add support for exporting exemplars when OTLP protobuf encoding is enabled via `PrivatePreviewEnableOtlpProtobufEncoding=true` in the connection string. From ec134bbd970f0a457e0775eb44472b7162ec4b36 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Tue, 14 May 2024 12:55:41 -0400 Subject: [PATCH 1058/1499] [Resources.Gcp] Add Google Cloud Platform resource detector (#1691) --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + .github/codecov.yml | 5 + .github/component_owners.yml | 6 ++ .github/workflows/ci.yml | 18 +++- .github/workflows/package-Resources.Gcp.yml | 21 ++++ .../Projects/OpenTelemetry.Resources.Gcp.proj | 32 +++++++ opentelemetry-dotnet-contrib.sln | 15 +++ .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 2 + .../AssemblyInfo.cs | 10 ++ src/OpenTelemetry.Resources.Gcp/CHANGELOG.md | 9 ++ .../GcpResourceBuilderExtensions.cs | 24 +++++ .../GcpResourceDetector.cs | 92 ++++++++++++++++++ .../OpenTelemetry.Resources.Gcp.csproj | 25 +++++ src/OpenTelemetry.Resources.Gcp/README.md | 85 ++++++++++++++++ .../ResourceAttributeConstants.cs | 14 +++ src/Shared/ResourceSemanticConventions.cs | 1 + .../GcpResourceDetectorTests.cs | 96 +++++++++++++++++++ .../GlobalUsings.cs | 4 + .../OpenTelemetry.Resources.Gcp.Tests.csproj | 18 ++++ 21 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/package-Resources.Gcp.yml create mode 100644 build/Projects/OpenTelemetry.Resources.Gcp.proj create mode 100644 src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Resources.Gcp/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Resources.Gcp/CHANGELOG.md create mode 100644 src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs create mode 100644 src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj create mode 100644 src/OpenTelemetry.Resources.Gcp/README.md create mode 100644 src/OpenTelemetry.Resources.Gcp/ResourceAttributeConstants.cs create mode 100644 test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs create mode 100644 test/OpenTelemetry.Resources.Gcp.Tests/GlobalUsings.cs create mode 100644 test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 229f08131b..d0f4aa71b2 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -54,6 +54,7 @@ body: - OpenTelemetry.ResourceDetectors.Host - OpenTelemetry.ResourceDetectors.Process - OpenTelemetry.ResourceDetectors.ProcessRuntime + - OpenTelemetry.Resources.Gcp - OpenTelemetry.Sampler.AWS - OpenTelemetry.SemanticConventions validations: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 9fecb78998..2d8c7483d7 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -54,6 +54,7 @@ body: - OpenTelemetry.ResourceDetectors.Host - OpenTelemetry.ResourceDetectors.Process - OpenTelemetry.ResourceDetectors.ProcessRuntime + - OpenTelemetry.Resources.Gcp - OpenTelemetry.Sampler.AWS - OpenTelemetry.SemanticConventions diff --git a/.github/codecov.yml b/.github/codecov.yml index 93c6e5eb08..3981524084 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -119,6 +119,11 @@ flags: paths: - src/OpenTelemetry.ResourceDetectors.Azure + unittests-Resources.Gcp: + carryforward: true + paths: + - src/OpenTelemetry.Resources.Gcp + unittests-ResourceDetectors.Host: carryforward: true paths: diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 73aba2c284..7df093a797 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -79,6 +79,9 @@ components: src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: - Kielek - lachmatt + src/OpenTelemetry.Resources.Gcp/: + - matt-hensley + - pyohannes src/OpenTelemetry.Sampler.AWS/: - srprash - atshaw43 @@ -169,6 +172,9 @@ components: test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: - Kielek - lachmatt + test/OpenTelemetry.Resources.Gcp.Tests/: + - matt-hensley + - pyohannes test/OpenTelemetry.Sampler.AWS.Tests/: - srprash - atshaw43 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6e0614a40..f07c34505b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,7 @@ jobs: eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] + gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] grpcnetclient: ['*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', '!**/*.md'] host: ['*/OpenTelemetry.ResourceDetectors.Host*/**', '!**/*.md'] http: ['*/OpenTelemetry.Instrumentation.Http*/**', '!**/*.md'] @@ -59,6 +60,7 @@ jobs: '!*/OpenTelemetry.ResourceDetectors.Process.Tests/**', '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', + '!*/OpenTelemetry.Resources.Gcp*/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions/**', @@ -167,6 +169,17 @@ jobs: project-name: OpenTelemetry.Exporter.Geneva code-cov-name: Exporter.Geneva + build-test-gcp: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'gcp') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Resources.Gcp + code-cov-name: Resources.Gcp + build-test-grpcnetclient: needs: detect-changes if: | @@ -379,7 +392,8 @@ jobs: OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, OpenTelemetry.ResourceDetectors.Host.Tests.csproj, OpenTelemetry.ResourceDetectors.Process.Tests.csproj, - OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj + OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj, + OpenTelemetry.Resources.Gcp.Tests.csproj $failedProjects = @() @@ -426,6 +440,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'aws') || contains(needs.detect-changes.outputs.changes, 'azure') || contains(needs.detect-changes.outputs.changes, 'extensions') + || contains(needs.detect-changes.outputs.changes, 'gcp') || contains(needs.detect-changes.outputs.changes, 'grpcnetclient') || contains(needs.detect-changes.outputs.changes, 'host') || contains(needs.detect-changes.outputs.changes, 'http') @@ -454,6 +469,7 @@ jobs: build-test-eventcounters, build-test-extensions, build-test-geneva, + build-test-gcp, build-test-grpcnetclient, build-test-host, build-test-http, diff --git a/.github/workflows/package-Resources.Gcp.yml b/.github/workflows/package-Resources.Gcp.yml new file mode 100644 index 0000000000..a10b917607 --- /dev/null +++ b/.github/workflows/package-Resources.Gcp.yml @@ -0,0 +1,21 @@ +name: Pack OpenTelemetry.Resources.Gcp + +on: + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'warning' + push: + tags: + - 'Resources.Gcp-*' # trigger when we create a tag with prefix "Resources.Gcp-" + +jobs: + call-build-test-pack: + permissions: + contents: write + uses: ./.github/workflows/Component.Package.yml + with: + project-name: OpenTelemetry.Resources.Gcp + secrets: inherit diff --git a/build/Projects/OpenTelemetry.Resources.Gcp.proj b/build/Projects/OpenTelemetry.Resources.Gcp.proj new file mode 100644 index 0000000000..19364c3155 --- /dev/null +++ b/build/Projects/OpenTelemetry.Resources.Gcp.proj @@ -0,0 +1,32 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 0809cbac97..e8bfaa1c85 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -338,6 +338,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj + build\Projects\OpenTelemetry.Resources.Gcp.proj = build\Projects\OpenTelemetry.Resources.Gcp.proj build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject @@ -355,6 +356,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.Abstractions.Tests", "test\OpenTelemetry.PersistentStorage.Abstractions.Tests\OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj", "{7AD707F9-DC6D-430A-8834-D5DCD517BF6E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Gcp", "src\OpenTelemetry.Resources.Gcp\OpenTelemetry.Resources.Gcp.csproj", "{CBC6D677-D1FF-470E-A244-477E8616A245}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Gcp.Tests", "test\OpenTelemetry.Resources.Gcp.Tests\OpenTelemetry.Resources.Gcp.Tests.csproj", "{EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.SqlClient", "src\OpenTelemetry.Instrumentation.SqlClient\OpenTelemetry.Instrumentation.SqlClient.csproj", "{737D1A9E-5A1A-4F4F-830B-E98ED100994C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.SqlClient.Tests", "test\OpenTelemetry.Instrumentation.SqlClient.Tests\OpenTelemetry.Instrumentation.SqlClient.Tests.csproj", "{9C996130-74D7-4FB7-8277-2EE6EBA2BFA6}" @@ -749,6 +754,14 @@ Global {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Debug|Any CPU.Build.0 = Debug|Any CPU {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.ActiveCfg = Release|Any CPU {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.Build.0 = Release|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Release|Any CPU.Build.0 = Release|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Release|Any CPU.Build.0 = Release|Any CPU {0156E342-CE63-46F5-992D-691A7CCB50F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0156E342-CE63-46F5-992D-691A7CCB50F8}.Debug|Any CPU.Build.0 = Debug|Any CPU {0156E342-CE63-46F5-992D-691A7CCB50F8}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -882,6 +895,8 @@ Global {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {7371E920-ECD0-403A-A009-7A1A301D9763} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {CBC6D677-D1FF-470E-A244-477E8616A245} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {0156E342-CE63-46F5-992D-691A7CCB50F8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2E1A5759-1431-4724-8885-3E9447FBF617} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} diff --git a/src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..2cd50017d2 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Resources.GcpResourceBuilderExtensions +static OpenTelemetry.Resources.GcpResourceBuilderExtensions.AddGcpDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.Resources.Gcp/AssemblyInfo.cs b/src/OpenTelemetry.Resources.Gcp/AssemblyInfo.cs new file mode 100644 index 0000000000..0751701190 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Gcp.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Gcp.Tests")] +#endif diff --git a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md new file mode 100644 index 0000000000..e1852ed3a7 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## Unreleased + +* Add Google Cloud Platform resource detector for GKE, GAE, GCR, and GCE. Dectector + is accessible via `AddGcpDetector` extension method on `ResourceBuilder`. + ([#1691](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1691)) + +For more details, please refer to the [README](README.md). diff --git a/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs new file mode 100644 index 0000000000..154242bb04 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; +using OpenTelemetry.Resources.Gcp; + +namespace OpenTelemetry.Resources; + +/// +/// Extension methods to simplify registering of Google Cloud Platform resource detectors. +/// +public static class GcpResourceBuilderExtensions +{ + /// + /// Enables Google Cloud Platform resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddGcpDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new GcpResourceDetector()); + } +} diff --git a/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs b/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs new file mode 100644 index 0000000000..de5d212484 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs @@ -0,0 +1,92 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections.Generic; +using Google.Api.Gax; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Resources.Gcp; + +/// +/// Resource detector for Google Cloud Platform (GCP). +/// +internal sealed class GcpResourceDetector : IResourceDetector +{ + /// + public Resource Detect() + { + var platform = Platform.Instance(); + + if (platform == null || platform.ProjectId == null) + { + return Resource.Empty; + } + + var attributeList = platform.Type switch + { + PlatformType.Gke => ExtractGkeResourceAttributes(platform), + PlatformType.CloudRun => ExtractCloudRunResourceAttributes(platform), + PlatformType.Gae => ExtractGaeResourceAttributes(platform), + PlatformType.Gce => ExtractGceResourceAttributes(platform), + _ => ExtractGceResourceAttributes(platform), + }; + + return new Resource(attributeList); + } + + internal static List> ExtractGkeResourceAttributes(Platform platform) + { + List> attributeList = new() + { + new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), + new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), + new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGkePlatformValue), + new(ResourceSemanticConventions.AttributeCloudZone, platform.GkeDetails.Zone), + new(ResourceSemanticConventions.AttributeHostId, platform.GkeDetails.InstanceId), + new(ResourceSemanticConventions.AttributeK8sCluster, platform.GkeDetails.ClusterName), + new(ResourceSemanticConventions.AttributeK8sNamespace, platform.GkeDetails.NamespaceId), + new(ResourceSemanticConventions.AttributeK8sPod, platform.GkeDetails.HostName), + }; + + return attributeList; + } + + internal static List> ExtractCloudRunResourceAttributes(Platform platform) + { + List> attributeList = new() + { + new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), + new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), + new(ResourceSemanticConventions.AttributeCloudAvailabilityZone, platform.CloudRunDetails.Zone), + new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpCloudRunPlatformValue), + new(ResourceSemanticConventions.AttributeCloudRegion, platform.CloudRunDetails.Region), + }; + + return attributeList; + } + + internal static List> ExtractGaeResourceAttributes(Platform platform) + { + List> attributeList = new() + { + new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), + new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), + new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGaePlatformValue), + }; + return attributeList; + } + + internal static List> ExtractGceResourceAttributes(Platform platform) + { + List> attributeList = new() + { + new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), + new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), + new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGcePlatformValue), + new(ResourceSemanticConventions.AttributeHostId, platform.GceDetails.InstanceId), + new(ResourceSemanticConventions.AttributeCloudAvailabilityZone, platform.GceDetails.Location), + }; + + return attributeList; + } +} diff --git a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj new file mode 100644 index 0000000000..e0b3c71433 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj @@ -0,0 +1,25 @@ + + + net6.0;netstandard2.0 + OpenTelemetry Resource Detectors for Google Cloud Platform environments + $(PackageTags);ResourceDetector + Resources.Gcp- + + + + + true + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Resources.Gcp/README.md b/src/OpenTelemetry.Resources.Gcp/README.md new file mode 100644 index 0000000000..3171fa579c --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/README.md @@ -0,0 +1,85 @@ +# Resource Detectors for Google Cloud Platform environments + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Gcp)](https://www.nuget.org/packages/OpenTelemetry.Resources.Gcp) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Azure)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) + +This package contains [Resource +Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) +for applications running in Google Cloud Platform environments. + +## Installation + +```shell +dotnet add package --prerelease OpenTelemetry.Resources.Gcp +``` + +```csharp +using OpenTelemetry; +using OpenTelemetry.Resources; + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + // other configurations + .ConfigureResource(resource => resource.AddGcpDetector()) + .Build(); + +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .ConfigureResource(resource => resource.AddGcpDetector()) + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder + .CreateDefault() + .AddGcpDetector()); + }); +}); +``` + +## Resource Attributes + +The following OpenTelemetry semantic conventions will be detected depending on +which Google Cloud Platform environment an application is running in. + +### Google Kubernetes Engine + +|-------------------------|-----------------------| +| Attribute | Value | +| cloud.provider | gcp | +| cloud.platform | gcp_kubernetes_engine | +| cloud.account.id | auto | +| cloud.availability_zone | auto | +| host.id | auto | +| k8s.cluster.name | auto | +| k8s.namespace.name | auto | +| k8s.pod.name | auto | + +### Google App Engine + +|-------------------------|----------------| +| Attribute | Value | +| cloud.provider | gcp | +| cloud.platform | gcp_app_engine | +| cloud.account.id | auto | + +### Google Cloud Run + +|-------------------------|---------------| +| Attribute | Value | +| cloud.provider | gcp | +| cloud.platform | gcp_cloud_run | +| cloud.account.id | auto | +| cloud.availability_zone | auto | +| cloud.region | auto | + +### Google Compute Engine + +|-------------------------|--------------------| +| Attribute | Value | +| cloud.provider | gcp | +| cloud.platform | gcp_compute_engine | +| cloud.account.id | auto | +| cloud.availability_zone | auto | +| host.id | auto | diff --git a/src/OpenTelemetry.Resources.Gcp/ResourceAttributeConstants.cs b/src/OpenTelemetry.Resources.Gcp/ResourceAttributeConstants.cs new file mode 100644 index 0000000000..6c9a0b8c36 --- /dev/null +++ b/src/OpenTelemetry.Resources.Gcp/ResourceAttributeConstants.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Resources.Gcp; + +internal sealed class ResourceAttributeConstants +{ + // GCP resource attributes constant values + internal const string GcpCloudProviderValue = "gcp"; + internal const string GcpGcePlatformValue = "gcp_compute_engine"; + internal const string GcpGaePlatformValue = "gcp_app_engine"; + internal const string GcpCloudRunPlatformValue = "gcp_cloud_run"; + internal const string GcpGkePlatformValue = "gcp_kubernetes_engine"; +} diff --git a/src/Shared/ResourceSemanticConventions.cs b/src/Shared/ResourceSemanticConventions.cs index 4b4aa6a9ea..22903d04bc 100644 --- a/src/Shared/ResourceSemanticConventions.cs +++ b/src/Shared/ResourceSemanticConventions.cs @@ -44,6 +44,7 @@ internal static class ResourceSemanticConventions public const string AttributeProcessUsername = "process.username"; public const string AttributeCloudAccount = "cloud.account.id"; + public const string AttributeCloudAvailabilityZone = "cloud.availability_zone"; public const string AttributeCloudPlatform = "cloud.platform"; public const string AttributeCloudProvider = "cloud.provider"; public const string AttributeCloudRegion = "cloud.region"; diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs b/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs new file mode 100644 index 0000000000..6369d7fda2 --- /dev/null +++ b/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs @@ -0,0 +1,96 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Linq; +using Google.Api.Gax; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Resources.Gcp.Tests; + +public class GcpResourceDetectorTests +{ + [Fact] + public void TestExtractGkeResourceAttributes() + { + var details = new GkePlatformDetails( + metadataJson: "json", + projectId: "projectId", + clusterName: "clusterName", + location: "location", + hostName: "hostName", + instanceId: "instanceId", + zone: "us-central1-a", + namespaceId: "namespaceId", + podId: "podId", + containerName: "containerName", + clusterLocation: "clusterLocation"); + var platform = new Platform(details); + var attrs = GcpResourceDetector.ExtractGkeResourceAttributes(platform).ToDictionary(x => x.Key, x => x.Value); + Assert.NotNull(attrs); + Assert.Equal(8, attrs.Count); + Assert.Equal(ResourceAttributeConstants.GcpCloudProviderValue, attrs[ResourceSemanticConventions.AttributeCloudProvider]); + Assert.Equal("projectId", attrs[ResourceSemanticConventions.AttributeCloudAccount]); + Assert.Equal(ResourceAttributeConstants.GcpGkePlatformValue, attrs[ResourceSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("us-central1-a", attrs[ResourceSemanticConventions.AttributeCloudZone]); + Assert.Equal("instanceId", attrs[ResourceSemanticConventions.AttributeHostId]); + Assert.Equal("clusterName", attrs[ResourceSemanticConventions.AttributeK8sCluster]); + Assert.Equal("namespaceId", attrs[ResourceSemanticConventions.AttributeK8sNamespace]); + Assert.Equal("hostName", attrs[ResourceSemanticConventions.AttributeK8sPod]); + } + + [Fact] + public void TestExtractCloudRunResourceAttributes() + { + var details = new CloudRunPlatformDetails( + metadataJson: "json", + projectId: "projectId", + zone: "us-central1-a", + serviceName: "serviceName", + revisionName: "revisionName", + configurationName: "configurationName"); + var platform = new Platform(details); + var attrs = GcpResourceDetector.ExtractCloudRunResourceAttributes(platform).ToDictionary(x => x.Key, x => x.Value); + Assert.NotNull(attrs); + Assert.Equal(5, attrs.Count); + Assert.Equal(ResourceAttributeConstants.GcpCloudProviderValue, attrs[ResourceSemanticConventions.AttributeCloudProvider]); + Assert.Equal("projectId", attrs[ResourceSemanticConventions.AttributeCloudAccount]); + Assert.Equal("us-central1-a", attrs[ResourceSemanticConventions.AttributeCloudAvailabilityZone]); + Assert.Equal(ResourceAttributeConstants.GcpCloudRunPlatformValue, attrs[ResourceSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("us-central1", attrs[ResourceSemanticConventions.AttributeCloudRegion]); + } + + [Fact] + public void TestExtractGaeResourceAttributes() + { + var details = new GaePlatformDetails( + gcloudProject: "gcloudProject", + gaeInstance: "gaeInstance", + gaeService: "gaeService", + gaeVersion: "gaeVersion"); + var platform = new Platform(details); + var attrs = GcpResourceDetector.ExtractGaeResourceAttributes(platform).ToDictionary(x => x.Key, x => x.Value); + Assert.NotNull(attrs); + Assert.Equal(3, attrs.Count); + Assert.Equal(ResourceAttributeConstants.GcpCloudProviderValue, attrs[ResourceSemanticConventions.AttributeCloudProvider]); + Assert.Equal("gcloudProject", attrs[ResourceSemanticConventions.AttributeCloudAccount]); + Assert.Equal(ResourceAttributeConstants.GcpGaePlatformValue, attrs[ResourceSemanticConventions.AttributeCloudPlatform]); + } + + [Fact] + public void TestExtractGceResourceAttributes() + { + var details = new GcePlatformDetails( + metadataJson: "json", + projectId: "projectId", + instanceId: "instanceId", + zoneName: "projects/12345/zones/us-central1-a"); + var platform = new Platform(details); + var attrs = GcpResourceDetector.ExtractGceResourceAttributes(platform).ToDictionary(x => x.Key, x => x.Value); + Assert.NotNull(attrs); + Assert.Equal(5, attrs.Count); + Assert.Equal(ResourceAttributeConstants.GcpCloudProviderValue, attrs[ResourceSemanticConventions.AttributeCloudProvider]); + Assert.Equal("projectId", attrs[ResourceSemanticConventions.AttributeCloudAccount]); + Assert.Equal(ResourceAttributeConstants.GcpGcePlatformValue, attrs[ResourceSemanticConventions.AttributeCloudPlatform]); + Assert.Equal("instanceId", attrs[ResourceSemanticConventions.AttributeHostId]); + } +} diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/GlobalUsings.cs b/test/OpenTelemetry.Resources.Gcp.Tests/GlobalUsings.cs new file mode 100644 index 0000000000..c9112be5f0 --- /dev/null +++ b/test/OpenTelemetry.Resources.Gcp.Tests/GlobalUsings.cs @@ -0,0 +1,4 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +global using Xunit; diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj new file mode 100644 index 0000000000..e1df281415 --- /dev/null +++ b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj @@ -0,0 +1,18 @@ + + + + Unit test project for GCP Detector for OpenTelemetry + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + + + + + From cd487412ded13fa5f1ee00987ab04da67ce8ad21 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 14 May 2024 14:56:57 -0700 Subject: [PATCH 1059/1499] [repo] Build script organization and additions (#1800) --- .github/workflows/add-labels.yml | 2 +- .github/workflows/sanitycheck.yml | 2 +- .github/workflows/verifyaotcompat.yml | 2 +- build/{ => scripts}/add-labels.ps1 | 0 build/scripts/finalize-publicapi.ps1 | 39 +++++++++++++++++++ build/{ => scripts}/sanitycheck.py | 0 .../{ => scripts}/test-aot-compatibility.ps1 | 3 +- build/scripts/update-changelogs.ps1 | 20 ++++++++++ opentelemetry-dotnet-contrib.sln | 33 ++++++++++------ 9 files changed, 85 insertions(+), 16 deletions(-) rename build/{ => scripts}/add-labels.ps1 (100%) create mode 100644 build/scripts/finalize-publicapi.ps1 rename build/{ => scripts}/sanitycheck.py (100%) rename build/{ => scripts}/test-aot-compatibility.ps1 (96%) create mode 100644 build/scripts/update-changelogs.ps1 diff --git a/.github/workflows/add-labels.yml b/.github/workflows/add-labels.yml index a1e8409b60..9c040eaaab 100644 --- a/.github/workflows/add-labels.yml +++ b/.github/workflows/add-labels.yml @@ -18,7 +18,7 @@ jobs: - name: Add labels for component found in bug issue descriptions shell: pwsh run: | - .\build\add-labels.ps1 -issueNumber $env:ISSUE_NUMBER -issueBody $env:ISSUE_BODY + .\build\scripts\add-labels.ps1 -issueNumber $env:ISSUE_NUMBER -issueBody $env:ISSUE_BODY env: GH_TOKEN: ${{ github.token }} ISSUE_NUMBER: ${{ github.event.issue.number }} diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 899677db69..8563d4b1cb 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -27,4 +27,4 @@ jobs: uses: actions/checkout@v4 - name: detect non-ASCII encoding and trailing space - run: python3 ./build/sanitycheck.py + run: python3 ./build/scripts/sanitycheck.py diff --git a/.github/workflows/verifyaotcompat.yml b/.github/workflows/verifyaotcompat.yml index 1a6cc014c7..a9877dbf1d 100644 --- a/.github/workflows/verifyaotcompat.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -18,4 +18,4 @@ jobs: - name: publish AOT testApp, assert static analysis warning count, and run the app shell: pwsh - run: .\build\test-aot-compatibility.ps1 ${{ matrix.version }} + run: .\build\scripts\test-aot-compatibility.ps1 ${{ matrix.version }} diff --git a/build/add-labels.ps1 b/build/scripts/add-labels.ps1 similarity index 100% rename from build/add-labels.ps1 rename to build/scripts/add-labels.ps1 diff --git a/build/scripts/finalize-publicapi.ps1 b/build/scripts/finalize-publicapi.ps1 new file mode 100644 index 0000000000..337d80191a --- /dev/null +++ b/build/scripts/finalize-publicapi.ps1 @@ -0,0 +1,39 @@ +param( + [Parameter(Mandatory=$true)][string]$minVerTagPrefix +) + +# For stable releases "Unshipped" PublicApi text files are merged into "Shipped" versions. + +$projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "$minVerTagPrefix" -List | Select Path | Split-Path -Parent + +$path = "\.publicApi\**\PublicAPI.Shipped.txt"; + +foreach ($projectDir in $projectDirs) { + $searchPath = Join-Path -Path $projectDir -ChildPath $path; + + Write-Host "Search glob: $searchPath"; + + Get-ChildItem -Path $searchPath -Recurse | + ForEach-Object { + Write-Host "Shipped: $_"; + + [string]$shipped = $_.FullName; + [string]$unshipped = $shipped -replace ".shipped.txt", ".Unshipped.txt"; + + if (Test-Path $unshipped) { + Write-Host "Unshipped: $unshipped"; + + Get-Content $shipped, $unshipped | # get contents of both text files + Where-Object {$_ -ne ""} | # filter empty lines + Sort-Object | # sort lines + Get-Unique | # filter duplicates + Set-Content $shipped; # write to shipped.txt + + Clear-Content $unshipped; # empty unshipped.txt + + Write-Host "...MERGED and SORTED"; + } + + Write-Host ""; + } +} diff --git a/build/sanitycheck.py b/build/scripts/sanitycheck.py similarity index 100% rename from build/sanitycheck.py rename to build/scripts/sanitycheck.py diff --git a/build/test-aot-compatibility.ps1 b/build/scripts/test-aot-compatibility.ps1 similarity index 96% rename from build/test-aot-compatibility.ps1 rename to build/scripts/test-aot-compatibility.ps1 index 5abe054bec..ca04cfe3de 100644 --- a/build/test-aot-compatibility.ps1 +++ b/build/scripts/test-aot-compatibility.ps1 @@ -1,6 +1,7 @@ param([string]$targetNetFramework) -$rootDirectory = Split-Path $PSScriptRoot -Parent +$rootDirectory = Get-Location + $publishOutput = dotnet publish $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj -nodeReuse:false /p:UseSharedCompilation=false $actualWarningCount = 0 diff --git a/build/scripts/update-changelogs.ps1 b/build/scripts/update-changelogs.ps1 new file mode 100644 index 0000000000..d2756d77b1 --- /dev/null +++ b/build/scripts/update-changelogs.ps1 @@ -0,0 +1,20 @@ +param( + [Parameter(Mandatory=$true)][string]$minVerTagPrefix, + [Parameter(Mandatory=$true)][string]$version +) + +$projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "$minVerTagPrefix" -List | Select Path | Split-Path -Parent + +$content = "Unreleased + +## $version + +Released $(Get-Date -UFormat '%Y-%b-%d')" + +foreach ($projectDir in $projectDirs) { + $path = Join-Path -Path $projectDir -ChildPath "CHANGELOG.md" + + Write-Host "Updating $path" + + (Get-Content -Path $path) -replace "Unreleased", $content | Set-Content -Path $path +} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e8bfaa1c85..aa6bf16d09 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -27,6 +27,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A06 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{43CAFE52-F329-4431-87DA-7FEE1454D9A9}" ProjectSection(SolutionItems) = preProject + .github\workflows\add-labels.yml = .github\workflows\add-labels.yml .github\workflows\assign-reviewers.yml = .github\workflows\assign-reviewers.yml .github\workflows\ci-Exporter.OneCollector-Integration.yml = .github\workflows\ci-Exporter.OneCollector-Integration.yml .github\workflows\ci.yml = .github\workflows\ci.yml @@ -91,9 +92,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset - build\sanitycheck.py = build\sanitycheck.py build\stylecop.json = build\stylecop.json - build\test-aot-compatibility.ps1 = build\test-aot-compatibility.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0112BD4F-B7A6-4E43-AB23-B6E961E27A49}" @@ -384,6 +383,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore", "test\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore.Benchmark", "test\OpenTelemetry.Instrumentation.AspNetCore.Benchmark\OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj", "{92CD1B60-74B8-4E6E-9E7F-83AC3C792980}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{45D29DAA-0DB9-4808-B879-1AECC37EF366}" + ProjectSection(SolutionItems) = preProject + build\scripts\add-labels.ps1 = build\scripts\add-labels.ps1 + build\scripts\finalize-publicapi.ps1 = build\scripts\finalize-publicapi.ps1 + build\scripts\sanitycheck.py = build\scripts\sanitycheck.py + build\scripts\test-aot-compatibility.ps1 = build\scripts\test-aot-compatibility.ps1 + build\scripts\update-changelogs.ps1 = build\scripts\update-changelogs.ps1 + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -730,6 +738,14 @@ Global {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Release|Any CPU.ActiveCfg = Release|Any CPU {7AD707F9-DC6D-430A-8834-D5DCD517BF6E}.Release|Any CPU.Build.0 = Release|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBC6D677-D1FF-470E-A244-477E8616A245}.Release|Any CPU.Build.0 = Release|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Release|Any CPU.Build.0 = Release|Any CPU {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Debug|Any CPU.Build.0 = Debug|Any CPU {737D1A9E-5A1A-4F4F-830B-E98ED100994C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -754,14 +770,6 @@ Global {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Debug|Any CPU.Build.0 = Debug|Any CPU {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.ActiveCfg = Release|Any CPU {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}.Release|Any CPU.Build.0 = Release|Any CPU - {CBC6D677-D1FF-470E-A244-477E8616A245}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBC6D677-D1FF-470E-A244-477E8616A245}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBC6D677-D1FF-470E-A244-477E8616A245}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBC6D677-D1FF-470E-A244-477E8616A245}.Release|Any CPU.Build.0 = Release|Any CPU - {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A}.Release|Any CPU.Build.0 = Release|Any CPU {0156E342-CE63-46F5-992D-691A7CCB50F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0156E342-CE63-46F5-992D-691A7CCB50F8}.Debug|Any CPU.Build.0 = Debug|Any CPU {0156E342-CE63-46F5-992D-691A7CCB50F8}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -889,20 +897,21 @@ Global {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {CBC6D677-D1FF-470E-A244-477E8616A245} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {737D1A9E-5A1A-4F4F-830B-E98ED100994C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {9C996130-74D7-4FB7-8277-2EE6EBA2BFA6} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {BC1959E3-164E-42AE-AE1C-DE2E3046E27C} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {BE92357F-DE09-477D-AFDB-6AD1D7AC7BA1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {7371E920-ECD0-403A-A009-7A1A301D9763} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1156D564-2E3C-47D6-97C1-FF3ADEDC41C8} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {CBC6D677-D1FF-470E-A244-477E8616A245} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {EECE8D5F-C319-42E8-B37C-A41D6FF43E4A} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {0156E342-CE63-46F5-992D-691A7CCB50F8} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {2E1A5759-1431-4724-8885-3E9447FBF617} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A8FF0DEB-F371-42FC-8A53-A8C25FE408FC} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {917AEC46-816C-4E05-913E-F0F44C24C437} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1E743561-B1D4-4100-B6AD-1FD25FA8659B} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {92CD1B60-74B8-4E6E-9E7F-83AC3C792980} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {45D29DAA-0DB9-4808-B879-1AECC37EF366} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From c5e8f19d1044d93ab661d9c1e6693b12dd3e5f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 15 May 2024 08:31:46 +0200 Subject: [PATCH 1060/1499] [Instrumentation.AspNetCore] Nullable enabled (#1718) --- .../.publicApi/PublicAPI.Shipped.txt | 17 +++--- .../AspNetCoreInstrumentation.cs | 2 +- ...entationTracerProviderBuilderExtensions.cs | 8 +-- .../AspNetCoreMetrics.cs | 2 +- .../AspNetCoreTraceInstrumentationOptions.cs | 10 ++-- .../Implementation/HttpInListener.cs | 40 +++++++------- .../Implementation/HttpInMetricsListener.cs | 32 +++++------ ...elemetry.Instrumentation.AspNetCore.csproj | 6 +- ...metry.Instrumentation.GrpcNetClient.csproj | 2 + .../GrpcStatusCanonicalCode.cs} | 6 +- .../GrpcTagHelper.cs | 12 ++-- .../AspNetCoreInstrumentationBenchmarks.cs | 52 +++++++++++------- .../AspNetCoreInstrumentationNewBenchmarks.cs | 55 ++++++++++++------- ...nstrumentation.AspNetCore.Benchmark.csproj | 1 - .../BasicTests.cs | 32 +++++++---- ...stsCollectionsIsAccordingToTheSpecTests.cs | 19 +++---- .../MetricTests.cs | 28 +++++----- ...ry.Instrumentation.AspNetCore.Tests.csproj | 2 - .../GrpcTagHelperTests.cs | 1 - .../GrpcTests.server.cs | 1 - 20 files changed, 179 insertions(+), 149 deletions(-) rename src/{OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs => Shared/GrpcStatusCanonicalCode.cs} (98%) rename src/{OpenTelemetry.Instrumentation.GrpcNetClient => Shared}/GrpcTagHelper.cs (86%) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt index fc47928891..c8d966c517 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt @@ -1,18 +1,19 @@ +#nullable enable OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.AspNetCoreTraceInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithException.get -> System.Action +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithException.get -> System.Action? OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithException.set -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpRequest.get -> System.Action +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpRequest.get -> System.Action? OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpRequest.set -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpResponse.get -> System.Action +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpResponse.get -> System.Action? OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.EnrichWithHttpResponse.set -> void -OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.Filter.get -> System.Func +OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.Filter.get -> System.Func? OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.RecordException.set -> void OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions -static OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs index d309679262..7043817037 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs @@ -19,7 +19,7 @@ internal sealed class AspNetCoreInstrumentation : IDisposable "Microsoft.AspNetCore.Hosting.UnhandledException", }; - private readonly Func isEnabled = (eventName, _, _) + private readonly Func isEnabled = (eventName, _, _) => DiagnosticSourceEvents.Contains(eventName); private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs index 00fa0d9435..09a60868c6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationTracerProviderBuilderExtensions.cs @@ -31,7 +31,7 @@ public static TracerProviderBuilder AddAspNetCoreInstrumentation(this TracerProv /// The instance of to chain the calls. public static TracerProviderBuilder AddAspNetCoreInstrumentation( this TracerProviderBuilder builder, - Action configureAspNetCoreTraceInstrumentationOptions) + Action? configureAspNetCoreTraceInstrumentationOptions) => AddAspNetCoreInstrumentation(builder, name: null, configureAspNetCoreTraceInstrumentationOptions); /// @@ -43,8 +43,8 @@ public static TracerProviderBuilder AddAspNetCoreInstrumentation( /// The instance of to chain the calls. public static TracerProviderBuilder AddAspNetCoreInstrumentation( this TracerProviderBuilder builder, - string name, - Action configureAspNetCoreTraceInstrumentationOptions) + string? name, + Action? configureAspNetCoreTraceInstrumentationOptions) { Guard.ThrowIfNull(builder); @@ -96,7 +96,7 @@ internal static TracerProviderBuilder AddAspNetCoreInstrumentation( private static void AddAspNetCoreInstrumentationSources( this TracerProviderBuilder builder, - IServiceProvider serviceProvider = null) + IServiceProvider? serviceProvider = null) { // For .NET7.0 onwards activity will be created using activitySource. // https://github.com/dotnet/aspnetcore/blob/bf3352f2422bf16fa3ca49021f0e31961ce525eb/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L327 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs index a819d561a9..00e34bd2ba 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs @@ -20,7 +20,7 @@ internal sealed class AspNetCoreMetrics : IDisposable "Microsoft.AspNetCore.Hosting.UnhandledException", }; - private readonly Func isEnabled = (eventName, _, _) + private readonly Func isEnabled = (eventName, _, _) => DiagnosticSourceEvents.Contains(eventName); private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs index f5ffb7962f..2a35fdc3ba 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreTraceInstrumentationOptions.cs @@ -23,8 +23,6 @@ public AspNetCoreTraceInstrumentationOptions() internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration) { - Debug.Assert(configuration != null, "configuration was null"); - if (configuration.TryGetBoolValue( AspNetCoreInstrumentationEventSource.Log, "OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_ENABLE_GRPC_INSTRUMENTATION", @@ -58,7 +56,7 @@ internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration) /// /// /// - public Func Filter { get; set; } + public Func? Filter { get; set; } /// /// Gets or sets an action to enrich an Activity. @@ -67,7 +65,7 @@ internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration) /// : the activity being enriched. /// : the HttpRequest object from which additional information can be extracted to enrich the activity. /// - public Action EnrichWithHttpRequest { get; set; } + public Action? EnrichWithHttpRequest { get; set; } /// /// Gets or sets an action to enrich an Activity. @@ -76,7 +74,7 @@ internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration) /// : the activity being enriched. /// : the HttpResponse object from which additional information can be extracted to enrich the activity. /// - public Action EnrichWithHttpResponse { get; set; } + public Action? EnrichWithHttpResponse { get; set; } /// /// Gets or sets an action to enrich an Activity. @@ -85,7 +83,7 @@ internal AspNetCoreTraceInstrumentationOptions(IConfiguration configuration) /// : the activity being enriched. /// : the Exception object from which additional information can be extracted to enrich the activity. /// - public Action EnrichWithException { get; set; } + public Action? EnrichWithException { get; set; } /// /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 89e8c1e278..6a9ec0be44 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -2,9 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; -#endif using System.Reflection; using System.Runtime.CompilerServices; using Microsoft.AspNetCore.Http; @@ -13,7 +11,6 @@ using Microsoft.AspNetCore.Routing; #endif using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Instrumentation.GrpcNetClient; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -31,8 +28,8 @@ internal class HttpInListener : ListenerHandler internal const string AspNetCoreActivitySourceName = "Microsoft.AspNetCore"; internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); - internal static readonly string ActivitySourceName = AssemblyName.Name; - internal static readonly Version Version = AssemblyName.Version; + internal static readonly string ActivitySourceName = AssemblyName.Name!; + internal static readonly Version Version = AssemblyName.Version!; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString()); internal static readonly bool Net7OrGreater = Environment.Version.Major >= 7; @@ -61,33 +58,35 @@ public HttpInListener(AspNetCoreTraceInstrumentationOptions options) this.options = options; } - public override void OnEventWritten(string name, object payload) + public override void OnEventWritten(string name, object? payload) { + var activity = Activity.Current!; + switch (name) { case OnStartEvent: { - this.OnStartActivity(Activity.Current, payload); + this.OnStartActivity(activity, payload); } break; case OnStopEvent: { - this.OnStopActivity(Activity.Current, payload); + this.OnStopActivity(activity, payload); } break; case OnUnhandledHostingExceptionEvent: case OnUnHandledDiagnosticsExceptionEvent: { - this.OnException(Activity.Current, payload); + this.OnException(activity, payload); } break; } } - public void OnStartActivity(Activity activity, object payload) + public void OnStartActivity(Activity activity, object? payload) { // The overall flow of what AspNetCore library does is as below: // Activity.Start() @@ -120,7 +119,7 @@ public void OnStartActivity(Activity activity, object payload) // Create a new activity with its parent set from the extracted context. // This makes the new activity as a "sibling" of the activity created by // Asp.Net Core. - Activity newOne; + Activity? newOne; if (Net7OrGreater) { // For NET7.0 onwards activity is created using ActivitySource so, @@ -135,7 +134,7 @@ public void OnStartActivity(Activity activity, object payload) newOne.SetParentId(ctx.ActivityContext.TraceId, ctx.ActivityContext.SpanId, ctx.ActivityContext.TraceFlags); } - newOne.TraceStateString = ctx.ActivityContext.TraceState; + newOne!.TraceStateString = ctx.ActivityContext.TraceState; newOne.SetTag("IsCreatedByInstrumentation", bool.TrueString); @@ -201,7 +200,7 @@ public void OnStartActivity(Activity activity, object payload) } else { - activity.SetTag(SemanticConventions.AttributeUrlQuery, RedactionHelper.GetRedactedQueryString(request.QueryString.Value)); + activity.SetTag(SemanticConventions.AttributeUrlQuery, RedactionHelper.GetRedactedQueryString(request.QueryString.Value!)); } } @@ -231,12 +230,11 @@ public void OnStartActivity(Activity activity, object payload) } } - public void OnStopActivity(Activity activity, object payload) + public void OnStopActivity(Activity activity, object? payload) { if (activity.IsAllDataRequested) { - HttpContext context = payload as HttpContext; - if (context == null) + if (payload is not HttpContext context) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStopActivity), activity.OperationName); return; @@ -276,7 +274,7 @@ public void OnStopActivity(Activity activity, object payload) } } - object tagValue; + object? tagValue; if (Net7OrGreater) { tagValue = activity.GetTagValue("IsCreatedByInstrumentation"); @@ -306,12 +304,12 @@ public void OnStopActivity(Activity activity, object payload) } } - public void OnException(Activity activity, object payload) + public void OnException(Activity activity, object? payload) { if (activity.IsAllDataRequested) { // We need to use reflection here as the payload type is not a defined public type. - if (!TryFetchException(payload, out Exception exc)) + if (!TryFetchException(payload, out Exception? exc)) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnException), activity.OperationName); return; @@ -342,12 +340,12 @@ public void OnException(Activity activity, object payload) #if NET6_0_OR_GREATER [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif - static bool TryFetchException(object payload, out Exception exc) + static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryGetGrpcMethod(Activity activity, out string grpcMethod) + private static bool TryGetGrpcMethod(Activity activity, [NotNullWhen(true)] out string? grpcMethod) { grpcMethod = GrpcTagHelper.GetGrpcMethodFromActivity(activity); return !string.IsNullOrEmpty(grpcMethod); diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index cf9682d1fa..c0676a2484 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Metrics; using System.Reflection; using Microsoft.AspNetCore.Http; using OpenTelemetry.Internal; #if NET6_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Routing; #endif @@ -24,8 +24,8 @@ internal sealed class HttpInMetricsListener : ListenerHandler internal const string OnUnhandledDiagnosticsExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException"; internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); - internal static readonly string InstrumentationName = AssemblyName.Name; - internal static readonly string InstrumentationVersion = AssemblyName.Version.ToString(); + internal static readonly string InstrumentationName = AssemblyName.Name!; + internal static readonly string InstrumentationVersion = AssemblyName.Version!.ToString(); internal static readonly Meter Meter = new(InstrumentationName, InstrumentationVersion); private const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; @@ -41,10 +41,10 @@ internal HttpInMetricsListener(string name) { } - public static void OnExceptionEventWritten(string name, object payload) + public static void OnExceptionEventWritten(string name, object? payload) { // We need to use reflection here as the payload type is not a defined public type. - if (!TryFetchException(payload, out Exception exc) || !TryFetchHttpContext(payload, out HttpContext ctx)) + if (!TryFetchException(payload, out Exception? exc) || !TryFetchHttpContext(payload, out HttpContext? ctx)) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnExceptionEventWritten), HttpServerRequestDurationMetricName); return; @@ -58,16 +58,16 @@ public static void OnExceptionEventWritten(string name, object payload) #if NET6_0_OR_GREATER [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] #endif - static bool TryFetchException(object payload, out Exception exc) + static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; #if NET6_0_OR_GREATER [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] #endif - static bool TryFetchHttpContext(object payload, out HttpContext ctx) + static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? ctx) => HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; } - public static void OnStopEventWritten(string name, object payload) + public static void OnStopEventWritten(string name, object? payload) { var context = payload as HttpContext; if (context == null) @@ -79,12 +79,12 @@ public static void OnStopEventWritten(string name, object payload) TagList tags = default; // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md - tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(context.Request.Protocol))); - tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme)); - tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(context.Response.StatusCode))); + tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(context.Request.Protocol))); + tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(context.Response.StatusCode))); var httpMethod = TelemetryHelper.RequestDataHelper.GetNormalizedHttpMethod(context.Request.Method); - tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); #if NET6_0_OR_GREATER // Check the exception handler feature first in case the endpoint was overwritten @@ -92,21 +92,21 @@ public static void OnStopEventWritten(string name, object payload) context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; if (!string.IsNullOrEmpty(route)) { - tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRoute, route)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRoute, route)); } #endif if (context.Items.TryGetValue(ErrorTypeHttpContextItemsKey, out var errorType)) { - tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, errorType)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, errorType)); } // We are relying here on ASP.NET Core to set duration before writing the stop event. // https://github.com/dotnet/aspnetcore/blob/d6fa351048617ae1c8b47493ba1abbe94c3a24cf/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L449 // TODO: Follow up with .NET team if we can continue to rely on this behavior. - HttpServerRequestDuration.Record(Activity.Current.Duration.TotalSeconds, tags); + HttpServerRequestDuration.Record(Activity.Current!.Duration.TotalSeconds, tags); } - public override void OnEventWritten(string name, object payload) + public override void OnEventWritten(string name, object? payload) { switch (name) { diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index c415de0ab1..b9e902ba43 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -8,15 +8,13 @@ 1.8.1 enable - - disable - - + + diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index 7622c13bec..141ff8c25a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -24,6 +24,8 @@ + + diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs b/src/Shared/GrpcStatusCanonicalCode.cs similarity index 98% rename from src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs rename to src/Shared/GrpcStatusCanonicalCode.cs index 4ddb1ec16c..d4ec2cf7fb 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/StatusCanonicalCode.cs +++ b/src/Shared/GrpcStatusCanonicalCode.cs @@ -1,7 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -namespace OpenTelemetry.Instrumentation.GrpcNetClient; +#nullable enable + +namespace OpenTelemetry.Instrumentation; /// /// Canonical result code of span execution. @@ -10,7 +12,7 @@ namespace OpenTelemetry.Instrumentation.GrpcNetClient; /// This follows the standard GRPC codes. /// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md. /// -internal enum StatusCanonicalCode +internal enum GrpcStatusCanonicalCode { /// /// The operation completed successfully. diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs b/src/Shared/GrpcTagHelper.cs similarity index 86% rename from src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs rename to src/Shared/GrpcTagHelper.cs index 836beb226a..9fa6dff377 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcTagHelper.cs +++ b/src/Shared/GrpcTagHelper.cs @@ -1,11 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Text.RegularExpressions; using OpenTelemetry.Trace; -namespace OpenTelemetry.Instrumentation.GrpcNetClient; +namespace OpenTelemetry.Instrumentation; internal static class GrpcTagHelper { @@ -18,7 +20,7 @@ internal static class GrpcTagHelper private static readonly Regex GrpcMethodRegex = new(@"^/?(?.*)/(?.*)$", RegexOptions.Compiled); - public static string GetGrpcMethodFromActivity(Activity activity) + public static string? GetGrpcMethodFromActivity(Activity activity) { return activity.GetTagValue(GrpcMethodTagName) as string; } @@ -62,11 +64,11 @@ public static ActivityStatusCode ResolveSpanStatusForGrpcStatusCode(int statusCo { var status = ActivityStatusCode.Error; - if (typeof(StatusCanonicalCode).IsEnumDefined(statusCode)) + if (typeof(GrpcStatusCanonicalCode).IsEnumDefined(statusCode)) { - status = ((StatusCanonicalCode)statusCode) switch + status = ((GrpcStatusCanonicalCode)statusCode) switch { - StatusCanonicalCode.Ok => ActivityStatusCode.Unset, + GrpcStatusCanonicalCode.Ok => ActivityStatusCode.Unset, _ => ActivityStatusCode.Error, }; } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs index 1175922312..f0caa4f9ec 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -67,10 +67,10 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; public class AspNetCoreInstrumentationBenchmarks { - private HttpClient httpClient; - private WebApplication app; - private TracerProvider tracerProvider; - private MeterProvider meterProvider; + private HttpClient? httpClient; + private WebApplication? app; + private TracerProvider? tracerProvider; + private MeterProvider? meterProvider; [Flags] public enum EnableInstrumentationOption @@ -81,12 +81,12 @@ public enum EnableInstrumentationOption None = 0, /// - /// Instrumentation is enbled only for Traces. + /// Instrumentation is enabled only for Traces. /// Traces = 1, /// - /// Instrumentation is enbled only for Metrics. + /// Instrumentation is enabled only for Metrics. /// Metrics = 2, } @@ -141,35 +141,49 @@ public async Task GetRequestForAspNetCoreAppGlobalCleanup() { if (this.EnableInstrumentation == EnableInstrumentationOption.None) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } } else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); - this.tracerProvider.Dispose(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } + + this.tracerProvider?.Dispose(); } else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); - this.meterProvider.Dispose(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } + + this.meterProvider?.Dispose(); } else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); - this.tracerProvider.Dispose(); - this.meterProvider.Dispose(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } + + this.meterProvider?.Dispose(); } } [Benchmark] public async Task GetRequestForAspNetCoreApp() { - var httpResponse = await this.httpClient.GetAsync(new Uri("http://localhost:5000")).ConfigureAwait(false); + var httpResponse = await this.httpClient!.GetAsync(new Uri("http://localhost:5000")).ConfigureAwait(false); httpResponse.EnsureSuccessStatusCode(); } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs index 9ed7771cd0..b98bb63ca4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs @@ -69,10 +69,10 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; public class AspNetCoreInstrumentationNewBenchmarks { - private HttpClient httpClient; - private WebApplication app; - private TracerProvider tracerProvider; - private MeterProvider meterProvider; + private HttpClient? httpClient; + private WebApplication? app; + private TracerProvider? tracerProvider; + private MeterProvider? meterProvider; [Flags] public enum EnableInstrumentationOption @@ -83,12 +83,12 @@ public enum EnableInstrumentationOption None = 0, /// - /// Instrumentation is enbled only for Traces. + /// Instrumentation is enabled only for Traces. /// Traces = 1, /// - /// Instrumentation is enbled only for Metrics. + /// Instrumentation is enabled only for Metrics. /// Metrics = 2, } @@ -99,7 +99,7 @@ public enum EnableInstrumentationOption [GlobalSetup(Target = nameof(GetRequestForAspNetCoreApp))] public void GetRequestForAspNetCoreAppGlobalSetup() { - KeyValuePair[] config = new KeyValuePair[] { new KeyValuePair("OTEL_SEMCONV_STABILITY_OPT_IN", "http") }; + KeyValuePair[] config = new KeyValuePair[] { new KeyValuePair("OTEL_SEMCONV_STABILITY_OPT_IN", "http") }; var configuration = new ConfigurationBuilder() .AddInMemoryCollection(config) .Build(); @@ -162,35 +162,50 @@ public async Task GetRequestForAspNetCoreAppGlobalCleanup() { if (this.EnableInstrumentation == EnableInstrumentationOption.None) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } } else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); - this.tracerProvider.Dispose(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } + + this.tracerProvider?.Dispose(); } else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); - this.meterProvider.Dispose(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } + + this.meterProvider?.Dispose(); } else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) { - this.httpClient.Dispose(); - await this.app.DisposeAsync(); - this.tracerProvider.Dispose(); - this.meterProvider.Dispose(); + this.httpClient?.Dispose(); + if (this.app != null) + { + await this.app.DisposeAsync(); + } + + this.tracerProvider?.Dispose(); + this.meterProvider?.Dispose(); } } [Benchmark] public async Task GetRequestForAspNetCoreApp() { - var httpResponse = await this.httpClient.GetAsync(new Uri("http://localhost:5000")).ConfigureAwait(false); + var httpResponse = await this.httpClient!.GetAsync(new Uri("http://localhost:5000")).ConfigureAwait(false); httpResponse.EnsureSuccessStatusCode(); } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj index 84fe25b212..6752bc4257 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) enable - disable diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 5590a2fb3e..37ba8b44bc 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -28,7 +28,7 @@ public sealed class BasicTests : IClassFixture>, IDisposable { private readonly WebApplicationFactory factory; - private TracerProvider tracerProvider; + private TracerProvider? tracerProvider; public BasicTests(WebApplicationFactory factory) { @@ -38,8 +38,8 @@ public BasicTests(WebApplicationFactory factory) [Fact] public void AddAspNetCoreInstrumentation_BadArgs() { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddAspNetCoreInstrumentation()); + TracerProviderBuilder? builder = null; + Assert.Throws(() => builder!.AddAspNetCoreInstrumentation()); } [Theory] @@ -375,6 +375,7 @@ public async Task ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision response.EnsureSuccessStatusCode(); + Assert.NotNull(childActivityTraceContext); Assert.Equal(expectedTraceId.ToString(), childActivityTraceContext["TraceId"]); Assert.Equal(expectedTraceState, childActivityTraceContext["TraceState"]); Assert.NotEqual(expectedParentSpanId.ToString(), childActivityTraceContext["ParentSpanId"]); // there is a new activity created in instrumentation therefore the ParentSpanId is different that what is provided in the headers @@ -387,6 +388,7 @@ public async Task ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision response.EnsureSuccessStatusCode(); + Assert.NotNull(childActivityBaggageContext); Assert.Single(childActivityBaggageContext, item => item.Key == "key1" && item.Value == "value1"); Assert.Single(childActivityBaggageContext, item => item.Key == "key2" && item.Value == "value2"); } @@ -445,6 +447,7 @@ public async Task ExtractContextIrrespectiveOfTheFilterApplied() response.EnsureSuccessStatusCode(); + Assert.NotNull(childActivityTraceContext); Assert.Equal(expectedTraceId.ToString(), childActivityTraceContext["TraceId"]); Assert.Equal(expectedTraceState, childActivityTraceContext["TraceState"]); Assert.NotEqual(expectedParentSpanId.ToString(), childActivityTraceContext["ParentSpanId"]); // there is a new activity created in instrumentation therefore the ParentSpanId is different that what is provided in the headers @@ -457,6 +460,7 @@ public async Task ExtractContextIrrespectiveOfTheFilterApplied() response.EnsureSuccessStatusCode(); + Assert.NotNull(childActivityBaggageContext); Assert.Single(childActivityBaggageContext, item => item.Key == "key1" && item.Value == "value1"); Assert.Single(childActivityBaggageContext, item => item.Key == "key2" && item.Value == "value2"); } @@ -1087,7 +1091,7 @@ public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQ var exportedItems = new List(); var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION"] = disableQueryRedaction.ToString() }) + .AddInMemoryCollection(new Dictionary { ["OTEL_DOTNET_EXPERIMENTAL_ASPNETCORE_DISABLE_URL_QUERY_REDACTION"] = disableQueryRedaction.ToString() }) .Build(); var path = "/api/values" + urlQuery; @@ -1148,6 +1152,7 @@ private static void ValidateAspNetCoreActivity(Activity activityToValidate, stri Assert.Equal(ActivityKind.Server, activityToValidate.Kind); #if NET7_0_OR_GREATER Assert.Equal(HttpInListener.AspNetCoreActivitySourceName, activityToValidate.Source.Name); + Assert.NotNull(activityToValidate.Source.Version); Assert.Empty(activityToValidate.Source.Version); #else Assert.Equal(HttpInListener.ActivitySourceName, activityToValidate.Source.Name); @@ -1208,22 +1213,27 @@ public override void Inject(PropagationContext context, T carrier, Action> attributes = null) : Sampler + private class TestSampler(SamplingDecision samplingDecision, IEnumerable>? attributes = null) : Sampler { private readonly SamplingDecision samplingDecision = samplingDecision; - private readonly IEnumerable> attributes = attributes; + private readonly IEnumerable>? attributes = attributes; public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { - return new SamplingResult(this.samplingDecision, this.attributes); + if (this.attributes != null) + { + return new SamplingResult(this.samplingDecision, this.attributes); + } + + return new SamplingResult(this.samplingDecision); } } private class TestHttpInListener(AspNetCoreTraceInstrumentationOptions options) : HttpInListener(options) { - public Action OnEventWrittenCallback; + public Action? OnEventWrittenCallback; - public override void OnEventWritten(string name, object payload) + public override void OnEventWritten(string name, object? payload) { base.OnEventWritten(name, payload); @@ -1235,7 +1245,7 @@ private class TestNullHostActivityMiddlewareImpl(string activitySourceName, stri { private readonly ActivitySource activitySource = new(activitySourceName); private readonly string activityName = activityName; - private Activity activity; + private Activity? activity; public override void PreProcess(HttpContext context) { @@ -1257,7 +1267,7 @@ private class TestTestActivityMiddleware(string activitySourceName, string activ { private readonly ActivitySource activitySource = new(activitySourceName); private readonly string activityName = activityName; - private Activity activity; + private Activity? activity; public override void PreProcess(HttpContext context) { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs index f6bc29a386..62b8f5abbc 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/IncomingRequestsCollectionsIsAccordingToTheSpecTests.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection; @@ -27,16 +26,15 @@ public IncomingRequestsCollectionsIsAccordingToTheSpecTests(WebApplicationFactor } [Theory] - [InlineData("/api/values", null, "user-agent", 200, null)] - [InlineData("/api/values", null, null, 200, null)] - [InlineData("/api/exception", null, null, 503, null)] - [InlineData("/api/exception", null, null, 503, null, true)] + [InlineData("/api/values", null, "user-agent", 200)] + [InlineData("/api/values", null, null, 200)] + [InlineData("/api/exception", null, null, 503)] + [InlineData("/api/exception", null, null, 503, true)] public async Task SuccessfulTemplateControllerCallGeneratesASpan_New( string urlPath, string query, string userAgent, int statusCode, - string reasonPhrase, bool recordException = false) { var exportedItems = new List(); @@ -47,7 +45,7 @@ public async Task SuccessfulTemplateControllerCallGeneratesASpan_New( { builder.ConfigureTestServices((IServiceCollection services) => { - services.AddSingleton(new ExceptionTestCallbackMiddleware(statusCode, reasonPhrase)); + services.AddSingleton(new ExceptionTestCallbackMiddleware(statusCode)); services.AddOpenTelemetry() .WithTracing(builder => builder .AddAspNetCoreInstrumentation(options => @@ -147,21 +145,18 @@ private static void ValidateTagValue(Activity activity, string attribute, string internal class ExceptionTestCallbackMiddleware : TestCallbackMiddleware { private readonly int statusCode; - private readonly string reasonPhrase; - public ExceptionTestCallbackMiddleware(int statusCode, string reasonPhrase) + public ExceptionTestCallbackMiddleware(int statusCode) { this.statusCode = statusCode; - this.reasonPhrase = reasonPhrase; } public override async Task ProcessAsync(HttpContext context) { context.Response.StatusCode = this.statusCode; - context.Response.HttpContext.Features.Get().ReasonPhrase = this.reasonPhrase; await context.Response.WriteAsync("empty"); - if (context.Request.Path.Value.EndsWith("exception", StringComparison.Ordinal)) + if (context.Request.Path.HasValue && context.Request.Path!.Value.EndsWith("exception", StringComparison.Ordinal)) { throw new Exception("exception description"); } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 21743e0faf..4711bd272b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -29,13 +29,13 @@ public class MetricTests(WebApplicationFactory factory) : IClassFixture>, IDisposable { private readonly WebApplicationFactory factory = factory; - private MeterProvider meterProvider; + private MeterProvider? meterProvider; [Fact] public void AddAspNetCoreInstrumentation_BadArgs() { - MeterProviderBuilder builder = null; - Assert.Throws(builder.AddAspNetCoreInstrumentation); + MeterProviderBuilder? builder = null; + Assert.Throws(builder!.AddAspNetCoreInstrumentation); } #if NET8_0_OR_GREATER @@ -151,7 +151,7 @@ void ConfigureTestServices(IServiceCollection services) // giving some breezing room for the callbacks to complete await Task.Delay(TimeSpan.FromSeconds(1)); - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); var activeRequestLeasesMetric = exportedItems .Where(item => item.Name == "aspnetcore.rate_limiting.active_request_leases") @@ -292,13 +292,13 @@ public async Task HttpRequestMethodIsCapturedAsPerSpec(string originalMethod, st var mp = metricPoints[0]; // Inspect Metric Attributes - var attributes = new Dictionary(); + var attributes = new Dictionary(); foreach (var tag in mp.Tags) { attributes[tag.Key] = tag.Value; } - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == expectedMethod); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value?.ToString() == expectedMethod); Assert.DoesNotContain(attributes, t => t.Key == SemanticConventions.AttributeHttpRequestMethodOriginal); } @@ -338,7 +338,7 @@ private static void AssertMetricPoints( { foreach (var tag in mp.Tags) { - if (tag.Key == SemanticConventions.AttributeHttpRoute && tag.Value.ToString() == expectedRoute) + if (tag.Key == SemanticConventions.AttributeHttpRoute && tag.Value?.ToString() == expectedRoute) { metricPoint = mp; } @@ -369,7 +369,7 @@ private static void AssertMetricPoint( Assert.Equal(1L, count); Assert.True(sum > 0); - var attributes = new KeyValuePair[metricPoint.Tags.Count]; + var attributes = new KeyValuePair[metricPoint.Tags.Count]; int i = 0; foreach (var tag in metricPoint.Tags) { @@ -379,11 +379,11 @@ private static void AssertMetricPoint( // Inspect Attributes Assert.Equal(expectedTagsCount, attributes.Length); - var method = new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, "GET"); - var scheme = new KeyValuePair(SemanticConventions.AttributeUrlScheme, "http"); - var statusCode = new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, expectedStatusCode); - var flavor = new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, "1.1"); - var route = new KeyValuePair(SemanticConventions.AttributeHttpRoute, expectedRoute); + var method = new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, "GET"); + var scheme = new KeyValuePair(SemanticConventions.AttributeUrlScheme, "http"); + var statusCode = new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, expectedStatusCode); + var flavor = new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, "1.1"); + var route = new KeyValuePair(SemanticConventions.AttributeHttpRoute, expectedRoute); Assert.Contains(method, attributes); Assert.Contains(scheme, attributes); Assert.Contains(statusCode, attributes); @@ -392,7 +392,7 @@ private static void AssertMetricPoint( if (expectedErrorType != null) { - var errorType = new KeyValuePair(SemanticConventions.AttributeErrorType, expectedErrorType); + var errorType = new KeyValuePair(SemanticConventions.AttributeErrorType, expectedErrorType); Assert.Contains(errorType, attributes); } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 4371b4f6ab..718b2a619a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -3,8 +3,6 @@ Unit test project for OpenTelemetry ASP.NET Core instrumentation net8.0;net7.0;net6.0 enable - - disable diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs index fbb1928117..b84c30228f 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using OpenTelemetry.Instrumentation.GrpcNetClient; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs index 1c397a27ab..325c061f04 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs @@ -11,7 +11,6 @@ using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Grpc.Services.Tests; -using OpenTelemetry.Instrumentation.GrpcNetClient; using OpenTelemetry.Trace; using Xunit; using Status = OpenTelemetry.Trace.Status; From cf0258da7873e3a6ce559a2b39d7c627a7ab806c Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Wed, 15 May 2024 03:05:13 -0400 Subject: [PATCH 1061/1499] [Resources.Process] Rename process detector namespace (#1717) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/codecov.yml | 8 +++---- .github/component_owners.yml | 8 +++---- .github/workflows/ci.yml | 14 +++++------ ...cess.yml => package-Resources.Process.yml} | 6 ++--- ...j => OpenTelemetry.Resources.Process.proj} | 8 +++---- opentelemetry-dotnet-contrib.sln | 8 +++---- .../.publicApi/PublicAPI.Unshipped.txt | 3 --- .../AssemblyInfo.cs | 10 -------- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 2 ++ .../AssemblyInfo.cs | 10 ++++++++ .../CHANGELOG.md | 6 +++++ .../OpenTelemetry.Resources.Process.csproj} | 6 ++++- .../ProcessDetector.cs | 5 ++-- .../ProcessResourceBuilderExtensions.cs | 24 +++++++++++++++++++ .../ProcessSemanticConventions.cs | 2 +- .../README.md | 11 ++++----- ...nTelemetry.AotCompatibility.TestApp.csproj | 2 +- ...nTelemetry.Resources.Process.Tests.csproj} | 2 +- .../ProcessDetectorTests.cs | 3 +-- 22 files changed, 86 insertions(+), 56 deletions(-) rename .github/workflows/{package-ResourceDetectors.Process.yml => package-Resources.Process.yml} (58%) rename build/Projects/{OpenTelemetry.ResourceDetectors.Process.proj => OpenTelemetry.Resources.Process.proj} (75%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.Process => OpenTelemetry.Resources.Process}/.publicApi/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Resources.Process/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Resources.Process/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.Process => OpenTelemetry.Resources.Process}/CHANGELOG.md (64%) rename src/{OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj => OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj} (84%) rename src/{OpenTelemetry.ResourceDetectors.Process => OpenTelemetry.Resources.Process}/ProcessDetector.cs (85%) create mode 100644 src/OpenTelemetry.Resources.Process/ProcessResourceBuilderExtensions.cs rename src/{OpenTelemetry.ResourceDetectors.Process => OpenTelemetry.Resources.Process}/ProcessSemanticConventions.cs (83%) rename src/{OpenTelemetry.ResourceDetectors.Process => OpenTelemetry.Resources.Process}/README.md (70%) rename test/{OpenTelemetry.ResourceDetectors.Process.Tests/OpenTelemetry.ResourceDetectors.Process.Tests.csproj => OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj} (88%) rename test/{OpenTelemetry.ResourceDetectors.Process.Tests => OpenTelemetry.Resources.Process.Tests}/ProcessDetectorTests.cs (88%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d0f4aa71b2..c33c1fe1e1 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -52,9 +52,9 @@ body: - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container - OpenTelemetry.ResourceDetectors.Host - - OpenTelemetry.ResourceDetectors.Process - OpenTelemetry.ResourceDetectors.ProcessRuntime - OpenTelemetry.Resources.Gcp + - OpenTelemetry.Resources.Process - OpenTelemetry.Sampler.AWS - OpenTelemetry.SemanticConventions validations: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 2d8c7483d7..48af8837b3 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -52,9 +52,9 @@ body: - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container - OpenTelemetry.ResourceDetectors.Host - - OpenTelemetry.ResourceDetectors.Process - OpenTelemetry.ResourceDetectors.ProcessRuntime - OpenTelemetry.Resources.Gcp + - OpenTelemetry.Resources.Process - OpenTelemetry.Sampler.AWS - OpenTelemetry.SemanticConventions diff --git a/.github/codecov.yml b/.github/codecov.yml index 3981524084..0664709197 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -129,15 +129,15 @@ flags: paths: - src/OpenTelemetry.ResourceDetectors.Host - unittests-ResourceDetectors.Process: + unittests-ResourceDetectors.ProcessRuntime: carryforward: true paths: - - src/OpenTelemetry.ResourceDetectors.Process + - src/OpenTelemetry.ResourceDetectors.ProcessRuntime - unittests-ResourceDetectors.ProcessRuntime: + unittests-Resources.Process: carryforward: true paths: - - src/OpenTelemetry.ResourceDetectors.ProcessRuntime + - src/OpenTelemetry.Resources.Process unittests-SemanticConventions: carryforward: true diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 7df093a797..505c9fb1d3 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -73,10 +73,10 @@ components: src/OpenTelemetry.ResourceDetectors.Host/: - Kielek - lachmatt - src/OpenTelemetry.ResourceDetectors.Process/: + src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: - Kielek - lachmatt - src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: + src/OpenTelemetry.Resources.Process/: - Kielek - lachmatt src/OpenTelemetry.Resources.Gcp/: @@ -166,10 +166,10 @@ components: test/OpenTelemetry.ResourceDetectors.Host.Tests/: - Kielek - lachmatt - test/OpenTelemetry.ResourceDetectors.Process.Tests/: + test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: - Kielek - lachmatt - test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: + test/OpenTelemetry.Resources.Process.Tests/: - Kielek - lachmatt test/OpenTelemetry.Resources.Gcp.Tests/: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f07c34505b..c232af80e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] - processdetector: ['*/OpenTelemetry.ResourceDetectors.Process/**', '*/OpenTelemetry.ResourceDetectors.Process.Tests/**', '!**/*.md'] + processdetector: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', '*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] resourcedetectors: ['*/OpenTelemetry.ResourceDetectors.*/**', '!**/*.md'] @@ -56,11 +56,11 @@ jobs: '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', '!*/OpenTelemetry.ResourceDetectors.Host*/**', - '!*/OpenTelemetry.ResourceDetectors.Process/**', - '!*/OpenTelemetry.ResourceDetectors.Process.Tests/**', '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!*/OpenTelemetry.Resources.Gcp*/**', + '!*/OpenTelemetry.Resources.Process/**', + '!*/OpenTelemetry.Resources.Process.Tests/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions/**', @@ -267,8 +267,8 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.ResourceDetectors.Process - code-cov-name: ResourceDetectors.Process + project-name: OpenTelemetry.Resources.Process + code-cov-name: Resources.Process build-test-processruntime: needs: detect-changes @@ -391,9 +391,9 @@ jobs: OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, OpenTelemetry.ResourceDetectors.Host.Tests.csproj, - OpenTelemetry.ResourceDetectors.Process.Tests.csproj, OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj, - OpenTelemetry.Resources.Gcp.Tests.csproj + OpenTelemetry.Resources.Gcp.Tests.csproj, + OpenTelemetry.Resources.Process.Tests.csproj $failedProjects = @() diff --git a/.github/workflows/package-ResourceDetectors.Process.yml b/.github/workflows/package-Resources.Process.yml similarity index 58% rename from .github/workflows/package-ResourceDetectors.Process.yml rename to .github/workflows/package-Resources.Process.yml index 874054383d..ff1dc2cf26 100644 --- a/.github/workflows/package-ResourceDetectors.Process.yml +++ b/.github/workflows/package-Resources.Process.yml @@ -1,4 +1,4 @@ -name: Pack OpenTelemetry.ResourceDetectors.Process +name: Pack OpenTelemetry.Resources.Process on: workflow_dispatch: @@ -9,7 +9,7 @@ on: default: 'warning' push: tags: - - 'ResourceDetectors.Process-*' # trigger when we create a tag with prefix "ResourceDetectors.Process-" + - 'Resources.Process-*' # trigger when we create a tag with prefix "Resources.Process-" jobs: call-build-test-pack: @@ -17,5 +17,5 @@ jobs: contents: write uses: ./.github/workflows/Component.Package.yml with: - project-name: OpenTelemetry.ResourceDetectors.Process + project-name: OpenTelemetry.Resources.Process secrets: inherit diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Process.proj b/build/Projects/OpenTelemetry.Resources.Process.proj similarity index 75% rename from build/Projects/OpenTelemetry.ResourceDetectors.Process.proj rename to build/Projects/OpenTelemetry.Resources.Process.proj index 032a74930c..364b4c2358 100644 --- a/build/Projects/OpenTelemetry.ResourceDetectors.Process.proj +++ b/build/Projects/OpenTelemetry.Resources.Process.proj @@ -5,12 +5,12 @@ - - + + - + - + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index aa6bf16d09..45a674d0c3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -70,8 +70,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-ResourceDetectors.Azure.yml = .github\workflows\package-ResourceDetectors.Azure.yml .github\workflows\package-ResourceDetectors.Container.yml = .github\workflows\package-ResourceDetectors.Container.yml .github\workflows\package-ResourceDetectors.Host.yml = .github\workflows\package-ResourceDetectors.Host.yml - .github\workflows\package-ResourceDetectors.Process.yml = .github\workflows\package-ResourceDetectors.Process.yml .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml + .github\workflows\package-Resources.Process.yml = .github\workflows\package-Resources.Process.yml .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml .github\workflows\package-SemanticConventions.yml = .github\workflows\package-SemanticConventions.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml @@ -335,9 +335,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj - build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj build\Projects\OpenTelemetry.Resources.Gcp.proj = build\Projects\OpenTelemetry.Resources.Gcp.proj + build\Projects\OpenTelemetry.Resources.Process.proj = build\Projects\OpenTelemetry.Resources.Process.proj build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject @@ -345,9 +345,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests", "test\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Process", "src\OpenTelemetry.ResourceDetectors.Process\OpenTelemetry.ResourceDetectors.Process.csproj", "{A5FCDD8F-20FF-4657-804E-707EAD4FE31D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process", "src\OpenTelemetry.Resources.Process\OpenTelemetry.Resources.Process.csproj", "{A5FCDD8F-20FF-4657-804E-707EAD4FE31D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Process.Tests", "test\OpenTelemetry.ResourceDetectors.Process.Tests\OpenTelemetry.ResourceDetectors.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process.Tests", "test\OpenTelemetry.Resources.Process.Tests\OpenTelemetry.Resources.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host", "src\OpenTelemetry.ResourceDetectors.Host\OpenTelemetry.ResourceDetectors.Host.csproj", "{033CA8D4-1529-413A-B244-07958D5F9A48}" EndProject diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Unshipped.txt deleted file mode 100644 index 536c6eae3b..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.Process.ProcessDetector -OpenTelemetry.ResourceDetectors.Process.ProcessDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Process.ProcessDetector.ProcessDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs deleted file mode 100644 index 221b668c6c..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Process/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Process.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Process.Tests")] -#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.Process/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Process/.publicApi/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.Process/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.Process/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.Process/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..4621d779b2 --- /dev/null +++ b/src/OpenTelemetry.Resources.Process/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Resources.ProcessResourceBuilderExtensions +static OpenTelemetry.Resources.ProcessResourceBuilderExtensions.AddProcessDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.Resources.Process/AssemblyInfo.cs b/src/OpenTelemetry.Resources.Process/AssemblyInfo.cs new file mode 100644 index 0000000000..e1263c0c07 --- /dev/null +++ b/src/OpenTelemetry.Resources.Process/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Process.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Process.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md similarity index 64% rename from src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md rename to src/OpenTelemetry.Resources.Process/CHANGELOG.md index 88b52267a6..daf5a47089 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Process` + to `OpenTelemetry.Resources.Process`. + ([#1717](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1717)) +* **Breaking Change**: `ProcessDetector` type is now internal, use `ResourceBuilder` + extension method `AddProcessDetector` to enable the detector. + ([#1717](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1717)) * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) diff --git a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj b/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj similarity index 84% rename from src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj rename to src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj index 73da91d636..5d90876bb5 100644 --- a/src/OpenTelemetry.ResourceDetectors.Process/OpenTelemetry.ResourceDetectors.Process.csproj +++ b/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj @@ -4,7 +4,7 @@ net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - Process Resource Detector. - ResourceDetectors.Process- + Resources.Process- \s*", "" + + Set-Content $project -Value $content.TrimEnd() + + git add $project 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git add failure' + } + } + } + + git commit -m "Update PackageValidationBaselineVersion in $tagPrefix projects to $version." 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git commit failure' + } + + git push -u origin $branch 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git push failure' + } + + $body = +@" +Note: This PR was opened automatically by the [package workflow](https://github.com/$gitRepository/actions/workflows/Component.Package.yml). + +Merge once packages are available on NuGet and the build passes. + +## Changes + +* Sets ``PackageValidationBaselineVersion`` in ``$tagPrefix`` projects to ``$version``. +"@ + + gh pr create ` + --title "[repo] $tagPrefix stable release $version updates" ` + --body $body ` + --base $targetBranch ` + --head $branch ` + --label infra +} + +Export-ModuleMember -Function CreatePackageValidationBaselineVersionUpdatePullRequest diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 2cf78f2f17..a3341a31dc 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -57,7 +57,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-Instrumentation.GrpcNetClient.yml = .github\workflows\package-Instrumentation.GrpcNetClient.yml .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml .github\workflows\package-Instrumentation.Http.yml = .github\workflows\package-Instrumentation.Http.yml - .github\workflows\package-Instrumentation.MassTransit.yml = .github\workflows\package-Instrumentation.MassTransit.yml .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml @@ -71,6 +70,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\package-ResourceDetectors.Container.yml = .github\workflows\package-ResourceDetectors.Container.yml .github\workflows\package-ResourceDetectors.Host.yml = .github\workflows\package-ResourceDetectors.Host.yml .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml + .github\workflows\package-Resources.Gcp.yml = .github\workflows\package-Resources.Gcp.yml .github\workflows\package-Resources.Process.yml = .github\workflows\package-Resources.Process.yml .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml .github\workflows\package-SemanticConventions.yml = .github\workflows\package-SemanticConventions.yml @@ -335,9 +335,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj + build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj build\Projects\OpenTelemetry.Resources.Gcp.proj = build\Projects\OpenTelemetry.Resources.Gcp.proj - build\Projects\OpenTelemetry.Resources.Process.proj = build\Projects\OpenTelemetry.Resources.Process.proj build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject @@ -893,8 +893,6 @@ Global {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} - {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} From e0121e9f6e8ba01ec0c8ab6ec4617afbeb81dd34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 16 May 2024 06:59:44 +0200 Subject: [PATCH 1065/1499] Execute tests for shared code (#1755) --- .github/workflows/ci.yml | 17 +++++++++- .../OpenTelemetry.Contrib.Shared.Tests.proj | 28 ++++++++++++++++ opentelemetry-dotnet-contrib.sln | 33 +++++++++++++++---- .../GrpcTagHelperTests.cs | 2 +- .../OpenTelemetry.Contrib.Shared.Tests.csproj | 21 ++++++++++++ .../RequestDataHelperTests.cs | 3 +- .../OpenTelemetry.Contrib.Tests.Shared.csproj | 14 -------- ...enTelemetry.Exporter.InfluxDB.Tests.csproj | 2 +- ...lemetry.Exporter.OneCollector.Tests.csproj | 6 ++-- .../OpenTelemetry.Extensions.Tests.csproj | 2 +- ...emetry.Instrumentation.AspNet.Tests.csproj | 10 +++--- ...ry.Instrumentation.AspNetCore.Tests.csproj | 8 ++--- ...try.Instrumentation.Cassandra.Tests.csproj | 2 +- ...mentation.ElasticsearchClient.Tests.csproj | 6 ++-- ...etry.Instrumentation.GrpcCore.Tests.csproj | 2 +- ...Instrumentation.GrpcNetClient.Tests.csproj | 8 ++--- ...elemetry.Instrumentation.Http.Tests.csproj | 12 +++---- ...try.Instrumentation.SqlClient.Tests.csproj | 10 +++--- ...umentation.StackExchangeRedis.Tests.csproj | 4 +-- ...ersistentStorage.Abstractions.Tests.csproj | 4 +-- ....PersistentStorage.FileSystem.Tests.csproj | 4 +-- .../CustomTextMapPropagator.cs | 0 .../EnabledOnDockerPlatformTheoryAttribute.cs | 0 .../EventSourceTestHelper.cs | 0 .../InMemoryEventListener.cs | 0 .../SkipUnlessEnvVarFoundFactAttribute.cs | 0 .../SkipUnlessEnvVarFoundTheoryAttribute.cs | 0 .../TestActivityExportProcessor.cs | 0 .../TestActivityProcessor.cs | 0 .../TestEventListener.cs | 0 .../TestHttpServer.cs | 0 .../TestSampler.cs | 0 .../TestTextMapPropagator.cs | 0 33 files changed, 133 insertions(+), 65 deletions(-) create mode 100644 build/Projects/OpenTelemetry.Contrib.Shared.Tests.proj rename test/{OpenTelemetry.Instrumentation.GrpcNetClient.Tests => OpenTelemetry.Contrib.Shared.Tests}/GrpcTagHelperTests.cs (97%) create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj rename test/{OpenTelemetry.Instrumentation.AspNet.Tests => OpenTelemetry.Contrib.Shared.Tests}/RequestDataHelperTests.cs (97%) delete mode 100644 test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/CustomTextMapPropagator.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/EnabledOnDockerPlatformTheoryAttribute.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/EventSourceTestHelper.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/InMemoryEventListener.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/SkipUnlessEnvVarFoundFactAttribute.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/SkipUnlessEnvVarFoundTheoryAttribute.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/TestActivityExportProcessor.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/TestActivityProcessor.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/TestEventListener.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/TestHttpServer.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/TestSampler.cs (100%) rename test/{OpenTelemetry.Contrib.Tests.Shared => Shared}/TestTextMapPropagator.cs (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c232af80e1..0961674d75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,8 @@ jobs: filters: | md: [ '**.md' ] build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*', '**/*.targets', '**/*.props'] - shared: ['src/Shared/**'] + shared: ['src/Shared/**', 'test/Shared/**'] + sharedtests: ['test/OpenTelemetry.Contrib.Shared.Tests/**'] code: ['**.cs', '**.csproj', '.editorconfig'] aot: ['src/OpenTelemetry.Extensions.Enrichment/**'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] @@ -82,6 +83,7 @@ jobs: '!*/OpenTelemetry.SemanticConventions*/**', '!*/OpenTelemetry.Instrumentation.Wcf*/**', '!examples/wcf/**', + '!*/OpenTelemetry.Contrib.Shared.Tests/**', '!**/*.md' ] @@ -344,6 +346,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Wcf code-cov-name: Instrumentation.Wcf + build-test-sharedtests: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'sharedtests') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Contrib.Shared.Tests + code-cov-name: Contrib.Shared.Tests + build-test-solution: needs: detect-changes if: | @@ -373,6 +386,7 @@ jobs: $projects = Get-ChildItem ` -Path test/*.Tests/*.csproj ` -Exclude ` + OpenTelemetry.Contrib.Shared.Tests.csproj, OpenTelemetry.Exporter.Geneva.Tests.csproj, OpenTelemetry.Exporter.OneCollector.Tests.csproj, OpenTelemetry.Extensions.Tests.csproj, @@ -486,6 +500,7 @@ jobs: build-test-sqlclient, build-test-wcf, build-test-solution, + build-test-sharedtests, verify-aot-compat ] if: always() && !cancelled() && !contains(needs.*.result, 'failure') diff --git a/build/Projects/OpenTelemetry.Contrib.Shared.Tests.proj b/build/Projects/OpenTelemetry.Contrib.Shared.Tests.proj new file mode 100644 index 0000000000..b9e65d01a5 --- /dev/null +++ b/build/Projects/OpenTelemetry.Contrib.Shared.Tests.proj @@ -0,0 +1,28 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a3341a31dc..4962985e93 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -141,8 +141,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "grpc.core", "grpc.core", "{ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.GrpcCore.AspNetCore", "examples\grpc.core\Examples.GrpcCore.AspNetCore\Examples.GrpcCore.AspNetCore.csproj", "{F1591DEE-79C0-4161-85C2-1477B261D274}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Tests.Shared", "test\OpenTelemetry.Contrib.Tests.Shared\OpenTelemetry.Contrib.Tests.Shared.csproj", "{C33F2D9D-89A6-459C-9A51-79BA5A9EF194}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz", "src\OpenTelemetry.Instrumentation.Quartz\OpenTelemetry.Instrumentation.Quartz.csproj", "{2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Quartz.Tests", "test\OpenTelemetry.Instrumentation.Quartz.Tests\OpenTelemetry.Instrumentation.Quartz.Tests.csproj", "{37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28}" @@ -276,6 +274,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\DiagnosticSourceListener.cs = src\Shared\DiagnosticSourceListener.cs src\Shared\DiagnosticSourceSubscriber.cs = src\Shared\DiagnosticSourceSubscriber.cs src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs + src\Shared\GrpcStatusCanonicalCode.cs = src\Shared\GrpcStatusCanonicalCode.cs + src\Shared\GrpcTagHelper.cs = src\Shared\GrpcTagHelper.cs src\Shared\Guard.cs = src\Shared\Guard.cs src\Shared\IServerCertificateValidationEventSource.cs = src\Shared\IServerCertificateValidationEventSource.cs src\Shared\IsExternalInit.cs = src\Shared\IsExternalInit.cs @@ -383,6 +383,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore", "test\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore.Benchmark", "test\OpenTelemetry.Instrumentation.AspNetCore.Benchmark\OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj", "{92CD1B60-74B8-4E6E-9E7F-83AC3C792980}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared.Tests", "test\OpenTelemetry.Contrib.Shared.Tests\OpenTelemetry.Contrib.Shared.Tests.csproj", "{B13394D6-D3D7-453E-B91A-24C199F41C5E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{70CA77D4-5D7F-4D70-A6B5-8AAC07A8EA3C}" + ProjectSection(SolutionItems) = preProject + test\Shared\CustomTextMapPropagator.cs = test\Shared\CustomTextMapPropagator.cs + test\Shared\EnabledOnDockerPlatformTheoryAttribute.cs = test\Shared\EnabledOnDockerPlatformTheoryAttribute.cs + test\Shared\EventSourceTestHelper.cs = test\Shared\EventSourceTestHelper.cs + test\Shared\InMemoryEventListener.cs = test\Shared\InMemoryEventListener.cs + test\Shared\SkipUnlessEnvVarFoundFactAttribute.cs = test\Shared\SkipUnlessEnvVarFoundFactAttribute.cs + test\Shared\SkipUnlessEnvVarFoundTheoryAttribute.cs = test\Shared\SkipUnlessEnvVarFoundTheoryAttribute.cs + test\Shared\TestActivityExportProcessor.cs = test\Shared\TestActivityExportProcessor.cs + test\Shared\TestActivityProcessor.cs = test\Shared\TestActivityProcessor.cs + test\Shared\TestEventListener.cs = test\Shared\TestEventListener.cs + test\Shared\TestHttpServer.cs = test\Shared\TestHttpServer.cs + test\Shared\TestSampler.cs = test\Shared\TestSampler.cs + test\Shared\TestTextMapPropagator.cs = test\Shared\TestTextMapPropagator.cs + EndProjectSection +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{45D29DAA-0DB9-4808-B879-1AECC37EF366}" ProjectSection(SolutionItems) = preProject build\scripts\add-labels.ps1 = build\scripts\add-labels.ps1 @@ -443,10 +461,6 @@ Global {F1591DEE-79C0-4161-85C2-1477B261D274}.Debug|Any CPU.Build.0 = Debug|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.ActiveCfg = Release|Any CPU {F1591DEE-79C0-4161-85C2-1477B261D274}.Release|Any CPU.Build.0 = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194}.Release|Any CPU.Build.0 = Release|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Debug|Any CPU.Build.0 = Debug|Any CPU {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -795,6 +809,10 @@ Global {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Debug|Any CPU.Build.0 = Debug|Any CPU {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Release|Any CPU.ActiveCfg = Release|Any CPU {92CD1B60-74B8-4E6E-9E7F-83AC3C792980}.Release|Any CPU.Build.0 = Release|Any CPU + {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -816,7 +834,6 @@ Global {76BAB24F-85DB-4FCE-89D0-EFB4185004C9} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {F1591DEE-79C0-4161-85C2-1477B261D274} = {58D1DE55-B0A5-4BC4-AB37-09B1C7B26752} - {C33F2D9D-89A6-459C-9A51-79BA5A9EF194} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {2CFC0D07-7AEC-4BC3-96C4-A06A38DBF6DF} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {37564EE6-F0A4-4F40-BB13-0BBFAC7F7F28} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {8D11A34C-D0EF-4DE1-8230-32168E67044D} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} @@ -910,6 +927,8 @@ Global {917AEC46-816C-4E05-913E-F0F44C24C437} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {1E743561-B1D4-4100-B6AD-1FD25FA8659B} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {92CD1B60-74B8-4E6E-9E7F-83AC3C792980} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {B13394D6-D3D7-453E-B91A-24C199F41C5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {70CA77D4-5D7F-4D70-A6B5-8AAC07A8EA3C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {45D29DAA-0DB9-4808-B879-1AECC37EF366} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs similarity index 97% rename from test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs rename to test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs index b84c30228f..a2fbb308cf 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTagHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs @@ -5,7 +5,7 @@ using OpenTelemetry.Trace; using Xunit; -namespace OpenTelemetry.Instrumentation.Grpc.Tests; +namespace OpenTelemetry.Instrumentation.Tests; public class GrpcTagHelperTests { diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj new file mode 100644 index 0000000000..9632dfb0de --- /dev/null +++ b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj @@ -0,0 +1,21 @@ + + + + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs similarity index 97% rename from test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs rename to test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs index b4e4c3c699..ecef96dde2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RequestDataHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs @@ -3,10 +3,9 @@ using System; using System.Collections.Generic; -using OpenTelemetry.Internal; using Xunit; -namespace OpenTelemetry.Instrumentation.AspNet.Tests; +namespace OpenTelemetry.Internal.Tests; public class RequestDataHelperTests : IDisposable { diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj b/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj deleted file mode 100644 index 78b3d66688..0000000000 --- a/test/OpenTelemetry.Contrib.Tests.Shared/OpenTelemetry.Contrib.Tests.Shared.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net8.0;net6.0 - $(TargetFrameworks);net462 - false - - - - - - - - diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 87bf79f2a0..6fa307f7e8 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 9d385b58b5..7cf35b4e49 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -21,9 +21,9 @@ - - - + + + diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index aa1088457d..704dda8498 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index 38b9d15dce..bb0d66597d 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -20,11 +20,11 @@ - - - - - + + + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 718b2a619a..a6ebc43bb6 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -31,10 +31,10 @@ - - - - + + + + diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 2b8f6f953d..3485ccbfe1 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index df940472e4..e51a2e7b55 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -19,9 +19,9 @@ - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 5053e55075..ed572dc067 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index 568b59d173..dc5486c97a 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -34,10 +34,10 @@ - - - - + + + + diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 9c004bf25d..9ea7b240b8 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -11,12 +11,12 @@ - - - - - - + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index e9f24130cf..5b515f5da9 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -8,11 +8,11 @@ - - - - - + + + + + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index efcb055383..b980538962 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj index faea9a07ba..10d560b8e9 100644 --- a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index dd08c02094..d33c3e28e8 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/CustomTextMapPropagator.cs b/test/Shared/CustomTextMapPropagator.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/CustomTextMapPropagator.cs rename to test/Shared/CustomTextMapPropagator.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EnabledOnDockerPlatformTheoryAttribute.cs b/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/EnabledOnDockerPlatformTheoryAttribute.cs rename to test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs b/test/Shared/EventSourceTestHelper.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/EventSourceTestHelper.cs rename to test/Shared/EventSourceTestHelper.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs b/test/Shared/InMemoryEventListener.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/InMemoryEventListener.cs rename to test/Shared/InMemoryEventListener.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundFactAttribute.cs rename to test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs rename to test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs b/test/Shared/TestActivityExportProcessor.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/TestActivityExportProcessor.cs rename to test/Shared/TestActivityExportProcessor.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs b/test/Shared/TestActivityProcessor.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/TestActivityProcessor.cs rename to test/Shared/TestActivityProcessor.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs b/test/Shared/TestEventListener.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/TestEventListener.cs rename to test/Shared/TestEventListener.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs b/test/Shared/TestHttpServer.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/TestHttpServer.cs rename to test/Shared/TestHttpServer.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs b/test/Shared/TestSampler.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/TestSampler.cs rename to test/Shared/TestSampler.cs diff --git a/test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs b/test/Shared/TestTextMapPropagator.cs similarity index 100% rename from test/OpenTelemetry.Contrib.Tests.Shared/TestTextMapPropagator.cs rename to test/Shared/TestTextMapPropagator.cs From 1d3ac1172d0daf50e395b9976b2e1e8759e3520b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 16 May 2024 08:56:52 -0700 Subject: [PATCH 1066/1499] [Exporter.Geneva] Add logging for successful exports (#1805) Co-authored-by: Cijo Thomas Co-authored-by: Cijo Thomas --- .../Internal/ExporterEventSource.cs | 7 +++++++ .../MsgPackExporter/MsgPackLogExporter.cs | 2 ++ .../MsgPackExporter/MsgPackTraceExporter.cs | 2 ++ 3 files changed, 11 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 693885f918..e96b0f9b4b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -16,6 +16,7 @@ internal sealed class ExporterEventSource : EventSource private const int EVENT_ID_METRIC = 3; // Failed to send Metric private const int EVENT_ID_ERROR = 4; // Other common exporter exceptions private const int EVENT_ID_OTLP_PROTOBUF_METRIC = 5; // Failed to serialize metric + private const int EVENT_ID_COMPLETED_EXPORT = 6; // Completed export [NonEvent] public void FailedToSendTraceData(Exception ex) @@ -103,4 +104,10 @@ public void FailedToSerializeMetric(string metricName, string error) { this.WriteEvent(EVENT_ID_OTLP_PROTOBUF_METRIC, metricName, error); } + + [Event(EVENT_ID_COMPLETED_EXPORT, Message = "'{0}' completed data export.", Level = EventLevel.Informational)] + public void ExportCompleted(string exporterName) + { + this.WriteEvent(EVENT_ID_COMPLETED_EXPORT, exporterName); + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 07d54e7355..2cbb03dcd5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -133,6 +133,8 @@ public ExportResult Export(in Batch batch) } } + ExporterEventSource.Log.ExportCompleted(nameof(MsgPackLogExporter)); + return result; } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 5a429e39c4..94b7f86bf9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -166,6 +166,8 @@ public ExportResult Export(in Batch batch) } } + ExporterEventSource.Log.ExportCompleted(nameof(MsgPackTraceExporter)); + return result; } From 2035202ba1df24fbd2384f68d53fa23cd20ad49b Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Thu, 16 May 2024 10:02:29 -0700 Subject: [PATCH 1067/1499] [Exporter.Geneva] Prepare Release - 1.8.0 (#1798) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 7 +++++++ .../Common.GenevaExporter.props | 2 +- .../OtlpProtobufMetricExporterTests.cs | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index f2f741fbcd..31d7907aed 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.8.0 + +Released 2024-May-15 + +* Update OpenTelemetry SDK version to `1.8.1`. + ([#1798](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1798)) + ## 1.8.0-rc.2 Released 2024-May-13 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 1673f7ab45..b00b55bd60 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - 1.8.0-rc.1 + 1.8.1 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 63d47cf648..7685755d88 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -30,6 +30,7 @@ public class OtlpProtobufMetricExporterTests { "Dim3", 3 }, }; +#if EXPOSE_EXPERIMENTAL_FEATURES private static readonly string[] TagKeys = new[] { "boolKey", @@ -50,6 +51,7 @@ public class OtlpProtobufMetricExporterTests "ulongKey", "ushortKey", }; +#endif private TagList exemplarTagList; @@ -215,6 +217,7 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l if (longValue != null) { var counter = meter.CreateCounter(instrumentName); +#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { counter.Add(longValue.Value, this.exemplarTagList); @@ -223,10 +226,14 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l { counter.Add(longValue.Value, this.TagList); } +#else + counter.Add(longValue.Value, this.TagList); +#endif } else { var counter = meter.CreateCounter(instrumentName); +#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { counter.Add(doubleValue.Value, this.exemplarTagList); @@ -235,6 +242,9 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l { counter.Add(doubleValue.Value, this.TagList); } +#else + counter.Add(doubleValue.Value, this.TagList); +#endif } meterProvider.ForceFlush(); @@ -805,6 +815,7 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add var meterProvider = meterProviderBuilder.Build(); var histogram = meter.CreateHistogram("TestHistogram"); +#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { histogram.Record(doubleValue, this.exemplarTagList); @@ -813,6 +824,9 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add { histogram.Record(doubleValue, this.TagList); } +#else + histogram.Record(doubleValue, this.TagList); +#endif meterProvider.ForceFlush(); @@ -1423,6 +1437,7 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal var instrumentName = "doubleExponentialHistogram"; var histogram = meter.CreateHistogram(instrumentName); +#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { histogram.Record(doubleValue.Value, this.exemplarTagList); @@ -1433,6 +1448,10 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal histogram.Record(doubleValue.Value, this.TagList); histogram.Record(0, this.TagList); } +#else + histogram.Record(doubleValue.Value, this.TagList); + histogram.Record(0, this.TagList); +#endif meterProvider.ForceFlush(); From c7dc6aeadd681dc35a89c0dfd141ae0de21cf345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 16 May 2024 22:15:28 +0200 Subject: [PATCH 1068/1499] [repo] Migrate shared code tests from main repository (#1806) Co-authored-by: Cijo Thomas --- ...nTelemetry.AotCompatibility.TestApp.csproj | 5 + .../Program.cs | 15 +- .../PropertyFetcherAotTest.cs | 56 +++++++ .../ActivityInstrumentationHelperTest.cs | 39 +++++ .../OpenTelemetry.Contrib.Shared.Tests.csproj | 3 + .../PropertyFetcherTest.cs | 156 ++++++++++++++++++ .../RedactionHelperTest.cs | 31 ++++ 7 files changed, 303 insertions(+), 2 deletions(-) create mode 100644 test/OpenTelemetry.AotCompatibility.TestApp/PropertyFetcherAotTest.cs create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/ActivityInstrumentationHelperTest.cs create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/PropertyFetcherTest.cs create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/RedactionHelperTest.cs diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index d9df364776..a4811723db 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -7,8 +7,13 @@ false true true + enable + + + + + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/Projects/OpenTelemetry.Exporter.Geneva.proj b/build/Projects/OpenTelemetry.Exporter.Geneva.proj index 2d51435254..acdfbd03af 100644 --- a/build/Projects/OpenTelemetry.Exporter.Geneva.proj +++ b/build/Projects/OpenTelemetry.Exporter.Geneva.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Exporter.Geneva- diff --git a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj index 534e3e326d..7ea413ce8e 100644 --- a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj +++ b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Exporter.OneCollector- diff --git a/build/Projects/OpenTelemetry.Extensions.proj b/build/Projects/OpenTelemetry.Extensions.proj index eb57800c45..e617435b2b 100644 --- a/build/Projects/OpenTelemetry.Extensions.proj +++ b/build/Projects/OpenTelemetry.Extensions.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Extensions- diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj index e42df6e094..ffbb1c643d 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNet.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.AspNet- diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj index 0e86e80ccf..3f550fe523 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.AspNetCore- diff --git a/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj b/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj index 28db30bced..06b2b83666 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.EventCounters.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.EventCounters- diff --git a/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj b/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj index 86cbf25ef5..03411cc713 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.GrpcNetClient- diff --git a/build/Projects/OpenTelemetry.Instrumentation.Http.proj b/build/Projects/OpenTelemetry.Instrumentation.Http.proj index 2e8b444448..5cd5154bb9 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Http.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Http.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.Http- diff --git a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj index 4742b9765f..2b375f5491 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Owin.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Owin.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.Owin- diff --git a/build/Projects/OpenTelemetry.Instrumentation.Process.proj b/build/Projects/OpenTelemetry.Instrumentation.Process.proj index 2eb64b6afd..79dc69a913 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Process.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Process.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.Process- diff --git a/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj b/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj index b57a3a224c..3386a32a56 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Runtime.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.Runtime- diff --git a/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj b/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj index 3cde77cdda..82d5eb5f75 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.SqlClient- diff --git a/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj b/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj index 051686d22a..1570dee1f1 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.StackExchangeRedis.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.StackExchangeRedis- diff --git a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj index 515f7ca280..b3c80fc7ee 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.Wcf.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.Wcf- diff --git a/build/Projects/OpenTelemetry.PersistentStorage.proj b/build/Projects/OpenTelemetry.PersistentStorage.proj index 714e728846..758b9b968f 100644 --- a/build/Projects/OpenTelemetry.PersistentStorage.proj +++ b/build/Projects/OpenTelemetry.PersistentStorage.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + PersistentStorage- diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj index 149ae576c5..a20c1b6e0b 100644 --- a/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj +++ b/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + ResourceDetectors.Azure- diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj index b3e56c12b0..c32258e331 100644 --- a/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj +++ b/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + ResourceDetectors.Host- diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj index c3d9bb68a4..0fb4b5e97d 100644 --- a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj +++ b/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + ResourceDetectors.ProcessRuntime- diff --git a/build/Projects/OpenTelemetry.Resources.Gcp.proj b/build/Projects/OpenTelemetry.Resources.Gcp.proj index 19364c3155..ad0a81c2a4 100644 --- a/build/Projects/OpenTelemetry.Resources.Gcp.proj +++ b/build/Projects/OpenTelemetry.Resources.Gcp.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Resources.Gcp- diff --git a/build/Projects/OpenTelemetry.Resources.Process.proj b/build/Projects/OpenTelemetry.Resources.Process.proj index 364b4c2358..b2e067bdc6 100644 --- a/build/Projects/OpenTelemetry.Resources.Process.proj +++ b/build/Projects/OpenTelemetry.Resources.Process.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Resources.Process- diff --git a/build/Projects/OpenTelemetry.SemanticConventions.proj b/build/Projects/OpenTelemetry.SemanticConventions.proj index 91d459a156..5f8e5ebcf7 100644 --- a/build/Projects/OpenTelemetry.SemanticConventions.proj +++ b/build/Projects/OpenTelemetry.SemanticConventions.proj @@ -2,6 +2,7 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Exporter.SemanticConventions- diff --git a/build/scripts/build.psm1 b/build/scripts/build.psm1 new file mode 100644 index 0000000000..df0ff22140 --- /dev/null +++ b/build/scripts/build.psm1 @@ -0,0 +1,58 @@ +function ResolveProjectForTag { + param( + [Parameter()][string]$tag + ) + + if ([string]::IsNullOrEmpty($tag)) + { + # Scheduled builds. No tag, build solution. + echo "title=opentelemetry-dotnet-contrib.proj" >> $env:GITHUB_OUTPUT + echo "project=opentelemetry-dotnet-contrib.proj" >> $env:GITHUB_OUTPUT + } + else { + $match = [regex]::Match($tag, '^(.*?-)(.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse prefix or version from tag' + } + + $tagPrefix = $match.Groups[1].Value + $version = $match.Groups[2].Value + + # Step 1: Look for a .proj file in build\Projects with a matching MinVerTagPrefix + $buildProjects = @(Get-ChildItem -Path build\Projects\*.proj | Select-String "$tagPrefix" -List | Select Path) + + if ($buildProjects.Length -gt 1) + { + throw 'Multiple build project files found matching tag prefix' + } + elseif ($buildProjects.Length -eq 1) + { + $buildProject = [System.IO.Path]::GetFileNameWithoutExtension($buildProjects[0].Path) + + echo "title=$buildProject.proj" >> $env:GITHUB_OUTPUT + echo "project=.\build\Projects\$buildProject.proj" >> $env:GITHUB_OUTPUT + Return + } + + # Step 2: If no .proj file found use component build for the csproj found matching MinVerTagPrefix + $projects = @(Get-ChildItem -Path src\**\*.csproj | Select-String "$tagPrefix" -List | Select Path) + + if ($projects.Length -gt 1) + { + throw 'Multiple project files found matching tag prefix' + } + elseif ($projects.Length -ne 1) + { + throw 'No project file found matching tag prefix' + } + + $project = [System.IO.Path]::GetFileNameWithoutExtension($projects[0].Path) + + echo "title=Component.proj[$project]" >> $env:GITHUB_OUTPUT + echo "project=.\build\Projects\Component.proj" >> $env:GITHUB_OUTPUT + echo "BUILD_COMPONENT=$project" >> $env:GITHUB_ENV + } +} + +Export-ModuleMember -Function ResolveProjectForTag diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 4962985e93..180999ecfa 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -33,47 +33,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .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 - .github\workflows\Component.Package.yml = .github\workflows\Component.Package.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml - .github\workflows\package-Exporter.Geneva.yml = .github\workflows\package-Exporter.Geneva.yml - .github\workflows\package-Exporter.InfluxDB.yml = .github\workflows\package-Exporter.InfluxDB.yml - .github\workflows\package-Exporter.Instana.yml = .github\workflows\package-Exporter.Instana.yml - .github\workflows\package-Exporter.OneCollector.yml = .github\workflows\package-Exporter.OneCollector.yml - .github\workflows\package-Exporter.Stackdriver.yml = .github\workflows\package-Exporter.Stackdriver.yml - .github\workflows\package-Extensions.AWS.yml = .github\workflows\package-Extensions.AWS.yml - .github\workflows\package-Extensions.Enrichment.yml = .github\workflows\package-Extensions.Enrichment.yml - .github\workflows\package-Extensions.yml = .github\workflows\package-Extensions.yml - .github\workflows\package-Instrumentation.AspNet.yml = .github\workflows\package-Instrumentation.AspNet.yml - .github\workflows\package-Instrumentation.AspNetCore.yml = .github\workflows\package-Instrumentation.AspNetCore.yml - .github\workflows\package-Instrumentation.AWS.yml = .github\workflows\package-Instrumentation.AWS.yml - .github\workflows\package-Instrumentation.AWSLambda.yml = .github\workflows\package-Instrumentation.AWSLambda.yml - .github\workflows\package-Instrumentation.Cassandra.yml = .github\workflows\package-Instrumentation.Cassandra.yml - .github\workflows\package-Instrumentation.Elasticsearch.yml = .github\workflows\package-Instrumentation.Elasticsearch.yml - .github\workflows\package-Instrumentation.EntityFrameworkCore.yml = .github\workflows\package-Instrumentation.EntityFrameworkCore.yml - .github\workflows\package-Instrumentation.EventCounters.yml = .github\workflows\package-Instrumentation.EventCounters.yml - .github\workflows\package-Instrumentation.GrpcCore.yml = .github\workflows\package-Instrumentation.GrpcCore.yml - .github\workflows\package-Instrumentation.GrpcNetClient.yml = .github\workflows\package-Instrumentation.GrpcNetClient.yml - .github\workflows\package-Instrumentation.Hangfire.yml = .github\workflows\package-Instrumentation.Hangfire.yml - .github\workflows\package-Instrumentation.Http.yml = .github\workflows\package-Instrumentation.Http.yml - .github\workflows\package-Instrumentation.Owin.yml = .github\workflows\package-Instrumentation.Owin.yml - .github\workflows\package-Instrumentation.Process.yml = .github\workflows\package-Instrumentation.Process.yml - .github\workflows\package-Instrumentation.Quartz.yml = .github\workflows\package-Instrumentation.Quartz.yml - .github\workflows\package-Instrumentation.Runtime.yml = .github\workflows\package-Instrumentation.Runtime.yml - .github\workflows\package-Instrumentation.SqlClient.yml = .github\workflows\package-Instrumentation.SqlClient.yml - .github\workflows\package-Instrumentation.StackExchangeRedis.yml = .github\workflows\package-Instrumentation.StackExchangeRedis.yml - .github\workflows\package-Instrumentation.Wcf.yml = .github\workflows\package-Instrumentation.Wcf.yml - .github\workflows\package-PersistentStorage.yml = .github\workflows\package-PersistentStorage.yml - .github\workflows\package-ResourceDetectors.AWS.yml = .github\workflows\package-ResourceDetectors.AWS.yml - .github\workflows\package-ResourceDetectors.Azure.yml = .github\workflows\package-ResourceDetectors.Azure.yml - .github\workflows\package-ResourceDetectors.Container.yml = .github\workflows\package-ResourceDetectors.Container.yml - .github\workflows\package-ResourceDetectors.Host.yml = .github\workflows\package-ResourceDetectors.Host.yml - .github\workflows\package-ResourceDetectors.ProcessRuntime.yml = .github\workflows\package-ResourceDetectors.ProcessRuntime.yml - .github\workflows\package-Resources.Gcp.yml = .github\workflows\package-Resources.Gcp.yml - .github\workflows\package-Resources.Process.yml = .github\workflows\package-Resources.Process.yml - .github\workflows\package-Sampler.AWS.yml = .github\workflows\package-Sampler.AWS.yml - .github\workflows\package-SemanticConventions.yml = .github\workflows\package-SemanticConventions.yml + .github\workflows\publish-packages.yml = .github\workflows\publish-packages.yml .github\workflows\sanitycheck.yml = .github\workflows\sanitycheck.yml .github\workflows\stale.yml = .github\workflows\stale.yml .github\workflows\verifyaotcompat.yml = .github\workflows\verifyaotcompat.yml @@ -318,6 +281,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{9B EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{048509D6-FB49-4B84-832A-90E55520B97B}" ProjectSection(SolutionItems) = preProject + build\Projects\Component.proj = build\Projects\Component.proj + build\Projects\OpenTelemetry.Contrib.Shared.Tests.proj = build\Projects\OpenTelemetry.Contrib.Shared.Tests.proj build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj @@ -335,9 +300,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj - build\Projects\OpenTelemetry.ResourceDetectors.Process.proj = build\Projects\OpenTelemetry.ResourceDetectors.Process.proj build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj build\Projects\OpenTelemetry.Resources.Gcp.proj = build\Projects\OpenTelemetry.Resources.Gcp.proj + build\Projects\OpenTelemetry.Resources.Process.proj = build\Projects\OpenTelemetry.Resources.Process.proj build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject @@ -404,6 +369,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{45D29DAA-0DB9-4808-B879-1AECC37EF366}" ProjectSection(SolutionItems) = preProject build\scripts\add-labels.ps1 = build\scripts\add-labels.ps1 + build\scripts\build.psm1 = build\scripts\build.psm1 build\scripts\finalize-publicapi.ps1 = build\scripts\finalize-publicapi.ps1 build\scripts\post-release.psm1 = build\scripts\post-release.psm1 build\scripts\sanitycheck.py = build\scripts\sanitycheck.py @@ -910,6 +876,8 @@ Global {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} From e2c1e71ddf8bb8becb1488e79c8ce3a616d79bcb Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Thu, 16 May 2024 18:56:35 -0400 Subject: [PATCH 1070/1499] [Resources.ProcessRuntime] Rename processruntime detector namespace (#1767) Co-authored-by: Mikel Blanchard --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/codecov.yml | 8 +++---- .github/component_owners.yml | 8 +++---- .github/workflows/ci.yml | 14 +++++------ ...enTelemetry.Resources.ProcessRuntime.proj} | 10 ++++---- opentelemetry-dotnet-contrib.sln | 6 ++--- .../.publicApi/PublicAPI.Unshipped.txt | 3 --- .../AssemblyInfo.cs | 10 -------- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 2 ++ .../AssemblyInfo.cs | 10 ++++++++ .../CHANGELOG.md | 6 +++++ ...Telemetry.Resources.ProcessRuntime.csproj} | 6 ++++- .../ProcessRuntimeDetector.cs | 5 ++-- ...ProcessRuntimeResourceBuilderExtensions.cs | 24 +++++++++++++++++++ .../ProcessRuntimeSemanticConventions.cs | 2 +- .../README.md | 12 +++++----- ...nTelemetry.AotCompatibility.TestApp.csproj | 2 +- ...try.Resources.ProcessRuntime.Tests.csproj} | 2 +- .../ProcessRuntimeDetectorTests.cs | 3 +-- 21 files changed, 84 insertions(+), 53 deletions(-) rename build/Projects/{OpenTelemetry.ResourceDetectors.ProcessRuntime.proj => OpenTelemetry.Resources.ProcessRuntime.proj} (68%) delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.ProcessRuntime => OpenTelemetry.Resources.ProcessRuntime}/.publicApi/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Resources.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Resources.ProcessRuntime/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.ProcessRuntime => OpenTelemetry.Resources.ProcessRuntime}/CHANGELOG.md (59%) rename src/{OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj => OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj} (86%) rename src/{OpenTelemetry.ResourceDetectors.ProcessRuntime => OpenTelemetry.Resources.ProcessRuntime}/ProcessRuntimeDetector.cs (95%) create mode 100644 src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeResourceBuilderExtensions.cs rename src/{OpenTelemetry.ResourceDetectors.ProcessRuntime => OpenTelemetry.Resources.ProcessRuntime}/ProcessRuntimeSemanticConventions.cs (87%) rename src/{OpenTelemetry.ResourceDetectors.ProcessRuntime => OpenTelemetry.Resources.ProcessRuntime}/README.md (69%) rename test/{OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj => OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj} (86%) rename test/{OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests => OpenTelemetry.Resources.ProcessRuntime.Tests}/ProcessRuntimeDetectorTests.cs (93%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c33c1fe1e1..1ab022a96a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -52,9 +52,9 @@ body: - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container - OpenTelemetry.ResourceDetectors.Host - - OpenTelemetry.ResourceDetectors.ProcessRuntime - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Process + - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS - OpenTelemetry.SemanticConventions validations: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 48af8837b3..a2833eeb8a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -52,9 +52,9 @@ body: - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container - OpenTelemetry.ResourceDetectors.Host - - OpenTelemetry.ResourceDetectors.ProcessRuntime - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Process + - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS - OpenTelemetry.SemanticConventions diff --git a/.github/codecov.yml b/.github/codecov.yml index 0664709197..25bd105893 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -129,15 +129,15 @@ flags: paths: - src/OpenTelemetry.ResourceDetectors.Host - unittests-ResourceDetectors.ProcessRuntime: + unittests-Resources.Process: carryforward: true paths: - - src/OpenTelemetry.ResourceDetectors.ProcessRuntime + - src/OpenTelemetry.Resources.Process - unittests-Resources.Process: + unittests-Resources.ProcessRuntime: carryforward: true paths: - - src/OpenTelemetry.Resources.Process + - src/OpenTelemetry.Resources.ProcessRuntime unittests-SemanticConventions: carryforward: true diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 505c9fb1d3..f79f7aa99f 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -73,10 +73,10 @@ components: src/OpenTelemetry.ResourceDetectors.Host/: - Kielek - lachmatt - src/OpenTelemetry.ResourceDetectors.ProcessRuntime/: + src/OpenTelemetry.Resources.Process/: - Kielek - lachmatt - src/OpenTelemetry.Resources.Process/: + src/OpenTelemetry.Resources.ProcessRuntime/: - Kielek - lachmatt src/OpenTelemetry.Resources.Gcp/: @@ -166,10 +166,10 @@ components: test/OpenTelemetry.ResourceDetectors.Host.Tests/: - Kielek - lachmatt - test/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/: + test/OpenTelemetry.Resources.Process.Tests/: - Kielek - lachmatt - test/OpenTelemetry.Resources.Process.Tests/: + test/OpenTelemetry.Resources.ProcessRuntime.Tests/: - Kielek - lachmatt test/OpenTelemetry.Resources.Gcp.Tests/: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0961674d75..caca6c4f9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] processdetector: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] - processruntime: ['*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', '*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!**/*.md'] + processruntime: ['*/OpenTelemetry.Resources.ProcessRuntime/**', '*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!**/*.md'] redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] resourcedetectors: ['*/OpenTelemetry.ResourceDetectors.*/**', '!**/*.md'] runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] @@ -57,11 +57,11 @@ jobs: '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', '!*/OpenTelemetry.ResourceDetectors.Host*/**', - '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime/**', - '!*/OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests/**', '!*/OpenTelemetry.Resources.Gcp*/**', '!*/OpenTelemetry.Resources.Process/**', '!*/OpenTelemetry.Resources.Process.Tests/**', + '!*/OpenTelemetry.Resources.ProcessRuntime/**', + '!*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!*/OpenTelemetry.Instrumentation.EventCounters*/**', '!examples/event-counters/**', '!*/OpenTelemetry.Extensions/**', @@ -280,8 +280,8 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.ResourceDetectors.ProcessRuntime - code-cov-name: ResourceDetectors.ProcessRuntime + project-name: OpenTelemetry.Resources.ProcessRuntime + code-cov-name: Resources.ProcessRuntime build-test-redis: needs: detect-changes @@ -405,9 +405,9 @@ jobs: OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, OpenTelemetry.ResourceDetectors.Host.Tests.csproj, - OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj, OpenTelemetry.Resources.Gcp.Tests.csproj, - OpenTelemetry.Resources.Process.Tests.csproj + OpenTelemetry.Resources.Process.Tests.csproj, + OpenTelemetry.Resources.ProcessRuntime.Tests.csproj $failedProjects = @() diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj b/build/Projects/OpenTelemetry.Resources.ProcessRuntime.proj similarity index 68% rename from build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj rename to build/Projects/OpenTelemetry.Resources.ProcessRuntime.proj index 0fb4b5e97d..6f428a4ff7 100644 --- a/build/Projects/OpenTelemetry.ResourceDetectors.ProcessRuntime.proj +++ b/build/Projects/OpenTelemetry.Resources.ProcessRuntime.proj @@ -2,16 +2,16 @@ $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - ResourceDetectors.ProcessRuntime- + Resources.ProcessRuntime- - - + + - + - + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 180999ecfa..bb6fe9ffc6 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -300,15 +300,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj - build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj = build\Projects\OpenTelemetry.ResourceDetectors.ProcessRuntime.proj build\Projects\OpenTelemetry.Resources.Gcp.proj = build\Projects\OpenTelemetry.Resources.Gcp.proj build\Projects\OpenTelemetry.Resources.Process.proj = build\Projects\OpenTelemetry.Resources.Process.proj + build\Projects\OpenTelemetry.Resources.ProcessRuntime.proj = build\Projects\OpenTelemetry.Resources.ProcessRuntime.proj build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime", "src\OpenTelemetry.ResourceDetectors.ProcessRuntime\OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.ProcessRuntime", "src\OpenTelemetry.Resources.ProcessRuntime\OpenTelemetry.Resources.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests", "test\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests\OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.ProcessRuntime.Tests", "test\OpenTelemetry.Resources.ProcessRuntime.Tests\OpenTelemetry.Resources.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process", "src\OpenTelemetry.Resources.Process\OpenTelemetry.Resources.Process.csproj", "{A5FCDD8F-20FF-4657-804E-707EAD4FE31D}" EndProject diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt deleted file mode 100644 index a4c8a74d8a..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.ProcessRuntime.ProcessRuntimeDetector.ProcessRuntimeDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs deleted file mode 100644 index 6f887cadae..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.ProcessRuntime.Tests")] -#endif diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.ProcessRuntime/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.ProcessRuntime/.publicApi/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.ProcessRuntime/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a0981630a9 --- /dev/null +++ b/src/OpenTelemetry.Resources.ProcessRuntime/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Resources.ProcessRuntimeResourceBuilderExtensions +static OpenTelemetry.Resources.ProcessRuntimeResourceBuilderExtensions.AddProcessRuntimeDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/AssemblyInfo.cs b/src/OpenTelemetry.Resources.ProcessRuntime/AssemblyInfo.cs new file mode 100644 index 0000000000..7668e61904 --- /dev/null +++ b/src/OpenTelemetry.Resources.ProcessRuntime/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.ProcessRuntime.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.ProcessRuntime.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md similarity index 59% rename from src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md rename to src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md index bea8688334..ee5bba5ec7 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.ProcessRuntime` + to `OpenTelemetry.Resources.ProcessRuntime`. + ([#1767](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1767)) +* **Breaking Change**: `ProcessRuntimeDetector` type is now internal, use `ResourceBuilder` + extension method `AddProcessRuntimeDetector` to enable the detector. + ([#1767](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1767)) * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) diff --git a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj b/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj similarity index 86% rename from src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj rename to src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj index 613ed57702..de63279f70 100644 --- a/src/OpenTelemetry.ResourceDetectors.ProcessRuntime/OpenTelemetry.ResourceDetectors.ProcessRuntime.csproj +++ b/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj @@ -4,7 +4,7 @@ net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - Process Runtime Resource Detector for .NET runtime. - ResourceDetectors.ProcessRuntime- + Resources.ProcessRuntime- +simple project structure. One csproj for source and tests is required. Optional +benchmark[s] and stress test csprojs are also supported. --> @@ -10,6 +11,16 @@ single project for source and tests. --> + + + + diff --git a/build/Projects/OpenTelemetry.Exporter.Geneva.proj b/build/Projects/OpenTelemetry.Exporter.Geneva.proj deleted file mode 100644 index acdfbd03af..0000000000 --- a/build/Projects/OpenTelemetry.Exporter.Geneva.proj +++ /dev/null @@ -1,35 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Exporter.Geneva- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj b/build/Projects/OpenTelemetry.Exporter.OneCollector.proj deleted file mode 100644 index 7ea413ce8e..0000000000 --- a/build/Projects/OpenTelemetry.Exporter.OneCollector.proj +++ /dev/null @@ -1,34 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Exporter.OneCollector- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Extensions.proj b/build/Projects/OpenTelemetry.Extensions.proj deleted file mode 100644 index e617435b2b..0000000000 --- a/build/Projects/OpenTelemetry.Extensions.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Extensions- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj index 3f550fe523..2d2098919a 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj @@ -7,7 +7,7 @@ - + diff --git a/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj b/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj deleted file mode 100644 index 03411cc713..0000000000 --- a/build/Projects/OpenTelemetry.Instrumentation.GrpcNetClient.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Instrumentation.GrpcNetClient- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Instrumentation.Http.proj b/build/Projects/OpenTelemetry.Instrumentation.Http.proj deleted file mode 100644 index 5cd5154bb9..0000000000 --- a/build/Projects/OpenTelemetry.Instrumentation.Http.proj +++ /dev/null @@ -1,34 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Instrumentation.Http- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj b/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj deleted file mode 100644 index 82d5eb5f75..0000000000 --- a/build/Projects/OpenTelemetry.Instrumentation.SqlClient.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Instrumentation.SqlClient- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj deleted file mode 100644 index a20c1b6e0b..0000000000 --- a/build/Projects/OpenTelemetry.ResourceDetectors.Azure.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - ResourceDetectors.Azure- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj b/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj deleted file mode 100644 index c32258e331..0000000000 --- a/build/Projects/OpenTelemetry.ResourceDetectors.Host.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - ResourceDetectors.Host- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Resources.Gcp.proj b/build/Projects/OpenTelemetry.Resources.Gcp.proj deleted file mode 100644 index ad0a81c2a4..0000000000 --- a/build/Projects/OpenTelemetry.Resources.Gcp.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Resources.Gcp- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Resources.Process.proj b/build/Projects/OpenTelemetry.Resources.Process.proj deleted file mode 100644 index b2e067bdc6..0000000000 --- a/build/Projects/OpenTelemetry.Resources.Process.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Resources.Process- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/Projects/OpenTelemetry.Resources.ProcessRuntime.proj b/build/Projects/OpenTelemetry.Resources.ProcessRuntime.proj deleted file mode 100644 index 6f428a4ff7..0000000000 --- a/build/Projects/OpenTelemetry.Resources.ProcessRuntime.proj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) - Resources.ProcessRuntime- - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/scripts/build.psm1 b/build/scripts/build.psm1 index df0ff22140..619fc8be17 100644 --- a/build/scripts/build.psm1 +++ b/build/scripts/build.psm1 @@ -1,58 +1,82 @@ function ResolveProjectForTag { param( - [Parameter()][string]$tag + [Parameter()][string]$tag, + [Parameter()][ref]$title, + [Parameter()][ref]$project, + [Parameter()][ref]$component ) + # Scheduled builds. No tag, build solution. if ([string]::IsNullOrEmpty($tag)) { - # Scheduled builds. No tag, build solution. - echo "title=opentelemetry-dotnet-contrib.proj" >> $env:GITHUB_OUTPUT - echo "project=opentelemetry-dotnet-contrib.proj" >> $env:GITHUB_OUTPUT + $title.value = "opentelemetry-dotnet-contrib.proj" + $project.value = "opentelemetry-dotnet-contrib.proj" + Return } - else { - $match = [regex]::Match($tag, '^(.*?-)(.*)$') - if ($match.Success -eq $false) - { - throw 'Could not parse prefix or version from tag' - } - - $tagPrefix = $match.Groups[1].Value - $version = $match.Groups[2].Value - - # Step 1: Look for a .proj file in build\Projects with a matching MinVerTagPrefix - $buildProjects = @(Get-ChildItem -Path build\Projects\*.proj | Select-String "$tagPrefix" -List | Select Path) - - if ($buildProjects.Length -gt 1) - { - throw 'Multiple build project files found matching tag prefix' - } - elseif ($buildProjects.Length -eq 1) - { - $buildProject = [System.IO.Path]::GetFileNameWithoutExtension($buildProjects[0].Path) - - echo "title=$buildProject.proj" >> $env:GITHUB_OUTPUT - echo "project=.\build\Projects\$buildProject.proj" >> $env:GITHUB_OUTPUT - Return - } - - # Step 2: If no .proj file found use component build for the csproj found matching MinVerTagPrefix - $projects = @(Get-ChildItem -Path src\**\*.csproj | Select-String "$tagPrefix" -List | Select Path) - - if ($projects.Length -gt 1) - { - throw 'Multiple project files found matching tag prefix' - } - elseif ($projects.Length -ne 1) - { - throw 'No project file found matching tag prefix' - } - - $project = [System.IO.Path]::GetFileNameWithoutExtension($projects[0].Path) - - echo "title=Component.proj[$project]" >> $env:GITHUB_OUTPUT - echo "project=.\build\Projects\Component.proj" >> $env:GITHUB_OUTPUT - echo "BUILD_COMPONENT=$project" >> $env:GITHUB_ENV + + $match = [regex]::Match($tag, '^(.*?-)(.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse prefix or version from tag' + } + + $tagPrefix = $match.Groups[1].Value + $version = $match.Groups[2].Value + + # Step 1: Look for a .proj file in build/Projects with a matching MinVerTagPrefix + $buildProjects = @(Get-ChildItem -Path build/Projects/*.proj | Select-String "$tagPrefix" -List | Select Path) + + if ($buildProjects.Length -gt 1) + { + throw 'Multiple build project files found matching tag prefix' + } + elseif ($buildProjects.Length -eq 1) + { + $buildProject = [System.IO.Path]::GetFileNameWithoutExtension($buildProjects[0].Path) + + $title.value = "$buildProject.proj" + $project.value = "./build/Projects/$buildProject.proj" + Return + } + + # Step 2: If no .proj file found use component build for the csproj found matching MinVerTagPrefix + $projects = @(Get-ChildItem -Path src/**/*.csproj | Select-String "$tagPrefix" -List | Select Path) + + if ($projects.Length -gt 1) + { + throw 'Multiple project files found matching tag prefix' + } + elseif ($projects.Length -ne 1) + { + throw 'No project file found matching tag prefix' } + + $component.value = [System.IO.Path]::GetFileNameWithoutExtension($projects[0].Path) + $title.value = "Component.proj for $($component.value)" + $project.value = "./build/Projects/Component.proj" } Export-ModuleMember -Function ResolveProjectForTag + +function ResolveProject { + param( + [Parameter(Mandatory=$true)][string]$projectNameOrComponentData, + [Parameter()][ref]$title, + [Parameter()][ref]$project, + [Parameter()][ref]$component + ) + + $match = [regex]::Match($projectNameOrComponentData, '^Component\[(.*)\]$') + if ($match.Success -eq $false) + { + $title.value = "$projectNameOrComponentData.proj" + $project.value = "./build/Projects/$projectNameOrComponentData.proj" + Return + } + + $component.value = $match.Groups[1].Value + $title.value = "Component.proj for $($component.value)" + $project.value = "./build/Projects/Component.proj" +} + +Export-ModuleMember -Function ResolveProject diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index bb6fe9ffc6..bd931b32ca 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -283,26 +283,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 ProjectSection(SolutionItems) = preProject build\Projects\Component.proj = build\Projects\Component.proj build\Projects\OpenTelemetry.Contrib.Shared.Tests.proj = build\Projects\OpenTelemetry.Contrib.Shared.Tests.proj - build\Projects\OpenTelemetry.Exporter.Geneva.proj = build\Projects\OpenTelemetry.Exporter.Geneva.proj - build\Projects\OpenTelemetry.Exporter.OneCollector.proj = build\Projects\OpenTelemetry.Exporter.OneCollector.proj - build\Projects\OpenTelemetry.Extensions.proj = build\Projects\OpenTelemetry.Extensions.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj = build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj - build\Projects\OpenTelemetry.Instrumentation.GrpcNetClient.proj = build\Projects\OpenTelemetry.Instrumentation.GrpcNetClient.proj - build\Projects\OpenTelemetry.Instrumentation.Http.proj = build\Projects\OpenTelemetry.Instrumentation.Http.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.Runtime.proj = build\Projects\OpenTelemetry.Instrumentation.Runtime.proj - build\Projects\OpenTelemetry.Instrumentation.SqlClient.proj = build\Projects\OpenTelemetry.Instrumentation.SqlClient.proj build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj = build\Projects\OpenTelemetry.Instrumentation.StackExchangeRedis.proj build\Projects\OpenTelemetry.Instrumentation.Wcf.proj = build\Projects\OpenTelemetry.Instrumentation.Wcf.proj build\Projects\OpenTelemetry.PersistentStorage.proj = build\Projects\OpenTelemetry.PersistentStorage.proj - build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj = build\Projects\OpenTelemetry.ResourceDetectors.Azure.proj - build\Projects\OpenTelemetry.ResourceDetectors.Host.proj = build\Projects\OpenTelemetry.ResourceDetectors.Host.proj - build\Projects\OpenTelemetry.Resources.Gcp.proj = build\Projects\OpenTelemetry.Resources.Gcp.proj - build\Projects\OpenTelemetry.Resources.Process.proj = build\Projects\OpenTelemetry.Resources.Process.proj - build\Projects\OpenTelemetry.Resources.ProcessRuntime.proj = build\Projects\OpenTelemetry.Resources.ProcessRuntime.proj build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject @@ -874,8 +863,6 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {B6157646-8EBA-464C-99B9-C386D474CB12} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} From 9f582abdd48dd0793bb6fa573ffcc31fd72240f3 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 20 May 2024 13:44:44 -0700 Subject: [PATCH 1077/1499] Remove exemplar and exponential histogram note from readme (#1817) --- src/OpenTelemetry.Exporter.Geneva/README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 44e6c27e91..7473017a0f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -262,13 +262,7 @@ specification](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.1.0 > [!NOTE] > `PrivatePreviewEnableOtlpProtobufEncoding` is currently - > only supported in Windows environment. Exporting - > [Exemplar](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar) - > and - > [ExponentialHistogram](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#exponentialhistogram) - > are not supported for now. - > ([#1685](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1685), - > [#1378](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1378)). + > only supported in Windows environment. #### `MetricExportIntervalMilliseconds` (optional) From 9c0fe935dd4f17dae9dea5724e682bcf41758680 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 20 May 2024 16:03:00 -0700 Subject: [PATCH 1078/1499] [Instrumentation.Runtime] Prepare release 1.8.1 (#1821) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index c1559e448b..4038c2a954 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.1 + +Released 2024-May-20 + * Update `OpenTelemetry.Api` to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) From 9b8c92c23700911da95d32a72b87e7721d59fe6d Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Mon, 20 May 2024 22:05:43 -0700 Subject: [PATCH 1079/1499] Temporary remove @atshaw43 from component_owners (#1822) It will allow us to successfully execute assignment PRs tasks --- .github/component_owners.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index f79f7aa99f..499dd98dde 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -23,13 +23,11 @@ components: - mikegoldsmith src/OpenTelemetry.Extensions.AWS/: - srprash - - atshaw43 - ppittle src/OpenTelemetry.Extensions.Enrichment/: - xakep139 src/OpenTelemetry.Instrumentation.AWS/: - srprash - - atshaw43 - ppittle src/OpenTelemetry.Instrumentation.AWSLambda/: - rypdal @@ -63,7 +61,6 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.AWS/: - srprash - - atshaw43 - ppittle src/OpenTelemetry.ResourceDetectors.Azure/: - rajkumar-rangaraj @@ -84,7 +81,6 @@ components: - pyohannes src/OpenTelemetry.Sampler.AWS/: - srprash - - atshaw43 - ppittle test/OpenTelemetry.Exporter.Geneva.Benchmark/: - cijothomas @@ -121,13 +117,12 @@ components: - mikegoldsmith test/OpenTelemetry.Extensions.AWS.Tests/: - srprash - - atshaw43 - ppittle test/OpenTelemetry.Extensions.Enrichment.Tests/: - xakep139 test/OpenTelemetry.Instrumentation.AWS.Tests/: - srprash - - atshaw43 + - ppittle test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: - rypdal - Oberon00 @@ -156,7 +151,6 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.AWS.Tests/: - srprash - - atshaw43 - ppittle test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - rajkumar-rangaraj @@ -177,5 +171,4 @@ components: - pyohannes test/OpenTelemetry.Sampler.AWS.Tests/: - srprash - - atshaw43 - ppittle From 24f0fa04c7f02b73422da38f93ddc4e32f99d983 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 07:30:54 +0200 Subject: [PATCH 1080/1499] [repo] Instrumentation.Runtime- stable release 1.8.1 updates (#1823) --- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index c5c5997d06..9a38f8bbcf 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,7 +5,7 @@ dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- - 1.8.0 + 1.8.1 From 38a2d74c425dd888b390b421314a8dba455ec008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 21 May 2024 09:41:45 +0200 Subject: [PATCH 1081/1499] [repo] Fix Solution file (Resources.ProcessRuntime projects) (#1826) --- opentelemetry-dotnet-contrib.sln | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index bd931b32ca..0c2cdf7b30 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -295,9 +295,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.SemanticConventions.proj = build\Projects\OpenTelemetry.SemanticConventions.proj EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.ProcessRuntime", "src\OpenTelemetry.Resources.ProcessRuntime\OpenTelemetry.Resources.ProcessRuntime.csproj", "{95372E82-CA5B-4C61-BD6C-74E6AB1970D4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.ProcessRuntime", "src\OpenTelemetry.Resources.ProcessRuntime\OpenTelemetry.Resources.ProcessRuntime.csproj", "{7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.ProcessRuntime.Tests", "test\OpenTelemetry.Resources.ProcessRuntime.Tests\OpenTelemetry.Resources.ProcessRuntime.Tests.csproj", "{B6157646-8EBA-464C-99B9-C386D474CB12}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.ProcessRuntime.Tests", "test\OpenTelemetry.Resources.ProcessRuntime.Tests\OpenTelemetry.Resources.ProcessRuntime.Tests.csproj", "{2A51E621-BCFA-4D52-96D0-E16AFF48CBE5}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process", "src\OpenTelemetry.Resources.Process\OpenTelemetry.Resources.Process.csproj", "{A5FCDD8F-20FF-4657-804E-707EAD4FE31D}" EndProject @@ -680,14 +680,14 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.Build.0 = Release|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95372E82-CA5B-4C61-BD6C-74E6AB1970D4}.Release|Any CPU.Build.0 = Release|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B6157646-8EBA-464C-99B9-C386D474CB12}.Release|Any CPU.Build.0 = Release|Any CPU + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Release|Any CPU.Build.0 = Release|Any CPU + {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5}.Release|Any CPU.Build.0 = Release|Any CPU {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5FCDD8F-20FF-4657-804E-707EAD4FE31D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -885,6 +885,8 @@ Global {B13394D6-D3D7-453E-B91A-24C199F41C5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {70CA77D4-5D7F-4D70-A6B5-8AAC07A8EA3C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {45D29DAA-0DB9-4808-B879-1AECC37EF366} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From 7665900a51ea7fecd6e5461a9a7da8cebcb9c805 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Tue, 21 May 2024 08:03:50 -0400 Subject: [PATCH 1082/1499] [Resources.Host] Rename host detector namespace (#1820) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/codecov.yml | 4 ++-- .github/component_owners.yml | 4 ++-- .github/workflows/ci.yml | 10 ++++---- opentelemetry-dotnet-contrib.sln | 10 ++++---- .../.publicApi/PublicAPI.Unshipped.txt | 3 --- .../AssemblyInfo.cs | 10 -------- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 2 ++ .../AssemblyInfo.cs | 10 ++++++++ .../CHANGELOG.md | 6 +++++ .../HostDetector.cs | 5 ++-- .../HostResourceBuilderExtensions.cs | 24 +++++++++++++++++++ .../HostResourceEventSource.cs | 4 ++-- .../HostSemanticConventions.cs | 2 +- .../OpenTelemetry.Resources.Host.csproj} | 3 ++- .../README.md | 12 +++++----- ...nTelemetry.AotCompatibility.TestApp.csproj | 2 +- .../HostDetectorTests.cs | 3 +-- ...OpenTelemetry.Resources.Host.Tests.csproj} | 2 +- .../Samples/etc_machineid | 0 .../Samples/etc_var_dbus_machineid | 0 23 files changed, 74 insertions(+), 46 deletions(-) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.Host => OpenTelemetry.Resources.Host}/.publicApi/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Resources.Host/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Resources.Host/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.Host => OpenTelemetry.Resources.Host}/CHANGELOG.md (69%) rename src/{OpenTelemetry.ResourceDetectors.Host => OpenTelemetry.Resources.Host}/HostDetector.cs (97%) create mode 100644 src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs rename src/{OpenTelemetry.ResourceDetectors.Host => OpenTelemetry.Resources.Host}/HostResourceEventSource.cs (87%) rename src/{OpenTelemetry.ResourceDetectors.Host => OpenTelemetry.Resources.Host}/HostSemanticConventions.cs (83%) rename src/{OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj => OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj} (88%) rename src/{OpenTelemetry.ResourceDetectors.Host => OpenTelemetry.Resources.Host}/README.md (71%) rename test/{OpenTelemetry.ResourceDetectors.Host.Tests => OpenTelemetry.Resources.Host.Tests}/HostDetectorTests.cs (98%) rename test/{OpenTelemetry.ResourceDetectors.Host.Tests/OpenTelemetry.ResourceDetectors.Host.Tests.csproj => OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj} (92%) rename test/{OpenTelemetry.ResourceDetectors.Host.Tests => OpenTelemetry.Resources.Host.Tests}/Samples/etc_machineid (100%) rename test/{OpenTelemetry.ResourceDetectors.Host.Tests => OpenTelemetry.Resources.Host.Tests}/Samples/etc_var_dbus_machineid (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1ab022a96a..2d9e8e82e6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -51,8 +51,8 @@ body: - OpenTelemetry.ResourceDetectors.AWS - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container - - OpenTelemetry.ResourceDetectors.Host - OpenTelemetry.Resources.Gcp + - OpenTelemetry.Resources.Host - OpenTelemetry.Resources.Process - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index a2833eeb8a..9e5b95ad58 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -51,8 +51,8 @@ body: - OpenTelemetry.ResourceDetectors.AWS - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container - - OpenTelemetry.ResourceDetectors.Host - OpenTelemetry.Resources.Gcp + - OpenTelemetry.Resources.Host - OpenTelemetry.Resources.Process - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS diff --git a/.github/codecov.yml b/.github/codecov.yml index 25bd105893..04587aaeb8 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -124,10 +124,10 @@ flags: paths: - src/OpenTelemetry.Resources.Gcp - unittests-ResourceDetectors.Host: + unittests-Resources.Host: carryforward: true paths: - - src/OpenTelemetry.ResourceDetectors.Host + - src/OpenTelemetry.Resources.Host unittests-Resources.Process: carryforward: true diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 499dd98dde..5c790b2dd4 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -67,7 +67,7 @@ components: - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev - src/OpenTelemetry.ResourceDetectors.Host/: + src/OpenTelemetry.Resources.Host/: - Kielek - lachmatt src/OpenTelemetry.Resources.Process/: @@ -157,7 +157,7 @@ components: - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev - test/OpenTelemetry.ResourceDetectors.Host.Tests/: + test/OpenTelemetry.Resources.Host.Tests/: - Kielek - lachmatt test/OpenTelemetry.Resources.Process.Tests/: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cadc8e3d68..27f703f3a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] grpcnetclient: ['*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', '!**/*.md'] - host: ['*/OpenTelemetry.ResourceDetectors.Host*/**', '!**/*.md'] + host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md'] http: ['*/OpenTelemetry.Instrumentation.Http*/**', '!**/*.md'] onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] @@ -56,7 +56,7 @@ jobs: '!*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!examples/AspNet/**', '!*/OpenTelemetry.ResourceDetectors.Azure*/**', - '!*/OpenTelemetry.ResourceDetectors.Host*/**', + '!*/OpenTelemetry.Resources.Host*/**', '!*/OpenTelemetry.Resources.Gcp*/**', '!*/OpenTelemetry.Resources.Process/**', '!*/OpenTelemetry.Resources.Process.Tests/**', @@ -201,8 +201,8 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.ResourceDetectors.Host] - code-cov-name: ResourceDetectors.Host + project-name: Component[OpenTelemetry.Resources.Host] + code-cov-name: Resources.Host build-test-http: needs: detect-changes @@ -404,8 +404,8 @@ jobs: OpenTelemetry.Instrumentation.Wcf.Tests.csproj, OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, - OpenTelemetry.ResourceDetectors.Host.Tests.csproj, OpenTelemetry.Resources.Gcp.Tests.csproj, + OpenTelemetry.Resources.Host.Tests.csproj, OpenTelemetry.Resources.Process.Tests.csproj, OpenTelemetry.Resources.ProcessRuntime.Tests.csproj diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 0c2cdf7b30..7824043f8e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -303,9 +303,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Pro EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process.Tests", "test\OpenTelemetry.Resources.Process.Tests\OpenTelemetry.Resources.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host", "src\OpenTelemetry.ResourceDetectors.Host\OpenTelemetry.ResourceDetectors.Host.csproj", "{033CA8D4-1529-413A-B244-07958D5F9A48}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Host", "src\OpenTelemetry.Resources.Host\OpenTelemetry.Resources.Host.csproj", "{033CA8D4-1529-413A-B244-07958D5F9A48}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Host.Tests", "test\OpenTelemetry.ResourceDetectors.Host.Tests\OpenTelemetry.ResourceDetectors.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Host.Tests", "test\OpenTelemetry.Resources.Host.Tests\OpenTelemetry.Resources.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.PersistentStorage.Abstractions.Tests", "test\OpenTelemetry.PersistentStorage.Abstractions.Tests\OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj", "{7AD707F9-DC6D-430A-8834-D5DCD517BF6E}" EndProject @@ -680,7 +680,7 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A}.Release|Any CPU.Build.0 = Release|Any CPU - {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Debug|Any CPU.Build.0 = Debug|Any CPU {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Release|Any CPU.ActiveCfg = Release|Any CPU {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6}.Release|Any CPU.Build.0 = Release|Any CPU @@ -863,6 +863,8 @@ Global {23AA75F6-403F-4867-BF0E-BAF0A44F9A7A} = {73474960-8F91-4EE5-8E3E-F7E7ADA99238} {9B30F5FD-3309-49CB-9CAD-D3372FAFD796} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {048509D6-FB49-4B84-832A-90E55520B97B} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} + {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} @@ -885,8 +887,6 @@ Global {B13394D6-D3D7-453E-B91A-24C199F41C5E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {70CA77D4-5D7F-4D70-A6B5-8AAC07A8EA3C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {45D29DAA-0DB9-4808-B879-1AECC37EF366} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} - {7EDD3E93-6C86-4199-B3D2-44C0DF1EA3F6} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Unshipped.txt deleted file mode 100644 index ab46f0419f..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,3 +0,0 @@ -OpenTelemetry.ResourceDetectors.Host.HostDetector -OpenTelemetry.ResourceDetectors.Host.HostDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Host.HostDetector.HostDetector() -> void diff --git a/src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs deleted file mode 100644 index d290537dd9..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Host/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Host.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Host.Tests")] -#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.Host/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Host/.publicApi/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.Host/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.Host/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.Host/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..e408682d12 --- /dev/null +++ b/src/OpenTelemetry.Resources.Host/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Resources.HostResourceBuilderExtensions +static OpenTelemetry.Resources.HostResourceBuilderExtensions.AddHostDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.Resources.Host/AssemblyInfo.cs b/src/OpenTelemetry.Resources.Host/AssemblyInfo.cs new file mode 100644 index 0000000000..a838583ff5 --- /dev/null +++ b/src/OpenTelemetry.Resources.Host/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Host.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Host.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md similarity index 69% rename from src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md rename to src/OpenTelemetry.Resources.Host/CHANGELOG.md index 729c7e61d6..07919e7166 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Host` + to `OpenTelemetry.Resources.Host`. + ([#1820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1820)) +* **Breaking Change**: `HostDetector` type is now internal, use `ResourceBuilder` + extension method `AddHostDetector` to enable the detector. + ([#1820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1820)) * Adds support for `host.id` resource attribute on non-containerized systems. `host.id` will be set per [semantic convention rules](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/host.md) ([#1631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1631)) diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs b/src/OpenTelemetry.Resources.Host/HostDetector.cs similarity index 97% rename from src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs rename to src/OpenTelemetry.Resources.Host/HostDetector.cs index 705be6ee0a..09115bd3fc 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/HostDetector.cs +++ b/src/OpenTelemetry.Resources.Host/HostDetector.cs @@ -7,14 +7,13 @@ using System.IO; using System.Text; using Microsoft.Win32; -using OpenTelemetry.Resources; -namespace OpenTelemetry.ResourceDetectors.Host; +namespace OpenTelemetry.Resources.Host; /// /// Host detector. /// -public sealed class HostDetector : IResourceDetector +internal sealed class HostDetector : IResourceDetector { private const string ETCMACHINEID = "/etc/machine-id"; private const string ETCVARDBUSMACHINEID = "/var/lib/dbus/machine-id"; diff --git a/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs new file mode 100644 index 0000000000..d1253685f3 --- /dev/null +++ b/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; +using OpenTelemetry.Resources.Host; + +namespace OpenTelemetry.Resources; + +/// +/// Extension methods to simplify registering of host resource detectors. +/// +public static class HostResourceBuilderExtensions +{ + /// + /// Enables host resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddHostDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new HostDetector()); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs b/src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs similarity index 87% rename from src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs rename to src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs index e7d0509c68..2a23f265c2 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/HostResourceEventSource.cs +++ b/src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs @@ -5,9 +5,9 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.ResourceDetectors.Host; +namespace OpenTelemetry.Resources.Host; -[EventSource(Name = "OpenTelemetry-ResourceDetectors-Host")] +[EventSource(Name = "OpenTelemetry-Resources-Host")] internal class HostResourceEventSource : EventSource { public static HostResourceEventSource Log = new(); diff --git a/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs b/src/OpenTelemetry.Resources.Host/HostSemanticConventions.cs similarity index 83% rename from src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs rename to src/OpenTelemetry.Resources.Host/HostSemanticConventions.cs index 209cfb9808..7f10aaa7c9 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/HostSemanticConventions.cs +++ b/src/OpenTelemetry.Resources.Host/HostSemanticConventions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -namespace OpenTelemetry.ResourceDetectors.Host; +namespace OpenTelemetry.Resources.Host; internal static class HostSemanticConventions { diff --git a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj b/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj similarity index 88% rename from src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj rename to src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj index bc95741131..becdd8962b 100644 --- a/src/OpenTelemetry.ResourceDetectors.Host/OpenTelemetry.ResourceDetectors.Host.csproj +++ b/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj @@ -4,7 +4,7 @@ net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - Host Resource Detector. - ResourceDetectors.Host- + Resources.Host- - diff --git a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj index 2d2098919a..d644e075b4 100644 --- a/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj +++ b/build/Projects/OpenTelemetry.Instrumentation.AspNetCore.proj @@ -7,7 +7,7 @@ - + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 7824043f8e..eb40cb1b7d 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -146,7 +146,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva", "src\OpenTelemetry.Exporter.Geneva\OpenTelemetry.Exporter.Geneva.csproj", "{1105C814-31DA-4214-BEA8-6DB5FC12C808}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Benchmark", "test\OpenTelemetry.Exporter.Geneva.Benchmark\OpenTelemetry.Exporter.Geneva.Benchmark.csproj", "{F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Benchmarks", "test\OpenTelemetry.Exporter.Geneva.Benchmarks\OpenTelemetry.Exporter.Geneva.Benchmarks.csproj", "{F53FD7F5-DBC0-4FA5-83BA-B4C07A5BD248}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Geneva.Stress", "test\OpenTelemetry.Exporter.Geneva.Stress\OpenTelemetry.Exporter.Geneva.Stress.csproj", "{F632DFB6-38AD-4356-8997-8CCC0492619C}" EndProject @@ -323,7 +323,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http.Tests", "test\OpenTelemetry.Instrumentation.Http.Tests\OpenTelemetry.Instrumentation.Http.Tests.csproj", "{7371E920-ECD0-403A-A009-7A1A301D9763}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http.Benchmark", "test\OpenTelemetry.Instrumentation.Http.Benchmark\OpenTelemetry.Instrumentation.Http.Benchmark.csproj", "{1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Http.Benchmarks", "test\OpenTelemetry.Instrumentation.Http.Benchmarks\OpenTelemetry.Instrumentation.Http.Benchmarks.csproj", "{1156D564-2E3C-47D6-97C1-FF3ADEDC41C8}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.GrpcNetClient", "src\OpenTelemetry.Instrumentation.GrpcNetClient\OpenTelemetry.Instrumentation.GrpcNetClient.csproj", "{0156E342-CE63-46F5-992D-691A7CCB50F8}" EndProject @@ -335,7 +335,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore", "test\TestApp.AspNetCore\TestApp.AspNetCore.csproj", "{1E743561-B1D4-4100-B6AD-1FD25FA8659B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore.Benchmark", "test\OpenTelemetry.Instrumentation.AspNetCore.Benchmark\OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj", "{92CD1B60-74B8-4E6E-9E7F-83AC3C792980}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.AspNetCore.Benchmarks", "test\OpenTelemetry.Instrumentation.AspNetCore.Benchmarks\OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj", "{92CD1B60-74B8-4E6E-9E7F-83AC3C792980}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Contrib.Shared.Tests", "test\OpenTelemetry.Contrib.Shared.Tests\OpenTelemetry.Contrib.Shared.Tests.csproj", "{B13394D6-D3D7-453E-B91A-24C199F41C5E}" EndProject diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs index 8487e73f48..9c892bb358 100644 --- a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] -[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Benchmark" + AssemblyInfo.PublicKey)] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Benchmarks" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Tests" + AssemblyInfo.PublicKey)] [assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Geneva.Stress" + AssemblyInfo.PublicKey)] diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs similarity index 87% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs index 73447b95f7..5bcd0d4358 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/Food.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Logging; -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; public static partial class Food { diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs index 65ec109add..bcf1176f86 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs @@ -28,7 +28,7 @@ .NET SDK 8.0.100 | Export | True | 971.7 ns | 19.47 ns | 44.75 ns | 947.5 ns | - | - | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class LogExporterBenchmarks diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs index d50a2b7ae0..f5fe2f4104 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs @@ -49,7 +49,7 @@ .NET SDK 8.0.202 | ExportHistogramMetricItemWith4Dimensions_Otlp | 513.72 ns | 7.481 ns | 6.998 ns | 0.0038 | 48 B | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class MetricExporterBenchmarks diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs similarity index 98% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs index 15c08c7d62..2b2a469282 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/SerializationBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs @@ -29,7 +29,7 @@ .NET SDK 8.0.100 | TLD_Reset | 7.856 ns | 0.0453 ns | 0.0379 ns | - | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class SerializationBenchmarks diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs index 98aa2a9a71..0f9056bf39 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs @@ -24,7 +24,7 @@ .NET SDK 8.0.100 | TLD_ExportLogRecord | 890.5 ns | 17.48 ns | 25.07 ns | - | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class TLDLogExporterBenchmarks diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs similarity index 98% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs index 33d37bf4be..7f4f31b9ed 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs @@ -23,7 +23,7 @@ .NET SDK 8.0.100 | TLD_ExportActivity | 878.6 ns | 9.84 ns | 9.20 ns | - | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class TLDTraceExporterBenchmarks diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs similarity index 98% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs index 5030b79ef3..fe8d236244 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs @@ -21,7 +21,7 @@ .NET SDK 8.0.100 | CreateActivityWithGenevaExporter | 1,066.0 ns | 20.98 ns | 56.35 ns | 0.0648 | 416 B | */ -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class TraceExporterBenchmarks diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj similarity index 100% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Program.cs similarity index 83% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/Program.cs index 16ccf0abca..246810d5d2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Program.cs @@ -3,7 +3,7 @@ using BenchmarkDotNet.Running; -namespace OpenTelemetry.Exporter.Geneva.Benchmark; +namespace OpenTelemetry.Exporter.Geneva.Benchmarks; internal class Program { diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/README.md similarity index 76% rename from test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md rename to test/OpenTelemetry.Exporter.Geneva.Benchmarks/README.md index d19d5e7f54..0b3d8ca0fe 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/README.md +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/README.md @@ -1,6 +1,6 @@ # OpenTelemetry GenevaExporter Benchmarks -Navigate to `./test/OpenTelemetry.Exporter.Geneva.Benchmark` directory and run +Navigate to `./test/OpenTelemetry.Exporter.Geneva.Benchmarks` directory and run the following command: ```sh diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs similarity index 100% rename from test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs rename to test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs similarity index 99% rename from test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs rename to test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs index b98bb63ca4..14d777d5c3 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs @@ -65,7 +65,7 @@ With Traces and Metrics = Baseline + With Traces + (With Metrics - (Activity creation + `Acitivity.Stop()`)) (they use the same activity) = 2.45 + (1032 + 64) / 1024 = 2.45 + 1.07 = ~3.52KB */ -namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; +namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.Instrumentation; public class AspNetCoreInstrumentationNewBenchmarks { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj similarity index 100% rename from test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/OpenTelemetry.Instrumentation.AspNetCore.Benchmark.csproj rename to test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Program.cs similarity index 80% rename from test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs rename to test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Program.cs index 612690cb98..5e1c1a3d17 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/Program.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Program.cs @@ -3,7 +3,7 @@ using BenchmarkDotNet.Running; -namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark; +namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmarks; internal class Program { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/README.md similarity index 94% rename from test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md rename to test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/README.md index 075e40772c..15065fb784 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark/README.md +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/README.md @@ -1,6 +1,6 @@ # OpenTelemetry ASP.NET Core Instrumentation Benchmarks -Navigate to `./test/OpenTelemetry.Instrumentation.AspNetCore.Benchmark` directory +Navigate to `./test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks` directory and run the following command: ```sh diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs similarity index 98% rename from test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs rename to test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs index 7651010ada..a63a1d2f1c 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmark/Instrumentation/HttpClientInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs @@ -24,7 +24,7 @@ | HttpClientRequest | Traces, Metrics | 175.6 us | 1.96 us | 1.83 us | 0.4883 | 4.28 KB | */ -namespace OpenTelemetry.Instrumentation.Http.Benchmark.Instrumentation; +namespace OpenTelemetry.Instrumentation.Http.Benchmarks.Instrumentation; public class HttpClientInstrumentationBenchmarks { diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/OpenTelemetry.Instrumentation.Http.Benchmark.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj similarity index 100% rename from test/OpenTelemetry.Instrumentation.Http.Benchmark/OpenTelemetry.Instrumentation.Http.Benchmark.csproj rename to test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/Program.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Program.cs similarity index 100% rename from test/OpenTelemetry.Instrumentation.Http.Benchmark/Program.cs rename to test/OpenTelemetry.Instrumentation.Http.Benchmarks/Program.cs diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/README.md similarity index 87% rename from test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md rename to test/OpenTelemetry.Instrumentation.Http.Benchmarks/README.md index 2cc3e82fbc..51e5bad021 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmark/README.md +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/README.md @@ -1,7 +1,7 @@ # OpenTelemetry HTTP Instrumentation Benchmarks -Navigate to `./test/OpenTelemetry.Instrumentation.Http.Benchmark` directory and run -the following command: +Navigate to `./test/OpenTelemetry.Instrumentation.Http.Benchmarks` directory +and run the following command: ```sh dotnet run -c Release -f net8.0 -- -m From 80e1e99891edd80f3bf94ac75f2e5fe1a5e76727 Mon Sep 17 00:00:00 2001 From: Ilia Brahinets Date: Tue, 21 May 2024 19:27:09 +0300 Subject: [PATCH 1084/1499] [Instrumentation.GrpcCore] Release 1.0.0-beta.6 (#1818) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 8f737f68dd..9bb02bb65a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.6 + +Released 2024-May-21 + * Make the context propagation extraction case insensitive. ([#483](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/483)) * Update minimal supported version of `Google.Protobuf` to `3.15.0`. @@ -18,11 +22,15 @@ ## 1.0.0-beta.5 +Released 2022-Mar-25 + * Switched Grpc.Core package dependency to Grpc.Core.Api in the same range. No functional change, just less exposure to unnecessary packages. ## 1.0.0-beta.4 +Released 2022-Mar-18 + * Going forward the NuGet package will be [`OpenTelemetry.Instrumentation.GrpcCore`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore). Older versions will remain at @@ -37,6 +45,8 @@ ## 1.0.0-beta3 +Released 2021-Jun-11 + * Updated OpenTelemetry SDK package version to 1.1.0-beta1 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) @@ -45,6 +55,8 @@ ## 1.0.0-beta2 +Released 2021-Mar-17 + * This is the first release of `OpenTelemetry.Contrib.Instrumentation.GrpcCore` package. From 9078ceb7a2ae273422412dcb6ae82d50cf7f8a9e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 21 May 2024 09:56:13 -0700 Subject: [PATCH 1085/1499] [repo] Automate tasks performed when a core release is pushed from main repo (#1819) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .github/workflows/core-version-update.yml | 39 ++++ build/scripts/post-release.psm1 | 252 +++++++++++++++++++++- opentelemetry-dotnet-contrib.sln | 1 + 3 files changed, 290 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/core-version-update.yml diff --git a/.github/workflows/core-version-update.yml b/.github/workflows/core-version-update.yml new file mode 100644 index 0000000000..58d23fd0f9 --- /dev/null +++ b/.github/workflows/core-version-update.yml @@ -0,0 +1,39 @@ +name: Core version update + +on: + workflow_dispatch: + inputs: + tag: + required: true + description: 'Release tag' + type: string + +permissions: + contents: write + pull-requests: write + +jobs: + core-version-update: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + with: + # Note: By default GitHub only fetches 1 commit. MinVer needs to find + # the version tag which is typically NOT on the first commit so we + # retrieve them all. + fetch-depth: 0 + + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + + - name: Create GitHub Pull Request to update core version in props and update CHANGELOGs in projects + shell: pwsh + run: | + Import-Module .\build\scripts\post-release.psm1 + + CreateOpenTelemetryCoreLatestVersionUpdatePullRequest ` + -tag '${{ inputs.tag }}' + env: + GH_TOKEN: ${{ github.token }} diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index 2b4c364307..374948c6c1 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -28,7 +28,6 @@ function CreateRelease { $changelogContent = Get-Content -Path "src/$packageName/CHANGELOG.md" - $headingWritten = $false $started = $false $content = "" @@ -181,7 +180,7 @@ function CreatePackageValidationBaselineVersionUpdatePullRequest { $body = @" -Note: This PR was opened automatically by the [package workflow](https://github.com/$gitRepository/actions/workflows/Component.Package.yml). +Note: This PR was opened automatically by the [package workflow](https://github.com/$gitRepository/actions/workflows/publish-packages.yml). Merge once packages are available on NuGet and the build passes. @@ -199,3 +198,252 @@ Merge once packages are available on NuGet and the build passes. } Export-ModuleMember -Function CreatePackageValidationBaselineVersionUpdatePullRequest + +function CreateOpenTelemetryCoreLatestVersionUpdatePullRequest { + param( + [Parameter(Mandatory=$true)][string]$tag, + [Parameter()][string]$gitUserName=$gitHubBotUserName, + [Parameter()][string]$gitUserEmail=$gitHubBotEmail, + [Parameter()][string]$targetBranch="main" + ) + + $match = [regex]::Match($tag, '^(.*?-)(.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse prefix from tag' + } + + $tagPrefix = $match.Groups[1].Value + if ($tagPrefix.StartsWith('core-') -eq $false) + { + Return + } + + $projectsAndDependenciesBefore = GetCoreDependenciesForProjects + + $version = $match.Groups[2].Value + $isPrerelease = ($version.Contains('-alpha.') -or $version.Contains('-beta.') -or $version.Contains('-rc.')) + + $branch="release/post-core-${version}-update" + + $propertyName = "OpenTelemetryCoreLatestVersion" + $propertyVersion = "[$version,2.0)" + if ($isPrerelease -eq $true) + { + $propertyName = "OpenTelemetryCoreLatestPrereleaseVersion" + $propertyVersion = "[$version]" + } + + (Get-Content build/Common.props) ` + -replace "<$propertyName>.*<\/$propertyName>", "<$propertyName>$propertyVersion" | + Set-Content build/Common.props + + $projectsAndDependenciesAfter = GetCoreDependenciesForProjects + + $changedProjects = @{} + + $projectsAndDependenciesBefore.GetEnumerator() | ForEach-Object { + $projectDir = $_.Key + $projectDependenciesBefore = $_.Value + $projectDependenciesAfter = $projectsAndDependenciesAfter[$projectDir] + + $projectDependenciesBefore.GetEnumerator() | ForEach-Object { + $packageName = $_.Key + $packageVersionBefore = $_.Value + if ($projectDependenciesAfter[$packageName] -ne $packageVersionBefore) + { + $changedProjects[$projectDir] = $true + } + } + } + + git config user.name $gitUserName + git config user.email $gitUserEmail + + git switch --create $branch origin/$targetBranch --no-track 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git switch failure' + } + + git add build/Common.props 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git add failure' + } + + git commit -m "Update $propertyName in Common.props to $version." 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git commit failure' + } + + git push -u origin $branch 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git push failure' + } + + $body = +@" +Note: This PR was opened automatically by the [core version update workflow](https://github.com/$gitRepository/actions/workflows/core-version-update.yml). + +Merge once packages are available on NuGet and the build passes. + +## Changes + +* Sets ``$propertyName`` in ``Common.props`` to ``$version``. +"@ + + $createPullRequestResponse = gh pr create ` + --title "[repo] Core release $version updates" ` + --body $body ` + --base $targetBranch ` + --head $branch ` + --label infra + + $match = [regex]::Match($createPullRequestResponse, "\/pull\/(.*)$") + if ($match.Success -eq $false) + { + throw 'Could not parse pull request number from gh pr create response' + } + + $pullRequestNumber = $match.Groups[1].Value + + if ($changedProjects.Count -eq 0) + { + Return + } + +$entry = @" +* Updated OpenTelemetry core component version(s) to ``$version``. + ([#$pullRequestNumber](https://github.com/$gitRepository/pull/$pullRequestNumber)) + + +"@ + + $lastLineBlank = $true + + foreach ($projectDir in $changedProjects.Keys) + { + $path = Join-Path -Path $projectDir -ChildPath "CHANGELOG.md" + + $changelogContent = Get-Content -Path $path + + $started = $false + $isRemoving = $false + $content = "" + + foreach ($line in $changelogContent) + { + if ($line -like "## Unreleased" -and $started -ne $true) + { + $started = $true + } + elseif ($line -like "## *" -and $started -eq $true) + { + if ($lastLineBlank -eq $false) + { + $content += "`r`n" + } + $content += $entry + $started = $false + $isRemoving = $false + } + elseif ($line -like '*Update* OpenTelemetry SDK version to*' -and $started -eq $true) + { + $isRemoving = $true + continue + } + + if ($line.StartsWith('* ')) + { + if ($isRemoving -eq $true) + { + $isRemoving = $false + } + + if ($lastLineBlank -eq $false) + { + $content += "`r`n" + } + } + + if ($isRemoving -eq $true) + { + continue + } + + $content += $line + "`r`n" + + $lastLineBlank = [string]::IsNullOrWhitespace($line) + } + + if ($started -eq $true) + { + # Note: If we never wrote the entry it means the file ended in the unreleased section + if ($lastLineBlank -eq $false) + { + $content += "`r`n" + } + $content += $entry + } + + Set-Content -Path $path -Value $content.TrimEnd() + + git add $path 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git add failure' + } + } + + git commit -m "Update CHANGELOGs for projects using $propertyName." 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git commit failure' + } + + git push -u origin $branch 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git push failure' + } +} + +Export-ModuleMember -Function CreateOpenTelemetryCoreLatestVersionUpdatePullRequest + +function GetCoreDependenciesForProjects { + $projects = @(Get-ChildItem -Path 'src/*/*.csproj') + + $projectsAndDependencies = @{} + + foreach ($project in $projects) + { + # Note: dotnet restore may fail if the core packages aren't available yet but that is fine, we just want to generate project.assets.json for these projects. + $output = dotnet restore $project + + $projectDir = $project | Split-Path -Parent + + $content = (Get-Content "$projectDir/obj/project.assets.json" -Raw) + + $projectDependencies = @{} + + $matches = [regex]::Matches($content, '"(OpenTelemetry(?:.*))?": {[\S\s]*?"target": "Package",[\S\s]*?"version": "(.*)"[\S\s]*?}') + foreach ($match in $matches) + { + $packageName = $match.Groups[1].Value + $packageVersion = $match.Groups[2].Value + if ($packageName -eq 'OpenTelemetry' -or + $packageName -eq 'OpenTelemetry.Api' -or + $packageName -eq 'OpenTelemetry.Api.ProviderBuilderExtensions' -or + $packageName -eq 'OpenTelemetry.Extensions.Hosting') + { + $projectDependencies[$packageName.ToString()] = $packageVersion.ToString() + } + } + $projectsAndDependencies[$projectDir.ToString()] = $projectDependencies + } + + return $projectsAndDependencies +} diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index eb40cb1b7d..a22def56b0 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -33,6 +33,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .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 + .github\workflows\core-version-update.yml = .github\workflows\core-version-update.yml .github\workflows\dotnet-format.yml = .github\workflows\dotnet-format.yml .github\workflows\integration.yml = .github\workflows\integration.yml .github\workflows\markdownlint.yml = .github\workflows\markdownlint.yml From b3f509acb09230fa52dceb488ff6dd6738501acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 21 May 2024 20:52:38 +0200 Subject: [PATCH 1086/1499] [Instrumentation.GrpcNetClient] Nullable (#1815) --- .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 10 +-- .../GrpcClientInstrumentation.cs | 2 +- .../GrpcClientTraceInstrumentationOptions.cs | 4 +- .../GrpcClientDiagnosticListener.cs | 67 ++++++++++--------- ...metry.Instrumentation.GrpcNetClient.csproj | 2 - .../TracerProviderBuilderExtensions.cs | 6 +- .../GrpcServer.cs | 8 +-- .../GrpcTestHelpers/ClientTestHelpers.cs | 8 +-- .../GrpcTests.client.cs | 4 +- .../GrpcTests.server.cs | 4 +- ...Instrumentation.GrpcNetClient.Tests.csproj | 2 - 12 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt index 32e717dc82..f9e6e3fe3b 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/.publicApi/PublicAPI.Unshipped.txt @@ -1,12 +1,12 @@ OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions -OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.get -> System.Action? OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpRequestMessage.set -> void -OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action +OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.get -> System.Action? OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.EnrichWithHttpResponseMessage.set -> void OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.GrpcClientTraceInstrumentationOptions() -> void OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.GrpcNetClient.GrpcClientTraceInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs index 961ddc1774..3a4ffa9d4f 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientInstrumentation.cs @@ -16,7 +16,7 @@ internal sealed class GrpcClientInstrumentation : IDisposable /// Initializes a new instance of the class. /// /// Configuration options for Grpc client instrumentation. - public GrpcClientInstrumentation(GrpcClientTraceInstrumentationOptions options = null) + public GrpcClientInstrumentation(GrpcClientTraceInstrumentationOptions options) { this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new GrpcClientDiagnosticListener(options), isEnabledFilter: null, GrpcInstrumentationEventSource.Log.UnknownErrorProcessingEvent); this.diagnosticSourceSubscriber.Subscribe(); diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs index b4cd871980..a7f9307854 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/GrpcClientTraceInstrumentationOptions.cs @@ -22,7 +22,7 @@ public class GrpcClientTraceInstrumentationOptions /// : the activity being enriched. /// object from which additional information can be extracted to enrich the activity. /// - public Action EnrichWithHttpRequestMessage { get; set; } + public Action? EnrichWithHttpRequestMessage { get; set; } /// /// Gets or sets an action to enrich an Activity with . @@ -31,5 +31,5 @@ public class GrpcClientTraceInstrumentationOptions /// : the activity being enriched. /// object from which additional information can be extracted to enrich the activity. /// - public Action EnrichWithHttpResponseMessage { get; set; } + public Action? EnrichWithHttpResponseMessage { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs index 99e5e89e02..5742dae08b 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs @@ -2,9 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; -#endif using System.Reflection; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; @@ -16,7 +14,7 @@ internal sealed class GrpcClientDiagnosticListener : ListenerHandler { internal static readonly Assembly Assembly = typeof(GrpcClientDiagnosticListener).Assembly; internal static readonly AssemblyName AssemblyName = Assembly.GetName(); - internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly string ActivitySourceName = AssemblyName.Name!; internal static readonly string Version = Assembly.GetPackageVersion(); internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version); @@ -34,26 +32,27 @@ public GrpcClientDiagnosticListener(GrpcClientTraceInstrumentationOptions option this.options = options; } - public override void OnEventWritten(string name, object payload) + public override void OnEventWritten(string name, object? payload) { + var activity = Activity.Current!; switch (name) { case OnStartEvent: { - this.OnStartActivity(Activity.Current, payload); + this.OnStartActivity(activity, payload); } break; case OnStopEvent: { - this.OnStopActivity(Activity.Current, payload); + this.OnStopActivity(activity, payload); } break; } } - public void OnStartActivity(Activity activity, object payload) + public void OnStartActivity(Activity activity, object? payload) { // The overall flow of what GrpcClient library does is as below: // Activity.Start() @@ -71,7 +70,7 @@ public void OnStartActivity(Activity activity, object payload) } // Ensure context propagation irrespective of sampling decision - if (!TryFetchRequest(payload, out HttpRequestMessage request)) + if (!TryFetchRequest(payload, out HttpRequestMessage? request)) { GrpcInstrumentationEventSource.Log.NullPayload(nameof(GrpcClientDiagnosticListener), nameof(this.OnStartActivity)); return; @@ -113,31 +112,39 @@ public void OnStartActivity(Activity activity, object payload) var grpcMethod = GrpcTagHelper.GetGrpcMethodFromActivity(activity); - activity.DisplayName = grpcMethod?.Trim('/'); - - activity.SetTag(SemanticConventions.AttributeRpcSystem, GrpcTagHelper.RpcSystemGrpc); - - if (GrpcTagHelper.TryParseRpcServiceAndRpcMethod(grpcMethod, out var rpcService, out var rpcMethod)) + if (grpcMethod != null) { - activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); - activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + activity.DisplayName = grpcMethod.Trim('/'); - // Remove the grpc.method tag added by the gRPC .NET library - activity.SetTag(GrpcTagHelper.GrpcMethodTagName, null); + if (GrpcTagHelper.TryParseRpcServiceAndRpcMethod(grpcMethod, out var rpcService, out var rpcMethod)) + { + activity.SetTag(SemanticConventions.AttributeRpcService, rpcService); + activity.SetTag(SemanticConventions.AttributeRpcMethod, rpcMethod); + + // Remove the grpc.method tag added by the gRPC .NET library + activity.SetTag(GrpcTagHelper.GrpcMethodTagName, null); + } } - var uriHostNameType = Uri.CheckHostName(request.RequestUri.Host); + activity.SetTag(SemanticConventions.AttributeRpcSystem, GrpcTagHelper.RpcSystemGrpc); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) - { - activity.SetTag(SemanticConventions.AttributeServerSocketAddress, request.RequestUri.Host); - } - else + var requestUri = request.RequestUri; + + if (requestUri != null) { - activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); - } + var uriHostNameType = Uri.CheckHostName(requestUri.Host); - activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + { + activity.SetTag(SemanticConventions.AttributeServerSocketAddress, requestUri.Host); + } + else + { + activity.SetTag(SemanticConventions.AttributeServerAddress, requestUri.Host); + } + + activity.SetTag(SemanticConventions.AttributeServerPort, requestUri.Port); + } try { @@ -154,11 +161,11 @@ public void OnStartActivity(Activity activity, object payload) #if NET6_0_OR_GREATER [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif - static bool TryFetchRequest(object payload, out HttpRequestMessage request) + static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) => StartRequestFetcher.TryFetch(payload, out request) && request != null; } - public void OnStopActivity(Activity activity, object payload) + public void OnStopActivity(Activity activity, object? payload) { if (activity.IsAllDataRequested) { @@ -177,7 +184,7 @@ public void OnStopActivity(Activity activity, object payload) // Remove the grpc.status_code tag added by the gRPC .NET library activity.SetTag(GrpcTagHelper.GrpcStatusCodeTagName, null); - if (TryFetchResponse(payload, out HttpResponseMessage response)) + if (TryFetchResponse(payload, out HttpResponseMessage? response)) { try { @@ -195,7 +202,7 @@ public void OnStopActivity(Activity activity, object payload) #if NET6_0_OR_GREATER [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif - static bool TryFetchResponse(object payload, out HttpResponseMessage response) + static bool TryFetchResponse(object? payload, [NotNullWhen(true)] out HttpResponseMessage? response) => StopResponseFetcher.TryFetch(payload, out response) && response != null; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index 141ff8c25a..be8d44f297 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -7,8 +7,6 @@ Instrumentation.GrpcNetClient- enable - - disable - disable From 9f992663d7fd53f046d2391ef4f265f635e8f11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 21 May 2024 21:08:02 +0200 Subject: [PATCH 1087/1499] [Instrumentation.AspNet] Improve enrich methods (#1824) --- .../.publicApi/PublicAPI.Unshipped.txt | 8 +++- .../AspNetTraceInstrumentationOptions.cs | 24 ++++++++++-- .../CHANGELOG.md | 13 +++++++ .../Implementation/HttpInListener.cs | 6 +-- .../README.md | 39 +++++++++---------- 5 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Unshipped.txt index ab28fe9ed9..9c6d819221 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNet/.publicApi/PublicAPI.Unshipped.txt @@ -5,8 +5,12 @@ OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.Enrich. OpenTelemetry.Instrumentation.AspNet.AspNetMetricsInstrumentationOptions.EnrichFunc OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.AspNetTraceInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Enrich.get -> System.Action? -OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Enrich.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.EnrichWithException.get -> System.Action? +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.EnrichWithException.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.EnrichWithHttpRequest.get -> System.Action? +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.EnrichWithHttpRequest.set -> void +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.EnrichWithHttpResponse.get -> System.Action? +OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.EnrichWithHttpResponse.set -> void OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Filter.get -> System.Func? OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.AspNet.AspNetTraceInstrumentationOptions.RecordException.get -> bool diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs index f5ec023288..ffb6993b31 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs @@ -55,11 +55,27 @@ public AspNetTraceInstrumentationOptions() /// /// /// : the activity being enriched. - /// string: the name of the event. - /// object: the raw object from which additional information can be extracted to enrich the activity. - /// The type of this object depends on the event, which is given by the above parameter. + /// : the HttpRequest object from which additional information can be extracted to enrich the activity. /// - public Action? Enrich { get; set; } + public Action? EnrichWithHttpRequest { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the HttpResponse object from which additional information can be extracted to enrich the activity. + /// + public Action? EnrichWithHttpResponse { get; set; } + + /// + /// Gets or sets an action to enrich an Activity. + /// + /// + /// : the activity being enriched. + /// : the Exception object from which additional information can be extracted to enrich the activity. + /// + public Action? EnrichWithException { get; set; } /// /// Gets or sets a value indicating whether the exception will be recorded as ActivityEvent or not. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 0fcaeef82d..4691709561 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## Unreleased + +* **Breaking change** The `Enrich` callback option has been removed. + For better usability, it has been replaced by three separate options: + `EnrichWithHttpRequest`, `EnrichWithHttpResponse` and `EnrichWithException`. + Previously, the single `Enrich` callback required the consumer to detect + which event triggered the callback to be invoked (e.g., request start, + response end, or an exception) and then cast the object received to the + appropriate type: `HttpRequest`, `HttpResponse`, or `Exception`. The separate + callbacks make it clear what event triggers them and there is no longer the + need to cast the argument to the expected type. + ([#1824](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1824)) + ## 1.8.0-beta.2 Released 2024-Apr-17 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index e31b10327d..374e1729d7 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -102,7 +102,7 @@ private void OnStartActivity(Activity activity, HttpContext context) try { - this.options.Enrich?.Invoke(activity, "OnStartActivity", request); + this.options.EnrichWithHttpRequest?.Invoke(activity, request); } catch (Exception ex) { @@ -135,7 +135,7 @@ private void OnStopActivity(Activity activity, HttpContext context) try { - this.options.Enrich?.Invoke(activity, "OnStopActivity", response); + this.options.EnrichWithHttpResponse?.Invoke(activity, response); } catch (Exception ex) { @@ -158,7 +158,7 @@ private void OnException(Activity activity, HttpContext context, Exception excep try { - this.options.Enrich?.Invoke(activity, "OnException", exception); + this.options.EnrichWithException?.Invoke(activity, exception); } catch (Exception ex) { diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index c3746b9028..e996cc1bb9 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -164,35 +164,32 @@ and the `Filter` option does the filtering *before* the Sampler is invoked. ### Trace Enrich -This option allows one to enrich the activity with additional information from -the raw `HttpRequest`, `HttpResponse` objects. The `Enrich` action is called +This instrumentation library provides `EnrichWithHttpRequest`, +`EnrichWithHttpResponse` and `EnrichWithException` options that can be used to +enrich the activity with additional information from the raw `HttpRequest`, +`HttpResponse` and `Exception` objects respectively. These actions are called only when `activity.IsAllDataRequested` is `true`. It contains the activity -itself (which can be enriched), the name of the event, and the actual raw -object. For event name "OnStartActivity", the actual object will be -`HttpRequest`. For event name "OnStopActivity", the actual object will be -`HttpResponse` +itself (which can be enriched) and the actual raw object. -The following code snippet shows how to add additional tags using `Enrich`. +The following code snippet shows how to enrich the activity using all 3 +different options. ```csharp this.tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation((options) => options.Enrich - = (activity, eventName, rawObject) => + .AddAspNetInstrumentation(o => { - if (eventName.Equals("OnStartActivity")) + o.EnrichWithHttpRequest = (activity, httpRequest) => { - if (rawObject is HttpRequest httpRequest) - { - activity.SetTag("physicalPath", httpRequest.PhysicalPath); - } - } - else if (eventName.Equals("OnStopActivity")) + activity.SetTag("physicalPath", httpRequest.PhysicalPath); + }; + o.EnrichWithHttpResponse = (activity, httpResponse) => { - if (rawObject is HttpResponse httpResponse) - { - activity.SetTag("responseType", httpResponse.ContentType); - } - } + activity.SetTag("responseType", httpResponse.ContentType); + }; + o.EnrichWithException = (activity, exception) => + { + activity.SetTag("exceptionType", exception.GetType().ToString()); + }; }) .Build(); ``` From 34a2ee8c1ea13de043955834489fd1cd5f783d3c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 21 May 2024 13:34:44 -0700 Subject: [PATCH 1088/1499] [aspnet] Fix AspNet rules in CI and issues introduced on latest PR (#1829) --- .github/workflows/ci.yml | 2 +- .../HttpInListenerTests.cs | 58 +++++++++---------- .../HttpInMetricsListenerTests.cs | 9 +-- 3 files changed, 32 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27f703f3a3..12fe5c00b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: code: ['**.cs', '**.csproj', '.editorconfig'] aot: ['src/OpenTelemetry.Extensions.Enrichment/**'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] - aspnet: ['*/OpenTelemetry.Instrumentation.AspNet.*/**', 'examples/AspNet/**', '!**/*.md'] + aspnet: ['*/OpenTelemetry.Instrumentation.AspNet/**', '*/OpenTelemetry.Instrumentation.OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/**', 'examples/AspNet/**', '!**/*.md'] aspnetcore: ['*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!**/*.md'] aws: ['*/OpenTelemetry.*.AWS*/**', '!**/*.md'] azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 4359a3b9b8..e5b84675ad 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -89,7 +89,34 @@ public void AspNetRequestsAreCollectedSuccessfully( return httpContext.Request.Path != filter; }; - options.Enrich = GetEnrichmentAction(setStatusToErrorInEnrich ? ActivityStatusCode.Error : default); + options.EnrichWithHttpRequest = (activity, request) => + { + Assert.NotNull(activity); + Assert.NotNull(request); + + Assert.True(activity.IsAllDataRequested); + }; + + options.EnrichWithHttpResponse = (activity, response) => + { + Assert.NotNull(activity); + Assert.NotNull(response); + + Assert.True(activity.IsAllDataRequested); + + if (setStatusToErrorInEnrich) + { + activity.SetStatus(ActivityStatusCode.Error); + } + }; + + options.EnrichWithException = (activity, exception) => + { + Assert.NotNull(activity); + Assert.NotNull(exception); + + Assert.True(activity.IsAllDataRequested); + }; options.RecordException = recordException; }) @@ -255,35 +282,6 @@ public void ExtractContextIrrespectiveOfTheFilterApplied() Assert.True(isPropagatorCalled); } - private static Action GetEnrichmentAction(ActivityStatusCode statusToBeSet) - { - void EnrichAction(Activity activity, string method, object obj) - { - Assert.True(activity.IsAllDataRequested); - switch (method) - { - case "OnStartActivity": - Assert.True(obj is HttpRequest); - break; - - case "OnStopActivity": - Assert.True(obj is HttpResponse); - if (statusToBeSet != default) - { - activity.SetStatus(statusToBeSet); - } - - break; - - case "OnException": - Assert.True(obj is Exception); - break; - } - } - - return EnrichAction; - } - private class TestSampler(SamplingDecision samplingDecision) : Sampler { private readonly SamplingDecision samplingDecision = samplingDecision; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index 8c39fb7db4..7cb3b0520e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -51,13 +51,10 @@ public void AspNetMetricTagsAreCollectedSuccessfully( // as it is created using ActivitySource inside TelemetryHttpModule // TODO: This should not be needed once the dependency on activity is removed from metrics using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation(opts => opts.Enrich - = (activity, eventName, rawObject) => + .AddAspNetInstrumentation(opts => opts.EnrichWithHttpResponse + = (activity, response) => { - if (eventName.Equals("OnStopActivity")) - { - duration = activity.Duration.TotalSeconds; - } + duration = activity.Duration.TotalSeconds; }) .Build(); From b5cd3d9af51135c655e53761244effb2272e77a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 13:44:30 -0700 Subject: [PATCH 1089/1499] [repo] Core release 1.9.0-alpha.1 updates (#1827) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index a6d4b3c4d0..de509382d6 100644 --- a/build/Common.props +++ b/build/Common.props @@ -40,7 +40,7 @@ [3.11.0-beta1.23525.2] [8.0.0,9.0) [1.8.1,2.0) - [1.8.0-rc.1] + [1.9.0-alpha.1] [2.1.58,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) From 1011988e823460a2611df2f39e292ff123a9ccbd Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 22 May 2024 14:25:40 +0000 Subject: [PATCH 1090/1499] Fix typo in README (#1832) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 18f92c8d95..dd10228236 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb [@open-telemetry/dotnet-contrib-approvers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-approvers): -The are no approvers today. +There are no approvers today. *Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).* From 200d66d844d6790af665d8c4f8bc3d10349ee864 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Wed, 22 May 2024 15:10:28 -0500 Subject: [PATCH 1091/1499] Fix variable usage in test-aot-compatibility script (#1837) --- 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 ca04cfe3de..5687ba1d25 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 4da345122567dc15e77da81260fa0b1bdcc18fb1 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 22 May 2024 13:26:19 -0700 Subject: [PATCH 1092/1499] [Exporter.Geneva] 1.9.0-alpha.1 release prep (#1834) --- .../CHANGELOG.md | 7 ++++ .../Common.GenevaExporter.props | 2 +- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 8 ----- .../Metrics/TlvMetricExporter.cs | 25 +------------ .../Exporter/MetricExporterBenchmarks.cs | 17 +-------- .../GenevaMetricExporterTests.cs | 34 ------------------ .../OtlpProtobufMetricExporterTests.cs | 36 +------------------ 7 files changed, 11 insertions(+), 118 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 31d7907aed..c7305b6af7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.9.0-alpha.1 + +Released 2024-May-22 + +* Update OpenTelemetry SDK version to `1.9.0-alpha.1`. + ([#1834](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1834)) + ## 1.8.0 Released 2024-May-15 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 5570a7a1fe..78181066e1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestVersion) + $(OpenTelemetryCoreLatestPrereleaseVersion) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 203be4d72f..9f1347bc3f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -394,7 +394,6 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) } } -#if EXPOSE_EXPERIMENTAL_FEATURES if (metricPoint.TryGetExemplars(out var exemplars)) { foreach (ref readonly var exemplar in exemplars) @@ -402,7 +401,6 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.HistogramDataPoint_exemplars); } } -#endif var metricPointStartPosition = this.metricPointTagAndLengthIndex; @@ -489,7 +487,6 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) // write Bucket ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref positiveBucketIndex, cursor - positiveBucketValueIndex, FieldNumberConstants.ExponentialHistogramDataPoint_positive, WireType.LEN); -#if EXPOSE_EXPERIMENTAL_FEATURES if (metricPoint.TryGetExemplars(out var exemplars)) { foreach (ref readonly var exemplar in exemplars) @@ -497,7 +494,6 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.ExponentialHistogramDataPoint_exemplars); } } -#endif var metricPointStartPosition = this.metricPointTagAndLengthIndex; @@ -549,7 +545,6 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum cursor += this.prepopulatedNumberDataPointAttributesLength; } -#if EXPOSE_EXPERIMENTAL_FEATURES if (metricPoint.TryGetExemplars(out var exemplars)) { foreach (ref readonly var exemplar in exemplars) @@ -564,7 +559,6 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum } } } -#endif var metricPointStartPosition = this.metricPointTagAndLengthIndex; @@ -572,7 +566,6 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, fieldNumber, WireType.LEN); } -#if EXPOSE_EXPERIMENTAL_FEATURES private void SerializeExemplar(byte[] buffer, ref int cursor, in Exemplar exemplar, T value, int fieldNumber) { int exemplarTagAndLengthIndex = cursor; @@ -617,7 +610,6 @@ private void SerializeExemplarTags(byte[] buffer, ref int cursor, ReadOnlyFilter SerializeTag(buffer, ref cursor, tag.Key, tag.Value, FieldNumberConstants.Exemplar_attributes); } } -#endif private void WriteIndividualMessageTagsAndLength(byte[] buffer, ref int cursor, MetricType metricType) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index b25eb9e05e..336115979c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -87,9 +87,8 @@ internal ExportResult Export(in Batch batch) { try { -#if EXPOSE_EXPERIMENTAL_FEATURES metricPoint.TryGetExemplars(out var exemplars); -#endif + var metricType = metric.MetricType; switch (metricType) { @@ -103,10 +102,8 @@ internal ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), // Using the endTime here as the timestamp as Geneva Metrics only allows for one field for timestamp metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -126,10 +123,8 @@ internal ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -149,10 +144,8 @@ internal ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -170,10 +163,8 @@ internal ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -190,10 +181,8 @@ internal ExportResult Export(in Batch batch) metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -219,10 +208,8 @@ internal ExportResult Export(in Batch batch) count, min, max, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out monitoringAccount, out metricNamespace); this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); @@ -271,10 +258,8 @@ internal unsafe ushort SerializeMetricWithTLV( long timestamp, in ReadOnlyTagCollection tags, MetricData value, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType metricType, ReadOnlyExemplarCollection exemplars, -#endif out string monitoringAccount, out string metricNamespace) { @@ -301,9 +286,7 @@ internal unsafe ushort SerializeMetricWithTLV( out monitoringAccount, out metricNamespace); -#if EXPOSE_EXPERIMENTAL_FEATURES SerializeExemplars(exemplars, metricType, this.buffer, ref bufferIndex); -#endif SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -336,10 +319,8 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( uint count, double min, double max, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType metricType, ReadOnlyExemplarCollection exemplars, -#endif out string monitoringAccount, out string metricNamespace) { @@ -366,9 +347,7 @@ internal unsafe ushort SerializeHistogramMetricWithTLV( out monitoringAccount, out metricNamespace); -#if EXPOSE_EXPERIMENTAL_FEATURES SerializeExemplars(exemplars, metricType, this.buffer, ref bufferIndex); -#endif SerializeMonitoringAccount(monitoringAccount, this.buffer, ref bufferIndex); @@ -413,7 +392,6 @@ private static void SerializeMonitoringAccount(string monitoringAccount, byte[] MetricSerializer.SerializeString(buffer, ref bufferIndex, monitoringAccount); } -#if EXPOSE_EXPERIMENTAL_FEATURES [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeExemplars(in ReadOnlyExemplarCollection exemplars, MetricType metricType, byte[] buffer, ref int bufferIndex) { @@ -516,7 +494,6 @@ private static void SerializeSingleExemplar(Exemplar exemplar, MetricType metric var exemplarLength = bufferIndex - bufferIndexForLength + 1; MetricSerializer.SerializeByte(buffer, ref bufferIndexForLength, (byte)exemplarLength); } -#endif [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void SerializeNonHistogramMetricData(MetricEventType eventType, MetricData value, long timestamp, byte[] buffer, ref int bufferIndex) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs index f5fe2f4104..0194dc9733 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs @@ -574,19 +574,16 @@ public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() [Benchmark] public void SerializeCounterMetricItemWith3Dimensions() { -#if EXPOSE_EXPERIMENTAL_FEATURES this.counterMetricPointWith3Dimensions.TryGetExemplars(out var exemplars); -#endif + this.tlvMetricsExporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith3Dimensions.Name, this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType.LongSum, exemplars, -#endif out _, out _); } @@ -594,19 +591,15 @@ public void SerializeCounterMetricItemWith3Dimensions() [Benchmark] public void SerializeCounterMetricItemWith4Dimensions() { -#if EXPOSE_EXPERIMENTAL_FEATURES this.counterMetricPointWith4Dimensions.TryGetExemplars(out var exemplars); -#endif this.tlvMetricsExporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, this.counterMetricWith4Dimensions.Name, this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType.LongSum, exemplars, -#endif out _, out _); } @@ -626,9 +619,7 @@ public void ExportCounterMetricItemWith4Dimensions() [Benchmark] public void SerializeHistogramMetricItemWith3Dimensions() { -#if EXPOSE_EXPERIMENTAL_FEATURES this.histogramMetricPointWith3Dimensions.TryGetExemplars(out var exemplars); -#endif this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith3Dimensions.Name, this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), @@ -638,10 +629,8 @@ public void SerializeHistogramMetricItemWith3Dimensions() this.histogramCountWith3Dimensions, this.histogramMinWith3Dimensions, this.histogramMaxWith3Dimensions, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType.Histogram, exemplars, -#endif out _, out _); } @@ -649,9 +638,7 @@ public void SerializeHistogramMetricItemWith3Dimensions() [Benchmark] public void SerializeHistogramMetricItemWith4Dimensions() { -#if EXPOSE_EXPERIMENTAL_FEATURES this.histogramMetricPointWith4Dimensions.TryGetExemplars(out var exemplars); -#endif this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( this.histogramMetricWith4Dimensions.Name, this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), @@ -661,10 +648,8 @@ public void SerializeHistogramMetricItemWith4Dimensions() this.histogramCountWith4Dimensions, this.histogramMinWith4Dimensions, this.histogramMaxWith4Dimensions, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType.Histogram, exemplars, -#endif out _, out _); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 4afcd08d47..039651efa1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -185,19 +185,15 @@ public void SuccessfulExportOnLinux() var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); var metricData = new MetricData { UInt64Value = metricDataValue }; -#if EXPOSE_EXPERIMENTAL_FEATURES metricPoint.TryGetExemplars(out var exemplars); -#endif var bodyLength = exporter.SerializeMetricWithTLV( MetricEventType.ULongMetric, metric.Name, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES MetricType.LongSum, exemplars, -#endif out _, out _); @@ -385,9 +381,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars if (hasExemplars) { -#if EXPOSE_EXPERIMENTAL_FEATURES meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); -#endif } if (hasFilteredTagsForExemplars) @@ -983,9 +977,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; -#if EXPOSE_EXPERIMENTAL_FEATURES metricPoint.TryGetExemplars(out var exemplars); -#endif List fields = null; @@ -1000,10 +992,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1029,10 +1019,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1060,10 +1048,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1091,10 +1077,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1129,10 +1113,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, count, min, max, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1171,7 +1153,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(bodyLength, data.LenBody); } -#if EXPOSE_EXPERIMENTAL_FEATURES List validExemplars = new List(); foreach (var exemplar in exemplars) @@ -1198,7 +1179,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, AssertExemplarFilteredTagSerialization(expectedExemplar, serializedExemplar); } } -#endif // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); @@ -1271,7 +1251,6 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(dimensionsCount, dimensions.NumDimensions); } -#if EXPOSE_EXPERIMENTAL_FEATURES private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExemplar, SingleExemplar serializedExemplar) { var serializedExemplarBody = serializedExemplar.Body; @@ -1328,7 +1307,6 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem Assert.Equal(filteredTagsExpectedCount, filteredTagsActualCount); } -#endif private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exporter) { @@ -1337,9 +1315,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; -#if EXPOSE_EXPERIMENTAL_FEATURES metricPoint.TryGetExemplars(out var exemplars); -#endif UserdataV2 result = null; @@ -1353,10 +1329,8 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1375,10 +1349,8 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1399,10 +1371,8 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1423,10 +1393,8 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp metricPoint.EndTime.ToFileTime(), metricPoint.Tags, metricData, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); @@ -1454,10 +1422,8 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp count, min, max, -#if EXPOSE_EXPERIMENTAL_FEATURES metricType, exemplars, -#endif out _, out _); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 7685755d88..a59df78c09 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -30,7 +30,6 @@ public class OtlpProtobufMetricExporterTests { "Dim3", 3 }, }; -#if EXPOSE_EXPERIMENTAL_FEATURES private static readonly string[] TagKeys = new[] { "boolKey", @@ -51,7 +50,6 @@ public class OtlpProtobufMetricExporterTests "ulongKey", "ushortKey", }; -#endif private TagList exemplarTagList; @@ -206,10 +204,8 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l .AddReader(inMemoryReader); if (isExemplarsEnabled) { -#if EXPOSE_EXPERIMENTAL_FEATURES meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = TagKeys }); -#endif } var meterProvider = meterProviderBuilder.Build(); @@ -217,7 +213,6 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l if (longValue != null) { var counter = meter.CreateCounter(instrumentName); -#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { counter.Add(longValue.Value, this.exemplarTagList); @@ -226,14 +221,10 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l { counter.Add(longValue.Value, this.TagList); } -#else - counter.Add(longValue.Value, this.TagList); -#endif } else { var counter = meter.CreateCounter(instrumentName); -#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { counter.Add(doubleValue.Value, this.exemplarTagList); @@ -242,9 +233,6 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l { counter.Add(doubleValue.Value, this.TagList); } -#else - counter.Add(doubleValue.Value, this.TagList); -#endif } meterProvider.ForceFlush(); @@ -311,7 +299,6 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l Assert.Equal((ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(), dataPoint.TimeUnixNano); -#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { Assert.Single(dataPoint.Exemplars); @@ -361,7 +348,6 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l { Assert.Empty(dataPoint.Exemplars); } -#endif if (addPrepopulatedDimensions) { @@ -806,16 +792,14 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add .AddReader(inMemoryReader); if (isExemplarsEnabled) { -#if EXPOSE_EXPERIMENTAL_FEATURES meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = TagKeys }); -#endif } var meterProvider = meterProviderBuilder.Build(); var histogram = meter.CreateHistogram("TestHistogram"); -#if EXPOSE_EXPERIMENTAL_FEATURES + if (isExemplarsEnabled) { histogram.Record(doubleValue, this.exemplarTagList); @@ -824,9 +808,6 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add { histogram.Record(doubleValue, this.TagList); } -#else - histogram.Record(doubleValue, this.TagList); -#endif meterProvider.ForceFlush(); @@ -916,7 +897,6 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } -#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { Assert.Single(dataPoint.Exemplars); @@ -959,7 +939,6 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add { Assert.Empty(dataPoint.Exemplars); } -#endif } [Theory] @@ -1418,18 +1397,12 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal if (isExemplarsEnabled) { -#if EXPOSE_EXPERIMENTAL_FEATURES meterProviderBuilder.SetExemplarFilter(ExemplarFilterType.AlwaysOn); -#endif } meterProviderBuilder.AddView(instrument => { -#if EXPOSE_EXPERIMENTAL_FEATURES return new Base2ExponentialBucketHistogramConfiguration() { TagKeys = TagKeys }; -#else - return new Base2ExponentialBucketHistogramConfiguration(); -#endif }); var meterProvider = meterProviderBuilder.Build(); @@ -1437,7 +1410,6 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal var instrumentName = "doubleExponentialHistogram"; var histogram = meter.CreateHistogram(instrumentName); -#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { histogram.Record(doubleValue.Value, this.exemplarTagList); @@ -1448,10 +1420,6 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal histogram.Record(doubleValue.Value, this.TagList); histogram.Record(0, this.TagList); } -#else - histogram.Record(doubleValue.Value, this.TagList); - histogram.Record(0, this.TagList); -#endif meterProvider.ForceFlush(); @@ -1542,7 +1510,6 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal AssertOtlpAttributes(this.TagList, dataPoint.Attributes); } -#if EXPOSE_EXPERIMENTAL_FEATURES if (isExemplarsEnabled) { // Exemplars are only emitted for positive/0 values. @@ -1600,7 +1567,6 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal { Assert.Empty(dataPoint.Exemplars); } -#endif } internal static void AssertOtlpAttributes( From fc75ce26b0c7df557c930164fe02aeb7a2a6de3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 23 May 2024 06:26:42 +0200 Subject: [PATCH 1093/1499] [Instrumentation.AspNet] Release 1.8.0-beta.3 (#1836) --- src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 4691709561..cf291d5c39 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.8.0-beta.3 + +Released 2024-May-23 + * **Breaking change** The `Enrich` callback option has been removed. For better usability, it has been replaced by three separate options: `EnrichWithHttpRequest`, `EnrichWithHttpResponse` and `EnrichWithException`. From c81572ee8d5dafb20c91486f967c0935c5290adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 23 May 2024 06:41:46 +0200 Subject: [PATCH 1094/1499] [repo] Use separate, standardized builds for all packages (#1833) Co-authored-by: Mikel Blanchard --- .github/workflows/ci.yml | 603 ++++++++++-------- .../OpenTelemetry.Exporter.InfluxDB.proj | 34 + .../OpenTelemetry.Extensions.Enrichment.proj | 34 + ...penTelemetry.Instrumentation.GrpcCore.proj | 34 + 4 files changed, 444 insertions(+), 261 deletions(-) create mode 100644 build/Projects/OpenTelemetry.Exporter.InfluxDB.proj create mode 100644 build/Projects/OpenTelemetry.Extensions.Enrichment.proj create mode 100644 build/Projects/OpenTelemetry.Instrumentation.GrpcCore.proj diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12fe5c00b6..b647d2f63d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,72 +20,46 @@ jobs: md: [ '**.md' ] build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*', '**/*.targets', '**/*.props'] shared: ['src/Shared/**', 'test/Shared/**'] - sharedtests: ['test/OpenTelemetry.Contrib.Shared.Tests/**'] + contrib-shared-tests: ['test/OpenTelemetry.Contrib.Shared.Tests/**'] code: ['**.cs', '**.csproj', '.editorconfig'] - aot: ['src/OpenTelemetry.Extensions.Enrichment/**'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] - aspnet: ['*/OpenTelemetry.Instrumentation.AspNet/**', '*/OpenTelemetry.Instrumentation.OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/**', 'examples/AspNet/**', '!**/*.md'] - aspnetcore: ['*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!**/*.md'] - aws: ['*/OpenTelemetry.*.AWS*/**', '!**/*.md'] - azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] - eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] + exporter-geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] + exporter-infuxdb: ['*/OpenTelemetry.Exporter.InfluxDB*/**', '!**/*.md'] + exporter-instana: ['*/OpenTelemetry.Exporter.Instana*/**', '!**/*.md'] + exporter-onecollector: ['*/OpenTelemetry.Exporter.OneCollector*/**', '!**/*.md'] + exporter-stackdriver: ['*/OpenTelemetry.Exporter.Stackdriver*/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] - geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] - gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] - grpcnetclient: ['*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', '!**/*.md'] - host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md'] - http: ['*/OpenTelemetry.Instrumentation.Http*/**', '!**/*.md'] - onecollector: ['*/OpenTelemetry.Instrumentation.OneCollector*/**', '!**/*.md'] - owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] + extensions-aws: ['*/OpenTelemetry.Extensions.AWS*/**', '!**/*.md'] + extensions-enrichment: ['*/OpenTelemetry.Extensions.Enrichment*/**', '!**/*.md'] + instrumentation-aspnet: ['*/OpenTelemetry.Instrumentation.AspNet/**', '*/OpenTelemetry.Instrumentation.AspNet.Tests/**', '*/OpenTelemetry.Instrumentation.OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.*/**', 'examples/AspNet/**', '!**/*.md'] + instrumentation-aspnetcore: ['*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!**/*.md'] + instrumentation-aws: ['*/OpenTelemetry.Instrumentation.AWS/**', '*/OpenTelemetry.Instrumentation.AWS.Tests/**', '!**/*.md'] + instrumentation-aws-lambda: ['*/OpenTelemetry.Instrumentation.AWSLambda/**', '*/OpenTelemetry.Instrumentation.AWSLambda.Tests/**', '!**/*.md'] + instrumentation-cassandra: ['*/OpenTelemetry.Instrumentation.Cassandra*/**', '!**/*.md'] + instrumentation-elasticsearchclient: ['*/OpenTelemetry.Instrumentation.ElasticsearchClient*/**', '!**/*.md'] + instrumentation-entityframeworkcore: ['*/OpenTelemetry.Instrumentation.EntityFrameworkCore*/**', '!**/*.md'] + instrumentation-eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] + instrumentation-grpccore: ['*/OpenTelemetry.Instrumentation.GrpcCore*/**', '!**/*.md'] + instrumentation-grpcnetclient: ['*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', '!**/*.md'] + instrumentation-hangfire: ['*/OpenTelemetry.Instrumentation.Hangfire*/**', '!**/*.md'] + instrumentation-http: ['*/OpenTelemetry.Instrumentation.Http*/**', '!**/*.md'] + instrumentation-owin: ['*/OpenTelemetry.Instrumentation.Owin*/**', 'examples/owin/**', '!**/*.md'] + instrumentation-process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] + instrumentation-quartz: ['*/OpenTelemetry.Instrumentation.Quartz*/**', '!**/*.md'] + instrumentation-runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] + instrumentation-sqlclient: ['*/OpenTelemetry.Instrumentation.SqlClient*/**', '!**/*.md'] + instrumentation-stackexchangeredis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] + instrumentation-wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] - process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] - processdetector: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] - processruntime: ['*/OpenTelemetry.Resources.ProcessRuntime/**', '*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!**/*.md'] - redis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] - resourcedetectors: ['*/OpenTelemetry.ResourceDetectors.*/**', '!**/*.md'] - runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] + resourcedetectors-aws: ['*/OpenTelemetry.ResourceDetectors.AWS*/**', '!**/*.md'] + resourcedetectors-azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] + resourcedetectors-container: ['*/OpenTelemetry.ResourceDetectors.Container*/**', '!**/*.md'] + resources-gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] + resources-host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md'] + resources-process: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] + resources-processruntime: ['*/OpenTelemetry.Resources.ProcessRuntime/**', '*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!**/*.md'] + sampler-aws: ['*/OpenTelemetry.Sampler.AWS**/**', '!**/*.md'] semanticconventions: ['*/OpenTelemetry.SemanticConventions*/**', '!**/*.md'] - sqlclient: ['*/OpenTelemetry.Instrumentation.SqlClient*/**', '!**/*.md'] - wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] - solution: [ - 'src/**', - 'test/**', - 'examples/**', - '!test/OpenTelemetry.AotCompatibility.TestApp/**', - '!*/OpenTelemetry.Instrumentation.AspNet.*/**', - '!*/OpenTelemetry.Instrumentation.AspNetCore*/**', - '!examples/AspNet/**', - '!*/OpenTelemetry.ResourceDetectors.Azure*/**', - '!*/OpenTelemetry.Resources.Host*/**', - '!*/OpenTelemetry.Resources.Gcp*/**', - '!*/OpenTelemetry.Resources.Process/**', - '!*/OpenTelemetry.Resources.Process.Tests/**', - '!*/OpenTelemetry.Resources.ProcessRuntime/**', - '!*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', - '!*/OpenTelemetry.Instrumentation.EventCounters*/**', - '!examples/event-counters/**', - '!*/OpenTelemetry.Extensions/**', - '!*/OpenTelemetry.Extensions.Tests/**', - '!*/OpenTelemetry.Exporter.Geneva*/**', - '!*/OpenTelemetry.Exporter.OneCollector*/**', - '!*/OpenTelemetry.Instrumentation.Owin*/**', - '!examples/owin/**', - '!*/OpenTelemetry.PersistentStorage*/**', - '!*/OpenTelemetry.Instrumentation.GrpcNetClient*/**', - '!*/OpenTelemetry.Instrumentation.Http*/**', - '!*/OpenTelemetry.Instrumentation.Process*/**', - '!examples/process-instrumentation/**', - '!*/OpenTelemetry.Instrumentation.SqlClient*/**', - '!*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', - '!examples/redis/**', - '!*/OpenTelemetry.Instrumentation.Runtime*/**', - '!examples/runtime-instrumentation/**', - '!*/OpenTelemetry.SemanticConventions*/**', - '!*/OpenTelemetry.Instrumentation.Wcf*/**', - '!examples/wcf/**', - '!*/OpenTelemetry.Contrib.Shared.Tests/**', - '!**/*.md' - ] lint-md: needs: detect-changes @@ -101,10 +75,98 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'build') uses: ./.github/workflows/dotnet-format.yml - build-test-aspnet: + build-test-exporter-geneva: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'aspnet') + contains(needs.detect-changes.outputs.changes, 'exporter-geneva') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Exporter.Geneva] + code-cov-name: Exporter.Geneva + + build-test-exporter-influxdb: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'exporter-influxdb') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Exporter.InfluxDB + code-cov-name: Exporter.InfluxDB + + build-test-exporter-instana: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'exporter-instana') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Exporter.Instana] + code-cov-name: Exporter.Instana + + build-test-exporter-onecollector: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'exporter-onecollector') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Exporter.OneCollector] + code-cov-name: Exporter.OneCollector + + build-test-exporter-stackdriver: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'exporter-stackdriver') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Exporter.Stackdriver] + code-cov-name: Exporter.Stackdriver + + build-test-extensions: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'extensions') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Extensions] + code-cov-name: Extensions + + build-test-extensions-aws: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'extensions-aws') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Extensions.AWS] + code-cov-name: Extensions.AWS + + build-test-extensions-enrichment: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'extensions-enrichment') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Extensions.Enrichment + code-cov-name: Extensions.Enrichment + + build-test-instrumentation-aspnet: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'instrumentation-aspnet') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml @@ -114,10 +176,10 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' - build-test-aspnetcore: + build-test-instrumentation-aspnetcore: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'aspnetcore') + contains(needs.detect-changes.outputs.changes, 'instrumentation-aspnetcore') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml @@ -126,110 +188,122 @@ jobs: code-cov-name: Instrumentation.AspNetCore tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' - build-test-azure: + build-test-instrumentation-aws: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'azure') + contains(needs.detect-changes.outputs.changes, 'instrumentation-aws') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.ResourceDetectors.Azure] - code-cov-name: ResourceDetectors.Azure + project-name: Component[OpenTelemetry.Instrumentation.AWS] + code-cov-name: Instrumentation.AWS - build-test-eventcounters: + build-test-instrumentation-awslambda: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'eventcounters') + contains(needs.detect-changes.outputs.changes, 'instrumentation-awslambda') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.Instrumentation.EventCounters - code-cov-name: Instrumentation.EventCounters + project-name: Component[OpenTelemetry.Instrumentation.AWSLambda] + code-cov-name: Instrumentation.AWSLambda tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' - build-test-extensions: + build-test-instrumentation-cassandra: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'extensions') + contains(needs.detect-changes.outputs.changes, 'instrumentation-cassandra') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Extensions] - code-cov-name: Extensions + project-name: Component[OpenTelemetry.Instrumentation.Cassandra] + code-cov-name: Instrumentation.Cassandra - build-test-geneva: + build-test-instrumentation-elasticsearchclient: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'geneva') + contains(needs.detect-changes.outputs.changes, 'instrumentation-elasticsearchclient') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Exporter.Geneva] - code-cov-name: Exporter.Geneva + project-name: Component[OpenTelemetry.Instrumentation.ElasticsearchClient] + code-cov-name: Instrumentation.ElasticsearchClient - build-test-gcp: + build-test-instrumentation-entityframeworkcore: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'gcp') + contains(needs.detect-changes.outputs.changes, 'instrumentation-entityframeworkcore') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Resources.Gcp] - code-cov-name: Resources.Gcp + project-name: Component[OpenTelemetry.Instrumentation.EntityFrameworkCore] + code-cov-name: Instrumentation.EntityFrameworkCore - build-test-grpcnetclient: + build-test-instrumentation-eventcounters: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'grpcnetclient') + contains(needs.detect-changes.outputs.changes, 'instrumentation-eventcounters') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Instrumentation.GrpcNetClient] - code-cov-name: Instrumentation.GrpcNetClient + project-name: OpenTelemetry.Instrumentation.EventCounters + code-cov-name: Instrumentation.EventCounters + tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' - build-test-host: + build-test-instrumentation-grpccore: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'host') + contains(needs.detect-changes.outputs.changes, 'instrumentation-grpccore') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Resources.Host] - code-cov-name: Resources.Host + project-name: OpenTelemetry.Instrumentation.GrpcCore + code-cov-name: Instrumentation.GrpcCore - build-test-http: + build-test-instrumentation-grpcnetclient: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'http') + contains(needs.detect-changes.outputs.changes, 'instrumentation-grpcnetclient') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Instrumentation.Http] - code-cov-name: Instrumentation.Http + project-name: Component[OpenTelemetry.Instrumentation.GrpcNetClient] + code-cov-name: Instrumentation.GrpcNetClient - build-test-onecollector: + build-test-instrumentation-hangfire: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'onecollector') + contains(needs.detect-changes.outputs.changes, 'instrumentation-hangfire') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Exporter.OneCollector] - code-cov-name: Exporter.OneCollector + project-name: Component[OpenTelemetry.Instrumentation.Hangfire] + code-cov-name: Instrumentation.Hangfire + + build-test-instrumentation-http: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'instrumentation-http') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Instrumentation.Http] + code-cov-name: Instrumentation.Http - build-test-owin: + build-test-instrumentation-owin: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'owin') + contains(needs.detect-changes.outputs.changes, 'instrumentation-owin') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml @@ -239,54 +313,54 @@ jobs: os-list: '[ "windows-latest" ]' tfm-list: '[ "net462" ]' - build-test-persistentstorage: + build-test-instrumentation-process: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'persistentstorage') + contains(needs.detect-changes.outputs.changes, 'instrumentation-process') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.PersistentStorage - code-cov-name: PersistentStorage + project-name: OpenTelemetry.Instrumentation.Process + code-cov-name: Instrumentation.Process - build-test-process: + build-test-instrumentation-quartz: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'process') + contains(needs.detect-changes.outputs.changes, 'instrumentation-quartz') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.Instrumentation.Process - code-cov-name: Instrumentation.Process + project-name: Component[OpenTelemetry.Instrumentation.Quartz] + code-cov-name: Instrumentation.Quartz - build-test-processdetector: + build-test-instrumentation-runtime: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'processdetector') + contains(needs.detect-changes.outputs.changes, 'instrumentation-runtime') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Resources.Process] - code-cov-name: Resources.Process + project-name: OpenTelemetry.Instrumentation.Runtime + code-cov-name: Instrumentation.Runtime - build-test-processruntime: + build-test-instrumentation-sqlclient: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'processruntime') + contains(needs.detect-changes.outputs.changes, 'instrumentation-sqlclient') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Resources.ProcessRuntime] - code-cov-name: Resources.ProcessRuntime + project-name: Component[OpenTelemetry.Instrumentation.SqlClient] + code-cov-name: Instrumentation.SqlClient - build-test-redis: + build-test-instrumentation-stackexchangeredis: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'redis') + contains(needs.detect-changes.outputs.changes, 'instrumentation-stackexchangeredis') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml @@ -294,180 +368,172 @@ jobs: project-name: OpenTelemetry.Instrumentation.StackExchangeRedis code-cov-name: Instrumentation.StackExchangeRedis - build-test-redis-integration: + build-test-instrumentation-stackexchangeredis-integration: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'redis') + contains(needs.detect-changes.outputs.changes, 'instrumentation-stackexchangeredis') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/integration.yml - build-test-runtime: + build-test-instrumentation-wcf: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'runtime') + contains(needs.detect-changes.outputs.changes, 'instrumentation-wcf') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.Instrumentation.Runtime - code-cov-name: Instrumentation.Runtime + project-name: OpenTelemetry.Instrumentation.Wcf + code-cov-name: Instrumentation.Wcf - build-test-semanticconventions: + build-test-persistentstorage: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'semanticconventions') + contains(needs.detect-changes.outputs.changes, 'persistentstorage') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.SemanticConventions - code-cov-name: SemanticConventions + project-name: OpenTelemetry.PersistentStorage + code-cov-name: PersistentStorage - build-test-sqlclient: + build-test-resourcedetectors-aws: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'sqlclient') + contains(needs.detect-changes.outputs.changes, 'resourcedetectors-aws') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Instrumentation.SqlClient] - code-cov-name: Instrumentation.SqlClient + project-name: Component[OpenTelemetry.ResourceDetectors.AWS] + code-cov-name: ResourceDetectors.AWS - build-test-wcf: + build-test-resourcedetectors-azure: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'wcf') + contains(needs.detect-changes.outputs.changes, 'resourcedetectors-azure') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.Instrumentation.Wcf - code-cov-name: Instrumentation.Wcf + project-name: Component[OpenTelemetry.ResourceDetectors.Azure] + code-cov-name: ResourceDetectors.Azure - build-test-sharedtests: + build-test-resourcedetectors-container: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'sharedtests') + contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: OpenTelemetry.Contrib.Shared.Tests - code-cov-name: Contrib.Shared.Tests + project-name: Component[OpenTelemetry.ResourceDetectors.Container] + code-cov-name: ResourceDetectors.Container + + build-test-resources-gcp: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'resources-gcp') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Resources.Gcp] + code-cov-name: Resources.Gcp + + build-test-resources-host: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'resources-host') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Resources.Host] + code-cov-name: Resources.Host - build-test-solution: + build-test-resources-process: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'solution') + contains(needs.detect-changes.outputs.changes, 'resources-process') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Resources.Process] + code-cov-name: Resources.Process - strategy: - fail-fast: false # ensures the entire test matrix is run, even if one permutation fails - matrix: - os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0, net8.0 ] - exclude: - - os: ubuntu-latest - version: net462 + build-test-resources-processruntime: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'resources-processruntime') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Resources.ProcessRuntime] + code-cov-name: Resources.ProcessRuntime - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - - name: Setup dotnet - uses: actions/setup-dotnet@v4 - - - name: Restore, Build, & Test ${{ matrix.version }} - shell: pwsh - run: | - $projects = Get-ChildItem ` - -Path test/*.Tests/*.csproj ` - -Exclude ` - OpenTelemetry.Contrib.Shared.Tests.csproj, - OpenTelemetry.Exporter.Geneva.Tests.csproj, - OpenTelemetry.Exporter.OneCollector.Tests.csproj, - OpenTelemetry.Extensions.Tests.csproj, - OpenTelemetry.Instrumentation.AspNet.Tests.csproj, - OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj, - OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj, - OpenTelemetry.Instrumentation.EventCounters.Tests.csproj, - OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj, - OpenTelemetry.Instrumentation.Http.Tests.csproj, - OpenTelemetry.Instrumentation.Owin.Tests.csproj, - OpenTelemetry.Instrumentation.Process.Tests.csproj, - OpenTelemetry.Instrumentation.Runtime.Tests.csproj, - OpenTelemetry.Instrumentation.SqlClient.Tests.csproj, - OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj, - OpenTelemetry.Instrumentation.Wcf.Tests.csproj, - OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj, - OpenTelemetry.ResourceDetectors.Azure.Tests.csproj, - OpenTelemetry.Resources.Gcp.Tests.csproj, - OpenTelemetry.Resources.Host.Tests.csproj, - OpenTelemetry.Resources.Process.Tests.csproj, - OpenTelemetry.Resources.ProcessRuntime.Tests.csproj - - $failedProjects = @() - - ForEach ($project in $projects) - { - dotnet test $project.FullName --collect:"Code Coverage" --results-directory:"TestResults" --framework ${{ matrix.version }} --configuration Release --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - - if ($LASTEXITCODE -ne 0) - { - $failedProjects = $failedProjects + $project - } - } - - if ($failedProjects.Count -gt 0) - { - throw "dotnet test failed on '$failedProjects' project(s)" - } - - - name: Install coverage tool - run: dotnet tool install -g dotnet-coverage - - - name: Merging test results - run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage - - - uses: codecov/codecov-action@v4 - continue-on-error: true # Note: Don't fail for upload failures - env: - OS: ${{ matrix.os }} - TFM: ${{ matrix.version }} - token: ${{ secrets.CODECOV_TOKEN }} - with: - file: TestResults/Cobertura.xml - env_vars: OS,TFM - flags: unittests-Solution - name: Code Coverage for solution on [${{ matrix.os }}.${{ matrix.version }}] - codecov_yml_path: .github/codecov.yml + build-test-sampler-aws: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'resources-sampler-aws') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Sampler.AWS] + code-cov-name: Sampler.AWS + + build-test-semanticconventions: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'semanticconventions') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.SemanticConventions + code-cov-name: SemanticConventions + + build-test-contrib-shared-tests: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'contrib-shared-tests') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: OpenTelemetry.Contrib.Shared.Tests + code-cov-name: Contrib.Shared.Tests verify-aot-compat: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'eventcounters') - || contains(needs.detect-changes.outputs.changes, 'runtime') - || contains(needs.detect-changes.outputs.changes, 'aspnetcore') - || contains(needs.detect-changes.outputs.changes, 'aws') - || contains(needs.detect-changes.outputs.changes, 'azure') + contains(needs.detect-changes.outputs.changes, 'exporter-geneva') + || contains(needs.detect-changes.outputs.changes, 'exporter-onecollector') || contains(needs.detect-changes.outputs.changes, 'extensions') - || contains(needs.detect-changes.outputs.changes, 'gcp') - || contains(needs.detect-changes.outputs.changes, 'grpcnetclient') - || contains(needs.detect-changes.outputs.changes, 'host') - || contains(needs.detect-changes.outputs.changes, 'http') - || contains(needs.detect-changes.outputs.changes, 'processdetector') - || contains(needs.detect-changes.outputs.changes, 'processruntime') - || contains(needs.detect-changes.outputs.changes, 'resourcedetectors') + || contains(needs.detect-changes.outputs.changes, 'extensions-enrichment') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-aspnetcore') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-aws') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-awslambda') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-eventcounters') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-grpcnetclient') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-http') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-runtime') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-sqlclient') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-stackexchangeredis') + || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-aws') + || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-azure') + || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') + || contains(needs.detect-changes.outputs.changes, 'resources-host') + || contains(needs.detect-changes.outputs.changes, 'resources-process') + || contains(needs.detect-changes.outputs.changes, 'resources-processruntime') + || contains(needs.detect-changes.outputs.changes, 'sampler-aws') || contains(needs.detect-changes.outputs.changes, 'aot') || contains(needs.detect-changes.outputs.changes, 'aottestapp') || contains(needs.detect-changes.outputs.changes, 'build') - || contains(needs.detect-changes.outputs.changes, 'geneva') - || contains(needs.detect-changes.outputs.changes, 'onecollector') - || contains(needs.detect-changes.outputs.changes, 'redis') - || contains(needs.detect-changes.outputs.changes, 'sqlclient') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/verifyaotcompat.yml @@ -477,30 +543,45 @@ jobs: detect-changes, lint-md, lint-dotnet-format, - build-test-aspnet, - build-test-aspnetcore, - build-test-azure, - build-test-eventcounters, + build-test-exporter-geneva, + build-test-exporter-influxdb, + build-test-exporter-instana, + build-test-exporter-onecollector, + build-test-exporter-stackdriver, build-test-extensions, - build-test-geneva, - build-test-gcp, - build-test-grpcnetclient, - build-test-host, - build-test-http, - build-test-onecollector, - build-test-owin, + build-test-extensions-aws, + build-test-extensions-enrichment, + build-test-instrumentation-aspnet, + build-test-instrumentation-aspnetcore, + build-test-instrumentation-aws, + build-test-instrumentation-awslambda, + build-test-instrumentation-cassandra, + build-test-instrumentation-elasticsearchclient, + build-test-instrumentation-entityframeworkcore, + build-test-instrumentation-eventcounters, + build-test-instrumentation-grpccore, + build-test-instrumentation-grpcnetclient, + build-test-instrumentation-hangfire, + build-test-instrumentation-http, + build-test-instrumentation-owin, + build-test-instrumentation-process, + build-test-instrumentation-quartz, + build-test-instrumentation-runtime, + build-test-instrumentation-sqlclient, + build-test-instrumentation-stackexchangeredis, + build-test-instrumentation-stackexchangeredis-integration, + build-test-instrumentation-wcf, build-test-persistentstorage, - build-test-process, - build-test-processdetector, - build-test-processruntime, - build-test-redis, - build-test-redis-integration, - build-test-runtime, + build-test-resourcedetectors-azure, + build-test-resourcedetectors-aws, + build-test-resourcedetectors-container, + build-test-resources-gcp, + build-test-resources-host, + build-test-resources-process, + build-test-resources-processruntime, + build-test-sampler-aws, build-test-semanticconventions, - build-test-sqlclient, - build-test-wcf, - build-test-solution, - build-test-sharedtests, + build-test-contrib-shared-tests, verify-aot-compat ] if: always() && !cancelled() && !contains(needs.*.result, 'failure') diff --git a/build/Projects/OpenTelemetry.Exporter.InfluxDB.proj b/build/Projects/OpenTelemetry.Exporter.InfluxDB.proj new file mode 100644 index 0000000000..1687d250fd --- /dev/null +++ b/build/Projects/OpenTelemetry.Exporter.InfluxDB.proj @@ -0,0 +1,34 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Exporter.InfluxDB- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/Projects/OpenTelemetry.Extensions.Enrichment.proj b/build/Projects/OpenTelemetry.Extensions.Enrichment.proj new file mode 100644 index 0000000000..b98720d76d --- /dev/null +++ b/build/Projects/OpenTelemetry.Extensions.Enrichment.proj @@ -0,0 +1,34 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Extensions.Enrichment- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/Projects/OpenTelemetry.Instrumentation.GrpcCore.proj b/build/Projects/OpenTelemetry.Instrumentation.GrpcCore.proj new file mode 100644 index 0000000000..97d0f3c684 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.GrpcCore.proj @@ -0,0 +1,34 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.GrpcCore- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f1fd71fdb60146be6399ecfd0dd90243e4c8cf1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 23 May 2024 16:03:29 +0200 Subject: [PATCH 1095/1499] [repo] Code Coverage badges (#1838) --- src/OpenTelemetry.Exporter.Geneva/README.md | 1 + src/OpenTelemetry.Exporter.InfluxDB/README.md | 1 + src/OpenTelemetry.Exporter.Instana/README.md | 1 + src/OpenTelemetry.Exporter.OneCollector/README.md | 1 + src/OpenTelemetry.Exporter.Stackdriver/README.md | 1 + src/OpenTelemetry.Extensions.AWS/README.md | 5 +++-- src/OpenTelemetry.Extensions.Enrichment/README.md | 1 + src/OpenTelemetry.Extensions/README.md | 1 + src/OpenTelemetry.Instrumentation.AWS/README.md | 1 + src/OpenTelemetry.Instrumentation.AWSLambda/README.md | 1 + .../README.md | 1 + src/OpenTelemetry.Instrumentation.AspNet/README.md | 1 + src/OpenTelemetry.Instrumentation.AspNetCore/README.md | 1 + src/OpenTelemetry.Instrumentation.Cassandra/README.md | 1 + .../README.md | 1 + .../README.md | 1 + src/OpenTelemetry.Instrumentation.EventCounters/README.md | 1 + src/OpenTelemetry.Instrumentation.GrpcCore/README.md | 1 + src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md | 1 + src/OpenTelemetry.Instrumentation.Hangfire/README.md | 1 + src/OpenTelemetry.Instrumentation.Http/README.md | 1 + src/OpenTelemetry.Instrumentation.Owin/README.md | 1 + src/OpenTelemetry.Instrumentation.Process/README.md | 1 + src/OpenTelemetry.Instrumentation.Quartz/README.md | 1 + src/OpenTelemetry.Instrumentation.Runtime/README.md | 1 + src/OpenTelemetry.Instrumentation.SqlClient/README.md | 1 + .../README.md | 1 + src/OpenTelemetry.Instrumentation.Wcf/README.md | 1 + src/OpenTelemetry.PersistentStorage.Abstractions/README.md | 1 + src/OpenTelemetry.PersistentStorage.FileSystem/README.md | 1 + src/OpenTelemetry.ResourceDetectors.AWS/README.md | 1 + src/OpenTelemetry.ResourceDetectors.Azure/README.md | 1 + src/OpenTelemetry.ResourceDetectors.Container/README.md | 1 + src/OpenTelemetry.Resources.Gcp/README.md | 3 ++- src/OpenTelemetry.Resources.Host/README.md | 1 + src/OpenTelemetry.Resources.Process/README.md | 1 + src/OpenTelemetry.Resources.ProcessRuntime/README.md | 1 + src/OpenTelemetry.Sampler.AWS/README.md | 1 + 38 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 7473017a0f..049bb6663c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.Geneva)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.Geneva) The Geneva Exporter exports telemetry to [Event Tracing for Windows (ETW)](https://docs.microsoft.com/windows/win32/etw/about-event-tracing) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/README.md b/src/OpenTelemetry.Exporter.InfluxDB/README.md index 4bedc318bb..c817e0d4d6 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/README.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.InfluxDB)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.InfluxDB) The InfluxDB exporter converts OpenTelemetry metrics into the InfluxDB model following the [OpenTelemetry->InfluxDB conversion schema](https://github.com/influxdata/influxdb-observability/blob/main/docs/index.md). diff --git a/src/OpenTelemetry.Exporter.Instana/README.md b/src/OpenTelemetry.Exporter.Instana/README.md index 5e4646da5c..3960cb9cb6 100644 --- a/src/OpenTelemetry.Exporter.Instana/README.md +++ b/src/OpenTelemetry.Exporter.Instana/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.Instana)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.Instana) The Instana Exporter exports telemetry to Instana backend. diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index 9d9622d130..11887a53a6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.OneCollector)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.OneCollector) The OneCollectorExporter is designed for Microsoft products to send data to public-facing end-points which route to Microsoft's internal data pipeline. It diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 9f68e6ef9f..483ccb6b35 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.Stackdriver)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.Stackdriver) **NOTE: This exporter is not affiliated with or officially supported by Google.** diff --git a/src/OpenTelemetry.Extensions.AWS/README.md b/src/OpenTelemetry.Extensions.AWS/README.md index 6822096863..1426ac3661 100644 --- a/src/OpenTelemetry.Extensions.AWS/README.md +++ b/src/OpenTelemetry.Extensions.AWS/README.md @@ -1,7 +1,8 @@ # Tracing with AWS Distro for OpenTelemetry .Net SDK -[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Contrib.Extensions.AWSXRay)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Extensions.AWSXRay) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Contrib.Extensions.AWSXRay)](https://www.nuget.org/packages/OpenTelemetry.Contrib.Extensions.AWSXRay) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AWS)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AWS) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.AWS)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AWS) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Extensions.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Extensions.AWS) If you want to send the traces to AWS X-Ray, you can do so by using AWS Distro with the OpenTelemetry SDK. diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index 0dd4a266e5..fac3fcae07 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Extensions.Enrichment)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Extensions.Enrichment) Contains OpenTelemetry .NET SDK telemetry enrichment framework which is used for enrichment of traces. diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index 8e4ca16c64..8c45cd56a7 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Extensions)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Extensions) Contains useful features and extensions to the OpenTelemetry .NET SDK that are not part of the official OpenTelemetry specification but might be added in the diff --git a/src/OpenTelemetry.Instrumentation.AWS/README.md b/src/OpenTelemetry.Instrumentation.AWS/README.md index 4579d3d72e..f781427566 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/README.md +++ b/src/OpenTelemetry.Instrumentation.AWS/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AWS) Download the `OpenTelemetry.Instrumentation.AWS` package: diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index dd9ab32d5e..58537aa641 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AWSLambda)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AWSLambda) This repo contains SDK to instrument Lambda handler to create incoming span. diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index 2d64278ddf..f6edab1435 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AspNet)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AspNet) The ASP.NET Telemetry HttpModule enables distributed tracing of incoming ASP.NET requests using the OpenTelemetry API. diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index e996cc1bb9..ec026a8416 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AspNet)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AspNet) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index f8ef36ef2d..24663404ef 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -2,6 +2,7 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AspNetCore)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AspNetCore) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index ec66e079c8..2e91962fed 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Cassandra)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Cassandra) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 7d66b4b72c..4e49077980 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -4,6 +4,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ElasticsearchClient)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.ElasticsearchClient)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.ElasticsearchClient) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index 9d04c7deaa..93ee0cf41a 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.EntityFrameworkCore)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.EntityFrameworkCore) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index 5c6b710803..ac9dbd3f43 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.EventCounters)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.EventCounters) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md index e2c8554568..023d3ab612 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.GrpcCore)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.GrpcCore) Adds OpenTelemetry instrumentation for gRPC Core-based client and server calls. diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md index eb6bdd12d9..2b4d9d320b 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md @@ -2,6 +2,7 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.GrpcNetClient)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.GrpcNetClient) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library) which instruments [Grpc.Net.Client](https://www.nuget.org/packages/Grpc.Net.Client) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index fec0182421..74f6d8dc4c 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Hangfire)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Hangfire) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index b3fec4ebe4..38b392e1eb 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -2,6 +2,7 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Http)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Http) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index 31afb50349..b9d70cc9e5 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Owin)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Owin) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 2f390a4245..cd8af80e17 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Process)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Process) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 84618541ea..d82010308d 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Quartz)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Quartz) Automatically instruments the Quartz jobs from [Quartz](https://www.nuget.org/packages/Quartz/). diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index aa0b0fbd63..469fd3e062 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Runtime)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Runtime) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index 1df0435250..842662679e 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -2,6 +2,7 @@ [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.SqlClient)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.SqlClient) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index 32fe81436c..947c818153 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.StackExchangeRedis)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.StackExchangeRedis) This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/glossary.md#instrumentation-library), diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 92828eb97e..16909be2eb 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Wcf)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Wcf) Instruments WCF clients and/or services. diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index c0698b9dc3..082e550688 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-PersistentStorage)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-PersistentStorage) This package includes APIs which can be extended by exporter owners to implement persistent storage. diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index 734297ce79..42db71387b 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-PersistentStorage)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-PersistentStorage) This package provides an implementation of [persistent-storage-abstractions](../OpenTelemetry.PersistentStorage.Abstractions/README.md#Persistent-Storage-Abstractions) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/README.md b/src/OpenTelemetry.ResourceDetectors.AWS/README.md index f5317a52b3..75b1d1d365 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/README.md +++ b/src/OpenTelemetry.ResourceDetectors.AWS/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.AWS)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.AWS)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.AWS) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-ResourceDetectors.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-ResourceDetectors.AWS) ## Getting Started diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/README.md b/src/OpenTelemetry.ResourceDetectors.Azure/README.md index 91095ec2af..f4c51c73f0 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Azure/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Azure)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Azure)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-ResourceDetectors.Azure)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-ResourceDetectors.Azure) This package contains [Resource Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) diff --git a/src/OpenTelemetry.ResourceDetectors.Container/README.md b/src/OpenTelemetry.ResourceDetectors.Container/README.md index 4cbfd046c0..ad4932e2f7 100644 --- a/src/OpenTelemetry.ResourceDetectors.Container/README.md +++ b/src/OpenTelemetry.ResourceDetectors.Container/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.ResourceDetectors.Container)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Container) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Container)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Container) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-ResourceDetectors.Container)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-ResourceDetectors.Container) ## Getting Started diff --git a/src/OpenTelemetry.Resources.Gcp/README.md b/src/OpenTelemetry.Resources.Gcp/README.md index 3171fa579c..5424920160 100644 --- a/src/OpenTelemetry.Resources.Gcp/README.md +++ b/src/OpenTelemetry.Resources.Gcp/README.md @@ -1,7 +1,8 @@ # Resource Detectors for Google Cloud Platform environments [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Gcp)](https://www.nuget.org/packages/OpenTelemetry.Resources.Gcp) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.ResourceDetectors.Azure)](https://www.nuget.org/packages/OpenTelemetry.ResourceDetectors.Azure) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Gcp)](https://www.nuget.org/packages/OpenTelemetry.Resources.Gcp) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Gcp)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Gcp) This package contains [Resource Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) diff --git a/src/OpenTelemetry.Resources.Host/README.md b/src/OpenTelemetry.Resources.Host/README.md index a5e1d9d35f..607816e688 100644 --- a/src/OpenTelemetry.Resources.Host/README.md +++ b/src/OpenTelemetry.Resources.Host/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Host)](https://www.nuget.org/packages/OpenTelemetry.Resources.Host) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Host)](https://www.nuget.org/packages/OpenTelemetry.Resources.Host) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Host)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Host) > [!IMPORTANT] > Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/host.md). diff --git a/src/OpenTelemetry.Resources.Process/README.md b/src/OpenTelemetry.Resources.Process/README.md index 7d1f9da74b..ceeefb728e 100644 --- a/src/OpenTelemetry.Resources.Process/README.md +++ b/src/OpenTelemetry.Resources.Process/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Process)](https://www.nuget.org/packages/OpenTelemetry.Resources.Process) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Process)](https://www.nuget.org/packages/OpenTelemetry.Resources.Process) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Process)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Process) > [!IMPORTANT] > Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/process.md#process). diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/README.md b/src/OpenTelemetry.Resources.ProcessRuntime/README.md index 04f1c2d2d1..03f4db0eda 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/README.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.Resources.ProcessRuntime) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.Resources.ProcessRuntime) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.ProcessRuntime)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.ProcessRuntime) > [!IMPORTANT] > Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/process.md#process-runtimes). diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md index 8dc2b4b023..daf3924c23 100644 --- a/src/OpenTelemetry.Sampler.AWS/README.md +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -2,6 +2,7 @@ [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Sampler.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Sampler.AWS) This package provides a sampler which can get sampling configurations from AWS X-Ray to make sampling decisions. From 1d112c860922f59a7ae5c5269b9d758fc8fb87ce Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Fri, 24 May 2024 21:35:31 +0300 Subject: [PATCH 1096/1499] Fix StackExchangeRedisInstrumentationOptions xml docs (#1842) --- .../StackExchangeRedisInstrumentationOptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs index 1e18d25fa5..87d67b0cdc 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentationOptions.cs @@ -18,7 +18,7 @@ public class StackExchangeRedisInstrumentationOptions public TimeSpan FlushInterval { get; set; } = TimeSpan.FromSeconds(10); /// - /// Gets or sets a value indicating whether or not the should use reflection to get more detailed tag values. Default value: False. + /// Gets or sets a value indicating whether the should use reflection to get more detailed tag values. Default value: . /// public bool SetVerboseDatabaseStatements { get; set; } @@ -32,7 +32,7 @@ public class StackExchangeRedisInstrumentationOptions public Action? Enrich { get; set; } /// - /// Gets or sets a value indicating whether or not the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to true. + /// Gets or sets a value indicating whether the should enrich Activity with entries about the Redis command processing/lifetime. Defaults to . /// public bool EnrichActivityWithTimingEvents { get; set; } = true; } From f1ec716d54eaa26bb15b79fc3f3dc2d749f19c98 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Mon, 27 May 2024 01:59:49 -0400 Subject: [PATCH 1097/1499] [Resources.Azure] Rename Azure detector namespace (#1840) Co-authored-by: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/codecov.yml | 4 +- .github/component_owners.yml | 12 ++--- .github/workflows/ci.yml | 22 ++++----- opentelemetry-dotnet-contrib.sln | 4 +- .../.publicApi/PublicAPI.Unshipped.txt | 9 ---- .../AssemblyInfo.cs | 10 ---- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 4 ++ .../AppServiceResourceDetector.cs | 5 +- .../AssemblyInfo.cs | 10 ++++ .../AzureContainerAppsResourceDetector.cs | 5 +- .../AzureResourceBuilderExtensions.cs | 46 +++++++++++++++++++ .../AzureVMResourceDetector.cs | 5 +- .../AzureVmMetaDataRequestor.cs | 2 +- .../AzureVmMetadataResponse.cs | 2 +- .../CHANGELOG.md | 13 ++++++ .../OpenTelemetry.Resources.Azure.csproj} | 2 +- .../README.md | 17 +++---- .../ResourceAttributeConstants.cs | 2 +- .../SourceGenerationContext.cs | 2 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 2 +- .../AzureResourceDetectorTests.cs | 3 +- ...penTelemetry.Resources.Azure.Tests.csproj} | 2 +- 25 files changed, 117 insertions(+), 70 deletions(-) delete mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/.publicApi/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/AppServiceResourceDetector.cs (96%) create mode 100644 src/OpenTelemetry.Resources.Azure/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/AzureContainerAppsResourceDetector.cs (92%) create mode 100644 src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/AzureVMResourceDetector.cs (93%) rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/AzureVmMetaDataRequestor.cs (95%) rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/AzureVmMetadataResponse.cs (98%) rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/CHANGELOG.md (77%) rename src/{OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj => OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj} (94%) rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/README.md (93%) rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/ResourceAttributeConstants.cs (97%) rename src/{OpenTelemetry.ResourceDetectors.Azure => OpenTelemetry.Resources.Azure}/SourceGenerationContext.cs (94%) rename test/{OpenTelemetry.ResourceDetectors.Azure.Tests => OpenTelemetry.Resources.Azure.Tests}/AzureResourceDetectorTests.cs (98%) rename test/{OpenTelemetry.ResourceDetectors.Azure.Tests/OpenTelemetry.ResourceDetectors.Azure.Tests.csproj => OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj} (86%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 2d9e8e82e6..39999c7e41 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -49,8 +49,8 @@ body: - OpenTelemetry.PersistentStorage.Abstractions - OpenTelemetry.PersistentStorage.FileSystem - OpenTelemetry.ResourceDetectors.AWS - - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container + - OpenTelemetry.Resources.Azure - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host - OpenTelemetry.Resources.Process diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 9e5b95ad58..4dff155b53 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -49,8 +49,8 @@ body: - OpenTelemetry.PersistentStorage.Abstractions - OpenTelemetry.PersistentStorage.FileSystem - OpenTelemetry.ResourceDetectors.AWS - - OpenTelemetry.ResourceDetectors.Azure - OpenTelemetry.ResourceDetectors.Container + - OpenTelemetry.Resources.Azure - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host - OpenTelemetry.Resources.Process diff --git a/.github/codecov.yml b/.github/codecov.yml index 04587aaeb8..0d3bda059b 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -114,10 +114,10 @@ flags: - src/OpenTelemetry.PersistentStorage.Abstractions - src/OpenTelemetry.PersistentStorage.FileSystem - unittests-ResourceDetectors.Azure: + unittests-Resources.Azure: carryforward: true paths: - - src/OpenTelemetry.ResourceDetectors.Azure + - src/OpenTelemetry.Resources.Azure unittests-Resources.Gcp: carryforward: true diff --git a/.github/component_owners.yml b/.github/component_owners.yml index d9a50eb243..a8261e34b6 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -62,11 +62,11 @@ components: src/OpenTelemetry.ResourceDetectors.AWS/: - srprash - ppittle - src/OpenTelemetry.ResourceDetectors.Azure/: - - rajkumar-rangaraj - - vishweshbankwar src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev + src/OpenTelemetry.Resources.Azure/: + - rajkumar-rangaraj + - vishweshbankwar src/OpenTelemetry.Resources.Host/: - Kielek - lachmatt @@ -152,11 +152,11 @@ components: test/OpenTelemetry.ResourceDetectors.AWS.Tests/: - srprash - ppittle - test/OpenTelemetry.ResourceDetectors.Azure.Tests/: - - rajkumar-rangaraj - - vishweshbankwar test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev + test/OpenTelemetry.Resources.Azure.Tests/: + - rajkumar-rangaraj + - vishweshbankwar test/OpenTelemetry.Resources.Host.Tests/: - Kielek - lachmatt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b647d2f63d..faffeeb558 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,8 +52,8 @@ jobs: instrumentation-wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] resourcedetectors-aws: ['*/OpenTelemetry.ResourceDetectors.AWS*/**', '!**/*.md'] - resourcedetectors-azure: ['*/OpenTelemetry.ResourceDetectors.Azure*/**', '!**/*.md'] resourcedetectors-container: ['*/OpenTelemetry.ResourceDetectors.Container*/**', '!**/*.md'] + resources-azure: ['*/OpenTelemetry.Resources.Azure*/**', '!**/*.md'] resources-gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] resources-host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md'] resources-process: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] @@ -409,27 +409,27 @@ jobs: project-name: Component[OpenTelemetry.ResourceDetectors.AWS] code-cov-name: ResourceDetectors.AWS - build-test-resourcedetectors-azure: + build-test-resourcedetectors-container: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'resourcedetectors-azure') + contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.ResourceDetectors.Azure] - code-cov-name: ResourceDetectors.Azure + project-name: Component[OpenTelemetry.ResourceDetectors.Container] + code-cov-name: ResourceDetectors.Container - build-test-resourcedetectors-container: + build-test-resources-azure: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') + contains(needs.detect-changes.outputs.changes, 'resources-azure') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.ResourceDetectors.Container] - code-cov-name: ResourceDetectors.Container + project-name: Component[OpenTelemetry.Resources.Azure] + code-cov-name: Resources.Azure build-test-resources-gcp: needs: detect-changes @@ -525,8 +525,8 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'instrumentation-sqlclient') || contains(needs.detect-changes.outputs.changes, 'instrumentation-stackexchangeredis') || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-aws') - || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-azure') || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') + || contains(needs.detect-changes.outputs.changes, 'resources-azure') || contains(needs.detect-changes.outputs.changes, 'resources-host') || contains(needs.detect-changes.outputs.changes, 'resources-process') || contains(needs.detect-changes.outputs.changes, 'resources-processruntime') @@ -572,9 +572,9 @@ jobs: build-test-instrumentation-stackexchangeredis-integration, build-test-instrumentation-wcf, build-test-persistentstorage, - build-test-resourcedetectors-azure, build-test-resourcedetectors-aws, build-test-resourcedetectors-container, + build-test-resources-azure, build-test-resources-gcp, build-test-resources-host, build-test-resources-process, diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a22def56b0..212ae016a2 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -203,9 +203,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentati EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.Cassandra.Tests", "test\OpenTelemetry.Instrumentation.Cassandra.Tests\OpenTelemetry.Instrumentation.Cassandra.Tests.csproj", "{FB48DC44-8C56-4329-9988-AEDF931E81E8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure", "src\OpenTelemetry.ResourceDetectors.Azure\OpenTelemetry.ResourceDetectors.Azure.csproj", "{B07DC3CB-F724-40A5-889A-DA6601F462F3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Azure", "src\OpenTelemetry.Resources.Azure\OpenTelemetry.Resources.Azure.csproj", "{B07DC3CB-F724-40A5-889A-DA6601F462F3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.Azure.Tests", "test\OpenTelemetry.ResourceDetectors.Azure.Tests\OpenTelemetry.ResourceDetectors.Azure.Tests.csproj", "{DFC6A4A9-5262-4507-B747-CC6B814205E6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Azure.Tests", "test\OpenTelemetry.Resources.Azure.Tests\OpenTelemetry.Resources.Azure.Tests.csproj", "{DFC6A4A9-5262-4507-B747-CC6B814205E6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OneCollector", "src\OpenTelemetry.Exporter.OneCollector\OpenTelemetry.Exporter.OneCollector.csproj", "{73C10993-03AC-42F4-85BB-96EAAA8212D9}" EndProject diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Unshipped.txt deleted file mode 100644 index 742d5f3fed..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,9 +0,0 @@ -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.AppServiceResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AppServiceResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector -OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.AzureContainerAppsResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AzureContainerAppsResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector -OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.AzureVMResourceDetector() -> void -OpenTelemetry.ResourceDetectors.Azure.AzureVMResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs deleted file mode 100644 index fdeff3214a..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Azure.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.Azure.Tests")] -#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.Azure/.publicApi/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..30a42e0213 --- /dev/null +++ b/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,4 @@ +OpenTelemetry.Resources.AzureResourceBuilderExtensions +static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAppServiceDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAzureVMDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAzureContainerAppsDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs similarity index 96% rename from src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs rename to src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs index 16bf46890a..7a44070de6 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs @@ -3,15 +3,14 @@ using System; using System.Collections.Generic; -using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace OpenTelemetry.ResourceDetectors.Azure; +namespace OpenTelemetry.Resources.Azure; /// /// Resource detector for Azure AppService environment. /// -public sealed class AppServiceResourceDetector : IResourceDetector +internal sealed class AppServiceResourceDetector : IResourceDetector { internal static readonly IReadOnlyDictionary AppServiceResourceAttributes = new Dictionary { diff --git a/src/OpenTelemetry.Resources.Azure/AssemblyInfo.cs b/src/OpenTelemetry.Resources.Azure/AssemblyInfo.cs new file mode 100644 index 0000000000..ad59a4686e --- /dev/null +++ b/src/OpenTelemetry.Resources.Azure/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Azure.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.Azure.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs similarity index 92% rename from src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs rename to src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs index a9129630dd..a72c771f9c 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureContainerAppsResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs @@ -3,15 +3,14 @@ using System; using System.Collections.Generic; -using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace OpenTelemetry.ResourceDetectors.Azure; +namespace OpenTelemetry.Resources.Azure; /// /// Resource detector for Azure Container Apps environment. /// -public sealed class AzureContainerAppsResourceDetector : IResourceDetector +internal sealed class AzureContainerAppsResourceDetector : IResourceDetector { internal static readonly IReadOnlyDictionary AzureContainerResourceAttributes = new Dictionary { diff --git a/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs new file mode 100644 index 0000000000..9fe109a32e --- /dev/null +++ b/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs @@ -0,0 +1,46 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; +using OpenTelemetry.Resources.Azure; + +namespace OpenTelemetry.Resources; + +/// +/// Extension methods to simplify registering of Azure resource detectors. +/// +public static class AzureResourceBuilderExtensions +{ + /// + /// Enables Azure AppService resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAppServiceDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AppServiceResourceDetector()); + } + + /// + /// Enables Azure VM resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAzureVMDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AzureVMResourceDetector()); + } + + /// + /// Enables Azure Container Apps resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAzureContainerAppsDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AzureContainerAppsResourceDetector()); + } +} diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs similarity index 93% rename from src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs rename to src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs index 2ecbb76a02..05d1666ddf 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs @@ -2,15 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 using System.Collections.Generic; -using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace OpenTelemetry.ResourceDetectors.Azure; +namespace OpenTelemetry.Resources.Azure; /// /// Resource detector for Azure VM environment. /// -public sealed class AzureVMResourceDetector : IResourceDetector +internal sealed class AzureVMResourceDetector : IResourceDetector { internal static readonly IReadOnlyCollection ExpectedAzureAmsFields = new string[] { diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs b/src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs similarity index 95% rename from src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs rename to src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs index ba3ca54877..01b59aac7c 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetaDataRequestor.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs @@ -5,7 +5,7 @@ using System.Net.Http; using System.Text.Json; -namespace OpenTelemetry.ResourceDetectors.Azure; +namespace OpenTelemetry.Resources.Azure; internal static class AzureVmMetaDataRequestor { diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs similarity index 98% rename from src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs rename to src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs index 09791edfba..81418c8920 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/AzureVmMetadataResponse.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs @@ -4,7 +4,7 @@ using System.Text.Json.Serialization; using OpenTelemetry.Trace; -namespace OpenTelemetry.ResourceDetectors.Azure; +namespace OpenTelemetry.Resources.Azure; internal sealed class AzureVmMetadataResponse { diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md similarity index 77% rename from src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md rename to src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 7c9eaf83ea..84d2d32fb1 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,19 @@ ## Unreleased +* **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Azure` + to `OpenTelemetry.Resources.Azure`. + ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) +* **Breaking Change**: `AppServiceResourceDetector` type is now internal, use `ResourceBuilder` + extension method `AddAppServiceDetector` to enable the detector. + ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) +* **Breaking Change**: `AzureVMResourceDetector` type is now internal, use `ResourceBuilder` + extension method `AddAzureVMResourceDetector` to enable the detector. + ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) +* **Breaking Change**: `AzureContainerAppsResourceDetector` type is now + internal, use `ResourceBuilder` extension method `AddAzureContainerAppsResourceDetector` + to enable the detector. + ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) diff --git a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj similarity index 94% rename from src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj rename to src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj index d615446585..a65a158f8b 100644 --- a/src/OpenTelemetry.ResourceDetectors.Azure/OpenTelemetry.ResourceDetectors.Azure.csproj +++ b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj @@ -3,7 +3,7 @@ net6.0;netstandard2.0 OpenTelemetry Resource Detectors for Azure cloud environments $(PackageTags);ResourceDetector - ResourceDetectors.Azure- + Resources.Azure- [0.13.12,0.14) [2.3.1,3.0) + 8.0.0 [17.9.0,18.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) diff --git a/build/Common.props b/build/Common.props index de509382d6..68e36b8237 100644 --- a/build/Common.props +++ b/build/Common.props @@ -33,8 +33,7 @@ [8.0.1,) [2.1.0,5.0) 8.0.0 - [3.1.0,) - 8.0.0 + 8.0.0 [1.0.3,2.0) [4.2.2,5.0) [3.11.0-beta1.23525.2] diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index b9e902ba43..9d74ddfd9c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -38,8 +38,8 @@ - - + + diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 0d736121d2..b01ae4472d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -4,6 +4,8 @@ * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Update `Microsoft.Extensions.Options` to `8.0.0`. + ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) ## 1.0.0-beta.11 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 2aacd745b6..b8e7a9a387 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -7,6 +7,8 @@ * Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. * Update `OpenTelemetry.Api` to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Update `Microsoft.Extensions.Options` to `8.0.0`. + ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) ## 1.6.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index d64d96feb9..b4124d8df7 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -35,7 +35,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index 7c6211b265..1ab0a99303 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 848b28bc53..e63e226fb9 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -4,6 +4,8 @@ * Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Update `Microsoft.Extensions.Options` to `8.0.0`. + ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) ## 1.0.0-rc9.14 diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 84863e9115..c7400ad0a6 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 3485ccbfe1..7bcac9f8e7 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index b980538962..12b74df91b 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -20,6 +20,6 @@ - + From 47b667acf8cde47aa73fc6d28b609ebb3aeca8d3 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 30 May 2024 18:47:01 +0000 Subject: [PATCH 1101/1499] [Resources.AWS] Rename AWS detector namespace (#1839) --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yml | 2 +- .github/component_owners.yml | 12 ++-- .github/workflows/ci.yml | 22 +++---- opentelemetry-dotnet-contrib.sln | 4 +- .../.publicApi/PublicAPI.Unshipped.txt | 6 -- .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 6 -- .../AssemblyInfo.cs | 10 ---- .../.publicApi/PublicAPI.Shipped.txt | 0 .../.publicApi/PublicAPI.Unshipped.txt | 3 + .../.publicApi/net6.0/PublicAPI.Shipped.txt | 0 .../.publicApi/net6.0/PublicAPI.Unshipped.txt | 2 + .../AWSEBSDetector.cs} | 13 ++-- .../AWSEC2Detector.cs} | 9 ++- .../AWSECSDetector.cs} | 15 +++-- .../AWSEKSDetector.cs} | 18 +++--- .../AWSResourceBuilderExtensions.cs | 59 +++++++++++++++++++ .../AWSResourcesEventSource.cs | 4 +- .../AWSSemanticConventions.cs | 2 +- .../AssemblyInfo.cs | 10 ++++ .../CHANGELOG.md | 13 ++++ .../Models/AWSEBSMetadataModel.cs | 2 +- .../Models/AWSEC2IdentityDocumentModel.cs | 2 +- .../Models/AWSEKSClusterDataModel.cs | 2 +- .../Models/AWSEKSClusterInformationModel.cs | 2 +- .../OpenTelemetry.Resources.AWS.csproj} | 2 +- .../README.md | 22 +++---- .../ResourceDetectorUtils.cs | 2 +- .../SourceGenerationContext.cs | 4 +- src/OpenTelemetry.Sampler.AWS/README.md | 2 +- ...IServerCertificateValidationEventSource.cs | 2 +- .../ServerCertificateValidationHandler.cs | 2 +- .../ServerCertificateValidationProvider.cs | 2 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 4 +- .../AWSEBSDetectorTests.cs} | 10 ++-- .../AWSEC2DetectorTests.cs} | 10 ++-- .../AWSECSDetectorTests.cs} | 16 ++--- .../AWSEKSDetectorTests.cs} | 18 +++--- .../Http/CertificateUploader.cs | 2 +- ...pServerCertificateValidationEventSource.cs | 2 +- ...ServerCertificateValidationHandlerTests.cs | 2 +- ...erverCertificateValidationProviderTests.cs | 2 +- .../OpenTelemetry.Resources.AWS.Tests.csproj} | 2 +- .../SampleAWSEBSMetadataModel.cs | 4 +- .../SampleAWSEC2IdentityDocumentModel.cs | 4 +- .../SampleMetadataFiles/environment.conf | 0 .../SampleMetadataFiles/testcgroup | 0 .../SampleMetadataFiles/testekstoken | 0 .../metadatav4-response-container-ec2.json | 0 ...metadatav4-response-container-fargate.json | 0 .../metadatav4-response-task-ec2.json | 0 .../metadatav4-response-task-fargate.json | 0 52 files changed, 197 insertions(+), 137 deletions(-) delete mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt delete mode 100644 src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/.publicApi/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Resources.AWS/.publicApi/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/.publicApi/net6.0/PublicAPI.Shipped.txt (100%) create mode 100644 src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt rename src/{OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs => OpenTelemetry.Resources.AWS/AWSEBSDetector.cs} (89%) rename src/{OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs => OpenTelemetry.Resources.AWS/AWSEC2Detector.cs} (94%) rename src/{OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs => OpenTelemetry.Resources.AWS/AWSECSDetector.cs} (93%) rename src/{OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs => OpenTelemetry.Resources.AWS/AWSEKSDetector.cs} (90%) create mode 100644 src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/AWSResourcesEventSource.cs (95%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/AWSSemanticConventions.cs (97%) create mode 100644 src/OpenTelemetry.Resources.AWS/AssemblyInfo.cs rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/CHANGELOG.md (64%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/Models/AWSEBSMetadataModel.cs (88%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/Models/AWSEC2IdentityDocumentModel.cs (91%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/Models/AWSEKSClusterDataModel.cs (82%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/Models/AWSEKSClusterInformationModel.cs (82%) rename src/{OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj => OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj} (96%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/README.md (62%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/ResourceDetectorUtils.cs (98%) rename src/{OpenTelemetry.ResourceDetectors.AWS => OpenTelemetry.Resources.AWS}/SourceGenerationContext.cs (91%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEBSResourceDetectorTests.cs => OpenTelemetry.Resources.AWS.Tests/AWSEBSDetectorTests.cs} (75%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEC2ResourceDetectorTests.cs => OpenTelemetry.Resources.AWS.Tests/AWSEC2DetectorTests.cs} (82%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests/AWSECSResourceDetectorTests.cs => OpenTelemetry.Resources.AWS.Tests/AWSECSDetectorTests.cs} (93%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests/AWSEKSResourceDetectorTests.cs => OpenTelemetry.Resources.AWS.Tests/AWSEKSDetectorTests.cs} (80%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/Http/CertificateUploader.cs (97%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/Http/NoopServerCertificateValidationEventSource.cs (91%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/Http/ServerCertificateValidationHandlerTests.cs (94%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/Http/ServerCertificateValidationProviderTests.cs (97%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests/OpenTelemetry.ResourceDetectors.AWS.Tests.csproj => OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj} (96%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/SampleAWSEBSMetadataModel.cs (76%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/SampleAWSEC2IdentityDocumentModel.cs (81%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/SampleMetadataFiles/environment.conf (100%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/SampleMetadataFiles/testcgroup (100%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/SampleMetadataFiles/testekstoken (100%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/ecs_metadata/metadatav4-response-container-ec2.json (100%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/ecs_metadata/metadatav4-response-container-fargate.json (100%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/ecs_metadata/metadatav4-response-task-ec2.json (100%) rename test/{OpenTelemetry.ResourceDetectors.AWS.Tests => OpenTelemetry.Resources.AWS.Tests}/ecs_metadata/metadatav4-response-task-fargate.json (100%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 39999c7e41..4d4eedc92e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -48,8 +48,8 @@ body: - OpenTelemetry.Instrumentation.Wcf - OpenTelemetry.PersistentStorage.Abstractions - OpenTelemetry.PersistentStorage.FileSystem - - OpenTelemetry.ResourceDetectors.AWS - OpenTelemetry.ResourceDetectors.Container + - OpenTelemetry.Resources.AWS - OpenTelemetry.Resources.Azure - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 4dff155b53..d388218eef 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -48,8 +48,8 @@ body: - OpenTelemetry.Instrumentation.Wcf - OpenTelemetry.PersistentStorage.Abstractions - OpenTelemetry.PersistentStorage.FileSystem - - OpenTelemetry.ResourceDetectors.AWS - OpenTelemetry.ResourceDetectors.Container + - OpenTelemetry.Resources.AWS - OpenTelemetry.Resources.Azure - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 50b705da97..9548884f10 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -60,11 +60,11 @@ components: - vishweshbankwar src/OpenTelemetry.PersistentStorage.FileSystem/: - vishweshbankwar - src/OpenTelemetry.ResourceDetectors.AWS/: - - srprash - - ppittle src/OpenTelemetry.ResourceDetectors.Container/: - iskiselev + src/OpenTelemetry.Resources.AWS/: + - srprash + - ppittle src/OpenTelemetry.Resources.Azure/: - rajkumar-rangaraj - vishweshbankwar @@ -151,11 +151,11 @@ components: - codeblanch test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: - vishweshbankwar - test/OpenTelemetry.ResourceDetectors.AWS.Tests/: - - srprash - - ppittle test/OpenTelemetry.ResourceDetectors.Container.Tests/: - iskiselev + test/OpenTelemetry.Resources.AWS.Tests/: + - srprash + - ppittle test/OpenTelemetry.Resources.Azure.Tests/: - rajkumar-rangaraj - vishweshbankwar diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index faffeeb558..3559327d91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,8 +51,8 @@ jobs: instrumentation-stackexchangeredis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] instrumentation-wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] persistentstorage: ['*/OpenTelemetry.PersistentStorage*/**', '!**/*.md'] - resourcedetectors-aws: ['*/OpenTelemetry.ResourceDetectors.AWS*/**', '!**/*.md'] resourcedetectors-container: ['*/OpenTelemetry.ResourceDetectors.Container*/**', '!**/*.md'] + resources-aws: ['*/OpenTelemetry.Resources.AWS*/**', '!**/*.md'] resources-azure: ['*/OpenTelemetry.Resources.Azure*/**', '!**/*.md'] resources-gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] resources-host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md'] @@ -398,27 +398,27 @@ jobs: project-name: OpenTelemetry.PersistentStorage code-cov-name: PersistentStorage - build-test-resourcedetectors-aws: + build-test-resourcedetectors-container: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'resourcedetectors-aws') + contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.ResourceDetectors.AWS] - code-cov-name: ResourceDetectors.AWS + project-name: Component[OpenTelemetry.ResourceDetectors.Container] + code-cov-name: ResourceDetectors.Container - build-test-resourcedetectors-container: + build-test-resources-aws: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') + contains(needs.detect-changes.outputs.changes, 'resources-aws') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.ResourceDetectors.Container] - code-cov-name: ResourceDetectors.Container + project-name: Component[OpenTelemetry.Resources.AWS] + code-cov-name: Resources.AWS build-test-resources-azure: needs: detect-changes @@ -524,8 +524,8 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'instrumentation-runtime') || contains(needs.detect-changes.outputs.changes, 'instrumentation-sqlclient') || contains(needs.detect-changes.outputs.changes, 'instrumentation-stackexchangeredis') - || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-aws') || contains(needs.detect-changes.outputs.changes, 'resourcedetectors-container') + || contains(needs.detect-changes.outputs.changes, 'resources-aws') || contains(needs.detect-changes.outputs.changes, 'resources-azure') || contains(needs.detect-changes.outputs.changes, 'resources-host') || contains(needs.detect-changes.outputs.changes, 'resources-process') @@ -572,8 +572,8 @@ jobs: build-test-instrumentation-stackexchangeredis-integration, build-test-instrumentation-wcf, build-test-persistentstorage, - build-test-resourcedetectors-aws, build-test-resourcedetectors-container, + build-test-resources-aws, build-test-resources-azure, build-test-resources-gcp, build-test-resources-host, diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 34a8bf60c0..133f94c4c0 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -259,9 +259,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\UriHelper.cs = src\Shared\UriHelper.cs EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS", "src\OpenTelemetry.ResourceDetectors.AWS\OpenTelemetry.ResourceDetectors.AWS.csproj", "{71BABAC0-E299-48BF-93E2-C11C3840B037}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.AWS", "src\OpenTelemetry.Resources.AWS\OpenTelemetry.Resources.AWS.csproj", "{71BABAC0-E299-48BF-93E2-C11C3840B037}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.ResourceDetectors.AWS.Tests", "test\OpenTelemetry.ResourceDetectors.AWS.Tests\OpenTelemetry.ResourceDetectors.AWS.Tests.csproj", "{DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.AWS.Tests", "test\OpenTelemetry.Resources.AWS.Tests\OpenTelemetry.Resources.AWS.Tests.csproj", "{DE898A1E-920E-476F-B0DB-A98AFD6E3BF4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.InfluxDB", "src\OpenTelemetry.Exporter.InfluxDB\OpenTelemetry.Exporter.InfluxDB.csproj", "{FD5E9AC8-DC05-4C64-BDC6-D26F5552808E}" EndProject diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Unshipped.txt deleted file mode 100644 index 2ca53c2ade..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,6 +0,0 @@ -OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector -OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.AWSEBSResourceDetector() -> void -OpenTelemetry.ResourceDetectors.AWS.AWSEBSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector -OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.AWSEC2ResourceDetector() -> void -OpenTelemetry.ResourceDetectors.AWS.AWSEC2ResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt deleted file mode 100644 index 2ac5b3257b..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,6 +0,0 @@ -OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector -OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector.AWSECSResourceDetector() -> void -OpenTelemetry.ResourceDetectors.AWS.AWSECSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! -OpenTelemetry.ResourceDetectors.AWS.AWSEKSResourceDetector -OpenTelemetry.ResourceDetectors.AWS.AWSEKSResourceDetector.AWSEKSResourceDetector() -> void -OpenTelemetry.ResourceDetectors.AWS.AWSEKSResourceDetector.Detect() -> OpenTelemetry.Resources.Resource! diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs b/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs deleted file mode 100644 index 85c339d6bd..0000000000 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AssemblyInfo.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Runtime.CompilerServices; - -#if SIGNED -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -#else -[assembly: InternalsVisibleTo("OpenTelemetry.ResourceDetectors.AWS.Tests")] -#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.AWS/.publicApi/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.AWS/.publicApi/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.AWS/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.AWS/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..a6dd3ce0c5 --- /dev/null +++ b/src/OpenTelemetry.Resources.AWS/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,3 @@ +OpenTelemetry.Resources.AWSResourceBuilderExtensions +static OpenTelemetry.Resources.AWSResourceBuilderExtensions.AddAWSEBSDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Resources.AWSResourceBuilderExtensions.AddAWSEC2Detector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.ResourceDetectors.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..dd8d0109c1 --- /dev/null +++ b/src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +static OpenTelemetry.Resources.AWSResourceBuilderExtensions.AddAWSECSDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Resources.AWSResourceBuilderExtensions.AddAWSEKSDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs similarity index 89% rename from src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs rename to src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs index 442ffe406c..4540259143 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEBSResourceDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs @@ -6,15 +6,14 @@ #if NET6_0_OR_GREATER using System.Runtime.InteropServices; #endif -using OpenTelemetry.ResourceDetectors.AWS.Models; -using OpenTelemetry.Resources; +using OpenTelemetry.Resources.AWS.Models; -namespace OpenTelemetry.ResourceDetectors.AWS; +namespace OpenTelemetry.Resources.AWS; /// -/// Resource detector for application running in AWS ElasticBeanstalk environment. +/// Resource detector for application running in AWS Elastic Beanstalk environment. /// -public sealed class AWSEBSResourceDetector : IResourceDetector +internal sealed class AWSEBSDetector : IResourceDetector { private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; #if NET6_0_OR_GREATER @@ -22,7 +21,7 @@ public sealed class AWSEBSResourceDetector : IResourceDetector #endif /// - /// Detector the required and optional resource attributes from AWS ElasticBeanstalk. + /// Detector the required and optional resource attributes from AWS Elastic Beanstalk. /// /// Resource with key-value pairs of resource attributes. public Resource Detect() @@ -49,7 +48,7 @@ public Resource Detect() } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSEBSDetector), ex); } return Resource.Empty; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs similarity index 94% rename from src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs rename to src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs index ce5e0bfffc..e0c605b984 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEC2ResourceDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs @@ -3,15 +3,14 @@ using System; using System.Collections.Generic; -using OpenTelemetry.ResourceDetectors.AWS.Models; -using OpenTelemetry.Resources; +using OpenTelemetry.Resources.AWS.Models; -namespace OpenTelemetry.ResourceDetectors.AWS; +namespace OpenTelemetry.Resources.AWS; /// /// Resource detector for application running on AWS EC2 instance. /// -public sealed class AWSEC2ResourceDetector : IResourceDetector +internal sealed class AWSEC2Detector : IResourceDetector { private const string AWSEC2MetadataTokenTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"; private const string AWSEC2MetadataTokenHeader = "X-aws-ec2-metadata-token"; @@ -35,7 +34,7 @@ public Resource Detect() } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2ResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSEC2Detector), ex); } return Resource.Empty; diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs similarity index 93% rename from src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs rename to src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs index 709c56560d..054f82c1b8 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSECSResourceDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs @@ -7,14 +7,13 @@ using System.Net.Http; using System.Text.Json; using System.Text.RegularExpressions; -using OpenTelemetry.Resources; -namespace OpenTelemetry.ResourceDetectors.AWS; +namespace OpenTelemetry.Resources.AWS; /// /// Resource detector for application running in AWS ECS. /// -public sealed class AWSECSResourceDetector : IResourceDetector +internal sealed class AWSECSDetector : IResourceDetector { private const string AWSECSMetadataPath = "/proc/self/cgroup"; private const string AWSECSMetadataURLKey = "ECS_CONTAINER_METADATA_URI"; @@ -47,7 +46,7 @@ public Resource Detect() } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), ex); } try @@ -56,7 +55,7 @@ public Resource Detect() } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), ex); } return new Resource(resourceAttributes); @@ -80,14 +79,14 @@ internal static List> ExtractMetadataV4ResourceAttr if (!containerResponse.RootElement.TryGetProperty("ContainerARN", out var containerArnElement) || containerArnElement.GetString() is not string containerArn) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); return new List>(); } if (!taskResponse.RootElement.TryGetProperty("Cluster", out var clusterArnElement) || clusterArnElement.GetString() is not string clusterArn) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); return new List>(); } @@ -129,7 +128,7 @@ internal static List> ExtractMetadataV4ResourceAttr } else { - AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSResourceDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{launchTypeElement}'")); + AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), new ArgumentException($"The ECS Metadata V4 response contained the unrecognized launch type '{launchTypeElement}'")); } if (taskResponse.RootElement.TryGetProperty("TaskARN", out var taskArnElement) && taskArnElement.ValueKind == JsonValueKind.String) diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs similarity index 90% rename from src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs rename to src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index c8a616f2b7..597ccc86a1 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSEKSResourceDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -1,21 +1,19 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NETFRAMEWORK - +#if !NETFRAMEWORK using System; using System.Collections.Generic; using System.Net.Http; using System.Text; -using OpenTelemetry.ResourceDetectors.AWS.Models; -using OpenTelemetry.Resources; +using OpenTelemetry.Resources.AWS.Models; -namespace OpenTelemetry.ResourceDetectors.AWS; +namespace OpenTelemetry.Resources.AWS; /// /// Resource detector for application running in AWS EKS. /// -public sealed class AWSEKSResourceDetector : IResourceDetector +internal sealed class AWSEKSDetector : IResourceDetector { private const string AWSEKSCertificatePath = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"; private const string AWSEKSCredentialPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"; @@ -83,7 +81,7 @@ internal static List> ExtractResourceAttributes(str } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to load client token", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSDetector)} : Failed to load client token", ex); } return null; @@ -107,7 +105,7 @@ internal static List> ExtractResourceAttributes(str } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get Container Id", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSDetector)} : Failed to get Container Id", ex); } return null; @@ -131,7 +129,7 @@ internal static List> ExtractResourceAttributes(str } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get cluster information", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSDetector)} : Failed to get cluster information", ex); } return null; @@ -146,7 +144,7 @@ private static bool IsEKSProcess(string credentials, HttpClientHandler? httpClie } catch (Exception ex) { - AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSResourceDetector)} : Failed to get EKS information", ex); + AWSResourcesEventSource.Log.ResourceAttributesExtractException($"{nameof(AWSEKSDetector)} : Failed to get EKS information", ex); } return !string.IsNullOrEmpty(awsAuth); diff --git a/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs new file mode 100644 index 0000000000..8ac475c773 --- /dev/null +++ b/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; +using OpenTelemetry.Resources.AWS; + +namespace OpenTelemetry.Resources; + +/// +/// Extension methods to simplify registering of AWS resource detectors. +/// +public static class AWSResourceBuilderExtensions +{ + /// + /// Enables AWS Elastic Beanstalk resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAWSEBSDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AWSEBSDetector()); + } + + /// + /// Enables AWS EC2 resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAWSEC2Detector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AWSEC2Detector()); + } + +#if !NETFRAMEWORK + /// + /// Enables AWS ECS resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAWSECSDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AWSECSDetector()); + } + + /// + /// Enables AWS EKS resource detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddAWSEKSDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new AWSEKSDetector()); + } +#endif +} diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs similarity index 95% rename from src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs rename to src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs index b956947a95..b352ab5515 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSResourcesEventSource.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs @@ -5,9 +5,9 @@ using System.Diagnostics.Tracing; using OpenTelemetry.Internal; -namespace OpenTelemetry.ResourceDetectors.AWS; +namespace OpenTelemetry.Resources.AWS; -[EventSource(Name = "OpenTelemetry-ResourceDetectors-AWS")] +[EventSource(Name = "OpenTelemetry-Resources-AWS")] internal sealed class AWSResourcesEventSource : EventSource, IServerCertificateValidationEventSource { public static AWSResourcesEventSource Log = new(); diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs b/src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs similarity index 97% rename from src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs rename to src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs index 850e6f4a44..1f5cd829d8 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -namespace OpenTelemetry.ResourceDetectors.AWS; +namespace OpenTelemetry.Resources.AWS; internal static class AWSSemanticConventions { diff --git a/src/OpenTelemetry.Resources.AWS/AssemblyInfo.cs b/src/OpenTelemetry.Resources.AWS/AssemblyInfo.cs new file mode 100644 index 0000000000..3fb32600ed --- /dev/null +++ b/src/OpenTelemetry.Resources.AWS/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.AWS.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.AWS.Tests")] +#endif diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md similarity index 64% rename from src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md rename to src/OpenTelemetry.Resources.AWS/CHANGELOG.md index b2e7f28f2e..32a9d6e0d5 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md @@ -9,6 +9,19 @@ ([#1576](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1576)) * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.AWS` + to `OpenTelemetry.Resources.AWS`. + ([#1839](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1839)) +* **Breaking Change**: `AWSEBSResourceDetector`, `AWSEC2ResourceDetector`, +`AWSECSResourceDetector` and `AWSEKSResourceDetector` types are now internal, +use `ResourceBuilder` extension methods `AddAWSEBSDetector`, +`AddAWSEC2Detector`, `AddAWSECSDetector` +and `AddAWSEKSDetector` respectively to enable the detectors. + ([#1839](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1839)) +* **Breaking Change**: Renamed EventSource +from `OpenTelemetry-ResourceDetectors-AWS` +to `OpenTelemetry-Resources-AWS`. + ([#1839](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1839)) ## 1.4.0-beta.1 diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs b/src/OpenTelemetry.Resources.AWS/Models/AWSEBSMetadataModel.cs similarity index 88% rename from src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs rename to src/OpenTelemetry.Resources.AWS/Models/AWSEBSMetadataModel.cs index a806fb8f69..223e5f9b47 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEBSMetadataModel.cs +++ b/src/OpenTelemetry.Resources.AWS/Models/AWSEBSMetadataModel.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; -namespace OpenTelemetry.ResourceDetectors.AWS.Models; +namespace OpenTelemetry.Resources.AWS.Models; internal class AWSEBSMetadataModel { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs b/src/OpenTelemetry.Resources.AWS/Models/AWSEC2IdentityDocumentModel.cs similarity index 91% rename from src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs rename to src/OpenTelemetry.Resources.AWS/Models/AWSEC2IdentityDocumentModel.cs index 4bd2f4dfef..665318c356 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEC2IdentityDocumentModel.cs +++ b/src/OpenTelemetry.Resources.AWS/Models/AWSEC2IdentityDocumentModel.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; -namespace OpenTelemetry.ResourceDetectors.AWS.Models; +namespace OpenTelemetry.Resources.AWS.Models; internal class AWSEC2IdentityDocumentModel { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs b/src/OpenTelemetry.Resources.AWS/Models/AWSEKSClusterDataModel.cs similarity index 82% rename from src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs rename to src/OpenTelemetry.Resources.AWS/Models/AWSEKSClusterDataModel.cs index 0284548085..06c7e7c6ce 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterDataModel.cs +++ b/src/OpenTelemetry.Resources.AWS/Models/AWSEKSClusterDataModel.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; -namespace OpenTelemetry.ResourceDetectors.AWS.Models; +namespace OpenTelemetry.Resources.AWS.Models; internal sealed class AWSEKSClusterDataModel { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs b/src/OpenTelemetry.Resources.AWS/Models/AWSEKSClusterInformationModel.cs similarity index 82% rename from src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs rename to src/OpenTelemetry.Resources.AWS/Models/AWSEKSClusterInformationModel.cs index b732eb7795..3fe0f39482 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/Models/AWSEKSClusterInformationModel.cs +++ b/src/OpenTelemetry.Resources.AWS/Models/AWSEKSClusterInformationModel.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; -namespace OpenTelemetry.ResourceDetectors.AWS.Models; +namespace OpenTelemetry.Resources.AWS.Models; internal sealed class AWSEKSClusterInformationModel { diff --git a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj similarity index 96% rename from src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj rename to src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj index b8d2ea3cd7..102b4946b0 100644 --- a/src/OpenTelemetry.ResourceDetectors.AWS/OpenTelemetry.ResourceDetectors.AWS.csproj +++ b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj @@ -5,7 +5,7 @@ net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. - ResourceDetectors.AWS- + Resources.AWS- $(NetMinimumSupportedVersion) OpenTelemetry Extensions - Container Resource Detector from Container environment. - ResourceDetectors.Container- + Resources.Container- + From 39a7818e63de7f55edfe9d1a5df1549ed0f87a27 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:25:55 +0000 Subject: [PATCH 1123/1499] [Resources.Azure] Rename AddAppServiceDetector to AddAzureAppServiceDetector (#1883) --- .../.publicApi/PublicAPI.Unshipped.txt | 2 +- .../AzureResourceBuilderExtensions.cs | 4 ++-- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Resources.Azure/README.md | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt index 30a42e0213..c013aaa0d3 100644 --- a/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Resources.Azure/.publicApi/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ OpenTelemetry.Resources.AzureResourceBuilderExtensions -static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAppServiceDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! +static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAzureAppServiceDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAzureVMDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! static OpenTelemetry.Resources.AzureResourceBuilderExtensions.AddAzureContainerAppsDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs index 9fe109a32e..588e92ccad 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs @@ -12,11 +12,11 @@ namespace OpenTelemetry.Resources; public static class AzureResourceBuilderExtensions { /// - /// Enables Azure AppService resource detector. + /// Enables Azure App Service resource detector. /// /// being configured. /// The instance of being configured. - public static ResourceBuilder AddAppServiceDetector(this ResourceBuilder builder) + public static ResourceBuilder AddAzureAppServiceDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); return builder.AddDetector(new AppServiceResourceDetector()); diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 0b82c8c635..983cd8a6e1 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* **Breaking Change**: Renamed method from `AddAppServiceDetector` + to `AddAzureAppServiceDetector`. + ([#1883](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1883)) + ## 1.0.0-beta.7 Released 2024-Jun-04 diff --git a/src/OpenTelemetry.Resources.Azure/README.md b/src/OpenTelemetry.Resources.Azure/README.md index 37276aacf7..7c7988d4b6 100644 --- a/src/OpenTelemetry.Resources.Azure/README.md +++ b/src/OpenTelemetry.Resources.Azure/README.md @@ -27,7 +27,7 @@ using OpenTelemetry.Resources; var tracerProvider = Sdk.CreateTracerProviderBuilder() // other configurations - .ConfigureResource(resource => resource.AddAppServiceDetector()) + .ConfigureResource(resource => resource.AddAzureAppServiceDetector()) .Build(); ``` From c49a8e8faaefca35041e57b6e6faa50ce71c53cc Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 12 Jun 2024 20:38:21 +0200 Subject: [PATCH 1124/1499] [repo] Prepare release Exporter.Geneva-1.9.0-rc.1 (#1875) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Vishwesh Bankwar Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 909424c295..9afb8423cd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +## 1.9.0-rc.1 + +Released 2024-Jun-12 + +* Update OpenTelemetry SDK version to `1.9.0-rc.1`. + ([#1869](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1869)) + * Added `LoggerProviderBuilder.AddGenevaLogExporter` registration extensions. Added `TracerProviderBuilder.AddGenevaTraceExporter()` registration extension. ([#1880](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1880)) From 1913cd007897422657dd20f760a3ee99343bedef Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 13 Jun 2024 10:04:20 -0700 Subject: [PATCH 1125/1499] [repo] Core version update improvements (#1882) --- build/scripts/post-release.psm1 | 93 ++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 30 deletions(-) diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index 5cdf7b5d85..0cc7e96fd7 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -264,6 +264,7 @@ function CreateOpenTelemetryCoreLatestVersionUpdatePullRequest { [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$tag, [Parameter()][string]$targetBranch="main", + [Parameter()][string]$lineEnding="`n", [Parameter()][string]$gitUserName, [Parameter()][string]$gitUserEmail ) @@ -275,26 +276,35 @@ function CreateOpenTelemetryCoreLatestVersionUpdatePullRequest { } $tagPrefix = $match.Groups[1].Value - if ($tagPrefix.StartsWith('core-') -eq $false) + $version = $match.Groups[2].Value + $isPrerelease = ($version.Contains('-alpha.') -or $version.Contains('-beta.') -or $version.Contains('-rc.')) + + if ($tagPrefix.StartsWith('core-') -eq $true) + { + $changelogEntry = "Updated OpenTelemetry core component version(s) to" + $propertyName = "OpenTelemetryCoreLatestVersion" + $propertyVersion = "[$version,2.0)" + if ($isPrerelease -eq $true) + { + $propertyName = "OpenTelemetryCoreLatestPrereleaseVersion" + $propertyVersion = "[$version]" + } + } + elseif ($tagPrefix.StartsWith('coreunstable-') -eq $true) + { + $changelogEntry = "Updated OpenTelemetry core unstable component version(s) to" + $propertyName = "OpenTelemetryCoreUnstableLatestVersion" + $propertyVersion = "[$version]" + } + else { Return } $projectsAndDependenciesBefore = GetCoreDependenciesForProjects - $version = $match.Groups[2].Value - $isPrerelease = ($version.Contains('-alpha.') -or $version.Contains('-beta.') -or $version.Contains('-rc.')) - $branch="release/post-core-${version}-update" - $propertyName = "OpenTelemetryCoreLatestVersion" - $propertyVersion = "[$version,2.0)" - if ($isPrerelease -eq $true) - { - $propertyName = "OpenTelemetryCoreLatestPrereleaseVersion" - $propertyVersion = "[$version]" - } - (Get-Content build/Common.props) ` -replace "<$propertyName>.*<\/$propertyName>", "<$propertyName>$propertyVersion" | Set-Content build/Common.props @@ -363,12 +373,14 @@ Merge once packages are available on NuGet and the build passes. "@ $createPullRequestResponse = gh pr create ` - --title "[release] Core release $version updates" ` + --title "[release] $tag release updates" ` --body $body ` --base $targetBranch ` --head $branch ` --label release + Write-Host $createPullRequestResponse + $match = [regex]::Match($createPullRequestResponse, "\/pull\/(.*)$") if ($match.Success -eq $false) { @@ -383,18 +395,25 @@ Merge once packages are available on NuGet and the build passes. } $entry = @" -* Updated OpenTelemetry core component version(s) to ``$version``. +* $changelogEntry ``$version``. ([#$pullRequestNumber](https://github.com/$gitRepository/pull/$pullRequestNumber)) "@ $lastLineBlank = $true + $changelogFilesUpdated = 0 foreach ($projectDir in $changedProjects.Keys) { $path = Join-Path -Path $projectDir -ChildPath "CHANGELOG.md" + if ([System.IO.File]::Exists($path) -eq $false) + { + Write-Host "No CHANGELOG found in $projectDir" + continue + } + $changelogContent = Get-Content -Path $path $started = $false @@ -411,16 +430,21 @@ $entry = @" { if ($lastLineBlank -eq $false) { - $content += "`r`n" + $content += $lineEnding } $content += $entry $started = $false $isRemoving = $false } - elseif ($line -like '*Update* OpenTelemetry SDK version to*' -and $started -eq $true) + elseif ($started -eq $true -and $tagPrefix.StartsWith('core-') -eq $true -and $line -like '*Update* OpenTelemetry SDK version to*') { - $isRemoving = $true - continue + $isRemoving = $true + continue + } + elseif ($started -eq $true -and $line -like "*$changelogEntry*") + { + $isRemoving = $true + continue } if ($line.StartsWith('* ')) @@ -432,7 +456,7 @@ $entry = @" if ($lastLineBlank -eq $false) { - $content += "`r`n" + $content += $lineEnding } } @@ -441,7 +465,7 @@ $entry = @" continue } - $content += $line + "`r`n" + $content += $line + $lineEnding $lastLineBlank = [string]::IsNullOrWhitespace($line) } @@ -451,7 +475,7 @@ $entry = @" # Note: If we never wrote the entry it means the file ended in the unreleased section if ($lastLineBlank -eq $false) { - $content += "`r`n" + $content += $lineEnding } $content += $entry } @@ -463,18 +487,23 @@ $entry = @" { throw 'git add failure' } - } - git commit -m "Update CHANGELOGs for projects using $propertyName." 2>&1 | % ToString - if ($LASTEXITCODE -gt 0) - { - throw 'git commit failure' + $changelogFilesUpdated++ } - git push -u origin $branch 2>&1 | % ToString - if ($LASTEXITCODE -gt 0) + if ($changelogFilesUpdated -gt 0) { - throw 'git push failure' + git commit -m "Update CHANGELOGs for projects using $propertyName." 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git commit failure' + } + + git push -u origin $branch 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git push failure' + } } } @@ -504,7 +533,11 @@ function GetCoreDependenciesForProjects { if ($packageName -eq 'OpenTelemetry' -or $packageName -eq 'OpenTelemetry.Api' -or $packageName -eq 'OpenTelemetry.Api.ProviderBuilderExtensions' -or - $packageName -eq 'OpenTelemetry.Extensions.Hosting') + $packageName -eq 'OpenTelemetry.Extensions.Hosting' -or + $packageName -eq 'OpenTelemetry.Extensions.Propagators' -or + $packageName -eq 'OpenTelemetry.Exporter.Prometheus.AspNetCore' -or + $packageName -eq 'OpenTelemetry.Exporter.Prometheus.HttpListener' -or + $packageName -eq 'OpenTelemetry.Shims.OpenTracing') { $projectDependencies[$packageName.ToString()] = $packageVersion.ToString() } From 0819114666abfdce08d05f879fda5ac4e071ef7f Mon Sep 17 00:00:00 2001 From: xiang17 Date: Thu, 13 Jun 2024 13:23:36 -0700 Subject: [PATCH 1126/1499] [Exporter.Geneva] Add TraceState support (#1850) Co-authored-by: Vishwesh Bankwar --- .../.publicApi/PublicAPI.Unshipped.txt | 4 ++- .../CHANGELOG.md | 6 ++++ .../GenevaExporterOptions.cs | 2 ++ .../MsgPackExporter/MsgPackTraceExporter.cs | 15 +++++++++ src/OpenTelemetry.Exporter.Geneva/README.md | 7 ++++ .../TLDExporter/TldTraceExporter.cs | 13 ++++++++ .../GenevaTraceExporterTests.cs | 33 ++++++++++++++++--- 7 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt index 1ebc2da8c6..47d044db99 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt @@ -1,4 +1,6 @@ +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.get -> bool +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.set -> void static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 9afb8423cd..77503d13fb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Update GenevaTraceExporter to export `activity.TraceStateString` as the value + for Part B `traceState` field for Spans when the `IncludeTraceStateForSpan` + option is set to `true`. This is an opt-in feature and the default value is `false`. + Note that this is for Spans only and not for LogRecord. + ([#1850](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1850)) + ## 1.9.0-rc.1 Released 2024-Jun-12 diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 9069182880..1f9bfa0aaf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -25,6 +25,8 @@ public class GenevaExporterOptions public EventNameExportMode EventNameExportMode { get; set; } + public bool IncludeTraceStateForSpan { get; set; } + public IReadOnlyDictionary TableNameMappings { get => this._tableNameMappings; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 94b7f86bf9..c205c8a0c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -91,6 +91,8 @@ public MsgPackTraceExporter(GenevaExporterOptions options) #endif } + this.m_shouldIncludeTraceState = options.IncludeTraceStateForSpan; + var buffer = new byte[BUFFER_SIZE]; var cursor = 0; @@ -243,6 +245,17 @@ internal int SerializeActivity(Activity activity) cntFields += 1; } + if (this.m_shouldIncludeTraceState) + { + var traceStateString = activity.TraceStateString; + if (!string.IsNullOrEmpty(traceStateString)) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "traceState"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, traceStateString); + cntFields += 1; + } + } + var linkEnumerator = activity.EnumerateLinks(); if (linkEnumerator.MoveNext()) { @@ -453,5 +466,7 @@ public void Dispose() private readonly HashSet m_dedicatedFields; #endif + private readonly bool m_shouldIncludeTraceState; + private bool isDisposed; } diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 049bb6663c..286fa63dfd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -98,6 +98,13 @@ A list of fields which should be stored as individual table columns. This is a collection of fields that will be applied to all the Logs and Traces sent through this exporter. +#### `IncludeTraceStateForSpan` (optional) + +Export `activity.TraceStateString` as the value for Part B `traceState` field for +Spans when the `IncludeTraceStateForSpan` option is set to `true`. +This is an opt-in feature and the default value is `false`. +Note that this is for Spans only and not for LogRecord. + #### `TableNameMappings` (optional) This defines the mapping for the table name used to store Logs and Traces. diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index 95e4d15b82..ce63e57fab 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -43,6 +43,7 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable private readonly byte partAFieldsCount = 3; // At least three fields: time, ext_dt_traceId, ext_dt_spanId private readonly HashSet m_customFields; private readonly Tuple repeatedPartAFields; + private readonly bool m_shouldIncludeTraceState; private readonly EventProvider eventProvider; @@ -114,6 +115,8 @@ public TldTraceExporter(GenevaExporterOptions options) this.repeatedPartAFields = eb.GetRawFields(); } } + + this.m_shouldIncludeTraceState = options.IncludeTraceStateForSpan; } public ExportResult Export(in Batch batch) @@ -205,6 +208,16 @@ internal void SerializeActivity(Activity activity) partBFieldsCount++; } + if (this.m_shouldIncludeTraceState) + { + var traceStateString = activity.TraceStateString; + if (!string.IsNullOrEmpty(traceStateString)) + { + eb.AddCountedAnsiString("traceState", traceStateString, Encoding.UTF8); + partBFieldsCount++; + } + } + var linkEnumerator = activity.EnumerateLinks(); if (linkEnumerator.MoveNext()) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index e9cc04eb8e..e7ee2668f5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -195,11 +195,15 @@ public void GenevaTraceExporter_Success_Windows() } [Theory] - [InlineData(false, false)] - [InlineData(false, true)] - [InlineData(true, false)] - [InlineData(true, true)] - public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields) + [InlineData(false, false, false)] + [InlineData(false, true, false)] + [InlineData(true, false, false)] + [InlineData(true, true, false)] + [InlineData(false, false, true)] + [InlineData(false, true, true)] + [InlineData(true, false, true)] + [InlineData(true, true, true)] + public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields, bool includeTraceState) { string path = string.Empty; Socket server = null; @@ -241,6 +245,11 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, exporterOptions.CustomFields = new string[] { "clientRequestId" }; } + if (includeTraceState) + { + exporterOptions.IncludeTraceStateForSpan = true; + } + using var exporter = new MsgPackTraceExporter(exporterOptions); #if NET8_0_OR_GREATER var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as FrozenSet; @@ -278,6 +287,11 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, var linkedtraceId2 = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686a2".AsSpan()); var linkedSpanId2 = ActivitySpanId.CreateFromString("888915b6286b9c02".AsSpan()); + if (includeTraceState) + { + parentActivity.TraceStateString = "some=state"; + } + var links = new[] { new ActivityLink(new ActivityContext( @@ -719,6 +733,15 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO Assert.Equal(activity.ParentSpanId.ToHexString(), mapping["parentId"]); } + if (!exporterOptions.IncludeTraceStateForSpan || string.IsNullOrEmpty(activity.TraceStateString)) + { + Assert.False(mapping.ContainsKey("traceState")); + } + else + { + Assert.Equal(activity.TraceStateString, mapping["traceState"]); + } + #region Assert Activity Links if (activity.Links.Any()) { From 47247c435fa437079ddefd051a76f1ff4cdaf77c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 13 Jun 2024 21:40:55 -0700 Subject: [PATCH 1127/1499] [repo] Auto-label PR workflow improvements (#1886) --- 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 a064b150be..d7d66c8396 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 119ff0c454b5ed802d732a8f9eecb7c0de226e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 14 Jun 2024 19:14:51 +0200 Subject: [PATCH 1128/1499] [Instrumentation.Elasticsearch] Nullable (#1881) --- .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 8 ++--- ...asticsearchClientInstrumentationOptions.cs | 2 +- ...searchRequestPipelineDiagnosticListener.cs | 32 +++++++++---------- ...Instrumentation.ElasticsearchClient.csproj | 1 - .../TracerProviderBuilderExtensions.cs | 6 ++-- src/Shared/ActivityInstrumentationHelper.cs | 10 +++--- src/Shared/ListenerHandler.cs | 2 +- src/Shared/MultiTypePropertyFetcher.cs | 17 ++++------ src/Shared/PropertyFetcher.AOT.cs | 2 -- .../Controllers/AnotherAreaController.cs | 2 -- .../ControllerForMyAreaController.cs | 2 -- .../Controllers/AttributeRouteController.cs | 2 -- .../ConventionalRouteController.cs | 2 -- .../Customer.cs | 4 +-- .../DependencyInjectionConfigTests.cs | 2 +- .../ElasticsearchClientTests.cs | 29 +++++++++++------ ...mentation.ElasticsearchClient.Tests.csproj | 1 - 18 files changed, 59 insertions(+), 66 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Unshipped.txt index 95461d9b80..a3c6cc40bf 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/.publicApi/PublicAPI.Unshipped.txt @@ -1,6 +1,6 @@ OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.ElasticsearchClientInstrumentationOptions() -> void -OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.get -> System.Action +OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.get -> int OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.MaxDbStatementLength.set -> void @@ -11,6 +11,6 @@ OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumenta OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.ElasticsearchClient.ElasticsearchClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddElasticsearchClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs index dcb91ef5c1..3c7e647ef4 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/ElasticsearchClientInstrumentationOptions.cs @@ -41,5 +41,5 @@ public class ElasticsearchClientInstrumentationOptions /// object: the raw object from which additional information can be extracted to enrich the activity. /// The type of this object depends on the event, which is given by the above parameter. /// - public Action Enrich { get; set; } + public Action? Enrich { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index af907e627d..315c7a4e44 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -28,17 +28,17 @@ internal class ElasticsearchRequestPipelineDiagnosticListener : ListenerHandler internal static readonly string ActivitySourceName = AssemblyName.Name; internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); - private static readonly Regex ParseRequest = new Regex(@"\n# Request:\r?\n(\{.*)\n# Response", RegexOptions.Compiled | RegexOptions.Singleline); - private static readonly ConcurrentDictionary MethodNameCache = new ConcurrentDictionary(); + private static readonly Regex ParseRequest = new(@"\n# Request:\r?\n(\{.*)\n# Response", RegexOptions.Compiled | RegexOptions.Singleline); + private static readonly ConcurrentDictionary MethodNameCache = new(); private readonly ElasticsearchClientInstrumentationOptions options; - private readonly MultiTypePropertyFetcher uriFetcher = new MultiTypePropertyFetcher("Uri"); - private readonly MultiTypePropertyFetcher methodFetcher = new MultiTypePropertyFetcher("Method"); - private readonly MultiTypePropertyFetcher debugInformationFetcher = new MultiTypePropertyFetcher("DebugInformation"); - private readonly MultiTypePropertyFetcher httpStatusFetcher = new MultiTypePropertyFetcher("HttpStatusCode"); - private readonly MultiTypePropertyFetcher originalExceptionFetcher = new MultiTypePropertyFetcher("OriginalException"); - private readonly MultiTypePropertyFetcher failureReasonFetcher = new MultiTypePropertyFetcher("FailureReason"); - private readonly MultiTypePropertyFetcher responseBodyFetcher = new MultiTypePropertyFetcher("ResponseBodyInBytes"); + private readonly MultiTypePropertyFetcher uriFetcher = new("Uri"); + private readonly MultiTypePropertyFetcher methodFetcher = new("Method"); + private readonly MultiTypePropertyFetcher debugInformationFetcher = new("DebugInformation"); + private readonly MultiTypePropertyFetcher httpStatusFetcher = new("HttpStatusCode"); + private readonly MultiTypePropertyFetcher originalExceptionFetcher = new("OriginalException"); + private readonly MultiTypePropertyFetcher failureReasonFetcher = new("FailureReason"); + private readonly MultiTypePropertyFetcher responseBodyFetcher = new("ResponseBodyInBytes"); public ElasticsearchRequestPipelineDiagnosticListener(ElasticsearchClientInstrumentationOptions options) : base("Elasticsearch.Net.RequestPipeline") @@ -46,7 +46,7 @@ public ElasticsearchRequestPipelineDiagnosticListener(ElasticsearchClientInstrum this.options = options; } - public override void OnEventWritten(string name, object payload) + public override void OnEventWritten(string name, object? payload) { var activity = Activity.Current; Guard.ThrowIfNull(activity); @@ -61,7 +61,7 @@ public override void OnEventWritten(string name, object payload) } } - private static string GetDisplayName(Activity activity, object method, string elasticType = null) + private static string GetDisplayName(Activity activity, object? method, string? elasticType = null) { switch (activity.OperationName) { @@ -83,7 +83,7 @@ private static string GetDisplayName(Activity activity, object method, string el } } - private static string GetElasticIndex(Uri uri) + private static string? GetElasticIndex(Uri uri) { // first segment is always / if (uri.Segments.Length < 2) @@ -91,7 +91,7 @@ private static string GetElasticIndex(Uri uri) return null; } - // operations starting with _ are not indices (_cat, _search, etc) + // operations starting with _ are not indices (_cat, _search, etc.) if (uri.Segments[1].StartsWith("_", StringComparison.Ordinal)) { return null; @@ -123,7 +123,7 @@ private string ParseAndFormatRequest(string debugInformation) var request = ParseRequest.Match(debugInformation); if (request.Success) { - string body = request.Groups[1]?.Value?.Trim(); + string? body = request.Groups[1]?.Value?.Trim(); if (body == null) { return debugInformation; @@ -150,7 +150,7 @@ private string ParseAndFormatRequest(string debugInformation) return debugInformation; } - private void OnStartActivity(Activity activity, object payload) + private void OnStartActivity(Activity activity, object? payload) { // By this time, samplers have already run and // activity.IsAllDataRequested populated accordingly. @@ -226,7 +226,7 @@ private void OnStartActivity(Activity activity, object payload) } } - private void OnStopActivity(Activity activity, object payload) + private void OnStopActivity(Activity activity, object? payload) { if (activity.IsAllDataRequested) { diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 30383291e8..8bd24ba026 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -6,7 +6,6 @@ Elasticsearch instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- - disable $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - disable From c513d144c503f4d61e90686a52bd187a43a11ef7 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 14 Jun 2024 14:17:03 -0700 Subject: [PATCH 1129/1499] [Exporter.Geneva] Fix test dependency conflict (#1889) --- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 8e9ab62345..24a2c36010 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -20,7 +20,7 @@ StrongNamer signs any unsigned assemblies present in the project dependencies --> - + From 1299c4789840f36198d88dbfdeaaf408f39733c2 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 06:40:02 +0200 Subject: [PATCH 1130/1499] [release] coreunstable-1.9.0-beta.1 release updates (#1890) --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index 900c2e2fa9..a2e94db9b5 100644 --- a/build/Common.props +++ b/build/Common.props @@ -38,7 +38,7 @@ [4.2.2,5.0) [3.11.0-beta1.23525.2] [8.0.0,9.0) - [1.9.0-alpha.2] + [1.9.0-beta.1] [1.8.1,2.0) [1.9.0-rc.1] [2.1.58,3.0) From 7652931371932fd96ba6e1b5b16f3b0a3ea3024e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 07:48:38 +0200 Subject: [PATCH 1131/1499] [release] core-1.9.0 release updates (#1888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- build/Common.props | 2 +- .../CHANGELOG.md | 3 +++ .../Common.GenevaExporter.props | 2 +- .../CHANGELOG.md | 6 ++++-- .../CHANGELOG.md | 8 ++++++-- .../CHANGELOG.md | 3 +++ ...OpenTelemetry.Exporter.OneCollector.csproj | 2 +- .../CHANGELOG.md | 11 ++++++++++ src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 16 +++++++++++++-- .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Extensions/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 5 +++-- .../CHANGELOG.md | 20 ++++++++++++++++--- .../CHANGELOG.md | 5 +++-- .../CHANGELOG.md | 15 ++++++++++++-- .../CHANGELOG.md | 6 ++++-- .../EntityFrameworkInstrumentationOptions.cs | 5 ++--- .../CHANGELOG.md | 6 ++++-- .../CHANGELOG.md | 8 ++++++++ .../CHANGELOG.md | 11 ++++++++-- .../CHANGELOG.md | 9 ++++++--- .../CHANGELOG.md | 15 +++++++++++--- .../CHANGELOG.md | 12 +++++++++-- .../CHANGELOG.md | 5 +++-- .../CHANGELOG.md | 8 ++++++-- .../CHANGELOG.md | 8 ++++++++ .../CHANGELOG.md | 15 +++++++++++--- .../CHANGELOG.md | 10 ++++++++-- .../CHANGELOG.md | 12 +++++++++-- .../CHANGELOG.md | 2 +- src/OpenTelemetry.Resources.AWS/CHANGELOG.md | 11 ++++++++++ .../CHANGELOG.md | 13 ++++++++++++ .../CHANGELOG.md | 7 +++++++ src/OpenTelemetry.Resources.Gcp/CHANGELOG.md | 3 +++ src/OpenTelemetry.Resources.Host/CHANGELOG.md | 6 ++++++ .../CHANGELOG.md | 6 ++++++ .../CHANGELOG.md | 5 +++++ src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 ++-- 38 files changed, 242 insertions(+), 49 deletions(-) diff --git a/build/Common.props b/build/Common.props index a2e94db9b5..7a6988f37f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -39,7 +39,7 @@ [3.11.0-beta1.23525.2] [8.0.0,9.0) [1.9.0-beta.1] - [1.8.1,2.0) + [1.9.0,2.0) [1.9.0-rc.1] [2.1.58,3.0) [3.16.0,4.0) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 77503d13fb..d48fa9a706 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -8,6 +8,9 @@ Note that this is for Spans only and not for LogRecord. ([#1850](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1850)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.9.0-rc.1 Released 2024-Jun-12 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 78181066e1..5570a7a1fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestPrereleaseVersion) + $(OpenTelemetryCoreLatestVersion) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index cd581033a3..a919418175 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Updates OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.0.0-alpha.3 @@ -11,6 +11,7 @@ Released 2023-Oct-13 * Updates to 1.6.0 of OpenTelemetry SDK. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + * Support for a configurable export interval in OpenTelemetry.Exporter.InfluxDB. ([#1394](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1394)) @@ -21,6 +22,7 @@ Released 2023-Jun-20 * Support for Resource attributes in OpenTelemetry.Exporter.InfluxDB, allowing resource attributes to be passed as InfluxDB tags. ([#1241](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1241)) + * Updates to 1.5.0 of OpenTelemetry SDK. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 1ecd8030b1..65df2e05a7 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -5,8 +5,9 @@ * Drop support for .NET Framework 4.6.1. The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.0.3 @@ -14,6 +15,7 @@ Released 2023-Feb-21 * Fixes issue in span serialization process introduced in 1.0.2 version. ([#979](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/979)) + * Update OpenTelemetry SDK version to `1.3.2`. ([#917](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/917)) @@ -33,8 +35,10 @@ Released 2022-Nov-02 * Instana span duration was not calculated correctly [376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/376) + * Application is crashing if environment variables are not defined [385](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/385) + * Update OpenTelemetry SDK version to `1.3.1`. ([#749](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/749)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index f3ad78eb10..a66bea6860 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.9.0-rc.1 Released 2024-Jun-11 diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 3a3a2cffb9..6ebaded012 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -19,7 +19,7 @@ - $(OpenTelemetryCoreLatestPrereleaseVersion) + $(OpenTelemetryCoreLatestVersion) $(DefineConstants);EXPOSE_EXPERIMENTAL_FEATURES diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 5d912749ed..00a00b1c6f 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-beta.6 Released 2024-Apr-22 @@ -9,8 +12,10 @@ Released 2024-Apr-22 * Fixes an issue when Activity/ActivityLink tags contain duplicate tag keys that lead to ArgumentException. ([#1660](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1660)) + * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + * Annotates trace information with `service.name` attribute if it's present in the resource tags. Please use `services.ConfigureResource(r => r.AddService("my-service", "1.0.0"))` @@ -23,6 +28,7 @@ Released 2024-Feb-15 * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + * Add support of a native "gRPC for .NET" for apps targeting .NET 6.0 or later. ([#1414](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1414)) 1. Add support net8.0, net6.0 as target frameworks. @@ -37,6 +43,7 @@ Released 2022-Dec-07 * Fix the issue of incorrect handling of null attributes. ([#566](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/566)) + * Support for Google Cloud Dependencies up to 3.x.x and OpenTelemetry SDK package to 1.3.1 ([#794](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/794)) @@ -46,8 +53,11 @@ Released 2022-Dec-07 Released 2022-Jul-22 * Updated OpenTelemetry SDK package version to 1.2.0 + * Updated minimum full framework support to net462 + * Update Google.Cloud.Monitoring.V3 2.1.0 -> 2.6.0 + * Update Google.Cloud.Monitoring.V3 2.0.0 -> 2.3.0 * Rename the namespaces to remove the word `Contrib` from them: @@ -70,6 +80,7 @@ Released 2022-Jul-22 ## 1.0.0-beta1 * Update OpenTelemetry SDK package version to 1.1.0 + * Log exceptions when failing to export data to stackdriver ## Initial Release diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 87a842cabd..0d049f8f79 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,11 +2,12 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) * Remove NuGet reference to `System.Net.Http` ([#1713](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1713)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.3.0-beta.1 Released 2023-Aug-02 @@ -14,29 +15,38 @@ Released 2023-Aug-02 * Rename package from `OpenTelemetry.Contrib.Extensions.AWSXRay` to `OpenTelemetry.Extensions.AWS` ([#1232](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1232)) + * Updates to 1.5.1 of OpenTelemetry SDK. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + * Enhancement - AWSXRayIdGenerator - Generate X-Ray IDs with global Random instance instead of recreating with ThreadLocal ([#380](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/380)) + * Raised minimum .NET version to `net462` ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) + * Replaced Newtonsoft.Json dependency with System.Text.Json ([#1092](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1092)) + * Enhancement - AWSECSResourceDetector - Implement `aws.{ecs.*,log.*}` resource attributes with data from ECS Metadata endpoint v4 ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) + * Removal - IResourceDetector - Remove local IResourceDetector interface and its supporting ResourceBuilderExtensions extension, and migrate all detectors to implement OpenTelemetry.Resources.IResourceDetector ([#875](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/875)) + * Add a `net6.0` build with optimized trace ID generation using the new `Activity.TraceIdGenerator` API. ([#1096](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1096)) + * Drop support for `AWSLambdaResourceDetector`. AWS Lambda Resources are detected by `OpenTelemetry.Instrumentation.AWSLambda` package ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) + * Extract AWS Resource Detectors to dedicated package `OpenTelemetry.ResourceDetectors.AWS` ([#1140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1140)) @@ -47,6 +57,7 @@ Released 2022-May-18 * Enhancement - AWSEKSResourceDetector - Validate ClusterName/ContainerID independently before adding it to the resource ([#205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/205)) + * Fix - AWSEKSResourceDetector fails to detect resources due to exception "The SSL connection could not be established" ([#208](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/208)) @@ -56,6 +67,7 @@ Released 2022-May-18 Released 2021-Sep-20 * Added AWS resource detectors ([#149](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/149)) + * Updated OTel SDK package version to 1.1.0 ([#100](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/100)) diff --git a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md index 642075cb3f..4c11ffe15d 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md @@ -4,3 +4,6 @@ * Make Extensions.Enrichment AoT compatible. ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) + +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index c71f4d8029..92a5f5775b 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-beta.5 Released 2024-May-08 diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 102e86b315..78b64f3b18 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update `OpenTelemetry.Api` to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.8.0-beta.1 @@ -11,6 +11,7 @@ Released 2024-Apr-05 * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + * Update `OpenTelemetry.Api` to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 2b31a759e3..02aedf6d07 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,9 +2,8 @@ ## Unreleased -* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. - * Update `OpenTelemetry.Api` to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.8.1 @@ -454,11 +453,14 @@ Released 2022-Aug-02 * Fix Remote IP Address - NULL reference exception. ([#3481](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3481)) + * Metrics instrumentation to correctly populate `http.flavor` tag. (1.1 instead of HTTP/1.1 etc.) ([#3379](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3379)) + * Tracing instrumentation to populate `http.flavor` tag. ([#3372](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3372)) + * Tracing instrumentation to populate `http.scheme` tag. ([#3392](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3392)) @@ -468,6 +470,7 @@ Released 2022-Jun-03 * Added additional metric dimensions. ([#3247](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3247)) + * Removes net5.0 target as .NET 5.0 is going out of support. The package keeps netstandard2.1 target, so it can still be used with .NET5.0 apps. @@ -487,9 +490,11 @@ Released 2022-Mar-30 * Fix: Http server span status is now unset for `400`-`499`. ([#2904](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2904)) + * Fix: drop direct reference of the `Microsoft.AspNetCore.Http.Features` from net5 & net6 targets (already part of the FrameworkReference since the net5). ([#2860](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2860)) + * Reduce allocations calculating the http.url tag. ([#2947](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2947)) @@ -542,6 +547,7 @@ Released 2021-Mar-19 and ActivityProcessors. Samplers, ActivityProcessor.OnStart will now get the Activity before any enrichment done by the instrumentation. ([#1836](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1836)) + * Performance optimization by leveraging sampling decision and short circuiting activity enrichment. `Filter` and `Enrich` are now only called if `activity.IsAllDataRequested` is `true` @@ -558,6 +564,7 @@ Released 2020-Nov-17 * AspNetCoreInstrumentation sets ActivitySource to activities created outside ActivitySource. ([#1515](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1515/)) + * For gRPC invocations, leading forward slash is trimmed from span name in order to conform to the specification. ([#1551](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1551)) @@ -569,17 +576,21 @@ Released 2020-Nov-5 * Record `Exception` in AspNetCore instrumentation based on `RecordException` in `AspNetCoreInstrumentationOptions` ([#1408](https://github.com/open-telemetry/opentelemetry-dotnet/issues/1408)) + * Added configuration option `EnableGrpcAspNetCoreSupport` to enable or disable support for adding OpenTelemetry RPC attributes when using [Grpc.AspNetCore](https://www.nuget.org/packages/Grpc.AspNetCore/). This option is enabled by default. ([#1423](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1423)) + * Renamed TextMapPropagator to TraceContextPropagator, CompositePropagator to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and changed from interface to abstract class. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) + * Propagators.DefaultTextMapPropagator will be used as the default Propagator ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) + * Removed Propagator from Instrumentation Options. Instrumentation now always respect the Propagator.DefaultTextMapPropagator. ([#1448](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1448)) @@ -592,6 +603,7 @@ Released 2020-Oct-16 Activity.CustomProperty. To enrich activity, use the Enrich action on the instrumentation. ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) + * Span Status is populated as per new spec ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) @@ -621,6 +633,7 @@ Released 2020-08-28 BaggageFormat)`. Baggage sent via the [W3C Baggage](https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md) header will now be parsed and set on incoming Http spans. + * Introduced support for Grpc.AspNetCore (#803). * Attributes are added to gRPC invocations: `rpc.system`, `rpc.service`, `rpc.method`. These attributes are added to an existing span generated by @@ -628,6 +641,7 @@ Released 2020-08-28 calls where one span is created for the gRPC call and a separate span is created for the underlying HTTP call in the event both gRPC and HTTP instrumentation are enabled. + * Renamed `ITextPropagator` to `IPropagator` ([#1190](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1190)) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index db0a98ed36..a8c7fd6100 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -4,8 +4,9 @@ * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.0.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 7fb2da394c..744daabdcb 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -4,14 +4,17 @@ * Span status is set based on [semantic convention for client spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md#status). ([#1538](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1538)) + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + * Replace `db.url` attribute with `url.full` to comply with [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/database/elasticsearch.md#attributes). Redact `username` and `password` part of the `url.full`. ([#1684](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1684)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-beta.5 Released 2023-Oct-24 @@ -19,6 +22,7 @@ Released 2023-Oct-24 * Fix issue of multiple instances of OpenTelemetry-Instrumentation EventSource being created ([#1362](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1362)) + * Updated OpenTelemetry SDK package version to 1.6.0 ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) @@ -28,14 +32,21 @@ Released 2023-Mar-06 * Updated OpenTelemetry SDK package version to 1.4.0 ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) + * Update minimum full framework support to net462 + * Requests that get an HTTP status code of 404 are not marked as an error span status + * Add MaxDbStatementLength option with default of 4096 + * Remove duplicated HTTP method and URL from db.statement attribute value + * Fix faulty logic of MaxDbStatementLength option ([#425](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/425)) + * Remove method with default attribute ([#1019](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1019)) + * Added overloads which accept a name to the `TracerProviderBuilder` `AddElasticsearchClientInstrumentation` extension to allow for more fine-grained options management diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index b01ae4472d..10a28a0625 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,11 +2,12 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) * Update `Microsoft.Extensions.Options` to `8.0.0`. ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-beta.11 Released 2024-Apr-05 @@ -21,6 +22,7 @@ Released 2024-Feb-07 * **Breaking Change**: Stop emitting `db.statement_type` attribute. This attribute never was part of the [semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md#call-level-attributes). ([#1559](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1559)) + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index eb16fad1fd..a8e3241ded 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -4,7 +4,6 @@ using System; using System.Data; using System.Diagnostics; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; @@ -14,12 +13,12 @@ namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; public class EntityFrameworkInstrumentationOptions { /// - /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default value: True. + /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default value: True. /// public bool SetDbStatementForStoredProcedure { get; set; } = true; /// - /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. + /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. /// public bool SetDbStatementForText { get; set; } diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 5e93613509..256a6c645b 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -4,8 +4,9 @@ * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) -* Update `OpenTelemetry.Api` to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.5.1-alpha.1 @@ -30,6 +31,7 @@ e.g.: exceptions.count, attribute name: gen->generation) and descriptions ([#475](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/475)) + * Change API for GC Heap Size for .NET 6 where the API has a bug ([#495](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/495)) + * Remove gc.heap.fragmentation.size metrics due to buggy API on .NET 6 ([#509](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/509)) @@ -170,8 +176,10 @@ which are not .NET Runtime specific. * Updated OpenTelemetry SDK package version to 1.3.0 ([#411](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/411)) + * Fix some bugs in Runtime metrics ([#409](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/409)) + * Add GC heap size and refactor GC count as multi-dimensional metrics in Runtime metrics ([#412](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/412)) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index d6ac6ff546..1df71e290d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -4,9 +4,9 @@ * `ActivitySource.Version` is set to NuGet package version. ([#5498](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5498)) -* Update `OpenTelemetry.Api.ProviderBuilderExtensions` to `1.8.1`. - * Update `OpenTelemetry.Api` to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.8.0-beta.1 @@ -22,9 +22,11 @@ Released 2024-Feb-09 Now that this suite of attributes are stable, this instrumentation will only emit the new attributes. ([#5270](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5270)) + * **Breaking Change**: Renamed `SqlClientInstrumentationOptions` to `SqlClientTraceInstrumentationOptions`. ([#5285](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5285)) + * **Breaking Change**: Stop emitting `db.statement_type` attribute. This attribute was never a part of the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/database/database-spans.md#call-level-attributes). ([#5301](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5301)) @@ -125,6 +127,7 @@ Released 2022-Oct-17 respectively to set activity status. ([#3118](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3118)) ([#3751](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3751)) + * Add support for Filter option for non .NET Framework Targets ([#3743](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3743)) @@ -197,6 +200,7 @@ Released 2021-Jun-09 Released 2021-Apr-23 * Instrumentation modified to depend only on the API. + * Activities are now created with the `db.system` attribute set for usage during sampling. ([#1979](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1979)) @@ -212,13 +216,16 @@ Released 2021-Jan-29 * Microsoft.Data.SqlClient v2.0.0 and higher is now properly instrumented on .NET Framework. ([#1599](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1599)) + * SqlClientInstrumentationOptions API changes: `SetStoredProcedureCommandName` and `SetTextCommandContent` have been renamed to `SetDbStatementForStoredProcedure` and `SetDbStatementForText`. They are now only available on .NET Core. On .NET Framework they are replaced by a single `SetDbStatement` property. + * On .NET Framework, "db.statement_type" attribute is no longer set for activities created by the instrumentation. + * New setting on SqlClientInstrumentationOptions on .NET Core: `RecordException` can be set to instruct the instrumentation to record SqlExceptions as Activity [events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md). @@ -244,6 +251,7 @@ Released 2020-Oct-16 Activity.CustomProperty. To enrich activity, use the Enrich action on the instrumentation. ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) + * Span Status is populated as per new spec ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) @@ -258,6 +266,7 @@ Released 2020-08-28 * .NET Core SqlClient instrumentation will now add the raw Command object to the Activity it creates ([#1099](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1099)) + * Renamed from `AddSqlClientDependencyInstrumentation` to `AddSqlClientInstrumentation` diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index e63e226fb9..25729f47e5 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,17 +2,19 @@ ## Unreleased -* Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) * Update `Microsoft.Extensions.Options` to `8.0.0`. ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-rc9.14 Released 2024-Apr-05 * Update `OpenTelemetry.Api.ProviderBuilderExtensions` version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) @@ -78,6 +80,7 @@ Released 2023-Feb-27 * Update OTel API version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + * Added a direct dependency on System.Reflection.Emit.Lightweight which previously came transitively through the OpenTelemetry API. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) @@ -88,6 +91,7 @@ Released 2022-Jul-25 * Update the `ActivitySource` name used to the assembly name: `OpenTelemetry.Instrumentation.StackExchangeRedis`. ([#485](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/485)) + * Drain thread is marked as background. It allows to close the application even if the instrumentation is not disposed. ([#528](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/528)) @@ -150,8 +154,10 @@ Released 2021-Oct-08 * Adds SetVerboseDatabaseStatements option to allow setting more detailed database statement tag values. + * Adds Enrich option to allow enriching activities from the source profiled command objects. + * Removes upper constraint for Microsoft.Extensions.Options dependency. ([#2179](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2179)) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index edd0b206a6..b7cf631f5d 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,8 +2,8 @@ ## Unreleased -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) ## 1.0.0-rc.16 @@ -11,6 +11,7 @@ Released 2024-Apr-05 * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) @@ -39,11 +40,14 @@ Released 2023-Oct-30 * Update OpenTelemetry SDK version to `1.6.0`. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + * Fixed span hierarchy when hosted in ASP.NET ([#1342](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1342)) + * **Breaking Change** `TelemetryClientMessageInspector` and `TelemetryDispatchMessageInspector` changed from public to internal ([#1376](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1376)) + * Added support for `IRequestSessionChannel` and `IDuplexChannel` channel shapes ([#1374](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1374)) @@ -60,6 +64,7 @@ Released 2023-Aug-14 * Update OpenTelemetry SDK version to `1.5.1`. ([#1255](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1255)) + * Client instrumentation implementation moved to lower-level `BindingElement`. ([#1247](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1247)) @@ -76,6 +81,7 @@ Released 2023-Feb-27 * Update OpenTelemetry SDK version to `1.4.0`. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) + * Removes `AddWcfInstrumentation` method with default configure parameter. ([#928](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/928)) @@ -85,6 +91,7 @@ Released 2022-Dec-28 * Update OpenTelemetry SDK version to `1.3.1`. ([#631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/631)) + * Change value `rpc.system` from `wcf` to `dotnet_wcf`. ([#837](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/837)) @@ -94,6 +101,7 @@ Released 2022-Aug-23 * Updated OpenTelemetry SDK package version to 1.3.0 ([#569](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/569)) + * Changed activity source name from `OpenTelemetry.WCF` to `OpenTelemetry.Instrumentation.Wcf` ([#570](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/570)) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index 14a7d7600b..89a5d7a7a7 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog - OpenTelemetry.PersistentStorage.FileSystem -## Unrealeased +## Unreleased * Fix `System.FormatException` thrown by `PersistentStorageEventSource`. [#1613](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1613) diff --git a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md index 1c8b247574..8997d27ac3 100644 --- a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.5.0-beta.1 Released 2024-Jun-04 @@ -9,19 +12,24 @@ Released 2024-Jun-04 * Implement support for cloud.{account.id,availability_zone,region} attributes in AWS ECS detector. ([#1552](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1552)) + * Implement support for `cloud.resource_id` attribute in AWS ECS detector. ([#1576](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1576)) + * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + * **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.AWS` to `OpenTelemetry.Resources.AWS`. ([#1839](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1839)) + * **Breaking Change**: `AWSEBSResourceDetector`, `AWSEC2ResourceDetector`, `AWSECSResourceDetector` and `AWSEKSResourceDetector` types are now internal, use `ResourceBuilder` extension methods `AddAWSEBSDetector`, `AddAWSEC2Detector`, `AddAWSECSDetector` and `AddAWSEKSDetector` respectively to enable the detectors. ([#1839](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1839)) + * **Breaking Change**: Renamed EventSource from `OpenTelemetry-ResourceDetectors-AWS` to `OpenTelemetry-Resources-AWS`. @@ -33,10 +41,13 @@ Released 2024-Jan-26 * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) + * Fix AWS EBS Resource Detector working on linux. ([#1350](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1350)) + * BREAKING: All Resource Detector classes marked as `sealed`. ([#1510](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1510)) + * Make OpenTelemetry.ResourceDetectors.AWS native AoT compatible. ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 983cd8a6e1..8ca0f16711 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -6,6 +6,9 @@ to `AddAzureAppServiceDetector`. ([#1883](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1883)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-beta.7 Released 2024-Jun-04 @@ -13,16 +16,20 @@ Released 2024-Jun-04 * **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Azure` to `OpenTelemetry.Resources.Azure`. ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) + * **Breaking Change**: `AppServiceResourceDetector` type is now internal, use `ResourceBuilder` extension method `AddAppServiceDetector` to enable the detector. ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) + * **Breaking Change**: `AzureVMResourceDetector` type is now internal, use `ResourceBuilder` extension method `AddAzureVMResourceDetector` to enable the detector. ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) + * **Breaking Change**: `AzureContainerAppsResourceDetector` type is now internal, use `ResourceBuilder` extension method `AddAzureContainerAppsResourceDetector` to enable the detector. ([#1840](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1840)) + * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) @@ -48,6 +55,7 @@ Released 2024-Jan-03 * Added NET6 target framework to support Trimming. ([#1405](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1405)) + * Update OpenTelemetry SDK version to `1.7.0`. ([#1486](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1486)) @@ -59,8 +67,10 @@ Released 2023-Sep-19 use a `Timeout` to `2` seconds. This is to improve the start-up time of applications not running on Azure VMs. ([#1358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1358)) + * Updates to 1.6.0 of OpenTelemetry SDK. ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) + * Suppress instrumentation for outgoing http call made to metadata service during `Detect()`. ([#1297](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1297)) @@ -85,6 +95,7 @@ Released 2023-Jul-24 `azInst_vmScaleSetName` to `azure.vm.scaleset.name`. * **Added attributes**: `cloud.provider` and `cloud.platform`. * **Removed attributes**: `azInst_resourceGroupName`, `azInst_subscriptionId`. + * For Azure App Service: ([#1272](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1272/files)) * **Updated attributes**: `appSrv_wsHost` to `host.id`, `appSrv_SlotName` to @@ -92,8 +103,10 @@ Released 2023-Jul-24 * **Added attributes**: `cloud.resource_id`, `cloud.provider`, `cloud.platform`, `cloud.region`. * **Removed attribute**: `appSrv_ResourceGroup`. + * Updates to 1.5.0 of OpenTelemetry SDK. ([#1220](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1220)) + * Added Azure VM resource detector. ([#1182](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1182)) diff --git a/src/OpenTelemetry.Resources.Container/CHANGELOG.md b/src/OpenTelemetry.Resources.Container/CHANGELOG.md index f7ac83f86e..5d2f2ee75f 100644 --- a/src/OpenTelemetry.Resources.Container/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Container/CHANGELOG.md @@ -2,19 +2,25 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 1.0.0-beta.8 Released 2024-Jun-04 * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) + * **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Container` to `OpenTelemetry.Resources.Container`. ([#1849](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1849)) + * **Breaking Change**: `ContainerResourceDetector` type is now internal, use `ResourceBuilder` extension method `AddContainerDetector` to enable the detector. ([#1849](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1849)) + * **Breaking Change**: Renamed EventSource from `OpenTelemetry-ResourceDetectors-Container` to `OpenTelemetry-Resources-Container`. @@ -66,6 +72,7 @@ Released 2023-Apr-7 OpenTelemetry.ResourceDetectors.Container`) and the class name (`DockerResourceDetector` to `ContainerResourceDetector`). ([#1123](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1123)) + * Updates to 1.4.0 of OpenTelemetry SDK. ([#1038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1038)) diff --git a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md index fdda330d72..fb7b8986e5 100644 --- a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md @@ -7,3 +7,6 @@ ([#1691](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1691)) For more details, please refer to the [README](README.md). + +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index d92336f260..67d1c8831b 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 0.1.0-beta.1 Released 2024-Jun-04 @@ -9,12 +12,15 @@ Released 2024-Jun-04 * **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Host` to `OpenTelemetry.Resources.Host`. ([#1820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1820)) + * **Breaking Change**: `HostDetector` type is now internal, use `ResourceBuilder` extension method `AddHostDetector` to enable the detector. ([#1820](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1820)) + * Adds support for `host.id` resource attribute on non-containerized systems. `host.id` will be set per [semantic convention rules](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/resource/host.md) ([#1631](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1631)) + * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index 834146d87d..76df6368e3 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 0.1.0-beta.1 Released 2024-Jun-04 @@ -9,9 +12,11 @@ Released 2024-Jun-04 * **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.Process` to `OpenTelemetry.Resources.Process`. ([#1717](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1717)) + * **Breaking Change**: `ProcessDetector` type is now internal, use `ResourceBuilder` extension method `AddProcessDetector` to enable the detector. ([#1717](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1717)) + * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) @@ -21,6 +26,7 @@ Released 2024-Apr-05 * Added `process.owner` attribute. ([#1608](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1608)) + * Update OpenTelemetry SDK version to `1.8.0`. ([#1635](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1635)) diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md index 87b2bb5a04..a6023ccba8 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + ## 0.1.0-beta.1 Released 2024-Jun-04 @@ -9,9 +12,11 @@ Released 2024-Jun-04 * **Breaking Change**: Renamed package from `OpenTelemetry.ResourceDetectors.ProcessRuntime` to `OpenTelemetry.Resources.ProcessRuntime`. ([#1767](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1767)) + * **Breaking Change**: `ProcessRuntimeDetector` type is now internal, use `ResourceBuilder` extension method `AddProcessRuntimeDetector` to enable the detector. ([#1767](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1767)) + * Update OpenTelemetry SDK version to `1.8.1`. ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 6ba90ca9e3..a7abd0c0c1 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -11,5 +11,5 @@ Initial release of `OpenTelemetry.Sampler.AWS`. * Make OpenTelemetry.Sampler.AWS native AoT compatible. ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) -* Update OpenTelemetry SDK version to `1.8.1`. - ([#1668](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1668)) +* Updated OpenTelemetry core component version(s) to `1.9.0`. + ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 7e930194ddd140e4807137b55e56b54e5e32db6b Mon Sep 17 00:00:00 2001 From: Mohamed Asaker Date: Sun, 16 Jun 2024 23:01:11 -0700 Subject: [PATCH 1132/1499] [Sampler.AWS] Tested and Updated X-Ray Sampler (#1887) --- src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 11 +++++++---- .../SamplingRuleApplier.cs | 8 ++++---- .../TestSamplingRuleApplier.cs | 14 +++++++------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs index 2f215b0ce3..bb55ef54a1 100644 --- a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -60,11 +60,14 @@ public void UpdateRules(List newRules) List newRuleAppliers = new List(); foreach (var rule in newRules) { - var currentStatistics = this.RuleAppliers - .FirstOrDefault(currentApplier => currentApplier.RuleName == rule.RuleName) - ?.Statistics ?? new Statistics(); + // If the ruleApplier already exists in the current list of appliers, then we reuse it. + var ruleApplier = this.RuleAppliers + .FirstOrDefault(currentApplier => currentApplier.RuleName == rule.RuleName) ?? + new SamplingRuleApplier(this.ClientId, this.Clock, rule, new Statistics()); + + // update the rule in the applier in case rule attributes have changed + ruleApplier.Rule = rule; - var ruleApplier = new SamplingRuleApplier(this.ClientId, this.Clock, rule, currentStatistics); newRuleAppliers.Add(ruleApplier); } diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index 32bbae4ed1..ee88ed2c98 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -36,7 +36,7 @@ public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Stat this.FixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(rule.FixedRate)); // We either have no reservoir sampling or borrow until we get a quota so have no end time. - this.ReservoirEndTime = DateTime.MaxValue; + this.ReservoirEndTime = DateTimeOffset.MaxValue; // We don't have a SamplingTarget so are ready to report a snapshot right away. this.NextSnapshotTime = this.Clock.Now(); @@ -97,15 +97,15 @@ public bool Matches(SamplingParameters samplingParameters, Resource resource) { foreach (var tag in samplingParameters.Tags) { - if (tag.Key.Equals(SemanticConventions.AttributeHttpTarget, StringComparison.Ordinal)) + if (tag.Key.Equals(SemanticConventions.AttributeUrlPath, StringComparison.Ordinal)) { httpTarget = (string?)tag.Value; } - else if (tag.Key.Equals(SemanticConventions.AttributeHttpUrl, StringComparison.Ordinal)) + else if (tag.Key.Equals(SemanticConventions.AttributeUrlFull, StringComparison.Ordinal)) { httpUrl = (string?)tag.Value; } - else if (tag.Key.Equals(SemanticConventions.AttributeHttpMethod, StringComparison.Ordinal)) + else if (tag.Key.Equals(SemanticConventions.AttributeHttpRequestMethod, StringComparison.Ordinal)) { httpMethod = (string?)tag.Value; } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs index 725eabb8f9..a28c8faa9d 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -30,8 +30,8 @@ public void TestRuleMatchesWithAllAttributes() var activityTags = new Dictionary { { "http.host", "localhost" }, - { "http.method", "GET" }, - { "http.url", @"http://127.0.0.1:5000/helloworld" }, + { "http.request.method", "GET" }, + { "url.full", @"http://127.0.0.1:5000/helloworld" }, { "faas.id", "arn:aws:lambda:us-west-2:123456789012:function:my-function" }, }; @@ -59,8 +59,8 @@ public void TestRuleMatchesWithWildcardAttributes() var activityTags = new Dictionary { { "http.host", "localhost" }, - { "http.method", "GET" }, - { "http.url", @"http://127.0.0.1:5000/helloworld" }, + { "http.request.method", "GET" }, + { "url.full", @"http://127.0.0.1:5000/helloworld" }, }; var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); @@ -132,7 +132,7 @@ public void TestRuleMatchesWithHttpTarget() var activityTags = new Dictionary { - { "http.target", "/helloworld" }, + { "url.path", "/helloworld" }, }; var applier = new SamplingRuleApplier("clientId", new TestClock(), rule, new Statistics()); @@ -164,7 +164,7 @@ public void TestAttributeMatching() var activityTags = new Dictionary { - { "http.target", "/helloworld" }, + { "url.path", "/helloworld" }, { "dog", "bark" }, { "cat", "meow" }, }; @@ -198,7 +198,7 @@ public void TestAttributeMatchingWithLessActivityTags() var activityTags = new Dictionary { - { "http.target", "/helloworld" }, + { "url.path", "/helloworld" }, { "dog", "bark" }, }; From d86836a15f769b0ab2931fe5d88db4bd539094de Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:24:21 +0200 Subject: [PATCH 1133/1499] [release] Prepare release Exporter.OneCollector-1.9.0 (#1891) --- .../.publicApi/PublicAPI.Shipped.txt | 16 ++++++++++++---- .../.publicApi/PublicAPI.Unshipped.txt | 8 -------- .../CHANGELOG.md | 4 ++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt index 305d07d5a8..6a1052d181 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable OpenTelemetry.Exporter.OneCollector.OneCollectorExporter -OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback, bool includeFailures) -> System.IDisposable? +OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.RegisterPayloadTransmittedCallback(OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction! callback) -> System.IDisposable? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.get -> string? OpenTelemetry.Exporter.OneCollector.OneCollectorExporterOptions.ConnectionString.set -> void @@ -21,8 +21,8 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoin OpenTelemetry.Exporter.OneCollector.OneCollectorExporterTransportOptions.Endpoint.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException() -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message, System.Exception? innerException) -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneCollectorExporterValidationException(string! message) -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void @@ -39,11 +39,19 @@ OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationO OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string! connectionString) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, string? connectionString, Microsoft.Extensions.Configuration.IConfiguration? configuration, System.Action? configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, string! connectionString) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action! configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! virtual OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackAction.Invoke(in OpenTelemetry.Exporter.OneCollector.OneCollectorExporterPayloadTransmittedCallbackArguments args) -> void diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt index 9700b06ef0..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, Microsoft.Extensions.Configuration.IConfiguration! configuration) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, Microsoft.Extensions.Configuration.IConfiguration! configuration, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string! connectionString) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string! connectionString, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, string? connectionString, Microsoft.Extensions.Configuration.IConfiguration? configuration, System.Action? configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! -static OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions.AddOneCollectorExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index a66bea6860..40efc68dac 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-17 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 17c0a6fee3e10086f8a8ebd699c0ec3e7b122ee1 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:44:32 +0200 Subject: [PATCH 1134/1499] [release] Exporter.OneCollector- stable release 1.9.0 updates (#1892) --- .../OpenTelemetry.Exporter.OneCollector.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 6ebaded012..26d9b1fbda 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -15,7 +15,7 @@ this at the call site but there is a bug. This could possibly be cleaned up in the future (hopefully .NET 9) see https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 - 1.8.0 + 1.9.0 From 8c478d263d6f62d717fb6a18d3c44271db33a9a4 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:59:21 +0200 Subject: [PATCH 1135/1499] [release] Prepare release Exporter.Geneva-1.9.0-rc.2 (#1893) Co-authored-by: Vishwesh Bankwar --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index d48fa9a706..08a6d458aa 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-rc.2 + +Released 2024-Jun-17 + * Update GenevaTraceExporter to export `activity.TraceStateString` as the value for Part B `traceState` field for Spans when the `IncludeTraceStateForSpan` option is set to `true`. This is an opt-in feature and the default value is `false`. From 52392fcb98588ce92b52f78afa94404e2e8888a4 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:08:26 +0200 Subject: [PATCH 1136/1499] [release] Prepare release Instrumentation.Http-1.9.0 (#1895) Co-authored-by: Vishwesh Bankwar --- .../.publicApi/PublicAPI.Shipped.txt | 2 +- src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt index a082f2c5be..a2ea70691d 100644 --- a/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Http/.publicApi/PublicAPI.Shipped.txt @@ -19,6 +19,6 @@ OpenTelemetry.Instrumentation.Http.HttpClientTraceInstrumentationOptions.RecordE OpenTelemetry.Metrics.HttpClientInstrumentationMeterProviderBuilderExtensions OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions static OpenTelemetry.Metrics.HttpClientInstrumentationMeterProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configureHttpClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureHttpClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder +static OpenTelemetry.Trace.HttpClientInstrumentationTracerProviderBuilderExtensions.AddHttpClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 934c93772d..8963cefb47 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-17 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 9eb6da0de1b4fc70006c08dfef4ba2da15327766 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:18:20 +0200 Subject: [PATCH 1137/1499] [release] Prepare release Instrumentation.AspNetCore-1.9.0 (#1894) Co-authored-by: Vishwesh Bankwar --- .../.publicApi/PublicAPI.Shipped.txt | 2 +- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt index c8d966c517..0e39d85690 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/.publicApi/PublicAPI.Shipped.txt @@ -14,6 +14,6 @@ OpenTelemetry.Instrumentation.AspNetCore.AspNetCoreTraceInstrumentationOptions.R OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions static OpenTelemetry.Metrics.AspNetCoreInstrumentationMeterProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configureAspNetCoreTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.AspNetCoreInstrumentationTracerProviderBuilderExtensions.AddAspNetCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 02aedf6d07..1567f79401 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-17 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 3aa93d3076fa637069c87236a131a49accbd0669 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:22:41 +0200 Subject: [PATCH 1138/1499] [release] Prepare release Instrumentation.SqlClient-1.9.0-beta.1 (#1896) Co-authored-by: Vishwesh Bankwar --- src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 1df71e290d..359f58a146 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-17 + * `ActivitySource.Version` is set to NuGet package version. ([#5498](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5498)) From a655e46fffc458e902a37f70d860d46e3579fe52 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 17 Jun 2024 23:25:07 +0200 Subject: [PATCH 1139/1499] [release] Prepare release Instrumentation.GrpcNetClient-1.9.0-beta.1 (#1897) Co-authored-by: Vishwesh Bankwar --- src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md index 2ba7dc3bdf..a35c62670e 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-17 + * `ActivitySource.Version` is set to NuGet package version. ([#5498](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5498)) From 8f2e793b9c02fd7b2de6492b3116d2ca1e6a7b1f Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 04:22:58 +0200 Subject: [PATCH 1140/1499] [release] Instrumentation.Http- stable release 1.9.0 updates (#1898) Co-authored-by: Vishwesh Bankwar --- .../OpenTelemetry.Instrumentation.Http.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index b4124d8df7..e10e49e85e 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -6,7 +6,7 @@ Http instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.Http- - 1.8.1 + 1.9.0 enable From 352991f51075551ae31e7839c2da32680e443ada Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:05:30 +0200 Subject: [PATCH 1141/1499] [release] Instrumentation.AspNetCore- stable release 1.9.0 updates (#1899) --- .../OpenTelemetry.Instrumentation.AspNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index 9d74ddfd9c..8093e70503 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -5,7 +5,7 @@ ASP.NET Core instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNetCore Instrumentation.AspNetCore- - 1.8.1 + 1.9.0 enable From a2716eb14b2905d566f990c87b4bf2d5c6792fa5 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:31:05 +0200 Subject: [PATCH 1142/1499] [release] Prepare release Instrumentation.AspNet-1.9.0-beta.1 (#1900) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 78b64f3b18..c324e7c06c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index cf291d5c39..a711002c29 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jun-18 + ## 1.8.0-beta.3 Released 2024-May-23 From af0cf6f56619eadb3e069b287d8aad6a414a0205 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:36:44 +0200 Subject: [PATCH 1143/1499] [release] Prepare release Instrumentation.Wcf-1.0.0-rc.17 (#1901) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index b7cf631f5d..e3080ccd88 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.17 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 0b276a7ada2707eea88535277fe778ed9989dc5a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:46:31 +0200 Subject: [PATCH 1144/1499] [release] Prepare release Instrumentation.EntityFrameworkCore-1.0.0-beta.12 (#1902) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 10a28a0625..e1c2828603 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.12 + +Released 2024-Jun-18 + * Update `Microsoft.Extensions.Options` to `8.0.0`. ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) From a966b221498db64d8956ace1443265e8e423f002 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:52:09 +0200 Subject: [PATCH 1145/1499] [release] Prepare release Instrumentation.Process-0.5.0-beta.6 (#1903) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 28c49412b4..af3f2d3c64 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.5.0-beta.6 + +Released 2024-Jun-18 + * Following changes related to [Semantic Convention v1.25.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.25.0/docs/system/process-metrics.md) * `process.cpu.time` metric attribute renamed from `state` to `process.cpu.state`, * Metric descriptions fixed for `process.memory.usage` and `process.memory.virtual`, From b512467d8c619b0ea6b7b77042d671c69ec0389a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:54:23 +0200 Subject: [PATCH 1146/1499] [release] Prepare release Instrumentation.Quartz-1.0.0-beta.3 (#1904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 400dfa7e57..3aa58ef9ce 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.3 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 59d4178c7c6b600639b7307f3996e41e587231db Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 06:59:32 +0200 Subject: [PATCH 1147/1499] [release] Prepare release Instrumentation.StackExchangeRedis-1.0.0-rc9.15 (#1906) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 25729f47e5..c06d7ff476 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc9.15 + +Released 2024-Jun-18 + * Update `Microsoft.Extensions.Options` to `8.0.0`. ([#1830](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1830)) From 7395e58461ecfe5e7be5bd02a3d17d93e2d38776 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:03:12 +0200 Subject: [PATCH 1148/1499] [release] Prepare release Resources.Azure-1.0.0-beta.8 (#1907) --- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 8ca0f16711..538efdf078 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.8 + +Released 2024-Jun-18 + * **Breaking Change**: Renamed method from `AddAppServiceDetector` to `AddAzureAppServiceDetector`. ([#1883](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1883)) From 691cf3ba67b6b05389bc900111d6858705097afa Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:05:42 +0200 Subject: [PATCH 1149/1499] [release] Prepare release Resources.Host-0.1.0-beta.2 (#1909) --- src/OpenTelemetry.Resources.Host/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index 67d1c8831b..865e94c949 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-beta.2 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From aee7cab21bd9c1856fe6a6c2e1404f60953d45d1 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:09:24 +0200 Subject: [PATCH 1150/1499] [release] Prepare release Resources.Container-1.0.0-beta.9 (#1908) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Resources.Container/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Container/CHANGELOG.md b/src/OpenTelemetry.Resources.Container/CHANGELOG.md index 5d2f2ee75f..c7a5c6be52 100644 --- a/src/OpenTelemetry.Resources.Container/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.9 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 09a68bf6e41f7fd84ffbedee068764a25deaa2e3 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:11:41 +0200 Subject: [PATCH 1151/1499] [release] Prepare release Resources.Process-0.1.0-beta.2 (#1910) --- src/OpenTelemetry.Resources.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index 76df6368e3..bb23a9cd56 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-beta.2 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 419a8938be7fc3783fe58c4699dedcd59e19882b Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:13:47 +0200 Subject: [PATCH 1152/1499] [release] Prepare release Resources.ProcessRuntime-0.1.0-beta.2 (#1911) --- src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md index a6023ccba8..16ac419f87 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-beta.2 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From b3bc01b19d3f914c5481bd23dd5840f4bf916366 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:24:30 +0200 Subject: [PATCH 1153/1499] [release] Prepare release Instrumentation.Runtime-1.9.0 (#1905) --- .../.publicApi/PublicAPI.Shipped.txt | 4 +++- .../.publicApi/PublicAPI.Unshipped.txt | 4 ---- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Shipped.txt index 4f1e7e604f..ae3b3f5c33 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Shipped.txt @@ -1,4 +1,6 @@ +#nullable enable OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions OpenTelemetry.Instrumentation.Runtime.RuntimeInstrumentationOptions.RuntimeInstrumentationOptions() -> void OpenTelemetry.Metrics.MeterProviderBuilderExtensions -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Unshipped.txt index b9754cf55f..e69de29bb2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Runtime/.publicApi/PublicAPI.Unshipped.txt @@ -1,4 +0,0 @@ -#nullable enable -*REMOVED*static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddRuntimeInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index b3ae38bb77..be54016cbb 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-18 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 24d94683789aba2ffd3f8383363b2cfc03fd5f3e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 18 Jun 2024 07:50:49 +0200 Subject: [PATCH 1154/1499] [release] Instrumentation.Runtime- stable release 1.9.0 updates (#1912) --- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 9a38f8bbcf..d873a9fd12 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -5,7 +5,7 @@ dotnet runtime instrumentation for OpenTelemetry .NET $(PackageTags);runtime Instrumentation.Runtime- - 1.8.1 + 1.9.0 From 15c9dc29cdfde64c7731fe1f9613732d86198525 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 20 Jun 2024 06:36:07 +0200 Subject: [PATCH 1155/1499] [release] Prepare release Sampler.AWS-0.1.0-alpha.1 (#1913) --- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index a7abd0c0c1..cd6560fd98 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.1 + +Released 2024-Jun-20 + Initial release of `OpenTelemetry.Sampler.AWS`. * Feature - AWSXRayRemoteSampler - Add support for AWS X-Ray remote sampling From 51d367573714ce55fba51f17d442dca633b812ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 20 Jun 2024 06:42:49 +0200 Subject: [PATCH 1156/1499] [Sampler.AWS] Update documentation to install package (#1914) --- src/OpenTelemetry.Sampler.AWS/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md index cb7218aab3..314228d3f9 100644 --- a/src/OpenTelemetry.Sampler.AWS/README.md +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -11,7 +11,7 @@ See: [AWS X-Ray Sampling](https://docs.aws.amazon.com/xray/latest/devguide/xray- Start with installing the package ```shell -dotnet add package OpenTelemetry.Sampler.AWS +dotnet add package OpenTelemetry.Sampler.AWS --prerelease ``` You can configure the `AWSXRayRemoteSampler` as per the following example. From 9114d0b183def59bc0cd747bdee024aae7d35fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 20 Jun 2024 20:50:35 +0200 Subject: [PATCH 1157/1499] [Tests] Simplify usage of SamplingResult constructor (#1915) --- .../BasicTests.cs | 7 +------ .../ElasticsearchClientTests.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 8cc9c62eb5..03cc160050 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -1220,12 +1220,7 @@ private class TestSampler(SamplingDecision samplingDecision, IEnumerable + _ => { samplerCalled = true; return new SamplingResult(SamplingDecision.RecordAndSample); @@ -207,7 +207,7 @@ public async Task CanRecordAndSampleSearchCall() { Assert.True(samplerCalled); Assert.False(Sdk.SuppressInstrumentation); - Assert.True(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true + Assert.True(a.IsAllDataRequested); // If Processor.OnStart is called, activity's IsAllDataRequested is set to true startCalled++; }; @@ -250,7 +250,7 @@ public async Task CanSupressDownstreamActivities() var sampler = new TestSampler { SamplingAction = - (samplingParameters) => + _ => { samplerCalled = true; return new SamplingResult(SamplingDecision.RecordAndSample); @@ -267,7 +267,7 @@ public async Task CanSupressDownstreamActivities() { Assert.True(samplerCalled); Assert.False(Sdk.SuppressInstrumentation); - Assert.True(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true + Assert.True(a.IsAllDataRequested); // If Processor.OnStart is called, activity's IsAllDataRequested is set to true startCalled++; }; @@ -310,7 +310,7 @@ public async Task CanDropSearchCall() var sampler = new TestSampler { SamplingAction = - (samplingParameters) => + _ => { samplerCalled = true; return new SamplingResult(SamplingDecision.Drop); @@ -327,7 +327,7 @@ public async Task CanDropSearchCall() { Assert.True(samplerCalled); Assert.False(Sdk.SuppressInstrumentation); - Assert.False(a.IsAllDataRequested); // If Proccessor.OnStart is called, activity's IsAllDataRequested is set to true + Assert.False(a.IsAllDataRequested); // If Processor.OnStart is called, activity's IsAllDataRequested is set to true startCalled++; }; @@ -740,7 +740,7 @@ public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecis var client = new ElasticClient(new ConnectionSettings(new InMemoryConnection()).DefaultIndex("customer")); using (Sdk.CreateTracerProviderBuilder() - .SetSampler(new TestSampler() { SamplingAction = (samplingParameters) => new SamplingResult(samplingDecision) }) + .SetSampler(new TestSampler() { SamplingAction = _ => new SamplingResult(samplingDecision) }) .AddElasticsearchClientInstrumentation() .SetResourceBuilder(expectedResource) .AddProcessor(processor) From a3f1ceee3e37d5b7018c4202bc1f8fb46c9a250a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 21 Jun 2024 20:11:04 +0200 Subject: [PATCH 1158/1499] [release] Prepare release Exporter.Geneva-1.9.0 (#1920) --- .../.publicApi/PublicAPI.Shipped.txt | 18 ++++++++++++------ .../.publicApi/PublicAPI.Unshipped.txt | 6 ------ src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt index 33a8b061ff..2fe51143f5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt @@ -1,10 +1,10 @@ Microsoft.Extensions.Logging.GenevaLoggingExtensions -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions @@ -13,11 +13,13 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> stri OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.get -> bool +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary @@ -43,9 +45,13 @@ override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposi override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt index 47d044db99..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt @@ -1,6 +0,0 @@ -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.get -> bool -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.set -> void -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 08a6d458aa..d0ce064c8a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0 + +Released 2024-Jun-21 + ## 1.9.0-rc.2 Released 2024-Jun-17 From a779f5cee3fed48b63aac6e138f08419686b4622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 21 Jun 2024 20:22:50 +0200 Subject: [PATCH 1159/1499] [repo] ImplicitUsings - part 1 (#1919) --- src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs | 2 -- src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs | 2 -- src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs | 3 --- src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs | 3 --- src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs | 1 - .../OpenTelemetry.Resources.AWS.csproj | 1 + src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs | 6 ++---- .../AppServiceResourceDetector.cs | 2 -- .../AzureContainerAppsResourceDetector.cs | 2 -- .../AzureVMResourceDetector.cs | 1 - .../AzureVmMetaDataRequestor.cs | 2 -- .../OpenTelemetry.Resources.Azure.csproj | 1 + src/OpenTelemetry.Resources.Container/ContainerDetector.cs | 3 --- .../ContainerExtensionsEventSource.cs | 1 - .../OpenTelemetry.Resources.Container.csproj | 1 + .../Utils/EncodingUtils.cs | 3 --- src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs | 1 - .../OpenTelemetry.Resources.Gcp.csproj | 1 + src/OpenTelemetry.Resources.Host/HostDetector.cs | 3 --- src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs | 1 - .../OpenTelemetry.Resources.Host.csproj | 1 + .../OpenTelemetry.Resources.Process.csproj | 1 + src/OpenTelemetry.Resources.Process/ProcessDetector.cs | 3 --- .../OpenTelemetry.Resources.ProcessRuntime.csproj | 1 + .../ProcessRuntimeDetector.cs | 4 ---- src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs | 3 --- .../AWSXRayRemoteSamplerBuilder.cs | 1 - src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs | 5 ++--- src/OpenTelemetry.Sampler.AWS/Clock.cs | 2 -- src/OpenTelemetry.Sampler.AWS/GetSamplingRulesResponse.cs | 1 - src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsRequest.cs | 1 - src/OpenTelemetry.Sampler.AWS/GetSamplingTargetsResponse.cs | 1 - src/OpenTelemetry.Sampler.AWS/Matcher.cs | 2 -- .../OpenTelemetry.Sampler.AWS.csproj | 1 + src/OpenTelemetry.Sampler.AWS/RateLimiter.cs | 2 -- src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 4 ---- src/OpenTelemetry.Sampler.AWS/SamplingRule.cs | 2 -- src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs | 3 --- src/OpenTelemetry.Sampler.AWS/SystemClock.cs | 2 -- .../OpenTelemetry.SemanticConventions.csproj | 1 + src/Shared/IServerCertificateValidationEventSource.cs | 2 -- src/Shared/ServerCertificateValidationHandler.cs | 3 --- src/Shared/ServerCertificateValidationProvider.cs | 3 --- .../AWSEBSDetectorTests.cs | 1 - .../AWSEC2DetectorTests.cs | 1 - .../AWSECSDetectorTests.cs | 5 ----- .../AWSEKSDetectorTests.cs | 1 - .../Http/CertificateUploader.cs | 3 --- .../Http/NoopServerCertificateValidationEventSource.cs | 2 -- .../OpenTelemetry.Resources.AWS.Tests.csproj | 2 +- .../AzureResourceDetectorTests.cs | 2 -- .../OpenTelemetry.Resources.Azure.Tests.csproj | 1 + .../ContainerDetectorTests.cs | 3 --- .../OpenTelemetry.Resources.Container.Tests.csproj | 2 +- test/OpenTelemetry.Resources.Container.Tests/TempFile.cs | 4 ---- .../GcpResourceDetectorTests.cs | 1 - .../OpenTelemetry.Resources.Gcp.Tests.csproj | 1 + .../OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs | 3 --- .../OpenTelemetry.Resources.Host.Tests.csproj | 1 + .../OpenTelemetry.Resources.Process.Tests.csproj | 1 + .../ProcessDetectorTests.cs | 1 - .../OpenTelemetry.Resources.ProcessRuntime.Tests.csproj | 1 + .../ProcessRuntimeDetectorTests.cs | 1 - .../OpenTelemetry.Sampler.AWS.Tests.csproj | 1 + .../TestAWSXRayRemoteSampler.cs | 4 ---- .../TestAWSXRaySamplerClient.cs | 4 ---- test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs | 2 -- test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs | 1 - test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs | 4 ---- .../TestRateLimitingSampler.cs | 1 - test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs | 2 -- .../TestSamplingRuleApplier.cs | 2 -- test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs | 1 - 73 files changed, 21 insertions(+), 127 deletions(-) diff --git a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs index 4540259143..d956ffb281 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; #if NET6_0_OR_GREATER using System.Runtime.InteropServices; #endif diff --git a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs index e0c605b984..57e8652f1f 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using OpenTelemetry.Resources.AWS.Models; namespace OpenTelemetry.Resources.AWS; diff --git a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs index 054f82c1b8..495e039946 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs @@ -2,9 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK -using System; -using System.Collections.Generic; -using System.Net.Http; using System.Text.Json; using System.Text.RegularExpressions; diff --git a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index 597ccc86a1..6261a05b84 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -2,9 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 #if !NETFRAMEWORK -using System; -using System.Collections.Generic; -using System.Net.Http; using System.Text; using OpenTelemetry.Resources.AWS.Models; diff --git a/src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs b/src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs index b352ab5515..8f1731ac71 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSResourcesEventSource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj index 102b4946b0..7cb49b8b0b 100644 --- a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj +++ b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj @@ -6,6 +6,7 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. Resources.AWS- + enable $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable + enable diff --git a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs index 23e0ae6c8f..63c52255ac 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj index 7309e53286..bc6b4c2d32 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj +++ b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj @@ -4,6 +4,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 + enable diff --git a/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs b/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs index 487278851f..1174a24e81 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; -using System.IO; -using System.Linq; using Xunit; namespace OpenTelemetry.Resources.Container.Tests; diff --git a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj index 0a8ffcb375..7cc0cc1001 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj +++ b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj @@ -4,7 +4,7 @@ Unit test project for Container Detector for OpenTelemetry $(SupportedNetTargets) - enable + enable diff --git a/test/OpenTelemetry.Resources.Container.Tests/TempFile.cs b/test/OpenTelemetry.Resources.Container.Tests/TempFile.cs index b89b20ad87..8fd3c339bf 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/TempFile.cs +++ b/test/OpenTelemetry.Resources.Container.Tests/TempFile.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.IO; -using System.Threading; - namespace OpenTelemetry.Resources.Container.Tests; internal class TempFile : IDisposable diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs b/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs index 6369d7fda2..473714c969 100644 --- a/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Gcp.Tests/GcpResourceDetectorTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq; using Google.Api.Gax; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj index e1df281415..8a9164530b 100644 --- a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj +++ b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj @@ -5,6 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs index 04a8afdabe..ea4d30efb0 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Linq; using Xunit; namespace OpenTelemetry.Resources.Host.Tests; diff --git a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj index 6675698cc8..03a1eb106b 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj +++ b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj @@ -5,6 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj index b86c6f5cd6..b36aadfc5b 100644 --- a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj +++ b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj @@ -5,6 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs b/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs index 33a762b68b..7b4e6903b0 100644 --- a/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq; using Xunit; namespace OpenTelemetry.Resources.Process.Tests; diff --git a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj index 3fec9af968..2b6ec43868 100644 --- a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj +++ b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj @@ -5,6 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs index c70021b8ac..32ce2b4a1a 100644 --- a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs +++ b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq; using Xunit; namespace OpenTelemetry.Resources.ProcessRuntime.Tests; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 6892d723eb..0d1505baad 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -3,6 +3,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index 4734b966cc..3c629e79c6 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Threading; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using WireMock.RequestBuilders; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs index e688d30539..401a48a026 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; using WireMock.RequestBuilders; using WireMock.ResponseBuilders; using WireMock.Server; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index c012a1827c..7ddcb72daf 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Sampler.AWS.Tests; internal class TestClock : Clock diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs index 7ce3628e4f..d0224d6c9b 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using Xunit; namespace OpenTelemetry.Sampler.AWS.Tests; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs index fe598c733d..acb46916c0 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace OpenTelemetry.Sampler.AWS.Tests; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs index 1832280e0f..090cf882b5 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs index 541c5daae7..f0e6831989 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs index a28c8faa9d..283528e90f 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs index c46a4c7d45..7b53882827 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; From 222818f906cb2c04761b3c82786aa1dbf1f8d071 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:50:45 +0200 Subject: [PATCH 1160/1499] [release] Exporter.Geneva- stable release 1.9.0 updates (#1921) --- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index e652db5bd1..0e28e227b8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -10,7 +10,7 @@ net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 Exporter.Geneva- - 1.8.0 + 1.9.0 disable From 02a7ddf8bb0448adac4ec7ccc18234f169f8225e Mon Sep 17 00:00:00 2001 From: Ilia Brahinets Date: Mon, 24 Jun 2024 07:57:07 +0300 Subject: [PATCH 1161/1499] [Instrumentation.GrpcCore] Use shared semantic conventions (#1917) --- .../ClientTracingInterceptor.cs | 13 +------ .../ClientTracingInterceptorOptions.cs | 6 +-- ...nTelemetry.Instrumentation.GrpcCore.csproj | 1 + .../RpcScope.cs | 2 +- .../SemanticConventions.cs | 30 -------------- .../ServerTracingInterceptor.cs | 12 +----- .../ServerTracingInterceptorOptions.cs | 6 +-- .../GrpcCoreClientInterceptorTests.cs | 30 ++++++++------ .../GrpcCoreServerInterceptorTests.cs | 12 +++--- .../InterceptorActivityListener.cs | 7 ++-- .../TestActivityTags.cs | 39 +++++++++++++++++++ 11 files changed, 77 insertions(+), 81 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs create mode 100644 test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index bfb982dee1..80933e0e6a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System; -using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using Grpc.Core; @@ -311,16 +310,6 @@ public ClientRpcScope(ClientInterceptorContext context, Cli return; } - // This if block is for unit testing only. - IEnumerable> customTags = null; - if (options.ActivityIdentifierValue != default) - { - customTags = new List> - { - new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), - }; - } - // We want to start an activity but don't activate it. // After calling StartActivity, Activity.Current will be the new Activity. // This scope is created synchronously before the RPC invocation starts and so this new Activity will overwrite @@ -331,7 +320,7 @@ public ClientRpcScope(ClientInterceptorContext context, Cli this.FullServiceName, ActivityKind.Client, this.parentActivity == default ? default : this.parentActivity.Context, - tags: customTags); + tags: options.AdditionalTags); if (rpcActivity == null) { diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 73200193d2..72ff93a4fe 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; +using System.Collections.Generic; using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -27,7 +27,7 @@ public class ClientTracingInterceptorOptions public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; /// - /// Gets or sets a custom identifier used during unit testing. + /// Gets or sets additional activity tags used during unit testing. /// - internal Guid ActivityIdentifierValue { get; set; } + internal IReadOnlyDictionary AdditionalTags { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 7801f29915..099152bc14 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -22,5 +22,6 @@ + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index 889a761fa2..b09cdf7fd3 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -243,7 +243,7 @@ private void AddMessageEvent(string eventName, IMessage message, bool request) { new KeyValuePair("name", "message"), new KeyValuePair(SemanticConventions.AttributeMessageType, request ? "SENT" : "RECEIVED"), - new KeyValuePair(SemanticConventions.AttributeMessageID, request ? this.requestMessageCounter : this.responseMessageCounter), + new KeyValuePair(SemanticConventions.AttributeMessageId, request ? this.requestMessageCounter : this.responseMessageCounter), // TODO how to get the real compressed or uncompressed sizes new KeyValuePair(SemanticConventions.AttributeMessageCompressedSize, messageSize), diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs deleted file mode 100644 index b4463adc93..0000000000 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/SemanticConventions.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Instrumentation.GrpcCore; - -/// -/// Semantic conventions. -/// -internal static class SemanticConventions -{ -#pragma warning disable SA1600 // Elements should be documented - public const string AttributeRpcSystem = "rpc.system"; - public const string AttributeRpcService = "rpc.service"; - public const string AttributeRpcMethod = "rpc.method"; - public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; - public const string AttributeMessageType = "message.type"; - public const string AttributeMessageID = "message.id"; - public const string AttributeMessageCompressedSize = "message.compressed_size"; - public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; - - // Used for unit testing only. - internal const string AttributeActivityIdentifier = "activityidentifier"; - - // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md - internal const string AttributeExceptionEventName = "exception"; - internal const string AttributeExceptionType = "exception.type"; - internal const string AttributeExceptionMessage = "exception.message"; - internal const string AttributeExceptionStacktrace = "exception.stacktrace"; -#pragma warning restore SA1600 // Elements should be documented -} diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index a1e5d99ed5..682f2e2ef0 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -205,21 +205,11 @@ public ServerRpcScope(ServerCallContext context, ServerTracingInterceptorOptions } } - // This if block is for unit testing only. - IEnumerable> customTags = null; - if (options.ActivityIdentifierValue != default) - { - customTags = new List> - { - new KeyValuePair(SemanticConventions.AttributeActivityIdentifier, options.ActivityIdentifierValue), - }; - } - var activity = GrpcCoreInstrumentation.ActivitySource.StartActivity( this.FullServiceName, ActivityKind.Server, currentContext ?? default, - tags: customTags); + tags: options.AdditionalTags); this.SetActivity(activity); } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index 8d3af09835..d13b705104 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; +using System.Collections.Generic; using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Instrumentation.GrpcCore; @@ -27,7 +27,7 @@ public class ServerTracingInterceptorOptions public TextMapPropagator Propagator { get; internal set; } = Propagators.DefaultTextMapPropagator; /// - /// Gets or sets a custom identfier used during unit testing. + /// Gets or sets additional activity tags used during unit testing. /// - internal Guid ActivityIdentifierValue { get; set; } + internal IReadOnlyDictionary AdditionalTags { get; set; } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index e1ec20a73a..4aa61712bc 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -10,7 +10,9 @@ using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Tests; +using OpenTelemetry.Trace; using Xunit; +using StatusCode = Grpc.Core.StatusCode; namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; @@ -237,7 +239,8 @@ public async Task DownstreamInterceptorActivityAccess() return metadata; }); - var interceptorOptions = new ClientTracingInterceptorOptions { ActivityIdentifierValue = Guid.NewGuid() }; + var testTags = new TestActivityTags(); + var interceptorOptions = new ClientTracingInterceptorOptions { AdditionalTags = testTags.Tags }; callInvoker = callInvoker.Intercept(new ClientTracingInterceptor(interceptorOptions)); var client = new Foobar.FoobarClient(callInvoker); @@ -248,7 +251,7 @@ static void ValidateNewTagOnActivity(InterceptorActivityListener listener) } // Check the blocking async call - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + using (var activityListener = new InterceptorActivityListener(testTags)) { Assert.Equal(parentActivity, Activity.Current); var response = client.Unary(FoobarService.DefaultRequestMessage); @@ -259,7 +262,7 @@ static void ValidateNewTagOnActivity(InterceptorActivityListener listener) } // Check unary async - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + using (var activityListener = new InterceptorActivityListener(testTags)) { Assert.Equal(parentActivity, Activity.Current); using var call = client.UnaryAsync(FoobarService.DefaultRequestMessage); @@ -274,7 +277,7 @@ static void ValidateNewTagOnActivity(InterceptorActivityListener listener) } // Check a streaming async call - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + using (var activityListener = new InterceptorActivityListener(testTags)) { Assert.Equal(parentActivity, Activity.Current); using var call = client.DuplexStreaming(); @@ -343,7 +346,7 @@ static void ValidateCommonEventAttributes(ActivityEvent activityEvent) { Assert.NotNull(activityEvent.Tags); Assert.Contains(activityEvent.Tags, t => t.Key == "name" && (string)t.Value == "message"); - Assert.Contains(activityEvent.Tags, t => t.Key == SemanticConventions.AttributeMessageID && (int)t.Value == 1); + Assert.Contains(activityEvent.Tags, t => t.Key == SemanticConventions.AttributeMessageId && (int)t.Value == 1); } Assert.NotEqual(default, requestMessage); @@ -403,15 +406,16 @@ private static async Task TestHandlerSuccess(Func(async () => await clientRequestFunc(client, null).ConfigureAwait(false)); var activity = activityListener.Activity; @@ -515,8 +520,9 @@ private static async Task TestHandlerFailure( private void TestActivityIsCancelledWhenHandlerDisposed(Action clientRequestAction) { using var server = FoobarService.Start(); - var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid() }; - using var activityListener = new InterceptorActivityListener(clientInterceptorOptions.ActivityIdentifierValue); + var testTags = new TestActivityTags(); + var clientInterceptorOptions = new ClientTracingInterceptorOptions { Propagator = new TraceContextPropagator(), AdditionalTags = testTags.Tags }; + using var activityListener = new InterceptorActivityListener(testTags); var client = FoobarService.ConstructRpcClient(server.UriString, new ClientTracingInterceptor(clientInterceptorOptions)); clientRequestAction(client); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 4357262e9e..65b00b4383 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -104,11 +104,12 @@ public async Task DuplexStreamingServerHandlerFail() private static async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) { // starts the server with the server interceptor - var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, ActivityIdentifierValue = Guid.NewGuid() }; + var testTags = new TestActivityTags(); + var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), RecordMessageEvents = true, AdditionalTags = testTags.Tags }; using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); // No parent Activity, no context from header - using (var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue)) + using (var activityListener = new InterceptorActivityListener(testTags)) { var client = FoobarService.ConstructRpcClient(server.UriString); await clientRequestFunc(client, additionalMetadata); @@ -119,7 +120,7 @@ private static async Task TestHandlerSuccess(Func clientRequestFunc, Metadata additionalMetadata = null) { // starts the server with the server interceptor - var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), ActivityIdentifierValue = Guid.NewGuid(), RecordException = true }; + var testTags = new TestActivityTags(); + var interceptorOptions = new ServerTracingInterceptorOptions { Propagator = new TraceContextPropagator(), AdditionalTags = testTags.Tags, RecordException = true }; using var server = FoobarService.Start(new ServerTracingInterceptor(interceptorOptions)); - using var activityListener = new InterceptorActivityListener(interceptorOptions.ActivityIdentifierValue); + using var activityListener = new InterceptorActivityListener(testTags); var client = FoobarService.ConstructRpcClient( server.UriString, additionalMetadata: new List diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index 0c43a7e003..e736367c75 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics; -using System.Linq; namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; @@ -20,15 +19,15 @@ internal sealed class InterceptorActivityListener : IDisposable /// /// Initializes a new instance of the class. /// - /// The activity identifier. - public InterceptorActivityListener(Guid activityIdentifier) + /// The test activity tags. + public InterceptorActivityListener(TestActivityTags testTags) { this.activityListener = new ActivityListener { ShouldListenTo = source => source.Name == GrpcCoreInstrumentation.ActivitySourceName, ActivityStarted = activity => { - if (activity.TagObjects.Any(t => t.Key == SemanticConventions.AttributeActivityIdentifier && (Guid)t.Value == activityIdentifier)) + if (testTags.HasTestTags(activity)) { this.Activity = activity; } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs new file mode 100644 index 0000000000..6994c4bdd8 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; + +internal class TestActivityTags +{ + public const string ActivityIdentifierTag = "activityidentifier"; + + public TestActivityTags() + { + this.Tags = new Dictionary() + { + [ActivityIdentifierTag] = Guid.NewGuid(), + }; + } + + internal IReadOnlyDictionary Tags { get; } + + /// + /// Checks whether the activity has test tags. + /// + /// The activity. + /// Returns true if the activty has test tags, false otherwise. + internal bool HasTestTags(Activity activity) + { + Guard.ThrowIfNull(activity); + + return this.Tags + .Select(tag => activity.TagObjects.Any(t => t.Key == tag.Key && t.Value == tag.Value)) + .All(v => v); + } +} From 36f7289055f587c539e302d991a095081b43a1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 24 Jun 2024 18:27:49 +0200 Subject: [PATCH 1162/1499] [repo] ImplicitUsings - part 2 (#1923) --- src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs | 1 - .../EventNameExportMode.cs | 2 -- .../GenevaExporterHelperExtensions.cs | 1 - .../GenevaExporterOptions.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs | 1 - .../GenevaLoggingExtensions.cs | 1 - .../GenevaTraceExporter.cs | 1 - .../Internal/ConnectionStringBuilder.cs | 2 -- .../Internal/ExporterEventSource.cs | 1 - .../Internal/ReentrantExportProcessor.cs | 1 - .../Internal/TableNameSerializer.cs | 2 -- .../Metrics/GenevaMetricExporter.cs | 1 - .../Metrics/GenevaMetricExporterExtensions.cs | 1 - .../Metrics/GenevaMetricExporterOptions.cs | 2 -- .../Metrics/MetricSerializer.cs | 1 - .../Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs | 2 -- .../Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs | 2 -- .../Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs | 1 - .../Metrics/OtlpProtobuf/TimestampHelpers.cs | 2 -- .../Metrics/TlvMetricExporter.cs | 2 -- .../Metrics/Transport/IMetricDataTransport.cs | 2 -- .../Metrics/Transport/MetricEtwDataTransport.cs | 1 - .../Metrics/Transport/MetricUnixDataTransport.cs | 2 +- .../MsgPackExporter/MessagePackSerializer.cs | 2 -- .../MsgPackExporter/MsgPackExporter.cs | 2 -- .../MsgPackExporter/MsgPackLogExporter.cs | 3 --- .../MsgPackExporter/MsgPackTraceExporter.cs | 3 --- .../MsgPackExporter/Transport/EtwDataTransport.cs | 1 - .../Transport/UnixDomainSocketDataTransport.cs | 1 - .../Transport/UnixDomainSocketEndPoint.cs | 1 - .../OpenTelemetry.Exporter.Geneva.csproj | 1 + .../TLDExporter/JsonSerializer.cs | 3 --- .../TLDExporter/TldExporter.cs | 2 -- .../TLDExporter/TldLogExporter.cs | 3 --- .../TLDExporter/TldTraceExporter.cs | 3 --- .../TLDExporter/UncheckedASCIIEncoding.cs | 1 - .../InfluxDBExporterExtensions.cs | 1 - .../InfluxDBMetricsExporter.cs | 1 - .../InfluxDBMetricsExporterOptions.cs | 1 - .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 + .../PointDataExtensions.cs | 1 - .../Implementation/InstanaExporterEventSource.cs | 1 - .../Implementation/InstanaSpan.cs | 2 -- .../Implementation/InstanaSpanFactory.cs | 2 -- .../Implementation/InstanaSpanSerializer.cs | 4 ---- .../Implementation/Processors/ActivityProcessorBase.cs | 2 -- .../Processors/DefaultActivityProcessor.cs | 2 -- .../Processors/ErrorActivityProcessor.cs | 1 - .../Processors/EventsActivityProcessor.cs | 2 -- .../Implementation/Processors/IActivityProcessor.cs | 2 -- .../Implementation/Processors/TagsActivityProcessor.cs | 2 -- .../Implementation/SpanSender.cs | 1 - .../Implementation/Transport.cs | 5 ++--- src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs | 3 --- .../InstanaExporterHelper.cs | 1 - .../OpenTelemetry.Exporter.Instana.csproj | 1 + .../TracerProviderBuilderExtensions.cs | 1 - .../OpenTelemetry.Exporter.OneCollector.csproj | 2 +- .../Implementation/ActivityExtensions.cs | 2 -- .../Implementation/ExporterStackdriverEventSource.cs | 1 - .../Implementation/GoogleCloudResourceUtils.cs | 2 -- .../Implementation/ResourceExtensions.cs | 1 - .../Implementation/StackdriverStatsConfiguration.cs | 1 - .../OpenTelemetry.Exporter.Stackdriver.csproj | 1 + .../StackdriverTraceExporter.cs | 2 -- .../Utils/CommonUtils.cs | 1 - src/OpenTelemetry.Extensions.AWS/AWSXRayEventSource.cs | 1 - src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs | 2 -- .../AWSXRayIdGenerator.net6.cs | 1 - .../OpenTelemetry.Extensions.AWS.csproj | 1 + .../Trace/AWSXRayPropagator.cs | 3 --- .../TracerProviderBuilderExtensions.cs | 2 +- .../Internal/TraceEnrichmentActions.cs | 4 ---- .../Internal/TraceEnrichmentProcessor.cs | 2 -- .../OpenTelemetry.Extensions.Enrichment.csproj | 1 + .../TraceEnrichmentProviderBuilderExtensions.cs | 1 - .../TraceEnrichmentServiceCollectionExtensions.cs | 2 -- src/OpenTelemetry.Extensions/AssemblyInfo.cs | 2 -- .../Internal/ActivityEventAttachingLogProcessor.cs | 1 - .../Internal/DefaultLogStateConverter.cs | 1 - .../Internal/OpenTelemetryExtensionsEventSource.cs | 1 - .../Logs/LogToActivityEventConversionOptions.cs | 2 -- .../Logs/OpenTelemetryLoggingExtensions.cs | 1 - .../OpenTelemetry.Extensions.csproj | 1 + .../Trace/AutoFlushActivityProcessor.cs | 2 -- .../TracerProviderBuilderExtensions.cs | 2 -- ...Telemetry.Instrumentation.StackExchangeRedis.csproj | 2 +- .../AssemblyInfo.cs | 1 - ...OpenTelemetry.PersistentStorage.Abstractions.csproj | 1 + .../PersistentBlob.cs | 1 - .../PersistentBlobProvider.cs | 3 --- .../PersistentStorageAbstractionsEventSource.cs | 1 - .../DirectorySizeTracker.cs | 4 ---- .../FileBlob.cs | 2 -- .../FileBlobProvider.cs | 10 +++------- .../OpenTelemetry.PersistentStorage.FileSystem.csproj | 1 + .../PersistentStorageEventSource.cs | 1 - .../PersistentStorageHelper.cs | 3 --- .../Exporter/LogExporterBenchmarks.cs | 1 - .../Exporter/MetricExporterBenchmarks.cs | 3 --- .../Exporter/SerializationBenchmarks.cs | 1 - .../Exporter/TLDLogExporterBenchmarks.cs | 1 - .../Exporter/TLDTraceExporterBenchmarks.cs | 1 - .../Exporter/TraceExporterBenchmarks.cs | 1 - .../OpenTelemetry.Exporter.Geneva.Benchmarks.csproj | 1 + .../DummyServer.cs | 3 --- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 1 + test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs | 5 ----- .../ConnectionStringBuilderTests.cs | 1 - .../GenevaLogExporterTests.cs | 5 ----- .../GenevaMetricExporterOptionsTests.cs | 2 -- .../GenevaMetricExporterTests.cs | 5 ----- .../GenevaTraceExporterTests.cs | 5 ----- .../JsonSerializerTests.cs | 2 -- .../LogSerializationTests.cs | 4 ---- .../MessagePackSerializerTests.cs | 2 -- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 + .../OtlpProtobufMetricExporterTests.cs | 3 --- .../TableNameSerializerTests.cs | 1 - .../UnixDomainSocketDataTransportTests.cs | 2 -- .../UnixDomainSocketEndPointTests.cs | 1 - .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 3 ++- .../InstanaSpanSerializerTests.cs | 3 --- .../InstanaSpanTest.cs | 2 -- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 1 + .../Processors/DefaultActivityProcessorTests.cs | 1 - .../Processors/ErrorActivityProcessorTests.cs | 1 - .../Processors/EventsActivityProcessorTests.cs | 3 --- .../Processors/TagsActivityProcessorTests.cs | 1 - .../TestActivityProcessor.cs | 2 -- .../TestInstanaExporterHelper.cs | 1 - .../TestSpanSender.cs | 1 - ...enTelemetry.Exporter.OneCollector.Benchmarks.csproj | 2 +- .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 2 +- .../ActivityExtensionsTest.cs | 2 -- .../StackdriverStatsConfigurationTests.cs | 1 - .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 1 + .../ResourceExtensionsTests.cs | 1 - .../StackdriverExporterTests.cs | 3 --- .../TestActivityProcessor.cs | 1 - .../TestTraceServiceClient.cs | 1 - .../AWSXRayIdGeneratorTests.cs | 1 - .../OpenTelemetry.Extensions.AWS.Tests.csproj | 1 + .../Trace/AWSXRayPropagatorTests.cs | 2 -- .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 1 + ...OpenTelemetryEnrichmentProviderBuilderExtensions.cs | 2 -- ...emetryEnrichmentServiceCollectionExtensionsTests.cs | 3 --- .../ActivityEventAttachingLogProcessorTests.cs | 3 --- .../OpenTelemetry.Extensions.Tests.csproj | 1 + .../Trace/AutoFlushActivityProcessorTests.cs | 1 - ...lemetry.PersistentStorage.Abstractions.Tests.csproj | 1 + .../DirectorySizeTrackerTests.cs | 1 - .../FileBlobProviderTests.cs | 3 --- .../FileBlobTests.cs | 3 --- ...Telemetry.PersistentStorage.FileSystem.Tests.csproj | 1 + test/Shared/TestActivityProcessor.cs | 2 ++ 156 files changed, 34 insertions(+), 250 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs index 9c892bb358..207e66dd83 100644 --- a/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Geneva/AssemblyInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] diff --git a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs index 12f768b1c4..3ef68a4892 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Exporter.Geneva; [Flags] diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 74b1a0113f..0fe7872da5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 1f9bfa0aaf..c9e87ef33c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 723817929e..1e3ef76dbf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.TldExporter; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 6d950f2180..4507997ce0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index d79a064bc5..309cb7b87c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.TldExporter; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index b007e5f4ab..9bf497c319 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index e96b0f9b4b..9da11fafbb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index b9575f2a8f..44e1686c11 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Linq.Expressions; using System.Reflection; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index c23ff0ee9f..89ad5f8195 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index b2fff46bf6..b596e592ab 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Reflection; using System.Text.RegularExpressions; using OpenTelemetry.Exporter.Geneva.Metrics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 545adff15b..f6202edf78 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index c2df90cc37..36e13d2ef3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs index e0355bae34..a5e38553ea 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index 54d3b14cdb..b5836f3d99 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 9f1347bc3f..40019f14ff 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs index f9eb43ddc1..74f06185fb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs index 92f8cc395e..68c23b28a9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 336115979c..8d05817fd5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs index 8b2be9ecee..1c40c4303d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Exporter.Geneva; internal interface IMetricDataTransport : IDisposable diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index e3a0065df3..1c7fa8770e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs index 863a6f5542..799e8bf7d2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs @@ -39,6 +39,6 @@ public void Dispose() public void SendOtlpProtobufEvent(byte[] body, int size) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index 62424f5693..21ed99dd71 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -1,11 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NET6_0_OR_GREATER using System.Buffers.Binary; #endif -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs index 581a07dcd3..7a6ed20f52 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs @@ -1,11 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NET8_0_OR_GREATER using System.Collections.Frozen; #endif -using System.Collections.Generic; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 2cbb03dcd5..0a143cd39a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -1,15 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NET8_0_OR_GREATER using System.Collections.Frozen; #endif -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Threading; using Microsoft.Extensions.Logging; using OpenTelemetry.Internal; using OpenTelemetry.Logs; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index c205c8a0c2..bddd2ba478 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -1,15 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NET8_0_OR_GREATER using System.Collections.Frozen; #endif -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; -using System.Threading; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index b17403699a..199818de29 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs index 024380127c..c7424a1023 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Net; using System.Net.Sockets; diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs index ef00b48764..7178ea45fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Net; using System.Net.Sockets; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 0e28e227b8..11c4d04c9e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -12,6 +12,7 @@ Exporter.Geneva- 1.9.0 disable + enable diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index ca5f4e6d96..06aaa294d8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -1,12 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; -using System.Threading; namespace OpenTelemetry.Exporter.Geneva.TldExporter; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs index 4891c5266e..a7f6f3ba33 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 318cb02092..2eeab5c30d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -1,12 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; -using System.Threading; using Microsoft.Extensions.Logging; using OpenTelemetry.Exporter.Geneva.External; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index ce63e57fab..6294d96056 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -1,12 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Text; -using System.Threading; using OpenTelemetry.Exporter.Geneva.External; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs index c7fdbb9967..c36b6c1059 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs index dd461973be..6628e761bf 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using InfluxDB.Client; using OpenTelemetry.Exporter.InfluxDB; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs index 0b2e827783..651d360162 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using InfluxDB.Client; using InfluxDB.Client.Writes; using OpenTelemetry.Metrics; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs index 35448f01b3..f79c5aff89 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporterOptions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.InfluxDB; diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index f1c7da1493..ca53d70296 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -7,6 +7,7 @@ $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) Exporter.InfluxDB- + enable $(NetMinimumSupportedVersion) $(TargetFrameworks);net48;net472;net471;net47;net462 - true + enable + enable diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index bb56142871..1b4bc7d42a 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using OpenTelemetry.Exporter.Instana.Implementation; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index 3e426a591a..aa2a0df58d 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 689b764d11..09fb327a2c 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -5,6 +5,7 @@ $(TargetFrameworks);net462 true disable + enable diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs index 6eaf8dca56..85ae5c3577 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Threading.Tasks; using OpenTelemetry.Exporter.Instana.Implementation; using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs index a27a7f1c52..18c37f236a 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Threading.Tasks; using OpenTelemetry.Exporter.Instana.Implementation; using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index e9bfc68a48..7ed21412ca 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -3,10 +3,7 @@ #nullable enable -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Threading.Tasks; using OpenTelemetry.Exporter.Instana.Implementation; using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs index e1acfefb61..b70bc79bf6 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Threading.Tasks; using OpenTelemetry.Exporter.Instana.Implementation; using OpenTelemetry.Exporter.Instana.Implementation.Processors; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs index da660e8c08..40f7ab44b4 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; -using System.Threading.Tasks; using OpenTelemetry.Exporter.Instana.Implementation; using OpenTelemetry.Exporter.Instana.Implementation.Processors; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs index e6fb2fb69b..bf48310c1f 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; using OpenTelemetry.Resources; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs index 054dea7235..33cd7f898e 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Exporter.Instana.Implementation; namespace OpenTelemetry.Exporter.Instana.Tests; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index 81feba070e..d29a103e22 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -6,7 +6,7 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 - true + enable diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 7cf35b4e49..dc5b007108 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -5,7 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 - true + enable diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs index 0efd380492..5e1b9a5f0b 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using OpenTelemetry.Exporter.Stackdriver.Implementation; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs index 32d7f56352..caaea64bc7 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/Implementation/StackdriverStatsConfigurationTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Exporter.Stackdriver.Implementation; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index ab94de47f5..0af211cf16 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -4,6 +4,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 + enable diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs index 651c69a009..8072d0aca7 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ResourceExtensionsTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using Google.Cloud.Trace.V2; using OpenTelemetry.Exporter.Stackdriver.Implementation; using OpenTelemetry.Resources; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 7c6a921d2c..854fb7bd0d 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using OpenTelemetry.Exporter.Stackdriver.Implementation; using OpenTelemetry.Resources; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index 603aea8406..eab6437c06 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; namespace OpenTelemetry.Exporter.Stackdriver.Tests; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs index c7122424ab..dd1aceb4a7 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using Google.Api.Gax.Grpc; using Google.Cloud.Trace.V2; using Grpc.Core; diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs index bb4ec1bcd5..810a2d6b77 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 68f248e657..5faa96d9c3 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -3,6 +3,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs index b73736ab3b..c654ec2b9e 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Extensions.AWS.Trace; diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index c7400ad0a6..0175c67b27 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -5,6 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + enable diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs index 804266db42..86976d8f5d 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentProviderBuilderExtensions.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs index dbad6bf253..19448cb7dc 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetryEnrichmentServiceCollectionExtensionsTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index 54874eb090..c2a582701e 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; using Xunit; diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 704dda8498..9e145180e1 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -5,6 +5,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 + enable diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs index 7009420a97..7f96a8f3fa 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/AutoFlushActivityProcessorTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using System.Runtime.CompilerServices; using OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj index 10d560b8e9..60b7fcc94f 100644 --- a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj @@ -4,6 +4,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 + enable diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs index 77547a8a30..65fe724208 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.IO; using Xunit; namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index cc202def9f..e35a2a4b90 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.IO; using System.Text; -using System.Threading; using Xunit; namespace OpenTelemetry.PersistentStorage.FileSystem.Tests; diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs index aee14a6c67..cde187fcc3 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.IO; using System.Text; -using System.Threading; using OpenTelemetry.PersistentStorage.Abstractions; using Xunit; diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index d33c3e28e8..6e35fbd5a9 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -4,6 +4,7 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 + enable diff --git a/test/Shared/TestActivityProcessor.cs b/test/Shared/TestActivityProcessor.cs index f4ab71afa4..378c25b58c 100644 --- a/test/Shared/TestActivityProcessor.cs +++ b/test/Shared/TestActivityProcessor.cs @@ -3,8 +3,10 @@ #nullable enable +#pragma warning disable IDE0005 // Using directive is unnecessary. using System; using System.Diagnostics; +#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; From f20e84dddbe2be565b3659211bbdae84ffe69c9f Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:45:56 +0000 Subject: [PATCH 1163/1499] [repo] Align PR template with main repo (#1925) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/PULL_REQUEST_TEMPLATE.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e5ef779df5..66b6162ea1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,11 +1,13 @@ -Fixes #. +Fixes # +Design discussion issue # ## Changes Please provide a brief description of the changes here. -For significant contributions please make sure you have completed the following items: +## Merge requirement checklist -* [ ] Appropriate `CHANGELOG.md` updated for non-trivial changes -* [ ] Design discussion issue # -* [ ] Changes in public API reviewed +* [ ] [CONTRIBUTING](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/CONTRIBUTING.md) guidelines followed (license requirements, nullable enabled, static analysis, etc.) +* [ ] Unit tests added/updated +* [ ] Appropriate `CHANGELOG.md` files updated for non-trivial changes +* [ ] Changes in public API reviewed (if applicable) From ea0611674c415a44810771b2fc58d298c31dc60e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 24 Jun 2024 23:21:09 +0200 Subject: [PATCH 1164/1499] [release] coreunstable-1.9.0-beta.2 release updates (#1926) --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index 7a6988f37f..9099eb0bff 100644 --- a/build/Common.props +++ b/build/Common.props @@ -38,7 +38,7 @@ [4.2.2,5.0) [3.11.0-beta1.23525.2] [8.0.0,9.0) - [1.9.0-beta.1] + [1.9.0-beta.2] [1.9.0,2.0) [1.9.0-rc.1] [2.1.58,3.0) From e3a90d7ac5b0cb50ebe9838c87a6e6fe06d4dd40 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Tue, 25 Jun 2024 04:48:51 +0000 Subject: [PATCH 1165/1499] [repo] Simplify preprocessor directives (#1924) --- .../Internal/ConnectionStringBuilder.cs | 2 +- .../Transport/MetricEtwDataTransport.cs | 6 +++--- .../MsgPackExporter/MessagePackSerializer.cs | 20 +++++++++---------- .../Transport/EtwDataTransport.cs | 4 ++-- .../TLDExporter/JsonSerializer.cs | 10 +++++----- .../Internal/ConnectionStringParser.cs | 2 +- .../Internal/EventNameManager.cs | 2 +- .../ExtensionFieldInformationManager.cs | 4 ++-- .../OneCollectorExporterEventSource.cs | 8 ++++---- .../CommonSchemaJsonSerializationHelper.cs | 4 ++-- .../CommonSchemaJsonSerializationState.cs | 8 ++++---- .../Transports/HttpJsonPostTransport.cs | 2 +- .../Internal/Transports/IHttpClient.cs | 2 +- .../OneCollectorExporterOptions.cs | 2 +- .../AWSXRayIdGenerator.cs | 2 +- .../TracerProviderBuilderExtensions.cs | 2 +- ...raceEnrichmentProviderBuilderExtensions.cs | 4 ++-- ...ceEnrichmentServiceCollectionExtensions.cs | 4 ++-- .../TracerProviderBuilderExtensions.cs | 2 +- .../AWSTracingPipelineHandler.cs | 2 +- .../AspNetCoreInstrumentationEventSource.cs | 6 +++--- .../Implementation/HttpInListener.cs | 2 +- .../Implementation/HttpInMetricsListener.cs | 11 +++++----- .../GrpcClientDiagnosticListener.cs | 4 ++-- .../HttpHandlerDiagnosticListener.cs | 10 +++++----- .../HttpHandlerMetricsDiagnosticListener.cs | 16 +++++++-------- .../RuntimeInstrumentationOptions.cs | 12 +++++------ .../RuntimeMetrics.cs | 6 +++--- .../SqlClientDiagnosticListener.cs | 4 ++-- .../SqlClientInstrumentation.cs | 6 +++--- .../TracerProviderBuilderExtensions.cs | 8 ++++---- .../RedisProfilerEntryToActivityConverter.cs | 12 +++++------ .../AWSEBSDetector.cs | 8 ++++---- .../AWSEC2Detector.cs | 2 +- .../AWSEKSDetector.cs | 2 +- .../ResourceDetectorUtils.cs | 4 ++-- .../SourceGenerationContext.cs | 2 +- .../AppServiceResourceDetector.cs | 2 +- .../AzureVmMetaDataRequestor.cs | 2 +- .../SourceGenerationContext.cs | 2 +- .../ProcessDetector.cs | 2 +- .../AWSXRaySamplerClient.cs | 6 +++--- .../SourceGenerationContext.cs | 2 +- src/Shared/AssemblyVersionExtensions.cs | 2 +- src/Shared/Guard.cs | 4 ++-- .../Options/DelegatingOptionsFactory.cs | 4 ++-- ...tionsFactoryServiceCollectionExtensions.cs | 8 ++++---- src/Shared/Options/SingletonOptionsManager.cs | 4 ++-- src/Shared/PropertyFetcher.AOT.cs | 20 +++++++++---------- ...ommonSchemaJsonSerializationHelperTests.cs | 4 ++-- .../GrpcTestHelpers/ClientTestHelpers.cs | 2 +- .../GrpcTests.client.cs | 2 +- .../GrpcTests.server.cs | 4 ++-- .../RuntimeInstrumentationOptionsTests.cs | 12 +++++------ .../RuntimeMetricsTests.cs | 6 +++--- test/Shared/TestHttpServer.cs | 4 ++-- 56 files changed, 149 insertions(+), 150 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 9bf497c319..48c76da6c4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -33,7 +33,7 @@ public ConnectionStringBuilder(string connectionString) continue; } -#if NET6_0_OR_GREATER +#if NET var index = token.IndexOf(EqualSign, StringComparison.Ordinal); #else var index = token.IndexOf(EqualSign); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 1c7fa8770e..121cb88d1f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using System.Diagnostics.Tracing; @@ -26,7 +26,7 @@ private MetricEtwDataTransport() } [NonEvent] -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] #endif public unsafe void Send(MetricEventType eventType, byte[] data, int size) @@ -41,7 +41,7 @@ public unsafe void Send(MetricEventType eventType, byte[] data, int size) } [NonEvent] -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] #endif public unsafe void SendOtlpProtobufEvent(byte[] data, int size) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index 21ed99dd71..ec3e8050b7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Buffers.Binary; #endif using System.Globalization; @@ -50,7 +50,7 @@ internal static class MessagePackSerializer private const int LIMIT_MAX_FIX_ARRAY_LENGTH = 15; private const int STRING_SIZE_LIMIT_CHAR_COUNT = (1 << 14) - 1; // 16 * 1024 - 1 = 16383 -#if NET6_0_OR_GREATER +#if NET private const int MAX_STACK_ALLOC_SIZE_IN_BYTES = 256; #endif @@ -187,7 +187,7 @@ public static int SerializeUInt64(byte[] buffer, int cursor, ulong value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteInt16(byte[] buffer, int cursor, short value) { -#if NET6_0_OR_GREATER +#if NET BinaryPrimitives.WriteInt16BigEndian(buffer.AsSpan(cursor), value); return cursor + sizeof(short); #else @@ -204,7 +204,7 @@ public static int WriteInt16(byte[] buffer, int cursor, short value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteInt32(byte[] buffer, int cursor, int value) { -#if NET6_0_OR_GREATER +#if NET BinaryPrimitives.WriteInt32BigEndian(buffer.AsSpan(cursor), value); return cursor + sizeof(int); #else @@ -223,7 +223,7 @@ public static int WriteInt32(byte[] buffer, int cursor, int value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteInt64(byte[] buffer, int cursor, long value) { -#if NET6_0_OR_GREATER +#if NET BinaryPrimitives.WriteInt64BigEndian(buffer.AsSpan(cursor), value); return cursor + sizeof(long); #else @@ -246,7 +246,7 @@ public static int WriteInt64(byte[] buffer, int cursor, long value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteUInt16(byte[] buffer, int cursor, ushort value) { -#if NET6_0_OR_GREATER +#if NET BinaryPrimitives.WriteUInt16BigEndian(buffer.AsSpan(cursor), value); return cursor + sizeof(ushort); #else @@ -263,7 +263,7 @@ public static int WriteUInt16(byte[] buffer, int cursor, ushort value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteUInt32(byte[] buffer, int cursor, uint value) { -#if NET6_0_OR_GREATER +#if NET BinaryPrimitives.WriteUInt32BigEndian(buffer.AsSpan(cursor), value); return cursor + sizeof(uint); #else @@ -282,7 +282,7 @@ public static int WriteUInt32(byte[] buffer, int cursor, uint value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteUInt64(byte[] buffer, int cursor, ulong value) { -#if NET6_0_OR_GREATER +#if NET BinaryPrimitives.WriteUInt64BigEndian(buffer.AsSpan(cursor), value); return cursor + sizeof(ulong); #else @@ -410,7 +410,7 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string value) return cursor; } -#if NET6_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeUnicodeString(byte[] buffer, int cursor, ReadOnlySpan value) @@ -636,7 +636,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) case DateTimeOffset v: return SerializeUtcDateTime(buffer, cursor, v.UtcDateTime); -#if NET6_0_OR_GREATER +#if NET case ISpanFormattable v: Span tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; if (v.TryFormat(tmp, out int charsWritten, string.Empty, CultureInfo.InvariantCulture)) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index 199818de29..d35c140d23 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using System.Diagnostics.Tracing; @@ -26,7 +26,7 @@ public void InformationalEvent() } [NonEvent] -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] #endif public unsafe void SendEvent(int eventId, byte[] data, int size) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index 06aaa294d8..c106c55f12 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -18,7 +18,7 @@ internal static class JsonSerializer private const byte ASCII_CARRIAGE_RETURN = 0x0D; private const byte ASCII_HORIZONTAL_TAB = 0x09; -#if NET6_0_OR_GREATER +#if NET private const int MAX_STACK_ALLOC_SIZE_IN_BYTES = 256; #endif @@ -88,7 +88,7 @@ public static int SerializeString(byte[] buffer, int cursor, string value) return cursor; } -#if NET6_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeString(byte[] buffer, int cursor, ReadOnlySpan value) { @@ -250,7 +250,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) { case bool v: return WriteString(buffer, cursor, v ? "true" : "false"); -#if NET6_0_OR_GREATER +#if NET case byte: case sbyte: case short: @@ -317,7 +317,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) case object[] v: return SerializeArray(buffer, cursor, v); -#if NET6_0_OR_GREATER +#if NET case ISpanFormattable v: tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; if (v.TryFormat(tmp, out charsWritten, default, CultureInfo.InvariantCulture)) @@ -410,7 +410,7 @@ private static int WriteString(byte[] buffer, int cursor, string value) return cursor; } -#if NET6_0_OR_GREATER +#if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int WriteString(byte[] buffer, int cursor, ReadOnlySpan value) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs index da9c35457c..40e30d61db 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs @@ -21,7 +21,7 @@ public ConnectionStringParser(string connectionString) continue; } -#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER var index = token.IndexOf(EqualSign, StringComparison.Ordinal); #else var index = token.IndexOf(EqualSign); diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs index 0b56f8f8d4..25ee9a0701 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs @@ -45,7 +45,7 @@ public EventNameManager(string defaultEventNamespace, string defaultEventName) this.defaultEventFullName = BuildEventFullName(defaultEventNamespace, defaultEventName)!; -#if NET6_0_OR_GREATER +#if NET Debug.Assert(this.defaultEventFullName != null, "this.defaultFullyQualifiedEventName was null"); #endif } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs index 97a3735b0c..08520bd082 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ExtensionFieldInformationManager.cs @@ -3,7 +3,7 @@ using System.Collections; using System.Diagnostics; -#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER +#if NETSTANDARD2_1_OR_GREATER || NET using System.Diagnostics.CodeAnalysis; #endif using System.Text.Json; @@ -21,7 +21,7 @@ internal sealed class ExtensionFieldInformationManager public bool TryResolveExtensionFieldInformation( string fullFieldName, -#if NETSTANDARD2_1_OR_GREATER || NET6_0_OR_GREATER +#if NETSTANDARD2_1_OR_GREATER || NET [NotNullWhen(true)] #endif out ExtensionFieldInformation? resolvedFieldInformation) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index 9543edb200..389d317ac4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using System.Diagnostics.Tracing; @@ -79,7 +79,7 @@ public void ExportExceptionThrown(string itemType, string exception) } [Event(2, Message = "Sent '{0}' batch of {1} item(s) to '{2}' transport.", Level = EventLevel.Informational)] -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] #endif public void TransportDataSent(string itemType, int numberOfRecords, string transportDescription) @@ -88,7 +88,7 @@ public void TransportDataSent(string itemType, int numberOfRecords, string trans } [Event(3, Message = "Wrote '{0}' batch of {1} item(s) to '{2}' sink.", Level = EventLevel.Informational)] -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] #endif public void SinkDataWritten(string itemType, int numberOfRecords, string sinkDescription) @@ -109,7 +109,7 @@ public void TransportExceptionThrown(string transportType, string exception) } [Event(6, Message = "Error response received by '{0}' transport. StatusCode: {1}, ErrorMessage: '{2}', ErrorDetails: '{3}'", Level = EventLevel.Error)] -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] #endif public void HttpTransportErrorResponseReceived(string transportType, int statusCode, string errorMessage, string errorDetails) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index 982cab47b3..ca30a223ba 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Exporter.OneCollector; internal static class CommonSchemaJsonSerializationHelper { -#if NET6_0_OR_GREATER +#if NET public const int MaximumStackAllocSizeInBytes = 256; #endif @@ -209,7 +209,7 @@ private static void SerializeMapValueToJson(IEnumerable destination = stackalloc char[MaximumStackAllocSizeInBytes / 2]; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs index b7c69c8db6..cfcfc7b496 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if NET6_0_OR_GREATER +#if NET using System.Runtime.InteropServices; #endif using System.Text.Json; @@ -46,7 +46,7 @@ public void AddExtensionAttribute(KeyValuePair attribute) Debug.Assert(fieldInformation?.FieldName != null, "fieldInformation.FieldName was null"); Debug.Assert(fieldInformation?.EncodedFieldName.EncodedUtf8Bytes.Length > 0, "fieldInformation.EncodedFieldName was empty"); -#if NET6_0_OR_GREATER +#if NET ref var lookupIndex = ref CollectionsMarshal.GetValueRefOrAddDefault(this.keys, fieldInformation.ExtensionName, out var existed); if (!existed) { @@ -92,7 +92,7 @@ public void SerializeExtensionPropertiesToJson(bool writeExtensionObjectEnvelope writer.WriteStartObject(CommonSchemaJsonSerializationHelper.ExtensionsProperty); } -#if NET6_0_OR_GREATER +#if NET var allValues = CollectionsMarshal.AsSpan(this.allValues); #else var allValues = this.allValues; @@ -108,7 +108,7 @@ public void SerializeExtensionPropertiesToJson(bool writeExtensionObjectEnvelope { unsafe { -#if NET6_0_OR_GREATER +#if NET ref var attribute = ref allValues[keyLookup.ValueIndicies[i]]; #else var attribute = allValues[keyLookup.ValueIndicies[i]]; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index 6585c0916a..40cb7f61b4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -276,7 +276,7 @@ protected override bool TryComputeLength(out long length) return true; } -#if NET6_0_OR_GREATER +#if NET protected override void SerializeToStream(Stream stream, TransportContext? context, CancellationToken cancellationToken) { this.stream.CopyTo(stream); diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs index 0bb175b248..f53f8474d5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs @@ -23,7 +23,7 @@ public HttpClientWrapper(HttpClient httpClient) public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { -#if NET6_0_OR_GREATER +#if NET return this.httpClient.Send(request, CancellationToken.None); #else return this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs index 2150a1cc9d..14300f830d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterOptions.cs @@ -51,7 +51,7 @@ internal virtual void Validate() throw new OneCollectorExporterValidationException("Instrumentation key was not specified on connection string."); } -#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER var positionOfFirstDash = this.InstrumentationKey.IndexOf('-', StringComparison.OrdinalIgnoreCase); #else var positionOfFirstDash = this.InstrumentationKey!.IndexOf('-'); diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs index 78c40219be..f55193111e 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NET6_0_OR_GREATER +#if !NET using System.Diagnostics; using System.Globalization; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs index a232660257..4ce36c65eb 100644 --- a/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.AWS/TracerProviderBuilderExtensions.cs @@ -24,7 +24,7 @@ public static TracerProviderBuilder AddXRayTraceId(this TracerProviderBuilder bu return builder; } -#if NET6_0_OR_GREATER +#if NET /// /// Replace the trace id of root activity. /// diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs index 188eb606b5..871bc63850 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentProviderBuilderExtensions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using Microsoft.Extensions.DependencyInjection; @@ -25,7 +25,7 @@ public static class TraceEnrichmentProviderBuilderExtensions /// /// Add this enricher *before* exporter related Activity processors. /// -#if NET6_0_OR_GREATER +#if NET public static TracerProviderBuilder AddTraceEnricher<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(this TracerProviderBuilder builder) #else public static TracerProviderBuilder AddTraceEnricher(this TracerProviderBuilder builder) diff --git a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs index add67c8c8c..3741f04e0c 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/TraceEnrichmentServiceCollectionExtensions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using Microsoft.Extensions.DependencyInjection.Extensions; @@ -26,7 +26,7 @@ public static class TraceEnrichmentServiceCollectionExtensions /// /// Add this enricher *before* exporter related Activity processors. /// -#if NET6_0_OR_GREATER +#if NET public static IServiceCollection AddTraceEnricher<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(this IServiceCollection services) #else public static IServiceCollection AddTraceEnricher(this IServiceCollection services) diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index 90e4bd3b96..321369ffc1 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -33,7 +33,7 @@ public static TracerProviderBuilder AddAutoFlushActivityProcessor( Func predicate, int timeoutMilliseconds = 10000) { -#if NET6_0_OR_GREATER +#if NET ArgumentNullException.ThrowIfNull(builder); #else if (builder == null) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index a58298b79a..f24843c97d 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -130,7 +130,7 @@ private static void ProcessException(Activity activity, Exception ex) } } -#if NET6_0_OR_GREATER +#if NET [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( "Trimming", "IL2075", diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs index cafd0141d9..b7c1ab5970 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/AspNetCoreInstrumentationEventSource.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using System.Diagnostics.Tracing; @@ -57,7 +57,7 @@ public void RequestIsFilteredOut(string handlerName, string eventName, string op this.WriteEvent(2, handlerName, eventName, operationName); } -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] #endif [Event(3, Message = "Filter threw exception, request will not be collected. HandlerName: '{0}', EventName: '{1}', OperationName: '{2}', Exception: {3}.", Level = EventLevel.Error)] @@ -66,7 +66,7 @@ public void RequestFilterException(string handlerName, string eventName, string this.WriteEvent(3, handlerName, eventName, operationName, exception); } -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Parameters to this method are primitive and are trimmer safe.")] #endif [Event(4, Message = "Enrich threw exception. HandlerName: '{0}', EventName: '{1}', OperationName: '{2}', Exception: {3}.", Level = EventLevel.Warning)] diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 6a9ec0be44..7f0aa51634 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -337,7 +337,7 @@ public void OnException(Activity activity, object? payload) // See https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L252 // and https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddlewareImpl.cs#L174 // this makes sure that top-level properties on the payload object are always preserved. -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index c0676a2484..08ab129cab 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -6,12 +6,11 @@ using System.Diagnostics.Metrics; using System.Reflection; using Microsoft.AspNetCore.Http; -using OpenTelemetry.Internal; - -#if NET6_0_OR_GREATER +#if NET using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Routing; #endif +using OpenTelemetry.Internal; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; @@ -55,12 +54,12 @@ public static void OnExceptionEventWritten(string name, object? payload) // See https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L252 // and https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddlewareImpl.cs#L174 // this makes sure that top-level properties on the payload object are always preserved. -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] #endif static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] #endif static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? ctx) @@ -86,7 +85,7 @@ public static void OnStopEventWritten(string name, object? payload) var httpMethod = TelemetryHelper.RequestDataHelper.GetNormalizedHttpMethod(context.Request.Method); tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); -#if NET6_0_OR_GREATER +#if NET // Check the exception handler feature first in case the endpoint was overwritten var route = (context.Features.Get()?.Endpoint as RouteEndpoint ?? context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs index 5742dae08b..d7d7ca78bd 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs @@ -158,7 +158,7 @@ public void OnStartActivity(Activity activity, object? payload) // See https://github.com/grpc/grpc-dotnet/blob/ff1a07b90c498f259e6d9f4a50cdad7c89ecd3c0/src/Grpc.Net.Client/Internal/GrpcCall.cs#L1180-L1183 // this makes sure that top-level properties on the payload object are always preserved. -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) @@ -199,7 +199,7 @@ public void OnStopActivity(Activity activity, object? payload) // See https://github.com/grpc/grpc-dotnet/blob/ff1a07b90c498f259e6d9f4a50cdad7c89ecd3c0/src/Grpc.Net.Client/Internal/GrpcCall.cs#L1180-L1183 // this makes sure that top-level properties on the payload object are always preserved. -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif static bool TryFetchResponse(object? payload, [NotNullWhen(true)] out HttpResponseMessage? response) diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index 61147eafc4..9201adae51 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif #if NETFRAMEWORK @@ -154,7 +154,7 @@ public void OnStartActivity(Activity activity, object payload) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] #endif static bool TryFetchRequest(object payload, out HttpRequestMessage request) @@ -220,7 +220,7 @@ public void OnStopActivity(Activity activity, object payload) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] #endif static TaskStatus GetRequestStatus(object payload) @@ -235,7 +235,7 @@ static TaskStatus GetRequestStatus(object payload) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] #endif static bool TryFetchResponse(object payload, out HttpResponseMessage response) @@ -283,7 +283,7 @@ public void OnException(Activity activity, object payload) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top-level properties are preserved")] #endif static bool TryFetchException(object payload, out Exception exc) diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs index eb781dbd97..84297e95ee 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using System.Diagnostics.Metrics; @@ -30,7 +30,7 @@ internal sealed class HttpHandlerMetricsDiagnosticListener : ListenerHandler private static readonly PropertyFetcher StopResponseFetcher = new("Response"); private static readonly PropertyFetcher StopExceptionFetcher = new("Exception"); private static readonly PropertyFetcher RequestFetcher = new("Request"); -#if NET6_0_OR_GREATER +#if NET private static readonly HttpRequestOptionsKey HttpRequestOptionsErrorKey = new(SemanticConventions.AttributeErrorType); #endif @@ -72,7 +72,7 @@ public static void OnStopEventWritten(Activity activity, object payload) if (response == null) { -#if !NET6_0_OR_GREATER +#if !NET request.Properties.TryGetValue(SemanticConventions.AttributeErrorType, out var errorType); #else request.Options.TryGetValue(HttpRequestOptionsErrorKey, out var errorType); @@ -94,7 +94,7 @@ public static void OnStopEventWritten(Activity activity, object payload) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] #endif static bool TryFetchRequest(object payload, out HttpRequestMessage request) => @@ -102,7 +102,7 @@ static bool TryFetchRequest(object payload, out HttpRequestMessage request) => // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] #endif static bool TryFetchResponse(object payload, out HttpResponseMessage response) => @@ -117,7 +117,7 @@ public static void OnExceptionEventWritten(Activity activity, object payload) return; } -#if !NET6_0_OR_GREATER +#if !NET request.Properties.Add(SemanticConventions.AttributeErrorType, exc.GetType().FullName); #else request.Options.Set(HttpRequestOptionsErrorKey, exc.GetType().FullName); @@ -125,7 +125,7 @@ public static void OnExceptionEventWritten(Activity activity, object payload) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] #endif static bool TryFetchException(object payload, out Exception exc) @@ -140,7 +140,7 @@ static bool TryFetchException(object payload, out Exception exc) // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] #endif static bool TryFetchRequest(object payload, out HttpRequestMessage request) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs index 6c1b2c43da..6f3a4e53ea 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeInstrumentationOptions.cs @@ -14,14 +14,14 @@ public class RuntimeInstrumentationOptions /// public bool? GcEnabled { get; set; } - #if NET6_0_OR_GREATER + #if NET /// /// Gets or sets a value indicating whether jitter metrics should be collected. /// public bool? JitEnabled { get; set; } #endif - #if NET6_0_OR_GREATER + #if NET /// /// Gets or sets a value indicating whether threading metrics should be collected. /// @@ -42,10 +42,10 @@ public class RuntimeInstrumentationOptions /// Gets a value indicating whether all metrics are enabled. /// internal bool IsAllEnabled => this.GcEnabled == null - #if NET6_0_OR_GREATER + #if NET && this.JitEnabled == null #endif - #if NET6_0_OR_GREATER + #if NET && this.ThreadingEnabled == null #endif && this.AssembliesEnabled == null @@ -56,14 +56,14 @@ public class RuntimeInstrumentationOptions /// internal bool IsGcEnabled => this.GcEnabled == true || this.IsAllEnabled; - #if NET6_0_OR_GREATER + #if NET /// /// Gets a value indicating whether jitter metrics is enabled. /// internal bool IsJitEnabled => this.JitEnabled == true || this.IsAllEnabled; #endif - #if NET6_0_OR_GREATER + #if NET /// /// Gets a value indicating whether threading metrics is enabled. /// diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 4fb23bf5ff..1e6569adc6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -6,7 +6,7 @@ using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Internal; -#if NET6_0_OR_GREATER +#if NET using System.Threading; using JitInfo = System.Runtime.JitInfo; #endif @@ -22,7 +22,7 @@ internal sealed class RuntimeMetrics internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly Meter MeterInstance = new(AssemblyName.Name!, Assembly.GetPackageVersion()); -#if NET6_0_OR_GREATER +#if NET private const long NanosecondsPerTick = 100; #endif private const int NumberOfGenerations = 3; @@ -43,7 +43,7 @@ static RuntimeMetrics() unit: "bytes", description: "Count of bytes currently in use by objects in the GC heap that haven't been collected yet. Fragmentation and other GC committed memory pools are excluded."); -#if NET6_0_OR_GREATER +#if NET MeterInstance.CreateObservableCounter( "process.runtime.dotnet.gc.allocations.size", () => GC.GetTotalAllocatedBytes(), diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index bf3b77c599..acbecedbb2 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -5,13 +5,13 @@ using System.Data; using System.Diagnostics; using OpenTelemetry.Trace; -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif namespace OpenTelemetry.Instrumentation.SqlClient.Implementation; -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] #endif internal sealed class SqlClientDiagnosticListener : ListenerHandler diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs index dfd02f558c..301f5a7891 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using OpenTelemetry.Instrumentation.SqlClient.Implementation; @@ -14,7 +14,7 @@ namespace OpenTelemetry.Instrumentation.SqlClient; internal sealed class SqlClientInstrumentation : IDisposable { internal const string SqlClientDiagnosticListenerName = "SqlClientDiagnosticListener"; -#if NET6_0_OR_GREATER +#if NET internal const string SqlClientTrimmingUnsupportedMessage = "Trimming is not yet supported with SqlClient instrumentation."; #endif #if NETFRAMEWORK @@ -40,7 +40,7 @@ internal sealed class SqlClientInstrumentation : IDisposable /// Initializes a new instance of the class. /// /// Configuration options for sql instrumentation. -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] #endif public SqlClientInstrumentation( diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs index e35707edc7..2959484eb3 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using Microsoft.Extensions.DependencyInjection; @@ -22,7 +22,7 @@ public static class TracerProviderBuilderExtensions /// /// being configured. /// The instance of to chain the calls. -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] #endif public static TracerProviderBuilder AddSqlClientInstrumentation(this TracerProviderBuilder builder) @@ -34,7 +34,7 @@ public static TracerProviderBuilder AddSqlClientInstrumentation(this TracerProvi /// being configured. /// Callback action for configuring . /// The instance of to chain the calls. -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] #endif public static TracerProviderBuilder AddSqlClientInstrumentation( @@ -49,7 +49,7 @@ public static TracerProviderBuilder AddSqlClientInstrumentation( /// Name which is used when retrieving options. /// Callback action for configuring . /// The instance of to chain the calls. -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] #endif diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 9052b95031..5b3a338383 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -7,7 +7,7 @@ using System.Reflection.Emit; using OpenTelemetry.Trace; using StackExchange.Redis.Profiling; -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; #endif @@ -56,14 +56,14 @@ internal static class RedisProfilerEntryToActivityConverter return (null, script); -#if NET6_0_OR_GREATER +#if NET [DynamicDependency("CommandAndKey", "StackExchange.Redis.Message", "StackExchange.Redis")] [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The CommandAndKey property is preserved by the above DynamicDependency")] #endif static bool GetCommandAndKey( PropertyFetcher commandAndKeyFetcher, object message, -#if NET6_0_OR_GREATER +#if NET [NotNullWhen(true)] #endif out string? value) @@ -192,7 +192,7 @@ public static void DrainSession(Activity? parentActivity, IEnumerable private static Func? CreateFieldGetter( -#if NET6_0_OR_GREATER +#if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] #endif Type classType, @@ -202,7 +202,7 @@ public static void DrainSession(Activity? parentActivity, IEnumerable)getterMethod.CreateDelegate(typeof(Func)); } -#if NET6_0_OR_GREATER +#if NET else { return obj => (TField?)field.GetValue(obj); diff --git a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs index d956ffb281..c17c291add 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Runtime.InteropServices; #endif using OpenTelemetry.Resources.AWS.Models; @@ -14,7 +14,7 @@ namespace OpenTelemetry.Resources.AWS; internal sealed class AWSEBSDetector : IResourceDetector { private const string AWSEBSMetadataWindowsFilePath = "C:\\Program Files\\Amazon\\XRay\\environment.conf"; -#if NET6_0_OR_GREATER +#if NET private const string AWSEBSMetadataLinuxFilePath = "/var/elasticbeanstalk/xray/environment.conf"; #endif @@ -27,7 +27,7 @@ public Resource Detect() try { string? filePath; -#if NET6_0_OR_GREATER +#if NET if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { filePath = AWSEBSMetadataWindowsFilePath; @@ -84,7 +84,7 @@ internal static List> ExtractResourceAttributes(AWS internal static AWSEBSMetadataModel? GetEBSMetadata(string filePath) { -#if NET6_0_OR_GREATER +#if NET return ResourceDetectorUtils.DeserializeFromFile(filePath, SourceGenerationContext.Default.AWSEBSMetadataModel); #else return ResourceDetectorUtils.DeserializeFromFile(filePath); diff --git a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs index 57e8652f1f..d56fe184c9 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs @@ -80,7 +80,7 @@ internal static List> ExtractResourceAttributes(AWS internal static AWSEC2IdentityDocumentModel? DeserializeResponse(string response) { -#if NET6_0_OR_GREATER +#if NET return ResourceDetectorUtils.DeserializeFromString(response, SourceGenerationContext.Default.AWSEC2IdentityDocumentModel); #else return ResourceDetectorUtils.DeserializeFromString(response); diff --git a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index 6261a05b84..b32ef0f2df 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -110,7 +110,7 @@ internal static List> ExtractResourceAttributes(str internal static AWSEKSClusterInformationModel? DeserializeResponse(string response) { -#if NET6_0_OR_GREATER +#if NET return ResourceDetectorUtils.DeserializeFromString(response, SourceGenerationContext.Default.AWSEKSClusterInformationModel); #else return ResourceDetectorUtils.DeserializeFromString(response); diff --git a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs index d68b708d4b..0c4318e5c7 100644 --- a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs @@ -17,7 +17,7 @@ namespace OpenTelemetry.Resources.AWS; /// internal static class ResourceDetectorUtils { -#if !NET6_0_OR_GREATER +#if !NET private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); #endif @@ -43,7 +43,7 @@ internal static async Task SendOutRequest(string url, string method, Key } } -#if NET6_0_OR_GREATER +#if NET internal static T? DeserializeFromFile(string filePath, JsonTypeInfo jsonTypeInfo) { using (var stream = GetStream(filePath)) diff --git a/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs b/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs index 3c14a8df70..51f0b9a4d5 100644 --- a/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs +++ b/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Text.Json.Serialization; using OpenTelemetry.Resources.AWS.Models; diff --git a/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs index 44c8cfb39e..71b0c03a5c 100644 --- a/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs @@ -64,7 +64,7 @@ public Resource Detect() string? websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); string websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty; -#if NET6_0_OR_GREATER +#if NET int idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal); #else int idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal); diff --git a/src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs b/src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs index 182ca89af5..41b0460c57 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureVmMetaDataRequestor.cs @@ -20,7 +20,7 @@ internal static class AzureVmMetaDataRequestor if (res != null) { -#if NET6_0_OR_GREATER +#if NET return JsonSerializer.Deserialize(res, SourceGenerationContext.Default.AzureVmMetadataResponse); #else return JsonSerializer.Deserialize(res); diff --git a/src/OpenTelemetry.Resources.Azure/SourceGenerationContext.cs b/src/OpenTelemetry.Resources.Azure/SourceGenerationContext.cs index 3f1a36bc8f..5fb96f1861 100644 --- a/src/OpenTelemetry.Resources.Azure/SourceGenerationContext.cs +++ b/src/OpenTelemetry.Resources.Azure/SourceGenerationContext.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Text.Json.Serialization; namespace OpenTelemetry.Resources.Azure; diff --git a/src/OpenTelemetry.Resources.Process/ProcessDetector.cs b/src/OpenTelemetry.Resources.Process/ProcessDetector.cs index 4b1c1257c8..57dffe6425 100644 --- a/src/OpenTelemetry.Resources.Process/ProcessDetector.cs +++ b/src/OpenTelemetry.Resources.Process/ProcessDetector.cs @@ -17,7 +17,7 @@ public Resource Detect() return new Resource(new List>(2) { new(ProcessSemanticConventions.AttributeProcessOwner, Environment.UserName), -#if NET6_0_OR_GREATER +#if NET new(ProcessSemanticConventions.AttributeProcessPid, Environment.ProcessId), #else new(ProcessSemanticConventions.AttributeProcessPid, System.Diagnostics.Process.GetCurrentProcess().Id), diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index a50b4d2391..758a0817fd 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -38,7 +38,7 @@ public async Task> GetSamplingRules() try { GetSamplingRulesResponse? getSamplingRulesResponse = JsonSerializer -#if NET6_0_OR_GREATER +#if NET .Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingRulesResponse); #else .Deserialize(responseJson); @@ -72,7 +72,7 @@ public async Task> GetSamplingRules() public async Task GetSamplingTargets(GetSamplingTargetsRequest getSamplingTargetsRequest) { var json = JsonSerializer -#if NET6_0_OR_GREATER +#if NET .Serialize(getSamplingTargetsRequest, SourceGenerationContext.Default.GetSamplingTargetsRequest); #else .Serialize(getSamplingTargetsRequest); @@ -90,7 +90,7 @@ public async Task> GetSamplingRules() try { GetSamplingTargetsResponse? getSamplingTargetsResponse = JsonSerializer -#if NET6_0_OR_GREATER +#if NET .Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingTargetsResponse); #else .Deserialize(responseJson); diff --git a/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs b/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs index 239c7dcfcc..08bcf6bc22 100644 --- a/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs +++ b/src/OpenTelemetry.Sampler.AWS/SourceGenerationContext.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Text.Json.Serialization; namespace OpenTelemetry.Sampler.AWS; diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs index 1ae08c8d15..a3a9a4f274 100644 --- a/src/Shared/AssemblyVersionExtensions.cs +++ b/src/Shared/AssemblyVersionExtensions.cs @@ -26,7 +26,7 @@ public static string GetPackageVersion(this Assembly assembly) var informationalVersion = assembly.GetCustomAttribute()?.InformationalVersion; Debug.Assert(!string.IsNullOrEmpty(informationalVersion), "AssemblyInformationalVersionAttribute was not found in assembly"); -#if NET6_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER +#if NET || NETSTANDARD2_1_OR_GREATER var indexOfPlusSign = informationalVersion!.IndexOf('+', StringComparison.Ordinal); #else var indexOfPlusSign = informationalVersion!.IndexOf('+'); diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index 3222a307b3..aec04ccd08 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -21,7 +21,7 @@ #pragma warning disable SA1403 // File may only contain a single namespace #pragma warning disable SA1649 // File name should match first type name -#if !NET6_0_OR_GREATER +#if !NET namespace System.Runtime.CompilerServices { /// Allows capturing of the expressions passed to a method. @@ -38,7 +38,7 @@ public CallerArgumentExpressionAttribute(string parameterName) } #endif -#if !NET6_0_OR_GREATER && !NETSTANDARD2_1_OR_GREATER +#if !NET && !NETSTANDARD2_1_OR_GREATER namespace System.Diagnostics.CodeAnalysis { /// Specifies that an output is not even if diff --git a/src/Shared/Options/DelegatingOptionsFactory.cs b/src/Shared/Options/DelegatingOptionsFactory.cs index 1b8fe62188..3e9b2914e3 100644 --- a/src/Shared/Options/DelegatingOptionsFactory.cs +++ b/src/Shared/Options/DelegatingOptionsFactory.cs @@ -16,7 +16,7 @@ example of how that works. #nullable enable using System.Diagnostics; -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using Microsoft.Extensions.Configuration; @@ -27,7 +27,7 @@ namespace Microsoft.Extensions.Options; /// Implementation of . /// /// The type of options being requested. -#if NET6_0_OR_GREATER +#if NET internal sealed class DelegatingOptionsFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : #else internal sealed class DelegatingOptionsFactory : diff --git a/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs index 69c7b6c3b6..b3b9736277 100644 --- a/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs +++ b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs @@ -4,7 +4,7 @@ #nullable enable using System.Diagnostics; -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif using Microsoft.Extensions.Configuration; @@ -15,7 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection; internal static class DelegatingOptionsFactoryServiceCollectionExtensions { -#if NET6_0_OR_GREATER +#if NET public static IServiceCollection RegisterOptionsFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( #else public static IServiceCollection RegisterOptionsFactory( @@ -40,7 +40,7 @@ public static IServiceCollection RegisterOptionsFactory( return services!; } -#if NET6_0_OR_GREATER +#if NET public static IServiceCollection RegisterOptionsFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( #else public static IServiceCollection RegisterOptionsFactory( @@ -65,7 +65,7 @@ public static IServiceCollection RegisterOptionsFactory( return services!; } -#if NET6_0_OR_GREATER +#if NET public static IServiceCollection DisableOptionsReloading<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>( #else public static IServiceCollection DisableOptionsReloading( diff --git a/src/Shared/Options/SingletonOptionsManager.cs b/src/Shared/Options/SingletonOptionsManager.cs index c1807183e3..4c7718e78c 100644 --- a/src/Shared/Options/SingletonOptionsManager.cs +++ b/src/Shared/Options/SingletonOptionsManager.cs @@ -3,13 +3,13 @@ #nullable enable -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics.CodeAnalysis; #endif namespace Microsoft.Extensions.Options; -#if NET6_0_OR_GREATER +#if NET internal sealed class SingletonOptionsManager<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] TOptions> : IOptionsMonitor, IOptionsSnapshot #else internal sealed class SingletonOptionsManager : IOptionsMonitor, IOptionsSnapshot diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index d15193a40a..003f4a4ee8 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -8,7 +8,7 @@ #nullable enable #pragma warning disable IDE0005 // Using directive is unnecessary. -#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER +#if NETSTANDARD2_1_0_OR_GREATER || NET using System.Diagnostics.CodeAnalysis; #endif using System; @@ -24,7 +24,7 @@ namespace OpenTelemetry.Instrumentation; /// The type of the property being fetched. internal sealed class PropertyFetcher { -#if NET6_0_OR_GREATER +#if NET private const string TrimCompatibilityMessage = "PropertyFetcher is used to access properties on objects dynamically by design and cannot be made trim compatible."; #endif private readonly string propertyName; @@ -49,11 +49,11 @@ public PropertyFetcher(string propertyName) /// Object to be fetched. /// Fetched value. /// if the property was fetched. -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(TrimCompatibilityMessage)] #endif public bool TryFetch( -#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER +#if NETSTANDARD2_1_0_OR_GREATER || NET [NotNullWhen(true)] #endif object? obj, @@ -68,7 +68,7 @@ public bool TryFetch( return innerFetcher.TryFetch(obj, out value); } -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(TrimCompatibilityMessage)] #endif private static bool TryFetchRare(object? obj, string propertyName, ref PropertyFetch? destination, out T? value) @@ -93,7 +93,7 @@ private static bool TryFetchRare(object? obj, string propertyName, ref PropertyF } // see https://github.com/dotnet/corefx/blob/master/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(TrimCompatibilityMessage)] #endif private abstract class PropertyFetch @@ -138,7 +138,7 @@ private abstract class PropertyFetch // IL3050 was generated here because of the call to MakeGenericType, which is problematic in AOT if one of the type parameters is a value type; // because the compiler might need to generate code specific to that type. // If the type parameter is a reference type, there will be no problem; because the generated code can be shared among all reference type instantiations. -#if NET6_0_OR_GREATER +#if NET [UnconditionalSuppressMessage("AOT", "IL3050", Justification = "The code guarantees that all the generic parameters are reference types.")] #endif static PropertyFetch? DynamicInstantiationHelper(Type declaringType, PropertyInfo propertyInfo) @@ -152,7 +152,7 @@ private abstract class PropertyFetch } public abstract bool TryFetch( -#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER +#if NETSTANDARD2_1_0_OR_GREATER || NET [NotNullWhen(true)] #endif object? obj, @@ -180,7 +180,7 @@ private static PropertyFetchInstantiated CreateInstantiated new PropertyFetchInstantiated(propertyInfo); -#if NET6_0_OR_GREATER +#if NET [RequiresUnreferencedCode(TrimCompatibilityMessage)] #endif private sealed class PropertyFetchInstantiated : PropertyFetch @@ -201,7 +201,7 @@ public PropertyFetchInstantiated(PropertyInfo property) : 1 + this.innerFetcher.NumberOfInnerFetchers; public override bool TryFetch( -#if NETSTANDARD2_1_0_OR_GREATER || NET6_0_OR_GREATER +#if NETSTANDARD2_1_0_OR_GREATER || NET [NotNullWhen(true)] #endif object? obj, diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs index 8e93368f0b..da78729fad 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -93,7 +93,7 @@ public void SerializeComplexValueToJsonTest() var version = new Version("1.4.0"); this.SerializeValueToJsonTest(version, "\"1.4.0\""); -#if NET6_0_OR_GREATER +#if NET var typeWithISpanFormattable = new TypeWithISpanFormattable(overflow: false); this.SerializeValueToJsonTest(typeWithISpanFormattable, "\"hello\""); @@ -139,7 +139,7 @@ private sealed class TypeWithThrowingToString public override string ToString() => throw new NotImplementedException(); } -#if NET6_0_OR_GREATER +#if NET private sealed class TypeWithISpanFormattable : ISpanFormattable { private readonly bool overflow; diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs index 6475ae7c2b..7835d3e7dd 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs @@ -52,7 +52,7 @@ public static async Task WriteResponseAsync(Stream ms, TResponse resp } await ResponseUtils.WriteHeaderAsync(ms, data.Length, compress, CancellationToken.None); -#if NET5_0_OR_GREATER +#if NET await ms.WriteAsync(data); #else await ms.WriteAsync(data, 0, data.Length); diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs index 82fc403153..1d2e9f6129 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs @@ -114,7 +114,7 @@ public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress, bool sho } } -#if NET6_0_OR_GREATER +#if NET [Theory] [InlineData(true)] [InlineData(false)] diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs index 8ff452d8e3..0052403748 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Diagnostics; using System.Net; using Greet; @@ -95,7 +95,7 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(string? enableGrp Assert.StartsWith("grpc-dotnet", activity.GetTagValue(SemanticConventions.AttributeUserAgentOriginal) as string); } -#if NET6_0_OR_GREATER +#if NET [Theory(Skip = "Skipping for .NET 6 and higher due to bug #3023")] #endif [InlineData(null)] diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs index 8b0ab4311f..39d8faff0d 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs @@ -12,7 +12,7 @@ public void Enable_All_If_Nothing_Was_Defined() var options = new RuntimeInstrumentationOptions(); Assert.True(options.IsGcEnabled); - #if NET6_0_OR_GREATER + #if NET Assert.True(options.IsJitEnabled); Assert.True(options.IsThreadingEnabled); #endif @@ -26,7 +26,7 @@ public void Enable_Gc_Only() var options = new RuntimeInstrumentationOptions { GcEnabled = true }; Assert.True(options.IsGcEnabled); - #if NET6_0_OR_GREATER + #if NET Assert.False(options.IsJitEnabled); Assert.False(options.IsThreadingEnabled); #endif @@ -34,7 +34,7 @@ public void Enable_Gc_Only() Assert.False(options.IsAllEnabled); } - #if NET6_0_OR_GREATER + #if NET [Fact] public void Enable_Jit_Only() { @@ -48,7 +48,7 @@ public void Enable_Jit_Only() } #endif - #if NET6_0_OR_GREATER + #if NET [Fact] public void Enable_Threading_Only() { @@ -68,7 +68,7 @@ public void Enable_Assemblies_Only() var options = new RuntimeInstrumentationOptions { AssembliesEnabled = true }; Assert.False(options.IsGcEnabled); - #if NET6_0_OR_GREATER + #if NET Assert.False(options.IsJitEnabled); Assert.False(options.IsThreadingEnabled); #endif @@ -82,7 +82,7 @@ public void Enable_Multiple() var options = new RuntimeInstrumentationOptions { GcEnabled = true, AssembliesEnabled = true }; Assert.True(options.IsGcEnabled); - #if NET6_0_OR_GREATER + #if NET Assert.False(options.IsJitEnabled); Assert.False(options.IsThreadingEnabled); #endif diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index f0b23686e7..5b6666a971 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; -#if NET6_0_OR_GREATER +#if NET using System.Threading; using System.Threading.Tasks; #endif @@ -66,7 +66,7 @@ public void GcMetricsTest() var totalObjectsSize = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.objects.size"); Assert.NotNull(totalObjectsSize); -#if NET6_0_OR_GREATER +#if NET var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); Assert.NotNull(gcAllocationSizeMetric); @@ -88,7 +88,7 @@ public void GcMetricsTest() #endif } -#if NET6_0_OR_GREATER +#if NET [Fact] public void JitRelatedMetricsTest() { diff --git a/test/Shared/TestHttpServer.cs b/test/Shared/TestHttpServer.cs index f5924c57e8..63f120c4c4 100644 --- a/test/Shared/TestHttpServer.cs +++ b/test/Shared/TestHttpServer.cs @@ -17,7 +17,7 @@ namespace OpenTelemetry.Tests; internal static class TestHttpServer { -#if !NET6_0_OR_GREATER +#if !NET private static readonly Random GlobalRandom = new(); #endif @@ -32,7 +32,7 @@ public static IDisposable RunServer(Action action, out stri { try { -#if NET6_0_OR_GREATER +#if NET port = RandomNumberGenerator.GetInt32(2000, 5000); #else #pragma warning disable CA5394 // Do not use insecure randomness From b842339c47cab806340cec04f38822f19d6f9dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 26 Jun 2024 07:25:47 +0200 Subject: [PATCH 1166/1499] [repo] ImplicitUsings - enable globally (#1927) --- build/Common.props | 1 + examples/AspNet/Controllers/WeatherForecastController.cs | 4 ---- examples/AspNet/Global.asax.cs | 1 - examples/AspNet/Models/WeatherForecast.cs | 2 -- examples/AspNet/SuppressInstrumentationHttpModule.cs | 1 - .../InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj | 1 - examples/enrichment/Examples.Enrichment/MyService.cs | 3 --- .../Examples.EventCounters/Examples.EventCounters.csproj | 1 - .../Controllers/WeatherForecastController.cs | 4 ---- .../Examples.GrpcCore.AspNetCore/EchoService.cs | 1 - .../grpc.core/Examples.GrpcCore.AspNetCore/Program.cs | 3 --- .../grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs | 7 ------- .../Examples.GrpcCore.AspNetCore/WeatherForecast.cs | 2 -- examples/owin/Program.cs | 3 --- .../process-instrumentation.csproj | 1 - .../Examples.StackExchangeRedis.csproj | 1 - .../runtime-instrumentation.csproj | 1 - examples/wcf/client-core/Program.cs | 3 --- examples/wcf/client-core/StatusServiceClient.cs | 1 - examples/wcf/client-netframework/Program.cs | 2 -- examples/wcf/client-netframework/StatusServiceClient.cs | 1 - examples/wcf/server-aspnetframework/Global.asax.cs | 1 - examples/wcf/server-aspnetframework/StatusService.svc.cs | 3 --- examples/wcf/server-netframework/Program.cs | 1 - examples/wcf/server-netframework/StatusService.cs | 2 -- examples/wcf/shared/IStatusServiceContract.cs | 1 - examples/wcf/shared/StatusResponse.cs | 1 - .../OpenTelemetry.Exporter.Geneva.csproj | 1 - .../OpenTelemetry.Exporter.InfluxDB.csproj | 1 - .../OpenTelemetry.Exporter.Instana.csproj | 1 - .../OpenTelemetry.Exporter.OneCollector.csproj | 1 - .../OpenTelemetry.Exporter.Stackdriver.csproj | 1 - .../OpenTelemetry.Extensions.AWS.csproj | 1 - .../OpenTelemetry.Extensions.Enrichment.csproj | 2 -- .../OpenTelemetry.Extensions.csproj | 1 - .../Implementation/AWSMessagingUtils.cs | 1 - .../Implementation/AWSPropagatorPipelineHandler.cs | 3 --- .../Implementation/AWSServiceHelper.cs | 1 - .../Implementation/AWSServiceType.cs | 2 -- .../Implementation/AWSTracingPipelineCustomizer.cs | 1 - .../Implementation/AWSTracingPipelineHandler.cs | 2 -- .../Implementation/SnsRequestContextHelper.cs | 2 -- .../Implementation/SqsRequestContextHelper.cs | 2 -- .../Implementation/Utils.cs | 2 -- .../TracerProviderBuilderExtensions.cs | 1 - .../AWSLambdaWrapper.cs | 4 ---- .../Implementation/AWSLambdaHttpUtils.cs | 2 -- .../Implementation/AWSLambdaResourceDetector.cs | 1 - .../Implementation/AWSLambdaUtils.cs | 3 --- .../Implementation/AWSMessagingUtils.cs | 3 --- .../Implementation/CommonExtensions.cs | 3 --- .../TracerProviderBuilderExtensions.cs | 1 - .../ActivityHelper.cs | 2 -- .../AspNetTelemetryEventSource.cs | 1 - .../TelemetryHttpModule.cs | 1 - .../TelemetryHttpModuleOptions.cs | 1 - .../AspNetInstrumentation.cs | 1 - .../AspNetMetrics.cs | 1 - .../AspNetTraceInstrumentationOptions.cs | 1 - .../Implementation/AspNetInstrumentationEventSource.cs | 1 - .../Implementation/HttpInListener.cs | 1 - .../Implementation/HttpInMetricsListener.cs | 1 - .../Implementation/HttpRequestRouteHelper.cs | 1 - .../MeterProviderBuilderExtensions.cs | 1 - .../TracerProviderBuilderExtensions.cs | 1 - .../OpenTelemetry.Instrumentation.AspNetCore.csproj | 2 -- .../CassandraDriverMetricsProvider.cs | 1 - .../DriverGauge.cs | 1 - .../ElasticsearchClientInstrumentation.cs | 1 - .../ElasticsearchClientInstrumentationOptions.cs | 1 - .../ElasticsearchInstrumentationEventSource.cs | 1 - .../ElasticsearchRequestPipelineDiagnosticListener.cs | 5 ++--- ...nTelemetry.Instrumentation.ElasticsearchClient.csproj | 2 +- .../TracerProviderBuilderExtensions.cs | 1 - .../EntityFrameworkInstrumentation.cs | 1 - .../EntityFrameworkInstrumentationOptions.cs | 1 - .../Implementation/EntityFrameworkDiagnosticListener.cs | 1 - .../EntityFrameworkInstrumentationEventSource.cs | 1 - ...nTelemetry.Instrumentation.EntityFrameworkCore.csproj | 2 +- .../TracerProviderBuilderExtensions.cs | 1 - .../EventCountersInstrumentationOptions.cs | 4 ---- .../EventCountersMetrics.cs | 2 -- .../MeterProviderBuilderExtensions.cs | 1 - .../AsyncStreamReaderProxy.cs | 3 --- .../ClientStreamWriterProxy.cs | 2 -- .../ClientTracingInterceptor.cs | 2 -- .../ClientTracingInterceptorOptions.cs | 1 - src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs | 2 -- src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs | 3 --- .../ServerStreamWriterProxy.cs | 2 -- .../ServerTracingInterceptor.cs | 4 ---- .../ServerTracingInterceptorOptions.cs | 1 - .../OpenTelemetry.Instrumentation.GrpcNetClient.csproj | 2 -- .../HangfireInstrumentationOptions.cs | 1 - .../Implementation/HangfireInstrumentation.cs | 1 - .../HangfireInstrumentationJobFilterAttribute.cs | 3 --- .../TracerProviderBuilderExtensions.cs | 1 - .../OpenTelemetry.Instrumentation.Http.csproj | 1 - src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs | 1 - .../Implementation/DiagnosticsMiddleware.cs | 3 --- .../Implementation/OwinInstrumentationEventSource.cs | 1 - .../OwinInstrumentationOptions.cs | 1 - .../TracerProviderBuilderExtensions.cs | 1 - .../AssemblyInfo.cs | 1 - .../ProcessMetrics.cs | 2 -- .../Implementation/QuartzDiagnosticListener.cs | 3 --- .../Implementation/QuartzInstrumentationEventSource.cs | 1 - .../QuartzInstrumentationOptions.cs | 2 -- .../QuartzJobInstrumentation.cs | 1 - .../TraceProviderBuilderExtensions.cs | 1 - .../AssemblyInfo.cs | 1 - .../MeterProviderBuilderExtensions.cs | 1 - .../RuntimeMetrics.cs | 3 --- .../OpenTelemetry.Instrumentation.SqlClient.csproj | 2 -- ...enTelemetry.Instrumentation.StackExchangeRedis.csproj | 1 - .../Implementation/AspNetParentSpanCorrector.cs | 1 - .../Implementation/AsyncResultWithTelemetryState.cs | 3 --- .../Implementation/ClientChannelInstrumentation.cs | 1 - .../Implementation/HttpRequestMessagePropertyWrapper.cs | 1 - .../Implementation/InstrumentedChannelFactory.cs | 1 - .../Implementation/InstrumentedCommunicationObject.cs | 1 - .../Implementation/InstrumentedDuplexChannel.cs | 2 -- .../Implementation/InstrumentedRequestChannel.cs | 2 -- .../Implementation/RequestTelemetryState.cs | 1 - .../Implementation/RequestTelemetryStateTracker.cs | 4 ---- .../Implementation/TelemetryClientMessageInspector.cs | 1 - .../Implementation/TelemetryContextMessageProperty.cs | 2 -- .../Implementation/TelemetryDispatchMessageInspector.cs | 2 -- .../Implementation/TelemetryPropagationReader.cs | 2 -- .../Implementation/TelemetryPropagationWriter.cs | 1 - .../Implementation/WcfInstrumentationActivitySource.cs | 1 - .../Implementation/WcfInstrumentationEventSource.cs | 1 - .../TelemetryContractBehaviorAttribute.cs | 1 - .../TelemetryEndpointBehavior.cs | 3 --- .../TelemetryEndpointBehaviorExtensionElement.cs | 1 - .../TelemetryServiceBehaviorExtensionElement.cs | 1 - .../TracerProviderBuilderExtensions.cs | 1 - .../WcfInstrumentationOptions.cs | 1 - .../OpenTelemetry.PersistentStorage.Abstractions.csproj | 1 - .../OpenTelemetry.PersistentStorage.FileSystem.csproj | 1 - .../OpenTelemetry.Resources.AWS.csproj | 1 - .../OpenTelemetry.Resources.Azure.csproj | 1 - .../OpenTelemetry.Resources.Container.csproj | 1 - .../OpenTelemetry.Resources.Gcp.csproj | 1 - .../OpenTelemetry.Resources.Host.csproj | 1 - .../OpenTelemetry.Resources.Process.csproj | 1 - .../OpenTelemetry.Resources.ProcessRuntime.csproj | 1 - .../OpenTelemetry.Sampler.AWS.csproj | 1 - .../OpenTelemetry.SemanticConventions.csproj | 1 - src/Shared/ActivityInstrumentationHelper.cs | 3 --- src/Shared/AssemblyVersionExtensions.cs | 3 --- src/Shared/DiagnosticSourceListener.cs | 4 ---- src/Shared/DiagnosticSourceSubscriber.cs | 5 ----- src/Shared/ExceptionExtensions.cs | 4 ---- src/Shared/Guard.cs | 6 ------ src/Shared/MultiTypePropertyFetcher.cs | 2 -- src/Shared/PropertyFetcher.AOT.cs | 4 ---- src/Shared/PropertyFetcher.cs | 4 ---- src/Shared/RequestDataHelper.cs | 6 ------ src/Shared/UriHelper.cs | 2 -- .../OpenTelemetry.AotCompatibility.TestApp.csproj | 1 - .../PropertyFetcherTest.cs | 1 - .../RequestDataHelperTests.cs | 2 -- .../OpenTelemetry.Exporter.Geneva.Benchmarks.csproj | 1 - .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 1 - .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 - .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 2 -- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 1 - ...OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj | 1 - .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 1 - .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 1 - .../OpenTelemetry.Extensions.AWS.Tests.csproj | 1 - .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 1 - .../OpenTelemetry.Extensions.Tests.csproj | 1 - .../Implementation/RequestContextHelperTests.cs | 2 -- .../Implementation/TestsHelper.cs | 2 -- .../TestAWSClientInstrumentation.cs | 5 ----- .../TestRequest.cs | 3 --- .../TestRequestContext.cs | 3 --- .../Tools/CustomResponses.cs | 8 -------- .../Tools/CustomWebResponse.cs | 4 ---- .../Tools/HttpResponseMessageBody.cs | 4 ---- .../Tools/MockHttpRequest.cs | 9 --------- .../Tools/MockHttpRequestFactory.cs | 4 ---- .../Tools/MockWebResponse.cs | 8 -------- .../Tools/Utils.cs | 4 ---- .../AWSLambdaWrapperTests.cs | 4 ---- .../Implementation/AWSLambdaHttpUtilsTests.cs | 2 -- .../Implementation/AWSMessagingUtilsTests.cs | 3 --- .../Implementation/CommonExtensionsTests.cs | 2 -- .../SampleHandlers.cs | 2 -- .../SampleLambdaContext.cs | 1 - .../ActivityHelperTest.cs | 4 ---- .../HttpContextHelper.cs | 3 --- .../WebConfigTransformTest.cs | 1 - .../WebConfigWithLocationTagTransformTest.cs | 1 - .../BasicTests.cs | 1 - .../HttpInListenerTests.cs | 4 ---- .../HttpInMetricsListenerTests.cs | 3 --- .../RouteTestHelper.cs | 2 -- .../TestHttpWorkerRequest.cs | 1 - ...elemetry.Instrumentation.AspNetCore.Benchmarks.csproj | 1 - ...OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj | 1 - .../BooksEntity.cs | 1 - .../CassandraInstrumentationTests.cs | 4 ---- .../DependencyInjectionConfigTests.cs | 3 --- .../ElasticsearchClientTests.cs | 4 ---- .../InMemoryConnectionWithDownstreamActivity.cs | 2 -- .../DependencyInjectionConfigTests.cs | 3 --- .../EntityFrameworkDiagnosticListenerTests.cs | 3 --- .../EventCountersMetricsTests.cs | 5 ----- .../FoobarService.cs | 4 ---- .../GrpcCoreClientInterceptorTests.cs | 4 ---- .../GrpcCoreServerInterceptorTests.cs | 3 --- .../InterceptorActivityListener.cs | 1 - .../TestActivityTags.cs | 3 --- ...nTelemetry.Instrumentation.GrpcNetClient.Tests.csproj | 1 - .../DependencyInjectionConfigTests.cs | 3 --- .../HangfireFixture.cs | 1 - .../HangfireInstrumentationJobFilterAttributeTests.cs | 4 ---- .../ProcessorMock.cs | 2 -- .../TestJob.cs | 2 -- .../OpenTelemetry.Instrumentation.Http.Benchmarks.csproj | 1 - .../OpenTelemetry.Instrumentation.Http.Tests.csproj | 1 - .../DiagnosticsMiddlewareTests.cs | 5 ----- .../ProcessMetricsTests.cs | 4 ---- .../QuartzDiagnosticListenerTests.cs | 5 ----- .../TestJob.cs | 4 ---- .../TestJobExecutionExceptionJob.cs | 1 - .../RuntimeMetricsTests.cs | 7 ------- .../OpenTelemetry.Instrumentation.SqlClient.Tests.csproj | 1 - .../RedisProfilerEntryToActivityConverterTests.cs | 1 - .../StackExchangeRedisCallsInstrumentationTests.cs | 3 --- .../TestProfiledCommand.cs | 1 - .../TelemetryBindingElementForHttpTests.cs | 6 ------ .../TelemetryBindingElementForTcpTests.netfx.cs | 5 ----- ...atchMessageInspectorForOneWayOperationsTests.netfx.cs | 4 ---- .../TelemetryDispatchMessageInspectorTests.netfx.cs | 4 ---- .../TelemetryPropagationTests.netfx.cs | 4 ---- .../Tools/DownstreamInstrumentationChannel.cs | 2 -- .../Tools/ErrorHandler.netfx.cs | 2 -- .../Tools/ErrorHandlerServiceBehavior.netfx.cs | 2 -- .../WCF/IServiceContract.cs | 1 - .../WCF/Service.netfx.cs | 5 ++--- .../WCF/ServiceClient.cs | 1 - ...Telemetry.PersistentStorage.Abstractions.Tests.csproj | 1 - ...enTelemetry.PersistentStorage.FileSystem.Tests.csproj | 1 - .../OpenTelemetry.Resources.AWS.Tests.csproj | 1 - .../OpenTelemetry.Resources.Azure.Tests.csproj | 1 - .../OpenTelemetry.Resources.Container.Tests.csproj | 1 - .../OpenTelemetry.Resources.Gcp.Tests.csproj | 1 - .../OpenTelemetry.Resources.Host.Tests.csproj | 1 - .../OpenTelemetry.Resources.Process.Tests.csproj | 1 - .../OpenTelemetry.Resources.ProcessRuntime.Tests.csproj | 1 - .../OpenTelemetry.Sampler.AWS.Tests.csproj | 1 - test/Shared/CustomTextMapPropagator.cs | 4 ---- test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs | 3 --- test/Shared/EventSourceTestHelper.cs | 5 ----- test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs | 3 --- test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs | 3 --- test/Shared/TestActivityExportProcessor.cs | 3 --- test/Shared/TestActivityProcessor.cs | 3 --- test/Shared/TestEventListener.cs | 5 ----- test/Shared/TestHttpServer.cs | 6 ++---- test/Shared/TestSampler.cs | 3 --- test/Shared/TestTextMapPropagator.cs | 2 -- test/TestApp.AspNetCore/TestApp.AspNetCore.csproj | 1 - 267 files changed, 9 insertions(+), 556 deletions(-) diff --git a/build/Common.props b/build/Common.props index 9099eb0bff..5fc436b894 100644 --- a/build/Common.props +++ b/build/Common.props @@ -12,6 +12,7 @@ true latest-all enable + enable diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index 7f5652d193..bf26ac9955 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -1,14 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Net; using System.Net.Http; using System.Security.Cryptography; -using System.Threading.Tasks; using System.Web.Http; using Examples.AspNet.Models; using OpenTelemetry; diff --git a/examples/AspNet/Global.asax.cs b/examples/AspNet/Global.asax.cs index 015ac54af2..171fd0974c 100644 --- a/examples/AspNet/Global.asax.cs +++ b/examples/AspNet/Global.asax.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Configuration; using System.Web; using System.Web.Http; diff --git a/examples/AspNet/Models/WeatherForecast.cs b/examples/AspNet/Models/WeatherForecast.cs index afdc107657..3a8571457a 100644 --- a/examples/AspNet/Models/WeatherForecast.cs +++ b/examples/AspNet/Models/WeatherForecast.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace Examples.AspNet.Models; public class WeatherForecast diff --git a/examples/AspNet/SuppressInstrumentationHttpModule.cs b/examples/AspNet/SuppressInstrumentationHttpModule.cs index 2b05a1cc59..0f4a3667e8 100644 --- a/examples/AspNet/SuppressInstrumentationHttpModule.cs +++ b/examples/AspNet/SuppressInstrumentationHttpModule.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Web; using OpenTelemetry; diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj index 474a3c5601..55b8906ea0 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -3,7 +3,6 @@ Exe net7.0 - enable Examples.InfluxDB diff --git a/examples/enrichment/Examples.Enrichment/MyService.cs b/examples/enrichment/Examples.Enrichment/MyService.cs index 00d0212505..bcab816f1d 100644 --- a/examples/enrichment/Examples.Enrichment/MyService.cs +++ b/examples/enrichment/Examples.Enrichment/MyService.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; - namespace Examples.Enrichment; internal sealed class MyService : IMyService diff --git a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj index 3cca08e4b8..757050d67f 100644 --- a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj +++ b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj @@ -3,7 +3,6 @@ Exe net6.0 - enable diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index 5570c6f07c..3dfccedde9 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace Examples.GrpcCore.AspNetCore.Controllers; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs index 4efeb0b45a..a1b5e3ff17 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/EchoService.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Threading.Tasks; using Grpc.Core; namespace Examples.GrpcCore.AspNetCore; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs index f4eddbaecf..c0a8cf0f46 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; - namespace Examples.GrpcCore.AspNetCore; public class Program diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index 0957ec35c9..196577a675 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -1,15 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Threading; -using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using OpenTelemetry.Instrumentation.GrpcCore; using OpenTelemetry.Trace; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index 5742858f1f..cfb073e95c 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace Examples.GrpcCore.AspNetCore; public class WeatherForecast diff --git a/examples/owin/Program.cs b/examples/owin/Program.cs index f1fb1fd2ad..baebb2d250 100644 --- a/examples/owin/Program.cs +++ b/examples/owin/Program.cs @@ -1,11 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; using System.Web.Http; using Microsoft.Owin.Hosting; using OpenTelemetry; diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj index 6cd4b9e56e..6d248c26ec 100644 --- a/examples/process-instrumentation/process-instrumentation.csproj +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -2,7 +2,6 @@ Exe net6.0 - enable diff --git a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj index c1ce1cc246..fec889477d 100644 --- a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj +++ b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj @@ -3,7 +3,6 @@ Exe net8.0 - enable diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index 5cff15d301..2531b68d58 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -2,7 +2,6 @@ net6.0 Exe - enable diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 857112700f..9388e2e232 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -1,11 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.IO; using System.ServiceModel; using System.ServiceModel.Channels; -using System.Threading.Tasks; using Microsoft.Extensions.Configuration; using OpenTelemetry; using OpenTelemetry.Instrumentation.Wcf; diff --git a/examples/wcf/client-core/StatusServiceClient.cs b/examples/wcf/client-core/StatusServiceClient.cs index 9fbbc4ade5..527c292916 100644 --- a/examples/wcf/client-core/StatusServiceClient.cs +++ b/examples/wcf/client-core/StatusServiceClient.cs @@ -3,7 +3,6 @@ using System.ServiceModel; using System.ServiceModel.Channels; -using System.Threading.Tasks; namespace Examples.Wcf.Client; diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index 340417f7bb..644a401213 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -1,10 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Configuration; using System.ServiceModel; -using System.Threading.Tasks; using OpenTelemetry; using OpenTelemetry.Resources; using OpenTelemetry.Trace; diff --git a/examples/wcf/client-netframework/StatusServiceClient.cs b/examples/wcf/client-netframework/StatusServiceClient.cs index 45f20c54d6..47b6302d62 100644 --- a/examples/wcf/client-netframework/StatusServiceClient.cs +++ b/examples/wcf/client-netframework/StatusServiceClient.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; -using System.Threading.Tasks; namespace Examples.Wcf.Client; diff --git a/examples/wcf/server-aspnetframework/Global.asax.cs b/examples/wcf/server-aspnetframework/Global.asax.cs index fbf6e5e51d..5813918ab6 100644 --- a/examples/wcf/server-aspnetframework/Global.asax.cs +++ b/examples/wcf/server-aspnetframework/Global.asax.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Configuration; using System.Web; using OpenTelemetry; diff --git a/examples/wcf/server-aspnetframework/StatusService.svc.cs b/examples/wcf/server-aspnetframework/StatusService.svc.cs index a44cf6c018..a1163e6106 100644 --- a/examples/wcf/server-aspnetframework/StatusService.svc.cs +++ b/examples/wcf/server-aspnetframework/StatusService.svc.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Threading.Tasks; - namespace Examples.Wcf.Server.AspNetFramework; public class StatusService : IStatusServiceContract diff --git a/examples/wcf/server-netframework/Program.cs b/examples/wcf/server-netframework/Program.cs index 9031736e40..cfff07318d 100644 --- a/examples/wcf/server-netframework/Program.cs +++ b/examples/wcf/server-netframework/Program.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.ServiceModel; using OpenTelemetry; using OpenTelemetry.Resources; diff --git a/examples/wcf/server-netframework/StatusService.cs b/examples/wcf/server-netframework/StatusService.cs index d5307343a0..41d979c15c 100644 --- a/examples/wcf/server-netframework/StatusService.cs +++ b/examples/wcf/server-netframework/StatusService.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.ServiceModel; -using System.Threading.Tasks; namespace Examples.Wcf.Server; diff --git a/examples/wcf/shared/IStatusServiceContract.cs b/examples/wcf/shared/IStatusServiceContract.cs index f7d632d6b5..5e458b1e39 100644 --- a/examples/wcf/shared/IStatusServiceContract.cs +++ b/examples/wcf/shared/IStatusServiceContract.cs @@ -5,7 +5,6 @@ #if NETFRAMEWORK using System.ServiceModel.Web; #endif -using System.Threading.Tasks; namespace Examples.Wcf; diff --git a/examples/wcf/shared/StatusResponse.cs b/examples/wcf/shared/StatusResponse.cs index b6fcdc85de..c3bf058020 100644 --- a/examples/wcf/shared/StatusResponse.cs +++ b/examples/wcf/shared/StatusResponse.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.Serialization; namespace Examples.Wcf; diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 11c4d04c9e..0e28e227b8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -12,7 +12,6 @@ Exporter.Geneva- 1.9.0 disable - enable diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index ca53d70296..f1c7da1493 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -7,7 +7,6 @@ $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) Exporter.InfluxDB- - enable true diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs index 4ecb84181b..64da5a1e71 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/TracerProviderBuilderExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ElasticsearchClient; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs index 26574973eb..7902787113 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentation.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index a8e3241ded..04b9cabf4a 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Data; using System.Diagnostics; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 9168ef9e39..6f04b69f86 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Data; using System.Diagnostics; using System.Reflection; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs index 91840a1501..98b6bf6c91 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkInstrumentationEventSource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index c7cc580799..1642fd0eb8 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -6,7 +6,7 @@ Instrumentation.EntityFrameworkCore- - true diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs index a40d6885c1..e0bb7bd938 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/TracerProviderBuilderExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.EntityFrameworkCore; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs index caea7a6ae0..7fdc25d72b 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Linq; - namespace OpenTelemetry.Instrumentation.EventCounters; /// diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index 72e4da73b4..8b42388883 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Diagnostics.Tracing; using System.Globalization; diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs index fe804a8dee..1c385aa18f 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/MeterProviderBuilderExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Instrumentation.EventCounters; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index 0b67d80637..a0d1b03303 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Threading; -using System.Threading.Tasks; using Grpc.Core; namespace OpenTelemetry.Instrumentation.GrpcCore; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index 7cc0219ef1..254b4ba709 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Threading.Tasks; using Grpc.Core; namespace OpenTelemetry.Instrumentation.GrpcCore; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 80933e0e6a..7f5d7d7da9 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; -using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 72ff93a4fe..02d214fea1 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Instrumentation.GrpcCore; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs index 7dee524966..0170a05048 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/Extensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Instrumentation.GrpcCore; /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index b09cdf7fd3..5ca663ab81 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Threading; using Google.Protobuf; using Grpc.Core; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index 781fafe430..f07e17c0f6 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Threading.Tasks; using Grpc.Core; namespace OpenTelemetry.Instrumentation.GrpcCore; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index 682f2e2ef0..d0894fd578 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs index d13b705104..9b0b6ca360 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptorOptions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Instrumentation.GrpcCore; diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index be8d44f297..e8103ae2c3 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -5,8 +5,6 @@ gRPC for .NET client instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.GrpcNetClient- - - enable disable diff --git a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs index c099854855..b681a45911 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/AssemblyInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.CompilerServices; #if SIGNED diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 1efc1ee464..65b44f7519 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -1,11 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Threading.Tasks; using Microsoft.Owin; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.Owin.Implementation; diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index 1f5f35ca9a..b3fd0a062e 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index e17a0c3bfd..d48269a8d7 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using Microsoft.Owin; diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index ca55244d23..62dc361cce 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Instrumentation.Owin; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs index ac49604063..863d60df96 100644 --- a/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Process/AssemblyInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index a85a00edc8..d3c9b65594 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -3,8 +3,6 @@ #nullable enable -using System; -using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 8c448f67b5..bb6e68b523 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Reflection; using OpenTelemetry.Internal; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs index 306a4f16dd..384b38431d 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzInstrumentationEventSource.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index a7b099ca4b..cdbad798c2 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; namespace OpenTelemetry.Instrumentation.Quartz; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs index 4ae531dd04..b9aaa2e8a1 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzJobInstrumentation.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Instrumentation.Quartz.Implementation; namespace OpenTelemetry.Instrumentation.Quartz; diff --git a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs index dcb980eec9..0cbdf9378b 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/TraceProviderBuilderExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Instrumentation.Quartz; using OpenTelemetry.Instrumentation.Quartz.Implementation; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs index 699ae92124..239492d4d3 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/AssemblyInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Runtime.CompilerServices; [assembly: CLSCompliant(false)] diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index d73997022d..70959d119c 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Instrumentation.Runtime; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index 1e6569adc6..b267c9c4a6 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -1,13 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Internal; #if NET -using System.Threading; using JitInfo = System.Runtime.JitInfo; #endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index 1ab0a99303..8b38c96bd0 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -6,8 +6,6 @@ SqlClient instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing Instrumentation.SqlClient- - - enable $(NetMinimumSupportedVersion) $(TargetFrameworks);net48;net472;net471;net47;net462 - enable - enable diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 09fb327a2c..689b764d11 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -5,7 +5,6 @@ $(TargetFrameworks);net462 true disable - enable diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index d29a103e22..953bd766ea 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -6,7 +6,6 @@ net7.0;net6.0 $(TargetFrameworks);net48;net472;net471;net47;net462 - enable diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index dc5b007108..48212e7194 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 - enable diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 0af211cf16..ab94de47f5 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 5faa96d9c3..68f248e657 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -3,7 +3,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 0175c67b27..c7400ad0a6 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 9e145180e1..704dda8498 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs index 6f8336633b..7e465a4694 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; using Amazon.Runtime.Internal; using OpenTelemetry.Context.Propagation; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index b6fd78aab0..56d2c67993 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using Amazon.Runtime; using Amazon.Runtime.Internal; using OpenTelemetry.Instrumentation.AWS.Implementation; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index a89dee8240..3ac9c4e664 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -1,12 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -#if !NETFRAMEWORK -using System.Threading.Tasks; -#endif using Amazon; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs index a177693858..8a83185af2 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.IO; using Amazon; using Amazon.Runtime; using Amazon.Runtime.Endpoints; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs index 208f0def71..516c1ba053 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequestContext.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Threading; using Amazon.Runtime; using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Auth; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index ab01696ddf..2fbdec7d8d 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -1,15 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -#if NETFRAMEWORK -using System.IO; -#endif using System.Net; -#if !NETFRAMEWORK -using System.Net.Http; -#endif using Amazon.Runtime; using Amazon.Runtime.Internal; #if NETFRAMEWORK diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index c07364329f..8c90c6c10c 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Linq; using System.Net; -using System.Net.Http; using System.Net.Http.Headers; using Amazon.Runtime.Internal.Transform; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index 70a02cfe6d..b13368ec3c 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.IO; -using System.Net.Http; -using System.Threading.Tasks; using Amazon.Runtime.Internal.Transform; namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index e342f08d33..28cb4d3b05 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -1,16 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Net; -#if !NETFRAMEWORK -using System.Net.Http; -#endif -using System.Threading; -using System.Threading.Tasks; using Amazon.Runtime; using Amazon.Runtime.Internal; using Amazon.Runtime.Internal.Transform; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs index b021814915..dd485676c1 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequestFactory.cs @@ -1,12 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; #if NETFRAMEWORK -using System.IO; using System.Net; -#else -using System.Net.Http; #endif using Amazon.Runtime; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index 80f62d0251..a6fccca9ab 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -1,15 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -#if NETFRAMEWORK -using System.IO; -#endif using System.Net; -#if !NETFRAMEWORK -using System.Net.Http; -#endif using System.Reflection; namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs index 7977399179..8c9630e4bc 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Reflection; namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index e41bdf2ee7..6262c29baa 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Resources; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 6c69a93a0f..04f6e5279f 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using Amazon.Lambda.APIGatewayEvents; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs index 43e6fb8d75..ba2aa4ed49 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using Amazon.Lambda.SQSEvents; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs index 9a3e80ac5c..cd14e91e71 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; -using System.Linq; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 591278fd6e..41843b6084 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Threading.Tasks; using Amazon.Lambda.Core; namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index 6dc9c9311d..cf608da60d 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using Amazon.Lambda.Core; namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index 5f8f18b3a4..0e7bacce92 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -1,13 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Collections; -using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; using System.Web; using OpenTelemetry.Context.Propagation; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs index 2d4c258eba..0b7541eb36 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; using System.Globalization; -using System.IO; -using System.Threading; using System.Web; using System.Web.Hosting; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs index e814d05620..29bdbea897 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigTransformTest.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.IO; using System.Xml.Linq; using Microsoft.Web.XmlTransform; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs index aaa625d24a..ce3f46ec55 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.IO; using System.Xml.Linq; using Microsoft.Web.XmlTransform; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs index ac5a5360b8..3b4823d2a1 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/BasicTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index e83249529c..a3dea82898 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Reflection; using System.Web; using System.Web.Routing; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index 5aeb4a2e8d..1a259e3c1d 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Threading; using System.Web; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Metrics; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs index fcebc17d5b..cebdc04598 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.IO; using System.Web; using System.Web.Routing; diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs index 7230af6a91..fcb09e5a22 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/TestHttpWorkerRequest.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Web; namespace OpenTelemetry.Instrumentation.AspNet.Tests; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj index 6752bc4257..b971a9eafd 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj @@ -3,7 +3,6 @@ Exe $(SupportedNetTargets) - enable diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index a6ebc43bb6..98a11d30d9 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -2,7 +2,6 @@ Unit test project for OpenTelemetry ASP.NET Core instrumentation net8.0;net7.0;net6.0 - enable diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs index 194b2f6972..71202573c6 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using Cassandra.Mapping.Attributes; namespace OpenTelemetry.Instrumentation.Cassandra.Tests; diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs index 51db99e961..380069bdf9 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Cassandra; using Cassandra.Mapping; using Cassandra.Metrics; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs index 736945d141..fc2abb01ae 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 23764de3d3..2d8cf5a40b 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -1,12 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Text; -using System.Threading.Tasks; using Elasticsearch.Net; using Nest; using OpenTelemetry.Resources; diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs index 201557db3d..ba9dfa1278 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Threading; -using System.Threading.Tasks; using Elasticsearch.Net; namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs index 5592f45806..7d01bdb8bb 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 80a72fa847..30accde1dd 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -1,12 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Diagnostics; -using System.Linq; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index dc5226af7e..0b82bc5445 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -1,12 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics.Tracing; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 5d762ff3e9..871299dd68 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Google.Protobuf; using Grpc.Core; using Grpc.Core.Interceptors; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 4aa61712bc..f0bf45e463 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; using OpenTelemetry.Context.Propagation; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index 65b00b4383..a3aa5af28d 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Threading.Tasks; using Grpc.Core; using OpenTelemetry.Context.Propagation; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs index e736367c75..5a5c165881 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/InterceptorActivityListener.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs index 6994c4bdd8..7f1425ab7a 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/TestActivityTags.cs @@ -1,10 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.GrpcCore.Tests; diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index bf3f302c7b..cf6f711f07 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -4,7 +4,6 @@ net8.0;net7.0;net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) $(NoWarn),CS8981 - enable diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs index e850dcebf6..558d53ef95 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs index 34155407c9..614882d572 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using Hangfire; using Hangfire.MemoryStorage; using Hangfire.Storage; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index badd9b8cc6..2b301d0f34 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -1,11 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; using Hangfire; using Hangfire.Storage.Monitoring; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs index 6c556045de..81620efad1 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Instrumentation.Hangfire.Tests; public class ProcessorMock : BaseProcessor diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs index 38e6342a6a..ae2d973450 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; - namespace OpenTelemetry.Instrumentation.Hangfire.Tests; public class TestJob diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj index ff8d777e89..0b9f55c0c2 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj @@ -3,7 +3,6 @@ Exe $(SupportedNetTargets) - enable disable diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 9ea7b240b8..1aa177f6d4 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -4,7 +4,6 @@ net8.0;net7.0;net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable disable diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 240b8a5ee3..ded5c55532 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -1,13 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; using System.Web.Http; using Microsoft.Owin; using Microsoft.Owin.Hosting; diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs index 065ad01c33..26aaff54c2 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/ProcessMetricsTests.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using OpenTelemetry.Metrics; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 98e4b03631..b2faa5ea71 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -1,12 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using OpenTelemetry.Trace; using Quartz; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs index 027ea461cf..7be379f91c 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Quartz; namespace OpenTelemetry.Instrumentation.Quartz.Tests; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs index 182d8387d6..6ebed283b5 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Threading.Tasks; using Quartz; namespace OpenTelemetry.Instrumentation.Quartz.Tests; diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 5b6666a971..ace5166232 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -1,13 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; -using System.Linq; -#if NET -using System.Threading; -using System.Threading.Tasks; -#endif using OpenTelemetry.Metrics; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 0036dbd152..a6b26ab43d 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -3,7 +3,6 @@ Unit test project for OpenTelemetry SqlClient instrumentations net8.0;net7.0;net6.0 $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index c737a8abd6..bf67721ea8 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; using System.Net; using OpenTelemetry.Instrumentation.StackExchangeRedis.Tests; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 0ee6e264bc..198c5c4613 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -1,11 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; using System.Net; -using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using OpenTelemetry.Tests; diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs index 8831c04e62..ea10cb5bfc 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/TestProfiledCommand.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Net; using StackExchange.Redis; using StackExchange.Redis.Profiling; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs index b52bf865ca..d04fce5f0b 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs @@ -1,16 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Net; using System.ServiceModel; using System.ServiceModel.Channels; -using System.Threading; -using System.Threading.Tasks; using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs index f48f622724..c4fd1d6fed 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs @@ -2,18 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Net.Security; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Security; -using System.Threading.Tasks; using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index ff10a2a196..aa91e53df6 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -2,12 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.ServiceModel; -using System.Threading; using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index 0dcd95ad22..938032f2a0 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -2,13 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.ServiceModel; using System.ServiceModel.Channels; -using System.Threading.Tasks; using OpenTelemetry.Trace; using Xunit; using Xunit.Abstractions; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs index 429c1d59fe..3f377702a7 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs @@ -2,14 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; -using System.Threading.Tasks; using OpenTelemetry.Trace; using Xunit; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs index a3aa58c2e4..8ee6338cd2 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System; using System.Diagnostics; -using System.Linq; using System.Reflection; using System.ServiceModel.Channels; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs index 2a223d1967..ecdfad4d37 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandler.netfx.cs @@ -2,10 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -using System; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; -using System.Threading; namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs index 9c5df1ef11..a9d787c45f 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -2,13 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 #if NETFRAMEWORK -using System; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; -using System.Threading; namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 9764bc69be..b9c1cef19a 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.ServiceModel; -using System.Threading.Tasks; namespace OpenTelemetry.Instrumentation.Wcf.Tests; diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs index 5b11e79f33..2f45d336c0 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/Service.netfx.cs @@ -3,7 +3,6 @@ #if NETFRAMEWORK using System.ServiceModel; -using System.Threading.Tasks; namespace OpenTelemetry.Instrumentation.Wcf.Tests; @@ -17,12 +16,12 @@ public class Service : IServiceContract { public Task ErrorAsync() { - throw new System.Exception(); + throw new Exception(); } public void ErrorSynchronous() { - throw new System.Exception(); + throw new Exception(); } public Task ExecuteAsync(ServiceRequest request) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index e63d66c906..b67b98caef 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -3,7 +3,6 @@ using System.ServiceModel; using System.ServiceModel.Channels; -using System.Threading.Tasks; namespace OpenTelemetry.Instrumentation.Wcf.Tests; diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj index 60b7fcc94f..10d560b8e9 100644 --- a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 6e35fbd5a9..d33c3e28e8 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj index 0fe562543e..8143037e07 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj +++ b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj index bc6b4c2d32..7309e53286 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj +++ b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);net462 - enable diff --git a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj index 7cc0cc1001..5edbf2dfe3 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj +++ b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj @@ -4,7 +4,6 @@ Unit test project for Container Detector for OpenTelemetry $(SupportedNetTargets) - enable diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj index 8a9164530b..e1df281415 100644 --- a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj +++ b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj index 03a1eb106b..6675698cc8 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj +++ b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj index b36aadfc5b..b86c6f5cd6 100644 --- a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj +++ b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj index 2b6ec43868..3fec9af968 100644 --- a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj +++ b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj @@ -5,7 +5,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 0d1505baad..6892d723eb 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -3,7 +3,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - enable diff --git a/test/Shared/CustomTextMapPropagator.cs b/test/Shared/CustomTextMapPropagator.cs index b331baeb4b..8d3404e816 100644 --- a/test/Shared/CustomTextMapPropagator.cs +++ b/test/Shared/CustomTextMapPropagator.cs @@ -3,12 +3,8 @@ #nullable enable -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System; -using System.Collections.Generic; using System.Diagnostics; using OpenTelemetry.Context.Propagation; -#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs b/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs index ef96054645..215de236f9 100644 --- a/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs +++ b/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs @@ -1,12 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#pragma warning disable IDE0005 // Using directive is unnecessary.using System; -using System; using System.Diagnostics; using System.Text; using Xunit; -#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/Shared/EventSourceTestHelper.cs b/test/Shared/EventSourceTestHelper.cs index b7a88fa1af..c430f52650 100644 --- a/test/Shared/EventSourceTestHelper.cs +++ b/test/Shared/EventSourceTestHelper.cs @@ -3,14 +3,9 @@ #nullable enable -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System; -using System.Collections.Generic; using System.Diagnostics.Tracing; using System.Globalization; -using System.Linq; using System.Reflection; -#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs index a15ed037d0..d6e4f02518 100644 --- a/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs +++ b/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs @@ -1,11 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled will see warnings on using System - #nullable enable -using System; using Xunit; namespace OpenTelemetry.Tests; diff --git a/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 453e80aa8b..5820d36bef 100644 --- a/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs @@ -1,11 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#pragma warning disable IDE0005 // Using directive is unnecessary. <- Projects with ImplicitUsings enabled will see warnings on using System - #nullable enable -using System; using Xunit; namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestActivityExportProcessor.cs b/test/Shared/TestActivityExportProcessor.cs index 898c9be4dc..b19eb9ad2f 100644 --- a/test/Shared/TestActivityExportProcessor.cs +++ b/test/Shared/TestActivityExportProcessor.cs @@ -3,9 +3,6 @@ #nullable enable -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System.Collections.Generic; -#pragma warning restore IDE0005 // Using directive is unnecessary. using System.Diagnostics; namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestActivityProcessor.cs b/test/Shared/TestActivityProcessor.cs index 378c25b58c..b788c5fa7c 100644 --- a/test/Shared/TestActivityProcessor.cs +++ b/test/Shared/TestActivityProcessor.cs @@ -3,10 +3,7 @@ #nullable enable -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System; using System.Diagnostics; -#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestEventListener.cs b/test/Shared/TestEventListener.cs index 57182d6232..c6b8db9c62 100644 --- a/test/Shared/TestEventListener.cs +++ b/test/Shared/TestEventListener.cs @@ -3,12 +3,7 @@ #nullable enable -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System; -using System.Collections.Generic; using System.Diagnostics.Tracing; -using System.Threading; -#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestHttpServer.cs b/test/Shared/TestHttpServer.cs index 63f120c4c4..c567606649 100644 --- a/test/Shared/TestHttpServer.cs +++ b/test/Shared/TestHttpServer.cs @@ -3,15 +3,13 @@ // Note: When implicit usings are enabled in a project this file will generate // warnings/errors without this suppression. -#pragma warning disable IDE0005 // Using directive is unnecessary. #nullable enable -using System; using System.Net; +#if !NETFRAMEWORK using System.Security.Cryptography; -using System.Threading; -using System.Threading.Tasks; +#endif namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestSampler.cs b/test/Shared/TestSampler.cs index 90c3e769c7..c23bf68ed1 100644 --- a/test/Shared/TestSampler.cs +++ b/test/Shared/TestSampler.cs @@ -3,10 +3,7 @@ #nullable enable -#pragma warning disable IDE0005 // Using directive is unnecessary. -using System; using OpenTelemetry.Trace; -#pragma warning restore IDE0005 // Using directive is unnecessary. namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestTextMapPropagator.cs b/test/Shared/TestTextMapPropagator.cs index 6ed59ae804..ba58606acf 100644 --- a/test/Shared/TestTextMapPropagator.cs +++ b/test/Shared/TestTextMapPropagator.cs @@ -3,8 +3,6 @@ #nullable enable -using System; -using System.Collections.Generic; using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Tests; diff --git a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj index ce4a4b6852..552a719fa7 100644 --- a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj +++ b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj @@ -2,7 +2,6 @@ net8.0;net7.0;net6.0 - enable From 39526e63399622476538353bd46c1aaa19abad26 Mon Sep 17 00:00:00 2001 From: zivaninstana <69787969+zivaninstana@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:34:22 +0200 Subject: [PATCH 1167/1499] [Exporter.Instana] nullable support (#1928) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/PublicAPI.Shipped.txt | 3 +- .../Implementation/InstanaSpan.cs | 221 ++++++++++++++++-- .../Implementation/InstanaSpanSerializer.cs | 29 ++- .../InstanaSpanTransformInfo.cs | 25 +- .../Processors/ActivityProcessorBase.cs | 2 +- .../Processors/DefaultActivityProcessor.cs | 51 ++-- .../Processors/ErrorActivityProcessor.cs | 16 +- .../Processors/EventsActivityProcessor.cs | 2 +- .../Processors/IActivityProcessor.cs | 2 +- .../Processors/TagsActivityProcessor.cs | 20 +- .../Implementation/Transport.cs | 16 +- .../InstanaExporter.cs | 33 +-- .../OpenTelemetry.Exporter.Instana.csproj | 2 +- .../EventsActivityProcessorTests.cs | 16 +- 14 files changed, 352 insertions(+), 86 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Shipped.txt index 5b4e5bba7a..f834db50b9 100644 --- a/src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Instana/.publicApi/PublicAPI.Shipped.txt @@ -1,2 +1,3 @@ +#nullable enable OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions -static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder options) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +static OpenTelemetry.Exporter.Instana.TracerProviderBuilderExtensions.AddInstanaExporter(this OpenTelemetry.Trace.TracerProviderBuilder! options) -> OpenTelemetry.Trace.TracerProviderBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs index 997f7a505f..e9a6ce6e34 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using OpenTelemetry.Internal; + namespace OpenTelemetry.Exporter.Instana.Implementation; internal enum SpanKind @@ -21,62 +23,245 @@ internal enum SpanKind internal class InstanaSpan { - public InstanaSpanTransformInfo TransformInfo { get; set; } + private InstanaSpanTransformInfo transformInfo = new InstanaSpanTransformInfo(); + private string n = string.Empty; + private string t = string.Empty; + private string lt = string.Empty; + private From f = new From(); + private string p = string.Empty; + private string s = string.Empty; + private SpanKind k = SpanKind.NOT_SET; + private long ts; + private long d; + private bool tp; + private int ec; + private Data data = new Data() + { + data = new Dictionary(8), + Events = new List(8), + Tags = new Dictionary(2), + }; - public string N { get; internal set; } + public InstanaSpanTransformInfo TransformInfo + { + get => this.transformInfo; + set + { + Guard.ThrowIfNull(value); + this.transformInfo = value; + } + } - public string T { get; internal set; } + public string N + { + get => this.n; + internal set + { + Guard.ThrowIfNull(value); + this.n = value; + } + } - public string Lt { get; internal set; } + public string T + { + get => this.t; + internal set + { + Guard.ThrowIfNull(value); + this.t = value; + } + } - public From F { get; internal set; } + public string Lt + { + get => this.lt; + internal set + { + Guard.ThrowIfNull(value); + this.lt = value; + } + } - public string P { get; internal set; } + public From F + { + get => this.f; + set + { + Guard.ThrowIfNull(value); + this.f = value; + } + } - public string S { get; internal set; } + public string P + { + get => this.p; + internal set + { + Guard.ThrowIfNull(value); + this.p = value; + } + } - public SpanKind K { get; internal set; } + public string S + { + get => this.s; + internal set + { + Guard.ThrowIfNull(value); + this.s = value; + } + } - public Data Data { get; internal set; } + public SpanKind K + { + get => this.k; + internal set + { + Guard.ThrowIfNull(value); + this.k = value; + } + } - public long Ts { get; internal set; } + public Data Data + { + get => this.data; + internal set + { + Guard.ThrowIfNull(value); + this.data = value; + } + } + + public long Ts + { + get => this.ts; + internal set + { + Guard.ThrowIfNull(value); + this.ts = value; + } + } - public long D { get; internal set; } + public long D + { + get => this.d; + internal set + { + Guard.ThrowIfNull(value); + this.d = value; + } + } - public bool Tp { get; internal set; } + public bool Tp + { + get => this.tp; + internal set + { + Guard.ThrowIfNull(value); + this.tp = value; + } + } - public int Ec { get; internal set; } + public int Ec + { + get => this.ec; + internal set + { + Guard.ThrowIfNull(value); + this.ec = value; + } + } } #pragma warning disable SA1402 // File may only contain a single type internal class From #pragma warning restore SA1402 // File may only contain a single type { + internal From() + { + this.E = string.Empty; + this.H = string.Empty; + } + public string E { get; internal set; } public string H { get; internal set; } + + internal bool IsEmpty() + { + return string.IsNullOrEmpty(this.E) && string.IsNullOrEmpty(this.H); + } } #pragma warning disable SA1402 // File may only contain a single type internal class Data #pragma warning restore SA1402 // File may only contain a single type { + private List events = new List(8); + private Dictionary dataField = new Dictionary(8); + private Dictionary tags = new Dictionary(2); + #pragma warning disable SA1300 // Element should begin with upper-case letter - public Dictionary data { get; internal set; } + + public Dictionary data + { + get => this.dataField; + internal set + { + Guard.ThrowIfNull(value); + this.dataField = value; + } + } #pragma warning restore SA1300 // Element should begin with upper-case letter - public Dictionary Tags { get; internal set; } - public List Events { get; internal set; } + public Dictionary Tags + { + get => this.tags; + internal set + { + Guard.ThrowIfNull(value); + this.tags = value; + } + } + + public List Events + { + get => this.events; + internal set + { + Guard.ThrowIfNull(value); + this.events = value; + } + } } #pragma warning disable SA1402 // File may only contain a single type internal class SpanEvent #pragma warning restore SA1402 // File may only contain a single type { - public string Name { get; internal set; } + private string name = string.Empty; + private Dictionary tags = new Dictionary(); + + public string Name + { + get => this.name; + internal set + { + Guard.ThrowIfNull(value); + this.name = value; + } + } public long Ts { get; internal set; } - public Dictionary Tags { get; internal set; } + public Dictionary Tags + { + get => this.tags; + internal set + { + Guard.ThrowIfNull(value); + this.tags = value; + } + } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 3e47cc80e1..55d8626dad 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -20,12 +20,12 @@ internal static class InstanaSpanSerializer #pragma warning restore SA1310 // Field names should not contain underscore private static readonly long UnixZeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0).Ticks; - internal static IEnumerator GetSpanTagsEnumerator(InstanaSpan instanaSpan) + internal static IEnumerator? GetSpanTagsEnumerator(InstanaSpan instanaSpan) { return instanaSpan.Data.Tags.GetEnumerator(); } - internal static IEnumerator GetSpanEventsEnumerator(InstanaSpan instanaSpan) + internal static IEnumerator? GetSpanEventsEnumerator(InstanaSpan instanaSpan) { return instanaSpan.Data.Events.GetEnumerator(); } @@ -95,9 +95,14 @@ private static async Task SerializeTagsAsync(InstanaSpan instanaSpan, StreamWrit await SerializeTagsLogicAsync(instanaSpan.Data.Tags, writer).ConfigureAwait(false); } - private static async Task SerializeTagsLogicAsync(Dictionary tags, StreamWriter writer) + private static async Task SerializeTagsLogicAsync(Dictionary? tags, StreamWriter writer) { await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); + if (tags == null) + { + return; + } + using (var enumerator = tags.GetEnumerator()) { byte i = 0; @@ -132,7 +137,7 @@ private static async Task SerializeTagsLogicAsync(Dictionary tag await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); } - private static async Task AppendProperty(string value, string name, StreamWriter json) + private static async Task AppendProperty(string? value, string? name, StreamWriter json) { await json.WriteAsync(QUOTE).ConfigureAwait(false); await json.WriteAsync(name).ConfigureAwait(false); @@ -160,6 +165,11 @@ private static async Task AppendObjectAsync(Func 0) + if (instanaSpan.Data.Tags.Count > 0) { await writer.WriteAsync(COMMA).ConfigureAwait(false); @@ -199,7 +209,7 @@ private static async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWrit await AppendObjectAsync(SerializeTagsAsync, InstanaExporterConstants.TAGS_FIELD, instanaSpan, writer).ConfigureAwait(false); } - if (instanaSpan.Data.Events?.Count > 0) + if (instanaSpan.Data.Events.Count > 0) { await writer.WriteAsync(COMMA).ConfigureAwait(false); @@ -212,6 +222,11 @@ private static async Task SerializeDataAsync(InstanaSpan instanaSpan, StreamWrit private static async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWriter writer) { + if (instanaSpan.Data.Events == null) + { + return; + } + using (var enumerator = instanaSpan.Data.Events.GetEnumerator()) { byte i = 0; @@ -240,7 +255,7 @@ private static async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWr await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false); await writer.WriteAsync(QUOTE).ConfigureAwait(false); - if (enumerator.Current.Tags?.Count > 0) + if (enumerator.Current.Tags.Count > 0) { await writer.WriteAsync(COMMA).ConfigureAwait(false); await writer.WriteAsync(QUOTE).ConfigureAwait(false); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs index 24df872045..0fffa8e9c5 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanTransformInfo.cs @@ -1,13 +1,34 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using OpenTelemetry.Internal; + namespace OpenTelemetry.Exporter.Instana.Implementation; internal class InstanaSpanTransformInfo { - public string StatusCode { get; internal set; } + private string statusCode = string.Empty; + private string statusDesc = string.Empty; + + public string StatusCode + { + get => this.statusCode; + set + { + Guard.ThrowIfNull(value); + this.statusCode = value; + } + } - public string StatusDesc { get; internal set; } + public string StatusDesc + { + get => this.statusDesc; + set + { + Guard.ThrowIfNull(value); + this.statusDesc = value; + } + } public bool HasExceptionEvent { get; internal set; } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs index e930059ecd..e4dbea1f3a 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; internal abstract class ActivityProcessorBase : IActivityProcessor { - public IActivityProcessor NextProcessor { get; set; } + public IActivityProcessor? NextProcessor { get; set; } public virtual async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs index 214c2af7dd..fd430b9b6a 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -40,7 +40,7 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp SetKind(activity, instanaSpan); - if (hasParent && instanaSpan.TransformInfo.IsEntrySpan) + if (hasParent && instanaSpan.TransformInfo != null && instanaSpan.TransformInfo.IsEntrySpan) { // If an OTel entry span continues an ongoing trace (which is equivalent to the original span having a parent), it // always uses the IDs from the traceparent header, thus we mark the span with span.tp accordingly. @@ -87,29 +87,36 @@ private static long GetLongFromHex(string hexValue) private static void SetKind(Activity activity, InstanaSpan instanaSpan) { bool isEntrySpan = false; - switch (activity.Kind) + + if (instanaSpan.Data.data != null) { - case ActivityKind.Server: - isEntrySpan = true; - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.SERVER_KIND; - break; - case ActivityKind.Client: - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CLIENT_KIND; - break; - case ActivityKind.Producer: - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.PRODUCER_KIND; - break; - case ActivityKind.Consumer: - isEntrySpan = true; - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CONSUMER_KIND; - break; - case ActivityKind.Internal: - instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.INTERNAL_KIND; - break; - default: - break; + switch (activity.Kind) + { + case ActivityKind.Server: + isEntrySpan = true; + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.SERVER_KIND; + break; + case ActivityKind.Client: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CLIENT_KIND; + break; + case ActivityKind.Producer: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.PRODUCER_KIND; + break; + case ActivityKind.Consumer: + isEntrySpan = true; + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.CONSUMER_KIND; + break; + case ActivityKind.Internal: + instanaSpan.Data.data[InstanaExporterConstants.KIND_FIELD] = InstanaExporterConstants.INTERNAL_KIND; + break; + default: + break; + } } - instanaSpan.TransformInfo.IsEntrySpan = isEntrySpan; + if (instanaSpan.TransformInfo != null) + { + instanaSpan.TransformInfo.IsEntrySpan = isEntrySpan; + } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs index 6c00a71cc5..133fe8e889 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ErrorActivityProcessor.cs @@ -14,13 +14,16 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp if (activity.Status == ActivityStatusCode.Error) { instanaSpan.Ec = 1; - instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD] = activity.Status.ToString(); - if (!string.IsNullOrEmpty(activity.StatusDescription)) + if (instanaSpan.Data.data != null) { - instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD] = activity.StatusDescription; + instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD] = activity.Status.ToString(); + if (activity.StatusDescription != null && !string.IsNullOrEmpty(activity.StatusDescription)) + { + instanaSpan.Data.data[InstanaExporterConstants.ERROR_DETAIL_FIELD] = activity.StatusDescription; + } } } - else if (instanaSpan.TransformInfo.HasExceptionEvent) + else if (instanaSpan.TransformInfo != null && instanaSpan.TransformInfo.HasExceptionEvent) { instanaSpan.Ec = 1; } @@ -29,6 +32,9 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.Ec = 0; } - await base.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); + if (activity != null && instanaSpan != null) + { + await base.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); + } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs index 0e1e08a514..1c1fb00c61 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -13,7 +13,7 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp foreach (var activityEvent in activity.Events) { - if (activityEvent.Name == InstanaExporterConstants.EXCEPTION_FIELD) + if (activityEvent.Name == InstanaExporterConstants.EXCEPTION_FIELD && instanaSpan.TransformInfo != null) { instanaSpan.TransformInfo.HasExceptionEvent = true; } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs index 920d5a83be..b66e437cb9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/IActivityProcessor.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.Instana.Implementation.Processors; internal interface IActivityProcessor { - IActivityProcessor NextProcessor { get; set; } + IActivityProcessor? NextProcessor { get; set; } Task ProcessAsync(System.Diagnostics.Activity activity, InstanaSpan instanaSpan); } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs index f1079955dc..0f6763c1a9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -9,6 +9,16 @@ internal class TagsActivityProcessor : ActivityProcessorBase, IActivityProcessor { public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { + if (instanaSpan == null) + { + return; + } + + if (activity == null) + { + return; + } + this.PreProcess(activity, instanaSpan); string statusCode = string.Empty; @@ -18,13 +28,13 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp { if (tag.Key == "otel.status_code") { - statusCode = tag.Value as string; + statusCode = (tag.Value as string) ?? string.Empty; continue; } if (tag.Key == "otel.status_description") { - statusDesc = tag.Value as string; + statusDesc = (tag.Value as string) ?? string.Empty; continue; } @@ -34,7 +44,11 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp } } - instanaSpan.Data.Tags = tags; + if (instanaSpan.Data != null) + { + instanaSpan.Data.Tags = tags; + } + instanaSpan.TransformInfo.StatusCode = statusCode; instanaSpan.TransformInfo.StatusDesc = statusDesc; diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index d13ae7922b..f39c6b2da7 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -22,7 +22,6 @@ internal static class Transport private static string configuredEndpoint = string.Empty; private static string configuredAgentKey = string.Empty; private static string bundleUrl = string.Empty; - private static InstanaHttpClient client; static Transport() { @@ -31,9 +30,11 @@ static Transport() internal static bool IsAvailable { - get { return isConfigured && client != null; } + get { return isConfigured && Client != null; } } + internal static InstanaHttpClient? Client { get; set; } + internal static async Task SendSpansAsync(ConcurrentQueue spanQueue) { try @@ -82,7 +83,10 @@ internal static async Task SendSpansAsync(ConcurrentQueue spanQueue }) { httpMsg.Content = content; - await client.SendAsync(httpMsg).ConfigureAwait(false); + if (Client != null) + { + await Client.SendAsync(httpMsg).ConfigureAwait(false); + } } } } @@ -136,7 +140,7 @@ private static void Configure() private static void ConfigureBackendClient() { - if (client != null) + if (Client != null) { return; } @@ -155,10 +159,10 @@ private static void ConfigureBackendClient() } #pragma warning disable CA5400 - client = new InstanaHttpClient(backendTimeout, configuredHandler); + Client = new InstanaHttpClient(backendTimeout, configuredHandler); #pragma warning restore CA5400 - client.DefaultRequestHeaders.Add("X-INSTANA-KEY", configuredAgentKey); + Client.DefaultRequestHeaders.Add("X-INSTANA-KEY", configuredAgentKey); } } diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index fa9df6854c..aa77513e7a 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -16,7 +16,7 @@ internal sealed class InstanaExporter : BaseExporter private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); private bool shutdownCalled; - public InstanaExporter(IActivityProcessor activityProcessor = null) + public InstanaExporter(IActivityProcessor? activityProcessor = null) { if (activityProcessor != null) { @@ -56,10 +56,10 @@ public override ExportResult Export(in Batch batch) return ExportResult.Failure; } - From from = null; + From from = new From(); if (this.instanaExporterHelper.IsWindows()) { - from = new From() { E = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture) }; + from = new From { E = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture) }; } string serviceName = this.ExtractServiceName(ref from); @@ -98,12 +98,12 @@ protected override bool OnForceFlush(int timeoutMilliseconds) private string ExtractServiceName(ref From from) { - string serviceName = null; - string serviceId = null; - string processId = null; - string hostId = null; + string serviceName = string.Empty; + string serviceId = string.Empty; + string processId = string.Empty; + string hostId = string.Empty; var resource = this.instanaExporterHelper.GetParentProviderResource(this); - if (resource != Resource.Empty && resource.Attributes?.Count() > 0) + if (resource != Resource.Empty && resource.Attributes.Any()) { foreach (var resourceAttribute in resource.Attributes) { @@ -114,7 +114,7 @@ private string ExtractServiceName(ref From from) serviceName = servName; } - if (from == null) + if (from.IsEmpty()) { if (resourceAttribute.Key.Equals("service.instance.id", StringComparison.OrdinalIgnoreCase)) { @@ -132,9 +132,8 @@ private string ExtractServiceName(ref From from) } } - if (from == null) + if (from.IsEmpty()) { - from = new From(); if (!string.IsNullOrEmpty(processId)) { from.E = processId; @@ -153,19 +152,23 @@ private string ExtractServiceName(ref From from) return serviceName; } - private async Task ParseActivityAsync(Activity activity, string serviceName = null, From from = null) + private async Task ParseActivityAsync(Activity activity, string? serviceName = null, From? from = null) { InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); await this.activityProcessor.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); - if (!string.IsNullOrEmpty(serviceName)) + if (serviceName != null && !string.IsNullOrEmpty(serviceName) && instanaSpan.Data.data != null) { instanaSpan.Data.data[InstanaExporterConstants.SERVICE_FIELD] = serviceName; } - instanaSpan.Data.data[InstanaExporterConstants.OPERATION_FIELD] = activity.DisplayName; - if (!string.IsNullOrEmpty(activity.TraceStateString)) + if (instanaSpan.Data.data != null) + { + instanaSpan.Data.data[InstanaExporterConstants.OPERATION_FIELD] = activity.DisplayName; + } + + if (activity.TraceStateString != null && !string.IsNullOrEmpty(activity.TraceStateString) && instanaSpan.Data.data != null) { instanaSpan.Data.data[InstanaExporterConstants.TRACE_STATE_FIELD] = activity.TraceStateString; } diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index 474df77b09..fe7cf73fad 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -7,7 +7,6 @@ Instana .NET Exporter for OpenTelemetry Exporter.Instana- 1.0.3 - disable @@ -26,6 +25,7 @@ + diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index 7ed21412ca..ce3b79dc8e 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -35,15 +35,25 @@ public async Task ProcessAsync() activity.AddEvent(activityEvent); activity.AddEvent(activityEvent2); InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; - await this.eventsActivityProcessor.ProcessAsync(activity, instanaSpan); + if (this.eventsActivityProcessor != null) + { + await this.eventsActivityProcessor.ProcessAsync(activity, instanaSpan); + } + Assert.NotNull(instanaSpan.Data?.Events); Assert.True(instanaSpan.Ec == 0); Assert.True(instanaSpan.Data.Events.Count == 2); Assert.True(instanaSpan.Data.Events[0].Name == "testActivityEvent"); Assert.True(instanaSpan.Data.Events[0].Ts > 0); - Assert.True(instanaSpan.Data.Events[0].Tags["eventTagKey"] == "eventTagValue"); + Assert.NotNull(instanaSpan.Data?.Events[0]?.Tags); + string? eventTagValue = string.Empty; + _ = instanaSpan.Data.Events[0].Tags?.TryGetValue("eventTagKey", out eventTagValue); + Assert.True(eventTagValue == "eventTagValue"); Assert.True(instanaSpan.Data.Events[1].Name == "testActivityEvent2"); Assert.True(instanaSpan.Data.Events[1].Ts > 0); - Assert.True(instanaSpan.Data.Events[1].Tags["eventTagKey2"] == "eventTagValue2"); + Assert.NotNull(instanaSpan.Data?.Events[1]?.Tags); + eventTagValue = string.Empty; + _ = instanaSpan.Data.Events[1].Tags?.TryGetValue("eventTagKey2", out eventTagValue); + Assert.True(eventTagValue == "eventTagValue2"); } } From c5cf3a4ecd42fd04a36a277cf71da3c12438a5d9 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 28 Jun 2024 05:33:00 +0000 Subject: [PATCH 1168/1499] [Resources.AWS] Prevent potential deadlocks by removing .Result calls (#1922) --- .../AWSEC2Detector.cs | 9 +- .../AWSECSDetector.cs | 8 +- .../AWSEKSDetector.cs | 4 +- .../AsyncHelper.cs | 44 +++++++ .../ResourceDetectorUtils.cs | 10 +- .../AsyncHelperTests.cs | 107 ++++++++++++++++++ 6 files changed, 169 insertions(+), 13 deletions(-) create mode 100644 src/OpenTelemetry.Resources.AWS/AsyncHelper.cs create mode 100644 test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs diff --git a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs index d56fe184c9..4d41c33338 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if NETFRAMEWORK +using System.Net.Http; +#endif using OpenTelemetry.Resources.AWS.Models; namespace OpenTelemetry.Resources.AWS; @@ -89,7 +92,7 @@ internal static List> ExtractResourceAttributes(AWS private static string GetAWSEC2Token() { - return ResourceDetectorUtils.SendOutRequest(AWSEC2MetadataTokenUrl, "PUT", new KeyValuePair(AWSEC2MetadataTokenTTLHeader, "60")).Result; + return AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync(AWSEC2MetadataTokenUrl, HttpMethod.Put, new KeyValuePair(AWSEC2MetadataTokenTTLHeader, "60"))); } private static AWSEC2IdentityDocumentModel? GetAWSEC2Identity(string token) @@ -102,11 +105,11 @@ private static string GetAWSEC2Token() private static string GetIdentityResponse(string token) { - return ResourceDetectorUtils.SendOutRequest(AWSEC2IdentityDocumentUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; + return AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync(AWSEC2IdentityDocumentUrl, HttpMethod.Get, new KeyValuePair(AWSEC2MetadataTokenHeader, token))); } private static string GetAWSEC2HostName(string token) { - return ResourceDetectorUtils.SendOutRequest(AWSEC2HostNameUrl, "GET", new KeyValuePair(AWSEC2MetadataTokenHeader, token)).Result; + return AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync(AWSEC2HostNameUrl, HttpMethod.Get, new KeyValuePair(AWSEC2MetadataTokenHeader, token))); } } diff --git a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs index 495e039946..c7b8e815c2 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs @@ -67,8 +67,8 @@ internal static List> ExtractMetadataV4ResourceAttr } using var httpClientHandler = new HttpClientHandler(); - var metadataV4ContainerResponse = ResourceDetectorUtils.SendOutRequest(metadataV4Url, "GET", null, httpClientHandler).Result; - var metadataV4TaskResponse = ResourceDetectorUtils.SendOutRequest($"{metadataV4Url.TrimEnd('/')}/task", "GET", null, httpClientHandler).Result; + var metadataV4ContainerResponse = AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync(metadataV4Url, HttpMethod.Get, null, httpClientHandler)); + var metadataV4TaskResponse = AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync($"{metadataV4Url.TrimEnd('/')}/task", HttpMethod.Get, null, httpClientHandler)); using var containerResponse = JsonDocument.Parse(metadataV4ContainerResponse); using var taskResponse = JsonDocument.Parse(metadataV4TaskResponse); @@ -89,10 +89,8 @@ internal static List> ExtractMetadataV4ResourceAttr if (!clusterArn.StartsWith("arn:", StringComparison.Ordinal)) { -#pragma warning disable CA1865 // Use string.LastIndexOf(char) instead of string.LastIndexOf(string) when you have string with a single char - var baseArn = containerArn.Substring(containerArn.LastIndexOf(":", StringComparison.Ordinal)); + var baseArn = containerArn.Substring(containerArn.LastIndexOf(':')); #pragma warning restore CA1865 // Use string.LastIndexOf(char) instead of string.LastIndexOf(string) when you have string with a single char - clusterArn = $"{baseArn}:cluster/{clusterArn}"; } var resourceAttributes = new List>() diff --git a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index b32ef0f2df..d28d0fc434 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -137,7 +137,7 @@ private static bool IsEKSProcess(string credentials, HttpClientHandler? httpClie string? awsAuth = null; try { - awsAuth = ResourceDetectorUtils.SendOutRequest(AWSAuthUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; + awsAuth = AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync(AWSAuthUrl, HttpMethod.Get, new KeyValuePair("Authorization", credentials), httpClientHandler)); } catch (Exception ex) { @@ -149,7 +149,7 @@ private static bool IsEKSProcess(string credentials, HttpClientHandler? httpClie private static string GetEKSClusterInfo(string credentials, HttpClientHandler? httpClientHandler) { - return ResourceDetectorUtils.SendOutRequest(AWSClusterInfoUrl, "GET", new KeyValuePair("Authorization", credentials), httpClientHandler).Result; + return AsyncHelper.RunSync(() => ResourceDetectorUtils.SendOutRequestAsync(AWSClusterInfoUrl, HttpMethod.Get, new KeyValuePair("Authorization", credentials), httpClientHandler)); } } #endif diff --git a/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs b/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs new file mode 100644 index 0000000000..f999beff0e --- /dev/null +++ b/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Resources.AWS; + +/// +/// A helper class for running asynchronous methods synchronously. +/// +internal static class AsyncHelper +{ + private static readonly TaskFactory TaskFactory = new TaskFactory( + CancellationToken.None, + TaskCreationOptions.None, + TaskContinuationOptions.None, + TaskScheduler.Default); + + /// + /// Executes an async task which has a void return value synchronously. + /// + /// The async task to execute. + public static void RunSync(Func task) + { + TaskFactory + .StartNew(() => task(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default) + .Unwrap() + .GetAwaiter() + .GetResult(); + } + + /// + /// Executes an async task which has a TResult return value synchronously. + /// + /// The return type of the task. + /// The async task to execute. + /// The result of the executed task. + public static TResult RunSync(Func> task) + { + return TaskFactory + .StartNew(() => task(), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default) + .Unwrap() + .GetAwaiter() + .GetResult(); + } +} diff --git a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs index 0c4318e5c7..ab957e7539 100644 --- a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs @@ -21,12 +21,16 @@ internal static class ResourceDetectorUtils private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); #endif - internal static async Task SendOutRequest(string url, string method, KeyValuePair? header, HttpClientHandler? handler = null) + internal static async Task SendOutRequestAsync( + string url, + HttpMethod method, + KeyValuePair? header, + HttpClientHandler? handler = null) { using (var httpRequestMessage = new HttpRequestMessage()) { httpRequestMessage.RequestUri = new Uri(url); - httpRequestMessage.Method = new HttpMethod(method); + httpRequestMessage.Method = method; if (header.HasValue) { httpRequestMessage.Headers.Add(header.Value.Key, header.Value.Value); @@ -61,7 +65,7 @@ internal static async Task SendOutRequest(string url, string method, Key { using (var stream = GetStream(filePath)) { - return (T?)JsonSerializer.Deserialize(stream, typeof(T), JsonSerializerOptions); + return JsonSerializer.Deserialize(stream, JsonSerializerOptions); } } diff --git a/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs b/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs new file mode 100644 index 0000000000..1bf9aafd6b --- /dev/null +++ b/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs @@ -0,0 +1,107 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Xunit; + +namespace OpenTelemetry.Resources.AWS.Tests; + +public class AsyncHelperTests +{ + [Fact] + public void RunSyncTaskCompletesSuccessfully() + { + // Arrange + Func task = async () => + { + await Task.Delay(100); + }; + + // Act + var exception = Record.Exception(() => AsyncHelper.RunSync(task)); + + // Assert + Assert.Null(exception); + } + + [Fact] + public void RunSyncTaskThrowsException() + { + // Arrange + Func task = async () => + { + await Task.Delay(100); + throw new InvalidOperationException("Test exception"); + }; + + // Act & Assert + var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + Assert.Equal("Test exception", exception.Message); + } + + [Fact] + public void RunSyncTaskCancellationThrowsTaskCanceledException() + { + // Arrange + var cts = new CancellationTokenSource(); + cts.Cancel(); + + Func task = async () => + { + await Task.Delay(100, cts.Token); + }; + + // Act & Assert + var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + Assert.Equal(cts.Token, exception.CancellationToken); + } + + [Fact] + public void RunSyncTaskWithResultCompletesSuccessfully() + { + // Arrange + Func> task = async () => + { + await Task.Delay(100); + return "Completed"; + }; + + // Act + var result = AsyncHelper.RunSync(task); + + // Assert + Assert.Equal("Completed", result); + } + + [Fact] + public void RunSyncTaskWithResultThrowsException() + { + // Arrange + Func> task = async () => + { + await Task.Delay(100); + throw new InvalidOperationException("Test exception"); + }; + + // Act & Assert + var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + Assert.Equal("Test exception", exception.Message); + } + + [Fact] + public void RunSyncTaskWithResultCancellationThrowsTaskCanceledException() + { + // Arrange + var cts = new CancellationTokenSource(); + cts.Cancel(); + + Func> task = async () => + { + await Task.Delay(100, cts.Token); + return "Completed"; + }; + + // Act & Assert + var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + Assert.Equal(cts.Token, exception.CancellationToken); + } +} From a6d5629ad6b7cf1f0e6ba1359b578c6aadbf529e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 28 Jun 2024 09:30:14 -0700 Subject: [PATCH 1169/1499] [infra] Automation sync-up with main repo (#1931) --- .github/workflows/core-version-update.yml | 1 + .github/workflows/prepare-release.yml | 41 ++++++++ build/scripts/post-release.psm1 | 34 +++--- build/scripts/prepare-release.psm1 | 121 ++++++++++++++++++++++ 4 files changed, 180 insertions(+), 17 deletions(-) diff --git a/.github/workflows/core-version-update.yml b/.github/workflows/core-version-update.yml index e97787b976..cf3d1019f3 100644 --- a/.github/workflows/core-version-update.yml +++ b/.github/workflows/core-version-update.yml @@ -28,6 +28,7 @@ jobs: with: ref: ${{ github.event.repository.default_branch }} token: ${{ secrets[needs.automation.outputs.token-secret-name] }} + - name: Setup dotnet uses: actions/setup-dotnet@v4 diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index eea3b61943..f855656280 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -92,6 +92,7 @@ jobs: -gitRepository '${{ github.repository }}' ` -component '${{ inputs.component }}' ` -version '${{ inputs.version }}' ` + -requestedByUserName '${{ github.event.sender.login }}' ` -targetBranch '${{ github.ref_name }}' ` -gitUserName '${{ needs.automation.outputs.username }}' ` -gitUserEmail '${{ needs.automation.outputs.email }}' @@ -166,3 +167,43 @@ jobs: -botUserName '${{ needs.automation.outputs.username }}' ` -gitUserName '${{ needs.automation.outputs.username }}' ` -gitUserEmail '${{ needs.automation.outputs.email }}' + + update-changelog-release-dates-on-prepare-pr-post-notice: + runs-on: ubuntu-latest + + needs: automation + + if: | + github.event_name == 'issue_comment' + && github.event.issue.pull_request + && github.event.issue.state == 'open' + && github.event.comment.user.login != needs.automation.outputs.username + && contains(github.event.comment.body, '/UpdateReleaseDates') + && startsWith(github.event.issue.title, '[release] Prepare release ') + && github.event.issue.pull_request.merged_at == null + && needs.automation.outputs.enabled + + env: + GH_TOKEN: ${{ secrets[needs.automation.outputs.token-secret-name] }} + + steps: + - name: check out code + uses: actions/checkout@v4 + 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: Update release date + id: create-tag + shell: pwsh + run: | + Import-Module .\build\scripts\prepare-release.psm1 + + UpdateChangelogReleaseDatesAndPostNoticeOnPullRequest ` + -gitRepository '${{ github.repository }}' ` + -pullRequestNumber '${{ github.event.issue.number }}' ` + -botUserName '${{ needs.automation.outputs.username }}' ` + -commentUserName '${{ github.event.comment.user.login }}' ` + -gitUserName '${{ needs.automation.outputs.username }}' ` + -gitUserEmail '${{ needs.automation.outputs.email }}' diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index 0cc7e96fd7..13ae216a04 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -301,10 +301,25 @@ function CreateOpenTelemetryCoreLatestVersionUpdatePullRequest { Return } - $projectsAndDependenciesBefore = GetCoreDependenciesForProjects - $branch="release/post-core-${version}-update" + 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) + { + throw 'git switch failure' + } + + $projectsAndDependenciesBefore = GetCoreDependenciesForProjects + (Get-Content build/Common.props) ` -replace "<$propertyName>.*<\/$propertyName>", "<$propertyName>$propertyVersion" | Set-Content build/Common.props @@ -328,21 +343,6 @@ function CreateOpenTelemetryCoreLatestVersionUpdatePullRequest { } } - 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) - { - throw 'git switch failure' - } - git add build/Common.props 2>&1 | % ToString if ($LASTEXITCODE -gt 0) { diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index f567987878..8bc8c4397c 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -3,11 +3,18 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis { [Parameter(Mandatory=$true)][string]$gitRepository, [Parameter(Mandatory=$true)][string]$component, [Parameter(Mandatory=$true)][string]$version, + [Parameter(Mandatory=$true)][string]$requestedByUserName, [Parameter()][string]$targetBranch="main", [Parameter()][string]$gitUserName, [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' + } + $projectContent = Get-Content -Path src/$component/$component.csproj $match = [regex]::Match($projectContent, '(.*)<\/MinVerTagPrefix>') @@ -39,6 +46,8 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis { @" Note: This PR was opened automatically by the [prepare release workflow](https://github.com/$gitRepository/actions/workflows/prepare-release.yml). +Requested by: @$requestedByUserName + ## Changes * CHANGELOG files updated for projects being released. @@ -55,6 +64,15 @@ Note: This PR was opened automatically by the [prepare release workflow](https:/ $body += "`r`n* Public API files updated for projects being released (only performed for stable releases)." } + $body += +@" + +## Commands + +``/UpdateReleaseDates``: Use to update release dates in CHANGELOGs before merging [``approvers``, ``maintainers``] +``/CreateReleaseTag``: Use after merging to push the release tag and trigger the job to create packages and push to NuGet [``approvers``, ``maintainers``] +"@ + git commit -a -m "Prepare repo to release $tag." 2>&1 | % ToString if ($LASTEXITCODE -gt 0) { @@ -183,3 +201,106 @@ The [package workflow](https://github.com/$gitRepository/actions/workflows/publi } Export-ModuleMember -Function CreateReleaseTagAndPostNoticeOnPullRequest + +function UpdateChangelogReleaseDatesAndPostNoticeOnPullRequest { + param( + [Parameter(Mandatory=$true)][string]$gitRepository, + [Parameter(Mandatory=$true)][string]$pullRequestNumber, + [Parameter(Mandatory=$true)][string]$botUserName, + [Parameter(Mandatory=$true)][string]$commentUserName, + [Parameter()][string]$gitUserName, + [Parameter()][string]$gitUserEmail + ) + + $prViewResponse = gh pr view $pullRequestNumber --json headRefName,author,title | ConvertFrom-Json + + if ($prViewResponse.author.login -ne $botUserName) + { + throw 'PR author was unexpected' + } + + $match = [regex]::Match($prViewResponse.title, '^\[release\] Prepare release (.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse tag from PR title' + } + + $tag = $match.Groups[1].Value + + $match = [regex]::Match($tag, '^(.*?-)(.*)$') + if ($match.Success -eq $false) + { + throw 'Could not parse prefix or version from tag' + } + + $tagPrefix = $match.Groups[1].Value + $version = $match.Groups[2].Value + + $commentUserPermission = gh api "repos/$gitRepository/collaborators/$commentUserName/permission" | ConvertFrom-Json + if ($commentUserPermission.permission -ne 'admin' -and $commentUserPermission.permission -ne 'write') + { + gh pr comment $pullRequestNumber ` + --body "I'm sorry @$commentUserName but you don't have permission to update this PR. Only maintainers and approvers can update this PR." + return + } + + if ([string]::IsNullOrEmpty($gitUserName) -eq $false) + { + git config user.name $gitUserName + } + if ([string]::IsNullOrEmpty($gitUserEmail) -eq $false) + { + git config user.email $gitUserEmail + } + + git switch $prViewResponse.headRefName 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git switch failure' + } + + $updatedFiles = 0 + $newHeader = +@" +## $version + +Released $(Get-Date -UFormat '%Y-%b-%d') +"@ + + $projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "$tagPrefix" -List | Select Path | Split-Path -Parent + + foreach ($projectDir in $projectDirs) + { + $content = (Get-Content "$projectDir/CHANGELOG.md" -Raw) + + $newContent = $content -replace "## $version\s*Released .*", $newHeader + + if ($content -ne $newContent) + { + $updatedFiles++ + Set-Content -Path "$projectDir/CHANGELOG.md" $newContent.Trim() + } + } + + if ($updatedFiles -eq 0) + { + gh pr comment $pullRequestNumber --body "All of the CHANGELOG files have valid release dates." + return + } + + git commit -a -m "Update CHANGELOG release dates for $tag." 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git commit failure' + } + + git push -u origin $prViewResponse.headRefName 2>&1 | % ToString + if ($LASTEXITCODE -gt 0) + { + throw 'git push failure' + } + + gh pr comment $pullRequestNumber --body "I updated the CHANGELOG release dates." +} + +Export-ModuleMember -Function UpdateChangelogReleaseDatesAndPostNoticeOnPullRequest From 4c69afa2fbb3b9d84b45bd73dcfad43331516e69 Mon Sep 17 00:00:00 2001 From: Arvin Kahbazi Date: Sat, 29 Jun 2024 11:06:49 +0330 Subject: [PATCH 1170/1499] [Instrumentation.StackExchangeRedis] Support when IConnectionMultiplexer is added with keyed service (#1885) 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.Unshipped.txt | 4 +- .../CHANGELOG.md | 4 ++ .../TracerProviderBuilderExtensions.cs | 49 +++++++++++++++++-- ...kExchangeRedisCallsInstrumentationTests.cs | 23 ++++++--- 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Unshipped.txt index c76bae94e0..a8e6e1c363 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/.publicApi/PublicAPI.Unshipped.txt @@ -14,9 +14,11 @@ OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentati OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisInstrumentationOptions.StackExchangeRedisInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, object! serviceKey) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, StackExchange.Redis.IConnectionMultiplexer! connection, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, object! serviceKey, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, StackExchange.Redis.IConnectionMultiplexer? connection, object? serviceKey, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.ConfigureRedisInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index c06d7ff476..031a6df25c 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Add support for instrumenting `IConnectionMultiplexer` + which is added with service key. + ([#1885](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1885)) + ## 1.0.0-rc9.15 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs index ccd7391b21..d9a450a2a6 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/TracerProviderBuilderExtensions.cs @@ -26,7 +26,7 @@ public static class TracerProviderBuilderExtensions /// The instance of to chain the calls. public static TracerProviderBuilder AddRedisInstrumentation( this TracerProviderBuilder builder) - => AddRedisInstrumentation(builder, name: null, connection: null, configure: null); + => AddRedisInstrumentation(builder, name: null, connection: null, configure: null, serviceKey: null); /// /// Enables automatic data collection of outgoing requests to Redis. @@ -40,7 +40,42 @@ public static TracerProviderBuilder AddRedisInstrumentation( { Guard.ThrowIfNull(connection); - return AddRedisInstrumentation(builder, name: null, connection, configure: null); + return AddRedisInstrumentation(builder, name: null, connection, configure: null, serviceKey: null); + } + + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// being configured. + /// Optional service key used to retrieve the to instrument from the . + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + object serviceKey) + { + Guard.ThrowIfNull(serviceKey); + + return AddRedisInstrumentation(builder, name: null, connection: null, serviceKey, configure: null); + } + + /// + /// Enables automatic data collection of outgoing requests to Redis. + /// + /// being configured. + /// Optional name which is used when retrieving options. + /// Optional service key used to retrieve the to instrument from the . + /// Callback to configure options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddRedisInstrumentation( + this TracerProviderBuilder builder, + string? name, + object serviceKey, + Action configure) + { + Guard.ThrowIfNull(serviceKey); + Guard.ThrowIfNull(configure); + + return AddRedisInstrumentation(builder, name: name, connection: null, serviceKey, configure); } /// @@ -59,7 +94,7 @@ public static TracerProviderBuilder AddRedisInstrumentation( { Guard.ThrowIfNull(configure); - return AddRedisInstrumentation(builder, name: null, connection: null, configure); + return AddRedisInstrumentation(builder, name: null, connection: null, serviceKey: null, configure); } /// @@ -77,7 +112,7 @@ public static TracerProviderBuilder AddRedisInstrumentation( Guard.ThrowIfNull(connection); Guard.ThrowIfNull(configure); - return AddRedisInstrumentation(builder, name: null, connection, configure); + return AddRedisInstrumentation(builder, name: null, connection, serviceKey: null, configure); } /// @@ -91,12 +126,14 @@ public static TracerProviderBuilder AddRedisInstrumentation( /// being configured. /// Optional name which is used when retrieving options. /// Optional to instrument. + /// Optional service key used to retrieve the to instrument from the . /// Optional callback to configure options. /// The instance of to chain the calls. public static TracerProviderBuilder AddRedisInstrumentation( this TracerProviderBuilder builder, string? name, IConnectionMultiplexer? connection, + object? serviceKey, Action? configure) { Guard.ThrowIfNull(builder); @@ -119,7 +156,9 @@ public static TracerProviderBuilder AddRedisInstrumentation( { var instrumentation = sp.GetRequiredService(); - connection ??= sp.GetService(); + connection ??= serviceKey == null + ? sp.GetService() + : sp.GetKeyedService(serviceKey); if (connection != null) { diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 198c5c4613..62487bf2d7 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -82,8 +82,9 @@ public void SuccessfulCommandTestWithKey(string value) [Trait("CategoryName", "RedisIntegrationTests")] [SkipUnlessEnvVarFoundTheory(RedisEndPointEnvVarName)] - [InlineData("value1")] - public void SuccessfulCommandTest(string value) + [InlineData("value1", null)] + [InlineData("value1", "serviceKey")] + public void SuccessfulCommandTest(string value, string? serviceKey) { var connectionOptions = new ConfigurationOptions { @@ -97,14 +98,24 @@ public void SuccessfulCommandTest(string value) using (Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => { - services.TryAddSingleton(sp => + if (serviceKey is null) + { + services.TryAddSingleton(sp => + { + return connection = ConnectionMultiplexer.Connect(connectionOptions); + }); + } + else { - return connection = ConnectionMultiplexer.Connect(connectionOptions); - }); + services.TryAddKeyedSingleton(serviceKey, (sp, key) => + { + return connection = ConnectionMultiplexer.Connect(connectionOptions); + }); + } }) .AddInMemoryExporter(exportedItems) .SetSampler(sampler) - .AddRedisInstrumentation(c => c.SetVerboseDatabaseStatements = false) + .AddRedisInstrumentation(null, null, serviceKey, c => c.SetVerboseDatabaseStatements = false) .Build()) { Assert.NotNull(connection); From 92f4b83755189a5d104a3535c9decbae5f4681e6 Mon Sep 17 00:00:00 2001 From: Guillaume Delahaye <681739+g7ed6e@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:15:54 +0200 Subject: [PATCH 1171/1499] Add ConfluentKafka instrumentation (#1493) Co-authored-by: Mikel Blanchard --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + .github/codecov.yml | 5 + .github/component_owners.yml | 4 + .github/workflows/ci.yml | 26 ++ .github/workflows/integration.yml | 20 +- .github/workflows/prepare-release.yml | 1 + build/Common.props | 1 + ...emetry.Instrumentation.ConfluentKafka.proj | 34 ++ examples/kafka/Constants.cs | 9 + examples/kafka/Examples.ConfluentKafka.csproj | 17 + examples/kafka/ProduceConsumeHostedService.cs | 53 +++ examples/kafka/Program.cs | 50 +++ examples/kafka/README.md | 13 + opentelemetry-dotnet-contrib.sln | 28 ++ .../.publicApi/PublicAPI.Shipped.txt | 2 + .../.publicApi/PublicAPI.Unshipped.txt | 20 + .../AssemblyInfo.cs | 18 + .../CHANGELOG.md | 5 + .../ConfluentKafkaCommon.cs | 21 + .../ConfluentKafkaConsumerInstrumentation.cs | 18 + ...uentKafkaConsumerInstrumentationOptions.cs | 11 + .../ConfluentKafkaProducerInstrumentation.cs | 18 + ...uentKafkaProducerInstrumentationOptions.cs | 11 + .../InstrumentedConsumer.cs | 404 ++++++++++++++++++ .../InstrumentedConsumerBuilder.cs | 46 ++ .../InstrumentedProducer.cs | 370 ++++++++++++++++ .../InstrumentedProducerBuilder.cs | 43 ++ ...MeterProviderBuilderExtensions.Consumer.cs | 90 ++++ ...MeterProviderBuilderExtensions.Producer.cs | 90 ++++ ...etry.Instrumentation.ConfluentKafka.csproj | 35 ++ .../README.md | 11 + ...racerProviderBuilderExtensions.Consumer.cs | 90 ++++ ...racerProviderBuilderExtensions.Producer.cs | 90 ++++ src/Shared/SemanticConventions.cs | 20 + .../Dockerfile | 19 + .../HostedMeteringTests.cs | 101 +++++ .../HostedTracingAndMeteringTests.cs | 115 +++++ .../HostedTracingTests.cs | 96 +++++ .../KafkaHelpers.cs | 30 ++ .../MeterProviderExtensions.cs | 19 + .../MeteringTests.cs | 135 ++++++ ...nstrumentation.ConfluentKafka.Tests.csproj | 28 ++ .../ProducerExtensions.cs | 17 + .../TracingTests.cs | 305 +++++++++++++ .../docker-compose.yml | 24 ++ 46 files changed, 2564 insertions(+), 1 deletion(-) create mode 100644 build/Projects/OpenTelemetry.Instrumentation.ConfluentKafka.proj create mode 100644 examples/kafka/Constants.cs create mode 100644 examples/kafka/Examples.ConfluentKafka.csproj create mode 100644 examples/kafka/ProduceConsumeHostedService.cs create mode 100644 examples/kafka/Program.cs create mode 100644 examples/kafka/README.md create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeterProviderExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/ProducerExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 79cb5b92b7..26d7a172bf 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -30,6 +30,7 @@ body: - OpenTelemetry.Instrumentation.AWS - OpenTelemetry.Instrumentation.AWSLambda - OpenTelemetry.Instrumentation.Cassandra + - OpenTelemetry.Instrumentation.ConfluentKafka - OpenTelemetry.Instrumentation.ElasticsearchClient - OpenTelemetry.Instrumentation.EntityFrameworkCore - OpenTelemetry.Instrumentation.EventCounters diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 11b6f1362d..e48fec3575 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -30,6 +30,7 @@ body: - OpenTelemetry.Instrumentation.AWS - OpenTelemetry.Instrumentation.AWSLambda - OpenTelemetry.Instrumentation.Cassandra + - OpenTelemetry.Instrumentation.ConfluentKafka - OpenTelemetry.Instrumentation.ElasticsearchClient - OpenTelemetry.Instrumentation.EntityFrameworkCore - OpenTelemetry.Instrumentation.EventCounters diff --git a/.github/codecov.yml b/.github/codecov.yml index 0d3bda059b..a8f7fd2412 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -63,6 +63,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.AspNetCore + unittests-Instrumentation.ConfluentKafka: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.ConfluentKafka + unittests-Instrumentation.EventCounters: carryforward: true paths: diff --git a/.github/component_owners.yml b/.github/component_owners.yml index b7c252688e..d4a5aa9ca3 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -35,6 +35,8 @@ components: - ppittle src/OpenTelemetry.Instrumentation.Cassandra/: - xsoheilalizadeh + src/OpenTelemetry.Instrumentation.ConfluentKafka/: + - g7ed6e src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith src/OpenTelemetry.Instrumentation.EventCounters/: @@ -130,6 +132,8 @@ components: - ppittle test/OpenTelemetry.Instrumentation.Cassandra.Tests/: - xsoheilalizadeh + test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/: + - g7ed6e test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith test/OpenTelemetry.Instrumentation.EventCounters.Tests/: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ceea50c2e..1f0778213e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,7 @@ jobs: instrumentation-aws: ['*/OpenTelemetry.Instrumentation.AWS/**', '*/OpenTelemetry.Instrumentation.AWS.Tests/**', '!**/*.md'] instrumentation-aws-lambda: ['*/OpenTelemetry.Instrumentation.AWSLambda/**', '*/OpenTelemetry.Instrumentation.AWSLambda.Tests/**', '!**/*.md'] instrumentation-cassandra: ['*/OpenTelemetry.Instrumentation.Cassandra*/**', '!**/*.md'] + instrumentation-confluentkafka: ['*/OpenTelemetry.Instrumentation.ConfluentKafka*/**', 'examples/kafka/**', '!**/*.md'] instrumentation-elasticsearchclient: ['*/OpenTelemetry.Instrumentation.ElasticsearchClient*/**', '!**/*.md'] instrumentation-entityframeworkcore: ['*/OpenTelemetry.Instrumentation.EntityFrameworkCore*/**', '!**/*.md'] instrumentation-eventcounters: ['*/OpenTelemetry.Instrumentation.EventCounters*/**', 'examples/event-counters/**', '!**/*.md'] @@ -222,6 +223,27 @@ jobs: project-name: Component[OpenTelemetry.Instrumentation.Cassandra] code-cov-name: Instrumentation.Cassandra + build-test-instrumentation-confluentkafka: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'instrumentation-confluentkafka') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Instrumentation.ConfluentKafka] + code-cov-name: Instrumentation.ConfluentKafka + + build-test-instrumentation-confluentkafka-integration: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'instrumentation-confluentkafka') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/integration.yml + with: + job: kafka-integration-test + build-test-instrumentation-elasticsearchclient: needs: detect-changes if: | @@ -375,6 +397,8 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/integration.yml + with: + job: redis-integration-test build-test-instrumentation-wcf: needs: detect-changes @@ -518,6 +542,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'instrumentation-aspnetcore') || contains(needs.detect-changes.outputs.changes, 'instrumentation-aws') || contains(needs.detect-changes.outputs.changes, 'instrumentation-awslambda') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-confluentkafka') || contains(needs.detect-changes.outputs.changes, 'instrumentation-eventcounters') || contains(needs.detect-changes.outputs.changes, 'instrumentation-grpcnetclient') || contains(needs.detect-changes.outputs.changes, 'instrumentation-http') @@ -556,6 +581,7 @@ jobs: build-test-instrumentation-aws, build-test-instrumentation-awslambda, build-test-instrumentation-cassandra, + build-test-instrumentation-confluentkafka, build-test-instrumentation-elasticsearchclient, build-test-instrumentation-entityframeworkcore, build-test-instrumentation-eventcounters, diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 17fc8a9da9..d139ad213b 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -2,9 +2,14 @@ name: Integration Build OpenTelemetry.Instrumentation.StackExchangeRedis on: workflow_call: + inputs: + job: + required: true + type: string jobs: redis-integration-test: + if: inputs.job == 'all' || inputs.job == 'redis-integration-test' runs-on: ubuntu-latest strategy: fail-fast: false @@ -13,5 +18,18 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Run redis docker-compose.integration + - name: Run redis docker-compose run: docker-compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build + + kafka-integration-test: + if: inputs.job == 'all' || inputs.job == 'kafka-integration-test' + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + version: [net6.0, net7.0, net8.0] + steps: + - uses: actions/checkout@v4 + + - name: Run kafka docker-compose + run: docker-compose --file=test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index f855656280..b0673ac73a 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -20,6 +20,7 @@ on: - OpenTelemetry.Instrumentation.AWS - OpenTelemetry.Instrumentation.AWSLambda - OpenTelemetry.Instrumentation.Cassandra + - OpenTelemetry.Instrumentation.ConfluentKafka - OpenTelemetry.Instrumentation.ElasticsearchClient - OpenTelemetry.Instrumentation.EntityFrameworkCore - OpenTelemetry.Instrumentation.EventCounters diff --git a/build/Common.props b/build/Common.props index 5fc436b894..3cf54473e1 100644 --- a/build/Common.props +++ b/build/Common.props @@ -43,6 +43,7 @@ [1.9.0,2.0) [1.9.0-rc.1] [2.1.58,3.0) + [2.3.0,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) [4.3.4,) diff --git a/build/Projects/OpenTelemetry.Instrumentation.ConfluentKafka.proj b/build/Projects/OpenTelemetry.Instrumentation.ConfluentKafka.proj new file mode 100644 index 0000000000..0d0a145639 --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.ConfluentKafka.proj @@ -0,0 +1,34 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.ConfluentKafka- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/kafka/Constants.cs b/examples/kafka/Constants.cs new file mode 100644 index 0000000000..af3cf026c4 --- /dev/null +++ b/examples/kafka/Constants.cs @@ -0,0 +1,9 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace Examples.ConfluentKafka; + +public static class Constants +{ + public static readonly string Topic = $"test-topic-{Guid.NewGuid()}"; +} diff --git a/examples/kafka/Examples.ConfluentKafka.csproj b/examples/kafka/Examples.ConfluentKafka.csproj new file mode 100644 index 0000000000..b9ce8848cb --- /dev/null +++ b/examples/kafka/Examples.ConfluentKafka.csproj @@ -0,0 +1,17 @@ + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/examples/kafka/ProduceConsumeHostedService.cs b/examples/kafka/ProduceConsumeHostedService.cs new file mode 100644 index 0000000000..04d14dd893 --- /dev/null +++ b/examples/kafka/ProduceConsumeHostedService.cs @@ -0,0 +1,53 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; + +namespace Examples.ConfluentKafka; + +public class ProduceConsumeHostedService( + InstrumentedProducerBuilder instrumentedProducerBuilder, + InstrumentedConsumerBuilder instrumentedConsumerBuilder) + : BackgroundService +{ + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + IProducer producer = instrumentedProducerBuilder.Build(); + IConsumer consumer = instrumentedConsumerBuilder.Build(); + + for (int j = 0; j < 100; j++) + { + await producer.ProduceAsync( + Constants.Topic, + new Message { Key = "any_key", Value = $"any_value_{j}" }, + stoppingToken); + } + + for (int j = 0; j < 100; j++) + { + producer.Produce( + Constants.Topic, + new Message { Key = "any_key", Value = $"any_value_{j}" }); + } + + producer.Flush(stoppingToken); + + consumer.Subscribe(Constants.Topic); + while (!stoppingToken.IsCancellationRequested) + { + ConsumeResult consumeResult = consumer.Consume(stoppingToken); + if (consumeResult == null) + { + continue; + } + + if (consumeResult.IsPartitionEOF) + { + break; + } + + Console.WriteLine($"Consumer {consumer.Name} received message: {consumeResult.Message.Value}"); + } + } +} diff --git a/examples/kafka/Program.cs b/examples/kafka/Program.cs new file mode 100644 index 0000000000..fe9c6dbcdd --- /dev/null +++ b/examples/kafka/Program.cs @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using Examples.ConfluentKafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +var builder = Host.CreateApplicationBuilder(args); + +const string bootstrapServers = "localhost:9092"; + +builder.Services.AddSingleton(_ => +{ + ProducerConfig producerConfig = new() { BootstrapServers = bootstrapServers }; + return new InstrumentedProducerBuilder(producerConfig); +}); +builder.Services.AddSingleton(_ => +{ + ConsumerConfig consumerConfigA = new() + { + BootstrapServers = bootstrapServers, + GroupId = "group-a", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + return new InstrumentedConsumerBuilder(consumerConfigA); +}); + +builder.Services.AddOpenTelemetry() + .WithTracing(tracing => + { + tracing.AddConsoleExporter() + .AddOtlpExporter() + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }) + .WithMetrics(metering => + { + metering.AddConsoleExporter() + .AddOtlpExporter() + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }); + +builder.Services.AddHostedService(); + +var app = builder.Build(); +await app.RunAsync(); diff --git a/examples/kafka/README.md b/examples/kafka/README.md new file mode 100644 index 0000000000..02f594480e --- /dev/null +++ b/examples/kafka/README.md @@ -0,0 +1,13 @@ +# Run Examples.ConfluentKafka + +Start the Confluent Kafka stack: + +```cmd +docker run -d --name kafka -p 9092:9092 confluentinc/confluent-local +``` + +Start the Aspire Dashboard: + +```cmd +docker run --rm -it -p 18888:18888 -p 4317:18889 -d --name aspire-dashboard mcr.microsoft.com/dotnet/nightly/aspire-dashboard:8.0.0 +``` diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f0a4560077..f7508674db 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -287,9 +287,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 ProjectSection(SolutionItems) = preProject build\Projects\Component.proj = build\Projects\Component.proj build\Projects\OpenTelemetry.Contrib.Shared.Tests.proj = build\Projects\OpenTelemetry.Contrib.Shared.Tests.proj + build\Projects\OpenTelemetry.Exporter.InfluxDB.proj = build\Projects\OpenTelemetry.Exporter.InfluxDB.proj + build\Projects\OpenTelemetry.Extensions.Enrichment.proj = build\Projects\OpenTelemetry.Extensions.Enrichment.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj = build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj + build\Projects\OpenTelemetry.Instrumentation.ConfluentKafka.proj = build\Projects\OpenTelemetry.Instrumentation.ConfluentKafka.proj build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj + build\Projects\OpenTelemetry.Instrumentation.GrpcCore.proj = build\Projects\OpenTelemetry.Instrumentation.GrpcCore.proj build\Projects\OpenTelemetry.Instrumentation.Owin.proj = build\Projects\OpenTelemetry.Instrumentation.Owin.proj build\Projects\OpenTelemetry.Instrumentation.Process.proj = build\Projects\OpenTelemetry.Instrumentation.Process.proj build\Projects\OpenTelemetry.Instrumentation.Runtime.proj = build\Projects\OpenTelemetry.Instrumentation.Runtime.proj @@ -377,6 +381,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEM .github\ISSUE_TEMPLATE\feature_request.yml = .github\ISSUE_TEMPLATE\feature_request.yml EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ConfluentKafka", "src\OpenTelemetry.Instrumentation.ConfluentKafka\OpenTelemetry.Instrumentation.ConfluentKafka.csproj", "{96341E23-990E-4144-A7E3-9EF0DAFF3232}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ConfluentKafka.Tests", "test\OpenTelemetry.Instrumentation.ConfluentKafka.Tests\OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj", "{BE40900A-2859-471D-8802-21DFD73DDAA7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kafka", "kafka", "{3A464E7A-42F3-44B0-B8D7-80521A7704A6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.ConfluentKafka", "examples\kafka\Examples.ConfluentKafka.csproj", "{9B994669-E839-4C42-A0F1-DF9DD058C1DC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -779,6 +791,18 @@ Global {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {B13394D6-D3D7-453E-B91A-24C199F41C5E}.Release|Any CPU.Build.0 = Release|Any CPU + {96341E23-990E-4144-A7E3-9EF0DAFF3232}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96341E23-990E-4144-A7E3-9EF0DAFF3232}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96341E23-990E-4144-A7E3-9EF0DAFF3232}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96341E23-990E-4144-A7E3-9EF0DAFF3232}.Release|Any CPU.Build.0 = Release|Any CPU + {BE40900A-2859-471D-8802-21DFD73DDAA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE40900A-2859-471D-8802-21DFD73DDAA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE40900A-2859-471D-8802-21DFD73DDAA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE40900A-2859-471D-8802-21DFD73DDAA7}.Release|Any CPU.Build.0 = Release|Any CPU + {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -899,6 +923,10 @@ Global {70CA77D4-5D7F-4D70-A6B5-8AAC07A8EA3C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {45D29DAA-0DB9-4808-B879-1AECC37EF366} = {824BD1DE-3FA8-4FE0-823A-FD365EAC78AF} {40373C78-0513-4067-A96B-96A851369761} = {1A06E14B-DD2F-4536-9D2E-F708C0C43555} + {96341E23-990E-4144-A7E3-9EF0DAFF3232} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {BE40900A-2859-471D-8802-21DFD73DDAA7} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {3A464E7A-42F3-44B0-B8D7-80521A7704A6} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} + {9B994669-E839-4C42-A0F1-DF9DD058C1DC} = {3A464E7A-42F3-44B0-B8D7-80521A7704A6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..074c6ad103 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1,2 @@ +#nullable enable + diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..d27211c49c --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,20 @@ +OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder +OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.InstrumentedConsumerBuilder(System.Collections.Generic.IEnumerable>! config) -> void +OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder +OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.InstrumentedProducerBuilder(System.Collections.Generic.IEnumerable>! config) -> void +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.Build() -> Confluent.Kafka.IConsumer! +override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.Build() -> Confluent.Kafka.IProducer! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/AssemblyInfo.cs new file mode 100644 index 0000000000..9bb32bb7a6 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/AssemblyInfo.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.ConfluentKafka.Tests" + AssemblyInfo.PublicKey)] + +#if SIGNED +internal static class AssemblyInfo +{ + public const string PublicKey = ", PublicKey=002400000480000094000000060200000024000052534131000400000100010051C1562A090FB0C9F391012A32198B5E5D9A60E9B80FA2D7B434C9E5CCB7259BD606E66F9660676AFC6692B8CDC6793D190904551D2103B7B22FA636DCBB8208839785BA402EA08FC00C8F1500CCEF28BBF599AA64FFB1E1D5DC1BF3420A3777BADFE697856E9D52070A50C3EA5821C80BEF17CA3ACFFA28F89DD413F096F898"; +} +#else +internal static class AssemblyInfo +{ + public const string PublicKey = ""; +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md new file mode 100644 index 0000000000..134621e04d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs new file mode 100644 index 0000000000..beb4c4812d --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Diagnostics.Metrics; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal static class ConfluentKafkaCommon +{ + internal static readonly string InstrumentationName = typeof(ConfluentKafkaCommon).Assembly.GetName().Name!; + internal static readonly string InstrumentationVersion = typeof(ConfluentKafkaCommon).Assembly.GetPackageVersion(); + internal static readonly ActivitySource ActivitySource = new(InstrumentationName, InstrumentationVersion); + internal static readonly Meter Meter = new(InstrumentationName, InstrumentationVersion); + internal static readonly Counter ReceiveMessagesCounter = Meter.CreateCounter(SemanticConventions.MetricMessagingReceiveMessages); + internal static readonly Histogram ReceiveDurationHistogram = Meter.CreateHistogram(SemanticConventions.MetricMessagingReceiveDuration); + internal static readonly Counter PublishMessagesCounter = Meter.CreateCounter(SemanticConventions.MetricMessagingPublishMessages); + internal static readonly Histogram PublishDurationHistogram = Meter.CreateHistogram(SemanticConventions.MetricMessagingPublishDuration); +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs new file mode 100644 index 0000000000..573b78d56b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal class ConfluentKafkaConsumerInstrumentation; + +#pragma warning disable SA1402 // File may only contain a single type +internal sealed class ConfluentKafkaConsumerInstrumentation : ConfluentKafkaConsumerInstrumentation +#pragma warning restore SA1402 // File may only contain a single type +{ + public ConfluentKafkaConsumerInstrumentation(InstrumentedConsumerBuilder consumerBuilder) + { + this.ConsumerBuilder = consumerBuilder; + } + + internal InstrumentedConsumerBuilder ConsumerBuilder { get; } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentationOptions.cs new file mode 100644 index 0000000000..c2a108c100 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentationOptions.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal class ConfluentKafkaConsumerInstrumentationOptions +{ + public bool Metrics { get; set; } + + public bool Traces { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs new file mode 100644 index 0000000000..13f71b1905 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal abstract class ConfluentKafkaProducerInstrumentation; + +#pragma warning disable SA1402 // File may only contain a single type +internal sealed class ConfluentKafkaProducerInstrumentation : ConfluentKafkaProducerInstrumentation +#pragma warning restore SA1402 // File may only contain a single type +{ + public ConfluentKafkaProducerInstrumentation(InstrumentedProducerBuilder producerBuilder) + { + this.ProducerBuilder = producerBuilder; + } + + internal InstrumentedProducerBuilder ProducerBuilder { get; } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentationOptions.cs new file mode 100644 index 0000000000..cb97821416 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentationOptions.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal class ConfluentKafkaProducerInstrumentationOptions +{ + public bool Metrics { get; set; } + + public bool Traces { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs new file mode 100644 index 0000000000..8fa5fa8b02 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs @@ -0,0 +1,404 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Text; +using Confluent.Kafka; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal class InstrumentedConsumer : IConsumer +{ + private const string ReceiveOperationName = "receive"; + private const string KafkaMessagingSystem = "kafka"; + private readonly IConsumer consumer; + private readonly ConfluentKafkaConsumerInstrumentationOptions options; + + public InstrumentedConsumer(IConsumer consumer, ConfluentKafkaConsumerInstrumentationOptions options) + { + this.consumer = consumer; + this.options = options; + } + + public Handle Handle => this.consumer.Handle; + + public string Name => this.consumer.Name; + + public string MemberId => this.consumer.MemberId; + + public List Assignment => this.consumer.Assignment; + + public List Subscription => this.consumer.Subscription; + + public IConsumerGroupMetadata ConsumerGroupMetadata => this.consumer.ConsumerGroupMetadata; + + public string? GroupId { get; internal set; } + + public void Dispose() + { + this.consumer.Dispose(); + } + + public int AddBrokers(string brokers) + { + return this.consumer.AddBrokers(brokers); + } + + public void SetSaslCredentials(string username, string password) + { + this.consumer.SetSaslCredentials(username, password); + } + + public ConsumeResult? Consume(int millisecondsTimeout) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + ConsumeResult? result = null; + ConsumeResult consumeResult = default; + string? errorType = null; + try + { + result = this.consumer.Consume(millisecondsTimeout); + consumeResult = ExtractConsumeResult(result); + return result; + } + catch (ConsumeException e) + { + (consumeResult, errorType) = ExtractConsumeResult(e); + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + if (result is { IsPartitionEOF: false }) + { + this.InstrumentConsumption(start, end, consumeResult, errorType); + } + } + } + + public ConsumeResult? Consume(CancellationToken cancellationToken = default) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + ConsumeResult? result = null; + ConsumeResult consumeResult = default; + string? errorType = null; + try + { + result = this.consumer.Consume(cancellationToken); + consumeResult = ExtractConsumeResult(result); + return result; + } + catch (ConsumeException e) + { + (consumeResult, errorType) = ExtractConsumeResult(e); + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + if (result is { IsPartitionEOF: false }) + { + this.InstrumentConsumption(start, end, consumeResult, errorType); + } + } + } + + public ConsumeResult? Consume(TimeSpan timeout) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + ConsumeResult? result = null; + ConsumeResult consumeResult = default; + string? errorType = null; + try + { + result = this.consumer.Consume(timeout); + consumeResult = ExtractConsumeResult(result); + return result; + } + catch (ConsumeException e) + { + (consumeResult, errorType) = ExtractConsumeResult(e); + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + if (result is { IsPartitionEOF: false }) + { + this.InstrumentConsumption(start, end, consumeResult, errorType); + } + } + } + + public void Subscribe(IEnumerable topics) + { + this.consumer.Subscribe(topics); + } + + public void Subscribe(string topic) + { + this.consumer.Subscribe(topic); + } + + public void Unsubscribe() + { + this.consumer.Unsubscribe(); + } + + public void Assign(TopicPartition partition) + { + this.consumer.Assign(partition); + } + + public void Assign(TopicPartitionOffset partition) + { + this.consumer.Assign(partition); + } + + public void Assign(IEnumerable partitions) + { + this.consumer.Assign(partitions); + } + + public void Assign(IEnumerable partitions) + { + this.consumer.Assign(partitions); + } + + public void IncrementalAssign(IEnumerable partitions) + { + this.consumer.IncrementalAssign(partitions); + } + + public void IncrementalAssign(IEnumerable partitions) + { + this.consumer.IncrementalAssign(partitions); + } + + public void IncrementalUnassign(IEnumerable partitions) + { + this.consumer.IncrementalUnassign(partitions); + } + + public void Unassign() + { + this.consumer.Unassign(); + } + + public void StoreOffset(ConsumeResult result) + { + this.consumer.StoreOffset(result); + } + + public void StoreOffset(TopicPartitionOffset offset) + { + this.consumer.StoreOffset(offset); + } + + public List Commit() + { + return this.consumer.Commit(); + } + + public void Commit(IEnumerable offsets) + { + this.consumer.Commit(offsets); + } + + public void Commit(ConsumeResult result) + { + this.consumer.Commit(result); + } + + public void Seek(TopicPartitionOffset tpo) + { + this.consumer.Seek(tpo); + } + + public void Pause(IEnumerable partitions) + { + this.consumer.Pause(partitions); + } + + public void Resume(IEnumerable partitions) + { + this.consumer.Resume(partitions); + } + + public List Committed(TimeSpan timeout) + { + return this.consumer.Committed(timeout); + } + + public List Committed(IEnumerable partitions, TimeSpan timeout) + { + return this.consumer.Committed(partitions, timeout); + } + + public Offset Position(TopicPartition partition) + { + return this.consumer.Position(partition); + } + + public List OffsetsForTimes(IEnumerable timestampsToSearch, TimeSpan timeout) + { + return this.consumer.OffsetsForTimes(timestampsToSearch, timeout); + } + + public WatermarkOffsets GetWatermarkOffsets(TopicPartition topicPartition) + { + return this.consumer.GetWatermarkOffsets(topicPartition); + } + + public WatermarkOffsets QueryWatermarkOffsets(TopicPartition topicPartition, TimeSpan timeout) + { + return this.consumer.QueryWatermarkOffsets(topicPartition, timeout); + } + + public void Close() + { + this.consumer.Close(); + } + + private static string FormatConsumeException(ConsumeException consumeException) => + $"ConsumeException: {consumeException.Error}"; + + private static PropagationContext ExtractPropagationContext(Headers? headers) + => Propagators.DefaultTextMapPropagator.Extract(default, headers, ExtractTraceContext); + + private static IEnumerable ExtractTraceContext(Headers? headers, string value) + { + if (headers?.TryGetLastBytes(value, out var bytes) == true) + { + yield return Encoding.UTF8.GetString(bytes); + } + } + + private static ConsumeResult ExtractConsumeResult(ConsumeResult result) => result switch + { + null => new ConsumeResult(null, null), + { Message: null } => new ConsumeResult(result.TopicPartitionOffset, null), + _ => new ConsumeResult(result.TopicPartitionOffset, result.Message.Headers, result.Message.Key), + }; + + private static (ConsumeResult ConsumeResult, string ErrorType) ExtractConsumeResult(ConsumeException exception) => exception switch + { + { ConsumerRecord: null } => (new ConsumeResult(null, null), FormatConsumeException(exception)), + { ConsumerRecord.Message: null } => (new ConsumeResult(exception.ConsumerRecord.TopicPartitionOffset, null), FormatConsumeException(exception)), + _ => (new ConsumeResult(exception.ConsumerRecord.TopicPartitionOffset, exception.ConsumerRecord.Message.Headers, exception.ConsumerRecord.Message.Key), FormatConsumeException(exception)), + }; + + private static void GetTags(string topic, out TagList tags, int? partition = null, string? errorType = null) + { + tags = new TagList() + { + new KeyValuePair( + SemanticConventions.AttributeMessagingOperation, + ReceiveOperationName), + new KeyValuePair( + SemanticConventions.AttributeMessagingSystem, + KafkaMessagingSystem), + new KeyValuePair( + SemanticConventions.AttributeMessagingDestinationName, + topic), + }; + + if (partition is not null) + { + tags.Add( + new KeyValuePair( + SemanticConventions.AttributeMessagingKafkaDestinationPartition, + partition)); + } + + if (errorType is not null) + { + tags.Add( + new KeyValuePair( + SemanticConventions.AttributeErrorType, + errorType)); + } + } + + private static void RecordReceive(TopicPartition topicPartition, TimeSpan duration, string? errorType = null) + { + GetTags(topicPartition.Topic, out var tags, partition: topicPartition.Partition, errorType); + + ConfluentKafkaCommon.ReceiveMessagesCounter.Add(1, in tags); + ConfluentKafkaCommon.ReceiveDurationHistogram.Record(duration.TotalSeconds, in tags); + } + + private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endTime, ConsumeResult consumeResult, string? errorType) + { + if (this.options.Traces) + { + PropagationContext propagationContext = consumeResult.Headers != null + ? ExtractPropagationContext(consumeResult.Headers) + : default; + + using Activity? activity = this.StartReceiveActivity(propagationContext, startTime, consumeResult.TopicPartitionOffset, consumeResult.Key); + if (activity != null) + { + if (errorType != null) + { + activity.SetStatus(ActivityStatusCode.Error); + if (activity.IsAllDataRequested) + { + activity.SetTag(SemanticConventions.AttributeErrorType, errorType); + } + } + + activity.SetEndTime(endTime.UtcDateTime); + } + } + + if (this.options.Metrics) + { + TimeSpan duration = endTime - startTime; + RecordReceive(consumeResult.TopicPartitionOffset!.TopicPartition, duration, errorType); + } + } + + private Activity? StartReceiveActivity(PropagationContext propagationContext, DateTimeOffset start, TopicPartitionOffset? topicPartitionOffset, object? key) + { + var spanName = string.IsNullOrEmpty(topicPartitionOffset?.Topic) + ? ReceiveOperationName + : string.Concat(topicPartitionOffset!.Topic, " ", ReceiveOperationName); + + ActivityLink[] activityLinks = propagationContext.ActivityContext.IsValid() + ? new[] { new ActivityLink(propagationContext.ActivityContext) } + : Array.Empty(); + + Activity? activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, startTime: start, parentContext: default); + if (activity?.IsAllDataRequested == true) + { + activity.SetTag(SemanticConventions.AttributeMessagingSystem, KafkaMessagingSystem); + activity.SetTag(SemanticConventions.AttributeMessagingClientId, this.Name); + activity.SetTag(SemanticConventions.AttributeMessagingDestinationName, topicPartitionOffset?.Topic); + activity.SetTag(SemanticConventions.AttributeMessagingKafkaDestinationPartition, topicPartitionOffset?.Partition.Value); + activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageOffset, topicPartitionOffset?.Offset.Value); + activity.SetTag(SemanticConventions.AttributeMessagingKafkaConsumerGroup, this.GroupId); + activity.SetTag(SemanticConventions.AttributeMessagingOperation, ReceiveOperationName); + if (key != null) + { + activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageKey, key); + } + } + + return activity; + } + + private readonly record struct ConsumeResult( + TopicPartitionOffset? TopicPartitionOffset, + Headers? Headers, + object? Key = null) + { + public object? Key { get; } = Key; + + public Headers? Headers { get; } = Headers; + + public TopicPartitionOffset? TopicPartitionOffset { get; } = TopicPartitionOffset; + } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs new file mode 100644 index 0000000000..93268ba5c7 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs @@ -0,0 +1,46 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Confluent.Kafka; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +/// +/// A builder of with support for instrumentation. +/// +/// Type of the key. +/// Type of value. +public sealed class InstrumentedConsumerBuilder : ConsumerBuilder +{ + /// + /// Initializes a new instance of the class. + /// + /// A collection of librdkafka configuration parameters (refer to https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md) and parameters specific to this client (refer to: ). At a minimum, 'bootstrap.servers' must be specified. + public InstrumentedConsumerBuilder(IEnumerable> config) + : base(config) + { + } + + internal ConfluentKafkaConsumerInstrumentationOptions? Options { get; set; } + + /// + /// Build a new IConsumer instance. + /// + /// an . + public override IConsumer Build() + { + Debug.Assert(this.Options != null, "Options should not be null."); + + ConsumerConfig config = (ConsumerConfig)this.Config; + if (this.Options!.Metrics) + { + config.StatisticsIntervalMs ??= 1000; + } + + var consumer = new InstrumentedConsumer(base.Build(), this.Options); + consumer.GroupId = config.GroupId; + + return consumer; + } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs new file mode 100644 index 0000000000..aa7d31ba48 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs @@ -0,0 +1,370 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Text; +using Confluent.Kafka; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal sealed class InstrumentedProducer : IProducer +{ + private const string PublishOperationName = "publish"; + private const string KafkaMessagingSystem = "kafka"; + + private readonly TextMapPropagator propagator = Propagators.DefaultTextMapPropagator; + private readonly IProducer producer; + private readonly ConfluentKafkaProducerInstrumentationOptions options; + + public InstrumentedProducer( + IProducer producer, + ConfluentKafkaProducerInstrumentationOptions options) + { + this.producer = producer; + this.options = options; + } + + public Handle Handle => this.producer.Handle; + + public string Name => this.producer.Name; + + internal ConfluentKafkaProducerInstrumentationOptions Options => this.options; + + public int AddBrokers(string brokers) + { + return this.producer.AddBrokers(brokers); + } + + public void SetSaslCredentials(string username, string password) + { + this.producer.SetSaslCredentials(username, password); + } + + public async Task> ProduceAsync( + string topic, + Message message, + CancellationToken cancellationToken = default) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + using Activity? activity = this.StartPublishActivity(start, topic, message); + if (activity != null) + { + this.InjectActivity(activity, message); + } + + DeliveryResult result; + string? errorType = null; + try + { + result = await this.producer.ProduceAsync(topic, message, cancellationToken).ConfigureAwait(false); + } + catch (ProduceException produceException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatProduceException(produceException)); + + throw; + } + catch (ArgumentException argumentException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatArgumentException(argumentException)); + + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + activity?.SetEndTime(end.UtcDateTime); + TimeSpan duration = end - start; + + if (this.options.Metrics) + { + RecordPublish(topic, duration, errorType); + } + } + + return result; + } + + public async Task> ProduceAsync( + TopicPartition topicPartition, + Message message, + CancellationToken cancellationToken = default) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + using Activity? activity = this.StartPublishActivity(start, topicPartition.Topic, message, topicPartition.Partition); + if (activity != null) + { + this.InjectActivity(activity, message); + } + + DeliveryResult result; + string? errorType = null; + try + { + result = await this.producer.ProduceAsync(topicPartition, message, cancellationToken).ConfigureAwait(false); + } + catch (ProduceException produceException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatProduceException(produceException)); + + throw; + } + catch (ArgumentException argumentException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatArgumentException(argumentException)); + + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + activity?.SetEndTime(end.UtcDateTime); + TimeSpan duration = end - start; + + if (this.options.Metrics) + { + RecordPublish(topicPartition, duration, errorType); + } + } + + return result; + } + + public void Produce(string topic, Message message, Action>? deliveryHandler = null) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + using Activity? activity = this.StartPublishActivity(start, topic, message); + if (activity != null) + { + this.InjectActivity(activity, message); + } + + string? errorType = null; + try + { + this.producer.Produce(topic, message, deliveryHandler); + } + catch (ProduceException produceException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatProduceException(produceException)); + + throw; + } + catch (ArgumentException argumentException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatArgumentException(argumentException)); + + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + activity?.SetEndTime(end.UtcDateTime); + TimeSpan duration = end - start; + + if (this.options.Metrics) + { + RecordPublish(topic, duration, errorType); + } + } + } + + public void Produce(TopicPartition topicPartition, Message message, Action>? deliveryHandler = null) + { + DateTimeOffset start = DateTimeOffset.UtcNow; + using Activity? activity = this.StartPublishActivity(start, topicPartition.Topic, message, topicPartition.Partition); + if (activity != null) + { + this.InjectActivity(activity, message); + } + + string? errorType = null; + try + { + this.producer.Produce(topicPartition, message, deliveryHandler); + } + catch (ProduceException produceException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatProduceException(produceException)); + + throw; + } + catch (ArgumentException argumentException) + { + activity?.SetStatus(ActivityStatusCode.Error); + activity?.SetTag(SemanticConventions.AttributeErrorType, errorType = FormatArgumentException(argumentException)); + + throw; + } + finally + { + DateTimeOffset end = DateTimeOffset.UtcNow; + activity?.SetEndTime(end.UtcDateTime); + TimeSpan duration = end - start; + + if (this.options.Metrics) + { + RecordPublish(topicPartition, duration, errorType); + } + } + } + + public int Poll(TimeSpan timeout) + { + return this.producer.Poll(timeout); + } + + public int Flush(TimeSpan timeout) + { + return this.producer.Flush(timeout); + } + + public void Flush(CancellationToken cancellationToken = default) + { + this.producer.Flush(cancellationToken); + } + + public void InitTransactions(TimeSpan timeout) + { + this.producer.InitTransactions(timeout); + } + + public void BeginTransaction() + { + this.producer.BeginTransaction(); + } + + public void CommitTransaction(TimeSpan timeout) + { + this.producer.CommitTransaction(timeout); + } + + public void CommitTransaction() + { + this.producer.CommitTransaction(); + } + + public void AbortTransaction(TimeSpan timeout) + { + this.producer.AbortTransaction(timeout); + } + + public void AbortTransaction() + { + this.producer.AbortTransaction(); + } + + public void SendOffsetsToTransaction(IEnumerable offsets, IConsumerGroupMetadata groupMetadata, TimeSpan timeout) + { + this.producer.SendOffsetsToTransaction(offsets, groupMetadata, timeout); + } + + public void Dispose() + { + this.producer.Dispose(); + } + + private static string FormatProduceException(ProduceException produceException) => + $"ProduceException: {produceException.Error.Code}"; + + private static string FormatArgumentException(ArgumentException argumentException) => + $"ArgumentException: {argumentException.ParamName}"; + + private static void GetTags(string topic, out TagList tags, int? partition = null, string? errorType = null) + { + tags = new TagList() + { + new KeyValuePair( + SemanticConventions.AttributeMessagingOperation, + PublishOperationName), + new KeyValuePair( + SemanticConventions.AttributeMessagingSystem, + KafkaMessagingSystem), + new KeyValuePair( + SemanticConventions.AttributeMessagingDestinationName, + topic), + }; + + if (partition is not null) + { + tags.Add( + new KeyValuePair( + SemanticConventions.AttributeMessagingKafkaDestinationPartition, + partition)); + } + + if (errorType is not null) + { + tags.Add( + new KeyValuePair( + SemanticConventions.AttributeErrorType, + errorType)); + } + } + + private static void RecordPublish(string topic, TimeSpan duration, string? errorType = null) + { + GetTags(topic, out var tags, partition: null, errorType); + + ConfluentKafkaCommon.PublishMessagesCounter.Add(1, in tags); + ConfluentKafkaCommon.PublishDurationHistogram.Record(duration.TotalSeconds, in tags); + } + + private static void RecordPublish(TopicPartition topicPartition, TimeSpan duration, string? errorType = null) + { + GetTags(topicPartition.Topic, out var tags, partition: topicPartition.Partition, errorType); + + ConfluentKafkaCommon.PublishMessagesCounter.Add(1, in tags); + ConfluentKafkaCommon.PublishDurationHistogram.Record(duration.TotalSeconds, in tags); + } + + private Activity? StartPublishActivity(DateTimeOffset start, string topic, Message message, int? partition = null) + { + var spanName = string.Concat(topic, " ", PublishOperationName); + var activity = ConfluentKafkaCommon.ActivitySource.StartActivity(name: spanName, kind: ActivityKind.Producer, startTime: start); + if (activity == null) + { + return null; + } + + if (activity.IsAllDataRequested) + { + activity.SetTag(SemanticConventions.AttributeMessagingSystem, KafkaMessagingSystem); + activity.SetTag(SemanticConventions.AttributeMessagingClientId, this.Name); + activity.SetTag(SemanticConventions.AttributeMessagingDestinationName, topic); + activity.SetTag(SemanticConventions.AttributeMessagingOperation, PublishOperationName); + + if (message.Key != null) + { + activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageKey, message.Key); + } + + if (partition is not null) + { + activity.SetTag(SemanticConventions.AttributeMessagingKafkaDestinationPartition, partition); + } + } + + return activity; + } + + private void InjectActivity(Activity? activity, Message message) + { + this.propagator.Inject(new PropagationContext(activity?.Context ?? default, Baggage.Current), message, this.InjectTraceContext); + } + + private void InjectTraceContext(Message message, string key, string value) + { + message.Headers ??= new Headers(); + message.Headers.Add(key, Encoding.UTF8.GetBytes(value)); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs new file mode 100644 index 0000000000..bcc29f5add --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs @@ -0,0 +1,43 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Confluent.Kafka; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +/// +/// A builder of with support for instrumentation. +/// +/// Type of the key. +/// Type of value. +public sealed class InstrumentedProducerBuilder : ProducerBuilder +{ + /// + /// Initializes a new instance of the class. + /// + /// A collection of librdkafka configuration parameters (refer to https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md) and parameters specific to this client (refer to: ). At a minimum, 'bootstrap.servers' must be specified. + public InstrumentedProducerBuilder(IEnumerable> config) + : base(config) + { + } + + internal ConfluentKafkaProducerInstrumentationOptions? Options { get; set; } + + /// + /// Build a new IProducer instance. + /// + /// an . + public override IProducer Build() + { + Debug.Assert(this.Options != null, "Options should not be null."); + + ProducerConfig config = (ProducerConfig)this.Config; + if (this.Options!.Metrics) + { + config.StatisticsIntervalMs ??= 1000; + } + + return new InstrumentedProducer(base.Build(), this.Options); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs new file mode 100644 index 0000000000..0cc6b91997 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.ConfluentKafka; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of Kafka instrumentation. +/// +public static partial class MeterProviderBuilderExtensions +{ + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaConsumerInstrumentation( + this MeterProviderBuilder builder) + => AddKafkaConsumerInstrumentation(builder, name: null, consumerBuilder: null); + + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// to instrument. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaConsumerInstrumentation( + this MeterProviderBuilder builder, + InstrumentedConsumerBuilder consumerBuilder) + { + Guard.ThrowIfNull(consumerBuilder); + + return AddKafkaConsumerInstrumentation(builder, name: null, consumerBuilder); + } + + /// + /// Enables the incoming requests automatic data collection for ASP.NET. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The name of the instrumentation. + /// to instrument. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaConsumerInstrumentation( + this MeterProviderBuilder builder, + string? name, + InstrumentedConsumerBuilder? consumerBuilder) + { + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; + + builder.ConfigureServices(services => + { + services.Configure>(name, EnableMetrics); + }); + + return builder + .AddMeter(ConfluentKafkaCommon.InstrumentationName) + .AddInstrumentation(sp => + { + if (consumerBuilder == null) + { + consumerBuilder = sp.GetRequiredService>(); + var options = sp.GetRequiredService>>(); + consumerBuilder.Options = options.Get(name); + } + + if (consumerBuilder.Options == null) + { + consumerBuilder.Options = new ConfluentKafkaConsumerInstrumentationOptions(); + EnableMetrics(consumerBuilder.Options); + } + + return new ConfluentKafkaConsumerInstrumentation(consumerBuilder); + }); + } + + private static void EnableMetrics(ConfluentKafkaConsumerInstrumentationOptions options) => + options.Metrics = true; +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs new file mode 100644 index 0000000000..3e4c4021db --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.ConfluentKafka; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of Kafka instrumentation. +/// +public static partial class MeterProviderBuilderExtensions +{ + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaProducerInstrumentation( + this MeterProviderBuilder builder) + => AddKafkaProducerInstrumentation(builder, name: null, producerBuilder: null); + + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// to instrument. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaProducerInstrumentation( + this MeterProviderBuilder builder, + InstrumentedProducerBuilder producerBuilder) + { + Guard.ThrowIfNull(producerBuilder); + + return AddKafkaProducerInstrumentation(builder, name: null, producerBuilder); + } + + /// + /// Enables the incoming requests automatic data collection for ASP.NET. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The name of the instrumentation. + /// to instrument. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaProducerInstrumentation( + this MeterProviderBuilder builder, + string? name, + InstrumentedProducerBuilder? producerBuilder) + { + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; + + builder.ConfigureServices(services => + { + services.Configure>(name, EnableMetrics); + }); + + return builder + .AddMeter(ConfluentKafkaCommon.InstrumentationName) + .AddInstrumentation(sp => + { + if (producerBuilder == null) + { + producerBuilder = sp.GetRequiredService>(); + var options = sp.GetRequiredService>>(); + producerBuilder.Options = options.Get(name); + } + + if (producerBuilder.Options == null) + { + producerBuilder.Options = new ConfluentKafkaProducerInstrumentationOptions(); + EnableMetrics(producerBuilder.Options); + } + + return new ConfluentKafkaProducerInstrumentation(producerBuilder); + }); + } + + private static void EnableMetrics(ConfluentKafkaProducerInstrumentationOptions options) => + options.Metrics = true; +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj new file mode 100644 index 0000000000..0d97d693a4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj @@ -0,0 +1,35 @@ + + + + net8.0;net6.0;net462 + Confluent.Kafka instrumentation for OpenTelemetry .NET + $(PackageTags);distributed-tracing;Kafka;Confluent.Kafka + true + Instrumentation.ConfluentKafka- + true + + + + + true + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md new file mode 100644 index 0000000000..546e654eec --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md @@ -0,0 +1,11 @@ +# Confluent.Kafka client instrumentation for OpenTelemetry + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.ConfluentKafka)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.ConfluentKafka) + +Download the `OpenTelemetry.Instrumentation.ConfluentKafka` package: + +```shell +dotnet add package OpenTelemetry.Instrumentation.ConfluentKafka --prerelease +``` diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs new file mode 100644 index 0000000000..d9eada36e1 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.ConfluentKafka; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static partial class TracerProviderBuilderExtensions +{ + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaConsumerInstrumentation( + this TracerProviderBuilder builder) + => AddKafkaConsumerInstrumentation(builder, name: null, consumerBuilder: null); + + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// to instrument. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaConsumerInstrumentation( + this TracerProviderBuilder builder, + InstrumentedConsumerBuilder consumerBuilder) + { + Guard.ThrowIfNull(consumerBuilder); + + return AddKafkaConsumerInstrumentation(builder, name: null, consumerBuilder); + } + + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// Optional name which is used when retrieving options. + /// Optional to instrument. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaConsumerInstrumentation( + this TracerProviderBuilder builder, + string? name, + InstrumentedConsumerBuilder? consumerBuilder) + { + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; + + builder.ConfigureServices(services => + { + services.Configure>(name, EnableTracing); + }); + + return builder + .AddSource(ConfluentKafkaCommon.InstrumentationName) + .AddInstrumentation(sp => + { + if (consumerBuilder == null) + { + consumerBuilder = sp.GetRequiredService>(); + var options = sp.GetRequiredService>>(); + consumerBuilder.Options = options.Get(name); + } + + if (consumerBuilder.Options == null) + { + consumerBuilder.Options = new ConfluentKafkaConsumerInstrumentationOptions(); + EnableTracing(consumerBuilder.Options); + } + + return new ConfluentKafkaConsumerInstrumentation(consumerBuilder); + }); + } + + private static void EnableTracing(ConfluentKafkaConsumerInstrumentationOptions options) => + options.Traces = true; +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs new file mode 100644 index 0000000000..db977c72ae --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.ConfluentKafka; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static partial class TracerProviderBuilderExtensions +{ + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaProducerInstrumentation( + this TracerProviderBuilder builder) + => AddKafkaProducerInstrumentation(builder, name: null, producerBuilder: null); + + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// to instrument. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaProducerInstrumentation( + this TracerProviderBuilder builder, + InstrumentedProducerBuilder producerBuilder) + { + Guard.ThrowIfNull(producerBuilder); + + return AddKafkaProducerInstrumentation(builder, name: null, producerBuilder); + } + + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// Optional name which is used when retrieving options. + /// Optional to instrument. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaProducerInstrumentation( + this TracerProviderBuilder builder, + string? name, + InstrumentedProducerBuilder? producerBuilder) + { + Guard.ThrowIfNull(builder); + + name ??= Options.DefaultName; + + builder.ConfigureServices(services => + { + services.Configure>(name, EnableTracing); + }); + + return builder + .AddSource(ConfluentKafkaCommon.InstrumentationName) + .AddInstrumentation(sp => + { + if (producerBuilder == null) + { + producerBuilder = sp.GetRequiredService>(); + var options = sp.GetRequiredService>>(); + producerBuilder.Options = options.Get(name); + } + + if (producerBuilder.Options == null) + { + producerBuilder.Options = new ConfluentKafkaProducerInstrumentationOptions(); + EnableTracing(producerBuilder.Options); + } + + return new ConfluentKafkaProducerInstrumentation(producerBuilder); + }); + } + + private static void EnableTracing(ConfluentKafkaProducerInstrumentationOptions options) => + options.Traces = true; +} diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index 2fa0c8144c..9f1c1ee234 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -116,5 +116,25 @@ internal static class SemanticConventions public const string AttributeServerAddress = "server.address"; // replaces: "net.host.name" (AttributeNetHostName) public const string AttributeServerPort = "server.port"; // replaces: "net.host.port" (AttributeNetHostPort) public const string AttributeUserAgentOriginal = "user_agent.original"; // replaces: http.user_agent (AttributeHttpUserAgent) + + // v1.24.0 Messaging spans + // https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/messaging-spans.md + public const string AttributeMessagingClientId = "messaging.client_id"; + public const string AttributeMessagingDestinationName = "messaging.destination.name"; + + // v1.24.0 Messaging metrics + // https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/messaging-metrics.md + public const string MetricMessagingPublishDuration = "messaging.publish.duration"; + public const string MetricMessagingPublishMessages = "messaging.publish.messages"; + public const string MetricMessagingReceiveDuration = "messaging.receive.duration"; + public const string MetricMessagingReceiveMessages = "messaging.receive.messages"; + + // v1.24.0 Messaging (Kafka) + // https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/kafka.md + public const string AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; + public const string AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition"; + public const string AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key"; + public const string AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; + #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile new file mode 100644 index 0000000000..300c474662 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile @@ -0,0 +1,19 @@ +# Create a container for running the OpenTelemetry ConfluentKafka integration tests. +# This should be run from the root of the repo: +# docker build --file test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile . + +ARG BUILD_SDK_VERSION=8.0 +ARG TEST_SDK_VERSION=8.0 + +FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build +ARG PUBLISH_CONFIGURATION=Release +ARG PUBLISH_FRAMEWORK=net8.0 +WORKDIR /repo +COPY . ./ +WORKDIR "/repo/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests" +RUN dotnet publish "OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} + +FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final +WORKDIR /test +COPY --from=build /drop . +ENTRYPOINT ["dotnet", "vstest", "OpenTelemetry.Instrumentation.ConfluentKafka.Tests.dll"] diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs new file mode 100644 index 0000000000..f9f188f343 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs @@ -0,0 +1,101 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +[Collection("Kafka")] +public class HostedMeteringTests(ITestOutputHelper outputHelper) +{ + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() + { + List metrics = new(); + var builder = Host.CreateDefaultBuilder(); + builder.ConfigureServices(services => + { + services.AddSingleton(_ => + new InstrumentedProducerBuilder(new ProducerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + })); + services.AddSingleton(_ => + new InstrumentedConsumerBuilder(new ConsumerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = Guid.NewGuid().ToString(), + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + })); + + services.AddOpenTelemetry().WithMetrics(metricsBuilder => + { + metricsBuilder + .AddInMemoryExporter(metrics) + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }); + }); + + IGrouping[] groups; + using (var host = builder.Build()) + { + await host.StartAsync(); + + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (var producer = host.Services.GetRequiredService>().Build()) + { + for (int i = 0; i < 100; i++) + { + producer.Produce(topic, new Message() + { + Key = $"any_key_{i}", + Value = $"any_value_{i}", + }); + outputHelper.WriteLine("produced message {0}", i); + } + + await producer.FlushAsync(); + } + + using (var consumer = host.Services.GetRequiredService>().Build()) + { + consumer.Subscribe(topic); + + int j = 0; + while (true) + { + var consumerResult = consumer.Consume(); + if (consumerResult == null) + { + continue; + } + + if (consumerResult.IsPartitionEOF) + { + break; + } + + outputHelper.WriteLine("consumed message {0}", j); + j++; + } + } + + host.Services.GetRequiredService().EnsureMetricsAreFlushed(); + + await host.StopAsync(); + } + + groups = metrics.GroupBy(x => x.Name).ToArray(); + + Assert.Equal(4, groups.Length); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs new file mode 100644 index 0000000000..a2ed848d1c --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs @@ -0,0 +1,115 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Confluent.Kafka; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +[Collection("Kafka")] +public class HostedTracingAndMeteringTests(ITestOutputHelper outputHelper) +{ + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() + { + List metrics = new(); + List activities = new(); + var builder = Host.CreateDefaultBuilder(); + builder.ConfigureServices(services => + { + services.AddSingleton(_ => + new InstrumentedProducerBuilder(new ProducerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + })); + services.AddSingleton(_ => + new InstrumentedConsumerBuilder(new ConsumerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = Guid.NewGuid().ToString(), + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + })); + + services.AddOpenTelemetry().WithTracing(tracingBuilder => + { + tracingBuilder + .AddInMemoryExporter(activities) + .SetSampler(new TestSampler()) + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }).WithMetrics(metricsBuilder => + { + metricsBuilder + .AddInMemoryExporter(metrics) + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }); + }); + + IGrouping[] groups = null; + using (var host = builder.Build()) + { + await host.StartAsync(); + + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (var producer = host.Services.GetRequiredService>().Build()) + { + for (int i = 0; i < 100; i++) + { + producer.Produce(topic, new Message() + { + Key = $"any_key_{i}", + Value = $"any_value_{i}", + }); + outputHelper.WriteLine("produced message {0}", i); + } + + await producer.FlushAsync(); + } + + using (var consumer = host.Services.GetRequiredService>().Build()) + { + consumer.Subscribe(topic); + + int j = 0; + while (true) + { + var consumerResult = consumer.Consume(); + if (consumerResult == null) + { + continue; + } + + if (consumerResult.IsPartitionEOF) + { + break; + } + + outputHelper.WriteLine("consumed message {0}", j); + j++; + } + + Assert.Equal(100, j); + } + + await host.StopAsync(); + + Assert.Equal(200, activities.Count); + + host.Services.GetRequiredService().EnsureMetricsAreFlushed(); + } + + groups = metrics.GroupBy(x => x.Name).ToArray(); + + Assert.Equal(4, groups.Length); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs new file mode 100644 index 0000000000..d47d93d14f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs @@ -0,0 +1,96 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Confluent.Kafka; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +[Collection("Kafka")] +public class HostedTracingTests(ITestOutputHelper outputHelper) +{ + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() + { + List activities = new(); + var builder = Host.CreateDefaultBuilder(); + builder.ConfigureServices(services => + { + services.AddSingleton(_ => + new InstrumentedProducerBuilder(new ProducerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + })); + services.AddSingleton(_ => + new InstrumentedConsumerBuilder(new ConsumerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = Guid.NewGuid().ToString(), + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + })); + + services.AddOpenTelemetry().WithTracing(tracingBuilder => + { + tracingBuilder + .AddInMemoryExporter(activities) + .SetSampler(new TestSampler()) + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }); + }); + + using (var host = builder.Build()) + { + await host.StartAsync(); + + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (var producer = host.Services.GetRequiredService>().Build()) + { + for (int i = 0; i < 100; i++) + { + producer.Produce(topic, new Message() { Key = $"any_key_{i}", Value = $"any_value_{i}", }); + outputHelper.WriteLine("produced message {0}", i); + } + + await producer.FlushAsync(); + } + + using (var consumer = host.Services.GetRequiredService>().Build()) + { + consumer.Subscribe(topic); + + int j = 0; + while (true) + { + var consumerResult = consumer.Consume(); + if (consumerResult == null) + { + continue; + } + + if (consumerResult.IsPartitionEOF) + { + break; + } + + outputHelper.WriteLine("consumed message {0}", j); + j++; + } + + Assert.Equal(100, j); + } + + await host.StopAsync(); + } + + Assert.Equal(200, activities.Count); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs new file mode 100644 index 0000000000..793753bdc2 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using OpenTelemetry.Tests; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +internal static class KafkaHelpers +{ + public const string KafkaEndPointEnvVarName = "OTEL_KAFKAENDPOINT"; + + public static readonly string KafkaEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(KafkaEndPointEnvVarName); + + public static async Task ProduceTestMessageAsync() + { + string topic = $"otel-topic-{Guid.NewGuid()}"; + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaEndPoint, + }; + ProducerBuilder producerBuilder = new(producerConfig); + IProducer producer = producerBuilder.Build(); + await producer.ProduceAsync(topic, new Message + { + Value = "any_value", + }); + return topic; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeterProviderExtensions.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeterProviderExtensions.cs new file mode 100644 index 0000000000..c26f38743a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeterProviderExtensions.cs @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Metrics; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +internal static class MeterProviderExtensions +{ + public static void EnsureMetricsAreFlushed(this MeterProvider meterProvider) + { + bool done; + do + { + done = meterProvider.ForceFlush(); + } + while (!done); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs new file mode 100644 index 0000000000..eff25507ff --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs @@ -0,0 +1,135 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +[Collection("Kafka")] +public class MeteringTests +{ + /* + To run the integration tests, set the OTEL_KAFKAENDPOINT machine-level environment variable to a valid Kafka endpoint. + + To use Docker... + 1) Run: docker run -d --name kafka -p 9092:9092 confluentinc/confluent-local + 2) Set OTEL_KAFKAENDPOINT as: localhost:9092 + */ + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicProduceToTopicTest() + { + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + }; + InstrumentedProducerBuilder producerBuilder = new(producerConfig); + var metrics = new List(); + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(metrics) + .AddKafkaProducerInstrumentation(producerBuilder) + .Build()) + { + IProducer producer = producerBuilder.Build(); + producer.Produce(topic, new Message + { + Value = "any_value", + }); + + await producer.FlushAsync(); + + meterProvider.EnsureMetricsAreFlushed(); + } + + var groups = metrics.GroupBy(m => m.Name).ToArray(); + + Assert.Equal(2, groups.Length); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicProduceAsyncToTopicTest() + { + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + }; + InstrumentedProducerBuilder producerBuilder = new(producerConfig); + var metrics = new List(); + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(metrics) + .AddKafkaProducerInstrumentation(producerBuilder) + .Build()) + { + IProducer producer = producerBuilder.Build(); + await producer.ProduceAsync(topic, new Message + { + Value = "any_value", + }); + + await producer.FlushAsync(); + + meterProvider.EnsureMetricsAreFlushed(); + } + + var groups = metrics.GroupBy(m => m.Name).ToArray(); + + Assert.Equal(2, groups.Length); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicConsumeWithTimeoutTimespanTest() + { + string topic = await KafkaHelpers.ProduceTestMessageAsync(); + + ConsumerConfig consumerConfig = new ConsumerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = "test-consumer-group", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + InstrumentedConsumerBuilder consumerBuilder = new(consumerConfig); + + var metrics = new List(); + using (var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddInMemoryExporter(metrics) + .AddKafkaConsumerInstrumentation(consumerBuilder) + .Build()) + { + using (IConsumer consumer = consumerBuilder.Build()) + { + consumer.Subscribe(topic); + while (true) + { + var consumeResult = consumer.Consume(); + + if (consumeResult == null) + { + continue; + } + + if (consumeResult.IsPartitionEOF) + { + break; + } + } + + consumer.Close(); + } + + meterProvider.EnsureMetricsAreFlushed(); + } + + var groups = metrics.GroupBy(m => m.Name).ToArray(); + + Assert.Equal(2, groups.Length); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj new file mode 100644 index 0000000000..defd085a4a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -0,0 +1,28 @@ + + + Unit test project for OpenTelemetry ConfluentKafka instrumentation + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + disable + + + + + + + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/ProducerExtensions.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/ProducerExtensions.cs new file mode 100644 index 0000000000..01168f5fe4 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/ProducerExtensions.cs @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +internal static class ProducerExtensions +{ + public static async Task FlushAsync(this IProducer producer) + { + while (producer.Flush(TimeSpan.FromMilliseconds(100)) != 0) + { + await Task.Delay(100); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs new file mode 100644 index 0000000000..923b4dae99 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs @@ -0,0 +1,305 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Confluent.Kafka; +using OpenTelemetry.Tests; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +[Collection("Kafka")] +public class TracingTests +{ + /* + To run the integration tests, set the OTEL_KAFKAENDPOINT machine-level environment variable to a valid Kafka endpoint. + + To use Docker... + 1) Run: docker run -d --name kafka -p 9092:9092 confluentinc/confluent-local + 2) Set OTEL_KAFKAENDPOINT as: localhost:9092 + */ + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicProduceAsyncToTopicTest() + { + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + }; + InstrumentedProducerBuilder producerBuilder = new(producerConfig); + var sampler = new TestSampler(); + var activities = new List(); + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaProducerInstrumentation(producerBuilder) + .Build()) + { + using IProducer producer = producerBuilder.Build(); + await producer.ProduceAsync(topic, new Message + { + Value = "any_value", + }); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " publish"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("publish", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicProduceAsyncToTopicPartitionTest() + { + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + }; + InstrumentedProducerBuilder producerBuilder = new(producerConfig); + var sampler = new TestSampler(); + var activities = new List(); + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaProducerInstrumentation(producerBuilder) + .Build()) + { + using IProducer producer = producerBuilder.Build(); + await producer.ProduceAsync(new TopicPartition(topic, new Partition(0)), new Message + { + Value = "any_value", + }); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " publish"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("publish", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + Assert.Equal(0, activity.GetTagValue("messaging.kafka.destination.partition")); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public void BasicProduceSyncToTopicTest() + { + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + }; + InstrumentedProducerBuilder producerBuilder = new(producerConfig); + var sampler = new TestSampler(); + var activities = new List(); + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaProducerInstrumentation(producerBuilder) + .Build()) + { + using IProducer producer = producerBuilder.Build(); + producer.Produce(topic, new Message + { + Value = "any_value", + }); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " publish"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("publish", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public void BasicProduceSyncToTopicPartitionTest() + { + ProducerConfig producerConfig = new ProducerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + }; + InstrumentedProducerBuilder producerBuilder = new(producerConfig); + var sampler = new TestSampler(); + var activities = new List(); + string topic = $"otel-topic-{Guid.NewGuid()}"; + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaProducerInstrumentation(producerBuilder) + .Build()) + { + using IProducer producer = producerBuilder.Build(); + producer.Produce(new TopicPartition(topic, new Partition(0)), new Message + { + Value = "any_value", + }); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " publish"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("publish", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + Assert.Equal(0, activity.GetTagValue("messaging.kafka.destination.partition")); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicConsumeWithCancellationTokenTest() + { + string topic = await KafkaHelpers.ProduceTestMessageAsync(); + + ConsumerConfig consumerConfig = new ConsumerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = "test-consumer-group", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + InstrumentedConsumerBuilder consumerBuilder = new(consumerConfig); + var sampler = new TestSampler(); + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaConsumerInstrumentation(consumerBuilder) + .Build()) + { + using IConsumer consumer = consumerBuilder.Build(); + consumer.Subscribe(topic); + while (true) + { + var consumeResult = consumer.Consume(); + if (consumeResult == null) + { + continue; + } + + if (consumeResult.IsPartitionEOF) + { + break; + } + } + + consumer.Close(); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " receive"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("receive", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + Assert.Equal(0, activity.GetTagValue("messaging.kafka.destination.partition")); + Assert.Equal(0L, activity.GetTagValue("messaging.kafka.message.offset")); + Assert.Equal("test-consumer-group", activity.GetTagValue("messaging.kafka.consumer.group")); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicConsumeWithTimeoutMsTest() + { + string topic = await KafkaHelpers.ProduceTestMessageAsync(); + + ConsumerConfig consumerConfig = new ConsumerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = "test-consumer-group", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + InstrumentedConsumerBuilder consumerBuilder = new(consumerConfig); + var sampler = new TestSampler(); + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaConsumerInstrumentation(consumerBuilder) + .Build()) + { + using IConsumer consumer = consumerBuilder.Build(); + consumer.Subscribe(topic); + while (true) + { + var consumeResult = consumer.Consume(100); + if (consumeResult == null) + { + continue; + } + + if (consumeResult.IsPartitionEOF) + { + break; + } + } + + consumer.Close(); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " receive"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("receive", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + Assert.Equal(0, activity.GetTagValue("messaging.kafka.destination.partition")); + Assert.Equal(0L, activity.GetTagValue("messaging.kafka.message.offset")); + Assert.Equal("test-consumer-group", activity.GetTagValue("messaging.kafka.consumer.group")); + } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task BasicConsumeWithTimeoutTimespanTest() + { + string topic = await KafkaHelpers.ProduceTestMessageAsync(); + + ConsumerConfig consumerConfig = new ConsumerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = "test-consumer-group", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + InstrumentedConsumerBuilder consumerBuilder = new(consumerConfig); + var sampler = new TestSampler(); + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaConsumerInstrumentation(consumerBuilder) + .Build()) + { + using IConsumer consumer = consumerBuilder.Build(); + consumer.Subscribe(topic); + while (true) + { + var consumeResult = consumer.Consume(TimeSpan.FromMilliseconds(100)); + if (consumeResult == null) + { + continue; + } + + if (consumeResult.IsPartitionEOF) + { + break; + } + } + + consumer.Close(); + } + + Assert.Contains(activities, activity => activity.DisplayName == topic + " receive"); + var activity = Assert.Single(activities); + Assert.Equal("kafka", activity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("receive", activity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, activity.GetTagValue("messaging.destination.name")); + Assert.Equal(0, activity.GetTagValue("messaging.kafka.destination.partition")); + Assert.Equal(0L, activity.GetTagValue("messaging.kafka.message.offset")); + Assert.Equal("test-consumer-group", activity.GetTagValue("messaging.kafka.consumer.group")); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml new file mode 100644 index 0000000000..c749ab3632 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml @@ -0,0 +1,24 @@ +# Start a kafka container and then run OpenTelemetry ConfluentKafka integration tests. +# This should be run from the root of the repo: +# opentelemetry>docker-compose --file=test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml --project-directory=. up --exit-code-from=tests --build +version: '3.7' + +services: + kafka: + image: confluentinc/confluent-local + environment: + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT + KAFKA_LISTENERS: PLAINTEXT://localhost:29092,CONTROLLER://localhost:29093,PLAINTEXT_HOST://0.0.0.0:9092,PLAINTEXT_INTERNAL://kafka:9093 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:29092,PLAINTEXT_INTERNAL://kafka:9093,PLAINTEXT_HOST://localhost:9092 + ports: + - "9093:9093" + + tests: + build: + context: . + dockerfile: ./test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile + command: --TestCaseFilter:CategoryName=KafkaIntegrationTests + environment: + - OTEL_KAFKAENDPOINT=kafka:9093 + depends_on: + - kafka From 38cd9638966bc7d97470d30bde9e232faa5e6f3f Mon Sep 17 00:00:00 2001 From: Moritz Wiesinger Date: Thu, 4 Jul 2024 07:03:47 +0200 Subject: [PATCH 1172/1499] Add YAMLLint to CI (#1933) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Moritz Wiesinger Co-authored-by: Piotr Kiełkowicz --- .../ci-Exporter.OneCollector-Integration.yml | 2 +- .github/workflows/ci.yml | 10 +- .github/workflows/codeql-analysis.yml | 36 +-- .github/workflows/publish-packages.yml | 224 +++++++++--------- .github/workflows/yamllint.yml | 18 ++ .yamllint | 21 ++ CONTRIBUTING.md | 7 + .../docker-compose.yml | 4 +- 8 files changed, 187 insertions(+), 135 deletions(-) create mode 100644 .github/workflows/yamllint.yml create mode 100644 .yamllint diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index 0a75af1ed4..25ffa9b3ee 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -20,7 +20,7 @@ jobs: 'external' || 'internal' }} runs-on: ubuntu-latest steps: - - run: echo ✓ + - run: echo ✓ build-integration-test: needs: authorize diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f0778213e..2ec5e2d6d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: with: filters: | md: [ '**.md' ] + yml: [ '**.yml', '**.yaml', '.yamllint' ] build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*', '**/*.targets', '**/*.props'] shared: ['src/Shared/**', 'test/Shared/**'] contrib-shared-tests: ['test/OpenTelemetry.Contrib.Shared.Tests/**'] @@ -69,6 +70,13 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'build') uses: ./.github/workflows/markdownlint.yml + lint-yml: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'yml') + || contains(needs.detect-changes.outputs.changes, 'build') + uses: ./.github/workflows/yamllint.yml + lint-dotnet-format: needs: detect-changes if: | @@ -609,7 +617,7 @@ jobs: build-test-semanticconventions, build-test-contrib-shared-tests, verify-aot-compat - ] + ] if: always() && !cancelled() && !contains(needs.*.result, 'failure') runs-on: windows-latest steps: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1ca6a8e383..3f47bb5eb3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -21,26 +21,26 @@ jobs: language: ['csharp'] steps: - - name: configure Pagefile - uses: al-cheb/configure-pagefile-action@v1.4 - with: - minimum-size: 8GB - maximum-size: 32GB - disk-root: "D:" + - name: configure Pagefile + uses: al-cheb/configure-pagefile-action@v1.4 + with: + minimum-size: 8GB + maximum-size: 32GB + disk-root: "D:" - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} - - name: Setup dotnet - uses: actions/setup-dotnet@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 - - name: dotnet pack opentelemetry-dotnet-contrib.proj - run: dotnet pack opentelemetry-dotnet-contrib.proj --configuration Release + - name: dotnet pack opentelemetry-dotnet-contrib.proj + run: dotnet pack opentelemetry-dotnet-contrib.proj --configuration Release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index f9cae34b57..6d13c4686a 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -29,86 +29,86 @@ jobs: artifact-id: ${{ steps.upload-artifacts.outputs.artifact-id }} steps: - - uses: actions/checkout@v4 - with: - # Note: By default GitHub only fetches 1 commit. MinVer needs to find - # the version tag which is typically NOT on the first commit so we - # retrieve them all. - fetch-depth: 0 - - - name: Resolve project - id: resolve-project - shell: pwsh - run: | - Import-Module .\build\scripts\build.psm1 - - # Note: The ResolveProjectForTag call here figures out the .proj file to - # use for the build. It will be either opentelemetry-dotnet-contrib.proj - # (for manual/scheduled builds), a .proj file in .\build\Projects\ (if - # one is defined with MinVerTagPrefix matching the tag), or - # Component.proj for simple projects (where a single csproj has - # MinVerTagPrefix matching the tag). - - $title = '' # Used for friendly names in action UI - $project = '' # Actual project passed to dotnet - $component = '' # Used to tell Component.proj what to build - - ResolveProjectForTag ` - -tag '${{ github.ref_type == 'tag' && github.ref_name || '' }}' ` - -title ([ref]$title) ` - -project ([ref]$project) ` - -component ([ref]$component) - - echo "title=$title" >> $env:GITHUB_OUTPUT - echo "project=$project" >> $env:GITHUB_OUTPUT - - # Note: BUILD_COMPONENT envvar tells Component.proj what to build. Only - # used if $project ends up Component.proj. - echo "BUILD_COMPONENT=$component" >> $env:GITHUB_ENV - - - name: Setup dotnet - uses: actions/setup-dotnet@v4 - - - name: dotnet restore ${{ steps.resolve-project.outputs.title }} - run: dotnet restore ${{ steps.resolve-project.outputs.project }} - - - name: dotnet build ${{ steps.resolve-project.outputs.title }} - run: dotnet build ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} - - - name: dotnet test ${{ steps.resolve-project.outputs.title }} - run: dotnet test ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore --no-build - - - name: dotnet pack ${{ steps.resolve-project.outputs.title }} - run: dotnet pack ${{ steps.resolve-project.outputs.project }} --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: ${{ github.ref_name }}-packages - path: 'src\**\*.*nupkg' - - - name: Publish MyGet - env: - MYGET_TOKEN_EXISTS: ${{ secrets.MYGET_TOKEN != '' }} - 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 src\**\*.nupkg -Source https://www.myget.org/F/opentelemetry/api/v2/package - - - name: Publish NuGets - env: - NUGET_TOKEN_EXISTS: ${{ secrets.NUGET_TOKEN != '' }} - if: github.ref_type == 'tag' && env.NUGET_TOKEN_EXISTS == 'true' # Skip NuGet publish for scheduled nightly builds or if run on a fork without the secret - run: | - nuget push src\**\*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} + - uses: actions/checkout@v4 + with: + # Note: By default GitHub only fetches 1 commit. MinVer needs to find + # the version tag which is typically NOT on the first commit so we + # retrieve them all. + fetch-depth: 0 + + - name: Resolve project + id: resolve-project + shell: pwsh + run: | + Import-Module .\build\scripts\build.psm1 + + # Note: The ResolveProjectForTag call here figures out the .proj file to + # use for the build. It will be either opentelemetry-dotnet-contrib.proj + # (for manual/scheduled builds), a .proj file in .\build\Projects\ (if + # one is defined with MinVerTagPrefix matching the tag), or + # Component.proj for simple projects (where a single csproj has + # MinVerTagPrefix matching the tag). + + $title = '' # Used for friendly names in action UI + $project = '' # Actual project passed to dotnet + $component = '' # Used to tell Component.proj what to build + + ResolveProjectForTag ` + -tag '${{ github.ref_type == 'tag' && github.ref_name || '' }}' ` + -title ([ref]$title) ` + -project ([ref]$project) ` + -component ([ref]$component) + + echo "title=$title" >> $env:GITHUB_OUTPUT + echo "project=$project" >> $env:GITHUB_OUTPUT + + # Note: BUILD_COMPONENT envvar tells Component.proj what to build. Only + # used if $project ends up Component.proj. + echo "BUILD_COMPONENT=$component" >> $env:GITHUB_ENV + + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + + - name: dotnet restore ${{ steps.resolve-project.outputs.title }} + run: dotnet restore ${{ steps.resolve-project.outputs.project }} + + - name: dotnet build ${{ steps.resolve-project.outputs.title }} + run: dotnet build ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore -p:Deterministic=true -p:BuildNumber=${{ github.run_number }} + + - name: dotnet test ${{ steps.resolve-project.outputs.title }} + run: dotnet test ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore --no-build + + - name: dotnet pack ${{ steps.resolve-project.outputs.title }} + run: dotnet pack ${{ steps.resolve-project.outputs.project }} --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: ${{ github.ref_name }}-packages + path: 'src\**\*.*nupkg' + + - name: Publish MyGet + env: + MYGET_TOKEN_EXISTS: ${{ secrets.MYGET_TOKEN != '' }} + 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 src\**\*.nupkg -Source https://www.myget.org/F/opentelemetry/api/v2/package + + - name: Publish NuGets + env: + NUGET_TOKEN_EXISTS: ${{ secrets.NUGET_TOKEN != '' }} + if: github.ref_type == 'tag' && env.NUGET_TOKEN_EXISTS == 'true' # Skip NuGet publish for scheduled nightly builds or if run on a fork without the secret + run: | + nuget push src\**\*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} post-build: runs-on: ubuntu-latest needs: - - automation - - build-pack-publish + - automation + - build-pack-publish if: needs.automation.outputs.enabled && github.event_name == 'push' @@ -116,40 +116,40 @@ jobs: 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: 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 - if: github.ref_type == 'tag' - shell: pwsh - run: | - Import-Module .\build\scripts\post-release.psm1 - - CreateRelease ` - -gitRepository '${{ github.repository }}' ` - -tag '${{ github.ref_name }}' ` - -releaseFiles '${{ github.workspace }}/artifacts/${{ github.ref_name }}-packages.zip#Packages' - - - name: Post notice when packages are ready - shell: pwsh - run: | - Import-Module .\build\scripts\post-release.psm1 - - TryPostPackagesReadyNoticeOnPrepareReleasePullRequest ` - -gitRepository '${{ github.repository }}' ` - -tag '${{ github.ref_name }}' ` - -tagSha '${{ github.sha }}' ` - -packagesUrl '${{ needs.build-pack-publish.outputs.artifact-url }}' ` - -botUserName '${{ needs.automation.outputs.username }}' + - name: check out code + uses: actions/checkout@v4 + 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 + if: github.ref_type == 'tag' + shell: pwsh + run: | + Import-Module .\build\scripts\post-release.psm1 + + CreateRelease ` + -gitRepository '${{ github.repository }}' ` + -tag '${{ github.ref_name }}' ` + -releaseFiles '${{ github.workspace }}/artifacts/${{ github.ref_name }}-packages.zip#Packages' + + - name: Post notice when packages are ready + shell: pwsh + run: | + Import-Module .\build\scripts\post-release.psm1 + + 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/.github/workflows/yamllint.yml b/.github/workflows/yamllint.yml new file mode 100644 index 0000000000..d802191d66 --- /dev/null +++ b/.github/workflows/yamllint.yml @@ -0,0 +1,18 @@ +name: Lint - YAML + +on: + workflow_call: + +jobs: + run-yamllint: + runs-on: ubuntu-latest + + steps: + - name: check out code + uses: actions/checkout@v4 + + - name: install yamllint + run: pip install yamllint + + - name: run yamllint + run: yamllint --no-warnings . diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000000..862068ccf5 --- /dev/null +++ b/.yamllint @@ -0,0 +1,21 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +extends: default + +ignore-from-file: [.gitignore] + +rules: + document-start: disable + octal-values: enable + truthy: + allowed-values: ['true', 'false', 'on'] # 'on' for GH action trigger + line-length: disable + indentation: + check-multi-line-strings: false + indent-sequences: consistent + brackets: + max-spaces-inside: 1 + max-spaces-inside-empty: 0 + braces: + max-spaces-inside: 1 + max-spaces-inside-empty: 0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5dabc31e12..2b21e75363 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,6 +96,13 @@ If you made changes to the Markdown documents (`*.md` files), install the latest markdownlint . ``` +If you made changes to any YAML files (`*.yaml` or `*.yml` files), install the latest +[`yamllint`](https://github.com/adrienverge/yamllint) and run: + +```sh +yamllint --no-warnings . +``` + Check out a new branch, make modifications and push the branch to your fork: ```sh diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml index 5fa4a2f8b9..daa2518e8e 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/docker-compose.yml @@ -9,7 +9,7 @@ services: ports: - "9042:9042" healthcheck: - test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra" ,"-e describe keyspaces" ] + test: [ "CMD", "cqlsh", "-u cassandra", "-p cassandra", "-e describe keyspaces" ] interval: 15s timeout: 10s retries: 10 @@ -24,5 +24,3 @@ services: depends_on: cassandra: condition: service_healthy - - From d6aff08a465c99d0a49f1797b6f20c7c34e8e911 Mon Sep 17 00:00:00 2001 From: Ilia Brahinets Date: Fri, 5 Jul 2024 07:46:55 +0300 Subject: [PATCH 1173/1499] [Instrumentation.GrpcCore] Nullable support (#1936) --- .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 28 ++++++------- .../AsyncStreamReaderProxy.cs | 8 ++-- .../CHANGELOG.md | 2 + .../ClientStreamWriterProxy.cs | 8 ++-- .../ClientTracingInterceptor.cs | 36 ++++++++++------ .../ClientTracingInterceptorOptions.cs | 2 +- .../GrpcCoreInstrumentation.cs | 2 +- ...nTelemetry.Instrumentation.GrpcCore.csproj | 3 +- .../RpcScope.cs | 41 +++++++++++-------- .../ServerStreamWriterProxy.cs | 4 +- .../ServerTracingInterceptorOptions.cs | 2 +- .../FoobarService.cs | 14 +++---- .../GrpcCoreClientInterceptorTests.cs | 37 +++++++++-------- .../GrpcCoreServerInterceptorTests.cs | 7 +++- .../InterceptorActivityListener.cs | 2 +- ...etry.Instrumentation.GrpcCore.Tests.csproj | 3 +- .../TestActivityTags.cs | 4 +- 18 files changed, 116 insertions(+), 88 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Unshipped.txt index 0fb3d72fd9..5415a53f00 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/.publicApi/PublicAPI.Unshipped.txt @@ -1,29 +1,29 @@ OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor -OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.ClientTracingInterceptor(OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions options) -> void +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.ClientTracingInterceptor(OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions! options) -> void OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.ClientTracingInterceptorOptions() -> void -OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.Propagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator +OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.Propagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator! OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.RecordException.set -> void OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.RecordMessageEvents.get -> bool OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptorOptions.RecordMessageEvents.set -> void OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor -OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ServerTracingInterceptor(OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions options) -> void +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ServerTracingInterceptor(OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions! options) -> void OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions -OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.Propagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator +OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.Propagator.get -> OpenTelemetry.Context.Propagation.TextMapPropagator! OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.RecordException.set -> void OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.RecordMessageEvents.get -> bool OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.RecordMessageEvents.set -> void OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptorOptions.ServerTracingInterceptorOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncClientStreamingCall(Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncClientStreamingCallContinuation continuation) -> Grpc.Core.AsyncClientStreamingCall -override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncDuplexStreamingCall(Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncDuplexStreamingCallContinuation continuation) -> Grpc.Core.AsyncDuplexStreamingCall -override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncServerStreamingCall(TRequest request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncServerStreamingCallContinuation continuation) -> Grpc.Core.AsyncServerStreamingCall -override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncUnaryCall(TRequest request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncUnaryCallContinuation continuation) -> Grpc.Core.AsyncUnaryCall -override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.BlockingUnaryCall(TRequest request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.BlockingUnaryCallContinuation continuation) -> TResponse -override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ClientStreamingServerHandler(Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.ServerCallContext context, Grpc.Core.ClientStreamingServerMethod continuation) -> System.Threading.Tasks.Task -override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.DuplexStreamingServerHandler(Grpc.Core.IAsyncStreamReader requestStream, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context, Grpc.Core.DuplexStreamingServerMethod continuation) -> System.Threading.Tasks.Task -override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ServerStreamingServerHandler(TRequest request, Grpc.Core.IServerStreamWriter responseStream, Grpc.Core.ServerCallContext context, Grpc.Core.ServerStreamingServerMethod continuation) -> System.Threading.Tasks.Task -override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.UnaryServerHandler(TRequest request, Grpc.Core.ServerCallContext context, Grpc.Core.UnaryServerMethod continuation) -> System.Threading.Tasks.Task -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncClientStreamingCall(Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncClientStreamingCallContinuation! continuation) -> Grpc.Core.AsyncClientStreamingCall! +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncDuplexStreamingCall(Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncDuplexStreamingCallContinuation! continuation) -> Grpc.Core.AsyncDuplexStreamingCall! +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncServerStreamingCall(TRequest! request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncServerStreamingCallContinuation! continuation) -> Grpc.Core.AsyncServerStreamingCall! +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.AsyncUnaryCall(TRequest! request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.AsyncUnaryCallContinuation! continuation) -> Grpc.Core.AsyncUnaryCall! +override OpenTelemetry.Instrumentation.GrpcCore.ClientTracingInterceptor.BlockingUnaryCall(TRequest! request, Grpc.Core.Interceptors.ClientInterceptorContext context, Grpc.Core.Interceptors.Interceptor.BlockingUnaryCallContinuation! continuation) -> TResponse! +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ClientStreamingServerHandler(Grpc.Core.IAsyncStreamReader! requestStream, Grpc.Core.ServerCallContext! context, Grpc.Core.ClientStreamingServerMethod! continuation) -> System.Threading.Tasks.Task! +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.DuplexStreamingServerHandler(Grpc.Core.IAsyncStreamReader! requestStream, Grpc.Core.IServerStreamWriter! responseStream, Grpc.Core.ServerCallContext! context, Grpc.Core.DuplexStreamingServerMethod! continuation) -> System.Threading.Tasks.Task! +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.ServerStreamingServerHandler(TRequest! request, Grpc.Core.IServerStreamWriter! responseStream, Grpc.Core.ServerCallContext! context, Grpc.Core.ServerStreamingServerMethod! continuation) -> System.Threading.Tasks.Task! +override OpenTelemetry.Instrumentation.GrpcCore.ServerTracingInterceptor.UnaryServerHandler(TRequest! request, Grpc.Core.ServerCallContext! context, Grpc.Core.UnaryServerMethod! continuation) -> System.Threading.Tasks.Task! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddGrpcCoreInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs index a0d1b03303..0885767c8a 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/AsyncStreamReaderProxy.cs @@ -24,17 +24,17 @@ internal class AsyncStreamReaderProxy : IAsyncStreamReader /// /// The on message action. /// - private readonly Action onMessage; + private readonly Action? onMessage; /// /// The on stream end action. /// - private readonly Action onStreamEnd; + private readonly Action? onStreamEnd; /// /// The on exception action. /// - private readonly Action onException; + private readonly Action? onException; /// /// Initializes a new instance of the class. @@ -43,7 +43,7 @@ internal class AsyncStreamReaderProxy : IAsyncStreamReader /// The on message action, if any. /// The on stream end action, if any. /// The on exception action, if any. - public AsyncStreamReaderProxy(IAsyncStreamReader reader, Action onMessage = null, Action onStreamEnd = null, Action onException = null) + public AsyncStreamReaderProxy(IAsyncStreamReader reader, Action? onMessage = null, Action? onStreamEnd = null, Action? onException = null) { this.reader = reader; this.onMessage = onMessage; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 2c50800621..276fedf468 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -4,6 +4,8 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Updated minimal supported version of `Grpc.Core.Api` to `2.43.0`. + ([#1936](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1936)) ## 1.0.0-beta.6 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index 254b4ba709..eafbd3bb32 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -24,17 +24,17 @@ internal class ClientStreamWriterProxy : IClientStreamWriter /// /// The on write action. /// - private readonly Action onWrite; + private readonly Action? onWrite; /// /// The on complete action. /// - private readonly Action onComplete; + private readonly Action? onComplete; /// /// The on exception action. /// - private readonly Action onException; + private readonly Action? onException; /// /// Initializes a new instance of the class. @@ -43,7 +43,7 @@ internal class ClientStreamWriterProxy : IClientStreamWriter /// The on write action if any. /// The on complete action, if any. /// The on exception action, if any. - public ClientStreamWriterProxy(IClientStreamWriter writer, Action onWrite = null, Action onComplete = null, Action onException = null) + public ClientStreamWriterProxy(IClientStreamWriter writer, Action? onWrite = null, Action? onComplete = null, Action? onException = null) { this.writer = writer; this.onWrite = onWrite; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs index 7f5d7d7da9..ce87f3a3d8 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptor.cs @@ -40,7 +40,7 @@ public override TResponse BlockingUnaryCall( Guard.ThrowIfNull(context); Guard.ThrowIfNull(continuation); - ClientRpcScope rpcScope = null; + ClientRpcScope? rpcScope = null; try { @@ -72,7 +72,7 @@ public override AsyncUnaryCall AsyncUnaryCall( Guard.ThrowIfNull(context); Guard.ThrowIfNull(continuation); - ClientRpcScope rpcScope = null; + ClientRpcScope? rpcScope = null; try { @@ -93,8 +93,14 @@ public override AsyncUnaryCall AsyncUnaryCall( } catch (AggregateException ex) { - rpcScope.CompleteWithException(ex.InnerException); - throw ex.InnerException; + if (ex.InnerException != null) + { + rpcScope.CompleteWithException(ex.InnerException); + throw ex.InnerException; + } + + rpcScope.CompleteWithException(ex); + throw; } }, TaskScheduler.Current); @@ -125,7 +131,7 @@ public override AsyncClientStreamingCall AsyncClientStreami Guard.ThrowIfNull(context); Guard.ThrowIfNull(continuation); - ClientRpcScope rpcScope = null; + ClientRpcScope? rpcScope = null; try { @@ -150,8 +156,14 @@ public override AsyncClientStreamingCall AsyncClientStreami } catch (AggregateException ex) { - rpcScope.CompleteWithException(ex.InnerException); - throw ex.InnerException; + if (ex.InnerException != null) + { + rpcScope.CompleteWithException(ex.InnerException); + throw ex.InnerException; + } + + rpcScope.CompleteWithException(ex); + throw; } }, TaskScheduler.Current); @@ -184,7 +196,7 @@ public override AsyncServerStreamingCall AsyncServerStreamingCall rpcScope = null; + ClientRpcScope? rpcScope = null; try { @@ -226,7 +238,7 @@ public override AsyncDuplexStreamingCall AsyncDuplexStreami Guard.ThrowIfNull(context); Guard.ThrowIfNull(continuation); - ClientRpcScope rpcScope = null; + ClientRpcScope? rpcScope = null; try { @@ -277,7 +289,7 @@ private sealed class ClientRpcScope : RpcScope /// The metadata setter action. /// - private static readonly Action MetadataSetter = (metadata, key, value) => { metadata.Add(new Metadata.Entry(key, value)); }; + private static readonly Action MetadataSetter = (metadata, key, value) => { metadata?.Add(new Metadata.Entry(key, value)); }; /// /// The context. @@ -287,7 +299,7 @@ private sealed class ClientRpcScope : RpcScope /// The parent activity. /// - private readonly Activity parentActivity; + private readonly Activity? parentActivity; /// /// Initializes a new instance of the class. @@ -343,7 +355,7 @@ public ClientRpcScope(ClientInterceptorContext context, Cli this.SetActivity(rpcActivity); options.Propagator.Inject(new PropagationContext(rpcActivity.Context, Baggage.Current), callOptions.Headers, MetadataSetter); - this.context = new ClientInterceptorContext(context.Method, context.Host, callOptions); + this.context = new ClientInterceptorContext(context.Method!, context.Host, callOptions); } /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs index 02d214fea1..4e720ae237 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientTracingInterceptorOptions.cs @@ -28,5 +28,5 @@ public class ClientTracingInterceptorOptions /// /// Gets or sets additional activity tags used during unit testing. /// - internal IReadOnlyDictionary AdditionalTags { get; set; } + internal IReadOnlyDictionary? AdditionalTags { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs index a3a627133a..b7285ca7d3 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/GrpcCoreInstrumentation.cs @@ -25,7 +25,7 @@ internal static class GrpcCoreInstrumentation /// /// The activity source name. /// - internal static readonly string ActivitySourceName = AssemblyName.Name; + internal static readonly string ActivitySourceName = AssemblyName.Name!; /// /// The activity source. diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 099152bc14..c0bd481471 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -4,7 +4,6 @@ .NET gRPC Core based client and server interceptors for OpenTelemetry. $(PackageTags);gRPC Core;interceptors Instrumentation.GrpcCore- - disable - disable diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs index 1d2e9f6129..1d6b01014a 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs @@ -180,7 +180,7 @@ public void GrpcAndHttpClientInstrumentationIsInvoked(bool shouldEnrich) } } - [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1727")] public void GrpcAndHttpClientInstrumentationWithSuppressInstrumentation() { var uri = new Uri($"http://localhost:{this.server.Port}"); @@ -233,7 +233,7 @@ public void GrpcAndHttpClientInstrumentationWithSuppressInstrumentation() Assert.Equal(0, grpcSpan4.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); } - [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1727")] public void GrpcPropagatesContextWithSuppressInstrumentationOptionSetToTrue() { try @@ -350,7 +350,7 @@ public void GrpcDoesNotPropagateContextWithSuppressInstrumentationOptionSetToFal } } - [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1727")] public void GrpcClientInstrumentationRespectsSdkSuppressInstrumentation() { try diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs index a63a1d2f1c..5664716337 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs @@ -30,10 +30,10 @@ public class HttpClientInstrumentationBenchmarks { private static readonly Uri Url = new("http://localhost:5000"); - private HttpClient httpClient; - private WebApplication app; - private TracerProvider tracerProvider; - private MeterProvider meterProvider; + private HttpClient? httpClient; + private WebApplication? app; + private TracerProvider? tracerProvider; + private MeterProvider? meterProvider; [Flags] public enum EnableInstrumentationOption @@ -114,43 +114,43 @@ public void HttpClientRequestGlobalCleanup() { if (this.EnableInstrumentation == EnableInstrumentationOption.None) { - this.httpClient.Dispose(); + this.httpClient?.Dispose(); #pragma warning disable CA2012 // Use ValueTasks correctly - this.app.DisposeAsync().GetAwaiter().GetResult(); + this.app?.DisposeAsync().GetAwaiter().GetResult(); #pragma warning restore CA2012 // Use ValueTasks correctly } else if (this.EnableInstrumentation == EnableInstrumentationOption.Traces) { - this.httpClient.Dispose(); + this.httpClient?.Dispose(); #pragma warning disable CA2012 // Use ValueTasks correctly - this.app.DisposeAsync().GetAwaiter().GetResult(); + this.app?.DisposeAsync().GetAwaiter().GetResult(); #pragma warning restore CA2012 // Use ValueTasks correctly - this.tracerProvider.Dispose(); + this.tracerProvider?.Dispose(); } else if (this.EnableInstrumentation == EnableInstrumentationOption.Metrics) { - this.httpClient.Dispose(); + this.httpClient?.Dispose(); #pragma warning disable CA2012 // Use ValueTasks correctly - this.app.DisposeAsync().GetAwaiter().GetResult(); + this.app?.DisposeAsync().GetAwaiter().GetResult(); #pragma warning restore CA2012 // Use ValueTasks correctly - this.meterProvider.Dispose(); + this.meterProvider?.Dispose(); } else if (this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Traces) && this.EnableInstrumentation.HasFlag(EnableInstrumentationOption.Metrics)) { - this.httpClient.Dispose(); + this.httpClient?.Dispose(); #pragma warning disable CA2012 // Use ValueTasks correctly - this.app.DisposeAsync().GetAwaiter().GetResult(); + this.app?.DisposeAsync().GetAwaiter().GetResult(); #pragma warning restore CA2012 // Use ValueTasks correctly - this.tracerProvider.Dispose(); - this.meterProvider.Dispose(); + this.tracerProvider?.Dispose(); + this.meterProvider?.Dispose(); } } [Benchmark] public async Task HttpClientRequest() { - var httpResponse = await this.httpClient.GetAsync(Url).ConfigureAwait(false); + var httpResponse = await this.httpClient!.GetAsync(Url).ConfigureAwait(false); httpResponse.EnsureSuccessStatusCode(); } diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj index 0b9f55c0c2..3c302f5b49 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj @@ -3,7 +3,6 @@ Exe $(SupportedNetTargets) - disable diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index f9923b869a..38ba3b1cb9 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -32,12 +32,14 @@ public HttpClientTests(ITestOutputHelper output) this.output = output; this.serverLifeTime = TestHttpServer.RunServer( - (ctx) => + ctx => { - string traceparent = ctx.Request.Headers["traceparent"]; - string custom_traceparent = ctx.Request.Headers["custom_traceparent"]; - if ((ctx.Request.Headers["contextRequired"] == null - || bool.Parse(ctx.Request.Headers["contextRequired"])) + var traceparent = ctx.Request.Headers["traceparent"]; + var custom_traceparent = ctx.Request.Headers["custom_traceparent"]; + var contextRequired = ctx.Request.Headers["contextRequired"]; + var responseCode = ctx.Request.Headers["responseCode"]; + if ((contextRequired == null + || bool.Parse(contextRequired)) && (string.IsNullOrWhiteSpace(traceparent) && string.IsNullOrWhiteSpace(custom_traceparent))) @@ -45,18 +47,18 @@ public HttpClientTests(ITestOutputHelper output) ctx.Response.StatusCode = 500; ctx.Response.StatusDescription = "Missing trace context"; } - else if (ctx.Request.Url.PathAndQuery.Contains("500")) + else if (ctx.Request.Url != null && ctx.Request.Url.PathAndQuery.Contains("500")) { ctx.Response.StatusCode = 500; } - else if (ctx.Request.Url.PathAndQuery.Contains("redirect")) + else if (ctx.Request.Url != null && ctx.Request.Url.PathAndQuery.Contains("redirect")) { ctx.Response.RedirectLocation = "/"; ctx.Response.StatusCode = 302; } - else if (ctx.Request.Headers["responseCode"] != null) + else if (responseCode != null) { - ctx.Response.StatusCode = int.Parse(ctx.Request.Headers["responseCode"]); + ctx.Response.StatusCode = int.Parse(responseCode); } else { @@ -78,15 +80,15 @@ public HttpClientTests(ITestOutputHelper output) [Fact] public void AddHttpClientInstrumentation_NamedOptions() { - int defaultExporterOptionsConfigureOptionsInvocations = 0; - int namedExporterOptionsConfigureOptionsInvocations = 0; + var defaultExporterOptionsConfigureOptionsInvocations = 0; + var namedExporterOptionsConfigureOptionsInvocations = 0; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => { - services.Configure(o => defaultExporterOptionsConfigureOptionsInvocations++); + services.Configure(_ => defaultExporterOptionsConfigureOptionsInvocations++); - services.Configure("Instrumentation2", o => namedExporterOptionsConfigureOptionsInvocations++); + services.Configure("Instrumentation2", _ => namedExporterOptionsConfigureOptionsInvocations++); }) .AddHttpClientInstrumentation() .AddHttpClientInstrumentation("Instrumentation2", configureHttpClientTraceInstrumentationOptions: null) @@ -99,8 +101,8 @@ public void AddHttpClientInstrumentation_NamedOptions() [Fact] public void AddHttpClientInstrumentation_BadArgs() { - TracerProviderBuilder builder = null; - Assert.Throws(() => builder.AddHttpClientInstrumentation()); + TracerProviderBuilder? builder = null; + Assert.Throws(() => builder!.AddHttpClientInstrumentation()); } [Theory] @@ -127,22 +129,22 @@ public async Task InjectsHeadersAsync(bool shouldEnrich) { if (shouldEnrich) { - o.EnrichWithHttpWebRequest = (activity, httpWebRequest) => + o.EnrichWithHttpWebRequest = (activity, _) => { activity.SetTag("enrichedWithHttpWebRequest", "yes"); }; - o.EnrichWithHttpWebResponse = (activity, httpWebResponse) => + o.EnrichWithHttpWebResponse = (activity, _) => { activity.SetTag("enrichedWithHttpWebResponse", "yes"); }; - o.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => + o.EnrichWithHttpRequestMessage = (activity, _) => { activity.SetTag("enrichedWithHttpRequestMessage", "yes"); }; - o.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => + o.EnrichWithHttpResponseMessage = (activity, _) => { activity.SetTag("enrichedWithHttpResponseMessage", "yes"); }; @@ -214,15 +216,13 @@ public async Task InjectsHeadersAsync_CustomFormat() { var propagator = new CustomTextMapPropagator(); propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); - propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current?.TraceStateString ?? string.Empty); var exportedItems = new List(); - using var request = new HttpRequestMessage - { - RequestUri = new Uri(this.url), - Method = new HttpMethod("GET"), - }; + using var request = new HttpRequestMessage(); + request.RequestUri = new Uri(this.url); + request.Method = new HttpMethod("GET"); using var parent = new Activity("parent") .SetIdFormat(ActivityIdFormat.W3C) @@ -264,29 +264,27 @@ public async Task InjectsHeadersAsync_CustomFormat() Assert.Equal("k1=v1,k2=v2", traceStates.Single()); #endif - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator( + [ new TraceContextPropagator(), new BaggagePropagator(), - })); + ])); } - [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092")] + [Fact(Skip = "https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1727")] public async Task RespectsSuppress() { try { var propagator = new CustomTextMapPropagator(); propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); - propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current?.TraceStateString ?? string.Empty); var exportedItems = new List(); - using var request = new HttpRequestMessage - { - RequestUri = new Uri(this.url), - Method = new HttpMethod("GET"), - }; + using var request = new HttpRequestMessage(); + request.RequestUri = new Uri(this.url); + request.Method = new HttpMethod("GET"); using var parent = new Activity("parent") .SetIdFormat(ActivityIdFormat.W3C) @@ -316,11 +314,11 @@ public async Task RespectsSuppress() } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator( + [ new TraceContextPropagator(), new BaggagePropagator(), - })); + ])); } } @@ -339,9 +337,9 @@ public async Task ExportsSpansCreatedForRetries() .AddInMemoryExporter(exportedItems) .Build(); - int maxRetries = 3; + var maxRetries = 3; using var clientHandler = new HttpClientHandler(); - using var retryHandler = new RetryHandler(clientHandler, maxRetries); + using var retryHandler = new RepeatHandler(clientHandler, maxRetries); using var httpClient = new HttpClient(retryHandler); await httpClient.SendAsync(request); @@ -386,7 +384,7 @@ public async Task ExportsSpansCreatedForRetries() [InlineData("Patch", "PATCH", "Patch")] [InlineData("Trace", "TRACE", "Trace")] [InlineData("CUSTOM", "_OTHER", "CUSTOM")] - public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMethod, string expectedMethod, string expectedOriginalMethod) + public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMethod, string expectedMethod, string? expectedOriginalMethod) { var exportedItems = new List(); using var request = new HttpRequestMessage @@ -482,13 +480,13 @@ public async Task HttpRequestMethodIsSetonRequestDurationMetricAsPerSpec(string var mp = metricPoints[0]; // Inspect Metric Attributes - var attributes = new Dictionary(); + var attributes = new Dictionary(); foreach (var tag in mp.Tags) { attributes[tag.Key] = tag.Value; } - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == expectedMethod); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value?.ToString() == expectedMethod); Assert.DoesNotContain(attributes, t => t.Key == SemanticConventions.AttributeHttpRequestMethodOriginal); } @@ -513,11 +511,11 @@ public async Task RedirectTest() // found. For now, this is not supported. Assert.Single(exportedItems); - Assert.Contains(exportedItems[0].TagObjects, t => t.Key == "http.response.status_code" && (int)t.Value == 200); + Assert.Contains(exportedItems[0].TagObjects, t => t.Key == "http.response.status_code" && (int?)t.Value == 200); #else Assert.Equal(2, exportedItems.Count); - Assert.Contains(exportedItems[0].TagObjects, t => t.Key == "http.response.status_code" && (int)t.Value == 302); - Assert.Contains(exportedItems[1].TagObjects, t => t.Key == "http.response.status_code" && (int)t.Value == 200); + Assert.Contains(exportedItems[0].TagObjects, t => t.Key == "http.response.status_code" && (int?)t.Value == 302); + Assert.Contains(exportedItems[1].TagObjects, t => t.Key == "http.response.status_code" && (int?)t.Value == 200); #endif } @@ -526,22 +524,22 @@ public async Task RequestNotCollectedWhenInstrumentationFilterApplied() { var exportedItems = new List(); - bool httpWebRequestFilterApplied = false; - bool httpRequestMessageFilterApplied = false; + var httpWebRequestFilterApplied = false; + var httpRequestMessageFilterApplied = false; using (Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation( opt => { - opt.FilterHttpWebRequest = (req) => + opt.FilterHttpWebRequest = req => { httpWebRequestFilterApplied = true; return !req.RequestUri.OriginalString.Contains(this.url); }; - opt.FilterHttpRequestMessage = (req) => + opt.FilterHttpRequestMessage = req => { httpRequestMessageFilterApplied = true; - return !req.RequestUri.OriginalString.Contains(this.url); + return req.RequestUri != null && !req.RequestUri.OriginalString.Contains(this.url); }; }) .AddInMemoryExporter(exportedItems) @@ -569,10 +567,10 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() using (Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation( - (opt) => + opt => { - opt.FilterHttpWebRequest = (req) => throw new Exception("From InstrumentationFilter"); - opt.FilterHttpRequestMessage = (req) => throw new Exception("From InstrumentationFilter"); + opt.FilterHttpWebRequest = _ => throw new Exception("From InstrumentationFilter"); + opt.FilterHttpRequestMessage = _ => throw new Exception("From InstrumentationFilter"); }) .AddInMemoryExporter(exportedItems) .Build()) @@ -580,7 +578,7 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() using var c = new HttpClient(); using var inMemoryEventListener = new InMemoryEventListener(HttpInstrumentationEventSource.Log); await c.GetAsync(new Uri(this.url)); - Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 4)); + Assert.Single(inMemoryEventListener.Events.Where(e => e.EventId == 4)); } Assert.Empty(exportedItems); @@ -590,7 +588,7 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() public async Task ReportsExceptionEventForNetworkFailuresWithGetAsync() { var exportedItems = new List(); - bool exceptionThrown = false; + var exceptionThrown = false; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation(o => o.RecordException = true) @@ -616,7 +614,7 @@ public async Task ReportsExceptionEventForNetworkFailuresWithGetAsync() public async Task DoesNotReportExceptionEventOnErrorResponseWithGetAsync() { var exportedItems = new List(); - bool exceptionThrown = false; + var exceptionThrown = false; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation(o => o.RecordException = true) @@ -642,7 +640,7 @@ public async Task DoesNotReportExceptionEventOnErrorResponseWithGetAsync() public async Task DoesNotReportExceptionEventOnErrorResponseWithGetStringAsync() { var exportedItems = new List(); - bool exceptionThrown = false; + var exceptionThrown = false; using var request = new HttpRequestMessage { RequestUri = new Uri($"{this.url}500"), @@ -704,7 +702,7 @@ public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQ var exportedItems = new List(); var configuration = new ConfigurationBuilder() - .AddInMemoryCollection(new Dictionary { ["OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION"] = disableQueryRedaction.ToString() }) + .AddInMemoryCollection(new Dictionary { ["OTEL_DOTNET_EXPERIMENTAL_HTTPCLIENT_DISABLE_URL_QUERY_REDACTION"] = disableQueryRedaction.ToString() }) .Build(); // Arrange @@ -737,15 +735,17 @@ public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQ [InlineData(false, false)] public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) { +#if NETFRAMEWORK ActivityContext parentContext = default; +#endif ActivityContext contextFromPropagator = default; var propagator = new CustomTextMapPropagator { - Injected = (context) => contextFromPropagator = context.ActivityContext, + Injected = context => contextFromPropagator = context.ActivityContext, }; propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); - propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current?.TraceStateString ?? string.Empty); var exportedItems = new List(); @@ -758,7 +758,7 @@ public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) var previousDefaultTextMapPropagator = Propagators.DefaultTextMapPropagator; Sdk.SetDefaultTextMapPropagator(propagator); - Activity parent = null; + Activity? parent = null; if (createParentActivity) { parent = new Activity("parent") @@ -768,14 +768,14 @@ public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) parent.TraceStateString = "k1=v1,k2=v2"; parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; +#if NETFRAMEWORK parentContext = parent.Context; +#endif } - using var request = new HttpRequestMessage - { - RequestUri = new Uri(this.url), - Method = new HttpMethod("GET"), - }; + using var request = new HttpRequestMessage(); + request.RequestUri = new Uri(this.url); + request.Method = new HttpMethod("GET"); using var c = new HttpClient(); await c.SendAsync(request); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index bbd3908cc5..f13b3c1004 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -103,7 +103,7 @@ public async Task DebugIndividualTestAsync() ", JsonSerializerOptions); - var t = (Task)this.GetType().InvokeMember(nameof(this.HttpOutCallsAreCollectedSuccessfullyTracesAndMetricsSemanticConventionsAsync), BindingFlags.InvokeMethod, null, this, HttpTestData.GetArgumentsFromTestCaseObject(input).First(), CultureInfo.InvariantCulture); + var t = (Task)this.GetType().InvokeMember(nameof(this.HttpOutCallsAreCollectedSuccessfullyTracesAndMetricsSemanticConventionsAsync), BindingFlags.InvokeMethod, null, this, HttpTestData.GetArgumentsFromTestCaseObject(input).First(), CultureInfo.InvariantCulture)!; await t; } #endif @@ -200,13 +200,13 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( if (enableTracing) { tracerProviderBuilder - .AddHttpClientInstrumentation((opt) => + .AddHttpClientInstrumentation(opt => { - opt.EnrichWithHttpWebRequest = (activity, httpRequestMessage) => { enrichWithHttpWebRequestCalled = true; }; - opt.EnrichWithHttpWebResponse = (activity, httpResponseMessage) => { enrichWithHttpWebResponseCalled = true; }; - opt.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; - opt.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; - opt.EnrichWithException = (activity, exception) => { enrichWithExceptionCalled = true; }; + opt.EnrichWithHttpWebRequest = (_, _) => { enrichWithHttpWebRequestCalled = true; }; + opt.EnrichWithHttpWebResponse = (_, _) => { enrichWithHttpWebResponseCalled = true; }; + opt.EnrichWithHttpRequestMessage = (_, _) => { enrichWithHttpRequestMessageCalled = true; }; + opt.EnrichWithHttpResponseMessage = (_, _) => { enrichWithHttpResponseMessageCalled = true; }; + opt.EnrichWithException = (_, _) => { enrichWithExceptionCalled = true; }; opt.RecordException = tc.RecordException ?? false; }); } @@ -293,7 +293,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( Assert.Equal(tc.SpanStatus, activity.Status.ToString()); Assert.Null(activity.StatusDescription); - var normalizedAttributes = activity.TagObjects.Where(kv => !kv.Key.StartsWith("otel.", StringComparison.Ordinal)).ToDictionary(x => x.Key, x => x.Value.ToString()); + var normalizedAttributes = activity.TagObjects.Where(kv => !kv.Key.StartsWith("otel.", StringComparison.Ordinal)).ToDictionary(x => x.Key, x => x.Value?.ToString()); int numberOfTags = activity.Status == ActivityStatusCode.Error ? 5 : 4; @@ -301,18 +301,18 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( Assert.Equal(expectedAttributeCount, normalizedAttributes.Count); - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeUrlFull && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlFull]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeUrlFull && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlFull]); if (tc.ResponseExpected) { - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); if (tc.ResponseCode >= 400) { - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); } } else @@ -323,11 +323,11 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( #if NET8_0_OR_GREATER // we are using fake address so it will be "name_resolution_error" // TODO: test other error types. - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_error"); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "name_resolution_error"); #elif NETFRAMEWORK - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_failure"); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "name_resolution_failure"); #else - Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "System.Net.Http.HttpRequestException"); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "System.Net.Http.HttpRequestException"); #endif } @@ -378,7 +378,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( } // Inspect Metric Attributes - var attributes = new Dictionary(); + var attributes = new Dictionary(); foreach (var tag in metricPoint.Tags) { attributes[tag.Key] = tag.Value; @@ -399,19 +399,19 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( Assert.Equal(expectedAttributeCount, attributes.Count); - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeUrlScheme && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlScheme]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeUrlScheme && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlScheme]); if (tc.ResponseExpected) { - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); if (tc.ResponseCode >= 400) { - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpResponseStatusCode]); } } else @@ -422,12 +422,12 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( #if NET8_0_OR_GREATER // we are using fake address so it will be "name_resolution_error" // TODO: test other error types. - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_error"); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "name_resolution_error"); #elif NETFRAMEWORK - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "name_resolution_failure"); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "name_resolution_failure"); #else - Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value.ToString() == "System.Net.Http.HttpRequestException"); + Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "System.Net.Http.HttpRequestException"); #endif } @@ -463,11 +463,11 @@ private static async Task CheckEnrichment(Sampler sampler, bool enrichExpected, .SetSampler(sampler) .AddHttpClientInstrumentation(options => { - options.EnrichWithHttpWebRequest = (activity, httpRequestMessage) => { enrichWithHttpWebRequestCalled = true; }; - options.EnrichWithHttpWebResponse = (activity, httpResponseMessage) => { enrichWithHttpWebResponseCalled = true; }; + options.EnrichWithHttpWebRequest = (_, _) => { enrichWithHttpWebRequestCalled = true; }; + options.EnrichWithHttpWebResponse = (_, _) => { enrichWithHttpWebResponseCalled = true; }; - options.EnrichWithHttpRequestMessage = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; }; - options.EnrichWithHttpResponseMessage = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; }; + options.EnrichWithHttpRequestMessage = (_, _) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (_, _) => { enrichWithHttpResponseMessageCalled = true; }; }) .Build()) { diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs index 45ffe0e6bf..dd632eb9e5 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs @@ -5,6 +5,20 @@ namespace OpenTelemetry.Instrumentation.Http.Tests; public class HttpOutTestCase { + public HttpOutTestCase(string name, string method, string url, Dictionary? headers, int responseCode, string spanName, bool responseExpected, bool? recordException, string spanStatus, Dictionary spanAttributes) + { + this.Name = name; + this.Method = method; + this.Url = url; + this.Headers = headers; + this.ResponseCode = responseCode; + this.SpanName = spanName; + this.ResponseExpected = responseExpected; + this.RecordException = recordException; + this.SpanStatus = spanStatus; + this.SpanAttributes = spanAttributes; + } + public string Name { get; set; } public string Method { get; set; } @@ -14,7 +28,7 @@ public class HttpOutTestCase #pragma warning restore CA1056 #pragma warning disable CA2227 - public Dictionary Headers { get; set; } + public Dictionary? Headers { get; set; } #pragma warning restore CA2227 public int ResponseCode { get; set; } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs index 14b5b96f6c..7f91eaaf0c 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs @@ -14,21 +14,25 @@ public static IEnumerable ReadTestCases() { var assembly = Assembly.GetExecutingAssembly(); var input = JsonSerializer.Deserialize( - assembly.GetManifestResourceStream("OpenTelemetry.Instrumentation.Http.Tests.http-out-test-cases.json"), + assembly.GetManifestResourceStream("OpenTelemetry.Instrumentation.Http.Tests.http-out-test-cases.json")!, JsonSerializerOptions); return GetArgumentsFromTestCaseObject(input); } - public static IEnumerable GetArgumentsFromTestCaseObject(IEnumerable input) + public static IEnumerable GetArgumentsFromTestCaseObject(IEnumerable? input) { var result = new List(); + if (input == null) + { + return result; + } + foreach (var testCase in input) { - result.Add(new object[] - { - testCase, - }); + result.Add([ + testCase + ]); } return result; diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs index ce30769a4a..ebcb77d0b0 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + #if NETFRAMEWORK using System.Collections.Concurrent; using System.Diagnostics; @@ -27,7 +29,7 @@ static HttpWebRequestActivitySourceTests() { HttpClientTraceInstrumentationOptions options = new() { - EnrichWithHttpWebRequest = (activity, httpWebRequest) => + EnrichWithHttpWebRequest = (_, httpWebRequest) => { VerifyHeaders(httpWebRequest); @@ -714,7 +716,7 @@ public async Task TestMultipleConcurrentRequests() } // wait up to 10 sec for all requests and suppress exceptions - await Task.WhenAll(tasks.Select(t => t.Value).ToArray()).ContinueWith(async tt => + await Task.WhenAll(tasks.Select(t => t.Value).ToArray()).ContinueWith(async _ => { foreach (var task in tasks) { @@ -817,10 +819,10 @@ public ActivitySourceRecorder(Action> onEvent = n { this.activityListener = new ActivityListener { - ShouldListenTo = (activitySource) => activitySource.Name == HttpWebRequestActivitySource.ActivitySourceName, + ShouldListenTo = activitySource => activitySource.Name == HttpWebRequestActivitySource.ActivitySourceName, ActivityStarted = this.ActivityStarted, ActivityStopped = this.ActivityStopped, - Sample = (ref ActivityCreationOptions options) => activitySamplingResult, + Sample = (ref ActivityCreationOptions _) => activitySamplingResult, }; ActivitySource.AddActivityListener(this.activityListener); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs index 3d9bb790d8..a314e456db 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs @@ -11,7 +11,9 @@ using OpenTelemetry.Trace; using Xunit; +#if !NETFRAMEWORK #pragma warning disable SYSLIB0014 // Type or member is obsolete +#endif namespace OpenTelemetry.Instrumentation.Http.Tests; @@ -27,7 +29,7 @@ public HttpWebRequestTests() Activity.ForceDefaultIdFormat = false; this.serverLifeTime = TestHttpServer.RunServer( - (ctx) => + ctx => { if (string.IsNullOrWhiteSpace(ctx.Request.Headers["traceparent"]) && string.IsNullOrWhiteSpace(ctx.Request.Headers["custom_traceparent"]) @@ -36,7 +38,7 @@ public HttpWebRequestTests() ctx.Response.StatusCode = 500; ctx.Response.StatusDescription = "Missing trace context"; } - else if (ctx.Request.Url.PathAndQuery.Contains("500")) + else if (ctx.Request.Url != null && ctx.Request.Url.PathAndQuery.Contains("500")) { ctx.Response.StatusCode = 500; } @@ -95,15 +97,15 @@ public async Task RequestNotCollectedWhenInstrumentationFilterApplied() .AddHttpClientInstrumentation( options => { - options.FilterHttpWebRequest = (req) => + options.FilterHttpWebRequest = req => { httpWebRequestFilterApplied = true; return !req.RequestUri.OriginalString.Contains(this.url); }; - options.FilterHttpRequestMessage = (req) => + options.FilterHttpRequestMessage = req => { httpRequestMessageFilterApplied = true; - return !req.RequestUri.OriginalString.Contains(this.url); + return req.RequestUri != null && !req.RequestUri.OriginalString.Contains(this.url); }; }) .Build(); @@ -135,8 +137,8 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() .AddHttpClientInstrumentation( c => { - c.FilterHttpWebRequest = (req) => throw new Exception("From Instrumentation filter"); - c.FilterHttpRequestMessage = (req) => throw new Exception("From Instrumentation filter"); + c.FilterHttpWebRequest = _ => throw new Exception("From Instrumentation filter"); + c.FilterHttpRequestMessage = _ => throw new Exception("From Instrumentation filter"); }) .Build(); @@ -148,7 +150,7 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() using var response = await request.GetResponseAsync(); - Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 4)); + Assert.Single(inMemoryEventListener.Events.Where(e => e.EventId == 4)); } Assert.Empty(exportedItems); @@ -203,7 +205,9 @@ public async Task InjectsHeadersAsync() [InlineData(false, false)] public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) { +#if NETFRAMEWORK ActivityContext parentContext = default; +#endif ActivityContext contextFromPropagator = default; var propagator = new CustomTextMapPropagator @@ -211,7 +215,7 @@ public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) Injected = (PropagationContext context) => contextFromPropagator = context.ActivityContext, }; propagator.InjectValues.Add("custom_traceParent", context => $"00/{context.ActivityContext.TraceId}/{context.ActivityContext.SpanId}/01"); - propagator.InjectValues.Add("custom_traceState", context => Activity.Current.TraceStateString); + propagator.InjectValues.Add("custom_traceState", context => Activity.Current?.TraceStateString ?? string.Empty); var exportedItems = new List(); @@ -224,7 +228,7 @@ public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) var previousDefaultTextMapPropagator = Propagators.DefaultTextMapPropagator; Sdk.SetDefaultTextMapPropagator(propagator); - Activity parent = null; + Activity? parent = null; if (createParentActivity) { parent = new Activity("parent") @@ -234,7 +238,9 @@ public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) parent.TraceStateString = "k1=v1,k2=v2"; parent.ActivityTraceFlags = ActivityTraceFlags.Recorded; +#if NETFRAMEWORK parentContext = parent.Context; +#endif } var request = (HttpWebRequest)WebRequest.Create(new Uri(this.url)); @@ -275,7 +281,7 @@ public async Task CustomPropagatorCalled(bool sample, bool createParentActivity) [Theory] [InlineData(null)] [InlineData("CustomName")] - public void AddHttpClientInstrumentationUsesOptionsApi(string name) + public void AddHttpClientInstrumentationUsesOptionsApi(string? name) { name ??= Options.DefaultName; @@ -284,7 +290,7 @@ public void AddHttpClientInstrumentationUsesOptionsApi(string name) using var tracerProvider = Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => { - services.Configure(name, o => configurationDelegateInvocations++); + services.Configure(name, _ => configurationDelegateInvocations++); }) .AddHttpClientInstrumentation(name, options => { diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs index abae3baf6f..24ebf2e3fe 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs @@ -8,7 +8,9 @@ using OpenTelemetry.Trace; using Xunit; +#if !NETFRAMEWORK #pragma warning disable SYSLIB0014 // Type or member is obsolete +#endif namespace OpenTelemetry.Instrumentation.Http.Tests; @@ -24,7 +26,7 @@ public partial class HttpWebRequestTests public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) { using var serverLifeTime = TestHttpServer.RunServer( - (ctx) => + ctx => { ctx.Response.StatusCode = tc.ResponseCode == 0 ? 200 : tc.ResponseCode; ctx.Response.OutputStream.Close(); @@ -43,11 +45,11 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) .AddInMemoryExporter(exportedItems) .AddHttpClientInstrumentation(options => { - options.EnrichWithHttpWebRequest = (activity, httpWebRequest) => { enrichWithHttpWebRequestCalled = true; }; - options.EnrichWithHttpWebResponse = (activity, httpWebResponse) => { enrichWithHttpWebResponseCalled = true; }; - options.EnrichWithHttpRequestMessage = (activity, request) => { enrichWithHttpRequestMessageCalled = true; }; - options.EnrichWithHttpResponseMessage = (activity, response) => { enrichWithHttpResponseMessageCalled = true; }; - options.EnrichWithException = (activity, exception) => { enrichWithExceptionCalled = true; }; + options.EnrichWithHttpWebRequest = (_, _) => { enrichWithHttpWebRequestCalled = true; }; + options.EnrichWithHttpWebResponse = (_, _) => { enrichWithHttpWebResponseCalled = true; }; + options.EnrichWithHttpRequestMessage = (_, _) => { enrichWithHttpRequestMessageCalled = true; }; + options.EnrichWithHttpResponseMessage = (_, _) => { enrichWithHttpResponseMessageCalled = true; }; + options.EnrichWithException = (_, _) => { enrichWithExceptionCalled = true; }; options.RecordException = tc.RecordException ?? false; }) .Build(); @@ -98,11 +100,11 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) return HttpTestData.NormalizeValues(x.Value, host, port); }); - foreach (KeyValuePair tag in activity.TagObjects) + foreach (KeyValuePair tag in activity.TagObjects) { - var tagValue = tag.Value.ToString(); + var tagValue = tag.Value?.ToString(); - if (!tc.SpanAttributes.TryGetValue(tag.Key, out string value)) + if (!tc.SpanAttributes.TryGetValue(tag.Key, out string? value)) { if (tag.Key == SpanAttributeConstants.StatusCodeKey) { @@ -179,6 +181,8 @@ public void DebugIndividualTest() } ", JsonSerializerOptions); + + Assert.NotNull(input); this.HttpOutCallsAreCollectedSuccessfully(input); } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 1aa177f6d4..fa09466eda 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -3,9 +3,6 @@ Unit test project for OpenTelemetry HTTP instrumentations net8.0;net7.0;net6.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - - - disable diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs similarity index 78% rename from test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs rename to test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs index d1a977b7e8..43a56ae26f 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/RetryHandler.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs @@ -7,11 +7,11 @@ namespace OpenTelemetry.Tests; -public class RetryHandler : DelegatingHandler +public class RepeatHandler : DelegatingHandler { private readonly int maxRetries; - public RetryHandler(HttpMessageHandler innerHandler, int maxRetries) + public RepeatHandler(HttpMessageHandler innerHandler, int maxRetries) : base(innerHandler) { this.maxRetries = maxRetries; @@ -21,7 +21,7 @@ protected override async Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { - HttpResponseMessage response = null; + HttpResponseMessage? response = null; for (int i = 0; i < this.maxRetries; i++) { response?.Dispose(); @@ -35,6 +35,6 @@ protected override async Task SendAsync( } } - return response; + return response!; } } From 93c7a6980ed1043ad2bc21763192f8e1e981631a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 10 Jul 2024 10:54:39 +0200 Subject: [PATCH 1175/1499] Fix yamlint (#1947) --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/component_owners.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 26d7a172bf..54f28fc566 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -30,7 +30,7 @@ body: - OpenTelemetry.Instrumentation.AWS - OpenTelemetry.Instrumentation.AWSLambda - OpenTelemetry.Instrumentation.Cassandra - - OpenTelemetry.Instrumentation.ConfluentKafka + - OpenTelemetry.Instrumentation.ConfluentKafka - OpenTelemetry.Instrumentation.ElasticsearchClient - OpenTelemetry.Instrumentation.EntityFrameworkCore - OpenTelemetry.Instrumentation.EventCounters diff --git a/.github/component_owners.yml b/.github/component_owners.yml index d4a5aa9ca3..d6855b826a 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -36,7 +36,7 @@ components: src/OpenTelemetry.Instrumentation.Cassandra/: - xsoheilalizadeh src/OpenTelemetry.Instrumentation.ConfluentKafka/: - - g7ed6e + - g7ed6e src/OpenTelemetry.Instrumentation.ElasticsearchClient/: - ejsmith src/OpenTelemetry.Instrumentation.EventCounters/: @@ -133,7 +133,7 @@ components: test/OpenTelemetry.Instrumentation.Cassandra.Tests/: - xsoheilalizadeh test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/: - - g7ed6e + - g7ed6e test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/: - ejsmith test/OpenTelemetry.Instrumentation.EventCounters.Tests/: From 50c055cbe7c1b303bfb3edce567c7356d421795c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 11 Jul 2024 06:53:06 +0200 Subject: [PATCH 1176/1499] Bump System.Text.Json to 8.0.4 due to CVE-2024-30105 (#1945) --- .../OpenTelemetry.Instrumentation.ConfluentKafka.csproj | 2 +- .../OpenTelemetry.Instrumentation.Http.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj index 0d97d693a4..da497e973c 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj @@ -29,7 +29,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index fa09466eda..3a3170cba1 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -18,7 +18,7 @@ - + From 7d3c03ff56fcb5affe43e91a4012efab0a5b5347 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Thu, 11 Jul 2024 07:24:01 +0200 Subject: [PATCH 1177/1499] [tests - resource packages] Use extension method instead of constructor in Tests (#1946) --- .../AzureResourceDetectorTests.cs | 6 +++--- .../OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs | 2 +- .../ProcessDetectorTests.cs | 2 +- .../ProcessRuntimeDetectorTests.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs index 63c52255ac..3e226d5d8e 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs @@ -32,7 +32,7 @@ public void AppServiceResourceDetectorReturnsResourceWithAttributes() { } - var resource = ResourceBuilder.CreateEmpty().AddDetector(new AppServiceResourceDetector()).Build(); + var resource = ResourceBuilder.CreateEmpty().AddAzureAppServiceDetector().Build(); Assert.NotNull(resource); var expectedResourceUri = "/subscriptions/testtestSubscriptionId/resourceGroups/testResourceGroup/providers/Microsoft.Web/sites/sitename"; @@ -65,7 +65,7 @@ public void TestAzureVmResourceDetector() }; }; - var resource = ResourceBuilder.CreateEmpty().AddDetector(new AzureVMResourceDetector()).Build(); + var resource = ResourceBuilder.CreateEmpty().AddAzureVMDetector().Build(); Assert.NotNull(resource); foreach (var field in AzureVMResourceDetector.ExpectedAzureAmsFields) @@ -108,7 +108,7 @@ public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes() { } - var resource = ResourceBuilder.CreateEmpty().AddDetector(new AzureContainerAppsResourceDetector()).Build(); + var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build(); Assert.NotNull(resource); Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppName"), resource.Attributes); diff --git a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs index ea4d30efb0..ef03af3c9c 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs @@ -42,7 +42,7 @@ public class HostDetectorTests [Fact] public void TestHostAttributes() { - var resource = ResourceBuilder.CreateEmpty().AddDetector(new HostDetector()).Build(); + var resource = ResourceBuilder.CreateEmpty().AddHostDetector().Build(); var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); diff --git a/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs b/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs index 7b4e6903b0..1bc4342125 100644 --- a/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Process.Tests/ProcessDetectorTests.cs @@ -10,7 +10,7 @@ public class ProcessDetectorTests [Fact] public void TestProcessAttributes() { - var resource = ResourceBuilder.CreateEmpty().AddDetector(new ProcessDetector()).Build(); + var resource = ResourceBuilder.CreateEmpty().AddProcessDetector().Build(); var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => x.Value); diff --git a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs index 32ce2b4a1a..40b9bdc9f5 100644 --- a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs +++ b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/ProcessRuntimeDetectorTests.cs @@ -10,7 +10,7 @@ public class ProcessRuntimeDetectorTests [Fact] public void TestProcessRuntimeAttributes() { - var resource = ResourceBuilder.CreateEmpty().AddDetector(new ProcessRuntimeDetector()).Build(); + var resource = ResourceBuilder.CreateEmpty().AddProcessRuntimeDetector().Build(); var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); From 8e6692090c2370881f692d13358bbae69e4aacc9 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Thu, 11 Jul 2024 17:54:39 +0200 Subject: [PATCH 1178/1499] [Resources.OperatingSystem] initial implementation (#1943) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + .github/codecov.yml | 5 ++ .github/component_owners.yml | 3 ++ .github/workflows/ci.yml | 13 +++++ .github/workflows/prepare-release.yml | 1 + opentelemetry-dotnet-contrib.sln | 14 +++++ .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 2 + .../AssemblyInfo.cs | 10 ++++ .../CHANGELOG.md | 8 +++ ...Telemetry.Resources.OperatingSystem.csproj | 25 +++++++++ .../OperatingSystemDetector.cs | 52 +++++++++++++++++++ ...peratingSystemResourceBuilderExtensions.cs | 24 +++++++++ .../OperatingSystemSemanticConventions.cs | 18 +++++++ .../README.md | 44 ++++++++++++++++ ...nTelemetry.AotCompatibility.TestApp.csproj | 1 + ...try.Resources.OperatingSystem.Tests.csproj | 14 +++++ .../OperatingSystemDetectorTests.cs | 30 +++++++++++ 19 files changed, 267 insertions(+) create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/README.md create mode 100644 test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj create mode 100644 test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 54f28fc566..849c72d016 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -54,6 +54,7 @@ body: - OpenTelemetry.Resources.Container - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host + - OpenTelemetry.Resources.OperatingSystem - OpenTelemetry.Resources.Process - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index e48fec3575..0c0b930633 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -54,6 +54,7 @@ body: - OpenTelemetry.Resources.Container - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host + - OpenTelemetry.Resources.OperatingSystem - OpenTelemetry.Resources.Process - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS diff --git a/.github/codecov.yml b/.github/codecov.yml index a8f7fd2412..b235a093c0 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -134,6 +134,11 @@ flags: paths: - src/OpenTelemetry.Resources.Host + unittests-Resources.OperatingSystem: + carryforward: true + paths: + - src/OpenTelemetry.Resources.OperatingSystem + unittests-Resources.Process: carryforward: true paths: diff --git a/.github/component_owners.yml b/.github/component_owners.yml index d6855b826a..cdcc10bc42 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -73,6 +73,9 @@ components: src/OpenTelemetry.Resources.Host/: - Kielek - lachmatt + src/OpenTelemetry.Resources.OperatingSystem/: + - Kielek + - lachmatt src/OpenTelemetry.Resources.Process/: - Kielek - lachmatt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ec5e2d6d6..2377e6c994 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,7 @@ jobs: resources-container: ['*/OpenTelemetry.Resources.Container*/**', '!**/*.md'] resources-gcp: ['*/OpenTelemetry.Resources.Gcp*/**', '!**/*.md'] resources-host: ['*/OpenTelemetry.Resources.Host*/**', '!**/*.md'] + resources-operatingsystem: ['*/OpenTelemetry.Resources.OperatingSystem/**', '*/OpenTelemetry.Resources.OperatingSystem.Tests/**', '!**/*.md'] resources-process: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] resources-processruntime: ['*/OpenTelemetry.Resources.ProcessRuntime/**', '*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!**/*.md'] sampler-aws: ['*/OpenTelemetry.Sampler.AWS**/**', '!**/*.md'] @@ -485,6 +486,17 @@ jobs: project-name: Component[OpenTelemetry.Resources.Host] code-cov-name: Resources.Host + build-test-resources-operatingsystem: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'resources-operatingsystem') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Resources.OperatingSystem] + code-cov-name: Resources.OperatingSystem + build-test-resources-process: needs: detect-changes if: | @@ -561,6 +573,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'resources-azure') || contains(needs.detect-changes.outputs.changes, 'resources-container') || contains(needs.detect-changes.outputs.changes, 'resources-host') + || contains(needs.detect-changes.outputs.changes, 'resources-operatingsystem') || contains(needs.detect-changes.outputs.changes, 'resources-process') || contains(needs.detect-changes.outputs.changes, 'resources-processruntime') || contains(needs.detect-changes.outputs.changes, 'sampler-aws') diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index b0673ac73a..11bc31a834 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -44,6 +44,7 @@ on: - OpenTelemetry.Resources.Container - OpenTelemetry.Resources.Gcp - OpenTelemetry.Resources.Host + - OpenTelemetry.Resources.OperatingSystem - OpenTelemetry.Resources.Process - OpenTelemetry.Resources.ProcessRuntime - OpenTelemetry.Sampler.AWS diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index f7508674db..e86c0bd8ee 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -311,6 +311,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Pro EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Process.Tests", "test\OpenTelemetry.Resources.Process.Tests\OpenTelemetry.Resources.Process.Tests.csproj", "{A5EF701C-439E-407F-8BB4-394166000C6D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.OperatingSystem", "src\OpenTelemetry.Resources.OperatingSystem\OpenTelemetry.Resources.OperatingSystem.csproj", "{F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.OperatingSystem.Tests", "test\OpenTelemetry.Resources.OperatingSystem.Tests\OpenTelemetry.Resources.OperatingSystem.Tests.csproj", "{62B7060A-C35B-4D49-A0C2-3BF02880A200}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Host", "src\OpenTelemetry.Resources.Host\OpenTelemetry.Resources.Host.csproj", "{033CA8D4-1529-413A-B244-07958D5F9A48}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Resources.Host.Tests", "test\OpenTelemetry.Resources.Host.Tests\OpenTelemetry.Resources.Host.Tests.csproj", "{36271347-2055-438E-9659-B71542A17A73}" @@ -803,6 +807,14 @@ Global {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.Build.0 = Release|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.Build.0 = Release|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -927,6 +939,8 @@ Global {BE40900A-2859-471D-8802-21DFD73DDAA7} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {3A464E7A-42F3-44B0-B8D7-80521A7704A6} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {9B994669-E839-4C42-A0F1-DF9DD058C1DC} = {3A464E7A-42F3-44B0-B8D7-80521A7704A6} + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {62B7060A-C35B-4D49-A0C2-3BF02880A200} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..46c3056f23 --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +OpenTelemetry.Resources.OperatingSystemResourceBuilderExtensions +static OpenTelemetry.Resources.OperatingSystemResourceBuilderExtensions.AddOperatingSystemDetector(this OpenTelemetry.Resources.ResourceBuilder! builder) -> OpenTelemetry.Resources.ResourceBuilder! diff --git a/src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs b/src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs new file mode 100644 index 0000000000..a71b8adff5 --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/AssemblyInfo.cs @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.OperatingSystem.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Resources.OperatingSystem.Tests")] +#endif diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md new file mode 100644 index 0000000000..940f68332a --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## Unreleased + +* Initial release of + `OpenTelemetry.ResourceDetectors.OperatingSystem` + project. + ([#1943](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1943)) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj new file mode 100644 index 0000000000..de79c48fe9 --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj @@ -0,0 +1,25 @@ + + + + + net6.0 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Extensions - Operating System Resource Detector for .NET + Resources.OperatingSystem- + + + + + true + + + + + + + + + + + diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs new file mode 100644 index 0000000000..b0a6101bad --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs @@ -0,0 +1,52 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using static OpenTelemetry.Resources.OperatingSystem.OperatingSystemSemanticConventions; + +namespace OpenTelemetry.Resources.OperatingSystem; + +/// +/// Operating system detector. +/// +internal sealed class OperatingSystemDetector : IResourceDetector +{ + /// + /// Detects the resource attributes from the operating system. + /// + /// Resource with key-value pairs of resource attributes. + public Resource Detect() + { + var osType = GetOSType(); + + if (osType == null) + { + return Resource.Empty; + } + + return new Resource( + [ + new(AttributeOperatingSystemType, osType), + ]); + } + + private static string? GetOSType() + { + var platform = Environment.OSVersion.Platform; + if (platform == PlatformID.Win32NT) + { + return OperatingSystemsValues.Windows; + } + + if (platform == PlatformID.MacOSX) + { + return OperatingSystemsValues.Darwin; + } + + if (platform == PlatformID.Unix) + { + return OperatingSystemsValues.Linux; + } + + return null; + } +} diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs new file mode 100644 index 0000000000..bab83370e9 --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Internal; +using OpenTelemetry.Resources.OperatingSystem; + +namespace OpenTelemetry.Resources; + +/// +/// Extension methods to simplify registering of operating system detectors. +/// +public static class OperatingSystemResourceBuilderExtensions +{ + /// + /// Enables operating system detector. + /// + /// being configured. + /// The instance of being configured. + public static ResourceBuilder AddOperatingSystemDetector(this ResourceBuilder builder) + { + Guard.ThrowIfNull(builder); + return builder.AddDetector(new OperatingSystemDetector()); + } +} diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs new file mode 100644 index 0000000000..356ad734da --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Resources.OperatingSystem; + +internal static class OperatingSystemSemanticConventions +{ + public const string AttributeOperatingSystemType = "os.type"; + + public static class OperatingSystemsValues + { + public const string Windows = "windows"; + + public const string Linux = "linux"; + + public const string Darwin = "darwin"; + } +} diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md new file mode 100644 index 0000000000..4c78424bff --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md @@ -0,0 +1,44 @@ +# Operating System Detectors + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.OperatingSyatem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSyatem) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.OperatingSyatem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSyatem) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.OperatingSyatem)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.OperatingSyatem) + +> [!IMPORTANT] +> Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/resource/os.md). +> These resources can be changed without prior notification. + +## Getting Started + +You need to install the +`OpenTelemetry.Resources.OperatingSystem` package to be able to use the +Operating System Resource Detectors. + +```shell +dotnet add package OpenTelemetry.Resources.OperatingSystem --prerelease +``` + +## Usage + +You can configure Operating System resource detector to +the `TracerProvider` with the following example below. + +```csharp +using OpenTelemetry; +using OpenTelemetry.Resources; + +var tracerProvider = Sdk.CreateTracerProviderBuilder() + // other configurations + .ConfigureResource(resource => resource + .AddOperatingSystemDetector()) + .Build(); +``` + +The resource detectors will record the following metadata based on where +your application is running: + +- **OperatingSystemDetector**: `os.type`. + +## References + +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index e71582d2e8..c4d79207e0 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -35,6 +35,7 @@ + diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj new file mode 100644 index 0000000000..c5b25f22ea --- /dev/null +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj @@ -0,0 +1,14 @@ + + + + Unit test project for Operating System Detector for OpenTelemetry + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + + + diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs new file mode 100644 index 0000000000..68cb378e34 --- /dev/null +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs @@ -0,0 +1,30 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Xunit; + +namespace OpenTelemetry.Resources.OperatingSystem.Test; + +public class OperatingSystemDetectorTests +{ + [Fact] + public void TestOperatingSystemAttributes() + { + var resource = ResourceBuilder.CreateEmpty().AddOperatingSystemDetector().Build(); + + var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + + var operatingSystems = new[] + { + OperatingSystemSemanticConventions.OperatingSystemsValues.Windows, + OperatingSystemSemanticConventions.OperatingSystemsValues.Linux, + OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin, + }; + + Assert.Single(resourceAttributes); + + Assert.True(resourceAttributes.ContainsKey(OperatingSystemSemanticConventions.AttributeOperatingSystemType)); + + Assert.Contains(resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemType], operatingSystems); + } +} From 65e3ffe16b2f309467b68c28d3d245219a131f81 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 11 Jul 2024 17:59:18 +0200 Subject: [PATCH 1179/1499] [release] Prepare release Resources.OperatingSystem-0.1.0-alpha.1 (#1950) --- src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index 940f68332a..c009449b27 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.1 + +Released 2024-Jul-11 + * Initial release of `OpenTelemetry.ResourceDetectors.OperatingSystem` project. From 7d03e00e63f9af05239069b5411d15fee1fc955f Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 12 Jul 2024 15:32:05 +0000 Subject: [PATCH 1180/1499] [repo] Clarify resource detectors README (#1952) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- .../AWSResourceBuilderExtensions.cs | 16 +++--- src/OpenTelemetry.Resources.AWS/README.md | 25 ++++++--- .../AzureResourceBuilderExtensions.cs | 12 ++-- src/OpenTelemetry.Resources.Azure/README.md | 56 +++++++++++++------ .../ContainerResourceBuilderExtensions.cs | 4 +- .../README.md | 24 ++++++-- .../GcpResourceBuilderExtensions.cs | 4 +- src/OpenTelemetry.Resources.Gcp/README.md | 23 +++++--- .../HostResourceBuilderExtensions.cs | 4 +- src/OpenTelemetry.Resources.Host/README.md | 24 ++++++-- ...peratingSystemResourceBuilderExtensions.cs | 4 +- .../README.md | 24 ++++++-- .../ProcessResourceBuilderExtensions.cs | 4 +- src/OpenTelemetry.Resources.Process/README.md | 24 ++++++-- ...ProcessRuntimeResourceBuilderExtensions.cs | 4 +- .../README.md | 24 ++++++-- 16 files changed, 187 insertions(+), 89 deletions(-) diff --git a/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs index 8ac475c773..f963f1e672 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class AWSResourceBuilderExtensions /// /// Enables AWS Elastic Beanstalk resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAWSEBSDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); @@ -25,8 +25,8 @@ public static ResourceBuilder AddAWSEBSDetector(this ResourceBuilder builder) /// /// Enables AWS EC2 resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAWSEC2Detector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); @@ -37,8 +37,8 @@ public static ResourceBuilder AddAWSEC2Detector(this ResourceBuilder builder) /// /// Enables AWS ECS resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAWSECSDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); @@ -48,8 +48,8 @@ public static ResourceBuilder AddAWSECSDetector(this ResourceBuilder builder) /// /// Enables AWS EKS resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAWSEKSDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.AWS/README.md b/src/OpenTelemetry.Resources.AWS/README.md index 0be07390c8..67e17fc329 100644 --- a/src/OpenTelemetry.Resources.AWS/README.md +++ b/src/OpenTelemetry.Resources.AWS/README.md @@ -20,18 +20,29 @@ dotnet add package OpenTelemetry.Resources.AWS ## Usage You can configure AWS resource detector to -the `TracerProvider` with the following EC2 example below. +the `ResourceBuilder` with the following EC2 example. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .SetResourceBuilder(ResourceBuilder - .CreateEmpty() - .AddAWSEC2Detector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddAWSEC2Detector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddAWSEC2Detector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAWSEC2Detector()); + }); +}); ``` The resource detectors will record the following metadata based on where diff --git a/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs index 588e92ccad..9287810786 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class AzureResourceBuilderExtensions /// /// Enables Azure App Service resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAzureAppServiceDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); @@ -25,8 +25,8 @@ public static ResourceBuilder AddAzureAppServiceDetector(this ResourceBuilder bu /// /// Enables Azure VM resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAzureVMDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); @@ -36,8 +36,8 @@ public static ResourceBuilder AddAzureVMDetector(this ResourceBuilder builder) /// /// Enables Azure Container Apps resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddAzureContainerAppsDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.Azure/README.md b/src/OpenTelemetry.Resources.Azure/README.md index 7c7988d4b6..bc9911f1eb 100644 --- a/src/OpenTelemetry.Resources.Azure/README.md +++ b/src/OpenTelemetry.Resources.Azure/README.md @@ -18,17 +18,29 @@ dotnet add package --prerelease OpenTelemetry.Resources.Azure Adds resource attributes for the applications running in Azure App Service. The following example shows how to add `AppServiceResourceDetector` to -`TracerProvider` configuration, but this can be added to logs and metrics -as well. +the `ResourceBuilder`. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource.AddAzureAppServiceDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddAzureAppServiceDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddAzureAppServiceDetector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddAzureAppServiceDetector()); + }); +}); ``` | Attribute | Description | @@ -47,17 +59,21 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() Adds resource attributes for the applications running in an Azure virtual machine. The following example shows how to add `AzureVMResourceDetector` to -`TracerProvider` configuration, but this can be added to logs and metrics -as well. +the `ResourceBuilder`. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource.AddAzureVMDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddAzureVMDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddAzureVMDetector()) + // other configurations + .Build(); ``` | Attribute | Description | @@ -79,17 +95,21 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() Adds resource attributes for the applications running in Azure Container Apps. The following example shows how to add `AzureContainerAppsResourceDetector` to -`TracerProvider` configuration, but this can be added to logs and metrics as -well. +the `ResourceBuilder`. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource.AddAzureContainerAppsDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddAzureContainerAppsDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddAzureContainerAppsDetector()) + // other configurations + .Build(); ``` | Attribute | Description | diff --git a/src/OpenTelemetry.Resources.Container/ContainerResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Container/ContainerResourceBuilderExtensions.cs index 983ea2af7b..32a99eddd8 100644 --- a/src/OpenTelemetry.Resources.Container/ContainerResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.Container/ContainerResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class ContainerResourceBuilderExtensions /// /// Enables Container resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddContainerDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.Container/README.md b/src/OpenTelemetry.Resources.Container/README.md index 83692e50c5..c0b32b05fc 100644 --- a/src/OpenTelemetry.Resources.Container/README.md +++ b/src/OpenTelemetry.Resources.Container/README.md @@ -17,17 +17,29 @@ dotnet add package OpenTelemetry.Resources.Container --prerelease ## Usage You can configure Container resource detector to -the `TracerProvider` with the following example below. +the `ResourceBuilder` with the following example. ```csharp using OpenTelemetry; using OpenTelemetry.Resources.Container; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource - .AddContainerDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddContainerDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddContainerDetector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddContainerDetector()); + }); +}); ``` The resource detectors will record the following metadata based on where diff --git a/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs index 154242bb04..3a926a05cc 100644 --- a/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.Gcp/GcpResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class GcpResourceBuilderExtensions /// /// Enables Google Cloud Platform resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddGcpDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.Gcp/README.md b/src/OpenTelemetry.Resources.Gcp/README.md index af45be5fd7..940a0e2942 100644 --- a/src/OpenTelemetry.Resources.Gcp/README.md +++ b/src/OpenTelemetry.Resources.Gcp/README.md @@ -8,33 +8,40 @@ This package contains [Resource Detectors](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#detecting-resource-information-from-the-environment) for applications running in Google Cloud Platform environments. -## Installation +## Getting Started + +You need to install the +`OpenTelemetry.Resources.Gcp` package to be able to use the +Google Cloud Platform Resource Detectors. ```shell dotnet add package --prerelease OpenTelemetry.Resources.Gcp ``` +## Usage + +You can configure Google Cloud Platform resource detector to +the `ResourceBuilder` with the following example. + ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -using var meterProvider = Sdk.CreateMeterProviderBuilder() - // other configurations +using var tracerProvider = Sdk.CreateTracerProviderBuilder() .ConfigureResource(resource => resource.AddGcpDetector()) + // other configurations .Build(); -using var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations +using var meterProvider = Sdk.CreateMeterProviderBuilder() .ConfigureResource(resource => resource.AddGcpDetector()) + // other configurations .Build(); using var loggerFactory = LoggerFactory.Create(builder => { builder.AddOpenTelemetry(options => { - options.SetResourceBuilder(ResourceBuilder - .CreateDefault() - .AddGcpDetector()); + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddGcpDetector()); }); }); ``` diff --git a/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs index d1253685f3..f2085e0c33 100644 --- a/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.Host/HostResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class HostResourceBuilderExtensions /// /// Enables host resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddHostDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.Host/README.md b/src/OpenTelemetry.Resources.Host/README.md index 607816e688..9d0f5283dc 100644 --- a/src/OpenTelemetry.Resources.Host/README.md +++ b/src/OpenTelemetry.Resources.Host/README.md @@ -21,17 +21,29 @@ dotnet add package OpenTelemetry.Resources.Host --prerelease ## Usage You can configure Host resource detector to -the `TracerProvider` with the following example below. +the `ResourceBuilder` with the following example. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource - .AddHostDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddHostDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddHostDetector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddHostDetector()); + }); +}); ``` The resource detectors will record the following metadata based on where diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs index bab83370e9..0f611859fc 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class OperatingSystemResourceBuilderExtensions /// /// Enables operating system detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddOperatingSystemDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md index 4c78424bff..6673daf190 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/README.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md @@ -21,17 +21,29 @@ dotnet add package OpenTelemetry.Resources.OperatingSystem --prerelease ## Usage You can configure Operating System resource detector to -the `TracerProvider` with the following example below. +the `ResourceBuilder` with the following example. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource - .AddOperatingSystemDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddOperatingSystemDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddOperatingSystemDetector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddOperatingSystemDetector()); + }); +}); ``` The resource detectors will record the following metadata based on where diff --git a/src/OpenTelemetry.Resources.Process/ProcessResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.Process/ProcessResourceBuilderExtensions.cs index 466a4b925a..14831dedc9 100644 --- a/src/OpenTelemetry.Resources.Process/ProcessResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.Process/ProcessResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class ProcessResourceBuilderExtensions /// /// Enables process resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddProcessDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.Process/README.md b/src/OpenTelemetry.Resources.Process/README.md index ceeefb728e..4c837abfa7 100644 --- a/src/OpenTelemetry.Resources.Process/README.md +++ b/src/OpenTelemetry.Resources.Process/README.md @@ -21,16 +21,28 @@ dotnet add package OpenTelemetry.Resources.Process --prerelease ## Usage You can configure Process Runtime resource detector to -the `TracerProvider` with the following example below. +the `ResourceBuilder` with the following example. ```csharp using OpenTelemetry; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource - .AddProcessDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddProcessDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddProcessDetector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddProcessDetector()); + }); +}); ``` The resource detectors will record the following metadata based on where diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeResourceBuilderExtensions.cs index 827c3527e4..e77e34cb99 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeResourceBuilderExtensions.cs @@ -14,8 +14,8 @@ public static class ProcessRuntimeResourceBuilderExtensions /// /// Enables process runtime resource detector. /// - /// being configured. - /// The instance of being configured. + /// The being configured. + /// The instance of being configured. public static ResourceBuilder AddProcessRuntimeDetector(this ResourceBuilder builder) { Guard.ThrowIfNull(builder); diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/README.md b/src/OpenTelemetry.Resources.ProcessRuntime/README.md index 03f4db0eda..d74449e508 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/README.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/README.md @@ -21,17 +21,29 @@ dotnet add package OpenTelemetry.Resources.ProcessRuntime --prerelease ## Usage You can configure Process Runtime resource detector to -the `TracerProvider` with the following example below. +the `ResourceBuilder` with the following example. ```csharp using OpenTelemetry; using OpenTelemetry.Resources; -var tracerProvider = Sdk.CreateTracerProviderBuilder() - // other configurations - .ConfigureResource(resource => resource - .AddProcessRuntimeDetector()) - .Build(); +using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .ConfigureResource(resource => resource.AddProcessRuntimeDetector()) + // other configurations + .Build(); + +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .ConfigureResource(resource => resource.AddProcessRuntimeDetector()) + // other configurations + .Build(); + +using var loggerFactory = LoggerFactory.Create(builder => +{ + builder.AddOpenTelemetry(options => + { + options.SetResourceBuilder(ResourceBuilder.CreateDefault().AddProcessRuntimeDetector()); + }); +}); ``` The resource detectors will record the following metadata based on where From d4d00a5295b332ea36486bbd98bbb730a02535a0 Mon Sep 17 00:00:00 2001 From: Mike Goldsmith Date: Tue, 16 Jul 2024 21:04:54 +0100 Subject: [PATCH 1181/1499] [Extensions] Update BaggageActivityProcessor to use baggage key predicate (#1816) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Cijo Thomas Co-authored-by: Tyler Helmuth <12352919+TylerHelmuth@users.noreply.github.com> --- .../.publicApi/PublicAPI.Unshipped.txt | 5 +- src/OpenTelemetry.Extensions/CHANGELOG.md | 3 + .../OpenTelemetryExtensionsEventSource.cs | 6 + src/OpenTelemetry.Extensions/README.md | 30 +++- .../Trace/BaggageActivityProcessor.cs | 27 +++- .../TracerProviderBuilderExtensions.cs | 20 ++- .../Trace/BaggageActivityProcessorTests.cs | 139 ++++++++++++++++++ 7 files changed, 219 insertions(+), 11 deletions(-) create mode 100644 test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs diff --git a/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt index 4b388d9972..76f352124e 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt @@ -8,7 +8,10 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> Sys OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void +OpenTelemetry.Trace.BaggageActivityProcessor OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Trace.BaggageActivityProcessor.OnStart(System.Diagnostics.Activity! data) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Trace.BaggageActivityProcessor.AllowAllBaggageKeys.get -> System.Predicate! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddBaggageActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Predicate! baggageKeyPredicate) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 92a5f5775b..fde331e39a 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Update BaggageActivityProcessor to require baggage key predicate. + ([#1816](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1816)) + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index 720933f0d9..7cef228fb4 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -43,4 +43,10 @@ public void LogRecordFilterException(string? categoryName, string exception) { this.WriteEvent(2, categoryName, exception); } + + [Event(3, Message = "Baggage key predicate threw exeption when trying to add baggage entry with key '{0}'. Baggage entry will not be added to the activity. Exception: '{1}'", Level = EventLevel.Warning)] + public void BaggageKeyPredicateException(string baggageKey, string exception) + { + this.WriteEvent(3, baggageKey, exception); + } } diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index 8c45cd56a7..38dde99d1f 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -46,10 +46,36 @@ and adds the baggage keys and values to the `Activity` as tags (attributes) on s Add this activity processor to a tracer provider. -Example of adding BaggageActivityProcessor to `TracerProvider`: +For example, to add all baggage entries to new activities: ```cs var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddBaggageActivityProcessor() + .AddBaggageActivityProcessor(BaggageActivityProcessor.AllowAllBaggageKeys) .Build(); ``` + +Alternatively, you can select which baggage keys you want to copy using a +custom predicate function. + +For example, to only copy baggage entries where the key start with `my-key` +using a custom function: + +```cs +var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor((baggageKey) => baggageKey.StartWith("my-key", System.StringComparison.Ordinal)) + .Build(); +``` + +For example, to only copy baggage entries where the key matches the regular +expression `^my-key`: + +```cs +var baggageKeyRegex = new Regex("^mykey", RegexOptions.Compiled); +var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor((baggageKey) => baggageKeyRegex.IsMatch(baggageKey)) + .Build(); +``` + +Warning: The baggage key predicate is executed for every baggage entry for each +started activity. +Do not use slow or intensive operations. diff --git a/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs index 23d08dec76..e85845b197 100644 --- a/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs +++ b/src/OpenTelemetry.Extensions/Trace/BaggageActivityProcessor.cs @@ -6,16 +6,35 @@ namespace OpenTelemetry.Trace; /// -/// Activity processor that adds fields to every new span. +/// Activity processor that adds fields to every new activity. /// -internal sealed class BaggageActivityProcessor : BaseProcessor +public sealed class BaggageActivityProcessor : BaseProcessor { + private readonly Predicate baggageKeyPredicate; + + /// + /// Initializes a new instance of the class. + /// + /// Predicate to determine which baggage keys should be added to the activity. + internal BaggageActivityProcessor(Predicate baggageKeyPredicate) + { + this.baggageKeyPredicate = baggageKeyPredicate ?? throw new ArgumentNullException(nameof(baggageKeyPredicate)); + } + + /// + /// Gets a baggage key predicate that returns true for all baggage keys. + /// + public static Predicate AllowAllBaggageKeys => (_) => true; + /// - public override void OnStart(Activity activity) + public override void OnStart(Activity data) { foreach (var entry in Baggage.Current) { - activity.SetTag(entry.Key, entry.Value); + if (this.baggageKeyPredicate(entry.Key)) + { + data?.SetTag(entry.Key, entry.Value); + } } } } diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index 321369ffc1..8ab9da3ac7 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -51,14 +51,26 @@ public static TracerProviderBuilder AddAutoFlushActivityProcessor( /// Adds the to the . /// /// to add the to. + /// Predicate to determine which baggage keys should be added to the activity. /// The instance of to chain the calls. public static TracerProviderBuilder AddBaggageActivityProcessor( - this TracerProviderBuilder builder) + this TracerProviderBuilder builder, + Predicate baggageKeyPredicate) { Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(baggageKeyPredicate); -#pragma warning disable CA2000 // Dispose objects before losing scope - return builder.AddProcessor(new BaggageActivityProcessor()); -#pragma warning restore CA2000 // Dispose objects before losing scope + return builder.AddProcessor(b => new BaggageActivityProcessor(baggageKey => + { + try + { + return baggageKeyPredicate(baggageKey); + } + catch (Exception exception) + { + OpenTelemetryExtensionsEventSource.Log.BaggageKeyPredicateException(baggageKey, exception.Message); + return false; + } + })); } } diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs new file mode 100644 index 0000000000..1f96b7c72d --- /dev/null +++ b/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs @@ -0,0 +1,139 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Tests.Trace; + +public class BaggageActivityProcessorTests +{ + [Fact] + public void BaggageActivityProcessor_CanAddAllowAllBaggageKeysPredicate() + { + var sourceName = GetTestMethodName(); + + using var provider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor(BaggageActivityProcessor.AllowAllBaggageKeys) + .AddSource(sourceName) + .Build(); + + Baggage.SetBaggage("key", "value"); + Baggage.SetBaggage("other_key", "other_value"); + + using var source = new ActivitySource(sourceName); + using var activity = source.StartActivity("name", ActivityKind.Server); + Assert.NotNull(activity); + activity.Stop(); + + Assert.Contains(activity.Tags, kv => kv.Key == "key" && kv.Value == "value"); + Assert.Contains(activity.Tags, kv => kv.Key == "other_key" && kv.Value == "other_value"); + } + + [Fact] + public void BaggageActivityProcessor_CanUseCustomPredicate() + { + var sourceName = GetTestMethodName(); + + using var provider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor((baggageKey) => baggageKey.StartsWith("key", StringComparison.Ordinal)) + .AddSource(sourceName) + .Build(); + + Baggage.SetBaggage("key", "value"); + Baggage.SetBaggage("other_key", "other_value"); + + using var source = new ActivitySource(sourceName); + using var activity = source.StartActivity("name", ActivityKind.Client); + Assert.NotNull(activity); + activity.Stop(); + + Assert.Contains(activity.Tags, kv => kv.Key == "key" && kv.Value == "value"); + Assert.DoesNotContain(activity.Tags, kv => kv.Key == "other_key" && kv.Value == "other_value"); + } + + [Fact] + public void BaggageActivityProcessor_CanUseRegex() + { + var sourceName = GetTestMethodName(); + + var regex = new Regex("^mykey", RegexOptions.Compiled); + using var provider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor((baggageKey) => regex.IsMatch(baggageKey)) + .AddSource(sourceName) + .Build(); + + Baggage.SetBaggage("mykey", "value"); + Baggage.SetBaggage("other_key", "other_value"); + + using var source = new ActivitySource(sourceName); + using var activity = source.StartActivity("name", ActivityKind.Client); + Assert.NotNull(activity); + activity.Stop(); + + Assert.Contains(activity.Tags, kv => kv.Key == "mykey" && kv.Value == "value"); + Assert.DoesNotContain(activity.Tags, kv => kv.Key == "other_key" && kv.Value == "other_value"); + } + + [Fact] + public void BaggageActivityProcessor_PredicateThrows_DoesNothing() + { + var sourceName = GetTestMethodName(); + + using var provider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor(_ => throw new Exception("Predicate throws an exception.")) + .AddSource(sourceName) + .Build(); + + Baggage.SetBaggage("key", "value"); + + using var source = new ActivitySource(sourceName); + using var activity = source.StartActivity("name", ActivityKind.Server); + Assert.NotNull(activity); + activity.Stop(); + + Assert.DoesNotContain(activity.Tags, kv => kv.Key == "key" && kv.Value == "value"); + } + + [Fact] + public void BaggageActivityProcessor_PredicateThrows_OnlyDropsEntriesThatThrow() + { + var sourceName = GetTestMethodName(); + + // First call to predicate should not throw, second call should. + using var provider = Sdk.CreateTracerProviderBuilder() + .AddBaggageActivityProcessor(key => + { + if (key == "key") + { + throw new Exception("Predicate throws an exception."); + } + + return true; + }) + .AddSource(sourceName) + .Build(); + + Baggage.SetBaggage("key", "value"); + Baggage.SetBaggage("other_key", "other_value"); + Baggage.SetBaggage("another_key", "another_value"); + + using var source = new ActivitySource(sourceName); + using var activity = source.StartActivity("name", ActivityKind.Server); + Assert.NotNull(activity); + activity.Stop(); + + // Only keys that do not throw should be added. + Assert.DoesNotContain(activity.Tags, kv => kv.Key == "key" && kv.Value == "value"); + Assert.Contains(activity.Tags, kv => kv.Key == "other_key" && kv.Value == "other_value"); + Assert.Contains(activity.Tags, kv => kv.Key == "another_key" && kv.Value == "another_value"); + } + + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } +} From 67494758e39c3f54815e46ee1cfc75a68f287c94 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 16 Jul 2024 13:53:23 -0700 Subject: [PATCH 1182/1499] [infra] Sync up add-labels with changes from main repo (#1963) Co-authored-by: Cijo Thomas --- 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 d7d66c8396..39da844873 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 273f3e5672beb5cb27af4929b3b06c98b6a04fde Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:31:07 -0400 Subject: [PATCH 1183/1499] [Instrumentation.StackExchangeRedis] @matt-hensley as component owner (#1966) --- .github/component_owners.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index cdcc10bc42..907bf3b71b 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -53,6 +53,8 @@ components: - Yun-Ting src/OpenTelemetry.Instrumentation.Quartz/: - maldago + src/OpenTelemetry.Instrumentation.StackExchangeRedis/: + - matt-hensley src/OpenTelemetry.Instrumentation.Runtime/: - twenzel - xiang17 @@ -151,6 +153,8 @@ components: - codeblanch test/OpenTelemetry.Instrumentation.Quartz.Tests/: - maldago + test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/: + - matt-hensley test/OpenTelemetry.Instrumentation.Runtime.Tests/: - twenzel - xiang17 From fde21f13d9570068b0d8bb27ef2f0ca5590436c8 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Mon, 22 Jul 2024 00:28:30 -0400 Subject: [PATCH 1184/1499] [Instrumentation.StackExchangeRedis] Updates `StackExchange.Redis` to `2.6.122` (#1961) --- build/Common.props | 2 +- .../CHANGELOG.md | 3 +++ .../StackExchangeRedisCallsInstrumentationTests.cs | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/build/Common.props b/build/Common.props index 3cf54473e1..fc7ab24872 100644 --- a/build/Common.props +++ b/build/Common.props @@ -42,7 +42,7 @@ [1.9.0-beta.2] [1.9.0,2.0) [1.9.0-rc.1] - [2.1.58,3.0) + [2.6.122,3.0) [2.3.0,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 031a6df25c..80fbb88f08 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -5,6 +5,9 @@ * Add support for instrumenting `IConnectionMultiplexer` which is added with service key. ([#1885](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1885)) +* Update `StackExchange.Redis` version to `2.6.122`, resolving warnings about + [CVE-2021-24112](https://github.com/advisories/GHSA-rxg9-xrhp-64gj). + ([#1961](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1961)) ## 1.0.0-rc9.15 diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 62487bf2d7..4ede2553fa 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -36,7 +36,7 @@ public void SuccessfulCommandTestWithKey(string value) { AbortOnConnectFail = true, }; - connectionOptions.EndPoints.Add(RedisEndPoint); + connectionOptions.EndPoints.Add(RedisEndPoint!); using var connection = ConnectionMultiplexer.Connect(connectionOptions); var db = connection.GetDatabase(); @@ -90,7 +90,7 @@ public void SuccessfulCommandTest(string value, string? serviceKey) { AbortOnConnectFail = true, }; - connectionOptions.EndPoints.Add(RedisEndPoint); + connectionOptions.EndPoints.Add(RedisEndPoint!); ConnectionMultiplexer? connection = null; var exportedItems = new List(); @@ -173,7 +173,7 @@ public void CanEnrichActivityFromCommand(string value) { AbortOnConnectFail = true, }; - connectionOptions.EndPoints.Add(RedisEndPoint); + connectionOptions.EndPoints.Add(RedisEndPoint!); using var connection = ConnectionMultiplexer.Connect(connectionOptions); var exportedItems = new List(); From b4d902909bd6ba638a20ebe0acd15459d092837a Mon Sep 17 00:00:00 2001 From: Ilia Brahinets Date: Mon, 22 Jul 2024 07:49:14 +0300 Subject: [PATCH 1185/1499] [Instrumentation.GrpcCore] Update minimal supported version of Grpc.Core.Api to 2.46.6 (#1940) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md | 5 +++-- .../ClientStreamWriterProxy.cs | 2 +- .../OpenTelemetry.Instrumentation.GrpcCore.csproj | 2 +- .../ServerStreamWriterProxy.cs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 276fedf468..70c54522c2 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -4,8 +4,9 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) -* Updated minimal supported version of `Grpc.Core.Api` to `2.43.0`. - ([#1936](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1936)) +* Updated minimal supported version of `Grpc.Core.Api` to `2.46.6`. + ([#1936](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1936), + [#1940](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1940)) ## 1.0.0-beta.6 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs index eafbd3bb32..c561dc9943 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ClientStreamWriterProxy.cs @@ -52,7 +52,7 @@ public ClientStreamWriterProxy(IClientStreamWriter writer, Action? onWrite } /// - public WriteOptions WriteOptions + public WriteOptions? WriteOptions { get => this.writer.WriteOptions; set => this.writer.WriteOptions = value; diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index c0bd481471..42f6a991f9 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs index 2fdbf22b13..633ec1d906 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerStreamWriterProxy.cs @@ -38,7 +38,7 @@ public ServerStreamWriterProxy(IServerStreamWriter writer, Action? onWrite } /// - public WriteOptions WriteOptions + public WriteOptions? WriteOptions { get => this.writer.WriteOptions; set => this.writer.WriteOptions = value; From 269a3b8ea637352ad423284db59c93a33cb6f45f Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Mon, 22 Jul 2024 08:31:46 +0200 Subject: [PATCH 1186/1499] [Resources.OperatingSystem] Fix issue with detecting MacOS (#1965) --- .github/workflows/Component.BuildTest.yml | 7 ++++++ .github/workflows/ci.yml | 1 + .../CHANGELOG.md | 3 +++ .../OperatingSystemDetector.cs | 24 +++++++++++------- .../OperatingSystemDetectorTests.cs | 25 ++++++++++++++----- 5 files changed, 45 insertions(+), 15 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 9322a40d5f..71c537cfd0 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -33,6 +33,8 @@ jobs: exclude: - os: ubuntu-latest version: net462 + - os: macos-latest + version: net462 runs-on: ${{ matrix.os }} @@ -73,6 +75,11 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 6.0.x + 7.0.x + 8.0.x - name: dotnet restore ${{ steps.resolve-project.outputs.title }} run: dotnet restore ${{ steps.resolve-project.outputs.project }} -p:EnablePackageValidation=true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2377e6c994..fc3954d2b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -496,6 +496,7 @@ jobs: with: project-name: Component[OpenTelemetry.Resources.OperatingSystem] code-cov-name: Resources.OperatingSystem + os-list: '[ "windows-latest", "ubuntu-latest", "macos-latest" ]' build-test-resources-process: needs: detect-changes diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index c009449b27..d75cd2bff5 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix detection of macOS which was wrongly identified as Linux. + ([#1965](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1965)) + ## 0.1.0-alpha.1 Released 2024-Jul-11 diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs index b0a6101bad..4bcce208ba 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if !NETFRAMEWORK +using System.Runtime.InteropServices; +#endif using static OpenTelemetry.Resources.OperatingSystem.OperatingSystemSemanticConventions; namespace OpenTelemetry.Resources.OperatingSystem; @@ -31,22 +34,25 @@ public Resource Detect() private static string? GetOSType() { - var platform = Environment.OSVersion.Platform; - if (platform == PlatformID.Win32NT) +#if NETFRAMEWORK + return OperatingSystemsValues.Windows; +#else + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return OperatingSystemsValues.Windows; } - - if (platform == PlatformID.MacOSX) + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return OperatingSystemsValues.Linux; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return OperatingSystemsValues.Darwin; } - - if (platform == PlatformID.Unix) + else { - return OperatingSystemsValues.Linux; + return null; } - - return null; +#endif } } diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs index 68cb378e34..dbcf1bb113 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Runtime.InteropServices; using Xunit; namespace OpenTelemetry.Resources.OperatingSystem.Test; @@ -14,17 +15,29 @@ public void TestOperatingSystemAttributes() var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); - var operatingSystems = new[] + string expectedPlatform; + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + expectedPlatform = OperatingSystemSemanticConventions.OperatingSystemsValues.Windows; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + expectedPlatform = OperatingSystemSemanticConventions.OperatingSystemsValues.Linux; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + expectedPlatform = OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin; + } + else { - OperatingSystemSemanticConventions.OperatingSystemsValues.Windows, - OperatingSystemSemanticConventions.OperatingSystemsValues.Linux, - OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin, - }; + throw new PlatformNotSupportedException("Unknown platform"); + } Assert.Single(resourceAttributes); Assert.True(resourceAttributes.ContainsKey(OperatingSystemSemanticConventions.AttributeOperatingSystemType)); - Assert.Contains(resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemType], operatingSystems); + Assert.Equal(resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemType], expectedPlatform); } } From fe74ee1a2481bb1bdb57b85745b413755117cbb1 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:44:49 +0200 Subject: [PATCH 1187/1499] [release] Prepare release Resources.OperatingSystem-0.1.0-alpha.2 (#1968) --- src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index d75cd2bff5..24e7e0ba47 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.2 + +Released 2024-Jul-22 + * Fix detection of macOS which was wrongly identified as Linux. ([#1965](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1965)) From 6f3ae2dd61a3fa8e520b1eb626d6de2873bab9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81ach?= Date: Mon, 22 Jul 2024 09:19:07 +0200 Subject: [PATCH 1188/1499] [Resources.OperatingSystem] readme typo fix (#1969) --- src/OpenTelemetry.Resources.OperatingSystem/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md index 6673daf190..d65014af41 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/README.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md @@ -1,8 +1,8 @@ # Operating System Detectors -[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.OperatingSyatem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSyatem) -[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.OperatingSyatem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSyatem) -[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.OperatingSyatem)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.OperatingSyatem) +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.OperatingSystem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSystem) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.OperatingSystem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSystem) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.OperatingSystem)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.OperatingSystem) > [!IMPORTANT] > Resources detected by this packages are defined by [experimental semantic convention](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/resource/os.md). From ce6f582a18ff2550e9fcc646b380aafd35a4a135 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 23 Jul 2024 21:54:27 +0200 Subject: [PATCH 1189/1499] [release] Prepare release Instrumentation.StackExchangeRedis-1.9.0-beta.1 (#1972) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 80fbb88f08..60254ac153 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Jul-23 + * Add support for instrumenting `IConnectionMultiplexer` which is added with service key. ([#1885](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1885)) From 73328b140633e3721bd6dbc3d9062b41dca07400 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 Jul 2024 10:23:38 -0700 Subject: [PATCH 1190/1499] [Instrumentation.Owin] Add IConfiguration support (#1973) --- .../CHANGELOG.md | 4 +++ .../OwinInstrumentationEventSource.cs | 25 +++++++--------- .../OpenTelemetry.Instrumentation.Owin.csproj | 3 ++ .../OwinInstrumentationOptions.cs | 23 ++++++++------- .../TracerProviderBuilderExtensions.cs | 21 +++++++++++--- .../DiagnosticsMiddlewareTests.cs | 29 ++++++++++++++++--- 6 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 9681f46fc4..b9f8971ff3 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -5,6 +5,10 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Updated registration extension code to retrieve environment variables through + `IConfiguration`. + ([#1973](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1973)) + ## 1.0.0-rc.6 Released 2024-Apr-19 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs index b3fd0a062e..774cd1fa10 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationEventSource.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; +using Microsoft.Extensions.Configuration; using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.Owin; @@ -10,7 +11,7 @@ namespace OpenTelemetry.Instrumentation.Owin; /// EventSource events emitted from the project. /// [EventSource(Name = "OpenTelemetry-Instrumentation-Owin")] -internal sealed class OwinInstrumentationEventSource : EventSource +internal sealed class OwinInstrumentationEventSource : EventSource, IConfigurationExtensionsLogger { public static OwinInstrumentationEventSource Log { get; } = new OwinInstrumentationEventSource(); @@ -44,25 +45,21 @@ public void EnrichmentException(Exception exception) } } - [NonEvent] - public void FailedToReadEnvironmentVariable(string envVarName, Exception ex) - { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.FailedToReadEnvironmentVariable(envVarName, ex.ToInvariantString()); - } - } - [Event(EventIds.EnrichmentException, Message = "Enrichment threw exception. Exception {0}.", Level = EventLevel.Error)] public void EnrichmentException(string exception) { this.WriteEvent(EventIds.EnrichmentException, exception); } - [Event(EventIds.FailedToReadEnvironmentVariable, Message = "Failed to read environment variable='{0}': {1}", Level = EventLevel.Error)] - public void FailedToReadEnvironmentVariable(string envVarName, string exception) + [Event(EventIds.InvalidConfigurationValue, Message = "Configuration key '{0}' has an invalid value: '{1}'", Level = EventLevel.Warning)] + public void InvalidConfigurationValue(string key, string value) + { + this.WriteEvent(EventIds.InvalidConfigurationValue, key, value); + } + + void IConfigurationExtensionsLogger.LogInvalidConfigurationValue(string key, string value) { - this.WriteEvent(4, envVarName, exception); + this.InvalidConfigurationValue(key, value); } private class EventIds @@ -70,6 +67,6 @@ private class EventIds public const int RequestIsFilteredOut = 1; public const int RequestFilterException = 2; public const int EnrichmentException = 3; - public const int FailedToReadEnvironmentVariable = 4; + public const int InvalidConfigurationValue = 4; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index b2aae6f9b7..de9b7691d5 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -14,8 +14,11 @@ + + + diff --git a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs index d48269a8d7..9535e932de 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/OwinInstrumentationOptions.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; +using Microsoft.Extensions.Configuration; using Microsoft.Owin; namespace OpenTelemetry.Instrumentation.Owin; @@ -17,18 +18,20 @@ public class OwinInstrumentationOptions /// Initializes a new instance of the class. /// public OwinInstrumentationOptions() + : this(new ConfigurationBuilder().AddEnvironmentVariables().Build()) { - try - { - var disableQueryRedaction = Environment.GetEnvironmentVariable(DisableQueryRedactionEnvVar); - if (disableQueryRedaction != null && disableQueryRedaction.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - this.DisableUrlQueryRedaction = true; - } - } - catch (Exception ex) + } + + internal OwinInstrumentationOptions(IConfiguration configuration) + { + Debug.Assert(configuration != null, "configuration was null"); + + if (configuration!.TryGetBoolValue( + OwinInstrumentationEventSource.Log, + DisableQueryRedactionEnvVar, + out var disableUrlQueryRedaction)) { - OwinInstrumentationEventSource.Log.FailedToReadEnvironmentVariable(DisableQueryRedactionEnvVar, ex); + this.DisableUrlQueryRedaction = disableUrlQueryRedaction; } } diff --git a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs index 62dc361cce..26a18725c7 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/TracerProviderBuilderExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.Owin; using OpenTelemetry.Internal; @@ -31,11 +33,22 @@ public static TracerProviderBuilder AddOwinInstrumentation( { Guard.ThrowIfNull(builder); - var owinOptions = new OwinInstrumentationOptions(); - configure?.Invoke(owinOptions); + return builder.ConfigureServices(services => + { + if (configure != null) + { + services.Configure(configure); + } - OwinInstrumentationActivitySource.Options = owinOptions; + services.RegisterOptionsFactory( + configuration => new OwinInstrumentationOptions(configuration)); - return builder.AddSource(OwinInstrumentationActivitySource.ActivitySourceName); + services.ConfigureOpenTelemetryTracerProvider((sp, builder) => + { + OwinInstrumentationActivitySource.Options = sp.GetRequiredService>().Get(name: null); + + builder.AddSource(OwinInstrumentationActivitySource.ActivitySourceName); + }); + }); } } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index ded5c55532..2222fecfc7 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Net.Http; using System.Web.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Owin; using Microsoft.Owin.Hosting; using OpenTelemetry.Instrumentation.Owin.Implementation; @@ -277,13 +279,18 @@ Owin has finished to inspect the activity status. */ } [Theory] - [InlineData("path?a=b&c=d", "path?a=Redacted&c=Redacted", false)] - [InlineData("path?a=b&c=d", "path?a=b&c=d", true)] - public async Task QueryParametersAreRedacted(string actualPath, string expectedPath, bool disableQueryRedaction) + [InlineData("path?a=b&c=d", "path?a=Redacted&c=Redacted", false, false)] + [InlineData("path?a=b&c=d", "path?a=b&c=d", true, false)] + [InlineData("path?a=b&c=d", "path?a=b&c=d", false, true)] + public async Task QueryParametersAreRedacted( + string actualPath, + string expectedPath, + bool disableQueryRedactionUsingEnvVar, + bool disableQueryRedactionUsingConfiguration) { try { - if (disableQueryRedaction) + if (disableQueryRedactionUsingEnvVar) { Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", "true"); } @@ -291,6 +298,20 @@ public async Task QueryParametersAreRedacted(string actualPath, string expectedP List stoppedActivities = new List(); var builder = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + if (disableQueryRedactionUsingConfiguration) + { + var config = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary() + { + ["OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION"] = "true", + }) + .Build(); + + services.AddSingleton(config); + } + }) .AddInMemoryExporter(stoppedActivities) .AddOwinInstrumentation() .Build(); From fc103472df2b2f1ed022ce83df23ec185e2c957c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 Jul 2024 11:23:54 -0700 Subject: [PATCH 1191/1499] [Instrumentation.AspNet] Add IConfiguration support (#1976) --- .../AspNetTraceInstrumentationOptions.cs | 23 ++- .../CHANGELOG.md | 4 + .../AspNetInstrumentationEventSource.cs | 23 +-- .../MeterProviderBuilderExtensions.cs | 20 +- ...penTelemetry.Instrumentation.AspNet.csproj | 9 + .../TracerProviderBuilderExtensions.cs | 23 ++- .../HttpInListenerTests.cs | 189 ++++++++++-------- 7 files changed, 177 insertions(+), 114 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs index bd57cf92d7..a6ea978941 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/AspNetTraceInstrumentationOptions.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Web; +using Microsoft.Extensions.Configuration; using OpenTelemetry.Instrumentation.AspNet.Implementation; namespace OpenTelemetry.Instrumentation.AspNet; @@ -18,18 +19,20 @@ public class AspNetTraceInstrumentationOptions /// Initializes a new instance of the class. /// public AspNetTraceInstrumentationOptions() + : this(new ConfigurationBuilder().AddEnvironmentVariables().Build()) { - try - { - var disableQueryRedaction = Environment.GetEnvironmentVariable(DisableQueryRedactionEnvVar); - if (disableQueryRedaction != null && disableQueryRedaction.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - this.DisableUrlQueryRedaction = true; - } - } - catch (Exception ex) + } + + internal AspNetTraceInstrumentationOptions(IConfiguration configuration) + { + Debug.Assert(configuration != null, "configuration was null"); + + if (configuration!.TryGetBoolValue( + AspNetInstrumentationEventSource.Log, + DisableQueryRedactionEnvVar, + out var disableUrlQueryRedaction)) { - AspNetInstrumentationEventSource.Log.FailedToReadEnvironmentVariable(DisableQueryRedactionEnvVar, ex); + this.DisableUrlQueryRedaction = disableUrlQueryRedaction; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index a711002c29..19a6894f61 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Updated registration extension code to retrieve environment variables through + `IConfiguration`. + ([#1976](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1976)) + ## 1.9.0-beta.1 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs index c07db1c67f..4fa822ad31 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/AspNetInstrumentationEventSource.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics.Tracing; +using Microsoft.Extensions.Configuration; using OpenTelemetry.Internal; namespace OpenTelemetry.Instrumentation.AspNet.Implementation; @@ -10,7 +11,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation; /// EventSource events emitted from the project. /// [EventSource(Name = "OpenTelemetry-Instrumentation-AspNet")] -internal sealed class AspNetInstrumentationEventSource : EventSource +internal sealed class AspNetInstrumentationEventSource : EventSource, IConfigurationExtensionsLogger { public static AspNetInstrumentationEventSource Log = new(); @@ -32,15 +33,6 @@ public void EnrichmentException(string eventName, Exception ex) } } - [NonEvent] - public void FailedToReadEnvironmentVariable(string envVarName, Exception ex) - { - if (this.IsEnabled(EventLevel.Error, EventKeywords.All)) - { - this.EnrichmentException(envVarName, ex.ToInvariantString()); - } - } - [Event(1, Message = "Request is filtered out and will not be collected. Operation='{0}'", Level = EventLevel.Verbose)] public void RequestIsFilteredOut(string operationName) { @@ -59,9 +51,14 @@ public void EnrichmentException(string eventName, string exception) this.WriteEvent(3, eventName, exception); } - [Event(4, Message = "Failed to read environment variable='{0}': {1}", Level = EventLevel.Error)] - public void FailedToReadEnvironmentVariable(string envVarName, string exception) + [Event(4, Message = "Configuration key '{0}' has an invalid value: '{1}'", Level = EventLevel.Warning)] + public void InvalidConfigurationValue(string key, string value) + { + this.WriteEvent(4, key, value); + } + + void IConfigurationExtensionsLogger.LogInvalidConfigurationValue(string key, string value) { - this.WriteEvent(4, envVarName, exception); + this.InvalidConfigurationValue(key, value); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs index 1dc43c40ba..4f7f21b3dc 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/MeterProviderBuilderExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.AspNet; using OpenTelemetry.Internal; @@ -31,10 +33,20 @@ public static MeterProviderBuilder AddAspNetInstrumentation( { Guard.ThrowIfNull(builder); - var options = new AspNetMetricsInstrumentationOptions(); - configure?.Invoke(options); + return builder.ConfigureServices(services => + { + if (configure != null) + { + services.Configure(configure); + } - builder.AddMeter(AspNetMetrics.InstrumentationName); - return builder.AddInstrumentation(() => new AspNetMetrics(options)); + services.ConfigureOpenTelemetryMeterProvider((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name: null); + + builder.AddInstrumentation(() => new AspNetMetrics(options)); + builder.AddMeter(AspNetMetrics.InstrumentationName); + }); + }); } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index 8900c31bf7..db66f84a14 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -20,8 +20,11 @@ + + + @@ -33,4 +36,10 @@ + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs index 0c9e5f7d19..4654b155d2 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/TracerProviderBuilderExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.AspNet; using OpenTelemetry.Internal; @@ -31,12 +33,23 @@ public static TracerProviderBuilder AddAspNetInstrumentation( { Guard.ThrowIfNull(builder); - var aspnetOptions = new AspNetTraceInstrumentationOptions(); - configure?.Invoke(aspnetOptions); + return builder.ConfigureServices(services => + { + if (configure != null) + { + services.Configure(configure); + } - builder.AddInstrumentation(() => new AspNetInstrumentation(aspnetOptions)); - builder.AddSource(TelemetryHttpModule.AspNetSourceName); + services.RegisterOptionsFactory( + configuration => new AspNetTraceInstrumentationOptions(configuration)); - return builder; + services.ConfigureOpenTelemetryTracerProvider((sp, builder) => + { + var options = sp.GetRequiredService>().Get(name: null); + + builder.AddInstrumentation(() => new AspNetInstrumentation(options)); + builder.AddSource(TelemetryHttpModule.AspNetSourceName); + }); + }); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index a3dea82898..6525a10d9f 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -5,6 +5,8 @@ using System.Reflection; using System.Web; using System.Web.Routing; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.AspNet.Implementation; using OpenTelemetry.Tests; @@ -15,30 +17,39 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests; public class HttpInListenerTests { + public enum QueryRedactionDisableBehavior + { +#pragma warning disable SA1602 // Enumeration items should be documented + DisableViaEnvVar, + DiableViaIConfiguration, +#pragma warning restore SA1602 // Enumeration items should be documented + } + [Theory] - [InlineData("http://localhost/", "http", "/", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] - [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", true, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] - [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=Redacted&baz=Redacted", false, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] - [InlineData("https://localhost/", "https", "/", null, true, "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null, "HTTP")] - [InlineData("https://user:pass@localhost/", "https", "/", null, true, "localhost", 443, "GeT", "GET", "GeT", 0, null, "GET")] // Test URL sanitization - [InlineData("http://localhost:443/", "http", "/", null, true, "localhost", 443, "GET", "GET", null, 0, null, "GET")] // Test http over 443 - [InlineData("https://localhost:80/", "https", "/", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test https over 80 - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL - [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=Redacted&q2=Redacted", false, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL - [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", true, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization - [InlineData("http://localhost:80/Index", "http", "/Index", null, true, "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}", "GET {controller}/{action}/{id}")] - [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, true, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] - [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, true, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] - [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, true, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")] - [InlineData("http://localhost/api/value", "http", "/api/value", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered - [InlineData("http://localhost/api/value", "http", "/api/value", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception - [InlineData("http://localhost/", "http", "/", null, true, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option + [InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", QueryRedactionDisableBehavior.DisableViaEnvVar, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", QueryRedactionDisableBehavior.DiableViaIConfiguration, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=Redacted&baz=Redacted", null, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("https://localhost/", "https", "/", null, null, "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null, "HTTP")] + [InlineData("https://user:pass@localhost/", "https", "/", null, null, "localhost", 443, "GeT", "GET", "GeT", 0, null, "GET")] // Test URL sanitization + [InlineData("http://localhost:443/", "http", "/", null, null, "localhost", 443, "GET", "GET", null, 0, null, "GET")] // Test http over 443 + [InlineData("https://localhost:80/", "https", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test https over 80 + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", QueryRedactionDisableBehavior.DisableViaEnvVar, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL + [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=Redacted&q2=Redacted", null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL + [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", QueryRedactionDisableBehavior.DiableViaIConfiguration, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization + [InlineData("http://localhost:80/Index", "http", "/Index", null, null, "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}", "GET {controller}/{action}/{id}")] + [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] + [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] + [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")] + [InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered + [InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception + [InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option public void AspNetRequestsAreCollectedSuccessfully( string url, string expectedUrlScheme, string expectedUrlPath, string? expectedUrlQuery, - bool disableQueryRedaction, + QueryRedactionDisableBehavior? disableQueryRedaction, string expectedHost, int expectedPort, string requestMethod, @@ -54,7 +65,7 @@ public void AspNetRequestsAreCollectedSuccessfully( { try { - if (disableQueryRedaction) + if (disableQueryRedaction == QueryRedactionDisableBehavior.DisableViaEnvVar) { Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION", "true"); } @@ -67,57 +78,71 @@ public void AspNetRequestsAreCollectedSuccessfully( Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); using (Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation((options) => - { - options.Filter = httpContext => - { - Assert.True(Activity.Current!.IsAllDataRequested); - if (string.IsNullOrEmpty(filter)) - { - return true; - } - - if (filter == "{ThrowException}") - { - throw new InvalidOperationException(); - } - - return httpContext.Request.Path != filter; - }; - - options.EnrichWithHttpRequest = (activity, request) => - { - Assert.NotNull(activity); - Assert.NotNull(request); - - Assert.True(activity.IsAllDataRequested); - }; - - options.EnrichWithHttpResponse = (activity, response) => - { - Assert.NotNull(activity); - Assert.NotNull(response); - - Assert.True(activity.IsAllDataRequested); - - if (setStatusToErrorInEnrich) - { - activity.SetStatus(ActivityStatusCode.Error); - } - }; - - options.EnrichWithException = (activity, exception) => - { - Assert.NotNull(activity); - Assert.NotNull(exception); - - Assert.True(activity.IsAllDataRequested); - }; - - options.RecordException = recordException; - }) - .AddInMemoryExporter(exportedItems) - .Build()) + .ConfigureServices(services => + { + if (disableQueryRedaction == QueryRedactionDisableBehavior.DiableViaIConfiguration) + { + var config = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary() + { + ["OTEL_DOTNET_EXPERIMENTAL_ASPNET_DISABLE_URL_QUERY_REDACTION"] = "true", + }) + .Build(); + + services.AddSingleton(config); + } + }) + .AddAspNetInstrumentation((options) => + { + options.Filter = httpContext => + { + Assert.True(Activity.Current!.IsAllDataRequested); + if (string.IsNullOrEmpty(filter)) + { + return true; + } + + if (filter == "{ThrowException}") + { + throw new InvalidOperationException(); + } + + return httpContext.Request.Path != filter; + }; + + options.EnrichWithHttpRequest = (activity, request) => + { + Assert.NotNull(activity); + Assert.NotNull(request); + + Assert.True(activity.IsAllDataRequested); + }; + + options.EnrichWithHttpResponse = (activity, response) => + { + Assert.NotNull(activity); + Assert.NotNull(response); + + Assert.True(activity.IsAllDataRequested); + + if (setStatusToErrorInEnrich) + { + activity.SetStatus(ActivityStatusCode.Error); + } + }; + + options.EnrichWithException = (activity, exception) => + { + Assert.NotNull(activity); + Assert.NotNull(exception); + + Assert.True(activity.IsAllDataRequested); + }; + + options.RecordException = recordException; + }) + .AddInMemoryExporter(exportedItems) + .Build()) { using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); @@ -226,9 +251,9 @@ public void ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision sampli var activityProcessor = new TestActivityProcessor(); Sdk.SetDefaultTextMapPropagator(propagator); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new TestSampler(samplingDecision)) - .AddAspNetInstrumentation() - .AddProcessor(activityProcessor).Build()) + .SetSampler(new TestSampler(samplingDecision)) + .AddAspNetInstrumentation() + .AddProcessor(activityProcessor).Build()) { var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); @@ -260,15 +285,15 @@ public void ExtractContextIrrespectiveOfTheFilterApplied() var activityProcessor = new TestActivityProcessor(); Sdk.SetDefaultTextMapPropagator(propagator); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddAspNetInstrumentation(options => - { - options.Filter = context => - { - isFilterCalled = true; - return false; - }; - }) - .AddProcessor(activityProcessor).Build()) + .AddAspNetInstrumentation(options => + { + options.Filter = context => + { + isFilterCalled = true; + return false; + }; + }) + .AddProcessor(activityProcessor).Build()) { var activity = ActivityHelper.StartAspNetActivity(Propagators.DefaultTextMapPropagator, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStartedCallback); ActivityHelper.StopAspNetActivity(Propagators.DefaultTextMapPropagator, activity, HttpContext.Current, TelemetryHttpModule.Options.OnRequestStoppedCallback); From abcc3d2dad8e76c00070e154442c174531c44e8a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 25 Jul 2024 11:41:18 -0700 Subject: [PATCH 1192/1499] [Instrumentation.Owin] Remove SDK dependency (#1977) --- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 5 +++++ .../OpenTelemetry.Instrumentation.Owin.csproj | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index b9f8971ff3..61ce939c32 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -9,6 +9,11 @@ `IConfiguration`. ([#1973](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1973)) +* **Breaking change** Updated to depend on the + `OpenTelemetry.Api.ProviderBuilderExtensions` (API) package instead of the + `OpenTelemetry` (SDK) package. + ([#1977](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1977)) + ## 1.0.0-rc.6 Released 2024-Apr-19 diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index de9b7691d5..a72d0b2a7c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -25,7 +25,9 @@ - + + + From 2da3c6e721b022916edf03f88c976f1803b81101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 29 Jul 2024 08:55:59 +0200 Subject: [PATCH 1193/1499] [Tests] Nullable - Instrumentation.ConfluentKafka and Exporter.Instana (#1978) --- examples/kafka/Examples.ConfluentKafka.csproj | 2 - .../InstanaExporterTests.cs | 4 +- .../InstanaSpanSerializerTests.cs | 34 ++++++++++------ .../InstanaSpanTest.cs | 40 +++++++++---------- ...penTelemetry.Exporter.Instana.Tests.csproj | 4 +- .../TestActivityProcessor.cs | 2 +- .../TestSpanSender.cs | 2 +- .../HostedTracingAndMeteringTests.cs | 3 +- .../KafkaHelpers.cs | 2 +- ...nstrumentation.ConfluentKafka.Tests.csproj | 1 - 10 files changed, 48 insertions(+), 46 deletions(-) diff --git a/examples/kafka/Examples.ConfluentKafka.csproj b/examples/kafka/Examples.ConfluentKafka.csproj index b9ce8848cb..1dd0024df3 100644 --- a/examples/kafka/Examples.ConfluentKafka.csproj +++ b/examples/kafka/Examples.ConfluentKafka.csproj @@ -2,8 +2,6 @@ Exe net8.0 - enable - enable diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index 5f705fef55..e83dc8c27b 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -12,8 +12,8 @@ public class InstanaExporterTests private readonly TestInstanaExporterHelper instanaExporterHelper = new(); private readonly TestActivityProcessor activityProcessor = new(); private readonly TestSpanSender spanSender = new(); - private InstanaSpan instanaSpan; - private InstanaExporter instanaExporter; + private InstanaSpan? instanaSpan; + private InstanaExporter? instanaExporter; [Fact] public void Export() diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 1b4bc7d42a..389acfdf74 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -14,7 +14,7 @@ public static class InstanaSpanSerializerTests public static async Task SerializeToStreamWriterAsync() { InstanaSpan instanaOtelSpan = InstanaSpanFactory.CreateSpan(); - instanaOtelSpan.F = new Implementation.From() { E = "12345", H = "localhost" }; + instanaOtelSpan.F = new Implementation.From { E = "12345", H = "localhost" }; instanaOtelSpan.N = "otel"; instanaOtelSpan.T = "hexNumberT1234"; instanaOtelSpan.S = "hexNumberS1234"; @@ -29,21 +29,21 @@ public static async Task SerializeToStreamWriterAsync() instanaOtelSpan.Data.data = new Dictionary(); instanaOtelSpan.Data.data["data1Key"] = "data1Vale"; instanaOtelSpan.Data.data["data2Key"] = "data2Vale"; - instanaOtelSpan.Data.Events = new List() + instanaOtelSpan.Data.Events = new List { - new Implementation.SpanEvent() + new() { Name = "testEvent", Ts = 111111, - Tags = new Dictionary() { { "eventTagKey", "eventTagValue" } }, + Tags = new Dictionary { { "eventTagKey", "eventTagValue" } }, }, - new Implementation.SpanEvent() + new() { Name = "testEvent2", Ts = 222222, - Tags = new Dictionary() { { "eventTag2Key", "eventTag2Value" } }, + Tags = new Dictionary { { "eventTag2Key", "eventTag2Value" } }, }, }; - InstanaSpanTest span; + InstanaSpanTest? span; using (MemoryStream sendBuffer = new MemoryStream(new byte[4096000])) { using (StreamWriter writer = new StreamWriter(sendBuffer)) @@ -54,8 +54,7 @@ public static async Task SerializeToStreamWriterAsync() sendBuffer.Position = 0; sendBuffer.SetLength(length); - JsonSerializer serializer = null; - serializer = new JsonSerializer(); + JsonSerializer serializer = new JsonSerializer(); serializer.Converters.Add(new JavaScriptDateTimeConverter()); serializer.NullValueHandling = NullValueHandling.Ignore; @@ -70,17 +69,26 @@ public static async Task SerializeToStreamWriterAsync() Assert.Equal(instanaOtelSpan.T, span.T); Assert.Equal(instanaOtelSpan.P, span.P); Assert.Equal(instanaOtelSpan.N, span.N); + Assert.NotNull(span.F); Assert.Equal(instanaOtelSpan.F.E, span.F.E); Assert.Equal(instanaOtelSpan.Ec, span.Ec); Assert.Equal(instanaOtelSpan.D / 10_000, span.D); Assert.Equal(instanaOtelSpan.Lt, span.Lt); + Assert.NotNull(span.Data); + Assert.NotNull(span.Data.Tags); Assert.Equal(instanaOtelSpan.Data.Tags["tag1Key"], span.Data.Tags["tag1Key"]); Assert.Equal(instanaOtelSpan.Data.Tags["tag2Key"], span.Data.Tags["tag2Key"]); + Assert.NotNull(span.Data.data); Assert.Equal(instanaOtelSpan.Data.data["data1Key"], span.Data.data["data1Key"]); Assert.Equal(instanaOtelSpan.Data.data["data2Key"], span.Data.data["data2Key"]); - Assert.Equal(instanaOtelSpan.Data.Events[0].Name, span.Data.Events[0].Name); - Assert.Equal(instanaOtelSpan.Data.Events[0].Tags["eventTagKey"], span.Data.Events[0].Tags["eventTagKey"]); - Assert.Equal(instanaOtelSpan.Data.Events[1].Name, span.Data.Events[1].Name); - Assert.Equal(instanaOtelSpan.Data.Events[1].Tags["eventTag2Key"], span.Data.Events[1].Tags["eventTag2Key"]); + Assert.NotNull(span.Data.Events); + var event0 = span.Data.Events[0]; + Assert.Equal(instanaOtelSpan.Data.Events[0].Name, event0.Name); + Assert.NotNull(event0.Tags); + Assert.Equal(instanaOtelSpan.Data.Events[0].Tags["eventTagKey"], event0.Tags["eventTagKey"]); + var event1 = span.Data.Events[1]; + Assert.Equal(instanaOtelSpan.Data.Events[1].Name, event1.Name); + Assert.NotNull(event1.Tags); + Assert.Equal(instanaOtelSpan.Data.Events[1].Tags["eventTag2Key"], event1.Tags["eventTag2Key"]); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index aa2a0df58d..201b0f3918 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -28,9 +28,9 @@ internal class InstanaSpanTransformInfo #pragma warning restore SA1649 // File name should match first type name #pragma warning restore SA1402 // File may only contain a single type { - public string StatusCode { get; internal set; } + public string? StatusCode { get; internal set; } - public string StatusDesc { get; internal set; } + public string? StatusDesc { get; internal set; } public bool HasExceptionEvent { get; internal set; } @@ -39,31 +39,31 @@ internal class InstanaSpanTransformInfo internal class InstanaSpanTest { - public InstanaSpanTransformInfo TransformInfo { get; set; } + public InstanaSpanTransformInfo? TransformInfo { get; set; } [JsonProperty] - public string N { get; internal set; } + public string? N { get; internal set; } [JsonProperty] - public string T { get; internal set; } + public string? T { get; internal set; } [JsonProperty] - public string Lt { get; internal set; } + public string? Lt { get; internal set; } [JsonProperty] - public From F { get; internal set; } + public From? F { get; internal set; } [JsonProperty] - public string P { get; internal set; } + public string? P { get; internal set; } [JsonProperty] - public string S { get; internal set; } + public string? S { get; internal set; } [JsonProperty] - public SpanKind K { get; internal set; } + public SpanKind? K { get; internal set; } [JsonProperty] - public Data Data { get; internal set; } + public Data? Data { get; internal set; } [JsonProperty] public long Ts { get; internal set; } @@ -83,10 +83,10 @@ internal class From #pragma warning restore SA1402 // File may only contain a single type { [JsonProperty] - public string E { get; internal set; } + public string? E { get; internal set; } [JsonProperty] - public string H { get; internal set; } + public string? H { get; internal set; } } [JsonConverter(typeof(DataConverter))] @@ -96,14 +96,14 @@ internal class Data { [JsonProperty] #pragma warning disable SA1300 // Element should begin with upper-case letter - public Dictionary data { get; internal set; } + public Dictionary? data { get; internal set; } #pragma warning restore SA1300 // Element should begin with upper-case letter [JsonProperty] - public Dictionary Tags { get; internal set; } + public Dictionary? Tags { get; internal set; } [JsonProperty] - public List Events { get; internal set; } + public List? Events { get; internal set; } } #pragma warning disable SA1402 // File may only contain a single type @@ -111,13 +111,13 @@ internal class SpanEvent #pragma warning restore SA1402 // File may only contain a single type { [JsonProperty] - public string Name { get; internal set; } + public string? Name { get; internal set; } [JsonProperty] public long Ts { get; internal set; } [JsonProperty] - public Dictionary Tags { get; internal set; } + public Dictionary? Tags { get; internal set; } } #pragma warning disable SA1402 // File may only contain a single type @@ -133,7 +133,7 @@ public override bool CanConvert(Type objectType) return objectType == typeof(Data); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { @@ -184,7 +184,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist } } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { throw new NotImplementedException(); } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index 689b764d11..3a2c826e7d 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -2,9 +2,7 @@ $(SupportedNetTargets) - $(TargetFrameworks);net462 - true - disable + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs index 40f7ab44b4..62c972e85b 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestActivityProcessor.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Exporter.Instana.Tests; internal class TestActivityProcessor : IActivityProcessor { - public IActivityProcessor NextProcessor { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public IActivityProcessor? NextProcessor { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public Task ProcessAsync(Activity activity, InstanaSpan instanaSpan) { diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs index 33cd7f898e..028ded1fa3 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestSpanSender.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Exporter.Instana.Tests; internal class TestSpanSender : ISpanSender { - public Action OnEnqueue { get; set; } + public Action? OnEnqueue { get; set; } public void Enqueue(InstanaSpan instanaSpan) { diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs index a2ed848d1c..adeb619e0d 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs @@ -55,7 +55,6 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() }); }); - IGrouping[] groups = null; using (var host = builder.Build()) { await host.StartAsync(); @@ -108,7 +107,7 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() host.Services.GetRequiredService().EnsureMetricsAreFlushed(); } - groups = metrics.GroupBy(x => x.Name).ToArray(); + IGrouping[] groups = metrics.GroupBy(x => x.Name).ToArray(); Assert.Equal(4, groups.Length); } diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs index 793753bdc2..43929b6a31 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs @@ -10,7 +10,7 @@ internal static class KafkaHelpers { public const string KafkaEndPointEnvVarName = "OTEL_KAFKAENDPOINT"; - public static readonly string KafkaEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(KafkaEndPointEnvVarName); + public static readonly string? KafkaEndPoint = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(KafkaEndPointEnvVarName); public static async Task ProduceTestMessageAsync() { diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj index defd085a4a..7419dad302 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - disable From a38b2f074fa189605e9d5c592b9efd9d19d9c53c Mon Sep 17 00:00:00 2001 From: Jesper De Temmerman Date: Wed, 31 Jul 2024 17:38:09 +0200 Subject: [PATCH 1194/1499] [Instrumentation.Http] Set http cancellation error description and type (#1955) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../CHANGELOG.md | 4 ++ .../HttpHandlerDiagnosticListener.cs | 6 ++- .../HttpClientTests.Basic.cs | 6 +++ .../HttpClientTests.cs | 42 +++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 8963cefb47..367c25a4c6 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -9,6 +9,10 @@ Released 2024-Jun-17 * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Fix an issue where cancellation of an HTTP request via the Cancellation Token + would not set a description or an `error.type` on the activity + ([#1831](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1831)) + ## 1.8.1 Released 2024-Apr-12 diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index e1139dc7d8..2fb2b20867 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -183,7 +183,11 @@ public void OnStopActivity(Activity activity, object? payload) { if (currentStatusCode == ActivityStatusCode.Unset) { - activity.SetStatus(ActivityStatusCode.Error); + // Task cancellation won't trigger the OnException so set the span error information here + // This can be either TaskCanceled or OperationCanceled but there is no way to figure out which one it is, + // so let's use the most common case as error type + activity.SetStatus(ActivityStatusCode.Error, "Task Canceled"); + activity.SetTag(SemanticConventions.AttributeErrorType, typeof(TaskCanceledException).FullName); } } else if (requestTaskStatus != TaskStatus.Faulted) diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index 38ba3b1cb9..05bc602e81 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -60,6 +60,12 @@ public HttpClientTests(ITestOutputHelper output) { ctx.Response.StatusCode = int.Parse(responseCode); } + else if (ctx.Request.Url != null && ctx.Request.Url.PathAndQuery.Contains("slow")) + { + Thread.Sleep(10000); + ctx.Response.RedirectLocation = "/"; + ctx.Response.StatusCode = 200; + } else { ctx.Response.StatusCode = 200; diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index f13b3c1004..f936f66fd1 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -172,6 +172,48 @@ public async Task ValidateNet8MetricsAsync(HttpOutTestCase tc) } #endif +#if NET8_0_OR_GREATER + [Fact] + public async Task HttpCancellationLogsError() + { + var activities = new List(); + + var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddHttpClientInstrumentation() + .AddInMemoryExporter(activities) + .Build(); + + try + { + using var c = new HttpClient(); + using var request = new HttpRequestMessage + { + RequestUri = new Uri($"{this.url}/slow"), + Method = new HttpMethod("GET"), + }; + + var cancellationTokenSource = new CancellationTokenSource(100); + await c.SendAsync(request, cancellationTokenSource.Token); + } + catch (OperationCanceledException) + { + // we expect this to be thrown here + } + finally + { + tracerProvider.Dispose(); + } + + var activity = Assert.Single(activities); + + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Equal("Task Canceled", activity.StatusDescription); + + var normalizedAttributes = activity.TagObjects.Where(kv => !kv.Key.StartsWith("otel.", StringComparison.Ordinal)).ToDictionary(x => x.Key, x => x.Value?.ToString()); + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "System.Threading.Tasks.TaskCanceledException"); + } +#endif + private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( string host, int port, From 85ee5670c48b84dbbe8dcb2cd3316cd1e3507aab Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 1 Aug 2024 12:27:10 -0700 Subject: [PATCH 1195/1499] [OneCollector] Fix events not firing for failed responses on .NET Framework (#1987) --- build/Common.nonprod.props | 4 +- .../CHANGELOG.md | 4 + .../OneCollectorExporterEventSource.cs | 9 -- .../Transports/HttpJsonPostTransport.cs | 20 +-- .../GenevaMetricExporterTests.cs | 2 +- .../HttpJsonPostTransportTests.cs | 129 ++++++++++++++++-- ...lemetry.Exporter.OneCollector.Tests.csproj | 1 + .../GrpcTests.client.cs | 4 +- .../SqlClientTests.cs | 2 +- test/Shared/InMemoryEventListener.cs | 13 +- 10 files changed, 155 insertions(+), 33 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 17782e9532..a5f30b7c4d 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -27,8 +27,8 @@ $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net7.0;net6.0 - [2.8.1,3.0) - [2.8.1,3.0) + [2.8.2,3.0) + [2.9.0,3.0) [1.5.58,2.0) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 40efc68dac..b569440d41 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fixed a bug preventing `HttpTransportErrorResponseReceived` events from firing + on .NET Framework. + ([#1987](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1987)) + ## 1.9.0 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index 389d317ac4..b68dc96478 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -27,15 +27,6 @@ public void WriteExportExceptionThrownEventIfEnabled(string itemType, Exception } } - [NonEvent] - public void WriteTransportDataSentEventIfEnabled(string itemType, int? numberOfRecords, string transportDescription) - { - if (this.IsInformationalLoggingEnabled()) - { - this.TransportDataSent(itemType, numberOfRecords ?? -1, transportDescription); - } - } - [NonEvent] public void WriteSinkDataWrittenEventIfEnabled(string itemType, int numberOfRecords, string sinkDescription) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index 40cb7f61b4..4026952ae5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -98,20 +98,22 @@ public bool Send(in TransportSendRequest sendRequest) request.Headers.TryAddWithoutValidation("sdk-version", SdkVersion); request.Headers.TryAddWithoutValidation("x-apikey", this.instrumentationKey); - bool logResponseDetails = OneCollectorExporterEventSource.Log.IsInformationalLoggingEnabled(); + bool infoLoggingEnabled = OneCollectorExporterEventSource.Log.IsInformationalLoggingEnabled(); - if (!logResponseDetails) + if (!infoLoggingEnabled) { request.Headers.TryAddWithoutValidation("NoResponseBody", "true"); } using var response = this.httpClient.Send(request, CancellationToken.None); - try + if (response.IsSuccessStatusCode) { - response.EnsureSuccessStatusCode(); - - OneCollectorExporterEventSource.Log.WriteTransportDataSentEventIfEnabled(sendRequest.ItemType, sendRequest.NumberOfItems, this.Description); + if (infoLoggingEnabled) + { + OneCollectorExporterEventSource.Log.TransportDataSent( + sendRequest.ItemType, sendRequest.NumberOfItems, this.Description); + } var root = this.payloadTransmittedSuccessCallbacks.Root; if (root != null) @@ -125,11 +127,13 @@ public bool Send(in TransportSendRequest sendRequest) return true; } - catch + else { response.Headers.TryGetValues("Collector-Error", out var collectorErrors); - var errorDetails = logResponseDetails ? response.Content.ReadAsStringAsync().GetAwaiter().GetResult() : null; + var errorDetails = infoLoggingEnabled + ? response.Content.ReadAsStringAsync().GetAwaiter().GetResult() + : null; OneCollectorExporterEventSource.Log.WriteHttpTransportErrorResponseReceivedEventIfEnabled( this.Description, diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index e39d3fe329..aaf386a50c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -746,7 +746,7 @@ public void SuccessfulSerializationWithTLVWithViews() Assert.Equal(7, exportedItems.Count); // observableLongCounter and observableDoubleGauge are dropped - Assert.Empty(exportedItems.Where(item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge")); + Assert.DoesNotContain(exportedItems, item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge"); // check serialization for longCounter CheckSerializationWithTLVForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index c2ca28a517..aabe086eff 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -33,7 +33,7 @@ public void RequestWithoutCompressionTest() }, (req, body) => { - AssertStandardHeaders(req); + AssertStandardHeaders(req, listenerEnabled: false); Assert.True(string.IsNullOrWhiteSpace(req.Headers["Content-Encoding"])); Assert.Equal(request, Encoding.ASCII.GetString(body.ToArray())); }); @@ -58,7 +58,7 @@ public void RequestUsingDeflateCompressionTest() }, (req, body) => { - AssertStandardHeaders(req); + AssertStandardHeaders(req, listenerEnabled: false); Assert.Equal("deflate", req.Headers["Content-Encoding"]); using var uncompressedStream = new MemoryStream(); @@ -110,7 +110,7 @@ public void RegisterPayloadTransmittedCallbackTest() }, (req, body) => { - AssertStandardHeaders(req); + AssertStandardHeaders(req, listenerEnabled: false); Assert.True(string.IsNullOrWhiteSpace(req.Headers["Content-Encoding"])); Assert.Equal(request, Encoding.ASCII.GetString(body.ToArray())); }, @@ -234,14 +234,95 @@ void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallbackArgum } } - private static void AssertStandardHeaders(HttpListenerRequest request) + [Fact] + public void TransportDataSentEventFiredTest() + { + var request = "{}"; + + using var httpClient = new HttpClient(); + + RunHttpServerTest( + request, + requestUri => + { + return new HttpJsonPostTransport( + "instrumentation-key", + requestUri, + OneCollectorExporterHttpTransportCompressionType.None, + new HttpClientWrapper(httpClient)); + }, + (req, body) => + { + AssertStandardHeaders(req, listenerEnabled: true); + }, + enabledListener: true); + } + + [Fact] + public void TransportExceptionThrownEventFiredTest() + { + var request = "{}"; + + using var httpClient = new HttpClient(); + + RunHttpServerTest( + request, + requestUri => + { + return new HttpJsonPostTransport( + "instrumentation-key", + requestUri, + OneCollectorExporterHttpTransportCompressionType.None, + new HttpClientWrapper(httpClient)); + }, + (req, body) => + { + AssertStandardHeaders(req, listenerEnabled: true); + }, + enabledListener: true, + transportFailure: true); + } + + [Fact] + public void HttpTransportErrorResponseReceivedEventFiredTest() + { + var request = "{}"; + + using var httpClient = new HttpClient(); + + RunHttpServerTest( + request, + requestUri => + { + return new HttpJsonPostTransport( + "instrumentation-key", + requestUri, + OneCollectorExporterHttpTransportCompressionType.None, + new HttpClientWrapper(httpClient)); + }, + (req, body) => + { + AssertStandardHeaders(req, listenerEnabled: true); + }, + enabledListener: true, + shouldTestFailFunc: i => true); + } + + private static void AssertStandardHeaders(HttpListenerRequest request, bool listenerEnabled) { Assert.Equal("POST", request.HttpMethod); Assert.True(!string.IsNullOrWhiteSpace(request.Headers["User-Agent"])); Assert.True(!string.IsNullOrWhiteSpace(request.Headers["sdk-version"])); Assert.True(!string.IsNullOrWhiteSpace(request.Headers["x-apikey"])); Assert.Equal("application/x-json-stream; charset=utf-8", request.Headers["Content-Type"]); - Assert.Equal("true", request.Headers["NoResponseBody"]); + if (listenerEnabled) + { + Assert.Null(request.Headers["NoResponseBody"]); + } + else + { + Assert.Equal("true", request.Headers["NoResponseBody"]); + } } private static void RunHttpServerTest( @@ -252,8 +333,14 @@ private static void RunHttpServerTest( int testIterations = 1, Func? shouldTestFailFunc = null, Action? testStartingAction = null, - Action? testFinishedAction = null) + Action? testFinishedAction = null, + bool enabledListener = false, + bool transportFailure = false) { + using var eventListener = enabledListener + ? new InMemoryEventListener(OneCollectorExporterEventSource.Log) + : null; + shouldTestFailFunc ??= static iteration => false; bool failTest = false; bool requestReceivedAndAsserted = false; @@ -289,7 +376,7 @@ private static void RunHttpServerTest( out var testServerPort); var transport = createTransportFunc( - new Uri($"http://{testServerHost}:{testServerPort}/")); + new Uri($"http://{testServerHost}:{(transportFailure ? 0 : testServerPort)}/")); try { @@ -317,8 +404,16 @@ private static void RunHttpServerTest( throw testException; } - Assert.NotEqual(failTest, result); - Assert.True(requestReceivedAndAsserted); + if (transportFailure) + { + Assert.False(result); + Assert.False(requestReceivedAndAsserted); + } + else + { + Assert.NotEqual(failTest, result); + Assert.True(requestReceivedAndAsserted); + } testFinishedAction?.Invoke(i, transport); } @@ -327,5 +422,21 @@ private static void RunHttpServerTest( { (transport as IDisposable)?.Dispose(); } + + if (eventListener != null) + { + if (failTest) + { + Assert.Contains(eventListener.Events, e => e.EventId == 6); + } + else if (transportFailure) + { + Assert.Contains(eventListener.Events, e => e.EventId == 5); + } + else + { + Assert.Contains(eventListener.Events, e => e.EventId == 2); + } + } } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 48212e7194..16a46f7998 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -20,6 +20,7 @@ + diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs index 1d6b01014a..abb6fc295e 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs @@ -175,8 +175,8 @@ public void GrpcAndHttpClientInstrumentationIsInvoked(bool shouldEnrich) } else { - Assert.Empty(grpcSpan.Tags.Where(tag => tag.Key == "enrichedWithHttpRequestMessage")); - Assert.Empty(grpcSpan.Tags.Where(tag => tag.Key == "enrichedWithHttpResponseMessage")); + Assert.DoesNotContain(grpcSpan.Tags, tag => tag.Key == "enrichedWithHttpRequestMessage"); + Assert.DoesNotContain(grpcSpan.Tags, tag => tag.Key == "enrichedWithHttpResponseMessage"); } } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 22dea15a54..4c2f913436 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -338,7 +338,7 @@ internal static void VerifyActivityData( } else { - Assert.Empty(activity.Tags.Where(tag => tag.Key == "enriched")); + Assert.DoesNotContain(activity.Tags, tag => tag.Key == "enriched"); } Assert.Equal(SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName, activity.GetTagValue(SemanticConventions.AttributeDbSystem)); diff --git a/test/Shared/InMemoryEventListener.cs b/test/Shared/InMemoryEventListener.cs index d0f9fcdc95..bf3d3fd567 100644 --- a/test/Shared/InMemoryEventListener.cs +++ b/test/Shared/InMemoryEventListener.cs @@ -10,13 +10,24 @@ namespace OpenTelemetry.Tests; internal class InMemoryEventListener : EventListener { - public ConcurrentQueue Events = new(); + private readonly EventSource eventSource; public InMemoryEventListener(EventSource eventSource, EventLevel minLevel = EventLevel.Verbose) { + this.eventSource = eventSource; + this.EnableEvents(eventSource, minLevel); } + public ConcurrentQueue Events { get; } = new(); + + public override void Dispose() + { + this.DisableEvents(this.eventSource); + + base.Dispose(); + } + protected override void OnEventWritten(EventWrittenEventArgs eventData) { this.Events.Enqueue(eventData); From ea449d1c7f26e12a4e951f002c4f79240d59b7b3 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:57:10 -0500 Subject: [PATCH 1196/1499] [release] Prepare release Exporter.OneCollector-1.9.1 (#1988) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index b569440d41..eef40b96d2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.1 + +Released 2024-Aug-01 + * Fixed a bug preventing `HttpTransportErrorResponseReceived` events from firing on .NET Framework. ([#1987](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1987)) From e868289a3a88497fb7ac09b351008a956fbdbf39 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:37:50 -0500 Subject: [PATCH 1197/1499] [release] Exporter.OneCollector- stable release 1.9.1 updates (#1990) --- .../OpenTelemetry.Exporter.OneCollector.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 3bc9e593d4..7d1dcf7199 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -14,7 +14,7 @@ this at the call site but there is a bug. This could possibly be cleaned up in the future (hopefully .NET 9) see https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 - 1.9.0 + 1.9.1 From 20ff07784c525029426c21dc0e673e5fac737264 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 5 Aug 2024 09:44:50 -0700 Subject: [PATCH 1198/1499] [onecollector] Use HttpClient.SendAsync on mobile platforms to avoid PlatformNotSupportedExceptions (#1992) --- .../CHANGELOG.md | 4 +++ .../Transports/HttpJsonPostTransport.cs | 5 +++- .../Internal/Transports/IHttpClient.cs | 27 ++++++++++++++++--- ...ecordCommonSchemaJsonHttpPostBenchmarks.cs | 5 +++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index eef40b96d2..cf5e40285c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Fixed `PlatformNotSupportedException`s being thrown during export when running + on mobile platforms which caused telemetry to be dropped silently. + ([#1992](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1992)) + ## 1.9.1 Released 2024-Aug-01 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index 4026952ae5..e590af68ef 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -105,7 +105,10 @@ public bool Send(in TransportSendRequest sendRequest) request.Headers.TryAddWithoutValidation("NoResponseBody", "true"); } - using var response = this.httpClient.Send(request, CancellationToken.None); + using var response = this.httpClient.Send( + request, + infoLoggingEnabled ? HttpCompletionOption.ResponseContentRead : HttpCompletionOption.ResponseHeadersRead, + CancellationToken.None); if (response.IsSuccessStatusCode) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs index f53f8474d5..a67d904af8 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/IHttpClient.cs @@ -9,24 +9,43 @@ namespace OpenTelemetry.Exporter.OneCollector; internal interface IHttpClient { - HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken); + HttpResponseMessage Send( + HttpRequestMessage request, + HttpCompletionOption completionOption, + CancellationToken cancellationToken); } internal sealed class HttpClientWrapper : IHttpClient { private readonly HttpClient httpClient; +#if NET + private readonly bool synchronousSendSupportedByCurrentPlatform; +#endif public HttpClientWrapper(HttpClient httpClient) { 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 } - public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) + public HttpResponseMessage Send( + HttpRequestMessage request, + HttpCompletionOption completionOption, + CancellationToken cancellationToken) { #if NET - return this.httpClient.Send(request, CancellationToken.None); + return this.synchronousSendSupportedByCurrentPlatform + ? this.httpClient.Send(request, completionOption, cancellationToken) + : this.httpClient.SendAsync(request, completionOption, cancellationToken).GetAwaiter().GetResult(); #else - return this.httpClient.SendAsync(request, CancellationToken.None).GetAwaiter().GetResult(); + return this.httpClient.SendAsync(request, completionOption, cancellationToken).GetAwaiter().GetResult(); #endif } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index 91ec2c8306..c6ad6b041a 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -153,7 +153,10 @@ private static LogRecord CreateLogRecord(int index) private sealed class NoopHttpClient : IHttpClient { - public HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) + public HttpResponseMessage Send( + HttpRequestMessage request, + HttpCompletionOption completionOption, + CancellationToken cancellationToken) { return new HttpResponseMessage { From b0ca29349eb2f32fb691ef10d0cf2e110e74cfe8 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Mon, 5 Aug 2024 10:51:38 -0700 Subject: [PATCH 1199/1499] [Exporter.Geneva] Edit 1.9.0 changelog to clarify exemplars support (#1993) Co-authored-by: Cijo Thomas Co-authored-by: Cijo Thomas --- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index d0ce064c8a..631613a201 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -6,6 +6,12 @@ Released 2024-Jun-21 +* Exemplars are now supported as a stable feature. Please note that + OpenTelemetry SDK has Exemplars disabled by default. Check [OpenTelemetry + Metrics + docs](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#exemplars) + to learn how to enable them. + ## 1.9.0-rc.2 Released 2024-Jun-17 From 88645a913eab3906c7e618961e1b16fbd3aedfce Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Tue, 6 Aug 2024 17:36:34 +0200 Subject: [PATCH 1200/1499] [repo] Update Docker Compose to v2 (#1995) Co-authored-by: Vishwesh Bankwar --- .github/workflows/integration.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index d139ad213b..3a11ddde2e 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -18,8 +18,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Run redis docker-compose - run: docker-compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build + - name: Run redis docker compose + run: docker compose --file=test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build kafka-integration-test: if: inputs.job == 'all' || inputs.job == 'kafka-integration-test' @@ -31,5 +31,5 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Run kafka docker-compose - run: docker-compose --file=test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build + - name: Run kafka docker compose + run: docker compose --file=test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/docker-compose.yml --file=build/docker-compose.${{ matrix.version }}.yml --project-directory=. up --exit-code-from=tests --build From 1c268456c2e8356525ee1af5fa79c3a8aeb0c040 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Mon, 12 Aug 2024 12:44:37 -0400 Subject: [PATCH 1201/1499] [Instrumentation.AWS] Add AWS metrics instrumentation (#1980) Co-authored-by: Vishwesh Bankwar Co-authored-by: Cijo Thomas --- .../.publicApi/PublicAPI.Unshipped.txt | 2 + .../CHANGELOG.md | 2 + .../Implementation/Metrics/AWSHistogram.cs | 31 +++ .../Implementation/Metrics/AWSMeter.cs | 60 ++++ .../Metrics/AWSMeterProvider.cs | 23 ++ .../Metrics/AWSMonotonicCounter.cs | 31 +++ .../Metrics/AWSUpDownCounter.cs | 31 +++ .../MeterProviderBuilderExtensions.cs | 31 +++ .../OpenTelemetry.Instrumentation.AWS.csproj | 6 +- ...Telemetry.Instrumentation.AWS.Tests.csproj | 3 +- .../TestAWSClientInstrumentation.cs | 20 +- .../TestAWSClientMetricsInstrumentation.cs | 259 ++++++++++++++++++ 12 files changed, 487 insertions(+), 12 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/MeterProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt index 1362c26ff9..d8633d91a7 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt @@ -6,3 +6,5 @@ OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownst OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +OpenTelemetry.Metrics.MeterProviderBuilderExtensions +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddAWSInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index a8de77fcd7..17ed8543c1 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Add AWS metrics instrumentation. + ([#1980](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1980)) * Added `rpc.system`, `rpc.service`, and `rpc.method` to activity tags based on [semantic convention v1.26.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/cloud-providers/aws-sdk.md#common-attributes). ([#1865](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1865)) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs new file mode 100644 index 0000000000..24884c0aae --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.Runtime.Telemetry; +using Amazon.Runtime.Telemetry.Metrics; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; + +internal class AWSHistogram : Histogram + where T : struct +{ + private readonly System.Diagnostics.Metrics.Histogram histogram; + + public AWSHistogram(System.Diagnostics.Metrics.Histogram histogram) + { + this.histogram = histogram; + } + + public override void Record(T value, Attributes? attributes = null) + { + if (attributes != null) + { + // TODO: remove ToArray call and use when AttributesAsSpan expected to be added at AWS SDK v4. + this.histogram.Record(value, attributes.AllAttributes.ToArray()); + } + else + { + this.histogram.Record(value); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs new file mode 100644 index 0000000000..ab152f2e77 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.Runtime.Telemetry.Metrics; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; + +internal class AWSMeter : Meter +{ + private readonly System.Diagnostics.Metrics.Meter meter; + + /// + /// Initializes a new instance of the class. + /// + /// The Meter used for creating and tracking the Instruments. + public AWSMeter(System.Diagnostics.Metrics.Meter meter) + { + this.meter = meter ?? throw new ArgumentNullException(nameof(meter)); + } + + public override UpDownCounter CreateUpDownCounter( + string name, + string? units = null, + string? description = null) + where T : struct + { + var upDownCounter = this.meter.CreateUpDownCounter(name, units, description); + return new AWSUpDownCounter(upDownCounter); + } + + public override MonotonicCounter CreateMonotonicCounter( + string name, + string? units = null, + string? description = null) + where T : struct + { + var counter = this.meter.CreateCounter(name, units, description); + return new AWSMonotonicCounter(counter); + } + + public override Histogram CreateHistogram( + string name, + string? units = null, + string? description = null) + where T : struct + { + var histogram = this.meter.CreateHistogram(name, units, description); + return new AWSHistogram(histogram); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.meter?.Dispose(); + } + + base.Dispose(disposing); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs new file mode 100644 index 0000000000..47a7ed2a86 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.Runtime.Telemetry; +using Amazon.Runtime.Telemetry.Metrics; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; + +internal class AWSMeterProvider : MeterProvider +{ + public override Meter GetMeter(string scope, Attributes? attributes = null) + { + // Passing attributes to the Meter is currently not possible due to version limitations + // in the dependencies. Since none of the SDK operations utilize attributes at this level, + // so we will omit the attributes for now. + // This will be revisited after the release of OpenTelemetry.Extensions.AWS which will + // update OpenTelemetry core component version(s) to `1.9.0` and allow passing tags to + // the meter constructor. + + var meter = new System.Diagnostics.Metrics.Meter(scope); + return new AWSMeter(meter); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs new file mode 100644 index 0000000000..9a1154db50 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.Runtime.Telemetry; +using Amazon.Runtime.Telemetry.Metrics; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; + +internal class AWSMonotonicCounter : MonotonicCounter + where T : struct +{ + private readonly System.Diagnostics.Metrics.Counter counter; + + public AWSMonotonicCounter(System.Diagnostics.Metrics.Counter counter) + { + this.counter = counter; + } + + public override void Add(T value, Attributes? attributes = null) + { + if (attributes != null) + { + // TODO: remove ToArray call and use when AttributesAsSpan expected to be added at AWS SDK v4. + this.counter.Add(value, attributes.AllAttributes.ToArray()); + } + else + { + this.counter.Add(value); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs new file mode 100644 index 0000000000..657d7c4f1e --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.Runtime.Telemetry; +using Amazon.Runtime.Telemetry.Metrics; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; + +internal class AWSUpDownCounter : UpDownCounter + where T : struct +{ + private readonly System.Diagnostics.Metrics.UpDownCounter upDownCounter; + + public AWSUpDownCounter(System.Diagnostics.Metrics.UpDownCounter upDownCounter) + { + this.upDownCounter = upDownCounter; + } + + public override void Add(T value, Attributes? attributes = null) + { + if (attributes != null) + { + // TODO: remove ToArray call and use when AttributesAsSpan expected to be added at AWS SDK v4. + this.upDownCounter.Add(value, attributes.AllAttributes.ToArray()); + } + else + { + this.upDownCounter.Add(value); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWS/MeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..fe468db79b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/MeterProviderBuilderExtensions.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon; +using Amazon.Runtime.Telemetry; +using OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class MeterProviderBuilderExtensions +{ + /// + /// Enables AWS instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddAWSInstrumentation( + this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + + AWSConfigs.TelemetryProvider.RegisterMeterProvider(new AWSMeterProvider()); + builder.AddMeter($"{TelemetryConstants.TelemetryScopePrefix}.*"); + + return builder; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index 5fc1c3b55a..b69158084f 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -15,9 +15,9 @@ - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 56b20ac4a8..975f08f5cd 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -8,7 +8,8 @@ - + + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 3ac9c4e664..84bab6bf3f 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -47,9 +47,10 @@ public async Task TestDDBScanSuccessful() #else await ddb.ScanAsync(scan_request); #endif - Assert.Single(exportedItems); + Assert.NotEmpty(exportedItems); - Activity awssdk_activity = exportedItems[0]; + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); @@ -90,9 +91,10 @@ public async Task TestDDBSubtypeScanSuccessful() #else await ddb.ScanAsync(scan_request); #endif - Assert.Single(exportedItems); + Assert.NotEmpty(exportedItems); - Activity awssdk_activity = exportedItems[0]; + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); @@ -142,9 +144,10 @@ public async Task TestDDBScanUnsuccessful() } catch (AmazonServiceException) { - Assert.Single(exportedItems); + Assert.NotEmpty(exportedItems); - Activity awssdk_activity = exportedItems[0]; + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); @@ -187,8 +190,9 @@ public async Task TestSQSSendMessageSuccessful() #else await sqs.SendMessageAsync(send_msg_req); #endif - Assert.Single(exportedItems); - Activity awssdk_activity = exportedItems[0]; + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "SQS.SendMessage"); + Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateSqsActivityTags(awssdk_activity); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs new file mode 100644 index 0000000000..6872c46d0f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs @@ -0,0 +1,259 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon; +using Amazon.Runtime; +using Amazon.Runtime.Telemetry; +using Amazon.S3; +using Amazon.S3.Model; +using Amazon.SimpleNotificationService; +using Amazon.SimpleNotificationService.Model; +using Amazon.SQS; +using Amazon.SQS.Model; +using OpenTelemetry.Instrumentation.AWS.Tests.Tools; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Instrumentation.AWS.Tests; + +public class TestAWSClientMetricsInstrumentation +{ + [Fact] +#if NETFRAMEWORK + public void TestS3PutObjectSuccessful() +#else + public async Task TestS3PutObjectSuccessful() +#endif + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var s3 = new AmazonS3Client(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + CustomResponses.SetResponse(s3, null, "test_request_id", true); + var putObjectRequest = new PutObjectRequest + { + BucketName = "TestBucket", + Key = "TestKey", + ContentBody = "Test Content", + }; +#if NETFRAMEWORK + s3.PutObject(putObjectRequest); +#else + await s3.PutObjectAsync(putObjectRequest); +#endif + meterProvider.ForceFlush(); + + this.ValidateCommonMetrics(exportedItems); + this.ValidateHTTPBytesMetric(exportedItems, "client.http.bytes_sent"); + } + + [Fact] +#if NETFRAMEWORK + public void TestSNSCreateTopicUnsuccessful() +#else + public async Task TestSNSCreateTopicUnsuccessful() +#endif + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var sns = new AmazonSimpleNotificationServiceClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + AmazonServiceException amazonServiceException = new AmazonServiceException(); + amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; + amazonServiceException.RequestId = "requestId"; + CustomResponses.SetResponse(sns, (request) => { throw amazonServiceException; }); + var createTopicRequest = new CreateTopicRequest + { + Name = "NewTopic", + }; + + try + { +#if NETFRAMEWORK + sns.CreateTopic(createTopicRequest); +#else + await sns.CreateTopicAsync(createTopicRequest); +#endif + } + catch (AmazonServiceException) + { + meterProvider.ForceFlush(); + + this.ValidateCommonMetrics(exportedItems, false); + + var callErrorsMetric = exportedItems.FirstOrDefault(i => i.Name == "client.call.errors"); + Assert.NotNull(callErrorsMetric); + + var metricPoints = new List(); + foreach (var p in callErrorsMetric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + var metricPoint = metricPoints[0]; + var sum = metricPoint.GetSumLong(); + + Assert.Equal(MetricType.LongSum, callErrorsMetric.MetricType); + Assert.Equal("{error}", callErrorsMetric.Unit); + Assert.True(sum > 0); + } + } + + [Fact] +#if NETFRAMEWORK + public void TestSQSCreateQueueSuccessful() +#else + public async Task TestSQSCreateQueueSuccessful() +#endif + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(sqs, dummyResponse, "requestId", true); + var send_msg_req = new CreateQueueRequest() + { + QueueName = "MyTestQueue", + }; + +#if NETFRAMEWORK + sqs.CreateQueue(send_msg_req); +#else + await sqs.CreateQueueAsync(send_msg_req); +#endif + meterProvider.ForceFlush(); + + this.ValidateCommonMetrics(exportedItems); + this.ValidateHTTPBytesMetric(exportedItems, "client.http.bytes_sent"); + this.ValidateHTTPBytesMetric(exportedItems, "client.http.bytes_received"); + } + + [Fact] + public void TestAWSUpDownCounterIsCalledProperly() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var countAmount = 7; + var counterName = "TestCounter"; + var meter = AWSConfigs.TelemetryProvider.MeterProvider.GetMeter($"{TelemetryConstants.TelemetryScopePrefix}.TestMeter"); + var counter = meter.CreateUpDownCounter(counterName); + + counter.Add(countAmount); + counter.Add(countAmount); + + meterProvider.ForceFlush(); + + var counterMetric = exportedItems.FirstOrDefault(i => i.Name == counterName); + + Assert.NotNull(counterMetric); + Assert.Equal(MetricType.LongSumNonMonotonic, counterMetric.MetricType); + + var metricPoints = new List(); + foreach (var p in counterMetric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + Assert.Single(metricPoints); + var metricPoint = metricPoints[0]; + + Assert.Equal(countAmount * 2, metricPoint.GetSumLong()); + } + + [Fact] + public void TestAWSUpDownCounterIsntCalledAfterMeterDispose() + { + var exportedItems = new List(); + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build(); + + var countAmount = 7; + var counterName = "TestCounter"; + var meter = AWSConfigs.TelemetryProvider.MeterProvider.GetMeter($"{TelemetryConstants.TelemetryScopePrefix}.TestDisposedMeter"); + var counter = meter.CreateUpDownCounter(counterName); + + meter.Dispose(); + counter.Add(countAmount); + + meterProvider.ForceFlush(); + + var counterMetric = exportedItems.FirstOrDefault(i => i.Name == counterName); + Assert.Null(counterMetric); + } + + private void ValidateHTTPBytesMetric(List exportedMetrics, string metricName) + { + var httpBytesSent = exportedMetrics.FirstOrDefault(i => i.Name == metricName); + Assert.NotNull(httpBytesSent); + + var metricPoints = new List(); + foreach (var p in httpBytesSent.GetMetricPoints()) + { + metricPoints.Add(p); + } + + var metricPoint = metricPoints[0]; + var sum = metricPoint.GetSumLong(); + + Assert.Equal(MetricType.LongSum, httpBytesSent.MetricType); + Assert.Equal("By", httpBytesSent.Unit); + Assert.True(sum > 0); + } + + private void ValidateCommonMetrics(List exportedMetrics, bool successful = true) + { + var callDuration = exportedMetrics.FirstOrDefault(i => i.Name == "client.call.duration"); + this.ValidateDurationMetric(callDuration); + + var callSerializationDuration = exportedMetrics.FirstOrDefault(i => i.Name == "client.call.serialization_duration"); + this.ValidateDurationMetric(callSerializationDuration); + + var callResolveEndpointDuration = exportedMetrics.FirstOrDefault(i => i.Name == "client.call.resolve_endpoint_duration"); + this.ValidateDurationMetric(callResolveEndpointDuration); + + var callAttemptDuration = exportedMetrics.FirstOrDefault(i => i.Name == "client.call.attempt_duration"); + this.ValidateDurationMetric(callAttemptDuration); + + // Unsuccessful calls wont reach the deserialization stage. + if (successful) + { + var callDeserializationDuration = exportedMetrics.FirstOrDefault(i => i.Name == "client.call.deserialization_duration"); + this.ValidateDurationMetric(callDeserializationDuration); + } + } + + private void ValidateDurationMetric(Metrics.Metric? durationMetric) + { + Assert.NotNull(durationMetric); + + var metricPoints = new List(); + foreach (var p in durationMetric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + var metricPoint = metricPoints[0]; + var count = metricPoint.GetHistogramCount(); + + Assert.Equal(MetricType.Histogram, durationMetric.MetricType); + Assert.Equal("s", durationMetric.Unit); + Assert.True(count > 0); + } +} From a1013720d0a8888f6adfb4294b4e986e850ac91d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 12 Aug 2024 10:08:48 -0700 Subject: [PATCH 1202/1499] [onecollector] Serialization fixes (#1999) --- .../CHANGELOG.md | 5 + .../OneCollectorExporterEventSource.cs | 9 +- .../Serialization/BatchSerializationResult.cs | 10 +- .../Serialization/BatchSerializationState.cs | 39 +++++ .../CommonSchemaJsonSerializer.cs | 34 ++++- .../Internal/Serialization/ISerializer.cs | 4 +- .../Sinks/WriteDirectlyToTransportSink.cs | 134 ++++++++---------- ...ogRecordCommonSchemaJsonSerializerTests.cs | 4 +- .../WriteDirectlyToTransportSinkTests.cs | 81 +++++++++-- 9 files changed, 212 insertions(+), 108 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationState.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index cf5e40285c..7416e8b718 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -6,6 +6,11 @@ on mobile platforms which caused telemetry to be dropped silently. ([#1992](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1992)) +* Fixed a bug which caused remaining records in a batch to be dropped silently + once the max payload size for a transmission (default 4 KiB) has been + reached. + ([#1999](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1999)) + ## 1.9.1 Released 2024-Aug-01 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs index b68dc96478..f27d4094b2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/OneCollectorExporterEventSource.cs @@ -87,10 +87,13 @@ public void SinkDataWritten(string itemType, int numberOfRecords, string sinkDes this.WriteEvent(3, itemType, numberOfRecords, sinkDescription); } - [Event(4, Message = "Dropped {1} '{0}' item(s).", Level = EventLevel.Warning)] - public void DataDropped(string itemType, int numberOfRecords) + [Event(4, Message = "Dropped {1} '{0}' item(s). {2} item(s) dropped during serialization. {3} item(s) dropped due to transmission failure.", Level = EventLevel.Warning)] +#if NET + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Parameters passed to WriteEvent are all primitive values.")] +#endif + public void DataDropped(string itemType, int numberOfRecords, int numberOfRecordsDroppedDuringSerialization, int numberOfRecordsDroppedDuringTransmission) { - this.WriteEvent(4, itemType, numberOfRecords); + this.WriteEvent(4, itemType, numberOfRecords, numberOfRecordsDroppedDuringSerialization, numberOfRecordsDroppedDuringTransmission); } [Event(5, Message = "Exception thrown by '{0}' transport: {1}", Level = EventLevel.Error)] diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs index 265c5d4ff5..ed12e24f54 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs @@ -1,12 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// Note: StyleCop doesn't understand the C#11 "required" modifier yet. Remove -// this in the future once StyleCop is updated. See: -// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3527 - -#pragma warning disable SA1206 // Declaration keywords should follow order - namespace OpenTelemetry.Exporter.OneCollector; internal readonly struct BatchSerializationResult @@ -14,10 +8,14 @@ internal readonly struct BatchSerializationResult #if NET7_0_OR_GREATER public required int NumberOfItemsSerialized { get; init; } + public required int NumberOfItemsDropped { get; init; } + public required long PayloadSizeInBytes { get; init; } #else public int NumberOfItemsSerialized { get; init; } + public int NumberOfItemsDropped { get; init; } + public long PayloadSizeInBytes { get; init; } #endif diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationState.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationState.cs new file mode 100644 index 0000000000..8bf5527712 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationState.cs @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Note: StyleCop doesn't understand the C#11 "required" modifier yet. Remove +// this in the future once StyleCop is updated. See: +// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3527 + +#if NETSTANDARD2_1_OR_GREATER || NET +using System.Diagnostics.CodeAnalysis; +#endif + +namespace OpenTelemetry.Exporter.OneCollector; + +internal ref struct BatchSerializationState + where T : class +{ + private Batch.Enumerator enumerator; + + public BatchSerializationState(in Batch batch) + { + this.enumerator = batch.GetEnumerator(); + } + + public bool TryGetNextItem( +#if NETSTANDARD2_1_OR_GREATER || NET + [NotNullWhen(true)] +#endif + out T? item) + { + if (this.enumerator.MoveNext()) + { + item = this.enumerator.Current; + return true; + } + + item = null; + return false; + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs index 47da925984..81dd686122 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -34,30 +34,45 @@ protected CommonSchemaJsonSerializer( protected JsonEncodedText TenantTokenWithTenancySystemSymbol { get; } - public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, Stream stream, int initialSizeOfPayloadInBytes, out BatchSerializationResult result) + public void SerializeBatchOfItemsToStream( + Resource resource, + ref BatchSerializationState state, + Stream stream, + int initialSizeOfPayloadInBytes, + out BatchSerializationResult result) { Guard.ThrowIfNull(stream); var numberOfSerializedItems = 0; + var numberOfDroppedItems = 0; long payloadSizeInBytes = initialSizeOfPayloadInBytes; - var state = ThreadStorageHelper.GetCommonSchemaJsonSerializationState(this.itemType, stream); + var jsonSerializerState = ThreadStorageHelper.GetCommonSchemaJsonSerializationState(this.itemType, stream); - var writer = state.Writer; + var writer = jsonSerializerState.Writer; - foreach (var item in batch) + while (state.TryGetNextItem(out var item)) { - this.SerializeItemToJson(resource, item, state); + this.SerializeItemToJson(resource, item!, jsonSerializerState); var currentItemSizeInBytes = writer.BytesCommitted + writer.BytesPending + 1; - payloadSizeInBytes += currentItemSizeInBytes; - writer.Flush(); writer.Reset(); stream.Write(CommonSchemaJsonSerializationHelper.NewLine, 0, 1); + if (currentItemSizeInBytes >= this.maxPayloadSizeInBytes) + { + // Note: If an individual item cannot fit inside the max size it + // is dropped. + numberOfDroppedItems++; + stream.SetLength(stream.Position - currentItemSizeInBytes); + continue; + } + + payloadSizeInBytes += currentItemSizeInBytes; + if (++numberOfSerializedItems >= this.maxNumberOfItemsPerPayload) { break; @@ -65,9 +80,13 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, if (payloadSizeInBytes >= this.maxPayloadSizeInBytes) { + // Note: If the last item written doesn't fit into the max size + // it is kept in the buffer and becomes the first item in the + // next transmission. result = new BatchSerializationResult { NumberOfItemsSerialized = numberOfSerializedItems, + NumberOfItemsDropped = numberOfDroppedItems, PayloadSizeInBytes = payloadSizeInBytes, PayloadOverflowItemSizeInBytes = currentItemSizeInBytes, }; @@ -78,6 +97,7 @@ public void SerializeBatchOfItemsToStream(Resource resource, in Batch batch, result = new BatchSerializationResult { NumberOfItemsSerialized = numberOfSerializedItems, + NumberOfItemsDropped = numberOfDroppedItems, PayloadSizeInBytes = payloadSizeInBytes, }; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs index f282c923c0..25e712cb6a 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/ISerializer.cs @@ -14,8 +14,8 @@ internal interface ISerializer void SerializeBatchOfItemsToStream( Resource resource, - in Batch batch, + ref BatchSerializationState state, Stream stream, int initialSizeOfPayloadInBytes, - out BatchSerializationResult serializationResult); + out BatchSerializationResult result); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs index 4ecf6a94ed..790c11c1c6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NETFRAMEWORK || NETSTANDARD2_0 -using System.Buffers; -#endif using System.Diagnostics; using OpenTelemetry.Internal; using OpenTelemetry.Resources; @@ -40,43 +37,74 @@ public WriteDirectlyToTransportSink( public void Dispose() { - this.TrySendRemainingData(); - (this.serializer as IDisposable)?.Dispose(); (this.Transport as IDisposable)?.Dispose(); } public int Write(Resource resource, in Batch batch) { - Span remainingData = default; - + var totalNumberOfItemsSerialized = 0; + var totalNumberOfItemsDroppedDuringSerialization = 0; + var totalNumberOfItemsDroppedDueToTransmissionFailure = 0; var buffer = this.buffer; + ArraySegment remainingDataFromPreviousTransmission = default; + var state = new BatchSerializationState(in batch); - try + while (true) { - this.serializer.SerializeBatchOfItemsToStream(resource, in batch, buffer, (int)buffer.Length, out var serializationResult); - - var numberOfItemsSerialized = serializationResult.NumberOfItemsSerialized; + int numberOfItemsToSend; - if (numberOfItemsSerialized <= 0) + if (remainingDataFromPreviousTransmission.Count > 0) { - return 0; + buffer.Position = 0; + buffer.Write( + remainingDataFromPreviousTransmission.Array!, + remainingDataFromPreviousTransmission.Offset, + remainingDataFromPreviousTransmission.Count); + buffer.SetLength(remainingDataFromPreviousTransmission.Count); + numberOfItemsToSend = 1; + remainingDataFromPreviousTransmission = default; } + else + { + buffer.SetLength(0); + numberOfItemsToSend = 0; + } + + this.serializer.SerializeBatchOfItemsToStream( + resource, + ref state, + buffer, + (int)buffer.Length, + out var result); - OneCollectorExporterEventSource.Log.WriteSinkDataWrittenEventIfEnabled(this.typeName, numberOfItemsSerialized, this.Description); + totalNumberOfItemsDroppedDuringSerialization += result.NumberOfItemsDropped; - var numberOfItemsToSend = numberOfItemsSerialized; + int numberOfItemsSerialized = result.NumberOfItemsSerialized; - if (serializationResult.PayloadOverflowItemSizeInBytes.HasValue) + if (numberOfItemsSerialized > 0) + { + OneCollectorExporterEventSource.Log.WriteSinkDataWrittenEventIfEnabled(this.typeName, numberOfItemsSerialized, this.Description); + + totalNumberOfItemsSerialized += numberOfItemsSerialized; + numberOfItemsToSend += numberOfItemsSerialized; + } + else if (numberOfItemsToSend <= 0) + { + break; + } + + if (result.PayloadOverflowItemSizeInBytes.HasValue) { var hasUnderlyingBuffer = buffer.TryGetBuffer(out var underlyingBuffer); Debug.Assert(hasUnderlyingBuffer, "Could not access underlying buffer"); - var endPositionOfValidMessages = (int)(serializationResult.PayloadSizeInBytes - serializationResult.PayloadOverflowItemSizeInBytes); + var endPositionOfValidMessages = (int)(result.PayloadSizeInBytes - result.PayloadOverflowItemSizeInBytes); - remainingData = underlyingBuffer.AsSpan().Slice( + remainingDataFromPreviousTransmission = new ArraySegment( + underlyingBuffer.Array!, endPositionOfValidMessages, - (int)serializationResult.PayloadOverflowItemSizeInBytes.Value); + (int)result.PayloadOverflowItemSizeInBytes.Value); buffer.SetLength(endPositionOfValidMessages); @@ -94,69 +122,19 @@ public int Write(Resource resource, in Batch batch) NumberOfItems = numberOfItemsToSend, })) { - OneCollectorExporterEventSource.Log.DataDropped(this.typeName, numberOfItemsToSend); + totalNumberOfItemsDroppedDueToTransmissionFailure += numberOfItemsToSend; } - - return numberOfItemsSerialized; } - finally - { - if (remainingData.Length > 0) - { - buffer.Position = 0; -#if NETFRAMEWORK || NETSTANDARD2_0 - var rentedBuffer = ArrayPool.Shared.Rent(remainingData.Length); - try - { - remainingData.CopyTo(rentedBuffer); - buffer.Write(rentedBuffer, 0, remainingData.Length); - } - finally - { - ArrayPool.Shared.Return(rentedBuffer); - } -#else - buffer.Write(remainingData); -#endif - buffer.SetLength(remainingData.Length); - } - else - { - buffer.SetLength(0); - } - } - } - private void TrySendRemainingData() - { - var buffer = this.buffer; - if (buffer != null && buffer.Length > 0) + if (totalNumberOfItemsDroppedDuringSerialization > 0 || totalNumberOfItemsDroppedDueToTransmissionFailure > 0) { - buffer.Position = 0; - - try - { - if (!this.Transport.Send( - new TransportSendRequest - { - ItemType = this.typeName, - ItemSerializationFormat = this.serializer.SerializationFormat, - ItemStream = buffer, - NumberOfItems = 1, - })) - { - OneCollectorExporterEventSource.Log.DataDropped(this.typeName, 1); - } - } - catch (Exception ex) - { - OneCollectorExporterEventSource.Log.DataDropped(this.typeName, 1); - OneCollectorExporterEventSource.Log.WriteExportExceptionThrownEventIfEnabled(this.typeName, ex); - } - finally - { - buffer.SetLength(0); - } + OneCollectorExporterEventSource.Log.DataDropped( + this.typeName, + totalNumberOfItemsDroppedDuringSerialization + totalNumberOfItemsDroppedDueToTransmissionFailure, + totalNumberOfItemsDroppedDuringSerialization, + totalNumberOfItemsDroppedDueToTransmissionFailure); } + + return totalNumberOfItemsSerialized; } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index c3f2e75645..97da992473 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -302,9 +302,11 @@ private static string GetLogRecordJson( var batch = new Batch(logRecords, numberOfLogRecords); + var state = new BatchSerializationState(in batch); + serializer.SerializeBatchOfItemsToStream( resource ?? Resource.Empty, - in batch, + ref state, stream, initialSizeOfPayloadInBytes: 0, out var result); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs index 229e7b8de3..2eddb26112 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -60,15 +60,19 @@ public void PartialDataWrittenToTransport_MaxItemsPerPayload_Test() var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); - Assert.Equal(2, numberOfRecordsWritten); + Assert.Equal(0, sink.Buffer.Length); + Assert.Equal(3, numberOfRecordsWritten); + Assert.Equal(2, transport.ExportedData.Count); var data = transport.ExportedData[0]; Assert.NotNull(data); - Assert.Equal("\"item1\"\n\"item2\"\n", Encoding.ASCII.GetString(data)); - Assert.Equal(0, sink.Buffer.Length); + data = transport.ExportedData[1]; + + Assert.NotNull(data); + Assert.Equal("\"item3\"\n", Encoding.ASCII.GetString(data)); } [Fact] @@ -78,7 +82,7 @@ public void PartialDataWrittenToTransport_MaxPayloadSize_Test() var transport = new TestTransport(); - var sink = new WriteDirectlyToTransportSink( + using var sink = new WriteDirectlyToTransportSink( new TestSerializer(maxPayloadSizeInBytes: expectedPayloadSizeInBytes + 1), transport); @@ -91,7 +95,9 @@ public void PartialDataWrittenToTransport_MaxPayloadSize_Test() var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + Assert.Equal(0, sink.Buffer.Length); Assert.Equal(3, numberOfRecordsWritten); + Assert.Equal(2, transport.ExportedData.Count); var data = transport.ExportedData[0]; @@ -99,7 +105,13 @@ public void PartialDataWrittenToTransport_MaxPayloadSize_Test() Assert.Equal(expectedPayloadSizeInBytes, data.Length); Assert.Equal("\"item1\"\n\"item2\"\n", Encoding.ASCII.GetString(data)); - Assert.NotEqual(0, sink.Buffer.Length); + data = transport.ExportedData[1]; + + Assert.NotNull(data); + Assert.NotEqual(expectedPayloadSizeInBytes, data.Length); + Assert.Equal("\"item3\"\n", Encoding.ASCII.GetString(data)); + + transport.ExportedData.Clear(); items = new string[] { @@ -109,24 +121,71 @@ public void PartialDataWrittenToTransport_MaxPayloadSize_Test() numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + Assert.Equal(0, sink.Buffer.Length); Assert.Equal(2, numberOfRecordsWritten); + Assert.Single(transport.ExportedData); - data = transport.ExportedData[1]; + data = transport.ExportedData[0]; Assert.NotNull(data); Assert.Equal(expectedPayloadSizeInBytes, data.Length); - Assert.Equal("\"item3\"\n\"item4\"\n", Encoding.ASCII.GetString(data)); + Assert.Equal("\"item4\"\n\"item5\"\n", Encoding.ASCII.GetString(data)); + } - Assert.NotEqual(0, sink.Buffer.Length); + [Fact] + public void SingleItem_MaxPayloadSize_Test() + { + var maxPayloadSizeInBytes = 100; + + var transport = new TestTransport(); - sink.Dispose(); + using var sink = new WriteDirectlyToTransportSink( + new TestSerializer(maxPayloadSizeInBytes), + transport); + + var items = new string[] + { + new('a', maxPayloadSizeInBytes - 3), // 3 characters added for "s and \n in JSON + }; + + var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); + + Assert.Equal(0, sink.Buffer.Length); + Assert.Equal(0, numberOfRecordsWritten); + Assert.Empty(transport.ExportedData); + } + + [Fact] + public void MultipleItems_MaxPayloadSize_Test() + { + var expectedPayloadSizeInBytes = "\"item1\"\n\"item2\"\n".Length; + + var maxPayloadSizeInBytes = 100; + + var transport = new TestTransport(); + + using var sink = new WriteDirectlyToTransportSink( + new TestSerializer(maxPayloadSizeInBytes), + transport); + + var items = new string[] + { + "item1", + new('a', maxPayloadSizeInBytes - 3), // 3 characters added for "s and \n in JSON + "item3", + }; + + var numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); Assert.Equal(0, sink.Buffer.Length); + Assert.Equal(2, numberOfRecordsWritten); + Assert.Single(transport.ExportedData); - data = transport.ExportedData[2]; + var data = transport.ExportedData[0]; Assert.NotNull(data); - Assert.Equal("\"item5\"\n", Encoding.ASCII.GetString(data)); + Assert.Equal(expectedPayloadSizeInBytes, data.Length); + Assert.Equal("\"item1\"\n\"item3\"\n", Encoding.ASCII.GetString(data)); } private sealed class TestSerializer : CommonSchemaJsonSerializer From 4c34ab422a581a295a0930d7e5c70a42f29879db Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:23:26 -0500 Subject: [PATCH 1203/1499] [release] Prepare release Exporter.OneCollector-1.9.2 (#2004) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 7416e8b718..ec1167039a 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.2 + +Released 2024-Aug-12 + * Fixed `PlatformNotSupportedException`s being thrown during export when running on mobile platforms which caused telemetry to be dropped silently. ([#1992](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1992)) From fe15be18ca9243d4f414ecc567ed4cab80b9d502 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 12 Aug 2024 12:55:32 -0500 Subject: [PATCH 1204/1499] [release] Exporter.OneCollector- stable release 1.9.2 updates (#2005) --- .../OpenTelemetry.Exporter.OneCollector.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 7d1dcf7199..54507931dc 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -14,7 +14,7 @@ this at the call site but there is a bug. This could possibly be cleaned up in the future (hopefully .NET 9) see https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 - 1.9.1 + 1.9.2 From cacbfbb5e02df6118953a6d450d079e15b3511cb Mon Sep 17 00:00:00 2001 From: Wraith Date: Mon, 12 Aug 2024 19:50:31 +0100 Subject: [PATCH 1205/1499] [aspnet] Add url.path to sampler tags (#1871) Co-authored-by: Mikel Blanchard Co-authored-by: Cijo Thomas --- .../ActivityHelper.cs | 22 ++++++++++++++++++- .../CHANGELOG.md | 8 +++++++ .../Implementation/HttpInListener.cs | 3 --- .../README.md | 17 +++++++++----- .../HttpInListenerTests.cs | 13 +++++++++++ 5 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index 102d3ba51a..bf3717da0c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -27,6 +27,9 @@ internal static class ActivityHelper TelemetryHttpModule.AspNetSourceName, typeof(ActivityHelper).Assembly.GetPackageVersion()); + [ThreadStatic] + private static KeyValuePair[]? cachedTagsStorage; + /// /// Try to get the started for the running . @@ -60,7 +63,24 @@ public static bool HasStarted(HttpContext context, out Activity? aspNetActivity) { PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); - Activity? activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext); + KeyValuePair[]? tags; + if (context.Request?.Unvalidated?.Path is string path) + { + tags = cachedTagsStorage ??= new KeyValuePair[1]; + + tags[0] = new KeyValuePair("url.path", path); + } + else + { + tags = null; + } + + Activity? activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext, tags); + + if (tags is not null) + { + tags[0] = default; + } if (activity != null) { diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index c324e7c06c..204d68c917 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* `TelemetryHttpModule` will now pass the `url.path` tag (set to + [Request.Unvalidated.Path](https://learn.microsoft.com/dotnet/api/system.web.unvalidatedrequestvalues.path)) + when starting `Activity` instances for incoming requests so that it is + available to samplers and may be used to influence the sampling decision made + by [custom + implementations](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/trace/extending-the-sdk#sampler). + ([#1871](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1871)) + ## 1.9.0-beta.1 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index ec4fcbc39f..f038d522b6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -64,7 +64,6 @@ private void OnStartActivity(Activity activity, HttpContext context) } var request = context.Request; - var requestValues = request.Unvalidated; // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md var originalHttpMethod = request.HttpMethod; @@ -83,8 +82,6 @@ private void OnStartActivity(Activity activity, HttpContext context) activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, protocolVersion); } - activity.SetTag(SemanticConventions.AttributeUrlPath, requestValues.Path); - // TODO url.query should be sanitized var query = url.Query; if (!string.IsNullOrEmpty(query)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 47e30f3efa..fb69da0625 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -137,6 +137,18 @@ below. ### Trace Filter +> [!NOTE] +> OpenTelemetry has the concept of a +[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling). +When using `OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule` the +`url.path` tag is supplied automatically to samplers when telemetry is started +for incoming requests. It is recommended to use a sampler which inspects +`url.path` (as opposed to the `Filter` option described below) in order to +perform filtering as it will prevent child spans from being created and bypass +data collection for anything NOT recorded by the sampler. The sampler approach +will reduce the impact on the process being instrumented for all filtered +requests. + This instrumentation by default collects all the incoming http requests. It allows filtering of requests by using the `Filter` function in `AspNetTraceInstrumentationOptions`. This defines the condition for allowable @@ -158,11 +170,6 @@ this.tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -It is important to note that this `Filter` option is specific to this -instrumentation. OpenTelemetry has a concept of a -[Sampler](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling), -and the `Filter` option does the filtering *before* the Sampler is invoked. - ### Trace Enrich This instrumentation library provides `EnrichWithHttpRequest`, diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 6525a10d9f..c76c1ec101 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -142,6 +142,11 @@ public void AspNetRequestsAreCollectedSuccessfully( options.RecordException = recordException; }) .AddInMemoryExporter(exportedItems) + .SetSampler( + new TestSampler(SamplingDecision.RecordAndSample) + { + ExpectedUrlPath = expectedUrlPath, + }) .Build()) { using var inMemoryEventListener = new InMemoryEventListener(AspNetInstrumentationEventSource.Log); @@ -307,8 +312,16 @@ private class TestSampler(SamplingDecision samplingDecision) : Sampler { private readonly SamplingDecision samplingDecision = samplingDecision; + public string? ExpectedUrlPath { get; set; } + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { + if (!string.IsNullOrEmpty(this.ExpectedUrlPath)) + { + Assert.NotNull(samplingParameters.Tags); + Assert.Contains(samplingParameters.Tags, t => t.Key == "url.path" && (t.Value as string) == this.ExpectedUrlPath); + } + return new SamplingResult(this.samplingDecision); } } From cf1bad4e2b07aeb72871e56877f7413f9a1bbc27 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 13 Aug 2024 14:37:13 -0700 Subject: [PATCH 1206/1499] Add component status and owners information for individual projects (#2006) Co-authored-by: Cijo Thomas --- README.md | 46 ++++++++++++++++++- src/OpenTelemetry.Exporter.Geneva/README.md | 5 ++ src/OpenTelemetry.Exporter.InfluxDB/README.md | 5 ++ src/OpenTelemetry.Exporter.Instana/README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ src/OpenTelemetry.Extensions.AWS/README.md | 5 ++ .../README.md | 5 ++ src/OpenTelemetry.Extensions/README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ .../README.md | 5 ++ src/OpenTelemetry.Resources.AWS/README.md | 5 ++ src/OpenTelemetry.Resources.Azure/README.md | 5 ++ .../README.md | 5 ++ src/OpenTelemetry.Resources.Gcp/README.md | 5 ++ src/OpenTelemetry.Resources.Host/README.md | 5 ++ .../README.md | 5 ++ src/OpenTelemetry.Resources.Process/README.md | 5 ++ .../README.md | 5 ++ src/OpenTelemetry.Sampler.AWS/README.md | 5 ++ 41 files changed, 244 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dd10228236..fdcfce7f38 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,56 @@ projects. For information on how to contribute, consult [the contributing guidelines](./CONTRIBUTING.md). +## Project status + +This repository is a collection of components maintained by different +authors and groups. As such, components shipped from this repository (via +[Nuget](https://www.nuget.org/)) may be at different stability/maturity levels. +The status for each individual component is mentioned in its respective +`README.md` file and will fall into one of the following categories: + +### Development + +Component is currently in development and is NOT available on +[Nuget](https://www.nuget.org/). + +### Alpha + +The component is ready to be used for limited non-critical workloads and the +authors of this component would welcome your feedback. Bugs and performance +problems should be reported, but component owners might not work on them right +away. Components can go through significant breaking changes and there are no +backward compatibility guarantees. Package versions in this status have the +`-alpha` extension (eg: opentelemetry.exporter.abc-1.0.0-alpha.1). + +### Beta + +Same as Alpha, but comparatively more stable. Package versions in this status +have the `-beta` extension (eg: opentelemetry.exporter.abc-1.0.0-beta.1). + +### Release candidate + +Component is close to stability. There may be minimal breaking changes between +releases. A component at this stage is expected to have had exposure to +non-critical production workloads already during its **Alpha/Beta** phase(s), +making it suitable for broader usage. Package versions in this status have the +`-rc` extension (eg: opentelemetry.exporter.abc-1.0.0-rc.1). + +### Stable + +The component is ready for general availability. Bugs and performance problems +should be reported and the component owner(s) SHOULD triage and/or resolve them +in a timely manner. The package versions MUST follow [SemVer +V2](https://semver.org/spec/v2.0.0.html). + ## Support This repository is maintained by [.NET Contrib maintainers](#maintainers) team and [.NET Contrib approvers](#approvers) who can help with reviews and code approval. However, as individual components are developed by numerous contributors, approvers and maintainers are not expected to directly contribute -to every component. The list of owners for each component can be found -[here](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/component_owners.yml). +to every component. The list of owners for each component can be found in +component's `Readme.md` file. ### Triagers diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 286fa63dfd..76fd3fc67b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -1,5 +1,10 @@ # Geneva Exporter for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#stable)| +| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@reyang](https://github.com/reyang), [@utpilla](https://github.com/utpilla), [@Yun-Ting](https://github.com/Yun-Ting)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.Geneva)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.Geneva) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/README.md b/src/OpenTelemetry.Exporter.InfluxDB/README.md index c817e0d4d6..a4bc2adec9 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/README.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/README.md @@ -1,5 +1,10 @@ # InfluxDB Exporter for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Alpha](..\..\Readme.md#alpha)| +| Code Owners | [@havret](https://github.com/havret)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.InfluxDB)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.InfluxDB) diff --git a/src/OpenTelemetry.Exporter.Instana/README.md b/src/OpenTelemetry.Exporter.Instana/README.md index 3960cb9cb6..2bc95b6d31 100644 --- a/src/OpenTelemetry.Exporter.Instana/README.md +++ b/src/OpenTelemetry.Exporter.Instana/README.md @@ -1,5 +1,10 @@ # Instana Exporter for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#stable)| +| Code Owners | [@zivaninstana](https://github.com/zivaninstana)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.Instana)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.Instana) diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index 11887a53a6..e2e854f6c4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -1,5 +1,10 @@ # OneCollector Exporter for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#stable)| +| Code Owners | [@codeblanch](https://github.com/codeblanch), [@reyang](https://github.com/reyang)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.OneCollector)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.OneCollector) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 483ccb6b35..59a2074091 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -1,5 +1,10 @@ # Stackdriver Exporter for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@SergeyKanzhelev](https://github.com/SergeyKanzhelev)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Exporter.Stackdriver)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Exporter.Stackdriver) diff --git a/src/OpenTelemetry.Extensions.AWS/README.md b/src/OpenTelemetry.Extensions.AWS/README.md index 1426ac3661..977c6004e4 100644 --- a/src/OpenTelemetry.Extensions.AWS/README.md +++ b/src/OpenTelemetry.Extensions.AWS/README.md @@ -1,5 +1,10 @@ # Tracing with AWS Distro for OpenTelemetry .Net SDK +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AWS)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.AWS)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AWS) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Extensions.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Extensions.AWS) diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index fac3fcae07..cf5b9dcad0 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -1,5 +1,10 @@ # OpenTelemetry .NET SDK telemetry enrichment framework +| Status | | +| ------------- |-----------| +| Stability | [Development](..\..\Readme.md#development)| +| Code Owners | [@xakep139](https://github.com/xakep139)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Extensions.Enrichment)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Extensions.Enrichment) diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index 38dde99d1f..763b1cc212 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -1,5 +1,10 @@ # OpenTelemetry .NET SDK preview features and extensions +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@codeblanch](https://github.com/codeblanch), [@mikegoldsmith](https://github.com/mikegoldsmith)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Extensions)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Extensions) diff --git a/src/OpenTelemetry.Instrumentation.AWS/README.md b/src/OpenTelemetry.Instrumentation.AWS/README.md index f781427566..ca731f9952 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/README.md +++ b/src/OpenTelemetry.Instrumentation.AWS/README.md @@ -1,5 +1,10 @@ # AWS SDK client instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AWS) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index 58537aa641..0b004e2c70 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -1,5 +1,10 @@ # AWS OTel .NET SDK for Lambda +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@rypdal](https://github.com/rypdal), [@Oberon00](https://github.com/Oberon00), [@ppittle](https://github.com/ppittle)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AWSLambda)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AWSLambda) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index f6edab1435..43daac8264 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -1,5 +1,10 @@ # ASP.NET Telemetry HttpModule for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AspNet)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AspNet) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index fb69da0625..653be178c6 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -1,5 +1,10 @@ # ASP.NET Instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AspNet)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AspNet) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index 408f449bc4..3d376b554e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -1,5 +1,10 @@ # ASP.NET Core Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#stable)| +| Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.AspNetCore)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.AspNetCore) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index 2e91962fed..474aa2c288 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -1,5 +1,10 @@ # Cassandra Instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@xsoheilalizadeh](https://github.com/xsoheilalizadeh)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Cassandra)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Cassandra) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md index 546e654eec..2f6daf01c1 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md @@ -1,5 +1,10 @@ # Confluent.Kafka client instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Development](..\..\Readme.md#development)| +| Code Owners | [@g7ed6e](https://github.com/g7ed6e)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.ConfluentKafka)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.ConfluentKafka) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 4e49077980..39c769565e 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -1,5 +1,10 @@ # Elasticsearch Client Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@ejsmith](https://github.com/ejsmith)| + ## NEST/Elasticsearch.Net [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ElasticsearchClient)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ElasticsearchClient) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index 93ee0cf41a..0ef9cab8ca 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -1,5 +1,10 @@ # EntityFrameworkCore Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners || + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.EntityFrameworkCore)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.EntityFrameworkCore) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index ac9dbd3f43..12480b82d7 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -1,5 +1,10 @@ # EventCounters Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Alpha](..\..\Readme.md#alpha)| +| Code Owners | [@hananiel](https://github.com/hananiel), [@mic-max](https://github.com/mic-max)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.EventCounters)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.EventCounters) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md index 023d3ab612..ae7297ca2b 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -1,5 +1,10 @@ # gRPC Core-based Client and Server Interceptors for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@IliaBrahinets](https://github.com/IliaBrahinets), [@pcwiese](https://github.com/pcwiese)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.GrpcCore)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.GrpcCore) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md index 2b4d9d320b..e1967b14db 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md @@ -1,5 +1,10 @@ # Grpc.Net.Client Instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.GrpcNetClient)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.GrpcNetClient) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index 74f6d8dc4c..91bef4677a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -1,5 +1,10 @@ # Hangfire Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@fred2u](https://github.com/fred2u)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Hangfire)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Hangfire) diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 38b392e1eb..2bcdf78926 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -1,5 +1,10 @@ # HttpClient and HttpWebRequest instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#stable)| +| Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Http)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Http) diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index b9d70cc9e5..1b5e5d4375 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -1,5 +1,10 @@ # OWIN Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [RC](..\..\Readme.md#rc)| +| Code Owners | [@codeblanch](https://github.com/codeblanch)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Owin)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Owin) diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index cd8af80e17..94c44cb1a3 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -1,5 +1,10 @@ # Process Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@Yun-Ting](https://github.com/Yun-Ting)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Process)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Process) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index d82010308d..43ff42f4d3 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -1,5 +1,10 @@ # QuartzNET Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@maldago](https://github.com/maldago)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Quartz)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Quartz) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 469fd3e062..2390259f57 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -1,5 +1,10 @@ # Runtime Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#beta)| +| Code Owners | [@twenzel](https://github.com/twenzel), [@xiang17](https://github.com/xiang17)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Runtime)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Runtime) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index 842662679e..c7caf63969 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -1,5 +1,10 @@ # SqlClient Instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| + [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) [![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.SqlClient)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.SqlClient) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index 947c818153..b2190fd28b 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -1,5 +1,10 @@ # StackExchange.Redis Instrumentation for OpenTelemetry +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@matt-hensley](https://github.com/matt-hensley)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.StackExchangeRedis)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.StackExchangeRedis) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 16909be2eb..f500be1ea0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -1,5 +1,10 @@ # WCF Instrumentation for OpenTelemetry .NET +| Status | | +| ------------- |-----------| +| Stability | [RC](..\..\Readme.md#rc)| +| Code Owners | [@codeblanch](https://github.com/codeblanch)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.Wcf)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.Wcf) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 082e550688..5c4515c298 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -1,5 +1,10 @@ # Persistent Storage Abstractions +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#stable)| +| Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-PersistentStorage)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-PersistentStorage) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index 42db71387b..c47af6a5cd 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -1,5 +1,10 @@ # Persistent Storage file based implementation +| Status | | +| ------------- |-----------| +| Stability | [Stable](..\..\Readme.md#stable)| +| Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-PersistentStorage)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-PersistentStorage) diff --git a/src/OpenTelemetry.Resources.AWS/README.md b/src/OpenTelemetry.Resources.AWS/README.md index 67e17fc329..e5a2333701 100644 --- a/src/OpenTelemetry.Resources.AWS/README.md +++ b/src/OpenTelemetry.Resources.AWS/README.md @@ -1,5 +1,10 @@ # AWS Resource Detectors +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.AWS)](https://www.nuget.org/packages/OpenTelemetry.Resources.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.AWS)](https://www.nuget.org/packages/OpenTelemetry.Resources.AWS) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.AWS) diff --git a/src/OpenTelemetry.Resources.Azure/README.md b/src/OpenTelemetry.Resources.Azure/README.md index bc9911f1eb..59ae5f32b4 100644 --- a/src/OpenTelemetry.Resources.Azure/README.md +++ b/src/OpenTelemetry.Resources.Azure/README.md @@ -1,5 +1,10 @@ # Resource Detectors for Azure cloud environments +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Azure)](https://www.nuget.org/packages/OpenTelemetry.Resources.Azure) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Azure)](https://www.nuget.org/packages/OpenTelemetry.Resources.Azure) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Azure)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Azure) diff --git a/src/OpenTelemetry.Resources.Container/README.md b/src/OpenTelemetry.Resources.Container/README.md index c0b32b05fc..519b4b270d 100644 --- a/src/OpenTelemetry.Resources.Container/README.md +++ b/src/OpenTelemetry.Resources.Container/README.md @@ -1,5 +1,10 @@ # Container Resource Detectors +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@iskiselev](https://github.com/iskiselev)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Container)](https://www.nuget.org/packages/OpenTelemetry.Resources.Container) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Container)](https://www.nuget.org/packages/OpenTelemetry.Resources.Container) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Container)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Container) diff --git a/src/OpenTelemetry.Resources.Gcp/README.md b/src/OpenTelemetry.Resources.Gcp/README.md index 940a0e2942..a772d0646d 100644 --- a/src/OpenTelemetry.Resources.Gcp/README.md +++ b/src/OpenTelemetry.Resources.Gcp/README.md @@ -1,5 +1,10 @@ # Resource Detectors for Google Cloud Platform environments +| Status | | +| ------------- |-----------| +| Stability | [Development](..\..\Readme.md#development)| +| Code Owners | [@matt-hensley](https://github.com/matt-hensley), [@pyohannes](https://github.com/pyohannes)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Gcp)](https://www.nuget.org/packages/OpenTelemetry.Resources.Gcp) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Gcp)](https://www.nuget.org/packages/OpenTelemetry.Resources.Gcp) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Gcp)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Gcp) diff --git a/src/OpenTelemetry.Resources.Host/README.md b/src/OpenTelemetry.Resources.Host/README.md index 9d0f5283dc..1df83bfb1e 100644 --- a/src/OpenTelemetry.Resources.Host/README.md +++ b/src/OpenTelemetry.Resources.Host/README.md @@ -1,5 +1,10 @@ # Host Resource Detectors +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Host)](https://www.nuget.org/packages/OpenTelemetry.Resources.Host) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Host)](https://www.nuget.org/packages/OpenTelemetry.Resources.Host) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Host)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Host) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md index d65014af41..452b92d75c 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/README.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md @@ -1,5 +1,10 @@ # Operating System Detectors +| Status | | +| ------------- |-----------| +| Stability | [Alpha](..\..\Readme.md#alpha)| +| Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.OperatingSystem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSystem) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.OperatingSystem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSystem) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.OperatingSystem)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.OperatingSystem) diff --git a/src/OpenTelemetry.Resources.Process/README.md b/src/OpenTelemetry.Resources.Process/README.md index 4c837abfa7..2fdfa8d8fc 100644 --- a/src/OpenTelemetry.Resources.Process/README.md +++ b/src/OpenTelemetry.Resources.Process/README.md @@ -1,5 +1,10 @@ # Process Resource Detectors +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Process)](https://www.nuget.org/packages/OpenTelemetry.Resources.Process) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Process)](https://www.nuget.org/packages/OpenTelemetry.Resources.Process) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.Process)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.Process) diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/README.md b/src/OpenTelemetry.Resources.ProcessRuntime/README.md index d74449e508..ccb1047cfb 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/README.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/README.md @@ -1,5 +1,10 @@ # Process Runtime Resource Detectors +| Status | | +| ------------- |-----------| +| Stability | [Beta](..\..\Readme.md#beta)| +| Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.Resources.ProcessRuntime) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.Resources.ProcessRuntime) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Resources.ProcessRuntime)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Resources.ProcessRuntime) diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md index 314228d3f9..1cd26870fb 100644 --- a/src/OpenTelemetry.Sampler.AWS/README.md +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -1,5 +1,10 @@ # AWS X-Ray Remote Sampler +| Status | | +| ------------- |-----------| +| Stability | [Alpha](..\..\Readme.md#alpha)| +| Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| + [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Sampler.AWS)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Sampler.AWS) From 29c99668ef181fa1424b127e52eb78121e3ac926 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Tue, 13 Aug 2024 15:34:39 -0700 Subject: [PATCH 1207/1499] Fix readme links (#2007) --- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- src/OpenTelemetry.Exporter.InfluxDB/README.md | 2 +- src/OpenTelemetry.Exporter.Instana/README.md | 2 +- src/OpenTelemetry.Exporter.OneCollector/README.md | 2 +- src/OpenTelemetry.Exporter.Stackdriver/README.md | 2 +- src/OpenTelemetry.Extensions.AWS/README.md | 2 +- src/OpenTelemetry.Extensions.Enrichment/README.md | 2 +- src/OpenTelemetry.Extensions/README.md | 2 +- src/OpenTelemetry.Instrumentation.AWS/README.md | 2 +- src/OpenTelemetry.Instrumentation.AWSLambda/README.md | 2 +- .../README.md | 2 +- src/OpenTelemetry.Instrumentation.AspNet/README.md | 2 +- src/OpenTelemetry.Instrumentation.AspNetCore/README.md | 2 +- src/OpenTelemetry.Instrumentation.Cassandra/README.md | 2 +- src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md | 2 +- src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md | 2 +- src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md | 2 +- src/OpenTelemetry.Instrumentation.EventCounters/README.md | 2 +- src/OpenTelemetry.Instrumentation.GrpcCore/README.md | 2 +- src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md | 2 +- src/OpenTelemetry.Instrumentation.Hangfire/README.md | 2 +- src/OpenTelemetry.Instrumentation.Http/README.md | 2 +- src/OpenTelemetry.Instrumentation.Owin/README.md | 2 +- src/OpenTelemetry.Instrumentation.Process/README.md | 2 +- src/OpenTelemetry.Instrumentation.Quartz/README.md | 2 +- src/OpenTelemetry.Instrumentation.Runtime/README.md | 2 +- src/OpenTelemetry.Instrumentation.SqlClient/README.md | 2 +- src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md | 2 +- src/OpenTelemetry.Instrumentation.Wcf/README.md | 2 +- src/OpenTelemetry.PersistentStorage.Abstractions/README.md | 2 +- src/OpenTelemetry.PersistentStorage.FileSystem/README.md | 2 +- src/OpenTelemetry.Resources.AWS/README.md | 2 +- src/OpenTelemetry.Resources.Azure/README.md | 2 +- src/OpenTelemetry.Resources.Container/README.md | 2 +- src/OpenTelemetry.Resources.Gcp/README.md | 2 +- src/OpenTelemetry.Resources.Host/README.md | 2 +- src/OpenTelemetry.Resources.OperatingSystem/README.md | 2 +- src/OpenTelemetry.Resources.Process/README.md | 2 +- src/OpenTelemetry.Resources.ProcessRuntime/README.md | 2 +- src/OpenTelemetry.Sampler.AWS/README.md | 2 +- 40 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 76fd3fc67b..b69c73b1b7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#stable)| +| Stability | [Stable](../../README.md#stable)| | Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@reyang](https://github.com/reyang), [@utpilla](https://github.com/utpilla), [@Yun-Ting](https://github.com/Yun-Ting)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/README.md b/src/OpenTelemetry.Exporter.InfluxDB/README.md index a4bc2adec9..3dfbbb893f 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/README.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Alpha](..\..\Readme.md#alpha)| +| Stability | [Alpha](../../README.md#alpha)| | Code Owners | [@havret](https://github.com/havret)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.InfluxDB)](https://www.nuget.org/packages/OpenTelemetry.Exporter.InfluxDB) diff --git a/src/OpenTelemetry.Exporter.Instana/README.md b/src/OpenTelemetry.Exporter.Instana/README.md index 2bc95b6d31..32f75fb844 100644 --- a/src/OpenTelemetry.Exporter.Instana/README.md +++ b/src/OpenTelemetry.Exporter.Instana/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#stable)| +| Stability | [Stable](../../README.md#stable)| | Code Owners | [@zivaninstana](https://github.com/zivaninstana)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Instana)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Instana) diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index e2e854f6c4..b6e816d41c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#stable)| +| Stability | [Stable](../../README.md#stable)| | Code Owners | [@codeblanch](https://github.com/codeblanch), [@reyang](https://github.com/reyang)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/README.md b/src/OpenTelemetry.Exporter.Stackdriver/README.md index 59a2074091..1ac5545aa6 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/README.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@SergeyKanzhelev](https://github.com/SergeyKanzhelev)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Stackdriver)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Stackdriver) diff --git a/src/OpenTelemetry.Extensions.AWS/README.md b/src/OpenTelemetry.Extensions.AWS/README.md index 977c6004e4..bfed40e316 100644 --- a/src/OpenTelemetry.Extensions.AWS/README.md +++ b/src/OpenTelemetry.Extensions.AWS/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.AWS)](https://www.nuget.org/packages/OpenTelemetry.Extensions.AWS) diff --git a/src/OpenTelemetry.Extensions.Enrichment/README.md b/src/OpenTelemetry.Extensions.Enrichment/README.md index cf5b9dcad0..4601755163 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/README.md +++ b/src/OpenTelemetry.Extensions.Enrichment/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Development](..\..\Readme.md#development)| +| Stability | [Development](../../README.md#development)| | Code Owners | [@xakep139](https://github.com/xakep139)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions.Enrichment)](https://www.nuget.org/packages/OpenTelemetry.Extensions.Enrichment) diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index 763b1cc212..fd395a0117 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@codeblanch](https://github.com/codeblanch), [@mikegoldsmith](https://github.com/mikegoldsmith)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Extensions)](https://www.nuget.org/packages/OpenTelemetry.Extensions) diff --git a/src/OpenTelemetry.Instrumentation.AWS/README.md b/src/OpenTelemetry.Instrumentation.AWS/README.md index ca731f9952..27917e6dd3 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/README.md +++ b/src/OpenTelemetry.Instrumentation.AWS/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWS)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWS) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index 0b004e2c70..69e5176d88 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@rypdal](https://github.com/rypdal), [@Oberon00](https://github.com/Oberon00), [@ppittle](https://github.com/ppittle)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AWSLambda)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AWSLambda) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md index 43daac8264..36c4b98213 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 653be178c6..403a4e78dc 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNet)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNet) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index 3d376b554e..a56cd2ff20 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#stable)| +| Stability | [Stable](../../README.md#stable)| | Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.AspNetCore) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index 474aa2c288..1cbeb92829 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@xsoheilalizadeh](https://github.com/xsoheilalizadeh)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Cassandra)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Cassandra) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md index 2f6daf01c1..b05ff16525 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Development](..\..\Readme.md#development)| +| Stability | [Development](../../README.md#development)| | Code Owners | [@g7ed6e](https://github.com/g7ed6e)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 39c769565e..690efee13a 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@ejsmith](https://github.com/ejsmith)| ## NEST/Elasticsearch.Net diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index 0ef9cab8ca..0a37df8cee 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners || [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EntityFrameworkCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EntityFrameworkCore) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/README.md b/src/OpenTelemetry.Instrumentation.EventCounters/README.md index 12480b82d7..f2b1b600b2 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/README.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Alpha](..\..\Readme.md#alpha)| +| Stability | [Alpha](../../README.md#alpha)| | Code Owners | [@hananiel](https://github.com/hananiel), [@mic-max](https://github.com/mic-max)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.EventCounters)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.EventCounters) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md index ae7297ca2b..a4b2489ddd 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@IliaBrahinets](https://github.com/IliaBrahinets), [@pcwiese](https://github.com/pcwiese)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcCore)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcCore) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md index e1967b14db..1941ded778 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.GrpcNetClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.GrpcNetClient) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/README.md b/src/OpenTelemetry.Instrumentation.Hangfire/README.md index 91bef4677a..6846339269 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/README.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@fred2u](https://github.com/fred2u)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Hangfire)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Hangfire) diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 2bcdf78926..2d77c64c51 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#stable)| +| Stability | [Beta](../../README.md#stable)| | Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Http.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Http) diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index 1b5e5d4375..b92d521fd9 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [RC](..\..\Readme.md#rc)| +| Stability | [RC](../../README.md#rc)| | Code Owners | [@codeblanch](https://github.com/codeblanch)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Owin)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Owin) diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 94c44cb1a3..4cebfd9a1e 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@Yun-Ting](https://github.com/Yun-Ting)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Process)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 43ff42f4d3..1ce4f8aac0 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@maldago](https://github.com/maldago)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Quartz)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Quartz) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 2390259f57..23e7717842 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#beta)| +| Stability | [Stable](../../README.md#beta)| | Code Owners | [@twenzel](https://github.com/twenzel), [@xiang17](https://github.com/xiang17)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Runtime)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index c7caf63969..4463ef2c26 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers)| [![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.SqlClient.svg)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.SqlClient) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index b2190fd28b..cf9efeae8f 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@matt-hensley](https://github.com/matt-hensley)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.StackExchangeRedis)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.StackExchangeRedis) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index f500be1ea0..773a07ffcd 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [RC](..\..\Readme.md#rc)| +| Stability | [RC](../../README.md#rc)| | Code Owners | [@codeblanch](https://github.com/codeblanch)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.Wcf)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Wcf/) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 5c4515c298..41db94b146 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#stable)| +| Stability | [Stable](../../README.md#stable)| | Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index c47af6a5cd..efadab3e17 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Stable](..\..\Readme.md#stable)| +| Stability | [Stable](../../README.md#stable)| | Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) diff --git a/src/OpenTelemetry.Resources.AWS/README.md b/src/OpenTelemetry.Resources.AWS/README.md index e5a2333701..ef528ea2f7 100644 --- a/src/OpenTelemetry.Resources.AWS/README.md +++ b/src/OpenTelemetry.Resources.AWS/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.AWS)](https://www.nuget.org/packages/OpenTelemetry.Resources.AWS) diff --git a/src/OpenTelemetry.Resources.Azure/README.md b/src/OpenTelemetry.Resources.Azure/README.md index 59ae5f32b4..ba0efb19ba 100644 --- a/src/OpenTelemetry.Resources.Azure/README.md +++ b/src/OpenTelemetry.Resources.Azure/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Azure)](https://www.nuget.org/packages/OpenTelemetry.Resources.Azure) diff --git a/src/OpenTelemetry.Resources.Container/README.md b/src/OpenTelemetry.Resources.Container/README.md index 519b4b270d..9cb0c6ce3c 100644 --- a/src/OpenTelemetry.Resources.Container/README.md +++ b/src/OpenTelemetry.Resources.Container/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@iskiselev](https://github.com/iskiselev)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Container)](https://www.nuget.org/packages/OpenTelemetry.Resources.Container) diff --git a/src/OpenTelemetry.Resources.Gcp/README.md b/src/OpenTelemetry.Resources.Gcp/README.md index a772d0646d..af8d8398e6 100644 --- a/src/OpenTelemetry.Resources.Gcp/README.md +++ b/src/OpenTelemetry.Resources.Gcp/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Development](..\..\Readme.md#development)| +| Stability | [Development](../../README.md#development)| | Code Owners | [@matt-hensley](https://github.com/matt-hensley), [@pyohannes](https://github.com/pyohannes)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Gcp)](https://www.nuget.org/packages/OpenTelemetry.Resources.Gcp) diff --git a/src/OpenTelemetry.Resources.Host/README.md b/src/OpenTelemetry.Resources.Host/README.md index 1df83bfb1e..632d6b2ff7 100644 --- a/src/OpenTelemetry.Resources.Host/README.md +++ b/src/OpenTelemetry.Resources.Host/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Host)](https://www.nuget.org/packages/OpenTelemetry.Resources.Host) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md index 452b92d75c..7b74713a40 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/README.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Alpha](..\..\Readme.md#alpha)| +| Stability | [Alpha](../../README.md#alpha)| | Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.OperatingSystem)](https://www.nuget.org/packages/OpenTelemetry.Resources.OperatingSystem) diff --git a/src/OpenTelemetry.Resources.Process/README.md b/src/OpenTelemetry.Resources.Process/README.md index 2fdfa8d8fc..c5fa2a0647 100644 --- a/src/OpenTelemetry.Resources.Process/README.md +++ b/src/OpenTelemetry.Resources.Process/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Process)](https://www.nuget.org/packages/OpenTelemetry.Resources.Process) diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/README.md b/src/OpenTelemetry.Resources.ProcessRuntime/README.md index ccb1047cfb..2f8beffdcd 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/README.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Beta](..\..\Readme.md#beta)| +| Stability | [Beta](../../README.md#beta)| | Code Owners | [@Kielek](https://github.com/Kielek), [@lachmatt](https://github.com/lachmatt)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.ProcessRuntime)](https://www.nuget.org/packages/OpenTelemetry.Resources.ProcessRuntime) diff --git a/src/OpenTelemetry.Sampler.AWS/README.md b/src/OpenTelemetry.Sampler.AWS/README.md index 1cd26870fb..98ac188917 100644 --- a/src/OpenTelemetry.Sampler.AWS/README.md +++ b/src/OpenTelemetry.Sampler.AWS/README.md @@ -2,7 +2,7 @@ | Status | | | ------------- |-----------| -| Stability | [Alpha](..\..\Readme.md#alpha)| +| Stability | [Alpha](../../README.md#alpha)| | Code Owners | [@srprash](https://github.com/srprash), [@ppittle](https://github.com/ppittle)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Sampler.AWS)](https://www.nuget.org/packages/OpenTelemetry.Sampler.AWS) From 7317b2a5c9edd27d018c3070d2b4526cc8ee5010 Mon Sep 17 00:00:00 2001 From: Sam Spencer <54915162+samsp-msft@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:24:06 -0700 Subject: [PATCH 1208/1499] Rate Limiting sampler for .NET (#1996) Co-authored-by: Cijo Thomas --- .../.publicApi/PublicAPI.Unshipped.txt | 3 + .../Internal/RateLimiter.cs | 48 +++++++++ src/OpenTelemetry.Extensions/README.md | 24 +++++ .../Trace/RateLimitingSampler.cs | 68 ++++++++++++ .../Trace/RateLimitingSamplerTests.cs | 102 ++++++++++++++++++ 5 files changed, 245 insertions(+) create mode 100644 src/OpenTelemetry.Extensions/Internal/RateLimiter.cs create mode 100644 src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs create mode 100644 test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs diff --git a/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt index 76f352124e..1b59a80012 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt @@ -8,8 +8,11 @@ OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.get -> Sys OpenTelemetry.Logs.LogToActivityEventConversionOptions.ScopeConverter.set -> void OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.get -> System.Action>!>! OpenTelemetry.Logs.LogToActivityEventConversionOptions.StateConverter.set -> void +OpenTelemetry.RateLimitingSampler +OpenTelemetry.RateLimitingSampler.RateLimitingSampler(int maxTracesPerSecond) -> void OpenTelemetry.Trace.BaggageActivityProcessor OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.RateLimitingSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult override OpenTelemetry.Trace.BaggageActivityProcessor.OnStart(System.Diagnostics.Activity! data) -> void static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Trace.BaggageActivityProcessor.AllowAllBaggageKeys.get -> System.Predicate! diff --git a/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs b/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs new file mode 100644 index 0000000000..fd1e51f895 --- /dev/null +++ b/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; + +namespace OpenTelemetry.Extensions.Internal; + +internal sealed class RateLimiter +{ + private readonly Stopwatch stopwatch = Stopwatch.StartNew(); + private readonly double creditsPerTick; + private readonly long maxBalance; // max balance in ticks + private long currentBalance; // last op ticks less remaining balance, using long directly with Interlocked for thread safety + + public RateLimiter(double creditsPerSecond, double maxBalance) + { + this.creditsPerTick = creditsPerSecond / Stopwatch.Frequency; + this.maxBalance = (long)(maxBalance / this.creditsPerTick); + this.currentBalance = this.stopwatch.ElapsedTicks - this.maxBalance; + } + + public bool TrySpend(double itemCost) + { + long cost = (long)(itemCost / this.creditsPerTick); + long currentTicks; + long currentBalanceTicks; + long availableBalanceAfterWithdrawal; + do + { + currentBalanceTicks = Interlocked.Read(ref this.currentBalance); + currentTicks = this.stopwatch.ElapsedTicks; + long currentAvailableBalance = currentTicks - currentBalanceTicks; + if (currentAvailableBalance > this.maxBalance) + { + currentAvailableBalance = this.maxBalance; + } + + availableBalanceAfterWithdrawal = currentAvailableBalance - cost; + if (availableBalanceAfterWithdrawal < 0) + { + return false; + } + } + + // CompareExchange will fail if currentBalance has changed since the last read, implying another thread has updated the balance + while (Interlocked.CompareExchange(ref this.currentBalance, currentTicks - availableBalanceAfterWithdrawal, currentBalanceTicks) != currentBalanceTicks); + return true; + } +} diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index fd395a0117..6ad53f5476 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -84,3 +84,27 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() Warning: The baggage key predicate is executed for every baggage entry for each started activity. Do not use slow or intensive operations. + +### RateLimitingSampler + +The rate limiting sampler is a sampler that will limit the number of samples to +the specified rate per second. It is typically used in conjunction with the ParentBasedSampler +to ensure that the rate limiting sampler is only applied to the root spans. When +using the ParentBasedSampler, when an Activity creation request comes in without +a sampling decision, it will delegate to the rate limiting sampler which will +make a decision based on the rate limit, that way all spans in the trace will use +the same sampling decision, and the rate will effectively become the number of +traces per second, irrespective of the number of spans within each trace. + +Example of RateLimitingSampler usage: + +```cs +builder.Services.AddOpenTelemetry() + .WithTracing(tracing => + { + tracing.AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + // Add the rate limiting sampler with a limit of 3 traces per second + .SetSampler(new ParentBasedSampler(new RateLimitingSampler(3))) + }); +``` diff --git a/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs b/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs new file mode 100644 index 0000000000..ecfe0726ad --- /dev/null +++ b/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Based on the jaeger remote sampler for Java from https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/jaeger-remote-sampler/src/main/java/io/opentelemetry/sdk/extension/trace/jaeger/sampler/RateLimitingSampler.java + +using System.Globalization; +using OpenTelemetry.Extensions.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry; + +/// +/// Rate limiting sampler that can be used to sample traces at a constant rate. +/// +public class RateLimitingSampler : Sampler +{ + private const string SAMPLERTYPE = "ratelimiting"; + private const string SAMPLERTYPEKEY = "sampler.type"; + private const string SAMPLERPARAMKEY = "sampler.param"; + + private readonly RateLimiter rateLimiter; + private readonly SamplingResult onSamplingResult; + private readonly SamplingResult offSamplingResult; + + /// + /// Initializes a new instance of the class. + /// + /// The maximum number of traces that will be emitted each second. + public RateLimitingSampler(int maxTracesPerSecond) + { + double maxBalance = maxTracesPerSecond < 1.0 ? 1.0 : maxTracesPerSecond; + this.rateLimiter = new RateLimiter(maxTracesPerSecond, maxBalance); + var attributes = new Dictionary() + { + { SAMPLERTYPEKEY, SAMPLERTYPE }, + { SAMPLERPARAMKEY, (double)maxTracesPerSecond }, + }; + this.onSamplingResult = new SamplingResult(SamplingDecision.RecordAndSample, attributes); + this.offSamplingResult = new SamplingResult(SamplingDecision.Drop, attributes); + this.Description = $"RateLimitingSampler{{{DecimalFormat(maxTracesPerSecond)}}}"; + } + + /// + /// Checks whether activity needs to be created and tracked. + /// + /// + /// The OpenTelemetry.Trace.SamplingParameters used by the OpenTelemetry.Trace.Sampler + /// to decide if the System.Diagnostics.Activity to be created is going to be sampled + /// or not. + /// + /// + /// Sampling decision on whether activity needs to be sampled or not. + /// + public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) + { + return this.rateLimiter.TrySpend(1.0) ? this.onSamplingResult : this.offSamplingResult; + } + + private static string DecimalFormat(double value) + { + NumberFormatInfo numberFormatInfo = new NumberFormatInfo + { + NumberDecimalSeparator = ".", + }; + + return value.ToString("0.00", numberFormatInfo); + } +} diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs new file mode 100644 index 0000000000..2acc236783 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs @@ -0,0 +1,102 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Tests.Trace; + +public class RateLimitingSamplerTests +{ + [Fact] + public void ShouldSample_ReturnsRecordAndSample_WhenWithinRateLimit() + { + // Arrange + var samplingParameters = new SamplingParameters( + parentContext: default, + traceId: default, + name: "TestOperation", + kind: default, + tags: null, + links: null); + + var sampler = new RateLimitingSampler(5); // 5 trace per second + int sampleIn = 0, sampleOut = 0; + + // Fire in 3 traces with a second, should all be sampled in + + for (var i = 0; i < 3; i++) + { + // Act + var result = sampler.ShouldSample(in samplingParameters); + switch (result.Decision) + { + case SamplingDecision.RecordAndSample: + sampleIn++; + break; + case SamplingDecision.RecordOnly: + Assert.Fail("Unexpected decision"); + break; + case SamplingDecision.Drop: + sampleOut++; + break; + } + + Thread.Sleep(333); + } + + // Assert + Assert.Equal(3, sampleIn); + Assert.Equal(0, sampleOut); + } + + [Fact] + public async Task ShouldFilter_WhenAboveRateLimit() + { + const int SAMPLE_RATE = 5; // 5 trace per second + const int CYCLES = 500; + + var samplingParameters = new SamplingParameters( + parentContext: default, + traceId: default, + name: "TestOperation", + kind: default, + tags: null, + links: null); + var sampler = new RateLimitingSampler(SAMPLE_RATE); + int sampleIn = 0, sampleOut = 0; + + var startTime = DateTime.UtcNow; + + for (var i = 0; i < CYCLES; i++) + { + var result = sampler.ShouldSample(in samplingParameters); + switch (result.Decision) + { + case SamplingDecision.RecordAndSample: + sampleIn++; + break; + case SamplingDecision.RecordOnly: + Assert.Fail("Unexpected decision"); + break; + case SamplingDecision.Drop: + sampleOut++; + break; + } + + // Task.Delay is limited by the OS Scheduler, so we can't guarantee the exact time + await Task.Delay(5); + } + + var timeTakenSeconds = (DateTime.UtcNow - startTime).TotalSeconds; + + // Approximate the number of samples we should have taken + // Account for the fact that the initial balance is the SampleRate, so they will all be sampled in + var approxSamples = Math.Floor(timeTakenSeconds * SAMPLE_RATE) + SAMPLE_RATE; + + // Assert - We should have sampled in 5 traces per second over duration + // Adding in a fudge factor + Assert.True(sampleIn > (approxSamples * 0.9) && sampleIn < (approxSamples * 1.1)); + Assert.True(sampleOut == (CYCLES - sampleIn)); + } +} From e82e28651ec63c682cd1c9344f8e1eecc1efbe94 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Fri, 16 Aug 2024 16:39:35 -0700 Subject: [PATCH 1209/1499] Add changelog for rate limiting sampler (#2009) --- src/OpenTelemetry.Extensions/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index fde331e39a..508ec3a4ce 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -8,6 +8,11 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Added rate limiting sampler which limits the number of traces to the specified +rate per second. For details see + [RateLimitingSampler](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Extensions#ratelimitingsampler). + ([#1996](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1996)) + ## 1.0.0-beta.5 Released 2024-May-08 From 131ccf35efcfd21584d7daecf2bbd2c4de196fcc Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Thu, 22 Aug 2024 10:57:09 -0400 Subject: [PATCH 1210/1499] [Instrumentation.AWS] Update the instrumentation logic to use AWS TracerProvider. (#1974) --- .../AWSClientInstrumentationOptions.cs | 4 +- .../CHANGELOG.md | 4 + .../AWSPropagatorPipelineHandler.cs | 74 +++++- .../AWSTracingPipelineCustomizer.cs | 11 +- .../AWSTracingPipelineHandler.cs | 251 ------------------ .../Implementation/Metrics/AWSHistogram.cs | 2 +- .../Implementation/Metrics/AWSMeter.cs | 2 +- .../Metrics/AWSMeterProvider.cs | 2 +- .../Metrics/AWSMonotonicCounter.cs | 2 +- .../Metrics/AWSUpDownCounter.cs | 2 +- .../Implementation/Tracing/AWSTraceSpan.cs | 91 +++++++ .../Implementation/Tracing/AWSTracer.cs | 72 +++++ .../Tracing/AWSTracerProvider.cs | 14 + .../TracerProviderBuilderExtensions.cs | 8 +- .../Implementation/TestsHelper.cs | 2 +- .../TestAWSClientInstrumentation.cs | 89 +++---- 16 files changed, 308 insertions(+), 322 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs diff --git a/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs index 3d729b7c06..f476d1915d 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Instrumentation.AWS; public class AWSClientInstrumentationOptions { /// - /// Gets or sets a value indicating whether downstream Http instrumentation is suppressed. + /// Gets or sets a value indicating whether downstream instrumentation is suppressed. /// - public bool SuppressDownstreamInstrumentation { get; set; } = true; + public bool SuppressDownstreamInstrumentation { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 17ed8543c1..812dc0f44b 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,8 +2,12 @@ ## Unreleased +* BREAKING: Update the instrumentation logic to use AWS TracerProvider. + ([#1974](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1974)) * Add AWS metrics instrumentation. ([#1980](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1980)) +* Updated dependency on AWS .NET SDK to version 3.7.400. + ([#1974](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1980)) * Added `rpc.system`, `rpc.service`, and `rpc.method` to activity tags based on [semantic convention v1.26.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/cloud-providers/aws-sdk.md#common-attributes). ([#1865](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1865)) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs index feb671ba93..38ee9a3dbc 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs @@ -1,10 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using Amazon.Runtime; using Amazon.Runtime.Internal; +using Amazon.Runtime.Telemetry; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Extensions.AWS.Trace; +using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation; @@ -25,15 +28,11 @@ internal class AWSPropagatorPipelineHandler : PipelineHandler carrier[name] = value; }; - /// - /// Rely on the the for retrieving the current - /// context. - /// - private readonly AWSTracingPipelineHandler tracingPipelineHandler; + private readonly AWSClientInstrumentationOptions options; - public AWSPropagatorPipelineHandler(AWSTracingPipelineHandler tracingPipelineHandler) + public AWSPropagatorPipelineHandler(AWSClientInstrumentationOptions options) { - this.tracingPipelineHandler = tracingPipelineHandler; + this.options = options; } public override void InvokeSync(IExecutionContext executionContext) @@ -50,15 +49,72 @@ public override async Task InvokeAsync(IExecutionContext executionContext) return await base.InvokeAsync(executionContext).ConfigureAwait(false); } +#if NET + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif + private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext) + { + var service = requestContext.ServiceMetaData.ServiceId; + + if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out var parameter)) + { + AmazonWebServiceRequest request = requestContext.OriginalRequest; + + try + { + var property = request.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(request)); + } + } + } + catch (Exception) + { + // Guard against any reflection-related exceptions when running in AoT. + // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + } + } + + if (AWSServiceType.IsDynamoDbService(service)) + { + activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); + } + else if (AWSServiceType.IsSqsService(service)) + { + SqsRequestContextHelper.AddAttributes( + requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); + } + else if (AWSServiceType.IsSnsService(service)) + { + SnsRequestContextHelper.AddAttributes( + requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); + } + } + private void ProcessBeginRequest(IExecutionContext executionContext) { - if (this.tracingPipelineHandler.Activity == null) + if (this.options.SuppressDownstreamInstrumentation) + { + SuppressInstrumentationScope.Enter(); + } + + var currentActivity = Activity.Current; + + // Propagate the current activity if it was created by the AWS SDK + if (currentActivity == null || !currentActivity.Source.Name.StartsWith(TelemetryConstants.TelemetryScopePrefix, StringComparison.Ordinal)) { return; } + AddRequestSpecificInformation(currentActivity, executionContext.RequestContext); AwsPropagator.Inject( - new PropagationContext(this.tracingPipelineHandler.Activity.Context, Baggage.Current), + new PropagationContext(currentActivity.Context, Baggage.Current), executionContext.RequestContext.Request.Headers, Setter); } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index cf16e6ae87..235a656c81 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -7,8 +7,8 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; /// -/// Wires and -/// into the AWS so they can inject trace headers and wrap sdk calls in spans. +/// Wires into the AWS +/// so it can inject trace headers and add request information to the tags. /// internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer { @@ -34,12 +34,7 @@ public void Customize(Type serviceClientType, RuntimePipeline pipeline) return; } - var tracingPipelineHandler = new AWSTracingPipelineHandler(this.options); - var propagatingPipelineHandler = new AWSPropagatorPipelineHandler(tracingPipelineHandler); - - // AWSTracingPipelineHandler must execute early in the AWS SDK pipeline - // in order to manipulate outgoing requests objects before they are marshalled (ie serialized). - pipeline.AddHandlerBefore(tracingPipelineHandler); + var propagatingPipelineHandler = new AWSPropagatorPipelineHandler(this.options); // AWSPropagatorPipelineHandler executes after the AWS SDK has marshalled (ie serialized) // the outgoing request object so that it can work with the request's Headers diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs deleted file mode 100644 index e37d8090a5..0000000000 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Diagnostics; -using Amazon.Runtime; -using Amazon.Runtime.Internal; -using Amazon.Util; -using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Internal; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Instrumentation.AWS.Implementation; - -/// -/// Wraps the outgoing AWS SDK Request in a Span and adds additional AWS specific Tags. -/// Depending on the target AWS Service, additional request specific information may be injected as well. -/// -/// This must execute early in the AWS SDK pipeline -/// in order to manipulate outgoing requests objects before they are marshalled (ie serialized). -/// -internal sealed class AWSTracingPipelineHandler : PipelineHandler -{ - internal const string ActivitySourceName = "Amazon.AWS.AWSClientInstrumentation"; - - private static readonly ActivitySource AWSSDKActivitySource = new(ActivitySourceName, typeof(AWSTracingPipelineHandler).Assembly.GetPackageVersion()); - - private readonly AWSClientInstrumentationOptions options; - - public AWSTracingPipelineHandler(AWSClientInstrumentationOptions options) - { - this.options = options; - } - - public Activity? Activity { get; private set; } - - public override void InvokeSync(IExecutionContext executionContext) - { - this.Activity = this.ProcessBeginRequest(executionContext); - try - { - base.InvokeSync(executionContext); - } - catch (Exception ex) - { - if (this.Activity != null) - { - ProcessException(this.Activity, ex); - } - - throw; - } - finally - { - if (this.Activity != null) - { - ProcessEndRequest(executionContext, this.Activity); - } - } - } - - public override async Task InvokeAsync(IExecutionContext executionContext) - { - T? ret = null; - - this.Activity = this.ProcessBeginRequest(executionContext); - try - { - ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); - } - catch (Exception ex) - { - if (this.Activity != null) - { - ProcessException(this.Activity, ex); - } - - throw; - } - finally - { - if (this.Activity != null) - { - ProcessEndRequest(executionContext, this.Activity); - } - } - - return ret; - } - - private static void ProcessEndRequest(IExecutionContext executionContext, Activity activity) - { - var responseContext = executionContext.ResponseContext; - var requestContext = executionContext.RequestContext; - - if (activity.IsAllDataRequested) - { - if (Utils.GetTagValue(activity, AWSSemanticConventions.AttributeAWSRequestId) == null) - { - activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, FetchRequestId(requestContext, responseContext)); - } - - var httpResponse = responseContext.HttpResponse; - if (httpResponse != null) - { - int statusCode = (int)httpResponse.StatusCode; - - AddStatusCodeToActivity(activity, statusCode); - activity.SetTag(AWSSemanticConventions.AttributeHttpResponseContentLength, httpResponse.ContentLength); - } - } - - activity.Stop(); - } - - private static void ProcessException(Activity activity, Exception ex) - { - if (activity.IsAllDataRequested) - { - activity.RecordException(ex); - - activity.SetStatus(Status.Error.WithDescription(ex.Message)); - - if (ex is AmazonServiceException amazonServiceException) - { - AddStatusCodeToActivity(activity, (int)amazonServiceException.StatusCode); - activity.SetTag(AWSSemanticConventions.AttributeAWSRequestId, amazonServiceException.RequestId); - } - } - } - -#if NET - [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( - "Trimming", - "IL2075", - Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] -#endif - private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext, string service) - { - if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out var parameter)) - { - AmazonWebServiceRequest request = requestContext.OriginalRequest; - - try - { - var property = request.GetType().GetProperty(parameter); - if (property != null) - { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) - { - activity.SetTag(attribute, property.GetValue(request)); - } - } - } - catch (Exception) - { - // Guard against any reflection-related exceptions when running in AoT. - // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. - } - } - - if (AWSServiceType.IsDynamoDbService(service)) - { - activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); - } - else if (AWSServiceType.IsSqsService(service)) - { - SqsRequestContextHelper.AddAttributes( - requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); - } - else if (AWSServiceType.IsSnsService(service)) - { - SnsRequestContextHelper.AddAttributes( - requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); - } - } - - private static void AddStatusCodeToActivity(Activity activity, int status_code) - { - activity.SetTag(AWSSemanticConventions.AttributeHttpStatusCode, status_code); - } - - private static string FetchRequestId(IRequestContext requestContext, IResponseContext responseContext) - { - string request_id = string.Empty; - var response = responseContext.Response; - if (response != null) - { - request_id = response.ResponseMetadata.RequestId; - } - else - { - var request_headers = requestContext.Request.Headers; - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amzn-RequestId", out var req_id)) - { - request_id = req_id; - } - - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amz-request-id", out req_id)) - { - request_id = req_id; - } - - if (string.IsNullOrEmpty(request_id) && request_headers.TryGetValue("x-amz-id-2", out req_id)) - { - request_id = req_id; - } - } - - return request_id; - } - - private Activity? ProcessBeginRequest(IExecutionContext executionContext) - { - var requestContext = executionContext.RequestContext; - var service = AWSServiceHelper.GetAWSServiceName(requestContext); - var operation = AWSServiceHelper.GetAWSOperationName(requestContext); - - Activity? activity = AWSSDKActivitySource.StartActivity(service + "." + operation, ActivityKind.Client); - - if (activity == null) - { - return null; - } - - if (this.options.SuppressDownstreamInstrumentation) - { - SuppressInstrumentationScope.Enter(); - } - - if (activity.IsAllDataRequested) - { - activity.SetTag(AWSSemanticConventions.AttributeAWSServiceName, service); - activity.SetTag(AWSSemanticConventions.AttributeAWSOperationName, operation); - - // Follow: https://github.com/open-telemetry/semantic-conventions/blob/v1.26.0/docs/cloud-providers/aws-sdk.md#common-attributes - activity.SetTag(AWSSemanticConventions.AttributeValueRPCSystem, "aws-api"); - activity.SetTag(AWSSemanticConventions.AttributeValueRPCService, service); - activity.SetTag(AWSSemanticConventions.AttributeValueRPCMethod, operation); - var client = executionContext.RequestContext.ClientConfig; - if (client != null) - { - var region = client.RegionEndpoint?.SystemName; - activity.SetTag(AWSSemanticConventions.AttributeAWSRegion, region ?? AWSSDKUtils.DetermineRegion(client.ServiceURL)); - } - - AddRequestSpecificInformation(activity, requestContext, service); - } - - return activity; - } -} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs index 24884c0aae..b4bcec7936 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; -internal class AWSHistogram : Histogram +internal sealed class AWSHistogram : Histogram where T : struct { private readonly System.Diagnostics.Metrics.Histogram histogram; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs index ab152f2e77..14f7ab1c12 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; -internal class AWSMeter : Meter +internal sealed class AWSMeter : Meter { private readonly System.Diagnostics.Metrics.Meter meter; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs index 47a7ed2a86..c86388503e 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; -internal class AWSMeterProvider : MeterProvider +internal sealed class AWSMeterProvider : MeterProvider { public override Meter GetMeter(string scope, Attributes? attributes = null) { diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs index 9a1154db50..dcbaba5d07 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; -internal class AWSMonotonicCounter : MonotonicCounter +internal sealed class AWSMonotonicCounter : MonotonicCounter where T : struct { private readonly System.Diagnostics.Metrics.Counter counter; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs index 657d7c4f1e..02901349ac 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; -internal class AWSUpDownCounter : UpDownCounter +internal sealed class AWSUpDownCounter : UpDownCounter where T : struct { private readonly System.Diagnostics.Metrics.UpDownCounter upDownCounter; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs new file mode 100644 index 0000000000..98de524b14 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs @@ -0,0 +1,91 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Amazon.Runtime.Telemetry; +using Amazon.Runtime.Telemetry.Tracing; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; + +internal sealed class AWSTraceSpan : TraceSpan +{ + private readonly Activity? activity; + + public AWSTraceSpan(Activity? activity) + { + this.activity = activity; + this.Name = activity?.DisplayName; + } + + public override void EmitEvent(string name, Attributes? attributes = null) + { + if (this.activity == null || !this.activity.IsAllDataRequested) + { + return; + } + + var tags = attributes != null ? new ActivityTagsCollection(attributes.AllAttributes) : null; + this.activity.AddEvent(new ActivityEvent(name, tags: tags)); + } + + public override void SetAttribute(string key, object value) + { + if (this.activity == null || !this.activity.IsAllDataRequested) + { + return; + } + + this.activity.SetTag(key, value); + } + + public override void SetStatus(SpanStatus status) + { + if (this.activity == null || !this.activity.IsAllDataRequested) + { + return; + } + + var activityStatus = ConvertToActivityStatusCode(status); + this.activity.SetStatus(activityStatus); + } + + public override void RecordException(Exception exception, Attributes? attributes = null) + { + if (this.activity == null || !this.activity.IsAllDataRequested) + { + return; + } + + var tags = attributes != null ? new TagList(attributes.AllAttributes.ToArray()) : default; + + this.activity.RecordException(exception, tags); + this.activity.SetStatus(Status.Error.WithDescription(exception.Message)); + } + + public override void End() + { + this.activity?.Stop(); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.End(); + this.activity?.Dispose(); + } + + base.Dispose(disposing); + } + + private static ActivityStatusCode ConvertToActivityStatusCode(SpanStatus status) + { + return status switch + { + SpanStatus.OK => ActivityStatusCode.Ok, + SpanStatus.ERROR => ActivityStatusCode.Error, + _ => ActivityStatusCode.Unset, + }; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs new file mode 100644 index 0000000000..6c8c1610a6 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs @@ -0,0 +1,72 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Amazon.Runtime.Telemetry; +using Amazon.Runtime.Telemetry.Tracing; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; + +internal sealed class AWSTracer : Tracer +{ + private readonly ActivitySource activitySource; + + /// + /// Initializes a new instance of the class. + /// + /// The name of the instrumentation scope that uniquely identifies the tracer. + public AWSTracer(string scope) + { + this.activitySource = new ActivitySource(scope); + } + + public override TraceSpan CreateSpan( + string name, + Attributes? initialAttributes = null, + SpanKind spanKind = SpanKind.INTERNAL, + SpanContext? parentContext = null) + { + var tags = initialAttributes != null ? new ActivityTagsCollection(initialAttributes.AllAttributes) : null; + var activityKind = ConvertToActivityKind(spanKind); + + ActivityContext parentActivityContext = ConvertToActivityContext(parentContext); + var activity = this.activitySource.StartActivity(name, activityKind, parentActivityContext, tags); + + return new AWSTraceSpan(activity); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.activitySource.Dispose(); + } + + base.Dispose(disposing); + } + + private static ActivityContext ConvertToActivityContext(SpanContext? parentContext) + { + if (parentContext == null) + { + return default; + } + + var traceId = ActivityTraceId.CreateFromString(parentContext.TraceId.AsSpan()); + var spanId = ActivitySpanId.CreateFromString(parentContext.SpanId.AsSpan()); + + return new ActivityContext(traceId, spanId, default, null, parentContext.IsRemote); + } + + private static ActivityKind ConvertToActivityKind(SpanKind spanKind) + { + return spanKind switch + { + SpanKind.CLIENT => ActivityKind.Client, + SpanKind.SERVER => ActivityKind.Server, + SpanKind.PRODUCER => ActivityKind.Producer, + SpanKind.CONSUMER => ActivityKind.Consumer, + _ => ActivityKind.Internal, + }; + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs new file mode 100644 index 0000000000..7e11ce0afc --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Amazon.Runtime.Telemetry.Tracing; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; + +internal sealed class AWSTracerProvider : TracerProvider +{ + public override Tracer GetTracer(string scope) + { + return new AWSTracer(scope); + } +} diff --git a/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs index c80ac2c1d0..5cf55bcd81 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/TracerProviderBuilderExtensions.cs @@ -1,8 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Amazon; +using Amazon.Runtime.Telemetry; using OpenTelemetry.Instrumentation.AWS; using OpenTelemetry.Instrumentation.AWS.Implementation; +using OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; using OpenTelemetry.Internal; namespace OpenTelemetry.Trace; @@ -36,7 +39,10 @@ public static TracerProviderBuilder AddAWSInstrumentation( configure?.Invoke(awsClientOptions); _ = new AWSClientsInstrumentation(awsClientOptions); - builder.AddSource(AWSTracingPipelineHandler.ActivitySourceName); + + AWSConfigs.TelemetryProvider.RegisterTracerProvider(new AWSTracerProvider()); + builder.AddSource($"{TelemetryConstants.TelemetryScopePrefix}.*"); + return builder; } } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index 56d2c67993..e695853e2f 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -16,7 +16,7 @@ internal static class TestsHelper /// Returns either or /// depending on . /// - /// This is meant to mimic thee logic in . + /// This is meant to mimic thee logic in . /// internal static Action>? CreateAddAttributesAction(string serviceType, IRequestContext context) { diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 84bab6bf3f..4f8c17835d 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -26,6 +26,7 @@ public async Task TestDDBScanSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -35,7 +36,6 @@ public async Task TestDDBScanSuccessful() .Build()) { var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; CustomResponses.SetResponse(ddb, null, requestId, true); var scan_request = new ScanRequest { @@ -47,17 +47,18 @@ public async Task TestDDBScanSuccessful() #else await ddb.ScanAsync(scan_request); #endif - Assert.NotEmpty(exportedItems); + } - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); - Assert.NotNull(awssdk_activity); + Assert.NotEmpty(exportedItems); - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateDynamoActivityTags(awssdk_activity); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + Assert.NotNull(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - } + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateDynamoActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } [Fact] @@ -70,6 +71,7 @@ public async Task TestDDBSubtypeScanSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -79,7 +81,6 @@ public async Task TestDDBSubtypeScanSuccessful() .Build()) { var ddb = new TestAmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; CustomResponses.SetResponse(ddb, null, requestId, true); var scan_request = new ScanRequest { @@ -91,17 +92,18 @@ public async Task TestDDBSubtypeScanSuccessful() #else await ddb.ScanAsync(scan_request); #endif - Assert.NotEmpty(exportedItems); + } - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); - Assert.NotNull(awssdk_activity); + Assert.NotEmpty(exportedItems); - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateDynamoActivityTags(awssdk_activity); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + Assert.NotNull(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - } + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateDynamoActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } [Fact] @@ -114,6 +116,7 @@ public async Task TestDDBScanUnsuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -123,7 +126,6 @@ public async Task TestDDBScanUnsuccessful() .Build()) { var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; AmazonServiceException amazonServiceException = new AmazonServiceException(); amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; amazonServiceException.RequestId = requestId; @@ -142,21 +144,23 @@ public async Task TestDDBScanUnsuccessful() await ddb.ScanAsync(scan_request); #endif } - catch (AmazonServiceException) + catch (AmazonServiceException ex) { - Assert.NotEmpty(exportedItems); + Assert.Equal(System.Net.HttpStatusCode.NotFound, ex.StatusCode); + } + } - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); - Assert.NotNull(awssdk_activity); + Assert.NotEmpty(exportedItems); - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateDynamoActivityTags(awssdk_activity); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + Assert.NotNull(awssdk_activity); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - Assert.Equal(Status.Error.WithDescription("Exception of type 'Amazon.Runtime.AmazonServiceException' was thrown."), awssdk_activity.GetStatus()); - Assert.Equal("exception", awssdk_activity.Events.First().Name); - } - } + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateDynamoActivityTags(awssdk_activity); + + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + Assert.Equal(Status.Error.WithDescription("Exception of type 'Amazon.Runtime.AmazonServiceException' was thrown."), awssdk_activity.GetStatus()); + Assert.Equal("exception", awssdk_activity.Events.First().Name); } [Fact] @@ -169,6 +173,7 @@ public async Task TestSQSSendMessageSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -178,7 +183,6 @@ public async Task TestSQSSendMessageSuccessful() .Build()) { var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; string dummyResponse = "{}"; CustomResponses.SetResponse(sqs, dummyResponse, requestId, true); var send_msg_req = new SendMessageRequest(); @@ -190,16 +194,17 @@ public async Task TestSQSSendMessageSuccessful() #else await sqs.SendMessageAsync(send_msg_req); #endif - Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "SQS.SendMessage"); - Assert.NotNull(awssdk_activity); + } - this.ValidateAWSActivity(awssdk_activity, parent); - this.ValidateSqsActivityTags(awssdk_activity); + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "SQS.SendMessage"); + Assert.NotNull(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); - Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.requestId")); - } + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateSqsActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } private void ValidateAWSActivity(Activity aws_activity, Activity parent) @@ -211,9 +216,6 @@ private void ValidateAWSActivity(Activity aws_activity, Activity parent) private void ValidateDynamoActivityTags(Activity ddb_activity) { Assert.Equal("DynamoDB.Scan", ddb_activity.DisplayName); - Assert.Equal("DynamoDB", Utils.GetTagValue(ddb_activity, "aws.service")); - Assert.Equal("Scan", Utils.GetTagValue(ddb_activity, "aws.operation")); - Assert.Equal("us-east-1", Utils.GetTagValue(ddb_activity, "aws.region")); Assert.Equal("SampleProduct", Utils.GetTagValue(ddb_activity, "aws.table_name")); Assert.Equal("dynamodb", Utils.GetTagValue(ddb_activity, "db.system")); Assert.Equal("aws-api", Utils.GetTagValue(ddb_activity, "rpc.system")); @@ -224,9 +226,6 @@ private void ValidateDynamoActivityTags(Activity ddb_activity) private void ValidateSqsActivityTags(Activity sqs_activity) { Assert.Equal("SQS.SendMessage", sqs_activity.DisplayName); - Assert.Equal("SQS", Utils.GetTagValue(sqs_activity, "aws.service")); - Assert.Equal("SendMessage", Utils.GetTagValue(sqs_activity, "aws.operation")); - Assert.Equal("us-east-1", Utils.GetTagValue(sqs_activity, "aws.region")); Assert.Equal("https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue", Utils.GetTagValue(sqs_activity, "aws.queue_url")); Assert.Equal("aws-api", Utils.GetTagValue(sqs_activity, "rpc.system")); Assert.Equal("SQS", Utils.GetTagValue(sqs_activity, "rpc.service")); From dc1cee86ba9191fbe99aa3196c1ef5e15dfff23e Mon Sep 17 00:00:00 2001 From: Artur Gordashnikov Date: Thu, 22 Aug 2024 18:22:44 +0300 Subject: [PATCH 1211/1499] Fix OpenTelemetry.Instrumentation.Http 1.9.0 release notes (#2017) --- src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 367c25a4c6..65249e41ce 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -11,7 +11,7 @@ Released 2024-Jun-17 * Fix an issue where cancellation of an HTTP request via the Cancellation Token would not set a description or an `error.type` on the activity - ([#1831](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1831)) + ([#1955](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1955)) ## 1.8.1 From b5961d5ce6f4bbcbd7afc0ceede5917bc6f62914 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Thu, 22 Aug 2024 11:26:25 -0400 Subject: [PATCH 1212/1499] Request to release OpenTelemetry.Instrumentation.AWS package (#2018) Co-authored-by: Vishwesh Bankwar --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 812dc0f44b..0ab5292147 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.5 + +Released 2024-Aug-22 + * BREAKING: Update the instrumentation logic to use AWS TracerProvider. ([#1974](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1974)) * Add AWS metrics instrumentation. From 434e3f5b8f52f4b5a9baf49bd34251e7aa769902 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:12:56 -0500 Subject: [PATCH 1213/1499] [release] Prepare release Instrumentation.AWS-1.1.0-beta.5 (#2020) Co-authored-by: Vishwesh Bankwar From 1b98099055fd12a845b03532c808f03171fb1039 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Mon, 26 Aug 2024 09:16:37 +0200 Subject: [PATCH 1214/1499] [Resources.Host] Fix the bug where macOS was detected as Linux (#1985) --- .github/workflows/ci.yml | 1 + src/OpenTelemetry.Resources.Host/CHANGELOG.md | 3 + .../HostDetector.cs | 114 ++++++++++++++---- .../HostResourceEventSource.cs | 13 +- .../HostDetectorTests.cs | 73 +++++++++-- 5 files changed, 170 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc3954d2b7..c547f0e902 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -485,6 +485,7 @@ jobs: with: project-name: Component[OpenTelemetry.Resources.Host] code-cov-name: Resources.Host + os-list: '[ "windows-latest", "ubuntu-latest", "macos-latest" ]' build-test-resources-operatingsystem: needs: detect-changes diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index 865e94c949..8b72918a64 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Fix the bug where macOS was detected as Linux + ([#1985](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1985)) + ## 0.1.0-beta.2 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Resources.Host/HostDetector.cs b/src/OpenTelemetry.Resources.Host/HostDetector.cs index 5da075d428..83ff701f53 100644 --- a/src/OpenTelemetry.Resources.Host/HostDetector.cs +++ b/src/OpenTelemetry.Resources.Host/HostDetector.cs @@ -2,8 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; +#if NET +using System.Runtime.InteropServices; +#endif using System.Text; using Microsoft.Win32; +using OpenTelemetry.Internal; namespace OpenTelemetry.Resources.Host; @@ -14,7 +18,9 @@ internal sealed class HostDetector : IResourceDetector { private const string ETCMACHINEID = "/etc/machine-id"; private const string ETCVARDBUSMACHINEID = "/var/lib/dbus/machine-id"; - private readonly PlatformID platformId; +#if NET + private readonly Func isOsPlatform; +#endif private readonly Func> getFilePaths; private readonly Func getMacOsMachineId; private readonly Func getWindowsMachineId; @@ -24,26 +30,50 @@ internal sealed class HostDetector : IResourceDetector /// public HostDetector() : this( - Environment.OSVersion.Platform, +#if NET + RuntimeInformation.IsOSPlatform, +#endif GetFilePaths, GetMachineIdMacOs, GetMachineIdWindows) { } - /// - /// Initializes a new instance of the class for testing. - /// - /// Target platform ID. - /// Function to get Linux file paths to probe. - /// Function to get MacOS machine ID. - /// Function to get Windows machine ID. - internal HostDetector(PlatformID platformId, Func> getFilePaths, Func getMacOsMachineId, Func getWindowsMachineId) +#if NET + public HostDetector( + Func> getFilePaths, + Func getMacOsMachineId, + Func getWindowsMachineId) + : this( + RuntimeInformation.IsOSPlatform, + getFilePaths, + getMacOsMachineId, + getWindowsMachineId) + { + } +#endif + + internal HostDetector( +#if NET + Func isOsPlatform, +#endif + Func> getFilePaths, + Func getMacOsMachineId, + Func getWindowsMachineId) { - this.platformId = platformId; - this.getFilePaths = getFilePaths ?? throw new ArgumentNullException(nameof(getFilePaths)); - this.getMacOsMachineId = getMacOsMachineId ?? throw new ArgumentNullException(nameof(getMacOsMachineId)); - this.getWindowsMachineId = getWindowsMachineId ?? throw new ArgumentNullException(nameof(getWindowsMachineId)); +#if NET + Guard.ThrowIfNull(isOsPlatform); +#endif + Guard.ThrowIfNull(getFilePaths); + Guard.ThrowIfNull(getMacOsMachineId); + Guard.ThrowIfNull(getWindowsMachineId); + +#if NET + this.isOsPlatform = isOsPlatform; +#endif + this.getFilePaths = getFilePaths; + this.getMacOsMachineId = getMacOsMachineId; + this.getWindowsMachineId = getWindowsMachineId; } /// @@ -118,17 +148,40 @@ private static IEnumerable GetFilePaths() var startInfo = new ProcessStartInfo { FileName = "sh", - Arguments = "ioreg -rd1 -c IOPlatformExpertDevice", + Arguments = "-c \"ioreg -rd1 -c IOPlatformExpertDevice\"", UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, + RedirectStandardError = true, }; var sb = new StringBuilder(); using var process = Process.Start(startInfo); - process?.WaitForExit(); - sb.Append(process?.StandardOutput.ReadToEnd()); - return sb.ToString(); + if (process != null) + { + var isExited = process.WaitForExit(5000); + if (isExited) + { + string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); + + if (!string.IsNullOrEmpty(error)) + { + HostResourceEventSource.Log.FailedToExtractResourceAttributes(nameof(HostDetector), error); + return null; + } + + sb.Append(output); + return sb.ToString(); + } + else + { + HostResourceEventSource.Log.ProcessTimeout("Process did not exit within the given timeout"); + return null; + } + } + + return null; } catch (Exception ex) { @@ -159,13 +212,26 @@ private static IEnumerable GetFilePaths() private string? GetMachineId() { - return this.platformId switch +#if NETFRAMEWORK + return this.getWindowsMachineId(); +#else + if (this.isOsPlatform(OSPlatform.Windows)) + { + return this.getWindowsMachineId(); + } + + if (this.isOsPlatform(OSPlatform.Linux)) + { + return this.GetMachineIdLinux(); + } + + if (this.isOsPlatform(OSPlatform.OSX)) { - PlatformID.Unix => this.GetMachineIdLinux(), - PlatformID.MacOSX => ParseMacOsOutput(this.getMacOsMachineId()), - PlatformID.Win32NT => this.getWindowsMachineId(), - _ => null, - }; + return ParseMacOsOutput(this.getMacOsMachineId()); + } + + return null; +#endif } private string? GetMachineIdLinux() diff --git a/src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs b/src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs index 75f55346f7..bec33ae279 100644 --- a/src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs +++ b/src/OpenTelemetry.Resources.Host/HostResourceEventSource.cs @@ -11,6 +11,9 @@ internal class HostResourceEventSource : EventSource { public static HostResourceEventSource Log = new(); + private const int EventIdFailedToExtractAttributes = 1; + private const int EventIdProcessTimeout = 2; + [NonEvent] public void ResourceAttributesExtractException(string format, Exception ex) { @@ -20,9 +23,15 @@ public void ResourceAttributesExtractException(string format, Exception ex) } } - [Event(1, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] + [Event(EventIdFailedToExtractAttributes, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] public void FailedToExtractResourceAttributes(string format, string exception) { - this.WriteEvent(3, format, exception); + this.WriteEvent(EventIdFailedToExtractAttributes, format, exception); + } + + [Event(EventIdProcessTimeout, Message = "Process timeout occurred: '{0}'", Level = EventLevel.Warning)] + public void ProcessTimeout(string processName) + { + this.WriteEvent(EventIdProcessTimeout, processName); } } diff --git a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs index ef03af3c9c..baf15769ff 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if NET +using System.Runtime.InteropServices; +#endif using Xunit; namespace OpenTelemetry.Resources.Host.Tests; @@ -36,8 +39,10 @@ public class HostDetectorTests ""IOPlatformUUID"" = ""1AB2345C-03E4-57D4-A375-1234D48DE123"" }"; +#if NET private static readonly IEnumerable ETCMACHINEID = new[] { "Samples/etc_machineid" }; private static readonly IEnumerable ETCVARDBUSMACHINEID = new[] { "Samples/etc_var_dbus_machineid" }; +#endif [Fact] public void TestHostAttributes() @@ -52,6 +57,7 @@ public void TestHostAttributes() Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); } +#if NET [Fact] public void TestHostMachineIdLinux() { @@ -66,13 +72,12 @@ public void TestHostMachineIdLinux() foreach (var (path, expected) in combos) { var detector = new HostDetector( - PlatformID.Unix, + osPlatform => osPlatform == OSPlatform.Linux, () => path, () => throw new Exception("should not be called"), () => throw new Exception("should not be called")); var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); - if (string.IsNullOrEmpty(expected)) { Assert.False(resourceAttributes.ContainsKey(HostSemanticConventions.AttributeHostId)); @@ -89,7 +94,7 @@ public void TestHostMachineIdLinux() public void TestHostMachineIdMacOs() { var detector = new HostDetector( - PlatformID.MacOSX, + osPlatform => osPlatform == OSPlatform.OSX, () => Enumerable.Empty(), () => MacOSMachineIdOutput, () => throw new Exception("should not be called")); @@ -98,6 +103,7 @@ public void TestHostMachineIdMacOs() Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); Assert.Equal("1AB2345C-03E4-57D4-A375-1234D48DE123", resourceAttributes[HostSemanticConventions.AttributeHostId]); } +#endif [Fact] public void TestParseMacOsOutput() @@ -109,14 +115,65 @@ public void TestParseMacOsOutput() [Fact] public void TestHostMachineIdWindows() { - var detector = new HostDetector( - PlatformID.Win32NT, - () => Enumerable.Empty(), - () => throw new Exception("should not be called"), - () => "windows-machine-id"); +#if NET + var detector = new HostDetector(osPlatform => osPlatform == OSPlatform.Windows, () => Enumerable.Empty(), () => throw new Exception("should not be called"), () => "windows-machine-id"); +#else + var detector = new HostDetector(() => Enumerable.Empty(), () => throw new Exception("should not be called"), () => "windows-machine-id"); +#endif + var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); Assert.NotEmpty(resourceAttributes[HostSemanticConventions.AttributeHostId]); Assert.Equal("windows-machine-id", resourceAttributes[HostSemanticConventions.AttributeHostId]); } + +#if NET + [Fact] + public void TestPlatformSpecificMethodInvocation() + { + bool linuxMethodCalled = false; + bool macOsMethodCalled = false; + bool windowsMethodCalled = false; + var detector = new HostDetector( + () => + { + linuxMethodCalled = true; + return Array.Empty(); + }, + () => + { + macOsMethodCalled = true; + return string.Empty; + }, + () => + { + windowsMethodCalled = true; + return string.Empty; + }); + detector.Detect(); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + Assert.True(linuxMethodCalled, "Linux method should have been called."); + Assert.False(windowsMethodCalled, "Windows method should not have been called."); + Assert.False(macOsMethodCalled, "MacOS method should not have been called."); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + Assert.False(linuxMethodCalled, "Linux method should not have been called."); + Assert.True(windowsMethodCalled, "Windows method should have been called."); + Assert.False(macOsMethodCalled, "MacOS method should not have been called."); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + Assert.False(linuxMethodCalled, "Linux method should not have been called."); + Assert.False(windowsMethodCalled, "Windows method should not have been called."); + Assert.True(macOsMethodCalled, "MacOS method should have been called."); + } + else + { + Assert.Fail("Unexpected platform detected."); + } + } +#endif } From 7fcae4903133fb8d6e249963bceaa81689c5e326 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Wed, 28 Aug 2024 11:18:03 -0700 Subject: [PATCH 1215/1499] [Asp.Net Core, HttpClient] Clarify Enrich callback sequence (#2011) --- .../README.md | 36 ++++++++++++++++++ .../README.md | 38 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index a56cd2ff20..12a76ed607 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -275,6 +275,42 @@ is the general extensibility point to add additional properties to any activity. The `Enrich` option is specific to this instrumentation, and is provided to get access to `HttpRequest` and `HttpResponse`. +When overriding the default settings provided by instrumentation or adding +additional telemetry, it is important to consider the sequence of callbacks. +Generally, it is recommended to use `EnrichWithHttpResponse` for any activity +enrichment that does not need access to exceptions, as the instrumentation +library populates all telemetry following the [OTel +specification](https://github.com/open-telemetry/semantic-conventions/tree/v1.27.0/docs/http) +before this callback. The following is the sequence in which these callbacks are +executed: + +1) Processor `OnStart` +2) `EnrichWithHttpRequest` +3) `EnrichWithException` +4) `EnrichWithHttpResponse` +5) Processor `OnEnd` + +As an example, if you need to override the default DisplayName or tags set by +the library you can do so as follows: + +```csharp +.AddAspNetCoreInstrumentation(o => +{ + o.EnrichWithHttpResponse = (activity, response) => + { + // Access request object if needed + // response.HttpContext.Request + activity.DisplayName = "CustomDisplayName"; + + // Overrides the value + activity.SetTag("http.route", "CustomRoute"); + + // Removes the tag + activity.SetTag("network.protocol.version", null); + }; +}); +``` + #### RecordException This instrumentation automatically sets Activity Status to Error if an unhandled diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index 2d77c64c51..cf729c8252 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -341,6 +341,44 @@ general extensibility point to add additional properties to any activity. The `Enrich` option is specific to this instrumentation, and is provided to get access to raw request, response, and exception objects. +When overriding the default settings provided by instrumentation or adding +additional telemetry, it is important to consider the sequence of callbacks. + +It is generally recommended to use `EnrichWithHttpResponseMessage` or +`EnrichWithHttpWebResponse` for any activity enrichment that does not require +access to exceptions or request object in case of .NET Framework, as the +instrumentation library populates all telemetry following the [OTel +specification](https://github.com/open-telemetry/semantic-conventions/tree/v1.27.0/docs/http) +before this callback. The following is the sequence in which these callbacks are +executed: + +1) Processor `OnStart` +2) `EnrichWithHttpRequestMessage` (.NET) / `EnrichWithHttpWebRequest` (.NET Framework) +3) `EnrichWithException` both +4) `EnrichWithHttpResponseMessage` (.NET) / `EnrichWithHttpWebResponse` (.NET Framework) +5) Processor `OnEnd` + +As an example, if you need to override the default DisplayName set by the +library you can do so as follows: + +```csharp +.AddHttpClientInstrumentation(o => +{ + o.EnrichWithHttpResponseMessage = (activity, response) => + { + // .NET only, access request object if needed. + // response.RequestMessage + activity.DisplayName = "CustomDisplayName"; + + // Overrides the value + activity.SetTag("url.full", "CustomUrl"); + + // Removes the tag + activity.SetTag("network.protocol.version", null); + }; +}); +``` + #### RecordException This instrumentation automatically sets Activity Status to Error if the Http From fbca637e9bb643e7dd1c4c30e275bd8acd9b78ef Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Fri, 30 Aug 2024 10:34:45 +0200 Subject: [PATCH 1216/1499] [Resources.OperatingSystem] Implement additional osdetector attributes (#1983) --- .../CHANGELOG.md | 8 + ...Telemetry.Resources.OperatingSystem.csproj | 1 + .../OperatingSystemDetector.cs | 236 +++++++++++++++++- .../OperatingSystemResourcesEventSource.cs | 44 ++++ .../OperatingSystemSemanticConventions.cs | 4 + .../README.md | 3 +- ...try.Resources.OperatingSystem.Tests.csproj | 9 + .../OperatingSystemDetectorTests.cs | 53 +++- .../Samples/SystemVersion.plist | 16 ++ .../Samples/os-release | 10 + 10 files changed, 371 insertions(+), 13 deletions(-) create mode 100644 src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourcesEventSource.cs create mode 100644 test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/SystemVersion.plist create mode 100644 test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/os-release diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index 24e7e0ba47..be9faebeed 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* Implement + `os.build_id`, + `os.description`, + `os.name`, + `os.version` attributes in + `OpenTelemetry.ResourceDetectors.OperatingSystem`. + ([#1983](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1983)) + ## 0.1.0-alpha.2 Released 2024-Jul-22 diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj index de79c48fe9..95c55dec8b 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj +++ b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj @@ -19,6 +19,7 @@ + diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs index 4bcce208ba..976307fba8 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs @@ -1,9 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NETFRAMEWORK +#if NET using System.Runtime.InteropServices; +using System.Xml.Linq; #endif + using static OpenTelemetry.Resources.OperatingSystem.OperatingSystemSemanticConventions; namespace OpenTelemetry.Resources.OperatingSystem; @@ -13,23 +15,98 @@ namespace OpenTelemetry.Resources.OperatingSystem; /// internal sealed class OperatingSystemDetector : IResourceDetector { + private const string RegistryKey = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; + private static readonly string[] DefaultEtcOsReleasePaths = + [ + "/etc/os-release", + "/usr/lib/os-release" + ]; + + private static readonly string[] DefaultPlistFilePaths = + [ + "/System/Library/CoreServices/SystemVersion.plist", + "/System/Library/CoreServices/ServerVersion.plist" + ]; + + private readonly string? osType; + private readonly string? registryKey; + private readonly string[]? etcOsReleasePaths; + private readonly string[]? plistFilePaths; + + internal OperatingSystemDetector() + : this( + GetOSType(), + RegistryKey, + DefaultEtcOsReleasePaths, + DefaultPlistFilePaths) + { + } + + /// + /// Initializes a new instance of the class for testing. + /// + /// The target platform identifier, specifying the operating system type from SemanticConventions. + /// The string path in the Windows Registry to retrieve specific Windows attributes. + /// The string path to the file used to obtain Linux attributes. + /// An array of file paths used to retrieve MacOS attributes from plist files. + internal OperatingSystemDetector(string? osType, string? registryKey, string[]? etcOsReleasePath, string[]? plistFilePaths) + { + this.osType = osType; + this.registryKey = registryKey; + this.etcOsReleasePaths = etcOsReleasePath; + this.plistFilePaths = plistFilePaths; + } + /// /// Detects the resource attributes from the operating system. /// /// Resource with key-value pairs of resource attributes. + /// public Resource Detect() { - var osType = GetOSType(); - - if (osType == null) + var attributes = new List>(5); + if (this.osType == null) { return Resource.Empty; } - return new Resource( - [ - new(AttributeOperatingSystemType, osType), - ]); + attributes.Add(new KeyValuePair(AttributeOperatingSystemType, this.osType)); + + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemDescription, GetOSDescription()); + + switch (this.osType) + { + case OperatingSystemsValues.Windows: + this.AddWindowsAttributes(attributes); + break; +#if NET + case OperatingSystemsValues.Linux: + this.AddLinuxAttributes(attributes); + break; + case OperatingSystemsValues.Darwin: + this.AddMacOSAttributes(attributes); + break; +#endif + } + + return new Resource(attributes); + } + + private static void AddAttributeIfNotNullOrEmpty(List> attributes, string key, object? value) + { + if (value == null) + { + OperatingSystemResourcesEventSource.Log.FailedToValidateValue("The provided value is null"); + return; + } + + if (value is string strValue && string.IsNullOrEmpty(strValue)) + { + OperatingSystemResourcesEventSource.Log.FailedToValidateValue("The provided value string is empty."); + return; + } + + attributes.Add(new KeyValuePair(key, value!)); } private static string? GetOSType() @@ -55,4 +132,147 @@ public Resource Detect() } #endif } + + private static string GetOSDescription() + { +#if NET + return RuntimeInformation.OSDescription; +#else + return Environment.OSVersion.ToString(); +#endif + } + +#pragma warning disable CA1416 + private void AddWindowsAttributes(List> attributes) + { + try + { + using var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(this.registryKey!); + if (key != null) + { + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemBuildId, key.GetValue("CurrentBuildNumber")?.ToString()); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemName, key.GetValue("ProductName")?.ToString()); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemVersion, key.GetValue("CurrentVersion")?.ToString()); + } + } + catch (Exception ex) + { + OperatingSystemResourcesEventSource.Log.ResourceAttributesExtractException("Failed to get Windows attributes", ex); + } + } +#pragma warning restore CA1416 + +#if NET + // based on: + // https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/Interop/Linux/os-release/Interop.OSReleaseFile.cs + private void AddLinuxAttributes(List> attributes) + { + try + { + string? etcOsReleasePath = this.etcOsReleasePaths!.FirstOrDefault(File.Exists); + if (string.IsNullOrEmpty(etcOsReleasePath)) + { + OperatingSystemResourcesEventSource.Log.FailedToFindFile("Failed to find the os-release file"); + return; + } + + var osReleaseContent = File.ReadAllLines(etcOsReleasePath); + ReadOnlySpan buildId = default, name = default, version = default; + + foreach (var line in osReleaseContent) + { + ReadOnlySpan lineSpan = line.AsSpan(); + + _ = TryGetFieldValue(lineSpan, "BUILD_ID=", ref buildId) || + TryGetFieldValue(lineSpan, "NAME=", ref name) || + TryGetFieldValue(lineSpan, "VERSION_ID=", ref version); + } + + // TODO: fallback for buildId + + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemBuildId, buildId.IsEmpty ? null : buildId.ToString()); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemName, name.IsEmpty ? "Linux" : name.ToString()); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemVersion, version.IsEmpty ? null : version.ToString()); + } + catch (Exception ex) + { + OperatingSystemResourcesEventSource.Log.ResourceAttributesExtractException("Failed to get Linux attributes", ex); + } + + static bool TryGetFieldValue(ReadOnlySpan line, ReadOnlySpan prefix, ref ReadOnlySpan value) + { + if (!line.StartsWith(prefix)) + { + return false; + } + + ReadOnlySpan fieldValue = line.Slice(prefix.Length); + + // Remove enclosing quotes if present. + if (fieldValue.Length >= 2 && + (fieldValue[0] == '"' || fieldValue[0] == '\'') && + fieldValue[0] == fieldValue[^1]) + { + fieldValue = fieldValue[1..^1]; + } + + value = fieldValue; + return true; + } + } + + private void AddMacOSAttributes(List> attributes) + { + try + { + string? plistFilePath = this.plistFilePaths!.FirstOrDefault(File.Exists); + if (string.IsNullOrEmpty(plistFilePath)) + { + OperatingSystemResourcesEventSource.Log.FailedToFindFile("No suitable plist file found"); + return; + } + + XDocument doc = XDocument.Load(plistFilePath); + var dict = doc.Root?.Element("dict"); + + string? buildId = null, name = null, version = null; + + if (dict != null) + { + var keys = dict.Elements("key").ToList(); + var values = dict.Elements("string").ToList(); + + if (keys.Count != values.Count) + { + OperatingSystemResourcesEventSource.Log.FailedToValidateValue($"Failed to get MacOS attributes: The number of keys does not match the number of values. Keys count: {keys.Count}, Values count: {values.Count}"); + return; + } + + for (int i = 0; i < keys.Count; i++) + { + switch (keys[i].Value) + { + case "ProductBuildVersion": + buildId = values[i].Value; + break; + case "ProductName": + name = values[i].Value; + break; + case "ProductVersion": + version = values[i].Value; + break; + } + } + } + + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemBuildId, buildId); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemName, name); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemVersion, version); + } + catch (Exception ex) + { + OperatingSystemResourcesEventSource.Log.ResourceAttributesExtractException("Failed to get MacOS attributes", ex); + } + } +#endif } diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourcesEventSource.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourcesEventSource.cs new file mode 100644 index 0000000000..12b82ec7aa --- /dev/null +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemResourcesEventSource.cs @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics.Tracing; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Resources.OperatingSystem; + +[EventSource(Name = "OpenTelemetry-Resources-OperatingSystem")] +internal sealed class OperatingSystemResourcesEventSource : EventSource +{ + public static OperatingSystemResourcesEventSource Log = new(); + + private const int EventIdFailedToExtractAttributes = 1; + private const int EventIdFailedToValidateValue = 2; + private const int EventIdFailedToFindFile = 3; + + [NonEvent] + public void ResourceAttributesExtractException(string format, Exception ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) + { + this.FailedToExtractResourceAttributes(format, ex.ToInvariantString()); + } + } + + [Event(EventIdFailedToExtractAttributes, Message = "Failed to extract resource attributes in '{0}'.", Level = EventLevel.Warning)] + public void FailedToExtractResourceAttributes(string format, string exception) + { + this.WriteEvent(EventIdFailedToExtractAttributes, format, exception); + } + + [Event(EventIdFailedToValidateValue, Message = "Failed to validate value. Details: '{0}'", Level = EventLevel.Warning)] + public void FailedToValidateValue(string error) + { + this.WriteEvent(EventIdFailedToValidateValue, error); + } + + [Event(EventIdFailedToFindFile, Message = "Process timeout occurred: '{0}'", Level = EventLevel.Warning)] + public void FailedToFindFile(string error) + { + this.WriteEvent(EventIdFailedToFindFile, error); + } +} diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs index 356ad734da..87d8c54081 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemSemanticConventions.cs @@ -6,6 +6,10 @@ namespace OpenTelemetry.Resources.OperatingSystem; internal static class OperatingSystemSemanticConventions { public const string AttributeOperatingSystemType = "os.type"; + public const string AttributeOperatingSystemBuildId = "os.build_id"; + public const string AttributeOperatingSystemDescription = "os.description"; + public const string AttributeOperatingSystemName = "os.name"; + public const string AttributeOperatingSystemVersion = "os.version"; public static class OperatingSystemsValues { diff --git a/src/OpenTelemetry.Resources.OperatingSystem/README.md b/src/OpenTelemetry.Resources.OperatingSystem/README.md index 7b74713a40..40c1c5a9b1 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/README.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/README.md @@ -54,7 +54,8 @@ using var loggerFactory = LoggerFactory.Create(builder => The resource detectors will record the following metadata based on where your application is running: -- **OperatingSystemDetector**: `os.type`. +- **OperatingSystemDetector**: `os.type`, `os.build_id`, `os.description`, + `os.name`, `os.version`. ## References diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj index c5b25f22ea..b8c188d1d8 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj @@ -11,4 +11,13 @@ + + + PreserveNewest + + + PreserveNewest + + + diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs index dbcf1bb113..68ae79e3c5 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs @@ -12,32 +12,77 @@ public class OperatingSystemDetectorTests public void TestOperatingSystemAttributes() { var resource = ResourceBuilder.CreateEmpty().AddOperatingSystemDetector().Build(); - var resourceAttributes = resource.Attributes.ToDictionary(x => x.Key, x => (string)x.Value); string expectedPlatform; + string expectedDescription; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { expectedPlatform = OperatingSystemSemanticConventions.OperatingSystemsValues.Windows; + expectedDescription = "Windows"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { expectedPlatform = OperatingSystemSemanticConventions.OperatingSystemsValues.Linux; + expectedDescription = "Linux"; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { expectedPlatform = OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin; + expectedDescription = "Darwin"; } else { throw new PlatformNotSupportedException("Unknown platform"); } - Assert.Single(resourceAttributes); + Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemDescription, resourceAttributes.Keys); + Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemName, resourceAttributes.Keys); + Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemType, resourceAttributes.Keys); + Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemVersion, resourceAttributes.Keys); + + // Not checking on Linux because the description may vary depending on the distribution. + if (expectedDescription != "Linux") + { + Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemBuildId, resourceAttributes.Keys); + Assert.Contains(expectedDescription, resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemDescription]); + Assert.Equal(5, resourceAttributes.Count); + } - Assert.True(resourceAttributes.ContainsKey(OperatingSystemSemanticConventions.AttributeOperatingSystemType)); + Assert.Equal(expectedPlatform, resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemType]); + } + +#if NET + [Fact] + public void TestParseMacOSPlist() + { + string path = "Samples/SystemVersion.plist"; + var osDetector = new OperatingSystemDetector( + OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin, + null, + null, + [path]); + var attributes = osDetector.Detect().Attributes.ToDictionary(x => x.Key, x => (string)x.Value); + + Assert.Equal("Mac OS X", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemName]); + Assert.Equal("10.6.8", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemVersion]); + Assert.Equal("10K549", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemBuildId]); + } + + [Fact] + public void TestParseLinuxOsRelease() + { + string path = "Samples/os-release"; + var osDetector = new OperatingSystemDetector( + OperatingSystemSemanticConventions.OperatingSystemsValues.Linux, + null, + [path], + null); + var attributes = osDetector.Detect().Attributes.ToDictionary(x => x.Key, x => (string)x.Value); - Assert.Equal(resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemType], expectedPlatform); + Assert.Equal("Ubuntu", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemName]); + Assert.Equal("22.04", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemVersion]); } +#endif } diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/SystemVersion.plist b/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/SystemVersion.plist new file mode 100644 index 0000000000..ef45504dcd --- /dev/null +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/SystemVersion.plist @@ -0,0 +1,16 @@ + + + + +ProductBuildVersion +10K549 +ProductCopyright +1983-2011 Apple Inc. +ProductName +Mac OS X +ProductUserVisibleVersion +10.6.8 +ProductVersion +10.6.8 + + diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/os-release b/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/os-release new file mode 100644 index 0000000000..af5f81109a --- /dev/null +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/os-release @@ -0,0 +1,10 @@ +NAME=Ubuntu +VERSION="22.04 LTS (Jammy Jellyfish)" +VERSION_ID="22.04" +VERSION_CODENAME=jammy +ID=ubuntu +HOME_URL=https://www.ubuntu.com/ +SUPPORT_URL=https://help.ubuntu.com/ +BUG_REPORT_URL=https://bugs.launchpad.net/ubuntu +PRIVACY_POLICY_URL=https://www.ubuntu.com/legal/terms-and-policies/privacy-policy +UBUNTU_CODENAME=jammy From b2723f6797c632f3f0cc940a395dcfdc9f474cab Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 30 Aug 2024 03:42:51 -0500 Subject: [PATCH 1217/1499] [release] Prepare release Resources.Host-0.1.0-beta.3 (#2030) --- src/OpenTelemetry.Resources.Host/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index 8b72918a64..a497691784 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-beta.3 + +Released 2024-Aug-30 + * Fix the bug where macOS was detected as Linux ([#1985](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1985)) From bc27d715b165fb77186e26e2b6313b78789dee0a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 30 Aug 2024 03:47:27 -0500 Subject: [PATCH 1218/1499] [release] Prepare release Resources.OperatingSystem-0.1.0-alpha.3 (#2031) --- src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index be9faebeed..75723ccda0 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.3 + +Released 2024-Aug-30 + * Implement `os.build_id`, `os.description`, From 544eb987aabbace91aa449edb1acd1141a983083 Mon Sep 17 00:00:00 2001 From: Guillaume Delahaye <681739+g7ed6e@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:41:57 +0200 Subject: [PATCH 1219/1499] Add a process span to ConfluentKafka instrumentation (#1937) Co-authored-by: Liudmila Molkova --- build/Common.props | 2 +- .../.publicApi/PublicAPI.Unshipped.txt | 6 + .../ConfluentKafkaCommon.cs | 5 + .../InstrumentedConsumer.cs | 28 +-- .../InstrumentedConsumerBuilder.cs | 6 +- .../InstrumentedProducer.cs | 13 +- .../InstrumentedProducerBuilder.cs | 8 +- ...etry.Instrumentation.ConfluentKafka.csproj | 5 - ...elemetryConsumeAndProcessMessageHandler.cs | 20 ++ .../OpenTelemetryConsumeResultExtensions.cs | 184 ++++++++++++++++++ .../TracingTests.cs | 59 ++++++ 11 files changed, 289 insertions(+), 47 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeAndProcessMessageHandler.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs diff --git a/build/Common.props b/build/Common.props index fc7ab24872..8139621283 100644 --- a/build/Common.props +++ b/build/Common.props @@ -43,7 +43,7 @@ [1.9.0,2.0) [1.9.0-rc.1] [2.6.122,3.0) - [2.3.0,3.0) + [2.4.0,3.0) [3.16.0,4.0) [1.2.0-beta.507,2.0) [4.3.4,) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt index d27211c49c..f0c6ffc9b1 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ +Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler +Confluent.Kafka.OpenTelemetryConsumeResultExtensions OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.InstrumentedConsumerBuilder(System.Collections.Generic.IEnumerable>! config) -> void OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder @@ -6,6 +8,9 @@ OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.Build() -> Confluent.Kafka.IConsumer! override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.Build() -> Confluent.Kafka.IProducer! +static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.ConsumeAndProcessMessageAsync(this Confluent.Kafka.IConsumer! consumer, Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler! handler) -> System.Threading.Tasks.ValueTask?> +static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.ConsumeAndProcessMessageAsync(this Confluent.Kafka.IConsumer! consumer, Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler! handler, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask?> +static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.TryExtractPropagationContext(this Confluent.Kafka.ConsumeResult! consumeResult, out OpenTelemetry.Context.Propagation.PropagationContext propagationContext) -> bool static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! @@ -18,3 +23,4 @@ static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstr static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +virtual Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler.Invoke(Confluent.Kafka.ConsumeResult! consumeResult, System.Diagnostics.Activity? activity, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs index beb4c4812d..b4c024db0e 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs @@ -10,6 +10,11 @@ namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal static class ConfluentKafkaCommon { + internal const string ReceiveOperationName = "receive"; + internal const string ProcessOperationName = "process"; + internal const string KafkaMessagingSystem = "kafka"; + internal const string PublishOperationName = "publish"; + internal static readonly string InstrumentationName = typeof(ConfluentKafkaCommon).Assembly.GetName().Name!; internal static readonly string InstrumentationVersion = typeof(ConfluentKafkaCommon).Assembly.GetPackageVersion(); internal static readonly ActivitySource ActivitySource = new(InstrumentationName, InstrumentationVersion); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs index 8fa5fa8b02..561f3a1014 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Text; using Confluent.Kafka; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Trace; @@ -11,8 +10,6 @@ namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal class InstrumentedConsumer : IConsumer { - private const string ReceiveOperationName = "receive"; - private const string KafkaMessagingSystem = "kafka"; private readonly IConsumer consumer; private readonly ConfluentKafkaConsumerInstrumentationOptions options; @@ -265,17 +262,6 @@ public void Close() private static string FormatConsumeException(ConsumeException consumeException) => $"ConsumeException: {consumeException.Error}"; - private static PropagationContext ExtractPropagationContext(Headers? headers) - => Propagators.DefaultTextMapPropagator.Extract(default, headers, ExtractTraceContext); - - private static IEnumerable ExtractTraceContext(Headers? headers, string value) - { - if (headers?.TryGetLastBytes(value, out var bytes) == true) - { - yield return Encoding.UTF8.GetString(bytes); - } - } - private static ConsumeResult ExtractConsumeResult(ConsumeResult result) => result switch { null => new ConsumeResult(null, null), @@ -296,10 +282,10 @@ private static void GetTags(string topic, out TagList tags, int? partition = nul { new KeyValuePair( SemanticConventions.AttributeMessagingOperation, - ReceiveOperationName), + ConfluentKafkaCommon.ReceiveOperationName), new KeyValuePair( SemanticConventions.AttributeMessagingSystem, - KafkaMessagingSystem), + ConfluentKafkaCommon.KafkaMessagingSystem), new KeyValuePair( SemanticConventions.AttributeMessagingDestinationName, topic), @@ -335,7 +321,7 @@ private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endT if (this.options.Traces) { PropagationContext propagationContext = consumeResult.Headers != null - ? ExtractPropagationContext(consumeResult.Headers) + ? OpenTelemetryConsumeResultExtensions.ExtractPropagationContext(consumeResult.Headers) : default; using Activity? activity = this.StartReceiveActivity(propagationContext, startTime, consumeResult.TopicPartitionOffset, consumeResult.Key); @@ -364,8 +350,8 @@ private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endT private Activity? StartReceiveActivity(PropagationContext propagationContext, DateTimeOffset start, TopicPartitionOffset? topicPartitionOffset, object? key) { var spanName = string.IsNullOrEmpty(topicPartitionOffset?.Topic) - ? ReceiveOperationName - : string.Concat(topicPartitionOffset!.Topic, " ", ReceiveOperationName); + ? ConfluentKafkaCommon.ReceiveOperationName + : string.Concat(topicPartitionOffset!.Topic, " ", ConfluentKafkaCommon.ReceiveOperationName); ActivityLink[] activityLinks = propagationContext.ActivityContext.IsValid() ? new[] { new ActivityLink(propagationContext.ActivityContext) } @@ -374,13 +360,13 @@ private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endT Activity? activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, startTime: start, parentContext: default); if (activity?.IsAllDataRequested == true) { - activity.SetTag(SemanticConventions.AttributeMessagingSystem, KafkaMessagingSystem); + activity.SetTag(SemanticConventions.AttributeMessagingSystem, ConfluentKafkaCommon.KafkaMessagingSystem); activity.SetTag(SemanticConventions.AttributeMessagingClientId, this.Name); activity.SetTag(SemanticConventions.AttributeMessagingDestinationName, topicPartitionOffset?.Topic); activity.SetTag(SemanticConventions.AttributeMessagingKafkaDestinationPartition, topicPartitionOffset?.Partition.Value); activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageOffset, topicPartitionOffset?.Offset.Value); activity.SetTag(SemanticConventions.AttributeMessagingKafkaConsumerGroup, this.GroupId); - activity.SetTag(SemanticConventions.AttributeMessagingOperation, ReceiveOperationName); + activity.SetTag(SemanticConventions.AttributeMessagingOperation, ConfluentKafkaCommon.ReceiveOperationName); if (key != null) { activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageKey, key); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs index 93268ba5c7..8352c874e3 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs @@ -33,12 +33,8 @@ public override IConsumer Build() Debug.Assert(this.Options != null, "Options should not be null."); ConsumerConfig config = (ConsumerConfig)this.Config; - if (this.Options!.Metrics) - { - config.StatisticsIntervalMs ??= 1000; - } - var consumer = new InstrumentedConsumer(base.Build(), this.Options); + var consumer = new InstrumentedConsumer(base.Build(), this.Options!); consumer.GroupId = config.GroupId; return consumer; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs index aa7d31ba48..a91c04314c 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs @@ -11,9 +11,6 @@ namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal sealed class InstrumentedProducer : IProducer { - private const string PublishOperationName = "publish"; - private const string KafkaMessagingSystem = "kafka"; - private readonly TextMapPropagator propagator = Propagators.DefaultTextMapPropagator; private readonly IProducer producer; private readonly ConfluentKafkaProducerInstrumentationOptions options; @@ -285,10 +282,10 @@ private static void GetTags(string topic, out TagList tags, int? partition = nul { new KeyValuePair( SemanticConventions.AttributeMessagingOperation, - PublishOperationName), + ConfluentKafkaCommon.PublishOperationName), new KeyValuePair( SemanticConventions.AttributeMessagingSystem, - KafkaMessagingSystem), + ConfluentKafkaCommon.KafkaMessagingSystem), new KeyValuePair( SemanticConventions.AttributeMessagingDestinationName, topic), @@ -329,7 +326,7 @@ private static void RecordPublish(TopicPartition topicPartition, TimeSpan durati private Activity? StartPublishActivity(DateTimeOffset start, string topic, Message message, int? partition = null) { - var spanName = string.Concat(topic, " ", PublishOperationName); + var spanName = string.Concat(topic, " ", ConfluentKafkaCommon.PublishOperationName); var activity = ConfluentKafkaCommon.ActivitySource.StartActivity(name: spanName, kind: ActivityKind.Producer, startTime: start); if (activity == null) { @@ -338,10 +335,10 @@ private static void RecordPublish(TopicPartition topicPartition, TimeSpan durati if (activity.IsAllDataRequested) { - activity.SetTag(SemanticConventions.AttributeMessagingSystem, KafkaMessagingSystem); + activity.SetTag(SemanticConventions.AttributeMessagingSystem, ConfluentKafkaCommon.KafkaMessagingSystem); activity.SetTag(SemanticConventions.AttributeMessagingClientId, this.Name); activity.SetTag(SemanticConventions.AttributeMessagingDestinationName, topic); - activity.SetTag(SemanticConventions.AttributeMessagingOperation, PublishOperationName); + activity.SetTag(SemanticConventions.AttributeMessagingOperation, ConfluentKafkaCommon.PublishOperationName); if (message.Key != null) { diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs index bcc29f5add..5dca3f77a3 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs @@ -32,12 +32,6 @@ public override IProducer Build() { Debug.Assert(this.Options != null, "Options should not be null."); - ProducerConfig config = (ProducerConfig)this.Config; - if (this.Options!.Metrics) - { - config.StatisticsIntervalMs ??= 1000; - } - - return new InstrumentedProducer(base.Build(), this.Options); + return new InstrumentedProducer(base.Build(), this.Options!); } } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj index da497e973c..bc7d46a90d 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj @@ -27,9 +27,4 @@ - - - - - diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeAndProcessMessageHandler.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeAndProcessMessageHandler.cs new file mode 100644 index 0000000000..fcbaa60e38 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeAndProcessMessageHandler.cs @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; + +namespace Confluent.Kafka; + +/// +/// An asynchronous action to process the . +/// +/// The . +/// The . +/// An optional . +/// The type of key of the . +/// The type of value of the . +/// A . +public delegate ValueTask OpenTelemetryConsumeAndProcessMessageHandler( + ConsumeResult consumeResult, + Activity? activity, + CancellationToken cancellationToken = default); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs new file mode 100644 index 0000000000..abedc35623 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs @@ -0,0 +1,184 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Text; +using OpenTelemetry; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Instrumentation.ConfluentKafka; +using OpenTelemetry.Trace; + +namespace Confluent.Kafka; + +/// +/// extension methods. +/// +public static class OpenTelemetryConsumeResultExtensions +{ + /// + /// Attempts to extract a from the 's property. + /// + /// The . + /// The . + /// The type of key of the . + /// The type of value of the . + /// True when a has been extracted from , otherwise false. + public static bool TryExtractPropagationContext( + this ConsumeResult consumeResult, + out PropagationContext propagationContext) + { +#if NETFRAMEWORK + if (consumeResult == null) + { + throw new ArgumentNullException(nameof(consumeResult)); + } +#else + ArgumentNullException.ThrowIfNull(consumeResult); +#endif + + try + { + propagationContext = ExtractPropagationContext(consumeResult.Message?.Headers); + return true; + } + catch + { + propagationContext = default; + return false; + } + } + + /// + /// Consumes a message and creates a process span embracing the . + /// + /// The . + /// A . + /// The type of key of the . + /// The type of value of the . + /// A . + public static ValueTask?> ConsumeAndProcessMessageAsync( + this IConsumer consumer, + OpenTelemetryConsumeAndProcessMessageHandler handler) => + ConsumeAndProcessMessageAsync(consumer, handler, default); + + /// + /// Consumes a message and creates a process span embracing the . + /// + /// The . + /// A . + /// An optional . + /// The type of key of the . + /// The type of value of the . + /// A . + public static async ValueTask?> ConsumeAndProcessMessageAsync( + this IConsumer consumer, + OpenTelemetryConsumeAndProcessMessageHandler handler, + CancellationToken cancellationToken) + { +#if NETFRAMEWORK + if (consumer == null) + { + throw new ArgumentNullException(nameof(consumer)); + } +#else + ArgumentNullException.ThrowIfNull(consumer); +#endif + + if (consumer is not InstrumentedConsumer instrumentedConsumer) + { + throw new ArgumentException("Invalid consumer type.", nameof(consumer)); + } + +#if NETFRAMEWORK + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } +#else + ArgumentNullException.ThrowIfNull(handler); +#endif + + var consumeResult = instrumentedConsumer.Consume(cancellationToken); + + if (consumeResult?.Message == null || consumeResult.IsPartitionEOF) + { + return consumeResult; + } + + Activity? processActivity = null; + if (TryExtractPropagationContext(consumeResult, out var propagationContext)) + { + processActivity = StartProcessActivity( + propagationContext, + consumeResult.TopicPartitionOffset, + consumeResult.Message.Key, + instrumentedConsumer.Name, + instrumentedConsumer.GroupId!); + } + else + { + processActivity = StartProcessActivity( + default, + consumeResult.TopicPartitionOffset, + consumeResult.Message.Key, + instrumentedConsumer.Name, + instrumentedConsumer.GroupId!); + } + + try + { + await handler(consumeResult, processActivity, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + processActivity?.SetStatus(Status.Error); + processActivity?.SetTag(SemanticConventions.AttributeErrorType, ex.GetType().FullName); + } + finally + { + processActivity?.Dispose(); + } + + return consumeResult; + } + + internal static PropagationContext ExtractPropagationContext(Headers? headers) + => Propagators.DefaultTextMapPropagator.Extract(default, headers, ExtractTraceContext); + + private static Activity? StartProcessActivity(PropagationContext propagationContext, TopicPartitionOffset? topicPartitionOffset, TKey? key, string clientId, string groupId) + { + var spanName = string.IsNullOrEmpty(topicPartitionOffset?.Topic) + ? ConfluentKafkaCommon.ProcessOperationName + : string.Concat(topicPartitionOffset!.Topic, " ", ConfluentKafkaCommon.ProcessOperationName); + + ActivityLink[] activityLinks = propagationContext != default && propagationContext.ActivityContext.IsValid() + ? new[] { new ActivityLink(propagationContext.ActivityContext) } + : Array.Empty(); + + Activity? activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, parentContext: default); + if (activity?.IsAllDataRequested == true) + { + activity.SetTag(SemanticConventions.AttributeMessagingSystem, ConfluentKafkaCommon.KafkaMessagingSystem); + activity.SetTag(SemanticConventions.AttributeMessagingClientId, clientId); + activity.SetTag(SemanticConventions.AttributeMessagingDestinationName, topicPartitionOffset?.Topic); + activity.SetTag(SemanticConventions.AttributeMessagingKafkaDestinationPartition, topicPartitionOffset?.Partition.Value); + activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageOffset, topicPartitionOffset?.Offset.Value); + activity.SetTag(SemanticConventions.AttributeMessagingKafkaConsumerGroup, groupId); + activity.SetTag(SemanticConventions.AttributeMessagingOperation, ConfluentKafkaCommon.ProcessOperationName); + if (key != null) + { + activity.SetTag(SemanticConventions.AttributeMessagingKafkaMessageKey, key); + } + } + + return activity; + } + + private static IEnumerable ExtractTraceContext(Headers? headers, string value) + { + if (headers?.TryGetLastBytes(value, out var bytes) == true) + { + yield return Encoding.UTF8.GetString(bytes); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs index 923b4dae99..b9de9a616b 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs @@ -302,4 +302,63 @@ public async Task BasicConsumeWithTimeoutTimespanTest() Assert.Equal(0L, activity.GetTagValue("messaging.kafka.message.offset")); Assert.Equal("test-consumer-group", activity.GetTagValue("messaging.kafka.consumer.group")); } + + [Trait("CategoryName", "KafkaIntegrationTests")] + [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] + public async Task ConsumeAndProcessMessageTest() + { + string topic = await KafkaHelpers.ProduceTestMessageAsync(); + + ConsumerConfig consumerConfig = new ConsumerConfig + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = "test-consumer-group", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + InstrumentedConsumerBuilder consumerBuilder = new(consumerConfig); + var sampler = new TestSampler(); + var activities = new List(); + using (Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(activities) + .SetSampler(sampler) + .AddKafkaConsumerInstrumentation(consumerBuilder) + .Build()) + { + using IConsumer consumer = consumerBuilder.Build(); + consumer.Subscribe(topic); + while (true) + { + var consumeResult = await consumer.ConsumeAndProcessMessageAsync(NoOpAsync); + if (consumeResult == null) + { + continue; + } + + if (consumeResult.IsPartitionEOF) + { + break; + } + } + + consumer.Close(); + } + + var processActivity = Assert.Single(activities, activity => activity.DisplayName == topic + " process"); + + Assert.Equal("kafka", processActivity.GetTagValue(SemanticConventions.AttributeMessagingSystem)); + Assert.Equal("process", processActivity.GetTagValue(SemanticConventions.AttributeMessagingOperation)); + Assert.Equal(topic, processActivity.GetTagValue("messaging.destination.name")); + Assert.Equal(0, processActivity.GetTagValue("messaging.kafka.destination.partition")); + Assert.Equal(0L, processActivity.GetTagValue("messaging.kafka.message.offset")); + Assert.Equal("test-consumer-group", processActivity.GetTagValue("messaging.kafka.consumer.group")); + + ValueTask NoOpAsync( + ConsumeResult consumeResult, + Activity? activity, + CancellationToken cancellationToken = default) + { + return default; + } + } } From 069181027d77a4891a8e5afd6532ec7d9bc3786e Mon Sep 17 00:00:00 2001 From: Oleksiy Dubinin <88040756+rypdal@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:46:33 +0200 Subject: [PATCH 1220/1499] [Instrumentation.AWSLambda] Incoming FaaS Span attributes: detect and set attribute for cold start (#2037) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Neumüller --- .../AWSLambdaWrapper.cs | 9 ++++++- .../CHANGELOG.md | 3 +++ .../AWSLambdaSemanticConventions.cs | 1 + .../Implementation/AWSLambdaUtils.cs | 3 ++- .../AWSLambdaWrapperTests.cs | 24 +++++++++++++++++++ 5 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index dcf1370e23..9ba0410d08 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -18,6 +18,8 @@ public static class AWSLambdaWrapper private static readonly ActivitySource AWSLambdaActivitySource = new(ActivitySourceName, typeof(AWSLambdaWrapper).Assembly.GetPackageVersion()); + private static bool isColdStart = true; + /// /// Gets or sets a value indicating whether AWS X-Ray propagation should be ignored. Default value is false. /// @@ -160,7 +162,9 @@ public static Task TraceAsync( } } - var functionTags = AWSLambdaUtils.GetFunctionTags(input, context); + // No parallel invocation of the same lambda handler expected. + var functionTags = AWSLambdaUtils.GetFunctionTags(input, context, isColdStart); + isColdStart = false; var httpTags = AWSLambdaHttpUtils.GetHttpTags(input); // We assume that functionTags and httpTags have no intersection. @@ -170,6 +174,9 @@ public static Task TraceAsync( return activity; } + // Use only for testing. + internal static void ResetColdStart() => isColdStart = true; + private static void OnFunctionStop(Activity? activity, TracerProvider? tracerProvider) { activity?.Stop(); diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 10f59f5d28..ce05cc975c 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add detection of Lambda cold start and set `faas.coldstart` Activity tag. + ([#2037](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2037)) + ## 1.3.0-beta.1 Released 2024-Jan-26 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs index 79185bcf60..6cfad894bb 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs @@ -16,4 +16,5 @@ internal static class AWSLambdaSemanticConventions public const string AttributeFaasName = "faas.name"; public const string AttributeFaasVersion = "faas.version"; public const string AttributeFaasTrigger = "faas.trigger"; + public const string AttributeFaasColdStart = "faas.coldstart"; } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 1db7bf12c7..d53f1ea6c4 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -98,11 +98,12 @@ internal static string GetCloudProvider() return Environment.GetEnvironmentVariable(FunctionVersion); } - internal static IEnumerable> GetFunctionTags(TInput input, ILambdaContext context) + internal static IEnumerable> GetFunctionTags(TInput input, ILambdaContext context, bool isColdStart) { var tags = new List> { new(AWSLambdaSemanticConventions.AttributeFaasTrigger, GetFaasTrigger(input)), + new(AWSLambdaSemanticConventions.AttributeFaasColdStart, isColdStart), }; var functionName = GetFunctionName(context); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index 6262c29baa..a7d617bc70 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -213,6 +213,30 @@ public void OnFunctionStart_NoSampledAndAwsXRayContextExtractionDisabled_Activit Assert.NotNull(activity); } + [Theory] + [InlineData(1)] + [InlineData(2)] + public void OnFunctionStart_ColdStart_ColdStartTagHasCorrectValue(int invocationsCount) + { + AWSLambdaWrapper.ResetColdStart(); + Activity? activity = null; + + using (var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) + .Build()) + { + for (int i = 1; i <= invocationsCount; i++) + { + activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); + } + } + + Assert.NotNull(activity); + Assert.NotNull(activity.TagObjects); + var expectedColdStartValue = invocationsCount == 1 ? true : false; + Assert.Contains(activity.TagObjects, x => x.Key == AWSLambdaSemanticConventions.AttributeFaasColdStart && expectedColdStartValue.Equals(x.Value)); + } + private static ActivityContext CreateParentContext() { var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); From 717bf88cb6bc342fa2b1d485b6b161848428aa3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 5 Sep 2024 07:02:23 +0200 Subject: [PATCH 1221/1499] [repo] Drop dotnet-xunit + bump test dependencies (#2035) --- build/Common.nonprod.props | 7 ++----- examples/AspNet/Examples.AspNet.csproj | 2 +- .../Examples.InfluxDB/Examples.InfluxDB.csproj | 2 +- ...Telemetry.Instrumentation.AspNetCore.Tests.csproj | 12 ++++++------ ...emetry.Instrumentation.GrpcNetClient.Tests.csproj | 4 ++-- ...nTelemetry.Instrumentation.SqlClient.Tests.csproj | 4 ++-- test/TestApp.AspNetCore/TestApp.AspNetCore.csproj | 2 +- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index a5f30b7c4d..b7cf1a447f 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -21,23 +21,20 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [0.13.12,0.14) - [2.3.1,3.0) 8.0.0 - [17.9.0,18.0) + [17.11.0,18.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net7.0;net6.0 [2.8.2,3.0) [2.9.0,3.0) - [1.5.58,2.0) + [1.6.1,2.0) - - diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 75126f63ed..f25b7b5887 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -53,7 +53,7 @@ - + diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj index 55b8906ea0..b4a514d60e 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 98a11d30d9..9a8eebc05e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -5,18 +5,18 @@ - - + + - - + + - - + + diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index cf6f711f07..2ce1d55199 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -18,8 +18,8 @@ - - + + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index a6b26ab43d..776634117a 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -16,8 +16,8 @@ - - + + diff --git a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj index 552a719fa7..24e5a6ee1a 100644 --- a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj +++ b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj @@ -5,7 +5,7 @@ - + From 3a8cbafa44878cf24478142f314c0e715d5fc6ee Mon Sep 17 00:00:00 2001 From: Harvey Rendell Date: Fri, 6 Sep 2024 22:45:01 +1200 Subject: [PATCH 1222/1499] [Instrumentation.AwsLambda] support for application loadbalancer events (#2033) --- .../CHANGELOG.md | 2 + .../Implementation/AWSLambdaHttpUtils.cs | 55 ++++++ .../Implementation/AWSLambdaUtils.cs | 19 +- ...Telemetry.Instrumentation.AWSLambda.csproj | 1 + .../README.md | 2 +- .../Implementation/AWSLambdaHttpUtilsTests.cs | 169 ++++++++++++++++++ 6 files changed, 246 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index ce05cc975c..b098e49db1 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -4,6 +4,8 @@ * Add detection of Lambda cold start and set `faas.coldstart` Activity tag. ([#2037](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2037)) +* Add HTTP server span attributes for Application Loadbalancer triggers + ([#2033](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2033)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index 120189d81e..38273c5331 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -5,6 +5,7 @@ using System.Text; using System.Web; using Amazon.Lambda.APIGatewayEvents; +using Amazon.Lambda.ApplicationLoadBalancerEvents; using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWSLambda.Implementation; @@ -42,6 +43,13 @@ internal static IEnumerable> GetHttpTags(TI var hostHeaderV2 = AWSLambdaUtils.GetHeaderValues(requestV2, HeaderHost)?.LastOrDefault(); (hostName, hostPort) = GetHostAndPort(httpScheme, hostHeaderV2); break; + case ApplicationLoadBalancerRequest albRequest: + httpScheme = AWSLambdaUtils.GetHeaderValues(albRequest, HeaderXForwardedProto)?.LastOrDefault(); + httpTarget = string.Concat(albRequest.Path ?? string.Empty, GetQueryString(albRequest)); + httpMethod = albRequest.HttpMethod; + var albHostHeader = AWSLambdaUtils.GetHeaderValues(albRequest, HeaderHost)?.LastOrDefault(); + (hostName, hostPort) = GetHostAndPort(httpScheme, albHostHeader); + break; default: return tags; } @@ -70,6 +78,9 @@ internal static void SetHttpTagsFromResult(Activity? activity, object? result) case APIGatewayHttpApiV2ProxyResponse responseV2: activity.SetTag(SemanticConventions.AttributeHttpStatusCode, responseV2.StatusCode); break; + case ApplicationLoadBalancerResponse albResponse: + activity.SetTag(SemanticConventions.AttributeHttpStatusCode, albResponse.StatusCode); + break; } } @@ -102,6 +113,50 @@ internal static void SetHttpTagsFromResult(Activity? activity, object? result) internal static string? GetQueryString(APIGatewayHttpApiV2ProxyRequest request) => string.IsNullOrEmpty(request.RawQueryString) ? string.Empty : "?" + request.RawQueryString; + internal static string? GetQueryString(ApplicationLoadBalancerRequest request) + { + // If the request has a query string value, one of the following properties will be set, depending on if + // "Multi value headers" is enabled on ELB Target Group. + if (request.MultiValueQueryStringParameters != null) + { + var queryString = new StringBuilder(); + var separator = '?'; + foreach (var parameterKvp in request.MultiValueQueryStringParameters) + { + // Multiple values for the same parameter will be added to query + // as ampersand separated: name=value1&name=value2 + foreach (var value in parameterKvp.Value) + { + queryString.Append(separator) + .Append(HttpUtility.UrlEncode(parameterKvp.Key)) + .Append('=') + .Append(HttpUtility.UrlEncode(value)); + separator = '&'; + } + } + + return queryString.ToString(); + } + + if (request.QueryStringParameters != null) + { + var queryString = new StringBuilder(); + var separator = '?'; + foreach (var parameterKvp in request.QueryStringParameters) + { + queryString.Append(separator) + .Append(HttpUtility.UrlEncode(parameterKvp.Key)) + .Append('=') + .Append(HttpUtility.UrlEncode(parameterKvp.Value)); + separator = '&'; + } + + return queryString.ToString(); + } + + return string.Empty; + } + internal static (string? Host, int? Port) GetHostAndPort(string? httpScheme, string? hostHeader) { if (hostHeader == null) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index d53f1ea6c4..5c0430ce05 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Amazon.Lambda.APIGatewayEvents; +using Amazon.Lambda.ApplicationLoadBalancerEvents; using Amazon.Lambda.Core; using Amazon.Lambda.SNSEvents; using Amazon.Lambda.SQSEvents; @@ -61,6 +62,9 @@ internal static (ActivityContext ParentContext, IEnumerable? Links case APIGatewayHttpApiV2ProxyRequest apiGatewayHttpApiV2ProxyRequest: parentContext = Propagators.DefaultTextMapPropagator.Extract(default, apiGatewayHttpApiV2ProxyRequest, GetHeaderValues); break; + case ApplicationLoadBalancerRequest applicationLoadBalancerRequest: + parentContext = Propagators.DefaultTextMapPropagator.Extract(default, applicationLoadBalancerRequest, GetHeaderValues); + break; case SQSEvent sqsEvent: (parentContext, links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); break; @@ -153,6 +157,19 @@ internal static IEnumerable> GetFunctionTags? GetHeaderValues(ApplicationLoadBalancerRequest request, string name) + { + var multiValueHeader = request.MultiValueHeaders?.GetValueByKeyIgnoringCase(name); + if (multiValueHeader != null) + { + return multiValueHeader; + } + + var headerValue = request.Headers?.GetValueByKeyIgnoringCase(name); + + return headerValue != null ? new[] { headerValue } : null; + } + private static string? GetHeaderValue(APIGatewayHttpApiV2ProxyRequest request, string name) => request.Headers?.GetValueByKeyIgnoringCase(name); @@ -190,7 +207,7 @@ private static string GetFaasTrigger(TInput input) => IsHttpRequest(input) ? "http" : "other"; private static bool IsHttpRequest(TInput input) => - input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest; + input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest || input is ApplicationLoadBalancerRequest; private static ActivityContext ParseXRayTraceHeader(string rawHeader) { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index ebd0158ede..e59ca1fbca 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -15,6 +15,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md index 69e5176d88..ad7828d792 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/README.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/README.md @@ -59,7 +59,7 @@ The parent extraction is supported for the input types listed in the table below | Type | Parent extraction source | |------|--------------------------| -| `APIGatewayProxyRequest, APIGatewayHttpApiV2ProxyRequest` | HTTP headers of the request | +| `APIGatewayProxyRequest, APIGatewayHttpApiV2ProxyRequest`, `ApplicationLoadBalancerRequest` | HTTP headers of the request | | `SQSEvent` | Attributes of the last `SQSMessage` (if `SetParentFromMessageBatch` is `true`) | | `SNSEvent` | Attributes of the last `SNSRecord` | diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index 04f6e5279f..c44df16f1e 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Amazon.Lambda.APIGatewayEvents; +using Amazon.Lambda.ApplicationLoadBalancerEvents; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Trace; using Xunit; @@ -49,6 +50,174 @@ public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() AssertTags(expectedTags, actualTags); } + [Fact] + public void GetHttpTags_ApplicationLoadBalancerRequest_ReturnsCorrectTags() + { + var request = new ApplicationLoadBalancerRequest + { + Headers = new Dictionary + { + { "X-Forwarded-Proto", "https" }, + { "Host", "localhost:1234" }, + }, + QueryStringParameters = new Dictionary + { + { "q1", "value1" }, + }, + HttpMethod = "GET", + Path = "/path/test", + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.scheme", "https" }, + { "http.target", "/path/test?q1=value1" }, + { "net.host.name", "localhost" }, + { "net.host.port", 1234 }, + { "http.method", "GET" }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void GetHttpTags_ApplicationLoadBalancerRequestWithMultiValue_ReturnsCorrectTags() + { + var request = new ApplicationLoadBalancerRequest + { + MultiValueHeaders = new Dictionary> + { + { "X-Forwarded-Proto", new List { "https" } }, + { "Host", new List { "localhost:1234" } }, + }, + MultiValueQueryStringParameters = new Dictionary> + { +#pragma warning disable CA1861 // Avoid constant arrays as arguments + { "q1", new[] { "value1" } }, +#pragma warning restore CA1861 // Avoid constant arrays as arguments + }, + HttpMethod = "GET", + Path = "/path/test", + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.scheme", "https" }, + { "http.target", "/path/test?q1=value1" }, + { "net.host.name", "localhost" }, + { "net.host.port", 1234 }, + { "http.method", "GET" }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void GetHttpTags_ApplicationLoadBalancerRequestWithMultiValueHeader_UsesLastValue() + { + var request = new ApplicationLoadBalancerRequest + { + MultiValueHeaders = new Dictionary> + { + { "X-Forwarded-Proto", new List { "https", "http" } }, + { "Host", new List { "localhost:1234", "myhost:432" } }, + }, + }; + + var actualTags = AWSLambdaHttpUtils.GetHttpTags(request); + + var expectedTags = new Dictionary + { + { "http.target", string.Empty }, + { "http.scheme", "http" }, + { "net.host.name", "myhost" }, + { "net.host.port", 432 }, + }; + + AssertTags(expectedTags, actualTags); + } + + [Fact] + public void SetHttpTagsFromResult_ApplicationLoadBalancerResponse_SetsCorrectTags() + { + var response = new ApplicationLoadBalancerResponse + { + StatusCode = 200, + }; + + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .AddSource("TestActivitySource") + .Build(); + + using var testActivitySource = new ActivitySource("TestActivitySource"); + using var activity = testActivitySource.StartActivity("TestActivity"); + + AWSLambdaHttpUtils.SetHttpTagsFromResult(activity, response); + + var expectedTags = new Dictionary + { + { "http.status_code", 200 }, + }; + + var actualTags = activity?.TagObjects + .Select(kvp => new KeyValuePair(kvp.Key, kvp.Value ?? new object())); + + AssertTags(expectedTags, actualTags); + } + + [Theory] + [InlineData(null, "")] +#pragma warning disable CA1861 // Avoid constant arrays as arguments + [InlineData("", "?name=")] + [InlineData("value1", "?name=value1")] + [InlineData("value$a", "?name=value%24a")] + [InlineData("value 1", "?name=value+1")] +#pragma warning restore CA1861 // Avoid constant arrays as arguments + public void GetQueryString_ApplicationLoadBalancerRequest_CorrectQueryString(string? value, string expectedQueryString) + { + var request = new ApplicationLoadBalancerRequest(); + if (value != null) + { + request.QueryStringParameters = new Dictionary + { + { "name", value }, + }; + } + + var queryString = AWSLambdaHttpUtils.GetQueryString(request); + + Assert.Equal(expectedQueryString, queryString); + } + + [Theory] + [InlineData(null, "")] +#pragma warning disable CA1861 // Avoid constant arrays as arguments + [InlineData(new string[] { }, "")] + [InlineData(new[] { "value1" }, "?name=value1")] + [InlineData(new[] { "value$a" }, "?name=value%24a")] + [InlineData(new[] { "value 1" }, "?name=value+1")] + [InlineData(new[] { "value1", "value2" }, "?name=value1&name=value2")] +#pragma warning restore CA1861 // Avoid constant arrays as arguments + public void GetQueryString_ApplicationLoadBalancerRequestMultiValue_CorrectQueryString(IList? values, string expectedQueryString) + { + var request = new ApplicationLoadBalancerRequest(); + if (values != null) + { + request.MultiValueQueryStringParameters = new Dictionary> + { + { "name", values }, + }; + } + + var queryString = AWSLambdaHttpUtils.GetQueryString(request); + + Assert.Equal(expectedQueryString, queryString); + } + [Fact] public void GetHttpTags_APIGatewayProxyRequestWithEmptyContext_ReturnsTagsFromRequest() { From 029077dcdf14a5e300c8b82b4932b23b96331c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 6 Sep 2024 20:43:12 +0200 Subject: [PATCH 1223/1499] [repo] Remove .NET 7 target (#2038) Co-authored-by: Mikel Blanchard --- .github/workflows/Component.BuildTest.yml | 3 +- .../ci-Exporter.OneCollector-Integration.yml | 2 +- .github/workflows/ci.yml | 6 +- .github/workflows/integration.yml | 4 +- CONTRIBUTING.md | 2 +- build/Common.nonprod.props | 2 +- build/docker-compose.net7.0.yml | 9 - .../Examples.InfluxDB.csproj | 2 +- .../Examples.Wcf.Client.DotNet.csproj | 2 +- opentelemetry-dotnet-contrib.sln | 1 - .../Metrics/GenevaMetricExporter.cs | 2 +- .../CHANGELOG.md | 6 +- .../CompatibilitySuppressions.xml | 12 + .../Internal/CallbackManager.cs | 2 +- .../Serialization/BatchSerializationResult.cs | 2 +- .../CommonSchemaJsonSerializationHelper.cs | 4 +- .../Transports/TransportSendRequest.cs | 4 +- ...OneCollectorExporterValidationException.cs | 4 + ...OpenTelemetry.Exporter.OneCollector.csproj | 4 +- ...OpenTelemetry.Extensions.Enrichment.csproj | 2 +- src/OpenTelemetry.Extensions/CHANGELOG.md | 3 + ...elemetry.Instrumentation.AspNetCore.csproj | 2 +- ...enTelemetry.Exporter.InfluxDB.Tests.csproj | 2 +- ...ry.Exporter.OneCollector.Benchmarks.csproj | 4 +- ...ommonSchemaJsonSerializationHelperTests.cs | 2 +- ...lemetry.Exporter.OneCollector.Tests.csproj | 2 +- .../BasicTests.cs | 4 +- ...ry.Instrumentation.AspNetCore.Tests.csproj | 7 +- .../RouteTests/README.md | 1 - .../RouteTests/README.net7.0.md | 654 ------------------ .../TestApplication/TestApplicationFactory.cs | 2 +- .../Dockerfile | 6 +- ...mentation.EntityFrameworkCore.Tests.csproj | 4 - ...Instrumentation.GrpcNetClient.Tests.csproj | 2 +- ...elemetry.Instrumentation.Http.Tests.csproj | 2 +- ...try.Instrumentation.SqlClient.Tests.csproj | 2 +- .../TestApp.AspNetCore.csproj | 2 +- 37 files changed, 62 insertions(+), 714 deletions(-) delete mode 100644 build/docker-compose.net7.0.yml create mode 100644 src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml delete mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 71c537cfd0..b4b916c293 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -18,7 +18,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 @@ -78,7 +78,6 @@ jobs: with: dotnet-version: | 6.0.x - 7.0.x 8.0.x - name: dotnet restore ${{ steps.resolve-project.outputs.title }} diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index 25ffa9b3ee..4f1a2dd9d2 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net7.0, net8.0 ] + version: [ net462, net6.0, net8.0 ] exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c547f0e902..1953b3bf47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,7 +196,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.AspNetCore code-cov-name: Instrumentation.AspNetCore - tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' + tfm-list: '[ "net6.0", "net8.0" ]' build-test-instrumentation-aws: needs: detect-changes @@ -219,7 +219,7 @@ jobs: with: project-name: Component[OpenTelemetry.Instrumentation.AWSLambda] code-cov-name: Instrumentation.AWSLambda - tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' + tfm-list: '[ "net6.0", "net8.0" ]' build-test-instrumentation-cassandra: needs: detect-changes @@ -285,7 +285,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.EventCounters code-cov-name: Instrumentation.EventCounters - tfm-list: '[ "net6.0", "net7.0", "net8.0" ]' + tfm-list: '[ "net6.0", "net8.0" ]' build-test-instrumentation-grpccore: needs: detect-changes diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3a11ddde2e..53c25d07fd 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - version: [net6.0, net7.0, net8.0] + version: [net6.0, net8.0] steps: - uses: actions/checkout@v4 @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - version: [net6.0, net7.0, net8.0] + version: [net6.0, net8.0] steps: - uses: actions/checkout@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b21e75363..f3a7eee404 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,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 7.0+ +* .NET 8.0+ Please note that individual project requirements might vary. diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index b7cf1a447f..0c8d95fde2 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -25,7 +25,7 @@ [17.11.0,18.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) - net8.0;net7.0;net6.0 + net8.0;net6.0 [2.8.2,3.0) [2.9.0,3.0) [1.6.1,2.0) diff --git a/build/docker-compose.net7.0.yml b/build/docker-compose.net7.0.yml deleted file mode 100644 index 48a2589cda..0000000000 --- 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" diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj index b4a514d60e..c39d5ecdbe 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 Examples.InfluxDB diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index 1da3e3ade7..f87ebac82a 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e86c0bd8ee..635826b25b 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -54,7 +54,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk 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\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index b596e592ab..3b66acdf56 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -109,7 +109,7 @@ internal static void DisableOpenTelemetrySdkMetricNameValidation() GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, GetDisableRegexPattern()); } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER [GeneratedRegex(DisableRegexPattern)] private static partial Regex GetDisableRegexPattern(); #else diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index ec1167039a..72360c5e85 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Dropped support for the `net7.0` target because .NET 7 is no longer supported. + Added a `net8.0` target. + ([#2038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/2038)) + ## 1.9.2 Released 2024-Aug-12 @@ -65,7 +69,7 @@ Released 2023-Sep-20 * Update OpenTelemetry to 1.6.0 ([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344)) -* Added support for receiving tranmission failures via the +* Added support for receiving transmission failures via the `RegisterPayloadTransmittedCallback` API. ([#1309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1309)) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml b/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml new file mode 100644 index 0000000000..c1b34f2891 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml @@ -0,0 +1,12 @@ + + + + + CP0008 + T:OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType + lib/net7.0/OpenTelemetry.Exporter.OneCollector.dll + lib/net6.0/OpenTelemetry.Exporter.OneCollector.dll + true + + diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs index dd342b779f..513bcf83d5 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs @@ -20,7 +20,7 @@ public IDisposable Add(T callback) lock (this.lockObject) { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER ObjectDisposedException.ThrowIf(this.disposed, nameof(CallbackManager)); #else if (this.disposed) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs index ed12e24f54..c3cc86222f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.OneCollector; internal readonly struct BatchSerializationResult { -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER public required int NumberOfItemsSerialized { get; init; } public required int NumberOfItemsDropped { get; init; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index ca30a223ba..db94e2d1fd 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -101,7 +101,7 @@ public static void SerializeValueToJson(object? value, Utf8JsonWriter writer) writer.WriteStringValue(v); return; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER case DateOnly v: JsonMetadataServices.DateOnlyConverter.Write(writer, v, null!); return; @@ -111,7 +111,7 @@ public static void SerializeValueToJson(object? value, Utf8JsonWriter writer) JsonMetadataServices.TimeSpanConverter.Write(writer, v, null!); return; -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER case TimeOnly v: JsonMetadataServices.TimeOnlyConverter.Write(writer, v, null!); return; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs index 1656f21f6b..2c71d15b6d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs @@ -13,14 +13,14 @@ internal readonly struct TransportSendRequest { public TransportSendRequest() { -#if !NET7_0_OR_GREATER +#if !NET8_0_OR_GREATER // Note: This is needed because < NET7 doesn't understand required. this.ItemType = string.Empty; this.ItemStream = default!; #endif } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER public required string ItemType { get; init; } public required OneCollectorExporterSerializationFormatType ItemSerializationFormat { get; init; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs index 5e86e02cd5..c6aea54de2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs @@ -1,7 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if !NET8_0_OR_GREATER using System.Runtime.Serialization; +#endif namespace OpenTelemetry.Exporter.OneCollector; @@ -41,8 +43,10 @@ public OneCollectorExporterValidationException(string message, Exception? innerE { } +#if !NET8_0_OR_GREATER private OneCollectorExporterValidationException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { } +#endif } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 54507931dc..3b3c96d5e3 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -4,7 +4,7 @@ true An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector OpenTelemetry Authors - net7.0;net6.0;netstandard2.1;netstandard2.0 + net8.0;net6.0;netstandard2.1;netstandard2.0 $(TargetFrameworks);net462 Exporter.OneCollector- true @@ -24,7 +24,7 @@ - + diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index c92c7ad934..9ed6c4e87b 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -2,7 +2,7 @@ - net7.0;net6.0;$(NetStandardMinimumSupportedVersion) + net8.0;net6.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry .NET SDK telemetry enrichment. $(NoWarn),CS1591 diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index 508ec3a4ce..fa8a23a1dc 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Dropped support for the `net7.0` target because .NET 7 is no longer supported. + ([#2038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/2038)) + * Update BaggageActivityProcessor to require baggage key predicate. ([#1816](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1816)) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index 301ce36d81..a95693ee5a 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -1,7 +1,7 @@ - net8.0;net7.0;net6.0;netstandard2.0 + net8.0;net6.0;netstandard2.0 ASP.NET Core instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNetCore Instrumentation.AspNetCore- diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index fb3469a04b..155dd334f7 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index 953bd766ea..04afec7346 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -4,13 +4,13 @@ Exe Benchmark project for OpenTelemetry .NET OneCollectorExporter. - net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 - + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs index da78729fad..d23addc8d5 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -101,7 +101,7 @@ public void SerializeComplexValueToJsonTest() this.SerializeValueToJsonTest(typeWithISpanFormattableOverflow, "\"Overflow\""); #endif -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER var dateOnly = DateOnly.FromDateTime(dt); this.SerializeValueToJsonTest(dateOnly, $"\"{dateOnly:O}\""); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 16a46f7998..54c7e19491 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 03cc160050..070a56bd84 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -738,7 +738,7 @@ public async Task ActivitiesStartedInMiddlewareBySettingHostActivityToNullShould Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", aspnetcoreframeworkactivity.OperationName); } -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER [Fact] public async Task UserRegisteredActivitySourceIsUsedForActivityCreationByAspNetCore() { @@ -1150,7 +1150,7 @@ private static void WaitForActivityExport(List exportedItems, int coun private static void ValidateAspNetCoreActivity(Activity activityToValidate, string expectedHttpPath) { Assert.Equal(ActivityKind.Server, activityToValidate.Kind); -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER Assert.Equal(HttpInListener.AspNetCoreActivitySourceName, activityToValidate.Source.Name); Assert.NotNull(activityToValidate.Source.Version); Assert.Empty(activityToValidate.Source.Version); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 9a8eebc05e..004daa67a8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -1,7 +1,7 @@ Unit test project for OpenTelemetry ASP.NET Core instrumentation - net8.0;net7.0;net6.0 + $(SupportedNetTargets) @@ -9,11 +9,6 @@ - - - - - diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md index 38ae9f93fd..12ec54af8a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.md @@ -22,7 +22,6 @@ each test case. These files are source-controlled, so if the behavior of the instrumentation changes, the README files will be updated to reflect the change. * [.NET 6](./README.net6.0.md) -* [.NET 7](./README.net7.0.md) * [.NET 8](./README.net8.0.md) For each test case a request is made to an ASP.NET Core application with a diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md deleted file mode 100644 index 49d8224155..0000000000 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net7.0.md +++ /dev/null @@ -1,654 +0,0 @@ -# Test results for ASP.NET Core 7 - -| http.route | App | Test Name | -| - | - | - | -| :broken_heart: | ConventionalRouting | [Root path](#conventionalrouting-root-path) | -| :broken_heart: | ConventionalRouting | [Non-default action with route parameter and query string](#conventionalrouting-non-default-action-with-route-parameter-and-query-string) | -| :broken_heart: | ConventionalRouting | [Non-default action with query string](#conventionalrouting-non-default-action-with-query-string) | -| :green_heart: | ConventionalRouting | [Not Found (404)](#conventionalrouting-not-found-404) | -| :green_heart: | ConventionalRouting | [Route template with parameter constraint](#conventionalrouting-route-template-with-parameter-constraint) | -| :green_heart: | ConventionalRouting | [Path that does not match parameter constraint](#conventionalrouting-path-that-does-not-match-parameter-constraint) | -| :broken_heart: | ConventionalRouting | [Area using `area:exists`, default controller/action](#conventionalrouting-area-using-areaexists-default-controlleraction) | -| :broken_heart: | ConventionalRouting | [Area using `area:exists`, non-default action](#conventionalrouting-area-using-areaexists-non-default-action) | -| :broken_heart: | ConventionalRouting | [Area w/o `area:exists`, default controller/action](#conventionalrouting-area-wo-areaexists-default-controlleraction) | -| :green_heart: | AttributeRouting | [Default action](#attributerouting-default-action) | -| :green_heart: | AttributeRouting | [Action without parameter](#attributerouting-action-without-parameter) | -| :green_heart: | AttributeRouting | [Action with parameter](#attributerouting-action-with-parameter) | -| :green_heart: | AttributeRouting | [Action with parameter before action name in template](#attributerouting-action-with-parameter-before-action-name-in-template) | -| :green_heart: | AttributeRouting | [Action invoked resulting in 400 Bad Request](#attributerouting-action-invoked-resulting-in-400-bad-request) | -| :broken_heart: | RazorPages | [Root path](#razorpages-root-path) | -| :broken_heart: | RazorPages | [Index page](#razorpages-index-page) | -| :broken_heart: | RazorPages | [Throws exception](#razorpages-throws-exception) | -| :green_heart: | RazorPages | [Static content](#razorpages-static-content) | -| :green_heart: | MinimalApi | [Action without parameter](#minimalapi-action-without-parameter) | -| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) | -| :green_heart: | MinimalApi | [Action without parameter (MapGroup)](#minimalapi-action-without-parameter-mapgroup) | -| :green_heart: | MinimalApi | [Action with parameter (MapGroup)](#minimalapi-action-with-parameter-mapgroup) | -| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) | - -## ConventionalRouting: Root path - -```json -{ - "IdealHttpRoute": "ConventionalRoute/Default/{id?}", - "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", - "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/", - "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "controller": "ConventionalRoute", - "action": "Default" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [], - "ControllerActionDescriptor": { - "ControllerName": "ConventionalRoute", - "ActionName": "Default" - }, - "PageActionDescriptor": null - } - } -} -``` - -## ConventionalRouting: Non-default action with route parameter and query string - -```json -{ - "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", - "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", - "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", - "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "controller": "ConventionalRoute", - "action": "ActionWithStringParameter", - "id": "2" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [ - "id", - "num" - ], - "ControllerActionDescriptor": { - "ControllerName": "ConventionalRoute", - "ActionName": "ActionWithStringParameter" - }, - "PageActionDescriptor": null - } - } -} -``` - -## ConventionalRouting: Non-default action with query string - -```json -{ - "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", - "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", - "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/ConventionalRoute/ActionWithStringParameter?num=3", - "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "controller": "ConventionalRoute", - "action": "ActionWithStringParameter" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [ - "id", - "num" - ], - "ControllerActionDescriptor": { - "ControllerName": "ConventionalRoute", - "ActionName": "ActionWithStringParameter" - }, - "PageActionDescriptor": null - } - } -} -``` - -## ConventionalRouting: Not Found (404) - -```json -{ - "IdealHttpRoute": "", - "ActivityDisplayName": "GET", - "ActivityHttpRoute": "", - "MetricHttpRoute": "", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/ConventionalRoute/NotFound", - "RoutePattern.RawText": null, - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": {}, - "ActionDescriptor": null - } -} -``` - -## ConventionalRouting: Route template with parameter constraint - -```json -{ - "IdealHttpRoute": "SomePath/{id}/{num:int}", - "ActivityDisplayName": "GET SomePath/{id}/{num:int}", - "ActivityHttpRoute": "SomePath/{id}/{num:int}", - "MetricHttpRoute": "SomePath/{id}/{num:int}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/SomePath/SomeString/2", - "RoutePattern.RawText": "SomePath/{id}/{num:int}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "controller": "ConventionalRoute", - "action": "ActionWithStringParameter", - "id": "SomeString", - "num": "2" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [ - "id", - "num" - ], - "ControllerActionDescriptor": { - "ControllerName": "ConventionalRoute", - "ActionName": "ActionWithStringParameter" - }, - "PageActionDescriptor": null - } - } -} -``` - -## ConventionalRouting: Path that does not match parameter constraint - -```json -{ - "IdealHttpRoute": "", - "ActivityDisplayName": "GET", - "ActivityHttpRoute": "", - "MetricHttpRoute": "", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/SomePath/SomeString/NotAnInt", - "RoutePattern.RawText": null, - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": {}, - "ActionDescriptor": null - } -} -``` - -## ConventionalRouting: Area using `area:exists`, default controller/action - -```json -{ - "IdealHttpRoute": "{area:exists}/ControllerForMyArea/Default/{id?}", - "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/MyArea", - "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "controller": "ControllerForMyArea", - "action": "Default", - "area": "MyArea" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [], - "ControllerActionDescriptor": { - "ControllerName": "ControllerForMyArea", - "ActionName": "Default" - }, - "PageActionDescriptor": null - } - } -} -``` - -## ConventionalRouting: Area using `area:exists`, non-default action - -```json -{ - "IdealHttpRoute": "{area:exists}/ControllerForMyArea/NonDefault/{id?}", - "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/MyArea/ControllerForMyArea/NonDefault", - "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "controller": "ControllerForMyArea", - "area": "MyArea", - "action": "NonDefault" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [], - "ControllerActionDescriptor": { - "ControllerName": "ControllerForMyArea", - "ActionName": "NonDefault" - }, - "PageActionDescriptor": null - } - } -} -``` - -## ConventionalRouting: Area w/o `area:exists`, default controller/action - -```json -{ - "IdealHttpRoute": "SomePrefix/AnotherArea/Index/{id?}", - "ActivityDisplayName": "GET SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", - "ActivityHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", - "MetricHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/SomePrefix", - "RoutePattern.RawText": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "area": "AnotherArea", - "controller": "AnotherArea", - "action": "Index" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": null, - "Parameters": [], - "ControllerActionDescriptor": { - "ControllerName": "AnotherArea", - "ActionName": "Index" - }, - "PageActionDescriptor": null - } - } -} -``` - -## AttributeRouting: Default action - -```json -{ - "IdealHttpRoute": "AttributeRoute", - "ActivityDisplayName": "GET AttributeRoute", - "ActivityHttpRoute": "AttributeRoute", - "MetricHttpRoute": "AttributeRoute", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/AttributeRoute", - "RoutePattern.RawText": "AttributeRoute", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "action": "Get", - "controller": "AttributeRoute" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "AttributeRoute", - "Parameters": [], - "ControllerActionDescriptor": { - "ControllerName": "AttributeRoute", - "ActionName": "Get" - }, - "PageActionDescriptor": null - } - } -} -``` - -## AttributeRouting: Action without parameter - -```json -{ - "IdealHttpRoute": "AttributeRoute/Get", - "ActivityDisplayName": "GET AttributeRoute/Get", - "ActivityHttpRoute": "AttributeRoute/Get", - "MetricHttpRoute": "AttributeRoute/Get", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/AttributeRoute/Get", - "RoutePattern.RawText": "AttributeRoute/Get", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "action": "Get", - "controller": "AttributeRoute" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "AttributeRoute/Get", - "Parameters": [], - "ControllerActionDescriptor": { - "ControllerName": "AttributeRoute", - "ActionName": "Get" - }, - "PageActionDescriptor": null - } - } -} -``` - -## AttributeRouting: Action with parameter - -```json -{ - "IdealHttpRoute": "AttributeRoute/Get/{id}", - "ActivityDisplayName": "GET AttributeRoute/Get/{id}", - "ActivityHttpRoute": "AttributeRoute/Get/{id}", - "MetricHttpRoute": "AttributeRoute/Get/{id}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/AttributeRoute/Get/12", - "RoutePattern.RawText": "AttributeRoute/Get/{id}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "action": "Get", - "controller": "AttributeRoute", - "id": "12" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "AttributeRoute/Get/{id}", - "Parameters": [ - "id" - ], - "ControllerActionDescriptor": { - "ControllerName": "AttributeRoute", - "ActionName": "Get" - }, - "PageActionDescriptor": null - } - } -} -``` - -## AttributeRouting: Action with parameter before action name in template - -```json -{ - "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/AttributeRoute/12/GetWithActionNameInDifferentSpotInTemplate", - "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "action": "GetWithActionNameInDifferentSpotInTemplate", - "controller": "AttributeRoute", - "id": "12" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "Parameters": [ - "id" - ], - "ControllerActionDescriptor": { - "ControllerName": "AttributeRoute", - "ActionName": "GetWithActionNameInDifferentSpotInTemplate" - }, - "PageActionDescriptor": null - } - } -} -``` - -## AttributeRouting: Action invoked resulting in 400 Bad Request - -```json -{ - "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/AttributeRoute/NotAnInt/GetWithActionNameInDifferentSpotInTemplate", - "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "action": "GetWithActionNameInDifferentSpotInTemplate", - "controller": "AttributeRoute", - "id": "NotAnInt" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", - "Parameters": [ - "id" - ], - "ControllerActionDescriptor": { - "ControllerName": "AttributeRoute", - "ActionName": "GetWithActionNameInDifferentSpotInTemplate" - }, - "PageActionDescriptor": null - } - } -} -``` - -## RazorPages: Root path - -```json -{ - "IdealHttpRoute": "/Index", - "ActivityDisplayName": "GET", - "ActivityHttpRoute": "", - "MetricHttpRoute": "", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/", - "RoutePattern.RawText": "", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "page": "/Index" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "", - "Parameters": [], - "ControllerActionDescriptor": null, - "PageActionDescriptor": { - "RelativePath": "/Pages/Index.cshtml", - "ViewEnginePath": "/Index" - } - } - } -} -``` - -## RazorPages: Index page - -```json -{ - "IdealHttpRoute": "/Index", - "ActivityDisplayName": "GET Index", - "ActivityHttpRoute": "Index", - "MetricHttpRoute": "Index", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/Index", - "RoutePattern.RawText": "Index", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "page": "/Index" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "Index", - "Parameters": [], - "ControllerActionDescriptor": null, - "PageActionDescriptor": { - "RelativePath": "/Pages/Index.cshtml", - "ViewEnginePath": "/Index" - } - } - } -} -``` - -## RazorPages: Throws exception - -```json -{ - "IdealHttpRoute": "/PageThatThrowsException", - "ActivityDisplayName": "GET PageThatThrowsException", - "ActivityHttpRoute": "PageThatThrowsException", - "MetricHttpRoute": "PageThatThrowsException", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/PageThatThrowsException", - "RoutePattern.RawText": "PageThatThrowsException", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "page": "/PageThatThrowsException" - }, - "ActionDescriptor": { - "AttributeRouteInfo.Template": "PageThatThrowsException", - "Parameters": [], - "ControllerActionDescriptor": null, - "PageActionDescriptor": { - "RelativePath": "/Pages/PageThatThrowsException.cshtml", - "ViewEnginePath": "/PageThatThrowsException" - } - } - } -} -``` - -## RazorPages: Static content - -```json -{ - "IdealHttpRoute": "", - "ActivityDisplayName": "GET", - "ActivityHttpRoute": "", - "MetricHttpRoute": "", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/js/site.js", - "RoutePattern.RawText": null, - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": {}, - "ActionDescriptor": null - } -} -``` - -## MinimalApi: Action without parameter - -```json -{ - "IdealHttpRoute": "/MinimalApi", - "ActivityDisplayName": "GET /MinimalApi", - "ActivityHttpRoute": "/MinimalApi", - "MetricHttpRoute": "/MinimalApi", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/MinimalApi", - "RoutePattern.RawText": "/MinimalApi", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": {}, - "ActionDescriptor": null - } -} -``` - -## MinimalApi: Action with parameter - -```json -{ - "IdealHttpRoute": "/MinimalApi/{id}", - "ActivityDisplayName": "GET /MinimalApi/{id}", - "ActivityHttpRoute": "/MinimalApi/{id}", - "MetricHttpRoute": "/MinimalApi/{id}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/MinimalApi/123", - "RoutePattern.RawText": "/MinimalApi/{id}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "id": "123" - }, - "ActionDescriptor": null - } -} -``` - -## MinimalApi: Action without parameter (MapGroup) - -```json -{ - "IdealHttpRoute": "/MinimalApiUsingMapGroup/", - "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/", - "ActivityHttpRoute": "/MinimalApiUsingMapGroup/", - "MetricHttpRoute": "/MinimalApiUsingMapGroup/", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/MinimalApiUsingMapGroup", - "RoutePattern.RawText": "/MinimalApiUsingMapGroup/", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": {}, - "ActionDescriptor": null - } -} -``` - -## MinimalApi: Action with parameter (MapGroup) - -```json -{ - "IdealHttpRoute": "/MinimalApiUsingMapGroup/{id}", - "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/{id}", - "ActivityHttpRoute": "/MinimalApiUsingMapGroup/{id}", - "MetricHttpRoute": "/MinimalApiUsingMapGroup/{id}", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/MinimalApiUsingMapGroup/123", - "RoutePattern.RawText": "/MinimalApiUsingMapGroup/{id}", - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": { - "id": "123" - }, - "ActionDescriptor": null - } -} -``` - -## ExceptionMiddleware: Exception Handled by Exception Handler Middleware - -```json -{ - "IdealHttpRoute": "/Exception", - "ActivityDisplayName": "GET /Exception", - "ActivityHttpRoute": "/Exception", - "MetricHttpRoute": "/Exception", - "RouteInfo": { - "HttpMethod": "GET", - "Path": "/Exception", - "RoutePattern.RawText": null, - "IRouteDiagnosticsMetadata.Route": null, - "HttpContext.GetRouteData()": {}, - "ActionDescriptor": null - } -} -``` diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs index b030ab7f42..51cd4ef643 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs @@ -131,7 +131,7 @@ private static WebApplication CreateMinimalApiApplication() app.MapGet("/MinimalApi", () => Results.Ok()); app.MapGet("/MinimalApi/{id}", (int id) => Results.Ok()); -#if NET7_0_OR_GREATER +#if NET8_0_OR_GREATER var api = app.MapGroup("/MinimalApiUsingMapGroup"); api.MapGet("/", () => Results.Ok()); api.MapGet("/{id}", (int id) => Results.Ok()); diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile index 3f06615552..206fa6b334 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile @@ -2,12 +2,12 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile . -ARG BUILD_SDK_VERSION=7.0 -ARG TEST_SDK_VERSION=7.0 +ARG BUILD_SDK_VERSION=8.0 +ARG TEST_SDK_VERSION=8.0 FROM mcr.microsoft.com/dotnet/sdk:${BUILD_SDK_VERSION} AS build ARG PUBLISH_CONFIGURATION=Release -ARG PUBLISH_FRAMEWORK=net7.0 +ARG PUBLISH_FRAMEWORK=net8.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.Cassandra.Tests" diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 0eea99c2ce..a33effea74 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -9,10 +9,6 @@ - - - - diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index 2ce1d55199..79ca9d1a02 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -1,7 +1,7 @@ Unit test project for OpenTelemetry Grpc for .NET instrumentation - net8.0;net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) $(NoWarn),CS8981 diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 3a3170cba1..8811a92001 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -1,7 +1,7 @@ Unit test project for OpenTelemetry HTTP instrumentations - net8.0;net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 776634117a..2d871bb3ef 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -1,7 +1,7 @@ Unit test project for OpenTelemetry SqlClient instrumentations - net8.0;net7.0;net6.0 + $(SupportedNetTargets) $(TargetFrameworks);net462 diff --git a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj index 24e5a6ee1a..ae0043309a 100644 --- a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj +++ b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj @@ -1,7 +1,7 @@ - net8.0;net7.0;net6.0 + $(SupportedNetTargets) From 039f495a3191570a6d838fa10c361d78335be82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fl=C3=A1vio=20Coutinho=20da=20Costa?= Date: Fri, 6 Sep 2024 16:06:31 -0500 Subject: [PATCH 1224/1499] [OneCollector] Introduce EventFullNameMappings on options (#2021) Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Unshipped.txt | 6 + .../CHANGELOG.md | 7 + .../Internal/EventFullName.cs | 90 +++++++++ .../Internal/EventNameManager.cs | 179 ++++++++++++++---- .../LogRecordCommonSchemaJsonSerializer.cs | 29 ++- .../OneCollectorLogExportProcessorBuilder.cs | 50 ++++- .../Logs/OneCollectorLogExporterOptions.cs | 158 ++++++++++++++-- .../README.md | 129 +++++++++++++ ...ecordCommonSchemaJsonHttpPostBenchmarks.cs | 5 +- .../EventNameManagerTests.cs | 128 +++++++++++-- ...ogRecordCommonSchemaJsonSerializerTests.cs | 36 +++- .../OneCollectorLogExporterOptionsTests.cs | 148 +++++++++++++++ ...torLoggerProviderBuilderExtensionsTests.cs | 41 ++++ 13 files changed, 925 insertions(+), 81 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs create mode 100644 test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt index e69de29bb2..01debf0cc7 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventNamespace.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventNamespace.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.EventFullNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary? +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.EventFullNameMappings.set -> void +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventNamespace(string! defaultEventNamespace) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetEventFullNameMappings(System.Collections.Generic.IReadOnlyDictionary? eventFullNameMappings) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 72360c5e85..4f3f8dd417 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -6,6 +6,13 @@ Added a `net8.0` target. ([#2038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/2038)) +* Added `SetEventFullNameMappings` API on + `OneCollectorLogExportProcessorBuilder` which can be used to change the event + full name sent to the OneCollector service for a given `LogRecord` + (`CategoryName` and `EventId.Name` are used to derive the event full name by + default). + ([#2021](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2021)) + ## 1.9.2 Released 2024-Aug-12 diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs new file mode 100644 index 0000000000..16331d45f4 --- /dev/null +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET || NETSTANDARD2_1_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + +namespace OpenTelemetry.Exporter.OneCollector; + +internal sealed class EventFullName +{ + private EventFullName( + string eventNamespace, + string eventName) + { + this.EventNamespace = eventNamespace; + this.EventName = eventName; + } + + public string EventNamespace { get; } + + public string EventName { get; } + + public static EventFullName Create(string eventName) + { + return new(eventNamespace: string.Empty, eventName: eventName); + } + + public static bool TryParseFromMapping( + string? eventFullNameMapping, +#if NET || NETSTANDARD2_1_OR_GREATER + [NotNullWhen(true)] +#endif + out EventFullName? eventFullName) + { + if (string.IsNullOrWhiteSpace(eventFullNameMapping)) + { + eventFullName = null; + return false; + } + + var parts = eventFullNameMapping!.Split('.'); + if (parts.Length > 1) + { + eventFullName = new( + string.Join(".", parts, 0, parts.Length - 1), + parts[parts.Length - 1]); + } + else + { + eventFullName = new(string.Empty, parts[0]); + } + + return true; + } + + internal void Validate(string key) + { + if (this.EventNamespace?.Length != 0 + && (this.EventNamespace == null + || !EventNameManager.IsEventNamespaceValid(this.EventNamespace!))) + { + throw new OneCollectorExporterValidationException($"The event full name mapping namespace value provided for key '{key}' was null or invalid."); + } + + if (this.EventName != "*" + && (string.IsNullOrWhiteSpace(this.EventName) + || !EventNameManager.IsEventNameValid(this.EventName!))) + { + throw new OneCollectorExporterValidationException($"The event full name mapping name value provided for key '{key}' was null or invalid."); + } + + if (this.EventName != "*") + { + var length = this.EventNamespace.Length; + if (length > 0) + { + length++; + } + + length += this.EventName.Length; + + if (length < EventNameManager.MinimumEventFullNameLength + || length > EventNameManager.MaximumEventFullNameLength) + { + throw new OneCollectorExporterValidationException($"The event full name mapping value provided for key '{key}' is shorter or longer than what is allowed."); + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs index 25ee9a0701..90a44634b2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs @@ -9,44 +9,37 @@ namespace OpenTelemetry.Exporter.OneCollector; internal sealed class EventNameManager { - private const int MinimumEventFullNameLength = 4; - private const int MaximumEventFullNameLength = 100; + // Note: OneCollector will silently drop events which have a name less than 4 characters. + internal const int MinimumEventFullNameLength = 4; + internal const int MaximumEventFullNameLength = 100; private static readonly Regex EventNamespaceValidationRegex = new(@"^[A-Za-z](?:\.?[A-Za-z0-9]+?)*$", RegexOptions.Compiled); private static readonly Regex EventNameValidationRegex = new(@"^[A-Za-z][A-Za-z0-9]*$", RegexOptions.Compiled); private readonly string defaultEventNamespace; private readonly string defaultEventName; - private readonly byte[] defaultEventFullName; + private readonly IReadOnlyDictionary? eventFullNameMappings; + private readonly ResolvedEventFullName defaultEventFullName; private readonly Hashtable eventNamespaceCache = new(StringComparer.OrdinalIgnoreCase); - public EventNameManager(string defaultEventNamespace, string defaultEventName) + public EventNameManager( + string defaultEventNamespace, + string defaultEventName, + IReadOnlyDictionary? eventFullNameMappings = null) { Debug.Assert(defaultEventNamespace != null, "defaultEventNamespace was null"); Debug.Assert(defaultEventName != null, "defaultEventName was null"); this.defaultEventNamespace = defaultEventNamespace!; this.defaultEventName = defaultEventName!; + this.eventFullNameMappings = eventFullNameMappings; - if (!IsEventNamespaceValid(defaultEventNamespace!)) - { - throw new ArgumentException($"Default event namespace '{defaultEventNamespace}' was invalid.", nameof(defaultEventNamespace)); - } - - if (!IsEventNamespaceValid(defaultEventName!)) - { - throw new ArgumentException($"Default event name '{defaultEventName}' was invalid.", nameof(defaultEventName)); - } - - var defaultEventFullNameLength = defaultEventNamespace!.Length + defaultEventName!.Length + 1; - if (defaultEventFullNameLength < MinimumEventFullNameLength || defaultEventFullNameLength > MaximumEventFullNameLength) - { - throw new ArgumentException($"Default event full name '{defaultEventNamespace}.{defaultEventName}' does not meet length requirements.", nameof(defaultEventName)); - } - - this.defaultEventFullName = BuildEventFullName(defaultEventNamespace, defaultEventName)!; + this.defaultEventFullName = new( + eventFullName: BuildEventFullName(this.defaultEventNamespace, this.defaultEventName), + originalEventNamespace: null, + originalEventName: null); #if NET - Debug.Assert(this.defaultEventFullName != null, "this.defaultFullyQualifiedEventName was null"); + Debug.Assert(this.defaultEventFullName.EventFullName != null, "this.defaultFullyQualifiedEventName was null"); #endif } @@ -59,10 +52,12 @@ public static bool IsEventNamespaceValid(string eventNamespace) public static bool IsEventNameValid(string eventName) => EventNameValidationRegex.IsMatch(eventName); - public ReadOnlySpan ResolveEventFullName( + public ResolvedEventFullName ResolveEventFullName( string? eventNamespace, string? eventName) { + var originalEventNamespace = eventNamespace; + var originalEventName = eventName; var eventNameIsNullOrWhiteSpace = string.IsNullOrWhiteSpace(eventName); if (string.IsNullOrWhiteSpace(eventNamespace)) @@ -82,12 +77,39 @@ public ReadOnlySpan ResolveEventFullName( var eventNameCache = this.GetEventNameCacheForEventNamespace(eventNamespace!); - if (eventNameCache[eventName!] is byte[] cachedEventFullName) + if (eventNameCache[eventName!] is ResolvedEventFullName cachedEventFullName) { return cachedEventFullName; } - return this.ResolveEventNameRare(eventNameCache, eventNamespace!, eventName!); + var eventFullNameBlob = this.ResolveEventNameRare( + ref eventNamespace!, + ref eventName!); + + byte[]? originalEventNamespaceBlob = !string.IsNullOrEmpty(originalEventNamespace) + && originalEventNamespace != eventNamespace + ? BuildEventFullName(string.Empty, originalEventNamespace!) + : null; + + byte[]? originalEventNameBlob = !string.IsNullOrEmpty(originalEventName) + && originalEventName != eventName + ? BuildEventFullName(string.Empty, originalEventName!) + : null; + + var resolvedEventFullName = new ResolvedEventFullName( + eventFullNameBlob, + originalEventNamespaceBlob, + originalEventNameBlob); + + lock (eventNameCache) + { + if (eventNameCache[eventName!] is null) + { + eventNameCache[eventName!] = resolvedEventFullName; + } + } + + return resolvedEventFullName; } private static byte[] BuildEventFullName(string eventNamespace, string eventName) @@ -98,9 +120,12 @@ private static byte[] BuildEventFullName(string eventNamespace, string eventName var cursor = 1; - WriteEventFullNameComponent(eventNamespace, destination, ref cursor); + if (eventNamespace.Length > 0) + { + WriteEventFullNameComponent(eventNamespace, destination, ref cursor); - destination[cursor++] = (byte)'.'; + destination[cursor++] = (byte)'.'; + } WriteEventFullNameComponent(eventName, destination, ref cursor); @@ -145,15 +170,78 @@ private Hashtable GetEventNameCacheForEventNamespace(string eventNamespace) return eventNameCacheForNamespace; } - private byte[] ResolveEventNameRare(Hashtable eventNameCache, string eventNamespace, string eventName) + private byte[] ResolveEventNameRare( + ref string eventNamespace, + ref string eventName) { - if (!IsEventNamespaceValid(eventNamespace)) + var originalNamespace = eventNamespace; + var originalName = eventName; + + var eventFullNameMappings = this.eventFullNameMappings; + if (eventFullNameMappings != null) { - OneCollectorExporterEventSource.Log.EventNamespaceInvalid(eventNamespace); - eventNamespace = this.defaultEventNamespace; + var tempEventFullName = $"{eventNamespace}.{eventName}"; + + if (eventFullNameMappings.TryGetValue( + tempEventFullName, + out var exactMatchRule)) + { + eventNamespace = exactMatchRule.EventNamespace; + eventName = exactMatchRule.EventName; + } + else + { + KeyValuePair? prefixMatchRule = null; + + foreach (var mappingRule in eventFullNameMappings) + { + if (!tempEventFullName.StartsWith(mappingRule.Key, StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + if (!prefixMatchRule.HasValue + || mappingRule.Key.Length >= prefixMatchRule.Value.Key.Length) + { + prefixMatchRule = mappingRule; + } + } + + if (prefixMatchRule.HasValue) + { + eventNamespace = prefixMatchRule.Value.Value.EventNamespace; + eventName = prefixMatchRule.Value.Value.EventName; + } + else if (eventFullNameMappings.TryGetValue("*", out var defaultRule)) + { + eventNamespace = defaultRule.EventNamespace; + eventName = defaultRule.EventName; + } + else + { + eventNamespace = this.defaultEventNamespace; + eventName = this.defaultEventName; + } + } + + if (eventNamespace.Length == 0 && eventName == "*") + { + eventNamespace = originalNamespace; + eventName = originalName; + } } - var eventNameHashtableKey = eventName; + var namespaceLength = eventNamespace.Length; + if (namespaceLength != 0) + { + if (!IsEventNamespaceValid(eventNamespace)) + { + OneCollectorExporterEventSource.Log.EventNamespaceInvalid(eventNamespace); + eventNamespace = this.defaultEventNamespace; + } + + namespaceLength = eventNamespace.Length + 1; + } if (!IsEventNameValid(eventName)) { @@ -163,25 +251,36 @@ private byte[] ResolveEventNameRare(Hashtable eventNameCache, string eventNamesp byte[] eventFullName; - var finalEventFullNameLength = eventNamespace.Length + eventName.Length + 1; + var finalEventFullNameLength = namespaceLength + eventName.Length; if (finalEventFullNameLength < MinimumEventFullNameLength || finalEventFullNameLength > MaximumEventFullNameLength) { OneCollectorExporterEventSource.Log.EventFullNameDiscarded(eventNamespace, eventName); - eventFullName = this.defaultEventFullName; + eventFullName = this.defaultEventFullName.EventFullName; } else { eventFullName = BuildEventFullName(eventNamespace!, eventName!); } - lock (eventNameCache) + return eventFullName; + } + + internal sealed class ResolvedEventFullName + { + public ResolvedEventFullName( + byte[] eventFullName, + byte[]? originalEventNamespace, + byte[]? originalEventName) { - if (eventNameCache[eventNameHashtableKey] is null) - { - eventNameCache[eventNameHashtableKey] = eventFullName; - } + this.EventFullName = eventFullName; + this.OriginalEventNamespace = originalEventNamespace; + this.OriginalEventName = originalEventName; } - return eventFullName; + public byte[] EventFullName { get; } + + public byte[]? OriginalEventNamespace { get; } + + public byte[]? OriginalEventName { get; } } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 33ac460af9..519a5e1d2c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -16,6 +16,7 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText SeverityNumberProperty = JsonEncodedText.Encode("severityNumber"); private static readonly JsonEncodedText BodyProperty = JsonEncodedText.Encode("body"); private static readonly JsonEncodedText FormattedMessageProperty = JsonEncodedText.Encode("formattedMessage"); + private static readonly JsonEncodedText NamespaceProperty = JsonEncodedText.Encode("namespace"); private static readonly JsonEncodedText DistributedTraceExtensionProperty = JsonEncodedText.Encode("dt"); private static readonly JsonEncodedText DistributedTraceExtensionTraceIdProperty = JsonEncodedText.Encode("traceId"); private static readonly JsonEncodedText DistributedTraceExtensionSpanIdProperty = JsonEncodedText.Encode("spanId"); @@ -48,7 +49,7 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri { if (scopeAttribute.Key == "{OriginalFormat}") { - return; + continue; } if (AttributeKeyStartWithExtensionPrefix(scopeAttribute.Key)) @@ -88,7 +89,7 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C Debug.Assert(writer != null, "writer was null"); - var eventName = this.eventNameManager.ResolveEventFullName( + var resolvedEventFullName = this.eventNameManager.ResolveEventFullName( item.CategoryName, item.EventId.Name); @@ -98,9 +99,9 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C writer.WritePropertyName(CommonSchemaJsonSerializationHelper.NameProperty); #if DEBUG - writer.WriteRawValue(eventName, skipInputValidation: false); + writer.WriteRawValue(resolvedEventFullName.EventFullName, skipInputValidation: false); #else - writer.WriteRawValue(eventName, skipInputValidation: true); + writer.WriteRawValue(resolvedEventFullName.EventFullName, skipInputValidation: true); #endif writer.WriteString(CommonSchemaJsonSerializationHelper.TimeProperty, item.Timestamp); @@ -114,6 +115,26 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C writer.WriteNumber(EventIdProperty, item.EventId.Id); } + if (resolvedEventFullName.OriginalEventNamespace != null) + { + writer.WritePropertyName(NamespaceProperty); +#if DEBUG + writer.WriteRawValue(resolvedEventFullName.OriginalEventNamespace, skipInputValidation: false); +#else + writer.WriteRawValue(resolvedEventFullName.OriginalEventNamespace, skipInputValidation: true); +#endif + } + + if (resolvedEventFullName.OriginalEventName != null) + { + writer.WritePropertyName(CommonSchemaJsonSerializationHelper.NameProperty); +#if DEBUG + writer.WriteRawValue(resolvedEventFullName.OriginalEventName, skipInputValidation: false); +#else + writer.WriteRawValue(resolvedEventFullName.OriginalEventName, skipInputValidation: true); +#endif + } + #if EXPOSE_EXPERIMENTAL_FEATURES #pragma warning disable CS0618 // Type or member is obsolete // TODO: Update to use LogRecord.Severity diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs index 3e61545d34..3c40dcf859 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExportProcessorBuilder.cs @@ -157,6 +157,51 @@ public OneCollectorLogExportProcessorBuilder SetConnectionString( return this; } + /// + /// Sets the event full name mappings used by the created by the builder. + /// + /// + /// Event full name mappings. + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder SetEventFullNameMappings( + IReadOnlyDictionary? eventFullNameMappings) + { + this.services.Configure( + this.name, + exporterOptions => exporterOptions.EventFullNameMappings = eventFullNameMappings); + + return this; + } + + /// + /// Sets the default event namespace used by the created by the builder. Default value: + /// OpenTelemetry.Logs. + /// + /// + /// Default event namespace. + /// The supplied for call + /// chaining. + public OneCollectorLogExportProcessorBuilder SetDefaultEventNamespace( + string defaultEventNamespace) + { + Guard.ThrowIfNullOrWhitespace(defaultEventNamespace); + + this.services.Configure( + this.name, + exporterOptions => exporterOptions.DefaultEventNamespace = defaultEventNamespace); + + return this; + } + /// /// Sets the default event name used by the created by the builder. Default value: @@ -250,7 +295,10 @@ private static WriteDirectlyToTransportSink CreateSink(OneCollectorLo #pragma warning disable CA2000 // Dispose objects before losing scope return new WriteDirectlyToTransportSink( new LogRecordCommonSchemaJsonSerializer( - new EventNameManager(exporterOptions.DefaultEventNamespace, exporterOptions.DefaultEventName), + new EventNameManager( + exporterOptions.DefaultEventNamespace, + exporterOptions.DefaultEventName, + exporterOptions.ParsedEventFullNameMappings), exporterOptions.TenantToken!, exporterOptions.SerializationOptions.ExceptionStackTraceHandling, transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index a64e7c76d9..d57b42c7d2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -12,43 +12,165 @@ namespace OpenTelemetry.Exporter.OneCollector; /// public sealed class OneCollectorLogExporterOptions : OneCollectorExporterOptions { + private IReadOnlyDictionary? eventFullNameMappings; + /// - /// Gets or sets the default event name. Default value: Log. + /// Gets or sets the default event namespace. Default value: + /// OpenTelemetry.Logs. /// /// - /// Note: The default event name is used when an has a null or whitespace . + /// Notes: + /// + /// The default event namespace is used if a is not supplied or if are defined and an event full name does + /// not match a defined rule. + /// Can be set to empty string "" but cannot be . + /// + /// When combined with the final default full + /// event name value must be at least four characters long and cannot be + /// more than 100 characters long. + /// + /// /// - public string DefaultEventName { get; set; } = "Log"; + public string DefaultEventNamespace { get; set; } = "OpenTelemetry.Logs"; /// - /// Gets the OneCollector log serialization options. + /// Gets or sets the default event name. Default value: Log. /// - public OneCollectorLogExporterSerializationOptions SerializationOptions { get; } = new(); + /// + /// Notes: + /// + /// The default event name is used when an has a null, whitespace, or invalid or if are + /// defined and an event full name does not match a defined rule. + /// + /// Cannot be set to empty string "" or . + /// + /// + /// When combined with the final default + /// full event name value must be at least four characters long and cannot + /// be more than 100 characters long. + /// + /// + /// + public string DefaultEventName { get; set; } = "Log"; /// - /// Gets or sets the default event namespace. Default value: - /// OpenTelemetry.Logs. + /// Gets or sets the event full name mappings. /// /// - /// Note: The default event namespace is used if a is not supplied. This is internal at the - /// moment because using the interface there should - /// always be a category name. + /// Event full name mappings may be used to change the final event + /// namespace and/or event name for a given . By + /// default (when is not used) event + /// full name is derived from the + /// (event namespace) and (event name) + /// values. + /// Notes: + /// + /// Key: + /// + /// Key may be * to set the default mapping rule. Only a single + /// default mapping rule may be defined. Example: *. + /// Key may be a fully qualified event name (exact match rule). + /// Example: MyCompany.Library.EventName. + /// Key may be a prefix (StartsWith rule). Example: + /// MyCompany.Library. + /// + /// + /// Value: + /// + /// Value may be an event name without a namespace. Example: + /// MyNewEventName. + /// Value may be a a fully qualified event name. Example: + /// MyCompany.Library.MyNewEventName. + /// Value may be * to pass-through the originally resolved full + /// event name value. Example: *. + /// + /// + /// /// - internal string DefaultEventNamespace { get; set; } = "OpenTelemetry.Logs"; + public IReadOnlyDictionary? EventFullNameMappings + { + get => this.eventFullNameMappings; + set + { + if (value == null) + { + this.eventFullNameMappings = null; + return; + } + + var copy = new Dictionary(value.Count); + + foreach (var entry in value) + { + copy[entry.Key] = entry.Value; + } + + this.eventFullNameMappings = copy; + } + } + + /// + /// Gets the OneCollector log serialization options. + /// + public OneCollectorLogExporterSerializationOptions SerializationOptions { get; } = new(); + + internal IReadOnlyDictionary? ParsedEventFullNameMappings { get; private set; } internal override void Validate() { - if (string.IsNullOrWhiteSpace(this.DefaultEventNamespace)) + if (this.DefaultEventNamespace?.Length != 0 + && (this.DefaultEventNamespace == null + || !EventNameManager.IsEventNamespaceValid(this.DefaultEventNamespace!))) { - throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventNamespace)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventNamespace)} was not specified on {nameof(OneCollectorLogExporterOptions)} options or was invalid."); } - if (string.IsNullOrWhiteSpace(this.DefaultEventName)) + if (string.IsNullOrWhiteSpace(this.DefaultEventName) + || !EventNameManager.IsEventNameValid(this.DefaultEventName)) { - throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventName)} was not specified on {nameof(OneCollectorLogExporterOptions)} options."); + throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventName)} was not specified on {nameof(OneCollectorLogExporterOptions)} options or was invalid."); + } + + var defaultEventFullNameLength = this.DefaultEventName.Length + + this.DefaultEventNamespace.Length + + (this.DefaultEventNamespace.Length > 0 ? 1 : 0); + + if (defaultEventFullNameLength < EventNameManager.MinimumEventFullNameLength + || defaultEventFullNameLength > EventNameManager.MaximumEventFullNameLength) + { + throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventNamespace)} & {nameof(this.DefaultEventName)} specified on {nameof(OneCollectorLogExporterOptions)} options cannot be less than 4 characters or greater than 100 characters in length when combined."); + } + + var eventFullNameMappings = this.eventFullNameMappings; + if (eventFullNameMappings != null) + { + var parsedEventFullNameMappings = new Dictionary( + capacity: eventFullNameMappings.Count, + comparer: StringComparer.OrdinalIgnoreCase); + + foreach (var entry in eventFullNameMappings) + { + if (string.IsNullOrWhiteSpace(entry.Key)) + { + throw new OneCollectorExporterValidationException("An event full name mapping key was null, empty, or consisted only of white-space characters."); + } + + if (!EventFullName.TryParseFromMapping(entry.Value, out var eventFullName)) + { + throw new OneCollectorExporterValidationException($"The event full name mapping value provided for key '{entry.Key}' was null."); + } + + eventFullName!.Validate(entry.Key); + + parsedEventFullNameMappings.Add(entry.Key, eventFullName); + } + + this.ParsedEventFullNameMappings = parsedEventFullNameMappings; } this.SerializationOptions.Validate(); diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index b6e816d41c..d806344a74 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -37,3 +37,132 @@ using var scope = logger.BeginScope("{requestContext}", Guid.NewGuid()); logger.LogInformation("Request received {requestId}!", 1); logger.LogWarning("Warning encountered {error_code}!", 0xBAADBEEF); ``` + +## Table name resolution + +By default when sending logs/events `OneCollectorExporter` generates fully +qualifed names using the `LogRecord` `CategoryName` and `EventId.Name` +properties (ex: `$"{CategoryName}.{EventId.Name}"`). When `EventId.Name` is not +supplied the `OneCollectorLogExporterOptions.DefaultEventName` property is used +(the default value is `Log`). Event full names are used by the OneCollector +service to create tables to store logs/events. The final table name may change +casing and will change `.` characters to `_` characters. + +The default behavior is designed so that each unique log/event is mapped to its +own table with its own schema. Attributes supplied on logs/events are promoted +to columns on the table. + +### Event full name mappings + +In the event that the default full name generation behavior does not result in +the desired table configuration, `EventFullNameMappings` may be supplied to +`OneCollectorExporter` to customize the final event full names sent to the +OneCollector service. + +> [!NOTE] +> When a log/event is mapped `OneCollectorExporter` will automatically add the +> `namespace` and/or `name` attribute(s) to preserve the original values. + +Mappings can be specified using a default wild card rule, exact-match rules, +and/or prefix-based (`StartsWith`) rules. In the event multiple prefix matches +are made the one matching the most characters is selected. + +* To change the default event full name for all logs add an entry with the key + `*` and set the value to the desired event full name. Only a single `*` + default entry may exist. + +* To change the event full name for a specific + namespace/[category](https://docs.microsoft.com/dotnet/core/extensions/logging#log-category) + of log records add an entry with the key set to a prefix that will match from + the starting portion of the namespace/category. Set the value to the desired + event full name. + + For example, given the configuration... + + ```csharp + logging.AddOneCollectorExporter( + "InstrumentationKey=instrumentation-key-here", + builder => builder.SetEventFullNameMappings( + new Dictionary() + { + { "*", "DefaultLogs" }, + { "MyCompany", "InternalLogs" }, + { "MyCompany.Product1", "InternalProduct1Logs" }, + { "MyCompany.Product2", "InternalProduct2Logs" }, + { "MyCompany.Product2.Security", "InternalSecurityLogs" }, + }); + ``` + + ...log event full name mapping would be performed as such: + + * `ILogger`: All logs emitted through this logger will use + the "DefaultLogs" event full name + + * `ILogger`: All logs emitted through this logger + will use the "InternalLogs" event full name + + * `ILogger`: All logs emitted through this logger + will use the "InternalProduct1Logs" event full name + + * `ILogger`: All logs emitted through this logger + will use the "InternalProduct2Logs" event full name + + * `ILogger`: All logs emitted through this + logger will use the "InternalSecurityLogs" event full name + +#### Schema management + +The default mapping behavior used by `OneCollectorExporter` is designed so that +each unique log/event is mapped to its own table with its own schema. Using +`EventFullNameMappings` may lead to many disparate logs/events with differing +schema going into the same table. This could lead to wide tables with many +columns or, in the case of logs/events sending attributes with the same name but +different data types, lost or corrupt data. + +`OneCollectorExporter` does not currently provide any features to automatically +flatten or stringify attributes into a single column to prevent "schema +explosion" issues as described above. Users are encouraged to manually stringify +attributes which should not become columns into JSON strings and log them into a +standard attribute: + +```csharp +logger.LogInformation( + "Hello world {ColumnA} {ColumnB} {Attributes}", + "A", // ColumnA + "B", // ColumnB + // Attributes: + JsonSerializer.Serialize( + new Dictionary() + { + ["id"] = 1, + ["name"] = "name_goes_here", + })); +``` + +#### Pass-through mappings + +Pass-through mappings that preserve the orignal event namespace and/or name are +also possible. + +For example, given the configuration... + +```csharp +logging.AddOneCollectorExporter( + "InstrumentationKey=instrumentation-key-here", + builder => builder.SetEventFullNameMappings( + new Dictionary() + { + { "*", "DefaultLogs" }, + { "MyCompany", "*" }, + }); +``` + +...log event full name mapping would be performed as such: + +* `ILogger`: All logs emitted through this logger will use + the "DefaultLogs" event full name via the wild-card default rule. + +* `ILogger`: All logs emitted through this logger will + have event full names generated as `$"MyCompany.OtherThing.{EventId.Name}"`. + `OneCollectorLogExporterOptions.DefaultEventName` is used (default value is + `Log`) if a log/event does not have `EventId.Name` specified. diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index c6ad6b041a..bf43e78f38 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -56,7 +56,10 @@ public void GlobalSetup() var sink = new WriteDirectlyToTransportSink( new LogRecordCommonSchemaJsonSerializer( - new EventNameManager(exporterOptions.DefaultEventNamespace, exporterOptions.DefaultEventName), + new EventNameManager( + exporterOptions.DefaultEventNamespace, + exporterOptions.DefaultEventName, + exporterOptions.ParsedEventFullNameMappings), exporterOptions.TenantToken!, exporterOptions.SerializationOptions.ExceptionStackTraceHandling, transportOptions.MaxPayloadSizeInBytes == -1 ? int.MaxValue : transportOptions.MaxPayloadSizeInBytes, diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs index e61360d03f..74e5d2c94c 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs @@ -52,14 +52,6 @@ public void InvalidEventNameTest(string eventNamespace) Assert.False(EventNameManager.IsEventNameValid(eventNamespace)); } - [Fact] - public void DefaultEventFullNameLengthTest() - { - Assert.Throws(() => new EventNameManager("N", "N")); - Assert.Throws(() => new EventNameManager(new string('N', 99), "N")); - Assert.Throws(() => new EventNameManager("N", new string('N', 99))); - } - [Theory] [InlineData(null, null, "DefaultNamespace.DefaultName")] [InlineData("myNamespace", null, "MyNamespace.DefaultName")] @@ -68,35 +60,35 @@ public void DefaultEventFullNameLengthTest() [InlineData("9", "[]", "DefaultNamespace.DefaultName")] public void DefaultEventNamespaceAndNameUsedToGenerateFullNameTest(string? eventNamespace, string? eventName, string expectedEventFullName) { - var eventNameManager = new EventNameManager("defaultNamespace", "defaultName"); + var eventNameManager = BuildEventNameManagerWithDefaultOptions(); var resolveEventFullName = eventNameManager.ResolveEventFullName(eventNamespace, eventName); - Assert.Equal(Encoding.ASCII.GetBytes($"\"{expectedEventFullName}\""), resolveEventFullName.ToArray()); + Assert.Equal(Encoding.ASCII.GetBytes($"\"{expectedEventFullName}\""), resolveEventFullName.EventFullName); } [Fact] public void DefaultEventNamespaceAndNameUsedToGenerateFullNameLengthTest() { - var eventNameManager = new EventNameManager("defaultNamespace", "defaultName"); + var eventNameManager = BuildEventNameManagerWithDefaultOptions(); var resolveEventFullName = eventNameManager.ResolveEventFullName("N", "N"); - Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.ToArray()); + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.EventFullName); resolveEventFullName = eventNameManager.ResolveEventFullName(new string('N', 99), "N"); - Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.ToArray()); + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.EventFullName); resolveEventFullName = eventNameManager.ResolveEventFullName("N", new string('N', 99)); - Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.ToArray()); + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultNamespace.DefaultName\""), resolveEventFullName.EventFullName); } [Fact] public void EventNameCacheTest() { - var eventNameManager = new EventNameManager("defaultNamespace", "defaultName"); + var eventNameManager = BuildEventNameManagerWithDefaultOptions(); Assert.Empty(eventNameManager.EventNamespaceCache); @@ -110,4 +102,110 @@ public void EventNameCacheTest() Assert.Single(eventNameManager.EventNamespaceCache); Assert.Single((eventNameManager.EventNamespaceCache["Test"] as Hashtable)!); } + + [Fact] + public void EventFullNameMappedWhenEventNamespaceMatchesTest() + { + var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( + new("*", "WildcardEventName"), + new("MyNamespace", "NewEventName1"), + new("mynamespace.match.in.full.MyEventName", "NewEventName2")); + + var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace.Match.In.Full", "MyEventName"); + + Assert.Equal(Encoding.ASCII.GetBytes("\"NewEventName2\""), resolveEventFullName.EventFullName); + } + + [Fact] + public void EventFullNameMappedWhenEventNamespaceStartsWithPrefixTest() + { + var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( + new("*", "WildcardEventName"), + new("MyNamespace", "NewEventName1"), + new("MyNamespace.NonMatch", "NewEventName2"), + new("MyNamespace.MyChild", "NewEventName3"), + new("mynamespace.mychild.namesp", "NewEventName4")); + + var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace.MyChild.Namespace", "MyEventName"); + + Assert.Equal(Encoding.ASCII.GetBytes("\"NewEventName4\""), resolveEventFullName.EventFullName); + } + + [Fact] + public void EventFullNameMappedUsingDefaultRuleTest() + { + var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( + new("MyNamespace1", "NewEventName1"), + new("MyNamespace2", "NewEventName2"), + new("*", "defaultEventName")); + + var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace", "MyEventName"); + + Assert.Equal(Encoding.ASCII.GetBytes("\"DefaultEventName\""), resolveEventFullName.EventFullName); + } + + [Theory] + [InlineData("DefaultNamespace")] + [InlineData("")] + public void EventFullNameMappedUsingDefaultsWhenNoDefaultRuleDefinedTest(string defaultNamespace) + { + var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( + defaultNamespace, + new KeyValuePair[] + { + new("MyNamespace1", "NewEventName1"), + new("MyNamespace2", "NewEventName2"), + }); + + var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace", "MyEventName"); + + Assert.Equal(Encoding.ASCII.GetBytes($"\"{(defaultNamespace.Length > 0 ? $"{defaultNamespace}." : string.Empty)}DefaultName\""), resolveEventFullName.EventFullName); + } + + [Fact] + public void EventFullNameMappedUsingPassthroughTest() + { + var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( + new KeyValuePair[] + { + new("*", "*"), + }); + + var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace", "MyEventName"); + + Assert.Equal(Encoding.ASCII.GetBytes("\"MyNamespace.MyEventName\""), resolveEventFullName.EventFullName); + } + + private static EventNameManager BuildEventNameManagerWithDefaultOptions() + { + return new EventNameManager("defaultNamespace", "defaultName"); + } + + private static EventNameManager BuildEventNameManagerWithEventFullNameMappings( + params KeyValuePair[] mappings) + { + return BuildEventNameManagerWithEventFullNameMappings( + "defaultNamespace", + mappings); + } + + private static EventNameManager BuildEventNameManagerWithEventFullNameMappings( + string defaultNamespace, + KeyValuePair[] mappings) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + EventFullNameMappings = mappings.ToDictionary( + kvp => kvp.Key, + kvp => kvp.Value), + }; + + options.Validate(); + + return new EventNameManager( + defaultNamespace, + "defaultName", + eventFullNameMappings: options.ParsedEventFullNameMappings); + } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 97da992473..0a7e92b2ab 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -73,6 +73,37 @@ public void LogRecordCategoryNameAndEventNameJsonTest(string categoryName, strin json); } + [Theory] + [InlineData("MyClass.Company", null, "MyNewEvent")] + [InlineData("MyClass.Company", "MyEvent", "MyNewEvent")] + [InlineData("MyClass.OtherCompany", "MyEvent", "MyDefaultEvent")] + [InlineData("NotMapped", null, "Namespace.Name")] + public void EventFullNameMappedJsonTest(string categoryName, string? eventName, string expectedEventFullName) + { + var eventFullNameMappings = new Dictionary + { + { "MyClass.Company", EventFullName.Create("MyNewEvent") }, + { "MyClass", EventFullName.Create("MyDefaultEvent") }, + }; + + string json = GetLogRecordJson( + 1, + (index, logRecord) => + { + logRecord.CategoryName = categoryName; + logRecord.EventId = new(0, eventName); + }, + eventFullNameMappings: eventFullNameMappings); + + string expectedName = eventName == null + ? string.Empty + : $"\"name\":\"{eventName}\","; + + Assert.Equal( + $$$"""{"ver":"4.0","name":"{{{expectedEventFullName}}}","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"namespace":"{{{categoryName}}}",{{{expectedName}}}"severityText":"Trace","severityNumber":1}}""" + "\n", + json); + } + [Fact] public void LogRecordEventIdJsonTest() { @@ -261,10 +292,11 @@ private static string GetLogRecordJson( Action writeLogRecordCallback, Resource? resource = null, ScopeProvider? scopeProvider = null, - bool includeStackTraceAsString = false) + bool includeStackTraceAsString = false, + IReadOnlyDictionary? eventFullNameMappings = null) { var serializer = new LogRecordCommonSchemaJsonSerializer( - new("Namespace", "Name"), + new EventNameManager("Namespace", "Name", eventFullNameMappings), "tenant-token", exceptionStackTraceHandling: includeStackTraceAsString ? OneCollectorExporterSerializationExceptionStackTraceHandlingType.IncludeAsString : OneCollectorExporterSerializationExceptionStackTraceHandlingType.Ignore); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs new file mode 100644 index 0000000000..1548012e78 --- /dev/null +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs @@ -0,0 +1,148 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Xunit; + +namespace OpenTelemetry.Exporter.OneCollector.Tests; + +public sealed class OneCollectorLogExporterOptionsTests +{ + [Theory] + [InlineData(null)] + [InlineData("_")] + [InlineData("123")] + public void InvalidDefaultEventNamespaceTests(string? defaultEventNamespace) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + DefaultEventNamespace = defaultEventNamespace!, + }; + + Assert.Throws( + () => options.Validate()); + } + + [Theory] + [InlineData("")] + [InlineData("A.B")] + [InlineData("default")] + public void ValidDefaultEventNamespaceTests(string? defaultEventNamespace) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + DefaultEventNamespace = defaultEventNamespace!, + DefaultEventName = "Logs", + }; + + options.Validate(); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("_")] + [InlineData(".")] + [InlineData("123")] + public void InvalidDefaultEventNameTests(string? defaultEventName) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + DefaultEventName = defaultEventName!, + }; + + Assert.Throws( + () => options.Validate()); + } + + [Theory] + [InlineData("default123")] + public void ValidDefaultEventNameTests(string? defaultEventName) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + DefaultEventName = defaultEventName!, + }; + + options.Validate(); + } + + [Theory] + [InlineData("A", "B")] + [InlineData("", "Log")] + public void InvalidDefaultEventFullNameTests(string defaultEventNamespace, string defaultEventName) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + DefaultEventNamespace = defaultEventNamespace, + DefaultEventName = defaultEventName, + }; + + Assert.Throws( + () => options.Validate()); + } + + [Theory] + [InlineData("A", "CD")] + [InlineData("", "ABCD")] + public void ValidDefaultEventFullNameTests(string defaultEventNamespace, string defaultEventName) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + DefaultEventNamespace = defaultEventNamespace, + DefaultEventName = defaultEventName, + }; + + options.Validate(); + } + + [Theory] + [InlineData("", "Value")] + [InlineData("Prefix", null)] + [InlineData("Prefix", "")] + [InlineData("*", "")] + [InlineData("Prefix", "ABC")] + [InlineData("Prefix", "_.EventName")] + [InlineData("Prefix", "Namespace.Event_Name")] + [InlineData("Prefix", "Namespace.")] + [InlineData("*", "*.EventName")] + [InlineData("*", "*.*")] + public void InvalidEventFullNameMappingTests(string key, string? value) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + EventFullNameMappings = new Dictionary() + { + { key, value! }, + }, + }; + + Assert.Throws( + () => options.Validate()); + } + + [Theory] + [InlineData("*", "ABCD")] + [InlineData("*", "A.BC")] + [InlineData("*", "A.B.C")] + [InlineData("*", "*")] + public void ValidEventFullNameMappingTests(string key, string? value) + { + var options = new OneCollectorLogExporterOptions() + { + ConnectionString = "InstrumentationKey=token-extrainformation", + EventFullNameMappings = new Dictionary() + { + { key, value! }, + }, + }; + + options.Validate(); + } +} diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs index 92218513cc..384f74ea70 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs @@ -96,6 +96,47 @@ public void SetConnectionStringTest() Assert.Equal("InstrumentationKey=token-extrainformation", options.ConnectionString); } + [Fact] + public void SetEventFullNameMappingsTest() + { + OneCollectorLogExporterOptions? options = null; + + var mappings = new Dictionary() + { + { "Key1", "Value1" }, + }; + + using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter( + builder => + { + builder.AddOneCollectorExporter( + "InstrumentationKey=token-extrainformation", + configure => configure.SetEventFullNameMappings(mappings)); + }, + services => services.Configure(o => options = o)); + + Assert.NotNull(options); + Assert.Equal(mappings, options.EventFullNameMappings); + } + + [Fact] + public void SetDefaultEventNamespaceTest() + { + OneCollectorLogExporterOptions? options = null; + + using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter( + builder => + { + builder.AddOneCollectorExporter( + "InstrumentationKey=token-extrainformation", + configure => configure.SetDefaultEventNamespace("MyDefaultEventNamespace")); + }, + services => services.Configure(o => options = o)); + + Assert.NotNull(options); + Assert.Equal("MyDefaultEventNamespace", options.DefaultEventNamespace); + } + [Fact] public void SetDefaultEventNameTest() { From 365e4f11b9933fe1b2765fd050022d737de3275b Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:43:31 -0500 Subject: [PATCH 1225/1499] [release] Prepare release Exporter.OneCollector-1.10.0-alpha.1 (#2042) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 4f3f8dd417..ad0bb5a576 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-alpha.1 + +Released 2024-Sep-06 + * Dropped support for the `net7.0` target because .NET 7 is no longer supported. Added a `net8.0` target. ([#2038](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/2038)) From ddd0a2e904e4cb3639335d956a3be0e3d83da943 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sat, 7 Sep 2024 07:11:48 -0700 Subject: [PATCH 1226/1499] [geneva] Add missing XML docs for public APIs (#2044) --- build/OpenTelemetryContrib.prod.ruleset | 2 ++ .../EventNameExportMode.cs | 3 +++ .../ExceptionStackExportMode.cs | 10 ++++++++ .../GenevaBaseExporter.cs | 6 ++++- .../GenevaExporterHelperExtensions.cs | 3 +++ .../GenevaExporterOptions.cs | 24 +++++++++++++++++++ .../GenevaLogExporter.cs | 9 +++++++ .../GenevaLoggingExtensions.cs | 19 +++++++++++---- .../GenevaTraceExporter.cs | 9 +++++++ .../Metrics/GenevaMetricExporter.cs | 6 +++++ .../Metrics/GenevaMetricExporterExtensions.cs | 3 +++ .../Metrics/GenevaMetricExporterOptions.cs | 3 +++ .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- 13 files changed, 93 insertions(+), 6 deletions(-) diff --git a/build/OpenTelemetryContrib.prod.ruleset b/build/OpenTelemetryContrib.prod.ruleset index d8632be288..472ce23694 100644 --- a/build/OpenTelemetryContrib.prod.ruleset +++ b/build/OpenTelemetryContrib.prod.ruleset @@ -9,5 +9,7 @@ + + diff --git a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs index 3ef68a4892..dd87d4e8c9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs @@ -3,6 +3,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// Contains the event name export mode defintions. +/// [Flags] public enum EventNameExportMode { diff --git a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs index 2c00fd9c7e..9030a32b9c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs @@ -3,9 +3,19 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// Contains the exception stack trace export mode defintions. +/// public enum ExceptionStackExportMode { + /// + /// Exception stack traces are dropped. + /// Drop, + + /// + /// Exception stack traces are exported as strings. + /// ExportAsString, // ExportAsArrayOfStacks - future if stacks can be exported in more structured way diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 946b6425b6..0dcfe55ce3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -3,7 +3,11 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// GenevaExporter base class. +/// +/// The type of object to be exported. public abstract class GenevaBaseExporter : BaseExporter -where T : class + where T : class { } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 0fe7872da5..ce1b378209 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -9,6 +9,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// Contains extension methods to register the Geneva trace exporter. +/// public static class GenevaExporterHelperExtensions { /// diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index c9e87ef33c..badf1a68c9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -6,6 +6,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// Contains Geneva exporter options. +/// public class GenevaExporterOptions { private IReadOnlyDictionary _fields = new Dictionary(1) @@ -15,16 +18,34 @@ public class GenevaExporterOptions private IReadOnlyDictionary _tableNameMappings; + /// + /// Gets or sets the connection string. + /// public string ConnectionString { get; set; } + /// + /// Gets or sets custom fields. + /// public IEnumerable CustomFields { get; set; } + /// + /// Gets or sets the exception stack trace export mode. + /// public ExceptionStackExportMode ExceptionStackExportMode { get; set; } + /// + /// Gets or sets the event name export mode. + /// public EventNameExportMode EventNameExportMode { get; set; } + /// + /// Gets or sets a value indicating whether or not trace state should be included when exporting traces. + /// public bool IncludeTraceStateForSpan { get; set; } + /// + /// Gets or sets table name mappings. + /// public IReadOnlyDictionary TableNameMappings { get => this._tableNameMappings; @@ -72,6 +93,9 @@ public IReadOnlyDictionary TableNameMappings } } + /// + /// Gets or sets prepopulated fields. + /// public IReadOnlyDictionary PrepopulatedFields { get => this._fields; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 1e3ef76dbf..918a5ee275 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -8,6 +8,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// An exporter for Geneva logs. +/// public class GenevaLogExporter : GenevaBaseExporter { internal bool IsUsingUnixDomainSocket; @@ -20,6 +23,10 @@ public class GenevaLogExporter : GenevaBaseExporter private readonly IDisposable exporter; + /// + /// Initializes a new instance of the class. + /// + /// . public GenevaLogExporter(GenevaExporterOptions options) { Guard.ThrowIfNull(options); @@ -76,11 +83,13 @@ public GenevaLogExporter(GenevaExporterOptions options) } } + /// public override ExportResult Export(in Batch batch) { return this.exportLogRecord(in batch); } + /// protected override void Dispose(bool disposing) { if (this.isDisposed) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 4507997ce0..0c8ac2e7ec 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -11,9 +11,20 @@ namespace Microsoft.Extensions.Logging; +/// +/// Contains extension methods to register the Geneva log exporter. +/// public static class GenevaLoggingExtensions { - public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetryLoggerOptions options, Action configure) + /// + /// Adds to the . + /// + /// . + /// Callback action for configuring . + /// The instance of to chain the calls. + public static OpenTelemetryLoggerOptions AddGenevaLogExporter( + this OpenTelemetryLoggerOptions options, + Action configure) { Guard.ThrowIfNull(options); @@ -31,7 +42,7 @@ public static OpenTelemetryLoggerOptions AddGenevaLogExporter(this OpenTelemetry } /// - /// Adds Geneva exporter to the LoggerProvider. + /// Adds to the . /// /// builder to use. /// The instance of to chain the calls. @@ -39,7 +50,7 @@ public static LoggerProviderBuilder AddGenevaLogExporter(this LoggerProviderBuil => AddGenevaLogExporter(builder, name: null, configureExporter: null); /// - /// Adds Geneva exporter to the LoggerProvider. + /// Adds to the . /// /// builder to use. /// Callback action for configuring . @@ -48,7 +59,7 @@ public static LoggerProviderBuilder AddGenevaLogExporter(this LoggerProviderBuil => AddGenevaLogExporter(builder, name: null, configureExporter); /// - /// Adds Geneva exporter to the LoggerProvider. + /// Adds to the . /// /// builder to use. /// Optional name which is used when retrieving options. diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 309cb7b87c..a0f614f00a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -8,6 +8,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// An exporter for Geneva traces. +/// public class GenevaTraceExporter : GenevaBaseExporter { internal readonly bool IsUsingUnixDomainSocket; @@ -20,6 +23,10 @@ public class GenevaTraceExporter : GenevaBaseExporter private readonly IDisposable exporter; + /// + /// Initializes a new instance of the class. + /// + /// . public GenevaTraceExporter(GenevaExporterOptions options) { Guard.ThrowIfNull(options); @@ -76,11 +83,13 @@ public GenevaTraceExporter(GenevaExporterOptions options) } } + /// public override ExportResult Export(in Batch batch) { return this.exportActivity(in batch); } + /// protected override void Dispose(bool disposing) { if (this.isDisposed) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 3b66acdf56..73128fb47d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -39,6 +39,10 @@ public partial class GenevaMetricExporter : BaseExporter internal Resource Resource => this.resource ??= this.ParentProvider.GetResource(); + /// + /// Initializes a new instance of the class. + /// + /// . public GenevaMetricExporter(GenevaMetricExporterOptions options) { Guard.ThrowIfNull(options); @@ -72,11 +76,13 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) } } + /// public override ExportResult Export(in Batch batch) { return this.exportMetrics(batch); } + /// protected override void Dispose(bool disposing) { if (this.isDisposed) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index f6202edf78..fb84697810 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -8,6 +8,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// Contains extension methods to register the Geneva metrics exporter. +/// public static class GenevaMetricExporterExtensions { /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index 36e13d2ef3..1533117eeb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -6,6 +6,9 @@ namespace OpenTelemetry.Exporter.Geneva; +/// +/// Contains Geneva metrics exporter options. +/// public class GenevaMetricExporterOptions { private IReadOnlyDictionary _prepopulatedMetricDimensions; diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 0e28e227b8..d7e16afe5b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,7 +5,7 @@ true An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors - $(NoWarn),CS1591,SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1602,SA1649,OTEL1002 + $(NoWarn),SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1649,OTEL1002 net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 From 0cac29200a2533a95700a80677da87d8d7692477 Mon Sep 17 00:00:00 2001 From: Vishwesh Bankwar Date: Sun, 8 Sep 2024 22:27:20 -0700 Subject: [PATCH 1227/1499] [repo] Move Vishwesh to Emeritus maintainer (#2041) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fdcfce7f38..9dd41b0f85 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,6 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb * [Cijo Thomas](https://github.com/cijothomas), Microsoft * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk -* [Vishwesh Bankwar](https://github.com/vishweshbankwar), Microsoft *Find more about the maintainer role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* @@ -104,6 +103,7 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb * [Prashant Srivastava](https://github.com/srprash) * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) * [Utkarsh Umesan Pillai](https://github.com/utpilla) +* [Vishwesh Bankwar](https://github.com/vishweshbankwar) Even though, anybody can contribute, there are benefits of being a member of our community. See to the [community membership From 0087cce37d7d1c625a1eb512dc7559715b7faa45 Mon Sep 17 00:00:00 2001 From: Eric Zhang Date: Mon, 9 Sep 2024 02:34:57 -0700 Subject: [PATCH 1228/1499] [Instrumentation.AWS] Add instrumentation for AWS Services: Bedrock, BedrockRuntime, BedrockAgent, BedrockAgentRuntime (#1979) --- .../CHANGELOG.md | 3 + .../AWSPropagatorPipelineHandler.cs | 133 ++++++- .../Implementation/AWSSemanticConventions.cs | 10 + .../Implementation/AWSServiceHelper.cs | 84 +++- .../Implementation/AWSServiceType.cs | 16 + ...Telemetry.Instrumentation.AWS.Tests.csproj | 4 + .../TestAWSClientInstrumentation.cs | 370 ++++++++++++++++++ 7 files changed, 605 insertions(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 0ab5292147..9d9e3ea1b8 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added instrumentation support for AWS Bedrock, BedrockRuntime, BedrockAgent, BedrockAgentRuntime. + ([#1979](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1979)) + ## 1.1.0-beta.5 Released 2024-Aug-22 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs index 38ee9a3dbc..1e97c34c88 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs @@ -40,13 +40,21 @@ public override void InvokeSync(IExecutionContext executionContext) this.ProcessBeginRequest(executionContext); base.InvokeSync(executionContext); + + ProcessEndRequest(executionContext); } public override async Task InvokeAsync(IExecutionContext executionContext) { + T? ret = null; + this.ProcessBeginRequest(executionContext); - return await base.InvokeAsync(executionContext).ConfigureAwait(false); + ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); + + ProcessEndRequest(executionContext); + + return ret; } #if NET @@ -59,25 +67,37 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon { var service = requestContext.ServiceMetaData.ServiceId; - if (AWSServiceHelper.ServiceParameterMap.TryGetValue(service, out var parameter)) + if (AWSServiceHelper.ServiceRequestParameterMap.TryGetValue(service, out var parameters)) { AmazonWebServiceRequest request = requestContext.OriginalRequest; - try + foreach (var parameter in parameters) { - var property = request.GetType().GetProperty(parameter); - if (property != null) + try { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + // for bedrock agent, we only extract one attribute based on the operation. + if (AWSServiceType.IsBedrockAgentService(service)) + { + if (AWSServiceHelper.OperationNameToResourceMap()[AWSServiceHelper.GetAWSOperationName(requestContext)] != parameter) + { + continue; + } + } + + var property = request.GetType().GetProperty(parameter); + if (property != null) { - activity.SetTag(attribute, property.GetValue(request)); + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(request)); + } } } - } - catch (Exception) - { - // Guard against any reflection-related exceptions when running in AoT. - // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + catch (Exception) + { + // Guard against any reflection-related exceptions when running in AoT. + // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + } } } @@ -95,6 +115,95 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon SnsRequestContextHelper.AddAttributes( requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); } + else if (AWSServiceType.IsBedrockRuntimeService(service)) + { + activity.SetTag(AWSSemanticConventions.AttributeGenAiSystem, "aws_bedrock"); + } + } + +#if NET + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif + private static void AddResponseSpecificInformation(Activity activity, IExecutionContext executionContext) + { + var service = executionContext.RequestContext.ServiceMetaData.ServiceId; + var responseContext = executionContext.ResponseContext; + + if (AWSServiceHelper.ServiceResponseParameterMap.TryGetValue(service, out var parameters)) + { + AmazonWebServiceResponse response = responseContext.Response; + + foreach (var parameter in parameters) + { + try + { + // for bedrock agent, extract attribute from object in response. + if (AWSServiceType.IsBedrockAgentService(service)) + { + var operationName = Utils.RemoveSuffix(response.GetType().Name, "Response"); + if (AWSServiceHelper.OperationNameToResourceMap()[operationName] == parameter) + { + AddBedrockAgentResponseAttribute(activity, response, parameter); + } + } + + var property = response.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(response)); + } + } + } + catch (Exception) + { + // Guard against any reflection-related exceptions when running in AoT. + // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + } + } + } + } + +#if NET + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif + private static void AddBedrockAgentResponseAttribute(Activity activity, AmazonWebServiceResponse response, string parameter) + { + var responseObject = response.GetType().GetProperty(Utils.RemoveSuffix(parameter, "Id")); + if (responseObject != null) + { + var attributeObject = responseObject.GetValue(response); + if (attributeObject != null) + { + var property = attributeObject.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(attributeObject)); + } + } + } + } + } + + private static void ProcessEndRequest(IExecutionContext executionContext) + { + var currentActivity = Activity.Current; + + if (currentActivity == null || !currentActivity.Source.Name.StartsWith(TelemetryConstants.TelemetryScopePrefix, StringComparison.Ordinal)) + { + return; + } + + AddResponseSpecificInformation(currentActivity, executionContext); } private void ProcessBeginRequest(IExecutionContext executionContext) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index ce6f1fe325..71fc82ddb3 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -13,6 +13,16 @@ internal static class AWSSemanticConventions public const string AttributeAWSDynamoTableName = "aws.table_name"; public const string AttributeAWSSQSQueueUrl = "aws.queue_url"; + // AWS Bedrock service attributes not yet defined in semantic conventions + public const string AttributeAWSBedrockAgentId = "aws.bedrock.agent.id"; + public const string AttributeAWSBedrockDataSourceId = "aws.bedrock.data_source.id"; + public const string AttributeAWSBedrockGuardrailId = "aws.bedrock.guardrail.id"; + public const string AttributeAWSBedrockKnowledgeBaseId = "aws.bedrock.knowledge_base.id"; + + // should be global convention for Gen AI attributes + public const string AttributeGenAiModelId = "gen_ai.request.model"; + public const string AttributeGenAiSystem = "gen_ai.system"; + public const string AttributeHttpStatusCode = "http.status_code"; public const string AttributeHttpResponseContentLength = "http.response_content_length"; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index 3cbb8ca6e9..bbe8e318a3 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -7,18 +7,96 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSServiceHelper { - internal static IReadOnlyDictionary ServiceParameterMap = new Dictionary() + internal static IReadOnlyDictionary> ServiceRequestParameterMap = new Dictionary>() { - { AWSServiceType.DynamoDbService, "TableName" }, - { AWSServiceType.SQSService, "QueueUrl" }, + { AWSServiceType.DynamoDbService, new List { "TableName" } }, + { AWSServiceType.SQSService, new List { "QueueUrl" } }, + { AWSServiceType.BedrockAgentService, new List { "AgentId", "KnowledgeBaseId", "DataSourceId" } }, + { AWSServiceType.BedrockAgentRuntimeService, new List { "AgentId", "KnowledgeBaseId" } }, + { AWSServiceType.BedrockRuntimeService, new List { "ModelId" } }, + }; + + internal static IReadOnlyDictionary> ServiceResponseParameterMap = new Dictionary>() + { + { AWSServiceType.BedrockService, new List { "GuardrailId" } }, + { AWSServiceType.BedrockAgentService, new List { "AgentId", "DataSourceId" } }, }; internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() { { "TableName", AWSSemanticConventions.AttributeAWSDynamoTableName }, { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, + { "ModelId", AWSSemanticConventions.AttributeGenAiModelId }, + { "AgentId", AWSSemanticConventions.AttributeAWSBedrockAgentId }, + { "DataSourceId", AWSSemanticConventions.AttributeAWSBedrockDataSourceId }, + { "GuardrailId", AWSSemanticConventions.AttributeAWSBedrockGuardrailId }, + { "KnowledgeBaseId", AWSSemanticConventions.AttributeAWSBedrockKnowledgeBaseId }, + }; + + // for Bedrock Agent operations, we map each supported operation to one resource: Agent, DataSource, or KnowledgeBase + internal static List BedrockAgentAgentOps = new List + { + "CreateAgentActionGroup", + "CreateAgentAlias", + "DeleteAgentActionGroup", + "DeleteAgentAlias", + "DeleteAgent", + "DeleteAgentVersion", + "GetAgentActionGroup", + "GetAgentAlias", + "GetAgent", + "GetAgentVersion", + "ListAgentActionGroups", + "ListAgentAliases", + "ListAgentKnowledgeBases", + "ListAgentVersions", + "PrepareAgent", + "UpdateAgentActionGroup", + "UpdateAgentAlias", + "UpdateAgent", }; + internal static List BedrockAgentKnowledgeBaseOps = new List + { + "AssociateAgentKnowledgeBase", + "CreateDataSource", + "DeleteKnowledgeBase", + "DisassociateAgentKnowledgeBase", + "GetAgentKnowledgeBase", + "GetKnowledgeBase", + "ListDataSources", + "UpdateAgentKnowledgeBase", + }; + + internal static List BedrockAgentDataSourceOps = new List + { + "DeleteDataSource", + "GetDataSource", + "UpdateDataSource", + }; + + internal static IReadOnlyDictionary OperationNameToResourceMap() + { + var operationClassMap = new Dictionary(); + + foreach (var op in BedrockAgentKnowledgeBaseOps) + { + operationClassMap[op] = "KnowledgeBaseId"; + } + + foreach (var op in BedrockAgentDataSourceOps) + { + operationClassMap[op] = "DataSourceId"; + } + + foreach (var op in BedrockAgentAgentOps) + { + operationClassMap[op] = "AgentId"; + } + + return operationClassMap; + } + internal static string GetAWSServiceName(IRequestContext requestContext) => Utils.RemoveAmazonPrefixFromServiceName(requestContext.ServiceMetaData.ServiceId); diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs index e9a5b51daa..4a69b87f17 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceType.cs @@ -8,6 +8,10 @@ internal class AWSServiceType internal const string DynamoDbService = "DynamoDB"; internal const string SQSService = "SQS"; internal const string SNSService = "SNS"; + internal const string BedrockService = "Bedrock"; + internal const string BedrockAgentService = "Bedrock Agent"; + internal const string BedrockAgentRuntimeService = "Bedrock Agent Runtime"; + internal const string BedrockRuntimeService = "Bedrock Runtime"; internal static bool IsDynamoDbService(string service) => DynamoDbService.Equals(service, StringComparison.OrdinalIgnoreCase); @@ -17,4 +21,16 @@ internal static bool IsSqsService(string service) internal static bool IsSnsService(string service) => SNSService.Equals(service, StringComparison.OrdinalIgnoreCase); + + internal static bool IsBedrockService(string service) + => BedrockService.Equals(service, StringComparison.OrdinalIgnoreCase); + + internal static bool IsBedrockAgentService(string service) + => BedrockAgentService.Equals(service, StringComparison.OrdinalIgnoreCase); + + internal static bool IsBedrockAgentRuntimeService(string service) + => BedrockAgentRuntimeService.Equals(service, StringComparison.OrdinalIgnoreCase); + + internal static bool IsBedrockRuntimeService(string service) + => BedrockRuntimeService.Equals(service, StringComparison.OrdinalIgnoreCase); } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 975f08f5cd..8b702a1c32 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -10,6 +10,10 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 4f8c17835d..558da3791e 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -3,6 +3,14 @@ using System.Diagnostics; using Amazon; +using Amazon.Bedrock; +using Amazon.Bedrock.Model; +using Amazon.BedrockAgent; +using Amazon.BedrockAgent.Model; +using Amazon.BedrockAgentRuntime; +using Amazon.BedrockAgentRuntime.Model; +using Amazon.BedrockRuntime; +using Amazon.BedrockRuntime.Model; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; using Amazon.Runtime; @@ -207,6 +215,304 @@ public async Task TestSQSSendMessageSuccessful() Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } + [Fact] +#if NETFRAMEWORK + public void TestBedrockGetGuardrailSuccessful() +#else + public async Task TestBedrockGetGuardrailSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrock = new AmazonBedrockClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{\"GuardrailId\":\"123456789\"}"; + CustomResponses.SetResponse(bedrock, dummyResponse, requestId, true); + var getGuardrailRequest = new GetGuardrailRequest(); + getGuardrailRequest.GuardrailIdentifier = "123456789"; +#if NETFRAMEWORK + bedrock.GetGuardrail(getGuardrailRequest); +#else + await bedrock.GetGuardrailAsync(getGuardrailRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock.GetGuardrail"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + + [Fact] +#if NETFRAMEWORK + public void TestBedrockRuntimeInvokeModelSuccessful() +#else + public async Task TestBedrockRuntimeInvokeModelSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrockruntime = new AmazonBedrockRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockruntime, dummyResponse, requestId, true); + var invokeModelRequest = new InvokeModelRequest(); + invokeModelRequest.ModelId = "amazon.titan-text-express-v1"; +#if NETFRAMEWORK + var response = bedrockruntime.InvokeModel(invokeModelRequest); +#else + var response = await bedrockruntime.InvokeModelAsync(invokeModelRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Runtime.InvokeModel"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockRuntimeActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + + [Fact] +#if NETFRAMEWORK + public void TestBedrockAgentGetAgentSuccessful() +#else + public async Task TestBedrockAgentGetAgentSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrockagent = new AmazonBedrockAgentClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockagent, dummyResponse, requestId, true); + var getAgentRequest = new GetAgentRequest(); + getAgentRequest.AgentId = "1234567890"; +#if NETFRAMEWORK + var response = bedrockagent.GetAgent(getAgentRequest); +#else + var response = await bedrockagent.GetAgentAsync(getAgentRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetAgent"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockAgentAgentOpsActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + + [Fact] +#if NETFRAMEWORK + public void TestBedrockAgentGetKnowledgeBaseSuccessful() +#else + public async Task TestBedrockAgentGetKnowledgeBaseSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrockagent = new AmazonBedrockAgentClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockagent, dummyResponse, requestId, true); + var getKnowledgeBaseRequest = new GetKnowledgeBaseRequest(); + getKnowledgeBaseRequest.KnowledgeBaseId = "1234567890"; +#if NETFRAMEWORK + var response = bedrockagent.GetKnowledgeBase(getKnowledgeBaseRequest); +#else + var response = await bedrockagent.GetKnowledgeBaseAsync(getKnowledgeBaseRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetKnowledgeBase"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockAgentKnowledgeBaseOpsActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + + [Fact] +#if NETFRAMEWORK + public void TestBedrockAgentGetDataSourceSuccessful() +#else + public async Task TestBedrockAgentGetDataSourceSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrockagent = new AmazonBedrockAgentClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockagent, dummyResponse, requestId, true); + var getDataSourceRequest = new GetDataSourceRequest(); + getDataSourceRequest.DataSourceId = "1234567890"; + getDataSourceRequest.KnowledgeBaseId = "1234567890"; +#if NETFRAMEWORK + var response = bedrockagent.GetDataSource(getDataSourceRequest); +#else + var response = await bedrockagent.GetDataSourceAsync(getDataSourceRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetDataSource"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockAgentDataSourceOpsActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + + [Fact] +#if NETFRAMEWORK + public void TestBedrockAgentRuntimeInvokeAgentSuccessful() +#else + public async Task TestBedrockAgentRuntimeInvokeAgentSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrockagentruntime = new AmazonBedrockAgentRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockagentruntime, dummyResponse, requestId, true); + var invokeAgentRequest = new InvokeAgentRequest(); + invokeAgentRequest.AgentId = "123456789"; + invokeAgentRequest.AgentAliasId = "testalias"; + invokeAgentRequest.SessionId = "test-session-id"; + invokeAgentRequest.InputText = "sample input text"; +#if NETFRAMEWORK + var response = bedrockagentruntime.InvokeAgent(invokeAgentRequest); +#else + var response = await bedrockagentruntime.InvokeAgentAsync(invokeAgentRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent Runtime.InvokeAgent"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockAgentRuntimeAgentOpsActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + + [Fact] +#if NETFRAMEWORK + public void TestBedrockAgentRuntimeRetrieveSuccessful() +#else + public async Task TestBedrockAgentRuntimeRetrieveSuccessful() +#endif + { + var exportedItems = new List(); + + var parent = new Activity("parent").Start(); + string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + + using (Sdk.CreateTracerProviderBuilder() + .AddXRayTraceId() + .SetSampler(new AlwaysOnSampler()) + .AddAWSInstrumentation() + .AddInMemoryExporter(exportedItems) + .Build()) + { + var bedrockagentruntime = new AmazonBedrockAgentRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + string dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockagentruntime, dummyResponse, requestId, true); + var retrieveRequest = new RetrieveRequest(); + retrieveRequest.KnowledgeBaseId = "123456789"; +#if NETFRAMEWORK + var response = bedrockagentruntime.Retrieve(retrieveRequest); +#else + var response = await bedrockagentruntime.RetrieveAsync(retrieveRequest); +#endif + } + + Assert.NotEmpty(exportedItems); + Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent Runtime.Retrieve"); + Assert.NotNull(awssdk_activity); + + this.ValidateAWSActivity(awssdk_activity, parent); + this.ValidateBedrockAgentRuntimeKnowledgeBaseOpsActivityTags(awssdk_activity); + + Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); + } + private void ValidateAWSActivity(Activity aws_activity, Activity parent) { Assert.Equal(parent.SpanId, aws_activity.ParentSpanId); @@ -231,4 +537,68 @@ private void ValidateSqsActivityTags(Activity sqs_activity) Assert.Equal("SQS", Utils.GetTagValue(sqs_activity, "rpc.service")); Assert.Equal("SendMessage", Utils.GetTagValue(sqs_activity, "rpc.method")); } + + private void ValidateBedrockActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock.GetGuardrail", bedrock_activity.DisplayName); + Assert.Equal("123456789", Utils.GetTagValue(bedrock_activity, "aws.bedrock.guardrail.id")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("GetGuardrail", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } + + private void ValidateBedrockRuntimeActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock Runtime.InvokeModel", bedrock_activity.DisplayName); + Assert.Equal("amazon.titan-text-express-v1", Utils.GetTagValue(bedrock_activity, "gen_ai.request.model")); + Assert.Equal("aws_bedrock", Utils.GetTagValue(bedrock_activity, "gen_ai.system")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock Runtime", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("InvokeModel", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } + + private void ValidateBedrockAgentAgentOpsActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock Agent.GetAgent", bedrock_activity.DisplayName); + Assert.Equal("1234567890", Utils.GetTagValue(bedrock_activity, "aws.bedrock.agent.id")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock Agent", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("GetAgent", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } + + private void ValidateBedrockAgentKnowledgeBaseOpsActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock Agent.GetKnowledgeBase", bedrock_activity.DisplayName); + Assert.Equal("1234567890", Utils.GetTagValue(bedrock_activity, "aws.bedrock.knowledge_base.id")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock Agent", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("GetKnowledgeBase", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } + + private void ValidateBedrockAgentDataSourceOpsActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock Agent.GetDataSource", bedrock_activity.DisplayName); + Assert.Equal("1234567890", Utils.GetTagValue(bedrock_activity, "aws.bedrock.data_source.id")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock Agent", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("GetDataSource", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } + + private void ValidateBedrockAgentRuntimeAgentOpsActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock Agent Runtime.InvokeAgent", bedrock_activity.DisplayName); + Assert.Equal("123456789", Utils.GetTagValue(bedrock_activity, "aws.bedrock.agent.id")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock Agent Runtime", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("InvokeAgent", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } + + private void ValidateBedrockAgentRuntimeKnowledgeBaseOpsActivityTags(Activity bedrock_activity) + { + Assert.Equal("Bedrock Agent Runtime.Retrieve", bedrock_activity.DisplayName); + Assert.Equal("123456789", Utils.GetTagValue(bedrock_activity, "aws.bedrock.knowledge_base.id")); + Assert.Equal("aws-api", Utils.GetTagValue(bedrock_activity, "rpc.system")); + Assert.Equal("Bedrock Agent Runtime", Utils.GetTagValue(bedrock_activity, "rpc.service")); + Assert.Equal("Retrieve", Utils.GetTagValue(bedrock_activity, "rpc.method")); + } } From 00e30cd368b86070f876bbbe62f546d9461276eb Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Mon, 9 Sep 2024 14:47:39 +0200 Subject: [PATCH 1229/1499] [Resources.OperatingSystem] Add a fallback mechanism for `build.id` (#2047) --- .../CHANGELOG.md | 3 +++ .../OperatingSystemDetector.cs | 19 ++++++++++++++++--- ...try.Resources.OperatingSystem.Tests.csproj | 3 +++ .../OperatingSystemDetectorTests.cs | 6 +++++- .../Samples/kernelOsrelease | 1 + 5 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/kernelOsrelease diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index 75723ccda0..707639afda 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add a fallback mechanism for `build.id` for Linux. + ([#2047](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2047)) + ## 0.1.0-alpha.3 Released 2024-Aug-30 diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs index 976307fba8..f25ac54f06 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs @@ -16,6 +16,7 @@ namespace OpenTelemetry.Resources.OperatingSystem; internal sealed class OperatingSystemDetector : IResourceDetector { private const string RegistryKey = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; + private const string KernelOsRelease = "/proc/sys/kernel/osrelease"; private static readonly string[] DefaultEtcOsReleasePaths = [ "/etc/os-release", @@ -30,6 +31,7 @@ internal sealed class OperatingSystemDetector : IResourceDetector private readonly string? osType; private readonly string? registryKey; + private readonly string? kernelOsRelease; private readonly string[]? etcOsReleasePaths; private readonly string[]? plistFilePaths; @@ -37,6 +39,7 @@ internal OperatingSystemDetector() : this( GetOSType(), RegistryKey, + KernelOsRelease, DefaultEtcOsReleasePaths, DefaultPlistFilePaths) { @@ -47,12 +50,14 @@ internal OperatingSystemDetector() /// /// The target platform identifier, specifying the operating system type from SemanticConventions. /// The string path in the Windows Registry to retrieve specific Windows attributes. + /// The string path to the file used to obtain Linux build id. /// The string path to the file used to obtain Linux attributes. /// An array of file paths used to retrieve MacOS attributes from plist files. - internal OperatingSystemDetector(string? osType, string? registryKey, string[]? etcOsReleasePath, string[]? plistFilePaths) + internal OperatingSystemDetector(string? osType, string? registryKey, string? kernelOsRelease, string[]? etcOsReleasePath, string[]? plistFilePaths) { this.osType = osType; this.registryKey = registryKey; + this.kernelOsRelease = kernelOsRelease; this.etcOsReleasePaths = etcOsReleasePath; this.plistFilePaths = plistFilePaths; } @@ -188,9 +193,17 @@ private void AddLinuxAttributes(List> attributes) TryGetFieldValue(lineSpan, "VERSION_ID=", ref version); } - // TODO: fallback for buildId + string? buildIdContent = null; + if (buildId.IsEmpty) + { + buildIdContent = File.ReadAllText(this.kernelOsRelease!).Trim(); + } + else + { + buildIdContent = buildId.ToString(); + } - AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemBuildId, buildId.IsEmpty ? null : buildId.ToString()); + AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemBuildId, buildIdContent); AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemName, name.IsEmpty ? "Linux" : name.ToString()); AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemVersion, version.IsEmpty ? null : version.ToString()); } diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj index b8c188d1d8..2648338374 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj @@ -15,6 +15,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs index 68ae79e3c5..5321bd8b63 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs @@ -41,11 +41,11 @@ public void TestOperatingSystemAttributes() Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemName, resourceAttributes.Keys); Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemType, resourceAttributes.Keys); Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemVersion, resourceAttributes.Keys); + Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemBuildId, resourceAttributes.Keys); // Not checking on Linux because the description may vary depending on the distribution. if (expectedDescription != "Linux") { - Assert.Contains(OperatingSystemSemanticConventions.AttributeOperatingSystemBuildId, resourceAttributes.Keys); Assert.Contains(expectedDescription, resourceAttributes[OperatingSystemSemanticConventions.AttributeOperatingSystemDescription]); Assert.Equal(5, resourceAttributes.Count); } @@ -62,6 +62,7 @@ public void TestParseMacOSPlist() OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin, null, null, + null, [path]); var attributes = osDetector.Detect().Attributes.ToDictionary(x => x.Key, x => (string)x.Value); @@ -74,15 +75,18 @@ public void TestParseMacOSPlist() public void TestParseLinuxOsRelease() { string path = "Samples/os-release"; + string kernelPath = "Samples/kernelOsrelease"; var osDetector = new OperatingSystemDetector( OperatingSystemSemanticConventions.OperatingSystemsValues.Linux, null, + kernelPath, [path], null); var attributes = osDetector.Detect().Attributes.ToDictionary(x => x.Key, x => (string)x.Value); Assert.Equal("Ubuntu", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemName]); Assert.Equal("22.04", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemVersion]); + Assert.Equal("5.15.0-76-generic", attributes[OperatingSystemSemanticConventions.AttributeOperatingSystemBuildId]); } #endif } diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/kernelOsrelease b/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/kernelOsrelease new file mode 100644 index 0000000000..78f2e651ce --- /dev/null +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/Samples/kernelOsrelease @@ -0,0 +1 @@ +5.15.0-76-generic From 8606d7dece6c584c383562098a1080cb3bd18448 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Sep 2024 07:52:21 -0500 Subject: [PATCH 1230/1499] [release] Prepare release Resources.OperatingSystem-0.1.0-alpha.4 (#2048) --- src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index 707639afda..f9f0cdd59d 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.4 + +Released 2024-Sep-09 + * Add a fallback mechanism for `build.id` for Linux. ([#2047](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2047)) From 43a0aeb2a9b43b98c2858d8818abbdd72ab2baad Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 9 Sep 2024 11:53:02 -0700 Subject: [PATCH 1231/1499] [onecollector] Prevent event full name mappings with "namespace.*" form (#2043) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../Internal/EventFullName.cs | 4 ++++ .../OneCollectorLogExporterOptionsTests.cs | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs index 16331d45f4..2023376f73 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs @@ -86,5 +86,9 @@ internal void Validate(string key) throw new OneCollectorExporterValidationException($"The event full name mapping value provided for key '{key}' is shorter or longer than what is allowed."); } } + else if (this.EventNamespace.Length != 0) + { + throw new OneCollectorExporterValidationException($"The event full name mapping value provided for key '{key}' has an invalid wild card pattern."); + } } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs index 1548012e78..6e52e8ea45 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs @@ -109,9 +109,14 @@ public void ValidDefaultEventFullNameTests(string defaultEventNamespace, string [InlineData("Prefix", "ABC")] [InlineData("Prefix", "_.EventName")] [InlineData("Prefix", "Namespace.Event_Name")] + [InlineData("Prefix", "Event_Name")] [InlineData("Prefix", "Namespace.")] + [InlineData("Prefix", ".")] [InlineData("*", "*.EventName")] [InlineData("*", "*.*")] + [InlineData("*", "Namespace.*")] + [InlineData("Valid", "Invalid*")] + [InlineData("Valid", "In*valid")] public void InvalidEventFullNameMappingTests(string key, string? value) { var options = new OneCollectorLogExporterOptions() @@ -129,9 +134,14 @@ public void InvalidEventFullNameMappingTests(string key, string? value) [Theory] [InlineData("*", "ABCD")] + [InlineData("Some.Prefix", "ABCD")] [InlineData("*", "A.BC")] + [InlineData("Some.Prefix", "A.BC")] [InlineData("*", "A.B.C")] + [InlineData("Some.Prefix", "A.B.C")] [InlineData("*", "*")] + [InlineData("Some.Prefix", "*")] + [InlineData("Some_Name", "New.Name")] public void ValidEventFullNameMappingTests(string key, string? value) { var options = new OneCollectorLogExporterOptions() From a21a307db9d9f5986d02012f9bc297fc8496f332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 9 Sep 2024 20:53:26 +0200 Subject: [PATCH 1232/1499] [repo] Enable NugetAudit - part 1 (#2034) --- build/Common.nonprod.props | 2 +- build/Common.props | 6 +++++- examples/kafka/Examples.ConfluentKafka.csproj | 2 ++ examples/owin/Examples.Owin.csproj | 2 +- ...penTelemetry.Instrumentation.ConfluentKafka.Tests.csproj | 2 ++ ...lemetry.Instrumentation.EntityFrameworkCore.Tests.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.Owin.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.SqlClient.Tests.csproj | 6 +++--- ...elemetry.Instrumentation.StackExchangeRedis.Tests.csproj | 2 ++ 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 0c8d95fde2..38928926cf 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -22,7 +22,7 @@ --> [0.13.12,0.14) 8.0.0 - [17.11.0,18.0) + [17.11.1,18.0) $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net6.0 diff --git a/build/Common.props b/build/Common.props index 8139621283..3c4da312f4 100644 --- a/build/Common.props +++ b/build/Common.props @@ -13,6 +13,10 @@ latest-all enable enable + true + + + low @@ -45,7 +49,7 @@ [2.6.122,3.0) [2.4.0,3.0) [3.16.0,4.0) - [1.2.0-beta.507,2.0) + [1.2.0-beta.556,2.0) [4.3.4,) 4.7.0 [6.0.0,) diff --git a/examples/kafka/Examples.ConfluentKafka.csproj b/examples/kafka/Examples.ConfluentKafka.csproj index 1dd0024df3..2c66343e81 100644 --- a/examples/kafka/Examples.ConfluentKafka.csproj +++ b/examples/kafka/Examples.ConfluentKafka.csproj @@ -11,5 +11,7 @@ + + diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index 228382acc7..086edcc3e4 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -6,7 +6,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj index 7419dad302..1263d4ff22 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -22,6 +22,8 @@ + + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index a33effea74..7a8b28872d 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -6,11 +6,11 @@ - + - + diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index e61f3950e7..3ffbc965b5 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 8c95aaccc7..5d33706ba9 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 2d871bb3ef..5c3e4d90a2 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -15,9 +15,9 @@ - - - + + + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 12b74df91b..2071a18c16 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -21,5 +21,7 @@ + + From 336a89d50e1db900c1d9174b9ea36d876ce6dec6 Mon Sep 17 00:00:00 2001 From: Biroj Nayak <49173255+birojnayak@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:06:33 +0000 Subject: [PATCH 1233/1499] [Sampler.Aws] perf improvements for AWS Xray sampler (#2046) --- src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs | 11 ++++++++++- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 5 +++++ src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 9 ++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs index 1228a8b3cc..802f72351a 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -15,6 +15,7 @@ public sealed class AWSXRayRemoteSampler : Trace.Sampler, IDisposable internal static readonly TimeSpan DefaultTargetInterval = TimeSpan.FromSeconds(10); private static readonly Random Random = new Random(); + private bool isFallBackEventToWriteSwitch = true; [SuppressMessage("Performance", "CA5394: Do not use insecure randomness", Justification = "Secure random is not required for jitters.")] internal AWSXRayRemoteSampler(Resource resource, TimeSpan pollingInterval, string endpoint, Clock clock) @@ -82,10 +83,18 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame { if (this.RulesCache.Expired()) { - AWSSamplerEventSource.Log.InfoUsingFallbackSampler(); + if (this.isFallBackEventToWriteSwitch) + { + this.isFallBackEventToWriteSwitch = false; + + // could be expensive operation, conditionally call once + AWSSamplerEventSource.Log.InfoUsingFallbackSampler(); + } + return this.FallbackSampler.ShouldSample(in samplingParameters); } + this.isFallBackEventToWriteSwitch = true; return this.RulesCache.ShouldSample(in samplingParameters); } diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index cd6560fd98..d903e437bb 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 0.1.0-alpha.2 + +* Performance problem fix for calling event source when required. + ([#2046](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2046)) + ## 0.1.0-alpha.1 Released 2024-Jun-20 diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs index 71e991217b..33c4cfbb39 100644 --- a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -11,6 +11,7 @@ internal class RulesCache : IDisposable private const int CacheTTL = 60 * 60; // cache expires 1 hour after the refresh (in sec) private readonly ReaderWriterLockSlim rwLock; + private bool isFallBackEventToWriteSwitch = true; public RulesCache(Clock clock, string clientId, Resource resource, Trace.Sampler fallbackSampler) { @@ -85,13 +86,19 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters) { if (ruleApplier.Matches(samplingParameters, this.Resource)) { + this.isFallBackEventToWriteSwitch = true; return ruleApplier.ShouldSample(in samplingParameters); } } // ideally the default rule should have matched. // if we are here then likely due to a bug. - AWSSamplerEventSource.Log.InfoUsingFallbackSampler(); + if (this.isFallBackEventToWriteSwitch) + { + this.isFallBackEventToWriteSwitch = false; + AWSSamplerEventSource.Log.InfoUsingFallbackSampler(); + } + return this.FallbackSampler.ShouldSample(in samplingParameters); } From f0a5a6e618f07f03bfca394ad997170b23d6ec4f Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:10:07 -0500 Subject: [PATCH 1234/1499] [release] Prepare release Sampler.AWS-0.1.0-alpha.2 (#2051) --- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index d903e437bb..94a027034e 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -4,6 +4,8 @@ ## 0.1.0-alpha.2 +Released 2024-Sep-09 + * Performance problem fix for calling event source when required. ([#2046](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2046)) From ce8c21ef571e1e02c73bd58ace68cd0253ffe658 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Tue, 10 Sep 2024 00:51:25 -0400 Subject: [PATCH 1235/1499] [OpenTelemetry.Instrumentation.AWS] Fix Memory Leak by Reusing ActivitySources, Meters, and Instruments (#2039) --- .../CHANGELOG.md | 2 ++ .../Implementation/Metrics/AWSHistogram.cs | 19 ++++++++++++-- .../Implementation/Metrics/AWSMeter.cs | 9 +++---- .../Metrics/AWSMeterProvider.cs | 15 +++++++++-- .../Metrics/AWSMonotonicCounter.cs | 25 +++++++++++++++---- .../Metrics/AWSUpDownCounter.cs | 19 ++++++++++++-- .../Implementation/Tracing/AWSTracer.cs | 6 ++--- .../Tracing/AWSTracerProvider.cs | 15 ++++++++++- .../TestAWSClientMetricsInstrumentation.cs | 5 ++-- 9 files changed, 92 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 9d9e3ea1b8..fb0d930d16 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Fix Memory Leak by Reusing ActivitySources, Meters, and Instruments + ([#2039](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2039)) * Added instrumentation support for AWS Bedrock, BedrockRuntime, BedrockAgent, BedrockAgentRuntime. ([#1979](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1979)) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs index b4bcec7936..dbab867b3f 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Concurrent; using Amazon.Runtime.Telemetry; using Amazon.Runtime.Telemetry.Metrics; @@ -9,11 +10,25 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSHistogram : Histogram where T : struct { + private static readonly ConcurrentDictionary> HistogramsDictionary + = new ConcurrentDictionary>(); + private readonly System.Diagnostics.Metrics.Histogram histogram; - public AWSHistogram(System.Diagnostics.Metrics.Histogram histogram) + public AWSHistogram( + System.Diagnostics.Metrics.Meter meter, + string name, + string? units = null, + string? description = null) { - this.histogram = histogram; + if (HistogramsDictionary.TryGetValue(name, out System.Diagnostics.Metrics.Histogram? histogram)) + { + this.histogram = histogram; + } + + this.histogram = HistogramsDictionary.GetOrAdd( + name, + meter.CreateHistogram(name, units, description)); } public override void Record(T value, Attributes? attributes = null) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs index 14f7ab1c12..db57f44c59 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeter.cs @@ -24,8 +24,7 @@ public override UpDownCounter CreateUpDownCounter( string? description = null) where T : struct { - var upDownCounter = this.meter.CreateUpDownCounter(name, units, description); - return new AWSUpDownCounter(upDownCounter); + return new AWSUpDownCounter(this.meter, name, units, description); } public override MonotonicCounter CreateMonotonicCounter( @@ -34,8 +33,7 @@ public override MonotonicCounter CreateMonotonicCounter( string? description = null) where T : struct { - var counter = this.meter.CreateCounter(name, units, description); - return new AWSMonotonicCounter(counter); + return new AWSMonotonicCounter(this.meter, name, units, description); } public override Histogram CreateHistogram( @@ -44,8 +42,7 @@ public override Histogram CreateHistogram( string? description = null) where T : struct { - var histogram = this.meter.CreateHistogram(name, units, description); - return new AWSHistogram(histogram); + return new AWSHistogram(this.meter, name, units, description); } protected override void Dispose(bool disposing) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs index c86388503e..240dc565f3 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Concurrent; using Amazon.Runtime.Telemetry; using Amazon.Runtime.Telemetry.Metrics; @@ -8,6 +9,8 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSMeterProvider : MeterProvider { + private static readonly ConcurrentDictionary MetersDictionary = new ConcurrentDictionary(); + public override Meter GetMeter(string scope, Attributes? attributes = null) { // Passing attributes to the Meter is currently not possible due to version limitations @@ -17,7 +20,15 @@ public override Meter GetMeter(string scope, Attributes? attributes = null) // update OpenTelemetry core component version(s) to `1.9.0` and allow passing tags to // the meter constructor. - var meter = new System.Diagnostics.Metrics.Meter(scope); - return new AWSMeter(meter); + if (MetersDictionary.TryGetValue(scope, out AWSMeter? meter)) + { + return meter; + } + + var awsMeter = MetersDictionary.GetOrAdd( + scope, + new AWSMeter(new System.Diagnostics.Metrics.Meter(scope))); + + return awsMeter; } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs index dcbaba5d07..7de5568996 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Concurrent; using Amazon.Runtime.Telemetry; using Amazon.Runtime.Telemetry.Metrics; @@ -9,11 +10,25 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSMonotonicCounter : MonotonicCounter where T : struct { - private readonly System.Diagnostics.Metrics.Counter counter; + private static readonly ConcurrentDictionary> MonotonicCountersDictionary + = new ConcurrentDictionary>(); - public AWSMonotonicCounter(System.Diagnostics.Metrics.Counter counter) + private readonly System.Diagnostics.Metrics.Counter monotonicCounter; + + public AWSMonotonicCounter( + System.Diagnostics.Metrics.Meter meter, + string name, + string? units = null, + string? description = null) { - this.counter = counter; + if (MonotonicCountersDictionary.TryGetValue(name, out System.Diagnostics.Metrics.Counter? monotonicCounter)) + { + this.monotonicCounter = monotonicCounter; + } + + this.monotonicCounter = MonotonicCountersDictionary.GetOrAdd( + name, + meter.CreateCounter(name, units, description)); } public override void Add(T value, Attributes? attributes = null) @@ -21,11 +36,11 @@ public override void Add(T value, Attributes? attributes = null) if (attributes != null) { // TODO: remove ToArray call and use when AttributesAsSpan expected to be added at AWS SDK v4. - this.counter.Add(value, attributes.AllAttributes.ToArray()); + this.monotonicCounter.Add(value, attributes.AllAttributes.ToArray()); } else { - this.counter.Add(value); + this.monotonicCounter.Add(value); } } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs index 02901349ac..2800ebacee 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Concurrent; using Amazon.Runtime.Telemetry; using Amazon.Runtime.Telemetry.Metrics; @@ -9,11 +10,25 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSUpDownCounter : UpDownCounter where T : struct { + private static readonly ConcurrentDictionary> UpDownCountersDictionary + = new ConcurrentDictionary>(); + private readonly System.Diagnostics.Metrics.UpDownCounter upDownCounter; - public AWSUpDownCounter(System.Diagnostics.Metrics.UpDownCounter upDownCounter) + public AWSUpDownCounter( + System.Diagnostics.Metrics.Meter meter, + string name, + string? units = null, + string? description = null) { - this.upDownCounter = upDownCounter; + if (UpDownCountersDictionary.TryGetValue(name, out System.Diagnostics.Metrics.UpDownCounter? upDownCounter)) + { + this.upDownCounter = upDownCounter; + } + + this.upDownCounter = UpDownCountersDictionary.GetOrAdd( + name, + meter.CreateUpDownCounter(name, units, description)); } public override void Add(T value, Attributes? attributes = null) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs index 6c8c1610a6..ecf8418e6a 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs @@ -14,10 +14,10 @@ internal sealed class AWSTracer : Tracer /// /// Initializes a new instance of the class. /// - /// The name of the instrumentation scope that uniquely identifies the tracer. - public AWSTracer(string scope) + /// The ActivitySource used for creating and tracking the activities. + public AWSTracer(ActivitySource activitySource) { - this.activitySource = new ActivitySource(scope); + this.activitySource = activitySource ?? throw new ArgumentNullException(nameof(activitySource)); } public override TraceSpan CreateSpan( diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs index 7e11ce0afc..44fa4986f2 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs @@ -1,14 +1,27 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Collections.Concurrent; +using System.Diagnostics; using Amazon.Runtime.Telemetry.Tracing; namespace OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; internal sealed class AWSTracerProvider : TracerProvider { + private static readonly ConcurrentDictionary TracersDictionary = new ConcurrentDictionary(); + public override Tracer GetTracer(string scope) { - return new AWSTracer(scope); + if (TracersDictionary.TryGetValue(scope, out AWSTracer? awsTracer)) + { + return awsTracer; + } + + awsTracer = TracersDictionary.GetOrAdd( + scope, + new AWSTracer(new ActivitySource(scope))); + + return awsTracer; } } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs index 6872c46d0f..5f2f8b922c 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs @@ -186,7 +186,8 @@ public void TestAWSUpDownCounterIsntCalledAfterMeterDispose() var countAmount = 7; var counterName = "TestCounter"; - var meter = AWSConfigs.TelemetryProvider.MeterProvider.GetMeter($"{TelemetryConstants.TelemetryScopePrefix}.TestDisposedMeter"); + var meterName = $"{TelemetryConstants.TelemetryScopePrefix}.TestDisposedMeter"; + var meter = AWSConfigs.TelemetryProvider.MeterProvider.GetMeter(meterName); var counter = meter.CreateUpDownCounter(counterName); meter.Dispose(); @@ -194,7 +195,7 @@ public void TestAWSUpDownCounterIsntCalledAfterMeterDispose() meterProvider.ForceFlush(); - var counterMetric = exportedItems.FirstOrDefault(i => i.Name == counterName); + var counterMetric = exportedItems.FirstOrDefault(i => i.MeterName == meterName && i.Name == counterName); Assert.Null(counterMetric); } From ce31331680a96b89a395cd33939d8248b0d49944 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Sep 2024 23:54:54 -0500 Subject: [PATCH 1236/1499] [release] Prepare release Instrumentation.AWS-1.1.0-beta.6 (#2053) --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index fb0d930d16..49380447de 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.1.0-beta.6 + +Released 2024-Sep-10 + * Fix Memory Leak by Reusing ActivitySources, Meters, and Instruments ([#2039](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2039)) * Added instrumentation support for AWS Bedrock, BedrockRuntime, BedrockAgent, BedrockAgentRuntime. From 4791960d8c49adb9e5b45b8900010e3337c06591 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:46:52 +0200 Subject: [PATCH 1237/1499] [repo] Allow skipping paths in sanity check script (#2060) --- build/scripts/sanitycheck.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build/scripts/sanitycheck.py b/build/scripts/sanitycheck.py index 901d364f46..06b33c3a61 100644 --- a/build/scripts/sanitycheck.py +++ b/build/scripts/sanitycheck.py @@ -8,12 +8,21 @@ CRLF = b'\r\n' LF = b'\n' +# Add paths to exclude from sanity checks here +exclude_folders = [ + "src/OpenTelemetry.SemanticConventions/Attributes" +] +# Normalize paths so they work in windows/unix +exclude_folders = [os.path.normpath(folder) for folder in exclude_folders] + def sanitycheck(pattern, allow_utf8 = False, allow_eol = (CRLF, LF), indent = 1): error_count = 0 for filename in glob.glob(pattern, recursive=True): if not os.path.isfile(filename): continue + if any(filename.startswith(exclude_folder) for exclude_folder in exclude_folders): + continue with open(filename, 'rb') as file: content = file.read() error = [] From fe9fbea9b6781d1f4d7a9a5e06ed64d45181f60a Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 10 Sep 2024 11:54:46 -0700 Subject: [PATCH 1238/1499] [geneva] Update code to follow more of the repo style conventions (#2052) Co-authored-by: Cijo Thomas --- .../GenevaExporterOptions.cs | 12 +- .../GenevaLogExporter.cs | 9 +- .../GenevaTraceExporter.cs | 9 +- .../Internal/ConnectionStringBuilder.cs | 96 ++--- .../Internal/ReentrantExportProcessor.cs | 4 +- .../Internal/TableNameSerializer.cs | 72 ++-- .../Metrics/GenevaMetricExporter.cs | 40 +- .../Metrics/GenevaMetricExporterOptions.cs | 12 +- .../Metrics/MetricSerializer.cs | 314 ++++++++-------- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 347 +++++++++--------- .../OtlpProtobuf/ProtobufSerializerHelper.cs | 4 +- .../Metrics/TlvMetricExporter.cs | 55 ++- .../Transport/MetricEtwDataTransport.cs | 14 +- .../MsgPackExporter/MessagePackSerializer.cs | 24 +- .../MsgPackExporter/MsgPackLogExporter.cs | 154 ++++---- .../MsgPackExporter/MsgPackTraceExporter.cs | 207 +++++------ .../Transport/EtwDataTransport.cs | 80 ++-- .../Transport/UnixDomainSocketEndPoint.cs | 8 +- .../OpenTelemetry.Exporter.Geneva.csproj | 4 +- .../TLDExporter/JsonSerializer.cs | 26 +- .../TLDExporter/TldLogExporter.cs | 46 ++- .../TLDExporter/TldTraceExporter.cs | 41 +-- .../TLDExporter/UncheckedASCIIEncoding.cs | 8 +- 23 files changed, 778 insertions(+), 808 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index badf1a68c9..e31e3d35d0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -11,12 +11,12 @@ namespace OpenTelemetry.Exporter.Geneva; /// public class GenevaExporterOptions { - private IReadOnlyDictionary _fields = new Dictionary(1) + private IReadOnlyDictionary fields = new Dictionary(1) { [Schema.V40.PartA.Ver] = "4.0", }; - private IReadOnlyDictionary _tableNameMappings; + private IReadOnlyDictionary tableNameMappings; /// /// Gets or sets the connection string. @@ -48,7 +48,7 @@ public class GenevaExporterOptions /// public IReadOnlyDictionary TableNameMappings { - get => this._tableNameMappings; + get => this.tableNameMappings; set { Guard.ThrowIfNull(value); @@ -89,7 +89,7 @@ public IReadOnlyDictionary TableNameMappings copy[entry.Key] = entry.Value; } - this._tableNameMappings = copy; + this.tableNameMappings = copy; } } @@ -98,7 +98,7 @@ public IReadOnlyDictionary TableNameMappings /// public IReadOnlyDictionary PrepopulatedFields { - get => this._fields; + get => this.fields; set { Guard.ThrowIfNull(value); @@ -153,7 +153,7 @@ public IReadOnlyDictionary PrepopulatedFields copy[entry.Key] = val; // shallow copy } - this._fields = copy; + this.fields = copy; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 918a5ee275..83826f174f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -15,14 +15,11 @@ public class GenevaLogExporter : GenevaBaseExporter { internal bool IsUsingUnixDomainSocket; - private bool isDisposed; - - private delegate ExportResult ExportLogRecordFunc(in Batch batch); - private readonly ExportLogRecordFunc exportLogRecord; - private readonly IDisposable exporter; + private bool isDisposed; + /// /// Initializes a new instance of the class. /// @@ -83,6 +80,8 @@ public GenevaLogExporter(GenevaExporterOptions options) } } + private delegate ExportResult ExportLogRecordFunc(in Batch batch); + /// public override ExportResult Export(in Batch batch) { diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index a0f614f00a..7840342587 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -15,14 +15,11 @@ public class GenevaTraceExporter : GenevaBaseExporter { internal readonly bool IsUsingUnixDomainSocket; - private bool isDisposed; - - private delegate ExportResult ExportActivityFunc(in Batch batch); - private readonly ExportActivityFunc exportActivity; - private readonly IDisposable exporter; + private bool isDisposed; + /// /// Initializes a new instance of the class. /// @@ -83,6 +80,8 @@ public GenevaTraceExporter(GenevaExporterOptions options) } } + private delegate ExportResult ExportActivityFunc(in Batch batch); + /// public override ExportResult Export(in Batch batch) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 48c76da6c4..51b8d0035b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -18,7 +18,7 @@ internal enum TransportProtocol internal sealed class ConnectionStringBuilder { - private readonly Dictionary _parts = new Dictionary(StringComparer.Ordinal); + private readonly Dictionary parts = new Dictionary(StringComparer.Ordinal); public ConnectionStringBuilder(string connectionString) { @@ -52,10 +52,10 @@ public ConnectionStringBuilder(string connectionString) throw new ArgumentException("Connection string cannot contain empty keys or values."); } - this._parts[key] = value; + this.parts[key] = value; } - if (this._parts.Count == 0) + if (this.parts.Count == 0) { throw new ArgumentNullException(nameof(connectionString), $"{nameof(connectionString)} is invalid."); } @@ -64,25 +64,25 @@ public ConnectionStringBuilder(string connectionString) public string EtwSession { get => this.ThrowIfNotExists(nameof(this.EtwSession)); - set => this._parts[nameof(this.EtwSession)] = value; + set => this.parts[nameof(this.EtwSession)] = value; } public string PrivatePreviewEnableTraceLoggingDynamic { get => this.ThrowIfNotExists(nameof(this.PrivatePreviewEnableTraceLoggingDynamic)); - set => this._parts[nameof(this.PrivatePreviewEnableTraceLoggingDynamic)] = value; + set => this.parts[nameof(this.PrivatePreviewEnableTraceLoggingDynamic)] = value; } public string PrivatePreviewEnableOtlpProtobufEncoding { - get => this._parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) ? value : null; - set => this._parts[nameof(this.PrivatePreviewEnableOtlpProtobufEncoding)] = value; + get => this.parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) ? value : null; + set => this.parts[nameof(this.PrivatePreviewEnableOtlpProtobufEncoding)] = value; } public string Endpoint { get => this.ThrowIfNotExists(nameof(this.Endpoint)); - set => this._parts[nameof(this.Endpoint)] = value; + set => this.parts[nameof(this.Endpoint)] = value; } public TransportProtocol Protocol @@ -92,9 +92,9 @@ public TransportProtocol Protocol try { // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux - if (this._parts.ContainsKey(nameof(this.EtwSession))) + if (this.parts.ContainsKey(nameof(this.EtwSession))) { - _ = this._parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var privatePreviewEnableTraceLoggingDynamic); + _ = this.parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var privatePreviewEnableTraceLoggingDynamic); if (privatePreviewEnableTraceLoggingDynamic != null && privatePreviewEnableTraceLoggingDynamic.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) { return TransportProtocol.EtwTld; @@ -103,7 +103,7 @@ public TransportProtocol Protocol return TransportProtocol.Etw; } - if (!this._parts.ContainsKey(nameof(this.Endpoint))) + if (!this.parts.ContainsKey(nameof(this.Endpoint))) { return TransportProtocol.Unspecified; } @@ -123,41 +123,11 @@ public TransportProtocol Protocol } } - /// - /// Replace first charater of string if it matches with with . - /// - /// String to be updated. - /// Old character to be replaced. - /// New character to be replaced with. - /// Updated string. - internal static string ReplaceFirstChar(string str, char oldChar, char newChar) - { - if (str.Length > 0 && str[0] == oldChar) - { - return $"{newChar}{str.Substring(1)}"; - } - - return str; - } - - public string ParseUnixDomainSocketPath() - { - try - { - var endpoint = new Uri(this.Endpoint); - return ReplaceFirstChar(endpoint.AbsolutePath, '@', '\0'); - } - catch (UriFormatException ex) - { - throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); - } - } - public int TimeoutMilliseconds { get { - if (!this._parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string value)) + if (!this.parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string value)) { return UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds; } @@ -186,7 +156,7 @@ public int TimeoutMilliseconds ex); } } - set => this._parts[nameof(this.TimeoutMilliseconds)] = value.ToString(CultureInfo.InvariantCulture); + set => this.parts[nameof(this.TimeoutMilliseconds)] = value.ToString(CultureInfo.InvariantCulture); } public string Host @@ -229,32 +199,62 @@ public int Port public string Account { get => this.ThrowIfNotExists(nameof(this.Account)); - set => this._parts[nameof(this.Account)] = value; + set => this.parts[nameof(this.Account)] = value; } public string Namespace { get => this.ThrowIfNotExists(nameof(this.Namespace)); - set => this._parts[nameof(this.Namespace)] = value; + set => this.parts[nameof(this.Namespace)] = value; } public bool DisableMetricNameValidation { get { - if (!this._parts.TryGetValue(nameof(this.DisableMetricNameValidation), out var value)) + if (!this.parts.TryGetValue(nameof(this.DisableMetricNameValidation), out var value)) { return false; } return string.Equals(bool.TrueString, value, StringComparison.OrdinalIgnoreCase); } - set => this._parts[nameof(this.DisableMetricNameValidation)] = value ? bool.TrueString : bool.FalseString; + set => this.parts[nameof(this.DisableMetricNameValidation)] = value ? bool.TrueString : bool.FalseString; + } + + public string ParseUnixDomainSocketPath() + { + try + { + var endpoint = new Uri(this.Endpoint); + return ReplaceFirstChar(endpoint.AbsolutePath, '@', '\0'); + } + catch (UriFormatException ex) + { + throw new ArgumentException($"{nameof(this.Endpoint)} value is malformed.", ex); + } + } + + /// + /// Replace first charater of string if it matches with with . + /// + /// String to be updated. + /// Old character to be replaced. + /// New character to be replaced with. + /// Updated string. + internal static string ReplaceFirstChar(string str, char oldChar, char newChar) + { + if (str.Length > 0 && str[0] == oldChar) + { + return $"{newChar}{str.Substring(1)}"; + } + + return str; } private T ThrowIfNotExists(string name) { - if (!this._parts.TryGetValue(name, out var value)) + if (!this.parts.TryGetValue(name, out var value)) { throw new ArgumentException($"'{name}' value is missing in connection string."); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index 44e1686c11..5e6493c178 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -14,6 +14,8 @@ namespace OpenTelemetry.Exporter.Geneva; internal class ReentrantExportProcessor : BaseExportProcessor where T : class { + private static readonly Func> CreateBatch; + static ReentrantExportProcessor() { var flags = BindingFlags.Instance | BindingFlags.NonPublic; @@ -32,6 +34,4 @@ protected override void OnExport(T data) { this.exporter.Export(CreateBatch(data)); } - - private static readonly Func> CreateBatch; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index 89ad5f8195..6a3b40add1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -18,44 +18,42 @@ internal sealed class TableNameSerializer /* Note: We don't use Array.Empty here because that is used to indicate an invalid name. We need a different instance to trigger the pass-through case. */ - private static readonly byte[] s_passthroughTableName = new byte[0]; + private static readonly byte[] PassthroughTableName = new byte[0]; #pragma warning restore CA1825 // Avoid zero-length array allocations - private static readonly StringComparer s_dictionaryKeyComparer = StringComparer.Ordinal; + private static readonly StringComparer DictionaryKeyComparer = StringComparer.Ordinal; - private readonly byte[] m_defaultTableName; - private readonly Dictionary m_tableMappings; - private readonly bool m_shouldPassThruTableMappings; - private readonly object m_lockObject = new(); - private TableNameCacheDictionary m_tableNameCache = new(); - - public ITableNameCacheDictionary TableNameCache => this.m_tableNameCache; + private readonly byte[] defaultTableName; + private readonly Dictionary tableMappings; + private readonly bool shouldPassThruTableMappings; + private readonly object lockObject = new(); + private TableNameCacheDictionary tableNameCache = new(); public TableNameSerializer(GenevaExporterOptions options, string defaultTableName) { Debug.Assert(options != null, "options were null"); Debug.Assert(!string.IsNullOrWhiteSpace(defaultTableName), "defaultEventName was null or whitespace"); - this.m_defaultTableName = BuildStr8BufferForAsciiString(defaultTableName); + this.defaultTableName = BuildStr8BufferForAsciiString(defaultTableName); if (options.TableNameMappings != null) { - var tempTableMappings = new Dictionary(options.TableNameMappings.Count, s_dictionaryKeyComparer); + var tempTableMappings = new Dictionary(options.TableNameMappings.Count, DictionaryKeyComparer); foreach (var kv in options.TableNameMappings) { if (kv.Key == "*") { if (kv.Value == "*") { - this.m_shouldPassThruTableMappings = true; + this.shouldPassThruTableMappings = true; } else { - this.m_defaultTableName = BuildStr8BufferForAsciiString(kv.Value); + this.defaultTableName = BuildStr8BufferForAsciiString(kv.Value); } } else if (kv.Value == "*") { - tempTableMappings[kv.Key] = s_passthroughTableName; + tempTableMappings[kv.Key] = PassthroughTableName; } else { @@ -63,16 +61,24 @@ public TableNameSerializer(GenevaExporterOptions options, string defaultTableNam } } - this.m_tableMappings = tempTableMappings; + this.tableMappings = tempTableMappings; } } + // Note: This is used for tests. + public interface ITableNameCacheDictionary : IReadOnlyDictionary + { + int CachedSanitizedTableNameCount { get; } + } + + public ITableNameCacheDictionary TableNameCache => this.tableNameCache; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ResolveAndSerializeTableNameForCategoryName(byte[] destination, int offset, string categoryName, out ReadOnlySpan tableName) { byte[] mappedTableName = this.ResolveTableMappingForCategoryName(categoryName); - if (mappedTableName == s_passthroughTableName) + if (mappedTableName == PassthroughTableName) { // Pass-through mode with a full cache. @@ -156,7 +162,7 @@ private static int WriteSanitizedCategoryNameToSpan(Span buffer, string ca private byte[] ResolveTableMappingForCategoryName(string categoryName) { - var tableNameCache = this.m_tableNameCache; + var tableNameCache = this.tableNameCache; if (tableNameCache.TryGetValue(categoryName, out byte[] tableName)) { @@ -171,14 +177,14 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) byte[] mappedTableName = null; // If user configured table name mappings run resolution logic. - if (this.m_tableMappings != null - && !this.m_tableMappings.TryGetValue(categoryName, out mappedTableName)) + if (this.tableMappings != null + && !this.tableMappings.TryGetValue(categoryName, out mappedTableName)) { // Find best match if an exact match was not found. string currentKey = null; - foreach (var mapping in this.m_tableMappings) + foreach (var mapping in this.tableMappings) { if (!categoryName.StartsWith(mapping.Key, DictionaryKeyComparison)) { @@ -193,11 +199,11 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) } } - mappedTableName ??= !this.m_shouldPassThruTableMappings - ? this.m_defaultTableName - : s_passthroughTableName; + mappedTableName ??= !this.shouldPassThruTableMappings + ? this.defaultTableName + : PassthroughTableName; - Span sanitizedTableNameStorage = mappedTableName == s_passthroughTableName + Span sanitizedTableNameStorage = mappedTableName == PassthroughTableName ? stackalloc byte[MaxSanitizedCategoryNameBytes] : Array.Empty(); @@ -218,9 +224,9 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) } } - lock (this.m_lockObject) + lock (this.lockObject) { - var tableNameCache = this.m_tableNameCache; + var tableNameCache = this.tableNameCache; // Check if another thread added the mapping while we waited on the // lock. @@ -229,7 +235,7 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) return tableName; } - if (mappedTableName == s_passthroughTableName + if (mappedTableName == PassthroughTableName && tableNameCache.CachedSanitizedTableNameCount < MaxCachedSanitizedTableNames) { mappedTableName = sanitizedTableNameStorage.ToArray(); @@ -243,27 +249,21 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) [categoryName] = mappedTableName, }; - this.m_tableNameCache = newTableNameCache; + this.tableNameCache = newTableNameCache; return mappedTableName; } } - // Note: This is used for tests. - public interface ITableNameCacheDictionary : IReadOnlyDictionary - { - int CachedSanitizedTableNameCount { get; } - } - private sealed class TableNameCacheDictionary : Dictionary, ITableNameCacheDictionary { public TableNameCacheDictionary() - : base(0, s_dictionaryKeyComparer) + : base(0, DictionaryKeyComparer) { } public TableNameCacheDictionary(TableNameCacheDictionary sourceCache) - : base(sourceCache, s_dictionaryKeyComparer) + : base(sourceCache, DictionaryKeyComparer) { this.CachedSanitizedTableNameCount = sourceCache.CachedSanitizedTableNameCount; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 73128fb47d..07c0839445 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -29,16 +29,12 @@ public partial class GenevaMetricExporter : BaseExporter private readonly IDisposable exporter; - private delegate ExportResult ExportMetricsFunc(in Batch batch); - private readonly ExportMetricsFunc exportMetrics; private bool isDisposed; private Resource resource; - internal Resource Resource => this.resource ??= this.ParentProvider.GetResource(); - /// /// Initializes a new instance of the class. /// @@ -76,12 +72,32 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) } } + private delegate ExportResult ExportMetricsFunc(in Batch batch); + + internal Resource Resource => this.resource ??= this.ParentProvider.GetResource(); + /// public override ExportResult Export(in Batch batch) { return this.exportMetrics(batch); } + internal static PropertyInfo GetOpenTelemetryInstrumentNameRegexProperty() + { + var meterProviderBuilderSdkType = Type.GetType("OpenTelemetry.Metrics.MeterProviderBuilderSdk, OpenTelemetry", throwOnError: false) + ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk type could not be found reflectively."); + + var instrumentNameRegexProperty = meterProviderBuilderSdkType.GetProperty("InstrumentNameRegex", BindingFlags.Public | BindingFlags.Static) + ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk.InstrumentNameRegex property could not be found reflectively."); + + return instrumentNameRegexProperty; + } + + internal static void DisableOpenTelemetrySdkMetricNameValidation() + { + GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, GetDisableRegexPattern()); + } + /// protected override void Dispose(bool disposing) { @@ -99,22 +115,6 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } - internal static PropertyInfo GetOpenTelemetryInstrumentNameRegexProperty() - { - var meterProviderBuilderSdkType = Type.GetType("OpenTelemetry.Metrics.MeterProviderBuilderSdk, OpenTelemetry", throwOnError: false) - ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk type could not be found reflectively."); - - var instrumentNameRegexProperty = meterProviderBuilderSdkType.GetProperty("InstrumentNameRegex", BindingFlags.Public | BindingFlags.Static) - ?? throw new InvalidOperationException("OpenTelemetry.Metrics.MeterProviderBuilderSdk.InstrumentNameRegex property could not be found reflectively."); - - return instrumentNameRegexProperty; - } - - internal static void DisableOpenTelemetrySdkMetricNameValidation() - { - GetOpenTelemetryInstrumentNameRegexProperty().SetValue(null, GetDisableRegexPattern()); - } - #if NET8_0_OR_GREATER [GeneratedRegex(DisableRegexPattern)] private static partial Regex GetDisableRegexPattern(); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index 1533117eeb..3367d43512 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -11,8 +11,8 @@ namespace OpenTelemetry.Exporter.Geneva; /// public class GenevaMetricExporterOptions { - private IReadOnlyDictionary _prepopulatedMetricDimensions; - private int _metricExporterIntervalMilliseconds = 60000; + private IReadOnlyDictionary prepopulatedMetricDimensions; + private int metricExporterIntervalMilliseconds = 60000; /// /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. @@ -27,14 +27,14 @@ public int MetricExportIntervalMilliseconds { get { - return this._metricExporterIntervalMilliseconds; + return this.metricExporterIntervalMilliseconds; } set { Guard.ThrowIfOutOfRange(value, min: 1000); - this._metricExporterIntervalMilliseconds = value; + this.metricExporterIntervalMilliseconds = value; } } @@ -45,7 +45,7 @@ public IReadOnlyDictionary PrepopulatedMetricDimensions { get { - return this._prepopulatedMetricDimensions; + return this.prepopulatedMetricDimensions; } set @@ -81,7 +81,7 @@ public IReadOnlyDictionary PrepopulatedMetricDimensions copy[entry.Key] = entry.Value; // shallow copy } - this._prepopulatedMetricDimensions = copy; + this.prepopulatedMetricDimensions = copy; } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs index a5e38553ea..07912927c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs @@ -7,6 +7,164 @@ namespace OpenTelemetry.Exporter.Geneva; +#pragma warning disable SA1649 // File name should match first type name + +internal enum MetricEventType +{ + ULongMetric = 50, + DoubleMetric = 55, + ExternallyAggregatedULongDistributionMetric = 56, + TLV = 70, +} + +internal enum PayloadType +{ + AccountName = 1, + Namespace = 2, + MetricName = 3, + Dimensions = 4, + ULongMetric = 5, + DoubleMetric = 6, + ExternallyAggregatedULongDistributionMetric = 8, + HistogramULongValueCountPairs = 12, + Exemplars = 15, +} + +[Flags] +internal enum ExemplarFlags : byte +{ + None = 0x0, + IsMetricValueDoubleStoredAsLong = 0x1, + IsTimestampAvailable = 0x2, + SpanIdExists = 0x4, + TraceIdExists = 0x8, + SampleCountExists = 0x10, +} + +/// +/// Represents the binary header for non-ETW transmitted metrics. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct BinaryHeader +{ + /// + /// The event ID that represents how it will be processed. + /// + [FieldOffset(0)] + public ushort EventId; + + /// + /// The length of the body following the header. + /// + [FieldOffset(2)] + public ushort BodyLength; +} + +/// +/// Represents the fixed payload of a standard metric. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct MetricPayload +{ + /// + /// The dimension count. + /// + [FieldOffset(0)] + public ushort CountDimension; + + /// + /// Reserved for alignment. + /// + [FieldOffset(2)] + public ushort ReservedWord; // for 8-byte aligned + + /// + /// Reserved for alignment. + /// + [FieldOffset(4)] + public uint ReservedDword; + + /// + /// The UTC timestamp of the metric. + /// + [FieldOffset(8)] + public ulong TimestampUtc; + + /// + /// The value of the metric. + /// + [FieldOffset(16)] + public MetricData Data; +} + +/// +/// Represents the fixed payload of an externally aggregated metric. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct ExternalPayload +{ + /// + /// The dimension count. + /// + [FieldOffset(0)] + public ushort CountDimension; + + /// + /// Reserved for alignment. + /// + [FieldOffset(2)] + public ushort ReservedWord; // for alignment + + /// + /// The number of samples produced in the period. + /// + [FieldOffset(4)] + public uint Count; + + /// + /// The UTC timestamp of the metric. + /// + [FieldOffset(8)] + public ulong TimestampUtc; + + /// + /// The sum of the samples produced in the period. + /// + [FieldOffset(16)] + public MetricData Sum; + + /// + /// The minimum value of the samples produced in the period. + /// + [FieldOffset(24)] + public MetricData Min; + + /// + /// The maximum value of the samples produced in the period. + /// + [FieldOffset(32)] + public MetricData Max; +} + +/// +/// Represents the value of a metric. +/// +[StructLayout(LayoutKind.Explicit)] +internal struct MetricData +{ + /// + /// The value represented as an integer. + /// + [FieldOffset(0)] + public ulong UInt64Value; + + /// + /// The value represented as a double. + /// + [FieldOffset(0)] + public double DoubleValue; +} + internal static class MetricSerializer { /// @@ -363,159 +521,3 @@ public static void SerializeSpanOfBytes(byte[] buffer, ref int bufferIndex, Span bufferIndex += dataLength; } } - -internal enum MetricEventType -{ - ULongMetric = 50, - DoubleMetric = 55, - ExternallyAggregatedULongDistributionMetric = 56, - TLV = 70, -} - -internal enum PayloadType -{ - AccountName = 1, - Namespace = 2, - MetricName = 3, - Dimensions = 4, - ULongMetric = 5, - DoubleMetric = 6, - ExternallyAggregatedULongDistributionMetric = 8, - HistogramULongValueCountPairs = 12, - Exemplars = 15, -} - -[Flags] -internal enum ExemplarFlags : byte -{ - None = 0x0, - IsMetricValueDoubleStoredAsLong = 0x1, - IsTimestampAvailable = 0x2, - SpanIdExists = 0x4, - TraceIdExists = 0x8, - SampleCountExists = 0x10, -} - -/// -/// Represents the binary header for non-ETW transmitted metrics. -/// -[StructLayout(LayoutKind.Explicit)] -internal struct BinaryHeader -{ - /// - /// The event ID that represents how it will be processed. - /// - [FieldOffset(0)] - public ushort EventId; - - /// - /// The length of the body following the header. - /// - [FieldOffset(2)] - public ushort BodyLength; -} - -/// -/// Represents the fixed payload of a standard metric. -/// -[StructLayout(LayoutKind.Explicit)] -internal struct MetricPayload -{ - /// - /// The dimension count. - /// - [FieldOffset(0)] - public ushort CountDimension; - - /// - /// Reserved for alignment. - /// - [FieldOffset(2)] - public ushort ReservedWord; // for 8-byte aligned - - /// - /// Reserved for alignment. - /// - [FieldOffset(4)] - public uint ReservedDword; - - /// - /// The UTC timestamp of the metric. - /// - [FieldOffset(8)] - public ulong TimestampUtc; - - /// - /// The value of the metric. - /// - [FieldOffset(16)] - public MetricData Data; -} - -/// -/// Represents the fixed payload of an externally aggregated metric. -/// -[StructLayout(LayoutKind.Explicit)] -internal struct ExternalPayload -{ - /// - /// The dimension count. - /// - [FieldOffset(0)] - public ushort CountDimension; - - /// - /// Reserved for alignment. - /// - [FieldOffset(2)] - public ushort ReservedWord; // for alignment - - /// - /// The number of samples produced in the period. - /// - [FieldOffset(4)] - public uint Count; - - /// - /// The UTC timestamp of the metric. - /// - [FieldOffset(8)] - public ulong TimestampUtc; - - /// - /// The sum of the samples produced in the period. - /// - [FieldOffset(16)] - public MetricData Sum; - - /// - /// The minimum value of the samples produced in the period. - /// - [FieldOffset(24)] - public MetricData Min; - - /// - /// The maximum value of the samples produced in the period. - /// - [FieldOffset(32)] - public MetricData Max; -} - -/// -/// Represents the value of a metric. -/// -[StructLayout(LayoutKind.Explicit)] -internal struct MetricData -{ - /// - /// The value represented as an integer. - /// - [FieldOffset(0)] - public ulong UInt64Value; - - /// - /// The value represented as a double. - /// - [FieldOffset(0)] - public double DoubleValue; -} diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 40019f14ff..4680b09887 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -9,50 +9,31 @@ namespace OpenTelemetry.Exporter.Geneva; internal sealed class OtlpProtobufSerializer { + internal IMetricDataTransport MetricDataTransport; + private const int TagAndLengthSize = 4; private readonly Dictionary> scopeMetrics = new(); - private readonly string metricNamespace; - private readonly string metricAccount; - private readonly byte[] prepopulatedNumberDataPointAttributes; - private readonly int prepopulatedNumberDataPointAttributesLength; - private readonly byte[] prepopulatedHistogramDataPointAttributes; - private readonly int prepopulatedHistogramDataPointAttributesLength; - private readonly byte[] prepopulatedExponentialHistogramDataPointAttributes; - private readonly int prepopulatedExponentialHistogramDataPointAttributesLength; - private int resourceMetricTagAndLengthIndex; - private int scopeMetricsTagAndLengthIndex; - private int metricTagAndLengthIndex; - private int instrumentTagAndLengthIndex; - private int metricPointTagAndLengthIndex; - private int resourceMetricValueIndex; - private int scopeMetricsValueIndex; - private int metricValueIndex; - private int instrumentValueIndex; - private int metricPointValueIndex; - private ExportResult metricExportResult; - internal IMetricDataTransport MetricDataTransport; - public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) { this.MetricDataTransport = metricDataTransport; @@ -100,6 +81,105 @@ public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, Connecti } } + internal static void WriteInstrumentDetails(byte[] buffer, ref int cursor, Metric metric) + { + // Write metric name + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_name, metric.Name); + + // Write metric description + if (metric.Description != null) + { + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_description, metric.Description); + } + + // Write metric unit + if (metric.Unit != null) + { + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_unit, metric.Unit); + } + } + + internal static void SerializeInstrumentationScope(byte[] buffer, ref int cursor, string name, IEnumerable> meterTags) + { + int tagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int valueIndex = cursor; + + // Write name + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.InstrumentationScope_name, name); + + SerializeTags(buffer, ref cursor, meterTags, FieldNumberConstants.InstrumentationScope_attributes); + + // Write instrumentation Scope Tag + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref tagAndLengthIndex, cursor - valueIndex, FieldNumberConstants.ScopeMetrics_scope, WireType.LEN); + } + + internal static void SerializeTags(byte[] buffer, ref int cursor, ReadOnlyTagCollection tags, int fieldNumber) + { + foreach (var tag in tags) + { + if (tag.Value != null) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, fieldNumber); + } + } + } + + internal static void SerializeTag(byte[] buffer, ref int cursor, string key, object value, int fieldNumber) + { + try + { + // TODO : Check if calculating the length in advance could be more efficient in this case. + // That way we wouldn't have to leave the fixed length space. + int keyValueTagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int keyValueIndex = cursor; + + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.KeyValue_key, key); + + int anyValueTagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int anyValueIndex = cursor; + + switch (value) + { + case char: + case string: + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); + break; + case bool b: + ProtobufSerializerHelper.WriteBoolWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_bool_value, (bool)value); + break; + case byte: + case sbyte: + case short: + case ushort: + case int: + case uint: + case long: + case ulong: + ProtobufSerializerHelper.WriteInt64WithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_int_value, (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture)); + break; + case float: + case double: + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_double_value, Convert.ToDouble(value, CultureInfo.InvariantCulture)); + break; + default: + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); + break; + + // TODO: Handle array type. + } + + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref anyValueTagAndLengthIndex, cursor - anyValueIndex, FieldNumberConstants.KeyValue_value, WireType.LEN); + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref keyValueTagAndLengthIndex, cursor - keyValueIndex, fieldNumber, WireType.LEN); + } + catch + { + // TODO: log exception. + } + } + internal ExportResult SerializeAndSendMetrics(byte[] buffer, Resource resource, in Batch metricBatch) { this.metricExportResult = ExportResult.Success; @@ -185,6 +265,65 @@ internal void SerializeScopeMetrics(byte[] buffer, ref int cursor, string scopeN // TODO: Serialize schema_url field. } + private static void SerializeExemplar(byte[] buffer, ref int cursor, in Exemplar exemplar, T value, int fieldNumber) + { + int exemplarTagAndLengthIndex = cursor; + cursor += TagAndLengthSize; + int valueIndex = cursor; + + SerializeExemplarTags(buffer, ref cursor, exemplar.FilteredTags); + + if (typeof(T) == typeof(long)) + { + // Casting to ulong is ok here as the bit representation for long versus ulong will be the same + // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_int, (ulong)(long)(object)value); + } + else if (typeof(T) == typeof(double)) + { + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_double, (double)(object)value); + } + + var time = (ulong)exemplar.Timestamp.ToUnixTimeNanoseconds(); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_time_unix_nano, time); + + if (exemplar.SpanId != default) + { + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref cursor, 16, FieldNumberConstants.Exemplar_trace_id, WireType.LEN); + var traceBytes = new Span(buffer, cursor, 16); + exemplar.TraceId.CopyTo(traceBytes); + cursor += 16; + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref cursor, 8, FieldNumberConstants.Exemplar_span_id, WireType.LEN); + var spanBytes = new Span(buffer, cursor, 8); + exemplar.SpanId.CopyTo(spanBytes); + cursor += 8; + } + + ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref exemplarTagAndLengthIndex, cursor - valueIndex, fieldNumber, WireType.LEN); + } + + private static void SerializeExemplarTags(byte[] buffer, ref int cursor, ReadOnlyFilteredTagCollection tags) + { + foreach (var tag in tags) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, FieldNumberConstants.Exemplar_attributes); + } + } + + private static void SerializeTags(byte[] buffer, ref int cursor, IEnumerable> attributes, int fieldNumber) + { + if (attributes != null) + { + foreach (var tag in attributes) + { + if (tag.Value != null) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, fieldNumber); + } + } + } + } + private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) { WriteInstrumentDetails(buffer, ref cursor, metric); @@ -396,7 +535,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) { foreach (ref readonly var exemplar in exemplars) { - this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.HistogramDataPoint_exemplars); + SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.HistogramDataPoint_exemplars); } } @@ -489,7 +628,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) { foreach (ref readonly var exemplar in exemplars) { - this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.ExponentialHistogramDataPoint_exemplars); + SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.ExponentialHistogramDataPoint_exemplars); } } @@ -549,11 +688,11 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum { if (typeof(T) == typeof(long)) { - this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.LongValue, FieldNumberConstants.NumberDataPoint_exemplars); + SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.LongValue, FieldNumberConstants.NumberDataPoint_exemplars); } else if (typeof(T) == typeof(double)) { - this.SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.NumberDataPoint_exemplars); + SerializeExemplar(buffer, ref cursor, in exemplar, exemplar.DoubleValue, FieldNumberConstants.NumberDataPoint_exemplars); } } } @@ -564,51 +703,6 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref metricPointStartPosition, cursor - this.metricPointValueIndex, fieldNumber, WireType.LEN); } - private void SerializeExemplar(byte[] buffer, ref int cursor, in Exemplar exemplar, T value, int fieldNumber) - { - int exemplarTagAndLengthIndex = cursor; - cursor += TagAndLengthSize; - int valueIndex = cursor; - - this.SerializeExemplarTags(buffer, ref cursor, exemplar.FilteredTags); - - if (typeof(T) == typeof(long)) - { - // Casting to ulong is ok here as the bit representation for long versus ulong will be the same - // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_int, (ulong)(long)(object)value); - } - else if (typeof(T) == typeof(double)) - { - ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_double, (double)(object)value); - } - - var time = (ulong)exemplar.Timestamp.ToUnixTimeNanoseconds(); - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_time_unix_nano, time); - - if (exemplar.SpanId != default) - { - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref cursor, 16, FieldNumberConstants.Exemplar_trace_id, WireType.LEN); - var traceBytes = new Span(buffer, cursor, 16); - exemplar.TraceId.CopyTo(traceBytes); - cursor += 16; - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref cursor, 8, FieldNumberConstants.Exemplar_span_id, WireType.LEN); - var spanBytes = new Span(buffer, cursor, 8); - exemplar.SpanId.CopyTo(spanBytes); - cursor += 8; - } - - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref exemplarTagAndLengthIndex, cursor - valueIndex, fieldNumber, WireType.LEN); - } - - private void SerializeExemplarTags(byte[] buffer, ref int cursor, ReadOnlyFilteredTagCollection tags) - { - foreach (var tag in tags) - { - SerializeTag(buffer, ref cursor, tag.Key, tag.Value, FieldNumberConstants.Exemplar_attributes); - } - } - private void WriteIndividualMessageTagsAndLength(byte[] buffer, ref int cursor, MetricType metricType) { var instrumentIndex = this.instrumentTagAndLengthIndex; @@ -638,53 +732,6 @@ private void SendMetricPoint(byte[] buffer, ref int cursor) this.MetricDataTransport.SendOtlpProtobufEvent(buffer, cursor); } - internal static void WriteInstrumentDetails(byte[] buffer, ref int cursor, Metric metric) - { - // Write metric name - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_name, metric.Name); - - // Write metric description - if (metric.Description != null) - { - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_description, metric.Description); - } - - // Write metric unit - if (metric.Unit != null) - { - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.Metric_unit, metric.Unit); - } - } - - internal static void SerializeInstrumentationScope(byte[] buffer, ref int cursor, string name, IEnumerable> meterTags) - { - int tagAndLengthIndex = cursor; - cursor += TagAndLengthSize; - int valueIndex = cursor; - - // Write name - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.InstrumentationScope_name, name); - - SerializeTags(buffer, ref cursor, meterTags, FieldNumberConstants.InstrumentationScope_attributes); - - // Write instrumentation Scope Tag - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref tagAndLengthIndex, cursor - valueIndex, FieldNumberConstants.ScopeMetrics_scope, WireType.LEN); - } - - private static void SerializeTags(byte[] buffer, ref int cursor, IEnumerable> attributes, int fieldNumber) - { - if (attributes != null) - { - foreach (var tag in attributes) - { - if (tag.Value != null) - { - SerializeTag(buffer, ref cursor, tag.Key, tag.Value, fieldNumber); - } - } - } - } - private void SerializeResource(byte[] buffer, ref int cursor, Resource resource) { if (resource != Resource.Empty) @@ -709,70 +756,4 @@ private void SerializeResource(byte[] buffer, ref int cursor, Resource resource) ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref tagAndLengthIndex, cursor - valueIndex, FieldNumberConstants.ResourceMetrics_resource, WireType.LEN); } } - - internal static void SerializeTags(byte[] buffer, ref int cursor, ReadOnlyTagCollection tags, int fieldNumber) - { - foreach (var tag in tags) - { - if (tag.Value != null) - { - SerializeTag(buffer, ref cursor, tag.Key, tag.Value, fieldNumber); - } - } - } - - internal static void SerializeTag(byte[] buffer, ref int cursor, string key, object value, int fieldNumber) - { - try - { - // TODO : Check if calculating the length in advance could be more efficient in this case. - // That way we wouldn't have to leave the fixed length space. - int keyValueTagAndLengthIndex = cursor; - cursor += TagAndLengthSize; - int keyValueIndex = cursor; - - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.KeyValue_key, key); - - int anyValueTagAndLengthIndex = cursor; - cursor += TagAndLengthSize; - int anyValueIndex = cursor; - - switch (value) - { - case char: - case string: - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); - break; - case bool b: - ProtobufSerializerHelper.WriteBoolWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_bool_value, (bool)value); - break; - case byte: - case sbyte: - case short: - case ushort: - case int: - case uint: - case long: - case ulong: - ProtobufSerializerHelper.WriteInt64WithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_int_value, (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture)); - break; - case float: - case double: - ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_double_value, Convert.ToDouble(value, CultureInfo.InvariantCulture)); - break; - default: - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); - break; - - // TODO: Handle array type. - } - - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref anyValueTagAndLengthIndex, cursor - anyValueIndex, FieldNumberConstants.KeyValue_value, WireType.LEN); - ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref keyValueTagAndLengthIndex, cursor - keyValueIndex, fieldNumber, WireType.LEN); - } - catch - { - // TODO: log exception. - } - } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs index 74f06185fb..9cfaa5a172 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -11,12 +11,12 @@ internal static class ProtobufSerializerHelper { private const int Fixed64Size = 8; - internal static Encoding Utf8Encoding => Encoding.UTF8; - private const ulong Ulong128 = 128; private const uint Uint128 = 128; + internal static Encoding Utf8Encoding => Encoding.UTF8; + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void WriteStringTag(byte[] buffer, ref int cursor, int fieldNumber, string value) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 8d05817fd5..0931510cde 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -12,19 +12,12 @@ namespace OpenTelemetry.Exporter.Geneva.Metrics; internal sealed class TlvMetricExporter : IDisposable { private readonly ushort prepopulatedDimensionsCount; - private readonly int fixedPayloadStartIndex; - private readonly IMetricDataTransport metricDataTransport; - private readonly List serializedPrepopulatedDimensionsKeys; - private readonly List serializedPrepopulatedDimensionsValues; - private readonly byte[] buffer = new byte[GenevaMetricExporter.BufferSize]; - private readonly string defaultMonitoringAccount; - private readonly string defaultMetricNamespace; private bool isDisposed; @@ -73,6 +66,30 @@ internal TlvMetricExporter(ConnectionStringBuilder connectionStringBuilder, IRea } } + public void Dispose() + { + if (this.isDisposed) + { + return; + } + + try + { + // The ETW data transport singleton on Windows should NOT be disposed. + // On Linux, Unix Domain Socket is used and should be disposed. + if (this.metricDataTransport != MetricEtwDataTransport.Instance) + { + this.metricDataTransport.Dispose(); + } + + this.isDisposed = true; + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("TlvMetricExporter Dispose failed.", ex); + } + } + internal ExportResult Export(in Batch batch) { string monitoringAccount = this.defaultMonitoringAccount; @@ -226,30 +243,6 @@ internal ExportResult Export(in Batch batch) return result; } - public void Dispose() - { - if (this.isDisposed) - { - return; - } - - try - { - // The ETW data transport singleton on Windows should NOT be disposed. - // On Linux, Unix Domain Socket is used and should be disposed. - if (this.metricDataTransport != MetricEtwDataTransport.Instance) - { - this.metricDataTransport.Dispose(); - } - - this.isDisposed = true; - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("TlvMetricExporter Dispose failed.", ex); - } - } - internal unsafe ushort SerializeMetricWithTLV( MetricEventType eventType, string metricName, diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 121cb88d1f..2aea97934b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -15,8 +15,6 @@ internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport private readonly int fixedPayloadEndIndex; private bool isDisposed; - public static MetricEtwDataTransport Instance { get; private set; } = new(); - private MetricEtwDataTransport() { unsafe @@ -25,6 +23,8 @@ private MetricEtwDataTransport() } } + public static MetricEtwDataTransport Instance { get; private set; } = new(); + [NonEvent] #if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] @@ -62,27 +62,27 @@ public unsafe void SendOtlpProtobufEvent(byte[] data, int size) } [Event(OtlpProtobufMetricEventId)] - private void OtlpProtobufEvent() + public void OtlpProtobufEvent() { } [Event((int)MetricEventType.ULongMetric)] - private void ULongMetricEvent() + public void ULongMetricEvent() { } [Event((int)MetricEventType.DoubleMetric)] - private void DoubleMetricEvent() + public void DoubleMetricEvent() { } [Event((int)MetricEventType.ExternallyAggregatedULongDistributionMetric)] - private void ExternallyAggregatedDoubleDistributionMetric() + public void ExternallyAggregatedDoubleDistributionMetric() { } [Event((int)MetricEventType.TLV)] - private void TLVMetricEvent() + public void TLVMetricEvent() { } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs index ec3e8050b7..d5a97bbe75 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs @@ -309,12 +309,6 @@ public static int SerializeFloat32(byte[] buffer, int cursor, float value) return WriteInt32(buffer, cursor, Float32ToInt32(value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe int Float32ToInt32(float value) - { - return *(int*)&value; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeFloat64(byte[] buffer, int cursor, double value) { @@ -322,12 +316,6 @@ public static int SerializeFloat64(byte[] buffer, int cursor, double value) return WriteInt64(buffer, cursor, Float64ToInt64(value)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe long Float64ToInt64(double value) - { - return *(long*)&value; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void WriteStr8Header(byte[] buffer, int nameStartIdx, int validNameLength) { @@ -676,4 +664,16 @@ public static int SerializeSpan(byte[] buffer, int cursor, ReadOnlySpan va return cursor + length; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe long Float64ToInt64(double value) + { + return *(long*)&value; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static unsafe int Float32ToInt32(float value) + { + return *(int*)&value; + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 0a143cd39a..0ddd57fc80 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -17,38 +17,41 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable { private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - private static readonly ThreadLocal m_buffer = new ThreadLocal(() => null); - private static readonly string[] logLevels = new string[7] + private static readonly ThreadLocal Buffer = new(); + private static readonly Action ProcessScopeForIndividualColumnsAction = OnProcessScopeForIndividualColumns; + private static readonly Action ProcessScopeForEnvPropertiesAction = OnProcessScopeForEnvProperties; + private static readonly string[] LogLevels = new string[7] { "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", }; - private readonly bool m_shouldExportEventName; - private readonly TableNameSerializer m_tableNameSerializer; + private readonly bool shouldExportEventName; + private readonly TableNameSerializer tableNameSerializer; #if NET8_0_OR_GREATER - private readonly FrozenSet m_customFields; - private readonly FrozenDictionary m_prepopulatedFields; + private readonly FrozenSet customFields; + private readonly FrozenDictionary prepopulatedFields; #else - private readonly HashSet m_customFields; - private readonly Dictionary m_prepopulatedFields; + private readonly HashSet customFields; + private readonly Dictionary prepopulatedFields; #endif - private readonly ExceptionStackExportMode m_exportExceptionStack; - private readonly List m_prepopulatedFieldKeys; - private readonly byte[] m_bufferEpilogue; - private readonly IDataTransport m_dataTransport; + private readonly ExceptionStackExportMode exportExceptionStack; + private readonly List prepopulatedFieldKeys; + private readonly byte[] bufferEpilogue; + private readonly IDataTransport dataTransport; // This is used for Scopes - private readonly ThreadLocal m_serializationData = new(() => null); + private readonly ThreadLocal serializationData = new(); + private bool isDisposed; public MsgPackLogExporter(GenevaExporterOptions options) { - this.m_tableNameSerializer = new(options, defaultTableName: "Log"); - this.m_exportExceptionStack = options.ExceptionStackExportMode; + this.tableNameSerializer = new(options, defaultTableName: "Log"); + this.exportExceptionStack = options.ExceptionStackExportMode; - this.m_shouldExportEventName = (options.EventNameExportMode & EventNameExportMode.ExportAsPartAName) != 0; + this.shouldExportEventName = (options.EventNameExportMode & EventNameExportMode.ExportAsPartAName) != 0; var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); switch (connectionStringBuilder.Protocol) @@ -59,7 +62,7 @@ public MsgPackLogExporter(GenevaExporterOptions options) throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); } - this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); + this.dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); break; case TransportProtocol.Unix: if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -68,7 +71,7 @@ public MsgPackLogExporter(GenevaExporterOptions options) } var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); + this.dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; default: throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); @@ -76,18 +79,18 @@ public MsgPackLogExporter(GenevaExporterOptions options) if (options.PrepopulatedFields != null) { - this.m_prepopulatedFieldKeys = new List(); + this.prepopulatedFieldKeys = new List(); var tempPrepopulatedFields = new Dictionary(options.PrepopulatedFields.Count, StringComparer.Ordinal); foreach (var kv in options.PrepopulatedFields) { tempPrepopulatedFields[kv.Key] = kv.Value; - this.m_prepopulatedFieldKeys.Add(kv.Key); + this.prepopulatedFieldKeys.Add(kv.Key); } #if NET8_0_OR_GREATER - this.m_prepopulatedFields = tempPrepopulatedFields.ToFrozenDictionary(StringComparer.Ordinal); + this.prepopulatedFields = tempPrepopulatedFields.ToFrozenDictionary(StringComparer.Ordinal); #else - this.m_prepopulatedFields = tempPrepopulatedFields; + this.prepopulatedFields = tempPrepopulatedFields; #endif } @@ -101,18 +104,20 @@ public MsgPackLogExporter(GenevaExporterOptions options) } #if NET8_0_OR_GREATER - this.m_customFields = customFields.ToFrozenSet(StringComparer.Ordinal); + this.customFields = customFields.ToFrozenSet(StringComparer.Ordinal); #else - this.m_customFields = customFields; + this.customFields = customFields; #endif } var buffer = new byte[BUFFER_SIZE]; var cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); - this.m_bufferEpilogue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + this.bufferEpilogue = new byte[cursor - 0]; + System.Buffer.BlockCopy(buffer, 0, this.bufferEpilogue, 0, cursor - 0); } + internal bool IsUsingUnixDomainSocket => this.dataTransport is UnixDomainSocketDataTransport; + public ExportResult Export(in Batch batch) { var result = ExportResult.Success; @@ -121,7 +126,7 @@ public ExportResult Export(in Batch batch) try { var cursor = this.SerializeLogRecord(logRecord); - this.m_dataTransport.Send(m_buffer.Value, cursor - 0); + this.dataTransport.Send(Buffer.Value, cursor - 0); } catch (Exception ex) { @@ -135,9 +140,26 @@ public ExportResult Export(in Batch batch) return result; } - internal bool IsUsingUnixDomainSocket + public void Dispose() { - get => this.m_dataTransport is UnixDomainSocketDataTransport; + if (this.isDisposed) + { + return; + } + + // DO NOT Dispose m_buffer as it is a static type + try + { + (this.dataTransport as IDisposable)?.Dispose(); + this.serializationData.Dispose(); + this.prepopulatedFieldKeys.Clear(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("MsgPackLogExporter Dispose failed.", ex); + } + + this.isDisposed = true; } internal int SerializeLogRecord(LogRecord logRecord) @@ -156,11 +178,11 @@ internal int SerializeLogRecord(LogRecord logRecord) } #pragma warning restore 0618 - var buffer = m_buffer.Value; + var buffer = Buffer.Value; if (buffer == null) { buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM - m_buffer.Value = buffer; + Buffer.Value = buffer; } /* Fluentd Forward Mode: @@ -189,7 +211,7 @@ internal int SerializeLogRecord(LogRecord logRecord) var categoryName = logRecord.CategoryName; - cursor = this.m_tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, cursor, categoryName, out ReadOnlySpan eventName); + cursor = this.tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, cursor, categoryName, out ReadOnlySpan eventName); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); @@ -198,12 +220,12 @@ internal int SerializeLogRecord(LogRecord logRecord) ushort cntFields = 0; var idxMapSizePatch = cursor - 2; - if (this.m_prepopulatedFieldKeys != null) + if (this.prepopulatedFieldKeys != null) { - for (int i = 0; i < this.m_prepopulatedFieldKeys.Count; i++) + for (int i = 0; i < this.prepopulatedFieldKeys.Count; i++) { - var key = this.m_prepopulatedFieldKeys[i]; - var value = this.m_prepopulatedFields[key]; + var key = this.prepopulatedFieldKeys[i]; + var value = this.prepopulatedFields[key]; cursor = AddPartAField(buffer, cursor, key, value); cntFields += 1; } @@ -214,7 +236,7 @@ internal int SerializeLogRecord(LogRecord logRecord) var eventId = logRecord.EventId; bool hasEventId = eventId != default; - if (hasEventId && this.m_shouldExportEventName && !string.IsNullOrWhiteSpace(eventId.Name)) + if (hasEventId && this.shouldExportEventName && !string.IsNullOrWhiteSpace(eventId.Name)) { // Export `eventId.Name` as the value for `env_name` cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, eventId.Name); @@ -256,7 +278,7 @@ internal int SerializeLogRecord(LogRecord logRecord) #pragma warning restore 0618 cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityText"); - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, logLevels[(int)logLevel]); + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, LogLevels[(int)logLevel]); cntFields += 1; cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "severityNumber"); @@ -280,7 +302,7 @@ internal int SerializeLogRecord(LogRecord logRecord) bodyPopulated = true; continue; } - else if (this.m_customFields == null || this.m_customFields.Contains(entry.Key)) + else if (this.customFields == null || this.customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. if (entry.Value != null) @@ -324,7 +346,7 @@ internal int SerializeLogRecord(LogRecord logRecord) } // Prepare state for scopes - var dataForScopes = this.m_serializationData.Value; + var dataForScopes = this.serializationData.Value; if (dataForScopes == null) { dataForScopes = new SerializationDataForScopes @@ -332,14 +354,14 @@ internal int SerializeLogRecord(LogRecord logRecord) Buffer = buffer, }; - this.m_serializationData.Value = dataForScopes; + this.serializationData.Value = dataForScopes; } dataForScopes.Cursor = cursor; dataForScopes.FieldsCount = cntFields; dataForScopes.HasEnvProperties = hasEnvProperties; - logRecord.ForEachScope(ProcessScopeForIndividualColumns, this); + logRecord.ForEachScope(ProcessScopeForIndividualColumnsAction, this); // Update the variables that could have been modified in ProcessScopeForIndividualColumns hasEnvProperties = dataForScopes.HasEnvProperties; @@ -357,7 +379,7 @@ internal int SerializeLogRecord(LogRecord logRecord) for (int i = 0; i < listKvp.Count; i++) { var entry = listKvp[i]; - if (entry.Key == "{OriginalFormat}" || this.m_customFields.Contains(entry.Key)) + if (entry.Key == "{OriginalFormat}" || this.customFields.Contains(entry.Key)) { continue; } @@ -373,7 +395,7 @@ internal int SerializeLogRecord(LogRecord logRecord) dataForScopes.Cursor = cursor; dataForScopes.EnvPropertiesCount = envPropertiesCount; - logRecord.ForEachScope(ProcessScopeForEnvProperties, this); + logRecord.ForEachScope(ProcessScopeForEnvPropertiesAction, this); // Update the variables that could have been modified in ProcessScopeForEnvProperties cursor = dataForScopes.Cursor; @@ -401,7 +423,7 @@ internal int SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); cntFields += 1; - if (this.m_exportExceptionStack == ExceptionStackExportMode.ExportAsString) + if (this.exportExceptionStack == ExceptionStackExportMode.ExportAsString) { // The current approach relies on the existing trim // capabilities which trims string in excess of STRING_SIZE_LIMIT_CHAR_COUNT @@ -418,8 +440,8 @@ internal int SerializeLogRecord(LogRecord logRecord) } MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); - Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); - cursor += this.m_bufferEpilogue.Length; + System.Buffer.BlockCopy(this.bufferEpilogue, 0, buffer, cursor, this.bufferEpilogue.Length); + cursor += this.bufferEpilogue.Length; return cursor; } @@ -453,32 +475,10 @@ private static byte GetSeverityNumber(LogLevel logLevel) } } - public void Dispose() + private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, MsgPackLogExporter state) { - if (this.isDisposed) - { - return; - } - - // DO NOT Dispose m_buffer as it is a static type - try - { - (this.m_dataTransport as IDisposable)?.Dispose(); - this.m_serializationData.Dispose(); - this.m_prepopulatedFieldKeys.Clear(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("MsgPackLogExporter Dispose failed.", ex); - } - - this.isDisposed = true; - } - - private static readonly Action ProcessScopeForIndividualColumns = (scope, state) => - { - var stateData = state.m_serializationData.Value; - var customFields = state.m_customFields; + var stateData = state.serializationData.Value; + var customFields = state.customFields; foreach (KeyValuePair scopeItem in scope) { @@ -502,12 +502,12 @@ public void Dispose() stateData.HasEnvProperties = true; } } - }; + } - private static readonly Action ProcessScopeForEnvProperties = (scope, state) => + private static void OnProcessScopeForEnvProperties(LogRecordScope scope, MsgPackLogExporter state) { - var stateData = state.m_serializationData.Value; - var customFields = state.m_customFields; + var stateData = state.serializationData.Value; + var customFields = state.customFields; foreach (KeyValuePair scopeItem in scope) { @@ -523,7 +523,7 @@ public void Dispose() stateData.EnvPropertiesCount += 1; } } - }; + } private sealed class SerializationDataForScopes { diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index bddd2ba478..b32e1622dd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -12,6 +12,55 @@ namespace OpenTelemetry.Exporter.Geneva; internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable { + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + + private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); + + private static readonly Dictionary CS40_PART_B_MAPPING_DICTIONARY = new() + { + ["db.system"] = "dbSystem", + ["db.name"] = "dbName", + ["db.statement"] = "dbStatement", + + ["http.method"] = "httpMethod", + ["http.request.method"] = "httpMethod", + ["http.url"] = "httpUrl", + ["url.full"] = "httpUrl", + ["http.status_code"] = "httpStatusCode", + ["http.response.status_code"] = "httpStatusCode", + + ["messaging.system"] = "messagingSystem", + ["messaging.destination"] = "messagingDestination", + ["messaging.url"] = "messagingUrl", + }; + +#if NET8_0_OR_GREATER + private static readonly FrozenDictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY.ToFrozenDictionary(); +#else + private static readonly Dictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY; +#endif + + private readonly ThreadLocal buffer = new(); + private readonly byte[] bufferPrologue; + private readonly byte[] bufferEpilogue; + private readonly ushort prepopulatedFieldsCount; + private readonly int timestampPatchIndex; + private readonly int mapSizePatchIndex; + private readonly IDataTransport dataTransport; + private readonly bool shouldIncludeTraceState; + +#if NET8_0_OR_GREATER + private readonly FrozenSet customFields; + + private readonly FrozenSet dedicatedFields; +#else + private readonly HashSet customFields; + + private readonly HashSet dedicatedFields; +#endif + + private bool isDisposed; + public MsgPackTraceExporter(GenevaExporterOptions options) { var partAName = "Span"; @@ -30,7 +79,7 @@ public MsgPackTraceExporter(GenevaExporterOptions options) throw new ArgumentException("ETW cannot be used on non-Windows operating systems."); } - this.m_dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); + this.dataTransport = new EtwDataTransport(connectionStringBuilder.EtwSession); break; case TransportProtocol.Unix: if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -39,7 +88,7 @@ public MsgPackTraceExporter(GenevaExporterOptions options) } var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.m_dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); + this.dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; default: throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); @@ -68,9 +117,9 @@ public MsgPackTraceExporter(GenevaExporterOptions options) } #if NET8_0_OR_GREATER - this.m_customFields = customFields.ToFrozenSet(StringComparer.Ordinal); + this.customFields = customFields.ToFrozenSet(StringComparer.Ordinal); #else - this.m_customFields = customFields; + this.customFields = customFields; #endif foreach (var name in CS40_PART_B_MAPPING.Keys) @@ -82,13 +131,13 @@ public MsgPackTraceExporter(GenevaExporterOptions options) dedicatedFields.Add("otel.status_description"); #if NET8_0_OR_GREATER - this.m_dedicatedFields = dedicatedFields.ToFrozenSet(StringComparer.Ordinal); + this.dedicatedFields = dedicatedFields.ToFrozenSet(StringComparer.Ordinal); #else - this.m_dedicatedFields = dedicatedFields; + this.dedicatedFields = dedicatedFields; #endif } - this.m_shouldIncludeTraceState = options.IncludeTraceStateForSpan; + this.shouldIncludeTraceState = options.IncludeTraceStateForSpan; var buffer = new byte[BUFFER_SIZE]; @@ -110,33 +159,38 @@ public MsgPackTraceExporter(GenevaExporterOptions options) // timestamp cursor = MessagePackSerializer.WriteTimestamp96Header(buffer, cursor); - this.m_idxTimestampPatch = cursor; + this.timestampPatchIndex = cursor; cursor += 12; // reserve 12 bytes for the timestamp cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); // Note: always use Map16 for perf consideration - this.m_idxMapSizePatch = cursor - 2; + this.mapSizePatchIndex = cursor - 2; - this.m_cntPrepopulatedFields = 0; + this.prepopulatedFieldsCount = 0; // TODO: Do we support PartB as well? // Part A - core envelope cursor = AddPartAField(buffer, cursor, Schema.V40.PartA.Name, partAName); - this.m_cntPrepopulatedFields += 1; + this.prepopulatedFieldsCount += 1; foreach (var entry in options.PrepopulatedFields) { var value = entry.Value; cursor = AddPartAField(buffer, cursor, entry.Key, value); - this.m_cntPrepopulatedFields += 1; + this.prepopulatedFieldsCount += 1; } - this.m_bufferPrologue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.m_bufferPrologue, 0, cursor - 0); + this.bufferPrologue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.bufferPrologue, 0, cursor - 0); cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); - this.m_bufferEpilogue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.m_bufferEpilogue, 0, cursor - 0); + this.bufferEpilogue = new byte[cursor - 0]; + Buffer.BlockCopy(buffer, 0, this.bufferEpilogue, 0, cursor - 0); + } + + internal bool IsUsingUnixDomainSocket + { + get => this.dataTransport is UnixDomainSocketDataTransport; } public ExportResult Export(in Batch batch) @@ -156,7 +210,7 @@ public ExportResult Export(in Batch batch) try { var cursor = this.SerializeActivity(activity); - this.m_dataTransport.Send(this.m_buffer.Value, cursor - 0); + this.dataTransport.Send(this.buffer.Value, cursor - 0); } catch (Exception ex) { @@ -170,29 +224,44 @@ public ExportResult Export(in Batch batch) return result; } - internal bool IsUsingUnixDomainSocket + public void Dispose() { - get => this.m_dataTransport is UnixDomainSocketDataTransport; + if (this.isDisposed) + { + return; + } + + try + { + (this.dataTransport as IDisposable)?.Dispose(); + this.buffer.Dispose(); + } + catch (Exception ex) + { + ExporterEventSource.Log.ExporterException("MsgPackTraceExporter Dispose failed.", ex); + } + + this.isDisposed = true; } internal int SerializeActivity(Activity activity) { - var buffer = this.m_buffer.Value; + var buffer = this.buffer.Value; if (buffer == null) { buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM - Buffer.BlockCopy(this.m_bufferPrologue, 0, buffer, 0, this.m_bufferPrologue.Length); - this.m_buffer.Value = buffer; + Buffer.BlockCopy(this.bufferPrologue, 0, buffer, 0, this.bufferPrologue.Length); + this.buffer.Value = buffer; } - var cursor = this.m_bufferPrologue.Length; - var cntFields = this.m_cntPrepopulatedFields; + var cursor = this.bufferPrologue.Length; + var cntFields = this.prepopulatedFieldsCount; var dtBegin = activity.StartTimeUtc; var tsBegin = dtBegin.Ticks; var tsEnd = tsBegin + activity.Duration.Ticks; var dtEnd = new DateTime(tsEnd); - MessagePackSerializer.WriteTimestamp96(buffer, this.m_idxTimestampPatch, tsEnd); + MessagePackSerializer.WriteTimestamp96(buffer, this.timestampPatchIndex, tsEnd); #region Part A - core envelope cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_time"); @@ -242,7 +311,7 @@ internal int SerializeActivity(Activity activity) cntFields += 1; } - if (this.m_shouldIncludeTraceState) + if (this.shouldIncludeTraceState) { var traceStateString = activity.TraceStateString; if (!string.IsNullOrEmpty(traceStateString)) @@ -311,7 +380,7 @@ internal int SerializeActivity(Activity activity) statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } - else if (this.m_customFields == null || this.m_customFields.Contains(entry.Key)) + else if (this.customFields == null || this.customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); @@ -338,7 +407,7 @@ internal int SerializeActivity(Activity activity) foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision - if (this.m_dedicatedFields.Contains(entry.Key)) + if (this.dedicatedFields.Contains(entry.Key)) { continue; } @@ -383,87 +452,11 @@ internal int SerializeActivity(Activity activity) } #endregion - MessagePackSerializer.WriteUInt16(buffer, this.m_idxMapSizePatch, cntFields); + MessagePackSerializer.WriteUInt16(buffer, this.mapSizePatchIndex, cntFields); - Buffer.BlockCopy(this.m_bufferEpilogue, 0, buffer, cursor, this.m_bufferEpilogue.Length); - cursor += this.m_bufferEpilogue.Length; + Buffer.BlockCopy(this.bufferEpilogue, 0, buffer, cursor, this.bufferEpilogue.Length); + cursor += this.bufferEpilogue.Length; return cursor; } - - public void Dispose() - { - if (this.isDisposed) - { - return; - } - - try - { - (this.m_dataTransport as IDisposable)?.Dispose(); - this.m_buffer.Dispose(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("MsgPackTraceExporter Dispose failed.", ex); - } - - this.isDisposed = true; - } - - private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - - private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - - private static readonly Dictionary CS40_PART_B_MAPPING_DICTIONARY = new() - { - ["db.system"] = "dbSystem", - ["db.name"] = "dbName", - ["db.statement"] = "dbStatement", - - ["http.method"] = "httpMethod", - ["http.request.method"] = "httpMethod", - ["http.url"] = "httpUrl", - ["url.full"] = "httpUrl", - ["http.status_code"] = "httpStatusCode", - ["http.response.status_code"] = "httpStatusCode", - - ["messaging.system"] = "messagingSystem", - ["messaging.destination"] = "messagingDestination", - ["messaging.url"] = "messagingUrl", - }; - -#if NET8_0_OR_GREATER - private static readonly FrozenDictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY.ToFrozenDictionary(); -#else - private static readonly Dictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY; -#endif - - private readonly ThreadLocal m_buffer = new(() => null); - - private readonly byte[] m_bufferPrologue; - - private readonly byte[] m_bufferEpilogue; - - private readonly ushort m_cntPrepopulatedFields; - - private readonly int m_idxTimestampPatch; - - private readonly int m_idxMapSizePatch; - - private readonly IDataTransport m_dataTransport; - -#if NET8_0_OR_GREATER - private readonly FrozenSet m_customFields; - - private readonly FrozenSet m_dedicatedFields; -#else - private readonly HashSet m_customFields; - - private readonly HashSet m_dedicatedFields; -#endif - - private readonly bool m_shouldIncludeTraceState; - - private bool isDisposed; } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index d35c140d23..51b7aece16 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -8,68 +8,68 @@ namespace OpenTelemetry.Exporter.Geneva; -internal sealed class EtwEventSource : EventSource +internal sealed class EtwDataTransport : IDataTransport, IDisposable { - public EtwEventSource(string providerName) - : base(providerName, EventSourceSettings.EtwManifestEventFormat) + private readonly EtwEventSource eventSource; + private bool disposed; + + public EtwDataTransport(string providerName) { + this.eventSource = new EtwEventSource(providerName); } - public enum EtwEventId + public void Send(byte[] data, int size) { - TraceEvent = 100, + this.eventSource.SendEvent((int)EtwEventSource.EtwEventId.TraceEvent, data, size); } - [Event((int)EtwEventId.TraceEvent, Version = 1, Level = EventLevel.Informational)] - public void InformationalEvent() + public bool IsEnabled() { + return this.eventSource.IsEnabled(); } - [NonEvent] -#if NET - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] -#endif - public unsafe void SendEvent(int eventId, byte[] data, int size) + public void Dispose() { - EventData* dataDesc = stackalloc EventData[1]; - fixed (byte* ptr = data) + if (this.disposed) { - dataDesc[0].DataPointer = (IntPtr)ptr; - dataDesc[0].Size = (int)size; - this.WriteEventCore(eventId, 1, dataDesc); + return; } - } -} -internal sealed class EtwDataTransport : IDataTransport, IDisposable -{ - public EtwDataTransport(string providerName) - { - this.m_eventSource = new EtwEventSource(providerName); - } + this.eventSource.Dispose(); - public void Send(byte[] data, int size) - { - this.m_eventSource.SendEvent((int)EtwEventSource.EtwEventId.TraceEvent, data, size); + this.disposed = true; } - public bool IsEnabled() + private sealed class EtwEventSource : EventSource { - return this.m_eventSource.IsEnabled(); - } - - private EtwEventSource m_eventSource; - private bool m_disposed; + public EtwEventSource(string providerName) + : base(providerName, EventSourceSettings.EtwManifestEventFormat) + { + } - public void Dispose() - { - if (this.m_disposed) + public enum EtwEventId { - return; + TraceEvent = 100, } - this.m_eventSource.Dispose(); + [Event((int)EtwEventId.TraceEvent, Version = 1, Level = EventLevel.Informational)] + public void InformationalEvent() + { + } - this.m_disposed = true; + [NonEvent] +#if NET + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] +#endif + public unsafe void SendEvent(int eventId, byte[] data, int size) + { + EventData* dataDesc = stackalloc EventData[1]; + fixed (byte* ptr = data) + { + dataDesc[0].DataPointer = (IntPtr)ptr; + dataDesc[0].Size = (int)size; + this.WriteEventCore(eventId, 1, dataDesc); + } + } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs index 7178ea45fe..d073fb5101 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs @@ -31,10 +31,6 @@ public UnixDomainSocketEndPoint(string path) } } - public override AddressFamily AddressFamily => AddressFamily.Unix; - - public override EndPoint Create(SocketAddress socketAddress) => new UnixDomainSocketEndPoint(socketAddress); - private UnixDomainSocketEndPoint(SocketAddress socketAddress) { Guard.ThrowIfNull(socketAddress); @@ -64,6 +60,10 @@ private UnixDomainSocketEndPoint(SocketAddress socketAddress) } } + public override AddressFamily AddressFamily => AddressFamily.Unix; + + public override EndPoint Create(SocketAddress socketAddress) => new UnixDomainSocketEndPoint(socketAddress); + public override SocketAddress Serialize() { var socketAddress = new SocketAddress(AddressFamily.Unix, NativePathOffset + this.nativePath.Length + 1); diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index d7e16afe5b..0613915b40 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,7 +5,9 @@ true An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors - $(NoWarn),SA1123,SA1310,CA1810,CA1822,CA2000,CA2208,SA1201,SA1202,SA1308,SA1309,SA1311,SA1402,SA1649,OTEL1002 + $(NoWarn),CA1810,CA1822,CA2000,CA2208 + + $(NoWarn);SA1123;SA1310 net8.0;net6.0;netstandard2.0 $(TargetFrameworks);net462 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index c106c55f12..c09b724154 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -23,7 +23,7 @@ internal static class JsonSerializer #endif private static readonly byte[] HEX_CODE; - private static readonly ThreadLocal threadLocalBuffer = new(() => null); + private static readonly ThreadLocal ThreadLocalBuffer = new(); static JsonSerializer() { @@ -43,11 +43,11 @@ static JsonSerializer() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SerializeNull() { - var buffer = threadLocalBuffer.Value; + var buffer = ThreadLocalBuffer.Value; if (buffer == null) { buffer = new byte[65360]; - threadLocalBuffer.Value = buffer; + ThreadLocalBuffer.Value = buffer; } var count = WriteString(buffer, 0, "null"); @@ -63,11 +63,11 @@ public static int SerializeNull(byte[] buffer, int cursor) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SerializeString(string value) { - var buffer = threadLocalBuffer.Value; + var buffer = ThreadLocalBuffer.Value; if (buffer == null) { buffer = new byte[65360]; - threadLocalBuffer.Value = buffer; + ThreadLocalBuffer.Value = buffer; } var count = SerializeString(buffer, 0, value); @@ -107,11 +107,11 @@ public static int SerializeString(byte[] buffer, int cursor, ReadOnlySpan [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SerializeArray(T[] array) { - var buffer = threadLocalBuffer.Value; + var buffer = ThreadLocalBuffer.Value; if (buffer == null) { buffer = new byte[65360]; - threadLocalBuffer.Value = buffer; + ThreadLocalBuffer.Value = buffer; } var count = SerializeArray(buffer, 0, array); @@ -145,11 +145,11 @@ public static int SerializeArray(byte[] buffer, int cursor, T[] array) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SerializeMap(IEnumerable> map) { - var buffer = threadLocalBuffer.Value; + var buffer = ThreadLocalBuffer.Value; if (buffer == null) { buffer = new byte[65360]; - threadLocalBuffer.Value = buffer; + ThreadLocalBuffer.Value = buffer; } var count = SerializeMap(buffer, 0, map); @@ -159,11 +159,11 @@ public static string SerializeMap(IEnumerable> map) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte[] SerializeKeyValuePairsListAsBytes(List> listKVp, out int count) { - var buffer = threadLocalBuffer.Value; + var buffer = ThreadLocalBuffer.Value; if (buffer == null) { buffer = new byte[65360]; - threadLocalBuffer.Value = buffer; + ThreadLocalBuffer.Value = buffer; } count = SerializeKeyValuePairList(buffer, 0, listKVp); @@ -227,11 +227,11 @@ public static int SerializeKeyValuePairList(byte[] buffer, int cursor, List eventBuilder = new(() => null); - private static readonly ThreadLocal>> envProperties = new(() => null); - private static readonly ThreadLocal[]> partCFields = new(() => null); // This is used to temporarily store the PartC fields from tags - - private static readonly string[] logLevels = new string[7] + private static readonly ThreadLocal EventBuilder = new(); + private static readonly ThreadLocal>> EnvProperties = new(); + private static readonly ThreadLocal[]> PartCFields = new(); // This is used to temporarily store the PartC fields from tags + private static readonly Action ProcessScopeForIndividualColumnsAction = OnProcessScopeForIndividualColumns; + private static readonly string[] LogLevels = new string[7] { "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", }; - private readonly ThreadLocal serializationData = new(() => null); // This is used for Scopes - + private readonly ThreadLocal serializationData = new(); // This is used for Scopes private readonly byte partAFieldsCount = 1; // At least one field: time private readonly bool shouldPassThruTableMappings; private readonly string defaultEventName = "Log"; @@ -34,7 +33,6 @@ internal sealed class TldLogExporter : TldExporter, IDisposable private readonly Dictionary tableMappings; private readonly Tuple repeatedPartAFields; private readonly ExceptionStackExportMode exceptionStackExportMode; - private readonly EventProvider eventProvider; private bool isDisposed; @@ -92,11 +90,11 @@ public TldLogExporter(GenevaExporterOptions options) var prePopulatedFieldsCount = (byte)(options.PrepopulatedFields.Count - 1); // PrepopulatedFields option has the key ".ver" added to it which is not needed for TLD this.partAFieldsCount += prePopulatedFieldsCount; - var eb = eventBuilder.Value; + var eb = EventBuilder.Value; if (eb == null) { eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - eventBuilder.Value = eb; + EventBuilder.Value = eb; } eb.Reset("_"); // EventName does not matter here as we only need the serialized key-value pairs @@ -130,7 +128,7 @@ public ExportResult Export(in Batch batch) try { this.SerializeLogRecord(activity); - this.eventProvider.Write(eventBuilder.Value); + this.eventProvider.Write(EventBuilder.Value); } catch (Exception ex) { @@ -213,11 +211,11 @@ internal void SerializeLogRecord(LogRecord logRecord) eventName = GetSanitizedCategoryName(categoryName); } - var eb = eventBuilder.Value; + var eb = EventBuilder.Value; if (eb == null) { eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - eventBuilder.Value = eb; + EventBuilder.Value = eb; } var timestamp = logRecord.Timestamp; @@ -283,7 +281,7 @@ internal void SerializeLogRecord(LogRecord logRecord) var logLevel = logRecord.LogLevel; #pragma warning restore 0618 - eb.AddCountedString("severityText", logLevels[(int)logLevel]); + eb.AddCountedString("severityText", LogLevels[(int)logLevel]); eb.AddUInt8("severityNumber", GetSeverityNumber(logLevel)); var eventId = logRecord.EventId; @@ -298,11 +296,11 @@ internal void SerializeLogRecord(LogRecord logRecord) bool namePopulated = false; byte partCFieldsCountFromState = 0; - var kvpArrayForPartCFields = partCFields.Value; + var kvpArrayForPartCFields = PartCFields.Value; if (kvpArrayForPartCFields == null) { kvpArrayForPartCFields = new KeyValuePair[120]; - partCFields.Value = kvpArrayForPartCFields; + PartCFields.Value = kvpArrayForPartCFields; } List> envPropertiesList = null; @@ -347,11 +345,11 @@ internal void SerializeLogRecord(LogRecord logRecord) if (hasEnvProperties == 0) { hasEnvProperties = 1; - envPropertiesList = envProperties.Value; + envPropertiesList = EnvProperties.Value; if (envPropertiesList == null) { envPropertiesList = new List>(); - envProperties.Value = envPropertiesList; + EnvProperties.Value = envPropertiesList; } envPropertiesList.Clear(); @@ -388,7 +386,7 @@ internal void SerializeLogRecord(LogRecord logRecord) dataForScopes.HasEnvProperties = hasEnvProperties; dataForScopes.PartCFieldsCountFromState = partCFieldsCountFromState; - logRecord.ForEachScope(ProcessScopeForIndividualColumns, this); + logRecord.ForEachScope(ProcessScopeForIndividualColumnsAction, this); // Update the variables that could have been modified in ProcessScopeForIndividualColumns hasEnvProperties = dataForScopes.HasEnvProperties; @@ -496,12 +494,12 @@ private static string GetSanitizedCategoryName(string categoryName) return result.Slice(0, validNameLength).ToString(); } - private static readonly Action ProcessScopeForIndividualColumns = (scope, state) => + private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, TldLogExporter state) { var stateData = state.serializationData.Value; var customFields = state.customFields; - var kvpArrayForPartCFields = partCFields.Value; - var envPropertiesList = envProperties.Value; + var kvpArrayForPartCFields = PartCFields.Value; + var envPropertiesList = EnvProperties.Value; foreach (KeyValuePair scopeItem in scope) { @@ -526,7 +524,7 @@ private static string GetSanitizedCategoryName(string categoryName) if (envPropertiesList == null) { envPropertiesList = new List>(); - envProperties.Value = envPropertiesList; + EnvProperties.Value = envPropertiesList; } envPropertiesList.Clear(); @@ -536,7 +534,7 @@ private static string GetSanitizedCategoryName(string categoryName) envPropertiesList.Add(new(scopeItem.Key, scopeItem.Value)); } } - }; + } private sealed class SerializationDataForScopes { diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index 6294d96056..cddfa44470 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -12,9 +12,9 @@ namespace OpenTelemetry.Exporter.Geneva.TldExporter; internal sealed class TldTraceExporter : TldExporter, IDisposable { // TODO: Is using a single ThreadLocal a better idea? - private static readonly ThreadLocal eventBuilder = new(() => null); - private static readonly ThreadLocal>> keyValuePairs = new(() => null); - private static readonly ThreadLocal[]> partCFields = new(() => null); // This is used to temporarily store the PartC fields from tags + private static readonly ThreadLocal EventBuilder = new(); + private static readonly ThreadLocal>> KeyValuePairs = new(); + private static readonly ThreadLocal[]> PartCFields = new(); // This is used to temporarily store the PartC fields from tags private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); @@ -38,10 +38,9 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable private readonly string partAName = "Span"; private readonly byte partAFieldsCount = 3; // At least three fields: time, ext_dt_traceId, ext_dt_spanId - private readonly HashSet m_customFields; + private readonly HashSet customFields; private readonly Tuple repeatedPartAFields; - private readonly bool m_shouldIncludeTraceState; - + private readonly bool shouldIncludeTraceState; private readonly EventProvider eventProvider; private bool isDisposed; @@ -78,7 +77,7 @@ public TldTraceExporter(GenevaExporterOptions options) customFields.Add(name); } - this.m_customFields = customFields; + this.customFields = customFields; } if (options.PrepopulatedFields != null) @@ -86,11 +85,11 @@ public TldTraceExporter(GenevaExporterOptions options) var prePopulatedFieldsCount = (byte)(options.PrepopulatedFields.Count - 1); // PrepopulatedFields option has the key ".ver" added to it which is not needed for TLD this.partAFieldsCount += prePopulatedFieldsCount; - var eb = eventBuilder.Value; + var eb = EventBuilder.Value; if (eb == null) { eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - eventBuilder.Value = eb; + EventBuilder.Value = eb; } eb.Reset(this.partAName); @@ -113,7 +112,7 @@ public TldTraceExporter(GenevaExporterOptions options) } } - this.m_shouldIncludeTraceState = options.IncludeTraceStateForSpan; + this.shouldIncludeTraceState = options.IncludeTraceStateForSpan; } public ExportResult Export(in Batch batch) @@ -126,7 +125,7 @@ public ExportResult Export(in Batch batch) try { this.SerializeActivity(activity); - this.eventProvider.Write(eventBuilder.Value); + this.eventProvider.Write(EventBuilder.Value); } catch (Exception ex) { @@ -165,11 +164,11 @@ public void Dispose() internal void SerializeActivity(Activity activity) { - var eb = eventBuilder.Value; + var eb = EventBuilder.Value; if (eb == null) { eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - eventBuilder.Value = eb; + EventBuilder.Value = eb; } eb.Reset(this.partAName); @@ -205,7 +204,7 @@ internal void SerializeActivity(Activity activity) partBFieldsCount++; } - if (this.m_shouldIncludeTraceState) + if (this.shouldIncludeTraceState) { var traceStateString = activity.TraceStateString; if (!string.IsNullOrEmpty(traceStateString)) @@ -218,11 +217,11 @@ internal void SerializeActivity(Activity activity) var linkEnumerator = activity.EnumerateLinks(); if (linkEnumerator.MoveNext()) { - var keyValuePairsForLinks = keyValuePairs.Value; + var keyValuePairsForLinks = KeyValuePairs.Value; if (keyValuePairsForLinks == null) { keyValuePairsForLinks = new List>(); - keyValuePairs.Value = keyValuePairsForLinks; + KeyValuePairs.Value = keyValuePairsForLinks; } keyValuePairsForLinks.Clear(); @@ -248,11 +247,11 @@ internal void SerializeActivity(Activity activity) string statusDescription = string.Empty; int partCFieldsCountFromTags = 0; - var kvpArrayForPartCFields = partCFields.Value; + var kvpArrayForPartCFields = PartCFields.Value; if (kvpArrayForPartCFields == null) { kvpArrayForPartCFields = new KeyValuePair[120]; - partCFields.Value = kvpArrayForPartCFields; + PartCFields.Value = kvpArrayForPartCFields; } List> envPropertiesList = null; @@ -279,7 +278,7 @@ internal void SerializeActivity(Activity activity) statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } - else if (this.m_customFields == null || this.m_customFields.Contains(entry.Key)) + else if (this.customFields == null || this.customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. kvpArrayForPartCFields[partCFieldsCountFromTags] = new(entry.Key, entry.Value); @@ -290,11 +289,11 @@ internal void SerializeActivity(Activity activity) if (hasEnvProperties == 0) { hasEnvProperties = 1; - envPropertiesList = keyValuePairs.Value; + envPropertiesList = KeyValuePairs.Value; if (envPropertiesList == null) { envPropertiesList = new List>(); - keyValuePairs.Value = envPropertiesList; + KeyValuePairs.Value = envPropertiesList; } envPropertiesList.Clear(); diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs index c36b6c1059..5b8f52b7b3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -23,6 +23,12 @@ public UncheckedASCIIEncoding() { } + #region Optional property overrides (performance/functionality improvement) + + public override bool IsSingleByte => true; + + #endregion + #region Required implementation of Encoding abstract methods public override int GetMaxByteCount(int charCount) @@ -115,8 +121,6 @@ public override unsafe int GetChars(byte* bytePtr, int byteCount, char* charPtr, #region Optional overrides (performance/functionality improvement) - public override bool IsSingleByte => true; - public override int GetByteCount(string chars) { Guard.ThrowIfNull(chars); From e33d6b44805c70e757f1539a91271dd0a9e6c2f3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 10 Sep 2024 17:06:02 -0700 Subject: [PATCH 1239/1499] [geneva] Remove reflection from tests to fix failures due to renames (#2062) --- .../MsgPackExporter/MsgPackLogExporter.cs | 3 +- .../MsgPackExporter/MsgPackTraceExporter.cs | 70 +++++++++---------- .../GenevaLogExporterTests.cs | 43 ++++-------- .../GenevaTraceExporterTests.cs | 14 ++-- .../LogSerializationTests.cs | 4 +- 5 files changed, 56 insertions(+), 78 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 0ddd57fc80..54b9b2444d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -15,9 +15,10 @@ namespace OpenTelemetry.Exporter.Geneva; internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable { + internal static readonly ThreadLocal Buffer = new(); + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - private static readonly ThreadLocal Buffer = new(); private static readonly Action ProcessScopeForIndividualColumnsAction = OnProcessScopeForIndividualColumns; private static readonly Action ProcessScopeForEnvPropertiesAction = OnProcessScopeForEnvProperties; private static readonly string[] LogLevels = new string[7] diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index b32e1622dd..8048b7612b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -12,11 +12,7 @@ namespace OpenTelemetry.Exporter.Geneva; internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable { - private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) - - private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - - private static readonly Dictionary CS40_PART_B_MAPPING_DICTIONARY = new() + internal static readonly Dictionary CS40_PART_B_MAPPING_DICTIONARY = new() { ["db.system"] = "dbSystem", ["db.name"] = "dbName", @@ -35,12 +31,27 @@ internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable }; #if NET8_0_OR_GREATER - private static readonly FrozenDictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY.ToFrozenDictionary(); + internal static readonly FrozenDictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY.ToFrozenDictionary(); +#else + internal static readonly Dictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY; +#endif + + internal readonly ThreadLocal Buffer = new(); + +#if NET8_0_OR_GREATER + internal readonly FrozenSet CustomFields; + + internal readonly FrozenSet DedicatedFields; #else - private static readonly Dictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY; + internal readonly HashSet CustomFields; + + internal readonly HashSet DedicatedFields; #endif - private readonly ThreadLocal buffer = new(); + private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) + + private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); + private readonly byte[] bufferPrologue; private readonly byte[] bufferEpilogue; private readonly ushort prepopulatedFieldsCount; @@ -49,16 +60,6 @@ internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable private readonly IDataTransport dataTransport; private readonly bool shouldIncludeTraceState; -#if NET8_0_OR_GREATER - private readonly FrozenSet customFields; - - private readonly FrozenSet dedicatedFields; -#else - private readonly HashSet customFields; - - private readonly HashSet dedicatedFields; -#endif - private bool isDisposed; public MsgPackTraceExporter(GenevaExporterOptions options) @@ -117,9 +118,9 @@ public MsgPackTraceExporter(GenevaExporterOptions options) } #if NET8_0_OR_GREATER - this.customFields = customFields.ToFrozenSet(StringComparer.Ordinal); + this.CustomFields = customFields.ToFrozenSet(StringComparer.Ordinal); #else - this.customFields = customFields; + this.CustomFields = customFields; #endif foreach (var name in CS40_PART_B_MAPPING.Keys) @@ -131,9 +132,9 @@ public MsgPackTraceExporter(GenevaExporterOptions options) dedicatedFields.Add("otel.status_description"); #if NET8_0_OR_GREATER - this.dedicatedFields = dedicatedFields.ToFrozenSet(StringComparer.Ordinal); + this.DedicatedFields = dedicatedFields.ToFrozenSet(StringComparer.Ordinal); #else - this.dedicatedFields = dedicatedFields; + this.DedicatedFields = dedicatedFields; #endif } @@ -180,18 +181,15 @@ public MsgPackTraceExporter(GenevaExporterOptions options) } this.bufferPrologue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.bufferPrologue, 0, cursor - 0); + System.Buffer.BlockCopy(buffer, 0, this.bufferPrologue, 0, cursor - 0); cursor = MessagePackSerializer.Serialize(buffer, 0, new Dictionary { { "TimeFormat", "DateTime" } }); this.bufferEpilogue = new byte[cursor - 0]; - Buffer.BlockCopy(buffer, 0, this.bufferEpilogue, 0, cursor - 0); + System.Buffer.BlockCopy(buffer, 0, this.bufferEpilogue, 0, cursor - 0); } - internal bool IsUsingUnixDomainSocket - { - get => this.dataTransport is UnixDomainSocketDataTransport; - } + internal bool IsUsingUnixDomainSocket => this.dataTransport is UnixDomainSocketDataTransport; public ExportResult Export(in Batch batch) { @@ -210,7 +208,7 @@ public ExportResult Export(in Batch batch) try { var cursor = this.SerializeActivity(activity); - this.dataTransport.Send(this.buffer.Value, cursor - 0); + this.dataTransport.Send(this.Buffer.Value, cursor - 0); } catch (Exception ex) { @@ -234,7 +232,7 @@ public void Dispose() try { (this.dataTransport as IDisposable)?.Dispose(); - this.buffer.Dispose(); + this.Buffer.Dispose(); } catch (Exception ex) { @@ -246,12 +244,12 @@ public void Dispose() internal int SerializeActivity(Activity activity) { - var buffer = this.buffer.Value; + var buffer = this.Buffer.Value; if (buffer == null) { buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM - Buffer.BlockCopy(this.bufferPrologue, 0, buffer, 0, this.bufferPrologue.Length); - this.buffer.Value = buffer; + System.Buffer.BlockCopy(this.bufferPrologue, 0, buffer, 0, this.bufferPrologue.Length); + this.Buffer.Value = buffer; } var cursor = this.bufferPrologue.Length; @@ -380,7 +378,7 @@ internal int SerializeActivity(Activity activity) statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } - else if (this.customFields == null || this.customFields.Contains(entry.Key)) + else if (this.CustomFields == null || this.CustomFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, entry.Key); @@ -407,7 +405,7 @@ internal int SerializeActivity(Activity activity) foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision - if (this.dedicatedFields.Contains(entry.Key)) + if (this.DedicatedFields.Contains(entry.Key)) { continue; } @@ -454,7 +452,7 @@ internal int SerializeActivity(Activity activity) MessagePackSerializer.WriteUInt16(buffer, this.mapSizePatchIndex, cntFields); - Buffer.BlockCopy(this.bufferEpilogue, 0, buffer, cursor, this.bufferEpilogue.Length); + System.Buffer.BlockCopy(this.bufferEpilogue, 0, buffer, cursor, this.bufferEpilogue.Length); cursor += this.bufferEpilogue.Length; return cursor; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 6cdc3cee06..33c27baae0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -173,7 +173,6 @@ public void TableNameMappingTest(params string[] category) using var exporter = new MsgPackLogExporter(exporterOptions); ILogger logger; - ThreadLocal m_buffer; object fluentdData; string actualTableName; string defaultLogTable = "Log"; @@ -187,9 +186,8 @@ public void TableNameMappingTest(params string[] category) logger.LogError("this does not matter"); Assert.Single(logRecordList); - m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); actualTableName = (fluentdData as object[])[0] as string; Assert.Equal(mapping.Value, actualTableName); logRecordList.Clear(); @@ -205,9 +203,8 @@ public void TableNameMappingTest(params string[] category) logger.LogError("this does not matter"); Assert.Single(logRecordList); - m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); actualTableName = (fluentdData as object[])[0] as string; Assert.Equal(defaultLogTable, actualTableName); logRecordList.Clear(); @@ -295,10 +292,9 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() using var exporter = new MsgPackLogExporter(exporterOptions); ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; - ThreadLocal m_buffer; + ThreadLocal m_buffer = MsgPackLogExporter.Buffer; object fluentdData; string actualTableName; - m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; // Verify that the category table mappings specified by the users in the Geneva Configuration are mapped correctly. foreach (var mapping in userInitializedCategoryToTableNameMappings) @@ -417,8 +413,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) byte[] serializedData; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; - serializedData = m_buffer.Value; + serializedData = MsgPackLogExporter.Buffer.Value; } else { @@ -548,9 +543,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var body = GetField(fluentdData, "body"); // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` @@ -573,9 +567,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` @@ -595,9 +588,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); body = GetField(fluentdData, "body"); // Even though Formatter is null, body is populated with the state @@ -620,9 +612,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); - m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); Assert.Equal("Value1", GetField(fluentdData, "Key1")); body = GetField(fluentdData, "body"); @@ -758,7 +749,7 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin // logRecordList should have 14 logRecord entries as there were 14 Log calls Assert.Equal(14, logRecordList.Count); - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; + var m_buffer = MsgPackLogExporter.Buffer; foreach (var logRecord in logRecordList) { @@ -961,9 +952,8 @@ public void SerializationTestForException() // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var exceptionType = GetField(fluentdData, "env_ex_type"); var exceptionMessage = GetField(fluentdData, "env_ex_msg"); Assert.Equal("System.Exception", exceptionType); @@ -1055,9 +1045,8 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var eventName = GetField(fluentdData, "env_name"); if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) @@ -1077,7 +1066,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod logger.LogInformation(eventId: new EventId(1, "TestEventNameWithLogExtensionMethod"), "Hello from {Name} {Price}.", "tomato", 2.99); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); eventName = GetField(fluentdData, "env_name"); if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) @@ -1096,7 +1085,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod logger.LogInformation(eventId: 1, "Hello from {Name} {Price}.", "tomato", 2.99); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); eventName = GetField(fluentdData, "env_name"); Assert.Equal(hasTableNameMapping ? "CustomTableName" : "Log", eventName); #endregion @@ -1200,9 +1189,8 @@ public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCu // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; @@ -1304,9 +1292,8 @@ public void SerializationTestForEventId() // VALIDATE Assert.Single(logRecordList); - var m_buffer = typeof(MsgPackLogExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as ThreadLocal; _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 9de3aa1639..e2dba881bb 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -1,9 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET8_0_OR_GREATER -using System.Collections.Frozen; -#endif using System.Diagnostics; using System.Net.Sockets; using System.Reflection; @@ -246,13 +243,10 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, } using var exporter = new MsgPackTraceExporter(exporterOptions); -#if NET8_0_OR_GREATER - var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as FrozenSet; -#else - var dedicatedFields = typeof(MsgPackTraceExporter).GetField("m_dedicatedFields", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as HashSet; -#endif - var CS40_PART_B_MAPPING = typeof(MsgPackTraceExporter).GetField("CS40_PART_B_MAPPING", BindingFlags.NonPublic | BindingFlags.Static).GetValue(exporter) as IReadOnlyDictionary; - var m_buffer = typeof(MsgPackTraceExporter).GetField("m_buffer", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as ThreadLocal; + + var dedicatedFields = exporter.DedicatedFields; + var CS40_PART_B_MAPPING = MsgPackTraceExporter.CS40_PART_B_MAPPING; + var m_buffer = exporter.Buffer; // Add an ActivityListener to serialize the activity and assert that it was valid on ActivityStopped event diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index 4e7643941b..ac90603019 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Net.Sockets; -using System.Reflection; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; using OpenTelemetry.Logs; @@ -125,9 +124,8 @@ private static Dictionary GetExportedFieldsAfterLogging(Action; _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); return GetFields(fluentdData); } From b2196b56ad35a20520856a2c6b51646db2880f01 Mon Sep 17 00:00:00 2001 From: Rajkumar Rangaraj Date: Tue, 10 Sep 2024 18:16:57 -0700 Subject: [PATCH 1240/1499] Update Component Ownership for Components (#2061) --- .github/component_owners.yml | 18 +++++++++--------- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- .../README.md | 2 +- .../README.md | 2 +- src/OpenTelemetry.Resources.Azure/README.md | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 907bf3b71b..ba7131f8eb 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -6,9 +6,9 @@ components: src/OpenTelemetry.Exporter.Geneva/: - cijothomas - codeblanch + - rajkumar-rangaraj - reyang - utpilla - - Yun-Ting src/OpenTelemetry.Exporter.InfluxDB/: - havret src/OpenTelemetry.Exporter.Instana/: @@ -61,15 +61,15 @@ components: src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch src/OpenTelemetry.PersistentStorage.Abstractions/: - - vishweshbankwar + - rajkumar-rangaraj src/OpenTelemetry.PersistentStorage.FileSystem/: - - vishweshbankwar + - rajkumar-rangaraj src/OpenTelemetry.Resources.AWS/: - srprash - ppittle src/OpenTelemetry.Resources.Azure/: - rajkumar-rangaraj - - vishweshbankwar + - TimothyMothra src/OpenTelemetry.Resources.Container/: - iskiselev src/OpenTelemetry.Resources.Host/: @@ -93,21 +93,21 @@ components: test/OpenTelemetry.Exporter.Geneva.Benchmarks/: - cijothomas - codeblanch + - rajkumar-rangaraj - reyang - utpilla - - Yun-Ting test/OpenTelemetry.Exporter.Geneva.Stress/: - cijothomas - codeblanch + - rajkumar-rangaraj - reyang - utpilla - - Yun-Ting test/OpenTelemetry.Exporter.Geneva.Tests/: - cijothomas - codeblanch + - rajkumar-rangaraj - reyang - utpilla - - Yun-Ting test/OpenTelemetry.Exporter.InfluxDB.Tests/: - havret test/OpenTelemetry.Exporter.Instana.Tests/: @@ -161,13 +161,13 @@ components: test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: - - vishweshbankwar + - rajkumar-rangaraj test/OpenTelemetry.Resources.AWS.Tests/: - srprash - ppittle test/OpenTelemetry.Resources.Azure.Tests/: - rajkumar-rangaraj - - vishweshbankwar + - TimothyMothra test/OpenTelemetry.Resources.Container.Tests/: - iskiselev test/OpenTelemetry.Resources.Host.Tests/: diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index b69c73b1b7..5d7e1efdb1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Stable](../../README.md#stable)| -| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@reyang](https://github.com/reyang), [@utpilla](https://github.com/utpilla), [@Yun-Ting](https://github.com/Yun-Ting)| +| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/), [@reyang](https://github.com/reyang), [@utpilla](https://github.com/utpilla)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md index 41db94b146..3982c065ff 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/README.md +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Stable](../../README.md#stable)| -| Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar)| +| Code Owners | [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.Abstractions)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.Abstractions) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md index efadab3e17..e5f4d94d0c 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/README.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Stable](../../README.md#stable)| -| Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar)| +| Code Owners | [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.PersistentStorage.FileSystem)](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem) diff --git a/src/OpenTelemetry.Resources.Azure/README.md b/src/OpenTelemetry.Resources.Azure/README.md index ba0efb19ba..a5850289ac 100644 --- a/src/OpenTelemetry.Resources.Azure/README.md +++ b/src/OpenTelemetry.Resources.Azure/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Beta](../../README.md#beta)| -| Code Owners | [@vishweshbankwar](https://github.com/vishweshbankwar), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj)| +| Code Owners | [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj), [@TimothyMothra](https://github.com/TimothyMothra)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Resources.Azure)](https://www.nuget.org/packages/OpenTelemetry.Resources.Azure) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Resources.Azure)](https://www.nuget.org/packages/OpenTelemetry.Resources.Azure) From 1fb3c599c0880e965d2a864489dccf2d2cc1d3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Sep 2024 06:39:13 +0200 Subject: [PATCH 1241/1499] [Instrumentation.Hangfire] NugetAudit - fix dependencies with known vulnerabilities (#2057) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Instrumentation.Hangfire.csproj | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index bf56d018d2..b3ecf9c96b 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -11,6 +11,10 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Added direct reference to `Newtonsoft.Json` with minimum version of + `13.0.1` in response to [CVE-2024-21907](https://github.com/advisories/GHSA-5crp-9r3c-p9vr). + ([#2057](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2057)) + ## 1.6.0-beta.1 Released 2023-Dec-20 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index ad5280d28c..7507f1205a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -17,6 +17,8 @@ + + From c37985da422c40569c639dff1d95dbdd056bea3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Sep 2024 06:53:00 +0200 Subject: [PATCH 1242/1499] [Instrumentation.Cassandra] NugetAudit - fix dependencies with known vulnerabilities (#2058) --- src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Instrumentation.Cassandra.csproj | 2 ++ .../OpenTelemetry.Instrumentation.Cassandra.Tests.csproj | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index a8c7fd6100..7ebec71fae 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -8,6 +8,10 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Added direct reference to `Newtonsoft.Json` with minimum version of + `13.0.1` in response to [CVE-2024-21907](https://github.com/advisories/GHSA-5crp-9r3c-p9vr). + ([#2058](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2058)) + ## 1.0.0-beta.1 Released 2023-Mar-30 diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index 6e6b111314..7dca3e007a 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -16,6 +16,8 @@ + + diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 7bcac9f8e7..40e26b7c91 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -10,6 +10,8 @@ + + From ea5d607dedf0340a3375d75bf3c64204c6c3039b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 10 Sep 2024 23:25:14 -0700 Subject: [PATCH 1243/1499] [geneva] Remove remaining project-level warning suppressions and update code to be compliant (#2063) --- .../GenevaExporterHelperExtensions.cs | 3 ++ .../GenevaLogExporter.cs | 2 +- .../GenevaLoggingExtensions.cs | 11 ++++-- .../GenevaTraceExporter.cs | 2 +- .../Internal/ReentrantExportProcessor.cs | 20 +++++------ .../Metrics/GenevaMetricExporterExtensions.cs | 13 +++++-- .../Metrics/TlvMetricExporter.cs | 2 +- .../Transport/MetricEtwDataTransport.cs | 4 +++ .../MsgPackExporter/MsgPackLogExporter.cs | 2 +- .../MsgPackExporter/MsgPackTraceExporter.cs | 2 +- .../Transport/EtwDataTransport.cs | 4 +++ .../Transport/UnixDomainSocketEndPoint.cs | 2 +- .../OpenTelemetry.Exporter.Geneva.csproj | 1 - .../TLDExporter/JsonSerializer.cs | 35 ++++++++++--------- .../GenevaTraceExporterTests.cs | 2 +- 15 files changed, 67 insertions(+), 38 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index ce1b378209..7e8c570484 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -91,7 +91,10 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu private static BaseProcessor BuildGenevaTraceExporter(GenevaExporterOptions options, BatchExportActivityProcessorOptions batchActivityExportProcessor) { +#pragma warning disable CA2000 // Dispose objects before losing scope var exporter = new GenevaTraceExporter(options); +#pragma warning restore CA2000 // Dispose objects before losing scope + if (exporter.IsUsingUnixDomainSocket) { return new BatchActivityExportProcessor( diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 83826f174f..476199bbad 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -61,7 +61,7 @@ public GenevaLogExporter(GenevaExporterOptions options) break; default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } if (useMsgPackExporter) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 0c8ac2e7ec..17530b7516 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -30,14 +30,18 @@ public static OpenTelemetryLoggerOptions AddGenevaLogExporter( var genevaOptions = new GenevaExporterOptions(); configure?.Invoke(genevaOptions); + +#pragma warning disable CA2000 // Dispose objects before losing scope var exporter = new GenevaLogExporter(genevaOptions); +#pragma warning restore CA2000 // Dispose objects before losing scope + if (exporter.IsUsingUnixDomainSocket) { - return options.AddProcessor(new BatchLogRecordExportProcessor(exporter)); + return options.AddProcessor(sp => new BatchLogRecordExportProcessor(exporter)); } else { - return options.AddProcessor(new ReentrantExportProcessor(exporter)); + return options.AddProcessor(sp => new ReentrantExportProcessor(exporter)); } } @@ -123,7 +127,10 @@ internal static BaseProcessor BuildGenevaLogExporter( { Debug.Assert(exporterOptions != null, "exporterOptions was null"); +#pragma warning disable CA2000 // Dispose objects before losing scope var exporter = new GenevaLogExporter(exporterOptions); +#pragma warning restore CA2000 // Dispose objects before losing scope + if (exporter.IsUsingUnixDomainSocket) { return new BatchLogRecordExportProcessor( diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 7840342587..d73cfc705a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -61,7 +61,7 @@ public GenevaTraceExporter(GenevaExporterOptions options) break; default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } if (useMsgPackExporter) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index 5e6493c178..3ae51105ee 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -14,16 +14,7 @@ namespace OpenTelemetry.Exporter.Geneva; internal class ReentrantExportProcessor : BaseExportProcessor where T : class { - private static readonly Func> CreateBatch; - - static ReentrantExportProcessor() - { - var flags = BindingFlags.Instance | BindingFlags.NonPublic; - var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); - var value = Expression.Parameter(typeof(T), null); - var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); - CreateBatch = lambda.Compile(); - } + private static readonly Func> CreateBatch = BuildCreateBatchDelegate(); public ReentrantExportProcessor(BaseExporter exporter) : base(exporter) @@ -34,4 +25,13 @@ protected override void OnExport(T data) { this.exporter.Export(CreateBatch(data)); } + + private static Func> BuildCreateBatchDelegate() + { + var flags = BindingFlags.Instance | BindingFlags.NonPublic; + var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); + var value = Expression.Parameter(typeof(T), null); + var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); + return lambda.Compile(); + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index fb84697810..1d25e7c374 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -59,7 +59,16 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui private static PeriodicExportingMetricReader BuildGenevaMetricExporter(GenevaMetricExporterOptions options, Action configure = null) { configure?.Invoke(options); - return new PeriodicExportingMetricReader(new GenevaMetricExporter(options), options.MetricExportIntervalMilliseconds) - { TemporalityPreference = MetricReaderTemporalityPreference.Delta }; + +#pragma warning disable CA2000 // Dispose objects before losing scope + var exporter = new GenevaMetricExporter(options); +#pragma warning restore CA2000 // Dispose objects before losing scope + + return new PeriodicExportingMetricReader( + exporter, + options.MetricExportIntervalMilliseconds) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 0931510cde..9ac707ab44 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -57,7 +57,7 @@ internal TlvMetricExporter(ConnectionStringBuilder connectionStringBuilder, IRea } default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } unsafe diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs index 2aea97934b..3b3088a9a8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs @@ -61,6 +61,8 @@ public unsafe void SendOtlpProtobufEvent(byte[] data, int size) } } +#pragma warning disable CA1822 // Mark members as static + [Event(OtlpProtobufMetricEventId)] public void OtlpProtobufEvent() { @@ -86,6 +88,8 @@ public void TLVMetricEvent() { } +#pragma warning restore CA1822 // Mark members as static + protected override void Dispose(bool disposing) { if (this.isDisposed) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs index 54b9b2444d..0268662b74 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs @@ -75,7 +75,7 @@ public MsgPackLogExporter(GenevaExporterOptions options) this.dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } if (options.PrepopulatedFields != null) diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs index 8048b7612b..9df8bd36ca 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs @@ -92,7 +92,7 @@ public MsgPackTraceExporter(GenevaExporterOptions options) this.dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; default: - throw new ArgumentOutOfRangeException(nameof(connectionStringBuilder.Protocol)); + throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } // TODO: Validate custom fields (reserved name? etc). diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs index 51b7aece16..bd61474887 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs @@ -52,11 +52,15 @@ public enum EtwEventId TraceEvent = 100, } +#pragma warning disable CA1822 // Mark members as static + [Event((int)EtwEventId.TraceEvent, Version = 1, Level = EventLevel.Informational)] public void InformationalEvent() { } +#pragma warning restore CA1822 // Mark members as static + [NonEvent] #if NET [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "WriteEventCore is safe when eventData object is a primitive type, which it is in this case.")] diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs index d073fb5101..97d384fc75 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs @@ -27,7 +27,7 @@ public UnixDomainSocketEndPoint(string path) this.nativePath = Encoding.UTF8.GetBytes(path); if (this.nativePath.Length == 0 || this.nativePath.Length > MaximumNativePathLength) { - throw new ArgumentOutOfRangeException(nameof(this.nativePath), "Path is of an invalid length for use with domain sockets."); + throw new ArgumentOutOfRangeException(nameof(path), "Path is of an invalid length for use with domain sockets."); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 0613915b40..080a106fbd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,7 +5,6 @@ true An OpenTelemetry .NET exporter that exports to local ETW or UDS OpenTelemetry Authors - $(NoWarn),CA1810,CA1822,CA2000,CA2208 $(NoWarn);SA1123;SA1310 diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index c09b724154..955f55a26f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -22,24 +22,9 @@ internal static class JsonSerializer private const int MAX_STACK_ALLOC_SIZE_IN_BYTES = 256; #endif - private static readonly byte[] HEX_CODE; + private static readonly byte[] HEX_CODE = InitializeHexCodeLookup(); private static readonly ThreadLocal ThreadLocalBuffer = new(); - static JsonSerializer() - { - var mapping = new byte[] - { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - }; - HEX_CODE = new byte[512]; - for (int i = 0; i < 256; i++) - { - HEX_CODE[i] = mapping[i >> 4]; - HEX_CODE[i + 256] = mapping[i & 0x0F]; - } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string SerializeNull() { @@ -343,6 +328,24 @@ public static int Serialize(byte[] buffer, int cursor, object obj) } } + private static byte[] InitializeHexCodeLookup() + { + var mapping = new byte[] + { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + }; + + var hexCodeLookup = new byte[512]; + for (int i = 0; i < 256; i++) + { + hexCodeLookup[i] = mapping[i >> 4]; + hexCodeLookup[i + 256] = mapping[i & 0x0F]; + } + + return hexCodeLookup; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int WriteString(byte[] buffer, int cursor, string value) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index e2dba881bb..6e2b6c5ddc 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -98,7 +98,7 @@ public void GenevaTraceExporter_constructor_Invalid_Input_Windows() if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { // no ETW session name - Assert.Throws(() => + Assert.Throws(() => { using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { From 2b9c80f1cec0bbdfaec57ac48ba1434bd5d8fad4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Sep 2024 15:37:39 +0200 Subject: [PATCH 1244/1499] [Resources.Gcp] NugetAudit - fix dependencies with known vulnerabilities (#2055) --- .../OpenTelemetry.Resources.Gcp.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj index e0b3c71433..02fc5995bd 100644 --- a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj +++ b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj @@ -16,6 +16,8 @@ + + From 413e943adef8608fdcc584a1e01b2c3eba040222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Sep 2024 21:22:32 +0200 Subject: [PATCH 1245/1499] [Resources.Azure] NugetAudit - fix dependencies with known vulnerabilities (#2056) --- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Resources.Azure.csproj | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 538efdf078..50b5a0065f 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Added direct reference to `System.Text.Encodings.Web` with minimum version of + `4.7.2` in response to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377). + ([#2056](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2056)) + ## 1.0.0-beta.8 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj index a65a158f8b..c771f22875 100644 --- a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj +++ b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj @@ -15,6 +15,8 @@ + + From 238d1117042fe92bd6acb2d65168be0a860c4c8e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 11 Sep 2024 21:43:44 -0700 Subject: [PATCH 1246/1499] [geneva] Enable nullable in GenevaExporter public API files (#2065) --- .../.publicApi/PublicAPI.Shipped.txt | 59 ++++++++++--------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt index 2fe51143f5..b07b736be2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt @@ -1,3 +1,4 @@ +#nullable enable Microsoft.Extensions.Logging.GenevaLoggingExtensions OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.EventNameExportMode.ExportAsPartAName = 1 -> OpenTelemetry.Exporter.Geneva.EventNameExportMode @@ -5,14 +6,9 @@ OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Expo OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode -OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions OpenTelemetry.Exporter.Geneva.GenevaExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode @@ -20,38 +16,43 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.get -> bool OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void OpenTelemetry.Exporter.Geneva.GenevaLogExporter -OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporter -OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary -OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void OpenTelemetry.Exporter.Geneva.GenevaTraceExporter -OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +~OpenTelemetry.Exporter.Geneva.GenevaBaseExporter +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary +~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void +~OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +~OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void +~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string +~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void +~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary +~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void +~OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void +~override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +~override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +~override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder +~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder +~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder +~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions +~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder +~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder From f3b4c2fecb96732d9bbfba29060ce450fd615209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 12 Sep 2024 07:04:59 +0200 Subject: [PATCH 1247/1499] [repo] Always execute build-test step (#2054) --- .github/workflows/ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1953b3bf47..83fa5c9a2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -590,6 +590,7 @@ jobs: lint-misspell-sanitycheck, detect-changes, lint-md, + lint-yml, lint-dotnet-format, build-test-exporter-geneva, build-test-exporter-influxdb, @@ -633,7 +634,8 @@ jobs: build-test-contrib-shared-tests, verify-aot-compat ] - 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 2f76c24ed65e7801faf49fe4918f375b05253a22 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:34:33 +0200 Subject: [PATCH 1248/1499] [SemanticConvention] Migrate generation to Weaver and bump version to 1.26 (#2040) --- build/scripts/sanitycheck.py | 1 + .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 1679 +++++++++-------- .../Attributes/AndroidAttributes.cs | 20 +- .../Attributes/AspnetcoreAttributes.cs | 46 +- .../Attributes/AwsAttributes.cs | 178 +- .../Attributes/BrowserAttributes.cs | 22 +- .../Attributes/ClientAttributes.cs | 14 +- .../Attributes/CloudAttributes.cs | 130 +- .../Attributes/CloudeventsAttributes.cs | 16 +- .../Attributes/CodeAttributes.cs | 18 +- .../Attributes/ContainerAttributes.cs | 54 +- .../Attributes/DbAttributes.cs | 329 ++-- .../Attributes/DeploymentAttributes.cs | 22 +- .../Attributes/DestinationAttributes.cs | 12 +- .../Attributes/DeviceAttributes.cs | 22 +- .../Attributes/DiskAttributes.cs | 14 +- .../Attributes/DnsAttributes.cs | 10 +- .../Attributes/EnduserAttributes.cs | 12 +- .../Attributes/ErrorAttributes.cs | 42 +- .../Attributes/EventAttributes.cs | 10 +- .../Attributes/ExceptionAttributes.cs | 40 +- .../Attributes/FaasAttributes.cs | 132 +- .../Attributes/FeatureFlagAttributes.cs | 24 +- .../Attributes/FileAttributes.cs | 18 +- .../Attributes/GcpAttributes.cs | 14 +- .../Attributes/GenAiAttributes.cs | 96 + .../Attributes/GraphqlAttributes.cs | 22 +- .../Attributes/HerokuAttributes.cs | 12 +- .../Attributes/HostAttributes.cs | 60 +- .../Attributes/HttpAttributes.cs | 182 +- .../Attributes/IosAttributes.cs | 28 +- .../Attributes/JvmAttributes.cs | 48 +- .../Attributes/K8sAttributes.cs | 107 +- .../Attributes/LogAttributes.cs | 26 +- .../Attributes/MessageAttributes.cs | 29 +- .../Attributes/MessagingAttributes.cs | 195 +- .../Attributes/NetAttributes.cs | 96 +- .../Attributes/NetworkAttributes.cs | 128 +- .../Attributes/OciAttributes.cs | 10 +- .../Attributes/OpentracingAttributes.cs | 16 +- .../Attributes/OsAttributes.cs | 40 +- .../Attributes/OtelAttributes.cs | 32 +- .../Attributes/OtherAttributes.cs | 17 +- .../Attributes/PeerAttributes.cs | 8 +- .../Attributes/PoolAttributes.cs | 9 +- .../Attributes/ProcessAttributes.cs | 122 +- .../Attributes/RpcAttributes.cs | 173 +- .../Attributes/ServerAttributes.cs | 14 +- .../Attributes/ServiceAttributes.cs | 60 +- .../Attributes/SessionAttributes.cs | 10 +- .../Attributes/SignalrAttributes.cs | 26 +- .../Attributes/SourceAttributes.cs | 12 +- .../Attributes/SystemAttributes.cs | 154 +- .../Attributes/TelemetryAttributes.cs | 54 +- .../Attributes/ThreadAttributes.cs | 10 +- .../Attributes/TlsAttributes.cs | 72 +- .../Attributes/UrlAttributes.cs | 55 +- .../Attributes/UserAgentAttributes.cs | 16 +- .../Attributes/WebengineAttributes.cs | 12 +- .../CHANGELOG.md | 3 + .../README.md | 7 +- .../scripts/generate.ps1 | 23 +- .../scripts/generate.sh | 21 +- .../SemanticConventionsAttributes.cs.j2 | 65 - .../SemanticConventionsAttributes.cs.j2 | 52 + .../scripts/templates/registry/common.j2 | 3 + .../scripts/templates/registry/weaver.yaml | 48 + 68 files changed, 2792 insertions(+), 2261 deletions(-) create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs delete mode 100644 src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/templates/registry/SemanticConventionsAttributes.cs.j2 create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/templates/registry/common.j2 create mode 100644 src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml diff --git a/build/scripts/sanitycheck.py b/build/scripts/sanitycheck.py index 06b33c3a61..2e7d10ceda 100644 --- a/build/scripts/sanitycheck.py +++ b/build/scripts/sanitycheck.py @@ -9,6 +9,7 @@ LF = b'\n' # Add paths to exclude from sanity checks here +# Mostly used for auto-generated code exclude_folders = [ "src/OpenTelemetry.SemanticConventions/Attributes" ] diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt index e69de29bb2..7dc5c58110 100644 --- a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt index f88e9e126f..6500a8befd 100644 --- a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt @@ -1,661 +1,711 @@ -const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Background = "background" -> string -const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Created = "created" -> string -const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Foreground = "foreground" -> string -const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidOsApiLevel = "android.os.api_level" -> string -const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidState = "android.state" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Aborted = "aborted" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Handled = "handled" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Skipped = "skipped" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Unhandled = "unhandled" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.Acquired = "acquired" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.EndpointLimiter = "endpoint_limiter" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.GlobalLimiter = "global_limiter" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.RequestCanceled = "request_canceled" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues.Failure = "failure" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues.Success = "success" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreDiagnosticsExceptionResult = "aspnetcore.diagnostics.exception.result" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreDiagnosticsHandlerType = "aspnetcore.diagnostics.handler.type" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRateLimitingPolicy = "aspnetcore.rate_limiting.policy" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRateLimitingResult = "aspnetcore.rate_limiting.result" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRequestIsUnhandled = "aspnetcore.request.is_unhandled" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRoutingIsFallback = "aspnetcore.routing.is_fallback" -> string -const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRoutingMatchStatus = "aspnetcore.routing.match_status" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbAttributeDefinitions = "aws.dynamodb.attribute_definitions" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbCount = "aws.dynamodb.count" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbGlobalSecondaryIndexes = "aws.dynamodb.global_secondary_indexes" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbGlobalSecondaryIndexUpdates = "aws.dynamodb.global_secondary_index_updates" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbIndexName = "aws.dynamodb.index_name" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbItemCollectionMetrics = "aws.dynamodb.item_collection_metrics" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbLimit = "aws.dynamodb.limit" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbLocalSecondaryIndexes = "aws.dynamodb.local_secondary_indexes" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProjection = "aws.dynamodb.projection" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProvisionedReadCapacity = "aws.dynamodb.provisioned_read_capacity" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProvisionedWriteCapacity = "aws.dynamodb.provisioned_write_capacity" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbScanForward = "aws.dynamodb.scan_forward" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbScannedCount = "aws.dynamodb.scanned_count" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbSegment = "aws.dynamodb.segment" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbSelect = "aws.dynamodb.select" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTableCount = "aws.dynamodb.table_count" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTableNames = "aws.dynamodb.table_names" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTotalSegments = "aws.dynamodb.total_segments" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsClusterArn = "aws.ecs.cluster.arn" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsContainerArn = "aws.ecs.container.arn" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsLaunchtype = "aws.ecs.launchtype" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskArn = "aws.ecs.task.arn" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskFamily = "aws.ecs.task.family" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskId = "aws.ecs.task.id" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskRevision = "aws.ecs.task.revision" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEksClusterArn = "aws.eks.cluster.arn" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLambdaInvokedArn = "aws.lambda.invoked_arn" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogGroupArns = "aws.log.group.arns" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogGroupNames = "aws.log.group.names" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogStreamArns = "aws.log.stream.arns" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogStreamNames = "aws.log.stream.names" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsRequestId = "aws.request_id" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Bucket = "aws.s3.bucket" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3CopySource = "aws.s3.copy_source" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Delete = "aws.s3.delete" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Key = "aws.s3.key" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3PartNumber = "aws.s3.part_number" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3UploadId = "aws.s3.upload_id" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Ec2 = "ec2" -> string -const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Fargate = "fargate" -> string -const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserBrands = "browser.brands" -> string -const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserLanguage = "browser.language" -> string -const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserMobile = "browser.mobile" -> string -const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserPlatform = "browser.platform" -> string -const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientAddress = "client.address" -> string -const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientPort = "client.port" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAccountId = "cloud.account.id" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAvailabilityZone = "cloud.availability_zone" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudPlatform = "cloud.platform" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudProvider = "cloud.provider" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudRegion = "cloud.region" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudResourceId = "cloud.resource_id" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudEcs = "alibaba_cloud_ecs" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudFc = "alibaba_cloud_fc" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudOpenshift = "alibaba_cloud_openshift" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsAppRunner = "aws_app_runner" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEc2 = "aws_ec2" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEcs = "aws_ecs" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEks = "aws_eks" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsElasticBeanstalk = "aws_elastic_beanstalk" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsLambda = "aws_lambda" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsOpenshift = "aws_openshift" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureAks = "azure_aks" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureAppService = "azure_app_service" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureContainerApps = "azure_container_apps" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureContainerInstances = "azure_container_instances" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureFunctions = "azure_functions" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureOpenshift = "azure_openshift" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureVm = "azure_vm" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpAppEngine = "gcp_app_engine" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpBareMetalSolution = "gcp_bare_metal_solution" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpCloudFunctions = "gcp_cloud_functions" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpCloudRun = "gcp_cloud_run" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpComputeEngine = "gcp_compute_engine" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpKubernetesEngine = "gcp_kubernetes_engine" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpOpenshift = "gcp_openshift" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.IbmCloudOpenshift = "ibm_cloud_openshift" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudCvm = "tencent_cloud_cvm" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudEks = "tencent_cloud_eks" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudScf = "tencent_cloud_scf" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.AlibabaCloud = "alibaba_cloud" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Aws = "aws" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Azure = "azure" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Gcp = "gcp" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Heroku = "heroku" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.IbmCloud = "ibm_cloud" -> string -const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.TencentCloud = "tencent_cloud" -> string -const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventId = "cloudevents.event_id" -> string -const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSource = "cloudevents.event_source" -> string -const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version" -> string -const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSubject = "cloudevents.event_subject" -> string -const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventType = "cloudevents.event_type" -> string -const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeColumn = "code.column" -> string -const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFilepath = "code.filepath" -> string -const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFunction = "code.function" -> string -const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeLineno = "code.lineno" -> string -const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeNamespace = "code.namespace" -> string -const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeStacktrace = "code.stacktrace" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommand = "container.command" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandArgs = "container.command_args" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandLine = "container.command_line" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCpuState = "container.cpu.state" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerId = "container.id" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageId = "container.image.id" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageName = "container.image.name" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageRepoDigests = "container.image.repo_digests" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageTags = "container.image.tags" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerLabel = "container.label" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerLabels = "container.labels" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerName = "container.name" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerRuntime = "container.runtime" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.Kernel = "kernel" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.System = "system" -> string -const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.User = "user" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraIdempotence = "db.cassandra.idempotence" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraPageSize = "db.cassandra.page_size" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraTable = "db.cassandra.table" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbConnectionString = "db.connection_string" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbClientId = "db.cosmosdb.client_id" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbContainer = "db.cosmosdb.container" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchNodeName = "db.elasticsearch.node.name" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchPathParts = "db.elasticsearch.path_parts" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbInstanceId = "db.instance.id" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbJdbcDriverClassname = "db.jdbc.driver_classname" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMongodbCollection = "db.mongodb.collection" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMssqlInstanceName = "db.mssql.instance_name" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbName = "db.name" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperation = "db.operation" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbRedisDatabaseIndex = "db.redis.database_index" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSqlTable = "db.sql.table" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbStatement = "db.statement" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSystem = "db.system" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbUser = "db.user" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.All = "all" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Any = "any" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.EachQuorum = "each_quorum" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalOne = "local_one" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalQuorum = "local_quorum" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalSerial = "local_serial" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.One = "one" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Quorum = "quorum" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Serial = "serial" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Three = "three" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Two = "two" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Direct = "direct" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Gateway = "gateway" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "Batch" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Create = "Create" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Delete = "Delete" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Execute = "Execute" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ExecuteJavascript = "ExecuteJavaScript" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Head = "Head" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.HeadFeed = "HeadFeed" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Invalid = "Invalid" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Patch = "Patch" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Query = "Query" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.QueryPlan = "QueryPlan" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Read = "Read" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ReadFeed = "ReadFeed" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Replace = "Replace" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Upsert = "Upsert" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Adabas = "adabas" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cache = "cache" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cassandra = "cassandra" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Clickhouse = "clickhouse" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cloudscape = "cloudscape" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cockroachdb = "cockroachdb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Coldfusion = "coldfusion" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cosmosdb = "cosmosdb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Couchbase = "couchbase" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Couchdb = "couchdb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Db2 = "db2" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Derby = "derby" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Dynamodb = "dynamodb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Edb = "edb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Elasticsearch = "elasticsearch" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Filemaker = "filemaker" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Firebird = "firebird" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Firstsql = "firstsql" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Geode = "geode" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.H2 = "h2" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hanadb = "hanadb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hbase = "hbase" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hive = "hive" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hsqldb = "hsqldb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Informix = "informix" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Ingres = "ingres" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Instantdb = "instantdb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Interbase = "interbase" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mariadb = "mariadb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Maxdb = "maxdb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Memcached = "memcached" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mongodb = "mongodb" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mssql = "mssql" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mssqlcompact = "mssqlcompact" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mysql = "mysql" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Neo4j = "neo4j" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Netezza = "netezza" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Opensearch = "opensearch" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Oracle = "oracle" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.OtherSql = "other_sql" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Pervasive = "pervasive" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Pointbase = "pointbase" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Postgresql = "postgresql" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Progress = "progress" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Redis = "redis" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Redshift = "redshift" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Spanner = "spanner" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Sqlite = "sqlite" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Sybase = "sybase" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Teradata = "teradata" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Trino = "trino" -> string -const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Vertica = "vertica" -> string -const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentEnvironment = "deployment.environment" -> string -const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationAddress = "destination.address" -> string -const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationPort = "destination.port" -> string -const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceId = "device.id" -> string -const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceManufacturer = "device.manufacturer" -> string -const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceModelIdentifier = "device.model.identifier" -> string -const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceModelName = "device.model.name" -> string -const OpenTelemetry.SemanticConventions.DiskAttributes.AttributeDiskIoDirection = "disk.io.direction" -> string -const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Read = "read" -> string -const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Write = "write" -> string -const OpenTelemetry.SemanticConventions.DnsAttributes.AttributeDnsQuestionName = "dns.question.name" -> string -const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserId = "enduser.id" -> string -const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserRole = "enduser.role" -> string -const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserScope = "enduser.scope" -> string -const OpenTelemetry.SemanticConventions.ErrorAttributes.AttributeErrorType = "error.type" -> string -const OpenTelemetry.SemanticConventions.ErrorAttributes.ErrorTypeValues.Other = "_OTHER" -> string -const OpenTelemetry.SemanticConventions.EventAttributes.AttributeEventName = "event.name" -> string -const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionEscaped = "exception.escaped" -> string -const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionMessage = "exception.message" -> string -const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionStacktrace = "exception.stacktrace" -> string -const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionType = "exception.type" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasColdstart = "faas.coldstart" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasCron = "faas.cron" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentCollection = "faas.document.collection" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentName = "faas.document.name" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentOperation = "faas.document.operation" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentTime = "faas.document.time" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInstance = "faas.instance" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvocationId = "faas.invocation_id" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedName = "faas.invoked_name" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedProvider = "faas.invoked_provider" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedRegion = "faas.invoked_region" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasMaxMemory = "faas.max_memory" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasName = "faas.name" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasTime = "faas.time" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasTrigger = "faas.trigger" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasVersion = "faas.version" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Delete = "delete" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Edit = "edit" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Insert = "insert" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.AlibabaCloud = "alibaba_cloud" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Aws = "aws" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Azure = "azure" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Gcp = "gcp" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.TencentCloud = "tencent_cloud" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Datasource = "datasource" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Http = "http" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Other = "other" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Pubsub = "pubsub" -> string -const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Timer = "timer" -> string -const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagKey = "feature_flag.key" -> string -const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagProviderName = "feature_flag.provider_name" -> string -const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagVariant = "feature_flag.variant" -> string -const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileDirectory = "file.directory" -> string -const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileExtension = "file.extension" -> string -const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileName = "file.name" -> string -const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFilePath = "file.path" -> string -const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileSize = "file.size" -> string -const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution" -> string -const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index" -> string -const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname" -> string -const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceName = "gcp.gce.instance.name" -> string -const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlDocument = "graphql.document" -> string -const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationName = "graphql.operation.name" -> string -const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationType = "graphql.operation.type" -> string -const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Mutation = "mutation" -> string -const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Query = "query" -> string -const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Subscription = "subscription" -> string -const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuAppId = "heroku.app.id" -> string -const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuReleaseCommit = "heroku.release.commit" -> string -const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostArch = "host.arch" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuCacheL2Size = "host.cpu.cache.l2.size" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuFamily = "host.cpu.family" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuModelId = "host.cpu.model.id" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuModelName = "host.cpu.model.name" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuStepping = "host.cpu.stepping" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuVendorId = "host.cpu.vendor.id" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostId = "host.id" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageId = "host.image.id" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageName = "host.image.name" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageVersion = "host.image.version" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostIp = "host.ip" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostMac = "host.mac" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostName = "host.name" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostType = "host.type" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Amd64 = "amd64" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Arm32 = "arm32" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Arm64 = "arm64" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ia64 = "ia64" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ppc32 = "ppc32" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ppc64 = "ppc64" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.S390x = "s390x" -> string -const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.X86 = "x86" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpConnectionState = "http.connection.state" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpFlavor = "http.flavor" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpMethod = "http.method" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestBodySize = "http.request.body.size" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestContentLength = "http.request_content_length" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestHeader = "http.request.header" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestMethod = "http.request.method" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestMethodOriginal = "http.request.method_original" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestResendCount = "http.request.resend_count" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestSize = "http.request.size" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseBodySize = "http.response.body.size" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseContentLength = "http.response_content_length" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseHeader = "http.response.header" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseSize = "http.response.size" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseStatusCode = "http.response.status_code" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRoute = "http.route" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpScheme = "http.scheme" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpStatusCode = "http.status_code" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpTarget = "http.target" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpUrl = "http.url" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpUserAgent = "http.user_agent" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues.Active = "active" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues.Idle = "idle" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http10 = "1.0" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http11 = "1.1" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http20 = "2.0" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http30 = "3.0" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Quic = "QUIC" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Spdy = "SPDY" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Connect = "CONNECT" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Delete = "DELETE" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Get = "GET" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Head = "HEAD" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Options = "OPTIONS" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Other = "_OTHER" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Patch = "PATCH" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Post = "POST" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Put = "PUT" -> string -const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Trace = "TRACE" -> string -const OpenTelemetry.SemanticConventions.IosAttributes.AttributeIosState = "ios.state" -> string -const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Active = "active" -> string -const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Background = "background" -> string -const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Foreground = "foreground" -> string -const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Inactive = "inactive" -> string -const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Terminate = "terminate" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmBufferPoolName = "jvm.buffer.pool.name" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmGcAction = "jvm.gc.action" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmGcName = "jvm.gc.name" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmMemoryPoolName = "jvm.memory.pool.name" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmMemoryType = "jvm.memory.type" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmThreadDaemon = "jvm.thread.daemon" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmThreadState = "jvm.thread.state" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues.Heap = "heap" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues.NonHeap = "non_heap" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Blocked = "blocked" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.New = "new" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Runnable = "runnable" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Terminated = "terminated" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.TimedWaiting = "timed_waiting" -> string -const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Waiting = "waiting" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sClusterName = "k8s.cluster.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sClusterUid = "k8s.cluster.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerName = "k8s.container.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerRestartCount = "k8s.container.restart_count" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sCronjobName = "k8s.cronjob.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sCronjobUid = "k8s.cronjob.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDaemonsetName = "k8s.daemonset.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDaemonsetUid = "k8s.daemonset.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDeploymentName = "k8s.deployment.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDeploymentUid = "k8s.deployment.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sJobName = "k8s.job.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sJobUid = "k8s.job.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNamespaceName = "k8s.namespace.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNodeName = "k8s.node.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNodeUid = "k8s.node.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodAnnotation = "k8s.pod.annotation" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodLabel = "k8s.pod.label" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodLabels = "k8s.pod.labels" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodName = "k8s.pod.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodUid = "k8s.pod.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetName = "k8s.replicaset.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetUid = "k8s.replicaset.uid" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetName = "k8s.statefulset.name" -> string -const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetUid = "k8s.statefulset.uid" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileName = "log.file.name" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileNameResolved = "log.file.name_resolved" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePath = "log.file.path" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePathResolved = "log.file.path_resolved" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogIostream = "log.iostream" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogRecordUid = "log.record.uid" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stderr = "stderr" -> string -const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stdout = "stdout" -> string -const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageCompressedSize = "message.compressed_size" -> string -const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageId = "message.id" -> string -const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageType = "message.type" -> string -const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageUncompressedSize = "message.uncompressed_size" -> string -const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Received = "RECEIVED" -> string -const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Sent = "SENT" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingBatchMessageCount = "messaging.batch.message_count" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingClientId = "messaging.client_id" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationName = "messaging.destination.name" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishName = "messaging.destination_publish.name" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemplate = "messaging.destination.template" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemporary = "messaging.destination.temporary" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsMessageEnqueuedTime = "messaging.eventhubs.message.enqueued_time" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageBodySize = "messaging.message.body.size" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageConversationId = "messaging.message.conversation_id" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageId = "messaging.message.id" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingOperation = "messaging.operation" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRabbitmqDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqConsumptionModel = "messaging.rocketmq.consumption_model" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageDelayTimeLevel = "messaging.rocketmq.message.delay_time_level" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageDeliveryTimestamp = "messaging.rocketmq.message.delivery_timestamp" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageType = "messaging.rocketmq.message.type" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusDispositionStatus = "messaging.servicebus.disposition_status" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageDeliveryCount = "messaging.servicebus.message.delivery_count" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingSystem = "messaging.system" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Create = "create" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Deliver = "process" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Publish = "publish" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Receive = "receive" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues.Settle = "settle" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Broadcasting = "broadcasting" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Clustering = "clustering" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Delay = "delay" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Fifo = "fifo" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Normal = "normal" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Transaction = "transaction" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Abandon = "abandon" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Complete = "complete" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.DeadLetter = "dead_letter" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Defer = "defer" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Activemq = "activemq" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.AwsSqs = "aws_sqs" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Eventgrid = "eventgrid" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Eventhubs = "eventhubs" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.GcpPubsub = "gcp_pubsub" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Jms = "jms" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Kafka = "kafka" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rabbitmq = "rabbitmq" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rocketmq = "rocketmq" -> string -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Servicebus = "servicebus" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostName = "net.host.name" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostPort = "net.host.port" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerName = "net.peer.name" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerPort = "net.peer.port" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetProtocolName = "net.protocol.name" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetProtocolVersion = "net.protocol.version" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockFamily = "net.sock.family" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockHostAddr = "net.sock.host.addr" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockHostPort = "net.sock.host.port" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerAddr = "net.sock.peer.addr" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerName = "net.sock.peer.name" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerPort = "net.sock.peer.port" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetTransport = "net.transport" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Inet = "inet" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Inet6 = "inet6" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Unix = "unix" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Inproc = "inproc" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.IpTcp = "ip_tcp" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.IpUdp = "ip_udp" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Other = "other" -> string -const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Pipe = "pipe" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierIcc = "network.carrier.icc" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierMcc = "network.carrier.mcc" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierMnc = "network.carrier.mnc" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierName = "network.carrier.name" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionSubtype = "network.connection.subtype" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionType = "network.connection.type" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkIoDirection = "network.io.direction" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalAddress = "network.local.address" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalPort = "network.local.port" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkPeerAddress = "network.peer.address" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkPeerPort = "network.peer.port" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkProtocolName = "network.protocol.name" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkProtocolVersion = "network.protocol.version" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkTransport = "network.transport" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkType = "network.type" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Cdma = "cdma" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Cdma20001xrtt = "cdma2000_1xrtt" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Edge = "edge" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Ehrpd = "ehrpd" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Evdo0 = "evdo_0" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.EvdoA = "evdo_a" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.EvdoB = "evdo_b" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Gprs = "gprs" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Gsm = "gsm" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hsdpa = "hsdpa" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hspa = "hspa" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hspap = "hspap" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hsupa = "hsupa" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Iden = "iden" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Iwlan = "iwlan" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Lte = "lte" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.LteCa = "lte_ca" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Nr = "nr" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Nrnsa = "nrnsa" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.TdScdma = "td_scdma" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Umts = "umts" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Cell = "cell" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Unavailable = "unavailable" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Unknown = "unknown" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Wifi = "wifi" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Wired = "wired" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Receive = "receive" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Transmit = "transmit" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Pipe = "pipe" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Tcp = "tcp" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Udp = "udp" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Unix = "unix" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv4 = "ipv4" -> string -const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv6 = "ipv6" -> string -const OpenTelemetry.SemanticConventions.OciAttributes.AttributeOciManifestDigest = "oci.manifest.digest" -> string -const OpenTelemetry.SemanticConventions.OpentracingAttributes.AttributeOpentracingRefType = "opentracing.ref_type" -> string -const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.ChildOf = "child_of" -> string -const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.FollowsFrom = "follows_from" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsBuildId = "os.build_id" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsDescription = "os.description" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsName = "os.name" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsType = "os.type" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsVersion = "os.version" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Aix = "aix" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Darwin = "darwin" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Dragonflybsd = "dragonflybsd" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Freebsd = "freebsd" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Hpux = "hpux" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Linux = "linux" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Netbsd = "netbsd" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Openbsd = "openbsd" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Solaris = "solaris" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Windows = "windows" -> string -const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.ZOs = "z_os" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelLibraryName = "otel.library.name" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelLibraryVersion = "otel.library.version" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelScopeName = "otel.scope.name" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelScopeVersion = "otel.scope.version" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelStatusCode = "otel.status_code" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelStatusDescription = "otel.status_description" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues.Error = "ERROR" -> string -const OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues.Ok = "OK" -> string -const OpenTelemetry.SemanticConventions.OtherAttributes.AttributeState = "state" -> string -const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Idle = "idle" -> string -const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Used = "used" -> string -const OpenTelemetry.SemanticConventions.PeerAttributes.AttributePeerService = "peer.service" -> string -const OpenTelemetry.SemanticConventions.PoolAttributes.AttributePoolName = "pool.name" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommand = "process.command" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandArgs = "process.command_args" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandLine = "process.command_line" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessContextSwitchType = "process.context_switch_type" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCpuState = "process.cpu.state" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableName = "process.executable.name" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutablePath = "process.executable.path" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessOwner = "process.owner" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPagingFaultType = "process.paging.fault_type" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessParentPid = "process.parent_pid" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPid = "process.pid" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeDescription = "process.runtime.description" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeName = "process.runtime.name" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeVersion = "process.runtime.version" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Involuntary = "involuntary" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Voluntary = "voluntary" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.System = "system" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.User = "user" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.Wait = "wait" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Major = "major" -> string -const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Minor = "minor" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcRequestMetadata = "rpc.connect_rpc.request.metadata" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcResponseMetadata = "rpc.connect_rpc.response.metadata" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcRequestMetadata = "rpc.grpc.request.metadata" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcResponseMetadata = "rpc.grpc.response.metadata" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcStatusCode = "rpc.grpc.status_code" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcRequestId = "rpc.jsonrpc.request_id" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcVersion = "rpc.jsonrpc.version" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMethod = "rpc.method" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcService = "rpc.service" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcSystem = "rpc.system" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Aborted = "aborted" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.AlreadyExists = "already_exists" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Cancelled = "cancelled" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.DataLoss = "data_loss" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.DeadlineExceeded = "deadline_exceeded" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.FailedPrecondition = "failed_precondition" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Internal = "internal" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.InvalidArgument = "invalid_argument" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.NotFound = "not_found" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.OutOfRange = "out_of_range" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.PermissionDenied = "permission_denied" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.ResourceExhausted = "resource_exhausted" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unauthenticated = "unauthenticated" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unavailable = "unavailable" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unimplemented = "unimplemented" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unknown = "unknown" -> string +const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Background = "background" -> string! +const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Created = "created" -> string! +const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Foreground = "foreground" -> string! +const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidOsApiLevel = "android.os.api_level" -> string! +const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidState = "android.state" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Aborted = "aborted" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Handled = "handled" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Skipped = "skipped" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Unhandled = "unhandled" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.Acquired = "acquired" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.EndpointLimiter = "endpoint_limiter" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.GlobalLimiter = "global_limiter" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues.RequestCanceled = "request_canceled" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues.Failure = "failure" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues.Success = "success" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreDiagnosticsExceptionResult = "aspnetcore.diagnostics.exception.result" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreDiagnosticsHandlerType = "aspnetcore.diagnostics.handler.type" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRateLimitingPolicy = "aspnetcore.rate_limiting.policy" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRateLimitingResult = "aspnetcore.rate_limiting.result" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRequestIsUnhandled = "aspnetcore.request.is_unhandled" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRoutingIsFallback = "aspnetcore.routing.is_fallback" -> string! +const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AttributeAspnetcoreRoutingMatchStatus = "aspnetcore.routing.match_status" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbAttributeDefinitions = "aws.dynamodb.attribute_definitions" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbCount = "aws.dynamodb.count" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbGlobalSecondaryIndexes = "aws.dynamodb.global_secondary_indexes" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbGlobalSecondaryIndexUpdates = "aws.dynamodb.global_secondary_index_updates" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbIndexName = "aws.dynamodb.index_name" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbItemCollectionMetrics = "aws.dynamodb.item_collection_metrics" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbLimit = "aws.dynamodb.limit" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbLocalSecondaryIndexes = "aws.dynamodb.local_secondary_indexes" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProjection = "aws.dynamodb.projection" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProvisionedReadCapacity = "aws.dynamodb.provisioned_read_capacity" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbProvisionedWriteCapacity = "aws.dynamodb.provisioned_write_capacity" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbScanForward = "aws.dynamodb.scan_forward" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbScannedCount = "aws.dynamodb.scanned_count" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbSegment = "aws.dynamodb.segment" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbSelect = "aws.dynamodb.select" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTableCount = "aws.dynamodb.table_count" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTableNames = "aws.dynamodb.table_names" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsDynamodbTotalSegments = "aws.dynamodb.total_segments" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsClusterArn = "aws.ecs.cluster.arn" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsContainerArn = "aws.ecs.container.arn" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsLaunchtype = "aws.ecs.launchtype" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskArn = "aws.ecs.task.arn" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskFamily = "aws.ecs.task.family" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskId = "aws.ecs.task.id" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEcsTaskRevision = "aws.ecs.task.revision" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsEksClusterArn = "aws.eks.cluster.arn" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLambdaInvokedArn = "aws.lambda.invoked_arn" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogGroupArns = "aws.log.group.arns" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogGroupNames = "aws.log.group.names" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogStreamArns = "aws.log.stream.arns" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsLogStreamNames = "aws.log.stream.names" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsRequestId = "aws.request_id" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Bucket = "aws.s3.bucket" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3CopySource = "aws.s3.copy_source" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Delete = "aws.s3.delete" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3Key = "aws.s3.key" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3PartNumber = "aws.s3.part_number" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3UploadId = "aws.s3.upload_id" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Ec2 = "ec2" -> string! +const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Fargate = "fargate" -> string! +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserBrands = "browser.brands" -> string! +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserLanguage = "browser.language" -> string! +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserMobile = "browser.mobile" -> string! +const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserPlatform = "browser.platform" -> string! +const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientAddress = "client.address" -> string! +const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientPort = "client.port" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAccountId = "cloud.account.id" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAvailabilityZone = "cloud.availability_zone" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudPlatform = "cloud.platform" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudProvider = "cloud.provider" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudRegion = "cloud.region" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudResourceId = "cloud.resource_id" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudEcs = "alibaba_cloud_ecs" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudFc = "alibaba_cloud_fc" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AlibabaCloudOpenshift = "alibaba_cloud_openshift" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsAppRunner = "aws_app_runner" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEc2 = "aws_ec2" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEcs = "aws_ecs" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsEks = "aws_eks" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsElasticBeanstalk = "aws_elastic_beanstalk" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsLambda = "aws_lambda" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AwsOpenshift = "aws_openshift" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureAks = "azure_aks" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureAppService = "azure_app_service" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureContainerApps = "azure_container_apps" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureContainerInstances = "azure_container_instances" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureFunctions = "azure_functions" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureOpenshift = "azure_openshift" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.AzureVm = "azure_vm" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpAppEngine = "gcp_app_engine" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpBareMetalSolution = "gcp_bare_metal_solution" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpCloudFunctions = "gcp_cloud_functions" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpCloudRun = "gcp_cloud_run" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpComputeEngine = "gcp_compute_engine" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpKubernetesEngine = "gcp_kubernetes_engine" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.GcpOpenshift = "gcp_openshift" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.IbmCloudOpenshift = "ibm_cloud_openshift" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudCvm = "tencent_cloud_cvm" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudEks = "tencent_cloud_eks" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues.TencentCloudScf = "tencent_cloud_scf" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.AlibabaCloud = "alibaba_cloud" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Aws = "aws" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Azure = "azure" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Gcp = "gcp" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.Heroku = "heroku" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.IbmCloud = "ibm_cloud" -> string! +const OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues.TencentCloud = "tencent_cloud" -> string! +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventId = "cloudevents.event_id" -> string! +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSource = "cloudevents.event_source" -> string! +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version" -> string! +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSubject = "cloudevents.event_subject" -> string! +const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventType = "cloudevents.event_type" -> string! +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeColumn = "code.column" -> string! +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFilepath = "code.filepath" -> string! +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFunction = "code.function" -> string! +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeLineno = "code.lineno" -> string! +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeNamespace = "code.namespace" -> string! +const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeStacktrace = "code.stacktrace" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommand = "container.command" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandArgs = "container.command_args" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandLine = "container.command_line" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCpuState = "container.cpu.state" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerId = "container.id" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageId = "container.image.id" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageName = "container.image.name" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageRepoDigests = "container.image.repo_digests" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageTags = "container.image.tags" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerLabelsTemplate = "container.labels" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerLabelTemplate = "container.label" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerName = "container.name" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerRuntime = "container.runtime" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.Kernel = "kernel" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.System = "system" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.User = "user" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraIdempotence = "db.cassandra.idempotence" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraPageSize = "db.cassandra.page_size" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraTable = "db.cassandra.table" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbClientConnectionsPoolName = "db.client.connections.pool.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbClientConnectionsState = "db.client.connections.state" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCollectionName = "db.collection.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbConnectionString = "db.connection_string" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbClientId = "db.cosmosdb.client_id" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbContainer = "db.cosmosdb.container" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchNodeName = "db.elasticsearch.node.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbElasticsearchPathPartsTemplate = "db.elasticsearch.path_parts" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbInstanceId = "db.instance.id" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbJdbcDriverClassname = "db.jdbc.driver_classname" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMongodbCollection = "db.mongodb.collection" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMssqlInstanceName = "db.mssql.instance_name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbName = "db.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbNamespace = "db.namespace" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperation = "db.operation" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationName = "db.operation.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryParameterTemplate = "db.query.parameter" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryText = "db.query.text" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbRedisDatabaseIndex = "db.redis.database_index" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSqlTable = "db.sql.table" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbStatement = "db.statement" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSystem = "db.system" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbUser = "db.user" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.All = "all" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Any = "any" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.EachQuorum = "each_quorum" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalOne = "local_one" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalQuorum = "local_quorum" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.LocalSerial = "local_serial" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.One = "one" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Quorum = "quorum" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Serial = "serial" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Three = "three" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Two = "two" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues.Idle = "idle" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues.Used = "used" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Direct = "direct" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Gateway = "gateway" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "Batch" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Create = "Create" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Delete = "Delete" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Execute = "Execute" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ExecuteJavascript = "ExecuteJavaScript" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Head = "Head" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.HeadFeed = "HeadFeed" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Invalid = "Invalid" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Patch = "Patch" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Query = "Query" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.QueryPlan = "QueryPlan" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Read = "Read" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ReadFeed = "ReadFeed" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Replace = "Replace" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Upsert = "Upsert" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Adabas = "adabas" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cache = "cache" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cassandra = "cassandra" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Clickhouse = "clickhouse" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cloudscape = "cloudscape" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cockroachdb = "cockroachdb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Coldfusion = "coldfusion" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cosmosdb = "cosmosdb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Couchbase = "couchbase" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Couchdb = "couchdb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Db2 = "db2" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Derby = "derby" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Dynamodb = "dynamodb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Edb = "edb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Elasticsearch = "elasticsearch" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Filemaker = "filemaker" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Firebird = "firebird" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Firstsql = "firstsql" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Geode = "geode" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.H2 = "h2" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hanadb = "hanadb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hbase = "hbase" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hive = "hive" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hsqldb = "hsqldb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Informix = "informix" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Ingres = "ingres" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Instantdb = "instantdb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Interbase = "interbase" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mariadb = "mariadb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Maxdb = "maxdb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Memcached = "memcached" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mongodb = "mongodb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mssql = "mssql" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mssqlcompact = "mssqlcompact" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mysql = "mysql" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Neo4j = "neo4j" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Netezza = "netezza" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Opensearch = "opensearch" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Oracle = "oracle" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.OtherSql = "other_sql" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Pervasive = "pervasive" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Pointbase = "pointbase" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Postgresql = "postgresql" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Progress = "progress" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Redis = "redis" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Redshift = "redshift" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Spanner = "spanner" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Sqlite = "sqlite" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Sybase = "sybase" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Teradata = "teradata" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Trino = "trino" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Vertica = "vertica" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentEnvironment = "deployment.environment" -> string! +const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationAddress = "destination.address" -> string! +const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationPort = "destination.port" -> string! +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceId = "device.id" -> string! +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceManufacturer = "device.manufacturer" -> string! +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceModelIdentifier = "device.model.identifier" -> string! +const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceModelName = "device.model.name" -> string! +const OpenTelemetry.SemanticConventions.DiskAttributes.AttributeDiskIoDirection = "disk.io.direction" -> string! +const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Read = "read" -> string! +const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Write = "write" -> string! +const OpenTelemetry.SemanticConventions.DnsAttributes.AttributeDnsQuestionName = "dns.question.name" -> string! +const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserId = "enduser.id" -> string! +const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserRole = "enduser.role" -> string! +const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserScope = "enduser.scope" -> string! +const OpenTelemetry.SemanticConventions.ErrorAttributes.AttributeErrorType = "error.type" -> string! +const OpenTelemetry.SemanticConventions.ErrorAttributes.ErrorTypeValues.Other = "_OTHER" -> string! +const OpenTelemetry.SemanticConventions.EventAttributes.AttributeEventName = "event.name" -> string! +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionEscaped = "exception.escaped" -> string! +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionMessage = "exception.message" -> string! +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionStacktrace = "exception.stacktrace" -> string! +const OpenTelemetry.SemanticConventions.ExceptionAttributes.AttributeExceptionType = "exception.type" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasColdstart = "faas.coldstart" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasCron = "faas.cron" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentCollection = "faas.document.collection" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentName = "faas.document.name" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentOperation = "faas.document.operation" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasDocumentTime = "faas.document.time" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInstance = "faas.instance" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvocationId = "faas.invocation_id" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedName = "faas.invoked_name" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedProvider = "faas.invoked_provider" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasInvokedRegion = "faas.invoked_region" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasMaxMemory = "faas.max_memory" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasName = "faas.name" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasTime = "faas.time" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasTrigger = "faas.trigger" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.AttributeFaasVersion = "faas.version" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Delete = "delete" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Edit = "edit" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues.Insert = "insert" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.AlibabaCloud = "alibaba_cloud" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Aws = "aws" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Azure = "azure" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.Gcp = "gcp" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues.TencentCloud = "tencent_cloud" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Datasource = "datasource" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Http = "http" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Other = "other" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Pubsub = "pubsub" -> string! +const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Timer = "timer" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagKey = "feature_flag.key" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagProviderName = "feature_flag.provider_name" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagVariant = "feature_flag.variant" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileDirectory = "file.directory" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileExtension = "file.extension" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileName = "file.name" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFilePath = "file.path" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileSize = "file.size" -> string! +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution" -> string! +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index" -> string! +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname" -> string! +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceName = "gcp.gce.instance.name" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiCompletion = "gen_ai.completion" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiPrompt = "gen_ai.prompt" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestMaxTokens = "gen_ai.request.max_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestModel = "gen_ai.request.model" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestTemperature = "gen_ai.request.temperature" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestTopP = "gen_ai.request.top_p" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiResponseFinishReasons = "gen_ai.response.finish_reasons" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiResponseId = "gen_ai.response.id" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiResponseModel = "gen_ai.response.model" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiSystem = "gen_ai.system" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageCompletionTokens = "gen_ai.usage.completion_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Openai = "openai" -> string! +const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlDocument = "graphql.document" -> string! +const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationName = "graphql.operation.name" -> string! +const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationType = "graphql.operation.type" -> string! +const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Mutation = "mutation" -> string! +const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Query = "query" -> string! +const OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues.Subscription = "subscription" -> string! +const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuAppId = "heroku.app.id" -> string! +const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuReleaseCommit = "heroku.release.commit" -> string! +const OpenTelemetry.SemanticConventions.HerokuAttributes.AttributeHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostArch = "host.arch" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuCacheL2Size = "host.cpu.cache.l2.size" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuFamily = "host.cpu.family" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuModelId = "host.cpu.model.id" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuModelName = "host.cpu.model.name" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuStepping = "host.cpu.stepping" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostCpuVendorId = "host.cpu.vendor.id" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostId = "host.id" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageId = "host.image.id" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageName = "host.image.name" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostImageVersion = "host.image.version" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostIp = "host.ip" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostMac = "host.mac" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostName = "host.name" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.AttributeHostType = "host.type" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Amd64 = "amd64" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Arm32 = "arm32" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Arm64 = "arm64" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ia64 = "ia64" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ppc32 = "ppc32" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.Ppc64 = "ppc64" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.S390x = "s390x" -> string! +const OpenTelemetry.SemanticConventions.HostAttributes.HostArchValues.X86 = "x86" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpClientIp = "http.client_ip" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpConnectionState = "http.connection.state" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpFlavor = "http.flavor" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpHost = "http.host" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpMethod = "http.method" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestBodySize = "http.request.body.size" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestContentLength = "http.request_content_length" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestContentLengthUncompressed = "http.request_content_length_uncompressed" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestHeaderTemplate = "http.request.header" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestMethod = "http.request.method" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestMethodOriginal = "http.request.method_original" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestResendCount = "http.request.resend_count" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRequestSize = "http.request.size" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseBodySize = "http.response.body.size" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseContentLength = "http.response_content_length" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseContentLengthUncompressed = "http.response_content_length_uncompressed" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseHeaderTemplate = "http.response.header" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseSize = "http.response.size" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpResponseStatusCode = "http.response.status_code" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpRoute = "http.route" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpScheme = "http.scheme" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpServerName = "http.server_name" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpStatusCode = "http.status_code" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpTarget = "http.target" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpUrl = "http.url" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.AttributeHttpUserAgent = "http.user_agent" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues.Active = "active" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues.Idle = "idle" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http10 = "1.0" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http11 = "1.1" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http20 = "2.0" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Http30 = "3.0" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Quic = "QUIC" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues.Spdy = "SPDY" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Connect = "CONNECT" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Delete = "DELETE" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Get = "GET" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Head = "HEAD" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Options = "OPTIONS" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Other = "_OTHER" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Patch = "PATCH" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Post = "POST" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Put = "PUT" -> string! +const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Trace = "TRACE" -> string! +const OpenTelemetry.SemanticConventions.IosAttributes.AttributeIosState = "ios.state" -> string! +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Active = "active" -> string! +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Background = "background" -> string! +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Foreground = "foreground" -> string! +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Inactive = "inactive" -> string! +const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Terminate = "terminate" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmBufferPoolName = "jvm.buffer.pool.name" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmGcAction = "jvm.gc.action" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmGcName = "jvm.gc.name" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmMemoryPoolName = "jvm.memory.pool.name" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmMemoryType = "jvm.memory.type" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmThreadDaemon = "jvm.thread.daemon" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.AttributeJvmThreadState = "jvm.thread.state" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues.Heap = "heap" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues.NonHeap = "non_heap" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Blocked = "blocked" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.New = "new" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Runnable = "runnable" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Terminated = "terminated" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.TimedWaiting = "timed_waiting" -> string! +const OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues.Waiting = "waiting" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sClusterName = "k8s.cluster.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sClusterUid = "k8s.cluster.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerName = "k8s.container.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerRestartCount = "k8s.container.restart_count" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sContainerStatusLastTerminatedReason = "k8s.container.status.last_terminated_reason" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sCronjobName = "k8s.cronjob.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sCronjobUid = "k8s.cronjob.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDaemonsetName = "k8s.daemonset.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDaemonsetUid = "k8s.daemonset.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDeploymentName = "k8s.deployment.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sDeploymentUid = "k8s.deployment.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sJobName = "k8s.job.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sJobUid = "k8s.job.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNamespaceName = "k8s.namespace.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNodeName = "k8s.node.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sNodeUid = "k8s.node.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodAnnotationTemplate = "k8s.pod.annotation" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodLabelsTemplate = "k8s.pod.labels" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodLabelTemplate = "k8s.pod.label" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodName = "k8s.pod.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sPodUid = "k8s.pod.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetName = "k8s.replicaset.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetUid = "k8s.replicaset.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetName = "k8s.statefulset.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetUid = "k8s.statefulset.uid" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileName = "log.file.name" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileNameResolved = "log.file.name_resolved" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePath = "log.file.path" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePathResolved = "log.file.path_resolved" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogIostream = "log.iostream" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogRecordUid = "log.record.uid" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stderr = "stderr" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stdout = "stdout" -> string! +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageCompressedSize = "message.compressed_size" -> string! +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageId = "message.id" -> string! +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageType = "message.type" -> string! +const OpenTelemetry.SemanticConventions.MessageAttributes.AttributeMessageUncompressedSize = "message.uncompressed_size" -> string! +const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Received = "RECEIVED" -> string! +const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Sent = "SENT" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingBatchMessageCount = "messaging.batch.message_count" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingClientId = "messaging.client.id" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationName = "messaging.destination.name" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishName = "messaging.destination_publish.name" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemplate = "messaging.destination.template" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemporary = "messaging.destination.temporary" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsMessageEnqueuedTime = "messaging.eventhubs.message.enqueued_time" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingGcpPubsubMessageAckDeadline = "messaging.gcp_pubsub.message.ack_deadline" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingGcpPubsubMessageAckId = "messaging.gcp_pubsub.message.ack_id" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingGcpPubsubMessageDeliveryAttempt = "messaging.gcp_pubsub.message.delivery_attempt" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageBodySize = "messaging.message.body.size" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageConversationId = "messaging.message.conversation_id" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageId = "messaging.message.id" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingOperation = "messaging.operation" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingOperationName = "messaging.operation.name" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingOperationType = "messaging.operation.type" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRabbitmqDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqConsumptionModel = "messaging.rocketmq.consumption_model" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageDelayTimeLevel = "messaging.rocketmq.message.delay_time_level" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageDeliveryTimestamp = "messaging.rocketmq.message.delivery_timestamp" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqMessageType = "messaging.rocketmq.message.type" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusDispositionStatus = "messaging.servicebus.disposition_status" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageDeliveryCount = "messaging.servicebus.message.delivery_count" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingSystem = "messaging.system" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Create = "create" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Deliver = "process" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Publish = "publish" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Receive = "receive" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Settle = "settle" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Broadcasting = "broadcasting" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Clustering = "clustering" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Delay = "delay" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Fifo = "fifo" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Normal = "normal" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues.Transaction = "transaction" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Abandon = "abandon" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Complete = "complete" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.DeadLetter = "dead_letter" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues.Defer = "defer" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Activemq = "activemq" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.AwsSqs = "aws_sqs" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Eventgrid = "eventgrid" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Eventhubs = "eventhubs" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.GcpPubsub = "gcp_pubsub" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Jms = "jms" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Kafka = "kafka" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rabbitmq = "rabbitmq" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rocketmq = "rocketmq" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Servicebus = "servicebus" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostIp = "net.host.ip" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostName = "net.host.name" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetHostPort = "net.host.port" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerIp = "net.peer.ip" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerName = "net.peer.name" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetPeerPort = "net.peer.port" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetProtocolName = "net.protocol.name" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetProtocolVersion = "net.protocol.version" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockFamily = "net.sock.family" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockHostAddr = "net.sock.host.addr" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockHostPort = "net.sock.host.port" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerAddr = "net.sock.peer.addr" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerName = "net.sock.peer.name" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetSockPeerPort = "net.sock.peer.port" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.AttributeNetTransport = "net.transport" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Inet = "inet" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Inet6 = "inet6" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetSockFamilyValues.Unix = "unix" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Inproc = "inproc" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.IpTcp = "ip_tcp" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.IpUdp = "ip_udp" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Other = "other" -> string! +const OpenTelemetry.SemanticConventions.NetAttributes.NetTransportValues.Pipe = "pipe" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierIcc = "network.carrier.icc" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierMcc = "network.carrier.mcc" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierMnc = "network.carrier.mnc" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierName = "network.carrier.name" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionSubtype = "network.connection.subtype" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionType = "network.connection.type" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkIoDirection = "network.io.direction" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalAddress = "network.local.address" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalPort = "network.local.port" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkPeerAddress = "network.peer.address" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkPeerPort = "network.peer.port" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkProtocolName = "network.protocol.name" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkProtocolVersion = "network.protocol.version" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkTransport = "network.transport" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkType = "network.type" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Cdma = "cdma" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Cdma20001xrtt = "cdma2000_1xrtt" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Edge = "edge" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Ehrpd = "ehrpd" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Evdo0 = "evdo_0" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.EvdoA = "evdo_a" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.EvdoB = "evdo_b" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Gprs = "gprs" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Gsm = "gsm" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hsdpa = "hsdpa" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hspa = "hspa" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hspap = "hspap" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Hsupa = "hsupa" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Iden = "iden" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Iwlan = "iwlan" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Lte = "lte" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.LteCa = "lte_ca" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Nr = "nr" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Nrnsa = "nrnsa" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.TdScdma = "td_scdma" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionSubtypeValues.Umts = "umts" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Cell = "cell" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Unavailable = "unavailable" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Unknown = "unknown" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Wifi = "wifi" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues.Wired = "wired" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Receive = "receive" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Transmit = "transmit" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Pipe = "pipe" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Tcp = "tcp" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Udp = "udp" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Unix = "unix" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv4 = "ipv4" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv6 = "ipv6" -> string! +const OpenTelemetry.SemanticConventions.OciAttributes.AttributeOciManifestDigest = "oci.manifest.digest" -> string! +const OpenTelemetry.SemanticConventions.OpentracingAttributes.AttributeOpentracingRefType = "opentracing.ref_type" -> string! +const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.ChildOf = "child_of" -> string! +const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.FollowsFrom = "follows_from" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsBuildId = "os.build_id" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsDescription = "os.description" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsName = "os.name" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsType = "os.type" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.AttributeOsVersion = "os.version" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Aix = "aix" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Darwin = "darwin" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Dragonflybsd = "dragonflybsd" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Freebsd = "freebsd" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Hpux = "hpux" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Linux = "linux" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Netbsd = "netbsd" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Openbsd = "openbsd" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Solaris = "solaris" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.Windows = "windows" -> string! +const OpenTelemetry.SemanticConventions.OsAttributes.OsTypeValues.ZOs = "z_os" -> string! +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelScopeName = "otel.scope.name" -> string! +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelScopeVersion = "otel.scope.version" -> string! +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelStatusCode = "otel.status_code" -> string! +const OpenTelemetry.SemanticConventions.OtelAttributes.AttributeOtelStatusDescription = "otel.status_description" -> string! +const OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues.Error = "ERROR" -> string! +const OpenTelemetry.SemanticConventions.OtelAttributes.OtelStatusCodeValues.Ok = "OK" -> string! +const OpenTelemetry.SemanticConventions.OtherAttributes.AttributeState = "state" -> string! +const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Idle = "idle" -> string! +const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Used = "used" -> string! +const OpenTelemetry.SemanticConventions.PeerAttributes.AttributePeerService = "peer.service" -> string! +const OpenTelemetry.SemanticConventions.PoolAttributes.AttributePoolName = "pool.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommand = "process.command" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandArgs = "process.command_args" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandLine = "process.command_line" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessContextSwitchType = "process.context_switch_type" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCpuState = "process.cpu.state" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCreationTime = "process.creation.time" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableName = "process.executable.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutablePath = "process.executable.path" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExitCode = "process.exit.code" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExitTime = "process.exit.time" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessGroupLeaderPid = "process.group_leader.pid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessInteractive = "process.interactive" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessOwner = "process.owner" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPagingFaultType = "process.paging.fault_type" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessParentPid = "process.parent_pid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPid = "process.pid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRealUserId = "process.real_user.id" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRealUserName = "process.real_user.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeDescription = "process.runtime.description" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeName = "process.runtime.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntimeVersion = "process.runtime.version" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessSavedUserId = "process.saved_user.id" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessSavedUserName = "process.saved_user.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessSessionLeaderPid = "process.session_leader.pid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessUserId = "process.user.id" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessUserName = "process.user.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessVpid = "process.vpid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Involuntary = "involuntary" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Voluntary = "voluntary" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.System = "system" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.User = "user" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.Wait = "wait" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Major = "major" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Minor = "minor" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcRequestMetadataTemplate = "rpc.connect_rpc.request.metadata" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcResponseMetadataTemplate = "rpc.connect_rpc.response.metadata" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcRequestMetadataTemplate = "rpc.grpc.request.metadata" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcResponseMetadataTemplate = "rpc.grpc.response.metadata" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcGrpcStatusCode = "rpc.grpc.status_code" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcRequestId = "rpc.jsonrpc.request_id" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcJsonrpcVersion = "rpc.jsonrpc.version" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMessageCompressedSize = "rpc.message.compressed_size" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMessageId = "rpc.message.id" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMessageType = "rpc.message.type" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMessageUncompressedSize = "rpc.message.uncompressed_size" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcMethod = "rpc.method" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcService = "rpc.service" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcSystem = "rpc.system" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Aborted = "aborted" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.AlreadyExists = "already_exists" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Cancelled = "cancelled" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.DataLoss = "data_loss" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.DeadlineExceeded = "deadline_exceeded" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.FailedPrecondition = "failed_precondition" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Internal = "internal" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.InvalidArgument = "invalid_argument" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.NotFound = "not_found" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.OutOfRange = "out_of_range" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.PermissionDenied = "permission_denied" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.ResourceExhausted = "resource_exhausted" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unauthenticated = "unauthenticated" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unavailable = "unavailable" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unimplemented = "unimplemented" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues.Unknown = "unknown" -> string! const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Aborted = 10 -> int const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.AlreadyExists = 6 -> int const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Cancelled = 1 -> int @@ -673,158 +723,161 @@ const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Un const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unavailable = 14 -> int const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unimplemented = 12 -> int const OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues.Unknown = 2 -> int -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.ApacheDubbo = "apache_dubbo" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.ConnectRpc = "connect_rpc" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.DotnetWcf = "dotnet_wcf" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.Grpc = "grpc" -> string -const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.JavaRmi = "java_rmi" -> string -const OpenTelemetry.SemanticConventions.ServerAttributes.AttributeServerAddress = "server.address" -> string -const OpenTelemetry.SemanticConventions.ServerAttributes.AttributeServerPort = "server.port" -> string -const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceInstanceId = "service.instance.id" -> string -const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceName = "service.name" -> string -const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceNamespace = "service.namespace" -> string -const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceVersion = "service.version" -> string -const OpenTelemetry.SemanticConventions.SessionAttributes.AttributeSessionId = "session.id" -> string -const OpenTelemetry.SemanticConventions.SessionAttributes.AttributeSessionPreviousId = "session.previous_id" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.AttributeSignalrConnectionStatus = "signalr.connection.status" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.AttributeSignalrTransport = "signalr.transport" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.AppShutdown = "app_shutdown" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.NormalClosure = "normal_closure" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.Timeout = "timeout" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.LongPolling = "long_polling" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.ServerSentEvents = "server_sent_events" -> string -const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.WebSockets = "web_sockets" -> string -const OpenTelemetry.SemanticConventions.SourceAttributes.AttributeSourceAddress = "source.address" -> string -const OpenTelemetry.SemanticConventions.SourceAttributes.AttributeSourcePort = "source.port" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemCpuLogicalNumber = "system.cpu.logical_number" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemCpuState = "system.cpu.state" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemDevice = "system.device" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemMode = "system.filesystem.mode" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemMountpoint = "system.filesystem.mountpoint" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemState = "system.filesystem.state" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemType = "system.filesystem.type" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemMemoryState = "system.memory.state" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemNetworkState = "system.network.state" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingDirection = "system.paging.direction" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingState = "system.paging.state" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingType = "system.paging.type" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemProcessesStatus = "system.processes.status" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemProcessStatus = "system.process.status" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Idle = "idle" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Interrupt = "interrupt" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Iowait = "iowait" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Nice = "nice" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Steal = "steal" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.System = "system" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.User = "user" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Free = "free" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Reserved = "reserved" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Used = "used" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Exfat = "exfat" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Ext4 = "ext4" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Fat32 = "fat32" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Hfsplus = "hfsplus" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Ntfs = "ntfs" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Refs = "refs" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Buffers = "buffers" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Cached = "cached" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Free = "free" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Shared = "shared" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Used = "used" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Close = "close" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.CloseWait = "close_wait" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Closing = "closing" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Delete = "delete" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Established = "established" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.FinWait1 = "fin_wait_1" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.FinWait2 = "fin_wait_2" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.LastAck = "last_ack" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Listen = "listen" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.SynRecv = "syn_recv" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.SynSent = "syn_sent" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.TimeWait = "time_wait" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues.In = "in" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues.Out = "out" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues.Free = "free" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues.Used = "used" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues.Major = "major" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues.Minor = "minor" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Defunct = "defunct" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Running = "running" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Sleeping = "sleeping" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Stopped = "stopped" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Defunct = "defunct" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Running = "running" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Sleeping = "sleeping" -> string -const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Stopped = "stopped" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetryDistroName = "telemetry.distro.name" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetryDistroVersion = "telemetry.distro.version" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkLanguage = "telemetry.sdk.language" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkName = "telemetry.sdk.name" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkVersion = "telemetry.sdk.version" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Cpp = "cpp" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Dotnet = "dotnet" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Erlang = "erlang" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Go = "go" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Java = "java" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Nodejs = "nodejs" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Php = "php" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Python = "python" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Ruby = "ruby" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Rust = "rust" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Swift = "swift" -> string -const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Webjs = "webjs" -> string -const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadId = "thread.id" -> string -const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadName = "thread.name" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCipher = "tls.cipher" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientCertificate = "tls.client.certificate" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientCertificateChain = "tls.client.certificate_chain" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashMd5 = "tls.client.hash.md5" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashSha1 = "tls.client.hash.sha1" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashSha256 = "tls.client.hash.sha256" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientIssuer = "tls.client.issuer" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientJa3 = "tls.client.ja3" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientNotAfter = "tls.client.not_after" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientNotBefore = "tls.client.not_before" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientServerName = "tls.client.server_name" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientSubject = "tls.client.subject" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientSupportedCiphers = "tls.client.supported_ciphers" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCurve = "tls.curve" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsEstablished = "tls.established" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsNextProtocol = "tls.next_protocol" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsProtocolName = "tls.protocol.name" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsProtocolVersion = "tls.protocol.version" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsResumed = "tls.resumed" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerCertificate = "tls.server.certificate" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerCertificateChain = "tls.server.certificate_chain" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashMd5 = "tls.server.hash.md5" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashSha1 = "tls.server.hash.sha1" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashSha256 = "tls.server.hash.sha256" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerIssuer = "tls.server.issuer" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerJa3s = "tls.server.ja3s" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerNotAfter = "tls.server.not_after" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerNotBefore = "tls.server.not_before" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerSubject = "tls.server.subject" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues.Ssl = "ssl" -> string -const OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues.Tls = "tls" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlDomain = "url.domain" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlExtension = "url.extension" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlFragment = "url.fragment" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlFull = "url.full" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlOriginal = "url.original" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlPath = "url.path" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlPort = "url.port" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlQuery = "url.query" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlRegisteredDomain = "url.registered_domain" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlScheme = "url.scheme" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlSubdomain = "url.subdomain" -> string -const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTopLevelDomain = "url.top_level_domain" -> string -const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentName = "user_agent.name" -> string -const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentOriginal = "user_agent.original" -> string -const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentVersion = "user_agent.version" -> string -const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineDescription = "webengine.description" -> string -const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineName = "webengine.name" -> string -const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineVersion = "webengine.version" -> string +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcMessageTypeValues.Received = "RECEIVED" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcMessageTypeValues.Sent = "SENT" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.ApacheDubbo = "apache_dubbo" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.ConnectRpc = "connect_rpc" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.DotnetWcf = "dotnet_wcf" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.Grpc = "grpc" -> string! +const OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues.JavaRmi = "java_rmi" -> string! +const OpenTelemetry.SemanticConventions.ServerAttributes.AttributeServerAddress = "server.address" -> string! +const OpenTelemetry.SemanticConventions.ServerAttributes.AttributeServerPort = "server.port" -> string! +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceInstanceId = "service.instance.id" -> string! +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceName = "service.name" -> string! +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceNamespace = "service.namespace" -> string! +const OpenTelemetry.SemanticConventions.ServiceAttributes.AttributeServiceVersion = "service.version" -> string! +const OpenTelemetry.SemanticConventions.SessionAttributes.AttributeSessionId = "session.id" -> string! +const OpenTelemetry.SemanticConventions.SessionAttributes.AttributeSessionPreviousId = "session.previous_id" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.AttributeSignalrConnectionStatus = "signalr.connection.status" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.AttributeSignalrTransport = "signalr.transport" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.AppShutdown = "app_shutdown" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.NormalClosure = "normal_closure" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrConnectionStatusValues.Timeout = "timeout" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.LongPolling = "long_polling" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.ServerSentEvents = "server_sent_events" -> string! +const OpenTelemetry.SemanticConventions.SignalrAttributes.SignalrTransportValues.WebSockets = "web_sockets" -> string! +const OpenTelemetry.SemanticConventions.SourceAttributes.AttributeSourceAddress = "source.address" -> string! +const OpenTelemetry.SemanticConventions.SourceAttributes.AttributeSourcePort = "source.port" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemCpuLogicalNumber = "system.cpu.logical_number" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemCpuState = "system.cpu.state" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemDevice = "system.device" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemMode = "system.filesystem.mode" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemMountpoint = "system.filesystem.mountpoint" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemState = "system.filesystem.state" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemFilesystemType = "system.filesystem.type" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemMemoryState = "system.memory.state" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemNetworkState = "system.network.state" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingDirection = "system.paging.direction" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingState = "system.paging.state" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemPagingType = "system.paging.type" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemProcessesStatus = "system.processes.status" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.AttributeSystemProcessStatus = "system.process.status" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Idle = "idle" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Interrupt = "interrupt" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Iowait = "iowait" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Nice = "nice" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.Steal = "steal" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.System = "system" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemCpuStateValues.User = "user" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Free = "free" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Reserved = "reserved" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemStateValues.Used = "used" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Exfat = "exfat" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Ext4 = "ext4" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Fat32 = "fat32" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Hfsplus = "hfsplus" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Ntfs = "ntfs" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemFilesystemTypeValues.Refs = "refs" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Buffers = "buffers" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Cached = "cached" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Free = "free" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Shared = "shared" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemMemoryStateValues.Used = "used" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Close = "close" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.CloseWait = "close_wait" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Closing = "closing" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Delete = "delete" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Established = "established" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.FinWait1 = "fin_wait_1" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.FinWait2 = "fin_wait_2" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.LastAck = "last_ack" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.Listen = "listen" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.SynRecv = "syn_recv" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.SynSent = "syn_sent" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemNetworkStateValues.TimeWait = "time_wait" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues.In = "in" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingDirectionValues.Out = "out" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues.Free = "free" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingStateValues.Used = "used" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues.Major = "major" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemPagingTypeValues.Minor = "minor" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Defunct = "defunct" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Running = "running" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Sleeping = "sleeping" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues.Stopped = "stopped" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Defunct = "defunct" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Running = "running" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Sleeping = "sleeping" -> string! +const OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues.Stopped = "stopped" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetryDistroName = "telemetry.distro.name" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetryDistroVersion = "telemetry.distro.version" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkLanguage = "telemetry.sdk.language" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkName = "telemetry.sdk.name" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.AttributeTelemetrySdkVersion = "telemetry.sdk.version" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Cpp = "cpp" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Dotnet = "dotnet" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Erlang = "erlang" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Go = "go" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Java = "java" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Nodejs = "nodejs" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Php = "php" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Python = "python" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Ruby = "ruby" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Rust = "rust" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Swift = "swift" -> string! +const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Webjs = "webjs" -> string! +const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadId = "thread.id" -> string! +const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadName = "thread.name" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCipher = "tls.cipher" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientCertificate = "tls.client.certificate" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientCertificateChain = "tls.client.certificate_chain" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashMd5 = "tls.client.hash.md5" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashSha1 = "tls.client.hash.sha1" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientHashSha256 = "tls.client.hash.sha256" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientIssuer = "tls.client.issuer" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientJa3 = "tls.client.ja3" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientNotAfter = "tls.client.not_after" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientNotBefore = "tls.client.not_before" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientServerName = "tls.client.server_name" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientSubject = "tls.client.subject" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsClientSupportedCiphers = "tls.client.supported_ciphers" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCurve = "tls.curve" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsEstablished = "tls.established" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsNextProtocol = "tls.next_protocol" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsProtocolName = "tls.protocol.name" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsProtocolVersion = "tls.protocol.version" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsResumed = "tls.resumed" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerCertificate = "tls.server.certificate" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerCertificateChain = "tls.server.certificate_chain" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashMd5 = "tls.server.hash.md5" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashSha1 = "tls.server.hash.sha1" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerHashSha256 = "tls.server.hash.sha256" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerIssuer = "tls.server.issuer" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerJa3s = "tls.server.ja3s" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerNotAfter = "tls.server.not_after" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerNotBefore = "tls.server.not_before" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsServerSubject = "tls.server.subject" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues.Ssl = "ssl" -> string! +const OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues.Tls = "tls" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlDomain = "url.domain" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlExtension = "url.extension" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlFragment = "url.fragment" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlFull = "url.full" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlOriginal = "url.original" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlPath = "url.path" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlPort = "url.port" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlQuery = "url.query" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlRegisteredDomain = "url.registered_domain" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlScheme = "url.scheme" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlSubdomain = "url.subdomain" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTemplate = "url.template" -> string! +const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTopLevelDomain = "url.top_level_domain" -> string! +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentName = "user_agent.name" -> string! +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentOriginal = "user_agent.original" -> string! +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentVersion = "user_agent.version" -> string! +const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineDescription = "webengine.description" -> string! +const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineName = "webengine.name" -> string! +const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineVersion = "webengine.version" -> string! OpenTelemetry.SemanticConventions.AndroidAttributes OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues OpenTelemetry.SemanticConventions.AspnetcoreAttributes @@ -844,6 +897,7 @@ OpenTelemetry.SemanticConventions.ContainerAttributes OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues OpenTelemetry.SemanticConventions.DbAttributes OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues +OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues @@ -865,6 +919,8 @@ OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues OpenTelemetry.SemanticConventions.FeatureFlagAttributes OpenTelemetry.SemanticConventions.FileAttributes OpenTelemetry.SemanticConventions.GcpAttributes +OpenTelemetry.SemanticConventions.GenAiAttributes +OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues OpenTelemetry.SemanticConventions.GraphqlAttributes OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues OpenTelemetry.SemanticConventions.HerokuAttributes @@ -885,7 +941,7 @@ OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues OpenTelemetry.SemanticConventions.MessageAttributes OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues OpenTelemetry.SemanticConventions.MessagingAttributes -OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationValues +OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqMessageTypeValues OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingServicebusDispositionStatusValues @@ -917,6 +973,7 @@ OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues OpenTelemetry.SemanticConventions.RpcAttributes OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues +OpenTelemetry.SemanticConventions.RpcAttributes.RpcMessageTypeValues OpenTelemetry.SemanticConventions.RpcAttributes.RpcSystemValues OpenTelemetry.SemanticConventions.ServerAttributes OpenTelemetry.SemanticConventions.ServiceAttributes diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs index d03c767675..87e2bbc526 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,35 +15,35 @@ namespace OpenTelemetry.SemanticConventions; public static class AndroidAttributes { /// - /// Uniquely identifies the framework API revision offered by a version (os.version) of the android operating system. More information can be found here. + /// Uniquely identifies the framework API revision offered by a version (os.version) of the android operating system. More information can be found here /// public const string AttributeAndroidOsApiLevel = "android.os.api_level"; /// - /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// Deprecated use the device.app.lifecycle event definition including android.state as a payload field instead /// /// - /// The Android lifecycle states are defined in Activity lifecycle callbacks, and from which the OS identifiers are derived. + /// The Android lifecycle states are defined in Activity lifecycle callbacks, and from which the OS identifiers are derived /// public const string AttributeAndroidState = "android.state"; /// - /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// Deprecated use the device.app.lifecycle event definition including android.state as a payload field instead /// public static class AndroidStateValues { /// - /// Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. + /// Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time /// public const string Created = "created"; /// - /// Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. + /// Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state /// public const string Background = "background"; /// - /// Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. + /// Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states /// public const string Foreground = "foreground"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs index cb436aacbb..3166fb95fb 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,104 +15,104 @@ namespace OpenTelemetry.SemanticConventions; public static class AspnetcoreAttributes { /// - /// ASP.NET Core exception middleware handling result. + /// ASP.NET Core exception middleware handling result /// public const string AttributeAspnetcoreDiagnosticsExceptionResult = "aspnetcore.diagnostics.exception.result"; /// - /// Full type name of the IExceptionHandler implementation that handled the exception. + /// Full type name of the IExceptionHandler implementation that handled the exception /// public const string AttributeAspnetcoreDiagnosticsHandlerType = "aspnetcore.diagnostics.handler.type"; /// - /// Rate limiting policy name. + /// Rate limiting policy name /// public const string AttributeAspnetcoreRateLimitingPolicy = "aspnetcore.rate_limiting.policy"; /// - /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason. + /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason /// public const string AttributeAspnetcoreRateLimitingResult = "aspnetcore.rate_limiting.result"; /// - /// Flag indicating if request was handled by the application pipeline. + /// Flag indicating if request was handled by the application pipeline /// public const string AttributeAspnetcoreRequestIsUnhandled = "aspnetcore.request.is_unhandled"; /// - /// A value that indicates whether the matched route is a fallback route. + /// A value that indicates whether the matched route is a fallback route /// public const string AttributeAspnetcoreRoutingIsFallback = "aspnetcore.routing.is_fallback"; /// - /// Match result - success or failure. + /// Match result - success or failure /// public const string AttributeAspnetcoreRoutingMatchStatus = "aspnetcore.routing.match_status"; /// - /// ASP.NET Core exception middleware handling result. + /// ASP.NET Core exception middleware handling result /// public static class AspnetcoreDiagnosticsExceptionResultValues { /// - /// Exception was handled by the exception handling middleware. + /// Exception was handled by the exception handling middleware /// public const string Handled = "handled"; /// - /// Exception was not handled by the exception handling middleware. + /// Exception was not handled by the exception handling middleware /// public const string Unhandled = "unhandled"; /// - /// Exception handling was skipped because the response had started. + /// Exception handling was skipped because the response had started /// public const string Skipped = "skipped"; /// - /// Exception handling didn't run because the request was aborted. + /// Exception handling didn't run because the request was aborted /// public const string Aborted = "aborted"; } /// - /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason. + /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason /// public static class AspnetcoreRateLimitingResultValues { /// - /// Lease was acquired. + /// Lease was acquired /// public const string Acquired = "acquired"; /// - /// Lease request was rejected by the endpoint limiter. + /// Lease request was rejected by the endpoint limiter /// public const string EndpointLimiter = "endpoint_limiter"; /// - /// Lease request was rejected by the global limiter. + /// Lease request was rejected by the global limiter /// public const string GlobalLimiter = "global_limiter"; /// - /// Lease request was canceled. + /// Lease request was canceled /// public const string RequestCanceled = "request_canceled"; } /// - /// Match result - success or failure. + /// Match result - success or failure /// public static class AspnetcoreRoutingMatchStatusValues { /// - /// Match succeeded. + /// Match succeeded /// public const string Success = "success"; /// - /// Match failed. + /// Match failed /// public const string Failure = "failure"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs index fcaad1e8a7..02ea3d403c 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,291 +15,297 @@ namespace OpenTelemetry.SemanticConventions; public static class AwsAttributes { /// - /// The JSON-serialized value of each item in the AttributeDefinitions request field. + /// The JSON-serialized value of each item in the AttributeDefinitions request field /// public const string AttributeAwsDynamodbAttributeDefinitions = "aws.dynamodb.attribute_definitions"; /// - /// The value of the AttributesToGet request parameter. + /// The value of the AttributesToGet request parameter /// public const string AttributeAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get"; /// - /// The value of the ConsistentRead request parameter. + /// The value of the ConsistentRead request parameter /// public const string AttributeAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read"; /// - /// The JSON-serialized value of each item in the ConsumedCapacity response field. + /// The JSON-serialized value of each item in the ConsumedCapacity response field /// public const string AttributeAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity"; /// - /// The value of the Count response parameter. + /// The value of the Count response parameter /// public const string AttributeAwsDynamodbCount = "aws.dynamodb.count"; /// - /// The value of the ExclusiveStartTableName request parameter. + /// The value of the ExclusiveStartTableName request parameter /// public const string AttributeAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table"; /// - /// The JSON-serialized value of each item in the GlobalSecondaryIndexUpdates request field. + /// The JSON-serialized value of each item in the GlobalSecondaryIndexUpdates request field /// public const string AttributeAwsDynamodbGlobalSecondaryIndexUpdates = "aws.dynamodb.global_secondary_index_updates"; /// - /// The JSON-serialized value of each item of the GlobalSecondaryIndexes request field. + /// The JSON-serialized value of each item of the GlobalSecondaryIndexes request field /// public const string AttributeAwsDynamodbGlobalSecondaryIndexes = "aws.dynamodb.global_secondary_indexes"; /// - /// The value of the IndexName request parameter. + /// The value of the IndexName request parameter /// public const string AttributeAwsDynamodbIndexName = "aws.dynamodb.index_name"; /// - /// The JSON-serialized value of the ItemCollectionMetrics response field. + /// The JSON-serialized value of the ItemCollectionMetrics response field /// public const string AttributeAwsDynamodbItemCollectionMetrics = "aws.dynamodb.item_collection_metrics"; /// - /// The value of the Limit request parameter. + /// The value of the Limit request parameter /// public const string AttributeAwsDynamodbLimit = "aws.dynamodb.limit"; /// - /// The JSON-serialized value of each item of the LocalSecondaryIndexes request field. + /// The JSON-serialized value of each item of the LocalSecondaryIndexes request field /// public const string AttributeAwsDynamodbLocalSecondaryIndexes = "aws.dynamodb.local_secondary_indexes"; /// - /// The value of the ProjectionExpression request parameter. + /// The value of the ProjectionExpression request parameter /// public const string AttributeAwsDynamodbProjection = "aws.dynamodb.projection"; /// - /// The value of the ProvisionedThroughput.ReadCapacityUnits request parameter. + /// The value of the ProvisionedThroughput.ReadCapacityUnits request parameter /// public const string AttributeAwsDynamodbProvisionedReadCapacity = "aws.dynamodb.provisioned_read_capacity"; /// - /// The value of the ProvisionedThroughput.WriteCapacityUnits request parameter. + /// The value of the ProvisionedThroughput.WriteCapacityUnits request parameter /// public const string AttributeAwsDynamodbProvisionedWriteCapacity = "aws.dynamodb.provisioned_write_capacity"; /// - /// The value of the ScanIndexForward request parameter. + /// The value of the ScanIndexForward request parameter /// public const string AttributeAwsDynamodbScanForward = "aws.dynamodb.scan_forward"; /// - /// The value of the ScannedCount response parameter. + /// The value of the ScannedCount response parameter /// public const string AttributeAwsDynamodbScannedCount = "aws.dynamodb.scanned_count"; /// - /// The value of the Segment request parameter. + /// The value of the Segment request parameter /// public const string AttributeAwsDynamodbSegment = "aws.dynamodb.segment"; /// - /// The value of the Select request parameter. + /// The value of the Select request parameter /// public const string AttributeAwsDynamodbSelect = "aws.dynamodb.select"; /// - /// The number of items in the TableNames response parameter. + /// The number of items in the TableNames response parameter /// public const string AttributeAwsDynamodbTableCount = "aws.dynamodb.table_count"; /// - /// The keys in the RequestItems object field. + /// The keys in the RequestItems object field /// public const string AttributeAwsDynamodbTableNames = "aws.dynamodb.table_names"; /// - /// The value of the TotalSegments request parameter. + /// The value of the TotalSegments request parameter /// public const string AttributeAwsDynamodbTotalSegments = "aws.dynamodb.total_segments"; /// - /// The ARN of an ECS cluster. + /// The ARN of an ECS cluster /// public const string AttributeAwsEcsClusterArn = "aws.ecs.cluster.arn"; /// - /// The Amazon Resource Name (ARN) of an ECS container instance. + /// The Amazon Resource Name (ARN) of an ECS container instance /// public const string AttributeAwsEcsContainerArn = "aws.ecs.container.arn"; /// - /// The launch type for an ECS task. + /// The launch type for an ECS task /// public const string AttributeAwsEcsLaunchtype = "aws.ecs.launchtype"; /// - /// The ARN of a running ECS task. + /// The ARN of a running ECS task /// public const string AttributeAwsEcsTaskArn = "aws.ecs.task.arn"; /// - /// The family name of the ECS task definition used to create the ECS task. + /// The family name of the ECS task definition used to create the ECS task /// public const string AttributeAwsEcsTaskFamily = "aws.ecs.task.family"; /// - /// The ID of a running ECS task. The ID MUST be extracted from task.arn. + /// The ID of a running ECS task. The ID MUST be extracted from task.arn /// public const string AttributeAwsEcsTaskId = "aws.ecs.task.id"; /// - /// The revision for the task definition used to create the ECS task. + /// The revision for the task definition used to create the ECS task /// public const string AttributeAwsEcsTaskRevision = "aws.ecs.task.revision"; /// - /// The ARN of an EKS cluster. + /// The ARN of an EKS cluster /// public const string AttributeAwsEksClusterArn = "aws.eks.cluster.arn"; /// - /// The full invoked ARN as provided on the Context passed to the function (Lambda-Runtime-Invoked-Function-Arn header on the /runtime/invocation/next applicable). + /// The full invoked ARN as provided on the Context passed to the function (Lambda-Runtime-Invoked-Function-Arn header on the /runtime/invocation/next applicable) /// /// - /// This may be different from cloud.resource_id if an alias is involved. + /// This may be different from cloud.resource_id if an alias is involved /// public const string AttributeAwsLambdaInvokedArn = "aws.lambda.invoked_arn"; /// - /// The Amazon Resource Name(s) (ARN) of the AWS log group(s). + /// The Amazon Resource Name(s) (ARN) of the AWS log group(s) /// /// - /// See the log group ARN format documentation. + /// See the log group ARN format documentation /// public const string AttributeAwsLogGroupArns = "aws.log.group.arns"; /// - /// The name(s) of the AWS log group(s) an application is writing to. + /// The name(s) of the AWS log group(s) an application is writing to /// /// - /// Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. + /// Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group /// public const string AttributeAwsLogGroupNames = "aws.log.group.names"; /// - /// The ARN(s) of the AWS log stream(s). + /// The ARN(s) of the AWS log stream(s) /// /// - /// See the log stream ARN format documentation. One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. + /// See the log stream ARN format documentation. One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream /// public const string AttributeAwsLogStreamArns = "aws.log.stream.arns"; /// - /// The name(s) of the AWS log stream(s) an application is writing to. + /// The name(s) of the AWS log stream(s) an application is writing to /// public const string AttributeAwsLogStreamNames = "aws.log.stream.names"; /// - /// The AWS request ID as returned in the response headers x-amz-request-id or x-amz-requestid. + /// The AWS request ID as returned in the response headers x-amz-request-id or x-amz-requestid /// public const string AttributeAwsRequestId = "aws.request_id"; /// - /// The S3 bucket name the request refers to. Corresponds to the --bucket parameter of the S3 API operations. + /// The S3 bucket name the request refers to. Corresponds to the --bucket parameter of the S3 API operations /// /// /// The bucket attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. - /// This applies to almost all S3 operations except list-buckets. + /// This applies to almost all S3 operations except list-buckets /// public const string AttributeAwsS3Bucket = "aws.s3.bucket"; /// - /// The source object (in the form bucket/key) for the copy operation. + /// The source object (in the form bucket/key) for the copy operation /// /// /// The copy_source attribute applies to S3 copy operations and corresponds to the --copy-source parameter - /// of the copy-object operation within the S3 API. - /// This applies in particular to the following operations:. + /// of the copy-object operation within the S3 API. + /// This applies in particular to the following operations: + ///

+ ///

///
public const string AttributeAwsS3CopySource = "aws.s3.copy_source"; /// - /// The delete request container that specifies the objects to be deleted. + /// The delete request container that specifies the objects to be deleted /// /// /// The delete attribute is only applicable to the delete-object operation. - /// The delete attribute corresponds to the --delete parameter of the - /// delete-objects operation within the S3 API. + /// The delete attribute corresponds to the --delete parameter of the + /// delete-objects operation within the S3 API /// public const string AttributeAwsS3Delete = "aws.s3.delete"; /// - /// The S3 object key the request refers to. Corresponds to the --key parameter of the S3 API operations. + /// The S3 object key the request refers to. Corresponds to the --key parameter of the S3 API operations /// /// /// The key attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. - /// This applies in particular to the following operations:. + /// This applies in particular to the following operations: + ///

+ ///

///
public const string AttributeAwsS3Key = "aws.s3.key"; /// - /// The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. + /// The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000 /// /// /// The part_number attribute is only applicable to the upload-part - /// and upload-part-copy operations. - /// The part_number attribute corresponds to the --part-number parameter of the - /// upload-part operation within the S3 API. + /// and upload-part-copy operations. + /// The part_number attribute corresponds to the --part-number parameter of the + /// upload-part operation within the S3 API /// public const string AttributeAwsS3PartNumber = "aws.s3.part_number"; /// - /// Upload ID that identifies the multipart upload. + /// Upload ID that identifies the multipart upload /// /// /// The upload_id attribute applies to S3 multipart-upload operations and corresponds to the --upload-id parameter - /// of the S3 API multipart operations. - /// This applies in particular to the following operations:. + /// of the S3 API multipart operations. + /// This applies in particular to the following operations: + ///

+ ///

///
public const string AttributeAwsS3UploadId = "aws.s3.upload_id"; /// - /// The launch type for an ECS task. + /// The launch type for an ECS task /// public static class AwsEcsLaunchtypeValues { /// - /// ec2. + /// ec2 /// public const string Ec2 = "ec2"; /// - /// fargate. + /// fargate /// public const string Fargate = "fargate"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs index b4d81c70b5..d8a1891593 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,35 +15,35 @@ namespace OpenTelemetry.SemanticConventions; public static class BrowserAttributes { /// - /// Array of brand name and version separated by a space. + /// Array of brand name and version separated by a space /// /// - /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.brands). + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.brands) /// public const string AttributeBrowserBrands = "browser.brands"; /// - /// Preferred language of the user using the browser. + /// Preferred language of the user using the browser /// /// - /// This value is intended to be taken from the Navigator API navigator.language. + /// This value is intended to be taken from the Navigator API navigator.language /// public const string AttributeBrowserLanguage = "browser.language"; /// - /// A boolean that is true if the browser is running on a mobile device. + /// A boolean that is true if the browser is running on a mobile device /// /// - /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.mobile). If unavailable, this attribute SHOULD be left unset. + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.mobile). If unavailable, this attribute SHOULD be left unset /// public const string AttributeBrowserMobile = "browser.mobile"; /// - /// The platform on which the browser is running. + /// The platform on which the browser is running /// /// /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.platform). If unavailable, the legacy navigator.platform API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. - /// The list of possible values is defined in the W3C User-Agent Client Hints specification. Note that some (but not all) of these values can overlap with values in the os.type and os.name attributes. However, for consistency, the values in the browser.platform attribute should capture the exact value that the user agent provides. + /// The list of possible values is defined in the W3C User-Agent Client Hints specification. Note that some (but not all) of these values can overlap with values in the os.type and os.name attributes. However, for consistency, the values in the browser.platform attribute should capture the exact value that the user agent provides /// public const string AttributeBrowserPlatform = "browser.platform"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs index 724e0bd156..d8aa303707 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,18 +15,18 @@ namespace OpenTelemetry.SemanticConventions; public static class ClientAttributes { /// - /// Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name /// /// - /// When observed from the server side, and when communicating through an intermediary, client.address SHOULD represent the client address behind any intermediaries, for example proxies, if it&#39;s available. + /// When observed from the server side, and when communicating through an intermediary, client.address SHOULD represent the client address behind any intermediaries, for example proxies, if it's available /// public const string AttributeClientAddress = "client.address"; /// - /// Client port number. + /// Client port number /// /// - /// When observed from the server side, and when communicating through an intermediary, client.port SHOULD represent the client port behind any intermediaries, for example proxies, if it&#39;s available. + /// When observed from the server side, and when communicating through an intermediary, client.port SHOULD represent the client port behind any intermediaries, for example proxies, if it's available /// public const string AttributeClientPort = "client.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs index a85e786392..dc96f362c7 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,244 +15,248 @@ namespace OpenTelemetry.SemanticConventions; public static class CloudAttributes { /// - /// The cloud account ID the resource is assigned to. + /// The cloud account ID the resource is assigned to /// public const string AttributeCloudAccountId = "cloud.account.id"; /// - /// Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. + /// Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running /// /// - /// Availability zones are called &#34;zones&#34; on Alibaba Cloud and Google Cloud. + /// Availability zones are called "zones" on Alibaba Cloud and Google Cloud /// public const string AttributeCloudAvailabilityZone = "cloud.availability_zone"; /// - /// The cloud platform in use. + /// The cloud platform in use /// /// - /// The prefix of the service SHOULD match the one specified in cloud.provider. + /// The prefix of the service SHOULD match the one specified in cloud.provider /// public const string AttributeCloudPlatform = "cloud.platform"; /// - /// Name of the cloud provider. + /// Name of the cloud provider /// public const string AttributeCloudProvider = "cloud.provider"; /// - /// The geographical region the resource is running. + /// The geographical region the resource is running /// /// - /// Refer to your provider&#39;s docs to see the available regions, for example Alibaba Cloud regions, AWS regions, Azure regions, Google Cloud regions, or Tencent Cloud regions. + /// Refer to your provider's docs to see the available regions, for example Alibaba Cloud regions, AWS regions, Azure regions, Google Cloud regions, or Tencent Cloud regions /// public const string AttributeCloudRegion = "cloud.region"; /// - /// Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on AWS, a fully qualified resource ID on Azure, a full resource name on GCP). + /// Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on AWS, a fully qualified resource ID on Azure, a full resource name on GCP) /// /// /// On some cloud providers, it may not be possible to determine the full ID at startup, - /// so it may be necessary to set cloud.resource_id as a span attribute instead.The exact value to use for cloud.resource_id depends on the cloud provider. - /// The following well-known definitions MUST be used if you set this attribute and they apply:
    - ///
  • AWS Lambda: The function ARN. - /// Take care not to use the &#34;invoked ARN&#34; directly but replace any - /// alias suffix - /// with the resolved function version, as the same runtime instance may be invokable with - /// multiple different aliases.
  • - ///
  • GCP: The URI of the resource
  • - ///
  • Azure: The Fully Qualified Resource ID of the invoked function, - /// not the function app, having the form - /// /subscriptions/<SUBSCIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>. - /// This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - /// a TracerProvider
  • - ///
. + /// so it may be necessary to set cloud.resource_id as a span attribute instead. + ///

+ /// The exact value to use for cloud.resource_id depends on the cloud provider. + /// The following well-known definitions MUST be used if you set this attribute and they apply: + ///

+ ///

    + ///
  • AWS Lambda: The function ARN. + /// Take care not to use the "invoked ARN" directly but replace any + /// alias suffix + /// with the resolved function version, as the same runtime instance may be invokable with + /// multiple different aliases.
  • + ///
  • GCP: The URI of the resource
  • + ///
  • Azure: The Fully Qualified Resource ID of the invoked function, + /// not the function app, having the form + /// /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/. + /// This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share + /// a TracerProvider
  • + ///
///
public const string AttributeCloudResourceId = "cloud.resource_id"; /// - /// The cloud platform in use. + /// The cloud platform in use /// public static class CloudPlatformValues { /// - /// Alibaba Cloud Elastic Compute Service. + /// Alibaba Cloud Elastic Compute Service /// public const string AlibabaCloudEcs = "alibaba_cloud_ecs"; /// - /// Alibaba Cloud Function Compute. + /// Alibaba Cloud Function Compute /// public const string AlibabaCloudFc = "alibaba_cloud_fc"; /// - /// Red Hat OpenShift on Alibaba Cloud. + /// Red Hat OpenShift on Alibaba Cloud /// public const string AlibabaCloudOpenshift = "alibaba_cloud_openshift"; /// - /// AWS Elastic Compute Cloud. + /// AWS Elastic Compute Cloud /// public const string AwsEc2 = "aws_ec2"; /// - /// AWS Elastic Container Service. + /// AWS Elastic Container Service /// public const string AwsEcs = "aws_ecs"; /// - /// AWS Elastic Kubernetes Service. + /// AWS Elastic Kubernetes Service /// public const string AwsEks = "aws_eks"; /// - /// AWS Lambda. + /// AWS Lambda /// public const string AwsLambda = "aws_lambda"; /// - /// AWS Elastic Beanstalk. + /// AWS Elastic Beanstalk /// public const string AwsElasticBeanstalk = "aws_elastic_beanstalk"; /// - /// AWS App Runner. + /// AWS App Runner /// public const string AwsAppRunner = "aws_app_runner"; /// - /// Red Hat OpenShift on AWS (ROSA). + /// Red Hat OpenShift on AWS (ROSA) /// public const string AwsOpenshift = "aws_openshift"; /// - /// Azure Virtual Machines. + /// Azure Virtual Machines /// public const string AzureVm = "azure_vm"; /// - /// Azure Container Apps. + /// Azure Container Apps /// public const string AzureContainerApps = "azure_container_apps"; /// - /// Azure Container Instances. + /// Azure Container Instances /// public const string AzureContainerInstances = "azure_container_instances"; /// - /// Azure Kubernetes Service. + /// Azure Kubernetes Service /// public const string AzureAks = "azure_aks"; /// - /// Azure Functions. + /// Azure Functions /// public const string AzureFunctions = "azure_functions"; /// - /// Azure App Service. + /// Azure App Service /// public const string AzureAppService = "azure_app_service"; /// - /// Azure Red Hat OpenShift. + /// Azure Red Hat OpenShift /// public const string AzureOpenshift = "azure_openshift"; /// - /// Google Bare Metal Solution (BMS). + /// Google Bare Metal Solution (BMS) /// public const string GcpBareMetalSolution = "gcp_bare_metal_solution"; /// - /// Google Cloud Compute Engine (GCE). + /// Google Cloud Compute Engine (GCE) /// public const string GcpComputeEngine = "gcp_compute_engine"; /// - /// Google Cloud Run. + /// Google Cloud Run /// public const string GcpCloudRun = "gcp_cloud_run"; /// - /// Google Cloud Kubernetes Engine (GKE). + /// Google Cloud Kubernetes Engine (GKE) /// public const string GcpKubernetesEngine = "gcp_kubernetes_engine"; /// - /// Google Cloud Functions (GCF). + /// Google Cloud Functions (GCF) /// public const string GcpCloudFunctions = "gcp_cloud_functions"; /// - /// Google Cloud App Engine (GAE). + /// Google Cloud App Engine (GAE) /// public const string GcpAppEngine = "gcp_app_engine"; /// - /// Red Hat OpenShift on Google Cloud. + /// Red Hat OpenShift on Google Cloud /// public const string GcpOpenshift = "gcp_openshift"; /// - /// Red Hat OpenShift on IBM Cloud. + /// Red Hat OpenShift on IBM Cloud /// public const string IbmCloudOpenshift = "ibm_cloud_openshift"; /// - /// Tencent Cloud Cloud Virtual Machine (CVM). + /// Tencent Cloud Cloud Virtual Machine (CVM) /// public const string TencentCloudCvm = "tencent_cloud_cvm"; /// - /// Tencent Cloud Elastic Kubernetes Service (EKS). + /// Tencent Cloud Elastic Kubernetes Service (EKS) /// public const string TencentCloudEks = "tencent_cloud_eks"; /// - /// Tencent Cloud Serverless Cloud Function (SCF). + /// Tencent Cloud Serverless Cloud Function (SCF) /// public const string TencentCloudScf = "tencent_cloud_scf"; } /// - /// Name of the cloud provider. + /// Name of the cloud provider /// public static class CloudProviderValues { /// - /// Alibaba Cloud. + /// Alibaba Cloud /// public const string AlibabaCloud = "alibaba_cloud"; /// - /// Amazon Web Services. + /// Amazon Web Services /// public const string Aws = "aws"; /// - /// Microsoft Azure. + /// Microsoft Azure /// public const string Azure = "azure"; /// - /// Google Cloud Platform. + /// Google Cloud Platform /// public const string Gcp = "gcp"; /// - /// Heroku Platform as a Service. + /// Heroku Platform as a Service /// public const string Heroku = "heroku"; /// - /// IBM Cloud. + /// IBM Cloud /// public const string IbmCloud = "ibm_cloud"; /// - /// Tencent Cloud. + /// Tencent Cloud /// public const string TencentCloud = "tencent_cloud"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs index 17114d24a0..7c13858791 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,27 +15,27 @@ namespace OpenTelemetry.SemanticConventions; public static class CloudeventsAttributes { /// - /// The event_id uniquely identifies the event. + /// The event_id uniquely identifies the event /// public const string AttributeCloudeventsEventId = "cloudevents.event_id"; /// - /// The source identifies the context in which an event happened. + /// The source identifies the context in which an event happened /// public const string AttributeCloudeventsEventSource = "cloudevents.event_source"; /// - /// The version of the CloudEvents specification which the event uses. + /// The version of the CloudEvents specification which the event uses /// public const string AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version"; /// - /// The subject of the event in the context of the event producer (identified by source). + /// The subject of the event in the context of the event producer (identified by source) /// public const string AttributeCloudeventsEventSubject = "cloudevents.event_subject"; /// - /// The event_type contains a value describing the type of event related to the originating occurrence. + /// The event_type contains a value describing the type of event related to the originating occurrence /// public const string AttributeCloudeventsEventType = "cloudevents.event_type"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs index ebe40ae35c..41eee11105 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,32 +15,32 @@ namespace OpenTelemetry.SemanticConventions; public static class CodeAttributes { /// - /// The column number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function. + /// The column number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function /// public const string AttributeCodeColumn = "code.column"; /// - /// The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). + /// The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path) /// public const string AttributeCodeFilepath = "code.filepath"; /// - /// The method or function name, or equivalent (usually rightmost part of the code unit's name). + /// The method or function name, or equivalent (usually rightmost part of the code unit's name) /// public const string AttributeCodeFunction = "code.function"; /// - /// The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function. + /// The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function /// public const string AttributeCodeLineno = "code.lineno"; /// - /// The "namespace" within which code.function is defined. Usually the qualified class or module name, such that code.namespace + some separator + code.function form a unique identifier for the code unit. + /// The "namespace" within which code.function is defined. Usually the qualified class or module name, such that code.namespace + some separator + code.function form a unique identifier for the code unit /// public const string AttributeCodeNamespace = "code.namespace"; /// - /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. + /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG /// public const string AttributeCodeStacktrace = "code.stacktrace"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs index 53f6b930b9..2476dd9440 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,99 +15,99 @@ namespace OpenTelemetry.SemanticConventions; public static class ContainerAttributes { /// - /// The command used to run the container (i.e. the command name). + /// The command used to run the container (i.e. the command name) /// /// - /// If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. + /// If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage /// public const string AttributeContainerCommand = "container.command"; /// - /// All the command arguments (including the command/executable itself) run by the container. [2]. + /// All the command arguments (including the command/executable itself) run by the container. [2] /// public const string AttributeContainerCommandArgs = "container.command_args"; /// - /// The full command run by the container as a single string representing the full command. [2]. + /// The full command run by the container as a single string representing the full command. [2] /// public const string AttributeContainerCommandLine = "container.command_line"; /// - /// The CPU state for this data point. + /// The CPU state for this data point /// public const string AttributeContainerCpuState = "container.cpu.state"; /// - /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated. + /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated /// public const string AttributeContainerId = "container.id"; /// - /// Runtime specific image identifier. Usually a hash algorithm followed by a UUID. + /// Runtime specific image identifier. Usually a hash algorithm followed by a UUID /// /// /// Docker defines a sha256 of the image id; container.image.id corresponds to the Image field from the Docker container inspect API endpoint. - /// K8s defines a link to the container registry repository with digest "imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625". - /// The ID is assinged by the container runtime and can vary in different environments. Consider using oci.manifest.digest if it is important to identify the same image in different environments/runtimes. + /// K8s defines a link to the container registry repository with digest "imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625". + /// The ID is assigned by the container runtime and can vary in different environments. Consider using oci.manifest.digest if it is important to identify the same image in different environments/runtimes /// public const string AttributeContainerImageId = "container.image.id"; /// - /// Name of the image the container was built on. + /// Name of the image the container was built on /// public const string AttributeContainerImageName = "container.image.name"; /// - /// Repo digests of the container image as provided by the container runtime. + /// Repo digests of the container image as provided by the container runtime /// /// - /// Docker and CRI report those under the RepoDigests field. + /// Docker and CRI report those under the RepoDigests field /// public const string AttributeContainerImageRepoDigests = "container.image.repo_digests"; /// - /// Container image tags. An example can be found in Docker Image Inspect. Should be only the section of the full name for example from registry.example.com/my-org/my-image:. + /// Container image tags. An example can be found in Docker Image Inspect. Should be only the section of the full name for example from registry.example.com/my-org/my-image: /// public const string AttributeContainerImageTags = "container.image.tags"; /// - /// Container labels, being the label name, the value being the label value. + /// Container labels, being the label name, the value being the label value /// - public const string AttributeContainerLabel = "container.label"; + public const string AttributeContainerLabelTemplate = "container.label"; /// - /// Deprecated, use container.label instead. + /// Deprecated, use container.label instead /// - [Obsolete("Replaced by `container.label`")] - public const string AttributeContainerLabels = "container.labels"; + [Obsolete("Replaced by container.label")] + public const string AttributeContainerLabelsTemplate = "container.labels"; /// - /// Container name used by container runtime. + /// Container name used by container runtime /// public const string AttributeContainerName = "container.name"; /// - /// The container runtime managing this container. + /// The container runtime managing this container /// public const string AttributeContainerRuntime = "container.runtime"; /// - /// The CPU state for this data point. + /// The CPU state for this data point /// public static class ContainerCpuStateValues { /// - /// When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). + /// When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows) /// public const string User = "user"; /// - /// When CPU is used by the system (host OS). + /// When CPU is used by the system (host OS) /// public const string System = "system"; /// - /// When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). + /// When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows) /// public const string Kernel = "kernel"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs index ffdbf56873..3ca71b84ff 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,596 +15,661 @@ namespace OpenTelemetry.SemanticConventions; public static class DbAttributes { /// - /// The consistency level of the query. Based on consistency values from CQL. + /// The consistency level of the query. Based on consistency values from CQL /// public const string AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level"; /// - /// The data center of the coordinating node for a query. + /// The data center of the coordinating node for a query /// public const string AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc"; /// - /// The ID of the coordinating node for a query. + /// The ID of the coordinating node for a query /// public const string AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id"; /// - /// Whether or not the query is idempotent. + /// Whether or not the query is idempotent /// public const string AttributeDbCassandraIdempotence = "db.cassandra.idempotence"; /// - /// The fetch size used for paging, i.e. how many rows will be returned at once. + /// The fetch size used for paging, i.e. how many rows will be returned at once /// public const string AttributeDbCassandraPageSize = "db.cassandra.page_size"; /// - /// The number of times a query was speculatively executed. Not set or 0 if the query was not executed speculatively. + /// The number of times a query was speculatively executed. Not set or 0 if the query was not executed speculatively /// public const string AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count"; /// - /// The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + /// Deprecated, use db.collection.name instead + /// + [Obsolete("Replaced by db.collection.name")] + public const string AttributeDbCassandraTable = "db.cassandra.table"; + + /// + /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of server.address and server.port attributes formatted as server.address:server.port + /// + public const string AttributeDbClientConnectionsPoolName = "db.client.connections.pool.name"; + + /// + /// The state of a connection in the pool + /// + public const string AttributeDbClientConnectionsState = "db.client.connections.state"; + + /// + /// The name of a collection (table, container) within the database /// /// - /// This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of db.statement just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + /// If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. + /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization /// - public const string AttributeDbCassandraTable = "db.cassandra.table"; + public const string AttributeDbCollectionName = "db.collection.name"; /// - /// Deprecated, use server.address, server.port attributes instead. + /// Deprecated, use server.address, server.port attributes instead /// - [Obsolete("Replaced by `server.address` and `server.port`.")] + [Obsolete("Replaced by server.address and server.port")] public const string AttributeDbConnectionString = "db.connection_string"; /// - /// Unique Cosmos client instance id. + /// Unique Cosmos client instance id /// public const string AttributeDbCosmosdbClientId = "db.cosmosdb.client_id"; /// - /// Cosmos client connection mode. + /// Cosmos client connection mode /// public const string AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode"; /// - /// Cosmos DB container name. + /// Deprecated, use db.collection.name instead /// + [Obsolete("Replaced by db.collection.name")] public const string AttributeDbCosmosdbContainer = "db.cosmosdb.container"; /// - /// CosmosDB Operation Type. + /// CosmosDB Operation Type /// public const string AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type"; /// - /// RU consumed for that operation. + /// RU consumed for that operation /// public const string AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge"; /// - /// Request payload size in bytes. + /// Request payload size in bytes /// public const string AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length"; /// - /// Cosmos DB status code. + /// Cosmos DB status code /// public const string AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code"; /// - /// Cosmos DB sub status code. + /// Cosmos DB sub status code /// public const string AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code"; /// - /// Represents the identifier of an Elasticsearch cluster. + /// Represents the identifier of an Elasticsearch cluster /// public const string AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name"; /// - /// Deprecated, use db.instance.id instead. + /// Represents the human-readable identifier of the node/instance to which a request was routed /// - [Obsolete("Replaced by `db.instance.id`")] public const string AttributeDbElasticsearchNodeName = "db.elasticsearch.node.name"; /// - /// A dynamic value in the url path. + /// A dynamic value in the url path /// /// - /// Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format db.elasticsearch.path_parts.<key>, where <key> is the url path part name. The implementation SHOULD reference the elasticsearch schema in order to map the path part values to their names. + /// Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format db.elasticsearch.path_parts., where is the url path part name. The implementation SHOULD reference the elasticsearch schema in order to map the path part values to their names /// - public const string AttributeDbElasticsearchPathParts = "db.elasticsearch.path_parts"; + public const string AttributeDbElasticsearchPathPartsTemplate = "db.elasticsearch.path_parts"; /// - /// An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like select @@hostname. + /// Deprecated, no general replacement at this time. For Elasticsearch, use db.elasticsearch.node.name instead /// + [Obsolete("Deprecated, no general replacement at this time. For Elasticsearch, use db.elasticsearch.node.name instead")] public const string AttributeDbInstanceId = "db.instance.id"; /// - /// Removed, no replacement at this time. + /// Removed, no replacement at this time /// [Obsolete("Removed as not used")] public const string AttributeDbJdbcDriverClassname = "db.jdbc.driver_classname"; /// - /// The MongoDB collection being accessed within the database stated in db.name. + /// Deprecated, use db.collection.name instead /// + [Obsolete("Replaced by db.collection.name")] public const string AttributeDbMongodbCollection = "db.mongodb.collection"; /// - /// The Microsoft SQL Server instance name connecting to. This name is used to determine the port of a named instance. + /// Deprecated, SQL Server instance is now populated as a part of db.namespace attribute /// - /// - /// If setting a db.mssql.instance_name, server.port is no longer required (but still recommended if non-standard). - /// + [Obsolete("Deprecated, no replacement at this time")] public const string AttributeDbMssqlInstanceName = "db.mssql.instance_name"; /// - /// This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). + /// Deprecated, use db.namespace instead /// - /// - /// In some SQL databases, the database name to be used is called &#34;schema name&#34;. In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name). - /// + [Obsolete("Replaced by db.namespace")] public const string AttributeDbName = "db.name"; /// - /// The name of the operation being executed, e.g. the MongoDB command name such as findAndModify, or the SQL keyword. + /// The name of the database, fully qualified within the server address and port /// /// - /// When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of db.statement just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted. + /// If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. + /// Semantic conventions for individual database systems SHOULD document what db.namespace means in the context of that system. + /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization /// + public const string AttributeDbNamespace = "db.namespace"; + + /// + /// Deprecated, use db.operation.name instead + /// + [Obsolete("Replaced by db.operation.name")] public const string AttributeDbOperation = "db.operation"; /// - /// The index of the database being accessed as used in the SELECT command, provided as an integer. To be used instead of the generic db.name attribute. + /// The name of the operation or command being executed /// - public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; + /// + /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization + /// + public const string AttributeDbOperationName = "db.operation.name"; /// - /// The name of the primary table that the operation is acting upon, including the database name (if applicable). + /// The query parameters used in db.query.text, with being the parameter name, and the attribute value being the parameter value /// /// - /// It is not recommended to attempt any client-side parsing of db.statement just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set. + /// Query parameters should only be captured when db.query.text is parameterized with placeholders. + /// If a parameter has no name and instead is referenced only by index, then SHOULD be the 0-based index /// + public const string AttributeDbQueryParameterTemplate = "db.query.parameter"; + + /// + /// The database query being executed + /// + public const string AttributeDbQueryText = "db.query.text"; + + /// + /// Deprecated, use db.namespace instead + /// + [Obsolete("Replaced by db.namespace")] + public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; + + /// + /// Deprecated, use db.collection.name instead + /// + [Obsolete("Replaced by db.collection.name")] public const string AttributeDbSqlTable = "db.sql.table"; /// - /// The database statement being executed. + /// The database statement being executed /// + [Obsolete("Replaced by db.query.text")] public const string AttributeDbStatement = "db.statement"; /// - /// An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + /// The database management system (DBMS) product as identified by the client instrumentation /// + /// + /// The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the db.system is set to postgresql based on the instrumentation's best knowledge + /// public const string AttributeDbSystem = "db.system"; /// - /// Username for accessing the database. + /// Deprecated, no replacement at this time /// + [Obsolete("No replacement at this time")] public const string AttributeDbUser = "db.user"; /// - /// The consistency level of the query. Based on consistency values from CQL. + /// The consistency level of the query. Based on consistency values from CQL /// public static class DbCassandraConsistencyLevelValues { /// - /// all. + /// all /// public const string All = "all"; /// - /// each_quorum. + /// each_quorum /// public const string EachQuorum = "each_quorum"; /// - /// quorum. + /// quorum /// public const string Quorum = "quorum"; /// - /// local_quorum. + /// local_quorum /// public const string LocalQuorum = "local_quorum"; /// - /// one. + /// one /// public const string One = "one"; /// - /// two. + /// two /// public const string Two = "two"; /// - /// three. + /// three /// public const string Three = "three"; /// - /// local_one. + /// local_one /// public const string LocalOne = "local_one"; /// - /// any. + /// any /// public const string Any = "any"; /// - /// serial. + /// serial /// public const string Serial = "serial"; /// - /// local_serial. + /// local_serial /// public const string LocalSerial = "local_serial"; } /// - /// Cosmos client connection mode. + /// The state of a connection in the pool + /// + public static class DbClientConnectionsStateValues + { + /// + /// idle + /// + public const string Idle = "idle"; + + /// + /// used + /// + public const string Used = "used"; + } + + /// + /// Cosmos client connection mode /// public static class DbCosmosdbConnectionModeValues { /// - /// Gateway (HTTP) connections mode. + /// Gateway (HTTP) connections mode /// public const string Gateway = "gateway"; /// - /// Direct connection. + /// Direct connection /// public const string Direct = "direct"; } /// - /// CosmosDB Operation Type. + /// CosmosDB Operation Type /// public static class DbCosmosdbOperationTypeValues { /// - /// invalid. + /// invalid /// public const string Invalid = "Invalid"; /// - /// create. + /// create /// public const string Create = "Create"; /// - /// patch. + /// patch /// public const string Patch = "Patch"; /// - /// read. + /// read /// public const string Read = "Read"; /// - /// read_feed. + /// read_feed /// public const string ReadFeed = "ReadFeed"; /// - /// delete. + /// delete /// public const string Delete = "Delete"; /// - /// replace. + /// replace /// public const string Replace = "Replace"; /// - /// execute. + /// execute /// public const string Execute = "Execute"; /// - /// query. + /// query /// public const string Query = "Query"; /// - /// head. + /// head /// public const string Head = "Head"; /// - /// head_feed. + /// head_feed /// public const string HeadFeed = "HeadFeed"; /// - /// upsert. + /// upsert /// public const string Upsert = "Upsert"; /// - /// batch. + /// batch /// public const string Batch = "Batch"; /// - /// query_plan. + /// query_plan /// public const string QueryPlan = "QueryPlan"; /// - /// execute_javascript. + /// execute_javascript /// public const string ExecuteJavascript = "ExecuteJavaScript"; } /// - /// An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + /// The database management system (DBMS) product as identified by the client instrumentation /// public static class DbSystemValues { /// - /// Some other SQL database. Fallback only. See notes. + /// Some other SQL database. Fallback only. See notes /// public const string OtherSql = "other_sql"; /// - /// Microsoft SQL Server. + /// Microsoft SQL Server /// public const string Mssql = "mssql"; /// - /// Microsoft SQL Server Compact. + /// Microsoft SQL Server Compact /// public const string Mssqlcompact = "mssqlcompact"; /// - /// MySQL. + /// MySQL /// public const string Mysql = "mysql"; /// - /// Oracle Database. + /// Oracle Database /// public const string Oracle = "oracle"; /// - /// IBM Db2. + /// IBM Db2 /// public const string Db2 = "db2"; /// - /// PostgreSQL. + /// PostgreSQL /// public const string Postgresql = "postgresql"; /// - /// Amazon Redshift. + /// Amazon Redshift /// public const string Redshift = "redshift"; /// - /// Apache Hive. + /// Apache Hive /// public const string Hive = "hive"; /// - /// Cloudscape. + /// Cloudscape /// public const string Cloudscape = "cloudscape"; /// - /// HyperSQL DataBase. + /// HyperSQL DataBase /// public const string Hsqldb = "hsqldb"; /// - /// Progress Database. + /// Progress Database /// public const string Progress = "progress"; /// - /// SAP MaxDB. + /// SAP MaxDB /// public const string Maxdb = "maxdb"; /// - /// SAP HANA. + /// SAP HANA /// public const string Hanadb = "hanadb"; /// - /// Ingres. + /// Ingres /// public const string Ingres = "ingres"; /// - /// FirstSQL. + /// FirstSQL /// public const string Firstsql = "firstsql"; /// - /// EnterpriseDB. + /// EnterpriseDB /// public const string Edb = "edb"; /// - /// InterSystems Caché. + /// InterSystems Caché /// public const string Cache = "cache"; /// - /// Adabas (Adaptable Database System). + /// Adabas (Adaptable Database System) /// public const string Adabas = "adabas"; /// - /// Firebird. + /// Firebird /// public const string Firebird = "firebird"; /// - /// Apache Derby. + /// Apache Derby /// public const string Derby = "derby"; /// - /// FileMaker. + /// FileMaker /// public const string Filemaker = "filemaker"; /// - /// Informix. + /// Informix /// public const string Informix = "informix"; /// - /// InstantDB. + /// InstantDB /// public const string Instantdb = "instantdb"; /// - /// InterBase. + /// InterBase /// public const string Interbase = "interbase"; /// - /// MariaDB. + /// MariaDB /// public const string Mariadb = "mariadb"; /// - /// Netezza. + /// Netezza /// public const string Netezza = "netezza"; /// - /// Pervasive PSQL. + /// Pervasive PSQL /// public const string Pervasive = "pervasive"; /// - /// PointBase. + /// PointBase /// public const string Pointbase = "pointbase"; /// - /// SQLite. + /// SQLite /// public const string Sqlite = "sqlite"; /// - /// Sybase. + /// Sybase /// public const string Sybase = "sybase"; /// - /// Teradata. + /// Teradata /// public const string Teradata = "teradata"; /// - /// Vertica. + /// Vertica /// public const string Vertica = "vertica"; /// - /// H2. + /// H2 /// public const string H2 = "h2"; /// - /// ColdFusion IMQ. + /// ColdFusion IMQ /// public const string Coldfusion = "coldfusion"; /// - /// Apache Cassandra. + /// Apache Cassandra /// public const string Cassandra = "cassandra"; /// - /// Apache HBase. + /// Apache HBase /// public const string Hbase = "hbase"; /// - /// MongoDB. + /// MongoDB /// public const string Mongodb = "mongodb"; /// - /// Redis. + /// Redis /// public const string Redis = "redis"; /// - /// Couchbase. + /// Couchbase /// public const string Couchbase = "couchbase"; /// - /// CouchDB. + /// CouchDB /// public const string Couchdb = "couchdb"; /// - /// Microsoft Azure Cosmos DB. + /// Microsoft Azure Cosmos DB /// public const string Cosmosdb = "cosmosdb"; /// - /// Amazon DynamoDB. + /// Amazon DynamoDB /// public const string Dynamodb = "dynamodb"; /// - /// Neo4j. + /// Neo4j /// public const string Neo4j = "neo4j"; /// - /// Apache Geode. + /// Apache Geode /// public const string Geode = "geode"; /// - /// Elasticsearch. + /// Elasticsearch /// public const string Elasticsearch = "elasticsearch"; /// - /// Memcached. + /// Memcached /// public const string Memcached = "memcached"; /// - /// CockroachDB. + /// CockroachDB /// public const string Cockroachdb = "cockroachdb"; /// - /// OpenSearch. + /// OpenSearch /// public const string Opensearch = "opensearch"; /// - /// ClickHouse. + /// ClickHouse /// public const string Clickhouse = "clickhouse"; /// - /// Cloud Spanner. + /// Cloud Spanner /// public const string Spanner = "spanner"; /// - /// Trino. + /// Trino /// public const string Trino = "trino"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs index 38312d89a3..048d733ccb 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,16 +15,18 @@ namespace OpenTelemetry.SemanticConventions; public static class DeploymentAttributes { /// - /// Name of the deployment environment (aka deployment tier). + /// Name of the deployment environment (aka deployment tier) /// /// /// deployment.environment does not affect the uniqueness constraints defined through - /// the service.namespace, service.name and service.instance.id resource attributes. - /// This implies that resources carrying the following attribute combinations MUST be - /// considered to be identifying the same service:
    - ///
  • service.name=frontend, deployment.environment=production
  • - ///
  • service.name=frontend, deployment.environment=staging
  • - ///
. + /// the service.namespace, service.name and service.instance.id resource attributes. + /// This implies that resources carrying the following attribute combinations MUST be + /// considered to be identifying the same service: + ///

+ ///

    + ///
  • service.name=frontend, deployment.environment=production
  • + ///
  • service.name=frontend, deployment.environment=staging
  • + ///
///
public const string AttributeDeploymentEnvironment = "deployment.environment"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs index 08d9e7f480..41bc27913d 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,15 +15,15 @@ namespace OpenTelemetry.SemanticConventions; public static class DestinationAttributes { /// - /// Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name /// /// - /// When observed from the source side, and when communicating through an intermediary, destination.address SHOULD represent the destination address behind any intermediaries, for example proxies, if it&#39;s available. + /// When observed from the source side, and when communicating through an intermediary, destination.address SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available /// public const string AttributeDestinationAddress = "destination.address"; /// - /// Destination port number. + /// Destination port number /// public const string AttributeDestinationPort = "destination.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs index 9ea1ebc4fb..04ca99d4ef 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,34 +15,34 @@ namespace OpenTelemetry.SemanticConventions; public static class DeviceAttributes { /// - /// A unique identifier representing the device. + /// A unique identifier representing the device /// /// - /// The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the vendor identifier. On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found here on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. + /// The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the vendor identifier. On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found here on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence /// public const string AttributeDeviceId = "device.id"; /// - /// The name of the device manufacturer. + /// The name of the device manufacturer /// /// - /// The Android OS provides this field via Build. iOS apps SHOULD hardcode the value Apple. + /// The Android OS provides this field via Build. iOS apps SHOULD hardcode the value Apple /// public const string AttributeDeviceManufacturer = "device.manufacturer"; /// - /// The model identifier for the device. + /// The model identifier for the device /// /// - /// It&#39;s recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. + /// It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device /// public const string AttributeDeviceModelIdentifier = "device.model.identifier"; /// - /// The marketing name for the device model. + /// The marketing name for the device model /// /// - /// It&#39;s recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. + /// It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative /// public const string AttributeDeviceModelName = "device.model.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs index efa5cb59ce..14921a8de6 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,22 +15,22 @@ namespace OpenTelemetry.SemanticConventions; public static class DiskAttributes { /// - /// The disk IO operation direction. + /// The disk IO operation direction /// public const string AttributeDiskIoDirection = "disk.io.direction"; /// - /// The disk IO operation direction. + /// The disk IO operation direction /// public static class DiskIoDirectionValues { /// - /// read. + /// read /// public const string Read = "read"; /// - /// write. + /// write /// public const string Write = "write"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs index c7db90e746..04dbadfd07 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,10 +15,10 @@ namespace OpenTelemetry.SemanticConventions; public static class DnsAttributes { /// - /// The name being queried. + /// The name being queried /// /// - /// If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. + /// If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively /// public const string AttributeDnsQuestionName = "dns.question.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs index cdee87e966..5153558c13 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,17 +15,17 @@ namespace OpenTelemetry.SemanticConventions; public static class EnduserAttributes { /// - /// Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system. + /// Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system /// public const string AttributeEnduserId = "enduser.id"; /// - /// Actual/assumed role the client is making the request under extracted from token or application security context. + /// Actual/assumed role the client is making the request under extracted from token or application security context /// public const string AttributeEnduserRole = "enduser.role"; /// - /// Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an OAuth 2.0 Access Token or an attribute value in a SAML 2.0 Assertion. + /// Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an OAuth 2.0 Access Token or an attribute value in a SAML 2.0 Assertion /// public const string AttributeEnduserScope = "enduser.scope"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs index 4793805994..d8edc109da 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,28 +15,40 @@ namespace OpenTelemetry.SemanticConventions; public static class ErrorAttributes { /// - /// Describes a class of error the operation ended with. + /// Describes a class of error the operation ended with /// /// - /// The error.type SHOULD be predictable and SHOULD have low cardinality. - /// Instrumentations SHOULD document the list of errors they report.The cardinality of error.type within one instrumentation library SHOULD be low. - /// Telemetry consumers that aggregate data from multiple instrumentation libraries and applications - /// should be prepared for error.type to have high cardinality at query time when no - /// additional filters are applied.If the operation has completed successfully, instrumentations SHOULD NOT set error.type.If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), - /// it&#39;s RECOMMENDED to:
    - ///
  • Use a domain-specific attribute
  • - ///
  • Set error.type to capture all errors, regardless of whether they are defined within the domain-specific set or not
  • - ///
. + /// The error.type SHOULD be predictable, and SHOULD have low cardinality. + ///

+ /// When error.type is set to a type (e.g., an exception type), its + /// canonical class name identifying the type within the artifact SHOULD be used. + ///

+ /// Instrumentations SHOULD document the list of errors they report. + ///

+ /// The cardinality of error.type within one instrumentation library SHOULD be low. + /// Telemetry consumers that aggregate data from multiple instrumentation libraries and applications + /// should be prepared for error.type to have high cardinality at query time when no + /// additional filters are applied. + ///

+ /// If the operation has completed successfully, instrumentations SHOULD NOT set error.type. + ///

+ /// If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), + /// it's RECOMMENDED to: + ///

+ ///

    + ///
  • Use a domain-specific attribute
  • + ///
  • Set error.type to capture all errors, regardless of whether they are defined within the domain-specific set or not
  • + ///
///
public const string AttributeErrorType = "error.type"; /// - /// Describes a class of error the operation ended with. + /// Describes a class of error the operation ended with /// public static class ErrorTypeValues { /// - /// A fallback error value to be used when the instrumentation doesn't define a custom value. + /// A fallback error value to be used when the instrumentation doesn't define a custom value /// public const string Other = "_OTHER"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs index 7def01aeaa..e8885e84d5 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,10 +15,10 @@ namespace OpenTelemetry.SemanticConventions; public static class EventAttributes { /// - /// Identifies the class / type of event. + /// Identifies the class / type of event /// /// - /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. + /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes /// public const string AttributeEventName = "event.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs index 9b26f61d88..66e71559be 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,36 +15,40 @@ namespace OpenTelemetry.SemanticConventions; public static class ExceptionAttributes { /// - /// SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. + /// SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span /// /// /// An exception is considered to have escaped (or left) the scope of a span, - /// if that span is ended while the exception is still logically &#34;in flight&#34;. - /// This may be actually &#34;in flight&#34; in some languages (e.g. if the exception - /// is passed to a Context manager&#39;s __exit__ method in Python) but will - /// usually be caught at the point of recording the exception in most languages.It is usually not possible to determine at the point where an exception is thrown - /// whether it will escape the scope of a span. - /// However, it is trivial to know that an exception - /// will escape, if one checks for an active exception just before ending the span, - /// as done in the example for recording span exceptions.It follows that an exception may still escape the scope of the span - /// even if the exception.escaped attribute was not set or set to false, - /// since the event might have been recorded at a time where it was not - /// clear whether the exception will escape. + /// if that span is ended while the exception is still logically "in flight". + /// This may be actually "in flight" in some languages (e.g. if the exception + /// is passed to a Context manager's __exit__ method in Python) but will + /// usually be caught at the point of recording the exception in most languages. + ///

+ /// It is usually not possible to determine at the point where an exception is thrown + /// whether it will escape the scope of a span. + /// However, it is trivial to know that an exception + /// will escape, if one checks for an active exception just before ending the span, + /// as done in the example for recording span exceptions. + ///

+ /// It follows that an exception may still escape the scope of the span + /// even if the exception.escaped attribute was not set or set to false, + /// since the event might have been recorded at a time where it was not + /// clear whether the exception will escape /// public const string AttributeExceptionEscaped = "exception.escaped"; ///

- /// The exception message. + /// The exception message /// public const string AttributeExceptionMessage = "exception.message"; /// - /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. + /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG /// public const string AttributeExceptionStacktrace = "exception.stacktrace"; /// - /// The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. + /// The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it /// public const string AttributeExceptionType = "exception.type"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs index bf4ff8d157..981e1a4a43 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,208 +15,214 @@ namespace OpenTelemetry.SemanticConventions; public static class FaasAttributes { /// - /// A boolean that is true if the serverless function is executed for the first time (aka cold-start). + /// A boolean that is true if the serverless function is executed for the first time (aka cold-start) /// public const string AttributeFaasColdstart = "faas.coldstart"; /// - /// A string containing the schedule period as Cron Expression. + /// A string containing the schedule period as Cron Expression /// public const string AttributeFaasCron = "faas.cron"; /// - /// The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. + /// The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name /// public const string AttributeFaasDocumentCollection = "faas.document.collection"; /// - /// The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. + /// The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name /// public const string AttributeFaasDocumentName = "faas.document.name"; /// - /// Describes the type of the operation that was performed on the data. + /// Describes the type of the operation that was performed on the data /// public const string AttributeFaasDocumentOperation = "faas.document.operation"; /// - /// A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC. + /// A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC /// public const string AttributeFaasDocumentTime = "faas.document.time"; /// - /// The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. + /// The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version /// /// ///
    - ///
  • AWS Lambda: Use the (full) log stream name
  • - ///
. + ///
  • AWS Lambda: Use the (full) log stream name
  • + /// ///
    public const string AttributeFaasInstance = "faas.instance"; /// - /// The invocation ID of the current function invocation. + /// The invocation ID of the current function invocation /// public const string AttributeFaasInvocationId = "faas.invocation_id"; /// - /// The name of the invoked function. + /// The name of the invoked function /// /// - /// SHOULD be equal to the faas.name resource attribute of the invoked function. + /// SHOULD be equal to the faas.name resource attribute of the invoked function /// public const string AttributeFaasInvokedName = "faas.invoked_name"; /// - /// The cloud provider of the invoked function. + /// The cloud provider of the invoked function /// /// - /// SHOULD be equal to the cloud.provider resource attribute of the invoked function. + /// SHOULD be equal to the cloud.provider resource attribute of the invoked function /// public const string AttributeFaasInvokedProvider = "faas.invoked_provider"; /// - /// The cloud region of the invoked function. + /// The cloud region of the invoked function /// /// - /// SHOULD be equal to the cloud.region resource attribute of the invoked function. + /// SHOULD be equal to the cloud.region resource attribute of the invoked function /// public const string AttributeFaasInvokedRegion = "faas.invoked_region"; /// - /// The amount of memory available to the serverless function converted to Bytes. + /// The amount of memory available to the serverless function converted to Bytes /// /// - /// It&#39;s recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE provides this information (which must be multiplied by 1,048,576). + /// It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE provides this information (which must be multiplied by 1,048,576) /// public const string AttributeFaasMaxMemory = "faas.max_memory"; /// - /// The name of the single function that this runtime instance executes. + /// The name of the single function that this runtime instance executes /// /// /// This is the name of the function as configured/deployed on the FaaS - /// platform and is usually different from the name of the callback - /// function (which may be stored in the - /// code.namespace/code.function - /// span attributes).For some cloud providers, the above definition is ambiguous. The following - /// definition of function name MUST be used for this attribute - /// (and consequently the span name) for the listed cloud providers/products:
      - ///
    • Azure: The full name <FUNCAPP>/<FUNC>, i.e., function app name - /// followed by a forward slash followed by the function name (this form - /// can also be seen in the resource JSON for the function). - /// This means that a span attribute MUST be used, as an Azure function - /// app can host multiple functions that would usually share - /// a TracerProvider (see also the cloud.resource_id attribute)
    • - ///
    . + /// platform and is usually different from the name of the callback + /// function (which may be stored in the + /// code.namespace/code.function + /// span attributes). + ///

    + /// For some cloud providers, the above definition is ambiguous. The following + /// definition of function name MUST be used for this attribute + /// (and consequently the span name) for the listed cloud providers/products: + ///

    + ///

      + ///
    • Azure: The full name /, i.e., function app name + /// followed by a forward slash followed by the function name (this form + /// can also be seen in the resource JSON for the function). + /// This means that a span attribute MUST be used, as an Azure function + /// app can host multiple functions that would usually share + /// a TracerProvider (see also the cloud.resource_id attribute)
    • + ///
    ///
    public const string AttributeFaasName = "faas.name"; /// - /// A string containing the function invocation time in the ISO 8601 format expressed in UTC. + /// A string containing the function invocation time in the ISO 8601 format expressed in UTC /// public const string AttributeFaasTime = "faas.time"; /// - /// Type of the trigger which caused this function invocation. + /// Type of the trigger which caused this function invocation /// public const string AttributeFaasTrigger = "faas.trigger"; /// - /// The immutable version of the function being executed. + /// The immutable version of the function being executed /// /// - /// Depending on the cloud provider and platform, use:
      - ///
    • AWS Lambda: The function version - /// (an integer represented as a decimal string).
    • - ///
    • Google Cloud Run (Services): The revision - /// (i.e., the function name plus the revision suffix).
    • - ///
    • Google Cloud Functions: The value of the - /// K_REVISION environment variable.
    • - ///
    • Azure Functions: Not applicable. Do not set this attribute
    • - ///
    . + /// Depending on the cloud provider and platform, use: + ///

    + ///

      + ///
    • AWS Lambda: The function version + /// (an integer represented as a decimal string).
    • + ///
    • Google Cloud Run (Services): The revision + /// (i.e., the function name plus the revision suffix).
    • + ///
    • Google Cloud Functions: The value of the + /// K_REVISION environment variable.
    • + ///
    • Azure Functions: Not applicable. Do not set this attribute
    • + ///
    ///
    public const string AttributeFaasVersion = "faas.version"; /// - /// Describes the type of the operation that was performed on the data. + /// Describes the type of the operation that was performed on the data /// public static class FaasDocumentOperationValues { /// - /// When a new object is created. + /// When a new object is created /// public const string Insert = "insert"; /// - /// When an object is modified. + /// When an object is modified /// public const string Edit = "edit"; /// - /// When an object is deleted. + /// When an object is deleted /// public const string Delete = "delete"; } /// - /// The cloud provider of the invoked function. + /// The cloud provider of the invoked function /// public static class FaasInvokedProviderValues { /// - /// Alibaba Cloud. + /// Alibaba Cloud /// public const string AlibabaCloud = "alibaba_cloud"; /// - /// Amazon Web Services. + /// Amazon Web Services /// public const string Aws = "aws"; /// - /// Microsoft Azure. + /// Microsoft Azure /// public const string Azure = "azure"; /// - /// Google Cloud Platform. + /// Google Cloud Platform /// public const string Gcp = "gcp"; /// - /// Tencent Cloud. + /// Tencent Cloud /// public const string TencentCloud = "tencent_cloud"; } /// - /// Type of the trigger which caused this function invocation. + /// Type of the trigger which caused this function invocation /// public static class FaasTriggerValues { /// - /// A response to some data source operation such as a database or filesystem read/write. + /// A response to some data source operation such as a database or filesystem read/write /// public const string Datasource = "datasource"; /// - /// To provide an answer to an inbound HTTP request. + /// To provide an answer to an inbound HTTP request /// public const string Http = "http"; /// - /// A function is set to be executed when messages are sent to a messaging system. + /// A function is set to be executed when messages are sent to a messaging system /// public const string Pubsub = "pubsub"; /// - /// A function is scheduled to be executed regularly. + /// A function is scheduled to be executed regularly /// public const string Timer = "timer"; /// - /// If none of the others apply. + /// If none of the others apply /// public const string Other = "other"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs index 31c3a7c683..b8aee7bdc4 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,25 +15,27 @@ namespace OpenTelemetry.SemanticConventions; public static class FeatureFlagAttributes { /// - /// The unique identifier of the feature flag. + /// The unique identifier of the feature flag /// public const string AttributeFeatureFlagKey = "feature_flag.key"; /// - /// The name of the service provider that performs the flag evaluation. + /// The name of the service provider that performs the flag evaluation /// public const string AttributeFeatureFlagProviderName = "feature_flag.provider_name"; /// - /// SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. + /// SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used /// /// /// A semantic identifier, commonly referred to as a variant, provides a means - /// for referring to a value without including the value itself. This can - /// provide additional context for understanding the meaning behind a value. - /// For example, the variant red maybe be used for the value #c05543.A stringified version of the value can be used in situations where a - /// semantic identifier is unavailable. String representation of the value - /// should be determined by the implementer. + /// for referring to a value without including the value itself. This can + /// provide additional context for understanding the meaning behind a value. + /// For example, the variant red maybe be used for the value #c05543. + ///

    + /// A stringified version of the value can be used in situations where a + /// semantic identifier is unavailable. String representation of the value + /// should be determined by the implementer /// public const string AttributeFeatureFlagVariant = "feature_flag.variant"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs index e0d80da3d4..1310eae87e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,30 +15,30 @@ namespace OpenTelemetry.SemanticConventions; public static class FileAttributes { ///

    - /// Directory where the file is located. It should include the drive letter, when appropriate. + /// Directory where the file is located. It should include the drive letter, when appropriate /// public const string AttributeFileDirectory = "file.directory"; /// - /// File extension, excluding the leading dot. + /// File extension, excluding the leading dot /// /// - /// When the file name has multiple extensions (example.tar.gz), only the last one should be captured (&#34;gz&#34;, not &#34;tar.gz&#34;). + /// When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz") /// public const string AttributeFileExtension = "file.extension"; /// - /// Name of the file including the extension, without the directory. + /// Name of the file including the extension, without the directory /// public const string AttributeFileName = "file.name"; /// - /// Full path to the file, including the file name. It should include the drive letter, when appropriate. + /// Full path to the file, including the file name. It should include the drive letter, when appropriate /// public const string AttributeFilePath = "file.path"; /// - /// File size in bytes. + /// File size in bytes /// public const string AttributeFileSize = "file.size"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs index d22ebdd455..f1a3601af5 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,22 +15,22 @@ namespace OpenTelemetry.SemanticConventions; public static class GcpAttributes { /// - /// The name of the Cloud Run execution being run for the Job, as set by the CLOUD_RUN_EXECUTION environment variable. + /// The name of the Cloud Run execution being run for the Job, as set by the CLOUD_RUN_EXECUTION environment variable /// public const string AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution"; /// - /// The index for a task within an execution as provided by the CLOUD_RUN_TASK_INDEX environment variable. + /// The index for a task within an execution as provided by the CLOUD_RUN_TASK_INDEX environment variable /// public const string AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index"; /// - /// The hostname of a GCE instance. This is the full value of the default or custom hostname. + /// The hostname of a GCE instance. This is the full value of the default or custom hostname /// public const string AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname"; /// - /// The instance name of a GCE instance. This is the value provided by host.name, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the default internal DNS name. + /// The instance name of a GCE instance. This is the value provided by host.name, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the default internal DNS name /// public const string AttributeGcpGceInstanceName = "gcp.gce.instance.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs new file mode 100644 index 0000000000..b335bf6444 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs @@ -0,0 +1,96 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class GenAiAttributes +{ + /// + /// The full response received from the LLM + /// + /// + /// It's RECOMMENDED to format completions as JSON string matching OpenAI messages format + /// + public const string AttributeGenAiCompletion = "gen_ai.completion"; + + /// + /// The full prompt sent to an LLM + /// + /// + /// It's RECOMMENDED to format prompts as JSON string matching OpenAI messages format + /// + public const string AttributeGenAiPrompt = "gen_ai.prompt"; + + /// + /// The maximum number of tokens the LLM generates for a request + /// + public const string AttributeGenAiRequestMaxTokens = "gen_ai.request.max_tokens"; + + /// + /// The name of the LLM a request is being made to + /// + public const string AttributeGenAiRequestModel = "gen_ai.request.model"; + + /// + /// The temperature setting for the LLM request + /// + public const string AttributeGenAiRequestTemperature = "gen_ai.request.temperature"; + + /// + /// The top_p sampling setting for the LLM request + /// + public const string AttributeGenAiRequestTopP = "gen_ai.request.top_p"; + + /// + /// Array of reasons the model stopped generating tokens, corresponding to each generation received + /// + public const string AttributeGenAiResponseFinishReasons = "gen_ai.response.finish_reasons"; + + /// + /// The unique identifier for the completion + /// + public const string AttributeGenAiResponseId = "gen_ai.response.id"; + + /// + /// The name of the LLM a response was generated from + /// + public const string AttributeGenAiResponseModel = "gen_ai.response.model"; + + /// + /// The Generative AI product as identified by the client instrumentation + /// + /// + /// The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the gen_ai.system is set to openai based on the instrumentation's best knowledge + /// + public const string AttributeGenAiSystem = "gen_ai.system"; + + /// + /// The number of tokens used in the LLM response (completion) + /// + public const string AttributeGenAiUsageCompletionTokens = "gen_ai.usage.completion_tokens"; + + /// + /// The number of tokens used in the LLM prompt + /// + public const string AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens"; + + /// + /// The Generative AI product as identified by the client instrumentation + /// + public static class GenAiSystemValues + { + /// + /// OpenAI + /// + public const string Openai = "openai"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs index d41a88d9c6..b770ad6a73 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,40 +15,40 @@ namespace OpenTelemetry.SemanticConventions; public static class GraphqlAttributes { /// - /// The GraphQL document being executed. + /// The GraphQL document being executed /// /// - /// The value may be sanitized to exclude sensitive information. + /// The value may be sanitized to exclude sensitive information /// public const string AttributeGraphqlDocument = "graphql.document"; /// - /// The name of the operation being executed. + /// The name of the operation being executed /// public const string AttributeGraphqlOperationName = "graphql.operation.name"; /// - /// The type of the operation being executed. + /// The type of the operation being executed /// public const string AttributeGraphqlOperationType = "graphql.operation.type"; /// - /// The type of the operation being executed. + /// The type of the operation being executed /// public static class GraphqlOperationTypeValues { /// - /// GraphQL query. + /// GraphQL query /// public const string Query = "query"; /// - /// GraphQL mutation. + /// GraphQL mutation /// public const string Mutation = "mutation"; /// - /// GraphQL subscription. + /// GraphQL subscription /// public const string Subscription = "subscription"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs index 0a4f498019..5d4aea042f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,17 +15,17 @@ namespace OpenTelemetry.SemanticConventions; public static class HerokuAttributes { /// - /// Unique identifier for the application. + /// Unique identifier for the application /// public const string AttributeHerokuAppId = "heroku.app.id"; /// - /// Commit hash for the current release. + /// Commit hash for the current release /// public const string AttributeHerokuReleaseCommit = "heroku.release.commit"; /// - /// Time and date the release was created. + /// Time and date the release was created /// public const string AttributeHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs index c80d817bde..d4e9506030 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,131 +15,131 @@ namespace OpenTelemetry.SemanticConventions; public static class HostAttributes { /// - /// The CPU architecture the host system is running on. + /// The CPU architecture the host system is running on /// public const string AttributeHostArch = "host.arch"; /// - /// The amount of level 2 memory cache available to the processor (in Bytes). + /// The amount of level 2 memory cache available to the processor (in Bytes) /// public const string AttributeHostCpuCacheL2Size = "host.cpu.cache.l2.size"; /// - /// Family or generation of the CPU. + /// Family or generation of the CPU /// public const string AttributeHostCpuFamily = "host.cpu.family"; /// - /// Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. + /// Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family /// public const string AttributeHostCpuModelId = "host.cpu.model.id"; /// - /// Model designation of the processor. + /// Model designation of the processor /// public const string AttributeHostCpuModelName = "host.cpu.model.name"; /// - /// Stepping or core revisions. + /// Stepping or core revisions /// public const string AttributeHostCpuStepping = "host.cpu.stepping"; /// - /// Processor manufacturer identifier. A maximum 12-character string. + /// Processor manufacturer identifier. A maximum 12-character string /// /// - /// CPUID command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. + /// CPUID command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string /// public const string AttributeHostCpuVendorId = "host.cpu.vendor.id"; /// - /// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the machine-id. See the table below for the sources to use to determine the machine-id based on operating system. + /// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the machine-id. See the table below for the sources to use to determine the machine-id based on operating system /// public const string AttributeHostId = "host.id"; /// - /// VM image ID or host OS image ID. For Cloud, this value is from the provider. + /// VM image ID or host OS image ID. For Cloud, this value is from the provider /// public const string AttributeHostImageId = "host.image.id"; /// - /// Name of the VM image or OS install the host was instantiated from. + /// Name of the VM image or OS install the host was instantiated from /// public const string AttributeHostImageName = "host.image.name"; /// - /// The version string of the VM image or host OS as defined in Version Attributes. + /// The version string of the VM image or host OS as defined in Version Attributes /// public const string AttributeHostImageVersion = "host.image.version"; /// - /// Available IP addresses of the host, excluding loopback interfaces. + /// Available IP addresses of the host, excluding loopback interfaces /// /// - /// IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the RFC 5952 format. + /// IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the RFC 5952 format /// public const string AttributeHostIp = "host.ip"; /// - /// Available MAC addresses of the host, excluding loopback interfaces. + /// Available MAC addresses of the host, excluding loopback interfaces /// /// - /// MAC Addresses MUST be represented in IEEE RA hexadecimal form: as hyphen-separated octets in uppercase hexadecimal form from most to least significant. + /// MAC Addresses MUST be represented in IEEE RA hexadecimal form: as hyphen-separated octets in uppercase hexadecimal form from most to least significant /// public const string AttributeHostMac = "host.mac"; /// - /// Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. + /// Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user /// public const string AttributeHostName = "host.name"; /// - /// Type of host. For Cloud, this must be the machine type. + /// Type of host. For Cloud, this must be the machine type /// public const string AttributeHostType = "host.type"; /// - /// The CPU architecture the host system is running on. + /// The CPU architecture the host system is running on /// public static class HostArchValues { /// - /// AMD64. + /// AMD64 /// public const string Amd64 = "amd64"; /// - /// ARM32. + /// ARM32 /// public const string Arm32 = "arm32"; /// - /// ARM64. + /// ARM64 /// public const string Arm64 = "arm64"; /// - /// Itanium. + /// Itanium /// public const string Ia64 = "ia64"; /// - /// 32-bit PowerPC. + /// 32-bit PowerPC /// public const string Ppc32 = "ppc32"; /// - /// 64-bit PowerPC. + /// 64-bit PowerPC /// public const string Ppc64 = "ppc64"; /// - /// IBM z/Architecture. + /// IBM z/Architecture /// public const string S390x = "s390x"; /// - /// 32-bit x86. + /// 32-bit x86 /// public const string X86 = "x86"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs index e84a5b8bf7..48dec9fbc1 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,250 +15,292 @@ namespace OpenTelemetry.SemanticConventions; public static class HttpAttributes { /// - /// State of the HTTP connection in the HTTP connection pool. + /// Deprecated, use client.address instead + /// + [Obsolete("Replaced by client.address")] + public const string AttributeHttpClientIp = "http.client_ip"; + + /// + /// State of the HTTP connection in the HTTP connection pool /// public const string AttributeHttpConnectionState = "http.connection.state"; /// - /// Deprecated, use network.protocol.name instead. + /// Deprecated, use network.protocol.name instead /// - [Obsolete("Replaced by `network.protocol.name`")] + [Obsolete("Replaced by network.protocol.name")] public const string AttributeHttpFlavor = "http.flavor"; /// - /// Deprecated, use http.request.method instead. + /// Deprecated, use one of server.address, client.address or http.request.header.host instead, depending on the usage /// - [Obsolete("Replaced by `http.request.method`")] + [Obsolete("Replaced by one of server.address, client.address or http.request.header.host, depending on the usage")] + public const string AttributeHttpHost = "http.host"; + + /// + /// Deprecated, use http.request.method instead + /// + [Obsolete("Replaced by http.request.method")] public const string AttributeHttpMethod = "http.method"; /// - /// The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size. + /// The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size /// public const string AttributeHttpRequestBodySize = "http.request.body.size"; /// - /// HTTP request headers, being the normalized HTTP Header name (lowercase), the value being the header values. + /// HTTP request headers, being the normalized HTTP Header name (lowercase), the value being the header values /// /// /// Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - /// The User-Agent header is already captured in the user_agent.original attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + /// The User-Agent header is already captured in the user_agent.original attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers /// - public const string AttributeHttpRequestHeader = "http.request.header"; + public const string AttributeHttpRequestHeaderTemplate = "http.request.header"; /// - /// HTTP request method. + /// HTTP request method /// /// - /// HTTP request method value SHOULD be &#34;known&#34; to the instrumentation. - /// By default, this convention defines &#34;known&#34; methods as the ones listed in RFC9110 - /// and the PATCH method defined in RFC5789.If the HTTP request method is not known to instrumentation, it MUST set the http.request.method attribute to _OTHER.If the HTTP instrumentation could end up converting valid HTTP request methods to _OTHER, then it MUST provide a way to override - /// the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named - /// OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods - /// (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).HTTP method names are case-sensitive and http.request.method attribute value MUST match a known HTTP method name exactly. - /// Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. - /// Tracing instrumentations that do so, MUST also set http.request.method_original to the original value. + /// HTTP request method value SHOULD be "known" to the instrumentation. + /// By default, this convention defines "known" methods as the ones listed in RFC9110 + /// and the PATCH method defined in RFC5789. + ///

    + /// If the HTTP request method is not known to instrumentation, it MUST set the http.request.method attribute to _OTHER. + ///

    + /// If the HTTP instrumentation could end up converting valid HTTP request methods to _OTHER, then it MUST provide a way to override + /// the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named + /// OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods + /// (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + ///

    + /// HTTP method names are case-sensitive and http.request.method attribute value MUST match a known HTTP method name exactly. + /// Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. + /// Tracing instrumentations that do so, MUST also set http.request.method_original to the original value /// public const string AttributeHttpRequestMethod = "http.request.method"; ///

    - /// Original HTTP method sent by the client in the request line. + /// Original HTTP method sent by the client in the request line /// public const string AttributeHttpRequestMethodOriginal = "http.request.method_original"; /// - /// The ordinal number of request resending attempt (for any reason, including redirects). + /// The ordinal number of request resending attempt (for any reason, including redirects) /// /// - /// The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). + /// The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other) /// public const string AttributeHttpRequestResendCount = "http.request.resend_count"; /// - /// The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. + /// The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any /// public const string AttributeHttpRequestSize = "http.request.size"; /// - /// Deprecated, use http.request.header.content-length instead. + /// Deprecated, use http.request.header.content-length instead /// - [Obsolete("Replaced by `http.request.header.content-length`")] + [Obsolete("Replaced by http.request.header.content-length")] public const string AttributeHttpRequestContentLength = "http.request_content_length"; /// - /// The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size. + /// Deprecated, use http.request.body.size instead + /// + [Obsolete("Replaced by http.request.body.size")] + public const string AttributeHttpRequestContentLengthUncompressed = "http.request_content_length_uncompressed"; + + /// + /// The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size /// public const string AttributeHttpResponseBodySize = "http.response.body.size"; /// - /// HTTP response headers, being the normalized HTTP Header name (lowercase), the value being the header values. + /// HTTP response headers, being the normalized HTTP Header name (lowercase), the value being the header values /// /// /// Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. - /// Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. + /// Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers /// - public const string AttributeHttpResponseHeader = "http.response.header"; + public const string AttributeHttpResponseHeaderTemplate = "http.response.header"; /// - /// The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. + /// The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any /// public const string AttributeHttpResponseSize = "http.response.size"; /// - /// HTTP response status code. + /// HTTP response status code /// public const string AttributeHttpResponseStatusCode = "http.response.status_code"; /// - /// Deprecated, use http.response.header.content-length instead. + /// Deprecated, use http.response.header.content-length instead /// - [Obsolete("Replaced by `http.response.header.content-length`")] + [Obsolete("Replaced by http.response.header.content-length")] public const string AttributeHttpResponseContentLength = "http.response_content_length"; /// - /// The matched route, that is, the path template in the format used by the respective server framework. + /// Deprecated, use http.response.body.size instead + /// + [Obsolete("Replace by http.response.body.size")] + public const string AttributeHttpResponseContentLengthUncompressed = "http.response_content_length_uncompressed"; + + /// + /// The matched route, that is, the path template in the format used by the respective server framework /// /// /// MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. - /// SHOULD include the application root if there is one. + /// SHOULD include the application root if there is one /// public const string AttributeHttpRoute = "http.route"; /// - /// Deprecated, use url.scheme instead. + /// Deprecated, use url.scheme instead /// - [Obsolete("Replaced by `url.scheme` instead")] + [Obsolete("Replaced by url.scheme instead")] public const string AttributeHttpScheme = "http.scheme"; /// - /// Deprecated, use http.response.status_code instead. + /// Deprecated, use server.address instead + /// + [Obsolete("Replaced by server.address")] + public const string AttributeHttpServerName = "http.server_name"; + + /// + /// Deprecated, use http.response.status_code instead /// - [Obsolete("Replaced by `http.response.status_code`")] + [Obsolete("Replaced by http.response.status_code")] public const string AttributeHttpStatusCode = "http.status_code"; /// - /// Deprecated, use url.path and url.query instead. + /// Deprecated, use url.path and url.query instead /// - [Obsolete("Split to `url.path` and `url.query")] + [Obsolete("Split to url.path and `url.query")] public const string AttributeHttpTarget = "http.target"; /// - /// Deprecated, use url.full instead. + /// Deprecated, use url.full instead /// - [Obsolete("Replaced by `url.full`")] + [Obsolete("Replaced by url.full")] public const string AttributeHttpUrl = "http.url"; /// - /// Deprecated, use user_agent.original instead. + /// Deprecated, use user_agent.original instead /// - [Obsolete("Replaced by `user_agent.original`")] + [Obsolete("Replaced by user_agent.original")] public const string AttributeHttpUserAgent = "http.user_agent"; /// - /// State of the HTTP connection in the HTTP connection pool. + /// State of the HTTP connection in the HTTP connection pool /// public static class HttpConnectionStateValues { /// - /// active state. + /// active state /// public const string Active = "active"; /// - /// idle state. + /// idle state /// public const string Idle = "idle"; } /// - /// Deprecated, use network.protocol.name instead. + /// Deprecated, use network.protocol.name instead /// public static class HttpFlavorValues { /// - /// HTTP/1.0. + /// HTTP/1.0 /// + [Obsolete("Replaced by network.protocol.name")] public const string Http10 = "1.0"; /// - /// HTTP/1.1. + /// HTTP/1.1 /// + [Obsolete("Replaced by network.protocol.name")] public const string Http11 = "1.1"; /// - /// HTTP/2. + /// HTTP/2 /// + [Obsolete("Replaced by network.protocol.name")] public const string Http20 = "2.0"; /// - /// HTTP/3. + /// HTTP/3 /// + [Obsolete("Replaced by network.protocol.name")] public const string Http30 = "3.0"; /// - /// SPDY protocol. + /// SPDY protocol /// + [Obsolete("Replaced by network.protocol.name")] public const string Spdy = "SPDY"; /// - /// QUIC protocol. + /// QUIC protocol /// + [Obsolete("Replaced by network.protocol.name")] public const string Quic = "QUIC"; } /// - /// HTTP request method. + /// HTTP request method /// public static class HttpRequestMethodValues { /// - /// CONNECT method. + /// CONNECT method /// public const string Connect = "CONNECT"; /// - /// DELETE method. + /// DELETE method /// public const string Delete = "DELETE"; /// - /// GET method. + /// GET method /// public const string Get = "GET"; /// - /// HEAD method. + /// HEAD method /// public const string Head = "HEAD"; /// - /// OPTIONS method. + /// OPTIONS method /// public const string Options = "OPTIONS"; /// - /// PATCH method. + /// PATCH method /// public const string Patch = "PATCH"; /// - /// POST method. + /// POST method /// public const string Post = "POST"; /// - /// PUT method. + /// PUT method /// public const string Put = "PUT"; /// - /// TRACE method. + /// TRACE method /// public const string Trace = "TRACE"; /// - /// Any HTTP method that the instrumentation has no prior knowledge of. + /// Any HTTP method that the instrumentation has no prior knowledge of /// public const string Other = "_OTHER"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs index 0ba843170d..d8a2b6b686 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,41 +15,47 @@ namespace OpenTelemetry.SemanticConventions; public static class IosAttributes { /// - /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// Deprecated use the device.app.lifecycle event definition including ios.state as a payload field instead /// /// - /// The iOS lifecycle states are defined in the UIApplicationDelegate documentation, and from which the OS terminology column values are derived. + /// The iOS lifecycle states are defined in the UIApplicationDelegate documentation, and from which the OS terminology column values are derived /// + [Obsolete("Moved to a payload field of device.app.lifecycle")] public const string AttributeIosState = "ios.state"; /// - /// This attribute represents the state the application has transitioned into at the occurrence of the event. + /// Deprecated use the device.app.lifecycle event definition including ios.state as a payload field instead /// public static class IosStateValues { /// - /// The app has become active. Associated with UIKit notification applicationDidBecomeActive. + /// The app has become active. Associated with UIKit notification applicationDidBecomeActive /// + [Obsolete("Moved to a payload field of device.app.lifecycle")] public const string Active = "active"; /// - /// The app is now inactive. Associated with UIKit notification applicationWillResignActive. + /// The app is now inactive. Associated with UIKit notification applicationWillResignActive /// + [Obsolete("Moved to a payload field of device.app.lifecycle")] public const string Inactive = "inactive"; /// - /// The app is now in the background. This value is associated with UIKit notification applicationDidEnterBackground. + /// The app is now in the background. This value is associated with UIKit notification applicationDidEnterBackground /// + [Obsolete("Moved to a payload field of device.app.lifecycle")] public const string Background = "background"; /// - /// The app is now in the foreground. This value is associated with UIKit notification applicationWillEnterForeground. + /// The app is now in the foreground. This value is associated with UIKit notification applicationWillEnterForeground /// + [Obsolete("Moved to a payload field of device.app.lifecycle")] public const string Foreground = "foreground"; /// - /// The app is about to terminate. Associated with UIKit notification applicationWillTerminate. + /// The app is about to terminate. Associated with UIKit notification applicationWillTerminate /// + [Obsolete("Moved to a payload field of device.app.lifecycle")] public const string Terminate = "terminate"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs index 74ba9d1983..f51450b140 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,100 +15,100 @@ namespace OpenTelemetry.SemanticConventions; public static class JvmAttributes { /// - /// Name of the buffer pool. + /// Name of the buffer pool /// /// - /// Pool names are generally obtained via BufferPoolMXBean#getName(). + /// Pool names are generally obtained via BufferPoolMXBean#getName() /// public const string AttributeJvmBufferPoolName = "jvm.buffer.pool.name"; /// - /// Name of the garbage collector action. + /// Name of the garbage collector action /// /// - /// Garbage collector action is generally obtained via GarbageCollectionNotificationInfo#getGcAction(). + /// Garbage collector action is generally obtained via GarbageCollectionNotificationInfo#getGcAction() /// public const string AttributeJvmGcAction = "jvm.gc.action"; /// - /// Name of the garbage collector. + /// Name of the garbage collector /// /// - /// Garbage collector name is generally obtained via GarbageCollectionNotificationInfo#getGcName(). + /// Garbage collector name is generally obtained via GarbageCollectionNotificationInfo#getGcName() /// public const string AttributeJvmGcName = "jvm.gc.name"; /// - /// Name of the memory pool. + /// Name of the memory pool /// /// - /// Pool names are generally obtained via MemoryPoolMXBean#getName(). + /// Pool names are generally obtained via MemoryPoolMXBean#getName() /// public const string AttributeJvmMemoryPoolName = "jvm.memory.pool.name"; /// - /// The type of memory. + /// The type of memory /// public const string AttributeJvmMemoryType = "jvm.memory.type"; /// - /// Whether the thread is daemon or not. + /// Whether the thread is daemon or not /// public const string AttributeJvmThreadDaemon = "jvm.thread.daemon"; /// - /// State of the thread. + /// State of the thread /// public const string AttributeJvmThreadState = "jvm.thread.state"; /// - /// The type of memory. + /// The type of memory /// public static class JvmMemoryTypeValues { /// - /// Heap memory. + /// Heap memory /// public const string Heap = "heap"; /// - /// Non-heap memory. + /// Non-heap memory /// public const string NonHeap = "non_heap"; } /// - /// State of the thread. + /// State of the thread /// public static class JvmThreadStateValues { /// - /// A thread that has not yet started is in this state. + /// A thread that has not yet started is in this state /// public const string New = "new"; /// - /// A thread executing in the Java virtual machine is in this state. + /// A thread executing in the Java virtual machine is in this state /// public const string Runnable = "runnable"; /// - /// A thread that is blocked waiting for a monitor lock is in this state. + /// A thread that is blocked waiting for a monitor lock is in this state /// public const string Blocked = "blocked"; /// - /// A thread that is waiting indefinitely for another thread to perform a particular action is in this state. + /// A thread that is waiting indefinitely for another thread to perform a particular action is in this state /// public const string Waiting = "waiting"; /// - /// A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. + /// A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state /// public const string TimedWaiting = "timed_waiting"; /// - /// A thread that has exited is in this state. + /// A thread that has exited is in this state /// public const string Terminated = "terminated"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs index 614ce06d72..e1013adc29 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,141 +15,154 @@ namespace OpenTelemetry.SemanticConventions; public static class K8sAttributes { /// - /// The name of the cluster. + /// The name of the cluster /// public const string AttributeK8sClusterName = "k8s.cluster.name"; /// - /// A pseudo-ID for the cluster, set to the UID of the kube-system namespace. + /// A pseudo-ID for the cluster, set to the UID of the kube-system namespace /// /// - /// K8s doesn&#39;t have support for obtaining a cluster ID. If this is ever - /// added, we will recommend collecting the k8s.cluster.uid through the - /// official APIs. In the meantime, we are able to use the uid of the - /// kube-system namespace as a proxy for cluster ID. Read on for the - /// rationale.Every object created in a K8s cluster is assigned a distinct UID. The - /// kube-system namespace is used by Kubernetes itself and will exist - /// for the lifetime of the cluster. Using the uid of the kube-system - /// namespace is a reasonable proxy for the K8s ClusterID as it will only - /// change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are - /// UUIDs as standardized by - /// ISO/IEC 9834-8 and ITU-T X.667. - /// Which states:&gt; If generated according to one of the mechanisms defined in Rec. - /// ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be - /// different from all other UUIDs generated before 3603 A.D., or is - /// extremely likely to be different (depending on the mechanism chosen).Therefore, UIDs between clusters should be extremely unlikely to - /// conflict. + /// K8s doesn't have support for obtaining a cluster ID. If this is ever + /// added, we will recommend collecting the k8s.cluster.uid through the + /// official APIs. In the meantime, we are able to use the uid of the + /// kube-system namespace as a proxy for cluster ID. Read on for the + /// rationale. + ///

    + /// Every object created in a K8s cluster is assigned a distinct UID. The + /// kube-system namespace is used by Kubernetes itself and will exist + /// for the lifetime of the cluster. Using the uid of the kube-system + /// namespace is a reasonable proxy for the K8s ClusterID as it will only + /// change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are + /// UUIDs as standardized by + /// ISO/IEC 9834-8 and ITU-T X.667. + /// Which states: + ///

    + ///

    + /// If generated according to one of the mechanisms defined in Rec. + /// ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be + /// different from all other UUIDs generated before 3603 A.D., or is + /// extremely likely to be different (depending on the mechanism chosen).
    + /// + ///

    + /// Therefore, UIDs between clusters should be extremely unlikely to + /// conflict /// public const string AttributeK8sClusterUid = "k8s.cluster.uid"; ///

    - /// The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (container.name). + /// The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (container.name) /// public const string AttributeK8sContainerName = "k8s.container.name"; /// - /// Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. + /// Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec /// public const string AttributeK8sContainerRestartCount = "k8s.container.restart_count"; /// - /// The name of the CronJob. + /// Last terminated reason of the Container + /// + public const string AttributeK8sContainerStatusLastTerminatedReason = "k8s.container.status.last_terminated_reason"; + + /// + /// The name of the CronJob /// public const string AttributeK8sCronjobName = "k8s.cronjob.name"; /// - /// The UID of the CronJob. + /// The UID of the CronJob /// public const string AttributeK8sCronjobUid = "k8s.cronjob.uid"; /// - /// The name of the DaemonSet. + /// The name of the DaemonSet /// public const string AttributeK8sDaemonsetName = "k8s.daemonset.name"; /// - /// The UID of the DaemonSet. + /// The UID of the DaemonSet /// public const string AttributeK8sDaemonsetUid = "k8s.daemonset.uid"; /// - /// The name of the Deployment. + /// The name of the Deployment /// public const string AttributeK8sDeploymentName = "k8s.deployment.name"; /// - /// The UID of the Deployment. + /// The UID of the Deployment /// public const string AttributeK8sDeploymentUid = "k8s.deployment.uid"; /// - /// The name of the Job. + /// The name of the Job /// public const string AttributeK8sJobName = "k8s.job.name"; /// - /// The UID of the Job. + /// The UID of the Job /// public const string AttributeK8sJobUid = "k8s.job.uid"; /// - /// The name of the namespace that the pod is running in. + /// The name of the namespace that the pod is running in /// public const string AttributeK8sNamespaceName = "k8s.namespace.name"; /// - /// The name of the Node. + /// The name of the Node /// public const string AttributeK8sNodeName = "k8s.node.name"; /// - /// The UID of the Node. + /// The UID of the Node /// public const string AttributeK8sNodeUid = "k8s.node.uid"; /// - /// The annotation key-value pairs placed on the Pod, the being the annotation name, the value being the annotation value. + /// The annotation key-value pairs placed on the Pod, the being the annotation name, the value being the annotation value /// - public const string AttributeK8sPodAnnotation = "k8s.pod.annotation"; + public const string AttributeK8sPodAnnotationTemplate = "k8s.pod.annotation"; /// - /// The label key-value pairs placed on the Pod, the being the label name, the value being the label value. + /// The label key-value pairs placed on the Pod, the being the label name, the value being the label value /// - public const string AttributeK8sPodLabel = "k8s.pod.label"; + public const string AttributeK8sPodLabelTemplate = "k8s.pod.label"; /// - /// Deprecated, use k8s.pod.label instead. + /// Deprecated, use k8s.pod.label instead /// - [Obsolete("Replaced by `k8s.pod.label`")] - public const string AttributeK8sPodLabels = "k8s.pod.labels"; + [Obsolete("Replaced by k8s.pod.label")] + public const string AttributeK8sPodLabelsTemplate = "k8s.pod.labels"; /// - /// The name of the Pod. + /// The name of the Pod /// public const string AttributeK8sPodName = "k8s.pod.name"; /// - /// The UID of the Pod. + /// The UID of the Pod /// public const string AttributeK8sPodUid = "k8s.pod.uid"; /// - /// The name of the ReplicaSet. + /// The name of the ReplicaSet /// public const string AttributeK8sReplicasetName = "k8s.replicaset.name"; /// - /// The UID of the ReplicaSet. + /// The UID of the ReplicaSet /// public const string AttributeK8sReplicasetUid = "k8s.replicaset.uid"; /// - /// The name of the StatefulSet. + /// The name of the StatefulSet /// public const string AttributeK8sStatefulsetName = "k8s.statefulset.name"; /// - /// The UID of the StatefulSet. + /// The UID of the StatefulSet /// public const string AttributeK8sStatefulsetUid = "k8s.statefulset.uid"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs index a314e0deb4..6ac9fc3706 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,51 +15,51 @@ namespace OpenTelemetry.SemanticConventions; public static class LogAttributes { /// - /// The basename of the file. + /// The basename of the file /// public const string AttributeLogFileName = "log.file.name"; /// - /// The basename of the file, with symlinks resolved. + /// The basename of the file, with symlinks resolved /// public const string AttributeLogFileNameResolved = "log.file.name_resolved"; /// - /// The full path to the file. + /// The full path to the file /// public const string AttributeLogFilePath = "log.file.path"; /// - /// The full path to the file, with symlinks resolved. + /// The full path to the file, with symlinks resolved /// public const string AttributeLogFilePathResolved = "log.file.path_resolved"; /// - /// The stream associated with the log. See below for a list of well-known values. + /// The stream associated with the log. See below for a list of well-known values /// public const string AttributeLogIostream = "log.iostream"; /// - /// A unique identifier for the Log Record. + /// A unique identifier for the Log Record /// /// /// If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. - /// The id MAY be an Universally Unique Lexicographically Sortable Identifier (ULID), but other identifiers (e.g. UUID) may be used as needed. + /// The id MAY be an Universally Unique Lexicographically Sortable Identifier (ULID), but other identifiers (e.g. UUID) may be used as needed /// public const string AttributeLogRecordUid = "log.record.uid"; /// - /// The stream associated with the log. See below for a list of well-known values. + /// The stream associated with the log. See below for a list of well-known values /// public static class LogIostreamValues { /// - /// Logs from stdout stream. + /// Logs from stdout stream /// public const string Stdout = "stdout"; /// - /// Events from stderr stream. + /// Events from stderr stream /// public const string Stderr = "stderr"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs index 5014c3b41d..af856c42b4 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,41 +15,44 @@ namespace OpenTelemetry.SemanticConventions; public static class MessageAttributes { /// - /// Compressed size of the message in bytes. + /// Deprecated, use rpc.message.compressed_size instead /// + [Obsolete("Replaced by rpc.message.compressed_size")] public const string AttributeMessageCompressedSize = "message.compressed_size"; /// - /// MUST be calculated as two different counters starting from 1 one for sent messages and one for received message. + /// Deprecated, use rpc.message.id instead /// - /// - /// This way we guarantee that the values will be consistent between different implementations. - /// + [Obsolete("Replaced by rpc.message.id")] public const string AttributeMessageId = "message.id"; /// - /// Whether this is a received or sent message. + /// Deprecated, use rpc.message.type instead /// + [Obsolete("Replaced by rpc.message.type")] public const string AttributeMessageType = "message.type"; /// - /// Uncompressed size of the message in bytes. + /// Deprecated, use rpc.message.uncompressed_size instead /// + [Obsolete("Replaced by rpc.message.uncompressed_size")] public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; /// - /// Whether this is a received or sent message. + /// Deprecated, use rpc.message.type instead /// public static class MessageTypeValues { /// - /// sent. + /// sent /// + [Obsolete("Replaced by rpc.message.type")] public const string Sent = "SENT"; /// - /// received. + /// received /// + [Obsolete("Replaced by rpc.message.type")] public const string Received = "RECEIVED"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs index 22c391ac2a..ba9a5dc46a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,375 +15,404 @@ namespace OpenTelemetry.SemanticConventions; public static class MessagingAttributes { /// - /// The number of messages sent, received, or processed in the scope of the batching operation. + /// The number of messages sent, received, or processed in the scope of the batching operation /// /// - /// Instrumentations SHOULD NOT set messaging.batch.message_count on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use messaging.batch.message_count for batching APIs and SHOULD NOT use it for single-message APIs. + /// Instrumentations SHOULD NOT set messaging.batch.message_count on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use messaging.batch.message_count for batching APIs and SHOULD NOT use it for single-message APIs /// public const string AttributeMessagingBatchMessageCount = "messaging.batch.message_count"; /// - /// A unique identifier for the client that consumes or produces a message. + /// A unique identifier for the client that consumes or produces a message /// - public const string AttributeMessagingClientId = "messaging.client_id"; + public const string AttributeMessagingClientId = "messaging.client.id"; /// - /// A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). + /// A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name) /// public const string AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous"; /// - /// The message destination name. + /// The message destination name /// /// /// Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If - /// the broker doesn&#39;t have such notion, the destination name SHOULD uniquely identify the broker. + /// the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker /// public const string AttributeMessagingDestinationName = "messaging.destination.name"; /// - /// The identifier of the partition messages are sent to or received from, unique within the messaging.destination.name. + /// The identifier of the partition messages are sent to or received from, unique within the messaging.destination.name /// public const string AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id"; /// - /// Low cardinality representation of the messaging destination name. + /// Low cardinality representation of the messaging destination name /// /// - /// Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. + /// Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation /// public const string AttributeMessagingDestinationTemplate = "messaging.destination.template"; /// - /// A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. + /// A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed /// public const string AttributeMessagingDestinationTemporary = "messaging.destination.temporary"; /// - /// A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name). + /// A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name) /// public const string AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous"; /// - /// The name of the original destination the message was published to. + /// The name of the original destination the message was published to /// /// /// The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If - /// the broker doesn&#39;t have such notion, the original destination name SHOULD uniquely identify the broker. + /// the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker /// public const string AttributeMessagingDestinationPublishName = "messaging.destination_publish.name"; /// - /// The name of the consumer group the event consumer is associated with. + /// The name of the consumer group the event consumer is associated with /// public const string AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group"; /// - /// The UTC epoch seconds at which the message has been accepted and stored in the entity. + /// The UTC epoch seconds at which the message has been accepted and stored in the entity /// public const string AttributeMessagingEventhubsMessageEnqueuedTime = "messaging.eventhubs.message.enqueued_time"; /// - /// The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. + /// The ack deadline in seconds set for the modify ack deadline request + /// + public const string AttributeMessagingGcpPubsubMessageAckDeadline = "messaging.gcp_pubsub.message.ack_deadline"; + + /// + /// The ack id for a given message + /// + public const string AttributeMessagingGcpPubsubMessageAckId = "messaging.gcp_pubsub.message.ack_id"; + + /// + /// The delivery attempt for a given message + /// + public const string AttributeMessagingGcpPubsubMessageDeliveryAttempt = "messaging.gcp_pubsub.message.delivery_attempt"; + + /// + /// The ordering key for a given message. If the attribute is not present, the message does not have an ordering key /// public const string AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key"; /// - /// Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers. + /// Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers /// public const string AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; /// - /// "Deprecated, use messaging.destination.partition.id instead.". + /// Deprecated, use messaging.destination.partition.id instead /// - [Obsolete("Replaced by `messaging.destination.partition.id`")] + [Obsolete("Replaced by messaging.destination.partition.id")] public const string AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition"; /// - /// Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from messaging.message.id in that they're not unique. If the key is null, the attribute MUST NOT be set. + /// Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from messaging.message.id in that they're not unique. If the key is null, the attribute MUST NOT be set /// /// - /// If the key type is not string, it&#39;s string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don&#39;t include its value. + /// If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value /// public const string AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key"; /// - /// The offset of a record in the corresponding Kafka partition. + /// The offset of a record in the corresponding Kafka partition /// public const string AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; /// - /// A boolean that is true if the message is a tombstone. + /// A boolean that is true if the message is a tombstone /// public const string AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone"; /// - /// The size of the message body in bytes. + /// The size of the message body in bytes /// /// /// This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed - /// body size should be used. + /// body size should be used /// public const string AttributeMessagingMessageBodySize = "messaging.message.body.size"; /// - /// The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". + /// The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID" /// public const string AttributeMessagingMessageConversationId = "messaging.message.conversation_id"; /// - /// The size of the message body and metadata in bytes. + /// The size of the message body and metadata in bytes /// /// /// This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed - /// size should be used. + /// size should be used /// public const string AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size"; /// - /// A value used by the messaging system as an identifier for the message, represented as a string. + /// A value used by the messaging system as an identifier for the message, represented as a string /// public const string AttributeMessagingMessageId = "messaging.message.id"; /// - /// A string identifying the kind of messaging operation. + /// Deprecated, use messaging.operation.type instead + /// + [Obsolete("Replaced by messaging.operation.type")] + public const string AttributeMessagingOperation = "messaging.operation"; + + /// + /// The system-specific name of the messaging operation + /// + public const string AttributeMessagingOperationName = "messaging.operation.name"; + + /// + /// A string identifying the type of the messaging operation /// /// - /// If a custom value is used, it MUST be of low cardinality. + /// If a custom value is used, it MUST be of low cardinality /// - public const string AttributeMessagingOperation = "messaging.operation"; + public const string AttributeMessagingOperationType = "messaging.operation.type"; /// - /// RabbitMQ message routing key. + /// RabbitMQ message routing key /// public const string AttributeMessagingRabbitmqDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key"; /// - /// RabbitMQ message delivery tag. + /// RabbitMQ message delivery tag /// public const string AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag"; /// - /// Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind. + /// Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind /// public const string AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group"; /// - /// Model of message consumption. This only applies to consumer spans. + /// Model of message consumption. This only applies to consumer spans /// public const string AttributeMessagingRocketmqConsumptionModel = "messaging.rocketmq.consumption_model"; /// - /// The delay time level for delay message, which determines the message delay time. + /// The delay time level for delay message, which determines the message delay time /// public const string AttributeMessagingRocketmqMessageDelayTimeLevel = "messaging.rocketmq.message.delay_time_level"; /// - /// The timestamp in milliseconds that the delay message is expected to be delivered to consumer. + /// The timestamp in milliseconds that the delay message is expected to be delivered to consumer /// public const string AttributeMessagingRocketmqMessageDeliveryTimestamp = "messaging.rocketmq.message.delivery_timestamp"; /// - /// It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. + /// It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group /// public const string AttributeMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group"; /// - /// Key(s) of message, another way to mark message besides message id. + /// Key(s) of message, another way to mark message besides message id /// public const string AttributeMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys"; /// - /// The secondary classifier of message besides topic. + /// The secondary classifier of message besides topic /// public const string AttributeMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag"; /// - /// Type of message. + /// Type of message /// public const string AttributeMessagingRocketmqMessageType = "messaging.rocketmq.message.type"; /// - /// Namespace of RocketMQ resources, resources in different namespaces are individual. + /// Namespace of RocketMQ resources, resources in different namespaces are individual /// public const string AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; /// - /// The name of the subscription in the topic messages are received from. + /// The name of the subscription in the topic messages are received from /// public const string AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name"; /// - /// Describes the settlement type. + /// Describes the settlement type /// public const string AttributeMessagingServicebusDispositionStatus = "messaging.servicebus.disposition_status"; /// - /// Number of deliveries that have been attempted for this message. + /// Number of deliveries that have been attempted for this message /// public const string AttributeMessagingServicebusMessageDeliveryCount = "messaging.servicebus.message.delivery_count"; /// - /// The UTC epoch seconds at which the message has been accepted and stored in the entity. + /// The UTC epoch seconds at which the message has been accepted and stored in the entity /// public const string AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time"; /// - /// An identifier for the messaging system being used. See below for a list of well-known identifiers. + /// The messaging system as identified by the client instrumentation /// + /// + /// The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the messaging.system is set to kafka based on the instrumentation's best knowledge + /// public const string AttributeMessagingSystem = "messaging.system"; /// - /// A string identifying the kind of messaging operation. + /// A string identifying the type of the messaging operation /// - public static class MessagingOperationValues + public static class MessagingOperationTypeValues { /// - /// One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. + /// One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created /// public const string Publish = "publish"; /// - /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. + /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios /// public const string Create = "create"; /// - /// One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. + /// One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages /// public const string Receive = "receive"; /// - /// One or more messages are delivered to or processed by a consumer. + /// One or more messages are delivered to or processed by a consumer /// public const string Deliver = "process"; /// - /// One or more messages are settled. + /// One or more messages are settled /// public const string Settle = "settle"; } /// - /// Model of message consumption. This only applies to consumer spans. + /// Model of message consumption. This only applies to consumer spans /// public static class MessagingRocketmqConsumptionModelValues { /// - /// Clustering consumption model. + /// Clustering consumption model /// public const string Clustering = "clustering"; /// - /// Broadcasting consumption model. + /// Broadcasting consumption model /// public const string Broadcasting = "broadcasting"; } /// - /// Type of message. + /// Type of message /// public static class MessagingRocketmqMessageTypeValues { /// - /// Normal message. + /// Normal message /// public const string Normal = "normal"; /// - /// FIFO message. + /// FIFO message /// public const string Fifo = "fifo"; /// - /// Delay message. + /// Delay message /// public const string Delay = "delay"; /// - /// Transaction message. + /// Transaction message /// public const string Transaction = "transaction"; } /// - /// Describes the settlement type. + /// Describes the settlement type /// public static class MessagingServicebusDispositionStatusValues { /// - /// Message is completed. + /// Message is completed /// public const string Complete = "complete"; /// - /// Message is abandoned. + /// Message is abandoned /// public const string Abandon = "abandon"; /// - /// Message is sent to dead letter queue. + /// Message is sent to dead letter queue /// public const string DeadLetter = "dead_letter"; /// - /// Message is deferred. + /// Message is deferred /// public const string Defer = "defer"; } /// - /// An identifier for the messaging system being used. See below for a list of well-known identifiers. + /// The messaging system as identified by the client instrumentation /// public static class MessagingSystemValues { /// - /// Apache ActiveMQ. + /// Apache ActiveMQ /// public const string Activemq = "activemq"; /// - /// Amazon Simple Queue Service (SQS). + /// Amazon Simple Queue Service (SQS) /// public const string AwsSqs = "aws_sqs"; /// - /// Azure Event Grid. + /// Azure Event Grid /// public const string Eventgrid = "eventgrid"; /// - /// Azure Event Hubs. + /// Azure Event Hubs /// public const string Eventhubs = "eventhubs"; /// - /// Azure Service Bus. + /// Azure Service Bus /// public const string Servicebus = "servicebus"; /// - /// Google Cloud Pub/Sub. + /// Google Cloud Pub/Sub /// public const string GcpPubsub = "gcp_pubsub"; /// - /// Java Message Service. + /// Java Message Service /// public const string Jms = "jms"; /// - /// Apache Kafka. + /// Apache Kafka /// public const string Kafka = "kafka"; /// - /// RabbitMQ. + /// RabbitMQ /// public const string Rabbitmq = "rabbitmq"; /// - /// Apache RocketMQ. + /// Apache RocketMQ /// public const string Rocketmq = "rocketmq"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs index 70ea82c16e..06fdfff932 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,132 +15,152 @@ namespace OpenTelemetry.SemanticConventions; public static class NetAttributes { /// - /// Deprecated, use server.address. + /// Deprecated, use network.local.address + /// + [Obsolete("Replaced by network.local.address")] + public const string AttributeNetHostIp = "net.host.ip"; + + /// + /// Deprecated, use server.address /// - [Obsolete("Replaced by `server.address`")] + [Obsolete("Replaced by server.address")] public const string AttributeNetHostName = "net.host.name"; /// - /// Deprecated, use server.port. + /// Deprecated, use server.port /// - [Obsolete("Replaced by `server.port`")] + [Obsolete("Replaced by server.port")] public const string AttributeNetHostPort = "net.host.port"; /// - /// Deprecated, use server.address on client spans and client.address on server spans. + /// Deprecated, use network.peer.address + /// + [Obsolete("Replaced by network.peer.address")] + public const string AttributeNetPeerIp = "net.peer.ip"; + + /// + /// Deprecated, use server.address on client spans and client.address on server spans /// - [Obsolete("Replaced by `server.address` on client spans and `client.address` on server spans")] + [Obsolete("Replaced by server.address on client spans and client.address on server spans")] public const string AttributeNetPeerName = "net.peer.name"; /// - /// Deprecated, use server.port on client spans and client.port on server spans. + /// Deprecated, use server.port on client spans and client.port on server spans /// - [Obsolete("Replaced by `server.port` on client spans and `client.port` on server spans")] + [Obsolete("Replaced by server.port on client spans and client.port on server spans")] public const string AttributeNetPeerPort = "net.peer.port"; /// - /// Deprecated, use network.protocol.name. + /// Deprecated, use network.protocol.name /// - [Obsolete("Replaced by `network.protocol.name`")] + [Obsolete("Replaced by network.protocol.name")] public const string AttributeNetProtocolName = "net.protocol.name"; /// - /// Deprecated, use network.protocol.version. + /// Deprecated, use network.protocol.version /// - [Obsolete("Replaced by `network.protocol.version`")] + [Obsolete("Replaced by network.protocol.version")] public const string AttributeNetProtocolVersion = "net.protocol.version"; /// - /// Deprecated, use network.transport and network.type. + /// Deprecated, use network.transport and network.type /// - [Obsolete("Split to `network.transport` and `network.type`")] + [Obsolete("Split to network.transport and network.type")] public const string AttributeNetSockFamily = "net.sock.family"; /// - /// Deprecated, use network.local.address. + /// Deprecated, use network.local.address /// - [Obsolete("Replaced by `network.local.address`")] + [Obsolete("Replaced by network.local.address")] public const string AttributeNetSockHostAddr = "net.sock.host.addr"; /// - /// Deprecated, use network.local.port. + /// Deprecated, use network.local.port /// - [Obsolete("Replaced by `network.local.port`")] + [Obsolete("Replaced by network.local.port")] public const string AttributeNetSockHostPort = "net.sock.host.port"; /// - /// Deprecated, use network.peer.address. + /// Deprecated, use network.peer.address /// - [Obsolete("Replaced by `network.peer.address`")] + [Obsolete("Replaced by network.peer.address")] public const string AttributeNetSockPeerAddr = "net.sock.peer.addr"; /// - /// Deprecated, no replacement at this time. + /// Deprecated, no replacement at this time /// [Obsolete("Removed")] public const string AttributeNetSockPeerName = "net.sock.peer.name"; /// - /// Deprecated, use network.peer.port. + /// Deprecated, use network.peer.port /// - [Obsolete("Replaced by `network.peer.port`")] + [Obsolete("Replaced by network.peer.port")] public const string AttributeNetSockPeerPort = "net.sock.peer.port"; /// - /// Deprecated, use network.transport. + /// Deprecated, use network.transport /// - [Obsolete("Replaced by `network.transport`")] + [Obsolete("Replaced by network.transport")] public const string AttributeNetTransport = "net.transport"; /// - /// Deprecated, use network.transport and network.type. + /// Deprecated, use network.transport and network.type /// public static class NetSockFamilyValues { /// - /// IPv4 address. + /// IPv4 address /// + [Obsolete("Split to network.transport and network.type")] public const string Inet = "inet"; /// - /// IPv6 address. + /// IPv6 address /// + [Obsolete("Split to network.transport and network.type")] public const string Inet6 = "inet6"; /// - /// Unix domain socket path. + /// Unix domain socket path /// + [Obsolete("Split to network.transport and network.type")] public const string Unix = "unix"; } /// - /// Deprecated, use network.transport. + /// Deprecated, use network.transport /// public static class NetTransportValues { /// - /// ip_tcp. + /// ip_tcp /// + [Obsolete("Replaced by network.transport")] public const string IpTcp = "ip_tcp"; /// - /// ip_udp. + /// ip_udp /// + [Obsolete("Replaced by network.transport")] public const string IpUdp = "ip_udp"; /// - /// Named or anonymous pipe. + /// Named or anonymous pipe /// + [Obsolete("Replaced by network.transport")] public const string Pipe = "pipe"; /// - /// In-process communication. + /// In-process communication /// + [Obsolete("Replaced by network.transport")] public const string Inproc = "inproc"; /// - /// Something else (non IP-based). + /// Something else (non IP-based) /// + [Obsolete("Replaced by network.transport")] public const string Other = "other"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs index 77e6914a6c..7bf9321337 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,290 +15,292 @@ namespace OpenTelemetry.SemanticConventions; public static class NetworkAttributes { /// - /// The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + /// The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network /// public const string AttributeNetworkCarrierIcc = "network.carrier.icc"; /// - /// The mobile carrier country code. + /// The mobile carrier country code /// public const string AttributeNetworkCarrierMcc = "network.carrier.mcc"; /// - /// The mobile carrier network code. + /// The mobile carrier network code /// public const string AttributeNetworkCarrierMnc = "network.carrier.mnc"; /// - /// The name of the mobile carrier. + /// The name of the mobile carrier /// public const string AttributeNetworkCarrierName = "network.carrier.name"; /// - /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. + /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection /// public const string AttributeNetworkConnectionSubtype = "network.connection.subtype"; /// - /// The internet connection type. + /// The internet connection type /// public const string AttributeNetworkConnectionType = "network.connection.type"; /// - /// The network IO operation direction. + /// The network IO operation direction /// public const string AttributeNetworkIoDirection = "network.io.direction"; /// - /// Local address of the network connection - IP address or Unix domain socket name. + /// Local address of the network connection - IP address or Unix domain socket name /// public const string AttributeNetworkLocalAddress = "network.local.address"; /// - /// Local port number of the network connection. + /// Local port number of the network connection /// public const string AttributeNetworkLocalPort = "network.local.port"; /// - /// Peer address of the network connection - IP address or Unix domain socket name. + /// Peer address of the network connection - IP address or Unix domain socket name /// public const string AttributeNetworkPeerAddress = "network.peer.address"; /// - /// Peer port number of the network connection. + /// Peer port number of the network connection /// public const string AttributeNetworkPeerPort = "network.peer.port"; /// - /// OSI application layer or non-OSI equivalent. + /// OSI application layer or non-OSI equivalent /// /// - /// The value SHOULD be normalized to lowercase. + /// The value SHOULD be normalized to lowercase /// public const string AttributeNetworkProtocolName = "network.protocol.name"; /// - /// The actual version of the protocol used for network communication. + /// The actual version of the protocol used for network communication /// /// - /// If protocol version is subject to negotiation (for example using ALPN), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. + /// If protocol version is subject to negotiation (for example using ALPN), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set /// public const string AttributeNetworkProtocolVersion = "network.protocol.version"; /// - /// OSI transport layer or inter-process communication method. + /// OSI transport layer or inter-process communication method /// /// - /// The value SHOULD be normalized to lowercase.Consider always setting the transport when setting a port number, since - /// a port number is ambiguous without knowing the transport. For example - /// different processes could be listening on TCP port 12345 and UDP port 12345. + /// The value SHOULD be normalized to lowercase. + ///

    + /// Consider always setting the transport when setting a port number, since + /// a port number is ambiguous without knowing the transport. For example + /// different processes could be listening on TCP port 12345 and UDP port 12345 /// public const string AttributeNetworkTransport = "network.transport"; ///

    - /// OSI network layer or non-OSI equivalent. + /// OSI network layer or non-OSI equivalent /// /// - /// The value SHOULD be normalized to lowercase. + /// The value SHOULD be normalized to lowercase /// public const string AttributeNetworkType = "network.type"; /// - /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. + /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection /// public static class NetworkConnectionSubtypeValues { /// - /// GPRS. + /// GPRS /// public const string Gprs = "gprs"; /// - /// EDGE. + /// EDGE /// public const string Edge = "edge"; /// - /// UMTS. + /// UMTS /// public const string Umts = "umts"; /// - /// CDMA. + /// CDMA /// public const string Cdma = "cdma"; /// - /// EVDO Rel. 0. + /// EVDO Rel. 0 /// public const string Evdo0 = "evdo_0"; /// - /// EVDO Rev. A. + /// EVDO Rev. A /// public const string EvdoA = "evdo_a"; /// - /// CDMA2000 1XRTT. + /// CDMA2000 1XRTT /// public const string Cdma20001xrtt = "cdma2000_1xrtt"; /// - /// HSDPA. + /// HSDPA /// public const string Hsdpa = "hsdpa"; /// - /// HSUPA. + /// HSUPA /// public const string Hsupa = "hsupa"; /// - /// HSPA. + /// HSPA /// public const string Hspa = "hspa"; /// - /// IDEN. + /// IDEN /// public const string Iden = "iden"; /// - /// EVDO Rev. B. + /// EVDO Rev. B /// public const string EvdoB = "evdo_b"; /// - /// LTE. + /// LTE /// public const string Lte = "lte"; /// - /// EHRPD. + /// EHRPD /// public const string Ehrpd = "ehrpd"; /// - /// HSPAP. + /// HSPAP /// public const string Hspap = "hspap"; /// - /// GSM. + /// GSM /// public const string Gsm = "gsm"; /// - /// TD-SCDMA. + /// TD-SCDMA /// public const string TdScdma = "td_scdma"; /// - /// IWLAN. + /// IWLAN /// public const string Iwlan = "iwlan"; /// - /// 5G NR (New Radio). + /// 5G NR (New Radio) /// public const string Nr = "nr"; /// - /// 5G NRNSA (New Radio Non-Standalone). + /// 5G NRNSA (New Radio Non-Standalone) /// public const string Nrnsa = "nrnsa"; /// - /// LTE CA. + /// LTE CA /// public const string LteCa = "lte_ca"; } /// - /// The internet connection type. + /// The internet connection type /// public static class NetworkConnectionTypeValues { /// - /// wifi. + /// wifi /// public const string Wifi = "wifi"; /// - /// wired. + /// wired /// public const string Wired = "wired"; /// - /// cell. + /// cell /// public const string Cell = "cell"; /// - /// unavailable. + /// unavailable /// public const string Unavailable = "unavailable"; /// - /// unknown. + /// unknown /// public const string Unknown = "unknown"; } /// - /// The network IO operation direction. + /// The network IO operation direction /// public static class NetworkIoDirectionValues { /// - /// transmit. + /// transmit /// public const string Transmit = "transmit"; /// - /// receive. + /// receive /// public const string Receive = "receive"; } /// - /// OSI transport layer or inter-process communication method. + /// OSI transport layer or inter-process communication method /// public static class NetworkTransportValues { /// - /// TCP. + /// TCP /// public const string Tcp = "tcp"; /// - /// UDP. + /// UDP /// public const string Udp = "udp"; /// - /// Named or anonymous pipe. + /// Named or anonymous pipe /// public const string Pipe = "pipe"; /// - /// Unix domain socket. + /// Unix domain socket /// public const string Unix = "unix"; } /// - /// OSI network layer or non-OSI equivalent. + /// OSI network layer or non-OSI equivalent /// public static class NetworkTypeValues { /// - /// IPv4. + /// IPv4 /// public const string Ipv4 = "ipv4"; /// - /// IPv6. + /// IPv6 /// public const string Ipv6 = "ipv6"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs index 7168299a0e..ca9e010ce8 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,11 +15,11 @@ namespace OpenTelemetry.SemanticConventions; public static class OciAttributes { /// - /// The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. + /// The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known /// /// /// Follows OCI Image Manifest Specification, and specifically the Digest property. - /// An example can be found in Example Image Manifest. + /// An example can be found in Example Image Manifest /// public const string AttributeOciManifestDigest = "oci.manifest.digest"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs index fbad4c94c8..99041c4ea9 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,25 +15,25 @@ namespace OpenTelemetry.SemanticConventions; public static class OpentracingAttributes { /// - /// Parent-child Reference type. + /// Parent-child Reference type /// /// - /// The causal relationship between a child Span and a parent Span. + /// The causal relationship between a child Span and a parent Span /// public const string AttributeOpentracingRefType = "opentracing.ref_type"; /// - /// Parent-child Reference type. + /// Parent-child Reference type /// public static class OpentracingRefTypeValues { /// - /// The parent Span depends on the child Span in some capacity. + /// The parent Span depends on the child Span in some capacity /// public const string ChildOf = "child_of"; /// - /// The parent Span doesn't depend in any way on the result of the child Span. + /// The parent Span doesn't depend in any way on the result of the child Span /// public const string FollowsFrom = "follows_from"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs index fd9e81d555..f5700c4ef3 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,87 +15,87 @@ namespace OpenTelemetry.SemanticConventions; public static class OsAttributes { /// - /// Unique identifier for a particular build or compilation of the operating system. + /// Unique identifier for a particular build or compilation of the operating system /// public const string AttributeOsBuildId = "os.build_id"; /// - /// Human readable (not intended to be parsed) OS version information, like e.g. reported by ver or lsb_release -a commands. + /// Human readable (not intended to be parsed) OS version information, like e.g. reported by ver or lsb_release -a commands /// public const string AttributeOsDescription = "os.description"; /// - /// Human readable operating system name. + /// Human readable operating system name /// public const string AttributeOsName = "os.name"; /// - /// The operating system type. + /// The operating system type /// public const string AttributeOsType = "os.type"; /// - /// The version string of the operating system as defined in Version Attributes. + /// The version string of the operating system as defined in Version Attributes /// public const string AttributeOsVersion = "os.version"; /// - /// The operating system type. + /// The operating system type /// public static class OsTypeValues { /// - /// Microsoft Windows. + /// Microsoft Windows /// public const string Windows = "windows"; /// - /// Linux. + /// Linux /// public const string Linux = "linux"; /// - /// Apple Darwin. + /// Apple Darwin /// public const string Darwin = "darwin"; /// - /// FreeBSD. + /// FreeBSD /// public const string Freebsd = "freebsd"; /// - /// NetBSD. + /// NetBSD /// public const string Netbsd = "netbsd"; /// - /// OpenBSD. + /// OpenBSD /// public const string Openbsd = "openbsd"; /// - /// DragonFly BSD. + /// DragonFly BSD /// public const string Dragonflybsd = "dragonflybsd"; /// - /// HP-UX (Hewlett Packard Unix). + /// HP-UX (Hewlett Packard Unix) /// public const string Hpux = "hpux"; /// - /// AIX (Advanced Interactive eXecutive). + /// AIX (Advanced Interactive eXecutive) /// public const string Aix = "aix"; /// - /// SunOS, Oracle Solaris. + /// SunOS, Oracle Solaris /// public const string Solaris = "solaris"; /// - /// IBM z/OS. + /// IBM z/OS /// public const string ZOs = "z_os"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs index 03c76f69ae..56695acece 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,49 +15,37 @@ namespace OpenTelemetry.SemanticConventions; public static class OtelAttributes { /// - /// None. - /// - [Obsolete("use the `otel.scope.name` attribute")] - public const string AttributeOtelLibraryName = "otel.library.name"; - - /// - /// None. - /// - [Obsolete("use the `otel.scope.version` attribute")] - public const string AttributeOtelLibraryVersion = "otel.library.version"; - - /// - /// The name of the instrumentation scope - (InstrumentationScope.Name in OTLP). + /// The name of the instrumentation scope - (InstrumentationScope.Name in OTLP) /// public const string AttributeOtelScopeName = "otel.scope.name"; /// - /// The version of the instrumentation scope - (InstrumentationScope.Version in OTLP). + /// The version of the instrumentation scope - (InstrumentationScope.Version in OTLP) /// public const string AttributeOtelScopeVersion = "otel.scope.version"; /// - /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET /// public const string AttributeOtelStatusCode = "otel.status_code"; /// - /// Description of the Status if it has a value, otherwise not set. + /// Description of the Status if it has a value, otherwise not set /// public const string AttributeOtelStatusDescription = "otel.status_description"; /// - /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. + /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET /// public static class OtelStatusCodeValues { /// - /// The operation has been validated by an Application developer or Operator to have completed successfully. + /// The operation has been validated by an Application developer or Operator to have completed successfully /// public const string Ok = "OK"; /// - /// The operation contains an error. + /// The operation contains an error /// public const string Error = "ERROR"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs index e489e2a8e0..025f142845 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,23 +15,26 @@ namespace OpenTelemetry.SemanticConventions; public static class OtherAttributes { /// - /// The state of a connection in the pool. + /// Deprecated, use db.client.connections.state instead /// + [Obsolete("Replaced by db.client.connections.state")] public const string AttributeState = "state"; /// - /// The state of a connection in the pool. + /// Deprecated, use db.client.connections.state instead /// public static class StateValues { /// - /// idle. + /// idle /// + [Obsolete("Replaced by db.client.connections.state")] public const string Idle = "idle"; /// - /// used. + /// used /// + [Obsolete("Replaced by db.client.connections.state")] public const string Used = "used"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs index d186722a12..3908588744 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class PeerAttributes { /// - /// The service.name of the remote service. SHOULD be equal to the actual service.name resource attribute of the remote service if any. + /// The service.name of the remote service. SHOULD be equal to the actual service.name resource attribute of the remote service if any /// public const string AttributePeerService = "peer.service"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs index 3e8f9d2dd6..f09530bc5a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,7 +15,8 @@ namespace OpenTelemetry.SemanticConventions; public static class PoolAttributes { /// - /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of server.address and server.port attributes formatted as server.address:server.port. + /// Deprecated, use db.client.connections.pool.name instead /// + [Obsolete("Replaced by db.client.connections.pool.name")] public const string AttributePoolName = "pool.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs index 4c9870fdd6..46c32087eb 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,124 +15,192 @@ namespace OpenTelemetry.SemanticConventions; public static class ProcessAttributes { /// - /// The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in proc/[pid]/cmdline. On Windows, can be set to the first parameter extracted from GetCommandLineW. + /// The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in proc/[pid]/cmdline. On Windows, can be set to the first parameter extracted from GetCommandLineW /// public const string AttributeProcessCommand = "process.command"; /// - /// All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from proc/[pid]/cmdline. For libc-based executables, this would be the full argv vector passed to main. + /// All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from proc/[pid]/cmdline. For libc-based executables, this would be the full argv vector passed to main /// public const string AttributeProcessCommandArgs = "process.command_args"; /// - /// The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of GetCommandLineW. Do not set this if you have to assemble it just for monitoring; use process.command_args instead. + /// The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of GetCommandLineW. Do not set this if you have to assemble it just for monitoring; use process.command_args instead /// public const string AttributeProcessCommandLine = "process.command_line"; /// - /// Specifies whether the context switches for this data point were voluntary or involuntary. + /// Specifies whether the context switches for this data point were voluntary or involuntary /// public const string AttributeProcessContextSwitchType = "process.context_switch_type"; /// - /// The CPU state for this data point. A process SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// The CPU state of the process /// public const string AttributeProcessCpuState = "process.cpu.state"; /// - /// The name of the process executable. On Linux based systems, can be set to the Name in proc/[pid]/status. On Windows, can be set to the base name of GetProcessImageFileNameW. + /// The date and time the process was created, in ISO 8601 format + /// + public const string AttributeProcessCreationTime = "process.creation.time"; + + /// + /// The name of the process executable. On Linux based systems, can be set to the Name in proc/[pid]/status. On Windows, can be set to the base name of GetProcessImageFileNameW /// public const string AttributeProcessExecutableName = "process.executable.name"; /// - /// The full path to the process executable. On Linux based systems, can be set to the target of proc/[pid]/exe. On Windows, can be set to the result of GetProcessImageFileNameW. + /// The full path to the process executable. On Linux based systems, can be set to the target of proc/[pid]/exe. On Windows, can be set to the result of GetProcessImageFileNameW /// public const string AttributeProcessExecutablePath = "process.executable.path"; /// - /// The username of the user that owns the process. + /// The exit code of the process + /// + public const string AttributeProcessExitCode = "process.exit.code"; + + /// + /// The date and time the process exited, in ISO 8601 format + /// + public const string AttributeProcessExitTime = "process.exit.time"; + + /// + /// The PID of the process's group leader. This is also the process group ID (PGID) of the process + /// + public const string AttributeProcessGroupLeaderPid = "process.group_leader.pid"; + + /// + /// Whether the process is connected to an interactive shell + /// + public const string AttributeProcessInteractive = "process.interactive"; + + /// + /// The username of the user that owns the process /// public const string AttributeProcessOwner = "process.owner"; /// - /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults. + /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults /// public const string AttributeProcessPagingFaultType = "process.paging.fault_type"; /// - /// Parent Process identifier (PPID). + /// Parent Process identifier (PPID) /// public const string AttributeProcessParentPid = "process.parent_pid"; /// - /// Process identifier (PID). + /// Process identifier (PID) /// public const string AttributeProcessPid = "process.pid"; /// - /// An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. + /// The real user ID (RUID) of the process + /// + public const string AttributeProcessRealUserId = "process.real_user.id"; + + /// + /// The username of the real user of the process + /// + public const string AttributeProcessRealUserName = "process.real_user.name"; + + /// + /// An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment /// public const string AttributeProcessRuntimeDescription = "process.runtime.description"; /// - /// The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler. + /// The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler /// public const string AttributeProcessRuntimeName = "process.runtime.name"; /// - /// The version of the runtime of this process, as returned by the runtime without modification. + /// The version of the runtime of this process, as returned by the runtime without modification /// public const string AttributeProcessRuntimeVersion = "process.runtime.version"; /// - /// Specifies whether the context switches for this data point were voluntary or involuntary. + /// The saved user ID (SUID) of the process + /// + public const string AttributeProcessSavedUserId = "process.saved_user.id"; + + /// + /// The username of the saved user + /// + public const string AttributeProcessSavedUserName = "process.saved_user.name"; + + /// + /// The PID of the process's session leader. This is also the session ID (SID) of the process + /// + public const string AttributeProcessSessionLeaderPid = "process.session_leader.pid"; + + /// + /// The effective user ID (EUID) of the process + /// + public const string AttributeProcessUserId = "process.user.id"; + + /// + /// The username of the effective user of the process + /// + public const string AttributeProcessUserName = "process.user.name"; + + /// + /// Virtual process identifier + /// + /// + /// The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within + /// + public const string AttributeProcessVpid = "process.vpid"; + + /// + /// Specifies whether the context switches for this data point were voluntary or involuntary /// public static class ProcessContextSwitchTypeValues { /// - /// voluntary. + /// voluntary /// public const string Voluntary = "voluntary"; /// - /// involuntary. + /// involuntary /// public const string Involuntary = "involuntary"; } /// - /// The CPU state for this data point. A process SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// The CPU state of the process /// public static class ProcessCpuStateValues { /// - /// system. + /// system /// public const string System = "system"; /// - /// user. + /// user /// public const string User = "user"; /// - /// wait. + /// wait /// public const string Wait = "wait"; } /// - /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults. + /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults /// public static class ProcessPagingFaultTypeValues { /// - /// major. + /// major /// public const string Major = "major"; /// - /// minor. + /// minor /// public const string Minor = "minor"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs index 40f96ac2f9..2757fdb910 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,292 +15,331 @@ namespace OpenTelemetry.SemanticConventions; public static class RpcAttributes { /// - /// The error codes of the Connect request. Error codes are always string values. + /// The error codes of the Connect request. Error codes are always string values /// public const string AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code"; /// - /// Connect request metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values. + /// Connect request metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information /// - public const string AttributeRpcConnectRpcRequestMetadata = "rpc.connect_rpc.request.metadata"; + public const string AttributeRpcConnectRpcRequestMetadataTemplate = "rpc.connect_rpc.request.metadata"; /// - /// Connect response metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values. + /// Connect response metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information /// - public const string AttributeRpcConnectRpcResponseMetadata = "rpc.connect_rpc.response.metadata"; + public const string AttributeRpcConnectRpcResponseMetadataTemplate = "rpc.connect_rpc.response.metadata"; /// - /// gRPC request metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values. + /// gRPC request metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information /// - public const string AttributeRpcGrpcRequestMetadata = "rpc.grpc.request.metadata"; + public const string AttributeRpcGrpcRequestMetadataTemplate = "rpc.grpc.request.metadata"; /// - /// gRPC response metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values. + /// gRPC response metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information /// - public const string AttributeRpcGrpcResponseMetadata = "rpc.grpc.response.metadata"; + public const string AttributeRpcGrpcResponseMetadataTemplate = "rpc.grpc.response.metadata"; /// - /// The numeric status code of the gRPC request. + /// The numeric status code of the gRPC request /// public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; /// - /// error.code property of response if it is an error response. + /// error.code property of response if it is an error response /// public const string AttributeRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code"; /// - /// error.message property of response if it is an error response. + /// error.message property of response if it is an error response /// public const string AttributeRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message"; /// - /// id property of request or response. Since protocol allows id to be int, string, null or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of null value. Omit entirely if this is a notification. + /// id property of request or response. Since protocol allows id to be int, string, null or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of null value. Omit entirely if this is a notification /// public const string AttributeRpcJsonrpcRequestId = "rpc.jsonrpc.request_id"; /// - /// Protocol version as in jsonrpc property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. + /// Protocol version as in jsonrpc property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted /// public const string AttributeRpcJsonrpcVersion = "rpc.jsonrpc.version"; /// - /// The name of the (logical) method being called, must be equal to the $method part in the span name. + /// Compressed size of the message in bytes + /// + public const string AttributeRpcMessageCompressedSize = "rpc.message.compressed_size"; + + /// + /// MUST be calculated as two different counters starting from 1 one for sent messages and one for received message + /// + /// + /// This way we guarantee that the values will be consistent between different implementations + /// + public const string AttributeRpcMessageId = "rpc.message.id"; + + /// + /// Whether this is a received or sent message + /// + public const string AttributeRpcMessageType = "rpc.message.type"; + + /// + /// Uncompressed size of the message in bytes + /// + public const string AttributeRpcMessageUncompressedSize = "rpc.message.uncompressed_size"; + + /// + /// The name of the (logical) method being called, must be equal to the $method part in the span name /// /// - /// This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The code.function attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). + /// This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The code.function attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side) /// public const string AttributeRpcMethod = "rpc.method"; /// - /// The full (logical) name of the service being called, including its package name, if applicable. + /// The full (logical) name of the service being called, including its package name, if applicable /// /// - /// This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The code.namespace attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). + /// This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The code.namespace attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side) /// public const string AttributeRpcService = "rpc.service"; /// - /// A string identifying the remoting system. See below for a list of well-known identifiers. + /// A string identifying the remoting system. See below for a list of well-known identifiers /// public const string AttributeRpcSystem = "rpc.system"; /// - /// The error codes of the Connect request. Error codes are always string values. + /// The error codes of the Connect request. Error codes are always string values /// public static class RpcConnectRpcErrorCodeValues { /// - /// cancelled. + /// cancelled /// public const string Cancelled = "cancelled"; /// - /// unknown. + /// unknown /// public const string Unknown = "unknown"; /// - /// invalid_argument. + /// invalid_argument /// public const string InvalidArgument = "invalid_argument"; /// - /// deadline_exceeded. + /// deadline_exceeded /// public const string DeadlineExceeded = "deadline_exceeded"; /// - /// not_found. + /// not_found /// public const string NotFound = "not_found"; /// - /// already_exists. + /// already_exists /// public const string AlreadyExists = "already_exists"; /// - /// permission_denied. + /// permission_denied /// public const string PermissionDenied = "permission_denied"; /// - /// resource_exhausted. + /// resource_exhausted /// public const string ResourceExhausted = "resource_exhausted"; /// - /// failed_precondition. + /// failed_precondition /// public const string FailedPrecondition = "failed_precondition"; /// - /// aborted. + /// aborted /// public const string Aborted = "aborted"; /// - /// out_of_range. + /// out_of_range /// public const string OutOfRange = "out_of_range"; /// - /// unimplemented. + /// unimplemented /// public const string Unimplemented = "unimplemented"; /// - /// internal. + /// internal /// public const string Internal = "internal"; /// - /// unavailable. + /// unavailable /// public const string Unavailable = "unavailable"; /// - /// data_loss. + /// data_loss /// public const string DataLoss = "data_loss"; /// - /// unauthenticated. + /// unauthenticated /// public const string Unauthenticated = "unauthenticated"; } /// - /// The numeric status code of the gRPC request. + /// The numeric status code of the gRPC request /// public static class RpcGrpcStatusCodeValues { /// - /// OK. + /// OK /// public const int Ok = 0; /// - /// CANCELLED. + /// CANCELLED /// public const int Cancelled = 1; /// - /// UNKNOWN. + /// UNKNOWN /// public const int Unknown = 2; /// - /// INVALID_ARGUMENT. + /// INVALID_ARGUMENT /// public const int InvalidArgument = 3; /// - /// DEADLINE_EXCEEDED. + /// DEADLINE_EXCEEDED /// public const int DeadlineExceeded = 4; /// - /// NOT_FOUND. + /// NOT_FOUND /// public const int NotFound = 5; /// - /// ALREADY_EXISTS. + /// ALREADY_EXISTS /// public const int AlreadyExists = 6; /// - /// PERMISSION_DENIED. + /// PERMISSION_DENIED /// public const int PermissionDenied = 7; /// - /// RESOURCE_EXHAUSTED. + /// RESOURCE_EXHAUSTED /// public const int ResourceExhausted = 8; /// - /// FAILED_PRECONDITION. + /// FAILED_PRECONDITION /// public const int FailedPrecondition = 9; /// - /// ABORTED. + /// ABORTED /// public const int Aborted = 10; /// - /// OUT_OF_RANGE. + /// OUT_OF_RANGE /// public const int OutOfRange = 11; /// - /// UNIMPLEMENTED. + /// UNIMPLEMENTED /// public const int Unimplemented = 12; /// - /// INTERNAL. + /// INTERNAL /// public const int Internal = 13; /// - /// UNAVAILABLE. + /// UNAVAILABLE /// public const int Unavailable = 14; /// - /// DATA_LOSS. + /// DATA_LOSS /// public const int DataLoss = 15; /// - /// UNAUTHENTICATED. + /// UNAUTHENTICATED /// public const int Unauthenticated = 16; } /// - /// A string identifying the remoting system. See below for a list of well-known identifiers. + /// Whether this is a received or sent message + /// + public static class RpcMessageTypeValues + { + /// + /// sent + /// + public const string Sent = "SENT"; + + /// + /// received + /// + public const string Received = "RECEIVED"; + } + + /// + /// A string identifying the remoting system. See below for a list of well-known identifiers /// public static class RpcSystemValues { /// - /// gRPC. + /// gRPC /// public const string Grpc = "grpc"; /// - /// Java RMI. + /// Java RMI /// public const string JavaRmi = "java_rmi"; /// - /// .NET WCF. + /// .NET WCF /// public const string DotnetWcf = "dotnet_wcf"; /// - /// Apache Dubbo. + /// Apache Dubbo /// public const string ApacheDubbo = "apache_dubbo"; /// - /// Connect RPC. + /// Connect RPC /// public const string ConnectRpc = "connect_rpc"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs index b31282b237..75ecf5f8af 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,18 +15,18 @@ namespace OpenTelemetry.SemanticConventions; public static class ServerAttributes { /// - /// Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name /// /// - /// When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it&#39;s available. + /// When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it's available /// public const string AttributeServerAddress = "server.address"; /// - /// Server port number. + /// Server port number /// /// - /// When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it&#39;s available. + /// When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it's available /// public const string AttributeServerPort = "server.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs index b2dfc48164..2d1352ef80 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,48 +15,56 @@ namespace OpenTelemetry.SemanticConventions; public static class ServiceAttributes { /// - /// The string ID of the service instance. + /// The string ID of the service instance /// /// /// MUST be unique for each instance of the same service.namespace,service.name pair (in other words - /// service.namespace,service.name,service.instance.id triplet MUST be globally unique). The ID helps to - /// distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled - /// service).Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 RFC - /// 4122 UUID, but are free to use an inherent unique ID as the source of - /// this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and - /// SHOULD use the following UUID as the namespace: 4d63009a-8d0f-11ee-aad7-4c796ed8e320.UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is - /// needed. Similar to what can be seen in the man page for the - /// /etc/machine-id file, the underlying - /// data, such as pod name and namespace should be treated as confidential, being the user&#39;s choice to expose it - /// or not via another resource attribute.For applications running behind an application server (like unicorn), we do not recommend using one identifier - /// for all processes participating in the application. Instead, it&#39;s recommended each division (e.g. a worker - /// thread in unicorn) to have its own instance.id.It&#39;s not recommended for a Collector to set service.instance.id if it can&#39;t unambiguously determine the - /// service instance that is generating that telemetry. For instance, creating an UUID based on pod.name will - /// likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. - /// However, Collectors can set the service.instance.id if they can unambiguously determine the service instance - /// for that telemetry. This is typically the case for scraping receivers, as they know the target address and - /// port. + /// service.namespace,service.name,service.instance.id triplet MUST be globally unique). The ID helps to + /// distinguish instances of the same service that exist at the same time (e.g. instances of a horizontally scaled + /// service). + ///

    + /// Implementations, such as SDKs, are recommended to generate a random Version 1 or Version 4 RFC + /// 4122 UUID, but are free to use an inherent unique ID as the source of + /// this value if stability is desirable. In that case, the ID SHOULD be used as source of a UUID Version 5 and + /// SHOULD use the following UUID as the namespace: 4d63009a-8d0f-11ee-aad7-4c796ed8e320. + ///

    + /// UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is + /// needed. Similar to what can be seen in the man page for the + /// /etc/machine-id file, the underlying + /// data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it + /// or not via another resource attribute. + ///

    + /// For applications running behind an application server (like unicorn), we do not recommend using one identifier + /// for all processes participating in the application. Instead, it's recommended each division (e.g. a worker + /// thread in unicorn) to have its own instance.id. + ///

    + /// It's not recommended for a Collector to set service.instance.id if it can't unambiguously determine the + /// service instance that is generating that telemetry. For instance, creating an UUID based on pod.name will + /// likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. + /// However, Collectors can set the service.instance.id if they can unambiguously determine the service instance + /// for that telemetry. This is typically the case for scraping receivers, as they know the target address and + /// port /// public const string AttributeServiceInstanceId = "service.instance.id"; ///

    - /// Logical name of the service. + /// Logical name of the service /// /// - /// MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to unknown_service: concatenated with process.executable.name, e.g. unknown_service:bash. If process.executable.name is not available, the value MUST be set to unknown_service. + /// MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to unknown_service: concatenated with process.executable.name, e.g. unknown_service:bash. If process.executable.name is not available, the value MUST be set to unknown_service /// public const string AttributeServiceName = "service.name"; /// - /// A namespace for service.name. + /// A namespace for service.name /// /// - /// A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. service.name is expected to be unique within the same namespace. If service.namespace is not specified in the Resource then service.name is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. + /// A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. service.name is expected to be unique within the same namespace. If service.namespace is not specified in the Resource then service.name is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace /// public const string AttributeServiceNamespace = "service.namespace"; /// - /// The version string of the service API or implementation. The format is not defined by these conventions. + /// The version string of the service API or implementation. The format is not defined by these conventions /// public const string AttributeServiceVersion = "service.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs index 7f6ff71fdb..ed3c893b3f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,12 +15,12 @@ namespace OpenTelemetry.SemanticConventions; public static class SessionAttributes { /// - /// A unique id to identify a session. + /// A unique id to identify a session /// public const string AttributeSessionId = "session.id"; /// - /// The previous session.id for this user, when known. + /// The previous session.id for this user, when known /// public const string AttributeSessionPreviousId = "session.previous_id"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs index dd937d7004..1940defe58 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,53 +15,53 @@ namespace OpenTelemetry.SemanticConventions; public static class SignalrAttributes { /// - /// SignalR HTTP connection closure status. + /// SignalR HTTP connection closure status /// public const string AttributeSignalrConnectionStatus = "signalr.connection.status"; /// - /// SignalR transport type. + /// SignalR transport type /// public const string AttributeSignalrTransport = "signalr.transport"; /// - /// SignalR HTTP connection closure status. + /// SignalR HTTP connection closure status /// public static class SignalrConnectionStatusValues { /// - /// The connection was closed normally. + /// The connection was closed normally /// public const string NormalClosure = "normal_closure"; /// - /// The connection was closed due to a timeout. + /// The connection was closed due to a timeout /// public const string Timeout = "timeout"; /// - /// The connection was closed because the app is shutting down. + /// The connection was closed because the app is shutting down /// public const string AppShutdown = "app_shutdown"; } /// - /// SignalR transport type. + /// SignalR transport type /// public static class SignalrTransportValues { /// - /// ServerSentEvents protocol. + /// ServerSentEvents protocol /// public const string ServerSentEvents = "server_sent_events"; /// - /// LongPolling protocol. + /// LongPolling protocol /// public const string LongPolling = "long_polling"; /// - /// WebSockets protocol. + /// WebSockets protocol /// public const string WebSockets = "web_sockets"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs index 5c24ee0440..d64f93a789 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,15 +15,15 @@ namespace OpenTelemetry.SemanticConventions; public static class SourceAttributes { /// - /// Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + /// Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name /// /// - /// When observed from the destination side, and when communicating through an intermediary, source.address SHOULD represent the source address behind any intermediaries, for example proxies, if it&#39;s available. + /// When observed from the destination side, and when communicating through an intermediary, source.address SHOULD represent the source address behind any intermediaries, for example proxies, if it's available /// public const string AttributeSourceAddress = "source.address"; /// - /// Source port number. + /// Source port number /// public const string AttributeSourcePort = "source.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs index 3270d58b22..d16c46b2e5 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,368 +15,372 @@ namespace OpenTelemetry.SemanticConventions; public static class SystemAttributes { /// - /// The logical CPU number [0..n-1]. + /// The logical CPU number [0..n-1] /// public const string AttributeSystemCpuLogicalNumber = "system.cpu.logical_number"; /// - /// The CPU state for this data point. A system's CPU SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// The state of the CPU /// public const string AttributeSystemCpuState = "system.cpu.state"; /// - /// The device identifier. + /// The device identifier /// public const string AttributeSystemDevice = "system.device"; /// - /// The filesystem mode. + /// The filesystem mode /// public const string AttributeSystemFilesystemMode = "system.filesystem.mode"; /// - /// The filesystem mount path. + /// The filesystem mount path /// public const string AttributeSystemFilesystemMountpoint = "system.filesystem.mountpoint"; /// - /// The filesystem state. + /// The filesystem state /// public const string AttributeSystemFilesystemState = "system.filesystem.state"; /// - /// The filesystem type. + /// The filesystem type /// public const string AttributeSystemFilesystemType = "system.filesystem.type"; /// - /// The memory state. + /// The memory state /// public const string AttributeSystemMemoryState = "system.memory.state"; /// - /// A stateless protocol MUST NOT set this attribute. + /// A stateless protocol MUST NOT set this attribute /// public const string AttributeSystemNetworkState = "system.network.state"; /// - /// The paging access direction. + /// The paging access direction /// public const string AttributeSystemPagingDirection = "system.paging.direction"; /// - /// The memory paging state. + /// The memory paging state /// public const string AttributeSystemPagingState = "system.paging.state"; /// - /// The memory paging type. + /// The memory paging type /// public const string AttributeSystemPagingType = "system.paging.type"; /// - /// The process state, e.g., Linux Process State Codes. + /// The process state, e.g., Linux Process State Codes /// public const string AttributeSystemProcessStatus = "system.process.status"; /// - /// Deprecated, use system.process.status instead. + /// Deprecated, use system.process.status instead /// - [Obsolete("Replaced by `system.process.status`")] + [Obsolete("Replaced by system.process.status")] public const string AttributeSystemProcessesStatus = "system.processes.status"; /// - /// The CPU state for this data point. A system's CPU SHOULD be characterized either by data points with no state labels, or only data points with state labels. + /// The state of the CPU /// public static class SystemCpuStateValues { /// - /// user. + /// user /// public const string User = "user"; /// - /// system. + /// system /// public const string System = "system"; /// - /// nice. + /// nice /// public const string Nice = "nice"; /// - /// idle. + /// idle /// public const string Idle = "idle"; /// - /// iowait. + /// iowait /// public const string Iowait = "iowait"; /// - /// interrupt. + /// interrupt /// public const string Interrupt = "interrupt"; /// - /// steal. + /// steal /// public const string Steal = "steal"; } /// - /// The filesystem state. + /// The filesystem state /// public static class SystemFilesystemStateValues { /// - /// used. + /// used /// public const string Used = "used"; /// - /// free. + /// free /// public const string Free = "free"; /// - /// reserved. + /// reserved /// public const string Reserved = "reserved"; } /// - /// The filesystem type. + /// The filesystem type /// public static class SystemFilesystemTypeValues { /// - /// fat32. + /// fat32 /// public const string Fat32 = "fat32"; /// - /// exfat. + /// exfat /// public const string Exfat = "exfat"; /// - /// ntfs. + /// ntfs /// public const string Ntfs = "ntfs"; /// - /// refs. + /// refs /// public const string Refs = "refs"; /// - /// hfsplus. + /// hfsplus /// public const string Hfsplus = "hfsplus"; /// - /// ext4. + /// ext4 /// public const string Ext4 = "ext4"; } /// - /// The memory state. + /// The memory state /// public static class SystemMemoryStateValues { /// - /// used. + /// used /// public const string Used = "used"; /// - /// free. + /// free /// public const string Free = "free"; /// - /// shared. + /// shared /// public const string Shared = "shared"; /// - /// buffers. + /// buffers /// public const string Buffers = "buffers"; /// - /// cached. + /// cached /// public const string Cached = "cached"; } /// - /// A stateless protocol MUST NOT set this attribute. + /// A stateless protocol MUST NOT set this attribute /// public static class SystemNetworkStateValues { /// - /// close. + /// close /// public const string Close = "close"; /// - /// close_wait. + /// close_wait /// public const string CloseWait = "close_wait"; /// - /// closing. + /// closing /// public const string Closing = "closing"; /// - /// delete. + /// delete /// public const string Delete = "delete"; /// - /// established. + /// established /// public const string Established = "established"; /// - /// fin_wait_1. + /// fin_wait_1 /// public const string FinWait1 = "fin_wait_1"; /// - /// fin_wait_2. + /// fin_wait_2 /// public const string FinWait2 = "fin_wait_2"; /// - /// last_ack. + /// last_ack /// public const string LastAck = "last_ack"; /// - /// listen. + /// listen /// public const string Listen = "listen"; /// - /// syn_recv. + /// syn_recv /// public const string SynRecv = "syn_recv"; /// - /// syn_sent. + /// syn_sent /// public const string SynSent = "syn_sent"; /// - /// time_wait. + /// time_wait /// public const string TimeWait = "time_wait"; } /// - /// The paging access direction. + /// The paging access direction /// public static class SystemPagingDirectionValues { /// - /// in. + /// in /// public const string In = "in"; /// - /// out. + /// out /// public const string Out = "out"; } /// - /// The memory paging state. + /// The memory paging state /// public static class SystemPagingStateValues { /// - /// used. + /// used /// public const string Used = "used"; /// - /// free. + /// free /// public const string Free = "free"; } /// - /// The memory paging type. + /// The memory paging type /// public static class SystemPagingTypeValues { /// - /// major. + /// major /// public const string Major = "major"; /// - /// minor. + /// minor /// public const string Minor = "minor"; } /// - /// The process state, e.g., Linux Process State Codes. + /// The process state, e.g., Linux Process State Codes /// public static class SystemProcessStatusValues { /// - /// running. + /// running /// public const string Running = "running"; /// - /// sleeping. + /// sleeping /// public const string Sleeping = "sleeping"; /// - /// stopped. + /// stopped /// public const string Stopped = "stopped"; /// - /// defunct. + /// defunct /// public const string Defunct = "defunct"; } /// - /// Deprecated, use system.process.status instead. + /// Deprecated, use system.process.status instead /// public static class SystemProcessesStatusValues { /// - /// running. + /// running /// + [Obsolete("Replaced by system.process.status")] public const string Running = "running"; /// - /// sleeping. + /// sleeping /// + [Obsolete("Replaced by system.process.status")] public const string Sleeping = "sleeping"; /// - /// stopped. + /// stopped /// + [Obsolete("Replaced by system.process.status")] public const string Stopped = "stopped"; /// - /// defunct. + /// defunct /// + [Obsolete("Replaced by system.process.status")] public const string Defunct = "defunct"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs index f08ca9fd85..300181e4fd 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,104 +15,104 @@ namespace OpenTelemetry.SemanticConventions; public static class TelemetryAttributes { /// - /// The name of the auto instrumentation agent or distribution, if used. + /// The name of the auto instrumentation agent or distribution, if used /// /// /// Official auto instrumentation agents and distributions SHOULD set the telemetry.distro.name attribute to - /// a string starting with opentelemetry-, e.g. opentelemetry-java-instrumentation. + /// a string starting with opentelemetry-, e.g. opentelemetry-java-instrumentation /// public const string AttributeTelemetryDistroName = "telemetry.distro.name"; /// - /// The version string of the auto instrumentation agent or distribution, if used. + /// The version string of the auto instrumentation agent or distribution, if used /// public const string AttributeTelemetryDistroVersion = "telemetry.distro.version"; /// - /// The language of the telemetry SDK. + /// The language of the telemetry SDK /// public const string AttributeTelemetrySdkLanguage = "telemetry.sdk.language"; /// - /// The name of the telemetry SDK as defined above. + /// The name of the telemetry SDK as defined above /// /// /// The OpenTelemetry SDK MUST set the telemetry.sdk.name attribute to opentelemetry. - /// If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the - /// telemetry.sdk.name attribute to the fully-qualified class or module name of this SDK&#39;s main entry point - /// or another suitable identifier depending on the language. - /// The identifier opentelemetry is reserved and MUST NOT be used in this case. - /// All custom identifiers SHOULD be stable across different versions of an implementation. + /// If another SDK, like a fork or a vendor-provided implementation, is used, this SDK MUST set the + /// telemetry.sdk.name attribute to the fully-qualified class or module name of this SDK's main entry point + /// or another suitable identifier depending on the language. + /// The identifier opentelemetry is reserved and MUST NOT be used in this case. + /// All custom identifiers SHOULD be stable across different versions of an implementation /// public const string AttributeTelemetrySdkName = "telemetry.sdk.name"; /// - /// The version string of the telemetry SDK. + /// The version string of the telemetry SDK /// public const string AttributeTelemetrySdkVersion = "telemetry.sdk.version"; /// - /// The language of the telemetry SDK. + /// The language of the telemetry SDK /// public static class TelemetrySdkLanguageValues { /// - /// cpp. + /// cpp /// public const string Cpp = "cpp"; /// - /// dotnet. + /// dotnet /// public const string Dotnet = "dotnet"; /// - /// erlang. + /// erlang /// public const string Erlang = "erlang"; /// - /// go. + /// go /// public const string Go = "go"; /// - /// java. + /// java /// public const string Java = "java"; /// - /// nodejs. + /// nodejs /// public const string Nodejs = "nodejs"; /// - /// php. + /// php /// public const string Php = "php"; /// - /// python. + /// python /// public const string Python = "python"; /// - /// ruby. + /// ruby /// public const string Ruby = "ruby"; /// - /// rust. + /// rust /// public const string Rust = "rust"; /// - /// swift. + /// swift /// public const string Swift = "swift"; /// - /// webjs. + /// webjs /// public const string Webjs = "webjs"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs index 82eb2c18ee..525597810c 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,12 +15,12 @@ namespace OpenTelemetry.SemanticConventions; public static class ThreadAttributes { /// - /// Current "managed" thread ID (as opposed to OS thread ID). + /// Current "managed" thread ID (as opposed to OS thread ID) /// public const string AttributeThreadId = "thread.id"; /// - /// Current thread name. + /// Current thread name /// public const string AttributeThreadName = "thread.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs index fbcac49fea..5d1d75a9ce 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,165 +15,165 @@ namespace OpenTelemetry.SemanticConventions; public static class TlsAttributes { /// - /// String indicating the cipher used during the current connection. + /// String indicating the cipher used during the current connection /// /// - /// The values allowed for tls.cipher MUST be one of the Descriptions of the registered TLS Cipher Suits. + /// The values allowed for tls.cipher MUST be one of the Descriptions of the registered TLS Cipher Suits /// public const string AttributeTlsCipher = "tls.cipher"; /// - /// PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of client.certificate_chain since this value also exists in that list. + /// PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of client.certificate_chain since this value also exists in that list /// public const string AttributeTlsClientCertificate = "tls.client.certificate"; /// - /// Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of client.certificate since that value should be the first certificate in the chain. + /// Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of client.certificate since that value should be the first certificate in the chain /// public const string AttributeTlsClientCertificateChain = "tls.client.certificate_chain"; /// - /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash /// public const string AttributeTlsClientHashMd5 = "tls.client.hash.md5"; /// - /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash /// public const string AttributeTlsClientHashSha1 = "tls.client.hash.sha1"; /// - /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash /// public const string AttributeTlsClientHashSha256 = "tls.client.hash.sha256"; /// - /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client. + /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client /// public const string AttributeTlsClientIssuer = "tls.client.issuer"; /// - /// A hash that identifies clients based on how they perform an SSL/TLS handshake. + /// A hash that identifies clients based on how they perform an SSL/TLS handshake /// public const string AttributeTlsClientJa3 = "tls.client.ja3"; /// - /// Date/Time indicating when client certificate is no longer considered valid. + /// Date/Time indicating when client certificate is no longer considered valid /// public const string AttributeTlsClientNotAfter = "tls.client.not_after"; /// - /// Date/Time indicating when client certificate is first considered valid. + /// Date/Time indicating when client certificate is first considered valid /// public const string AttributeTlsClientNotBefore = "tls.client.not_before"; /// - /// Also called an SNI, this tells the server which hostname to which the client is attempting to connect to. + /// Also called an SNI, this tells the server which hostname to which the client is attempting to connect to /// public const string AttributeTlsClientServerName = "tls.client.server_name"; /// - /// Distinguished name of subject of the x.509 certificate presented by the client. + /// Distinguished name of subject of the x.509 certificate presented by the client /// public const string AttributeTlsClientSubject = "tls.client.subject"; /// - /// Array of ciphers offered by the client during the client hello. + /// Array of ciphers offered by the client during the client hello /// public const string AttributeTlsClientSupportedCiphers = "tls.client.supported_ciphers"; /// - /// String indicating the curve used for the given cipher, when applicable. + /// String indicating the curve used for the given cipher, when applicable /// public const string AttributeTlsCurve = "tls.curve"; /// - /// Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. + /// Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel /// public const string AttributeTlsEstablished = "tls.established"; /// - /// String indicating the protocol being tunneled. Per the values in the IANA registry, this string should be lower case. + /// String indicating the protocol being tunneled. Per the values in the IANA registry, this string should be lower case /// public const string AttributeTlsNextProtocol = "tls.next_protocol"; /// - /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version. + /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version /// public const string AttributeTlsProtocolName = "tls.protocol.name"; /// - /// Numeric part of the version parsed from the original string of the negotiated SSL/TLS protocol version. + /// Numeric part of the version parsed from the original string of the negotiated SSL/TLS protocol version /// public const string AttributeTlsProtocolVersion = "tls.protocol.version"; /// - /// Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. + /// Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation /// public const string AttributeTlsResumed = "tls.resumed"; /// - /// PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of server.certificate_chain since this value also exists in that list. + /// PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of server.certificate_chain since this value also exists in that list /// public const string AttributeTlsServerCertificate = "tls.server.certificate"; /// - /// Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of server.certificate since that value should be the first certificate in the chain. + /// Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of server.certificate since that value should be the first certificate in the chain /// public const string AttributeTlsServerCertificateChain = "tls.server.certificate_chain"; /// - /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash /// public const string AttributeTlsServerHashMd5 = "tls.server.hash.md5"; /// - /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash /// public const string AttributeTlsServerHashSha1 = "tls.server.hash.sha1"; /// - /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. + /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash /// public const string AttributeTlsServerHashSha256 = "tls.server.hash.sha256"; /// - /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client. + /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client /// public const string AttributeTlsServerIssuer = "tls.server.issuer"; /// - /// A hash that identifies servers based on how they perform an SSL/TLS handshake. + /// A hash that identifies servers based on how they perform an SSL/TLS handshake /// public const string AttributeTlsServerJa3s = "tls.server.ja3s"; /// - /// Date/Time indicating when server certificate is no longer considered valid. + /// Date/Time indicating when server certificate is no longer considered valid /// public const string AttributeTlsServerNotAfter = "tls.server.not_after"; /// - /// Date/Time indicating when server certificate is first considered valid. + /// Date/Time indicating when server certificate is first considered valid /// public const string AttributeTlsServerNotBefore = "tls.server.not_before"; /// - /// Distinguished name of subject of the x.509 certificate presented by the server. + /// Distinguished name of subject of the x.509 certificate presented by the server /// public const string AttributeTlsServerSubject = "tls.server.subject"; /// - /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version. + /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version /// public static class TlsProtocolNameValues { /// - /// ssl. + /// ssl /// public const string Ssl = "ssl"; /// - /// tls. + /// tls /// public const string Tls = "tls"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs index 7471d882e5..47fba2eb6e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,92 +15,97 @@ namespace OpenTelemetry.SemanticConventions; public static class UrlAttributes { /// - /// Domain extracted from the url.full, such as "opentelemetry.io". + /// Domain extracted from the url.full, such as "opentelemetry.io" /// /// - /// In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a literal IPv6 address enclosed by [ and ], the [ and ] characters should also be captured in the domain field. + /// In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a literal IPv6 address enclosed by [ and ], the [ and ] characters should also be captured in the domain field /// public const string AttributeUrlDomain = "url.domain"; /// - /// The file extension extracted from the url.full, excluding the leading dot. + /// The file extension extracted from the url.full, excluding the leading dot /// /// - /// The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions example.tar.gz, only the last one should be captured gz, not tar.gz. + /// The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions example.tar.gz, only the last one should be captured gz, not tar.gz /// public const string AttributeUrlExtension = "url.extension"; /// - /// The URI fragment component. + /// The URI fragment component /// public const string AttributeUrlFragment = "url.fragment"; /// - /// Absolute URL describing a network resource according to RFC3986. + /// Absolute URL describing a network resource according to RFC3986 /// /// /// For network calls, URL usually has scheme://host[:port][path][?query][#fragment] format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. - /// url.full MUST NOT contain credentials passed via URL in form of https://username:password@www.example.com/. In such case username and password SHOULD be redacted and attribute&#39;s value SHOULD be https://REDACTED:REDACTED@www.example.com/. - /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it. + /// url.full MUST NOT contain credentials passed via URL in form of https://username:password@www.example.com/. In such case username and password SHOULD be redacted and attribute's value SHOULD be https://REDACTED:REDACTED@www.example.com/. + /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it /// public const string AttributeUrlFull = "url.full"; /// - /// Unmodified original URL as seen in the event source. + /// Unmodified original URL as seen in the event source /// /// /// In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. - /// url.original might contain credentials passed via URL in form of https://username:password@www.example.com/. In such case password and username SHOULD NOT be redacted and attribute&#39;s value SHOULD remain the same. + /// url.original might contain credentials passed via URL in form of https://username:password@www.example.com/. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same /// public const string AttributeUrlOriginal = "url.original"; /// - /// The URI path component. + /// The URI path component /// /// - /// Sensitive content provided in url.path SHOULD be scrubbed when instrumentations can identify it. + /// Sensitive content provided in url.path SHOULD be scrubbed when instrumentations can identify it /// public const string AttributeUrlPath = "url.path"; /// - /// Port extracted from the url.full. + /// Port extracted from the url.full /// public const string AttributeUrlPort = "url.port"; /// - /// The URI query component. + /// The URI query component /// /// - /// Sensitive content provided in url.query SHOULD be scrubbed when instrumentations can identify it. + /// Sensitive content provided in url.query SHOULD be scrubbed when instrumentations can identify it /// public const string AttributeUrlQuery = "url.query"; /// - /// The highest registered url domain, stripped of the subdomain. + /// The highest registered url domain, stripped of the subdomain /// /// - /// This value can be determined precisely with the public suffix list. For example, the registered domain for foo.example.com is example.com. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as co.uk. + /// This value can be determined precisely with the public suffix list. For example, the registered domain for foo.example.com is example.com. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as co.uk /// public const string AttributeUrlRegisteredDomain = "url.registered_domain"; /// - /// The URI scheme component identifying the used protocol. + /// The URI scheme component identifying the used protocol /// public const string AttributeUrlScheme = "url.scheme"; /// - /// The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. + /// The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain /// /// - /// The subdomain portion of www.east.mydomain.co.uk is east. If the domain has multiple levels of subdomain, such as sub2.sub1.example.com, the subdomain field should contain sub2.sub1, with no trailing period. + /// The subdomain portion of www.east.mydomain.co.uk is east. If the domain has multiple levels of subdomain, such as sub2.sub1.example.com, the subdomain field should contain sub2.sub1, with no trailing period /// public const string AttributeUrlSubdomain = "url.subdomain"; /// - /// The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is com. + /// The low-cardinality template of an absolute path reference + /// + public const string AttributeUrlTemplate = "url.template"; + + /// + /// The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is com /// /// - /// This value can be determined precisely with the public suffix list. + /// This value can be determined precisely with the public suffix list /// public const string AttributeUrlTopLevelDomain = "url.top_level_domain"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs index 86c35643f2..b6f934206e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,23 +15,23 @@ namespace OpenTelemetry.SemanticConventions; public static class UserAgentAttributes { /// - /// Name of the user-agent extracted from original. Usually refers to the browser's name. + /// Name of the user-agent extracted from original. Usually refers to the browser's name /// /// - /// Example of extracting browser&#39;s name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant name SHOULD be selected. In such a scenario it should align with user_agent.version. + /// Example of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant name SHOULD be selected. In such a scenario it should align with user_agent.version /// public const string AttributeUserAgentName = "user_agent.name"; /// - /// Value of the HTTP User-Agent header sent by the client. + /// Value of the HTTP User-Agent header sent by the client /// public const string AttributeUserAgentOriginal = "user_agent.original"; /// - /// Version of the user-agent extracted from original. Usually refers to the browser's version. + /// Version of the user-agent extracted from original. Usually refers to the browser's version /// /// - /// Example of extracting browser&#39;s version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant version SHOULD be selected. In such a scenario it should align with user_agent.name. + /// Example of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant version SHOULD be selected. In such a scenario it should align with user_agent.name /// public const string AttributeUserAgentVersion = "user_agent.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs index 1a3d5ca741..7797afcca9 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs @@ -1,11 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// This file has been auto generated from scripts/templates/SemanticConventionsAttributes.cs.j2 +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' -#pragma warning disable CS1570 // XML comment has badly formed XML +#nullable enable -using System; +#pragma warning disable CS1570 // XML comment has badly formed XML namespace OpenTelemetry.SemanticConventions; @@ -15,17 +15,17 @@ namespace OpenTelemetry.SemanticConventions; public static class WebengineAttributes { /// - /// Additional description of the web engine (e.g. detailed version and edition information). + /// Additional description of the web engine (e.g. detailed version and edition information) /// public const string AttributeWebengineDescription = "webengine.description"; /// - /// The name of the web engine. + /// The name of the web engine /// public const string AttributeWebengineName = "webengine.name"; /// - /// The version of the web engine. + /// The version of the web engine /// public const string AttributeWebengineVersion = "webengine.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md index 49e8b99e72..20ab003382 100644 --- a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md +++ b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated to `v1.26.0` release of OpenTelemetry Semantic Conventions. + ([#2040](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2040)) + * Updated to `1.25.0` release of OpenTelemetry Semantic Conventions. ([#1672](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1672)) diff --git a/src/OpenTelemetry.SemanticConventions/README.md b/src/OpenTelemetry.SemanticConventions/README.md index 5c68066ab0..f79941dbcf 100644 --- a/src/OpenTelemetry.SemanticConventions/README.md +++ b/src/OpenTelemetry.SemanticConventions/README.md @@ -11,8 +11,8 @@ dotnet add package OpenTelemetry.SemanticConventions --prerelease ## Generating the files -This project uses the -[Semantic Convention Generator](https://github.com/open-telemetry/build-tools/blob/main/semantic-conventions/README.md). +This project uses +[Weaver](https://github.com/open-telemetry/weaver). The folder `scripts` at the top level of the project contains the template and the script files used in the process. @@ -31,4 +31,5 @@ Or, with PowerShell: ## References * [OpenTelemetry Project](https://opentelemetry.io/) -* [Build tools](https://github.com/open-telemetry/build-tools) +* [Semantic Conventions](https://github.com/open-telemetry/semantic-conventions) +* [Weaver](https://github.com/open-telemetry/weaver) diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 index 81d03e27f3..c05f576e0a 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 @@ -2,28 +2,29 @@ $SCRIPT_DIR = $PSScriptRoot $ROOT_DIR = "${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -$SPEC_VERSION = "1.25.0" -$GENERATOR_VERSION = "latest" +$SEMCONV_VERSION="1.26.0" +$GENERATOR_VERSION="v0.9.2" Set-Location $SCRIPT_DIR -Remove-Item -r -fo semantic-conventions +Remove-Item -r -fo -ErrorAction SilentlyContinue semantic-conventions mkdir semantic-conventions Set-Location semantic-conventions git init git remote add origin https://github.com/open-telemetry/semantic-conventions.git -git fetch origin v$SPEC_VERSION +git fetch origin v$SEMCONV_VERSION git reset --hard FETCH_HEAD Set-Location ${SCRIPT_DIR} docker run --rm ` -v ${SCRIPT_DIR}/semantic-conventions/model:/source ` -v ${SCRIPT_DIR}/templates:/templates ` - -v ${ROOT_DIR}/Attributes:/output ` - otel/semconvgen:$GENERATOR_VERSION ` - -f /source code ` - --template /templates/SemanticConventionsAttributes.cs.j2 ` - --output "/output/{{pascal_prefix}}Attributes.cs" ` - --trim-whitespace ` - --file-per-group root_namespace + -v ${ROOT_DIR}/Attributes/:/output ` + otel/weaver:$GENERATOR_VERSION ` + registry ` + generate ` + --registry=/source ` + --templates=/templates ` + "./" ` + "/output/./"` diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh index a60fdb1a26..226a09d8c8 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh @@ -5,8 +5,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -SPEC_VERSION=1.25.0 -GENERATOR_VERSION=latest +SEMCONV_VERSION="1.26.0" +GENERATOR_VERSION="v0.9.2" cd ${SCRIPT_DIR} @@ -16,17 +16,18 @@ cd semantic-conventions git init git remote add origin https://github.com/open-telemetry/semantic-conventions.git -git fetch origin "v$SPEC_VERSION" +git fetch origin "v$SEMCONV_VERSION" git reset --hard FETCH_HEAD cd ${SCRIPT_DIR} docker run --rm \ -v ${SCRIPT_DIR}/semantic-conventions/model:/source \ -v ${SCRIPT_DIR}/templates:/templates \ - -v ${ROOT_DIR}/Attributes:/output \ - otel/semconvgen:$GENERATOR_VERSION \ - -f /source code \ - --template /templates/SemanticConventionsAttributes.cs.j2 \ - --output /output/{{pascal_prefix}}Attributes.cs \ - --trim-whitespace \ - --file-per-group root_namespace + -v ${ROOT_DIR}/Attributes/:/output \ + otel/weaver:$GENERATOR_VERSION \ + registry \ + generate \ + --registry=/source \ + --templates=/templates \ + "./" \ + "/output/./"\ \ No newline at end of file diff --git a/src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 b/src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 deleted file mode 100644 index 1c2e139a73..0000000000 --- a/src/OpenTelemetry.SemanticConventions/scripts/templates/SemanticConventionsAttributes.cs.j2 +++ /dev/null @@ -1,65 +0,0 @@ -{%- macro format_remarks(text) -%} -{%- set notes = '\n /// '.join(text.splitlines()).encode('ascii', 'xmlcharrefreplace').decode() -%} -{{notes}} -{%- endmacro -%} - -{%- macro format_xml_doc(text) -%} -{%- set escaped = text.encode('ascii', 'xmlcharrefreplace').decode() -%} - {%- if not escaped.endswith('.')-%} - {{escaped + '.'}} - {%- else -%} - {{escaped}} - {%- endif -%} -{%- endmacro -%} - -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -// This file has been auto generated from scripts{{template}} - -#pragma warning disable CS1570 // XML comment has badly formed XML - -using System; - -namespace OpenTelemetry.SemanticConventions; - -/// -/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. -/// -public static class {{ root_namespace | to_camelcase(True) }}Attributes -{ -{% for attribute in attributes_and_templates %} -{% if not loop.first %}{{"\n"}}{% endif %} - /// - /// {{format_xml_doc(attribute.brief | render_markdown(code="{0}", paragraph="{0}"))}} - /// -{% if attribute.note %} - /// - /// {{format_remarks(attribute.note | to_doc_brief | escape | render_markdown(code="{0}", paragraph="{0}"))}}. - /// -{% endif %} -{% if attribute.deprecated %} - [Obsolete("{{attribute.deprecated | to_doc_brief | replace('"', "")}}")] -{% endif %} - public const string Attribute{{attribute.fqn | replace("-","_") | to_camelcase(True)}} = "{{attribute.fqn}}"; -{% endfor %} -{% for attribute in enum_attributes %} -{% set class_name = attribute.fqn | to_camelcase(True) ~ "Values" %} -{% set type = attribute.attr_type.enum_type %} - - /// - /// {{format_xml_doc(attribute.brief | render_markdown(code="{0}", paragraph="{0}"))}} - /// - public static class {{class_name}} - { - {% for member in attribute.attr_type.members %} - /// - /// {{format_xml_doc(member.brief | render_markdown(code="{0}", paragraph="{0}"))}} - /// - public const {{ type }} {{ member.member_id | to_camelcase(True) }} = {{ attribute | print_member_value(member) }}; - {% if not loop.last %}{{"\n"}}{% endif %} - {% endfor %} - } -{% endfor %} -} - diff --git a/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/SemanticConventionsAttributes.cs.j2 b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/SemanticConventionsAttributes.cs.j2 new file mode 100644 index 0000000000..6f177cbf0b --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/SemanticConventionsAttributes.cs.j2 @@ -0,0 +1,52 @@ +{%- import 'common.j2' as c %} + +{%- set my_file_name = ctx.root_namespace | pascal_case ~ "Attributes.cs" -%} +{%- set my_class_name = ctx.root_namespace | pascal_case ~ "Attributes" -%} +{{- template.set_file_name(my_file_name) -}} + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class {{my_class_name}} +{ +{% for attribute in ctx.attributes | rejectattr("name", "in", ctx.excluded_attributes) %} +{% set attr_name = c.attribute_name(attribute) %} +{% if not loop.first %}{{"\n"}}{% endif %} + {{ attribute.brief | comment(indent=4) }} +{% if attribute.note %} + {{ attribute.note | comment(header="/// ", footer="/// ", indent=4) }} +{% endif %} +{% if attribute.deprecated %} + [Obsolete("{{ attribute.deprecated | replace("\"", "") | comment(header="", footer="", prefix="", indent=0) }}")] +{% endif %} + public const string Attribute{{attr_name}} = "{{attribute.name}}"; +{% endfor %} +{% for attribute in ctx.attributes %}{% if attribute.type is mapping %} +{% set enum_class_name = attribute.name | pascal_case ~ "Values" %} +{% set attribute_resolved_type = attribute.type | instantiated_type %} + + {{ attribute.brief | comment(indent=4) }} + public static class {{enum_class_name}} + { + {% for member in attribute.type.members %} + {{ [member.brief or (member.id ~ '.')] | comment(indent=8) }} + {% if attribute.deprecated %} + [Obsolete("{{ attribute.deprecated | replace("\"", "") | comment(header="", footer="", prefix="", indent=0) }}")] + {% endif %} + public const {{ attribute_resolved_type | map_text("csharp_type") }} {{ member.id | pascal_case }} = {{ member.value | print_member_value }}; + {% if not loop.last %}{{"\n"}}{% endif %} + {% endfor %} + } +{% endif %}{% endfor %} +} diff --git a/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/common.j2 b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/common.j2 new file mode 100644 index 0000000000..1a477cd761 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/common.j2 @@ -0,0 +1,3 @@ +{%- macro attribute_name(attribute) -%} +{{ attribute.name | pascal_case }}{%- if "template" in attribute.type -%}Template{%- endif -%} +{%- endmacro -%} diff --git a/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml new file mode 100644 index 0000000000..80787a2831 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml @@ -0,0 +1,48 @@ +params: + + # excluded attributes will not be generated + # this behavior is fully controlled by jinja templates + excluded_attributes: ["messaging.client_id", "otel.library.name", "otel.library.version"] + +whitespace_control: + trim_blocks: true + lstrip_blocks: true + keep_trailing_newline: true + +comment_formats: + csharp: + format: html + header: "/// " + prefix: "/// " + footer: "/// " + old_style_paragraph: true + omit_closing_li: false + inline_code_snippet: "{{code}}" + block_code_snippet: "{{code}}" + trim: true + remove_trailing_dots: true +default_comment_format: csharp + +templates: + - pattern: SemanticConventionsAttributes.cs.j2 + filter: > + semconv_grouped_attributes({ + "exclude_deprecated": false, + "exclude_stability": [], + }) | map({ + root_namespace: .root_namespace, + attributes: .attributes, + excluded_attributes: $excluded_attributes + }) + application_mode: each + +text_maps: + csharp_type: + int: int + double: double + boolean: bool + string: string + string[]: List + int[]: List + double[]: List + boolean[]: List From 05b84081b2eea249057b5049c127b2560cdb8e1f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 13 Sep 2024 20:46:19 -0700 Subject: [PATCH 1249/1499] [geneva] Nullable annotations for registration extensions (#2067) --- .../.publicApi/PublicAPI.Shipped.txt | 20 +++++++++---------- .../GenevaExporterHelperExtensions.cs | 17 +++++++++++----- .../GenevaLoggingExtensions.cs | 10 ++++++---- .../Metrics/GenevaMetricExporterExtensions.cs | 17 +++++++++++----- 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt index b07b736be2..c503b19aa8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt @@ -46,13 +46,13 @@ override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposin ~override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult ~override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult ~override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 7e8c570484..fda33995c1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -26,7 +28,7 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu /// Adds to the . /// /// builder to use. - /// Exporter configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) => AddGenevaTraceExporter(builder, name: null, configure); @@ -35,10 +37,13 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu /// Adds to the . /// /// builder to use. - /// /// Name which is used when retrieving options. - /// Exporter configuration options. + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. - public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, string name, Action configure) + public static TracerProviderBuilder AddGenevaTraceExporter( + this TracerProviderBuilder builder, + string? name, + Action? configure) { Guard.ThrowIfNull(builder); @@ -89,7 +94,9 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu }); } - private static BaseProcessor BuildGenevaTraceExporter(GenevaExporterOptions options, BatchExportActivityProcessorOptions batchActivityExportProcessor) + private static BaseProcessor BuildGenevaTraceExporter( + GenevaExporterOptions options, + BatchExportActivityProcessorOptions batchActivityExportProcessor) { #pragma warning disable CA2000 // Dispose objects before losing scope var exporter = new GenevaTraceExporter(options); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 17530b7516..853e96bf00 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -20,11 +22,11 @@ public static class GenevaLoggingExtensions /// Adds to the . /// /// . - /// Callback action for configuring . + /// Optional callback action for configuring . /// The instance of to chain the calls. public static OpenTelemetryLoggerOptions AddGenevaLogExporter( this OpenTelemetryLoggerOptions options, - Action configure) + Action? configure) { Guard.ThrowIfNull(options); @@ -71,8 +73,8 @@ public static LoggerProviderBuilder AddGenevaLogExporter(this LoggerProviderBuil /// The instance of to chain the calls. public static LoggerProviderBuilder AddGenevaLogExporter( this LoggerProviderBuilder builder, - string name, - Action configureExporter) + string? name, + Action? configureExporter) { var finalOptionsName = name ?? Options.Options.DefaultName; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 1d25e7c374..9f876453d4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; @@ -25,7 +27,7 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui /// Adds to the . /// /// builder to use. - /// Exporter configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure) => AddGenevaMetricExporter(builder, name: null, configure); @@ -34,10 +36,13 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui /// Adds to the . /// /// builder to use. - /// /// Name which is used when retrieving options. - /// Exporter configuration options. + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. - public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, string name, Action configure) + public static MeterProviderBuilder AddGenevaMetricExporter( + this MeterProviderBuilder builder, + string? name, + Action? configure) { Guard.ThrowIfNull(builder); @@ -56,7 +61,9 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui }); } - private static PeriodicExportingMetricReader BuildGenevaMetricExporter(GenevaMetricExporterOptions options, Action configure = null) + private static PeriodicExportingMetricReader BuildGenevaMetricExporter( + GenevaMetricExporterOptions options, + Action? configure = null) { configure?.Invoke(options); From 5a4a74718367b9c2b9c2957370d49f95ad4f730b Mon Sep 17 00:00:00 2001 From: Guillaume Delahaye <681739+g7ed6e@users.noreply.github.com> Date: Mon, 16 Sep 2024 07:20:15 +0200 Subject: [PATCH 1250/1499] [Instrumentation.ConfluentKafka] Add instrumentation helper methods (#1975) --- examples/kafka/ProduceConsumeHostedService.cs | 1 - examples/kafka/Program.cs | 1 - .../.publicApi/PublicAPI.Unshipped.txt | 32 ++-- .../ConfluentKafkaConsumerInstrumentation.cs | 2 + .../ConfluentKafkaProducerInstrumentation.cs | 2 + .../InstrumentedConsumerBuilder.cs | 4 +- .../InstrumentedProducerBuilder.cs | 4 +- ...MeterProviderBuilderExtensions.Consumer.cs | 3 +- ...MeterProviderBuilderExtensions.Producer.cs | 3 +- .../OpenTelemetryConsumerBuilderExtensions.cs | 108 +++++++++++++ .../OpenTelemetryProducerBuilderExtensions.cs | 104 +++++++++++++ .../README.md | 122 ++++++++++++++- .../ReflectionHelpers.cs | 51 ++++++ ...racerProviderBuilderExtensions.Consumer.cs | 3 +- ...racerProviderBuilderExtensions.Producer.cs | 3 +- ...TelemetryConsumerBuilderExtensionsTests.cs | 145 ++++++++++++++++++ ...TelemetryProducerBuilderExtensionsTests.cs | 113 ++++++++++++++ 17 files changed, 674 insertions(+), 27 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs create mode 100644 src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs diff --git a/examples/kafka/ProduceConsumeHostedService.cs b/examples/kafka/ProduceConsumeHostedService.cs index 04d14dd893..ae8754c23a 100644 --- a/examples/kafka/ProduceConsumeHostedService.cs +++ b/examples/kafka/ProduceConsumeHostedService.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using Confluent.Kafka; -using OpenTelemetry.Instrumentation.ConfluentKafka; namespace Examples.ConfluentKafka; diff --git a/examples/kafka/Program.cs b/examples/kafka/Program.cs index fe9c6dbcdd..afd1a99a85 100644 --- a/examples/kafka/Program.cs +++ b/examples/kafka/Program.cs @@ -3,7 +3,6 @@ using Confluent.Kafka; using Examples.ConfluentKafka; -using OpenTelemetry.Instrumentation.ConfluentKafka; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt index f0c6ffc9b1..a577dafdcd 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt @@ -1,26 +1,30 @@ +Confluent.Kafka.InstrumentedConsumerBuilder +Confluent.Kafka.InstrumentedConsumerBuilder.InstrumentedConsumerBuilder(System.Collections.Generic.IEnumerable>! config) -> void +Confluent.Kafka.InstrumentedProducerBuilder +Confluent.Kafka.InstrumentedProducerBuilder.InstrumentedProducerBuilder(System.Collections.Generic.IEnumerable>! config) -> void Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler +Confluent.Kafka.OpenTelemetryConsumerBuilderExtensions Confluent.Kafka.OpenTelemetryConsumeResultExtensions -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.InstrumentedConsumerBuilder(System.Collections.Generic.IEnumerable>! config) -> void -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.InstrumentedProducerBuilder(System.Collections.Generic.IEnumerable>! config) -> void +Confluent.Kafka.OpenTelemetryProducerBuilderExtensions OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.Build() -> Confluent.Kafka.IConsumer! -override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.Build() -> Confluent.Kafka.IProducer! +override Confluent.Kafka.InstrumentedConsumerBuilder.Build() -> Confluent.Kafka.IConsumer! +override Confluent.Kafka.InstrumentedProducerBuilder.Build() -> Confluent.Kafka.IProducer! +static Confluent.Kafka.OpenTelemetryConsumerBuilderExtensions.AsInstrumentedConsumerBuilder(this Confluent.Kafka.ConsumerBuilder! consumerBuilder) -> Confluent.Kafka.InstrumentedConsumerBuilder! static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.ConsumeAndProcessMessageAsync(this Confluent.Kafka.IConsumer! consumer, Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler! handler) -> System.Threading.Tasks.ValueTask?> static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.ConsumeAndProcessMessageAsync(this Confluent.Kafka.IConsumer! consumer, Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler! handler, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask?> static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.TryExtractPropagationContext(this Confluent.Kafka.ConsumeResult! consumeResult, out OpenTelemetry.Context.Propagation.PropagationContext propagationContext) -> bool +static Confluent.Kafka.OpenTelemetryProducerBuilderExtensions.AsInstrumentedProducerBuilder(this Confluent.Kafka.ProducerBuilder! producerBuilder) -> Confluent.Kafka.InstrumentedProducerBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, Confluent.Kafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, Confluent.Kafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, Confluent.Kafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, Confluent.Kafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! virtual Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler.Invoke(Confluent.Kafka.ConsumeResult! consumeResult, System.Diagnostics.Activity? activity, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs index 573b78d56b..71e8d2baea 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; + namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal class ConfluentKafkaConsumerInstrumentation; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs index 13f71b1905..4f9a720510 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; + namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal abstract class ConfluentKafkaProducerInstrumentation; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs index 8352c874e3..edc70f9085 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; -namespace OpenTelemetry.Instrumentation.ConfluentKafka; +namespace Confluent.Kafka; /// /// A builder of with support for instrumentation. diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs index 5dca3f77a3..eaefacdc19 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; -namespace OpenTelemetry.Instrumentation.ConfluentKafka; +namespace Confluent.Kafka; /// /// A builder of with support for instrumentation. diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs index 0cc6b91997..c2bb25f490 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static MeterProviderBuilder AddKafkaConsumerInstrumentation /// The type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static MeterProviderBuilder AddKafkaConsumerInstrumentation( this MeterProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs index 3e4c4021db..e5fb587066 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static MeterProviderBuilder AddKafkaProducerInstrumentation /// The type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static MeterProviderBuilder AddKafkaProducerInstrumentation( this MeterProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs new file mode 100644 index 0000000000..c139ba1956 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs @@ -0,0 +1,108 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.ConfluentKafka; + +namespace Confluent.Kafka; + +/// +/// Extensions for . +/// +public static class OpenTelemetryConsumerBuilderExtensions +{ + /// + /// Converts a to an . + /// + /// Type of the key. + /// Type of the value. + /// The instance. + /// An instance. +#if !NETFRAMEWORK + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedConsumerBuilder' constructor to avoid reflection.")] +#endif + public static InstrumentedConsumerBuilder AsInstrumentedConsumerBuilder(this ConsumerBuilder consumerBuilder) + { + InstrumentedConsumerBuilder result = new InstrumentedConsumerBuilder(consumerBuilder.GetInternalConfig() ?? Enumerable.Empty>()); + result.SetInternalErrorHandler(consumerBuilder.GetInternalErrorHandler()); + result.SetInternalLogHandler(consumerBuilder.GetInternalLogHandler()); + result.SetInternalStatisticsHandler(consumerBuilder.GetInternalStatisticsHandler()); + result.SetInternalOAuthBearerTokenRefreshHandler(consumerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + result.SetInternalOffsetsCommittedHandler(consumerBuilder.GetInternalOffsetsCommittedHandler()); + result.SetInternalPartitionsAssignedHandler(consumerBuilder.GetInternalPartitionsAssignedHandler()); + result.SetInternalPartitionsRevokedHandler(consumerBuilder.GetInternalPartitionsRevokedHandler()); + result.SetInternalPartitionsLostHandler(consumerBuilder.GetInternalPartitionsLostHandler()); + result.SetInternalRevokedOrLostHandlerIsFunc(consumerBuilder.GetInternalRevokedOrLostHandlerIsFunc() ?? false); + result.SetInternalKeyDeserializer(consumerBuilder.GetInternalKeyDeserializer()); + result.SetInternalValueDeserializer(consumerBuilder.GetInternalValueDeserializer()); + return result; + } + + internal static IEnumerable>? GetInternalConfig(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "Config") as IEnumerable>; + + internal static Action, Error>? GetInternalErrorHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "ErrorHandler") as Action, Error>; + + internal static Action, LogMessage>? GetInternalLogHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "LogHandler") as Action, LogMessage>; + + internal static Action, string>? GetInternalStatisticsHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "StatisticsHandler") as Action, string>; + + internal static Action, string>? GetInternalOAuthBearerTokenRefreshHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "OAuthBearerTokenRefreshHandler") as Action, string>; + + internal static Action, CommittedOffsets>? GetInternalOffsetsCommittedHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "OffsetsCommittedHandler") as Action, CommittedOffsets>; + + internal static Func, List, IEnumerable>? GetInternalPartitionsAssignedHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "PartitionsAssignedHandler") as Func, List, IEnumerable>; + + internal static Func, List, IEnumerable>? GetInternalPartitionsRevokedHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "PartitionsRevokedHandler") as Func, List, IEnumerable>; + + internal static Func, List, IEnumerable>? GetInternalPartitionsLostHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "PartitionsLostHandler") as Func, List, IEnumerable>; + + internal static IDeserializer? GetInternalKeyDeserializer(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "KeyDeserializer") as IDeserializer; + + internal static IDeserializer? GetInternalValueDeserializer(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "ValueDeserializer") as IDeserializer; + + internal static bool? GetInternalRevokedOrLostHandlerIsFunc(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetField(consumerBuilder, "RevokedOrLostHandlerIsFunc") as bool?; + + internal static void SetInternalErrorHandler(this ConsumerBuilder consumerBuilder, Action, Error>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "ErrorHandler", value); + + internal static void SetInternalLogHandler(this ConsumerBuilder consumerBuilder, Action, LogMessage>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "LogHandler", value); + + internal static void SetInternalStatisticsHandler(this ConsumerBuilder consumerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "StatisticsHandler", value); + + internal static void SetInternalOAuthBearerTokenRefreshHandler(this ConsumerBuilder consumerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "OAuthBearerTokenRefreshHandler", value); + + internal static void SetInternalOffsetsCommittedHandler(this ConsumerBuilder consumerBuilder, Action, CommittedOffsets>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "OffsetsCommittedHandler", value); + + internal static void SetInternalPartitionsAssignedHandler(this ConsumerBuilder consumerBuilder, Func, List, IEnumerable>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "PartitionsAssignedHandler", value); + + internal static void SetInternalPartitionsRevokedHandler(this ConsumerBuilder consumerBuilder, Func, List, IEnumerable>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "PartitionsRevokedHandler", value); + + internal static void SetInternalPartitionsLostHandler(this ConsumerBuilder consumerBuilder, Func, List, IEnumerable>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "PartitionsLostHandler", value); + + internal static void SetInternalKeyDeserializer(this ConsumerBuilder consumerBuilder, IDeserializer? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "KeyDeserializer", value); + + internal static void SetInternalValueDeserializer(this ConsumerBuilder consumerBuilder, IDeserializer? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "ValueDeserializer", value); + + internal static void SetInternalRevokedOrLostHandlerIsFunc(this ConsumerBuilder consumerBuilder, bool? value) + => ReflectionHelpers.SetField(consumerBuilder, "RevokedOrLostHandlerIsFunc", value); +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs new file mode 100644 index 0000000000..3eb243af70 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs @@ -0,0 +1,104 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.ConfluentKafka; + +namespace Confluent.Kafka; + +/// +/// Extensions for . +/// +public static class OpenTelemetryProducerBuilderExtensions +{ + /// + /// Converts to . + /// + /// Type of the key. + /// Type of the value. + /// The instance. + /// An instance. +#if !NETFRAMEWORK + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedProducerBuilder' constructor to avoid reflection.")] +#endif + public static InstrumentedProducerBuilder AsInstrumentedProducerBuilder(this ProducerBuilder producerBuilder) + { + InstrumentedProducerBuilder instrumentedProducerBuilder = new InstrumentedProducerBuilder(producerBuilder.GetInternalConfig() ?? Enumerable.Empty>()); + instrumentedProducerBuilder.SetInternalLogHandler(producerBuilder.GetInternalLogHandler()); + instrumentedProducerBuilder.SetInternalErrorHandler(producerBuilder.GetInternalErrorHandler()); + instrumentedProducerBuilder.SetInternalStatisticsHandler(producerBuilder.GetInternalStatisticsHandler()); + instrumentedProducerBuilder.SetInternalOAuthBearerTokenRefreshHandler(producerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + instrumentedProducerBuilder.SetInternalPartitioners(producerBuilder.GetInternalPartitioners()); + instrumentedProducerBuilder.SetInternalDefaultPartitioner(producerBuilder.GetInternalDefaultPartitioner()); + instrumentedProducerBuilder.SetInternalKeySerializer(producerBuilder.GetInternalKeySerializer()); + instrumentedProducerBuilder.SetInternalValueSerializer(producerBuilder.GetInternalValueSerializer()); + instrumentedProducerBuilder.SetInternalAsyncKeySerializer(producerBuilder.GetInternalAsyncKeySerializer()); + instrumentedProducerBuilder.SetInternalAsyncValueSerializer(producerBuilder.GetInternalAsyncValueSerializer()); + return instrumentedProducerBuilder; + } + + internal static IEnumerable>? GetInternalConfig(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "Config") as IEnumerable>; + + internal static Action, Error>? GetInternalErrorHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "ErrorHandler") as Action, Error>; + + internal static Action, LogMessage>? GetInternalLogHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "LogHandler") as Action, LogMessage>; + + internal static Action, string>? GetInternalStatisticsHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "StatisticsHandler") as Action, string>; + + internal static Action, string>? GetInternalOAuthBearerTokenRefreshHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "OAuthBearerTokenRefreshHandler") as Action, string>; + + internal static Dictionary? GetInternalPartitioners(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "Partitioners") as Dictionary; + + internal static PartitionerDelegate? GetInternalDefaultPartitioner(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "DefaultPartitioner") as PartitionerDelegate; + + internal static ISerializer? GetInternalKeySerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "KeySerializer") as ISerializer; + + internal static ISerializer? GetInternalValueSerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "ValueSerializer") as ISerializer; + + internal static IAsyncSerializer? GetInternalAsyncKeySerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "AsyncKeySerializer") as IAsyncSerializer; + + internal static IAsyncSerializer? GetInternalAsyncValueSerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "AsyncValueSerializer") as IAsyncSerializer; + + internal static void SetInternalConfig(this ProducerBuilder producerBuilder, IEnumerable>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "Config", value); + + internal static void SetInternalErrorHandler(this ProducerBuilder producerBuilder, Action, Error>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "ErrorHandler", value); + + internal static void SetInternalLogHandler(this ProducerBuilder producerBuilder, Action, LogMessage>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "LogHandler", value); + + internal static void SetInternalStatisticsHandler(this ProducerBuilder producerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "StatisticsHandler", value); + + internal static void SetInternalOAuthBearerTokenRefreshHandler(this ProducerBuilder producerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "OAuthBearerTokenRefreshHandler", value); + + internal static void SetInternalPartitioners(this ProducerBuilder producerBuilder, Dictionary? value) + => ReflectionHelpers.SetProperty(producerBuilder, "Partitioners", value); + + internal static void SetInternalDefaultPartitioner(this ProducerBuilder producerBuilder, PartitionerDelegate? value) + => ReflectionHelpers.SetProperty(producerBuilder, "DefaultPartitioner", value); + + internal static void SetInternalKeySerializer(this ProducerBuilder producerBuilder, ISerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "KeySerializer", value); + + internal static void SetInternalValueSerializer(this ProducerBuilder producerBuilder, ISerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "ValueSerializer", value); + + internal static void SetInternalAsyncKeySerializer(this ProducerBuilder producerBuilder, IAsyncSerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "AsyncKeySerializer", value); + + internal static void SetInternalAsyncValueSerializer(this ProducerBuilder producerBuilder, IAsyncSerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "AsyncValueSerializer", value); +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md index b05ff16525..09ed24368c 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md @@ -9,8 +9,124 @@ [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.ConfluentKafka)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.ConfluentKafka) -Download the `OpenTelemetry.Instrumentation.ConfluentKafka` package: +## Usage -```shell -dotnet add package OpenTelemetry.Instrumentation.ConfluentKafka --prerelease +To use the `OpenTelemetry.Instrumentation.ConfluentKafka` package, follow these steps: + +1. **Install the package**: + + ```shell + dotnet add package OpenTelemetry.Instrumentation.ConfluentKafka --prerelease + ``` + +2. **Configure OpenTelemetry in your application**: + + ```csharp + using Confluent.Kafka; + using OpenTelemetry.Metrics; + using OpenTelemetry.Trace; + + var builder = Host.CreateApplicationBuilder(args); + + const string bootstrapServers = "localhost:9092"; + + builder.Services.AddSingleton(_ => + { + ProducerConfig producerConfig = new() { BootstrapServers = bootstrapServers }; + return new InstrumentedProducerBuilder(producerConfig); + }); + builder.Services.AddSingleton(_ => + { + ConsumerConfig consumerConfigA = new() + { + BootstrapServers = bootstrapServers, + GroupId = "group-a", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + return new InstrumentedConsumerBuilder(consumerConfigA); + }); + + builder.Services.AddOpenTelemetry() + .WithTracing(tracing => + { + tracing.AddConsoleExporter() + .AddOtlpExporter() + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }) + .WithMetrics(metering => + { + metering.AddConsoleExporter() + .AddOtlpExporter() + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }); + + builder.Services.AddHostedService(); + + var app = builder.Build(); + await app.RunAsync(); + ``` + +This will set up OpenTelemetry instrumentation for Confluent.Kafka producers +and consumers, allowing you to collect and export telemetry data. + +## Extending `ConsumerBuilder` or `ProducerBuilder` instances + +To extend an already built `ConsumerBuilder` +or `ProducerBuilder` +instance with OpenTelemetry instrumentation, you can use the `AsInstrumentedConsumerBuilder` +and `AsInstrumentedProducerBuilder` extension methods. + +### Example for `ConsumerBuilder` + +```csharp +using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; + +var consumerConfig = new ConsumerConfig +{ + BootstrapServers = "localhost:9092", + GroupId = "my-group", + AutoOffsetReset = AutoOffsetReset.Earliest +}; + +var consumerBuilder = new ConsumerBuilder(consumerConfig); + +// Set various handlers and properties +consumerBuilder.SetErrorHandler((consumer, error) => Console.WriteLine($"Error: {error.Reason}")); +consumerBuilder.SetLogHandler((consumer, logMessage) => Console.WriteLine($"Log: {logMessage.Message}")); +consumerBuilder.SetStatisticsHandler((consumer, statistics) => Console.WriteLine($"Statistics: {statistics}")); + +// Convert to InstrumentedConsumerBuilder +var instrumentedConsumerBuilder = consumerBuilder.AsInstrumentedConsumerBuilder(); + +// Build the consumer +var consumer = instrumentedConsumerBuilder.Build(); +``` + +### Example for `ProducerBuilder` + +```csharp +using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; + +var producerConfig = new ProducerConfig +{ + BootstrapServers = "localhost:9092" +}; + +var producerBuilder = new ProducerBuilder(producerConfig); + +// Set various handlers and properties +producerBuilder.SetErrorHandler((producer, error) => Console.WriteLine($"Error: {error.Reason}")); +producerBuilder.SetLogHandler((producer, logMessage) => Console.WriteLine($"Log: {logMessage.Message}")); +producerBuilder.SetStatisticsHandler((producer, statistics) => Console.WriteLine($"Statistics: {statistics}")); + +// Convert to InstrumentedProducerBuilder +var instrumentedProducerBuilder = producerBuilder.AsInstrumentedProducerBuilder(); + +// Build the producer +var producer = instrumentedProducerBuilder.Build(); ``` diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs new file mode 100644 index 0000000000..e48695bbe3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal static class ReflectionHelpers +{ + public static void SetProperty(T instance, string fieldName, object? value) + { + var property = typeof(T).GetProperty(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (property == null) + { + throw new InvalidOperationException($"Could not find property '{fieldName}' on type '{typeof(T).FullName}'."); + } + + property.SetValue(instance, value); + } + + public static object? GetProperty(T instance, string fieldName) + { + var property = typeof(T).GetProperty(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (property == null) + { + throw new InvalidOperationException($"Could not find property '{fieldName}' on type '{typeof(T).FullName}'."); + } + + return property.GetValue(instance); + } + + public static void SetField(T instance, string fieldName, object? value) + { + var field = typeof(T).GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (field == null) + { + throw new InvalidOperationException($"Could not find field '{fieldName}' on type '{typeof(T).FullName}'."); + } + + field.SetValue(instance, value); + } + + public static object? GetField(T instance, string fieldName) + { + var field = typeof(T).GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (field == null) + { + throw new InvalidOperationException($"Could not find field '{fieldName}' on type '{typeof(T).FullName}'."); + } + + return field.GetValue(instance); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs index d9eada36e1..ee6025f885 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static TracerProviderBuilder AddKafkaConsumerInstrumentationThe type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static TracerProviderBuilder AddKafkaConsumerInstrumentation( this TracerProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs index db977c72ae..5f8adbfb84 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static TracerProviderBuilder AddKafkaProducerInstrumentationThe type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static TracerProviderBuilder AddKafkaProducerInstrumentation( this TracerProviderBuilder builder, diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs new file mode 100644 index 0000000000..1af7aefd27 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs @@ -0,0 +1,145 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +public class OpenTelemetryConsumerBuilderExtensionsTests +{ + [Fact] + public void ShouldConvertConsumerBuilderToInstrumentedConsumerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var consumerBuilder = new ConsumerBuilder(config); + + IDeserializer keyDeserializer = Deserializers.Utf8; + IDeserializer valueDeserializer = Deserializers.Utf8; + + consumerBuilder.SetErrorHandler(ErrorHandler); + consumerBuilder.SetLogHandler(LogHandler); + consumerBuilder.SetStatisticsHandler(StatisticsHandler); + consumerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + consumerBuilder.SetOffsetsCommittedHandler(OffsetsCommittedHandler); + consumerBuilder.SetPartitionsAssignedHandler(PartitionsAssignedHandler); + consumerBuilder.SetPartitionsRevokedHandler(PartitionsRevokedHandler); + consumerBuilder.SetPartitionsLostHandler(PartitionsLostHandler); + consumerBuilder.SetKeyDeserializer(keyDeserializer); + consumerBuilder.SetValueDeserializer(valueDeserializer); + + // Act + var instrumentedConsumerBuilder = consumerBuilder.AsInstrumentedConsumerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedConsumerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedConsumerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedConsumerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedConsumerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(OffsetsCommittedHandler, instrumentedConsumerBuilder.GetInternalOffsetsCommittedHandler()); + Assert.Equal(PartitionsAssignedHandler, instrumentedConsumerBuilder.GetInternalPartitionsAssignedHandler()); + Assert.Equal(PartitionsRevokedHandler, instrumentedConsumerBuilder.GetInternalPartitionsRevokedHandler()); + Assert.Equal(PartitionsLostHandler, instrumentedConsumerBuilder.GetInternalPartitionsLostHandler()); + Assert.Equal(keyDeserializer, instrumentedConsumerBuilder.GetInternalKeyDeserializer()); + Assert.Equal(valueDeserializer, instrumentedConsumerBuilder.GetInternalValueDeserializer()); + return; + + void ErrorHandler(IConsumer consumer, Error error) + { + } + + void LogHandler(IConsumer consumer, LogMessage logMessage) + { + } + + void StatisticsHandler(IConsumer consumer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IConsumer consumer, string oauthBearerToken) + { + } + + void OffsetsCommittedHandler(IConsumer consumer, CommittedOffsets offsets) + { + } + + IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) => new List(); + } + + [Fact] + public void ShouldConvertUserDefinedConsumerBuilderToInstrumentedConsumerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var consumerBuilder = new CustomConsumerBuilder(config); + + IDeserializer keyDeserializer = Deserializers.Utf8; + IDeserializer valueDeserializer = Deserializers.Utf8; + + consumerBuilder.SetErrorHandler(ErrorHandler); + consumerBuilder.SetLogHandler(LogHandler); + consumerBuilder.SetStatisticsHandler(StatisticsHandler); + consumerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + consumerBuilder.SetOffsetsCommittedHandler(OffsetsCommittedHandler); + consumerBuilder.SetPartitionsAssignedHandler(PartitionsAssignedHandler); + consumerBuilder.SetPartitionsRevokedHandler(PartitionsRevokedHandler); + consumerBuilder.SetPartitionsLostHandler(PartitionsLostHandler); + consumerBuilder.SetKeyDeserializer(keyDeserializer); + consumerBuilder.SetValueDeserializer(valueDeserializer); + + // Act + var instrumentedConsumerBuilder = consumerBuilder.AsInstrumentedConsumerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedConsumerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedConsumerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedConsumerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedConsumerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(OffsetsCommittedHandler, instrumentedConsumerBuilder.GetInternalOffsetsCommittedHandler()); + Assert.Equal(PartitionsAssignedHandler, instrumentedConsumerBuilder.GetInternalPartitionsAssignedHandler()); + Assert.Equal(PartitionsRevokedHandler, instrumentedConsumerBuilder.GetInternalPartitionsRevokedHandler()); + Assert.Equal(PartitionsLostHandler, instrumentedConsumerBuilder.GetInternalPartitionsLostHandler()); + Assert.Equal(keyDeserializer, instrumentedConsumerBuilder.GetInternalKeyDeserializer()); + Assert.Equal(valueDeserializer, instrumentedConsumerBuilder.GetInternalValueDeserializer()); + return; + + void ErrorHandler(IConsumer consumer, Error error) + { + } + + void LogHandler(IConsumer consumer, LogMessage logMessage) + { + } + + void StatisticsHandler(IConsumer consumer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IConsumer consumer, string oauthBearerToken) + { + } + + void OffsetsCommittedHandler(IConsumer consumer, CommittedOffsets offsets) + { + } + + IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) => new List(); + } + + private class CustomConsumerBuilder(IEnumerable> config) + : ConsumerBuilder(config); +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs new file mode 100644 index 0000000000..83025fe323 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs @@ -0,0 +1,113 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +public class OpenTelemetryProducerBuilderExtensionsTests +{ + [Fact] + public void ShouldConvertToInstrumentedProducerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var producerBuilder = new ProducerBuilder(config); + + ISerializer keySerializer = Serializers.Utf8; + ISerializer valueSerializer = Serializers.Utf8; + + producerBuilder.SetErrorHandler(ErrorHandler); + producerBuilder.SetLogHandler(LogHandler); + producerBuilder.SetStatisticsHandler(StatisticsHandler); + producerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + producerBuilder.SetKeySerializer(keySerializer); + producerBuilder.SetValueSerializer(valueSerializer); + + // Act + var instrumentedProducerBuilder = producerBuilder.AsInstrumentedProducerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedProducerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedProducerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedProducerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedProducerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(keySerializer, instrumentedProducerBuilder.GetInternalKeySerializer()); + Assert.Equal(valueSerializer, instrumentedProducerBuilder.GetInternalValueSerializer()); + return; + + void ErrorHandler(IProducer producer, Error error) + { + } + + void LogHandler(IProducer producer, LogMessage logMessage) + { + } + + void StatisticsHandler(IProducer producer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IProducer producer, string oauthBearerToken) + { + } + } + + [Fact] + public void ShouldConvertUserDefinedProducerBuilderToInstrumentedProducerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var producerBuilder = new CustomProducerBuilder(config); + + ISerializer keySerializer = Serializers.Utf8; + ISerializer valueSerializer = Serializers.Utf8; + + producerBuilder.SetErrorHandler(ErrorHandler); + producerBuilder.SetLogHandler(LogHandler); + producerBuilder.SetStatisticsHandler(StatisticsHandler); + producerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + producerBuilder.SetKeySerializer(keySerializer); + producerBuilder.SetValueSerializer(valueSerializer); + + // Act + var instrumentedProducerBuilder = producerBuilder.AsInstrumentedProducerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedProducerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedProducerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedProducerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedProducerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(keySerializer, instrumentedProducerBuilder.GetInternalKeySerializer()); + Assert.Equal(valueSerializer, instrumentedProducerBuilder.GetInternalValueSerializer()); + return; + + void ErrorHandler(IProducer producer, Error error) + { + } + + void LogHandler(IProducer producer, LogMessage logMessage) + { + } + + void StatisticsHandler(IProducer producer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IProducer producer, string oauthBearerToken) + { + } + } + + private class CustomProducerBuilder(IEnumerable> config) + : ProducerBuilder(config); +} From d5a630fe62c72be42f49309709f6a77c2058df22 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Mon, 16 Sep 2024 07:32:01 +0200 Subject: [PATCH 1251/1499] [Instrumentation.Owin] Update to semantic convention v1.27.0 (#2028) --- .../CHANGELOG.md | 5 +++ .../Implementation/DiagnosticsMiddleware.cs | 45 +++++++------------ .../OpenTelemetry.Instrumentation.Owin.csproj | 1 + .../README.md | 19 ++++++++ .../DiagnosticsMiddlewareTests.cs | 22 ++++----- 5 files changed, 53 insertions(+), 39 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 61ce939c32..e775f6e7b8 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Updated activity tags to use new + [semantic conventions](https://github.com/open-telemetry/semantic-conventions/tree/v1.27.0/docs/http/http-spans.md) + attribute schema. + ([#2028](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2028)) + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 65b44f7519..cf029720c0 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -20,6 +20,8 @@ internal sealed class DiagnosticsMiddleware : OwinMiddleware private static readonly Func> OwinRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); + private static readonly RequestDataHelper RequestDataHelper = new(configureByHttpKnownMethodsEnvironmentalVariable: false); + /// /// Initializes a new instance of the class. /// @@ -84,39 +86,26 @@ private static void BeginRequest(IOwinContext owinContext) { var request = owinContext.Request; - /* - * Note: Display name is intentionally set to a low cardinality - * value because OWIN does not expose any kind of - * route/template. See: - * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name - */ - activity.DisplayName = request.Method switch - { - "GET" => "HTTP GET", - "POST" => "HTTP POST", - "PUT" => "HTTP PUT", - "DELETE" => "HTTP DELETE", - _ => $"HTTP {request.Method}", - }; + // Note: Display name is intentionally set to a low cardinality + // value because OWIN does not expose any kind of + // route/template. See: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name + RequestDataHelper.SetActivityDisplayName(activity, request.Method); if (activity.IsAllDataRequested) { - if (request.Uri.Port == 80 || request.Uri.Port == 443) - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host + ":" + request.Uri.Port); - } + RequestDataHelper.SetHttpMethodTag(activity, request.Method); + activity.SetTag(SemanticConventions.AttributeServerAddress, request.Uri.Host); + activity.SetTag(SemanticConventions.AttributeServerPort, request.Uri.Port); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, request.Protocol); - activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); - activity.SetTag(SemanticConventions.AttributeHttpTarget, request.Uri.AbsolutePath); - activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Uri, OwinInstrumentationActivitySource.Options.DisableUrlQueryRedaction)); + activity.SetTag(SemanticConventions.AttributeUrlPath, request.Uri.AbsolutePath); + activity.SetTag(SemanticConventions.AttributeUrlQuery, request.Query); + activity.SetTag(SemanticConventions.AttributeUrlScheme, owinContext.Request.Scheme); if (request.Headers.TryGetValue("User-Agent", out string[] userAgent) && userAgent.Length > 0) { - activity.SetTag(SemanticConventions.AttributeHttpUserAgent, userAgent[0]); + activity.SetTag(SemanticConventions.AttributeUserAgentOriginal, userAgent[0]); } try @@ -163,7 +152,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l { activity.SetStatus(Status.Error); - if (OwinInstrumentationActivitySource.Options != null && OwinInstrumentationActivitySource.Options.RecordException) + if (OwinInstrumentationActivitySource.Options?.RecordException == true) { activity.RecordException(exception); } @@ -173,7 +162,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); } - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, response.StatusCode); try { diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index a72d0b2a7c..184409a304 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -20,6 +20,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index b92d521fd9..f2553161b3 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -59,6 +59,25 @@ OpenTelemetry instrumentation which listens to the OWIN diagnostic events. .Build(); ``` +Following list of attributes are added by default on activity. See +[http-spans](https://github.com/open-telemetry/semantic-conventions/tree/v1.27.0/docs/http/http-spans.md) +for more details about each individual attribute: + +* `http.request.method` +* `http.request.method_original` +* `http.response.status_code` +* `network.protocol.version` +* `user_agent.original` +* `server.address` +* `server.port` +* `url.path` +* `url.query` - By default, the values in the query component are replaced with + the text `Redacted`. For example, `?key1=value1&key2=value2` becomes + `?key1=Redacted&key2=Redacted`. You can disable this redaction by setting the + environment variable + `OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION` to `true`. +* `url.scheme` + #### Configure OpenTelemetry MeterProvider Call the `AddOwinInstrumentation` `MeterProviderBuilder` extension to register diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 2222fecfc7..445818e461 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -195,12 +195,12 @@ Owin has finished to inspect the activity status. */ Activity activity = stoppedActivities[0]; Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); - Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); - Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); - Assert.Equal(requestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); + Assert.Equal(requestUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerAddress).Value); + Assert.Equal(requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerPort).Value); + Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpRequestMethod).Value); + Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeUrlPath).Value); + Assert.Equal(generateRemoteException ? 500 : 200, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpResponseStatusCode).Value); - Assert.Equal(generateRemoteException ? 500 : 200, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpStatusCode).Value); if (generateRemoteException) { Assert.Equal(Status.Error, activity.GetStatus()); @@ -248,13 +248,13 @@ Owin has finished to inspect the activity status. */ { switch (tag.Key) { - case SemanticConventions.AttributeHttpMethod: + case SemanticConventions.AttributeHttpRequestMethod: Assert.Equal("GET", tag.Value); break; case SemanticConventions.AttributeHttpScheme: Assert.Equal(requestUri.Scheme, tag.Value); break; - case SemanticConventions.AttributeHttpStatusCode: + case SemanticConventions.AttributeHttpResponseStatusCode: Assert.Equal(generateRemoteException ? 500 : 200, tag.Value); break; } @@ -343,10 +343,10 @@ Owin has finished to inspect the activity status. */ Activity activity = stoppedActivities[0]; Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); - Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); - Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); - Assert.Equal(expectedRequestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); + Assert.Equal(requestUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerAddress).Value); + Assert.Equal(requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerPort).Value); + Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpRequestMethod).Value); + Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeUrlPath).Value); } finally { From ee03fc31f64388b30d2f80b267911aaf0fbbeb0c Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:47:55 -0500 Subject: [PATCH 1252/1499] [release] Prepare release Instrumentation.ConfluentKafka-0.1.0-alpha.1 (#2072) --- src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index 134621e04d..42980dd334 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -2,4 +2,8 @@ ## Unreleased +## 0.1.0-alpha.1 + +Released 2024-Sep-16 + * Initial release From 4a9d97c169dd7870395d2787b301fb8f2f5a928b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 16 Sep 2024 14:33:08 -0700 Subject: [PATCH 1253/1499] [geneva] Nullable annotations for the remaining public API (#2070) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/PublicAPI.Shipped.txt | 38 +++++++++---------- .../GenevaBaseExporter.cs | 2 + .../GenevaExporterOptions.cs | 10 +++-- .../GenevaLogExporter.cs | 2 + .../GenevaLoggingExtensions.cs | 2 +- .../GenevaTraceExporter.cs | 2 + .../Metrics/GenevaMetricExporter.cs | 4 +- .../Metrics/GenevaMetricExporterOptions.cs | 13 ++++--- 8 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt index c503b19aa8..437f3b1c4c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt @@ -6,9 +6,14 @@ OpenTelemetry.Exporter.Geneva.EventNameExportMode.None = 0 -> OpenTelemetry.Expo OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.Drop = 0 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsString = 1 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode +OpenTelemetry.Exporter.Geneva.GenevaBaseExporter OpenTelemetry.Exporter.Geneva.GenevaBaseExporter.GenevaBaseExporter() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions OpenTelemetry.Exporter.Geneva.GenevaExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable? +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.get -> OpenTelemetry.Exporter.Geneva.EventNameExportMode OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.EventNameExportMode.set -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.get -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode @@ -16,36 +21,31 @@ OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ExceptionStackExportMode.set OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.GenevaExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.get -> bool OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.IncludeTraceStateForSpan.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary! +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary? +OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void OpenTelemetry.Exporter.Geneva.GenevaLogExporter +OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions! options) -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporter +OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions! options) -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string? +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.GenevaMetricExporterOptions() -> void OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.get -> int OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.MetricExportIntervalMilliseconds.set -> void +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary? +OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void OpenTelemetry.Exporter.Geneva.GenevaTraceExporter +OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions! options) -> void override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposing) -> void +override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void -~OpenTelemetry.Exporter.Geneva.GenevaBaseExporter -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.get -> string -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.ConnectionString.set -> void -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.get -> System.Collections.Generic.IEnumerable -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.CustomFields.set -> void -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.get -> System.Collections.Generic.IReadOnlyDictionary -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.PrepopulatedFields.set -> void -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary -~OpenTelemetry.Exporter.Geneva.GenevaExporterOptions.TableNameMappings.set -> void -~OpenTelemetry.Exporter.Geneva.GenevaLogExporter.GenevaLogExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -~OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.GenevaMetricExporter(OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions options) -> void -~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.get -> string -~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.ConnectionString.set -> void -~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.get -> System.Collections.Generic.IReadOnlyDictionary -~OpenTelemetry.Exporter.Geneva.GenevaMetricExporterOptions.PrepopulatedMetricDimensions.set -> void -~OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.GenevaTraceExporter(OpenTelemetry.Exporter.Geneva.GenevaExporterOptions options) -> void -~override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -~override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -~override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 0dcfe55ce3..452ae78f1e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index e31e3d35d0..849b294894 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Text; using OpenTelemetry.Internal; @@ -16,17 +18,17 @@ public class GenevaExporterOptions [Schema.V40.PartA.Ver] = "4.0", }; - private IReadOnlyDictionary tableNameMappings; + private IReadOnlyDictionary? tableNameMappings; /// /// Gets or sets the connection string. /// - public string ConnectionString { get; set; } + public string? ConnectionString { get; set; } /// /// Gets or sets custom fields. /// - public IEnumerable CustomFields { get; set; } + public IEnumerable? CustomFields { get; set; } /// /// Gets or sets the exception stack trace export mode. @@ -46,7 +48,7 @@ public class GenevaExporterOptions /// /// Gets or sets table name mappings. /// - public IReadOnlyDictionary TableNameMappings + public IReadOnlyDictionary? TableNameMappings { get => this.tableNameMappings; set diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 476199bbad..2b7cee0379 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.TldExporter; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 853e96bf00..bc6bc3371e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -130,7 +130,7 @@ internal static BaseProcessor BuildGenevaLogExporter( Debug.Assert(exporterOptions != null, "exporterOptions was null"); #pragma warning disable CA2000 // Dispose objects before losing scope - var exporter = new GenevaLogExporter(exporterOptions); + var exporter = new GenevaLogExporter(exporterOptions!); #pragma warning restore CA2000 // Dispose objects before losing scope if (exporter.IsUsingUnixDomainSocket) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index d73cfc705a..af3b070af9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.TldExporter; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 07c0839445..ce640bbef4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Reflection; using System.Text.RegularExpressions; using OpenTelemetry.Exporter.Geneva.Metrics; @@ -33,7 +35,7 @@ public partial class GenevaMetricExporter : BaseExporter private bool isDisposed; - private Resource resource; + private Resource? resource; /// /// Initializes a new instance of the class. diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index 3367d43512..ca14f2d939 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Globalization; using OpenTelemetry.Internal; @@ -11,14 +13,14 @@ namespace OpenTelemetry.Exporter.Geneva; /// public class GenevaMetricExporterOptions { - private IReadOnlyDictionary prepopulatedMetricDimensions; + private IReadOnlyDictionary? prepopulatedMetricDimensions; private int metricExporterIntervalMilliseconds = 60000; /// /// Gets or sets the ConnectionString which contains semicolon separated list of key-value pairs. /// For e.g.: "Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace". /// - public string ConnectionString { get; set; } + public string? ConnectionString { get; set; } /// /// Gets or sets the metric export interval in milliseconds. The default value is 60000. @@ -41,7 +43,7 @@ public int MetricExportIntervalMilliseconds /// /// Gets or sets the pre-populated dimensions for all the metrics exported by the exporter. /// - public IReadOnlyDictionary PrepopulatedMetricDimensions + public IReadOnlyDictionary? PrepopulatedMetricDimensions { get { @@ -67,12 +69,13 @@ public IReadOnlyDictionary PrepopulatedMetricDimensions throw new ArgumentException($"The dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionNameSize} characters for a dimension name."); } - if (entry.Value == null) + string? dimensionValue; + if (entry.Value == null + || (dimensionValue = Convert.ToString(entry.Value, CultureInfo.InvariantCulture)) == null) { throw new ArgumentNullException($"{nameof(this.PrepopulatedMetricDimensions)}[\"{entry.Key}\"]"); } - var dimensionValue = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); if (dimensionValue.Length > GenevaMetricExporter.MaxDimensionValueSize) { throw new ArgumentException($"Value provided for the dimension: {entry.Key} exceeds the maximum allowed limit of {GenevaMetricExporter.MaxDimensionValueSize} characters for dimension value."); From 7f29ef35a726ce7bd825fb7931709cc06fa5ee90 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 16 Sep 2024 21:56:20 -0700 Subject: [PATCH 1254/1499] [geneva] Nullable annotations for the internal folder (#2076) --- .../EventNameExportMode.cs | 2 ++ .../ExceptionStackExportMode.cs | 2 ++ .../External/TraceLoggingDynamic.cs | 5 +++- .../Internal/ConnectionStringBuilder.cs | 25 ++++++++++++------- .../Internal/ExporterEventSource.cs | 2 ++ .../ReentrantActivityExportProcessor.cs | 2 ++ .../Internal/ReentrantExportProcessor.cs | 5 +++- .../Internal/Schema.cs | 2 ++ .../Internal/TableNameSerializer.cs | 14 ++++++----- .../Metrics/GenevaMetricExporter.cs | 2 +- 10 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs index dd87d4e8c9..ab0183c1e5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs index 9030a32b9c..de9e62607c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs index c5d46a6bbf..e2cea7bb1f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs +++ b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs @@ -70,6 +70,9 @@ that is larger than the buffer size of the recording session. Most ETW decoding tools are unable to decode an event with more than 128 fields. */ + +#nullable enable + namespace OpenTelemetry.Exporter.Geneva.External; using System; @@ -315,7 +318,7 @@ public static Guid GetGuidForName(string providerName) // Guid = Hash[0..15], with Hash[7] tweaked approximately following RFC 4122 byte[] guidBytes = new byte[16]; - Buffer.BlockCopy(sha1.Hash, 0, guidBytes, 0, 16); + Buffer.BlockCopy(sha1.Hash!, 0, guidBytes, 0, 16); guidBytes[7] = (byte)((guidBytes[7] & 0x0F) | 0x50); return new Guid(guidBytes); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 51b8d0035b..f441aeeef5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Globalization; using OpenTelemetry.Internal; @@ -67,16 +69,22 @@ public string EtwSession set => this.parts[nameof(this.EtwSession)] = value; } - public string PrivatePreviewEnableTraceLoggingDynamic + public bool PrivatePreviewEnableTraceLoggingDynamic { - get => this.ThrowIfNotExists(nameof(this.PrivatePreviewEnableTraceLoggingDynamic)); - set => this.parts[nameof(this.PrivatePreviewEnableTraceLoggingDynamic)] = value; + get + { + return this.parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var value) + && bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase); + } } - public string PrivatePreviewEnableOtlpProtobufEncoding + public bool PrivatePreviewEnableOtlpProtobufEncoding { - get => this.parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) ? value : null; - set => this.parts[nameof(this.PrivatePreviewEnableOtlpProtobufEncoding)] = value; + get + { + return this.parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) + && bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase); + } } public string Endpoint @@ -94,8 +102,7 @@ public TransportProtocol Protocol // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux if (this.parts.ContainsKey(nameof(this.EtwSession))) { - _ = this.parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var privatePreviewEnableTraceLoggingDynamic); - if (privatePreviewEnableTraceLoggingDynamic != null && privatePreviewEnableTraceLoggingDynamic.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + if (this.PrivatePreviewEnableTraceLoggingDynamic) { return TransportProtocol.EtwTld; } @@ -127,7 +134,7 @@ public int TimeoutMilliseconds { get { - if (!this.parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string value)) + if (!this.parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string? value)) { return UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 9da11fafbb..107acaf52d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs index fff9eebf9c..59e732a10d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index 3ae51105ee..b53e74861f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Linq.Expressions; using System.Reflection; @@ -29,7 +31,8 @@ protected override void OnExport(T data) private static Func> BuildCreateBatchDelegate() { var flags = BindingFlags.Instance | BindingFlags.NonPublic; - var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null); + var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null) + ?? throw new InvalidOperationException("Batch ctor accepting a single item could not be found reflectively"); var value = Expression.Parameter(typeof(T), null); var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); return lambda.Compile(); diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs index b665743364..39a9fb2931 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; internal static class Schema diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index 6a3b40add1..c9de7b1a47 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Runtime.CompilerServices; using System.Text; @@ -23,7 +25,7 @@ indicate an invalid name. We need a different instance to trigger the private static readonly StringComparer DictionaryKeyComparer = StringComparer.Ordinal; private readonly byte[] defaultTableName; - private readonly Dictionary tableMappings; + private readonly Dictionary? tableMappings; private readonly bool shouldPassThruTableMappings; private readonly object lockObject = new(); private TableNameCacheDictionary tableNameCache = new(); @@ -35,7 +37,7 @@ public TableNameSerializer(GenevaExporterOptions options, string defaultTableNam this.defaultTableName = BuildStr8BufferForAsciiString(defaultTableName); - if (options.TableNameMappings != null) + if (options!.TableNameMappings != null) { var tempTableMappings = new Dictionary(options.TableNameMappings.Count, DictionaryKeyComparer); foreach (var kv in options.TableNameMappings) @@ -164,7 +166,7 @@ private byte[] ResolveTableMappingForCategoryName(string categoryName) { var tableNameCache = this.tableNameCache; - if (tableNameCache.TryGetValue(categoryName, out byte[] tableName)) + if (tableNameCache.TryGetValue(categoryName, out byte[]? tableName)) { return tableName; } @@ -174,7 +176,7 @@ private byte[] ResolveTableMappingForCategoryName(string categoryName) private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) { - byte[] mappedTableName = null; + byte[]? mappedTableName = null; // If user configured table name mappings run resolution logic. if (this.tableMappings != null @@ -182,7 +184,7 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) { // Find best match if an exact match was not found. - string currentKey = null; + string? currentKey = null; foreach (var mapping in this.tableMappings) { @@ -230,7 +232,7 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) // Check if another thread added the mapping while we waited on the // lock. - if (tableNameCache.TryGetValue(categoryName, out byte[] tableName)) + if (tableNameCache.TryGetValue(categoryName, out byte[]? tableName)) { return tableName; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index ce640bbef4..d769946906 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -53,7 +53,7 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) DisableOpenTelemetrySdkMetricNameValidation(); } - if (connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding != null && connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase)) + if (connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding) { var otlpProtobufExporter = new OtlpProtobufMetricExporter( () => { return this.Resource; }, From a724d9625a0dad0813c65697681863335f76433c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Sep 2024 07:08:15 +0200 Subject: [PATCH 1255/1499] [repo] Fix InfluxDB pipeline definition (#2077) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83fa5c9a2d..28a3db1968 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: code: ['**.cs', '**.csproj', '.editorconfig'] aottestapp: ['test/OpenTelemetry.AotCompatibility.TestApp/**'] exporter-geneva: ['*/OpenTelemetry.Exporter.Geneva*/**', '!**/*.md'] - exporter-infuxdb: ['*/OpenTelemetry.Exporter.InfluxDB*/**', '!**/*.md'] + exporter-influxdb: ['*/OpenTelemetry.Exporter.InfluxDB*/**', '!**/*.md'] exporter-instana: ['*/OpenTelemetry.Exporter.Instana*/**', '!**/*.md'] exporter-onecollector: ['*/OpenTelemetry.Exporter.OneCollector*/**', '!**/*.md'] exporter-stackdriver: ['*/OpenTelemetry.Exporter.Stackdriver*/**', '!**/*.md'] From 95b037205ebe4d598f96cdef3effa663af019af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Sep 2024 19:36:48 +0200 Subject: [PATCH 1256/1499] [Exporter.InfluxDB] NugetAudit - fix dependencies with known vulnerabilities (#2073) --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 5 +++++ .../OpenTelemetry.Exporter.InfluxDB.csproj | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index a919418175..271706b380 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -5,6 +5,11 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Updated `InfluxDB.Client` to `4.18.0` to mitigate [CVE-2024-45302](https://github.com/advisories/GHSA-4rr6-2v9v-wcpc) + and [CVE-2024-30105](https://github.com/advisories/GHSA-hh2w-p6rv-4g7w) + in transitive dependencies. + ([#2073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2073)) + ## 1.0.0-alpha.3 Released 2023-Oct-13 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index f1c7da1493..9da39c289a 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -16,7 +16,7 @@ - + From 18c5a26eecf150837e7548303c72665612c95823 Mon Sep 17 00:00:00 2001 From: Guillaume Delahaye <681739+g7ed6e@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:17:36 +0200 Subject: [PATCH 1257/1499] [Instrumentation.ConfluentKafka] Add named instrumentation support (#2074) --- .../.publicApi/PublicAPI.Unshipped.txt | 4 + .../CHANGELOG.md | 5 +- .../InstrumentedConsumerBuilder.cs | 19 +- .../InstrumentedProducer.cs | 7 +- .../InstrumentedProducerBuilder.cs | 19 +- ...MeterProviderBuilderExtensions.Consumer.cs | 36 ++-- ...MeterProviderBuilderExtensions.Producer.cs | 36 ++-- ...racerProviderBuilderExtensions.Consumer.cs | 38 ++-- ...racerProviderBuilderExtensions.Producer.cs | 38 ++-- .../HostedTracingAndMeteringTests.cs | 201 +++++++++++++++--- 10 files changed, 287 insertions(+), 116 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt index a577dafdcd..33f9216f8b 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt @@ -17,14 +17,18 @@ static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.TryExtractPropagatio static Confluent.Kafka.OpenTelemetryProducerBuilderExtensions.AsInstrumentedProducerBuilder(this Confluent.Kafka.ProducerBuilder! producerBuilder) -> Confluent.Kafka.InstrumentedProducerBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, Confluent.Kafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, Confluent.Kafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, Confluent.Kafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, Confluent.Kafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! virtual Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler.Invoke(Confluent.Kafka.ConsumeResult! consumeResult, System.Diagnostics.Activity? activity, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index 42980dd334..83bc70a47b 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased +- Add named instrumentation support + ([#2074](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2074)) + ## 0.1.0-alpha.1 Released 2024-Sep-16 -* Initial release +- Initial release diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs index edc70f9085..8affdfa5fd 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Diagnostics; using OpenTelemetry.Instrumentation.ConfluentKafka; namespace Confluent.Kafka; @@ -13,6 +12,8 @@ namespace Confluent.Kafka; /// Type of value. public sealed class InstrumentedConsumerBuilder : ConsumerBuilder { + private readonly ConfluentKafkaConsumerInstrumentationOptions options = new(); + /// /// Initializes a new instance of the class. /// @@ -22,7 +23,17 @@ public InstrumentedConsumerBuilder(IEnumerable> con { } - internal ConfluentKafkaConsumerInstrumentationOptions? Options { get; set; } + internal bool EnableMetrics + { + get => this.options.Metrics; + set => this.options.Metrics = value; + } + + internal bool EnableTraces + { + get => this.options.Traces; + set => this.options.Traces = value; + } /// /// Build a new IConsumer instance. @@ -30,11 +41,9 @@ public InstrumentedConsumerBuilder(IEnumerable> con /// an . public override IConsumer Build() { - Debug.Assert(this.Options != null, "Options should not be null."); - ConsumerConfig config = (ConsumerConfig)this.Config; - var consumer = new InstrumentedConsumer(base.Build(), this.Options!); + var consumer = new InstrumentedConsumer(base.Build(), this.options); consumer.GroupId = config.GroupId; return consumer; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs index a91c04314c..b47caa3591 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs @@ -27,8 +27,6 @@ public InstrumentedProducer( public string Name => this.producer.Name; - internal ConfluentKafkaProducerInstrumentationOptions Options => this.options; - public int AddBrokers(string brokers) { return this.producer.AddBrokers(brokers); @@ -326,6 +324,11 @@ private static void RecordPublish(TopicPartition topicPartition, TimeSpan durati private Activity? StartPublishActivity(DateTimeOffset start, string topic, Message message, int? partition = null) { + if (!this.options.Traces) + { + return null; + } + var spanName = string.Concat(topic, " ", ConfluentKafkaCommon.PublishOperationName); var activity = ConfluentKafkaCommon.ActivitySource.StartActivity(name: spanName, kind: ActivityKind.Producer, startTime: start); if (activity == null) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs index eaefacdc19..79e9a25748 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Diagnostics; using OpenTelemetry.Instrumentation.ConfluentKafka; namespace Confluent.Kafka; @@ -13,6 +12,8 @@ namespace Confluent.Kafka; /// Type of value. public sealed class InstrumentedProducerBuilder : ProducerBuilder { + private readonly ConfluentKafkaProducerInstrumentationOptions options = new(); + /// /// Initializes a new instance of the class. /// @@ -22,7 +23,17 @@ public InstrumentedProducerBuilder(IEnumerable> con { } - internal ConfluentKafkaProducerInstrumentationOptions? Options { get; set; } + internal bool EnableMetrics + { + get => this.options.Metrics; + set => this.options.Metrics = value; + } + + internal bool EnableTraces + { + get => this.options.Traces; + set => this.options.Traces = value; + } /// /// Build a new IProducer instance. @@ -30,8 +41,6 @@ public InstrumentedProducerBuilder(IEnumerable> con /// an . public override IProducer Build() { - Debug.Assert(this.Options != null, "Options should not be null."); - - return new InstrumentedProducer(base.Build(), this.Options!); + return new InstrumentedProducer(base.Build(), this.options); } } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs index c2bb25f490..b10b715b2b 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs @@ -3,7 +3,6 @@ using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; using OpenTelemetry.Internal; @@ -25,6 +24,18 @@ public static MeterProviderBuilder AddKafkaConsumerInstrumentation this MeterProviderBuilder builder) => AddKafkaConsumerInstrumentation(builder, name: null, consumerBuilder: null); + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The name of the instrumentation. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaConsumerInstrumentation( + this MeterProviderBuilder builder, string? name) + => AddKafkaConsumerInstrumentation(builder, name: name, consumerBuilder: null); + /// /// Enables automatic data collection of outgoing requests to Kafka. /// @@ -58,34 +69,21 @@ public static MeterProviderBuilder AddKafkaConsumerInstrumentation { Guard.ThrowIfNull(builder); - name ??= Options.DefaultName; - - builder.ConfigureServices(services => - { - services.Configure>(name, EnableMetrics); - }); - return builder .AddMeter(ConfluentKafkaCommon.InstrumentationName) .AddInstrumentation(sp => { - if (consumerBuilder == null) + if (name == null) { - consumerBuilder = sp.GetRequiredService>(); - var options = sp.GetRequiredService>>(); - consumerBuilder.Options = options.Get(name); + consumerBuilder ??= sp.GetRequiredService>(); } - - if (consumerBuilder.Options == null) + else { - consumerBuilder.Options = new ConfluentKafkaConsumerInstrumentationOptions(); - EnableMetrics(consumerBuilder.Options); + consumerBuilder ??= sp.GetRequiredKeyedService>(name); } + consumerBuilder.EnableMetrics = true; return new ConfluentKafkaConsumerInstrumentation(consumerBuilder); }); } - - private static void EnableMetrics(ConfluentKafkaConsumerInstrumentationOptions options) => - options.Metrics = true; } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs index e5fb587066..387761679e 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs @@ -3,7 +3,6 @@ using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; using OpenTelemetry.Internal; @@ -25,6 +24,18 @@ public static MeterProviderBuilder AddKafkaProducerInstrumentation this MeterProviderBuilder builder) => AddKafkaProducerInstrumentation(builder, name: null, producerBuilder: null); + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The name of the instrumentation. + /// The instance of to chain the calls. + public static MeterProviderBuilder AddKafkaProducerInstrumentation( + this MeterProviderBuilder builder, string? name) + => AddKafkaProducerInstrumentation(builder, name: name, producerBuilder: null); + /// /// Enables automatic data collection of outgoing requests to Kafka. /// @@ -58,34 +69,21 @@ public static MeterProviderBuilder AddKafkaProducerInstrumentation { Guard.ThrowIfNull(builder); - name ??= Options.DefaultName; - - builder.ConfigureServices(services => - { - services.Configure>(name, EnableMetrics); - }); - return builder .AddMeter(ConfluentKafkaCommon.InstrumentationName) .AddInstrumentation(sp => { - if (producerBuilder == null) + if (name == null) { - producerBuilder = sp.GetRequiredService>(); - var options = sp.GetRequiredService>>(); - producerBuilder.Options = options.Get(name); + producerBuilder ??= sp.GetRequiredService>(); } - - if (producerBuilder.Options == null) + else { - producerBuilder.Options = new ConfluentKafkaProducerInstrumentationOptions(); - EnableMetrics(producerBuilder.Options); + producerBuilder ??= sp.GetRequiredKeyedService>(name); } + producerBuilder.EnableMetrics = true; return new ConfluentKafkaProducerInstrumentation(producerBuilder); }); } - - private static void EnableMetrics(ConfluentKafkaProducerInstrumentationOptions options) => - options.Metrics = true; } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs index ee6025f885..bf1a4e95a5 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs @@ -3,7 +3,6 @@ using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; using OpenTelemetry.Internal; @@ -25,6 +24,18 @@ public static TracerProviderBuilder AddKafkaConsumerInstrumentation AddKafkaConsumerInstrumentation(builder, name: null, consumerBuilder: null); + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The name of the instrumentation. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaConsumerInstrumentation( + this TracerProviderBuilder builder, string? name) + => AddKafkaConsumerInstrumentation(builder, name: name, consumerBuilder: null); + /// /// Enables automatic data collection of outgoing requests to Kafka. /// @@ -48,7 +59,7 @@ public static TracerProviderBuilder AddKafkaConsumerInstrumentationThe type of the key. /// The type of the value. /// being configured. - /// Optional name which is used when retrieving options. + /// The name of the instrumentation. /// Optional to instrument. /// The instance of to chain the calls. public static TracerProviderBuilder AddKafkaConsumerInstrumentation( @@ -58,34 +69,21 @@ public static TracerProviderBuilder AddKafkaConsumerInstrumentation - { - services.Configure>(name, EnableTracing); - }); - return builder .AddSource(ConfluentKafkaCommon.InstrumentationName) .AddInstrumentation(sp => { - if (consumerBuilder == null) + if (name == null) { - consumerBuilder = sp.GetRequiredService>(); - var options = sp.GetRequiredService>>(); - consumerBuilder.Options = options.Get(name); + consumerBuilder ??= sp.GetRequiredService>(); } - - if (consumerBuilder.Options == null) + else { - consumerBuilder.Options = new ConfluentKafkaConsumerInstrumentationOptions(); - EnableTracing(consumerBuilder.Options); + consumerBuilder ??= sp.GetRequiredKeyedService>(name); } + consumerBuilder.EnableTraces = true; return new ConfluentKafkaConsumerInstrumentation(consumerBuilder); }); } - - private static void EnableTracing(ConfluentKafkaConsumerInstrumentationOptions options) => - options.Traces = true; } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs index 5f8adbfb84..8e427c7a32 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs @@ -3,7 +3,6 @@ using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; using OpenTelemetry.Internal; @@ -25,6 +24,18 @@ public static TracerProviderBuilder AddKafkaProducerInstrumentation AddKafkaProducerInstrumentation(builder, name: null, producerBuilder: null); + /// + /// Enables automatic data collection of outgoing requests to Kafka. + /// + /// The type of the key. + /// The type of the value. + /// being configured. + /// The name of the instrumentation. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddKafkaProducerInstrumentation( + this TracerProviderBuilder builder, string? name) + => AddKafkaProducerInstrumentation(builder, name: name, producerBuilder: null); + /// /// Enables automatic data collection of outgoing requests to Kafka. /// @@ -48,7 +59,7 @@ public static TracerProviderBuilder AddKafkaProducerInstrumentationThe type of the key. /// The type of the value. /// being configured. - /// Optional name which is used when retrieving options. + /// The name of the instrumentation. /// Optional to instrument. /// The instance of to chain the calls. public static TracerProviderBuilder AddKafkaProducerInstrumentation( @@ -58,34 +69,21 @@ public static TracerProviderBuilder AddKafkaProducerInstrumentation - { - services.Configure>(name, EnableTracing); - }); - return builder .AddSource(ConfluentKafkaCommon.InstrumentationName) .AddInstrumentation(sp => { - if (producerBuilder == null) + if (name == null) { - producerBuilder = sp.GetRequiredService>(); - var options = sp.GetRequiredService>>(); - producerBuilder.Options = options.Get(name); + producerBuilder ??= sp.GetRequiredService>(); } - - if (producerBuilder.Options == null) + else { - producerBuilder.Options = new ConfluentKafkaProducerInstrumentationOptions(); - EnableTracing(producerBuilder.Options); + producerBuilder ??= sp.GetRequiredKeyedService>(name); } + producerBuilder.EnableTraces = true; return new ConfluentKafkaProducerInstrumentation(producerBuilder); }); } - - private static void EnableTracing(ConfluentKafkaProducerInstrumentationOptions options) => - options.Traces = true; } diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs index adeb619e0d..c49f03deb1 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs @@ -17,41 +17,147 @@ namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; public class HostedTracingAndMeteringTests(ITestOutputHelper outputHelper) { [Trait("CategoryName", "KafkaIntegrationTests")] - [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] - public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() + [SkipUnlessEnvVarFoundTheory(KafkaHelpers.KafkaEndPointEnvVarName)] + [InlineData(true, true, true, true, true, true)] + [InlineData(true, true, true, true, true, false)] + [InlineData(true, true, true, true, false, true)] + [InlineData(true, true, true, true, false, false)] + [InlineData(true, true, true, false, true, true)] + [InlineData(true, true, true, false, true, false)] + [InlineData(true, true, true, false, false, true)] + [InlineData(true, true, true, false, false, false)] + [InlineData(true, true, false, true, true, true)] + [InlineData(true, true, false, true, true, false)] + [InlineData(true, true, false, true, false, true)] + [InlineData(true, true, false, true, false, false)] + [InlineData(true, true, false, false, true, true)] + [InlineData(true, true, false, false, true, false)] + [InlineData(true, true, false, false, false, true)] + [InlineData(true, true, false, false, false, false)] + [InlineData(true, false, true, true, true, true)] + [InlineData(true, false, true, true, true, false)] + [InlineData(true, false, true, true, false, true)] + [InlineData(true, false, true, true, false, false)] + [InlineData(true, false, true, false, true, true)] + [InlineData(true, false, true, false, true, false)] + [InlineData(true, false, true, false, false, true)] + [InlineData(true, false, true, false, false, false)] + [InlineData(true, false, false, true, true, true)] + [InlineData(true, false, false, true, true, false)] + [InlineData(true, false, false, true, false, true)] + [InlineData(true, false, false, true, false, false)] + [InlineData(true, false, false, false, true, true)] + [InlineData(true, false, false, false, true, false)] + [InlineData(true, false, false, false, false, true)] + [InlineData(true, false, false, false, false, false)] + [InlineData(false, true, true, true, true, true)] + [InlineData(false, true, true, true, true, false)] + [InlineData(false, true, true, true, false, true)] + [InlineData(false, true, true, true, false, false)] + [InlineData(false, true, true, false, true, true)] + [InlineData(false, true, true, false, true, false)] + [InlineData(false, true, true, false, false, true)] + [InlineData(false, true, true, false, false, false)] + [InlineData(false, true, false, true, true, true)] + [InlineData(false, true, false, true, true, false)] + [InlineData(false, true, false, true, false, true)] + [InlineData(false, true, false, true, false, false)] + [InlineData(false, true, false, false, true, true)] + [InlineData(false, true, false, false, true, false)] + [InlineData(false, true, false, false, false, true)] + [InlineData(false, true, false, false, false, false)] + [InlineData(false, false, true, true, true, true)] + [InlineData(false, false, true, true, true, false)] + [InlineData(false, false, true, true, false, true)] + [InlineData(false, false, true, true, false, false)] + [InlineData(false, false, true, false, true, true)] + [InlineData(false, false, true, false, true, false)] + [InlineData(false, false, true, false, false, true)] + [InlineData(false, false, true, false, false, false)] + [InlineData(false, false, false, true, true, true)] + [InlineData(false, false, false, true, true, false)] + [InlineData(false, false, false, true, false, true)] + [InlineData(false, false, false, true, false, false)] + [InlineData(false, false, false, false, true, true)] + [InlineData(false, false, false, false, true, false)] + [InlineData(false, false, false, false, false, true)] + [InlineData(false, false, false, false, false, false)] + public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest(bool enableProducerMetrics, bool enableProducerTraces, bool useNamedProducerInstrumentation, bool enableConsumerMetrics, bool enableConsumerTraces, bool useNamedConsumerInstrumentation) { + string? producerInstrumentationName = useNamedProducerInstrumentation ? "MyProducer" : null; + string? consumerInstrumentationName = useNamedConsumerInstrumentation ? "MyConsumer" : null; List metrics = new(); List activities = new(); var builder = Host.CreateDefaultBuilder(); builder.ConfigureServices(services => { - services.AddSingleton(_ => - new InstrumentedProducerBuilder(new ProducerConfig() - { - BootstrapServers = KafkaHelpers.KafkaEndPoint, - })); - services.AddSingleton(_ => - new InstrumentedConsumerBuilder(new ConsumerConfig() - { - BootstrapServers = KafkaHelpers.KafkaEndPoint, - GroupId = Guid.NewGuid().ToString(), - AutoOffsetReset = AutoOffsetReset.Earliest, - EnablePartitionEof = true, - })); + if (useNamedProducerInstrumentation) + { + services.AddKeyedSingleton(producerInstrumentationName, (_, _) => + new InstrumentedProducerBuilder(new ProducerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + })); + } + else + { + services.AddSingleton(_ => + new InstrumentedProducerBuilder(new ProducerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + })); + } + + if (useNamedConsumerInstrumentation) + { + services.AddKeyedSingleton(consumerInstrumentationName, (_, _) => + new InstrumentedConsumerBuilder(new ConsumerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = Guid.NewGuid().ToString(), + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + })); + } + else + { + services.AddSingleton(_ => + new InstrumentedConsumerBuilder(new ConsumerConfig() + { + BootstrapServers = KafkaHelpers.KafkaEndPoint, + GroupId = Guid.NewGuid().ToString(), + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + })); + } services.AddOpenTelemetry().WithTracing(tracingBuilder => { tracingBuilder .AddInMemoryExporter(activities) - .SetSampler(new TestSampler()) - .AddKafkaProducerInstrumentation() - .AddKafkaConsumerInstrumentation(); + .SetSampler(new TestSampler()); + if (enableProducerTraces) + { + tracingBuilder.AddKafkaProducerInstrumentation(name: producerInstrumentationName, producerBuilder: null); + } + + if (enableConsumerTraces) + { + tracingBuilder.AddKafkaConsumerInstrumentation(name: consumerInstrumentationName, consumerBuilder: null); + } }).WithMetrics(metricsBuilder => { metricsBuilder - .AddInMemoryExporter(metrics) - .AddKafkaProducerInstrumentation() - .AddKafkaConsumerInstrumentation(); + .AddInMemoryExporter(metrics); + if (enableProducerMetrics) + { + metricsBuilder.AddKafkaProducerInstrumentation(name: producerInstrumentationName, producerBuilder: null); + } + + if (enableConsumerMetrics) + { + metricsBuilder.AddKafkaConsumerInstrumentation(name: consumerInstrumentationName, consumerBuilder: null); + } }); }); @@ -59,8 +165,21 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { await host.StartAsync(); + var producerBuilder = useNamedProducerInstrumentation + ? host.Services.GetRequiredKeyedService>(producerInstrumentationName) + : host.Services.GetRequiredService>(); + Assert.Equal(enableProducerMetrics, producerBuilder.EnableMetrics); + Assert.Equal(enableProducerTraces, producerBuilder.EnableTraces); + var consumerBuilder = useNamedConsumerInstrumentation + ? host.Services.GetRequiredKeyedService>(consumerInstrumentationName) + : host.Services.GetRequiredService>(); + Assert.Equal(enableConsumerMetrics, consumerBuilder.EnableMetrics); + Assert.Equal(enableConsumerTraces, consumerBuilder.EnableTraces); + string topic = $"otel-topic-{Guid.NewGuid()}"; - using (var producer = host.Services.GetRequiredService>().Build()) + using (var producer = (useNamedProducerInstrumentation + ? host.Services.GetRequiredKeyedService>(producerInstrumentationName) + : host.Services.GetRequiredService>()).Build()) { for (int i = 0; i < 100; i++) { @@ -75,7 +194,16 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() await producer.FlushAsync(); } - using (var consumer = host.Services.GetRequiredService>().Build()) + if (enableProducerTraces) + { + Assert.Equal(100, activities.Count); + } + + activities.Clear(); + + using (var consumer = (useNamedConsumerInstrumentation + ? host.Services.GetRequiredKeyedService>(consumerInstrumentationName) + : host.Services.GetRequiredService>()).Build()) { consumer.Subscribe(topic); @@ -102,13 +230,36 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() await host.StopAsync(); - Assert.Equal(200, activities.Count); + if (enableConsumerTraces) + { + Assert.Equal(100, activities.Count); + } host.Services.GetRequiredService().EnsureMetricsAreFlushed(); } IGrouping[] groups = metrics.GroupBy(x => x.Name).ToArray(); - Assert.Equal(4, groups.Length); + if (enableProducerMetrics) + { + Assert.Contains("messaging.publish.messages", groups.Select(x => x.Key)); + Assert.Contains("messaging.publish.duration", groups.Select(x => x.Key)); + } + else + { + Assert.DoesNotContain("messaging.publish.messages", groups.Select(x => x.Key)); + Assert.DoesNotContain("messaging.publish.duration", groups.Select(x => x.Key)); + } + + if (enableConsumerMetrics) + { + Assert.Contains("messaging.receive.messages", groups.Select(x => x.Key)); + Assert.Contains("messaging.receive.duration", groups.Select(x => x.Key)); + } + else + { + Assert.DoesNotContain("messaging.receive.messages", groups.Select(x => x.Key)); + Assert.DoesNotContain("messaging.receive.duration", groups.Select(x => x.Key)); + } } } From 378a1a3510af243816868e694aa77ac8300aef30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 18 Sep 2024 11:35:08 +0200 Subject: [PATCH 1258/1499] [repo] Enable NugetAudit - finalize (#2079) --- build/Common.nonprod.props | 2 +- build/Common.props | 3 +-- .../wcf/client-core/Examples.Wcf.Client.DotNet.csproj | 4 +++- examples/wcf/shared/Examples.Wcf.Shared.csproj | 11 +++++++++-- .../OpenTelemetry.AotCompatibility.TestApp.csproj | 5 +++++ .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 4 ++++ .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 4 ++++ .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 2 ++ .../OpenTelemetry.Sampler.AWS.Tests.csproj | 2 ++ 9 files changed, 31 insertions(+), 6 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 38928926cf..29cd1456ea 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -28,7 +28,7 @@ net8.0;net6.0 [2.8.2,3.0) [2.9.0,3.0) - [1.6.1,2.0) + [1.6.3,2.0) diff --git a/build/Common.props b/build/Common.props index 3c4da312f4..52f8c3bcc0 100644 --- a/build/Common.props +++ b/build/Common.props @@ -14,8 +14,7 @@ enable enable true - - + all low diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index f87ebac82a..38ac618f6a 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -9,8 +9,10 @@ - + + + diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index 265744f7ed..bcef073cb9 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -2,7 +2,7 @@ - netstandard2.0;net462 + net8.0;net462 @@ -10,8 +10,15 @@ - + + + + + + + + diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index c4d79207e0..fb9ef875d2 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -13,6 +13,11 @@ + + + + + + + + diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index c7400ad0a6..b86cc62d34 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -11,6 +11,10 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index f95d11bd98..017682e469 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -22,6 +22,8 @@ + + diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 6892d723eb..d8db5a8c05 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -7,6 +7,8 @@ + + From 0bcf991560a42941cb15aface2cb664e7c5303f5 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 18 Sep 2024 04:36:26 -0500 Subject: [PATCH 1259/1499] [release] Prepare release Instrumentation.ConfluentKafka-0.1.0-alpha.2 (#2081) --- src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index 83bc70a47b..ce758fbebc 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.2 + +Released 2024-Sep-18 + - Add named instrumentation support ([#2074](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2074)) From 88de33c3383118e5f8d864987400a23aa4e64c64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 19 Sep 2024 10:03:02 +0200 Subject: [PATCH 1260/1499] [SemanticConvention] Bump to v1.27.0 (#2069) --- .../.publicApi/PublicAPI.Unshipped.txt | 132 ++++++++- .../Attributes/ArtifactAttributes.cs | 67 +++++ .../Attributes/AzAttributes.cs | 21 ++ .../Attributes/CicdAttributes.cs | 67 +++++ .../Attributes/CloudAttributes.cs | 2 +- .../Attributes/ContainerAttributes.cs | 8 +- .../Attributes/CpuAttributes.cs | 67 +++++ .../Attributes/DbAttributes.cs | 269 +++++++++++------- .../Attributes/DeploymentAttributes.cs | 45 ++- .../Attributes/EnduserAttributes.cs | 9 +- .../Attributes/EventAttributes.cs | 2 +- .../Attributes/GcpAttributes.cs | 8 + .../Attributes/GenAiAttributes.cs | 124 +++++++- .../Attributes/GoAttributes.cs | 37 +++ .../Attributes/LinuxAttributes.cs | 37 +++ .../Attributes/LogAttributes.cs | 8 + .../Attributes/MessagingAttributes.cs | 60 +++- .../Attributes/NetworkAttributes.cs | 5 + .../Attributes/OtherAttributes.cs | 10 +- .../Attributes/PoolAttributes.cs | 4 +- .../Attributes/ProcessAttributes.cs | 10 +- .../Attributes/SystemAttributes.cs | 12 +- .../Attributes/TestAttributes.cs | 88 ++++++ .../Attributes/TlsAttributes.cs | 3 +- .../Attributes/UserAttributes.cs | 49 ++++ .../Attributes/V8jsAttributes.cs | 86 ++++++ .../Attributes/VcsAttributes.cs | 73 +++++ .../CHANGELOG.md | 3 + .../scripts/generate.ps1 | 2 +- .../scripts/generate.sh | 4 +- 30 files changed, 1152 insertions(+), 160 deletions(-) create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt index 6500a8befd..41f6d5209c 100644 --- a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt @@ -3,6 +3,13 @@ const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Cre const OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues.Foreground = "foreground" -> string! const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidOsApiLevel = "android.os.api_level" -> string! const OpenTelemetry.SemanticConventions.AndroidAttributes.AttributeAndroidState = "android.state" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactAttestationFilename = "artifact.attestation.filename" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactAttestationHash = "artifact.attestation.hash" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactAttestationId = "artifact.attestation.id" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactFilename = "artifact.filename" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactHash = "artifact.hash" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactPurl = "artifact.purl" -> string! +const OpenTelemetry.SemanticConventions.ArtifactAttributes.AttributeArtifactVersion = "artifact.version" -> string! const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Aborted = "aborted" -> string! const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Handled = "handled" -> string! const OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues.Skipped = "skipped" -> string! @@ -64,10 +71,20 @@ const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3PartNumber = const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3UploadId = "aws.s3.upload_id" -> string! const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Ec2 = "ec2" -> string! const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Fargate = "fargate" -> string! +const OpenTelemetry.SemanticConventions.AzAttributes.AttributeAzServiceRequestId = "az.service_request_id" -> string! const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserBrands = "browser.brands" -> string! const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserLanguage = "browser.language" -> string! const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserMobile = "browser.mobile" -> string! const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserPlatform = "browser.platform" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.AttributeCicdPipelineName = "cicd.pipeline.name" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.AttributeCicdPipelineRunId = "cicd.pipeline.run.id" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.AttributeCicdPipelineTaskName = "cicd.pipeline.task.name" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.AttributeCicdPipelineTaskRunId = "cicd.pipeline.task.run.id" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.AttributeCicdPipelineTaskRunUrlFull = "cicd.pipeline.task.run.url.full" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.AttributeCicdPipelineTaskType = "cicd.pipeline.task.type" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.CicdPipelineTaskTypeValues.Build = "build" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.CicdPipelineTaskTypeValues.Deploy = "deploy" -> string! +const OpenTelemetry.SemanticConventions.CicdAttributes.CicdPipelineTaskTypeValues.Test = "test" -> string! const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientAddress = "client.address" -> string! const OpenTelemetry.SemanticConventions.ClientAttributes.AttributeClientPort = "client.port" -> string! const OpenTelemetry.SemanticConventions.CloudAttributes.AttributeCloudAccountId = "cloud.account.id" -> string! @@ -138,6 +155,15 @@ const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerRu const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.Kernel = "kernel" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.System = "system" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues.User = "user" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.AttributeCpuMode = "cpu.mode" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.Idle = "idle" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.Interrupt = "interrupt" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.Iowait = "iowait" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.Kernel = "kernel" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.Nice = "nice" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.Steal = "steal" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.System = "system" -> string! +const OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues.User = "user" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id" -> string! @@ -145,8 +171,10 @@ const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraIdempot const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraPageSize = "db.cassandra.page_size" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCassandraTable = "db.cassandra.table" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbClientConnectionPoolName = "db.client.connection.pool.name" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbClientConnectionsPoolName = "db.client.connections.pool.name" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbClientConnectionsState = "db.client.connections.state" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbClientConnectionState = "db.client.connection.state" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCollectionName = "db.collection.name" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbConnectionString = "db.connection_string" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbClientId = "db.cosmosdb.client_id" -> string! @@ -167,6 +195,7 @@ const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbMssqlInstanceNam const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbName = "db.name" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbNamespace = "db.namespace" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperation = "db.operation" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationBatchSize = "db.operation.batch.size" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationName = "db.operation.name" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryParameterTemplate = "db.query.parameter" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryText = "db.query.text" -> string! @@ -188,6 +217,8 @@ const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevel const OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues.Two = "two" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues.Idle = "idle" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues.Used = "used" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValues.Idle = "idle" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValues.Used = "used" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Direct = "direct" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Gateway = "gateway" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "Batch" -> string! @@ -229,10 +260,12 @@ const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hanadb = "ha const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hbase = "hbase" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hive = "hive" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Hsqldb = "hsqldb" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Influxdb = "influxdb" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Informix = "informix" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Ingres = "ingres" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Instantdb = "instantdb" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Interbase = "interbase" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.IntersystemsCache = "intersystems_cache" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Mariadb = "mariadb" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Maxdb = "maxdb" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Memcached = "memcached" -> string! @@ -258,6 +291,12 @@ const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Teradata = " const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Trino = "trino" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Vertica = "vertica" -> string! const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentEnvironment = "deployment.environment" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentEnvironmentName = "deployment.environment.name" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentId = "deployment.id" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentName = "deployment.name" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.AttributeDeploymentStatus = "deployment.status" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.DeploymentStatusValues.Failed = "failed" -> string! +const OpenTelemetry.SemanticConventions.DeploymentAttributes.DeploymentStatusValues.Succeeded = "succeeded" -> string! const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationAddress = "destination.address" -> string! const OpenTelemetry.SemanticConventions.DestinationAttributes.AttributeDestinationPort = "destination.port" -> string! const OpenTelemetry.SemanticConventions.DeviceAttributes.AttributeDeviceId = "device.id" -> string! @@ -315,23 +354,42 @@ const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileExtension = const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileName = "file.name" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFilePath = "file.path" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileSize = "file.size" -> string! +const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpClientService = "gcp.client.service" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceName = "gcp.gce.instance.name" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiCompletion = "gen_ai.completion" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOperationName = "gen_ai.operation.name" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiPrompt = "gen_ai.prompt" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestFrequencyPenalty = "gen_ai.request.frequency_penalty" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestMaxTokens = "gen_ai.request.max_tokens" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestModel = "gen_ai.request.model" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestPresencePenalty = "gen_ai.request.presence_penalty" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestStopSequences = "gen_ai.request.stop_sequences" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestTemperature = "gen_ai.request.temperature" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestTopK = "gen_ai.request.top_k" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestTopP = "gen_ai.request.top_p" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiResponseFinishReasons = "gen_ai.response.finish_reasons" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiResponseId = "gen_ai.response.id" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiResponseModel = "gen_ai.response.model" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiSystem = "gen_ai.system" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiTokenType = "gen_ai.token.type" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageCompletionTokens = "gen_ai.usage.completion_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageInputTokens = "gen_ai.usage.input_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageOutputTokens = "gen_ai.usage.output_tokens" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.Chat = "chat" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.TextCompletion = "text_completion" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Anthropic = "anthropic" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Cohere = "cohere" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Openai = "openai" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.VertexAi = "vertex_ai" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues.Completion = "output" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues.Input = "input" -> string! +const OpenTelemetry.SemanticConventions.GoAttributes.AttributeGoMemoryType = "go.memory.type" -> string! +const OpenTelemetry.SemanticConventions.GoAttributes.GoMemoryTypeValues.Other = "other" -> string! +const OpenTelemetry.SemanticConventions.GoAttributes.GoMemoryTypeValues.Stack = "stack" -> string! const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlDocument = "graphql.document" -> string! const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationName = "graphql.operation.name" -> string! const OpenTelemetry.SemanticConventions.GraphqlAttributes.AttributeGraphqlOperationType = "graphql.operation.type" -> string! @@ -454,11 +512,15 @@ const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetName const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetUid = "k8s.replicaset.uid" -> string! const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetName = "k8s.statefulset.name" -> string! const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetUid = "k8s.statefulset.uid" -> string! +const OpenTelemetry.SemanticConventions.LinuxAttributes.AttributeLinuxMemorySlabState = "linux.memory.slab.state" -> string! +const OpenTelemetry.SemanticConventions.LinuxAttributes.LinuxMemorySlabStateValues.Reclaimable = "reclaimable" -> string! +const OpenTelemetry.SemanticConventions.LinuxAttributes.LinuxMemorySlabStateValues.Unreclaimable = "unreclaimable" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileName = "log.file.name" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFileNameResolved = "log.file.name_resolved" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePath = "log.file.path" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogFilePathResolved = "log.file.path_resolved" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogIostream = "log.iostream" -> string! +const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogRecordOriginal = "log.record.original" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.AttributeLogRecordUid = "log.record.uid" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stderr = "stderr" -> string! const OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues.Stdout = "stdout" -> string! @@ -470,11 +532,13 @@ const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Rece const OpenTelemetry.SemanticConventions.MessageAttributes.MessageTypeValues.Sent = "SENT" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingBatchMessageCount = "messaging.batch.message_count" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingClientId = "messaging.client.id" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingConsumerGroupName = "messaging.consumer.group.name" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationName = "messaging.destination.name" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationPublishName = "messaging.destination_publish.name" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationSubscriptionName = "messaging.destination.subscription.name" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemplate = "messaging.destination.template" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingDestinationTemporary = "messaging.destination.temporary" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group" -> string! @@ -488,6 +552,7 @@ const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKa const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingKafkaOffset = "messaging.kafka.offset" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageBodySize = "messaging.message.body.size" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageConversationId = "messaging.message.conversation_id" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size" -> string! @@ -512,7 +577,8 @@ const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingSe const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.AttributeMessagingSystem = "messaging.system" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Create = "create" -> string! -const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Deliver = "process" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Deliver = "deliver" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Process = "process" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Publish = "publish" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Receive = "receive" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Settle = "settle" -> string! @@ -533,6 +599,7 @@ const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValue const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.GcpPubsub = "gcp_pubsub" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Jms = "jms" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Kafka = "kafka" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Pulsar = "pulsar" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rabbitmq = "rabbitmq" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Rocketmq = "rocketmq" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingSystemValues.Servicebus = "servicebus" -> string! @@ -603,6 +670,7 @@ const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeV const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Receive = "receive" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues.Transmit = "transmit" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Pipe = "pipe" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Quic = "quic" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Tcp = "tcp" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Udp = "udp" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Unix = "unix" -> string! @@ -826,6 +894,18 @@ const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguage const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Rust = "rust" -> string! const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Swift = "swift" -> string! const OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues.Webjs = "webjs" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.AttributeTestCaseName = "test.case.name" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.AttributeTestCaseResultStatus = "test.case.result.status" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.AttributeTestSuiteName = "test.suite.name" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.AttributeTestSuiteRunStatus = "test.suite.run.status" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestCaseResultStatusValues.Fail = "fail" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestCaseResultStatusValues.Pass = "pass" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues.Aborted = "aborted" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues.Failure = "failure" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues.InProgress = "in_progress" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues.Skipped = "skipped" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues.Success = "success" -> string! +const OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues.TimedOut = "timed_out" -> string! const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadId = "thread.id" -> string! const OpenTelemetry.SemanticConventions.ThreadAttributes.AttributeThreadName = "thread.name" -> string! const OpenTelemetry.SemanticConventions.TlsAttributes.AttributeTlsCipher = "tls.cipher" -> string! @@ -875,18 +955,47 @@ const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTopLevelDomain const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentName = "user_agent.name" -> string! const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentOriginal = "user_agent.original" -> string! const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentVersion = "user_agent.version" -> string! +const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserEmail = "user.email" -> string! +const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserFullName = "user.full_name" -> string! +const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserHash = "user.hash" -> string! +const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserId = "user.id" -> string! +const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserName = "user.name" -> string! +const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserRoles = "user.roles" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.AttributeV8jsGcType = "v8js.gc.type" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.AttributeV8jsHeapSpaceName = "v8js.heap.space.name" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues.Incremental = "incremental" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues.Major = "major" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues.Minor = "minor" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues.Weakcb = "weakcb" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.CodeSpace = "code_space" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.LargeObjectSpace = "large_object_space" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.MapSpace = "map_space" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.NewSpace = "new_space" -> string! +const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.OldSpace = "old_space" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryChangeId = "vcs.repository.change.id" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryChangeTitle = "vcs.repository.change.title" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryRefName = "vcs.repository.ref.name" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryRefRevision = "vcs.repository.ref.revision" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryRefType = "vcs.repository.ref.type" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryUrlFull = "vcs.repository.url.full" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues.Branch = "branch" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues.Tag = "tag" -> string! const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineDescription = "webengine.description" -> string! const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineName = "webengine.name" -> string! const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineVersion = "webengine.version" -> string! OpenTelemetry.SemanticConventions.AndroidAttributes OpenTelemetry.SemanticConventions.AndroidAttributes.AndroidStateValues +OpenTelemetry.SemanticConventions.ArtifactAttributes OpenTelemetry.SemanticConventions.AspnetcoreAttributes OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreDiagnosticsExceptionResultValues OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRateLimitingResultValues OpenTelemetry.SemanticConventions.AspnetcoreAttributes.AspnetcoreRoutingMatchStatusValues OpenTelemetry.SemanticConventions.AwsAttributes OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues +OpenTelemetry.SemanticConventions.AzAttributes OpenTelemetry.SemanticConventions.BrowserAttributes +OpenTelemetry.SemanticConventions.CicdAttributes +OpenTelemetry.SemanticConventions.CicdAttributes.CicdPipelineTaskTypeValues OpenTelemetry.SemanticConventions.ClientAttributes OpenTelemetry.SemanticConventions.CloudAttributes OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues @@ -895,13 +1004,17 @@ OpenTelemetry.SemanticConventions.CloudeventsAttributes OpenTelemetry.SemanticConventions.CodeAttributes OpenTelemetry.SemanticConventions.ContainerAttributes OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues +OpenTelemetry.SemanticConventions.CpuAttributes +OpenTelemetry.SemanticConventions.CpuAttributes.CpuModeValues OpenTelemetry.SemanticConventions.DbAttributes OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues +OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValues OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues OpenTelemetry.SemanticConventions.DeploymentAttributes +OpenTelemetry.SemanticConventions.DeploymentAttributes.DeploymentStatusValues OpenTelemetry.SemanticConventions.DestinationAttributes OpenTelemetry.SemanticConventions.DeviceAttributes OpenTelemetry.SemanticConventions.DiskAttributes @@ -920,7 +1033,11 @@ OpenTelemetry.SemanticConventions.FeatureFlagAttributes OpenTelemetry.SemanticConventions.FileAttributes OpenTelemetry.SemanticConventions.GcpAttributes OpenTelemetry.SemanticConventions.GenAiAttributes +OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues +OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues +OpenTelemetry.SemanticConventions.GoAttributes +OpenTelemetry.SemanticConventions.GoAttributes.GoMemoryTypeValues OpenTelemetry.SemanticConventions.GraphqlAttributes OpenTelemetry.SemanticConventions.GraphqlAttributes.GraphqlOperationTypeValues OpenTelemetry.SemanticConventions.HerokuAttributes @@ -936,6 +1053,8 @@ OpenTelemetry.SemanticConventions.JvmAttributes OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues OpenTelemetry.SemanticConventions.K8sAttributes +OpenTelemetry.SemanticConventions.LinuxAttributes +OpenTelemetry.SemanticConventions.LinuxAttributes.LinuxMemorySlabStateValues OpenTelemetry.SemanticConventions.LogAttributes OpenTelemetry.SemanticConventions.LogAttributes.LogIostreamValues OpenTelemetry.SemanticConventions.MessageAttributes @@ -995,9 +1114,18 @@ OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessesStatusValues OpenTelemetry.SemanticConventions.SystemAttributes.SystemProcessStatusValues OpenTelemetry.SemanticConventions.TelemetryAttributes OpenTelemetry.SemanticConventions.TelemetryAttributes.TelemetrySdkLanguageValues +OpenTelemetry.SemanticConventions.TestAttributes +OpenTelemetry.SemanticConventions.TestAttributes.TestCaseResultStatusValues +OpenTelemetry.SemanticConventions.TestAttributes.TestSuiteRunStatusValues OpenTelemetry.SemanticConventions.ThreadAttributes OpenTelemetry.SemanticConventions.TlsAttributes OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues OpenTelemetry.SemanticConventions.UrlAttributes OpenTelemetry.SemanticConventions.UserAgentAttributes -OpenTelemetry.SemanticConventions.WebengineAttributes \ No newline at end of file +OpenTelemetry.SemanticConventions.UserAttributes +OpenTelemetry.SemanticConventions.V8jsAttributes +OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues +OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues +OpenTelemetry.SemanticConventions.VcsAttributes +OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues +OpenTelemetry.SemanticConventions.WebengineAttributes diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs new file mode 100644 index 0000000000..04cc367c16 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs @@ -0,0 +1,67 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ArtifactAttributes +{ + /// + /// The provenance filename of the built attestation which directly relates to the build artifact filename. This filename SHOULD accompany the artifact at publish time. See the SLSA Relationship specification for more information + /// + public const string AttributeArtifactAttestationFilename = "artifact.attestation.filename"; + + /// + /// The full hash value (see glossary), of the built attestation. Some envelopes in the software attestation space also refer to this as the digest + /// + public const string AttributeArtifactAttestationHash = "artifact.attestation.hash"; + + /// + /// The id of the build software attestation + /// + public const string AttributeArtifactAttestationId = "artifact.attestation.id"; + + /// + /// The human readable file name of the artifact, typically generated during build and release processes. Often includes the package name and version in the file name + /// + /// + /// This file name can also act as the Package Name + /// in cases where the package ecosystem maps accordingly. + /// Additionally, the artifact can be published + /// for others, but that is not a guarantee + /// + public const string AttributeArtifactFilename = "artifact.filename"; + + /// + /// The full hash value (see glossary), often found in checksum.txt on a release of the artifact and used to verify package integrity + /// + /// + /// The specific algorithm used to create the cryptographic hash value is + /// not defined. In situations where an artifact has multiple + /// cryptographic hashes, it is up to the implementer to choose which + /// hash value to set here; this should be the most secure hash algorithm + /// that is suitable for the situation and consistent with the + /// corresponding attestation. The implementer can then provide the other + /// hash values through an additional set of attribute extensions as they + /// deem necessary + /// + public const string AttributeArtifactHash = "artifact.hash"; + + /// + /// The Package URL of the package artifact provides a standard way to identify and locate the packaged artifact + /// + public const string AttributeArtifactPurl = "artifact.purl"; + + /// + /// The version of the artifact + /// + public const string AttributeArtifactVersion = "artifact.version"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs new file mode 100644 index 0000000000..c0d96104b7 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class AzAttributes +{ + /// + /// The unique identifier of the service request. It's generated by the Azure service and returned with the response + /// + public const string AttributeAzServiceRequestId = "az.service_request_id"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs new file mode 100644 index 0000000000..447fa09887 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs @@ -0,0 +1,67 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class CicdAttributes +{ + /// + /// The human readable name of the pipeline within a CI/CD system + /// + public const string AttributeCicdPipelineName = "cicd.pipeline.name"; + + /// + /// The unique identifier of a pipeline run within a CI/CD system + /// + public const string AttributeCicdPipelineRunId = "cicd.pipeline.run.id"; + + /// + /// The human readable name of a task within a pipeline. Task here most closely aligns with a computing process in a pipeline. Other terms for tasks include commands, steps, and procedures + /// + public const string AttributeCicdPipelineTaskName = "cicd.pipeline.task.name"; + + /// + /// The unique identifier of a task run within a pipeline + /// + public const string AttributeCicdPipelineTaskRunId = "cicd.pipeline.task.run.id"; + + /// + /// The URL of the pipeline run providing the complete address in order to locate and identify the pipeline run + /// + public const string AttributeCicdPipelineTaskRunUrlFull = "cicd.pipeline.task.run.url.full"; + + /// + /// The type of the task within a pipeline + /// + public const string AttributeCicdPipelineTaskType = "cicd.pipeline.task.type"; + + /// + /// The type of the task within a pipeline + /// + public static class CicdPipelineTaskTypeValues + { + /// + /// build + /// + public const string Build = "build"; + + /// + /// test + /// + public const string Test = "test"; + + /// + /// deploy + /// + public const string Deploy = "deploy"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs index dc96f362c7..5906c9d812 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs @@ -62,7 +62,7 @@ public static class CloudAttributes ///
  • AWS Lambda: The function ARN. /// Take care not to use the "invoked ARN" directly but replace any /// alias suffix - /// with the resolved function version, as the same runtime instance may be invokable with + /// with the resolved function version, as the same runtime instance may be invocable with /// multiple different aliases.
  • ///
  • GCP: The URI of the resource
  • ///
  • Azure: The Fully Qualified Resource ID of the invoked function, diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs index 2476dd9440..cd4bd4e3e3 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs @@ -33,8 +33,9 @@ public static class ContainerAttributes public const string AttributeContainerCommandLine = "container.command_line"; /// - /// The CPU state for this data point + /// Deprecated, use cpu.mode instead /// + [Obsolete("Replaced by cpu.mode")] public const string AttributeContainerCpuState = "container.cpu.state"; /// @@ -92,23 +93,26 @@ public static class ContainerAttributes public const string AttributeContainerRuntime = "container.runtime"; /// - /// The CPU state for this data point + /// Deprecated, use cpu.mode instead /// public static class ContainerCpuStateValues { /// /// When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows) /// + [Obsolete("Replaced by cpu.mode")] public const string User = "user"; /// /// When CPU is used by the system (host OS) /// + [Obsolete("Replaced by cpu.mode")] public const string System = "system"; /// /// When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows) /// + [Obsolete("Replaced by cpu.mode")] public const string Kernel = "kernel"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs new file mode 100644 index 0000000000..9e04aee7cf --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs @@ -0,0 +1,67 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class CpuAttributes +{ + /// + /// The mode of the CPU + /// + public const string AttributeCpuMode = "cpu.mode"; + + /// + /// The mode of the CPU + /// + public static class CpuModeValues + { + /// + /// user + /// + public const string User = "user"; + + /// + /// system + /// + public const string System = "system"; + + /// + /// nice + /// + public const string Nice = "nice"; + + /// + /// idle + /// + public const string Idle = "idle"; + + /// + /// iowait + /// + public const string Iowait = "iowait"; + + /// + /// interrupt + /// + public const string Interrupt = "interrupt"; + + /// + /// steal + /// + public const string Steal = "steal"; + + /// + /// kernel + /// + public const string Kernel = "kernel"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs index 3ca71b84ff..7f728af41a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs @@ -51,21 +51,34 @@ public static class DbAttributes public const string AttributeDbCassandraTable = "db.cassandra.table"; /// - /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation should use a combination of server.address and server.port attributes formatted as server.address:server.port + /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation SHOULD use a combination of parameters that would make the name unique, for example, combining attributes server.address, server.port, and db.namespace, formatted as server.address:server.port/db.namespace. Instrumentations that generate connection pool name following different patterns SHOULD document it /// - public const string AttributeDbClientConnectionsPoolName = "db.client.connections.pool.name"; + public const string AttributeDbClientConnectionPoolName = "db.client.connection.pool.name"; /// /// The state of a connection in the pool /// + public const string AttributeDbClientConnectionState = "db.client.connection.state"; + + /// + /// Deprecated, use db.client.connection.pool.name instead + /// + [Obsolete("Replaced by db.client.connection.pool.name")] + public const string AttributeDbClientConnectionsPoolName = "db.client.connections.pool.name"; + + /// + /// Deprecated, use db.client.connection.state instead + /// + [Obsolete("Replaced by db.client.connection.state")] public const string AttributeDbClientConnectionsState = "db.client.connections.state"; /// /// The name of a collection (table, container) within the database /// /// - /// If the collection name is parsed from the query, it SHOULD match the value provided in the query and may be qualified with the schema and database name. - /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization + /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. + /// If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. + /// For batch operations, if the individual operations are known to have the same collection name then that collection name SHOULD be used, otherwise db.collection.name SHOULD NOT be captured /// public const string AttributeDbCollectionName = "db.collection.name"; @@ -117,8 +130,9 @@ public static class DbAttributes public const string AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code"; /// - /// Represents the identifier of an Elasticsearch cluster + /// Deprecated, use db.namespace instead /// + [Obsolete("Replaced by db.namespace")] public const string AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name"; /// @@ -180,16 +194,26 @@ public static class DbAttributes [Obsolete("Replaced by db.operation.name")] public const string AttributeDbOperation = "db.operation"; + /// + /// The number of queries included in a batch operation + /// + /// + /// Operations are only considered batches when they contain two or more operations, and so db.operation.batch.size SHOULD never be 1 + /// + public const string AttributeDbOperationBatchSize = "db.operation.batch.size"; + /// /// The name of the operation or command being executed /// /// - /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization + /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. + /// If the operation name is parsed from the query text, it SHOULD be the first operation name found in the query. + /// For batch operations, if the individual operations are known to have the same operation name then that operation name SHOULD be used prepended by BATCH , otherwise db.operation.name SHOULD be BATCH or some other database system specific term if more applicable /// public const string AttributeDbOperationName = "db.operation.name"; /// - /// The query parameters used in db.query.text, with being the parameter name, and the attribute value being the parameter value + /// A query parameter used in db.query.text, with being the parameter name, and the attribute value being a string representation of the parameter value /// /// /// Query parameters should only be captured when db.query.text is parameterized with placeholders. @@ -200,6 +224,11 @@ public static class DbAttributes /// /// The database query being executed /// + /// + /// For sanitization see Sanitization of db.query.text. + /// For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator ; or some other database system specific separator if more applicable. + /// Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk + /// public const string AttributeDbQueryText = "db.query.text"; /// @@ -298,16 +327,34 @@ public static class DbCassandraConsistencyLevelValues /// /// The state of a connection in the pool /// + public static class DbClientConnectionStateValues + { + /// + /// idle + /// + public const string Idle = "idle"; + + /// + /// used + /// + public const string Used = "used"; + } + + /// + /// Deprecated, use db.client.connection.state instead + /// public static class DbClientConnectionsStateValues { /// /// idle /// + [Obsolete("Replaced by db.client.connection.state")] public const string Idle = "idle"; /// /// used /// + [Obsolete("Replaced by db.client.connection.state")] public const string Used = "used"; } @@ -419,79 +466,74 @@ public static class DbSystemValues public const string OtherSql = "other_sql"; /// - /// Microsoft SQL Server - /// - public const string Mssql = "mssql"; - - /// - /// Microsoft SQL Server Compact + /// Adabas (Adaptable Database System) /// - public const string Mssqlcompact = "mssqlcompact"; + public const string Adabas = "adabas"; /// - /// MySQL + /// Deprecated, use intersystems_cache instead /// - public const string Mysql = "mysql"; + public const string Cache = "cache"; /// - /// Oracle Database + /// InterSystems Caché /// - public const string Oracle = "oracle"; + public const string IntersystemsCache = "intersystems_cache"; /// - /// IBM Db2 + /// Apache Cassandra /// - public const string Db2 = "db2"; + public const string Cassandra = "cassandra"; /// - /// PostgreSQL + /// ClickHouse /// - public const string Postgresql = "postgresql"; + public const string Clickhouse = "clickhouse"; /// - /// Amazon Redshift + /// Deprecated, use other_sql instead /// - public const string Redshift = "redshift"; + public const string Cloudscape = "cloudscape"; /// - /// Apache Hive + /// CockroachDB /// - public const string Hive = "hive"; + public const string Cockroachdb = "cockroachdb"; /// - /// Cloudscape + /// Deprecated, no replacement at this time /// - public const string Cloudscape = "cloudscape"; + public const string Coldfusion = "coldfusion"; /// - /// HyperSQL DataBase + /// Microsoft Azure Cosmos DB /// - public const string Hsqldb = "hsqldb"; + public const string Cosmosdb = "cosmosdb"; /// - /// Progress Database + /// Couchbase /// - public const string Progress = "progress"; + public const string Couchbase = "couchbase"; /// - /// SAP MaxDB + /// CouchDB /// - public const string Maxdb = "maxdb"; + public const string Couchdb = "couchdb"; /// - /// SAP HANA + /// IBM Db2 /// - public const string Hanadb = "hanadb"; + public const string Db2 = "db2"; /// - /// Ingres + /// Apache Derby /// - public const string Ingres = "ingres"; + public const string Derby = "derby"; /// - /// FirstSQL + /// Amazon DynamoDB /// - public const string Firstsql = "firstsql"; + public const string Dynamodb = "dynamodb"; /// /// EnterpriseDB @@ -499,14 +541,14 @@ public static class DbSystemValues public const string Edb = "edb"; /// - /// InterSystems Caché + /// Elasticsearch /// - public const string Cache = "cache"; + public const string Elasticsearch = "elasticsearch"; /// - /// Adabas (Adaptable Database System) + /// FileMaker /// - public const string Adabas = "adabas"; + public const string Filemaker = "filemaker"; /// /// Firebird @@ -514,163 +556,178 @@ public static class DbSystemValues public const string Firebird = "firebird"; /// - /// Apache Derby + /// Deprecated, use other_sql instead /// - public const string Derby = "derby"; + public const string Firstsql = "firstsql"; /// - /// FileMaker + /// Apache Geode /// - public const string Filemaker = "filemaker"; + public const string Geode = "geode"; /// - /// Informix + /// H2 /// - public const string Informix = "informix"; + public const string H2 = "h2"; /// - /// InstantDB + /// SAP HANA /// - public const string Instantdb = "instantdb"; + public const string Hanadb = "hanadb"; /// - /// InterBase + /// Apache HBase /// - public const string Interbase = "interbase"; + public const string Hbase = "hbase"; /// - /// MariaDB + /// Apache Hive /// - public const string Mariadb = "mariadb"; + public const string Hive = "hive"; /// - /// Netezza + /// HyperSQL DataBase /// - public const string Netezza = "netezza"; + public const string Hsqldb = "hsqldb"; /// - /// Pervasive PSQL + /// InfluxDB /// - public const string Pervasive = "pervasive"; + public const string Influxdb = "influxdb"; /// - /// PointBase + /// Informix /// - public const string Pointbase = "pointbase"; + public const string Informix = "informix"; /// - /// SQLite + /// Ingres /// - public const string Sqlite = "sqlite"; + public const string Ingres = "ingres"; /// - /// Sybase + /// InstantDB /// - public const string Sybase = "sybase"; + public const string Instantdb = "instantdb"; /// - /// Teradata + /// InterBase /// - public const string Teradata = "teradata"; + public const string Interbase = "interbase"; /// - /// Vertica + /// MariaDB /// - public const string Vertica = "vertica"; + public const string Mariadb = "mariadb"; /// - /// H2 + /// SAP MaxDB /// - public const string H2 = "h2"; + public const string Maxdb = "maxdb"; /// - /// ColdFusion IMQ + /// Memcached /// - public const string Coldfusion = "coldfusion"; + public const string Memcached = "memcached"; /// - /// Apache Cassandra + /// MongoDB /// - public const string Cassandra = "cassandra"; + public const string Mongodb = "mongodb"; /// - /// Apache HBase + /// Microsoft SQL Server /// - public const string Hbase = "hbase"; + public const string Mssql = "mssql"; /// - /// MongoDB + /// Deprecated, Microsoft SQL Server Compact is discontinued /// - public const string Mongodb = "mongodb"; + public const string Mssqlcompact = "mssqlcompact"; /// - /// Redis + /// MySQL /// - public const string Redis = "redis"; + public const string Mysql = "mysql"; /// - /// Couchbase + /// Neo4j /// - public const string Couchbase = "couchbase"; + public const string Neo4j = "neo4j"; /// - /// CouchDB + /// Netezza /// - public const string Couchdb = "couchdb"; + public const string Netezza = "netezza"; /// - /// Microsoft Azure Cosmos DB + /// OpenSearch /// - public const string Cosmosdb = "cosmosdb"; + public const string Opensearch = "opensearch"; /// - /// Amazon DynamoDB + /// Oracle Database /// - public const string Dynamodb = "dynamodb"; + public const string Oracle = "oracle"; /// - /// Neo4j + /// Pervasive PSQL /// - public const string Neo4j = "neo4j"; + public const string Pervasive = "pervasive"; /// - /// Apache Geode + /// PointBase /// - public const string Geode = "geode"; + public const string Pointbase = "pointbase"; /// - /// Elasticsearch + /// PostgreSQL /// - public const string Elasticsearch = "elasticsearch"; + public const string Postgresql = "postgresql"; /// - /// Memcached + /// Progress Database /// - public const string Memcached = "memcached"; + public const string Progress = "progress"; /// - /// CockroachDB + /// Redis /// - public const string Cockroachdb = "cockroachdb"; + public const string Redis = "redis"; /// - /// OpenSearch + /// Amazon Redshift /// - public const string Opensearch = "opensearch"; + public const string Redshift = "redshift"; /// - /// ClickHouse + /// Cloud Spanner /// - public const string Clickhouse = "clickhouse"; + public const string Spanner = "spanner"; /// - /// Cloud Spanner + /// SQLite /// - public const string Spanner = "spanner"; + public const string Sqlite = "sqlite"; + + /// + /// Sybase + /// + public const string Sybase = "sybase"; + + /// + /// Teradata + /// + public const string Teradata = "teradata"; /// /// Trino /// public const string Trino = "trino"; + + /// + /// Vertica + /// + public const string Vertica = "vertica"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs index 048d733ccb..7119853d88 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs @@ -14,19 +14,56 @@ namespace OpenTelemetry.SemanticConventions; /// public static class DeploymentAttributes { + /// + /// 'Deprecated, use deployment.environment.name instead.' + /// + [Obsolete("Deprecated, use deployment.environment.name instead")] + public const string AttributeDeploymentEnvironment = "deployment.environment"; + /// /// Name of the deployment environment (aka deployment tier) /// /// - /// deployment.environment does not affect the uniqueness constraints defined through + /// deployment.environment.name does not affect the uniqueness constraints defined through /// the service.namespace, service.name and service.instance.id resource attributes. /// This implies that resources carrying the following attribute combinations MUST be /// considered to be identifying the same service: ///

    ///

      - ///
    • service.name=frontend, deployment.environment=production
    • - ///
    • service.name=frontend, deployment.environment=staging
    • + ///
    • service.name=frontend, deployment.environment.name=production
    • + ///
    • service.name=frontend, deployment.environment.name=staging
    • ///
    ///
    - public const string AttributeDeploymentEnvironment = "deployment.environment"; + public const string AttributeDeploymentEnvironmentName = "deployment.environment.name"; + + /// + /// The id of the deployment + /// + public const string AttributeDeploymentId = "deployment.id"; + + /// + /// The name of the deployment + /// + public const string AttributeDeploymentName = "deployment.name"; + + /// + /// The status of the deployment + /// + public const string AttributeDeploymentStatus = "deployment.status"; + + /// + /// The status of the deployment + /// + public static class DeploymentStatusValues + { + /// + /// failed + /// + public const string Failed = "failed"; + + /// + /// succeeded + /// + public const string Succeeded = "succeeded"; + } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs index 5153558c13..de53dabda3 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs @@ -15,17 +15,20 @@ namespace OpenTelemetry.SemanticConventions; public static class EnduserAttributes { /// - /// Username or client_id extracted from the access token or Authorization header in the inbound request from outside the system + /// Deprecated, use user.id instead /// + [Obsolete("Replaced by user.id attribute")] public const string AttributeEnduserId = "enduser.id"; /// - /// Actual/assumed role the client is making the request under extracted from token or application security context + /// Deprecated, use user.roles instead /// + [Obsolete("Replaced by user.roles attribute")] public const string AttributeEnduserRole = "enduser.role"; /// - /// Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an OAuth 2.0 Access Token or an attribute value in a SAML 2.0 Assertion + /// Deprecated, no replacement at this time /// + [Obsolete("Removed")] public const string AttributeEnduserScope = "enduser.scope"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs index e8885e84d5..2714806e25 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs @@ -18,7 +18,7 @@ public static class EventAttributes /// Identifies the class / type of event ///
    /// - /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes + /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes /// public const string AttributeEventName = "event.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs index f1a3601af5..2dedab1196 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs @@ -14,6 +14,14 @@ namespace OpenTelemetry.SemanticConventions; ///
    public static class GcpAttributes { + /// + /// Identifies the Google Cloud service for which the official client library is intended + /// + /// + /// Intended to be a stable identifier for Google Cloud client libraries that is uniform across implementation languages. The value should be derived from the canonical service domain for the service; for example, 'foo.googleapis.com' should result in a value of 'foo' + /// + public const string AttributeGcpClientService = "gcp.client.service"; + /// /// The name of the Cloud Run execution being run for the Job, as set by the CLOUD_RUN_EXECUTION environment variable /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs index b335bf6444..a100c1f1e3 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class GenAiAttributes { /// - /// The full response received from the LLM + /// The full response received from the GenAI model /// /// /// It's RECOMMENDED to format completions as JSON string matching OpenAI messages format @@ -23,7 +23,15 @@ public static class GenAiAttributes public const string AttributeGenAiCompletion = "gen_ai.completion"; /// - /// The full prompt sent to an LLM + /// The name of the operation being performed + /// + /// + /// If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value + /// + public const string AttributeGenAiOperationName = "gen_ai.operation.name"; + + /// + /// The full prompt sent to the GenAI model /// /// /// It's RECOMMENDED to format prompts as JSON string matching OpenAI messages format @@ -31,22 +39,42 @@ public static class GenAiAttributes public const string AttributeGenAiPrompt = "gen_ai.prompt"; /// - /// The maximum number of tokens the LLM generates for a request + /// The frequency penalty setting for the GenAI request + /// + public const string AttributeGenAiRequestFrequencyPenalty = "gen_ai.request.frequency_penalty"; + + /// + /// The maximum number of tokens the model generates for a request /// public const string AttributeGenAiRequestMaxTokens = "gen_ai.request.max_tokens"; /// - /// The name of the LLM a request is being made to + /// The name of the GenAI model a request is being made to /// public const string AttributeGenAiRequestModel = "gen_ai.request.model"; /// - /// The temperature setting for the LLM request + /// The presence penalty setting for the GenAI request + /// + public const string AttributeGenAiRequestPresencePenalty = "gen_ai.request.presence_penalty"; + + /// + /// List of sequences that the model will use to stop generating further tokens + /// + public const string AttributeGenAiRequestStopSequences = "gen_ai.request.stop_sequences"; + + /// + /// The temperature setting for the GenAI request /// public const string AttributeGenAiRequestTemperature = "gen_ai.request.temperature"; /// - /// The top_p sampling setting for the LLM request + /// The top_k sampling setting for the GenAI request + /// + public const string AttributeGenAiRequestTopK = "gen_ai.request.top_k"; + + /// + /// The top_p sampling setting for the GenAI request /// public const string AttributeGenAiRequestTopP = "gen_ai.request.top_p"; @@ -61,30 +89,71 @@ public static class GenAiAttributes public const string AttributeGenAiResponseId = "gen_ai.response.id"; /// - /// The name of the LLM a response was generated from + /// The name of the model that generated the response /// public const string AttributeGenAiResponseModel = "gen_ai.response.model"; /// - /// The Generative AI product as identified by the client instrumentation + /// The Generative AI product as identified by the client or server instrumentation /// /// - /// The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the gen_ai.system is set to openai based on the instrumentation's best knowledge + /// The gen_ai.system describes a family of GenAI models with specific model identified + /// by gen_ai.request.model and gen_ai.response.model attributes. + ///

    + /// The actual GenAI product may differ from the one identified by the client. + /// For example, when using OpenAI client libraries to communicate with Mistral, the gen_ai.system + /// is set to openai based on the instrumentation's best knowledge. + ///

    + /// For custom model, a custom friendly name SHOULD be used. + /// If none of these options apply, the gen_ai.system SHOULD be set to _OTHER /// public const string AttributeGenAiSystem = "gen_ai.system"; ///

    - /// The number of tokens used in the LLM response (completion) + /// The type of token being counted /// + public const string AttributeGenAiTokenType = "gen_ai.token.type"; + + /// + /// Deprecated, use gen_ai.usage.output_tokens instead + /// + [Obsolete("Replaced by gen_ai.usage.output_tokens attribute")] public const string AttributeGenAiUsageCompletionTokens = "gen_ai.usage.completion_tokens"; /// - /// The number of tokens used in the LLM prompt + /// The number of tokens used in the GenAI input (prompt) + /// + public const string AttributeGenAiUsageInputTokens = "gen_ai.usage.input_tokens"; + + /// + /// The number of tokens used in the GenAI response (completion) /// + public const string AttributeGenAiUsageOutputTokens = "gen_ai.usage.output_tokens"; + + /// + /// Deprecated, use gen_ai.usage.input_tokens instead + /// + [Obsolete("Replaced by gen_ai.usage.input_tokens attribute")] public const string AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens"; /// - /// The Generative AI product as identified by the client instrumentation + /// The name of the operation being performed + /// + public static class GenAiOperationNameValues + { + /// + /// Chat completion operation such as OpenAI Chat API + /// + public const string Chat = "chat"; + + /// + /// Text completions operation such as OpenAI Completions API (Legacy) + /// + public const string TextCompletion = "text_completion"; + } + + /// + /// The Generative AI product as identified by the client or server instrumentation /// public static class GenAiSystemValues { @@ -92,5 +161,36 @@ public static class GenAiSystemValues /// OpenAI ///
    public const string Openai = "openai"; + + /// + /// Vertex AI + /// + public const string VertexAi = "vertex_ai"; + + /// + /// Anthropic + /// + public const string Anthropic = "anthropic"; + + /// + /// Cohere + /// + public const string Cohere = "cohere"; + } + + /// + /// The type of token being counted + /// + public static class GenAiTokenTypeValues + { + /// + /// Input tokens (prompt, input, etc.) + /// + public const string Input = "input"; + + /// + /// Output tokens (completion, response, etc.) + /// + public const string Completion = "output"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs new file mode 100644 index 0000000000..847f8f1df7 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class GoAttributes +{ + /// + /// The type of memory + /// + public const string AttributeGoMemoryType = "go.memory.type"; + + /// + /// The type of memory + /// + public static class GoMemoryTypeValues + { + /// + /// Memory allocated from the heap that is reserved for stack space, whether or not it is currently in-use + /// + public const string Stack = "stack"; + + /// + /// Memory used by the Go runtime, excluding other categories of memory usage described in this enumeration + /// + public const string Other = "other"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs new file mode 100644 index 0000000000..a93e9712ca --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class LinuxAttributes +{ + /// + /// The Linux Slab memory state + /// + public const string AttributeLinuxMemorySlabState = "linux.memory.slab.state"; + + /// + /// The Linux Slab memory state + /// + public static class LinuxMemorySlabStateValues + { + /// + /// reclaimable + /// + public const string Reclaimable = "reclaimable"; + + /// + /// unreclaimable + /// + public const string Unreclaimable = "unreclaimable"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs index 6ac9fc3706..c0ad17a9ed 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs @@ -39,6 +39,14 @@ public static class LogAttributes ///
    public const string AttributeLogIostream = "log.iostream"; + /// + /// The complete orignal Log Record + /// + /// + /// This value MAY be added when processing a Log Record which was originally transmitted as a string or equivalent data type AND the Body field of the Log Record does not contain the same value. (e.g. a syslog or a log record read from a file.) + /// + public const string AttributeLogRecordOriginal = "log.record.original"; + /// /// A unique identifier for the Log Record /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs index ba9a5dc46a..b3851d2ad3 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs @@ -27,6 +27,14 @@ public static class MessagingAttributes ///
  • public const string AttributeMessagingClientId = "messaging.client.id"; + /// + /// The name of the consumer group with which a consumer is associated + /// + /// + /// Semantic conventions for individual messaging systems SHOULD document whether messaging.consumer.group.name is applicable and what it means in the context of that system + /// + public const string AttributeMessagingConsumerGroupName = "messaging.consumer.group.name"; + /// /// A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name) /// @@ -46,6 +54,14 @@ public static class MessagingAttributes ///
    public const string AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id"; + /// + /// The name of the destination subscription from which a message is consumed + /// + /// + /// Semantic conventions for individual messaging systems SHOULD document whether messaging.destination.subscription.name is applicable and what it means in the context of that system + /// + public const string AttributeMessagingDestinationSubscriptionName = "messaging.destination.subscription.name"; + /// /// Low cardinality representation of the messaging destination name /// @@ -60,22 +76,21 @@ public static class MessagingAttributes public const string AttributeMessagingDestinationTemporary = "messaging.destination.temporary"; /// - /// A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name) + /// Deprecated, no replacement at this time /// + [Obsolete("No replacement at this time")] public const string AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous"; /// - /// The name of the original destination the message was published to + /// Deprecated, no replacement at this time /// - /// - /// The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If - /// the broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker - /// + [Obsolete("No replacement at this time")] public const string AttributeMessagingDestinationPublishName = "messaging.destination_publish.name"; /// - /// The name of the consumer group the event consumer is associated with + /// Deprecated, use messaging.consumer.group.name instead /// + [Obsolete("Replaced by messaging.consumer.group.name")] public const string AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group"; /// @@ -104,8 +119,9 @@ public static class MessagingAttributes public const string AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key"; /// - /// Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers + /// Deprecated, use messaging.consumer.group.name instead /// + [Obsolete("Replaced by messaging.consumer.group.name")] public const string AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; /// @@ -123,8 +139,9 @@ public static class MessagingAttributes public const string AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key"; /// - /// The offset of a record in the corresponding Kafka partition + /// Deprecated, use messaging.kafka.offset instead /// + [Obsolete("Replaced by messaging.kafka.offset")] public const string AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; /// @@ -132,6 +149,11 @@ public static class MessagingAttributes /// public const string AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone"; + /// + /// The offset of a record in the corresponding Kafka partition + /// + public const string AttributeMessagingKafkaOffset = "messaging.kafka.offset"; + /// /// The size of the message body in bytes /// @@ -190,8 +212,9 @@ public static class MessagingAttributes public const string AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag"; /// - /// Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind + /// Deprecated, use messaging.consumer.group.name instead /// + [Obsolete("Replaced by messaging.consumer.group.name on the consumer spans. No replacement for producer spans")] public const string AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group"; /// @@ -235,8 +258,9 @@ public static class MessagingAttributes public const string AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; /// - /// The name of the subscription in the topic messages are received from + /// Deprecated, use messaging.servicebus.destination.subscription_name instead /// + [Obsolete("Replaced by messaging.servicebus.destination.subscription_name")] public const string AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name"; /// @@ -283,14 +307,19 @@ public static class MessagingOperationTypeValues public const string Receive = "receive"; /// - /// One or more messages are delivered to or processed by a consumer + /// One or more messages are processed by a consumer /// - public const string Deliver = "process"; + public const string Process = "process"; /// /// One or more messages are settled /// public const string Settle = "settle"; + + /// + /// Deprecated. Use process instead + /// + public const string Deliver = "deliver"; } /// @@ -415,5 +444,10 @@ public static class MessagingSystemValues /// Apache RocketMQ /// public const string Rocketmq = "rocketmq"; + + /// + /// Apache Pulsar + /// + public const string Pulsar = "pulsar"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs index 7bf9321337..ef64321563 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs @@ -287,6 +287,11 @@ public static class NetworkTransportValues /// Unix domain socket /// public const string Unix = "unix"; + + /// + /// QUIC + /// + public const string Quic = "quic"; } /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs index 025f142845..4be44a0190 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs @@ -15,26 +15,26 @@ namespace OpenTelemetry.SemanticConventions; public static class OtherAttributes { /// - /// Deprecated, use db.client.connections.state instead + /// Deprecated, use db.client.connection.state instead /// - [Obsolete("Replaced by db.client.connections.state")] + [Obsolete("Replaced by db.client.connection.state")] public const string AttributeState = "state"; /// - /// Deprecated, use db.client.connections.state instead + /// Deprecated, use db.client.connection.state instead /// public static class StateValues { /// /// idle /// - [Obsolete("Replaced by db.client.connections.state")] + [Obsolete("Replaced by db.client.connection.state")] public const string Idle = "idle"; /// /// used /// - [Obsolete("Replaced by db.client.connections.state")] + [Obsolete("Replaced by db.client.connection.state")] public const string Used = "used"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs index f09530bc5a..1d791b869b 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs @@ -15,8 +15,8 @@ namespace OpenTelemetry.SemanticConventions; public static class PoolAttributes { /// - /// Deprecated, use db.client.connections.pool.name instead + /// Deprecated, use db.client.connection.pool.name instead /// - [Obsolete("Replaced by db.client.connections.pool.name")] + [Obsolete("Replaced by db.client.connection.pool.name")] public const string AttributePoolName = "pool.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs index 46c32087eb..17273e200a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs @@ -35,8 +35,9 @@ public static class ProcessAttributes public const string AttributeProcessContextSwitchType = "process.context_switch_type"; /// - /// The CPU state of the process + /// Deprecated, use cpu.mode instead /// + [Obsolete("Replaced by cpu.mode")] public const string AttributeProcessCpuState = "process.cpu.state"; /// @@ -110,7 +111,7 @@ public static class ProcessAttributes public const string AttributeProcessRuntimeDescription = "process.runtime.description"; /// - /// The name of the runtime of this process. For compiled native binaries, this SHOULD be the name of the compiler + /// The name of the runtime of this process /// public const string AttributeProcessRuntimeName = "process.runtime.name"; @@ -169,23 +170,26 @@ public static class ProcessContextSwitchTypeValues } /// - /// The CPU state of the process + /// Deprecated, use cpu.mode instead /// public static class ProcessCpuStateValues { /// /// system /// + [Obsolete("Replaced by cpu.mode")] public const string System = "system"; /// /// user /// + [Obsolete("Replaced by cpu.mode")] public const string User = "user"; /// /// wait /// + [Obsolete("Replaced by cpu.mode")] public const string Wait = "wait"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs index d16c46b2e5..8cac7b5d53 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs @@ -20,8 +20,9 @@ public static class SystemAttributes public const string AttributeSystemCpuLogicalNumber = "system.cpu.logical_number"; /// - /// The state of the CPU + /// Deprecated, use cpu.mode instead /// + [Obsolete("Replaced by cpu.mode")] public const string AttributeSystemCpuState = "system.cpu.state"; /// @@ -86,43 +87,50 @@ public static class SystemAttributes public const string AttributeSystemProcessesStatus = "system.processes.status"; /// - /// The state of the CPU + /// Deprecated, use cpu.mode instead /// public static class SystemCpuStateValues { /// /// user /// + [Obsolete("Replaced by cpu.mode")] public const string User = "user"; /// /// system /// + [Obsolete("Replaced by cpu.mode")] public const string System = "system"; /// /// nice /// + [Obsolete("Replaced by cpu.mode")] public const string Nice = "nice"; /// /// idle /// + [Obsolete("Replaced by cpu.mode")] public const string Idle = "idle"; /// /// iowait /// + [Obsolete("Replaced by cpu.mode")] public const string Iowait = "iowait"; /// /// interrupt /// + [Obsolete("Replaced by cpu.mode")] public const string Interrupt = "interrupt"; /// /// steal /// + [Obsolete("Replaced by cpu.mode")] public const string Steal = "steal"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs new file mode 100644 index 0000000000..6eae4b3f2a --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs @@ -0,0 +1,88 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class TestAttributes +{ + /// + /// The fully qualified human readable name of the test case + /// + public const string AttributeTestCaseName = "test.case.name"; + + /// + /// The status of the actual test case result from test execution + /// + public const string AttributeTestCaseResultStatus = "test.case.result.status"; + + /// + /// The human readable name of a test suite + /// + public const string AttributeTestSuiteName = "test.suite.name"; + + /// + /// The status of the test suite run + /// + public const string AttributeTestSuiteRunStatus = "test.suite.run.status"; + + /// + /// The status of the actual test case result from test execution + /// + public static class TestCaseResultStatusValues + { + /// + /// pass + /// + public const string Pass = "pass"; + + /// + /// fail + /// + public const string Fail = "fail"; + } + + /// + /// The status of the test suite run + /// + public static class TestSuiteRunStatusValues + { + /// + /// success + /// + public const string Success = "success"; + + /// + /// failure + /// + public const string Failure = "failure"; + + /// + /// skipped + /// + public const string Skipped = "skipped"; + + /// + /// aborted + /// + public const string Aborted = "aborted"; + + /// + /// timed_out + /// + public const string TimedOut = "timed_out"; + + /// + /// in_progress + /// + public const string InProgress = "in_progress"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs index 5d1d75a9ce..87351db7ba 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs @@ -68,8 +68,9 @@ public static class TlsAttributes public const string AttributeTlsClientNotBefore = "tls.client.not_before"; /// - /// Also called an SNI, this tells the server which hostname to which the client is attempting to connect to + /// Deprecated, use server.address instead /// + [Obsolete("Replaced by `server.address")] public const string AttributeTlsClientServerName = "tls.client.server_name"; /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs new file mode 100644 index 0000000000..eff0f4754a --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class UserAttributes +{ + /// + /// User email address + /// + public const string AttributeUserEmail = "user.email"; + + /// + /// User's full name + /// + public const string AttributeUserFullName = "user.full_name"; + + /// + /// Unique user hash to correlate information for a user in anonymized form + /// + /// + /// Useful if user.id or user.name contain confidential information and cannot be used + /// + public const string AttributeUserHash = "user.hash"; + + /// + /// Unique identifier of the user + /// + public const string AttributeUserId = "user.id"; + + /// + /// Short name or login/username of the user + /// + public const string AttributeUserName = "user.name"; + + /// + /// Array of user roles at the time of the event + /// + public const string AttributeUserRoles = "user.roles"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs new file mode 100644 index 0000000000..93e68417b6 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs @@ -0,0 +1,86 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class V8jsAttributes +{ + /// + /// The type of garbage collection + /// + public const string AttributeV8jsGcType = "v8js.gc.type"; + + /// + /// The name of the space type of heap memory + /// + /// + /// Value can be retrieved from value space_name of v8.getHeapSpaceStatistics() + /// + public const string AttributeV8jsHeapSpaceName = "v8js.heap.space.name"; + + /// + /// The type of garbage collection + /// + public static class V8jsGcTypeValues + { + /// + /// Major (Mark Sweep Compact) + /// + public const string Major = "major"; + + /// + /// Minor (Scavenge) + /// + public const string Minor = "minor"; + + /// + /// Incremental (Incremental Marking) + /// + public const string Incremental = "incremental"; + + /// + /// Weak Callbacks (Process Weak Callbacks) + /// + public const string Weakcb = "weakcb"; + } + + /// + /// The name of the space type of heap memory + /// + public static class V8jsHeapSpaceNameValues + { + /// + /// New memory space + /// + public const string NewSpace = "new_space"; + + /// + /// Old memory space + /// + public const string OldSpace = "old_space"; + + /// + /// Code memory space + /// + public const string CodeSpace = "code_space"; + + /// + /// Map memory space + /// + public const string MapSpace = "map_space"; + + /// + /// Large object memory space + /// + public const string LargeObjectSpace = "large_object_space"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs new file mode 100644 index 0000000000..09a595f4c6 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs @@ -0,0 +1,73 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class VcsAttributes +{ + /// + /// The ID of the change (pull request/merge request) if applicable. This is usually a unique (within repository) identifier generated by the VCS system + /// + public const string AttributeVcsRepositoryChangeId = "vcs.repository.change.id"; + + /// + /// The human readable title of the change (pull request/merge request). This title is often a brief summary of the change and may get merged in to a ref as the commit summary + /// + public const string AttributeVcsRepositoryChangeTitle = "vcs.repository.change.title"; + + /// + /// The name of the reference such as branch or tag in the repository + /// + public const string AttributeVcsRepositoryRefName = "vcs.repository.ref.name"; + + /// + /// The revision, literally revised version, The revision most often refers to a commit object in Git, or a revision number in SVN + /// + /// + /// The revision can be a full hash value (see glossary), + /// of the recorded change to a ref within a repository pointing to a + /// commit commit object. It does + /// not necessarily have to be a hash; it can simply define a + /// revision number + /// which is an integer that is monotonically increasing. In cases where + /// it is identical to the ref.name, it SHOULD still be included. It is + /// up to the implementer to decide which value to set as the revision + /// based on the VCS system and situational context + /// + public const string AttributeVcsRepositoryRefRevision = "vcs.repository.ref.revision"; + + /// + /// The type of the reference in the repository + /// + public const string AttributeVcsRepositoryRefType = "vcs.repository.ref.type"; + + /// + /// The URL of the repository providing the complete address in order to locate and identify the repository + /// + public const string AttributeVcsRepositoryUrlFull = "vcs.repository.url.full"; + + /// + /// The type of the reference in the repository + /// + public static class VcsRepositoryRefTypeValues + { + /// + /// branch + /// + public const string Branch = "branch"; + + /// + /// tag + /// + public const string Tag = "tag"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md index 20ab003382..29ab84bca7 100644 --- a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md +++ b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated to `v1.27.0` release of OpenTelemetry Semantic Conventions. + ([#2069](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2069)) + * Updated to `v1.26.0` release of OpenTelemetry Semantic Conventions. ([#2040](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2040)) diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 index c05f576e0a..1a4e9581f3 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 @@ -2,7 +2,7 @@ $SCRIPT_DIR = $PSScriptRoot $ROOT_DIR = "${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -$SEMCONV_VERSION="1.26.0" +$SEMCONV_VERSION="1.27.0" $GENERATOR_VERSION="v0.9.2" Set-Location $SCRIPT_DIR diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh index 226a09d8c8..a5c6c8e9c4 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh @@ -5,7 +5,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -SEMCONV_VERSION="1.26.0" +SEMCONV_VERSION="1.27.0" GENERATOR_VERSION="v0.9.2" cd ${SCRIPT_DIR} @@ -30,4 +30,4 @@ docker run --rm \ --registry=/source \ --templates=/templates \ "./" \ - "/output/./"\ \ No newline at end of file + "/output/./"\ From c55961c596a64a8972d6272784ada07682b05910 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 20 Sep 2024 13:43:34 -0700 Subject: [PATCH 1261/1499] [repo] Release request issue template & automation (#2080) --- .github/ISSUE_TEMPLATE/release_request.yml | 81 +++++++++++ .github/workflows/prepare-release.yml | 55 +++++++ build/scripts/prepare-release.psm1 | 161 ++++++++++++++++++++- opentelemetry-dotnet-contrib.sln | 1 + 4 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/release_request.yml diff --git a/.github/ISSUE_TEMPLATE/release_request.yml b/.github/ISSUE_TEMPLATE/release_request.yml new file mode 100644 index 0000000000..d7bfea1b5c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release_request.yml @@ -0,0 +1,81 @@ +name: Release request +title: "[release request] " +description: Request a release for a component +labels: ["release"] +body: + - type: markdown + attributes: + value: | + Fill out this form to request a release of one of the components in this repository. + + - type: dropdown + id: component + attributes: + label: Component + description: Which component does this release request concern? + multiple: false + options: + - OpenTelemetry.Exporter.Geneva + - OpenTelemetry.Exporter.InfluxDB + - OpenTelemetry.Exporter.Instana + - OpenTelemetry.Exporter.OneCollector + - OpenTelemetry.Exporter.Stackdriver + - OpenTelemetry.Extensions + - OpenTelemetry.Extensions.AWS + - OpenTelemetry.Extensions.Enrichment + - OpenTelemetry.Instrumentation.AspNet + - OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule + - OpenTelemetry.Instrumentation.AspNetCore + - OpenTelemetry.Instrumentation.AWS + - OpenTelemetry.Instrumentation.AWSLambda + - OpenTelemetry.Instrumentation.Cassandra + - OpenTelemetry.Instrumentation.ConfluentKafka + - OpenTelemetry.Instrumentation.ElasticsearchClient + - OpenTelemetry.Instrumentation.EntityFrameworkCore + - OpenTelemetry.Instrumentation.EventCounters + - OpenTelemetry.Instrumentation.GrpcCore + - OpenTelemetry.Instrumentation.GrpcNetClient + - OpenTelemetry.Instrumentation.Hangfire + - OpenTelemetry.Instrumentation.Http + - OpenTelemetry.Instrumentation.MassTransit + - OpenTelemetry.Instrumentation.MySqlData + - OpenTelemetry.Instrumentation.Owin + - OpenTelemetry.Instrumentation.Process + - OpenTelemetry.Instrumentation.Quartz + - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.SqlClient + - OpenTelemetry.Instrumentation.StackExchangeRedis + - OpenTelemetry.Instrumentation.Wcf + - OpenTelemetry.PersistentStorage.Abstractions + - OpenTelemetry.PersistentStorage.FileSystem + - OpenTelemetry.Resources.AWS + - OpenTelemetry.Resources.Azure + - OpenTelemetry.Resources.Container + - OpenTelemetry.Resources.Gcp + - OpenTelemetry.Resources.Host + - OpenTelemetry.Resources.OperatingSystem + - OpenTelemetry.Resources.Process + - OpenTelemetry.Resources.ProcessRuntime + - OpenTelemetry.Sampler.AWS + - OpenTelemetry.SemanticConventions + validations: + required: true + + - type: input + attributes: + label: Version + description: | + What is the requested version for the release? + Version must specify [Major].[Minor].[Patch] and may also include prerelease information -[alpha|beta|rc].[Increment]. + Examples: + * 1.9.0 + * 1.10.0-rc.1 + * 1.12.0-beta.2 + * 0.2.0-alpha.3 + validations: + required: true + + - type: textarea + attributes: + label: Additional context + description: Any additional information you think may be relevant to this release request. diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 11bc31a834..224c04ce69 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -55,11 +55,20 @@ on: type: string description: 'Release version' required: true + releaseIssue: + type: string + description: 'Release request issue' + required: false pull_request: types: - closed + issues: + types: + - opened + - edited + issue_comment: types: - created @@ -95,6 +104,7 @@ jobs: -component '${{ inputs.component }}' ` -version '${{ inputs.version }}' ` -requestedByUserName '${{ github.event.sender.login }}' ` + -releaseIssue '${{ inputs.releaseIssue }}' ` -targetBranch '${{ github.ref_name }}' ` -gitUserName '${{ needs.automation.outputs.username }}' ` -gitUserEmail '${{ needs.automation.outputs.email }}' @@ -209,3 +219,48 @@ jobs: -commentUserName '${{ github.event.comment.user.login }}' ` -gitUserName '${{ needs.automation.outputs.username }}' ` -gitUserEmail '${{ needs.automation.outputs.email }}' + + process-release-request-issue: + runs-on: ubuntu-latest + + needs: automation + + if: | + startsWith(github.event.issue.title, '[release request] ') + && github.event.issue.pull_request == null + && needs.automation.outputs.enabled + && ( + (github.event_name == 'issues') + || + (github.event_name == 'issue_comment' + && github.event.issue.state == 'open' + && contains(github.event.comment.body, '/PrepareRelease') + && github.event.comment.user.login != needs.automation.outputs.username) + ) + + 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: Process release request issue being opened or commented + shell: pwsh + run: | + Import-Module .\build\scripts\prepare-release.psm1 + + TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue ` + -gitRepository '${{ github.repository }}' ` + -targetBranch '${{ github.event.repository.default_branch }}' ` + -triggeringEventName '${{ github.event_name }}' ` + -approvingGroups '@${{ github.repository_owner }}/dotnet-approvers @${{ github.repository_owner }}/dotnet-maintainers' ` + -requestedByUserName '${{ github.event.comment.user.login || github.event.sender.login }}' ` + -issueNumber '${{ github.event.issue.number }}' ` + -issueBody $env:ISSUE_BODY ` + -gitUserName '${{ needs.automation.outputs.username }}' ` + -gitUserEmail '${{ needs.automation.outputs.email }}' + env: + ISSUE_BODY: ${{ github.event.issue.body }} diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index 8bc8c4397c..4ddde60b83 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -4,6 +4,7 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis { [Parameter(Mandatory=$true)][string]$component, [Parameter(Mandatory=$true)][string]$version, [Parameter(Mandatory=$true)][string]$requestedByUserName, + [Parameter()][string]$releaseIssue, [Parameter()][string]$targetBranch="main", [Parameter()][string]$gitUserName, [Parameter()][string]$gitUserEmail @@ -42,10 +43,19 @@ function CreatePullRequestToUpdateChangelogsAndPublicApis { throw 'git switch failure' } + if ([string]::IsNullOrEmpty($releaseIssue) -eq $false) + { + $issueText = +@" + +Release request: #$releaseIssue +"@ + } + $body = @" Note: This PR was opened automatically by the [prepare release workflow](https://github.com/$gitRepository/actions/workflows/prepare-release.yml). - +$issueText Requested by: @$requestedByUserName ## Changes @@ -304,3 +314,152 @@ Released $(Get-Date -UFormat '%Y-%b-%d') } Export-ModuleMember -Function UpdateChangelogReleaseDatesAndPostNoticeOnPullRequest + +function TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue { + param( + [Parameter(Mandatory=$true)][string]$gitRepository, + [Parameter(Mandatory=$true)][string]$triggeringEventName, + [Parameter(Mandatory=$true)][string]$approvingGroups, + [Parameter(Mandatory=$true)][string]$requestedByUserName, + [Parameter(Mandatory=$true)][string]$issueNumber, + [Parameter(Mandatory=$true)][string]$issueBody, + [Parameter()][string]$targetBranch="main", + [Parameter()][string]$gitUserName, + [Parameter()][string]$gitUserEmail + ) + + $match = [regex]::Match($issueBody, '^[#]+ Component\s*(OpenTelemetry\.(?:.|\w+)+)$', [Text.RegularExpressions.RegexOptions]::Multiline) + if ($match.Success -eq $false) + { + Write-Host 'Component could not be parsed from body' + Return + } + + $component = $match.Groups[1].Value.Trim() + + $match = [regex]::Match($issueBody, '^[#]+ Version\s*(.*)$', [Text.RegularExpressions.RegexOptions]::Multiline) + if ($match.Success -eq $false) + { + Write-Host 'Version could not be parsed from body' + Return + } + + $version = $match.Groups[1].Value.Trim() + + $match = [regex]::Match($version, '^(\d+\.\d+\.\d+)(?:-((?:alpha)|(?:beta)|(?:rc))\.(\d+))?$') + if ($match.Success -eq $false) + { + gh issue comment $issueNumber ` + --body "The version specified on the release request is invalid. Please create a new release request with a valid version or edit the description and set a valid version." + Return + } + + $projectPath = "src/$component/$component.csproj" + + if ((Test-Path -Path $projectPath) -eq $false) + { + gh issue comment $issueNumber ` + --body "I couldn't find the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component." + Return + } + + $projectContent = Get-Content -Path $projectPath + + $match = [regex]::Match($projectContent, '(.*)<\/MinVerTagPrefix>') + if ($match.Success -eq $false) + { + gh issue comment $issueNumber ` + --body "I couldn't find ``MinVerTagPrefix`` in the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component." + Return + } + + $minVerTagPrefix = $match.Groups[1].Value + + $projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "$minVerTagPrefix" -List | Select Path | Split-Path -Parent + + $componentOwnersContent = Get-Content '.github/component_owners.yml' -Raw + + $componentOwners = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) + + foreach ($projectDir in $projectDirs) + { + $projectName = [System.IO.Path]::GetFileName($projectDir) + + $match = [regex]::Match($componentOwnersContent, "src\/$projectName\/:([\w\W\s]*?)src") + if ($match.Success -eq $true) + { + $matches = [regex]::Matches($match.Groups[1].Value, "-\s*(.*)") + foreach ($match in $matches) + { + $owner = $match.Groups[1].Value + $_ = $componentOwners.Add($owner.Trim()) + } + } + } + + $requestedByUserPermission = gh api "repos/$gitRepository/collaborators/$requestedByUserName/permission" | ConvertFrom-Json + + $kickOffWorkflow = $false + $kickOffWorkflowReason = '' + + if ($requestedByUserPermission.permission -eq 'admin' -or $requestedByUserPermission.permission -eq 'write') + { + $kickOffWorkflow = $true + $kickOffWorkflowReason = "@$requestedByUserName has collaborator or greater permission" + } + elseif ($componentOwners.Contains($requestedByUserName) -eq $true) + { + $kickOffWorkflow = $true + $kickOffWorkflowReason = "@$requestedByUserName is a component owner" + } + + if ($kickOffWorkflow -eq $true) + { + CreatePullRequestToUpdateChangelogsAndPublicApis ` + -gitRepository $gitRepository ` + -component $component ` + -version $version ` + -requestedByUserName $requestedByUserName ` + -releaseIssue $issueNumber ` + -targetBranch $targetBranch ` + -gitUserName $gitUserName ` + -gitUserEmail $gitUserEmail + + gh issue close $issueNumber ` + --comment "I executed the prepare release script for ``$component`` version ``$version``` because $kickOffWorkflowReason." + + return + } + + if ($triggeringEventName -eq 'issues') + { + # Executed when issues are created or edited + $componentOwnerApprovers = '' + if ($componentOwners.Count -gt 0) + { + foreach ($componentOwner in $componentOwners) + { + $componentOwnerApprovers += "@$componentOwner " + } + } + + $body = +@" +$componentOwnerApprovers$approvingGroups + +Post a comment with "/PrepareRelease" in the body if you would like me to execute the prepare release script for the component and version listed in the description. +"@ + + gh issue comment $issueNumber --body $body + } + else { + # Executed when issues are commented with the /PrepareRelease command + if ($kickOffWorkflow -eq $false) + { + gh issue comment $issueNumber ` + --body "I'm sorry @$requestedByUserName but you don't have permission to execute the prepare release script. Only maintainers, approvers, and/or owners of the component may use the `"/PrepareRelease`" command." + } + } +} + +Export-ModuleMember -Function TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 635826b25b..8c093fb419 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -382,6 +382,7 @@ 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\release_request.yml = .github\ISSUE_TEMPLATE\release_request.yml EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ConfluentKafka", "src\OpenTelemetry.Instrumentation.ConfluentKafka\OpenTelemetry.Instrumentation.ConfluentKafka.csproj", "{96341E23-990E-4144-A7E3-9EF0DAFF3232}" From f66086b9236ae4f5d900cf429f0ca0b1fe3103a1 Mon Sep 17 00:00:00 2001 From: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com> Date: Mon, 23 Sep 2024 18:59:37 +0200 Subject: [PATCH 1262/1499] [semantic conventions] Update generator version (#2089) --- .../Attributes/AndroidAttributes.cs | 14 +- .../Attributes/ArtifactAttributes.cs | 18 +- .../Attributes/AspnetcoreAttributes.cs | 40 +-- .../Attributes/AwsAttributes.cs | 110 +++--- .../Attributes/AzAttributes.cs | 2 +- .../Attributes/BrowserAttributes.cs | 16 +- .../Attributes/CicdAttributes.cs | 20 +- .../Attributes/ClientAttributes.cs | 8 +- .../Attributes/CloudAttributes.cs | 94 +++--- .../Attributes/CloudeventsAttributes.cs | 10 +- .../Attributes/CodeAttributes.cs | 12 +- .../Attributes/ContainerAttributes.cs | 50 +-- .../Attributes/CpuAttributes.cs | 20 +- .../Attributes/DbAttributes.cs | 316 +++++++++--------- .../Attributes/DeploymentAttributes.cs | 20 +- .../Attributes/DestinationAttributes.cs | 6 +- .../Attributes/DeviceAttributes.cs | 16 +- .../Attributes/DiskAttributes.cs | 8 +- .../Attributes/DnsAttributes.cs | 4 +- .../Attributes/EnduserAttributes.cs | 12 +- .../Attributes/ErrorAttributes.cs | 8 +- .../Attributes/EventAttributes.cs | 4 +- .../Attributes/ExceptionAttributes.cs | 10 +- .../Attributes/FaasAttributes.cs | 78 ++--- .../Attributes/FeatureFlagAttributes.cs | 8 +- .../Attributes/FileAttributes.cs | 12 +- .../Attributes/GcpAttributes.cs | 12 +- .../Attributes/GenAiAttributes.cs | 74 ++-- .../Attributes/GoAttributes.cs | 8 +- .../Attributes/GraphqlAttributes.cs | 16 +- .../Attributes/HerokuAttributes.cs | 6 +- .../Attributes/HostAttributes.cs | 54 +-- .../Attributes/HttpAttributes.cs | 144 ++++---- .../Attributes/IosAttributes.cs | 28 +- .../Attributes/JvmAttributes.cs | 42 +-- .../Attributes/K8sAttributes.cs | 54 +-- .../Attributes/LinuxAttributes.cs | 8 +- .../Attributes/LogAttributes.cs | 24 +- .../Attributes/MessageAttributes.cs | 26 +- .../Attributes/MessagingAttributes.cs | 194 +++++------ .../Attributes/NetAttributes.cs | 96 +++--- .../Attributes/NetworkAttributes.cs | 118 +++---- .../Attributes/OciAttributes.cs | 4 +- .../Attributes/OpentracingAttributes.cs | 10 +- .../Attributes/OsAttributes.cs | 34 +- .../Attributes/OtelAttributes.cs | 14 +- .../Attributes/OtherAttributes.cs | 14 +- .../Attributes/PeerAttributes.cs | 2 +- .../Attributes/PoolAttributes.cs | 4 +- .../Attributes/ProcessAttributes.cs | 84 ++--- .../Attributes/RpcAttributes.cs | 136 ++++---- .../Attributes/ServerAttributes.cs | 8 +- .../Attributes/ServiceAttributes.cs | 14 +- .../Attributes/SessionAttributes.cs | 4 +- .../Attributes/SignalrAttributes.cs | 20 +- .../Attributes/SourceAttributes.cs | 6 +- .../Attributes/SystemAttributes.cs | 168 +++++----- .../Attributes/TelemetryAttributes.cs | 40 +-- .../Attributes/TestAttributes.cs | 28 +- .../Attributes/ThreadAttributes.cs | 4 +- .../Attributes/TlsAttributes.cs | 68 ++-- .../Attributes/UrlAttributes.cs | 44 +-- .../Attributes/UserAgentAttributes.cs | 10 +- .../Attributes/UserAttributes.cs | 14 +- .../Attributes/V8jsAttributes.cs | 28 +- .../Attributes/VcsAttributes.cs | 20 +- .../Attributes/WebengineAttributes.cs | 6 +- .../scripts/generate.ps1 | 2 +- .../scripts/generate.sh | 2 +- .../scripts/templates/registry/weaver.yaml | 3 +- 70 files changed, 1306 insertions(+), 1305 deletions(-) diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs index 87e2bbc526..9cb66d6a2b 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs @@ -15,35 +15,35 @@ namespace OpenTelemetry.SemanticConventions; public static class AndroidAttributes { /// - /// Uniquely identifies the framework API revision offered by a version (os.version) of the android operating system. More information can be found here + /// Uniquely identifies the framework API revision offered by a version (os.version) of the android operating system. More information can be found here. /// public const string AttributeAndroidOsApiLevel = "android.os.api_level"; /// - /// Deprecated use the device.app.lifecycle event definition including android.state as a payload field instead + /// Deprecated use the device.app.lifecycle event definition including android.state as a payload field instead. /// /// - /// The Android lifecycle states are defined in Activity lifecycle callbacks, and from which the OS identifiers are derived + /// The Android lifecycle states are defined in Activity lifecycle callbacks, and from which the OS identifiers are derived. /// public const string AttributeAndroidState = "android.state"; /// - /// Deprecated use the device.app.lifecycle event definition including android.state as a payload field instead + /// Deprecated use the device.app.lifecycle event definition including android.state as a payload field instead. /// public static class AndroidStateValues { /// - /// Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time + /// Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. /// public const string Created = "created"; /// - /// Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state + /// Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. /// public const string Background = "background"; /// - /// Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states + /// Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. /// public const string Foreground = "foreground"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs index 04cc367c16..e59cb7da33 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ArtifactAttributes.cs @@ -15,33 +15,33 @@ namespace OpenTelemetry.SemanticConventions; public static class ArtifactAttributes { /// - /// The provenance filename of the built attestation which directly relates to the build artifact filename. This filename SHOULD accompany the artifact at publish time. See the SLSA Relationship specification for more information + /// The provenance filename of the built attestation which directly relates to the build artifact filename. This filename SHOULD accompany the artifact at publish time. See the SLSA Relationship specification for more information. /// public const string AttributeArtifactAttestationFilename = "artifact.attestation.filename"; /// - /// The full hash value (see glossary), of the built attestation. Some envelopes in the software attestation space also refer to this as the digest + /// The full hash value (see glossary), of the built attestation. Some envelopes in the software attestation space also refer to this as the digest. /// public const string AttributeArtifactAttestationHash = "artifact.attestation.hash"; /// - /// The id of the build software attestation + /// The id of the build software attestation. /// public const string AttributeArtifactAttestationId = "artifact.attestation.id"; /// - /// The human readable file name of the artifact, typically generated during build and release processes. Often includes the package name and version in the file name + /// The human readable file name of the artifact, typically generated during build and release processes. Often includes the package name and version in the file name. /// /// /// This file name can also act as the Package Name /// in cases where the package ecosystem maps accordingly. /// Additionally, the artifact can be published - /// for others, but that is not a guarantee + /// for others, but that is not a guarantee. /// public const string AttributeArtifactFilename = "artifact.filename"; /// - /// The full hash value (see glossary), often found in checksum.txt on a release of the artifact and used to verify package integrity + /// The full hash value (see glossary), often found in checksum.txt on a release of the artifact and used to verify package integrity. /// /// /// The specific algorithm used to create the cryptographic hash value is @@ -51,17 +51,17 @@ public static class ArtifactAttributes /// that is suitable for the situation and consistent with the /// corresponding attestation. The implementer can then provide the other /// hash values through an additional set of attribute extensions as they - /// deem necessary + /// deem necessary. /// public const string AttributeArtifactHash = "artifact.hash"; /// - /// The Package URL of the package artifact provides a standard way to identify and locate the packaged artifact + /// The Package URL of the package artifact provides a standard way to identify and locate the packaged artifact. /// public const string AttributeArtifactPurl = "artifact.purl"; /// - /// The version of the artifact + /// The version of the artifact. /// public const string AttributeArtifactVersion = "artifact.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs index 3166fb95fb..12bc44887a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AspnetcoreAttributes.cs @@ -15,104 +15,104 @@ namespace OpenTelemetry.SemanticConventions; public static class AspnetcoreAttributes { /// - /// ASP.NET Core exception middleware handling result + /// ASP.NET Core exception middleware handling result. /// public const string AttributeAspnetcoreDiagnosticsExceptionResult = "aspnetcore.diagnostics.exception.result"; /// - /// Full type name of the IExceptionHandler implementation that handled the exception + /// Full type name of the IExceptionHandler implementation that handled the exception. /// public const string AttributeAspnetcoreDiagnosticsHandlerType = "aspnetcore.diagnostics.handler.type"; /// - /// Rate limiting policy name + /// Rate limiting policy name. /// public const string AttributeAspnetcoreRateLimitingPolicy = "aspnetcore.rate_limiting.policy"; /// - /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason + /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason. /// public const string AttributeAspnetcoreRateLimitingResult = "aspnetcore.rate_limiting.result"; /// - /// Flag indicating if request was handled by the application pipeline + /// Flag indicating if request was handled by the application pipeline. /// public const string AttributeAspnetcoreRequestIsUnhandled = "aspnetcore.request.is_unhandled"; /// - /// A value that indicates whether the matched route is a fallback route + /// A value that indicates whether the matched route is a fallback route. /// public const string AttributeAspnetcoreRoutingIsFallback = "aspnetcore.routing.is_fallback"; /// - /// Match result - success or failure + /// Match result - success or failure. /// public const string AttributeAspnetcoreRoutingMatchStatus = "aspnetcore.routing.match_status"; /// - /// ASP.NET Core exception middleware handling result + /// ASP.NET Core exception middleware handling result. /// public static class AspnetcoreDiagnosticsExceptionResultValues { /// - /// Exception was handled by the exception handling middleware + /// Exception was handled by the exception handling middleware. /// public const string Handled = "handled"; /// - /// Exception was not handled by the exception handling middleware + /// Exception was not handled by the exception handling middleware. /// public const string Unhandled = "unhandled"; /// - /// Exception handling was skipped because the response had started + /// Exception handling was skipped because the response had started. /// public const string Skipped = "skipped"; /// - /// Exception handling didn't run because the request was aborted + /// Exception handling didn't run because the request was aborted. /// public const string Aborted = "aborted"; } /// - /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason + /// Rate-limiting result, shows whether the lease was acquired or contains a rejection reason. /// public static class AspnetcoreRateLimitingResultValues { /// - /// Lease was acquired + /// Lease was acquired. /// public const string Acquired = "acquired"; /// - /// Lease request was rejected by the endpoint limiter + /// Lease request was rejected by the endpoint limiter. /// public const string EndpointLimiter = "endpoint_limiter"; /// - /// Lease request was rejected by the global limiter + /// Lease request was rejected by the global limiter. /// public const string GlobalLimiter = "global_limiter"; /// - /// Lease request was canceled + /// Lease request was canceled. /// public const string RequestCanceled = "request_canceled"; } /// - /// Match result - success or failure + /// Match result - success or failure. /// public static class AspnetcoreRoutingMatchStatusValues { /// - /// Match succeeded + /// Match succeeded. /// public const string Success = "success"; /// - /// Match failed + /// Match failed. /// public const string Failure = "failure"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs index 02ea3d403c..9ba5b04bd4 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs @@ -15,208 +15,208 @@ namespace OpenTelemetry.SemanticConventions; public static class AwsAttributes { /// - /// The JSON-serialized value of each item in the AttributeDefinitions request field + /// The JSON-serialized value of each item in the AttributeDefinitions request field. /// public const string AttributeAwsDynamodbAttributeDefinitions = "aws.dynamodb.attribute_definitions"; /// - /// The value of the AttributesToGet request parameter + /// The value of the AttributesToGet request parameter. /// public const string AttributeAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get"; /// - /// The value of the ConsistentRead request parameter + /// The value of the ConsistentRead request parameter. /// public const string AttributeAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read"; /// - /// The JSON-serialized value of each item in the ConsumedCapacity response field + /// The JSON-serialized value of each item in the ConsumedCapacity response field. /// public const string AttributeAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity"; /// - /// The value of the Count response parameter + /// The value of the Count response parameter. /// public const string AttributeAwsDynamodbCount = "aws.dynamodb.count"; /// - /// The value of the ExclusiveStartTableName request parameter + /// The value of the ExclusiveStartTableName request parameter. /// public const string AttributeAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table"; /// - /// The JSON-serialized value of each item in the GlobalSecondaryIndexUpdates request field + /// The JSON-serialized value of each item in the GlobalSecondaryIndexUpdates request field. /// public const string AttributeAwsDynamodbGlobalSecondaryIndexUpdates = "aws.dynamodb.global_secondary_index_updates"; /// - /// The JSON-serialized value of each item of the GlobalSecondaryIndexes request field + /// The JSON-serialized value of each item of the GlobalSecondaryIndexes request field. /// public const string AttributeAwsDynamodbGlobalSecondaryIndexes = "aws.dynamodb.global_secondary_indexes"; /// - /// The value of the IndexName request parameter + /// The value of the IndexName request parameter. /// public const string AttributeAwsDynamodbIndexName = "aws.dynamodb.index_name"; /// - /// The JSON-serialized value of the ItemCollectionMetrics response field + /// The JSON-serialized value of the ItemCollectionMetrics response field. /// public const string AttributeAwsDynamodbItemCollectionMetrics = "aws.dynamodb.item_collection_metrics"; /// - /// The value of the Limit request parameter + /// The value of the Limit request parameter. /// public const string AttributeAwsDynamodbLimit = "aws.dynamodb.limit"; /// - /// The JSON-serialized value of each item of the LocalSecondaryIndexes request field + /// The JSON-serialized value of each item of the LocalSecondaryIndexes request field. /// public const string AttributeAwsDynamodbLocalSecondaryIndexes = "aws.dynamodb.local_secondary_indexes"; /// - /// The value of the ProjectionExpression request parameter + /// The value of the ProjectionExpression request parameter. /// public const string AttributeAwsDynamodbProjection = "aws.dynamodb.projection"; /// - /// The value of the ProvisionedThroughput.ReadCapacityUnits request parameter + /// The value of the ProvisionedThroughput.ReadCapacityUnits request parameter. /// public const string AttributeAwsDynamodbProvisionedReadCapacity = "aws.dynamodb.provisioned_read_capacity"; /// - /// The value of the ProvisionedThroughput.WriteCapacityUnits request parameter + /// The value of the ProvisionedThroughput.WriteCapacityUnits request parameter. /// public const string AttributeAwsDynamodbProvisionedWriteCapacity = "aws.dynamodb.provisioned_write_capacity"; /// - /// The value of the ScanIndexForward request parameter + /// The value of the ScanIndexForward request parameter. /// public const string AttributeAwsDynamodbScanForward = "aws.dynamodb.scan_forward"; /// - /// The value of the ScannedCount response parameter + /// The value of the ScannedCount response parameter. /// public const string AttributeAwsDynamodbScannedCount = "aws.dynamodb.scanned_count"; /// - /// The value of the Segment request parameter + /// The value of the Segment request parameter. /// public const string AttributeAwsDynamodbSegment = "aws.dynamodb.segment"; /// - /// The value of the Select request parameter + /// The value of the Select request parameter. /// public const string AttributeAwsDynamodbSelect = "aws.dynamodb.select"; /// - /// The number of items in the TableNames response parameter + /// The number of items in the TableNames response parameter. /// public const string AttributeAwsDynamodbTableCount = "aws.dynamodb.table_count"; /// - /// The keys in the RequestItems object field + /// The keys in the RequestItems object field. /// public const string AttributeAwsDynamodbTableNames = "aws.dynamodb.table_names"; /// - /// The value of the TotalSegments request parameter + /// The value of the TotalSegments request parameter. /// public const string AttributeAwsDynamodbTotalSegments = "aws.dynamodb.total_segments"; /// - /// The ARN of an ECS cluster + /// The ARN of an ECS cluster. /// public const string AttributeAwsEcsClusterArn = "aws.ecs.cluster.arn"; /// - /// The Amazon Resource Name (ARN) of an ECS container instance + /// The Amazon Resource Name (ARN) of an ECS container instance. /// public const string AttributeAwsEcsContainerArn = "aws.ecs.container.arn"; /// - /// The launch type for an ECS task + /// The launch type for an ECS task. /// public const string AttributeAwsEcsLaunchtype = "aws.ecs.launchtype"; /// - /// The ARN of a running ECS task + /// The ARN of a running ECS task. /// public const string AttributeAwsEcsTaskArn = "aws.ecs.task.arn"; /// - /// The family name of the ECS task definition used to create the ECS task + /// The family name of the ECS task definition used to create the ECS task. /// public const string AttributeAwsEcsTaskFamily = "aws.ecs.task.family"; /// - /// The ID of a running ECS task. The ID MUST be extracted from task.arn + /// The ID of a running ECS task. The ID MUST be extracted from task.arn. /// public const string AttributeAwsEcsTaskId = "aws.ecs.task.id"; /// - /// The revision for the task definition used to create the ECS task + /// The revision for the task definition used to create the ECS task. /// public const string AttributeAwsEcsTaskRevision = "aws.ecs.task.revision"; /// - /// The ARN of an EKS cluster + /// The ARN of an EKS cluster. /// public const string AttributeAwsEksClusterArn = "aws.eks.cluster.arn"; /// - /// The full invoked ARN as provided on the Context passed to the function (Lambda-Runtime-Invoked-Function-Arn header on the /runtime/invocation/next applicable) + /// The full invoked ARN as provided on the Context passed to the function (Lambda-Runtime-Invoked-Function-Arn header on the /runtime/invocation/next applicable). /// /// - /// This may be different from cloud.resource_id if an alias is involved + /// This may be different from cloud.resource_id if an alias is involved. /// public const string AttributeAwsLambdaInvokedArn = "aws.lambda.invoked_arn"; /// - /// The Amazon Resource Name(s) (ARN) of the AWS log group(s) + /// The Amazon Resource Name(s) (ARN) of the AWS log group(s). /// /// - /// See the log group ARN format documentation + /// See the log group ARN format documentation. /// public const string AttributeAwsLogGroupArns = "aws.log.group.arns"; /// - /// The name(s) of the AWS log group(s) an application is writing to + /// The name(s) of the AWS log group(s) an application is writing to. /// /// - /// Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group + /// Multiple log groups must be supported for cases like multi-container applications, where a single application has sidecar containers, and each write to their own log group. /// public const string AttributeAwsLogGroupNames = "aws.log.group.names"; /// - /// The ARN(s) of the AWS log stream(s) + /// The ARN(s) of the AWS log stream(s). /// /// - /// See the log stream ARN format documentation. One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream + /// See the log stream ARN format documentation. One log group can contain several log streams, so these ARNs necessarily identify both a log group and a log stream. /// public const string AttributeAwsLogStreamArns = "aws.log.stream.arns"; /// - /// The name(s) of the AWS log stream(s) an application is writing to + /// The name(s) of the AWS log stream(s) an application is writing to. /// public const string AttributeAwsLogStreamNames = "aws.log.stream.names"; /// - /// The AWS request ID as returned in the response headers x-amz-request-id or x-amz-requestid + /// The AWS request ID as returned in the response headers x-amz-request-id or x-amz-requestid. /// public const string AttributeAwsRequestId = "aws.request_id"; /// - /// The S3 bucket name the request refers to. Corresponds to the --bucket parameter of the S3 API operations + /// The S3 bucket name the request refers to. Corresponds to the --bucket parameter of the S3 API operations. /// /// /// The bucket attribute is applicable to all S3 operations that reference a bucket, i.e. that require the bucket name as a mandatory parameter. - /// This applies to almost all S3 operations except list-buckets + /// This applies to almost all S3 operations except list-buckets. /// public const string AttributeAwsS3Bucket = "aws.s3.bucket"; /// - /// The source object (in the form bucket/key) for the copy operation + /// The source object (in the form bucket/key) for the copy operation. /// /// /// The copy_source attribute applies to S3 copy operations and corresponds to the --copy-source parameter @@ -225,23 +225,23 @@ public static class AwsAttributes ///

    ///

    ///
    public const string AttributeAwsS3CopySource = "aws.s3.copy_source"; /// - /// The delete request container that specifies the objects to be deleted + /// The delete request container that specifies the objects to be deleted. /// /// /// The delete attribute is only applicable to the delete-object operation. /// The delete attribute corresponds to the --delete parameter of the - /// delete-objects operation within the S3 API + /// delete-objects operation within the S3 API. /// public const string AttributeAwsS3Delete = "aws.s3.delete"; /// - /// The S3 object key the request refers to. Corresponds to the --key parameter of the S3 API operations + /// The S3 object key the request refers to. Corresponds to the --key parameter of the S3 API operations. /// /// /// The key attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. @@ -260,24 +260,24 @@ public static class AwsAttributes ///
  • create-multipart-upload
  • ///
  • list-parts
  • ///
  • upload-part
  • - ///
  • upload-part-copy
  • + ///
  • upload-part-copy.
  • /// ///
    public const string AttributeAwsS3Key = "aws.s3.key"; /// - /// The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000 + /// The part number of the part being uploaded in a multipart-upload operation. This is a positive integer between 1 and 10,000. /// /// /// The part_number attribute is only applicable to the upload-part /// and upload-part-copy operations. /// The part_number attribute corresponds to the --part-number parameter of the - /// upload-part operation within the S3 API + /// upload-part operation within the S3 API. /// public const string AttributeAwsS3PartNumber = "aws.s3.part_number"; /// - /// Upload ID that identifies the multipart upload + /// Upload ID that identifies the multipart upload. /// /// /// The upload_id attribute applies to S3 multipart-upload operations and corresponds to the --upload-id parameter @@ -289,23 +289,23 @@ public static class AwsAttributes ///
  • complete-multipart-upload
  • ///
  • list-parts
  • ///
  • upload-part
  • - ///
  • upload-part-copy
  • + ///
  • upload-part-copy.
  • /// ///
    public const string AttributeAwsS3UploadId = "aws.s3.upload_id"; /// - /// The launch type for an ECS task + /// The launch type for an ECS task. /// public static class AwsEcsLaunchtypeValues { /// - /// ec2 + /// ec2. /// public const string Ec2 = "ec2"; /// - /// fargate + /// fargate. /// public const string Fargate = "fargate"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs index c0d96104b7..50a88c4b1f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class AzAttributes { /// - /// The unique identifier of the service request. It's generated by the Azure service and returned with the response + /// The unique identifier of the service request. It's generated by the Azure service and returned with the response. /// public const string AttributeAzServiceRequestId = "az.service_request_id"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs index d8a1891593..846e6fd23a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/BrowserAttributes.cs @@ -15,35 +15,35 @@ namespace OpenTelemetry.SemanticConventions; public static class BrowserAttributes { /// - /// Array of brand name and version separated by a space + /// Array of brand name and version separated by a space. /// /// - /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.brands) + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.brands). /// public const string AttributeBrowserBrands = "browser.brands"; /// - /// Preferred language of the user using the browser + /// Preferred language of the user using the browser. /// /// - /// This value is intended to be taken from the Navigator API navigator.language + /// This value is intended to be taken from the Navigator API navigator.language. /// public const string AttributeBrowserLanguage = "browser.language"; /// - /// A boolean that is true if the browser is running on a mobile device + /// A boolean that is true if the browser is running on a mobile device. /// /// - /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.mobile). If unavailable, this attribute SHOULD be left unset + /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.mobile). If unavailable, this attribute SHOULD be left unset. /// public const string AttributeBrowserMobile = "browser.mobile"; /// - /// The platform on which the browser is running + /// The platform on which the browser is running. /// /// /// This value is intended to be taken from the UA client hints API (navigator.userAgentData.platform). If unavailable, the legacy navigator.platform API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. - /// The list of possible values is defined in the W3C User-Agent Client Hints specification. Note that some (but not all) of these values can overlap with values in the os.type and os.name attributes. However, for consistency, the values in the browser.platform attribute should capture the exact value that the user agent provides + /// The list of possible values is defined in the W3C User-Agent Client Hints specification. Note that some (but not all) of these values can overlap with values in the os.type and os.name attributes. However, for consistency, the values in the browser.platform attribute should capture the exact value that the user agent provides. /// public const string AttributeBrowserPlatform = "browser.platform"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs index 447fa09887..3af1aed457 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs @@ -15,52 +15,52 @@ namespace OpenTelemetry.SemanticConventions; public static class CicdAttributes { /// - /// The human readable name of the pipeline within a CI/CD system + /// The human readable name of the pipeline within a CI/CD system. /// public const string AttributeCicdPipelineName = "cicd.pipeline.name"; /// - /// The unique identifier of a pipeline run within a CI/CD system + /// The unique identifier of a pipeline run within a CI/CD system. /// public const string AttributeCicdPipelineRunId = "cicd.pipeline.run.id"; /// - /// The human readable name of a task within a pipeline. Task here most closely aligns with a computing process in a pipeline. Other terms for tasks include commands, steps, and procedures + /// The human readable name of a task within a pipeline. Task here most closely aligns with a computing process in a pipeline. Other terms for tasks include commands, steps, and procedures. /// public const string AttributeCicdPipelineTaskName = "cicd.pipeline.task.name"; /// - /// The unique identifier of a task run within a pipeline + /// The unique identifier of a task run within a pipeline. /// public const string AttributeCicdPipelineTaskRunId = "cicd.pipeline.task.run.id"; /// - /// The URL of the pipeline run providing the complete address in order to locate and identify the pipeline run + /// The URL of the pipeline run providing the complete address in order to locate and identify the pipeline run. /// public const string AttributeCicdPipelineTaskRunUrlFull = "cicd.pipeline.task.run.url.full"; /// - /// The type of the task within a pipeline + /// The type of the task within a pipeline. /// public const string AttributeCicdPipelineTaskType = "cicd.pipeline.task.type"; /// - /// The type of the task within a pipeline + /// The type of the task within a pipeline. /// public static class CicdPipelineTaskTypeValues { /// - /// build + /// build. /// public const string Build = "build"; /// - /// test + /// test. /// public const string Test = "test"; /// - /// deploy + /// deploy. /// public const string Deploy = "deploy"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs index d8aa303707..029524ba8c 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ClientAttributes.cs @@ -15,18 +15,18 @@ namespace OpenTelemetry.SemanticConventions; public static class ClientAttributes { /// - /// Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name + /// Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. /// /// - /// When observed from the server side, and when communicating through an intermediary, client.address SHOULD represent the client address behind any intermediaries, for example proxies, if it's available + /// When observed from the server side, and when communicating through an intermediary, client.address SHOULD represent the client address behind any intermediaries, for example proxies, if it's available. /// public const string AttributeClientAddress = "client.address"; /// - /// Client port number + /// Client port number. /// /// - /// When observed from the server side, and when communicating through an intermediary, client.port SHOULD represent the client port behind any intermediaries, for example proxies, if it's available + /// When observed from the server side, and when communicating through an intermediary, client.port SHOULD represent the client port behind any intermediaries, for example proxies, if it's available. /// public const string AttributeClientPort = "client.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs index 5906c9d812..d8dcd99627 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs @@ -15,41 +15,41 @@ namespace OpenTelemetry.SemanticConventions; public static class CloudAttributes { /// - /// The cloud account ID the resource is assigned to + /// The cloud account ID the resource is assigned to. /// public const string AttributeCloudAccountId = "cloud.account.id"; /// - /// Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running + /// Cloud regions often have multiple, isolated locations known as zones to increase availability. Availability zone represents the zone where the resource is running. /// /// - /// Availability zones are called "zones" on Alibaba Cloud and Google Cloud + /// Availability zones are called "zones" on Alibaba Cloud and Google Cloud. /// public const string AttributeCloudAvailabilityZone = "cloud.availability_zone"; /// - /// The cloud platform in use + /// The cloud platform in use. /// /// - /// The prefix of the service SHOULD match the one specified in cloud.provider + /// The prefix of the service SHOULD match the one specified in cloud.provider. /// public const string AttributeCloudPlatform = "cloud.platform"; /// - /// Name of the cloud provider + /// Name of the cloud provider. /// public const string AttributeCloudProvider = "cloud.provider"; /// - /// The geographical region the resource is running + /// The geographical region the resource is running. /// /// - /// Refer to your provider's docs to see the available regions, for example Alibaba Cloud regions, AWS regions, Azure regions, Google Cloud regions, or Tencent Cloud regions + /// Refer to your provider's docs to see the available regions, for example Alibaba Cloud regions, AWS regions, Azure regions, Google Cloud regions, or Tencent Cloud regions. /// public const string AttributeCloudRegion = "cloud.region"; /// - /// Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on AWS, a fully qualified resource ID on Azure, a full resource name on GCP) + /// Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on AWS, a fully qualified resource ID on Azure, a full resource name on GCP). /// /// /// On some cloud providers, it may not be possible to determine the full ID at startup, @@ -69,194 +69,194 @@ public static class CloudAttributes /// not the function app, having the form /// /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/. /// This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share - /// a TracerProvider + /// a TracerProvider. /// /// public const string AttributeCloudResourceId = "cloud.resource_id"; /// - /// The cloud platform in use + /// The cloud platform in use. /// public static class CloudPlatformValues { /// - /// Alibaba Cloud Elastic Compute Service + /// Alibaba Cloud Elastic Compute Service. /// public const string AlibabaCloudEcs = "alibaba_cloud_ecs"; /// - /// Alibaba Cloud Function Compute + /// Alibaba Cloud Function Compute. /// public const string AlibabaCloudFc = "alibaba_cloud_fc"; /// - /// Red Hat OpenShift on Alibaba Cloud + /// Red Hat OpenShift on Alibaba Cloud. /// public const string AlibabaCloudOpenshift = "alibaba_cloud_openshift"; /// - /// AWS Elastic Compute Cloud + /// AWS Elastic Compute Cloud. /// public const string AwsEc2 = "aws_ec2"; /// - /// AWS Elastic Container Service + /// AWS Elastic Container Service. /// public const string AwsEcs = "aws_ecs"; /// - /// AWS Elastic Kubernetes Service + /// AWS Elastic Kubernetes Service. /// public const string AwsEks = "aws_eks"; /// - /// AWS Lambda + /// AWS Lambda. /// public const string AwsLambda = "aws_lambda"; /// - /// AWS Elastic Beanstalk + /// AWS Elastic Beanstalk. /// public const string AwsElasticBeanstalk = "aws_elastic_beanstalk"; /// - /// AWS App Runner + /// AWS App Runner. /// public const string AwsAppRunner = "aws_app_runner"; /// - /// Red Hat OpenShift on AWS (ROSA) + /// Red Hat OpenShift on AWS (ROSA). /// public const string AwsOpenshift = "aws_openshift"; /// - /// Azure Virtual Machines + /// Azure Virtual Machines. /// public const string AzureVm = "azure_vm"; /// - /// Azure Container Apps + /// Azure Container Apps. /// public const string AzureContainerApps = "azure_container_apps"; /// - /// Azure Container Instances + /// Azure Container Instances. /// public const string AzureContainerInstances = "azure_container_instances"; /// - /// Azure Kubernetes Service + /// Azure Kubernetes Service. /// public const string AzureAks = "azure_aks"; /// - /// Azure Functions + /// Azure Functions. /// public const string AzureFunctions = "azure_functions"; /// - /// Azure App Service + /// Azure App Service. /// public const string AzureAppService = "azure_app_service"; /// - /// Azure Red Hat OpenShift + /// Azure Red Hat OpenShift. /// public const string AzureOpenshift = "azure_openshift"; /// - /// Google Bare Metal Solution (BMS) + /// Google Bare Metal Solution (BMS). /// public const string GcpBareMetalSolution = "gcp_bare_metal_solution"; /// - /// Google Cloud Compute Engine (GCE) + /// Google Cloud Compute Engine (GCE). /// public const string GcpComputeEngine = "gcp_compute_engine"; /// - /// Google Cloud Run + /// Google Cloud Run. /// public const string GcpCloudRun = "gcp_cloud_run"; /// - /// Google Cloud Kubernetes Engine (GKE) + /// Google Cloud Kubernetes Engine (GKE). /// public const string GcpKubernetesEngine = "gcp_kubernetes_engine"; /// - /// Google Cloud Functions (GCF) + /// Google Cloud Functions (GCF). /// public const string GcpCloudFunctions = "gcp_cloud_functions"; /// - /// Google Cloud App Engine (GAE) + /// Google Cloud App Engine (GAE). /// public const string GcpAppEngine = "gcp_app_engine"; /// - /// Red Hat OpenShift on Google Cloud + /// Red Hat OpenShift on Google Cloud. /// public const string GcpOpenshift = "gcp_openshift"; /// - /// Red Hat OpenShift on IBM Cloud + /// Red Hat OpenShift on IBM Cloud. /// public const string IbmCloudOpenshift = "ibm_cloud_openshift"; /// - /// Tencent Cloud Cloud Virtual Machine (CVM) + /// Tencent Cloud Cloud Virtual Machine (CVM). /// public const string TencentCloudCvm = "tencent_cloud_cvm"; /// - /// Tencent Cloud Elastic Kubernetes Service (EKS) + /// Tencent Cloud Elastic Kubernetes Service (EKS). /// public const string TencentCloudEks = "tencent_cloud_eks"; /// - /// Tencent Cloud Serverless Cloud Function (SCF) + /// Tencent Cloud Serverless Cloud Function (SCF). /// public const string TencentCloudScf = "tencent_cloud_scf"; } /// - /// Name of the cloud provider + /// Name of the cloud provider. /// public static class CloudProviderValues { /// - /// Alibaba Cloud + /// Alibaba Cloud. /// public const string AlibabaCloud = "alibaba_cloud"; /// - /// Amazon Web Services + /// Amazon Web Services. /// public const string Aws = "aws"; /// - /// Microsoft Azure + /// Microsoft Azure. /// public const string Azure = "azure"; /// - /// Google Cloud Platform + /// Google Cloud Platform. /// public const string Gcp = "gcp"; /// - /// Heroku Platform as a Service + /// Heroku Platform as a Service. /// public const string Heroku = "heroku"; /// - /// IBM Cloud + /// IBM Cloud. /// public const string IbmCloud = "ibm_cloud"; /// - /// Tencent Cloud + /// Tencent Cloud. /// public const string TencentCloud = "tencent_cloud"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs index 7c13858791..d334bc1667 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudeventsAttributes.cs @@ -15,27 +15,27 @@ namespace OpenTelemetry.SemanticConventions; public static class CloudeventsAttributes { /// - /// The event_id uniquely identifies the event + /// The event_id uniquely identifies the event. /// public const string AttributeCloudeventsEventId = "cloudevents.event_id"; /// - /// The source identifies the context in which an event happened + /// The source identifies the context in which an event happened. /// public const string AttributeCloudeventsEventSource = "cloudevents.event_source"; /// - /// The version of the CloudEvents specification which the event uses + /// The version of the CloudEvents specification which the event uses. /// public const string AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version"; /// - /// The subject of the event in the context of the event producer (identified by source) + /// The subject of the event in the context of the event producer (identified by source). /// public const string AttributeCloudeventsEventSubject = "cloudevents.event_subject"; /// - /// The event_type contains a value describing the type of event related to the originating occurrence + /// The event_type contains a value describing the type of event related to the originating occurrence. /// public const string AttributeCloudeventsEventType = "cloudevents.event_type"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs index 41eee11105..065149dc52 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CodeAttributes.cs @@ -15,32 +15,32 @@ namespace OpenTelemetry.SemanticConventions; public static class CodeAttributes { /// - /// The column number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function + /// The column number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function. /// public const string AttributeCodeColumn = "code.column"; /// - /// The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path) + /// The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). /// public const string AttributeCodeFilepath = "code.filepath"; /// - /// The method or function name, or equivalent (usually rightmost part of the code unit's name) + /// The method or function name, or equivalent (usually rightmost part of the code unit's name). /// public const string AttributeCodeFunction = "code.function"; /// - /// The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function + /// The line number in code.filepath best representing the operation. It SHOULD point within the code unit named in code.function. /// public const string AttributeCodeLineno = "code.lineno"; /// - /// The "namespace" within which code.function is defined. Usually the qualified class or module name, such that code.namespace + some separator + code.function form a unique identifier for the code unit + /// The "namespace" within which code.function is defined. Usually the qualified class or module name, such that code.namespace + some separator + code.function form a unique identifier for the code unit. /// public const string AttributeCodeNamespace = "code.namespace"; /// - /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG + /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. /// public const string AttributeCodeStacktrace = "code.stacktrace"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs index cd4bd4e3e3..955f1f8e0a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs @@ -15,104 +15,104 @@ namespace OpenTelemetry.SemanticConventions; public static class ContainerAttributes { /// - /// The command used to run the container (i.e. the command name) + /// The command used to run the container (i.e. the command name). /// /// - /// If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage + /// If using embedded credentials or sensitive data, it is recommended to remove them to prevent potential leakage. /// public const string AttributeContainerCommand = "container.command"; /// - /// All the command arguments (including the command/executable itself) run by the container. [2] + /// All the command arguments (including the command/executable itself) run by the container. [2]. /// public const string AttributeContainerCommandArgs = "container.command_args"; /// - /// The full command run by the container as a single string representing the full command. [2] + /// The full command run by the container as a single string representing the full command. [2]. /// public const string AttributeContainerCommandLine = "container.command_line"; /// - /// Deprecated, use cpu.mode instead + /// Deprecated, use cpu.mode instead. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string AttributeContainerCpuState = "container.cpu.state"; /// - /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated + /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated. /// public const string AttributeContainerId = "container.id"; /// - /// Runtime specific image identifier. Usually a hash algorithm followed by a UUID + /// Runtime specific image identifier. Usually a hash algorithm followed by a UUID. /// /// /// Docker defines a sha256 of the image id; container.image.id corresponds to the Image field from the Docker container inspect API endpoint. /// K8s defines a link to the container registry repository with digest "imageID": "registry.azurecr.io /namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625". - /// The ID is assigned by the container runtime and can vary in different environments. Consider using oci.manifest.digest if it is important to identify the same image in different environments/runtimes + /// The ID is assigned by the container runtime and can vary in different environments. Consider using oci.manifest.digest if it is important to identify the same image in different environments/runtimes. /// public const string AttributeContainerImageId = "container.image.id"; /// - /// Name of the image the container was built on + /// Name of the image the container was built on. /// public const string AttributeContainerImageName = "container.image.name"; /// - /// Repo digests of the container image as provided by the container runtime + /// Repo digests of the container image as provided by the container runtime. /// /// - /// Docker and CRI report those under the RepoDigests field + /// Docker and CRI report those under the RepoDigests field. /// public const string AttributeContainerImageRepoDigests = "container.image.repo_digests"; /// - /// Container image tags. An example can be found in Docker Image Inspect. Should be only the section of the full name for example from registry.example.com/my-org/my-image: + /// Container image tags. An example can be found in Docker Image Inspect. Should be only the section of the full name for example from registry.example.com/my-org/my-image:. /// public const string AttributeContainerImageTags = "container.image.tags"; /// - /// Container labels, being the label name, the value being the label value + /// Container labels, being the label name, the value being the label value. /// public const string AttributeContainerLabelTemplate = "container.label"; /// - /// Deprecated, use container.label instead + /// Deprecated, use container.label instead. /// - [Obsolete("Replaced by container.label")] + [Obsolete("Replaced by container.label.")] public const string AttributeContainerLabelsTemplate = "container.labels"; /// - /// Container name used by container runtime + /// Container name used by container runtime. /// public const string AttributeContainerName = "container.name"; /// - /// The container runtime managing this container + /// The container runtime managing this container. /// public const string AttributeContainerRuntime = "container.runtime"; /// - /// Deprecated, use cpu.mode instead + /// Deprecated, use cpu.mode instead. /// public static class ContainerCpuStateValues { /// - /// When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows) + /// When tasks of the cgroup are in user mode (Linux). When all container processes are in user mode (Windows). /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string User = "user"; /// - /// When CPU is used by the system (host OS) + /// When CPU is used by the system (host OS). /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string System = "system"; /// - /// When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows) + /// When tasks of the cgroup are in kernel mode (Linux). When all container processes are in kernel mode (Windows). /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Kernel = "kernel"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs index 9e04aee7cf..d5f227e744 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CpuAttributes.cs @@ -15,52 +15,52 @@ namespace OpenTelemetry.SemanticConventions; public static class CpuAttributes { /// - /// The mode of the CPU + /// The mode of the CPU. /// public const string AttributeCpuMode = "cpu.mode"; /// - /// The mode of the CPU + /// The mode of the CPU. /// public static class CpuModeValues { /// - /// user + /// user. /// public const string User = "user"; /// - /// system + /// system. /// public const string System = "system"; /// - /// nice + /// nice. /// public const string Nice = "nice"; /// - /// idle + /// idle. /// public const string Idle = "idle"; /// - /// iowait + /// iowait. /// public const string Iowait = "iowait"; /// - /// interrupt + /// interrupt. /// public const string Interrupt = "interrupt"; /// - /// steal + /// steal. /// public const string Steal = "steal"; /// - /// kernel + /// kernel. /// public const string Kernel = "kernel"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs index 7f728af41a..adaef65554 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs @@ -15,718 +15,718 @@ namespace OpenTelemetry.SemanticConventions; public static class DbAttributes { /// - /// The consistency level of the query. Based on consistency values from CQL + /// The consistency level of the query. Based on consistency values from CQL. /// public const string AttributeDbCassandraConsistencyLevel = "db.cassandra.consistency_level"; /// - /// The data center of the coordinating node for a query + /// The data center of the coordinating node for a query. /// public const string AttributeDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc"; /// - /// The ID of the coordinating node for a query + /// The ID of the coordinating node for a query. /// public const string AttributeDbCassandraCoordinatorId = "db.cassandra.coordinator.id"; /// - /// Whether or not the query is idempotent + /// Whether or not the query is idempotent. /// public const string AttributeDbCassandraIdempotence = "db.cassandra.idempotence"; /// - /// The fetch size used for paging, i.e. how many rows will be returned at once + /// The fetch size used for paging, i.e. how many rows will be returned at once. /// public const string AttributeDbCassandraPageSize = "db.cassandra.page_size"; /// - /// The number of times a query was speculatively executed. Not set or 0 if the query was not executed speculatively + /// The number of times a query was speculatively executed. Not set or 0 if the query was not executed speculatively. /// public const string AttributeDbCassandraSpeculativeExecutionCount = "db.cassandra.speculative_execution_count"; /// - /// Deprecated, use db.collection.name instead + /// Deprecated, use db.collection.name instead. /// - [Obsolete("Replaced by db.collection.name")] + [Obsolete("Replaced by db.collection.name.")] public const string AttributeDbCassandraTable = "db.cassandra.table"; /// - /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation SHOULD use a combination of parameters that would make the name unique, for example, combining attributes server.address, server.port, and db.namespace, formatted as server.address:server.port/db.namespace. Instrumentations that generate connection pool name following different patterns SHOULD document it + /// The name of the connection pool; unique within the instrumented application. In case the connection pool implementation doesn't provide a name, instrumentation SHOULD use a combination of parameters that would make the name unique, for example, combining attributes server.address, server.port, and db.namespace, formatted as server.address:server.port/db.namespace. Instrumentations that generate connection pool name following different patterns SHOULD document it. /// public const string AttributeDbClientConnectionPoolName = "db.client.connection.pool.name"; /// - /// The state of a connection in the pool + /// The state of a connection in the pool. /// public const string AttributeDbClientConnectionState = "db.client.connection.state"; /// - /// Deprecated, use db.client.connection.pool.name instead + /// Deprecated, use db.client.connection.pool.name instead. /// - [Obsolete("Replaced by db.client.connection.pool.name")] + [Obsolete("Replaced by db.client.connection.pool.name.")] public const string AttributeDbClientConnectionsPoolName = "db.client.connections.pool.name"; /// - /// Deprecated, use db.client.connection.state instead + /// Deprecated, use db.client.connection.state instead. /// - [Obsolete("Replaced by db.client.connection.state")] + [Obsolete("Replaced by db.client.connection.state.")] public const string AttributeDbClientConnectionsState = "db.client.connections.state"; /// - /// The name of a collection (table, container) within the database + /// The name of a collection (table, container) within the database. /// /// /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. /// If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. - /// For batch operations, if the individual operations are known to have the same collection name then that collection name SHOULD be used, otherwise db.collection.name SHOULD NOT be captured + /// For batch operations, if the individual operations are known to have the same collection name then that collection name SHOULD be used, otherwise db.collection.name SHOULD NOT be captured. /// public const string AttributeDbCollectionName = "db.collection.name"; /// - /// Deprecated, use server.address, server.port attributes instead + /// Deprecated, use server.address, server.port attributes instead. /// - [Obsolete("Replaced by server.address and server.port")] + [Obsolete("Replaced by server.address and server.port.")] public const string AttributeDbConnectionString = "db.connection_string"; /// - /// Unique Cosmos client instance id + /// Unique Cosmos client instance id. /// public const string AttributeDbCosmosdbClientId = "db.cosmosdb.client_id"; /// - /// Cosmos client connection mode + /// Cosmos client connection mode. /// public const string AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode"; /// - /// Deprecated, use db.collection.name instead + /// Deprecated, use db.collection.name instead. /// - [Obsolete("Replaced by db.collection.name")] + [Obsolete("Replaced by db.collection.name.")] public const string AttributeDbCosmosdbContainer = "db.cosmosdb.container"; /// - /// CosmosDB Operation Type + /// CosmosDB Operation Type. /// public const string AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type"; /// - /// RU consumed for that operation + /// RU consumed for that operation. /// public const string AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge"; /// - /// Request payload size in bytes + /// Request payload size in bytes. /// public const string AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length"; /// - /// Cosmos DB status code + /// Cosmos DB status code. /// public const string AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code"; /// - /// Cosmos DB sub status code + /// Cosmos DB sub status code. /// public const string AttributeDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code"; /// - /// Deprecated, use db.namespace instead + /// Deprecated, use db.namespace instead. /// - [Obsolete("Replaced by db.namespace")] + [Obsolete("Replaced by db.namespace.")] public const string AttributeDbElasticsearchClusterName = "db.elasticsearch.cluster.name"; /// - /// Represents the human-readable identifier of the node/instance to which a request was routed + /// Represents the human-readable identifier of the node/instance to which a request was routed. /// public const string AttributeDbElasticsearchNodeName = "db.elasticsearch.node.name"; /// - /// A dynamic value in the url path + /// A dynamic value in the url path. /// /// - /// Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format db.elasticsearch.path_parts., where is the url path part name. The implementation SHOULD reference the elasticsearch schema in order to map the path part values to their names + /// Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format db.elasticsearch.path_parts., where is the url path part name. The implementation SHOULD reference the elasticsearch schema in order to map the path part values to their names. /// public const string AttributeDbElasticsearchPathPartsTemplate = "db.elasticsearch.path_parts"; /// - /// Deprecated, no general replacement at this time. For Elasticsearch, use db.elasticsearch.node.name instead + /// Deprecated, no general replacement at this time. For Elasticsearch, use db.elasticsearch.node.name instead. /// - [Obsolete("Deprecated, no general replacement at this time. For Elasticsearch, use db.elasticsearch.node.name instead")] + [Obsolete("Deprecated, no general replacement at this time. For Elasticsearch, use db.elasticsearch.node.name instead.")] public const string AttributeDbInstanceId = "db.instance.id"; /// - /// Removed, no replacement at this time + /// Removed, no replacement at this time. /// - [Obsolete("Removed as not used")] + [Obsolete("Removed as not used.")] public const string AttributeDbJdbcDriverClassname = "db.jdbc.driver_classname"; /// - /// Deprecated, use db.collection.name instead + /// Deprecated, use db.collection.name instead. /// - [Obsolete("Replaced by db.collection.name")] + [Obsolete("Replaced by db.collection.name.")] public const string AttributeDbMongodbCollection = "db.mongodb.collection"; /// - /// Deprecated, SQL Server instance is now populated as a part of db.namespace attribute + /// Deprecated, SQL Server instance is now populated as a part of db.namespace attribute. /// - [Obsolete("Deprecated, no replacement at this time")] + [Obsolete("Deprecated, no replacement at this time.")] public const string AttributeDbMssqlInstanceName = "db.mssql.instance_name"; /// - /// Deprecated, use db.namespace instead + /// Deprecated, use db.namespace instead. /// - [Obsolete("Replaced by db.namespace")] + [Obsolete("Replaced by db.namespace.")] public const string AttributeDbName = "db.name"; /// - /// The name of the database, fully qualified within the server address and port + /// The name of the database, fully qualified within the server address and port. /// /// /// If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. /// Semantic conventions for individual database systems SHOULD document what db.namespace means in the context of that system. - /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization + /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. /// public const string AttributeDbNamespace = "db.namespace"; /// - /// Deprecated, use db.operation.name instead + /// Deprecated, use db.operation.name instead. /// - [Obsolete("Replaced by db.operation.name")] + [Obsolete("Replaced by db.operation.name.")] public const string AttributeDbOperation = "db.operation"; /// - /// The number of queries included in a batch operation + /// The number of queries included in a batch operation. /// /// - /// Operations are only considered batches when they contain two or more operations, and so db.operation.batch.size SHOULD never be 1 + /// Operations are only considered batches when they contain two or more operations, and so db.operation.batch.size SHOULD never be 1. /// public const string AttributeDbOperationBatchSize = "db.operation.batch.size"; /// - /// The name of the operation or command being executed + /// The name of the operation or command being executed. /// /// /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. /// If the operation name is parsed from the query text, it SHOULD be the first operation name found in the query. - /// For batch operations, if the individual operations are known to have the same operation name then that operation name SHOULD be used prepended by BATCH , otherwise db.operation.name SHOULD be BATCH or some other database system specific term if more applicable + /// For batch operations, if the individual operations are known to have the same operation name then that operation name SHOULD be used prepended by BATCH , otherwise db.operation.name SHOULD be BATCH or some other database system specific term if more applicable. /// public const string AttributeDbOperationName = "db.operation.name"; /// - /// A query parameter used in db.query.text, with being the parameter name, and the attribute value being a string representation of the parameter value + /// A query parameter used in db.query.text, with being the parameter name, and the attribute value being a string representation of the parameter value. /// /// /// Query parameters should only be captured when db.query.text is parameterized with placeholders. - /// If a parameter has no name and instead is referenced only by index, then SHOULD be the 0-based index + /// If a parameter has no name and instead is referenced only by index, then SHOULD be the 0-based index. /// public const string AttributeDbQueryParameterTemplate = "db.query.parameter"; /// - /// The database query being executed + /// The database query being executed. /// /// /// For sanitization see Sanitization of db.query.text. /// For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator ; or some other database system specific separator if more applicable. - /// Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk + /// Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. /// public const string AttributeDbQueryText = "db.query.text"; /// - /// Deprecated, use db.namespace instead + /// Deprecated, use db.namespace instead. /// - [Obsolete("Replaced by db.namespace")] + [Obsolete("Replaced by db.namespace.")] public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; /// - /// Deprecated, use db.collection.name instead + /// Deprecated, use db.collection.name instead. /// - [Obsolete("Replaced by db.collection.name")] + [Obsolete("Replaced by db.collection.name.")] public const string AttributeDbSqlTable = "db.sql.table"; /// - /// The database statement being executed + /// The database statement being executed. /// - [Obsolete("Replaced by db.query.text")] + [Obsolete("Replaced by db.query.text.")] public const string AttributeDbStatement = "db.statement"; /// - /// The database management system (DBMS) product as identified by the client instrumentation + /// The database management system (DBMS) product as identified by the client instrumentation. /// /// - /// The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the db.system is set to postgresql based on the instrumentation's best knowledge + /// The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the db.system is set to postgresql based on the instrumentation's best knowledge. /// public const string AttributeDbSystem = "db.system"; /// - /// Deprecated, no replacement at this time + /// Deprecated, no replacement at this time. /// - [Obsolete("No replacement at this time")] + [Obsolete("No replacement at this time.")] public const string AttributeDbUser = "db.user"; /// - /// The consistency level of the query. Based on consistency values from CQL + /// The consistency level of the query. Based on consistency values from CQL. /// public static class DbCassandraConsistencyLevelValues { /// - /// all + /// all. /// public const string All = "all"; /// - /// each_quorum + /// each_quorum. /// public const string EachQuorum = "each_quorum"; /// - /// quorum + /// quorum. /// public const string Quorum = "quorum"; /// - /// local_quorum + /// local_quorum. /// public const string LocalQuorum = "local_quorum"; /// - /// one + /// one. /// public const string One = "one"; /// - /// two + /// two. /// public const string Two = "two"; /// - /// three + /// three. /// public const string Three = "three"; /// - /// local_one + /// local_one. /// public const string LocalOne = "local_one"; /// - /// any + /// any. /// public const string Any = "any"; /// - /// serial + /// serial. /// public const string Serial = "serial"; /// - /// local_serial + /// local_serial. /// public const string LocalSerial = "local_serial"; } /// - /// The state of a connection in the pool + /// The state of a connection in the pool. /// public static class DbClientConnectionStateValues { /// - /// idle + /// idle. /// public const string Idle = "idle"; /// - /// used + /// used. /// public const string Used = "used"; } /// - /// Deprecated, use db.client.connection.state instead + /// Deprecated, use db.client.connection.state instead. /// public static class DbClientConnectionsStateValues { /// - /// idle + /// idle. /// - [Obsolete("Replaced by db.client.connection.state")] + [Obsolete("Replaced by db.client.connection.state.")] public const string Idle = "idle"; /// - /// used + /// used. /// - [Obsolete("Replaced by db.client.connection.state")] + [Obsolete("Replaced by db.client.connection.state.")] public const string Used = "used"; } /// - /// Cosmos client connection mode + /// Cosmos client connection mode. /// public static class DbCosmosdbConnectionModeValues { /// - /// Gateway (HTTP) connections mode + /// Gateway (HTTP) connections mode. /// public const string Gateway = "gateway"; /// - /// Direct connection + /// Direct connection. /// public const string Direct = "direct"; } /// - /// CosmosDB Operation Type + /// CosmosDB Operation Type. /// public static class DbCosmosdbOperationTypeValues { /// - /// invalid + /// invalid. /// public const string Invalid = "Invalid"; /// - /// create + /// create. /// public const string Create = "Create"; /// - /// patch + /// patch. /// public const string Patch = "Patch"; /// - /// read + /// read. /// public const string Read = "Read"; /// - /// read_feed + /// read_feed. /// public const string ReadFeed = "ReadFeed"; /// - /// delete + /// delete. /// public const string Delete = "Delete"; /// - /// replace + /// replace. /// public const string Replace = "Replace"; /// - /// execute + /// execute. /// public const string Execute = "Execute"; /// - /// query + /// query. /// public const string Query = "Query"; /// - /// head + /// head. /// public const string Head = "Head"; /// - /// head_feed + /// head_feed. /// public const string HeadFeed = "HeadFeed"; /// - /// upsert + /// upsert. /// public const string Upsert = "Upsert"; /// - /// batch + /// batch. /// public const string Batch = "Batch"; /// - /// query_plan + /// query_plan. /// public const string QueryPlan = "QueryPlan"; /// - /// execute_javascript + /// execute_javascript. /// public const string ExecuteJavascript = "ExecuteJavaScript"; } /// - /// The database management system (DBMS) product as identified by the client instrumentation + /// The database management system (DBMS) product as identified by the client instrumentation. /// public static class DbSystemValues { /// - /// Some other SQL database. Fallback only. See notes + /// Some other SQL database. Fallback only. See notes. /// public const string OtherSql = "other_sql"; /// - /// Adabas (Adaptable Database System) + /// Adabas (Adaptable Database System). /// public const string Adabas = "adabas"; /// - /// Deprecated, use intersystems_cache instead + /// Deprecated, use intersystems_cache instead. /// public const string Cache = "cache"; /// - /// InterSystems Caché + /// InterSystems Caché. /// public const string IntersystemsCache = "intersystems_cache"; /// - /// Apache Cassandra + /// Apache Cassandra. /// public const string Cassandra = "cassandra"; /// - /// ClickHouse + /// ClickHouse. /// public const string Clickhouse = "clickhouse"; /// - /// Deprecated, use other_sql instead + /// Deprecated, use other_sql instead. /// public const string Cloudscape = "cloudscape"; /// - /// CockroachDB + /// CockroachDB. /// public const string Cockroachdb = "cockroachdb"; /// - /// Deprecated, no replacement at this time + /// Deprecated, no replacement at this time. /// public const string Coldfusion = "coldfusion"; /// - /// Microsoft Azure Cosmos DB + /// Microsoft Azure Cosmos DB. /// public const string Cosmosdb = "cosmosdb"; /// - /// Couchbase + /// Couchbase. /// public const string Couchbase = "couchbase"; /// - /// CouchDB + /// CouchDB. /// public const string Couchdb = "couchdb"; /// - /// IBM Db2 + /// IBM Db2. /// public const string Db2 = "db2"; /// - /// Apache Derby + /// Apache Derby. /// public const string Derby = "derby"; /// - /// Amazon DynamoDB + /// Amazon DynamoDB. /// public const string Dynamodb = "dynamodb"; /// - /// EnterpriseDB + /// EnterpriseDB. /// public const string Edb = "edb"; /// - /// Elasticsearch + /// Elasticsearch. /// public const string Elasticsearch = "elasticsearch"; /// - /// FileMaker + /// FileMaker. /// public const string Filemaker = "filemaker"; /// - /// Firebird + /// Firebird. /// public const string Firebird = "firebird"; /// - /// Deprecated, use other_sql instead + /// Deprecated, use other_sql instead. /// public const string Firstsql = "firstsql"; /// - /// Apache Geode + /// Apache Geode. /// public const string Geode = "geode"; /// - /// H2 + /// H2. /// public const string H2 = "h2"; /// - /// SAP HANA + /// SAP HANA. /// public const string Hanadb = "hanadb"; /// - /// Apache HBase + /// Apache HBase. /// public const string Hbase = "hbase"; /// - /// Apache Hive + /// Apache Hive. /// public const string Hive = "hive"; /// - /// HyperSQL DataBase + /// HyperSQL DataBase. /// public const string Hsqldb = "hsqldb"; /// - /// InfluxDB + /// InfluxDB. /// public const string Influxdb = "influxdb"; /// - /// Informix + /// Informix. /// public const string Informix = "informix"; /// - /// Ingres + /// Ingres. /// public const string Ingres = "ingres"; /// - /// InstantDB + /// InstantDB. /// public const string Instantdb = "instantdb"; /// - /// InterBase + /// InterBase. /// public const string Interbase = "interbase"; /// - /// MariaDB + /// MariaDB. /// public const string Mariadb = "mariadb"; /// - /// SAP MaxDB + /// SAP MaxDB. /// public const string Maxdb = "maxdb"; /// - /// Memcached + /// Memcached. /// public const string Memcached = "memcached"; /// - /// MongoDB + /// MongoDB. /// public const string Mongodb = "mongodb"; /// - /// Microsoft SQL Server + /// Microsoft SQL Server. /// public const string Mssql = "mssql"; /// - /// Deprecated, Microsoft SQL Server Compact is discontinued + /// Deprecated, Microsoft SQL Server Compact is discontinued. /// public const string Mssqlcompact = "mssqlcompact"; /// - /// MySQL + /// MySQL. /// public const string Mysql = "mysql"; /// - /// Neo4j + /// Neo4j. /// public const string Neo4j = "neo4j"; /// - /// Netezza + /// Netezza. /// public const string Netezza = "netezza"; /// - /// OpenSearch + /// OpenSearch. /// public const string Opensearch = "opensearch"; /// - /// Oracle Database + /// Oracle Database. /// public const string Oracle = "oracle"; /// - /// Pervasive PSQL + /// Pervasive PSQL. /// public const string Pervasive = "pervasive"; /// - /// PointBase + /// PointBase. /// public const string Pointbase = "pointbase"; /// - /// PostgreSQL + /// PostgreSQL. /// public const string Postgresql = "postgresql"; /// - /// Progress Database + /// Progress Database. /// public const string Progress = "progress"; /// - /// Redis + /// Redis. /// public const string Redis = "redis"; /// - /// Amazon Redshift + /// Amazon Redshift. /// public const string Redshift = "redshift"; /// - /// Cloud Spanner + /// Cloud Spanner. /// public const string Spanner = "spanner"; /// - /// SQLite + /// SQLite. /// public const string Sqlite = "sqlite"; /// - /// Sybase + /// Sybase. /// public const string Sybase = "sybase"; /// - /// Teradata + /// Teradata. /// public const string Teradata = "teradata"; /// - /// Trino + /// Trino. /// public const string Trino = "trino"; /// - /// Vertica + /// Vertica. /// public const string Vertica = "vertica"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs index 7119853d88..692bf8b875 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs @@ -15,13 +15,13 @@ namespace OpenTelemetry.SemanticConventions; public static class DeploymentAttributes { /// - /// 'Deprecated, use deployment.environment.name instead.' + /// 'Deprecated, use deployment.environment.name instead.'. /// - [Obsolete("Deprecated, use deployment.environment.name instead")] + [Obsolete("Deprecated, use deployment.environment.name instead.")] public const string AttributeDeploymentEnvironment = "deployment.environment"; /// - /// Name of the deployment environment (aka deployment tier) + /// Name of the deployment environment (aka deployment tier). /// /// /// deployment.environment.name does not affect the uniqueness constraints defined through @@ -31,38 +31,38 @@ public static class DeploymentAttributes ///

    ///

      ///
    • service.name=frontend, deployment.environment.name=production
    • - ///
    • service.name=frontend, deployment.environment.name=staging
    • + ///
    • service.name=frontend, deployment.environment.name=staging.
    • ///
    ///
    public const string AttributeDeploymentEnvironmentName = "deployment.environment.name"; /// - /// The id of the deployment + /// The id of the deployment. /// public const string AttributeDeploymentId = "deployment.id"; /// - /// The name of the deployment + /// The name of the deployment. /// public const string AttributeDeploymentName = "deployment.name"; /// - /// The status of the deployment + /// The status of the deployment. /// public const string AttributeDeploymentStatus = "deployment.status"; /// - /// The status of the deployment + /// The status of the deployment. /// public static class DeploymentStatusValues { /// - /// failed + /// failed. /// public const string Failed = "failed"; /// - /// succeeded + /// succeeded. /// public const string Succeeded = "succeeded"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs index 41bc27913d..6958b8805c 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DestinationAttributes.cs @@ -15,15 +15,15 @@ namespace OpenTelemetry.SemanticConventions; public static class DestinationAttributes { /// - /// Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name + /// Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. /// /// - /// When observed from the source side, and when communicating through an intermediary, destination.address SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available + /// When observed from the source side, and when communicating through an intermediary, destination.address SHOULD represent the destination address behind any intermediaries, for example proxies, if it's available. /// public const string AttributeDestinationAddress = "destination.address"; /// - /// Destination port number + /// Destination port number. /// public const string AttributeDestinationPort = "destination.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs index 04ca99d4ef..b68a08e80e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeviceAttributes.cs @@ -15,34 +15,34 @@ namespace OpenTelemetry.SemanticConventions; public static class DeviceAttributes { /// - /// A unique identifier representing the device + /// A unique identifier representing the device. /// /// - /// The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the vendor identifier. On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found here on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence + /// The device identifier MUST only be defined using the values outlined below. This value is not an advertising identifier and MUST NOT be used as such. On iOS (Swift or Objective-C), this value MUST be equal to the vendor identifier. On Android (Java or Kotlin), this value MUST be equal to the Firebase Installation ID or a globally unique UUID which is persisted across sessions in your application. More information can be found here on best practices and exact implementation details. Caution should be taken when storing personal data or anything which can identify a user. GDPR and data protection laws may apply, ensure you do your own due diligence. /// public const string AttributeDeviceId = "device.id"; /// - /// The name of the device manufacturer + /// The name of the device manufacturer. /// /// - /// The Android OS provides this field via Build. iOS apps SHOULD hardcode the value Apple + /// The Android OS provides this field via Build. iOS apps SHOULD hardcode the value Apple. /// public const string AttributeDeviceManufacturer = "device.manufacturer"; /// - /// The model identifier for the device + /// The model identifier for the device. /// /// - /// It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device + /// It's recommended this value represents a machine-readable version of the model identifier rather than the market or consumer-friendly name of the device. /// public const string AttributeDeviceModelIdentifier = "device.model.identifier"; /// - /// The marketing name for the device model + /// The marketing name for the device model. /// /// - /// It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative + /// It's recommended this value represents a human-readable version of the device model rather than a machine-readable alternative. /// public const string AttributeDeviceModelName = "device.model.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs index 14921a8de6..820f933a23 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DiskAttributes.cs @@ -15,22 +15,22 @@ namespace OpenTelemetry.SemanticConventions; public static class DiskAttributes { /// - /// The disk IO operation direction + /// The disk IO operation direction. /// public const string AttributeDiskIoDirection = "disk.io.direction"; /// - /// The disk IO operation direction + /// The disk IO operation direction. /// public static class DiskIoDirectionValues { /// - /// read + /// read. /// public const string Read = "read"; /// - /// write + /// write. /// public const string Write = "write"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs index 04dbadfd07..a84dace046 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DnsAttributes.cs @@ -15,10 +15,10 @@ namespace OpenTelemetry.SemanticConventions; public static class DnsAttributes { /// - /// The name being queried + /// The name being queried. /// /// - /// If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively + /// If the name field contains non-printable characters (below 32 or above 126), those characters should be represented as escaped base 10 integers (\DDD). Back slashes and quotes should be escaped. Tabs, carriage returns, and line feeds should be converted to \t, \r, and \n respectively. /// public const string AttributeDnsQuestionName = "dns.question.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs index de53dabda3..26b493cfa2 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EnduserAttributes.cs @@ -15,20 +15,20 @@ namespace OpenTelemetry.SemanticConventions; public static class EnduserAttributes { /// - /// Deprecated, use user.id instead + /// Deprecated, use user.id instead. /// - [Obsolete("Replaced by user.id attribute")] + [Obsolete("Replaced by user.id attribute.")] public const string AttributeEnduserId = "enduser.id"; /// - /// Deprecated, use user.roles instead + /// Deprecated, use user.roles instead. /// - [Obsolete("Replaced by user.roles attribute")] + [Obsolete("Replaced by user.roles attribute.")] public const string AttributeEnduserRole = "enduser.role"; /// - /// Deprecated, no replacement at this time + /// Deprecated, no replacement at this time. /// - [Obsolete("Removed")] + [Obsolete("Removed.")] public const string AttributeEnduserScope = "enduser.scope"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs index d8edc109da..c3924017fc 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class ErrorAttributes { /// - /// Describes a class of error the operation ended with + /// Describes a class of error the operation ended with. /// /// /// The error.type SHOULD be predictable, and SHOULD have low cardinality. @@ -37,18 +37,18 @@ public static class ErrorAttributes ///

    ///

      ///
    • Use a domain-specific attribute
    • - ///
    • Set error.type to capture all errors, regardless of whether they are defined within the domain-specific set or not
    • + ///
    • Set error.type to capture all errors, regardless of whether they are defined within the domain-specific set or not.
    • ///
    ///
    public const string AttributeErrorType = "error.type"; /// - /// Describes a class of error the operation ended with + /// Describes a class of error the operation ended with. /// public static class ErrorTypeValues { /// - /// A fallback error value to be used when the instrumentation doesn't define a custom value + /// A fallback error value to be used when the instrumentation doesn't define a custom value. /// public const string Other = "_OTHER"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs index 2714806e25..cdf0c4db59 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/EventAttributes.cs @@ -15,10 +15,10 @@ namespace OpenTelemetry.SemanticConventions; public static class EventAttributes { /// - /// Identifies the class / type of event + /// Identifies the class / type of event. /// /// - /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes + /// Event names are subject to the same rules as attribute names. Notably, event names are namespaced to avoid collisions and provide a clean separation of semantics for events in separate domains like browser, mobile, and kubernetes. /// public const string AttributeEventName = "event.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs index 66e71559be..d1d24f7357 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ExceptionAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class ExceptionAttributes { /// - /// SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span + /// SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span. /// /// /// An exception is considered to have escaped (or left) the scope of a span, @@ -33,22 +33,22 @@ public static class ExceptionAttributes /// It follows that an exception may still escape the scope of the span /// even if the exception.escaped attribute was not set or set to false, /// since the event might have been recorded at a time where it was not - /// clear whether the exception will escape + /// clear whether the exception will escape. /// public const string AttributeExceptionEscaped = "exception.escaped"; /// - /// The exception message + /// The exception message. /// public const string AttributeExceptionMessage = "exception.message"; /// - /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG + /// A stacktrace as a string in the natural representation for the language runtime. The representation is to be determined and documented by each language SIG. /// public const string AttributeExceptionStacktrace = "exception.stacktrace"; /// - /// The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it + /// The type of the exception (its fully-qualified class name, if applicable). The dynamic type of the exception should be preferred over the static type in languages that support it. /// public const string AttributeExceptionType = "exception.type"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs index 981e1a4a43..688c78976b 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs @@ -15,84 +15,84 @@ namespace OpenTelemetry.SemanticConventions; public static class FaasAttributes { /// - /// A boolean that is true if the serverless function is executed for the first time (aka cold-start) + /// A boolean that is true if the serverless function is executed for the first time (aka cold-start). /// public const string AttributeFaasColdstart = "faas.coldstart"; /// - /// A string containing the schedule period as Cron Expression + /// A string containing the schedule period as Cron Expression. /// public const string AttributeFaasCron = "faas.cron"; /// - /// The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name + /// The name of the source on which the triggering operation was performed. For example, in Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. /// public const string AttributeFaasDocumentCollection = "faas.document.collection"; /// - /// The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name + /// The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the name of the file, and in Cosmos DB the table name. /// public const string AttributeFaasDocumentName = "faas.document.name"; /// - /// Describes the type of the operation that was performed on the data + /// Describes the type of the operation that was performed on the data. /// public const string AttributeFaasDocumentOperation = "faas.document.operation"; /// - /// A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC + /// A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC. /// public const string AttributeFaasDocumentTime = "faas.document.time"; /// - /// The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version + /// The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. /// /// ///
      - ///
    • AWS Lambda: Use the (full) log stream name
    • + ///
    • AWS Lambda: Use the (full) log stream name.
    • ///
    ///
    public const string AttributeFaasInstance = "faas.instance"; /// - /// The invocation ID of the current function invocation + /// The invocation ID of the current function invocation. /// public const string AttributeFaasInvocationId = "faas.invocation_id"; /// - /// The name of the invoked function + /// The name of the invoked function. /// /// - /// SHOULD be equal to the faas.name resource attribute of the invoked function + /// SHOULD be equal to the faas.name resource attribute of the invoked function. /// public const string AttributeFaasInvokedName = "faas.invoked_name"; /// - /// The cloud provider of the invoked function + /// The cloud provider of the invoked function. /// /// - /// SHOULD be equal to the cloud.provider resource attribute of the invoked function + /// SHOULD be equal to the cloud.provider resource attribute of the invoked function. /// public const string AttributeFaasInvokedProvider = "faas.invoked_provider"; /// - /// The cloud region of the invoked function + /// The cloud region of the invoked function. /// /// - /// SHOULD be equal to the cloud.region resource attribute of the invoked function + /// SHOULD be equal to the cloud.region resource attribute of the invoked function. /// public const string AttributeFaasInvokedRegion = "faas.invoked_region"; /// - /// The amount of memory available to the serverless function converted to Bytes + /// The amount of memory available to the serverless function converted to Bytes. /// /// - /// It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE provides this information (which must be multiplied by 1,048,576) + /// It's recommended to set this attribute since e.g. too little memory can easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable AWS_LAMBDA_FUNCTION_MEMORY_SIZE provides this information (which must be multiplied by 1,048,576). /// public const string AttributeFaasMaxMemory = "faas.max_memory"; /// - /// The name of the single function that this runtime instance executes + /// The name of the single function that this runtime instance executes. /// /// /// This is the name of the function as configured/deployed on the FaaS @@ -111,23 +111,23 @@ public static class FaasAttributes /// can also be seen in the resource JSON for the function). /// This means that a span attribute MUST be used, as an Azure function /// app can host multiple functions that would usually share - /// a TracerProvider (see also the cloud.resource_id attribute) + /// a TracerProvider (see also the cloud.resource_id attribute). /// /// public const string AttributeFaasName = "faas.name"; /// - /// A string containing the function invocation time in the ISO 8601 format expressed in UTC + /// A string containing the function invocation time in the ISO 8601 format expressed in UTC. /// public const string AttributeFaasTime = "faas.time"; /// - /// Type of the trigger which caused this function invocation + /// Type of the trigger which caused this function invocation. /// public const string AttributeFaasTrigger = "faas.trigger"; /// - /// The immutable version of the function being executed + /// The immutable version of the function being executed. /// /// /// Depending on the cloud provider and platform, use: @@ -139,90 +139,90 @@ public static class FaasAttributes /// (i.e., the function name plus the revision suffix). ///
  • Google Cloud Functions: The value of the /// K_REVISION environment variable.
  • - ///
  • Azure Functions: Not applicable. Do not set this attribute
  • + ///
  • Azure Functions: Not applicable. Do not set this attribute.
  • /// ///
    public const string AttributeFaasVersion = "faas.version"; /// - /// Describes the type of the operation that was performed on the data + /// Describes the type of the operation that was performed on the data. /// public static class FaasDocumentOperationValues { /// - /// When a new object is created + /// When a new object is created. /// public const string Insert = "insert"; /// - /// When an object is modified + /// When an object is modified. /// public const string Edit = "edit"; /// - /// When an object is deleted + /// When an object is deleted. /// public const string Delete = "delete"; } /// - /// The cloud provider of the invoked function + /// The cloud provider of the invoked function. /// public static class FaasInvokedProviderValues { /// - /// Alibaba Cloud + /// Alibaba Cloud. /// public const string AlibabaCloud = "alibaba_cloud"; /// - /// Amazon Web Services + /// Amazon Web Services. /// public const string Aws = "aws"; /// - /// Microsoft Azure + /// Microsoft Azure. /// public const string Azure = "azure"; /// - /// Google Cloud Platform + /// Google Cloud Platform. /// public const string Gcp = "gcp"; /// - /// Tencent Cloud + /// Tencent Cloud. /// public const string TencentCloud = "tencent_cloud"; } /// - /// Type of the trigger which caused this function invocation + /// Type of the trigger which caused this function invocation. /// public static class FaasTriggerValues { /// - /// A response to some data source operation such as a database or filesystem read/write + /// A response to some data source operation such as a database or filesystem read/write. /// public const string Datasource = "datasource"; /// - /// To provide an answer to an inbound HTTP request + /// To provide an answer to an inbound HTTP request. /// public const string Http = "http"; /// - /// A function is set to be executed when messages are sent to a messaging system + /// A function is set to be executed when messages are sent to a messaging system. /// public const string Pubsub = "pubsub"; /// - /// A function is scheduled to be executed regularly + /// A function is scheduled to be executed regularly. /// public const string Timer = "timer"; /// - /// If none of the others apply + /// If none of the others apply. /// public const string Other = "other"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs index b8aee7bdc4..9c56474985 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs @@ -15,17 +15,17 @@ namespace OpenTelemetry.SemanticConventions; public static class FeatureFlagAttributes { /// - /// The unique identifier of the feature flag + /// The unique identifier of the feature flag. /// public const string AttributeFeatureFlagKey = "feature_flag.key"; /// - /// The name of the service provider that performs the flag evaluation + /// The name of the service provider that performs the flag evaluation. /// public const string AttributeFeatureFlagProviderName = "feature_flag.provider_name"; /// - /// SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used + /// SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. /// /// /// A semantic identifier, commonly referred to as a variant, provides a means @@ -35,7 +35,7 @@ public static class FeatureFlagAttributes ///

    /// A stringified version of the value can be used in situations where a /// semantic identifier is unavailable. String representation of the value - /// should be determined by the implementer + /// should be determined by the implementer. /// public const string AttributeFeatureFlagVariant = "feature_flag.variant"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs index 1310eae87e..a0c9fd58dd 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs @@ -15,30 +15,30 @@ namespace OpenTelemetry.SemanticConventions; public static class FileAttributes { ///

    - /// Directory where the file is located. It should include the drive letter, when appropriate + /// Directory where the file is located. It should include the drive letter, when appropriate. /// public const string AttributeFileDirectory = "file.directory"; /// - /// File extension, excluding the leading dot + /// File extension, excluding the leading dot. /// /// - /// When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz") + /// When the file name has multiple extensions (example.tar.gz), only the last one should be captured ("gz", not "tar.gz"). /// public const string AttributeFileExtension = "file.extension"; /// - /// Name of the file including the extension, without the directory + /// Name of the file including the extension, without the directory. /// public const string AttributeFileName = "file.name"; /// - /// Full path to the file, including the file name. It should include the drive letter, when appropriate + /// Full path to the file, including the file name. It should include the drive letter, when appropriate. /// public const string AttributeFilePath = "file.path"; /// - /// File size in bytes + /// File size in bytes. /// public const string AttributeFileSize = "file.size"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs index 2dedab1196..001052a0c8 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GcpAttributes.cs @@ -15,30 +15,30 @@ namespace OpenTelemetry.SemanticConventions; public static class GcpAttributes { /// - /// Identifies the Google Cloud service for which the official client library is intended + /// Identifies the Google Cloud service for which the official client library is intended. /// /// - /// Intended to be a stable identifier for Google Cloud client libraries that is uniform across implementation languages. The value should be derived from the canonical service domain for the service; for example, 'foo.googleapis.com' should result in a value of 'foo' + /// Intended to be a stable identifier for Google Cloud client libraries that is uniform across implementation languages. The value should be derived from the canonical service domain for the service; for example, 'foo.googleapis.com' should result in a value of 'foo'. /// public const string AttributeGcpClientService = "gcp.client.service"; /// - /// The name of the Cloud Run execution being run for the Job, as set by the CLOUD_RUN_EXECUTION environment variable + /// The name of the Cloud Run execution being run for the Job, as set by the CLOUD_RUN_EXECUTION environment variable. /// public const string AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution"; /// - /// The index for a task within an execution as provided by the CLOUD_RUN_TASK_INDEX environment variable + /// The index for a task within an execution as provided by the CLOUD_RUN_TASK_INDEX environment variable. /// public const string AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index"; /// - /// The hostname of a GCE instance. This is the full value of the default or custom hostname + /// The hostname of a GCE instance. This is the full value of the default or custom hostname. /// public const string AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname"; /// - /// The instance name of a GCE instance. This is the value provided by host.name, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the default internal DNS name + /// The instance name of a GCE instance. This is the value provided by host.name, the visible name of the instance in the Cloud Console UI, and the prefix for the default hostname of the instance as defined by the default internal DNS name. /// public const string AttributeGcpGceInstanceName = "gcp.gce.instance.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs index a100c1f1e3..16bac1669a 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs @@ -15,86 +15,86 @@ namespace OpenTelemetry.SemanticConventions; public static class GenAiAttributes { /// - /// The full response received from the GenAI model + /// The full response received from the GenAI model. /// /// - /// It's RECOMMENDED to format completions as JSON string matching OpenAI messages format + /// It's RECOMMENDED to format completions as JSON string matching OpenAI messages format. /// public const string AttributeGenAiCompletion = "gen_ai.completion"; /// - /// The name of the operation being performed + /// The name of the operation being performed. /// /// - /// If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value + /// If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value. /// public const string AttributeGenAiOperationName = "gen_ai.operation.name"; /// - /// The full prompt sent to the GenAI model + /// The full prompt sent to the GenAI model. /// /// - /// It's RECOMMENDED to format prompts as JSON string matching OpenAI messages format + /// It's RECOMMENDED to format prompts as JSON string matching OpenAI messages format. /// public const string AttributeGenAiPrompt = "gen_ai.prompt"; /// - /// The frequency penalty setting for the GenAI request + /// The frequency penalty setting for the GenAI request. /// public const string AttributeGenAiRequestFrequencyPenalty = "gen_ai.request.frequency_penalty"; /// - /// The maximum number of tokens the model generates for a request + /// The maximum number of tokens the model generates for a request. /// public const string AttributeGenAiRequestMaxTokens = "gen_ai.request.max_tokens"; /// - /// The name of the GenAI model a request is being made to + /// The name of the GenAI model a request is being made to. /// public const string AttributeGenAiRequestModel = "gen_ai.request.model"; /// - /// The presence penalty setting for the GenAI request + /// The presence penalty setting for the GenAI request. /// public const string AttributeGenAiRequestPresencePenalty = "gen_ai.request.presence_penalty"; /// - /// List of sequences that the model will use to stop generating further tokens + /// List of sequences that the model will use to stop generating further tokens. /// public const string AttributeGenAiRequestStopSequences = "gen_ai.request.stop_sequences"; /// - /// The temperature setting for the GenAI request + /// The temperature setting for the GenAI request. /// public const string AttributeGenAiRequestTemperature = "gen_ai.request.temperature"; /// - /// The top_k sampling setting for the GenAI request + /// The top_k sampling setting for the GenAI request. /// public const string AttributeGenAiRequestTopK = "gen_ai.request.top_k"; /// - /// The top_p sampling setting for the GenAI request + /// The top_p sampling setting for the GenAI request. /// public const string AttributeGenAiRequestTopP = "gen_ai.request.top_p"; /// - /// Array of reasons the model stopped generating tokens, corresponding to each generation received + /// Array of reasons the model stopped generating tokens, corresponding to each generation received. /// public const string AttributeGenAiResponseFinishReasons = "gen_ai.response.finish_reasons"; /// - /// The unique identifier for the completion + /// The unique identifier for the completion. /// public const string AttributeGenAiResponseId = "gen_ai.response.id"; /// - /// The name of the model that generated the response + /// The name of the model that generated the response. /// public const string AttributeGenAiResponseModel = "gen_ai.response.model"; /// - /// The Generative AI product as identified by the client or server instrumentation + /// The Generative AI product as identified by the client or server instrumentation. /// /// /// The gen_ai.system describes a family of GenAI models with specific model identified @@ -105,91 +105,91 @@ public static class GenAiAttributes /// is set to openai based on the instrumentation's best knowledge. ///

    /// For custom model, a custom friendly name SHOULD be used. - /// If none of these options apply, the gen_ai.system SHOULD be set to _OTHER + /// If none of these options apply, the gen_ai.system SHOULD be set to _OTHER. /// public const string AttributeGenAiSystem = "gen_ai.system"; ///

    - /// The type of token being counted + /// The type of token being counted. /// public const string AttributeGenAiTokenType = "gen_ai.token.type"; /// - /// Deprecated, use gen_ai.usage.output_tokens instead + /// Deprecated, use gen_ai.usage.output_tokens instead. /// - [Obsolete("Replaced by gen_ai.usage.output_tokens attribute")] + [Obsolete("Replaced by gen_ai.usage.output_tokens attribute.")] public const string AttributeGenAiUsageCompletionTokens = "gen_ai.usage.completion_tokens"; /// - /// The number of tokens used in the GenAI input (prompt) + /// The number of tokens used in the GenAI input (prompt). /// public const string AttributeGenAiUsageInputTokens = "gen_ai.usage.input_tokens"; /// - /// The number of tokens used in the GenAI response (completion) + /// The number of tokens used in the GenAI response (completion). /// public const string AttributeGenAiUsageOutputTokens = "gen_ai.usage.output_tokens"; /// - /// Deprecated, use gen_ai.usage.input_tokens instead + /// Deprecated, use gen_ai.usage.input_tokens instead. /// - [Obsolete("Replaced by gen_ai.usage.input_tokens attribute")] + [Obsolete("Replaced by gen_ai.usage.input_tokens attribute.")] public const string AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens"; /// - /// The name of the operation being performed + /// The name of the operation being performed. /// public static class GenAiOperationNameValues { /// - /// Chat completion operation such as OpenAI Chat API + /// Chat completion operation such as OpenAI Chat API. /// public const string Chat = "chat"; /// - /// Text completions operation such as OpenAI Completions API (Legacy) + /// Text completions operation such as OpenAI Completions API (Legacy). /// public const string TextCompletion = "text_completion"; } /// - /// The Generative AI product as identified by the client or server instrumentation + /// The Generative AI product as identified by the client or server instrumentation. /// public static class GenAiSystemValues { /// - /// OpenAI + /// OpenAI. /// public const string Openai = "openai"; /// - /// Vertex AI + /// Vertex AI. /// public const string VertexAi = "vertex_ai"; /// - /// Anthropic + /// Anthropic. /// public const string Anthropic = "anthropic"; /// - /// Cohere + /// Cohere. /// public const string Cohere = "cohere"; } /// - /// The type of token being counted + /// The type of token being counted. /// public static class GenAiTokenTypeValues { /// - /// Input tokens (prompt, input, etc.) + /// Input tokens (prompt, input, etc.). /// public const string Input = "input"; /// - /// Output tokens (completion, response, etc.) + /// Output tokens (completion, response, etc.). /// public const string Completion = "output"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs index 847f8f1df7..6be62a6d5e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GoAttributes.cs @@ -15,22 +15,22 @@ namespace OpenTelemetry.SemanticConventions; public static class GoAttributes { /// - /// The type of memory + /// The type of memory. /// public const string AttributeGoMemoryType = "go.memory.type"; /// - /// The type of memory + /// The type of memory. /// public static class GoMemoryTypeValues { /// - /// Memory allocated from the heap that is reserved for stack space, whether or not it is currently in-use + /// Memory allocated from the heap that is reserved for stack space, whether or not it is currently in-use. /// public const string Stack = "stack"; /// - /// Memory used by the Go runtime, excluding other categories of memory usage described in this enumeration + /// Memory used by the Go runtime, excluding other categories of memory usage described in this enumeration. /// public const string Other = "other"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs index b770ad6a73..2cf790dc32 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GraphqlAttributes.cs @@ -15,40 +15,40 @@ namespace OpenTelemetry.SemanticConventions; public static class GraphqlAttributes { /// - /// The GraphQL document being executed + /// The GraphQL document being executed. /// /// - /// The value may be sanitized to exclude sensitive information + /// The value may be sanitized to exclude sensitive information. /// public const string AttributeGraphqlDocument = "graphql.document"; /// - /// The name of the operation being executed + /// The name of the operation being executed. /// public const string AttributeGraphqlOperationName = "graphql.operation.name"; /// - /// The type of the operation being executed + /// The type of the operation being executed. /// public const string AttributeGraphqlOperationType = "graphql.operation.type"; /// - /// The type of the operation being executed + /// The type of the operation being executed. /// public static class GraphqlOperationTypeValues { /// - /// GraphQL query + /// GraphQL query. /// public const string Query = "query"; /// - /// GraphQL mutation + /// GraphQL mutation. /// public const string Mutation = "mutation"; /// - /// GraphQL subscription + /// GraphQL subscription. /// public const string Subscription = "subscription"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs index 5d4aea042f..5a5bf23188 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HerokuAttributes.cs @@ -15,17 +15,17 @@ namespace OpenTelemetry.SemanticConventions; public static class HerokuAttributes { /// - /// Unique identifier for the application + /// Unique identifier for the application. /// public const string AttributeHerokuAppId = "heroku.app.id"; /// - /// Commit hash for the current release + /// Commit hash for the current release. /// public const string AttributeHerokuReleaseCommit = "heroku.release.commit"; /// - /// Time and date the release was created + /// Time and date the release was created. /// public const string AttributeHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs index d4e9506030..288b949243 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HostAttributes.cs @@ -15,131 +15,131 @@ namespace OpenTelemetry.SemanticConventions; public static class HostAttributes { /// - /// The CPU architecture the host system is running on + /// The CPU architecture the host system is running on. /// public const string AttributeHostArch = "host.arch"; /// - /// The amount of level 2 memory cache available to the processor (in Bytes) + /// The amount of level 2 memory cache available to the processor (in Bytes). /// public const string AttributeHostCpuCacheL2Size = "host.cpu.cache.l2.size"; /// - /// Family or generation of the CPU + /// Family or generation of the CPU. /// public const string AttributeHostCpuFamily = "host.cpu.family"; /// - /// Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family + /// Model identifier. It provides more granular information about the CPU, distinguishing it from other CPUs within the same family. /// public const string AttributeHostCpuModelId = "host.cpu.model.id"; /// - /// Model designation of the processor + /// Model designation of the processor. /// public const string AttributeHostCpuModelName = "host.cpu.model.name"; /// - /// Stepping or core revisions + /// Stepping or core revisions. /// public const string AttributeHostCpuStepping = "host.cpu.stepping"; /// - /// Processor manufacturer identifier. A maximum 12-character string + /// Processor manufacturer identifier. A maximum 12-character string. /// /// - /// CPUID command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string + /// CPUID command returns the vendor ID string in EBX, EDX and ECX registers. Writing these to memory in this order results in a 12-character string. /// public const string AttributeHostCpuVendorId = "host.cpu.vendor.id"; /// - /// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the machine-id. See the table below for the sources to use to determine the machine-id based on operating system + /// Unique host ID. For Cloud, this must be the instance_id assigned by the cloud provider. For non-containerized systems, this should be the machine-id. See the table below for the sources to use to determine the machine-id based on operating system. /// public const string AttributeHostId = "host.id"; /// - /// VM image ID or host OS image ID. For Cloud, this value is from the provider + /// VM image ID or host OS image ID. For Cloud, this value is from the provider. /// public const string AttributeHostImageId = "host.image.id"; /// - /// Name of the VM image or OS install the host was instantiated from + /// Name of the VM image or OS install the host was instantiated from. /// public const string AttributeHostImageName = "host.image.name"; /// - /// The version string of the VM image or host OS as defined in Version Attributes + /// The version string of the VM image or host OS as defined in Version Attributes. /// public const string AttributeHostImageVersion = "host.image.version"; /// - /// Available IP addresses of the host, excluding loopback interfaces + /// Available IP addresses of the host, excluding loopback interfaces. /// /// - /// IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the RFC 5952 format + /// IPv4 Addresses MUST be specified in dotted-quad notation. IPv6 addresses MUST be specified in the RFC 5952 format. /// public const string AttributeHostIp = "host.ip"; /// - /// Available MAC addresses of the host, excluding loopback interfaces + /// Available MAC addresses of the host, excluding loopback interfaces. /// /// - /// MAC Addresses MUST be represented in IEEE RA hexadecimal form: as hyphen-separated octets in uppercase hexadecimal form from most to least significant + /// MAC Addresses MUST be represented in IEEE RA hexadecimal form: as hyphen-separated octets in uppercase hexadecimal form from most to least significant. /// public const string AttributeHostMac = "host.mac"; /// - /// Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user + /// Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully qualified hostname, or another name specified by the user. /// public const string AttributeHostName = "host.name"; /// - /// Type of host. For Cloud, this must be the machine type + /// Type of host. For Cloud, this must be the machine type. /// public const string AttributeHostType = "host.type"; /// - /// The CPU architecture the host system is running on + /// The CPU architecture the host system is running on. /// public static class HostArchValues { /// - /// AMD64 + /// AMD64. /// public const string Amd64 = "amd64"; /// - /// ARM32 + /// ARM32. /// public const string Arm32 = "arm32"; /// - /// ARM64 + /// ARM64. /// public const string Arm64 = "arm64"; /// - /// Itanium + /// Itanium. /// public const string Ia64 = "ia64"; /// - /// 32-bit PowerPC + /// 32-bit PowerPC. /// public const string Ppc32 = "ppc32"; /// - /// 64-bit PowerPC + /// 64-bit PowerPC. /// public const string Ppc64 = "ppc64"; /// - /// IBM z/Architecture + /// IBM z/Architecture. /// public const string S390x = "s390x"; /// - /// 32-bit x86 + /// 32-bit x86. /// public const string X86 = "x86"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs index 48dec9fbc1..8e30d56d98 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs @@ -15,51 +15,51 @@ namespace OpenTelemetry.SemanticConventions; public static class HttpAttributes { /// - /// Deprecated, use client.address instead + /// Deprecated, use client.address instead. /// - [Obsolete("Replaced by client.address")] + [Obsolete("Replaced by client.address.")] public const string AttributeHttpClientIp = "http.client_ip"; /// - /// State of the HTTP connection in the HTTP connection pool + /// State of the HTTP connection in the HTTP connection pool. /// public const string AttributeHttpConnectionState = "http.connection.state"; /// - /// Deprecated, use network.protocol.name instead + /// Deprecated, use network.protocol.name instead. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string AttributeHttpFlavor = "http.flavor"; /// - /// Deprecated, use one of server.address, client.address or http.request.header.host instead, depending on the usage + /// Deprecated, use one of server.address, client.address or http.request.header.host instead, depending on the usage. /// - [Obsolete("Replaced by one of server.address, client.address or http.request.header.host, depending on the usage")] + [Obsolete("Replaced by one of server.address, client.address or http.request.header.host, depending on the usage.")] public const string AttributeHttpHost = "http.host"; /// - /// Deprecated, use http.request.method instead + /// Deprecated, use http.request.method instead. /// - [Obsolete("Replaced by http.request.method")] + [Obsolete("Replaced by http.request.method.")] public const string AttributeHttpMethod = "http.method"; /// - /// The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size + /// The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size. /// public const string AttributeHttpRequestBodySize = "http.request.body.size"; /// - /// HTTP request headers, being the normalized HTTP Header name (lowercase), the value being the header values + /// HTTP request headers, being the normalized HTTP Header name (lowercase), the value being the header values. /// /// /// Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information. /// The User-Agent header is already captured in the user_agent.original attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers + /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. /// public const string AttributeHttpRequestHeaderTemplate = "http.request.header"; /// - /// HTTP request method + /// HTTP request method. /// /// /// HTTP request method value SHOULD be "known" to the instrumentation. @@ -75,232 +75,232 @@ public static class HttpAttributes ///

    /// HTTP method names are case-sensitive and http.request.method attribute value MUST match a known HTTP method name exactly. /// Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. - /// Tracing instrumentations that do so, MUST also set http.request.method_original to the original value + /// Tracing instrumentations that do so, MUST also set http.request.method_original to the original value. /// public const string AttributeHttpRequestMethod = "http.request.method"; ///

    - /// Original HTTP method sent by the client in the request line + /// Original HTTP method sent by the client in the request line. /// public const string AttributeHttpRequestMethodOriginal = "http.request.method_original"; /// - /// The ordinal number of request resending attempt (for any reason, including redirects) + /// The ordinal number of request resending attempt (for any reason, including redirects). /// /// - /// The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other) + /// The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). /// public const string AttributeHttpRequestResendCount = "http.request.resend_count"; /// - /// The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any + /// The total size of the request in bytes. This should be the total number of bytes sent over the wire, including the request line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and request body if any. /// public const string AttributeHttpRequestSize = "http.request.size"; /// - /// Deprecated, use http.request.header.content-length instead + /// Deprecated, use http.request.header.content-length instead. /// - [Obsolete("Replaced by http.request.header.content-length")] + [Obsolete("Replaced by http.request.header.content-length.")] public const string AttributeHttpRequestContentLength = "http.request_content_length"; /// - /// Deprecated, use http.request.body.size instead + /// Deprecated, use http.request.body.size instead. /// - [Obsolete("Replaced by http.request.body.size")] + [Obsolete("Replaced by http.request.body.size.")] public const string AttributeHttpRequestContentLengthUncompressed = "http.request_content_length_uncompressed"; /// - /// The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size + /// The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the Content-Length header. For requests using transport encoding, this should be the compressed size. /// public const string AttributeHttpResponseBodySize = "http.response.body.size"; /// - /// HTTP response headers, being the normalized HTTP Header name (lowercase), the value being the header values + /// HTTP response headers, being the normalized HTTP Header name (lowercase), the value being the header values. /// /// /// Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information. /// Users MAY explicitly configure instrumentations to capture them even though it is not recommended. - /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers + /// The attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers. /// public const string AttributeHttpResponseHeaderTemplate = "http.response.header"; /// - /// The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any + /// The total size of the response in bytes. This should be the total number of bytes sent over the wire, including the status line (HTTP/1.1), framing (HTTP/2 and HTTP/3), headers, and response body and trailers if any. /// public const string AttributeHttpResponseSize = "http.response.size"; /// - /// HTTP response status code + /// HTTP response status code. /// public const string AttributeHttpResponseStatusCode = "http.response.status_code"; /// - /// Deprecated, use http.response.header.content-length instead + /// Deprecated, use http.response.header.content-length instead. /// - [Obsolete("Replaced by http.response.header.content-length")] + [Obsolete("Replaced by http.response.header.content-length.")] public const string AttributeHttpResponseContentLength = "http.response_content_length"; /// - /// Deprecated, use http.response.body.size instead + /// Deprecated, use http.response.body.size instead. /// - [Obsolete("Replace by http.response.body.size")] + [Obsolete("Replace by http.response.body.size.")] public const string AttributeHttpResponseContentLengthUncompressed = "http.response_content_length_uncompressed"; /// - /// The matched route, that is, the path template in the format used by the respective server framework + /// The matched route, that is, the path template in the format used by the respective server framework. /// /// /// MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. - /// SHOULD include the application root if there is one + /// SHOULD include the application root if there is one. /// public const string AttributeHttpRoute = "http.route"; /// - /// Deprecated, use url.scheme instead + /// Deprecated, use url.scheme instead. /// - [Obsolete("Replaced by url.scheme instead")] + [Obsolete("Replaced by url.scheme instead.")] public const string AttributeHttpScheme = "http.scheme"; /// - /// Deprecated, use server.address instead + /// Deprecated, use server.address instead. /// - [Obsolete("Replaced by server.address")] + [Obsolete("Replaced by server.address.")] public const string AttributeHttpServerName = "http.server_name"; /// - /// Deprecated, use http.response.status_code instead + /// Deprecated, use http.response.status_code instead. /// - [Obsolete("Replaced by http.response.status_code")] + [Obsolete("Replaced by http.response.status_code.")] public const string AttributeHttpStatusCode = "http.status_code"; /// - /// Deprecated, use url.path and url.query instead + /// Deprecated, use url.path and url.query instead. /// - [Obsolete("Split to url.path and `url.query")] + [Obsolete("Split to url.path and `url.query.")] public const string AttributeHttpTarget = "http.target"; /// - /// Deprecated, use url.full instead + /// Deprecated, use url.full instead. /// - [Obsolete("Replaced by url.full")] + [Obsolete("Replaced by url.full.")] public const string AttributeHttpUrl = "http.url"; /// - /// Deprecated, use user_agent.original instead + /// Deprecated, use user_agent.original instead. /// - [Obsolete("Replaced by user_agent.original")] + [Obsolete("Replaced by user_agent.original.")] public const string AttributeHttpUserAgent = "http.user_agent"; /// - /// State of the HTTP connection in the HTTP connection pool + /// State of the HTTP connection in the HTTP connection pool. /// public static class HttpConnectionStateValues { /// - /// active state + /// active state. /// public const string Active = "active"; /// - /// idle state + /// idle state. /// public const string Idle = "idle"; } /// - /// Deprecated, use network.protocol.name instead + /// Deprecated, use network.protocol.name instead. /// public static class HttpFlavorValues { /// - /// HTTP/1.0 + /// HTTP/1.0. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string Http10 = "1.0"; /// - /// HTTP/1.1 + /// HTTP/1.1. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string Http11 = "1.1"; /// - /// HTTP/2 + /// HTTP/2. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string Http20 = "2.0"; /// - /// HTTP/3 + /// HTTP/3. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string Http30 = "3.0"; /// - /// SPDY protocol + /// SPDY protocol. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string Spdy = "SPDY"; /// - /// QUIC protocol + /// QUIC protocol. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string Quic = "QUIC"; } /// - /// HTTP request method + /// HTTP request method. /// public static class HttpRequestMethodValues { /// - /// CONNECT method + /// CONNECT method. /// public const string Connect = "CONNECT"; /// - /// DELETE method + /// DELETE method. /// public const string Delete = "DELETE"; /// - /// GET method + /// GET method. /// public const string Get = "GET"; /// - /// HEAD method + /// HEAD method. /// public const string Head = "HEAD"; /// - /// OPTIONS method + /// OPTIONS method. /// public const string Options = "OPTIONS"; /// - /// PATCH method + /// PATCH method. /// public const string Patch = "PATCH"; /// - /// POST method + /// POST method. /// public const string Post = "POST"; /// - /// PUT method + /// PUT method. /// public const string Put = "PUT"; /// - /// TRACE method + /// TRACE method. /// public const string Trace = "TRACE"; /// - /// Any HTTP method that the instrumentation has no prior knowledge of + /// Any HTTP method that the instrumentation has no prior knowledge of. /// public const string Other = "_OTHER"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs index d8a2b6b686..981fd5a53f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/IosAttributes.cs @@ -15,47 +15,47 @@ namespace OpenTelemetry.SemanticConventions; public static class IosAttributes { /// - /// Deprecated use the device.app.lifecycle event definition including ios.state as a payload field instead + /// Deprecated use the device.app.lifecycle event definition including ios.state as a payload field instead. /// /// - /// The iOS lifecycle states are defined in the UIApplicationDelegate documentation, and from which the OS terminology column values are derived + /// The iOS lifecycle states are defined in the UIApplicationDelegate documentation, and from which the OS terminology column values are derived. /// - [Obsolete("Moved to a payload field of device.app.lifecycle")] + [Obsolete("Moved to a payload field of device.app.lifecycle.")] public const string AttributeIosState = "ios.state"; /// - /// Deprecated use the device.app.lifecycle event definition including ios.state as a payload field instead + /// Deprecated use the device.app.lifecycle event definition including ios.state as a payload field instead. /// public static class IosStateValues { /// - /// The app has become active. Associated with UIKit notification applicationDidBecomeActive + /// The app has become active. Associated with UIKit notification applicationDidBecomeActive. /// - [Obsolete("Moved to a payload field of device.app.lifecycle")] + [Obsolete("Moved to a payload field of device.app.lifecycle.")] public const string Active = "active"; /// - /// The app is now inactive. Associated with UIKit notification applicationWillResignActive + /// The app is now inactive. Associated with UIKit notification applicationWillResignActive. /// - [Obsolete("Moved to a payload field of device.app.lifecycle")] + [Obsolete("Moved to a payload field of device.app.lifecycle.")] public const string Inactive = "inactive"; /// - /// The app is now in the background. This value is associated with UIKit notification applicationDidEnterBackground + /// The app is now in the background. This value is associated with UIKit notification applicationDidEnterBackground. /// - [Obsolete("Moved to a payload field of device.app.lifecycle")] + [Obsolete("Moved to a payload field of device.app.lifecycle.")] public const string Background = "background"; /// - /// The app is now in the foreground. This value is associated with UIKit notification applicationWillEnterForeground + /// The app is now in the foreground. This value is associated with UIKit notification applicationWillEnterForeground. /// - [Obsolete("Moved to a payload field of device.app.lifecycle")] + [Obsolete("Moved to a payload field of device.app.lifecycle.")] public const string Foreground = "foreground"; /// - /// The app is about to terminate. Associated with UIKit notification applicationWillTerminate + /// The app is about to terminate. Associated with UIKit notification applicationWillTerminate. /// - [Obsolete("Moved to a payload field of device.app.lifecycle")] + [Obsolete("Moved to a payload field of device.app.lifecycle.")] public const string Terminate = "terminate"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs index f51450b140..687d2e4018 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/JvmAttributes.cs @@ -15,100 +15,100 @@ namespace OpenTelemetry.SemanticConventions; public static class JvmAttributes { /// - /// Name of the buffer pool + /// Name of the buffer pool. /// /// - /// Pool names are generally obtained via BufferPoolMXBean#getName() + /// Pool names are generally obtained via BufferPoolMXBean#getName(). /// public const string AttributeJvmBufferPoolName = "jvm.buffer.pool.name"; /// - /// Name of the garbage collector action + /// Name of the garbage collector action. /// /// - /// Garbage collector action is generally obtained via GarbageCollectionNotificationInfo#getGcAction() + /// Garbage collector action is generally obtained via GarbageCollectionNotificationInfo#getGcAction(). /// public const string AttributeJvmGcAction = "jvm.gc.action"; /// - /// Name of the garbage collector + /// Name of the garbage collector. /// /// - /// Garbage collector name is generally obtained via GarbageCollectionNotificationInfo#getGcName() + /// Garbage collector name is generally obtained via GarbageCollectionNotificationInfo#getGcName(). /// public const string AttributeJvmGcName = "jvm.gc.name"; /// - /// Name of the memory pool + /// Name of the memory pool. /// /// - /// Pool names are generally obtained via MemoryPoolMXBean#getName() + /// Pool names are generally obtained via MemoryPoolMXBean#getName(). /// public const string AttributeJvmMemoryPoolName = "jvm.memory.pool.name"; /// - /// The type of memory + /// The type of memory. /// public const string AttributeJvmMemoryType = "jvm.memory.type"; /// - /// Whether the thread is daemon or not + /// Whether the thread is daemon or not. /// public const string AttributeJvmThreadDaemon = "jvm.thread.daemon"; /// - /// State of the thread + /// State of the thread. /// public const string AttributeJvmThreadState = "jvm.thread.state"; /// - /// The type of memory + /// The type of memory. /// public static class JvmMemoryTypeValues { /// - /// Heap memory + /// Heap memory. /// public const string Heap = "heap"; /// - /// Non-heap memory + /// Non-heap memory. /// public const string NonHeap = "non_heap"; } /// - /// State of the thread + /// State of the thread. /// public static class JvmThreadStateValues { /// - /// A thread that has not yet started is in this state + /// A thread that has not yet started is in this state. /// public const string New = "new"; /// - /// A thread executing in the Java virtual machine is in this state + /// A thread executing in the Java virtual machine is in this state. /// public const string Runnable = "runnable"; /// - /// A thread that is blocked waiting for a monitor lock is in this state + /// A thread that is blocked waiting for a monitor lock is in this state. /// public const string Blocked = "blocked"; /// - /// A thread that is waiting indefinitely for another thread to perform a particular action is in this state + /// A thread that is waiting indefinitely for another thread to perform a particular action is in this state. /// public const string Waiting = "waiting"; /// - /// A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state + /// A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. /// public const string TimedWaiting = "timed_waiting"; /// - /// A thread that has exited is in this state + /// A thread that has exited is in this state. /// public const string Terminated = "terminated"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs index e1013adc29..34ae1936b1 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs @@ -15,12 +15,12 @@ namespace OpenTelemetry.SemanticConventions; public static class K8sAttributes { /// - /// The name of the cluster + /// The name of the cluster. /// public const string AttributeK8sClusterName = "k8s.cluster.name"; /// - /// A pseudo-ID for the cluster, set to the UID of the kube-system namespace + /// A pseudo-ID for the cluster, set to the UID of the kube-system namespace. /// /// /// K8s doesn't have support for obtaining a cluster ID. If this is ever @@ -46,123 +46,123 @@ public static class K8sAttributes /// ///

    /// Therefore, UIDs between clusters should be extremely unlikely to - /// conflict + /// conflict. /// public const string AttributeK8sClusterUid = "k8s.cluster.uid"; ///

    - /// The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (container.name) + /// The name of the Container from Pod specification, must be unique within a Pod. Container runtime usually uses different globally unique name (container.name). /// public const string AttributeK8sContainerName = "k8s.container.name"; /// - /// Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec + /// Number of times the container was restarted. This attribute can be used to identify a particular container (running or stopped) within a container spec. /// public const string AttributeK8sContainerRestartCount = "k8s.container.restart_count"; /// - /// Last terminated reason of the Container + /// Last terminated reason of the Container. /// public const string AttributeK8sContainerStatusLastTerminatedReason = "k8s.container.status.last_terminated_reason"; /// - /// The name of the CronJob + /// The name of the CronJob. /// public const string AttributeK8sCronjobName = "k8s.cronjob.name"; /// - /// The UID of the CronJob + /// The UID of the CronJob. /// public const string AttributeK8sCronjobUid = "k8s.cronjob.uid"; /// - /// The name of the DaemonSet + /// The name of the DaemonSet. /// public const string AttributeK8sDaemonsetName = "k8s.daemonset.name"; /// - /// The UID of the DaemonSet + /// The UID of the DaemonSet. /// public const string AttributeK8sDaemonsetUid = "k8s.daemonset.uid"; /// - /// The name of the Deployment + /// The name of the Deployment. /// public const string AttributeK8sDeploymentName = "k8s.deployment.name"; /// - /// The UID of the Deployment + /// The UID of the Deployment. /// public const string AttributeK8sDeploymentUid = "k8s.deployment.uid"; /// - /// The name of the Job + /// The name of the Job. /// public const string AttributeK8sJobName = "k8s.job.name"; /// - /// The UID of the Job + /// The UID of the Job. /// public const string AttributeK8sJobUid = "k8s.job.uid"; /// - /// The name of the namespace that the pod is running in + /// The name of the namespace that the pod is running in. /// public const string AttributeK8sNamespaceName = "k8s.namespace.name"; /// - /// The name of the Node + /// The name of the Node. /// public const string AttributeK8sNodeName = "k8s.node.name"; /// - /// The UID of the Node + /// The UID of the Node. /// public const string AttributeK8sNodeUid = "k8s.node.uid"; /// - /// The annotation key-value pairs placed on the Pod, the being the annotation name, the value being the annotation value + /// The annotation key-value pairs placed on the Pod, the being the annotation name, the value being the annotation value. /// public const string AttributeK8sPodAnnotationTemplate = "k8s.pod.annotation"; /// - /// The label key-value pairs placed on the Pod, the being the label name, the value being the label value + /// The label key-value pairs placed on the Pod, the being the label name, the value being the label value. /// public const string AttributeK8sPodLabelTemplate = "k8s.pod.label"; /// - /// Deprecated, use k8s.pod.label instead + /// Deprecated, use k8s.pod.label instead. /// - [Obsolete("Replaced by k8s.pod.label")] + [Obsolete("Replaced by k8s.pod.label.")] public const string AttributeK8sPodLabelsTemplate = "k8s.pod.labels"; /// - /// The name of the Pod + /// The name of the Pod. /// public const string AttributeK8sPodName = "k8s.pod.name"; /// - /// The UID of the Pod + /// The UID of the Pod. /// public const string AttributeK8sPodUid = "k8s.pod.uid"; /// - /// The name of the ReplicaSet + /// The name of the ReplicaSet. /// public const string AttributeK8sReplicasetName = "k8s.replicaset.name"; /// - /// The UID of the ReplicaSet + /// The UID of the ReplicaSet. /// public const string AttributeK8sReplicasetUid = "k8s.replicaset.uid"; /// - /// The name of the StatefulSet + /// The name of the StatefulSet. /// public const string AttributeK8sStatefulsetName = "k8s.statefulset.name"; /// - /// The UID of the StatefulSet + /// The UID of the StatefulSet. /// public const string AttributeK8sStatefulsetUid = "k8s.statefulset.uid"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs index a93e9712ca..b15a6e506e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LinuxAttributes.cs @@ -15,22 +15,22 @@ namespace OpenTelemetry.SemanticConventions; public static class LinuxAttributes { /// - /// The Linux Slab memory state + /// The Linux Slab memory state. /// public const string AttributeLinuxMemorySlabState = "linux.memory.slab.state"; /// - /// The Linux Slab memory state + /// The Linux Slab memory state. /// public static class LinuxMemorySlabStateValues { /// - /// reclaimable + /// reclaimable. /// public const string Reclaimable = "reclaimable"; /// - /// unreclaimable + /// unreclaimable. /// public const string Unreclaimable = "unreclaimable"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs index c0ad17a9ed..6b4dc2714d 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs @@ -15,59 +15,59 @@ namespace OpenTelemetry.SemanticConventions; public static class LogAttributes { /// - /// The basename of the file + /// The basename of the file. /// public const string AttributeLogFileName = "log.file.name"; /// - /// The basename of the file, with symlinks resolved + /// The basename of the file, with symlinks resolved. /// public const string AttributeLogFileNameResolved = "log.file.name_resolved"; /// - /// The full path to the file + /// The full path to the file. /// public const string AttributeLogFilePath = "log.file.path"; /// - /// The full path to the file, with symlinks resolved + /// The full path to the file, with symlinks resolved. /// public const string AttributeLogFilePathResolved = "log.file.path_resolved"; /// - /// The stream associated with the log. See below for a list of well-known values + /// The stream associated with the log. See below for a list of well-known values. /// public const string AttributeLogIostream = "log.iostream"; /// - /// The complete orignal Log Record + /// The complete orignal Log Record. /// /// - /// This value MAY be added when processing a Log Record which was originally transmitted as a string or equivalent data type AND the Body field of the Log Record does not contain the same value. (e.g. a syslog or a log record read from a file.) + /// This value MAY be added when processing a Log Record which was originally transmitted as a string or equivalent data type AND the Body field of the Log Record does not contain the same value. (e.g. a syslog or a log record read from a file.). /// public const string AttributeLogRecordOriginal = "log.record.original"; /// - /// A unique identifier for the Log Record + /// A unique identifier for the Log Record. /// /// /// If an id is provided, other log records with the same id will be considered duplicates and can be removed safely. This means, that two distinguishable log records MUST have different values. - /// The id MAY be an Universally Unique Lexicographically Sortable Identifier (ULID), but other identifiers (e.g. UUID) may be used as needed + /// The id MAY be an Universally Unique Lexicographically Sortable Identifier (ULID), but other identifiers (e.g. UUID) may be used as needed. /// public const string AttributeLogRecordUid = "log.record.uid"; /// - /// The stream associated with the log. See below for a list of well-known values + /// The stream associated with the log. See below for a list of well-known values. /// public static class LogIostreamValues { /// - /// Logs from stdout stream + /// Logs from stdout stream. /// public const string Stdout = "stdout"; /// - /// Events from stderr stream + /// Events from stderr stream. /// public const string Stderr = "stderr"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs index af856c42b4..3bf2a05fc7 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessageAttributes.cs @@ -15,44 +15,44 @@ namespace OpenTelemetry.SemanticConventions; public static class MessageAttributes { /// - /// Deprecated, use rpc.message.compressed_size instead + /// Deprecated, use rpc.message.compressed_size instead. /// - [Obsolete("Replaced by rpc.message.compressed_size")] + [Obsolete("Replaced by rpc.message.compressed_size.")] public const string AttributeMessageCompressedSize = "message.compressed_size"; /// - /// Deprecated, use rpc.message.id instead + /// Deprecated, use rpc.message.id instead. /// - [Obsolete("Replaced by rpc.message.id")] + [Obsolete("Replaced by rpc.message.id.")] public const string AttributeMessageId = "message.id"; /// - /// Deprecated, use rpc.message.type instead + /// Deprecated, use rpc.message.type instead. /// - [Obsolete("Replaced by rpc.message.type")] + [Obsolete("Replaced by rpc.message.type.")] public const string AttributeMessageType = "message.type"; /// - /// Deprecated, use rpc.message.uncompressed_size instead + /// Deprecated, use rpc.message.uncompressed_size instead. /// - [Obsolete("Replaced by rpc.message.uncompressed_size")] + [Obsolete("Replaced by rpc.message.uncompressed_size.")] public const string AttributeMessageUncompressedSize = "message.uncompressed_size"; /// - /// Deprecated, use rpc.message.type instead + /// Deprecated, use rpc.message.type instead. /// public static class MessageTypeValues { /// - /// sent + /// sent. /// - [Obsolete("Replaced by rpc.message.type")] + [Obsolete("Replaced by rpc.message.type.")] public const string Sent = "SENT"; /// - /// received + /// received. /// - [Obsolete("Replaced by rpc.message.type")] + [Obsolete("Replaced by rpc.message.type.")] public const string Received = "RECEIVED"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs index b3851d2ad3..31baedee43 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs @@ -15,438 +15,438 @@ namespace OpenTelemetry.SemanticConventions; public static class MessagingAttributes { /// - /// The number of messages sent, received, or processed in the scope of the batching operation + /// The number of messages sent, received, or processed in the scope of the batching operation. /// /// - /// Instrumentations SHOULD NOT set messaging.batch.message_count on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use messaging.batch.message_count for batching APIs and SHOULD NOT use it for single-message APIs + /// Instrumentations SHOULD NOT set messaging.batch.message_count on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use messaging.batch.message_count for batching APIs and SHOULD NOT use it for single-message APIs. /// public const string AttributeMessagingBatchMessageCount = "messaging.batch.message_count"; /// - /// A unique identifier for the client that consumes or produces a message + /// A unique identifier for the client that consumes or produces a message. /// public const string AttributeMessagingClientId = "messaging.client.id"; /// - /// The name of the consumer group with which a consumer is associated + /// The name of the consumer group with which a consumer is associated. /// /// - /// Semantic conventions for individual messaging systems SHOULD document whether messaging.consumer.group.name is applicable and what it means in the context of that system + /// Semantic conventions for individual messaging systems SHOULD document whether messaging.consumer.group.name is applicable and what it means in the context of that system. /// public const string AttributeMessagingConsumerGroupName = "messaging.consumer.group.name"; /// - /// A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name) + /// A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name). /// public const string AttributeMessagingDestinationAnonymous = "messaging.destination.anonymous"; /// - /// The message destination name + /// The message destination name. /// /// /// Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If - /// the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker + /// the broker doesn't have such notion, the destination name SHOULD uniquely identify the broker. /// public const string AttributeMessagingDestinationName = "messaging.destination.name"; /// - /// The identifier of the partition messages are sent to or received from, unique within the messaging.destination.name + /// The identifier of the partition messages are sent to or received from, unique within the messaging.destination.name. /// public const string AttributeMessagingDestinationPartitionId = "messaging.destination.partition.id"; /// - /// The name of the destination subscription from which a message is consumed + /// The name of the destination subscription from which a message is consumed. /// /// - /// Semantic conventions for individual messaging systems SHOULD document whether messaging.destination.subscription.name is applicable and what it means in the context of that system + /// Semantic conventions for individual messaging systems SHOULD document whether messaging.destination.subscription.name is applicable and what it means in the context of that system. /// public const string AttributeMessagingDestinationSubscriptionName = "messaging.destination.subscription.name"; /// - /// Low cardinality representation of the messaging destination name + /// Low cardinality representation of the messaging destination name. /// /// - /// Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation + /// Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation. /// public const string AttributeMessagingDestinationTemplate = "messaging.destination.template"; /// - /// A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed + /// A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed. /// public const string AttributeMessagingDestinationTemporary = "messaging.destination.temporary"; /// - /// Deprecated, no replacement at this time + /// Deprecated, no replacement at this time. /// - [Obsolete("No replacement at this time")] + [Obsolete("No replacement at this time.")] public const string AttributeMessagingDestinationPublishAnonymous = "messaging.destination_publish.anonymous"; /// - /// Deprecated, no replacement at this time + /// Deprecated, no replacement at this time. /// - [Obsolete("No replacement at this time")] + [Obsolete("No replacement at this time.")] public const string AttributeMessagingDestinationPublishName = "messaging.destination_publish.name"; /// - /// Deprecated, use messaging.consumer.group.name instead + /// Deprecated, use messaging.consumer.group.name instead. /// - [Obsolete("Replaced by messaging.consumer.group.name")] + [Obsolete("Replaced by messaging.consumer.group.name.")] public const string AttributeMessagingEventhubsConsumerGroup = "messaging.eventhubs.consumer.group"; /// - /// The UTC epoch seconds at which the message has been accepted and stored in the entity + /// The UTC epoch seconds at which the message has been accepted and stored in the entity. /// public const string AttributeMessagingEventhubsMessageEnqueuedTime = "messaging.eventhubs.message.enqueued_time"; /// - /// The ack deadline in seconds set for the modify ack deadline request + /// The ack deadline in seconds set for the modify ack deadline request. /// public const string AttributeMessagingGcpPubsubMessageAckDeadline = "messaging.gcp_pubsub.message.ack_deadline"; /// - /// The ack id for a given message + /// The ack id for a given message. /// public const string AttributeMessagingGcpPubsubMessageAckId = "messaging.gcp_pubsub.message.ack_id"; /// - /// The delivery attempt for a given message + /// The delivery attempt for a given message. /// public const string AttributeMessagingGcpPubsubMessageDeliveryAttempt = "messaging.gcp_pubsub.message.delivery_attempt"; /// - /// The ordering key for a given message. If the attribute is not present, the message does not have an ordering key + /// The ordering key for a given message. If the attribute is not present, the message does not have an ordering key. /// public const string AttributeMessagingGcpPubsubMessageOrderingKey = "messaging.gcp_pubsub.message.ordering_key"; /// - /// Deprecated, use messaging.consumer.group.name instead + /// Deprecated, use messaging.consumer.group.name instead. /// - [Obsolete("Replaced by messaging.consumer.group.name")] + [Obsolete("Replaced by messaging.consumer.group.name.")] public const string AttributeMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; /// - /// Deprecated, use messaging.destination.partition.id instead + /// Deprecated, use messaging.destination.partition.id instead. /// - [Obsolete("Replaced by messaging.destination.partition.id")] + [Obsolete("Replaced by messaging.destination.partition.id.")] public const string AttributeMessagingKafkaDestinationPartition = "messaging.kafka.destination.partition"; /// - /// Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from messaging.message.id in that they're not unique. If the key is null, the attribute MUST NOT be set + /// Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from messaging.message.id in that they're not unique. If the key is null, the attribute MUST NOT be set. /// /// - /// If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value + /// If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value. /// public const string AttributeMessagingKafkaMessageKey = "messaging.kafka.message.key"; /// - /// Deprecated, use messaging.kafka.offset instead + /// Deprecated, use messaging.kafka.offset instead. /// - [Obsolete("Replaced by messaging.kafka.offset")] + [Obsolete("Replaced by messaging.kafka.offset.")] public const string AttributeMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; /// - /// A boolean that is true if the message is a tombstone + /// A boolean that is true if the message is a tombstone. /// public const string AttributeMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone"; /// - /// The offset of a record in the corresponding Kafka partition + /// The offset of a record in the corresponding Kafka partition. /// public const string AttributeMessagingKafkaOffset = "messaging.kafka.offset"; /// - /// The size of the message body in bytes + /// The size of the message body in bytes. /// /// /// This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed - /// body size should be used + /// body size should be used. /// public const string AttributeMessagingMessageBodySize = "messaging.message.body.size"; /// - /// The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID" + /// The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called "Correlation ID". /// public const string AttributeMessagingMessageConversationId = "messaging.message.conversation_id"; /// - /// The size of the message body and metadata in bytes + /// The size of the message body and metadata in bytes. /// /// /// This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed - /// size should be used + /// size should be used. /// public const string AttributeMessagingMessageEnvelopeSize = "messaging.message.envelope.size"; /// - /// A value used by the messaging system as an identifier for the message, represented as a string + /// A value used by the messaging system as an identifier for the message, represented as a string. /// public const string AttributeMessagingMessageId = "messaging.message.id"; /// - /// Deprecated, use messaging.operation.type instead + /// Deprecated, use messaging.operation.type instead. /// - [Obsolete("Replaced by messaging.operation.type")] + [Obsolete("Replaced by messaging.operation.type.")] public const string AttributeMessagingOperation = "messaging.operation"; /// - /// The system-specific name of the messaging operation + /// The system-specific name of the messaging operation. /// public const string AttributeMessagingOperationName = "messaging.operation.name"; /// - /// A string identifying the type of the messaging operation + /// A string identifying the type of the messaging operation. /// /// - /// If a custom value is used, it MUST be of low cardinality + /// If a custom value is used, it MUST be of low cardinality. /// public const string AttributeMessagingOperationType = "messaging.operation.type"; /// - /// RabbitMQ message routing key + /// RabbitMQ message routing key. /// public const string AttributeMessagingRabbitmqDestinationRoutingKey = "messaging.rabbitmq.destination.routing_key"; /// - /// RabbitMQ message delivery tag + /// RabbitMQ message delivery tag. /// public const string AttributeMessagingRabbitmqMessageDeliveryTag = "messaging.rabbitmq.message.delivery_tag"; /// - /// Deprecated, use messaging.consumer.group.name instead + /// Deprecated, use messaging.consumer.group.name instead. /// - [Obsolete("Replaced by messaging.consumer.group.name on the consumer spans. No replacement for producer spans")] + [Obsolete("Replaced by messaging.consumer.group.name on the consumer spans. No replacement for producer spans.")] public const string AttributeMessagingRocketmqClientGroup = "messaging.rocketmq.client_group"; /// - /// Model of message consumption. This only applies to consumer spans + /// Model of message consumption. This only applies to consumer spans. /// public const string AttributeMessagingRocketmqConsumptionModel = "messaging.rocketmq.consumption_model"; /// - /// The delay time level for delay message, which determines the message delay time + /// The delay time level for delay message, which determines the message delay time. /// public const string AttributeMessagingRocketmqMessageDelayTimeLevel = "messaging.rocketmq.message.delay_time_level"; /// - /// The timestamp in milliseconds that the delay message is expected to be delivered to consumer + /// The timestamp in milliseconds that the delay message is expected to be delivered to consumer. /// public const string AttributeMessagingRocketmqMessageDeliveryTimestamp = "messaging.rocketmq.message.delivery_timestamp"; /// - /// It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group + /// It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group. /// public const string AttributeMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group"; /// - /// Key(s) of message, another way to mark message besides message id + /// Key(s) of message, another way to mark message besides message id. /// public const string AttributeMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys"; /// - /// The secondary classifier of message besides topic + /// The secondary classifier of message besides topic. /// public const string AttributeMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag"; /// - /// Type of message + /// Type of message. /// public const string AttributeMessagingRocketmqMessageType = "messaging.rocketmq.message.type"; /// - /// Namespace of RocketMQ resources, resources in different namespaces are individual + /// Namespace of RocketMQ resources, resources in different namespaces are individual. /// public const string AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; /// - /// Deprecated, use messaging.servicebus.destination.subscription_name instead + /// Deprecated, use messaging.servicebus.destination.subscription_name instead. /// - [Obsolete("Replaced by messaging.servicebus.destination.subscription_name")] + [Obsolete("Replaced by messaging.servicebus.destination.subscription_name.")] public const string AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name"; /// - /// Describes the settlement type + /// Describes the settlement type. /// public const string AttributeMessagingServicebusDispositionStatus = "messaging.servicebus.disposition_status"; /// - /// Number of deliveries that have been attempted for this message + /// Number of deliveries that have been attempted for this message. /// public const string AttributeMessagingServicebusMessageDeliveryCount = "messaging.servicebus.message.delivery_count"; /// - /// The UTC epoch seconds at which the message has been accepted and stored in the entity + /// The UTC epoch seconds at which the message has been accepted and stored in the entity. /// public const string AttributeMessagingServicebusMessageEnqueuedTime = "messaging.servicebus.message.enqueued_time"; /// - /// The messaging system as identified by the client instrumentation + /// The messaging system as identified by the client instrumentation. /// /// - /// The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the messaging.system is set to kafka based on the instrumentation's best knowledge + /// The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the messaging.system is set to kafka based on the instrumentation's best knowledge. /// public const string AttributeMessagingSystem = "messaging.system"; /// - /// A string identifying the type of the messaging operation + /// A string identifying the type of the messaging operation. /// public static class MessagingOperationTypeValues { /// - /// One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created + /// One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. /// public const string Publish = "publish"; /// - /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios + /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. /// public const string Create = "create"; /// - /// One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages + /// One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. /// public const string Receive = "receive"; /// - /// One or more messages are processed by a consumer + /// One or more messages are processed by a consumer. /// public const string Process = "process"; /// - /// One or more messages are settled + /// One or more messages are settled. /// public const string Settle = "settle"; /// - /// Deprecated. Use process instead + /// Deprecated. Use process instead. /// public const string Deliver = "deliver"; } /// - /// Model of message consumption. This only applies to consumer spans + /// Model of message consumption. This only applies to consumer spans. /// public static class MessagingRocketmqConsumptionModelValues { /// - /// Clustering consumption model + /// Clustering consumption model. /// public const string Clustering = "clustering"; /// - /// Broadcasting consumption model + /// Broadcasting consumption model. /// public const string Broadcasting = "broadcasting"; } /// - /// Type of message + /// Type of message. /// public static class MessagingRocketmqMessageTypeValues { /// - /// Normal message + /// Normal message. /// public const string Normal = "normal"; /// - /// FIFO message + /// FIFO message. /// public const string Fifo = "fifo"; /// - /// Delay message + /// Delay message. /// public const string Delay = "delay"; /// - /// Transaction message + /// Transaction message. /// public const string Transaction = "transaction"; } /// - /// Describes the settlement type + /// Describes the settlement type. /// public static class MessagingServicebusDispositionStatusValues { /// - /// Message is completed + /// Message is completed. /// public const string Complete = "complete"; /// - /// Message is abandoned + /// Message is abandoned. /// public const string Abandon = "abandon"; /// - /// Message is sent to dead letter queue + /// Message is sent to dead letter queue. /// public const string DeadLetter = "dead_letter"; /// - /// Message is deferred + /// Message is deferred. /// public const string Defer = "defer"; } /// - /// The messaging system as identified by the client instrumentation + /// The messaging system as identified by the client instrumentation. /// public static class MessagingSystemValues { /// - /// Apache ActiveMQ + /// Apache ActiveMQ. /// public const string Activemq = "activemq"; /// - /// Amazon Simple Queue Service (SQS) + /// Amazon Simple Queue Service (SQS). /// public const string AwsSqs = "aws_sqs"; /// - /// Azure Event Grid + /// Azure Event Grid. /// public const string Eventgrid = "eventgrid"; /// - /// Azure Event Hubs + /// Azure Event Hubs. /// public const string Eventhubs = "eventhubs"; /// - /// Azure Service Bus + /// Azure Service Bus. /// public const string Servicebus = "servicebus"; /// - /// Google Cloud Pub/Sub + /// Google Cloud Pub/Sub. /// public const string GcpPubsub = "gcp_pubsub"; /// - /// Java Message Service + /// Java Message Service. /// public const string Jms = "jms"; /// - /// Apache Kafka + /// Apache Kafka. /// public const string Kafka = "kafka"; /// - /// RabbitMQ + /// RabbitMQ. /// public const string Rabbitmq = "rabbitmq"; /// - /// Apache RocketMQ + /// Apache RocketMQ. /// public const string Rocketmq = "rocketmq"; /// - /// Apache Pulsar + /// Apache Pulsar. /// public const string Pulsar = "pulsar"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs index 06fdfff932..95b28032ab 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetAttributes.cs @@ -15,152 +15,152 @@ namespace OpenTelemetry.SemanticConventions; public static class NetAttributes { /// - /// Deprecated, use network.local.address + /// Deprecated, use network.local.address. /// - [Obsolete("Replaced by network.local.address")] + [Obsolete("Replaced by network.local.address.")] public const string AttributeNetHostIp = "net.host.ip"; /// - /// Deprecated, use server.address + /// Deprecated, use server.address. /// - [Obsolete("Replaced by server.address")] + [Obsolete("Replaced by server.address.")] public const string AttributeNetHostName = "net.host.name"; /// - /// Deprecated, use server.port + /// Deprecated, use server.port. /// - [Obsolete("Replaced by server.port")] + [Obsolete("Replaced by server.port.")] public const string AttributeNetHostPort = "net.host.port"; /// - /// Deprecated, use network.peer.address + /// Deprecated, use network.peer.address. /// - [Obsolete("Replaced by network.peer.address")] + [Obsolete("Replaced by network.peer.address.")] public const string AttributeNetPeerIp = "net.peer.ip"; /// - /// Deprecated, use server.address on client spans and client.address on server spans + /// Deprecated, use server.address on client spans and client.address on server spans. /// - [Obsolete("Replaced by server.address on client spans and client.address on server spans")] + [Obsolete("Replaced by server.address on client spans and client.address on server spans.")] public const string AttributeNetPeerName = "net.peer.name"; /// - /// Deprecated, use server.port on client spans and client.port on server spans + /// Deprecated, use server.port on client spans and client.port on server spans. /// - [Obsolete("Replaced by server.port on client spans and client.port on server spans")] + [Obsolete("Replaced by server.port on client spans and client.port on server spans.")] public const string AttributeNetPeerPort = "net.peer.port"; /// - /// Deprecated, use network.protocol.name + /// Deprecated, use network.protocol.name. /// - [Obsolete("Replaced by network.protocol.name")] + [Obsolete("Replaced by network.protocol.name.")] public const string AttributeNetProtocolName = "net.protocol.name"; /// - /// Deprecated, use network.protocol.version + /// Deprecated, use network.protocol.version. /// - [Obsolete("Replaced by network.protocol.version")] + [Obsolete("Replaced by network.protocol.version.")] public const string AttributeNetProtocolVersion = "net.protocol.version"; /// - /// Deprecated, use network.transport and network.type + /// Deprecated, use network.transport and network.type. /// - [Obsolete("Split to network.transport and network.type")] + [Obsolete("Split to network.transport and network.type.")] public const string AttributeNetSockFamily = "net.sock.family"; /// - /// Deprecated, use network.local.address + /// Deprecated, use network.local.address. /// - [Obsolete("Replaced by network.local.address")] + [Obsolete("Replaced by network.local.address.")] public const string AttributeNetSockHostAddr = "net.sock.host.addr"; /// - /// Deprecated, use network.local.port + /// Deprecated, use network.local.port. /// - [Obsolete("Replaced by network.local.port")] + [Obsolete("Replaced by network.local.port.")] public const string AttributeNetSockHostPort = "net.sock.host.port"; /// - /// Deprecated, use network.peer.address + /// Deprecated, use network.peer.address. /// - [Obsolete("Replaced by network.peer.address")] + [Obsolete("Replaced by network.peer.address.")] public const string AttributeNetSockPeerAddr = "net.sock.peer.addr"; /// - /// Deprecated, no replacement at this time + /// Deprecated, no replacement at this time. /// - [Obsolete("Removed")] + [Obsolete("Removed.")] public const string AttributeNetSockPeerName = "net.sock.peer.name"; /// - /// Deprecated, use network.peer.port + /// Deprecated, use network.peer.port. /// - [Obsolete("Replaced by network.peer.port")] + [Obsolete("Replaced by network.peer.port.")] public const string AttributeNetSockPeerPort = "net.sock.peer.port"; /// - /// Deprecated, use network.transport + /// Deprecated, use network.transport. /// - [Obsolete("Replaced by network.transport")] + [Obsolete("Replaced by network.transport.")] public const string AttributeNetTransport = "net.transport"; /// - /// Deprecated, use network.transport and network.type + /// Deprecated, use network.transport and network.type. /// public static class NetSockFamilyValues { /// - /// IPv4 address + /// IPv4 address. /// - [Obsolete("Split to network.transport and network.type")] + [Obsolete("Split to network.transport and network.type.")] public const string Inet = "inet"; /// - /// IPv6 address + /// IPv6 address. /// - [Obsolete("Split to network.transport and network.type")] + [Obsolete("Split to network.transport and network.type.")] public const string Inet6 = "inet6"; /// - /// Unix domain socket path + /// Unix domain socket path. /// - [Obsolete("Split to network.transport and network.type")] + [Obsolete("Split to network.transport and network.type.")] public const string Unix = "unix"; } /// - /// Deprecated, use network.transport + /// Deprecated, use network.transport. /// public static class NetTransportValues { /// - /// ip_tcp + /// ip_tcp. /// - [Obsolete("Replaced by network.transport")] + [Obsolete("Replaced by network.transport.")] public const string IpTcp = "ip_tcp"; /// - /// ip_udp + /// ip_udp. /// - [Obsolete("Replaced by network.transport")] + [Obsolete("Replaced by network.transport.")] public const string IpUdp = "ip_udp"; /// - /// Named or anonymous pipe + /// Named or anonymous pipe. /// - [Obsolete("Replaced by network.transport")] + [Obsolete("Replaced by network.transport.")] public const string Pipe = "pipe"; /// - /// In-process communication + /// In-process communication. /// - [Obsolete("Replaced by network.transport")] + [Obsolete("Replaced by network.transport.")] public const string Inproc = "inproc"; /// - /// Something else (non IP-based) + /// Something else (non IP-based). /// - [Obsolete("Replaced by network.transport")] + [Obsolete("Replaced by network.transport.")] public const string Other = "other"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs index ef64321563..301b5d9e70 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs @@ -15,297 +15,297 @@ namespace OpenTelemetry.SemanticConventions; public static class NetworkAttributes { /// - /// The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network + /// The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. /// public const string AttributeNetworkCarrierIcc = "network.carrier.icc"; /// - /// The mobile carrier country code + /// The mobile carrier country code. /// public const string AttributeNetworkCarrierMcc = "network.carrier.mcc"; /// - /// The mobile carrier network code + /// The mobile carrier network code. /// public const string AttributeNetworkCarrierMnc = "network.carrier.mnc"; /// - /// The name of the mobile carrier + /// The name of the mobile carrier. /// public const string AttributeNetworkCarrierName = "network.carrier.name"; /// - /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection + /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. /// public const string AttributeNetworkConnectionSubtype = "network.connection.subtype"; /// - /// The internet connection type + /// The internet connection type. /// public const string AttributeNetworkConnectionType = "network.connection.type"; /// - /// The network IO operation direction + /// The network IO operation direction. /// public const string AttributeNetworkIoDirection = "network.io.direction"; /// - /// Local address of the network connection - IP address or Unix domain socket name + /// Local address of the network connection - IP address or Unix domain socket name. /// public const string AttributeNetworkLocalAddress = "network.local.address"; /// - /// Local port number of the network connection + /// Local port number of the network connection. /// public const string AttributeNetworkLocalPort = "network.local.port"; /// - /// Peer address of the network connection - IP address or Unix domain socket name + /// Peer address of the network connection - IP address or Unix domain socket name. /// public const string AttributeNetworkPeerAddress = "network.peer.address"; /// - /// Peer port number of the network connection + /// Peer port number of the network connection. /// public const string AttributeNetworkPeerPort = "network.peer.port"; /// - /// OSI application layer or non-OSI equivalent + /// OSI application layer or non-OSI equivalent. /// /// - /// The value SHOULD be normalized to lowercase + /// The value SHOULD be normalized to lowercase. /// public const string AttributeNetworkProtocolName = "network.protocol.name"; /// - /// The actual version of the protocol used for network communication + /// The actual version of the protocol used for network communication. /// /// - /// If protocol version is subject to negotiation (for example using ALPN), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set + /// If protocol version is subject to negotiation (for example using ALPN), this attribute SHOULD be set to the negotiated version. If the actual protocol version is not known, this attribute SHOULD NOT be set. /// public const string AttributeNetworkProtocolVersion = "network.protocol.version"; /// - /// OSI transport layer or inter-process communication method + /// OSI transport layer or inter-process communication method. /// /// /// The value SHOULD be normalized to lowercase. ///

    /// Consider always setting the transport when setting a port number, since /// a port number is ambiguous without knowing the transport. For example - /// different processes could be listening on TCP port 12345 and UDP port 12345 + /// different processes could be listening on TCP port 12345 and UDP port 12345. /// public const string AttributeNetworkTransport = "network.transport"; ///

    - /// OSI network layer or non-OSI equivalent + /// OSI network layer or non-OSI equivalent. /// /// - /// The value SHOULD be normalized to lowercase + /// The value SHOULD be normalized to lowercase. /// public const string AttributeNetworkType = "network.type"; /// - /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection + /// This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection. /// public static class NetworkConnectionSubtypeValues { /// - /// GPRS + /// GPRS. /// public const string Gprs = "gprs"; /// - /// EDGE + /// EDGE. /// public const string Edge = "edge"; /// - /// UMTS + /// UMTS. /// public const string Umts = "umts"; /// - /// CDMA + /// CDMA. /// public const string Cdma = "cdma"; /// - /// EVDO Rel. 0 + /// EVDO Rel. 0. /// public const string Evdo0 = "evdo_0"; /// - /// EVDO Rev. A + /// EVDO Rev. A. /// public const string EvdoA = "evdo_a"; /// - /// CDMA2000 1XRTT + /// CDMA2000 1XRTT. /// public const string Cdma20001xrtt = "cdma2000_1xrtt"; /// - /// HSDPA + /// HSDPA. /// public const string Hsdpa = "hsdpa"; /// - /// HSUPA + /// HSUPA. /// public const string Hsupa = "hsupa"; /// - /// HSPA + /// HSPA. /// public const string Hspa = "hspa"; /// - /// IDEN + /// IDEN. /// public const string Iden = "iden"; /// - /// EVDO Rev. B + /// EVDO Rev. B. /// public const string EvdoB = "evdo_b"; /// - /// LTE + /// LTE. /// public const string Lte = "lte"; /// - /// EHRPD + /// EHRPD. /// public const string Ehrpd = "ehrpd"; /// - /// HSPAP + /// HSPAP. /// public const string Hspap = "hspap"; /// - /// GSM + /// GSM. /// public const string Gsm = "gsm"; /// - /// TD-SCDMA + /// TD-SCDMA. /// public const string TdScdma = "td_scdma"; /// - /// IWLAN + /// IWLAN. /// public const string Iwlan = "iwlan"; /// - /// 5G NR (New Radio) + /// 5G NR (New Radio). /// public const string Nr = "nr"; /// - /// 5G NRNSA (New Radio Non-Standalone) + /// 5G NRNSA (New Radio Non-Standalone). /// public const string Nrnsa = "nrnsa"; /// - /// LTE CA + /// LTE CA. /// public const string LteCa = "lte_ca"; } /// - /// The internet connection type + /// The internet connection type. /// public static class NetworkConnectionTypeValues { /// - /// wifi + /// wifi. /// public const string Wifi = "wifi"; /// - /// wired + /// wired. /// public const string Wired = "wired"; /// - /// cell + /// cell. /// public const string Cell = "cell"; /// - /// unavailable + /// unavailable. /// public const string Unavailable = "unavailable"; /// - /// unknown + /// unknown. /// public const string Unknown = "unknown"; } /// - /// The network IO operation direction + /// The network IO operation direction. /// public static class NetworkIoDirectionValues { /// - /// transmit + /// transmit. /// public const string Transmit = "transmit"; /// - /// receive + /// receive. /// public const string Receive = "receive"; } /// - /// OSI transport layer or inter-process communication method + /// OSI transport layer or inter-process communication method. /// public static class NetworkTransportValues { /// - /// TCP + /// TCP. /// public const string Tcp = "tcp"; /// - /// UDP + /// UDP. /// public const string Udp = "udp"; /// - /// Named or anonymous pipe + /// Named or anonymous pipe. /// public const string Pipe = "pipe"; /// - /// Unix domain socket + /// Unix domain socket. /// public const string Unix = "unix"; /// - /// QUIC + /// QUIC. /// public const string Quic = "quic"; } /// - /// OSI network layer or non-OSI equivalent + /// OSI network layer or non-OSI equivalent. /// public static class NetworkTypeValues { /// - /// IPv4 + /// IPv4. /// public const string Ipv4 = "ipv4"; /// - /// IPv6 + /// IPv6. /// public const string Ipv6 = "ipv6"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs index ca9e010ce8..6f22b46301 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OciAttributes.cs @@ -15,11 +15,11 @@ namespace OpenTelemetry.SemanticConventions; public static class OciAttributes { /// - /// The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known + /// The digest of the OCI image manifest. For container images specifically is the digest by which the container image is known. /// /// /// Follows OCI Image Manifest Specification, and specifically the Digest property. - /// An example can be found in Example Image Manifest + /// An example can be found in Example Image Manifest. /// public const string AttributeOciManifestDigest = "oci.manifest.digest"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs index 99041c4ea9..29f6aa5a02 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OpentracingAttributes.cs @@ -15,25 +15,25 @@ namespace OpenTelemetry.SemanticConventions; public static class OpentracingAttributes { /// - /// Parent-child Reference type + /// Parent-child Reference type. /// /// - /// The causal relationship between a child Span and a parent Span + /// The causal relationship between a child Span and a parent Span. /// public const string AttributeOpentracingRefType = "opentracing.ref_type"; /// - /// Parent-child Reference type + /// Parent-child Reference type. /// public static class OpentracingRefTypeValues { /// - /// The parent Span depends on the child Span in some capacity + /// The parent Span depends on the child Span in some capacity. /// public const string ChildOf = "child_of"; /// - /// The parent Span doesn't depend in any way on the result of the child Span + /// The parent Span doesn't depend in any way on the result of the child Span. /// public const string FollowsFrom = "follows_from"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs index f5700c4ef3..0dac23f161 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OsAttributes.cs @@ -15,87 +15,87 @@ namespace OpenTelemetry.SemanticConventions; public static class OsAttributes { /// - /// Unique identifier for a particular build or compilation of the operating system + /// Unique identifier for a particular build or compilation of the operating system. /// public const string AttributeOsBuildId = "os.build_id"; /// - /// Human readable (not intended to be parsed) OS version information, like e.g. reported by ver or lsb_release -a commands + /// Human readable (not intended to be parsed) OS version information, like e.g. reported by ver or lsb_release -a commands. /// public const string AttributeOsDescription = "os.description"; /// - /// Human readable operating system name + /// Human readable operating system name. /// public const string AttributeOsName = "os.name"; /// - /// The operating system type + /// The operating system type. /// public const string AttributeOsType = "os.type"; /// - /// The version string of the operating system as defined in Version Attributes + /// The version string of the operating system as defined in Version Attributes. /// public const string AttributeOsVersion = "os.version"; /// - /// The operating system type + /// The operating system type. /// public static class OsTypeValues { /// - /// Microsoft Windows + /// Microsoft Windows. /// public const string Windows = "windows"; /// - /// Linux + /// Linux. /// public const string Linux = "linux"; /// - /// Apple Darwin + /// Apple Darwin. /// public const string Darwin = "darwin"; /// - /// FreeBSD + /// FreeBSD. /// public const string Freebsd = "freebsd"; /// - /// NetBSD + /// NetBSD. /// public const string Netbsd = "netbsd"; /// - /// OpenBSD + /// OpenBSD. /// public const string Openbsd = "openbsd"; /// - /// DragonFly BSD + /// DragonFly BSD. /// public const string Dragonflybsd = "dragonflybsd"; /// - /// HP-UX (Hewlett Packard Unix) + /// HP-UX (Hewlett Packard Unix). /// public const string Hpux = "hpux"; /// - /// AIX (Advanced Interactive eXecutive) + /// AIX (Advanced Interactive eXecutive). /// public const string Aix = "aix"; /// - /// SunOS, Oracle Solaris + /// SunOS, Oracle Solaris. /// public const string Solaris = "solaris"; /// - /// IBM z/OS + /// IBM z/OS. /// public const string ZOs = "z_os"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs index 56695acece..4d0407eda1 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtelAttributes.cs @@ -15,37 +15,37 @@ namespace OpenTelemetry.SemanticConventions; public static class OtelAttributes { /// - /// The name of the instrumentation scope - (InstrumentationScope.Name in OTLP) + /// The name of the instrumentation scope - (InstrumentationScope.Name in OTLP). /// public const string AttributeOtelScopeName = "otel.scope.name"; /// - /// The version of the instrumentation scope - (InstrumentationScope.Version in OTLP) + /// The version of the instrumentation scope - (InstrumentationScope.Version in OTLP). /// public const string AttributeOtelScopeVersion = "otel.scope.version"; /// - /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET + /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. /// public const string AttributeOtelStatusCode = "otel.status_code"; /// - /// Description of the Status if it has a value, otherwise not set + /// Description of the Status if it has a value, otherwise not set. /// public const string AttributeOtelStatusDescription = "otel.status_description"; /// - /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET + /// Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code is UNSET. /// public static class OtelStatusCodeValues { /// - /// The operation has been validated by an Application developer or Operator to have completed successfully + /// The operation has been validated by an Application developer or Operator to have completed successfully. /// public const string Ok = "OK"; /// - /// The operation contains an error + /// The operation contains an error. /// public const string Error = "ERROR"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs index 4be44a0190..267c5f867b 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/OtherAttributes.cs @@ -15,26 +15,26 @@ namespace OpenTelemetry.SemanticConventions; public static class OtherAttributes { /// - /// Deprecated, use db.client.connection.state instead + /// Deprecated, use db.client.connection.state instead. /// - [Obsolete("Replaced by db.client.connection.state")] + [Obsolete("Replaced by db.client.connection.state.")] public const string AttributeState = "state"; /// - /// Deprecated, use db.client.connection.state instead + /// Deprecated, use db.client.connection.state instead. /// public static class StateValues { /// - /// idle + /// idle. /// - [Obsolete("Replaced by db.client.connection.state")] + [Obsolete("Replaced by db.client.connection.state.")] public const string Idle = "idle"; /// - /// used + /// used. /// - [Obsolete("Replaced by db.client.connection.state")] + [Obsolete("Replaced by db.client.connection.state.")] public const string Used = "used"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs index 3908588744..849d1f4302 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PeerAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class PeerAttributes { /// - /// The service.name of the remote service. SHOULD be equal to the actual service.name resource attribute of the remote service if any + /// The service.name of the remote service. SHOULD be equal to the actual service.name resource attribute of the remote service if any. /// public const string AttributePeerService = "peer.service"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs index 1d791b869b..8616ce65db 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/PoolAttributes.cs @@ -15,8 +15,8 @@ namespace OpenTelemetry.SemanticConventions; public static class PoolAttributes { /// - /// Deprecated, use db.client.connection.pool.name instead + /// Deprecated, use db.client.connection.pool.name instead. /// - [Obsolete("Replaced by db.client.connection.pool.name")] + [Obsolete("Replaced by db.client.connection.pool.name.")] public const string AttributePoolName = "pool.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs index 17273e200a..da4d98d30e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs @@ -15,196 +15,196 @@ namespace OpenTelemetry.SemanticConventions; public static class ProcessAttributes { /// - /// The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in proc/[pid]/cmdline. On Windows, can be set to the first parameter extracted from GetCommandLineW + /// The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in proc/[pid]/cmdline. On Windows, can be set to the first parameter extracted from GetCommandLineW. /// public const string AttributeProcessCommand = "process.command"; /// - /// All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from proc/[pid]/cmdline. For libc-based executables, this would be the full argv vector passed to main + /// All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from proc/[pid]/cmdline. For libc-based executables, this would be the full argv vector passed to main. /// public const string AttributeProcessCommandArgs = "process.command_args"; /// - /// The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of GetCommandLineW. Do not set this if you have to assemble it just for monitoring; use process.command_args instead + /// The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of GetCommandLineW. Do not set this if you have to assemble it just for monitoring; use process.command_args instead. /// public const string AttributeProcessCommandLine = "process.command_line"; /// - /// Specifies whether the context switches for this data point were voluntary or involuntary + /// Specifies whether the context switches for this data point were voluntary or involuntary. /// public const string AttributeProcessContextSwitchType = "process.context_switch_type"; /// - /// Deprecated, use cpu.mode instead + /// Deprecated, use cpu.mode instead. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string AttributeProcessCpuState = "process.cpu.state"; /// - /// The date and time the process was created, in ISO 8601 format + /// The date and time the process was created, in ISO 8601 format. /// public const string AttributeProcessCreationTime = "process.creation.time"; /// - /// The name of the process executable. On Linux based systems, can be set to the Name in proc/[pid]/status. On Windows, can be set to the base name of GetProcessImageFileNameW + /// The name of the process executable. On Linux based systems, can be set to the Name in proc/[pid]/status. On Windows, can be set to the base name of GetProcessImageFileNameW. /// public const string AttributeProcessExecutableName = "process.executable.name"; /// - /// The full path to the process executable. On Linux based systems, can be set to the target of proc/[pid]/exe. On Windows, can be set to the result of GetProcessImageFileNameW + /// The full path to the process executable. On Linux based systems, can be set to the target of proc/[pid]/exe. On Windows, can be set to the result of GetProcessImageFileNameW. /// public const string AttributeProcessExecutablePath = "process.executable.path"; /// - /// The exit code of the process + /// The exit code of the process. /// public const string AttributeProcessExitCode = "process.exit.code"; /// - /// The date and time the process exited, in ISO 8601 format + /// The date and time the process exited, in ISO 8601 format. /// public const string AttributeProcessExitTime = "process.exit.time"; /// - /// The PID of the process's group leader. This is also the process group ID (PGID) of the process + /// The PID of the process's group leader. This is also the process group ID (PGID) of the process. /// public const string AttributeProcessGroupLeaderPid = "process.group_leader.pid"; /// - /// Whether the process is connected to an interactive shell + /// Whether the process is connected to an interactive shell. /// public const string AttributeProcessInteractive = "process.interactive"; /// - /// The username of the user that owns the process + /// The username of the user that owns the process. /// public const string AttributeProcessOwner = "process.owner"; /// - /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults + /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults. /// public const string AttributeProcessPagingFaultType = "process.paging.fault_type"; /// - /// Parent Process identifier (PPID) + /// Parent Process identifier (PPID). /// public const string AttributeProcessParentPid = "process.parent_pid"; /// - /// Process identifier (PID) + /// Process identifier (PID). /// public const string AttributeProcessPid = "process.pid"; /// - /// The real user ID (RUID) of the process + /// The real user ID (RUID) of the process. /// public const string AttributeProcessRealUserId = "process.real_user.id"; /// - /// The username of the real user of the process + /// The username of the real user of the process. /// public const string AttributeProcessRealUserName = "process.real_user.name"; /// - /// An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment + /// An additional description about the runtime of the process, for example a specific vendor customization of the runtime environment. /// public const string AttributeProcessRuntimeDescription = "process.runtime.description"; /// - /// The name of the runtime of this process + /// The name of the runtime of this process. /// public const string AttributeProcessRuntimeName = "process.runtime.name"; /// - /// The version of the runtime of this process, as returned by the runtime without modification + /// The version of the runtime of this process, as returned by the runtime without modification. /// public const string AttributeProcessRuntimeVersion = "process.runtime.version"; /// - /// The saved user ID (SUID) of the process + /// The saved user ID (SUID) of the process. /// public const string AttributeProcessSavedUserId = "process.saved_user.id"; /// - /// The username of the saved user + /// The username of the saved user. /// public const string AttributeProcessSavedUserName = "process.saved_user.name"; /// - /// The PID of the process's session leader. This is also the session ID (SID) of the process + /// The PID of the process's session leader. This is also the session ID (SID) of the process. /// public const string AttributeProcessSessionLeaderPid = "process.session_leader.pid"; /// - /// The effective user ID (EUID) of the process + /// The effective user ID (EUID) of the process. /// public const string AttributeProcessUserId = "process.user.id"; /// - /// The username of the effective user of the process + /// The username of the effective user of the process. /// public const string AttributeProcessUserName = "process.user.name"; /// - /// Virtual process identifier + /// Virtual process identifier. /// /// - /// The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within + /// The process ID within a PID namespace. This is not necessarily unique across all processes on the host but it is unique within the process namespace that the process exists within. /// public const string AttributeProcessVpid = "process.vpid"; /// - /// Specifies whether the context switches for this data point were voluntary or involuntary + /// Specifies whether the context switches for this data point were voluntary or involuntary. /// public static class ProcessContextSwitchTypeValues { /// - /// voluntary + /// voluntary. /// public const string Voluntary = "voluntary"; /// - /// involuntary + /// involuntary. /// public const string Involuntary = "involuntary"; } /// - /// Deprecated, use cpu.mode instead + /// Deprecated, use cpu.mode instead. /// public static class ProcessCpuStateValues { /// - /// system + /// system. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string System = "system"; /// - /// user + /// user. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string User = "user"; /// - /// wait + /// wait. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Wait = "wait"; } /// - /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults + /// The type of page fault for this data point. Type major is for major/hard page faults, and minor is for minor/soft page faults. /// public static class ProcessPagingFaultTypeValues { /// - /// major + /// major. /// public const string Major = "major"; /// - /// minor + /// minor. /// public const string Minor = "minor"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs index 2757fdb910..094511cff4 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/RpcAttributes.cs @@ -15,331 +15,331 @@ namespace OpenTelemetry.SemanticConventions; public static class RpcAttributes { /// - /// The error codes of the Connect request. Error codes are always string values + /// The error codes of the Connect request. Error codes are always string values. /// public const string AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code"; /// - /// Connect request metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values + /// Connect request metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values. /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. /// public const string AttributeRpcConnectRpcRequestMetadataTemplate = "rpc.connect_rpc.request.metadata"; /// - /// Connect response metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values + /// Connect response metadata, being the normalized Connect Metadata key (lowercase), the value being the metadata values. /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. /// public const string AttributeRpcConnectRpcResponseMetadataTemplate = "rpc.connect_rpc.response.metadata"; /// - /// gRPC request metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values + /// gRPC request metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values. /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all request metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. /// public const string AttributeRpcGrpcRequestMetadataTemplate = "rpc.grpc.request.metadata"; /// - /// gRPC response metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values + /// gRPC response metadata, being the normalized gRPC Metadata key (lowercase), the value being the metadata values. /// /// - /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information + /// Instrumentations SHOULD require an explicit configuration of which metadata values are to be captured. Including all response metadata values can be a security risk - explicit configuration helps avoid leaking sensitive information. /// public const string AttributeRpcGrpcResponseMetadataTemplate = "rpc.grpc.response.metadata"; /// - /// The numeric status code of the gRPC request + /// The numeric status code of the gRPC request. /// public const string AttributeRpcGrpcStatusCode = "rpc.grpc.status_code"; /// - /// error.code property of response if it is an error response + /// error.code property of response if it is an error response. /// public const string AttributeRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code"; /// - /// error.message property of response if it is an error response + /// error.message property of response if it is an error response. /// public const string AttributeRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message"; /// - /// id property of request or response. Since protocol allows id to be int, string, null or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of null value. Omit entirely if this is a notification + /// id property of request or response. Since protocol allows id to be int, string, null or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of null value. Omit entirely if this is a notification. /// public const string AttributeRpcJsonrpcRequestId = "rpc.jsonrpc.request_id"; /// - /// Protocol version as in jsonrpc property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted + /// Protocol version as in jsonrpc property of request/response. Since JSON-RPC 1.0 doesn't specify this, the value can be omitted. /// public const string AttributeRpcJsonrpcVersion = "rpc.jsonrpc.version"; /// - /// Compressed size of the message in bytes + /// Compressed size of the message in bytes. /// public const string AttributeRpcMessageCompressedSize = "rpc.message.compressed_size"; /// - /// MUST be calculated as two different counters starting from 1 one for sent messages and one for received message + /// MUST be calculated as two different counters starting from 1 one for sent messages and one for received message. /// /// - /// This way we guarantee that the values will be consistent between different implementations + /// This way we guarantee that the values will be consistent between different implementations. /// public const string AttributeRpcMessageId = "rpc.message.id"; /// - /// Whether this is a received or sent message + /// Whether this is a received or sent message. /// public const string AttributeRpcMessageType = "rpc.message.type"; /// - /// Uncompressed size of the message in bytes + /// Uncompressed size of the message in bytes. /// public const string AttributeRpcMessageUncompressedSize = "rpc.message.uncompressed_size"; /// - /// The name of the (logical) method being called, must be equal to the $method part in the span name + /// The name of the (logical) method being called, must be equal to the $method part in the span name. /// /// - /// This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The code.function attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side) + /// This is the logical name of the method from the RPC interface perspective, which can be different from the name of any implementing method/function. The code.function attribute may be used to store the latter (e.g., method actually executing the call on the server side, RPC client stub method on the client side). /// public const string AttributeRpcMethod = "rpc.method"; /// - /// The full (logical) name of the service being called, including its package name, if applicable + /// The full (logical) name of the service being called, including its package name, if applicable. /// /// - /// This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The code.namespace attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side) + /// This is the logical name of the service from the RPC interface perspective, which can be different from the name of any implementing class. The code.namespace attribute may be used to store the latter (despite the attribute name, it may include a class name; e.g., class with method actually executing the call on the server side, RPC client stub class on the client side). /// public const string AttributeRpcService = "rpc.service"; /// - /// A string identifying the remoting system. See below for a list of well-known identifiers + /// A string identifying the remoting system. See below for a list of well-known identifiers. /// public const string AttributeRpcSystem = "rpc.system"; /// - /// The error codes of the Connect request. Error codes are always string values + /// The error codes of the Connect request. Error codes are always string values. /// public static class RpcConnectRpcErrorCodeValues { /// - /// cancelled + /// cancelled. /// public const string Cancelled = "cancelled"; /// - /// unknown + /// unknown. /// public const string Unknown = "unknown"; /// - /// invalid_argument + /// invalid_argument. /// public const string InvalidArgument = "invalid_argument"; /// - /// deadline_exceeded + /// deadline_exceeded. /// public const string DeadlineExceeded = "deadline_exceeded"; /// - /// not_found + /// not_found. /// public const string NotFound = "not_found"; /// - /// already_exists + /// already_exists. /// public const string AlreadyExists = "already_exists"; /// - /// permission_denied + /// permission_denied. /// public const string PermissionDenied = "permission_denied"; /// - /// resource_exhausted + /// resource_exhausted. /// public const string ResourceExhausted = "resource_exhausted"; /// - /// failed_precondition + /// failed_precondition. /// public const string FailedPrecondition = "failed_precondition"; /// - /// aborted + /// aborted. /// public const string Aborted = "aborted"; /// - /// out_of_range + /// out_of_range. /// public const string OutOfRange = "out_of_range"; /// - /// unimplemented + /// unimplemented. /// public const string Unimplemented = "unimplemented"; /// - /// internal + /// internal. /// public const string Internal = "internal"; /// - /// unavailable + /// unavailable. /// public const string Unavailable = "unavailable"; /// - /// data_loss + /// data_loss. /// public const string DataLoss = "data_loss"; /// - /// unauthenticated + /// unauthenticated. /// public const string Unauthenticated = "unauthenticated"; } /// - /// The numeric status code of the gRPC request + /// The numeric status code of the gRPC request. /// public static class RpcGrpcStatusCodeValues { /// - /// OK + /// OK. /// public const int Ok = 0; /// - /// CANCELLED + /// CANCELLED. /// public const int Cancelled = 1; /// - /// UNKNOWN + /// UNKNOWN. /// public const int Unknown = 2; /// - /// INVALID_ARGUMENT + /// INVALID_ARGUMENT. /// public const int InvalidArgument = 3; /// - /// DEADLINE_EXCEEDED + /// DEADLINE_EXCEEDED. /// public const int DeadlineExceeded = 4; /// - /// NOT_FOUND + /// NOT_FOUND. /// public const int NotFound = 5; /// - /// ALREADY_EXISTS + /// ALREADY_EXISTS. /// public const int AlreadyExists = 6; /// - /// PERMISSION_DENIED + /// PERMISSION_DENIED. /// public const int PermissionDenied = 7; /// - /// RESOURCE_EXHAUSTED + /// RESOURCE_EXHAUSTED. /// public const int ResourceExhausted = 8; /// - /// FAILED_PRECONDITION + /// FAILED_PRECONDITION. /// public const int FailedPrecondition = 9; /// - /// ABORTED + /// ABORTED. /// public const int Aborted = 10; /// - /// OUT_OF_RANGE + /// OUT_OF_RANGE. /// public const int OutOfRange = 11; /// - /// UNIMPLEMENTED + /// UNIMPLEMENTED. /// public const int Unimplemented = 12; /// - /// INTERNAL + /// INTERNAL. /// public const int Internal = 13; /// - /// UNAVAILABLE + /// UNAVAILABLE. /// public const int Unavailable = 14; /// - /// DATA_LOSS + /// DATA_LOSS. /// public const int DataLoss = 15; /// - /// UNAUTHENTICATED + /// UNAUTHENTICATED. /// public const int Unauthenticated = 16; } /// - /// Whether this is a received or sent message + /// Whether this is a received or sent message. /// public static class RpcMessageTypeValues { /// - /// sent + /// sent. /// public const string Sent = "SENT"; /// - /// received + /// received. /// public const string Received = "RECEIVED"; } /// - /// A string identifying the remoting system. See below for a list of well-known identifiers + /// A string identifying the remoting system. See below for a list of well-known identifiers. /// public static class RpcSystemValues { /// - /// gRPC + /// gRPC. /// public const string Grpc = "grpc"; /// - /// Java RMI + /// Java RMI. /// public const string JavaRmi = "java_rmi"; /// - /// .NET WCF + /// .NET WCF. /// public const string DotnetWcf = "dotnet_wcf"; /// - /// Apache Dubbo + /// Apache Dubbo. /// public const string ApacheDubbo = "apache_dubbo"; /// - /// Connect RPC + /// Connect RPC. /// public const string ConnectRpc = "connect_rpc"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs index 75ecf5f8af..d201a41e92 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServerAttributes.cs @@ -15,18 +15,18 @@ namespace OpenTelemetry.SemanticConventions; public static class ServerAttributes { /// - /// Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name + /// Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. /// /// - /// When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it's available + /// When observed from the client side, and when communicating through an intermediary, server.address SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. /// public const string AttributeServerAddress = "server.address"; /// - /// Server port number + /// Server port number. /// /// - /// When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it's available + /// When observed from the client side, and when communicating through an intermediary, server.port SHOULD represent the server port behind any intermediaries, for example proxies, if it's available. /// public const string AttributeServerPort = "server.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs index 2d1352ef80..18d3b5f96b 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class ServiceAttributes { /// - /// The string ID of the service instance + /// The string ID of the service instance. /// /// /// MUST be unique for each instance of the same service.namespace,service.name pair (in other words @@ -43,28 +43,28 @@ public static class ServiceAttributes /// likely be wrong, as the Collector might not know from which container within that pod the telemetry originated. /// However, Collectors can set the service.instance.id if they can unambiguously determine the service instance /// for that telemetry. This is typically the case for scraping receivers, as they know the target address and - /// port + /// port. /// public const string AttributeServiceInstanceId = "service.instance.id"; /// - /// Logical name of the service + /// Logical name of the service. /// /// - /// MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to unknown_service: concatenated with process.executable.name, e.g. unknown_service:bash. If process.executable.name is not available, the value MUST be set to unknown_service + /// MUST be the same for all instances of horizontally scaled services. If the value was not specified, SDKs MUST fallback to unknown_service: concatenated with process.executable.name, e.g. unknown_service:bash. If process.executable.name is not available, the value MUST be set to unknown_service. /// public const string AttributeServiceName = "service.name"; /// - /// A namespace for service.name + /// A namespace for service.name. /// /// - /// A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. service.name is expected to be unique within the same namespace. If service.namespace is not specified in the Resource then service.name is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace + /// A string value having a meaning that helps to distinguish a group of services, for example the team name that owns a group of services. service.name is expected to be unique within the same namespace. If service.namespace is not specified in the Resource then service.name is expected to be unique for all services that have no explicit namespace defined (so the empty/unspecified namespace is simply one more valid namespace). Zero-length namespace string is assumed equal to unspecified namespace. /// public const string AttributeServiceNamespace = "service.namespace"; /// - /// The version string of the service API or implementation. The format is not defined by these conventions + /// The version string of the service API or implementation. The format is not defined by these conventions. /// public const string AttributeServiceVersion = "service.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs index ed3c893b3f..9c2dbd9222 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SessionAttributes.cs @@ -15,12 +15,12 @@ namespace OpenTelemetry.SemanticConventions; public static class SessionAttributes { /// - /// A unique id to identify a session + /// A unique id to identify a session. /// public const string AttributeSessionId = "session.id"; /// - /// The previous session.id for this user, when known + /// The previous session.id for this user, when known. /// public const string AttributeSessionPreviousId = "session.previous_id"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs index 1940defe58..396d051e8c 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SignalrAttributes.cs @@ -15,53 +15,53 @@ namespace OpenTelemetry.SemanticConventions; public static class SignalrAttributes { /// - /// SignalR HTTP connection closure status + /// SignalR HTTP connection closure status. /// public const string AttributeSignalrConnectionStatus = "signalr.connection.status"; /// - /// SignalR transport type + /// SignalR transport type. /// public const string AttributeSignalrTransport = "signalr.transport"; /// - /// SignalR HTTP connection closure status + /// SignalR HTTP connection closure status. /// public static class SignalrConnectionStatusValues { /// - /// The connection was closed normally + /// The connection was closed normally. /// public const string NormalClosure = "normal_closure"; /// - /// The connection was closed due to a timeout + /// The connection was closed due to a timeout. /// public const string Timeout = "timeout"; /// - /// The connection was closed because the app is shutting down + /// The connection was closed because the app is shutting down. /// public const string AppShutdown = "app_shutdown"; } /// - /// SignalR transport type + /// SignalR transport type. /// public static class SignalrTransportValues { /// - /// ServerSentEvents protocol + /// ServerSentEvents protocol. /// public const string ServerSentEvents = "server_sent_events"; /// - /// LongPolling protocol + /// LongPolling protocol. /// public const string LongPolling = "long_polling"; /// - /// WebSockets protocol + /// WebSockets protocol. /// public const string WebSockets = "web_sockets"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs index d64f93a789..47cf1d00dc 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SourceAttributes.cs @@ -15,15 +15,15 @@ namespace OpenTelemetry.SemanticConventions; public static class SourceAttributes { /// - /// Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name + /// Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. /// /// - /// When observed from the destination side, and when communicating through an intermediary, source.address SHOULD represent the source address behind any intermediaries, for example proxies, if it's available + /// When observed from the destination side, and when communicating through an intermediary, source.address SHOULD represent the source address behind any intermediaries, for example proxies, if it's available. /// public const string AttributeSourceAddress = "source.address"; /// - /// Source port number + /// Source port number. /// public const string AttributeSourcePort = "source.port"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs index 8cac7b5d53..d0595df537 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/SystemAttributes.cs @@ -15,380 +15,380 @@ namespace OpenTelemetry.SemanticConventions; public static class SystemAttributes { /// - /// The logical CPU number [0..n-1] + /// The logical CPU number [0..n-1]. /// public const string AttributeSystemCpuLogicalNumber = "system.cpu.logical_number"; /// - /// Deprecated, use cpu.mode instead + /// Deprecated, use cpu.mode instead. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string AttributeSystemCpuState = "system.cpu.state"; /// - /// The device identifier + /// The device identifier. /// public const string AttributeSystemDevice = "system.device"; /// - /// The filesystem mode + /// The filesystem mode. /// public const string AttributeSystemFilesystemMode = "system.filesystem.mode"; /// - /// The filesystem mount path + /// The filesystem mount path. /// public const string AttributeSystemFilesystemMountpoint = "system.filesystem.mountpoint"; /// - /// The filesystem state + /// The filesystem state. /// public const string AttributeSystemFilesystemState = "system.filesystem.state"; /// - /// The filesystem type + /// The filesystem type. /// public const string AttributeSystemFilesystemType = "system.filesystem.type"; /// - /// The memory state + /// The memory state. /// public const string AttributeSystemMemoryState = "system.memory.state"; /// - /// A stateless protocol MUST NOT set this attribute + /// A stateless protocol MUST NOT set this attribute. /// public const string AttributeSystemNetworkState = "system.network.state"; /// - /// The paging access direction + /// The paging access direction. /// public const string AttributeSystemPagingDirection = "system.paging.direction"; /// - /// The memory paging state + /// The memory paging state. /// public const string AttributeSystemPagingState = "system.paging.state"; /// - /// The memory paging type + /// The memory paging type. /// public const string AttributeSystemPagingType = "system.paging.type"; /// - /// The process state, e.g., Linux Process State Codes + /// The process state, e.g., Linux Process State Codes. /// public const string AttributeSystemProcessStatus = "system.process.status"; /// - /// Deprecated, use system.process.status instead + /// Deprecated, use system.process.status instead. /// - [Obsolete("Replaced by system.process.status")] + [Obsolete("Replaced by system.process.status.")] public const string AttributeSystemProcessesStatus = "system.processes.status"; /// - /// Deprecated, use cpu.mode instead + /// Deprecated, use cpu.mode instead. /// public static class SystemCpuStateValues { /// - /// user + /// user. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string User = "user"; /// - /// system + /// system. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string System = "system"; /// - /// nice + /// nice. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Nice = "nice"; /// - /// idle + /// idle. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Idle = "idle"; /// - /// iowait + /// iowait. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Iowait = "iowait"; /// - /// interrupt + /// interrupt. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Interrupt = "interrupt"; /// - /// steal + /// steal. /// - [Obsolete("Replaced by cpu.mode")] + [Obsolete("Replaced by cpu.mode.")] public const string Steal = "steal"; } /// - /// The filesystem state + /// The filesystem state. /// public static class SystemFilesystemStateValues { /// - /// used + /// used. /// public const string Used = "used"; /// - /// free + /// free. /// public const string Free = "free"; /// - /// reserved + /// reserved. /// public const string Reserved = "reserved"; } /// - /// The filesystem type + /// The filesystem type. /// public static class SystemFilesystemTypeValues { /// - /// fat32 + /// fat32. /// public const string Fat32 = "fat32"; /// - /// exfat + /// exfat. /// public const string Exfat = "exfat"; /// - /// ntfs + /// ntfs. /// public const string Ntfs = "ntfs"; /// - /// refs + /// refs. /// public const string Refs = "refs"; /// - /// hfsplus + /// hfsplus. /// public const string Hfsplus = "hfsplus"; /// - /// ext4 + /// ext4. /// public const string Ext4 = "ext4"; } /// - /// The memory state + /// The memory state. /// public static class SystemMemoryStateValues { /// - /// used + /// used. /// public const string Used = "used"; /// - /// free + /// free. /// public const string Free = "free"; /// - /// shared + /// shared. /// public const string Shared = "shared"; /// - /// buffers + /// buffers. /// public const string Buffers = "buffers"; /// - /// cached + /// cached. /// public const string Cached = "cached"; } /// - /// A stateless protocol MUST NOT set this attribute + /// A stateless protocol MUST NOT set this attribute. /// public static class SystemNetworkStateValues { /// - /// close + /// close. /// public const string Close = "close"; /// - /// close_wait + /// close_wait. /// public const string CloseWait = "close_wait"; /// - /// closing + /// closing. /// public const string Closing = "closing"; /// - /// delete + /// delete. /// public const string Delete = "delete"; /// - /// established + /// established. /// public const string Established = "established"; /// - /// fin_wait_1 + /// fin_wait_1. /// public const string FinWait1 = "fin_wait_1"; /// - /// fin_wait_2 + /// fin_wait_2. /// public const string FinWait2 = "fin_wait_2"; /// - /// last_ack + /// last_ack. /// public const string LastAck = "last_ack"; /// - /// listen + /// listen. /// public const string Listen = "listen"; /// - /// syn_recv + /// syn_recv. /// public const string SynRecv = "syn_recv"; /// - /// syn_sent + /// syn_sent. /// public const string SynSent = "syn_sent"; /// - /// time_wait + /// time_wait. /// public const string TimeWait = "time_wait"; } /// - /// The paging access direction + /// The paging access direction. /// public static class SystemPagingDirectionValues { /// - /// in + /// in. /// public const string In = "in"; /// - /// out + /// out. /// public const string Out = "out"; } /// - /// The memory paging state + /// The memory paging state. /// public static class SystemPagingStateValues { /// - /// used + /// used. /// public const string Used = "used"; /// - /// free + /// free. /// public const string Free = "free"; } /// - /// The memory paging type + /// The memory paging type. /// public static class SystemPagingTypeValues { /// - /// major + /// major. /// public const string Major = "major"; /// - /// minor + /// minor. /// public const string Minor = "minor"; } /// - /// The process state, e.g., Linux Process State Codes + /// The process state, e.g., Linux Process State Codes. /// public static class SystemProcessStatusValues { /// - /// running + /// running. /// public const string Running = "running"; /// - /// sleeping + /// sleeping. /// public const string Sleeping = "sleeping"; /// - /// stopped + /// stopped. /// public const string Stopped = "stopped"; /// - /// defunct + /// defunct. /// public const string Defunct = "defunct"; } /// - /// Deprecated, use system.process.status instead + /// Deprecated, use system.process.status instead. /// public static class SystemProcessesStatusValues { /// - /// running + /// running. /// - [Obsolete("Replaced by system.process.status")] + [Obsolete("Replaced by system.process.status.")] public const string Running = "running"; /// - /// sleeping + /// sleeping. /// - [Obsolete("Replaced by system.process.status")] + [Obsolete("Replaced by system.process.status.")] public const string Sleeping = "sleeping"; /// - /// stopped + /// stopped. /// - [Obsolete("Replaced by system.process.status")] + [Obsolete("Replaced by system.process.status.")] public const string Stopped = "stopped"; /// - /// defunct + /// defunct. /// - [Obsolete("Replaced by system.process.status")] + [Obsolete("Replaced by system.process.status.")] public const string Defunct = "defunct"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs index 300181e4fd..85693b3786 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TelemetryAttributes.cs @@ -15,26 +15,26 @@ namespace OpenTelemetry.SemanticConventions; public static class TelemetryAttributes { /// - /// The name of the auto instrumentation agent or distribution, if used + /// The name of the auto instrumentation agent or distribution, if used. /// /// /// Official auto instrumentation agents and distributions SHOULD set the telemetry.distro.name attribute to - /// a string starting with opentelemetry-, e.g. opentelemetry-java-instrumentation + /// a string starting with opentelemetry-, e.g. opentelemetry-java-instrumentation. /// public const string AttributeTelemetryDistroName = "telemetry.distro.name"; /// - /// The version string of the auto instrumentation agent or distribution, if used + /// The version string of the auto instrumentation agent or distribution, if used. /// public const string AttributeTelemetryDistroVersion = "telemetry.distro.version"; /// - /// The language of the telemetry SDK + /// The language of the telemetry SDK. /// public const string AttributeTelemetrySdkLanguage = "telemetry.sdk.language"; /// - /// The name of the telemetry SDK as defined above + /// The name of the telemetry SDK as defined above. /// /// /// The OpenTelemetry SDK MUST set the telemetry.sdk.name attribute to opentelemetry. @@ -42,77 +42,77 @@ public static class TelemetryAttributes /// telemetry.sdk.name attribute to the fully-qualified class or module name of this SDK's main entry point /// or another suitable identifier depending on the language. /// The identifier opentelemetry is reserved and MUST NOT be used in this case. - /// All custom identifiers SHOULD be stable across different versions of an implementation + /// All custom identifiers SHOULD be stable across different versions of an implementation. /// public const string AttributeTelemetrySdkName = "telemetry.sdk.name"; /// - /// The version string of the telemetry SDK + /// The version string of the telemetry SDK. /// public const string AttributeTelemetrySdkVersion = "telemetry.sdk.version"; /// - /// The language of the telemetry SDK + /// The language of the telemetry SDK. /// public static class TelemetrySdkLanguageValues { /// - /// cpp + /// cpp. /// public const string Cpp = "cpp"; /// - /// dotnet + /// dotnet. /// public const string Dotnet = "dotnet"; /// - /// erlang + /// erlang. /// public const string Erlang = "erlang"; /// - /// go + /// go. /// public const string Go = "go"; /// - /// java + /// java. /// public const string Java = "java"; /// - /// nodejs + /// nodejs. /// public const string Nodejs = "nodejs"; /// - /// php + /// php. /// public const string Php = "php"; /// - /// python + /// python. /// public const string Python = "python"; /// - /// ruby + /// ruby. /// public const string Ruby = "ruby"; /// - /// rust + /// rust. /// public const string Rust = "rust"; /// - /// swift + /// swift. /// public const string Swift = "swift"; /// - /// webjs + /// webjs. /// public const string Webjs = "webjs"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs index 6eae4b3f2a..d3d1bf9705 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs @@ -15,73 +15,73 @@ namespace OpenTelemetry.SemanticConventions; public static class TestAttributes { /// - /// The fully qualified human readable name of the test case + /// The fully qualified human readable name of the test case. /// public const string AttributeTestCaseName = "test.case.name"; /// - /// The status of the actual test case result from test execution + /// The status of the actual test case result from test execution. /// public const string AttributeTestCaseResultStatus = "test.case.result.status"; /// - /// The human readable name of a test suite + /// The human readable name of a test suite. /// public const string AttributeTestSuiteName = "test.suite.name"; /// - /// The status of the test suite run + /// The status of the test suite run. /// public const string AttributeTestSuiteRunStatus = "test.suite.run.status"; /// - /// The status of the actual test case result from test execution + /// The status of the actual test case result from test execution. /// public static class TestCaseResultStatusValues { /// - /// pass + /// pass. /// public const string Pass = "pass"; /// - /// fail + /// fail. /// public const string Fail = "fail"; } /// - /// The status of the test suite run + /// The status of the test suite run. /// public static class TestSuiteRunStatusValues { /// - /// success + /// success. /// public const string Success = "success"; /// - /// failure + /// failure. /// public const string Failure = "failure"; /// - /// skipped + /// skipped. /// public const string Skipped = "skipped"; /// - /// aborted + /// aborted. /// public const string Aborted = "aborted"; /// - /// timed_out + /// timed_out. /// public const string TimedOut = "timed_out"; /// - /// in_progress + /// in_progress. /// public const string InProgress = "in_progress"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs index 525597810c..e1b1c6db6f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ThreadAttributes.cs @@ -15,12 +15,12 @@ namespace OpenTelemetry.SemanticConventions; public static class ThreadAttributes { /// - /// Current "managed" thread ID (as opposed to OS thread ID) + /// Current "managed" thread ID (as opposed to OS thread ID). /// public const string AttributeThreadId = "thread.id"; /// - /// Current thread name + /// Current thread name. /// public const string AttributeThreadName = "thread.name"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs index 87351db7ba..3c2845a398 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs @@ -15,166 +15,166 @@ namespace OpenTelemetry.SemanticConventions; public static class TlsAttributes { /// - /// String indicating the cipher used during the current connection + /// String indicating the cipher used during the current connection. /// /// - /// The values allowed for tls.cipher MUST be one of the Descriptions of the registered TLS Cipher Suits + /// The values allowed for tls.cipher MUST be one of the Descriptions of the registered TLS Cipher Suits. /// public const string AttributeTlsCipher = "tls.cipher"; /// - /// PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of client.certificate_chain since this value also exists in that list + /// PEM-encoded stand-alone certificate offered by the client. This is usually mutually-exclusive of client.certificate_chain since this value also exists in that list. /// public const string AttributeTlsClientCertificate = "tls.client.certificate"; /// - /// Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of client.certificate since that value should be the first certificate in the chain + /// Array of PEM-encoded certificates that make up the certificate chain offered by the client. This is usually mutually-exclusive of client.certificate since that value should be the first certificate in the chain. /// public const string AttributeTlsClientCertificateChain = "tls.client.certificate_chain"; /// - /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash + /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. /// public const string AttributeTlsClientHashMd5 = "tls.client.hash.md5"; /// - /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash + /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. /// public const string AttributeTlsClientHashSha1 = "tls.client.hash.sha1"; /// - /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash + /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the client. For consistency with other hash values, this value should be formatted as an uppercase hash. /// public const string AttributeTlsClientHashSha256 = "tls.client.hash.sha256"; /// - /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client + /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client. /// public const string AttributeTlsClientIssuer = "tls.client.issuer"; /// - /// A hash that identifies clients based on how they perform an SSL/TLS handshake + /// A hash that identifies clients based on how they perform an SSL/TLS handshake. /// public const string AttributeTlsClientJa3 = "tls.client.ja3"; /// - /// Date/Time indicating when client certificate is no longer considered valid + /// Date/Time indicating when client certificate is no longer considered valid. /// public const string AttributeTlsClientNotAfter = "tls.client.not_after"; /// - /// Date/Time indicating when client certificate is first considered valid + /// Date/Time indicating when client certificate is first considered valid. /// public const string AttributeTlsClientNotBefore = "tls.client.not_before"; /// - /// Deprecated, use server.address instead + /// Deprecated, use server.address instead. /// - [Obsolete("Replaced by `server.address")] + [Obsolete("Replaced by `server.address.")] public const string AttributeTlsClientServerName = "tls.client.server_name"; /// - /// Distinguished name of subject of the x.509 certificate presented by the client + /// Distinguished name of subject of the x.509 certificate presented by the client. /// public const string AttributeTlsClientSubject = "tls.client.subject"; /// - /// Array of ciphers offered by the client during the client hello + /// Array of ciphers offered by the client during the client hello. /// public const string AttributeTlsClientSupportedCiphers = "tls.client.supported_ciphers"; /// - /// String indicating the curve used for the given cipher, when applicable + /// String indicating the curve used for the given cipher, when applicable. /// public const string AttributeTlsCurve = "tls.curve"; /// - /// Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel + /// Boolean flag indicating if the TLS negotiation was successful and transitioned to an encrypted tunnel. /// public const string AttributeTlsEstablished = "tls.established"; /// - /// String indicating the protocol being tunneled. Per the values in the IANA registry, this string should be lower case + /// String indicating the protocol being tunneled. Per the values in the IANA registry, this string should be lower case. /// public const string AttributeTlsNextProtocol = "tls.next_protocol"; /// - /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version + /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version. /// public const string AttributeTlsProtocolName = "tls.protocol.name"; /// - /// Numeric part of the version parsed from the original string of the negotiated SSL/TLS protocol version + /// Numeric part of the version parsed from the original string of the negotiated SSL/TLS protocol version. /// public const string AttributeTlsProtocolVersion = "tls.protocol.version"; /// - /// Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation + /// Boolean flag indicating if this TLS connection was resumed from an existing TLS negotiation. /// public const string AttributeTlsResumed = "tls.resumed"; /// - /// PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of server.certificate_chain since this value also exists in that list + /// PEM-encoded stand-alone certificate offered by the server. This is usually mutually-exclusive of server.certificate_chain since this value also exists in that list. /// public const string AttributeTlsServerCertificate = "tls.server.certificate"; /// - /// Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of server.certificate since that value should be the first certificate in the chain + /// Array of PEM-encoded certificates that make up the certificate chain offered by the server. This is usually mutually-exclusive of server.certificate since that value should be the first certificate in the chain. /// public const string AttributeTlsServerCertificateChain = "tls.server.certificate_chain"; /// - /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash + /// Certificate fingerprint using the MD5 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. /// public const string AttributeTlsServerHashMd5 = "tls.server.hash.md5"; /// - /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash + /// Certificate fingerprint using the SHA1 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. /// public const string AttributeTlsServerHashSha1 = "tls.server.hash.sha1"; /// - /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash + /// Certificate fingerprint using the SHA256 digest of DER-encoded version of certificate offered by the server. For consistency with other hash values, this value should be formatted as an uppercase hash. /// public const string AttributeTlsServerHashSha256 = "tls.server.hash.sha256"; /// - /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client + /// Distinguished name of subject of the issuer of the x.509 certificate presented by the client. /// public const string AttributeTlsServerIssuer = "tls.server.issuer"; /// - /// A hash that identifies servers based on how they perform an SSL/TLS handshake + /// A hash that identifies servers based on how they perform an SSL/TLS handshake. /// public const string AttributeTlsServerJa3s = "tls.server.ja3s"; /// - /// Date/Time indicating when server certificate is no longer considered valid + /// Date/Time indicating when server certificate is no longer considered valid. /// public const string AttributeTlsServerNotAfter = "tls.server.not_after"; /// - /// Date/Time indicating when server certificate is first considered valid + /// Date/Time indicating when server certificate is first considered valid. /// public const string AttributeTlsServerNotBefore = "tls.server.not_before"; /// - /// Distinguished name of subject of the x.509 certificate presented by the server + /// Distinguished name of subject of the x.509 certificate presented by the server. /// public const string AttributeTlsServerSubject = "tls.server.subject"; /// - /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version + /// Normalized lowercase protocol name parsed from original string of the negotiated SSL/TLS protocol version. /// public static class TlsProtocolNameValues { /// - /// ssl + /// ssl. /// public const string Ssl = "ssl"; /// - /// tls + /// tls. /// public const string Tls = "tls"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs index 47fba2eb6e..c6277699c2 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs @@ -15,97 +15,97 @@ namespace OpenTelemetry.SemanticConventions; public static class UrlAttributes { /// - /// Domain extracted from the url.full, such as "opentelemetry.io" + /// Domain extracted from the url.full, such as "opentelemetry.io". /// /// - /// In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a literal IPv6 address enclosed by [ and ], the [ and ] characters should also be captured in the domain field + /// In some cases a URL may refer to an IP and/or port directly, without a domain name. In this case, the IP address would go to the domain field. If the URL contains a literal IPv6 address enclosed by [ and ], the [ and ] characters should also be captured in the domain field. /// public const string AttributeUrlDomain = "url.domain"; /// - /// The file extension extracted from the url.full, excluding the leading dot + /// The file extension extracted from the url.full, excluding the leading dot. /// /// - /// The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions example.tar.gz, only the last one should be captured gz, not tar.gz + /// The file extension is only set if it exists, as not every url has a file extension. When the file name has multiple extensions example.tar.gz, only the last one should be captured gz, not tar.gz. /// public const string AttributeUrlExtension = "url.extension"; /// - /// The URI fragment component + /// The URI fragment component. /// public const string AttributeUrlFragment = "url.fragment"; /// - /// Absolute URL describing a network resource according to RFC3986 + /// Absolute URL describing a network resource according to RFC3986. /// /// /// For network calls, URL usually has scheme://host[:port][path][?query][#fragment] format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. /// url.full MUST NOT contain credentials passed via URL in form of https://username:password@www.example.com/. In such case username and password SHOULD be redacted and attribute's value SHOULD be https://REDACTED:REDACTED@www.example.com/. - /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it + /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it. /// public const string AttributeUrlFull = "url.full"; /// - /// Unmodified original URL as seen in the event source + /// Unmodified original URL as seen in the event source. /// /// /// In network monitoring, the observed URL may be a full URL, whereas in access logs, the URL is often just represented as a path. This field is meant to represent the URL as it was observed, complete or not. - /// url.original might contain credentials passed via URL in form of https://username:password@www.example.com/. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same + /// url.original might contain credentials passed via URL in form of https://username:password@www.example.com/. In such case password and username SHOULD NOT be redacted and attribute's value SHOULD remain the same. /// public const string AttributeUrlOriginal = "url.original"; /// - /// The URI path component + /// The URI path component. /// /// - /// Sensitive content provided in url.path SHOULD be scrubbed when instrumentations can identify it + /// Sensitive content provided in url.path SHOULD be scrubbed when instrumentations can identify it. /// public const string AttributeUrlPath = "url.path"; /// - /// Port extracted from the url.full + /// Port extracted from the url.full. /// public const string AttributeUrlPort = "url.port"; /// - /// The URI query component + /// The URI query component. /// /// - /// Sensitive content provided in url.query SHOULD be scrubbed when instrumentations can identify it + /// Sensitive content provided in url.query SHOULD be scrubbed when instrumentations can identify it. /// public const string AttributeUrlQuery = "url.query"; /// - /// The highest registered url domain, stripped of the subdomain + /// The highest registered url domain, stripped of the subdomain. /// /// - /// This value can be determined precisely with the public suffix list. For example, the registered domain for foo.example.com is example.com. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as co.uk + /// This value can be determined precisely with the public suffix list. For example, the registered domain for foo.example.com is example.com. Trying to approximate this by simply taking the last two labels will not work well for TLDs such as co.uk. /// public const string AttributeUrlRegisteredDomain = "url.registered_domain"; /// - /// The URI scheme component identifying the used protocol + /// The URI scheme component identifying the used protocol. /// public const string AttributeUrlScheme = "url.scheme"; /// - /// The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain + /// The subdomain portion of a fully qualified domain name includes all of the names except the host name under the registered_domain. In a partially qualified domain, or if the qualification level of the full name cannot be determined, subdomain contains all of the names below the registered domain. /// /// - /// The subdomain portion of www.east.mydomain.co.uk is east. If the domain has multiple levels of subdomain, such as sub2.sub1.example.com, the subdomain field should contain sub2.sub1, with no trailing period + /// The subdomain portion of www.east.mydomain.co.uk is east. If the domain has multiple levels of subdomain, such as sub2.sub1.example.com, the subdomain field should contain sub2.sub1, with no trailing period. /// public const string AttributeUrlSubdomain = "url.subdomain"; /// - /// The low-cardinality template of an absolute path reference + /// The low-cardinality template of an absolute path reference. /// public const string AttributeUrlTemplate = "url.template"; /// - /// The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is com + /// The effective top level domain (eTLD), also known as the domain suffix, is the last part of the domain name. For example, the top level domain for example.com is com. /// /// - /// This value can be determined precisely with the public suffix list + /// This value can be determined precisely with the public suffix list. /// public const string AttributeUrlTopLevelDomain = "url.top_level_domain"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs index b6f934206e..7b728d07be 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs @@ -15,23 +15,23 @@ namespace OpenTelemetry.SemanticConventions; public static class UserAgentAttributes { /// - /// Name of the user-agent extracted from original. Usually refers to the browser's name + /// Name of the user-agent extracted from original. Usually refers to the browser's name. /// /// - /// Example of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant name SHOULD be selected. In such a scenario it should align with user_agent.version + /// Example of extracting browser's name from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant name SHOULD be selected. In such a scenario it should align with user_agent.version. /// public const string AttributeUserAgentName = "user_agent.name"; /// - /// Value of the HTTP User-Agent header sent by the client + /// Value of the HTTP User-Agent header sent by the client. /// public const string AttributeUserAgentOriginal = "user_agent.original"; /// - /// Version of the user-agent extracted from original. Usually refers to the browser's version + /// Version of the user-agent extracted from original. Usually refers to the browser's version. /// /// - /// Example of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant version SHOULD be selected. In such a scenario it should align with user_agent.name + /// Example of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant version SHOULD be selected. In such a scenario it should align with user_agent.name. /// public const string AttributeUserAgentVersion = "user_agent.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs index eff0f4754a..79df46aed5 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UserAttributes.cs @@ -15,35 +15,35 @@ namespace OpenTelemetry.SemanticConventions; public static class UserAttributes { /// - /// User email address + /// User email address. /// public const string AttributeUserEmail = "user.email"; /// - /// User's full name + /// User's full name. /// public const string AttributeUserFullName = "user.full_name"; /// - /// Unique user hash to correlate information for a user in anonymized form + /// Unique user hash to correlate information for a user in anonymized form. /// /// - /// Useful if user.id or user.name contain confidential information and cannot be used + /// Useful if user.id or user.name contain confidential information and cannot be used. /// public const string AttributeUserHash = "user.hash"; /// - /// Unique identifier of the user + /// Unique identifier of the user. /// public const string AttributeUserId = "user.id"; /// - /// Short name or login/username of the user + /// Short name or login/username of the user. /// public const string AttributeUserName = "user.name"; /// - /// Array of user roles at the time of the event + /// Array of user roles at the time of the event. /// public const string AttributeUserRoles = "user.roles"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs index 93e68417b6..552b92e723 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/V8jsAttributes.cs @@ -15,71 +15,71 @@ namespace OpenTelemetry.SemanticConventions; public static class V8jsAttributes { /// - /// The type of garbage collection + /// The type of garbage collection. /// public const string AttributeV8jsGcType = "v8js.gc.type"; /// - /// The name of the space type of heap memory + /// The name of the space type of heap memory. /// /// - /// Value can be retrieved from value space_name of v8.getHeapSpaceStatistics() + /// Value can be retrieved from value space_name of v8.getHeapSpaceStatistics(). /// public const string AttributeV8jsHeapSpaceName = "v8js.heap.space.name"; /// - /// The type of garbage collection + /// The type of garbage collection. /// public static class V8jsGcTypeValues { /// - /// Major (Mark Sweep Compact) + /// Major (Mark Sweep Compact). /// public const string Major = "major"; /// - /// Minor (Scavenge) + /// Minor (Scavenge). /// public const string Minor = "minor"; /// - /// Incremental (Incremental Marking) + /// Incremental (Incremental Marking). /// public const string Incremental = "incremental"; /// - /// Weak Callbacks (Process Weak Callbacks) + /// Weak Callbacks (Process Weak Callbacks). /// public const string Weakcb = "weakcb"; } /// - /// The name of the space type of heap memory + /// The name of the space type of heap memory. /// public static class V8jsHeapSpaceNameValues { /// - /// New memory space + /// New memory space. /// public const string NewSpace = "new_space"; /// - /// Old memory space + /// Old memory space. /// public const string OldSpace = "old_space"; /// - /// Code memory space + /// Code memory space. /// public const string CodeSpace = "code_space"; /// - /// Map memory space + /// Map memory space. /// public const string MapSpace = "map_space"; /// - /// Large object memory space + /// Large object memory space. /// public const string LargeObjectSpace = "large_object_space"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs index 09a595f4c6..5173e18ffd 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs @@ -15,22 +15,22 @@ namespace OpenTelemetry.SemanticConventions; public static class VcsAttributes { /// - /// The ID of the change (pull request/merge request) if applicable. This is usually a unique (within repository) identifier generated by the VCS system + /// The ID of the change (pull request/merge request) if applicable. This is usually a unique (within repository) identifier generated by the VCS system. /// public const string AttributeVcsRepositoryChangeId = "vcs.repository.change.id"; /// - /// The human readable title of the change (pull request/merge request). This title is often a brief summary of the change and may get merged in to a ref as the commit summary + /// The human readable title of the change (pull request/merge request). This title is often a brief summary of the change and may get merged in to a ref as the commit summary. /// public const string AttributeVcsRepositoryChangeTitle = "vcs.repository.change.title"; /// - /// The name of the reference such as branch or tag in the repository + /// The name of the reference such as branch or tag in the repository. /// public const string AttributeVcsRepositoryRefName = "vcs.repository.ref.name"; /// - /// The revision, literally revised version, The revision most often refers to a commit object in Git, or a revision number in SVN + /// The revision, literally revised version, The revision most often refers to a commit object in Git, or a revision number in SVN. /// /// /// The revision can be a full hash value (see glossary), @@ -41,32 +41,32 @@ public static class VcsAttributes /// which is an integer that is monotonically increasing. In cases where /// it is identical to the ref.name, it SHOULD still be included. It is /// up to the implementer to decide which value to set as the revision - /// based on the VCS system and situational context + /// based on the VCS system and situational context. /// public const string AttributeVcsRepositoryRefRevision = "vcs.repository.ref.revision"; /// - /// The type of the reference in the repository + /// The type of the reference in the repository. /// public const string AttributeVcsRepositoryRefType = "vcs.repository.ref.type"; /// - /// The URL of the repository providing the complete address in order to locate and identify the repository + /// The URL of the repository providing the complete address in order to locate and identify the repository. /// public const string AttributeVcsRepositoryUrlFull = "vcs.repository.url.full"; /// - /// The type of the reference in the repository + /// The type of the reference in the repository. /// public static class VcsRepositoryRefTypeValues { /// - /// branch + /// branch. /// public const string Branch = "branch"; /// - /// tag + /// tag. /// public const string Tag = "tag"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs index 7797afcca9..d0122990e1 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/WebengineAttributes.cs @@ -15,17 +15,17 @@ namespace OpenTelemetry.SemanticConventions; public static class WebengineAttributes { /// - /// Additional description of the web engine (e.g. detailed version and edition information) + /// Additional description of the web engine (e.g. detailed version and edition information). /// public const string AttributeWebengineDescription = "webengine.description"; /// - /// The name of the web engine + /// The name of the web engine. /// public const string AttributeWebengineName = "webengine.name"; /// - /// The version of the web engine + /// The version of the web engine. /// public const string AttributeWebengineVersion = "webengine.version"; } diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 index 1a4e9581f3..d5969ddac0 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 @@ -3,7 +3,7 @@ $ROOT_DIR = "${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible $SEMCONV_VERSION="1.27.0" -$GENERATOR_VERSION="v0.9.2" +$GENERATOR_VERSION="v0.10.0" Set-Location $SCRIPT_DIR diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh index a5c6c8e9c4..fb0f0315ec 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh @@ -6,7 +6,7 @@ ROOT_DIR="${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible SEMCONV_VERSION="1.27.0" -GENERATOR_VERSION="v0.9.2" +GENERATOR_VERSION="v0.10.0" cd ${SCRIPT_DIR} diff --git a/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml index 80787a2831..97cec0f8be 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml +++ b/src/OpenTelemetry.SemanticConventions/scripts/templates/registry/weaver.yaml @@ -20,7 +20,8 @@ comment_formats: inline_code_snippet: "{{code}}" block_code_snippet: "{{code}}" trim: true - remove_trailing_dots: true + remove_trailing_dots: false + enforce_trailing_dots: true default_comment_format: csharp templates: From b8577b5c8d2fc02dadf01d2c8879c6d40fb14efe Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 23 Sep 2024 10:30:43 -0700 Subject: [PATCH 1263/1499] [geneva] Nullable annotations for TLDExporter folder (#2085) --- .../TLDExporter/JsonSerializer.cs | 28 ++-- .../TLDExporter/TldExporter.cs | 9 +- .../TLDExporter/TldLogExporter.cs | 136 ++++++++--------- .../TLDExporter/TldTraceExporter.cs | 137 ++++++++---------- .../TLDExporter/UncheckedASCIIEncoding.cs | 2 + 5 files changed, 149 insertions(+), 163 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs index 955f55a26f..57ccdbfcd3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Globalization; using System.Runtime.CompilerServices; using System.Text; @@ -46,7 +48,7 @@ public static int SerializeNull(byte[] buffer, int cursor) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string SerializeString(string value) + public static string SerializeString(string? value) { var buffer = ThreadLocalBuffer.Value; if (buffer == null) @@ -60,7 +62,7 @@ public static string SerializeString(string value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeString(byte[] buffer, int cursor, string value) + public static int SerializeString(byte[] buffer, int cursor, string? value) { if (value == null) { @@ -90,7 +92,7 @@ public static int SerializeString(byte[] buffer, int cursor, ReadOnlySpan #endif [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string SerializeArray(T[] array) + public static string SerializeArray(T[]? array) { var buffer = ThreadLocalBuffer.Value; if (buffer == null) @@ -104,7 +106,7 @@ public static string SerializeArray(T[] array) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeArray(byte[] buffer, int cursor, T[] array) + public static int SerializeArray(byte[] buffer, int cursor, T[]? array) { if (array == null) { @@ -128,7 +130,7 @@ public static int SerializeArray(byte[] buffer, int cursor, T[] array) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static string SerializeMap(IEnumerable> map) + public static string SerializeMap(IEnumerable>? map) { var buffer = ThreadLocalBuffer.Value; if (buffer == null) @@ -142,7 +144,7 @@ public static string SerializeMap(IEnumerable> map) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] SerializeKeyValuePairsListAsBytes(List> listKVp, out int count) + public static byte[] SerializeKeyValuePairsListAsBytes(List>? listKVp, out int count) { var buffer = ThreadLocalBuffer.Value; if (buffer == null) @@ -156,7 +158,7 @@ public static byte[] SerializeKeyValuePairsListAsBytes(List> map) + public static int SerializeMap(byte[] buffer, int cursor, IEnumerable>? map) { if (map == null) { @@ -183,7 +185,7 @@ public static int SerializeMap(byte[] buffer, int cursor, IEnumerable> listKvp) + public static int SerializeKeyValuePairList(byte[] buffer, int cursor, List>? listKvp) { if (listKvp == null) { @@ -210,7 +212,7 @@ public static int SerializeKeyValuePairList(byte[] buffer, int cursor, List tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; - (obj as ISpanFormattable).TryFormat(tmp, out int charsWritten, default, CultureInfo.InvariantCulture); + ((ISpanFormattable)obj).TryFormat(tmp, out int charsWritten, default, CultureInfo.InvariantCulture); return WriteString(buffer, cursor, tmp.Slice(0, charsWritten)); case DateTime dt: tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; @@ -297,7 +299,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) return SerializeArray(buffer, cursor, vdtarray); case string v: return SerializeString(buffer, cursor, v); - case IEnumerable> v: + case IEnumerable> v: return SerializeMap(buffer, cursor, v); case object[] v: return SerializeArray(buffer, cursor, v); @@ -314,7 +316,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) #endif default: - string repr; + string? repr; try { repr = Convert.ToString(obj, CultureInfo.InvariantCulture); diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs index a7f6f3ba33..92b7ed47a0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; @@ -35,6 +38,8 @@ internal abstract class TldExporter [MethodImpl(MethodImplOptions.AggressiveInlining)] protected static void Serialize(EventBuilder eb, string key, object value) { + Debug.Assert(value != null, "value was null"); + switch (value) { case bool vb: @@ -124,11 +129,11 @@ protected static void Serialize(EventBuilder eb, string key, object value) string repr; try { - repr = Convert.ToString(value, CultureInfo.InvariantCulture); + repr = Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty; } catch { - repr = $"ERROR: type {value.GetType().FullName} is not supported"; + repr = $"ERROR: type {value!.GetType().FullName} is not supported"; } eb.AddCountedAnsiString(key, repr, Encoding.UTF8, 0, Math.Min(repr.Length, StringLengthLimit)); diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs index 6053771a9d..b14a1f3f6a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; using System.Text; @@ -17,7 +20,7 @@ internal sealed class TldLogExporter : TldExporter, IDisposable // TODO: Is using a single ThreadLocal a better idea? private static readonly ThreadLocal EventBuilder = new(); - private static readonly ThreadLocal>> EnvProperties = new(); + private static readonly ThreadLocal>> EnvProperties = new(); private static readonly ThreadLocal[]> PartCFields = new(); // This is used to temporarily store the PartC fields from tags private static readonly Action ProcessScopeForIndividualColumnsAction = OnProcessScopeForIndividualColumns; private static readonly string[] LogLevels = new string[7] @@ -29,9 +32,9 @@ internal sealed class TldLogExporter : TldExporter, IDisposable private readonly byte partAFieldsCount = 1; // At least one field: time private readonly bool shouldPassThruTableMappings; private readonly string defaultEventName = "Log"; - private readonly HashSet customFields; - private readonly Dictionary tableMappings; - private readonly Tuple repeatedPartAFields; + private readonly HashSet? customFields; + private readonly Dictionary? tableMappings; + private readonly Tuple? repeatedPartAFields; private readonly ExceptionStackExportMode exceptionStackExportMode; private readonly EventProvider eventProvider; @@ -90,12 +93,7 @@ public TldLogExporter(GenevaExporterOptions options) var prePopulatedFieldsCount = (byte)(options.PrepopulatedFields.Count - 1); // PrepopulatedFields option has the key ".ver" added to it which is not needed for TLD this.partAFieldsCount += prePopulatedFieldsCount; - var eb = EventBuilder.Value; - if (eb == null) - { - eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - EventBuilder.Value = eb; - } + var eb = EventBuilder.Value ??= new EventBuilder(UncheckedASCIIEncoding.SharedInstance); eb.Reset("_"); // EventName does not matter here as we only need the serialized key-value pairs @@ -109,7 +107,7 @@ public TldLogExporter(GenevaExporterOptions options) continue; } - V40_PART_A_TLD_MAPPING.TryGetValue(key, out string replacementKey); + V40_PART_A_TLD_MAPPING.TryGetValue(key, out string? replacementKey); var keyToSerialize = replacementKey ?? key; Serialize(eb, keyToSerialize, value); @@ -120,15 +118,17 @@ public TldLogExporter(GenevaExporterOptions options) public ExportResult Export(in Batch batch) { - var result = ExportResult.Success; if (this.eventProvider.IsEnabled()) { - foreach (var activity in batch) + var result = ExportResult.Success; + + foreach (var logRecord in batch) { try { - this.SerializeLogRecord(activity); - this.eventProvider.Write(EventBuilder.Value); + var eventBuilder = this.SerializeLogRecord(logRecord); + + this.eventProvider.Write(eventBuilder); } catch (Exception ex) { @@ -136,13 +136,11 @@ public ExportResult Export(in Batch batch) result = ExportResult.Failure; } } - } - else - { - return ExportResult.Failure; + + return result; } - return result; + return ExportResult.Failure; } public void Dispose() @@ -166,9 +164,9 @@ public void Dispose() this.isDisposed = true; } - internal void SerializeLogRecord(LogRecord logRecord) + internal EventBuilder SerializeLogRecord(LogRecord logRecord) { - IReadOnlyList> listKvp; + IReadOnlyList>? listKvp; // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 #pragma warning disable 0618 @@ -179,7 +177,7 @@ internal void SerializeLogRecord(LogRecord logRecord) else { // Attempt to see if State could be ROL_KVP. - listKvp = logRecord.State as IReadOnlyList>; + listKvp = logRecord.State as IReadOnlyList>; } #pragma warning restore 0618 @@ -194,33 +192,27 @@ internal void SerializeLogRecord(LogRecord logRecord) // price = 100 // TODO: 2. Structured with strongly typed logging. - string eventName; - var categoryName = logRecord.CategoryName; + var categoryName = logRecord.CategoryName ?? this.defaultEventName; // If user configured explicit TableName, use it. - if (this.tableMappings != null && this.tableMappings.TryGetValue(categoryName, out eventName)) + if (this.tableMappings?.TryGetValue(categoryName, out var eventName) != true) { - } - else if (!this.shouldPassThruTableMappings) - { - eventName = this.defaultEventName; - } - else - { - // TODO: Avoid allocation - eventName = GetSanitizedCategoryName(categoryName); + if (!this.shouldPassThruTableMappings) + { + eventName = this.defaultEventName; + } + else + { + // TODO: Avoid allocation + eventName = GetSanitizedCategoryName(categoryName); + } } - var eb = EventBuilder.Value; - if (eb == null) - { - eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - EventBuilder.Value = eb; - } + var eb = EventBuilder.Value ??= new EventBuilder(UncheckedASCIIEncoding.SharedInstance); var timestamp = logRecord.Timestamp; - eb.Reset(eventName); + eb.Reset(eventName!); eb.AddUInt16("__csver__", 1024, EventOutType.Hex); var partAFieldsCountPatch = eb.AddStruct("PartA", this.partAFieldsCount); @@ -248,7 +240,12 @@ internal void SerializeLogRecord(LogRecord logRecord) // Part A - ex extension if (logRecord.Exception != null) { - eb.AddCountedAnsiString("ext_ex_type", logRecord.Exception.GetType().FullName, Encoding.UTF8); + var fullName = logRecord.Exception.GetType().FullName; + if (!string.IsNullOrEmpty(fullName)) + { + eb.AddCountedAnsiString("ext_ex_type", fullName, Encoding.UTF8); + } + eb.AddCountedAnsiString("ext_ex_msg", logRecord.Exception.Message, Encoding.UTF8); partAFieldsCount += 2; @@ -296,14 +293,9 @@ internal void SerializeLogRecord(LogRecord logRecord) bool namePopulated = false; byte partCFieldsCountFromState = 0; - var kvpArrayForPartCFields = PartCFields.Value; - if (kvpArrayForPartCFields == null) - { - kvpArrayForPartCFields = new KeyValuePair[120]; - PartCFields.Value = kvpArrayForPartCFields; - } + var kvpArrayForPartCFields = PartCFields.Value ??= new KeyValuePair[120]; - List> envPropertiesList = null; + List>? envPropertiesList = null; for (int i = 0; i < listKvp?.Count; i++) { @@ -313,7 +305,10 @@ internal void SerializeLogRecord(LogRecord logRecord) // i.e all Part B fields and opt-in Part C fields. if (entry.Key == "{OriginalFormat}") { - eb.AddCountedAnsiString("body", logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture), Encoding.UTF8); + eb.AddCountedAnsiString( + "body", + logRecord.FormattedMessage ?? Convert.ToString(entry.Value, CultureInfo.InvariantCulture) ?? string.Empty, + Encoding.UTF8); partBFieldsCount++; bodyPopulated = true; continue; @@ -345,18 +340,13 @@ internal void SerializeLogRecord(LogRecord logRecord) if (hasEnvProperties == 0) { hasEnvProperties = 1; - envPropertiesList = EnvProperties.Value; - if (envPropertiesList == null) - { - envPropertiesList = new List>(); - EnvProperties.Value = envPropertiesList; - } + envPropertiesList = EnvProperties.Value ??= new(); envPropertiesList.Clear(); } // TODO: This could lead to unbounded memory usage. - envPropertiesList.Add(new(entry.Key, entry.Value)); + envPropertiesList!.Add(new(entry.Key, entry.Value)); } } @@ -376,12 +366,7 @@ internal void SerializeLogRecord(LogRecord logRecord) // Part C // Prepare state for scopes - var dataForScopes = this.serializationData.Value; - if (dataForScopes == null) - { - dataForScopes = new SerializationDataForScopes(); - this.serializationData.Value = dataForScopes; - } + var dataForScopes = this.serializationData.Value ??= new(); dataForScopes.HasEnvProperties = hasEnvProperties; dataForScopes.PartCFieldsCountFromState = partCFieldsCountFromState; @@ -413,6 +398,8 @@ internal void SerializeLogRecord(LogRecord logRecord) eb.SetStructFieldCount(partCFieldsCountPatch, (byte)partCFieldsCount); } + + return eb; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -496,12 +483,16 @@ private static string GetSanitizedCategoryName(string categoryName) private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, TldLogExporter state) { - var stateData = state.serializationData.Value; + Debug.Assert(state.serializationData.Value != null, "state.serializationData was null"); + Debug.Assert(PartCFields.Value != null, "PartCFields.Value was null"); + + var stateData = state.serializationData.Value!; var customFields = state.customFields; - var kvpArrayForPartCFields = PartCFields.Value; - var envPropertiesList = EnvProperties.Value; + var kvpArrayForPartCFields = PartCFields.Value!; - foreach (KeyValuePair scopeItem in scope) + List>? envPropertiesList = null; + + foreach (KeyValuePair scopeItem in scope) { if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { @@ -521,17 +512,14 @@ private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, Tld if (stateData.HasEnvProperties == 0) { stateData.HasEnvProperties = 1; - if (envPropertiesList == null) - { - envPropertiesList = new List>(); - EnvProperties.Value = envPropertiesList; - } + + envPropertiesList = EnvProperties.Value ??= new(); envPropertiesList.Clear(); } // TODO: This could lead to unbounded memory usage. - envPropertiesList.Add(new(scopeItem.Key, scopeItem.Value)); + envPropertiesList!.Add(new(scopeItem.Key, scopeItem.Value)); } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs index cddfa44470..33fdefecdd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Globalization; using System.Text; @@ -13,12 +15,12 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable { // TODO: Is using a single ThreadLocal a better idea? private static readonly ThreadLocal EventBuilder = new(); - private static readonly ThreadLocal>> KeyValuePairs = new(); + private static readonly ThreadLocal>> KeyValuePairs = new(); private static readonly ThreadLocal[]> PartCFields = new(); // This is used to temporarily store the PartC fields from tags private static readonly string INVALID_SPAN_ID = default(ActivitySpanId).ToHexString(); - private static readonly Dictionary CS40_PART_B_MAPPING = new Dictionary + private static readonly Dictionary CS40_PART_B_MAPPING = new() { ["db.system"] = "dbSystem", ["db.name"] = "dbName", @@ -38,8 +40,8 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable private readonly string partAName = "Span"; private readonly byte partAFieldsCount = 3; // At least three fields: time, ext_dt_traceId, ext_dt_spanId - private readonly HashSet customFields; - private readonly Tuple repeatedPartAFields; + private readonly HashSet? customFields; + private readonly Tuple? repeatedPartAFields; private readonly bool shouldIncludeTraceState; private readonly EventProvider eventProvider; @@ -67,9 +69,9 @@ public TldTraceExporter(GenevaExporterOptions options) // Seed customFields with Span PartB customFields.Add("azureResourceProvider"); - foreach (var name in CS40_PART_B_MAPPING.Values) + foreach (var mapping in CS40_PART_B_MAPPING) { - customFields.Add(name); + customFields.Add(mapping.Key); } foreach (var name in options.CustomFields) @@ -85,12 +87,7 @@ public TldTraceExporter(GenevaExporterOptions options) var prePopulatedFieldsCount = (byte)(options.PrepopulatedFields.Count - 1); // PrepopulatedFields option has the key ".ver" added to it which is not needed for TLD this.partAFieldsCount += prePopulatedFieldsCount; - var eb = EventBuilder.Value; - if (eb == null) - { - eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - EventBuilder.Value = eb; - } + var eb = EventBuilder.Value ??= new EventBuilder(UncheckedASCIIEncoding.SharedInstance); eb.Reset(this.partAName); @@ -104,7 +101,7 @@ public TldTraceExporter(GenevaExporterOptions options) continue; } - V40_PART_A_TLD_MAPPING.TryGetValue(key, out string replacementKey); + V40_PART_A_TLD_MAPPING.TryGetValue(key, out string? replacementKey); var keyToSerialize = replacementKey ?? key; Serialize(eb, keyToSerialize, value); @@ -117,15 +114,17 @@ public TldTraceExporter(GenevaExporterOptions options) public ExportResult Export(in Batch batch) { - var result = ExportResult.Success; if (this.eventProvider.IsEnabled()) { + var result = ExportResult.Success; + foreach (var activity in batch) { try { - this.SerializeActivity(activity); - this.eventProvider.Write(EventBuilder.Value); + var eventBuilder = this.SerializeActivity(activity); + + this.eventProvider.Write(eventBuilder); } catch (Exception ex) { @@ -133,13 +132,11 @@ public ExportResult Export(in Batch batch) result = ExportResult.Failure; } } - } - else - { - return ExportResult.Failure; + + return result; } - return result; + return ExportResult.Failure; } public void Dispose() @@ -162,14 +159,9 @@ public void Dispose() this.isDisposed = true; } - internal void SerializeActivity(Activity activity) + internal EventBuilder SerializeActivity(Activity activity) { - var eb = EventBuilder.Value; - if (eb == null) - { - eb = new EventBuilder(UncheckedASCIIEncoding.SharedInstance); - EventBuilder.Value = eb; - } + var eb = EventBuilder.Value ??= new EventBuilder(UncheckedASCIIEncoding.SharedInstance); eb.Reset(this.partAName); eb.AddUInt16("__csver__", 1024, EventOutType.Hex); @@ -209,7 +201,7 @@ internal void SerializeActivity(Activity activity) var traceStateString = activity.TraceStateString; if (!string.IsNullOrEmpty(traceStateString)) { - eb.AddCountedAnsiString("traceState", traceStateString, Encoding.UTF8); + eb.AddCountedAnsiString("traceState", traceStateString!, Encoding.UTF8); partBFieldsCount++; } } @@ -217,12 +209,7 @@ internal void SerializeActivity(Activity activity) var linkEnumerator = activity.EnumerateLinks(); if (linkEnumerator.MoveNext()) { - var keyValuePairsForLinks = KeyValuePairs.Value; - if (keyValuePairsForLinks == null) - { - keyValuePairsForLinks = new List>(); - KeyValuePairs.Value = keyValuePairsForLinks; - } + var keyValuePairsForLinks = KeyValuePairs.Value ??= new(); keyValuePairsForLinks.Clear(); @@ -247,61 +234,64 @@ internal void SerializeActivity(Activity activity) string statusDescription = string.Empty; int partCFieldsCountFromTags = 0; - var kvpArrayForPartCFields = PartCFields.Value; - if (kvpArrayForPartCFields == null) - { - kvpArrayForPartCFields = new KeyValuePair[120]; - PartCFields.Value = kvpArrayForPartCFields; - } + var kvpArrayForPartCFields = PartCFields.Value ??= new KeyValuePair[120]; - List> envPropertiesList = null; + List>? envPropertiesList = null; foreach (ref readonly var entry in activity.EnumerateTagObjects()) { + if (entry.Value == null) + { + continue; + } + // TODO: check name collision - if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string? replacementKey)) { Serialize(eb, replacementKey, entry.Value); partBFieldsCount++; + continue; } - else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) + + if (entry.Key.StartsWith("otel.status_", StringComparison.Ordinal)) { - if (string.Equals(Convert.ToString(entry.Value, CultureInfo.InvariantCulture), "ERROR", StringComparison.Ordinal)) + var keyPart = entry.Key.AsSpan().Slice(12); + if (keyPart is "code") { - isStatusSuccess = 0; + if (string.Equals(Convert.ToString(entry.Value, CultureInfo.InvariantCulture), "ERROR", StringComparison.Ordinal)) + { + isStatusSuccess = 0; + } + + continue; } - continue; - } - else if (string.Equals(entry.Key, "otel.status_description", StringComparison.Ordinal)) - { - statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); - continue; + if (keyPart is "description") + { + statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture) ?? string.Empty; + continue; + } } - else if (this.customFields == null || this.customFields.Contains(entry.Key)) + + if (this.customFields == null || this.customFields.Contains(entry.Key)) { // TODO: the above null check can be optimized and avoided inside foreach. kvpArrayForPartCFields[partCFieldsCountFromTags] = new(entry.Key, entry.Value); partCFieldsCountFromTags++; + continue; } - else + + if (hasEnvProperties == 0) { - if (hasEnvProperties == 0) - { - hasEnvProperties = 1; - envPropertiesList = KeyValuePairs.Value; - if (envPropertiesList == null) - { - envPropertiesList = new List>(); - KeyValuePairs.Value = envPropertiesList; - } + hasEnvProperties = 1; - envPropertiesList.Clear(); - } + envPropertiesList = KeyValuePairs.Value ??= new(); - // TODO: This could lead to unbounded memory usage. - envPropertiesList.Add(new(entry.Key, entry.Value)); + envPropertiesList.Clear(); } + + // TODO: This could lead to unbounded memory usage. + envPropertiesList!.Add(new(entry.Key, entry.Value)); } if (activity.Status != ActivityStatusCode.Unset) @@ -313,17 +303,14 @@ internal void SerializeActivity(Activity activity) if (!string.IsNullOrEmpty(activity.StatusDescription)) { - eb.AddCountedAnsiString("statusMessage", statusDescription, Encoding.UTF8); + eb.AddCountedAnsiString("statusMessage", statusDescription!, Encoding.UTF8); partBFieldsCount++; } } - else + else if (!string.IsNullOrEmpty(activity.StatusDescription)) { - if (!string.IsNullOrEmpty(activity.StatusDescription)) - { - eb.AddCountedAnsiString("statusMessage", statusDescription, Encoding.UTF8); - partBFieldsCount++; - } + eb.AddCountedAnsiString("statusMessage", statusDescription!, Encoding.UTF8); + partBFieldsCount++; } // Do not increment partBFieldsCount here as the field "success" has already been accounted for @@ -351,5 +338,7 @@ internal void SerializeActivity(Activity activity) eb.AddCountedAnsiString("env_properties", serializedEnvPropertiesStringAsBytes, 0, count); } } + + return eb; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs index 5b8f52b7b3..a27c983040 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Text; using OpenTelemetry.Internal; From 7a09ef727844dd7968baee5564d2b1f1c30bf507 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 23 Sep 2024 13:17:05 -0700 Subject: [PATCH 1264/1499] [docs] Contributing and releasing doc updates (#2091) --- .markdownlint.yaml | 7 +- CONTRIBUTING.md | 212 +++++++++++++++++-------------- build/RELEASING.md | 154 +++++++++++++++++++--- opentelemetry-dotnet-contrib.sln | 22 ++-- 4 files changed, 270 insertions(+), 125 deletions(-) diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 30672f8e7f..c388b69fd5 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -1,7 +1,12 @@ # Default state for all rules default: true -# allow long lines for tables and code blocks +# MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md013.md MD013: code_blocks: false tables: false + +# MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md033.md +MD033: + # Allowed elements + allowed_elements: [ 'details', 'summary' ] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3a7eee404..45df3c028c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,16 @@ 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). -## Find a Buddy and Get Started Quickly +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), +[**Approver**](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver) +and +[**Maintainer**](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer). + +## 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! @@ -25,19 +34,19 @@ 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 8.0+ +* Git client and command line tools +* [.NET SDK (latest stable version)](https://dotnet.microsoft.com/download) -Please note that individual project requirements might vary. +Please note that individual project requirements may vary. ### Linux or MacOS @@ -52,9 +61,24 @@ are disabled outside of Windows. * Visual Studio 2022+ or Visual Studio Code * .NET Framework 4.6.2+ +## 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. + +For details about working with these packages and updating "public API files" +when new APIs are added see: [OpenTelemetry .NET > Contributing to +opentelemetry-dotnet > Public API +validation](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/CONTRIBUTING.md#public-api-validation). + ## Pull Requests -### How to Send Pull Requests +### How to create pull requests Everyone is welcome to contribute code to `opentelemetry-dotnet-contrib` via GitHub pull requests (PRs). @@ -114,17 +138,20 @@ $ git push fork feature Open a pull request against the main `opentelemetry-dotnet-contrib` 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/). -* Make sure CLA is signed and CI is clear. -* Submit small, focused PRs addressing a single concern/issue. +* Make sure CLA is signed and all required CI checks are clear. +* 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. -### How to Get PRs Merged +### How to get pull requests merged A PR is considered to be **ready to merge** when: @@ -133,37 +160,30 @@ A PR is considered to be **ready to merge** when: / [Maintainers](https://github.com/open-telemetry/community/blob/master/community-membership.md#maintainer) or the respective component owner. -* 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. - -Any Maintainer can merge the PR once it is **ready to merge**. Note that some -PR may not be merged immediately if repo is being in process of a major release -and the new feature doesn't fit it. + * 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. -### How to request for release of package +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. -* Submit a PR with `CHANGELOG.md` file reflecting the version to be released -along with the date in the following format `yyyy-MMM-dd`. - -For example: - -```text -## 1.2.0-beta.2 - -Released 2022-Jun-21 -``` +## Release process -* Tag the maintainers of this repository -(@open-telemetry/dotnet-contrib-maintainers) who can release the package. +For details about the release process and information about how to request a +release for a component in this repository see: [Requesting a +release](./build/RELEASING.md#requesting-a-release). -## Style Guide +## Style guide This project includes a [`.editorconfig`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/master/.editorconfig) -file which is supported by all the IDEs/editor mentioned above. It works with +file which is 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 @@ -171,10 +191,11 @@ files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/maste These files are used to configure the _StyleCop.Analyzers_ which runs during build. Breaking the rules will result in a build failure. -## Contributing a new project +## New projects -This repo is a great place to contribute a new instrumentation, exporter or any -kind of extension. Please refer to [this +This repo is a great place to contribute exporters, instrumentation libraries, +resource detectors, samplers, or any other kind of extension/component not +explicitly defined in the OpenTelemetry Specification. Please refer to [this page](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#extending-the-opentelemetry-net-sdk) for help writing your component. @@ -194,62 +215,60 @@ within `/src` and corresponding test project within `/test`, here are a few things you should do to ensure that your project is automatically built and shipped through CI. -* Based on what your project is, you may need to depend on the [OpenTelemetry -SDK](https://www.nuget.org/packages/OpenTelemetry) or the [OpenTelemetry -API](https://www.nuget.org/packages/OpenTelemetry.Api) Include the necessary -package in your project. You can choose the version that you want to depend on. -Usually, it is a good idea to use the latest stable version. For example: - -```xml - - - -``` - -* If your component relies on new features not yet part of the stable release, you -can refer to the latest pre-release version. +> [!NOTE] +> It is generally helpful to reference a previous pull request when adding a new + project to the repository. A good example to follow is the pull request which + added the `OpenTelemetry.Resources.OperatingSystem` project: + [#1943](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1943). -```xml - - - -``` +* Based on what your project is, you may need to depend on the [OpenTelemetry + SDK](https://www.nuget.org/packages/OpenTelemetry) or the [OpenTelemetry + API](https://www.nuget.org/packages/OpenTelemetry.Api) Include the necessary + package in your project. You can choose the version that you want to depend + on. Usually, it is a good idea to use the latest stable version. For example: + + ```xml + + + + ``` + +* If your component relies on new features not yet part of the stable release, + you can refer to the latest pre-release version. + + ```xml + + + + ``` * The assembly and nuget versioning is managed through -[MinVer](https://github.com/adamralph/minver) for all the projects in the repo. -MinVer will assign the version to your project based on the tag prefix specified -by you. To ensure your project is versioned appropriately, specify a -`` property in your project file. If your project is named as -"OpenTelemetry.Instrumentation.FooBar", the MinVerTagPrefix must be -"Instrumentation.FooBar-". Example: - -```xml - - Instrumentation.FooBar- - -``` - -* Public API of all packages is analyzed by -[Microsoft.CodeAnalysis.PublicApiAnalyzers](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md). -This analyzer requires files structure to store the information about public API. -Create `PublicAPI.Shipped.txt` and `PublicAPI.Unshipped.txt` for each `TargetFramework` -defined in csproj under `{ProjectFolder}\.publicApi\{TargetFramework}`. - -* To build and release your project as nuget, you must provide a GitHub workflow -to be triggered when a tag with prefix "Instrumentation.FooBar-" is pushed to -the main branch. The workflow file should be named as -`package-Instrumentation.FooBar.yml` and to be placed in the -`.github/workflows/` folder. - - You can copy one of the [existing workflow - files](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml) - and replace the workflow - [`name`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L1) - with "Pack OpenTelemetry.Instrumentation.FooBar", - [`tags`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L12) - with "Instrumentation.FooBar-*" and - [`PROJECT`](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/package-Instrumentation.AspNet.yml#L18) - with "OpenTelemetry.Instrumentation.FooBar". + [MinVer](https://github.com/adamralph/minver) for all the projects in the + repo. MinVer will assign the version to your project based on the tag prefix + specified by you. To ensure your project is versioned appropriately, specify a + `` property in your project file. If your project is named as + "OpenTelemetry.Instrumentation.FooBar", the MinVerTagPrefix must be + "Instrumentation.FooBar-". Example: + + ```xml + + Instrumentation.FooBar- + + ``` + +* The public API surface of all packages is analyzed by + [Microsoft.CodeAnalysis.PublicApiAnalyzers](https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/Microsoft.CodeAnalysis.PublicApiAnalyzers.md). + This analyzer requires a specific file structure to store the information + about public API. See [this + doc](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/CONTRIBUTING.md#enable-public-api-validation-in-new-projects) + for help setting up public API analysis. + +* Update the [CI + workflow](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/ci.yml) + so that it builds your new project and update the [code + coverage](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/codecov.yml) + definition for your new component (it should match what you define in the CI + workflow). * Add your component name to the [issue templates](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/.github/ISSUE_TEMPLATE/) @@ -257,14 +276,17 @@ the main branch. The workflow file should be named as label](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/labels?q=comp%3A) once the PR is merged. -* Add a README file for your project describing how to install and use your +* Add a `README.md` file for your project describing how to install and use your package. Every project's README file needs to have a link to the Nuget package. You can use the below snippet for reference: -```md -[![NuGet version badge](https://img.shields.io/nuget/v/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) -[![NuGet download count badge](https://img.shields.io/nuget/dt/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) -``` + ```md + [![NuGet version badge](https://img.shields.io/nuget/v/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) + [![NuGet download count badge](https://img.shields.io/nuget/dt/{your_package_name})](https://www.nuget.org/packages/{your_package_name}) + ``` + +* Add a `CHANGELOG.md` file for your project to track changes made after the + initial pull request. ### Guidance for components on supporting target frameworks diff --git a/build/RELEASING.md b/build/RELEASING.md index 87136190ee..d44c4faccb 100644 --- a/build/RELEASING.md +++ b/build/RELEASING.md @@ -1,9 +1,118 @@ # Release Process -Releasing of projects from the opentelemetry-dotnet-contrib repo is -currently a mix of automated workflow and some manual steps. Hopefully -most of this will be automated soon. +Releasing of projects from the opentelemetry-dotnet-contrib repo is typically a +fully automated process. + +## Requesting a release + +Anyone may request the release of a component by using the [Release +request](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/new?assignees=&labels=release&projects=&template=release_request.yml&title=%5Brelease+request%5D+) +issue template. + +* Select the component you want released from the dropdown. + + > [!NOTE] + > Most components only have a single entry which makes this selection simple. + However some components, for example AspNet instrumentation, are really + multiple components released together. For the multi-component case, pick + any component from the group in the dropdown. All components in a group will + be released together regardless of which is selected. + +* Specify the version for the release. + + > [!NOTE] + > Any version may be specified when creating the release request issue but the + release will not be initiated until the version complies with the + `^(\d+\.\d+\.\d+)(?:-((?:alpha)|(?:beta)|(?:rc))\.(\d+))?$` regular + expression. + +* Specify any additional context for why the release is being requested. + +* Create the release request issue. + + * If you are an approver or a maintainer of the repo, the release request will + automatically be approved and the automation will proceed to create the + "Prepare release" pull request. See [Working with the release + automation](#working-with-the-release-automation) to continue. + + > [!NOTE] + > Approvers and maintainers may skip the release request issue and use the + [GitHub Actions + UI](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/prepare-release.yml) + to run the [prepare-release + workflow](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/prepare-release.yml) + directly. + + * If you are a [component + owner](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/component_owners.yml) + for the component requested, the release request will automatically be + approved and the automation will proceed to create the "Prepare release" + pull request. See [Working with the release + automation](#working-with-the-release-automation) to continue. + + * If neither of the above two cases are true for you, then the release request + issue you created will need to be approved by a component owner, approver, + or maintainer. They should automatically be tagged/mentioned on your issue + by the automation. + +## Working with the release automation + +The release request issue created using the [Requesting a +release](#requesting-a-release) flow above is used to trigger the +[prepare-release +workflow](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/.github/workflows/prepare-release.yml) +which will create a pull request to begin the automation flow for all of the +book-keeping/routine tasks needed to be done in the release process: + +> [!NOTE] +> Once the "Prepare release" pull request is opened the job of users and + component owners is complete. Only approvers and maintainers of the repo can + proceed from this point. + +Pre-build: + +* `CHANGELOG` updates. +* Public API file (`.publicApi` folder) updates (for stable releases only). + +Post-build: + +* NuGet push. +* GitHub release creation. +* `PackageValidationBaselineVersion` updates (for stable releases only). + +
    +Instructions for approvers and maintainers + +1. Review and merge the opened "Prepare release" pull request. + +2. Post a comment with "/CreateReleaseTag" in the body. This will tell the + [Prepare for a + release](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/prepare-release.yml) + workflow to push the tag for the merge commit of the PR which will trigger + the [Build, pack, and + publish](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/publish-packages.yml) + workflow. + +3. Wait for the [Build, pack, and + publish](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/publish-packages.yml) + workflow to complete. When complete a trigger will automatically add a + comment on the "Prepare Release" PR with a link to the package artifacts and + GitHub release. + +4. If a new stable version of the component was released, a PR should have been + automatically created by the [Complete + release](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions/workflows/post-release.yml) + workflow to update the `PackageValidationBaselineVersion` property in project + files (`.csproj`) to the just released stable version. Merge that PR once the + build passes (this requires the packages be available on NuGet). + +
    + +## Manual process + +
    +Instructions for preparing for a release manually ## Pre-requisites @@ -12,30 +121,35 @@ To carry out the release successfully, make sure you fulfill the following: 1. You must be a maintainer on the repo. This will allow you to push tags to `main` branch and create a GitHub release later on. -2. Have access to the Nuget token for releasing the project to Nuget.org +2. Have access to the NuGet token for releasing the project to NuGet.org OpenTelemetry account. ## Pre-steps 1. Decide on the version to use for the release. -2. Update the Changelog for your project with relevant details. +2. Update the `CHANGELOG.md` file for your project with relevant details. Replace any "Unreleased" heading with this version and add the release date. -3. If you are releasing stable version, update public API definition -in `PublicAPI.Shipped.txt` files and cleanup corresponding `PublicAPI.Unshipped.txt`. +3. If you are releasing stable version, update public API definition in +`PublicAPI.Shipped.txt` files and cleanup corresponding +`PublicAPI.Unshipped.txt`. -4. Submit a PR to update Changelog and get it merged to `main` branch. +4. Submit a PR to update `CHANGELOG.md` and get it merged to `main` branch. ## Steps *Note:* Before starting with the following steps, ensure that the latest commit -on the `main` branch is the one which added/updated the Changelog to -the project being released. *This latest commit will be tagged on the release.* +on the `main` branch is the one which added/updated the `CHANGELOG.md` to the +project being released. *This latest commit will be tagged on the release.* + +1. Create and push git tag for the project and the version of the project you + want to release. The version should be the one used in the **Pre-steps** to + update the Changelog. -1. Create and push git tag for the project and the version of the project -you want to release. The version should be the one used in the **Pre-steps** to -update the Changelog. + Note: In the below examples `git push origin` is used. If running in a fork, + add the main repo as `upstream` and use `git push upstream` instead. Pushing + a tag to `origin` in a fork pushes the tag to the fork. ```powershell git tag -a - -m "-" @@ -49,7 +163,7 @@ update the Changelog. git push origin - ``` - **example:** + **Example:** ```powershell git tag -a Instrumentation.AWS-1.0.0 -m "Instrumentation.AWS-1.0.0" @@ -66,15 +180,17 @@ update the Changelog. This will trigger the building and packaging workflow for the project. 2. Navigate to the -[**Actions**](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions) -tab on the repo and monitor the "Pack YOUR_PROJECT_NAME" workflow. The last step -in the workflow is to publish to Nuget.org and prepare corresponding github -release page. + [**Actions**](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/actions) + tab on the repo and monitor the "Pack YOUR_PROJECT_NAME" workflow. The last + step in the workflow is to publish to NuGet.org and prepare corresponding + GitHub release page. 3. Validate that the new version (as specified in step 1) of the project is -successfully published to nuget.org under OpenTelemetry owner. + successfully published to NuGet.org under OpenTelemetry owner. 4. Validate that the new version was published in GitHub. 5. If you released stable package, update `PackageValidationBaselineVersion` in corresponding `csproj` file. + +
    diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 8c093fb419..e7d54517db 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -9,6 +9,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{07AA0F83-22F6-4B8C-921D-029D3384CB17}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + .markdownlint.yaml = .markdownlint.yaml CODEOWNERS = CODEOWNERS CONTRIBUTING.md = CONTRIBUTING.md global.json = global.json @@ -58,6 +59,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset + build\RELEASING.md = build\RELEASING.md build\stylecop.json = build\stylecop.json EndProjectSection EndProject @@ -723,6 +725,14 @@ Global {A5EF701C-439E-407F-8BB4-394166000C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A5EF701C-439E-407F-8BB4-394166000C6D}.Release|Any CPU.Build.0 = Release|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.Build.0 = Release|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.Build.0 = Release|Any CPU {033CA8D4-1529-413A-B244-07958D5F9A48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {033CA8D4-1529-413A-B244-07958D5F9A48}.Debug|Any CPU.Build.0 = Debug|Any CPU {033CA8D4-1529-413A-B244-07958D5F9A48}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -807,14 +817,6 @@ Global {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.Build.0 = Release|Any CPU - {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1}.Release|Any CPU.Build.0 = Release|Any CPU - {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Debug|Any CPU.Build.0 = Debug|Any CPU - {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62B7060A-C35B-4D49-A0C2-3BF02880A200}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -914,6 +916,8 @@ Global {2A51E621-BCFA-4D52-96D0-E16AFF48CBE5} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {A5FCDD8F-20FF-4657-804E-707EAD4FE31D} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {A5EF701C-439E-407F-8BB4-394166000C6D} = {2097345F-4DD3-477D-BC54-A922F9B2B402} + {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {62B7060A-C35B-4D49-A0C2-3BF02880A200} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {033CA8D4-1529-413A-B244-07958D5F9A48} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} {36271347-2055-438E-9659-B71542A17A73} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {7AD707F9-DC6D-430A-8834-D5DCD517BF6E} = {2097345F-4DD3-477D-BC54-A922F9B2B402} @@ -939,8 +943,6 @@ Global {BE40900A-2859-471D-8802-21DFD73DDAA7} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {3A464E7A-42F3-44B0-B8D7-80521A7704A6} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {9B994669-E839-4C42-A0F1-DF9DD058C1DC} = {3A464E7A-42F3-44B0-B8D7-80521A7704A6} - {F8E9EC7E-85A1-4C97-9C05-7EA82C1513A1} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} - {62B7060A-C35B-4D49-A0C2-3BF02880A200} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} From 8be3ff207a2dfa5f13df0efc4a79e11154a067cc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 23 Sep 2024 21:18:03 -0700 Subject: [PATCH 1265/1499] [sql] Workaround integration test failures (#2086) --- .../SqlClientIntegrationTests.cs | 22 +++------ .../SqlClientIntegrationTestsFixture.cs | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs index 9b77fe5deb..7d34f18dd2 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -3,8 +3,6 @@ using System.Data; using System.Diagnostics; -using System.Runtime.InteropServices; -using DotNet.Testcontainers.Containers; using Microsoft.Data.SqlClient; using OpenTelemetry.Tests; using OpenTelemetry.Trace; @@ -14,22 +12,16 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Tests; -public sealed class SqlClientIntegrationTests : IAsyncLifetime +[Trait("CategoryName", "SqlIntegrationTests")] +public sealed class SqlClientIntegrationTests : IClassFixture { - // The Microsoft SQL Server Docker image is not compatible with ARM devices, such as Macs with Apple Silicon. - private readonly IContainer databaseContainer = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? new SqlEdgeBuilder().Build() : new MsSqlBuilder().Build(); + private readonly SqlClientIntegrationTestsFixture fixture; - public Task InitializeAsync() + public SqlClientIntegrationTests(SqlClientIntegrationTestsFixture fixture) { - return this.databaseContainer.StartAsync(); + this.fixture = fixture; } - public Task DisposeAsync() - { - return this.databaseContainer.DisposeAsync().AsTask(); - } - - [Trait("CategoryName", "SqlIntegrationTests")] [EnabledOnDockerPlatformTheory(EnabledOnDockerPlatformTheoryAttribute.DockerPlatform.Linux)] [InlineData(CommandType.Text, "select 1/1", false)] [InlineData(CommandType.Text, "select 1/1", false, true)] @@ -105,14 +97,14 @@ public void SuccessfulCommandTest( private string GetConnectionString() { - switch (this.databaseContainer) + switch (this.fixture.DatabaseContainer) { case SqlEdgeContainer container: return container.GetConnectionString(); case MsSqlContainer container: return container.GetConnectionString(); default: - throw new InvalidOperationException($"Container type ${this.databaseContainer.GetType().Name} not supported."); + throw new InvalidOperationException($"Container type '${this.fixture.DatabaseContainer.GetType().Name}' is not supported."); } } } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs new file mode 100644 index 0000000000..57e0c85c6f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs @@ -0,0 +1,47 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.InteropServices; +using DotNet.Testcontainers.Containers; +using Testcontainers.MsSql; +using Testcontainers.SqlEdge; +using Xunit; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public sealed class SqlClientIntegrationTestsFixture : IAsyncLifetime +{ + // The Microsoft SQL Server Docker image is not compatible with ARM devices, such as Macs with Apple Silicon. + private readonly IContainer databaseContainer = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? CreateSqlEdge() : CreateMsSql(); + + public IContainer DatabaseContainer => this.databaseContainer; + + public Task InitializeAsync() + { + return this.databaseContainer.StartAsync(); + } + + public Task DisposeAsync() + { + return this.databaseContainer.DisposeAsync().AsTask(); + } + + private static SqlEdgeContainer CreateSqlEdge() + { + // Note: The Testcontainers.SqlEdge package has been deprecated. Seems + // it will not work with newer GItHub-hosted runners. Need to find an + // alternative solution. See: + // https://github.com/testcontainers/testcontainers-dotnet/pull/1265 + return new SqlEdgeBuilder().Build(); + } + + private static MsSqlContainer CreateMsSql() + { + // Note: This "WithImage" line can most likely be removed when there is + // a new version (>3.10.0) of Testcontainers.MsSql released. See: + // https://github.com/testcontainers/testcontainers-dotnet/pull/1265 + return new MsSqlBuilder() + .WithImage("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") + .Build(); + } +} From 1139fac084bec85e3541cc881e50a48525aebc39 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 23 Sep 2024 22:01:37 -0700 Subject: [PATCH 1266/1499] [repo] Sync-up .editorconfig with main repo (#2093) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .editorconfig | 45 +++++++++---------- .../External/TraceLoggingDynamic.cs | 2 + 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/.editorconfig b/.editorconfig index 42cb1f628d..cdfa4e3246 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 @@ -152,14 +156,9 @@ dotnet_diagnostic.IDE0005.severity = warning # RS0041: Public members should not use oblivious types dotnet_diagnostic.RS0041.severity = suggestion -[obj/**.cs] -[**/External/**.cs] +[**/obj/**.cs] generated_code = true -# Skip check for .cs files generated by proto -[**/proto/**.cs] -dotnet_diagnostic.SA1518.severity = none - [*.csproj] indent_size = 2 diff --git a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs index e2cea7bb1f..481e41c981 100644 --- a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs +++ b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs @@ -1,3 +1,5 @@ +// (Turns off StyleCop analysis in this file.) + /* Dynamic ETW TraceLogging Provider API for .NET. From b05067fa14a3137326a38e2e76aa3acde7a1ee75 Mon Sep 17 00:00:00 2001 From: Hans Bakker Date: Tue, 24 Sep 2024 07:20:39 +0200 Subject: [PATCH 1267/1499] [Resources.Azure] Add support for Container App Jobs (#2064) --- .../AzureContainerAppsResourceDetector.cs | 52 +++++++++++++------ .../CHANGELOG.md | 3 ++ src/OpenTelemetry.Resources.Azure/README.md | 10 ++-- .../ResourceAttributeConstants.cs | 4 ++ .../AzureResourceDetectorTests.cs | 41 +++++++++++++-- 5 files changed, 87 insertions(+), 23 deletions(-) diff --git a/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs index 97339af6e9..58c11aa2bd 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs @@ -10,35 +10,38 @@ namespace OpenTelemetry.Resources.Azure; ///
    internal sealed class AzureContainerAppsResourceDetector : IResourceDetector { - internal static readonly IReadOnlyDictionary AzureContainerResourceAttributes = new Dictionary + internal static readonly IReadOnlyDictionary AzureContainerAppResourceAttributes = new Dictionary { { ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar }, { ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppsRevisionEnvVar }, }; + internal static readonly IReadOnlyDictionary AzureContainerAppJobResourceAttributes = new Dictionary + { + { ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar }, + { ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppJobExecutionNameEnvVar }, + }; + /// public Resource Detect() { - List> attributeList = new(); - + List> attributeList = new List>(); try { var containerAppName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar); + var containerAppJobName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar); if (containerAppName != null) { - attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, containerAppName)); - attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue)); - attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureContainerAppsPlatformValue)); - - foreach (var kvp in AzureContainerResourceAttributes) - { - var attributeValue = Environment.GetEnvironmentVariable(kvp.Value); - if (attributeValue != null) - { - attributeList.Add(new KeyValuePair(kvp.Key, attributeValue)); - } - } + AddBaseAttributes(attributeList, containerAppName); + + AddResourceAttributes(attributeList, AzureContainerAppResourceAttributes); + } + else if (containerAppJobName != null) + { + AddBaseAttributes(attributeList, containerAppJobName); + + AddResourceAttributes(attributeList, AzureContainerAppJobResourceAttributes); } } catch @@ -49,4 +52,23 @@ public Resource Detect() return new Resource(attributeList); } + + private static void AddResourceAttributes(List> attributeList, IReadOnlyDictionary resourceAttributes) + { + foreach (var kvp in resourceAttributes) + { + var attributeValue = Environment.GetEnvironmentVariable(kvp.Value); + if (attributeValue != null) + { + attributeList.Add(new KeyValuePair(kvp.Key, attributeValue)); + } + } + } + + private static void AddBaseAttributes(List> attributeList, string serviceName) + { + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, serviceName)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue)); + attributeList.Add(new KeyValuePair(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureContainerAppsPlatformValue)); + } } diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 50b5a0065f..9a62044dde 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Added support for [Azure Container Apps jobs](https://learn.microsoft.com/en-us/azure/container-apps/jobs?tabs=azure-cli). + ([#2064](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2064)) + * Added direct reference to `System.Text.Encodings.Web` with minimum version of `4.7.2` in response to [CVE-2021-26701](https://github.com/dotnet/runtime/issues/49377). ([#2056](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2056)) diff --git a/src/OpenTelemetry.Resources.Azure/README.md b/src/OpenTelemetry.Resources.Azure/README.md index a5850289ac..d35976575e 100644 --- a/src/OpenTelemetry.Resources.Azure/README.md +++ b/src/OpenTelemetry.Resources.Azure/README.md @@ -98,9 +98,9 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder() ## Azure Container Apps Resource Detector -Adds resource attributes for the applications running in Azure Container Apps. -The following example shows how to add `AzureContainerAppsResourceDetector` to -the `ResourceBuilder`. +Adds resource attributes for the applications running in Azure Container Apps +or Azure Container App jobs. The following example shows how to add +`AzureContainerAppsResourceDetector` to the `ResourceBuilder`. ```csharp using OpenTelemetry; @@ -122,5 +122,5 @@ using var meterProvider = Sdk.CreateMeterProviderBuilder() | cloud.platform | The cloud platform. Here, it's always "azure_container_apps". | | cloud.provider | The cloud service provider. In this context, it's always "azure". | | service.instance.id | Represents the specific instance ID of Azure Container Apps, useful in scaled-out configurations. | -| service.name | The name of the Azure Container Apps. | -| service.version | The current revision or version of Azure Container Apps. | +| service.name | The name of the Azure Container Apps or Azure Container Apps job. | +| service.version | The current revision or version of Azure Container Apps, or in case of a Azure Container Apps job - the job execution name. | diff --git a/src/OpenTelemetry.Resources.Azure/ResourceAttributeConstants.cs b/src/OpenTelemetry.Resources.Azure/ResourceAttributeConstants.cs index 3a4a669a08..98a2ab3d75 100644 --- a/src/OpenTelemetry.Resources.Azure/ResourceAttributeConstants.cs +++ b/src/OpenTelemetry.Resources.Azure/ResourceAttributeConstants.cs @@ -27,6 +27,10 @@ internal sealed class ResourceAttributeConstants internal const string AzureContainerAppsReplicaNameEnvVar = "CONTAINER_APP_REPLICA_NAME"; internal const string AzureContainerAppsRevisionEnvVar = "CONTAINER_APP_REVISION"; + // Azure Container Apps Jobs environment variables + internal const string AzureContainerAppJobNameEnvVar = "CONTAINER_APP_JOB_NAME"; + internal const string AzureContainerAppJobExecutionNameEnvVar = "CONTAINER_APP_JOB_EXECUTION_NAME"; + // Azure resource attributes constant values internal const string AzureAppServicePlatformValue = "azure_app_service"; internal const string AzureCloudProviderValue = "azure"; diff --git a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs index 3e226d5d8e..cbe8ce70c1 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Azure.Tests/AzureResourceDetectorTests.cs @@ -97,7 +97,7 @@ public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes() { try { - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes) + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) { Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); } @@ -113,7 +113,34 @@ public void AzureContainerAppsResourceDetectorReturnsResourceWithAttributes() Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppName"), resource.Attributes); - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes) + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) + { + Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); + } + } + + [Fact] + public void AzureContainerAppsJobResourceDetectorReturnsResourceWithAttributes() + { + try + { + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) + { + Environment.SetEnvironmentVariable(kvp.Value, kvp.Key); + } + + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar, "containerAppJobName"); + } + catch + { + } + + var resource = ResourceBuilder.CreateEmpty().AddAzureContainerAppsDetector().Build(); + Assert.NotNull(resource); + + Assert.Contains(new KeyValuePair(ResourceSemanticConventions.AttributeServiceName, "containerAppJobName"), resource.Attributes); + + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) { Assert.Contains(new KeyValuePair(kvp.Key, kvp.Key), resource.Attributes); } @@ -126,9 +153,17 @@ public void Dispose() Environment.SetEnvironmentVariable(kvp.Value, null); } - foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerResourceAttributes) + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppResourceAttributes) + { + Environment.SetEnvironmentVariable(kvp.Value, null); + } + + foreach (var kvp in AzureContainerAppsResourceDetector.AzureContainerAppJobResourceAttributes) { Environment.SetEnvironmentVariable(kvp.Value, null); } + + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar, null); + Environment.SetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar, null); } } From 595512390565bca4e3279d3a1a59565b95d19405 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 24 Sep 2024 11:47:38 -0500 Subject: [PATCH 1268/1499] [release] Prepare release Resources.Azure-1.0.0-beta.9 (#2096) --- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 9a62044dde..1ee8315ba3 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.9 + +Released 2024-Sep-24 + * Added support for [Azure Container Apps jobs](https://learn.microsoft.com/en-us/azure/container-apps/jobs?tabs=azure-cli). ([#2064](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2064)) From 3dc3d782585f730b59d67bef804be8d9c62f7a6e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 24 Sep 2024 12:31:12 -0500 Subject: [PATCH 1269/1499] [release] Prepare release Extensions.AWS-1.3.0-beta.2 (#2099) --- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 0d049f8f79..93b92a0d21 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.3.0-beta.2 + +Released 2024-Sep-24 + * Remove NuGet reference to `System.Net.Http` ([#1713](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1713)) From 55c0dfbc759f0a13fa00e298c5452726b9aaac32 Mon Sep 17 00:00:00 2001 From: Stanislav Perekrestov Date: Tue, 24 Sep 2024 13:49:53 -0700 Subject: [PATCH 1270/1499] =?UTF-8?q?[Instrumentation.Process,=20Resources?= =?UTF-8?q?.Process]=20Properly=20disposes=20of=20System.Diagnostics.Proce?= =?UTF-8?q?ss=20class=20instances=20insta=E2=80=A6=20(#2101)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CHANGELOG.md | 3 +++ .../ProcessMetrics.cs | 11 +++++++---- src/OpenTelemetry.Resources.Process/CHANGELOG.md | 3 +++ .../ProcessDetector.cs | 10 ++++++++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index af3f2d3c64..d5fc9e7dba 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Properly dispose of System.Diagnostics.Process class instances + ([#2101](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2101)) + ## 0.5.0-beta.6 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index d3c9b65594..15fab0e0fa 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -24,7 +24,8 @@ static ProcessMetrics() "process.memory.usage", () => { - return Diagnostics.Process.GetCurrentProcess().WorkingSet64; + using var process = Diagnostics.Process.GetCurrentProcess(); + return process.WorkingSet64; }, unit: "By", description: "The amount of physical memory in use."); @@ -33,7 +34,8 @@ static ProcessMetrics() "process.memory.virtual", () => { - return Diagnostics.Process.GetCurrentProcess().VirtualMemorySize64; + using var process = Diagnostics.Process.GetCurrentProcess(); + return process.VirtualMemorySize64; }, unit: "By", description: "The amount of committed virtual memory."); @@ -42,7 +44,7 @@ static ProcessMetrics() "process.cpu.time", () => { - var process = Diagnostics.Process.GetCurrentProcess(); + using var process = Diagnostics.Process.GetCurrentProcess(); return new[] { new Measurement(process.UserProcessorTime.TotalSeconds, new KeyValuePair("process.cpu.state", "user")), @@ -65,7 +67,8 @@ static ProcessMetrics() "process.thread.count", () => { - return Diagnostics.Process.GetCurrentProcess().Threads.Count; + using var process = Diagnostics.Process.GetCurrentProcess(); + return process.Threads.Count; }, unit: "{thread}", description: "Process threads count."); diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index bb23a9cd56..adacf93879 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Properly dispose of System.Diagnostics.Process class instances + ([#2101](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2101)) + ## 0.1.0-beta.2 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Resources.Process/ProcessDetector.cs b/src/OpenTelemetry.Resources.Process/ProcessDetector.cs index 57dffe6425..d6a3624bae 100644 --- a/src/OpenTelemetry.Resources.Process/ProcessDetector.cs +++ b/src/OpenTelemetry.Resources.Process/ProcessDetector.cs @@ -19,9 +19,15 @@ public Resource Detect() new(ProcessSemanticConventions.AttributeProcessOwner, Environment.UserName), #if NET new(ProcessSemanticConventions.AttributeProcessPid, Environment.ProcessId), + }); #else - new(ProcessSemanticConventions.AttributeProcessPid, System.Diagnostics.Process.GetCurrentProcess().Id), -#endif + new(ProcessSemanticConventions.AttributeProcessPid, GetProcessPid()), }); + static int GetProcessPid() + { + using var process = System.Diagnostics.Process.GetCurrentProcess(); + return process.Id; + } +#endif } } From 3af32fbf5faca5d44d5398e228a747f19b0b4f89 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 24 Sep 2024 23:12:07 -0500 Subject: [PATCH 1271/1499] [release] Prepare release Resources.Process-0.1.0-beta.3 (#2104) --- src/OpenTelemetry.Resources.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index adacf93879..a218d81bf9 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-beta.3 + +Released 2024-Sep-25 + * Properly dispose of System.Diagnostics.Process class instances ([#2101](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2101)) From 6534edc72fba8dbfc6ee8b47500629c79b7b535a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 24 Sep 2024 23:13:36 -0500 Subject: [PATCH 1272/1499] [release] Prepare release Instrumentation.Process-0.5.0-beta.7 (#2105) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index d5fc9e7dba..bde93ea437 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.5.0-beta.7 + +Released 2024-Sep-25 + * Properly dispose of System.Diagnostics.Process class instances ([#2101](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2101)) From cd3f7e3a2e186995cd7a7d2eb7f4448f8ea681a2 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 25 Sep 2024 11:31:14 -0700 Subject: [PATCH 1273/1499] [geneva] Nullable annotations for MsgPackExporter folder (#2092) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../GenevaLogExporter.cs | 4 +- .../GenevaTraceExporter.cs | 4 +- .../Internal/ConnectionStringBuilder.cs | 6 +- .../MsgPack}/MessagePackSerializer.cs | 24 +++-- .../MsgPack}/MsgPackExporter.cs | 10 ++- .../MsgPack}/MsgPackLogExporter.cs | 84 +++++++++--------- .../MsgPack}/MsgPackTraceExporter.cs | 88 ++++++++++++------- .../Internal/TableNameSerializer.cs | 1 + .../Tld}/JsonSerializer.cs | 2 +- .../Tld}/TldExporter.cs | 2 +- .../Tld}/TldLogExporter.cs | 3 +- .../Tld}/TldTraceExporter.cs | 3 +- .../Tld}/UncheckedASCIIEncoding.cs | 2 +- .../Transports}/EtwDataTransport.cs | 4 +- .../Transports}/IDataTransport.cs | 4 +- .../UnixDomainSocketDataTransport.cs | 58 +++++------- .../Transports}/UnixDomainSocketEndPoint.cs | 10 ++- .../Metrics/GenevaMetricExporter.cs | 1 - .../Transport/MetricUnixDataTransport.cs | 2 + .../OpenTelemetry.Exporter.Geneva.csproj | 1 + src/Shared/NullableAttributes.cs | 20 +++++ .../Exporter/LogExporterBenchmarks.cs | 1 + .../Exporter/SerializationBenchmarks.cs | 3 +- .../Exporter/TLDLogExporterBenchmarks.cs | 3 +- .../Exporter/TLDTraceExporterBenchmarks.cs | 3 +- .../Exporter/TraceExporterBenchmarks.cs | 1 + .../Program.cs | 1 + .../ConnectionStringBuilderTests.cs | 1 + .../GenevaLogExporterTests.cs | 6 +- .../GenevaTraceExporterTests.cs | 5 +- .../JsonSerializerTests.cs | 2 +- .../LogSerializationTests.cs | 1 + .../MessagePackSerializerTests.cs | 1 + .../UnixDomainSocketDataTransportTests.cs | 1 + .../UnixDomainSocketEndPointTests.cs | 4 + 35 files changed, 219 insertions(+), 147 deletions(-) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter => Internal/MsgPack}/MessagePackSerializer.cs (98%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter => Internal/MsgPack}/MsgPackExporter.cs (89%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter => Internal/MsgPack}/MsgPackLogExporter.cs (91%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter => Internal/MsgPack}/MsgPackTraceExporter.cs (89%) rename src/OpenTelemetry.Exporter.Geneva/{TLDExporter => Internal/Tld}/JsonSerializer.cs (99%) rename src/OpenTelemetry.Exporter.Geneva/{TLDExporter => Internal/Tld}/TldExporter.cs (98%) rename src/OpenTelemetry.Exporter.Geneva/{TLDExporter => Internal/Tld}/TldLogExporter.cs (99%) rename src/OpenTelemetry.Exporter.Geneva/{TLDExporter => Internal/Tld}/TldTraceExporter.cs (99%) rename src/OpenTelemetry.Exporter.Geneva/{TLDExporter => Internal/Tld}/UncheckedASCIIEncoding.cs (99%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter/Transport => Internal/Transports}/EtwDataTransport.cs (96%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter/Transport => Internal/Transports}/IDataTransport.cs (71%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter/Transport => Internal/Transports}/UnixDomainSocketDataTransport.cs (60%) rename src/OpenTelemetry.Exporter.Geneva/{MsgPackExporter/Transport => Internal/Transports}/UnixDomainSocketEndPoint.cs (97%) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 2b7cee0379..199e46ea08 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -4,7 +4,8 @@ #nullable enable using System.Runtime.InteropServices; -using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Exporter.Geneva.MsgPack; +using OpenTelemetry.Exporter.Geneva.Tld; using OpenTelemetry.Internal; using OpenTelemetry.Logs; @@ -29,7 +30,6 @@ public class GenevaLogExporter : GenevaBaseExporter public GenevaLogExporter(GenevaExporterOptions options) { Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); bool useMsgPackExporter; var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index af3b070af9..5d472e2519 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -5,7 +5,8 @@ using System.Diagnostics; using System.Runtime.InteropServices; -using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Exporter.Geneva.MsgPack; +using OpenTelemetry.Exporter.Geneva.Tld; using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -29,7 +30,6 @@ public class GenevaTraceExporter : GenevaBaseExporter public GenevaTraceExporter(GenevaExporterOptions options) { Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); bool useMsgPackExporter; var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index f441aeeef5..fa8515ba0a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -3,7 +3,9 @@ #nullable enable +using System.Diagnostics.CodeAnalysis; using System.Globalization; +using OpenTelemetry.Exporter.Geneva.Transports; using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Geneva; @@ -20,9 +22,9 @@ internal enum TransportProtocol internal sealed class ConnectionStringBuilder { - private readonly Dictionary parts = new Dictionary(StringComparer.Ordinal); + private readonly Dictionary parts = new(StringComparer.Ordinal); - public ConnectionStringBuilder(string connectionString) + public ConnectionStringBuilder([NotNull] string? connectionString) { Guard.ThrowIfNullOrWhitespace(connectionString); diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs similarity index 98% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs index d5a97bbe75..ca0a5a4ce9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if NET using System.Buffers.Binary; #endif @@ -8,7 +10,7 @@ using System.Runtime.CompilerServices; using System.Text; -namespace OpenTelemetry.Exporter.Geneva; +namespace OpenTelemetry.Exporter.Geneva.MsgPack; internal static class MessagePackSerializer { @@ -331,7 +333,7 @@ public static void WriteStr8Header(Span buffer, int nameStartIdx, int vali } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeAsciiString(byte[] buffer, int cursor, string value) + public static int SerializeAsciiString(byte[] buffer, int cursor, string? value) { if (value == null) { @@ -401,13 +403,19 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string value) #if NET [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUnicodeString(byte[] buffer, int cursor, ReadOnlySpan value) + public static int SerializeUnicodeString(byte[] buffer, int cursor, string? value) { if (value == null) { return SerializeNull(buffer, cursor); } + return SerializeUnicodeString(buffer, cursor, value.AsSpan()); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SerializeUnicodeString(byte[] buffer, int cursor, ReadOnlySpan value) + { int start = cursor; var cch = value.Length; int cb; @@ -438,7 +446,7 @@ public static int SerializeUnicodeString(byte[] buffer, int cursor, ReadOnlySpan #else [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeUnicodeString(byte[] buffer, int cursor, string value) + public static int SerializeUnicodeString(byte[] buffer, int cursor, string? value) { if (value == null) { @@ -496,7 +504,7 @@ public static int WriteArrayHeader(byte[] buffer, int cursor, int length) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeArray(byte[] buffer, int cursor, T[] array) + public static int SerializeArray(byte[] buffer, int cursor, T[]? array) { if (array == null) { @@ -534,7 +542,7 @@ public static int WriteMapHeader(byte[] buffer, int cursor, int count) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int SerializeMap(byte[] buffer, int cursor, IDictionary map) + public static int SerializeMap(byte[] buffer, int cursor, IDictionary? map) { if (map == null) { @@ -582,7 +590,7 @@ public static int SerializeUtcDateTime(byte[] buffer, int cursor, DateTime utc) return SerializeTimestamp96(buffer, cursor, utc.Ticks); } - public static int Serialize(byte[] buffer, int cursor, object obj) + public static int Serialize(byte[] buffer, int cursor, object? obj) { if (obj == null) { @@ -636,7 +644,7 @@ public static int Serialize(byte[] buffer, int cursor, object obj) #endif default: - string repr; + string? repr; try { diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs similarity index 89% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs index 7a6ed20f52..c37581d5e3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs @@ -1,11 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if NET8_0_OR_GREATER using System.Collections.Frozen; #endif -namespace OpenTelemetry.Exporter.Geneva; +namespace OpenTelemetry.Exporter.Geneva.MsgPack; internal abstract class MsgPackExporter { @@ -37,9 +39,9 @@ internal abstract class MsgPackExporter internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = PART_A_MAPPING_DICTIONARY; #endif - protected static int AddPartAField(byte[] buffer, int cursor, string name, object value) + protected static int AddPartAField(byte[] buffer, int cursor, string name, object? value) { - if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) + if (V40_PART_A_MAPPING.TryGetValue(name, out string? replacementKey)) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); } @@ -54,7 +56,7 @@ protected static int AddPartAField(byte[] buffer, int cursor, string name, objec protected static int AddPartAField(byte[] buffer, int cursor, string name, ReadOnlySpan value) { - if (V40_PART_A_MAPPING.TryGetValue(name, out string replacementKey)) + if (V40_PART_A_MAPPING.TryGetValue(name, out string? replacementKey)) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs similarity index 91% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs index 0268662b74..6e00b6a723 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs @@ -1,17 +1,21 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if NET8_0_OR_GREATER using System.Collections.Frozen; #endif +using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.Geneva.Transports; using OpenTelemetry.Internal; using OpenTelemetry.Logs; -namespace OpenTelemetry.Exporter.Geneva; +namespace OpenTelemetry.Exporter.Geneva.MsgPack; internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable { @@ -30,15 +34,15 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private readonly TableNameSerializer tableNameSerializer; #if NET8_0_OR_GREATER - private readonly FrozenSet customFields; - private readonly FrozenDictionary prepopulatedFields; + private readonly FrozenSet? customFields; + private readonly FrozenDictionary? prepopulatedFields; #else - private readonly HashSet customFields; - private readonly Dictionary prepopulatedFields; + private readonly HashSet? customFields; + private readonly Dictionary? prepopulatedFields; #endif private readonly ExceptionStackExportMode exportExceptionStack; - private readonly List prepopulatedFieldKeys; + private readonly List? prepopulatedFieldKeys; private readonly byte[] bufferEpilogue; private readonly IDataTransport dataTransport; @@ -49,6 +53,8 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable public MsgPackLogExporter(GenevaExporterOptions options) { + Guard.ThrowIfNull(options); + this.tableNameSerializer = new(options, defaultTableName: "Log"); this.exportExceptionStack = options.ExceptionStackExportMode; @@ -122,12 +128,14 @@ public MsgPackLogExporter(GenevaExporterOptions options) public ExportResult Export(in Batch batch) { var result = ExportResult.Success; + foreach (var logRecord in batch) { try { - var cursor = this.SerializeLogRecord(logRecord); - this.dataTransport.Send(Buffer.Value, cursor - 0); + var data = this.SerializeLogRecord(logRecord); + + this.dataTransport.Send(data.Array!, data.Count); } catch (Exception ex) { @@ -153,7 +161,6 @@ public void Dispose() { (this.dataTransport as IDisposable)?.Dispose(); this.serializationData.Dispose(); - this.prepopulatedFieldKeys.Clear(); } catch (Exception ex) { @@ -163,11 +170,12 @@ public void Dispose() this.isDisposed = true; } - internal int SerializeLogRecord(LogRecord logRecord) + internal ArraySegment SerializeLogRecord(LogRecord logRecord) { // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 #pragma warning disable 0618 - IReadOnlyList> listKvp; + IReadOnlyList>? listKvp; + if (logRecord.StateValues != null) { listKvp = logRecord.StateValues; @@ -175,16 +183,11 @@ internal int SerializeLogRecord(LogRecord logRecord) else { // Attempt to see if State could be ROL_KVP. - listKvp = logRecord.State as IReadOnlyList>; + listKvp = logRecord.State as IReadOnlyList>; } #pragma warning restore 0618 - var buffer = Buffer.Value; - if (buffer == null) - { - buffer = new byte[BUFFER_SIZE]; // TODO: handle OOM - Buffer.Value = buffer; - } + var buffer = Buffer.Value ??= new byte[BUFFER_SIZE]; // TODO: handle OOM /* Fluentd Forward Mode: [ @@ -210,7 +213,7 @@ internal int SerializeLogRecord(LogRecord logRecord) var cursor = 0; cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 3); - var categoryName = logRecord.CategoryName; + var categoryName = logRecord.CategoryName ?? "Log"; cursor = this.tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, cursor, categoryName, out ReadOnlySpan eventName); @@ -226,7 +229,7 @@ internal int SerializeLogRecord(LogRecord logRecord) for (int i = 0; i < this.prepopulatedFieldKeys.Count; i++) { var key = this.prepopulatedFieldKeys[i]; - var value = this.prepopulatedFields[key]; + var value = this.prepopulatedFields![key]; cursor = AddPartAField(buffer, cursor, key, value); cntFields += 1; } @@ -347,16 +350,7 @@ internal int SerializeLogRecord(LogRecord logRecord) } // Prepare state for scopes - var dataForScopes = this.serializationData.Value; - if (dataForScopes == null) - { - dataForScopes = new SerializationDataForScopes - { - Buffer = buffer, - }; - - this.serializationData.Value = dataForScopes; - } + var dataForScopes = this.serializationData.Value ??= new(buffer); dataForScopes.Cursor = cursor; dataForScopes.FieldsCount = cntFields; @@ -377,10 +371,10 @@ internal int SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); int idxMapSizeEnvPropertiesPatch = cursor - 2; - for (int i = 0; i < listKvp.Count; i++) + for (int i = 0; i < listKvp!.Count; i++) { var entry = listKvp[i]; - if (entry.Key == "{OriginalFormat}" || this.customFields.Contains(entry.Key)) + if (entry.Key == "{OriginalFormat}" || this.customFields!.Contains(entry.Key)) { continue; } @@ -443,7 +437,7 @@ internal int SerializeLogRecord(LogRecord logRecord) MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); System.Buffer.BlockCopy(this.bufferEpilogue, 0, buffer, cursor, this.bufferEpilogue.Length); cursor += this.bufferEpilogue.Length; - return cursor; + return new(buffer, 0, cursor); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -478,10 +472,12 @@ private static byte GetSeverityNumber(LogLevel logLevel) private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, MsgPackLogExporter state) { - var stateData = state.serializationData.Value; + Debug.Assert(state.serializationData.Value != null, "state.serializationData.Value was null"); + + var stateData = state.serializationData.Value!; var customFields = state.customFields; - foreach (KeyValuePair scopeItem in scope) + foreach (KeyValuePair scopeItem in scope) { if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { @@ -507,17 +503,19 @@ private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, Msg private static void OnProcessScopeForEnvProperties(LogRecordScope scope, MsgPackLogExporter state) { - var stateData = state.serializationData.Value; + Debug.Assert(state.serializationData.Value != null, "state.serializationData.Value was null"); + + var stateData = state.serializationData.Value!; var customFields = state.customFields; - foreach (KeyValuePair scopeItem in scope) + foreach (KeyValuePair scopeItem in scope) { if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { continue; } - if (!customFields.Contains(scopeItem.Key)) + if (!customFields!.Contains(scopeItem.Key)) { stateData.Cursor = MessagePackSerializer.SerializeUnicodeString(stateData.Buffer, stateData.Cursor, scopeItem.Key); stateData.Cursor = MessagePackSerializer.Serialize(stateData.Buffer, stateData.Cursor, scopeItem.Value); @@ -528,11 +526,15 @@ private static void OnProcessScopeForEnvProperties(LogRecordScope scope, MsgPack private sealed class SerializationDataForScopes { + public readonly byte[] Buffer; + public int Cursor; + public ushort FieldsCount; public bool HasEnvProperties; public ushort EnvPropertiesCount; - public int Cursor; - public byte[] Buffer; - public ushort FieldsCount; + public SerializationDataForScopes(byte[] buffer) + { + this.Buffer = buffer; + } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs similarity index 89% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs index 9df8bd36ca..2778de0bfd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs @@ -1,14 +1,18 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if NET8_0_OR_GREATER using System.Collections.Frozen; #endif using System.Diagnostics; using System.Globalization; using System.Runtime.InteropServices; +using OpenTelemetry.Exporter.Geneva.Transports; +using OpenTelemetry.Internal; -namespace OpenTelemetry.Exporter.Geneva; +namespace OpenTelemetry.Exporter.Geneva.MsgPack; internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable { @@ -39,13 +43,13 @@ internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable internal readonly ThreadLocal Buffer = new(); #if NET8_0_OR_GREATER - internal readonly FrozenSet CustomFields; + internal readonly FrozenSet? CustomFields; - internal readonly FrozenSet DedicatedFields; + internal readonly FrozenSet? DedicatedFields; #else - internal readonly HashSet CustomFields; + internal readonly HashSet? CustomFields; - internal readonly HashSet DedicatedFields; + internal readonly HashSet? DedicatedFields; #endif private const int BUFFER_SIZE = 65360; // the maximum ETW payload (inclusive) @@ -64,6 +68,8 @@ internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable public MsgPackTraceExporter(GenevaExporterOptions options) { + Guard.ThrowIfNull(options); + var partAName = "Span"; if (options.TableNameMappings != null && options.TableNameMappings.TryGetValue("Span", out var customTableName)) @@ -203,12 +209,14 @@ public ExportResult Export(in Batch batch) // } var result = ExportResult.Success; + foreach (var activity in batch) { try { - var cursor = this.SerializeActivity(activity); - this.dataTransport.Send(this.Buffer.Value, cursor - 0); + var data = this.SerializeActivity(activity); + + this.dataTransport.Send(data.Array!, data.Count); } catch (Exception ex) { @@ -242,7 +250,7 @@ public void Dispose() this.isDisposed = true; } - internal int SerializeActivity(Activity activity) + internal ArraySegment SerializeActivity(Activity activity) { var buffer = this.Buffer.Value; if (buffer == null) @@ -355,27 +363,17 @@ internal int SerializeActivity(Activity activity) // i.e all PartB fields and opt-in part c fields. bool hasEnvProperties = false; bool isStatusSuccess = true; - string statusDescription = string.Empty; + string? statusDescription = null; foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision - if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string replacementKey)) + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string? replacementKey)) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); } - else if (string.Equals(entry.Key, "otel.status_code", StringComparison.Ordinal)) + else if (IfTagMatchesStatusOrStatusDescription(entry, ref isStatusSuccess, ref statusDescription)) { - if (string.Equals(Convert.ToString(entry.Value, CultureInfo.InvariantCulture), "ERROR", StringComparison.Ordinal)) - { - isStatusSuccess = false; - } - - continue; - } - else if (string.Equals(entry.Key, "otel.status_description", StringComparison.Ordinal)) - { - statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture); continue; } else if (this.CustomFields == null || this.CustomFields.Contains(entry.Key)) @@ -405,7 +403,7 @@ internal int SerializeActivity(Activity activity) foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision - if (this.DedicatedFields.Contains(entry.Key)) + if (this.DedicatedFields!.Contains(entry.Key)) { continue; } @@ -435,17 +433,15 @@ internal int SerializeActivity(Activity activity) cntFields += 1; } } - else + else if (!isStatusSuccess) { - if (!isStatusSuccess) + MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); + + if (!string.IsNullOrEmpty(statusDescription)) { - MessagePackSerializer.SerializeBool(buffer, idxSuccessPatch, false); - if (!string.IsNullOrEmpty(statusDescription)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "statusMessage"); - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, statusDescription); - cntFields += 1; - } + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "statusMessage"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, statusDescription); + cntFields += 1; } } #endregion @@ -455,6 +451,34 @@ internal int SerializeActivity(Activity activity) System.Buffer.BlockCopy(this.bufferEpilogue, 0, buffer, cursor, this.bufferEpilogue.Length); cursor += this.bufferEpilogue.Length; - return cursor; + return new(buffer, 0, cursor); + } + + private static bool IfTagMatchesStatusOrStatusDescription( + KeyValuePair entry, + ref bool isStatusSuccess, + ref string? statusDescription) + { + if (entry.Key.StartsWith("otel.status_", StringComparison.Ordinal)) + { + var keyPart = entry.Key.AsSpan().Slice(12); + if (keyPart is "code") + { + if (string.Equals(Convert.ToString(entry.Value, CultureInfo.InvariantCulture), "ERROR", StringComparison.Ordinal)) + { + isStatusSuccess = false; + } + + return true; + } + + if (keyPart is "description") + { + statusDescription = Convert.ToString(entry.Value, CultureInfo.InvariantCulture) ?? string.Empty; + return true; + } + } + + return false; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index c9de7b1a47..15282d29ae 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using System.Text; +using OpenTelemetry.Exporter.Geneva.MsgPack; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs similarity index 99% rename from src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs index 57ccdbfcd3..8249dc0b50 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs @@ -7,7 +7,7 @@ using System.Runtime.CompilerServices; using System.Text; -namespace OpenTelemetry.Exporter.Geneva.TldExporter; +namespace OpenTelemetry.Exporter.Geneva.Tld; internal static class JsonSerializer { diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs similarity index 98% rename from src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs index 92b7ed47a0..9c3712a94c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs @@ -9,7 +9,7 @@ using System.Text; using OpenTelemetry.Exporter.Geneva.External; -namespace OpenTelemetry.Exporter.Geneva.TldExporter; +namespace OpenTelemetry.Exporter.Geneva.Tld; internal abstract class TldExporter { diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs similarity index 99% rename from src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs index b14a1f3f6a..96e7062a11 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs @@ -12,7 +12,7 @@ using OpenTelemetry.Internal; using OpenTelemetry.Logs; -namespace OpenTelemetry.Exporter.Geneva.TldExporter; +namespace OpenTelemetry.Exporter.Geneva.Tld; internal sealed class TldLogExporter : TldExporter, IDisposable { @@ -43,7 +43,6 @@ internal sealed class TldLogExporter : TldExporter, IDisposable public TldLogExporter(GenevaExporterOptions options) { Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); this.eventProvider = new EventProvider(connectionStringBuilder.EtwSession); diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs similarity index 99% rename from src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs index 33fdefecdd..062e97c875 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs @@ -9,7 +9,7 @@ using OpenTelemetry.Exporter.Geneva.External; using OpenTelemetry.Internal; -namespace OpenTelemetry.Exporter.Geneva.TldExporter; +namespace OpenTelemetry.Exporter.Geneva.Tld; internal sealed class TldTraceExporter : TldExporter, IDisposable { @@ -50,7 +50,6 @@ internal sealed class TldTraceExporter : TldExporter, IDisposable public TldTraceExporter(GenevaExporterOptions options) { Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); this.eventProvider = new EventProvider(connectionStringBuilder.EtwSession); diff --git a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs similarity index 99% rename from src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs index a27c983040..aed31bd1b1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/TLDExporter/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs @@ -6,7 +6,7 @@ using System.Text; using OpenTelemetry.Internal; -namespace OpenTelemetry.Exporter.Geneva.TldExporter; +namespace OpenTelemetry.Exporter.Geneva.Tld; /// /// Like ASCIIEncoding but instead of checking for non-ASCII characters, it just diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs similarity index 96% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs index bd61474887..d25d88fcf3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs @@ -1,12 +1,14 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if NET using System.Diagnostics.CodeAnalysis; #endif using System.Diagnostics.Tracing; -namespace OpenTelemetry.Exporter.Geneva; +namespace OpenTelemetry.Exporter.Geneva.Transports; internal sealed class EtwDataTransport : IDataTransport, IDisposable { diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/IDataTransport.cs similarity index 71% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Transports/IDataTransport.cs index 9641ee757d..36746697ee 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/IDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/IDataTransport.cs @@ -1,7 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -namespace OpenTelemetry.Exporter.Geneva; +#nullable enable + +namespace OpenTelemetry.Exporter.Geneva.Transports; internal interface IDataTransport { diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs similarity index 60% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs index c7424a1023..741daa7516 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs @@ -1,17 +1,20 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Sockets; -namespace OpenTelemetry.Exporter.Geneva; +namespace OpenTelemetry.Exporter.Geneva.Transports; internal sealed class UnixDomainSocketDataTransport : IDataTransport, IDisposable { public const int DefaultTimeoutMilliseconds = 15000; private readonly EndPoint unixEndpoint; + private readonly int timeoutMilliseconds; private Socket socket; - private int timeoutMilliseconds; /// /// Initializes a new instance of the class. @@ -29,14 +32,8 @@ public UnixDomainSocketDataTransport( { this.unixEndpoint = new UnixDomainSocketEndPoint(unixDomainSocketPath); this.timeoutMilliseconds = timeoutMilliseconds; - try - { - this.Connect(); - } - catch (Exception ex) - { - ExporterEventSource.Log.ExporterException("UDS unavailable at startup.", ex); - } + + this.Connect(); } public bool IsEnabled() @@ -46,21 +43,13 @@ public bool IsEnabled() public void Send(byte[] data, int size) { - try + if (!this.socket.Connected + && !this.Reconnect()) { - if (!this.socket.Connected) - { - // Socket connection is off! Server might have stopped. Trying to reconnect. - this.Reconnect(); - } - - this.socket.Send(data, size, SocketFlags.None); - } - catch (Exception) - { - // Re-throw the exception so that Export method catches it and sets the ExportResult correctly. - throw; + throw new InvalidOperationException("UDS not connected."); } + + this.socket.Send(data, size, SocketFlags.None); } public void Dispose() @@ -68,30 +57,31 @@ public void Dispose() this.socket.Dispose(); } - private void Connect() + [MemberNotNull(nameof(socket))] + private bool Connect() { + this.socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) + { + SendTimeout = this.timeoutMilliseconds, + }; + try { - this.socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) - { - SendTimeout = this.timeoutMilliseconds, - }; this.socket.Connect(this.unixEndpoint); + + return true; } catch (Exception ex) { ExporterEventSource.Log.ExporterException("UDS Connect failed.", ex); - // Re-throw the exception to - // 1. fail fast in Geneva exporter contructor, or - // 2. fail in the Reconnect attempt. - throw; + return false; } } - private void Reconnect() + private bool Reconnect() { this.socket.Close(); - this.Connect(); + return this.Connect(); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs similarity index 97% rename from src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs rename to src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs index 97d384fc75..62f87ce1f1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/MsgPackExporter/Transport/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs @@ -1,12 +1,14 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Net; -using System.Net.Sockets; +#if !NET + +#nullable enable + using System.Text; using OpenTelemetry.Internal; -namespace OpenTelemetry.Exporter.Geneva; +namespace System.Net.Sockets; internal sealed class UnixDomainSocketEndPoint : EndPoint { @@ -78,3 +80,5 @@ public override SocketAddress Serialize() public override string ToString() => this.path; } + +#endif diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index d769946906..253fbd9a63 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -44,7 +44,6 @@ public partial class GenevaMetricExporter : BaseExporter public GenevaMetricExporter(GenevaMetricExporterOptions options) { Guard.ThrowIfNull(options); - Guard.ThrowIfNullOrWhitespace(options.ConnectionString); var connectionStringBuilder = new ConnectionStringBuilder(options.ConnectionString); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs index 799e8bf7d2..c30fa6e401 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using OpenTelemetry.Exporter.Geneva.Transports; + namespace OpenTelemetry.Exporter.Geneva; internal sealed class MetricUnixDataTransport : IMetricDataTransport diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 080a106fbd..4605cafce6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -23,6 +23,7 @@ + diff --git a/src/Shared/NullableAttributes.cs b/src/Shared/NullableAttributes.cs index c471bbe613..21607db302 100644 --- a/src/Shared/NullableAttributes.cs +++ b/src/Shared/NullableAttributes.cs @@ -34,5 +34,25 @@ internal sealed class NotNullWhenAttribute : Attribute /// Gets the return value condition. public bool ReturnValue { get; } } + + /// Specifies that the method or property will ensure that the listed field and property members have not-null values. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + internal sealed class MemberNotNullAttribute : Attribute + { + /// Initializes the attribute with a field or property member. + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullAttribute(string member) => Members = new[] { member }; + + /// Initializes the attribute with the list of field and property members. + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullAttribute(params string[] members) => Members = members; + + /// Gets field or property member names. + public string[] Members { get; } + } } #endif diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs index 94afeadecd..afc45c8cdd 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs @@ -3,6 +3,7 @@ using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Logs; /* diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs index 8247f250f0..24272abd96 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs @@ -4,7 +4,8 @@ using System.Text; using BenchmarkDotNet.Attributes; using OpenTelemetry.Exporter.Geneva.External; -using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Exporter.Geneva.MsgPack; +using OpenTelemetry.Exporter.Geneva.Tld; /* BenchmarkDotNet v0.13.10, Windows 11 (10.0.23424.1000) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs index 2dea0ec1b3..8e52bc5f8b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs @@ -3,7 +3,8 @@ using BenchmarkDotNet.Attributes; using Microsoft.Extensions.Logging; -using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Exporter.Geneva.MsgPack; +using OpenTelemetry.Exporter.Geneva.Tld; using OpenTelemetry.Logs; using OpenTelemetry.Trace; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs index 7c439eb22f..2175a2a250 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs @@ -3,7 +3,8 @@ using System.Diagnostics; using BenchmarkDotNet.Attributes; -using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Exporter.Geneva.MsgPack; +using OpenTelemetry.Exporter.Geneva.Tld; using OpenTelemetry.Trace; /* diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs index db6f3afa3d..223cbd111c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using BenchmarkDotNet.Attributes; +using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Trace; /* diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index 1e84290389..1a6c97297d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -5,6 +5,7 @@ using System.Globalization; using System.Runtime.CompilerServices; using CommandLine; +using OpenTelemetry.Exporter.Geneva.Transports; using OpenTelemetry.Trace; namespace OpenTelemetry.Exporter.Geneva.Stress; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs index d0f34b5b68..751b5e412a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/ConnectionStringBuilderTests.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using OpenTelemetry.Exporter.Geneva.Transports; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 33c27baae0..2d2c810fd2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Logs; using Xunit; @@ -859,8 +860,7 @@ public void SuccessfulExportOnLinux() // logRecordList should have a singleLogRecord entry after the logger.LogInformation call Assert.Single(logRecordList); - int messagePackDataSize; - messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + int messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; // Read the data sent via socket. var receivedData = new byte[1024]; @@ -882,7 +882,7 @@ public void SuccessfulExportOnLinux() // logRecordList should have a singleLogRecord entry after the logger.LogInformation call Assert.Single(logRecordList); - messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]); + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; receivedDataSize = serverSocket.Receive(receivedData); Assert.Equal(messagePackDataSize, receivedDataSize); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 6e2b6c5ddc..e91078de79 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Trace; using Xunit; @@ -435,7 +436,7 @@ public void GenevaTraceExporter_Success_Linux() using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) { - messagePackDataSize = exporter.SerializeActivity(activity); + messagePackDataSize = exporter.SerializeActivity(activity).Count; } // Read the data sent via socket. @@ -450,7 +451,7 @@ public void GenevaTraceExporter_Success_Linux() { using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) { - messagePackDataSize = exporter.SerializeActivity(activity); + messagePackDataSize = exporter.SerializeActivity(activity).Count; } }); thread.Start(); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs index 527b2c2c94..c49a58b40c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Text; -using OpenTelemetry.Exporter.Geneva.TldExporter; +using OpenTelemetry.Exporter.Geneva.Tld; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index ac90603019..75b3bb94f1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -4,6 +4,7 @@ using System.Net.Sockets; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Logs; using Xunit; using Xunit.Abstractions; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 93593abfd8..ae55fea742 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -3,6 +3,7 @@ using System.Globalization; using System.Text; +using OpenTelemetry.Exporter.Geneva.MsgPack; using Xunit; using Xunit.Sdk; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index d559c6e65b..fa879d1ed2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -4,6 +4,7 @@ using System.Net.Sockets; using System.Reflection; using System.Runtime.InteropServices; +using OpenTelemetry.Exporter.Geneva.Transports; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index ebb764ce4d..d0d922ca2b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if !NET + using System.Net; using System.Net.Sockets; using System.Text; @@ -67,3 +69,5 @@ private SocketAddress CreateSocketAddress(string path) return sa; } } + +#endif From c74c2acea312dc1d61d7ed33ae3b14a6347edd9f Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 25 Sep 2024 13:27:00 -0700 Subject: [PATCH 1274/1499] [repo] Add Mothra as triager (#2107) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9dd41b0f85..69a0768a40 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ component's `Readme.md` file. [@open-telemetry/dotnet-contrib-triagers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-triagers): * [Martin Thwaites](https://github.com/martinjt), Honeycomb +* [Timothy "Mothra" Lee](https://github.com/TimothyMothra), Microsoft *Find more about the triager role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager).* From 9c9fed6407f32f88e0ed70cac25efce8a704df12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 26 Sep 2024 05:45:30 +0200 Subject: [PATCH 1275/1499] [docs] README - Fix links to membership descriptions (#2109) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 69a0768a40..a9ce137154 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ component's `Readme.md` file. * [Timothy "Mothra" Lee](https://github.com/TimothyMothra), Microsoft *Find more about the triager role in [community -repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#triager).* +repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#triager).* ### Approvers @@ -83,7 +83,7 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb There are no approvers today. *Find more about the approver role in [community -repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).* +repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#approver).* ### Maintainers @@ -95,11 +95,11 @@ repository](https://github.com/open-telemetry/community/blob/main/community-memb * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk *Find more about the maintainer role in [community -repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer).* +repository](h[ttps://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer)).* ### Emeritus -[Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): +[Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager): * [Prashant Srivastava](https://github.com/srprash) * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) From 10502338b957236d738562a211506c708e55ac14 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 27 Sep 2024 15:39:47 +0000 Subject: [PATCH 1276/1499] [examples] Centralize TFMs for easier management (#2111) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- build/Common.nonprod.props | 4 ++++ .../Examples.InfluxDB/Examples.InfluxDB.csproj | 2 +- .../Examples.Enrichment/Examples.Enrichment.csproj | 2 +- .../Examples.EventCounters.csproj | 2 +- .../Examples.GrpcCore.AspNetCore.csproj | 10 +++++----- examples/kafka/Examples.ConfluentKafka.csproj | 6 +++++- examples/owin/Examples.Owin.csproj | 2 +- .../process-instrumentation.csproj | 5 ++++- .../Examples.StackExchangeRedis.csproj | 2 +- .../runtime-instrumentation.csproj | 5 ++++- .../wcf/client-core/Examples.Wcf.Client.DotNet.csproj | 2 +- .../Examples.Wcf.Client.NetFramework.csproj | 5 +---- .../Examples.Wcf.Server.AspNetFramework.csproj | 2 +- .../Examples.Wcf.Server.NetFramework.csproj | 5 +---- examples/wcf/shared/Examples.Wcf.Shared.csproj | 3 +-- 15 files changed, 32 insertions(+), 25 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 29cd1456ea..1b7ed15854 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -11,6 +11,10 @@ + + net8.0 + + true diff --git a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj index c39d5ecdbe..d21749c659 100644 --- a/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj +++ b/examples/InfluxDB/Examples.InfluxDB/Examples.InfluxDB.csproj @@ -1,8 +1,8 @@ + $(DefaultTargetFrameworkForExampleApps) Exe - net8.0 Examples.InfluxDB diff --git a/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj b/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj index b3b1885099..735516af62 100644 --- a/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj +++ b/examples/enrichment/Examples.Enrichment/Examples.Enrichment.csproj @@ -1,8 +1,8 @@ + $(DefaultTargetFrameworkForExampleApps) Exe - net6.0 diff --git a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj index 757050d67f..78eb2b9eda 100644 --- a/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj +++ b/examples/event-counters/Examples.EventCounters/Examples.EventCounters.csproj @@ -1,8 +1,8 @@ + $(DefaultTargetFrameworkForExampleApps) Exe - net6.0 diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 101df6a51d..6f60b4f98d 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -1,21 +1,21 @@ - net6.0 + $(DefaultTargetFrameworkForExampleApps) - - - - + + + + diff --git a/examples/kafka/Examples.ConfluentKafka.csproj b/examples/kafka/Examples.ConfluentKafka.csproj index 2c66343e81..c10dbfcb21 100644 --- a/examples/kafka/Examples.ConfluentKafka.csproj +++ b/examples/kafka/Examples.ConfluentKafka.csproj @@ -1,11 +1,14 @@ + + $(DefaultTargetFrameworkForExampleApps) Exe - net8.0 + + @@ -14,4 +17,5 @@ + diff --git a/examples/owin/Examples.Owin.csproj b/examples/owin/Examples.Owin.csproj index 086edcc3e4..b1f1da9a0f 100644 --- a/examples/owin/Examples.Owin.csproj +++ b/examples/owin/Examples.Owin.csproj @@ -1,8 +1,8 @@ + $(NetFrameworkMinimumSupportedVersion) Exe - net462 diff --git a/examples/process-instrumentation/process-instrumentation.csproj b/examples/process-instrumentation/process-instrumentation.csproj index 6d248c26ec..1e45f4bf86 100644 --- a/examples/process-instrumentation/process-instrumentation.csproj +++ b/examples/process-instrumentation/process-instrumentation.csproj @@ -1,10 +1,13 @@ + + $(DefaultTargetFrameworkForExampleApps) Exe - net6.0 + + diff --git a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj index fec889477d..6687d84436 100644 --- a/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj +++ b/examples/redis/Examples.StackExchangeRedis/Examples.StackExchangeRedis.csproj @@ -1,8 +1,8 @@ + $(DefaultTargetFrameworkForExampleApps) Exe - net8.0 diff --git a/examples/runtime-instrumentation/runtime-instrumentation.csproj b/examples/runtime-instrumentation/runtime-instrumentation.csproj index 2531b68d58..40c7117f90 100644 --- a/examples/runtime-instrumentation/runtime-instrumentation.csproj +++ b/examples/runtime-instrumentation/runtime-instrumentation.csproj @@ -1,10 +1,13 @@ + - net6.0 + $(DefaultTargetFrameworkForExampleApps) Exe + + diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index 38ac618f6a..ac31365665 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -1,8 +1,8 @@ + $(DefaultTargetFrameworkForExampleApps) Exe - net8.0 diff --git a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj index cdf07abc4b..25cd5c57b3 100644 --- a/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj +++ b/examples/wcf/client-netframework/Examples.Wcf.Client.NetFramework.csproj @@ -1,8 +1,8 @@ + $(NetFrameworkMinimumSupportedVersion) Exe - net462 @@ -11,9 +11,6 @@ - - - diff --git a/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj b/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj index c4efc4eceb..836974962c 100644 --- a/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj +++ b/examples/wcf/server-aspnetframework/Examples.Wcf.Server.AspNetFramework.csproj @@ -1,7 +1,7 @@ - net462 + $(NetFrameworkMinimumSupportedVersion) Library bin\ false diff --git a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj index 2e846ea19e..2ad352a183 100644 --- a/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj +++ b/examples/wcf/server-netframework/Examples.Wcf.Server.NetFramework.csproj @@ -1,8 +1,8 @@ + $(NetFrameworkMinimumSupportedVersion) Exe - net462 @@ -11,9 +11,6 @@ - - - diff --git a/examples/wcf/shared/Examples.Wcf.Shared.csproj b/examples/wcf/shared/Examples.Wcf.Shared.csproj index bcef073cb9..3353fb70ab 100644 --- a/examples/wcf/shared/Examples.Wcf.Shared.csproj +++ b/examples/wcf/shared/Examples.Wcf.Shared.csproj @@ -1,8 +1,7 @@ - - net8.0;net462 + $(DefaultTargetFrameworkForExampleApps);$(NetFrameworkMinimumSupportedVersion) From 68a25e8a0344e231e3740914610ad122f97d3cfc Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 30 Sep 2024 09:17:09 -0700 Subject: [PATCH 1277/1499] [geneva] Vendor code for writing tracepoints on Linux (#2114) --- .editorconfig | 3 + .../External/.editorconfig | 2 + .../LinuxTracepoints-Net/.editorconfig | 6 + .../Provider/DataSegment.cs | 24 + .../Provider/PerfTracepoint.cs | 411 ++++++++++++ .../Provider/RawFileHandle.cs | 165 +++++ .../Provider/TracepointHandle.cs | 631 ++++++++++++++++++ .../LinuxTracepoints-Net/Provider/Utility.cs | 41 ++ .../External/LinuxTracepoints-Net/README.md | 17 + .../LinuxTracepoints-Net/Types/EventHeader.cs | 302 +++++++++ .../Types/EventHeaderExtension.cs | 46 ++ .../Types/EventHeaderExtensionKind.cs | 117 ++++ .../Types/EventHeaderFieldEncoding.cs | 269 ++++++++ .../Types/EventHeaderFieldFormat.cs | 168 +++++ .../Types/EventHeaderFlags.cs | 36 + .../External/TraceLoggingDynamic.cs | 2 - .../OpenTelemetry.Exporter.Geneva.csproj | 6 + .../THIRD-PARTY-NOTICES.TXT | 30 + 18 files changed, 2274 insertions(+), 2 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/.editorconfig create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/.editorconfig create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/DataSegment.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/PerfTracepoint.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/RawFileHandle.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/TracepointHandle.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/Utility.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/README.md create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeader.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtension.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtensionKind.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldEncoding.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldFormat.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFlags.cs create mode 100644 src/OpenTelemetry.Exporter.Geneva/THIRD-PARTY-NOTICES.TXT diff --git a/.editorconfig b/.editorconfig index cdfa4e3246..3b4f1d86da 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,7 @@ # To learn more about .editorconfig see https://aka.ms/editorconfigdocs + +root = true + ############################### # Core EditorConfig Options # ############################### diff --git a/src/OpenTelemetry.Exporter.Geneva/External/.editorconfig b/src/OpenTelemetry.Exporter.Geneva/External/.editorconfig new file mode 100644 index 0000000000..c895abfaeb --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/.editorconfig @@ -0,0 +1,2 @@ +[*.cs] +generated_code = true diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/.editorconfig b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/.editorconfig new file mode 100644 index 0000000000..e0875140a8 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/.editorconfig @@ -0,0 +1,6 @@ +[*.cs] +# Use DefaultDllImportSearchPaths attribute for P/Invokes +dotnet_diagnostic.CA5392.severity = none + +# The ref modifier for argument corresponding to in parameter is equivalent to in. Consider using in instead. +dotnet_diagnostic.CS9191.severity = none diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/DataSegment.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/DataSegment.cs new file mode 100644 index 0000000000..7ff5ce81a6 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/DataSegment.cs @@ -0,0 +1,24 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints.Provider; + +using System.Runtime.InteropServices; + +/// +/// struct iovec, for use with calls to writev. +/// +[StructLayout(LayoutKind.Sequential)] +internal unsafe struct DataSegment +{ + public void* PinnedBase; + public nuint Length; + + public DataSegment(void* pinnedBase, nuint length) + { + this.PinnedBase = pinnedBase; + this.Length = length; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/PerfTracepoint.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/PerfTracepoint.cs new file mode 100644 index 0000000000..c352eed671 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/PerfTracepoint.cs @@ -0,0 +1,411 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints.Provider; + +using System; + +/// +/// Flags used when registering a user_events tracepoint. +/// From LINUX/include/uapi/linux/user_events.h enum user_reg_flag. +/// +[Flags] +internal enum PerfUserEventReg : UInt16 +{ + /// + /// No flags set (default). + /// + None, + + /// + /// USER_EVENT_REG_PERSIST: + /// Event will not delete upon last reference closing. + /// + Persist = 1 << 0, + + /// + /// USER_EVENT_REG_MULTI_FORMAT: + /// Event will be allowed to have multiple formats. + /// + MultiFormat = 1 << 1, +} + +/// +/// Direct access to a user_events tracepoint -- caller is responsible for the registration +/// string and for packing/marshalling event data. +///
    +/// For more information, see user_events. +///
    +/// The tracepoint is registered by the constructor. +/// You'll generally construct all of your application's Tracepoint objects at application +/// start or component initialization. +///
    +/// You'll use the IsEnabled property to determine +/// whether any sessions are collecting the tracecpoint, and you'll use the Write method +/// to write events. +///
    +/// Normal usage: +/// +/// Tracepoint tp = new PerfTracepoint("MyEventName int MyField1; int MyField2"); +/// +/// // To log an event where preparing the data is very simple: +/// tp.Write(data...); +/// +/// // To log an event where preparing the data is expensive: +/// if (tp.IsEnabled) // Skip preparing data and calling Write if the tracepoint is not enabled. +/// { +/// var data = ...; // Prepare data that needs to be logged. +/// tp.Write(data...); +/// } +/// +/// Note that tracepoint registration can fail, and Write operations can also fail. +/// The RegisterResult property and the error code returned by the Write method are provided +/// for debugging and diagnostics, but you'll usually ignore these in normal operation (most +/// applications should continue to work even if tracing isn't working). +///
    +internal class PerfTracepoint : IDisposable +{ + private readonly TracepointHandle handle; + + /// + /// As a performance optimization, avoid one level of indirection during calls to IsEnabled + /// by caching the enablement array. The array always has Length == 1. The contents of this + /// array should be considered read-only and MUST NOT be modified (the array data is updated + /// by the Linux kernel when the tracepoint is enabled or disabled). + ///
    + /// When handle.IsInvalid, one array is shared by all invalid handles and is a normal allocation. + /// When !handle.IsInvalid, the array is unique for for each handle and is a pinned allocation. + ///
    + private readonly Int32[] enablementArray; + + /// + /// Given a user_events command string, attempts to register a user_events tracepoint. + ///
    + /// If registration succeeds, the new tracepoint will be valid and active: + /// IsEnabled is dynamic, RegisterResult == 0, Write sends data to the kernel. + ///
    + /// If registration fails, the new tracepoint will be invalid and inactive: + /// IsEnabled == false, RegisterResult != 0, Write does nothing and immediately returns EBADF. + ///
    + /// + /// user_events command string, + /// e.g. "MyEventName int arg1; u32 arg2". String should use only Latin-1 characters (each + /// char in the string should have value 255 or below). + /// + /// + /// user_reg flags, + /// e.g. USER_EVENT_REG_PERSIST or USER_EVENT_REG_MULTI_FORMAT. + /// + public PerfTracepoint(ReadOnlySpan nameArgs, PerfUserEventReg flags = 0) + { + var h = TracepointHandle.Register(nameArgs, flags); + this.handle = h; + this.enablementArray = h.DangerousGetEnablementArray(); + } + + /// + /// Given a NUL-terminated Latin1-encoded user_events command string, attempts to + /// register a user_events tracepoint. + ///
    + /// If registration succeeds, the new tracepoint will be valid and active: + /// IsEnabled is dynamic, RegisterResult == 0, Write sends data to the kernel. + ///
    + /// If registration fails, the new tracepoint will be invalid and inactive: + /// IsEnabled == false, RegisterResult != 0, Write does nothing and immediately returns EBADF. + ///
    + /// + /// user_events command string, + /// Latin-1 encoded, NUL-terminated, e.g. "MyEventName int arg1; u32 arg2\0". + /// + /// + /// user_reg flags, + /// e.g. USER_EVENT_REG_PERSIST or USER_EVENT_REG_MULTI_FORMAT. + /// + /// + /// nulTerminatedNameArgs does not contain any NUL termination (no 0 bytes). + /// + public PerfTracepoint(ReadOnlySpan nulTerminatedNameArgs, PerfUserEventReg flags = 0) + { + if (0 > nulTerminatedNameArgs.LastIndexOf((byte)0)) + { + throw new ArgumentException( + nameof(nulTerminatedNameArgs) + " must be NUL-terminated, i.e. must contain (byte)0.", + nameof(nulTerminatedNameArgs)); + } + + var h = TracepointHandle.Register(nulTerminatedNameArgs, flags); + this.handle = h; + this.enablementArray = h.DangerousGetEnablementArray(); + } + + /// + /// Returns true if this tracepoint is registered and one or more tracepoint collection sessions + /// are collecting this tracepoint. + ///
    + /// Returns false if this tracepoint is unregistered or if there are no tracepoint collection + /// sessions that are collecting this tracepoint. The tracepoint will be unregistered if + /// registration failed or if the tracepoint has been disposed. + ///
    + /// Note that this property is provided to support performance optimization, but use of this + /// property is optional. It's ok to call Write even if IsEnabled returns false. If your + /// tracepoint is not being collected, the Write method will do nothing and will immediately + /// return EBADF. This property is provided so that you can efficiently skip preparing your data + /// and calling the Write method if your tracepoint is not being collected. + ///
    + public bool IsEnabled => this.enablementArray[0] != 0; + + /// + /// If tracepoint registration succeeded, returns 0. + /// Otherwise, returns an errno indicating the error. + ///
    + /// This property is for diagnostic purposes and should usually be ignored for normal + /// operation -- most programs should continue to operate even if trace registration + /// fails. + ///
    + public int RegisterResult => this.handle.RegisterResult; + + /// + /// Unregisters the tracepoint. After calling Dispose(), IsEnabled will return false and + /// Write will do nothing and immediately return EBADF. + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// If !IsEnabled, immediately returns EBADF. + /// Otherwise, writes an event with no data. + /// + /// + /// 0 if event was written, errno otherwise. + /// Typically returns EBADF if no data collection sessions are listening for the tracepoint. + /// The return value is for debugging/diagnostic purposes and is usually ignored in normal operation + /// since most programs should continue to function even when tracing is not configured. + /// + public int Write() + { + if (this.enablementArray[0] == 0) + { + return TracepointHandle.DisabledEventError; + } + + return this.handle.Write(stackalloc DataSegment[] { + default, // segment[0] is used for headers. + }); + } + + /// + /// If !IsEnabled, immediately returns EBADF. + /// Otherwise, writes an event with 1 chunk of data. + /// + /// + /// 0 if event was written, errno otherwise. + /// Typically returns EBADF if no data collection sessions are listening for the tracepoint. + /// The return value is for debugging/diagnostic purposes and is usually ignored in normal operation + /// since most programs should continue to function even when tracing is not configured. + /// + public int Write( + ReadOnlySpan v1) + where T1 : unmanaged + { + if (this.enablementArray[0] == 0) + { + return TracepointHandle.DisabledEventError; + } + + unsafe + { + fixed (void* + p1 = v1) + { + return this.handle.Write(stackalloc DataSegment[] { + default, // segment[0] is used for headers. + new DataSegment(p1, (uint)v1.Length * (uint)sizeof(T1)), + }); + } + } + } + + /// + /// If !IsEnabled, immediately returns EBADF. + /// Otherwise, writes an event with 2 chunks of data. + /// + /// + /// 0 if event was written, errno otherwise. + /// Typically returns EBADF if no data collection sessions are listening for the tracepoint. + /// The return value is for debugging/diagnostic purposes and is usually ignored in normal operation + /// since most programs should continue to function even when tracing is not configured. + /// + public int Write( + ReadOnlySpan v1, + ReadOnlySpan v2) + where T1 : unmanaged + where T2 : unmanaged + { + if (this.enablementArray[0] == 0) + { + return TracepointHandle.DisabledEventError; + } + + unsafe + { + fixed (void* + p1 = v1, + p2 = v2) + { + return this.handle.Write(stackalloc DataSegment[] { + default, // segment[0] is used for headers. + new DataSegment(p1, (uint)v1.Length * (uint)sizeof(T1)), + new DataSegment(p2, (uint)v2.Length * (uint)sizeof(T2)), + }); + } + } + } + + /// + /// If !IsEnabled, immediately returns EBADF. + /// Otherwise, writes an event with 3 chunks of data. + /// + /// + /// 0 if event was written, errno otherwise. + /// Typically returns EBADF if no data collection sessions are listening for the tracepoint. + /// The return value is for debugging/diagnostic purposes and is usually ignored in normal operation + /// since most programs should continue to function even when tracing is not configured. + /// + public int Write( + ReadOnlySpan v1, + ReadOnlySpan v2, + ReadOnlySpan v3) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + { + if (this.enablementArray[0] == 0) + { + return TracepointHandle.DisabledEventError; + } + + unsafe + { + fixed (void* + p1 = v1, + p2 = v2, + p3 = v3) + { + return this.handle.Write(stackalloc DataSegment[] { + default, // segment[0] is used for headers. + new DataSegment(p1, (uint)v1.Length * (uint)sizeof(T1)), + new DataSegment(p2, (uint)v2.Length * (uint)sizeof(T2)), + new DataSegment(p3, (uint)v3.Length * (uint)sizeof(T3)), + }); + } + } + } + + /// + /// If !IsEnabled, immediately returns EBADF. + /// Otherwise, writes an event with 4 chunks of data. + /// + /// + /// 0 if event was written, errno otherwise. + /// Typically returns EBADF if no data collection sessions are listening for the tracepoint. + /// The return value is for debugging/diagnostic purposes and is usually ignored in normal operation + /// since most programs should continue to function even when tracing is not configured. + /// + public int Write( + ReadOnlySpan v1, + ReadOnlySpan v2, + ReadOnlySpan v3, + ReadOnlySpan v4) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + { + if (this.enablementArray[0] == 0) + { + return TracepointHandle.DisabledEventError; + } + + unsafe + { + fixed (void* + p1 = v1, + p2 = v2, + p3 = v3, + p4 = v4) + { + return this.handle.Write(stackalloc DataSegment[] { + default, // segment[0] is used for headers. + new DataSegment(p1, (uint)v1.Length * (uint)sizeof(T1)), + new DataSegment(p2, (uint)v2.Length * (uint)sizeof(T2)), + new DataSegment(p3, (uint)v3.Length * (uint)sizeof(T3)), + new DataSegment(p4, (uint)v4.Length * (uint)sizeof(T4)), + }); + } + } + } + + /// + /// If !IsEnabled, immediately returns EBADF. + /// Otherwise, writes an event with 5 chunks of data. + /// + /// + /// 0 if event was written, errno otherwise. + /// Typically returns EBADF if no data collection sessions are listening for the tracepoint. + /// The return value is for debugging/diagnostic purposes and is usually ignored in normal operation + /// since most programs should continue to function even when tracing is not configured. + /// + public int Write( + ReadOnlySpan v1, + ReadOnlySpan v2, + ReadOnlySpan v3, + ReadOnlySpan v4, + ReadOnlySpan v5) + where T1 : unmanaged + where T2 : unmanaged + where T3 : unmanaged + where T4 : unmanaged + where T5 : unmanaged + { + if (this.enablementArray[0] == 0) + { + return TracepointHandle.DisabledEventError; + } + + unsafe + { + fixed (void* + p1 = v1, + p2 = v2, + p3 = v3, + p4 = v4, + p5 = v5) + { + return this.handle.Write(stackalloc DataSegment[] { + default, // segment[0] is used for headers. + new DataSegment(p1, (uint)v1.Length * (uint)sizeof(T1)), + new DataSegment(p2, (uint)v2.Length * (uint)sizeof(T2)), + new DataSegment(p3, (uint)v3.Length * (uint)sizeof(T3)), + new DataSegment(p4, (uint)v4.Length * (uint)sizeof(T4)), + new DataSegment(p5, (uint)v5.Length * (uint)sizeof(T5)), + }); + } + } + } + + /// + /// If disposing is true, calls this.handle.Dispose(). + /// + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + this.handle.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/RawFileHandle.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/RawFileHandle.cs new file mode 100644 index 0000000000..7d80faa023 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/RawFileHandle.cs @@ -0,0 +1,165 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints.Provider; + +using System; +using System.Runtime.InteropServices; + +/// +/// Wraps a raw Posix file descriptor returned from "open". +/// Non-negative handle is a valid descriptor. +/// Negative handle is a negative errno with the result of the "open" operation. +/// +internal sealed class RawFileHandle + : SafeHandle +{ + private const int UnknownErrno = int.MaxValue; + + /// + /// Initializes a new handle that is invalid. + /// Do not use this constructor. To create a valid handle, call the static Open method. + /// + public RawFileHandle() + : base(new IntPtr(-UnknownErrno), true) + { + return; + } + + /// + /// Returns true if handle is negative (stores a negative errno). + /// + public override bool IsInvalid => (nint)this.handle < 0; + + /// + /// If open succeeded, returns 0. Otherwise returns the errno from open. + /// + public int OpenResult + { + get + { + var h = (nint)this.handle; + return h >= 0 ? 0 : -(int)h; + } + } + + /// + /// Calls "open" with the given path name and with flags = O_WRONLY. + /// On success, returns a valid handle. On failure, returns an invalid handle + /// (check OpenResult for the errno). + /// + public static RawFileHandle OpenWRONLY(ReadOnlySpan nulTerminatedPathName) + { + var result = new RawFileHandle(); + + // Need a finally block to make sure the thread is not interrupted + // between the open and the handle assignment. + try + { + // Nothing. + } + finally + { + unsafe + { + fixed (byte* pathNamePtr = nulTerminatedPathName) + { + const int O_WRONLY = 0x0001; + result.handle = (nint)NativeMethods.open(pathNamePtr, O_WRONLY, 0); + } + } + } + + if (0 > (nint)result.handle) + { + var errno = Marshal.GetLastWin32Error(); + if (errno <= 0) + { + errno = UnknownErrno; + } + + result.handle = new IntPtr(-errno); + } + + return result; + } + + /// + /// Calls "writev" with the given data. + /// On success, returns the number of bytes written. + /// On error, returns -1 (check Marshal.GetLastWin32Error() for the errno). + /// + public nint WriteV(ReadOnlySpan iovecs) + { + var needRelease = false; + try + { + this.DangerousAddRef(ref needRelease); + unsafe + { + fixed (DataSegment* iovecsPtr = iovecs) + { + return NativeMethods.writev((Int32)(nint)this.handle, iovecsPtr, iovecs.Length); + } + } + } + finally + { + if (needRelease) + { + this.DangerousRelease(); + } + } + } + + /// + /// Calls "ioctl" with the given request and data. + /// On error, returns -1 (check Marshal.GetLastWin32Error() for the errno). + /// + public int Ioctl(uint request, ref T data) + where T : unmanaged + { + var needRelease = false; + try + { + this.DangerousAddRef(ref needRelease); + unsafe + { + fixed (void* dataPtr = &data) + { + return NativeMethods.ioctl((Int32)(nint)this.handle, new UIntPtr(request), dataPtr); + } + } + } + finally + { + if (needRelease) + { + this.DangerousRelease(); + } + } + } + + protected override bool ReleaseHandle() + { + var h = unchecked((Int32)(nint)this.handle); + return 0 <= NativeMethods.close(h); + } + + private unsafe static class NativeMethods + { + [DllImport("libc", SetLastError = true)] + public static extern int close(Int32 fd); + + [DllImport("libc", SetLastError = true)] + public static extern int open(byte* pathname, Int32 flags, Int32 mode); + + [DllImport("libc", SetLastError = true)] + public static extern int ioctl(Int32 fd, UIntPtr request, void* data); + + [DllImport("libc", SetLastError = true)] + public static extern IntPtr writev(Int32 fd, DataSegment* iovec, Int32 iovecCount); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/TracepointHandle.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/TracepointHandle.cs new file mode 100644 index 0000000000..e50d6092c5 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/TracepointHandle.cs @@ -0,0 +1,631 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints.Provider; + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Debug = System.Diagnostics.Debug; +using Interlocked = System.Threading.Interlocked; + +/// +/// Low-level owner of a tracepoint registration. +/// Handle is the tracepoint's write_index. +/// Uses a pinned allocation for the tracepoint's is-enabled buffer. +/// +internal sealed class TracepointHandle : SafeHandle +{ + /// + /// The error to return from Write to a disabled event = EBADF = 9. + /// + public const int DisabledEventError = 9; + + /// + /// The error to return from Write of an event that is too big = E2BIG = 7. + /// + public const int EventTooBigError = 7; + + private const byte EnableSize = sizeof(UInt32); + + private const int EBADF = 9; + private const int UnknownErrno = int.MaxValue; + private const int UnregisteredWriteIndex = -1; + + private const int IOC_NRSHIFT = 0; + private const int IOC_TYPESHIFT = IOC_NRSHIFT + 8; // 8 = IOC_NRBITS + private const int IOC_SIZESHIFT = IOC_TYPESHIFT + 8; // 8 = IOC_TYPEBITS + private const int IOC_DIRSHIFT = IOC_SIZESHIFT + 14; // 14 = IOC_SIZEBITS + private const uint IOC_WRITE = 1; + private const uint IOC_READ = 2; + private const uint DIAG_IOC_MAGIC = '*'; + + private static RawFileHandle? userEventsDataStatic; + private static Int32[]? emptyEnabledPinned; // From normal heap. + + /// + /// When this.IsInvalid, enabledPinned is a shared emptyEnabledPinned from the normal heap. + /// When !this.IsInvalid, enabledPinned is a unique allocation from the pinned object heap. + /// + private Int32[] enabledPinned; + + /// + /// Initializes a new handle that is invalid. + /// +#pragma warning disable CA1419 // Provide a parameterless constructor. (We don't need the runtime to create instances of TracepointHandle.) + private TracepointHandle() +#pragma warning restore CA1419 + : base((nint)UnregisteredWriteIndex, true) + { + var enabledPinned = emptyEnabledPinned ?? + Utility.InterlockedInitSingleton(ref emptyEnabledPinned, new Int32[1]); + Debug.Assert(0 == enabledPinned[0]); + this.enabledPinned = enabledPinned; + } + + /// + /// If registration succeeded, returns 0. + /// If registration failed, returns the errno from the failed open/ioctl. + /// + public int RegisterResult { get; private set; } = UnknownErrno; + + /// + /// Returns true if this tracepoint is enabled, false otherwise. + /// Value may change at any time while the tracepoint is registered. + /// + public bool IsEnabled => 0 != this.enabledPinned[0]; + + /// + /// Returns true if registration was successful. + /// (Remains true even after handle is closed/disposed.) + /// + public override bool IsInvalid => (nint)UnregisteredWriteIndex == this.handle; + + /// + /// Given an all-Latin1 user_events command string (no characters with value > 255), + /// attempts to register it. Returns a TracepointHandle with the result. + /// Syntax for nameArgs is given here: + /// https://docs.kernel.org/trace/user_events.html#command-format, + /// e.g. "MyEventName int arg1; u32 arg2". + ///
    + /// If registration succeeds, the returned handle will be valid and active: + /// IsInvalid == false, IsEnabled is dynamic, RegisterResult == 0, + /// Write is meaningful. + ///
    + /// If registration fails, the returned handle will be invalid and inactive: + /// IsInvalid == true, IsEnabled == false, RegisterResult != 0, + /// Write will always return EBADF. + ///
    + public static TracepointHandle Register(ReadOnlySpan nameArgs, PerfUserEventReg flags = 0) + { + Span nulTerminatedNameArgs = stackalloc byte[nameArgs.Length + 1]; + for (var i = 0; i < nameArgs.Length; i += 1) + { + nulTerminatedNameArgs[i] = unchecked((byte)nameArgs[i]); + } + + nulTerminatedNameArgs[nameArgs.Length] = 0; + return Register(nulTerminatedNameArgs, flags); + } + + /// + /// Given a NUL-terminated Latin1 user_events command string, attempts to register it. + /// Returns a TracepointHandle with the result. + /// Syntax for nameArgs is given here: + /// https://docs.kernel.org/trace/user_events.html#command-format, + /// e.g. "MyEventName int arg1; u32 arg2". + ///
    + /// If registration succeeds, the returned handle will be valid and active: + /// IsInvalid == false, IsEnabled is meaningful, RegisterResult == 0, + /// Write is meaningful. + ///
    + /// If registration fails, the returned handle will be invalid and inactive: + /// IsInvalid == true, IsEnabled == false, RegisterResult != 0, + /// Write will always return EBADF. + ///
    + public static TracepointHandle Register(ReadOnlySpan nulTerminatedNameArgs, PerfUserEventReg flags = 0) + { + Debug.Assert(0 <= nulTerminatedNameArgs.LastIndexOf((byte)0)); + + var tracepoint = new TracepointHandle(); + + var userEventsData = userEventsDataStatic ?? InitUserEventsDataStatic(); + if (userEventsData.OpenResult != 0) + { + tracepoint.InitFailed(userEventsData.OpenResult); + } + else + { + var enabledPinned = GC.AllocateArray(1, pinned: true); + Debug.Assert(0 == enabledPinned[0]); + + int ioctlResult; + unsafe + { + fixed (Int32* enabledPtr = enabledPinned) + { + fixed (byte* nameArgsPtr = nulTerminatedNameArgs) + { + var reg = new user_reg + { + size = user_reg.SizeOfStruct, + enable_size = EnableSize, + flags = flags, + enable_addr = (nuint)enabledPtr, + name_args = (nuint)nameArgsPtr, + }; + + // Need a finally block to make sure the thread is not interrupted + // between the ioctl and the SetHandle. + try + { + // Nothing. + } + finally + { + var DIAG_IOCSREG = + ((IOC_WRITE | IOC_READ) << IOC_DIRSHIFT) | + (DIAG_IOC_MAGIC << IOC_TYPESHIFT) | + (0u << IOC_NRSHIFT) | + ((uint)IntPtr.Size << IOC_SIZESHIFT); + ioctlResult = userEventsData.Ioctl(DIAG_IOCSREG, ref reg); + if (ioctlResult >= 0) + { + tracepoint.enabledPinned = enabledPinned; + tracepoint.SetHandle((nint)reg.write_index); + } + } + } + } + } + + if (ioctlResult >= 0) + { + tracepoint.InitSucceeded(); + } + else + { + var errno = Marshal.GetLastWin32Error(); + if (errno <= 0) + { + errno = UnknownErrno; + } + + tracepoint.InitFailed(errno); + } + } + + // All code paths should have called either InitSucceeded or InitFailed. + return tracepoint; + } + + /// + /// Sends tracepoint data to the user_events_data file. Uses data[0] for headers. + /// Returns EBADF if closed. Does NOT check IsEnabled (caller should do that). + ///
    + /// Requires: data[0].Length == 0 (data[0] will be used for headers). + ///
    + public int Write(Span data) + { + // Precondition: slot for write_index in data[0]. + Debug.Assert(data[0].Length == 0); + + var userEventsData = userEventsDataStatic; + Debug.Assert(userEventsData != null); // Otherwise there would be no TracepointHandle instance. + Debug.Assert(userEventsData.OpenResult == 0); // Otherwise Enabled would be false. + + var writeIndex = new WriteIndexPlus { WriteIndex = (Int32)(nint)this.handle, Padding = 0 }; + unsafe + { + // Workaround: On old kernels, events with 0 bytes of data don't get written. + // If event has 0 bytes of data, add a byte to avoid the problem. + data[0] = new DataSegment(&writeIndex, sizeof(Int32) + (data.Length == 1 ? 1u : 0u)); + } + + if (this.IsClosed) + { + return DisabledEventError; + } + + // Ignore race condition: if we're disposed between checking IsClosed and calling WriteV, + // we will write the data using a write_index that doesn't belong to us. That's not great, + // but it's not fatal and probably not worth degrading performance to avoid it. The + // write_index is unlikely to be recycled during the race condition, and even if it is + // recycled, the worst consequence would be a garbage event in a trace. Could avoid with: + // try { AddRef; WriteV; } catch { return EBADF; } finally { Release; }. + + var writevResult = userEventsData.WriteV(data); + return writevResult >= 0 ? 0 : Marshal.GetLastWin32Error(); + } + + /// + /// Sends tracepoint with EventHeader to the user_events_data file. Uses data[0] for headers. + /// Returns EBADF if closed. Does NOT check IsEnabled (caller should do that). + ///
    + /// Fills in data[0] with writeIndex + eventHeader + activityIdBlock? + metadataHeader?. Sets the extension + /// block's flags based on metaLength. + ///
    + /// Requires: data[0].Length == 0 (data[0] will be used for headers). + ///
    + /// Requires: relatedId cannot be present unless activityId is present. + ///
    + /// Requires: If activityId is present or metaLength != 0 then + /// eventHeader.Flags must equal DefaultWithExtension. + ///
    + /// Requires: If metaLength != 0 then data[1] starts with metadata extension block data. + ///
    + public unsafe int WriteEventHeader( + EventHeader eventHeader, + Guid* activityId, + Guid* relatedId, + ushort metaLength, + Span data) + { + // Precondition: slot for write_index in data[0]. + Debug.Assert(data[0].Length == 0); + + // Precondition: relatedId cannot be present unless activityId is present. + Debug.Assert(relatedId == null || activityId != null); + + // Precondition: eventHeader.Flags must match up with presence of first extension. + Debug.Assert((activityId == null && metaLength == 0) || + eventHeader.Flags == (EventHeader.DefaultFlags | EventHeaderFlags.Extension)); + + // Precondition: metaLength implies metadata extension block data. + Debug.Assert(metaLength == 0 || data.Length > 1); + + var userEventsData = userEventsDataStatic; + Debug.Assert(userEventsData != null); // Otherwise there would be no TracepointHandle instance. + Debug.Assert(userEventsData.OpenResult == 0); // Otherwise Enabled would be false. + + const byte HeadersMax = sizeof(Int32) // writeIndex + + EventHeader.SizeOfStruct // eventHeader + + EventHeaderExtension.SizeOfStruct + 16 + 16 // activityId header + activityId + relatedId + + EventHeaderExtension.SizeOfStruct; // metadata header + var writeIndex = (Int32)(nint)this.handle; + unsafe + { + uint* headersUInt32 = stackalloc UInt32[HeadersMax / sizeof(UInt32)]; // Ensure 4-byte alignment. + byte* headers = (byte*)headersUInt32; + uint pos = 0; + + *(Int32*)&headers[pos] = (Int32)(nint)this.handle; + pos += sizeof(Int32); + + *(EventHeader*)&headers[pos] = eventHeader; + pos += EventHeader.SizeOfStruct; + + if (activityId != null) + { + var kind = EventHeaderExtensionKind.ActivityId | (metaLength == 0 ? 0 : EventHeaderExtensionKind.ChainFlag); + if (relatedId != null) + { + *(EventHeaderExtension*)&headers[pos] = new EventHeaderExtension { Kind = kind, Size = 32 }; + pos += EventHeaderExtension.SizeOfStruct; + Utility.WriteGuidBigEndian(new Span(&headers[pos], 16), *activityId); + pos += 16; + Utility.WriteGuidBigEndian(new Span(&headers[pos], 16), *relatedId); + pos += 16; + } + else + { + *(EventHeaderExtension*)&headers[pos] = new EventHeaderExtension { Kind = kind, Size = 16 }; + pos += EventHeaderExtension.SizeOfStruct; + Utility.WriteGuidBigEndian(new Span(&headers[pos], 16), *activityId); + pos += 16; + } + } + + if (metaLength != 0) + { + *(EventHeaderExtension*)&headers[pos] = new EventHeaderExtension + { + Kind = EventHeaderExtensionKind.Metadata, // Last one, so no chain flag. + Size = metaLength, + }; + pos += EventHeaderExtension.SizeOfStruct; + } + + data[0] = new DataSegment(headers, pos); + } + + if (this.IsClosed) + { + return DisabledEventError; + } + + // Ignore race condition: if we're disposed between checking IsClosed and calling WriteV, + // we will write the data using a write_index that doesn't belong to us. That's not great, + // but it's not fatal and probably not worth degrading performance to avoid it. The + // write_index is unlikely to be recycled during the race condition, and even if it is + // recycled, the worst consequence would be a garbage event in a trace. Could avoid with: + // try { AddRef; WriteV; } catch { return EBADF; } finally { Release; }. + + var writevResult = userEventsData.WriteV(data); + return writevResult >= 0 ? 0 : Marshal.GetLastWin32Error(); + } + + /// + /// Returns an array of length 1 that contains the value that will be updated by the + /// kernel when the tracepoint is enabled or disabled. Caller MUST NOT modify the contents + /// of the array. + ///
    + /// When this.IsInvalid, the array is shared by all other invalid handles and is a normal allocation. + /// When !this.IsInvalid, there is a separate array for each handle and is a pinned allocation. + ///
    + public Int32[] DangerousGetEnablementArray() + { + return this.enabledPinned; + } + + protected override bool ReleaseHandle() + { + var userEventsData = userEventsDataStatic; + Debug.Assert(userEventsData != null); // Otherwise there would be no TracepointHandle instance. + + var enabledPinned = this.enabledPinned; + int ioctlResult; + unsafe + { + Debug.Assert(!ReferenceEquals(enabledPinned, emptyEnabledPinned)); + fixed (Int32* enabledPtr = enabledPinned) + { + var unreg = new user_unreg + { + size = user_unreg.SizeOfStruct, + disable_addr = (nuint)enabledPtr, + }; + + var DIAG_IOCSUNREG = + (IOC_WRITE << IOC_DIRSHIFT) | + (DIAG_IOC_MAGIC << IOC_TYPESHIFT) | + (2u << IOC_NRSHIFT) | + ((uint)IntPtr.Size << IOC_SIZESHIFT); + ioctlResult = userEventsData.Ioctl(DIAG_IOCSUNREG, ref unreg); + } + } + + enabledPinned[0] = 0; // Force IsEnabled = false. + return 0 <= ioctlResult; + } + + /// + /// Locates and opens the user_events_data file. + /// First call to this will update userEventsDataStatic with the result. + /// + /// The new value of userEventsDataStatic (never null). + private static RawFileHandle InitUserEventsDataStatic() + { + RawFileHandle? resultHandle = null; + RawFileHandle? newHandle = null; + try + { + newHandle = RawFileHandle.OpenWRONLY("/sys/kernel/tracing/user_events_data\0"u8); + if (newHandle.OpenResult == 0) + { + // Success. + } + else if (!File.Exists("/proc/mounts")) + { + // Give up. + } + else + { + Span path = stackalloc byte[274]; // 256 + sizeof("/user_events_data\0") + FileStream? mounts = null; + try + { + mounts = File.OpenRead("/proc/mounts"); + + Span line = stackalloc byte[4096]; + bool eof = false; + while (!eof) + { + // ~fgets + int lineEnd; + for (lineEnd = 0; lineEnd < line.Length; lineEnd += 1) + { + var b = mounts.ReadByte(); + if (b < 0) + { + eof = true; + break; + } + else if (b == '\n') + { + break; + } + else + { + line[lineEnd] = (byte)b; + } + } + + // line is "device_name mount_point file_system other_stuff..." + + int linePos = 0; + + // device_name + while (linePos < lineEnd && IsNonspaceByte(line[linePos])) + { + linePos += 1; + } + + // whitespace + while (linePos < lineEnd && IsSpaceByte(line[linePos])) + { + linePos += 1; + } + + // mount_point + var mountBegin = linePos; + while (linePos < lineEnd && IsNonspaceByte(line[linePos])) + { + linePos += 1; + } + + var mountEnd = linePos; + + // whitespace + while (linePos < lineEnd && IsSpaceByte(line[linePos])) + { + linePos += 1; + } + + // file_system + var fsBegin = linePos; + while (linePos < lineEnd && IsNonspaceByte(line[linePos])) + { + linePos += 1; + } + + var fsEnd = linePos; + + if (linePos == lineEnd || !IsSpaceByte(line[linePos])) + { + // Ignore line if no whitespace after file_system. + continue; + } + + bool foundTraceFS; + var fs = line.Slice(fsBegin, fsEnd - fsBegin); + if (fs.SequenceEqual("tracefs"u8)) + { + // "tracefsMountPoint/user_events_data" + foundTraceFS = true; + } + else if (path[0] == 0 && fs.SequenceEqual("debugfs"u8)) + { + // "debugfsMountPoint/tracing/user_events_data" + foundTraceFS = false; + } + else + { + continue; + } + + var pathSuffix0 = foundTraceFS + ? "/user_events_data\0"u8 + : "/tracing/user_events_data\0"u8; + + var mountLen = mountEnd - mountBegin; + var pathLen = mountLen + pathSuffix0.Length; // Includes NUL + if (pathLen > path.Length) + { + continue; + } + + // path = mountpoint + suffix + line.Slice(mountBegin, mountLen).CopyTo(path); + pathSuffix0.CopyTo(path.Slice(mountLen)); // Includes NUL + + if (foundTraceFS) + { + // Found a match, and it's tracefs, so stop looking. + break; + } + else + { + // Found a match, but it's debugfs. We prefer tracefs, so keep looking. + } + } + } + catch (ArgumentException) { } + catch (IOException) { } + catch (NotSupportedException) { } + catch (UnauthorizedAccessException) { } + finally + { + mounts?.Dispose(); + } + + if (path[0] != 0) + { + newHandle.Dispose(); + newHandle = RawFileHandle.OpenWRONLY(path); + } + } + + var oldHandle = Interlocked.CompareExchange(ref userEventsDataStatic, newHandle, null); + if (oldHandle != null) + { + resultHandle = oldHandle; + } + else + { + resultHandle = newHandle; + } + } + finally + { + if (newHandle != null && newHandle != resultHandle) + { + newHandle.Dispose(); + } + } + + return resultHandle; + } + + private static bool IsSpaceByte(byte b) + { + return b == ' ' || b == '\t'; + } + + private static bool IsNonspaceByte(byte b) + { + return b != '\0' && !IsSpaceByte(b); + } + + private void InitSucceeded() + { + this.RegisterResult = 0; + Debug.Assert(1 >= this.enabledPinned[0]); + Debug.Assert(!ReferenceEquals(this.enabledPinned, emptyEnabledPinned)); + Debug.Assert(!this.IsClosed); + Debug.Assert(!this.IsInvalid); + } + + private void InitFailed(int registerResult) + { + this.SetHandleAsInvalid(); + this.RegisterResult = registerResult; + Debug.Assert(0 == this.enabledPinned[0]); + Debug.Assert(ReferenceEquals(this.enabledPinned, emptyEnabledPinned)); + Debug.Assert(this.IsClosed); + Debug.Assert(this.IsInvalid); + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private struct user_reg + { + public const int SizeOfStruct = 28; + public UInt32 size; + public byte enable_bit; + public byte enable_size; + public PerfUserEventReg flags; + public UInt64 enable_addr; + public UInt64 name_args; + public Int32 write_index; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + private struct user_unreg + { + public const int SizeOfStruct = 16; + public UInt32 size; + public byte disable_bit; + public byte reserved; + public UInt16 reserved2; + public UInt64 disable_addr; + } + + [StructLayout(LayoutKind.Sequential)] + private struct WriteIndexPlus + { + public Int32 WriteIndex; + public UInt32 Padding; + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/Utility.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/Utility.cs new file mode 100644 index 0000000000..ef68419d51 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Provider/Utility.cs @@ -0,0 +1,41 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints.Provider; + +using System; +using System.Runtime.InteropServices; +using Interlocked = System.Threading.Interlocked; +using BinaryPrimitives = System.Buffers.Binary.BinaryPrimitives; + +internal static class Utility +{ + /// + /// Atomically: old = location; if (old != null) { return old; } else { location = value; return value; } + /// + public static T InterlockedInitSingleton(ref T? location, T value) + where T : class + { + return Interlocked.CompareExchange(ref location, value, null) ?? value; + } + + public static void WriteGuidBigEndian(Span destination, Guid value) + { + if (BitConverter.IsLittleEndian) + { + unsafe + { + var p = (byte*)&value; + var p0 = (uint*)p; + var p1 = (ushort*)(p + 4); + var p2 = (ushort*)(p + 6); + *p0 = BinaryPrimitives.ReverseEndianness(*p0); + *p1 = BinaryPrimitives.ReverseEndianness(*p1); + *p2 = BinaryPrimitives.ReverseEndianness(*p2); + } + } + MemoryMarshal.Write(destination, ref value); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/README.md b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/README.md new file mode 100644 index 0000000000..3e4bb7b133 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/README.md @@ -0,0 +1,17 @@ +# LinuxTracepoints-Net + +The code in this folder came from the +[LinuxTracepoints-Net](https://github.com/microsoft/LinuxTracepoints-Net) repo +([commit +974c475](https://github.com/microsoft/LinuxTracepoints-Net/blob/974c47522d053c915009ef5112840026eaf22adb)). + +Only the files required to build +`Microsoft.LinuxTracepoints.Provider.PerfTracepoint` were included. + +The following changes were made: + +* `#nullable enabled` added at the top of all files. This is because + LinuxTracepoints-Net has `enabled` repo-wide but + GenevaExporter has `disabled` at the moment. + +* `public` types made `internal`. diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeader.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeader.cs new file mode 100644 index 0000000000..a8db3a3140 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeader.cs @@ -0,0 +1,302 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +/*--EventHeader Events-------------------------------------------------------- + +EventHeader is a tracing convention layered on top of Linux Tracepoints. + +To reduce the number of unique Tracepoint names tracked by the kernel, we +use a small number of Tracepoints to manage a larger number of events. All +events with the same attributes (provider name, severity level, category +keyword, etc.) will share one Tracepoint. + +- This means we cannot enable/disable events individually. Instead, all events + with the same attributes will be enabled/disabled as a group. +- This means we cannot rely on the kernel's Tracepoint metadata for event + identity or event field names/types. Instead, all events contain a common + header that provides event identity, core event attributes, and support for + optional event attributes. The kernel's Tracepoint metadata is used only for + the Tracepoint's name and to determine whether the event follows the + EventHeader conventions. + +We define a naming scheme to be used for the shared Tracepoints: + + TracepointName = ProviderName + '_' + 'L' + EventLevel + 'K' + EventKeyword + + [Options] + +We define a common event layout to be used by all EventHeader events. The +event has a header, optional header extensions, and then the event data: + + Event = eventheader + [HeaderExtensions] + Data + +We define a format to be used for header extensions: + + HeaderExtension = eventheader_extension + ExtensionData + +We define a header extension to be used for activity IDs. + +We define a header extension to be used for event metadata (event name, field +names, field types). + +For use in the event metadata extension, we define a field type system that +supports scalar, string, binary, array, and struct. + +Note that we assume that the Tracepoint name corresponding to the event is +available during event decoding. The event decoder obtains the provider name +and keyword for an event by parsing the event's Tracepoint name. + +--Provider Names-------------------------------------------------------------- + +A provider is a component that generates events. Each event from a provider is +associated with a Provider Name that uniquely identifies the provider. + +The provider name should be short, yet descriptive enough to minimize the +chance of collision and to help developers track down the component generating +the events. Hierarchical namespaces may be useful for provider names, e.g. +"MyCompany_MyOrg_MyComponent". + +Restrictions: + +- ProviderName may not contain ' ' or ':' characters. +- strlen(ProviderName + '_' + Attributes) must be less than + EVENTHEADER_NAME_MAX (256) characters. +- Some event APIs (e.g. tracefs) might impose additional restrictions on + tracepoint names. For best compatibility, use only ASCII identifier characters + [A-Za-z0-9_] in provider names. + +Event attribute semantics should be consistent within a given provider. While +some event attributes have generally-accepted semantics (e.g. level value 3 +is defined below as "warning"), the precise semantics of the attribute values +are defined at the scope of a provider (e.g. different providers will use +different criteria for what constitutes a warning). In addition, some +attributes (tag, keyword) are completely provider-defined. All events with a +particular provider name should use consistent semantics for all attributes +(e.g. keyword bit 0x1 should have a consistent meaning for all events from a +particular provider but will mean something different for other providers). + +--Tracepoint Names------------------------------------------------------------ + +A Tracepoint is registered with the kernel for each unique combination of +ProviderName + Attributes. This allows a larger number of distinct events to +be controlled by a smaller number of kernel Tracepoints while still allowing +events to be enabled/disabled at a reasonable granularity. + +The Tracepoint name for an EventHeader event is defined as: + + ProviderName + '_' + 'L' + eventLevel + 'K' + eventKeyword + [Options] + or printf("%s_L%xK%lx%s", providerName, eventLevel, eventKeyword, options), + e.g. "MyProvider_L3K2a" or "OtherProvider_L5K0Gperf". + +Event level is a uint8 value 1..255 indicating event severity, formatted as +lowercase hexadecimal, e.g. printf("L%x", eventLevel). The defined level values +are: 1 = critical error, 2 = error, 3 = warning, 4 = information, 5 = verbose. + +Event keyword is a uint64 bitmask indicating event category membership, +formatted as lowercase hexadecimal, e.g. printf("K%lx", eventKeyword). Each +bit in the keyword corresponds to a provider-defined category, e.g. a provider +might define 0x2 = networking and 0x4 = I/O so that keyword value of 0x2|0x4 = +0x6 would indicate that an event is in both the networking and I/O categories. + +Options (optional attributes) can be specified after the keyword attribute. +Each option consists of an uppercase ASCII letter (option type) followed by 0 +or more ASCII digits or lowercase ASCII letters (option value). To support +consistent event names, the options must be sorted in alphabetical order, e.g. +"Aoption" should come before "Boption". + +The currently defined options are: + +- 'G' = provider Group name. Defines a group of providers. This can be used by + event analysis tools to find all providers that generate a certain kind of + information. + +Restrictions: + +- ProviderName may not contain ' ' or ':' characters. +- Tracepoint name must be less than EVENTHEADER_NAME_MAX (256) + characters in length. +- Some event APIs (e.g. tracefs) might impose additional restrictions on + tracepoint names. For best compatibility, use only ASCII identifier characters + [A-Za-z0-9_] in provider names. + +--Header----------------------------------------------------------------------- + +Because multiple events may share a single Tracepoint, each event must contain +information needed to distinguish it from other events. To enable this, each +event starts with an EventHeader structure which contains information about +the event: + +- flags: Bits indicating pointer size (32 or 64 bits), byte order + (big-endian or little), and whether any header extensions are present. +- opcode: Indicates special event semantics e.g. "normal event", + "activity start event", "activity end event". +- tag: Provider-defined 16-bit value. Can be used for anything. +- id: 16-bit stable event identifier, or 0 if no identifier is assigned. +- version: 8-bit event version, incremented for e.g. field type changes. +- level: 8-bit event severity level, 1 = critical .. 5 = verbose. + (level value in event header must match the level in the Tracepoint name.) + +If the extension flag is not set, the header is immediately followed by the +event payload. + +If the extension flag is set, the header is immediately followed by one or more +header extensions. Each header extension has a 16-bit size, a 15-bit type code, +and a 1-bit flag indicating whether another header extension follows the +current extension. The final header extension is immediately followed by the +event payload. + +The following header extensions are defined: + +- Activity ID: Contains a 128-bit ID that can be used to correlate events. May + also contain the 128-bit ID of the parent activity (typically used only for + the first event of an activity). +- Metadata: Contains the event's metadata: event name, event attributes, field + names, field attributes, and field types. Both simple (e.g. Int32, HexInt16, + Float64, Char32, Uuid) and complex (e.g. NulTerminatedString8, + CountedString16, Binary, Struct, Array) types are supported. +*/ +namespace Microsoft.LinuxTracepoints +{ + using System; + using System.Runtime.InteropServices; + using Tracing = System.Diagnostics.Tracing; + + /// + /// + /// Core metadata for an EventHeader event. + /// + /// Each EventHeader event starts with an instance of the EventHeader structure. + /// It contains core information recorded for every event to help with event + /// identification, filtering, and decoding. + /// + /// If EventHeader.Flags has the Extension bit set then the EventHeader is followed + /// by one or more EventHeaderExtension blocks. Otherwise the EventHeader is + /// followed by the event payload data. + /// + /// If an EventHeaderExtension.Kind has the Chain flag set then the + /// EventHeaderExtension block is followed immediately (no alignment/padding) by + /// another extension block. Otherwise it is followed immediately (no + /// alignment/padding) by the event payload data. + /// + /// If there is a Metadata extension then it contains the event name, field names, + /// and field types needed to decode the payload data. Otherwise, the payload + /// decoding system is defined externally, i.e. you will use the provider name to + /// find the appropriate decoding manifest, then use the event's id+version to + /// find the decoding information within the manifest, then use that decoding + /// information to decode the event payload data. + /// + /// For a particular event definition (i.e. for a particular event name, or for a + /// particular event id+version), the information in the EventHeader (and in the + /// Metadata extension, if present) should be constant. For example, instead of + /// having a single event with a runtime-variable level, you should have a + /// distinct event definition (with distinct event name and/or distinct event id) + /// for each level. + /// + /// + [StructLayout(LayoutKind.Sequential)] + internal struct EventHeader + { + /// + /// The size of this structure in bytes (8). + /// + public const int SizeOfStruct = 8; + + /// + /// Pointer-size and Endian flags as appropriate for the currently-running process, + /// no extension blocks present. + /// + public static readonly EventHeaderFlags DefaultFlags = + (IntPtr.Size == 8 ? EventHeaderFlags.Pointer64 : EventHeaderFlags.None) | + (BitConverter.IsLittleEndian ? EventHeaderFlags.LittleEndian : EventHeaderFlags.None); + + /// + /// The encoding corresponding to IntPtr. If IntPtr.Size == 8, this is Value64. + /// Otherwise, this is Value32. + /// + public static readonly EventHeaderFieldEncoding IntPtrEncoding = + IntPtr.Size == 8 ? EventHeaderFieldEncoding.Value64 : EventHeaderFieldEncoding.Value32; + + /// + /// Pointer64, LittleEndian, Extension. + /// + public EventHeaderFlags Flags; + + /// + /// Increment Version whenever event layout changes. + /// + public byte Version; + + /// + /// Stable id for this event, or 0 if none. + /// + public ushort Id; + + /// + /// Provider-defined event tag, or 0 if none. + /// + public ushort Tag; + + /// + /// EventOpcode raw value. (Stores the value of the Opcode property.) + /// + public byte OpcodeByte; + + /// + /// EventLevel raw value. (Stores the value of the Level property.) + /// + public byte LevelByte; + + /// + /// EventOpcode: info, start activity, stop activity, etc. + /// Throws OverflowException if set value > 255. + /// + /// + /// Most events set Opcode = Info (0). Other Opcode values add special semantics to + /// an event that help the event analysis tool with grouping related events. The + /// most frequently-used special semantics are ActivityStart and ActivityStop. + /// + /// To record an activity: + /// + /// Generate a new activity id. An activity id is a 128-bit value that must be + /// unique within the trace. This can be a UUID or it can be generated by any + /// other id-generation system that is unlikely to create the same value for any + /// other activity id in the same trace. + /// + /// Write an event with opcode = ActivityStart and with an ActivityId header + /// extension. The ActivityId extension should have the newly-generated activity + /// id, followed by the id of a parent activity (if any). If there is a parent + /// activity, the extension length will be 32; otherwise it will be 16. + /// + /// As appropriate, write any number of normal events (events with opcode set to + /// something other than ActivityStart or ActivityStop, e.g. opcode = Info). To + /// indicate that the events are part of the activity, each of these events + /// should have an ActivityId header extension with the new activity id + /// (extension length will be 16). + /// + /// When the activity ends, write an event with opcode = ActivityStop and with + /// an ActivityId header extension containing the activity id of the activity + /// that is ending (extension length will be 16). + /// + /// + /// Set value > 255 + public Tracing.EventOpcode Opcode + { + readonly get => (Tracing.EventOpcode)OpcodeByte; + set => OpcodeByte = checked((byte)value); + } + + /// + /// EventLevel: critical, error, warning, info, verbose. + /// Throws OverflowException if set value > 255. + /// + /// Set value > 255 + public Tracing.EventLevel Level + { + readonly get => (Tracing.EventLevel)LevelByte; + set => LevelByte = checked((byte)value); + } + + // Followed by: EventHeaderExtension block(s), then event payload. + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtension.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtension.cs new file mode 100644 index 0000000000..807217a5f0 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtension.cs @@ -0,0 +1,46 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints +{ + using System.Runtime.InteropServices; + + /// + /// + /// Additional information for an EventHeader event. + /// + /// If EventHeader.Flags has the Extension bit set then the EventHeader is + /// followed by one or more EventHeaderExtension blocks. Otherwise the EventHeader + /// is followed by the event payload data. + /// + /// If EventHeaderExtension.Kind has the Chain flag set then the + /// EventHeaderExtension block is followed immediately (no alignment/padding) by + /// another extension block. Otherwise it is followed immediately (no + /// alignment/padding) by the event payload data. + /// + /// + [StructLayout(LayoutKind.Sequential)] + internal struct EventHeaderExtension + { + /// + /// The size of this structure in bytes (4). + /// + public const int SizeOfStruct = 4; + + /// + /// The size of the extension data in bytes. + /// The data immediately follows this structure with no padding/alignment. + /// + public ushort Size; + + /// + /// The kind of extension. This determines the format of the extension data. + /// In addition, the Chain flag indicates whether another extension follows. + /// + public EventHeaderExtensionKind Kind; + + // Followed by Size bytes of data. No padding/alignment. + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtensionKind.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtensionKind.cs new file mode 100644 index 0000000000..2d2e845f33 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderExtensionKind.cs @@ -0,0 +1,117 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints +{ + /// + /// Values for EventHeaderExtension.Kind. + /// + internal enum EventHeaderExtensionKind : ushort + { + /// + /// Mask for the base extension kind (low 15 bits). + /// + ValueMask = 0x7fff, + + /// + /// If not set, this is the last extension block (event payload data follows). + /// If set, this is not the last extension block (another extension block follows). + /// + ChainFlag = 0x8000, + + /// + /// Invalid extension kind. + /// + Invalid = 0, + + /// + /// + /// Extension contains an event definition (i.e. event metadata). + /// + /// Event definition format: + /// + /// char EventName[]; // Nul-terminated utf-8 string: "eventName{;attribName=attribValue}" + /// + /// 0 or more field definition blocks. + /// + /// Field definition block: + /// + /// char FieldName[]; // Nul-terminated utf-8 string: "fieldName{;attribName=attribValue}" + /// + /// uint8_t Encoding; // Encoding is 0..31, with 3 flag bits. + /// + /// uint8_t Format; // Present if (Encoding & 128). Format is 0..127, with 1 flag bit. + /// + /// uint16_t Tag; // Present if (Format & 128). Contains provider-defined value. + /// + /// uint16_t ArrayLength; // Present if (Encoding & 32). Contains element count of constant-length array. + /// + /// Notes: + /// + /// eventName and fieldName may not contain any ';' characters. + /// + /// eventName and fieldName may be followed by attribute strings. + /// + /// attribute string is: ';' + attribName + '=' + attribValue. + /// + /// attribName may not contain any ';' or '=' characters. + /// + /// Semicolons in attribValue must be escaped by doubling, e.g. + /// "my;value" is escaped as "my;;value". + /// + /// + Metadata, + + /// + /// + /// Extension contains activity id information. + /// + /// Any event that is part of an activity has an ActivityId extension. + /// + /// Activity is started by an event with opcode = ActivityStart. The + /// ActivityId extension for the start event must contain a newly-generated + /// activity id and may optionally contain the parent activity id. + /// + /// Activity may contain any number of normal events (opcode something other + /// than ActivityStart or ActivityStop). The ActivityId extension for each + /// normal event must contain the id of the associated activity (otherwise + /// it is not considered to be part of the activity). + /// + /// Activity is ended by an event with opcode = ActivityStop. The ActivityId + /// extension for the stop event must contain the id of the activity that is + /// ending. + /// + /// An activity id is a 128-bit value that is unique within this trace + /// session. It may be a UUID. Since UUID generation can be expensive, this + /// may also be a 128-bit LUID (locally-unique id), generated using any method + /// that is unlikely to conflict with other activity ids in the same trace. + /// + /// If extension.Size == 16 then value is a 128-bit activity id. + /// + /// If extension.Size == 32 then value is a 128-bit activity id followed by a + /// 128-bit related (parent) activity id. + /// + /// + ActivityId, + } + + /// + /// Extension methods for . + /// + internal static class EventHeaderExtensionKindExtensions + { + /// + /// Returns the format without any flags (format & ValueMask). + /// + public static EventHeaderExtensionKind BaseKind(this EventHeaderExtensionKind kind) => + kind & EventHeaderExtensionKind.ValueMask; + + /// + /// Returns true if ChainFlag is present (more extensions are present in event). + /// + public static bool HasChainFlag(this EventHeaderExtensionKind kind) => + 0 != (kind & EventHeaderExtensionKind.ChainFlag); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldEncoding.cs new file mode 100644 index 0000000000..28cb80ff87 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldEncoding.cs @@ -0,0 +1,269 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +namespace Microsoft.LinuxTracepoints +{ + /// + /// + /// Values for the Encoding byte of a field definition. + /// + /// The low 5 bits of the Encoding byte contain the field's encoding. The encoding + /// indicates the following information about the field: + /// + /// How the decoder should determine the size of the field. For example, + /// Value32 indicates a 4-byte field, Value128 indicates a 16-byte + /// field, ZStringChar8 indicates that the field ends at the first char8 unit + /// with value 0, and BinaryLength16Char8 indicates that the first 16 bits of + /// the field are the uint16 Length and that the subsequent Length + /// char8 units are the field value. + /// + /// How the field should be formatted if the field's format is + /// , unrecognized, or unsupported. For + /// example, a Value32 encoding with Default or unrecognized format + /// should be treated as if it had UnsignedInt format. A + /// StringLength16Char8 encoding with Default or unrecognized format + /// should be treated as if it had StringUtf format. A + /// BinaryLength16Char8 encoding with Default or unrecognized format + /// should be treated as if it had HexBytes format. + /// + /// + /// The StringLength16Char8 and BinaryLength16Char8 are special. These + /// encodings can be used with both variable-length (e.g. HexBytes and + /// String) formats as well as with fixed-length (e.g. UnsignedInt, + /// Float, IPAddress) formats. When used with fixed-length formats, + /// the semantics depend on the field's variable Length (as determined from the first + /// two bytes of the field): + /// + /// If the Length is 0, the field is formatted as null. For example, a field + /// with encoding = BinaryLength16Char8, format = SignedInt, and + /// Length = 0 would be formatted as a null value. + /// + /// If the Length is appropriate for the format, the field is formatted as if it had + /// the Value8, Value16, Value32, Value64, or Value128 encoding corresponding to its + /// size. For example, a field with encoding = BinaryLength16Char8, + /// format = SignedInt, and Length = 4 would be formatted as an Int32 field. + /// + /// If the Length is not appropriate for the format, the field is formatted as if it + /// had the default format for the encoding. For example, a field with + /// encoding = BinaryLength16Char8, format = SignedInt, and Length = 16 + /// would be formatted as a HexBytes field since 16 is not a supported size + /// for the SignedInt format and the default format for + /// BinaryLength16Char8 is HexBytes. + /// + /// + /// The top 3 bits of the field encoding byte are flags: + /// + /// CArrayFlag indicates that this field is a constant-length array, with the + /// element count specified as a 16-bit value in the event metadata (must not be + /// 0). + /// + /// VArrayFlag indicates that this field is a variable-length array, with the + /// element count specified as a 16-bit value in the event payload (immediately + /// before the array elements, may be 0). + /// + /// ChainFlag indicates that a format byte is present after the encoding byte. + /// If Chain is not set, the format byte is omitted and is assumed to be 0. + /// + /// Setting both CArray and VArray is invalid (reserved). + /// + /// + internal enum EventHeaderFieldEncoding : byte + { + /// + /// Mask for the base encoding type (low 5 bits). + /// + ValueMask = 0x1F, + + /// + /// Mask for the encoding flags: CArrayFlag, VArrayFlag, ChainFlag. + /// + FlagMask = 0xE0, + + /// + /// Mask for the array flags: CArrayFlag, VArrayFlag. + /// + ArrayFlagMask = 0x60, + + /// + /// Constant-length array: 16-bit element count in metadata (must not be 0). + /// + CArrayFlag = 0x20, + + /// + /// Variable-length array: 16-bit element count in payload (may be 0). + /// + VArrayFlag = 0x40, + + /// + /// If present in the field, this flag indicates that an EventHeaderFieldFormat + /// byte follows the EventHeaderFieldEncoding byte. + /// + ChainFlag = 0x80, + + /// + /// Invalid encoding value. + /// + Invalid = 0, + + /// + /// 0-byte value, logically groups subsequent N fields, N = format & 0x7F, N must not be 0. + /// + Struct, + + /// + /// 1-byte value, default format UnsignedInt. + /// + Value8, + + /// + /// 2-byte value, default format UnsignedInt. + /// + Value16, + + /// + /// 4-byte value, default format UnsignedInt. + /// + Value32, + + /// + /// 8-byte value, default format UnsignedInt. + /// + Value64, + + /// + /// 16-byte value, default format HexBytes. + /// + Value128, + + /// + /// zero-terminated uint8[], default format StringUtf. + /// + ZStringChar8, + + /// + /// zero-terminated uint16[], default format StringUtf. + /// + ZStringChar16, + + /// + /// zero-terminated uint32[], default format StringUtf. + /// + ZStringChar32, + + /// + /// uint16 Length followed by uint8 Data[Length], default format StringUtf. + /// This should be treated exactly the same as BinaryLength16Char8 except that it + /// has a different default format. + /// + StringLength16Char8, + + /// + /// uint16 Length followed by uint16 Data[Length], default format StringUtf. + /// + StringLength16Char16, + + /// + /// uint16 Length followed by uint32 Data[Length], default format StringUtf. + /// + StringLength16Char32, + + /// + /// uint16 Length followed by uint8 Data[Length], default format HexBytes. + /// This should be treated exactly the same as StringLength16Char8 except that it + /// has a different default format. + /// + BinaryLength16Char8, + + /// + /// Invalid encoding value. Value will change in future versions of this header. + /// + Max, + } + + /// + /// Extension methods for . + /// + internal static class EventHeaderFieldEncodingExtensions + { + /// + /// Returns the encoding without any flags (encoding & ValueMask). + /// + public static EventHeaderFieldEncoding WithoutFlags(this EventHeaderFieldEncoding encoding) => + encoding & EventHeaderFieldEncoding.ValueMask; + + /// + /// Returns the encoding without the chain flag (encoding & ~ChainFlag). + /// + public static EventHeaderFieldEncoding WithoutChainFlag(this EventHeaderFieldEncoding encoding) => + encoding & ~EventHeaderFieldEncoding.ChainFlag; + + /// + /// Returns the array flags of the encoding (VArrayFlag or CArrayFlag, if set). + /// + public static EventHeaderFieldEncoding ArrayFlags(this EventHeaderFieldEncoding encoding) => + encoding & EventHeaderFieldEncoding.ArrayFlagMask; + + /// + /// Returns true if any ArrayFlag is present (constant-length or variable-length array). + /// + public static bool IsArray(this EventHeaderFieldEncoding encoding) => + 0 != (encoding & EventHeaderFieldEncoding.ArrayFlagMask); + + /// + /// Returns true if CArrayFlag is present (constant-length array). + /// + public static bool IsCArray(this EventHeaderFieldEncoding encoding) => + 0 != (encoding & EventHeaderFieldEncoding.CArrayFlag); + + /// + /// Returns true if VArrayFlag is present (variable-length array). + /// + public static bool IsVArray(this EventHeaderFieldEncoding encoding) => + 0 != (encoding & EventHeaderFieldEncoding.VArrayFlag); + + /// + /// Returns true if ChainFlag is present (format byte is present in event). + /// + public static bool HasChainFlag(this EventHeaderFieldEncoding encoding) => + 0 != (encoding & EventHeaderFieldEncoding.ChainFlag); + + /// + /// Gets the default format for the encoding, or EventHeaderFieldFormat.Default if the encoding is invalid. + /// + /// Value8, Value16, Value32, Value64: UnsignedInt. + /// + /// Value128: HexBytes. + /// + /// String: StringUtf. + /// + /// Other: Default. + /// + /// + public static EventHeaderFieldFormat DefaultFormat(this EventHeaderFieldEncoding encoding) + { + switch (encoding & EventHeaderFieldEncoding.ValueMask) + { + case EventHeaderFieldEncoding.Value8: + case EventHeaderFieldEncoding.Value16: + case EventHeaderFieldEncoding.Value32: + case EventHeaderFieldEncoding.Value64: + return EventHeaderFieldFormat.UnsignedInt; + case EventHeaderFieldEncoding.Value128: + return EventHeaderFieldFormat.HexBytes; + case EventHeaderFieldEncoding.ZStringChar8: + case EventHeaderFieldEncoding.ZStringChar16: + case EventHeaderFieldEncoding.ZStringChar32: + case EventHeaderFieldEncoding.StringLength16Char8: + case EventHeaderFieldEncoding.StringLength16Char16: + case EventHeaderFieldEncoding.StringLength16Char32: + return EventHeaderFieldFormat.StringUtf; + case EventHeaderFieldEncoding.BinaryLength16Char8: + return EventHeaderFieldFormat.HexBytes; + default: + return EventHeaderFieldFormat.Default; + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldFormat.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldFormat.cs new file mode 100644 index 0000000000..e6fa34e4fb --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFieldFormat.cs @@ -0,0 +1,168 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma warning disable CA1720 // Identifier contains type name + +namespace Microsoft.LinuxTracepoints +{ + /// + /// + /// Values for the Format byte of a field definition. + /// + /// The low 7 bits of the Format byte contain the field's format. + /// In the case of the Struct encoding, the low 7 bits of the Format byte contain + /// the number of logical fields in the struct (which must not be 0). + /// + /// The top bit of the field format byte is the ChainFlag. If set, it indicates + /// that a field tag (uint16) is present after the format byte. If not set, the + /// field tag is not present and is assumed to be 0. + /// + /// + internal enum EventHeaderFieldFormat : byte + { + /// + /// Mask for the base format type (low 7 bits). + /// + ValueMask = 0x7F, + + /// + /// If present in the field, this flag indicates that a uint16 + /// field tag follows the EventHeaderFieldFormat byte. + /// + ChainFlag = 0x80, + + /// + /// Use the default format of the encoding. + /// + Default = 0, + + /// + /// unsigned integer, event byte order. + /// Use with Value8..Value64 encodings. + /// + UnsignedInt, + + /// + /// signed integer, event byte order. + /// Use with Value8..Value64 encodings. + /// + SignedInt, + + /// + /// hex integer, event byte order. + /// Use with Value8..Value64 encodings. + /// + HexInt, + + /// + /// errno, event byte order. + /// Use with Value32 encoding. + /// + Errno, + + /// + /// process id, event byte order. + /// Use with Value32 encoding. + /// + Pid, + + /// + /// signed integer, event byte order, seconds since 1970. + /// Use with Value32 or Value64 encodings. + /// + Time, + + /// + /// 0 = false, 1 = true, event byte order. + /// Use with Value8..Value32 encodings. + /// + Boolean, + + /// + /// floating point, event byte order. + /// Use with Value32..Value64 encodings. + /// + Float, + + /// + /// binary, decoded as hex dump of bytes. + /// Use with any encoding. + /// + HexBytes, + + /// + /// 8-bit char string, unspecified character set (usually treated as ISO-8859-1 or CP-1252). + /// Use with Value8 and Char8 encodings. + /// + String8, + + /// + /// UTF string, event byte order, code unit size based on encoding. + /// Use with Value16..Value32 and Char8..Char32 encodings. + /// + StringUtf, + + /// + /// UTF string, BOM used if present, otherwise behaves like StringUtf. + /// Use with Char8..Char32 encodings. + /// + StringUtfBom, + + /// + /// XML string, otherwise behaves like StringUtfBom. + /// Use with Char8..Char32 encodings. + /// + StringXml, + + /// + /// JSON string, otherwise behaves like StringUtfBom. + /// Use with Char8..Char32 encodings. + /// + StringJson, + + /// + /// UUID, network byte order (RFC 4122 format). + /// Use with Value128 encoding. + /// + Uuid, + + /// + /// IP port, network byte order (in_port_t layout). + /// Use with Value16 encoding. + /// + Port, + + /// + /// IP address, network byte order (in_addr/in6_addr layout). + /// Use with Value32 or Value128 encoding. + /// + IPAddress, + + /// + /// Deprecated: Alternate format for IPAddress. + /// Do not generate events with this format. + /// Decode this format as IPAddress. + /// + IPAddressObsolete, + } + + /// + /// Extension methods for . + /// + internal static class EventHeaderFieldFormatExtensions + { + /// + /// Returns the format without any flags (format & ValueMask). + /// + public static EventHeaderFieldFormat WithoutFlags(this EventHeaderFieldFormat format) => + format & EventHeaderFieldFormat.ValueMask; + + /// + /// Returns true if ChainFlag is present (tag present in event). + /// + public static bool HasChainFlag(this EventHeaderFieldFormat format) => + 0 != (format & EventHeaderFieldFormat.ChainFlag); + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFlags.cs b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFlags.cs new file mode 100644 index 0000000000..af554483c9 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/External/LinuxTracepoints-Net/Types/EventHeaderFlags.cs @@ -0,0 +1,36 @@ +#nullable enable + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma warning disable CA1711 // Identifiers should not have incorrect suffix + +namespace Microsoft.LinuxTracepoints +{ + /// + /// Values for EventHeader.Flags. + /// + [System.Flags] + internal enum EventHeaderFlags : byte + { + /// + /// Pointer32, BigEndian, no extensions. + /// + None = 0x00, + + /// + /// Pointer is 64 bits, not 32 bits. + /// + Pointer64 = 0x01, + + /// + /// Event uses little-endian, not big-endian. + /// + LittleEndian = 0x02, + + /// + /// There is at least one EventHeaderExtension block. + /// + Extension = 0x04, + } +} diff --git a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs index 481e41c981..e2cea7bb1f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs +++ b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs @@ -1,5 +1,3 @@ -// (Turns off StyleCop analysis in this file.) - /* Dynamic ETW TraceLogging Provider API for .NET. diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 4605cafce6..ca6ebaf6dc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -1,4 +1,5 @@ + @@ -20,6 +21,11 @@
    + + + + + diff --git a/src/OpenTelemetry.Exporter.Geneva/THIRD-PARTY-NOTICES.TXT b/src/OpenTelemetry.Exporter.Geneva/THIRD-PARTY-NOTICES.TXT new file mode 100644 index 0000000000..3d74bb0bd8 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/THIRD-PARTY-NOTICES.TXT @@ -0,0 +1,30 @@ +OpenTelemetry.Exporter.Geneva uses third-party libraries or other resources that +may be distributed under licenses different than the +OpenTelemetry.Exporter.Geneva software. + +The attached notices are provided for information only. + +License notice for LinuxTracepoints-Net +------------------------------- + +MIT License + +Copyright (c) 2024 Microsoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 794eb4831f24ba182e99796a9d2966694f23124e Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:35:16 +0000 Subject: [PATCH 1278/1499] [Exporter.Geneva] Remove .NET 6 target (#2117) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- .../CHANGELOG.md | 3 +++ .../CompatibilitySuppressions.xml | 19 +++++++++++++++++++ .../Internal/MsgPack/MsgPackExporter.cs | 4 ++-- .../Internal/MsgPack/MsgPackLogExporter.cs | 8 ++++---- .../Internal/MsgPack/MsgPackTraceExporter.cs | 10 +++++----- .../Internal/Tld/UncheckedASCIIEncoding.cs | 4 ++-- .../Metrics/GenevaMetricExporter.cs | 2 +- .../OpenTelemetry.Exporter.Geneva.csproj | 9 ++++----- ...penTelemetry.Exporter.Geneva.Stress.csproj | 6 +++--- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 7 ++++--- 10 files changed, 47 insertions(+), 25 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 631613a201..47b1b1f495 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported. + ([#2117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2117)) + ## 1.9.0 Released 2024-Jun-21 diff --git a/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml b/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml new file mode 100644 index 0000000000..61ae99654f --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml @@ -0,0 +1,19 @@ + + + + + CP0008 + T:OpenTelemetry.Exporter.Geneva.EventNameExportMode + lib/net6.0/OpenTelemetry.Exporter.Geneva.dll + lib/netstandard2.0/OpenTelemetry.Exporter.Geneva.dll + true + + + CP0008 + T:OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode + lib/net6.0/OpenTelemetry.Exporter.Geneva.dll + lib/netstandard2.0/OpenTelemetry.Exporter.Geneva.dll + true + + diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs index c37581d5e3..3d7bb7def1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs @@ -3,7 +3,7 @@ #nullable enable -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif @@ -33,7 +33,7 @@ internal abstract class MsgPackExporter [Schema.V40.PartA.Extensions.Os.Ver] = "env_os_ver", }; -#if NET8_0_OR_GREATER +#if NET internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = PART_A_MAPPING_DICTIONARY.ToFrozenDictionary(); #else internal static readonly IReadOnlyDictionary V40_PART_A_MAPPING = PART_A_MAPPING_DICTIONARY; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs index 6e00b6a723..4371d7d373 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs @@ -3,7 +3,7 @@ #nullable enable -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif using System.Diagnostics; @@ -33,7 +33,7 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private readonly bool shouldExportEventName; private readonly TableNameSerializer tableNameSerializer; -#if NET8_0_OR_GREATER +#if NET private readonly FrozenSet? customFields; private readonly FrozenDictionary? prepopulatedFields; #else @@ -94,7 +94,7 @@ public MsgPackLogExporter(GenevaExporterOptions options) this.prepopulatedFieldKeys.Add(kv.Key); } -#if NET8_0_OR_GREATER +#if NET this.prepopulatedFields = tempPrepopulatedFields.ToFrozenDictionary(StringComparer.Ordinal); #else this.prepopulatedFields = tempPrepopulatedFields; @@ -110,7 +110,7 @@ public MsgPackLogExporter(GenevaExporterOptions options) customFields.Add(name); } -#if NET8_0_OR_GREATER +#if NET this.customFields = customFields.ToFrozenSet(StringComparer.Ordinal); #else this.customFields = customFields; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs index 2778de0bfd..9c0d15beef 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs @@ -3,7 +3,7 @@ #nullable enable -#if NET8_0_OR_GREATER +#if NET using System.Collections.Frozen; #endif using System.Diagnostics; @@ -34,7 +34,7 @@ internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable ["messaging.url"] = "messagingUrl", }; -#if NET8_0_OR_GREATER +#if NET internal static readonly FrozenDictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY.ToFrozenDictionary(); #else internal static readonly Dictionary CS40_PART_B_MAPPING = CS40_PART_B_MAPPING_DICTIONARY; @@ -42,7 +42,7 @@ internal sealed class MsgPackTraceExporter : MsgPackExporter, IDisposable internal readonly ThreadLocal Buffer = new(); -#if NET8_0_OR_GREATER +#if NET internal readonly FrozenSet? CustomFields; internal readonly FrozenSet? DedicatedFields; @@ -123,7 +123,7 @@ public MsgPackTraceExporter(GenevaExporterOptions options) dedicatedFields.Add(name); } -#if NET8_0_OR_GREATER +#if NET this.CustomFields = customFields.ToFrozenSet(StringComparer.Ordinal); #else this.CustomFields = customFields; @@ -137,7 +137,7 @@ public MsgPackTraceExporter(GenevaExporterOptions options) dedicatedFields.Add("otel.status_code"); dedicatedFields.Add("otel.status_description"); -#if NET8_0_OR_GREATER +#if NET this.DedicatedFields = dedicatedFields.ToFrozenSet(StringComparer.Ordinal); #else this.DedicatedFields = dedicatedFields; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs index aed31bd1b1..04085f22c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs @@ -83,7 +83,7 @@ public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, public override unsafe int GetBytes(char* charPtr, int charCount, byte* bytePtr, int byteCount) { -#if NET8_0_OR_GREATER +#if NET ArgumentOutOfRangeException.ThrowIfLessThan(byteCount, charCount); #else if (byteCount < charCount) @@ -102,7 +102,7 @@ public override unsafe int GetBytes(char* charPtr, int charCount, byte* bytePtr, public override unsafe int GetChars(byte* bytePtr, int byteCount, char* charPtr, int charCount) { -#if NET8_0_OR_GREATER +#if NET ArgumentOutOfRangeException.ThrowIfLessThan(charCount, byteCount); #else if (charCount < byteCount) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 253fbd9a63..ade4ff8593 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -116,7 +116,7 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } -#if NET8_0_OR_GREATER +#if NET [GeneratedRegex(DisableRegexPattern)] private static partial Regex GetDisableRegexPattern(); #else diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index ca6ebaf6dc..bc27891120 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -3,14 +3,13 @@ + + net8.0;$(NetStandardMinimumSupportedVersion) + $(TargetFrameworks);net462 true - An OpenTelemetry .NET exporter that exports to local ETW or UDS - OpenTelemetry Authors + An OpenTelemetry .NET exporter that exports to local ETW or UDS. $(NoWarn);SA1123;SA1310 - - net8.0;net6.0;netstandard2.0 - $(TargetFrameworks);net462 Exporter.Geneva- 1.9.0 disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 00273f8729..a9cd3cffcf 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -1,11 +1,11 @@ - Exe - $(SupportedNetTargets) + net8.0 $(TargetFrameworks);net48;net472;net471;net47;net462 - $(NoWarn),SA1308,SA1201 + Exe + $(NoWarn);SA1308;SA1201 disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 040ef19fa6..8f3e724c44 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -1,12 +1,13 @@ + - Unit test project for Geneva Exporters for OpenTelemetry - $(SupportedNetTargets) + net8.0 $(TargetFrameworks);net48;net472;net471;net47;net462 - $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202,OTEL1002 + Unit test project for Geneva Exporters for OpenTelemetry. + $(NoWarn);SA1311;SA1312;SA1313;SA1123;SA1202;OTEL1002 disable From 5559a6c8836f5f1bb7450af10ec61e0893f1347d Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 30 Sep 2024 10:54:00 -0700 Subject: [PATCH 1279/1499] [geneva] Rename metric transports (#2119) --- .../Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs | 2 +- .../Metrics/TlvMetricExporter.cs | 6 +++--- ...aTransport.cs => MetricUnixDomainSocketDataTransport.cs} | 4 ++-- ...ansport.cs => MetricWindowsEventTracingDataTransport.cs} | 6 +++--- .../GenevaMetricExporterTests.cs | 6 +++--- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/{MetricUnixDataTransport.cs => MetricUnixDomainSocketDataTransport.cs} (89%) rename src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/{MetricEtwDataTransport.cs => MetricWindowsEventTracingDataTransport.cs} (92%) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index b5836f3d99..a6bdffad6c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -25,7 +25,7 @@ public OtlpProtobufMetricExporter(Func getResource, ConnectionStringBu this.getResource = getResource; - this.otlpProtobufSerializer = new OtlpProtobufSerializer(MetricEtwDataTransport.Instance, connectionStringBuilder, prepopulatedMetricDimensions); + this.otlpProtobufSerializer = new OtlpProtobufSerializer(MetricWindowsEventTracingDataTransport.Instance, connectionStringBuilder, prepopulatedMetricDimensions); } public ExportResult Export(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 9ac707ab44..78fcd1cce8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -43,12 +43,12 @@ internal TlvMetricExporter(ConnectionStringBuilder connectionStringBuilder, IRea } var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); - this.metricDataTransport = new MetricUnixDataTransport(unixDomainSocketPath); + this.metricDataTransport = new MetricUnixDomainSocketDataTransport(unixDomainSocketPath); break; case TransportProtocol.Unspecified: if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - this.metricDataTransport = MetricEtwDataTransport.Instance; + this.metricDataTransport = MetricWindowsEventTracingDataTransport.Instance; break; } else @@ -77,7 +77,7 @@ public void Dispose() { // The ETW data transport singleton on Windows should NOT be disposed. // On Linux, Unix Domain Socket is used and should be disposed. - if (this.metricDataTransport != MetricEtwDataTransport.Instance) + if (this.metricDataTransport != MetricWindowsEventTracingDataTransport.Instance) { this.metricDataTransport.Dispose(); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs similarity index 89% rename from src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs index c30fa6e401..4faa04560f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs @@ -5,13 +5,13 @@ namespace OpenTelemetry.Exporter.Geneva; -internal sealed class MetricUnixDataTransport : IMetricDataTransport +internal sealed class MetricUnixDomainSocketDataTransport : IMetricDataTransport { private readonly int fixedPayloadLength; private readonly UnixDomainSocketDataTransport udsDataTransport; private bool isDisposed; - public MetricUnixDataTransport( + public MetricUnixDomainSocketDataTransport( string unixDomainSocketPath, int timeoutMilliseconds = UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs similarity index 92% rename from src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs rename to src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs index 3b3088a9a8..becbcf7ead 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricEtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs @@ -9,13 +9,13 @@ namespace OpenTelemetry.Exporter.Geneva; [EventSource(Name = "OpenTelemetryGenevaMetricExporter", Guid = "{edc24920-e004-40f6-a8e1-0e6e48f39d84}")] -internal sealed class MetricEtwDataTransport : EventSource, IMetricDataTransport +internal sealed class MetricWindowsEventTracingDataTransport : EventSource, IMetricDataTransport { private const int OtlpProtobufMetricEventId = 81; private readonly int fixedPayloadEndIndex; private bool isDisposed; - private MetricEtwDataTransport() + private MetricWindowsEventTracingDataTransport() { unsafe { @@ -23,7 +23,7 @@ private MetricEtwDataTransport() } } - public static MetricEtwDataTransport Instance { get; private set; } = new(); + public static MetricWindowsEventTracingDataTransport Instance { get; private set; } = new(); [NonEvent] #if NET diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index aaf386a50c..98ae138cb7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -249,11 +249,11 @@ public void MultipleCallsOnWindowsReusesSingletonEtwDataTransport() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - var singleton = MetricEtwDataTransport.Instance; + var singleton = MetricWindowsEventTracingDataTransport.Instance; this.EmitMetrics("one"); - Assert.Equal(singleton, MetricEtwDataTransport.Instance); + Assert.Equal(singleton, MetricWindowsEventTracingDataTransport.Instance); this.EmitMetrics("two"); - Assert.Equal(singleton, MetricEtwDataTransport.Instance); + Assert.Equal(singleton, MetricWindowsEventTracingDataTransport.Instance); } } From 6026a05cf6e1198b94dfa2f92d852882b6fc94b7 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:03:57 +0000 Subject: [PATCH 1280/1499] [Exporter.InfluxDB] Replace .NET 6 target with .NET 8 (#2116) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 3 +++ .../OpenTelemetry.Exporter.InfluxDB.csproj | 11 +++++------ .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 4 ++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 271706b380..aba0951e9c 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -10,6 +10,9 @@ in transitive dependencies. ([#2073](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2073)) +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2116](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2116)) + ## 1.0.0-alpha.3 Released 2023-Oct-13 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index 9da39c289a..5d6c507da1 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -1,16 +1,15 @@ - true - An OpenTelemetry .NET exporter that exports to InfluxDB - OpenTelemetry Authors - $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) + net8.0;$(NetStandardMinimumSupportedVersion) + true + An OpenTelemetry .NET exporter that exports to InfluxDB. Exporter.InfluxDB- - + true diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 155dd334f7..8c24d8c21e 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for InfluxDB Exporter for OpenTelemetry. - $(NetMinimumSupportedVersion) + net8.0 $(TargetFrameworks);net48;net472;net471;net47;net462 + Unit test project for InfluxDB Exporter for OpenTelemetry. From 1bdbf965fe13e1ace0d85331821b177f79e23705 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 30 Sep 2024 11:38:14 -0700 Subject: [PATCH 1281/1499] [repo] Tag component owners on issues (#2115) --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + .github/workflows/add-labels.yml | 1 + build/scripts/add-labels.psm1 | 34 ++++++++++++- build/scripts/build.psm1 | 59 ++++++++++++++++++++++ build/scripts/prepare-release.psm1 | 48 +++--------------- 6 files changed, 102 insertions(+), 42 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 849c72d016..c87b9935e8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,4 +1,5 @@ name: Bug report +title: "[bug] " description: Create a report to help us improve labels: ["bug"] body: diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 0c0b930633..0443264723 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,4 +1,5 @@ name: Feature request +title: "[feature request] " description: Suggest an idea for this project labels: ["enhancement"] body: diff --git a/.github/workflows/add-labels.yml b/.github/workflows/add-labels.yml index 23137c1aa8..3ba9ad161c 100644 --- a/.github/workflows/add-labels.yml +++ b/.github/workflows/add-labels.yml @@ -27,6 +27,7 @@ jobs: AddLabelsOnIssuesForComponentFoundInBody ` -issueNumber ${{ github.event.issue.number }} ` + -issueLabels '${{ join(github.event.issue.labels.*.name, ', ') }}' ` -issueBody $env:ISSUE_BODY env: GH_TOKEN: ${{ github.token }} diff --git a/build/scripts/add-labels.psm1 b/build/scripts/add-labels.psm1 index 39da844873..f219bcf09d 100644 --- a/build/scripts/add-labels.psm1 +++ b/build/scripts/add-labels.psm1 @@ -1,6 +1,9 @@ +Import-Module $PSScriptRoot\build.psm1 + function AddLabelsOnIssuesForComponentFoundInBody { param( [Parameter(Mandatory=$true)][int]$issueNumber, + [Parameter(Mandatory=$true)][string]$issueLabels, [Parameter(Mandatory=$true)][string]$issueBody ) @@ -10,7 +13,36 @@ function AddLabelsOnIssuesForComponentFoundInBody { Return } - gh issue edit $issueNumber --add-label $("comp:" + $match.Groups[1].Value.ToLower()) + $component = $match.Groups[1].Value.Trim() + + gh issue edit $issueNumber --add-label $("comp:" + $component.ToLower()) + + if ($issueLabels.Contains('bug') -or $issueLabels.Contains('enhancement')) + { + $componentOwners = $null + + FindComponentOwners ` + -component "OpenTelemetry.$component" ` + -componentOwners ([ref]$componentOwners) + + if ($componentOwners.Count -gt 0) + { + $componentOwnerApprovers = '' + foreach ($componentOwner in $componentOwners) + { + $componentOwnerApprovers += "@$componentOwner " + } + + $body = +@" +Tagging component owner(s). + +$componentOwnerApprovers +"@ + + gh issue comment $issueNumber --body $body + } + } } Export-ModuleMember -Function AddLabelsOnIssuesForComponentFoundInBody diff --git a/build/scripts/build.psm1 b/build/scripts/build.psm1 index 619fc8be17..9b7d560b60 100644 --- a/build/scripts/build.psm1 +++ b/build/scripts/build.psm1 @@ -80,3 +80,62 @@ function ResolveProject { } Export-ModuleMember -Function ResolveProject + +function FindComponentOwners { + param( + [Parameter(Mandatory=$true)][string]$component, + [Parameter()][string]$issueNumber, + [Parameter()][ref]$componentOwners + ) + + $projectPath = "src/$component/$component.csproj" + + if ((Test-Path -Path $projectPath) -eq $false) + { + if ([string]::IsNullOrEmpty($issueNumber) -eq $false) + { + gh issue comment $issueNumber ` + --body "I couldn't find the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component." + } + Return + } + + $projectContent = Get-Content -Path $projectPath + + $match = [regex]::Match($projectContent, '(.*)<\/MinVerTagPrefix>') + if ($match.Success -eq $false) + { + if ([string]::IsNullOrEmpty($issueNumber) -eq $false) + { + gh issue comment $issueNumber ` + --body "I couldn't find ``MinVerTagPrefix`` in the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component." + } + Return + } + + $minVerTagPrefix = $match.Groups[1].Value + + $projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "$minVerTagPrefix" -List | Select Path | Split-Path -Parent + + $componentOwnersContent = Get-Content '.github/component_owners.yml' -Raw + + $componentOwners.Value = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) + + foreach ($projectDir in $projectDirs) + { + $projectName = [System.IO.Path]::GetFileName($projectDir) + + $match = [regex]::Match($componentOwnersContent, "src\/$projectName\/:([\w\W\s]*?)src") + if ($match.Success -eq $true) + { + $matches = [regex]::Matches($match.Groups[1].Value, "-\s*(.*)") + foreach ($match in $matches) + { + $owner = $match.Groups[1].Value + $_ = $componentOwners.Value.Add($owner.Trim()) + } + } + } +} + +Export-ModuleMember -Function FindComponentOwners diff --git a/build/scripts/prepare-release.psm1 b/build/scripts/prepare-release.psm1 index 4ddde60b83..50b0f45cca 100644 --- a/build/scripts/prepare-release.psm1 +++ b/build/scripts/prepare-release.psm1 @@ -1,3 +1,5 @@ +Import-Module $PSScriptRoot\build.psm1 + function CreatePullRequestToUpdateChangelogsAndPublicApis { param( [Parameter(Mandatory=$true)][string]$gitRepository, @@ -354,48 +356,12 @@ function TagCodeOwnersOnOrRunWorkflowForRequestReleaseIssue { Return } - $projectPath = "src/$component/$component.csproj" - - if ((Test-Path -Path $projectPath) -eq $false) - { - gh issue comment $issueNumber ` - --body "I couldn't find the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component." - Return - } - - $projectContent = Get-Content -Path $projectPath - - $match = [regex]::Match($projectContent, '(.*)<\/MinVerTagPrefix>') - if ($match.Success -eq $false) - { - gh issue comment $issueNumber ` - --body "I couldn't find ``MinVerTagPrefix`` in the project file for the requested component. Please create a new release request and select a valid component or edit the description and set a valid component." - Return - } - - $minVerTagPrefix = $match.Groups[1].Value - - $projectDirs = Get-ChildItem -Path src/**/*.csproj | Select-String "$minVerTagPrefix" -List | Select Path | Split-Path -Parent - - $componentOwnersContent = Get-Content '.github/component_owners.yml' -Raw - - $componentOwners = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) - - foreach ($projectDir in $projectDirs) - { - $projectName = [System.IO.Path]::GetFileName($projectDir) + $componentOwners = $null - $match = [regex]::Match($componentOwnersContent, "src\/$projectName\/:([\w\W\s]*?)src") - if ($match.Success -eq $true) - { - $matches = [regex]::Matches($match.Groups[1].Value, "-\s*(.*)") - foreach ($match in $matches) - { - $owner = $match.Groups[1].Value - $_ = $componentOwners.Add($owner.Trim()) - } - } - } + FindComponentOwners ` + -component $component ` + -issueNumber $issueNumber ` + -componentOwners ([ref]$componentOwners) $requestedByUserPermission = gh api "repos/$gitRepository/collaborators/$requestedByUserName/permission" | ConvertFrom-Json From aadcdbb9d376ddbf3b921cdeb6a8aa645ac55843 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 30 Sep 2024 22:23:46 -0700 Subject: [PATCH 1282/1499] [repo] Include license files in packages (#2118) --- LICENSE => LICENSE.TXT | 0 build/Common.prod.props | 31 ++++++++----------- opentelemetry-dotnet-contrib.sln | 1 + src/Directory.Build.targets | 21 ++++++++----- .../OpenTelemetry.Exporter.Geneva.csproj | 1 + 5 files changed, 29 insertions(+), 25 deletions(-) rename LICENSE => LICENSE.TXT (100%) diff --git a/LICENSE b/LICENSE.TXT similarity index 100% rename from LICENSE rename to LICENSE.TXT diff --git a/build/Common.prod.props b/build/Common.prod.props index 52db728344..c402eaa2cc 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -6,10 +6,11 @@ https://github.com/open-telemetry/opentelemetry-dotnet-contrib https://OpenTelemetry.io Apache-2.0 + true + $(RepoRoot)\LICENSE.TXT opentelemetry-icon-color.png - OpenTelemetry authors + OpenTelemetry Authors Copyright The OpenTelemetry Authors - true $(MSBuildThisFileDirectory)/OpenTelemetryContrib.prod.ruleset $(NoWarn),1573,1712 $(Build_ArtifactStagingDirectory) @@ -19,13 +20,9 @@ - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + @@ -55,11 +52,14 @@ snupkg
    - - + + + + + - + true @@ -69,14 +69,9 @@ - - - - - + Condition="'$(EnablePublicApi)' != 'false'"> diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index e7d54517db..6a322c454e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution CODEOWNERS = CODEOWNERS CONTRIBUTING.md = CONTRIBUTING.md global.json = global.json + LICENSE.TXT = LICENSE.TXT NuGet.config = NuGet.config opentelemetry-dotnet-contrib.proj = opentelemetry-dotnet-contrib.proj README.md = README.md diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 986e063e61..0b683f6d32 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,18 +1,25 @@ + - - - all - runtime; build; native; contentfiles; analyzers - - - $([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)')) + + + + + + + diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index bc27891120..00e0b3e8ab 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -8,6 +8,7 @@ $(TargetFrameworks);net462 true An OpenTelemetry .NET exporter that exports to local ETW or UDS. + THIRD-PARTY-NOTICES.TXT $(NoWarn);SA1123;SA1310 Exporter.Geneva- From c22490ff1d51fbd672b77ede571ede99e8cbd669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 1 Oct 2024 07:42:22 +0200 Subject: [PATCH 1283/1499] [onecollector] remove Author tag (#2122) --- .../OpenTelemetry.Exporter.OneCollector.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 3b3c96d5e3..f7402e2fa1 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -3,7 +3,6 @@ true An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector - OpenTelemetry Authors net8.0;net6.0;netstandard2.1;netstandard2.0 $(TargetFrameworks);net462 Exporter.OneCollector- From a05d5f2d97ab8cdf690c0c6ef38817a29ef57d61 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 1 Oct 2024 12:21:42 -0700 Subject: [PATCH 1284/1499] [geneva] Test platform helpers and refactoring (#2120) --- build/OpenTelemetryContrib.test.ruleset | 1 + opentelemetry-dotnet-contrib.sln | 1 + .../GenevaLogExporterTests.cs | 240 +++++------ .../GenevaMetricExporterTests.cs | 255 ++++++------ .../GenevaTraceExporterTests.cs | 389 +++++++++--------- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 4 + .../UnixDomainSocketDataTransportTests.cs | 291 +++++++------ test/Shared/PlatformHelpers.cs | 98 +++++ 8 files changed, 660 insertions(+), 619 deletions(-) create mode 100644 test/Shared/PlatformHelpers.cs diff --git a/build/OpenTelemetryContrib.test.ruleset b/build/OpenTelemetryContrib.test.ruleset index 9818eca018..fc3130bec8 100644 --- a/build/OpenTelemetryContrib.test.ruleset +++ b/build/OpenTelemetryContrib.test.ruleset @@ -40,6 +40,7 @@ + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6a322c454e..68d49b391e 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -359,6 +359,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{70CA77 test\Shared\EnabledOnDockerPlatformTheoryAttribute.cs = test\Shared\EnabledOnDockerPlatformTheoryAttribute.cs test\Shared\EventSourceTestHelper.cs = test\Shared\EventSourceTestHelper.cs test\Shared\InMemoryEventListener.cs = test\Shared\InMemoryEventListener.cs + test\Shared\PlatformHelpers.cs = test\Shared\PlatformHelpers.cs test\Shared\SkipUnlessEnvVarFoundFactAttribute.cs = test\Shared\SkipUnlessEnvVarFoundFactAttribute.cs test\Shared\SkipUnlessEnvVarFoundTheoryAttribute.cs = test\Shared\SkipUnlessEnvVarFoundTheoryAttribute.cs test\Shared\TestActivityExportProcessor.cs = test\Shared\TestActivityExportProcessor.cs diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 2d2c810fd2..3b1cfe5cd9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging; using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Logs; +using OpenTelemetry.Tests; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests; @@ -93,32 +94,26 @@ public void InvalidConnectionString(string connectionString) }); } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void IncompatibleConnectionString_Windows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; + var exception = Assert.Throws(() => { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q" }; - var exception = Assert.Throws(() => - { - using var exporter = new GenevaLogExporter(exporterOptions); - }); - Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); - } + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal("Unix domain socket should not be used on Windows.", exception.Message); } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void IncompatibleConnectionString_Linux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; + var exception = Assert.Throws(() => { - var exporterOptions = new GenevaExporterOptions() { ConnectionString = "EtwSession=OpenTelemetry" }; - var exception = Assert.Throws(() => - { - using var exporter = new GenevaLogExporter(exporterOptions); - }); - Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); - } + using var exporter = new GenevaLogExporter(exporterOptions); + }); + Assert.Equal("ETW cannot be used on non-Windows operating systems.", exception.Message); } [Theory] @@ -772,27 +767,57 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void SuccessfulExport_Windows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + var exporterOptions = new GenevaExporterOptions() { - var exporterOptions = new GenevaExporterOptions() + PrepopulatedFields = new Dictionary { - PrepopulatedFields = new Dictionary + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }; + + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddGenevaLogExporter(options => { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary + { + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }); + })); + + var logger = loggerFactory.CreateLogger(); + + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); + } + + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] + public void SuccessfulExport_Linux() + { + string path = GenerateTempFilePath(); + var logRecordList = new List(); + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(options => { options.AddGenevaLogExporter(options => { - options.ConnectionString = "EtwSession=OpenTelemetry"; + options.ConnectionString = "Endpoint=unix:" + path; options.PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", @@ -800,101 +825,65 @@ public void SuccessfulExport_Windows() ["cloud.roleVer"] = "9.0.15289.2", }; }); + options.AddInMemoryExporter(logRecordList); })); + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; - var logger = loggerFactory.CreateLogger(); - - logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); - } - } - - [Fact] - public void SuccessfulExportOnLinux() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - string path = GenerateTempFilePath(); - var logRecordList = new List(); - try + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + using var exporter = new MsgPackLogExporter(new GenevaExporterOptions { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - - using var loggerFactory = LoggerFactory.Create(builder => builder - .AddOpenTelemetry(options => - { - options.AddGenevaLogExporter(options => - { - options.ConnectionString = "Endpoint=unix:" + path; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }); - options.AddInMemoryExporter(logRecordList); - })); - using var serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 10000; - - // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - using var exporter = new MsgPackLogExporter(new GenevaExporterOptions + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary { - ConnectionString = "Endpoint=unix:" + path, - PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }); + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); - // Emit a LogRecord and grab a copy of internal buffer for validation. - var logger = loggerFactory.CreateLogger(); + // Emit a LogRecord and grab a copy of internal buffer for validation. + var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); - // logRecordList should have a singleLogRecord entry after the logger.LogInformation call - Assert.Single(logRecordList); + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); - int messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; + int messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); - // Validation - Assert.Equal(messagePackDataSize, receivedDataSize); + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); - logRecordList.Clear(); + logRecordList.Clear(); - // Emit log on a different thread to test for multithreading scenarios - var thread = new Thread(() => - { - logger.LogInformation("Hello from another thread {Food} {Price}.", "artichoke", 3.99); - }); - thread.Start(); - thread.Join(); + // Emit log on a different thread to test for multithreading scenarios + var thread = new Thread(() => + { + logger.LogInformation("Hello from another thread {Food} {Price}.", "artichoke", 3.99); + }); + thread.Start(); + thread.Join(); - // logRecordList should have a singleLogRecord entry after the logger.LogInformation call - Assert.Single(logRecordList); + // logRecordList should have a singleLogRecord entry after the logger.LogInformation call + Assert.Single(logRecordList); - messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; - receivedDataSize = serverSocket.Receive(receivedData); - Assert.Equal(messagePackDataSize, receivedDataSize); + messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; + receivedDataSize = serverSocket.Receive(receivedData); + Assert.Equal(messagePackDataSize, receivedDataSize); + } + finally + { + try + { + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } @@ -1313,12 +1302,10 @@ public void SerializationTestForEventId() } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void TLDLogExporter_Success_Windows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - using var loggerFactory = LoggerFactory.Create(builder => builder + using var loggerFactory = LoggerFactory.Create(builder => builder .AddOpenTelemetry(loggerOptions => { loggerOptions.AddGenevaLogExporter(exporterOptions => @@ -1333,25 +1320,17 @@ public void TLDLogExporter_Success_Windows() }); })); - var logger = loggerFactory.CreateLogger(); + var logger = loggerFactory.CreateLogger(); - logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); - } + logger.LogInformation("Hello from {Food} {Price}.", "artichoke", 3.99); } [Fact] public void AddGenevaExporterWithNamedOptions() { - string connectionString = null; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - connectionString = "EtwSession=OpenTelemetry"; - } - else - { - connectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q"; - } + var connectionString = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? "EtwSession=OpenTelemetry" + : "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q"; int defaultConfigureExporterOptionsInvocations = 0; int namedConfigureExporterOptionsInvocations = 0; @@ -1395,16 +1374,9 @@ public void AddGenevaExporterWithNamedOptions() [Fact] public void AddGenevaBatchExportProcessorOptions() { - string connectionString = null; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - connectionString = "EtwSession=OpenTelemetry"; - } - else - { - connectionString = "Endpoint=unix:" + GenerateTempFilePath(); - } + var connectionString = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? "EtwSession=OpenTelemetry" + : "Endpoint=unix:" + GenerateTempFilePath(); var sp = new ServiceCollection(); sp.AddOpenTelemetry().WithLogging(builder => builder diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 98ae138cb7..62d1176481 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Metrics; +using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; using static OpenTelemetry.Exporter.Geneva.Tests.MetricsContract; @@ -108,153 +109,147 @@ public void CannotUseReservedDimensionsInPrepopulatedFields() Assert.Throws(() => { exporterOptions.PrepopulatedMetricDimensions = prepopulatedMetricDimensions; }); } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public async Task SuccessfulExportOnLinux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - string path = GenerateTempFilePath(); - var exportedItems = new List(); + string path = GenerateTempFilePath(); + var exportedItems = new List(); - using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); - var counter = meter.CreateCounter("counter"); + using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); + var counter = meter.CreateCounter("counter"); - using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); - var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); + using var inMemoryMeter = new Meter("InMemoryExportOnLinux", "0.0.1"); + var inMemoryCounter = inMemoryMeter.CreateCounter("counter"); - try + try + { + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + TemporalityPreference = MetricReaderTemporalityPreference.Delta, + }; - using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) - { - TemporalityPreference = MetricReaderTemporalityPreference.Delta, - }; - - // Set up two different providers as only one Metric Processor is allowed. - // TODO: Simplify the setup when multiple Metric processors are allowed. - using var meterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("SuccessfulExportOnLinux") - .AddGenevaMetricExporter(options => - { - options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; - options.MetricExportIntervalMilliseconds = 5000; - }) - .Build(); - - using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() - .AddMeter("InMemoryExportOnLinux") - .AddReader(inMemoryReader) - .Build(); - - using var serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 15000; - - // Create a test exporter to get byte data for validation of the data received via Socket. - var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; - using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); - - // Emit a metric and grab a copy of internal buffer for validation. - counter.Add( - 123, - new KeyValuePair("tag1", "value1"), - new KeyValuePair("tag2", "value2")); - - inMemoryCounter.Add( - 123, - new KeyValuePair("tag1", "value1"), - new KeyValuePair("tag2", "value2")); - - // exportedItems list should have a single entry after the MetricReader.Collect call - inMemoryReader.Collect(); - - Assert.Single(exportedItems); - - var metric = exportedItems[0]; - var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); - metricPointsEnumerator.MoveNext(); - var metricPoint = metricPointsEnumerator.Current; - var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); - var metricData = new MetricData { UInt64Value = metricDataValue }; - - metricPoint.TryGetExemplars(out var exemplars); - var bodyLength = exporter.SerializeMetricWithTLV( - MetricEventType.ULongMetric, - metric.Name, - metricPoint.EndTime.ToFileTime(), - metricPoint.Tags, - metricData, - MetricType.LongSum, - exemplars, - out _, - out _); - - // Wait a little more than the ExportInterval for the exporter to export the data. - await Task.Delay(5500); - - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); - - var fixedPayloadLength = (int)typeof(TlvMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); - - // The whole payload is sent to the Unix Domain Socket - // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload - Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); - - var stream = new KaitaiStream(receivedData); - var data = new MetricsContract(stream); - var userData = data.Body as UserdataV2; - var fields = userData.Fields; - - Assert.Contains(fields, field => field.Type == PayloadTypes.MetricName && (field.Value as WrappedString).Value == metric.Name); - Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == "OTelMonitoringAccount"); - Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == "OTelMetricNamespace"); - - var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleUint64Value).Value as SingleUint64ValueV2; - Assert.Equal(metricDataValue, valueSection.Value); - - var dimensions = fields.FirstOrDefault(field => field.Type == PayloadTypes.Dimensions).Value as Dimensions; - Assert.Equal(2, dimensions.NumDimensions); - - int i = 0; - foreach (var tag in metricPoint.Tags) + // Set up two different providers as only one Metric Processor is allowed. + // TODO: Simplify the setup when multiple Metric processors are allowed. + using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("SuccessfulExportOnLinux") + .AddGenevaMetricExporter(options => { - Assert.Equal(tag.Key, dimensions.DimensionsNames[i].Value); - Assert.Equal(tag.Value, dimensions.DimensionsValues[i].Value); - i++; - } + options.ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace"; + options.MetricExportIntervalMilliseconds = 5000; + }) + .Build(); + + using var inMemoryMeterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter("InMemoryExportOnLinux") + .AddReader(inMemoryReader) + .Build(); + + using var serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 15000; + + // Create a test exporter to get byte data for validation of the data received via Socket. + var exporterOptions = new GenevaMetricExporterOptions() { ConnectionString = $"Endpoint=unix:{path};Account=OTelMonitoringAccount;Namespace=OTelMetricNamespace" }; + using var exporter = new TlvMetricExporter(new ConnectionStringBuilder(exporterOptions.ConnectionString), exporterOptions.PrepopulatedMetricDimensions); + + // Emit a metric and grab a copy of internal buffer for validation. + counter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + inMemoryCounter.Add( + 123, + new KeyValuePair("tag1", "value1"), + new KeyValuePair("tag2", "value2")); + + // exportedItems list should have a single entry after the MetricReader.Collect call + inMemoryReader.Collect(); + + Assert.Single(exportedItems); + + var metric = exportedItems[0]; + var metricPointsEnumerator = metric.GetMetricPoints().GetEnumerator(); + metricPointsEnumerator.MoveNext(); + var metricPoint = metricPointsEnumerator.Current; + var metricDataValue = Convert.ToUInt64(metricPoint.GetSumLong()); + var metricData = new MetricData { UInt64Value = metricDataValue }; + + metricPoint.TryGetExemplars(out var exemplars); + var bodyLength = exporter.SerializeMetricWithTLV( + MetricEventType.ULongMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData, + MetricType.LongSum, + exemplars, + out _, + out _); + + // Wait a little more than the ExportInterval for the exporter to export the data. + await Task.Delay(5500); + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); + + var fixedPayloadLength = (int)typeof(TlvMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); + + // The whole payload is sent to the Unix Domain Socket + // BinaryHeader (fixed payload) + variable payload which starts with MetricPayload + Assert.Equal(bodyLength + fixedPayloadLength, receivedDataSize); + + var stream = new KaitaiStream(receivedData); + var data = new MetricsContract(stream); + var userData = data.Body as UserdataV2; + var fields = userData.Fields; + + Assert.Contains(fields, field => field.Type == PayloadTypes.MetricName && (field.Value as WrappedString).Value == metric.Name); + Assert.Contains(fields, field => field.Type == PayloadTypes.AccountName && (field.Value as WrappedString).Value == "OTelMonitoringAccount"); + Assert.Contains(fields, field => field.Type == PayloadTypes.NamespaceName && (field.Value as WrappedString).Value == "OTelMetricNamespace"); + + var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.SingleUint64Value).Value as SingleUint64ValueV2; + Assert.Equal(metricDataValue, valueSection.Value); + + var dimensions = fields.FirstOrDefault(field => field.Type == PayloadTypes.Dimensions).Value as Dimensions; + Assert.Equal(2, dimensions.NumDimensions); + + int i = 0; + foreach (var tag in metricPoint.Tags) + { + Assert.Equal(tag.Key, dimensions.DimensionsNames[i].Value); + Assert.Equal(tag.Value, dimensions.DimensionsValues[i].Value); + i++; + } - Assert.Equal((ushort)MetricEventType.TLV, data.EventId); - Assert.Equal(bodyLength, data.LenBody); + Assert.Equal((ushort)MetricEventType.TLV, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } + finally + { + try + { + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void MultipleCallsOnWindowsReusesSingletonEtwDataTransport() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var singleton = MetricWindowsEventTracingDataTransport.Instance; - this.EmitMetrics("one"); - Assert.Equal(singleton, MetricWindowsEventTracingDataTransport.Instance); - this.EmitMetrics("two"); - Assert.Equal(singleton, MetricWindowsEventTracingDataTransport.Instance); - } + var singleton = MetricWindowsEventTracingDataTransport.Instance; + this.EmitMetrics("one"); + Assert.Equal(singleton, MetricWindowsEventTracingDataTransport.Instance); + this.EmitMetrics("two"); + Assert.Equal(singleton, MetricWindowsEventTracingDataTransport.Instance); } private void EmitMetrics(string attempt) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index e91078de79..066a4ccbec 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter.Geneva.MsgPack; +using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; @@ -93,29 +94,26 @@ public void GenevaTraceExporter_constructor_Invalid_Input() Assert.Null(exception); } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void GenevaTraceExporter_constructor_Invalid_Input_Windows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // no ETW session name + Assert.Throws(() => { - // no ETW session name - Assert.Throws(() => + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "key=value", - }); + ConnectionString = "key=value", }); + }); - // empty ETW session name - Assert.Throws(() => + // empty ETW session name + Assert.Throws(() => + { + using var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - using var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "EtwSession=", - }); + ConnectionString = "EtwSession=", }); - } + }); } [Fact] @@ -130,60 +128,57 @@ public void GenevaTraceExporter_TableNameMappings_SpecialCharacters() }); } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void GenevaTraceExporter_Success_Windows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); - // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "EtwSession=OpenTelemetry"; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); - - var source = new ActivitySource(sourceName); - using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) + // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => { - parent.SetTag("http.method", "GET"); - parent.SetTag("http.url", "https://localhost/wiki/Rabbit"); - using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) + options.ConnectionString = "EtwSession=OpenTelemetry"; + options.PrepopulatedFields = new Dictionary { - child.SetTag("http.method", "GET"); - child.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); - child.SetTag("http.status_code", 404); - } - - parent?.SetTag("http.status_code", 200); - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); - var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); - using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) + var source = new ActivitySource(sourceName); + using (var parent = source.StartActivity("HttpIn", ActivityKind.Server)) + { + parent.SetTag("http.method", "GET"); + parent.SetTag("http.url", "https://localhost/wiki/Rabbit"); + using (var child = source.StartActivity("HttpOut", ActivityKind.Client)) { + child.SetTag("http.method", "GET"); + child.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + child.SetTag("http.status_code", 404); } - using (var activity = source.StartActivity("Bar")) - { - activity.SetStatus(Status.Error); - } + parent?.SetTag("http.status_code", 200); + } - using (var activity = source.StartActivity("Baz")) - { - activity.SetStatus(Status.Ok); - } + var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); + using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) + { + } + + using (var activity = source.StartActivity("Bar")) + { + activity.SetStatus(Status.Error); + } + + using (var activity = source.StartActivity("Baz")) + { + activity.SetStatus(Status.Ok); } } @@ -337,181 +332,172 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - string path = GetRandomFilePath(); + string path = GetRandomFilePath(); - // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address - try - { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "Endpoint=unix:" + path; - }) - .Build(); + // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address + try + { + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "Endpoint=unix:" + path; + }) + .Build(); - // GenevaExporter would not throw if it was not able to connect to the UDS socket in ctor. It would - // keep attempting to connect to the socket when sending telemetry. - Assert.True(true, "GenevaTraceExporter should not fail in constructor."); - } - catch (SocketException ex) - { - // There is no one to listent to the socket. - Assert.Contains("Cannot assign requested address", ex.Message); - } + // GenevaExporter would not throw if it was not able to connect to the UDS socket in ctor. It would + // keep attempting to connect to the socket when sending telemetry. + Assert.True(true, "GenevaTraceExporter should not fail in constructor."); + } + catch (SocketException ex) + { + // There is no one to listent to the socket. + Assert.Contains("Cannot assign requested address", ex.Message); + } - try - { - var exporter = new GenevaTraceExporter(new GenevaExporterOptions - { - ConnectionString = "Endpoint=unix:" + path, - }); - Assert.True(true, "GenevaTraceExporter should not fail in constructor."); - } - catch (SocketException ex) + try + { + var exporter = new GenevaTraceExporter(new GenevaExporterOptions { - // There is no one to listent to the socket. - Assert.Contains("Cannot assign requested address", ex.Message); - } + ConnectionString = "Endpoint=unix:" + path, + }); + Assert.True(true, "GenevaTraceExporter should not fail in constructor."); + } + catch (SocketException ex) + { + // There is no one to listent to the socket. + Assert.Contains("Cannot assign requested address", ex.Message); } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void GenevaTraceExporter_Success_Linux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GetRandomFilePath(); + try { - string path = GetRandomFilePath(); - try - { - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => - { - options.ConnectionString = "Endpoint=unix:" + path; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); - using Socket serverSocket = server.Accept(); - serverSocket.ReceiveTimeout = 10000; - - // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. - var exporter = new MsgPackTraceExporter(new GenevaExporterOptions + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => { - ConnectionString = "Endpoint=unix:" + path, - PrepopulatedFields = new Dictionary + options.ConnectionString = "Endpoint=unix:" + path; + options.PrepopulatedFields = new Dictionary { ["cloud.role"] = "BusyWorker", ["cloud.roleInstance"] = "CY1SCH030021417", ["cloud.roleVer"] = "9.0.15289.2", - }, - }); - - // Emit trace and grab a copy of internal buffer for validation. - var source = new ActivitySource(sourceName); - int messagePackDataSize = 0; + }; + }) + .Build(); + using Socket serverSocket = server.Accept(); + serverSocket.ReceiveTimeout = 10000; - using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) + // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. + var exporter = new MsgPackTraceExporter(new GenevaExporterOptions + { + ConnectionString = "Endpoint=unix:" + path, + PrepopulatedFields = new Dictionary { - messagePackDataSize = exporter.SerializeActivity(activity).Count; - } + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }, + }); - // Read the data sent via socket. - var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + // Emit trace and grab a copy of internal buffer for validation. + var source = new ActivitySource(sourceName); + int messagePackDataSize = 0; + + using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) + { + messagePackDataSize = exporter.SerializeActivity(activity).Count; + } + + // Read the data sent via socket. + var receivedData = new byte[1024]; + int receivedDataSize = serverSocket.Receive(receivedData); - // Validation - Assert.Equal(messagePackDataSize, receivedDataSize); + // Validation + Assert.Equal(messagePackDataSize, receivedDataSize); - // Create activity on a different thread to test for multithreading scenarios - var thread = new Thread(() => + // Create activity on a different thread to test for multithreading scenarios + var thread = new Thread(() => + { + using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) { - using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) - { - messagePackDataSize = exporter.SerializeActivity(activity).Count; - } - }); - thread.Start(); - thread.Join(); + messagePackDataSize = exporter.SerializeActivity(activity).Count; + } + }); + thread.Start(); + thread.Join(); - receivedDataSize = serverSocket.Receive(receivedData); - Assert.Equal(messagePackDataSize, receivedDataSize); - } - catch (Exception) + receivedDataSize = serverSocket.Receive(receivedData); + Assert.Equal(messagePackDataSize, receivedDataSize); + } + catch (Exception) + { + throw; + } + finally + { + try { - throw; + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Windows)] public void TLDTraceExporter_Success_Windows() { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // Set the ActivitySourceName to the unique value of the test method name to avoid interference with - // the ActivitySource used by other unit tests. - var sourceName = GetTestMethodName(); + // Set the ActivitySourceName to the unique value of the test method name to avoid interference with + // the ActivitySource used by other unit tests. + var sourceName = GetTestMethodName(); - // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. - using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .SetSampler(new AlwaysOnSampler()) - .AddSource(sourceName) - .AddGenevaTraceExporter(options => + // TODO: Setup a mock or spy for eventLogger to assert that eventLogger.LogInformationalEvent is actually called. + using var tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetSampler(new AlwaysOnSampler()) + .AddSource(sourceName) + .AddGenevaTraceExporter(options => + { + options.ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true"; + options.PrepopulatedFields = new Dictionary { - options.ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true"; - options.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }) - .Build(); + ["cloud.role"] = "BusyWorker", + ["cloud.roleInstance"] = "CY1SCH030021417", + ["cloud.roleVer"] = "9.0.15289.2", + }; + }) + .Build(); - var source = new ActivitySource(sourceName); - using (var activity = source.StartActivity("SayHello")) - { - activity?.SetTag("foo", 1); - activity?.SetTag("bar", "Hello, World!"); + var source = new ActivitySource(sourceName); + using (var activity = source.StartActivity("SayHello")) + { + activity?.SetTag("foo", 1); + activity?.SetTag("bar", "Hello, World!"); #pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array - activity?.SetTag("baz", new int[] { 1, 2, 3 }); + activity?.SetTag("baz", new int[] { 1, 2, 3 }); #pragma warning restore CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array - activity?.SetStatus(ActivityStatusCode.Ok); - } + activity?.SetStatus(ActivityStatusCode.Ok); } } @@ -560,16 +546,9 @@ public void AddGenevaTraceExporterNamedOptionsSupport() [Fact] public void AddGenevaBatchExportProcessorOptions() { - string connectionString = null; - - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - connectionString = "EtwSession=OpenTelemetry"; - } - else - { - connectionString = "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q"; - } + var connectionString = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? "EtwSession=OpenTelemetry" + : "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q"; var sp = new ServiceCollection(); sp.AddOpenTelemetry().WithTracing(builder => builder diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 8f3e724c44..6a9cf6603c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -32,6 +32,10 @@ + + + + Proto diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index fa879d1ed2..753de5c7e0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -3,195 +3,186 @@ using System.Net.Sockets; using System.Reflection; -using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.Transports; +using OpenTelemetry.Tests; using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests; public class UnixDomainSocketDataTransportTests { - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void UnixDomainSocketDataTransport_Success_Linux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + try + { + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + using Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + } + catch (Exception) + { + throw; + } + finally { - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); try { - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - - // Client - using var dataTransport = new UnixDomainSocketDataTransport(path); - using Socket serverSocket = server.Accept(); - var data = new byte[] { 12, 34, 56 }; - dataTransport.Send(data, data.Length); - var receivedData = new byte[5]; - serverSocket.Receive(receivedData); - Assert.Equal(data[0], receivedData[0]); - Assert.Equal(data[1], receivedData[1]); - Assert.Equal(data[2], receivedData[2]); - } - catch (Exception) - { - throw; + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server.Bind(endpoint); + server.Listen(1); + var data = new byte[1024]; + var i = 0; + using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests + var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; + try { - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); - using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server.Bind(endpoint); - server.Listen(1); - var data = new byte[1024]; - var i = 0; - using var dataTransport = new UnixDomainSocketDataTransport(path, 5000); // Set low timeout for faster tests - var socket = typeof(UnixDomainSocketDataTransport).GetField("socket", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(dataTransport) as Socket; - try + // Client + using Socket serverSocket = server.Accept(); + while (true) { - // Client - using Socket serverSocket = server.Accept(); - while (true) - { - Console.WriteLine($"Sending request #{i++}."); - socket.Send(data, data.Length, SocketFlags.None); - } - - // The server is not processing sent data (because of heavy load, etc.) + Console.WriteLine($"Sending request #{i++}."); + socket.Send(data, data.Length, SocketFlags.None); } - catch (Exception) + + // The server is not processing sent data (because of heavy load, etc.) + } + catch (Exception) + { + // At this point, the outgoing buffer for the socket must be full, + // because the last Send failed. + // Send again and assert the exception to confirm: + Assert.Throws(() => + { + Console.WriteLine($"Sending request #{i}."); + socket.Send(data, data.Length, SocketFlags.None); + }); + } + finally + { + try { - // At this point, the outgoing buffer for the socket must be full, - // because the last Send failed. - // Send again and assert the exception to confirm: - Assert.Throws(() => - { - Console.WriteLine($"Sending request #{i}."); - socket.Send(data, data.Length, SocketFlags.None); - }); + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } - [Fact] + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void UnixDomainSocketDataTransport_ServerRestart_Linux() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + Console.WriteLine("Test starts."); + string path = GetRandomFilePath(); + var endpoint = new UnixDomainSocketEndPoint(path); + try { - Console.WriteLine("Test starts."); - string path = GetRandomFilePath(); - var endpoint = new UnixDomainSocketEndPoint(path); + var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + + // LingerOption lo = new LingerOption(false, 0); + // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); + server.Bind(endpoint); + server.Listen(1); + + // Client + using var dataTransport = new UnixDomainSocketDataTransport(path); + Socket serverSocket = server.Accept(); + var data = new byte[] { 12, 34, 56 }; + dataTransport.Send(data, data.Length); + var receivedData = new byte[5]; + serverSocket.Receive(receivedData); + Assert.Equal(data[0], receivedData[0]); + Assert.Equal(data[1], receivedData[1]); + Assert.Equal(data[2], receivedData[2]); + + Console.WriteLine("Successfully sent a message."); + + // Emulate server stops + serverSocket.Shutdown(SocketShutdown.Both); + serverSocket.Disconnect(false); + serverSocket.Dispose(); + + if (server.Connected) + { + // On MacOS the 'server' socket never shows up as connected + // so trying to shutdown/disconnect throws an exception. + server.Shutdown(SocketShutdown.Both); + server.Disconnect(false); + } + + server.Dispose(); try { - var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - - // LingerOption lo = new LingerOption(false, 0); - // server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, lo); - server.Bind(endpoint); - server.Listen(1); - - // Client - using var dataTransport = new UnixDomainSocketDataTransport(path); - Socket serverSocket = server.Accept(); - var data = new byte[] { 12, 34, 56 }; - dataTransport.Send(data, data.Length); - var receivedData = new byte[5]; - serverSocket.Receive(receivedData); - Assert.Equal(data[0], receivedData[0]); - Assert.Equal(data[1], receivedData[1]); - Assert.Equal(data[2], receivedData[2]); - - Console.WriteLine("Successfully sent a message."); - - // Emulate server stops - serverSocket.Shutdown(SocketShutdown.Both); - serverSocket.Disconnect(false); - serverSocket.Dispose(); - - if (server.Connected) - { - // On MacOS the 'server' socket never shows up as connected - // so trying to shutdown/disconnect throws an exception. - server.Shutdown(SocketShutdown.Both); - server.Disconnect(false); - } - - server.Dispose(); - try - { - File.Delete(path); - } - catch - { - } - - Console.WriteLine("Destroyed server."); - - Console.WriteLine("Client will fail during Send, and should throw an Exception"); - Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); - Console.WriteLine("Client will fail during Reconnect, and should throw an Exception"); - Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); - - using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); - server2.Bind(endpoint); - server2.Listen(1); - Console.WriteLine("Started a new server and listening."); - - var data2 = new byte[] { 34, 56, 78 }; - dataTransport.Send(data2, data2.Length); - Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); - - using Socket serverSocket2 = server2.Accept(); - Console.WriteLine("The new server is ready and accepting connections."); - var receivedData2 = new byte[5]; - serverSocket2.Receive(receivedData2); - Console.WriteLine("Server received a messge."); - Assert.Equal(data2[0], receivedData2[0]); - Assert.Equal(data2[1], receivedData2[1]); - Assert.Equal(data2[2], receivedData2[2]); + File.Delete(path); + } + catch + { } - catch (Exception) + + Console.WriteLine("Destroyed server."); + + Console.WriteLine("Client will fail during Send, and should throw an Exception"); + Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); + Console.WriteLine("Client will fail during Reconnect, and should throw an Exception"); + Assert.ThrowsAny(() => dataTransport.Send(data, data.Length)); + + using var server2 = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + server2.Bind(endpoint); + server2.Listen(1); + Console.WriteLine("Started a new server and listening."); + + var data2 = new byte[] { 34, 56, 78 }; + dataTransport.Send(data2, data2.Length); + Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); + + using Socket serverSocket2 = server2.Accept(); + Console.WriteLine("The new server is ready and accepting connections."); + var receivedData2 = new byte[5]; + serverSocket2.Receive(receivedData2); + Console.WriteLine("Server received a messge."); + Assert.Equal(data2[0], receivedData2[0]); + Assert.Equal(data2[1], receivedData2[1]); + Assert.Equal(data2[2], receivedData2[2]); + } + catch (Exception) + { + throw; + } + finally + { + try { - throw; + File.Delete(path); } - finally + catch { - try - { - File.Delete(path); - } - catch - { - } } } } diff --git a/test/Shared/PlatformHelpers.cs b/test/Shared/PlatformHelpers.cs new file mode 100644 index 0000000000..60d876c609 --- /dev/null +++ b/test/Shared/PlatformHelpers.cs @@ -0,0 +1,98 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +#pragma warning disable SA1649 // File name should match first type name +#pragma warning disable SA1402 // File may only contain a single type + +using System.Runtime.InteropServices; +using Xunit; + +namespace OpenTelemetry.Tests; + +internal enum TestPlatform +{ + Unknown = 0, + Windows = 1, + Linux = 2, + OSX = 3, +} + +internal sealed class TestPlatformHelpers +{ + public static bool IsProcessElevated(TestPlatform platform) + { + if (platform != TestPlatform.Linux) + { + // TODO: Add support for this check on other platforms as needed. + throw new NotImplementedException(); + } + + uint userId = SystemNativeUnix.GetEUid(); + return userId == 0; + } + + // From: https://github.com/dotnet/corefx/blob/v2.2.8/src/Common/src/Interop/Unix/System.Native/Interop.GetEUid.cs + private static class SystemNativeUnix + { +#pragma warning disable CA5392 // Use DefaultDllImportSearchPaths attribute for P/Invokes + [DllImport("libc", SetLastError = true)] + internal static extern uint GetEUid(); +#pragma warning restore CA5392 // Use DefaultDllImportSearchPaths attribute for P/Invokes + } +} + +internal sealed class SkipUnlessPlatformMatchesFactAttribute : FactAttribute +{ + public SkipUnlessPlatformMatchesFactAttribute(TestPlatform platform, bool requireElevatedProcess = false) + { + var osPlatform = platform switch + { + TestPlatform.Windows => OSPlatform.Windows, + TestPlatform.Linux => OSPlatform.Linux, + TestPlatform.OSX => OSPlatform.OSX, + _ => throw new NotSupportedException($"TestPlatform '{platform}' is not supported"), + }; + + if (!RuntimeInformation.IsOSPlatform(osPlatform)) + { + this.Skip = $"Skipped because current platform does not match requested '{platform}' platform."; + return; + } + + if (requireElevatedProcess + && !TestPlatformHelpers.IsProcessElevated(platform)) + { + this.Skip = $"Skipped because current process isn't elevated."; + return; + } + } +} + +internal sealed class SkipUnlessPlatformMatchesTheoryAttribute : TheoryAttribute +{ + public SkipUnlessPlatformMatchesTheoryAttribute(TestPlatform platform, bool requireElevatedProcess = false) + { + var osPlatform = platform switch + { + TestPlatform.Windows => OSPlatform.Windows, + TestPlatform.Linux => OSPlatform.Linux, + TestPlatform.OSX => OSPlatform.OSX, + _ => throw new NotSupportedException($"TestPlatform '{platform}' is not supported"), + }; + + if (!RuntimeInformation.IsOSPlatform(osPlatform)) + { + this.Skip = $"Skipped because current platform does not match requested '{platform}' platform."; + return; + } + + if (requireElevatedProcess + && !TestPlatformHelpers.IsProcessElevated(platform)) + { + this.Skip = $"Skipped because current process isn't elevated."; + return; + } + } +} From d700e8ed5e34f316d6f65c799a9c72fe3b504d65 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Tue, 1 Oct 2024 19:47:52 +0000 Subject: [PATCH 1285/1499] [Exporter.OneCollector] Remove .NET 6 target (#2123) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- build/Common.nonprod.props | 1 + src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 3 +++ .../CompatibilitySuppressions.xml | 9 ++++++++- .../Internal/CallbackManager.cs | 2 +- .../Serialization/BatchSerializationResult.cs | 2 +- .../CommonSchemaJsonSerializationHelper.cs | 4 ++-- .../Internal/Transports/TransportSendRequest.cs | 2 +- .../OpenTelemetry.Exporter.OneCollector.csproj | 8 ++++---- ...nTelemetry.Exporter.OneCollector.Benchmarks.csproj | 11 +++++++---- .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 8 ++------ 10 files changed, 30 insertions(+), 20 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 1b7ed15854..9f866b82f1 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -30,6 +30,7 @@ $(OpenTelemetryCoreLatestVersion) $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net6.0 + net8.0 [2.8.2,3.0) [2.9.0,3.0) [1.6.3,2.0) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index ad0bb5a576..79451efd20 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported. + ([#2123](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2123)) + ## 1.10.0-alpha.1 Released 2024-Sep-06 diff --git a/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml b/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml index c1b34f2891..9d4d66e28f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml +++ b/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml @@ -2,11 +2,18 @@ + + CP0008 + T:OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType + lib/net6.0/OpenTelemetry.Exporter.OneCollector.dll + lib/netstandard2.1/OpenTelemetry.Exporter.OneCollector.dll + true + CP0008 T:OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType lib/net7.0/OpenTelemetry.Exporter.OneCollector.dll - lib/net6.0/OpenTelemetry.Exporter.OneCollector.dll + lib/netstandard2.1/OpenTelemetry.Exporter.OneCollector.dll true diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs index 513bcf83d5..ad33c02d29 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs @@ -20,7 +20,7 @@ public IDisposable Add(T callback) lock (this.lockObject) { -#if NET8_0_OR_GREATER +#if NET ObjectDisposedException.ThrowIf(this.disposed, nameof(CallbackManager)); #else if (this.disposed) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs index c3cc86222f..d7b6b94b86 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/BatchSerializationResult.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.OneCollector; internal readonly struct BatchSerializationResult { -#if NET8_0_OR_GREATER +#if NET public required int NumberOfItemsSerialized { get; init; } public required int NumberOfItemsDropped { get; init; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index db94e2d1fd..dd3e4a4539 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -101,7 +101,7 @@ public static void SerializeValueToJson(object? value, Utf8JsonWriter writer) writer.WriteStringValue(v); return; -#if NET8_0_OR_GREATER +#if NET case DateOnly v: JsonMetadataServices.DateOnlyConverter.Write(writer, v, null!); return; @@ -111,7 +111,7 @@ public static void SerializeValueToJson(object? value, Utf8JsonWriter writer) JsonMetadataServices.TimeSpanConverter.Write(writer, v, null!); return; -#if NET8_0_OR_GREATER +#if NET case TimeOnly v: JsonMetadataServices.TimeOnlyConverter.Write(writer, v, null!); return; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs index 2c71d15b6d..7ed65321d4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs @@ -20,7 +20,7 @@ public TransportSendRequest() #endif } -#if NET8_0_OR_GREATER +#if NET public required string ItemType { get; init; } public required OneCollectorExporterSerializationFormatType ItemSerializationFormat { get; init; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index f7402e2fa1..5cea309c2c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -1,10 +1,10 @@ - true - An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector - net8.0;net6.0;netstandard2.1;netstandard2.0 + net8.0;netstandard2.1;netstandard2.0 $(TargetFrameworks);net462 + true + An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector. Exporter.OneCollector- true - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net48;net472;net471;net47;net462 + Exe + Benchmark project for OpenTelemetry .NET OneCollectorExporter. - + + + + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 54c7e19491..15509b13c8 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -1,16 +1,12 @@ - Unit test project for OpenTelemetry .NET OneCollectorExporter. - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net48;net472;net471;net47;net462 + Unit test project for OpenTelemetry .NET OneCollectorExporter. - - - - From f24e67f847f0f9bb42b1715d13bbb7151b235479 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 1 Oct 2024 15:40:19 -0500 Subject: [PATCH 1286/1499] [release] core-1.10.0-beta.1 release updates (#2121) Co-authored-by: Mikel Blanchard --- build/Common.nonprod.props | 1 - build/Common.props | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmarks.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj | 2 +- .../OpenTelemetry.Instrumentation.Http.Benchmarks.csproj | 2 +- .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 2 +- 9 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 9f866b82f1..4ba068d4b2 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -28,7 +28,6 @@ 8.0.0 [17.11.1,18.0) $(OpenTelemetryCoreLatestVersion) - $(OpenTelemetryCoreLatestPrereleaseVersion) net8.0;net6.0 net8.0 [2.8.2,3.0) diff --git a/build/Common.props b/build/Common.props index 52f8c3bcc0..66bb0baca7 100644 --- a/build/Common.props +++ b/build/Common.props @@ -44,7 +44,7 @@ [8.0.0,9.0) [1.9.0-beta.2] [1.9.0,2.0) - [1.9.0-rc.1] + [1.10.0-beta.1] [2.6.122,3.0) [2.4.0,3.0) [3.16.0,4.0) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj index b6260babc9..170ff43bf7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj @@ -12,7 +12,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 6a9cf6603c..aa1b41057d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -20,7 +20,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj index b971a9eafd..23c4731175 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj index 3c302f5b49..4216b838eb 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 0f5351f3c3..2ab1c80bb1 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 4e2b6b51e5..9741d5d6b7 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 017682e469..d4e96d79a9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -27,7 +27,7 @@ - + From a8367f2a2e789d1dd3d3274d3e6d9c43aabffbf0 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:20:00 +0000 Subject: [PATCH 1287/1499] [Exporter.InfluxDB] Replace hardcoded TFM in test project (#2129) --- .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 8c24d8c21e..0823891329 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -2,7 +2,7 @@ - net8.0 + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net48;net472;net471;net47;net462 Unit test project for InfluxDB Exporter for OpenTelemetry. From 3ba134eb6470b66f8003af9acbc4afc6b02cc148 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:48:59 +0000 Subject: [PATCH 1288/1499] [Exporter.Geneva] Replace hardcoded TFM in test projects (#2128) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- .../OpenTelemetry.Exporter.Geneva.Benchmarks.csproj | 7 ++++--- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj index 170ff43bf7..d8de7b41c1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj @@ -1,12 +1,13 @@ + - Exe - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net48;net472;net471;net47;net462 - $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 + Exe + $(NoWarn);SA1201;SA1202;SA1204;SA1311;SA1123 disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index a9cd3cffcf..d38697183e 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -2,7 +2,7 @@ - net8.0 + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net48;net472;net471;net47;net462 Exe $(NoWarn);SA1308;SA1201 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index aa1b41057d..c7f15254ab 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -4,7 +4,7 @@ - net8.0 + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net48;net472;net471;net47;net462 Unit test project for Geneva Exporters for OpenTelemetry. $(NoWarn);SA1311;SA1312;SA1313;SA1123;SA1202;OTEL1002 From 2859fc940f830068f074aeb57c6bc5b8468b0f6e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:02:34 -0500 Subject: [PATCH 1289/1499] [release] Prepare release Instrumentation.Hangfire-1.9.0-beta.1 (#2136) --- src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index b3ecf9c96b..55724ff852 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.9.0-beta.1 + +Released 2024-Oct-02 + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) From e5fbb2ab7d058ad569c7160f534f7c86f6940bce Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 2 Oct 2024 19:31:33 +0000 Subject: [PATCH 1290/1499] [Extensions] Replace .NET 6 target with .NET 8 (#2124) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- build/Common.prod.props | 2 +- src/OpenTelemetry.Extensions/CHANGELOG.md | 3 +++ .../OpenTelemetry.Extensions.csproj | 8 ++++---- .../Trace/AutoFlushActivityProcessor.cs | 4 ++++ .../OpenTelemetry.Extensions.Tests.csproj | 6 +++--- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/build/Common.prod.props b/build/Common.prod.props index c402eaa2cc..b62120f65f 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -12,7 +12,7 @@ OpenTelemetry Authors Copyright The OpenTelemetry Authors $(MSBuildThisFileDirectory)/OpenTelemetryContrib.prod.ruleset - $(NoWarn),1573,1712 + $(NoWarn);1573;1712 $(Build_ArtifactStagingDirectory) Observability;OpenTelemetry;Monitoring;Telemetry diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index fa8a23a1dc..e382789b8d 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -16,6 +16,9 @@ rate per second. For details see [RateLimitingSampler](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Extensions#ratelimitingsampler). ([#1996](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1996)) +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2124)) + ## 1.0.0-beta.5 Released 2024-May-08 diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index b204e085c8..ab4423858e 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -2,14 +2,14 @@ - net6.0;netstandard2.0 + net8.0;netstandard2.0 $(TargetFrameworks);net462 - OpenTelemetry .NET SDK preview features and extensions + OpenTelemetry .NET SDK preview features and extensions. Extensions- - + true diff --git a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs index b2a38d6799..a88186c6a7 100644 --- a/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs +++ b/src/OpenTelemetry.Extensions/Trace/AutoFlushActivityProcessor.cs @@ -39,10 +39,14 @@ internal sealed class AutoFlushActivityProcessor : BaseProcessor internal AutoFlushActivityProcessor(Func predicate, int timeoutMilliseconds) { this.predicate = predicate ?? throw new ArgumentNullException(nameof(predicate)); +#if NET + ArgumentOutOfRangeException.ThrowIfLessThan(timeoutMilliseconds, Timeout.Infinite); +#else if (timeoutMilliseconds < Timeout.Infinite) { throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds)); } +#endif this.timeoutMilliseconds = timeoutMilliseconds; } diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 704dda8498..6b9ffb3dd1 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for OpenTelemetry .NET SDK preview features and extensions - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry .NET SDK preview features and extensions. From d8f4872e19e2bcc5a6ae23df050c47f4fdbd92a8 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 2 Oct 2024 19:49:21 +0000 Subject: [PATCH 1291/1499] [Extensions.Enrichment] Remove .NET 6 target (#2126) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md | 3 +++ .../OpenTelemetry.Extensions.Enrichment.csproj | 8 ++++---- .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md index 4c11ffe15d..a00f3d58cf 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md @@ -7,3 +7,6 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + +* Drop support for .NET 6 as this target is no longer supported. + ([#2126](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2126)) diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index 9ed6c4e87b..24ba74844c 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -2,15 +2,15 @@ - net8.0;net6.0;$(NetStandardMinimumSupportedVersion) + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry .NET SDK telemetry enrichment. - $(NoWarn),CS1591 + $(NoWarn);CS1591 Extensions.Enrichment- - + true diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index b86cc62d34..5cc3e698c7 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for OpenTelemetry .NET SDK telemetry enrichment. - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry .NET SDK telemetry enrichment. From 1f8e668f8838e6a518cbebef66e2988fccd544f6 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:15:07 +0000 Subject: [PATCH 1292/1499] [Extensions.AWS] Replace .NET 6 target with .NET 8 (#2125) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../.publicApi/{net6.0 => net8.0}/PublicAPI.Shipped.txt | 0 .../{net6.0 => net8.0}/PublicAPI.Unshipped.txt | 0 src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 3 +++ .../OpenTelemetry.Extensions.AWS.csproj | 9 +++++---- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) rename src/OpenTelemetry.Extensions.AWS/.publicApi/{net6.0 => net8.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Extensions.AWS/.publicApi/{net6.0 => net8.0}/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net8.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Extensions.AWS/.publicApi/net8.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/net8.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Extensions.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Extensions.AWS/.publicApi/net8.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 93b92a0d21..a889ec48bb 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -12,6 +12,9 @@ Released 2024-Sep-24 * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2125](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2125)) + ## 1.3.0-beta.1 Released 2023-Aug-02 diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index 253518e82b..ad5ce16572 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -1,14 +1,15 @@ + - net6.0;netstandard2.0 + net8.0;netstandard2.0 $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Extensions.AWS- - + true @@ -17,7 +18,7 @@ - + diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 68f248e657..3beba0091d 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 2729349aa164d0bba41b0f3084b21aea5d7fe1f5 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 2 Oct 2024 20:24:28 +0000 Subject: [PATCH 1293/1499] [Exporter.Stackdriver] Remove .NET 6 target and add .NET Standard 2.0 (#2127) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../CHANGELOG.md | 9 +++++++++ .../OpenTelemetry.Exporter.Stackdriver.csproj | 14 ++++++++------ ...OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 8 +++++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 00a00b1c6f..5028755fcd 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -5,6 +5,15 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Drop support for .NET 6 as this target is no longer supported + and add .NET Standard 2.0 target. + ([#2127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2127)) + +* Update Google Cloud libraries: + * Google.Cloud.Monitoring.V3 3.4.0 -> 3.8.0 + * Google.Cloud.Trace.V2 3.3.0 -> 3.5.0 + ([#2127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2127)) + ## 1.0.0-beta.6 Released 2024-Apr-22 diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index a4f5b0c32b..15c3b04992 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -1,21 +1,22 @@ + - net8.0;net6.0;net462 - Stackdriver .NET Exporter for OpenTelemetry. + net8.0;$(NetStandardMinimumSupportedVersion);net462 + An OpenTelemetry .NET exporter that sends telemetry to Google Stackdriver. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- - + true - - + + @@ -23,4 +24,5 @@ + diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index ab94de47f5..9c5c605224 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -1,9 +1,10 @@ + - Unit test project for Stackdriver Exporter for OpenTelemetry - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for Stackdriver Exporter for OpenTelemetry. @@ -31,4 +32,5 @@ True + From 4c9cbaa5b6df9503b2343ddd70f191ca28b584cb Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:34:26 -0500 Subject: [PATCH 1294/1499] [release] Prepare release Exporter.InfluxDB-1.0.0-alpha.4 (#2132) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index aba0951e9c..553e33cc2e 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-alpha.4 + +Released 2024-Oct-02 + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) From 1fa85552ff85c2a745b6d951f946c03db563cb18 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:37:10 -0500 Subject: [PATCH 1295/1499] [release] Prepare release Instrumentation.Cassandra-1.0.0-beta.2 (#2134) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 7ebec71fae..25b73d906b 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-beta.2 + +Released 2024-Oct-02 + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) From fb4cf321adda7e1c17a3d75af1bd47b92eb09757 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 08:46:51 +0000 Subject: [PATCH 1296/1499] [Instrumentation.Cassandra] Replace .NET 6 target with .NET 8 for test project (#2141) --- .../OpenTelemetry.Instrumentation.Cassandra.csproj | 8 ++++---- .../OpenTelemetry.Instrumentation.Cassandra.Tests.csproj | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj index 7dca3e007a..436d5f79dd 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj +++ b/src/OpenTelemetry.Instrumentation.Cassandra/OpenTelemetry.Instrumentation.Cassandra.csproj @@ -1,14 +1,14 @@ - netstandard2.0 - OpenTelemetry Cassandra Instrumentation + $(NetStandardMinimumSupportedVersion) + OpenTelemetry Cassandra Instrumentation. $(PackageTags);Cassandra;CassandraCSharpDriver Instrumentation.Cassandra- - + true diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 40e26b7c91..f61ba57d48 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -1,8 +1,8 @@ - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) @@ -22,4 +22,5 @@ + From 999398236fe3ba14cfaef4cfe9dda5a268161ddb Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 08:52:19 +0000 Subject: [PATCH 1297/1499] [Instrumentation.EntityFrameworkCore] Replace .NET 6 target with .NET 8 for test project (#2145) --- ...try.Instrumentation.EntityFrameworkCore.csproj | 7 ++++--- ...strumentation.EntityFrameworkCore.Tests.csproj | 15 +++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 1642fd0eb8..a14e26ba44 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -1,13 +1,14 @@ + netstandard2.0 - Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET + Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.EntityFrameworkCore- - + true diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 7a8b28872d..7fab9bb83a 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -1,31 +1,26 @@ + - Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) + Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation. - - - - + - - - - + From 2c76d335f4c71b9bf75372d95416a561e6167b3e Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 08:52:41 +0000 Subject: [PATCH 1298/1499] [Instrumentation.AspNetCore] Remove .NET 6 target (#2138) --- ....Instrumentation.AspNet.TelemetryHttpModule.csproj | 6 ++++-- .../OpenTelemetry.Instrumentation.AspNet.csproj | 7 ++++--- .../CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.AspNetCore.csproj | 3 ++- ...umentation.AspNet.TelemetryHttpModule.Tests.csproj | 4 +++- .../OpenTelemetry.Instrumentation.AspNet.Tests.csproj | 3 ++- ...metry.Instrumentation.AspNetCore.Benchmarks.csproj | 7 +++++-- ...nTelemetry.Instrumentation.AspNetCore.Tests.csproj | 11 ++++------- 8 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj index 01cfa35bb3..753152a182 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.csproj @@ -1,4 +1,5 @@ + $(NetFrameworkMinimumSupportedVersion) @@ -7,8 +8,8 @@ Instrumentation.AspNet- - + true @@ -31,4 +32,5 @@ + diff --git a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj index db66f84a14..c21ef4a406 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNet/OpenTelemetry.Instrumentation.AspNet.csproj @@ -1,15 +1,16 @@ + $(NetFrameworkMinimumSupportedVersion) - ASP.NET instrumentation for OpenTelemetry .NET + ASP.NET instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing;AspNet;MVC;WebAPI true Instrumentation.AspNet- - + true diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 1567f79401..be111b2388 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported. + ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138)) + ## 1.9.0 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index a95693ee5a..0f5087d0f1 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -1,7 +1,8 @@ + - net8.0;net6.0;netstandard2.0 + net8.0;$(NetStandardMinimumSupportedVersion) ASP.NET Core instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNetCore Instrumentation.AspNetCore- diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj index 88d63d331b..526236c90d 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests.csproj @@ -1,8 +1,9 @@ + - Unit test project for ASP.NET HttpModule $(NetFrameworkMinimumSupportedVersion) + Unit test project for ASP.NET HttpModule. @@ -26,4 +27,5 @@ Resources\web.config.uninstall.xdt + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj index bb0d66597d..e0fd3fe7a6 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/OpenTelemetry.Instrumentation.AspNet.Tests.csproj @@ -1,8 +1,9 @@ + - Unit test project for OpenTelemetry ASP.NET instrumentation $(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry ASP.NET instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj index 23c4731175..7d0cb435f8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj @@ -1,13 +1,16 @@ + - Exe - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) + Exe + + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 004daa67a8..dd8ec60246 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -1,14 +1,10 @@ + - Unit test project for OpenTelemetry ASP.NET Core instrumentation - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) + Unit test project for OpenTelemetry ASP.NET Core instrumentation. - - - - - @@ -37,4 +33,5 @@ Always + From 5d63580f9208bee51b8e23c12e79657e26fdc8a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 3 Oct 2024 11:08:06 +0200 Subject: [PATCH 1299/1499] Typofixes - diable ->disable (#2148) --- build/scripts/post-release.psm1 | 6 +++--- .../HttpInListenerTests.cs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build/scripts/post-release.psm1 b/build/scripts/post-release.psm1 index 13ae216a04..0321e9c092 100644 --- a/build/scripts/post-release.psm1 +++ b/build/scripts/post-release.psm1 @@ -201,18 +201,18 @@ function CreatePackageValidationBaselineVersionUpdatePullRequest { } } - $diabledTag = "true" + $disabledTag = "true" $disabledProjects = Get-ChildItem -Path src/**/*.csproj | where { $_ | Select-String "$tagPrefix" } | - where { $_ | Select-String $diabledTag } + where { $_ | Select-String $disabledTag } if ($disabledProjects.Length -ne 0) { foreach ($project in $disabledProjects) { $content = (Get-Content $project -Raw) - $content = $content -replace $diabledTag, "$version" + $content = $content -replace $disabledTag, "$version" $content = $content -replace "\s*", "" diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index c76c1ec101..b14a987eeb 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -21,14 +21,14 @@ public enum QueryRedactionDisableBehavior { #pragma warning disable SA1602 // Enumeration items should be documented DisableViaEnvVar, - DiableViaIConfiguration, + DisableViaIConfiguration, #pragma warning restore SA1602 // Enumeration items should be documented } [Theory] [InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", QueryRedactionDisableBehavior.DisableViaEnvVar, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] - [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", QueryRedactionDisableBehavior.DiableViaIConfiguration, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] + [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=bar&baz=test", QueryRedactionDisableBehavior.DisableViaIConfiguration, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] [InlineData("http://localhost/?foo=bar&baz=test", "http", "/", "foo=Redacted&baz=Redacted", null, "localhost", 80, "POST", "POST", null, 0, null, "POST", true)] [InlineData("https://localhost/", "https", "/", null, null, "localhost", 443, "NonStandard", "_OTHER", "NonStandard", 0, null, "HTTP")] [InlineData("https://user:pass@localhost/", "https", "/", null, null, "localhost", 443, "GeT", "GET", "GeT", 0, null, "GET")] // Test URL sanitization @@ -36,7 +36,7 @@ public enum QueryRedactionDisableBehavior [InlineData("https://localhost:80/", "https", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test https over 80 [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", QueryRedactionDisableBehavior.DisableViaEnvVar, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL [InlineData("https://localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=Redacted&q2=Redacted", null, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL - [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", QueryRedactionDisableBehavior.DiableViaIConfiguration, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization + [InlineData("https://user:password@localhost:80/Home/Index.htm?q1=v1&q2=v2#FragmentName", "https", "/Home/Index.htm", "q1=v1&q2=v2", QueryRedactionDisableBehavior.DisableViaIConfiguration, "localhost", 80, "GET", "GET", null, 0, null, "GET")] // Test complex URL sanitization [InlineData("http://localhost:80/Index", "http", "/Index", null, null, "localhost", 80, "GET", "GET", null, 1, "{controller}/{action}/{id}", "GET {controller}/{action}/{id}")] [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] @@ -80,7 +80,7 @@ public void AspNetRequestsAreCollectedSuccessfully( using (Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => { - if (disableQueryRedaction == QueryRedactionDisableBehavior.DiableViaIConfiguration) + if (disableQueryRedaction == QueryRedactionDisableBehavior.DisableViaIConfiguration) { var config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary() From 1a61e938568efd288236cac08d1a3c6cce5207eb Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:55:55 +0000 Subject: [PATCH 1300/1499] [Instrumentation.GrpcNetClient] Remove .NET 6 target (#2150) --- .../CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.GrpcNetClient.csproj | 9 +++++---- ...nTelemetry.Instrumentation.GrpcNetClient.Tests.csproj | 7 ++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md index a35c62670e..ab16d3d6d2 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported. + ([#2150](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2150)) + ## 1.9.0-beta.1 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index e8103ae2c3..9c5bf71676 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -1,14 +1,15 @@ + - net8.0;net6.0;netstandard2.1;netstandard2.0 - gRPC for .NET client instrumentation for OpenTelemetry .NET + net8.0;netstandard2.1;netstandard2.0 + gRPC for .NET client instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.GrpcNetClient- - + true diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index 79ca9d1a02..1efe5efe2e 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -1,9 +1,10 @@ + - Unit test project for OpenTelemetry Grpc for .NET instrumentation - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - $(NoWarn),CS8981 + Unit test project for OpenTelemetry Grpc for .NET instrumentation. + $(NoWarn);CS8981 From 2a943c9126300c15de74797280711a800354692c Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:05:13 +0000 Subject: [PATCH 1301/1499] [Instrumentation.AWS] Replace .NET 6 target with .NET 8 (#2139) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.AWS.csproj | 8 ++++---- .../OpenTelemetry.Instrumentation.AWS.Tests.csproj | 4 ++-- .../Tools/HttpResponseMessageBody.cs | 8 ++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index 49380447de..f00015d971 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2139](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2139)) + ## 1.1.0-beta.6 Released 2024-Sep-10 diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index b69158084f..1b9b5cc120 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -2,14 +2,14 @@ - net6.0;netstandard2.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - AWS client instrumentation for OpenTelemetry .NET + AWS client instrumentation for OpenTelemetry .NET. Instrumentation.AWS- - + true diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 8b702a1c32..531c31e2b7 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for AWS client instrumentation for OpenTelemetry. - net6.0 + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for AWS client instrumentation for OpenTelemetry. diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index b13368ec3c..f1e7d4f3ba 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -27,20 +27,28 @@ public void Dispose() Stream IHttpResponseBody.OpenResponse() { +#if NET + ObjectDisposedException.ThrowIf(this.disposed, this); +#else if (this.disposed) { throw new ObjectDisposedException("HttpWebResponseBody"); } +#endif return this.response.Content.ReadAsStreamAsync().Result; } Task IHttpResponseBody.OpenResponseAsync() { +#if NET + ObjectDisposedException.ThrowIf(this.disposed, this); +#else if (this.disposed) { throw new ObjectDisposedException("HttpWebResponseBody"); } +#endif if (this.response.Content != null) { From be8f01b0ffb03586296ea7fcc2b2afafa31214e4 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:17:21 +0000 Subject: [PATCH 1302/1499] [Instrumentation.AWSLambda] Replace .NET 6 target with .NET 8 and add .NET Standard 2.0 (#2140) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 3 +++ .../Implementation/AWSMessagingUtils.cs | 5 +++++ .../OpenTelemetry.Instrumentation.AWSLambda.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index b098e49db1..ada5abb5e3 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -6,6 +6,9 @@ ([#2037](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2037)) * Add HTTP server span attributes for Application Loadbalancer triggers ([#2033](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2033)) +* Drop support for .NET 6 as this target is no longer supported + and add .NET 8/.NET Standard 2.0 targets. + ([#2140](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2140)) ## 1.3.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs index 3d97d01fd4..47c571908e 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -124,8 +124,13 @@ internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage? mes var body = sqsMessage.Body; if (body != null && +#if NET body.TrimStart().StartsWith('{') && body.Contains(SnsMessageAttributes, StringComparison.Ordinal)) +#else + body.TrimStart().StartsWith("{", StringComparison.Ordinal) && + body.Contains(SnsMessageAttributes)) +#endif { try { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index e59ca1fbca..13cdc16840 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -1,8 +1,8 @@ - net6.0 - AWS Lambda tracing wrapper for OpenTelemetry .NET + net8.0;$(NetStandardMinimumSupportedVersion) + AWS Lambda tracing wrapper for OpenTelemetry .NET. $(PackageTags);AWS Lambda Instrumentation.AWSLambda- diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index 91a0bb9a75..e81df4b035 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -1,8 +1,8 @@ - Unit test project of OpenTelemetry instrumentation for AWS Lambda - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) + Unit test project of OpenTelemetry instrumentation for AWS Lambda. From da9b5381d421be13efe190303552a585afdcb61e Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:26:45 +0000 Subject: [PATCH 1303/1499] [Instrumentation.ConfluentKafka] Remove .NET 6 target and add .NET Standard 2.0 (#2142) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .github/workflows/integration.yml | 2 +- .../CHANGELOG.md | 8 ++++++-- ...etry.Instrumentation.ConfluentKafka.csproj | 9 +++++---- .../OpenTelemetryConsumeResultExtensions.cs | 20 +++++++++---------- .../OpenTelemetryConsumerBuilderExtensions.cs | 2 +- .../OpenTelemetryProducerBuilderExtensions.cs | 2 +- ...nstrumentation.ConfluentKafka.Tests.csproj | 5 +++-- 7 files changed, 27 insertions(+), 21 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 53c25d07fd..3f242240f0 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - version: [net6.0, net8.0] + version: [net8.0] steps: - uses: actions/checkout@v4 diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index ce758fbebc..932234cb6e 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -2,15 +2,19 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported + and add .NET Standard 2.0 target. + ([#2142](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2142)) + ## 0.1.0-alpha.2 Released 2024-Sep-18 -- Add named instrumentation support +* Add named instrumentation support ([#2074](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2074)) ## 0.1.0-alpha.1 Released 2024-Sep-16 -- Initial release +* Initial release diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj index bc7d46a90d..d607322439 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj @@ -1,16 +1,17 @@ + - net8.0;net6.0;net462 - Confluent.Kafka instrumentation for OpenTelemetry .NET + net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + Confluent.Kafka instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing;Kafka;Confluent.Kafka true Instrumentation.ConfluentKafka- true - + true diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs index abedc35623..5ef64a43ac 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs @@ -27,13 +27,13 @@ public static bool TryExtractPropagationContext( this ConsumeResult consumeResult, out PropagationContext propagationContext) { -#if NETFRAMEWORK +#if NET + ArgumentNullException.ThrowIfNull(consumeResult); +#else if (consumeResult == null) { throw new ArgumentNullException(nameof(consumeResult)); } -#else - ArgumentNullException.ThrowIfNull(consumeResult); #endif try @@ -75,13 +75,13 @@ public static bool TryExtractPropagationContext( OpenTelemetryConsumeAndProcessMessageHandler handler, CancellationToken cancellationToken) { -#if NETFRAMEWORK +#if NET + ArgumentNullException.ThrowIfNull(consumer); +#else if (consumer == null) { throw new ArgumentNullException(nameof(consumer)); } -#else - ArgumentNullException.ThrowIfNull(consumer); #endif if (consumer is not InstrumentedConsumer instrumentedConsumer) @@ -89,13 +89,13 @@ public static bool TryExtractPropagationContext( throw new ArgumentException("Invalid consumer type.", nameof(consumer)); } -#if NETFRAMEWORK - if (handler is null) +#if NET + ArgumentNullException.ThrowIfNull(handler); +#else + if (handler == null) { throw new ArgumentNullException(nameof(handler)); } -#else - ArgumentNullException.ThrowIfNull(handler); #endif var consumeResult = instrumentedConsumer.Consume(cancellationToken); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs index c139ba1956..11936c3694 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs @@ -17,7 +17,7 @@ public static class OpenTelemetryConsumerBuilderExtensions /// Type of the value. /// The instance. /// An instance. -#if !NETFRAMEWORK +#if !NETFRAMEWORK && !NETSTANDARD [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedConsumerBuilder' constructor to avoid reflection.")] #endif public static InstrumentedConsumerBuilder AsInstrumentedConsumerBuilder(this ConsumerBuilder consumerBuilder) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs index 3eb243af70..f2a722f5af 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs @@ -17,7 +17,7 @@ public static class OpenTelemetryProducerBuilderExtensions /// Type of the value. /// The instance. /// An instance. -#if !NETFRAMEWORK +#if !NETFRAMEWORK && !NETSTANDARD [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedProducerBuilder' constructor to avoid reflection.")] #endif public static InstrumentedProducerBuilder AsInstrumentedProducerBuilder(this ProducerBuilder producerBuilder) diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj index 1263d4ff22..f74df494f5 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -1,9 +1,10 @@ + - Unit test project for OpenTelemetry ConfluentKafka instrumentation - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry ConfluentKafka instrumentation. From 03cc56dd8e434f389657215044459d5546cde673 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:35:03 +0000 Subject: [PATCH 1304/1499] [Instrumentation.ElasticsearchClient] Replace .NET 6 target with .NET 8 for test project (#2144) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- ...elemetry.Instrumentation.ElasticsearchClient.csproj | 10 ++++++---- ...ry.Instrumentation.ElasticsearchClient.Tests.csproj | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 35a67f0d61..26630e1596 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -1,15 +1,16 @@ + - netstandard2.0 + $(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - Elasticsearch instrumentation for OpenTelemetry .NET + Elasticsearch instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- - + true @@ -36,4 +37,5 @@ + diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index dee17e80d3..390dec1886 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -1,9 +1,10 @@ + - Unit test project for OpenTelemetry Elasticsearch client instrumentation - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry Elasticsearch client instrumentation. From 37831480e138d256d1ff2af9012b5ce8f453b0aa Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:42:23 +0000 Subject: [PATCH 1305/1499] [Instrumentation.EventCounters] Replace .NET 6 target with .NET 8 for test project (#2146) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Instrumentation.EventCounters.csproj | 10 ++++++---- ...elemetry.Instrumentation.EventCounters.Tests.csproj | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj index 5b6d47e2c1..faa6feaaca 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj +++ b/src/OpenTelemetry.Instrumentation.EventCounters/OpenTelemetry.Instrumentation.EventCounters.csproj @@ -1,13 +1,14 @@ + - netstandard2.0 - OpenTelemetry Metrics instrumentation for Dotnet EventCounters + $(NetStandardMinimumSupportedVersion) + OpenTelemetry Metrics instrumentation for .NET EventCounters. $(PackageTags);metrics;eventcounters Instrumentation.EventCounters- - + true @@ -20,4 +21,5 @@ + diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index a22694028b..e3e1e17a7a 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) @@ -12,4 +12,5 @@ + From db2837a32089d0dac4561295cd0023a9cf554575 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:51:31 +0000 Subject: [PATCH 1306/1499] [Instrumentation.GrpcCore] Replace .NET 6 target with .NET 8 for test project (#2147) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Instrumentation.GrpcCore.csproj | 8 +++++--- .../OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj index 42f6a991f9..c9af6075fc 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/OpenTelemetry.Instrumentation.GrpcCore.csproj @@ -1,13 +1,14 @@ + - netstandard2.0 + $(NetStandardMinimumSupportedVersion) .NET gRPC Core based client and server interceptors for OpenTelemetry. $(PackageTags);gRPC Core;interceptors Instrumentation.GrpcCore- - + true @@ -23,4 +24,5 @@ + diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index 6dac68bae0..aeb25ed8be 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -1,11 +1,11 @@ - net6.0 + $(SupportedNetTargetsWithoutNet6) - + From 3f23c16df17075b38bfabbca85c317a7a8144076 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 18:55:53 +0000 Subject: [PATCH 1307/1499] [Instrumentation.Http] Remove .NET 6 target (#2152) --- src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.Http.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.Http.Benchmarks.csproj | 5 +++-- .../OpenTelemetry.Instrumentation.Http.Tests.csproj | 5 +++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 65249e41ce..77f97966fd 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported. + ([#2152](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2152)) + ## 1.9.0 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index 7650ca7e12..a51f538f71 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -1,9 +1,9 @@ - net8.0;net6.0;netstandard2.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - Http instrumentation for OpenTelemetry .NET + Http instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.Http- 1.9.0 diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj index 4216b838eb..c96496222f 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj @@ -1,8 +1,9 @@ + - Exe - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) + Exe diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 8811a92001..7e65697a06 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -1,8 +1,9 @@ + - Unit test project for OpenTelemetry HTTP instrumentations - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry HTTP instrumentations. From c1a4084d908fb5da6e565f68ad95049038baa9b5 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:42:39 +0000 Subject: [PATCH 1308/1499] [Instrumentation.Hangfire] Replace .NET 6 target with .NET 8 for test project (#2151) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Instrumentation.Hangfire.csproj | 11 +++++++---- ...penTelemetry.Instrumentation.Hangfire.Tests.csproj | 10 +++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj index 7507f1205a..0819efe24c 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj +++ b/src/OpenTelemetry.Instrumentation.Hangfire/OpenTelemetry.Instrumentation.Hangfire.csproj @@ -1,14 +1,15 @@ + - netstandard2.0 - OpenTelemetry Hangfire Instrumentation + $(NetStandardMinimumSupportedVersion) + OpenTelemetry Hangfire Instrumentation. $(PackageTags);Hangfire Instrumentation.Hangfire- false - + true @@ -20,8 +21,10 @@ + + diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index bb9244d155..2db7102751 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -1,18 +1,22 @@ + - Unit test project for OpenTelemetry Hangfire instrumentation - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry Hangfire instrumentation. false + + + From c2189659d41ab2ed2c1e114e36c6c356795d156d Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:00:42 +0000 Subject: [PATCH 1309/1499] [Instrumentation.Process] Replace .NET 6 target with .NET 8 for test project (#2153) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Instrumentation.Process.csproj | 9 +++++---- .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj index f71ebcf4bf..6df12c32ea 100644 --- a/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj +++ b/src/OpenTelemetry.Instrumentation.Process/OpenTelemetry.Instrumentation.Process.csproj @@ -1,13 +1,14 @@ + - netstandard2.0 - dotnet process instrumentation for OpenTelemetry .NET + $(NetStandardMinimumSupportedVersion) + dotnet process instrumentation for OpenTelemetry .NET. $(PackageTags);process Instrumentation.Process- - + true diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 2ab1c80bb1..8f786a052b 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -2,8 +2,8 @@ - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 4946b2a3194764ddf3df4d9f7718bfa8ff9e0f90 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:14:13 +0000 Subject: [PATCH 1310/1499] [Instrumentation.Runtime] Replace .NET 6 target with .NET 8 (#2155) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.Runtime.csproj | 6 ++++-- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index be54016cbb..1f71e065ef 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2155](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2155)) + ## 1.9.0 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index d873a9fd12..b516536ab4 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -1,8 +1,9 @@ + - net6.0;netstandard2.0;net462 - dotnet runtime instrumentation for OpenTelemetry .NET + net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + .NET runtime instrumentation for OpenTelemetry .NET. $(PackageTags);runtime Instrumentation.Runtime- 1.9.0 @@ -16,4 +17,5 @@ + diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 9741d5d6b7..ea6d3e9922 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -2,8 +2,8 @@ - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 2a0f7cbee70e9cf534f85cf0eb8ae926b52307a8 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:40:27 +0000 Subject: [PATCH 1311/1499] [Instrumentation.Quartz] Replace .NET 6 target with .NET 8 for test project (#2154) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Instrumentation.Quartz.csproj | 8 +++++--- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index 05d43a3384..ef13ab8526 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -1,13 +1,14 @@ + + $(NetStandardMinimumSupportedVersion) OpenTelemetry Quartz.NET Instrumentation $(PackageTags);distributed-tracing Instrumentation.Quartz- - netstandard2.0 - + true @@ -26,4 +27,5 @@ + diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 5d33706ba9..1675b22eb9 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -1,9 +1,9 @@ - Unit test project for OpenTelemetry Quartz.NET instrumentation - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);net472 + Unit test project for OpenTelemetry Quartz.NET instrumentation. @@ -20,4 +20,5 @@ + From e5106b25f96815ec0c75e912bdf071f7877bd8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 4 Oct 2024 09:34:59 +0200 Subject: [PATCH 1312/1499] [Instrumentation.Cassandra] Document how to enable tracing (#2158) --- src/OpenTelemetry.Instrumentation.Cassandra/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index 1cbeb92829..d9dcda3611 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -14,6 +14,11 @@ This is an which instruments [CassandraCSharpDriver](https://github.com/datastax/csharp-driver) and collects telemetry about cassandra metrics. +> [!NOTE] +> This package provides support for metrics only. + You can enable tracing using [`Cassandra.OpenTelemetry`](https://docs.datastax.com/en/developer/csharp-driver/3.22/features/opentelemetry/index.html) + package. + ## Steps to enable OpenTelemetry.Instrumentation.Cassandra ### Step 1: Install Package From 0b01daa36521b897dcefa0cbbc9cb4b912c5881a Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:12:49 +0000 Subject: [PATCH 1313/1499] [Instrumentation.SqlClient] Remove .NET 6 target (#2159) --- src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.SqlClient.csproj | 8 ++++---- .../OpenTelemetry.Instrumentation.SqlClient.Tests.csproj | 5 +++-- .../SqlClientIntegrationTestsFixture.cs | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 359f58a146..fa9054cb07 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported. + ([#2159](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2159)) + ## 1.9.0-beta.1 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index 8b38c96bd0..26c571d46d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -1,15 +1,15 @@ - net8.0;net6.0;netstandard2.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - SqlClient instrumentation for OpenTelemetry .NET + SqlClient instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.SqlClient- - + true diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 5c3e4d90a2..730389a718 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -1,8 +1,9 @@ + Unit test project for OpenTelemetry SqlClient instrumentations - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs index 57e0c85c6f..28e39184bf 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs @@ -29,7 +29,7 @@ public Task DisposeAsync() private static SqlEdgeContainer CreateSqlEdge() { // Note: The Testcontainers.SqlEdge package has been deprecated. Seems - // it will not work with newer GItHub-hosted runners. Need to find an + // it will not work with newer GitHub-hosted runners. Need to find an // alternative solution. See: // https://github.com/testcontainers/testcontainers-dotnet/pull/1265 return new SqlEdgeBuilder().Build(); From 8beed69c23caeb62e8c71462ca382577404bc22f Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:28:54 +0000 Subject: [PATCH 1314/1499] [Instrumentation.Wcf] Replace .NET 6 target with .NET 8 for test project (#2161) --- .../OpenTelemetry.Instrumentation.Wcf.csproj | 8 ++++---- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 7376dc4e12..3bbf68e673 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -2,8 +2,8 @@ - netstandard2.0;net462 - OpenTelemetry instrumentation for WCF + $(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry instrumentation for WCF. $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- @@ -18,12 +18,12 @@ - + - + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index d4e96d79a9..6559d126d9 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -1,17 +1,17 @@ - Unit test project for OpenTelemetry WCF instrumentation - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry WCF instrumentation. - + @@ -19,7 +19,7 @@ - + From b14d5850df87abf0bbed561667ef1352059cb0c1 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:40:38 +0000 Subject: [PATCH 1315/1499] [PersistentStorage.FileSystem] Replace .NET 6 target with .NET 8 for test project (#2163) --- .../OpenTelemetry.PersistentStorage.FileSystem.csproj | 9 +++------ ...enTelemetry.PersistentStorage.FileSystem.Tests.csproj | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj index fe8baa3a91..facc9c3023 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/OpenTelemetry.PersistentStorage.FileSystem.csproj @@ -2,17 +2,14 @@ - netstandard2.0 - $(TargetFrameworks);net462 + $(NetStandardMinimumSupportedVersion) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Persistent Storage + $(NoWarn);1591 PersistentStorage- 1.0.0 - - $(NoWarn),1591 - - diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index d33c3e28e8..92d7b61fa1 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -2,8 +2,8 @@ - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 364cd812a7a1e4e8ca04e4096b61f5609f06dd52 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:57:01 +0000 Subject: [PATCH 1316/1499] [PersistentStorage.Abstractions] Replace .NET 6 target with .NET 8 for test project (#2162) --- .../OpenTelemetry.PersistentStorage.Abstractions.csproj | 8 ++++---- ...nTelemetry.PersistentStorage.Abstractions.Tests.csproj | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj index e2c02a33b8..20f57dcc64 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/OpenTelemetry.PersistentStorage.Abstractions.csproj @@ -2,12 +2,12 @@ - netstandard2.0 - $(TargetFrameworks);net462 - OpenTelemetry Persistent Storage Abstractions + $(NetStandardMinimumSupportedVersion) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + OpenTelemetry Persistent Storage Abstractions. + $(NoWarn);1591 PersistentStorage- 1.0.0 - $(NoWarn),1591 diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj index 10d560b8e9..e6bf4b974b 100644 --- a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj @@ -2,8 +2,8 @@ - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 370ca666f393630e9340bfad89cc66ec2c2bac5e Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 09:34:27 +0000 Subject: [PATCH 1317/1499] [Resources.Azure] Replace .NET 6 target with .NET 8 (#2165) --- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 3 +++ .../OpenTelemetry.Resources.Azure.csproj | 10 ++++++---- .../OpenTelemetry.Resources.Azure.Tests.csproj | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 1ee8315ba3..fb00a275bd 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2165](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2165)) + ## 1.0.0-beta.9 Released 2024-Sep-24 diff --git a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj index c771f22875..4541d9ffb8 100644 --- a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj +++ b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj @@ -1,13 +1,14 @@ + - net6.0;netstandard2.0 - OpenTelemetry Resource Detectors for Azure cloud environments + net8.0;$(NetStandardMinimumSupportedVersion) + OpenTelemetry Resource Detectors for Azure cloud environments. $(PackageTags);ResourceDetector Resources.Azure- - + true @@ -23,4 +24,5 @@ + diff --git a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj index 7309e53286..def2a76649 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj +++ b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj @@ -2,8 +2,8 @@ - $(SupportedNetTargets) - $(TargetFrameworks);net462 + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 9400d5cd9ff13f36281ef8d0b4bda3030afa40bc Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:23:43 +0000 Subject: [PATCH 1318/1499] [Resources.Process] Replace .NET 6 target with .NET 8 and add .NET Standard 2.0 target (#2170) --- src/OpenTelemetry.Resources.Process/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Resources.Process.csproj | 10 ++++++---- .../OpenTelemetry.Resources.Process.Tests.csproj | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index a218d81bf9..75f0743c3c 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported + and add .NET 8/.NET Standard 2.0 targets. + ([#2170](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2170)) + ## 0.1.0-beta.3 Released 2024-Sep-25 diff --git a/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj b/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj index 5d90876bb5..7d333a1c31 100644 --- a/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj +++ b/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj @@ -1,14 +1,15 @@ + - net6.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry Extensions - Process Resource Detector. + OpenTelemetry Resource Detectors for Process. Resources.Process- - + true @@ -20,4 +21,5 @@ + diff --git a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj index b86c6f5cd6..bccea101b5 100644 --- a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj +++ b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for Process Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for Process Detector for OpenTelemetry. From 7f91d747369315f1dbeac2dd42190b10f4064db9 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:33:11 +0000 Subject: [PATCH 1319/1499] [Resources.Host] Replace .NET 6 target with .NET 8 and add .NET Standard 2.0 target (#2168) --- src/OpenTelemetry.Resources.Host/CHANGELOG.md | 4 ++++ .../HostDetector.cs | 20 +++++++++---------- .../OpenTelemetry.Resources.Host.csproj | 11 ++++++---- .../OpenTelemetry.Resources.Host.Tests.csproj | 4 ++-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index a497691784..a07b292e58 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported + and add .NET 8/.NET Standard 2.0 targets. + ([#2168](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2168)) + ## 0.1.0-beta.3 Released 2024-Aug-30 diff --git a/src/OpenTelemetry.Resources.Host/HostDetector.cs b/src/OpenTelemetry.Resources.Host/HostDetector.cs index 83ff701f53..a52e527e5a 100644 --- a/src/OpenTelemetry.Resources.Host/HostDetector.cs +++ b/src/OpenTelemetry.Resources.Host/HostDetector.cs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -#if NET +#if !NETFRAMEWORK using System.Runtime.InteropServices; #endif using System.Text; @@ -18,7 +18,7 @@ internal sealed class HostDetector : IResourceDetector { private const string ETCMACHINEID = "/etc/machine-id"; private const string ETCVARDBUSMACHINEID = "/var/lib/dbus/machine-id"; -#if NET +#if !NETFRAMEWORK private readonly Func isOsPlatform; #endif private readonly Func> getFilePaths; @@ -30,7 +30,7 @@ internal sealed class HostDetector : IResourceDetector ///
    public HostDetector() : this( -#if NET +#if !NETFRAMEWORK RuntimeInformation.IsOSPlatform, #endif GetFilePaths, @@ -39,7 +39,7 @@ public HostDetector() { } -#if NET +#if !NETFRAMEWORK public HostDetector( Func> getFilePaths, Func getMacOsMachineId, @@ -54,21 +54,21 @@ public HostDetector( #endif internal HostDetector( -#if NET +#if !NETFRAMEWORK Func isOsPlatform, #endif Func> getFilePaths, Func getMacOsMachineId, Func getWindowsMachineId) { -#if NET +#if !NETFRAMEWORK Guard.ThrowIfNull(isOsPlatform); #endif Guard.ThrowIfNull(getFilePaths); Guard.ThrowIfNull(getMacOsMachineId); Guard.ThrowIfNull(getWindowsMachineId); -#if NET +#if !NETFRAMEWORK this.isOsPlatform = isOsPlatform; #endif this.getFilePaths = getFilePaths; @@ -117,10 +117,10 @@ public Resource Detect() foreach (var line in lines) { -#if NETFRAMEWORK - if (line.IndexOf("IOPlatformUUID", StringComparison.OrdinalIgnoreCase) >= 0) -#else +#if NET if (line.Contains("IOPlatformUUID", StringComparison.OrdinalIgnoreCase)) +#else + if (line.IndexOf("IOPlatformUUID", StringComparison.OrdinalIgnoreCase) >= 0) #endif { var parts = line.Split('"'); diff --git a/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj b/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj index becdd8962b..319966e6a3 100644 --- a/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj +++ b/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj @@ -1,24 +1,27 @@ + - net6.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry Extensions - Host Resource Detector. + OpenTelemetry Resource Detectors for Host. Resources.Host- - + true + + diff --git a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj index 6675698cc8..257601185e 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj +++ b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for Host Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for Host Detector for OpenTelemetry. From 8be448b8f347b056ed077f41b302940805bda540 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:46:41 +0000 Subject: [PATCH 1320/1499] [SemanticConventions] Replace hardcoded TFM (#2173) --- .../OpenTelemetry.SemanticConventions.csproj | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj b/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj index 7b5c96cd86..0d9a0f7401 100644 --- a/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj +++ b/src/OpenTelemetry.SemanticConventions/OpenTelemetry.SemanticConventions.csproj @@ -1,16 +1,17 @@ - netstandard2.0 - OpenTelemetry Semantic Conventions + $(NetStandardMinimumSupportedVersion) + OpenTelemetry Semantic Conventions. $(PackageTags);semantic-conventions SemanticConventions- false - + true + From 6f359367066e1a11aa6c8f748359c7caef7c33c0 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:47:21 +0000 Subject: [PATCH 1321/1499] [Resources.ProcessRuntime] Replace .NET 6 target with .NET 8 and add .NET Standard 2.0 target (#2171) --- .../CHANGELOG.md | 4 ++++ .../OpenTelemetry.Resources.ProcessRuntime.csproj | 10 ++++++---- ...OpenTelemetry.Resources.ProcessRuntime.Tests.csproj | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md index 16ac419f87..5c820fc189 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported + and add .NET 8/.NET Standard 2.0 targets. + ([#2171](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2171)) + ## 0.1.0-beta.2 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj b/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj index de63279f70..03ff0bc483 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj +++ b/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj @@ -1,14 +1,15 @@ + - net6.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry Extensions - Process Runtime Resource Detector for .NET runtime. + OpenTelemetry Resource Detectors for Process Runtime. Resources.ProcessRuntime- - + true @@ -21,4 +22,5 @@ + diff --git a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj index 3fec9af968..34894d55fd 100644 --- a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj +++ b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for Process Runtime Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for Process Runtime Detector for OpenTelemetry. From 5e7c50d06d4764fb689e40aabdf2face48ff5e27 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 10:56:24 +0000 Subject: [PATCH 1322/1499] [Resources.OperatingSystem] Replace .NET 6 target with .NET 8 and add .NET Standard 2.0 target (#2169) --- .../CHANGELOG.md | 4 ++++ ...Telemetry.Resources.OperatingSystem.csproj | 9 ++++---- .../OperatingSystemDetector.cs | 21 ++++++++++--------- ...try.Resources.OperatingSystem.Tests.csproj | 4 ++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index f9f0cdd59d..4775cc550e 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported + and add .NET 8/.NET Standard 2.0 targets. + ([#2169](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2169)) + ## 0.1.0-alpha.4 Released 2024-Sep-09 diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj index 95c55dec8b..63b085d0c5 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj +++ b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj @@ -2,20 +2,21 @@ - net6.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry Extensions - Operating System Resource Detector for .NET + OpenTelemetry Resource Detectors for Operating System. Resources.OperatingSystem- - + true + diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs index f25ac54f06..1e018c25fd 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs @@ -1,11 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET +#if !NETFRAMEWORK using System.Runtime.InteropServices; +#endif +#if NET using System.Xml.Linq; #endif - using static OpenTelemetry.Resources.OperatingSystem.OperatingSystemSemanticConventions; namespace OpenTelemetry.Resources.OperatingSystem; @@ -18,16 +19,16 @@ internal sealed class OperatingSystemDetector : IResourceDetector private const string RegistryKey = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; private const string KernelOsRelease = "/proc/sys/kernel/osrelease"; private static readonly string[] DefaultEtcOsReleasePaths = - [ - "/etc/os-release", - "/usr/lib/os-release" - ]; + [ + "/etc/os-release", + "/usr/lib/os-release" + ]; private static readonly string[] DefaultPlistFilePaths = - [ - "/System/Library/CoreServices/SystemVersion.plist", - "/System/Library/CoreServices/ServerVersion.plist" - ]; + [ + "/System/Library/CoreServices/SystemVersion.plist", + "/System/Library/CoreServices/ServerVersion.plist" + ]; private readonly string? osType; private readonly string? registryKey; diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj index 2648338374..b31c404002 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for Operating System Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for Operating System Detector for OpenTelemetry. From cc6d06a3f8aadbd8469de7209e0e82788a524da7 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:21:00 +0000 Subject: [PATCH 1323/1499] [Resources.Container] Replace .NET 6 target with .NET 8 and add .NET Standard 2.0 target (#2166) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- build/Common.props | 1 - src/OpenTelemetry.Resources.Container/CHANGELOG.md | 4 ++++ .../ContainerDetector.cs | 4 ++++ .../OpenTelemetry.Resources.Container.csproj | 10 ++++++---- .../OpenTelemetry.Resources.Container.Tests.csproj | 8 ++------ 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/build/Common.props b/build/Common.props index 66bb0baca7..9a5fbde756 100644 --- a/build/Common.props +++ b/build/Common.props @@ -7,7 +7,6 @@ $(DefineConstants);SIGNED true net462 - net6.0 netstandard2.0 true latest-all diff --git a/src/OpenTelemetry.Resources.Container/CHANGELOG.md b/src/OpenTelemetry.Resources.Container/CHANGELOG.md index c7a5c6be52..85c7614e00 100644 --- a/src/OpenTelemetry.Resources.Container/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported + and add .NET 8/.NET Standard 2.0 targets. + ([#2166](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2166)) + ## 1.0.0-beta.9 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Resources.Container/ContainerDetector.cs b/src/OpenTelemetry.Resources.Container/ContainerDetector.cs index 624fa5e0e6..8b00d6776a 100644 --- a/src/OpenTelemetry.Resources.Container/ContainerDetector.cs +++ b/src/OpenTelemetry.Resources.Container/ContainerDetector.cs @@ -152,7 +152,11 @@ private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex { containerId = GetIdFromLineV1(line); } +#if NET else if (cgroupVersion == ParseMode.V2 && line.Contains(Hostname, StringComparison.Ordinal)) +#else + else if (cgroupVersion == ParseMode.V2 && line.Contains(Hostname)) +#endif { containerId = GetIdFromLineV2(line); } diff --git a/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj b/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj index befa4a2439..ad9bec76ea 100644 --- a/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj +++ b/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj @@ -1,13 +1,14 @@ + - $(NetMinimumSupportedVersion) - OpenTelemetry Extensions - Container Resource Detector from Container environment. + net8.0;$(NetStandardMinimumSupportedVersion) + OpenTelemetry Resource Detectors for Container environment. Resources.Container- - + true @@ -20,4 +21,5 @@ + diff --git a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj index 5edbf2dfe3..7af24366c8 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj +++ b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj @@ -1,17 +1,13 @@ - Unit test project for Container Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) + Unit test project for Container Detector for OpenTelemetry. - - - - From 60ffba4e8b31869a17be431ec40fc55fc381dd78 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:21:39 +0000 Subject: [PATCH 1324/1499] [Resources.Gcp] Replace .NET 6 target with .NET 8 (#2167) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Resources.Gcp.csproj | 10 ++++++---- .../OpenTelemetry.Resources.Gcp.Tests.csproj | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj index 02fc5995bd..940fb756f3 100644 --- a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj +++ b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj @@ -1,13 +1,14 @@ + - net6.0;netstandard2.0 - OpenTelemetry Resource Detectors for Google Cloud Platform environments + net8.0;$(NetStandardMinimumSupportedVersion) + OpenTelemetry Resource Detectors for Google Cloud Platform environments. $(PackageTags);ResourceDetector Resources.Gcp- - + true @@ -24,4 +25,5 @@ + diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj index e1df281415..663e1e5a41 100644 --- a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj +++ b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for GCP Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for GCP Detector for OpenTelemetry. From 6905370de0014d938fb63df60be67d0dbd44274e Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:30:31 +0000 Subject: [PATCH 1325/1499] [Sampler.AWS] Replace .NET 6 target with .NET 8 (#2172) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 3 +++ .../OpenTelemetry.Sampler.AWS.csproj | 9 +++++---- .../OpenTelemetry.Sampler.AWS.Tests.csproj | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 94a027034e..01fdb8bef2 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2172](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2172)) + ## 0.1.0-alpha.2 Released 2024-Sep-09 diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index 8811644f38..791d699747 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -1,14 +1,15 @@ + - net6.0;netstandard2.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry remote sampler for AWS X-Ray. Sampler.AWS- - + true @@ -18,7 +19,7 @@ - + diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index d8db5a8c05..9f6ec1878e 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 0decdac9f3e544e84cd3103564c0d8c1346fa8f3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 4 Oct 2024 11:10:39 -0700 Subject: [PATCH 1326/1499] [geneva] Bump MessagePack to a more modern version in test project (#2177) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../GenevaLogExporterTests.cs | 32 +++++++++---------- .../GenevaTraceExporterTests.cs | 2 +- .../LogSerializationTests.cs | 2 +- .../MessagePackSerializerTests.cs | 8 ++--- ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index 3b1cfe5cd9..e5065cc143 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -183,7 +183,7 @@ public void TableNameMappingTest(params string[] category) Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); actualTableName = (fluentdData as object[])[0] as string; Assert.Equal(mapping.Value, actualTableName); logRecordList.Clear(); @@ -200,7 +200,7 @@ public void TableNameMappingTest(params string[] category) Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); actualTableName = (fluentdData as object[])[0] as string; Assert.Equal(defaultLogTable, actualTableName); logRecordList.Clear(); @@ -302,7 +302,7 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); actualTableName = (fluentdData as object[])[0] as string; userInitializedCategoryToTableNameMappings.TryGetValue(mapping.Key, out var expectedTableNme); Assert.Equal(expectedTableNme, actualTableName); @@ -319,7 +319,7 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); actualTableName = (fluentdData as object[])[0] as string; string expectedTableName = string.Empty; expectedTableName = mapping.Value; @@ -418,7 +418,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) _ = receiverSocket.Receive(serializedData); } - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Options); var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; @@ -540,7 +540,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var body = GetField(fluentdData, "body"); // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` @@ -564,7 +564,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); body = GetField(fluentdData, "body"); // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` @@ -585,7 +585,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); body = GetField(fluentdData, "body"); // Even though Formatter is null, body is populated with the state @@ -609,7 +609,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); Assert.Equal("Value1", GetField(fluentdData, "Key1")); body = GetField(fluentdData, "body"); @@ -750,7 +750,7 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin foreach (var logRecord in logRecordList) { _ = exporter.SerializeLogRecord(logRecord); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); this.AssertFluentdForwardModeForLogRecord(exporterOptions, fluentdData, logRecord); } } @@ -942,7 +942,7 @@ public void SerializationTestForException() // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var exceptionType = GetField(fluentdData, "env_ex_type"); var exceptionMessage = GetField(fluentdData, "env_ex_msg"); Assert.Equal("System.Exception", exceptionType); @@ -1035,7 +1035,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var eventName = GetField(fluentdData, "env_name"); if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) @@ -1055,7 +1055,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod logger.LogInformation(eventId: new EventId(1, "TestEventNameWithLogExtensionMethod"), "Hello from {Name} {Price}.", "tomato", 2.99); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); eventName = GetField(fluentdData, "env_name"); if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) @@ -1074,7 +1074,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod logger.LogInformation(eventId: 1, "Hello from {Name} {Price}.", "tomato", 2.99); _ = exporter.SerializeLogRecord(logRecordList[0]); - fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); eventName = GetField(fluentdData, "env_name"); Assert.Equal(hasTableNameMapping ? "CustomTableName" : "Log", eventName); #endregion @@ -1179,7 +1179,7 @@ public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCu // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; @@ -1282,7 +1282,7 @@ public void SerializationTestForEventId() // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 066a4ccbec..c4d8d21205 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -257,7 +257,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, listener.ActivityStopped = (activity) => { _ = exporter.SerializeActivity(activity); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields, customChecksForActivity); invocationCount++; }; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index 75b3bb94f1..8fc867f571 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -126,7 +126,7 @@ private static Dictionary GetExportedFieldsAfterLogging(Action(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Instance); + object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); return GetFields(fluentdData); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index ae55fea742..997a6afd87 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -25,11 +25,11 @@ private void AssertBytes(byte[] expected, byte[] actual, int length) } } - private void MessagePackSerializer_TestSerialization(object obj) + private void MessagePackSerializer_TestSerialization(T value) { var buffer = new byte[64 * 1024]; - var length = MessagePackSerializer.Serialize(buffer, 0, obj); - this.AssertBytes(MessagePack.MessagePackSerializer.Serialize(obj), buffer, length); + var length = MessagePackSerializer.Serialize(buffer, 0, value); + this.AssertBytes(MessagePack.MessagePackSerializer.Serialize(value), buffer, length); } private void MessagePackSerializer_TestASCIIStringSerialization(string input) @@ -134,7 +134,7 @@ private void MessagePackSerializer_TestUnicodeStringSerialization(string input) [Fact] public void MessagePackSerializer_Null() { - this.MessagePackSerializer_TestSerialization(null); + this.MessagePackSerializer_TestSerialization(null); } [Fact] diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index c7f15254ab..39cdc04c15 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -16,7 +16,7 @@ - + From d8643cb30fb029f3deafddced52f09fc71306485 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:42:32 +0000 Subject: [PATCH 1327/1499] [Instrumentation.StackExchangeRedis] Replace .NET 6 target with .NET 8 (#2160) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .github/workflows/integration.yml | 2 +- .../CHANGELOG.md | 3 +++ ...enTelemetry.Instrumentation.StackExchangeRedis.csproj | 9 +++++---- .../Dockerfile | 2 +- .../Dockerfile | 2 +- .../Dockerfile | 2 +- ...metry.Instrumentation.StackExchangeRedis.Tests.csproj | 9 +++++---- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3f242240f0..8acaf0ee2d 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -14,7 +14,7 @@ jobs: strategy: fail-fast: false matrix: - version: [net6.0, net8.0] + version: [net8.0] steps: - uses: actions/checkout@v4 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 60254ac153..252b9bf246 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2160](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2160)) + ## 1.9.0-beta.1 Released 2024-Jul-23 diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index 253d8083be..bc2acbe7a7 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -1,14 +1,15 @@ + - net6.0;netstandard2.0;net462 - StackExchange.Redis instrumentation for OpenTelemetry .NET + net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + StackExchange.Redis instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing;Redis;StackExchange.Redis Instrumentation.StackExchangeRedis- - + true diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile index 206fa6b334..ade4c12591 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/Dockerfile @@ -11,7 +11,7 @@ ARG PUBLISH_FRAMEWORK=net8.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.Cassandra.Tests" -RUN dotnet publish "OpenTelemetry.Instrumentation.Cassandra.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} +RUN dotnet publish "OpenTelemetry.Instrumentation.Cassandra.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final WORKDIR /test diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile index 300c474662..13c925e0e4 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile @@ -11,7 +11,7 @@ ARG PUBLISH_FRAMEWORK=net8.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests" -RUN dotnet publish "OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} +RUN dotnet publish "OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final WORKDIR /test diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile index a8f86395df..f17bd22d2b 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile @@ -11,7 +11,7 @@ ARG PUBLISH_FRAMEWORK=net8.0 WORKDIR /repo COPY . ./ WORKDIR "/repo/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests" -RUN dotnet publish "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true -p:TARGET_FRAMEWORK=${PUBLISH_FRAMEWORK} +RUN dotnet publish "OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj" -c "${PUBLISH_CONFIGURATION}" -f "${PUBLISH_FRAMEWORK}" -o /drop -p:IntegrationBuild=true FROM mcr.microsoft.com/dotnet/sdk:${TEST_SDK_VERSION} AS final WORKDIR /test diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 2071a18c16..48ff8eaecc 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -1,10 +1,10 @@ + - Unit test project for OpenTelemetry StackExchangeRedis instrumentation - $(SupportedNetTargets) - $(TargetFrameworks);net462 - $(TARGET_FRAMEWORK) + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry StackExchangeRedis instrumentation. @@ -24,4 +24,5 @@ + From 1f7c44e6d780136ea8f3ce95ef17a79baa630a7d Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:49:54 +0000 Subject: [PATCH 1328/1499] [repo] Reencode few files from UTF-8 with BOM to UTF-8 (#2175) --- NuGet.config | 2 +- build/stylecop.json | 2 +- build/xunit.runner.json | 2 +- .../Properties/launchSettings.json | 2 +- .../appsettings.Development.json | 12 ++++++------ .../metadatav4-response-container-fargate.json | 2 +- .../metadatav4-response-task-fargate.json | 2 +- .../Properties/launchSettings.json | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/NuGet.config b/NuGet.config index 1374d3c7f9..64efb74c6b 100644 --- a/NuGet.config +++ b/NuGet.config @@ -1,4 +1,4 @@ - + diff --git a/build/stylecop.json b/build/stylecop.json index 6d32e9d35e..2aea02972f 100644 --- a/build/stylecop.json +++ b/build/stylecop.json @@ -1,4 +1,4 @@ -{ +{ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", "settings": { "documentationRules": { diff --git a/build/xunit.runner.json b/build/xunit.runner.json index fdeefaa456..ba955e0f60 100644 --- a/build/xunit.runner.json +++ b/build/xunit.runner.json @@ -1,4 +1,4 @@ -{ +{ "maxParallelThreads": 1, "parallelizeTestCollections": false } diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json index 734290b4b9..4ea99f27f4 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Properties/launchSettings.json @@ -10,4 +10,4 @@ } } } -} \ No newline at end of file +} diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.Development.json b/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.Development.json index dba68eb124..70734009e5 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.Development.json +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/appsettings.Development.json @@ -1,9 +1,9 @@ -{ - "Logging": { - "LogLevel": { +{ + "Logging": { + "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" - } - } -} + } + } +} diff --git a/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-container-fargate.json b/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-container-fargate.json index ccbe70bc44..9a664c91b6 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-container-fargate.json +++ b/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-container-fargate.json @@ -47,4 +47,4 @@ "awslogs-stream": "ecs/curl/cd189a933e5849daa93386466019ab50" }, "LogDriver": "awslogs" -} \ No newline at end of file +} diff --git a/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-task-fargate.json b/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-task-fargate.json index 7979db708d..ba723620d0 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-task-fargate.json +++ b/test/OpenTelemetry.Resources.AWS.Tests/ecs_metadata/metadatav4-response-task-fargate.json @@ -74,4 +74,4 @@ } ], "LaunchType": "FARGATE" -} \ No newline at end of file +} diff --git a/test/TestApp.AspNetCore/Properties/launchSettings.json b/test/TestApp.AspNetCore/Properties/launchSettings.json index f627182e41..faa3024179 100644 --- a/test/TestApp.AspNetCore/Properties/launchSettings.json +++ b/test/TestApp.AspNetCore/Properties/launchSettings.json @@ -9,4 +9,4 @@ "applicationUrl": "https://localhost:58211;http://localhost:58212" } } -} \ No newline at end of file +} From 98a36c86cc313657175c0ecc85d787c0e180d8f3 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Fri, 4 Oct 2024 21:24:05 +0000 Subject: [PATCH 1329/1499] [Resources.AWS] Remove .NET 6 target and add .NET Standard 2.0 (#2164) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../{net6.0 => net8.0}/PublicAPI.Shipped.txt | 0 .../{net6.0 => net8.0}/PublicAPI.Unshipped.txt | 0 src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs | 2 +- src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs | 6 ++---- .../AWSResourceBuilderExtensions.cs | 2 +- src/OpenTelemetry.Resources.AWS/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Resources.AWS.csproj | 13 +++++-------- .../ResourceDetectorUtils.cs | 2 +- .../OpenTelemetry.Resources.AWS.Tests.csproj | 5 ++--- 9 files changed, 16 insertions(+), 18 deletions(-) rename src/OpenTelemetry.Resources.AWS/.publicApi/{net6.0 => net8.0}/PublicAPI.Shipped.txt (100%) rename src/OpenTelemetry.Resources.AWS/.publicApi/{net6.0 => net8.0}/PublicAPI.Unshipped.txt (100%) diff --git a/src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Resources.AWS/.publicApi/net8.0/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Resources.AWS/.publicApi/net8.0/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Resources.AWS/.publicApi/net8.0/PublicAPI.Unshipped.txt similarity index 100% rename from src/OpenTelemetry.Resources.AWS/.publicApi/net6.0/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Resources.AWS/.publicApi/net8.0/PublicAPI.Unshipped.txt diff --git a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs index c7b8e815c2..c992995072 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NETFRAMEWORK +#if NET using System.Text.Json; using System.Text.RegularExpressions; diff --git a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index d28d0fc434..c26e10571d 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NETFRAMEWORK +#if NET using System.Text; using OpenTelemetry.Resources.AWS.Models; @@ -62,7 +62,7 @@ internal static List> ExtractResourceAttributes(str { try { - var stringBuilder = new StringBuilder(); + var stringBuilder = new StringBuilder("Bearer "); using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) { @@ -72,8 +72,6 @@ internal static List> ExtractResourceAttributes(str } } - stringBuilder.Insert(0, "Bearer "); - return stringBuilder.ToString(); } catch (Exception ex) diff --git a/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs b/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs index f963f1e672..325f7a5b08 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSResourceBuilderExtensions.cs @@ -33,7 +33,7 @@ public static ResourceBuilder AddAWSEC2Detector(this ResourceBuilder builder) return builder.AddDetector(new AWSEC2Detector()); } -#if !NETFRAMEWORK +#if NET /// /// Enables AWS ECS resource detector. /// diff --git a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md index 8997d27ac3..96cd089d1b 100644 --- a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md @@ -5,6 +5,10 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Drop support for .NET 6 as this target is no longer supported + and add .NET Standard 2.0 target. + ([#2164](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2164)) + ## 1.5.0-beta.1 Released 2024-Jun-04 diff --git a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj index 102b4946b0..acfae6f7c4 100644 --- a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj +++ b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj @@ -2,24 +2,21 @@ - net6.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - OpenTelemetry Extensions - AWS Resource Detectors for ElasticBeanstalk, EC2, ECS, EKS. + OpenTelemetry Resource Detectors for AWS ElasticBeanstalk, EC2, ECS, EKS. Resources.AWS- - + true - - - - + diff --git a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs index ab957e7539..4ec15c1a90 100644 --- a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs @@ -6,7 +6,7 @@ #endif using System.Text; using System.Text.Json; -#if !NETFRAMEWORK +#if NET using System.Text.Json.Serialization.Metadata; #endif diff --git a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj index 8143037e07..abfaa2d3f6 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj +++ b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj @@ -1,10 +1,10 @@ - Unit test project for AWS Detector for OpenTelemetry - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + Unit test project for AWS Detector for OpenTelemetry. @@ -25,7 +25,6 @@ PreserveNewest - From 0f2bef7849efc178d2866954d713193bebe9bb67 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Sat, 5 Oct 2024 18:11:30 +0000 Subject: [PATCH 1330/1499] [Instrumentation.ConfluentKafka] Remove ImplicitUsings property (#2179) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- .../OpenTelemetry.Instrumentation.ConfluentKafka.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj index d607322439..099e818c78 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj @@ -7,7 +7,6 @@ $(PackageTags);distributed-tracing;Kafka;Confluent.Kafka true Instrumentation.ConfluentKafka- - true - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) From 71ca622c6ba1401f845a4e99768eda5aa1712d60 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 7 Oct 2024 05:14:50 +0000 Subject: [PATCH 1332/1499] [TestApp.AspNetCore] Replace .NET 6 target with .NET 8 (#2184) --- test/TestApp.AspNetCore/TestApp.AspNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj index ae0043309a..7b4d72c295 100644 --- a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj +++ b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet6) From c32fea375a52344ee1ebbf219675decb2699c9bd Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 7 Oct 2024 05:27:29 +0000 Subject: [PATCH 1333/1499] [repo] Simplify preprocessor directives after dropping support for .NET 6 (#2180) --- .../Internal/Transports/TransportSendRequest.cs | 2 +- .../OneCollectorExporterValidationException.cs | 4 ++-- ...nerator.net6.cs => AWSXRayIdGenerator.net.cs} | 2 +- ...trumentationMeterProviderBuilderExtensions.cs | 4 ++-- .../AspNetCoreMetrics.cs | 2 +- .../OpenTelemetryConsumerBuilderExtensions.cs | 2 +- .../OpenTelemetryProducerBuilderExtensions.cs | 2 +- ...trumentationMeterProviderBuilderExtensions.cs | 4 ++-- .../HttpHandlerDiagnosticListener.cs | 2 +- .../OpenTelemetryConfigurationExtensions.cs | 10 +++++----- .../CommonSchemaJsonSerializationHelperTests.cs | 2 -- .../BasicTests.cs | 4 ++-- .../MetricTests.cs | 10 +++++----- .../RouteTests/TestApplication/RouteInfo.cs | 4 ++-- .../TestApplication/TestApplicationFactory.cs | 4 ++-- .../HttpClientTests.cs | 16 ++++++++-------- 16 files changed, 36 insertions(+), 38 deletions(-) rename src/OpenTelemetry.Extensions.AWS/{AWSXRayIdGenerator.net6.cs => AWSXRayIdGenerator.net.cs} (98%) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs index 7ed65321d4..13d059eb0f 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/TransportSendRequest.cs @@ -13,7 +13,7 @@ internal readonly struct TransportSendRequest { public TransportSendRequest() { -#if !NET8_0_OR_GREATER +#if !NET // Note: This is needed because < NET7 doesn't understand required. this.ItemType = string.Empty; this.ItemStream = default!; diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs index c6aea54de2..b53c613c82 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterValidationException.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NET8_0_OR_GREATER +#if !NET using System.Runtime.Serialization; #endif @@ -43,7 +43,7 @@ public OneCollectorExporterValidationException(string message, Exception? innerE { } -#if !NET8_0_OR_GREATER +#if !NET private OneCollectorExporterValidationException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net.cs similarity index 98% rename from src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs rename to src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net.cs index 44f465e262..cd9f65dd91 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net6.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.net.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET6_0_OR_GREATER +#if NET using System.Buffers.Binary; using System.Diagnostics; using System.Security.Cryptography; diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs index a9d7ef7c8a..0815bef20e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NET8_0_OR_GREATER +#if !NET using OpenTelemetry.Instrumentation.AspNetCore; using OpenTelemetry.Instrumentation.AspNetCore.Implementation; #endif @@ -24,7 +24,7 @@ public static MeterProviderBuilder AddAspNetCoreInstrumentation( { Guard.ThrowIfNull(builder); -#if NET8_0_OR_GREATER +#if NET return builder.ConfigureMeters(); #else // Note: Warm-up the status code and method mapping. diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs index 00e34bd2ba..75676510f4 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NET8_0_OR_GREATER +#if !NET using OpenTelemetry.Instrumentation.AspNetCore.Implementation; namespace OpenTelemetry.Instrumentation.AspNetCore; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs index 11936c3694..0e2762a779 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs @@ -17,7 +17,7 @@ public static class OpenTelemetryConsumerBuilderExtensions /// Type of the value. /// The instance. /// An instance. -#if !NETFRAMEWORK && !NETSTANDARD +#if NET [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedConsumerBuilder' constructor to avoid reflection.")] #endif public static InstrumentedConsumerBuilder AsInstrumentedConsumerBuilder(this ConsumerBuilder consumerBuilder) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs index f2a722f5af..071736f509 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs @@ -17,7 +17,7 @@ public static class OpenTelemetryProducerBuilderExtensions /// Type of the value. /// The instance. /// An instance. -#if !NETFRAMEWORK && !NETSTANDARD +#if NET [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedProducerBuilder' constructor to avoid reflection.")] #endif public static InstrumentedProducerBuilder AsInstrumentedProducerBuilder(this ProducerBuilder producerBuilder) diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs index 2694208968..8008ae7262 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentationMeterProviderBuilderExtensions.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NET8_0_OR_GREATER +#if !NET #if !NETFRAMEWORK using OpenTelemetry.Instrumentation.Http; #endif @@ -27,7 +27,7 @@ public static MeterProviderBuilder AddHttpClientInstrumentation( { Guard.ThrowIfNull(builder); -#if NET8_0_OR_GREATER +#if NET return builder .AddMeter("System.Net.Http") .AddMeter("System.Net.NameResolution"); diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index 2fb2b20867..14e2ebbec7 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -310,7 +310,7 @@ static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception private static string? GetErrorType(Exception exc) { -#if NET8_0_OR_GREATER +#if NET // For net8.0 and above exception type can be found using HttpRequestError. // https://learn.microsoft.com/dotnet/api/system.net.http.httprequesterror?view=net-8.0 if (exc is HttpRequestException httpRequestException) diff --git a/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs b/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs index c61377cb19..e663c53a67 100644 --- a/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs +++ b/src/Shared/Configuration/OpenTelemetryConfigurationExtensions.cs @@ -4,7 +4,7 @@ #nullable enable using System.Diagnostics; -#if !NETFRAMEWORK && !NETSTANDARD2_0 +#if NET || NETSTANDARD2_1 using System.Diagnostics.CodeAnalysis; #endif using System.Globalization; @@ -15,7 +15,7 @@ internal static class OpenTelemetryConfigurationExtensions { public delegate bool TryParseFunc( string value, -#if !NETFRAMEWORK && !NETSTANDARD2_0 +#if NET || NETSTANDARD2_1 [NotNullWhen(true)] #endif out T? parsedValue); @@ -23,7 +23,7 @@ public delegate bool TryParseFunc( public static bool TryGetStringValue( this IConfiguration configuration, string key, -#if !NETFRAMEWORK && !NETSTANDARD2_0 +#if NET || NETSTANDARD2_1 [NotNullWhen(true)] #endif out string? value) @@ -39,7 +39,7 @@ public static bool TryGetUriValue( this IConfiguration configuration, IConfigurationExtensionsLogger logger, string key, -#if !NETFRAMEWORK && !NETSTANDARD2_0 +#if NET || NETSTANDARD2_1 [NotNullWhen(true)] #endif out Uri? value) @@ -112,7 +112,7 @@ public static bool TryGetValue( IConfigurationExtensionsLogger logger, string key, TryParseFunc tryParseFunc, -#if !NETFRAMEWORK && !NETSTANDARD2_0 +#if NET || NETSTANDARD2_1 [NotNullWhen(true)] #endif out T? value) diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs index d23addc8d5..29431596de 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -99,9 +99,7 @@ public void SerializeComplexValueToJsonTest() var typeWithISpanFormattableOverflow = new TypeWithISpanFormattable(overflow: true); this.SerializeValueToJsonTest(typeWithISpanFormattableOverflow, "\"Overflow\""); -#endif -#if NET8_0_OR_GREATER var dateOnly = DateOnly.FromDateTime(dt); this.SerializeValueToJsonTest(dateOnly, $"\"{dateOnly:O}\""); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 070a56bd84..fb0284ac09 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -738,7 +738,7 @@ public async Task ActivitiesStartedInMiddlewareBySettingHostActivityToNullShould Assert.Equal("Microsoft.AspNetCore.Hosting.HttpRequestIn", aspnetcoreframeworkactivity.OperationName); } -#if NET8_0_OR_GREATER +#if NET [Fact] public async Task UserRegisteredActivitySourceIsUsedForActivityCreationByAspNetCore() { @@ -1150,7 +1150,7 @@ private static void WaitForActivityExport(List exportedItems, int coun private static void ValidateAspNetCoreActivity(Activity activityToValidate, string expectedHttpPath) { Assert.Equal(ActivityKind.Server, activityToValidate.Kind); -#if NET8_0_OR_GREATER +#if NET Assert.Equal(HttpInListener.AspNetCoreActivitySourceName, activityToValidate.Source.Name); Assert.NotNull(activityToValidate.Source.Version); Assert.Empty(activityToValidate.Source.Version); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 413c335194..e0eb0c32b5 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -1,19 +1,19 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET8_0_OR_GREATER +#if NET using System.Threading.RateLimiting; using Microsoft.AspNetCore.Builder; #endif using Microsoft.AspNetCore.Hosting; -#if NET8_0_OR_GREATER +#if NET using Microsoft.AspNetCore.Http; #endif using Microsoft.AspNetCore.Mvc.Testing; -#if NET8_0_OR_GREATER +#if NET using Microsoft.AspNetCore.RateLimiting; #endif -#if NET8_0_OR_GREATER +#if NET using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; #endif @@ -38,7 +38,7 @@ public void AddAspNetCoreInstrumentation_BadArgs() Assert.Throws(builder!.AddAspNetCoreInstrumentation); } -#if NET8_0_OR_GREATER +#if NET [Fact] public async Task ValidateNet8MetricsAsync() { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs index 08433fc666..610145dbc7 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs @@ -5,7 +5,7 @@ using System.Text.Json.Serialization; using Microsoft.AspNetCore.Http; -#if NET8_0_OR_GREATER +#if NET using Microsoft.AspNetCore.Http.Metadata; #endif using Microsoft.AspNetCore.Mvc.Abstractions; @@ -40,7 +40,7 @@ public void SetValues(HttpContext context) this.Path = $"{context.Request.Path}{context.Request.QueryString}"; var endpoint = context.GetEndpoint(); this.RawText = (endpoint as RouteEndpoint)?.RoutePattern.RawText; -#if NET8_0_OR_GREATER +#if NET this.RouteDiagnosticMetadata = endpoint?.Metadata.GetMetadata()?.Route; #endif this.RouteData = new Dictionary(); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs index 51cd4ef643..aa864b5bab 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs @@ -131,7 +131,7 @@ private static WebApplication CreateMinimalApiApplication() app.MapGet("/MinimalApi", () => Results.Ok()); app.MapGet("/MinimalApi/{id}", (int id) => Results.Ok()); -#if NET8_0_OR_GREATER +#if NET var api = app.MapGroup("/MinimalApiUsingMapGroup"); api.MapGet("/", () => Results.Ok()); api.MapGet("/{id}", (int id) => Results.Ok()); @@ -188,7 +188,7 @@ private static WebApplication CreateExceptionHandlerApplication() // This is because ASP.NET Core 8+ has native metric instrumentation. // When ASP.NET Core 8.0.2 is released then its behavior will align with .NET 6/7. // See: https://github.com/dotnet/aspnetcore/issues/52648#issuecomment-1853432776 -#if !NET8_0_OR_GREATER +#if !NET app.MapGet("/Exception", (ctx) => throw new ApplicationException()); #else app.MapGet("/Exception", () => Results.Content(content: "Error", contentType: null, contentEncoding: null, statusCode: 500)); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index f936f66fd1..83e594179b 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -5,7 +5,7 @@ #if NETFRAMEWORK using System.Net.Http; #endif -#if !NET8_0_OR_GREATER +#if !NET using System.Globalization; using System.Reflection; using System.Text.Json; @@ -21,7 +21,7 @@ public partial class HttpClientTests { public static readonly IEnumerable TestData = HttpTestData.ReadTestCases(); -#if !NET8_0_OR_GREATER +#if !NET private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; #endif @@ -73,7 +73,7 @@ await HttpOutCallsAreCollectedSuccessfullyBodyAsync( enableMetrics: false); } -#if !NET8_0_OR_GREATER +#if !NET [Fact] public async Task DebugIndividualTestAsync() { @@ -115,7 +115,7 @@ public async Task CheckEnrichmentWhenSampling() await CheckEnrichment(new AlwaysOnSampler(), true, this.url); } -#if NET8_0_OR_GREATER +#if NET [Theory] [MemberData(nameof(TestData))] public async Task ValidateNet8MetricsAsync(HttpOutTestCase tc) @@ -172,7 +172,7 @@ public async Task ValidateNet8MetricsAsync(HttpOutTestCase tc) } #endif -#if NET8_0_OR_GREATER +#if NET [Fact] public async Task HttpCancellationLogsError() { @@ -362,7 +362,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( Assert.DoesNotContain(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode); Assert.DoesNotContain(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion); -#if NET8_0_OR_GREATER +#if NET // we are using fake address so it will be "name_resolution_error" // TODO: test other error types. Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "name_resolution_error"); @@ -410,7 +410,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( if (enableTracing) { var activity = Assert.Single(activities); -#if !NET8_0_OR_GREATER +#if !NET Assert.Equal(activity.Duration.TotalSeconds, sum); #endif } @@ -461,7 +461,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( Assert.DoesNotContain(attributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion); Assert.DoesNotContain(attributes, kvp => kvp.Key == SemanticConventions.AttributeHttpResponseStatusCode); -#if NET8_0_OR_GREATER +#if NET // we are using fake address so it will be "name_resolution_error" // TODO: test other error types. Assert.Contains(attributes, kvp => kvp.Key == SemanticConventions.AttributeErrorType && kvp.Value?.ToString() == "name_resolution_error"); From c7e88349f5fe25e105246ee9c9f872f68b85f52e Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 7 Oct 2024 07:07:53 +0000 Subject: [PATCH 1334/1499] [Exporter.Instana] Replace .NET 6 target with .NET 8 for test project (#2183) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz --- .../OpenTelemetry.Exporter.Instana.csproj | 6 +++--- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj index fe7cf73fad..7e671d211d 100644 --- a/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj +++ b/src/OpenTelemetry.Exporter.Instana/OpenTelemetry.Exporter.Instana.csproj @@ -2,9 +2,9 @@ - netstandard2.0;$(NetFrameworkMinimumSupportedVersion) + $(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) Instana Tracing APM - Instana .NET Exporter for OpenTelemetry + Instana .NET Exporter for OpenTelemetry. Exporter.Instana- 1.0.3 @@ -12,7 +12,7 @@ - - - - - - diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/THIRD-PARTY-NOTICES.TXT b/test/OpenTelemetry.Exporter.Geneva.Tests/THIRD-PARTY-NOTICES.TXT new file mode 100644 index 0000000000..0f9d5a997e --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/THIRD-PARTY-NOTICES.TXT @@ -0,0 +1,27 @@ +OpenTelemetry.Exporter.Geneva.Tests uses third-party libraries or other +resources that may be distributed under licenses different than the +OpenTelemetry.Exporter.Geneva.Tests software. + +The attached notices are provided for information only. + +License notice for kaitai-io/kaitai_struct_csharp_runtime +------------------------------- + +Copyright 2015-2024 Kaitai Project: MIT license + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From b42426919ff563a76728820f63f7164eb7337744 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:18:11 +0000 Subject: [PATCH 1336/1499] [Resources.AWS] Use System.Text.Json source generator with .NET Standard 2.0 (#2185) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../AWSEBSDetector.cs | 6 ++--- .../AWSEC2Detector.cs | 6 ++--- .../ResourceDetectorUtils.cs | 22 +++++++++---------- .../SourceGenerationContext.cs | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs index c17c291add..80acea1404 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs @@ -84,10 +84,10 @@ internal static List> ExtractResourceAttributes(AWS internal static AWSEBSMetadataModel? GetEBSMetadata(string filePath) { -#if NET - return ResourceDetectorUtils.DeserializeFromFile(filePath, SourceGenerationContext.Default.AWSEBSMetadataModel); -#else +#if NETFRAMEWORK return ResourceDetectorUtils.DeserializeFromFile(filePath); +#else + return ResourceDetectorUtils.DeserializeFromFile(filePath, SourceGenerationContext.Default.AWSEBSMetadataModel); #endif } } diff --git a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs index 4d41c33338..076adbf48d 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs @@ -83,10 +83,10 @@ internal static List> ExtractResourceAttributes(AWS internal static AWSEC2IdentityDocumentModel? DeserializeResponse(string response) { -#if NET - return ResourceDetectorUtils.DeserializeFromString(response, SourceGenerationContext.Default.AWSEC2IdentityDocumentModel); -#else +#if NETFRAMEWORK return ResourceDetectorUtils.DeserializeFromString(response); +#else + return ResourceDetectorUtils.DeserializeFromString(response, SourceGenerationContext.Default.AWSEC2IdentityDocumentModel); #endif } diff --git a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs index 4ec15c1a90..b870fd499d 100644 --- a/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs +++ b/src/OpenTelemetry.Resources.AWS/ResourceDetectorUtils.cs @@ -6,7 +6,7 @@ #endif using System.Text; using System.Text.Json; -#if NET +#if !NETFRAMEWORK using System.Text.Json.Serialization.Metadata; #endif @@ -17,7 +17,7 @@ namespace OpenTelemetry.Resources.AWS; /// internal static class ResourceDetectorUtils { -#if !NET +#if NETFRAMEWORK private static readonly JsonSerializerOptions JsonSerializerOptions = new(JsonSerializerDefaults.Web); #endif @@ -47,31 +47,31 @@ internal static async Task SendOutRequestAsync( } } -#if NET - internal static T? DeserializeFromFile(string filePath, JsonTypeInfo jsonTypeInfo) +#if NETFRAMEWORK + internal static T? DeserializeFromFile(string filePath) { using (var stream = GetStream(filePath)) { - return JsonSerializer.Deserialize(stream, jsonTypeInfo); + return JsonSerializer.Deserialize(stream, JsonSerializerOptions); } } - internal static T? DeserializeFromString(string json, JsonTypeInfo jsonTypeInfo) + internal static T? DeserializeFromString(string json) { - return JsonSerializer.Deserialize(json, jsonTypeInfo); + return JsonSerializer.Deserialize(json, JsonSerializerOptions); } #else - internal static T? DeserializeFromFile(string filePath) + internal static T? DeserializeFromFile(string filePath, JsonTypeInfo jsonTypeInfo) { using (var stream = GetStream(filePath)) { - return JsonSerializer.Deserialize(stream, JsonSerializerOptions); + return JsonSerializer.Deserialize(stream, jsonTypeInfo); } } - internal static T? DeserializeFromString(string json) + internal static T? DeserializeFromString(string json, JsonTypeInfo jsonTypeInfo) { - return JsonSerializer.Deserialize(json, JsonSerializerOptions); + return JsonSerializer.Deserialize(json, jsonTypeInfo); } #endif diff --git a/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs b/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs index 51f0b9a4d5..8857095023 100644 --- a/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs +++ b/src/OpenTelemetry.Resources.AWS/SourceGenerationContext.cs @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET +#if !NETFRAMEWORK using System.Text.Json.Serialization; using OpenTelemetry.Resources.AWS.Models; From 508405465a83af8d625b22c6559929c79c2ec0a3 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:22:40 +0000 Subject: [PATCH 1337/1499] [repo] Some cleanup after dropping support for .NET 6 (#2187) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/workflows/Component.BuildTest.yml | 2 +- .../workflows/ci-Exporter.OneCollector-Integration.yml | 2 +- .github/workflows/ci.yml | 6 +++--- build/docker-compose.net6.0.yml | 9 --------- opentelemetry-dotnet-contrib.sln | 1 - .../LogSerializationTests.cs | 2 +- .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 2 +- 8 files changed, 8 insertions(+), 18 deletions(-) delete mode 100644 build/docker-compose.net6.0.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c87b9935e8..9441d40269 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -79,7 +79,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 b4b916c293..f3ac05bfde 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -18,7 +18,7 @@ on: required: false type: string tfm-list: - default: '[ "net462", "net6.0", "net8.0" ]' + default: '[ "net462", "net8.0" ]' required: false type: string diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index 4f1a2dd9d2..bac716d202 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -29,7 +29,7 @@ jobs: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: os: [ windows-latest, ubuntu-latest ] - version: [ net462, net6.0, net8.0 ] + version: [ net462, net8.0 ] exclude: - os: ubuntu-latest version: net462 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28a3db1968..8368761a64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,7 +196,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.AspNetCore code-cov-name: Instrumentation.AspNetCore - tfm-list: '[ "net6.0", "net8.0" ]' + tfm-list: '[ "net8.0" ]' build-test-instrumentation-aws: needs: detect-changes @@ -219,7 +219,7 @@ jobs: with: project-name: Component[OpenTelemetry.Instrumentation.AWSLambda] code-cov-name: Instrumentation.AWSLambda - tfm-list: '[ "net6.0", "net8.0" ]' + tfm-list: '[ "net8.0" ]' build-test-instrumentation-cassandra: needs: detect-changes @@ -285,7 +285,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.EventCounters code-cov-name: Instrumentation.EventCounters - tfm-list: '[ "net6.0", "net8.0" ]' + tfm-list: '[ "net8.0" ]' build-test-instrumentation-grpccore: needs: detect-changes diff --git a/build/docker-compose.net6.0.yml b/build/docker-compose.net6.0.yml deleted file mode 100644 index 099f100727..0000000000 --- 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/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 68d49b391e..b4f5fc258c 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -55,7 +55,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.props = build\Common.props build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk - 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\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index 8fc867f571..dd311dcff1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -15,7 +15,7 @@ public class LogSerializationTests { /* Run from the current directory: - dotnet test -f net6.0 --filter FullyQualifiedName~LogSerializationTests -l "console;verbosity=detailed" + dotnet test -f net8.0 --filter FullyQualifiedName~LogSerializationTests -l "console;verbosity=detailed" */ private readonly ITestOutputHelper output; diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 0823891329..039e19e902 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -8,7 +8,7 @@ - + From 11281a791fea314c569bd9b54fea4818cae07cf6 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:20:34 +0000 Subject: [PATCH 1338/1499] [repo] Replace some hardcoded TFM (#2192) --- .../OpenTelemetry.Exporter.Geneva.csproj | 4 ++-- .../OpenTelemetry.Exporter.OneCollector.csproj | 4 ++-- .../OpenTelemetry.Exporter.Stackdriver.csproj | 2 +- .../OpenTelemetry.Extensions.AWS.csproj | 7 ++----- .../OpenTelemetry.Extensions.csproj | 4 ++-- .../OpenTelemetry.Instrumentation.AWSLambda.csproj | 4 ++-- ...elemetry.Instrumentation.EntityFrameworkCore.csproj | 2 +- .../OpenTelemetry.Instrumentation.GrpcNetClient.csproj | 2 +- .../OpenTelemetry.Instrumentation.Owin.csproj | 6 +++--- .../OpenTelemetry.Instrumentation.Quartz.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.csproj | 4 ++-- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 2 +- ...enTelemetry.Exporter.OneCollector.Benchmarks.csproj | 2 +- .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 2 +- ...penTelemetry.Instrumentation.Cassandra.Tests.csproj | 10 ++++------ ...lemetry.Instrumentation.ConfluentKafka.Tests.csproj | 2 +- ...ry.Instrumentation.EntityFrameworkCore.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Owin.Tests.csproj | 2 +- 18 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 00e0b3e8ab..a2f6c2585c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -5,7 +5,7 @@ net8.0;$(NetStandardMinimumSupportedVersion) - $(TargetFrameworks);net462 + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) true An OpenTelemetry .NET exporter that exports to local ETW or UDS. THIRD-PARTY-NOTICES.TXT @@ -18,7 +18,7 @@ - + diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 5cea309c2c..111cb4960c 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -1,8 +1,8 @@ - net8.0;netstandard2.1;netstandard2.0 - $(TargetFrameworks);net462 + net8.0;netstandard2.1;$(NetStandardMinimumSupportedVersion) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) true An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector. Exporter.OneCollector- diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 15c3b04992..7e41243dd9 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion);net462 + net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) An OpenTelemetry .NET exporter that sends telemetry to Google Stackdriver. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index ad5ce16572..cbee74c229 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -2,7 +2,7 @@ - net8.0;netstandard2.0 + net8.0;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Extensions.AWS- @@ -16,10 +16,7 @@ - - - - + diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index ab4423858e..c206aa60fc 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -2,8 +2,8 @@ - net8.0;netstandard2.0 - $(TargetFrameworks);net462 + net8.0;$(NetStandardMinimumSupportedVersion) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry .NET SDK preview features and extensions. Extensions- diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index 13cdc16840..1fd2a97946 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -7,8 +7,8 @@ Instrumentation.AWSLambda- - + true diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index a14e26ba44..4af147744b 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -1,7 +1,7 @@ - netstandard2.0 + $(NetStandardMinimumSupportedVersion) Microsoft.EntityFrameworkCore instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.EntityFrameworkCore- diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index 9c5bf71676..20785b022b 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -2,7 +2,7 @@ - net8.0;netstandard2.1;netstandard2.0 + net8.0;netstandard2.1;$(NetStandardMinimumSupportedVersion) gRPC for .NET client instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.GrpcNetClient- diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index 184409a304..1a20f2eb55 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -1,13 +1,13 @@ $(NetFrameworkMinimumSupportedVersion) - OpenTelemetry instrumentation for OWIN + OpenTelemetry instrumentation for OWIN. $(PackageTags);distributed-tracing;OWIN Instrumentation.Owin- - + true diff --git a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj index ef13ab8526..c840575770 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj +++ b/src/OpenTelemetry.Instrumentation.Quartz/OpenTelemetry.Instrumentation.Quartz.csproj @@ -2,7 +2,7 @@ $(NetStandardMinimumSupportedVersion) - OpenTelemetry Quartz.NET Instrumentation + OpenTelemetry Quartz.NET Instrumentation. $(PackageTags);distributed-tracing Instrumentation.Quartz- diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 3bbf68e673..b9558189a8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -8,8 +8,8 @@ Instrumentation.Wcf- - + true diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index cb809e69ae..ea1dd04e66 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index 7493cb836e..6b9e0c552c 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -3,7 +3,7 @@ $(SupportedNetTargetsWithoutNet6) - $(TargetFrameworks);net48;net472;net471;net47;net462 + $(TargetFrameworks);net48;net472;net471;net47;$(NetFrameworkMinimumSupportedVersion) Exe Benchmark project for OpenTelemetry .NET OneCollectorExporter. diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index 15509b13c8..c3f1264678 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -3,7 +3,7 @@ $(SupportedNetTargetsWithoutNet6) - $(TargetFrameworks);net48;net472;net471;net47;net462 + $(TargetFrameworks);net48;net472;net471;net47;$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry .NET OneCollectorExporter. diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index f61ba57d48..32872d85f5 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -1,10 +1,9 @@ - - $(SupportedNetTargetsWithoutNet6) - $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) - - + + $(SupportedNetTargetsWithoutNet6) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + @@ -14,7 +13,6 @@ - diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj index f74df494f5..f19d274b32 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -22,7 +22,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 7fab9bb83a..44074137a1 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -6,7 +6,7 @@ Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation. - + diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj index 3ffbc965b5..ea99af551e 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/OpenTelemetry.Instrumentation.Owin.Tests.csproj @@ -1,8 +1,8 @@ - Unit test project for OpenTelemetry OWIN instrumentation $(NetFrameworkMinimumSupportedVersion) + Unit test project for OpenTelemetry OWIN instrumentation. From 03880e5a5a9ed41301ac3fd6cd9a91988ef55cb3 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:34:46 +0000 Subject: [PATCH 1339/1499] [repo] Simplify a couple of MSBuild conditions (#2193) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .../OpenTelemetry.Sampler.AWS.csproj | 5 +---- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index 791d699747..36abdc1fbc 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -17,10 +17,7 @@ - - - - + diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 3beba0091d..8489e41f72 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -9,7 +9,7 @@ - + From 80f2dbff8089325df2f3e9adc8bc4ae6c59e621e Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 9 Oct 2024 10:55:17 -0700 Subject: [PATCH 1340/1499] [examples] Bump packages dependent on vulnerable System.Text.Json versions (#2194) --- examples/kafka/Examples.ConfluentKafka.csproj | 4 +--- examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/kafka/Examples.ConfluentKafka.csproj b/examples/kafka/Examples.ConfluentKafka.csproj index c10dbfcb21..b169bc8cc2 100644 --- a/examples/kafka/Examples.ConfluentKafka.csproj +++ b/examples/kafka/Examples.ConfluentKafka.csproj @@ -10,12 +10,10 @@ - + - - diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index ac31365665..d3bb71d854 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -8,11 +8,9 @@ - + - - From af6da0e72badec417937344249ae6c5b31883bf3 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 9 Oct 2024 12:17:22 -0700 Subject: [PATCH 1341/1499] [tests] Bump packages dependent on vulnerable System.Text.Json versions (#2195) --- build/Common.nonprod.props | 3 ++- examples/kafka/Examples.ConfluentKafka.csproj | 2 +- examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj | 4 ++-- .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 4 ---- .../OpenTelemetry.Instrumentation.Cassandra.Tests.csproj | 2 -- .../OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj | 4 +--- .../OpenTelemetry.Instrumentation.Http.Tests.csproj | 2 +- ...nTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj | 2 -- 8 files changed, 7 insertions(+), 16 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 4ba068d4b2..255792353f 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -25,7 +25,8 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [0.13.12,0.14) - 8.0.0 + 8.0.1 + 8.0.1 [17.11.1,18.0) $(OpenTelemetryCoreLatestVersion) net8.0;net6.0 diff --git a/examples/kafka/Examples.ConfluentKafka.csproj b/examples/kafka/Examples.ConfluentKafka.csproj index b169bc8cc2..3f60ecbc1b 100644 --- a/examples/kafka/Examples.ConfluentKafka.csproj +++ b/examples/kafka/Examples.ConfluentKafka.csproj @@ -10,7 +10,7 @@ - + diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index d3bb71d854..75dc57fc09 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 5cc3e698c7..6382acc150 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -11,10 +11,6 @@ - - - - diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index 32872d85f5..ca925749b8 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -9,8 +9,6 @@ - - diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj index f19d274b32..e9faf0e74c 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -21,10 +21,8 @@ - + - - diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index 7e65697a06..14f4228107 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 48ff8eaecc..cfbd7c6aa5 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -21,8 +21,6 @@ - - From 69532cd20509543897b6a953779aaab1033fc098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 9 Oct 2024 22:32:25 +0200 Subject: [PATCH 1342/1499] [SemanticConvention] Bump to v1.28.0 (#2189) Co-authored-by: Cijo Thomas --- .../.publicApi/PublicAPI.Unshipped.txt | 138 +++++++++++++++-- .../Attributes/AndroidAttributes.cs | 4 + .../Attributes/AzAttributes.cs | 5 + .../Attributes/CloudAttributes.cs | 2 +- .../Attributes/CloudfoundryAttributes.cs | 141 ++++++++++++++++++ .../Attributes/ContainerAttributes.cs | 22 ++- .../Attributes/DbAttributes.cs | 92 +++++++----- .../Attributes/DotnetAttributes.cs | 52 +++++++ .../Attributes/FileAttributes.cs | 84 +++++++++++ .../Attributes/GenAiAttributes.cs | 69 ++++++++- .../Attributes/HttpAttributes.cs | 8 +- .../Attributes/HwAttributes.cs | 141 ++++++++++++++++++ .../Attributes/K8sAttributes.cs | 46 ++++++ .../Attributes/LogAttributes.cs | 2 +- .../Attributes/MessagingAttributes.cs | 17 ++- .../Attributes/NodejsAttributes.cs | 37 +++++ .../Attributes/ProcessAttributes.cs | 36 +++++ .../Attributes/ProfileAttributes.cs | 72 +++++++++ .../Attributes/TlsAttributes.cs | 2 +- .../CHANGELOG.md | 3 + .../scripts/generate.ps1 | 2 +- .../scripts/generate.sh | 2 +- 22 files changed, 898 insertions(+), 79 deletions(-) create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/DotnetAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/HwAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/NodejsAttributes.cs create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/ProfileAttributes.cs diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt index 41f6d5209c..3e05247004 100644 --- a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt @@ -71,6 +71,7 @@ const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3PartNumber = const OpenTelemetry.SemanticConventions.AwsAttributes.AttributeAwsS3UploadId = "aws.s3.upload_id" -> string! const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Ec2 = "ec2" -> string! const OpenTelemetry.SemanticConventions.AwsAttributes.AwsEcsLaunchtypeValues.Fargate = "fargate" -> string! +const OpenTelemetry.SemanticConventions.AzAttributes.AttributeAzNamespace = "az.namespace" -> string! const OpenTelemetry.SemanticConventions.AzAttributes.AttributeAzServiceRequestId = "az.service_request_id" -> string! const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserBrands = "browser.brands" -> string! const OpenTelemetry.SemanticConventions.BrowserAttributes.AttributeBrowserLanguage = "browser.language" -> string! @@ -133,6 +134,17 @@ const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeven const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSpecVersion = "cloudevents.event_spec_version" -> string! const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventSubject = "cloudevents.event_subject" -> string! const OpenTelemetry.SemanticConventions.CloudeventsAttributes.AttributeCloudeventsEventType = "cloudevents.event_type" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryAppId = "cloudfoundry.app.id" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryAppInstanceId = "cloudfoundry.app.instance.id" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryAppName = "cloudfoundry.app.name" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryOrgId = "cloudfoundry.org.id" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryOrgName = "cloudfoundry.org.name" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryProcessId = "cloudfoundry.process.id" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundryProcessType = "cloudfoundry.process.type" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundrySpaceId = "cloudfoundry.space.id" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundrySpaceName = "cloudfoundry.space.name" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundrySystemId = "cloudfoundry.system.id" -> string! +const OpenTelemetry.SemanticConventions.CloudfoundryAttributes.AttributeCloudfoundrySystemInstanceId = "cloudfoundry.system.instance.id" -> string! const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeColumn = "code.column" -> string! const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFilepath = "code.filepath" -> string! const OpenTelemetry.SemanticConventions.CodeAttributes.AttributeCodeFunction = "code.function" -> string! @@ -143,6 +155,8 @@ const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCo const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandArgs = "container.command_args" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCommandLine = "container.command_line" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCpuState = "container.cpu.state" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCsiPluginName = "container.csi.plugin.name" -> string! +const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerCsiVolumeId = "container.csi.volume.id" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerId = "container.id" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageId = "container.image.id" -> string! const OpenTelemetry.SemanticConventions.ContainerAttributes.AttributeContainerImageName = "container.image.name" -> string! @@ -200,6 +214,7 @@ const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationName = const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryParameterTemplate = "db.query.parameter" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryText = "db.query.text" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbRedisDatabaseIndex = "db.redis.database_index" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbResponseStatusCode = "db.response.status_code" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSqlTable = "db.sql.table" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbStatement = "db.statement" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSystem = "db.system" -> string! @@ -221,21 +236,21 @@ const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValu const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValues.Used = "used" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Direct = "direct" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Gateway = "gateway" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "Batch" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Create = "Create" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Delete = "Delete" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Execute = "Execute" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ExecuteJavascript = "ExecuteJavaScript" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Head = "Head" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.HeadFeed = "HeadFeed" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Invalid = "Invalid" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Patch = "Patch" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Query = "Query" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.QueryPlan = "QueryPlan" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Read = "Read" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ReadFeed = "ReadFeed" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Replace = "Replace" -> string! -const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Upsert = "Upsert" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "batch" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Create = "create" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Delete = "delete" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Execute = "execute" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ExecuteJavascript = "execute_javascript" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Head = "head" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.HeadFeed = "head_feed" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Invalid = "invalid" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Patch = "patch" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Query = "query" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.QueryPlan = "query_plan" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Read = "read" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.ReadFeed = "read_feed" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Replace = "replace" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Upsert = "upsert" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Adabas = "adabas" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cache = "cache" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues.Cassandra = "cassandra" -> string! @@ -307,6 +322,12 @@ const OpenTelemetry.SemanticConventions.DiskAttributes.AttributeDiskIoDirection const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Read = "read" -> string! const OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues.Write = "write" -> string! const OpenTelemetry.SemanticConventions.DnsAttributes.AttributeDnsQuestionName = "dns.question.name" -> string! +const OpenTelemetry.SemanticConventions.DotnetAttributes.AttributeDotnetGcHeapGeneration = "dotnet.gc.heap.generation" -> string! +const OpenTelemetry.SemanticConventions.DotnetAttributes.DotnetGcHeapGenerationValues.Gen0 = "gen0" -> string! +const OpenTelemetry.SemanticConventions.DotnetAttributes.DotnetGcHeapGenerationValues.Gen1 = "gen1" -> string! +const OpenTelemetry.SemanticConventions.DotnetAttributes.DotnetGcHeapGenerationValues.Gen2 = "gen2" -> string! +const OpenTelemetry.SemanticConventions.DotnetAttributes.DotnetGcHeapGenerationValues.Loh = "loh" -> string! +const OpenTelemetry.SemanticConventions.DotnetAttributes.DotnetGcHeapGenerationValues.Poh = "poh" -> string! const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserId = "enduser.id" -> string! const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserRole = "enduser.role" -> string! const OpenTelemetry.SemanticConventions.EnduserAttributes.AttributeEnduserScope = "enduser.scope" -> string! @@ -349,17 +370,34 @@ const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Timer = const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagKey = "feature_flag.key" -> string! const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagProviderName = "feature_flag.provider_name" -> string! const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagVariant = "feature_flag.variant" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileAccessed = "file.accessed" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileAttributes = "file.attributes" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileChanged = "file.changed" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileCreated = "file.created" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileDirectory = "file.directory" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileExtension = "file.extension" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileForkName = "file.fork_name" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileGroupId = "file.group.id" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileGroupName = "file.group.name" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileInode = "file.inode" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileMode = "file.mode" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileModified = "file.modified" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileName = "file.name" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileOwnerId = "file.owner.id" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileOwnerName = "file.owner.name" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFilePath = "file.path" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileSize = "file.size" -> string! +const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileSymbolicLinkTargetPath = "file.symbolic_link.target_path" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpClientService = "gcp.client.service" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobExecution = "gcp.cloud_run.job.execution" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceHostname = "gcp.gce.instance.hostname" -> string! const OpenTelemetry.SemanticConventions.GcpAttributes.AttributeGcpGceInstanceName = "gcp.gce.instance.name" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiCompletion = "gen_ai.completion" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiRequestResponseFormat = "gen_ai.openai.request.response_format" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiRequestSeed = "gen_ai.openai.request.seed" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiRequestServiceTier = "gen_ai.openai.request.service_tier" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiResponseServiceTier = "gen_ai.openai.response.service_tier" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOperationName = "gen_ai.operation.name" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiPrompt = "gen_ai.prompt" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestFrequencyPenalty = "gen_ai.request.frequency_penalty" -> string! @@ -379,6 +417,11 @@ const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageCompl const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageInputTokens = "gen_ai.usage.input_tokens" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsageOutputTokens = "gen_ai.usage.output_tokens" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestResponseFormatValues.JsonObject = "json_object" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestResponseFormatValues.JsonSchema = "json_schema" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestResponseFormatValues.Text = "text" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestServiceTierValues.Auto = "auto" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestServiceTierValues.Default = "default" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.Chat = "chat" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.TextCompletion = "text_completion" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Anthropic = "anthropic" -> string! @@ -466,6 +509,28 @@ const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.P const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Post = "POST" -> string! const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Put = "PUT" -> string! const OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues.Trace = "TRACE" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.AttributeHwId = "hw.id" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.AttributeHwName = "hw.name" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.AttributeHwParent = "hw.parent" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.AttributeHwState = "hw.state" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.AttributeHwType = "hw.type" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwStateValues.Degraded = "degraded" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwStateValues.Failed = "failed" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwStateValues.Ok = "ok" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Battery = "battery" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Cpu = "cpu" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.DiskController = "disk_controller" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Enclosure = "enclosure" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Fan = "fan" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Gpu = "gpu" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.LogicalDisk = "logical_disk" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Memory = "memory" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Network = "network" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.PhysicalDisk = "physical_disk" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.PowerSupply = "power_supply" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.TapeDrive = "tape_drive" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Temperature = "temperature" -> string! +const OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues.Voltage = "voltage" -> string! const OpenTelemetry.SemanticConventions.IosAttributes.AttributeIosState = "ios.state" -> string! const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Active = "active" -> string! const OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues.Background = "background" -> string! @@ -512,6 +577,14 @@ const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetName const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sReplicasetUid = "k8s.replicaset.uid" -> string! const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetName = "k8s.statefulset.name" -> string! const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sStatefulsetUid = "k8s.statefulset.uid" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sVolumeName = "k8s.volume.name" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.AttributeK8sVolumeType = "k8s.volume.type" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues.ConfigMap = "configMap" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues.DownwardApi = "downwardAPI" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues.EmptyDir = "emptyDir" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues.Local = "local" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues.PersistentVolumeClaim = "persistentVolumeClaim" -> string! +const OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues.Secret = "secret" -> string! const OpenTelemetry.SemanticConventions.LinuxAttributes.AttributeLinuxMemorySlabState = "linux.memory.slab.state" -> string! const OpenTelemetry.SemanticConventions.LinuxAttributes.LinuxMemorySlabStateValues.Reclaimable = "reclaimable" -> string! const OpenTelemetry.SemanticConventions.LinuxAttributes.LinuxMemorySlabStateValues.Unreclaimable = "unreclaimable" -> string! @@ -581,6 +654,7 @@ const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTy const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Process = "process" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Publish = "publish" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Receive = "receive" -> string! +const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Send = "send" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingOperationTypeValues.Settle = "settle" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Broadcasting = "broadcasting" -> string! const OpenTelemetry.SemanticConventions.MessagingAttributes.MessagingRocketmqConsumptionModelValues.Clustering = "clustering" -> string! @@ -676,6 +750,9 @@ const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues.Unix = "unix" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv4 = "ipv4" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues.Ipv6 = "ipv6" -> string! +const OpenTelemetry.SemanticConventions.NodejsAttributes.AttributeNodejsEventloopState = "nodejs.eventloop.state" -> string! +const OpenTelemetry.SemanticConventions.NodejsAttributes.NodejsEventloopStateValues.Active = "active" -> string! +const OpenTelemetry.SemanticConventions.NodejsAttributes.NodejsEventloopStateValues.Idle = "idle" -> string! const OpenTelemetry.SemanticConventions.OciAttributes.AttributeOciManifestDigest = "oci.manifest.digest" -> string! const OpenTelemetry.SemanticConventions.OpentracingAttributes.AttributeOpentracingRefType = "opentracing.ref_type" -> string! const OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues.ChildOf = "child_of" -> string! @@ -707,12 +784,16 @@ const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Idle = "idle const OpenTelemetry.SemanticConventions.OtherAttributes.StateValues.Used = "used" -> string! const OpenTelemetry.SemanticConventions.PeerAttributes.AttributePeerService = "peer.service" -> string! const OpenTelemetry.SemanticConventions.PoolAttributes.AttributePoolName = "pool.name" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessArgsCount = "process.args_count" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommand = "process.command" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandArgs = "process.command_args" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCommandLine = "process.command_line" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessContextSwitchType = "process.context_switch_type" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCpuState = "process.cpu.state" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCreationTime = "process.creation.time" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdGnu = "process.executable.build_id.gnu" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdGo = "process.executable.build_id.go" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdProfiling = "process.executable.build_id.profiling" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableName = "process.executable.name" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutablePath = "process.executable.path" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExitCode = "process.exit.code" -> string! @@ -731,9 +812,11 @@ const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessRuntim const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessSavedUserId = "process.saved_user.id" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessSavedUserName = "process.saved_user.name" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessSessionLeaderPid = "process.session_leader.pid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessTitle = "process.title" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessUserId = "process.user.id" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessUserName = "process.user.name" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessVpid = "process.vpid" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessWorkingDirectory = "process.working_directory" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Involuntary = "involuntary" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues.Voluntary = "voluntary" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.System = "system" -> string! @@ -741,6 +824,16 @@ const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues. const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues.Wait = "wait" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Major = "major" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues.Minor = "minor" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.AttributeProfileFrameType = "profile.frame.type" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Cpython = "cpython" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Dotnet = "dotnet" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Jvm = "jvm" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Kernel = "kernel" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Native = "native" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Perl = "perl" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Php = "php" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.Ruby = "ruby" -> string! +const OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues.V8js = "v8js" -> string! const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code" -> string! const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcRequestMetadataTemplate = "rpc.connect_rpc.request.metadata" -> string! const OpenTelemetry.SemanticConventions.RpcAttributes.AttributeRpcConnectRpcResponseMetadataTemplate = "rpc.connect_rpc.response.metadata" -> string! @@ -1001,6 +1094,7 @@ OpenTelemetry.SemanticConventions.CloudAttributes OpenTelemetry.SemanticConventions.CloudAttributes.CloudPlatformValues OpenTelemetry.SemanticConventions.CloudAttributes.CloudProviderValues OpenTelemetry.SemanticConventions.CloudeventsAttributes +OpenTelemetry.SemanticConventions.CloudfoundryAttributes OpenTelemetry.SemanticConventions.CodeAttributes OpenTelemetry.SemanticConventions.ContainerAttributes OpenTelemetry.SemanticConventions.ContainerAttributes.ContainerCpuStateValues @@ -1020,6 +1114,8 @@ OpenTelemetry.SemanticConventions.DeviceAttributes OpenTelemetry.SemanticConventions.DiskAttributes OpenTelemetry.SemanticConventions.DiskAttributes.DiskIoDirectionValues OpenTelemetry.SemanticConventions.DnsAttributes +OpenTelemetry.SemanticConventions.DotnetAttributes +OpenTelemetry.SemanticConventions.DotnetAttributes.DotnetGcHeapGenerationValues OpenTelemetry.SemanticConventions.EnduserAttributes OpenTelemetry.SemanticConventions.ErrorAttributes OpenTelemetry.SemanticConventions.ErrorAttributes.ErrorTypeValues @@ -1033,6 +1129,8 @@ OpenTelemetry.SemanticConventions.FeatureFlagAttributes OpenTelemetry.SemanticConventions.FileAttributes OpenTelemetry.SemanticConventions.GcpAttributes OpenTelemetry.SemanticConventions.GenAiAttributes +OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestResponseFormatValues +OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestServiceTierValues OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues @@ -1047,12 +1145,16 @@ OpenTelemetry.SemanticConventions.HttpAttributes OpenTelemetry.SemanticConventions.HttpAttributes.HttpConnectionStateValues OpenTelemetry.SemanticConventions.HttpAttributes.HttpFlavorValues OpenTelemetry.SemanticConventions.HttpAttributes.HttpRequestMethodValues +OpenTelemetry.SemanticConventions.HwAttributes +OpenTelemetry.SemanticConventions.HwAttributes.HwStateValues +OpenTelemetry.SemanticConventions.HwAttributes.HwTypeValues OpenTelemetry.SemanticConventions.IosAttributes OpenTelemetry.SemanticConventions.IosAttributes.IosStateValues OpenTelemetry.SemanticConventions.JvmAttributes OpenTelemetry.SemanticConventions.JvmAttributes.JvmMemoryTypeValues OpenTelemetry.SemanticConventions.JvmAttributes.JvmThreadStateValues OpenTelemetry.SemanticConventions.K8sAttributes +OpenTelemetry.SemanticConventions.K8sAttributes.K8sVolumeTypeValues OpenTelemetry.SemanticConventions.LinuxAttributes OpenTelemetry.SemanticConventions.LinuxAttributes.LinuxMemorySlabStateValues OpenTelemetry.SemanticConventions.LogAttributes @@ -1074,6 +1176,8 @@ OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkConnectionTypeValues OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkIoDirectionValues OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTransportValues OpenTelemetry.SemanticConventions.NetworkAttributes.NetworkTypeValues +OpenTelemetry.SemanticConventions.NodejsAttributes +OpenTelemetry.SemanticConventions.NodejsAttributes.NodejsEventloopStateValues OpenTelemetry.SemanticConventions.OciAttributes OpenTelemetry.SemanticConventions.OpentracingAttributes OpenTelemetry.SemanticConventions.OpentracingAttributes.OpentracingRefTypeValues @@ -1089,6 +1193,8 @@ OpenTelemetry.SemanticConventions.ProcessAttributes OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessContextSwitchTypeValues OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessCpuStateValues OpenTelemetry.SemanticConventions.ProcessAttributes.ProcessPagingFaultTypeValues +OpenTelemetry.SemanticConventions.ProfileAttributes +OpenTelemetry.SemanticConventions.ProfileAttributes.ProfileFrameTypeValues OpenTelemetry.SemanticConventions.RpcAttributes OpenTelemetry.SemanticConventions.RpcAttributes.RpcConnectRpcErrorCodeValues OpenTelemetry.SemanticConventions.RpcAttributes.RpcGrpcStatusCodeValues @@ -1128,4 +1234,4 @@ OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues OpenTelemetry.SemanticConventions.VcsAttributes OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues -OpenTelemetry.SemanticConventions.WebengineAttributes +OpenTelemetry.SemanticConventions.WebengineAttributes \ No newline at end of file diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs index 9cb66d6a2b..a9b0c8fde7 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AndroidAttributes.cs @@ -25,6 +25,7 @@ public static class AndroidAttributes /// /// The Android lifecycle states are defined in Activity lifecycle callbacks, and from which the OS identifiers are derived. /// + [Obsolete("Replaced by device.app.lifecycle.")] public const string AttributeAndroidState = "android.state"; /// @@ -35,16 +36,19 @@ public static class AndroidStateValues /// /// Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time. /// + [Obsolete("Replaced by device.app.lifecycle.")] public const string Created = "created"; /// /// Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state. /// + [Obsolete("Replaced by device.app.lifecycle.")] public const string Background = "background"; /// /// Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states. /// + [Obsolete("Replaced by device.app.lifecycle.")] public const string Foreground = "foreground"; } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs index 50a88c4b1f..608c8e2a11 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AzAttributes.cs @@ -14,6 +14,11 @@ namespace OpenTelemetry.SemanticConventions; /// public static class AzAttributes { + /// + /// Azure Resource Provider Namespace as recognized by the client. + /// + public const string AttributeAzNamespace = "az.namespace"; + /// /// The unique identifier of the service request. It's generated by the Azure service and returned with the response. /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs index d8dcd99627..c3a23ce1ff 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs @@ -67,7 +67,7 @@ public static class CloudAttributes ///
  • GCP: The URI of the resource
  • ///
  • Azure: The Fully Qualified Resource ID of the invoked function, /// not the function app, having the form - /// /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/. + /// /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/. /// This means that a span attribute MUST be used, as an Azure function app can host multiple functions that would usually share /// a TracerProvider.
  • /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs new file mode 100644 index 0000000000..51c841d0c6 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs @@ -0,0 +1,141 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class CloudfoundryAttributes +{ + /// + /// The guid of the application. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.application_id. This is the same value as + /// reported by cf app --guid. + /// + public const string AttributeCloudfoundryAppId = "cloudfoundry.app.id"; + + /// + /// The index of the application instance. 0 when just one instance is active. + /// + /// + /// CloudFoundry defines the instance_id in the Loggegator v2 envelope. + /// It is used for logs and metrics emitted by CloudFoundry. It is + /// supposed to contain the application instance index for applications + /// deployed on the runtime. + ///

    + /// Application instrumentation should use the value from environment + /// variable CF_INSTANCE_INDEX. + /// + public const string AttributeCloudfoundryAppInstanceId = "cloudfoundry.app.instance.id"; + + ///

    + /// The name of the application. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.application_name. This is the same value + /// as reported by cf apps. + /// + public const string AttributeCloudfoundryAppName = "cloudfoundry.app.name"; + + /// + /// The guid of the CloudFoundry org the application is running in. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.org_id. This is the same value as + /// reported by cf org --guid. + /// + public const string AttributeCloudfoundryOrgId = "cloudfoundry.org.id"; + + /// + /// The name of the CloudFoundry organization the app is running in. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.org_name. This is the same value as + /// reported by cf orgs. + /// + public const string AttributeCloudfoundryOrgName = "cloudfoundry.org.name"; + + /// + /// The UID identifying the process. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.process_id. It is supposed to be equal to + /// VCAP_APPLICATION.app_id for applications deployed to the runtime. + /// For system components, this could be the actual PID. + /// + public const string AttributeCloudfoundryProcessId = "cloudfoundry.process.id"; + + /// + /// The type of process. + /// + /// + /// CloudFoundry applications can consist of multiple jobs. Usually the + /// main process will be of type web. There can be additional background + /// tasks or side-cars with different process types. + /// + public const string AttributeCloudfoundryProcessType = "cloudfoundry.process.type"; + + /// + /// The guid of the CloudFoundry space the application is running in. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.space_id. This is the same value as + /// reported by cf space --guid. + /// + public const string AttributeCloudfoundrySpaceId = "cloudfoundry.space.id"; + + /// + /// The name of the CloudFoundry space the application is running in. + /// + /// + /// Application instrumentation should use the value from environment + /// variable VCAP_APPLICATION.space_name. This is the same value as + /// reported by cf spaces. + /// + public const string AttributeCloudfoundrySpaceName = "cloudfoundry.space.name"; + + /// + /// A guid or another name describing the event source. + /// + /// + /// CloudFoundry defines the source_id in the Loggregator v2 envelope. + /// It is used for logs and metrics emitted by CloudFoundry. It is + /// supposed to contain the component name, e.g. "gorouter", for + /// CloudFoundry components. + ///

    + /// When system components are instrumented, values from the + /// Bosh spec + /// should be used. The system.id should be set to + /// spec.deployment/spec.name. + /// + public const string AttributeCloudfoundrySystemId = "cloudfoundry.system.id"; + + ///

    + /// A guid describing the concrete instance of the event source. + /// + /// + /// CloudFoundry defines the instance_id in the Loggregator v2 envelope. + /// It is used for logs and metrics emitted by CloudFoundry. It is + /// supposed to contain the vm id for CloudFoundry components. + ///

    + /// When system components are instrumented, values from the + /// Bosh spec + /// should be used. The system.instance.id should be set to spec.id. + /// + public const string AttributeCloudfoundrySystemInstanceId = "cloudfoundry.system.instance.id"; +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs index 955f1f8e0a..2fa0bd5e85 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ContainerAttributes.cs @@ -23,12 +23,12 @@ public static class ContainerAttributes public const string AttributeContainerCommand = "container.command"; ///

    - /// All the command arguments (including the command/executable itself) run by the container. [2]. + /// All the command arguments (including the command/executable itself) run by the container. /// public const string AttributeContainerCommandArgs = "container.command_args"; /// - /// The full command run by the container as a single string representing the full command. [2]. + /// The full command run by the container as a single string representing the full command. /// public const string AttributeContainerCommandLine = "container.command_line"; @@ -39,7 +39,23 @@ public static class ContainerAttributes public const string AttributeContainerCpuState = "container.cpu.state"; /// - /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated. + /// The name of the CSI (Container Storage Interface) plugin used by the volume. + /// + /// + /// This can sometimes be referred to as a "driver" in CSI implementations. This should represent the name field of the GetPluginInfo RPC. + /// + public const string AttributeContainerCsiPluginName = "container.csi.plugin.name"; + + /// + /// The unique volume ID returned by the CSI (Container Storage Interface) plugin. + /// + /// + /// This can sometimes be referred to as a "volume handle" in CSI implementations. This should represent the Volume.volume_id field in CSI spec. + /// + public const string AttributeContainerCsiVolumeId = "container.csi.volume.id"; + + /// + /// Container ID. Usually a UUID, as for example used to identify Docker containers. The UUID might be abbreviated. /// public const string AttributeContainerId = "container.id"; diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs index adaef65554..3c8d6ca97c 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs @@ -79,6 +79,7 @@ public static class DbAttributes /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. /// If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. /// For batch operations, if the individual operations are known to have the same collection name then that collection name SHOULD be used, otherwise db.collection.name SHOULD NOT be captured. + /// This attribute has stability level RELEASE CANDIDATE. ///
    public const string AttributeDbCollectionName = "db.collection.name"; @@ -105,7 +106,7 @@ public static class DbAttributes public const string AttributeDbCosmosdbContainer = "db.cosmosdb.container"; /// - /// CosmosDB Operation Type. + /// Cosmos DB Operation Type. /// public const string AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type"; @@ -120,8 +121,9 @@ public static class DbAttributes public const string AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length"; /// - /// Cosmos DB status code. + /// Deprecated, use db.response.status_code instead. /// + [Obsolete("Replaced by db.response.status_code.")] public const string AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code"; /// @@ -185,6 +187,7 @@ public static class DbAttributes /// If a database system has multiple namespace components, they SHOULD be concatenated (potentially using database system specific conventions) from most general to most specific namespace component, and more specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" queries for the more general namespaces will be valid. /// Semantic conventions for individual database systems SHOULD document what db.namespace means in the context of that system. /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. + /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbNamespace = "db.namespace"; @@ -195,10 +198,11 @@ public static class DbAttributes public const string AttributeDbOperation = "db.operation"; /// - /// The number of queries included in a batch operation. + /// The number of queries included in a batch operation. /// /// /// Operations are only considered batches when they contain two or more operations, and so db.operation.batch.size SHOULD never be 1. + /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbOperationBatchSize = "db.operation.batch.size"; @@ -209,6 +213,7 @@ public static class DbAttributes /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. /// If the operation name is parsed from the query text, it SHOULD be the first operation name found in the query. /// For batch operations, if the individual operations are known to have the same operation name then that operation name SHOULD be used prepended by BATCH , otherwise db.operation.name SHOULD be BATCH or some other database system specific term if more applicable. + /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbOperationName = "db.operation.name"; @@ -218,6 +223,7 @@ public static class DbAttributes /// /// Query parameters should only be captured when db.query.text is parameterized with placeholders. /// If a parameter has no name and instead is referenced only by index, then SHOULD be the 0-based index. + /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbQueryParameterTemplate = "db.query.parameter"; @@ -228,6 +234,7 @@ public static class DbAttributes /// For sanitization see Sanitization of db.query.text. /// For batch operations, if the individual operations are known to have the same query text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated with separator ; or some other database system specific separator if more applicable. /// Even though parameterized query text can potentially have sensitive data, by using a parameterized query the user is giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to observability of capturing the static part of the query text by default outweighs the risk. + /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbQueryText = "db.query.text"; @@ -237,6 +244,16 @@ public static class DbAttributes [Obsolete("Replaced by db.namespace.")] public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; + /// + /// Database response status code. + /// + /// + /// The status code returned by the database. Usually it represents an error code, but may also represent partial success, warning, or differentiate between various types of successful outcomes. + /// Semantic conventions for individual database systems SHOULD document what db.response.status_code means in the context of that system. + /// This attribute has stability level RELEASE CANDIDATE. + /// + public const string AttributeDbResponseStatusCode = "db.response.status_code"; + /// /// Deprecated, use db.collection.name instead. /// @@ -254,6 +271,7 @@ public static class DbAttributes /// /// /// The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL client libraries to connect to a CockroachDB, the db.system is set to postgresql based on the instrumentation's best knowledge. + /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbSystem = "db.system"; @@ -375,84 +393,84 @@ public static class DbCosmosdbConnectionModeValues } /// - /// CosmosDB Operation Type. + /// Cosmos DB Operation Type. /// public static class DbCosmosdbOperationTypeValues { /// - /// invalid. + /// batch. /// - public const string Invalid = "Invalid"; + public const string Batch = "batch"; /// /// create. /// - public const string Create = "Create"; + public const string Create = "create"; /// - /// patch. + /// delete. /// - public const string Patch = "Patch"; + public const string Delete = "delete"; /// - /// read. + /// execute. /// - public const string Read = "Read"; + public const string Execute = "execute"; /// - /// read_feed. + /// execute_javascript. /// - public const string ReadFeed = "ReadFeed"; + public const string ExecuteJavascript = "execute_javascript"; /// - /// delete. + /// invalid. /// - public const string Delete = "Delete"; + public const string Invalid = "invalid"; /// - /// replace. + /// head. /// - public const string Replace = "Replace"; + public const string Head = "head"; /// - /// execute. + /// head_feed. /// - public const string Execute = "Execute"; + public const string HeadFeed = "head_feed"; /// - /// query. + /// patch. /// - public const string Query = "Query"; + public const string Patch = "patch"; /// - /// head. + /// query. /// - public const string Head = "Head"; + public const string Query = "query"; /// - /// head_feed. + /// query_plan. /// - public const string HeadFeed = "HeadFeed"; + public const string QueryPlan = "query_plan"; /// - /// upsert. + /// read. /// - public const string Upsert = "Upsert"; + public const string Read = "read"; /// - /// batch. + /// read_feed. /// - public const string Batch = "Batch"; + public const string ReadFeed = "read_feed"; /// - /// query_plan. + /// replace. /// - public const string QueryPlan = "QueryPlan"; + public const string Replace = "replace"; /// - /// execute_javascript. + /// upsert. /// - public const string ExecuteJavascript = "ExecuteJavaScript"; + public const string Upsert = "upsert"; } /// @@ -616,7 +634,7 @@ public static class DbSystemValues public const string Interbase = "interbase"; /// - /// MariaDB. + /// MariaDB (This value has stability level RELEASE CANDIDATE). /// public const string Mariadb = "mariadb"; @@ -636,7 +654,7 @@ public static class DbSystemValues public const string Mongodb = "mongodb"; /// - /// Microsoft SQL Server. + /// Microsoft SQL Server (This value has stability level RELEASE CANDIDATE). /// public const string Mssql = "mssql"; @@ -646,7 +664,7 @@ public static class DbSystemValues public const string Mssqlcompact = "mssqlcompact"; /// - /// MySQL. + /// MySQL (This value has stability level RELEASE CANDIDATE). /// public const string Mysql = "mysql"; @@ -681,7 +699,7 @@ public static class DbSystemValues public const string Pointbase = "pointbase"; /// - /// PostgreSQL. + /// PostgreSQL (This value has stability level RELEASE CANDIDATE). /// public const string Postgresql = "postgresql"; diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DotnetAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DotnetAttributes.cs new file mode 100644 index 0000000000..b8dc8bd8fe --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DotnetAttributes.cs @@ -0,0 +1,52 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class DotnetAttributes +{ + /// + /// Name of the garbage collector managed heap generation. + /// + public const string AttributeDotnetGcHeapGeneration = "dotnet.gc.heap.generation"; + + /// + /// Name of the garbage collector managed heap generation. + /// + public static class DotnetGcHeapGenerationValues + { + /// + /// Generation 0. + /// + public const string Gen0 = "gen0"; + + /// + /// Generation 1. + /// + public const string Gen1 = "gen1"; + + /// + /// Generation 2. + /// + public const string Gen2 = "gen2"; + + /// + /// Large Object Heap. + /// + public const string Loh = "loh"; + + /// + /// Pinned Object Heap. + /// + public const string Poh = "poh"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs index a0c9fd58dd..1d7ea2d7ae 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FileAttributes.cs @@ -14,6 +14,38 @@ namespace OpenTelemetry.SemanticConventions; /// public static class FileAttributes { + /// + /// Time when the file was last accessed, in ISO 8601 format. + /// + /// + /// This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. + /// + public const string AttributeFileAccessed = "file.accessed"; + + /// + /// Array of file attributes. + /// + /// + /// Attributes names depend on the OS or file system. Here’s a non-exhaustive list of values expected for this attribute: archive, compressed, directory, encrypted, execute, hidden, immutable, journaled, read, readonly, symbolic link, system, temporary, write. + /// + public const string AttributeFileAttributes = "file.attributes"; + + /// + /// Time when the file attributes or metadata was last changed, in ISO 8601 format. + /// + /// + /// file.changed captures the time when any of the file's properties or attributes (including the content) are changed, while file.modified captures the timestamp when the file content is modified. + /// + public const string AttributeFileChanged = "file.changed"; + + /// + /// Time when the file was created, in ISO 8601 format. + /// + /// + /// This attribute might not be supported by some file systems — NFS, FAT32, in embedded OS, etc. + /// + public const string AttributeFileCreated = "file.created"; + /// /// Directory where the file is located. It should include the drive letter, when appropriate. /// @@ -27,11 +59,55 @@ public static class FileAttributes ///
    public const string AttributeFileExtension = "file.extension"; + /// + /// Name of the fork. A fork is additional data associated with a filesystem object. + /// + /// + /// On Linux, a resource fork is used to store additional data with a filesystem object. A file always has at least one fork for the data portion, and additional forks may exist. + /// On NTFS, this is analogous to an Alternate Data Stream (ADS), and the default data stream for a file is just called $DATA. Zone.Identifier is commonly used by Windows to track contents downloaded from the Internet. An ADS is typically of the form: C:\path\to\filename.extension:some_fork_name, and some_fork_name is the value that should populate fork_name. filename.extension should populate file.name, and extension should populate file.extension. The full path, file.path, will include the fork name. + /// + public const string AttributeFileForkName = "file.fork_name"; + + /// + /// Primary Group ID (GID) of the file. + /// + public const string AttributeFileGroupId = "file.group.id"; + + /// + /// Primary group name of the file. + /// + public const string AttributeFileGroupName = "file.group.name"; + + /// + /// Inode representing the file in the filesystem. + /// + public const string AttributeFileInode = "file.inode"; + + /// + /// Mode of the file in octal representation. + /// + public const string AttributeFileMode = "file.mode"; + + /// + /// Time when the file content was last modified, in ISO 8601 format. + /// + public const string AttributeFileModified = "file.modified"; + /// /// Name of the file including the extension, without the directory. /// public const string AttributeFileName = "file.name"; + /// + /// The user ID (UID) or security identifier (SID) of the file owner. + /// + public const string AttributeFileOwnerId = "file.owner.id"; + + /// + /// Username of the file owner. + /// + public const string AttributeFileOwnerName = "file.owner.name"; + /// /// Full path to the file, including the file name. It should include the drive letter, when appropriate. /// @@ -41,4 +117,12 @@ public static class FileAttributes /// File size in bytes. /// public const string AttributeFileSize = "file.size"; + + /// + /// Path to the target of a symbolic link. + /// + /// + /// This attribute is only applicable to symbolic links. + /// + public const string AttributeFileSymbolicLinkTargetPath = "file.symbolic_link.target_path"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs index 16bac1669a..13b13ef464 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs @@ -15,13 +15,31 @@ namespace OpenTelemetry.SemanticConventions; public static class GenAiAttributes { /// - /// The full response received from the GenAI model. + /// Deprecated, use Event API to report completions contents. /// - /// - /// It's RECOMMENDED to format completions as JSON string matching OpenAI messages format. - /// + [Obsolete("Removed, no replacement at this time.")] public const string AttributeGenAiCompletion = "gen_ai.completion"; + /// + /// The response format that is requested. + /// + public const string AttributeGenAiOpenaiRequestResponseFormat = "gen_ai.openai.request.response_format"; + + /// + /// Requests with same seed value more likely to return same result. + /// + public const string AttributeGenAiOpenaiRequestSeed = "gen_ai.openai.request.seed"; + + /// + /// The service tier requested. May be a specific tier, detault, or auto. + /// + public const string AttributeGenAiOpenaiRequestServiceTier = "gen_ai.openai.request.service_tier"; + + /// + /// The service tier used for the response. + /// + public const string AttributeGenAiOpenaiResponseServiceTier = "gen_ai.openai.response.service_tier"; + /// /// The name of the operation being performed. /// @@ -31,11 +49,9 @@ public static class GenAiAttributes public const string AttributeGenAiOperationName = "gen_ai.operation.name"; /// - /// The full prompt sent to the GenAI model. + /// Deprecated, use Event API to report prompt contents. /// - /// - /// It's RECOMMENDED to format prompts as JSON string matching OpenAI messages format. - /// + [Obsolete("Removed, no replacement at this time.")] public const string AttributeGenAiPrompt = "gen_ai.prompt"; /// @@ -136,6 +152,43 @@ public static class GenAiAttributes [Obsolete("Replaced by gen_ai.usage.input_tokens attribute.")] public const string AttributeGenAiUsagePromptTokens = "gen_ai.usage.prompt_tokens"; + /// + /// The response format that is requested. + /// + public static class GenAiOpenaiRequestResponseFormatValues + { + /// + /// Text response format. + /// + public const string Text = "text"; + + /// + /// JSON object response format. + /// + public const string JsonObject = "json_object"; + + /// + /// JSON schema response format. + /// + public const string JsonSchema = "json_schema"; + } + + /// + /// The service tier requested. May be a specific tier, detault, or auto. + /// + public static class GenAiOpenaiRequestServiceTierValues + { + /// + /// The system will utilize scale tier credits until they are exhausted. + /// + public const string Auto = "auto"; + + /// + /// The system will utilize the default scale tier. + /// + public const string Default = "default"; + } + /// /// The name of the operation being performed. /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs index 8e30d56d98..2e2b5675da 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HttpAttributes.cs @@ -98,9 +98,9 @@ public static class HttpAttributes public const string AttributeHttpRequestSize = "http.request.size"; /// - /// Deprecated, use http.request.header.content-length instead. + /// Deprecated, use http.request.header. instead. /// - [Obsolete("Replaced by http.request.header.content-length.")] + [Obsolete("Replaced by http.request.header..")] public const string AttributeHttpRequestContentLength = "http.request_content_length"; /// @@ -135,9 +135,9 @@ public static class HttpAttributes public const string AttributeHttpResponseStatusCode = "http.response.status_code"; /// - /// Deprecated, use http.response.header.content-length instead. + /// Deprecated, use http.response.header. instead. /// - [Obsolete("Replaced by http.response.header.content-length.")] + [Obsolete("Replaced by http.response.header..")] public const string AttributeHttpResponseContentLength = "http.response_content_length"; /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/HwAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/HwAttributes.cs new file mode 100644 index 0000000000..4239ef2c70 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/HwAttributes.cs @@ -0,0 +1,141 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class HwAttributes +{ + /// + /// An identifier for the hardware component, unique within the monitored host. + /// + public const string AttributeHwId = "hw.id"; + + /// + /// An easily-recognizable name for the hardware component. + /// + public const string AttributeHwName = "hw.name"; + + /// + /// Unique identifier of the parent component (typically the hw.id attribute of the enclosure, or disk controller). + /// + public const string AttributeHwParent = "hw.parent"; + + /// + /// The current state of the component. + /// + public const string AttributeHwState = "hw.state"; + + /// + /// Type of the component. + /// + /// + /// Describes the category of the hardware component for which hw.state is being reported. For example, hw.type=temperature along with hw.state=degraded would indicate that the temperature of the hardware component has been reported as degraded. + /// + public const string AttributeHwType = "hw.type"; + + /// + /// The current state of the component. + /// + public static class HwStateValues + { + /// + /// Ok. + /// + public const string Ok = "ok"; + + /// + /// Degraded. + /// + public const string Degraded = "degraded"; + + /// + /// Failed. + /// + public const string Failed = "failed"; + } + + /// + /// Type of the component. + /// + public static class HwTypeValues + { + /// + /// Battery. + /// + public const string Battery = "battery"; + + /// + /// CPU. + /// + public const string Cpu = "cpu"; + + /// + /// Disk controller. + /// + public const string DiskController = "disk_controller"; + + /// + /// Enclosure. + /// + public const string Enclosure = "enclosure"; + + /// + /// Fan. + /// + public const string Fan = "fan"; + + /// + /// GPU. + /// + public const string Gpu = "gpu"; + + /// + /// Logical disk. + /// + public const string LogicalDisk = "logical_disk"; + + /// + /// Memory. + /// + public const string Memory = "memory"; + + /// + /// Network. + /// + public const string Network = "network"; + + /// + /// Physical disk. + /// + public const string PhysicalDisk = "physical_disk"; + + /// + /// Power supply. + /// + public const string PowerSupply = "power_supply"; + + /// + /// Tape drive. + /// + public const string TapeDrive = "tape_drive"; + + /// + /// Temperature. + /// + public const string Temperature = "temperature"; + + /// + /// Voltage. + /// + public const string Voltage = "voltage"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs index 34ae1936b1..28eb510d0e 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs @@ -165,4 +165,50 @@ public static class K8sAttributes /// The UID of the StatefulSet. /// public const string AttributeK8sStatefulsetUid = "k8s.statefulset.uid"; + + /// + /// The name of the K8s volume. + /// + public const string AttributeK8sVolumeName = "k8s.volume.name"; + + /// + /// The type of the K8s volume. + /// + public const string AttributeK8sVolumeType = "k8s.volume.type"; + + /// + /// The type of the K8s volume. + /// + public static class K8sVolumeTypeValues + { + /// + /// A persistentVolumeClaim volume. + /// + public const string PersistentVolumeClaim = "persistentVolumeClaim"; + + /// + /// A configMap volume. + /// + public const string ConfigMap = "configMap"; + + /// + /// A downwardAPI volume. + /// + public const string DownwardApi = "downwardAPI"; + + /// + /// An emptyDir volume. + /// + public const string EmptyDir = "emptyDir"; + + /// + /// A secret volume. + /// + public const string Secret = "secret"; + + /// + /// A local volume. + /// + public const string Local = "local"; + } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs index 6b4dc2714d..8680108444 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/LogAttributes.cs @@ -40,7 +40,7 @@ public static class LogAttributes public const string AttributeLogIostream = "log.iostream"; /// - /// The complete orignal Log Record. + /// The complete original Log Record. /// /// /// This value MAY be added when processing a Log Record which was originally transmitted as a string or equivalent data type AND the Body field of the Log Record does not contain the same value. (e.g. a syslog or a log record read from a file.). diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs index 31baedee43..acb83bcdf5 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/MessagingAttributes.cs @@ -258,9 +258,9 @@ public static class MessagingAttributes public const string AttributeMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; /// - /// Deprecated, use messaging.servicebus.destination.subscription_name instead. + /// Deprecated, use messaging.destination.subscription.name instead. /// - [Obsolete("Replaced by messaging.servicebus.destination.subscription_name.")] + [Obsolete("Replaced by messaging.destination.subscription.name.")] public const string AttributeMessagingServicebusDestinationSubscriptionName = "messaging.servicebus.destination.subscription_name"; /// @@ -292,14 +292,14 @@ public static class MessagingAttributes public static class MessagingOperationTypeValues { /// - /// One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the "Publish" span can be used as the creation context and no "Create" span needs to be created. + /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch sending scenarios. /// - public const string Publish = "publish"; + public const string Create = "create"; /// - /// A message is created. "Create" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios. + /// One or more messages are provided for sending to an intermediary. If a single message is sent, the context of the "Send" span can be used as the creation context and no "Create" span needs to be created. /// - public const string Create = "create"; + public const string Send = "send"; /// /// One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages. @@ -320,6 +320,11 @@ public static class MessagingOperationTypeValues /// Deprecated. Use process instead. /// public const string Deliver = "deliver"; + + /// + /// Deprecated. Use send instead. + /// + public const string Publish = "publish"; } /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NodejsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NodejsAttributes.cs new file mode 100644 index 0000000000..f18510dc80 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NodejsAttributes.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class NodejsAttributes +{ + /// + /// The state of event loop time. + /// + public const string AttributeNodejsEventloopState = "nodejs.eventloop.state"; + + /// + /// The state of event loop time. + /// + public static class NodejsEventloopStateValues + { + /// + /// Active time. + /// + public const string Active = "active"; + + /// + /// Idle time. + /// + public const string Idle = "idle"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs index da4d98d30e..76395a4be3 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs @@ -14,6 +14,14 @@ namespace OpenTelemetry.SemanticConventions; /// public static class ProcessAttributes { + /// + /// Length of the process.command_args array. + /// + /// + /// This field can be useful for querying or performing bucket analysis on how many arguments were provided to start a process. More arguments may be an indication of suspicious activity. + /// + public const string AttributeProcessArgsCount = "process.args_count"; + /// /// The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in proc/[pid]/cmdline. On Windows, can be set to the first parameter extracted from GetCommandLineW. /// @@ -45,6 +53,21 @@ public static class ProcessAttributes /// public const string AttributeProcessCreationTime = "process.creation.time"; + /// + /// The GNU build ID as found in the .note.gnu.build-id ELF section (hex string). + /// + public const string AttributeProcessExecutableBuildIdGnu = "process.executable.build_id.gnu"; + + /// + /// The Go build ID as retrieved by go tool buildid . + /// + public const string AttributeProcessExecutableBuildIdGo = "process.executable.build_id.go"; + + /// + /// Profiling specific build ID for executables. See the OTel specification for Profiles for more information. + /// + public const string AttributeProcessExecutableBuildIdProfiling = "process.executable.build_id.profiling"; + /// /// The name of the process executable. On Linux based systems, can be set to the Name in proc/[pid]/status. On Windows, can be set to the base name of GetProcessImageFileNameW. /// @@ -135,6 +158,14 @@ public static class ProcessAttributes /// public const string AttributeProcessSessionLeaderPid = "process.session_leader.pid"; + /// + /// Process title (proctitle). + /// + /// + /// In many Unix-like systems, process title (proctitle), is the string that represents the name or command line of a running process, displayed by system monitoring tools like ps, top, and htop. + /// + public const string AttributeProcessTitle = "process.title"; + /// /// The effective user ID (EUID) of the process. /// @@ -153,6 +184,11 @@ public static class ProcessAttributes /// public const string AttributeProcessVpid = "process.vpid"; + /// + /// The working directory of the process. + /// + public const string AttributeProcessWorkingDirectory = "process.working_directory"; + /// /// Specifies whether the context switches for this data point were voluntary or involuntary. /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProfileAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProfileAttributes.cs new file mode 100644 index 0000000000..7d6acb5640 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProfileAttributes.cs @@ -0,0 +1,72 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class ProfileAttributes +{ + /// + /// Describes the interpreter or compiler of a single frame. + /// + public const string AttributeProfileFrameType = "profile.frame.type"; + + /// + /// Describes the interpreter or compiler of a single frame. + /// + public static class ProfileFrameTypeValues + { + /// + /// .NET. + /// + public const string Dotnet = "dotnet"; + + /// + /// JVM. + /// + public const string Jvm = "jvm"; + + /// + /// Kernel. + /// + public const string Kernel = "kernel"; + + /// + /// C, C++, Go, Rust. + /// + public const string Native = "native"; + + /// + /// Perl. + /// + public const string Perl = "perl"; + + /// + /// PHP. + /// + public const string Php = "php"; + + /// + /// Python. + /// + public const string Cpython = "cpython"; + + /// + /// Ruby. + /// + public const string Ruby = "ruby"; + + /// + /// V8JS. + /// + public const string V8js = "v8js"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs index 3c2845a398..7f70dbf417 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TlsAttributes.cs @@ -70,7 +70,7 @@ public static class TlsAttributes /// /// Deprecated, use server.address instead. /// - [Obsolete("Replaced by `server.address.")] + [Obsolete("Replaced by server.address.")] public const string AttributeTlsClientServerName = "tls.client.server_name"; /// diff --git a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md index 29ab84bca7..331dc114d9 100644 --- a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md +++ b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated to `v1.28.0` release of OpenTelemetry Semantic Conventions. + ([#2189](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2189)) + * Updated to `v1.27.0` release of OpenTelemetry Semantic Conventions. ([#2069](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2069)) diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 index d5969ddac0..8f60be53b9 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 @@ -2,7 +2,7 @@ $SCRIPT_DIR = $PSScriptRoot $ROOT_DIR = "${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -$SEMCONV_VERSION="1.27.0" +$SEMCONV_VERSION="1.28.0" $GENERATOR_VERSION="v0.10.0" Set-Location $SCRIPT_DIR diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh index fb0f0315ec..ea34b10635 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh @@ -5,7 +5,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -SEMCONV_VERSION="1.27.0" +SEMCONV_VERSION="1.28.0" GENERATOR_VERSION="v0.10.0" cd ${SCRIPT_DIR} From 81bcef54b9c4b580850f3621359b741fbb88aeb4 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 9 Oct 2024 14:20:45 -0700 Subject: [PATCH 1343/1499] [onecollector & resources.aws] Mitigate STJ vulnerabilities (#2196) --- build/Common.props | 13 ++++++++---- build/Common.targets | 20 +++++++++++++++++++ .../CHANGELOG.md | 5 +++++ ...OpenTelemetry.Exporter.OneCollector.csproj | 4 ++-- src/OpenTelemetry.Resources.AWS/CHANGELOG.md | 5 +++++ .../OpenTelemetry.Resources.AWS.csproj | 2 +- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/build/Common.props b/build/Common.props index 9a5fbde756..d224b292ad 100644 --- a/build/Common.props +++ b/build/Common.props @@ -35,8 +35,8 @@ [5.0.0,6.0) [8.0.1,) [2.1.0,5.0) - 8.0.0 - 8.0.0 + [8.0.0,) + [8.0.0,) [1.0.3,2.0) [4.2.2,5.0) [3.11.0-beta1.23525.2] @@ -49,8 +49,13 @@ [3.16.0,4.0) [1.2.0-beta.556,2.0) [4.3.4,) - 4.7.0 - [6.0.0,) + [4.7.0,) + + + [4.7.2,) + [4.7.2,) + [6.0.10,) + [8.0.5,) diff --git a/build/Common.targets b/build/Common.targets index faf2349bae..97495b2300 100644 --- a/build/Common.targets +++ b/build/Common.targets @@ -1,3 +1,23 @@ + + + + + + + + diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 79451efd20..7767c3de52 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -5,6 +5,11 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2123](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2123)) +* Bumped `System.Text.Json` reference to `6.0.10` for runtimes older than + `net8.0` and bumped to `8.0.5` on `net8.0` in response to + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#2196](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2196)) + ## 1.10.0-alpha.1 Released 2024-Sep-06 diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 111cb4960c..a1efbd7490 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -14,6 +14,7 @@ in the future (hopefully .NET 9) see https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 1.9.2 + $(SystemTextJsonLatestNet6OutOfBandPkgVer) @@ -23,12 +24,11 @@ - - + diff --git a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md index 96cd089d1b..d9887fb7ed 100644 --- a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md @@ -9,6 +9,11 @@ and add .NET Standard 2.0 target. ([#2164](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2164)) +* Bumped `System.Text.Json` reference to `6.0.10` for runtimes older than + `net8.0` and bumped to `8.0.5` on `net8.0` in response to + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#2196](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2196)) + ## 1.5.0-beta.1 Released 2024-Jun-04 diff --git a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj index acfae6f7c4..1484689837 100644 --- a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj +++ b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj @@ -6,6 +6,7 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Resource Detectors for AWS ElasticBeanstalk, EC2, ECS, EKS. Resources.AWS- + $(SystemTextJsonLatestNet6OutOfBandPkgVer) + Condition="($(SystemTextJsonMinimumRequiredPkgVer.StartsWith('[4.7.2')) OR '$(SystemTextJsonMinimumRequiredPkgVer)' == '4.7.2') AND '$(TargetFrameworkIdentifier)' != '.NETCoreApp'" /> diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 744daabdcb..95b04c34c0 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -15,6 +15,11 @@ * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Lowered the `System.Text.Json` reference to `4.7.2` for `net462` and + `netstandard2.0` targets in response to + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#2198](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2198)) + ## 1.0.0-beta.5 Released 2023-Oct-24 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj index 26630e1596..df75e3f75f 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/OpenTelemetry.Instrumentation.ElasticsearchClient.csproj @@ -7,9 +7,10 @@ Elasticsearch instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.ElasticsearchClient- + $(SystemTextJsonMinimumOutOfBandPkgVer) - true @@ -17,7 +18,6 @@ - diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index fb00a275bd..4295c36d21 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -5,6 +5,11 @@ * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2165](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2165)) +* Added direct reference to `System.Text.Json` for the `net8.0` target with + minimum version of `8.0.5` in response to + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#2198](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2198)) + ## 1.0.0-beta.9 Released 2024-Sep-24 diff --git a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj index 4541d9ffb8..88abca4cb8 100644 --- a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj +++ b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj @@ -5,6 +5,7 @@ OpenTelemetry Resource Detectors for Azure cloud environments. $(PackageTags);ResourceDetector Resources.Azure- + $(SystemTextJsonMinimumOutOfBandPkgVer) - diff --git a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md index fb7b8986e5..66091ab475 100644 --- a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md @@ -6,7 +6,13 @@ is accessible via `AddGcpDetector` extension method on `ResourceBuilder`. ([#1691](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1691)) -For more details, please refer to the [README](README.md). - * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) + +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2167](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2167)) + +* Added direct reference to `System.Text.Json` for the `net8.0` target with + minimum version of `8.0.5` in response to + [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). + ([#2198](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2198)) diff --git a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj index 940fb756f3..6f573b04b6 100644 --- a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj +++ b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj @@ -5,6 +5,7 @@ OpenTelemetry Resource Detectors for Google Cloud Platform environments. $(PackageTags);ResourceDetector Resources.Gcp- + $(SystemTextJsonMinimumOutOfBandPkgVer) - From d51c9f410466699a7848651054faa43fe7aa4470 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 10 Oct 2024 06:53:12 +0000 Subject: [PATCH 1346/1499] [EntityFrameworkCore.Tests] Replace hardcoded TFM (#2201) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- ...elemetry.Instrumentation.EntityFrameworkCore.Tests.csproj | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 44074137a1..6f16846001 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -6,11 +6,8 @@ Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation. - - - - + From 32ad0c2b0ebd85d10b154b8d3f41e8ff1b43c0ed Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 10 Oct 2024 00:05:41 -0700 Subject: [PATCH 1347/1499] [tests] Bump packages and add references to mitigate vulnerability warnings (#2200) --- .../OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj | 4 ++-- ...elemetry.Instrumentation.EntityFrameworkCore.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.SqlClient.Tests.csproj | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index dd8ec60246..2b7c71f91e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 6f16846001..3ccfc7b093 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 730389a718..365d9b93e3 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -20,6 +20,11 @@ + + + + + From 3047022bcad623065cfe09b328368be54b07d30c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 10 Oct 2024 00:17:00 -0700 Subject: [PATCH 1348/1499] [influxdb] Mitigate STJ vulnerabilities (#2202) --- src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md | 5 +++++ .../OpenTelemetry.Exporter.InfluxDB.csproj | 3 +++ .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 553e33cc2e..414cccd813 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Added a direct reference to `System.Text.Json` at `8.0.5` for the + `netstandard2.0` target in response to + [CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4). + ([#2202](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2202)) + ## 1.0.0-alpha.4 Released 2024-Oct-02 diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index 5d6c507da1..f9aa46548e 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -17,6 +17,9 @@ + + + diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index 039e19e902..dc83859018 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -8,7 +8,7 @@ - + From f6bd1a7d391481ac9359e5c30177c69490ce1ee6 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Thu, 10 Oct 2024 09:38:30 -0700 Subject: [PATCH 1349/1499] [extensions.aws + sampler.aws] Lower STJ version (#2199) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 2 +- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 11 ++++++----- .../OpenTelemetry.Extensions.AWS.csproj | 2 +- .../CHANGELOG.md | 2 +- src/OpenTelemetry.Resources.AWS/CHANGELOG.md | 2 +- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 2 +- src/OpenTelemetry.Resources.Gcp/CHANGELOG.md | 2 +- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 5 +++-- .../OpenTelemetry.Sampler.AWS.csproj | 2 +- 9 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index c07e8706eb..cfdb08750e 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -9,7 +9,7 @@ `net8.0` and added a direct reference for `System.Text.Json` at `8.0.5` on `net8.0` in response to [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). - ([#2196](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2196)) + ([#2196](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2196)) ## 1.10.0-alpha.1 diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index f7bb4216b1..00902517b3 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,11 +2,15 @@ ## Unreleased -* Bumped the `System.Text.Json` reference to `6.0.10` for runtimes older than +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2125](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2125)) + +* Lowered the `System.Text.Json` reference to `4.7.2` for runtimes older than `net8.0` and added a direct reference for `System.Text.Json` at `8.0.5` on `net8.0` in response to [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). - ([#2197](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2197)) + ([#2197](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2197), + [#2199](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2199)) ## 1.3.0-beta.2 @@ -18,9 +22,6 @@ Released 2024-Sep-24 * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) -* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. - ([#2125](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2125)) - ## 1.3.0-beta.1 Released 2023-Aug-02 diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index c37c68dd1d..9256c85ddc 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -6,7 +6,7 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Extensions.AWS- - $(SystemTextJsonLatestNet6OutOfBandPkgVer) + $(SystemTextJsonMinimumOutOfBandPkgVer) $(NoWarn);SYSLIB1100;SYSLIB1101 - 1.9.2 + 1.9.3 $(SystemTextJsonLatestNet6OutOfBandPkgVer) diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs index 06694d1d46..6f87d12d02 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs @@ -17,6 +17,8 @@ public void AddExtensionAttributeTest() var state = new CommonSchemaJsonSerializationState("Test", writer); + state.BeginItem(); + state.AddExtensionAttribute(new KeyValuePair("ext.something.field1", 1)); state.AddExtensionAttribute(new KeyValuePair("ext.something.field2", 2)); state.AddExtensionAttribute(new KeyValuePair("ext.something.field3", 3)); @@ -42,8 +44,11 @@ public void AddExtensionAttributeTest() stream.SetLength(0); writer.Reset(stream); + state.Reset("Test", writer); + state.BeginItem(); + Assert.Equal(0, state.ExtensionPropertyCount); Assert.Equal(0, state.ExtensionAttributeCount); From 3010b5f5777af80f8f8c1d256a00c9fb4c1c7066 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 11 Oct 2024 15:34:52 -0700 Subject: [PATCH 1355/1499] [geneva] Add support for exporting otlp metrics via user_events on Linux (#2113) --- .../CHANGELOG.md | 9 + .../Internal/ExporterEventSource.cs | 31 ++ .../UnixDomainSocketDataTransport.cs | 2 +- .../OtlpProtobufMetricExporter.cs | 24 +- .../MetricUnixUserEventsDataTransport.cs | 70 ++++ src/OpenTelemetry.Exporter.Geneva/README.md | 23 +- .../UnixUserEventsDataTransportTests.cs | 334 ++++++++++++++++++ test/Shared/PlatformHelpers.cs | 2 +- 8 files changed, 483 insertions(+), 12 deletions(-) create mode 100644 src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 47b1b1f495..e1fbedc7df 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,6 +5,15 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2117)) +* Added support for exporting metrics via + [user_events](https://docs.kernel.org/trace/user_events.html) on Linux when + OTLP protobuf encoding is enabled via the + `PrivatePreviewEnableOtlpProtobufEncoding=true` connection string switch. With + this, `PrivatePreviewEnableOtlpProtobufEncoding=true` is now supported on both + Widows and Linux. Windows uses ETW as transport, while Linux uses user_events + as transport. + ([#2113](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2113)) + ## 1.9.0 Released 2024-Jun-21 diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index 107acaf52d..d7dacb2383 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -18,6 +18,9 @@ internal sealed class ExporterEventSource : EventSource private const int EVENT_ID_ERROR = 4; // Other common exporter exceptions private const int EVENT_ID_OTLP_PROTOBUF_METRIC = 5; // Failed to serialize metric private const int EVENT_ID_COMPLETED_EXPORT = 6; // Completed export + private const int EVENT_ID_TRANSPORT_ERROR = 7; // Transport error + private const int EVENT_ID_TRANSPORT_EXCEPTION = 8; // Transport exception + private const int EVENT_ID_TRANSPORT_INFO = 9; // Transport info [NonEvent] public void FailedToSendTraceData(Exception ex) @@ -76,6 +79,16 @@ public void FailedToSerializeMetric(string metricName, Exception ex) } } + [NonEvent] + public void TransportException(string transportType, string message, Exception ex) + { + if (Log.IsEnabled(EventLevel.Error, EventKeywords.All)) + { + // TODO: Do not hit ETW size limit even for external library exception stack. + this.TransportException(transportType, message, ex.ToInvariantString()); + } + } + [Event(EVENT_ID_TRACE, Message = "Exporter failed to send trace data. Exception: {0}", Level = EventLevel.Error)] public void FailedToSendTraceData(string error) { @@ -111,4 +124,22 @@ public void ExportCompleted(string exporterName) { this.WriteEvent(EVENT_ID_COMPLETED_EXPORT, exporterName); } + + [Event(EVENT_ID_TRANSPORT_ERROR, Message = "Transport '{0}' error. Message: {1}", Level = EventLevel.Error)] + public void TransportError(string transportType, string error) + { + this.WriteEvent(EVENT_ID_TRANSPORT_ERROR, transportType, error); + } + + [Event(EVENT_ID_TRANSPORT_EXCEPTION, Message = "Transport '{0}' error. Message: {1}, Exception: {2}", Level = EventLevel.Error)] + public void TransportException(string transportType, string error, string ex) + { + this.WriteEvent(EVENT_ID_TRANSPORT_EXCEPTION, transportType, error, ex); + } + + [Event(EVENT_ID_TRANSPORT_INFO, Message = "Transport '{0}' information. Message: {1}", Level = EventLevel.Informational)] + public void TransportInformation(string transportType, string error) + { + this.WriteEvent(EVENT_ID_TRANSPORT_INFO, transportType, error); + } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs index 741daa7516..8a2c4e036f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs @@ -73,7 +73,7 @@ private bool Connect() } catch (Exception ex) { - ExporterEventSource.Log.ExporterException("UDS Connect failed.", ex); + ExporterEventSource.Log.TransportException(nameof(UnixDomainSocketDataTransport), "Attempt to connect to socket failed. Connection will be retried periodically until established.", ex); return false; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index a6bdffad6c..fc6f67e4f8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using System.Runtime.InteropServices; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -15,17 +16,32 @@ internal sealed class OtlpProtobufMetricExporter : IDisposable private readonly Func getResource; - public OtlpProtobufMetricExporter(Func getResource, ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) + public OtlpProtobufMetricExporter( + Func getResource, + ConnectionStringBuilder connectionStringBuilder, + IReadOnlyDictionary prepopulatedMetricDimensions) { + Debug.Assert(getResource != null, "getResource was null"); + + this.getResource = getResource; + +#if NET6_0_OR_GREATER + IMetricDataTransport transport = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? MetricUnixUserEventsDataTransport.Instance + : MetricWindowsEventTracingDataTransport.Instance; +#else if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - // Temporary until we add support for user_events. throw new NotSupportedException("Exporting data in protobuf format is not supported on Linux."); } - this.getResource = getResource; + var transport = MetricWindowsEventTracingDataTransport.Instance; +#endif - this.otlpProtobufSerializer = new OtlpProtobufSerializer(MetricWindowsEventTracingDataTransport.Instance, connectionStringBuilder, prepopulatedMetricDimensions); + this.otlpProtobufSerializer = new OtlpProtobufSerializer( + transport, + connectionStringBuilder, + prepopulatedMetricDimensions); } public ExportResult Export(in Batch batch) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs new file mode 100644 index 0000000000..ea1810201b --- /dev/null +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs @@ -0,0 +1,70 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET + +#nullable enable + +using System.Text; +using Microsoft.LinuxTracepoints.Provider; + +namespace OpenTelemetry.Exporter.Geneva; + +internal sealed class MetricUnixUserEventsDataTransport : IMetricDataTransport +{ + public const uint MetricsProtocol = 0U; + public const string MetricsVersion = "v0.19.00"; + public const string MetricsTracepointName = "otlp_metrics"; + public const string MetricsTracepointNameArgs = $"{MetricsTracepointName} u32 protocol;char[8] version;__rel_loc u8[] buffer"; + + private static readonly ReadOnlyMemory MetricsVersionUtf8 = Encoding.UTF8.GetBytes(MetricsVersion); + private readonly PerfTracepoint metricsTracepoint; + + private MetricUnixUserEventsDataTransport() + { + this.metricsTracepoint = new PerfTracepoint(MetricsTracepointNameArgs); + if (this.metricsTracepoint.RegisterResult != 0) + { + // ENOENT (2): No such file or directory + if (this.metricsTracepoint.RegisterResult == 2) + { + throw new NotSupportedException( + $"Tracepoint registration for 'otlp_metrics' failed with result: '{this.metricsTracepoint.RegisterResult}'. Verify your distribution/kernel supports user_events: https://docs.kernel.org/trace/user_events.html."); + } + + ExporterEventSource.Log.TransportInformation( + nameof(MetricUnixUserEventsDataTransport), + $"Tracepoint registration operation for 'otlp_metrics' returned result '{this.metricsTracepoint.RegisterResult}' which is considered recoverable. Entering running state."); + } + } + + public static MetricUnixUserEventsDataTransport Instance { get; } = new(); + + public void Send(MetricEventType eventType, byte[] body, int size) + { + throw new NotSupportedException(); + } + + public void SendOtlpProtobufEvent(byte[] body, int size) + { + if (this.metricsTracepoint.IsEnabled) + { + var buffer = new ReadOnlySpan(body, 0, size); + + var bufferRelLoc = 0u | ((uint)buffer.Length << 16); + + this.metricsTracepoint.Write( + [MetricsProtocol], + MetricsVersionUtf8.Span, + [bufferRelLoc], + buffer); + } + } + + public void Dispose() + { + this.metricsTracepoint.Dispose(); + } +} + +#endif diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 5d7e1efdb1..2ba0725906 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -268,14 +268,25 @@ On Linux provide an `Endpoint` in addition to the `Account` and `Namespace`. For example: `Endpoint=unix:{UDS Path};Account={MetricAccount};Namespace={MetricNamespace}`. -Set `PrivatePreviewEnableOtlpProtobufEncoding=true` to opt-in to the -experimental feature for changing the underlying serialization format to binary -protobuf following the schema defined in [OTLP +##### OtlpProtobufEncoding + +On Windows set `PrivatePreviewEnableOtlpProtobufEncoding=true` on the +`ConnectionString` to opt-in to the experimental feature for changing the +underlying serialization format to binary protobuf following the schema defined +in [OTLP specification](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.1.0/opentelemetry/proto/metrics/v1/metrics.proto). -> [!NOTE] - > `PrivatePreviewEnableOtlpProtobufEncoding` is currently - > only supported in Windows environment. +As of `1.10.0` `PrivatePreviewEnableOtlpProtobufEncoding=true` is also supported +on Linux. On Linux when using `PrivatePreviewEnableOtlpProtobufEncoding=true` an +`Endpoint` is **NOT** required to be provided on `ConnectionString`. For +example: `Endpoint=unix:Account={MetricAccount};Namespace={MetricNamespace}`. + +> [!IMPORTANT] +> When `PrivatePreviewEnableOtlpProtobufEncoding` is enabled on Linux metrics +> are written using +> [user_events](https://docs.kernel.org/trace/user_events.html). `user_events` +> are a newer feature of the Linux kernel and require a distro with the feature +> enabled. #### `MetricExportIntervalMilliseconds` (optional) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs new file mode 100644 index 0000000000..d3b7fd1ee1 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs @@ -0,0 +1,334 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET6_0_OR_GREATER + +#nullable enable + +using System.Diagnostics; +using System.Globalization; +using System.Text.RegularExpressions; +using Microsoft.LinuxTracepoints.Provider; +using OpenTelemetry.Tests; +using Xunit; +using Xunit.Abstractions; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +[Trait("CategoryName", "Geneva:user_events:metrics")] +public class UnixUserEventsDataTransportTests +{ + /* + * Instructions for running these tests: + * + * 1) You need a version of Linux with user_events available in the kernel. + * This can be done on WSL2 using the 6.6+ kernel. + * + * 2) You have to run the tests with elevation. You don't need elevation to + * write/emit user_events but you need elevation to read them (which + * these tests do). + * + * Command: + * sudo dotnet test --configuration Debug --framework net8.0 --filter CategoryName=Geneva:user_events:metrics + * + * How these tests work: + * + * 1) The tests validate user_events are enabled and make sure the otlp_metrics tracepoint is registered. + * + * 2) A process is spawned to run cat /sys/kernel/debug/tracing/trace_pipe. This is what is listening for events. + * + * 3) Depending on the test, a process is spawned to run sh -c "echo '1' > /sys/kernel/tracing/events/user_events/{this.name}/enable" to enable events. + * + * 4) The thread running the tests writes to user_events using the GenevaExporter code. Then it waits for a bit. Then it checks to see what events (if any) were emitted. + * + * 5) Depending on the test, a process is spawned to run sh -c "echo '0' > /sys/kernel/tracing/events/user_events/{this.name}/enable" to disable events. + */ + + private static readonly byte[] testRequest = [0x0a, 0x0f, 0x12, 0x0d, 0x0a, 0x0b, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x65, 0x72]; + private readonly ITestOutputHelper testOutputHelper; + + public UnixUserEventsDataTransportTests(ITestOutputHelper testOutputHelper) + { + this.testOutputHelper = testOutputHelper; + } + + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux, requireElevatedProcess: true)] + public void UserEvents_Enabled_Succes_Linux() + { + EnsureUserEventsEnabled(); + + var listener = new PerfTracepointListener( + MetricUnixUserEventsDataTransport.MetricsTracepointName, + MetricUnixUserEventsDataTransport.MetricsTracepointNameArgs); + + try + { + listener.Enable(); + + MetricUnixUserEventsDataTransport.Instance.SendOtlpProtobufEvent( + testRequest, + testRequest.Length); + + Thread.Sleep(5000); + + foreach (var e in listener.Events) + { + this.testOutputHelper.WriteLine(string.Join(", ", e.Select(kvp => $"{kvp.Key}={kvp.Value}"))); + } + + Assert.Single(listener.Events); + + var @event = listener.Events[0]; + + Assert.EndsWith($" ({MetricUnixUserEventsDataTransport.MetricsProtocol})", @event["protocol"]); + Assert.Equal(MetricUnixUserEventsDataTransport.MetricsVersion, @event["version"]); + + var eventBufferStringData = @event["buffer"].AsSpan(); + + byte[] eventBuffer = new byte[(eventBufferStringData.Length + 1) / 3]; + + var index = 0; + var position = 0; + while (position < eventBufferStringData.Length) + { + eventBuffer[index++] = byte.Parse(eventBufferStringData.Slice(position, 2), NumberStyles.HexNumber); + position += 3; + } + + Assert.Equal(testRequest, eventBuffer); + } + finally + { + try + { + listener.Disable(); + } + catch + { + } + + listener.Dispose(); + } + } + + [SkipUnlessPlatformMatchesFact(TestPlatform.Linux, requireElevatedProcess: true)] + public void UserEvents_Disabled_Succes_Linux() + { + EnsureUserEventsEnabled(); + + var listener = new PerfTracepointListener( + MetricUnixUserEventsDataTransport.MetricsTracepointName, + MetricUnixUserEventsDataTransport.MetricsTracepointNameArgs); + + try + { + MetricUnixUserEventsDataTransport.Instance.SendOtlpProtobufEvent( + testRequest, + testRequest.Length); + + Thread.Sleep(5000); + + Assert.Empty(listener.Events); + } + finally + { + listener.Dispose(); + } + } + + private static void EnsureUserEventsEnabled() + { + using var userEventsEnableTest = ConsoleCommand.Run("cat", "/sys/kernel/tracing/user_events_status"); + if (userEventsEnableTest.Errors.Any()) + { + throw new NotSupportedException("Kernel does not support user_events. Verify your distribution/kernel supports user_events: https://docs.kernel.org/trace/user_events.html."); + } + } + + private sealed class ConsoleCommand : IDisposable + { + private readonly Process process; + private readonly List output = new(); + private readonly List errors = new(); + + private ConsoleCommand( + string command, + string arguments, + Action? onOutputReceived, + Action? onErrorReceived) + { + Console.WriteLine($"{command} {arguments}"); + + var process = new Process + { + StartInfo = new() + { + FileName = command, + Arguments = arguments, + RedirectStandardOutput = true, + RedirectStandardError = true, + RedirectStandardInput = false, + }, + }; + + process.OutputDataReceived += (sender, args) => + { + if (!string.IsNullOrEmpty(args.Data)) + { + this.output.Add(args.Data); + Console.WriteLine($"[OUT] {args.Data}"); + + onOutputReceived?.Invoke(args.Data); + } + }; + + process.ErrorDataReceived += (sender, args) => + { + if (!string.IsNullOrEmpty(args.Data)) + { + this.errors.Add(args.Data); + Console.WriteLine($"[ERR] {args.Data}"); + + onErrorReceived?.Invoke(args.Data); + } + }; + + process.Start(); + + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + + this.process = process; + } + + public IEnumerable Output => this.output; + + public IEnumerable Errors => this.errors; + + public static ConsoleCommand Run( + string command, + string arguments, + Action? onOutputReceived = null, + Action? onErrorReceived = null) + => new(command, arguments, onOutputReceived, onErrorReceived); + + public void Kill() + { + this.process.Kill(); + } + + public void Dispose() + { + this.process.WaitForExit(); + + this.process.CancelOutputRead(); + this.process.CancelErrorRead(); + + this.process.Dispose(); + } + } + + // Warning: Do NOT use this class/design to listen/read user_events in prod. + // It is a hack to workaround lack of decent bits for listening. Hopefully + // this can be removed if/when + // https://github.com/microsoft/LinuxTracepoints-Net/ has listening bits or + // dotnet/runtime supports user_events (both reading & writing) directly. + private sealed class PerfTracepointListener : IDisposable + { + private readonly string name; + private readonly PerfTracepoint tracepoint; + private readonly ConsoleCommand catCommand; + private readonly Regex eventRegex = new("(\\w+?)=([\\w\\(\\) .,-]*)( |$)", RegexOptions.Compiled); + + public PerfTracepointListener(string name, string nameArgs) + { + this.name = name; + + this.tracepoint = new PerfTracepoint(nameArgs); + if (this.tracepoint.RegisterResult != 0) + { + throw new NotSupportedException($"Tracepoint could not be registered: '{this.tracepoint.RegisterResult}'"); + } + + this.catCommand = ConsoleCommand.Run("cat", "/sys/kernel/debug/tracing/trace_pipe", onOutputReceived: this.OnCatOutputReceived); + if (this.catCommand.Errors.Any()) + { + throw new InvalidOperationException($"Could not read '{name}' tracepoints"); + } + } + + public List> Events { get; } = new(); + + public bool IsEnabled() + { + using var command = ConsoleCommand.Run("cat", $"/sys/kernel/tracing/events/user_events/{this.name}/enable"); + + return command.Errors.Any() || command.Output.Count() != 1 + ? throw new InvalidOperationException($"Could not determine if '{this.name}' tracepoint is enabled") + : command.Output.First() != "0"; + } + + public void Enable() + { + using var command = ConsoleCommand.Run("sh", @$"-c ""echo '1' > /sys/kernel/tracing/events/user_events/{this.name}/enable"""); + if (command.Errors.Any()) + { + throw new InvalidOperationException($"Could not enable '{this.name}' tracepoint"); + } + } + + public void Disable() + { + using var command = ConsoleCommand.Run("sh", @$"-c ""echo '0' > /sys/kernel/tracing/events/user_events/{this.name}/enable"""); + if (command.Errors.Any()) + { + throw new InvalidOperationException($"Could not disable '{this.name}' tracepoint"); + } + } + + public void Dispose() + { + try + { + if (this.catCommand != null) + { + this.catCommand.Kill(); + this.catCommand.Dispose(); + } + } + finally + { + this.tracepoint.Dispose(); + } + } + + private void OnCatOutputReceived(string output) + { + var name = $": {this.name}:"; + + int startingPosition = output.IndexOf(name, StringComparison.Ordinal); + if (startingPosition < 0) + { + return; + } + + startingPosition += name.Length; + + var matches = this.eventRegex.Matches(output, startingPosition); + + if (matches.Count > 0) + { + Dictionary eventData = new(matches.Count); + + foreach (Match match in matches) + { + eventData[match.Groups[1].Value] = match.Groups[2].Value; + } + + this.Events.Add(eventData); + } + } + } +} + +#endif diff --git a/test/Shared/PlatformHelpers.cs b/test/Shared/PlatformHelpers.cs index 60d876c609..a737fa49f3 100644 --- a/test/Shared/PlatformHelpers.cs +++ b/test/Shared/PlatformHelpers.cs @@ -37,7 +37,7 @@ public static bool IsProcessElevated(TestPlatform platform) private static class SystemNativeUnix { #pragma warning disable CA5392 // Use DefaultDllImportSearchPaths attribute for P/Invokes - [DllImport("libc", SetLastError = true)] + [DllImport("libc", EntryPoint = "geteuid", SetLastError = true)] internal static extern uint GetEUid(); #pragma warning restore CA5392 // Use DefaultDllImportSearchPaths attribute for P/Invokes } From 0c3ded8da01711144c6d6d607e0908600a9af6ed Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Sun, 13 Oct 2024 22:32:40 -0700 Subject: [PATCH 1356/1499] [repo] Update CI for AWS projects sharing a tag (#2214) --- .github/codecov.yml | 17 ++++++++ .github/workflows/ci.yml | 36 ++-------------- .../OpenTelemetry.Instrumentation.AWS.proj | 41 +++++++++++++++++++ opentelemetry-dotnet-contrib.sln | 1 + 4 files changed, 63 insertions(+), 32 deletions(-) create mode 100644 build/Projects/OpenTelemetry.Instrumentation.AWS.proj diff --git a/.github/codecov.yml b/.github/codecov.yml index b235a093c0..2bbed7c9e0 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -63,6 +63,13 @@ flags: paths: - src/OpenTelemetry.Instrumentation.AspNetCore + unittests-Instrumentation.AWS: + carryforward: true + paths: + - src/OpenTelemetry.Extensions.AWS + - src/OpenTelemetry.Instrumentation.AWS + - src/OpenTelemetry.Instrumentation.AWSLambda + unittests-Instrumentation.ConfluentKafka: carryforward: true paths: @@ -119,6 +126,11 @@ flags: - src/OpenTelemetry.PersistentStorage.Abstractions - src/OpenTelemetry.PersistentStorage.FileSystem + unittests-Resources.AWS: + carryforward: true + paths: + - src/OpenTelemetry.Resources.AWS + unittests-Resources.Azure: carryforward: true paths: @@ -149,6 +161,11 @@ flags: paths: - src/OpenTelemetry.Resources.ProcessRuntime + unittests-Sampler.AWS: + carryforward: true + paths: + - src/OpenTelemetry.Sampler.AWS + unittests-SemanticConventions: carryforward: true paths: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8368761a64..bba59cb532 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,12 +30,10 @@ jobs: exporter-onecollector: ['*/OpenTelemetry.Exporter.OneCollector*/**', '!**/*.md'] exporter-stackdriver: ['*/OpenTelemetry.Exporter.Stackdriver*/**', '!**/*.md'] extensions: ['*/OpenTelemetry.Extensions/**', '*/OpenTelemetry.Extensions.Tests/**', '!**/*.md'] - extensions-aws: ['*/OpenTelemetry.Extensions.AWS*/**', '!**/*.md'] extensions-enrichment: ['*/OpenTelemetry.Extensions.Enrichment*/**', '!**/*.md'] instrumentation-aspnet: ['*/OpenTelemetry.Instrumentation.AspNet/**', '*/OpenTelemetry.Instrumentation.AspNet.Tests/**', '*/OpenTelemetry.Instrumentation.OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.*/**', 'examples/AspNet/**', '!**/*.md'] instrumentation-aspnetcore: ['*/OpenTelemetry.Instrumentation.AspNetCore*/**', '!**/*.md'] - instrumentation-aws: ['*/OpenTelemetry.Instrumentation.AWS/**', '*/OpenTelemetry.Instrumentation.AWS.Tests/**', '!**/*.md'] - instrumentation-aws-lambda: ['*/OpenTelemetry.Instrumentation.AWSLambda/**', '*/OpenTelemetry.Instrumentation.AWSLambda.Tests/**', '!**/*.md'] + instrumentation-aws: ['*/OpenTelemetry.Extensions.AWS*/**', '*/OpenTelemetry.Instrumentation.AWS*/**', '!**/*.md'] instrumentation-cassandra: ['*/OpenTelemetry.Instrumentation.Cassandra*/**', '!**/*.md'] instrumentation-confluentkafka: ['*/OpenTelemetry.Instrumentation.ConfluentKafka*/**', 'examples/kafka/**', '!**/*.md'] instrumentation-elasticsearchclient: ['*/OpenTelemetry.Instrumentation.ElasticsearchClient*/**', '!**/*.md'] @@ -61,7 +59,7 @@ jobs: resources-operatingsystem: ['*/OpenTelemetry.Resources.OperatingSystem/**', '*/OpenTelemetry.Resources.OperatingSystem.Tests/**', '!**/*.md'] resources-process: ['*/OpenTelemetry.Resources.Process/**', '*/OpenTelemetry.Resources.Process.Tests/**', '!**/*.md'] resources-processruntime: ['*/OpenTelemetry.Resources.ProcessRuntime/**', '*/OpenTelemetry.Resources.ProcessRuntime.Tests/**', '!**/*.md'] - sampler-aws: ['*/OpenTelemetry.Sampler.AWS**/**', '!**/*.md'] + sampler-aws: ['*/OpenTelemetry.Sampler.AWS*/**', '!**/*.md'] semanticconventions: ['*/OpenTelemetry.SemanticConventions*/**', '!**/*.md'] lint-md: @@ -151,17 +149,6 @@ jobs: project-name: Component[OpenTelemetry.Extensions] code-cov-name: Extensions - build-test-extensions-aws: - needs: detect-changes - if: | - contains(needs.detect-changes.outputs.changes, 'extensions-aws') - || contains(needs.detect-changes.outputs.changes, 'build') - || contains(needs.detect-changes.outputs.changes, 'shared') - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: Component[OpenTelemetry.Extensions.AWS] - code-cov-name: Extensions.AWS - build-test-extensions-enrichment: needs: detect-changes if: | @@ -206,21 +193,9 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml with: - project-name: Component[OpenTelemetry.Instrumentation.AWS] + project-name: OpenTelemetry.Instrumentation.AWS code-cov-name: Instrumentation.AWS - build-test-instrumentation-awslambda: - needs: detect-changes - if: | - contains(needs.detect-changes.outputs.changes, 'instrumentation-awslambda') - || contains(needs.detect-changes.outputs.changes, 'build') - || contains(needs.detect-changes.outputs.changes, 'shared') - uses: ./.github/workflows/Component.BuildTest.yml - with: - project-name: Component[OpenTelemetry.Instrumentation.AWSLambda] - code-cov-name: Instrumentation.AWSLambda - tfm-list: '[ "net8.0" ]' - build-test-instrumentation-cassandra: needs: detect-changes if: | @@ -524,7 +499,7 @@ jobs: build-test-sampler-aws: needs: detect-changes if: | - contains(needs.detect-changes.outputs.changes, 'resources-sampler-aws') + contains(needs.detect-changes.outputs.changes, 'sampler-aws') || contains(needs.detect-changes.outputs.changes, 'build') || contains(needs.detect-changes.outputs.changes, 'shared') uses: ./.github/workflows/Component.BuildTest.yml @@ -563,7 +538,6 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'extensions-enrichment') || contains(needs.detect-changes.outputs.changes, 'instrumentation-aspnetcore') || contains(needs.detect-changes.outputs.changes, 'instrumentation-aws') - || contains(needs.detect-changes.outputs.changes, 'instrumentation-awslambda') || contains(needs.detect-changes.outputs.changes, 'instrumentation-confluentkafka') || contains(needs.detect-changes.outputs.changes, 'instrumentation-eventcounters') || contains(needs.detect-changes.outputs.changes, 'instrumentation-grpcnetclient') @@ -598,12 +572,10 @@ jobs: build-test-exporter-onecollector, build-test-exporter-stackdriver, build-test-extensions, - build-test-extensions-aws, build-test-extensions-enrichment, build-test-instrumentation-aspnet, build-test-instrumentation-aspnetcore, build-test-instrumentation-aws, - build-test-instrumentation-awslambda, build-test-instrumentation-cassandra, build-test-instrumentation-confluentkafka, build-test-instrumentation-elasticsearchclient, diff --git a/build/Projects/OpenTelemetry.Instrumentation.AWS.proj b/build/Projects/OpenTelemetry.Instrumentation.AWS.proj new file mode 100644 index 0000000000..3b569606ba --- /dev/null +++ b/build/Projects/OpenTelemetry.Instrumentation.AWS.proj @@ -0,0 +1,41 @@ + + + + $([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.Parent.FullName) + Instrumentation.AWS- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index b4f5fc258c..b4ee4018d3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -292,6 +292,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{04 build\Projects\OpenTelemetry.Extensions.Enrichment.proj = build\Projects\OpenTelemetry.Extensions.Enrichment.proj build\Projects\OpenTelemetry.Instrumentation.AspNet.proj = build\Projects\OpenTelemetry.Instrumentation.AspNet.proj build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj = build\Projects\OpenTelemetry.Instrumentation.AspNetCore.proj + build\Projects\OpenTelemetry.Instrumentation.AWS.proj = build\Projects\OpenTelemetry.Instrumentation.AWS.proj build\Projects\OpenTelemetry.Instrumentation.ConfluentKafka.proj = build\Projects\OpenTelemetry.Instrumentation.ConfluentKafka.proj build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj = build\Projects\OpenTelemetry.Instrumentation.EventCounters.proj build\Projects\OpenTelemetry.Instrumentation.GrpcCore.proj = build\Projects\OpenTelemetry.Instrumentation.GrpcCore.proj From e6061287c851d0dd921df3eec178e71ee0715494 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 15 Oct 2024 21:06:25 -0700 Subject: [PATCH 1357/1499] [repo] Clean up codecov (#2216) --- .github/codecov.yml | 74 ++++++++++++++++++++--- .github/workflows/Component.BuildTest.yml | 10 ++- .github/workflows/ci.yml | 6 ++ 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/.github/codecov.yml b/.github/codecov.yml index 2bbed7c9e0..ae835620c7 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -24,7 +24,6 @@ comment: ignore: - "**.md" - - "src/Shared" # copied from main OTel project and has code coverage there - "test" - "examples" - "build" @@ -32,26 +31,41 @@ ignore: - ".vscode" flags: - unittests-Solution: + unittests-Exporter.Geneva: carryforward: true paths: - - src + - src/OpenTelemetry.Exporter.Geneva - unittests-Exporter.Geneva: + unittests-Exporter.InfluxDB: carryforward: true paths: - - src/OpenTelemetry.Exporter.Geneva + - src/OpenTelemetry.Exporter.InfluxDB + + unittests-Exporter.Instana: + carryforward: true + paths: + - src/OpenTelemetry.Exporter.Instana unittests-Exporter.OneCollector: carryforward: true paths: - src/OpenTelemetry.Exporter.OneCollector + unittests-Exporter.Stackdriver: + carryforward: true + paths: + - src/OpenTelemetry.Exporter.Stackdriver + unittests-Extensions: carryforward: true paths: - src/OpenTelemetry.Extensions + unittests-Extensions.Enrichment: + carryforward: true + paths: + - src/OpenTelemetry.Extensions.Enrichment + unittests-Instrumentation.AspNet: carryforward: true paths: @@ -70,26 +84,52 @@ flags: - src/OpenTelemetry.Instrumentation.AWS - src/OpenTelemetry.Instrumentation.AWSLambda + # Note: No unit tests currently for Cassandra being run in CI. + #unittests-Instrumentation.Cassandra: + # carryforward: true + # paths: + # - src/OpenTelemetry.Instrumentation.Cassandra + unittests-Instrumentation.ConfluentKafka: carryforward: true paths: - src/OpenTelemetry.Instrumentation.ConfluentKafka + unittests-Instrumentation.ElasticsearchClient: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.ElasticsearchClient + + unittests-Instrumentation.EntityFrameworkCore: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.EntityFrameworkCore + unittests-Instrumentation.EventCounters: carryforward: true paths: - src/OpenTelemetry.Instrumentation.EventCounters - unittests-Instrumentation.Http: + unittests-Instrumentation.GrpcCore: carryforward: true paths: - - src/OpenTelemetry.Instrumentation.Http + - src/OpenTelemetry.Instrumentation.GrpcCore unittests-Instrumentation.GrpcNetClient: carryforward: true paths: - src/OpenTelemetry.Instrumentation.GrpcNetClient + unittests-Instrumentation.Hangfire: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Hangfire + + unittests-Instrumentation.Http: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Http + unittests-Instrumentation.Owin: carryforward: true paths: @@ -100,6 +140,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Process + unittests-Instrumentation.Quartz: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.Quartz + unittests-Instrumentation.Runtime: carryforward: true paths: @@ -136,6 +181,11 @@ flags: paths: - src/OpenTelemetry.Resources.Azure + unittests-Resources.Container: + carryforward: true + paths: + - src/OpenTelemetry.Resources.Container + unittests-Resources.Gcp: carryforward: true paths: @@ -166,7 +216,13 @@ flags: paths: - src/OpenTelemetry.Sampler.AWS - unittests-SemanticConventions: + # Note: No unit tests currently for SemanticConventions being run in CI. + #unittests-SemanticConventions: + # carryforward: true + # paths: + # - src/OpenTelemetry.SemanticConventions + + unittests-Contrib.Shared.Tests: carryforward: true paths: - - src/OpenTelemetry.SemanticConventions + - src/Shared diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index f3ac05bfde..8d7a245595 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -6,6 +6,10 @@ on: project-name: required: true type: string + run-tests: + required: false + default: true + type: boolean code-cov-name: required: true type: string @@ -87,6 +91,7 @@ jobs: run: dotnet build ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore - name: dotnet test ${{ steps.resolve-project.outputs.title }} + if: ${{ inputs.run-tests }} run: dotnet test ${{ steps.resolve-project.outputs.project }} --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true - name: dotnet pack ${{ steps.resolve-project.outputs.title }} @@ -94,14 +99,15 @@ jobs: run: dotnet pack ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore --no-build -p:EnablePackageValidation=true - name: Install coverage tool + if: ${{ inputs.run-tests }} run: dotnet tool install -g dotnet-coverage - name: Merging test results - if: ${{ hashFiles('./TestResults/**/*.coverage') != '' }} + if: ${{ inputs.run-tests && hashFiles('./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 }} - if: ${{ hashFiles('./TestResults/Cobertura.xml') != '' }} + if: ${{ inputs.run-tests && hashFiles('./TestResults/Cobertura.xml') != '' }} uses: codecov/codecov-action@v4 continue-on-error: true # Note: Don't fail for upload failures env: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bba59cb532..a158adc921 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -206,6 +206,11 @@ jobs: with: project-name: Component[OpenTelemetry.Instrumentation.Cassandra] code-cov-name: Instrumentation.Cassandra + run-tests: false + # Note: There is a unit test project for Cassandra but it only contains + # integration tests, which get skipped. This results in empty coverage + # files which messes with codecov. Enable tests if any real unit tests + # get added. build-test-instrumentation-confluentkafka: needs: detect-changes @@ -517,6 +522,7 @@ jobs: with: project-name: OpenTelemetry.SemanticConventions code-cov-name: SemanticConventions + run-tests: false # Note: No test project build-test-contrib-shared-tests: needs: detect-changes From f2ccaf703e1c3fe34d18039f2faf34b6696b0f73 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 15 Oct 2024 23:24:02 -0700 Subject: [PATCH 1358/1499] [geneva] Nullable annotations for the metrics folder (#2218) --- .../Internal/ConnectionStringBuilder.cs | 10 +++ .../Metrics/MetricSerializer.cs | 11 ++- .../OtlpProtobuf/FieldNumberConstants.cs | 2 + .../OtlpProtobufMetricExporter.cs | 6 +- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 80 +++++++++++-------- .../OtlpProtobuf/ProtobufSerializerHelper.cs | 2 + .../Metrics/OtlpProtobuf/TimestampHelpers.cs | 2 + .../Metrics/OtlpProtobuf/WireType.cs | 2 + .../Metrics/TlvMetricExporter.cs | 40 +++++++--- .../Metrics/Transport/IMetricDataTransport.cs | 2 + .../MetricUnixDomainSocketDataTransport.cs | 2 + .../MetricWindowsEventTracingDataTransport.cs | 4 +- 12 files changed, 113 insertions(+), 50 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index fa8515ba0a..2f0e32f07e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -244,6 +244,16 @@ public string ParseUnixDomainSocketPath() } } + public bool TryGetMetricsAccountAndNamespace( + [NotNullWhen(true)] out string? metricsAccount, + [NotNullWhen(true)] out string? metricsNamespace) + { + var hasAccount = this.parts.TryGetValue(nameof(this.Account), out metricsAccount); + var hasNamespace = this.parts.TryGetValue(nameof(this.Namespace), out metricsNamespace); + + return hasAccount && hasNamespace; + } + /// /// Replace first charater of string if it matches with with . /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs index 07912927c2..ee5358693b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -174,11 +176,11 @@ internal static class MetricSerializer /// Index of the buffer. /// The value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeString(byte[] buffer, ref int bufferIndex, string value) + public static void SerializeString(byte[] buffer, ref int bufferIndex, string? value) { if (!string.IsNullOrEmpty(value)) { - if (bufferIndex + value.Length + sizeof(short) >= buffer.Length) + if (bufferIndex + value!.Length + sizeof(short) >= buffer.Length) { // TODO: What should we do when the data is invalid? } @@ -391,12 +393,13 @@ public static unsafe void SerializeFloat64(byte[] buffer, ref int bufferIndex, d /// Index of the buffer. /// The value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SerializeBase128String(byte[] buffer, ref int bufferIndex, string value) + public static void SerializeBase128String(byte[] buffer, ref int bufferIndex, string? value) { if (!string.IsNullOrEmpty(value)) { - if (bufferIndex + value.Length + sizeof(short) >= buffer.Length) + if (bufferIndex + value!.Length + sizeof(short) >= buffer.Length) { + // TODO: What should we do when the data is invalid? } var encodedValue = Encoding.UTF8.GetBytes(value); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs index 65d8738ef4..bc43c5d956 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Runtime.CompilerServices; using OpenTelemetry.Metrics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index fc6f67e4f8..07c5b9fa77 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using System.Runtime.InteropServices; using OpenTelemetry.Metrics; @@ -19,11 +21,11 @@ internal sealed class OtlpProtobufMetricExporter : IDisposable public OtlpProtobufMetricExporter( Func getResource, ConnectionStringBuilder connectionStringBuilder, - IReadOnlyDictionary prepopulatedMetricDimensions) + IReadOnlyDictionary? prepopulatedMetricDimensions) { Debug.Assert(getResource != null, "getResource was null"); - this.getResource = getResource; + this.getResource = getResource!; #if NET6_0_OR_GREATER IMetricDataTransport transport = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 4680b09887..302de42bef 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + +using System.Diagnostics; using System.Globalization; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -14,13 +17,13 @@ internal sealed class OtlpProtobufSerializer private const int TagAndLengthSize = 4; private readonly Dictionary> scopeMetrics = new(); - private readonly string metricNamespace; - private readonly string metricAccount; - private readonly byte[] prepopulatedNumberDataPointAttributes; + private readonly string? metricNamespace; + private readonly string? metricAccount; + private readonly byte[]? prepopulatedNumberDataPointAttributes; private readonly int prepopulatedNumberDataPointAttributesLength; - private readonly byte[] prepopulatedHistogramDataPointAttributes; + private readonly byte[]? prepopulatedHistogramDataPointAttributes; private readonly int prepopulatedHistogramDataPointAttributesLength; - private readonly byte[] prepopulatedExponentialHistogramDataPointAttributes; + private readonly byte[]? prepopulatedExponentialHistogramDataPointAttributes; private readonly int prepopulatedExponentialHistogramDataPointAttributesLength; private int resourceMetricTagAndLengthIndex; private int scopeMetricsTagAndLengthIndex; @@ -34,9 +37,14 @@ internal sealed class OtlpProtobufSerializer private int metricPointValueIndex; private ExportResult metricExportResult; - public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) + public OtlpProtobufSerializer( + IMetricDataTransport metricDataTransport, + ConnectionStringBuilder? connectionStringBuilder, + IReadOnlyDictionary? prepopulatedMetricDimensions) { - this.MetricDataTransport = metricDataTransport; + Debug.Assert(metricDataTransport != null, "metricDataTransport was null"); + + this.MetricDataTransport = metricDataTransport!; // Taking a arbitrary number here for writing attributes. byte[] temp = new byte[20000]; @@ -44,40 +52,31 @@ public OtlpProtobufSerializer(IMetricDataTransport metricDataTransport, Connecti { // Initialize numberDataPoint attributes. int cursor = 0; - SerializeTags(temp, ref cursor, prepopulatedMetricDimensions, FieldNumberConstants.NumberDataPoint_attributes); + SerializeTags(temp, ref cursor, prepopulatedMetricDimensions!, FieldNumberConstants.NumberDataPoint_attributes); this.prepopulatedNumberDataPointAttributes = new byte[cursor]; Array.Copy(temp, this.prepopulatedNumberDataPointAttributes, cursor); this.prepopulatedNumberDataPointAttributesLength = cursor; // Initialize histogramDataPoint attributes. cursor = 0; - SerializeTags(temp, ref cursor, prepopulatedMetricDimensions, FieldNumberConstants.HistogramDataPoint_attributes); + SerializeTags(temp, ref cursor, prepopulatedMetricDimensions!, FieldNumberConstants.HistogramDataPoint_attributes); this.prepopulatedHistogramDataPointAttributes = new byte[cursor]; Array.Copy(temp, this.prepopulatedHistogramDataPointAttributes, cursor); this.prepopulatedHistogramDataPointAttributesLength = cursor; cursor = 0; - SerializeTags(temp, ref cursor, prepopulatedMetricDimensions, FieldNumberConstants.ExponentialHistogramDataPoint_attributes); + SerializeTags(temp, ref cursor, prepopulatedMetricDimensions!, FieldNumberConstants.ExponentialHistogramDataPoint_attributes); this.prepopulatedExponentialHistogramDataPointAttributes = new byte[cursor]; Array.Copy(temp, this.prepopulatedExponentialHistogramDataPointAttributes, cursor); this.prepopulatedExponentialHistogramDataPointAttributesLength = cursor; } - try + if (connectionStringBuilder?.TryGetMetricsAccountAndNamespace( + out var metricsAccount, + out var metricsNamespace) == true) { - if (connectionStringBuilder != null && connectionStringBuilder.Namespace != null) - { - this.metricNamespace = connectionStringBuilder.Namespace; - } - - if (connectionStringBuilder != null && connectionStringBuilder.Account != null) - { - this.metricAccount = connectionStringBuilder.Account; - } - } - catch - { - // TODO: add log. + this.metricAccount = metricsAccount; + this.metricNamespace = metricsNamespace; } } @@ -99,7 +98,7 @@ internal static void WriteInstrumentDetails(byte[] buffer, ref int cursor, Metri } } - internal static void SerializeInstrumentationScope(byte[] buffer, ref int cursor, string name, IEnumerable> meterTags) + internal static void SerializeInstrumentationScope(byte[] buffer, ref int cursor, string name, IEnumerable>? meterTags) { int tagAndLengthIndex = cursor; cursor += TagAndLengthSize; @@ -145,7 +144,7 @@ internal static void SerializeTag(byte[] buffer, ref int cursor, string key, obj { case char: case string: - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)!); break; case bool b: ProtobufSerializerHelper.WriteBoolWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_bool_value, (bool)value); @@ -165,7 +164,17 @@ internal static void SerializeTag(byte[] buffer, ref int cursor, string key, obj ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.AnyValue_double_value, Convert.ToDouble(value, CultureInfo.InvariantCulture)); break; default: - ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, Convert.ToString(value, CultureInfo.InvariantCulture)); + string repr; + try + { + repr = Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty; + } + catch + { + repr = $"ERROR: type {value.GetType().FullName} is not supported"; + } + + ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.AnyValue_string_value, repr); break; // TODO: Handle array type. @@ -277,11 +286,11 @@ private static void SerializeExemplar(byte[] buffer, ref int cursor, in Exemp { // Casting to ulong is ok here as the bit representation for long versus ulong will be the same // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_int, (ulong)(long)(object)value); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_int, (ulong)(long)(object)value!); } else if (typeof(T) == typeof(double)) { - ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_double, (double)(object)value); + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.Exemplar_as_double, (double)(object)value!); } var time = (ulong)exemplar.Timestamp.ToUnixTimeNanoseconds(); @@ -306,11 +315,14 @@ private static void SerializeExemplarTags(byte[] buffer, ref int cursor, ReadOnl { foreach (var tag in tags) { - SerializeTag(buffer, ref cursor, tag.Key, tag.Value, FieldNumberConstants.Exemplar_attributes); + if (tag.Value != null) + { + SerializeTag(buffer, ref cursor, tag.Key, tag.Value, FieldNumberConstants.Exemplar_attributes); + } } } - private static void SerializeTags(byte[] buffer, ref int cursor, IEnumerable> attributes, int fieldNumber) + private static void SerializeTags(byte[] buffer, ref int cursor, IEnumerable>? attributes, int fieldNumber) { if (attributes != null) { @@ -661,11 +673,11 @@ private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNum { // Casting to ulong is ok here as the bit representation for long versus ulong will be the same // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) - ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_int, (ulong)(long)(object)value); + ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_int, (ulong)(long)(object)value!); } else if (typeof(T) == typeof(double)) { - ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_double, (double)(object)value); + ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.NumberDataPoint_as_double, (double)(object)value!); } var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); @@ -740,7 +752,7 @@ private void SerializeResource(byte[] buffer, ref int cursor, Resource resource) cursor += TagAndLengthSize; int valueIndex = cursor; - SerializeTags(buffer, ref cursor, resource.Attributes, FieldNumberConstants.Resource_attributes); + SerializeTags(buffer, ref cursor, resource.Attributes!, FieldNumberConstants.Resource_attributes); // TODO: check to see if should de-dupe in case the values are also provided via resource attributes. if (this.metricAccount != null) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs index 9cfaa5a172..f4edfacc26 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs index 68c23b28a9..c7d0600d45 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs index af5b2b297b..2dd15eef04 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 78fcd1cce8..49c69ab2dc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -14,15 +16,17 @@ internal sealed class TlvMetricExporter : IDisposable private readonly ushort prepopulatedDimensionsCount; private readonly int fixedPayloadStartIndex; private readonly IMetricDataTransport metricDataTransport; - private readonly List serializedPrepopulatedDimensionsKeys; - private readonly List serializedPrepopulatedDimensionsValues; + private readonly List? serializedPrepopulatedDimensionsKeys; + private readonly List? serializedPrepopulatedDimensionsValues; private readonly byte[] buffer = new byte[GenevaMetricExporter.BufferSize]; private readonly string defaultMonitoringAccount; private readonly string defaultMetricNamespace; private bool isDisposed; - internal TlvMetricExporter(ConnectionStringBuilder connectionStringBuilder, IReadOnlyDictionary prepopulatedMetricDimensions) + internal TlvMetricExporter( + ConnectionStringBuilder connectionStringBuilder, + IReadOnlyDictionary? prepopulatedMetricDimensions) { this.defaultMonitoringAccount = connectionStringBuilder.Account; this.defaultMetricNamespace = connectionStringBuilder.Namespace; @@ -581,6 +585,21 @@ private static void SerializeHistogramBucketWithTLV(in HistogramBucket bucket, b MetricSerializer.SerializeUInt32(buffer, ref bufferIndex, Convert.ToUInt32(bucket.BucketCount)); } + private static string? ConvertTagValueToString(object? value) + { + string? repr; + try + { + repr = Convert.ToString(value, CultureInfo.InvariantCulture); + } + catch + { + repr = $"ERROR: type {value?.GetType().FullName} is not supported"; + } + + return repr; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagCollection tags, byte[] buffer, ref int bufferIndex, out string monitoringAccount, out string metricNamespace) { @@ -602,7 +621,7 @@ private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagColle // Serialize PrepopulatedDimensions keys for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) { - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys[i]); + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsKeys![i]); } if (this.prepopulatedDimensionsCount > 0) @@ -635,7 +654,7 @@ private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagColle // Serialize PrepopulatedDimensions values for (ushort i = 0; i < this.prepopulatedDimensionsCount; i++) { - MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues[i]); + MetricSerializer.SerializeEncodedString(buffer, ref bufferIndex, this.serializedPrepopulatedDimensionsValues![i]); } // Serialize MetricPoint Dimension values @@ -661,8 +680,8 @@ private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagColle continue; } - var dimensionValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture); - if (dimensionValue.Length > GenevaMetricExporter.MaxDimensionValueSize) + var dimensionValue = ConvertTagValueToString(tag.Value); + if (dimensionValue?.Length > GenevaMetricExporter.MaxDimensionValueSize) { // TODO: Data Validation } @@ -693,8 +712,11 @@ private List SerializePrepopulatedDimensionsValues(IEnumerable v var serializedValues = new List(this.prepopulatedDimensionsCount); foreach (var value in values) { - var valueAsString = Convert.ToString(value, CultureInfo.InvariantCulture); - serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); + var valueAsString = ConvertTagValueToString(value); + if (valueAsString != null) + { + serializedValues.Add(Encoding.UTF8.GetBytes(valueAsString)); + } } return serializedValues; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs index 1c40c4303d..108f8a082c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + namespace OpenTelemetry.Exporter.Geneva; internal interface IMetricDataTransport : IDisposable diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs index 4faa04560f..27bef6682b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using OpenTelemetry.Exporter.Geneva.Transports; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs index becbcf7ead..0e04309d8b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + #if NET using System.Diagnostics.CodeAnalysis; #endif @@ -102,7 +104,7 @@ protected override void Dispose(bool disposing) // No managed resources to release. // The singleton instance is kept alive for the lifetime of the application. // Set the instance to null so that future calls to the singleton property can fail explicitly. - Instance = null; + Instance = null!; } this.isDisposed = true; From 3b266fe067ede104eca41dd83d238fbb91fc87a2 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Wed, 16 Oct 2024 05:27:48 -0400 Subject: [PATCH 1359/1499] Add muhammad-othman as Instrumentation.AWS component co-owner (#2217) --- .github/component_owners.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index ba7131f8eb..237de74f1f 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -29,6 +29,7 @@ components: src/OpenTelemetry.Instrumentation.AWS/: - srprash - ppittle + - muhammad-othman src/OpenTelemetry.Instrumentation.AWSLambda/: - rypdal - Oberon00 @@ -131,6 +132,7 @@ components: test/OpenTelemetry.Instrumentation.AWS.Tests/: - srprash - ppittle + - muhammad-othman test/OpenTelemetry.Instrumentation.AWSLambda.Tests/: - rypdal - Oberon00 From b8fe2cb419738f41c0855c25dbe77bb75de10a98 Mon Sep 17 00:00:00 2001 From: Ilia Brahinets Date: Wed, 16 Oct 2024 13:39:43 +0300 Subject: [PATCH 1360/1499] [Exporter.Geneva] Enable nullable globally (#2190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs | 2 -- .../External/TraceLoggingDynamic.cs | 1 - src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs | 2 -- .../GenevaExporterHelperExtensions.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs | 2 -- .../Internal/ConnectionStringBuilder.cs | 2 -- .../Internal/ExporterEventSource.cs | 2 -- .../Internal/MsgPack/MessagePackSerializer.cs | 2 -- .../Internal/MsgPack/MsgPackExporter.cs | 2 -- .../Internal/MsgPack/MsgPackLogExporter.cs | 3 --- .../Internal/MsgPack/MsgPackTraceExporter.cs | 2 -- .../Internal/ReentrantActivityExportProcessor.cs | 2 -- .../Internal/ReentrantExportProcessor.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs | 2 -- .../Internal/TableNameSerializer.cs | 2 -- .../Internal/Tld/JsonSerializer.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs | 2 -- .../Internal/Tld/TldLogExporter.cs | 2 -- .../Internal/Tld/TldTraceExporter.cs | 2 -- .../Internal/Tld/UncheckedASCIIEncoding.cs | 2 -- .../Internal/Transports/EtwDataTransport.cs | 2 -- .../Internal/Transports/IDataTransport.cs | 2 -- .../Internal/Transports/UnixDomainSocketDataTransport.cs | 2 -- .../Internal/Transports/UnixDomainSocketEndPoint.cs | 2 -- .../Metrics/GenevaMetricExporter.cs | 2 -- .../Metrics/GenevaMetricExporterExtensions.cs | 2 -- .../Metrics/GenevaMetricExporterOptions.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs | 2 -- .../Metrics/OtlpProtobuf/FieldNumberConstants.cs | 2 -- .../Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs | 2 -- .../Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs | 2 -- .../Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs | 2 -- .../Metrics/OtlpProtobuf/TimestampHelpers.cs | 2 -- .../Metrics/OtlpProtobuf/WireType.cs | 2 -- src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs | 2 -- .../Metrics/Transport/IMetricDataTransport.cs | 2 -- .../Metrics/Transport/MetricUnixDomainSocketDataTransport.cs | 2 -- .../Metrics/Transport/MetricUnixUserEventsDataTransport.cs | 2 -- .../Transport/MetricWindowsEventTracingDataTransport.cs | 2 -- .../OpenTelemetry.Exporter.Geneva.csproj | 1 - 44 files changed, 87 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs index ab0183c1e5..dd87d4e8c9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/EventNameExportMode.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs index de9e62607c..9030a32b9c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs index e2cea7bb1f..ef2395dad8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs +++ b/src/OpenTelemetry.Exporter.Geneva/External/TraceLoggingDynamic.cs @@ -71,7 +71,6 @@ Most ETW decoding tools are unable to decode an event with more than 128 fields. */ -#nullable enable namespace OpenTelemetry.Exporter.Geneva.External; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs index 452ae78f1e..0dcfe55ce3 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaBaseExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index fda33995c1..380000d30c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.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; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 849b294894..2d508399f4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index 199e46ea08..b7970d1169 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Exporter.Geneva.Tld; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index bc6bc3371e..3a0e4d1189 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.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; diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 5d472e2519..9393e0aa85 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Runtime.InteropServices; using OpenTelemetry.Exporter.Geneva.MsgPack; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 2f0e32f07e..169f3f1a7e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using System.Globalization; using OpenTelemetry.Exporter.Geneva.Transports; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs index d7dacb2383..19c4d4014d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ExporterEventSource.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.Tracing; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs index ca0a5a4ce9..dd5c0312ac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Buffers.Binary; #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs index 3d7bb7def1..cf91ac510d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Collections.Frozen; #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs index 4371d7d373..0c845aaa9f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Collections.Frozen; #endif @@ -175,7 +173,6 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 #pragma warning disable 0618 IReadOnlyList>? listKvp; - if (logRecord.StateValues != null) { listKvp = logRecord.StateValues; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs index 9c0d15beef..675305ad16 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Collections.Frozen; #endif diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs index 59e732a10d..fff9eebf9c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantActivityExportProcessor.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index b53e74861f..b0da2159fc 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Linq.Expressions; using System.Reflection; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs index 39a9fb2931..b665743364 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Schema.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; internal static class Schema diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index 15282d29ae..db60ffe605 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.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 System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs index 8249dc0b50..35a2d8a960 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Globalization; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs index 9c3712a94c..ca52b09a1f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs index 96e7062a11..4aeb5895e8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs index 062e97c875..4e1ae97ceb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Globalization; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs index 04085f22c2..25c4f19591 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs index d25d88fcf3..16797ef848 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.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.Exporter.Geneva/Internal/Transports/IDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/IDataTransport.cs index 36746697ee..daccc87059 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/IDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/IDataTransport.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva.Transports; internal interface IDataTransport diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs index 8a2c4e036f..cf395e03f8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketDataTransport.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Sockets; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs index 62f87ce1f1..a4d6ca0fc6 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs @@ -3,8 +3,6 @@ #if !NET -#nullable enable - using System.Text; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index ade4ff8593..ed78dda6ee 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Reflection; using System.Text.RegularExpressions; using OpenTelemetry.Exporter.Geneva.Metrics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 9f876453d4..c2642a17ed 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index ca14f2d939..f00ab46b77 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Globalization; using OpenTelemetry.Internal; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs index ee5358693b..14634665da 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/MetricSerializer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs index bc43c5d956..65d8738ef4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Runtime.CompilerServices; using OpenTelemetry.Metrics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index 07c5b9fa77..174e5ded5c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Runtime.InteropServices; using OpenTelemetry.Metrics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 302de42bef..73123d6b5f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Globalization; using OpenTelemetry.Metrics; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs index f4edfacc26..9cfaa5a172 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Buffers.Binary; using System.Runtime.CompilerServices; using System.Text; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs index c7d0600d45..68c23b28a9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/TimestampHelpers.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs index 2dd15eef04..af5b2b297b 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/WireType.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; /// diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 49c69ab2dc..1fb5931871 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs index 108f8a082c..1c40c4303d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/IMetricDataTransport.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Exporter.Geneva; internal interface IMetricDataTransport : IDisposable diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs index 27bef6682b..4faa04560f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using OpenTelemetry.Exporter.Geneva.Transports; namespace OpenTelemetry.Exporter.Geneva; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs index ea1810201b..fd81474ccb 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixUserEventsDataTransport.cs @@ -3,8 +3,6 @@ #if NET -#nullable enable - using System.Text; using Microsoft.LinuxTracepoints.Provider; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs index 0e04309d8b..0ad18c47c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.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.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index a2f6c2585c..ed29b2587a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -13,7 +13,6 @@ $(NoWarn);SA1123;SA1310 Exporter.Geneva- 1.9.0 - disable From 5a9c9a88b7cbf38d4f1300d7a22eae1a8f28be13 Mon Sep 17 00:00:00 2001 From: joegoldman2 <147369450+joegoldman2@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:07:08 +0000 Subject: [PATCH 1361/1499] [Instrumentation.EntityFrameworkCore] Update semantic conventions for stable release (#2130) Co-authored-by: joegoldman2 <147369450+joegoldman@users.noreply.github.com> --- opentelemetry-dotnet-contrib.sln | 1 + .../CHANGELOG.md | 22 +++++ .../EntityFrameworkInstrumentationOptions.cs | 27 ++++++ .../EntityFrameworkDiagnosticListener.cs | 36 +++++++- ...Instrumentation.EntityFrameworkCore.csproj | 6 +- .../DatabaseSemanticConventionHelper.cs | 83 +++++++++++++++++++ .../DatabaseSemanticConventionHelperTests.cs | 79 ++++++++++++++++++ .../OpenTelemetry.Contrib.Shared.Tests.csproj | 4 + .../EntityFrameworkDiagnosticListenerTests.cs | 46 +++++++++- ...EntityFrameworkInstrumentationOptionsTests | 42 ++++++++++ 10 files changed, 339 insertions(+), 7 deletions(-) create mode 100644 src/Shared/DatabaseSemanticConventionHelper.cs create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkInstrumentationOptionsTests diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index b4ee4018d3..03eeebb4e7 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -239,6 +239,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E ProjectSection(SolutionItems) = preProject src\Shared\ActivityInstrumentationHelper.cs = src\Shared\ActivityInstrumentationHelper.cs src\Shared\AssemblyVersionExtensions.cs = src\Shared\AssemblyVersionExtensions.cs + src\Shared\DatabaseSemanticConventionHelper.cs = src\Shared\DatabaseSemanticConventionHelper.cs src\Shared\DiagnosticSourceListener.cs = src\Shared\DiagnosticSourceListener.cs src\Shared\DiagnosticSourceSubscriber.cs = src\Shared\DiagnosticSourceSubscriber.cs src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index e1c2828603..2c8fc2c1de 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,28 @@ ## Unreleased +* The new database semantic conventions can be opted in to by setting + the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a + transition period for users to experiment with the new semantic conventions + and adapt as necessary. The environment variable supports the following + values: + * `database` - emit the new, frozen (proposed for stable) database + attributes, and stop emitting the old experimental database + attributes that the instrumentation emitted previously. + * `database/dup` - emit both the old and the frozen (proposed for stable) database + attributes, allowing for a more seamless transition. + * The default behavior (in the absence of one of these values) is to continue + emitting the same database semantic conventions that were emitted in + the previous version. + * Note: this option will be be removed after the new database + semantic conventions is marked stable. At which time this + instrumentation can receive a stable release, and the old database + semantic conventions will no longer be supported. Refer to the + specification for more information regarding the new database + semantic conventions for + [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-spans.md). + ([#2130](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2130)) + ## 1.0.0-beta.12 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs index 04b9cabf4a..60bf2b527d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/EntityFrameworkInstrumentationOptions.cs @@ -3,6 +3,8 @@ using System.Data; using System.Diagnostics; +using Microsoft.Extensions.Configuration; +using static OpenTelemetry.Internal.DatabaseSemanticConventionHelper; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; @@ -11,6 +13,21 @@ namespace OpenTelemetry.Instrumentation.EntityFrameworkCore; /// public class EntityFrameworkInstrumentationOptions { + /// + /// Initializes a new instance of the class. + /// + public EntityFrameworkInstrumentationOptions() + : this(new ConfigurationBuilder().AddEnvironmentVariables().Build()) + { + } + + internal EntityFrameworkInstrumentationOptions(IConfiguration configuration) + { + var databaseSemanticConvention = GetSemanticConventionOptIn(configuration); + this.EmitOldAttributes = databaseSemanticConvention.HasFlag(DatabaseSemanticConvention.Old); + this.EmitNewAttributes = databaseSemanticConvention.HasFlag(DatabaseSemanticConvention.New); + } + /// /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default value: True. /// @@ -50,4 +67,14 @@ public class EntityFrameworkInstrumentationOptions /// /// public Func? Filter { get; set; } + + /// + /// Gets or sets a value indicating whether the old database attributes should be emitted. + /// + internal bool EmitOldAttributes { get; set; } + + /// + /// Gets or sets a value indicating whether the new database attributes should be emitted. + /// + internal bool EmitNewAttributes { get; set; } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 6f04b69f86..322c35c587 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -19,9 +19,12 @@ internal sealed class EntityFrameworkDiagnosticListener : ListenerHandler internal const string EntityFrameworkCoreCommandError = "Microsoft.EntityFrameworkCore.Database.Command.CommandError"; internal const string AttributePeerService = "peer.service"; + internal const string AttributeServerAddress = "server.address"; internal const string AttributeDbSystem = "db.system"; internal const string AttributeDbName = "db.name"; + internal const string AttributeDbNamespace = "db.namespace"; internal const string AttributeDbStatement = "db.statement"; + internal const string AttributeDbQueryText = "db.query.text"; internal static readonly Assembly Assembly = typeof(EntityFrameworkDiagnosticListener).Assembly; internal static readonly string ActivitySourceName = Assembly.GetName().Name; @@ -139,10 +142,19 @@ public override void OnEventWritten(string name, object? payload) } var dataSource = (string)this.dataSourceFetcher.Fetch(connection); - activity.AddTag(AttributeDbName, database); if (!string.IsNullOrEmpty(dataSource)) { - activity.AddTag(AttributePeerService, dataSource); + activity.AddTag(AttributeServerAddress, dataSource); + } + + if (this.options.EmitOldAttributes) + { + activity.AddTag(AttributeDbName, database); + } + + if (this.options.EmitNewAttributes) + { + activity.AddTag(AttributeDbNamespace, database); } } } @@ -196,7 +208,15 @@ public override void OnEventWritten(string name, object? payload) case CommandType.StoredProcedure: if (this.options.SetDbStatementForStoredProcedure) { - activity.AddTag(AttributeDbStatement, commandText); + if (this.options.EmitOldAttributes) + { + activity.AddTag(AttributeDbStatement, commandText); + } + + if (this.options.EmitNewAttributes) + { + activity.AddTag(AttributeDbQueryText, commandText); + } } break; @@ -204,7 +224,15 @@ public override void OnEventWritten(string name, object? payload) case CommandType.Text: if (this.options.SetDbStatementForText) { - activity.AddTag(AttributeDbStatement, commandText); + if (this.options.EmitOldAttributes) + { + activity.AddTag(AttributeDbStatement, commandText); + } + + if (this.options.EmitNewAttributes) + { + activity.AddTag(AttributeDbQueryText, commandText); + } } break; diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj index 4af147744b..361404b0af 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/OpenTelemetry.Instrumentation.EntityFrameworkCore.csproj @@ -7,24 +7,28 @@ Instrumentation.EntityFrameworkCore- - true + + + + diff --git a/src/Shared/DatabaseSemanticConventionHelper.cs b/src/Shared/DatabaseSemanticConventionHelper.cs new file mode 100644 index 0000000000..ef1c85cbc1 --- /dev/null +++ b/src/Shared/DatabaseSemanticConventionHelper.cs @@ -0,0 +1,83 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#nullable enable + +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.Configuration; + +namespace OpenTelemetry.Internal; + +/// +/// Helper class for Database Semantic Conventions. +/// +/// +/// Due to a breaking change in the semantic convention, affected instrumentation libraries +/// must inspect an environment variable to determine which attributes to emit. +/// This is expected to be removed when the instrumentation libraries reach Stable. +/// . +/// +internal static class DatabaseSemanticConventionHelper +{ + internal const string SemanticConventionOptInKeyName = "OTEL_SEMCONV_STABILITY_OPT_IN"; + internal static readonly char[] Separator = new[] { ',', ' ' }; + + [Flags] + public enum DatabaseSemanticConvention + { + /// + /// Instructs an instrumentation library to emit the old experimental Database attributes. + /// + Old = 0x1, + + /// + /// Instructs an instrumentation library to emit the new, v1.28.0 Database attributes. + /// + New = 0x2, + + /// + /// Instructs an instrumentation library to emit both the old and new attributes. + /// + Dupe = Old | New, + } + + public static DatabaseSemanticConvention GetSemanticConventionOptIn(IConfiguration configuration) + { + if (TryGetConfiguredValues(configuration, out var values)) + { + if (values.Contains("database/dup")) + { + return DatabaseSemanticConvention.Dupe; + } + else if (values.Contains("database")) + { + return DatabaseSemanticConvention.New; + } + } + + return DatabaseSemanticConvention.Old; + } + + private static bool TryGetConfiguredValues(IConfiguration configuration, [NotNullWhen(true)] out HashSet? values) + { + try + { + var stringValue = configuration[SemanticConventionOptInKeyName]; + + if (string.IsNullOrWhiteSpace(stringValue)) + { + values = null; + return false; + } + + var stringValues = stringValue!.Split(separator: Separator, options: StringSplitOptions.RemoveEmptyEntries); + values = new HashSet(stringValues, StringComparer.OrdinalIgnoreCase); + return true; + } + catch + { + values = null; + return false; + } + } +} diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs new file mode 100644 index 0000000000..748ac1ea90 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs @@ -0,0 +1,79 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.Configuration; +using Xunit; +using static OpenTelemetry.Internal.DatabaseSemanticConventionHelper; + +namespace OpenTelemetry.Internal.Tests; + +public class DatabaseSemanticConventionHelperTests +{ + public static IEnumerable TestCases => new List + { + new object[] { null!, DatabaseSemanticConvention.Old }, + new object[] { string.Empty, DatabaseSemanticConvention.Old }, + new object[] { " ", DatabaseSemanticConvention.Old }, + new object[] { "junk", DatabaseSemanticConvention.Old }, + new object[] { "none", DatabaseSemanticConvention.Old }, + new object[] { "NONE", DatabaseSemanticConvention.Old }, + new object[] { "database", DatabaseSemanticConvention.New }, + new object[] { "DATABASE", DatabaseSemanticConvention.New }, + new object[] { "database/dup", DatabaseSemanticConvention.Dupe }, + new object[] { "DATABASE/DUP", DatabaseSemanticConvention.Dupe }, + new object[] { "junk,,junk", DatabaseSemanticConvention.Old }, + new object[] { "junk,JUNK", DatabaseSemanticConvention.Old }, + new object[] { "junk1,junk2", DatabaseSemanticConvention.Old }, + new object[] { "junk,database", DatabaseSemanticConvention.New }, + new object[] { "junk,database , database ,junk", DatabaseSemanticConvention.New }, + new object[] { "junk,database/dup", DatabaseSemanticConvention.Dupe }, + new object[] { "junk, database/dup ", DatabaseSemanticConvention.Dupe }, + new object[] { "database/dup,database", DatabaseSemanticConvention.Dupe }, + new object[] { "database,database/dup", DatabaseSemanticConvention.Dupe }, + }; + + [Fact] + public void VerifyFlags() + { + var testValue = DatabaseSemanticConvention.Dupe; + Assert.True(testValue.HasFlag(DatabaseSemanticConvention.Old)); + Assert.True(testValue.HasFlag(DatabaseSemanticConvention.New)); + + testValue = DatabaseSemanticConvention.Old; + Assert.True(testValue.HasFlag(DatabaseSemanticConvention.Old)); + Assert.False(testValue.HasFlag(DatabaseSemanticConvention.New)); + + testValue = DatabaseSemanticConvention.New; + Assert.False(testValue.HasFlag(DatabaseSemanticConvention.Old)); + Assert.True(testValue.HasFlag(DatabaseSemanticConvention.New)); + } + + [Theory] + [MemberData(nameof(TestCases))] + public void VerifyGetSemanticConventionOptIn_UsingEnvironmentVariable(string input, string expectedValue) + { + try + { + Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, input); + + var expected = Enum.Parse(typeof(DatabaseSemanticConvention), expectedValue); + Assert.Equal(expected, GetSemanticConventionOptIn(new ConfigurationBuilder().AddEnvironmentVariables().Build())); + } + finally + { + Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, null); + } + } + + [Theory] + [MemberData(nameof(TestCases))] + public void VerifyGetSemanticConventionOptIn_UsingIConfiguration(string input, string expectedValue) + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = input }) + .Build(); + + var expected = Enum.Parse(typeof(DatabaseSemanticConvention), expectedValue); + Assert.Equal(expected, GetSemanticConventionOptIn(configuration)); + } +} diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj index 53e2d966e5..f6b04bb9c4 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj @@ -7,14 +7,18 @@ + + + + diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 30accde1dd..6610d02ffd 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -86,6 +86,40 @@ public void EntityFrameworkEnrichDisplayNameWithEnrichWithIDbCommand() VerifyActivityData(activity, altDisplayName: $"{expectedDisplayName}"); } + [Fact] + public void EntityFrameworkEnrichDisplayNameWithEnrichWithIDbCommand_New() + { + var exportedItems = new List(); + var expectedDisplayName = "Text main"; + using var shutdownSignal = Sdk.CreateTracerProviderBuilder() + .AddInMemoryExporter(exportedItems) + .AddEntityFrameworkCoreInstrumentation(options => + { + options.EnrichWithIDbCommand = (activity1, command) => + { + var stateDisplayName = $"{command.CommandType} main"; + activity1.DisplayName = stateDisplayName; + activity1.SetTag("db.namespace", stateDisplayName); + }; + options.EmitNewAttributes = true; + }).Build(); + + using (var context = new ItemsContext(this.contextOptions)) + { + var items = context.Set().OrderBy(e => e.Name).ToList(); + + Assert.Equal(3, items.Count); + Assert.Equal("ItemOne", items[0].Name); + Assert.Equal("ItemThree", items[1].Name); + Assert.Equal("ItemTwo", items[2].Name); + } + + Assert.Single(exportedItems); + var activity = exportedItems[0]; + + VerifyActivityData(activity, altDisplayName: $"{expectedDisplayName}", emitNewAttributes: true); + } + [Fact] public void EntityFrameworkContextExceptionEventsInstrumentedTest() { @@ -227,7 +261,7 @@ private static SqliteConnection CreateInMemoryDatabase() return connection; } - private static void VerifyActivityData(Activity activity, bool isError = false, string? altDisplayName = null) + private static void VerifyActivityData(Activity activity, bool isError = false, string? altDisplayName = null, bool emitNewAttributes = false) { Assert.Equal(altDisplayName ?? "main", activity.DisplayName); @@ -237,7 +271,15 @@ private static void VerifyActivityData(Activity activity, bool isError = false, // TBD: SqlLite not setting the DataSource so it doesn't get set. Assert.DoesNotContain(activity.Tags, t => t.Key == EntityFrameworkDiagnosticListener.AttributePeerService); - Assert.Equal(altDisplayName ?? "main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); + if (!emitNewAttributes) + { + Assert.Equal(altDisplayName ?? "main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbName).Value); + } + + if (emitNewAttributes) + { + Assert.Equal(altDisplayName ?? "main", activity.Tags.FirstOrDefault(t => t.Key == EntityFrameworkDiagnosticListener.AttributeDbNamespace).Value); + } if (!isError) { diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkInstrumentationOptionsTests b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkInstrumentationOptionsTests new file mode 100644 index 0000000000..6f8d54b892 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkInstrumentationOptionsTests @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.Configuration; +using OpenTelemetry.Internal; +using Xunit; + +namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests; + +public class EntityFrameworkInstrumentationOptionsTests +{ + [Fact] + public void ShouldEmitOldAttributesWhenStabilityOptInIsDatabaseDup() + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { [DatabaseSemanticConventionHelper.SemanticConventionOptInKeyName] = "database/dup" }) + .Build(); + var options = new EntityFrameworkInstrumentationOptions(configuration); + Assert.True(options.EmitOldAttributes); + Assert.True(options.EmitNewAttributes); + } + + [Fact] + public void ShouldEmitOldAttributesWhenStabilityOptInIsNotSpecified() + { + var configuration = new ConfigurationBuilder().Build(); + var options = new EntityFrameworkInstrumentationOptions(configuration); + Assert.True(options.EmitOldAttributes); + Assert.False(options.EmitNewAttributes); + } + + [Fact] + public void ShouldEmitNewAttributesWhenStabilityOptInIsDatabase() + { + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { [DatabaseSemanticConventionHelper.SemanticConventionOptInKeyName] = "database" }) + .Build(); + var options = new EntityFrameworkInstrumentationOptions(configuration); + Assert.False(options.EmitOldAttributes); + Assert.True(options.EmitNewAttributes); + } +} From f6fb714aaa2cdadd08d1ce0fb629f0c5e36cb2ec Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 18 Oct 2024 10:00:48 -0700 Subject: [PATCH 1362/1499] [repo] Clean up SupportedNetTargetsWithoutNet6 (#2220) --- .github/workflows/Component.BuildTest.yml | 4 ---- build/Common.nonprod.props | 3 +-- .../OpenTelemetry.Contrib.Shared.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Benchmarks.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.InfluxDB.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Instana.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj | 2 +- .../OpenTelemetry.Exporter.OneCollector.Tests.csproj | 2 +- .../OpenTelemetry.Exporter.Stackdriver.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.AWS.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.Enrichment.Tests.csproj | 2 +- .../OpenTelemetry.Extensions.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.AWS.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj | 2 +- ...OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj | 2 +- .../OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Cassandra.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj | 2 +- ...Telemetry.Instrumentation.ElasticsearchClient.Tests.csproj | 2 +- ...Telemetry.Instrumentation.EntityFrameworkCore.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.EventCounters.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Hangfire.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Http.Benchmarks.csproj | 2 +- .../OpenTelemetry.Instrumentation.Http.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Process.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Quartz.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Runtime.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.SqlClient.Tests.csproj | 2 +- ...nTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj | 2 +- .../OpenTelemetry.Instrumentation.Wcf.Tests.csproj | 2 +- .../OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj | 2 +- .../OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj | 2 +- .../OpenTelemetry.Resources.AWS.Tests.csproj | 2 +- .../OpenTelemetry.Resources.Azure.Tests.csproj | 2 +- .../OpenTelemetry.Resources.Container.Tests.csproj | 2 +- .../OpenTelemetry.Resources.Gcp.Tests.csproj | 2 +- .../OpenTelemetry.Resources.Host.Tests.csproj | 2 +- .../OpenTelemetry.Resources.OperatingSystem.Tests.csproj | 2 +- .../OpenTelemetry.Resources.Process.Tests.csproj | 2 +- .../OpenTelemetry.Resources.ProcessRuntime.Tests.csproj | 2 +- .../OpenTelemetry.Sampler.AWS.Tests.csproj | 2 +- test/TestApp.AspNetCore/TestApp.AspNetCore.csproj | 2 +- 46 files changed, 45 insertions(+), 50 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 8d7a245595..dfa463391a 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -79,10 +79,6 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 - with: - dotnet-version: | - 6.0.x - 8.0.x - name: dotnet restore ${{ steps.resolve-project.outputs.title }} run: dotnet restore ${{ steps.resolve-project.outputs.project }} -p:EnablePackageValidation=true diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 255792353f..00bcdce0ba 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -29,8 +29,7 @@ 8.0.1 [17.11.1,18.0) $(OpenTelemetryCoreLatestVersion) - net8.0;net6.0 - net8.0 + net8.0 [2.8.2,3.0) [2.9.0,3.0) [1.6.3,2.0) diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj index f6b04bb9c4..4762d556b8 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj index d8de7b41c1..6a758c273f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj @@ -4,7 +4,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Exe $(NoWarn);SA1201;SA1202;SA1204;SA1311;SA1123 diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index d38697183e..e307744bc8 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Exe $(NoWarn);SA1308;SA1201 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index d72546cfc6..3a410027d8 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -4,7 +4,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Unit test project for Geneva Exporters for OpenTelemetry. $(NoWarn);SA1311;SA1312;SA1313;SA1123;SA1202;OTEL1002 diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj index dc83859018..57deae64a6 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/OpenTelemetry.Exporter.InfluxDB.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Unit test project for InfluxDB Exporter for OpenTelemetry. diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj index ea1dd04e66..58420201b6 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Instana.Tests/OpenTelemetry.Exporter.Instana.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj index 6b9e0c552c..1aa3195078 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/OpenTelemetry.Exporter.OneCollector.Benchmarks.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;$(NetFrameworkMinimumSupportedVersion) Exe Benchmark project for OpenTelemetry .NET OneCollectorExporter. diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj index c3f1264678..fbfa22161a 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OpenTelemetry.Exporter.OneCollector.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry .NET OneCollectorExporter. diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj index 9c5c605224..ad822c461e 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/OpenTelemetry.Exporter.Stackdriver.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for Stackdriver Exporter for OpenTelemetry. diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj index 8489e41f72..c3d48e4f9f 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj +++ b/test/OpenTelemetry.Extensions.AWS.Tests/OpenTelemetry.Extensions.AWS.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj index 6382acc150..0099fdb3eb 100644 --- a/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Enrichment.Tests/OpenTelemetry.Extensions.Enrichment.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry .NET SDK telemetry enrichment. diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 6b9ffb3dd1..1aa7195de6 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry .NET SDK preview features and extensions. diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj index 531c31e2b7..502975fd17 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/OpenTelemetry.Instrumentation.AWS.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for AWS client instrumentation for OpenTelemetry. diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj index e81df4b035..9fcacf8979 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/OpenTelemetry.Instrumentation.AWSLambda.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) Unit test project of OpenTelemetry instrumentation for AWS Lambda. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj index 7d0cb435f8..417dcde39a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) Exe diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 2b7c71f91e..05355921c1 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) Unit test project for OpenTelemetry ASP.NET Core instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj index ca925749b8..757032a71f 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/OpenTelemetry.Instrumentation.Cassandra.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj index e9faf0e74c..03e6599485 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetry.Instrumentation.ConfluentKafka.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry ConfluentKafka instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj index 390dec1886..1fc4a3e23c 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry Elasticsearch client instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj index 3ccfc7b093..74df3dd0dc 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) Unit test project for OpenTelemetry Microsoft.EntityFrameworkCore instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj index e3e1e17a7a..70942ae401 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/OpenTelemetry.Instrumentation.EventCounters.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index aeb25ed8be..b18abc2f97 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index 1efe5efe2e..19028bb635 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry Grpc for .NET instrumentation. $(NoWarn);CS8981 diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj index 2db7102751..2f17480926 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/OpenTelemetry.Instrumentation.Hangfire.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry Hangfire instrumentation. false diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj index c96496222f..2e8a6e4f1c 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/OpenTelemetry.Instrumentation.Http.Benchmarks.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) Exe diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj index c219109b35..586ea0002e 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/OpenTelemetry.Instrumentation.Http.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry HTTP instrumentations. diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 8f786a052b..26e013afed 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj index 1675b22eb9..68031f6206 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/OpenTelemetry.Instrumentation.Quartz.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);net472 Unit test project for OpenTelemetry Quartz.NET instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index ea6d3e9922..3cf92d6f2b 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj index 365d9b93e3..6817647016 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/OpenTelemetry.Instrumentation.SqlClient.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for OpenTelemetry SqlClient instrumentations - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index cfbd7c6aa5..71ae753f08 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry StackExchangeRedis instrumentation. diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 6559d126d9..8343f2c6ae 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry WCF instrumentation. diff --git a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj index e6bf4b974b..ef38c104e4 100644 --- a/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.Abstractions.Tests/OpenTelemetry.PersistentStorage.Abstractions.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj index 92d7b61fa1..13c97097bf 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/OpenTelemetry.PersistentStorage.FileSystem.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj index abfaa2d3f6..8e2510fc3b 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj +++ b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for AWS Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj index def2a76649..2faced9fd9 100644 --- a/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj +++ b/test/OpenTelemetry.Resources.Azure.Tests/OpenTelemetry.Resources.Azure.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj index 7af24366c8..27337cec83 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj +++ b/test/OpenTelemetry.Resources.Container.Tests/OpenTelemetry.Resources.Container.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) Unit test project for Container Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj index 663e1e5a41..6dbe2abd1b 100644 --- a/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj +++ b/test/OpenTelemetry.Resources.Gcp.Tests/OpenTelemetry.Resources.Gcp.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for GCP Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj index 257601185e..465c2f7723 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj +++ b/test/OpenTelemetry.Resources.Host.Tests/OpenTelemetry.Resources.Host.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for Host Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj index b31c404002..3928099638 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OpenTelemetry.Resources.OperatingSystem.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for Operating System Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj index bccea101b5..3fe50dcb1d 100644 --- a/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj +++ b/test/OpenTelemetry.Resources.Process.Tests/OpenTelemetry.Resources.Process.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for Process Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj index 34894d55fd..3a81ad1a82 100644 --- a/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj +++ b/test/OpenTelemetry.Resources.ProcessRuntime.Tests/OpenTelemetry.Resources.ProcessRuntime.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for Process Runtime Detector for OpenTelemetry. diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj index 9f6ec1878e..d8db5a8c05 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj +++ b/test/OpenTelemetry.Sampler.AWS.Tests/OpenTelemetry.Sampler.AWS.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj index 7b4d72c295..ae0043309a 100644 --- a/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj +++ b/test/TestApp.AspNetCore/TestApp.AspNetCore.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargetsWithoutNet6) + $(SupportedNetTargets) From 177748ed2b5d216954b24d45a8511d9963288b1b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Fri, 18 Oct 2024 10:47:25 -0700 Subject: [PATCH 1363/1499] [geneva] Bump MessagePack version in test project to fix vulnerability warning (#2227) --- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 3a410027d8..4cc8b83b36 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -15,7 +15,7 @@ - + From 52099ac22bb29a747435f4904078b14efd549d34 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 21 Oct 2024 10:26:15 -0700 Subject: [PATCH 1364/1499] [repo] Add geneva integration test leg to CI (#2219) --- .github/workflows/Component.BuildTest.yml | 30 ++++++++- .github/workflows/ci.yml | 17 +++++ build/Common.prod.props | 5 ++ .../UnixUserEventsDataTransportTests.cs | 66 +++++++++++++++---- 4 files changed, 104 insertions(+), 14 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index dfa463391a..803606e931 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -25,6 +25,17 @@ on: default: '[ "net462", "net8.0" ]' required: false type: string + test-case-filter: + required: false + type: string + test-require-elevated: + default: false + required: false + type: boolean + pack: + default: true + required: false + type: boolean jobs: build-test: @@ -88,10 +99,22 @@ jobs: - name: dotnet test ${{ steps.resolve-project.outputs.title }} if: ${{ inputs.run-tests }} - run: dotnet test ${{ steps.resolve-project.outputs.project }} --collect:"Code Coverage" --results-directory:TestResults --framework ${{ matrix.version }} --configuration Release --no-restore --no-build --logger:"console;verbosity=detailed" -- RunConfiguration.DisableAppDomain=true + run: > + ${{ inputs.test-require-elevated && matrix.os != 'windows-latest' && 'sudo -E' || '' }} + dotnet test ${{ steps.resolve-project.outputs.project }} + --collect:"Code Coverage" + --results-directory:TestResults + --framework ${{ matrix.version }} + --configuration Release + --no-restore + --no-build + --logger:"console;verbosity=detailed" + --filter "${{ inputs.test-case-filter }}" + -- RunConfiguration.DisableAppDomain=true + ${{ inputs.test-require-elevated && matrix.os != 'windows-latest' && '&& sudo chmod a+rw ./TestResults' || '' }} - name: dotnet pack ${{ steps.resolve-project.outputs.title }} - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ matrix.os == 'windows-latest' && inputs.pack }} run: dotnet pack ${{ steps.resolve-project.outputs.project }} --configuration Release --no-restore --no-build -p:EnablePackageValidation=true - name: Install coverage tool @@ -109,10 +132,11 @@ jobs: env: OS: ${{ matrix.os }} TFM: ${{ matrix.version }} + FILTER: ${{ inputs.test-case-filter }} token: ${{ secrets.CODECOV_TOKEN }} with: file: TestResults/Cobertura.xml - env_vars: OS,TFM + env_vars: OS,TFM,FILTER flags: ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} name: Code Coverage for ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} on [${{ matrix.os }}.${{ matrix.version }}] codecov_yml_path: .github/codecov.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a158adc921..c5ad249b79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -94,6 +94,22 @@ jobs: project-name: Component[OpenTelemetry.Exporter.Geneva] code-cov-name: Exporter.Geneva + build-test-exporter-geneva-integration: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'exporter-geneva') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Exporter.Geneva] + code-cov-name: Exporter.Geneva + os-list: '[ "ubuntu-24.04" ]' # Note: This may be switched to latest once ubuntu-latest has a kernel version >= 6.8.0-1014-azure + tfm-list: '[ "net8.0" ]' # Note: Should be able to remove this once the above is using ubuntu-latest + test-case-filter: CategoryName=Geneva:user_events:metrics + test-require-elevated: true + pack: false + build-test-exporter-influxdb: needs: detect-changes if: | @@ -573,6 +589,7 @@ jobs: lint-yml, lint-dotnet-format, build-test-exporter-geneva, + build-test-exporter-geneva-integration, build-test-exporter-influxdb, build-test-exporter-instana, build-test-exporter-onecollector, diff --git a/build/Common.prod.props b/build/Common.prod.props index b62120f65f..f0f0788648 100644 --- a/build/Common.prod.props +++ b/build/Common.prod.props @@ -34,6 +34,11 @@ $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(RevisionNumber) $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(RevisionNumber) $(MinVerMajor).$(MinVerMinor).$(MinVerPatch).$(RevisionNumber) + + + false - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) true An OpenTelemetry .NET exporter that exports to local ETW or UDS. diff --git a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj index f9aa46548e..2ce6e466e5 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj +++ b/src/OpenTelemetry.Exporter.InfluxDB/OpenTelemetry.Exporter.InfluxDB.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) true An OpenTelemetry .NET exporter that exports to InfluxDB. Exporter.InfluxDB- diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 0e6b5ca94b..dfb5f27c1d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -1,7 +1,7 @@ - net8.0;netstandard2.1;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);netstandard2.1;$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) true An OpenTelemetry .NET exporter that sends telemetry to Microsoft OneCollector. diff --git a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj index 7e41243dd9..a291cb8043 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj +++ b/src/OpenTelemetry.Exporter.Stackdriver/OpenTelemetry.Exporter.Stackdriver.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) An OpenTelemetry .NET exporter that sends telemetry to Google Stackdriver. $(PackageTags);Stackdriver;Google;GCP;distributed-tracing Exporter.Stackdriver- diff --git a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj index a9ab877267..fe268c03e4 100644 --- a/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj +++ b/src/OpenTelemetry.Extensions.AWS/OpenTelemetry.Extensions.AWS.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry extensions for AWS. Instrumentation.AWS- diff --git a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj index 24ba74844c..47c496cb93 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj +++ b/src/OpenTelemetry.Extensions.Enrichment/OpenTelemetry.Extensions.Enrichment.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry .NET SDK telemetry enrichment. $(NoWarn);CS1591 diff --git a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj index c206aa60fc..74b07e5117 100644 --- a/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj +++ b/src/OpenTelemetry.Extensions/OpenTelemetry.Extensions.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry .NET SDK preview features and extensions. Extensions- diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index c5b345c636..b4b422dd49 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) AWS client instrumentation for OpenTelemetry .NET. Instrumentation.AWS- diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj index e53917cea3..3c3147cc76 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/OpenTelemetry.Instrumentation.AWSLambda.csproj @@ -1,7 +1,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) AWS Lambda tracing wrapper for OpenTelemetry .NET. $(PackageTags);AWS Lambda Instrumentation.AWS- diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index 0f5087d0f1..24409c62c0 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) ASP.NET Core instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNetCore Instrumentation.AspNetCore- diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj index 099e818c78..bede08a835 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetry.Instrumentation.ConfluentKafka.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) Confluent.Kafka instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing;Kafka;Confluent.Kafka true diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj index 20785b022b..b29b183db3 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/OpenTelemetry.Instrumentation.GrpcNetClient.csproj @@ -2,7 +2,7 @@ - net8.0;netstandard2.1;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);netstandard2.1;$(NetStandardMinimumSupportedVersion) gRPC for .NET client instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.GrpcNetClient- diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index a51f538f71..9970dc7fcc 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -1,7 +1,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Http instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index b516536ab4..8f107f48b5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) .NET runtime instrumentation for OpenTelemetry .NET. $(PackageTags);runtime Instrumentation.Runtime- diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index 2736e3ddc5..9a9827c62f 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -1,7 +1,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) SqlClient instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj index bc2acbe7a7..bfc95f6f77 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/OpenTelemetry.Instrumentation.StackExchangeRedis.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) StackExchange.Redis instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing;Redis;StackExchange.Redis Instrumentation.StackExchangeRedis- diff --git a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj index 1484689837..6c9fe6bf60 100644 --- a/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj +++ b/src/OpenTelemetry.Resources.AWS/OpenTelemetry.Resources.AWS.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Resource Detectors for AWS ElasticBeanstalk, EC2, ECS, EKS. Resources.AWS- diff --git a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj index 88abca4cb8..d69f5a3e24 100644 --- a/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj +++ b/src/OpenTelemetry.Resources.Azure/OpenTelemetry.Resources.Azure.csproj @@ -1,7 +1,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) OpenTelemetry Resource Detectors for Azure cloud environments. $(PackageTags);ResourceDetector Resources.Azure- diff --git a/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj b/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj index ad9bec76ea..6bef037057 100644 --- a/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj +++ b/src/OpenTelemetry.Resources.Container/OpenTelemetry.Resources.Container.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) OpenTelemetry Resource Detectors for Container environment. Resources.Container- diff --git a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj index 6f573b04b6..fac843baa0 100644 --- a/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj +++ b/src/OpenTelemetry.Resources.Gcp/OpenTelemetry.Resources.Gcp.csproj @@ -1,7 +1,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) OpenTelemetry Resource Detectors for Google Cloud Platform environments. $(PackageTags);ResourceDetector Resources.Gcp- diff --git a/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj b/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj index 319966e6a3..122277c10b 100644 --- a/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj +++ b/src/OpenTelemetry.Resources.Host/OpenTelemetry.Resources.Host.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Resource Detectors for Host. Resources.Host- diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj index 63b085d0c5..64c0ba695f 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj +++ b/src/OpenTelemetry.Resources.OperatingSystem/OpenTelemetry.Resources.OperatingSystem.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Resource Detectors for Operating System. Resources.OperatingSystem- diff --git a/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj b/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj index 7d333a1c31..d38472ebfc 100644 --- a/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj +++ b/src/OpenTelemetry.Resources.Process/OpenTelemetry.Resources.Process.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Resource Detectors for Process. Resources.Process- diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj b/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj index 03ff0bc483..6e1df6fa94 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj +++ b/src/OpenTelemetry.Resources.ProcessRuntime/OpenTelemetry.Resources.ProcessRuntime.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry Resource Detectors for Process Runtime. Resources.ProcessRuntime- diff --git a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj index dc886777ef..91d0443c6e 100644 --- a/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj +++ b/src/OpenTelemetry.Sampler.AWS/OpenTelemetry.Sampler.AWS.csproj @@ -2,7 +2,7 @@ - net8.0;$(NetStandardMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry remote sampler for AWS X-Ray. Sampler.AWS- diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index fb9ef875d2..85c4c98f0c 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + $(NetMinimumSupportedVersion) true false true From 819161efefa1cba4d303f6baf99e867993ce17d3 Mon Sep 17 00:00:00 2001 From: Muhammad Othman Date: Thu, 24 Oct 2024 14:25:36 -0400 Subject: [PATCH 1369/1499] [Instrumentation.AWS] Move adding request and response info to AWSTracingPipelineHandler (#2137) --- .../CHANGELOG.md | 2 + .../AWSPropagatorPipelineHandler.cs | 179 +-------------- .../Implementation/AWSSemanticConventions.cs | 1 + .../AWSTracingPipelineCustomizer.cs | 11 +- .../AWSTracingPipelineHandler.cs | 213 ++++++++++++++++++ 5 files changed, 228 insertions(+), 178 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index f00015d971..fa00815171 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +* Move adding request and response info to AWSTracingPipelineHandler + ([#2137](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2137)) * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2139](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2139)) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs index 1e97c34c88..20818ba0ff 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSPropagatorPipelineHandler.cs @@ -7,7 +7,6 @@ using Amazon.Runtime.Telemetry; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Extensions.AWS.Trace; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation; @@ -28,191 +27,22 @@ internal class AWSPropagatorPipelineHandler : PipelineHandler carrier[name] = value; }; - private readonly AWSClientInstrumentationOptions options; - - public AWSPropagatorPipelineHandler(AWSClientInstrumentationOptions options) - { - this.options = options; - } - public override void InvokeSync(IExecutionContext executionContext) { - this.ProcessBeginRequest(executionContext); + ProcessBeginRequest(executionContext); base.InvokeSync(executionContext); - - ProcessEndRequest(executionContext); } public override async Task InvokeAsync(IExecutionContext executionContext) { - T? ret = null; - - this.ProcessBeginRequest(executionContext); - - ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); - - ProcessEndRequest(executionContext); - - return ret; - } - -#if NET - [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( - "Trimming", - "IL2075", - Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] -#endif - private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext) - { - var service = requestContext.ServiceMetaData.ServiceId; - - if (AWSServiceHelper.ServiceRequestParameterMap.TryGetValue(service, out var parameters)) - { - AmazonWebServiceRequest request = requestContext.OriginalRequest; - - foreach (var parameter in parameters) - { - try - { - // for bedrock agent, we only extract one attribute based on the operation. - if (AWSServiceType.IsBedrockAgentService(service)) - { - if (AWSServiceHelper.OperationNameToResourceMap()[AWSServiceHelper.GetAWSOperationName(requestContext)] != parameter) - { - continue; - } - } - - var property = request.GetType().GetProperty(parameter); - if (property != null) - { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) - { - activity.SetTag(attribute, property.GetValue(request)); - } - } - } - catch (Exception) - { - // Guard against any reflection-related exceptions when running in AoT. - // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. - } - } - } + ProcessBeginRequest(executionContext); - if (AWSServiceType.IsDynamoDbService(service)) - { - activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); - } - else if (AWSServiceType.IsSqsService(service)) - { - SqsRequestContextHelper.AddAttributes( - requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); - } - else if (AWSServiceType.IsSnsService(service)) - { - SnsRequestContextHelper.AddAttributes( - requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); - } - else if (AWSServiceType.IsBedrockRuntimeService(service)) - { - activity.SetTag(AWSSemanticConventions.AttributeGenAiSystem, "aws_bedrock"); - } + return await base.InvokeAsync(executionContext).ConfigureAwait(false); } -#if NET - [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( - "Trimming", - "IL2075", - Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] -#endif - private static void AddResponseSpecificInformation(Activity activity, IExecutionContext executionContext) + private static void ProcessBeginRequest(IExecutionContext executionContext) { - var service = executionContext.RequestContext.ServiceMetaData.ServiceId; - var responseContext = executionContext.ResponseContext; - - if (AWSServiceHelper.ServiceResponseParameterMap.TryGetValue(service, out var parameters)) - { - AmazonWebServiceResponse response = responseContext.Response; - - foreach (var parameter in parameters) - { - try - { - // for bedrock agent, extract attribute from object in response. - if (AWSServiceType.IsBedrockAgentService(service)) - { - var operationName = Utils.RemoveSuffix(response.GetType().Name, "Response"); - if (AWSServiceHelper.OperationNameToResourceMap()[operationName] == parameter) - { - AddBedrockAgentResponseAttribute(activity, response, parameter); - } - } - - var property = response.GetType().GetProperty(parameter); - if (property != null) - { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) - { - activity.SetTag(attribute, property.GetValue(response)); - } - } - } - catch (Exception) - { - // Guard against any reflection-related exceptions when running in AoT. - // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. - } - } - } - } - -#if NET - [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( - "Trimming", - "IL2075", - Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] -#endif - private static void AddBedrockAgentResponseAttribute(Activity activity, AmazonWebServiceResponse response, string parameter) - { - var responseObject = response.GetType().GetProperty(Utils.RemoveSuffix(parameter, "Id")); - if (responseObject != null) - { - var attributeObject = responseObject.GetValue(response); - if (attributeObject != null) - { - var property = attributeObject.GetType().GetProperty(parameter); - if (property != null) - { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) - { - activity.SetTag(attribute, property.GetValue(attributeObject)); - } - } - } - } - } - - private static void ProcessEndRequest(IExecutionContext executionContext) - { - var currentActivity = Activity.Current; - - if (currentActivity == null || !currentActivity.Source.Name.StartsWith(TelemetryConstants.TelemetryScopePrefix, StringComparison.Ordinal)) - { - return; - } - - AddResponseSpecificInformation(currentActivity, executionContext); - } - - private void ProcessBeginRequest(IExecutionContext executionContext) - { - if (this.options.SuppressDownstreamInstrumentation) - { - SuppressInstrumentationScope.Enter(); - } - var currentActivity = Activity.Current; // Propagate the current activity if it was created by the AWS SDK @@ -221,7 +51,6 @@ private void ProcessBeginRequest(IExecutionContext executionContext) return; } - AddRequestSpecificInformation(currentActivity, executionContext.RequestContext); AwsPropagator.Inject( new PropagationContext(currentActivity.Context, Baggage.Current), executionContext.RequestContext.Request.Headers, diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs index 71fc82ddb3..61d72da34e 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs @@ -18,6 +18,7 @@ internal static class AWSSemanticConventions public const string AttributeAWSBedrockDataSourceId = "aws.bedrock.data_source.id"; public const string AttributeAWSBedrockGuardrailId = "aws.bedrock.guardrail.id"; public const string AttributeAWSBedrockKnowledgeBaseId = "aws.bedrock.knowledge_base.id"; + public const string AttributeAWSBedrock = "aws_bedrock"; // should be global convention for Gen AI attributes public const string AttributeGenAiModelId = "gen_ai.request.model"; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index 235a656c81..cdb420ad80 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -7,8 +7,8 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; /// -/// Wires into the AWS -/// so it can inject trace headers and add request information to the tags. +/// Wires and into the AWS +/// so they can inject trace headers and add request information to the tags. /// internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer { @@ -34,7 +34,12 @@ public void Customize(Type serviceClientType, RuntimePipeline pipeline) return; } - var propagatingPipelineHandler = new AWSPropagatorPipelineHandler(this.options); + var tracingPipelineHandler = new AWSTracingPipelineHandler(this.options); + var propagatingPipelineHandler = new AWSPropagatorPipelineHandler(); + + // AWSTracingPipelineHandler must execute early in the AWS SDK pipeline + // in order to manipulate outgoing requests objects before they are marshalled (ie serialized). + pipeline.AddHandlerBefore(tracingPipelineHandler); // AWSPropagatorPipelineHandler executes after the AWS SDK has marshalled (ie serialized) // the outgoing request object so that it can work with the request's Headers diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs new file mode 100644 index 0000000000..3ff390ef54 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -0,0 +1,213 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Amazon.Runtime; +using Amazon.Runtime.Internal; +using Amazon.Runtime.Telemetry; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AWS.Implementation; + +/// +/// Adds additional request and response tags depending on the target AWS Service. +/// +/// This must execute early in the AWS SDK pipeline +/// in order to manipulate outgoing requests objects before they are marshalled (ie serialized). +/// +internal sealed class AWSTracingPipelineHandler : PipelineHandler +{ + private readonly AWSClientInstrumentationOptions options; + + public AWSTracingPipelineHandler(AWSClientInstrumentationOptions options) + { + this.options = options; + } + + public override void InvokeSync(IExecutionContext executionContext) + { + var activity = this.ProcessBeginRequest(executionContext); + base.InvokeSync(executionContext); + ProcessEndRequest(activity, executionContext); + } + + public override async Task InvokeAsync(IExecutionContext executionContext) + { + T? ret = null; + + var activity = this.ProcessBeginRequest(executionContext); + ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); + + ProcessEndRequest(activity, executionContext); + + return ret; + } + +#if NET + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif + private static void AddResponseSpecificInformation(Activity activity, IExecutionContext executionContext) + { + var service = executionContext.RequestContext.ServiceMetaData.ServiceId; + var responseContext = executionContext.ResponseContext; + + if (AWSServiceHelper.ServiceResponseParameterMap.TryGetValue(service, out var parameters)) + { + AmazonWebServiceResponse response = responseContext.Response; + + foreach (var parameter in parameters) + { + try + { + // for bedrock agent, extract attribute from object in response. + if (AWSServiceType.IsBedrockAgentService(service)) + { + var operationName = Utils.RemoveSuffix(response.GetType().Name, "Response"); + if (AWSServiceHelper.OperationNameToResourceMap()[operationName] == parameter) + { + AddBedrockAgentResponseAttribute(activity, response, parameter); + } + } + + var property = response.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(response)); + } + } + } + catch (Exception) + { + // Guard against any reflection-related exceptions when running in AoT. + // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + } + } + } + } + +#if NET + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif + private static void AddBedrockAgentResponseAttribute(Activity activity, AmazonWebServiceResponse response, string parameter) + { + var responseObject = response.GetType().GetProperty(Utils.RemoveSuffix(parameter, "Id")); + if (responseObject != null) + { + var attributeObject = responseObject.GetValue(response); + if (attributeObject != null) + { + var property = attributeObject.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(attributeObject)); + } + } + } + } + } + +#if NET + [System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage( + "Trimming", + "IL2075", + Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] +#endif + private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext) + { + var service = requestContext.ServiceMetaData.ServiceId; + + if (AWSServiceHelper.ServiceRequestParameterMap.TryGetValue(service, out var parameters)) + { + AmazonWebServiceRequest request = requestContext.OriginalRequest; + + foreach (var parameter in parameters) + { + try + { + // for bedrock agent, we only extract one attribute based on the operation. + if (AWSServiceType.IsBedrockAgentService(service)) + { + if (AWSServiceHelper.OperationNameToResourceMap()[AWSServiceHelper.GetAWSOperationName(requestContext)] != parameter) + { + continue; + } + } + + var property = request.GetType().GetProperty(parameter); + if (property != null) + { + if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + { + activity.SetTag(attribute, property.GetValue(request)); + } + } + } + catch (Exception) + { + // Guard against any reflection-related exceptions when running in AoT. + // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1543#issuecomment-1907667722. + } + } + } + + if (AWSServiceType.IsDynamoDbService(service)) + { + activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); + } + else if (AWSServiceType.IsSqsService(service)) + { + SqsRequestContextHelper.AddAttributes( + requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); + } + else if (AWSServiceType.IsSnsService(service)) + { + SnsRequestContextHelper.AddAttributes( + requestContext, AWSMessagingUtils.InjectIntoDictionary(new PropagationContext(activity.Context, Baggage.Current))); + } + else if (AWSServiceType.IsBedrockRuntimeService(service)) + { + activity.SetTag(AWSSemanticConventions.AttributeGenAiSystem, AWSSemanticConventions.AttributeAWSBedrock); + } + } + + private static void ProcessEndRequest(Activity? activity, IExecutionContext executionContext) + { + if (activity == null || !activity.IsAllDataRequested) + { + return; + } + + AddResponseSpecificInformation(activity, executionContext); + } + + private Activity? ProcessBeginRequest(IExecutionContext executionContext) + { + if (this.options.SuppressDownstreamInstrumentation) + { + SuppressInstrumentationScope.Enter(); + } + + var currentActivity = Activity.Current; + + if (currentActivity == null + || !currentActivity.Source.Name.StartsWith(TelemetryConstants.TelemetryScopePrefix, StringComparison.Ordinal) + || !currentActivity.IsAllDataRequested) + { + return null; + } + + AddRequestSpecificInformation(currentActivity, executionContext.RequestContext); + return currentActivity; + } +} From cf14a5af35e00c54ca64db40eb48e60c41a41f49 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:32:06 -0700 Subject: [PATCH 1370/1499] [sqlclient] Enable collecting server.* attributes by default (#2249) --- src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md | 8 +++++--- src/OpenTelemetry.Instrumentation.SqlClient/README.md | 6 +++--- .../SqlClientTraceInstrumentationOptions.cs | 7 +++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index f68e4c49d4..b6fa12db57 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -30,11 +30,13 @@ for the same information. Note that `server.address` is only included when the `EnableConnectionLevelAttributes` option is enabled. ([#2229](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2229)) -* When `EnableConnectionLevelAttributes` is enabled, the `server.port` attribute - will now be written as an integer to be compliant with the - [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/server.md). +* **Breaking change**: When `EnableConnectionLevelAttributes` is enabled, the + `server.port` attribute will now be written as an integer to be compliant with + the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/server.md). Previously, it was written as a string. ([#2233](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2233)) +* The `EnableConnectionLevelAttributes` option is now enabled by default. + ([#2249](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2249)) ## 1.9.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index f5fe916ac3..e1c15c28c7 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -165,13 +165,13 @@ command text will be captured. > [!NOTE] > EnableConnectionLevelAttributes is supported on all runtimes. -By default, `EnabledConnectionLevelAttributes` is disabled. -If `EnabledConnectionLevelAttributes` is enabled, +By default, `EnabledConnectionLevelAttributes` is enabled. +When `EnabledConnectionLevelAttributes` is enabled, the [`DataSource`](https://docs.microsoft.com/dotnet/api/system.data.common.dbconnection.datasource) will be parsed and the server name or IP address will be sent as the `server.address` attribute, the instance name will be sent as the `db.mssql.instance_name` attribute, and the port will be sent as the -`net.peer.port` attribute if it is not 1433 (the default port). +`server.port` attribute if it is not 1433 (the default port). The following example shows how to use `EnableConnectionLevelAttributes`. diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs index 48b69212e9..dd7b38eb0e 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs @@ -81,21 +81,20 @@ internal SqlClientTraceInstrumentationOptions(IConfiguration configuration) /// cref="SqlClientInstrumentation"/> should parse the DataSource on a /// SqlConnection into server name, instance name, and/or port /// connection-level attribute tags. Default value: . + /// langword="true"/>. /// /// /// /// EnableConnectionLevelAttributes is supported on all runtimes. /// /// - /// The default behavior is to set the SqlConnection DataSource as the tag. /// If enabled, SqlConnection DataSource will be parsed and the server name will be sent as the - /// or tag, + /// tag, /// the instance name will be sent as the tag, /// and the port will be sent as the tag if it is not 1433 (the default port). /// /// - public bool EnableConnectionLevelAttributes { get; set; } + public bool EnableConnectionLevelAttributes { get; set; } = true; /// /// Gets or sets an action to enrich an with the From 5bbfbc8e737faf5e46879edbdf2978913792e7ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 28 Oct 2024 18:53:07 +0100 Subject: [PATCH 1371/1499] [repo/Resources] Prepare to .NET9 (#2253) --- .../AWSECSDetector.cs | 12 ++-- .../AWSEKSDetector.cs | 29 ++++---- .../AsyncHelper.cs | 2 +- .../AppServiceResourceDetector.cs | 21 +++--- .../AzureContainerAppsResourceDetector.cs | 2 +- .../AzureVMResourceDetector.cs | 8 +-- .../AzureVmMetadataResponse.cs | 2 + .../ContainerDetector.cs | 35 +++------ .../Utils/EncodingUtils.cs | 5 +- .../GcpResourceDetector.cs | 33 ++++----- .../HostDetector.cs | 24 ++----- .../OperatingSystemDetector.cs | 71 +++++++++---------- .../ProcessRuntimeDetector.cs | 15 ++-- .../ServerCertificateValidationProvider.cs | 3 +- .../FileBlobTests.cs | 2 +- .../AsyncHelperTests.cs | 48 ++++++------- .../ContainerDetectorTests.cs | 36 ++++++---- .../HostDetectorTests.cs | 20 +++--- 18 files changed, 167 insertions(+), 201 deletions(-) diff --git a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs index c992995072..ac43f694ff 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs @@ -63,7 +63,7 @@ internal static List> ExtractMetadataV4ResourceAttr var metadataV4Url = Environment.GetEnvironmentVariable(AWSECSMetadataURLV4Key); if (metadataV4Url == null) { - return new List>(); + return []; } using var httpClientHandler = new HttpClientHandler(); @@ -77,14 +77,14 @@ internal static List> ExtractMetadataV4ResourceAttr || containerArnElement.GetString() is not string containerArn) { AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'ContainerARN' field")); - return new List>(); + return []; } if (!taskResponse.RootElement.TryGetProperty("Cluster", out var clusterArnElement) || clusterArnElement.GetString() is not string clusterArn) { AWSResourcesEventSource.Log.ResourceAttributesExtractException(nameof(AWSECSDetector), new ArgumentException("The ECS Metadata V4 response did not contain the 'Cluster' field")); - return new List>(); + return []; } if (!clusterArn.StartsWith("arn:", StringComparison.Ordinal)) @@ -95,9 +95,9 @@ internal static List> ExtractMetadataV4ResourceAttr var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudResourceId, containerArn), - new KeyValuePair(AWSSemanticConventions.AttributeEcsContainerArn, containerArn), - new KeyValuePair(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn), + new(AWSSemanticConventions.AttributeCloudResourceId, containerArn), + new(AWSSemanticConventions.AttributeEcsContainerArn, containerArn), + new(AWSSemanticConventions.AttributeEcsClusterArn, clusterArn), }; if (taskResponse.RootElement.TryGetProperty("AvailabilityZone", out var availabilityZoneElement) && availabilityZoneElement.ValueKind == JsonValueKind.String) diff --git a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index c26e10571d..adf4a59632 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -27,22 +27,19 @@ public Resource Detect() var credentials = GetEKSCredentials(AWSEKSCredentialPath); using var httpClientHandler = ServerCertificateValidationHandler.Create(AWSEKSCertificatePath, AWSResourcesEventSource.Log); - if (credentials == null || !IsEKSProcess(credentials, httpClientHandler)) - { - return Resource.Empty; - } - - return new Resource(ExtractResourceAttributes( - GetEKSClusterName(credentials, httpClientHandler), - GetEKSContainerId(AWSEKSMetadataFilePath))); + return credentials == null || !IsEKSProcess(credentials, httpClientHandler) + ? Resource.Empty + : new Resource(ExtractResourceAttributes( + GetEKSClusterName(credentials, httpClientHandler), + GetEKSContainerId(AWSEKSMetadataFilePath))); } internal static List> ExtractResourceAttributes(string? clusterName, string? containerId) { var resourceAttributes = new List>() { - new KeyValuePair(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new KeyValuePair(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), + new(AWSSemanticConventions.AttributeCloudProvider, "aws"), + new(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), }; if (!string.IsNullOrEmpty(clusterName)) @@ -86,15 +83,13 @@ internal static List> ExtractResourceAttributes(str { try { - using (var streamReader = ResourceDetectorUtils.GetStreamReader(path)) + using var streamReader = ResourceDetectorUtils.GetStreamReader(path); + while (!streamReader.EndOfStream) { - while (!streamReader.EndOfStream) + var trimmedLine = streamReader.ReadLine()?.Trim(); + if (trimmedLine?.Length > 64) { - var trimmedLine = streamReader.ReadLine()?.Trim(); - if (trimmedLine?.Length > 64) - { - return trimmedLine.Substring(trimmedLine.Length - 64); - } + return trimmedLine.Substring(trimmedLine.Length - 64); } } } diff --git a/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs b/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs index f999beff0e..a75d5579c9 100644 --- a/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs +++ b/src/OpenTelemetry.Resources.AWS/AsyncHelper.cs @@ -8,7 +8,7 @@ namespace OpenTelemetry.Resources.AWS; /// internal static class AsyncHelper { - private static readonly TaskFactory TaskFactory = new TaskFactory( + private static readonly TaskFactory TaskFactory = new( CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, diff --git a/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs index 71b0c03a5c..6163fed898 100644 --- a/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs @@ -22,7 +22,7 @@ internal sealed class AppServiceResourceDetector : IResourceDetector /// public Resource Detect() { - List> attributeList = new(); + List> attributeList = []; try { @@ -61,21 +61,18 @@ public Resource Detect() private static string? GetAzureResourceURI(string websiteSiteName) { - string? websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); - string websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty; + var websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar); + var websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty; #if NET - int idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal); + var idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal); #else - int idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal); + var idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal); #endif - string subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName; + var subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName; - if (string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId)) - { - return null; - } - - return $"/subscriptions/{subscriptionId}/resourceGroups/{websiteResourceGroup}/providers/Microsoft.Web/sites/{websiteSiteName}"; + return string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId) + ? null + : $"/subscriptions/{subscriptionId}/resourceGroups/{websiteResourceGroup}/providers/Microsoft.Web/sites/{websiteSiteName}"; } } diff --git a/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs index 58c11aa2bd..aa04c2b35c 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs @@ -25,7 +25,7 @@ internal sealed class AzureContainerAppsResourceDetector : IResourceDetector /// public Resource Detect() { - List> attributeList = new List>(); + List> attributeList = []; try { var containerAppName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar); diff --git a/src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs b/src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs index 5553488629..3feeee3a99 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs @@ -10,8 +10,8 @@ namespace OpenTelemetry.Resources.Azure; /// internal sealed class AzureVMResourceDetector : IResourceDetector { - internal static readonly IReadOnlyCollection ExpectedAzureAmsFields = new string[] - { + internal static readonly IReadOnlyCollection ExpectedAzureAmsFields = + [ ResourceAttributeConstants.AzureVmScaleSetName, ResourceAttributeConstants.AzureVmSku, ResourceSemanticConventions.AttributeCloudPlatform, @@ -23,8 +23,8 @@ internal sealed class AzureVMResourceDetector : IResourceDetector ResourceSemanticConventions.AttributeHostType, ResourceSemanticConventions.AttributeOsType, ResourceSemanticConventions.AttributeOsVersion, - ResourceSemanticConventions.AttributeServiceInstance, - }; + ResourceSemanticConventions.AttributeServiceInstance + ]; private static Resource? vmResource; diff --git a/src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs b/src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs index 81418c8920..1282298fed 100644 --- a/src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs +++ b/src/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs @@ -80,6 +80,8 @@ internal string GetValueForField(string fieldName) case ResourceAttributeConstants.AzureVmSku: amsValue = this.Sku; break; + default: + break; } amsValue ??= string.Empty; diff --git a/src/OpenTelemetry.Resources.Container/ContainerDetector.cs b/src/OpenTelemetry.Resources.Container/ContainerDetector.cs index 8b00d6776a..0f43e1495f 100644 --- a/src/OpenTelemetry.Resources.Container/ContainerDetector.cs +++ b/src/OpenTelemetry.Resources.Container/ContainerDetector.cs @@ -56,14 +56,7 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) { var containerId = this.ExtractContainerId(path, cgroupVersion); - if (string.IsNullOrEmpty(containerId)) - { - return Resource.Empty; - } - else - { - return new Resource(new List>(1) { new(ContainerSemanticConventions.AttributeContainerId, containerId!) }); - } + return string.IsNullOrEmpty(containerId) ? Resource.Empty : new Resource([new(ContainerSemanticConventions.AttributeContainerId, containerId!)]); } /// @@ -74,24 +67,19 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) private static string? GetIdFromLineV1(string line) { // This cgroup output line should have the container id in it - int lastSlashIndex = line.LastIndexOf('/'); + var lastSlashIndex = line.LastIndexOf('/'); if (lastSlashIndex < 0) { return null; } - string lastSection = line.Substring(lastSlashIndex + 1); - int startIndex = lastSection.LastIndexOf('-'); - int endIndex = lastSection.LastIndexOf('.'); - - string containerId = RemovePrefixAndSuffixIfNeeded(lastSection, startIndex, endIndex); + var lastSection = line.Substring(lastSlashIndex + 1); + var startIndex = lastSection.LastIndexOf('-'); + var endIndex = lastSection.LastIndexOf('.'); - if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId)) - { - return null; - } + var containerId = RemovePrefixAndSuffixIfNeeded(lastSection, startIndex, endIndex); - return containerId; + return string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId) ? null : containerId; } /// @@ -108,12 +96,7 @@ internal Resource BuildResource(string path, ParseMode cgroupVersion) containerId = match.Groups[1].Value; } - if (string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId!)) - { - return null; - } - - return containerId; + return string.IsNullOrEmpty(containerId) || !EncodingUtils.IsValidHexString(containerId!) ? null : containerId; } private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex, int endIndex) @@ -143,7 +126,7 @@ private static string RemovePrefixAndSuffixIfNeeded(string input, int startIndex return null; } - foreach (string line in File.ReadLines(path)) + foreach (var line in File.ReadLines(path)) { string? containerId = null; if (!string.IsNullOrEmpty(line)) diff --git a/src/OpenTelemetry.Resources.Container/Utils/EncodingUtils.cs b/src/OpenTelemetry.Resources.Container/Utils/EncodingUtils.cs index 3ad985bd95..f33ad70126 100644 --- a/src/OpenTelemetry.Resources.Container/Utils/EncodingUtils.cs +++ b/src/OpenTelemetry.Resources.Container/Utils/EncodingUtils.cs @@ -12,9 +12,6 @@ internal class EncodingUtils /// true if valid else false. public static bool IsValidHexString(IEnumerable hexString) { - return hexString.All(currentCharacter => - (currentCharacter >= '0' && currentCharacter <= '9') || - (currentCharacter >= 'a' && currentCharacter <= 'f') || - (currentCharacter >= 'A' && currentCharacter <= 'F')); + return hexString.All(currentCharacter => currentCharacter is (>= '0' and <= '9') or (>= 'a' and <= 'f') or (>= 'A' and <= 'F')); } } diff --git a/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs b/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs index 99de6d8309..f2dd4da02b 100644 --- a/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs +++ b/src/OpenTelemetry.Resources.Gcp/GcpResourceDetector.cs @@ -27,6 +27,7 @@ public Resource Detect() PlatformType.CloudRun => ExtractCloudRunResourceAttributes(platform), PlatformType.Gae => ExtractGaeResourceAttributes(platform), PlatformType.Gce => ExtractGceResourceAttributes(platform), + PlatformType.Unknown => ExtractGceResourceAttributes(platform), _ => ExtractGceResourceAttributes(platform), }; @@ -35,8 +36,8 @@ public Resource Detect() internal static List> ExtractGkeResourceAttributes(Platform platform) { - List> attributeList = new() - { + List> attributeList = + [ new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGkePlatformValue), @@ -44,47 +45,47 @@ internal static List> ExtractGkeResourceAttributes( new(ResourceSemanticConventions.AttributeHostId, platform.GkeDetails.InstanceId), new(ResourceSemanticConventions.AttributeK8sCluster, platform.GkeDetails.ClusterName), new(ResourceSemanticConventions.AttributeK8sNamespace, platform.GkeDetails.NamespaceId), - new(ResourceSemanticConventions.AttributeK8sPod, platform.GkeDetails.HostName), - }; + new(ResourceSemanticConventions.AttributeK8sPod, platform.GkeDetails.HostName) + ]; return attributeList; } internal static List> ExtractCloudRunResourceAttributes(Platform platform) { - List> attributeList = new() - { + List> attributeList = + [ new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), new(ResourceSemanticConventions.AttributeCloudAvailabilityZone, platform.CloudRunDetails.Zone), new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpCloudRunPlatformValue), - new(ResourceSemanticConventions.AttributeCloudRegion, platform.CloudRunDetails.Region), - }; + new(ResourceSemanticConventions.AttributeCloudRegion, platform.CloudRunDetails.Region) + ]; return attributeList; } internal static List> ExtractGaeResourceAttributes(Platform platform) { - List> attributeList = new() - { + List> attributeList = + [ new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), - new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGaePlatformValue), - }; + new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGaePlatformValue) + ]; return attributeList; } internal static List> ExtractGceResourceAttributes(Platform platform) { - List> attributeList = new() - { + List> attributeList = + [ new(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.GcpCloudProviderValue), new(ResourceSemanticConventions.AttributeCloudAccount, platform.ProjectId), new(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.GcpGcePlatformValue), new(ResourceSemanticConventions.AttributeHostId, platform.GceDetails.InstanceId), - new(ResourceSemanticConventions.AttributeCloudAvailabilityZone, platform.GceDetails.Location), - }; + new(ResourceSemanticConventions.AttributeCloudAvailabilityZone, platform.GceDetails.Location) + ]; return attributeList; } diff --git a/src/OpenTelemetry.Resources.Host/HostDetector.cs b/src/OpenTelemetry.Resources.Host/HostDetector.cs index a52e527e5a..1127e2037c 100644 --- a/src/OpenTelemetry.Resources.Host/HostDetector.cs +++ b/src/OpenTelemetry.Resources.Host/HostDetector.cs @@ -113,7 +113,7 @@ public Resource Detect() return null; } - var lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); + var lines = output.Split([Environment.NewLine], StringSplitOptions.None); foreach (var line in lines) { @@ -162,8 +162,8 @@ private static IEnumerable GetFilePaths() var isExited = process.WaitForExit(5000); if (isExited) { - string output = process.StandardOutput.ReadToEnd(); - string error = process.StandardError.ReadToEnd(); + var output = process.StandardOutput.ReadToEnd(); + var error = process.StandardError.ReadToEnd(); if (!string.IsNullOrEmpty(error)) { @@ -215,22 +215,10 @@ private static IEnumerable GetFilePaths() #if NETFRAMEWORK return this.getWindowsMachineId(); #else - if (this.isOsPlatform(OSPlatform.Windows)) - { - return this.getWindowsMachineId(); - } - - if (this.isOsPlatform(OSPlatform.Linux)) - { - return this.GetMachineIdLinux(); - } + return this.isOsPlatform(OSPlatform.Windows) ? this.getWindowsMachineId() : + this.isOsPlatform(OSPlatform.Linux) ? this.GetMachineIdLinux() : + this.isOsPlatform(OSPlatform.OSX) ? ParseMacOsOutput(this.getMacOsMachineId()) : null; - if (this.isOsPlatform(OSPlatform.OSX)) - { - return ParseMacOsOutput(this.getMacOsMachineId()); - } - - return null; #endif } diff --git a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs index 1e018c25fd..8f01fa9f7c 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs +++ b/src/OpenTelemetry.Resources.OperatingSystem/OperatingSystemDetector.cs @@ -17,6 +17,7 @@ namespace OpenTelemetry.Resources.OperatingSystem; internal sealed class OperatingSystemDetector : IResourceDetector { private const string RegistryKey = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion"; +#if NET private const string KernelOsRelease = "/proc/sys/kernel/osrelease"; private static readonly string[] DefaultEtcOsReleasePaths = [ @@ -29,23 +30,26 @@ internal sealed class OperatingSystemDetector : IResourceDetector "/System/Library/CoreServices/SystemVersion.plist", "/System/Library/CoreServices/ServerVersion.plist" ]; +#endif private readonly string? osType; private readonly string? registryKey; +#if NET private readonly string? kernelOsRelease; private readonly string[]? etcOsReleasePaths; private readonly string[]? plistFilePaths; +#endif internal OperatingSystemDetector() - : this( - GetOSType(), - RegistryKey, - KernelOsRelease, - DefaultEtcOsReleasePaths, - DefaultPlistFilePaths) +#if NET + : this(GetOSType(), RegistryKey, KernelOsRelease, DefaultEtcOsReleasePaths, DefaultPlistFilePaths) +#else + : this(GetOSType(), RegistryKey) +#endif { } +#if NET /// /// Initializes a new instance of the class for testing. /// @@ -55,12 +59,22 @@ internal OperatingSystemDetector() /// The string path to the file used to obtain Linux attributes. /// An array of file paths used to retrieve MacOS attributes from plist files. internal OperatingSystemDetector(string? osType, string? registryKey, string? kernelOsRelease, string[]? etcOsReleasePath, string[]? plistFilePaths) +#else + /// + /// Initializes a new instance of the class for testing. + /// + /// The target platform identifier, specifying the operating system type from SemanticConventions. + /// The string path in the Windows Registry to retrieve specific Windows attributes. + internal OperatingSystemDetector(string? osType, string? registryKey) +#endif { this.osType = osType; this.registryKey = registryKey; +#if NET this.kernelOsRelease = kernelOsRelease; this.etcOsReleasePaths = etcOsReleasePath; this.plistFilePaths = plistFilePaths; +#endif } /// @@ -93,6 +107,8 @@ public Resource Detect() this.AddMacOSAttributes(attributes); break; #endif + default: + break; } return new Resource(attributes); @@ -120,22 +136,9 @@ private static void AddAttributeIfNotNullOrEmpty(List> attributes) { try { - string? etcOsReleasePath = this.etcOsReleasePaths!.FirstOrDefault(File.Exists); + var etcOsReleasePath = this.etcOsReleasePaths!.FirstOrDefault(File.Exists); if (string.IsNullOrEmpty(etcOsReleasePath)) { OperatingSystemResourcesEventSource.Log.FailedToFindFile("Failed to find the os-release file"); @@ -187,22 +190,14 @@ private void AddLinuxAttributes(List> attributes) foreach (var line in osReleaseContent) { - ReadOnlySpan lineSpan = line.AsSpan(); + var lineSpan = line.AsSpan(); _ = TryGetFieldValue(lineSpan, "BUILD_ID=", ref buildId) || TryGetFieldValue(lineSpan, "NAME=", ref name) || TryGetFieldValue(lineSpan, "VERSION_ID=", ref version); } - string? buildIdContent = null; - if (buildId.IsEmpty) - { - buildIdContent = File.ReadAllText(this.kernelOsRelease!).Trim(); - } - else - { - buildIdContent = buildId.ToString(); - } + var buildIdContent = buildId.IsEmpty ? File.ReadAllText(this.kernelOsRelease!).Trim() : buildId.ToString(); AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemBuildId, buildIdContent); AddAttributeIfNotNullOrEmpty(attributes, AttributeOperatingSystemName, name.IsEmpty ? "Linux" : name.ToString()); @@ -220,7 +215,7 @@ static bool TryGetFieldValue(ReadOnlySpan line, ReadOnlySpan prefix, return false; } - ReadOnlySpan fieldValue = line.Slice(prefix.Length); + var fieldValue = line.Slice(prefix.Length); // Remove enclosing quotes if present. if (fieldValue.Length >= 2 && @@ -239,14 +234,14 @@ private void AddMacOSAttributes(List> attributes) { try { - string? plistFilePath = this.plistFilePaths!.FirstOrDefault(File.Exists); + var plistFilePath = this.plistFilePaths!.FirstOrDefault(File.Exists); if (string.IsNullOrEmpty(plistFilePath)) { OperatingSystemResourcesEventSource.Log.FailedToFindFile("No suitable plist file found"); return; } - XDocument doc = XDocument.Load(plistFilePath); + var doc = XDocument.Load(plistFilePath); var dict = doc.Root?.Element("dict"); string? buildId = null, name = null, version = null; @@ -262,7 +257,7 @@ private void AddMacOSAttributes(List> attributes) return; } - for (int i = 0; i < keys.Count; i++) + for (var i = 0; i < keys.Count; i++) { switch (keys[i].Value) { @@ -275,6 +270,8 @@ private void AddMacOSAttributes(List> attributes) case "ProductVersion": version = values[i].Value; break; + default: + break; } } } diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeDetector.cs b/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeDetector.cs index feac335fba..c2f43e2f6f 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeDetector.cs +++ b/src/OpenTelemetry.Resources.ProcessRuntime/ProcessRuntimeDetector.cs @@ -22,7 +22,7 @@ public Resource Detect() var frameworkDescription = RuntimeInformation.FrameworkDescription; string netRuntimeName; #if NETFRAMEWORK - string? netFrameworkVersion = GetNetFrameworkVersionFromRegistry(); + var netFrameworkVersion = GetNetFrameworkVersionFromRegistry(); #endif var lastSpace = frameworkDescription.LastIndexOf(' '); @@ -43,8 +43,8 @@ public Resource Detect() #endif } - return new Resource(new List>(3) - { + return new Resource( + [ new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeDescription, frameworkDescription), new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeName, netRuntimeName), #if NETFRAMEWORK @@ -52,7 +52,7 @@ public Resource Detect() #else new(ProcessRuntimeSemanticConventions.AttributeProcessRuntimeVersion, Environment.Version.ToString()), #endif - }); + ]); } #if NETFRAMEWORK @@ -64,12 +64,7 @@ public Resource Detect() using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); using var ndpKey = baseKey.OpenSubKey(subKey); - if (ndpKey?.GetValue("Release") != null) - { - return CheckFor45PlusVersion((int)ndpKey.GetValue("Release")); - } - - return null; + return ndpKey?.GetValue("Release") != null ? CheckFor45PlusVersion((int)ndpKey.GetValue("Release")) : null; } catch { diff --git a/src/Shared/ServerCertificateValidationProvider.cs b/src/Shared/ServerCertificateValidationProvider.cs index 232266ad3b..7b976c2119 100644 --- a/src/Shared/ServerCertificateValidationProvider.cs +++ b/src/Shared/ServerCertificateValidationProvider.cs @@ -77,8 +77,7 @@ private static bool HasCommonCertificate(X509Chain chain, X509Certificate2Collec private bool ValidateCertificate(X509Certificate2? cert, X509Chain? chain, SslPolicyErrors errors) { - var isSslPolicyPassed = errors == SslPolicyErrors.None || - errors == SslPolicyErrors.RemoteCertificateChainErrors; + var isSslPolicyPassed = errors is SslPolicyErrors.None or SslPolicyErrors.RemoteCertificateChainErrors; if (!isSslPolicyPassed) { if ((errors | SslPolicyErrors.RemoteCertificateNotAvailable) == errors) diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs index cde187fcc3..706dae983f 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs @@ -172,6 +172,6 @@ public void FileBlobTests_FailedWrite() var nonExistingPath = Path.Combine("FakePath:/", Path.GetRandomFileName()); FileBlob blob = new FileBlob(nonExistingPath); - Assert.False(blob.TryWrite(Array.Empty())); + Assert.False(blob.TryWrite([])); } } diff --git a/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs b/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs index 1bf9aafd6b..fe0efe2a81 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs +++ b/test/OpenTelemetry.Resources.AWS.Tests/AsyncHelperTests.cs @@ -11,13 +11,13 @@ public class AsyncHelperTests public void RunSyncTaskCompletesSuccessfully() { // Arrange - Func task = async () => + static async Task Task() { - await Task.Delay(100); - }; + await System.Threading.Tasks.Task.Delay(100); + } // Act - var exception = Record.Exception(() => AsyncHelper.RunSync(task)); + var exception = Record.Exception(() => AsyncHelper.RunSync(Task)); // Assert Assert.Null(exception); @@ -27,14 +27,14 @@ public void RunSyncTaskCompletesSuccessfully() public void RunSyncTaskThrowsException() { // Arrange - Func task = async () => + static async Task Task() { - await Task.Delay(100); + await System.Threading.Tasks.Task.Delay(100); throw new InvalidOperationException("Test exception"); - }; + } // Act & Assert - var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + var exception = Assert.Throws(() => AsyncHelper.RunSync(Task)); Assert.Equal("Test exception", exception.Message); } @@ -45,13 +45,13 @@ public void RunSyncTaskCancellationThrowsTaskCanceledException() var cts = new CancellationTokenSource(); cts.Cancel(); - Func task = async () => + async Task Task() { - await Task.Delay(100, cts.Token); - }; + await System.Threading.Tasks.Task.Delay(100, cts.Token); + } // Act & Assert - var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + var exception = Assert.Throws(() => AsyncHelper.RunSync(Task)); Assert.Equal(cts.Token, exception.CancellationToken); } @@ -59,14 +59,14 @@ public void RunSyncTaskCancellationThrowsTaskCanceledException() public void RunSyncTaskWithResultCompletesSuccessfully() { // Arrange - Func> task = async () => + static async Task Task() { - await Task.Delay(100); + await System.Threading.Tasks.Task.Delay(100); return "Completed"; - }; + } // Act - var result = AsyncHelper.RunSync(task); + var result = AsyncHelper.RunSync(Task); // Assert Assert.Equal("Completed", result); @@ -76,14 +76,14 @@ public void RunSyncTaskWithResultCompletesSuccessfully() public void RunSyncTaskWithResultThrowsException() { // Arrange - Func> task = async () => + static async Task Task() { - await Task.Delay(100); + await System.Threading.Tasks.Task.Delay(100); throw new InvalidOperationException("Test exception"); - }; + } // Act & Assert - var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + var exception = Assert.Throws(() => AsyncHelper.RunSync(Task)); Assert.Equal("Test exception", exception.Message); } @@ -94,14 +94,14 @@ public void RunSyncTaskWithResultCancellationThrowsTaskCanceledException() var cts = new CancellationTokenSource(); cts.Cancel(); - Func> task = async () => + async Task Task() { - await Task.Delay(100, cts.Token); + await System.Threading.Tasks.Task.Delay(100, cts.Token); return "Completed"; - }; + } // Act & Assert - var exception = Assert.Throws(() => AsyncHelper.RunSync(task)); + var exception = Assert.Throws(() => AsyncHelper.RunSync(Task)); Assert.Equal(cts.Token, exception.CancellationToken); } } diff --git a/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs b/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs index 1174a24e81..47b43b329b 100644 --- a/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Container.Tests/ContainerDetectorTests.cs @@ -7,75 +7,87 @@ namespace OpenTelemetry.Resources.Container.Tests; public class ContainerDetectorTests { - private readonly List testValidCasesV1 = new() - { + private readonly List testValidCasesV1 = + [ new( name: "cgroupv1 with prefix", line: "13:name=systemd:/podruntime/docker/kubepods/crio-e2cc29debdf85dde404998aa128997a819ff", expectedContainerId: "e2cc29debdf85dde404998aa128997a819ff", cgroupVersion: ContainerDetector.ParseMode.V1), + new( name: "cgroupv1 with suffix", line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23.aaaa", expectedContainerId: "ac679f8a8319c8cf7d38e1adf263bc08d23", cgroupVersion: ContainerDetector.ParseMode.V1), + new( name: "cgroupv1 with prefix and suffix", line: "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d23.stuff", expectedContainerId: "dc679f8a8319c8cf7d38e1adf263bc08d23", cgroupVersion: ContainerDetector.ParseMode.V1), + new( name: "cgroupv1 with container Id", line: "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", expectedContainerId: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", - cgroupVersion: ContainerDetector.ParseMode.V1), - }; + cgroupVersion: ContainerDetector.ParseMode.V1) - private readonly List testValidCasesV2 = new() - { + ]; + + private readonly List testValidCasesV2 = + [ new( name: "cgroupv2 with container Id", line: "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356/hostname", expectedContainerId: "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356", cgroupVersion: ContainerDetector.ParseMode.V2), + new( name: "cgroupv2 with full line", line: "473 456 254:1 /docker/containers/dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", expectedContainerId: "dc64b5743252dbaef6e30521c34d6bbd1620c8ce65bdb7bf9e7143b61bb5b183", cgroupVersion: ContainerDetector.ParseMode.V2), + new( name: "cgroupv2 with minikube containerd mountinfo", line: "1537 1517 8:1 /var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", expectedContainerId: "fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3ff9320f4402ae6", cgroupVersion: ContainerDetector.ParseMode.V2), + new( name: "cgroupv2 with minikube docker mountinfo", line: "2327 2307 8:1 /var/lib/docker/containers/a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19/hostname /etc/hostname rw,relatime - ext4 /dev/sda1 rw", expectedContainerId: "a1551a1d7e1881d6c18d2c9ec462cab6ad3666825f0adb2098e9d5b198fd7e19", cgroupVersion: ContainerDetector.ParseMode.V2), + new( name: "cgroupv2 with minikube docker mountinfo2", line: "929 920 254:1 /docker/volumes/minikube/_data/lib/docker/containers/0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33/hostname /etc/hostname rw,relatime - ext4 /dev/vda1 rw", expectedContainerId: "0eaa6718003210b6520f7e82d14b4c8d4743057a958a503626240f8d1900bc33", cgroupVersion: ContainerDetector.ParseMode.V2), + new( name: "cgroupv2 with podman mountinfo", line: "1096 1088 0:104 /containers/overlay-containers/1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809/userdata/hostname /etc/hostname rw,nosuid,nodev,relatime - tmpfs tmpfs rw,size=813800k,nr_inodes=203450,mode=700,uid=1000,gid=1000", expectedContainerId: "1a2de27e7157106568f7e081e42a8c14858c02bd9df30d6e352b298178b46809", - cgroupVersion: ContainerDetector.ParseMode.V2), - }; + cgroupVersion: ContainerDetector.ParseMode.V2) - private readonly List testInvalidCases = new() - { + ]; + + private readonly List testInvalidCases = + [ new( name: "Invalid cgroupv1 line", line: "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz", cgroupVersion: ContainerDetector.ParseMode.V1), + new( name: "Invalid hex cgroupv2 line (contains a z)", line: "13:name=systemd:/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/fb5916a02feca96bdeecd8e062df9e5e51d6617c8214b5e1f3fz9320f4402ae6/hostname", - cgroupVersion: ContainerDetector.ParseMode.V2), - }; + cgroupVersion: ContainerDetector.ParseMode.V2) + + ]; [Fact] public void TestValidContainer() diff --git a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs index baf15769ff..d6c9ea9add 100644 --- a/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs +++ b/test/OpenTelemetry.Resources.Host.Tests/HostDetectorTests.cs @@ -40,8 +40,8 @@ public class HostDetectorTests }"; #if NET - private static readonly IEnumerable ETCMACHINEID = new[] { "Samples/etc_machineid" }; - private static readonly IEnumerable ETCVARDBUSMACHINEID = new[] { "Samples/etc_var_dbus_machineid" }; + private static readonly IEnumerable ETCMACHINEID = ["Samples/etc_machineid"]; + private static readonly IEnumerable ETCVARDBUSMACHINEID = ["Samples/etc_var_dbus_machineid"]; #endif [Fact] @@ -63,7 +63,7 @@ public void TestHostMachineIdLinux() { var combos = new[] { - (Enumerable.Empty(), null), + ([], null), (ETCMACHINEID, "etc_machineid"), (ETCVARDBUSMACHINEID, "etc_var_dbus_machineid"), (Enumerable.Concat(ETCMACHINEID, ETCVARDBUSMACHINEID), "etc_machineid"), @@ -95,7 +95,7 @@ public void TestHostMachineIdMacOs() { var detector = new HostDetector( osPlatform => osPlatform == OSPlatform.OSX, - () => Enumerable.Empty(), + () => [], () => MacOSMachineIdOutput, () => throw new Exception("should not be called")); var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); @@ -116,9 +116,9 @@ public void TestParseMacOsOutput() public void TestHostMachineIdWindows() { #if NET - var detector = new HostDetector(osPlatform => osPlatform == OSPlatform.Windows, () => Enumerable.Empty(), () => throw new Exception("should not be called"), () => "windows-machine-id"); + var detector = new HostDetector(osPlatform => osPlatform == OSPlatform.Windows, () => [], () => throw new Exception("should not be called"), () => "windows-machine-id"); #else - var detector = new HostDetector(() => Enumerable.Empty(), () => throw new Exception("should not be called"), () => "windows-machine-id"); + var detector = new HostDetector(() => [], () => throw new Exception("should not be called"), () => "windows-machine-id"); #endif var resource = ResourceBuilder.CreateEmpty().AddDetector(detector).Build(); @@ -131,14 +131,14 @@ public void TestHostMachineIdWindows() [Fact] public void TestPlatformSpecificMethodInvocation() { - bool linuxMethodCalled = false; - bool macOsMethodCalled = false; - bool windowsMethodCalled = false; + var linuxMethodCalled = false; + var macOsMethodCalled = false; + var windowsMethodCalled = false; var detector = new HostDetector( () => { linuxMethodCalled = true; - return Array.Empty(); + return []; }, () => { From b9553c39efb3fea3047188c54b7bc2018d3b1fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 28 Oct 2024 19:02:49 +0100 Subject: [PATCH 1372/1499] [redis] Prepare to .NET9 (#2252) --- .../RedisProfilerEntryToActivityConverter.cs | 19 +++++++------------ ...kExchangeRedisConnectionInstrumentation.cs | 10 +++++----- .../StackExchangeRedisInstrumentation.cs | 2 +- src/Shared/PropertyFetcher.AOT.cs | 2 +- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs index 5b3a338383..a46574f451 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/Implementation/RedisProfilerEntryToActivityConverter.cs @@ -18,8 +18,8 @@ internal static class RedisProfilerEntryToActivityConverter { private static readonly Lazy> MessageDataGetter = new(() => { - Type profiledCommandType = Type.GetType("StackExchange.Redis.Profiling.ProfiledCommand, StackExchange.Redis", throwOnError: true)!; - Type scriptMessageType = Type.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage, StackExchange.Redis", throwOnError: true)!; + var profiledCommandType = Type.GetType("StackExchange.Redis.Profiling.ProfiledCommand, StackExchange.Redis", throwOnError: true)!; + var scriptMessageType = Type.GetType("StackExchange.Redis.RedisDatabase+ScriptEvalMessage, StackExchange.Redis", throwOnError: true)!; var messageDelegate = CreateFieldGetter(profiledCommandType, "Message", BindingFlags.NonPublic | BindingFlags.Instance); var scriptDelegate = CreateFieldGetter(scriptMessageType, "script", BindingFlags.NonPublic | BindingFlags.Instance); @@ -49,12 +49,7 @@ internal static class RedisProfilerEntryToActivityConverter script = scriptDelegate?.Invoke(message); } - if (GetCommandAndKey(commandAndKeyFetcher, message, out var value)) - { - return (value, script); - } - - return (null, script); + return GetCommandAndKey(commandAndKeyFetcher, message, out var value) ? (value, script) : (null, script); #if NET [DynamicDependency("CommandAndKey", "StackExchange.Redis.Message", "StackExchange.Redis")] @@ -199,19 +194,19 @@ public static void DrainSession(Activity? parentActivity, IEnumerable> CreationTags = new[] - { - new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis"), - }; + internal static readonly IEnumerable> CreationTags = + [ + new KeyValuePair(SemanticConventions.AttributeDbSystem, "redis") + ]; internal readonly ConcurrentDictionary<(ActivityTraceId TraceId, ActivitySpanId SpanId), (Activity Activity, ProfilingSession Session)> Cache = new(); @@ -119,7 +119,7 @@ internal void Flush() continue; } - ProfilingSession session = entry.Value.Session; + var session = entry.Value.Session; RedisProfilerEntryToActivityConverter.DrainSession(parent, session.FinishProfiling(), this.options); this.Cache.TryRemove((entry.Key.TraceId, entry.Key.SpanId), out _); } diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs index 4436a42df4..41e6671ace 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisInstrumentation.cs @@ -20,7 +20,7 @@ internal StackExchangeRedisInstrumentation( this.options = options; } - internal List InstrumentedConnections { get; } = new(); + internal List InstrumentedConnections { get; } = []; /// /// Adds an to the instrumentation. diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index 80bf4c9188..cb8ecb1b8b 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -142,7 +142,7 @@ private abstract class PropertyFetch return (PropertyFetch?)typeof(PropertyFetch) .GetMethod(nameof(CreateInstantiated), BindingFlags.NonPublic | BindingFlags.Static)! .MakeGenericMethod(declaringType) // This is validated in the earlier call chain to be a reference type. - .Invoke(null, new object[] { propertyInfo })!; + .Invoke(null, [propertyInfo])!; } } } From c09a3318cb79b2b8382eaffb53b9c90c864e2560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 28 Oct 2024 19:10:13 +0100 Subject: [PATCH 1373/1499] [Exporter.Geneva] benchmarks nullable (#2254) --- .../OtlpProtobufMetricExporter.cs | 2 +- .../Exporter/MetricExporterBenchmarks.cs | 138 +++++++++--------- .../Exporter/TLDTraceExporterBenchmarks.cs | 18 +-- .../Exporter/TraceExporterBenchmarks.cs | 4 +- ...elemetry.Exporter.Geneva.Benchmarks.csproj | 1 - 5 files changed, 81 insertions(+), 82 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index 174e5ded5c..835c6cac1d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -18,7 +18,7 @@ internal sealed class OtlpProtobufMetricExporter : IDisposable public OtlpProtobufMetricExporter( Func getResource, - ConnectionStringBuilder connectionStringBuilder, + ConnectionStringBuilder? connectionStringBuilder, IReadOnlyDictionary? prepopulatedMetricDimensions) { Debug.Assert(getResource != null, "getResource was null"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs index 7c190a8005..0e45b72a37 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs @@ -51,16 +51,16 @@ namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class MetricExporterBenchmarks { - private Metric counterMetricWith3Dimensions; - private Metric counterMetricWith4Dimensions; + private Metric? counterMetricWith3Dimensions; + private Metric? counterMetricWith4Dimensions; private MetricPoint counterMetricPointWith3Dimensions; private MetricPoint counterMetricPointWith4Dimensions; private MetricData counterMetricDataWith3Dimensions; private MetricData counterMetricDataWith4Dimensions; private Batch counterMetricBatchWith3Dimensions; private Batch counterMetricBatchWith4Dimensions; - private Metric histogramMetricWith3Dimensions; - private Metric histogramMetricWith4Dimensions; + private Metric? histogramMetricWith3Dimensions; + private Metric? histogramMetricWith4Dimensions; private MetricPoint histogramMetricPointWith3Dimensions; private MetricPoint histogramMetricPointWith4Dimensions; private ulong histogramSumWith3Dimensions; @@ -77,23 +77,23 @@ public class MetricExporterBenchmarks private Meter meterWithListener = new Meter("MeterWithListener", "0.0.1"); private Meter meterWithDummyReader = new Meter("MeterWithDummyReader", "0.0.1"); private Meter meterWithGenevaMetricExporter = new Meter("MeterWithGenevaMetricExporter", "0.0.1"); - private Counter counterWithNoListener; - private Counter counterWithListener; - private Counter counterWithDummyReader; - private Counter counterWithGenevaMetricExporter; - private MeterListener listener; - private MeterProvider meterProviderWithDummyReader; - private MeterProvider meterProviderWithGenevaMetricExporter; - private MeterProvider meterProviderForCounterBatchWith3Dimensions; - private MeterProvider meterProviderForCounterBatchWith4Dimensions; - private MeterProvider meterProviderForHistogramBatchWith3Dimensions; - private MeterProvider meterProviderForHistogramBatchWith4Dimensions; - private TlvMetricExporter tlvMetricsExporter; - private OtlpProtobufMetricExporter otlpProtobufMetricExporter; - private OtlpProtobufSerializer otlpProtobufSerializer; - private Resource resource; - private byte[] buffer; - private ThreadLocal random = new ThreadLocal(() => new Random()); + private Counter? counterWithNoListener; + private Counter? counterWithListener; + private Counter? counterWithDummyReader; + private Counter? counterWithGenevaMetricExporter; + private MeterListener? listener; + private MeterProvider? meterProviderWithDummyReader; + private MeterProvider? meterProviderWithGenevaMetricExporter; + private MeterProvider? meterProviderForCounterBatchWith3Dimensions; + private MeterProvider? meterProviderForCounterBatchWith4Dimensions; + private MeterProvider? meterProviderForHistogramBatchWith3Dimensions; + private MeterProvider? meterProviderForHistogramBatchWith4Dimensions; + private TlvMetricExporter? tlvMetricsExporter; + private OtlpProtobufMetricExporter? otlpProtobufMetricExporter; + private OtlpProtobufSerializer? otlpProtobufSerializer; + private Resource? resource; + private byte[]? buffer; + private ThreadLocal random = new(() => new Random()); private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported private static readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; @@ -192,7 +192,7 @@ private MetricPoint GenerateCounterMetricItemWith3Dimensions(out MetricData metr counter.Add( 100, - new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]), new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); @@ -226,7 +226,7 @@ private MetricPoint GenerateCounterMetricItemWith4Dimensions(out MetricData metr var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -264,7 +264,7 @@ private Batch GenerateCounterBatchWith3Dimensions() counter.Add( 100, - new("DimName1", dimensionValues[this.random.Value.Next(0, 10)]), + new("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]), new("DimName2", dimensionValues[this.random.Value.Next(0, 10)]), new("DimName3", dimensionValues[this.random.Value.Next(0, 10)])); @@ -290,7 +290,7 @@ private Batch GenerateCounterBatchWith4Dimensions() var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -318,9 +318,9 @@ private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out ulong sum, ou .AddReader(inMemoryReader) .Build(); - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); for (int i = 0; i < 1000; i++) { @@ -363,7 +363,7 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out ulong sum, ou var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -408,9 +408,9 @@ private Batch GenerateHistogramBatchWith3Dimensions() .AddReader(batchGeneratorReader) .Build(); - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); for (int i = 0; i < 1000; i++) { @@ -439,7 +439,7 @@ private Batch GenerateHistogramBatchWith4Dimensions() var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -475,9 +475,9 @@ public void Cleanup() [Benchmark] public void InstrumentWithNoListener3Dimensions() { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); this.counterWithNoListener?.Add(100, tag1, tag2, tag3); } @@ -486,7 +486,7 @@ public void InstrumentWithNoListener4Dimensions() { var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -499,9 +499,9 @@ public void InstrumentWithNoListener4Dimensions() [Benchmark] public void InstrumentWithWithListener3Dimensions() { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); this.counterWithListener?.Add(100, tag1, tag2, tag3); } @@ -510,7 +510,7 @@ public void InstrumentWithWithListener4Dimensions() { var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -523,9 +523,9 @@ public void InstrumentWithWithListener4Dimensions() [Benchmark] public void InstrumentWithWithDummyReader3Dimensions() { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); this.counterWithDummyReader?.Add(100, tag1, tag2, tag3); } @@ -534,7 +534,7 @@ public void InstrumentWithWithDummyReader4Dimensions() { var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -547,9 +547,9 @@ public void InstrumentWithWithDummyReader4Dimensions() [Benchmark] public void InstrumentWithWithGenevaCounterMetricExporter3Dimensions() { - var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value.Next(0, 10)]); - var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); - var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); + var tag1 = new KeyValuePair("DimName1", dimensionValues[this.random.Value!.Next(0, 10)]); + var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); + var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); this.counterWithGenevaMetricExporter?.Add(100, tag1, tag2, tag3); } @@ -558,7 +558,7 @@ public void InstrumentWithWithGenevaCounterMetricExporter4Dimensions() { var tags = new TagList { - { "DimName1", dimensionValues[this.random.Value.Next(0, 2)] }, + { "DimName1", dimensionValues[this.random.Value!.Next(0, 2)] }, { "DimName2", dimensionValues[this.random.Value.Next(0, 5)] }, { "DimName3", dimensionValues[this.random.Value.Next(0, 10)] }, { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, @@ -573,9 +573,9 @@ public void SerializeCounterMetricItemWith3Dimensions() { this.counterMetricPointWith3Dimensions.TryGetExemplars(out var exemplars); - this.tlvMetricsExporter.SerializeMetricWithTLV( + this.tlvMetricsExporter!.SerializeMetricWithTLV( MetricEventType.ULongMetric, - this.counterMetricWith3Dimensions.Name, + this.counterMetricWith3Dimensions!.Name, this.counterMetricPointWith3Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith3Dimensions.Tags, this.counterMetricDataWith3Dimensions, @@ -589,9 +589,9 @@ public void SerializeCounterMetricItemWith3Dimensions() public void SerializeCounterMetricItemWith4Dimensions() { this.counterMetricPointWith4Dimensions.TryGetExemplars(out var exemplars); - this.tlvMetricsExporter.SerializeMetricWithTLV( + this.tlvMetricsExporter!.SerializeMetricWithTLV( MetricEventType.ULongMetric, - this.counterMetricWith4Dimensions.Name, + this.counterMetricWith4Dimensions!.Name, this.counterMetricPointWith4Dimensions.EndTime.ToFileTime(), this.counterMetricPointWith4Dimensions.Tags, this.counterMetricDataWith4Dimensions, @@ -604,21 +604,21 @@ public void SerializeCounterMetricItemWith4Dimensions() [Benchmark] public void ExportCounterMetricItemWith3Dimensions() { - this.tlvMetricsExporter.Export(this.counterMetricBatchWith3Dimensions); + this.tlvMetricsExporter!.Export(this.counterMetricBatchWith3Dimensions); } [Benchmark] public void ExportCounterMetricItemWith4Dimensions() { - this.tlvMetricsExporter.Export(this.counterMetricBatchWith4Dimensions); + this.tlvMetricsExporter!.Export(this.counterMetricBatchWith4Dimensions); } [Benchmark] public void SerializeHistogramMetricItemWith3Dimensions() { this.histogramMetricPointWith3Dimensions.TryGetExemplars(out var exemplars); - this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( - this.histogramMetricWith3Dimensions.Name, + this.tlvMetricsExporter!.SerializeHistogramMetricWithTLV( + this.histogramMetricWith3Dimensions!.Name, this.histogramMetricPointWith3Dimensions.EndTime.ToFileTime(), this.histogramMetricPointWith3Dimensions.Tags, this.histogramMetricPointWith3Dimensions.GetHistogramBuckets(), @@ -636,8 +636,8 @@ public void SerializeHistogramMetricItemWith3Dimensions() public void SerializeHistogramMetricItemWith4Dimensions() { this.histogramMetricPointWith4Dimensions.TryGetExemplars(out var exemplars); - this.tlvMetricsExporter.SerializeHistogramMetricWithTLV( - this.histogramMetricWith4Dimensions.Name, + this.tlvMetricsExporter!.SerializeHistogramMetricWithTLV( + this.histogramMetricWith4Dimensions!.Name, this.histogramMetricPointWith4Dimensions.EndTime.ToFileTime(), this.histogramMetricPointWith4Dimensions.Tags, this.histogramMetricPointWith4Dimensions.GetHistogramBuckets(), @@ -654,61 +654,61 @@ public void SerializeHistogramMetricItemWith4Dimensions() [Benchmark] public void ExportHistogramMetricItemWith3Dimensions() { - this.tlvMetricsExporter.Export(this.histogramMetricBatchWith3Dimensions); + this.tlvMetricsExporter!.Export(this.histogramMetricBatchWith3Dimensions); } [Benchmark] public void ExportHistogramMetricItemWith4Dimensions() { - this.tlvMetricsExporter.Export(this.histogramMetricBatchWith4Dimensions); + this.tlvMetricsExporter!.Export(this.histogramMetricBatchWith4Dimensions); } [Benchmark] public void SerializeCounterMetricItemWith3Dimensions_Otlp() { - this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.counterMetricBatchWith3Dimensions); + this.otlpProtobufSerializer!.SerializeAndSendMetrics(this.buffer!, this.resource!, this.counterMetricBatchWith3Dimensions); } [Benchmark] public void SerializeCounterMetricItemWith4Dimensions_Otlp() { - this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.counterMetricBatchWith4Dimensions); + this.otlpProtobufSerializer!.SerializeAndSendMetrics(this.buffer!, this.resource!, this.counterMetricBatchWith4Dimensions); } [Benchmark] public void ExportCounterMetricItemWith3Dimensions_Otlp() { - this.otlpProtobufMetricExporter.Export(this.counterMetricBatchWith3Dimensions); + this.otlpProtobufMetricExporter!.Export(this.counterMetricBatchWith3Dimensions); } [Benchmark] public void ExportCounterMetricItemWith4Dimensions_Otlp() { - this.otlpProtobufMetricExporter.Export(this.counterMetricBatchWith4Dimensions); + this.otlpProtobufMetricExporter!.Export(this.counterMetricBatchWith4Dimensions); } [Benchmark] public void SerializeHistogramMetricItemWith3Dimensions_Otlp() { - this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.histogramMetricBatchWith3Dimensions); + this.otlpProtobufSerializer!.SerializeAndSendMetrics(this.buffer!, this.resource!, this.histogramMetricBatchWith3Dimensions); } [Benchmark] public void SerializeHistogramMetricItemWith4Dimensions_Otlp() { - this.otlpProtobufSerializer.SerializeAndSendMetrics(this.buffer, this.resource, this.histogramMetricBatchWith4Dimensions); + this.otlpProtobufSerializer!.SerializeAndSendMetrics(this.buffer!, this.resource!, this.histogramMetricBatchWith4Dimensions); } [Benchmark] public void ExportHistogramMetricItemWith3Dimensions_Otlp() { - this.otlpProtobufMetricExporter.Export(this.histogramMetricBatchWith3Dimensions); + this.otlpProtobufMetricExporter!.Export(this.histogramMetricBatchWith3Dimensions); } [Benchmark] public void ExportHistogramMetricItemWith4Dimensions_Otlp() { - this.otlpProtobufMetricExporter.Export(this.histogramMetricBatchWith4Dimensions); + this.otlpProtobufMetricExporter!.Export(this.histogramMetricBatchWith4Dimensions); } private class DummyReader : BaseExportingMetricReader diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs index 2175a2a250..479026a277 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs @@ -28,7 +28,7 @@ namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] public class TLDTraceExporterBenchmarks { - private readonly Activity activity; + private readonly Activity? activity; private readonly Batch batch; private readonly MsgPackTraceExporter msgPackExporter; private readonly TldTraceExporter tldExporter; @@ -52,10 +52,10 @@ public TLDTraceExporterBenchmarks() using (var testActivity = this.activitySource.StartActivity("Benchmark")) { - this.activity = testActivity; - this.activity?.SetTag("tagString", "value"); - this.activity?.SetTag("tagInt", 100); - this.activity?.SetStatus(Status.Error); + this.activity = testActivity!; + this.activity.SetTag("tagString", "value"); + this.activity.SetTag("tagInt", 100); + this.activity.SetStatus(Status.Error); } this.msgPackExporter = new MsgPackTraceExporter(new GenevaExporterOptions @@ -84,13 +84,13 @@ public TLDTraceExporterBenchmarks() [Benchmark] public void MsgPack_SerializeActivity() { - this.msgPackExporter.SerializeActivity(this.activity); + this.msgPackExporter.SerializeActivity(this.activity!); } [Benchmark] public void TLD_SerializeActivity() { - this.tldExporter.SerializeActivity(this.activity); + this.tldExporter.SerializeActivity(this.activity!); } [Benchmark] @@ -108,7 +108,7 @@ public void TLD_ExportActivity() [GlobalCleanup] public void Cleanup() { - this.activity.Dispose(); + this.activity?.Dispose(); this.batch.Dispose(); this.activitySource.Dispose(); this.msgPackExporter.Dispose(); @@ -124,7 +124,7 @@ private Batch CreateBatch() .AddProcessor(new SimpleActivityExportProcessor(batchGeneratorExporter)) .Build(); - using (var activity = this.activitySource.StartActivity("Benchmark")) + using (var activity = this.activitySource.StartActivity("Benchmark")!) { activity.SetTag("tagString", "value"); activity.SetTag("tagInt", 100); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs index 223cbd111c..cfec940e3f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs @@ -51,7 +51,7 @@ public TraceExporterBenchmarks() using (var testActivity = this.activitySource.StartActivity("Benchmark")) { - this.activity = testActivity; + this.activity = testActivity!; this.activity.SetTag("tagString", "value"); this.activity.SetTag("tagInt", 100); this.activity.SetStatus(Status.Error); @@ -125,7 +125,7 @@ private Batch CreateBatch() .AddProcessor(new SimpleActivityExportProcessor(batchGeneratorExporter)) .Build(); - using (var activity = this.activitySource.StartActivity("Benchmark")) + using (var activity = this.activitySource.StartActivity("Benchmark")!) { activity.SetTag("tagString", "value"); activity.SetTag("tagInt", 100); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj index 6a758c273f..3a6871c3b7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj @@ -8,7 +8,6 @@ $(TargetFrameworks);net48;net472;net471;net47;net462 Exe $(NoWarn);SA1201;SA1202;SA1204;SA1311;SA1123 - disable From 3f5d91ca98126a027ad83455c4a5baab0bb1a295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 28 Oct 2024 19:20:45 +0100 Subject: [PATCH 1374/1499] [Exporter.Geneva] stress nullable (#2255) --- test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs | 2 +- .../OpenTelemetry.Exporter.Geneva.Stress.csproj | 1 - test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index 675b26b9b1..c6cdb17609 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -33,7 +33,7 @@ public void Start() this.serverSocket.Bind(this.endpoint); this.serverSocket.Listen(20); - Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs args) => + Console.CancelKeyPress += (object? sender, ConsoleCancelEventArgs args) => { Console.WriteLine("Program is terminating."); this.serverSocket.Close(); diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index e307744bc8..435acd8b5d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -6,7 +6,6 @@ $(TargetFrameworks);net48;net472;net471;net47;net462 Exe $(NoWarn);SA1308;SA1201 - disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index 1a6c97297d..71877c8c94 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -39,14 +39,14 @@ private class WindowsOptions private class LinuxOptions { [Option('p', "path", Default = "/var/run/default_fluent.socket", HelpText = "Specify a path for Unix domain socket.")] - public string Path { get; set; } + public string? Path { get; set; } } [Verb("server", HelpText = "Start a dummy server on Linux.")] private class ServerOptions { [Option('p', "path", HelpText = "Specify a path for Unix domain socket.", Required = true)] - public string Path { get; set; } + public string? Path { get; set; } } [Verb("ExporterCreation", HelpText = "Validate exporter dispose behavior")] @@ -78,12 +78,12 @@ private static int RunExporterCreation() private static int RunLinux(LinuxOptions options) { - return EntryPoint(() => InitTracesOnLinux(options.Path), RunTraces); + return EntryPoint(() => InitTracesOnLinux(options.Path!), RunTraces); } private static int RunServer(ServerOptions options) { - var server = new DummyServer(options.Path); + var server = new DummyServer(options.Path!); server.Start(); return 0; } From fdedd5baf6ed03624fee7d43146e754e82733bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 28 Oct 2024 19:33:37 +0100 Subject: [PATCH 1375/1499] [Instrumentation.Wcf] Add .NET6 as target framework (#2243) Co-authored-by: Mikel Blanchard --- .../CHANGELOG.md | 4 ++++ .../AsyncResultWithTelemetryState.cs | 2 +- .../ClientChannelInstrumentation.cs | 4 ++-- .../HttpRequestMessagePropertyWrapper.cs | 24 ++++++++++--------- .../InstrumentedDuplexChannel.cs | 15 ++++++++---- .../InstrumentedRequestChannel.cs | 13 +++++++--- .../RequestTelemetryStateTracker.cs | 14 +++++++---- .../TelemetryPropagationWriter.cs | 3 +-- .../WcfInstrumentationActivitySource.cs | 2 +- .../OpenTelemetry.Instrumentation.Wcf.csproj | 5 ++-- ...Telemetry.Instrumentation.Wcf.Tests.csproj | 2 -- 11 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index e3080ccd88..745314baa5 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +* Add target for `net6.0` to ensure that non-vulnerable transient + dependencies are referenced by default for .NET6+. + ([#2243](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2243)) + ## 1.0.0-rc.17 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs index 7d50404090..cf26181c7c 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AsyncResultWithTelemetryState.cs @@ -15,7 +15,7 @@ public AsyncResultWithTelemetryState(IAsyncResult inner, RequestTelemetryState t public RequestTelemetryState TelemetryState { get; } - object IAsyncResult.AsyncState => this.Inner.AsyncState; + object? IAsyncResult.AsyncState => this.Inner.AsyncState; WaitHandle IAsyncResult.AsyncWaitHandle => this.Inner.AsyncWaitHandle; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index ecba99793d..6fca3efada 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -82,7 +82,7 @@ public static RequestTelemetryState BeforeSendRequest(Message request, Uri? remo }; } - public static void AfterRequestCompleted(Message? reply, RequestTelemetryState state) + public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? state) { Guard.ThrowIfNull(state); @@ -128,7 +128,7 @@ private static ActionMetadata GetActionMetadata(Message request, string action) if (request.Properties.TryGetValue(TelemetryContextMessageProperty.Name, out object telemetryContextProperty)) { var actionMappings = (telemetryContextProperty as TelemetryContextMessageProperty)?.ActionMappings; - if (actionMappings != null && actionMappings.TryGetValue(action, out ActionMetadata metadata)) + if (actionMappings != null && actionMappings.TryGetValue(action, out var metadata)) { actionMetadata = metadata; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs index 9864302715..26e62a054a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs @@ -32,7 +32,7 @@ public static string Name public static object CreateNew() { AssertHttpEnabled(); - return Activator.CreateInstance(ReflectedValues!.Type); + return Activator.CreateInstance(ReflectedValues!.Type)!; } public static WebHeaderCollection GetHeaders(object httpRequestMessageProperty) @@ -49,23 +49,25 @@ public static WebHeaderCollection GetHeaders(object httpRequestMessageProperty) { type = Type.GetType( "System.ServiceModel.Channels.HttpRequestMessageProperty, System.ServiceModel, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", - true); + true)!; - var headersProp = type.GetProperty("Headers", BindingFlags.Public | BindingFlags.Instance, null, typeof(WebHeaderCollection), Array.Empty(), null); - if (headersProp == null) - { - throw new NotSupportedException("HttpRequestMessageProperty.Headers property not found"); - } + var constructor = type.GetConstructor(Type.EmptyTypes) + ?? throw new NotSupportedException("HttpRequestMessageProperty public parameterless constructor was not found"); + + var headersProp = type.GetProperty("Headers", BindingFlags.Public | BindingFlags.Instance, null, typeof(WebHeaderCollection), Array.Empty(), null) + ?? throw new NotSupportedException("HttpRequestMessageProperty.Headers property not found"); + + var nameProp = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static, null, typeof(string), Array.Empty(), null) + ?? throw new NotSupportedException("HttpRequestMessageProperty.Name property not found"); - var nameProp = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static, null, typeof(string), Array.Empty(), null); - if (nameProp == null) + if (nameProp.GetValue(null) is not string name) { - throw new NotSupportedException("HttpRequestMessageProperty.Name property not found"); + throw new NotSupportedException("HttpRequestMessageProperty.Name property was null"); } return new ReflectedInfo( type: type, - name: (string)nameProp.GetValue(null), + name: name, headersFetcher: new PropertyFetcher("Headers")); } catch (Exception ex) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs index ef58ab4ef8..d58157d836 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs @@ -178,20 +178,27 @@ private IAsyncResult SendInternal(Message message, TimeSpan timeout, Func executeSend) { RequestTelemetryState? telemetryState = null; - ContextCallback executeInChildContext = _ => + + void ExecuteInChildContext(object? unused) { telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, this.RemoteAddress?.Uri); RequestTelemetryStateTracker.PushTelemetryState(message, telemetryState, timeout, OnTelemetryStateTimedOut); executeSend(telemetryState); - }; + } + + var executionContext = ExecutionContext.Capture(); + if (executionContext == null) + { + throw new InvalidOperationException("Cannot fetch execution context"); + } try { - ExecutionContext.Run(ExecutionContext.Capture(), executeInChildContext, null); + ExecutionContext.Run(executionContext, ExecuteInChildContext, null); } catch (Exception) { - ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState!); + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); throw; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs index 7c6caa3fce..30c245cc91 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs @@ -99,14 +99,21 @@ Message IRequestChannel.EndRequest(IAsyncResult result) private IAsyncResult InternalBeginRequest(Message message, Func beginRequestDelegate, AsyncCallback callback, object? state) { IAsyncResult? result = null; - ContextCallback executeInChildContext = _ => + + void ExecuteInChildContext(object? unused) { var telemetryState = ClientChannelInstrumentation.BeforeSendRequest(message, ((IRequestChannel)this).RemoteAddress?.Uri); var asyncCallback = AsyncResultWithTelemetryState.GetAsyncCallback(callback, telemetryState); result = new AsyncResultWithTelemetryState(beginRequestDelegate(asyncCallback, state), telemetryState); - }; + } + + var executionContext = ExecutionContext.Capture(); + if (executionContext == null) + { + throw new InvalidOperationException("Cannot fetch execution context"); + } - ExecutionContext.Run(ExecutionContext.Capture(), executeInChildContext, null); + ExecutionContext.Run(executionContext, ExecuteInChildContext, null); return result!; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs index 874d7b3d36..282f0c91e0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs @@ -9,8 +9,8 @@ internal static class RequestTelemetryStateTracker { private static readonly Dictionary OutstandingRequestStates = new Dictionary(); private static readonly SortedSet TimeoutQueue = new SortedSet(); - private static readonly object Sync = new object(); - private static readonly Timer Timer = new Timer(OnTimer); + private static readonly object Sync = new(); + private static readonly Timer Timer = new(OnTimer); private static long currentTimerDueAt = Timeout.Infinite; public static void PushTelemetryState(Message request, RequestTelemetryState telemetryState, TimeSpan timeout, Action timeoutCallback) @@ -50,7 +50,7 @@ public static void PushTelemetryState(Message request, RequestTelemetryState tel } } - private static void OnTimer(object state) + private static void OnTimer(object? state) { List>? timedOutEntries = null; lock (Sync) @@ -139,9 +139,13 @@ public EntryTimeoutProperties(string messageId, long expiresAt, Action - $(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + net6.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry instrumentation for WCF. $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- @@ -23,9 +23,10 @@ - + + diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj index 8343f2c6ae..64ee92e89b 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/OpenTelemetry.Instrumentation.Wcf.Tests.csproj @@ -22,8 +22,6 @@ - - From c6d650194e90e42ba93beae84b44552f14d9c815 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:36:24 -0500 Subject: [PATCH 1376/1499] [release] Prepare release Instrumentation.Wcf-1.0.0-rc.18 (#2260) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 745314baa5..aed823fb26 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.0.0-rc.18 + +Released 2024-Oct-28 + * Add target for `net6.0` to ensure that non-vulnerable transient dependencies are referenced by default for .NET6+. ([#2243](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2243)) From f6326f5bd984d06d7b6d9b73dd28062637eb157c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 29 Oct 2024 20:21:01 +0100 Subject: [PATCH 1377/1499] [repo/InfluxDB] Prepare to .NET9 (#2268) --- .../InfluxDBExporterExtensions.cs | 2 ++ .../InfluxDBMetricsExporter.cs | 2 ++ .../TelegrafPrometheusWriterV1.cs | 6 +++++- .../TelegrafPrometheusWriterV2.cs | 6 +++++- .../InfluxDBMetricsExporterTests.cs | 11 ++--------- .../Utils/AssertUtils.cs | 2 +- .../Utils/InfluxDBFakeServer.cs | 18 ++++++++---------- ...xDBMetricsExporterOptionsTestExtensions.cs | 4 ++-- .../Utils/LineProtocolParser.cs | 19 ++++++++----------- .../MeterProviderBuilderTestExtensions.cs | 2 +- .../Utils/PointData.cs | 2 +- 11 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs index 6628e761bf..88e917cf90 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBExporterExtensions.cs @@ -61,6 +61,8 @@ private static IMetricsWriter CreateMetricsWriter(MetricsSchema metricsSchema) return metricsSchema switch { MetricsSchema.TelegrafPrometheusV2 => new TelegrafPrometheusWriterV2(), + MetricsSchema.TelegrafPrometheusV1 => new TelegrafPrometheusWriterV1(), + MetricsSchema.None => new TelegrafPrometheusWriterV1(), _ => new TelegrafPrometheusWriterV1(), }; } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs index 651d360162..4c5d7a45be 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/InfluxDBMetricsExporter.cs @@ -26,6 +26,8 @@ public InfluxDBMetricsExporter(IMetricsWriter writer, InfluxDBClient influxDbCli case WriteErrorEvent writeErrorEvent: InfluxDBEventSource.Log.FailedToExport(writeErrorEvent.Exception.Message); break; + default: + break; } }; } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs index 078e64916e..555e6e8873 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV1.cs @@ -125,7 +125,7 @@ public void Write(Metric metric, Resource? resource, WriteApi writeApi) .Tags(resource?.Attributes) .Timestamp(dataPoint.EndTime.UtcDateTime, WritePrecision.Ns); - if (dataPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (dataPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { pointData = pointData.Field("min", min) .Field("max", max); @@ -142,6 +142,10 @@ public void Write(Metric metric, Resource? resource, WriteApi writeApi) writeApi.WritePoint(pointData); } + break; + case MetricType.ExponentialHistogram: + break; + default: break; } } diff --git a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs index df2a25e0fa..d0eda952d4 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs +++ b/src/OpenTelemetry.Exporter.InfluxDB/TelegrafPrometheusWriterV2.cs @@ -128,7 +128,7 @@ public void Write(Metric metric, Resource? resource, WriteApi writeApi) .Field($"{metricName}_count", metricPoint.GetHistogramCount()) .Field($"{metricName}_sum", metricPoint.GetHistogramSum()); - if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (metricPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { headPoint = headPoint .Field($"{metricName}_min", min) @@ -149,6 +149,10 @@ public void Write(Metric metric, Resource? resource, WriteApi writeApi) } } + break; + case MetricType.ExponentialHistogram: + break; + default: break; } } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs index 5528c0bb32..f9105672cf 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/InfluxDBMetricsExporterTests.cs @@ -12,21 +12,14 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests; public class InfluxDBMetricsExporterTests { private static readonly string OpenTelemetrySdkVersion; - private static readonly double[] TestBoundaries = new[] { 10D, 20D, 100D, 200D }; + private static readonly double[] TestBoundaries = [10D, 20D, 100D, 200D]; #pragma warning disable CA1810 // Initialize reference type static fields inline static InfluxDBMetricsExporterTests() #pragma warning restore CA1810 // Initialize reference type static fields inline { var sdkVersion = typeof(Sdk).Assembly.GetCustomAttribute()?.Version; - if (sdkVersion != null) - { - OpenTelemetrySdkVersion = Version.Parse(sdkVersion).ToString(3); - } - else - { - OpenTelemetrySdkVersion = "0.0.0"; - } + OpenTelemetrySdkVersion = sdkVersion != null ? Version.Parse(sdkVersion).ToString(3) : "0.0.0"; } [Theory] diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs index 3c8d12c4ca..9d7c81b2b3 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/AssertUtils.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; -public static class AssertUtils +internal static class AssertUtils { public static void HasField(TKey expectedKey, TValue expectedValue, IReadOnlyDictionary collection) where TKey : notnull diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs index 595b733949..e332000c42 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBFakeServer.cs @@ -8,7 +8,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; -public class InfluxDBFakeServer : IDisposable +internal class InfluxDBFakeServer : IDisposable { private static readonly char[] SplitChars = Environment.NewLine.ToCharArray(); private readonly IDisposable httpServer; @@ -16,13 +16,13 @@ public class InfluxDBFakeServer : IDisposable public InfluxDBFakeServer() { - this.lines = new BlockingCollection(); + this.lines = []; this.httpServer = TestHttpServer.RunServer( context => { - byte[] buffer = new byte[context.Request.ContentLength64]; + var buffer = new byte[context.Request.ContentLength64]; _ = context.Request.InputStream.Read(buffer, 0, buffer.Length); - string text = Encoding.UTF8.GetString(buffer); + var text = Encoding.UTF8.GetString(buffer); foreach (var line in text.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries)) { this.lines.Add(line); @@ -45,11 +45,9 @@ public void Dispose() public PointData ReadPoint() { - if (this.lines.TryTake(out var line, TimeSpan.FromSeconds(5))) - { - return LineProtocolParser.ParseLine(line); - } - - throw new InvalidOperationException("Failed to read a data point from the InfluxDB server within the 5-second timeout."); + return this.lines.TryTake(out var line, TimeSpan.FromSeconds(5)) + ? LineProtocolParser.ParseLine(line) + : throw new InvalidOperationException( + "Failed to read a data point from the InfluxDB server within the 5-second timeout."); } } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs index c3d84543eb..93b682d07b 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/InfluxDBMetricsExporterOptionsTestExtensions.cs @@ -3,7 +3,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; -public static class InfluxDBMetricsExporterOptionsTestExtensions +internal static class InfluxDBMetricsExporterOptionsTestExtensions { public static void WithDefaultTestConfiguration(this InfluxDBMetricsExporterOptions options) { @@ -11,7 +11,7 @@ public static void WithDefaultTestConfiguration(this InfluxDBMetricsExporterOpti options.Org = "MyOrg"; options.Token = "MyToken"; - // For tests we want to flush the metrics ASAP + // For tests, we want to flush the metrics ASAP options.FlushInterval = 1; } } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs index 4116cd9d6d..8ee5b7aa2d 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/LineProtocolParser.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; -public class LineProtocolParser +internal class LineProtocolParser { private static readonly DateTime UnixEpoch = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc); @@ -57,35 +57,32 @@ private static List> ParseTags(IEnumerable private static object ParseFieldValue(string fieldValue) { - if (bool.TryParse(fieldValue, out bool boolValue)) + if (bool.TryParse(fieldValue, out var boolValue)) { return boolValue; } #pragma warning disable CA1865 // Use char overload if (fieldValue.EndsWith("i", StringComparison.Ordinal) - && long.TryParse(fieldValue.AsSpan(0, fieldValue.Length - 1).ToString(), out long intValue)) + && long.TryParse(fieldValue.AsSpan(0, fieldValue.Length - 1).ToString(), out var intValue)) { return intValue; } #pragma warning restore CA1865 // Use char overload - if (double.TryParse(fieldValue, NumberStyles.Float, CultureInfo.InvariantCulture, out double doubleValue)) - { - return doubleValue; - } - - return fieldValue; + return double.TryParse(fieldValue, NumberStyles.Float, CultureInfo.InvariantCulture, out var doubleValue) + ? doubleValue + : fieldValue; } private static DateTime ParseTimestamp(string? timestampSection) { - if (string.IsNullOrEmpty(timestampSection) || !long.TryParse(timestampSection, out long unixTimeNanoseconds)) + if (string.IsNullOrEmpty(timestampSection) || !long.TryParse(timestampSection, out var unixTimeNanoseconds)) { throw new ArgumentException("Invalid formatted timestamp."); } - long ticks = unixTimeNanoseconds / 100; + var ticks = unixTimeNanoseconds / 100; return UnixEpoch.AddTicks(ticks); } } diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs index 1df7fa1bc8..ddfa310485 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/MeterProviderBuilderTestExtensions.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; -public static class MeterProviderBuilderTestExtensions +internal static class MeterProviderBuilderTestExtensions { public static MeterProviderBuilder ConfigureDefaultTestResource(this MeterProviderBuilder meterProviderBuilder) { diff --git a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs index 9c159e0c9e..4d2c66ceea 100644 --- a/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs +++ b/test/OpenTelemetry.Exporter.InfluxDB.Tests/Utils/PointData.cs @@ -3,7 +3,7 @@ namespace OpenTelemetry.Exporter.InfluxDB.Tests.Utils; -public class PointData +internal class PointData { public string Measurement { get; init; } = null!; From 637219bf49faf2575a118423f1fe2ff0e64cbf88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 29 Oct 2024 20:57:34 +0100 Subject: [PATCH 1378/1499] [repo/shared] Prepare to .NET9 (#2267) --- ...Telemetry.Instrumentation.SqlClient.csproj | 1 - src/Shared/ActivityInstrumentationHelper.cs | 10 ++++ .../DatabaseSemanticConventionHelper.cs | 4 +- src/Shared/GrpcTagHelper.cs | 25 ++++++--- src/Shared/NullableAttributes.cs | 2 +- src/Shared/PropertyFetcher.AOT.cs | 18 +++---- src/Shared/RequestDataHelper.cs | 2 +- .../DatabaseSemanticConventionHelperTests.cs | 52 +++++++++++-------- .../RequestDataHelperTests.cs | 15 +++--- 9 files changed, 75 insertions(+), 54 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj index 9a9827c62f..cdeb2cd9a4 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj +++ b/src/OpenTelemetry.Instrumentation.SqlClient/OpenTelemetry.Instrumentation.SqlClient.csproj @@ -15,7 +15,6 @@ - diff --git a/src/Shared/ActivityInstrumentationHelper.cs b/src/Shared/ActivityInstrumentationHelper.cs index be48827fb1..02a0d83e16 100644 --- a/src/Shared/ActivityInstrumentationHelper.cs +++ b/src/Shared/ActivityInstrumentationHelper.cs @@ -14,13 +14,23 @@ internal static class ActivityInstrumentationHelper private static Action CreateActivitySourceSetter() { +#if NET + return typeof(Activity).GetProperty("Source")! + .SetMethod!.CreateDelegate>(); +#else return (Action)typeof(Activity).GetProperty("Source")! .SetMethod!.CreateDelegate(typeof(Action)); +#endif } private static Action CreateActivityKindSetter() { +#if NET + return typeof(Activity).GetProperty("Kind")! + .SetMethod!.CreateDelegate>(); +#else return (Action)typeof(Activity).GetProperty("Kind")! .SetMethod!.CreateDelegate(typeof(Action)); +#endif } } diff --git a/src/Shared/DatabaseSemanticConventionHelper.cs b/src/Shared/DatabaseSemanticConventionHelper.cs index ef1c85cbc1..a3bc4b5e98 100644 --- a/src/Shared/DatabaseSemanticConventionHelper.cs +++ b/src/Shared/DatabaseSemanticConventionHelper.cs @@ -20,10 +20,10 @@ namespace OpenTelemetry.Internal; internal static class DatabaseSemanticConventionHelper { internal const string SemanticConventionOptInKeyName = "OTEL_SEMCONV_STABILITY_OPT_IN"; - internal static readonly char[] Separator = new[] { ',', ' ' }; + internal static readonly char[] Separator = [',', ' ']; [Flags] - public enum DatabaseSemanticConvention + internal enum DatabaseSemanticConvention { /// /// Instructs an instrumentation library to emit the old experimental Database attributes. diff --git a/src/Shared/GrpcTagHelper.cs b/src/Shared/GrpcTagHelper.cs index 9fa6dff377..d7c22b1c63 100644 --- a/src/Shared/GrpcTagHelper.cs +++ b/src/Shared/GrpcTagHelper.cs @@ -29,12 +29,7 @@ public static bool TryGetGrpcStatusCodeFromActivity(Activity activity, out int s { statusCode = -1; var grpcStatusCodeTag = activity.GetTagValue(GrpcStatusCodeTagName); - if (grpcStatusCodeTag == null) - { - return false; - } - - return int.TryParse(grpcStatusCodeTag as string, out statusCode); + return grpcStatusCodeTag != null && int.TryParse(grpcStatusCodeTag as string, out statusCode); } public static bool TryParseRpcServiceAndRpcMethod(string grpcMethod, out string rpcService, out string rpcMethod) @@ -66,9 +61,25 @@ public static ActivityStatusCode ResolveSpanStatusForGrpcStatusCode(int statusCo if (typeof(GrpcStatusCanonicalCode).IsEnumDefined(statusCode)) { - status = ((GrpcStatusCanonicalCode)statusCode) switch + status = (GrpcStatusCanonicalCode)statusCode switch { GrpcStatusCanonicalCode.Ok => ActivityStatusCode.Unset, + GrpcStatusCanonicalCode.Cancelled => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.Unknown => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.InvalidArgument => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.DeadlineExceeded => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.NotFound => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.AlreadyExists => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.PermissionDenied => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.ResourceExhausted => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.FailedPrecondition => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.Aborted => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.OutOfRange => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.Unimplemented => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.Internal => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.Unavailable => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.DataLoss => ActivityStatusCode.Error, + GrpcStatusCanonicalCode.Unauthenticated => ActivityStatusCode.Error, _ => ActivityStatusCode.Error, }; } diff --git a/src/Shared/NullableAttributes.cs b/src/Shared/NullableAttributes.cs index 21607db302..9706b278a1 100644 --- a/src/Shared/NullableAttributes.cs +++ b/src/Shared/NullableAttributes.cs @@ -43,7 +43,7 @@ internal sealed class MemberNotNullAttribute : Attribute /// /// The field or property member that is promised to be not-null. /// - public MemberNotNullAttribute(string member) => Members = new[] { member }; + public MemberNotNullAttribute(string member) => Members = [member]; /// Initializes the attribute with the list of field and property members. /// diff --git a/src/Shared/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index cb8ecb1b8b..209f91cada 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -56,12 +56,7 @@ public bool TryFetch( out T? value) { var innerFetcher = this.innerFetcher; - if (innerFetcher is null) - { - return TryFetchRare(obj, this.propertyName, ref this.innerFetcher, out value); - } - - return innerFetcher.TryFetch(obj, out value); + return innerFetcher is null ? TryFetchRare(obj, this.propertyName, ref this.innerFetcher, out value) : innerFetcher.TryFetch(obj, out value); } #if NET @@ -189,7 +184,11 @@ private sealed class PropertyFetchInstantiated : PropertyFetch public PropertyFetchInstantiated(PropertyInfo property) { this.propertyName = property.Name; +#if NET + this.propertyFetch = property.GetMethod!.CreateDelegate>(); +#else this.propertyFetch = (Func)property.GetMethod!.CreateDelegate(typeof(Func)); +#endif } public override int NumberOfInnerFetchers => this.innerFetcher == null @@ -210,12 +209,7 @@ public override bool TryFetch( } var innerFetcher = this.innerFetcher; - if (innerFetcher is null) - { - return TryFetchRare(obj, this.propertyName, ref this.innerFetcher, out value); - } - - return innerFetcher.TryFetch(obj, out value); + return innerFetcher is null ? TryFetchRare(obj, this.propertyName, ref this.innerFetcher, out value) : innerFetcher.TryFetch(obj, out value); } } } diff --git a/src/Shared/RequestDataHelper.cs b/src/Shared/RequestDataHelper.cs index 80df85c552..6acce7fe40 100644 --- a/src/Shared/RequestDataHelper.cs +++ b/src/Shared/RequestDataHelper.cs @@ -19,7 +19,7 @@ internal sealed class RequestDataHelper // https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md#common-attributes private const string OtherHttpMethod = "_OTHER"; - private static readonly char[] SplitChars = new[] { ',' }; + private static readonly char[] SplitChars = [',']; #if NET private readonly FrozenDictionary knownHttpMethods; diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs index 748ac1ea90..7b812b7f5d 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/DatabaseSemanticConventionHelperTests.cs @@ -9,28 +9,28 @@ namespace OpenTelemetry.Internal.Tests; public class DatabaseSemanticConventionHelperTests { - public static IEnumerable TestCases => new List - { - new object[] { null!, DatabaseSemanticConvention.Old }, - new object[] { string.Empty, DatabaseSemanticConvention.Old }, - new object[] { " ", DatabaseSemanticConvention.Old }, - new object[] { "junk", DatabaseSemanticConvention.Old }, - new object[] { "none", DatabaseSemanticConvention.Old }, - new object[] { "NONE", DatabaseSemanticConvention.Old }, - new object[] { "database", DatabaseSemanticConvention.New }, - new object[] { "DATABASE", DatabaseSemanticConvention.New }, - new object[] { "database/dup", DatabaseSemanticConvention.Dupe }, - new object[] { "DATABASE/DUP", DatabaseSemanticConvention.Dupe }, - new object[] { "junk,,junk", DatabaseSemanticConvention.Old }, - new object[] { "junk,JUNK", DatabaseSemanticConvention.Old }, - new object[] { "junk1,junk2", DatabaseSemanticConvention.Old }, - new object[] { "junk,database", DatabaseSemanticConvention.New }, - new object[] { "junk,database , database ,junk", DatabaseSemanticConvention.New }, - new object[] { "junk,database/dup", DatabaseSemanticConvention.Dupe }, - new object[] { "junk, database/dup ", DatabaseSemanticConvention.Dupe }, - new object[] { "database/dup,database", DatabaseSemanticConvention.Dupe }, - new object[] { "database,database/dup", DatabaseSemanticConvention.Dupe }, - }; + public static IEnumerable TestCases => + [ + [null!, DatabaseSemanticConvention.Old], + [string.Empty, DatabaseSemanticConvention.Old], + [" ", DatabaseSemanticConvention.Old], + ["junk", DatabaseSemanticConvention.Old], + ["none", DatabaseSemanticConvention.Old], + ["NONE", DatabaseSemanticConvention.Old], + ["database", DatabaseSemanticConvention.New], + ["DATABASE", DatabaseSemanticConvention.New], + ["database/dup", DatabaseSemanticConvention.Dupe], + ["DATABASE/DUP", DatabaseSemanticConvention.Dupe], + ["junk,,junk", DatabaseSemanticConvention.Old], + ["junk,JUNK", DatabaseSemanticConvention.Old], + ["junk1,junk2", DatabaseSemanticConvention.Old], + ["junk,database", DatabaseSemanticConvention.New], + ["junk,database , database ,junk", DatabaseSemanticConvention.New], + ["junk,database/dup", DatabaseSemanticConvention.Dupe], + ["junk, database/dup ", DatabaseSemanticConvention.Dupe], + ["database/dup,database", DatabaseSemanticConvention.Dupe], + ["database,database/dup", DatabaseSemanticConvention.Dupe], + ]; [Fact] public void VerifyFlags() @@ -56,7 +56,11 @@ public void VerifyGetSemanticConventionOptIn_UsingEnvironmentVariable(string inp { Environment.SetEnvironmentVariable(SemanticConventionOptInKeyName, input); +#if NET + var expected = Enum.Parse(expectedValue); +#else var expected = Enum.Parse(typeof(DatabaseSemanticConvention), expectedValue); +#endif Assert.Equal(expected, GetSemanticConventionOptIn(new ConfigurationBuilder().AddEnvironmentVariables().Build())); } finally @@ -73,7 +77,11 @@ public void VerifyGetSemanticConventionOptIn_UsingIConfiguration(string input, s .AddInMemoryCollection(new Dictionary { [SemanticConventionOptInKeyName] = input }) .Build(); +#if NET + var expected = Enum.Parse(expectedValue); +#else var expected = Enum.Parse(typeof(DatabaseSemanticConvention), expectedValue); +#endif Assert.Equal(expected, GetSemanticConventionOptIn(configuration)); } } diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs index f0c3a975cd..3795504a75 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/RequestDataHelperTests.cs @@ -8,14 +8,13 @@ namespace OpenTelemetry.Internal.Tests; public class RequestDataHelperTests : IDisposable { public static IEnumerable MappingVersionProtocolToVersionData => - new List - { - new object[] { new Version(1, 0), "1.0" }, - new object[] { new Version(1, 1), "1.1" }, - new object[] { new Version(2, 0), "2" }, - new object[] { new Version(3, 0), "3" }, - new object[] { new Version(7, 6, 5), "7.6.5" }, - }; + [ + [new Version(1, 0), "1.0"], + [new Version(1, 1), "1.1"], + [new Version(2, 0), "2"], + [new Version(3, 0), "3"], + [new Version(7, 6, 5), "7.6.5"], + ]; [Theory] [InlineData("GET", "GET")] From 7e789b0c1c1e7f4914444425edafb22a6cb1ecc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 29 Oct 2024 21:36:22 +0100 Subject: [PATCH 1379/1499] [repo/PersistentStorage] Prepare to .NET9 (#2264) --- .../PersistentBlobProvider.cs | 4 +-- .../DirectorySizeTracker.cs | 6 ++-- .../FileBlob.cs | 2 +- .../FileBlobProvider.cs | 13 ++------ .../PersistentStorageHelper.cs | 12 +++---- test/Shared/EventSourceTestHelper.cs | 32 +++++++++---------- test/Shared/TestEventListener.cs | 2 +- 7 files changed, 31 insertions(+), 40 deletions(-) diff --git a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs index 29d3dee8a0..465af27746 100644 --- a/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.Abstractions/PersistentBlobProvider.cs @@ -102,12 +102,12 @@ public IEnumerable GetBlobs() { try { - return this.OnGetBlobs() ?? Enumerable.Empty(); + return this.OnGetBlobs() ?? []; } catch (Exception ex) { PersistentStorageAbstractionsEventSource.Log.PersistentStorageAbstractionsException(nameof(PersistentBlobProvider), "Failed to get all the blobs", ex); - return Enumerable.Empty(); + return []; } } diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs index 2bbc352817..d251885f81 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/DirectorySizeTracker.cs @@ -56,16 +56,16 @@ internal static long CalculateFolderSize(string path) long directorySize = 0; try { - foreach (string file in Directory.EnumerateFiles(path)) + foreach (var file in Directory.EnumerateFiles(path)) { if (File.Exists(file)) { - FileInfo fileInfo = new FileInfo(file); + var fileInfo = new FileInfo(file); directorySize += fileInfo.Length; } } - foreach (string dir in Directory.GetDirectories(path)) + foreach (var dir in Directory.GetDirectories(path)) { directorySize += CalculateFolderSize(dir); } diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs index cfb1c395d0..72f121b950 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlob.cs @@ -58,7 +58,7 @@ protected override bool OnTryWrite(byte[] buffer, int leasePeriodMilliseconds = { Guard.ThrowIfNull(buffer); - string path = this.FullPath + ".tmp"; + var path = this.FullPath + ".tmp"; try { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs index b0abae2f40..edd1e1d489 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/FileBlobProvider.cs @@ -121,7 +121,7 @@ protected override IEnumerable OnGetBlobs() foreach (var file in Directory.EnumerateFiles(this.DirectoryPath, "*.blob", SearchOption.TopDirectoryOnly).OrderByDescending(f => f)) { - DateTime fileDateTime = PersistentStorageHelper.GetDateTimeFromBlobName(file); + var fileDateTime = PersistentStorageHelper.GetDateTimeFromBlobName(file); if (fileDateTime > retentionDeadline) { yield return new FileBlob(file, this.directorySizeTracker); @@ -173,7 +173,7 @@ private void OnMaintenanceEvent(object? source, ElapsedEventArgs e) private bool CheckStorageSize() { - if (!this.directorySizeTracker.IsSpaceAvailable(out long size)) + if (!this.directorySizeTracker.IsSpaceAvailable(out var size)) { // TODO: check accuracy of size reporting. PersistentStorageEventSource.Log.PersistentStorageWarning( @@ -197,14 +197,7 @@ private bool CheckStorageSize() var blobFilePath = Path.Combine(this.DirectoryPath, PersistentStorageHelper.GetUniqueFileName(".blob")); var blob = new FileBlob(blobFilePath, this.directorySizeTracker); - if (blob.TryWrite(buffer, leasePeriodMilliseconds)) - { - return blob; - } - else - { - return null; - } + return blob.TryWrite(buffer, leasePeriodMilliseconds) ? blob : null; } catch (Exception ex) { diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs index 63005646fc..6d2fd821cb 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/PersistentStorageHelper.cs @@ -12,7 +12,7 @@ internal static void RemoveExpiredBlob(DateTime retentionDeadline, string filePa { if (filePath.EndsWith(".blob", StringComparison.OrdinalIgnoreCase)) { - DateTime fileDateTime = GetDateTimeFromBlobName(filePath); + var fileDateTime = GetDateTimeFromBlobName(filePath); if (fileDateTime < retentionDeadline) { try @@ -30,11 +30,11 @@ internal static void RemoveExpiredBlob(DateTime retentionDeadline, string filePa internal static bool RemoveExpiredLease(DateTime leaseDeadline, string filePath) { - bool success = false; + var success = false; if (filePath.EndsWith(".lock", StringComparison.OrdinalIgnoreCase)) { - DateTime fileDateTime = GetDateTimeFromLeaseName(filePath); + var fileDateTime = GetDateTimeFromLeaseName(filePath); if (fileDateTime < leaseDeadline) { var newFilePath = filePath.Substring(0, filePath.LastIndexOf('@')); @@ -55,11 +55,11 @@ internal static bool RemoveExpiredLease(DateTime leaseDeadline, string filePath) internal static bool RemoveTimedOutTmpFiles(DateTime timeoutDeadline, string filePath) { - bool success = false; + var success = false; if (filePath.EndsWith(".tmp", StringComparison.OrdinalIgnoreCase)) { - DateTime fileDateTime = GetDateTimeFromBlobName(filePath); + var fileDateTime = GetDateTimeFromBlobName(filePath); if (fileDateTime < timeoutDeadline) { try @@ -144,7 +144,7 @@ internal static DateTime GetDateTimeFromLeaseName(string filePath) { var fileName = Path.GetFileNameWithoutExtension(filePath); var startIndex = fileName.LastIndexOf('@') + 1; - var time = fileName.Substring(startIndex, fileName.Length - startIndex); + var time = fileName.Substring(startIndex); DateTime.TryParseExact(time, "yyyy-MM-ddTHHmmss.fffffffZ", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dateTime); return dateTime.ToUniversalTime(); } diff --git a/test/Shared/EventSourceTestHelper.cs b/test/Shared/EventSourceTestHelper.cs index c430f52650..02de7a2a76 100644 --- a/test/Shared/EventSourceTestHelper.cs +++ b/test/Shared/EventSourceTestHelper.cs @@ -13,7 +13,7 @@ internal static class EventSourceTestHelper { public static void MethodsAreImplementedConsistentlyWithTheirAttributes(EventSource eventSource) { - foreach (MethodInfo publicMethod in GetEventMethods(eventSource)) + foreach (var publicMethod in GetEventMethods(eventSource)) { VerifyMethodImplementation(eventSource, publicMethod); } @@ -25,7 +25,7 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn listener.EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.All); try { - object[] eventArguments = GenerateEventArguments(eventMethod); + var eventArguments = GenerateEventArguments(eventMethod); eventMethod.Invoke(eventSource, eventArguments); var actualEvent = listener.Messages.First(q => q.EventName == eventMethod.Name); @@ -54,9 +54,9 @@ private static void VerifyMethodImplementation(EventSource eventSource, MethodIn private static object[] GenerateEventArguments(MethodInfo eventMethod) { - ParameterInfo[] parameters = eventMethod.GetParameters(); + var parameters = eventMethod.GetParameters(); var arguments = new object[parameters.Length]; - for (int i = 0; i < parameters.Length; i++) + for (var i = 0; i < parameters.Length; i++) { arguments[i] = GenerateArgument(parameters[i]); } @@ -71,37 +71,35 @@ private static object GenerateArgument(ParameterInfo parameter) return "Test String"; } - if (parameter.ParameterType.IsValueType) - { - return Activator.CreateInstance(parameter.ParameterType) - ?? throw new NotSupportedException($"Could not create an instance of the '{parameter.ParameterType}' type."); - } - - throw new NotSupportedException("Complex types are not supported"); + return parameter.ParameterType.IsValueType + ? Activator.CreateInstance(parameter.ParameterType) + ?? throw new NotSupportedException( + $"Could not create an instance of the '{parameter.ParameterType}' type.") + : throw new NotSupportedException("Complex types are not supported"); } private static void VerifyEventId(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) { - int expectedEventId = GetEventAttribute(eventMethod).EventId; + var expectedEventId = GetEventAttribute(eventMethod).EventId; AssertEqual(nameof(VerifyEventId), expectedEventId, actualEvent.EventId); } private static void VerifyEventLevel(MethodInfo eventMethod, EventWrittenEventArgs actualEvent) { - EventLevel expectedLevel = GetEventAttribute(eventMethod).Level; + var expectedLevel = GetEventAttribute(eventMethod).Level; AssertEqual(nameof(VerifyEventLevel), expectedLevel, actualEvent.Level); } private static void VerifyEventMessage(MethodInfo eventMethod, EventWrittenEventArgs actualEvent, object[] eventArguments) { - string expectedMessage = eventArguments.Length == 0 + var expectedMessage = eventArguments.Length == 0 ? GetEventAttribute(eventMethod).Message! : string.Format(CultureInfo.InvariantCulture, GetEventAttribute(eventMethod).Message!, eventArguments); - string actualMessage = string.Format( + var actualMessage = string.Format( CultureInfo.InvariantCulture, actualEvent.Message!, - actualEvent.Payload?.ToArray() ?? Array.Empty()); + actualEvent.Payload?.ToArray() ?? []); AssertEqual(nameof(VerifyEventMessage), expectedMessage, actualMessage); } @@ -128,7 +126,7 @@ private static EventAttribute GetEventAttribute(MethodInfo eventMethod) private static IEnumerable GetEventMethods(EventSource eventSource) { - MethodInfo[] methods = eventSource.GetType().GetMethods(); + var methods = eventSource.GetType().GetMethods(); return methods.Where(m => m.GetCustomAttributes(typeof(EventAttribute), false).Length != 0); } } diff --git a/test/Shared/TestEventListener.cs b/test/Shared/TestEventListener.cs index c6b8db9c62..424ba512a6 100644 --- a/test/Shared/TestEventListener.cs +++ b/test/Shared/TestEventListener.cs @@ -77,7 +77,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; + var callback = this.OnOnEventSourceCreated; callback?.Invoke(eventSource); } } From ae6d420c7312a3bc91a882edbd100b81e909800e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 29 Oct 2024 21:45:08 +0100 Subject: [PATCH 1380/1499] [repo/StackDriver] Prepare to .NET9 (#2270) --- .../Implementation/ActivityExtensions.cs | 36 +++++++------------ .../StackdriverTraceExporter.cs | 15 +++----- .../ActivityExtensionsTest.cs | 20 +++++------ .../StackdriverExporterTests.cs | 23 ++++++------ .../TestActivityProcessor.cs | 2 +- .../TestTraceServiceClient.cs | 2 +- 6 files changed, 40 insertions(+), 58 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs index 39b4cde0d5..d833dc9eed 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/Implementation/ActivityExtensions.cs @@ -11,7 +11,7 @@ namespace OpenTelemetry.Exporter.Stackdriver.Implementation; internal static class ActivityExtensions { - private static readonly Dictionary LabelsToReplace = new Dictionary + private static readonly Dictionary LabelsToReplace = new() { { "component", "/component" }, { "http.method", "/http/method" }, @@ -110,29 +110,17 @@ public static Span.Types.Link ToLink(this ActivityLink link) public static AttributeValue ToAttributeValue(this object? av) { - switch (av) + return av switch { - case string s: - return new AttributeValue - { - StringValue = new TruncatableString { Value = s }, - }; - case bool b: - return new AttributeValue { BoolValue = b }; - case long l: - return new AttributeValue { IntValue = l }; - case double d: - return new AttributeValue - { - StringValue = new TruncatableString { Value = d.ToString(CultureInfo.InvariantCulture) }, - }; - case null: - return new AttributeValue(); - default: - return new AttributeValue - { - StringValue = new TruncatableString { Value = av.ToString() }, - }; - } + string s => new AttributeValue { StringValue = new TruncatableString { Value = s } }, + bool b => new AttributeValue { BoolValue = b }, + long l => new AttributeValue { IntValue = l }, + double d => new AttributeValue + { + StringValue = new TruncatableString { Value = d.ToString(CultureInfo.InvariantCulture) }, + }, + null => new AttributeValue(), + _ => new AttributeValue { StringValue = new TruncatableString { Value = av.ToString() } }, + }; } } diff --git a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs index 46899657f0..5aa5067fd2 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Stackdriver/StackdriverTraceExporter.cs @@ -8,7 +8,6 @@ using Google.Cloud.Trace.V2; using Grpc.Core; using OpenTelemetry.Exporter.Stackdriver.Implementation; -using OpenTelemetry.Resources; namespace OpenTelemetry.Exporter.Stackdriver; @@ -78,27 +77,23 @@ internal StackdriverTraceExporter(string projectId, TraceServiceClient traceServ /// public override ExportResult Export(in Batch batch) { - TraceServiceClient? traceWriter = this.traceServiceClient; - if (traceWriter == null) + var traceWriter = this.traceServiceClient ?? new TraceServiceClientBuilder { - traceWriter = new TraceServiceClientBuilder - { - Settings = this.traceServiceSettings, - }.Build(); - } + Settings = this.traceServiceSettings, + }.Build(); var batchSpansRequest = new BatchWriteSpansRequest { ProjectName = this.googleCloudProjectId, }; - Resource? resource = this.ParentProvider?.GetResource(); + var resource = this.ParentProvider?.GetResource(); foreach (var activity in batch) { // It should never happen that the time has no correct kind, only if OpenTelemetry is used incorrectly. if (activity.StartTimeUtc.Kind == DateTimeKind.Utc) { - Span span = activity.ToSpan(this.googleCloudProjectId.ProjectId); + var span = activity.ToSpan(this.googleCloudProjectId.ProjectId); if (resource != null) { span.AnnotateWith(resource); diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs index 5e1b9a5f0b..2adf881ce8 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs @@ -45,17 +45,17 @@ public void ActivityExtensions_Export_Duplicate_ActivityLink_Tag_Key() var spanId1 = ActivitySpanId.CreateRandom(); var spanId2 = ActivitySpanId.CreateRandom(); - ActivityContext context1 = new ActivityContext(traceId, spanId1, ActivityTraceFlags.Recorded, isRemote: true); - ActivityContext context2 = new ActivityContext(traceId, spanId2, ActivityTraceFlags.Recorded, isRemote: true); + var context1 = new ActivityContext(traceId, spanId1, ActivityTraceFlags.Recorded, isRemote: true); + var context2 = new ActivityContext(traceId, spanId2, ActivityTraceFlags.Recorded, isRemote: true); - KeyValuePair[] dupTags = new[] - { - new KeyValuePair("key1", "value1"), - new KeyValuePair("key2", "value2"), - new KeyValuePair("key1", "value3"), - }; - ActivityLink link1 = new ActivityLink(context1, tags: new ActivityTagsCollection(dupTags)); - ActivityLink link2 = new ActivityLink(context2); + KeyValuePair[] dupTags = + [ + new("key1", "value1"), + new("key2", "value2"), + new("key1", "value3") + ]; + var link1 = new ActivityLink(context1, tags: new ActivityTagsCollection(dupTags)); + var link2 = new ActivityLink(context2); var links = new List { link1, link2 }; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs index 854fb7bd0d..5d6a65772c 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/StackdriverExporterTests.cs @@ -29,11 +29,11 @@ static StackdriverExporterTests() public void StackdriverExporter_CustomActivityProcessor() { const string ActivitySourceName = "stackdriver.test"; - Guid requestId = Guid.NewGuid(); - TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + var requestId = Guid.NewGuid(); + var testActivityProcessor = new TestActivityProcessor(); - bool startCalled = false; - bool endCalled = false; + var startCalled = false; + var endCalled = false; testActivityProcessor.StartAction = (a) => @@ -86,7 +86,7 @@ public void StackdriverExporter_WithServiceNameMetadata() public void StackdriverExporter_TraceClientThrows_ExportResultFailure() { Exception? exception; - ExportResult result = ExportResult.Success; + var result = ExportResult.Success; var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); @@ -95,9 +95,9 @@ public void StackdriverExporter_TraceClientThrows_ExportResultFailure() var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); - for (int i = 0; i < 10; i++) + for (var i = 0; i < 10; i++) { - using Activity activity = CreateTestActivity(); + using var activity = CreateTestActivity(); processor.OnEnd(activity); } @@ -122,7 +122,7 @@ void RunTest(Batch batch) public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() { Exception? exception; - ExportResult result = ExportResult.Failure; + var result = ExportResult.Failure; var exportedItems = new List(); const string ActivitySourceName = "stackdriver.test"; var source = new ActivitySource(ActivitySourceName); @@ -131,9 +131,9 @@ public void StackdriverExporter_TraceClientDoesNotTrow_ExportResultSuccess() var processor = new BatchActivityExportProcessor(new InMemoryExporter(exportedItems)); - for (int i = 0; i < 10; i++) + for (var i = 0; i < 10; i++) { - using Activity activity = CreateTestActivity(); + using var activity = CreateTestActivity(); processor.OnEnd(activity); } @@ -159,7 +159,6 @@ internal static Activity CreateTestActivity( Dictionary? additionalAttributes = null, bool addEvents = true, bool addLinks = true, - Resource? resource = null, ActivityKind kind = ActivityKind.Client) { var startTimestamp = DateTime.UtcNow; @@ -167,7 +166,7 @@ internal static Activity CreateTestActivity( var eventTimestamp = DateTime.UtcNow; var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); - var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); + var parentSpanId = ActivitySpanId.CreateFromBytes([12, 23, 34, 45, 56, 67, 78, 89]); var attributes = new Dictionary { diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs index eab6437c06..e82193e16a 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestActivityProcessor.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.Stackdriver.Tests; -public class TestActivityProcessor : BaseProcessor, IDisposable +internal class TestActivityProcessor : BaseProcessor, IDisposable { public Action? StartAction; public Action? EndAction; diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs index dd1aceb4a7..8baebef691 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/TestTraceServiceClient.cs @@ -11,7 +11,7 @@ internal class TestTraceServiceClient(bool throwException) : TraceServiceClient { private readonly bool throwException = throwException; - public List Spans { get; } = new List(); + public List Spans { get; } = []; public override void BatchWriteSpans(BatchWriteSpansRequest request, CallSettings callSettings) { From 9b8b4ba250ec26b7db9360dcf054ff3f277ffefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 29 Oct 2024 21:57:18 +0100 Subject: [PATCH 1381/1499] [repo/Extensions] Prepare to .NET9 (#2265) --- .../AWSXRayIdGenerator.cs | 21 +++++++------- .../Trace/AWSXRayPropagator.cs | 29 +++++++------------ .../Internal/TraceEnrichmentActions.cs | 2 +- .../Trace/AWSXRayPropagatorTests.cs | 11 ++----- .../Trace/BaggageActivityProcessorTests.cs | 9 ++---- .../Trace/RateLimitingSamplerTests.cs | 6 ++++ 6 files changed, 33 insertions(+), 45 deletions(-) diff --git a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs index f55193111e..2031bb244d 100644 --- a/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs +++ b/src/OpenTelemetry.Extensions.AWS/AWSXRayIdGenerator.cs @@ -20,10 +20,10 @@ public static class AWSXRayIdGenerator private const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000; private const long MicrosecondPerSecond = TimeSpan.TicksPerSecond / TicksPerMicrosecond; - private static readonly DateTime EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private static readonly DateTime EpochStart = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly long UnixEpochMicroseconds = EpochStart.Ticks / TicksPerMicrosecond; - private static readonly Random Global = new Random(); - private static object randLock = new object(); + private static readonly Random Global = new(); + private static readonly object RandLock = new(); internal static void ReplaceTraceId(Sampler? sampler = null) { @@ -67,15 +67,15 @@ internal static ActivityTraceId GenerateAWSXRayCompatibleTraceId() internal static void UpdateSamplingDecision(Activity activity, Sampler sampler) { - if (!(sampler is AlwaysOnSampler) && !(sampler is AlwaysOffSampler)) + if (sampler is not AlwaysOnSampler and not AlwaysOffSampler) { - ActivitySamplingResult result = !Sdk.SuppressInstrumentation ? ComputeRootActivitySamplingResult(activity, sampler) : ActivitySamplingResult.None; + var result = !Sdk.SuppressInstrumentation ? ComputeRootActivitySamplingResult(activity, sampler) : ActivitySamplingResult.None; activity.ActivityTraceFlags = ActivityTraceFlags.None; // Following the same behavior when .NET runtime sets the trace flag for a newly created root activity. // See: https://github.com/dotnet/runtime/blob/master/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.cs#L1022-L1027 - activity.IsAllDataRequested = result == ActivitySamplingResult.AllData || result == ActivitySamplingResult.AllDataAndRecorded; + activity.IsAllDataRequested = result is ActivitySamplingResult.AllData or ActivitySamplingResult.AllDataAndRecorded; if (result == ActivitySamplingResult.AllDataAndRecorded) { @@ -91,8 +91,8 @@ internal static void UpdateSamplingDecision(Activity activity, Sampler sampler) /// The number of seconds elapsed since 1970-01-01 00:00:00 UTC. The value is expressed in whole and fractional seconds with resolution of microsecond. private static decimal ToUnixTimeSeconds(this DateTime date) { - long microseconds = date.Ticks / TicksPerMicrosecond; - long microsecondsSinceEpoch = microseconds - UnixEpochMicroseconds; + var microseconds = date.Ticks / TicksPerMicrosecond; + var microsecondsSinceEpoch = microseconds - UnixEpochMicroseconds; return (decimal)microsecondsSinceEpoch / MicrosecondPerSecond; } @@ -105,11 +105,11 @@ private static string GenerateHexNumber(int digits) { Guard.ThrowIfOutOfRange(digits, min: 0); - byte[] bytes = new byte[digits / 2]; + var bytes = new byte[digits / 2]; string hexNumber; - lock (randLock) + lock (RandLock) { NextBytes(bytes); hexNumber = string.Concat(bytes.Select(x => x.ToString("x2", CultureInfo.InvariantCulture)).ToArray()); @@ -164,6 +164,7 @@ private static ActivitySamplingResult ComputeRootActivitySamplingResult( { SamplingDecision.RecordAndSample => ActivitySamplingResult.AllDataAndRecorded, SamplingDecision.RecordOnly => ActivitySamplingResult.AllData, + SamplingDecision.Drop => ActivitySamplingResult.PropagationData, _ => ActivitySamplingResult.PropagationData, }; diff --git a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs index 569bae5391..8927b136f7 100644 --- a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs @@ -68,12 +68,7 @@ public override PropagationContext Extract(PropagationContext context, T carr var parentHeader = parentTraceHeader.First(); - if (!TryParseXRayTraceHeader(parentHeader, out var newActivityContext)) - { - return context; - } - - return new PropagationContext(newActivityContext, context.Baggage); + return !TryParseXRayTraceHeader(parentHeader, out var newActivityContext) ? context : new PropagationContext(newActivityContext, context.Baggage); } catch (Exception ex) { @@ -135,10 +130,10 @@ internal static bool TryParseXRayTraceHeader(string rawHeader, out ActivityConte return false; } - ReadOnlySpan header = rawHeader.AsSpan(); + var header = rawHeader.AsSpan(); while (header.Length > 0) { - int delimiterIndex = header.IndexOf(TraceHeaderDelimiter); + var delimiterIndex = header.IndexOf(TraceHeaderDelimiter); ReadOnlySpan part; if (delimiterIndex >= 0) { @@ -151,14 +146,14 @@ internal static bool TryParseXRayTraceHeader(string rawHeader, out ActivityConte header = header.Slice(header.Length); } - ReadOnlySpan trimmedPart = part.Trim(); - int equalsIndex = trimmedPart.IndexOf(KeyValueDelimiter); + var trimmedPart = part.Trim(); + var equalsIndex = trimmedPart.IndexOf(KeyValueDelimiter); if (equalsIndex < 0) { return false; } - ReadOnlySpan value = trimmedPart.Slice(equalsIndex + 1); + var value = trimmedPart.Slice(equalsIndex + 1); if (trimmedPart.StartsWith(RootKey.AsSpan())) { if (!TryParseOTFormatTraceId(value, out var otFormatTraceId)) @@ -188,7 +183,7 @@ internal static bool TryParseXRayTraceHeader(string rawHeader, out ActivityConte } } - if (traceId == default || parentId == default || traceOptions == default) + if (traceId.IsEmpty || parentId.IsEmpty || traceOptions == default) { return false; } @@ -252,12 +247,8 @@ internal static bool TryParseOTFormatTraceId(ReadOnlySpan traceId, out Rea internal static bool IsParentIdValid(ReadOnlySpan parentId) { - if (parentId.IsEmpty || parentId.IsWhiteSpace()) - { - return false; - } - - return parentId.Length == ParentIdHexDigits && long.TryParse(parentId.ToString(), NumberStyles.HexNumber, null, out _); + return !parentId.IsEmpty && !parentId.IsWhiteSpace() && parentId.Length == ParentIdHexDigits && + long.TryParse(parentId.ToString(), NumberStyles.HexNumber, null, out _); } internal static bool TryParseSampleDecision(ReadOnlySpan sampleDecision, out char result) @@ -274,7 +265,7 @@ internal static bool TryParseSampleDecision(ReadOnlySpan sampleDecision, o return false; } - if (tempChar != SampledValue && tempChar != NotSampledValue) + if (tempChar is not SampledValue and not NotSampledValue) { return false; } diff --git a/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs index 1417e5edb3..aa745bfed3 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs +++ b/src/OpenTelemetry.Extensions.Enrichment/Internal/TraceEnrichmentActions.cs @@ -16,7 +16,7 @@ public TraceEnrichmentActions(IEnumerable> actions) public override void Enrich(in TraceEnrichmentBag bag) { - for (int i = 0; i < this.actions.Length; i++) + for (var i = 0; i < this.actions.Length; i++) { this.actions[i].Invoke(bag); } diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs index c654ec2b9e..3502808f42 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/Trace/AWSXRayPropagatorTests.cs @@ -14,16 +14,11 @@ public class AWSXRayPropagatorTests private const string TraceId = "5759e988bd862e3fe1be46a994272793"; private const string ParentId = "53995c3f42cd8ad8"; - 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 Empty; + return headers.TryGetValue(name, out var value) ? [value] : Empty; }; private static readonly Action, string, string> Setter = (carrier, name, value) => @@ -31,7 +26,7 @@ public class AWSXRayPropagatorTests carrier[name] = value; }; - private readonly AWSXRayPropagator awsXRayPropagator = new AWSXRayPropagator(); + private readonly AWSXRayPropagator awsXRayPropagator = new(); [Fact] public void TestInjectTraceHeader() diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs index 1f96b7c72d..0f43e32d8f 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/BaggageActivityProcessorTests.cs @@ -62,7 +62,7 @@ public void BaggageActivityProcessor_CanUseRegex() var regex = new Regex("^mykey", RegexOptions.Compiled); using var provider = Sdk.CreateTracerProviderBuilder() - .AddBaggageActivityProcessor((baggageKey) => regex.IsMatch(baggageKey)) + .AddBaggageActivityProcessor(regex.IsMatch) .AddSource(sourceName) .Build(); @@ -107,12 +107,7 @@ public void BaggageActivityProcessor_PredicateThrows_OnlyDropsEntriesThatThrow() using var provider = Sdk.CreateTracerProviderBuilder() .AddBaggageActivityProcessor(key => { - if (key == "key") - { - throw new Exception("Predicate throws an exception."); - } - - return true; + return key == "key" ? throw new Exception("Predicate throws an exception.") : true; }) .AddSource(sourceName) .Build(); diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs index 2acc236783..df56e6430d 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs @@ -40,6 +40,9 @@ public void ShouldSample_ReturnsRecordAndSample_WhenWithinRateLimit() case SamplingDecision.Drop: sampleOut++; break; + default: + Assert.Fail("Unexpected value"); + break; } Thread.Sleep(333); @@ -82,6 +85,9 @@ public async Task ShouldFilter_WhenAboveRateLimit() case SamplingDecision.Drop: sampleOut++; break; + default: + Assert.Fail("Unexpected value"); + break; } // Task.Delay is limited by the OS Scheduler, so we can't guarantee the exact time From 0a89d818964bdf2d978fa770580ae79740062896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 30 Oct 2024 06:28:50 +0100 Subject: [PATCH 1382/1499] [repo/Instana] Prepare to .NET9 (#2269) --- .../Implementation/InstanaSpan.cs | 14 +-- .../Implementation/InstanaSpanFactory.cs | 6 +- .../Implementation/InstanaSpanSerializer.cs | 80 ++++++++------- .../Processors/ActivityProcessorBase.cs | 18 ++-- .../Processors/DefaultActivityProcessor.cs | 28 +++--- .../Processors/EventsActivityProcessor.cs | 2 +- .../Processors/TagsActivityProcessor.cs | 10 +- .../Implementation/SpanSender.cs | 4 +- .../Implementation/Transport.cs | 99 +++++++++---------- .../InstanaExporter.cs | 56 ++++------- .../InstanaExporterTests.cs | 18 ++-- .../InstanaSpanFactoryTests.cs | 2 +- .../InstanaSpanSerializerTests.cs | 54 +++++----- .../InstanaSpanTest.cs | 10 +- .../DefaultActivityProcessorTests.cs | 6 +- .../Processors/ErrorActivityProcessorTests.cs | 14 +-- .../EventsActivityProcessorTests.cs | 14 ++- .../Processors/TagsActivityProcessorTests.cs | 10 +- .../TestInstanaExporterHelper.cs | 2 +- 19 files changed, 198 insertions(+), 249 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs index e9a6ce6e34..159baf28cf 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpan.cs @@ -23,11 +23,11 @@ internal enum SpanKind internal class InstanaSpan { - private InstanaSpanTransformInfo transformInfo = new InstanaSpanTransformInfo(); + private InstanaSpanTransformInfo transformInfo = new(); private string n = string.Empty; private string t = string.Empty; private string lt = string.Empty; - private From f = new From(); + private From f = new(); private string p = string.Empty; private string s = string.Empty; private SpanKind k = SpanKind.NOT_SET; @@ -35,7 +35,7 @@ internal class InstanaSpan private long d; private bool tp; private int ec; - private Data data = new Data() + private Data data = new() { data = new Dictionary(8), Events = new List(8), @@ -197,9 +197,9 @@ internal bool IsEmpty() internal class Data #pragma warning restore SA1402 // File may only contain a single type { - private List events = new List(8); - private Dictionary dataField = new Dictionary(8); - private Dictionary tags = new Dictionary(2); + private List events = new(8); + private Dictionary dataField = new(8); + private Dictionary tags = new(2); #pragma warning disable SA1300 // Element should begin with upper-case letter @@ -241,7 +241,7 @@ internal class SpanEvent #pragma warning restore SA1402 // File may only contain a single type { private string name = string.Empty; - private Dictionary tags = new Dictionary(); + private Dictionary tags = []; public string Name { diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs index 0d106cd0d5..fe3dbf4843 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanFactory.cs @@ -7,12 +7,12 @@ internal class InstanaSpanFactory { internal static InstanaSpan CreateSpan() { - InstanaSpan instanaSpan = new InstanaSpan + var instanaSpan = new InstanaSpan { Data = new Data() { - data = new Dictionary(), - Tags = new Dictionary(), + data = [], + Tags = [], Events = new List(8), }, diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs index 55d8626dad..3046fa58ba 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/InstanaSpanSerializer.cs @@ -68,7 +68,7 @@ internal static async Task SerializeToStreamWriterAsync(InstanaSpan instanaSpan, await writer.WriteAsync(COMMA).ConfigureAwait(false); await AppendPropertyAsync(DateToUnixMillis(instanaSpan.Ts), "ts", writer).ConfigureAwait(false); await writer.WriteAsync(COMMA).ConfigureAwait(false); - await AppendPropertyAsync((long)(instanaSpan.D / 10_000), "d", writer).ConfigureAwait(false); + await AppendPropertyAsync(instanaSpan.D / 10_000L, "d", writer).ConfigureAwait(false); await writer.WriteAsync(COMMA).ConfigureAwait(false); await AppendObjectAsync(SerializeDataAsync, "data", instanaSpan, writer).ConfigureAwait(false); await writer.WriteAsync(COMMA).ConfigureAwait(false); @@ -227,55 +227,53 @@ private static async Task SerializeEventsAsync(InstanaSpan instanaSpan, StreamWr return; } - using (var enumerator = instanaSpan.Data.Events.GetEnumerator()) + using var enumerator = instanaSpan.Data.Events.GetEnumerator(); + byte i = 0; + try { - byte i = 0; - try + await writer.WriteAsync("[").ConfigureAwait(false); + while (enumerator.MoveNext()) { - await writer.WriteAsync("[").ConfigureAwait(false); - while (enumerator.MoveNext()) + if (i > 0) { - if (i > 0) - { - await writer.WriteAsync(COMMA).ConfigureAwait(false); - } - else - { - i = 1; - } + await writer.WriteAsync(COMMA).ConfigureAwait(false); + } + else + { + i = 1; + } - await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); + await writer.WriteAsync(OPEN_BRACE).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(enumerator.Current.Name).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COMMA_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD).ConfigureAwait(false); + await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); + await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false); + await writer.WriteAsync(QUOTE).ConfigureAwait(false); + + if (enumerator.Current.Tags.Count > 0) + { + await writer.WriteAsync(COMMA).ConfigureAwait(false); await writer.WriteAsync(QUOTE).ConfigureAwait(false); - await writer.WriteAsync(InstanaExporterConstants.EVENT_NAME_FIELD).ConfigureAwait(false); - await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); - await writer.WriteAsync(enumerator.Current.Name).ConfigureAwait(false); - await writer.WriteAsync(QUOTE_COMMA_QUOTE).ConfigureAwait(false); - await writer.WriteAsync(InstanaExporterConstants.EVENT_TIMESTAMP_FIELD).ConfigureAwait(false); - await writer.WriteAsync(QUOTE_COLON_QUOTE).ConfigureAwait(false); - await writer.WriteAsync(DateToUnixMillis(enumerator.Current.Ts).ToString(CultureInfo.InvariantCulture)).ConfigureAwait(false); + await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD).ConfigureAwait(false); await writer.WriteAsync(QUOTE).ConfigureAwait(false); - - if (enumerator.Current.Tags.Count > 0) - { - await writer.WriteAsync(COMMA).ConfigureAwait(false); - await writer.WriteAsync(QUOTE).ConfigureAwait(false); - await writer.WriteAsync(InstanaExporterConstants.TAGS_FIELD).ConfigureAwait(false); - await writer.WriteAsync(QUOTE).ConfigureAwait(false); - await writer.WriteAsync(COLON).ConfigureAwait(false); - await SerializeTagsLogicAsync(enumerator.Current.Tags, writer).ConfigureAwait(false); - } - - await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); + await writer.WriteAsync(COLON).ConfigureAwait(false); + await SerializeTagsLogicAsync(enumerator.Current.Tags, writer).ConfigureAwait(false); } - await writer.WriteAsync("]").ConfigureAwait(false); - } - catch (InvalidOperationException) - { - // if the collection gets modified while serializing, we might get a collision. - // There is no good way of preventing this and continuing normally except locking - // which needs investigation + await writer.WriteAsync(CLOSE_BRACE).ConfigureAwait(false); } + + await writer.WriteAsync("]").ConfigureAwait(false); + } + catch (InvalidOperationException) + { + // if the collection gets modified while serializing, we might get a collision. + // There is no good way of preventing this and continuing normally except locking + // which needs investigation } } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs index e4dbea1f3a..ff86416aae 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/ActivityProcessorBase.cs @@ -19,19 +19,13 @@ public virtual async Task ProcessAsync(Activity activity, InstanaSpan instanaSpa protected virtual void PreProcess(Activity activity, InstanaSpan instanaSpan) { - if (instanaSpan.TransformInfo == null) - { - instanaSpan.TransformInfo = new InstanaSpanTransformInfo(); - } + instanaSpan.TransformInfo ??= new InstanaSpanTransformInfo(); - if (instanaSpan.Data == null) + instanaSpan.Data ??= new Data() { - instanaSpan.Data = new Data() - { - data = new Dictionary(), - Events = new List(8), - Tags = new Dictionary(), - }; - } + data = [], + Events = new List(8), + Tags = [], + }; } } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs index fd430b9b6a..3c6447bcec 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/DefaultActivityProcessor.cs @@ -13,7 +13,7 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.N = InstanaExporterConstants.OTEL_SPAN_TYPE; - string traceId = activity.TraceId.ToHexString(); + var traceId = activity.TraceId.ToHexString(); if (traceId.Length == 32) { instanaSpan.T = traceId.Substring(16); @@ -24,8 +24,8 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp instanaSpan.T = traceId; } - bool hasParent = false; - string parentSpanId = activity.ParentSpanId.ToHexString(); + var hasParent = false; + var parentSpanId = activity.ParentSpanId.ToHexString(); if (!string.IsNullOrEmpty(parentSpanId) && GetLongFromHex(parentSpanId) != 0) { hasParent = true; @@ -52,19 +52,13 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp private static SpanKind GetSpanKind(ActivityKind activityKind) { - switch (activityKind) + return activityKind switch { - case ActivityKind.Consumer: - case ActivityKind.Server: - return SpanKind.ENTRY; - case ActivityKind.Client: - case ActivityKind.Producer: - return SpanKind.EXIT; - case ActivityKind.Internal: - return SpanKind.INTERMEDIATE; - default: - return SpanKind.NOT_SET; - } + ActivityKind.Consumer or ActivityKind.Server => SpanKind.ENTRY, + ActivityKind.Client or ActivityKind.Producer => SpanKind.EXIT, + ActivityKind.Internal => SpanKind.INTERMEDIATE, + _ => SpanKind.NOT_SET, + }; } private static long GetLongFromHex(string hexValue) @@ -73,7 +67,7 @@ private static long GetLongFromHex(string hexValue) { try { - string[] ids = hexValue.Split(','); + var ids = hexValue.Split(','); return Convert.ToInt64(ids[ids.Length - 1].Trim(), 16); } catch (Exception) @@ -86,7 +80,7 @@ private static long GetLongFromHex(string hexValue) private static void SetKind(Activity activity, InstanaSpan instanaSpan) { - bool isEntrySpan = false; + var isEntrySpan = false; if (instanaSpan.Data.data != null) { diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs index 1c1fb00c61..df3e8decf8 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/EventsActivityProcessor.cs @@ -22,7 +22,7 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp { Name = activityEvent.Name, Ts = activityEvent.Timestamp.Ticks, - Tags = new Dictionary(), + Tags = [], }; foreach (var eventTag in activityEvent.Tags) diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs index 0f6763c1a9..1d6341e7a9 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Processors/TagsActivityProcessor.cs @@ -21,20 +21,20 @@ public override async Task ProcessAsync(Activity activity, InstanaSpan instanaSp this.PreProcess(activity, instanaSpan); - string statusCode = string.Empty; - string statusDesc = string.Empty; - Dictionary tags = new Dictionary(); + var statusCode = string.Empty; + var statusDesc = string.Empty; + var tags = new Dictionary(); foreach (var tag in activity.Tags) { if (tag.Key == "otel.status_code") { - statusCode = (tag.Value as string) ?? string.Empty; + statusCode = tag.Value ?? string.Empty; continue; } if (tag.Key == "otel.status_description") { - statusDesc = (tag.Value as string) ?? string.Empty; + statusDesc = tag.Value ?? string.Empty; continue; } diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs index 0381b25a5a..9e20b6e805 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/SpanSender.cs @@ -10,7 +10,7 @@ internal sealed class SpanSender : ISpanSender #pragma warning restore CA1001 // Types that own disposable fields should be disposable { private readonly Task queueSenderTask; - private readonly ConcurrentQueue spansQueue = new ConcurrentQueue(); + private readonly ConcurrentQueue spansQueue = new(); public SpanSender() { @@ -33,7 +33,7 @@ private async void TaskSpanSender() while (true) { // check if we can send spans - if (this.spansQueue.TryPeek(out InstanaSpan _)) + if (this.spansQueue.TryPeek(out var _)) { // actually send spans await Transport.SendSpansAsync(this.spansQueue).ConfigureAwait(false); diff --git a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs index f39c6b2da7..97cee57f7b 100644 --- a/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs +++ b/src/OpenTelemetry.Exporter.Instana/Implementation/Transport.cs @@ -15,7 +15,7 @@ internal static class Transport { private const int MultiSpanBufferSize = 4096000; private const int MultiSpanBufferLimit = 4070000; - private static readonly MediaTypeHeaderValue MEDIAHEADER = new MediaTypeHeaderValue("application/json"); + private static readonly MediaTypeHeaderValue MEDIAHEADER = new("application/json"); private static readonly byte[] TracesBuffer = new byte[MultiSpanBufferSize]; private static bool isConfigured; private static int backendTimeout; @@ -28,10 +28,7 @@ static Transport() Configure(); } - internal static bool IsAvailable - { - get { return isConfigured && Client != null; } - } + internal static bool IsAvailable => isConfigured && Client != null; internal static InstanaHttpClient? Client { get; set; } @@ -39,56 +36,50 @@ internal static async Task SendSpansAsync(ConcurrentQueue spanQueue { try { - using (MemoryStream sendBuffer = new MemoryStream(TracesBuffer)) + using var sendBuffer = new MemoryStream(TracesBuffer); + using var writer = new StreamWriter(sendBuffer); + await writer.WriteAsync("{\"spans\":[").ConfigureAwait(false); + var first = true; + + // peek instead of dequeue, because we don't yet know whether the next span + // fits within our MULTI_SPAN_BUFFER_LIMIT + while (spanQueue.TryPeek(out var span) && sendBuffer.Position < MultiSpanBufferLimit) { - using (StreamWriter writer = new StreamWriter(sendBuffer)) + if (!first) { - await writer.WriteAsync("{\"spans\":[").ConfigureAwait(false); - bool first = true; - - // peek instead of dequeue, because we don't yet know whether the next span - // fits within our MULTI_SPAN_BUFFER_LIMIT - while (spanQueue.TryPeek(out InstanaSpan span) && sendBuffer.Position < MultiSpanBufferLimit) - { - if (!first) - { - await writer.WriteAsync(",").ConfigureAwait(false); - } - - await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer).ConfigureAwait(false); - await writer.FlushAsync().ConfigureAwait(false); - - first = false; - - // Now we can dequeue. Note, this means we'll be giving up/losing - // this span if we fail to send for any reason. - spanQueue.TryDequeue(out _); - } - - await writer.WriteAsync("]}").ConfigureAwait(false); - await writer.FlushAsync().ConfigureAwait(false); - - long length = sendBuffer.Position; - sendBuffer.Position = 0; - sendBuffer.SetLength(length); - - HttpContent content = new StreamContent(sendBuffer, (int)length); - content.Headers.ContentType = MEDIAHEADER; - content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(CultureInfo.InvariantCulture)); - - using (var httpMsg = new HttpRequestMessage() - { - Method = HttpMethod.Post, - RequestUri = new Uri(bundleUrl), - }) - { - httpMsg.Content = content; - if (Client != null) - { - await Client.SendAsync(httpMsg).ConfigureAwait(false); - } - } + await writer.WriteAsync(",").ConfigureAwait(false); } + + await InstanaSpanSerializer.SerializeToStreamWriterAsync(span, writer).ConfigureAwait(false); + await writer.FlushAsync().ConfigureAwait(false); + + first = false; + + // Now we can dequeue. Note, this means we'll be giving up/losing + // this span if we fail to send for any reason. + spanQueue.TryDequeue(out _); + } + + await writer.WriteAsync("]}").ConfigureAwait(false); + await writer.FlushAsync().ConfigureAwait(false); + + var length = sendBuffer.Position; + sendBuffer.Position = 0; + sendBuffer.SetLength(length); + + HttpContent content = new StreamContent(sendBuffer, (int)length); + content.Headers.ContentType = MEDIAHEADER; + content.Headers.Add("X-INSTANA-TIME", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(CultureInfo.InvariantCulture)); + + using var httpMsg = new HttpRequestMessage() + { + Method = HttpMethod.Post, + RequestUri = new Uri(bundleUrl), + }; + httpMsg.Content = content; + if (Client != null) + { + await Client.SendAsync(httpMsg).ConfigureAwait(false); } } catch (Exception e) @@ -148,8 +139,8 @@ private static void ConfigureBackendClient() #pragma warning disable CA2000 var configuredHandler = new HttpClientHandler(); #pragma warning restore CA2000 - string proxy = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_PROXY); - if (Uri.TryCreate(proxy, UriKind.Absolute, out Uri proxyAddress)) + var proxy = Environment.GetEnvironmentVariable(InstanaExporterConstants.ENVVAR_INSTANA_ENDPOINT_PROXY); + if (Uri.TryCreate(proxy, UriKind.Absolute, out var proxyAddress)) { configuredHandler.Proxy = new WebProxy(proxyAddress, true); configuredHandler.UseProxy = true; diff --git a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs index aa77513e7a..1c2fc4ad23 100644 --- a/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs +++ b/src/OpenTelemetry.Exporter.Instana/InstanaExporter.cs @@ -12,42 +12,22 @@ namespace OpenTelemetry.Exporter.Instana; internal sealed class InstanaExporter : BaseExporter { private readonly IActivityProcessor activityProcessor; - private ISpanSender spanSender = new SpanSender(); - private IInstanaExporterHelper instanaExporterHelper = new InstanaExporterHelper(); private bool shutdownCalled; public InstanaExporter(IActivityProcessor? activityProcessor = null) { - if (activityProcessor != null) + this.activityProcessor = activityProcessor ?? new DefaultActivityProcessor { - this.activityProcessor = activityProcessor; - } - else - { - this.activityProcessor = new DefaultActivityProcessor + NextProcessor = new TagsActivityProcessor { - NextProcessor = new TagsActivityProcessor - { - NextProcessor = new EventsActivityProcessor - { - NextProcessor = new ErrorActivityProcessor(), - }, - }, - }; - } + NextProcessor = new EventsActivityProcessor { NextProcessor = new ErrorActivityProcessor() }, + }, + }; } - internal ISpanSender SpanSender - { - get { return this.spanSender; } - set { this.spanSender = value; } - } + internal ISpanSender SpanSender { get; set; } = new SpanSender(); - internal IInstanaExporterHelper InstanaExporterHelper - { - get { return this.instanaExporterHelper; } - set { this.instanaExporterHelper = value; } - } + internal IInstanaExporterHelper InstanaExporterHelper { get; set; } = new InstanaExporterHelper(); public override ExportResult Export(in Batch batch) { @@ -56,13 +36,13 @@ public override ExportResult Export(in Batch batch) return ExportResult.Failure; } - From from = new From(); - if (this.instanaExporterHelper.IsWindows()) + var from = new From(); + if (this.InstanaExporterHelper.IsWindows()) { from = new From { E = Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture) }; } - string serviceName = this.ExtractServiceName(ref from); + var serviceName = this.ExtractServiceName(ref from); foreach (var activity in batch) { @@ -71,8 +51,8 @@ public override ExportResult Export(in Batch batch) continue; } - InstanaSpan span = this.ParseActivityAsync(activity, serviceName, from).Result; - this.spanSender.Enqueue(span); + var span = this.ParseActivityAsync(activity, serviceName, from).Result; + this.SpanSender.Enqueue(span); } return ExportResult.Success; @@ -98,11 +78,11 @@ protected override bool OnForceFlush(int timeoutMilliseconds) private string ExtractServiceName(ref From from) { - string serviceName = string.Empty; - string serviceId = string.Empty; - string processId = string.Empty; - string hostId = string.Empty; - var resource = this.instanaExporterHelper.GetParentProviderResource(this); + var serviceName = string.Empty; + var serviceId = string.Empty; + var processId = string.Empty; + var hostId = string.Empty; + var resource = this.InstanaExporterHelper.GetParentProviderResource(this); if (resource != Resource.Empty && resource.Attributes.Any()) { foreach (var resourceAttribute in resource.Attributes) @@ -154,7 +134,7 @@ private string ExtractServiceName(ref From from) private async Task ParseActivityAsync(Activity activity, string? serviceName = null, From? from = null) { - InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); + var instanaSpan = InstanaSpanFactory.CreateSpan(); await this.activityProcessor.ProcessAsync(activity, instanaSpan).ConfigureAwait(false); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs index e83dc8c27b..d076911310 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaExporterTests.cs @@ -32,12 +32,12 @@ public void Export() SpanSender = this.spanSender, }; - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); activity.TraceStateString = "TraceStateString"; - Activity[] activities = new Activity[1] { activity }; - Batch batch = new Batch(activities, activities.Length); + Activity[] activities = [activity]; + var batch = new Batch(activities, activities.Length); var result = this.instanaExporter.Export(in batch); Assert.Equal(ExportResult.Success, result); @@ -65,11 +65,11 @@ public void Export_ProcessPidDoesNotExistButServiceIdExists() SpanSender = this.spanSender, }; - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); - Activity[] activities = new Activity[1] { activity }; - Batch batch = new Batch(activities, activities.Length); + Activity[] activities = [activity]; + var batch = new Batch(activities, activities.Length); var result = this.instanaExporter.Export(in batch); Assert.Equal(ExportResult.Success, result); @@ -89,13 +89,13 @@ public void Export_ExporterIsShotDown() SpanSender = this.spanSender, }; - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); this.instanaExporter.Shutdown(); - Activity[] activities = new Activity[1] { activity }; - Batch batch = new Batch(activities, activities.Length); + Activity[] activities = [activity]; + var batch = new Batch(activities, activities.Length); var result = this.instanaExporter.Export(in batch); Assert.Equal(ExportResult.Failure, result); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs index 3e1e14f773..f53310e25c 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanFactoryTests.cs @@ -12,7 +12,7 @@ public static class InstanaSpanFactoryTests public static void CreateSpan() { _ = new InstanaSpanFactory(); - InstanaSpan instanaSpan = InstanaSpanFactory.CreateSpan(); + var instanaSpan = InstanaSpanFactory.CreateSpan(); Assert.NotNull(instanaSpan); Assert.NotNull(instanaSpan.TransformInfo); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs index 389acfdf74..6063f4befc 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanSerializerTests.cs @@ -13,7 +13,7 @@ public static class InstanaSpanSerializerTests [Fact] public static async Task SerializeToStreamWriterAsync() { - InstanaSpan instanaOtelSpan = InstanaSpanFactory.CreateSpan(); + var instanaOtelSpan = InstanaSpanFactory.CreateSpan(); instanaOtelSpan.F = new Implementation.From { E = "12345", H = "localhost" }; instanaOtelSpan.N = "otel"; instanaOtelSpan.T = "hexNumberT1234"; @@ -23,45 +23,43 @@ public static async Task SerializeToStreamWriterAsync() instanaOtelSpan.D = 123456; instanaOtelSpan.Lt = "hexNumberLT1234567890123"; instanaOtelSpan.Tp = true; - instanaOtelSpan.Data.Tags = new Dictionary(); - instanaOtelSpan.Data.Tags["tag1Key"] = "tag1Vale"; - instanaOtelSpan.Data.Tags["tag2Key"] = "tag2Vale"; - instanaOtelSpan.Data.data = new Dictionary(); - instanaOtelSpan.Data.data["data1Key"] = "data1Vale"; - instanaOtelSpan.Data.data["data2Key"] = "data2Vale"; - instanaOtelSpan.Data.Events = new List - { + instanaOtelSpan.Data.Tags = new Dictionary { ["tag1Key"] = "tag1Vale", ["tag2Key"] = "tag2Vale" }; + instanaOtelSpan.Data.data = new Dictionary { ["data1Key"] = "data1Vale", ["data2Key"] = "data2Vale" }; + instanaOtelSpan.Data.Events = + [ new() { - Name = "testEvent", Ts = 111111, + Name = "testEvent", + Ts = 111111, Tags = new Dictionary { { "eventTagKey", "eventTagValue" } }, }, + new() { - Name = "testEvent2", Ts = 222222, + Name = "testEvent2", + Ts = 222222, Tags = new Dictionary { { "eventTag2Key", "eventTag2Value" } }, - }, - }; + } + + ]; InstanaSpanTest? span; - using (MemoryStream sendBuffer = new MemoryStream(new byte[4096000])) + using (var sendBuffer = new MemoryStream(new byte[4096000])) { - using (StreamWriter writer = new StreamWriter(sendBuffer)) - { - await InstanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); - await writer.FlushAsync(); - long length = sendBuffer.Position; - sendBuffer.Position = 0; - sendBuffer.SetLength(length); + using var writer = new StreamWriter(sendBuffer); + await InstanaSpanSerializer.SerializeToStreamWriterAsync(instanaOtelSpan, writer); + await writer.FlushAsync(); + var length = sendBuffer.Position; + sendBuffer.Position = 0; + sendBuffer.SetLength(length); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new JavaScriptDateTimeConverter()); - serializer.NullValueHandling = NullValueHandling.Ignore; + var serializer = new JsonSerializer(); + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + serializer.NullValueHandling = NullValueHandling.Ignore; - TextReader textReader = new StreamReader(sendBuffer); - JsonReader reader = new JsonTextReader(textReader); - span = serializer.Deserialize(reader); - } + TextReader textReader = new StreamReader(sendBuffer); + JsonReader reader = new JsonTextReader(textReader); + span = serializer.Deserialize(reader); } Assert.NotNull(span); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs index 201b0f3918..32bfef6851 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/InstanaSpanTest.cs @@ -145,23 +145,19 @@ public override bool CanConvert(Type objectType) } else { - JObject obj = JObject.Load(reader); + var obj = JObject.Load(reader); var data = obj.Root; if (data != null) { var newData = new Data(); foreach (var field in data) { - if (((JProperty)field).Name == "tags" || - ((JProperty)field).Name == "events") + if (((JProperty)field).Name is "tags" or "events") { continue; } - if (newData.data == null) - { - newData.data = new Dictionary(); - } + newData.data ??= []; newData.data[((JProperty)field).Name] = ((JProperty)field).Value.ToString(); } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs index 85ae5c3577..bdf6907982 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/DefaultActivityProcessorTests.cs @@ -10,16 +10,16 @@ namespace OpenTelemetry.Exporter.Instana.Tests.Processors; public class DefaultActivityProcessorTests { - private DefaultActivityProcessor defaultActivityProcessor = new DefaultActivityProcessor(); + private readonly DefaultActivityProcessor defaultActivityProcessor = new(); [Fact] public async Task ProcessAsync() { - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.Start(); await Task.Delay(200); activity.Stop(); - InstanaSpan instanaSpan = new InstanaSpan(); + var instanaSpan = new InstanaSpan(); await this.defaultActivityProcessor.ProcessAsync(activity, instanaSpan); Assert.False(string.IsNullOrEmpty(instanaSpan.S)); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs index 18c37f236a..216eae523c 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -10,14 +10,14 @@ namespace OpenTelemetry.Exporter.Instana.Tests.Processors; public class ErrorActivityProcessorTests { - private ErrorActivityProcessor errorActivityProcessor = new ErrorActivityProcessor(); + private readonly ErrorActivityProcessor errorActivityProcessor = new(); [Fact] public async Task Process_ErrorStatusCodeIsSet() { - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.SetStatus(ActivityStatusCode.Error, "TestErrorDesc"); - InstanaSpan instanaSpan = new InstanaSpan(); + var instanaSpan = new InstanaSpan(); await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); Assert.True(instanaSpan.Ec == 1); @@ -30,8 +30,8 @@ public async Task Process_ErrorStatusCodeIsSet() [Fact] public async Task Process_ExistsExceptionEvent() { - Activity activity = new Activity("testOperationName"); - InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() { HasExceptionEvent = true } }; + var activity = new Activity("testOperationName"); + var instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() { HasExceptionEvent = true } }; await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); Assert.True(instanaSpan.Ec == 1); @@ -40,8 +40,8 @@ public async Task Process_ExistsExceptionEvent() [Fact] public async Task Process_NoError() { - Activity activity = new Activity("testOperationName"); - InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; + var activity = new Activity("testOperationName"); + var instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); Assert.True(instanaSpan.Ec == 0); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index ce3b79dc8e..35452ace15 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -12,29 +12,27 @@ namespace OpenTelemetry.Exporter.Instana.Tests.Processors; public class EventsActivityProcessorTests { - private EventsActivityProcessor eventsActivityProcessor = new EventsActivityProcessor(); + private readonly EventsActivityProcessor eventsActivityProcessor = new(); [Fact] public async Task ProcessAsync() { - var activityTagsCollection = new ActivityTagsCollection(); - activityTagsCollection.Add(new KeyValuePair("eventTagKey", "eventTagValue")); + var activityTagsCollection = new ActivityTagsCollection { new KeyValuePair("eventTagKey", "eventTagValue") }; var activityEvent = new ActivityEvent( "testActivityEvent", DateTimeOffset.MinValue, activityTagsCollection); - var activityTagsCollection2 = new ActivityTagsCollection(); - activityTagsCollection2.Add(new KeyValuePair("eventTagKey2", "eventTagValue2")); + var activityTagsCollection2 = new ActivityTagsCollection { new KeyValuePair("eventTagKey2", "eventTagValue2") }; var activityEvent2 = new ActivityEvent( "testActivityEvent2", DateTimeOffset.MaxValue, activityTagsCollection2); - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.AddEvent(activityEvent); activity.AddEvent(activityEvent2); - InstanaSpan instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; + var instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; if (this.eventsActivityProcessor != null) { await this.eventsActivityProcessor.ProcessAsync(activity, instanaSpan); @@ -46,7 +44,7 @@ public async Task ProcessAsync() Assert.True(instanaSpan.Data.Events[0].Name == "testActivityEvent"); Assert.True(instanaSpan.Data.Events[0].Ts > 0); Assert.NotNull(instanaSpan.Data?.Events[0]?.Tags); - string? eventTagValue = string.Empty; + var eventTagValue = string.Empty; _ = instanaSpan.Data.Events[0].Tags?.TryGetValue("eventTagKey", out eventTagValue); Assert.True(eventTagValue == "eventTagValue"); Assert.True(instanaSpan.Data.Events[1].Name == "testActivityEvent2"); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs index b70bc79bf6..fb2a4d05a2 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/TagsActivityProcessorTests.cs @@ -10,17 +10,17 @@ namespace OpenTelemetry.Exporter.Instana.Tests.Processors; public class TagsActivityProcessorTests { - private TagsActivityProcessor tagsActivityProcessor = new TagsActivityProcessor(); + private readonly TagsActivityProcessor tagsActivityProcessor = new(); [Fact] public async Task ProcessAsync_StatusTagsExist() { - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.AddTag("otel.status_code", "testStatusCode"); activity.AddTag("otel.status_description", "testStatusDescription"); activity.AddTag("otel.testTag", "testTag"); - InstanaSpan instanaSpan = new InstanaSpan(); + var instanaSpan = new InstanaSpan(); await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); Assert.NotNull(instanaSpan.Data); @@ -33,10 +33,10 @@ public async Task ProcessAsync_StatusTagsExist() [Fact] public async Task ProcessAsync_StatusTagsDoNotExist() { - Activity activity = new Activity("testOperationName"); + var activity = new Activity("testOperationName"); activity.AddTag("otel.testTag", "testTag"); - InstanaSpan instanaSpan = new InstanaSpan(); + var instanaSpan = new InstanaSpan(); await this.tagsActivityProcessor.ProcessAsync(activity, instanaSpan); Assert.NotNull(instanaSpan.Data); diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs b/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs index bf48310c1f..7a88315de0 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/TestInstanaExporterHelper.cs @@ -8,7 +8,7 @@ namespace OpenTelemetry.Exporter.Instana.Tests; internal class TestInstanaExporterHelper : IInstanaExporterHelper { - public Dictionary Attributes { get; } = new(); + public Dictionary Attributes { get; } = []; public Resource GetParentProviderResource(BaseExporter otelExporter) { From 3fc14157e0b05e4902deabc68774850230088da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 30 Oct 2024 06:39:58 +0100 Subject: [PATCH 1383/1499] [repo/AWS.Sampler] Prepare to .NET9 (#2266) --- .../AWSXRayRemoteSampler.cs | 22 +++---- .../AWSXRaySamplerClient.cs | 6 +- .../FallbackSampler.cs | 11 +--- src/OpenTelemetry.Sampler.AWS/Matcher.cs | 23 +++----- src/OpenTelemetry.Sampler.AWS/RateLimiter.cs | 4 +- src/OpenTelemetry.Sampler.AWS/RulesCache.cs | 17 ++---- src/OpenTelemetry.Sampler.AWS/SamplingRule.cs | 2 +- .../SamplingRuleApplier.cs | 58 +++++++------------ src/OpenTelemetry.Sampler.AWS/SystemClock.cs | 4 +- src/Shared/Guard.cs | 9 +-- .../TestAWSXRayRemoteSampler.cs | 19 +++--- .../TestAWSXRaySamplerClient.cs | 20 +++---- .../TestClock.cs | 4 +- .../TestMatcher.cs | 2 +- .../TestRateLimiter.cs | 30 +++++----- .../TestRateLimitingSampler.cs | 2 +- .../TestRulesCache.cs | 8 +-- .../TestSamplingRuleApplier.cs | 44 +++++++------- test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs | 8 +-- 19 files changed, 127 insertions(+), 166 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs index 802f72351a..cc1836fc0e 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs @@ -14,7 +14,7 @@ public sealed class AWSXRayRemoteSampler : Trace.Sampler, IDisposable { internal static readonly TimeSpan DefaultTargetInterval = TimeSpan.FromSeconds(10); - private static readonly Random Random = new Random(); + private static readonly Random Random = new(); private bool isFallBackEventToWriteSwitch = true; [SuppressMessage("Performance", "CA5394: Do not use insecure randomness", Justification = "Secure random is not required for jitters.")] @@ -111,9 +111,9 @@ public void Dispose() Justification = "using insecure random is fine here since clientId doesn't need to be secure.")] private static string GenerateClientId() { - char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - char[] clientIdChars = new char[24]; - for (int i = 0; i < clientIdChars.Length; i++) + char[] hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; + var clientIdChars = new char[24]; + for (var i = 0; i < clientIdChars.Length; i++) { clientIdChars[i] = hex[Random.Next(hex.Length)]; } @@ -133,7 +133,7 @@ private void Dispose(bool disposing) private async void GetAndUpdateRules(object? state) { - List rules = await this.Client.GetSamplingRules().ConfigureAwait(false); + var rules = await this.Client.GetSamplingRules().ConfigureAwait(false); this.RulesCache.UpdateRules(rules); @@ -143,14 +143,14 @@ private async void GetAndUpdateRules(object? state) private async void GetAndUpdateTargets(object? state) { - List statistics = this.RulesCache.Snapshot(this.Clock.Now()); + var statistics = this.RulesCache.Snapshot(this.Clock.Now()); - GetSamplingTargetsRequest request = new GetSamplingTargetsRequest(statistics); - GetSamplingTargetsResponse? response = await this.Client.GetSamplingTargets(request).ConfigureAwait(false); + var request = new GetSamplingTargetsRequest(statistics); + var response = await this.Client.GetSamplingTargets(request).ConfigureAwait(false); if (response != null) { - Dictionary targets = new Dictionary(); - foreach (SamplingTargetDocument target in response.SamplingTargetDocuments) + Dictionary targets = []; + foreach (var target in response.SamplingTargetDocuments) { if (target.RuleName != null) { @@ -174,7 +174,7 @@ private async void GetAndUpdateTargets(object? state) // schedule next target poll var nextTargetFetchTime = this.RulesCache.NextTargetFetchTime(); - TimeSpan nextTargetFetchInterval = nextTargetFetchTime.Subtract(this.Clock.Now()); + var nextTargetFetchInterval = nextTargetFetchTime.Subtract(this.Clock.Now()); if (nextTargetFetchInterval < TimeSpan.Zero) { nextTargetFetchInterval = DefaultTargetInterval; diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs index 758a0817fd..a99b090261 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs @@ -26,7 +26,7 @@ public AWSXRaySamplerClient(string host) public async Task> GetSamplingRules() { - List samplingRules = new List(); + List samplingRules = []; using (var request = new HttpRequestMessage(HttpMethod.Post, this.getSamplingRulesEndpoint) { @@ -37,7 +37,7 @@ public async Task> GetSamplingRules() try { - GetSamplingRulesResponse? getSamplingRulesResponse = JsonSerializer + var getSamplingRulesResponse = JsonSerializer #if NET .Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingRulesResponse); #else @@ -89,7 +89,7 @@ public async Task> GetSamplingRules() try { - GetSamplingTargetsResponse? getSamplingTargetsResponse = JsonSerializer + var getSamplingTargetsResponse = JsonSerializer #if NET .Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingTargetsResponse); #else diff --git a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs index bf92a8ec97..356ecf4570 100644 --- a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs @@ -9,23 +9,16 @@ internal class FallbackSampler : Trace.Sampler { private readonly Trace.Sampler reservoirSampler; private readonly Trace.Sampler fixedRateSampler; - private readonly Clock clock; public FallbackSampler(Clock clock) { - this.clock = clock; this.reservoirSampler = new ParentBasedSampler(new RateLimitingSampler(1, clock)); this.fixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(0.05)); } public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) { - SamplingResult result = this.reservoirSampler.ShouldSample(in samplingParameters); - if (result.Decision != SamplingDecision.Drop) - { - return result; - } - - return this.fixedRateSampler.ShouldSample(in samplingParameters); + var result = this.reservoirSampler.ShouldSample(in samplingParameters); + return result.Decision != SamplingDecision.Drop ? result : this.fixedRateSampler.ShouldSample(in samplingParameters); } } diff --git a/src/OpenTelemetry.Sampler.AWS/Matcher.cs b/src/OpenTelemetry.Sampler.AWS/Matcher.cs index 3c51cf16d0..a08f3a67b7 100644 --- a/src/OpenTelemetry.Sampler.AWS/Matcher.cs +++ b/src/OpenTelemetry.Sampler.AWS/Matcher.cs @@ -36,9 +36,9 @@ public static bool WildcardMatch(string? text, string? globPattern) // it is faster to check if we need a regex comparison than // doing always regex comparison, even where we may not need it. - foreach (char c in globPattern) + foreach (var c in globPattern) { - if (c == '*' || c == '?') + if (c is '*' or '?') { return Regex.IsMatch(text, ToRegexPattern(globPattern)); } @@ -59,7 +59,7 @@ public static bool AttributeMatch(IEnumerable>? ta return false; } - int matchedCount = 0; + var matchedCount = 0; foreach (var tag in tags) { @@ -77,23 +77,18 @@ public static bool AttributeMatch(IEnumerable>? ta } } - if (matchedCount == ruleAttributes.Count) - { - return true; - } - - return false; + return matchedCount == ruleAttributes.Count; } private static string ToRegexPattern(string globPattern) { - int tokenStart = -1; - StringBuilder patternBuilder = new StringBuilder(); + var tokenStart = -1; + var patternBuilder = new StringBuilder(); - for (int i = 0; i < globPattern.Length; i++) + for (var i = 0; i < globPattern.Length; i++) { - char c = globPattern[i]; - if (c == '*' || c == '?') + var c = globPattern[i]; + if (c is '*' or '?') { if (tokenStart != -1) { diff --git a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs index 6dfc5b5099..5745d669fb 100644 --- a/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs +++ b/src/OpenTelemetry.Sampler.AWS/RateLimiter.cs @@ -20,7 +20,7 @@ internal RateLimiter(double creditsPerSecond, double maxBalance, Clock clock) public bool TrySpend(double itemCost) { - long cost = (long)(itemCost / this.creditsPerMillisecond); + var cost = (long)(itemCost / this.creditsPerMillisecond); long currentMillis; long currentBalanceMillis; long availableBalanceAfterWithdrawal; @@ -29,7 +29,7 @@ public bool TrySpend(double itemCost) { currentBalanceMillis = Interlocked.Read(ref this.currentBalance); currentMillis = this.clock.NowInMilliSeconds(); - long currentAvailableBalance = currentMillis - currentBalanceMillis; + var currentAvailableBalance = currentMillis - currentBalanceMillis; if (currentAvailableBalance > this.maxBalance) { currentAvailableBalance = this.maxBalance; diff --git a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs index 33c4cfbb39..deb00da679 100644 --- a/src/OpenTelemetry.Sampler.AWS/RulesCache.cs +++ b/src/OpenTelemetry.Sampler.AWS/RulesCache.cs @@ -20,7 +20,7 @@ public RulesCache(Clock clock, string clientId, Resource resource, Trace.Sampler this.ClientId = clientId; this.Resource = resource; this.FallbackSampler = fallbackSampler; - this.RuleAppliers = new List(); + this.RuleAppliers = []; this.UpdatedAt = this.Clock.Now(); } @@ -54,7 +54,7 @@ public void UpdateRules(List newRules) // sort the new rules newRules.Sort((x, y) => x.CompareTo(y)); - List newRuleAppliers = new List(); + List newRuleAppliers = []; foreach (var rule in newRules) { // If the ruleApplier already exists in the current list of appliers, then we reuse it. @@ -104,7 +104,7 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters) public List Snapshot(DateTimeOffset now) { - List snapshots = new List(); + List snapshots = []; foreach (var ruleApplier in this.RuleAppliers) { snapshots.Add(ruleApplier.Snapshot(now)); @@ -115,10 +115,10 @@ public List Snapshot(DateTimeOffset now) public void UpdateTargets(Dictionary targets) { - List newRuleAppliers = new List(); + List newRuleAppliers = []; foreach (var ruleApplier in this.RuleAppliers) { - targets.TryGetValue(ruleApplier.RuleName, out SamplingTargetDocument? target); + targets.TryGetValue(ruleApplier.RuleName, out var target); if (target != null) { newRuleAppliers.Add(ruleApplier.WithTarget(target, this.Clock.Now())); @@ -154,12 +154,7 @@ public DateTimeOffset NextTargetFetchTime() .Select(r => r.NextSnapshotTime) .Min(); - if (minPollingTime < this.Clock.Now()) - { - return defaultPollingTime; - } - - return minPollingTime; + return minPollingTime < this.Clock.Now() ? defaultPollingTime : minPollingTime; } public void Dispose() diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs index bba8f75088..fa14605f90 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRule.cs @@ -73,7 +73,7 @@ public SamplingRule( public int CompareTo(SamplingRule? other) { - int result = this.Priority.CompareTo(other?.Priority); + var result = this.Priority.CompareTo(other?.Priority); if (result == 0) { result = string.Compare(this.RuleName, other?.RuleName, StringComparison.Ordinal); diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index b5910499c5..73a59c17bf 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -116,25 +116,18 @@ public bool Matches(SamplingParameters samplingParameters, Resource resource) // URL path may be in either http.target or http.url if (httpTarget == null && httpUrl != null) { - int schemeEndIndex = httpUrl.IndexOf("://", StringComparison.Ordinal); + var schemeEndIndex = httpUrl.IndexOf("://", StringComparison.Ordinal); // Per spec, http.url is always populated with scheme://host/target. If scheme doesn't // match, assume it's bad instrumentation and ignore. if (schemeEndIndex > 0) { - int pathIndex = httpUrl.IndexOf('/', schemeEndIndex + "://".Length); - if (pathIndex < 0) - { - httpTarget = "/"; - } - else - { - httpTarget = httpUrl.Substring(pathIndex); - } + var pathIndex = httpUrl.IndexOf('/', schemeEndIndex + "://".Length); + httpTarget = pathIndex < 0 ? "/" : httpUrl.Substring(pathIndex); } } - string serviceName = (string)resource.Attributes.FirstOrDefault(kvp => + var serviceName = (string)resource.Attributes.FirstOrDefault(kvp => kvp.Key.Equals("service.name", StringComparison.Ordinal)).Value; return Matcher.AttributeMatch(samplingParameters.Tags, this.Rule.Attributes) && @@ -149,8 +142,8 @@ public bool Matches(SamplingParameters samplingParameters, Resource resource) public SamplingResult ShouldSample(in SamplingParameters samplingParameters) { Interlocked.Increment(ref this.Statistics.RequestCount); - bool reservoirExpired = this.Clock.Now() >= this.ReservoirEndTime; - SamplingResult result = !reservoirExpired + var reservoirExpired = this.Clock.Now() >= this.ReservoirEndTime; + var result = !reservoirExpired ? this.ReservoirSampler.ShouldSample(in samplingParameters) : new SamplingResult(SamplingDecision.Drop); @@ -178,13 +171,13 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters) // take the snapshot and reset the statistics. public SamplingStatisticsDocument Snapshot(DateTimeOffset now) { - double timestamp = this.Clock.ToDouble(now); + var timestamp = this.Clock.ToDouble(now); - long matchedRequests = Interlocked.Exchange(ref this.Statistics.RequestCount, 0L); - long sampledRequests = Interlocked.Exchange(ref this.Statistics.SampleCount, 0L); - long borrowedRequests = Interlocked.Exchange(ref this.Statistics.BorrowCount, 0L); + var matchedRequests = Interlocked.Exchange(ref this.Statistics.RequestCount, 0L); + var sampledRequests = Interlocked.Exchange(ref this.Statistics.SampleCount, 0L); + var borrowedRequests = Interlocked.Exchange(ref this.Statistics.BorrowCount, 0L); - SamplingStatisticsDocument statiscticsDocument = new SamplingStatisticsDocument( + var statiscticsDocument = new SamplingStatisticsDocument( this.ClientId, this.RuleName, matchedRequests, @@ -197,27 +190,22 @@ public SamplingStatisticsDocument Snapshot(DateTimeOffset now) public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOffset now) { - Trace.Sampler newFixedRateSampler = target.FixedRate != null + var newFixedRateSampler = target.FixedRate != null ? new ParentBasedSampler(new TraceIdRatioBasedSampler(target.FixedRate.Value)) : this.FixedRateSampler; Trace.Sampler newReservoirSampler = new AlwaysOffSampler(); - DateTimeOffset newReservoirEndTime = DateTimeOffset.MaxValue; + var newReservoirEndTime = DateTimeOffset.MaxValue; if (target.ReservoirQuota != null && target.ReservoirQuotaTTL != null) { - if (target.ReservoirQuota > 0) - { - newReservoirSampler = new ParentBasedSampler(new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock)); - } - else - { - newReservoirSampler = new AlwaysOffSampler(); - } + newReservoirSampler = target.ReservoirQuota > 0 + ? new ParentBasedSampler(new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock)) + : new AlwaysOffSampler(); newReservoirEndTime = this.Clock.ToDateTime(target.ReservoirQuotaTTL.Value); } - DateTimeOffset newNextSnapshotTime = target.Interval != null + var newNextSnapshotTime = target.Interval != null ? now.AddSeconds(target.Interval.Value) : now.Add(AWSXRayRemoteSampler.DefaultTargetInterval); @@ -235,21 +223,17 @@ public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOff private static string GetServiceType(Resource resource) { - string cloudPlatform = (string)resource.Attributes.FirstOrDefault(kvp => + var cloudPlatform = (string)resource.Attributes.FirstOrDefault(kvp => kvp.Key.Equals("cloud.platform", StringComparison.Ordinal)).Value; - if (cloudPlatform == null) - { - return string.Empty; - } - - return Matcher.XRayCloudPlatform.TryGetValue(cloudPlatform, out string? value) ? value : string.Empty; + return cloudPlatform == null ? string.Empty : + Matcher.XRayCloudPlatform.TryGetValue(cloudPlatform, out var value) ? value : string.Empty; } private static string GetArn(in SamplingParameters samplingParameters, Resource resource) { // currently the aws resource detectors only capture ARNs for ECS and Lambda environments. - string? arn = (string?)resource.Attributes.FirstOrDefault(kvp => + var arn = (string?)resource.Attributes.FirstOrDefault(kvp => kvp.Key.Equals("aws.ecs.container.arn", StringComparison.Ordinal)).Value; if (arn != null) diff --git a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs index c079d58527..8c960542c7 100644 --- a/src/OpenTelemetry.Sampler.AWS/SystemClock.cs +++ b/src/OpenTelemetry.Sampler.AWS/SystemClock.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Sampler.AWS; // A clock based on System time. internal class SystemClock : Clock { - private static readonly SystemClock Instance = new SystemClock(); + private static readonly SystemClock Instance = new(); private static readonly DateTimeOffset EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); @@ -37,7 +37,7 @@ public override DateTimeOffset ToDateTime(double seconds) public override double ToDouble(DateTimeOffset dateTime) { var current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); - double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; + var timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; return timestamp; } } diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index 2e21736b00..a00cfafb09 100644 --- a/src/Shared/Guard.cs +++ b/src/Shared/Guard.cs @@ -174,12 +174,9 @@ public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression(nam [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T ThrowIfNotOfType([NotNull] object? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) { - if (value is not T result) - { - throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'"); - } - - return result; + return value is not T result + ? throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'") + : result; } [DebuggerHidden] diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index 3c629e79c6..e61cb76d31 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -16,10 +16,10 @@ public class TestAWSXRayRemoteSampler [Fact] public void TestSamplerWithConfiguration() { - TimeSpan pollingInterval = TimeSpan.FromSeconds(5); - string endpoint = "http://localhost:3000"; + var pollingInterval = TimeSpan.FromSeconds(5); + var endpoint = "http://localhost:3000"; - AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) + var sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) .SetPollingInterval(pollingInterval) .SetEndpoint(endpoint) .Build(); @@ -33,7 +33,7 @@ public void TestSamplerWithConfiguration() [Fact] public void TestSamplerWithDefaults() { - AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); + var sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); Assert.Equal(TimeSpan.FromMinutes(5), sampler.PollingInterval); Assert.Equal("http://localhost:2000", sampler.Endpoint); @@ -45,11 +45,11 @@ public void TestSamplerWithDefaults() public void TestSamplerUpdateAndSample() { // setup mock server - TestClock clock = new TestClock(); - WireMockServer mockServer = WireMockServer.Start(); + var clock = new TestClock(); + var mockServer = WireMockServer.Start(); // create sampler - AWSXRayRemoteSampler sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) + var sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) .SetPollingInterval(TimeSpan.FromMilliseconds(10)) .SetEndpoint(mockServer.Url!) .SetClock(clock) @@ -100,10 +100,7 @@ private SamplingDecision DoSample(Trace.Sampler sampler, string serviceName) ActivityTraceId.CreateRandom(), "myActivityName", ActivityKind.Server, - new List> - { - new("test", serviceName), - }, + [new("test", serviceName)], null); return sampler.ShouldSample(samplingParams).Decision; diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs index 401a48a026..42f99c5e6c 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRaySamplerClient.cs @@ -82,7 +82,7 @@ public async Task TestGetSamplingRulesMalformed() .RespondWith( Response.Create().WithStatusCode(200).WithHeader("Content-Type", "application/json").WithBody("notJson")); - List rules = await this.client.GetSamplingRules(); + var rules = await this.client.GetSamplingRules(); Assert.Empty(rules); } @@ -90,12 +90,12 @@ public async Task TestGetSamplingRulesMalformed() [Fact] public async Task TestGetSamplingTargets() { - TestClock clock = new TestClock(); + var clock = new TestClock(); this.CreateResponse("/SamplingTargets", "Data/GetSamplingTargetsResponse.json"); - var request = new GetSamplingTargetsRequest(new List - { + var request = new GetSamplingTargetsRequest( + [ new( "clientId", "rule1", @@ -117,7 +117,7 @@ public async Task TestGetSamplingTargets() 10, 2, clock.ToDouble(clock.Now())), - }); + ]); var targetsResponse = await this.client.GetSamplingTargets(request); Assert.NotNull(targetsResponse); @@ -145,14 +145,14 @@ public async Task TestGetSamplingTargets() [Fact] public async Task TestGetSamplingTargetsWithMalformed() { - TestClock clock = new TestClock(); + var clock = new TestClock(); this.mockServer .Given(Request.Create().WithPath("/SamplingTargets").UsingPost()) .RespondWith( Response.Create().WithStatusCode(200).WithHeader("Content-Type", "application/json").WithBody("notJson")); - var request = new GetSamplingTargetsRequest(new List - { + var request = new GetSamplingTargetsRequest( + [ new( "clientId", "rule1", @@ -160,7 +160,7 @@ public async Task TestGetSamplingTargetsWithMalformed() 50, 10, clock.ToDouble(clock.Now())), - }); + ]); var targetsResponse = await this.client.GetSamplingTargets(request); @@ -169,7 +169,7 @@ public async Task TestGetSamplingTargetsWithMalformed() private void CreateResponse(string endpoint, string filePath) { - string mockResponse = File.ReadAllText(filePath); + var mockResponse = File.ReadAllText(filePath); this.mockServer .Given(Request.Create().WithPath(endpoint).UsingPost()) .RespondWith( diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs index 7ddcb72daf..0cfe5c25cb 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestClock.cs @@ -35,8 +35,8 @@ public override DateTimeOffset ToDateTime(double seconds) public override double ToDouble(DateTimeOffset dateTime) { - TimeSpan current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); - double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; + var current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks); + var timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0; return timestamp; } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs index d0224d6c9b..e586079a61 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestMatcher.cs @@ -74,7 +74,7 @@ public void TestAttributeMatchingWithoutSpanTags() { "cow", "mooo" }, }; - Assert.False(Matcher.AttributeMatch(new List>(), ruleAttributes)); + Assert.False(Matcher.AttributeMatch([], ruleAttributes)); Assert.False(Matcher.AttributeMatch(null, ruleAttributes)); } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs index acb46916c0..c404f26163 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimiter.cs @@ -16,7 +16,7 @@ public class TestRateLimiter public void TestRateLimiterWholeNumber() { var testClock = new TestClock(); - RateLimiter limiter = new RateLimiter(2.0, 2.0, testClock); + var limiter = new RateLimiter(2.0, 2.0, testClock); Assert.True(limiter.TrySpend(1.0)); Assert.True(limiter.TrySpend(1.0)); @@ -44,8 +44,8 @@ public void TestRateLimiterWholeNumber() [Fact] public void TestRateLimiterLessThanOne() { - TestClock clock = new TestClock(); - RateLimiter limiter = new RateLimiter(0.5, 0.5, clock); + var clock = new TestClock(); + var limiter = new RateLimiter(0.5, 0.5, clock); Assert.True(limiter.TrySpend(0.25)); Assert.True(limiter.TrySpend(0.25)); @@ -72,8 +72,8 @@ public void TestRateLimiterLessThanOne() [Fact] public void TestRateLimiterMaxBalance() { - TestClock clock = new TestClock(); - RateLimiter limiter = new RateLimiter(0.1, 1.0, clock); + var clock = new TestClock(); + var limiter = new RateLimiter(0.1, 1.0, clock); clock.Advance(TimeSpan.FromMilliseconds(0.1)); Assert.True(limiter.TrySpend(1.0)); @@ -90,8 +90,8 @@ public void TestRateLimiterMaxBalance() [Fact] public void TestRateLimiterInitial() { - TestClock clock = new TestClock(); - RateLimiter limiter = new RateLimiter(1000, 100, clock); + var clock = new TestClock(); + var limiter = new RateLimiter(1000, 100, clock); Assert.True(limiter.TrySpend(100)); // consume initial (max) balance Assert.False(limiter.TrySpend(1)); @@ -115,18 +115,18 @@ public void TestRateLimiterInitial() [Fact] public async Task TestRateLimiterConcurrencyAsync() { - int numWorkers = 8; - int creditsPerWorker = 1000; - TestClock clock = new TestClock(); - RateLimiter limiter = new RateLimiter(1, numWorkers * creditsPerWorker, clock); - int count = 0; + var numWorkers = 8; + var creditsPerWorker = 1000; + var clock = new TestClock(); + var limiter = new RateLimiter(1, numWorkers * creditsPerWorker, clock); + var count = 0; List tasks = new(numWorkers); - for (int w = 0; w < numWorkers; ++w) + for (var w = 0; w < numWorkers; ++w) { - Task task = Task.Run(() => + var task = Task.Run(() => { - for (int i = 0; i < creditsPerWorker * 2; ++i) + for (var i = 0; i < creditsPerWorker * 2; ++i) { if (limiter.TrySpend(1)) { diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs index 090cf882b5..2eb3e1710a 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRateLimitingSampler.cs @@ -11,7 +11,7 @@ public class TestRateLimitingSampler [Fact] public void TestLimitsRate() { - TestClock clock = new TestClock(); + var clock = new TestClock(); Trace.Sampler sampler = new RateLimitingSampler(1, clock); Assert.Equal(SamplingDecision.RecordAndSample, sampler.ShouldSample(Utils.CreateSamplingParameters()).Decision); diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs index f0e6831989..d24d2457bf 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestRulesCache.cs @@ -44,7 +44,7 @@ public void TestUpdateRules() // update the default rule var newDefaultRule = this.CreateDefaultRule(10, 0.20); - cache.UpdateRules(new List { newDefaultRule }); + cache.UpdateRules([newDefaultRule]); // asserts Assert.Single(cache.RuleAppliers); @@ -74,7 +74,7 @@ public void TestUpdateRulesRemovesOlderRule() // the update contains only the default rule var newDefaultRule = this.CreateDefaultRule(10, 0.20); - rulesCache.UpdateRules(new List { newDefaultRule }); + rulesCache.UpdateRules([newDefaultRule]); // assert that Rule1 doesn't exist in rules cache Assert.Single(rulesCache.RuleAppliers); @@ -116,7 +116,7 @@ public void TestFallbackSamplerMatchesWhenNoRules() var clock = new TestClock(); var rulesCache = new RulesCache(clock, "clientId", ResourceBuilder.CreateEmpty().Build(), new AlwaysOffSampler()) { - RuleAppliers = new List(), + RuleAppliers = [], }; // the fallback sampler will not sample @@ -233,6 +233,6 @@ private SamplingRule CreateRule(string name, int reservoirSize, double fixedRate serviceType: "*", urlPath: "*", version: 1, - attributes: new Dictionary()); + attributes: []); } } diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs index 283528e90f..f93bd7804e 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestSamplingRuleApplier.cs @@ -23,7 +23,7 @@ public void TestRuleMatchesWithAllAttributes() serviceType: "AWS::Lambda::Function", urlPath: "/helloworld", version: 1, - attributes: new Dictionary()); + attributes: []); var activityTags = new Dictionary { @@ -52,7 +52,7 @@ public void TestRuleMatchesWithWildcardAttributes() serviceType: "*", urlPath: "/helloworld", version: 1, - attributes: new Dictionary()); + attributes: []); var activityTags = new Dictionary { @@ -80,7 +80,7 @@ public void TestRuleMatchesWithNoActivityAttributes() serviceType: "*", urlPath: "/helloworld", version: 1, - attributes: new Dictionary()); + attributes: []); var activityTags = new Dictionary(); @@ -103,7 +103,7 @@ public void TestRuleMatchesWithNoActivityAttributesAndWildcardRules() serviceType: "*", urlPath: "*", version: 1, - attributes: new Dictionary()); + attributes: []); var activityTags = new Dictionary(); @@ -126,7 +126,7 @@ public void TestRuleMatchesWithHttpTarget() serviceType: "*", urlPath: "/hello*", version: 1, - attributes: new Dictionary()); + attributes: []); var activityTags = new Dictionary { @@ -208,8 +208,8 @@ public void TestAttributeMatchingWithLessActivityTags() [Fact] public void TestFixedRateAlwaysSample() { - TestClock clock = new TestClock(); - SamplingRule rule = new SamplingRule( + var clock = new TestClock(); + var rule = new SamplingRule( "rule1", 1, 1.0, // fixed rate @@ -221,7 +221,7 @@ public void TestFixedRateAlwaysSample() "*", "*", 1, - new Dictionary()); + []); var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); @@ -247,8 +247,8 @@ public void TestFixedRateAlwaysSample() [Fact] public void TestFixedRateNeverSample() { - TestClock clock = new TestClock(); - SamplingRule rule = new SamplingRule( + var clock = new TestClock(); + var rule = new SamplingRule( "rule1", 1, 0.0, // fixed rate @@ -260,7 +260,7 @@ public void TestFixedRateNeverSample() "*", "*", 1, - new Dictionary()); + []); var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); @@ -279,8 +279,8 @@ public void TestFixedRateNeverSample() [Fact] public void TestBorrowFromReservoir() { - TestClock clock = new TestClock(); - SamplingRule rule = new SamplingRule( + var clock = new TestClock(); + var rule = new SamplingRule( "rule1", 1, 0.0, // fixed rate @@ -292,7 +292,7 @@ public void TestBorrowFromReservoir() "*", "*", 1, - new Dictionary()); + []); var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); @@ -315,8 +315,8 @@ public void TestBorrowFromReservoir() [Fact] public void TestWithTarget() { - TestClock clock = new TestClock(); - SamplingRule rule = new SamplingRule( + var clock = new TestClock(); + var rule = new SamplingRule( "rule1", 1, 0.0, // fixed rate @@ -328,7 +328,7 @@ public void TestWithTarget() "*", "*", 1, - new Dictionary()); + []); var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); @@ -340,7 +340,7 @@ public void TestWithTarget() Assert.Equal(SamplingDecision.Drop, applier.ShouldSample(default).Decision); // get the target - SamplingTargetDocument target = new SamplingTargetDocument + var target = new SamplingTargetDocument { FixedRate = 0.0, Interval = 10, @@ -360,8 +360,8 @@ public void TestWithTarget() [Fact] public void TestWithTargetWithoutQuota() { - TestClock clock = new TestClock(); - SamplingRule rule = new SamplingRule( + var clock = new TestClock(); + var rule = new SamplingRule( "rule1", 1, 0.0, // fixed rate @@ -373,7 +373,7 @@ public void TestWithTargetWithoutQuota() "*", "*", 1, - new Dictionary()); + []); var applier = new SamplingRuleApplier("clientId", clock, rule, new Statistics()); @@ -390,7 +390,7 @@ public void TestWithTargetWithoutQuota() Assert.Equal(2, statistics.BorrowCount); // get the target - SamplingTargetDocument target = new SamplingTargetDocument + var target = new SamplingTargetDocument { FixedRate = 1.0, Interval = 10, diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs index 7b53882827..3d5f45aef6 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/Utils.cs @@ -11,14 +11,14 @@ internal static class Utils { internal static SamplingParameters CreateSamplingParameters() { - return CreateSamplingParametersWithTags(new Dictionary()); + return CreateSamplingParametersWithTags([]); } internal static SamplingParameters CreateSamplingParametersWithTags(Dictionary tags) { - ActivityTraceId traceId = ActivityTraceId.CreateRandom(); - ActivitySpanId parentSpanId = ActivitySpanId.CreateRandom(); - ActivityTraceFlags traceFlags = ActivityTraceFlags.None; + var traceId = ActivityTraceId.CreateRandom(); + var parentSpanId = ActivitySpanId.CreateRandom(); + var traceFlags = ActivityTraceFlags.None; var parentContext = new ActivityContext(traceId, parentSpanId, traceFlags); From 2ca95ada73d6e3332bd4f48303b087ec438324f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 30 Oct 2024 10:33:34 +0100 Subject: [PATCH 1384/1499] [Instrumentation.WCF] Switch .NET6 to .NET8 (#2263) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 3 +++ .../OpenTelemetry.Instrumentation.Wcf.csproj | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index aed823fb26..5a8143925e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. + ([#2263](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2263)) + ## 1.0.0-rc.18 Released 2024-Oct-28 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj index 8724466ada..69b8dcc6f0 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj +++ b/src/OpenTelemetry.Instrumentation.Wcf/OpenTelemetry.Instrumentation.Wcf.csproj @@ -2,7 +2,7 @@ - net6.0;$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) + $(NetMinimumSupportedVersion);$(NetStandardMinimumSupportedVersion);$(NetFrameworkMinimumSupportedVersion) OpenTelemetry instrumentation for WCF. $(PackageTags);distributed-tracing;WCF Instrumentation.Wcf- @@ -23,10 +23,10 @@ - + - + From e61cea4cd7acac77767e7db78ca62fac5a40626e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 30 Oct 2024 17:10:02 +0100 Subject: [PATCH 1385/1499] [repo/WCF] Prepare to .NET9 (#2273) --- .../ActivityHelper.cs | 6 +- .../TelemetryHttpModule.cs | 8 +- .../AspNetParentSpanCorrector.cs | 17 +-- .../ClientChannelInstrumentation.cs | 8 +- .../HttpRequestMessagePropertyWrapper.cs | 19 ++-- .../RequestTelemetryStateTracker.cs | 9 +- .../TelemetryDispatchMessageInspector.cs | 8 +- .../WcfInstrumentationEventSource.cs | 2 +- src/Shared/PropertyFetcher.cs | 20 ++-- .../AspNetParentSpanCorrectorTests.netfx.cs | 6 +- .../TelemetryBindingElementForHttpTests.cs | 66 ++++++------ ...elemetryBindingElementForTcpTests.netfx.cs | 100 ++++++++---------- ...InspectorForOneWayOperationsTests.netfx.cs | 20 ++-- ...etryDispatchMessageInspectorTests.netfx.cs | 46 +++----- .../TelemetryPropagationTests.netfx.cs | 4 +- ...DownstreamInstrumentationBindingElement.cs | 2 + .../Tools/DownstreamInstrumentationChannel.cs | 4 +- ...DownstreamInstrumentationChannelFactory.cs | 9 +- ...wnstreamInstrumentationEndpointBehavior.cs | 2 + .../DownstreamInstrumentationExtensions.cs | 2 +- .../ErrorHandlerServiceBehavior.netfx.cs | 2 +- .../WCF/IServiceContract.cs | 2 + .../WCF/ServiceClient.cs | 2 + .../WCF/ServiceRequest.cs | 2 + .../WCF/ServiceResponse.cs | 2 + 25 files changed, 167 insertions(+), 201 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs index bf3717da0c..99c8fd8fd3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/ActivityHelper.cs @@ -41,7 +41,7 @@ internal static class ActivityHelper /// if start has been called. public static bool HasStarted(HttpContext context, out Activity? aspNetActivity) { - object itemValue = context.Items[ContextKey]; + var itemValue = context.Items[ContextKey]; if (itemValue is ContextHolder contextHolder) { aspNetActivity = contextHolder.Activity; @@ -61,7 +61,7 @@ public static bool HasStarted(HttpContext context, out Activity? aspNetActivity) /// New root activity. public static Activity? StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action? onRequestStartedCallback) { - PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); + var propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter); KeyValuePair[]? tags; if (context.Request?.Unvalidated?.Path is string path) @@ -75,7 +75,7 @@ public static bool HasStarted(HttpContext context, out Activity? aspNetActivity) tags = null; } - Activity? activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext, tags); + var activity = AspNetSource.StartActivity(TelemetryHttpModule.AspNetActivityName, ActivityKind.Server, propagationContext.ActivityContext, tags); if (tags is not null) { diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs index 92a8185447..f155c71352 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/TelemetryHttpModule.cs @@ -55,7 +55,7 @@ public void Init(HttpApplication context) // OnExecuteRequestStep is available starting with 4.7.1 try { - OnExecuteRequestStepMethodInfo.Invoke(context, new object[] { (Action)this.OnExecuteRequestStep }); + OnExecuteRequestStepMethodInfo.Invoke(context, [(Action)this.OnExecuteRequestStep]); } catch (Exception e) { @@ -80,11 +80,11 @@ private void OnExecuteRequestStep(HttpContextBase context, Action step) private void Application_EndRequest(object sender, EventArgs e) { AspNetTelemetryEventSource.Log.TraceCallback("Application_EndRequest"); - bool trackActivity = true; + var trackActivity = true; var context = ((HttpApplication)sender).Context; - if (!ActivityHelper.HasStarted(context, out Activity? aspNetActivity)) + if (!ActivityHelper.HasStarted(context, out var aspNetActivity)) { // Rewrite: In case of rewrite, a new request context is created, called the child request, and it goes through the entire IIS/ASP.NET integrated pipeline. // The child request can be mapped to any of the handlers configured in IIS, and it's execution is no different than it would be if it was received via the HTTP stack. @@ -119,7 +119,7 @@ private void Application_Error(object sender, EventArgs e) var exception = context.Error; if (exception != null) { - if (!ActivityHelper.HasStarted(context, out Activity? aspNetActivity)) + if (!ActivityHelper.HasStarted(context, out var aspNetActivity)) { aspNetActivity = ActivityHelper.StartAspNetActivity(Options.TextMapPropagator, context, Options.OnRequestStartedCallback); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs index 9d8e691b61..bdcd994691 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs @@ -27,8 +27,8 @@ internal static class AspNetParentSpanCorrector private const string TelemetryHttpModuleOptionsTypeName = "OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModuleOptions, OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule"; private static readonly ReflectedInfo? ReflectedValues = Initialize(); - private static readonly PropertyFetcher RequestFetcher = new PropertyFetcher("Request"); - private static readonly PropertyFetcher HeadersFetcher = new PropertyFetcher("Headers"); + private static readonly PropertyFetcher RequestFetcher = new("Request"); + private static readonly PropertyFetcher HeadersFetcher = new("Headers"); private static bool isRegistered; public static void Register() @@ -63,11 +63,7 @@ private static void OnRequestStarted(Activity activity, object context) { try { - var isReadOnlyProp = typeof(NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); - if (isReadOnlyProp == null) - { - throw new NotSupportedException("NameValueCollection.IsReadOnly property not found"); - } + var isReadOnlyProp = typeof(NameValueCollection).GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) ?? throw new NotSupportedException("NameValueCollection.IsReadOnly property not found"); var setHeadersReadOnly = (Action)isReadOnlyProp.SetMethod.CreateDelegate(typeof(Action)); @@ -102,12 +98,7 @@ private static Func GenerateSubscribeLambda() var telemetryHttpModuleType = Type.GetType(TelemetryHttpModuleTypeName, true); var telemetryHttpModuleOptionsType = Type.GetType(TelemetryHttpModuleOptionsTypeName, true); - var onRequestStartedProp = telemetryHttpModuleOptionsType.GetProperty("OnRequestStartedCallback"); - if (onRequestStartedProp == null) - { - throw new NotSupportedException("TelemetryHttpModuleOptions.OnRequestStartedCallback property not found"); - } - + var onRequestStartedProp = telemetryHttpModuleOptionsType.GetProperty("OnRequestStartedCallback") ?? throw new NotSupportedException("TelemetryHttpModuleOptions.OnRequestStartedCallback property not found"); Func addOurCallbackToDelegate = (existingCallback) => { var myCallback = OnRequestStarted; diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index 6fca3efada..ae569c3cf2 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -18,10 +18,10 @@ public static RequestTelemetryState BeforeSendRequest(Message request, Uri? remo return new RequestTelemetryState { SuppressionScope = SuppressDownstreamInstrumentation() }; } - Activity? activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + var activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( WcfInstrumentationActivitySource.OutgoingRequestActivityName, ActivityKind.Client); - IDisposable? suppressionScope = SuppressDownstreamInstrumentation(); + var suppressionScope = SuppressDownstreamInstrumentation(); if (activity != null) { @@ -125,7 +125,7 @@ public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? private static ActionMetadata GetActionMetadata(Message request, string action) { ActionMetadata? actionMetadata = null; - if (request.Properties.TryGetValue(TelemetryContextMessageProperty.Name, out object telemetryContextProperty)) + if (request.Properties.TryGetValue(TelemetryContextMessageProperty.Name, out var telemetryContextProperty)) { var actionMappings = (telemetryContextProperty as TelemetryContextMessageProperty)?.ActionMappings; if (actionMappings != null && actionMappings.TryGetValue(action, out var metadata)) @@ -134,7 +134,7 @@ private static ActionMetadata GetActionMetadata(Message request, string action) } } - return actionMetadata != null ? actionMetadata : new ActionMetadata( + return actionMetadata ?? new ActionMetadata( contractName: null, operationName: action); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs index 26e62a054a..c6f4c58685 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs @@ -54,21 +54,18 @@ public static WebHeaderCollection GetHeaders(object httpRequestMessageProperty) var constructor = type.GetConstructor(Type.EmptyTypes) ?? throw new NotSupportedException("HttpRequestMessageProperty public parameterless constructor was not found"); - var headersProp = type.GetProperty("Headers", BindingFlags.Public | BindingFlags.Instance, null, typeof(WebHeaderCollection), Array.Empty(), null) + var headersProp = type.GetProperty("Headers", BindingFlags.Public | BindingFlags.Instance, null, typeof(WebHeaderCollection), [], null) ?? throw new NotSupportedException("HttpRequestMessageProperty.Headers property not found"); - var nameProp = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static, null, typeof(string), Array.Empty(), null) + var nameProp = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static, null, typeof(string), [], null) ?? throw new NotSupportedException("HttpRequestMessageProperty.Name property not found"); - if (nameProp.GetValue(null) is not string name) - { - throw new NotSupportedException("HttpRequestMessageProperty.Name property was null"); - } - - return new ReflectedInfo( - type: type, - name: name, - headersFetcher: new PropertyFetcher("Headers")); + return nameProp.GetValue(null) is not string name + ? throw new NotSupportedException("HttpRequestMessageProperty.Name property was null") + : new ReflectedInfo( + type: type, + name: name, + headersFetcher: new PropertyFetcher("Headers")); } catch (Exception ex) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs index 282f0c91e0..db8f5f1402 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/RequestTelemetryStateTracker.cs @@ -7,8 +7,8 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; internal static class RequestTelemetryStateTracker { - private static readonly Dictionary OutstandingRequestStates = new Dictionary(); - private static readonly SortedSet TimeoutQueue = new SortedSet(); + private static readonly Dictionary OutstandingRequestStates = []; + private static readonly SortedSet TimeoutQueue = []; private static readonly object Sync = new(); private static readonly Timer Timer = new(OnTimer); private static long currentTimerDueAt = Timeout.Infinite; @@ -61,10 +61,7 @@ private static void OnTimer(object? state) { if (entryTimeoutProps.ExpiresAt <= now) { - if (timedOutEntries == null) - { - timedOutEntries = new List>(); - } + timedOutEntries ??= []; timedOutEntries.Add(new(entryTimeoutProps, OutstandingRequestStates[entryTimeoutProps.MessageId])); } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs index 653ef55ad3..9c2c981b05 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs @@ -49,7 +49,7 @@ internal TelemetryDispatchMessageInspector(IDictionary a var textMapPropagator = Propagators.DefaultTextMapPropagator; var ctx = textMapPropagator.Extract(default, request, WcfInstrumentationActivitySource.MessageHeaderValuesGetter); - Activity? activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( + var activity = WcfInstrumentationActivitySource.ActivitySource.StartActivity( WcfInstrumentationActivitySource.IncomingRequestActivityName, ActivityKind.Server, ctx.ActivityContext); @@ -71,7 +71,7 @@ internal TelemetryDispatchMessageInspector(IDictionary a { activity.SetTag(WcfInstrumentationConstants.RpcSystemTag, WcfInstrumentationConstants.WcfSystemValue); - if (!this.actionMappings.TryGetValue(action, out ActionMetadata actionMetadata)) + if (!this.actionMappings.TryGetValue(action, out var actionMetadata)) { actionMetadata = new ActionMetadata( contractName: null, @@ -105,7 +105,7 @@ internal TelemetryDispatchMessageInspector(IDictionary a } } - if (!(textMapPropagator is TraceContextPropagator)) + if (textMapPropagator is not TraceContextPropagator) { Baggage.Current = ctx.Baggage; } @@ -139,7 +139,7 @@ public void BeforeSendReply(ref Message reply, object? correlationState) activity.Stop(); - if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) + if (Propagators.DefaultTextMapPropagator is not TraceContextPropagator) { Baggage.Current = default; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs index 28655258e3..507b5c1f64 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/WcfInstrumentationEventSource.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; [EventSource(Name = "OpenTelemetry-Instrumentation-Wcf")] internal sealed class WcfInstrumentationEventSource : EventSource { - public static readonly WcfInstrumentationEventSource Log = new WcfInstrumentationEventSource(); + public static readonly WcfInstrumentationEventSource Log = new(); [NonEvent] public void RequestFilterException(Exception ex) diff --git a/src/Shared/PropertyFetcher.cs b/src/Shared/PropertyFetcher.cs index 7dbcda9afa..1ed16cc7bb 100644 --- a/src/Shared/PropertyFetcher.cs +++ b/src/Shared/PropertyFetcher.cs @@ -34,12 +34,9 @@ public PropertyFetcher(string propertyName) /// Property fetched. public T Fetch(object obj) { - if (!this.TryFetch(obj, out T value)) - { - throw new ArgumentException("Supplied object was null or did not match the expected type.", nameof(obj)); - } - - return value; + return !this.TryFetch(obj, out var value) + ? throw new ArgumentException("Supplied object was null or did not match the expected type.", nameof(obj)) + : value; } /// @@ -59,12 +56,7 @@ public bool TryFetch(object obj, out T value) if (this.innerFetcher == null) { var type = obj.GetType().GetTypeInfo(); - var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.OrdinalIgnoreCase)); - if (property == null) - { - property = type.GetProperty(this.propertyName); - } - + var property = type.DeclaredProperties.FirstOrDefault(p => string.Equals(p.Name, this.propertyName, StringComparison.OrdinalIgnoreCase)) ?? type.GetProperty(this.propertyName); this.innerFetcher = PropertyFetch.FetcherForProperty(property); } @@ -107,7 +99,11 @@ private sealed class TypedPropertyFetch : Pr public TypedPropertyFetch(PropertyInfo property) { +#if NET + this.propertyFetch = property.GetMethod.CreateDelegate>(); +#else this.propertyFetch = (Func)property.GetMethod.CreateDelegate(typeof(Func)); +#endif } public override bool TryFetch(object obj, out T value) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs index 63113a4f8d..dea64b6447 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/AspNetParentSpanCorrectorTests.netfx.cs @@ -31,7 +31,7 @@ public void IncomingRequestHeadersAreOverwrittenWithAspNetParent() var context = new FakeHttpContext(); var method = typeof(AspNetParentSpanCorrector).GetMethod("OnRequestStarted", BindingFlags.Static | BindingFlags.NonPublic); - method.Invoke(null, new object[] { aspNetActivity, context }); + method.Invoke(null, [aspNetActivity, context]); var headerVal = context.Request.Headers["traceparent"]; Assert.Contains(aspNetActivity.TraceId.ToString(), headerVal); @@ -43,12 +43,12 @@ public void IncomingRequestHeadersAreOverwrittenWithAspNetParent() private class FakeHttpContext { - public FakeRequest Request { get; } = new FakeRequest(); + public FakeRequest Request { get; } = new(); } private class FakeRequest { - public NameValueCollection Headers { get; } = new NameValueCollection(); + public NameValueCollection Headers { get; } = []; } } #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs index d04fce5f0b..d255648c91 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForHttpTests.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Net; using System.ServiceModel; -using System.ServiceModel.Channels; using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; using Xunit; @@ -19,7 +18,7 @@ public class TelemetryBindingElementForHttpTests : IDisposable public TelemetryBindingElementForHttpTests() { - Random random = new Random(); + var random = new Random(); var retryCount = 5; HttpListener? createdListener = null; while (retryCount > 0) @@ -57,7 +56,9 @@ public TelemetryBindingElementForHttpTests() finally { initializationHandle.Dispose(); +#pragma warning disable IDE0059 // Unnecessary assignment of a value initializationHandle = null; +#pragma warning restore IDE0059 // Unnecessary assignment of a value } async void Listener() @@ -72,14 +73,14 @@ async void Listener() var ctx = await ctxTask.ConfigureAwait(false); - using StreamReader reader = new StreamReader(ctx.Request.InputStream); + using var reader = new StreamReader(ctx.Request.InputStream); - string request = reader.ReadToEnd(); + var request = reader.ReadToEnd(); ctx.Response.StatusCode = 200; ctx.Response.ContentType = "text/xml; charset=utf-8"; - using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream)) + using (var writer = new StreamWriter(ctx.Response.OutputStream)) { if (request.Contains("ExecuteWithEmptyActionName")) { @@ -139,7 +140,7 @@ public async Task OutgoingRequestInstrumentationTest( bool enrichmentException = false, bool emptyOrNullAction = false) { - List stoppedActivities = new List(); + List stoppedActivities = []; var builder = Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(stoppedActivities); @@ -151,9 +152,9 @@ public async Task OutgoingRequestInstrumentationTest( { if (enrich) { - if (!enrichmentException) - { - options.Enrich = (activity, eventName, message) => + options.Enrich = enrichmentException + ? (_, _, _) => throw new Exception("Error while enriching activity") + : (activity, eventName, _) => { switch (eventName) { @@ -163,25 +164,22 @@ public async Task OutgoingRequestInstrumentationTest( case WcfEnrichEventNames.AfterReceiveReply: activity.SetTag("client.afterreceivereply", WcfEnrichEventNames.AfterReceiveReply); break; + default: + break; } }; - } - else - { - options.Enrich = (activity, eventName, message) => throw new Exception("Error while enriching activity"); - } } - options.OutgoingRequestFilter = (Message m) => !filter; + options.OutgoingRequestFilter = _ => !filter; options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; options.SetSoapMessageVersion = includeVersion; }) .AddDownstreamInstrumentation(); } - TracerProvider? tracerProvider = builder.Build(); + var tracerProvider = builder.Build(); - ServiceClient client = new ServiceClient( + var client = new ServiceClient( new BasicHttpBinding(BasicHttpSecurityMode.None), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try @@ -243,7 +241,7 @@ await client.ExecuteAsync( Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; + var activity = stoppedActivities[0]; if (emptyOrNullAction) { @@ -298,21 +296,19 @@ public async Task ActivitiesHaveCorrectParentTest() .AddWcfInstrumentation() .Build(); - ServiceClient client = new ServiceClient( + var client = new ServiceClient( new BasicHttpBinding(BasicHttpSecurityMode.None), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - using (var parentActivity = testSource.StartActivity("ParentActivity")) - { - client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); - client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); - var firstAsyncCall = client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); - await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); - await firstAsyncCall; - } + using var parentActivity = testSource.StartActivity("ParentActivity"); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + var firstAsyncCall = client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); + await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); + await firstAsyncCall; } finally { @@ -351,10 +347,10 @@ public async Task ErrorsAreHandledProperlyTest() .AddWcfInstrumentation() .Build(); - ServiceClient client = new ServiceClient( + var client = new ServiceClient( new BasicHttpBinding(BasicHttpSecurityMode.None), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); - ServiceClient clientBadUrl = new ServiceClient( + var clientBadUrl = new ServiceClient( new BasicHttpBinding(BasicHttpSecurityMode.None), new EndpointAddress(new Uri("http://localhost:1/Service"))); try @@ -362,13 +358,11 @@ public async Task ErrorsAreHandledProperlyTest() client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); clientBadUrl.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - using (var parentActivity = testSource.StartActivity("ParentActivity")) - { - Assert.ThrowsAny(() => client.ErrorSynchronous()); - await Assert.ThrowsAnyAsync(client.ErrorAsync); - Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!"))); - await Assert.ThrowsAnyAsync(() => clientBadUrl.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); - } + using var parentActivity = testSource.StartActivity("ParentActivity"); + Assert.ThrowsAny(client.ErrorSynchronous); + await Assert.ThrowsAnyAsync(client.ErrorAsync); + Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!"))); + await Assert.ThrowsAnyAsync(() => clientBadUrl.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); } finally { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs index c4fd1d6fed..88088c0ef1 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryBindingElementForTcpTests.netfx.cs @@ -7,7 +7,6 @@ using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.ServiceModel; -using System.ServiceModel.Channels; using System.ServiceModel.Security; using OpenTelemetry.Instrumentation.Wcf.Tests.Tools; using OpenTelemetry.Trace; @@ -53,7 +52,7 @@ public async Task OutgoingRequestInstrumentationTest( bool enrichmentException = false, bool emptyOrNullAction = false) { - List stoppedActivities = new List(); + List stoppedActivities = []; var builder = Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(stoppedActivities); @@ -65,9 +64,9 @@ public async Task OutgoingRequestInstrumentationTest( { if (enrich) { - if (!enrichmentException) - { - options.Enrich = (activity, eventName, message) => + options.Enrich = enrichmentException + ? (_, _, _) => throw new Exception("Error while enriching activity") + : (activity, eventName, _) => { switch (eventName) { @@ -77,23 +76,20 @@ public async Task OutgoingRequestInstrumentationTest( case WcfEnrichEventNames.AfterReceiveReply: activity.SetTag("client.afterreceivereply", WcfEnrichEventNames.AfterReceiveReply); break; + default: + break; } }; - } - else - { - options.Enrich = (activity, eventName, message) => throw new Exception("Error while enriching activity"); - } } - options.OutgoingRequestFilter = (Message m) => !filter; + options.OutgoingRequestFilter = _ => !filter; options.SuppressDownstreamInstrumentation = suppressDownstreamInstrumentation; options.SetSoapMessageVersion = includeVersion; }) .AddDownstreamInstrumentation(); } - TracerProvider? tracerProvider = builder.Build(); + var tracerProvider = builder.Build(); var client = new ServiceClient( new NetTcpBinding(SecurityMode.None), @@ -157,7 +153,7 @@ await client.ExecuteAsync( Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; + var activity = stoppedActivities[0]; if (emptyOrNullAction) { @@ -220,14 +216,12 @@ public async Task ActivitiesHaveCorrectParentTest() { client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - using (var parentActivity = testSource.StartActivity("ParentActivity")) - { - client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); - client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); - var firstAsyncCall = client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); - await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); - await firstAsyncCall; - } + using var parentActivity = testSource.StartActivity("ParentActivity"); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + client.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!")); + var firstAsyncCall = client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); + await client.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!")); + await firstAsyncCall; } finally { @@ -277,21 +271,19 @@ public async Task ErrorsAreHandledProperlyTest() clientBadUrl.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); clientBadUrl2.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); - using (var parentActivity = testSource.StartActivity("ParentActivity")) - { - Assert.ThrowsAny(() => client.ErrorSynchronous()); - - // weird corner case: if an async call is made as the first hit (before the client is opened) the - // async execution context gets lost somewhere in WCF internals, so we'll explicitly open it first - client2.Open(); - await Assert.ThrowsAnyAsync(client2.ErrorAsync); - Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!"))); - await Assert.ThrowsAnyAsync(() => clientBadUrl2.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); - } + using var parentActivity = testSource.StartActivity("ParentActivity"); + Assert.ThrowsAny(client.ErrorSynchronous); + + // weird corner case: if an async call is made as the first hit (before the client is opened) the + // async execution context gets lost somewhere in WCF internals, so we'll explicitly open it first + client2.Open(); + await Assert.ThrowsAnyAsync(client2.ErrorAsync); + Assert.ThrowsAny(() => clientBadUrl.ExecuteSynchronous(new ServiceRequest(payload: "Hello Open Telemetry!"))); + await Assert.ThrowsAnyAsync(() => clientBadUrl2.ExecuteAsync(new ServiceRequest(payload: "Hello Open Telemetry!"))); } finally { - Action closeClient = client => + static void CloseClient(ServiceClient client) { if (client.State == CommunicationState.Faulted) { @@ -301,11 +293,12 @@ public async Task ErrorsAreHandledProperlyTest() { client.Close(); } - }; - closeClient(client); - closeClient(client2); - closeClient(clientBadUrl); - closeClient(clientBadUrl2); + } + + CloseClient(client); + CloseClient(client2); + CloseClient(clientBadUrl); + CloseClient(clientBadUrl2); tracerProvider?.Shutdown(); tracerProvider?.Dispose(); @@ -330,8 +323,10 @@ public async Task OrphanedTelemetryTimesOut() .AddWcfInstrumentation() .Build(); - var binding = new NetTcpBinding(SecurityMode.None); - binding.SendTimeout = TimeSpan.FromMilliseconds(1000); + var binding = new NetTcpBinding(SecurityMode.None) + { + SendTimeout = TimeSpan.FromMilliseconds(1000), + }; var client = new ServiceClient(binding, new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { @@ -378,8 +373,10 @@ public async Task DynamicTimeoutValuesAreRespected() .AddWcfInstrumentation() .Build(); - var binding = new NetTcpBinding(SecurityMode.None); - binding.SendTimeout = TimeSpan.FromMilliseconds(15000); + var binding = new NetTcpBinding(SecurityMode.None) + { + SendTimeout = TimeSpan.FromMilliseconds(15000), + }; var client = new ServiceClient(binding, new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try { @@ -426,18 +423,20 @@ public void StreamedTransferWithTransportSecurityWithMessageCredentialWorks() // this config combination is unique because it uses an IRequestSessionChannel, // where other NetTcp configs use IDuplexChannel - List stoppedActivities = new List(); + List stoppedActivities = []; var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(stoppedActivities) .AddWcfInstrumentation() .Build(); - var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential); - binding.TransferMode = TransferMode.Streamed; + var binding = new NetTcpBinding(SecurityMode.TransportWithMessageCredential) + { + TransferMode = TransferMode.Streamed, + }; binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign; binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; var host = this.CreateServiceHost(binding, LoadCertificate()); - ServiceClient client = new ServiceClient(binding, new EndpointAddress(new Uri(host.BaseAddresses[0], "/Service"))); + var client = new ServiceClient(binding, new EndpointAddress(new Uri(host.BaseAddresses[0], "/Service"))); try { client.ClientCredentials.ClientCertificate.Certificate = LoadCertificate(); @@ -489,7 +488,7 @@ private static X509Certificate2 LoadCertificate() private ServiceHost CreateServiceHost(NetTcpBinding binding, X509Certificate2? cert) { ServiceHost? serviceHost = null; - Random random = new Random(); + var random = new Random(); var retryCount = 5; while (retryCount > 0) { @@ -527,12 +526,7 @@ private ServiceHost CreateServiceHost(NetTcpBinding binding, X509Certificate2? c } } - if (serviceHost == null) - { - throw new InvalidOperationException("ServiceHost could not be started."); - } - - return serviceHost; + return serviceHost ?? throw new InvalidOperationException("ServiceHost could not be started."); } } #endif diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs index aa91e53df6..3ee5ad8c15 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorForOneWayOperationsTests.netfx.cs @@ -18,14 +18,14 @@ public class TelemetryDispatchMessageInspectorForOneWayOperationsTests : IDispos private readonly Uri serviceBaseUri; private readonly ServiceHost serviceHost; - private readonly EventWaitHandle thrownExceptionsHandle = new EventWaitHandle(false, EventResetMode.ManualReset); - private readonly List thrownExceptions = new List(); + private readonly EventWaitHandle thrownExceptionsHandle = new(false, EventResetMode.ManualReset); + private readonly List thrownExceptions = []; public TelemetryDispatchMessageInspectorForOneWayOperationsTests(ITestOutputHelper outputHelper) { this.output = outputHelper; - Random random = new Random(); + var random = new Random(); var retryCount = 5; ServiceHost? createdHost = null; while (retryCount > 0) @@ -42,7 +42,7 @@ public TelemetryDispatchMessageInspectorForOneWayOperationsTests(ITestOutputHelp endpoint.Behaviors.Add(new TelemetryEndpointBehavior()); createdHost.Description.Behaviors.Add( - new ErrorHandlerServiceBehavior(this.thrownExceptionsHandle, ex => this.thrownExceptions.Add(ex))); + new ErrorHandlerServiceBehavior(this.thrownExceptionsHandle, this.thrownExceptions.Add)); createdHost.Open(); @@ -82,20 +82,20 @@ public void Dispose() [Fact] public void IncomingRequestOneWayOperationInstrumentationTest() { - List stoppedActivities = new List(); + List stoppedActivities = []; - using ActivityListener activityListener = new ActivityListener + using var activityListener = new ActivityListener { ShouldListenTo = activitySource => true, - ActivityStopped = activity => stoppedActivities.Add(activity), + ActivityStopped = stoppedActivities.Add, }; ActivitySource.AddActivityListener(activityListener); - TracerProvider? tracerProvider = Sdk.CreateTracerProviderBuilder() + var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddWcfInstrumentation() .Build(); - ServiceClient client = new ServiceClient( + var client = new ServiceClient( new NetTcpBinding(), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); @@ -127,7 +127,7 @@ public void IncomingRequestOneWayOperationInstrumentationTest() Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; + var activity = stoppedActivities[0]; Assert.Equal("http://opentelemetry.io/Service/ExecuteWithOneWay", activity.DisplayName); Assert.Equal("ExecuteWithOneWay", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.RpcMethodTag).Value); Assert.DoesNotContain(activity.TagObjects, t => t.Key == WcfInstrumentationConstants.SoapReplyActionTag); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs index 938032f2a0..2faafc3a29 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryDispatchMessageInspectorTests.netfx.cs @@ -4,7 +4,6 @@ #if NETFRAMEWORK using System.Diagnostics; using System.ServiceModel; -using System.ServiceModel.Channels; using OpenTelemetry.Trace; using Xunit; using Xunit.Abstractions; @@ -22,7 +21,7 @@ public TelemetryDispatchMessageInspectorTests(ITestOutputHelper outputHelper) { this.output = outputHelper; - Random random = new Random(); + var random = new Random(); var retryCount = 5; ServiceHost? createdHost = null; while (retryCount > 0) @@ -82,15 +81,15 @@ public async Task IncomingRequestInstrumentationTest( bool filter = false, bool includeVersion = false, bool enrich = false, - bool enrichmentExcecption = false, + bool enrichmentException = false, bool emptyOrNullAction = false) { - List stoppedActivities = new List(); + List stoppedActivities = []; - using ActivityListener activityListener = new ActivityListener + using var activityListener = new ActivityListener { ShouldListenTo = activitySource => true, - ActivityStopped = activity => stoppedActivities.Add(activity), + ActivityStopped = stoppedActivities.Add, }; ActivitySource.AddActivityListener(activityListener); @@ -103,44 +102,31 @@ public async Task IncomingRequestInstrumentationTest( { if (enrich) { - if (!enrichmentExcecption) - { - options.Enrich = (activity, eventName, message) => + options.Enrich = enrichmentException + ? (_, _, _) => throw new Exception("Failure whilst enriching activity") + : (activity, eventName, _) => { switch (eventName) { case WcfEnrichEventNames.AfterReceiveRequest: - activity.SetTag( - "server.afterreceiverequest", - WcfEnrichEventNames.AfterReceiveRequest); + activity.SetTag("server.afterreceiverequest", WcfEnrichEventNames.AfterReceiveRequest); break; case WcfEnrichEventNames.BeforeSendReply: - activity.SetTag( - "server.beforesendreply", - WcfEnrichEventNames.BeforeSendReply); + activity.SetTag("server.beforesendreply", WcfEnrichEventNames.BeforeSendReply); + break; + default: break; } }; - } - else - { - options.Enrich = (activity, eventName, message) => - { - throw new Exception("Failure whilst enriching activity"); - }; - } } - options.IncomingRequestFilter = (Message m) => - { - return !filter; - }; + options.IncomingRequestFilter = _ => !filter; options.SetSoapMessageVersion = includeVersion; }) .Build(); } - ServiceClient client = new ServiceClient( + var client = new ServiceClient( new NetTcpBinding(), new EndpointAddress(new Uri(this.serviceBaseUri, "/Service"))); try @@ -180,7 +166,7 @@ await client.ExecuteAsync( Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; + var activity = stoppedActivities[0]; if (emptyOrNullAction) { @@ -208,7 +194,7 @@ await client.ExecuteAsync( Assert.Equal("Soap12 (http://www.w3.org/2003/05/soap-envelope) Addressing10 (http://www.w3.org/2005/08/addressing)", activity.TagObjects.FirstOrDefault(t => t.Key == WcfInstrumentationConstants.SoapMessageVersionTag).Value); } - if (enrich && !enrichmentExcecption) + if (enrich && !enrichmentException) { Assert.Equal(WcfEnrichEventNames.AfterReceiveRequest, activity.TagObjects.Single(t => t.Key == "server.afterreceiverequest").Value); Assert.Equal(WcfEnrichEventNames.BeforeSendReply, activity.TagObjects.Single(t => t.Key == "server.beforesendreply").Value); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs index 3f377702a7..fc5fc7b5c3 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/TelemetryPropagationTests.netfx.cs @@ -20,7 +20,7 @@ public class TelemetryPropagationTests : IDisposable public TelemetryPropagationTests() { - Random random = new Random(); + var random = new Random(); var retryCount = 5; ServiceHost? createdHost = null; while (retryCount > 0) @@ -101,7 +101,7 @@ public async Task TelemetryContextPropagatesTest( "rest" => new WebHttpBinding(), _ => throw new ArgumentException("Invalid endpoint type", nameof(endpoint)), }; - ServiceClient client = new ServiceClient(binding, new EndpointAddress(new Uri(serviceBase, $"/{endpoint}"))); + var client = new ServiceClient(binding, new EndpointAddress(new Uri(serviceBase, $"/{endpoint}"))); try { client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs index 8d52c63e3c..ff6e69dba7 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationBindingElement : BindingElement +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public override BindingElement Clone() { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs index 8ee6338cd2..5b93254776 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs @@ -7,10 +7,12 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationChannel : DispatchProxy +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public const string DownstreamInstrumentationSourceName = "DownstreamInstrumentationSource"; - private static readonly ActivitySource DownstreamInstrumentationSource = new ActivitySource(DownstreamInstrumentationSourceName); + private static readonly ActivitySource DownstreamInstrumentationSource = new(DownstreamInstrumentationSourceName); private static bool failNextReceive; private object? Target { get; set; } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs index 41870371b9..78769adea8 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationChannelFactory : DispatchProxy +#pragma warning restore CA1515 // Make class internal, public is needed for WCF where TChannel : notnull { public IChannelFactory? Target { get; set; } @@ -14,11 +16,6 @@ public class DownstreamInstrumentationChannelFactory : DispatchProxy protected override object? Invoke(MethodInfo? targetMethod, object?[]? args) { var returnValue = targetMethod!.Invoke(this.Target, args); - if (targetMethod.Name == nameof(IChannelFactory.CreateChannel)) - { - return DownstreamInstrumentationChannel.Create((TChannel)returnValue!); - } - - return returnValue; + return targetMethod.Name == nameof(IChannelFactory.CreateChannel) ? DownstreamInstrumentationChannel.Create((TChannel)returnValue!) : returnValue; } } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs index 20c8417239..24b11c21cc 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs @@ -7,7 +7,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationEndpointBehavior : IEndpointBehavior +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs index 958af96d95..278364b4f0 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationExtensions.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; -public static class DownstreamInstrumentationExtensions +internal static class DownstreamInstrumentationExtensions { public static TracerProviderBuilder AddDownstreamInstrumentation(this TracerProviderBuilder builder) => builder.AddSource(DownstreamInstrumentationChannel.DownstreamInstrumentationSourceName); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs index a9d787c45f..cddb6acbe6 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/ErrorHandlerServiceBehavior.netfx.cs @@ -27,7 +27,7 @@ public void AddBindingParameters(ServiceDescription serviceDescription, ServiceH public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { - foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) + foreach (var dispatcher in serviceHostBase.ChannelDispatchers.Cast()) { dispatcher.ErrorHandlers.Add(new ErrorHandler(this.handle, this.action)); } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index b9c1cef19a..8eaec2db43 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [ServiceContract(Namespace = "http://opentelemetry.io/", Name = "Service", SessionMode = SessionMode.Allowed)] +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public interface IServiceContract +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { [OperationContract] Task ExecuteAsync(ServiceRequest request); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index b67b98caef..c3f2056b4c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class ServiceClient : ClientBase, IServiceContract +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public ServiceClient(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index c41027301b..1329f1b654 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [DataContract] +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class ServiceRequest +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public ServiceRequest(string payload) { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index d26066edc6..8dfef624bd 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [DataContract] +#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class ServiceResponse +#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public ServiceResponse(string payload) { From 503e0b165422d0af31ca3d65a9582443cf4187c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 30 Oct 2024 17:21:19 +0100 Subject: [PATCH 1386/1499] [repo/Kafka] Prepare to .NET9 (#2275) --- .../InstrumentedConsumer.cs | 24 ++++----- .../InstrumentedConsumerBuilder.cs | 8 +-- .../InstrumentedProducer.cs | 34 ++++++------- .../OpenTelemetryConsumeResultExtensions.cs | 26 ++-------- .../OpenTelemetryConsumerBuilderExtensions.cs | 2 +- .../OpenTelemetryProducerBuilderExtensions.cs | 2 +- .../HostedMeteringTests.cs | 8 +-- .../HostedTracingAndMeteringTests.cs | 16 +++--- .../HostedTracingTests.cs | 8 +-- .../KafkaHelpers.cs | 6 +-- .../MeteringTests.cs | 18 +++---- ...TelemetryConsumerBuilderExtensionsTests.cs | 42 ++++++++++++---- ...TelemetryProducerBuilderExtensionsTests.cs | 8 +-- .../TracingTests.cs | 50 +++++++++---------- 14 files changed, 129 insertions(+), 123 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs index 561f3a1014..6fe22b0f19 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumer.cs @@ -50,7 +50,7 @@ public void SetSaslCredentials(string username, string password) public ConsumeResult? Consume(int millisecondsTimeout) { - DateTimeOffset start = DateTimeOffset.UtcNow; + var start = DateTimeOffset.UtcNow; ConsumeResult? result = null; ConsumeResult consumeResult = default; string? errorType = null; @@ -67,7 +67,7 @@ public void SetSaslCredentials(string username, string password) } finally { - DateTimeOffset end = DateTimeOffset.UtcNow; + var end = DateTimeOffset.UtcNow; if (result is { IsPartitionEOF: false }) { this.InstrumentConsumption(start, end, consumeResult, errorType); @@ -77,7 +77,7 @@ public void SetSaslCredentials(string username, string password) public ConsumeResult? Consume(CancellationToken cancellationToken = default) { - DateTimeOffset start = DateTimeOffset.UtcNow; + var start = DateTimeOffset.UtcNow; ConsumeResult? result = null; ConsumeResult consumeResult = default; string? errorType = null; @@ -94,7 +94,7 @@ public void SetSaslCredentials(string username, string password) } finally { - DateTimeOffset end = DateTimeOffset.UtcNow; + var end = DateTimeOffset.UtcNow; if (result is { IsPartitionEOF: false }) { this.InstrumentConsumption(start, end, consumeResult, errorType); @@ -104,7 +104,7 @@ public void SetSaslCredentials(string username, string password) public ConsumeResult? Consume(TimeSpan timeout) { - DateTimeOffset start = DateTimeOffset.UtcNow; + var start = DateTimeOffset.UtcNow; ConsumeResult? result = null; ConsumeResult consumeResult = default; string? errorType = null; @@ -121,7 +121,7 @@ public void SetSaslCredentials(string username, string password) } finally { - DateTimeOffset end = DateTimeOffset.UtcNow; + var end = DateTimeOffset.UtcNow; if (result is { IsPartitionEOF: false }) { this.InstrumentConsumption(start, end, consumeResult, errorType); @@ -320,11 +320,11 @@ private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endT { if (this.options.Traces) { - PropagationContext propagationContext = consumeResult.Headers != null + var propagationContext = consumeResult.Headers != null ? OpenTelemetryConsumeResultExtensions.ExtractPropagationContext(consumeResult.Headers) : default; - using Activity? activity = this.StartReceiveActivity(propagationContext, startTime, consumeResult.TopicPartitionOffset, consumeResult.Key); + using var activity = this.StartReceiveActivity(propagationContext, startTime, consumeResult.TopicPartitionOffset, consumeResult.Key); if (activity != null) { if (errorType != null) @@ -342,7 +342,7 @@ private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endT if (this.options.Metrics) { - TimeSpan duration = endTime - startTime; + var duration = endTime - startTime; RecordReceive(consumeResult.TopicPartitionOffset!.TopicPartition, duration, errorType); } } @@ -354,10 +354,10 @@ private void InstrumentConsumption(DateTimeOffset startTime, DateTimeOffset endT : string.Concat(topicPartitionOffset!.Topic, " ", ConfluentKafkaCommon.ReceiveOperationName); ActivityLink[] activityLinks = propagationContext.ActivityContext.IsValid() - ? new[] { new ActivityLink(propagationContext.ActivityContext) } - : Array.Empty(); + ? [new ActivityLink(propagationContext.ActivityContext)] + : []; - Activity? activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, startTime: start, parentContext: default); + var activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, startTime: start, parentContext: default); if (activity?.IsAllDataRequested == true) { activity.SetTag(SemanticConventions.AttributeMessagingSystem, ConfluentKafkaCommon.KafkaMessagingSystem); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs index 8affdfa5fd..82f29e3391 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs @@ -41,10 +41,12 @@ internal bool EnableTraces /// an . public override IConsumer Build() { - ConsumerConfig config = (ConsumerConfig)this.Config; + var config = (ConsumerConfig)this.Config; - var consumer = new InstrumentedConsumer(base.Build(), this.options); - consumer.GroupId = config.GroupId; + var consumer = new InstrumentedConsumer(base.Build(), this.options) + { + GroupId = config.GroupId, + }; return consumer; } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs index b47caa3591..657fbfd629 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducer.cs @@ -42,8 +42,8 @@ public async Task> ProduceAsync( Message message, CancellationToken cancellationToken = default) { - DateTimeOffset start = DateTimeOffset.UtcNow; - using Activity? activity = this.StartPublishActivity(start, topic, message); + var start = DateTimeOffset.UtcNow; + using var activity = this.StartPublishActivity(start, topic, message); if (activity != null) { this.InjectActivity(activity, message); @@ -71,9 +71,9 @@ public async Task> ProduceAsync( } finally { - DateTimeOffset end = DateTimeOffset.UtcNow; + var end = DateTimeOffset.UtcNow; activity?.SetEndTime(end.UtcDateTime); - TimeSpan duration = end - start; + var duration = end - start; if (this.options.Metrics) { @@ -89,8 +89,8 @@ public async Task> ProduceAsync( Message message, CancellationToken cancellationToken = default) { - DateTimeOffset start = DateTimeOffset.UtcNow; - using Activity? activity = this.StartPublishActivity(start, topicPartition.Topic, message, topicPartition.Partition); + var start = DateTimeOffset.UtcNow; + using var activity = this.StartPublishActivity(start, topicPartition.Topic, message, topicPartition.Partition); if (activity != null) { this.InjectActivity(activity, message); @@ -118,9 +118,9 @@ public async Task> ProduceAsync( } finally { - DateTimeOffset end = DateTimeOffset.UtcNow; + var end = DateTimeOffset.UtcNow; activity?.SetEndTime(end.UtcDateTime); - TimeSpan duration = end - start; + var duration = end - start; if (this.options.Metrics) { @@ -133,8 +133,8 @@ public async Task> ProduceAsync( public void Produce(string topic, Message message, Action>? deliveryHandler = null) { - DateTimeOffset start = DateTimeOffset.UtcNow; - using Activity? activity = this.StartPublishActivity(start, topic, message); + var start = DateTimeOffset.UtcNow; + using var activity = this.StartPublishActivity(start, topic, message); if (activity != null) { this.InjectActivity(activity, message); @@ -161,9 +161,9 @@ public void Produce(string topic, Message message, Action message, Action message, Action>? deliveryHandler = null) { - DateTimeOffset start = DateTimeOffset.UtcNow; - using Activity? activity = this.StartPublishActivity(start, topicPartition.Topic, message, topicPartition.Partition); + var start = DateTimeOffset.UtcNow; + using var activity = this.StartPublishActivity(start, topicPartition.Topic, message, topicPartition.Partition); if (activity != null) { this.InjectActivity(activity, message); @@ -202,9 +202,9 @@ public void Produce(TopicPartition topicPartition, Message message } finally { - DateTimeOffset end = DateTimeOffset.UtcNow; + var end = DateTimeOffset.UtcNow; activity?.SetEndTime(end.UtcDateTime); - TimeSpan duration = end - start; + var duration = end - start; if (this.options.Metrics) { @@ -364,7 +364,7 @@ private void InjectActivity(Activity? activity, Message message) private void InjectTraceContext(Message message, string key, string value) { - message.Headers ??= new Headers(); + message.Headers ??= []; message.Headers.Add(key, Encoding.UTF8.GetBytes(value)); } } diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs index 5ef64a43ac..5e302b50c6 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs @@ -105,25 +105,7 @@ public static bool TryExtractPropagationContext( return consumeResult; } - Activity? processActivity = null; - if (TryExtractPropagationContext(consumeResult, out var propagationContext)) - { - processActivity = StartProcessActivity( - propagationContext, - consumeResult.TopicPartitionOffset, - consumeResult.Message.Key, - instrumentedConsumer.Name, - instrumentedConsumer.GroupId!); - } - else - { - processActivity = StartProcessActivity( - default, - consumeResult.TopicPartitionOffset, - consumeResult.Message.Key, - instrumentedConsumer.Name, - instrumentedConsumer.GroupId!); - } + var processActivity = StartProcessActivity(TryExtractPropagationContext(consumeResult, out var propagationContext) ? propagationContext : default, consumeResult.TopicPartitionOffset, consumeResult.Message.Key, instrumentedConsumer.Name, instrumentedConsumer.GroupId!); try { @@ -152,10 +134,10 @@ internal static PropagationContext ExtractPropagationContext(Headers? headers) : string.Concat(topicPartitionOffset!.Topic, " ", ConfluentKafkaCommon.ProcessOperationName); ActivityLink[] activityLinks = propagationContext != default && propagationContext.ActivityContext.IsValid() - ? new[] { new ActivityLink(propagationContext.ActivityContext) } - : Array.Empty(); + ? [new ActivityLink(propagationContext.ActivityContext)] + : []; - Activity? activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, parentContext: default); + var activity = ConfluentKafkaCommon.ActivitySource.StartActivity(spanName, kind: ActivityKind.Consumer, links: activityLinks, parentContext: default); if (activity?.IsAllDataRequested == true) { activity.SetTag(SemanticConventions.AttributeMessagingSystem, ConfluentKafkaCommon.KafkaMessagingSystem); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs index 0e2762a779..e26de22b62 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs @@ -22,7 +22,7 @@ public static class OpenTelemetryConsumerBuilderExtensions #endif public static InstrumentedConsumerBuilder AsInstrumentedConsumerBuilder(this ConsumerBuilder consumerBuilder) { - InstrumentedConsumerBuilder result = new InstrumentedConsumerBuilder(consumerBuilder.GetInternalConfig() ?? Enumerable.Empty>()); + var result = new InstrumentedConsumerBuilder(consumerBuilder.GetInternalConfig() ?? []); result.SetInternalErrorHandler(consumerBuilder.GetInternalErrorHandler()); result.SetInternalLogHandler(consumerBuilder.GetInternalLogHandler()); result.SetInternalStatisticsHandler(consumerBuilder.GetInternalStatisticsHandler()); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs index 071736f509..f2610c63ed 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs @@ -22,7 +22,7 @@ public static class OpenTelemetryProducerBuilderExtensions #endif public static InstrumentedProducerBuilder AsInstrumentedProducerBuilder(this ProducerBuilder producerBuilder) { - InstrumentedProducerBuilder instrumentedProducerBuilder = new InstrumentedProducerBuilder(producerBuilder.GetInternalConfig() ?? Enumerable.Empty>()); + var instrumentedProducerBuilder = new InstrumentedProducerBuilder(producerBuilder.GetInternalConfig() ?? []); instrumentedProducerBuilder.SetInternalLogHandler(producerBuilder.GetInternalLogHandler()); instrumentedProducerBuilder.SetInternalErrorHandler(producerBuilder.GetInternalErrorHandler()); instrumentedProducerBuilder.SetInternalStatisticsHandler(producerBuilder.GetInternalStatisticsHandler()); diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs index f9f188f343..228ef108eb 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedMeteringTests.cs @@ -18,7 +18,7 @@ public class HostedMeteringTests(ITestOutputHelper outputHelper) [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { - List metrics = new(); + List metrics = []; var builder = Host.CreateDefaultBuilder(); builder.ConfigureServices(services => { @@ -50,10 +50,10 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { await host.StartAsync(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (var producer = host.Services.GetRequiredService>().Build()) { - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) { producer.Produce(topic, new Message() { @@ -70,7 +70,7 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { consumer.Subscribe(topic); - int j = 0; + var j = 0; while (true) { var consumerResult = consumer.Consume(); diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs index c49f03deb1..8d4685c707 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingAndMeteringTests.cs @@ -84,10 +84,10 @@ public class HostedTracingAndMeteringTests(ITestOutputHelper outputHelper) [InlineData(false, false, false, false, false, false)] public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest(bool enableProducerMetrics, bool enableProducerTraces, bool useNamedProducerInstrumentation, bool enableConsumerMetrics, bool enableConsumerTraces, bool useNamedConsumerInstrumentation) { - string? producerInstrumentationName = useNamedProducerInstrumentation ? "MyProducer" : null; - string? consumerInstrumentationName = useNamedConsumerInstrumentation ? "MyConsumer" : null; - List metrics = new(); - List activities = new(); + var producerInstrumentationName = useNamedProducerInstrumentation ? "MyProducer" : null; + var consumerInstrumentationName = useNamedConsumerInstrumentation ? "MyConsumer" : null; + List metrics = []; + List activities = []; var builder = Host.CreateDefaultBuilder(); builder.ConfigureServices(services => { @@ -176,12 +176,12 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest(bool en Assert.Equal(enableConsumerMetrics, consumerBuilder.EnableMetrics); Assert.Equal(enableConsumerTraces, consumerBuilder.EnableTraces); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (var producer = (useNamedProducerInstrumentation ? host.Services.GetRequiredKeyedService>(producerInstrumentationName) : host.Services.GetRequiredService>()).Build()) { - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) { producer.Produce(topic, new Message() { @@ -207,7 +207,7 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest(bool en { consumer.Subscribe(topic); - int j = 0; + var j = 0; while (true) { var consumerResult = consumer.Consume(); @@ -238,7 +238,7 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest(bool en host.Services.GetRequiredService().EnsureMetricsAreFlushed(); } - IGrouping[] groups = metrics.GroupBy(x => x.Name).ToArray(); + var groups = metrics.GroupBy(x => x.Name).ToArray(); if (enableProducerMetrics) { diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs index d47d93d14f..07bae00bf3 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/HostedTracingTests.cs @@ -19,7 +19,7 @@ public class HostedTracingTests(ITestOutputHelper outputHelper) [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { - List activities = new(); + List activities = []; var builder = Host.CreateDefaultBuilder(); builder.ConfigureServices(services => { @@ -51,10 +51,10 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { await host.StartAsync(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (var producer = host.Services.GetRequiredService>().Build()) { - for (int i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) { producer.Produce(topic, new Message() { Key = $"any_key_{i}", Value = $"any_value_{i}", }); outputHelper.WriteLine("produced message {0}", i); @@ -67,7 +67,7 @@ public async Task ResolveInstrumentedBuildersFromHostServiceProviderTest() { consumer.Subscribe(topic); - int j = 0; + var j = 0; while (true) { var consumerResult = consumer.Consume(); diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs index 43929b6a31..df8c3d1c38 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/KafkaHelpers.cs @@ -14,13 +14,13 @@ internal static class KafkaHelpers public static async Task ProduceTestMessageAsync() { - string topic = $"otel-topic-{Guid.NewGuid()}"; - ProducerConfig producerConfig = new ProducerConfig + var topic = $"otel-topic-{Guid.NewGuid()}"; + var producerConfig = new ProducerConfig { BootstrapServers = KafkaEndPoint, }; ProducerBuilder producerBuilder = new(producerConfig); - IProducer producer = producerBuilder.Build(); + var producer = producerBuilder.Build(); await producer.ProduceAsync(topic, new Message { Value = "any_value", diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs index eff25507ff..eee6235952 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/MeteringTests.cs @@ -23,19 +23,19 @@ To use Docker... [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicProduceToTopicTest() { - ProducerConfig producerConfig = new ProducerConfig + var producerConfig = new ProducerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, }; InstrumentedProducerBuilder producerBuilder = new(producerConfig); var metrics = new List(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (var meterProvider = Sdk.CreateMeterProviderBuilder() .AddInMemoryExporter(metrics) .AddKafkaProducerInstrumentation(producerBuilder) .Build()) { - IProducer producer = producerBuilder.Build(); + var producer = producerBuilder.Build(); producer.Produce(topic, new Message { Value = "any_value", @@ -55,19 +55,19 @@ public async Task BasicProduceToTopicTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicProduceAsyncToTopicTest() { - ProducerConfig producerConfig = new ProducerConfig + var producerConfig = new ProducerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, }; InstrumentedProducerBuilder producerBuilder = new(producerConfig); var metrics = new List(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (var meterProvider = Sdk.CreateMeterProviderBuilder() .AddInMemoryExporter(metrics) .AddKafkaProducerInstrumentation(producerBuilder) .Build()) { - IProducer producer = producerBuilder.Build(); + var producer = producerBuilder.Build(); await producer.ProduceAsync(topic, new Message { Value = "any_value", @@ -87,9 +87,9 @@ public async Task BasicProduceAsyncToTopicTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicConsumeWithTimeoutTimespanTest() { - string topic = await KafkaHelpers.ProduceTestMessageAsync(); + var topic = await KafkaHelpers.ProduceTestMessageAsync(); - ConsumerConfig consumerConfig = new ConsumerConfig + var consumerConfig = new ConsumerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, GroupId = "test-consumer-group", @@ -104,7 +104,7 @@ public async Task BasicConsumeWithTimeoutTimespanTest() .AddKafkaConsumerInstrumentation(consumerBuilder) .Build()) { - using (IConsumer consumer = consumerBuilder.Build()) + using (var consumer = consumerBuilder.Build()) { consumer.Subscribe(topic); while (true) diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs index 1af7aefd27..7ed0bb9731 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs @@ -19,8 +19,8 @@ public void ShouldConvertConsumerBuilderToInstrumentedConsumerBuilder() var consumerBuilder = new ConsumerBuilder(config); - IDeserializer keyDeserializer = Deserializers.Utf8; - IDeserializer valueDeserializer = Deserializers.Utf8; + var keyDeserializer = Deserializers.Utf8; + var valueDeserializer = Deserializers.Utf8; consumerBuilder.SetErrorHandler(ErrorHandler); consumerBuilder.SetLogHandler(LogHandler); @@ -69,9 +69,20 @@ void OffsetsCommittedHandler(IConsumer consumer, CommittedOffset { } - IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) => new List(); - IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) => new List(); - IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) + { + return []; + } + + IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) + { + return []; + } + + IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) + { + return []; + } } [Fact] @@ -85,8 +96,8 @@ public void ShouldConvertUserDefinedConsumerBuilderToInstrumentedConsumerBuilder var consumerBuilder = new CustomConsumerBuilder(config); - IDeserializer keyDeserializer = Deserializers.Utf8; - IDeserializer valueDeserializer = Deserializers.Utf8; + var keyDeserializer = Deserializers.Utf8; + var valueDeserializer = Deserializers.Utf8; consumerBuilder.SetErrorHandler(ErrorHandler); consumerBuilder.SetLogHandler(LogHandler); @@ -135,9 +146,20 @@ void OffsetsCommittedHandler(IConsumer consumer, CommittedOffset { } - IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) => new List(); - IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) => new List(); - IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) + { + return []; + } + + IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) + { + return []; + } + + IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) + { + return []; + } } private class CustomConsumerBuilder(IEnumerable> config) diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs index 83025fe323..c82a5ca12b 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs @@ -19,8 +19,8 @@ public void ShouldConvertToInstrumentedProducerBuilder() var producerBuilder = new ProducerBuilder(config); - ISerializer keySerializer = Serializers.Utf8; - ISerializer valueSerializer = Serializers.Utf8; + var keySerializer = Serializers.Utf8; + var valueSerializer = Serializers.Utf8; producerBuilder.SetErrorHandler(ErrorHandler); producerBuilder.SetLogHandler(LogHandler); @@ -69,8 +69,8 @@ public void ShouldConvertUserDefinedProducerBuilderToInstrumentedProducerBuilder var producerBuilder = new CustomProducerBuilder(config); - ISerializer keySerializer = Serializers.Utf8; - ISerializer valueSerializer = Serializers.Utf8; + var keySerializer = Serializers.Utf8; + var valueSerializer = Serializers.Utf8; producerBuilder.SetErrorHandler(ErrorHandler); producerBuilder.SetLogHandler(LogHandler); diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs index b9de9a616b..cd60bd9a2c 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/TracingTests.cs @@ -24,21 +24,21 @@ To use Docker... [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicProduceAsyncToTopicTest() { - ProducerConfig producerConfig = new ProducerConfig + var producerConfig = new ProducerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, }; InstrumentedProducerBuilder producerBuilder = new(producerConfig); var sampler = new TestSampler(); var activities = new List(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(activities) .SetSampler(sampler) .AddKafkaProducerInstrumentation(producerBuilder) .Build()) { - using IProducer producer = producerBuilder.Build(); + using var producer = producerBuilder.Build(); await producer.ProduceAsync(topic, new Message { Value = "any_value", @@ -56,21 +56,21 @@ public async Task BasicProduceAsyncToTopicTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicProduceAsyncToTopicPartitionTest() { - ProducerConfig producerConfig = new ProducerConfig + var producerConfig = new ProducerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, }; InstrumentedProducerBuilder producerBuilder = new(producerConfig); var sampler = new TestSampler(); var activities = new List(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(activities) .SetSampler(sampler) .AddKafkaProducerInstrumentation(producerBuilder) .Build()) { - using IProducer producer = producerBuilder.Build(); + using var producer = producerBuilder.Build(); await producer.ProduceAsync(new TopicPartition(topic, new Partition(0)), new Message { Value = "any_value", @@ -89,21 +89,21 @@ public async Task BasicProduceAsyncToTopicPartitionTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public void BasicProduceSyncToTopicTest() { - ProducerConfig producerConfig = new ProducerConfig + var producerConfig = new ProducerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, }; InstrumentedProducerBuilder producerBuilder = new(producerConfig); var sampler = new TestSampler(); var activities = new List(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(activities) .SetSampler(sampler) .AddKafkaProducerInstrumentation(producerBuilder) .Build()) { - using IProducer producer = producerBuilder.Build(); + using var producer = producerBuilder.Build(); producer.Produce(topic, new Message { Value = "any_value", @@ -121,21 +121,21 @@ public void BasicProduceSyncToTopicTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public void BasicProduceSyncToTopicPartitionTest() { - ProducerConfig producerConfig = new ProducerConfig + var producerConfig = new ProducerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, }; InstrumentedProducerBuilder producerBuilder = new(producerConfig); var sampler = new TestSampler(); var activities = new List(); - string topic = $"otel-topic-{Guid.NewGuid()}"; + var topic = $"otel-topic-{Guid.NewGuid()}"; using (Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(activities) .SetSampler(sampler) .AddKafkaProducerInstrumentation(producerBuilder) .Build()) { - using IProducer producer = producerBuilder.Build(); + using var producer = producerBuilder.Build(); producer.Produce(new TopicPartition(topic, new Partition(0)), new Message { Value = "any_value", @@ -154,9 +154,9 @@ public void BasicProduceSyncToTopicPartitionTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicConsumeWithCancellationTokenTest() { - string topic = await KafkaHelpers.ProduceTestMessageAsync(); + var topic = await KafkaHelpers.ProduceTestMessageAsync(); - ConsumerConfig consumerConfig = new ConsumerConfig + var consumerConfig = new ConsumerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, GroupId = "test-consumer-group", @@ -172,7 +172,7 @@ public async Task BasicConsumeWithCancellationTokenTest() .AddKafkaConsumerInstrumentation(consumerBuilder) .Build()) { - using IConsumer consumer = consumerBuilder.Build(); + using var consumer = consumerBuilder.Build(); consumer.Subscribe(topic); while (true) { @@ -205,9 +205,9 @@ public async Task BasicConsumeWithCancellationTokenTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicConsumeWithTimeoutMsTest() { - string topic = await KafkaHelpers.ProduceTestMessageAsync(); + var topic = await KafkaHelpers.ProduceTestMessageAsync(); - ConsumerConfig consumerConfig = new ConsumerConfig + var consumerConfig = new ConsumerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, GroupId = "test-consumer-group", @@ -223,7 +223,7 @@ public async Task BasicConsumeWithTimeoutMsTest() .AddKafkaConsumerInstrumentation(consumerBuilder) .Build()) { - using IConsumer consumer = consumerBuilder.Build(); + using var consumer = consumerBuilder.Build(); consumer.Subscribe(topic); while (true) { @@ -256,9 +256,9 @@ public async Task BasicConsumeWithTimeoutMsTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task BasicConsumeWithTimeoutTimespanTest() { - string topic = await KafkaHelpers.ProduceTestMessageAsync(); + var topic = await KafkaHelpers.ProduceTestMessageAsync(); - ConsumerConfig consumerConfig = new ConsumerConfig + var consumerConfig = new ConsumerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, GroupId = "test-consumer-group", @@ -274,7 +274,7 @@ public async Task BasicConsumeWithTimeoutTimespanTest() .AddKafkaConsumerInstrumentation(consumerBuilder) .Build()) { - using IConsumer consumer = consumerBuilder.Build(); + using var consumer = consumerBuilder.Build(); consumer.Subscribe(topic); while (true) { @@ -307,9 +307,9 @@ public async Task BasicConsumeWithTimeoutTimespanTest() [SkipUnlessEnvVarFoundFact(KafkaHelpers.KafkaEndPointEnvVarName)] public async Task ConsumeAndProcessMessageTest() { - string topic = await KafkaHelpers.ProduceTestMessageAsync(); + var topic = await KafkaHelpers.ProduceTestMessageAsync(); - ConsumerConfig consumerConfig = new ConsumerConfig + var consumerConfig = new ConsumerConfig { BootstrapServers = KafkaHelpers.KafkaEndPoint, GroupId = "test-consumer-group", @@ -325,7 +325,7 @@ public async Task ConsumeAndProcessMessageTest() .AddKafkaConsumerInstrumentation(consumerBuilder) .Build()) { - using IConsumer consumer = consumerBuilder.Build(); + using var consumer = consumerBuilder.Build(); consumer.Subscribe(topic); while (true) { @@ -353,7 +353,7 @@ public async Task ConsumeAndProcessMessageTest() Assert.Equal(0L, processActivity.GetTagValue("messaging.kafka.message.offset")); Assert.Equal("test-consumer-group", processActivity.GetTagValue("messaging.kafka.consumer.group")); - ValueTask NoOpAsync( + static ValueTask NoOpAsync( ConsumeResult consumeResult, Activity? activity, CancellationToken cancellationToken = default) From 0351a0bcbcf8c43bcaab1fb17a01a9b845ca67c2 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 30 Oct 2024 10:17:23 -0700 Subject: [PATCH 1387/1499] [geneva] Add support for sending metrics in OTLP format over UDS (#2261) Co-authored-by: Cijo Thomas --- .../CHANGELOG.md | 21 ++- .../Metrics/GenevaMetricExporter.cs | 42 ++++- .../OtlpProtobufMetricExporter.cs | 31 ++-- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 27 ++-- .../MetricUnixDomainSocketDataTransport.cs | 10 +- src/OpenTelemetry.Exporter.Geneva/README.md | 73 +++++++-- .../Exporter/MetricExporterBenchmarks.cs | 4 +- .../OtlpProtobufMetricExporterTests.cs | 146 ++++++++++++------ ...lpProtobufMetricExporterWithPrefixTests.cs | 12 ++ ...rotobufMetricExporterWithoutPrefixTests.cs | 12 ++ 10 files changed, 274 insertions(+), 104 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs create mode 100644 test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index e1fbedc7df..7ca97b842c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -5,14 +5,19 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2117)) -* Added support for exporting metrics via - [user_events](https://docs.kernel.org/trace/user_events.html) on Linux when - OTLP protobuf encoding is enabled via the - `PrivatePreviewEnableOtlpProtobufEncoding=true` connection string switch. With - this, `PrivatePreviewEnableOtlpProtobufEncoding=true` is now supported on both - Widows and Linux. Windows uses ETW as transport, while Linux uses user_events - as transport. - ([#2113](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2113)) +* Added support for exporting metrics on Linux when OTLP protobuf encoding is + enabled via the `PrivatePreviewEnableOtlpProtobufEncoding=true` connection + string switch. `PrivatePreviewEnableOtlpProtobufEncoding=true` is now + supported on both Windows and Linux. + + * `user_events` transport: + [#2113](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2113). + + * Unix domain socket transport: + [#2261](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2261). + + For configuration details see: + [OtlpProtobufEncoding](./README.md#otlpprotobufencoding). ## 1.9.0 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index ed78dda6ee..8607744849 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Reflection; +using System.Runtime.InteropServices; using System.Text.RegularExpressions; using OpenTelemetry.Exporter.Geneva.Metrics; using OpenTelemetry.Internal; @@ -52,14 +53,49 @@ public GenevaMetricExporter(GenevaMetricExporterOptions options) if (connectionStringBuilder.PrivatePreviewEnableOtlpProtobufEncoding) { + IMetricDataTransport transport; + + if (connectionStringBuilder.Protocol == TransportProtocol.Unix) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new ArgumentException("Unix domain socket should not be used on Windows."); + } + + var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); + + transport = new MetricUnixDomainSocketDataTransport(unixDomainSocketPath); + } + else + { +#if NET6_0_OR_GREATER + transport = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? MetricUnixUserEventsDataTransport.Instance + : MetricWindowsEventTracingDataTransport.Instance; +#else + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new NotSupportedException("Exporting data in protobuf format is not supported on Linux."); + } + + transport = MetricWindowsEventTracingDataTransport.Instance; +#endif + } + + connectionStringBuilder.TryGetMetricsAccountAndNamespace( + out var metricsAccount, + out var metricsNamespace); + var otlpProtobufExporter = new OtlpProtobufMetricExporter( () => { return this.Resource; }, - connectionStringBuilder, + transport, + metricsAccount, + metricsNamespace, options.PrepopulatedMetricDimensions); - this.exporter = otlpProtobufExporter; - this.exportMetrics = otlpProtobufExporter.Export; + + this.exporter = otlpProtobufExporter; } else { diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs index 835c6cac1d..1931cf2dd4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufMetricExporter.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Runtime.InteropServices; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -18,30 +17,22 @@ internal sealed class OtlpProtobufMetricExporter : IDisposable public OtlpProtobufMetricExporter( Func getResource, - ConnectionStringBuilder? connectionStringBuilder, + IMetricDataTransport transport, + string? metricsAccount, + string? metricsNamespace, IReadOnlyDictionary? prepopulatedMetricDimensions) { Debug.Assert(getResource != null, "getResource was null"); + Debug.Assert(transport != null, "transport was null"); this.getResource = getResource!; -#if NET6_0_OR_GREATER - IMetricDataTransport transport = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) - ? MetricUnixUserEventsDataTransport.Instance - : MetricWindowsEventTracingDataTransport.Instance; -#else - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new NotSupportedException("Exporting data in protobuf format is not supported on Linux."); - } - - var transport = MetricWindowsEventTracingDataTransport.Instance; -#endif - this.otlpProtobufSerializer = new OtlpProtobufSerializer( - transport, - connectionStringBuilder, - prepopulatedMetricDimensions); + transport!, + metricsAccount, + metricsNamespace, + prepopulatedMetricDimensions, + prefixBufferWithUInt32LittleEndianLength: transport is MetricUnixDomainSocketDataTransport); } public ExportResult Export(in Batch batch) @@ -59,5 +50,9 @@ public ExportResult Export(in Batch batch) public void Dispose() { + if (this.otlpProtobufSerializer.MetricDataTransport is MetricUnixDomainSocketDataTransport udsTransport) + { + udsTransport.Dispose(); + } } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 73123d6b5f..e837fc327c 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Buffers.Binary; using System.Diagnostics; using System.Globalization; using OpenTelemetry.Metrics; @@ -17,6 +18,7 @@ internal sealed class OtlpProtobufSerializer private readonly Dictionary> scopeMetrics = new(); private readonly string? metricNamespace; private readonly string? metricAccount; + private readonly bool prefixBufferWithUInt32LittleEndianLength; private readonly byte[]? prepopulatedNumberDataPointAttributes; private readonly int prepopulatedNumberDataPointAttributesLength; private readonly byte[]? prepopulatedHistogramDataPointAttributes; @@ -37,12 +39,17 @@ internal sealed class OtlpProtobufSerializer public OtlpProtobufSerializer( IMetricDataTransport metricDataTransport, - ConnectionStringBuilder? connectionStringBuilder, - IReadOnlyDictionary? prepopulatedMetricDimensions) + string? metricsAccount, + string? metricsNamespace, + IReadOnlyDictionary? prepopulatedMetricDimensions, + bool prefixBufferWithUInt32LittleEndianLength = false) { Debug.Assert(metricDataTransport != null, "metricDataTransport was null"); this.MetricDataTransport = metricDataTransport!; + this.metricAccount = metricsAccount; + this.metricNamespace = metricsNamespace; + this.prefixBufferWithUInt32LittleEndianLength = prefixBufferWithUInt32LittleEndianLength; // Taking a arbitrary number here for writing attributes. byte[] temp = new byte[20000]; @@ -68,14 +75,6 @@ public OtlpProtobufSerializer( Array.Copy(temp, this.prepopulatedExponentialHistogramDataPointAttributes, cursor); this.prepopulatedExponentialHistogramDataPointAttributesLength = cursor; } - - if (connectionStringBuilder?.TryGetMetricsAccountAndNamespace( - out var metricsAccount, - out var metricsNamespace) == true) - { - this.metricAccount = metricsAccount; - this.metricNamespace = metricsNamespace; - } } internal static void WriteInstrumentDetails(byte[] buffer, ref int cursor, Metric metric) @@ -222,7 +221,7 @@ internal void ClearScopeMetrics() internal void SerializeResourceMetrics(byte[] buffer, Resource resource) { - int cursor = 0; + int cursor = this.prefixBufferWithUInt32LittleEndianLength ? 4 : 0; this.resourceMetricTagAndLengthIndex = cursor; @@ -734,11 +733,15 @@ private void WriteIndividualMessageTagsAndLength(byte[] buffer, ref int cursor, // Write resource metric tag and length ProtobufSerializerHelper.WriteTagAndLengthPrefix(buffer, ref resourceMetricIndex, cursor - this.resourceMetricValueIndex, FieldNumberConstants.ResourceMetrics_resource, WireType.LEN); + + if (this.prefixBufferWithUInt32LittleEndianLength) + { + BinaryPrimitives.WriteUInt32LittleEndian(buffer, (uint)cursor - 4); + } } private void SendMetricPoint(byte[] buffer, ref int cursor) { - // TODO: Extend this for user_events. this.MetricDataTransport.SendOtlpProtobufEvent(buffer, cursor); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs index 4faa04560f..70856642c1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricUnixDomainSocketDataTransport.cs @@ -28,6 +28,11 @@ public void Send(MetricEventType eventType, byte[] body, int size) this.udsDataTransport.Send(body, size + this.fixedPayloadLength); } + public void SendOtlpProtobufEvent(byte[] body, int size) + { + this.udsDataTransport.Send(body, size); + } + public void Dispose() { if (this.isDisposed) @@ -38,9 +43,4 @@ public void Dispose() this.udsDataTransport.Dispose(); this.isDisposed = true; } - - public void SendOtlpProtobufEvent(byte[] body, int size) - { - throw new NotImplementedException(); - } } diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 2ba0725906..2410808596 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -270,23 +270,72 @@ For example: ##### OtlpProtobufEncoding -On Windows set `PrivatePreviewEnableOtlpProtobufEncoding=true` on the -`ConnectionString` to opt-in to the experimental feature for changing the -underlying serialization format to binary protobuf following the schema defined -in [OTLP +An experimental feature flag is available to opt-into changing the underlying +serialization format to binary protobuf following the schema defined in [OTLP specification](https://github.com/open-telemetry/opentelemetry-proto/blob/v1.1.0/opentelemetry/proto/metrics/v1/metrics.proto). +When using OTLP protobuf encoding `Account` and `Namespace` are **NOT** required +to be set on the `ConnectionString`. The recommended approach is to use +OpenTelemetry Resource instead: + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + // Other configuration not shown + .ConfigureResource(r => r.AddAttributes( + new Dictionary() + { + ["_microsoft_metrics_account"] = "MetricsAccountGoesHere", + ["_microsoft_metrics_namespace"] = "MetricsNamespaceGoesHere", + })) + .AddGenevaMetricExporter(options => + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + options.ConnectionString = "PrivatePreviewEnableOtlpProtobufEncoding=true"; + } + else + { + // Note: 1.10.0+ version required to use OTLP protobuf encoding on Linux + + // Use Unix domain socket mode + options.ConnectionString = "Endpoint=unix:{OTLP UDS Path};PrivatePreviewEnableOtlpProtobufEncoding=true"; + + // Use user_events mode (preferred but considered experimental as this is a new capability in Linux kernel) + // options.ConnectionString = "PrivatePreviewEnableOtlpProtobufEncoding=true"; + } + }) + .Build(); +``` + +###### Windows + +To send metric data over ETW using OTLP protobuf encoding set +`PrivatePreviewEnableOtlpProtobufEncoding=true` on the `ConnectionString`. + +###### Linux + As of `1.10.0` `PrivatePreviewEnableOtlpProtobufEncoding=true` is also supported -on Linux. On Linux when using `PrivatePreviewEnableOtlpProtobufEncoding=true` an -`Endpoint` is **NOT** required to be provided on `ConnectionString`. For -example: `Endpoint=unix:Account={MetricAccount};Namespace={MetricNamespace}`. +on Linux. + +###### When using unix domain socket + +To send metric data over UDS using OTLP protobuf encoding set the `Endpoint` to +use the correct `OtlpSocketPath` path and set +`PrivatePreviewEnableOtlpProtobufEncoding=true` on the `ConnectionString`: +`Endpoint=unix:{OTLP UDS Path};PrivatePreviewEnableOtlpProtobufEncoding=true`. > [!IMPORTANT] -> When `PrivatePreviewEnableOtlpProtobufEncoding` is enabled on Linux metrics -> are written using -> [user_events](https://docs.kernel.org/trace/user_events.html). `user_events` -> are a newer feature of the Linux kernel and require a distro with the feature -> enabled. +> OTLP over UDS requires a different socket path than TLV over UDS. + +###### When using user_events + +> [!IMPORTANT] +> [user_events](https://docs.kernel.org/trace/user_events.html) are a newer +> feature of the Linux kernel and require a distro with the feature enabled. + +To send metric data over user_events using OTLP protobuf encoding do **NOT** +specify an `Endpoint` and set `PrivatePreviewEnableOtlpProtobufEncoding=true` on +the `ConnectionString`. #### `MetricExportIntervalMilliseconds` (optional) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs index 0e45b72a37..70c343a0fc 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs @@ -111,12 +111,12 @@ public void Setup() this.tlvMetricsExporter = new TlvMetricExporter(connectionStringBuilder, exporterOptions.PrepopulatedMetricDimensions); // Using test transport here with noop to benchmark just the serialization part. - this.otlpProtobufSerializer = new OtlpProtobufSerializer(new TestTransport(), null, null); + this.otlpProtobufSerializer = new OtlpProtobufSerializer(new TestTransport(), metricsAccount: null, metricsNamespace: null, prepopulatedMetricDimensions: null); var resourceBuilder = ResourceBuilder.CreateDefault().Clear() .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); this.resource = resourceBuilder.Build(); - this.otlpProtobufMetricExporter = new OtlpProtobufMetricExporter(() => { return this.resource; }, null, null); + this.otlpProtobufMetricExporter = new OtlpProtobufMetricExporter(() => { return this.resource; }, new TestTransport(), metricsAccount: null, metricsNamespace: null, prepopulatedMetricDimensions: null); this.buffer = new byte[GenevaMetricExporter.BufferSize]; this.counterMetricPointWith3Dimensions = this.GenerateCounterMetricItemWith3Dimensions(out this.counterMetricDataWith3Dimensions); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index cc8d84b9cc..4870b6aee1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -14,7 +14,7 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; -public class OtlpProtobufMetricExporterTests +public abstract class OtlpProtobufMetricExporterTests { public TagList TagList; @@ -50,7 +50,7 @@ public class OtlpProtobufMetricExporterTests private TagList exemplarTagList; - public OtlpProtobufMetricExporterTests() + protected OtlpProtobufMetricExporterTests() { this.TagList = default; @@ -95,6 +95,8 @@ public OtlpProtobufMetricExporterTests() this.exemplarTagList.Add(new("zfilteredKey1", "zfilteredValue1")); } + protected abstract bool PrefixBufferWithUInt32LittleEndianLength { get; } + [Theory] [InlineData("longcounter", 123L, null, true, true, true, true)] [InlineData("longcounter", 123L, null, true, true, true, false)] @@ -238,17 +240,19 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l var testTransport = new TestTransport(); - ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); - - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + addAccountAndNamespace ? expectedAccount : null, + addAccountAndNamespace ? expectedNamespace : null, + addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); Assert.Single(testTransport.ExportedItems); - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[0]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[0]); Assert.Single(request.ResourceMetrics); @@ -410,7 +414,13 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + metricsAccount: null, + metricsNamespace: null, + prepopulatedMetricDimensions: null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -421,9 +431,8 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long for (int i = 0; i < expectedMetricPoints; i++) { - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[i]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[i]); Assert.Single(request.ResourceMetrics); @@ -535,16 +544,20 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l var buffer = new byte[65360]; var testTransport = new TestTransport(); - ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + addAccountAndNamespace ? expectedAccount : null, + addAccountAndNamespace ? expectedNamespace : null, + addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); Assert.Single(testTransport.ExportedItems); - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[0]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[0]); Assert.Single(request.ResourceMetrics); @@ -656,7 +669,13 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + metricsAccount: null, + metricsNamespace: null, + prepopulatedMetricDimensions: null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -667,9 +686,8 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName for (int i = 0; i < expectedMetricPoints; i++) { - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[i]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[i]); Assert.Single(request.ResourceMetrics); @@ -811,16 +829,20 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add var buffer = new byte[65360]; var testTransport = new TestTransport(); - ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + addAccountAndNamespace ? expectedAccount : null, + addAccountAndNamespace ? expectedNamespace : null, + addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); Assert.Single(testTransport.ExportedItems); - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[0]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[0]); Assert.Single(request.ResourceMetrics); @@ -982,7 +1004,13 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + metricsAccount: null, + metricsNamespace: null, + prepopulatedMetricDimensions: null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -992,9 +1020,8 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) for (int i = 0; i < expectedMetricPointCount; i++) { - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[i]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[i]); Assert.NotNull(request.ResourceMetrics[0].Resource); @@ -1133,16 +1160,20 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon var buffer = new byte[65360]; var testTransport = new TestTransport(); - ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + addAccountAndNamespace ? expectedAccount : null, + addAccountAndNamespace ? expectedNamespace : null, + addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); Assert.Single(testTransport.ExportedItems); - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[0]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[0]); Assert.Single(request.ResourceMetrics); @@ -1264,7 +1295,13 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] var buffer = new byte[65360]; var testTransport = new TestTransport(); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, null, null); + + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + metricsAccount: null, + metricsNamespace: null, + prepopulatedMetricDimensions: null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); @@ -1275,9 +1312,8 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] for (int i = 0; i < expectedMetricPoints; i++) { - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[i]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[i]); Assert.Single(request.ResourceMetrics); @@ -1424,16 +1460,19 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal var testTransport = new TestTransport(); - ConnectionStringBuilder connectionStringBuilder = new ConnectionStringBuilder($"Account={expectedAccount};Namespace={expectedNamespace}"); - var otlpProtobufSerializer = new OtlpProtobufSerializer(testTransport, addAccountAndNamespace ? connectionStringBuilder : null, addPrepopulatedDimensions ? prepopulatedMetricDimensions : null); + var otlpProtobufSerializer = new OtlpProtobufSerializer( + testTransport, + addAccountAndNamespace ? expectedAccount : null, + addAccountAndNamespace ? expectedNamespace : null, + addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, + prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); Assert.Single(testTransport.ExportedItems); - var request = new OtlpCollector.ExportMetricsServiceRequest(); - - request.MergeFrom(testTransport.ExportedItems[0]); + var request = this.AssertAndConvertExportedBlobToRequest( + testTransport.ExportedItems[0]); Assert.Single(request.ResourceMetrics); @@ -1623,6 +1662,25 @@ private static void AssertOtlpAttributeValue(object expected, OtlpCommon.AnyValu } } + private OtlpCollector.ExportMetricsServiceRequest AssertAndConvertExportedBlobToRequest( + byte[] blob) + { + var request = new OtlpCollector.ExportMetricsServiceRequest(); + + if (this.PrefixBufferWithUInt32LittleEndianLength) + { + var content = blob.AsSpan().Slice(4); + Assert.Equal((uint)content.Length, BitConverter.ToUInt32(blob, 0)); + request.MergeFrom(content); + } + else + { + request.MergeFrom(blob); + } + + return request; + } + private class TestTransport : IMetricDataTransport { public List ExportedItems = new(); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs new file mode 100644 index 0000000000..9421c8de95 --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs @@ -0,0 +1,12 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +[Collection("OtlpProtobufMetricExporterTests")] +public class OtlpProtobufMetricExporterWithPrefixTests : OtlpProtobufMetricExporterTests +{ + protected override bool PrefixBufferWithUInt32LittleEndianLength => true; +} diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs new file mode 100644 index 0000000000..f21059620f --- /dev/null +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs @@ -0,0 +1,12 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Xunit; + +namespace OpenTelemetry.Exporter.Geneva.Tests; + +[Collection("OtlpProtobufMetricExporterTests")] +public class OtlpProtobufMetricExporterWithoutPrefixTests : OtlpProtobufMetricExporterTests +{ + protected override bool PrefixBufferWithUInt32LittleEndianLength => false; +} From 72d1030d5ee16d5fdc9f6e2d61c9aa1a1747da0d Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Wed, 30 Oct 2024 11:56:05 -0700 Subject: [PATCH 1388/1499] [SqlClient] Include instance in `db.namespace` and activity name, start activity with required tags (#2277) --- .../CHANGELOG.md | 8 +- .../Implementation/SqlActivitySourceHelper.cs | 71 +++++++--- .../SqlClientDiagnosticListener.cs | 55 +++----- .../SqlEventSourceListener.netfx.cs | 23 +-- .../SqlClientTestCase.cs | 53 +++++++ .../SqlClientTests.cs | 132 ++++++++++++++---- .../SqlEventSourceTests.netfx.cs | 12 +- 7 files changed, 247 insertions(+), 107 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index b6fa12db57..bfc0dc4d1e 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -24,7 +24,8 @@ specification for more information regarding the new database semantic conventions for [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-spans.md). - ([#2229](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2229)) + ([#2229](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2229), + [#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277)) * **Breaking change**: The `peer.service` and `server.socket.address` attributes are no longer emitted. Users should rely on the `server.address` attribute for the same information. Note that `server.address` is only included when @@ -37,6 +38,11 @@ ([#2233](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2233)) * The `EnableConnectionLevelAttributes` option is now enabled by default. ([#2249](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2249)) +* The following attributes are now provided when starting an activity for a database + call: `db.system`, `db.name` (old conventions), `db.namespace` (new conventions), + `server.address`, and `server.port`. These attributes are now available for sampling + decisions. + ([#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277)) ## 1.9.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index 88bf750c9d..b20a2d5174 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -20,41 +20,72 @@ internal sealed class SqlActivitySourceHelper public static readonly AssemblyName AssemblyName = Assembly.GetName(); public static readonly string ActivitySourceName = AssemblyName.Name!; public static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); - public static readonly string ActivityName = ActivitySourceName + ".Execute"; - public static readonly IEnumerable> CreationTags = new[] + public static TagList GetTagListFromConnectionInfo(string? dataSource, string? databaseName, SqlClientTraceInstrumentationOptions options, out string activityName) { - new KeyValuePair(SemanticConventions.AttributeDbSystem, MicrosoftSqlServerDatabaseSystemName), - }; + activityName = MicrosoftSqlServerDatabaseSystemName; - public static void AddConnectionLevelDetailsToActivity(string dataSource, Activity activity, SqlClientTraceInstrumentationOptions options) - { - // TODO: The attributes added here are required. We need to consider - // collecting these attributes by default. - if (options.EnableConnectionLevelAttributes) + var tags = new TagList { - var connectionDetails = SqlConnectionDetails.ParseFromDataSource((string)dataSource); + { SemanticConventions.AttributeDbSystem, MicrosoftSqlServerDatabaseSystemName }, + }; - // TODO: In the new conventions, instance name should now be captured - // as a part of db.namespace, when available. - if (options.EmitOldAttributes && !string.IsNullOrEmpty(connectionDetails.InstanceName)) + if (options.EnableConnectionLevelAttributes && dataSource != null) + { + var connectionDetails = SqlConnectionDetails.ParseFromDataSource(dataSource); + + if (options.EmitOldAttributes && !string.IsNullOrEmpty(databaseName)) + { + tags.Add(SemanticConventions.AttributeDbName, databaseName); + activityName = databaseName!; + } + + if (options.EmitNewAttributes && !string.IsNullOrEmpty(databaseName)) + { + var dbNamespace = !string.IsNullOrEmpty(connectionDetails.InstanceName) + ? $"{connectionDetails.InstanceName}.{databaseName}" // TODO: Refactor SqlConnectionDetails to include database to avoid string allocation here. + : databaseName!; + tags.Add(SemanticConventions.AttributeDbNamespace, dbNamespace); + activityName = dbNamespace; + } + + var serverAddress = connectionDetails.ServerHostName ?? connectionDetails.ServerIpAddress; + if (!string.IsNullOrEmpty(serverAddress)) { - activity.SetTag(SemanticConventions.AttributeDbMsSqlInstanceName, connectionDetails.InstanceName); + tags.Add(SemanticConventions.AttributeServerAddress, serverAddress); + if (connectionDetails.Port.HasValue) + { + tags.Add(SemanticConventions.AttributeServerPort, connectionDetails.Port); + } + + if (activityName == MicrosoftSqlServerDatabaseSystemName) + { + activityName = connectionDetails.Port.HasValue + ? $"{serverAddress}:{connectionDetails.Port}" // TODO: Another opportunity to refactor SqlConnectionDetails + : serverAddress!; + } } - if (!string.IsNullOrEmpty(connectionDetails.ServerHostName)) + if (options.EmitOldAttributes && !string.IsNullOrEmpty(connectionDetails.InstanceName)) { - activity.SetTag(SemanticConventions.AttributeServerAddress, connectionDetails.ServerHostName); + tags.Add(SemanticConventions.AttributeDbMsSqlInstanceName, connectionDetails.InstanceName); } - else + } + else if (!string.IsNullOrEmpty(databaseName)) + { + if (options.EmitNewAttributes) { - activity.SetTag(SemanticConventions.AttributeServerAddress, connectionDetails.ServerIpAddress); + tags.Add(SemanticConventions.AttributeDbNamespace, databaseName); } - if (connectionDetails.Port.HasValue) + if (options.EmitOldAttributes) { - activity.SetTag(SemanticConventions.AttributeServerPort, connectionDetails.Port); + tags.Add(SemanticConventions.AttributeDbName, databaseName); } + + activityName = databaseName!; } + + return tags; } } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index b16f71402a..f0739ac7ec 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -27,8 +27,8 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler private readonly PropertyFetcher commandFetcher = new("Command"); private readonly PropertyFetcher connectionFetcher = new("Connection"); - private readonly PropertyFetcher dataSourceFetcher = new("DataSource"); - private readonly PropertyFetcher databaseFetcher = new("Database"); + private readonly PropertyFetcher dataSourceFetcher = new("DataSource"); + private readonly PropertyFetcher databaseFetcher = new("Database"); private readonly PropertyFetcher commandTypeFetcher = new("CommandType"); private readonly PropertyFetcher commandTextFetcher = new("CommandText"); private readonly PropertyFetcher exceptionFetcher = new("Exception"); @@ -50,12 +50,23 @@ public override void OnEventWritten(string name, object? payload) case SqlDataBeforeExecuteCommand: case SqlMicrosoftBeforeExecuteCommand: { - // SqlClient does not create an Activity. So the activity coming in here will be null or the root span. + _ = this.commandFetcher.TryFetch(payload, out var command); + if (command == null) + { + SqlClientInstrumentationEventSource.Log.NullPayload(nameof(SqlClientDiagnosticListener), name); + return; + } + + _ = this.connectionFetcher.TryFetch(command, out var connection); + _ = this.databaseFetcher.TryFetch(connection, out var databaseName); + _ = this.dataSourceFetcher.TryFetch(connection, out var dataSource); + + var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, this.options, out var activityName); activity = SqlActivitySourceHelper.ActivitySource.StartActivity( - SqlActivitySourceHelper.ActivityName, + activityName, ActivityKind.Client, default(ActivityContext), - SqlActivitySourceHelper.CreationTags); + startTags); if (activity == null) { @@ -63,14 +74,6 @@ public override void OnEventWritten(string name, object? payload) return; } - _ = this.commandFetcher.TryFetch(payload, out var command); - if (command == null) - { - SqlClientInstrumentationEventSource.Log.NullPayload(nameof(SqlClientDiagnosticListener), name); - activity.Stop(); - return; - } - if (activity.IsAllDataRequested) { try @@ -91,34 +94,8 @@ public override void OnEventWritten(string name, object? payload) return; } - _ = this.connectionFetcher.TryFetch(command, out var connection); - _ = this.databaseFetcher.TryFetch(connection, out var database); - - // TODO: Need to understand what scenario (if any) database will be null here - // so that we set DisplayName and db.name/db.namespace correctly. - if (database != null) - { - activity.DisplayName = (string)database; - - if (this.options.EmitOldAttributes) - { - activity.SetTag(SemanticConventions.AttributeDbName, database); - } - - if (this.options.EmitNewAttributes) - { - activity.SetTag(SemanticConventions.AttributeDbNamespace, database); - } - } - - _ = this.dataSourceFetcher.TryFetch(connection, out var dataSource); _ = this.commandTextFetcher.TryFetch(command, out var commandText); - if (dataSource != null) - { - SqlActivitySourceHelper.AddConnectionLevelDetailsToActivity((string)dataSource, activity, this.options); - } - if (this.commandTypeFetcher.TryFetch(command, out CommandType commandType)) { switch (commandType) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index 0b4085183a..19a6f7526d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -112,11 +112,14 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) return; } + string dataSource = (string)eventData.Payload[1]; + string databaseName = (string)eventData.Payload[2]; + var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, this.options, out var activityName); var activity = SqlActivitySourceHelper.ActivitySource.StartActivity( - SqlActivitySourceHelper.ActivityName, + activityName, ActivityKind.Client, default(ActivityContext), - SqlActivitySourceHelper.CreationTags); + startTags); if (activity == null) { @@ -124,24 +127,8 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) return; } - string? databaseName = (string)eventData.Payload[2]; - - activity.DisplayName = databaseName; - if (activity.IsAllDataRequested) { - if (this.options.EmitOldAttributes) - { - activity.SetTag(SemanticConventions.AttributeDbName, databaseName); - } - - if (this.options.EmitNewAttributes) - { - activity.SetTag(SemanticConventions.AttributeDbNamespace, databaseName); - } - - SqlActivitySourceHelper.AddConnectionLevelDetailsToActivity((string)eventData.Payload[1], activity, this.options); - string commandText = (string)eventData.Payload[3]; if (!string.IsNullOrEmpty(commandText) && this.options.SetDbStatementForText) { diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs new file mode 100644 index 0000000000..f2b7e07e2b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs @@ -0,0 +1,53 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Collections; + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +public class SqlClientTestCase : IEnumerable +{ + public string ConnectionString { get; set; } = string.Empty; + + public string ExpectedActivityName { get; set; } = string.Empty; + + public string? ExpectedServerAddress { get; set; } + + public int? ExpectedPort { get; set; } + + public string? ExpectedDbNamespace { get; set; } + + public string? ExpectedInstanceName { get; set; } + + private static SqlClientTestCase[] TestCases => + [ + new SqlClientTestCase + { + ConnectionString = @"Data Source=SomeServer", + ExpectedActivityName = "SomeServer", + ExpectedServerAddress = "SomeServer", + ExpectedPort = null, + ExpectedDbNamespace = null, + ExpectedInstanceName = null, + }, + new SqlClientTestCase + { + ConnectionString = @"Data Source=SomeServer,1434", + ExpectedActivityName = "SomeServer:1434", + ExpectedServerAddress = "SomeServer", + ExpectedPort = 1434, + ExpectedDbNamespace = null, + ExpectedInstanceName = null, + }, + ]; + + public IEnumerator GetEnumerator() + { + foreach (var testCase in TestCases) + { + yield return new object[] { testCase }; + } + } + + IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); +} diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 0328780b18..d978beed88 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -200,27 +200,27 @@ public void SqlClientAddsConnectionLevelAttributes( bool emitOldAttributes = true, bool emitNewAttributes = false) { - var activity = new Activity("Test Sql Activity"); var options = new SqlClientTraceInstrumentationOptions() { EnableConnectionLevelAttributes = enableConnectionLevelAttributes, EmitOldAttributes = emitOldAttributes, EmitNewAttributes = emitNewAttributes, }; - SqlActivitySourceHelper.AddConnectionLevelDetailsToActivity(dataSource, activity, options); - Assert.Equal(expectedServerHostName ?? expectedServerIpAddress, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + var tags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName: null, options, out var _); + + Assert.Equal(expectedServerHostName ?? expectedServerIpAddress, tags.FirstOrDefault(x => x.Key == SemanticConventions.AttributeServerAddress).Value); if (emitOldAttributes) { - Assert.Equal(expectedInstanceName, activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); + Assert.Equal(expectedInstanceName, tags.FirstOrDefault(x => x.Key == SemanticConventions.AttributeDbMsSqlInstanceName).Value); } else { - Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); + Assert.Null(tags.FirstOrDefault(x => x.Key == SemanticConventions.AttributeDbMsSqlInstanceName).Value); } - Assert.Equal(expectedPort, activity.GetTagValue(SemanticConventions.AttributeServerPort)); + Assert.Equal(expectedPort, tags.FirstOrDefault(x => x.Key == SemanticConventions.AttributeServerPort).Value); } [Theory] @@ -291,27 +291,17 @@ public void SqlClientErrorsAreCollectedSuccessfully(string beforeCommand, string } [Theory] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand)] - public void SqlClientCreatesActivityWithDbSystem( - string beforeCommand) + [ClassData(typeof(SqlClientTestCase))] + public void SqlDataStartsActivityWithExpectedAttributes(SqlClientTestCase testCase) { - using var sqlConnection = new SqlConnection(TestConnectionString); - using var sqlCommand = sqlConnection.CreateCommand(); - - var sampler = new TestSampler - { - SamplingAction = _ => new SamplingResult(SamplingDecision.Drop), - }; - using (Sdk.CreateTracerProviderBuilder() - .AddSqlClientInstrumentation() - .SetSampler(sampler) - .Build()) - { - this.fakeSqlClientDiagnosticSource.Write(beforeCommand, new { }); - } + this.RunSqlClientTestCase(testCase, SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand); + } - VerifySamplingParameters(sampler.LatestSamplingParameters); + [Theory] + [ClassData(typeof(SqlClientTestCase))] + public void MicrosoftDataStartsActivityWithExpectedAttributes(SqlClientTestCase testCase) + { + this.RunSqlClientTestCase(testCase, SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand); } [Fact] @@ -384,7 +374,15 @@ internal static void VerifyActivityData( bool emitOldAttributes = true, bool emitNewAttributes = false) { - Assert.Equal("master", activity.DisplayName); + if (emitNewAttributes) + { + Assert.Equal("MSSQLLocalDB.master", activity.DisplayName); + } + else + { + Assert.Equal("master", activity.DisplayName); + } + Assert.Equal(ActivityKind.Client, activity.Kind); if (!isFailure) @@ -429,7 +427,7 @@ internal static void VerifyActivityData( if (emitNewAttributes) { - Assert.Equal("master", activity.GetTagValue(SemanticConventions.AttributeDbNamespace)); + Assert.Equal("MSSQLLocalDB.master", activity.GetTagValue(SemanticConventions.AttributeDbNamespace)); } switch (commandType) @@ -488,6 +486,60 @@ internal static void VerifySamplingParameters(SamplingParameters samplingParamet && (string)kvp.Value == SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName); } + internal static void VerifySamplingParameters(SqlClientTestCase testCase, Activity activity, SamplingParameters samplingParameters) + { + Assert.NotNull(samplingParameters.Tags); + + Assert.Equal(testCase.ExpectedActivityName, activity.DisplayName); + Assert.Equal(SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName, activity.GetTagItem(SemanticConventions.AttributeDbSystem)); + Assert.Equal(testCase.ExpectedDbNamespace, activity.GetTagItem(SemanticConventions.AttributeDbName)); + Assert.Equal(testCase.ExpectedServerAddress, activity.GetTagItem(SemanticConventions.AttributeServerAddress)); + Assert.Equal(testCase.ExpectedPort, activity.GetTagItem(SemanticConventions.AttributeServerPort)); + Assert.Equal(testCase.ExpectedInstanceName, activity.GetTagItem(SemanticConventions.AttributeDbMsSqlInstanceName)); + + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeDbSystem + && kvp.Value is string + && (string)kvp.Value == SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName); + + if (testCase.ExpectedDbNamespace != null) + { + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeDbName + && kvp.Value is string + && (string)kvp.Value == testCase.ExpectedDbNamespace); + } + + if (testCase.ExpectedServerAddress != null) + { + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeServerAddress + && kvp.Value is string + && (string)kvp.Value == testCase.ExpectedServerAddress); + } + + if (testCase.ExpectedPort.HasValue) + { + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeServerPort + && kvp.Value is int + && (int)kvp.Value == testCase.ExpectedPort); + } + + if (testCase.ExpectedInstanceName != null) + { + Assert.Contains( + samplingParameters.Tags, + kvp => kvp.Key == SemanticConventions.AttributeDbMsSqlInstanceName + && kvp.Value is string + && (string)kvp.Value == testCase.ExpectedInstanceName); + } + } + internal static void ActivityEnrichment(Activity activity, string method, object obj) { activity.SetTag("enriched", "yes"); @@ -504,6 +556,32 @@ internal static void ActivityEnrichment(Activity activity, string method, object } #if !NETFRAMEWORK + private void RunSqlClientTestCase(SqlClientTestCase testCase, string beforeCommand, string afterCommand) + { + using var sqlConnection = new SqlConnection(testCase.ConnectionString); + using var sqlCommand = sqlConnection.CreateCommand(); + + var exportedItems = new List(); + + var sampler = new TestSampler + { + SamplingAction = _ => new SamplingResult(SamplingDecision.RecordAndSample), + }; + + using (Sdk.CreateTracerProviderBuilder() + .AddSqlClientInstrumentation() + .SetSampler(sampler) + .AddInMemoryExporter(exportedItems) + .Build()) + { + this.fakeSqlClientDiagnosticSource.Write(beforeCommand, new { Command = sqlCommand }); + this.fakeSqlClientDiagnosticSource.Write(afterCommand, new { Command = sqlCommand }); + } + + Assert.Single(exportedItems); + VerifySamplingParameters(testCase, exportedItems.First(), sampler.LatestSamplingParameters); + } + private Activity[] RunCommandWithFilter( Action sqlCommandSetup, Func filter) diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index 1d1c234c85..2280e5502f 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -243,7 +243,15 @@ private static void VerifyActivityData( bool emitOldAttributes = true, bool emitNewAttributes = false) { - Assert.Equal("master", activity.DisplayName); + if (emitNewAttributes && enableConnectionLevelAttributes) + { + Assert.Equal("instanceName.master", activity.DisplayName); + } + else + { + Assert.Equal("master", activity.DisplayName); + } + Assert.Equal(ActivityKind.Client, activity.Kind); Assert.Equal(SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName, activity.GetTagValue(SemanticConventions.AttributeDbSystem)); @@ -282,7 +290,7 @@ private static void VerifyActivityData( if (emitNewAttributes) { - Assert.Equal("master", activity.GetTagValue(SemanticConventions.AttributeDbNamespace)); + Assert.Equal(!enableConnectionLevelAttributes ? "master" : "instanceName.master", activity.GetTagValue(SemanticConventions.AttributeDbNamespace)); } if (captureText) From d4b2e61956e5402b771137ff4b2caf828f029cab Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:35:42 -0700 Subject: [PATCH 1389/1499] [SqlClient] For `CommandType.StoredProcedure` set `db.operation.name` and `db.collection.name` (#2279) --- src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md | 3 ++- .../Implementation/SqlClientDiagnosticListener.cs | 2 ++ .../SqlClientTests.cs | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index bfc0dc4d1e..1a3b4168e7 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -25,7 +25,8 @@ semantic conventions for [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-spans.md). ([#2229](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2229), - [#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277)) + [#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277), + [#2279](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2279)) * **Breaking change**: The `peer.service` and `server.socket.address` attributes are no longer emitted. Users should rely on the `server.address` attribute for the same information. Note that `server.address` is only included when diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index f0739ac7ec..b8b20b72ac 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -110,6 +110,8 @@ public override void OnEventWritten(string name, object? payload) if (this.options.EmitNewAttributes) { + activity.SetTag(SemanticConventions.AttributeDbOperationName, "EXECUTE"); + activity.SetTag(SemanticConventions.AttributeDbCollectionName, commandText); activity.SetTag(SemanticConventions.AttributeDbQueryText, commandText); } } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index d978beed88..1eb6774267 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -442,6 +442,8 @@ internal static void VerifyActivityData( if (emitNewAttributes) { + Assert.Equal("EXECUTE", activity.GetTagValue(SemanticConventions.AttributeDbOperationName)); + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbCollectionName)); Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbQueryText)); } } From 32d6db527ba3e4681d4ba0bf838428e04ce8585e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 31 Oct 2024 20:00:26 +0100 Subject: [PATCH 1390/1499] [repo/AwsInstrumentations] Prepare to .NET9 (#2272) --- .../Implementation/AWSServiceHelper.cs | 42 +++--- .../AWSTracingPipelineHandler.cs | 8 +- .../Implementation/Metrics/AWSHistogram.cs | 5 +- .../Metrics/AWSMeterProvider.cs | 4 +- .../Metrics/AWSMonotonicCounter.cs | 5 +- .../Metrics/AWSUpDownCounter.cs | 5 +- .../Implementation/SnsRequestContextHelper.cs | 4 +- .../Implementation/SqsRequestContextHelper.cs | 4 +- .../Implementation/Tracing/AWSTraceSpan.cs | 1 + .../Implementation/Tracing/AWSTracer.cs | 3 +- .../Tracing/AWSTracerProvider.cs | 4 +- .../Implementation/Utils.cs | 33 ++--- .../Implementation/AWSLambdaHttpUtils.cs | 14 +- .../Implementation/AWSLambdaUtils.cs | 18 +-- .../Implementation/AWSMessagingUtils.cs | 35 ++--- .../RequestContextHelperTests.cs | 2 +- .../Implementation/TestsHelper.cs | 21 ++- .../TestAWSClientInstrumentation.cs | 121 +++++++++--------- .../TestAWSClientMetricsInstrumentation.cs | 10 +- .../TestRequest.cs | 6 +- .../Tools/CustomResponses.cs | 26 ++-- .../Tools/CustomWebResponse.cs | 29 ++--- .../Tools/MockHttpRequest.cs | 27 +--- .../Tools/MockWebResponse.cs | 22 ++-- .../Tools/Utils.cs | 17 +-- .../AWSLambdaWrapperTests.cs | 4 +- .../Implementation/AWSLambdaHttpUtilsTests.cs | 8 +- .../Implementation/AWSMessagingUtilsTests.cs | 24 ++-- .../SampleHandlers.cs | 13 +- .../SampleLambdaContext.cs | 2 +- 30 files changed, 223 insertions(+), 294 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index bbe8e318a3..7e87865b3c 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -9,17 +9,17 @@ internal class AWSServiceHelper { internal static IReadOnlyDictionary> ServiceRequestParameterMap = new Dictionary>() { - { AWSServiceType.DynamoDbService, new List { "TableName" } }, - { AWSServiceType.SQSService, new List { "QueueUrl" } }, - { AWSServiceType.BedrockAgentService, new List { "AgentId", "KnowledgeBaseId", "DataSourceId" } }, - { AWSServiceType.BedrockAgentRuntimeService, new List { "AgentId", "KnowledgeBaseId" } }, - { AWSServiceType.BedrockRuntimeService, new List { "ModelId" } }, + { AWSServiceType.DynamoDbService, ["TableName"] }, + { AWSServiceType.SQSService, ["QueueUrl"] }, + { AWSServiceType.BedrockAgentService, ["AgentId", "KnowledgeBaseId", "DataSourceId"] }, + { AWSServiceType.BedrockAgentRuntimeService, ["AgentId", "KnowledgeBaseId"] }, + { AWSServiceType.BedrockRuntimeService, ["ModelId"] }, }; internal static IReadOnlyDictionary> ServiceResponseParameterMap = new Dictionary>() { - { AWSServiceType.BedrockService, new List { "GuardrailId" } }, - { AWSServiceType.BedrockAgentService, new List { "AgentId", "DataSourceId" } }, + { AWSServiceType.BedrockService, ["GuardrailId"] }, + { AWSServiceType.BedrockAgentService, ["AgentId", "DataSourceId"] }, }; internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() @@ -34,8 +34,8 @@ internal class AWSServiceHelper }; // for Bedrock Agent operations, we map each supported operation to one resource: Agent, DataSource, or KnowledgeBase - internal static List BedrockAgentAgentOps = new List - { + internal static List BedrockAgentAgentOps = + [ "CreateAgentActionGroup", "CreateAgentAlias", "DeleteAgentActionGroup", @@ -53,11 +53,11 @@ internal class AWSServiceHelper "PrepareAgent", "UpdateAgentActionGroup", "UpdateAgentAlias", - "UpdateAgent", - }; + "UpdateAgent" + ]; - internal static List BedrockAgentKnowledgeBaseOps = new List - { + internal static List BedrockAgentKnowledgeBaseOps = + [ "AssociateAgentKnowledgeBase", "CreateDataSource", "DeleteKnowledgeBase", @@ -65,15 +65,15 @@ internal class AWSServiceHelper "GetAgentKnowledgeBase", "GetKnowledgeBase", "ListDataSources", - "UpdateAgentKnowledgeBase", - }; + "UpdateAgentKnowledgeBase" + ]; - internal static List BedrockAgentDataSourceOps = new List - { + internal static List BedrockAgentDataSourceOps = + [ "DeleteDataSource", "GetDataSource", - "UpdateDataSource", - }; + "UpdateDataSource" + ]; internal static IReadOnlyDictionary OperationNameToResourceMap() { @@ -102,8 +102,8 @@ internal static string GetAWSServiceName(IRequestContext requestContext) internal static string GetAWSOperationName(IRequestContext requestContext) { - string completeRequestName = requestContext.OriginalRequest.GetType().Name; - string suffix = "Request"; + var completeRequestName = requestContext.OriginalRequest.GetType().Name; + var suffix = "Request"; var operationName = Utils.RemoveSuffix(completeRequestName, suffix); return operationName; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 3ff390ef54..2a13fed2ba 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -34,10 +34,8 @@ public override void InvokeSync(IExecutionContext executionContext) public override async Task InvokeAsync(IExecutionContext executionContext) { - T? ret = null; - var activity = this.ProcessBeginRequest(executionContext); - ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); + var ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); ProcessEndRequest(activity, executionContext); @@ -57,7 +55,7 @@ private static void AddResponseSpecificInformation(Activity activity, IExecution if (AWSServiceHelper.ServiceResponseParameterMap.TryGetValue(service, out var parameters)) { - AmazonWebServiceResponse response = responseContext.Response; + var response = responseContext.Response; foreach (var parameter in parameters) { @@ -129,7 +127,7 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon if (AWSServiceHelper.ServiceRequestParameterMap.TryGetValue(service, out var parameters)) { - AmazonWebServiceRequest request = requestContext.OriginalRequest; + var request = requestContext.OriginalRequest; foreach (var parameter in parameters) { diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs index dbab867b3f..d8dc7febec 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSHistogram.cs @@ -10,8 +10,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSHistogram : Histogram where T : struct { - private static readonly ConcurrentDictionary> HistogramsDictionary - = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> HistogramsDictionary = new(); private readonly System.Diagnostics.Metrics.Histogram histogram; @@ -21,7 +20,7 @@ public AWSHistogram( string? units = null, string? description = null) { - if (HistogramsDictionary.TryGetValue(name, out System.Diagnostics.Metrics.Histogram? histogram)) + if (HistogramsDictionary.TryGetValue(name, out var histogram)) { this.histogram = histogram; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs index 240dc565f3..ee5dad188d 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMeterProvider.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSMeterProvider : MeterProvider { - private static readonly ConcurrentDictionary MetersDictionary = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary MetersDictionary = new(); public override Meter GetMeter(string scope, Attributes? attributes = null) { @@ -20,7 +20,7 @@ public override Meter GetMeter(string scope, Attributes? attributes = null) // update OpenTelemetry core component version(s) to `1.9.0` and allow passing tags to // the meter constructor. - if (MetersDictionary.TryGetValue(scope, out AWSMeter? meter)) + if (MetersDictionary.TryGetValue(scope, out var meter)) { return meter; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs index 7de5568996..aaab9e7b68 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSMonotonicCounter.cs @@ -10,8 +10,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSMonotonicCounter : MonotonicCounter where T : struct { - private static readonly ConcurrentDictionary> MonotonicCountersDictionary - = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> MonotonicCountersDictionary = new(); private readonly System.Diagnostics.Metrics.Counter monotonicCounter; @@ -21,7 +20,7 @@ public AWSMonotonicCounter( string? units = null, string? description = null) { - if (MonotonicCountersDictionary.TryGetValue(name, out System.Diagnostics.Metrics.Counter? monotonicCounter)) + if (MonotonicCountersDictionary.TryGetValue(name, out var monotonicCounter)) { this.monotonicCounter = monotonicCounter; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs index 2800ebacee..7757814b14 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Metrics/AWSUpDownCounter.cs @@ -10,8 +10,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Metrics; internal sealed class AWSUpDownCounter : UpDownCounter where T : struct { - private static readonly ConcurrentDictionary> UpDownCountersDictionary - = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> UpDownCountersDictionary = new(); private readonly System.Diagnostics.Metrics.UpDownCounter upDownCounter; @@ -21,7 +20,7 @@ public AWSUpDownCounter( string? units = null, string? description = null) { - if (UpDownCountersDictionary.TryGetValue(name, out System.Diagnostics.Metrics.UpDownCounter? upDownCounter)) + if (UpDownCountersDictionary.TryGetValue(name, out var upDownCounter)) { this.upDownCounter = upDownCounter; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs index b7988f4e20..eee5ecc7f8 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SnsRequestContextHelper.cs @@ -21,13 +21,13 @@ internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary< return; } - if (attributes.Keys.Any(k => originalRequest.MessageAttributes.ContainsKey(k))) + if (attributes.Keys.Any(originalRequest.MessageAttributes.ContainsKey)) { // If at least one attribute is already present in the request then we skip the injection. return; } - int attributesCount = originalRequest.MessageAttributes.Count; + var attributesCount = originalRequest.MessageAttributes.Count; if (attributes.Count + attributesCount > MaxMessageAttributes) { // TODO: add logging (event source). diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs index 06d873adfd..fdeb26ac64 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/SqsRequestContextHelper.cs @@ -21,13 +21,13 @@ internal static void AddAttributes(IRequestContext context, IReadOnlyDictionary< return; } - if (attributes.Keys.Any(k => originalRequest.MessageAttributes.ContainsKey(k))) + if (attributes.Keys.Any(originalRequest.MessageAttributes.ContainsKey)) { // If at least one attribute is already present in the request then we skip the injection. return; } - int attributesCount = originalRequest.MessageAttributes.Count; + var attributesCount = originalRequest.MessageAttributes.Count; if (attributes.Count + attributesCount > MaxMessageAttributes) { // TODO: add logging (event source). diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs index 98de524b14..4e1e494b35 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs @@ -85,6 +85,7 @@ private static ActivityStatusCode ConvertToActivityStatusCode(SpanStatus status) { SpanStatus.OK => ActivityStatusCode.Ok, SpanStatus.ERROR => ActivityStatusCode.Error, + SpanStatus.UNSET => ActivityStatusCode.Unset, _ => ActivityStatusCode.Unset, }; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs index ecf8418e6a..001b2915e5 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracer.cs @@ -29,7 +29,7 @@ public override TraceSpan CreateSpan( var tags = initialAttributes != null ? new ActivityTagsCollection(initialAttributes.AllAttributes) : null; var activityKind = ConvertToActivityKind(spanKind); - ActivityContext parentActivityContext = ConvertToActivityContext(parentContext); + var parentActivityContext = ConvertToActivityContext(parentContext); var activity = this.activitySource.StartActivity(name, activityKind, parentActivityContext, tags); return new AWSTraceSpan(activity); @@ -66,6 +66,7 @@ private static ActivityKind ConvertToActivityKind(SpanKind spanKind) SpanKind.SERVER => ActivityKind.Server, SpanKind.PRODUCER => ActivityKind.Producer, SpanKind.CONSUMER => ActivityKind.Consumer, + SpanKind.INTERNAL => ActivityKind.Internal, _ => ActivityKind.Internal, }; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs index 44fa4986f2..99817b4f97 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTracerProvider.cs @@ -9,11 +9,11 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; internal sealed class AWSTracerProvider : TracerProvider { - private static readonly ConcurrentDictionary TracersDictionary = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary TracersDictionary = new(); public override Tracer GetTracer(string scope) { - if (TracersDictionary.TryGetValue(scope, out AWSTracer? awsTracer)) + if (TracersDictionary.TryGetValue(scope, out var awsTracer)) { return awsTracer; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs index 1cb7fe979a..3919ea16bd 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Utils.cs @@ -9,7 +9,7 @@ internal class Utils { internal static object? GetTagValue(Activity activity, string tagName) { - foreach (KeyValuePair tag in activity.TagObjects) + foreach (var tag in activity.TagObjects) { if (tag.Key.Equals(tagName, StringComparison.Ordinal)) { @@ -22,17 +22,12 @@ internal class Utils internal static string RemoveSuffix(string originalString, string suffix) { - if (string.IsNullOrEmpty(originalString)) - { - return string.Empty; - } - - if (originalString.EndsWith(suffix, StringComparison.Ordinal)) - { - return originalString.Substring(0, originalString.Length - suffix.Length); - } - - return originalString; + return string.IsNullOrEmpty(originalString) + ? string.Empty + : originalString.EndsWith(suffix, StringComparison.Ordinal) + ? + originalString.Substring(0, originalString.Length - suffix.Length) + : originalString; } /// @@ -50,16 +45,8 @@ internal static string RemoveAmazonPrefixFromServiceName(string serviceName) private static string RemovePrefix(string originalString, string prefix) { - if (string.IsNullOrEmpty(originalString)) - { - return string.Empty; - } - - if (originalString.StartsWith(prefix, StringComparison.Ordinal)) - { - return originalString.Substring(prefix.Length); - } - - return originalString; + return string.IsNullOrEmpty(originalString) ? string.Empty : + originalString.StartsWith(prefix, StringComparison.Ordinal) ? originalString.Substring(prefix.Length) : + originalString; } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs index 38273c5331..958f3923c1 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaHttpUtils.cs @@ -20,11 +20,11 @@ internal static IEnumerable> GetHttpTags(TI { var tags = new List>(); - string? httpScheme = null; - string? httpTarget = null; - string? httpMethod = null; - string? hostName = null; - int? hostPort = null; + string? httpScheme; + string? httpTarget; + string? httpMethod; + string? hostName; + int? hostPort; switch (input) { @@ -81,6 +81,8 @@ internal static void SetHttpTagsFromResult(Activity? activity, object? result) case ApplicationLoadBalancerResponse albResponse: activity.SetTag(SemanticConventions.AttributeHttpStatusCode, albResponse.StatusCode); break; + default: + break; } } @@ -165,7 +167,7 @@ internal static (string? Host, int? Port) GetHostAndPort(string? httpScheme, str } #pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array - var hostAndPort = hostHeader.Split(new char[] { ':' }, 2); + var hostAndPort = hostHeader.Split([':'], 2); #pragma warning restore CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array if (hostAndPort.Length > 1) { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs index 5c0430ce05..56902fa909 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaUtils.cs @@ -26,12 +26,7 @@ internal static class AWSLambdaUtils private static readonly Func, string, IEnumerable> Getter = (headers, name) => { - if (headers.TryGetValue(name, out var value)) - { - return new[] { value }; - } - - return Array.Empty(); + return headers.TryGetValue(name, out var value) ? [value] : []; }; internal static ActivityContext GetXRayParentContext() @@ -77,6 +72,8 @@ internal static (ActivityContext ParentContext, IEnumerable? Links case SNSEvent.SNSRecord snsRecord: parentContext = AWSMessagingUtils.ExtractParentContext(snsRecord); break; + default: + break; } return (parentContext.ActivityContext, links); @@ -179,12 +176,7 @@ internal static IEnumerable> GetFunctionTags::function: var items = functionArn.Split(':'); - if (items.Length >= 5) - { - return items[4]; - } - - return null; + return items.Length >= 5 ? items[4] : null; } private static string GetFaasId(string functionArn) @@ -207,7 +199,7 @@ private static string GetFaasTrigger(TInput input) => IsHttpRequest(input) ? "http" : "other"; private static bool IsHttpRequest(TInput input) => - input is APIGatewayProxyRequest || input is APIGatewayHttpApiV2ProxyRequest || input is ApplicationLoadBalancerRequest; + input is APIGatewayProxyRequest or APIGatewayHttpApiV2ProxyRequest or ApplicationLoadBalancerRequest; private static ActivityContext ParseXRayTraceHeader(string rawHeader) { diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs index 47c571908e..50ea0bdeb1 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSMessagingUtils.cs @@ -58,7 +58,7 @@ internal static PropagationContext ExtractParentContext(SQSEvent.SQSMessage sqsM { // SQS subscribed to SNS topic with raw delivery disabled case, i.e. SNS record serialized into SQS body. // https://docs.aws.amazon.com/sns/latest/dg/sns-large-payload-raw-message-delivery.html - SNSEvent.SNSMessage? snsMessage = GetSnsMessage(sqsMessage); + var snsMessage = GetSnsMessage(sqsMessage); parentContext = ExtractParentContext(snsMessage); } @@ -89,33 +89,22 @@ internal static PropagationContext ExtractParentContext(SNSEvent.SNSMessage? mes private static IEnumerable? SqsMessageAttributeGetter(IDictionary attributes, string attributeName) { - if (!attributes.TryGetValue(attributeName, out var attribute)) - { - return null; - } - - return attribute?.StringValue != null ? - new[] { attribute.StringValue } : + return !attributes.TryGetValue(attributeName, out var attribute) ? null : + attribute?.StringValue != null ? new[] { attribute.StringValue } : attribute?.StringListValues; } private static IEnumerable? SnsMessageAttributeGetter(IDictionary attributes, string attributeName) { - if (!attributes.TryGetValue(attributeName, out var attribute)) - { - return null; - } - - switch (attribute?.Type) - { - case SnsAttributeTypeString when attribute.Value != null: - return new[] { attribute.Value }; - case SnsAttributeTypeStringArray when attribute.Value != null: - // Multiple values are stored as CSV (https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html). - return attribute.Value.Split(','); - default: - return null; - } + return !attributes.TryGetValue(attributeName, out var attribute) + ? null + : attribute?.Type switch + { + SnsAttributeTypeString when attribute.Value != null => [attribute.Value], + SnsAttributeTypeStringArray when attribute.Value != null => + attribute.Value.Split(','), // Multiple values are stored as CSV (https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html). + _ => null, + }; } private static SNSEvent.SNSMessage? GetSnsMessage(SQSEvent.SQSMessage sqsMessage) diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs index 7e465a4694..d49ac7601c 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/RequestContextHelperTests.cs @@ -37,7 +37,7 @@ public void AddAttributes_ParametersCollectionSizeReachesLimit_TraceDataNotInjec var context = new TestRequestContext(originalRequest, request); - var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType, context); + var addAttributes = TestsHelper.CreateAddAttributesAction(serviceType); addAttributes?.Invoke(context, AWSMessagingUtils.InjectIntoDictionary(CreatePropagationContext())); Assert.Equal(30, parameters.Count); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs index e695853e2f..519b677628 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Implementation/TestsHelper.cs @@ -16,9 +16,9 @@ internal static class TestsHelper /// Returns either or /// depending on . /// - /// This is meant to mimic thee logic in . + /// This is meant to mimic these logic in . /// - internal static Action>? CreateAddAttributesAction(string serviceType, IRequestContext context) + internal static Action>? CreateAddAttributesAction(string serviceType) { return serviceType switch { @@ -49,7 +49,7 @@ internal static AmazonWebServiceRequest CreateOriginalRequest(string serviceType throw new NotSupportedException($"Tests for service type {serviceType} not supported."); } - for (int i = 1; i <= attributesCount; i++) + for (var i = 1; i <= attributesCount; i++) { addAttribute(i); } @@ -59,15 +59,14 @@ internal static AmazonWebServiceRequest CreateOriginalRequest(string serviceType internal static void AddAttribute(this AmazonWebServiceRequest serviceRequest, string name, string value) { - var sendRequest = serviceRequest as SQS::SendMessageRequest; var publishRequest = serviceRequest as SNS::PublishRequest; - if (sendRequest != null) + if (serviceRequest is SQS::SendMessageRequest sendRequest) { sendRequest.MessageAttributes.Add(name, new SQS::MessageAttributeValue { DataType = "String", StringValue = value }); } - else if (publishRequest != null) + else { - publishRequest.MessageAttributes.Add(name, new SNS::MessageAttributeValue { DataType = "String", StringValue = value }); + publishRequest?.MessageAttributes.Add(name, new SNS::MessageAttributeValue { DataType = "String", StringValue = value }); } } @@ -81,17 +80,15 @@ internal static void AddStringParameter(this ParameterCollection parameters, str internal static void AddStringParameters(this ParameterCollection parameters, string serviceType, AmazonWebServiceRequest serviceRequest) { - var sendRequest = serviceRequest as SQS::SendMessageRequest; - var publishRequest = serviceRequest as SNS::PublishRequest; - int index = 1; - if (sendRequest != null) + var index = 1; + if (serviceRequest is SQS::SendMessageRequest sendRequest) { foreach (var a in sendRequest.MessageAttributes) { AddStringParameter(parameters, serviceType, a.Key, a.Value.StringValue, index++); } } - else if (publishRequest != null) + else if (serviceRequest is SNS::PublishRequest publishRequest) { foreach (var a in publishRequest.MessageAttributes) { diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 558da3791e..7d466c0cf4 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -34,7 +34,7 @@ public async Task TestDDBScanSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -48,7 +48,7 @@ public async Task TestDDBScanSuccessful() var scan_request = new ScanRequest { TableName = "SampleProduct", - AttributesToGet = new List { "Id", "Name" }, + AttributesToGet = ["Id", "Name"], }; #if NETFRAMEWORK ddb.Scan(scan_request); @@ -59,7 +59,7 @@ public async Task TestDDBScanSuccessful() Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -79,7 +79,7 @@ public async Task TestDDBSubtypeScanSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -93,7 +93,7 @@ public async Task TestDDBSubtypeScanSuccessful() var scan_request = new ScanRequest { TableName = "SampleProduct", - AttributesToGet = new List() { "Id", "Name" }, + AttributesToGet = ["Id", "Name"], }; #if NETFRAMEWORK ddb.Scan(scan_request); @@ -104,7 +104,7 @@ public async Task TestDDBSubtypeScanSuccessful() Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -124,7 +124,7 @@ public async Task TestDDBScanUnsuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .SetSampler(new AlwaysOnSampler()) @@ -134,14 +134,16 @@ public async Task TestDDBScanUnsuccessful() .Build()) { var ddb = new AmazonDynamoDBClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - AmazonServiceException amazonServiceException = new AmazonServiceException(); - amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; - amazonServiceException.RequestId = requestId; + var amazonServiceException = new AmazonServiceException + { + StatusCode = System.Net.HttpStatusCode.NotFound, + RequestId = requestId, + }; CustomResponses.SetResponse(ddb, (request) => { throw amazonServiceException; }); var scan_request = new ScanRequest { TableName = "SampleProduct", - AttributesToGet = new List() { "Id", "Name" }, + AttributesToGet = ["Id", "Name"], }; try @@ -160,7 +162,7 @@ public async Task TestDDBScanUnsuccessful() Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "DynamoDB.Scan"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -181,7 +183,7 @@ public async Task TestSQSSendMessageSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -191,11 +193,13 @@ public async Task TestSQSSendMessageSuccessful() .Build()) { var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(sqs, dummyResponse, requestId, true); - var send_msg_req = new SendMessageRequest(); - send_msg_req.QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue"; - send_msg_req.MessageBody = "Hello from OT"; + var send_msg_req = new SendMessageRequest + { + QueueUrl = "https://sqs.us-east-1.amazonaws.com/123456789/MyTestQueue", + MessageBody = "Hello from OT", + }; send_msg_req.MessageAttributes.Add("Custom", new MessageAttributeValue { StringValue = "Value", DataType = "String" }); #if NETFRAMEWORK sqs.SendMessage(send_msg_req); @@ -205,7 +209,7 @@ public async Task TestSQSSendMessageSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "SQS.SendMessage"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "SQS.SendMessage"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -225,7 +229,7 @@ public async Task TestBedrockGetGuardrailSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -235,10 +239,9 @@ public async Task TestBedrockGetGuardrailSuccessful() .Build()) { var bedrock = new AmazonBedrockClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{\"GuardrailId\":\"123456789\"}"; + var dummyResponse = "{\"GuardrailId\":\"123456789\"}"; CustomResponses.SetResponse(bedrock, dummyResponse, requestId, true); - var getGuardrailRequest = new GetGuardrailRequest(); - getGuardrailRequest.GuardrailIdentifier = "123456789"; + var getGuardrailRequest = new GetGuardrailRequest { GuardrailIdentifier = "123456789" }; #if NETFRAMEWORK bedrock.GetGuardrail(getGuardrailRequest); #else @@ -247,7 +250,7 @@ public async Task TestBedrockGetGuardrailSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock.GetGuardrail"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock.GetGuardrail"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -267,7 +270,7 @@ public async Task TestBedrockRuntimeInvokeModelSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -277,10 +280,9 @@ public async Task TestBedrockRuntimeInvokeModelSuccessful() .Build()) { var bedrockruntime = new AmazonBedrockRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(bedrockruntime, dummyResponse, requestId, true); - var invokeModelRequest = new InvokeModelRequest(); - invokeModelRequest.ModelId = "amazon.titan-text-express-v1"; + var invokeModelRequest = new InvokeModelRequest { ModelId = "amazon.titan-text-express-v1" }; #if NETFRAMEWORK var response = bedrockruntime.InvokeModel(invokeModelRequest); #else @@ -289,7 +291,7 @@ public async Task TestBedrockRuntimeInvokeModelSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Runtime.InvokeModel"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Runtime.InvokeModel"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -309,7 +311,7 @@ public async Task TestBedrockAgentGetAgentSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -319,10 +321,9 @@ public async Task TestBedrockAgentGetAgentSuccessful() .Build()) { var bedrockagent = new AmazonBedrockAgentClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(bedrockagent, dummyResponse, requestId, true); - var getAgentRequest = new GetAgentRequest(); - getAgentRequest.AgentId = "1234567890"; + var getAgentRequest = new GetAgentRequest { AgentId = "1234567890" }; #if NETFRAMEWORK var response = bedrockagent.GetAgent(getAgentRequest); #else @@ -331,7 +332,7 @@ public async Task TestBedrockAgentGetAgentSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetAgent"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetAgent"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -351,7 +352,7 @@ public async Task TestBedrockAgentGetKnowledgeBaseSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -361,10 +362,9 @@ public async Task TestBedrockAgentGetKnowledgeBaseSuccessful() .Build()) { var bedrockagent = new AmazonBedrockAgentClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(bedrockagent, dummyResponse, requestId, true); - var getKnowledgeBaseRequest = new GetKnowledgeBaseRequest(); - getKnowledgeBaseRequest.KnowledgeBaseId = "1234567890"; + var getKnowledgeBaseRequest = new GetKnowledgeBaseRequest { KnowledgeBaseId = "1234567890" }; #if NETFRAMEWORK var response = bedrockagent.GetKnowledgeBase(getKnowledgeBaseRequest); #else @@ -373,7 +373,7 @@ public async Task TestBedrockAgentGetKnowledgeBaseSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetKnowledgeBase"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetKnowledgeBase"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -393,7 +393,7 @@ public async Task TestBedrockAgentGetDataSourceSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -403,11 +403,9 @@ public async Task TestBedrockAgentGetDataSourceSuccessful() .Build()) { var bedrockagent = new AmazonBedrockAgentClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(bedrockagent, dummyResponse, requestId, true); - var getDataSourceRequest = new GetDataSourceRequest(); - getDataSourceRequest.DataSourceId = "1234567890"; - getDataSourceRequest.KnowledgeBaseId = "1234567890"; + var getDataSourceRequest = new GetDataSourceRequest { DataSourceId = "1234567890", KnowledgeBaseId = "1234567890", }; #if NETFRAMEWORK var response = bedrockagent.GetDataSource(getDataSourceRequest); #else @@ -416,7 +414,7 @@ public async Task TestBedrockAgentGetDataSourceSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetDataSource"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent.GetDataSource"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -436,7 +434,7 @@ public async Task TestBedrockAgentRuntimeInvokeAgentSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -445,23 +443,25 @@ public async Task TestBedrockAgentRuntimeInvokeAgentSuccessful() .AddInMemoryExporter(exportedItems) .Build()) { - var bedrockagentruntime = new AmazonBedrockAgentRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; - CustomResponses.SetResponse(bedrockagentruntime, dummyResponse, requestId, true); - var invokeAgentRequest = new InvokeAgentRequest(); - invokeAgentRequest.AgentId = "123456789"; - invokeAgentRequest.AgentAliasId = "testalias"; - invokeAgentRequest.SessionId = "test-session-id"; - invokeAgentRequest.InputText = "sample input text"; + var bedrockAgentRuntimeClient = new AmazonBedrockAgentRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); + var dummyResponse = "{}"; + CustomResponses.SetResponse(bedrockAgentRuntimeClient, dummyResponse, requestId, true); + var invokeAgentRequest = new InvokeAgentRequest + { + AgentId = "123456789", + AgentAliasId = "testalias", + SessionId = "test-session-id", + InputText = "sample input text", + }; #if NETFRAMEWORK - var response = bedrockagentruntime.InvokeAgent(invokeAgentRequest); + var response = bedrockAgentRuntimeClient.InvokeAgent(invokeAgentRequest); #else - var response = await bedrockagentruntime.InvokeAgentAsync(invokeAgentRequest); + var response = await bedrockAgentRuntimeClient.InvokeAgentAsync(invokeAgentRequest); #endif } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent Runtime.InvokeAgent"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent Runtime.InvokeAgent"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); @@ -481,7 +481,7 @@ public async Task TestBedrockAgentRuntimeRetrieveSuccessful() var exportedItems = new List(); var parent = new Activity("parent").Start(); - string requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; + var requestId = @"fakerequ-esti-dfak-ereq-uestidfakere"; using (Sdk.CreateTracerProviderBuilder() .AddXRayTraceId() @@ -491,10 +491,9 @@ public async Task TestBedrockAgentRuntimeRetrieveSuccessful() .Build()) { var bedrockagentruntime = new AmazonBedrockAgentRuntimeClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(bedrockagentruntime, dummyResponse, requestId, true); - var retrieveRequest = new RetrieveRequest(); - retrieveRequest.KnowledgeBaseId = "123456789"; + var retrieveRequest = new RetrieveRequest { KnowledgeBaseId = "123456789" }; #if NETFRAMEWORK var response = bedrockagentruntime.Retrieve(retrieveRequest); #else @@ -503,7 +502,7 @@ public async Task TestBedrockAgentRuntimeRetrieveSuccessful() } Assert.NotEmpty(exportedItems); - Activity? awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent Runtime.Retrieve"); + var awssdk_activity = exportedItems.FirstOrDefault(e => e.DisplayName == "Bedrock Agent Runtime.Retrieve"); Assert.NotNull(awssdk_activity); this.ValidateAWSActivity(awssdk_activity, parent); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs index 5f2f8b922c..46718423e1 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientMetricsInstrumentation.cs @@ -65,9 +65,11 @@ public async Task TestSNSCreateTopicUnsuccessful() .Build(); var sns = new AmazonSimpleNotificationServiceClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - AmazonServiceException amazonServiceException = new AmazonServiceException(); - amazonServiceException.StatusCode = System.Net.HttpStatusCode.NotFound; - amazonServiceException.RequestId = "requestId"; + var amazonServiceException = new AmazonServiceException + { + StatusCode = System.Net.HttpStatusCode.NotFound, + RequestId = "requestId", + }; CustomResponses.SetResponse(sns, (request) => { throw amazonServiceException; }); var createTopicRequest = new CreateTopicRequest { @@ -120,7 +122,7 @@ public async Task TestSQSCreateQueueSuccessful() .Build(); var sqs = new AmazonSQSClient(new AnonymousAWSCredentials(), RegionEndpoint.USEast1); - string dummyResponse = "{}"; + var dummyResponse = "{}"; CustomResponses.SetResponse(sqs, dummyResponse, "requestId", true); var send_msg_req = new CreateQueueRequest() { diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs index 8a83185af2..cb5d05ce85 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestRequest.cs @@ -12,11 +12,9 @@ namespace OpenTelemetry.Instrumentation.AWS.Tests; internal class TestRequest : IRequest { - private readonly ParameterCollection parameters; - public TestRequest(ParameterCollection? parameters = null) { - this.parameters = parameters ?? new ParameterCollection(); + this.ParameterCollection = parameters ?? []; } public string RequestName => throw new NotImplementedException(); @@ -27,7 +25,7 @@ public TestRequest(ParameterCollection? parameters = null) public IDictionary Parameters => throw new NotImplementedException(); - public ParameterCollection ParameterCollection => this.parameters; + public ParameterCollection ParameterCollection { get; } public IDictionary SubResources => throw new NotImplementedException(); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs index 2fbdec7d8d..04dbc175f2 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomResponses.cs @@ -31,8 +31,7 @@ public static void SetResponse( .GetValue(client, null) as RuntimePipeline; - var requestFactory = new MockHttpRequestFactory(); - requestFactory.ResponseCreator = responseCreator; + var requestFactory = new MockHttpRequestFactory { ResponseCreator = responseCreator }; var httpHandler = new HttpHandler(requestFactory, client); pipeline?.ReplaceHandler>(httpHandler); } @@ -44,7 +43,7 @@ public static void SetResponse( return (request) => { - Dictionary headers = new Dictionary(StringComparer.Ordinal); + var headers = new Dictionary(StringComparer.Ordinal); if (!string.IsNullOrEmpty(requestId)) { headers.Add(HeaderKeys.RequestIdHeader, requestId); @@ -52,12 +51,7 @@ public static void SetResponse( var response = MockWebResponse.Create(status, headers, content); - if (isOK) - { - return response; - } - - throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); + return isOK ? response : throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); }; } #else @@ -75,8 +69,7 @@ public static void SetResponse(AmazonServiceClient client, Func(requestFactory, client); pipeline?.ReplaceHandler>(httpHandler); } @@ -88,7 +81,7 @@ private static Func Create( return (request) => { - Dictionary headers = new Dictionary(StringComparer.Ordinal); + var headers = new Dictionary(StringComparer.Ordinal); if (!string.IsNullOrEmpty(requestId)) { headers.Add(HeaderKeys.RequestIdHeader, requestId); @@ -96,12 +89,9 @@ private static Func Create( var response = MockWebResponse.Create(status, headers, content); - if (isOK) - { - return response; - } - - throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); + return isOK + ? response + : throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); }; } #endif diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs index 8c90c6c10c..ae7d4443c0 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/CustomWebResponse.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal class CustomWebResponse : IWebResponseData { - private HttpResponseMessageBody response; + private readonly HttpResponseMessageBody response; private string[]? headerNames; private Dictionary? headers; private HashSet? headerNamesSet; @@ -37,10 +37,7 @@ public CustomWebResponse(HttpResponseMessage responseMsg, HttpClient? httpClient public long ContentLength { get; private set; } - public IHttpResponseBody ResponseBody - { - get { return this.response; } - } + public IHttpResponseBody ResponseBody => this.response; public static IWebResponseData GenerateWebResponse(HttpResponseMessage response) { @@ -49,12 +46,9 @@ public static IWebResponseData GenerateWebResponse(HttpResponseMessage response) public string? GetHeaderValue(string headerName) { - if (this.headers != null && this.headers.TryGetValue(headerName, out var headerValue)) - { - return headerValue; - } - - return string.Empty; + return this.headers != null && this.headers.TryGetValue(headerName, out var headerValue) + ? headerValue + : string.Empty; } public bool IsHeaderPresent(string headerName) @@ -69,10 +63,10 @@ public bool IsHeaderPresent(string headerName) private void CopyHeaderValues(HttpResponseMessage response) { - List headerNames = new List(); + List headerNames = []; this.headers = new Dictionary(10, StringComparer.OrdinalIgnoreCase); - foreach (KeyValuePair> kvp in response.Headers) + foreach (var kvp in response.Headers) { headerNames.Add(kvp.Key); var headerValue = this.GetFirstHeaderValue(response.Headers, kvp.Key); @@ -92,17 +86,12 @@ private void CopyHeaderValues(HttpResponseMessage response) } } - this.headerNames = headerNames.ToArray(); + this.headerNames = [.. headerNames]; this.headerNamesSet = new HashSet(this.headerNames, StringComparer.OrdinalIgnoreCase); } private string? GetFirstHeaderValue(HttpHeaders headers, string key) { - if (headers.TryGetValues(key, out var headerValues)) - { - return headerValues.FirstOrDefault(); - } - - return string.Empty; + return headers.TryGetValues(key, out var headerValues) ? headerValues.FirstOrDefault() : string.Empty; } } diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs index 28cb4d3b05..a7fbd08adb 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockHttpRequest.cs @@ -57,10 +57,7 @@ public Stream GetRequestContent() public IWebResponseData GetResponse() { - if (this.GetResponseAction != null) - { - this.GetResponseAction(); - } + this.GetResponseAction?.Invoke(); var response = this.ResponseCreator(this); return new HttpWebRequestResponseData(response); @@ -123,14 +120,9 @@ private HttpWebResponse CreateResponse(MockHttpRequest request) var resourceName = request.RequestUri.Host.Split('.').Last(); var response = MockWebResponse.CreateFromResource(resourceName); - if (response?.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) - { - return response; - } - else - { - throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); - } + return response?.StatusCode is >= HttpStatusCode.OK and <= (HttpStatusCode)299 + ? response + : throw new HttpErrorResponseException(new HttpWebRequestResponseData(response)); } } #else @@ -234,14 +226,9 @@ private HttpResponseMessage CreateResponse(MockHttpRequest request) var resourceName = request.RequestUri.Host.Split('.').Last(); var response = MockWebResponse.CreateFromResource(resourceName); - if (response.StatusCode >= HttpStatusCode.OK && response.StatusCode <= (HttpStatusCode)299) - { - return response; - } - else - { - throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); - } + return response.StatusCode is >= HttpStatusCode.OK and <= (HttpStatusCode)299 + ? response + : throw new HttpErrorResponseException(CustomWebResponse.GenerateWebResponse(response)); } } #endif diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs index a6fccca9ab..2baf2c4473 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/MockWebResponse.cs @@ -21,9 +21,8 @@ internal class MockWebResponse { var type = typeof(HttpWebResponse); var assembly = Assembly.GetAssembly(type); - var obj = assembly?.CreateInstance("System.Net.HttpWebResponse") as HttpWebResponse; - if (obj == null) + if (assembly?.CreateInstance("System.Net.HttpWebResponse") is not HttpWebResponse obj) { return null; } @@ -38,7 +37,7 @@ internal class MockWebResponse } body ??= string.Empty; - Stream responseBodyStream = Utils.CreateStreamFromString(body); + var responseBodyStream = Utils.CreateStreamFromString(body); var statusFieldInfo = type.GetField( "m_StatusCode", @@ -58,7 +57,7 @@ internal class MockWebResponse streamFieldInfo?.SetValue(obj, responseBodyStream); contentLengthFieldInfo?.SetValue(obj, responseBodyStream.Length); - return obj as HttpWebResponse; + return obj; } #else @@ -66,7 +65,7 @@ public static HttpResponseMessage CreateFromResource(string resourceName) { var rawResponse = Utils.GetResourceText(resourceName); - HttpResponse response = ParseRawReponse(rawResponse); + var response = ParseRawReponse(rawResponse); var statusCode = ParseStatusCode(response.StatusLine); return Create(statusCode, response.Headers, response.Body); @@ -95,7 +94,7 @@ public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary< } httpResponseMessage!.StatusCode = statusCode; - string dummyJson = "{\"key1\":\"value1\"}"; + var dummyJson = "{\"key1\":\"value1\"}"; httpResponseMessage.Content = new StringContent(body ?? dummyJson); // Content should be in Json format else we get exception from downstream unmarshalling return httpResponseMessage; } @@ -103,8 +102,7 @@ public static HttpResponseMessage Create(HttpStatusCode statusCode, IDictionary< #endif public static HttpResponse ParseRawReponse(string rawResponse) { - HttpResponse response = new HttpResponse(); - response.StatusLine = rawResponse; + var response = new HttpResponse { StatusLine = rawResponse }; var responseLines = rawResponse.Split('\n'); @@ -152,8 +150,12 @@ private static HttpStatusCode ParseStatusCode(string? statusLine) { try { - string statusCode = statusLine?.Split(' ')[1] ?? string.Empty; + var statusCode = statusLine?.Split(' ')[1] ?? string.Empty; +#if NET + return Enum.Parse(statusCode); +#else return (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), statusCode); +#endif } catch (Exception exception) { @@ -161,7 +163,7 @@ private static HttpStatusCode ParseStatusCode(string? statusLine) } } - public class HttpResponse + internal class HttpResponse { public HttpResponse() { diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs index 8c9630e4bc..87ec0182ef 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/Utils.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using System.Reflection; namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; @@ -10,8 +9,8 @@ internal static class Utils { public static Stream CreateStreamFromString(string s) { - MemoryStream stream = new MemoryStream(); - StreamWriter writer = new StreamWriter(stream); + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); writer.Write(s); writer.Flush(); stream.Position = 0; @@ -20,9 +19,9 @@ public static Stream CreateStreamFromString(string s) public static Stream? GetResourceStream(string resourceName) { - Assembly assembly = typeof(Utils).Assembly; + var assembly = typeof(Utils).Assembly; var resource = FindResourceName(resourceName); - Stream? stream = assembly.GetManifestResourceStream(resource); + var stream = assembly.GetManifestResourceStream(resource); return stream; } @@ -34,10 +33,8 @@ public static string GetResourceText(string resourceName) return string.Empty; } - using (StreamReader reader = new StreamReader(stream)) - { - return reader.ReadToEnd(); - } + using var reader = new StreamReader(stream); + return reader.ReadToEnd(); } public static string FindResourceName(string partialName) @@ -49,7 +46,7 @@ public static string FindResourceName(string partialName) public static IEnumerable FindResourceName(Predicate match) { - Assembly assembly = typeof(Utils).Assembly; + var assembly = typeof(Utils).Assembly; var allResources = assembly.GetManifestResourceNames(); foreach (var resource in allResources) { diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index a7d617bc70..d36277b099 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -225,7 +225,7 @@ public void OnFunctionStart_ColdStart_ColdStartTagHasCorrectValue(int invocation .AddAWSLambdaConfigurations(c => c.DisableAwsXRayContextExtraction = true) .Build()) { - for (int i = 1; i <= invocationsCount; i++) + for (var i = 1; i <= invocationsCount; i++) { activity = AWSLambdaWrapper.OnFunctionStart("test-input", new SampleLambdaContext()); } @@ -233,7 +233,7 @@ public void OnFunctionStart_ColdStart_ColdStartTagHasCorrectValue(int invocation Assert.NotNull(activity); Assert.NotNull(activity.TagObjects); - var expectedColdStartValue = invocationsCount == 1 ? true : false; + var expectedColdStartValue = invocationsCount == 1; Assert.Contains(activity.TagObjects, x => x.Key == AWSLambdaSemanticConventions.AttributeFaasColdStart && expectedColdStartValue.Equals(x.Value)); } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs index c44df16f1e..06a0e1dbbe 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSLambdaHttpUtilsTests.cs @@ -26,7 +26,7 @@ public void GetHttpTags_APIGatewayProxyRequest_ReturnsCorrectTags() MultiValueQueryStringParameters = new Dictionary> { #pragma warning disable CA1861 // Avoid constant arrays as arguments - { "q1", new[] { "value1" } }, + { "q1", ["value1"] }, #pragma warning restore CA1861 // Avoid constant arrays as arguments }, RequestContext = new APIGatewayProxyRequest.ProxyRequestContext @@ -95,7 +95,7 @@ public void GetHttpTags_ApplicationLoadBalancerRequestWithMultiValue_ReturnsCorr MultiValueQueryStringParameters = new Dictionary> { #pragma warning disable CA1861 // Avoid constant arrays as arguments - { "q1", new[] { "value1" } }, + { "q1", ["value1"] }, #pragma warning restore CA1861 // Avoid constant arrays as arguments }, HttpMethod = "GET", @@ -226,7 +226,7 @@ public void GetHttpTags_APIGatewayProxyRequestWithEmptyContext_ReturnsTagsFromRe MultiValueQueryStringParameters = new Dictionary> { #pragma warning disable CA1861 // Avoid constant arrays as arguments - { "q1", new[] { "value1" } }, + { "q1", ["value1"] }, #pragma warning restore CA1861 // Avoid constant arrays as arguments }, HttpMethod = "POST", @@ -444,7 +444,7 @@ public void GetQueryString_APIGatewayHttpApiV2ProxyRequest_CorrectQueryString(st Assert.Equal(expectedQueryString, queryString); } - private static void AssertTags(IReadOnlyDictionary expectedTags, IEnumerable>? actualTags) + private static void AssertTags(Dictionary expectedTags, IEnumerable>? actualTags) where TActualValue : class { Assert.NotNull(actualTags); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs index ba2aa4ed49..967bc3fe77 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/AWSMessagingUtilsTests.cs @@ -1,9 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Diagnostics; using Amazon.Lambda.SQSEvents; -using OpenTelemetry.Context.Propagation; using OpenTelemetry.Instrumentation.AWSLambda.Implementation; using OpenTelemetry.Trace; using Xunit; @@ -35,9 +33,9 @@ public void Dispose() public void ExtractParentContext_SetParentFromMessageBatchIsDisabled_ParentIsNotSet() { AWSMessagingUtils.SetParentFromMessageBatch = false; - var sqsEvent = CreateSqsEventWithMessages(new[] { SpanId1, SpanId2 }); + var sqsEvent = CreateSqsEventWithMessages([SpanId1, SpanId2]); - (PropagationContext parentContext, IEnumerable? links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + (var parentContext, var links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); Assert.Equal(default, parentContext); Assert.Equal(2, links!.Count()); @@ -47,9 +45,9 @@ public void ExtractParentContext_SetParentFromMessageBatchIsDisabled_ParentIsNot public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetFromLastMessage() { AWSMessagingUtils.SetParentFromMessageBatch = true; - var sqsEvent = CreateSqsEventWithMessages(new[] { SpanId1, SpanId2 }); + var sqsEvent = CreateSqsEventWithMessages([SpanId1, SpanId2]); - (PropagationContext parentContext, IEnumerable? links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + (var parentContext, var links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); Assert.NotEqual(default, parentContext); Assert.Equal(SpanId2, parentContext.ActivityContext.SpanId.ToHexString()); @@ -62,11 +60,11 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF AWSMessagingUtils.SetParentFromMessageBatch = true; var sqsEvent = new SQSEvent { - Records = new List - { + Records = + [ new SQSMessage { - MessageAttributes = new(), + MessageAttributes = [], #pragma warning disable format // dotnet-format butchers the raw string & all following code (use dotnet format instead?) Body = /*lang=json,strict*/ """ @@ -87,10 +85,10 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF } """, }, - }, + ], }; - (PropagationContext parentContext, IEnumerable? links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); + (var parentContext, var links) = AWSMessagingUtils.ExtractParentContext(sqsEvent); Assert.NotEqual(default, parentContext); Assert.Equal(SpanId1, parentContext.ActivityContext.SpanId.ToHexString()); @@ -99,10 +97,10 @@ public void ExtractParentContext_SetParentFromMessageBatchIsEnabled_ParentIsSetF private static SQSEvent CreateSqsEventWithMessages(string[] spans) { - var @event = new SQSEvent { Records = new List() }; + var @event = new SQSEvent { Records = [] }; for (var i = 0; i < spans.Length; i++) { - var message = new SQSMessage { MessageAttributes = new Dictionary() }; + var message = new SQSMessage { MessageAttributes = [] }; message.MessageAttributes.Add("traceparent", new MessageAttribute { StringValue = $"00-{TraceId}-{spans[i]}-01" }); message.MessageAttributes.Add("tracestate", new MessageAttribute { StringValue = $"k1=v1,k2=v2" }); @event.Records.Add(message); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs index 41843b6084..94bf75053b 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleHandlers.cs @@ -8,30 +8,33 @@ namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; internal class SampleHandlers { // Action - public void SampleHandlerSyncInputAndNoReturn(string str, ILambdaContext context) +#pragma warning disable SA1313 + public void SampleHandlerSyncInputAndNoReturn(string _1, ILambdaContext _2) { } // Func - public string SampleHandlerSyncInputAndReturn(string str, ILambdaContext context) + public string SampleHandlerSyncInputAndReturn(string str, ILambdaContext _2) { return str; } // Func - public async Task SampleHandlerAsyncInputAndNoReturn(string str, ILambdaContext context) + public async Task SampleHandlerAsyncInputAndNoReturn(string _1, ILambdaContext _2) { await Task.Delay(10); } // Func> - public async Task SampleHandlerAsyncInputAndReturn(string str, ILambdaContext context) + public async Task SampleHandlerAsyncInputAndReturn(string str, ILambdaContext _2) { await Task.Delay(10); return str; } - public void SampleHandlerSyncNoReturnException(string str, ILambdaContext context) + // Action + public void SampleHandlerSyncNoReturnException(string str, ILambdaContext _2) +#pragma warning restore SA1313 { throw new Exception(str); } diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs index cf608da60d..792ba8d606 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/SampleLambdaContext.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Instrumentation.AWSLambda.Tests; -public class SampleLambdaContext : ILambdaContext +internal class SampleLambdaContext : ILambdaContext { public string AwsRequestId { get; } = "testrequestid"; From 1c1f8d214153c130cb1ca93790014781acea049d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 31 Oct 2024 20:19:05 +0100 Subject: [PATCH 1391/1499] [repo/AspNetCore] Prepare to .NET9 (#2283) --- .../AspNetCoreInstrumentation.cs | 8 +-- .../AspNetCoreMetrics.cs | 8 +-- .../Implementation/HttpInListener.cs | 15 +++-- .../Implementation/HttpInMetricsListener.cs | 15 +++-- .../Implementation/TelemetryHelper.cs | 7 +- src/Shared/DiagnosticSourceSubscriber.cs | 7 +- src/Shared/RedactionHelper.cs | 4 +- .../AspNetCoreInstrumentationBenchmarks.cs | 4 ++ .../AspNetCoreInstrumentationNewBenchmarks.cs | 6 +- .../BasicTests.cs | 66 ++++++++----------- .../DependencyInjectionConfigTests.cs | 2 +- .../MetricTests.cs | 15 +++-- .../RouteTests/RoutingTestCases.cs | 4 +- .../RouteTests/RoutingTestFixture.cs | 4 +- .../RouteTests/RoutingTests.cs | 12 ++-- .../TestApplication/ActionDescriptorInfo.cs | 2 +- .../Controllers/AttributeRouteController.cs | 2 + .../ConventionalRouteController.cs | 2 + .../RouteTests/TestApplication/RouteInfo.cs | 5 +- .../RouteInfoDiagnosticObserver.cs | 2 +- .../TestApplication/TestApplicationFactory.cs | 22 +++---- test/TestApp.AspNetCore/CallbackMiddleware.cs | 2 +- .../Controllers/ChildActivityController.cs | 2 + .../Controllers/ErrorController.cs | 2 + .../Controllers/ValuesController.cs | 6 +- .../Filters/ExceptionFilter1.cs | 2 + .../Filters/ExceptionFilter2.cs | 2 + test/TestApp.AspNetCore/Program.cs | 2 + .../TestActivityMiddleware.cs | 2 + .../TestCallbackMiddleware.cs | 2 + test/TestApp.AspNetCore/TestMiddleware.cs | 2 + 31 files changed, 125 insertions(+), 111 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs index 7043817037..d7d02ecdc3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentation.cs @@ -10,14 +10,14 @@ namespace OpenTelemetry.Instrumentation.AspNetCore; /// internal sealed class AspNetCoreInstrumentation : IDisposable { - private static readonly HashSet DiagnosticSourceEvents = new() - { + private static readonly HashSet DiagnosticSourceEvents = + [ "Microsoft.AspNetCore.Hosting.HttpRequestIn", "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", "Microsoft.AspNetCore.Diagnostics.UnhandledException", - "Microsoft.AspNetCore.Hosting.UnhandledException", - }; + "Microsoft.AspNetCore.Hosting.UnhandledException" + ]; private readonly Func isEnabled = (eventName, _, _) => DiagnosticSourceEvents.Contains(eventName); diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs index 75676510f4..877f5ece38 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs @@ -11,14 +11,14 @@ namespace OpenTelemetry.Instrumentation.AspNetCore; /// internal sealed class AspNetCoreMetrics : IDisposable { - private static readonly HashSet DiagnosticSourceEvents = new() - { + private static readonly HashSet DiagnosticSourceEvents = + [ "Microsoft.AspNetCore.Hosting.HttpRequestIn", "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", "Microsoft.AspNetCore.Diagnostics.UnhandledException", - "Microsoft.AspNetCore.Hosting.UnhandledException", - }; + "Microsoft.AspNetCore.Hosting.UnhandledException" + ]; private readonly Func isEnabled = (eventName, _, _) => DiagnosticSourceEvents.Contains(eventName); diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 7f0aa51634..26eafb164d 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -43,7 +43,7 @@ internal class HttpInListener : ListenerHandler return value; } - return Enumerable.Empty(); + return []; }; private static readonly PropertyFetcher ExceptionPropertyFetcher = new("Exception"); @@ -82,6 +82,8 @@ public override void OnEventWritten(string name, object? payload) this.OnException(activity, payload); } + break; + default: break; } } @@ -98,8 +100,7 @@ public void OnStartActivity(Activity activity, object? payload) // By this time, samplers have already run and // activity.IsAllDataRequested populated accordingly. - var context = payload as HttpContext; - if (context == null) + if (payload is not HttpContext context) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnStartActivity), activity.OperationName); return; @@ -309,7 +310,7 @@ public void OnException(Activity activity, object? payload) if (activity.IsAllDataRequested) { // We need to use reflection here as the payload type is not a defined public type. - if (!TryFetchException(payload, out Exception? exc)) + if (!TryFetchException(payload, out var exc)) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInListener), nameof(this.OnException), activity.OperationName); return; @@ -341,7 +342,9 @@ public void OnException(Activity activity, object? payload) [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) - => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; + { + return ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -370,7 +373,7 @@ private static void AddGrpcAttributes(Activity activity, string grpcMethod, Http activity.SetTag(SemanticConventions.AttributeClientPort, context.Connection.RemotePort); - bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + var validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out var status); if (validConversion) { activity.SetStatus(GrpcTagHelper.ResolveSpanStatusForGrpcStatusCode(status)); diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index 08ab129cab..c9040d0248 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -43,7 +43,7 @@ internal HttpInMetricsListener(string name) public static void OnExceptionEventWritten(string name, object? payload) { // We need to use reflection here as the payload type is not a defined public type. - if (!TryFetchException(payload, out Exception? exc) || !TryFetchHttpContext(payload, out HttpContext? ctx)) + if (!TryFetchException(payload, out var exc) || !TryFetchHttpContext(payload, out var ctx)) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnExceptionEventWritten), HttpServerRequestDurationMetricName); return; @@ -58,18 +58,21 @@ public static void OnExceptionEventWritten(string name, object? payload) [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] #endif static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) - => ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; + { + return ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; + } #if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] #endif static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? ctx) - => HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; + { + return HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; + } } public static void OnStopEventWritten(string name, object? payload) { - var context = payload as HttpContext; - if (context == null) + if (payload is not HttpContext context) { AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnStopEventWritten), HttpServerRequestDurationMetricName); return; @@ -121,6 +124,8 @@ public override void OnEventWritten(string name, object? payload) OnStopEventWritten(name, payload); } + break; + default: break; } } diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs index ad51848e85..ab3e8a4627 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/TelemetryHelper.cs @@ -12,12 +12,7 @@ internal static class TelemetryHelper public static object GetBoxedStatusCode(int statusCode) { - if (statusCode >= 100 && statusCode < 600) - { - return BoxedStatusCodes[statusCode - 100]; - } - - return statusCode; + return statusCode is >= 100 and < 600 ? BoxedStatusCodes[statusCode - 100] : statusCode; } private static object[] InitializeBoxedStatusCodes() diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index e01d14c3ad..3318216db0 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -34,7 +34,7 @@ public DiagnosticSourceSubscriber( { Guard.ThrowIfNull(handlerFactory); - this.listenerSubscriptions = new List(); + this.listenerSubscriptions = []; this.handlerFactory = handlerFactory; this.diagnosticSourceFilter = diagnosticSourceFilter; this.isEnabledFilter = isEnabledFilter; @@ -43,10 +43,7 @@ public DiagnosticSourceSubscriber( public void Subscribe() { - if (this.allSourcesSubscription == null) - { - this.allSourcesSubscription = DiagnosticListener.AllListeners.Subscribe(this); - } + this.allSourcesSubscription ??= DiagnosticListener.AllListeners.Subscribe(this); } public void OnNext(DiagnosticListener value) diff --git a/src/Shared/RedactionHelper.cs b/src/Shared/RedactionHelper.cs index cc6e34c7ea..045d99cad2 100644 --- a/src/Shared/RedactionHelper.cs +++ b/src/Shared/RedactionHelper.cs @@ -13,8 +13,8 @@ internal sealed class RedactionHelper public static string? GetRedactedQueryString(string query) { - int length = query.Length; - int index = 0; + var length = query.Length; + var index = 0; // Preallocate some size to avoid re-sizing multiple times. // Since the size will increase, allocating twice as much. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs index f0caa4f9ec..3981971027 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -65,7 +65,9 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; +#pragma warning disable CA1515 public class AspNetCoreInstrumentationBenchmarks +#pragma warning restore CA1515 { private HttpClient? httpClient; private WebApplication? app; @@ -73,7 +75,9 @@ public class AspNetCoreInstrumentationBenchmarks private MeterProvider? meterProvider; [Flags] +#pragma warning disable CA1515 public enum EnableInstrumentationOption +#pragma warning restore CA1515 { /// /// Instrumentation is not enabled for any signal. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs index 14d777d5c3..3a13e17507 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs @@ -67,7 +67,9 @@ */ namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.Instrumentation; +#pragma warning disable CA1515 public class AspNetCoreInstrumentationNewBenchmarks +#pragma warning restore CA1515 { private HttpClient? httpClient; private WebApplication? app; @@ -75,7 +77,9 @@ public class AspNetCoreInstrumentationNewBenchmarks private MeterProvider? meterProvider; [Flags] +#pragma warning disable CA1515 public enum EnableInstrumentationOption +#pragma warning restore CA1515 { /// /// Instrumentation is not enabled for any signal. @@ -99,7 +103,7 @@ public enum EnableInstrumentationOption [GlobalSetup(Target = nameof(GetRequestForAspNetCoreApp))] public void GetRequestForAspNetCoreAppGlobalSetup() { - KeyValuePair[] config = new KeyValuePair[] { new KeyValuePair("OTEL_SEMCONV_STABILITY_OPT_IN", "http") }; + KeyValuePair[] config = [new("OTEL_SEMCONV_STABILITY_OPT_IN", "http")]; var configuration = new ConfigurationBuilder() .AddInMemoryCollection(config) .Build(); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index fb0284ac09..1d0ad5aa7f 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -241,11 +241,7 @@ public async Task CustomPropagator(bool addSampler) } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - })); + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([new TraceContextPropagator(), new BaggagePropagator()])); } } @@ -299,14 +295,9 @@ void ConfigureTestServices(IServiceCollection services) this.tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation((opt) => opt.Filter = (ctx) => { - if (ctx.Request.Path == "/api/values/2") - { - throw new Exception("from InstrumentationFilter"); - } - else - { - return true; - } + return ctx.Request.Path == "/api/values/2" + ? throw new Exception("from InstrumentationFilter") + : true; }) .AddInMemoryExporter(exportedItems) .Build(); @@ -394,11 +385,7 @@ public async Task ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - })); + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([new TraceContextPropagator(), new BaggagePropagator()])); } } @@ -415,7 +402,7 @@ public async Task ExtractContextIrrespectiveOfTheFilterApplied() Sdk.SetDefaultTextMapPropagator(new ExtractOnlyPropagator(activityContext, expectedBaggage)); // Arrange - bool isFilterCalled = false; + var isFilterCalled = false; using var testFactory = this.factory .WithWebHostBuilder(builder => { @@ -466,11 +453,7 @@ public async Task ExtractContextIrrespectiveOfTheFilterApplied() } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - })); + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([new TraceContextPropagator(), new BaggagePropagator()])); } } @@ -479,7 +462,7 @@ public async Task BaggageIsNotClearedWhenActivityStopped() { int? baggageCountAfterStart = null; int? baggageCountAfterStop = null; - using EventWaitHandle stopSignal = new EventWaitHandle(false, EventResetMode.ManualReset); + using var stopSignal = new EventWaitHandle(false, EventResetMode.ManualReset); void ConfigureTestServices(IServiceCollection services) { @@ -503,6 +486,8 @@ void ConfigureTestServices(IServiceCollection services) stopSignal.Set(); } + break; + default: break; } }, @@ -542,9 +527,9 @@ void ConfigureTestServices(IServiceCollection services) [InlineData(SamplingDecision.RecordAndSample, true, true)] public async Task FilterAndEnrichAreOnlyCalledWhenSampled(SamplingDecision samplingDecision, bool shouldFilterBeCalled, bool shouldEnrichBeCalled) { - bool filterCalled = false; - bool enrichWithHttpRequestCalled = false; - bool enrichWithHttpResponseCalled = false; + var filterCalled = false; + var enrichWithHttpRequestCalled = false; + var enrichWithHttpResponseCalled = false; void ConfigureTestServices(IServiceCollection services) { this.tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -667,9 +652,10 @@ void ConfigureTestServices(IServiceCollection services) }) .CreateClient(); - var message = new HttpRequestMessage(); - - message.Method = new HttpMethod(originalMethod); + var message = new HttpRequestMessage + { + Method = new HttpMethod(originalMethod), + }; try { @@ -811,8 +797,8 @@ public async Task ShouldExportActivityWithOneOrMoreExceptionFilters(int mode) [Fact] public async Task DiagnosticSourceCallbacksAreReceivedOnlyForSubscribedEvents() { - int numberOfUnSubscribedEvents = 0; - int numberofSubscribedEvents = 0; + var numberOfUnSubscribedEvents = 0; + var numberofSubscribedEvents = 0; this.tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation( @@ -866,9 +852,9 @@ public async Task DiagnosticSourceCallbacksAreReceivedOnlyForSubscribedEvents() [Fact] public async Task DiagnosticSourceExceptionCallbackIsReceivedForUnHandledException() { - int numberOfUnSubscribedEvents = 0; - int numberofSubscribedEvents = 0; - int numberOfExceptionCallbacks = 0; + var numberOfUnSubscribedEvents = 0; + var numberofSubscribedEvents = 0; + var numberOfExceptionCallbacks = 0; this.tracerProvider = Sdk.CreateTracerProviderBuilder() .AddAspNetCoreInstrumentation( @@ -941,10 +927,10 @@ public async Task DiagnosticSourceExceptionCallbackIsReceivedForUnHandledExcepti [Fact] public async Task DiagnosticSourceExceptionCallBackIsNotReceivedForExceptionsHandledInMiddleware() { - int numberOfUnSubscribedEvents = 0; - int numberOfSubscribedEvents = 0; - int numberOfExceptionCallbacks = 0; - bool exceptionHandled = false; + var numberOfUnSubscribedEvents = 0; + var numberOfSubscribedEvents = 0; + var numberOfExceptionCallbacks = 0; + var exceptionHandled = false; // configure SDK this.tracerProvider = Sdk.CreateTracerProviderBuilder() diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs index b5c6db209c..859a53f746 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/DependencyInjectionConfigTests.cs @@ -28,7 +28,7 @@ public void TestTracingOptionsDIConfig(string? name) { name ??= Options.DefaultName; - bool optionsPickedFromDI = false; + var optionsPickedFromDI = false; void ConfigureTestServices(IServiceCollection services) { services.AddOpenTelemetry() diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index e0eb0c32b5..c3f80a9cee 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -132,7 +132,10 @@ void ConfigureTestServices(IServiceCollection services) app.UseRateLimiter(); - static string GetTicks() => (DateTime.Now.Ticks & 0x11111).ToString("00000"); + static string GetTicks() + { + return (DateTime.Now.Ticks & 0x11111).ToString("00000"); + } app.MapGet("/", () => Results.Ok($"Hello {GetTicks()}")) .RequireRateLimiting("fixed"); @@ -226,7 +229,7 @@ public async Task RequestMetricIsCaptured(string api, string expectedRoute, stri AssertMetricPoints( metricPoints: metricPoints, - expectedRoutes: new List { expectedRoute }, + expectedRoutes: [expectedRoute], expectedErrorType, expectedStatusCode, expectedTagsCount: expectedErrorType == null ? 5 : 6); @@ -260,8 +263,10 @@ public async Task HttpRequestMethodIsCapturedAsPerSpec(string originalMethod, st }) .CreateClient(); - var message = new HttpRequestMessage(); - message.Method = new HttpMethod(originalMethod); + var message = new HttpRequestMessage + { + Method = new HttpMethod(originalMethod), + }; try { @@ -370,7 +375,7 @@ private static void AssertMetricPoint( Assert.True(sum > 0); var attributes = new KeyValuePair[metricPoint.Tags.Count]; - int i = 0; + var i = 0; foreach (var tag in metricPoint.Tags) { attributes[i++] = tag; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs index 44d0e84e43..e14243fbbe 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs @@ -11,7 +11,7 @@ namespace RouteTests; public static class RoutingTestCases { - private static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions + private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, Converters = { new JsonStringEnumConverter() }, @@ -37,7 +37,7 @@ private static List GetArgumentsFromTestCaseObject(IEnumerable apps = new(); + private readonly Dictionary apps = []; private readonly RouteInfoDiagnosticObserver diagnostics = new(); - private readonly List testResults = new(); + private readonly List testResults = []; public RoutingTestFixture() { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs index e140a3bb60..c6cbc6fba4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs @@ -20,8 +20,8 @@ public class RoutingTests : IClassFixture private const string HttpRoute = "http.route"; private readonly RoutingTestFixture fixture; - private readonly List exportedActivities = new(); - private readonly List exportedMetrics = new(); + private readonly List exportedActivities = []; + private readonly List exportedMetrics = []; public RoutingTests(RoutingTestFixture fixture) { @@ -58,7 +58,7 @@ public async Task TestHttpRoute(TestCase testCase) meterProvider.ForceFlush(); - var durationMetric = this.exportedMetrics.Single(x => x.Name == "http.server.request.duration" || x.Name == "http.server.duration"); + var durationMetric = this.exportedMetrics.Single(x => x.Name is "http.server.request.duration" or "http.server.duration"); var metricPoints = new List(); foreach (var mp in durationMetric.GetMetricPoints()) { @@ -69,7 +69,7 @@ public async Task TestHttpRoute(TestCase testCase) var metricPoint = Assert.Single(metricPoints); GetTagsFromActivity(activity, out var activityHttpStatusCode, out var activityHttpMethod, out var activityHttpRoute); - GetTagsFromMetricPoint(Environment.Version.Major < 8, metricPoint, out var metricHttpStatusCode, out var metricHttpMethod, out var metricHttpRoute); + GetTagsFromMetricPoint(metricPoint, out var metricHttpStatusCode, out var metricHttpMethod, out var metricHttpRoute); Assert.Equal(testCase.ExpectedStatusCode, activityHttpStatusCode); Assert.Equal(testCase.ExpectedStatusCode, metricHttpStatusCode); @@ -78,7 +78,7 @@ public async Task TestHttpRoute(TestCase testCase) // TODO: The CurrentHttpRoute property will go away. It They only serve to capture status quo. // If CurrentHttpRoute is null, then that means we already conform to the correct behavior. - var expectedHttpRoute = testCase.CurrentHttpRoute != null ? testCase.CurrentHttpRoute : testCase.ExpectedHttpRoute; + var expectedHttpRoute = testCase.CurrentHttpRoute ?? testCase.ExpectedHttpRoute; Assert.Equal(expectedHttpRoute, activityHttpRoute); Assert.Equal(expectedHttpRoute, metricHttpRoute); @@ -112,7 +112,7 @@ private static void GetTagsFromActivity(Activity activity, out int httpStatusCod httpRoute = activity.GetTagItem(HttpRoute) as string ?? string.Empty; } - private static void GetTagsFromMetricPoint(bool useLegacyConventions, MetricPoint metricPoint, out int httpStatusCode, out string httpMethod, out string? httpRoute) + private static void GetTagsFromMetricPoint(MetricPoint metricPoint, out int httpStatusCode, out string httpMethod, out string? httpRoute) { var expectedStatusCodeKey = HttpStatusCode; var expectedHttpMethodKey = HttpMethod; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs index 20fc1f281b..98c15a18ba 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs @@ -19,7 +19,7 @@ public ActionDescriptorInfo(ActionDescriptor actionDescriptor) { this.AttributeRouteInfo = actionDescriptor.AttributeRouteInfo?.Template; - this.ActionParameters = new List(); + this.ActionParameters = []; foreach (var item in actionDescriptor.Parameters) { this.ActionParameters.Add(item.Name); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs index 93e4174166..5394349281 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/AttributeRouteController.cs @@ -14,8 +14,10 @@ public class AttributeRouteController : ControllerBase public IActionResult Get() => this.Ok(); [HttpGet("[action]/{id}")] +#pragma warning disable IDE0060 // Remove unused parameter public IActionResult Get(int id) => this.Ok(); [HttpGet("{id}/[action]")] public IActionResult GetWithActionNameInDifferentSpotInTemplate(int id) => this.Ok(); +#pragma warning restore IDE0060 // Remove unused parameter } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs index ac6bc3be0f..4e8dafd4b3 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/Controllers/ConventionalRouteController.cs @@ -9,7 +9,9 @@ public class ConventionalRouteController : Controller { public IActionResult Default() => this.Ok(); +#pragma warning disable IDE0060 // Remove unused parameter public IActionResult ActionWithParameter(int id) => this.Ok(); public IActionResult ActionWithStringParameter(string id, int num) => this.Ok(); +#pragma warning restore IDE0060 // Remove unused parameter } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs index 610145dbc7..0d8d2e9668 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs @@ -52,9 +52,6 @@ public void SetValues(HttpContext context) public void SetValues(ActionDescriptor actionDescriptor) { - if (this.ActionDescriptor == null) - { - this.ActionDescriptor = new ActionDescriptorInfo(actionDescriptor); - } + this.ActionDescriptor ??= new ActionDescriptorInfo(actionDescriptor); } } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs index 3b3feb59e1..e5e4025ec4 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs @@ -20,7 +20,7 @@ internal sealed class RouteInfoDiagnosticObserver : IDisposable, IObserver listenerSubscriptions = new(); + private readonly List listenerSubscriptions = []; private IDisposable? allSourcesSubscription; private long disposed; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs index aa864b5bab..cc9d682db6 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs @@ -49,21 +49,15 @@ internal class TestApplicationFactory public static WebApplication? CreateApplication(TestApplicationScenario config) { Debug.Assert(Directory.Exists(ContentRootPath), $"Cannot find ContentRootPath: {ContentRootPath}"); - switch (config) + return config switch { - case TestApplicationScenario.ConventionalRouting: - return CreateConventionalRoutingApplication(); - case TestApplicationScenario.AttributeRouting: - return CreateAttributeRoutingApplication(); - case TestApplicationScenario.MinimalApi: - return CreateMinimalApiApplication(); - case TestApplicationScenario.RazorPages: - return CreateRazorPagesApplication(); - case TestApplicationScenario.ExceptionMiddleware: - return CreateExceptionHandlerApplication(); - default: - throw new ArgumentException($"Invalid {nameof(TestApplicationScenario)}"); - } + TestApplicationScenario.ConventionalRouting => CreateConventionalRoutingApplication(), + TestApplicationScenario.AttributeRouting => CreateAttributeRoutingApplication(), + TestApplicationScenario.MinimalApi => CreateMinimalApiApplication(), + TestApplicationScenario.RazorPages => CreateRazorPagesApplication(), + TestApplicationScenario.ExceptionMiddleware => CreateExceptionHandlerApplication(), + _ => throw new ArgumentException($"Invalid {nameof(TestApplicationScenario)}"), + }; } private static WebApplication CreateConventionalRoutingApplication() diff --git a/test/TestApp.AspNetCore/CallbackMiddleware.cs b/test/TestApp.AspNetCore/CallbackMiddleware.cs index 9ee236845d..4afcc87a4d 100644 --- a/test/TestApp.AspNetCore/CallbackMiddleware.cs +++ b/test/TestApp.AspNetCore/CallbackMiddleware.cs @@ -3,7 +3,7 @@ namespace TestApp.AspNetCore; -public class CallbackMiddleware +internal class CallbackMiddleware { private readonly TestCallbackMiddleware testCallbackMiddleware; private readonly RequestDelegate next; diff --git a/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs b/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs index b55927000f..068e587204 100644 --- a/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs +++ b/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs @@ -8,7 +8,9 @@ namespace TestApp.AspNetCore.Controllers; +#pragma warning disable CA1515 public class ChildActivityController : Controller +#pragma warning restore CA1515 { [HttpGet] [Route("api/GetChildActivityTraceContext")] diff --git a/test/TestApp.AspNetCore/Controllers/ErrorController.cs b/test/TestApp.AspNetCore/Controllers/ErrorController.cs index 24c904cfe9..acecf79292 100644 --- a/test/TestApp.AspNetCore/Controllers/ErrorController.cs +++ b/test/TestApp.AspNetCore/Controllers/ErrorController.cs @@ -6,7 +6,9 @@ namespace TestApp.AspNetCore.Controllers; [Route("api/[controller]")] +#pragma warning disable CA1515 public class ErrorController : Controller +#pragma warning restore CA1515 { // GET api/error [HttpGet] diff --git a/test/TestApp.AspNetCore/Controllers/ValuesController.cs b/test/TestApp.AspNetCore/Controllers/ValuesController.cs index 27a9ab0d2d..6173415709 100644 --- a/test/TestApp.AspNetCore/Controllers/ValuesController.cs +++ b/test/TestApp.AspNetCore/Controllers/ValuesController.cs @@ -6,17 +6,20 @@ namespace TestApp.AspNetCore.Controllers; [Route("api/[controller]")] +#pragma warning disable CA1515 public class ValuesController : Controller +#pragma warning restore CA1515 { // GET api/values [HttpGet] public IEnumerable Get() { - return new string[] { "value1", "value2" }; + return ["value1", "value2"]; } // GET api/values/5 [HttpGet("{id}")] +#pragma warning disable IDE0060 // Remove unused parameter public string Get(int id) { return "value"; @@ -37,6 +40,7 @@ public void Put(int id, [FromBody] string value) // DELETE api/values/5 [HttpDelete("{id}")] public void Delete(int id) +#pragma warning restore IDE0060 // Remove unused parameter { } } diff --git a/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs b/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs index 1f05886069..9f23da3f0a 100644 --- a/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs +++ b/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs @@ -5,7 +5,9 @@ namespace TestApp.AspNetCore.Filters; +#pragma warning disable CA1515 public class ExceptionFilter1 : IExceptionFilter +#pragma warning restore CA1515 { public void OnException(ExceptionContext context) { diff --git a/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs b/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs index fc81905c65..4bf428d53f 100644 --- a/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs +++ b/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs @@ -5,7 +5,9 @@ namespace TestApp.AspNetCore.Filters; +#pragma warning disable CA1515 public class ExceptionFilter2 : IExceptionFilter +#pragma warning restore CA1515 { public void OnException(ExceptionContext context) { diff --git a/test/TestApp.AspNetCore/Program.cs b/test/TestApp.AspNetCore/Program.cs index 5cbe2b5e3a..c673e205eb 100644 --- a/test/TestApp.AspNetCore/Program.cs +++ b/test/TestApp.AspNetCore/Program.cs @@ -3,7 +3,9 @@ using TestApp.AspNetCore; +#pragma warning disable CA1515 public class Program +#pragma warning restore CA1515 { public static void Main(string[] args) { diff --git a/test/TestApp.AspNetCore/TestActivityMiddleware.cs b/test/TestApp.AspNetCore/TestActivityMiddleware.cs index be1e2e5a1e..e14ad9295c 100644 --- a/test/TestApp.AspNetCore/TestActivityMiddleware.cs +++ b/test/TestApp.AspNetCore/TestActivityMiddleware.cs @@ -3,7 +3,9 @@ namespace TestApp.AspNetCore; +#pragma warning disable CA1515 public class TestActivityMiddleware +#pragma warning restore CA1515 { public virtual void PreProcess(HttpContext context) { diff --git a/test/TestApp.AspNetCore/TestCallbackMiddleware.cs b/test/TestApp.AspNetCore/TestCallbackMiddleware.cs index ba11577ff0..50e563da16 100644 --- a/test/TestApp.AspNetCore/TestCallbackMiddleware.cs +++ b/test/TestApp.AspNetCore/TestCallbackMiddleware.cs @@ -3,7 +3,9 @@ namespace TestApp.AspNetCore; +#pragma warning disable CA1515 public class TestCallbackMiddleware +#pragma warning restore CA1515 { public virtual async Task ProcessAsync(HttpContext context) { diff --git a/test/TestApp.AspNetCore/TestMiddleware.cs b/test/TestApp.AspNetCore/TestMiddleware.cs index 39acf58db3..711814d263 100644 --- a/test/TestApp.AspNetCore/TestMiddleware.cs +++ b/test/TestApp.AspNetCore/TestMiddleware.cs @@ -3,7 +3,9 @@ namespace TestApp.AspNetCore; +#pragma warning disable CA1515 public static class TestMiddleware +#pragma warning restore CA1515 { private static readonly AsyncLocal?> Current = new(); From 6b7ad127061c01295201b1f8a29884b9f3a1d207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 31 Oct 2024 20:29:26 +0100 Subject: [PATCH 1392/1499] [repo/AspNet] Prepare to .NET9 (#2282) --- .../ActivityHelperTest.cs | 27 +++++++---------- .../HttpContextHelper.cs | 29 ++++--------------- .../WebConfigWithLocationTagTransformTest.cs | 5 ---- .../HttpInMetricsListenerTests.cs | 2 +- 4 files changed, 18 insertions(+), 45 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index 0e7bacce92..93d9c59ea2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -30,7 +30,7 @@ public void Has_Started_Returns_Correctly() { var context = HttpContextHelper.GetFakeHttpContext(); - bool result = ActivityHelper.HasStarted(context, out Activity? aspNetActivity); + var result = ActivityHelper.HasStarted(context, out var aspNetActivity); Assert.False(result); Assert.Null(aspNetActivity); @@ -42,7 +42,7 @@ public void Has_Started_Returns_Correctly() Assert.True(result); Assert.Null(aspNetActivity); - Activity activity = new Activity(TestActivityName); + var activity = new Activity(TestActivityName); context.Items[ActivityHelper.ContextKey] = new ActivityHelper.ContextHolder(activity); result = ActivityHelper.HasStarted(context, out aspNetActivity); @@ -90,7 +90,7 @@ public async Task Can_Restore_Baggage() }; var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null)!; + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator([new TraceContextPropagator(), new BaggagePropagator()]), context, null)!; rootActivity.AddTag("k1", "v1"); rootActivity.AddTag("k2", "v2"); @@ -237,7 +237,7 @@ public async Task Can_Stop_Root_Activity_If_It_Is_Broken() using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; new Activity("child").Start(); - for (int i = 0; i < 2; i++) + for (var i = 0; i < 2; i++) { await Task.Run(() => { @@ -266,7 +266,7 @@ public void Stop_Root_Activity_With_129_Nesting_Depth() var context = HttpContextHelper.GetFakeHttpContext(); using var root = ActivityHelper.StartAspNetActivity(this.noopTextMapPropagator, context, null)!; - for (int i = 0; i < 129; i++) + for (var i = 0; i < 129; i++) { new Activity("child" + i).Start(); } @@ -368,7 +368,7 @@ public void Can_Create_RootActivity_From_W3C_Traceparent_With_Baggage() }; var context = HttpContextHelper.GetFakeHttpContext(headers: requestHeaders); - using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator(new TextMapPropagator[] { new TraceContextPropagator(), new BaggagePropagator() }), context, null); + using var rootActivity = ActivityHelper.StartAspNetActivity(new CompositeTextMapPropagator([new TraceContextPropagator(), new BaggagePropagator()]), context, null); Assert.NotNull(rootActivity); Assert.Equal(ActivityIdFormat.W3C, rootActivity.IdFormat); @@ -416,11 +416,11 @@ public void Can_Create_RootActivity_And_Saved_In_HttContext() public void Fire_Exception_Events() #pragma warning restore CA1030 // Use events where appropriate { - int callbacksFired = 0; + var callbacksFired = 0; var context = HttpContextHelper.GetFakeHttpContext(); - Activity activity = new Activity(TestActivityName); + var activity = new Activity(TestActivityName); ActivityHelper.WriteActivityException(activity, context, new InvalidOperationException(), (a, c, e) => { callbacksFired++; }); @@ -480,12 +480,7 @@ private void EnableListener(Action? onStarted = null, Action ActivityStopped = (a) => onStopped?.Invoke(a), Sample = (ref ActivityCreationOptions options) => { - if (onSample != null) - { - return onSample(options.Parent); - } - - return ActivitySamplingResult.AllDataAndRecorded; + return onSample?.Invoke(options.Parent) ?? ActivitySamplingResult.AllDataAndRecorded; }, }; @@ -494,7 +489,7 @@ private void EnableListener(Action? onStarted = null, Action private class TestHttpRequest : HttpRequestBase { - private readonly NameValueCollection headers = new(); + private readonly NameValueCollection headers = []; public override NameValueCollection Headers => this.headers; @@ -537,7 +532,7 @@ private class TestHttpContext : HttpContextBase public TestHttpContext(Exception? error = null) { this.Server = new TestHttpServerUtility(this); - this.items = new Hashtable(); + this.items = []; this.Error = error; } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs index 0b7541eb36..a9c079584a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/HttpContextHelper.cs @@ -33,23 +33,16 @@ private class SimpleWorkerRequestWithHeaders : SimpleWorkerRequest public SimpleWorkerRequestWithHeaders(string page, string query, TextWriter output, IDictionary? headers) : base(page, query, output) { - if (headers != null) - { - this.headers = headers; - } - else - { - this.headers = new Dictionary(); - } + this.headers = headers ?? new Dictionary(); } public override string[][] GetUnknownRequestHeaders() { - List result = new List(); + List result = []; foreach (var header in this.headers) { - result.Add(new string[] { header.Key, header.Value }); + result.Add([header.Key, header.Value]); } var baseResult = base.GetUnknownRequestHeaders(); @@ -58,29 +51,19 @@ public override string[][] GetUnknownRequestHeaders() result.AddRange(baseResult); } - return result.ToArray(); + return [.. result]; } public override string GetUnknownRequestHeader(string name) { - if (this.headers.TryGetValue(name, out var value)) - { - return value; - } - - return base.GetUnknownRequestHeader(name); + return this.headers.TryGetValue(name, out var value) ? value : base.GetUnknownRequestHeader(name); } public override string GetKnownRequestHeader(int index) { var name = GetKnownRequestHeaderName(index); - if (this.headers.TryGetValue(name, out var value)) - { - return value; - } - - return base.GetKnownRequestHeader(index); + return this.headers.TryGetValue(name, out var value) ? value : base.GetKnownRequestHeader(index); } } } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs index ce3f46ec55..aa3c072680 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/WebConfigWithLocationTagTransformTest.cs @@ -384,11 +384,6 @@ private XDocument ApplyInstallTransformation(string originalConfiguration, strin return this.ApplyTransformation(originalConfiguration, resourceName); } - private XDocument ApplyUninstallTransformation(string originalConfiguration, string resourceName) - { - return this.ApplyTransformation(originalConfiguration, resourceName); - } - private void VerifyTransformation(string expectedConfigContent, XDocument transformedWebConfig) { Assert.True( diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs index 1a259e3c1d..2f7c82d65e 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInMetricsListenerTests.cs @@ -154,7 +154,7 @@ public void AspNetMetricTagsAreCollectedSuccessfully( } Assert.Equal( - expected: new List { 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, double.PositiveInfinity }, + expected: [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, double.PositiveInfinity], actual: histogramBounds); void ExpectTag(T? expected, string tagName) From 7a94d1db234f9e1fe9d55c2aecbe7f36071b62b5 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 31 Oct 2024 12:34:50 -0700 Subject: [PATCH 1393/1499] [SqlClient] Add error.type and db.response.status_code attributes (#2262) --- .../CHANGELOG.md | 1 + .../SqlClientDiagnosticListener.cs | 11 ++++++++++- .../SqlEventSourceListener.netfx.cs | 10 ++++++++-- src/Shared/SemanticConventions.cs | 2 +- .../SqlClientIntegrationTests.cs | 17 +++++++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 1a3b4168e7..0cd67e6192 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -26,6 +26,7 @@ [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-spans.md). ([#2229](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2229), [#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277), + [#2262](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2262), [#2279](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2279)) * **Breaking change**: The `peer.service` and `server.socket.address` attributes are no longer emitted. Users should rely on the `server.address` attribute diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index b8b20b72ac..defc740632 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -4,10 +4,11 @@ #if !NETFRAMEWORK using System.Data; using System.Diagnostics; -using OpenTelemetry.Trace; #if NET using System.Diagnostics.CodeAnalysis; #endif +using System.Globalization; +using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.SqlClient.Implementation; @@ -32,6 +33,7 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler private readonly PropertyFetcher commandTypeFetcher = new("CommandType"); private readonly PropertyFetcher commandTextFetcher = new("CommandText"); private readonly PropertyFetcher exceptionFetcher = new("Exception"); + private readonly PropertyFetcher exceptionNumberFetcher = new("Number"); private readonly SqlClientTraceInstrumentationOptions options; public SqlClientDiagnosticListener(string sourceName, SqlClientTraceInstrumentationOptions? options) @@ -189,6 +191,13 @@ public override void OnEventWritten(string name, object? payload) { if (this.exceptionFetcher.TryFetch(payload, out Exception? exception) && exception != null) { + activity.AddTag(SemanticConventions.AttributeErrorType, exception.GetType().FullName); + + if (this.exceptionNumberFetcher.TryFetch(exception, out var exceptionNumber)) + { + activity.AddTag(SemanticConventions.AttributeDbResponseStatusCode, exceptionNumber.ToString(CultureInfo.InvariantCulture)); + } + activity.SetStatus(ActivityStatusCode.Error, exception.Message); if (this.options.RecordException) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index 19a6f7526d..371cae85a3 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -175,8 +175,14 @@ private void OnEndExecute(EventWrittenEventArgs eventData) { if ((compositeState & 0b010) == 0b010) { - var errorText = $"SqlExceptionNumber {eventData.Payload[2]} thrown."; - activity.SetStatus(ActivityStatusCode.Error, errorText); + var errorNumber = $"{eventData.Payload[2]}"; + activity.SetStatus(ActivityStatusCode.Error, errorNumber); + activity.SetTag(SemanticConventions.AttributeDbResponseStatusCode, errorNumber); + + var exceptionType = eventData.EventSource.Name == MdsEventSourceName + ? "Microsoft.Data.SqlClient.SqlException" + : "System.Data.SqlClient.SqlException"; + activity.SetTag(SemanticConventions.AttributeErrorType, exceptionType); } else { diff --git a/src/Shared/SemanticConventions.cs b/src/Shared/SemanticConventions.cs index cd3847cc2a..fe87612551 100644 --- a/src/Shared/SemanticConventions.cs +++ b/src/Shared/SemanticConventions.cs @@ -141,7 +141,7 @@ internal static class SemanticConventions public const string AttributeDbCollectionName = "db.collection.name"; public const string AttributeDbNamespace = "db.namespace"; public const string AttributeDbOperationName = "db.operation.name"; - public const string AttributeResponseStatusCode = "db.response.status_code"; + public const string AttributeDbResponseStatusCode = "db.response.status_code"; public const string AttributeDbOperationBatchSize = "db.operation.batch.size"; public const string AttributeDbQuerySummary = "db.query.summary"; public const string AttributeDbQueryText = "db.query.text"; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs index 9086c31490..a22e70cac9 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -93,6 +93,23 @@ public void SuccessfulCommandTest( SqlClientTests.VerifyActivityData(commandType, commandText, captureStoredProcedureCommandName, captureTextCommandContent, isFailure, recordException, shouldEnrich, activity); SqlClientTests.VerifySamplingParameters(sampler.LatestSamplingParameters); + + if (isFailure) + { +#if NET + var status = activity.GetStatus(); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Equal("Divide by zero error encountered.", activity.StatusDescription); + Assert.EndsWith("SqlException", activity.GetTagValue(SemanticConventions.AttributeErrorType) as string); + Assert.Equal("8134", activity.GetTagValue(SemanticConventions.AttributeDbResponseStatusCode)); +#else + var status = activity.GetStatus(); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Equal("8134", activity.StatusDescription); + Assert.EndsWith("SqlException", activity.GetTagValue(SemanticConventions.AttributeErrorType) as string); + Assert.Equal("8134", activity.GetTagValue(SemanticConventions.AttributeDbResponseStatusCode)); +#endif + } } private string GetConnectionString() From 79cf6e02ac15c4358dc422cc9beb36c321db3297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 31 Oct 2024 20:47:04 +0100 Subject: [PATCH 1394/1499] [repo/Grpc*] Prepare to .NET9 (#2276) --- .../ServerTracingInterceptor.cs | 4 +- .../GrpcClientDiagnosticListener.cs | 18 ++++--- .../QuartzInstrumentationOptions.cs | 10 ++-- .../FoobarService.cs | 18 ++++--- .../GrpcCoreClientInterceptorTests.cs | 11 ++-- .../GrpcCoreServerInterceptorTests.cs | 11 ++-- .../GrpcServer.cs | 2 +- .../GrpcTestHelpers/ClientTestHelpers.cs | 8 +-- .../GrpcTestHelpers/TestHttpMessageHandler.cs | 2 +- .../GrpcTestHelpers/TrailingHeadersHelpers.cs | 2 +- .../GrpcTests.client.cs | 52 ++++++++----------- .../GrpcTests.server.cs | 9 ++-- .../Services/GreeterService.cs | 2 +- test/Shared/TestActivityExportProcessor.cs | 2 +- 14 files changed, 76 insertions(+), 75 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs index d0894fd578..07600cbc5c 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/ServerTracingInterceptor.cs @@ -163,11 +163,11 @@ private class ServerRpcScope : RpcScope(); + return []; }; /// diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs index d7d7ca78bd..ed44c001fa 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/Implementation/GrpcClientDiagnosticListener.cs @@ -48,6 +48,8 @@ public override void OnEventWritten(string name, object? payload) this.OnStopActivity(activity, payload); } + break; + default: break; } } @@ -70,7 +72,7 @@ public void OnStartActivity(Activity activity, object? payload) } // Ensure context propagation irrespective of sampling decision - if (!TryFetchRequest(payload, out HttpRequestMessage? request)) + if (!TryFetchRequest(payload, out var request)) { GrpcInstrumentationEventSource.Log.NullPayload(nameof(GrpcClientDiagnosticListener), nameof(this.OnStartActivity)); return; @@ -134,7 +136,7 @@ public void OnStartActivity(Activity activity, object? payload) { var uriHostNameType = Uri.CheckHostName(requestUri.Host); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + if (uriHostNameType is UriHostNameType.IPv4 or UriHostNameType.IPv6) { activity.SetTag(SemanticConventions.AttributeServerSocketAddress, requestUri.Host); } @@ -162,14 +164,16 @@ public void OnStartActivity(Activity activity, object? payload) [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) - => StartRequestFetcher.TryFetch(payload, out request) && request != null; + { + return StartRequestFetcher.TryFetch(payload, out request) && request != null; + } } public void OnStopActivity(Activity activity, object? payload) { if (activity.IsAllDataRequested) { - bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + var validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out var status); if (validConversion) { if (activity.Status == ActivityStatusCode.Unset) @@ -184,7 +188,7 @@ public void OnStopActivity(Activity activity, object? payload) // Remove the grpc.status_code tag added by the gRPC .NET library activity.SetTag(GrpcTagHelper.GrpcStatusCodeTagName, null); - if (TryFetchResponse(payload, out HttpResponseMessage? response)) + if (TryFetchResponse(payload, out var response)) { try { @@ -203,6 +207,8 @@ public void OnStopActivity(Activity activity, object? payload) [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The event source guarantees that top level properties are preserved")] #endif static bool TryFetchResponse(object? payload, [NotNullWhen(true)] out HttpResponseMessage? response) - => StopResponseFetcher.TryFetch(payload, out response) && response != null; + { + return StopResponseFetcher.TryFetch(payload, out response) && response != null; + } } } diff --git a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs index cdbad798c2..c66006c7f8 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/QuartzInstrumentationOptions.cs @@ -13,11 +13,11 @@ public class QuartzInstrumentationOptions /// /// Default traced operations. /// - private static readonly IEnumerable DefaultTracedOperations = new[] - { + private static readonly IEnumerable DefaultTracedOperations = + [ OperationName.Job.Execute, - OperationName.Job.Veto, - }; + OperationName.Job.Veto + ]; /// /// Gets or sets an action to enrich an Activity. @@ -42,6 +42,6 @@ public class QuartzInstrumentationOptions /// Gets or sets traced operations set. /// #pragma warning disable CA2227 // Collection properties should be read only - public HashSet TracedOperations { get; set; } = new(DefaultTracedOperations); + public HashSet TracedOperations { get; set; } = [.. DefaultTracedOperations]; #pragma warning restore CA2227 // Collection properties should be read only } diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs index 1942f5f88f..fa3fc1adf5 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/FoobarService.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using Google.Protobuf; using Grpc.Core; using Grpc.Core.Interceptors; @@ -36,22 +35,22 @@ internal class FoobarService : Foobar.FoobarBase /// /// The default request message. /// - internal static readonly FoobarRequest DefaultRequestMessage = new FoobarRequest { Message = "foo" }; + internal static readonly FoobarRequest DefaultRequestMessage = new() { Message = "foo" }; /// /// The default request message size. /// - internal static readonly int DefaultRequestMessageSize = ((IMessage)DefaultRequestMessage).CalculateSize(); + internal static readonly int DefaultRequestMessageSize = DefaultRequestMessage.CalculateSize(); /// /// The default response message. /// - internal static readonly FoobarResponse DefaultResponseMessage = new FoobarResponse { Message = "bar" }; + internal static readonly FoobarResponse DefaultResponseMessage = new() { Message = "bar" }; /// /// The default request message size. /// - internal static readonly int DefaultResponseMessageSize = ((IMessage)DefaultResponseMessage).CalculateSize(); + internal static readonly int DefaultResponseMessageSize = DefaultResponseMessage.CalculateSize(); /// /// Starts the specified service. @@ -226,7 +225,12 @@ private void CheckForFailure(ServerCallContext context) var failureDescription = context.RequestHeaders.GetValue(RequestHeaderErrorDescription); if (failureStatusCodeString != null) { - throw new RpcException(new Status((StatusCode)Enum.Parse(typeof(StatusCode), failureStatusCodeString), failureDescription ?? string.Empty)); +#if NET + var statusCode = Enum.Parse(failureStatusCodeString); +#else + var statusCode = (StatusCode)Enum.Parse(typeof(StatusCode), failureStatusCodeString); +#endif + throw new RpcException(new Status(statusCode, failureDescription ?? string.Empty)); } } @@ -234,7 +238,7 @@ private void CheckForFailure(ServerCallContext context) /// Wraps server shutdown with an IDisposable pattern. /// /// - public sealed class DisposableServer : IDisposable + internal sealed class DisposableServer : IDisposable { /// /// The server. diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs index 150f20a358..7573e3e694 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreClientInterceptorTests.cs @@ -25,7 +25,7 @@ public class GrpcCoreClientInterceptorTests /// /// The default metadata func. /// - private static readonly Func DefaultMetadataFunc = () => new Metadata { new Metadata.Entry("foo", "bar") }; + private static readonly Func DefaultMetadataFunc = () => [new Metadata.Entry("foo", "bar")]; /// /// Validates a successful AsyncUnary call. @@ -327,7 +327,7 @@ internal static void ValidateCommonActivityTags( Assert.Contains(activity.TagObjects, t => t.Key == SemanticConventions.AttributeRpcGrpcStatusCode && (int?)t.Value == (int)expectedStatusCode); // Cancelled is not an error. - if (expectedStatusCode != StatusCode.OK && expectedStatusCode != StatusCode.Cancelled) + if (expectedStatusCode is not StatusCode.OK and not StatusCode.Cancelled) { Assert.Equal(ActivityStatusCode.Error, activity.Status); } @@ -495,11 +495,10 @@ private static async Task TestHandlerFailure( var client = FoobarService.ConstructRpcClient( serverUriString ?? server.UriString, new ClientTracingInterceptor(interceptorOptions), - new List - { + [ new(FoobarService.RequestHeaderFailWithStatusCode, statusCode.ToString()), - new(FoobarService.RequestHeaderErrorDescription, "fubar"), - }); + new(FoobarService.RequestHeaderErrorDescription, "fubar") + ]); using var activityListener = new InterceptorActivityListener(testTags); await Assert.ThrowsAsync(async () => await clientRequestFunc(client, null).ConfigureAwait(false)); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs index bd892bd77a..478d9623e9 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/GrpcCoreServerInterceptorTests.cs @@ -122,10 +122,7 @@ private static async Task TestHandlerSuccess(Func - { - new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), - }); + additionalMetadata: [new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling)]); await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false); @@ -152,12 +149,12 @@ private static async Task TestHandlerFailure(Func - { + additionalMetadata: + [ new Metadata.Entry("traceparent", FoobarService.DefaultTraceparentWithSampling), new Metadata.Entry(FoobarService.RequestHeaderFailWithStatusCode, StatusCode.ResourceExhausted.ToString()), new Metadata.Entry(FoobarService.RequestHeaderErrorDescription, "fubar"), - }); + ]); await Assert.ThrowsAsync(async () => await clientRequestFunc(client, additionalMetadata).ConfigureAwait(false)); diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs index 264be3be42..80ffd3fbad 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcServer.cs @@ -10,7 +10,7 @@ namespace OpenTelemetry.Instrumentation.Grpc.Tests; -public class GrpcServer : IDisposable +internal class GrpcServer : IDisposable where TService : class { private static readonly Random GlobalRandom = new(); diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs index 7835d3e7dd..ff33ec691a 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/ClientTestHelpers.cs @@ -15,8 +15,10 @@ internal static class ClientTestHelpers public static HttpClient CreateTestClient(Func> sendAsync, Uri? baseAddress = null) { var handler = TestHttpMessageHandler.Create(sendAsync); - var httpClient = new HttpClient(handler); - httpClient.BaseAddress = baseAddress ?? new Uri("https://localhost"); + var httpClient = new HttpClient(handler) + { + BaseAddress = baseAddress ?? new Uri("https://localhost"), + }; return httpClient; } @@ -24,7 +26,7 @@ public static HttpClient CreateTestClient(Func CreateResponseContent(TResponse response, ICompressionProvider? compressionProvider = null) where TResponse : IMessage { - return CreateResponseContentCore(new[] { response }, compressionProvider); + return CreateResponseContentCore([response], compressionProvider); } public static async Task WriteResponseAsync(Stream ms, TResponse response, ICompressionProvider? compressionProvider) diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs index 4f1837ce70..323195f738 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TestHttpMessageHandler.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Instrumentation.Grpc.Tests.GrpcTestHelpers; -public class TestHttpMessageHandler : HttpMessageHandler +internal class TestHttpMessageHandler : HttpMessageHandler { private readonly Func> sendAsync; diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs index 22e6e37eb4..ff3c589e95 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTestHelpers/TrailingHeadersHelpers.cs @@ -41,7 +41,7 @@ public static void EnsureTrailingHeaders(this HttpResponseMessage responseMessag private class ResponseTrailers : HttpHeaders { - public static readonly ResponseTrailers Empty = new ResponseTrailers(); + public static readonly ResponseTrailers Empty = []; } #endif } diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs index abb6fc295e..de6e55d223 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs @@ -33,8 +33,8 @@ public partial class GrpcTests [InlineData("http://[::1]", false)] public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress, bool shouldEnrich = true) { - bool enrichWithHttpRequestMessageCalled = false; - bool enrichWithHttpResponseMessageCalled = false; + var enrichWithHttpRequestMessageCalled = false; + var enrichWithHttpResponseMessageCalled = false; var uri = new Uri($"{baseAddress}:1234"); var uriHostNameType = Uri.CheckHostName(uri.Host); @@ -88,7 +88,7 @@ public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress, bool sho Assert.Equal("greet.Greeter", activity.GetTagValue(SemanticConventions.AttributeRpcService)); Assert.Equal("SayHello", activity.GetTagValue(SemanticConventions.AttributeRpcMethod)); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + if (uriHostNameType is UriHostNameType.IPv4 or UriHostNameType.IPv6) { Assert.Equal(uri.Host, activity.GetTagValue(SemanticConventions.AttributeServerSocketAddress)); Assert.Null(activity.GetTagValue(SemanticConventions.AttributeServerAddress)); @@ -246,11 +246,10 @@ public void GrpcPropagatesContextWithSuppressInstrumentationOptionSetToTrue() var propagator = new CustomTextMapPropagator(); propagator.InjectValues.Add("customField", context => "customValue"); - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([ new TraceContextPropagator(), - propagator, - })); + propagator + ])); using (Sdk.CreateTracerProviderBuilder() .AddSource("test-source") @@ -288,11 +287,10 @@ public void GrpcPropagatesContextWithSuppressInstrumentationOptionSetToTrue() } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([ new TraceContextPropagator(), - new BaggagePropagator(), - })); + new BaggagePropagator() + ])); } } @@ -305,7 +303,7 @@ public void GrpcDoesNotPropagateContextWithSuppressInstrumentationOptionSetToFal var exportedItems = new List(); using var source = new ActivitySource("test-source"); - bool isPropagatorCalled = false; + var isPropagatorCalled = false; var propagator = new CustomTextMapPropagator { Injected = (context) => isPropagatorCalled = true, @@ -342,11 +340,10 @@ public void GrpcDoesNotPropagateContextWithSuppressInstrumentationOptionSetToFal } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([ new TraceContextPropagator(), - new BaggagePropagator(), - })); + new BaggagePropagator() + ])); } } @@ -360,15 +357,13 @@ public void GrpcClientInstrumentationRespectsSdkSuppressInstrumentation() using var source = new ActivitySource("test-source"); - bool isPropagatorCalled = false; - var propagator = new CustomTextMapPropagator(); - propagator.Injected = (context) => isPropagatorCalled = true; + var isPropagatorCalled = false; + var propagator = new CustomTextMapPropagator { Injected = _ => isPropagatorCalled = true }; - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([ new TraceContextPropagator(), - propagator, - })); + propagator + ])); using (Sdk.CreateTracerProviderBuilder() .AddSource("test-source") @@ -395,11 +390,10 @@ public void GrpcClientInstrumentationRespectsSdkSuppressInstrumentation() } finally { - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([ new TraceContextPropagator(), - new BaggagePropagator(), - })); + new BaggagePropagator() + ])); } } #endif @@ -407,8 +401,8 @@ public void GrpcClientInstrumentationRespectsSdkSuppressInstrumentation() [Fact] public void AddGrpcClientInstrumentationNamedOptionsSupported() { - int defaultExporterOptionsConfigureOptionsInvocations = 0; - int namedExporterOptionsConfigureOptionsInvocations = 0; + var defaultExporterOptionsConfigureOptionsInvocations = 0; + var namedExporterOptionsConfigureOptionsInvocations = 0; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs index 0052403748..5d16091ed3 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs @@ -173,11 +173,10 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewAc finally { // Set the SDK to use the default propagator for other unit tests - Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[] - { - new TraceContextPropagator(), - new BaggagePropagator(), - })); + Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator([ + new TraceContextPropagator(), + new BaggagePropagator() + ])); } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs index f2f7b4c1aa..81bdb7dc57 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/Services/GreeterService.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Instrumentation.Grpc.Services.Tests; -public class GreeterService : Greeter.GreeterBase +internal class GreeterService : Greeter.GreeterBase { private readonly ILogger logger; diff --git a/test/Shared/TestActivityExportProcessor.cs b/test/Shared/TestActivityExportProcessor.cs index b19eb9ad2f..0c4dadfb16 100644 --- a/test/Shared/TestActivityExportProcessor.cs +++ b/test/Shared/TestActivityExportProcessor.cs @@ -9,7 +9,7 @@ namespace OpenTelemetry.Tests; internal class TestActivityExportProcessor : SimpleActivityExportProcessor { - public List ExportedItems = new List(); + public List ExportedItems = []; public TestActivityExportProcessor(BaseExporter exporter) : base(exporter) From 32c4e943405acf811120b9723aabd3740f63b8ae Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 31 Oct 2024 16:41:21 -0700 Subject: [PATCH 1395/1499] [sqlclient] Remove SetDbStatementForStoredProcedure option (#2284) --- .../.publicApi/PublicAPI.Unshipped.txt | 2 - .../CHANGELOG.md | 2 + .../SqlClientDiagnosticListener.cs | 19 ++--- .../README.md | 72 ++++++++---------- .../SqlClientTraceInstrumentationOptions.cs | 13 ---- .../SqlClientIntegrationTests.cs | 21 ++---- .../SqlClientTests.cs | 75 ++++++++----------- 7 files changed, 80 insertions(+), 124 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt index bc00a1d8c2..7a79bbb9f4 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt @@ -8,8 +8,6 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Fil OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForStoredProcedure.get -> bool -OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.get -> bool OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SqlClientTraceInstrumentationOptions() -> void diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 0cd67e6192..d69cfbd959 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -45,6 +45,8 @@ `server.address`, and `server.port`. These attributes are now available for sampling decisions. ([#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277)) +* **Breaking change**: The `SetDbStatementForStoredProcedure` option has been removed. + ([#TBD](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/TBD)) ## 1.9.0-beta.1 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index defc740632..36c3ac89ba 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -103,19 +103,16 @@ public override void OnEventWritten(string name, object? payload) switch (commandType) { case CommandType.StoredProcedure: - if (this.options.SetDbStatementForStoredProcedure) + if (this.options.EmitOldAttributes) { - if (this.options.EmitOldAttributes) - { - activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); - } + activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); + } - if (this.options.EmitNewAttributes) - { - activity.SetTag(SemanticConventions.AttributeDbOperationName, "EXECUTE"); - activity.SetTag(SemanticConventions.AttributeDbCollectionName, commandText); - activity.SetTag(SemanticConventions.AttributeDbQueryText, commandText); - } + if (this.options.EmitNewAttributes) + { + activity.SetTag(SemanticConventions.AttributeDbOperationName, "EXECUTE"); + activity.SetTag(SemanticConventions.AttributeDbCollectionName, commandText); + activity.SetTag(SemanticConventions.AttributeDbQueryText, commandText); } break; diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index e1c15c28c7..71cd7dd3eb 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -83,42 +83,32 @@ For an ASP.NET application, adding instrumentation is typically done in the This instrumentation can be configured to change the default behavior by using `SqlClientTraceInstrumentationOptions`. -### Capturing database statements +### SetDbStatementForText -The `SqlClientTraceInstrumentationOptions` class exposes two properties that can -be used to configure how the +Capturing the text of a database query may run the risk of capturing sensitive data. +`SetDbStatementForText` controls whether the [`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) -attribute is captured upon execution of a query but the behavior depends on the -runtime used. +attribute is captured in scenarios where there could be a risk of exposing +sensitive data. The behavior of `SetDbStatementForText` depends on the runtime +used. -#### .NET and .NET Core +#### .NET -On .NET and .NET Core, two properties are available: -`SetDbStatementForStoredProcedure` and `SetDbStatementForText`. These properties -control capturing of `CommandType.StoredProcedure` and `CommandType.Text` -respectively. - -`SetDbStatementForStoredProcedure` is _true_ by default and will set +On .NET, `SetDbStatementForText` controls whether or not +this instrumentation will set the +[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) +attribute to the `CommandText` of the `SqlCommand` being executed when the `CommandType` +is `CommandType.Text`. The [`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) -attribute to the stored procedure command name. +attribute is always captured for `CommandType.StoredProcedure` because the `SqlCommand.CommandText` +only contains the stored procedure name. -`SetDbStatementForText` is _false_ by default (to prevent accidental capture of -sensitive data that might be part of the SQL statement text). When set to -`true`, the instrumentation will set +`SetDbStatementForText` is _false_ by default. When set to `true`, the +instrumentation will set [`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) attribute to the text of the SQL command being executed. -To disable capturing stored procedure commands use configuration like below. - -```csharp -using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSqlClientInstrumentation( - options => options.SetDbStatementForStoredProcedure = false) - .AddConsoleExporter() - .Build(); -``` - -To enable capturing of `sqlCommand.CommandText` for `CommandType.Text` use the +To enable capturing of `SqlCommand.CommandText` for `CommandType.Text` use the following configuration. ```csharp @@ -131,20 +121,22 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() #### .NET Framework -On .NET Framework, the `SetDbStatementForText` property controls whether or not -this instrumentation will set the +On .NET Framework, there is no way to determine the type of command being +executed, so the `SetDbStatementForText` property always controls whether +or not this instrumentation will set the +[`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) +attribute to the `CommandText` of the `SqlCommand` being executed. The +`CommandText` could be the name of a stored procedure (when +`CommandType.StoredProcedure` is used) or the full text of a `CommandType.Text` +query. + +`SetDbStatementForText` is _false_ by default. When set to `true`, the +instrumentation will set [`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md#call-level-attributes) -attribute to the text of the `SqlCommand` being executed. This could either be -the name of a stored procedure (when `CommandType.StoredProcedure` is used) or -the full text of a `CommandType.Text` query. `SetDbStatementForStoredProcedure` -is ignored because on .NET Framework there is no way to determine the type of -command being executed. - -Since `CommandType.Text` might contain sensitive data, all SQL capturing is -_disabled_ by default to protect against accidentally sending full query text to -a telemetry backend. If you are only using stored procedures or have no -sensitive data in your `sqlCommand.CommandText`, you can enable SQL capturing -using the options like below: +attribute to the text of the SQL command being executed. + +To enable capturing of `SqlCommand.CommandText` for `CommandType.Text` use the +following configuration. ```csharp using var tracerProvider = Sdk.CreateTracerProviderBuilder() diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs index dd7b38eb0e..1aa0078e2f 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs @@ -32,19 +32,6 @@ internal SqlClientTraceInstrumentationOptions(IConfiguration configuration) this.EmitNewAttributes = databaseSemanticConvention.HasFlag(DatabaseSemanticConvention.New); } - /// - /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default - /// value: . - /// - /// - /// SetDbStatementForStoredProcedure is only supported on .NET - /// and .NET Core runtimes. - /// - public bool SetDbStatementForStoredProcedure { get; set; } = true; - /// /// Gets or sets a value indicating whether or not the should add the text of commands as diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs index a22e70cac9..cc70a4d8ee 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -23,17 +23,15 @@ public SqlClientIntegrationTests(SqlClientIntegrationTestsFixture fixture) } [EnabledOnDockerPlatformTheory(EnabledOnDockerPlatformTheoryAttribute.DockerPlatform.Linux)] - [InlineData(CommandType.Text, "select 1/1", false)] - [InlineData(CommandType.Text, "select 1/1", false, true)] - [InlineData(CommandType.Text, "select 1/0", false, false, true)] - [InlineData(CommandType.Text, "select 1/0", false, false, true, false, false)] - [InlineData(CommandType.Text, "select 1/0", false, false, true, true, false)] - [InlineData(CommandType.StoredProcedure, "sp_who", false)] - [InlineData(CommandType.StoredProcedure, "sp_who", true)] + [InlineData(CommandType.Text, "select 1/1")] + [InlineData(CommandType.Text, "select 1/1", true)] + [InlineData(CommandType.Text, "select 1/0", false, true)] + [InlineData(CommandType.Text, "select 1/0", false, true, false, false)] + [InlineData(CommandType.Text, "select 1/0", false, true, true, false)] + [InlineData(CommandType.StoredProcedure, "sp_who")] public void SuccessfulCommandTest( CommandType commandType, string commandText, - bool captureStoredProcedureCommandName, bool captureTextCommandContent = false, bool isFailure = false, bool recordException = false, @@ -52,12 +50,7 @@ public void SuccessfulCommandTest( .AddInMemoryExporter(activities) .AddSqlClientInstrumentation(options => { -#if !NETFRAMEWORK - options.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName; options.SetDbStatementForText = captureTextCommandContent; -#else - options.SetDbStatementForText = captureStoredProcedureCommandName || captureTextCommandContent; -#endif options.RecordException = recordException; if (shouldEnrich) { @@ -91,7 +84,7 @@ public void SuccessfulCommandTest( Assert.Single(activities); var activity = activities[0]; - SqlClientTests.VerifyActivityData(commandType, commandText, captureStoredProcedureCommandName, captureTextCommandContent, isFailure, recordException, shouldEnrich, activity); + SqlClientTests.VerifyActivityData(commandType, commandText, captureTextCommandContent, isFailure, recordException, shouldEnrich, activity); SqlClientTests.VerifySamplingParameters(sampler.LatestSamplingParameters); if (isFailure) diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 1eb6774267..9e68bb1624 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -65,40 +65,39 @@ public void SqlClient_NamedOptions() // DiagnosticListener-based instrumentation is only available on .NET Core #if !NETFRAMEWORK [Theory] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, false)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, false)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, false)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false)] // Test cases when EmitOldAttributes = false and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database) - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, false, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, false, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, false, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, false, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, false, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, false, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, true, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, true, false, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, false, true)] // Test cases when EmitOldAttributes = true and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database/dup) - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, false, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, false, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, false, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, false, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, false, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, false, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, true, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, true, true, true)] + [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, true, true)] public void SqlClientCallsAreCollectedSuccessfully( string beforeCommand, string afterCommand, CommandType commandType, string commandText, - bool captureStoredProcedureCommandName, bool captureTextCommandContent, bool shouldEnrich = true, bool emitOldAttributes = true, @@ -113,7 +112,6 @@ public void SqlClientCallsAreCollectedSuccessfully( (opt) => { opt.SetDbStatementForText = captureTextCommandContent; - opt.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName; if (shouldEnrich) { opt.Enrich = ActivityEnrichment; @@ -160,7 +158,6 @@ public void SqlClientCallsAreCollectedSuccessfully( VerifyActivityData( sqlCommand.CommandType, sqlCommand.CommandText, - captureStoredProcedureCommandName, captureTextCommandContent, false, false, @@ -282,7 +279,6 @@ public void SqlClientErrorsAreCollectedSuccessfully(string beforeCommand, string VerifyActivityData( sqlCommand.CommandType, sqlCommand.CommandText, - true, false, true, recordException, @@ -365,7 +361,6 @@ public void ShouldNotCollectTelemetryAndShouldNotPropagateExceptionWhenFilterThr internal static void VerifyActivityData( CommandType commandType, string commandText, - bool captureStoredProcedureCommandName, bool captureTextCommandContent, bool isFailure, bool recordException, @@ -433,24 +428,16 @@ internal static void VerifyActivityData( switch (commandType) { case CommandType.StoredProcedure: - if (captureStoredProcedureCommandName) + if (emitOldAttributes) { - if (emitOldAttributes) - { - Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - } - - if (emitNewAttributes) - { - Assert.Equal("EXECUTE", activity.GetTagValue(SemanticConventions.AttributeDbOperationName)); - Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbCollectionName)); - Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbQueryText)); - } + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbStatement)); } - else + + if (emitNewAttributes) { - Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbStatement)); - Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbQueryText)); + Assert.Equal("EXECUTE", activity.GetTagValue(SemanticConventions.AttributeDbOperationName)); + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbCollectionName)); + Assert.Equal(commandText, activity.GetTagValue(SemanticConventions.AttributeDbQueryText)); } break; From 3649132478e8178968356025ca2e3d7a52732cf2 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sun, 3 Nov 2024 23:36:54 -0600 Subject: [PATCH 1396/1499] [release] core-1.10.0-rc.1 release updates (#2285) --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index bbbe345136..ff82b6647f 100644 --- a/build/Common.props +++ b/build/Common.props @@ -44,7 +44,7 @@ [8.0.0,9.0) [1.9.0-beta.2] [1.9.0,2.0) - [1.10.0-beta.1] + [1.10.0-rc.1] [2.6.122,3.0) [2.4.0,3.0) [3.16.0,4.0) From c732609e0f372d697e8453f0e9d6858a8d0f7112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Nov 2024 13:00:58 +0100 Subject: [PATCH 1397/1499] [repo/Runtime] Prepare to .NET9 (#2281) --- .../RuntimeMetrics.cs | 53 +++++++++---------- .../RuntimeInstrumentationOptionsTests.cs | 2 +- .../RuntimeMetricsTests.cs | 22 ++++---- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index b267c9c4a6..a67f264633 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -24,14 +24,16 @@ internal sealed class RuntimeMetrics #endif private const int NumberOfGenerations = 3; - private static readonly string[] GenNames = new string[] { "gen0", "gen1", "gen2", "loh", "poh" }; + private static readonly string[] GenNames = ["gen0", "gen1", "gen2", "loh", "poh"]; +#if NET private static bool isGcInfoAvailable; +#endif static RuntimeMetrics() { MeterInstance.CreateObservableCounter( "process.runtime.dotnet.gc.collections.count", - () => GetGarbageCollectionCounts(), + GetGarbageCollectionCounts, description: "Number of garbage collections that have occurred since process start."); MeterInstance.CreateObservableUpDownCounter( @@ -51,19 +53,14 @@ static RuntimeMetrics() "process.runtime.dotnet.gc.committed_memory.size", () => { - if (!IsGcInfoAvailable) - { - return Array.Empty>(); - } - - return new Measurement[] { new(GC.GetGCMemoryInfo().TotalCommittedBytes) }; + return !IsGcInfoAvailable ? Array.Empty>() : [new(GC.GetGCMemoryInfo().TotalCommittedBytes)]; }, unit: "bytes", description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); // GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 Func? getGenerationSize = null; - bool isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; + var isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; if (isCodeRunningOnBuggyRuntimeVersion) { var mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); @@ -82,22 +79,17 @@ static RuntimeMetrics() { if (!IsGcInfoAvailable) { - return Array.Empty>(); + return []; } var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) + var measurements = new Measurement[generationInfo.Length]; + var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (var i = 0; i < maxSupportedLength; ++i) { - if (isCodeRunningOnBuggyRuntimeVersion) - { - measurements[i] = new((long)getGenerationSize!(i), new KeyValuePair("generation", GenNames[i])); - } - else - { - measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); - } + measurements[i] = isCodeRunningOnBuggyRuntimeVersion + ? new((long)getGenerationSize!(i), new KeyValuePair("generation", GenNames[i])) + : new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); } return measurements; @@ -115,13 +107,13 @@ static RuntimeMetrics() { if (!IsGcInfoAvailable) { - return Array.Empty>(); + return []; } var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - Measurement[] measurements = new Measurement[generationInfo.Length]; - int maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (int i = 0; i < maxSupportedLength; ++i) + var measurements = new Measurement[generationInfo.Length]; + var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (var i = 0; i < maxSupportedLength; ++i) { measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); } @@ -201,15 +193,17 @@ static RuntimeMetrics() exceptionCounter.Add(1); }; } - +#pragma warning disable SA1313 /// /// Initializes a new instance of the class. /// - /// The options to define the metrics. - public RuntimeMetrics(RuntimeInstrumentationOptions options) + /// The options to define the metrics. + public RuntimeMetrics(RuntimeInstrumentationOptions _1) +#pragma warning restore SA1313 { } +#if NET private static bool IsGcInfoAvailable { get @@ -227,12 +221,13 @@ private static bool IsGcInfoAvailable return isGcInfoAvailable; } } +#endif private static IEnumerable> GetGarbageCollectionCounts() { long collectionsFromHigherGeneration = 0; - for (int gen = NumberOfGenerations - 1; gen >= 0; --gen) + for (var gen = NumberOfGenerations - 1; gen >= 0; --gen) { long collectionsFromThisGeneration = GC.CollectionCount(gen); diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs index 39d8faff0d..4ee8aceb74 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeInstrumentationOptionsTests.cs @@ -3,7 +3,7 @@ namespace OpenTelemetry.Instrumentation.Runtime.Tests; -public class RuntimeInstrumentationOptionsTests +internal class RuntimeInstrumentationOptionsTests { /* [Fact] diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index ace5166232..877c3a4d52 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -113,9 +113,9 @@ public async Task ThreadingRelatedMetricsTest() .Build(); // Bump the count for `thread_pool.completed_items.count` metric - int taskCount = 50; - List tasks = new List(); - for (int i = 0; i < taskCount; i++) + var taskCount = 50; + var tasks = new List(); + for (var i = 0; i < taskCount; i++) { tasks.Add(Task.Run(() => { })); } @@ -137,15 +137,19 @@ public async Task ThreadingRelatedMetricsTest() var queueLengthMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.thread_pool.queue.length"); Assert.NotNull(queueLengthMetric); - List timers = new List(); + var timers = new List(); try { // Create 10 timers to bump timer.count metrics. - int timerCount = 10; - TimerCallback timerCallback = _ => { }; - for (int i = 0; i < timerCount; i++) + var timerCount = 10; +#pragma warning disable SA1313 + static void TimerCallback(object? _) { - Timer timer = new Timer(timerCallback, null, 1000, 250); + } +#pragma warning restore SA1313 + for (var i = 0; i < timerCount; i++) + { + var timer = new Timer(TimerCallback, null, 1000, 250); timers.Add(timer); } @@ -157,7 +161,7 @@ public async Task ThreadingRelatedMetricsTest() } finally { - for (int i = 0; i < timers.Count; i++) + for (var i = 0; i < timers.Count; i++) { timers[i].Dispose(); } From 5acf5e6bb6c4c9304a9f4a5536a010b8716be15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Nov 2024 18:49:15 +0100 Subject: [PATCH 1398/1499] [repo] Remove #nullable enable (#2290) --- src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs | 2 -- src/Shared/ActivityHelperExtensions.cs | 2 -- src/Shared/ActivityInstrumentationHelper.cs | 2 -- src/Shared/AssemblyVersionExtensions.cs | 2 -- src/Shared/Configuration/IConfigurationExtensionsLogger.cs | 2 -- .../Configuration/OpenTelemetryConfigurationExtensions.cs | 2 -- src/Shared/DatabaseSemanticConventionHelper.cs | 2 -- src/Shared/DiagnosticSourceListener.cs | 2 -- src/Shared/DiagnosticSourceSubscriber.cs | 2 -- src/Shared/ExceptionExtensions.cs | 2 -- src/Shared/GrpcStatusCanonicalCode.cs | 2 -- src/Shared/GrpcTagHelper.cs | 2 -- src/Shared/Guard.cs | 2 -- src/Shared/ListenerHandler.cs | 2 -- src/Shared/MultiTypePropertyFetcher.cs | 2 -- .../DelegatingOptionsFactoryServiceCollectionExtensions.cs | 2 -- src/Shared/Options/SingletonOptionsManager.cs | 2 -- src/Shared/PropertyFetcher.AOT.cs | 2 -- src/Shared/RedactionHelper.cs | 2 -- src/Shared/RequestDataHelper.cs | 2 -- .../GenevaLogExporterTests.cs | 2 ++ .../GenevaMetricExporterOptionsTests.cs | 2 ++ .../GenevaMetricExporterTests.cs | 2 ++ .../GenevaTraceExporterTests.cs | 2 ++ test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs | 2 ++ .../LogSerializationTests.cs | 2 ++ .../MessagePackSerializerTests.cs | 2 ++ .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 - .../OtlpProtobufMetricExporterTests.cs | 2 ++ .../TableNameSerializerTests.cs | 2 ++ .../UnixDomainSocketDataTransportTests.cs | 2 ++ .../UnixDomainSocketEndPointTests.cs | 2 ++ .../UnixUserEventsDataTransportTests.cs | 2 -- .../Processors/EventsActivityProcessorTests.cs | 2 -- .../RouteTests/RoutingTestCases.cs | 2 -- .../RouteTests/RoutingTestFixture.cs | 2 -- .../RouteTests/RoutingTestResult.cs | 2 -- .../RouteTests/RoutingTests.cs | 2 -- .../RouteTests/TestApplication/ActionDescriptorInfo.cs | 1 - .../TestApplication/ControllerActionDescriptorInfo.cs | 1 - .../RouteTests/TestApplication/PageActionDescriptorInfo.cs | 1 - .../RouteTests/TestApplication/RouteInfo.cs | 2 -- .../RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs | 2 -- .../RouteTests/TestApplication/TestApplicationFactory.cs | 2 -- .../RouteTests/TestCase.cs | 1 - test/Shared/CustomTextMapPropagator.cs | 2 -- test/Shared/EventSourceTestHelper.cs | 2 -- test/Shared/InMemoryEventListener.cs | 2 -- test/Shared/PlatformHelpers.cs | 2 -- test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs | 2 -- test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs | 2 -- test/Shared/TestActivityExportProcessor.cs | 2 -- test/Shared/TestActivityProcessor.cs | 2 -- test/Shared/TestEventListener.cs | 2 -- test/Shared/TestHttpServer.cs | 2 -- test/Shared/TestSampler.cs | 2 -- test/Shared/TestTextMapPropagator.cs | 2 -- 57 files changed, 22 insertions(+), 87 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index 15fab0e0fa..abf8f996bf 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Internal; diff --git a/src/Shared/ActivityHelperExtensions.cs b/src/Shared/ActivityHelperExtensions.cs index 7425c97edc..2e5430ead6 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; diff --git a/src/Shared/ActivityInstrumentationHelper.cs b/src/Shared/ActivityInstrumentationHelper.cs index 02a0d83e16..0f7ec41d1a 100644 --- a/src/Shared/ActivityInstrumentationHelper.cs +++ b/src/Shared/ActivityInstrumentationHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; namespace OpenTelemetry.Instrumentation; diff --git a/src/Shared/AssemblyVersionExtensions.cs b/src/Shared/AssemblyVersionExtensions.cs index 4c71ae3598..953de906cc 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.Reflection; diff --git a/src/Shared/Configuration/IConfigurationExtensionsLogger.cs b/src/Shared/Configuration/IConfigurationExtensionsLogger.cs index 0835cf6ff8..196a485bf3 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 e663c53a67..3637927de2 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 NET || NETSTANDARD2_1 using System.Diagnostics.CodeAnalysis; diff --git a/src/Shared/DatabaseSemanticConventionHelper.cs b/src/Shared/DatabaseSemanticConventionHelper.cs index a3bc4b5e98..1225e43069 100644 --- a/src/Shared/DatabaseSemanticConventionHelper.cs +++ b/src/Shared/DatabaseSemanticConventionHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Configuration; diff --git a/src/Shared/DiagnosticSourceListener.cs b/src/Shared/DiagnosticSourceListener.cs index 3ffad9bf33..9b0b07b3c8 100644 --- a/src/Shared/DiagnosticSourceListener.cs +++ b/src/Shared/DiagnosticSourceListener.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/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index 3318216db0..87863b2193 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.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/Shared/ExceptionExtensions.cs b/src/Shared/ExceptionExtensions.cs index 9070b59c20..5071a8feeb 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/GrpcStatusCanonicalCode.cs b/src/Shared/GrpcStatusCanonicalCode.cs index d4ec2cf7fb..8abad05f25 100644 --- a/src/Shared/GrpcStatusCanonicalCode.cs +++ b/src/Shared/GrpcStatusCanonicalCode.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - namespace OpenTelemetry.Instrumentation; /// diff --git a/src/Shared/GrpcTagHelper.cs b/src/Shared/GrpcTagHelper.cs index d7c22b1c63..7911cc5c7d 100644 --- a/src/Shared/GrpcTagHelper.cs +++ b/src/Shared/GrpcTagHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using System.Text.RegularExpressions; using OpenTelemetry.Trace; diff --git a/src/Shared/Guard.cs b/src/Shared/Guard.cs index a00cfafb09..d8b88d6a07 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 - // Note: For some targets this file will contain more than one type/namespace. #pragma warning disable IDE0161 // Convert to file-scoped namespace diff --git a/src/Shared/ListenerHandler.cs b/src/Shared/ListenerHandler.cs index a7c6f9049d..d711aab6b0 100644 --- a/src/Shared/ListenerHandler.cs +++ b/src/Shared/ListenerHandler.cs @@ -3,8 +3,6 @@ using System.Diagnostics; -#nullable enable - namespace OpenTelemetry.Instrumentation; /// diff --git a/src/Shared/MultiTypePropertyFetcher.cs b/src/Shared/MultiTypePropertyFetcher.cs index 1370094a58..b5f82fd86d 100644 --- a/src/Shared/MultiTypePropertyFetcher.cs +++ b/src/Shared/MultiTypePropertyFetcher.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Collections.Concurrent; using System.Reflection; diff --git a/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs b/src/Shared/Options/DelegatingOptionsFactoryServiceCollectionExtensions.cs index b3b9736277..81e9ac0a66 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 4c7718e78c..d3b1928d55 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/PropertyFetcher.AOT.cs b/src/Shared/PropertyFetcher.AOT.cs index 209f91cada..19b3153814 100644 --- a/src/Shared/PropertyFetcher.AOT.cs +++ b/src/Shared/PropertyFetcher.AOT.cs @@ -5,8 +5,6 @@ // Usages of the non-AOT-compatible version can be moved over to this one when they need to support AOT/trimming. // Copied from https://github.com/open-telemetry/opentelemetry-dotnet/blob/86a6ba0b7f7ed1f5e84e5a6610e640989cd3ae9f/src/Shared/DiagnosticSourceInstrumentation/PropertyFetcher.cs#L30 -#nullable enable - #if NETSTANDARD2_1_0_OR_GREATER || NET using System.Diagnostics.CodeAnalysis; #endif diff --git a/src/Shared/RedactionHelper.cs b/src/Shared/RedactionHelper.cs index 045d99cad2..ed34bb3e4f 100644 --- a/src/Shared/RedactionHelper.cs +++ b/src/Shared/RedactionHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Text; namespace OpenTelemetry.Internal; diff --git a/src/Shared/RequestDataHelper.cs b/src/Shared/RequestDataHelper.cs index 6acce7fe40..edd9532569 100644 --- a/src/Shared/RequestDataHelper.cs +++ b/src/Shared/RequestDataHelper.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #if NET using System.Collections.Frozen; #endif diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index e5065cc143..eaa566ed9d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Diagnostics; using System.Globalization; using System.Net.Sockets; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs index e711d89757..5ccc866188 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterOptionsTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using Xunit; namespace OpenTelemetry.Exporter.Geneva.Tests; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 62d1176481..d7f189a0e6 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Diagnostics; using System.Diagnostics.Metrics; using System.Globalization; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index c4d8d21205..6bf12ca320 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Diagnostics; using System.Net.Sockets; using System.Reflection; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs index c49a58b40c..783e3524cf 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Text; using OpenTelemetry.Exporter.Geneva.Tld; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index dd311dcff1..d71cbb2cb7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Net.Sockets; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 997a6afd87..640f78f0c0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Globalization; using System.Text; using OpenTelemetry.Exporter.Geneva.MsgPack; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 4cc8b83b36..31ae1a4442 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -8,7 +8,6 @@ $(TargetFrameworks);net48;net472;net471;net47;net462 Unit test project for Geneva Exporters for OpenTelemetry. $(NoWarn);SA1311;SA1312;SA1313;SA1123;SA1202;OTEL1002 - disable diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 4870b6aee1..5ac0832ba0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Diagnostics; using System.Diagnostics.Metrics; using Google.Protobuf; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs index b4b01ab8f4..636676c55c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Text; using Xunit; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 753de5c7e0..0fb9e2302c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable disable + using System.Net.Sockets; using System.Reflection; using OpenTelemetry.Exporter.Geneva.Transports; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index d0d922ca2b..85351d141c 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -3,6 +3,8 @@ #if !NET +#nullable disable + using System.Net; using System.Net.Sockets; using System.Text; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs index 6cc7956eb9..4af7484581 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs @@ -3,8 +3,6 @@ #if NET6_0_OR_GREATER -#nullable enable - using System.Diagnostics; using System.Globalization; using System.Text.RegularExpressions; diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index 35452ace15..7b46ec5013 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using OpenTelemetry.Exporter.Instana.Implementation; using OpenTelemetry.Exporter.Instana.Implementation.Processors; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs index e14243fbbe..f02b4203fe 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestCases.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs index fdb42af421..a49503722b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Globalization; using System.Text; using Microsoft.AspNetCore.Builder; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs index f1df77ba10..affa074c20 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Text.Json; using System.Text.Json.Serialization; using RouteTests.TestApplication; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs index c6cbc6fba4..93199709ea 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTests.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using OpenTelemetry; using OpenTelemetry.Metrics; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs index 98c15a18ba..e0df2673e8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable using System.Text.Json.Serialization; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Controllers; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs index ae5ef6b907..34260c4889 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ControllerActionDescriptorInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable using System.Text.Json.Serialization; namespace RouteTests.TestApplication; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs index dda48ae462..bdaf96851a 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable using System.Text.Json.Serialization; namespace RouteTests.TestApplication; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs index 0d8d2e9668..2754617e78 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Text.Json.Serialization; using Microsoft.AspNetCore.Http; #if NET diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs index e5e4025ec4..a144f56b58 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs index cc9d682db6..c50fe412f2 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/TestApplicationFactory.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Diagnostics; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics; diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs index 36710fe4a9..f4e07d2388 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestCase.cs @@ -1,7 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable using RouteTests.TestApplication; namespace RouteTests; diff --git a/test/Shared/CustomTextMapPropagator.cs b/test/Shared/CustomTextMapPropagator.cs index 8d3404e816..436879e8b5 100644 --- a/test/Shared/CustomTextMapPropagator.cs +++ b/test/Shared/CustomTextMapPropagator.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/test/Shared/EventSourceTestHelper.cs b/test/Shared/EventSourceTestHelper.cs index 02de7a2a76..837f3cd569 100644 --- a/test/Shared/EventSourceTestHelper.cs +++ b/test/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/Shared/InMemoryEventListener.cs b/test/Shared/InMemoryEventListener.cs index bf3d3fd567..4ddb42bb52 100644 --- a/test/Shared/InMemoryEventListener.cs +++ b/test/Shared/InMemoryEventListener.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using System.Collections.Concurrent; using System.Diagnostics.Tracing; diff --git a/test/Shared/PlatformHelpers.cs b/test/Shared/PlatformHelpers.cs index a737fa49f3..22b9c3a570 100644 --- a/test/Shared/PlatformHelpers.cs +++ b/test/Shared/PlatformHelpers.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - #pragma warning disable SA1649 // File name should match first type name #pragma warning disable SA1402 // File may only contain a single type diff --git a/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs b/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs index d6e4f02518..88bedacb31 100644 --- a/test/Shared/SkipUnlessEnvVarFoundFactAttribute.cs +++ b/test/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/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs b/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs index 5820d36bef..2e43f8cb19 100644 --- a/test/Shared/SkipUnlessEnvVarFoundTheoryAttribute.cs +++ b/test/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/Shared/TestActivityExportProcessor.cs b/test/Shared/TestActivityExportProcessor.cs index 0c4dadfb16..b882af8f8e 100644 --- a/test/Shared/TestActivityExportProcessor.cs +++ b/test/Shared/TestActivityExportProcessor.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/Shared/TestActivityProcessor.cs b/test/Shared/TestActivityProcessor.cs index b788c5fa7c..e0319da15a 100644 --- a/test/Shared/TestActivityProcessor.cs +++ b/test/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/Shared/TestEventListener.cs b/test/Shared/TestEventListener.cs index 424ba512a6..29cb03d6bc 100644 --- a/test/Shared/TestEventListener.cs +++ b/test/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/Shared/TestHttpServer.cs b/test/Shared/TestHttpServer.cs index c567606649..d294ff24eb 100644 --- a/test/Shared/TestHttpServer.cs +++ b/test/Shared/TestHttpServer.cs @@ -4,8 +4,6 @@ // Note: When implicit usings are enabled in a project this file will generate // warnings/errors without this suppression. -#nullable enable - using System.Net; #if !NETFRAMEWORK using System.Security.Cryptography; diff --git a/test/Shared/TestSampler.cs b/test/Shared/TestSampler.cs index c23bf68ed1..972985bfad 100644 --- a/test/Shared/TestSampler.cs +++ b/test/Shared/TestSampler.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using OpenTelemetry.Trace; namespace OpenTelemetry.Tests; diff --git a/test/Shared/TestTextMapPropagator.cs b/test/Shared/TestTextMapPropagator.cs index ba58606acf..5ce7fd9bd3 100644 --- a/test/Shared/TestTextMapPropagator.cs +++ b/test/Shared/TestTextMapPropagator.cs @@ -1,8 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#nullable enable - using OpenTelemetry.Context.Propagation; namespace OpenTelemetry.Tests; From cd8f08aa9328badf79273bb7d8874fff79816734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Nov 2024 18:58:06 +0100 Subject: [PATCH 1399/1499] [repo/OWIN] Prepare to .NET9 (#2291) --- .../Implementation/DiagnosticsMiddleware.cs | 27 +++-------- .../DiagnosticsMiddlewareTests.cs | 45 +++++++++---------- 2 files changed, 27 insertions(+), 45 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index cf029720c0..56092245f4 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -77,7 +77,7 @@ private static void BeginRequest(IOwinContext owinContext) var textMapPropagator = Propagators.DefaultTextMapPropagator; var ctx = textMapPropagator.Extract(default, owinContext.Request, OwinRequestHeaderValuesGetter); - Activity? activity = OwinInstrumentationActivitySource.ActivitySource.StartActivity( + var activity = OwinInstrumentationActivitySource.ActivitySource.StartActivity( OwinInstrumentationActivitySource.IncomingRequestActivityName, ActivityKind.Server, ctx.ActivityContext); @@ -103,7 +103,7 @@ private static void BeginRequest(IOwinContext owinContext) activity.SetTag(SemanticConventions.AttributeUrlQuery, request.Query); activity.SetTag(SemanticConventions.AttributeUrlScheme, owinContext.Request.Scheme); - if (request.Headers.TryGetValue("User-Agent", out string[] userAgent) && userAgent.Length > 0) + if (request.Headers.TryGetValue("User-Agent", out var userAgent) && userAgent.Length > 0) { activity.SetTag(SemanticConventions.AttributeUserAgentOriginal, userAgent[0]); } @@ -124,7 +124,7 @@ private static void BeginRequest(IOwinContext owinContext) } } - if (!(textMapPropagator is TraceContextPropagator)) + if (textMapPropagator is not TraceContextPropagator) { Baggage.Current = ctx.Baggage; } @@ -136,7 +136,7 @@ private static void BeginRequest(IOwinContext owinContext) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void RequestEnd(IOwinContext owinContext, Exception? exception, long startTimestamp) { - if (owinContext.Environment.TryGetValue(ContextKey, out object context) + if (owinContext.Environment.TryGetValue(ContextKey, out var context) && context is Activity activity) { if (Activity.Current != activity) @@ -191,7 +191,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l new(SemanticConventions.AttributeHttpResponseStatusCode, owinContext.Response.StatusCode)); } - if (!(Propagators.DefaultTextMapPropagator is TraceContextPropagator)) + if (Propagators.DefaultTextMapPropagator is not TraceContextPropagator) { Baggage.Current = default; } @@ -209,21 +209,4 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l new(SemanticConventions.AttributeHttpResponseStatusCode, owinContext.Response.StatusCode)); } } - - /// - /// Gets the OpenTelemetry standard uri tag value for a span based on its request . - /// - /// . - /// Span uri value. - private static string GetUriTagValueFromRequestUri(Uri uri, bool disableQueryRedaction) - { - if (string.IsNullOrEmpty(uri.UserInfo) && disableQueryRedaction) - { - return uri.OriginalString; - } - - var query = disableQueryRedaction ? uri.Query : RedactionHelper.GetRedactedQueryString(uri.Query); - - return string.Concat(uri.Scheme, Uri.SchemeDelimiter, uri.Authority, uri.AbsolutePath, query, uri.Fragment); - } } diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 445818e461..849b30f0c3 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -24,7 +24,7 @@ public class DiagnosticsMiddlewareTests : IDisposable public DiagnosticsMiddlewareTests() { - Random random = new Random(); + var random = new Random(); var retryCount = 5; do { @@ -60,7 +60,7 @@ public DiagnosticsMiddlewareTests() return next(); }); - HttpConfiguration config = new HttpConfiguration(); + var config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", @@ -120,8 +120,8 @@ public async Task OutgoingRequestInstrumentationTest( bool generateRemoteException = false, bool recordException = false) { - List stoppedActivities = new List(); - List exportedMetrics = new List(); + List stoppedActivities = []; + List exportedMetrics = []; var builder = Sdk.CreateTracerProviderBuilder() .AddInMemoryExporter(stoppedActivities); @@ -135,9 +135,9 @@ public async Task OutgoingRequestInstrumentationTest( { if (enrich) { - if (!enrichmentException) - { - options.Enrich = (activity, eventName, context, exception) => + options.Enrich = enrichmentException + ? (_, _, _, _) => throw new Exception("Error while enriching activity") + : (activity, eventName, _, _) => { switch (eventName) { @@ -147,13 +147,10 @@ public async Task OutgoingRequestInstrumentationTest( case OwinEnrichEventType.EndRequest: activity.SetTag("client.endrequest", nameof(OwinEnrichEventType.EndRequest)); break; + default: + break; } }; - } - else - { - options.Enrich = (activity, eventName, context, exception) => throw new Exception("Error while enriching activity"); - } } options.Filter = _ => !filter; @@ -166,12 +163,12 @@ public async Task OutgoingRequestInstrumentationTest( meterBuilder.AddOwinInstrumentation(); } - using TracerProvider tracerProvider = builder.Build(); - using MeterProvider meterProvider = meterBuilder.Build(); + using var tracerProvider = builder.Build(); + using var meterProvider = meterBuilder.Build(); - using HttpClient client = new HttpClient(); + using var client = new HttpClient(); - Uri requestUri = generateRemoteException + var requestUri = generateRemoteException ? new Uri($"{this.serviceBaseUri}exception") : new Uri($"{this.serviceBaseUri}api/test"); @@ -192,7 +189,7 @@ Owin has finished to inspect the activity status. */ Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; + var activity = stoppedActivities[0]; Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); Assert.Equal(requestUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerAddress).Value); @@ -257,6 +254,8 @@ Owin has finished to inspect the activity status. */ case SemanticConventions.AttributeHttpResponseStatusCode: Assert.Equal(generateRemoteException ? 500 : 200, tag.Value); break; + default: + break; } } } @@ -295,7 +294,7 @@ public async Task QueryParametersAreRedacted( Environment.SetEnvironmentVariable("OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION", "true"); } - List stoppedActivities = new List(); + List stoppedActivities = []; var builder = Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => @@ -316,10 +315,10 @@ public async Task QueryParametersAreRedacted( .AddOwinInstrumentation() .Build(); - using HttpClient client = new HttpClient(); + using var client = new HttpClient(); - Uri requestUri = new Uri($"{this.serviceBaseUri}{actualPath}"); - Uri expectedRequestUri = new Uri($"{this.serviceBaseUri}{expectedPath}"); + var requestUri = new Uri($"{this.serviceBaseUri}{actualPath}"); + var expectedRequestUri = new Uri($"{this.serviceBaseUri}{expectedPath}"); this.requestCompleteHandle.Reset(); @@ -340,7 +339,7 @@ Owin has finished to inspect the activity status. */ Assert.NotEmpty(stoppedActivities); Assert.Single(stoppedActivities); - Activity activity = stoppedActivities[0]; + var activity = stoppedActivities[0]; Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); Assert.Equal(requestUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerAddress).Value); @@ -356,7 +355,7 @@ Owin has finished to inspect the activity status. */ private List GetMetricPoints(Metric metric) { - List metricPoints = new(); + List metricPoints = []; foreach (var metricPoint in metric.GetMetricPoints()) { From a1edda618d56f3c3a5746f84bac13e834b7e0412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Nov 2024 19:10:01 +0100 Subject: [PATCH 1400/1499] [repo/Quartz] Prepare to .NET9 (#2293) --- .../QuartzDiagnosticListener.cs | 7 ++-- .../QuartzDiagnosticListenerTests.cs | 38 +++++++++---------- .../TestJob.cs | 6 +-- .../TestJobExecutionExceptionJob.cs | 2 +- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index bb6e68b523..9f390287d9 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -28,7 +28,7 @@ public QuartzDiagnosticListener(string sourceName, QuartzInstrumentationOptions public override void OnEventWritten(string name, object? payload) { - Activity? activity = Activity.Current; + var activity = Activity.Current; Guard.ThrowIfNull(activity); switch (name) { @@ -44,6 +44,8 @@ public override void OnEventWritten(string name, object? payload) case "Quartz.Job.Veto.Exception": this.OnException(activity, payload); break; + default: + break; } } @@ -127,8 +129,7 @@ private void OnException(Activity activity, object? payload) { if (activity.IsAllDataRequested) { - var exc = payload as Exception; - if (exc == null) + if (payload is not Exception exc) { QuartzInstrumentationEventSource.Log.NullPayload(nameof(QuartzDiagnosticListener), nameof(this.OnStopActivity)); return; diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index b2faa5ea71..09289ecf17 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -21,8 +21,8 @@ public QuartzDiagnosticListenerTests() public async Task Should_Create_Activity() { // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); + var barrier = new Barrier(2); + List jobExecTimestamps = []; var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() @@ -38,7 +38,7 @@ public async Task Should_Create_Activity() scheduler.Context.Put("DATESTAMPS", jobExecTimestamps); await scheduler.Start(); - JobDataMap jobDataMap = new JobDataMap { { "A", "B" } }; + var jobDataMap = new JobDataMap { { "A", "B" } }; var name = Guid.NewGuid().ToString(); var job = JobBuilder.Create() @@ -74,8 +74,8 @@ public async Task Should_Create_Activity() public async Task Should_Create_Activity_And_Enrich_When_Enrich() { // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); + var barrier = new Barrier(2); + List jobExecTimestamps = []; var exportedItems = new List(); @@ -105,7 +105,7 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() await scheduler.Start(); var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + var jobDataMap = new JobDataMap { { "TestId", testId } }; var name = Guid.NewGuid().ToString(); var job = JobBuilder.Create() @@ -141,8 +141,8 @@ public async Task Should_Create_Activity_And_Enrich_When_Enrich() public async Task Should_Record_Exception_When_Record_Exception_Enabled() { // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); + var barrier = new Barrier(2); + List jobExecTimestamps = []; var exportedItems = new List(); @@ -162,7 +162,7 @@ public async Task Should_Record_Exception_When_Record_Exception_Enabled() await scheduler.Start(); var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + var jobDataMap = new JobDataMap { { "TestId", testId } }; var name = Guid.NewGuid().ToString(); var job = JobBuilder.Create() @@ -195,8 +195,8 @@ public async Task Should_Record_Exception_When_Record_Exception_Enabled() public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enrich() { // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); + var barrier = new Barrier(2); + List jobExecTimestamps = []; var exportedItems = new List(); @@ -229,7 +229,7 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri await scheduler.Start(); var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + var jobDataMap = new JobDataMap { { "TestId", testId } }; var name = Guid.NewGuid().ToString(); var job = JobBuilder.Create() @@ -262,8 +262,8 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() { // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); + var barrier = new Barrier(2); + List jobExecTimestamps = []; var exportedItems = new List(); using var tel = Sdk.CreateTracerProviderBuilder() @@ -291,7 +291,7 @@ public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() await scheduler.Start(); var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + var jobDataMap = new JobDataMap { { "TestId", testId } }; var name = Guid.NewGuid().ToString(); var job = JobBuilder.Create() @@ -323,8 +323,8 @@ public async Task Should_Creates_Activity_Event_On_Job_Execution_Exception() public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present() { // Arrange - Barrier barrier = new Barrier(2); - List jobExecTimestamps = new List(); + var barrier = new Barrier(2); + List jobExecTimestamps = []; var exportedItems = new List(); @@ -332,7 +332,7 @@ public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present .SetSampler(new AlwaysOnSampler()) .AddQuartzInstrumentation(q => { - q.TracedOperations = new HashSet(); + q.TracedOperations = []; }) .AddInMemoryExporter(exportedItems) .Build(); @@ -346,7 +346,7 @@ public async Task Should_Not_Record_Activity_When_Trace_Operation_Is_Not_Present await scheduler.Start(); var testId = Guid.NewGuid().ToString(); - JobDataMap jobDataMap = new JobDataMap { { "TestId", testId } }; + var jobDataMap = new JobDataMap { { "TestId", testId } }; var name = Guid.NewGuid().ToString(); var job = JobBuilder.Create() diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs index 7be379f91c..e1fbee1e48 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJob.cs @@ -5,14 +5,14 @@ namespace OpenTelemetry.Instrumentation.Quartz.Tests; -public class TestJob : IJob +internal class TestJob : IJob { public Task Execute(IJobExecutionContext context) { try { - List jobExecTimestamps = (List)context.Scheduler.Context.Get("DATESTAMPS"); - Barrier barrier = (Barrier)context.Scheduler.Context.Get("BARRIER"); + var jobExecTimestamps = (List)context.Scheduler.Context.Get("DATESTAMPS"); + var barrier = (Barrier)context.Scheduler.Context.Get("BARRIER"); jobExecTimestamps.Add(DateTime.UtcNow); diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs index 6ebed283b5..bb81998837 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/TestJobExecutionExceptionJob.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Instrumentation.Quartz.Tests; -public class TestJobExecutionExceptionJob : IJob +internal class TestJobExecutionExceptionJob : IJob { public Task Execute(IJobExecutionContext context) { From d7a8fc21f2bea8d042c60b0a159f06bff0e2d61b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 4 Nov 2024 19:19:17 +0100 Subject: [PATCH 1401/1499] [repo/ElasticsearchClient] Prepare to .NET9 (#2292) --- ...searchRequestPipelineDiagnosticListener.cs | 23 +++++-------- .../Customer.cs | 2 +- .../DependencyInjectionConfigTests.cs | 2 +- .../ElasticsearchClientTests.cs | 32 +++++++++---------- ...nMemoryConnectionWithDownstreamActivity.cs | 6 ++-- 5 files changed, 29 insertions(+), 36 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 0687bd2582..5f57879521 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -57,6 +57,8 @@ public override void OnEventWritten(string name, object? payload) case "CallElasticsearch.Stop": this.OnStopActivity(activity, payload); break; + default: + break; } } @@ -69,12 +71,7 @@ private static string GetDisplayName(Activity activity, object? method, string? case "CallElasticsearch" when method != null: { var methodName = MethodNameCache.GetOrAdd(method, $"Elasticsearch {method}"); - if (elasticType == null) - { - return methodName; - } - - return $"{methodName} {elasticType}"; + return elasticType == null ? methodName : $"{methodName} {elasticType}"; } default: @@ -122,7 +119,7 @@ private string ParseAndFormatRequest(string debugInformation) var request = ParseRequest.Match(debugInformation); if (request.Success) { - string? body = request.Groups[1]?.Value?.Trim(); + var body = request.Groups[1]?.Value?.Trim(); if (body == null) { return debugInformation; @@ -193,7 +190,7 @@ private void OnStartActivity(Activity activity, object? payload) } var uriHostNameType = Uri.CheckHostName(uri.Host); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + if (uriHostNameType is UriHostNameType.IPv4 or UriHostNameType.IPv6) { activity.SetTag(SemanticConventions.AttributeNetPeerIp, uri.Host); } @@ -269,14 +266,10 @@ private void OnStopActivity(Activity activity, object? payload) if (originalException is HttpRequestException) { - if (originalException.InnerException is SocketException exception) + if (originalException.InnerException is SocketException { SocketErrorCode: SocketError.HostNotFound }) { - switch (exception.SocketErrorCode) - { - case SocketError.HostNotFound: - activity.SetStatus(Status.Error.WithDescription(originalException.Message)); - return; - } + activity.SetStatus(Status.Error.WithDescription(originalException.Message)); + return; } if (originalException.InnerException != null) diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs index 2ace4b977c..a0d5bbe566 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/Customer.cs @@ -3,7 +3,7 @@ namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; -public class Customer +internal class Customer { public string? Id { get; set; } diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs index fc2abb01ae..b8a3d14c34 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/DependencyInjectionConfigTests.cs @@ -15,7 +15,7 @@ public class DependencyInjectionConfigTests [InlineData("CustomName")] public async Task TestTracingOptionsDiConfig(string? name) { - bool optionsPickedFromDi = false; + var optionsPickedFromDi = false; var services = new ServiceCollection(); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 2d8cf5a40b..5e23f346c5 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -181,7 +181,7 @@ public async Task CanCaptureSearchCall() [Fact] public async Task CanRecordAndSampleSearchCall() { - bool samplerCalled = false; + var samplerCalled = false; var sampler = new TestSampler { @@ -193,10 +193,10 @@ public async Task CanRecordAndSampleSearchCall() }, }; - using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + using var testActivityProcessor = new TestActivityProcessor(); - int startCalled = 0; - int endCalled = 0; + var startCalled = 0; + var endCalled = 0; testActivityProcessor.StartAction = (a) => @@ -239,9 +239,9 @@ public async Task CanRecordAndSampleSearchCall() } [Fact] - public async Task CanSupressDownstreamActivities() + public async Task CanSuppressDownstreamActivities() { - bool samplerCalled = false; + var samplerCalled = false; var sampler = new TestSampler { @@ -253,10 +253,10 @@ public async Task CanSupressDownstreamActivities() }, }; - using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + using var testActivityProcessor = new TestActivityProcessor(); - int startCalled = 0; - int endCalled = 0; + var startCalled = 0; + var endCalled = 0; testActivityProcessor.StartAction = (a) => @@ -301,7 +301,7 @@ public async Task CanSupressDownstreamActivities() [Fact] public async Task CanDropSearchCall() { - bool samplerCalled = false; + var samplerCalled = false; var sampler = new TestSampler { @@ -313,10 +313,10 @@ public async Task CanDropSearchCall() }, }; - using TestActivityProcessor testActivityProcessor = new TestActivityProcessor(); + using var testActivityProcessor = new TestActivityProcessor(); - int startCalled = 0; - int endCalled = 0; + var startCalled = 0; + var endCalled = 0; testActivityProcessor.StartAction = (a) => @@ -725,8 +725,8 @@ public async Task DoesNotCaptureWhenInstrumentationIsSuppressed() public async Task CapturesBasedOnSamplingDecision(SamplingDecision samplingDecision, bool isActivityExpected) { var expectedResource = ResourceBuilder.CreateDefault().AddService("test-service"); - bool startActivityCalled = false; - bool endActivityCalled = false; + var startActivityCalled = false; + var endActivityCalled = false; var processor = new TestActivityProcessor( activity => startActivityCalled = true, activity => endActivityCalled = true); @@ -851,7 +851,7 @@ public async Task ShouldRemoveSensitiveInformation() Assert.Single(exportedItems); var searchActivity = exportedItems[0]; - string? dbUrl = (string?)searchActivity.GetTagValue(SemanticConventions.AttributeUrlFull); + var dbUrl = (string?)searchActivity.GetTagValue(SemanticConventions.AttributeUrlFull); Assert.DoesNotContain("sensitive", dbUrl); Assert.Contains("REDACTED:REDACTED", dbUrl); diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs index ba9dfa1278..8fdb784976 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/InMemoryConnectionWithDownstreamActivity.cs @@ -6,10 +6,10 @@ namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; -public class InMemoryConnectionWithDownstreamActivity : InMemoryConnection +internal class InMemoryConnectionWithDownstreamActivity : InMemoryConnection { - internal static readonly ActivitySource ActivitySource = new ActivitySource("Downstream"); - internal static readonly ActivitySource NestedActivitySource = new ActivitySource("NestedDownstream"); + internal static readonly ActivitySource ActivitySource = new("Downstream"); + internal static readonly ActivitySource NestedActivitySource = new("NestedDownstream"); public override Task RequestAsync(RequestData requestData, CancellationToken cancellationToken) { From a197116eec74b099ca5c86e421bc552708ff5dda Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 4 Nov 2024 10:45:25 -0800 Subject: [PATCH 1402/1499] [geneva] Updates for 1.10.0-rc.1 (#2294) --- .../CHANGELOG.md | 3 +++ .../Common.GenevaExporter.props | 2 +- .../Internal/ReentrantExportProcessor.cs | 22 +------------------ .../Exporter/TLDTraceExporterBenchmarks.cs | 4 ++-- .../Exporter/TraceExporterBenchmarks.cs | 4 ++-- .../GenevaTraceExporterTests.cs | 20 +++++++++++------ 6 files changed, 22 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 7ca97b842c..317de4751a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -19,6 +19,9 @@ For configuration details see: [OtlpProtobufEncoding](./README.md#otlpprotobufencoding). +* Update OpenTelemetry SDK version to `1.10.0-rc.1`. + ([#2294](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2294)) + ## 1.9.0 Released 2024-Jun-21 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 5570a7a1fe..78181066e1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestVersion) + $(OpenTelemetryCoreLatestPrereleaseVersion) diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs index b0da2159fc..71ac6bbb6e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ReentrantExportProcessor.cs @@ -1,21 +1,11 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Linq.Expressions; -using System.Reflection; - namespace OpenTelemetry.Exporter.Geneva; -// This export processor exports without synchronization. -// Once OpenTelemetry .NET officially support this, -// we can get rid of this class. -// This is currently only used in ETW export, where we know -// that the underlying system is safe under concurrent calls. internal class ReentrantExportProcessor : BaseExportProcessor where T : class { - private static readonly Func> CreateBatch = BuildCreateBatchDelegate(); - public ReentrantExportProcessor(BaseExporter exporter) : base(exporter) { @@ -23,16 +13,6 @@ public ReentrantExportProcessor(BaseExporter exporter) protected override void OnExport(T data) { - this.exporter.Export(CreateBatch(data)); - } - - private static Func> BuildCreateBatchDelegate() - { - var flags = BindingFlags.Instance | BindingFlags.NonPublic; - var ctor = typeof(Batch).GetConstructor(flags, null, new Type[] { typeof(T) }, null) - ?? throw new InvalidOperationException("Batch ctor accepting a single item could not be found reflectively"); - var value = Expression.Parameter(typeof(T), null); - var lambda = Expression.Lambda>>(Expression.New(ctor, value), value); - return lambda.Compile(); + this.exporter.Export(new(data)); } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs index 479026a277..af493c8574 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs @@ -55,7 +55,7 @@ public TLDTraceExporterBenchmarks() this.activity = testActivity!; this.activity.SetTag("tagString", "value"); this.activity.SetTag("tagInt", 100); - this.activity.SetStatus(Status.Error); + this.activity.SetStatus(ActivityStatusCode.Error); } this.msgPackExporter = new MsgPackTraceExporter(new GenevaExporterOptions @@ -128,7 +128,7 @@ private Batch CreateBatch() { activity.SetTag("tagString", "value"); activity.SetTag("tagInt", 100); - activity.SetStatus(Status.Error); + activity.SetStatus(ActivityStatusCode.Error); } return batchGeneratorExporter.Batch; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs index cfec940e3f..2a4d7e01f5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs @@ -54,7 +54,7 @@ public TraceExporterBenchmarks() this.activity = testActivity!; this.activity.SetTag("tagString", "value"); this.activity.SetTag("tagInt", 100); - this.activity.SetStatus(Status.Error); + this.activity.SetStatus(ActivityStatusCode.Error); } activityListener.Dispose(); @@ -129,7 +129,7 @@ private Batch CreateBatch() { activity.SetTag("tagString", "value"); activity.SetTag("tagInt", 100); - activity.SetStatus(Status.Error); + activity.SetStatus(ActivityStatusCode.Error); } return batchGeneratorExporter.Batch; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 6bf12ca320..06e6ee74d0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -175,12 +175,12 @@ public void GenevaTraceExporter_Success_Windows() using (var activity = source.StartActivity("Bar")) { - activity.SetStatus(Status.Error); + activity.SetStatus(ActivityStatusCode.Error); } using (var activity = source.StartActivity("Baz")) { - activity.SetStatus(Status.Ok); + activity.SetStatus(ActivityStatusCode.Ok); } } @@ -298,21 +298,25 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); activity?.SetTag("foo", 1); activity?.SetTag("bar", 2); +#pragma warning disable CS0618 // Type or member is obsolete activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); +#pragma warning restore CS0618 // Type or member is obsolete } } using (var activity = source.StartActivity("TestActivityForSetStatusAPI")) { - activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); + activity?.SetStatus(ActivityStatusCode.Error, description: "Error description from .NET API"); } // If the activity Status is set using both the OTel API and the .NET API, the `Status` and `StatusDescription` set by // the .NET API is chosen using (var activity = source.StartActivity("PreferStatusFromDotnetAPI")) { +#pragma warning disable CS0618 // Type or member is obsolete activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); - activity?.SetStatus(ActivityStatusCode.Error, "Error description from .NET API"); +#pragma warning restore CS0618 // Type or member is obsolete + activity?.SetStatus(ActivityStatusCode.Error, description: "Error description from .NET API"); customChecksForActivity = mapping => { Assert.Equal("Error description from .NET API", mapping["statusMessage"]); @@ -680,17 +684,19 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO Assert.Equal((byte)activity.Kind, mapping["kind"]); Assert.Equal(activity.StartTimeUtc, mapping["startTime"]); - var activityStatusCode = activity.GetStatus().StatusCode; +#pragma warning disable CS0618 // Type or member is obsolete + var otelApiStatusCode = activity.GetStatus(); +#pragma warning restore CS0618 // Type or member is obsolete if (activity.Status == ActivityStatusCode.Error) { Assert.False((bool)mapping["success"]); Assert.Equal(activity.StatusDescription, mapping["statusMessage"]); } - else if (activityStatusCode == StatusCode.Error) + else if (otelApiStatusCode.StatusCode == StatusCode.Error) { Assert.False((bool)mapping["success"]); - var activityStatusDesc = activity.GetStatus().Description; + var activityStatusDesc = otelApiStatusCode.Description; Assert.Equal(activityStatusDesc, mapping["statusMessage"]); } else From 09e3619d9bf4a529da017d012704e7ffa1c69c13 Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Mon, 4 Nov 2024 11:25:09 -0800 Subject: [PATCH 1403/1499] [OneCollector] Bump SDK to 1.10.0-rc.1 (#2295) --- src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ .../OpenTelemetry.Exporter.OneCollector.csproj | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 0803ff2ac5..b4f4b438cc 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -15,6 +15,10 @@ also be applied to subsequent `LogRecord`s in the same batch. ([#2205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2205)) +* Update OpenTelemetry SDK version to `1.10.0-rc.1` and removed the direct + reference to `Microsoft.Extensions.Configuration.Binder`. + ([#2295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2295)) + ## 1.9.3 Released 2024-Oct-11 diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index dfb5f27c1d..c8d10cef7d 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -18,13 +18,12 @@ - $(OpenTelemetryCoreLatestVersion) + $(OpenTelemetryCoreLatestPrereleaseVersion) $(DefineConstants);EXPOSE_EXPERIMENTAL_FEATURES - From cca539cbf78ae4e168b9d1632abc2a188a54bd73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 5 Nov 2024 13:35:00 +0100 Subject: [PATCH 1404/1499] [repo/Hangfire] Prepare to .NET9 (#2296) --- ...ngfireInstrumentationJobFilterAttribute.cs | 2 +- .../HangfireFixture.cs | 2 ++ ...eInstrumentationJobFilterAttributeTests.cs | 22 +++++++++---------- .../ProcessorMock.cs | 2 +- .../TestJob.cs | 2 +- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index f793e52a62..0f0afaaa2a 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -122,7 +122,7 @@ private static void InjectActivityProperties(IDictionary jobPara private static IEnumerable ExtractActivityProperties(Dictionary telemetryData, string key) { - return telemetryData.TryGetValue(key, out var value) ? new[] { value } : Enumerable.Empty(); + return telemetryData.TryGetValue(key, out var value) ? [value] : []; } private void SetStatusAndRecordException(Activity activity, Exception exception) diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs index 614882d572..7157660583 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -7,7 +7,9 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Tests; +#pragma warning disable CA1515 public class HangfireFixture : IDisposable +#pragma warning restore CA1515 { public HangfireFixture() { diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs index 2b301d0f34..37fb369af7 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireInstrumentationJobFilterAttributeTests.cs @@ -34,8 +34,8 @@ public async Task Should_Create_Activity() await this.WaitJobProcessedAsync(jobId, 5); // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Single(exportedItems, i => (i.GetTagItem("job.id") as string) == jobId); + var activity = exportedItems.Single(i => (i.GetTagItem("job.id") as string) == jobId); Assert.Contains("JOB TestJob.Execute", activity.DisplayName); Assert.Equal(ActivityKind.Internal, activity.Kind); } @@ -55,8 +55,8 @@ public async Task Should_Create_Activity_With_Status_Error_When_Job_Failed() await this.WaitJobProcessedAsync(jobId, 5); // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Single(exportedItems, i => (i.GetTagItem("job.id") as string) == jobId); + var activity = exportedItems.Single(i => (i.GetTagItem("job.id") as string) == jobId); Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); Assert.Equal(ActivityKind.Internal, activity.Kind); Assert.Equal(ActivityStatusCode.Error, activity.Status); @@ -79,8 +79,8 @@ public async Task Should_Create_Activity_With_Exception_Event_When_Job_Failed_An await this.WaitJobProcessedAsync(jobId, 5); // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Single(exportedItems, i => (i.GetTagItem("job.id") as string) == jobId); + var activity = exportedItems.Single(i => (i.GetTagItem("job.id") as string) == jobId); Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); Assert.Equal(ActivityKind.Internal, activity.Kind); Assert.Equal(ActivityStatusCode.Error, activity.Status); @@ -103,8 +103,8 @@ public async Task Should_Create_Activity_Without_Exception_Event_When_Job_Failed await this.WaitJobProcessedAsync(jobId, 5); // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Single(exportedItems, i => (i.GetTagItem("job.id") as string) == jobId); + var activity = exportedItems.Single(i => (i.GetTagItem("job.id") as string) == jobId); Assert.Contains("JOB TestJob.ThrowException", activity.DisplayName); Assert.Equal(ActivityKind.Internal, activity.Kind); Assert.Equal(ActivityStatusCode.Error, activity.Status); @@ -128,8 +128,8 @@ public async Task Should_Create_Activity_With_Custom_DisplayName() await this.WaitJobProcessedAsync(jobId, 5); // Assert - Assert.Single(exportedItems, i => i.GetTagItem("job.id") as string == jobId); - var activity = exportedItems.Single(i => i.GetTagItem("job.id") as string == jobId); + Assert.Single(exportedItems, i => (i.GetTagItem("job.id") as string) == jobId); + var activity = exportedItems.Single(i => (i.GetTagItem("job.id") as string) == jobId); Assert.Contains($"JOB {jobId}", activity.DisplayName); Assert.Equal(ActivityKind.Internal, activity.Kind); } @@ -174,7 +174,7 @@ public async Task Should_Respect_Filter_Option(string filter, bool shouldRecord) private async Task WaitJobProcessedAsync(string jobId, int timeToWaitInSeconds) { var timeout = DateTime.Now.AddSeconds(timeToWaitInSeconds); - string[] states = new[] { "Enqueued", "Processing" }; + string[] states = ["Enqueued", "Processing"]; JobDetailsDto jobDetails; while (((jobDetails = this.hangfireFixture.MonitoringApi.JobDetails(jobId)) == null || jobDetails.History.All(h => states.Contains(h.StateName))) && DateTime.Now < timeout) diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs index 81620efad1..e7652b7ff4 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/ProcessorMock.cs @@ -3,7 +3,7 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Tests; -public class ProcessorMock : BaseProcessor +internal class ProcessorMock : BaseProcessor { private readonly Action? onStart; private readonly Action? onEnd; diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs index ae2d973450..795e4e73df 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/TestJob.cs @@ -3,7 +3,7 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Tests; -public class TestJob +internal class TestJob { public void Execute() { From 9e02384c92130fa1f9a918d671f8e301b01ef633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 5 Nov 2024 21:57:20 +0100 Subject: [PATCH 1405/1499] [repo/EventCounters] Prepare to .NET9 (#2301) --- .../EventCountersInstrumentationOptions.cs | 2 +- .../EventCountersMetrics.cs | 8 ++++---- .../EventCountersMetricsTests.cs | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs index 7fdc25d72b..8e4df4cc81 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersInstrumentationOptions.cs @@ -8,7 +8,7 @@ namespace OpenTelemetry.Instrumentation.EventCounters; /// public class EventCountersInstrumentationOptions { - internal readonly HashSet EventSourceNames = new(); + internal readonly HashSet EventSourceNames = []; /// /// Gets or sets the subscription interval in seconds for reading values diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs index 8b42388883..4cb8444f76 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.EventCounters/EventCountersMetrics.cs @@ -18,8 +18,8 @@ internal sealed class EventCountersMetrics : EventListener private const int MaxInstrumentNameLength = 63; private readonly EventCountersInstrumentationOptions options; - private readonly List preInitEventSources = new(); - private readonly List enabledEventSources = new(); + private readonly List preInitEventSources = []; + private readonly List enabledEventSources = []; private readonly ConcurrentDictionary<(string, string), Instrument> instruments = new(); private readonly ConcurrentDictionary<(string, string), double> values = new(); private bool isDisposed; @@ -45,7 +45,7 @@ public EventCountersMetrics(EventCountersInstrumentationOptions options) { this.options = options; - foreach (EventSource eventSource in this.preInitEventSources) + foreach (var eventSource in this.preInitEventSources) { if (this.options.ShouldListenToSource(eventSource.Name)) { @@ -167,7 +167,7 @@ private static Dictionary GetEnableEventsArguments(EventCounters /// private static string GetInstrumentName(string sourceName, string eventName) { - int totalLength = Prefix.Length + 1 + sourceName.Length + 1 + eventName.Length; + var totalLength = Prefix.Length + 1 + sourceName.Length + 1 + eventName.Length; if (totalLength <= MaxInstrumentNameLength) { return string.Concat(Prefix, ".", sourceName, ".", eventName); diff --git a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs index 0b82bc5445..ccd2150a5c 100644 --- a/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.EventCounters.Tests/EventCountersMetricsTests.cs @@ -13,7 +13,7 @@ public class EventCountersMetricsTests public void EventCounter() { // Arrange - List metricItems = new(); + List metricItems = []; using EventSource source = new("a"); using EventCounter counter = new("c", source); @@ -39,7 +39,7 @@ public void EventCounter() public void IncrementingEventCounter() { // Arrange - List metricItems = new(); + List metricItems = []; using EventSource source = new("b"); using IncrementingEventCounter incCounter = new("inc-c", source); @@ -67,8 +67,8 @@ public void IncrementingEventCounter() public void PollingCounter() { // Arrange - int i = 0; - List metricItems = new(); + var i = 0; + List metricItems = []; using EventSource source = new("c"); using PollingCounter pollCounter = new("poll-c", source, () => ++i * 10); @@ -93,8 +93,8 @@ public void PollingCounter() public void IncrementingPollingCounter() { // Arrange - int i = 1; - List metricItems = new(); + var i = 1; + List metricItems = []; using EventSource source = new("d"); using IncrementingPollingCounter incPollCounter = new("inc-poll-c", source, () => i++); @@ -142,7 +142,7 @@ public void ThrowExceptionForUnsupportedEventSources() public void EventSourceNameShortening(string sourceName, string eventName, string expectedInstrumentName) { // Arrange - List metricItems = new(); + List metricItems = []; using EventSource source = new(sourceName); using IncrementingEventCounter connections = new(eventName, source); @@ -167,11 +167,11 @@ public void EventSourceNameShortening(string sourceName, string eventName, strin public async Task InstrumentNameTooLong() { // Arrange - List metricItems = new(); + List metricItems = []; using EventSource source = new("source"); // ec.s. + event name is 63; - string veryLongEventName = new string('e', 100); + var veryLongEventName = new string('e', 100); using IncrementingEventCounter connections = new(veryLongEventName, source); using var meterProvider = Sdk.CreateMeterProviderBuilder() From e7449fb34b616ec950ccad8a00ddb15b2e6d53ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 5 Nov 2024 22:17:18 +0100 Subject: [PATCH 1406/1499] [repo/Http] Prepare to .NET9 (#2298) Co-authored-by: Mikel Blanchard --- .../HttpClientInstrumentation.cs | 27 ++-- .../HttpClientMetrics.cs | 8 +- .../HttpClientTraceInstrumentationOptions.cs | 2 +- .../HttpHandlerDiagnosticListener.cs | 33 ++--- .../HttpHandlerMetricsDiagnosticListener.cs | 32 ++--- .../HttpWebRequestActivitySource.netfx.cs | 136 ++++++++---------- .../Implementation/TelemetryHelper.cs | 18 +-- .../HttpClientInstrumentationBenchmarks.cs | 4 + .../HttpClientTests.Basic.cs | 14 +- .../HttpClientTests.cs | 28 ++-- .../HttpOutTestCase.cs | 2 + .../HttpTestData.cs | 2 +- ...HttpWebRequestActivitySourceTests.netfx.cs | 112 +++++++-------- .../HttpWebRequestTests.Basic.cs | 14 +- .../HttpWebRequestTests.cs | 21 ++- .../RepeatHandler.cs | 4 +- 16 files changed, 198 insertions(+), 259 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs index 40daae9660..4400a15f5b 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientInstrumentation.cs @@ -10,18 +10,18 @@ namespace OpenTelemetry.Instrumentation.Http; /// internal sealed class HttpClientInstrumentation : IDisposable { - private static readonly HashSet ExcludedDiagnosticSourceEventsNet7OrGreater = new() - { + private static readonly HashSet ExcludedDiagnosticSourceEventsNet7OrGreater = + [ "System.Net.Http.Request", "System.Net.Http.Response", - "System.Net.Http.HttpRequestOut", - }; + "System.Net.Http.HttpRequestOut" + ]; - private static readonly HashSet ExcludedDiagnosticSourceEvents = new() - { + private static readonly HashSet ExcludedDiagnosticSourceEvents = + [ "System.Net.Http.Request", - "System.Net.Http.Response", - }; + "System.Net.Http.Response" + ]; private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; @@ -43,14 +43,9 @@ public HttpClientInstrumentation(HttpClientTraceInstrumentationOptions options) // the framework will fall back to creating activity anyways due to active diagnostic source listener // To prevent this, isEnabled is implemented which will return false always // so that the sampler's decision is respected. - if (HttpHandlerDiagnosticListener.IsNet7OrGreater) - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpHandlerDiagnosticListener(options), this.isEnabledNet7OrGreater, HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent); - } - else - { - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(new HttpHandlerDiagnosticListener(options), this.isEnabled, HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent); - } + this.diagnosticSourceSubscriber = HttpHandlerDiagnosticListener.IsNet7OrGreater + ? new DiagnosticSourceSubscriber(new HttpHandlerDiagnosticListener(options), this.isEnabledNet7OrGreater, HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent) + : new DiagnosticSourceSubscriber(new HttpHandlerDiagnosticListener(options), this.isEnabled, HttpInstrumentationEventSource.Log.UnknownErrorProcessingEvent); this.diagnosticSourceSubscriber.Subscribe(); } diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs index e03cd6a46a..8913f8daf7 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientMetrics.cs @@ -10,11 +10,11 @@ namespace OpenTelemetry.Instrumentation.Http; /// internal sealed class HttpClientMetrics : IDisposable { - private static readonly HashSet ExcludedDiagnosticSourceEvents = new() - { + private static readonly HashSet ExcludedDiagnosticSourceEvents = + [ "System.Net.Http.Request", - "System.Net.Http.Response", - }; + "System.Net.Http.Response" + ]; private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; diff --git a/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs index e63f77bae3..cba754cc9f 100644 --- a/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Http/HttpClientTraceInstrumentationOptions.cs @@ -165,7 +165,7 @@ internal bool EventFilterHttpRequestMessage(string activityName, object arg1) { return this.FilterHttpRequestMessage == null || - !TryParseHttpRequestMessage(activityName, arg1, out HttpRequestMessage? requestMessage) || + !TryParseHttpRequestMessage(activityName, arg1, out var requestMessage) || this.FilterHttpRequestMessage(requestMessage); } catch (Exception ex) diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index 14e2ebbec7..5b65c673d0 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -65,6 +65,8 @@ public override void OnEventWritten(string name, object? payload) this.OnException(activity, payload); } + break; + default: break; } } @@ -81,7 +83,7 @@ public void OnStartActivity(Activity activity, object? payload) // By this time, samplers have already run and // activity.IsAllDataRequested populated accordingly. - if (!TryFetchRequest(payload, out HttpRequestMessage? request)) + if (!TryFetchRequest(payload, out var request)) { HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnStartActivity)); return; @@ -109,7 +111,7 @@ public void OnStartActivity(Activity activity, object? payload) { try { - if (this.options.EventFilterHttpRequestMessage(activity.OperationName, request) == false) + if (!this.options.EventFilterHttpRequestMessage(activity.OperationName, request)) { HttpInstrumentationEventSource.Log.RequestIsFilteredOut(activity.OperationName); activity.IsAllDataRequested = false; @@ -161,12 +163,7 @@ public void OnStartActivity(Activity activity, object? payload) #endif static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) { - if (!StartRequestFetcher.TryFetch(payload, out request) || request == null) - { - return false; - } - - return true; + return StartRequestFetcher.TryFetch(payload, out request) && request != null; } } @@ -176,7 +173,7 @@ public void OnStopActivity(Activity activity, object? payload) { var requestTaskStatus = GetRequestStatus(payload); - ActivityStatusCode currentStatusCode = activity.Status; + var currentStatusCode = activity.Status; if (requestTaskStatus != TaskStatus.RanToCompletion) { if (requestTaskStatus == TaskStatus.Canceled) @@ -200,7 +197,7 @@ public void OnStopActivity(Activity activity, object? payload) } } - if (TryFetchResponse(payload, out HttpResponseMessage? response)) + if (TryFetchResponse(payload, out var response)) { if (currentStatusCode == ActivityStatusCode.Unset) { @@ -246,12 +243,7 @@ static TaskStatus GetRequestStatus(object? payload) #endif static bool TryFetchResponse(object? payload, [NotNullWhen(true)] out HttpResponseMessage? response) { - if (StopResponseFetcher.TryFetch(payload, out response) && response != null) - { - return true; - } - - return false; + return StopResponseFetcher.TryFetch(payload, out response) && response != null; } } @@ -259,7 +251,7 @@ public void OnException(Activity activity, object? payload) { if (activity.IsAllDataRequested) { - if (!TryFetchException(payload, out Exception? exc)) + if (!TryFetchException(payload, out var exc)) { HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerDiagnosticListener), nameof(this.OnException)); return; @@ -299,12 +291,7 @@ public void OnException(Activity activity, object? payload) #endif static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) { - if (!StopExceptionFetcher.TryFetch(payload, out exc) || exc == null) - { - return false; - } - - return true; + return StopExceptionFetcher.TryFetch(payload, out exc) && exc != null; } } diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs index 7a841bf654..dd3dc6970c 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs @@ -39,7 +39,7 @@ public HttpHandlerMetricsDiagnosticListener(string name) public static void OnStopEventWritten(Activity activity, object? payload) { - if (TryFetchRequest(payload, out HttpRequestMessage? request)) + if (TryFetchRequest(payload, out var request)) { // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-metrics.md TagList tags = default; @@ -58,7 +58,7 @@ public static void OnStopEventWritten(Activity activity, object? payload) } } - if (TryFetchResponse(payload, out HttpResponseMessage? response)) + if (TryFetchResponse(payload, out var response)) { tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(response.Version))); tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode))); @@ -98,21 +98,25 @@ public static void OnStopEventWritten(Activity activity, object? payload) #if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] #endif - static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) => - StopRequestFetcher.TryFetch(payload, out request) && request != null; + static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) + { + return StopRequestFetcher.TryFetch(payload, out request) && request != null; + } // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. // see https://github.com/dotnet/runtime/blob/f9246538e3d49b90b0e9128d7b1defef57cd6911/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L325 #if NET [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The System.Net.Http library guarantees that top-level properties are preserved")] #endif - static bool TryFetchResponse(object? payload, [NotNullWhen(true)] out HttpResponseMessage? response) => - StopResponseFetcher.TryFetch(payload, out response) && response != null; + static bool TryFetchResponse(object? payload, [NotNullWhen(true)] out HttpResponseMessage? response) + { + return StopResponseFetcher.TryFetch(payload, out response) && response != null; + } } public static void OnExceptionEventWritten(Activity activity, object? payload) { - if (!TryFetchException(payload, out Exception? exc) || !TryFetchRequest(payload, out HttpRequestMessage? request)) + if (!TryFetchException(payload, out var exc) || !TryFetchRequest(payload, out var request)) { HttpInstrumentationEventSource.Log.NullPayload(nameof(HttpHandlerMetricsDiagnosticListener), nameof(OnExceptionEventWritten)); return; @@ -131,12 +135,7 @@ public static void OnExceptionEventWritten(Activity activity, object? payload) #endif static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) { - if (!StopExceptionFetcher.TryFetch(payload, out exc) || exc == null) - { - return false; - } - - return true; + return StopExceptionFetcher.TryFetch(payload, out exc) && exc != null; } // The AOT-annotation DynamicallyAccessedMembers in System.Net.Http library ensures that top-level properties on the payload object are always preserved. @@ -146,12 +145,7 @@ static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception #endif static bool TryFetchRequest(object? payload, [NotNullWhen(true)] out HttpRequestMessage? request) { - if (!RequestFetcher.TryFetch(payload, out request) || request == null) - { - return false; - } - - return true; + return RequestFetcher.TryFetch(payload, out request) && request != null; } } diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index c99639639d..7f8ba01066 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -40,8 +40,6 @@ internal static class HttpWebRequestActivitySource private static readonly Meter WebRequestMeter = new(MeterName, Version); private static readonly Histogram HttpClientRequestDuration = WebRequestMeter.CreateHistogram("http.client.request.duration", "s", "Duration of HTTP client requests."); - private static HttpClientTraceInstrumentationOptions tracingOptions; - // Fields for reflection private static FieldInfo connectionGroupListField; private static Type connectionGroupType; @@ -86,14 +84,7 @@ static HttpWebRequestActivitySource() } } - internal static HttpClientTraceInstrumentationOptions TracingOptions - { - get => tracingOptions; - set - { - tracingOptions = value; - } - } + internal static HttpClientTraceInstrumentationOptions TracingOptions { get; set; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, Activity activity) @@ -108,7 +99,7 @@ private static void AddRequestTagsAndInstrumentRequest(HttpWebRequest request, A activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); - activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri, tracingOptions.DisableUrlQueryRedaction)); + activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri, TracingOptions.DisableUrlQueryRedaction)); try { @@ -232,7 +223,7 @@ private static void ProcessRequest(HttpWebRequest request) return; } - Activity activity = enableTracing + var activity = enableTracing ? WebRequestActivitySource.StartActivity(ActivityName, ActivityKind.Client) : null; @@ -243,12 +234,12 @@ private static void ProcessRequest(HttpWebRequest request) // Eg: Parent could be the Asp.Net activity. InstrumentRequest(request, activityContext); - IAsyncResult asyncContext = writeAResultAccessor(request); + var asyncContext = writeAResultAccessor(request); if (asyncContext != null) { // Flow here is for [Begin]GetRequestStream[Async]. - AsyncCallbackWrapper callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext), Stopwatch.GetTimestamp()); + var callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext), Stopwatch.GetTimestamp()); asyncCallbackModifier(asyncContext, callback.AsyncCallback); } else @@ -256,7 +247,7 @@ private static void ProcessRequest(HttpWebRequest request) // Flow here is for [Begin]GetResponse[Async] without a prior call to [Begin]GetRequestStream[Async]. asyncContext = readAResultAccessor(request); - AsyncCallbackWrapper callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext), Stopwatch.GetTimestamp()); + var callback = new AsyncCallbackWrapper(request, activity, asyncCallbackAccessor(asyncContext), Stopwatch.GetTimestamp()); asyncCallbackModifier(asyncContext, callback.AsyncCallback); } @@ -268,7 +259,7 @@ private static void ProcessRequest(HttpWebRequest request) private static void HookOrProcessResult(HttpWebRequest request) { - IAsyncResult writeAsyncContext = writeAResultAccessor(request); + var writeAsyncContext = writeAResultAccessor(request); if (writeAsyncContext == null || asyncCallbackAccessor(writeAsyncContext)?.Target is not AsyncCallbackWrapper writeAsyncContextCallback) { // If we already hooked into the read result during ProcessRequest or we hooked up after the fact already we don't need to do anything here. @@ -277,7 +268,7 @@ private static void HookOrProcessResult(HttpWebRequest request) // If we got here it means the user called [Begin]GetRequestStream[Async] and we have to hook the read result after the fact. - IAsyncResult readAsyncContext = readAResultAccessor(request); + var readAsyncContext = readAResultAccessor(request); if (readAsyncContext == null) { // We're still trying to establish the connection (no read has started). @@ -295,7 +286,7 @@ private static void HookOrProcessResult(HttpWebRequest request) } // Hook into the result callback if it hasn't already fired. - AsyncCallbackWrapper callback = new AsyncCallbackWrapper(writeAsyncContextCallback.Request, writeAsyncContextCallback.Activity, asyncCallbackAccessor(readAsyncContext), Stopwatch.GetTimestamp()); + var callback = new AsyncCallbackWrapper(writeAsyncContextCallback.Request, writeAsyncContextCallback.Activity, asyncCallbackAccessor(readAsyncContext), Stopwatch.GetTimestamp()); asyncCallbackModifier(readAsyncContext, callback.AsyncCallback); } @@ -304,7 +295,7 @@ private static void ProcessResult(IAsyncResult asyncResult, AsyncCallback asyncC HttpStatusCode? httpStatusCode = null; string errorType = null; Version protocolVersion = null; - ActivityStatusCode activityStatus = ActivityStatusCode.Unset; + var activityStatus = ActivityStatusCode.Unset; // Activity may be null if we are not tracing in these cases: // 1. No listeners @@ -349,7 +340,7 @@ private static void ProcessResult(IAsyncResult asyncResult, AsyncCallback asyncC } else { - HttpWebResponse response = (HttpWebResponse)result; + var response = (HttpWebResponse)result; if (forceResponseCopy || (asyncCallback == null && isContextAwareResultChecker(asyncResult))) { @@ -358,13 +349,12 @@ private static void ProcessResult(IAsyncResult asyncResult, AsyncCallback asyncC // in which case they could dispose the HttpWebResponse before our listeners have a chance to work with it. // Disposed HttpWebResponse throws when accessing properties, so let's make a copy of the data to ensure that doesn't happen. - HttpWebResponse responseCopy = httpWebResponseCtor( - new object[] - { - uriAccessor(response), verbAccessor(response), coreResponseDataAccessor(response), mediaTypeAccessor(response), + var responseCopy = httpWebResponseCtor( + [ + uriAccessor(response), verbAccessor(response), coreResponseDataAccessor(response), mediaTypeAccessor(response), usesProxySemanticsAccessor(response), DecompressionMethods.None, - isWebSocketResponseAccessor(response), connectionGroupNameAccessor(response), - }); + isWebSocketResponseAccessor(response), connectionGroupNameAccessor(response) + ]); if (activity != null) { @@ -458,8 +448,8 @@ private static void PrepareReflectionObjects() { // At any point, if the operation failed, it should just throw. The caller should catch all exceptions and swallow. - Type servicePointType = typeof(ServicePoint); - Assembly systemNetHttpAssembly = servicePointType.Assembly; + var servicePointType = typeof(ServicePoint); + var systemNetHttpAssembly = servicePointType.Assembly; connectionGroupListField = servicePointType.GetField("m_ConnectionGroupList", BindingFlags.Instance | BindingFlags.NonPublic); connectionGroupType = systemNetHttpAssembly?.GetType("System.Net.ConnectionGroup"); connectionListField = connectionGroupType?.GetField("m_ConnectionList", BindingFlags.Instance | BindingFlags.NonPublic); @@ -489,7 +479,7 @@ private static void PrepareReflectionObjects() private static bool PrepareAsyncResultReflectionObjects(Assembly systemNetHttpAssembly) { - Type lazyAsyncResultType = systemNetHttpAssembly?.GetType("System.Net.LazyAsyncResult"); + var lazyAsyncResultType = systemNetHttpAssembly?.GetType("System.Net.LazyAsyncResult"); if (lazyAsyncResultType != null) { asyncCallbackAccessor = CreateFieldGetter(lazyAsyncResultType, "m_AsyncCallback", BindingFlags.NonPublic | BindingFlags.Instance); @@ -500,7 +490,7 @@ private static bool PrepareAsyncResultReflectionObjects(Assembly systemNetHttpAs resultAccessor = CreateFieldGetter(lazyAsyncResultType, "m_Result", BindingFlags.NonPublic | BindingFlags.Instance); } - Type contextAwareResultType = systemNetHttpAssembly?.GetType("System.Net.ContextAwareResult"); + var contextAwareResultType = systemNetHttpAssembly?.GetType("System.Net.ContextAwareResult"); if (contextAwareResultType != null) { isContextAwareResultChecker = CreateTypeChecker(contextAwareResultType); @@ -517,8 +507,8 @@ private static bool PrepareAsyncResultReflectionObjects(Assembly systemNetHttpAs private static bool PrepareHttpWebResponseReflectionObjects(Assembly systemNetHttpAssembly) { - Type knownHttpVerbType = systemNetHttpAssembly?.GetType("System.Net.KnownHttpVerb"); - Type coreResponseData = systemNetHttpAssembly?.GetType("System.Net.CoreResponseData"); + var knownHttpVerbType = systemNetHttpAssembly?.GetType("System.Net.KnownHttpVerb"); + var coreResponseData = systemNetHttpAssembly?.GetType("System.Net.CoreResponseData"); if (knownHttpVerbType != null && coreResponseData != null) { @@ -529,7 +519,7 @@ private static bool PrepareHttpWebResponseReflectionObjects(Assembly systemNetHt typeof(bool), typeof(string), }; - ConstructorInfo ctor = typeof(HttpWebResponse).GetConstructor( + var ctor = typeof(HttpWebResponse).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, constructorParameterTypes, @@ -563,11 +553,11 @@ private static bool PrepareHttpWebResponseReflectionObjects(Assembly systemNetHt private static void PerformInjection() { - FieldInfo servicePointTableField = typeof(ServicePointManager).GetField("s_ServicePointTable", BindingFlags.Static | BindingFlags.NonPublic) - ?? throw new InvalidOperationException("Unable to access the ServicePointTable field"); + var servicePointTableField = typeof(ServicePointManager).GetField("s_ServicePointTable", BindingFlags.Static | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("Unable to access the ServicePointTable field"); - Hashtable originalTable = servicePointTableField.GetValue(null) as Hashtable; - ServicePointHashtable newTable = new ServicePointHashtable(originalTable ?? new Hashtable()); + var originalTable = servicePointTableField.GetValue(null) as Hashtable; + var newTable = new ServicePointHashtable(originalTable ?? []); foreach (DictionaryEntry existingServicePoint in originalTable) { @@ -586,8 +576,8 @@ private static void HookServicePoint(object value) // Replace the ConnectionGroup hashtable inside this ServicePoint object, // which allows us to intercept each new ConnectionGroup object added under // this ServicePoint. - Hashtable originalTable = connectionGroupListField.GetValue(servicePoint) as Hashtable; - ConnectionGroupHashtable newTable = new ConnectionGroupHashtable(originalTable ?? new Hashtable()); + var originalTable = connectionGroupListField.GetValue(servicePoint) as Hashtable; + var newTable = new ConnectionGroupHashtable(originalTable ?? []); foreach (DictionaryEntry existingConnectionGroup in originalTable) { @@ -605,10 +595,10 @@ private static void HookConnectionGroup(object value) // Replace the Connection arraylist inside this ConnectionGroup object, // which allows us to intercept each new Connection object added under // this ConnectionGroup. - ArrayList originalArrayList = connectionListField.GetValue(value) as ArrayList; - ConnectionArrayList newArrayList = new ConnectionArrayList(originalArrayList ?? new ArrayList()); + var originalArrayList = connectionListField.GetValue(value) as ArrayList; + var newArrayList = new ConnectionArrayList(originalArrayList ?? []); - foreach (object connection in originalArrayList) + foreach (var connection in originalArrayList) { HookConnection(connection); } @@ -624,8 +614,8 @@ private static void HookConnection(object value) // Replace the HttpWebRequest arraylist inside this Connection object, // which allows us to intercept each new HttpWebRequest object added under // this Connection. - ArrayList originalArrayList = writeListField.GetValue(value) as ArrayList; - HttpWebRequestArrayList newArrayList = new HttpWebRequestArrayList(originalArrayList ?? new ArrayList()); + var originalArrayList = writeListField.GetValue(value) as ArrayList; + var newArrayList = new HttpWebRequestArrayList(originalArrayList ?? []); writeListField.SetValue(value, newArrayList); } @@ -634,12 +624,12 @@ private static void HookConnection(object value) private static Func CreateFieldGetter(string fieldName, BindingFlags flags) where TClass : class { - FieldInfo field = typeof(TClass).GetField(fieldName, flags); + var field = typeof(TClass).GetField(fieldName, flags); if (field != null) { - string methodName = field.ReflectedType.FullName + ".get_" + field.Name; - DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(TClass) }, true); - ILGenerator generator = getterMethod.GetILGenerator(); + var methodName = field.ReflectedType.FullName + ".get_" + field.Name; + var getterMethod = new DynamicMethod(methodName, typeof(TField), [typeof(TClass)], true); + var generator = getterMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, field); generator.Emit(OpCodes.Ret); @@ -655,12 +645,12 @@ private static Func CreateFieldGetter(string fie /// private static Func CreateFieldGetter(Type classType, string fieldName, BindingFlags flags) { - FieldInfo field = classType.GetField(fieldName, flags); + var field = classType.GetField(fieldName, flags); if (field != null) { - string methodName = classType.FullName + ".get_" + field.Name; - DynamicMethod getterMethod = new DynamicMethod(methodName, typeof(TField), new[] { typeof(object) }, true); - ILGenerator generator = getterMethod.GetILGenerator(); + var methodName = classType.FullName + ".get_" + field.Name; + var getterMethod = new DynamicMethod(methodName, typeof(TField), [typeof(object)], true); + var generator = getterMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Castclass, classType); generator.Emit(OpCodes.Ldfld, field); @@ -678,12 +668,12 @@ private static Func CreateFieldGetter(Type classType, st /// private static Action CreateFieldSetter(Type classType, string fieldName, BindingFlags flags) { - FieldInfo field = classType.GetField(fieldName, flags); + var field = classType.GetField(fieldName, flags); if (field != null) { - string methodName = classType.FullName + ".set_" + field.Name; - DynamicMethod setterMethod = new DynamicMethod(methodName, null, new[] { typeof(object), typeof(TField) }, true); - ILGenerator generator = setterMethod.GetILGenerator(); + var methodName = classType.FullName + ".set_" + field.Name; + var setterMethod = new DynamicMethod(methodName, null, [typeof(object), typeof(TField)], true); + var generator = setterMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Castclass, classType); generator.Emit(OpCodes.Ldarg_1); @@ -701,9 +691,9 @@ private static Action CreateFieldSetter(Type classType, /// private static Func CreateTypeChecker(Type classType) { - string methodName = classType.FullName + ".typeCheck"; - DynamicMethod setterMethod = new DynamicMethod(methodName, typeof(bool), new[] { typeof(object) }, true); - ILGenerator generator = setterMethod.GetILGenerator(); + var methodName = classType.FullName + ".typeCheck"; + var setterMethod = new DynamicMethod(methodName, typeof(bool), [typeof(object)], true); + var generator = setterMethod.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Isinst, classType); generator.Emit(OpCodes.Ldnull); @@ -718,13 +708,13 @@ private static Func CreateTypeChecker(Type classType) /// private static Func CreateTypeInstance(ConstructorInfo constructorInfo) { - Type classType = typeof(T); - string methodName = classType.FullName + ".ctor"; - DynamicMethod setterMethod = new DynamicMethod(methodName, classType, new Type[] { typeof(object[]) }, true); - ILGenerator generator = setterMethod.GetILGenerator(); + var classType = typeof(T); + var methodName = classType.FullName + ".ctor"; + var setterMethod = new DynamicMethod(methodName, classType, [typeof(object[])], true); + var generator = setterMethod.GetILGenerator(); - ParameterInfo[] ctorParams = constructorInfo.GetParameters(); - for (int i = 0; i < ctorParams.Length; i++) + var ctorParams = constructorInfo.GetParameters(); + for (var i = 0; i < ctorParams.Length; i++) { generator.Emit(OpCodes.Ldarg_0); switch (i) @@ -742,7 +732,7 @@ private static Func CreateTypeInstance(ConstructorInfo construct } generator.Emit(OpCodes.Ldelem_Ref); - Type paramType = ctorParams[i].ParameterType; + var paramType = ctorParams[i].ParameterType; generator.Emit(paramType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, paramType); } @@ -1083,7 +1073,7 @@ public override void TrimToSize() public ArrayList Swap() { - ArrayList old = this.list; + var old = this.list; this.list = new ArrayList(old.Capacity); return old; } @@ -1125,7 +1115,7 @@ public HttpWebRequestArrayList(ArrayList list) public override int Add(object value) { // Add before firing events so if some user code cancels/aborts the request it will be found in the outstanding list. - int index = base.Add(value); + var index = base.Add(value); if (value is HttpWebRequest request) { @@ -1137,7 +1127,7 @@ public override int Add(object value) public override void RemoveAt(int index) { - object request = this[index]; + var request = this[index]; base.RemoveAt(index); @@ -1149,8 +1139,8 @@ public override void RemoveAt(int index) public override void Clear() { - ArrayList oldList = this.Swap(); - for (int i = 0; i < oldList.Count; i++) + var oldList = this.Swap(); + for (var i = 0; i < oldList.Count; i++) { if (oldList[i] is HttpWebRequest request) { @@ -1183,8 +1173,8 @@ public AsyncCallbackWrapper(HttpWebRequest request, Activity activity, AsyncCall public void AsyncCallback(IAsyncResult asyncResult) { - object result = resultAccessor(asyncResult); - if (result is Exception || result is HttpWebResponse) + var result = resultAccessor(asyncResult); + if (result is Exception or HttpWebResponse) { ProcessResult( asyncResult, diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs index 49bd111f4e..4a5a4e84f4 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/TelemetryHelper.cs @@ -12,24 +12,14 @@ internal static class TelemetryHelper public static object GetBoxedStatusCode(HttpStatusCode statusCode) { - int intStatusCode = (int)statusCode; - if (intStatusCode >= 100 && intStatusCode < 600) - { - return BoxedStatusCodes[intStatusCode - 100].Item1; - } - - return statusCode; + var intStatusCode = (int)statusCode; + return intStatusCode is >= 100 and < 600 ? BoxedStatusCodes[intStatusCode - 100].Item1 : statusCode; } public static string GetStatusCodeString(HttpStatusCode statusCode) { - int intStatusCode = (int)statusCode; - if (intStatusCode >= 100 && intStatusCode < 600) - { - return BoxedStatusCodes[intStatusCode - 100].Item2; - } - - return statusCode.ToString(); + var intStatusCode = (int)statusCode; + return intStatusCode is >= 100 and < 600 ? BoxedStatusCodes[intStatusCode - 100].Item2 : statusCode.ToString(); } private static (object, string)[] InitializeBoxedStatusCodes() diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs index 5664716337..1905acb938 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs @@ -26,7 +26,9 @@ namespace OpenTelemetry.Instrumentation.Http.Benchmarks.Instrumentation; +#pragma warning disable CA1515 public class HttpClientInstrumentationBenchmarks +#pragma warning restore CA1515 { private static readonly Uri Url = new("http://localhost:5000"); @@ -36,7 +38,9 @@ public class HttpClientInstrumentationBenchmarks private MeterProvider? meterProvider; [Flags] +#pragma warning disable CA1515 public enum EnableInstrumentationOption +#pragma warning restore CA1515 { /// /// Instrumentation is not enabled for any signal. diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index 05bc602e81..0ee5a4b4c7 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -38,11 +38,7 @@ public HttpClientTests(ITestOutputHelper output) var custom_traceparent = ctx.Request.Headers["custom_traceparent"]; var contextRequired = ctx.Request.Headers["contextRequired"]; var responseCode = ctx.Request.Headers["responseCode"]; - if ((contextRequired == null - || bool.Parse(contextRequired)) - && - (string.IsNullOrWhiteSpace(traceparent) - && string.IsNullOrWhiteSpace(custom_traceparent))) + if ((contextRequired == null || bool.Parse(contextRequired)) && string.IsNullOrWhiteSpace(traceparent) && string.IsNullOrWhiteSpace(custom_traceparent)) { ctx.Response.StatusCode = 500; ctx.Response.StatusDescription = "Missing trace context"; @@ -189,8 +185,8 @@ public async Task InjectsHeadersAsync(bool shouldEnrich) #if NETFRAMEWORK if (shouldEnrich) { - Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpWebRequest").FirstOrDefault().Value); - Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpWebResponse").FirstOrDefault().Value); + Assert.Equal("yes", activity.Tags.FirstOrDefault(tag => tag.Key == "enrichedWithHttpWebRequest").Value); + Assert.Equal("yes", activity.Tags.FirstOrDefault(tag => tag.Key == "enrichedWithHttpWebResponse").Value); } else { @@ -206,8 +202,8 @@ public async Task InjectsHeadersAsync(bool shouldEnrich) if (shouldEnrich) { - Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpRequestMessage").FirstOrDefault().Value); - Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enrichedWithHttpResponseMessage").FirstOrDefault().Value); + Assert.Equal("yes", activity.Tags.FirstOrDefault(tag => tag.Key == "enrichedWithHttpRequestMessage").Value); + Assert.Equal("yes", activity.Tags.FirstOrDefault(tag => tag.Key == "enrichedWithHttpResponseMessage").Value); } else { diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index 83e594179b..fd01551bf3 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -151,13 +151,7 @@ public async Task ValidateNet8MetricsAsync(HttpOutTestCase tc) } var requestMetrics = metrics - .Where(metric => - metric.Name == "http.client.request.duration" || - metric.Name == "http.client.active_requests" || - metric.Name == "http.client.request.time_in_queue" || - metric.Name == "http.client.connection.duration" || - metric.Name == "http.client.open_connections" || - metric.Name == "dns.lookup.duration") + .Where(metric => metric.Name is "http.client.request.duration" or "http.client.active_requests" or "http.client.request.time_in_queue" or "http.client.connection.duration" or "http.client.open_connections" or "dns.lookup.duration") .ToArray(); if (tc.ResponseExpected) @@ -221,11 +215,11 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( bool enableTracing, bool enableMetrics) { - bool enrichWithHttpWebRequestCalled = false; - bool enrichWithHttpWebResponseCalled = false; - bool enrichWithHttpRequestMessageCalled = false; - bool enrichWithHttpResponseMessageCalled = false; - bool enrichWithExceptionCalled = false; + var enrichWithHttpWebRequestCalled = false; + var enrichWithHttpWebResponseCalled = false; + var enrichWithHttpRequestMessageCalled = false; + var enrichWithHttpResponseMessageCalled = false; + var enrichWithExceptionCalled = false; var testUrl = HttpTestData.NormalizeValues(tc.Url, host, port); @@ -337,7 +331,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( var normalizedAttributes = activity.TagObjects.Where(kv => !kv.Key.StartsWith("otel.", StringComparison.Ordinal)).ToDictionary(x => x.Key, x => x.Value?.ToString()); - int numberOfTags = activity.Status == ActivityStatusCode.Error ? 5 : 4; + var numberOfTags = activity.Status == ActivityStatusCode.Error ? 5 : 4; var expectedAttributeCount = numberOfTags + (tc.ResponseExpected ? 2 : 0); @@ -495,11 +489,11 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( private static async Task CheckEnrichment(Sampler sampler, bool enrichExpected, string url) { - bool enrichWithHttpWebRequestCalled = false; - bool enrichWithHttpWebResponseCalled = false; + var enrichWithHttpWebRequestCalled = false; + var enrichWithHttpWebResponseCalled = false; - bool enrichWithHttpRequestMessageCalled = false; - bool enrichWithHttpResponseMessageCalled = false; + var enrichWithHttpRequestMessageCalled = false; + var enrichWithHttpResponseMessageCalled = false; using (Sdk.CreateTracerProviderBuilder() .SetSampler(sampler) diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs index dd632eb9e5..43cdefd887 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs @@ -3,7 +3,9 @@ namespace OpenTelemetry.Instrumentation.Http.Tests; +#pragma warning disable CA1515 public class HttpOutTestCase +#pragma warning restore CA1515 { public HttpOutTestCase(string name, string method, string url, Dictionary? headers, int responseCode, string spanName, bool responseExpected, bool? recordException, string spanStatus, Dictionary spanAttributes) { diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs index 7f91eaaf0c..e139b23237 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpTestData.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests; -public static class HttpTestData +internal static class HttpTestData { private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs index ebcb77d0b0..9c035f97fa 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestActivitySourceTests.netfx.cs @@ -54,7 +54,7 @@ public HttpWebRequestActivitySourceTests() Activity.ForceDefaultIdFormat = false; this.testServer = TestHttpServer.RunServer( - ctx => ProcessServerRequest(ctx), + ProcessServerRequest, out this.testServerHost, out this.testServerPort); @@ -63,8 +63,8 @@ public HttpWebRequestActivitySourceTests() void ProcessServerRequest(HttpListenerContext context) { - string redirects = context.Request.QueryString["redirects"]; - if (!string.IsNullOrWhiteSpace(redirects) && int.TryParse(redirects, out int parsedRedirects) && parsedRedirects > 0) + var redirects = context.Request.QueryString["redirects"]; + if (!string.IsNullOrWhiteSpace(redirects) && int.TryParse(redirects, out var parsedRedirects) && parsedRedirects > 0) { context.Response.Redirect(this.BuildRequestUrl(queryString: $"redirects={--parsedRedirects}")); context.Response.OutputStream.Close(); @@ -74,7 +74,7 @@ void ProcessServerRequest(HttpListenerContext context) string responseContent; if (context.Request.QueryString["skipRequestContent"] == null) { - using StreamReader readStream = new StreamReader(context.Request.InputStream); + using var readStream = new StreamReader(context.Request.InputStream); responseContent = readStream.ReadToEnd(); } @@ -83,19 +83,12 @@ void ProcessServerRequest(HttpListenerContext context) responseContent = $"{{\"Id\":\"{Guid.NewGuid()}\"}}"; } - string responseCode = context.Request.QueryString["responseCode"]; - if (!string.IsNullOrWhiteSpace(responseCode)) - { - context.Response.StatusCode = int.Parse(responseCode); - } - else - { - context.Response.StatusCode = 200; - } + var responseCode = context.Request.QueryString["responseCode"]; + context.Response.StatusCode = !string.IsNullOrWhiteSpace(responseCode) ? int.Parse(responseCode) : 200; if (context.Response.StatusCode != 204) { - using StreamWriter writeStream = new StreamWriter(context.Response.OutputStream); + using var writeStream = new StreamWriter(context.Response.OutputStream); writeStream.Write(responseContent); } @@ -117,8 +110,8 @@ public void Dispose() [Fact] public void TestHttpDiagnosticListenerIsRegistered() { - bool listenerFound = false; - using ActivityListener activityListener = new ActivityListener + var listenerFound = false; + using var activityListener = new ActivityListener { ShouldListenTo = activitySource => { @@ -182,7 +175,7 @@ public async Task TestBasicReceiveAndResponseEvents(string method, string queryS Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); // Check to make sure: The first record must be a request, the next record must be a response. - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); @@ -222,7 +215,7 @@ public async Task TestBasicReceiveAndResponseEventsWithoutSampling(string method [InlineData("POST", 3)] public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int mode) { - string url = this.BuildRequestUrl(); + var url = this.BuildRequestUrl(); using var eventRecords = new ActivitySourceRecorder(); @@ -244,9 +237,9 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int break; case 2: { - object state = new object(); - using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); - IAsyncResult asyncResult = webRequest.BeginGetRequestStream( + var state = new object(); + using var handle = new EventWaitHandle(false, EventResetMode.ManualReset); + var asyncResult = webRequest.BeginGetRequestStream( ar => { Assert.Equal(state, ar.AsyncState); @@ -265,8 +258,8 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int break; case 3: { - using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); - object state = new object(); + using var handle = new EventWaitHandle(false, EventResetMode.ManualReset); + var state = new object(); webRequest.BeginGetRequestStream( ar => { @@ -290,7 +283,7 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int Assert.NotNull(stream); - using StreamWriter writer = new StreamWriter(stream); + using var writer = new StreamWriter(stream); writer.WriteLine("hello world"); } @@ -306,9 +299,9 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int break; case 2: { - object state = new object(); - using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); - IAsyncResult asyncResult = webRequest.BeginGetResponse( + var state = new object(); + using var handle = new EventWaitHandle(false, EventResetMode.ManualReset); + var asyncResult = webRequest.BeginGetResponse( ar => { Assert.Equal(state, ar.AsyncState); @@ -327,8 +320,8 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int break; case 3: { - using EventWaitHandle handle = new EventWaitHandle(false, EventResetMode.ManualReset); - object state = new object(); + using var handle = new EventWaitHandle(false, EventResetMode.ManualReset); + var state = new object(); webRequest.BeginGetResponse( ar => { @@ -352,7 +345,7 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int Assert.NotNull(webResponse); - using StreamReader reader = new StreamReader(webResponse.GetResponseStream()); + using var reader = new StreamReader(webResponse.GetResponseStream()); reader.ReadToEnd(); // Make sure response is not disposed. @@ -362,7 +355,7 @@ public async Task TestBasicReceiveAndResponseWebRequestEvents(string method, int Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); // Check to make sure: The first record must be a request, the next record must be a response. - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); @@ -450,14 +443,14 @@ public async Task DoNotInjectTraceParentWhenPresent(string method) [InlineData("POST")] public async Task TestResponseWithoutContentEvents(string method) { - string url = this.BuildRequestUrl(queryString: "responseCode=204"); + var url = this.BuildRequestUrl(queryString: "responseCode=204"); using var eventRecords = new ActivitySourceRecorder(); // Send a random Http request to generate some events using (var client = new HttpClient()) { - using HttpResponseMessage response = method == "GET" + using var response = method == "GET" ? await client.GetAsync(new Uri(url)) : await client.PostAsync(new Uri(url), new StringContent("hello world")); } @@ -468,7 +461,7 @@ public async Task TestResponseWithoutContentEvents(string method) Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); // Check to make sure: The first record must be a request, the next record must be a response. - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); @@ -490,7 +483,7 @@ public async Task TestRedirectedRequest(string method) using (var client = new HttpClient()) { - using HttpResponseMessage response = method == "GET" + using var response = method == "GET" ? await client.GetAsync(new Uri(this.BuildRequestUrl(queryString: "redirects=10"))) : await client.PostAsync(new Uri(this.BuildRequestUrl(queryString: "redirects=10")), new StringContent("hello world")); } @@ -509,8 +502,8 @@ public async Task TestRedirectedRequest(string method) [InlineData("POST")] public async Task TestRequestWithException(string method) { - string host = Guid.NewGuid().ToString() + ".com"; - string url = method == "GET" + var host = Guid.NewGuid().ToString() + ".com"; + var url = method == "GET" ? $"http://{host}" : $"http://{host}"; @@ -534,10 +527,10 @@ public async Task TestRequestWithException(string method) Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); // Check to make sure: The first record must be a request, the next record must be an exception. - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags(host, null, method, url, activity); - Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.True(eventRecords.Records.TryDequeue(out var exceptionEvent)); Assert.Equal("Stop", exceptionEvent.Key); Assert.NotEqual(ActivityStatusCode.Unset, activity.Status); @@ -552,9 +545,9 @@ public async Task TestRequestWithException(string method) [InlineData("POST")] public async Task TestCanceledRequest(string method) { - string url = this.BuildRequestUrl(); + var url = this.BuildRequestUrl(); - CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); using var eventRecords = new ActivitySourceRecorder(_ => { cts.Cancel(); }); using (var client = new HttpClient()) @@ -565,7 +558,7 @@ public async Task TestCanceledRequest(string method) ? client.GetAsync(new Uri(url), cts.Token) : client.PostAsync(new Uri(url), new StringContent("hello world"), cts.Token); }); - Assert.True(ex is TaskCanceledException || ex is WebException); + Assert.True(ex is TaskCanceledException or WebException); } // We should have one Start event and one Stop event with an exception. @@ -573,10 +566,10 @@ public async Task TestCanceledRequest(string method) Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); - Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.True(eventRecords.Records.TryDequeue(out var exceptionEvent)); Assert.Equal("Stop", exceptionEvent.Key); Assert.NotEqual(ActivityStatusCode.Unset, exceptionEvent.Value.Status); @@ -591,7 +584,7 @@ public async Task TestCanceledRequest(string method) [InlineData("POST")] public async Task TestSecureTransportFailureRequest(string method) { - string url = "https://expired.badssl.com/"; + var url = "https://expired.badssl.com/"; using var eventRecords = new ActivitySourceRecorder(); @@ -612,10 +605,10 @@ public async Task TestSecureTransportFailureRequest(string method) Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags("expired.badssl.com", null, method, url, activity); - Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.True(eventRecords.Records.TryDequeue(out var exceptionEvent)); Assert.Equal("Stop", exceptionEvent.Key); Assert.NotEqual(ActivityStatusCode.Unset, exceptionEvent.Value.Status); @@ -634,7 +627,7 @@ public async Task TestSecureTransportRetryFailureRequest(string method) // It should retry. What we want to test for is 1 start, 1 exception event even // though multiple are actually sent. - string url = this.BuildRequestUrl(useHttps: true); + var url = this.BuildRequestUrl(useHttps: true); using var eventRecords = new ActivitySourceRecorder(); @@ -654,10 +647,10 @@ public async Task TestSecureTransportRetryFailureRequest(string method) Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start")); Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop")); - Activity activity = AssertFirstEventWasStart(eventRecords); + var activity = AssertFirstEventWasStart(eventRecords); VerifyActivityStartTags(this.netPeerName, this.netPeerPort, method, url, activity); - Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair exceptionEvent)); + Assert.True(eventRecords.Records.TryDequeue(out var exceptionEvent)); Assert.Equal("Stop", exceptionEvent.Key); Assert.NotEqual(ActivityStatusCode.Unset, exceptionEvent.Value.Status); @@ -697,19 +690,19 @@ public async Task TestMultipleConcurrentRequests() using var parentActivity = new Activity("parent").Start(); using var eventRecords = new ActivitySourceRecorder(); - Dictionary> requestData = new Dictionary>(); - for (int i = 0; i < 10; i++) + Dictionary> requestData = []; + for (var i = 0; i < 10; i++) { - Uri uriWithRedirect = new Uri(this.BuildRequestUrl(queryString: $"q={i}&redirects=3")); + var uriWithRedirect = new Uri(this.BuildRequestUrl(queryString: $"q={i}&redirects=3")); requestData[uriWithRedirect] = null; } // Issue all requests simultaneously using var httpClient = new HttpClient(); - Dictionary> tasks = new Dictionary>(); + Dictionary> tasks = []; - CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); foreach (var url in requestData.Keys) { tasks.Add(url, httpClient.GetAsync(url, cts.Token)); @@ -736,18 +729,17 @@ await Task.WhenAll(tasks.Select(t => t.Value).ToArray()).ContinueWith(async _ => // Check to make sure: We have a WebRequest and a WebResponse for each successful request foreach (var pair in eventRecords.Records) { - Activity activity = pair.Value; + var activity = pair.Value; Assert.True( - pair.Key == "Start" || - pair.Key == "Stop", + pair.Key is "Start" or "Stop", "An unexpected event of name " + pair.Key + "was received"); } } private static Activity AssertFirstEventWasStart(ActivitySourceRecorder eventRecords) { - Assert.True(eventRecords.Records.TryDequeue(out KeyValuePair startEvent)); + Assert.True(eventRecords.Records.TryDequeue(out var startEvent)); Assert.Equal("Start", startEvent.Key); return startEvent.Value; } @@ -786,7 +778,7 @@ private static void VerifyActivityStopTags(int statusCode, Activity activity) private static void ValidateBaggage(HttpWebRequest request) { - string[] baggage = request.Headers["baggage"].Split(','); + var baggage = request.Headers["baggage"].Split(','); Assert.Equal(3, baggage.Length); Assert.Contains("key=value", baggage); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs index a314e456db..cdc717d00b 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs @@ -87,8 +87,8 @@ public async Task BacksOffIfAlreadyInstrumented() [Fact] public async Task RequestNotCollectedWhenInstrumentationFilterApplied() { - bool httpWebRequestFilterApplied = false; - bool httpRequestMessageFilterApplied = false; + var httpWebRequestFilterApplied = false; + var httpRequestMessageFilterApplied = false; var exportedItems = new List(); @@ -186,8 +186,8 @@ public async Task InjectsHeadersAsync() Assert.NotEqual(default, activity.Context.SpanId); #if NETFRAMEWORK - string traceparent = request.Headers.Get("traceparent"); - string tracestate = request.Headers.Get("tracestate"); + var traceparent = request.Headers.Get("traceparent"); + var tracestate = request.Headers.Get("tracestate"); Assert.Equal($"00-{activity.Context.TraceId}-{activity.Context.SpanId}-01", traceparent); Assert.Equal("k1=v1,k2=v2", tracestate); @@ -285,7 +285,7 @@ public void AddHttpClientInstrumentationUsesOptionsApi(string? name) { name ??= Options.DefaultName; - int configurationDelegateInvocations = 0; + var configurationDelegateInvocations = 0; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => @@ -305,7 +305,7 @@ public void AddHttpClientInstrumentationUsesOptionsApi(string? name) public async Task ReportsExceptionEventForNetworkFailures() { var exportedItems = new List(); - bool exceptionThrown = false; + var exceptionThrown = false; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation(o => o.RecordException = true) @@ -334,7 +334,7 @@ public async Task ReportsExceptionEventForNetworkFailures() public async Task ReportsExceptionEventOnErrorResponse() { var exportedItems = new List(); - bool exceptionThrown = false; + var exceptionThrown = false; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddHttpClientInstrumentation(o => o.RecordException = true) diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs index 24ebf2e3fe..9e01f266c4 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs @@ -34,11 +34,11 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) out var host, out var port); - bool enrichWithHttpWebRequestCalled = false; - bool enrichWithHttpWebResponseCalled = false; - bool enrichWithHttpRequestMessageCalled = false; - bool enrichWithHttpResponseMessageCalled = false; - bool enrichWithExceptionCalled = false; + var enrichWithHttpWebRequestCalled = false; + var enrichWithHttpWebResponseCalled = false; + var enrichWithHttpRequestMessageCalled = false; + var enrichWithHttpResponseMessageCalled = false; + var enrichWithExceptionCalled = false; var exportedItems = new List(); using var tracerProvider = Sdk.CreateTracerProviderBuilder() @@ -92,19 +92,14 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) x => x.Key, x => { - if (x.Key == "network.protocol.version") - { - return "1.1"; - } - - return HttpTestData.NormalizeValues(x.Value, host, port); + return x.Key == "network.protocol.version" ? "1.1" : HttpTestData.NormalizeValues(x.Value, host, port); }); - foreach (KeyValuePair tag in activity.TagObjects) + foreach (var tag in activity.TagObjects) { var tagValue = tag.Value?.ToString(); - if (!tc.SpanAttributes.TryGetValue(tag.Key, out string? value)) + if (!tc.SpanAttributes.TryGetValue(tag.Key, out var value)) { if (tag.Key == SpanAttributeConstants.StatusCodeKey) { diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs index 43a56ae26f..40143c2e6d 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/RepeatHandler.cs @@ -7,7 +7,7 @@ namespace OpenTelemetry.Tests; -public class RepeatHandler : DelegatingHandler +internal class RepeatHandler : DelegatingHandler { private readonly int maxRetries; @@ -22,7 +22,7 @@ protected override async Task SendAsync( CancellationToken cancellationToken) { HttpResponseMessage? response = null; - for (int i = 0; i < this.maxRetries; i++) + for (var i = 0; i < this.maxRetries; i++) { response?.Dispose(); From 4301c9497887509c6fd996e4560d2ac7172de249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 5 Nov 2024 22:28:46 +0100 Subject: [PATCH 1407/1499] [repo/SqlClient] Prepare to .NET9 (#2297) --- .../SqlClientDiagnosticListener.cs | 8 +++-- .../Implementation/SqlConnectionDetails.cs | 18 +++++----- .../SqlEventSourceListener.netfx.cs | 8 ++--- .../SqlClientInstrumentation.cs | 8 ++--- .../SqlClientIntegrationTests.cs | 19 +++++------ .../SqlClientIntegrationTestsFixture.cs | 10 +++--- .../SqlClientTestCase.cs | 2 ++ .../SqlClientTests.cs | 28 +++++++-------- .../SqlEventSourceTests.netfx.cs | 34 +++++++++---------- .../EnabledOnDockerPlatformTheoryAttribute.cs | 33 ++++++++++++------ 10 files changed, 89 insertions(+), 79 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 36c3ac89ba..027a6dc749 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -98,7 +98,7 @@ public override void OnEventWritten(string name, object? payload) _ = this.commandTextFetcher.TryFetch(command, out var commandText); - if (this.commandTypeFetcher.TryFetch(command, out CommandType commandType)) + if (this.commandTypeFetcher.TryFetch(command, out var commandType)) { switch (commandType) { @@ -135,6 +135,8 @@ public override void OnEventWritten(string name, object? payload) case CommandType.TableDirect: break; + default: + break; } } @@ -186,7 +188,7 @@ public override void OnEventWritten(string name, object? payload) { if (activity.IsAllDataRequested) { - if (this.exceptionFetcher.TryFetch(payload, out Exception? exception) && exception != null) + if (this.exceptionFetcher.TryFetch(payload, out var exception) && exception != null) { activity.AddTag(SemanticConventions.AttributeErrorType, exception.GetType().FullName); @@ -214,6 +216,8 @@ public override void OnEventWritten(string name, object? payload) } } + break; + default: break; } } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlConnectionDetails.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlConnectionDetails.cs index 2e5c595335..78110fd1cd 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlConnectionDetails.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlConnectionDetails.cs @@ -55,32 +55,32 @@ private SqlConnectionDetails() public static SqlConnectionDetails ParseFromDataSource(string dataSource) { - if (ConnectionDetailCache.TryGetValue(dataSource, out SqlConnectionDetails? connectionDetails)) + if (ConnectionDetailCache.TryGetValue(dataSource, out var connectionDetails)) { return connectionDetails; } var match = DataSourceRegex.Match(dataSource); - string? serverHostName = match.Groups[2].Value; + var serverHostName = match.Groups[2].Value; string? serverIpAddress = null; string? instanceName = null; int? port = null; var uriHostNameType = Uri.CheckHostName(serverHostName); - if (uriHostNameType == UriHostNameType.IPv4 || uriHostNameType == UriHostNameType.IPv6) + if (uriHostNameType is UriHostNameType.IPv4 or UriHostNameType.IPv6) { serverIpAddress = serverHostName; serverHostName = null; } - string maybeProtocol = match.Groups[1].Value; - bool isNamedPipe = maybeProtocol.Length > 0 && - maybeProtocol.StartsWith("np", StringComparison.OrdinalIgnoreCase); + var maybeProtocol = match.Groups[1].Value; + var isNamedPipe = maybeProtocol.Length > 0 && + maybeProtocol.StartsWith("np", StringComparison.OrdinalIgnoreCase); if (isNamedPipe) { - string pipeName = match.Groups[3].Value; + var pipeName = match.Groups[3].Value; if (pipeName.Length > 0) { var namedInstancePipeMatch = NamedPipeRegex.Match(pipeName); @@ -95,11 +95,11 @@ public static SqlConnectionDetails ParseFromDataSource(string dataSource) if (match.Groups[4].Length > 0) { instanceName = match.Groups[3].Value; - port = int.TryParse(match.Groups[4].Value, out int parsedPort) + port = int.TryParse(match.Groups[4].Value, out var parsedPort) ? parsedPort == 1433 ? null : parsedPort : null; } - else if (int.TryParse(match.Groups[3].Value, out int parsedPort)) + else if (int.TryParse(match.Groups[3].Value, out var parsedPort)) { instanceName = null; port = parsedPort == 1433 ? null : parsedPort; diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index 371cae85a3..45f1800db2 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -112,8 +112,8 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) return; } - string dataSource = (string)eventData.Payload[1]; - string databaseName = (string)eventData.Payload[2]; + var dataSource = (string)eventData.Payload[1]; + var databaseName = (string)eventData.Payload[2]; var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, this.options, out var activityName); var activity = SqlActivitySourceHelper.ActivitySource.StartActivity( activityName, @@ -129,7 +129,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) if (activity.IsAllDataRequested) { - string commandText = (string)eventData.Payload[3]; + var commandText = (string)eventData.Payload[3]; if (!string.IsNullOrEmpty(commandText) && this.options.SetDbStatementForText) { if (this.options.EmitOldAttributes) @@ -170,7 +170,7 @@ private void OnEndExecute(EventWrittenEventArgs eventData) { if (activity.IsAllDataRequested) { - int compositeState = (int)eventData.Payload[1]; + var compositeState = (int)eventData.Payload[1]; if ((compositeState & 0b001) != 0b001) { if ((compositeState & 0b010) == 0b010) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs index 301f5a7891..c1b3ea6988 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs @@ -20,15 +20,15 @@ internal sealed class SqlClientInstrumentation : IDisposable #if NETFRAMEWORK private readonly SqlEventSourceListener sqlEventSourceListener; #else - private static readonly HashSet DiagnosticSourceEvents = new() - { + private static readonly HashSet DiagnosticSourceEvents = + [ "System.Data.SqlClient.WriteCommandBefore", "Microsoft.Data.SqlClient.WriteCommandBefore", "System.Data.SqlClient.WriteCommandAfter", "Microsoft.Data.SqlClient.WriteCommandAfter", "System.Data.SqlClient.WriteCommandError", - "Microsoft.Data.SqlClient.WriteCommandError", - }; + "Microsoft.Data.SqlClient.WriteCommandError" + ]; private readonly Func isEnabled = (eventName, _, _) => DiagnosticSourceEvents.Contains(eventName); diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs index cc70a4d8ee..6c13ba7171 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -59,15 +59,15 @@ public void SuccessfulCommandTest( }) .Build(); - using SqlConnection sqlConnection = new SqlConnection(this.GetConnectionString()); + using var sqlConnection = new SqlConnection(this.GetConnectionString()); sqlConnection.Open(); - string dataSource = sqlConnection.DataSource; + var dataSource = sqlConnection.DataSource; sqlConnection.ChangeDatabase("master"); #pragma warning disable CA2100 - using SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection) + using var sqlCommand = new SqlCommand(commandText, sqlConnection) #pragma warning restore CA2100 { CommandType = commandType, @@ -107,14 +107,11 @@ public void SuccessfulCommandTest( private string GetConnectionString() { - switch (this.fixture.DatabaseContainer) + return this.fixture.DatabaseContainer switch { - case SqlEdgeContainer container: - return container.GetConnectionString(); - case MsSqlContainer container: - return container.GetConnectionString(); - default: - throw new InvalidOperationException($"Container type '${this.fixture.DatabaseContainer.GetType().Name}' is not supported."); - } + SqlEdgeContainer container => container.GetConnectionString(), + MsSqlContainer container => container.GetConnectionString(), + _ => throw new InvalidOperationException($"Container type '${this.fixture.DatabaseContainer.GetType().Name}' is not supported."), + }; } } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs index 28e39184bf..549afff40b 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs @@ -9,21 +9,21 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Tests; +#pragma warning disable CA1515 public sealed class SqlClientIntegrationTestsFixture : IAsyncLifetime +#pragma warning restore CA1515 { // The Microsoft SQL Server Docker image is not compatible with ARM devices, such as Macs with Apple Silicon. - private readonly IContainer databaseContainer = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? CreateSqlEdge() : CreateMsSql(); - - public IContainer DatabaseContainer => this.databaseContainer; + public IContainer DatabaseContainer { get; } = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? CreateSqlEdge() : CreateMsSql(); public Task InitializeAsync() { - return this.databaseContainer.StartAsync(); + return this.DatabaseContainer.StartAsync(); } public Task DisposeAsync() { - return this.databaseContainer.DisposeAsync().AsTask(); + return this.DatabaseContainer.DisposeAsync().AsTask(); } private static SqlEdgeContainer CreateSqlEdge() diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs index f2b7e07e2b..62ba66c37c 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs @@ -5,7 +5,9 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Tests; +#pragma warning disable CA1515 public class SqlClientTestCase : IEnumerable +#pragma warning restore CA1515 { public string ConnectionString { get; set; } = string.Empty; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 9e68bb1624..5a5bc8d89c 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -44,8 +44,8 @@ public void SqlClient_BadArgs() [Fact] public void SqlClient_NamedOptions() { - int defaultExporterOptionsConfigureOptionsInvocations = 0; - int namedExporterOptionsConfigureOptionsInvocations = 0; + var defaultExporterOptionsConfigureOptionsInvocations = 0; + var namedExporterOptionsConfigureOptionsInvocations = 0; using var tracerProvider = Sdk.CreateTracerProviderBuilder() .ConfigureServices(services => @@ -310,12 +310,7 @@ public void ShouldCollectTelemetryWhenFilterEvaluatesToTrue() }, cmd => { - if (cmd is SqlCommand command) - { - return command.CommandText == "select 2"; - } - - return true; + return cmd is not SqlCommand command || command.CommandText == "select 2"; }); Assert.Single(activities); @@ -333,12 +328,7 @@ public void ShouldNotCollectTelemetryWhenFilterEvaluatesToFalse() }, cmd => { - if (cmd is SqlCommand command) - { - return command.CommandText == "select 2"; - } - - return true; + return cmd is not SqlCommand command || command.CommandText == "select 2"; }); Assert.Empty(activities); @@ -406,7 +396,7 @@ internal static void VerifyActivityData( if (shouldEnrich) { Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enriched")); - Assert.Equal("yes", activity.Tags.Where(tag => tag.Key == "enriched").FirstOrDefault().Value); + Assert.Equal("yes", activity.Tags.FirstOrDefault(tag => tag.Key == "enriched").Value); } else { @@ -461,6 +451,12 @@ internal static void VerifyActivityData( Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbQueryText)); } + break; + case CommandType.TableDirect: + Assert.Fail("Not supported command type: CommandType.TableDirect"); + break; + default: + Assert.Fail($"Not supported command type: {commandType}"); break; } } @@ -614,7 +610,7 @@ private Activity[] RunCommandWithFilter( afterExecuteEventData); } - return activities.ToArray(); + return [.. activities]; } #endif diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index 2280e5502f..d91951692a 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -45,16 +45,16 @@ public async Task SuccessfulCommandTest(CommandType commandType, string commandT .Build(); Assert.NotNull(SqlConnectionString); - using SqlConnection sqlConnection = new SqlConnection(SqlConnectionString); + using var sqlConnection = new SqlConnection(SqlConnectionString); await sqlConnection.OpenAsync(); - string dataSource = sqlConnection.DataSource; + var dataSource = sqlConnection.DataSource; sqlConnection.ChangeDatabase("master"); #pragma warning disable CA2100 - using SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection) + using var sqlCommand = new SqlCommand(commandText, sqlConnection) #pragma warning restore CA2100 { CommandType = commandType, @@ -114,7 +114,7 @@ public void EventSourceFakeTests( bool emitOldAttributes = true, bool emitNewAttributes = false) { - using IFakeBehavingSqlEventSource fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + using var fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() @@ -128,21 +128,21 @@ public void EventSourceFakeTests( }) .Build(); - int objectId = Guid.NewGuid().GetHashCode(); + var objectId = Guid.NewGuid().GetHashCode(); var dataSource = "127.0.0.1\\instanceName,port"; fakeSqlEventSource.WriteBeginExecuteEvent(objectId, dataSource, "master", commandType == CommandType.StoredProcedure ? commandText : string.Empty); // success is stored in the first bit in compositeState 0b001 - int successFlag = !isFailure ? 1 : 0; + var successFlag = !isFailure ? 1 : 0; // isSqlException is stored in the second bit in compositeState 0b010 - int isSqlExceptionFlag = sqlExceptionNumber > 0 ? 2 : 0; + var isSqlExceptionFlag = sqlExceptionNumber > 0 ? 2 : 0; // synchronous state is stored in the third bit in compositeState 0b100 - int synchronousFlag = false ? 4 : 0; + var synchronousFlag = false ? 4 : 0; - int compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; + var compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; fakeSqlEventSource.WriteEndExecuteEvent(objectId, compositeState, sqlExceptionNumber); shutdownSignal.Dispose(); @@ -158,7 +158,7 @@ public void EventSourceFakeTests( [InlineData(typeof(FakeMisbehavingMdsSqlEventSource))] public void EventSourceFakeUnknownEventWithNullPayloadTest(Type eventSourceType) { - using IFakeMisbehavingSqlEventSource fakeSqlEventSource = (IFakeMisbehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + using var fakeSqlEventSource = (IFakeMisbehavingSqlEventSource)Activator.CreateInstance(eventSourceType); var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() @@ -178,7 +178,7 @@ public void EventSourceFakeUnknownEventWithNullPayloadTest(Type eventSourceType) [InlineData(typeof(FakeMisbehavingMdsSqlEventSource))] public void EventSourceFakeInvalidPayloadTest(Type eventSourceType) { - using IFakeMisbehavingSqlEventSource fakeSqlEventSource = (IFakeMisbehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + using var fakeSqlEventSource = (IFakeMisbehavingSqlEventSource)Activator.CreateInstance(eventSourceType); var exportedItems = new List(); using var shutdownSignal = Sdk.CreateTracerProviderBuilder() @@ -199,7 +199,7 @@ public void EventSourceFakeInvalidPayloadTest(Type eventSourceType) [InlineData(typeof(FakeBehavingMdsSqlEventSource))] public void DefaultCaptureTextFalse(Type eventSourceType) { - using IFakeBehavingSqlEventSource fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); + using var fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); var exportedItems = new List(); var shutdownSignal = Sdk.CreateTracerProviderBuilder() @@ -207,21 +207,21 @@ public void DefaultCaptureTextFalse(Type eventSourceType) .AddSqlClientInstrumentation() .Build(); - int objectId = Guid.NewGuid().GetHashCode(); + var objectId = Guid.NewGuid().GetHashCode(); const string commandText = "TestCommandTest"; fakeSqlEventSource.WriteBeginExecuteEvent(objectId, "127.0.0.1", "master", commandText); // success is stored in the first bit in compositeState 0b001 - int successFlag = 1; + var successFlag = 1; // isSqlException is stored in the second bit in compositeState 0b010 - int isSqlExceptionFlag = 2; + var isSqlExceptionFlag = 2; // synchronous state is stored in the third bit in compositeState 0b100 - int synchronousFlag = 4; + var synchronousFlag = 4; - int compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; + var compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; fakeSqlEventSource.WriteEndExecuteEvent(objectId, compositeState, 0); shutdownSignal.Dispose(); diff --git a/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs b/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs index 215de236f9..bb4738d5c1 100644 --- a/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs +++ b/test/Shared/EnabledOnDockerPlatformTheoryAttribute.cs @@ -22,18 +22,29 @@ public EnabledOnDockerPlatformTheoryAttribute(DockerPlatform dockerPlatform) var stdout = new StringBuilder(); var stderr = new StringBuilder(); - void AppendStdout(object sender, DataReceivedEventArgs e) => stdout.Append(e.Data); - void AppendStderr(object sender, DataReceivedEventArgs e) => stderr.Append(e.Data); + void AppendStdout(object sender, DataReceivedEventArgs e) + { + stdout.Append(e.Data); + } - var processStartInfo = new ProcessStartInfo(); - processStartInfo.FileName = executable; - processStartInfo.Arguments = string.Join(" ", "version", "--format '{{.Server.Os}}'"); - processStartInfo.RedirectStandardOutput = true; - processStartInfo.RedirectStandardError = true; - processStartInfo.UseShellExecute = false; + void AppendStderr(object sender, DataReceivedEventArgs e) + { + stderr.Append(e.Data); + } - var process = new Process(); - process.StartInfo = processStartInfo; + var processStartInfo = new ProcessStartInfo + { + FileName = executable, + Arguments = string.Join(" ", "version", "--format '{{.Server.Os}}'"), + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + }; + + var process = new Process + { + StartInfo = processStartInfo, + }; process.OutputDataReceived += AppendStdout; process.ErrorDataReceived += AppendStderr; @@ -58,7 +69,7 @@ public EnabledOnDockerPlatformTheoryAttribute(DockerPlatform dockerPlatform) this.Skip = $"The Docker {dockerPlatform} engine is not available."; } - public enum DockerPlatform + internal enum DockerPlatform { /// /// Docker Linux engine. From 4d7161b1d99e2419ed0c005dc0f7aa0f78d46138 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:40:59 -0800 Subject: [PATCH 1408/1499] [sqlclient] Make SqlClientInstrumentation a singleton (#2305) Co-authored-by: Mikel Blanchard --- .../SqlClientDiagnosticListener.cs | 28 ++++++------ .../SqlEventSourceListener.netfx.cs | 26 ++++++----- .../SqlClientInstrumentation.cs | 43 +++++++++++++++---- .../TracerProviderBuilderExtensions.cs | 5 +-- 4 files changed, 69 insertions(+), 33 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 027a6dc749..f10fb831ec 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -34,18 +34,22 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler private readonly PropertyFetcher commandTextFetcher = new("CommandText"); private readonly PropertyFetcher exceptionFetcher = new("Exception"); private readonly PropertyFetcher exceptionNumberFetcher = new("Number"); - private readonly SqlClientTraceInstrumentationOptions options; - public SqlClientDiagnosticListener(string sourceName, SqlClientTraceInstrumentationOptions? options) + public SqlClientDiagnosticListener(string sourceName) : base(sourceName) { - this.options = options ?? new SqlClientTraceInstrumentationOptions(); } public override bool SupportsNullActivity => true; public override void OnEventWritten(string name, object? payload) { + if (SqlClientInstrumentation.TracingHandles == 0) + { + return; + } + + var options = SqlClientInstrumentation.TracingOptions; var activity = Activity.Current; switch (name) { @@ -63,7 +67,7 @@ public override void OnEventWritten(string name, object? payload) _ = this.databaseFetcher.TryFetch(connection, out var databaseName); _ = this.dataSourceFetcher.TryFetch(connection, out var dataSource); - var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, this.options, out var activityName); + var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, options, out var activityName); activity = SqlActivitySourceHelper.ActivitySource.StartActivity( activityName, ActivityKind.Client, @@ -80,7 +84,7 @@ public override void OnEventWritten(string name, object? payload) { try { - if (this.options.Filter?.Invoke(command) == false) + if (options.Filter?.Invoke(command) == false) { SqlClientInstrumentationEventSource.Log.CommandIsFilteredOut(activity.OperationName); activity.IsAllDataRequested = false; @@ -103,12 +107,12 @@ public override void OnEventWritten(string name, object? payload) switch (commandType) { case CommandType.StoredProcedure: - if (this.options.EmitOldAttributes) + if (options.EmitOldAttributes) { activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); } - if (this.options.EmitNewAttributes) + if (options.EmitNewAttributes) { activity.SetTag(SemanticConventions.AttributeDbOperationName, "EXECUTE"); activity.SetTag(SemanticConventions.AttributeDbCollectionName, commandText); @@ -118,14 +122,14 @@ public override void OnEventWritten(string name, object? payload) break; case CommandType.Text: - if (this.options.SetDbStatementForText) + if (options.SetDbStatementForText) { - if (this.options.EmitOldAttributes) + if (options.EmitOldAttributes) { activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); } - if (this.options.EmitNewAttributes) + if (options.EmitNewAttributes) { activity.SetTag(SemanticConventions.AttributeDbQueryText, commandText); } @@ -142,7 +146,7 @@ public override void OnEventWritten(string name, object? payload) try { - this.options.Enrich?.Invoke(activity, "OnCustom", command); + options.Enrich?.Invoke(activity, "OnCustom", command); } catch (Exception ex) { @@ -199,7 +203,7 @@ public override void OnEventWritten(string name, object? payload) activity.SetStatus(ActivityStatusCode.Error, exception.Message); - if (this.options.RecordException) + if (options.RecordException) { activity.RecordException(exception); } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index 45f1800db2..329aa8e184 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -29,15 +29,9 @@ internal sealed class SqlEventSourceListener : EventListener internal const int BeginExecuteEventId = 1; internal const int EndExecuteEventId = 2; - private readonly SqlClientTraceInstrumentationOptions options; private EventSource? adoNetEventSource; private EventSource? mdsEventSource; - public SqlEventSourceListener(SqlClientTraceInstrumentationOptions? options = null) - { - this.options = options ?? new SqlClientTraceInstrumentationOptions(); - } - public override void Dispose() { if (this.adoNetEventSource != null) @@ -106,6 +100,13 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) (https://github.com/dotnet/SqlClient/blob/f4568ce68da21db3fe88c0e72e1287368aaa1dc8/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs#L6641) */ + if (SqlClientInstrumentation.TracingHandles == 0) + { + return; + } + + var options = SqlClientInstrumentation.TracingOptions; + if (eventData.Payload.Count < 4) { SqlClientInstrumentationEventSource.Log.InvalidPayload(nameof(SqlEventSourceListener), nameof(this.OnBeginExecute)); @@ -114,7 +115,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) var dataSource = (string)eventData.Payload[1]; var databaseName = (string)eventData.Payload[2]; - var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, this.options, out var activityName); + var startTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo(dataSource, databaseName, options, out var activityName); var activity = SqlActivitySourceHelper.ActivitySource.StartActivity( activityName, ActivityKind.Client, @@ -130,14 +131,14 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) if (activity.IsAllDataRequested) { var commandText = (string)eventData.Payload[3]; - if (!string.IsNullOrEmpty(commandText) && this.options.SetDbStatementForText) + if (!string.IsNullOrEmpty(commandText) && options.SetDbStatementForText) { - if (this.options.EmitOldAttributes) + if (options.EmitOldAttributes) { activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); } - if (this.options.EmitNewAttributes) + if (options.EmitNewAttributes) { activity.SetTag(SemanticConventions.AttributeDbQueryText, commandText); } @@ -154,6 +155,11 @@ private void OnEndExecute(EventWrittenEventArgs eventData) [2] -> SqlExceptionNumber */ + if (SqlClientInstrumentation.TracingHandles == 0) + { + return; + } + if (eventData.Payload.Count < 3) { SqlClientInstrumentationEventSource.Log.InvalidPayload(nameof(SqlEventSourceListener), nameof(this.OnEndExecute)); diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs index c1b3ea6988..be77ab5796 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs @@ -11,12 +11,18 @@ namespace OpenTelemetry.Instrumentation.SqlClient; /// /// SqlClient instrumentation. /// +#if NET +[RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] +#endif internal sealed class SqlClientInstrumentation : IDisposable { + public static readonly SqlClientInstrumentation Instance = new SqlClientInstrumentation(); + internal const string SqlClientDiagnosticListenerName = "SqlClientDiagnosticListener"; #if NET internal const string SqlClientTrimmingUnsupportedMessage = "Trimming is not yet supported with SqlClient instrumentation."; #endif + internal static int TracingHandles; #if NETFRAMEWORK private readonly SqlEventSourceListener sqlEventSourceListener; #else @@ -39,18 +45,13 @@ internal sealed class SqlClientInstrumentation : IDisposable /// /// Initializes a new instance of the class. /// - /// Configuration options for sql instrumentation. -#if NET - [RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] -#endif - public SqlClientInstrumentation( - SqlClientTraceInstrumentationOptions? options = null) + private SqlClientInstrumentation() { #if NETFRAMEWORK - this.sqlEventSourceListener = new SqlEventSourceListener(options); + this.sqlEventSourceListener = new SqlEventSourceListener(); #else this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber( - name => new SqlClientDiagnosticListener(name, options), + name => new SqlClientDiagnosticListener(name), listener => listener.Name == SqlClientDiagnosticListenerName, this.isEnabled, SqlClientInstrumentationEventSource.Log.UnknownErrorProcessingEvent); @@ -58,6 +59,10 @@ public SqlClientInstrumentation( #endif } + public static SqlClientTraceInstrumentationOptions TracingOptions { get; set; } = new SqlClientTraceInstrumentationOptions(); + + public static IDisposable AddTracingHandle() => new TracingHandle(); + /// public void Dispose() { @@ -67,4 +72,26 @@ public void Dispose() this.diagnosticSourceSubscriber?.Dispose(); #endif } + +#if NET + [RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] +#endif + private sealed class TracingHandle : IDisposable + { + private bool disposed; + + public TracingHandle() + { + Interlocked.Increment(ref TracingHandles); + } + + public void Dispose() + { + if (!this.disposed) + { + Interlocked.Decrement(ref TracingHandles); + this.disposed = true; + } + } + } } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs index 2959484eb3..e7145081d2 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/TracerProviderBuilderExtensions.cs @@ -52,7 +52,6 @@ public static TracerProviderBuilder AddSqlClientInstrumentation( #if NET [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] #endif - public static TracerProviderBuilder AddSqlClientInstrumentation( this TracerProviderBuilder builder, string? name, @@ -70,8 +69,8 @@ public static TracerProviderBuilder AddSqlClientInstrumentation( builder.AddInstrumentation(sp => { var sqlOptions = sp.GetRequiredService>().Get(name); - - return new SqlClientInstrumentation(sqlOptions); + SqlClientInstrumentation.TracingOptions = sqlOptions; + return SqlClientInstrumentation.AddTracingHandle(); }); builder.AddSource(SqlActivitySourceHelper.ActivitySourceName); From 01532d429d0d356e84eb9ba49c48e027609c63be Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:20:10 -0500 Subject: [PATCH 1409/1499] [Instrumentation.SqlClient] Implements database metric `db.client.operation.duration` (#2309) --- .../.publicApi/PublicAPI.Unshipped.txt | 2 + .../Implementation/SqlActivitySourceHelper.cs | 9 + .../SqlClientDiagnosticListener.cs | 101 +++++++- .../SqlClientInstrumentation.cs | 25 ++ ...SqlClientMeterProviderBuilderExtensions.cs | 39 +++ .../SqlClientTests.cs | 243 ++++++++++++------ .../SqlTestData.cs | 69 +++++ 7 files changed, 408 insertions(+), 80 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.SqlClient/SqlClientMeterProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt index 7a79bbb9f4..2d3a76d224 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt @@ -11,7 +11,9 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Rec OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.get -> bool OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SetDbStatementForText.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.SqlClientTraceInstrumentationOptions() -> void +OpenTelemetry.Metrics.SqlClientMeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions +static OpenTelemetry.Metrics.SqlClientMeterProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configureSqlClientTraceInstrumentationOptions) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index b20a2d5174..d2e362fa63 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; +using System.Diagnostics.Metrics; using System.Reflection; using OpenTelemetry.Internal; using OpenTelemetry.Trace; @@ -21,6 +22,14 @@ internal sealed class SqlActivitySourceHelper public static readonly string ActivitySourceName = AssemblyName.Name!; public static readonly ActivitySource ActivitySource = new(ActivitySourceName, Assembly.GetPackageVersion()); + public static readonly string MeterName = AssemblyName.Name!; + public static readonly Meter Meter = new(MeterName, Assembly.GetPackageVersion()); + + public static readonly Histogram DbClientOperationDuration = Meter.CreateHistogram( + "db.client.operation.duration", + "s", + "Duration of database client operations."); + public static TagList GetTagListFromConnectionInfo(string? dataSource, string? databaseName, SqlClientTraceInstrumentationOptions options, out string activityName) { activityName = MicrosoftSqlServerDatabaseSystemName; diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index f10fb831ec..c5d234550e 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -26,6 +26,18 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler public const string SqlDataWriteCommandError = "System.Data.SqlClient.WriteCommandError"; public const string SqlMicrosoftWriteCommandError = "Microsoft.Data.SqlClient.WriteCommandError"; + private static readonly string[] SharedTagNames = + [ + SemanticConventions.AttributeDbSystem, + SemanticConventions.AttributeDbCollectionName, + SemanticConventions.AttributeDbNamespace, + SemanticConventions.AttributeDbResponseStatusCode, + SemanticConventions.AttributeDbOperationName, + SemanticConventions.AttributeErrorType, + SemanticConventions.AttributeServerPort, + SemanticConventions.AttributeServerAddress, + ]; + private readonly PropertyFetcher commandFetcher = new("Command"); private readonly PropertyFetcher connectionFetcher = new("Connection"); private readonly PropertyFetcher dataSourceFetcher = new("DataSource"); @@ -34,6 +46,7 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler private readonly PropertyFetcher commandTextFetcher = new("CommandText"); private readonly PropertyFetcher exceptionFetcher = new("Exception"); private readonly PropertyFetcher exceptionNumberFetcher = new("Number"); + private readonly AsyncLocal beginTimestamp = new(); public SqlClientDiagnosticListener(string sourceName) : base(sourceName) @@ -44,7 +57,7 @@ public SqlClientDiagnosticListener(string sourceName) public override void OnEventWritten(string name, object? payload) { - if (SqlClientInstrumentation.TracingHandles == 0) + if (SqlClientInstrumentation.TracingHandles == 0 && SqlClientInstrumentation.MetricHandles == 0) { return; } @@ -77,6 +90,7 @@ public override void OnEventWritten(string name, object? payload) if (activity == null) { // There is no listener or it decided not to sample the current request. + this.beginTimestamp.Value = Stopwatch.GetTimestamp(); return; } @@ -162,15 +176,18 @@ public override void OnEventWritten(string name, object? payload) if (activity == null) { SqlClientInstrumentationEventSource.Log.NullActivity(name); + this.RecordDuration(null, payload); return; } if (activity.Source != SqlActivitySourceHelper.ActivitySource) { + this.RecordDuration(null, payload); return; } activity.Stop(); + this.RecordDuration(activity, payload); } break; @@ -180,11 +197,13 @@ public override void OnEventWritten(string name, object? payload) if (activity == null) { SqlClientInstrumentationEventSource.Log.NullActivity(name); + this.RecordDuration(null, payload); return; } if (activity.Source != SqlActivitySourceHelper.ActivitySource) { + this.RecordDuration(null, payload); return; } @@ -217,6 +236,7 @@ public override void OnEventWritten(string name, object? payload) finally { activity.Stop(); + this.RecordDuration(activity, payload, hasError: true); } } @@ -225,5 +245,84 @@ public override void OnEventWritten(string name, object? payload) break; } } + + private void RecordDuration(Activity? activity, object? payload, bool hasError = false) + { + if (SqlClientInstrumentation.MetricHandles == 0) + { + return; + } + + TagList tags = default(TagList); + + if (activity != null && activity.IsAllDataRequested) + { + foreach (var name in SharedTagNames) + { + var value = activity.GetTagItem(name); + if (value != null) + { + tags.Add(name, value); + } + } + } + else if (payload != null) + { + if (this.commandFetcher.TryFetch(payload, out var command) && command != null && + this.connectionFetcher.TryFetch(command, out var connection)) + { + this.databaseFetcher.TryFetch(connection, out var databaseName); + this.dataSourceFetcher.TryFetch(connection, out var dataSource); + + var connectionTags = SqlActivitySourceHelper.GetTagListFromConnectionInfo( + dataSource, + databaseName, + SqlClientInstrumentation.TracingOptions, + out _); + + foreach (var tag in connectionTags) + { + tags.Add(tag.Key, tag.Value); + } + + if (this.commandTypeFetcher.TryFetch(command, out var commandType) && + commandType == CommandType.StoredProcedure) + { + if (this.commandTextFetcher.TryFetch(command, out var commandText)) + { + tags.Add(SemanticConventions.AttributeDbOperationName, "EXECUTE"); + tags.Add(SemanticConventions.AttributeDbCollectionName, commandText); + } + } + } + + if (hasError) + { + if (this.exceptionFetcher.TryFetch(payload, out var exception) && exception != null) + { + tags.Add(SemanticConventions.AttributeErrorType, exception.GetType().FullName); + + if (this.exceptionNumberFetcher.TryFetch(exception, out var exceptionNumber)) + { + tags.Add(SemanticConventions.AttributeDbResponseStatusCode, exceptionNumber.ToString(CultureInfo.InvariantCulture)); + } + } + } + } + + var duration = activity?.Duration.TotalSeconds ?? this.CalculateDurationFromTimestamp(); + SqlActivitySourceHelper.DbClientOperationDuration.Record(duration, tags); + } + + private double CalculateDurationFromTimestamp() + { + var timestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency; + var begin = this.beginTimestamp.Value; + var end = Stopwatch.GetTimestamp(); + var delta = end - begin; + var ticks = (long)(timestampToTicks * delta); + var duration = new TimeSpan(ticks); + return duration.TotalSeconds; + } } #endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs index be77ab5796..e21f0bca88 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentation.cs @@ -22,6 +22,7 @@ internal sealed class SqlClientInstrumentation : IDisposable #if NET internal const string SqlClientTrimmingUnsupportedMessage = "Trimming is not yet supported with SqlClient instrumentation."; #endif + internal static int MetricHandles; internal static int TracingHandles; #if NETFRAMEWORK private readonly SqlEventSourceListener sqlEventSourceListener; @@ -61,6 +62,8 @@ private SqlClientInstrumentation() public static SqlClientTraceInstrumentationOptions TracingOptions { get; set; } = new SqlClientTraceInstrumentationOptions(); + public static IDisposable AddMetricHandle() => new MetricHandle(); + public static IDisposable AddTracingHandle() => new TracingHandle(); /// @@ -73,6 +76,28 @@ public void Dispose() #endif } +#if NET + [RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] +#endif + private sealed class MetricHandle : IDisposable + { + private bool disposed; + + public MetricHandle() + { + Interlocked.Increment(ref MetricHandles); + } + + public void Dispose() + { + if (!this.disposed) + { + Interlocked.Decrement(ref MetricHandles); + this.disposed = true; + } + } + } + #if NET [RequiresUnreferencedCode(SqlClientTrimmingUnsupportedMessage)] #endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientMeterProviderBuilderExtensions.cs new file mode 100644 index 0000000000..cddb97cb84 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientMeterProviderBuilderExtensions.cs @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if NET +using System.Diagnostics.CodeAnalysis; +#endif +using OpenTelemetry.Instrumentation.SqlClient; +using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics; + +/// +/// Extension methods to simplify registering of dependency instrumentation. +/// +public static class SqlClientMeterProviderBuilderExtensions +{ + /// + /// Enables SqlClient instrumentation. + /// + /// being configured. + /// The instance of to chain the calls. +#if NET + [RequiresUnreferencedCode(SqlClientInstrumentation.SqlClientTrimmingUnsupportedMessage)] +#endif + public static MeterProviderBuilder AddSqlClientInstrumentation(this MeterProviderBuilder builder) + { + Guard.ThrowIfNull(builder); + + builder.AddInstrumentation(sp => + { + return SqlClientInstrumentation.AddMetricHandle(); + }); + + builder.AddMeter(SqlActivitySourceHelper.MeterName); + + return builder; + } +} diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 5a5bc8d89c..c02e01d2a2 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -6,6 +6,8 @@ using Microsoft.Data.SqlClient; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Metrics; + #if !NETFRAMEWORK using OpenTelemetry.Tests; #endif @@ -65,34 +67,7 @@ public void SqlClient_NamedOptions() // DiagnosticListener-based instrumentation is only available on .NET Core #if !NETFRAMEWORK [Theory] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, false)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false)] - - // Test cases when EmitOldAttributes = false and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database) - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, false, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, false, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, true, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, false, true)] - - // Test cases when EmitOldAttributes = true and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database/dup) - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", false, false, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataAfterExecuteCommand, CommandType.Text, "select * from sys.databases", false, false, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.StoredProcedure, "SP_GetOrders", true, false, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, true, true, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand, CommandType.Text, "select * from sys.databases", true, false, true, true)] + [MemberData(nameof(SqlTestData.SqlClientCallsAreCollectedSuccessfullyCases), MemberType = typeof(SqlTestData))] public void SqlClientCallsAreCollectedSuccessfully( string beforeCommand, string afterCommand, @@ -101,27 +76,47 @@ public void SqlClientCallsAreCollectedSuccessfully( bool captureTextCommandContent, bool shouldEnrich = true, bool emitOldAttributes = true, - bool emitNewAttributes = false) + bool emitNewAttributes = false, + bool tracingEnabled = true, + bool metricsEnabled = true) { using var sqlConnection = new SqlConnection(TestConnectionString); using var sqlCommand = sqlConnection.CreateCommand(); var activities = new List(); - using (Sdk.CreateTracerProviderBuilder() - .AddSqlClientInstrumentation( - (opt) => - { - opt.SetDbStatementForText = captureTextCommandContent; - if (shouldEnrich) - { - opt.Enrich = ActivityEnrichment; - } - - opt.EmitOldAttributes = emitOldAttributes; - opt.EmitNewAttributes = emitNewAttributes; - }) - .AddInMemoryExporter(activities) - .Build()) + var metrics = new List(); + + var traceProviderBuilder = Sdk.CreateTracerProviderBuilder(); + + if (tracingEnabled) + { + traceProviderBuilder.AddSqlClientInstrumentation( + (opt) => + { + opt.SetDbStatementForText = captureTextCommandContent; + if (shouldEnrich) + { + opt.Enrich = ActivityEnrichment; + } + + opt.EmitOldAttributes = emitOldAttributes; + opt.EmitNewAttributes = emitNewAttributes; + }); + traceProviderBuilder.AddInMemoryExporter(activities); + } + + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder(); + + if (metricsEnabled) + { + meterProviderBuilder.AddSqlClientInstrumentation(); + meterProviderBuilder.AddInMemoryExporter(metrics); + } + + var traceProvider = traceProviderBuilder.Build(); + var meterProvider = meterProviderBuilder.Build(); + + try { var operationId = Guid.NewGuid(); sqlCommand.CommandType = commandType; @@ -151,20 +146,42 @@ public void SqlClientCallsAreCollectedSuccessfully( afterCommand, afterExecuteEventData); } + finally + { + traceProvider.Dispose(); + meterProvider.Dispose(); + } - Assert.Single(activities); - var activity = activities[0]; - - VerifyActivityData( - sqlCommand.CommandType, - sqlCommand.CommandText, - captureTextCommandContent, - false, - false, - shouldEnrich, - activity, - emitOldAttributes, - emitNewAttributes); + Activity? activity = null; + + if (tracingEnabled) + { + activity = Assert.Single(activities); + VerifyActivityData( + sqlCommand.CommandType, + sqlCommand.CommandText, + captureTextCommandContent, + false, + false, + shouldEnrich, + activity, + emitOldAttributes, + emitNewAttributes); + } + + var dbClientOperationDurationMetrics = metrics + .Where(metric => metric.Name == "db.client.operation.duration") + .ToArray(); + + if (metricsEnabled) + { + var metric = Assert.Single(dbClientOperationDurationMetrics); + VerifyDurationMetricData(metric, activity); + } + else + { + Assert.Empty(dbClientOperationDurationMetrics); + } } [Theory] @@ -221,20 +238,25 @@ public void SqlClientAddsConnectionLevelAttributes( } [Theory] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataWriteCommandError)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataWriteCommandError, false)] - [InlineData(SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlDataWriteCommandError, false, true)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError, false)] - [InlineData(SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError, false, true)] - public void SqlClientErrorsAreCollectedSuccessfully(string beforeCommand, string errorCommand, bool shouldEnrich = true, bool recordException = false) + [MemberData(nameof(SqlTestData.SqlClientErrorsAreCollectedSuccessfullyCases), MemberType = typeof(SqlTestData))] + public void SqlClientErrorsAreCollectedSuccessfully( + string beforeCommand, + string errorCommand, + bool shouldEnrich = true, + bool recordException = false, + bool tracingEnabled = true, + bool metricsEnabled = true) { using var sqlConnection = new SqlConnection(TestConnectionString); using var sqlCommand = sqlConnection.CreateCommand(); var activities = new List(); - using (Sdk.CreateTracerProviderBuilder() - .AddSqlClientInstrumentation(options => + var metrics = new List(); + var traceProviderBuilder = Sdk.CreateTracerProviderBuilder(); + + if (tracingEnabled) + { + traceProviderBuilder.AddSqlClientInstrumentation(options => { options.RecordException = recordException; if (shouldEnrich) @@ -242,8 +264,23 @@ public void SqlClientErrorsAreCollectedSuccessfully(string beforeCommand, string options.Enrich = ActivityEnrichment; } }) - .AddInMemoryExporter(activities) - .Build()) + .AddInMemoryExporter(activities); + } + + var traceProvider = traceProviderBuilder.Build(); + + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder(); + + if (metricsEnabled) + { + meterProviderBuilder + .AddSqlClientInstrumentation() + .AddInMemoryExporter(metrics); + } + + var meterProvider = meterProviderBuilder.Build(); + + try { var operationId = Guid.NewGuid(); sqlCommand.CommandText = "SP_GetOrders"; @@ -272,18 +309,44 @@ public void SqlClientErrorsAreCollectedSuccessfully(string beforeCommand, string errorCommand, commandErrorEventData); } + finally + { + traceProvider.Dispose(); + meterProvider.Dispose(); + } - Assert.Single(activities); - var activity = activities[0]; - - VerifyActivityData( - sqlCommand.CommandType, - sqlCommand.CommandText, - false, - true, - recordException, - shouldEnrich, - activity); + Activity? activity = null; + + if (tracingEnabled) + { + activity = Assert.Single(activities); + VerifyActivityData( + sqlCommand.CommandType, + sqlCommand.CommandText, + false, + true, + recordException, + shouldEnrich, + activity); + } + else + { + Assert.Empty(activities); + } + + var dbClientOperationDurationMetrics = metrics + .Where(metric => metric.Name == "db.client.operation.duration") + .ToArray(); + + if (metricsEnabled) + { + var metric = Assert.Single(dbClientOperationDurationMetrics); + VerifyDurationMetricData(metric, activity); + } + else + { + Assert.Empty(dbClientOperationDurationMetrics); + } } [Theory] @@ -461,6 +524,28 @@ internal static void VerifyActivityData( } } + internal static void VerifyDurationMetricData(Metric metric, Activity? activity) + { + Assert.NotNull(metric); + Assert.Equal("s", metric.Unit); + Assert.Equal(MetricType.Histogram, metric.MetricType); + + var metricPoints = new List(); + foreach (var p in metric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + var metricPoint = Assert.Single(metricPoints); + + if (activity != null) + { + var count = metricPoint.GetHistogramCount(); + var sum = metricPoint.GetHistogramSum(); + Assert.Equal(activity.Duration.TotalSeconds, sum); + } + } + internal static void VerifySamplingParameters(SamplingParameters samplingParameters) { Assert.NotNull(samplingParameters.Tags); diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs new file mode 100644 index 0000000000..2f648af344 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs @@ -0,0 +1,69 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NETFRAMEWORK +using System.Data; +using OpenTelemetry.Instrumentation.SqlClient.Implementation; +#endif + +namespace OpenTelemetry.Instrumentation.SqlClient.Tests; + +internal class SqlTestData +{ +#if !NETFRAMEWORK + public static IEnumerable SqlClientCallsAreCollectedSuccessfullyCases() + { + var bools = new[] { true, false }; + return from beforeCommand in new[] { SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand } + from commandType in new[] { CommandType.StoredProcedure, CommandType.Text } + from captureTextCommandContent in bools + from shouldEnrich in bools + from emitOldAttributes in bools + from emitNewAttributes in bools + from tracingEnabled in bools + from metricsEnabled in bools + where emitOldAttributes != false && emitNewAttributes != false + let endCommand = beforeCommand == SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand + ? SqlClientDiagnosticListener.SqlDataAfterExecuteCommand + : SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand + let commandText = commandType == CommandType.Text + ? "select * from sys.databases" + : "SP_GetOrders" + select new object[] + { + beforeCommand, + endCommand, + commandType, + commandText, + captureTextCommandContent, + shouldEnrich, + emitOldAttributes, + emitNewAttributes, + tracingEnabled, + metricsEnabled, + }; + } + + public static IEnumerable SqlClientErrorsAreCollectedSuccessfullyCases() + { + var bools = new[] { true, false }; + return from beforeCommand in new[] { SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand, SqlClientDiagnosticListener.SqlMicrosoftBeforeExecuteCommand } + from shouldEnrich in bools + from recordException in bools + from tracingEnabled in bools + from metricsEnabled in bools + let errorCommand = beforeCommand == SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand + ? SqlClientDiagnosticListener.SqlDataWriteCommandError + : SqlClientDiagnosticListener.SqlMicrosoftWriteCommandError + select new object[] + { + beforeCommand, + errorCommand, + shouldEnrich, + recordException, + tracingEnabled, + metricsEnabled, + }; + } +#endif +} From 25025fbb35843d14c2cfea8cfecd44e73c0b273f Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Mon, 11 Nov 2024 13:21:33 -0800 Subject: [PATCH 1410/1499] =?UTF-8?q?Remove=20Reiley=20Yang=20=F0=9F=90=87?= =?UTF-8?q?=20from=20the=20component=20owners=20list=F0=9F=91=8B=20(#2307)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/component_owners.yml | 7 ------- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- src/OpenTelemetry.Exporter.OneCollector/README.md | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 237de74f1f..683e7520e7 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -7,7 +7,6 @@ components: - cijothomas - codeblanch - rajkumar-rangaraj - - reyang - utpilla src/OpenTelemetry.Exporter.InfluxDB/: - havret @@ -15,7 +14,6 @@ components: - zivaninstana src/OpenTelemetry.Exporter.OneCollector/: - codeblanch - - reyang src/OpenTelemetry.Exporter.Stackdriver/: - SergeyKanzhelev src/OpenTelemetry.Extensions/: @@ -95,19 +93,16 @@ components: - cijothomas - codeblanch - rajkumar-rangaraj - - reyang - utpilla test/OpenTelemetry.Exporter.Geneva.Stress/: - cijothomas - codeblanch - rajkumar-rangaraj - - reyang - utpilla test/OpenTelemetry.Exporter.Geneva.Tests/: - cijothomas - codeblanch - rajkumar-rangaraj - - reyang - utpilla test/OpenTelemetry.Exporter.InfluxDB.Tests/: - havret @@ -115,10 +110,8 @@ components: - zivaninstana test/OpenTelemetry.Exporter.OneCollector.Benchmarks/: - codeblanch - - reyang test/OpenTelemetry.Exporter.OneCollector.Tests/: - codeblanch - - reyang test/OpenTelemetry.Exporter.Stackdriver.Tests/: - SergeyKanzhelev test/OpenTelemetry.Extensions.Tests/: diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index 2410808596..d2a3e3eddd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Stable](../../README.md#stable)| -| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/), [@reyang](https://github.com/reyang), [@utpilla](https://github.com/utpilla)| +| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/), [@utpilla](https://github.com/utpilla)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) diff --git a/src/OpenTelemetry.Exporter.OneCollector/README.md b/src/OpenTelemetry.Exporter.OneCollector/README.md index d806344a74..2d0eac2196 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/README.md +++ b/src/OpenTelemetry.Exporter.OneCollector/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Stable](../../README.md#stable)| -| Code Owners | [@codeblanch](https://github.com/codeblanch), [@reyang](https://github.com/reyang)| +| Code Owners | [@codeblanch](https://github.com/codeblanch)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.OneCollector)](https://www.nuget.org/packages/OpenTelemetry.Exporter.OneCollector) From 4a53b3f90d5d98dc47bb0f7a22f3d86cb2c4f522 Mon Sep 17 00:00:00 2001 From: Haihong Lin Date: Wed, 13 Nov 2024 10:51:14 +0800 Subject: [PATCH 1411/1499] Correct default MetricExporterIntervalMilliseconds from 20000 to 60000 in documentation (#2315) --- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index d2a3e3eddd..c61e7c16ce 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -340,7 +340,7 @@ the `ConnectionString`. #### `MetricExportIntervalMilliseconds` (optional) Set the exporter's periodic time interval to export Metrics. The default value -is 20000 milliseconds. +is 60000 milliseconds. #### `PrepopulatedMetricDimensions` (optional) From 4f230d8034548508910c46f554e632f41dde1fde Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 12 Nov 2024 21:05:30 -0600 Subject: [PATCH 1412/1499] [release] core-1.10.0 release updates (#2317) Co-authored-by: Mikel Blanchard --- build/Common.props | 7 +++--- .../Controllers/WeatherForecastController.cs | 2 +- examples/AspNet/Web.config | 16 ++++++++----- .../Examples.Wcf.Client.DotNet.csproj | 1 - .../CHANGELOG.md | 4 ++-- .../Common.GenevaExporter.props | 2 +- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 7 +++--- ...OpenTelemetry.Exporter.OneCollector.csproj | 2 +- .../CHANGELOG.md | 6 ++--- .../.publicApi/PublicAPI.Unshipped.txt | 2 +- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 3 +++ .../Trace/AWSXRayPropagator.cs | 2 +- .../CHANGELOG.md | 6 ++--- src/OpenTelemetry.Extensions/CHANGELOG.md | 6 ++--- .../ActivityEventAttachingLogProcessor.cs | 3 +-- .../Implementation/Tracing/AWSTraceSpan.cs | 4 +++- .../AWSLambdaWrapper.cs | 4 +++- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 11 +++++++++ .../Implementation/HttpInListener.cs | 2 +- .../CHANGELOG.md | 3 +++ .../Implementation/HttpInListener.cs | 2 +- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../OpenTelemetryConsumeResultExtensions.cs | 2 ++ .../CHANGELOG.md | 6 ++--- ...searchRequestPipelineDiagnosticListener.cs | 8 +++---- .../CHANGELOG.md | 3 +++ .../EntityFrameworkDiagnosticListener.cs | 2 ++ .../CHANGELOG.md | 4 ++-- .../CHANGELOG.md | 5 ++-- .../RpcScope.cs | 2 +- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ ...ngfireInstrumentationJobFilterAttribute.cs | 2 +- .../CHANGELOG.md | 3 +++ .../HttpHandlerDiagnosticListener.cs | 2 +- .../HttpWebRequestActivitySource.netfx.cs | 2 +- .../CHANGELOG.md | 6 ++--- .../Implementation/DiagnosticsMiddleware.cs | 6 +++-- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../QuartzDiagnosticListener.cs | 4 +++- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 9 ++++++++ .../SqlClientDiagnosticListener.cs | 2 +- .../CHANGELOG.md | 4 ++++ .../CHANGELOG.md | 3 +++ .../ClientChannelInstrumentation.cs | 2 ++ .../TelemetryDispatchMessageInspector.cs | 2 ++ src/OpenTelemetry.Resources.AWS/CHANGELOG.md | 6 ++--- .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Resources.Gcp/CHANGELOG.md | 6 ++--- src/OpenTelemetry.Resources.Host/CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ .../CHANGELOG.md | 3 +++ src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 3 +++ .../TestAWSClientInstrumentation.cs | 23 ++++++++++--------- .../ActivityHelperTest.cs | 2 +- .../BasicTests.cs | 2 +- .../ElasticsearchClientTests.cs | 20 ++++++++-------- .../EntityFrameworkDiagnosticListenerTests.cs | 7 +++--- .../GrpcTests.client.cs | 3 +-- .../GrpcTests.server.cs | 5 ++-- .../DiagnosticsMiddlewareTests.cs | 4 ++-- .../SqlClientIntegrationTests.cs | 2 -- .../SqlClientTests.cs | 1 - ...kExchangeRedisCallsInstrumentationTests.cs | 2 +- test/Shared/CustomTextMapPropagator.cs | 2 +- test/Shared/TestTextMapPropagator.cs | 4 ++-- 74 files changed, 207 insertions(+), 108 deletions(-) diff --git a/build/Common.props b/build/Common.props index ff82b6647f..f67b57da36 100644 --- a/build/Common.props +++ b/build/Common.props @@ -34,16 +34,15 @@ Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> [5.0.0,6.0) - [8.0.1,) [2.1.0,5.0) - [8.0.0,) - [8.0.0,) + [9.0.0,) + [9.0.0,) [1.0.3,2.0) [4.2.2,5.0) [3.11.0-beta1.23525.2] [8.0.0,9.0) [1.9.0-beta.2] - [1.9.0,2.0) + [1.10.0,2.0) [1.10.0-rc.1] [2.6.122,3.0) [2.4.0,3.0) diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index bf26ac9955..c51fe1a49a 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -89,7 +89,7 @@ public async Task GetData() [HttpPost] public async Task PostData() { - string value1 = Baggage.GetBaggage("key1"); + string? value1 = Baggage.GetBaggage("key1"); if (string.IsNullOrEmpty(value1)) { throw new InvalidOperationException("Key1 was not found on Baggage."); diff --git a/examples/AspNet/Web.config b/examples/AspNet/Web.config index e143e102d4..57e033590c 100644 --- a/examples/AspNet/Web.config +++ b/examples/AspNet/Web.config @@ -40,19 +40,23 @@ - + - - + + + + + + - + - + @@ -84,7 +88,7 @@ - + diff --git a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj index 75dc57fc09..8786127849 100644 --- a/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj +++ b/examples/wcf/client-core/Examples.Wcf.Client.DotNet.csproj @@ -9,7 +9,6 @@ - diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 317de4751a..68287b629d 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -19,8 +19,8 @@ For configuration details see: [OtlpProtobufEncoding](./README.md#otlpprotobufencoding). -* Update OpenTelemetry SDK version to `1.10.0-rc.1`. - ([#2294](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2294)) +* Update OpenTelemetry SDK version to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) ## 1.9.0 diff --git a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props index 78181066e1..5570a7a1fe 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props +++ b/src/OpenTelemetry.Exporter.Geneva/Common.GenevaExporter.props @@ -1,6 +1,6 @@ - $(OpenTelemetryCoreLatestPrereleaseVersion) + $(OpenTelemetryCoreLatestVersion) diff --git a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md index 414cccd813..1928acb44e 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/CHANGELOG.md @@ -7,6 +7,9 @@ [CVE-2024-43485](https://github.com/advisories/GHSA-8g4q-xg66-9fp4). ([#2202](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2202)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-alpha.4 Released 2024-Oct-02 diff --git a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md index 65df2e05a7..ca9a35d921 100644 --- a/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Instana/CHANGELOG.md @@ -6,8 +6,8 @@ The lowest supported version is .NET Framework 4.6.2. ([#1050](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1050)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) ## 1.0.3 diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index b4f4b438cc..877f084dd0 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -15,9 +15,10 @@ also be applied to subsequent `LogRecord`s in the same batch. ([#2205](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2205)) -* Update OpenTelemetry SDK version to `1.10.0-rc.1` and removed the direct - reference to `Microsoft.Extensions.Configuration.Binder`. - ([#2295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2295)) +* Update OpenTelemetry SDK version to `1.10.0` and removed the direct reference + to `Microsoft.Extensions.Configuration.Binder`. + ([#2295](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2295), + [#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) ## 1.9.3 diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index c8d10cef7d..9057a060ab 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -18,7 +18,7 @@ - $(OpenTelemetryCoreLatestPrereleaseVersion) + $(OpenTelemetryCoreLatestVersion) $(DefineConstants);EXPOSE_EXPERIMENTAL_FEATURES diff --git a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md index 5028755fcd..7ffc98164d 100644 --- a/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Stackdriver/CHANGELOG.md @@ -2,9 +2,6 @@ ## Unreleased -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Drop support for .NET 6 as this target is no longer supported and add .NET Standard 2.0 target. ([#2127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2127)) @@ -14,6 +11,9 @@ * Google.Cloud.Trace.V2 3.3.0 -> 3.5.0 ([#2127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2127)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.6 Released 2024-Apr-22 diff --git a/src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Unshipped.txt index a7a1588b77..cc69db22ab 100644 --- a/src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions.AWS/.publicApi/PublicAPI.Unshipped.txt @@ -2,7 +2,7 @@ OpenTelemetry.Extensions.AWS.AWSXRayIdGenerator OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.AWSXRayPropagator() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func!>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext +override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Extract(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Func?>! getter) -> OpenTelemetry.Context.Propagation.PropagationContext override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Fields.get -> System.Collections.Generic.ISet! override OpenTelemetry.Extensions.AWS.Trace.AWSXRayPropagator.Inject(OpenTelemetry.Context.Propagation.PropagationContext context, T carrier, System.Action! setter) -> void static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddXRayTraceId(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 90a29a6b95..472b28d538 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -8,6 +8,9 @@ * Removed the unused `System.Text.Json` reference. ([#2209](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2209)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.3.0-beta.2 Released 2024-Sep-24 diff --git a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs index 8927b136f7..bad3b9a9d6 100644 --- a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs @@ -38,7 +38,7 @@ public class AWSXRayPropagator : TextMapPropagator public override ISet Fields => new HashSet() { AWSXRayTraceHeaderKey }; /// - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { if (context.ActivityContext.IsValid()) { diff --git a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md index a00f3d58cf..d29aa9b9ed 100644 --- a/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.Enrichment/CHANGELOG.md @@ -5,8 +5,8 @@ * Make Extensions.Enrichment AoT compatible. ([#1541](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1541)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Drop support for .NET 6 as this target is no longer supported. ([#2126](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2126)) + +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index e382789b8d..a0848e428f 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -8,9 +8,6 @@ * Update BaggageActivityProcessor to require baggage key predicate. ([#1816](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1816)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Added rate limiting sampler which limits the number of traces to the specified rate per second. For details see [RateLimitingSampler](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Extensions#ratelimitingsampler). @@ -19,6 +16,9 @@ rate per second. For details see * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2124](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2124)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.5 Released 2024-May-08 diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index fbd1737966..0c2c7dd059 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using OpenTelemetry.Internal; -using OpenTelemetry.Trace; namespace OpenTelemetry.Logs; @@ -88,7 +87,7 @@ public override void OnEnd(LogRecord data) if (data.Exception != null) { - activity.RecordException(data.Exception); + activity.AddException(data.Exception); } } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs index 4e1e494b35..a825155d7f 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs @@ -59,8 +59,10 @@ public override void RecordException(Exception exception, Attributes? attributes var tags = attributes != null ? new TagList(attributes.AllAttributes.ToArray()) : default; - this.activity.RecordException(exception, tags); + this.activity.AddException(exception, tags); +#pragma warning disable CS0618 // Type or member is obsolete this.activity.SetStatus(Status.Error.WithDescription(exception.Message)); +#pragma warning restore CS0618 // Type or member is obsolete } public override void End() diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index 9ba0410d08..ab5930feec 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -191,8 +191,10 @@ private static void OnException(Activity? activity, Exception exception) { if (activity.IsAllDataRequested) { - activity.RecordException(exception); + activity.AddException(exception); +#pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error.WithDescription(exception.Message)); +#pragma warning restore CS0618 // Type or member is obsolete } } } diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 204d68c917..21b04d012c 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -10,6 +10,9 @@ implementations](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/trace/extending-the-sdk#sampler). ([#1871](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1871)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0-beta.1 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 19a6894f61..316b980d59 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -6,6 +6,9 @@ `IConfiguration`. ([#1976](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1976)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0-beta.1 Released 2024-Jun-18 @@ -44,9 +47,11 @@ Released 2024-Apr-05 * **Breaking Change**: Renamed `AspNetInstrumentationOptions` to `AspNetTraceInstrumentationOptions`. ([#1604](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1604)) + * **Breaking Change**: `server.address` and `server.port` no longer added for `http.server.request.duration` metric. ([#1606](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1606)) + * **Breaking change** Spans names and attributes will be set as per [HTTP semantic convention v1.24.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/http/http-spans.md): * span names follows: `{HTTP method} [route name if available]` pattern @@ -62,6 +67,7 @@ Released 2024-Apr-05 * `url.scheme` added with `http` or `https` value, * `user_agent.original` replaces `http.user_agent`. ([#1607](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1607)) + * `ActivitySource.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) @@ -252,6 +258,7 @@ Released 2021-Mar-19 and ActivityProcessors. Samplers, ActivityProcessor.OnStart will now get the Activity before any enrichment done by the instrumentation. ([#1836](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1836)) + * Performance optimization by leveraging sampling decision and short circuiting activity enrichment. ([#1903](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1903)) @@ -276,8 +283,10 @@ Released 2020-Nov-5 CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator and changed from interface to abstract class. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427)) + * Propagators.DefaultTextMapPropagator will be used as the default Propagator. ([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1428)) + * Removed Propagator from Instrumentation Options. Instrumentation now always respect the Propagator.DefaultTextMapPropagator. ([#1448](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1448)) @@ -290,6 +299,7 @@ Released 2020-Oct-16 Activity.CustomProperty. To enrich activity, use the Enrich action on the instrumentation. ([#1261](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1261)) + * Span Status is populated as per new spec ([#1313](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1313)) @@ -313,6 +323,7 @@ Released 2020-08-28 BaggageFormat)`. Baggage sent via the [W3C Baggage](https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md) header will now be parsed and set on incoming Http spans. + * Renamed `ITextPropagator` to `IPropagator` ([#1190](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1190)) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs index f038d522b6..03f5751a34 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInListener.cs @@ -146,7 +146,7 @@ private void OnException(Activity activity, HttpContext context, Exception excep { if (this.options.RecordException) { - activity.RecordException(exception); + activity.AddException(exception); } activity.SetStatus(ActivityStatusCode.Error, exception.Message); diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index be111b2388..eb7c0d907b 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -5,6 +5,9 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs index 26eafb164d..5ac36618e3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInListener.cs @@ -320,7 +320,7 @@ public void OnException(Activity activity, object? payload) if (this.options.RecordException) { - activity.RecordException(exc); + activity.AddException(exc); } activity.SetStatus(ActivityStatusCode.Error); diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md index 25b73d906b..480fbf3dc3 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.2 Released 2024-Oct-02 diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index 932234cb6e..cfa2dcb4f8 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -6,6 +6,9 @@ and add .NET Standard 2.0 target. ([#2142](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2142)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.1.0-alpha.2 Released 2024-Sep-18 diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs index 5e302b50c6..c1d650e2aa 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs @@ -113,7 +113,9 @@ public static bool TryExtractPropagationContext( } catch (Exception ex) { +#pragma warning disable CS0618 // Type or member is obsolete processActivity?.SetStatus(Status.Error); +#pragma warning restore CS0618 // Type or member is obsolete processActivity?.SetTag(SemanticConventions.AttributeErrorType, ex.GetType().FullName); } finally diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md index 5d444bb333..360b855a70 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/CHANGELOG.md @@ -12,14 +12,14 @@ Redact `username` and `password` part of the `url.full`. ([#1684](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1684)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Lowered the `System.Text.Json` reference to `4.7.2` for `net462` and `netstandard2.0` targets in response to [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). ([#2198](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2198)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.5 Released 2023-Oct-24 diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs index 5f57879521..4f927fbd45 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/Implementation/ElasticsearchRequestPipelineDiagnosticListener.cs @@ -254,27 +254,27 @@ private void OnStopActivity(Activity activity, object? payload) var failureReason = this.failureReasonFetcher.Fetch(originalException); if (failureReason != null) { - activity.SetStatus(Status.Error.WithDescription($"{failureReason} {originalException.Message}")); + activity.SetStatus(ActivityStatusCode.Error, description: $"{failureReason} {originalException.Message}"); } var responseBody = this.responseBodyFetcher.Fetch(payload); if (responseBody != null && responseBody.Length > 0) { var response = Encoding.UTF8.GetString(responseBody); - activity.SetStatus(Status.Error.WithDescription($"{failureReason} {originalException.Message}\r\n{response}")); + activity.SetStatus(ActivityStatusCode.Error, description: $"{failureReason} {originalException.Message}\r\n{response}"); } if (originalException is HttpRequestException) { if (originalException.InnerException is SocketException { SocketErrorCode: SocketError.HostNotFound }) { - activity.SetStatus(Status.Error.WithDescription(originalException.Message)); + activity.SetStatus(ActivityStatusCode.Error, description: originalException.Message); return; } if (originalException.InnerException != null) { - activity.SetStatus(Status.Error.WithDescription(originalException.Message)); + activity.SetStatus(ActivityStatusCode.Error, description: originalException.Message); } } } diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 2c8fc2c1de..0522374f01 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -24,6 +24,9 @@ [spans](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-spans.md). ([#2130](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2130)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.12 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 322c35c587..ef526d8c74 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -295,7 +295,9 @@ public override void OnEventWritten(string name, object? payload) { if (this.exceptionFetcher.Fetch(payload) is Exception exception) { +#pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error.WithDescription(exception.Message)); +#pragma warning restore CS0618 // Type or member is obsolete } else { diff --git a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md index 256a6c645b..0a2aa7b9c4 100644 --- a/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EventCounters/CHANGELOG.md @@ -5,8 +5,8 @@ * `Meter.Version` is set to NuGet package version. ([#1624](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1624)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) ## 1.5.1-alpha.1 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md index 70c54522c2..78e27daa5f 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/CHANGELOG.md @@ -2,12 +2,13 @@ ## Unreleased -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) * Updated minimal supported version of `Grpc.Core.Api` to `2.46.6`. ([#1936](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1936), [#1940](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1940)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.6 Released 2024-May-21 diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs index 24571bacb6..23bc198e72 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/RpcScope.cs @@ -218,7 +218,7 @@ private void StopActivity(Exception exception) if (this.activity!.IsAllDataRequested && this.recordException) { - this.activity.RecordException(exception); + this.activity.AddException(exception); } this.StopActivity((int)grpcStatusCode, markAsCompleted: false); diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md index ab16d3d6d2..ce1cb42da1 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -5,6 +5,9 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2150](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2150)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0-beta.1 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md index 55724ff852..682addf2e2 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0-beta.1 Released 2024-Oct-02 diff --git a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs index 0f0afaaa2a..df367de5d3 100644 --- a/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs +++ b/src/OpenTelemetry.Instrumentation.Hangfire/Implementation/HangfireInstrumentationJobFilterAttribute.cs @@ -131,7 +131,7 @@ private void SetStatusAndRecordException(Activity activity, Exception exception) if (this.options.RecordException) { - activity.RecordException(exception); + activity.AddException(exception); } } } diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 77f97966fd..beb4f6db93 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -5,6 +5,9 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2152](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2152)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index 5b65c673d0..f7b98fac07 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -266,7 +266,7 @@ public void OnException(Activity activity, object? payload) if (this.options.RecordException) { - activity.RecordException(exc); + activity.AddException(exc); } if (exc is HttpRequestException) diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index 7f8ba01066..df48fd4807 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -178,7 +178,7 @@ private static void AddExceptionEvent(Exception exception, Activity activity) if (TracingOptions.RecordException) { - activity.RecordException(exception); + activity.AddException(exception); } try diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index e775f6e7b8..956886a70b 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -7,9 +7,6 @@ attribute schema. ([#2028](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2028)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Updated registration extension code to retrieve environment variables through `IConfiguration`. ([#1973](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1973)) @@ -19,6 +16,9 @@ `OpenTelemetry` (SDK) package. ([#1977](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1977)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-rc.6 Released 2024-Apr-19 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 56092245f4..bc509a794d 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -150,14 +150,16 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l if (exception != null) { +#pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error); +#pragma warning restore CS0618 // Type or member is obsolete if (OwinInstrumentationActivitySource.Options?.RecordException == true) { - activity.RecordException(exception); + activity.AddException(exception); } } - else if (activity.GetStatus().StatusCode == StatusCode.Unset) + else if (activity.Status == ActivityStatusCode.Unset) { activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); } diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index bde93ea437..5d53d76d65 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.5.0-beta.7 Released 2024-Sep-25 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 3aa58ef9ce..f9ad69cdbf 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.3 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 9f390287d9..242df493f5 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -137,10 +137,12 @@ private void OnException(Activity activity, object? payload) if (this.options.RecordException) { - activity.RecordException(exc); + activity.AddException(exc); } +#pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error.WithDescription(exc.Message)); +#pragma warning restore CS0618 // Type or member is obsolete try { diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 1f71e065ef..069bc27ee2 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -5,6 +5,9 @@ * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2155](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2155)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index d69cfbd959..244489dff9 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -4,6 +4,7 @@ * Drop support for .NET 6 as this target is no longer supported. ([#2159](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2159)) + * The new database semantic conventions can be opted in to by setting the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a transition period for users to experiment with the new semantic conventions @@ -28,26 +29,34 @@ [#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277), [#2262](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2262), [#2279](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2279)) + * **Breaking change**: The `peer.service` and `server.socket.address` attributes are no longer emitted. Users should rely on the `server.address` attribute for the same information. Note that `server.address` is only included when the `EnableConnectionLevelAttributes` option is enabled. ([#2229](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2229)) + * **Breaking change**: When `EnableConnectionLevelAttributes` is enabled, the `server.port` attribute will now be written as an integer to be compliant with the [semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/attributes-registry/server.md). Previously, it was written as a string. ([#2233](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2233)) + * The `EnableConnectionLevelAttributes` option is now enabled by default. ([#2249](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2249)) + * The following attributes are now provided when starting an activity for a database call: `db.system`, `db.name` (old conventions), `db.namespace` (new conventions), `server.address`, and `server.port`. These attributes are now available for sampling decisions. ([#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277)) + * **Breaking change**: The `SetDbStatementForStoredProcedure` option has been removed. ([#TBD](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/TBD)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0-beta.1 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index c5d234550e..1478cca3ff 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -224,7 +224,7 @@ public override void OnEventWritten(string name, object? payload) if (options.RecordException) { - activity.RecordException(exception); + activity.AddException(exception); } } else diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index 252b9bf246..e73e8e34e4 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -5,6 +5,9 @@ * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2160](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2160)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.9.0-beta.1 Released 2024-Jul-23 @@ -12,6 +15,7 @@ Released 2024-Jul-23 * Add support for instrumenting `IConnectionMultiplexer` which is added with service key. ([#1885](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1885)) + * Update `StackExchange.Redis` version to `2.6.122`, resolving warnings about [CVE-2021-24112](https://github.com/advisories/GHSA-rxg9-xrhp-64gj). ([#1961](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1961)) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 5a8143925e..e5e4f3a2b7 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -5,6 +5,9 @@ * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2263](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2263)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-rc.18 Released 2024-Oct-28 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index ae569c3cf2..f6d4b58058 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -94,7 +94,9 @@ public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? { if (reply == null || reply.IsFault) { +#pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error); +#pragma warning restore CS0618 // Type or member is obsolete } if (reply != null) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs index 9c2c981b05..3741f0b832 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs @@ -123,7 +123,9 @@ public void BeforeSendReply(ref Message reply, object? correlationState) { if (reply.IsFault) { +#pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error); +#pragma warning restore CS0618 // Type or member is obsolete } activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); diff --git a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md index 76396646ea..a7f3bdd855 100644 --- a/src/OpenTelemetry.Resources.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.AWS/CHANGELOG.md @@ -2,9 +2,6 @@ ## Unreleased -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Drop support for .NET 6 as this target is no longer supported and add .NET Standard 2.0 target. ([#2164](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2164)) @@ -15,6 +12,9 @@ [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). ([#2196](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2196)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.5.0-beta.1 Released 2024-Jun-04 diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index a8da6ce17b..882b013ea0 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -10,6 +10,9 @@ [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). ([#2198](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2198)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.9 Released 2024-Sep-24 diff --git a/src/OpenTelemetry.Resources.Container/CHANGELOG.md b/src/OpenTelemetry.Resources.Container/CHANGELOG.md index 85c7614e00..47ef54a9cf 100644 --- a/src/OpenTelemetry.Resources.Container/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Container/CHANGELOG.md @@ -6,6 +6,9 @@ and add .NET 8/.NET Standard 2.0 targets. ([#2166](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2166)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 1.0.0-beta.9 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md index 3daabc8726..b072361a38 100644 --- a/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Gcp/CHANGELOG.md @@ -6,9 +6,6 @@ is accessible via `AddGcpDetector` extension method on `ResourceBuilder`. ([#1691](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1691)) -* Updated OpenTelemetry core component version(s) to `1.9.0`. - ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) - * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2167](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2167)) @@ -16,3 +13,6 @@ minimum version of `8.0.5` in response to [CVE-2024-43485](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485). ([#2198](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2198)) + +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index a07b292e58..8109eb733d 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -6,6 +6,9 @@ and add .NET 8/.NET Standard 2.0 targets. ([#2168](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2168)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.1.0-beta.3 Released 2024-Aug-30 diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index 4775cc550e..0cc52c09fe 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -6,6 +6,9 @@ and add .NET 8/.NET Standard 2.0 targets. ([#2169](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2169)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.1.0-alpha.4 Released 2024-Sep-09 diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index 75f0743c3c..ef692be8cd 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -6,6 +6,9 @@ and add .NET 8/.NET Standard 2.0 targets. ([#2170](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2170)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.1.0-beta.3 Released 2024-Sep-25 diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md index 5c820fc189..aed621d76c 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md @@ -6,6 +6,9 @@ and add .NET 8/.NET Standard 2.0 targets. ([#2171](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2171)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.1.0-beta.2 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 1a1de86b04..6c3514b50c 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -14,6 +14,9 @@ * Removed the `System.Net.Http` package reference from all targets. ([#2197](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2197)) +* Updated OpenTelemetry core component version(s) to `1.10.0`. + ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) + ## 0.1.0-alpha.2 Released 2024-Sep-09 diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs index 7d466c0cf4..62dab131ce 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/TestAWSClientInstrumentation.cs @@ -65,7 +65,7 @@ public async Task TestDDBScanSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -110,7 +110,7 @@ public async Task TestDDBSubtypeScanSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateDynamoActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -169,7 +169,8 @@ public async Task TestDDBScanUnsuccessful() this.ValidateDynamoActivityTags(awssdk_activity); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); - Assert.Equal(Status.Error.WithDescription("Exception of type 'Amazon.Runtime.AmazonServiceException' was thrown."), awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Error, awssdk_activity.Status); + Assert.Equal("Exception of type 'Amazon.Runtime.AmazonServiceException' was thrown.", awssdk_activity.StatusDescription); Assert.Equal("exception", awssdk_activity.Events.First().Name); } @@ -215,7 +216,7 @@ public async Task TestSQSSendMessageSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateSqsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -256,7 +257,7 @@ public async Task TestBedrockGetGuardrailSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -297,7 +298,7 @@ public async Task TestBedrockRuntimeInvokeModelSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockRuntimeActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -338,7 +339,7 @@ public async Task TestBedrockAgentGetAgentSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockAgentAgentOpsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -379,7 +380,7 @@ public async Task TestBedrockAgentGetKnowledgeBaseSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockAgentKnowledgeBaseOpsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -420,7 +421,7 @@ public async Task TestBedrockAgentGetDataSourceSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockAgentDataSourceOpsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -467,7 +468,7 @@ public async Task TestBedrockAgentRuntimeInvokeAgentSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockAgentRuntimeAgentOpsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } @@ -508,7 +509,7 @@ public async Task TestBedrockAgentRuntimeRetrieveSuccessful() this.ValidateAWSActivity(awssdk_activity, parent); this.ValidateBedrockAgentRuntimeKnowledgeBaseOpsActivityTags(awssdk_activity); - Assert.Equal(Status.Unset, awssdk_activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, awssdk_activity.Status); Assert.Equal(requestId, Utils.GetTagValue(awssdk_activity, "aws.request_id")); } diff --git a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs index 93d9c59ea2..18c4a538d1 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule.Tests/ActivityHelperTest.cs @@ -550,7 +550,7 @@ private class NoopTextMapPropagator : TextMapPropagator { 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 default; } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index 1d0ad5aa7f..abbf3148c5 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -1188,7 +1188,7 @@ private class ExtractOnlyPropagator(ActivityContext activityContext, Baggage bag public override ISet Fields => throw new NotImplementedException(); - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { return new PropagationContext(this.activityContext, this.baggage); } diff --git a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs index 5e23f346c5..95266c5528 100644 --- a/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.ElasticsearchClient.Tests/ElasticsearchClientTests.cs @@ -9,7 +9,6 @@ using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; -using Status = OpenTelemetry.Trace.Status; namespace OpenTelemetry.Instrumentation.ElasticsearchClient.Tests; @@ -68,7 +67,7 @@ public async Task CanCaptureGetById() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -121,7 +120,7 @@ public async Task CanCaptureGetByIdNotFound() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (404) low level call", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Error, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -173,7 +172,7 @@ public async Task CanCaptureSearchCall() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -405,7 +404,7 @@ public async Task CanCaptureSearchCallWithDebugMode() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -472,7 +471,7 @@ public async Task CanCaptureSearchCallWithParseAndFormatRequestOption() }".Replace("\r\n", "\n"), debugInfo.Replace("\r\n", "\n")); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -524,7 +523,7 @@ public async Task CanCaptureSearchCallWithoutDebugMode() Assert.NotEmpty(debugInfo); Assert.DoesNotContain("123", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -576,7 +575,7 @@ public async Task CanCaptureMultipleIndiceSearchCall() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -629,8 +628,7 @@ public async Task CanCaptureElasticsearchClientException() Assert.NotEmpty(debugInfo); Assert.Contains("Unsuccessful (500) low level call", debugInfo); - var status = searchActivity.GetStatus(); - Assert.Equal(Status.Error.StatusCode, status.StatusCode); + Assert.Equal(ActivityStatusCode.Error, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } @@ -682,7 +680,7 @@ public async Task CanCaptureCatRequest() Assert.NotEmpty(debugInfo); Assert.Contains("Successful (200) low level call", debugInfo); - Assert.Equal(Status.Unset, searchActivity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, searchActivity.Status); // Assert.Equal(expectedResource, searchActivity.GetResource()); } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 6610d02ffd..7974ef93de 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -283,13 +283,12 @@ private static void VerifyActivityData(Activity activity, bool isError = false, if (!isError) { - Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); } else { - Status status = activity.GetStatus(); - Assert.Equal(StatusCode.Error, status.StatusCode); - Assert.Equal("SQLite Error 1: 'no such table: no_table'.", status.Description); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Equal("SQLite Error 1: 'no such table: no_table'.", activity.StatusDescription); Assert.Contains(activity.Tags, t => t.Key == SpanAttributeConstants.StatusDescriptionKey); } } diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs index de6e55d223..2db706c0a3 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.client.cs @@ -18,7 +18,6 @@ using OpenTelemetry.Instrumentation.GrpcNetClient.Implementation; using OpenTelemetry.Trace; using Xunit; -using Status = OpenTelemetry.Trace.Status; namespace OpenTelemetry.Instrumentation.Grpc.Tests; @@ -100,7 +99,7 @@ public void GrpcClientCallsAreCollectedSuccessfully(string baseAddress, bool sho } Assert.Equal(uri.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort)); - Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); // Tags added by the library then removed from the instrumentation Assert.Null(activity.GetTagValue(GrpcTagHelper.GrpcMethodTagName)); diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs index 5d16091ed3..ce2105e591 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/GrpcTests.server.cs @@ -13,7 +13,6 @@ using OpenTelemetry.Instrumentation.Grpc.Services.Tests; using OpenTelemetry.Trace; using Xunit; -using Status = OpenTelemetry.Trace.Status; namespace OpenTelemetry.Instrumentation.Grpc.Tests; @@ -83,7 +82,7 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributes(string? enableGrp Assert.NotNull(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); } - Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); // The following are http.* attributes that are also included on the span for the gRPC invocation. Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeServerAddress)); @@ -160,7 +159,7 @@ public void GrpcAspNetCoreInstrumentationAddsCorrectAttributesWhenItCreatesNewAc Assert.NotNull(activity.GetTagValue(GrpcTagHelper.GrpcStatusCodeTagName)); } - Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); // The following are http.* attributes that are also included on the span for the gRPC invocation. Assert.Equal("localhost", activity.GetTagValue(SemanticConventions.AttributeNetHostName)); diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 849b30f0c3..eea813ec36 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -200,7 +200,7 @@ Owin has finished to inspect the activity status. */ if (generateRemoteException) { - Assert.Equal(Status.Error, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Error, activity.Status); if (recordException) { @@ -209,7 +209,7 @@ Owin has finished to inspect the activity status. */ } else { - Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); } if (enrich && !enrichmentException) diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs index 6c13ba7171..2185963f9e 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTests.cs @@ -90,13 +90,11 @@ public void SuccessfulCommandTest( if (isFailure) { #if NET - var status = activity.GetStatus(); Assert.Equal(ActivityStatusCode.Error, activity.Status); Assert.Equal("Divide by zero error encountered.", activity.StatusDescription); Assert.EndsWith("SqlException", activity.GetTagValue(SemanticConventions.AttributeErrorType) as string); Assert.Equal("8134", activity.GetTagValue(SemanticConventions.AttributeDbResponseStatusCode)); #else - var status = activity.GetStatus(); Assert.Equal(ActivityStatusCode.Error, activity.Status); Assert.Equal("8134", activity.StatusDescription); Assert.EndsWith("SqlException", activity.GetTagValue(SemanticConventions.AttributeErrorType) as string); diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index c02e01d2a2..1587d407a1 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -439,7 +439,6 @@ internal static void VerifyActivityData( } else { - var status = activity.GetStatus(); Assert.Equal(ActivityStatusCode.Error, activity.Status); Assert.NotNull(activity.StatusDescription); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index 4ede2553fa..acf0081639 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -411,7 +411,7 @@ private static void VerifyActivityData(Activity activity, bool isSet, EndPoint e } } - Assert.Equal(Status.Unset, activity.GetStatus()); + Assert.Equal(ActivityStatusCode.Unset, activity.Status); Assert.Equal("redis", activity.GetTagValue(SemanticConventions.AttributeDbSystem)); Assert.Equal(0, activity.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisDatabaseIndexKeyName)); diff --git a/test/Shared/CustomTextMapPropagator.cs b/test/Shared/CustomTextMapPropagator.cs index 436879e8b5..97aea2f6a7 100644 --- a/test/Shared/CustomTextMapPropagator.cs +++ b/test/Shared/CustomTextMapPropagator.cs @@ -22,7 +22,7 @@ internal sealed class CustomTextMapPropagator : TextMapPropagator #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) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { if (this.TraceId != default && this.SpanId != default) { diff --git a/test/Shared/TestTextMapPropagator.cs b/test/Shared/TestTextMapPropagator.cs index 5ce7fd9bd3..adabbde7d7 100644 --- a/test/Shared/TestTextMapPropagator.cs +++ b/test/Shared/TestTextMapPropagator.cs @@ -13,7 +13,7 @@ internal class TestTextMapPropagator : TextMapPropagator public override ISet Fields => throw new NotImplementedException(); - public override PropagationContext Extract(PropagationContext context, T carrier, Func> getter) + public override PropagationContext Extract(PropagationContext context, T carrier, Func?> getter) { this.Extracted?.Invoke(); return context; @@ -24,7 +24,7 @@ public override void Inject(PropagationContext context, T carrier, Action((c, k, v) => setter(c, k, v)); this.OnInject?.Invoke( context, - carrier, + carrier!, new Action((c, k, v) => setter((T)c, k, v))); } } From c9b91f3233bdef72e24d4a4c6378814c8af363a4 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 12 Nov 2024 21:27:55 -0600 Subject: [PATCH 1413/1499] [release] coreunstable-1.10.0-beta.1 release updates (#2318) --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index f67b57da36..a33837c548 100644 --- a/build/Common.props +++ b/build/Common.props @@ -41,7 +41,7 @@ [4.2.2,5.0) [3.11.0-beta1.23525.2] [8.0.0,9.0) - [1.9.0-beta.2] + [1.10.0-beta.1] [1.10.0,2.0) [1.10.0-rc.1] [2.6.122,3.0) From b2c20e33b65fed373b140b0937925f780176ec2a Mon Sep 17 00:00:00 2001 From: xiang17 Date: Wed, 13 Nov 2024 06:12:47 -0800 Subject: [PATCH 1414/1499] [repo] Bump SDK to 9.0.100 (#2316) Co-authored-by: Mikel Blanchard --- .github/workflows/ci.yml | 2 -- .github/workflows/verifyaotcompat.yml | 5 ++++- build/Common.nonprod.props | 1 + build/Common.props | 2 +- build/docker-compose.net8.0.yml | 2 +- build/docker-compose.net9.0.yml | 9 +++++++++ build/scripts/test-aot-compatibility.ps1 | 2 +- global.json | 2 +- opentelemetry-dotnet-contrib.sln | 1 + .../OpenTelemetry.AotCompatibility.TestApp.csproj | 2 +- .../UnixUserEventsDataTransportTests.cs | 9 ++++----- .../Dockerfile | 6 +++--- .../Dockerfile | 6 +++--- 13 files changed, 30 insertions(+), 19 deletions(-) create mode 100644 build/docker-compose.net9.0.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5ad249b79..c116d7d555 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,8 +104,6 @@ jobs: with: project-name: Component[OpenTelemetry.Exporter.Geneva] code-cov-name: Exporter.Geneva - os-list: '[ "ubuntu-24.04" ]' # Note: This may be switched to latest once ubuntu-latest has a kernel version >= 6.8.0-1014-azure - tfm-list: '[ "net8.0" ]' # Note: Should be able to remove this once the above is using ubuntu-latest test-case-filter: CategoryName=Geneva:user_events:metrics test-require-elevated: true pack: false diff --git a/.github/workflows/verifyaotcompat.yml b/.github/workflows/verifyaotcompat.yml index a9877dbf1d..1aff3cac2a 100644 --- a/.github/workflows/verifyaotcompat.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -10,12 +10,15 @@ 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: - uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + - name: publish AOT testApp, assert static analysis warning count, and run the app shell: pwsh run: .\build\scripts\test-aot-compatibility.ps1 ${{ matrix.version }} diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 49f87abbdd..57551d83b0 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -30,6 +30,7 @@ [17.11.1,18.0) $(OpenTelemetryCoreLatestVersion) net8.0 + net9.0;net8.0 [2.8.2,3.0) [2.9.0,3.0) [1.6.3,2.0) diff --git a/build/Common.props b/build/Common.props index a33837c548..1f610aad30 100644 --- a/build/Common.props +++ b/build/Common.props @@ -10,7 +10,7 @@ net8.0 netstandard2.0 true - latest-all + 8.0 enable enable true diff --git a/build/docker-compose.net8.0.yml b/build/docker-compose.net8.0.yml index a5ac999e43..22787bff66 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 0000000000..29663b3246 --- /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/build/scripts/test-aot-compatibility.ps1 b/build/scripts/test-aot-compatibility.ps1 index 5687ba1d25..f477ed1063 100644 --- a/build/scripts/test-aot-compatibility.ps1 +++ b/build/scripts/test-aot-compatibility.ps1 @@ -2,7 +2,7 @@ param([string]$targetNetFramework) $rootDirectory = Get-Location -$publishOutput = dotnet publish $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj -nodeReuse:false /p:UseSharedCompilation=false +$publishOutput = dotnet publish $rootDirectory/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj --framework $targetNetFramework -nodeReuse:false /p:UseSharedCompilation=false $actualWarningCount = 0 diff --git a/global.json b/global.json index 0aca8b1293..6a79b98070 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestFeature", - "version": "8.0.100" + "version": "9.0.100" } } diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 03eeebb4e7..6f378a2ab0 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -56,6 +56,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{824BD1DE build\Common.targets = build\Common.targets build\debug.snk = build\debug.snk 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\opentelemetry-icon-color.png = build\opentelemetry-icon-color.png build\OpenTelemetryContrib.prod.ruleset = build\OpenTelemetryContrib.prod.ruleset build\OpenTelemetryContrib.test.ruleset = build\OpenTelemetryContrib.test.ruleset diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 85c4c98f0c..10ec3c7e99 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -2,7 +2,7 @@ Exe - $(NetMinimumSupportedVersion) + $(TargetFrameworksForAotCompatibilityTests) true false true diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs index 4af7484581..b1b8ea9601 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs @@ -7,7 +7,6 @@ using System.Globalization; using System.Text.RegularExpressions; using Microsoft.LinuxTracepoints.Provider; -using OpenTelemetry.Tests; using Xunit; using Xunit.Abstractions; @@ -50,8 +49,8 @@ public UnixUserEventsDataTransportTests(ITestOutputHelper testOutputHelper) this.testOutputHelper = testOutputHelper; } - [SkipUnlessPlatformMatchesFact(TestPlatform.Linux, requireElevatedProcess: true)] - public void UserEvents_Enabled_Succes_Linux() + [Fact(Skip = "This would fail on Ubuntu. Skipping for now.")] + public void UserEvents_Enabled_Success_Linux() { EnsureUserEventsEnabled(); @@ -114,8 +113,8 @@ public void UserEvents_Enabled_Succes_Linux() } } - [SkipUnlessPlatformMatchesFact(TestPlatform.Linux, requireElevatedProcess: true)] - public void UserEvents_Disabled_Succes_Linux() + [Fact(Skip = "This would fail on Ubuntu. Skipping for now.")] + public void UserEvents_Disabled_Success_Linux() { EnsureUserEventsEnabled(); diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile index 13c925e0e4..818d8920e6 100644 --- a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/Dockerfile @@ -2,12 +2,12 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.ConfluentKafka.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 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.ConfluentKafka.Tests" diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile index f17bd22d2b..80c57daa23 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Dockerfile @@ -2,12 +2,12 @@ # This should be run from the root of the repo: # docker build --file test/OpenTelemetry.Instrumentation.StackExchangeRedis.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 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.StackExchangeRedis.Tests" From ea459ff791daa958086339acda1c5b6e721ba518 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 13 Nov 2024 08:42:22 -0800 Subject: [PATCH 1415/1499] [repo] Move Cijo to Emeritus (#2320) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9ce137154..cab0fc0fdc 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,6 @@ repository](https://github.com/open-telemetry/community/blob/main/guides/contrib [@open-telemetry/dotnet-contrib-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-contrib-maintainers): * [Alan West](https://github.com/alanwest), New Relic -* [Cijo Thomas](https://github.com/cijothomas), Microsoft * [Mikel Blanchard](https://github.com/CodeBlanch), Microsoft * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk @@ -101,6 +100,7 @@ repository](h[ttps://github.com/open-telemetry/community/blob/main/community-mem [Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager): +* [Cijo Thomas](https://github.com/cijothomas) * [Prashant Srivastava](https://github.com/srprash) * [Sergey Kanzhelev](https://github.com/SergeyKanzhelev) * [Utkarsh Umesan Pillai](https://github.com/utpilla) From afe43426a9e23d4e2f26d5992730e0282b19a24b Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Wed, 13 Nov 2024 09:29:15 -0800 Subject: [PATCH 1416/1499] [geneva] Tweak OtlpProtobufSerializer to access MetricPoint by ref (#2310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../OtlpProtobuf/OtlpProtobufSerializer.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index e837fc327c..68c3ab36b5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -354,7 +354,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.metricPointTagAndLengthIndex = cursor; this.metricPointValueIndex = cursor + TagAndLengthSize; - foreach (var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { try { @@ -363,7 +363,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var sum = metricPoint.GetSumLong(); - this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Sum_data_points, metricPoint, sum); + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Sum_data_points, in metricPoint, sum); // Finish writing current batch this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); @@ -394,7 +394,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.metricPointTagAndLengthIndex = cursor; this.metricPointValueIndex = cursor + TagAndLengthSize; - foreach (var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { try { @@ -403,7 +403,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var sum = metricPoint.GetSumDouble(); - this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Sum_data_points, metricPoint, sum); + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Sum_data_points, in metricPoint, sum); // Finish writing current batch this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); @@ -427,7 +427,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.metricPointTagAndLengthIndex = cursor; this.metricPointValueIndex = cursor + TagAndLengthSize; - foreach (var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { try { @@ -436,7 +436,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var lastValue = metricPoint.GetGaugeLastValueLong(); - this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Gauge_data_points, metricPoint, lastValue); + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Gauge_data_points, in metricPoint, lastValue); // Finish writing current batch this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); @@ -460,7 +460,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.metricPointTagAndLengthIndex = cursor; this.metricPointValueIndex = cursor + TagAndLengthSize; - foreach (var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { try { @@ -469,7 +469,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var lastValue = metricPoint.GetGaugeLastValueDouble(); - this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Gauge_data_points, metricPoint, lastValue); + this.WriteNumberDataPoint(buffer, ref cursor, FieldNumberConstants.Gauge_data_points, in metricPoint, lastValue); // Finish writing current batch this.WriteIndividualMessageTagsAndLength(buffer, ref cursor, metric.MetricType); @@ -496,7 +496,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.metricPointTagAndLengthIndex = cursor; this.metricPointValueIndex = cursor + TagAndLengthSize; - foreach (var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { try { @@ -579,7 +579,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) this.metricPointTagAndLengthIndex = cursor; this.metricPointValueIndex = cursor + TagAndLengthSize; - foreach (var metricPoint in metric.GetMetricPoints()) + foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { try { @@ -664,7 +664,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) } } - private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNumber, MetricPoint metricPoint, T value) + private void WriteNumberDataPoint(byte[] buffer, ref int cursor, int fieldNumber, in MetricPoint metricPoint, T value) { if (typeof(T) == typeof(long)) { From 9ea2d08569e5a7232fa31becaa8d647a6ba93811 Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Thu, 14 Nov 2024 14:38:48 -0500 Subject: [PATCH 1417/1499] [Instrumentation.SqlClient] Implements database metric `db.client.operation.duration` (part 2/netfx) (#2311) Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- .../CHANGELOG.md | 10 + .../Implementation/SqlActivitySourceHelper.cs | 22 +++ .../SqlClientDiagnosticListener.cs | 28 +-- .../SqlEventSourceListener.netfx.cs | 89 ++++++++- .../SqlEventSourceTests.netfx.cs | 178 ++++++++++++------ 5 files changed, 237 insertions(+), 90 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 244489dff9..8a45888983 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -53,6 +53,16 @@ * **Breaking change**: The `SetDbStatementForStoredProcedure` option has been removed. ([#TBD](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/TBD)) +* Add support for metric `db.client.operation.duration` + from [new database semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-metrics.md#metric-dbclientoperationduration) + on .NET 8+. + ([#2309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2309)) +* Add support for metric `db.client.operation.duration` + from [new database semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-metrics.md#metric-dbclientoperationduration) + on .NET Framework. + ([#2311](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2311)) + * Only the following attributes are available when a trace is not captured: + `db.system`, `db.response.status_code`, and `error.type` * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index d2e362fa63..01cde6bd66 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -30,6 +30,18 @@ internal sealed class SqlActivitySourceHelper "s", "Duration of database client operations."); + internal static readonly string[] SharedTagNames = + [ + SemanticConventions.AttributeDbSystem, + SemanticConventions.AttributeDbCollectionName, + SemanticConventions.AttributeDbNamespace, + SemanticConventions.AttributeDbResponseStatusCode, + SemanticConventions.AttributeDbOperationName, + SemanticConventions.AttributeErrorType, + SemanticConventions.AttributeServerPort, + SemanticConventions.AttributeServerAddress, + ]; + public static TagList GetTagListFromConnectionInfo(string? dataSource, string? databaseName, SqlClientTraceInstrumentationOptions options, out string activityName) { activityName = MicrosoftSqlServerDatabaseSystemName; @@ -97,4 +109,14 @@ public static TagList GetTagListFromConnectionInfo(string? dataSource, string? d return tags; } + + internal static double CalculateDurationFromTimestamp(long begin, long? end = null) + { + end = end ?? Stopwatch.GetTimestamp(); + var timestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency; + var delta = end - begin; + var ticks = (long)(timestampToTicks * delta); + var duration = new TimeSpan(ticks); + return duration.TotalSeconds; + } } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 1478cca3ff..3695f7424d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -26,18 +26,6 @@ internal sealed class SqlClientDiagnosticListener : ListenerHandler public const string SqlDataWriteCommandError = "System.Data.SqlClient.WriteCommandError"; public const string SqlMicrosoftWriteCommandError = "Microsoft.Data.SqlClient.WriteCommandError"; - private static readonly string[] SharedTagNames = - [ - SemanticConventions.AttributeDbSystem, - SemanticConventions.AttributeDbCollectionName, - SemanticConventions.AttributeDbNamespace, - SemanticConventions.AttributeDbResponseStatusCode, - SemanticConventions.AttributeDbOperationName, - SemanticConventions.AttributeErrorType, - SemanticConventions.AttributeServerPort, - SemanticConventions.AttributeServerAddress, - ]; - private readonly PropertyFetcher commandFetcher = new("Command"); private readonly PropertyFetcher connectionFetcher = new("Connection"); private readonly PropertyFetcher dataSourceFetcher = new("DataSource"); @@ -257,7 +245,7 @@ private void RecordDuration(Activity? activity, object? payload, bool hasError = if (activity != null && activity.IsAllDataRequested) { - foreach (var name in SharedTagNames) + foreach (var name in SqlActivitySourceHelper.SharedTagNames) { var value = activity.GetTagItem(name); if (value != null) @@ -310,19 +298,9 @@ private void RecordDuration(Activity? activity, object? payload, bool hasError = } } - var duration = activity?.Duration.TotalSeconds ?? this.CalculateDurationFromTimestamp(); + var duration = activity?.Duration.TotalSeconds + ?? SqlActivitySourceHelper.CalculateDurationFromTimestamp(this.beginTimestamp.Value); SqlActivitySourceHelper.DbClientOperationDuration.Record(duration, tags); } - - private double CalculateDurationFromTimestamp() - { - var timestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency; - var begin = this.beginTimestamp.Value; - var end = Stopwatch.GetTimestamp(); - var delta = end - begin; - var ticks = (long)(timestampToTicks * delta); - var duration = new TimeSpan(ticks); - return duration.TotalSeconds; - } } #endif diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index 329aa8e184..f58f97cd2d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -29,6 +29,7 @@ internal sealed class SqlEventSourceListener : EventListener internal const int BeginExecuteEventId = 1; internal const int EndExecuteEventId = 2; + private readonly AsyncLocal beginTimestamp = new(); private EventSource? adoNetEventSource; private EventSource? mdsEventSource; @@ -82,6 +83,29 @@ protected override void OnEventWritten(EventWrittenEventArgs eventData) } } + private static (bool HasError, string? ErrorNumber, string? ExceptionType) ExtractErrorFromEvent(EventWrittenEventArgs eventData) + { + var compositeState = (int)eventData.Payload[1]; + + if ((compositeState & 0b001) != 0b001) + { + if ((compositeState & 0b010) == 0b010) + { + var errorNumber = $"{eventData.Payload[2]}"; + var exceptionType = eventData.EventSource.Name == MdsEventSourceName + ? "Microsoft.Data.SqlClient.SqlException" + : "System.Data.SqlClient.SqlException"; + return (true, errorNumber, exceptionType); + } + else + { + return (true, null, null); + } + } + + return (false, null, null); + } + private void OnBeginExecute(EventWrittenEventArgs eventData) { /* @@ -100,7 +124,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) (https://github.com/dotnet/SqlClient/blob/f4568ce68da21db3fe88c0e72e1287368aaa1dc8/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs#L6641) */ - if (SqlClientInstrumentation.TracingHandles == 0) + if (SqlClientInstrumentation.TracingHandles == 0 && SqlClientInstrumentation.MetricHandles == 0) { return; } @@ -125,6 +149,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) if (activity == null) { // There is no listener or it decided not to sample the current request. + this.beginTimestamp.Value = Stopwatch.GetTimestamp(); return; } @@ -155,7 +180,7 @@ private void OnEndExecute(EventWrittenEventArgs eventData) [2] -> SqlExceptionNumber */ - if (SqlClientInstrumentation.TracingHandles == 0) + if (SqlClientInstrumentation.TracingHandles == 0 && SqlClientInstrumentation.MetricHandles == 0) { return; } @@ -166,6 +191,12 @@ private void OnEndExecute(EventWrittenEventArgs eventData) return; } + if (SqlClientInstrumentation.TracingHandles == 0 && SqlClientInstrumentation.MetricHandles != 0) + { + this.RecordDuration(null, eventData); + return; + } + var activity = Activity.Current; if (activity?.Source != SqlActivitySourceHelper.ActivitySource) { @@ -176,18 +207,14 @@ private void OnEndExecute(EventWrittenEventArgs eventData) { if (activity.IsAllDataRequested) { - var compositeState = (int)eventData.Payload[1]; - if ((compositeState & 0b001) != 0b001) + var (hasError, errorNumber, exceptionType) = ExtractErrorFromEvent(eventData); + + if (hasError) { - if ((compositeState & 0b010) == 0b010) + if (errorNumber != null && exceptionType != null) { - var errorNumber = $"{eventData.Payload[2]}"; activity.SetStatus(ActivityStatusCode.Error, errorNumber); activity.SetTag(SemanticConventions.AttributeDbResponseStatusCode, errorNumber); - - var exceptionType = eventData.EventSource.Name == MdsEventSourceName - ? "Microsoft.Data.SqlClient.SqlException" - : "System.Data.SqlClient.SqlException"; activity.SetTag(SemanticConventions.AttributeErrorType, exceptionType); } else @@ -200,7 +227,49 @@ private void OnEndExecute(EventWrittenEventArgs eventData) finally { activity.Stop(); + this.RecordDuration(activity, eventData); + } + } + + private void RecordDuration(Activity? activity, EventWrittenEventArgs eventData) + { + if (SqlClientInstrumentation.MetricHandles == 0) + { + return; + } + + var tags = default(TagList); + + if (activity != null && activity.IsAllDataRequested) + { + foreach (var name in SqlActivitySourceHelper.SharedTagNames) + { + var value = activity.GetTagItem(name); + if (value != null) + { + tags.Add(name, value); + } + } + } + else + { + tags.Add(SemanticConventions.AttributeDbSystem, SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName); + + var (hasError, errorNumber, exceptionType) = ExtractErrorFromEvent(eventData); + + if (hasError) + { + if (errorNumber != null && exceptionType != null) + { + tags.Add(SemanticConventions.AttributeDbResponseStatusCode, errorNumber); + tags.Add(SemanticConventions.AttributeErrorType, exceptionType); + } + } } + + var duration = activity?.Duration.TotalSeconds + ?? SqlActivitySourceHelper.CalculateDurationFromTimestamp(this.beginTimestamp.Value); + SqlActivitySourceHelper.DbClientOperationDuration.Record(duration, tags); } } #endif diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index d91951692a..8d0c47d002 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Diagnostics.Tracing; using OpenTelemetry.Instrumentation.SqlClient.Implementation; +using OpenTelemetry.Metrics; using OpenTelemetry.Tests; using OpenTelemetry.Trace; using Xunit; @@ -27,6 +28,42 @@ To use Docker... private const string SqlConnectionStringEnvVarName = "OTEL_SQLCONNECTIONSTRING"; private static readonly string? SqlConnectionString = SkipUnlessEnvVarFoundTheoryAttribute.GetEnvironmentVariable(SqlConnectionStringEnvVarName); + public static IEnumerable EventSourceFakeTestCases() + { + /* netfx driver can't capture queries, only stored procedure names */ + /* always emit some attribute */ + var bools = new[] { true, false }; + return from eventSourceType in new[] { typeof(FakeBehavingAdoNetSqlEventSource), typeof(FakeBehavingMdsSqlEventSource) } + from commandType in new[] { CommandType.StoredProcedure, CommandType.Text } + from isFailure in bools + from captureText in bools + from enableConnectionLevelAttributes in bools + from emitOldAttributes in bools + from emitNewAttributes in bools + from tracingEnabled in bools + from metricsEnabled in bools + where !(commandType == CommandType.Text && captureText == true) + where emitOldAttributes != false && emitNewAttributes != false + let commandText = commandType == CommandType.Text + ? (isFailure == false ? "select 1/1" : "select 1/0") + : "sp_who" + let sqlExceptionNumber = 0 + select new object[] + { + eventSourceType, + commandType, + commandText, + captureText, + isFailure, + sqlExceptionNumber, + enableConnectionLevelAttributes, + emitOldAttributes, + emitNewAttributes, + tracingEnabled, + metricsEnabled, + }; + } + [Trait("CategoryName", "SqlIntegrationTests")] [SkipUnlessEnvVarFoundTheory(SqlConnectionStringEnvVarName)] [InlineData(CommandType.Text, "select 1/1", false)] @@ -75,34 +112,7 @@ public async Task SuccessfulCommandTest(CommandType commandType, string commandT } [Theory] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/1", false)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/0", false, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", false)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/1", false)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/0", false, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", false)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true)] - - // Test cases when EmitOldAttributes = false and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database) - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/1", false, false, 0, false, false, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/0", false, true, 0, false, false, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", false, false, 0, false, false, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true, false, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/1", false, false, 0, false, false, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/0", false, true, 0, false, false, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", false, false, 0, false, false, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true, false, true)] - - // Test cases when EmitOldAttributes = true and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database/dup) - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/1", false, false, 0, false, true, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.Text, "select 1/0", false, true, 0, false, true, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", false, false, 0, false, true, true)] - [InlineData(typeof(FakeBehavingAdoNetSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true, true, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/1", false, false, 0, false, true, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.Text, "select 1/0", false, true, 0, false, true, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", false, false, 0, false, true, true)] - [InlineData(typeof(FakeBehavingMdsSqlEventSource), CommandType.StoredProcedure, "sp_who", true, false, 0, true, true, true)] + [MemberData(nameof(EventSourceFakeTestCases))] public void EventSourceFakeTests( Type eventSourceType, CommandType commandType, @@ -112,45 +122,104 @@ public void EventSourceFakeTests( int sqlExceptionNumber = 0, bool enableConnectionLevelAttributes = false, bool emitOldAttributes = true, - bool emitNewAttributes = false) + bool emitNewAttributes = false, + bool tracingEnabled = true, + bool metricsEnabled = true) { using var fakeSqlEventSource = (IFakeBehavingSqlEventSource)Activator.CreateInstance(eventSourceType); - var exportedItems = new List(); - using var shutdownSignal = Sdk.CreateTracerProviderBuilder() - .AddInMemoryExporter(exportedItems) - .AddSqlClientInstrumentation(options => - { - options.SetDbStatementForText = captureText; - options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; - options.EmitOldAttributes = emitOldAttributes; - options.EmitNewAttributes = emitNewAttributes; - }) - .Build(); + var activities = new List(); + var metrics = new List(); - var objectId = Guid.NewGuid().GetHashCode(); + var traceProviderBuilder = Sdk.CreateTracerProviderBuilder(); + if (tracingEnabled) + { + traceProviderBuilder.AddInMemoryExporter(activities) + .AddSqlClientInstrumentation(options => + { + options.SetDbStatementForText = captureText; + options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; + options.EmitOldAttributes = emitOldAttributes; + options.EmitNewAttributes = emitNewAttributes; + }); + } + + var meterProviderBuilder = Sdk.CreateMeterProviderBuilder(); + + if (metricsEnabled) + { + meterProviderBuilder.AddInMemoryExporter(metrics) + .AddSqlClientInstrumentation(); + } + + using var traceProvider = traceProviderBuilder.Build(); + using var meterProvider = meterProviderBuilder.Build(); + + var objectId = Guid.NewGuid().GetHashCode(); var dataSource = "127.0.0.1\\instanceName,port"; - fakeSqlEventSource.WriteBeginExecuteEvent(objectId, dataSource, "master", commandType == CommandType.StoredProcedure ? commandText : string.Empty); - // success is stored in the first bit in compositeState 0b001 - var successFlag = !isFailure ? 1 : 0; + try + { + fakeSqlEventSource.WriteBeginExecuteEvent(objectId, dataSource, "master", commandType == CommandType.StoredProcedure ? commandText : string.Empty); - // isSqlException is stored in the second bit in compositeState 0b010 - var isSqlExceptionFlag = sqlExceptionNumber > 0 ? 2 : 0; + // success is stored in the first bit in compositeState 0b001 + var successFlag = !isFailure ? 1 : 0; - // synchronous state is stored in the third bit in compositeState 0b100 - var synchronousFlag = false ? 4 : 0; + // isSqlException is stored in the second bit in compositeState 0b010 + var isSqlExceptionFlag = sqlExceptionNumber > 0 ? 2 : 0; - var compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; + // synchronous state is stored in the third bit in compositeState 0b100 + var synchronousFlag = false ? 4 : 0; - fakeSqlEventSource.WriteEndExecuteEvent(objectId, compositeState, sqlExceptionNumber); - shutdownSignal.Dispose(); - Assert.Single(exportedItems); + var compositeState = successFlag | isSqlExceptionFlag | synchronousFlag; - var activity = exportedItems[0]; + fakeSqlEventSource.WriteEndExecuteEvent(objectId, compositeState, sqlExceptionNumber); + } + finally + { + traceProvider.Dispose(); + Assert.True(meterProvider.ForceFlush()); + } + + Activity? activity = null; + + if (tracingEnabled) + { + activity = Assert.Single(activities); + VerifyActivityData(commandText, captureText, isFailure, dataSource, activity, enableConnectionLevelAttributes, emitOldAttributes, emitNewAttributes); + } + + var dbClientOperationDurationMetrics = metrics + .Where(metric => metric.Name == "db.client.operation.duration") + .ToArray(); - VerifyActivityData(commandText, captureText, isFailure, dataSource, activity, enableConnectionLevelAttributes, emitOldAttributes, emitNewAttributes); + if (metricsEnabled) + { + var metric = Assert.Single(dbClientOperationDurationMetrics); + Assert.NotNull(metric); + Assert.Equal("s", metric.Unit); + Assert.Equal(MetricType.Histogram, metric.MetricType); + + var metricPoints = new List(); + foreach (var p in metric.GetMetricPoints()) + { + metricPoints.Add(p); + } + + var metricPoint = Assert.Single(metricPoints); + + if (activity != null) + { + var count = metricPoint.GetHistogramCount(); + var sum = metricPoint.GetHistogramSum(); + Assert.Equal(activity.Duration.TotalSeconds, sum); + } + } + else + { + Assert.Empty(dbClientOperationDurationMetrics); + } } [Theory] @@ -323,7 +392,6 @@ private static void VerifyActivityData( } #pragma warning disable SA1201 // Elements should appear in the correct order - // Helper interface to be able to have single test method for multiple EventSources, want to keep it close to the event sources themselves. private interface IFakeBehavingSqlEventSource : IDisposable #pragma warning restore SA1201 // Elements should appear in the correct order From 3c6cf48dce2415714f5518b5faa516d3d8e3da93 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Thu, 14 Nov 2024 14:19:48 -0800 Subject: [PATCH 1418/1499] Add .NET 9 in tests projects (#2313) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .github/workflows/Component.BuildTest.yml | 2 +- .github/workflows/ci.yml | 4 +- build/Common.nonprod.props | 5 +- ...nTelemetry.AotCompatibility.TestApp.csproj | 2 +- ...elemetry.Exporter.Geneva.Benchmarks.csproj | 1 - ...penTelemetry.Exporter.Geneva.Stress.csproj | 1 - ...OpenTelemetry.Exporter.Geneva.Tests.csproj | 1 - ...strumentation.AspNetCore.Benchmarks.csproj | 1 - ...ry.Instrumentation.AspNetCore.Tests.csproj | 9 +- .../RouteTests/README.net9.0.md | 654 ++++++++++++++++++ ...etry.Instrumentation.GrpcCore.Tests.csproj | 2 +- ...metry.Instrumentation.Process.Tests.csproj | 1 - ...metry.Instrumentation.Runtime.Tests.csproj | 1 - ...umentation.StackExchangeRedis.Tests.csproj | 2 +- .../OpenTelemetry.Resources.AWS.Tests.csproj | 2 +- 15 files changed, 671 insertions(+), 17 deletions(-) create mode 100644 test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net9.0.md diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index 803606e931..dc571bb118 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -22,7 +22,7 @@ on: required: false type: string tfm-list: - default: '[ "net462", "net8.0" ]' + default: '[ "net462", "net8.0", "net9.0" ]' required: false type: string test-case-filter: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c116d7d555..1557da70f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,7 +197,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.AspNetCore code-cov-name: Instrumentation.AspNetCore - tfm-list: '[ "net8.0" ]' + tfm-list: '[ "net8.0", "net9.0" ]' build-test-instrumentation-aws: needs: detect-changes @@ -279,7 +279,7 @@ jobs: with: project-name: OpenTelemetry.Instrumentation.EventCounters code-cov-name: Instrumentation.EventCounters - tfm-list: '[ "net8.0" ]' + tfm-list: '[ "net8.0", "net9.0" ]' build-test-instrumentation-grpccore: needs: detect-changes diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 57551d83b0..8e50abe1da 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -29,8 +29,9 @@ 8.0.1 [17.11.1,18.0) $(OpenTelemetryCoreLatestVersion) - net8.0 - net9.0;net8.0 + + net9.0;net8.0 + net8.0 [2.8.2,3.0) [2.9.0,3.0) [1.6.3,2.0) diff --git a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj index 10ec3c7e99..f033f77641 100644 --- a/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj +++ b/test/OpenTelemetry.AotCompatibility.TestApp/OpenTelemetry.AotCompatibility.TestApp.csproj @@ -2,7 +2,7 @@ Exe - $(TargetFrameworksForAotCompatibilityTests) + $(SupportedNetTargets) true false true diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj index 3a6871c3b7..6c83c7a14b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/OpenTelemetry.Exporter.Geneva.Benchmarks.csproj @@ -3,7 +3,6 @@ - $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Exe diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 435acd8b5d..d78dacb3e9 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -1,7 +1,6 @@ - $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Exe diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 31ae1a4442..2d51d7d2f1 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -3,7 +3,6 @@ - $(SupportedNetTargets) $(TargetFrameworks);net48;net472;net471;net47;net462 Unit test project for Geneva Exporters for OpenTelemetry. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj index 417dcde39a..f006beaa0b 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.csproj @@ -1,7 +1,6 @@ - $(SupportedNetTargets) Exe diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj index 05355921c1..11def19721 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/OpenTelemetry.Instrumentation.AspNetCore.Tests.csproj @@ -6,8 +6,13 @@ - - + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net9.0.md b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net9.0.md new file mode 100644 index 0000000000..0ae09e497a --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/README.net9.0.md @@ -0,0 +1,654 @@ +# Test results for ASP.NET Core 9 + +| http.route | App | Test Name | +| - | - | - | +| :broken_heart: | ConventionalRouting | [Root path](#conventionalrouting-root-path) | +| :broken_heart: | ConventionalRouting | [Non-default action with route parameter and query string](#conventionalrouting-non-default-action-with-route-parameter-and-query-string) | +| :broken_heart: | ConventionalRouting | [Non-default action with query string](#conventionalrouting-non-default-action-with-query-string) | +| :green_heart: | ConventionalRouting | [Not Found (404)](#conventionalrouting-not-found-404) | +| :green_heart: | ConventionalRouting | [Route template with parameter constraint](#conventionalrouting-route-template-with-parameter-constraint) | +| :green_heart: | ConventionalRouting | [Path that does not match parameter constraint](#conventionalrouting-path-that-does-not-match-parameter-constraint) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, default controller/action](#conventionalrouting-area-using-areaexists-default-controlleraction) | +| :broken_heart: | ConventionalRouting | [Area using `area:exists`, non-default action](#conventionalrouting-area-using-areaexists-non-default-action) | +| :broken_heart: | ConventionalRouting | [Area w/o `area:exists`, default controller/action](#conventionalrouting-area-wo-areaexists-default-controlleraction) | +| :green_heart: | AttributeRouting | [Default action](#attributerouting-default-action) | +| :green_heart: | AttributeRouting | [Action without parameter](#attributerouting-action-without-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter](#attributerouting-action-with-parameter) | +| :green_heart: | AttributeRouting | [Action with parameter before action name in template](#attributerouting-action-with-parameter-before-action-name-in-template) | +| :green_heart: | AttributeRouting | [Action invoked resulting in 400 Bad Request](#attributerouting-action-invoked-resulting-in-400-bad-request) | +| :broken_heart: | RazorPages | [Root path](#razorpages-root-path) | +| :broken_heart: | RazorPages | [Index page](#razorpages-index-page) | +| :broken_heart: | RazorPages | [Throws exception](#razorpages-throws-exception) | +| :green_heart: | RazorPages | [Static content](#razorpages-static-content) | +| :green_heart: | MinimalApi | [Action without parameter](#minimalapi-action-without-parameter) | +| :green_heart: | MinimalApi | [Action with parameter](#minimalapi-action-with-parameter) | +| :green_heart: | MinimalApi | [Action without parameter (MapGroup)](#minimalapi-action-without-parameter-mapgroup) | +| :green_heart: | MinimalApi | [Action with parameter (MapGroup)](#minimalapi-action-with-parameter-mapgroup) | +| :green_heart: | ExceptionMiddleware | [Exception Handled by Exception Handler Middleware](#exceptionmiddleware-exception-handled-by-exception-handler-middleware) | + +## ConventionalRouting: Root path + +```json +{ + "IdealHttpRoute": "ConventionalRoute/Default/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "Default" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with route parameter and query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter/2?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Non-default action with query string + +```json +{ + "IdealHttpRoute": "ConventionalRoute/ActionWithStringParameter/{id?}", + "ActivityDisplayName": "GET {controller=ConventionalRoute}/{action=Default}/{id?}", + "ActivityHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "MetricHttpRoute": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/ActionWithStringParameter?num=3", + "RoutePattern.RawText": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{controller=ConventionalRoute}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Not Found (404) + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/ConventionalRoute/NotFound", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Route template with parameter constraint + +```json +{ + "IdealHttpRoute": "SomePath/{id}/{num:int}", + "ActivityDisplayName": "GET SomePath/{id}/{num:int}", + "ActivityHttpRoute": "SomePath/{id}/{num:int}", + "MetricHttpRoute": "SomePath/{id}/{num:int}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/2", + "RoutePattern.RawText": "SomePath/{id}/{num:int}", + "IRouteDiagnosticsMetadata.Route": "SomePath/{id}/{num:int}", + "HttpContext.GetRouteData()": { + "controller": "ConventionalRoute", + "action": "ActionWithStringParameter", + "id": "SomeString", + "num": "2" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [ + "id", + "num" + ], + "ControllerActionDescriptor": { + "ControllerName": "ConventionalRoute", + "ActionName": "ActionWithStringParameter" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Path that does not match parameter constraint + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePath/SomeString/NotAnInt", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## ConventionalRouting: Area using `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/Default/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "action": "Default", + "area": "MyArea" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "Default" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area using `area:exists`, non-default action + +```json +{ + "IdealHttpRoute": "{area:exists}/ControllerForMyArea/NonDefault/{id?}", + "ActivityDisplayName": "GET {area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "ActivityHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "MetricHttpRoute": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MyArea/ControllerForMyArea/NonDefault", + "RoutePattern.RawText": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "IRouteDiagnosticsMetadata.Route": "{area:exists}/{controller=ControllerForMyArea}/{action=Default}/{id?}", + "HttpContext.GetRouteData()": { + "controller": "ControllerForMyArea", + "area": "MyArea", + "action": "NonDefault" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "ControllerForMyArea", + "ActionName": "NonDefault" + }, + "PageActionDescriptor": null + } + } +} +``` + +## ConventionalRouting: Area w/o `area:exists`, default controller/action + +```json +{ + "IdealHttpRoute": "SomePrefix/AnotherArea/Index/{id?}", + "ActivityDisplayName": "GET SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "ActivityHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "MetricHttpRoute": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/SomePrefix", + "RoutePattern.RawText": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "IRouteDiagnosticsMetadata.Route": "SomePrefix/{controller=AnotherArea}/{action=Index}/{id?}", + "HttpContext.GetRouteData()": { + "area": "AnotherArea", + "controller": "AnotherArea", + "action": "Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": null, + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AnotherArea", + "ActionName": "Index" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Default action + +```json +{ + "IdealHttpRoute": "AttributeRoute", + "ActivityDisplayName": "GET AttributeRoute", + "ActivityHttpRoute": "AttributeRoute", + "MetricHttpRoute": "AttributeRoute", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute", + "RoutePattern.RawText": "AttributeRoute", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute", + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action without parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get", + "ActivityDisplayName": "GET AttributeRoute/Get", + "ActivityHttpRoute": "AttributeRoute/Get", + "MetricHttpRoute": "AttributeRoute/Get", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get", + "RoutePattern.RawText": "AttributeRoute/Get", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/Get", + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get", + "Parameters": [], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter + +```json +{ + "IdealHttpRoute": "AttributeRoute/Get/{id}", + "ActivityDisplayName": "GET AttributeRoute/Get/{id}", + "ActivityHttpRoute": "AttributeRoute/Get/{id}", + "MetricHttpRoute": "AttributeRoute/Get/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/Get/12", + "RoutePattern.RawText": "AttributeRoute/Get/{id}", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/Get/{id}", + "HttpContext.GetRouteData()": { + "action": "Get", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/Get/{id}", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "Get" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action with parameter before action name in template + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/12/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "12" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## AttributeRouting: Action invoked resulting in 400 Bad Request + +```json +{ + "IdealHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityDisplayName": "GET AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "ActivityHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "MetricHttpRoute": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/AttributeRoute/NotAnInt/GetWithActionNameInDifferentSpotInTemplate", + "RoutePattern.RawText": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "IRouteDiagnosticsMetadata.Route": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "HttpContext.GetRouteData()": { + "action": "GetWithActionNameInDifferentSpotInTemplate", + "controller": "AttributeRoute", + "id": "NotAnInt" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "AttributeRoute/{id}/GetWithActionNameInDifferentSpotInTemplate", + "Parameters": [ + "id" + ], + "ControllerActionDescriptor": { + "ControllerName": "AttributeRoute", + "ActionName": "GetWithActionNameInDifferentSpotInTemplate" + }, + "PageActionDescriptor": null + } + } +} +``` + +## RazorPages: Root path + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/", + "RoutePattern.RawText": "", + "IRouteDiagnosticsMetadata.Route": "", + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Index page + +```json +{ + "IdealHttpRoute": "/Index", + "ActivityDisplayName": "GET Index", + "ActivityHttpRoute": "Index", + "MetricHttpRoute": "Index", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Index", + "RoutePattern.RawText": "Index", + "IRouteDiagnosticsMetadata.Route": "Index", + "HttpContext.GetRouteData()": { + "page": "/Index" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "Index", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/Index.cshtml", + "ViewEnginePath": "/Index" + } + } + } +} +``` + +## RazorPages: Throws exception + +```json +{ + "IdealHttpRoute": "/PageThatThrowsException", + "ActivityDisplayName": "GET PageThatThrowsException", + "ActivityHttpRoute": "PageThatThrowsException", + "MetricHttpRoute": "PageThatThrowsException", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/PageThatThrowsException", + "RoutePattern.RawText": "PageThatThrowsException", + "IRouteDiagnosticsMetadata.Route": "PageThatThrowsException", + "HttpContext.GetRouteData()": { + "page": "/PageThatThrowsException" + }, + "ActionDescriptor": { + "AttributeRouteInfo.Template": "PageThatThrowsException", + "Parameters": [], + "ControllerActionDescriptor": null, + "PageActionDescriptor": { + "RelativePath": "/Pages/PageThatThrowsException.cshtml", + "ViewEnginePath": "/PageThatThrowsException" + } + } + } +} +``` + +## RazorPages: Static content + +```json +{ + "IdealHttpRoute": "", + "ActivityDisplayName": "GET", + "ActivityHttpRoute": "", + "MetricHttpRoute": "", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/js/site.js", + "RoutePattern.RawText": null, + "IRouteDiagnosticsMetadata.Route": null, + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi", + "ActivityDisplayName": "GET /MinimalApi", + "ActivityHttpRoute": "/MinimalApi", + "MetricHttpRoute": "/MinimalApi", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi", + "RoutePattern.RawText": "/MinimalApi", + "IRouteDiagnosticsMetadata.Route": "/MinimalApi", + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter + +```json +{ + "IdealHttpRoute": "/MinimalApi/{id}", + "ActivityDisplayName": "GET /MinimalApi/{id}", + "ActivityHttpRoute": "/MinimalApi/{id}", + "MetricHttpRoute": "/MinimalApi/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApi/123", + "RoutePattern.RawText": "/MinimalApi/{id}", + "IRouteDiagnosticsMetadata.Route": "/MinimalApi/{id}", + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action without parameter (MapGroup) + +```json +{ + "IdealHttpRoute": "/MinimalApiUsingMapGroup/", + "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/", + "ActivityHttpRoute": "/MinimalApiUsingMapGroup/", + "MetricHttpRoute": "/MinimalApiUsingMapGroup/", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApiUsingMapGroup", + "RoutePattern.RawText": "/MinimalApiUsingMapGroup/", + "IRouteDiagnosticsMetadata.Route": "/MinimalApiUsingMapGroup/", + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` + +## MinimalApi: Action with parameter (MapGroup) + +```json +{ + "IdealHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "ActivityDisplayName": "GET /MinimalApiUsingMapGroup/{id}", + "ActivityHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "MetricHttpRoute": "/MinimalApiUsingMapGroup/{id}", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/MinimalApiUsingMapGroup/123", + "RoutePattern.RawText": "/MinimalApiUsingMapGroup/{id}", + "IRouteDiagnosticsMetadata.Route": "/MinimalApiUsingMapGroup/{id}", + "HttpContext.GetRouteData()": { + "id": "123" + }, + "ActionDescriptor": null + } +} +``` + +## ExceptionMiddleware: Exception Handled by Exception Handler Middleware + +```json +{ + "IdealHttpRoute": "/Exception", + "ActivityDisplayName": "GET /Exception", + "ActivityHttpRoute": "/Exception", + "MetricHttpRoute": "/Exception", + "RouteInfo": { + "HttpMethod": "GET", + "Path": "/Exception", + "RoutePattern.RawText": "/Exception", + "IRouteDiagnosticsMetadata.Route": "/Exception", + "HttpContext.GetRouteData()": {}, + "ActionDescriptor": null + } +} +``` diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index b18abc2f97..ae45b9c775 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -1,7 +1,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargets) diff --git a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj index 26e013afed..bae293c282 100644 --- a/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Process.Tests/OpenTelemetry.Instrumentation.Process.Tests.csproj @@ -1,7 +1,6 @@ - $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj index 3cf92d6f2b..68e46c3e90 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/OpenTelemetry.Instrumentation.Runtime.Tests.csproj @@ -1,7 +1,6 @@ - $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index 71ae753f08..a85616c632 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet9) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry StackExchangeRedis instrumentation. diff --git a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj index 8e2510fc3b..dc0a10ebc8 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj +++ b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargets) + $(SupportedNetTargetsWithoutNet9) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for AWS Detector for OpenTelemetry. From 37a80ca93d2e9c709e71f6c30c82000ceeb9c346 Mon Sep 17 00:00:00 2001 From: Yevhenii Solomchenko Date: Fri, 15 Nov 2024 13:46:59 +0100 Subject: [PATCH 1419/1499] [Instrumentation.Wcf] Add RecordException (#2271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/PublicAPI.Unshipped.txt | 2 ++ src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ .../Implementation/ClientChannelInstrumentation.cs | 9 ++++++--- .../Implementation/InstrumentedDuplexChannel.cs | 8 ++++---- .../Implementation/InstrumentedRequestChannel.cs | 12 ++++++------ src/OpenTelemetry.Instrumentation.Wcf/README.md | 12 ++++++++++++ .../WcfInstrumentationOptions.cs | 12 ++++++++++++ 7 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Unshipped.txt index 2d11286dca..158186f0f4 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.Wcf/.publicApi/PublicAPI.Unshipped.txt @@ -20,6 +20,8 @@ OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilte OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.IncomingRequestFilter.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.get -> System.Func? OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.OutgoingRequestFilter.set -> void +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.RecordException.get -> bool +OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.RecordException.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.get -> bool OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SetSoapMessageVersion.set -> void OpenTelemetry.Instrumentation.Wcf.WcfInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index e5e4f3a2b7..00310a2e3c 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -8,6 +8,10 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Added a `RecordException` property to specify if exceptions should be + recorded (defaults to `false`). This is only supported by client instrumentation. + ([#2271](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2271)) + ## 1.0.0-rc.18 Released 2024-Oct-28 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index f6d4b58058..c6e56f2b34 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -82,12 +82,10 @@ public static RequestTelemetryState BeforeSendRequest(Message request, Uri? remo }; } - public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? state) + public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? state, Exception? exception = null) { Guard.ThrowIfNull(state); - state.SuppressionScope?.Dispose(); - if (state.Activity is Activity activity) { if (activity.IsAllDataRequested) @@ -97,6 +95,11 @@ public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? #pragma warning disable CS0618 // Type or member is obsolete activity.SetStatus(Status.Error); #pragma warning restore CS0618 // Type or member is obsolete + + if (WcfInstrumentationActivitySource.Options!.RecordException && exception != null) + { + activity.AddException(exception); + } } if (reply != null) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs index d58157d836..3f1335f066 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedDuplexChannel.cs @@ -64,9 +64,9 @@ public void EndSend(IAsyncResult result) { this.Inner.EndSend(asyncResult.Inner); } - catch (Exception) + catch (Exception ex) { - ClientChannelInstrumentation.AfterRequestCompleted(null, asyncResult.TelemetryState); + ClientChannelInstrumentation.AfterRequestCompleted(null, asyncResult.TelemetryState, ex); throw; } } @@ -196,9 +196,9 @@ void ExecuteInChildContext(object? unused) { ExecutionContext.Run(executionContext, ExecuteInChildContext, null); } - catch (Exception) + catch (Exception ex) { - ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState, ex); throw; } } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs index 30c245cc91..7d875f224a 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedRequestChannel.cs @@ -30,9 +30,9 @@ Message IRequestChannel.Request(Message message) { reply = this.Inner.Request(message); } - catch (Exception) + catch (Exception ex) { - ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState, ex); throw; } @@ -50,9 +50,9 @@ Message IRequestChannel.Request(Message message, TimeSpan timeout) { reply = this.Inner.Request(message, timeout); } - catch (Exception) + catch (Exception ex) { - ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState); + ClientChannelInstrumentation.AfterRequestCompleted(null, telemetryState, ex); throw; } @@ -86,9 +86,9 @@ Message IRequestChannel.EndRequest(IAsyncResult result) { reply = this.Inner.EndRequest(asyncResult.Inner); } - catch (Exception) + catch (Exception ex) { - ClientChannelInstrumentation.AfterRequestCompleted(null, asyncResult.TelemetryState); + ClientChannelInstrumentation.AfterRequestCompleted(null, asyncResult.TelemetryState, ex); throw; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/README.md b/src/OpenTelemetry.Instrumentation.Wcf/README.md index 773a07ffcd..3a924ed9c5 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/README.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/README.md @@ -224,6 +224,18 @@ on the service contracts you want to instrument: } ``` +## Advanced configuration + +This instrumentation can be configured to change the default behavior by using +`WcfInstrumentationOptions`. + +### RecordException + +This instrumentation automatically sets Activity Status to Error if an unhandled +exception is thrown. Additionally, `RecordException` feature may be turned on, +to store the exception to the Activity itself as ActivityEvent. `RecordException` +is available only on the client side. + ## References * [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs index 2dd8484897..b876b873f4 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/WcfInstrumentationOptions.cs @@ -48,4 +48,16 @@ public class WcfInstrumentationOptions /// Gets or sets a value indicating whether or not the SOAP message version should be added as the tag. Default value: False. /// public bool SetSoapMessageVersion { get; set; } + + /// + /// Gets or sets a value indicating whether exception will be recorded + /// as an or not. Default value: . + /// + /// + /// For specification details see: . + /// + public bool RecordException { get; set; } } From cf9384a183bfeaf87d5861033974b6ed7fe8c019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 15 Nov 2024 06:15:19 -0700 Subject: [PATCH 1420/1499] [Instrumentation.StackExchangeRedis] Fix tests on .NET9 (#2327) --- .../RedisProfilerEntryToActivityConverterTests.cs | 2 +- ...penTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index bf67721ea8..d4d864cb48 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -104,7 +104,7 @@ public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() Assert.NotNull(result); Assert.NotNull(result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); -#if NET8_0 +#if NET Assert.Equal("FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); #else Assert.Equal("PreferMaster, FireAndForget, NoRedirect", result.GetTagValue(StackExchangeRedisConnectionInstrumentation.RedisFlagsKeyName)); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj index a85616c632..71ae753f08 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet9) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry StackExchangeRedis instrumentation. From 8a062aac842bc0c5d61ef8aac0b3822ed1833d6b Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Fri, 15 Nov 2024 14:46:00 -0800 Subject: [PATCH 1421/1499] [infra] Update .gitignore to ignore config files for Visual Studio Live Unit Testing (#2329) --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 21d9bcaff5..a4eed63c7b 100644 --- a/.gitignore +++ b/.gitignore @@ -142,6 +142,10 @@ _TeamCity* *.coverage *.coveragexml +# Visual Studio live unit testing config +*.lutconfig +*.lutignore + # NCrunch _NCrunch_* .*crunch*.local.xml From 32bc2ca106dbfbdaff374da630d85d75d936426f Mon Sep 17 00:00:00 2001 From: tchowice <136763937+tchowice@users.noreply.github.com> Date: Mon, 18 Nov 2024 02:44:08 -0800 Subject: [PATCH 1422/1499] [Instrumentation.AspNet] Fix multiple routes of same template in attribute-based routing (#2250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: Rasmus Kuusmann Co-authored-by: Yevhenii Solomchenko --- .../CHANGELOG.md | 4 +++ .../Implementation/HttpRequestRouteHelper.cs | 5 +++- .../HttpInListenerTests.cs | 1 + .../RouteTestHelper.cs | 27 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 316b980d59..9e73e645cd 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -9,6 +9,10 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Fixed an issue in ASP.NET instrumentation where route extraction failed for + attribute-based routing with multiple HTTP methods sharing the same route template. + ([#2250](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2250)) + ## 1.9.0-beta.1 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs index 982f1b09b7..43b50b7168 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs @@ -28,8 +28,11 @@ internal sealed class HttpRequestRouteHelper { // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. - if (msSubRoutes is Array attributeRouting && attributeRouting.Length == 1) + if (msSubRoutes is Array attributeRouting && attributeRouting.Length >= 1) { + // There could be more than one subroute, each with a different method. + // But the template is the same across them, so we simply take the template + // from the first route. var subRouteData = attributeRouting.GetValue(0); _ = this.routeFetcher.TryFetch(subRouteData, out var route); diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index b14a987eeb..973d106599 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -41,6 +41,7 @@ public enum QueryRedactionDisableBehavior [InlineData("https://localhost:443/about_attr_route/10", "https", "/about_attr_route/10", null, null, "localhost", 443, "HEAD", "HEAD", null, 2, "about_attr_route/{customerId}", "HEAD about_attr_route/{customerId}")] [InlineData("http://localhost:1880/api/weatherforecast", "http", "/api/weatherforecast", null, null, "localhost", 1880, "GET", "GET", null, 3, "api/{controller}/{id}", "GET api/{controller}/{id}")] [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 4, "subroute/{customerId}", "GET subroute/{customerId}")] + [InlineData("https://localhost:1843/subroute/10", "https", "/subroute/10", null, null, "localhost", 1843, "GET", "GET", null, 5, "subroute/{customerId}", "GET subroute/{customerId}")] [InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "/api/value")] // Request will be filtered [InlineData("http://localhost/api/value", "http", "/api/value", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, "{ThrowException}")] // Filter user code will throw an exception [InlineData("http://localhost/", "http", "/", null, null, "localhost", 80, "GET", "GET", null, 0, null, "GET", false, null, true, "System.InvalidOperationException")] // Test RecordException option diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs index cebdc04598..437e93bde8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/RouteTestHelper.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Net.Http; using System.Web; using System.Web.Routing; @@ -40,6 +41,32 @@ public static HttpContext BuildHttpContext(string url, int routeType, string? ro "MS_SubRoutes", value); break; + case 5: // Multi-method attribute routing WebAPI. + routeData = new RouteData(); + var httpMethods = new[] { HttpMethod.Get, HttpMethod.Put, HttpMethod.Delete }; + + var multiMethodSubroutes = httpMethods.Select(method => new + { + Route = new + { + RouteTemplate = routeTemplate, + DataTokens = new Dictionary + { + ["actions"] = new[] + { + new + { + SupportedHttpMethods = new[] { method }, + }, + }, + }, + }, + }).ToArray(); + + routeData.Values.Add( + "MS_SubRoutes", + multiMethodSubroutes); + break; default: throw new NotSupportedException(); } From d5b47cbcc65b03047f2adce5aeebce0737cb815a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 18 Nov 2024 04:22:00 -0700 Subject: [PATCH 1423/1499] [Resources.AWS] Execute tests against .NET9 (#2328) --- build/Common.nonprod.props | 1 - .../Http/ServerCertificateValidationProviderTests.cs | 11 ++++++++++- .../OpenTelemetry.Resources.AWS.Tests.csproj | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 8e50abe1da..54d1acd980 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -31,7 +31,6 @@ $(OpenTelemetryCoreLatestVersion) net9.0;net8.0 - net8.0 [2.8.2,3.0) [2.9.0,3.0) [1.6.3,2.0) diff --git a/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index c3164353be..7151659be8 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -23,7 +23,11 @@ public void TestValidCertificate() Assert.NotNull(serverCertificateValidationProvider); +#if NET9_0_OR_GREATER + var certificate = X509CertificateLoader.LoadCertificateFromFile(certificateUploader.FilePath); +#else var certificate = new X509Certificate2(certificateUploader.FilePath); +#endif X509Chain chain = new X509Chain(); chain.Build(certificate); @@ -65,7 +69,12 @@ public void TestCallbackWithNullChain() ServerCertificateValidationProvider.FromCertificateFile(certificateUploader.FilePath, NoopServerCertificateValidationEventSource.Instance); Assert.NotNull(serverCertificateValidationProvider); - Assert.False(serverCertificateValidationProvider.ValidationCallback(this, new X509Certificate2(certificateUploader.FilePath), null, default)); +#if NET9_0_OR_GREATER + var certificate = X509CertificateLoader.LoadCertificateFromFile(certificateUploader.FilePath); +#else + var certificate = new X509Certificate2(certificateUploader.FilePath); +#endif + Assert.False(serverCertificateValidationProvider.ValidationCallback(this, certificate, null, default)); } } diff --git a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj index dc0a10ebc8..8e2510fc3b 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj +++ b/test/OpenTelemetry.Resources.AWS.Tests/OpenTelemetry.Resources.AWS.Tests.csproj @@ -2,7 +2,7 @@ - $(SupportedNetTargetsWithoutNet9) + $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for AWS Detector for OpenTelemetry. From f596cfe3582ead71b551a801e1f83349c0a47812 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:27:09 -0600 Subject: [PATCH 1424/1499] [release] Prepare release Exporter.Geneva-1.10.0 (#2335) --- .../.publicApi/PublicAPI.Shipped.txt | 6 +++--- src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt index 437f3b1c4c..bd3ce78a85 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt @@ -46,13 +46,13 @@ override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Dispose(bool disposi override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposing) -> void override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! -static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 68287b629d..5635ffc0c0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0 + +Released 2024-Nov-18 + * Drop support for .NET 6 as this target is no longer supported. ([#2117](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2117)) From 91d8d2be4cccd37839401f03b99e18fb490da019 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:13:51 -0600 Subject: [PATCH 1425/1499] [release] Exporter.Geneva- stable release 1.10.0 updates (#2336) Co-authored-by: Mikel Blanchard --- .../CompatibilitySuppressions.xml | 14 -------------- .../OpenTelemetry.Exporter.Geneva.csproj | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml b/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml index 61ae99654f..8fd727b95e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml +++ b/src/OpenTelemetry.Exporter.Geneva/CompatibilitySuppressions.xml @@ -2,18 +2,4 @@ - - CP0008 - T:OpenTelemetry.Exporter.Geneva.EventNameExportMode - lib/net6.0/OpenTelemetry.Exporter.Geneva.dll - lib/netstandard2.0/OpenTelemetry.Exporter.Geneva.dll - true - - - CP0008 - T:OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode - lib/net6.0/OpenTelemetry.Exporter.Geneva.dll - lib/netstandard2.0/OpenTelemetry.Exporter.Geneva.dll - true - diff --git a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj index 2dc03114e3..f2e4eb3294 100644 --- a/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj +++ b/src/OpenTelemetry.Exporter.Geneva/OpenTelemetry.Exporter.Geneva.csproj @@ -12,7 +12,7 @@ $(NoWarn);SA1123;SA1310 Exporter.Geneva- - 1.9.0 + 1.10.0 From ad5d037a0b6b41f4f0c19983a6b2d4ebacddf1e5 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:22:48 -0600 Subject: [PATCH 1426/1499] [release] Prepare release Exporter.OneCollector-1.10.0 (#2337) Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Shipped.txt | 6 ++++++ .../.publicApi/PublicAPI.Unshipped.txt | 6 ------ src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt index 6a1052d181..cc960e02b3 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Shipped.txt @@ -26,6 +26,10 @@ OpenTelemetry.Exporter.OneCollector.OneCollectorExporterValidationException.OneC OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.get -> string! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventName.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventNamespace.get -> string! +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventNamespace.set -> void +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.EventFullNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary? +OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.EventFullNameMappings.set -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.OneCollectorLogExporterOptions() -> void OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.SerializationOptions.get -> OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions! OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterSerializationOptions @@ -39,6 +43,8 @@ OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureSerializationO OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.ConfigureTransportOptions(System.Action! configure) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetConnectionString(string! connectionString) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventName(string! defaultEventName) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventNamespace(string! defaultEventNamespace) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! +OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetEventFullNameMappings(System.Collections.Generic.IReadOnlyDictionary? eventFullNameMappings) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! OpenTelemetry.Logs.OneCollectorLoggerProviderBuilderExtensions OpenTelemetry.Logs.OneCollectorOpenTelemetryLoggerOptionsExtensions override sealed OpenTelemetry.Exporter.OneCollector.OneCollectorExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult diff --git a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt index 01debf0cc7..e69de29bb2 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OneCollector/.publicApi/PublicAPI.Unshipped.txt @@ -1,6 +0,0 @@ -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventNamespace.get -> string! -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.DefaultEventNamespace.set -> void -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.EventFullNameMappings.get -> System.Collections.Generic.IReadOnlyDictionary? -OpenTelemetry.Exporter.OneCollector.OneCollectorLogExporterOptions.EventFullNameMappings.set -> void -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetDefaultEventNamespace(string! defaultEventNamespace) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! -OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder.SetEventFullNameMappings(System.Collections.Generic.IReadOnlyDictionary? eventFullNameMappings) -> OpenTelemetry.Logs.OneCollectorLogExportProcessorBuilder! \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md index 877f084dd0..a133728124 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OneCollector/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0 + +Released 2024-Nov-18 + * Drop support for .NET 6 as this target is no longer supported. ([#2123](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2123)) From 3e8b607df06e47b902f3051f8a2cec850881b5e3 Mon Sep 17 00:00:00 2001 From: Mohamed Asaker Date: Mon, 18 Nov 2024 11:39:07 -0800 Subject: [PATCH 1427/1499] [Sampler.AWS] Wrapped root sampler with ParentBasedSampler (#2188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/PublicAPI.Unshipped.txt | 2 +- .../AWSXRayRemoteSamplerBuilder.cs | 8 +++-- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 +++ .../FallbackSampler.cs | 4 +-- .../SamplingRuleApplier.cs | 8 ++--- .../TestAWSXRayRemoteSampler.cs | 30 ++++++++++++------- 6 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Unshipped.txt index 063bdbf96d..96770ae2fa 100644 --- a/src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Sampler.AWS/.publicApi/PublicAPI.Unshipped.txt @@ -2,7 +2,7 @@ OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.Dispose() -> void OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder -OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler! +OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.Build() -> OpenTelemetry.Trace.Sampler! OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetEndpoint(string! endpoint) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder.SetPollingInterval(System.TimeSpan pollingInterval) -> OpenTelemetry.Sampler.AWS.AWSXRayRemoteSamplerBuilder! override OpenTelemetry.Sampler.AWS.AWSXRayRemoteSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs index 7d64254b7b..7f2ad35bee 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using OpenTelemetry.Resources; +using OpenTelemetry.Trace; namespace OpenTelemetry.Sampler.AWS; @@ -66,10 +67,11 @@ public AWSXRayRemoteSamplerBuilder SetEndpoint(string endpoint) /// /// Returns a with configuration of this builder. /// - /// an instance of . - public AWSXRayRemoteSampler Build() + /// an instance of . + public Trace.Sampler Build() { - return new AWSXRayRemoteSampler(this.resource, this.pollingInterval, this.endpoint, this.clock); + var rootSampler = new AWSXRayRemoteSampler(this.resource, this.pollingInterval, this.endpoint, this.clock); + return new ParentBasedSampler(rootSampler); } // This is intended for testing with a mock clock. diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 6c3514b50c..6a78f967c5 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -17,6 +17,10 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* `AWSXRayRemoteSamplerBuilder.Build()` now returns `ParentBasedSampler` which + which is of type `Sampler` instead of `AWSXRayRemoteSampler`. + ([#2188](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2188)) + ## 0.1.0-alpha.2 Released 2024-Sep-09 diff --git a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs index 356ecf4570..08d271cc49 100644 --- a/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs +++ b/src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs @@ -12,8 +12,8 @@ internal class FallbackSampler : Trace.Sampler public FallbackSampler(Clock clock) { - this.reservoirSampler = new ParentBasedSampler(new RateLimitingSampler(1, clock)); - this.fixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(0.05)); + this.reservoirSampler = new RateLimitingSampler(1, clock); + this.fixedRateSampler = new TraceIdRatioBasedSampler(0.05); } public override SamplingResult ShouldSample(in SamplingParameters samplingParameters) diff --git a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs index 73a59c17bf..2deb456fdd 100644 --- a/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs +++ b/src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs @@ -20,7 +20,7 @@ public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Stat { // Until calling GetSamplingTargets, the default is to borrow 1/s if reservoir size is // positive. - this.ReservoirSampler = new ParentBasedSampler(new RateLimitingSampler(1, this.Clock)); + this.ReservoirSampler = new RateLimitingSampler(1, this.Clock); this.Borrowing = true; } else @@ -30,7 +30,7 @@ public SamplingRuleApplier(string clientId, Clock clock, SamplingRule rule, Stat this.Borrowing = false; } - this.FixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(rule.FixedRate)); + this.FixedRateSampler = new TraceIdRatioBasedSampler(rule.FixedRate); // We either have no reservoir sampling or borrow until we get a quota so have no end time. this.ReservoirEndTime = DateTimeOffset.MaxValue; @@ -191,7 +191,7 @@ public SamplingStatisticsDocument Snapshot(DateTimeOffset now) public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOffset now) { var newFixedRateSampler = target.FixedRate != null - ? new ParentBasedSampler(new TraceIdRatioBasedSampler(target.FixedRate.Value)) + ? new TraceIdRatioBasedSampler(target.FixedRate.Value) : this.FixedRateSampler; Trace.Sampler newReservoirSampler = new AlwaysOffSampler(); @@ -199,7 +199,7 @@ public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOff if (target.ReservoirQuota != null && target.ReservoirQuotaTTL != null) { newReservoirSampler = target.ReservoirQuota > 0 - ? new ParentBasedSampler(new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock)) + ? new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock) : new AlwaysOffSampler(); newReservoirEndTime = this.Clock.ToDateTime(target.ReservoirQuotaTTL.Value); diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index e61cb76d31..5d0c0bbc04 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; +using System.Reflection; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using WireMock.RequestBuilders; @@ -18,27 +19,34 @@ public void TestSamplerWithConfiguration() { var pollingInterval = TimeSpan.FromSeconds(5); var endpoint = "http://localhost:3000"; - - var sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) + var parentBasedSampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()) .SetPollingInterval(pollingInterval) .SetEndpoint(endpoint) .Build(); - Assert.Equal(pollingInterval, sampler.PollingInterval); - Assert.Equal(endpoint, sampler.Endpoint); - Assert.NotNull(sampler.RulePollerTimer); - Assert.NotNull(sampler.Client); + FieldInfo? rootSamplerFieldInfo = typeof(ParentBasedSampler).GetField("rootSampler", BindingFlags.NonPublic | BindingFlags.Instance); + + var xraySampler = (AWSXRayRemoteSampler?)rootSamplerFieldInfo?.GetValue(parentBasedSampler); + + Assert.Equal(pollingInterval, xraySampler?.PollingInterval); + Assert.Equal(endpoint, xraySampler?.Endpoint); + Assert.NotNull(xraySampler?.RulePollerTimer); + Assert.NotNull(xraySampler?.Client); } [Fact] public void TestSamplerWithDefaults() { - var sampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); + var parentBasedSampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); + + FieldInfo? rootSamplerFieldInfo = typeof(ParentBasedSampler).GetField("rootSampler", BindingFlags.NonPublic | BindingFlags.Instance); + + var xraySampler = (AWSXRayRemoteSampler?)rootSamplerFieldInfo?.GetValue(parentBasedSampler); - Assert.Equal(TimeSpan.FromMinutes(5), sampler.PollingInterval); - Assert.Equal("http://localhost:2000", sampler.Endpoint); - Assert.NotNull(sampler.RulePollerTimer); - Assert.NotNull(sampler.Client); + Assert.Equal(TimeSpan.FromMinutes(5), xraySampler?.PollingInterval); + Assert.Equal("http://localhost:2000", xraySampler?.Endpoint); + Assert.NotNull(xraySampler?.RulePollerTimer); + Assert.NotNull(xraySampler?.Client); } [Fact(Skip = "Flaky test. Related issue: https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1219")] From 15190d0eca2647f1468c39f4943e2dea4ac546a8 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:57:13 -0600 Subject: [PATCH 1428/1499] [release] Exporter.OneCollector- stable release 1.10.0 updates (#2338) Co-authored-by: Mikel Blanchard --- .../CompatibilitySuppressions.xml | 14 -------------- .../OpenTelemetry.Exporter.OneCollector.csproj | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml b/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml index 9d4d66e28f..8fd727b95e 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml +++ b/src/OpenTelemetry.Exporter.OneCollector/CompatibilitySuppressions.xml @@ -2,18 +2,4 @@ - - CP0008 - T:OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType - lib/net6.0/OpenTelemetry.Exporter.OneCollector.dll - lib/netstandard2.1/OpenTelemetry.Exporter.OneCollector.dll - true - - - CP0008 - T:OpenTelemetry.Exporter.OneCollector.OneCollectorExporterSerializationExceptionStackTraceHandlingType - lib/net7.0/OpenTelemetry.Exporter.OneCollector.dll - lib/netstandard2.1/OpenTelemetry.Exporter.OneCollector.dll - true - diff --git a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj index 9057a060ab..6cc8264c49 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj +++ b/src/OpenTelemetry.Exporter.OneCollector/OpenTelemetry.Exporter.OneCollector.csproj @@ -13,7 +13,7 @@ this at the call site but there is a bug. This could possibly be cleaned up in the future (hopefully .NET 9) see https://github.com/dotnet/runtime/issues/92509 --> $(NoWarn);SYSLIB1100;SYSLIB1101 - 1.9.3 + 1.10.0 $(SystemTextJsonLatestNet6OutOfBandPkgVer) From a7d5aeb52349f5f7c0504898a748c6edcdfb3afb Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:38:41 -0800 Subject: [PATCH 1429/1499] [shared] Implement SQL sanitization for MSSQL (#2330) --- opentelemetry-dotnet-contrib.sln | 1 + src/Shared/SqlProcessor.cs | 234 ++++++++++++++++++ .../OpenTelemetry.Contrib.Shared.Tests.csproj | 8 + .../SqlProcessorTestCases.cs | 46 ++++ .../SqlProcessorTestCases.json | 128 ++++++++++ .../SqlProcessorTests.cs | 19 ++ 6 files changed, 436 insertions(+) create mode 100644 src/Shared/SqlProcessor.cs create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.json create mode 100644 test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTests.cs diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 6f378a2ab0..936e6672f8 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -261,6 +261,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs + src\Shared\SqlProcessor.cs = src\Shared\SqlProcessor.cs src\Shared\UriHelper.cs = src\Shared\UriHelper.cs EndProjectSection EndProject diff --git a/src/Shared/SqlProcessor.cs b/src/Shared/SqlProcessor.cs new file mode 100644 index 0000000000..2625a062b7 --- /dev/null +++ b/src/Shared/SqlProcessor.cs @@ -0,0 +1,234 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Text; + +namespace OpenTelemetry.Instrumentation; + +public static class SqlProcessor +{ + public static string GetSanitizedSql(string sql) + { + if (sql == null) + { + return string.Empty; + } + + var sb = new StringBuilder(capacity: sql.Length); + for (var i = 0; i < sql.Length; ++i) + { + if (SkipComment(sql, ref i)) + { + continue; + } + + if (SanitizeStringLiteral(sql, ref i) || + SanitizeHexLiteral(sql, ref i) || + SanitizeNumericLiteral(sql, ref i)) + { + sb.Append('?'); + continue; + } + + WriteToken(sql, ref i, sb); + } + + return sb.ToString(); + } + + private static bool SkipComment(string sql, ref int index) + { + var i = index; + var ch = sql[i]; + var length = sql.Length; + + // Scan past multi-line comment + if (ch == '/' && i + 1 < length && sql[i + 1] == '*') + { + for (i += 2; i < length; ++i) + { + ch = sql[i]; + if (ch == '*' && i + 1 < length && sql[i + 1] == '/') + { + i += 1; + break; + } + } + + index = i; + return true; + } + + // Scan past single-line comment + if (ch == '-' && i + 1 < length && sql[i + 1] == '-') + { + for (i += 2; i < length; ++i) + { + ch = sql[i]; + if (ch == '\r' || ch == '\n') + { + i -= 1; + break; + } + } + + index = i; + return true; + } + + return false; + } + + private static bool SanitizeStringLiteral(string sql, ref int index) + { + var ch = sql[index]; + if (ch == '\'') + { + var i = index + 1; + var length = sql.Length; + for (; i < length; ++i) + { + ch = sql[i]; + if (ch == '\'' && i + 1 < length && sql[i + 1] == '\'') + { + ++i; + continue; + } + + if (ch == '\'') + { + break; + } + } + + index = i; + return true; + } + + return false; + } + + private static bool SanitizeHexLiteral(string sql, ref int index) + { + var i = index; + var ch = sql[i]; + var length = sql.Length; + + if (ch == '0' && i + 1 < length && (sql[i + 1] == 'x' || sql[i + 1] == 'X')) + { + for (i += 2; i < length; ++i) + { + ch = sql[i]; + if (char.IsDigit(ch) || + ch == 'A' || ch == 'a' || + ch == 'B' || ch == 'b' || + ch == 'C' || ch == 'c' || + ch == 'D' || ch == 'd' || + ch == 'E' || ch == 'e' || + ch == 'F' || ch == 'f') + { + continue; + } + + i -= 1; + break; + } + + index = i; + return true; + } + + return false; + } + + private static bool SanitizeNumericLiteral(string sql, ref int index) + { + var i = index; + var ch = sql[i]; + var length = sql.Length; + + // Scan past leading sign + if ((ch == '-' || ch == '+') && i + 1 < length && (char.IsDigit(sql[i + 1]) || sql[i + 1] == '.')) + { + i += 1; + ch = sql[i]; + } + + // Scan past leading decimal point + var periodMatched = false; + if (ch == '.' && i + 1 < length && char.IsDigit(sql[i + 1])) + { + periodMatched = true; + i += 1; + ch = sql[i]; + } + + if (char.IsDigit(ch)) + { + var exponentMatched = false; + for (i += 1; i < length; ++i) + { + ch = sql[i]; + if (char.IsDigit(ch)) + { + continue; + } + + if (!periodMatched && ch == '.') + { + periodMatched = true; + continue; + } + + if (!exponentMatched && (ch == 'e' || ch == 'E')) + { + // Scan past sign in exponent + if (i + 1 < length && (sql[i + 1] == '-' || sql[i + 1] == '+')) + { + i += 1; + } + + exponentMatched = true; + continue; + } + + i -= 1; + break; + } + + index = i; + return true; + } + + return false; + } + + private static void WriteToken(string sql, ref int index, StringBuilder sb) + { + var i = index; + var ch = sql[i]; + + if (char.IsLetter(ch) || ch == '_') + { + for (; i < sql.Length; i++) + { + ch = sql[i]; + if (char.IsLetter(ch) || ch == '_' || char.IsDigit(ch)) + { + sb.Append(ch); + continue; + } + + break; + } + + i -= 1; + } + else + { + sb.Append(ch); + } + + index = i; + } +} diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj index 4762d556b8..e53431c07b 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj +++ b/test/OpenTelemetry.Contrib.Shared.Tests/OpenTelemetry.Contrib.Shared.Tests.csproj @@ -9,6 +9,7 @@ + @@ -23,6 +24,13 @@ + + + + + + SqlProcessorTestCases.json + diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs new file mode 100644 index 0000000000..f739683fdc --- /dev/null +++ b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs @@ -0,0 +1,46 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Reflection; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace OpenTelemetry.Instrumentation.Tests; + +public static class SqlProcessorTestCases +{ + private static readonly JsonSerializerOptions JsonSerializerOptions = new() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + Converters = { new JsonStringEnumConverter() }, + }; + + public static IEnumerable GetTestCases() + { + var assembly = Assembly.GetExecutingAssembly(); + var input = JsonSerializer.Deserialize( + assembly.GetManifestResourceStream("SqlProcessorTestCases.json")!, + JsonSerializerOptions)!; + + foreach (var testCase in input) + { + yield return new object[] { testCase }; + } + } + + public class TestCase + { + public string Name { get; set; } = string.Empty; + + public string Sql { get; set; } = string.Empty; + + public string Sanitized { get; set; } = string.Empty; + + public IEnumerable Dialects { get; set; } = []; + + public override string ToString() + { + return this.Name; + } + } +} diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.json b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.json new file mode 100644 index 0000000000..4971427b94 --- /dev/null +++ b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.json @@ -0,0 +1,128 @@ +[ + { + "name": "numeric_literal_integers", + "sql": "SELECT 12, -12, +12", + "sanitized": "SELECT ?, ?, ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "numeric_literal_with_decimal_point", + "sql": "SELECT 12.34, -12.34, +12.34, .01, -.01", + "sanitized": "SELECT ?, ?, ?, ?, ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "numeric_literal_exponential", + "sql": "SELECT 12.34e56, -12.34e56, +12.34e56", + "sanitized": "SELECT ?, ?, ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "numeric_literal_negative_exponential", + "sql": "SELECT 12.34e-56, -12.34e-56, +12.34e-56", + "sanitized": "SELECT ?, ?, ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "hex_literal", + "sql": "SELECT 0xDEADBEEF, 0XdeadBEEF", + "sanitized": "SELECT ?, ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "string_literal", + "sql": "SELECT 'hello'", + "sanitized": "SELECT ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "string_literal_escaped_single_quote", + "sql": "SELECT 'My name''s not important'", + "sanitized": "SELECT ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "string_with_embedded_newline", + "sql": "SELECT 'My name is \n not important'", + "sanitized": "SELECT ?", + "dialects": [ + "mssql" + ] + }, + { + "name": "numbers_in_identifiers", + "sql": "SELECT c3po, r2d2 FROM covid19 WHERE n1h1=1234", + "sanitized": "SELECT c3po, r2d2 FROM covid19 WHERE n1h1=?", + "dialects": [ + "mssql" + ] + }, + { + "name": "periods_in_identifiers", + "sql": "SELECT a FROM dbo.Table JOIN dbo.AnotherTable", + "sanitized": "SELECT a FROM dbo.Table JOIN dbo.AnotherTable", + "dialects": [ + "mssql" + ] + }, + { + "name": "insert_into", + "sql": "INSERT INTO X VALUES(1, 23456, 123.456, 99+100)", + "sanitized": "INSERT INTO X VALUES(?, ?, ?, ??)", + "dialects": [ + "mssql" + ], + "comments": [ + "The following may also be acceptable but would require", + "recognizing expressions", + "INSERT INTO X VALUES(?, ?, ?, ?+?)" + ] + }, + { + "name": "uuid", + "sql": "SELECT { guid '01234567-89ab-cdef-0123-456789abcdef' }", + "sanitized": "SELECT { guid ? }", + "dialects": [ + "mssql" + ], + "comments": [ + "The following may be preferable", + "SELECT ?" + ] + }, + { + "name": "in_clause", + "sql": "SELECT * FROM table WHERE value IN (123, 456, 'abc')", + "sanitized": "SELECT * FROM table WHERE value IN (?, ?, ?)", + "dialects": [ + "mssql" + ], + "comments": [ + "The following is allowed by the spec", + "but not required", + "SELECT * FROM table WHERE value IN (?)" + ] + }, + { + "name": "comments", + "sql": "SELECT column -- end of line comment\nFROM /* block \n comment */ table", + "sanitized": "SELECT column \nFROM table", + "dialects": [ + "mssql" + ] + } +] diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTests.cs new file mode 100644 index 0000000000..e6d1a4640d --- /dev/null +++ b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTests.cs @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Xunit; + +namespace OpenTelemetry.Instrumentation.Tests; + +public class SqlProcessorTests +{ + public static IEnumerable TestData => SqlProcessorTestCases.GetTestCases(); + + [Theory] + [MemberData(nameof(TestData))] + public void TestGetSanitizedSql(SqlProcessorTestCases.TestCase test) + { + var sanitized = SqlProcessor.GetSanitizedSql(test.Sql); + Assert.Equal(test.Sanitized, sanitized); + } +} From 85afc5dd1bd7deef9b8949f36a14cd3fd1aacecb Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:15:37 -0800 Subject: [PATCH 1430/1499] [repo] Update GenevaExporter component owners (#2340) --- .github/component_owners.yml | 4 ---- src/OpenTelemetry.Exporter.Geneva/README.md | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/component_owners.yml b/.github/component_owners.yml index 683e7520e7..cbd6deb94c 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -7,7 +7,6 @@ components: - cijothomas - codeblanch - rajkumar-rangaraj - - utpilla src/OpenTelemetry.Exporter.InfluxDB/: - havret src/OpenTelemetry.Exporter.Instana/: @@ -93,17 +92,14 @@ components: - cijothomas - codeblanch - rajkumar-rangaraj - - utpilla test/OpenTelemetry.Exporter.Geneva.Stress/: - cijothomas - codeblanch - rajkumar-rangaraj - - utpilla test/OpenTelemetry.Exporter.Geneva.Tests/: - cijothomas - codeblanch - rajkumar-rangaraj - - utpilla test/OpenTelemetry.Exporter.InfluxDB.Tests/: - havret test/OpenTelemetry.Exporter.Instana.Tests/: diff --git a/src/OpenTelemetry.Exporter.Geneva/README.md b/src/OpenTelemetry.Exporter.Geneva/README.md index c61e7c16ce..1b20d17059 100644 --- a/src/OpenTelemetry.Exporter.Geneva/README.md +++ b/src/OpenTelemetry.Exporter.Geneva/README.md @@ -3,7 +3,7 @@ | Status | | | ------------- |-----------| | Stability | [Stable](../../README.md#stable)| -| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/), [@utpilla](https://github.com/utpilla)| +| Code Owners | [@cijothomas](https://github.com/cijothomas), [@codeblanch](https://github.com/codeblanch), [@rajkumar-rangaraj](https://github.com/rajkumar-rangaraj/)| [![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Geneva)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Geneva) From a0c764e763966dc665a4188262260fce3f0e9bb1 Mon Sep 17 00:00:00 2001 From: xiang17 Date: Thu, 21 Nov 2024 03:36:08 -0800 Subject: [PATCH 1431/1499] [Instrumentation.Runtime] Remove legacy checks that only applied for .NET 6 (#2325) --- .../CHANGELOG.md | 3 +- .../RuntimeMetrics.cs | 119 +++++++----------- .../RuntimeMetricsTests.cs | 11 +- 3 files changed, 54 insertions(+), 79 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 069bc27ee2..65731d372b 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -3,7 +3,8 @@ ## Unreleased * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. - ([#2155](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2155)) + ([#2155](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2155)), + ([#2325](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2325)) * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs index a67f264633..d66dc2ca30 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/RuntimeMetrics.cs @@ -58,82 +58,59 @@ static RuntimeMetrics() unit: "bytes", description: "The amount of committed virtual memory for the managed GC heap, as observed during the latest garbage collection. Committed virtual memory may be larger than the heap size because it includes both memory for storing existing objects (the heap size) and some extra memory that is ready to handle newly allocated objects in the future. The value will be unavailable until at least one garbage collection has occurred."); - // GC.GetGCMemoryInfo().GenerationInfo[i].SizeAfterBytes is better but it has a bug in .NET 6. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 - Func? getGenerationSize = null; - var isCodeRunningOnBuggyRuntimeVersion = Environment.Version.Major == 6; - if (isCodeRunningOnBuggyRuntimeVersion) - { - var mi = typeof(GC).GetMethod("GetGenerationSize", BindingFlags.NonPublic | BindingFlags.Static); - if (mi != null) + MeterInstance.CreateObservableUpDownCounter( + "process.runtime.dotnet.gc.heap.size", + () => { - getGenerationSize = mi.CreateDelegate>(); - } - } - - // Either Environment.Version is not 6 or (it's 6 but internal API GC.GetGenerationSize is valid) - if (!isCodeRunningOnBuggyRuntimeVersion || getGenerationSize != null) - { - MeterInstance.CreateObservableUpDownCounter( - "process.runtime.dotnet.gc.heap.size", - () => + if (!IsGcInfoAvailable) { - if (!IsGcInfoAvailable) - { - return []; - } - - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - var measurements = new Measurement[generationInfo.Length]; - var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (var i = 0; i < maxSupportedLength; ++i) - { - measurements[i] = isCodeRunningOnBuggyRuntimeVersion - ? new((long)getGenerationSize!(i), new KeyValuePair("generation", GenNames[i])) - : new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); - } - - return measurements; - }, - unit: "bytes", - description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); - } + return []; + } - if (Environment.Version.Major >= 7) - { - // Not valid until .NET 7 where the bug in the API is fixed. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/496 - MeterInstance.CreateObservableUpDownCounter( - "process.runtime.dotnet.gc.heap.fragmentation.size", - () => + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + var measurements = new Measurement[generationInfo.Length]; + var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (var i = 0; i < maxSupportedLength; ++i) { - if (!IsGcInfoAvailable) - { - return []; - } - - var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; - var measurements = new Measurement[generationInfo.Length]; - var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); - for (var i = 0; i < maxSupportedLength; ++i) - { - measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); - } - - return measurements; - }, - unit: "bytes", - description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); - - // GC.GetTotalPauseDuration() is not available until .NET 7. See context in https://github.com/open-telemetry/opentelemetry-dotnet-contrib/issues/1163 - var mi = typeof(GC).GetMethod("GetTotalPauseDuration", BindingFlags.Public | BindingFlags.Static); - var getTotalPauseDuration = mi?.CreateDelegate>(); - if (getTotalPauseDuration != null) + measurements[i] = new(generationInfo[i].SizeAfterBytes, new KeyValuePair("generation", GenNames[i])); + } + + return measurements; + }, + unit: "bytes", + description: "The heap size (including fragmentation), as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + + MeterInstance.CreateObservableUpDownCounter( + "process.runtime.dotnet.gc.heap.fragmentation.size", + () => { - MeterInstance.CreateObservableCounter( - "process.runtime.dotnet.gc.duration", - () => getTotalPauseDuration().Ticks * NanosecondsPerTick, - unit: "ns", - description: "The total amount of time paused in GC since the process start."); - } + if (!IsGcInfoAvailable) + { + return []; + } + + var generationInfo = GC.GetGCMemoryInfo().GenerationInfo; + var measurements = new Measurement[generationInfo.Length]; + var maxSupportedLength = Math.Min(generationInfo.Length, GenNames.Length); + for (var i = 0; i < maxSupportedLength; ++i) + { + measurements[i] = new(generationInfo[i].FragmentationAfterBytes, new KeyValuePair("generation", GenNames[i])); + } + + return measurements; + }, + unit: "bytes", + description: "The heap fragmentation, as observed during the latest garbage collection. The value will be unavailable until at least one garbage collection has occurred."); + + var mi = typeof(GC).GetMethod("GetTotalPauseDuration", BindingFlags.Public | BindingFlags.Static); + var getTotalPauseDuration = mi?.CreateDelegate>(); + if (getTotalPauseDuration != null) + { + MeterInstance.CreateObservableCounter( + "process.runtime.dotnet.gc.duration", + () => getTotalPauseDuration().Ticks * NanosecondsPerTick, + unit: "ns", + description: "The total amount of time paused in GC since the process start."); } MeterInstance.CreateObservableCounter( diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index 877c3a4d52..f9f0bc34d1 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -70,14 +70,11 @@ public void GcMetricsTest() var gcHeapSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.size"); Assert.NotNull(gcHeapSizeMetric); - if (Environment.Version.Major >= 7) - { - var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); - Assert.NotNull(gcHeapFragmentationSizeMetric); + var gcHeapFragmentationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.heap.fragmentation.size"); + Assert.NotNull(gcHeapFragmentationSizeMetric); - var gcDurationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.duration"); - Assert.NotNull(gcDurationMetric); - } + var gcDurationMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.duration"); + Assert.NotNull(gcDurationMetric); #endif } From 07f634d82f5f274d95a6dd479248fdc54cb3558d Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Fri, 22 Nov 2024 07:17:26 +0000 Subject: [PATCH 1432/1499] [Instrumentation.Runtime] Prefer the built-in runtime metrics for .NET 9 targets. (#2339) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz Co-authored-by: xiang17 --- .../CHANGELOG.md | 4 ++ .../MeterProviderBuilderExtensions.cs | 8 ++++ ...enTelemetry.Instrumentation.Runtime.csproj | 2 +- .../README.md | 6 +++ .../RuntimeMetricsTests.cs | 42 ++++++++++++++++++- 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index 65731d372b..eaeddeec72 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -9,6 +9,10 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Built-in .NET `System.Runtime` metrics are reported for .NET 9 and greater. + For details about each individual metric check [.NET Runtime metrics docs page](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/built-in-metrics-runtime). + ([#2339](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2339)) + ## 1.9.0 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs index 70959d119c..2a9e3c9e7c 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Runtime/MeterProviderBuilderExtensions.cs @@ -11,6 +11,9 @@ namespace OpenTelemetry.Metrics; /// public static class MeterProviderBuilderExtensions { + private const string DotNetRuntimeMeterName = "System.Runtime"; + private static readonly bool Net9OrGreater = Environment.Version.Major >= 9; + /// /// Enables runtime instrumentation. /// @@ -32,6 +35,11 @@ public static MeterProviderBuilder AddRuntimeInstrumentation( { Guard.ThrowIfNull(builder); + if (Net9OrGreater) + { + return builder.AddMeter(DotNetRuntimeMeterName); + } + var options = new RuntimeInstrumentationOptions(); configure?.Invoke(options); diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 8f107f48b5..8f349f186a 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -14,8 +14,8 @@ - + diff --git a/src/OpenTelemetry.Instrumentation.Runtime/README.md b/src/OpenTelemetry.Instrumentation.Runtime/README.md index 23e7717842..4120618f70 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/README.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/README.md @@ -48,6 +48,12 @@ to the application. ## Metrics +> [!NOTE] +> .NET 9 introduced built-in runtime metrics. As such, when applications target + .NET 9 or greater this package registers a `Meter` to receive the built-in + `System.Runtime` metrics. See the [.NET Runtime metrics documentation](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/built-in-metrics-runtime) + for details of the metric and attribute names for the built-in metrics. + ### GC related metrics #### process.runtime.dotnet.**gc.collections.count** diff --git a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs index f9f0bc34d1..a4d50c88ac 100644 --- a/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs +++ b/test/OpenTelemetry.Instrumentation.Runtime.Tests/RuntimeMetricsTests.cs @@ -32,12 +32,21 @@ public void RuntimeMetricsAreCaptured() meterProvider.ForceFlush(MaxTimeToAllowForFlush); Assert.True(exportedItems.Count > 1); +#if NET9_0_OR_GREATER + var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.assembly.count"); + Assert.NotNull(assembliesCountMetric); + + var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.exceptions"); + Assert.NotNull(exceptionsCountMetric); + Assert.True(GetValue(exceptionsCountMetric) >= 1); +#else var assembliesCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.assemblies.count"); Assert.NotNull(assembliesCountMetric); var exceptionsCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.exceptions.count"); Assert.NotNull(exceptionsCountMetric); Assert.True(GetValue(exceptionsCountMetric) >= 1); +#endif } [Fact] @@ -53,13 +62,23 @@ public void GcMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); +#if NET9_0_OR_GREATER + // We don't need to test all metrics here as those are tested in the runtime. + // This is sufficient to validate that the runtime metrics are enabled. + var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.gc.collections"); + Assert.NotNull(gcCountMetric); + + var totalObjectsSize = exportedItems.FirstOrDefault(i => i.Name == "dotnet.gc.heap.total_allocated"); + Assert.NotNull(totalObjectsSize); +#else var gcCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.collections.count"); Assert.NotNull(gcCountMetric); var totalObjectsSize = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.objects.size"); Assert.NotNull(totalObjectsSize); +#endif -#if NET +#if NET8_0 var gcAllocationSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.gc.allocations.size"); Assert.NotNull(gcAllocationSizeMetric); @@ -90,6 +109,16 @@ public void JitRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); +#if NET9_0_OR_GREATER + var jitCompiledSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.jit.compiled_il.size"); + Assert.NotNull(jitCompiledSizeMetric); + + var jitMethodsCompiledCountMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.jit.compiled_methods"); + Assert.NotNull(jitMethodsCompiledCountMetric); + + var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.jit.compilation.time"); + Assert.NotNull(jitCompilationTimeMetric); +#else var jitCompiledSizeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.il_compiled.size"); Assert.NotNull(jitCompiledSizeMetric); @@ -98,6 +127,7 @@ public void JitRelatedMetricsTest() var jitCompilationTimeMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.jit.compilation_time"); Assert.NotNull(jitCompilationTimeMetric); +#endif } [Fact] @@ -121,6 +151,15 @@ public async Task ThreadingRelatedMetricsTest() meterProvider.ForceFlush(MaxTimeToAllowForFlush); +#if NET9_0_OR_GREATER + // We don't need to test all metrics here as those are tested in the runtime. + // This is sufficient to validate that the runtime metrics are enabled. + var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.monitor.lock_contentions"); + Assert.NotNull(lockContentionCountMetric); + + var threadCountMetric = exportedItems.FirstOrDefault(i => i.Name == "dotnet.thread_pool.thread.count"); + Assert.NotNull(threadCountMetric); +#else var lockContentionCountMetric = exportedItems.FirstOrDefault(i => i.Name == "process.runtime.dotnet.monitor.lock_contention.count"); Assert.NotNull(lockContentionCountMetric); @@ -163,6 +202,7 @@ static void TimerCallback(object? _) timers[i].Dispose(); } } +#endif } #endif From 739337fb598b8d130928afd0cd68e517b6dedd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 22 Nov 2024 19:46:17 +0100 Subject: [PATCH 1433/1499] [repo/OneCollector] Prepare to .NET9 (#2341) --- .../Internal/CallbackManager.cs | 9 ++- .../Internal/ConnectionStringParser.cs | 2 +- .../Internal/EventFullName.cs | 17 ++---- .../Internal/EventNameManager.cs | 21 ++++--- .../CommonSchemaJsonSerializationHelper.cs | 4 +- .../CommonSchemaJsonSerializationState.cs | 21 ++++--- .../CommonSchemaJsonSerializer.cs | 4 +- .../LogRecordCommonSchemaJsonSerializer.cs | 20 +++---- .../Sinks/WriteDirectlyToTransportSink.cs | 9 ++- .../Transports/HttpJsonPostTransport.cs | 2 +- .../Logs/OneCollectorLogExporterOptions.cs | 4 +- .../OneCollectorExporterTransportOptions.cs | 4 +- ...ecordCommonSchemaJsonHttpPostBenchmarks.cs | 41 ++++++-------- ...ommonSchemaJsonSerializationHelperTests.cs | 8 +-- ...CommonSchemaJsonSerializationStateTests.cs | 4 +- .../EventNameManagerTests.cs | 14 ++--- .../ExtensionFieldInformationManagerTests.cs | 2 +- .../HttpJsonPostTransportTests.cs | 20 ++++--- ...ogRecordCommonSchemaJsonSerializerTests.cs | 55 +++++++++++-------- .../OneCollectorLogExporterOptionsTests.cs | 8 +-- ...torLoggerProviderBuilderExtensionsTests.cs | 10 ++-- .../WriteDirectlyToTransportSinkTests.cs | 10 ++-- 22 files changed, 140 insertions(+), 149 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs index ad33c02d29..bf6cf39268 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/CallbackManager.cs @@ -9,10 +9,9 @@ internal sealed class CallbackManager : IDisposable where T : Delegate { private readonly object lockObject = new(); - private T? root; private bool disposed; - public T? Root { get => this.root; } + public T? Root { get; private set; } public IDisposable Add(T callback) { @@ -29,14 +28,14 @@ public IDisposable Add(T callback) } #endif - this.root = (T)Delegate.Combine(this.root, callback); + this.Root = (T)Delegate.Combine(this.Root, callback); } return new CallbackManagerRegistration(() => { lock (this.lockObject) { - this.root = (T?)Delegate.Remove(this.root, callback); + this.Root = (T?)Delegate.Remove(this.Root, callback); } }); } @@ -45,7 +44,7 @@ public void Dispose() { lock (this.lockObject) { - this.root = null; + this.Root = null; this.disposed = true; } } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs index 40e30d61db..d3de2b9ac4 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/ConnectionStringParser.cs @@ -53,7 +53,7 @@ public string? InstrumentationKey { get { - this.ParsedKeyValues.TryGetValue(nameof(this.InstrumentationKey), out string? instrumentationKey); + this.ParsedKeyValues.TryGetValue(nameof(this.InstrumentationKey), out var instrumentationKey); return instrumentationKey; } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs index 2023376f73..389236d398 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventFullName.cs @@ -40,16 +40,11 @@ public static bool TryParseFromMapping( } var parts = eventFullNameMapping!.Split('.'); - if (parts.Length > 1) - { - eventFullName = new( + eventFullName = parts.Length > 1 + ? new( string.Join(".", parts, 0, parts.Length - 1), - parts[parts.Length - 1]); - } - else - { - eventFullName = new(string.Empty, parts[0]); - } + parts[parts.Length - 1]) + : new(string.Empty, parts[0]); return true; } @@ -80,8 +75,8 @@ internal void Validate(string key) length += this.EventName.Length; - if (length < EventNameManager.MinimumEventFullNameLength - || length > EventNameManager.MaximumEventFullNameLength) + if (length is < EventNameManager.MinimumEventFullNameLength + or > EventNameManager.MaximumEventFullNameLength) { throw new OneCollectorExporterValidationException($"The event full name mapping value provided for key '{key}' is shorter or longer than what is allowed."); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs index 90a44634b2..2bef0e3473 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/EventNameManager.cs @@ -19,7 +19,6 @@ internal sealed class EventNameManager private readonly string defaultEventName; private readonly IReadOnlyDictionary? eventFullNameMappings; private readonly ResolvedEventFullName defaultEventFullName; - private readonly Hashtable eventNamespaceCache = new(StringComparer.OrdinalIgnoreCase); public EventNameManager( string defaultEventNamespace, @@ -44,7 +43,7 @@ public EventNameManager( } // Note: This is exposed for unit tests. - internal Hashtable EventNamespaceCache => this.eventNamespaceCache; + internal Hashtable EventNamespaceCache { get; } = new(StringComparer.OrdinalIgnoreCase); public static bool IsEventNamespaceValid(string eventNamespace) => EventNamespaceValidationRegex.IsMatch(eventNamespace); @@ -86,13 +85,13 @@ public ResolvedEventFullName ResolveEventFullName( ref eventNamespace!, ref eventName!); - byte[]? originalEventNamespaceBlob = !string.IsNullOrEmpty(originalEventNamespace) - && originalEventNamespace != eventNamespace + var originalEventNamespaceBlob = !string.IsNullOrEmpty(originalEventNamespace) + && originalEventNamespace != eventNamespace ? BuildEventFullName(string.Empty, originalEventNamespace!) : null; - byte[]? originalEventNameBlob = !string.IsNullOrEmpty(originalEventName) - && originalEventName != eventName + var originalEventNameBlob = !string.IsNullOrEmpty(originalEventName) + && originalEventName != eventName ? BuildEventFullName(string.Empty, originalEventName!) : null; @@ -136,15 +135,15 @@ private static byte[] BuildEventFullName(string eventNamespace, string eventName private static void WriteEventFullNameComponent(string component, Span destination, ref int cursor) { - char firstChar = component[0]; - if (firstChar >= 'a' && firstChar <= 'z') + var firstChar = component[0]; + if (firstChar is >= 'a' and <= 'z') { firstChar -= (char)32; } destination[cursor++] = (byte)firstChar; - for (int i = 1; i < component.Length; i++) + for (var i = 1; i < component.Length; i++) { destination[cursor++] = (byte)component[i]; } @@ -152,7 +151,7 @@ private static void WriteEventFullNameComponent(string component, Span des private Hashtable GetEventNameCacheForEventNamespace(string eventNamespace) { - var eventNamespaceCache = this.eventNamespaceCache; + var eventNamespaceCache = this.EventNamespaceCache; if (eventNamespaceCache[eventNamespace] is not Hashtable eventNameCacheForNamespace) { @@ -252,7 +251,7 @@ private byte[] ResolveEventNameRare( byte[] eventFullName; var finalEventFullNameLength = namespaceLength + eventName.Length; - if (finalEventFullNameLength < MinimumEventFullNameLength || finalEventFullNameLength > MaximumEventFullNameLength) + if (finalEventFullNameLength is < MinimumEventFullNameLength or > MaximumEventFullNameLength) { OneCollectorExporterEventSource.Log.EventFullNameDiscarded(eventNamespace, eventName); eventFullName = this.defaultEventFullName.EventFullName; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs index dd3e4a4539..89ab2d9d47 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationHelper.cs @@ -175,7 +175,7 @@ private static void SerializeMapValueToJson(IReadOnlyList destination = stackalloc char[MaximumStackAllocSizeInBytes / 2]; - if (spanFormattable.TryFormat(destination, out int charsWritten, string.Empty, CultureInfo.InvariantCulture)) + if (spanFormattable.TryFormat(destination, out var charsWritten, string.Empty, CultureInfo.InvariantCulture)) { writer.WriteStringValue(destination.Slice(0, charsWritten)); return; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs index 95f98513b3..a6a2c0d072 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializationState.cs @@ -16,7 +16,6 @@ internal sealed class CommonSchemaJsonSerializationState private readonly Dictionary keys = new(4, StringComparer.OrdinalIgnoreCase); private readonly List> allValues = new(16); private string itemType; - private int nextKeysToAllValuesLookupIndex; private KeyValueLookup[] keysToAllValuesLookup = new KeyValueLookup[4]; public CommonSchemaJsonSerializationState(string itemType, Utf8JsonWriter writer) @@ -27,7 +26,7 @@ public CommonSchemaJsonSerializationState(string itemType, Utf8JsonWriter writer public Utf8JsonWriter Writer { get; private set; } - public int ExtensionPropertyCount => this.nextKeysToAllValuesLookupIndex; + public int ExtensionPropertyCount { get; private set; } public int ExtensionAttributeCount => this.allValues.Count; @@ -53,7 +52,7 @@ public void AddExtensionAttribute(KeyValuePair attribute) this.AssignNewExtensionToLookupIndex(ref lookupIndex); } #else - if (!this.keys.TryGetValue(fieldInformation!.ExtensionName!, out int lookupIndex)) + if (!this.keys.TryGetValue(fieldInformation!.ExtensionName!, out var lookupIndex)) { this.AssignNewExtensionToLookupIndex(ref lookupIndex); this.keys[fieldInformation.ExtensionName!] = lookupIndex; @@ -66,7 +65,7 @@ public void AddExtensionAttribute(KeyValuePair attribute) return; } - ref KeyValueLookup keyLookup = ref this.keysToAllValuesLookup[lookupIndex]; + ref var keyLookup = ref this.keysToAllValuesLookup[lookupIndex]; if (keyLookup.Count >= MaxNumberOfExtensionValuesPerKey) { @@ -74,7 +73,7 @@ public void AddExtensionAttribute(KeyValuePair attribute) return; } - int index = this.allValues.Count; + var index = this.allValues.Count; this.allValues.Add(new KeyValuePair(fieldInformation, attribute.Value)); unsafe @@ -102,9 +101,9 @@ public void SerializeExtensionPropertiesToJson(bool writeExtensionObjectEnvelope { var wroteStartObject = false; - ref KeyValueLookup keyLookup = ref this.keysToAllValuesLookup[extensionPropertyKey.Value]; + ref var keyLookup = ref this.keysToAllValuesLookup[extensionPropertyKey.Value]; - for (int i = 0; i < keyLookup.Count; i++) + for (var i = 0; i < keyLookup.Count; i++) { unsafe { @@ -151,13 +150,13 @@ public void BeginItem() return; } - for (int i = 0; i < this.nextKeysToAllValuesLookupIndex; i++) + for (var i = 0; i < this.ExtensionPropertyCount; i++) { ref var lookup = ref this.keysToAllValuesLookup[i]; lookup.Count = 0; } - this.nextKeysToAllValuesLookupIndex = 0; + this.ExtensionPropertyCount = 0; this.keys.Clear(); @@ -166,7 +165,7 @@ public void BeginItem() private void AssignNewExtensionToLookupIndex(ref int lookupIndex) { - lookupIndex = this.nextKeysToAllValuesLookupIndex; + lookupIndex = this.ExtensionPropertyCount; if (lookupIndex >= this.keysToAllValuesLookup.Length) { @@ -181,7 +180,7 @@ private void AssignNewExtensionToLookupIndex(ref int lookupIndex) this.keysToAllValuesLookup = newKeysToAllValuesLookup; } - this.nextKeysToAllValuesLookupIndex++; + this.ExtensionPropertyCount++; } private unsafe struct KeyValueLookup diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs index bcda85d369..6dd89e04a6 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/CommonSchemaJsonSerializer.cs @@ -120,7 +120,7 @@ protected static void SerializeResourceToJsonInsideCurrentObject(Resource resour if (resource!.Attributes is IReadOnlyList> resourceAttributeList) { - for (int i = 0; i < resourceAttributeList.Count; i++) + for (var i = 0; i < resourceAttributeList.Count; i++) { var resourceAttribute = resourceAttributeList[i]; @@ -135,7 +135,7 @@ protected static void SerializeResourceToJsonInsideCurrentObject(Resource resour } else { - foreach (KeyValuePair resourceAttribute in resource.Attributes) + foreach (var resourceAttribute in resource.Attributes) { if (AttributeKeyStartWithExtensionPrefix(resourceAttribute.Key)) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs index 519a5e1d2c..2398c20743 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Serialization/LogRecordCommonSchemaJsonSerializer.cs @@ -25,27 +25,27 @@ internal sealed class LogRecordCommonSchemaJsonSerializer : CommonSchemaJsonSeri private static readonly JsonEncodedText ExceptionExtensionMessageProperty = JsonEncodedText.Encode("msg"); private static readonly JsonEncodedText ExceptionExtensionStackTraceProperty = JsonEncodedText.Encode("stack"); - private static readonly JsonEncodedText[] LogLevelToSeverityTextMappings = new JsonEncodedText[] - { + private static readonly JsonEncodedText[] LogLevelToSeverityTextMappings = + [ JsonEncodedText.Encode("Trace"), JsonEncodedText.Encode("Debug"), JsonEncodedText.Encode("Information"), JsonEncodedText.Encode("Warning"), JsonEncodedText.Encode("Error"), JsonEncodedText.Encode("Critical"), - JsonEncodedText.Encode("Trace"), // Note: This is the "None" bucket. - }; + JsonEncodedText.Encode("Trace") // Note: This is the "None" bucket. + ]; - private static readonly int[] LogLevelToSeverityNumberMappings = new int[] - { - 1, 5, 9, 13, 17, 21, 1, - }; + private static readonly int[] LogLevelToSeverityNumberMappings = + [ + 1, 5, 9, 13, 17, 21, 1 + ]; private static readonly Action SerializeScopeItemToJson = (scope, serializationState) => { var writer = serializationState.Writer; - foreach (KeyValuePair scopeAttribute in scope) + foreach (var scopeAttribute in scope) { if (scopeAttribute.Key == "{OriginalFormat}") { @@ -150,7 +150,7 @@ protected override void SerializeItemToJson(Resource resource, LogRecord item, C if (item.Attributes != null) { - for (int i = 0; i < item.Attributes.Count; i++) + for (var i = 0; i < item.Attributes.Count; i++) { var attribute = item.Attributes[i]; diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs index 790c11c1c6..7309bed1d8 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Sinks/WriteDirectlyToTransportSink.cs @@ -12,7 +12,6 @@ internal sealed class WriteDirectlyToTransportSink : ISink, IDisposable { private readonly string typeName; private readonly ISerializer serializer; - private readonly MemoryStream buffer; public WriteDirectlyToTransportSink( ISerializer serializer, @@ -26,14 +25,14 @@ public WriteDirectlyToTransportSink( this.typeName = typeof(T).Name; this.serializer = serializer; this.Transport = transport; - this.buffer = new(initialBufferCapacity); + this.Buffer = new(initialBufferCapacity); } public string Description => "WriteDirectlyToTransportSink"; public ITransport Transport { get; } - internal MemoryStream Buffer => this.buffer; + internal MemoryStream Buffer { get; } public void Dispose() { @@ -46,7 +45,7 @@ public int Write(Resource resource, in Batch batch) var totalNumberOfItemsSerialized = 0; var totalNumberOfItemsDroppedDuringSerialization = 0; var totalNumberOfItemsDroppedDueToTransmissionFailure = 0; - var buffer = this.buffer; + var buffer = this.Buffer; ArraySegment remainingDataFromPreviousTransmission = default; var state = new BatchSerializationState(in batch); @@ -80,7 +79,7 @@ public int Write(Resource resource, in Batch batch) totalNumberOfItemsDroppedDuringSerialization += result.NumberOfItemsDropped; - int numberOfItemsSerialized = result.NumberOfItemsSerialized; + var numberOfItemsSerialized = result.NumberOfItemsSerialized; if (numberOfItemsSerialized > 0) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs index e590af68ef..b05070feef 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Internal/Transports/HttpJsonPostTransport.cs @@ -98,7 +98,7 @@ public bool Send(in TransportSendRequest sendRequest) request.Headers.TryAddWithoutValidation("sdk-version", SdkVersion); request.Headers.TryAddWithoutValidation("x-apikey", this.instrumentationKey); - bool infoLoggingEnabled = OneCollectorExporterEventSource.Log.IsInformationalLoggingEnabled(); + var infoLoggingEnabled = OneCollectorExporterEventSource.Log.IsInformationalLoggingEnabled(); if (!infoLoggingEnabled) { diff --git a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs index d57b42c7d2..83b5cdb8cf 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/Logs/OneCollectorLogExporterOptions.cs @@ -140,8 +140,8 @@ internal override void Validate() + this.DefaultEventNamespace.Length + (this.DefaultEventNamespace.Length > 0 ? 1 : 0); - if (defaultEventFullNameLength < EventNameManager.MinimumEventFullNameLength - || defaultEventFullNameLength > EventNameManager.MaximumEventFullNameLength) + if (defaultEventFullNameLength is < EventNameManager.MinimumEventFullNameLength + or > EventNameManager.MaximumEventFullNameLength) { throw new OneCollectorExporterValidationException($"{nameof(this.DefaultEventNamespace)} & {nameof(this.DefaultEventName)} specified on {nameof(OneCollectorLogExporterOptions)} options cannot be less than 4 characters or greater than 100 characters in length when combined."); } diff --git a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs index 28a14abb53..3e27f3df43 100644 --- a/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs +++ b/src/OpenTelemetry.Exporter.OneCollector/OneCollectorExporterTransportOptions.cs @@ -88,12 +88,12 @@ internal void Validate() throw new OneCollectorExporterValidationException($"{nameof(this.Endpoint)} was not specified on {this.GetType().Name} options."); } - if (this.MaxPayloadSizeInBytes <= 0 && this.MaxPayloadSizeInBytes != -1) + if (this.MaxPayloadSizeInBytes is <= 0 and not -1) { throw new OneCollectorExporterValidationException($"{nameof(this.MaxPayloadSizeInBytes)} was invalid on {this.GetType().Name} options."); } - if (this.MaxNumberOfItemsPerPayload <= 0 && this.MaxNumberOfItemsPerPayload != -1) + if (this.MaxNumberOfItemsPerPayload is <= 0 and not -1) { throw new OneCollectorExporterValidationException($"{nameof(this.MaxNumberOfItemsPerPayload)} was invalid on {this.GetType().Name} options."); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index bf43e78f38..8c0fa2529f 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -14,7 +14,9 @@ namespace OpenTelemetry.Exporter.OneCollector.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class LogRecordCommonSchemaJsonHttpPostBenchmarks +#pragma warning restore CA1515 { private static readonly MethodInfo LogRecordSetScopeProviderMethodInfo = typeof(LogRecord).GetProperty("ScopeProvider", BindingFlags.Instance | BindingFlags.NonPublic)?.SetMethod ?? throw new InvalidOperationException("LogRecord.ScopeProvider.Set could not be found reflectively."); @@ -36,7 +38,7 @@ public void GlobalSetup() { this.logRecords = new LogRecord[this.NumberOfLogRecordsPerBatch]; - for (int i = 0; i < this.NumberOfLogRecordsPerBatch; i++) + for (var i = 0; i < this.NumberOfLogRecordsPerBatch; i++) { this.logRecords[i] = CreateLogRecord(i); } @@ -82,7 +84,7 @@ public void GlobalCleanup() [Benchmark] public void Export() { - for (int i = 0; i < this.NumberOfBatches; i++) + for (var i = 0; i < this.NumberOfBatches; i++) { this.exporter!.Export(new Batch(this.logRecords!, this.logRecords!.Length)); } @@ -101,29 +103,25 @@ private static LogRecord CreateLogRecord(int index) if (index % 2 == 0) { - if (index % 4 == 0) - { - logRecord.EventId = new EventId(2, "MyEvent"); - } - else - { - logRecord.EventId = new EventId(1); - } + logRecord.EventId = index % 4 == 0 ? new EventId(2, "MyEvent") : new EventId(1); - logRecord.Attributes = new List> - { + logRecord.Attributes = + [ new KeyValuePair("userId", 18), new KeyValuePair("greeting", "hello world"), - new KeyValuePair("{OriginalFormat}", "Structured logging {userId} {greeting}"), - }; + new KeyValuePair("{OriginalFormat}", "Structured logging {userId} {greeting}") + ]; if (index % 3 == 0) { var scopeProvider = new ScopeProvider( - new List> { new KeyValuePair("scope1Key1", "scope1Value1"), new KeyValuePair("scope1Key2", "scope1Value2") }, - new List> { new KeyValuePair("scope2Key1", "scope2Value1") }); + [ + new KeyValuePair("scope1Key1", "scope1Value1"), + new KeyValuePair("scope1Key2", "scope1Value2") + ], + [new KeyValuePair("scope2Key1", "scope2Value1")]); - LogRecordSetScopeProviderMethodInfo.Invoke(logRecord, new object[] { scopeProvider }); + LogRecordSetScopeProviderMethodInfo.Invoke(logRecord, [scopeProvider]); } } else @@ -136,14 +134,7 @@ private static LogRecord CreateLogRecord(int index) logRecord.TraceId = ActivityTraceId.CreateRandom(); logRecord.SpanId = ActivitySpanId.CreateRandom(); - if (index % 6 == 0) - { - logRecord.TraceFlags = ActivityTraceFlags.None; - } - else - { - logRecord.TraceFlags = ActivityTraceFlags.Recorded; - } + logRecord.TraceFlags = index % 6 == 0 ? ActivityTraceFlags.None : ActivityTraceFlags.Recorded; } if (index % 9 == 0) diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs index 29431596de..a1130ef8cf 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationHelperTests.cs @@ -12,7 +12,7 @@ public class CommonSchemaJsonSerializationHelperTests [Fact] public void SerializeKeyValueToJsonTest() { - string actualJson = GetJson(key: "key1", value: "value1"); + var actualJson = GetJson(key: "key1", value: "value1"); Assert.Equal("\"key1\":\"value1\"", actualJson); } @@ -41,7 +41,7 @@ public void SerializeKeyValueToJsonTest() #endif public void SerializeValueToJsonTest(object? value, string expectedJson) { - string actualJson = GetJson(value); + var actualJson = GetJson(value); Assert.Equal(expectedJson, actualJson); } @@ -69,7 +69,7 @@ public void SerializeComplexValueToJsonTest() var array = new[] { 0, 1, 18 }; this.SerializeValueToJsonTest(array, "[0,1,18]"); - var listMap = new List> { new KeyValuePair("key1", "value1") }; + var listMap = new List> { new("key1", "value1") }; this.SerializeValueToJsonTest(listMap, "{\"key1\":\"value1\"}"); var dictMap = new Dictionary { ["key1"] = "value1" }; @@ -79,7 +79,7 @@ public void SerializeComplexValueToJsonTest() this.SerializeValueToJsonTest(typeWithToString, "\"Hello world\""); var typeWithThrowingToString = new TypeWithThrowingToString(); - this.SerializeValueToJsonTest(typeWithThrowingToString, $"\"ERROR: type {typeof(CommonSchemaJsonSerializationHelperTests).FullName}\\u002B{typeof(TypeWithThrowingToString).Name} is not supported\""); + this.SerializeValueToJsonTest(typeWithThrowingToString, $"\"ERROR: type {typeof(CommonSchemaJsonSerializationHelperTests).FullName}\\u002B{nameof(TypeWithThrowingToString)} is not supported\""); var ts = new TimeSpan(0, 10, 18, 59, 1); this.SerializeValueToJsonTest(ts, "\"10:18:59.0010000\""); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs index 6f87d12d02..d0ec17723c 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/CommonSchemaJsonSerializationStateTests.cs @@ -106,7 +106,7 @@ public void AddExtensionAttributeKeyLimitTest() var state = new CommonSchemaJsonSerializationState("Test", writer); - for (int i = 0; i < CommonSchemaJsonSerializationState.MaxNumberOfExtensionKeys + 10; i++) + for (var i = 0; i < CommonSchemaJsonSerializationState.MaxNumberOfExtensionKeys + 10; i++) { state.AddExtensionAttribute(new KeyValuePair($"ext.something{i}.field1", 1)); } @@ -123,7 +123,7 @@ public void AddExtensionAttributeKeyValueLimitTest() var state = new CommonSchemaJsonSerializationState("Test", writer); - for (int i = 0; i < CommonSchemaJsonSerializationState.MaxNumberOfExtensionValuesPerKey + 10; i++) + for (var i = 0; i < CommonSchemaJsonSerializationState.MaxNumberOfExtensionValuesPerKey + 10; i++) { state.AddExtensionAttribute(new KeyValuePair($"ext.something.field{i}", i)); } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs index 74e5d2c94c..53c8723f27 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/EventNameManagerTests.cs @@ -151,11 +151,10 @@ public void EventFullNameMappedUsingDefaultsWhenNoDefaultRuleDefinedTest(string { var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( defaultNamespace, - new KeyValuePair[] - { + [ new("MyNamespace1", "NewEventName1"), - new("MyNamespace2", "NewEventName2"), - }); + new("MyNamespace2", "NewEventName2") + ]); var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace", "MyEventName"); @@ -166,10 +165,9 @@ public void EventFullNameMappedUsingDefaultsWhenNoDefaultRuleDefinedTest(string public void EventFullNameMappedUsingPassthroughTest() { var eventNameManager = BuildEventNameManagerWithEventFullNameMappings( - new KeyValuePair[] - { - new("*", "*"), - }); + [ + new("*", "*") + ]); var resolveEventFullName = eventNameManager.ResolveEventFullName("MyNamespace", "MyEventName"); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs index 1229a65179..c7669f7db1 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/ExtensionFieldInformationManagerTests.cs @@ -68,7 +68,7 @@ public void FieldInformationCacheLimitTest() { var extensionFieldInformationManager = new ExtensionFieldInformationManager(); - for (int i = 0; i < ExtensionFieldInformationManager.MaxNumberOfCachedFieldInformations + 128; i++) + for (var i = 0; i < ExtensionFieldInformationManager.MaxNumberOfCachedFieldInformations + 128; i++) { var fieldName = $"fieldName{i}"; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs index aabe086eff..4d7d01f0d7 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/HttpJsonPostTransportTests.cs @@ -81,9 +81,9 @@ public void RegisterPayloadTransmittedCallbackTest() using var httpClient = new HttpClient(); - int lastCompletedIteration = -1; + var lastCompletedIteration = -1; IDisposable? callbackRegistration = null; - bool callbackFired = false; + var callbackFired = false; /* * This test runs a few different iterations... @@ -114,7 +114,7 @@ public void RegisterPayloadTransmittedCallbackTest() Assert.True(string.IsNullOrWhiteSpace(req.Headers["Content-Encoding"])); Assert.Equal(request, Encoding.ASCII.GetString(body.ToArray())); }, - shouldTestFailFunc: (iteration) => iteration == 4 || iteration == 5, + shouldTestFailFunc: (iteration) => iteration is 4 or 5, testStartingAction: (iteration, transport) => { switch (iteration) @@ -138,6 +138,8 @@ public void RegisterPayloadTransmittedCallbackTest() Assert.Null(callbackRegistration); callbackRegistration = transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted, includeFailures: true); break; + default: + break; } }, testFinishedAction: (iteration, transport) => @@ -169,6 +171,8 @@ public void RegisterPayloadTransmittedCallbackTest() Assert.Null(callbackRegistration); Assert.False(callbackFired); break; + default: + break; } callbackFired = false; @@ -213,7 +217,7 @@ public void RegisterPayloadTransmittedCallbackConnectionFailureTest() transport.RegisterPayloadTransmittedCallback(OnPayloadTransmitted, includeFailures: true); - bool callbackFired = false; + var callbackFired = false; var result = transport.Send( new TransportSendRequest @@ -342,8 +346,8 @@ private static void RunHttpServerTest( : null; shouldTestFailFunc ??= static iteration => false; - bool failTest = false; - bool requestReceivedAndAsserted = false; + var failTest = false; + var requestReceivedAndAsserted = false; Exception? testException = null; using var testServer = TestHttpServer.RunServer( @@ -351,7 +355,7 @@ private static void RunHttpServerTest( { context.Response.StatusCode = failTest ? 400 : 200; - using MemoryStream requestBody = new MemoryStream(); + using var requestBody = new MemoryStream(); context.Request.InputStream.CopyTo(requestBody); @@ -382,7 +386,7 @@ private static void RunHttpServerTest( { var requestBodyBytes = Encoding.ASCII.GetBytes(requestBody); - for (int i = 0; i < testIterations; i++) + for (var i = 0; i < testIterations; i++) { failTest = shouldTestFailFunc(i); diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs index 87d557461e..8df736a680 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/LogRecordCommonSchemaJsonSerializerTests.cs @@ -16,7 +16,7 @@ public class LogRecordCommonSchemaJsonSerializerTests [Fact] public void EmptyLogRecordJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => { }); + var json = GetLogRecordJson(1, (index, logRecord) => { }); Assert.Equal( """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n", @@ -26,7 +26,7 @@ public void EmptyLogRecordJsonTest() [Fact] public void MultipleEmptyLogRecordJsonTest() { - string json = GetLogRecordJson(2, (index, logRecord) => { }); + var json = GetLogRecordJson(2, (index, logRecord) => { }); Assert.Equal( """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1}}""" + "\n" @@ -44,7 +44,7 @@ public void MultipleEmptyLogRecordJsonTest() [InlineData(LogLevel.None, "Trace", 1)] public void LogRecordLogLevelJsonTest(LogLevel logLevel, string severityText, int severityNumber) { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { #pragma warning disable CS0618 // Type or member is obsolete // TODO: Update to use LogRecord.Severity @@ -62,7 +62,7 @@ public void LogRecordLogLevelJsonTest(LogLevel logLevel, string severityText, in [InlineData("MyClass.Company", "MyEvent")] public void LogRecordCategoryNameAndEventNameJsonTest(string categoryName, string? eventName) { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { logRecord.CategoryName = categoryName; logRecord.EventId = new(0, eventName); @@ -86,7 +86,7 @@ public void EventFullNameMappedJsonTest(string categoryName, string? eventName, { "MyClass", EventFullName.Create("MyDefaultEvent") }, }; - string json = GetLogRecordJson( + var json = GetLogRecordJson( 1, (index, logRecord) => { @@ -95,7 +95,7 @@ public void EventFullNameMappedJsonTest(string categoryName, string? eventName, }, eventFullNameMappings: eventFullNameMappings); - string expectedName = eventName == null + var expectedName = eventName == null ? string.Empty : $"\"name\":\"{eventName}\","; @@ -107,7 +107,7 @@ public void EventFullNameMappedJsonTest(string categoryName, string? eventName, [Fact] public void LogRecordEventIdJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { logRecord.EventId = new(18); }); @@ -120,7 +120,7 @@ public void LogRecordEventIdJsonTest() [Fact] public void LogRecordTimestampJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { logRecord.Timestamp = DateTime.SpecifyKind(new DateTime(2023, 1, 18, 10, 18, 0), DateTimeKind.Utc); }); @@ -133,9 +133,9 @@ public void LogRecordTimestampJsonTest() [Fact] public void LogRecordOriginalFormatBodyJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { - logRecord.Attributes = new List> { new KeyValuePair("{OriginalFormat}", "hello world") }; + logRecord.Attributes = [new KeyValuePair("{OriginalFormat}", "hello world")]; logRecord.FormattedMessage = "goodbye world"; }); @@ -147,7 +147,7 @@ public void LogRecordOriginalFormatBodyJsonTest() [Fact] public void LogRecordBodyJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { logRecord.Body = "hello world"; logRecord.FormattedMessage = "goodbye world"; @@ -161,7 +161,7 @@ public void LogRecordBodyJsonTest() [Fact] public void LogRecordFormattedMessageBodyJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { logRecord.FormattedMessage = "goodbye world"; }); @@ -182,7 +182,7 @@ public void LogRecordResourceJsonTest() }) .Build(); - string json = GetLogRecordJson(1, (index, logRecord) => { }, resource); + var json = GetLogRecordJson(1, (index, logRecord) => { }, resource); Assert.Equal( """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"resourceKey1":"resourceValue1","resourceKey2":"resourceValue2"}}""" + "\n", @@ -193,10 +193,13 @@ public void LogRecordResourceJsonTest() public void LogRecordScopesJsonTest() { var scopeProvider = new ScopeProvider( - new List> { new KeyValuePair("scope1Key1", "scope1Value1"), new KeyValuePair("scope1Key2", "scope1Value2") }, - new List> { new KeyValuePair("scope2Key1", "scope2Value1") }); + [ + new KeyValuePair("scope1Key1", "scope1Value1"), + new KeyValuePair("scope1Key2", "scope1Value2") + ], + [new KeyValuePair("scope2Key1", "scope2Value1")]); - string json = GetLogRecordJson(1, (index, logRecord) => { }, scopeProvider: scopeProvider); + var json = GetLogRecordJson(1, (index, logRecord) => { }, scopeProvider: scopeProvider); Assert.Equal( """{"ver":"4.0","name":"Namespace.Name","time":"2032-01-18T10:11:12Z","iKey":"o:tenant-token","data":{"severityText":"Trace","severityNumber":1,"scope1Key1":"scope1Value1","scope1Key2":"scope1Value2","scope2Key1":"scope2Value1"}}""" + "\n", @@ -206,9 +209,13 @@ public void LogRecordScopesJsonTest() [Fact] public void LogRecordStateValuesJsonTest() { - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { - logRecord.Attributes = new List> { new KeyValuePair("stateKey1", "stateValue1"), new KeyValuePair("stateKey2", "stateValue2") }; + logRecord.Attributes = + [ + new KeyValuePair("stateKey1", "stateValue1"), + new KeyValuePair("stateKey2", "stateValue2") + ]; }); Assert.Equal( @@ -222,7 +229,7 @@ public void LogRecordTraceContextJsonTest() var traceId = ActivityTraceId.CreateRandom(); var spanId = ActivitySpanId.CreateRandom(); - string json = GetLogRecordJson(1, (index, logRecord) => + var json = GetLogRecordJson(1, (index, logRecord) => { logRecord.TraceId = traceId; logRecord.SpanId = spanId; @@ -241,7 +248,7 @@ public void LogRecordTraceContextJsonTest() [InlineData(false)] public void LogRecordExceptionJsonTest(bool includeStackTraceAsString) { - string json = GetLogRecordJson( + var json = GetLogRecordJson( 1, (index, logRecord) => { @@ -264,7 +271,7 @@ public void LogRecordExceptionJsonTest(bool includeStackTraceAsString) public void LogRecordExtensionsJsonTest() { var scopeProvider = new ScopeProvider( - new List> { new KeyValuePair("ext.scope.field", "scopeValue1") }); + [new KeyValuePair("ext.scope.field", "scopeValue1")]); var resource = ResourceBuilder.CreateEmpty() .AddAttributes(new Dictionary @@ -273,11 +280,11 @@ public void LogRecordExtensionsJsonTest() }) .Build(); - string json = GetLogRecordJson( + var json = GetLogRecordJson( 2, (index, logRecord) => { - logRecord.Attributes = new List> { new KeyValuePair("ext.state.field", "stateValue1") }; + logRecord.Attributes = [new KeyValuePair("ext.state.field", "stateValue1")]; }, resource, scopeProvider); @@ -305,7 +312,7 @@ private static string GetLogRecordJson( var logRecords = new LogRecord[numberOfLogRecords]; - for (int i = 0; i < numberOfLogRecords; i++) + for (var i = 0; i < numberOfLogRecords; i++) { var logRecord = (LogRecord)Activator.CreateInstance(typeof(LogRecord), nonPublic: true)!; diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs index 6e52e8ea45..0ff041e465 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLogExporterOptionsTests.cs @@ -20,7 +20,7 @@ public void InvalidDefaultEventNamespaceTests(string? defaultEventNamespace) }; Assert.Throws( - () => options.Validate()); + options.Validate); } [Theory] @@ -54,7 +54,7 @@ public void InvalidDefaultEventNameTests(string? defaultEventName) }; Assert.Throws( - () => options.Validate()); + options.Validate); } [Theory] @@ -83,7 +83,7 @@ public void InvalidDefaultEventFullNameTests(string defaultEventNamespace, strin }; Assert.Throws( - () => options.Validate()); + options.Validate); } [Theory] @@ -129,7 +129,7 @@ public void InvalidEventFullNameMappingTests(string key, string? value) }; Assert.Throws( - () => options.Validate()); + options.Validate); } [Theory] diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs index 384f74ea70..01166308ae 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/OneCollectorLoggerProviderBuilderExtensionsTests.cs @@ -14,7 +14,7 @@ public class OneCollectorLoggerProviderBuilderExtensionsTests [Fact] public void ConfigureBatchOptionsTest() { - int configurationInvocations = 0; + var configurationInvocations = 0; using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter(builder => { @@ -52,7 +52,7 @@ static void OnPayloadTransmitted(in OneCollectorExporterPayloadTransmittedCallba [Fact] public void ConfigureSerializationOptionsTest() { - int configurationInvocations = 0; + var configurationInvocations = 0; using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter(builder => { @@ -67,7 +67,7 @@ public void ConfigureSerializationOptionsTest() [Fact] public void ConfigureTransportOptionsTest() { - int configurationInvocations = 0; + var configurationInvocations = 0; using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter(builder => { @@ -235,7 +235,7 @@ public void InstrumentationKeyAndTenantTokenValidationTest() [Fact] public void OptionsTest() { - int configurationInvocations = 0; + var configurationInvocations = 0; using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter( builder => @@ -261,7 +261,7 @@ public void OptionsTest() [Fact] public void NamedOptionsTest() { - int configurationInvocations = 0; + var configurationInvocations = 0; using var loggerFactory = CreateLoggerFactoryWithOneCollectorExporter( builder => diff --git a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs index 2eddb26112..6c7eea94dd 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Tests/WriteDirectlyToTransportSinkTests.cs @@ -113,11 +113,11 @@ public void PartialDataWrittenToTransport_MaxPayloadSize_Test() transport.ExportedData.Clear(); - items = new string[] - { + items = + [ "item4", - "item5", - }; + "item5" + ]; numberOfRecordsWritten = sink.Write(Resource.Empty, new(items, items.Length)); @@ -209,7 +209,7 @@ private sealed class TestTransport : ITransport { public string Description => nameof(TestTransport); - public List ExportedData { get; } = new(); + public List ExportedData { get; } = []; public IDisposable RegisterPayloadTransmittedCallback(OneCollectorExporterPayloadTransmittedCallbackAction callback, bool includeFailures) { From 7f52212dac9d621216f98c69ed97186fb50653c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 22 Nov 2024 20:47:30 +0100 Subject: [PATCH 1434/1499] [repo/Geneva] Prepare to .NET9 (#2342) --- .../GenevaExporterOptions.cs | 2 +- .../GenevaLogExporter.cs | 8 +- .../GenevaTraceExporter.cs | 8 +- .../Internal/ConnectionStringBuilder.cs | 82 ++------- .../Internal/MsgPack/MessagePackSerializer.cs | 19 +- .../Internal/MsgPack/MsgPackExporter.cs | 18 +- .../Internal/MsgPack/MsgPackLogExporter.cs | 64 ++++--- .../Internal/MsgPack/MsgPackTraceExporter.cs | 12 +- .../Internal/TableNameSerializer.cs | 44 ++--- .../Internal/Tld/JsonSerializer.cs | 28 ++- .../Internal/Tld/TldExporter.cs | 2 +- .../Internal/Tld/TldLogExporter.cs | 64 +++---- .../Internal/Tld/TldTraceExporter.cs | 23 +-- .../Internal/Tld/UncheckedASCIIEncoding.cs | 10 +- .../Internal/Transports/EtwDataTransport.cs | 4 +- .../Transports/UnixDomainSocketEndPoint.cs | 8 +- .../OtlpProtobuf/FieldNumberConstants.cs | 3 + .../OtlpProtobuf/OtlpProtobufSerializer.cs | 39 ++-- .../OtlpProtobuf/ProtobufSerializerHelper.cs | 8 +- .../Metrics/TlvMetricExporter.cs | 21 ++- .../MetricWindowsEventTracingDataTransport.cs | 2 +- .../Exporter/Food.cs | 2 +- .../Exporter/LogExporterBenchmarks.cs | 6 +- .../Exporter/MetricExporterBenchmarks.cs | 39 ++-- .../Exporter/SerializationBenchmarks.cs | 2 + .../Exporter/TLDLogExporterBenchmarks.cs | 25 +-- .../Exporter/TLDTraceExporterBenchmarks.cs | 4 +- .../Exporter/TraceExporterBenchmarks.cs | 4 +- .../Program.cs | 27 +-- .../GenevaLogExporterTests.cs | 125 ++++++------- .../GenevaMetricExporterTests.cs | 94 ++++------ .../GenevaTraceExporterTests.cs | 68 ++++--- .../JsonSerializerTests.cs | 58 +++--- .../LogSerializationTests.cs | 24 +-- .../MessagePackSerializerTests.cs | 34 ++-- .../OtlpProtobufMetricExporterTests.cs | 172 +++++++++--------- ...lpProtobufMetricExporterWithPrefixTests.cs | 2 + ...rotobufMetricExporterWithoutPrefixTests.cs | 2 + .../TableNameSerializerTests.cs | 4 +- .../UnixDomainSocketDataTransportTests.cs | 18 +- .../UnixDomainSocketEndPointTests.cs | 18 +- .../UnixUserEventsDataTransportTests.cs | 10 +- test/Shared/PlatformHelpers.cs | 4 +- 43 files changed, 540 insertions(+), 671 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs index 2d508399f4..94272f3b19 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterOptions.cs @@ -110,7 +110,7 @@ public IReadOnlyDictionary PrepopulatedFields schemaVersion = value[Schema.V40.PartA.Ver] as string; } - if (schemaVersion != "2.1" && schemaVersion != "4.0") + if (schemaVersion is not "2.1" and not "4.0") { throw new ArgumentException("Unsupported schema version, only 2.1 and 4.0 are supported."); } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs index b7970d1169..75215490df 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLogExporter.cs @@ -59,7 +59,9 @@ public GenevaLogExporter(GenevaExporterOptions options) useMsgPackExporter = false; break; - + case TransportProtocol.Tcp: + case TransportProtocol.Udp: + case TransportProtocol.Unspecified: default: throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } @@ -68,14 +70,14 @@ public GenevaLogExporter(GenevaExporterOptions options) { var msgPackLogExporter = new MsgPackLogExporter(options); this.IsUsingUnixDomainSocket = msgPackLogExporter.IsUsingUnixDomainSocket; - this.exportLogRecord = (in Batch batch) => msgPackLogExporter.Export(in batch); + this.exportLogRecord = msgPackLogExporter.Export; this.exporter = msgPackLogExporter; } else { var tldLogExporter = new TldLogExporter(options); this.IsUsingUnixDomainSocket = false; - this.exportLogRecord = (in Batch batch) => tldLogExporter.Export(in batch); + this.exportLogRecord = tldLogExporter.Export; this.exporter = tldLogExporter; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs index 9393e0aa85..c06cd51469 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaTraceExporter.cs @@ -59,7 +59,9 @@ public GenevaTraceExporter(GenevaExporterOptions options) useMsgPackExporter = false; break; - + case TransportProtocol.Tcp: + case TransportProtocol.Udp: + case TransportProtocol.Unspecified: default: throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } @@ -68,14 +70,14 @@ public GenevaTraceExporter(GenevaExporterOptions options) { var msgPackTraceExporter = new MsgPackTraceExporter(options); this.IsUsingUnixDomainSocket = msgPackTraceExporter.IsUsingUnixDomainSocket; - this.exportActivity = (in Batch batch) => msgPackTraceExporter.Export(in batch); + this.exportActivity = msgPackTraceExporter.Export; this.exporter = msgPackTraceExporter; } else { var tldTraceExporter = new TldTraceExporter(options); this.IsUsingUnixDomainSocket = false; - this.exportActivity = (in Batch batch) => tldTraceExporter.Export(in batch); + this.exportActivity = tldTraceExporter.Export; this.exporter = tldTraceExporter; } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs index 169f3f1a7e..55a244dbe7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/ConnectionStringBuilder.cs @@ -69,23 +69,11 @@ public string EtwSession set => this.parts[nameof(this.EtwSession)] = value; } - public bool PrivatePreviewEnableTraceLoggingDynamic - { - get - { - return this.parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var value) + public bool PrivatePreviewEnableTraceLoggingDynamic => this.parts.TryGetValue(nameof(this.PrivatePreviewEnableTraceLoggingDynamic), out var value) && bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase); - } - } - public bool PrivatePreviewEnableOtlpProtobufEncoding - { - get - { - return this.parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) + public bool PrivatePreviewEnableOtlpProtobufEncoding => this.parts.TryGetValue(nameof(this.PrivatePreviewEnableOtlpProtobufEncoding), out var value) && bool.TrueString.Equals(value, StringComparison.OrdinalIgnoreCase); - } - } public string Endpoint { @@ -102,12 +90,7 @@ public TransportProtocol Protocol // Checking Etw first, since it's preferred for Windows and enables fail fast on Linux if (this.parts.ContainsKey(nameof(this.EtwSession))) { - if (this.PrivatePreviewEnableTraceLoggingDynamic) - { - return TransportProtocol.EtwTld; - } - - return TransportProtocol.Etw; + return this.PrivatePreviewEnableTraceLoggingDynamic ? TransportProtocol.EtwTld : TransportProtocol.Etw; } if (!this.parts.ContainsKey(nameof(this.Endpoint))) @@ -116,12 +99,9 @@ public TransportProtocol Protocol } var endpoint = new Uri(this.Endpoint); - if (Enum.TryParse(endpoint.Scheme, true, out TransportProtocol protocol)) - { - return protocol; - } - - throw new ArgumentException("Endpoint scheme is invalid."); + return Enum.TryParse(endpoint.Scheme, true, out TransportProtocol protocol) + ? protocol + : throw new ArgumentException("Endpoint scheme is invalid."); } catch (UriFormatException ex) { @@ -134,22 +114,19 @@ public int TimeoutMilliseconds { get { - if (!this.parts.TryGetValue(nameof(this.TimeoutMilliseconds), out string? value)) + if (!this.parts.TryGetValue(nameof(this.TimeoutMilliseconds), out var value)) { return UnixDomainSocketDataTransport.DefaultTimeoutMilliseconds; } try { - int timeout = int.Parse(value, CultureInfo.InvariantCulture); - if (timeout <= 0) - { - throw new ArgumentException( + var timeout = int.Parse(value, CultureInfo.InvariantCulture); + return timeout <= 0 + ? throw new ArgumentException( $"{nameof(this.TimeoutMilliseconds)} should be greater than zero.", - nameof(this.TimeoutMilliseconds)); - } - - return timeout; + nameof(this.TimeoutMilliseconds)) + : timeout; } catch (ArgumentException) { @@ -189,12 +166,9 @@ public int Port try { var endpoint = new Uri(this.Endpoint); - if (endpoint.IsDefaultPort) - { - throw new ArgumentException($"Port should be explicitly set in {nameof(this.Endpoint)} value."); - } - - return endpoint.Port; + return endpoint.IsDefaultPort + ? throw new ArgumentException($"Port should be explicitly set in {nameof(this.Endpoint)} value.") + : endpoint.Port; } catch (UriFormatException ex) { @@ -217,15 +191,7 @@ public string Namespace public bool DisableMetricNameValidation { - get - { - if (!this.parts.TryGetValue(nameof(this.DisableMetricNameValidation), out var value)) - { - return false; - } - - return string.Equals(bool.TrueString, value, StringComparison.OrdinalIgnoreCase); - } + get => this.parts.TryGetValue(nameof(this.DisableMetricNameValidation), out var value) && string.Equals(bool.TrueString, value, StringComparison.OrdinalIgnoreCase); set => this.parts[nameof(this.DisableMetricNameValidation)] = value ? bool.TrueString : bool.FalseString; } @@ -261,21 +227,13 @@ public bool TryGetMetricsAccountAndNamespace( /// Updated string. internal static string ReplaceFirstChar(string str, char oldChar, char newChar) { - if (str.Length > 0 && str[0] == oldChar) - { - return $"{newChar}{str.Substring(1)}"; - } - - return str; + return str.Length > 0 && str[0] == oldChar ? $"{newChar}{str.Substring(1)}" : str; } private T ThrowIfNotExists(string name) { - if (!this.parts.TryGetValue(name, out var value)) - { - throw new ArgumentException($"'{name}' value is missing in connection string."); - } - - return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); + return !this.parts.TryGetValue(name, out var value) + ? throw new ArgumentException($"'{name}' value is missing in connection string.") + : (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs index dd5c0312ac..432fc0ed41 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MessagePackSerializer.cs @@ -338,7 +338,7 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string? value) return SerializeNull(buffer, cursor); } - int start = cursor; + var start = cursor; var cch = value.Length; int cb; if (cch <= LIMIT_MAX_FIX_STRING_LENGTH_IN_BYTES) @@ -403,18 +403,13 @@ public static int SerializeAsciiString(byte[] buffer, int cursor, string? value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeUnicodeString(byte[] buffer, int cursor, string? value) { - if (value == null) - { - return SerializeNull(buffer, cursor); - } - - return SerializeUnicodeString(buffer, cursor, value.AsSpan()); + return value == null ? SerializeNull(buffer, cursor) : SerializeUnicodeString(buffer, cursor, value.AsSpan()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SerializeUnicodeString(byte[] buffer, int cursor, ReadOnlySpan value) { - int start = cursor; + var start = cursor; var cch = value.Length; int cb; cursor += 3; @@ -451,7 +446,7 @@ public static int SerializeUnicodeString(byte[] buffer, int cursor, string? valu return SerializeNull(buffer, cursor); } - int start = cursor; + var start = cursor; var cch = value.Length; int cb; cursor += 3; @@ -510,7 +505,7 @@ public static int SerializeArray(byte[] buffer, int cursor, T[]? array) } cursor = WriteArrayHeader(buffer, cursor, array.Length); - for (int i = 0; i < array.Length; i++) + for (var i = 0; i < array.Length; i++) { cursor = Serialize(buffer, cursor, array[i]); } @@ -569,7 +564,9 @@ public static int WriteTimestamp96Header(byte[] buffer, int cursor) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int WriteTimestamp96(byte[] buffer, int cursor, long ticks) { +#pragma warning disable IDE0047 // Remove unnecessary parentheses, it is in conflict with SA1407 cursor = WriteUInt32(buffer, cursor, unchecked((uint)((ticks % TimeSpan.TicksPerSecond) * 100))); +#pragma warning restore IDE0047 // Remove unnecessary parentheses cursor = WriteInt64(buffer, cursor, (ticks / TimeSpan.TicksPerSecond) - 62135596800L); return cursor; } @@ -633,7 +630,7 @@ public static int Serialize(byte[] buffer, int cursor, object? obj) #if NET case ISpanFormattable v: Span tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; - if (v.TryFormat(tmp, out int charsWritten, string.Empty, CultureInfo.InvariantCulture)) + if (v.TryFormat(tmp, out var charsWritten, string.Empty, CultureInfo.InvariantCulture)) { return SerializeUnicodeString(buffer, cursor, tmp.Slice(0, charsWritten)); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs index cf91ac510d..0a597cae51 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackExporter.cs @@ -39,14 +39,7 @@ internal abstract class MsgPackExporter protected static int AddPartAField(byte[] buffer, int cursor, string name, object? value) { - if (V40_PART_A_MAPPING.TryGetValue(name, out string? replacementKey)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); - } + cursor = V40_PART_A_MAPPING.TryGetValue(name, out var replacementKey) ? MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey) : MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); cursor = MessagePackSerializer.Serialize(buffer, cursor, value); return cursor; @@ -54,14 +47,7 @@ protected static int AddPartAField(byte[] buffer, int cursor, string name, objec protected static int AddPartAField(byte[] buffer, int cursor, string name, ReadOnlySpan value) { - if (V40_PART_A_MAPPING.TryGetValue(name, out string? replacementKey)) - { - cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); - } - else - { - cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); - } + cursor = V40_PART_A_MAPPING.TryGetValue(name, out var replacementKey) ? MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey) : MessagePackSerializer.SerializeUnicodeString(buffer, cursor, name); cursor = MessagePackSerializer.SerializeSpan(buffer, cursor, value); return cursor; diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs index 0c845aaa9f..de39f6e7fd 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs @@ -23,10 +23,10 @@ internal sealed class MsgPackLogExporter : MsgPackExporter, IDisposable private static readonly Action ProcessScopeForIndividualColumnsAction = OnProcessScopeForIndividualColumns; private static readonly Action ProcessScopeForEnvPropertiesAction = OnProcessScopeForEnvProperties; - private static readonly string[] LogLevels = new string[7] - { - "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", - }; + private static readonly string[] LogLevels = + [ + "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None" + ]; private readonly bool shouldExportEventName; private readonly TableNameSerializer tableNameSerializer; @@ -78,13 +78,17 @@ public MsgPackLogExporter(GenevaExporterOptions options) var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); this.dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; + case TransportProtocol.Tcp: + case TransportProtocol.Udp: + case TransportProtocol.EtwTld: + case TransportProtocol.Unspecified: default: throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } if (options.PrepopulatedFields != null) { - this.prepopulatedFieldKeys = new List(); + this.prepopulatedFieldKeys = []; var tempPrepopulatedFields = new Dictionary(options.PrepopulatedFields.Count, StringComparer.Ordinal); foreach (var kv in options.PrepopulatedFields) { @@ -212,7 +216,7 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) var categoryName = logRecord.CategoryName ?? "Log"; - cursor = this.tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, cursor, categoryName, out ReadOnlySpan eventName); + cursor = this.tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, cursor, categoryName, out var eventName); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 1); cursor = MessagePackSerializer.WriteArrayHeader(buffer, cursor, 2); @@ -223,7 +227,7 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) if (this.prepopulatedFieldKeys != null) { - for (int i = 0; i < this.prepopulatedFieldKeys.Count; i++) + for (var i = 0; i < this.prepopulatedFieldKeys.Count; i++) { var key = this.prepopulatedFieldKeys[i]; var value = this.prepopulatedFields![key]; @@ -235,7 +239,7 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) // Part A - core envelope var eventId = logRecord.EventId; - bool hasEventId = eventId != default; + var hasEventId = eventId != default; if (hasEventId && this.shouldExportEventName && !string.IsNullOrWhiteSpace(eventId.Name)) { @@ -286,10 +290,10 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.SerializeUInt8(buffer, cursor, GetSeverityNumber(logLevel)); cntFields += 1; - bool hasEnvProperties = false; - bool bodyPopulated = false; - bool namePopulated = false; - for (int i = 0; i < listKvp?.Count; i++) + var hasEnvProperties = false; + var bodyPopulated = false; + var namePopulated = false; + for (var i = 0; i < listKvp?.Count; i++) { var entry = listKvp[i]; @@ -311,7 +315,7 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) // null is not supported. if (string.Equals(entry.Key, "name", StringComparison.Ordinal)) { - if (!(entry.Value is string)) + if (entry.Value is not string) { // name must be string according to Part B in Common Schema. Skip serializing this field otherwise continue; @@ -367,8 +371,8 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) ushort envPropertiesCount = 0; cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int idxMapSizeEnvPropertiesPatch = cursor - 2; - for (int i = 0; i < listKvp!.Count; i++) + var idxMapSizeEnvPropertiesPatch = cursor - 2; + for (var i = 0; i < listKvp!.Count; i++) { var entry = listKvp[i]; if (entry.Key == "{OriginalFormat}" || this.customFields!.Contains(entry.Key)) @@ -444,27 +448,21 @@ private static byte GetSeverityNumber(LogLevel logLevel) // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#mapping-of-severitynumber // TODO: for improving perf simply do ((int)loglevel * 4) + 1 // or ((int)logLevel << 2) + 1 - switch (logLevel) + return logLevel switch { - case LogLevel.Trace: - return 1; - case LogLevel.Debug: - return 5; - case LogLevel.Information: - return 9; - case LogLevel.Warning: - return 13; - case LogLevel.Error: - return 17; - case LogLevel.Critical: - return 21; + LogLevel.Trace => 1, + LogLevel.Debug => 5, + LogLevel.Information => 9, + LogLevel.Warning => 13, + LogLevel.Error => 17, + LogLevel.Critical => 21, // we reach default only for LogLevel.None // but that is filtered out anyway. // should we throw here then? - default: - return 1; - } + LogLevel.None => 1, + _ => 1, + }; } private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, MsgPackLogExporter state) @@ -474,7 +472,7 @@ private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, Msg var stateData = state.serializationData.Value!; var customFields = state.customFields; - foreach (KeyValuePair scopeItem in scope) + foreach (var scopeItem in scope) { if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { @@ -505,7 +503,7 @@ private static void OnProcessScopeForEnvProperties(LogRecordScope scope, MsgPack var stateData = state.serializationData.Value!; var customFields = state.customFields; - foreach (KeyValuePair scopeItem in scope) + foreach (var scopeItem in scope) { if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs index 675305ad16..840c35ba2f 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackTraceExporter.cs @@ -95,6 +95,10 @@ public MsgPackTraceExporter(GenevaExporterOptions options) var unixDomainSocketPath = connectionStringBuilder.ParseUnixDomainSocketPath(); this.dataTransport = new UnixDomainSocketDataTransport(unixDomainSocketPath); break; + case TransportProtocol.Tcp: + case TransportProtocol.Udp: + case TransportProtocol.EtwTld: + case TransportProtocol.Unspecified: default: throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } @@ -359,14 +363,14 @@ internal ArraySegment SerializeActivity(Activity activity) // Iteration #1 - Get those fields which become dedicated column // i.e all PartB fields and opt-in part c fields. - bool hasEnvProperties = false; - bool isStatusSuccess = true; + var hasEnvProperties = false; + var isStatusSuccess = true; string? statusDescription = null; foreach (ref readonly var entry in activity.EnumerateTagObjects()) { // TODO: check name collision - if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string? replacementKey)) + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out var replacementKey)) { cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, replacementKey); } @@ -396,7 +400,7 @@ internal ArraySegment SerializeActivity(Activity activity) ushort envPropertiesCount = 0; cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_properties"); cursor = MessagePackSerializer.WriteMapHeader(buffer, cursor, ushort.MaxValue); - int idxMapSizeEnvPropertiesPatch = cursor - 2; + var idxMapSizeEnvPropertiesPatch = cursor - 2; foreach (ref readonly var entry in activity.EnumerateTagObjects()) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs index db60ffe605..e080795194 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/TableNameSerializer.cs @@ -19,7 +19,7 @@ internal sealed class TableNameSerializer /* Note: We don't use Array.Empty here because that is used to indicate an invalid name. We need a different instance to trigger the pass-through case. */ - private static readonly byte[] PassthroughTableName = new byte[0]; + private static readonly byte[] PassthroughTableName = []; #pragma warning restore CA1825 // Avoid zero-length array allocations private static readonly StringComparer DictionaryKeyComparer = StringComparer.Ordinal; @@ -52,13 +52,10 @@ public TableNameSerializer(GenevaExporterOptions options, string defaultTableNam this.defaultTableName = BuildStr8BufferForAsciiString(kv.Value); } } - else if (kv.Value == "*") - { - tempTableMappings[kv.Key] = PassthroughTableName; - } else { - tempTableMappings[kv.Key] = BuildStr8BufferForAsciiString(kv.Value); + tempTableMappings[kv.Key] = + kv.Value == "*" ? PassthroughTableName : BuildStr8BufferForAsciiString(kv.Value); } } @@ -77,13 +74,13 @@ public interface ITableNameCacheDictionary : IReadOnlyDictionary [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ResolveAndSerializeTableNameForCategoryName(byte[] destination, int offset, string categoryName, out ReadOnlySpan tableName) { - byte[] mappedTableName = this.ResolveTableMappingForCategoryName(categoryName); + var mappedTableName = this.ResolveTableMappingForCategoryName(categoryName); if (mappedTableName == PassthroughTableName) { // Pass-through mode with a full cache. - int bytesWritten = WriteSanitizedCategoryNameToSpan(new Span(destination, offset, MaxSanitizedCategoryNameBytes), categoryName); + var bytesWritten = WriteSanitizedCategoryNameToSpan(new Span(destination, offset, MaxSanitizedCategoryNameBytes), categoryName); tableName = new ReadOnlySpan(destination, offset, bytesWritten); @@ -99,7 +96,7 @@ private static byte[] BuildStr8BufferForAsciiString(string value) { var length = value.Length; - byte[] buffer = new byte[length + 2]; + var buffer = new byte[length + 2]; Encoding.ASCII.GetBytes(value, 0, length, buffer, 2); @@ -117,17 +114,17 @@ private static int WriteSanitizedCategoryNameToSpan(Span buffer, string ca { // Reserve 2 bytes for storing LIMIT_MAX_STR8_LENGTH_IN_BYTES and (byte)validNameLength - // these 2 bytes will be back filled after iterating through categoryName. - int cursor = 2; - int validNameLength = 0; + var cursor = 2; + var validNameLength = 0; // Special treatment for the first character. var firstChar = categoryName[0]; - if (firstChar >= 'A' && firstChar <= 'Z') + if (firstChar is >= 'A' and <= 'Z') { buffer[cursor++] = (byte)firstChar; ++validNameLength; } - else if (firstChar >= 'a' && firstChar <= 'z') + else if (firstChar is >= 'a' and <= 'z') { // If the first character in the resulting string is a lower-case alphabet, // it will be converted to the corresponding upper-case. @@ -140,7 +137,7 @@ private static int WriteSanitizedCategoryNameToSpan(Span buffer, string ca return 0; } - for (int i = 1; i < categoryName.Length; ++i) + for (var i = 1; i < categoryName.Length; ++i) { if (validNameLength == MaxSanitizedCategoryNameLength) { @@ -148,7 +145,7 @@ private static int WriteSanitizedCategoryNameToSpan(Span buffer, string ca } var cur = categoryName[i]; - if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) + if (cur is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or (>= '0' and <= '9')) { buffer[cursor++] = (byte)cur; ++validNameLength; @@ -165,12 +162,7 @@ private byte[] ResolveTableMappingForCategoryName(string categoryName) { var tableNameCache = this.tableNameCache; - if (tableNameCache.TryGetValue(categoryName, out byte[]? tableName)) - { - return tableName; - } - - return this.ResolveTableMappingForCategoryNameRare(categoryName); + return tableNameCache.TryGetValue(categoryName, out var tableName) ? tableName : this.ResolveTableMappingForCategoryNameRare(categoryName); } private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) @@ -204,15 +196,15 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) ? this.defaultTableName : PassthroughTableName; - Span sanitizedTableNameStorage = mappedTableName == PassthroughTableName + var sanitizedTableNameStorage = mappedTableName == PassthroughTableName ? stackalloc byte[MaxSanitizedCategoryNameBytes] - : Array.Empty(); + : []; if (sanitizedTableNameStorage.Length > 0) { // We resolved to a wildcard which is pass-through mode. - int bytesWritten = WriteSanitizedCategoryNameToSpan(sanitizedTableNameStorage, categoryName); + var bytesWritten = WriteSanitizedCategoryNameToSpan(sanitizedTableNameStorage, categoryName); if (bytesWritten > 0) { sanitizedTableNameStorage = sanitizedTableNameStorage.Slice(0, bytesWritten); @@ -221,7 +213,7 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) { // Note: When the table name could not be sanitized we cache // the empty array NOT s_passthroughTableName. - mappedTableName = Array.Empty(); + mappedTableName = []; } } @@ -231,7 +223,7 @@ private byte[] ResolveTableMappingForCategoryNameRare(string categoryName) // Check if another thread added the mapping while we waited on the // lock. - if (tableNameCache.TryGetValue(categoryName, out byte[]? tableName)) + if (tableNameCache.TryGetValue(categoryName, out var tableName)) { return tableName; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs index 35a2d8a960..031dd48b51 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/JsonSerializer.cs @@ -116,7 +116,7 @@ public static int SerializeArray(byte[] buffer, int cursor, T[]? array) if (length >= 1) { cursor = Serialize(buffer, cursor, array[0]); - for (int i = 1; i < length; i++) + for (var i = 1; i < length; i++) { buffer[cursor++] = unchecked((byte)','); cursor = Serialize(buffer, cursor, array[i]); @@ -164,7 +164,7 @@ public static int SerializeMap(byte[] buffer, int cursor, IEnumerable 0) @@ -191,8 +191,8 @@ public static int SerializeKeyValuePairList(byte[] buffer, int cursor, List 0) { @@ -247,12 +247,12 @@ public static int Serialize(byte[] buffer, int cursor, object? obj) case float: case double: Span tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; - ((ISpanFormattable)obj).TryFormat(tmp, out int charsWritten, default, CultureInfo.InvariantCulture); + ((ISpanFormattable)obj).TryFormat(tmp, out var charsWritten, default, CultureInfo.InvariantCulture); return WriteString(buffer, cursor, tmp.Slice(0, charsWritten)); case DateTime dt: tmp = stackalloc char[MAX_STACK_ALLOC_SIZE_IN_BYTES / sizeof(char)]; dt = dt.ToUniversalTime(); - dt.TryFormat(tmp, out int count, default, CultureInfo.InvariantCulture); + dt.TryFormat(tmp, out var count, default, CultureInfo.InvariantCulture); return WriteString(buffer, cursor, tmp.Slice(0, count)); #else case byte: @@ -330,14 +330,10 @@ public static int Serialize(byte[] buffer, int cursor, object? obj) private static byte[] InitializeHexCodeLookup() { - var mapping = new byte[] - { - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - }; + var mapping = "0123456789abcdef"u8.ToArray(); var hexCodeLookup = new byte[512]; - for (int i = 0; i < 256; i++) + for (var i = 0; i < 256; i++) { hexCodeLookup[i] = mapping[i >> 4]; hexCodeLookup[i + 256] = mapping[i & 0x0F]; @@ -349,7 +345,7 @@ private static byte[] InitializeHexCodeLookup() [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int WriteString(byte[] buffer, int cursor, string value) { - for (int i = 0; i < value.Length; i++) + for (var i = 0; i < value.Length; i++) { var ordinal = (ushort)value[i]; switch (ordinal) @@ -388,7 +384,7 @@ private static int WriteString(byte[] buffer, int cursor, string value) break; default: // ASCII printable characters - if (ordinal >= 32 && ordinal < 127) + if (ordinal is >= 32 and < 127) { buffer[cursor++] = unchecked((byte)ordinal); } @@ -417,7 +413,7 @@ private static int WriteString(byte[] buffer, int cursor, string value) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int WriteString(byte[] buffer, int cursor, ReadOnlySpan value) { - for (int i = 0; i < value.Length; i++) + for (var i = 0; i < value.Length; i++) { var ordinal = (ushort)value[i]; switch (ordinal) @@ -456,7 +452,7 @@ private static int WriteString(byte[] buffer, int cursor, ReadOnlySpan val break; default: // ASCII printable characters - if (ordinal >= 32 && ordinal < 127) + if (ordinal is >= 32 and < 127) { buffer[cursor++] = unchecked((byte)ordinal); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs index ca52b09a1f..c4fa6db451 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldExporter.cs @@ -116,7 +116,7 @@ protected static void Serialize(EventBuilder eb, string key, object value) eb.AddCountedStringArray(key, vsarray); break; case DateTime[] vdtarray: - for (int i = 0; i < vdtarray.Length; i++) + for (var i = 0; i < vdtarray.Length; i++) { vdtarray[i] = vdtarray[i].ToUniversalTime(); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs index 4aeb5895e8..1e28710271 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs @@ -21,10 +21,10 @@ internal sealed class TldLogExporter : TldExporter, IDisposable private static readonly ThreadLocal>> EnvProperties = new(); private static readonly ThreadLocal[]> PartCFields = new(); // This is used to temporarily store the PartC fields from tags private static readonly Action ProcessScopeForIndividualColumnsAction = OnProcessScopeForIndividualColumns; - private static readonly string[] LogLevels = new string[7] - { - "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None", - }; + private static readonly string[] LogLevels = + [ + "Trace", "Debug", "Information", "Warning", "Error", "Critical", "None" + ]; private readonly ThreadLocal serializationData = new(); // This is used for Scopes private readonly byte partAFieldsCount = 1; // At least one field: time @@ -104,7 +104,7 @@ public TldLogExporter(GenevaExporterOptions options) continue; } - V40_PART_A_TLD_MAPPING.TryGetValue(key, out string? replacementKey); + V40_PART_A_TLD_MAPPING.TryGetValue(key, out var replacementKey); var keyToSerialize = replacementKey ?? key; Serialize(eb, keyToSerialize, value); @@ -219,7 +219,7 @@ internal EventBuilder SerializeLogRecord(LogRecord logRecord) eb.AppendRawFields(this.repeatedPartAFields); } - byte partAFieldsCount = this.partAFieldsCount; + var partAFieldsCount = this.partAFieldsCount; // Part A - dt extension if (logRecord.TraceId != default) @@ -286,15 +286,15 @@ internal EventBuilder SerializeLogRecord(LogRecord logRecord) } byte hasEnvProperties = 0; - bool bodyPopulated = false; - bool namePopulated = false; + var bodyPopulated = false; + var namePopulated = false; byte partCFieldsCountFromState = 0; var kvpArrayForPartCFields = PartCFields.Value ??= new KeyValuePair[120]; List>? envPropertiesList = null; - for (int i = 0; i < listKvp?.Count; i++) + for (var i = 0; i < listKvp?.Count; i++) { var entry = listKvp[i]; @@ -337,7 +337,7 @@ internal EventBuilder SerializeLogRecord(LogRecord logRecord) if (hasEnvProperties == 0) { hasEnvProperties = 1; - envPropertiesList = EnvProperties.Value ??= new(); + envPropertiesList = EnvProperties.Value ??= []; envPropertiesList.Clear(); } @@ -374,13 +374,13 @@ internal EventBuilder SerializeLogRecord(LogRecord logRecord) hasEnvProperties = dataForScopes.HasEnvProperties; partCFieldsCountFromState = dataForScopes.PartCFieldsCountFromState; - int partCFieldsCount = partCFieldsCountFromState + hasEnvProperties; // We at least have these many fields in Part C + var partCFieldsCount = partCFieldsCountFromState + hasEnvProperties; // We at least have these many fields in Part C if (partCFieldsCount > 0) { var partCFieldsCountPatch = eb.AddStruct("PartC", (byte)partCFieldsCount); - for (int i = 0; i < partCFieldsCountFromState; i++) + for (var i = 0; i < partCFieldsCountFromState; i++) { Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); } @@ -406,27 +406,21 @@ private static byte GetSeverityNumber(LogLevel logLevel) // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#mapping-of-severitynumber // TODO: for improving perf simply do ((int)loglevel * 4) + 1 // or ((int)logLevel << 2) + 1 - switch (logLevel) + return logLevel switch { - case LogLevel.Trace: - return 1; - case LogLevel.Debug: - return 5; - case LogLevel.Information: - return 9; - case LogLevel.Warning: - return 13; - case LogLevel.Error: - return 17; - case LogLevel.Critical: - return 21; + LogLevel.Trace => 1, + LogLevel.Debug => 5, + LogLevel.Information => 9, + LogLevel.Warning => 13, + LogLevel.Error => 17, + LogLevel.Critical => 21, // we reach default only for LogLevel.None // but that is filtered out anyway. // should we throw here then? - default: - return 1; - } + LogLevel.None => 1, + _ => 1, + }; } // This method would map the logger category to a table name which only contains alphanumeric values with the following additions: @@ -437,17 +431,17 @@ private static byte GetSeverityNumber(LogLevel logLevel) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static string GetSanitizedCategoryName(string categoryName) { - int validNameLength = 0; + var validNameLength = 0; Span result = stackalloc char[MaxSanitizedEventNameLength]; // Special treatment for the first character. var firstChar = categoryName[0]; - if (firstChar >= 'A' && firstChar <= 'Z') + if (firstChar is >= 'A' and <= 'Z') { result[0] = firstChar; ++validNameLength; } - else if (firstChar >= 'a' && firstChar <= 'z') + else if (firstChar is >= 'a' and <= 'z') { // If the first character in the resulting string is a lower-case alphabet, // it will be converted to the corresponding upper-case. @@ -460,7 +454,7 @@ private static string GetSanitizedCategoryName(string categoryName) return string.Empty; } - for (int i = 1; i < categoryName.Length; i++) + for (var i = 1; i < categoryName.Length; i++) { if (validNameLength == MaxSanitizedEventNameLength) { @@ -468,7 +462,7 @@ private static string GetSanitizedCategoryName(string categoryName) } var cur = categoryName[i]; - if ((cur >= 'a' && cur <= 'z') || (cur >= 'A' && cur <= 'Z') || (cur >= '0' && cur <= '9')) + if (cur is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or (>= '0' and <= '9')) { result[validNameLength] = cur; ++validNameLength; @@ -489,7 +483,7 @@ private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, Tld List>? envPropertiesList = null; - foreach (KeyValuePair scopeItem in scope) + foreach (var scopeItem in scope) { if (string.IsNullOrEmpty(scopeItem.Key) || scopeItem.Key == "{OriginalFormat}") { @@ -510,7 +504,7 @@ private static void OnProcessScopeForIndividualColumns(LogRecordScope scope, Tld { stateData.HasEnvProperties = 1; - envPropertiesList = EnvProperties.Value ??= new(); + envPropertiesList = EnvProperties.Value ??= []; envPropertiesList.Clear(); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs index 4e1ae97ceb..dcd9c56fac 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldTraceExporter.cs @@ -61,10 +61,11 @@ public TldTraceExporter(GenevaExporterOptions options) // TODO: Validate custom fields (reserved name? etc). if (options.CustomFields != null) { - var customFields = new HashSet(StringComparer.Ordinal); - - // Seed customFields with Span PartB - customFields.Add("azureResourceProvider"); + var customFields = new HashSet(StringComparer.Ordinal) + { + // Seed customFields with Span PartB + "azureResourceProvider", + }; foreach (var mapping in CS40_PART_B_MAPPING) { @@ -98,7 +99,7 @@ public TldTraceExporter(GenevaExporterOptions options) continue; } - V40_PART_A_TLD_MAPPING.TryGetValue(key, out string? replacementKey); + V40_PART_A_TLD_MAPPING.TryGetValue(key, out var replacementKey); var keyToSerialize = replacementKey ?? key; Serialize(eb, keyToSerialize, value); @@ -206,7 +207,7 @@ internal EventBuilder SerializeActivity(Activity activity) var linkEnumerator = activity.EnumerateLinks(); if (linkEnumerator.MoveNext()) { - var keyValuePairsForLinks = KeyValuePairs.Value ??= new(); + var keyValuePairsForLinks = KeyValuePairs.Value ??= []; keyValuePairsForLinks.Clear(); @@ -228,9 +229,9 @@ internal EventBuilder SerializeActivity(Activity activity) byte hasEnvProperties = 0; byte isStatusSuccess = 1; - string statusDescription = string.Empty; + var statusDescription = string.Empty; - int partCFieldsCountFromTags = 0; + var partCFieldsCountFromTags = 0; var kvpArrayForPartCFields = PartCFields.Value ??= new KeyValuePair[120]; List>? envPropertiesList = null; @@ -243,7 +244,7 @@ internal EventBuilder SerializeActivity(Activity activity) } // TODO: check name collision - if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out string? replacementKey)) + if (CS40_PART_B_MAPPING.TryGetValue(entry.Key, out var replacementKey)) { Serialize(eb, replacementKey, entry.Value); partBFieldsCount++; @@ -282,7 +283,7 @@ internal EventBuilder SerializeActivity(Activity activity) { hasEnvProperties = 1; - envPropertiesList = KeyValuePairs.Value ??= new(); + envPropertiesList = KeyValuePairs.Value ??= []; envPropertiesList.Clear(); } @@ -321,7 +322,7 @@ internal EventBuilder SerializeActivity(Activity activity) { eb.AddStruct("PartC", (byte)partCFieldsCount); - for (int i = 0; i < partCFieldsCountFromTags; i++) + for (var i = 0; i < partCFieldsCountFromTags; i++) { Serialize(eb, kvpArrayForPartCFields[i].Key, kvpArrayForPartCFields[i].Value); } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs index 25c4f19591..23fe829333 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/UncheckedASCIIEncoding.cs @@ -51,7 +51,7 @@ public override int GetCharCount(byte[] bytes, int byteIndex, int byteCount) return byteCount; } - public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { ValidateArgs(chars, charIndex, charCount, bytes, byteIndex, "char", "byte"); fixed (char* charPtr = chars) @@ -63,7 +63,7 @@ public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, } } - public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { ValidateArgs(bytes, byteIndex, byteCount, chars, charIndex, "byte", "char"); fixed (byte* bytePtr = bytes) @@ -90,7 +90,7 @@ public override unsafe int GetBytes(char* charPtr, int charCount, byte* bytePtr, } #endif - for (int i = 0; i < charCount; i += 1) + for (var i = 0; i < charCount; i += 1) { bytePtr[i] = unchecked((byte)(charPtr[i] & 0x7F)); } @@ -109,7 +109,7 @@ public override unsafe int GetChars(byte* bytePtr, int byteCount, char* charPtr, } #endif - for (int i = 0; i < byteCount; i += 1) + for (var i = 0; i < byteCount; i += 1) { charPtr[i] = (char)bytePtr[i]; } @@ -137,7 +137,7 @@ public override unsafe int GetCharCount(byte* bytePtr, int byteCount) return byteCount; } - public unsafe override int GetBytes(string chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + public override unsafe int GetBytes(string chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { if (chars == null || bytes == null) { diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs index 16797ef848..cb4d7597cf 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/EtwDataTransport.cs @@ -67,11 +67,11 @@ public void InformationalEvent() #endif public unsafe void SendEvent(int eventId, byte[] data, int size) { - EventData* dataDesc = stackalloc EventData[1]; + var dataDesc = stackalloc EventData[1]; fixed (byte* ptr = data) { dataDesc[0].DataPointer = (IntPtr)ptr; - dataDesc[0].Size = (int)size; + dataDesc[0].Size = size; this.WriteEventCore(eventId, 1, dataDesc); } } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs index a4d6ca0fc6..bbfc0e2fc7 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Transports/UnixDomainSocketEndPoint.cs @@ -25,7 +25,7 @@ public UnixDomainSocketEndPoint(string path) this.path = path; this.nativePath = Encoding.UTF8.GetBytes(path); - if (this.nativePath.Length == 0 || this.nativePath.Length > MaximumNativePathLength) + if (this.nativePath.Length is 0 or > MaximumNativePathLength) { throw new ArgumentOutOfRangeException(nameof(path), "Path is of an invalid length for use with domain sockets."); } @@ -46,7 +46,7 @@ private UnixDomainSocketEndPoint(SocketAddress socketAddress) if (socketAddress.Size > NativePathOffset) { this.nativePath = new byte[socketAddress.Size - NativePathOffset]; - for (int i = 0; i < this.nativePath.Length; ++i) + for (var i = 0; i < this.nativePath.Length; ++i) { this.nativePath[i] = socketAddress[NativePathOffset + i]; } @@ -56,7 +56,7 @@ private UnixDomainSocketEndPoint(SocketAddress socketAddress) else { this.path = string.Empty; - this.nativePath = Array.Empty(); + this.nativePath = []; } } @@ -67,7 +67,7 @@ private UnixDomainSocketEndPoint(SocketAddress socketAddress) public override SocketAddress Serialize() { var socketAddress = new SocketAddress(AddressFamily.Unix, NativePathOffset + this.nativePath.Length + 1); - for (int i = 0; i < this.nativePath.Length; ++i) + for (var i = 0; i < this.nativePath.Length; ++i) { socketAddress[NativePathOffset + i] = this.nativePath[i]; } diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs index 65d8738ef4..334f7b107e 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/FieldNumberConstants.cs @@ -157,6 +157,9 @@ internal static int GetMetricTypeFieldNumber(MetricType metricType) { return 10; } + + default: + break; } return 0; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs index 68c3ab36b5..66072863b0 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/OtlpProtobufSerializer.cs @@ -15,7 +15,7 @@ internal sealed class OtlpProtobufSerializer private const int TagAndLengthSize = 4; - private readonly Dictionary> scopeMetrics = new(); + private readonly Dictionary> scopeMetrics = []; private readonly string? metricNamespace; private readonly string? metricAccount; private readonly bool prefixBufferWithUInt32LittleEndianLength; @@ -52,11 +52,11 @@ public OtlpProtobufSerializer( this.prefixBufferWithUInt32LittleEndianLength = prefixBufferWithUInt32LittleEndianLength; // Taking a arbitrary number here for writing attributes. - byte[] temp = new byte[20000]; + var temp = new byte[20000]; if (prepopulatedMetricDimensions != null) { // Initialize numberDataPoint attributes. - int cursor = 0; + var cursor = 0; SerializeTags(temp, ref cursor, prepopulatedMetricDimensions!, FieldNumberConstants.NumberDataPoint_attributes); this.prepopulatedNumberDataPointAttributes = new byte[cursor]; Array.Copy(temp, this.prepopulatedNumberDataPointAttributes, cursor); @@ -97,9 +97,9 @@ internal static void WriteInstrumentDetails(byte[] buffer, ref int cursor, Metri internal static void SerializeInstrumentationScope(byte[] buffer, ref int cursor, string name, IEnumerable>? meterTags) { - int tagAndLengthIndex = cursor; + var tagAndLengthIndex = cursor; cursor += TagAndLengthSize; - int valueIndex = cursor; + var valueIndex = cursor; // Write name ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.InstrumentationScope_name, name); @@ -127,15 +127,15 @@ internal static void SerializeTag(byte[] buffer, ref int cursor, string key, obj { // TODO : Check if calculating the length in advance could be more efficient in this case. // That way we wouldn't have to leave the fixed length space. - int keyValueTagAndLengthIndex = cursor; + var keyValueTagAndLengthIndex = cursor; cursor += TagAndLengthSize; - int keyValueIndex = cursor; + var keyValueIndex = cursor; ProtobufSerializerHelper.WriteStringTag(buffer, ref cursor, FieldNumberConstants.KeyValue_key, key); - int anyValueTagAndLengthIndex = cursor; + var anyValueTagAndLengthIndex = cursor; cursor += TagAndLengthSize; - int anyValueIndex = cursor; + var anyValueIndex = cursor; switch (value) { @@ -221,7 +221,7 @@ internal void ClearScopeMetrics() internal void SerializeResourceMetrics(byte[] buffer, Resource resource) { - int cursor = this.prefixBufferWithUInt32LittleEndianLength ? 4 : 0; + var cursor = this.prefixBufferWithUInt32LittleEndianLength ? 4 : 0; this.resourceMetricTagAndLengthIndex = cursor; @@ -238,7 +238,7 @@ internal void SerializeResourceMetrics(byte[] buffer, Resource resource) // Serialize ScopeMetrics field this.scopeMetricsTagAndLengthIndex = cursor; this.scopeMetricsValueIndex = cursor + TagAndLengthSize; - foreach (KeyValuePair> entry in this.scopeMetrics) + foreach (var entry in this.scopeMetrics) { if (entry.Value.Count > 0) { @@ -259,7 +259,7 @@ internal void SerializeScopeMetrics(byte[] buffer, ref int cursor, string scopeN this.metricTagAndLengthIndex = cursor; this.metricValueIndex = cursor + TagAndLengthSize; - foreach (Metric metric in metrics) + foreach (var metric in metrics) { // Reset cursor to write new metric cursor = this.metricValueIndex; @@ -273,9 +273,9 @@ internal void SerializeScopeMetrics(byte[] buffer, ref int cursor, string scopeN private static void SerializeExemplar(byte[] buffer, ref int cursor, in Exemplar exemplar, T value, int fieldNumber) { - int exemplarTagAndLengthIndex = cursor; + var exemplarTagAndLengthIndex = cursor; cursor += TagAndLengthSize; - int valueIndex = cursor; + var valueIndex = cursor; SerializeExemplarTags(buffer, ref cursor, exemplar.FilteredTags); @@ -523,7 +523,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var sum = metricPoint.GetHistogramSum(); ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_sum, sum); - if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (metricPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_min, min); ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.HistogramDataPoint_max, max); @@ -607,7 +607,7 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) var count = (ulong)metricPoint.GetHistogramCount(); ProtobufSerializerHelper.WriteFixed64WithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_count, count); - if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (metricPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_min, min); ProtobufSerializerHelper.WriteDoubleWithTag(buffer, ref cursor, FieldNumberConstants.ExponentialHistogramDataPoint_max, max); @@ -661,6 +661,9 @@ private void SerializeMetric(byte[] buffer, ref int cursor, Metric metric) break; } + + default: + break; } } @@ -749,9 +752,9 @@ private void SerializeResource(byte[] buffer, ref int cursor, Resource resource) { if (resource != Resource.Empty) { - int tagAndLengthIndex = cursor; + var tagAndLengthIndex = cursor; cursor += TagAndLengthSize; - int valueIndex = cursor; + var valueIndex = cursor; SerializeTags(buffer, ref cursor, resource.Attributes!, FieldNumberConstants.Resource_attributes); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs index 9cfaa5a172..d501848b56 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/OtlpProtobuf/ProtobufSerializerHelper.cs @@ -20,7 +20,7 @@ internal static class ProtobufSerializerHelper [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void WriteStringTag(byte[] buffer, ref int cursor, int fieldNumber, string value) { - int stringSize = Utf8Encoding.GetByteCount(value); + var stringSize = Utf8Encoding.GetByteCount(value); WriteTag(buffer, ref cursor, fieldNumber, WireType.LEN); @@ -92,12 +92,12 @@ internal static void WriteLength(byte[] buffer, ref int cursor, int length) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void WriteVarintCustom(byte[] buffer, ref int cursor, uint value) { - int index = 0; + var index = 0; // Loop until all 7 bits from the integer value have been encoded while (value > 0) { - byte chunk = (byte)(value & 0x7F); // Extract the least significant 7 bits + var chunk = (byte)(value & 0x7F); // Extract the least significant 7 bits value >>= 7; // Right shift the value by 7 bits to process the next chunk // If there are more bits to encode, set the most significant bit to 1 @@ -166,7 +166,7 @@ internal static void WriteFixed64LittleEndianFormat(byte[] buffer, ref int curso { if (cursor < buffer.Length) { - Span span = new Span(buffer, cursor, Fixed64Size); + var span = new Span(buffer, cursor, Fixed64Size); BinaryPrimitives.WriteUInt64LittleEndian(span, value); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs index 1fb5931871..ac0e55398a 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/TlvMetricExporter.cs @@ -58,6 +58,10 @@ internal TlvMetricExporter( throw new ArgumentException("Endpoint not specified"); } + case TransportProtocol.Etw: + case TransportProtocol.Tcp: + case TransportProtocol.Udp: + case TransportProtocol.EtwTld: default: throw new NotSupportedException($"Protocol '{connectionStringBuilder.Protocol}' is not supported"); } @@ -94,8 +98,8 @@ public void Dispose() internal ExportResult Export(in Batch batch) { - string monitoringAccount = this.defaultMonitoringAccount; - string metricNamespace = this.defaultMetricNamespace; + var monitoringAccount = this.defaultMonitoringAccount; + var metricNamespace = this.defaultMetricNamespace; var result = ExportResult.Success; foreach (var metric in batch) @@ -210,7 +214,7 @@ internal ExportResult Export(in Batch batch) { var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (!metricPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { min = 0; max = 0; @@ -232,6 +236,11 @@ internal ExportResult Export(in Batch batch) this.metricDataTransport.Send(MetricEventType.TLV, this.buffer, bodyLength); break; } + + case MetricType.ExponentialHistogram: + break; + default: + break; } } catch (Exception ex) @@ -495,7 +504,7 @@ private static void SerializeNonHistogramMetricData(MetricEventType eventType, M MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)payloadType); // Get a placeholder to add the payloadType length - int payloadTypeStartIndex = bufferIndex; + var payloadTypeStartIndex = bufferIndex; bufferIndex += 2; MetricSerializer.SerializeUInt64(buffer, ref bufferIndex, (ulong)timestamp); // timestamp @@ -519,7 +528,7 @@ private static void SerializeHistogramMetricData(HistogramBuckets buckets, doubl MetricSerializer.SerializeByte(buffer, ref bufferIndex, (byte)PayloadType.ExternallyAggregatedULongDistributionMetric); // Get a placeholder to add the payloadType length - int payloadTypeStartIndex = bufferIndex; + var payloadTypeStartIndex = bufferIndex; bufferIndex += 2; // Serialize sum, count, min, and max @@ -627,7 +636,7 @@ private void SerializeDimensionsAndGetCustomAccountNamespace(in ReadOnlyTagColle dimensionsWritten += this.prepopulatedDimensionsCount; } - int reservedTags = 0; + var reservedTags = 0; // Serialize MetricPoint Dimension keys foreach (var tag in tags) diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs index 0ad18c47c2..b9c1ad32ea 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/Transport/MetricWindowsEventTracingDataTransport.cs @@ -48,7 +48,7 @@ public unsafe void SendOtlpProtobufEvent(byte[] data, int size) { if (this.IsEnabled()) { - EventData* descr = stackalloc EventData[1]; + var descr = stackalloc EventData[1]; if (data != null && data.Length != 0) { fixed (byte* blob = data) diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs index 5bcd0d4358..fab119e852 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/Food.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Exporter.Geneva.Benchmarks; -public static partial class Food +internal static partial class Food { [LoggerMessage( EventId = 0, diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs index afc45c8cdd..1325447358 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs @@ -31,7 +31,9 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class LogExporterBenchmarks +#pragma warning restore CA1515 { private readonly ILogger logger; private readonly ILoggerFactory loggerFactory; @@ -102,8 +104,8 @@ public void LoggerWithDirectLoggerAPI() eventId: default, state: new List>() { - new KeyValuePair("food", food), - new KeyValuePair("price", price), + new("food", food), + new("price", price), }, exception: null, formatter: (state, ex) => $"Hello from {food} {price}."); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs index 70c343a0fc..d73c5ca4f2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs @@ -49,8 +49,15 @@ .NET SDK 8.0.202 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class MetricExporterBenchmarks +#pragma warning restore CA1515 { + private readonly Meter meterWithNoListener = new("MeterWithNoListener", "0.0.1"); + private readonly Meter meterWithListener = new("MeterWithListener", "0.0.1"); + private readonly Meter meterWithDummyReader = new("MeterWithDummyReader", "0.0.1"); + private readonly Meter meterWithGenevaMetricExporter = new("MeterWithGenevaMetricExporter", "0.0.1"); + private readonly ThreadLocal random = new(() => new Random()); private Metric? counterMetricWith3Dimensions; private Metric? counterMetricWith4Dimensions; private MetricPoint counterMetricPointWith3Dimensions; @@ -73,10 +80,6 @@ public class MetricExporterBenchmarks private uint histogramCountWith4Dimensions; private Batch histogramMetricBatchWith3Dimensions; private Batch histogramMetricBatchWith4Dimensions; - private Meter meterWithNoListener = new Meter("MeterWithNoListener", "0.0.1"); - private Meter meterWithListener = new Meter("MeterWithListener", "0.0.1"); - private Meter meterWithDummyReader = new Meter("MeterWithDummyReader", "0.0.1"); - private Meter meterWithGenevaMetricExporter = new Meter("MeterWithGenevaMetricExporter", "0.0.1"); private Counter? counterWithNoListener; private Counter? counterWithListener; private Counter? counterWithDummyReader; @@ -93,10 +96,10 @@ public class MetricExporterBenchmarks private OtlpProtobufSerializer? otlpProtobufSerializer; private Resource? resource; private byte[]? buffer; - private ThreadLocal random = new(() => new Random()); - private static readonly Random randomForHistogram = new Random(); // Use the same seed for all the benchmarks to have the same data exported - private static readonly string[] dimensionValues = new string[] { "DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" }; + private static readonly Random randomForHistogram = new(); // Use the same seed for all the benchmarks to have the same data exported + private static readonly string[] dimensionValues = ["DimVal1", "DimVal2", "DimVal3", "DimVal4", "DimVal5", "DimVal6", "DimVal7", "DimVal8", "DimVal9", "DimVal10" + ]; [GlobalSetup] public void Setup() @@ -114,7 +117,7 @@ public void Setup() this.otlpProtobufSerializer = new OtlpProtobufSerializer(new TestTransport(), metricsAccount: null, metricsNamespace: null, prepopulatedMetricDimensions: null); var resourceBuilder = ResourceBuilder.CreateDefault().Clear() - .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + .AddAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")]); this.resource = resourceBuilder.Build(); this.otlpProtobufMetricExporter = new OtlpProtobufMetricExporter(() => { return this.resource; }, new TestTransport(), metricsAccount: null, metricsNamespace: null, prepopulatedMetricDimensions: null); this.buffer = new byte[GenevaMetricExporter.BufferSize]; @@ -148,13 +151,15 @@ public void Setup() this.histogramMetricWith4Dimensions = enumeratorForHistogramBatchWith4Dimensions.Current; #region Setup MeterListener - this.listener = new MeterListener(); - this.listener.InstrumentPublished = (instrument, listener) => + this.listener = new MeterListener { - if (instrument.Meter.Name == this.meterWithListener.Name) + InstrumentPublished = (instrument, listener) => { - listener.EnableMeasurementEvents(instrument); - } + if (instrument.Meter.Name == this.meterWithListener.Name) + { + listener.EnableMeasurementEvents(instrument); + } + }, }; this.listener.Start(); @@ -322,7 +327,7 @@ private MetricPoint GenerateHistogramMetricItemWith3Dimensions(out ulong sum, ou var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - for (int i = 0; i < 1000; i++) + for (var i = 0; i < 1000; i++) { histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); } @@ -369,7 +374,7 @@ private MetricPoint GenerateHistogramMetricItemWith4Dimensions(out ulong sum, ou { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - for (int i = 0; i < 1000; i++) + for (var i = 0; i < 1000; i++) { histogram.Record(randomForHistogram.Next(1, 1000), tags); } @@ -412,7 +417,7 @@ private Batch GenerateHistogramBatchWith3Dimensions() var tag2 = new KeyValuePair("DimName2", dimensionValues[this.random.Value.Next(0, 10)]); var tag3 = new KeyValuePair("DimName3", dimensionValues[this.random.Value.Next(0, 10)]); - for (int i = 0; i < 1000; i++) + for (var i = 0; i < 1000; i++) { histogram.Record(randomForHistogram.Next(1, 1000), tag1, tag2, tag3); } @@ -445,7 +450,7 @@ private Batch GenerateHistogramBatchWith4Dimensions() { "DimName4", dimensionValues[this.random.Value.Next(0, 10)] }, }; - for (int i = 0; i < 1000; i++) + for (var i = 0; i < 1000; i++) { histogram.Record(randomForHistogram.Next(1, 1000), tags); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs index 24272abd96..ecc48f27a8 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs @@ -32,7 +32,9 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class SerializationBenchmarks +#pragma warning restore CA1515 { private const int StringLengthLimit = (1 << 14) - 1; private const string Key = "ext_dt_traceId"; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs index 8e52bc5f8b..b97ae7f1fa 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs @@ -27,15 +27,14 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class TLDLogExporterBenchmarks +#pragma warning restore CA1515 { private readonly LogRecord logRecord; private readonly Batch batch; private readonly MsgPackLogExporter msgPackExporter; private readonly TldLogExporter tldExporter; - private readonly ILogger loggerForTLD; - private readonly ILogger loggerForMsgPack; - private readonly ILoggerFactory loggerFactoryForTLD; private readonly ILoggerFactory loggerFactoryForMsgPack; public TLDLogExporterBenchmarks() @@ -65,23 +64,6 @@ public TLDLogExporterBenchmarks() this.logRecord = GenerateTestLogRecord(); this.batch = GenerateTestLogRecordBatch(); - this.loggerFactoryForTLD = LoggerFactory.Create(builder => - builder.AddOpenTelemetry(loggerOptions => - { - loggerOptions.AddGenevaLogExporter(exporterOptions => - { - exporterOptions.ConnectionString = "EtwSession=OpenTelemetry;PrivatePreviewEnableTraceLoggingDynamic=true"; - exporterOptions.PrepopulatedFields = new Dictionary - { - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }; - }); - })); - - this.loggerForTLD = this.loggerFactoryForTLD.CreateLogger(); - this.loggerFactoryForMsgPack = LoggerFactory.Create(builder => builder.AddOpenTelemetry(loggerOptions => { @@ -96,8 +78,6 @@ public TLDLogExporterBenchmarks() }; }); })); - - this.loggerForMsgPack = this.loggerFactoryForMsgPack.CreateLogger(); } [Benchmark] @@ -128,7 +108,6 @@ public void TLD_ExportLogRecord() public void Cleanup() { this.batch.Dispose(); - this.loggerFactoryForTLD.Dispose(); this.loggerFactoryForMsgPack.Dispose(); this.tldExporter.Dispose(); this.msgPackExporter.Dispose(); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs index af493c8574..29a670b110 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs @@ -26,13 +26,15 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class TLDTraceExporterBenchmarks +#pragma warning restore CA1515 { private readonly Activity? activity; private readonly Batch batch; private readonly MsgPackTraceExporter msgPackExporter; private readonly TldTraceExporter tldExporter; - private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); + private readonly ActivitySource activitySource = new("OpenTelemetry.Exporter.Geneva.Benchmark"); public TLDTraceExporterBenchmarks() { diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs index 2a4d7e01f5..b6b012e222 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs @@ -24,13 +24,15 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] +#pragma warning disable CA1515 public class TraceExporterBenchmarks +#pragma warning restore CA1515 { private readonly Activity activity; private readonly Batch batch; private readonly MsgPackTraceExporter exporter; private readonly TracerProvider tracerProvider; - private readonly ActivitySource activitySource = new ActivitySource("OpenTelemetry.Exporter.Geneva.Benchmark"); + private readonly ActivitySource activitySource = new("OpenTelemetry.Exporter.Geneva.Benchmark"); public TraceExporterBenchmarks() { diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs index 71877c8c94..b3ddf82a70 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/Program.cs @@ -12,11 +12,10 @@ namespace OpenTelemetry.Exporter.Geneva.Stress; internal class Program { + private static readonly ActivitySource Source = new("OpenTelemetry.Exporter.Geneva.Stress"); private static volatile bool s_bContinue = true; private static long s_nEvents; - private static ActivitySource source = new ActivitySource("OpenTelemetry.Exporter.Geneva.Stress"); - private static int Main(string[] args) { return Parser.Default.ParseArguments(args) @@ -56,18 +55,6 @@ private class ExporterCreationOptions private static int RunExporterCreation() { - var options = new GenevaExporterOptions() - { - ConnectionString = "EtwSession=OpenTelemetry", - PrepopulatedFields = new Dictionary - { - ["ver"] = "4.0", - ["cloud.role"] = "BusyWorker", - ["cloud.roleInstance"] = "CY1SCH030021417", - ["cloud.roleVer"] = "9.0.15289.2", - }, - }; - for (var i = 0; i < 300000; ++i) { using var dataTransport = new EtwDataTransport("OpenTelemetry"); @@ -103,12 +90,14 @@ private static int EntryPoint(Action init, Action run) if (Console.KeyAvailable) { var key = Console.ReadKey(true).Key; +#pragma warning disable IDE0010 // Add missing cases switch (key) { case ConsoleKey.Escape: s_bContinue = false; return; } +#pragma warning restore IDE0010 // Add missing cases continue; } @@ -158,12 +147,10 @@ private static void InitTraces() [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void RunTraces() { - using (var activity = source.StartActivity("Stress")) - { - activity?.SetTag("http.method", "GET"); - activity?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); - activity?.SetTag("http.status_code", 200); - } + using var activity = Source.StartActivity("Stress"); + activity?.SetTag("http.method", "GET"); + activity?.SetTag("http.url", "https://www.wikipedia.org/wiki/Rabbit"); + activity?.SetTag("http.status_code", 200); } private static void InitTracesOnLinux(string path) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs index eaa566ed9d..d3926f00c6 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaLogExporterTests.cs @@ -33,14 +33,14 @@ public void BadArgs() [Fact] public void ExportExceptionStackDefaultIsDrop() { - GenevaExporterOptions exporterOptions = new GenevaExporterOptions(); + var exporterOptions = new GenevaExporterOptions(); Assert.Equal(ExceptionStackExportMode.Drop, exporterOptions.ExceptionStackExportMode); } [Fact] public void ExportEventNameDefaultIsNone() { - GenevaExporterOptions exporterOptions = new GenevaExporterOptions(); + var exporterOptions = new GenevaExporterOptions(); Assert.Equal(EventNameExportMode.None, exporterOptions.EventNameExportMode); } @@ -128,7 +128,7 @@ public void IncompatibleConnectionString_Linux() public void TableNameMappingTest(params string[] category) { // ARRANGE - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); Dictionary mappingsDict = null; @@ -137,8 +137,8 @@ public void TableNameMappingTest(params string[] category) var exporterOptions = new GenevaExporterOptions(); if (category?.Length > 0) { - mappingsDict = new Dictionary(); - for (int i = 0; i < category.Length; i = i + 2) + mappingsDict = []; + for (var i = 0; i < category.Length; i += 2) { mappingsDict.Add(category[i], category[i + 1]); } @@ -173,7 +173,7 @@ public void TableNameMappingTest(params string[] category) ILogger logger; object fluentdData; string actualTableName; - string defaultLogTable = "Log"; + var defaultLogTable = "Log"; if (mappingsDict != null) { foreach (var mapping in mappingsDict) @@ -224,7 +224,7 @@ public void TableNameMappingTest(params string[] category) [Fact] public void PassThruTableMappingsWhenTheRuleIsEnabled() { - string path = string.Empty; + var path = string.Empty; Socket server = null; try { @@ -238,25 +238,25 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() var expectedCategoryToTableNameList = new List> { // The category name must match "^[A-Z][a-zA-Z0-9]*$"; any character that is not allowed will be removed. - new KeyValuePair("Company.Customer", "CompanyCustomer"), + new("Company.Customer", "CompanyCustomer"), - new KeyValuePair("Company-%-Customer*Region$##", "CompanyCustomerRegion"), + new("Company-%-Customer*Region$##", "CompanyCustomerRegion"), // If the first character in the resulting string is lower-case ALPHA, // it will be converted to the corresponding upper-case. - new KeyValuePair("company.Calendar", "CompanyCalendar"), + new("company.Calendar", "CompanyCalendar"), // After removing not allowed characters, // if the resulting string is still an illegal event name, the data will get dropped on the floor. - new KeyValuePair("$&-.$~!!", null), + new("$&-.$~!!", null), - new KeyValuePair("dlmwl3bvd84bxsx8wf700nx9rydrrhfewbxf82ceoo0h8rpla4", "Dlmwl3bvd84bxsx8wf700nx9rydrrhfewbxf82ceoo0h8rpla4"), + new("dlmwl3bvd84bxsx8wf700nx9rydrrhfewbxf82ceoo0h8rpla4", "Dlmwl3bvd84bxsx8wf700nx9rydrrhfewbxf82ceoo0h8rpla4"), // If the resulting string is longer than 50 characters, only the first 50 characters will be taken. - new KeyValuePair("Company.Customer.rsLiheLClHJasBOvM.XI4uW7iop6ghvwBzahfs", "CompanyCustomerrsLiheLClHJasBOvMXI4uW7iop6ghvwBzah"), + new("Company.Customer.rsLiheLClHJasBOvM.XI4uW7iop6ghvwBzahfs", "CompanyCustomerrsLiheLClHJasBOvMXI4uW7iop6ghvwBzah"), // The data will be dropped on the floor as the exporter cannot deduce a valid table name. - new KeyValuePair("1.2", null), + new("1.2", null), }; var logRecordList = new List(); @@ -290,7 +290,7 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() using var exporter = new MsgPackLogExporter(exporterOptions); ILogger passThruTableMappingsLogger, userInitializedTableMappingsLogger; - ThreadLocal m_buffer = MsgPackLogExporter.Buffer; + var m_buffer = MsgPackLogExporter.Buffer; object fluentdData; string actualTableName; @@ -323,7 +323,7 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() _ = exporter.SerializeLogRecord(logRecordList[0]); fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); actualTableName = (fluentdData as object[])[0] as string; - string expectedTableName = string.Empty; + var expectedTableName = string.Empty; expectedTableName = mapping.Value; Assert.Equal(expectedTableName, actualTableName); @@ -348,7 +348,7 @@ public void PassThruTableMappingsWhenTheRuleIsEnabled() [InlineData(true)] public void SerializeILoggerScopes(bool hasCustomFields) { - string path = string.Empty; + var path = string.Empty; Socket senderSocket = null; Socket receiverSocket = null; try @@ -371,7 +371,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) if (hasCustomFields) { - exporterOptions.CustomFields = new string[] { "Food", "Name", "Key1" }; + exporterOptions.CustomFields = ["Food", "Name", "Key1"]; } var exportedItems = new List(); @@ -420,7 +420,7 @@ public void SerializeILoggerScopes(bool hasCustomFields) _ = receiverSocket.Receive(serializedData); } - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(serializedData, MessagePack.Resolvers.ContractlessStandardResolver.Options); var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; @@ -487,7 +487,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger.log // ARRANGE - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); try @@ -533,8 +533,8 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) default, new List>() { - new KeyValuePair("Key1", "Value1"), - new KeyValuePair("Key2", "Value2"), + new("Key1", "Value1"), + new("Key2", "Value2"), }, null, (state, ex) => "Formatted Message"); @@ -542,7 +542,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var body = GetField(fluentdData, "body"); // Body gets populated as "Formatted Message" regardless of the value of `IncludeFormattedMessage` @@ -603,7 +603,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) eventId: default, new List>() { - new KeyValuePair("Key1", "Value1"), + new("Key1", "Value1"), }, exception: null, formatter: (state, ex) => "Example formatted message."); @@ -643,7 +643,7 @@ public void SerializationTestWithILoggerLogMethod(bool includeFormattedMessage) [InlineData(true, true, true)] public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMapping, bool hasCustomFields, bool parseStateValues) { - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); try @@ -685,7 +685,7 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin { // The field "customField" of LogRecord.State should be present in the mapping as a separate key. Other fields of LogRecord.State which are not present // in CustomFields should be added in the mapping under "env_properties" - exporterOptions.CustomFields = new string[] { "customField" }; + exporterOptions.CustomFields = ["customField"]; } using var loggerFactory = LoggerFactory.Create(builder => builder @@ -752,7 +752,7 @@ public void SerializationTestWithILoggerLogWithTemplates(bool hasTableNameMappin foreach (var logRecord in logRecordList) { _ = exporter.SerializeLogRecord(logRecord); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); this.AssertFluentdForwardModeForLogRecord(exporterOptions, fluentdData, logRecord); } } @@ -805,7 +805,7 @@ public void SuccessfulExport_Windows() [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void SuccessfulExport_Linux() { - string path = GenerateTempFilePath(); + var path = GenerateTempFilePath(); var logRecordList = new List(); try { @@ -852,11 +852,11 @@ public void SuccessfulExport_Linux() // logRecordList should have a singleLogRecord entry after the logger.LogInformation call Assert.Single(logRecordList); - int messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; + var messagePackDataSize = exporter.SerializeLogRecord(logRecordList[0]).Count; // Read the data sent via socket. var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + var receivedDataSize = serverSocket.Receive(receivedData); // Validation Assert.Equal(messagePackDataSize, receivedDataSize); @@ -894,7 +894,7 @@ public void SuccessfulExport_Linux() public void SerializationTestForException() { // ARRANGE - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); try @@ -944,7 +944,7 @@ public void SerializationTestForException() // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var exceptionType = GetField(fluentdData, "env_ex_type"); var exceptionMessage = GetField(fluentdData, "env_ex_msg"); Assert.Equal("System.Exception", exceptionType); @@ -971,13 +971,15 @@ public void SerializationTestForException() public void SerializationTestForEventName(EventNameExportMode eventNameExportMode, bool hasTableNameMapping) { // ARRANGE - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); try { - var exporterOptions = new GenevaExporterOptions(); - exporterOptions.EventNameExportMode = eventNameExportMode; + var exporterOptions = new GenevaExporterOptions + { + EventNameExportMode = eventNameExportMode, + }; if (hasTableNameMapping) { @@ -1037,7 +1039,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var eventName = GetField(fluentdData, "env_name"); if (eventNameExportMode.HasFlag(EventNameExportMode.ExportAsPartAName)) @@ -1107,7 +1109,7 @@ public void SerializationTestForEventName(EventNameExportMode eventNameExportMod public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCustomFields, object customNameValue) { // ARRANGE - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); try @@ -1130,14 +1132,7 @@ public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCu if (hasCustomFields) { - if (hasNameInCustomFields) - { - exporterOptions.CustomFields = new string[] { "name", "Key1" }; - } - else - { - exporterOptions.CustomFields = new string[] { "Key1" }; - } + exporterOptions.CustomFields = hasNameInCustomFields ? ["name", "Key1"] : ["Key1"]; } using var loggerFactory = LoggerFactory.Create(builder => builder @@ -1162,8 +1157,8 @@ public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCu var state = new List>() { - new KeyValuePair("Key1", "Value1"), - new KeyValuePair("Key2", "Value2"), + new("Key1", "Value1"), + new("Key2", "Value2"), }; if (customNameValue != null) @@ -1181,7 +1176,7 @@ public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCu // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var signal = (fluentdData as object[])[0] as string; var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; @@ -1234,7 +1229,7 @@ public void SerializationTestForPartBName(bool hasCustomFields, bool hasNameInCu public void SerializationTestForEventId() { // ARRANGE - string path = string.Empty; + var path = string.Empty; Socket server = null; var logRecordList = new List(); try @@ -1284,7 +1279,7 @@ public void SerializationTestForEventId() // VALIDATE Assert.Single(logRecordList); _ = exporter.SerializeLogRecord(logRecordList[0]); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; @@ -1334,8 +1329,8 @@ public void AddGenevaExporterWithNamedOptions() ? "EtwSession=OpenTelemetry" : "Endpoint=unix:" + @"C:\Users\user\AppData\Local\Temp\14tj4ac4.v2q"; - int defaultConfigureExporterOptionsInvocations = 0; - int namedConfigureExporterOptionsInvocations = 0; + var defaultConfigureExporterOptionsInvocations = 0; + var namedConfigureExporterOptionsInvocations = 0; var sp = new ServiceCollection(); sp.AddOpenTelemetry().WithLogging(builder => builder @@ -1430,7 +1425,7 @@ private static string GenerateTempFilePath() { while (true) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!File.Exists(path)) { return path; @@ -1458,14 +1453,7 @@ private static object GetField(object fluentdData, string key) var TimeStampAndMappings = ((fluentdData as object[])[1] as object[])[0]; var mapping = (TimeStampAndMappings as object[])[1] as Dictionary; - if (mapping.TryGetValue(key, out var value)) - { - return value; - } - else - { - return null; - } + return mapping.TryGetValue(key, out var value) ? value : null; } private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporterOptions, object fluentdData, LogRecord logRecord) @@ -1554,19 +1542,14 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter Assert.Equal(logRecord.CategoryName, mapping["name"]); - bool isUnstructuredLog = true; + var isUnstructuredLog = true; IReadOnlyList> stateKeyValuePairList; // `LogRecord.State` and `LogRecord.StateValues` were marked Obsolete in https://github.com/open-telemetry/opentelemetry-dotnet/pull/4334 #pragma warning disable 0618 - if (logRecord.State == null) - { - stateKeyValuePairList = logRecord.StateValues; - } - else - { - stateKeyValuePairList = logRecord.State as IReadOnlyList>; - } + stateKeyValuePairList = logRecord.State == null + ? logRecord.StateValues + : logRecord.State as IReadOnlyList>; #pragma warning restore 0618 if (stateKeyValuePairList != null) @@ -1590,7 +1573,7 @@ private void AssertFluentdForwardModeForLogRecord(GenevaExporterOptions exporter } else { - _ = mapping.TryGetValue("env_properties", out object envProperties); + _ = mapping.TryGetValue("env_properties", out var envProperties); var envPropertiesMapping = envProperties as IDictionary; foreach (var item in stateKeyValuePairList) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index d7f189a0e6..fb6599138b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -46,7 +46,7 @@ public void InvalidConnectionString(string connectionString) [Fact] public void ParseConnectionStringCorrectly() { - string path = string.Empty; + var path = string.Empty; Socket server = null; try { @@ -114,7 +114,7 @@ public void CannotUseReservedDimensionsInPrepopulatedFields() [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public async Task SuccessfulExportOnLinux() { - string path = GenerateTempFilePath(); + var path = GenerateTempFilePath(); var exportedItems = new List(); using var meter = new Meter("SuccessfulExportOnLinux", "0.0.1"); @@ -198,7 +198,7 @@ public async Task SuccessfulExportOnLinux() // Read the data sent via socket. var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + var receivedDataSize = serverSocket.Receive(receivedData); var fixedPayloadLength = (int)typeof(TlvMetricExporter).GetField("fixedPayloadStartIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter); @@ -221,7 +221,7 @@ public async Task SuccessfulExportOnLinux() var dimensions = fields.FirstOrDefault(field => field.Type == PayloadTypes.Dimensions).Value as Dimensions; Assert.Equal(2, dimensions.NumDimensions); - int i = 0; + var i = 0; foreach (var tag in metricPoint.Tags) { Assert.Equal(tag.Key, dimensions.DimensionsNames[i].Value); @@ -378,13 +378,13 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars if (hasFilteredTagsForExemplars) { - meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = new string[] { "tag1", "tag2" } }); + meterProviderBuilder.AddView("*", new MetricStreamConfiguration { TagKeys = ["tag1", "tag2"] }); } using var meterProvider = meterProviderBuilder.Build(); long longValue = 123; - double doubleValue = 123.45; + var doubleValue = 123.45; if (testMaxLimits) { @@ -488,7 +488,7 @@ public void SuccessfulSerializationWithTLV(bool testMaxLimits, bool hasExemplars histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2"), new("filteredTag1", "filteredValue1")); } - string path = string.Empty; + var path = string.Empty; Socket server = null; try { @@ -587,23 +587,18 @@ public void SuccessfulSerializationWithTLVWithViews() using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter("SuccessfulSerializationWithViews") .AddView("longCounter", "renamedLongCounter") - .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = new string[] { "tag1" } }) + .AddView("doubleCounter", new MetricStreamConfiguration { TagKeys = ["tag1"] }) .AddView( "histogramWithCustomBounds", new ExplicitBucketHistogramConfiguration { Name = "renamedhistogramWithCustomBounds", Description = "modifiedDescription", - Boundaries = new double[] { 500, 1000, 10000 }, + Boundaries = [500, 1000, 10000], }) .AddView(instrument => { - if (instrument.Name == "histogramWithNoBounds") - { - return new ExplicitBucketHistogramConfiguration { Boundaries = Array.Empty() }; - } - - return null; + return instrument.Name == "histogramWithNoBounds" ? new ExplicitBucketHistogramConfiguration { Boundaries = [] } : null; }) .AddView( "histogramWithNoMinMax", @@ -612,29 +607,18 @@ public void SuccessfulSerializationWithTLVWithViews() RecordMinMax = false, }) .AddView("observableLongCounter", MetricStreamConfiguration.Drop) - .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = Array.Empty() }) - .AddView(instrument => - { - if (instrument.Name == "observableLongGauge") + .AddView("observableDoubleCounter", new MetricStreamConfiguration { TagKeys = [] }) + .AddView(instrument => instrument.Name == "observableLongGauge" + ? new MetricStreamConfiguration { - return new MetricStreamConfiguration - { - Name = "renamedobservableLongGauge", - Description = "modifiedDescription", - TagKeys = new string[] { "tag1" }, - }; + Name = "renamedobservableLongGauge", + Description = "modifiedDescription", + TagKeys = ["tag1"], } - - return null; - }) + : null) .AddView(instrument => { - if (instrument.Name == "observableDoubleGauge") - { - return MetricStreamConfiguration.Drop; - } - - return null; + return instrument.Name == "observableDoubleGauge" ? MetricStreamConfiguration.Drop : null; }) .AddReader(inMemoryReader) .Build(); @@ -710,7 +694,7 @@ public void SuccessfulSerializationWithTLVWithViews() histogramWithNoMinMax.Record(750, new("tag1", "value1"), new("tag2", "value2")); histogramWithNoMinMax.Record(2500, new("tag1", "value1"), new("tag2", "value2")); - string path = string.Empty; + var path = string.Empty; Socket server = null; try { @@ -743,7 +727,7 @@ public void SuccessfulSerializationWithTLVWithViews() Assert.Equal(7, exportedItems.Count); // observableLongCounter and observableDoubleGauge are dropped - Assert.DoesNotContain(exportedItems, item => item.Name == "observableLongCounter" || item.Name == "observableDoubleGauge"); + Assert.DoesNotContain(exportedItems, item => item.Name is "observableLongCounter" or "observableDoubleGauge"); // check serialization for longCounter CheckSerializationWithTLVForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); @@ -795,7 +779,7 @@ public void SuccessfulSerializationWithCustomAccountAndNamespace() .Build(); long longValue = 123; - double doubleValue = 123.45; + var doubleValue = 123.45; longCounter.Add( longValue, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForLongCounter")); @@ -828,7 +812,7 @@ public void SuccessfulSerializationWithCustomAccountAndNamespace() histogram.Record(750, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); histogram.Record(2500, new("tag1", "value1"), new("tag2", "value2"), new("_microsoft_metrics_account", "AccountForHistogram"), new("_microsoft_metrics_namespace", "NamespaceForHistogram")); - string path = string.Empty; + var path = string.Empty; Socket server = null; try { @@ -940,7 +924,7 @@ private static string GenerateTempFilePath() { while (true) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!File.Exists(path)) { return path; @@ -1028,7 +1012,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal((ushort)MetricEventType.TLV, data.EventId); Assert.Equal(bodyLength, data.LenBody); } - else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + else if (metricType is MetricType.DoubleSum or MetricType.DoubleGauge) { var metricDataValue = metricType == MetricType.DoubleSum ? metricPoint.GetSumDouble() : @@ -1057,7 +1041,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal((ushort)MetricEventType.TLV, data.EventId); Assert.Equal(bodyLength, data.LenBody); } - else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) + else if (metricType is MetricType.LongSumNonMonotonic or MetricType.DoubleSumNonMonotonic) { var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? Convert.ToDouble(metricPoint.GetSumLong()) : @@ -1090,7 +1074,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, { var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (!metricPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { min = 0; max = 0; @@ -1119,8 +1103,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, var valueSection = fields.FirstOrDefault(field => field.Type == PayloadTypes.ExtAggregatedUint64Value).Value as ExtAggregatedUint64ValueV2; var valueCountPairs = fields.FirstOrDefault(field => field.Type == PayloadTypes.HistogramUint64ValueCountPairs).Value as HistogramValueCountPairs; - int listIterator = 0; - int bucketsWithPositiveCount = 0; + var listIterator = 0; + var bucketsWithPositiveCount = 0; double lastExplicitBound = default; foreach (var bucket in metricPoint.GetHistogramBuckets()) { @@ -1145,7 +1129,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(bodyLength, data.LenBody); } - List validExemplars = new List(); + List validExemplars = []; foreach (var exemplar in exemplars) { @@ -1163,7 +1147,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, Assert.Equal(validExemplars.Count, exemplarsPayload.NumberOfExemplars.Value); Assert.Equal(validExemplars.Count, singleExemplarList.Count); - for (int i = 0; i < validExemplars.Count; i++) + for (var i = 0; i < validExemplars.Count; i++) { var expectedExemplar = validExemplars[i]; var serializedExemplar = singleExemplarList[i]; @@ -1175,8 +1159,8 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, // Check metric name, account, and namespace var connectionStringBuilder = new ConnectionStringBuilder(exporterOptions.ConnectionString); - string monitoringAccount = connectionStringBuilder.Account; - string metricNamespace = connectionStringBuilder.Namespace; + var monitoringAccount = connectionStringBuilder.Account; + var metricNamespace = connectionStringBuilder.Namespace; foreach (var tag in metricPoint.Tags) { @@ -1215,7 +1199,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, } // Check metric dimensions - int index = 0; + var index = 0; foreach (var item in exporterOptions.PrepopulatedMetricDimensions) { Assert.Equal(item.Key, dimensions.DimensionsNames[index].Value); @@ -1223,7 +1207,7 @@ private static void CheckSerializationWithTLVForSingleMetricPoint(Metric metric, index++; } - int reservedTags = 0; + var reservedTags = 0; foreach (var tag in metricPoint.Tags) { if (tag.Key.Equals("_microsoft_metrics_account", StringComparison.OrdinalIgnoreCase) || @@ -1282,8 +1266,8 @@ private static void AssertExemplarFilteredTagSerialization(Exemplar expectedExem } int filteredTagsActualCount = serializedExemplarBody.NumberOfLabels; - int filteredTagsExpectedCount = 0; - int filteredTagsActualIndex = 0; + var filteredTagsExpectedCount = 0; + var filteredTagsActualIndex = 0; foreach (var tag in expectedExemplar.FilteredTags) { @@ -1351,7 +1335,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp var data = new MetricsContract(stream); result = data.Body as UserdataV2; } - else if (metricType == MetricType.DoubleSum || metricType == MetricType.DoubleGauge) + else if (metricType is MetricType.DoubleSum or MetricType.DoubleGauge) { var metricDataValue = metricType == MetricType.DoubleSum ? metricPoint.GetSumDouble() : @@ -1373,7 +1357,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp var data = new MetricsContract(stream); result = data.Body as UserdataV2; } - else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) + else if (metricType is MetricType.LongSumNonMonotonic or MetricType.DoubleSumNonMonotonic) { var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? Convert.ToDouble(metricPoint.GetSumLong()) : @@ -1399,7 +1383,7 @@ private static UserdataV2 GetSerializedData(Metric metric, TlvMetricExporter exp { var sum = Convert.ToUInt64(metricPoint.GetHistogramSum()); var count = Convert.ToUInt32(metricPoint.GetHistogramCount()); - if (!metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) + if (!metricPoint.TryGetHistogramMinMaxValues(out var min, out var max)) { min = 0; max = 0; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs index 06e6ee74d0..e7bbe4cc05 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaTraceExporterTests.cs @@ -169,7 +169,7 @@ public void GenevaTraceExporter_Success_Windows() } var link = new ActivityLink(new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded)); - using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, new ActivityLink[] { link })) + using (var activity = source.StartActivity("Foo", ActivityKind.Internal, null, null, [link])) { } @@ -195,11 +195,11 @@ public void GenevaTraceExporter_Success_Windows() [InlineData(true, true, true)] public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, bool hasCustomFields, bool includeTraceState) { - string path = string.Empty; + var path = string.Empty; Socket server = null; try { - int invocationCount = 0; + var invocationCount = 0; var exporterOptions = new GenevaExporterOptions { PrepopulatedFields = new Dictionary @@ -232,7 +232,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, { // The tag "clientRequestId" should be present in the mapping as a separate key. Other tags which are not present // in the m_dedicatedFields should be added in the mapping under "env_properties" - exporterOptions.CustomFields = new string[] { "clientRequestId" }; + exporterOptions.CustomFields = ["clientRequestId"]; } if (includeTraceState) @@ -259,7 +259,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, listener.ActivityStopped = (activity) => { _ = exporter.SerializeActivity(activity); - object fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(m_buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); this.AssertFluentdForwardModeForActivity(exporterOptions, fluentdData, activity, CS40_PART_B_MAPPING, dedicatedFields, customChecksForActivity); invocationCount++; }; @@ -291,17 +291,15 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, ActivityTraceFlags.Recorded)), }; - using (var activity = source.StartActivity("SayHello", ActivityKind.Internal, parentActivity.Context, null, links)) - { - activity?.SetTag("http.status_code", 500); // This should be added as httpStatusCode in the mapping - activity?.SetTag("azureResourceProvider", "Microsoft.AAD"); - activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); - activity?.SetTag("foo", 1); - activity?.SetTag("bar", 2); + using var activity = source.StartActivity("SayHello", ActivityKind.Internal, parentActivity.Context, null, links); + activity?.SetTag("http.status_code", 500); // This should be added as httpStatusCode in the mapping + activity?.SetTag("azureResourceProvider", "Microsoft.AAD"); + activity?.SetTag("clientRequestId", "58a37988-2c05-427a-891f-5e0e1266fcc5"); + activity?.SetTag("foo", 1); + activity?.SetTag("bar", 2); #pragma warning disable CS0618 // Type or member is obsolete - activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); + activity?.SetStatus(Status.Error.WithDescription("Error description from OTel API")); #pragma warning restore CS0618 // Type or member is obsolete - } } using (var activity = source.StartActivity("TestActivityForSetStatusAPI")) @@ -341,7 +339,7 @@ public void GenevaTraceExporter_Serialization_Success(bool hasTableNameMapping, [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() { - string path = GetRandomFilePath(); + var path = GetRandomFilePath(); // System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Cannot assign requested address try @@ -386,7 +384,7 @@ public void GenevaTraceExporter_Constructor_Missing_Agent_Linux() [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void GenevaTraceExporter_Success_Linux() { - string path = GetRandomFilePath(); + var path = GetRandomFilePath(); try { var endpoint = new UnixDomainSocketEndPoint(path); @@ -411,7 +409,7 @@ public void GenevaTraceExporter_Success_Linux() }; }) .Build(); - using Socket serverSocket = server.Accept(); + using var serverSocket = server.Accept(); serverSocket.ReceiveTimeout = 10000; // Create a test exporter to get MessagePack byte data for validation of the data received via Socket. @@ -428,7 +426,7 @@ public void GenevaTraceExporter_Success_Linux() // Emit trace and grab a copy of internal buffer for validation. var source = new ActivitySource(sourceName); - int messagePackDataSize = 0; + var messagePackDataSize = 0; using (var activity = source.StartActivity("Foo", ActivityKind.Internal)) { @@ -437,7 +435,7 @@ public void GenevaTraceExporter_Success_Linux() // Read the data sent via socket. var receivedData = new byte[1024]; - int receivedDataSize = serverSocket.Receive(receivedData); + var receivedDataSize = serverSocket.Receive(receivedData); // Validation Assert.Equal(messagePackDataSize, receivedDataSize); @@ -445,10 +443,8 @@ public void GenevaTraceExporter_Success_Linux() // Create activity on a different thread to test for multithreading scenarios var thread = new Thread(() => { - using (var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal)) - { - messagePackDataSize = exporter.SerializeActivity(activity).Count; - } + using var activity = source.StartActivity("ActivityFromAnotherThread", ActivityKind.Internal); + messagePackDataSize = exporter.SerializeActivity(activity).Count; }); thread.Start(); thread.Join(); @@ -496,15 +492,13 @@ public void TLDTraceExporter_Success_Windows() .Build(); var source = new ActivitySource(sourceName); - using (var activity = source.StartActivity("SayHello")) - { - activity?.SetTag("foo", 1); - activity?.SetTag("bar", "Hello, World!"); + using var activity = source.StartActivity("SayHello"); + activity?.SetTag("foo", 1); + activity?.SetTag("bar", "Hello, World!"); #pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array - activity?.SetTag("baz", new int[] { 1, 2, 3 }); + activity?.SetTag("baz", new int[] { 1, 2, 3 }); #pragma warning restore CA1861 // Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array - activity?.SetStatus(ActivityStatusCode.Ok); - } + activity?.SetStatus(ActivityStatusCode.Ok); } [Fact] @@ -606,7 +600,7 @@ private static string GetRandomFilePath() { while (true) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!File.Exists(path)) { return path; @@ -722,10 +716,10 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO #region Assert Activity Links if (activity.Links.Any()) { - Assert.Contains(mapping, m => m.Key as string == "links"); + Assert.Contains(mapping, m => (m.Key as string) == "links"); var mappingLinks = mapping["links"] as IEnumerable; - using IEnumerator activityLinksEnumerator = activity.Links.GetEnumerator(); - using IEnumerator mappingLinksEnumerator = mappingLinks.GetEnumerator(); + using var activityLinksEnumerator = activity.Links.GetEnumerator(); + using var mappingLinksEnumerator = mappingLinks.GetEnumerator(); while (activityLinksEnumerator.MoveNext() && mappingLinksEnumerator.MoveNext()) { var activityLink = activityLinksEnumerator.Current; @@ -741,16 +735,16 @@ private void AssertFluentdForwardModeForActivity(GenevaExporterOptions exporterO } else { - Assert.DoesNotContain(mapping, m => m.Key as string == "links"); + Assert.DoesNotContain(mapping, m => (m.Key as string) == "links"); } #endregion #region Assert Activity Tags - _ = mapping.TryGetValue("env_properties", out object envProperties); + _ = mapping.TryGetValue("env_properties", out var envProperties); var envPropertiesMapping = envProperties as IDictionary; foreach (var tag in activity.TagObjects) { - if (CS40_PART_B_MAPPING.TryGetValue(tag.Key, out string replacementKey)) + if (CS40_PART_B_MAPPING.TryGetValue(tag.Key, out var replacementKey)) { Assert.Equal(tag.Value.ToString(), mapping[replacementKey].ToString()); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs index 783e3524cf..d578fc2519 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/JsonSerializerTests.cs @@ -12,34 +12,33 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; public static class JsonSerializerTests { public static IEnumerable Data => - new List - { - new object[] { null, "null" }, - new object[] { true, "true" }, - new object[] { false, "false" }, - new object[] { 0, "0" }, - new object[] { 123, "123" }, - new object[] { -123, "-123" }, - new object[] { 0.0f, "0" }, - new object[] { 1.0f, "1" }, - new object[] { 3.14f, "3.14" }, - new object[] { -3.14f, "-3.14" }, - new object[] { 0.0d, "0" }, - new object[] { 3.14d, "3.14" }, - new object[] { 3.1415926d, "3.1415926" }, - new object[] { -3.1415926d, "-3.1415926" }, - new object[] { string.Empty, "''".Replace("'", "\"") }, - new object[] { "Hello, World!", "'Hello, World!'".Replace("'", "\"") }, - new object[] { "\"", "'\\\"'".Replace("'", "\"") }, - new object[] { "\n", "'\\n'".Replace("'", "\"") }, - new object[] { "\t", "'\\t'".Replace("'", "\"") }, - new object[] { "\0", "'\\u0000'".Replace("'", "\"") }, - new object[] { "\u6768", "'\\u6768'".Replace("'", "\"") }, - new object[] { Array.Empty(), "[]" }, - new object[] { new object[] { 1, 2, 3 }, "[1,2,3]" }, - new object[] { new Dictionary(), "{}" }, - new object[] { new Dictionary { ["foo"] = 1, ["bar"] = "baz", ["golden ratio"] = 0.6180340f, ["pi"] = 3.14159265358979d }, "{'foo':1,'bar':'baz','golden ratio':0.618034,'pi':3.14159265358979}".Replace("'", "\"") }, - }; + [ + [null, "null"], + [true, "true"], + [false, "false"], + [0, "0"], + [123, "123"], + [-123, "-123"], + [0.0f, "0"], + [1.0f, "1"], + [3.14f, "3.14"], + [-3.14f, "-3.14"], + [0.0d, "0"], + [3.14d, "3.14"], + [3.1415926d, "3.1415926"], + [-3.1415926d, "-3.1415926"], + [string.Empty, "''".Replace("'", "\"")], + ["Hello, World!", "'Hello, World!'".Replace("'", "\"")], + ["\"", "'\\\"'".Replace("'", "\"")], + ["\n", "'\\n'".Replace("'", "\"")], + ["\t", "'\\t'".Replace("'", "\"")], + ["\0", "'\\u0000'".Replace("'", "\"")], + ["\u6768", "'\\u6768'".Replace("'", "\"")], + [Array.Empty(), "[]"], + [new object[] { 1, 2, 3 }, "[1,2,3]"], + [new Dictionary(), "{}"], + [new Dictionary { ["foo"] = 1, ["bar"] = "baz", ["golden ratio"] = 0.6180340f, ["pi"] = 3.14159265358979d }, "{'foo':1,'bar':'baz','golden ratio':0.618034,'pi':3.14159265358979}".Replace("'", "\"")], + ]; [Theory] [MemberData(nameof(Data))] @@ -87,7 +86,6 @@ public static void JsonSerializer_Numeric() [Trait("Platform", "Any")] public static void JsonSerializer_String() { - TestSerialization((string)null, "null"); TestSerialization(string.Empty, "''".Replace("'", "\"")); TestSerialization("Hello, World!", "'Hello, World!'".Replace("'", "\"")); TestSerialization("\"", "'\\\"'".Replace("'", "\"")); @@ -101,7 +99,6 @@ public static void JsonSerializer_String() [Trait("Platform", "Any")] public static void JsonSerializer_Array() { - TestSerialization((object[])null, "null"); TestSerialization(Array.Empty(), "[]"); TestSerialization(new object[] { 1, 2, 3 }, "[1,2,3]"); } @@ -110,7 +107,6 @@ public static void JsonSerializer_Array() [Trait("Platform", "Any")] public static void JsonSerializer_Map() { - TestSerialization((Dictionary)null, "null"); TestSerialization(new Dictionary(), "{}"); TestSerialization( new Dictionary diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs index d71cbb2cb7..0c9758db87 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/LogSerializationTests.cs @@ -9,7 +9,6 @@ using OpenTelemetry.Exporter.Geneva.MsgPack; using OpenTelemetry.Logs; using Xunit; -using Xunit.Abstractions; namespace OpenTelemetry.Exporter.Geneva.Tests; @@ -19,13 +18,6 @@ public class LogSerializationTests Run from the current directory: dotnet test -f net8.0 --filter FullyQualifiedName~LogSerializationTests -l "console;verbosity=detailed" */ - private readonly ITestOutputHelper output; - - public LogSerializationTests(ITestOutputHelper output) - { - this.output = output; - } - [Fact] public void SerializationTestForException() { @@ -83,18 +75,10 @@ public void SerializationTestForExceptionTrim() // PrintFields(this.output, exportedFields); } - private static void PrintFields(ITestOutputHelper output, Dictionary fields) - { - foreach (var field in fields) - { - output.WriteLine($"{field.Key}:{field.Value}"); - } - } - private static Dictionary GetExportedFieldsAfterLogging(Action doLog, Action configureGeneva = null) { Socket server = null; - string path = string.Empty; + var path = string.Empty; try { var logRecordList = new List(); @@ -128,7 +112,7 @@ private static Dictionary GetExportedFieldsAfterLogging(Action(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); + var fluentdData = MessagePack.MessagePackSerializer.Deserialize(MsgPackLogExporter.Buffer.Value, MessagePack.Resolvers.ContractlessStandardResolver.Options); return GetFields(fluentdData); } @@ -149,7 +133,7 @@ private static string GenerateTempFilePath() { while (true) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!File.Exists(path)) { return path; @@ -176,7 +160,7 @@ private static Dictionary GetFields(object fluentdData) private class MyException : Exception { - private string stackTrace; + private readonly string stackTrace; public MyException(string message, string stackTrace) : base(message) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs index 640f78f0c0..b6d364c5ff 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/MessagePackSerializerTests.cs @@ -16,14 +16,12 @@ public class MessagePackSerializerTests private void AssertBytes(byte[] expected, byte[] actual, int length) { Assert.Equal(expected.Length, length); - for (int i = 0; i < length; i++) + for (var i = 0; i < length; i++) { - byte expectedByte = expected[i]; - byte actualByte = actual[i]; + var expectedByte = expected[i]; + var actualByte = actual[i]; - Assert.True( - expectedByte == actualByte, - string.Format($"Expected: '{(byte)expectedByte}', Actual: '{(byte)actualByte}' at offset {i}.")); + Assert.Equal(expectedByte, actualByte); } } @@ -150,7 +148,7 @@ public void MessagePackSerializer_Boolean() public void MessagePackSerializer_Int() { // 8 bits - for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + for (var value = sbyte.MinValue; value < sbyte.MaxValue; value++) { this.MessagePackSerializer_TestSerialization(value); } @@ -158,7 +156,7 @@ public void MessagePackSerializer_Int() this.MessagePackSerializer_TestSerialization(sbyte.MaxValue); // 16 bits - for (short value = short.MinValue; value < short.MaxValue; value++) + for (var value = short.MinValue; value < short.MaxValue; value++) { this.MessagePackSerializer_TestSerialization(value); } @@ -168,20 +166,20 @@ public void MessagePackSerializer_Int() // 32 bits this.MessagePackSerializer_TestSerialization(int.MinValue); this.MessagePackSerializer_TestSerialization(int.MinValue + 1); - this.MessagePackSerializer_TestSerialization((int)short.MinValue - 1); + this.MessagePackSerializer_TestSerialization(short.MinValue - 1); this.MessagePackSerializer_TestSerialization((int)short.MinValue); - this.MessagePackSerializer_TestSerialization((int)short.MinValue + 1); - this.MessagePackSerializer_TestSerialization((int)sbyte.MinValue - 1); - for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + this.MessagePackSerializer_TestSerialization(short.MinValue + 1); + this.MessagePackSerializer_TestSerialization(sbyte.MinValue - 1); + for (var value = sbyte.MinValue; value < sbyte.MaxValue; value++) { this.MessagePackSerializer_TestSerialization((int)value); } this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue); - this.MessagePackSerializer_TestSerialization((int)sbyte.MaxValue + 1); - this.MessagePackSerializer_TestSerialization((int)short.MaxValue - 1); + this.MessagePackSerializer_TestSerialization(sbyte.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(short.MaxValue - 1); this.MessagePackSerializer_TestSerialization((int)short.MaxValue); - this.MessagePackSerializer_TestSerialization((int)short.MaxValue + 1); + this.MessagePackSerializer_TestSerialization(short.MaxValue + 1); this.MessagePackSerializer_TestSerialization(int.MaxValue - 1); this.MessagePackSerializer_TestSerialization(int.MaxValue); @@ -195,7 +193,7 @@ public void MessagePackSerializer_Int() this.MessagePackSerializer_TestSerialization((long)short.MinValue); this.MessagePackSerializer_TestSerialization((long)short.MinValue + 1); this.MessagePackSerializer_TestSerialization((long)sbyte.MinValue - 1); - for (sbyte value = sbyte.MinValue; value < sbyte.MaxValue; value++) + for (var value = sbyte.MinValue; value < sbyte.MaxValue; value++) { this.MessagePackSerializer_TestSerialization((long)value); } @@ -216,7 +214,7 @@ public void MessagePackSerializer_Int() public void MessagePackSerializer_UInt() { // 8 bits - for (byte value = byte.MinValue; value < byte.MaxValue; value++) + for (var value = byte.MinValue; value < byte.MaxValue; value++) { this.MessagePackSerializer_TestSerialization(value); } @@ -224,7 +222,7 @@ public void MessagePackSerializer_UInt() this.MessagePackSerializer_TestSerialization(byte.MaxValue); // 16 bits - for (ushort value = ushort.MinValue; value < ushort.MaxValue; value++) + for (var value = ushort.MinValue; value < ushort.MaxValue; value++) { this.MessagePackSerializer_TestSerialization(value); } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index 5ac0832ba0..d1856b528a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -22,15 +22,15 @@ public abstract class OtlpProtobufMetricExporterTests public TagList TagListWithPrepopulatedDimensions; - private static readonly Dictionary prepopulatedMetricDimensions = new Dictionary + private static readonly Dictionary prepopulatedMetricDimensions = new() { { "Dim1", 1 }, { "Dim2", 2 }, { "Dim3", 3 }, }; - private static readonly string[] TagKeys = new[] - { + private static readonly string[] TagKeys = + [ "boolKey", "doubleKey", "intKey", @@ -47,8 +47,8 @@ public abstract class OtlpProtobufMetricExporterTests "stringValueUnicodeKey", "uintKey", "ulongKey", - "ushortKey", - }; + "ushortKey" + ]; private TagList exemplarTagList; @@ -56,23 +56,23 @@ protected OtlpProtobufMetricExporterTests() { this.TagList = default; - bool boolValue = true; - double doubleValue = 23.45; - int intValue = 29; + var boolValue = true; + var doubleValue = 23.45; + var intValue = 29; long longValue = 345; - double negativeDoubleValue = -23.45; - int negativeIntValue = -29; + var negativeDoubleValue = -23.45; + var negativeIntValue = -29; long negativeLongValue = -97; - sbyte negativeSbyteValue = sbyte.MinValue; + var negativeSbyteValue = sbyte.MinValue; short negativeShortValue = -12; - sbyte sByteValue = sbyte.MaxValue; - short shortValue = short.MaxValue; - string stringValueAscii = "TestString"; - string stringValueMixAsciiAndUnicode = "\u0418TestString"; - string stringValueUnicode = "\u0418"; - uint uintValue = uint.MaxValue; + var sByteValue = sbyte.MaxValue; + var shortValue = short.MaxValue; + var stringValueAscii = "TestString"; + var stringValueMixAsciiAndUnicode = "\u0418TestString"; + var stringValueUnicode = "\u0418"; + var uintValue = uint.MaxValue; ulong ulongValue = 1234; - ushort ushortValue = ushort.MaxValue; + var ushortValue = ushort.MaxValue; // Keep the keys in sorted order, Sdk outputs them in sorted order. this.TagList.Add(new("boolKey", boolValue)); @@ -182,16 +182,16 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; - Dictionary resourceAttributes = new Dictionary + var resourceAttributes = new Dictionary { { "TestResourceKey", "TestResourceValue" }, { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, }; - string expectedAccount = "TestAccount"; - string expectedNamespace = "TestNameSpace"; - Dictionary accountAndNamespace = new Dictionary + var expectedAccount = "TestAccount"; + var expectedNamespace = "TestNameSpace"; + var accountAndNamespace = new Dictionary { { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, @@ -249,7 +249,7 @@ public void CounterSerializationSingleMetricPoint(string instrumentName, long? l addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch([.. exportedItems], exportedItems.Count)); Assert.Single(testTransport.ExportedItems); @@ -381,12 +381,12 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long .AddReader(inMemoryReader) .Build(); - int expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; - TagList[] tags = new TagList[expectedMetricPoints]; + var expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; + var tags = new TagList[expectedMetricPoints]; - for (int i = 0; i < tags.Length; i++) + for (var i = 0; i < tags.Length; i++) { - for (int j = 1; j <= (i + 1); j++) + for (var j = 1; j <= (i + 1); j++) { tags[i].Add(new("tag" + j, "value" + j)); } @@ -396,7 +396,7 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long { var counter = meter.CreateCounter(instrumentName); - for (int i = 0; i < longValues.Length; i++) + for (var i = 0; i < longValues.Length; i++) { counter.Add(longValues[i], tags[i]); } @@ -405,7 +405,7 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long { var counter = meter.CreateCounter(instrumentName); - for (int i = 0; i < doubleValues.Length; i++) + for (var i = 0; i < doubleValues.Length; i++) { counter.Add(doubleValues[i], tags[i]); } @@ -424,14 +424,14 @@ public void CounterSerializationMultipleMetricPoints(string instrumentName, long prepopulatedMetricDimensions: null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch([.. exportedItems], exportedItems.Count)); Assert.Equal(expectedMetricPoints, testTransport.ExportedItems.Count); // For asserting time var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); - for (int i = 0; i < expectedMetricPoints; i++) + for (var i = 0; i < expectedMetricPoints; i++) { var request = this.AssertAndConvertExportedBlobToRequest( testTransport.ExportedItems[i]); @@ -507,16 +507,16 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; - Dictionary resourceAttributes = new Dictionary + var resourceAttributes = new Dictionary { { "TestResourceKey", "TestResourceValue" }, { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, }; - string expectedAccount = "TestAccount"; - string expectedNamespace = "TestNameSpace"; - Dictionary accountAndNamespace = new Dictionary + var expectedAccount = "TestAccount"; + var expectedNamespace = "TestNameSpace"; + var accountAndNamespace = new Dictionary { { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, @@ -554,7 +554,7 @@ public void UpdownCounterSerializationSingleMetricPoint(string instrumentName, l addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch([.. exportedItems], exportedItems.Count)); Assert.Single(testTransport.ExportedItems); @@ -636,12 +636,12 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName .AddReader(inMemoryReader) .Build(); - int expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; - TagList[] tags = new TagList[expectedMetricPoints]; + var expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; + var tags = new TagList[expectedMetricPoints]; - for (int i = 0; i < tags.Length; i++) + for (var i = 0; i < tags.Length; i++) { - for (int j = 1; j <= (i + 1); j++) + for (var j = 1; j <= (i + 1); j++) { tags[i].Add(new("tag" + j, "value" + j)); } @@ -651,7 +651,7 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName { var counter = meter.CreateUpDownCounter(instrumentName); - for (int i = 0; i < longValues.Length; i++) + for (var i = 0; i < longValues.Length; i++) { counter.Add(longValues[i], tags[i]); } @@ -660,7 +660,7 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName { var counter = meter.CreateUpDownCounter(instrumentName); - for (int i = 0; i < doubleValues.Length; i++) + for (var i = 0; i < doubleValues.Length; i++) { counter.Add(doubleValues[i], tags[i]); } @@ -679,14 +679,14 @@ public void UpdownCounterSerializationMultipleMetricPoints(string instrumentName prepopulatedMetricDimensions: null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch([.. exportedItems], exportedItems.Count)); Assert.Equal(expectedMetricPoints, testTransport.ExportedItems.Count); // For asserting time var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); - for (int i = 0; i < expectedMetricPoints; i++) + for (var i = 0; i < expectedMetricPoints; i++) { var request = this.AssertAndConvertExportedBlobToRequest( testTransport.ExportedItems[i]); @@ -786,16 +786,16 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; - Dictionary resourceAttributes = new Dictionary + var resourceAttributes = new Dictionary { { "TestResourceKey", "TestResourceValue" }, { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, }; - string expectedAccount = "TestAccount"; - string expectedNamespace = "TestNameSpace"; - Dictionary accountAndNamespace = new Dictionary + var expectedAccount = "TestAccount"; + var expectedNamespace = "TestNameSpace"; + var accountAndNamespace = new Dictionary { { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, @@ -839,7 +839,7 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch([.. exportedItems], exportedItems.Count)); Assert.Single(testTransport.ExportedItems); @@ -883,8 +883,8 @@ public void HistogramSerializationSingleMetricPoint(double doubleValue, bool add metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - int bucketCountIndex = 0; - int explicitBoundCountIndex = 0; + var bucketCountIndex = 0; + var explicitBoundCountIndex = 0; foreach (var histogramMeasurement in metricPoint.GetHistogramBuckets()) { @@ -975,7 +975,7 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) }; var resourceBuilder = ResourceBuilder.CreateDefault().Clear() - .AddAttributes(new[] { new KeyValuePair("TestResourceKey", "TestResourceValue") }); + .AddAttributes([new KeyValuePair("TestResourceKey", "TestResourceValue")]); using var meterProvider = Sdk.CreateMeterProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddMeter(nameof(this.HistogramSerializationSingleMetricPoint)) @@ -984,19 +984,19 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) var histogram = meter.CreateHistogram("TestHistogram"); - int expectedMetricPointCount = doubleValues.Length; + var expectedMetricPointCount = doubleValues.Length; - TagList[] tags = new TagList[expectedMetricPointCount]; + var tags = new TagList[expectedMetricPointCount]; - for (int i = 0; i < tags.Length; i++) + for (var i = 0; i < tags.Length; i++) { - for (int j = 1; j <= (i + 1); j++) + for (var j = 1; j <= (i + 1); j++) { tags[i].Add(new("tag" + j, "value" + j)); } } - for (int i = 0; i < expectedMetricPointCount; i++) + for (var i = 0; i < expectedMetricPointCount; i++) { histogram.Record(doubleValues[i], tags[i]); } @@ -1014,13 +1014,13 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) prepopulatedMetricDimensions: null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch([.. exportedItems], exportedItems.Count)); Assert.Equal(expectedMetricPointCount, testTransport.ExportedItems.Count); var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); - for (int i = 0; i < expectedMetricPointCount; i++) + for (var i = 0; i < expectedMetricPointCount; i++) { var request = this.AssertAndConvertExportedBlobToRequest( testTransport.ExportedItems[i]); @@ -1058,8 +1058,8 @@ public void HistogramSerializationMultipleMetricPoints(double[] doubleValues) metricPointsEnumerator.MoveNext(); var metricPoint = metricPointsEnumerator.Current; - int bucketCountIndex = 0; - int explicitBoundCountIndex = 0; + var bucketCountIndex = 0; + var explicitBoundCountIndex = 0; foreach (var histogramMeasurement in metricPoint.GetHistogramBuckets()) { @@ -1115,16 +1115,16 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; - Dictionary resourceAttributes = new Dictionary + var resourceAttributes = new Dictionary { { "TestResourceKey", "TestResourceValue" }, { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, }; - string expectedAccount = "TestAccount"; - string expectedNamespace = "TestNameSpace"; - Dictionary accountAndNamespace = new Dictionary + var expectedAccount = "TestAccount"; + var expectedNamespace = "TestNameSpace"; + var accountAndNamespace = new Dictionary { { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, @@ -1170,7 +1170,7 @@ public void GaugeSerializationSingleMetricPoint(string instrumentName, long? lon addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch([.. exportedItems], exportedItems.Count)); Assert.Single(testTransport.ExportedItems); @@ -1248,12 +1248,12 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] .AddReader(inMemoryReader) .Build(); - int expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; - TagList[] tags = new TagList[expectedMetricPoints]; + var expectedMetricPoints = longValues != null ? longValues.Length : doubleValues.Length; + var tags = new TagList[expectedMetricPoints]; - for (int i = 0; i < tags.Length; i++) + for (var i = 0; i < tags.Length; i++) { - for (int j = 1; j <= (i + 1); j++) + for (var j = 1; j <= (i + 1); j++) { tags[i].Add(new("tag" + j, "value" + j)); } @@ -1267,8 +1267,8 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] instrumentName, () => { - List> list = new List>(); - for (int i = 0; i < longValues.Length; i++) + List> list = []; + for (var i = 0; i < longValues.Length; i++) { list.Add(new(longValues[i], tags[i])); } @@ -1282,8 +1282,8 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] instrumentName, () => { - List> list = new List>(); - for (int i = 0; i < doubleValues.Length; i++) + List> list = []; + for (var i = 0; i < doubleValues.Length; i++) { list.Add(new(doubleValues[i], tags[i])); } @@ -1305,14 +1305,14 @@ public void GaugeSerializationMultipleMetricPoints(string instrumentName, long[] prepopulatedMetricDimensions: null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, Resource.Empty, new Batch([.. exportedItems], exportedItems.Count)); Assert.Equal(expectedMetricPoints, testTransport.ExportedItems.Count); // For asserting time var metricPointsEnumerator = exportedItems[0].GetMetricPoints().GetEnumerator(); - for (int i = 0; i < expectedMetricPoints; i++) + for (var i = 0; i < expectedMetricPoints; i++) { var request = this.AssertAndConvertExportedBlobToRequest( testTransport.ExportedItems[i]); @@ -1408,16 +1408,16 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal TemporalityPreference = MetricReaderTemporalityPreference.Delta, }; - Dictionary resourceAttributes = new Dictionary + var resourceAttributes = new Dictionary { { "TestResourceKey", "TestResourceValue" }, { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, "ResourceAccount" }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, "ResourceNamespace" }, }; - string expectedAccount = "TestAccount"; - string expectedNamespace = "TestNameSpace"; - Dictionary accountAndNamespace = new Dictionary + var expectedAccount = "TestAccount"; + var expectedNamespace = "TestNameSpace"; + var accountAndNamespace = new Dictionary { { GenevaMetricExporter.DimensionKeyForCustomMonitoringAccount, expectedAccount }, { GenevaMetricExporter.DimensionKeyForCustomMetricsNamespace, expectedNamespace }, @@ -1469,7 +1469,7 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal addPrepopulatedDimensions ? prepopulatedMetricDimensions : null, prefixBufferWithUInt32LittleEndianLength: this.PrefixBufferWithUInt32LittleEndianLength); - otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch(exportedItems.ToArray(), exportedItems.Count)); + otlpProtobufSerializer.SerializeAndSendMetrics(buffer, meterProvider.GetResource(), new Batch([.. exportedItems], exportedItems.Count)); Assert.Single(testTransport.ExportedItems); @@ -1564,9 +1564,9 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal var exemplarsEnumerator = exemplars.GetEnumerator(); - double[] exemplarValues = doubleValue.Value > 0 ? new double[] { doubleValue.Value, 0 } : new double[] { 0 }; + double[] exemplarValues = doubleValue.Value > 0 ? [doubleValue.Value, 0] : [0]; - int exemplarValuesIndex = 0; + var exemplarValuesIndex = 0; foreach (var exemplar in dataPoint.Exemplars) { @@ -1612,8 +1612,8 @@ internal static void AssertOtlpAttributes( RepeatedField actual) { var expectedAttributes = expected.ToList(); - int expectedAttributesCount = expectedAttributes.Count; - for (int i = 0; i < expectedAttributesCount; i++) + var expectedAttributesCount = expectedAttributes.Count; + for (var i = 0; i < expectedAttributesCount; i++) { var current = expectedAttributes[i].Value; @@ -1685,7 +1685,7 @@ private OtlpCollector.ExportMetricsServiceRequest AssertAndConvertExportedBlobTo private class TestTransport : IMetricDataTransport { - public List ExportedItems = new(); + public List ExportedItems = []; public void SendOtlpProtobufEvent(byte[] body, int size) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs index 9421c8de95..c5771b1380 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; [Collection("OtlpProtobufMetricExporterTests")] +#pragma warning disable CA1515 public class OtlpProtobufMetricExporterWithPrefixTests : OtlpProtobufMetricExporterTests +#pragma warning restore CA1515 { protected override bool PrefixBufferWithUInt32LittleEndianLength => true; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs index f21059620f..90a278bc3a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs @@ -6,7 +6,9 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; [Collection("OtlpProtobufMetricExporterTests")] +#pragma warning disable CA1515 public class OtlpProtobufMetricExporterWithoutPrefixTests : OtlpProtobufMetricExporterTests +#pragma warning restore CA1515 { protected override bool PrefixBufferWithUInt32LittleEndianLength => false; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs index 636676c55c..be20571892 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/TableNameSerializerTests.cs @@ -111,12 +111,12 @@ public void TableNameCacheTest() var numberOfCategoryNames = TableNameSerializer.MaxCachedSanitizedTableNames * 2; - for (int i = 0; i < numberOfCategoryNames; i++) + for (var i = 0; i < numberOfCategoryNames; i++) { var categoryName = $"category.{i}-test"; var sanitizedCategoryName = $"Category{i}test"; - for (int c = 0; c < 10; c++) + for (var c = 0; c < 10; c++) { var bytesWritten = tableNameSerializer.ResolveAndSerializeTableNameForCategoryName(buffer, 0, categoryName, out var tableName); diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs index 0fb9e2302c..9808f11384 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketDataTransportTests.cs @@ -16,7 +16,7 @@ public class UnixDomainSocketDataTransportTests [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void UnixDomainSocketDataTransport_Success_Linux() { - string path = GetRandomFilePath(); + var path = GetRandomFilePath(); var endpoint = new UnixDomainSocketEndPoint(path); try { @@ -26,7 +26,7 @@ public void UnixDomainSocketDataTransport_Success_Linux() // Client using var dataTransport = new UnixDomainSocketDataTransport(path); - using Socket serverSocket = server.Accept(); + using var serverSocket = server.Accept(); var data = new byte[] { 12, 34, 56 }; dataTransport.Send(data, data.Length); var receivedData = new byte[5]; @@ -54,7 +54,7 @@ public void UnixDomainSocketDataTransport_Success_Linux() [SkipUnlessPlatformMatchesFact(TestPlatform.Linux)] public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() { - string path = GetRandomFilePath(); + var path = GetRandomFilePath(); var endpoint = new UnixDomainSocketEndPoint(path); using var server = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); server.Bind(endpoint); @@ -66,7 +66,7 @@ public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() try { // Client - using Socket serverSocket = server.Accept(); + using var serverSocket = server.Accept(); while (true) { Console.WriteLine($"Sending request #{i++}."); @@ -102,7 +102,7 @@ public void UnixDomainSocketDataTransport_SendTimesOutIfSocketBufferFull_Linux() public void UnixDomainSocketDataTransport_ServerRestart_Linux() { Console.WriteLine("Test starts."); - string path = GetRandomFilePath(); + var path = GetRandomFilePath(); var endpoint = new UnixDomainSocketEndPoint(path); try { @@ -115,7 +115,7 @@ public void UnixDomainSocketDataTransport_ServerRestart_Linux() // Client using var dataTransport = new UnixDomainSocketDataTransport(path); - Socket serverSocket = server.Accept(); + var serverSocket = server.Accept(); var data = new byte[] { 12, 34, 56 }; dataTransport.Send(data, data.Length); var receivedData = new byte[5]; @@ -160,11 +160,13 @@ public void UnixDomainSocketDataTransport_ServerRestart_Linux() server2.Listen(1); Console.WriteLine("Started a new server and listening."); +#pragma warning disable IDE0230 // Use UTF-8 string literal var data2 = new byte[] { 34, 56, 78 }; +#pragma warning restore IDE0230 // Use UTF-8 string literal dataTransport.Send(data2, data2.Length); Console.WriteLine("The same client sent a new message. Internally it should reconnect if server ever stopped and the socket is not connected anymore."); - using Socket serverSocket2 = server2.Accept(); + using var serverSocket2 = server2.Accept(); Console.WriteLine("The new server is ready and accepting connections."); var receivedData2 = new byte[5]; serverSocket2.Receive(receivedData2); @@ -193,7 +195,7 @@ private static string GetRandomFilePath() { while (true) { - string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); if (!File.Exists(path)) { return path; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs index 85351d141c..27cf917b61 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixDomainSocketEndPointTests.cs @@ -3,8 +3,6 @@ #if !NET -#nullable disable - using System.Net; using System.Net.Sockets; using System.Text; @@ -15,9 +13,9 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; public class UnixDomainSocketEndPointTests { [Fact] - public void UnixDomainSocketEndPoint_constructor_InvalidArgument() + public void UnixDomainSocketEndPoint_Constructor_InvalidArgument() { - Assert.Throws(() => _ = new UnixDomainSocketEndPoint(null)); + Assert.Throws(() => _ = new UnixDomainSocketEndPoint(null!)); Assert.Throws(() => _ = new UnixDomainSocketEndPoint(string.Empty)); Assert.Throws(() => _ = new UnixDomainSocketEndPoint(new string('a', 100))); } @@ -33,7 +31,7 @@ public void UnixDomainSocketEndPoint_constructor_Success() public void UnixDomainSocketEndPoint_Create_InvalidArgument() { var endpoint = new UnixDomainSocketEndPoint("abc"); - Assert.Throws(() => _ = endpoint.Create(null)); + Assert.Throws(() => _ = endpoint.Create(null!)); Assert.Throws(() => _ = endpoint.Create(this.CreateSocketAddress(new string('a', 100)))); } @@ -59,15 +57,15 @@ public void UnixDomainSocketEndPoint_Serialize() private SocketAddress CreateSocketAddress(string path) { - int NativePathOffset = 2; + const int nativePathOffset = 2; var nativePath = Encoding.UTF8.GetBytes(path); - var sa = new SocketAddress(AddressFamily.Unix, NativePathOffset + nativePath.Length + 1); - for (int i = 0; i < nativePath.Length; ++i) + var sa = new SocketAddress(AddressFamily.Unix, nativePathOffset + nativePath.Length + 1); + for (var i = 0; i < nativePath.Length; ++i) { - sa[NativePathOffset + i] = nativePath[i]; + sa[nativePathOffset + i] = nativePath[i]; } - sa[NativePathOffset + nativePath.Length] = 0; + sa[nativePathOffset + nativePath.Length] = 0; return sa; } } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs index b1b8ea9601..c2b3eb1c80 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/UnixUserEventsDataTransportTests.cs @@ -87,7 +87,7 @@ public void UserEvents_Enabled_Success_Linux() var eventBufferStringData = @event["buffer"].AsSpan(); - byte[] eventBuffer = new byte[(eventBufferStringData.Length + 1) / 3]; + var eventBuffer = new byte[(eventBufferStringData.Length + 1) / 3]; var index = 0; var position = 0; @@ -156,8 +156,8 @@ private static void EnsureUserEventsEnabled() private sealed class ConsoleCommand : IDisposable { private readonly Process process; - private readonly List output = new(); - private readonly List errors = new(); + private readonly List output = []; + private readonly List errors = []; private ConsoleCommand( string command, @@ -287,7 +287,7 @@ public PerfTracepointListener(string name, string nameArgs) } } - public List> Events { get; } = new(); + public List> Events { get; } = []; public bool IsEnabled() { @@ -347,7 +347,7 @@ private void OnCatOutputReceived(string output) { var name = $": {this.name}:"; - int startingPosition = output.IndexOf(name, StringComparison.Ordinal); + var startingPosition = output.IndexOf(name, StringComparison.Ordinal); if (startingPosition < 0) { return; diff --git a/test/Shared/PlatformHelpers.cs b/test/Shared/PlatformHelpers.cs index 22b9c3a570..3f111cf822 100644 --- a/test/Shared/PlatformHelpers.cs +++ b/test/Shared/PlatformHelpers.cs @@ -27,7 +27,7 @@ public static bool IsProcessElevated(TestPlatform platform) throw new NotImplementedException(); } - uint userId = SystemNativeUnix.GetEUid(); + var userId = SystemNativeUnix.GetEUid(); return userId == 0; } @@ -50,6 +50,7 @@ public SkipUnlessPlatformMatchesFactAttribute(TestPlatform platform, bool requir TestPlatform.Windows => OSPlatform.Windows, TestPlatform.Linux => OSPlatform.Linux, TestPlatform.OSX => OSPlatform.OSX, + TestPlatform.Unknown => throw new NotSupportedException("TestPlatform 'Unknown' is not supported"), _ => throw new NotSupportedException($"TestPlatform '{platform}' is not supported"), }; @@ -77,6 +78,7 @@ public SkipUnlessPlatformMatchesTheoryAttribute(TestPlatform platform, bool requ TestPlatform.Windows => OSPlatform.Windows, TestPlatform.Linux => OSPlatform.Linux, TestPlatform.OSX => OSPlatform.OSX, + TestPlatform.Unknown => throw new NotSupportedException("TestPlatform 'Unknown' is not supported"), _ => throw new NotSupportedException($"TestPlatform '{platform}' is not supported"), }; From 953706ffdf06d487a2085a9c7a78f128284967a9 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Sat, 23 Nov 2024 01:07:05 -0600 Subject: [PATCH 1435/1499] [release] Prepare release Instrumentation.AWS-1.10.0-beta.1 (#2344) --- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 472b28d538..b46f03eb53 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Nov-23 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2125](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2125)) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index fa00815171..ff3c2ba693 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Nov-23 + * Move adding request and response info to AWSTracingPipelineHandler ([#2137](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2137)) * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 6b5b3987c5..0e1193c2d2 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Nov-23 + * Add detection of Lambda cold start and set `faas.coldstart` Activity tag. ([#2037](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2037)) * Add HTTP server span attributes for Application Loadbalancer triggers From 65629b0fbe0321a5ef7ee8092539c25894658e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 25 Nov 2024 22:06:08 +0100 Subject: [PATCH 1436/1499] [repo/examples] Prepare to .NET9 (#2251) --- .../AspNet/Controllers/WeatherForecastController.cs | 10 +++++----- .../enrichment/Examples.Enrichment/IMyService.cs | 2 +- examples/enrichment/Examples.Enrichment/MyService.cs | 8 ++++---- examples/enrichment/Examples.Enrichment/Program.cs | 2 +- .../Controllers/WeatherForecastController.cs | 10 ++++++---- .../Examples.GrpcCore.AspNetCore/Program.cs | 2 +- .../Examples.GrpcCore.AspNetCore/Startup.cs | 2 +- .../Examples.GrpcCore.AspNetCore/WeatherForecast.cs | 2 ++ examples/kafka/Constants.cs | 2 +- examples/kafka/ProduceConsumeHostedService.cs | 12 ++++++------ examples/owin/Controllers/TestController.cs | 2 ++ examples/process-instrumentation/Program.cs | 2 +- examples/runtime-instrumentation/Program.cs | 2 +- examples/wcf/client-core/StatusServiceClient.cs | 2 ++ .../wcf/client-netframework/StatusServiceClient.cs | 2 +- examples/wcf/server-netframework/StatusService.cs | 2 +- 16 files changed, 36 insertions(+), 28 deletions(-) diff --git a/examples/AspNet/Controllers/WeatherForecastController.cs b/examples/AspNet/Controllers/WeatherForecastController.cs index c51fe1a49a..984f41a783 100644 --- a/examples/AspNet/Controllers/WeatherForecastController.cs +++ b/examples/AspNet/Controllers/WeatherForecastController.cs @@ -13,10 +13,10 @@ namespace Examples.AspNet.Controllers; public class WeatherForecastController : ApiController { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", - }; + private static readonly string[] Summaries = + [ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + ]; [HttpGet] // For testing traditional routing. Ex: https://localhost:XXXX/api/weatherforecast public async Task> Get() @@ -89,7 +89,7 @@ public async Task GetData() [HttpPost] public async Task PostData() { - string? value1 = Baggage.GetBaggage("key1"); + var value1 = Baggage.GetBaggage("key1"); if (string.IsNullOrEmpty(value1)) { throw new InvalidOperationException("Key1 was not found on Baggage."); diff --git a/examples/enrichment/Examples.Enrichment/IMyService.cs b/examples/enrichment/Examples.Enrichment/IMyService.cs index 977ecb8bd0..46f83d9270 100644 --- a/examples/enrichment/Examples.Enrichment/IMyService.cs +++ b/examples/enrichment/Examples.Enrichment/IMyService.cs @@ -3,7 +3,7 @@ namespace Examples.Enrichment; -public interface IMyService +internal interface IMyService { public (string Service, string Status) MyDailyStatus(); } diff --git a/examples/enrichment/Examples.Enrichment/MyService.cs b/examples/enrichment/Examples.Enrichment/MyService.cs index bcab816f1d..2707454ee8 100644 --- a/examples/enrichment/Examples.Enrichment/MyService.cs +++ b/examples/enrichment/Examples.Enrichment/MyService.cs @@ -5,12 +5,12 @@ namespace Examples.Enrichment; internal sealed class MyService : IMyService { - private readonly List statuses = new() - { + private readonly List statuses = + [ "Blocked", "No blockers", - "Out of office", - }; + "Out of office" + ]; /// /// Returns daily status. diff --git a/examples/enrichment/Examples.Enrichment/Program.cs b/examples/enrichment/Examples.Enrichment/Program.cs index c1f3c81a79..7d1cca1801 100644 --- a/examples/enrichment/Examples.Enrichment/Program.cs +++ b/examples/enrichment/Examples.Enrichment/Program.cs @@ -9,7 +9,7 @@ namespace Examples.Enrichment; -public static class Program +internal static class Program { public static void Main() { diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index 3dfccedde9..65126feec3 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -7,12 +7,14 @@ namespace Examples.GrpcCore.AspNetCore.Controllers; [ApiController] [Route("[controller]")] +#pragma warning disable CA1515 public class WeatherForecastController : ControllerBase +#pragma warning restore CA1515 { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching", - }; + private static readonly string[] Summaries = + [ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + ]; private readonly Echo.EchoClient echoClient; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs index c0a8cf0f46..132cd7cde2 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Program.cs @@ -3,7 +3,7 @@ namespace Examples.GrpcCore.AspNetCore; -public class Program +internal class Program { internal const int Port = 5000; internal const int GrpcServicePort = 5001; diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs index 196577a675..ea78a4a6ae 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Startup.cs @@ -8,7 +8,7 @@ namespace Examples.GrpcCore.AspNetCore; -public class Startup +internal class Startup { public Startup(IConfiguration configuration) { diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index cfb073e95c..e8aa41fb67 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -3,7 +3,9 @@ namespace Examples.GrpcCore.AspNetCore; +#pragma warning disable CA1515 public class WeatherForecast +#pragma warning restore CA1515 { public WeatherForecast(DateTime date, int temperatureC, string summary) { diff --git a/examples/kafka/Constants.cs b/examples/kafka/Constants.cs index af3cf026c4..0e9950fc68 100644 --- a/examples/kafka/Constants.cs +++ b/examples/kafka/Constants.cs @@ -3,7 +3,7 @@ namespace Examples.ConfluentKafka; -public static class Constants +internal static class Constants { public static readonly string Topic = $"test-topic-{Guid.NewGuid()}"; } diff --git a/examples/kafka/ProduceConsumeHostedService.cs b/examples/kafka/ProduceConsumeHostedService.cs index ae8754c23a..b61a39aebd 100644 --- a/examples/kafka/ProduceConsumeHostedService.cs +++ b/examples/kafka/ProduceConsumeHostedService.cs @@ -5,17 +5,17 @@ namespace Examples.ConfluentKafka; -public class ProduceConsumeHostedService( +internal class ProduceConsumeHostedService( InstrumentedProducerBuilder instrumentedProducerBuilder, InstrumentedConsumerBuilder instrumentedConsumerBuilder) : BackgroundService { protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - IProducer producer = instrumentedProducerBuilder.Build(); - IConsumer consumer = instrumentedConsumerBuilder.Build(); + var producer = instrumentedProducerBuilder.Build(); + var consumer = instrumentedConsumerBuilder.Build(); - for (int j = 0; j < 100; j++) + for (var j = 0; j < 100; j++) { await producer.ProduceAsync( Constants.Topic, @@ -23,7 +23,7 @@ await producer.ProduceAsync( stoppingToken); } - for (int j = 0; j < 100; j++) + for (var j = 0; j < 100; j++) { producer.Produce( Constants.Topic, @@ -35,7 +35,7 @@ await producer.ProduceAsync( consumer.Subscribe(Constants.Topic); while (!stoppingToken.IsCancellationRequested) { - ConsumeResult consumeResult = consumer.Consume(stoppingToken); + var consumeResult = consumer.Consume(stoppingToken); if (consumeResult == null) { continue; diff --git a/examples/owin/Controllers/TestController.cs b/examples/owin/Controllers/TestController.cs index 6c18aa8309..80a6051efb 100644 --- a/examples/owin/Controllers/TestController.cs +++ b/examples/owin/Controllers/TestController.cs @@ -5,7 +5,9 @@ namespace Examples.Owin.Controllers; +#pragma warning disable CA1515 public class TestController : ApiController +#pragma warning restore CA1515 { // GET api/test/{id} public string Get(string? id = null) diff --git a/examples/process-instrumentation/Program.cs b/examples/process-instrumentation/Program.cs index e1d9b832eb..f0d02dcbfd 100644 --- a/examples/process-instrumentation/Program.cs +++ b/examples/process-instrumentation/Program.cs @@ -4,7 +4,7 @@ using OpenTelemetry; using OpenTelemetry.Metrics; -public class Program +internal class Program { public static void Main() { diff --git a/examples/runtime-instrumentation/Program.cs b/examples/runtime-instrumentation/Program.cs index 8c8612d0fc..e5d8b0c526 100644 --- a/examples/runtime-instrumentation/Program.cs +++ b/examples/runtime-instrumentation/Program.cs @@ -4,7 +4,7 @@ using OpenTelemetry; using OpenTelemetry.Metrics; -public class Program +internal class Program { public static void Main() { diff --git a/examples/wcf/client-core/StatusServiceClient.cs b/examples/wcf/client-core/StatusServiceClient.cs index 527c292916..4c844c8cf1 100644 --- a/examples/wcf/client-core/StatusServiceClient.cs +++ b/examples/wcf/client-core/StatusServiceClient.cs @@ -6,7 +6,9 @@ namespace Examples.Wcf.Client; +#pragma warning disable CA1515 public class StatusServiceClient : ClientBase, IStatusServiceContract +#pragma warning restore CA1515 { public StatusServiceClient(string name) : base(name) diff --git a/examples/wcf/client-netframework/StatusServiceClient.cs b/examples/wcf/client-netframework/StatusServiceClient.cs index 47b6302d62..8b84dd1848 100644 --- a/examples/wcf/client-netframework/StatusServiceClient.cs +++ b/examples/wcf/client-netframework/StatusServiceClient.cs @@ -5,7 +5,7 @@ namespace Examples.Wcf.Client; -public class StatusServiceClient : ClientBase, IStatusServiceContract +internal class StatusServiceClient : ClientBase, IStatusServiceContract { public StatusServiceClient(string name) : base(name) diff --git a/examples/wcf/server-netframework/StatusService.cs b/examples/wcf/server-netframework/StatusService.cs index 41d979c15c..44b46dd196 100644 --- a/examples/wcf/server-netframework/StatusService.cs +++ b/examples/wcf/server-netframework/StatusService.cs @@ -11,7 +11,7 @@ namespace Examples.Wcf.Server; InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false, Name = "StatusService")] -public class StatusService : IStatusServiceContract +internal class StatusService : IStatusServiceContract { public Task PingAsync(StatusRequest request) { From f6c4195057fddbf0f475c8db263ea3485ccf9894 Mon Sep 17 00:00:00 2001 From: Timothy Mothra Date: Wed, 27 Nov 2024 12:25:53 -0800 Subject: [PATCH 1437/1499] [Instrumentation.Http] Skip tagging traces when running on .NET 9+ (#2314) Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- .../CHANGELOG.md | 5 ++ .../HttpHandlerDiagnosticListener.cs | 51 +++++++++---------- .../README.md | 8 +++ .../HttpClientTests.Basic.cs | 20 ++++++++ .../HttpClientTests.cs | 18 +++++++ .../HttpWebRequestTests.cs | 10 ++++ 6 files changed, 84 insertions(+), 28 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index beb4f6db93..4dfe8ff572 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -8,6 +8,11 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Trace instrumentation no longer sets attributes when running on .NET 9 and + greater because `HttpClient` now includes native instrumentation which adds + attributes directly. + ([#2314](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2314)) + ## 1.9.0 Released 2024-Jun-17 diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index f7b98fac07..ff2e971456 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -20,7 +20,8 @@ internal sealed class HttpHandlerDiagnosticListener : ListenerHandler #endif internal static readonly AssemblyName AssemblyName = typeof(HttpHandlerDiagnosticListener).Assembly.GetName(); - internal static readonly bool IsNet7OrGreater = InitializeIsNet7OrGreater(); + internal static readonly bool IsNet7OrGreater = Environment.Version.Major >= 7; + internal static readonly bool IsNet9OrGreater = Environment.Version.Major >= 9; // https://github.com/dotnet/runtime/blob/7d034ddbbbe1f2f40c264b323b3ed3d6b3d45e9a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs#L19 internal static readonly string ActivitySourceName = AssemblyName.Name + ".HttpClient"; @@ -35,6 +36,7 @@ internal sealed class HttpHandlerDiagnosticListener : ListenerHandler private static readonly PropertyFetcher StopResponseFetcher = new("Response"); private static readonly PropertyFetcher StopExceptionFetcher = new("Exception"); private static readonly PropertyFetcher StopRequestStatusFetcher = new("RequestTaskStatus"); + private readonly HttpClientTraceInstrumentationOptions options; public HttpHandlerDiagnosticListener(HttpClientTraceInstrumentationOptions options) @@ -135,15 +137,17 @@ public void OnStartActivity(Activity activity, object? payload) ActivityInstrumentationHelper.SetKindProperty(activity, ActivityKind.Client); } - // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md - HttpTagHelper.RequestDataHelper.SetHttpMethodTag(activity, request.Method.Method); - - if (request.RequestUri != null) + if (!IsNet9OrGreater) { - activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); - activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.23.0/docs/http/http-spans.md + HttpTagHelper.RequestDataHelper.SetHttpMethodTag(activity, request.Method.Method); - activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri, this.options.DisableUrlQueryRedaction)); + if (request.RequestUri != null) + { + activity.SetTag(SemanticConventions.AttributeServerAddress, request.RequestUri.Host); + activity.SetTag(SemanticConventions.AttributeServerPort, request.RequestUri.Port); + activity.SetTag(SemanticConventions.AttributeUrlFull, HttpTagHelper.GetUriTagValueFromRequestUri(request.RequestUri, this.options.DisableUrlQueryRedaction)); + } } try @@ -199,16 +203,19 @@ public void OnStopActivity(Activity activity, object? payload) if (TryFetchResponse(payload, out var response)) { - if (currentStatusCode == ActivityStatusCode.Unset) + if (!IsNet9OrGreater) { - activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, (int)response.StatusCode)); - } + if (currentStatusCode == ActivityStatusCode.Unset) + { + activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, (int)response.StatusCode)); + } - activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(response.Version)); - activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode)); - if (activity.Status == ActivityStatusCode.Error) - { - activity.SetTag(SemanticConventions.AttributeErrorType, TelemetryHelper.GetStatusCodeString(response.StatusCode)); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(response.Version)); + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(response.StatusCode)); + if (activity.Status == ActivityStatusCode.Error) + { + activity.SetTag(SemanticConventions.AttributeErrorType, TelemetryHelper.GetStatusCodeString(response.StatusCode)); + } } try @@ -323,16 +330,4 @@ static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception #endif return exc.GetType().FullName; } - - private static bool InitializeIsNet7OrGreater() - { - try - { - return typeof(HttpClient).Assembly.GetName().Version!.Major >= 7; - } - catch (Exception) - { - return false; - } - } } diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index cf729c8252..df39d39614 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -40,6 +40,14 @@ HTTP instrumentation must be enabled at application startup. #### Traces +Starting with .NET 9, trace instrumentation is natively implemented, and the +HttpClient library emits attributes defined in the +[OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/http/http-spans.md). +When running on .NET 9+ this instrumentation library will not add/change/override +any attributes set by the native instrumentation but it is still required for +performing context propagation using the OpenTelemetry SDK and supports additional +features not available in runtime (enrichment, filtering, etc.). + The following example demonstrates adding `HttpClient` instrumentation with the extension method `.AddHttpClientInstrumentation()` on `TracerProviderBuilder` to a console application. This example also sets up the OpenTelemetry Console diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index 0ee5a4b4c7..af7413b149 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -425,6 +425,18 @@ public async Task HttpRequestMethodIsSetOnActivityAsPerSpec(string originalMetho } Assert.Equal(expectedMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethod)); + +#if NET9_0_OR_GREATER + if (expectedOriginalMethod is not null and not "CUSTOM") + { + // HACK: THIS IS A HACK TO MAKE THE TEST PASS. + // TODO: THIS CAN BE REMOVED AFTER RUNTIME PATCHES NET9. + // Currently Runtime is not following the OTel Spec for Http Spans: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-client + // Currently "http.request.method_original" is not being set as expected. + // Tracking issue: https://github.com/dotnet/runtime/issues/109847 + expectedOriginalMethod = null; + } +#endif Assert.Equal(expectedOriginalMethod, activity.GetTagValue(SemanticConventions.AttributeHttpRequestMethodOriginal)); } @@ -727,6 +739,14 @@ public async Task ValidateUrlQueryRedaction(string urlQuery, string expectedUrlQ var activity = exportedItems[0]; var expectedUrl = $"{this.url}path{expectedUrlQuery}"; + +#if NET9_0_OR_GREATER + // HACK: THIS IS A HACK TO MAKE THE TEST PASS. + // TODO: NEED TO UPDATE THIS TEST TO USE .NET'S SETTING TO DISABLE REDACTION. + // Currently this doesn't work with our tests which run in parallel. + // For more information see: https://github.com/dotnet/docs/issues/42792 + expectedUrl = $"{this.url}path?*"; +#endif Assert.Equal(expectedUrl, activity.GetTagValue(SemanticConventions.AttributeUrlFull)); } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index fd01551bf3..1ccf563a51 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -340,7 +340,25 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeHttpRequestMethod && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeHttpRequestMethod]); Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerAddress && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerAddress]); Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeServerPort && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeServerPort]); + +#if NET9_0_OR_GREATER + // HACK: THIS IS A HACK TO MAKE THE TEST PASS. + // TODO: THIS CAN BE REMOVED AFTER RUNTIME PATCHES NET9. + // Currently Runtime is not following the OTel Spec for Http Spans: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-client + // Currently the URL Fragment Identifier (#fragment) isn't being recorded. + // Tracking issue: https://github.com/dotnet/runtime/issues/109847 + var expected = normalizedAttributesTestCase[SemanticConventions.AttributeUrlFull]; + if (expected.EndsWith("#fragment", StringComparison.Ordinal)) + { + // remove fragment from expected value + expected = expected.Substring(0, expected.Length - "#fragment".Length); + } + + Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeUrlFull && kvp.Value?.ToString() == expected); +#else Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeUrlFull && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeUrlFull]); +#endif + if (tc.ResponseExpected) { Assert.Contains(normalizedAttributes, kvp => kvp.Key == SemanticConventions.AttributeNetworkProtocolVersion && kvp.Value?.ToString() == normalizedAttributesTestCase[SemanticConventions.AttributeNetworkProtocolVersion]); diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs index 9e01f266c4..2445a6baf6 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs @@ -122,6 +122,16 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) Assert.Fail($"Tag {tag.Key} was not found in test data."); } +#if NET9_0_OR_GREATER + // TODO: NEED TO REVIEW THE SPEC + // NET9 does not record the URL Fragment Identifier. + if (value.EndsWith("#fragment", StringComparison.Ordinal)) + { + // remove fragment from expected value + value = value.Substring(0, value.Length - "#fragment".Length); + } +#endif + Assert.Equal(value, tagValue); } From fad377b2ad63c1dd0e517a4a89e1a7d0fe06bc75 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 27 Nov 2024 14:41:33 -0600 Subject: [PATCH 1438/1499] [release] Prepare release Instrumentation.Http-1.10.0 (#2348) --- src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 4dfe8ff572..3e90df8b9b 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0 + +Released 2024-Nov-27 + * Drop support for .NET 6 as this target is no longer supported. ([#2152](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2152)) From 1f2799f904f50918acede4e1a561cd6bc9d7f3e3 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:46:51 -0600 Subject: [PATCH 1439/1499] [release] Instrumentation.Http- stable release 1.10.0 updates (#2349) --- .../OpenTelemetry.Instrumentation.Http.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj index 9970dc7fcc..7390c19a6e 100644 --- a/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj +++ b/src/OpenTelemetry.Instrumentation.Http/OpenTelemetry.Instrumentation.Http.csproj @@ -6,7 +6,7 @@ Http instrumentation for OpenTelemetry .NET. $(PackageTags);distributed-tracing Instrumentation.Http- - 1.9.0 + 1.10.0 From 687bc557163869fc06f9f9ba5cc68b4f030a1039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 3 Dec 2024 06:13:25 +0100 Subject: [PATCH 1440/1499] [repo] Prepare to .NET9 - reenable analysis level (#2350) Co-authored-by: Timothy Mothra --- build/Common.nonprod.props | 2 +- build/Common.props | 2 +- .../Controllers/WeatherForecastController.cs | 2 -- .../WeatherForecast.cs | 2 -- examples/owin/Controllers/TestController.cs | 2 -- examples/owin/Program.cs | 2 +- examples/wcf/client-core/Program.cs | 4 ++-- .../wcf/client-core/StatusServiceClient.cs | 2 -- examples/wcf/client-netframework/Program.cs | 2 +- examples/wcf/server-netframework/Program.cs | 2 +- .../Metrics/GenevaMetricExporterOptions.cs | 10 ++------- .../ActivityEventAttachingLogProcessor.cs | 2 +- .../Internal/DefaultLogStateConverter.cs | 12 +++++----- .../Internal/RateLimiter.cs | 4 ++-- .../Trace/RateLimitingSampler.cs | 4 ++-- .../AWSTracingPipelineCustomizer.cs | 8 +------ .../Implementation/HttpRequestRouteHelper.cs | 2 +- .../DriverGauge.cs | 2 ++ .../EntityFrameworkDiagnosticListener.cs | 6 ++++- .../HttpHandlerDiagnosticListener.cs | 2 +- .../HttpWebRequestActivitySource.netfx.cs | 2 ++ .../MeterProviderBuilderExtensions.cs | 3 +-- .../ProcessInstrumentationOptions.cs | 11 ---------- .../ProcessMetrics.cs | 4 ---- .../Implementation/SqlActivitySourceHelper.cs | 2 +- .../SqlClientDiagnosticListener.cs | 2 +- .../AspNetParentSpanCorrector.cs | 6 ++--- .../HttpRequestMessagePropertyWrapper.cs | 6 ++--- .../InstrumentedCommunicationObject.cs | 5 +---- .../Implementation/TelemetryMessageHeader.cs | 9 ++++---- .../AWSXRayRemoteSamplerBuilder.cs | 4 +++- src/Shared/DiagnosticSourceSubscriber.cs | 13 ++++++++--- .../ServerCertificateValidationHandler.cs | 2 +- src/Shared/SqlProcessor.cs | 4 ++-- .../GrpcTagHelperTests.cs | 4 ++-- .../PropertyFetcherTest.cs | 16 +++++++------- .../SqlProcessorTestCases.cs | 2 ++ .../Exporter/LogExporterBenchmarks.cs | 2 -- .../Exporter/MetricExporterBenchmarks.cs | 2 -- .../Exporter/SerializationBenchmarks.cs | 2 -- .../Exporter/TLDLogExporterBenchmarks.cs | 2 -- .../Exporter/TLDTraceExporterBenchmarks.cs | 2 -- .../Exporter/TraceExporterBenchmarks.cs | 2 -- .../DummyServer.cs | 12 +++++----- .../OtlpProtobufMetricExporterTests.cs | 6 ++--- ...lpProtobufMetricExporterWithPrefixTests.cs | 2 -- ...rotobufMetricExporterWithoutPrefixTests.cs | 2 -- .../Processors/ErrorActivityProcessorTests.cs | 6 ++--- .../EventsActivityProcessorTests.cs | 12 +++++----- ...ecordCommonSchemaJsonHttpPostBenchmarks.cs | 2 -- .../ActivityExtensionsTest.cs | 8 +++---- .../AWSXRayIdGeneratorTests.cs | 4 ++-- ...ActivityEventAttachingLogProcessorTests.cs | 22 +++++++++---------- .../Tools/HttpResponseMessageBody.cs | 11 ++++------ .../HttpInListenerTests.cs | 10 ++++----- .../AspNetCoreInstrumentationBenchmarks.cs | 4 ---- .../AspNetCoreInstrumentationNewBenchmarks.cs | 4 ---- .../RouteTests/RoutingTestFixture.cs | 2 +- .../RouteTests/RoutingTestResult.cs | 6 ++--- .../TestApplication/ActionDescriptorInfo.cs | 2 +- .../PageActionDescriptorInfo.cs | 2 +- .../RouteTests/TestApplication/RouteInfo.cs | 2 +- .../RouteInfoDiagnosticObserver.cs | 13 ++++++++--- .../BooksEntity.cs | 2 +- .../CassandraInstrumentationTests.cs | 6 ++--- .../DependencyInjectionConfigTests.cs | 2 +- .../DependencyInjectionConfigTests.cs | 2 +- .../HangfireFixture.cs | 2 -- .../HttpClientInstrumentationBenchmarks.cs | 4 ---- .../HttpOutTestCase.cs | 2 -- .../SqlClientIntegrationTestsFixture.cs | 2 -- .../SqlClientTestCase.cs | 2 -- .../SqlClientTests.cs | 2 +- .../SqlEventSourceTests.netfx.cs | 6 ++--- .../SqlTestData.cs | 2 +- ...isProfilerEntryToActivityConverterTests.cs | 4 ++-- ...kExchangeRedisCallsInstrumentationTests.cs | 22 +++++++++---------- ...DownstreamInstrumentationBindingElement.cs | 2 -- .../Tools/DownstreamInstrumentationChannel.cs | 2 -- ...DownstreamInstrumentationChannelFactory.cs | 2 -- ...wnstreamInstrumentationEndpointBehavior.cs | 2 -- .../WCF/IServiceContract.cs | 2 -- .../WCF/ServiceClient.cs | 2 -- .../WCF/ServiceRequest.cs | 2 -- .../WCF/ServiceResponse.cs | 2 -- .../DirectorySizeTrackerTests.cs | 10 ++++----- .../FileBlobProviderTests.cs | 18 +++++++-------- .../FileBlobTests.cs | 14 ++++++------ .../Http/CertificateUploader.cs | 10 ++++----- ...ServerCertificateValidationHandlerTests.cs | 2 +- ...erverCertificateValidationProviderTests.cs | 4 ++-- .../OperatingSystemDetectorTests.cs | 6 ++--- .../TestAWSXRayRemoteSampler.cs | 4 ++-- .../Controllers/ChildActivityController.cs | 2 -- .../Controllers/ErrorController.cs | 2 -- .../Controllers/ValuesController.cs | 2 -- .../Filters/ExceptionFilter1.cs | 4 +--- .../Filters/ExceptionFilter2.cs | 4 +--- test/TestApp.AspNetCore/Program.cs | 2 -- .../TestActivityMiddleware.cs | 2 -- .../TestCallbackMiddleware.cs | 2 -- test/TestApp.AspNetCore/TestMiddleware.cs | 2 -- 102 files changed, 195 insertions(+), 284 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 54d1acd980..39899ccd69 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -4,7 +4,7 @@ false $(MSBuildThisFileDirectory)/OpenTelemetryContrib.test.ruleset - $(NoWarn),1574,1591 + $(NoWarn),1574,1591;CA1515 diff --git a/build/Common.props b/build/Common.props index 1f610aad30..a33837c548 100644 --- a/build/Common.props +++ b/build/Common.props @@ -10,7 +10,7 @@ net8.0 netstandard2.0 true - 8.0 + latest-all enable enable true diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs index 65126feec3..2e9f5c964e 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Controllers/WeatherForecastController.cs @@ -7,9 +7,7 @@ namespace Examples.GrpcCore.AspNetCore.Controllers; [ApiController] [Route("[controller]")] -#pragma warning disable CA1515 public class WeatherForecastController : ControllerBase -#pragma warning restore CA1515 { private static readonly string[] Summaries = [ diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs index e8aa41fb67..cfb073e95c 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/WeatherForecast.cs @@ -3,9 +3,7 @@ namespace Examples.GrpcCore.AspNetCore; -#pragma warning disable CA1515 public class WeatherForecast -#pragma warning restore CA1515 { public WeatherForecast(DateTime date, int temperatureC, string summary) { diff --git a/examples/owin/Controllers/TestController.cs b/examples/owin/Controllers/TestController.cs index 80a6051efb..6c18aa8309 100644 --- a/examples/owin/Controllers/TestController.cs +++ b/examples/owin/Controllers/TestController.cs @@ -5,9 +5,7 @@ namespace Examples.Owin.Controllers; -#pragma warning disable CA1515 public class TestController : ApiController -#pragma warning restore CA1515 { // GET api/test/{id} public string Get(string? id = null) diff --git a/examples/owin/Program.cs b/examples/owin/Program.cs index baebb2d250..2babca8222 100644 --- a/examples/owin/Program.cs +++ b/examples/owin/Program.cs @@ -24,7 +24,7 @@ public static void Main() // the request as soon as possible. appBuilder.UseOpenTelemetry(); - HttpConfiguration config = new HttpConfiguration(); + var config = new HttpConfiguration(); config.MessageHandlers.Add(new ActivityDisplayNameRouteEnrichingHandler()); diff --git a/examples/wcf/client-core/Program.cs b/examples/wcf/client-core/Program.cs index 9388e2e232..7ce0b7895f 100644 --- a/examples/wcf/client-core/Program.cs +++ b/examples/wcf/client-core/Program.cs @@ -15,7 +15,7 @@ internal static class Program { public static async Task Main() { - IConfigurationRoot config = new ConfigurationBuilder() + var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); @@ -52,7 +52,7 @@ private static async Task CallService(Binding binding, EndpointAddress remoteAdd // Note: Best practice is to re-use your client/channel instances. // This code is not meant to illustrate best practices, only the // instrumentation. - StatusServiceClient client = new StatusServiceClient(binding, remoteAddress); + var client = new StatusServiceClient(binding, remoteAddress); client.Endpoint.EndpointBehaviors.Add(new TelemetryEndpointBehavior()); try { diff --git a/examples/wcf/client-core/StatusServiceClient.cs b/examples/wcf/client-core/StatusServiceClient.cs index 4c844c8cf1..527c292916 100644 --- a/examples/wcf/client-core/StatusServiceClient.cs +++ b/examples/wcf/client-core/StatusServiceClient.cs @@ -6,9 +6,7 @@ namespace Examples.Wcf.Client; -#pragma warning disable CA1515 public class StatusServiceClient : ClientBase, IStatusServiceContract -#pragma warning restore CA1515 { public StatusServiceClient(string name) : base(name) diff --git a/examples/wcf/client-netframework/Program.cs b/examples/wcf/client-netframework/Program.cs index 644a401213..17eb84edc2 100644 --- a/examples/wcf/client-netframework/Program.cs +++ b/examples/wcf/client-netframework/Program.cs @@ -40,7 +40,7 @@ private static async Task CallService(string name) // Note: Best practice is to re-use your client/channel instances. // This code is not meant to illustrate best practices, only the // instrumentation. - StatusServiceClient client = new StatusServiceClient(name); + var client = new StatusServiceClient(name); try { await client.OpenAsync().ConfigureAwait(false); diff --git a/examples/wcf/server-netframework/Program.cs b/examples/wcf/server-netframework/Program.cs index cfff07318d..b495da2c35 100644 --- a/examples/wcf/server-netframework/Program.cs +++ b/examples/wcf/server-netframework/Program.cs @@ -18,7 +18,7 @@ public static void Main() .AddZipkinExporter() .Build(); - ServiceHost serviceHost = new ServiceHost(typeof(StatusService)); + var serviceHost = new ServiceHost(typeof(StatusService)); serviceHost.Open(); Console.WriteLine("Service listening. Press enter to exit."); diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs index f00ab46b77..6b4930cad9 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterOptions.cs @@ -25,10 +25,7 @@ public class GenevaMetricExporterOptions /// public int MetricExportIntervalMilliseconds { - get - { - return this.metricExporterIntervalMilliseconds; - } + get => this.metricExporterIntervalMilliseconds; set { @@ -43,10 +40,7 @@ public int MetricExportIntervalMilliseconds /// public IReadOnlyDictionary? PrepopulatedMetricDimensions { - get - { - return this.prepopulatedMetricDimensions; - } + get => this.prepopulatedMetricDimensions; set { diff --git a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs index 0c2c7dd059..2fae912207 100644 --- a/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs +++ b/src/OpenTelemetry.Extensions/Internal/ActivityEventAttachingLogProcessor.cs @@ -31,7 +31,7 @@ public ActivityEventAttachingLogProcessor(LogToActivityEventConversionOptions op public override void OnEnd(LogRecord data) { - Activity? activity = Activity.Current; + var activity = Activity.Current; if (activity?.IsAllDataRequested == true) { diff --git a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs index c104049f39..6419586b78 100644 --- a/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs +++ b/src/OpenTelemetry.Extensions/Internal/DefaultLogStateConverter.cs @@ -9,11 +9,11 @@ internal static class DefaultLogStateConverter { public static void ConvertState(ActivityTagsCollection tags, IReadOnlyList> state) { - for (int i = 0; i < state.Count; i++) + for (var i = 0; i < state.Count; i++) { - KeyValuePair stateItem = state[i]; + var stateItem = state[i]; - object? value = stateItem.Value; + var value = stateItem.Value; if (value != null) { if (string.IsNullOrEmpty(stateItem.Key)) @@ -30,11 +30,11 @@ public static void ConvertState(ActivityTagsCollection tags, IReadOnlyList scopeItem in scope) + foreach (var scopeItem in scope) { - object? value = scopeItem.Value; + var value = scopeItem.Value; if (value != null) { if (string.IsNullOrEmpty(scopeItem.Key)) diff --git a/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs b/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs index fd1e51f895..1a6d62b10a 100644 --- a/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs +++ b/src/OpenTelemetry.Extensions/Internal/RateLimiter.cs @@ -20,7 +20,7 @@ public RateLimiter(double creditsPerSecond, double maxBalance) public bool TrySpend(double itemCost) { - long cost = (long)(itemCost / this.creditsPerTick); + var cost = (long)(itemCost / this.creditsPerTick); long currentTicks; long currentBalanceTicks; long availableBalanceAfterWithdrawal; @@ -28,7 +28,7 @@ public bool TrySpend(double itemCost) { currentBalanceTicks = Interlocked.Read(ref this.currentBalance); currentTicks = this.stopwatch.ElapsedTicks; - long currentAvailableBalance = currentTicks - currentBalanceTicks; + var currentAvailableBalance = currentTicks - currentBalanceTicks; if (currentAvailableBalance > this.maxBalance) { currentAvailableBalance = this.maxBalance; diff --git a/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs b/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs index ecfe0726ad..341ffcacad 100644 --- a/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs +++ b/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs @@ -28,7 +28,7 @@ public class RateLimitingSampler : Sampler /// The maximum number of traces that will be emitted each second. public RateLimitingSampler(int maxTracesPerSecond) { - double maxBalance = maxTracesPerSecond < 1.0 ? 1.0 : maxTracesPerSecond; + var maxBalance = maxTracesPerSecond < 1.0 ? 1.0 : maxTracesPerSecond; this.rateLimiter = new RateLimiter(maxTracesPerSecond, maxBalance); var attributes = new Dictionary() { @@ -58,7 +58,7 @@ public override SamplingResult ShouldSample(in SamplingParameters samplingParame private static string DecimalFormat(double value) { - NumberFormatInfo numberFormatInfo = new NumberFormatInfo + var numberFormatInfo = new NumberFormatInfo { NumberDecimalSeparator = ".", }; diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index cdb420ad80..d9c1f550a5 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -19,13 +19,7 @@ public AWSTracingPipelineCustomizer(AWSClientInstrumentationOptions options) this.options = options; } - public string UniqueName - { - get - { - return "AWS Tracing Registration Customization"; - } - } + public string UniqueName => "AWS Tracing Registration Customization"; public void Customize(Type serviceClientType, RuntimePipeline pipeline) { diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs index 43b50b7168..80a88c174f 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpRequestRouteHelper.cs @@ -24,7 +24,7 @@ internal sealed class HttpRequestRouteHelper var routeData = request.RequestContext.RouteData; string? template = null; - if (routeData.Values.TryGetValue("MS_SubRoutes", out object msSubRoutes)) + if (routeData.Values.TryGetValue("MS_SubRoutes", out var msSubRoutes)) { // WebAPI attribute routing flows here. Use reflection to not take a dependency on microsoft.aspnet.webapi.core\[version]\lib\[framework]\System.Web.Http. diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs b/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs index 5bc0b1db3c..75bf342c1a 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs +++ b/src/OpenTelemetry.Instrumentation.Cassandra/DriverGauge.cs @@ -8,7 +8,9 @@ namespace OpenTelemetry.Instrumentation.Cassandra; internal sealed class DriverGauge : IDriverGauge { +#pragma warning disable IDE0052 // Remove unread private members private readonly ObservableGauge gauge; +#pragma warning restore IDE0052 // Remove unread private members public DriverGauge(string name, Func value) { diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index ef526d8c74..630a8ebef7 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -54,7 +54,7 @@ public EntityFrameworkDiagnosticListener(string sourceName, EntityFrameworkInstr public override void OnEventWritten(string name, object? payload) { - Activity? activity = Activity.Current; + var activity = Activity.Current; switch (name) { @@ -239,6 +239,8 @@ public override void OnEventWritten(string name, object? payload) case CommandType.TableDirect: break; + default: + break; } } @@ -311,6 +313,8 @@ public override void OnEventWritten(string name, object? payload) } } + break; + default: break; } } diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs index ff2e971456..234cfa10ac 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerDiagnosticListener.cs @@ -324,7 +324,7 @@ static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception HttpRequestError.ConfigurationLimitExceeded => "configuration_limit_exceeded", // Fall back to the exception type name in case of HttpRequestError.Unknown - _ => exc.GetType().FullName, + HttpRequestError.Unknown or _ => exc.GetType().FullName, }; } #endif diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index df48fd4807..c28670cbd7 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -140,6 +140,7 @@ private static string GetErrorType(Exception exception) { // TODO: consider other Status values from // https://learn.microsoft.com/dotnet/api/system.net.webexceptionstatus?view=netframework-4.6.2 +#pragma warning disable IDE0072 // Add missing cases return wexc.Status switch { WebExceptionStatus.NameResolutionFailure => "name_resolution_failure", @@ -161,6 +162,7 @@ private static string GetErrorType(Exception exception) WebExceptionStatus.RequestProhibitedByProxy => "request_prohibited_by_proxy", _ => wexc.GetType().FullName, }; +#pragma warning restore IDE0072 // Add missing cases } return exception.GetType().FullName; diff --git a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs index 7aede241ca..de2f9e97df 100644 --- a/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.Process/MeterProviderBuilderExtensions.cs @@ -21,8 +21,7 @@ public static MeterProviderBuilder AddProcessInstrumentation( { Guard.ThrowIfNull(builder); - var options = new ProcessInstrumentationOptions(); builder.AddMeter(ProcessMetrics.MeterName); - return builder.AddInstrumentation(() => new ProcessMetrics(options)); + return builder.AddInstrumentation(() => new ProcessMetrics()); } } diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs deleted file mode 100644 index 28a54b6d7c..0000000000 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessInstrumentationOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Instrumentation.Process; - -/// -/// Options to define the process metrics. -/// -internal sealed class ProcessInstrumentationOptions -{ -} diff --git a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs index abf8f996bf..de23bd4353 100644 --- a/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Process/ProcessMetrics.cs @@ -71,8 +71,4 @@ static ProcessMetrics() unit: "{thread}", description: "Process threads count."); } - - public ProcessMetrics(ProcessInstrumentationOptions options) - { - } } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index 01cde6bd66..a176f338d7 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -112,7 +112,7 @@ public static TagList GetTagListFromConnectionInfo(string? dataSource, string? d internal static double CalculateDurationFromTimestamp(long begin, long? end = null) { - end = end ?? Stopwatch.GetTimestamp(); + end ??= Stopwatch.GetTimestamp(); var timestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency; var delta = end - begin; var ticks = (long)(timestampToTicks * delta); diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 3695f7424d..00342c6c58 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -241,7 +241,7 @@ private void RecordDuration(Activity? activity, object? payload, bool hasError = return; } - TagList tags = default(TagList); + var tags = default(TagList); if (activity != null && activity.IsAllDataRequested) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs index bdcd994691..5893487d7e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/AspNetParentSpanCorrector.cs @@ -115,9 +115,9 @@ private static Func GenerateSubscribeLambda() private sealed class ReflectedInfo { - public Action SetHeadersReadOnly; - public Func GetTelemetryHttpModulePropagator; - public Func SubscribeToOnRequestStartedCallback; + public readonly Action SetHeadersReadOnly; + public readonly Func GetTelemetryHttpModulePropagator; + public readonly Func SubscribeToOnRequestStartedCallback; public ReflectedInfo( Action setHeadersReadOnly, diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs index c6f4c58685..411949a6c3 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/HttpRequestMessagePropertyWrapper.cs @@ -96,9 +96,9 @@ private static void AssertIsFrameworkMessageProperty(object httpRequestMessagePr private sealed class ReflectedInfo { - public Type Type; - public string Name; - public PropertyFetcher HeadersFetcher; + public readonly Type Type; + public readonly string Name; + public readonly PropertyFetcher HeadersFetcher; public ReflectedInfo(Type type, string name, PropertyFetcher headersFetcher) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs index 555c6334f8..3df1121973 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/InstrumentedCommunicationObject.cs @@ -23,10 +23,7 @@ public InstrumentedCommunicationObject(T inner) event EventHandler ICommunicationObject.Opening { add => this.Inner.Opening += value; remove => this.Inner.Opening -= value; } - CommunicationState ICommunicationObject.State - { - get { return this.Inner.State; } - } + CommunicationState ICommunicationObject.State => this.Inner.State; protected T Inner { get; } diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs index 14b56ca30f..a9cdbf259e 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryMessageHeader.cs @@ -9,18 +9,17 @@ namespace OpenTelemetry.Instrumentation.Wcf.Implementation; internal class TelemetryMessageHeader : MessageHeader { private const string NAMESPACE = "https://www.w3.org/TR/trace-context/"; - private string name; - private string value; + private readonly string name; private TelemetryMessageHeader(string name, string value) { this.name = name; - this.value = value; + this.Value = value; } public override string Name => this.name; - public string Value => this.value; + public string Value { get; } public override string Namespace => NAMESPACE; @@ -51,6 +50,6 @@ public static TelemetryMessageHeader CreateHeader(string name, string value) protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion) { - writer.WriteString(this.value); + writer.WriteString(this.Value); } } diff --git a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs index 7f2ad35bee..24f665c69f 100644 --- a/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs +++ b/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSamplerBuilder.cs @@ -15,7 +15,7 @@ public class AWSXRayRemoteSamplerBuilder private static readonly TimeSpan DefaultPollingInterval = TimeSpan.FromMinutes(5); - private Resource resource; + private readonly Resource resource; private TimeSpan pollingInterval; private string endpoint; private Clock clock; @@ -70,7 +70,9 @@ public AWSXRayRemoteSamplerBuilder SetEndpoint(string endpoint) /// an instance of . public Trace.Sampler Build() { +#pragma warning disable CA2000 // Dispose objects before losing scope var rootSampler = new AWSXRayRemoteSampler(this.resource, this.pollingInterval, this.endpoint, this.clock); +#pragma warning restore CA2000 return new ParentBasedSampler(rootSampler); } diff --git a/src/Shared/DiagnosticSourceSubscriber.cs b/src/Shared/DiagnosticSourceSubscriber.cs index 87863b2193..38898695c8 100644 --- a/src/Shared/DiagnosticSourceSubscriber.cs +++ b/src/Shared/DiagnosticSourceSubscriber.cs @@ -86,15 +86,22 @@ private void Dispose(bool disposing) lock (this.listenerSubscriptions) { - foreach (var listenerSubscription in this.listenerSubscriptions) + if (disposing) { - listenerSubscription?.Dispose(); + foreach (var listenerSubscription in this.listenerSubscriptions) + { + listenerSubscription?.Dispose(); + } } this.listenerSubscriptions.Clear(); } - this.allSourcesSubscription?.Dispose(); + if (disposing) + { + this.allSourcesSubscription?.Dispose(); + } + this.allSourcesSubscription = null; } } diff --git a/src/Shared/ServerCertificateValidationHandler.cs b/src/Shared/ServerCertificateValidationHandler.cs index fd22eb86cc..1fce9c09a5 100644 --- a/src/Shared/ServerCertificateValidationHandler.cs +++ b/src/Shared/ServerCertificateValidationHandler.cs @@ -11,7 +11,7 @@ internal static class ServerCertificateValidationHandler { try { - ServerCertificateValidationProvider? serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile, log); + var serverCertificateValidationProvider = ServerCertificateValidationProvider.FromCertificateFile(certificateFile, log); if (serverCertificateValidationProvider == null) { diff --git a/src/Shared/SqlProcessor.cs b/src/Shared/SqlProcessor.cs index 2625a062b7..c5c5ee9a62 100644 --- a/src/Shared/SqlProcessor.cs +++ b/src/Shared/SqlProcessor.cs @@ -5,7 +5,7 @@ namespace OpenTelemetry.Instrumentation; -public static class SqlProcessor +internal static class SqlProcessor { public static string GetSanitizedSql(string sql) { @@ -65,7 +65,7 @@ private static bool SkipComment(string sql, ref int index) for (i += 2; i < length; ++i) { ch = sql[i]; - if (ch == '\r' || ch == '\n') + if (ch is '\r' or '\n') { i -= 1; break; diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs b/test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs index a2fbb308cf..cdbd0707bb 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/GrpcTagHelperTests.cs @@ -42,7 +42,7 @@ public void GrpcTagHelper_GetGrpcStatusCodeFromActivity() using var activity = new Activity("operationName"); activity.SetTag(GrpcTagHelper.GrpcStatusCodeTagName, "0"); - bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + var validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out var status); Assert.True(validConversion); var statusCode = GrpcTagHelper.ResolveSpanStatusForGrpcStatusCode(status); @@ -57,7 +57,7 @@ public void GrpcTagHelper_GetGrpcStatusCodeFromEmptyActivity() { using var activity = new Activity("operationName"); - bool validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out int status); + var validConversion = GrpcTagHelper.TryGetGrpcStatusCodeFromActivity(activity, out var status); Assert.False(validConversion); Assert.Equal(-1, status); Assert.Null(activity.GetTagValue(SemanticConventions.AttributeRpcGrpcStatusCode)); diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/PropertyFetcherTest.cs b/test/OpenTelemetry.Contrib.Shared.Tests/PropertyFetcherTest.cs index b328f7a9b4..7434e4d967 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/PropertyFetcherTest.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/PropertyFetcherTest.cs @@ -17,7 +17,7 @@ public void FetchValidProperty() Assert.Equal(0, fetch.NumberOfInnerFetchers); - Assert.True(fetch.TryFetch(activity, out string? result)); + Assert.True(fetch.TryFetch(activity, out var result)); Assert.Equal(activity.DisplayName, result); Assert.Equal(1, fetch.NumberOfInnerFetchers); @@ -33,10 +33,10 @@ public void FetchInvalidProperty() { using var activity = new Activity("test"); var fetch = new PropertyFetcher("DisplayName2"); - Assert.False(fetch.TryFetch(activity, out string? result)); + Assert.False(fetch.TryFetch(activity, out var result)); var fetchInt = new PropertyFetcher("DisplayName2"); - Assert.False(fetchInt.TryFetch(activity, out int resultInt)); + Assert.False(fetchInt.TryFetch(activity, out var resultInt)); Assert.Equal(default, result); Assert.Equal(default, resultInt); @@ -56,7 +56,7 @@ public void FetchPropertyMultiplePayloadTypes() Assert.Equal(0, fetch.NumberOfInnerFetchers); - Assert.True(fetch.TryFetch(new PayloadTypeA(), out string? propertyValue)); + Assert.True(fetch.TryFetch(new PayloadTypeA(), out var propertyValue)); Assert.Equal("A", propertyValue); Assert.Equal(1, fetch.NumberOfInnerFetchers); @@ -82,7 +82,7 @@ public void FetchPropertyMultiplePayloadTypes_IgnoreTypesWithoutExpectedProperty Assert.False(fetch.TryFetch(new PayloadTypeC(), out _)); - Assert.True(fetch.TryFetch(new PayloadTypeA(), out string? propertyValue)); + Assert.True(fetch.TryFetch(new PayloadTypeA(), out var propertyValue)); Assert.Equal("A", propertyValue); } @@ -91,7 +91,7 @@ public void FetchPropertyWithDerivedInstanceType() { var fetch = new PropertyFetcher("Property"); - Assert.True(fetch.TryFetch(new PayloadTypeWithBaseType(), out BaseType? value)); + Assert.True(fetch.TryFetch(new PayloadTypeWithBaseType(), out var value)); Assert.IsType(value); } @@ -100,7 +100,7 @@ public void FetchPropertyWithDerivedDeclaredType() { var fetch = new PropertyFetcher("Property"); - Assert.True(fetch.TryFetch(new PayloadTypeWithDerivedType(), out BaseType? value)); + Assert.True(fetch.TryFetch(new PayloadTypeWithDerivedType(), out var value)); Assert.IsType(value); } @@ -108,7 +108,7 @@ public void FetchPropertyWithDerivedDeclaredType() public void FetchPropertyWhenPayloadIsValueType() { var fetch = new PropertyFetcher("Property"); - var ex = Assert.Throws(() => fetch.TryFetch(new PayloadTypeIsValueType(), out BaseType? value)); + var ex = Assert.Throws(() => fetch.TryFetch(new PayloadTypeIsValueType(), out var value)); Assert.Contains("PropertyFetcher can only operate on reference payload types.", ex.Message); } diff --git a/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs index f739683fdc..c0fc6fc50b 100644 --- a/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs +++ b/test/OpenTelemetry.Contrib.Shared.Tests/SqlProcessorTestCases.cs @@ -28,7 +28,9 @@ public static IEnumerable GetTestCases() } } +#pragma warning disable CA1034 // Nested types should not be visible public class TestCase +#pragma warning restore CA1034 { public string Name { get; set; } = string.Empty; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs index 1325447358..1c1bef453d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/LogExporterBenchmarks.cs @@ -31,9 +31,7 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class LogExporterBenchmarks -#pragma warning restore CA1515 { private readonly ILogger logger; private readonly ILoggerFactory loggerFactory; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs index d73c5ca4f2..734b09e516 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/MetricExporterBenchmarks.cs @@ -49,9 +49,7 @@ .NET SDK 8.0.202 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class MetricExporterBenchmarks -#pragma warning restore CA1515 { private readonly Meter meterWithNoListener = new("MeterWithNoListener", "0.0.1"); private readonly Meter meterWithListener = new("MeterWithListener", "0.0.1"); diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs index ecc48f27a8..24272abd96 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/SerializationBenchmarks.cs @@ -32,9 +32,7 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class SerializationBenchmarks -#pragma warning restore CA1515 { private const int StringLengthLimit = (1 << 14) - 1; private const string Key = "ext_dt_traceId"; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs index b97ae7f1fa..4256741e44 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDLogExporterBenchmarks.cs @@ -27,9 +27,7 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class TLDLogExporterBenchmarks -#pragma warning restore CA1515 { private readonly LogRecord logRecord; private readonly Batch batch; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs index 29a670b110..6e91217fd2 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TLDTraceExporterBenchmarks.cs @@ -26,9 +26,7 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class TLDTraceExporterBenchmarks -#pragma warning restore CA1515 { private readonly Activity? activity; private readonly Batch batch; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs index b6b012e222..1e1072cbe3 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmarks/Exporter/TraceExporterBenchmarks.cs @@ -24,9 +24,7 @@ .NET SDK 8.0.100 namespace OpenTelemetry.Exporter.Geneva.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class TraceExporterBenchmarks -#pragma warning restore CA1515 { private readonly Activity activity; private readonly Batch batch; diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs index c6cdb17609..354aa3c9c5 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/DummyServer.cs @@ -8,8 +8,8 @@ namespace OpenTelemetry.Exporter.Geneva.Stress; internal class DummyServer { - private EndPoint endpoint; - private Socket serverSocket; + private readonly EndPoint endpoint; + private readonly Socket serverSocket; public DummyServer(string path) { @@ -41,18 +41,18 @@ public void Start() while (true) { - Socket acceptSocket = this.serverSocket.Accept(); + var acceptSocket = this.serverSocket.Accept(); Task.Run(() => { - int threadId = Environment.CurrentManagedThreadId; + var threadId = Environment.CurrentManagedThreadId; Console.WriteLine($"ThreadID {threadId}: Start reading from socket."); - int totalBytes = 0; + var totalBytes = 0; try { while (acceptSocket.Connected) { var receivedData = new byte[1024]; - int receivedDataSize = acceptSocket.Receive(receivedData); + var receivedDataSize = acceptSocket.Receive(receivedData); totalBytes += receivedDataSize; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs index d1856b528a..792827b18a 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterTests.cs @@ -50,7 +50,7 @@ public abstract class OtlpProtobufMetricExporterTests "ushortKey" ]; - private TagList exemplarTagList; + private readonly TagList exemplarTagList; protected OtlpProtobufMetricExporterTests() { @@ -1535,7 +1535,7 @@ public void ExponentialHistogramSerializationSingleMetricPoint(double? doubleVal Assert.Equal(0, dataPoint.Max); 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); } @@ -1685,7 +1685,7 @@ private OtlpCollector.ExportMetricsServiceRequest AssertAndConvertExportedBlobTo private class TestTransport : IMetricDataTransport { - public List ExportedItems = []; + public readonly List ExportedItems = []; public void SendOtlpProtobufEvent(byte[] body, int size) { diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs index c5771b1380..9421c8de95 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithPrefixTests.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; [Collection("OtlpProtobufMetricExporterTests")] -#pragma warning disable CA1515 public class OtlpProtobufMetricExporterWithPrefixTests : OtlpProtobufMetricExporterTests -#pragma warning restore CA1515 { protected override bool PrefixBufferWithUInt32LittleEndianLength => true; } diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs index 90a278bc3a..f21059620f 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OtlpProtobufMetricExporterWithoutPrefixTests.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Exporter.Geneva.Tests; [Collection("OtlpProtobufMetricExporterTests")] -#pragma warning disable CA1515 public class OtlpProtobufMetricExporterWithoutPrefixTests : OtlpProtobufMetricExporterTests -#pragma warning restore CA1515 { protected override bool PrefixBufferWithUInt32LittleEndianLength => false; } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs index 216eae523c..3d41ecf9bb 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/ErrorActivityProcessorTests.cs @@ -20,7 +20,7 @@ public async Task Process_ErrorStatusCodeIsSet() var instanaSpan = new InstanaSpan(); await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); - Assert.True(instanaSpan.Ec == 1); + Assert.Equal(1, instanaSpan.Ec); Assert.NotNull(instanaSpan.Data); Assert.NotNull(instanaSpan.Data.data); Assert.Equal("Error", instanaSpan.Data.data[InstanaExporterConstants.ERROR_FIELD]); @@ -34,7 +34,7 @@ public async Task Process_ExistsExceptionEvent() var instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() { HasExceptionEvent = true } }; await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); - Assert.True(instanaSpan.Ec == 1); + Assert.Equal(1, instanaSpan.Ec); } [Fact] @@ -44,6 +44,6 @@ public async Task Process_NoError() var instanaSpan = new InstanaSpan() { TransformInfo = new Implementation.InstanaSpanTransformInfo() }; await this.errorActivityProcessor.ProcessAsync(activity, instanaSpan); - Assert.True(instanaSpan.Ec == 0); + Assert.Equal(0, instanaSpan.Ec); } } diff --git a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs index 7b46ec5013..ef2730186d 100644 --- a/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs +++ b/test/OpenTelemetry.Exporter.Instana.Tests/Processors/EventsActivityProcessorTests.cs @@ -37,19 +37,19 @@ public async Task ProcessAsync() } Assert.NotNull(instanaSpan.Data?.Events); - Assert.True(instanaSpan.Ec == 0); - Assert.True(instanaSpan.Data.Events.Count == 2); - Assert.True(instanaSpan.Data.Events[0].Name == "testActivityEvent"); + Assert.Equal(0, instanaSpan.Ec); + Assert.Equal(2, instanaSpan.Data.Events.Count); + Assert.Equal("testActivityEvent", instanaSpan.Data.Events[0].Name); Assert.True(instanaSpan.Data.Events[0].Ts > 0); Assert.NotNull(instanaSpan.Data?.Events[0]?.Tags); var eventTagValue = string.Empty; _ = instanaSpan.Data.Events[0].Tags?.TryGetValue("eventTagKey", out eventTagValue); - Assert.True(eventTagValue == "eventTagValue"); - Assert.True(instanaSpan.Data.Events[1].Name == "testActivityEvent2"); + Assert.Equal("eventTagValue", eventTagValue); + Assert.Equal("testActivityEvent2", instanaSpan.Data.Events[1].Name); Assert.True(instanaSpan.Data.Events[1].Ts > 0); Assert.NotNull(instanaSpan.Data?.Events[1]?.Tags); eventTagValue = string.Empty; _ = instanaSpan.Data.Events[1].Tags?.TryGetValue("eventTagKey2", out eventTagValue); - Assert.True(eventTagValue == "eventTagValue2"); + Assert.Equal("eventTagValue2", eventTagValue); } } diff --git a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs index 8c0fa2529f..2f12b38d69 100644 --- a/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs +++ b/test/OpenTelemetry.Exporter.OneCollector.Benchmarks/LogRecordCommonSchemaJsonHttpPostBenchmarks.cs @@ -14,9 +14,7 @@ namespace OpenTelemetry.Exporter.OneCollector.Benchmarks; [MemoryDiagnoser] -#pragma warning disable CA1515 public class LogRecordCommonSchemaJsonHttpPostBenchmarks -#pragma warning restore CA1515 { private static readonly MethodInfo LogRecordSetScopeProviderMethodInfo = typeof(LogRecord).GetProperty("ScopeProvider", BindingFlags.Instance | BindingFlags.NonPublic)?.SetMethod ?? throw new InvalidOperationException("LogRecord.ScopeProvider.Set could not be found reflectively."); diff --git a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs index 2adf881ce8..eca7421a25 100644 --- a/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs +++ b/test/OpenTelemetry.Exporter.Stackdriver.Tests/ActivityExtensionsTest.cs @@ -34,8 +34,8 @@ public void ActivityExtensions_Export_Duplicate_Activity_Tag_Key() activity.AddTag("key2", "value3"); var span = activity.ToSpan("project1"); - Assert.True(span.Attributes.AttributeMap.Count == 2); - Assert.True(span.Attributes.AttributeMap["key2"].StringValue.Value == "value3"); + Assert.Equal(2, span.Attributes.AttributeMap.Count); + Assert.Equal("value3", span.Attributes.AttributeMap["key2"].StringValue.Value); } [Fact] @@ -63,7 +63,7 @@ public void ActivityExtensions_Export_Duplicate_ActivityLink_Tag_Key() using var activity = source.StartActivity("NewActivityWithLinks", ActivityKind.Internal, parentContext: default, links: links); var span = activity?.ToSpan("project1"); - Assert.True((span?.Links.Link.Count ?? 0) == 2); - Assert.True(span?.Links.Link.First().Attributes.AttributeMap["key1"].StringValue.Value == "value3"); + Assert.Equal(2, span?.Links.Link.Count ?? 0); + Assert.Equal("value3", span?.Links.Link.First().Attributes.AttributeMap["key1"].StringValue.Value); } } diff --git a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs index 810a2d6b77..1f8c66d8cb 100644 --- a/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs +++ b/test/OpenTelemetry.Extensions.AWS.Tests/AWSXRayIdGeneratorTests.cs @@ -79,7 +79,7 @@ public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSam { using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) { - Assert.True(activity?.ActivityTraceFlags == ActivityTraceFlags.Recorded); + Assert.Equal(ActivityTraceFlags.Recorded, activity?.ActivityTraceFlags); } } } @@ -100,7 +100,7 @@ public void TestGenerateTraceIdForRootNodeUsingActivitySourceWithTraceIdBasedSam { using (var activity = activitySource.StartActivity("RootActivity", ActivityKind.Internal)) { - Assert.True(activity?.ActivityTraceFlags == ActivityTraceFlags.None); + Assert.Equal(ActivityTraceFlags.None, activity?.ActivityTraceFlags); } } } diff --git a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs index c2a582701e..14e99325d8 100644 --- a/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/ActivityEventAttachingLogProcessorTests.cs @@ -53,7 +53,7 @@ public void AttachLogsToActivityEventTest( { this.sampled = sampled; - using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => + using var loggerFactory = LoggerFactory.Create(builder => { builder.AddOpenTelemetry(options => { @@ -73,10 +73,10 @@ public void AttachLogsToActivityEventTest( }); ILogger logger = loggerFactory.CreateLogger(); - Activity? activity = this.activitySource.StartActivity("Test"); + var activity = this.activitySource.StartActivity("Test"); Assert.NotNull(activity); - using IDisposable? scope = logger.BeginScope("{NodeId}", 99); + using var scope = logger.BeginScope("{NodeId}", 99); logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); @@ -86,7 +86,7 @@ public void AttachLogsToActivityEventTest( innerActivity = this.activitySource.StartActivity("InnerTest"); Assert.NotNull(innerActivity); - using IDisposable? innerScope = logger.BeginScope("{RequestId}", "1234"); + using var innerScope = logger.BeginScope("{RequestId}", "1234"); logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); @@ -102,7 +102,7 @@ public void AttachLogsToActivityEventTest( Assert.NotNull(logEvent); Assert.Equal("log", logEvent.Value.Name); - Dictionary? tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + var tags = logEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(tags); Assert.Equal("OpenTelemetry.Extensions.Tests.ActivityEventAttachingLogProcessorTests", tags[nameof(LogRecord.CategoryName)]); @@ -145,7 +145,7 @@ public void AttachLogsToActivityEventTest( Assert.NotNull(exLogEvent); Assert.Equal("log", exLogEvent.Value.Name); - Dictionary? exLogTags = exLogEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + var exLogTags = exLogEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(exLogTags); Assert.Equal(99, exLogTags["scope[0].NodeId"]); @@ -156,7 +156,7 @@ public void AttachLogsToActivityEventTest( Assert.NotNull(exEvent); Assert.Equal("exception", exEvent.Value.Name); - Dictionary? exTags = exEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); + var exTags = exEvent.Value.Tags?.ToDictionary(i => i.Key, i => i.Value); Assert.NotNull(exTags); Assert.Equal("System.InvalidOperationException", exTags["exception.type"]); @@ -190,7 +190,7 @@ public void AttachLogsToActivityEventTest_Filter( { this.sampled = sampled; - using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => + using var loggerFactory = LoggerFactory.Create(builder => { builder.AddOpenTelemetry(options => { @@ -205,10 +205,10 @@ public void AttachLogsToActivityEventTest_Filter( }); ILogger logger = loggerFactory.CreateLogger(); - Activity? activity = this.activitySource.StartActivity("Test"); + var activity = this.activitySource.StartActivity("Test"); Assert.NotNull(activity); - using IDisposable? scope = logger.BeginScope("{NodeId}", 99); + using var scope = logger.BeginScope("{NodeId}", 99); logger.LogInformation(eventId, "Hello OpenTelemetry {UserId}!", 8); @@ -217,7 +217,7 @@ public void AttachLogsToActivityEventTest_Filter( var innerActivity = this.activitySource.StartActivity("InnerTest"); Assert.NotNull(innerActivity); - using IDisposable? innerScope = logger.BeginScope("{RequestId}", "1234"); + using var innerScope = logger.BeginScope("{RequestId}", "1234"); logger.LogError(new InvalidOperationException("Goodbye OpenTelemetry."), "Exception event."); diff --git a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs index f1e7d4f3ba..2cebb33632 100644 --- a/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs +++ b/test/OpenTelemetry.Instrumentation.AWS.Tests/Tools/HttpResponseMessageBody.cs @@ -7,9 +7,9 @@ namespace OpenTelemetry.Instrumentation.AWS.Tests.Tools; internal class HttpResponseMessageBody : IHttpResponseBody { - private HttpClient? httpClient; - private HttpResponseMessage response; - private bool disposeClient; + private readonly HttpClient? httpClient; + private readonly HttpResponseMessage response; + private readonly bool disposeClient; private bool disposed; public HttpResponseMessageBody(HttpResponseMessage response, HttpClient? httpClient, bool disposeClient) @@ -70,10 +70,7 @@ protected virtual void Dispose(bool disposing) if (disposing) { - if (this.response != null) - { - this.response.Dispose(); - } + this.response?.Dispose(); if (this.httpClient != null && this.disposeClient) { diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index 973d106599..e119eb5962 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -75,7 +75,7 @@ public void AspNetRequestsAreCollectedSuccessfully( typeof(HttpRequest).GetField("_wr", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(HttpContext.Current.Request, new TestHttpWorkerRequest()); - List exportedItems = new List(16); + var exportedItems = new List(16); Sdk.SetDefaultTextMapPropagator(new TraceContextPropagator()); using (Sdk.CreateTracerProviderBuilder() @@ -177,7 +177,7 @@ public void AspNetRequestsAreCollectedSuccessfully( Assert.Single(exportedItems); - Activity span = exportedItems[0]; + var span = exportedItems[0]; Assert.Equal(TelemetryHttpModule.AspNetActivityName, span.OperationName); Assert.NotEqual(TimeSpan.Zero, span.Duration); @@ -248,7 +248,7 @@ public void ExtractContextIrrespectiveOfSamplingDecision(SamplingDecision sampli }, new HttpResponse(new StringWriter())); - bool isPropagatorCalled = false; + var isPropagatorCalled = false; var propagator = new TestTextMapPropagator { Extracted = () => isPropagatorCalled = true, @@ -281,13 +281,13 @@ public void ExtractContextIrrespectiveOfTheFilterApplied() }, new HttpResponse(new StringWriter())); - bool isPropagatorCalled = false; + var isPropagatorCalled = false; var propagator = new TestTextMapPropagator { Extracted = () => isPropagatorCalled = true, }; - bool isFilterCalled = false; + var isFilterCalled = false; var activityProcessor = new TestActivityProcessor(); Sdk.SetDefaultTextMapPropagator(propagator); using (var tracerProvider = Sdk.CreateTracerProviderBuilder() diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs index 3981971027..f0caa4f9ec 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationBenchmarks.cs @@ -65,9 +65,7 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmark.Instrumentation; -#pragma warning disable CA1515 public class AspNetCoreInstrumentationBenchmarks -#pragma warning restore CA1515 { private HttpClient? httpClient; private WebApplication? app; @@ -75,9 +73,7 @@ public class AspNetCoreInstrumentationBenchmarks private MeterProvider? meterProvider; [Flags] -#pragma warning disable CA1515 public enum EnableInstrumentationOption -#pragma warning restore CA1515 { /// /// Instrumentation is not enabled for any signal. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs index 3a13e17507..e08872d0ca 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Benchmarks/Instrumentation/AspNetCoreInstrumentationNewBenchmarks.cs @@ -67,9 +67,7 @@ */ namespace OpenTelemetry.Instrumentation.AspNetCore.Benchmarks.Instrumentation; -#pragma warning disable CA1515 public class AspNetCoreInstrumentationNewBenchmarks -#pragma warning restore CA1515 { private HttpClient? httpClient; private WebApplication? app; @@ -77,9 +75,7 @@ public class AspNetCoreInstrumentationNewBenchmarks private MeterProvider? meterProvider; [Flags] -#pragma warning disable CA1515 public enum EnableInstrumentationOption -#pragma warning restore CA1515 { /// /// Instrumentation is not enabled for any signal. diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs index a49503722b..f16ff357a7 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestFixture.cs @@ -59,7 +59,7 @@ public async Task MakeRequest(TestApplicationScenario scenario, string path) await HttpClient.GetAsync(new Uri(url)); } - public void AddTestResult(RoutingTestResult result) + internal void AddTestResult(RoutingTestResult result) { this.testResults.Add(result); } diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs index affa074c20..fb0c5e65c8 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/RoutingTestResult.cs @@ -7,7 +7,7 @@ namespace RouteTests; -public class RoutingTestResult +internal class RoutingTestResult { private static readonly JsonSerializerOptions JsonSerializerOptions = new() { WriteIndented = true }; @@ -19,10 +19,10 @@ public class RoutingTestResult public string? MetricHttpRoute { get; set; } - public RouteInfo RouteInfo { get; set; } = new RouteInfo(); + public RouteInfo RouteInfo { get; set; } = new(); [JsonIgnore] - public TestCase TestCase { get; set; } = new TestCase(); + public TestCase TestCase { get; set; } = new(); public override string ToString() { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs index e0df2673e8..67c6fd112f 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/ActionDescriptorInfo.cs @@ -8,7 +8,7 @@ namespace RouteTests.TestApplication; -public class ActionDescriptorInfo +internal class ActionDescriptorInfo { public ActionDescriptorInfo() { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs index bdaf96851a..fa98679e02 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/PageActionDescriptorInfo.cs @@ -5,7 +5,7 @@ namespace RouteTests.TestApplication; -public class PageActionDescriptorInfo +internal class PageActionDescriptorInfo { public PageActionDescriptorInfo() { diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs index 2754617e78..ad2e92e737 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfo.cs @@ -11,7 +11,7 @@ namespace RouteTests.TestApplication; -public class RouteInfo +internal class RouteInfo { public static RouteInfo Current { get; set; } = new(); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs index a144f56b58..5b1b5297dc 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/RouteTests/TestApplication/RouteInfoDiagnosticObserver.cs @@ -94,15 +94,22 @@ private void Dispose(bool disposing) lock (this.listenerSubscriptions) { - foreach (var listenerSubscription in this.listenerSubscriptions) + if (disposing) { - listenerSubscription?.Dispose(); + foreach (var listenerSubscription in this.listenerSubscriptions) + { + listenerSubscription?.Dispose(); + } } this.listenerSubscriptions.Clear(); } - this.allSourcesSubscription?.Dispose(); + if (disposing) + { + this.allSourcesSubscription?.Dispose(); + } + this.allSourcesSubscription = null; } } diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs index 71202573c6..fea8023cff 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/BooksEntity.cs @@ -6,7 +6,7 @@ namespace OpenTelemetry.Instrumentation.Cassandra.Tests; [Table("books")] -public class BooksEntity +internal class BooksEntity { public BooksEntity(Guid id, string name) { diff --git a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs index 380069bdf9..206b596f04 100644 --- a/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.Cassandra.Tests/CassandraInstrumentationTests.cs @@ -72,8 +72,8 @@ public async Task CassandraMetricsWithCustomOptionsCaptured() var options = new DriverMetricsOptions(); - options.SetEnabledNodeMetrics(new[] { NodeMetric.Gauges.InFlight }); - options.SetEnabledSessionMetrics(new List()); + options.SetEnabledNodeMetrics([NodeMetric.Gauges.InFlight]); + options.SetEnabledSessionMetrics([]); var cluster = new Builder() .WithConnectionString(this.cassandraConnectionString) @@ -97,7 +97,7 @@ public async Task CassandraMetricsWithCustomOptionsCaptured() var inFlightConnection = exportedItems.FirstOrDefault(i => i.Name == "cassandra.pool.in-flight"); Assert.NotNull(inFlightConnection); - Assert.True(exportedItems.Count == 1); + Assert.Single(exportedItems); Assert.NotEmpty(books); } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs index 7d01bdb8bb..b1512d7d94 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/DependencyInjectionConfigTests.cs @@ -15,7 +15,7 @@ public class DependencyInjectionConfigTests [InlineData("CustomName")] public async Task TestTracingOptionsDiConfig(string? name) { - bool optionsPickedFromDi = false; + var optionsPickedFromDi = false; var services = new ServiceCollection(); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs index 558d53ef95..efaf6d8776 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/DependencyInjectionConfigTests.cs @@ -16,7 +16,7 @@ public class DependencyInjectionConfigTests [InlineData("CustomName")] public async Task TestTracingOptionsDiConfig(string? name) { - bool optionsPickedFromDi = false; + var optionsPickedFromDi = false; var services = new ServiceCollection(); diff --git a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs index 7157660583..614882d572 100644 --- a/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs +++ b/test/OpenTelemetry.Instrumentation.Hangfire.Tests/HangfireFixture.cs @@ -7,9 +7,7 @@ namespace OpenTelemetry.Instrumentation.Hangfire.Tests; -#pragma warning disable CA1515 public class HangfireFixture : IDisposable -#pragma warning restore CA1515 { public HangfireFixture() { diff --git a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs index 1905acb938..5664716337 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Benchmarks/Instrumentation/HttpClientInstrumentationBenchmarks.cs @@ -26,9 +26,7 @@ namespace OpenTelemetry.Instrumentation.Http.Benchmarks.Instrumentation; -#pragma warning disable CA1515 public class HttpClientInstrumentationBenchmarks -#pragma warning restore CA1515 { private static readonly Uri Url = new("http://localhost:5000"); @@ -38,9 +36,7 @@ public class HttpClientInstrumentationBenchmarks private MeterProvider? meterProvider; [Flags] -#pragma warning disable CA1515 public enum EnableInstrumentationOption -#pragma warning restore CA1515 { /// /// Instrumentation is not enabled for any signal. diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs index 43cdefd887..dd632eb9e5 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpOutTestCase.cs @@ -3,9 +3,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests; -#pragma warning disable CA1515 public class HttpOutTestCase -#pragma warning restore CA1515 { public HttpOutTestCase(string name, string method, string url, Dictionary? headers, int responseCode, string spanName, bool responseExpected, bool? recordException, string spanStatus, Dictionary spanAttributes) { diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs index 549afff40b..3c2fed27fc 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientIntegrationTestsFixture.cs @@ -9,9 +9,7 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Tests; -#pragma warning disable CA1515 public sealed class SqlClientIntegrationTestsFixture : IAsyncLifetime -#pragma warning restore CA1515 { // The Microsoft SQL Server Docker image is not compatible with ARM devices, such as Macs with Apple Silicon. public IContainer DatabaseContainer { get; } = Architecture.Arm64.Equals(RuntimeInformation.ProcessArchitecture) ? CreateSqlEdge() : CreateMsSql(); diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs index 62ba66c37c..f2b7e07e2b 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTestCase.cs @@ -5,9 +5,7 @@ namespace OpenTelemetry.Instrumentation.SqlClient.Tests; -#pragma warning disable CA1515 public class SqlClientTestCase : IEnumerable -#pragma warning restore CA1515 { public string ConnectionString { get; set; } = string.Empty; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 1587d407a1..1ef38476e1 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -539,7 +539,7 @@ internal static void VerifyDurationMetricData(Metric metric, Activity? activity) if (activity != null) { - var count = metricPoint.GetHistogramCount(); + _ = metricPoint.GetHistogramCount(); var sum = metricPoint.GetHistogramSum(); Assert.Equal(activity.Duration.TotalSeconds, sum); } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index 8d0c47d002..891395edd8 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -42,10 +42,10 @@ from emitOldAttributes in bools from emitNewAttributes in bools from tracingEnabled in bools from metricsEnabled in bools - where !(commandType == CommandType.Text && captureText == true) - where emitOldAttributes != false && emitNewAttributes != false + where !(commandType == CommandType.Text && captureText) + where emitOldAttributes && emitNewAttributes let commandText = commandType == CommandType.Text - ? (isFailure == false ? "select 1/1" : "select 1/0") + ? (!isFailure ? "select 1/1" : "select 1/0") : "sp_who" let sqlExceptionNumber = 0 select new object[] diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs index 2f648af344..ee27070d04 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlTestData.cs @@ -22,7 +22,7 @@ from emitOldAttributes in bools from emitNewAttributes in bools from tracingEnabled in bools from metricsEnabled in bools - where emitOldAttributes != false && emitNewAttributes != false + where emitOldAttributes && emitNewAttributes let endCommand = beforeCommand == SqlClientDiagnosticListener.SqlDataBeforeExecuteCommand ? SqlClientDiagnosticListener.SqlDataAfterExecuteCommand : SqlClientDiagnosticListener.SqlMicrosoftAfterExecuteCommand diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs index d4d864cb48..7bb7c332b9 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/Implementation/RedisProfilerEntryToActivityConverterTests.cs @@ -115,10 +115,10 @@ public void ProfilerCommandToActivity_UsesFlagsForFlagsAttribute() public void ProfilerCommandToActivity_UsesIpEndPointAsEndPoint() { long address = 1; - int port = 2; + var port = 2; var activity = new Activity("redis-profiler"); - IPEndPoint ipLocalEndPoint = new IPEndPoint(address, port); + var ipLocalEndPoint = new IPEndPoint(address, port); var profiledCommand = new TestProfiledCommand(DateTime.UtcNow, ipLocalEndPoint); var result = RedisProfilerEntryToActivityConverter.ProfilerCommandToActivity(activity, profiledCommand, new StackExchangeRedisInstrumentationOptions()); diff --git a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs index acf0081639..b5ceb13249 100644 --- a/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs +++ b/test/OpenTelemetry.Instrumentation.StackExchangeRedis.Tests/StackExchangeRedisCallsInstrumentationTests.cs @@ -57,7 +57,7 @@ public void SuccessfulCommandTestWithKey(string value) Assert.False(redisValue.HasValue); - bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + var set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); Assert.True(set); @@ -122,7 +122,7 @@ public void SuccessfulCommandTest(string value, string? serviceKey) var db = connection.GetDatabase(); - bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + var set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); Assert.True(set); @@ -199,7 +199,7 @@ public void CanEnrichActivityFromCommand(string value) var db = connection.GetDatabase(); - bool set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); + var set = db.StringSet("key1", value, TimeSpan.FromSeconds(60)); Assert.True(set); @@ -232,7 +232,7 @@ public void CheckCacheIsFlushedProperly() var profilerFactory = instrumentation.GetProfilerSessionsFactory(); // start a root level activity - using Activity rootActivity = new Activity("Parent") + using var rootActivity = new Activity("Parent") .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) .Start(); @@ -240,7 +240,7 @@ public void CheckCacheIsFlushedProperly() // get an initial profiler from root activity Activity.Current = rootActivity; - ProfilingSession? profiler0 = profilerFactory(); + var profiler0 = profilerFactory(); // expect different result from synchronous child activity using (Activity.Current = new Activity("Child-Span-1").SetParentId(rootActivity.Id).Start()) @@ -271,7 +271,7 @@ public async Task ProfilerSessionsHandleMultipleSpans() var profilerFactory = instrumentation.GetProfilerSessionsFactory(); // start a root level activity - using Activity rootActivity = new Activity("Parent") + using var rootActivity = new Activity("Parent") .SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded) .Start(); @@ -279,7 +279,7 @@ public async Task ProfilerSessionsHandleMultipleSpans() // get an initial profiler from root activity Activity.Current = rootActivity; - ProfilingSession? profiler0 = profilerFactory(); + var profiler0 = profilerFactory(); // expect different result from synchronous child activity ProfilingSession? profiler1; @@ -297,7 +297,7 @@ public async Task ProfilerSessionsHandleMultipleSpans() // lose async context on purpose await Task.Delay(100); - ProfilingSession? profiler2 = profilerFactory(); + var profiler2 = profilerFactory(); Assert.NotSame(profiler0, profiler2); Assert.NotSame(profiler1, profiler2); } @@ -305,15 +305,15 @@ public async Task ProfilerSessionsHandleMultipleSpans() Activity.Current = rootActivity; // ensure same result back in root activity - ProfilingSession? profiles3 = profilerFactory(); + var profiles3 = profilerFactory(); Assert.Same(profiler0, profiles3); } [Fact] public void StackExchangeRedis_DependencyInjection_Success() { - bool connectionMultiplexerPickedFromDI = false; - bool optionsPickedFromDI = false; + var connectionMultiplexerPickedFromDI = false; + var optionsPickedFromDI = false; var connectionOptions = new ConfigurationOptions { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs index ff6e69dba7..8d52c63e3c 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationBindingElement.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationBindingElement : BindingElement -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public override BindingElement Clone() { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs index 5b93254776..db6f1d0af0 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannel.cs @@ -7,9 +7,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationChannel : DispatchProxy -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public const string DownstreamInstrumentationSourceName = "DownstreamInstrumentationSource"; private static readonly ActivitySource DownstreamInstrumentationSource = new(DownstreamInstrumentationSourceName); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs index 78769adea8..ce30c6e5f4 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationChannelFactory.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationChannelFactory : DispatchProxy -#pragma warning restore CA1515 // Make class internal, public is needed for WCF where TChannel : notnull { public IChannelFactory? Target { get; set; } diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs index 24b11c21cc..20c8417239 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/Tools/DownstreamInstrumentationEndpointBehavior.cs @@ -7,9 +7,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests.Tools; -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class DownstreamInstrumentationEndpointBehavior : IEndpointBehavior -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs index 8eaec2db43..b9c1cef19a 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/IServiceContract.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [ServiceContract(Namespace = "http://opentelemetry.io/", Name = "Service", SessionMode = SessionMode.Allowed)] -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public interface IServiceContract -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { [OperationContract] Task ExecuteAsync(ServiceRequest request); diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs index c3f2056b4c..b67b98caef 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceClient.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class ServiceClient : ClientBase, IServiceContract -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public ServiceClient(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs index 1329f1b654..c41027301b 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceRequest.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [DataContract] -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class ServiceRequest -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public ServiceRequest(string payload) { diff --git a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs index 8dfef624bd..d26066edc6 100644 --- a/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs +++ b/test/OpenTelemetry.Instrumentation.Wcf.Tests/WCF/ServiceResponse.cs @@ -6,9 +6,7 @@ namespace OpenTelemetry.Instrumentation.Wcf.Tests; [DataContract] -#pragma warning disable CA1515 // Make class internal, public is needed for WCF public class ServiceResponse -#pragma warning restore CA1515 // Make class internal, public is needed for WCF { public ServiceResponse(string payload) { diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs index 65fe724208..e657f5411e 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/DirectorySizeTrackerTests.cs @@ -16,28 +16,28 @@ public void VerifyDirectorySizeTracker() var directorySizeTracker = new DirectorySizeTracker(maxSizeInBytes: 100, path: testDirectory.FullName); // new directory, expected to have space - Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize1)); + Assert.True(directorySizeTracker.IsSpaceAvailable(out var currentSize1)); Assert.Equal(0, currentSize1); // add a file and check current space. directorySizeTracker.FileAdded(30); - Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize2)); + Assert.True(directorySizeTracker.IsSpaceAvailable(out var currentSize2)); Assert.Equal(30, currentSize2); // add a file and check current space. Here we've exceeded the configured max size directorySizeTracker.FileAdded(100); - Assert.False(directorySizeTracker.IsSpaceAvailable(out long currentSize3)); + Assert.False(directorySizeTracker.IsSpaceAvailable(out var currentSize3)); Assert.Equal(130, currentSize3); // remove a file and check current space. directorySizeTracker.FileRemoved(50); - Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize4)); + Assert.True(directorySizeTracker.IsSpaceAvailable(out var currentSize4)); Assert.Equal(80, currentSize4); // since we haven't actually written any files to disk, // Recount will reset to zero. directorySizeTracker.RecountCurrentSize(); - Assert.True(directorySizeTracker.IsSpaceAvailable(out long currentSize5)); + Assert.True(directorySizeTracker.IsSpaceAvailable(out var currentSize5)); Assert.Equal(0, currentSize5); // cleanup diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs index e35a2a4b90..9decfd36f2 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobProviderTests.cs @@ -70,9 +70,9 @@ public void FileBlobProvider_TestRetentionPeriod() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; - int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 1000; - int writeTimeOutInMilliseconds = 1000; + var maintenancePeriodInMilliseconds = 3000; + var retentionPeriodInMilliseconds = 1000; + var writeTimeOutInMilliseconds = 1000; using var blobProvider = new FileBlobProvider( testDirectory.FullName, maxSizeInBytes, @@ -99,9 +99,9 @@ public void FileBlobProvider_TestWriteTimeoutPeriod() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; - int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 2000; - int writeTimeOutInMilliseconds = 1000; + var maintenancePeriodInMilliseconds = 3000; + var retentionPeriodInMilliseconds = 2000; + var writeTimeOutInMilliseconds = 1000; using var blobProvider = new FileBlobProvider( testDirectory.FullName, maxSizeInBytes, @@ -136,9 +136,9 @@ public void FileBlobProviderTests_TestLeaseExpiration() { var testDirectory = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); long maxSizeInBytes = 100000; - int maintenancePeriodInMilliseconds = 3000; - int retentionPeriodInMilliseconds = 2000; - int writeTimeOutInMilliseconds = 1000; + var maintenancePeriodInMilliseconds = 3000; + var retentionPeriodInMilliseconds = 2000; + var writeTimeOutInMilliseconds = 1000; using var blobProvider = new FileBlobProvider( testDirectory.FullName, maxSizeInBytes, diff --git a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs index 706dae983f..96f0463bf2 100644 --- a/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs +++ b/test/OpenTelemetry.PersistentStorage.FileSystem.Tests/FileBlobTests.cs @@ -62,8 +62,8 @@ public void FileBlobTests_LeaseAfterDelete() public void FileBlobTests_ReadFailsOnAlreadyLeasedFile() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob1 = new FileBlob(testFile.FullName); - FileBlob blob2 = new FileBlob(testFile.FullName); + var blob1 = new FileBlob(testFile.FullName); + var blob2 = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); Assert.True(blob2.TryWrite(data)); @@ -83,8 +83,8 @@ public void FileBlobTests_ReadFailsOnAlreadyLeasedFile() public void FileBlobTests_LeaseFailsOnAlreadyLeasedFileByOtherObject() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob1 = new FileBlob(testFile.FullName); - FileBlob blob2 = new FileBlob(testFile.FullName); + var blob1 = new FileBlob(testFile.FullName); + var blob2 = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); Assert.True(blob1.TryWrite(data)); @@ -103,7 +103,7 @@ public void FileBlobTests_LeaseFailsOnAlreadyLeasedFileByOtherObject() public void FileBlobTests_Delete() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob = new FileBlob(testFile.FullName); + var blob = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); @@ -147,7 +147,7 @@ public void FileBlobTests_DeleteFailsAfterLeaseIsExpired() public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() { var testFile = new FileInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - FileBlob blob = new FileBlob(testFile.FullName); + var blob = new FileBlob(testFile.FullName); var data = Encoding.UTF8.GetBytes("Hello, World!"); Assert.True(blob.TryWrite(data)); @@ -170,7 +170,7 @@ public void FileBlobTests_LeaseTimeIsUpdatedWhenLeasingAlreadyLeasedFile() public void FileBlobTests_FailedWrite() { var nonExistingPath = Path.Combine("FakePath:/", Path.GetRandomFileName()); - FileBlob blob = new FileBlob(nonExistingPath); + var blob = new FileBlob(nonExistingPath); Assert.False(blob.TryWrite([])); } diff --git a/test/OpenTelemetry.Resources.AWS.Tests/Http/CertificateUploader.cs b/test/OpenTelemetry.Resources.AWS.Tests/Http/CertificateUploader.cs index 924821e7a4..f2d4384295 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/Http/CertificateUploader.cs +++ b/test/OpenTelemetry.Resources.AWS.Tests/Http/CertificateUploader.cs @@ -21,8 +21,8 @@ public CertificateUploader() public string FilePath { - get { return this.filePath; } - set { this.filePath = value; } + get => this.filePath; + set => this.filePath = value; } public void Create() @@ -40,9 +40,9 @@ public void Create() var exportData = certificate.Export(X509ContentType.Cert); var crt = Convert.ToBase64String(exportData, Base64FormattingOptions.InsertLineBreaks); - using (FileStream stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) + using (var stream = new FileStream(this.filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete)) { - using (StreamWriter sw = new StreamWriter(stream)) + using (var sw = new StreamWriter(stream)) { sw.Write(CRTHEADER + crt + CRTFOOTER); } @@ -51,7 +51,7 @@ public void Create() public void Dispose() { - for (int tries = 0; ; tries++) + for (var tries = 0; ; tries++) { try { diff --git a/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs b/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs index 762c04ca02..f06438c411 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs +++ b/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationHandlerTests.cs @@ -14,7 +14,7 @@ public class ServerCertificateValidationHandlerTests [Fact] public void TestValidHandler() { - using (CertificateUploader certificateUploader = new CertificateUploader()) + using (var certificateUploader = new CertificateUploader()) { certificateUploader.Create(); diff --git a/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs b/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs index 7151659be8..e45c2787c6 100644 --- a/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs +++ b/test/OpenTelemetry.Resources.AWS.Tests/Http/ServerCertificateValidationProviderTests.cs @@ -15,7 +15,7 @@ public class ServerCertificateValidationProviderTests [Fact] public void TestValidCertificate() { - using CertificateUploader certificateUploader = new CertificateUploader(); + using var certificateUploader = new CertificateUploader(); certificateUploader.Create(); var serverCertificateValidationProvider = @@ -28,7 +28,7 @@ public void TestValidCertificate() #else var certificate = new X509Certificate2(certificateUploader.FilePath); #endif - X509Chain chain = new X509Chain(); + var chain = new X509Chain(); chain.Build(certificate); // validates if certificate is valid diff --git a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs index 5321bd8b63..fedea860d3 100644 --- a/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs +++ b/test/OpenTelemetry.Resources.OperatingSystem.Tests/OperatingSystemDetectorTests.cs @@ -57,7 +57,7 @@ public void TestOperatingSystemAttributes() [Fact] public void TestParseMacOSPlist() { - string path = "Samples/SystemVersion.plist"; + var path = "Samples/SystemVersion.plist"; var osDetector = new OperatingSystemDetector( OperatingSystemSemanticConventions.OperatingSystemsValues.Darwin, null, @@ -74,8 +74,8 @@ public void TestParseMacOSPlist() [Fact] public void TestParseLinuxOsRelease() { - string path = "Samples/os-release"; - string kernelPath = "Samples/kernelOsrelease"; + var path = "Samples/os-release"; + var kernelPath = "Samples/kernelOsrelease"; var osDetector = new OperatingSystemDetector( OperatingSystemSemanticConventions.OperatingSystemsValues.Linux, null, diff --git a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs index 5d0c0bbc04..419c2094d6 100644 --- a/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs +++ b/test/OpenTelemetry.Sampler.AWS.Tests/TestAWSXRayRemoteSampler.cs @@ -24,7 +24,7 @@ public void TestSamplerWithConfiguration() .SetEndpoint(endpoint) .Build(); - FieldInfo? rootSamplerFieldInfo = typeof(ParentBasedSampler).GetField("rootSampler", BindingFlags.NonPublic | BindingFlags.Instance); + var rootSamplerFieldInfo = typeof(ParentBasedSampler).GetField("rootSampler", BindingFlags.NonPublic | BindingFlags.Instance); var xraySampler = (AWSXRayRemoteSampler?)rootSamplerFieldInfo?.GetValue(parentBasedSampler); @@ -39,7 +39,7 @@ public void TestSamplerWithDefaults() { var parentBasedSampler = AWSXRayRemoteSampler.Builder(ResourceBuilder.CreateEmpty().Build()).Build(); - FieldInfo? rootSamplerFieldInfo = typeof(ParentBasedSampler).GetField("rootSampler", BindingFlags.NonPublic | BindingFlags.Instance); + var rootSamplerFieldInfo = typeof(ParentBasedSampler).GetField("rootSampler", BindingFlags.NonPublic | BindingFlags.Instance); var xraySampler = (AWSXRayRemoteSampler?)rootSamplerFieldInfo?.GetValue(parentBasedSampler); diff --git a/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs b/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs index 068e587204..b55927000f 100644 --- a/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs +++ b/test/TestApp.AspNetCore/Controllers/ChildActivityController.cs @@ -8,9 +8,7 @@ namespace TestApp.AspNetCore.Controllers; -#pragma warning disable CA1515 public class ChildActivityController : Controller -#pragma warning restore CA1515 { [HttpGet] [Route("api/GetChildActivityTraceContext")] diff --git a/test/TestApp.AspNetCore/Controllers/ErrorController.cs b/test/TestApp.AspNetCore/Controllers/ErrorController.cs index acecf79292..24c904cfe9 100644 --- a/test/TestApp.AspNetCore/Controllers/ErrorController.cs +++ b/test/TestApp.AspNetCore/Controllers/ErrorController.cs @@ -6,9 +6,7 @@ namespace TestApp.AspNetCore.Controllers; [Route("api/[controller]")] -#pragma warning disable CA1515 public class ErrorController : Controller -#pragma warning restore CA1515 { // GET api/error [HttpGet] diff --git a/test/TestApp.AspNetCore/Controllers/ValuesController.cs b/test/TestApp.AspNetCore/Controllers/ValuesController.cs index 6173415709..4528f037fa 100644 --- a/test/TestApp.AspNetCore/Controllers/ValuesController.cs +++ b/test/TestApp.AspNetCore/Controllers/ValuesController.cs @@ -6,9 +6,7 @@ namespace TestApp.AspNetCore.Controllers; [Route("api/[controller]")] -#pragma warning disable CA1515 public class ValuesController : Controller -#pragma warning restore CA1515 { // GET api/values [HttpGet] diff --git a/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs b/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs index 9f23da3f0a..f2b7a03f6d 100644 --- a/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs +++ b/test/TestApp.AspNetCore/Filters/ExceptionFilter1.cs @@ -5,12 +5,10 @@ namespace TestApp.AspNetCore.Filters; -#pragma warning disable CA1515 public class ExceptionFilter1 : IExceptionFilter -#pragma warning restore CA1515 { public void OnException(ExceptionContext context) { - // test the behaviour when an application has two ExceptionFilters defined + // test the behavior when an application has two ExceptionFilters defined } } diff --git a/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs b/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs index 4bf428d53f..6efeecfe0d 100644 --- a/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs +++ b/test/TestApp.AspNetCore/Filters/ExceptionFilter2.cs @@ -5,12 +5,10 @@ namespace TestApp.AspNetCore.Filters; -#pragma warning disable CA1515 public class ExceptionFilter2 : IExceptionFilter -#pragma warning restore CA1515 { public void OnException(ExceptionContext context) { - // test the behaviour when an application has two ExceptionFilters defined + // test the behavior when an application has two ExceptionFilters defined } } diff --git a/test/TestApp.AspNetCore/Program.cs b/test/TestApp.AspNetCore/Program.cs index c673e205eb..5cbe2b5e3a 100644 --- a/test/TestApp.AspNetCore/Program.cs +++ b/test/TestApp.AspNetCore/Program.cs @@ -3,9 +3,7 @@ using TestApp.AspNetCore; -#pragma warning disable CA1515 public class Program -#pragma warning restore CA1515 { public static void Main(string[] args) { diff --git a/test/TestApp.AspNetCore/TestActivityMiddleware.cs b/test/TestApp.AspNetCore/TestActivityMiddleware.cs index e14ad9295c..be1e2e5a1e 100644 --- a/test/TestApp.AspNetCore/TestActivityMiddleware.cs +++ b/test/TestApp.AspNetCore/TestActivityMiddleware.cs @@ -3,9 +3,7 @@ namespace TestApp.AspNetCore; -#pragma warning disable CA1515 public class TestActivityMiddleware -#pragma warning restore CA1515 { public virtual void PreProcess(HttpContext context) { diff --git a/test/TestApp.AspNetCore/TestCallbackMiddleware.cs b/test/TestApp.AspNetCore/TestCallbackMiddleware.cs index 50e563da16..ba11577ff0 100644 --- a/test/TestApp.AspNetCore/TestCallbackMiddleware.cs +++ b/test/TestApp.AspNetCore/TestCallbackMiddleware.cs @@ -3,9 +3,7 @@ namespace TestApp.AspNetCore; -#pragma warning disable CA1515 public class TestCallbackMiddleware -#pragma warning restore CA1515 { public virtual async Task ProcessAsync(HttpContext context) { diff --git a/test/TestApp.AspNetCore/TestMiddleware.cs b/test/TestApp.AspNetCore/TestMiddleware.cs index 711814d263..39acf58db3 100644 --- a/test/TestApp.AspNetCore/TestMiddleware.cs +++ b/test/TestApp.AspNetCore/TestMiddleware.cs @@ -3,9 +3,7 @@ namespace TestApp.AspNetCore; -#pragma warning disable CA1515 public static class TestMiddleware -#pragma warning restore CA1515 { private static readonly AsyncLocal?> Current = new(); From 053fc353eca3f9936b65b51072268b6f3a4d454c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 4 Dec 2024 06:43:05 +0100 Subject: [PATCH 1441/1499] [repo] Bump internal packages (#2355) --- build/Common.nonprod.props | 6 +++--- build/Common.props | 2 +- examples/AspNet/Examples.AspNet.csproj | 2 +- .../Examples.GrpcCore.AspNetCore.csproj | 2 +- .../OpenTelemetry.Exporter.Geneva.Tests.csproj | 2 +- .../HttpInListenerTests.cs | 2 +- .../BasicTests.cs | 6 +++--- .../OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj | 2 +- ...OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj | 5 ++--- .../HttpClientTests.Basic.cs | 4 ++-- .../HttpClientTests.cs | 2 +- .../HttpWebRequestTests.Basic.cs | 6 +++--- .../HttpWebRequestTests.cs | 2 +- .../SqlClientTests.cs | 2 +- 14 files changed, 22 insertions(+), 23 deletions(-) diff --git a/build/Common.nonprod.props b/build/Common.nonprod.props index 39899ccd69..6ee87b2d65 100644 --- a/build/Common.nonprod.props +++ b/build/Common.nonprod.props @@ -27,13 +27,13 @@ [0.13.12,0.14) 8.0.1 8.0.1 - [17.11.1,18.0) + [17.12.0,18.0) $(OpenTelemetryCoreLatestVersion) net9.0;net8.0 [2.8.2,3.0) - [2.9.0,3.0) - [1.6.3,2.0) + [2.9.2,3.0) + [1.6.8,2.0) diff --git a/build/Common.props b/build/Common.props index a33837c548..4305b94351 100644 --- a/build/Common.props +++ b/build/Common.props @@ -33,7 +33,7 @@ Please sort alphabetically. Refer to https://docs.microsoft.com/en-us/nuget/concepts/package-versioning for semver syntax. --> - [5.0.0,6.0) + [6.0.0,7.0) [2.1.0,5.0) [9.0.0,) [9.0.0,) diff --git a/examples/AspNet/Examples.AspNet.csproj b/examples/AspNet/Examples.AspNet.csproj index 265a3c3319..49942bee82 100644 --- a/examples/AspNet/Examples.AspNet.csproj +++ b/examples/AspNet/Examples.AspNet.csproj @@ -53,7 +53,7 @@ - + diff --git a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj index 6f60b4f98d..a1d4774eb7 100644 --- a/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj +++ b/examples/grpc.core/Examples.GrpcCore.AspNetCore/Examples.GrpcCore.AspNetCore.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index 2d51d7d2f1..a793d6cfea 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs index e119eb5962..48b8bdc58c 100644 --- a/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNet.Tests/HttpInListenerTests.cs @@ -156,7 +156,7 @@ public void AspNetRequestsAreCollectedSuccessfully( if (filter == "{ThrowException}") { - Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 2)); + Assert.Single(inMemoryEventListener.Events, e => e.EventId == 2); } Assert.Equal(TelemetryHttpModule.AspNetActivityName, Activity.Current!.OperationName); diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs index abbf3148c5..ac7a5929ec 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/BasicTests.cs @@ -129,8 +129,8 @@ void ConfigureTestServices(IServiceCollection services) if (shouldEnrich) { - Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enrichedOnStart" && tag.Value == "yes")); - Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enrichedOnStop" && tag.Value == "yes")); + Assert.Contains(activity.Tags, tag => tag.Key == "enrichedOnStart" && tag.Value == "yes"); + Assert.Contains(activity.Tags, tag => tag.Key == "enrichedOnStop" && tag.Value == "yes"); } ValidateAspNetCoreActivity(activity, "/api/values"); @@ -321,7 +321,7 @@ void ConfigureTestServices(IServiceCollection services) response1.EnsureSuccessStatusCode(); // Status Code 200-299 response2.EnsureSuccessStatusCode(); // Status Code 200-299 - Assert.Single(inMemoryEventListener.Events.Where((e) => e.EventId == 3)); + Assert.Single(inMemoryEventListener.Events, e => e.EventId == 3); } WaitForActivityExport(exportedItems, 1); diff --git a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj index ae45b9c775..bc2e9fcf01 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcCore.Tests/OpenTelemetry.Instrumentation.GrpcCore.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj index 19028bb635..de04519bb7 100644 --- a/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj +++ b/test/OpenTelemetry.Instrumentation.GrpcNetClient.Tests/OpenTelemetry.Instrumentation.GrpcNetClient.Tests.csproj @@ -4,7 +4,6 @@ $(SupportedNetTargets) $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) Unit test project for OpenTelemetry Grpc for .NET instrumentation. - $(NoWarn);CS8981 @@ -15,12 +14,12 @@ - + - + diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs index af7413b149..43f28daf74 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.Basic.cs @@ -592,7 +592,7 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() using var c = new HttpClient(); using var inMemoryEventListener = new InMemoryEventListener(HttpInstrumentationEventSource.Log); await c.GetAsync(new Uri(this.url)); - Assert.Single(inMemoryEventListener.Events.Where(e => e.EventId == 4)); + Assert.Single(inMemoryEventListener.Events, e => e.EventId == 4); } Assert.Empty(exportedItems); @@ -621,7 +621,7 @@ public async Task ReportsExceptionEventForNetworkFailuresWithGetAsync() // Exception is thrown and collected as event Assert.True(exceptionThrown); - Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + Assert.Single(exportedItems[0].Events, evt => evt.Name.Equals("exception")); } [Fact] diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs index 1ccf563a51..4d205386d5 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpClientTests.cs @@ -387,7 +387,7 @@ private static async Task HttpOutCallsAreCollectedSuccessfullyBodyAsync( if (tc.RecordException.HasValue && tc.RecordException.Value) { - Assert.Single(activity.Events.Where(evt => evt.Name.Equals("exception"))); + Assert.Single(activity.Events, evt => evt.Name.Equals("exception")); Assert.True(enrichWithExceptionCalled); } } diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs index cdc717d00b..f3390a3ab1 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.Basic.cs @@ -150,7 +150,7 @@ public async Task RequestNotCollectedWhenInstrumentationFilterThrowsException() using var response = await request.GetResponseAsync(); - Assert.Single(inMemoryEventListener.Events.Where(e => e.EventId == 4)); + Assert.Single(inMemoryEventListener.Events, e => e.EventId == 4); } Assert.Empty(exportedItems); @@ -327,7 +327,7 @@ public async Task ReportsExceptionEventForNetworkFailures() // Exception is thrown and collected as event Assert.True(exceptionThrown); - Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + Assert.Single(exportedItems[0].Events, evt => evt.Name.Equals("exception")); } [Fact] @@ -357,7 +357,7 @@ public async Task ReportsExceptionEventOnErrorResponse() #if NETFRAMEWORK // Exception is thrown and collected as event Assert.True(exceptionThrown); - Assert.Single(exportedItems[0].Events.Where(evt => evt.Name.Equals("exception"))); + Assert.Single(exportedItems[0].Events, evt => evt.Name.Equals("exception")); #else // Note: On .NET Core exceptions through HttpWebRequest do not // trigger exception events they just throw: diff --git a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs index 2445a6baf6..70e217715a 100644 --- a/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs +++ b/test/OpenTelemetry.Instrumentation.Http.Tests/HttpWebRequestTests.cs @@ -155,7 +155,7 @@ public void HttpOutCallsAreCollectedSuccessfully(HttpOutTestCase tc) if (tc.RecordException.HasValue && tc.RecordException.Value) { - Assert.Single(activity.Events.Where(evt => evt.Name.Equals("exception"))); + Assert.Single(activity.Events, evt => evt.Name.Equals("exception")); Assert.True(enrichWithExceptionCalled); } } diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 1ef38476e1..a253ef350d 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -457,7 +457,7 @@ internal static void VerifyActivityData( if (shouldEnrich) { - Assert.NotEmpty(activity.Tags.Where(tag => tag.Key == "enriched")); + Assert.Contains(activity.Tags, tag => tag.Key == "enriched"); Assert.Equal("yes", activity.Tags.FirstOrDefault(tag => tag.Key == "enriched").Value); } else From cd8e05cc7b648ba4b5626b59fe51a98b683e37e9 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 5 Dec 2024 18:25:35 -0600 Subject: [PATCH 1442/1499] [release] Prepare release Instrumentation.Runtime-1.10.0 (#2365) --- src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md index eaeddeec72..cc507dc6f5 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Runtime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0 + +Released 2024-Dec-05 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2155](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2155)), ([#2325](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2325)) From aff07e35b1b134e1b0943e44c4028598fab56bce Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:40:18 -0600 Subject: [PATCH 1443/1499] [release] Instrumentation.Runtime- stable release 1.10.0 updates (#2366) --- .../OpenTelemetry.Instrumentation.Runtime.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj index 8f349f186a..956f6d3867 100644 --- a/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj +++ b/src/OpenTelemetry.Instrumentation.Runtime/OpenTelemetry.Instrumentation.Runtime.csproj @@ -6,7 +6,7 @@ .NET runtime instrumentation for OpenTelemetry .NET. $(PackageTags);runtime Instrumentation.Runtime- - 1.9.0 + 1.10.0 From 57d476905157d12c58a6cbd1d7e2ee0cbf2e1260 Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Thu, 5 Dec 2024 22:02:01 -0800 Subject: [PATCH 1444/1499] [Resources.AWS] Move string literals to AWS Semantic Conventions class (#2363) --- src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs | 6 +++--- src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs | 4 ++-- src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs | 4 ++-- src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs | 4 ++-- src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs | 6 ++++++ 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs index 80acea1404..be18b19080 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEBSDetector.cs @@ -56,9 +56,9 @@ internal static List> ExtractResourceAttributes(AWS { var resourceAttributes = new List>() { - new(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new(AWSSemanticConventions.AttributeCloudPlatform, "aws_elastic_beanstalk"), - new(AWSSemanticConventions.AttributeServiceName, "aws_elastic_beanstalk"), + new(AWSSemanticConventions.AttributeCloudProvider, AWSSemanticConventions.CloudProviderValuesAws), + new(AWSSemanticConventions.AttributeCloudPlatform, AWSSemanticConventions.CloudPlatformValuesAwsElasticBeanstalk), + new(AWSSemanticConventions.AttributeServiceName, AWSSemanticConventions.ServiceNameValuesAwsElasticBeanstalk), }; if (metadata != null) diff --git a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs index 076adbf48d..d93ed52611 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEC2Detector.cs @@ -45,8 +45,8 @@ internal static List> ExtractResourceAttributes(AWS { var resourceAttributes = new List>() { - new(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new(AWSSemanticConventions.AttributeCloudPlatform, "aws_ec2"), + new(AWSSemanticConventions.AttributeCloudProvider, AWSSemanticConventions.CloudProviderValuesAws), + new(AWSSemanticConventions.AttributeCloudPlatform, AWSSemanticConventions.CloudPlatformValuesAwsEc2), new(AWSSemanticConventions.AttributeHostName, hostName), }; diff --git a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs index ac43f694ff..0f527f6a84 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSECSDetector.cs @@ -29,8 +29,8 @@ public Resource Detect() var resourceAttributes = new List>() { - new(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new(AWSSemanticConventions.AttributeCloudPlatform, "aws_ecs"), + new(AWSSemanticConventions.AttributeCloudProvider, AWSSemanticConventions.CloudProviderValuesAws), + new(AWSSemanticConventions.AttributeCloudPlatform, AWSSemanticConventions.CloudPlatformValuesAwsEcs), }; try diff --git a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs index adf4a59632..8d0860c4af 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSEKSDetector.cs @@ -38,8 +38,8 @@ internal static List> ExtractResourceAttributes(str { var resourceAttributes = new List>() { - new(AWSSemanticConventions.AttributeCloudProvider, "aws"), - new(AWSSemanticConventions.AttributeCloudPlatform, "aws_eks"), + new(AWSSemanticConventions.AttributeCloudProvider, AWSSemanticConventions.CloudProviderValuesAws), + new(AWSSemanticConventions.AttributeCloudPlatform, AWSSemanticConventions.CloudPlatformValuesAwsEks), }; if (!string.IsNullOrEmpty(clusterName)) diff --git a/src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs b/src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs index 1f5cd829d8..049047ea70 100644 --- a/src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs +++ b/src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs @@ -11,6 +11,11 @@ internal static class AWSSemanticConventions public const string AttributeCloudProvider = "cloud.provider"; public const string AttributeCloudRegion = "cloud.region"; public const string AttributeCloudResourceId = "cloud.resource_id"; + public const string CloudPlatformValuesAwsEc2 = "aws_ec2"; + public const string CloudPlatformValuesAwsEcs = "aws_ecs"; + public const string CloudPlatformValuesAwsEks = "aws_eks"; + public const string CloudPlatformValuesAwsElasticBeanstalk = "aws_elastic_beanstalk"; + public const string CloudProviderValuesAws = "aws"; public const string AttributeContainerID = "container.id"; @@ -43,4 +48,5 @@ internal static class AWSSemanticConventions public const string AttributeServiceNamespace = "service.namespace"; public const string AttributeServiceInstanceID = "service.instance.id"; public const string AttributeServiceVersion = "service.version"; + public const string ServiceNameValuesAwsElasticBeanstalk = "aws_elastic_beanstalk"; } From 9d50640c102e5ac1185d4e61cb074ff3802df354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 6 Dec 2024 07:16:18 +0100 Subject: [PATCH 1445/1499] Replace ActivityExtensions.SetStatus by Activity.SetStatus (#2358) Co-authored-by: Mikel Blanchard --- src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 5 +++++ .../Implementation/Tracing/AWSTraceSpan.cs | 5 +---- .../AWSLambdaWrapper.cs | 4 +--- .../CHANGELOG.md | 5 +++++ .../CHANGELOG.md | 5 +++++ .../OpenTelemetryConsumeResultExtensions.cs | 4 +--- .../CHANGELOG.md | 5 +++++ .../EntityFrameworkDiagnosticListener.cs | 5 +---- src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md | 5 +++++ .../Implementation/DiagnosticsMiddleware.cs | 4 +--- .../CHANGELOG.md | 5 +++++ .../Implementation/QuartzDiagnosticListener.cs | 5 +---- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 5 +++++ .../Implementation/ClientChannelInstrumentation.cs | 5 +---- .../TelemetryDispatchMessageInspector.cs | 5 +---- .../AWSLambdaWrapperTests.cs | 7 +++++-- .../EntityFrameworkDiagnosticListenerTests.cs | 1 - .../QuartzDiagnosticListenerTests.cs | 13 ++++++++----- 18 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index ff3c2ba693..a0e7c5398e 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 1.10.0-beta.1 Released 2024-Nov-23 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs index a825155d7f..c390c6bbd9 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/Tracing/AWSTraceSpan.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using Amazon.Runtime.Telemetry; using Amazon.Runtime.Telemetry.Tracing; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation.Tracing; @@ -60,9 +59,7 @@ public override void RecordException(Exception exception, Attributes? attributes var tags = attributes != null ? new TagList(attributes.AllAttributes.ToArray()) : default; this.activity.AddException(exception, tags); -#pragma warning disable CS0618 // Type or member is obsolete - this.activity.SetStatus(Status.Error.WithDescription(exception.Message)); -#pragma warning restore CS0618 // Type or member is obsolete + this.activity.SetStatus(ActivityStatusCode.Error, exception.Message); } public override void End() diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs index ab5930feec..7dbe014fbb 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/AWSLambdaWrapper.cs @@ -192,9 +192,7 @@ private static void OnException(Activity? activity, Exception exception) if (activity.IsAllDataRequested) { activity.AddException(exception); -#pragma warning disable CS0618 // Type or member is obsolete - activity.SetStatus(Status.Error.WithDescription(exception.Message)); -#pragma warning restore CS0618 // Type or member is obsolete + activity.SetStatus(ActivityStatusCode.Error, exception.Message); } } } diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index 0e1193c2d2..f57beb4e4d 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 1.10.0-beta.1 Released 2024-Nov-23 diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index cfa2dcb4f8..bd314a325b 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -9,6 +9,11 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 0.1.0-alpha.2 Released 2024-Sep-18 diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs index c1d650e2aa..2b67de516d 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumeResultExtensions.cs @@ -113,9 +113,7 @@ public static bool TryExtractPropagationContext( } catch (Exception ex) { -#pragma warning disable CS0618 // Type or member is obsolete - processActivity?.SetStatus(Status.Error); -#pragma warning restore CS0618 // Type or member is obsolete + processActivity?.SetStatus(ActivityStatusCode.Error); processActivity?.SetTag(SemanticConventions.AttributeErrorType, ex.GetType().FullName); } finally diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 0522374f01..8b43e2c59d 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -27,6 +27,11 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 1.0.0-beta.12 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs index 630a8ebef7..509402f807 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/Implementation/EntityFrameworkDiagnosticListener.cs @@ -5,7 +5,6 @@ using System.Diagnostics; using System.Reflection; using OpenTelemetry.Internal; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.EntityFrameworkCore.Implementation; @@ -297,9 +296,7 @@ public override void OnEventWritten(string name, object? payload) { if (this.exceptionFetcher.Fetch(payload) is Exception exception) { -#pragma warning disable CS0618 // Type or member is obsolete - activity.SetStatus(Status.Error.WithDescription(exception.Message)); -#pragma warning restore CS0618 // Type or member is obsolete + activity.SetStatus(ActivityStatusCode.Error, exception.Message); } else { diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 956886a70b..89a4131868 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -19,6 +19,11 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 1.0.0-rc.6 Released 2024-Apr-19 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index bc509a794d..a112528ae2 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -150,9 +150,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l if (exception != null) { -#pragma warning disable CS0618 // Type or member is obsolete - activity.SetStatus(Status.Error); -#pragma warning restore CS0618 // Type or member is obsolete + activity.SetStatus(ActivityStatusCode.Error); if (OwinInstrumentationActivitySource.Options?.RecordException == true) { diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index f9ad69cdbf..92b0d94fe4 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -5,6 +5,11 @@ * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 1.0.0-beta.3 Released 2024-Jun-18 diff --git a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs index 242df493f5..cd940ba04b 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Quartz/Implementation/QuartzDiagnosticListener.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Reflection; using OpenTelemetry.Internal; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Quartz.Implementation; @@ -140,9 +139,7 @@ private void OnException(Activity activity, object? payload) activity.AddException(exc); } -#pragma warning disable CS0618 // Type or member is obsolete - activity.SetStatus(Status.Error.WithDescription(exc.Message)); -#pragma warning restore CS0618 // Type or member is obsolete + activity.SetStatus(ActivityStatusCode.Error, exc.Message); try { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 00310a2e3c..60993f36e1 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -12,6 +12,11 @@ recorded (defaults to `false`). This is only supported by client instrumentation. ([#2271](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2271)) +* Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) + API instead of the deprecated OpenTelemetry API package extension when setting + span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). + ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) + ## 1.0.0-rc.18 Released 2024-Oct-28 diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs index c6e56f2b34..e33f07c0a8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/ClientChannelInstrumentation.cs @@ -5,7 +5,6 @@ using System.ServiceModel.Channels; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Wcf.Implementation; @@ -92,9 +91,7 @@ public static void AfterRequestCompleted(Message? reply, RequestTelemetryState? { if (reply == null || reply.IsFault) { -#pragma warning disable CS0618 // Type or member is obsolete - activity.SetStatus(Status.Error); -#pragma warning restore CS0618 // Type or member is obsolete + activity.SetStatus(ActivityStatusCode.Error); if (WcfInstrumentationActivitySource.Options!.RecordException && exception != null) { diff --git a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs index 3741f0b832..c32dffb8b8 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs +++ b/src/OpenTelemetry.Instrumentation.Wcf/Implementation/TelemetryDispatchMessageInspector.cs @@ -8,7 +8,6 @@ using System.ServiceModel.Dispatcher; using OpenTelemetry.Context.Propagation; using OpenTelemetry.Internal; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.Wcf.Implementation; @@ -123,9 +122,7 @@ public void BeforeSendReply(ref Message reply, object? correlationState) { if (reply.IsFault) { -#pragma warning disable CS0618 // Type or member is obsolete - activity.SetStatus(Status.Error); -#pragma warning restore CS0618 // Type or member is obsolete + activity.SetStatus(ActivityStatusCode.Error); } activity.SetTag(WcfInstrumentationConstants.SoapReplyActionTag, reply.Headers.Action); diff --git a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs index d36277b099..a63ec740b2 100644 --- a/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs +++ b/test/OpenTelemetry.Instrumentation.AWSLambda.Tests/AWSLambdaWrapperTests.cs @@ -279,7 +279,10 @@ private void AssertSpanAttributes(Activity activity) private void AssertSpanException(Activity activity) { - Assert.Equal("ERROR", activity.GetTagValue(SpanAttributeConstants.StatusCodeKey)); - Assert.NotNull(activity.GetTagValue(SpanAttributeConstants.StatusDescriptionKey)); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + Assert.Equal("TestException", activity.StatusDescription); + var exception = Assert.Single(activity.Events); + Assert.Equal("exception", exception.Name); + Assert.Equal("TestException", exception.Tags.SingleOrDefault(t => t.Key.Equals("exception.message")).Value); } } diff --git a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs index 7974ef93de..e96a059844 100644 --- a/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.EntityFrameworkCore.Tests/EntityFrameworkDiagnosticListenerTests.cs @@ -289,7 +289,6 @@ private static void VerifyActivityData(Activity activity, bool isError = false, { Assert.Equal(ActivityStatusCode.Error, activity.Status); Assert.Equal("SQLite Error 1: 'no such table: no_table'.", activity.StatusDescription); - Assert.Contains(activity.Tags, t => t.Key == SpanAttributeConstants.StatusDescriptionKey); } } diff --git a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs index 09289ecf17..980361f98e 100644 --- a/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs +++ b/test/OpenTelemetry.Instrumentation.Quartz.Tests/QuartzDiagnosticListenerTests.cs @@ -186,9 +186,10 @@ public async Task Should_Record_Exception_When_Record_Exception_Enabled() Assert.Single(exportedItems); var activity = exportedItems[0]; - Assert.Equal("exception", activity.Events.First().Name); - Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); - Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + var exception = Assert.Single(activity.Events); + Assert.Equal("exception", exception.Name); + Assert.Equal("Catch me if you can!", exception.Tags.SingleOrDefault(t => t.Key.Equals("exception.message")).Value); } [Fact] @@ -253,8 +254,10 @@ public async Task Should_Enrich_Exception_When_Record_Exception_Enabled_And_Enri Assert.Single(exportedItems); var activity = exportedItems[0]; - Assert.Equal("ERROR", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusCodeKey)).Value); - Assert.Equal("Catch me if you can!", activity.Tags.SingleOrDefault(t => t.Key.Equals(SpanAttributeConstants.StatusDescriptionKey)).Value); + Assert.Equal(ActivityStatusCode.Error, activity.Status); + var exception = Assert.Single(activity.Events); + Assert.Equal("exception", exception.Name); + Assert.Equal("Catch me if you can!", exception.Tags.SingleOrDefault(t => t.Key.Equals("exception.message")).Value); Assert.Equal(testId, activity.Tags.SingleOrDefault(t => t.Key.Equals("test.id")).Value); } From d0d7761bcd1babb9814b5d9a965bfd358f07197a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:04:21 -0600 Subject: [PATCH 1446/1499] [release] Prepare release Instrumentation.AspNet-1.10.0-beta.1 (#2370) --- .../CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md index 21b04d012c..ea89310332 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet.TelemetryHttpModule/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * `TelemetryHttpModule` will now pass the `url.path` tag (set to [Request.Unvalidated.Path](https://learn.microsoft.com/dotnet/api/system.web.unvalidatedrequestvalues.path)) when starting `Activity` instances for incoming requests so that it is diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 9e73e645cd..567a32e291 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Updated registration extension code to retrieve environment variables through `IConfiguration`. ([#1976](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1976)) From b7c188341621f8bc033bf08a967f5c7ad2d393bd Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:10:02 -0600 Subject: [PATCH 1447/1499] [release] Prepare release Instrumentation.EntityFrameworkCore-1.10.0-beta.1 (#2372) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md index 8b43e2c59d..c2510f474b 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * The new database semantic conventions can be opted in to by setting the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This allows for a transition period for users to experiment with the new semantic conventions From dfc2b74f4c22bd54948940bc3c889bccbb4e3a29 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:13:25 -0600 Subject: [PATCH 1448/1499] [release] Prepare release Instrumentation.GrpcNetClient-1.10.0-beta.1 (#2374) --- src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md index ce1cb42da1..50a8581489 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported. ([#2150](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2150)) From e5b1a17b8bbcf8354011797b5f12d073fc140102 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:16:55 -0600 Subject: [PATCH 1449/1499] [release] Prepare release Instrumentation.Process-1.10.0-beta.1 (#2376) --- src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md index 5d53d76d65..292d6060c0 100644 --- a/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) From 61c117ceccf4af016bbfee04591c2438c9eba6ba Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:19:45 -0600 Subject: [PATCH 1450/1499] [release] Prepare release Instrumentation.Quartz-1.10.0-beta.1 (#2378) --- src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md index 92b0d94fe4..f047a5fe0e 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) From feeffa27becd9d165df645417479275a3366b58e Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:25:57 -0600 Subject: [PATCH 1451/1499] [release] Prepare release Instrumentation.SqlClient-1.10.0-beta.1 (#2380) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr Kiełkowicz --- src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 8a45888983..b5181622f8 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported. ([#2159](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2159)) @@ -52,11 +56,13 @@ ([#2277](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2277)) * **Breaking change**: The `SetDbStatementForStoredProcedure` option has been removed. - ([#TBD](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/TBD)) + ([#2284](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2284)) + * Add support for metric `db.client.operation.duration` from [new database semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-metrics.md#metric-dbclientoperationduration) on .NET 8+. ([#2309](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2309)) + * Add support for metric `db.client.operation.duration` from [new database semantic conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-metrics.md#metric-dbclientoperationduration) on .NET Framework. From f0a032ca07b606899eab13fcf242cfe6671ed6a8 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:28:20 -0600 Subject: [PATCH 1452/1499] [release] Prepare release Instrumentation.StackExchangeRedis-1.10.0-beta.1 (#2382) --- .../CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md index e73e8e34e4..37bc0bd189 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2160](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2160)) From 05e64b20ed1a7459c5309b999b23784a6a6a4c11 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:30:56 -0600 Subject: [PATCH 1453/1499] [release] Prepare release Instrumentation.Wcf-1.10.0-beta.1 (#2384) --- src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md index 60993f36e1..0b770b5f44 100644 --- a/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Wcf/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2263](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2263)) From 661c98a5470ab2bde2fe2d0b0146fc3a40218291 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:34:54 -0600 Subject: [PATCH 1454/1499] [release] Prepare release Resources.Azure-1.10.0-beta.1 (#2388) --- src/OpenTelemetry.Resources.Azure/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md index 882b013ea0..e9a1801512 100644 --- a/src/OpenTelemetry.Resources.Azure/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Azure/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2165](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2165)) From 729546ba11dd00637d50df7148e0c64989280d54 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:37:28 -0600 Subject: [PATCH 1455/1499] [release] Prepare release Resources.Container-1.10.0-beta.1 (#2390) --- src/OpenTelemetry.Resources.Container/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Container/CHANGELOG.md b/src/OpenTelemetry.Resources.Container/CHANGELOG.md index 47ef54a9cf..a8ebb3af83 100644 --- a/src/OpenTelemetry.Resources.Container/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Container/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8/.NET Standard 2.0 targets. ([#2166](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2166)) From 0d0db1b0fb5beeadb17d77c0bb781b1ee43f7f7a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:16:58 -0600 Subject: [PATCH 1456/1499] [release] Prepare release Resources.Host-1.10.0-beta.1 (#2392) --- src/OpenTelemetry.Resources.Host/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Host/CHANGELOG.md b/src/OpenTelemetry.Resources.Host/CHANGELOG.md index 8109eb733d..f18b573360 100644 --- a/src/OpenTelemetry.Resources.Host/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Host/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8/.NET Standard 2.0 targets. ([#2168](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2168)) From 9875d90a3e53ddf802dd059abf891b033f3304b9 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:19:41 -0600 Subject: [PATCH 1457/1499] [release] Prepare release Resources.OperatingSystem-1.10.0-beta.1 (#2394) --- src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md index 0cc52c09fe..5f8aafbaf4 100644 --- a/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.OperatingSystem/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8/.NET Standard 2.0 targets. ([#2169](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2169)) From 94af78ebb2177c168f4a89bb7bdddfd68d874553 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:22:35 -0600 Subject: [PATCH 1458/1499] [release] Prepare release Resources.Process-1.10.0-beta.1 (#2396) --- src/OpenTelemetry.Resources.Process/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.Process/CHANGELOG.md b/src/OpenTelemetry.Resources.Process/CHANGELOG.md index ef692be8cd..e28f61246d 100644 --- a/src/OpenTelemetry.Resources.Process/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.Process/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8/.NET Standard 2.0 targets. ([#2170](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2170)) From e4f3b05814f127a5078abcdc0fcb141425d0b7d5 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:26:22 -0600 Subject: [PATCH 1459/1499] [release] Prepare release Resources.ProcessRuntime-1.10.0-beta.1 (#2398) --- src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md index aed621d76c..eac054449e 100644 --- a/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md +++ b/src/OpenTelemetry.Resources.ProcessRuntime/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.1 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8/.NET Standard 2.0 targets. ([#2171](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2171)) From 3964894633756c01b9d5e4fb5aa578f75cd37553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 9 Dec 2024 08:55:34 +0100 Subject: [PATCH 1460/1499] [Instrumentation.AspNetCore] metrics - cleanup code after dropping support for .NET6 (#2360) --- ...mentationMeterProviderBuilderExtensions.cs | 28 +--- .../AspNetCoreMetrics.cs | 41 ------ .../CHANGELOG.md | 3 +- .../Implementation/HttpInMetricsListener.cs | 132 ------------------ .../README.md | 31 ---- .../MetricTests.cs | 11 -- 6 files changed, 8 insertions(+), 238 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs delete mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs index 0815bef20e..9e8f3d9919 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs @@ -1,10 +1,6 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if !NET -using OpenTelemetry.Instrumentation.AspNetCore; -using OpenTelemetry.Instrumentation.AspNetCore.Implementation; -#endif using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics; @@ -22,27 +18,15 @@ public static class AspNetCoreInstrumentationMeterProviderBuilderExtensions public static MeterProviderBuilder AddAspNetCoreInstrumentation( this MeterProviderBuilder builder) { - Guard.ThrowIfNull(builder); - -#if NET - return builder.ConfigureMeters(); -#else - // Note: Warm-up the status code and method mapping. - _ = TelemetryHelper.BoxedStatusCodes; - _ = TelemetryHelper.RequestDataHelper; - - builder.AddMeter(HttpInMetricsListener.InstrumentationName); +#if NETSTANDARD2_0_OR_GREATER + if (Environment.Version.Major < 8) + { + throw new PlatformNotSupportedException("Metrics instrumentation is not supported when executing on .NET 7 and lower."); + } -#pragma warning disable CA2000 - builder.AddInstrumentation(new AspNetCoreMetrics()); -#pragma warning restore CA2000 - - return builder; #endif - } + Guard.ThrowIfNull(builder); - internal static MeterProviderBuilder ConfigureMeters(this MeterProviderBuilder builder) - { return builder .AddMeter("Microsoft.AspNetCore.Hosting") .AddMeter("Microsoft.AspNetCore.Server.Kestrel") diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs deleted file mode 100644 index 877f5ece38..0000000000 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#if !NET -using OpenTelemetry.Instrumentation.AspNetCore.Implementation; - -namespace OpenTelemetry.Instrumentation.AspNetCore; - -/// -/// Asp.Net Core Requests instrumentation. -/// -internal sealed class AspNetCoreMetrics : IDisposable -{ - private static readonly HashSet DiagnosticSourceEvents = - [ - "Microsoft.AspNetCore.Hosting.HttpRequestIn", - "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", - "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", - "Microsoft.AspNetCore.Diagnostics.UnhandledException", - "Microsoft.AspNetCore.Hosting.UnhandledException" - ]; - - private readonly Func isEnabled = (eventName, _, _) - => DiagnosticSourceEvents.Contains(eventName); - - private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; - - internal AspNetCoreMetrics() - { - var metricsListener = new HttpInMetricsListener("Microsoft.AspNetCore"); - this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(metricsListener, this.isEnabled, AspNetCoreInstrumentationEventSource.Log.UnknownErrorProcessingEvent); - this.diagnosticSourceSubscriber.Subscribe(); - } - - /// - public void Dispose() - { - this.diagnosticSourceSubscriber?.Dispose(); - } -} -#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index eb7c0d907b..477cb8e52e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -3,7 +3,8 @@ ## Unreleased * Drop support for .NET 6 as this target is no longer supported. - ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138)) + ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138), + ([#2360](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2360)) * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs deleted file mode 100644 index c9040d0248..0000000000 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Diagnostics.Metrics; -using System.Reflection; -using Microsoft.AspNetCore.Http; -#if NET -using Microsoft.AspNetCore.Diagnostics; -using Microsoft.AspNetCore.Routing; -#endif -using OpenTelemetry.Internal; -using OpenTelemetry.Trace; - -namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; - -internal sealed class HttpInMetricsListener : ListenerHandler -{ - internal const string HttpServerRequestDurationMetricName = "http.server.request.duration"; - - internal const string OnUnhandledHostingExceptionEvent = "Microsoft.AspNetCore.Hosting.UnhandledException"; - internal const string OnUnhandledDiagnosticsExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException"; - - internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); - internal static readonly string InstrumentationName = AssemblyName.Name!; - internal static readonly string InstrumentationVersion = AssemblyName.Version!.ToString(); - internal static readonly Meter Meter = new(InstrumentationName, InstrumentationVersion); - - private const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; - - private static readonly PropertyFetcher ExceptionPropertyFetcher = new("Exception"); - private static readonly PropertyFetcher HttpContextPropertyFetcher = new("HttpContext"); - private static readonly object ErrorTypeHttpContextItemsKey = new(); - - private static readonly Histogram HttpServerRequestDuration = Meter.CreateHistogram(HttpServerRequestDurationMetricName, "s", "Duration of HTTP server requests."); - - internal HttpInMetricsListener(string name) - : base(name) - { - } - - public static void OnExceptionEventWritten(string name, object? payload) - { - // We need to use reflection here as the payload type is not a defined public type. - if (!TryFetchException(payload, out var exc) || !TryFetchHttpContext(payload, out var ctx)) - { - AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnExceptionEventWritten), HttpServerRequestDurationMetricName); - return; - } - - ctx.Items.Add(ErrorTypeHttpContextItemsKey, exc.GetType().FullName); - - // See https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L252 - // and https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddlewareImpl.cs#L174 - // this makes sure that top-level properties on the payload object are always preserved. -#if NET - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] -#endif - static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) - { - return ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; - } -#if NET - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] -#endif - static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? ctx) - { - return HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; - } - } - - public static void OnStopEventWritten(string name, object? payload) - { - if (payload is not HttpContext context) - { - AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnStopEventWritten), HttpServerRequestDurationMetricName); - return; - } - - TagList tags = default; - - // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md - tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(context.Request.Protocol))); - tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme)); - tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(context.Response.StatusCode))); - - var httpMethod = TelemetryHelper.RequestDataHelper.GetNormalizedHttpMethod(context.Request.Method); - tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); - -#if NET - // Check the exception handler feature first in case the endpoint was overwritten - var route = (context.Features.Get()?.Endpoint as RouteEndpoint ?? - context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; - if (!string.IsNullOrEmpty(route)) - { - tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRoute, route)); - } -#endif - if (context.Items.TryGetValue(ErrorTypeHttpContextItemsKey, out var errorType)) - { - tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, errorType)); - } - - // We are relying here on ASP.NET Core to set duration before writing the stop event. - // https://github.com/dotnet/aspnetcore/blob/d6fa351048617ae1c8b47493ba1abbe94c3a24cf/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L449 - // TODO: Follow up with .NET team if we can continue to rely on this behavior. - HttpServerRequestDuration.Record(Activity.Current!.Duration.TotalSeconds, tags); - } - - public override void OnEventWritten(string name, object? payload) - { - switch (name) - { - case OnUnhandledDiagnosticsExceptionEvent: - case OnUnhandledHostingExceptionEvent: - { - OnExceptionEventWritten(name, payload); - } - - break; - case OnStopEvent: - { - OnStopEventWritten(name, payload); - } - - break; - default: - break; - } - } -} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index 12a76ed607..74938b4592 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -113,29 +113,8 @@ public void ConfigureServices(IServiceCollection services) } ``` -Following list of attributes are added by default on -`http.server.request.duration` metric. See -[http-metrics](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http/http-metrics.md) -for more details about each individual attribute. `.NET8.0` and above supports -additional metrics, see [list of metrics produced](#list-of-metrics-produced) for -more details. - -* `error.type` -* `http.response.status_code` -* `http.request.method` -* `http.route` -* `network.protocol.version` -* `url.scheme` - #### List of metrics produced -When the application targets `.NET6.0` or `.NET7.0`, the instrumentation emits -the following metric: - -| Name | Details | -|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| -| `http.server.request.duration` | [Specification](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md#metric-httpserverrequestduration) | - Starting from `.NET8.0`, metrics instrumentation is natively implemented, and the ASP.NET Core library has incorporated support for [built-in metrics](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-aspnetcore) @@ -164,16 +143,6 @@ to achieve this. > There is no difference in features or emitted metrics when enabling metrics using `AddMeter()` or `AddAspNetCoreInstrumentation()` on `.NET8.0` and newer versions. - -> [!NOTE] -> The `http.server.request.duration` metric is emitted in `seconds` as per the -semantic convention. While the convention [recommends using custom histogram -buckets](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md) -, this feature is not yet available via .NET Metrics API. A -[workaround](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4820) -has been included in OTel SDK starting version `1.6.0` which applies recommended -buckets by default for `http.server.request.duration`. This applies to all -targeted frameworks. ## Advanced configuration diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index c3f80a9cee..804332f450 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -1,22 +1,13 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -#if NET using System.Threading.RateLimiting; using Microsoft.AspNetCore.Builder; -#endif using Microsoft.AspNetCore.Hosting; -#if NET using Microsoft.AspNetCore.Http; -#endif using Microsoft.AspNetCore.Mvc.Testing; -#if NET using Microsoft.AspNetCore.RateLimiting; -#endif -#if NET using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -#endif using Microsoft.Extensions.Logging; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; @@ -38,7 +29,6 @@ public void AddAspNetCoreInstrumentation_BadArgs() Assert.Throws(builder!.AddAspNetCoreInstrumentation); } -#if NET [Fact] public async Task ValidateNet8MetricsAsync() { @@ -178,7 +168,6 @@ static string GetTicks() await app.DisposeAsync(); } -#endif [Theory] [InlineData("/api/values/2", "api/Values/{id}", null, 200)] From bef4fbe7dc544e1e21b289fa6337c06217d0c930 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 01:58:02 -0600 Subject: [PATCH 1461/1499] [release] Prepare release Instrumentation.AspNetCore-1.10.0 (#2400) --- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 477cb8e52e..30d7ea82ae 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0 + +Released 2024-Dec-09 + * Drop support for .NET 6 as this target is no longer supported. ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138), ([#2360](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2360)) From 5811e1dee2322faae4409cada06241d04b96cca3 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Mon, 9 Dec 2024 02:22:22 -0600 Subject: [PATCH 1462/1499] [release] Instrumentation.AspNetCore- stable release 1.10.0 updates (#2401) --- .../OpenTelemetry.Instrumentation.AspNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index 24409c62c0..c8e78c28eb 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -6,7 +6,7 @@ ASP.NET Core instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNetCore Instrumentation.AspNetCore- - 1.9.0 + 1.10.0 From 92b48e14b77faf989b8c8ec55261da44786b6946 Mon Sep 17 00:00:00 2001 From: Mohamed Asaker Date: Mon, 9 Dec 2024 11:35:29 -0800 Subject: [PATCH 1463/1499] Added changes to AWSXRayPropagator (#2359) --- .../Trace/AWSXRayPropagator.cs | 31 ++++++++++ .../Trace/AWSXRayPropagatorTests.cs | 58 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs index bad3b9a9d6..2a8d71b6f2 100644 --- a/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs +++ b/src/OpenTelemetry.Extensions.AWS/Trace/AWSXRayPropagator.cs @@ -1,6 +1,9 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if NETFRAMEWORK +using System.Net; +#endif using System.Diagnostics; using System.Globalization; using System.Numerics; @@ -99,6 +102,34 @@ public override void Inject(PropagationContext context, T carrier, Action HeaderValueSetter = (request, name, value) => request.Headers.Add(name, value); +#endif + private readonly AWSXRayPropagator awsXRayPropagator = new(); +#if !NETFRAMEWORK + private static Action HeaderValueSetter => (request, name, value) => + { + request.Headers.Remove(name); + request.Headers.Add(name, value); + }; +#endif + [Fact] public void TestInjectTraceHeader() { @@ -56,6 +71,49 @@ public void TestInjectTraceHeaderNotSampled() Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0", carrier[AWSXRayTraceHeaderKey]); } + [Fact] + public void TestInjectTraceHeaderAlreadyExists() + { + var traceIdHeader = "Root=1-00000-00000000000000000;Parent=123456789;Sampled=0"; + +#if !NETFRAMEWORK + var carrier = new HttpRequestMessage(); +#else + var carrier = (HttpWebRequest)WebRequest.Create(new Uri("http://www.google.com/")); +#endif + carrier.Headers.Add(AWSXRayTraceHeaderKey, traceIdHeader); + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.None; + var activityContext = new ActivityContext(traceId, parentId, traceFlags); + this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, HeaderValueSetter); + +#if !NETFRAMEWORK + Assert.True(carrier.Headers.Contains(AWSXRayTraceHeaderKey)); + Assert.Equal(traceIdHeader, carrier.Headers.GetValues(AWSXRayTraceHeaderKey).FirstOrDefault()); +#else + Assert.Equal(traceIdHeader, carrier.Headers.Get(AWSXRayTraceHeaderKey)); +#endif + } + + [Fact] + public void TestInjectTraceHeaderAlreadyExistsButNotHttpRequestMessage() + { + var traceIdHeader = "Root=1-00000-00000000000000000;Parent=123456789;Sampled=0"; + var carrier = new Dictionary() + { + { AWSXRayTraceHeaderKey, traceIdHeader }, + }; + var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); + var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); + var traceFlags = ActivityTraceFlags.None; + var activityContext = new ActivityContext(traceId, parentId, traceFlags); + this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter); + + Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey)); + Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0", carrier[AWSXRayTraceHeaderKey]); + } + [Fact] public void TestExtractTraceHeader() { From efe6eda4375ebf64cb652bf18669d6cd53f8ab11 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:59:56 -0800 Subject: [PATCH 1464/1499] [aspnetcore] Restore metrics instrumentation in netstandard builds (#2403) --- ...mentationMeterProviderBuilderExtensions.cs | 28 +++- .../AspNetCoreMetrics.cs | 41 ++++++ .../CHANGELOG.md | 7 +- .../Implementation/HttpInMetricsListener.cs | 132 ++++++++++++++++++ .../README.md | 31 ++++ .../MetricTests.cs | 11 ++ 6 files changed, 242 insertions(+), 8 deletions(-) create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs create mode 100644 src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs index 9e8f3d9919..0815bef20e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreInstrumentationMeterProviderBuilderExtensions.cs @@ -1,6 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if !NET +using OpenTelemetry.Instrumentation.AspNetCore; +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; +#endif using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics; @@ -18,15 +22,27 @@ public static class AspNetCoreInstrumentationMeterProviderBuilderExtensions public static MeterProviderBuilder AddAspNetCoreInstrumentation( this MeterProviderBuilder builder) { -#if NETSTANDARD2_0_OR_GREATER - if (Environment.Version.Major < 8) - { - throw new PlatformNotSupportedException("Metrics instrumentation is not supported when executing on .NET 7 and lower."); - } + Guard.ThrowIfNull(builder); + +#if NET + return builder.ConfigureMeters(); +#else + // Note: Warm-up the status code and method mapping. + _ = TelemetryHelper.BoxedStatusCodes; + _ = TelemetryHelper.RequestDataHelper; + + builder.AddMeter(HttpInMetricsListener.InstrumentationName); +#pragma warning disable CA2000 + builder.AddInstrumentation(new AspNetCoreMetrics()); +#pragma warning restore CA2000 + + return builder; #endif - Guard.ThrowIfNull(builder); + } + internal static MeterProviderBuilder ConfigureMeters(this MeterProviderBuilder builder) + { return builder .AddMeter("Microsoft.AspNetCore.Hosting") .AddMeter("Microsoft.AspNetCore.Server.Kestrel") diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs new file mode 100644 index 0000000000..877f5ece38 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/AspNetCoreMetrics.cs @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#if !NET +using OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +namespace OpenTelemetry.Instrumentation.AspNetCore; + +/// +/// Asp.Net Core Requests instrumentation. +/// +internal sealed class AspNetCoreMetrics : IDisposable +{ + private static readonly HashSet DiagnosticSourceEvents = + [ + "Microsoft.AspNetCore.Hosting.HttpRequestIn", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Start", + "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop", + "Microsoft.AspNetCore.Diagnostics.UnhandledException", + "Microsoft.AspNetCore.Hosting.UnhandledException" + ]; + + private readonly Func isEnabled = (eventName, _, _) + => DiagnosticSourceEvents.Contains(eventName); + + private readonly DiagnosticSourceSubscriber diagnosticSourceSubscriber; + + internal AspNetCoreMetrics() + { + var metricsListener = new HttpInMetricsListener("Microsoft.AspNetCore"); + this.diagnosticSourceSubscriber = new DiagnosticSourceSubscriber(metricsListener, this.isEnabled, AspNetCoreInstrumentationEventSource.Log.UnknownErrorProcessingEvent); + this.diagnosticSourceSubscriber.Subscribe(); + } + + /// + public void Dispose() + { + this.diagnosticSourceSubscriber?.Dispose(); + } +} +#endif diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 30d7ea82ae..7ac9ef4851 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,13 +2,16 @@ ## Unreleased +* Metric support for the .NET Standard target was removed by mistake in 1.10.0. + This functionality has been restored. + ([#2403](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2403)) + ## 1.10.0 Released 2024-Dec-09 * Drop support for .NET 6 as this target is no longer supported. - ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138), - ([#2360](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2360)) + ([#2138](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2138)) * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs new file mode 100644 index 0000000000..c9040d0248 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -0,0 +1,132 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Metrics; +using System.Reflection; +using Microsoft.AspNetCore.Http; +#if NET +using Microsoft.AspNetCore.Diagnostics; +using Microsoft.AspNetCore.Routing; +#endif +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation; + +internal sealed class HttpInMetricsListener : ListenerHandler +{ + internal const string HttpServerRequestDurationMetricName = "http.server.request.duration"; + + internal const string OnUnhandledHostingExceptionEvent = "Microsoft.AspNetCore.Hosting.UnhandledException"; + internal const string OnUnhandledDiagnosticsExceptionEvent = "Microsoft.AspNetCore.Diagnostics.UnhandledException"; + + internal static readonly AssemblyName AssemblyName = typeof(HttpInListener).Assembly.GetName(); + internal static readonly string InstrumentationName = AssemblyName.Name!; + internal static readonly string InstrumentationVersion = AssemblyName.Version!.ToString(); + internal static readonly Meter Meter = new(InstrumentationName, InstrumentationVersion); + + private const string OnStopEvent = "Microsoft.AspNetCore.Hosting.HttpRequestIn.Stop"; + + private static readonly PropertyFetcher ExceptionPropertyFetcher = new("Exception"); + private static readonly PropertyFetcher HttpContextPropertyFetcher = new("HttpContext"); + private static readonly object ErrorTypeHttpContextItemsKey = new(); + + private static readonly Histogram HttpServerRequestDuration = Meter.CreateHistogram(HttpServerRequestDurationMetricName, "s", "Duration of HTTP server requests."); + + internal HttpInMetricsListener(string name) + : base(name) + { + } + + public static void OnExceptionEventWritten(string name, object? payload) + { + // We need to use reflection here as the payload type is not a defined public type. + if (!TryFetchException(payload, out var exc) || !TryFetchHttpContext(payload, out var ctx)) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnExceptionEventWritten), HttpServerRequestDurationMetricName); + return; + } + + ctx.Items.Add(ErrorTypeHttpContextItemsKey, exc.GetType().FullName); + + // See https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L252 + // and https://github.com/dotnet/aspnetcore/blob/690d78279e940d267669f825aa6627b0d731f64c/src/Middleware/Diagnostics/src/DeveloperExceptionPage/DeveloperExceptionPageMiddlewareImpl.cs#L174 + // this makes sure that top-level properties on the payload object are always preserved. +#if NET + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] +#endif + static bool TryFetchException(object? payload, [NotNullWhen(true)] out Exception? exc) + { + return ExceptionPropertyFetcher.TryFetch(payload, out exc) && exc != null; + } +#if NET + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The ASP.NET Core framework guarantees that top level properties are preserved")] +#endif + static bool TryFetchHttpContext(object? payload, [NotNullWhen(true)] out HttpContext? ctx) + { + return HttpContextPropertyFetcher.TryFetch(payload, out ctx) && ctx != null; + } + } + + public static void OnStopEventWritten(string name, object? payload) + { + if (payload is not HttpContext context) + { + AspNetCoreInstrumentationEventSource.Log.NullPayload(nameof(HttpInMetricsListener), nameof(OnStopEventWritten), HttpServerRequestDurationMetricName); + return; + } + + TagList tags = default; + + // see the spec https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md + tags.Add(new KeyValuePair(SemanticConventions.AttributeNetworkProtocolVersion, RequestDataHelper.GetHttpProtocolVersion(context.Request.Protocol))); + tags.Add(new KeyValuePair(SemanticConventions.AttributeUrlScheme, context.Request.Scheme)); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpResponseStatusCode, TelemetryHelper.GetBoxedStatusCode(context.Response.StatusCode))); + + var httpMethod = TelemetryHelper.RequestDataHelper.GetNormalizedHttpMethod(context.Request.Method); + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRequestMethod, httpMethod)); + +#if NET + // Check the exception handler feature first in case the endpoint was overwritten + var route = (context.Features.Get()?.Endpoint as RouteEndpoint ?? + context.GetEndpoint() as RouteEndpoint)?.RoutePattern.RawText; + if (!string.IsNullOrEmpty(route)) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeHttpRoute, route)); + } +#endif + if (context.Items.TryGetValue(ErrorTypeHttpContextItemsKey, out var errorType)) + { + tags.Add(new KeyValuePair(SemanticConventions.AttributeErrorType, errorType)); + } + + // We are relying here on ASP.NET Core to set duration before writing the stop event. + // https://github.com/dotnet/aspnetcore/blob/d6fa351048617ae1c8b47493ba1abbe94c3a24cf/src/Hosting/Hosting/src/Internal/HostingApplicationDiagnostics.cs#L449 + // TODO: Follow up with .NET team if we can continue to rely on this behavior. + HttpServerRequestDuration.Record(Activity.Current!.Duration.TotalSeconds, tags); + } + + public override void OnEventWritten(string name, object? payload) + { + switch (name) + { + case OnUnhandledDiagnosticsExceptionEvent: + case OnUnhandledHostingExceptionEvent: + { + OnExceptionEventWritten(name, payload); + } + + break; + case OnStopEvent: + { + OnStopEventWritten(name, payload); + } + + break; + default: + break; + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index 74938b4592..12a76ed607 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -113,8 +113,29 @@ public void ConfigureServices(IServiceCollection services) } ``` +Following list of attributes are added by default on +`http.server.request.duration` metric. See +[http-metrics](https://github.com/open-telemetry/semantic-conventions/tree/v1.23.0/docs/http/http-metrics.md) +for more details about each individual attribute. `.NET8.0` and above supports +additional metrics, see [list of metrics produced](#list-of-metrics-produced) for +more details. + +* `error.type` +* `http.response.status_code` +* `http.request.method` +* `http.route` +* `network.protocol.version` +* `url.scheme` + #### List of metrics produced +When the application targets `.NET6.0` or `.NET7.0`, the instrumentation emits +the following metric: + +| Name | Details | +|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| `http.server.request.duration` | [Specification](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md#metric-httpserverrequestduration) | + Starting from `.NET8.0`, metrics instrumentation is natively implemented, and the ASP.NET Core library has incorporated support for [built-in metrics](https://learn.microsoft.com/dotnet/core/diagnostics/built-in-metrics-aspnetcore) @@ -143,6 +164,16 @@ to achieve this. > There is no difference in features or emitted metrics when enabling metrics using `AddMeter()` or `AddAspNetCoreInstrumentation()` on `.NET8.0` and newer versions. + +> [!NOTE] +> The `http.server.request.duration` metric is emitted in `seconds` as per the +semantic convention. While the convention [recommends using custom histogram +buckets](https://github.com/open-telemetry/semantic-conventions/blob/release/v1.23.x/docs/http/http-metrics.md) +, this feature is not yet available via .NET Metrics API. A +[workaround](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4820) +has been included in OTel SDK starting version `1.6.0` which applies recommended +buckets by default for `http.server.request.duration`. This applies to all +targeted frameworks. ## Advanced configuration diff --git a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs index 804332f450..c3f80a9cee 100644 --- a/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs +++ b/test/OpenTelemetry.Instrumentation.AspNetCore.Tests/MetricTests.cs @@ -1,13 +1,22 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if NET using System.Threading.RateLimiting; using Microsoft.AspNetCore.Builder; +#endif using Microsoft.AspNetCore.Hosting; +#if NET using Microsoft.AspNetCore.Http; +#endif using Microsoft.AspNetCore.Mvc.Testing; +#if NET using Microsoft.AspNetCore.RateLimiting; +#endif +#if NET using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +#endif using Microsoft.Extensions.Logging; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; @@ -29,6 +38,7 @@ public void AddAspNetCoreInstrumentation_BadArgs() Assert.Throws(builder!.AddAspNetCoreInstrumentation); } +#if NET [Fact] public async Task ValidateNet8MetricsAsync() { @@ -168,6 +178,7 @@ static string GetTicks() await app.DisposeAsync(); } +#endif [Theory] [InlineData("/api/values/2", "api/Values/{id}", null, 200)] From 1fc2dba0720b8c3016f87776b23d702291a341fc Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Tue, 10 Dec 2024 17:48:28 -0600 Subject: [PATCH 1465/1499] [release] Prepare release Instrumentation.AspNetCore-1.10.1 (#2406) --- src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 7ac9ef4851..2bb349e1fc 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.1 + +Released 2024-Dec-10 + * Metric support for the .NET Standard target was removed by mistake in 1.10.0. This functionality has been restored. ([#2403](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2403)) From ce419ab69909b7c15d5a4adce693b409a27afe8a Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:19:05 -0600 Subject: [PATCH 1466/1499] [release] Instrumentation.AspNetCore- stable release 1.10.1 updates (#2407) --- .../OpenTelemetry.Instrumentation.AspNetCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj index c8e78c28eb..83e13b0762 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/OpenTelemetry.Instrumentation.AspNetCore.csproj @@ -6,7 +6,7 @@ ASP.NET Core instrumentation for OpenTelemetry .NET $(PackageTags);distributed-tracing;AspNetCore Instrumentation.AspNetCore- - 1.10.0 + 1.10.1 From 01fe660f7f8496b81fb466fdc2af3d1a214f109b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Wed, 11 Dec 2024 23:50:27 +0100 Subject: [PATCH 1467/1499] [Instrumentation.SqlClient] Metrics documentation (#2404) Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> --- .../README.md | 2 +- .../README.md | 49 +++++++++++++++++-- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 403a4e78dc..4e9c7b5447 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -127,7 +127,7 @@ public class WebApiApplication : HttpApplication #### List of metrics produced The instrumentation is implemented based on [metrics semantic -conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration). +conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/http/http-metrics.md#metric-httpserverrequestduration). Currently, the instrumentation supports the following metric. | Name | Instrument Type | Unit | Description | diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index 71cd7dd3eb..6d2fa60f8e 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -49,10 +49,12 @@ dotnet add package --prerelease OpenTelemetry.Instrumentation.SqlClient SqlClient instrumentation must be enabled at application startup. -The following example demonstrates adding SqlClient instrumentation to a console -application. This example also sets up the OpenTelemetry Console exporter, which -requires adding the package -[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +#### Traces + +The following example demonstrates adding SqlClient traces instrumentation +to a console application. This example also sets up the OpenTelemetry Console +exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) to the application. ```csharp @@ -70,13 +72,50 @@ public class Program } ``` +#### Metrics + +The following example demonstrates adding SqlClient metrics instrumentation +to a console application. This example also sets up the OpenTelemetry Console +exporter, which requires adding the package +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) +to the application. + +```csharp +using OpenTelemetry.Metrics; + +public class Program +{ + public static void Main(string[] args) + { + using var tracerProvider = Sdk.CreateMeterProviderBuilder() + .AddSqlClientInstrumentation() + .AddConsoleExporter() + .Build(); + } +} +``` + +##### List of metrics produced + +The instrumentation is implemented based on [metrics semantic +conventions](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/database/database-metrics.md#database-operation). +Currently, the instrumentation supports the following metric. + +| Name | Instrument Type | Unit | Description | +|-------|-----------------|------|-------------| +| `db.client.operation.duration` | Histogram | `s` | Duration of database client operations. | + +#### ASP.NET Core + For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for [OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). +#### ASP.NET + For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to the documentation for -[OpenTelemetry.Instrumentation.AspNet](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md). +[OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). ## Advanced configuration From b7c0f03458127fda13b09d1145100e6c10a733b4 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 11 Dec 2024 23:32:46 -0600 Subject: [PATCH 1468/1499] [release] Prepare release Sampler.AWS-0.1.0-alpha.3 (#2412) --- src/OpenTelemetry.Sampler.AWS/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md index 6a78f967c5..2ae442c3c6 100644 --- a/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Sampler.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 0.1.0-alpha.3 + +Released 2024-Dec-12 + * Drop support for .NET 6 as this target is no longer supported and add .NET 8 target. ([#2172](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2172)) From e9834b35c5aecbb552e5a98a954e855eecc401ad Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Wed, 11 Dec 2024 23:35:01 -0600 Subject: [PATCH 1469/1499] [release] Prepare release Instrumentation.AWS-1.10.0-beta.2 (#2411) --- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md | 4 ++++ src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index b46f03eb53..057affda10 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.2 + +Released 2024-Dec-12 + ## 1.10.0-beta.1 Released 2024-Nov-23 diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index a0e7c5398e..b4affacd6c 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.2 + +Released 2024-Dec-12 + * Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) API instead of the deprecated OpenTelemetry API package extension when setting span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). diff --git a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md index f57beb4e4d..0c713f611b 100644 --- a/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWSLambda/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## 1.10.0-beta.2 + +Released 2024-Dec-12 + * Trace instrumentation will now call the [Activity.SetStatus](https://learn.microsoft.com/dotnet/api/system.diagnostics.activity.setstatus) API instead of the deprecated OpenTelemetry API package extension when setting span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). From e3417bc2b87947113fc58204c4d3835c5fa2c557 Mon Sep 17 00:00:00 2001 From: OpenTelemetry Bot <107717825+opentelemetrybot@users.noreply.github.com> Date: Thu, 12 Dec 2024 00:00:43 -0600 Subject: [PATCH 1470/1499] [release] core-1.11.0-rc.1 release updates (#2415) --- build/Common.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Common.props b/build/Common.props index 4305b94351..8f9490f903 100644 --- a/build/Common.props +++ b/build/Common.props @@ -43,7 +43,7 @@ [8.0.0,9.0) [1.10.0-beta.1] [1.10.0,2.0) - [1.10.0-rc.1] + [1.11.0-rc.1] [2.6.122,3.0) [2.4.0,3.0) [3.16.0,4.0) From da7bb32601d0fee92c0cfb4dbcefc512d8715c79 Mon Sep 17 00:00:00 2001 From: Alan West <3676547+alanwest@users.noreply.github.com> Date: Wed, 11 Dec 2024 22:11:36 -0800 Subject: [PATCH 1471/1499] Remove EnableConnectionLevelAttributes option (#2414) --- .../.publicApi/PublicAPI.Unshipped.txt | 2 - .../CHANGELOG.md | 3 ++ .../Implementation/SqlActivitySourceHelper.cs | 2 +- .../README.md | 23 -------- .../SqlClientTraceInstrumentationOptions.cs | 20 ------- .../SqlClientTests.cs | 29 +++++----- .../SqlEventSourceTests.netfx.cs | 54 ++++++++----------- 7 files changed, 39 insertions(+), 94 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt index 2d3a76d224..3cd16fd49a 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/PublicAPI.Unshipped.txt @@ -1,7 +1,5 @@ #nullable enable OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions -OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.EnableConnectionLevelAttributes.get -> bool -OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.EnableConnectionLevelAttributes.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.get -> System.Action? OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions.Filter.get -> System.Func? diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index b5181622f8..16f15d141d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* **Breaking change** The `EnableConnectionLevelAttributes` option has been removed. + ([#2414](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2414)) + ## 1.10.0-beta.1 Released 2024-Dec-09 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index a176f338d7..a332be18b7 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -51,7 +51,7 @@ public static TagList GetTagListFromConnectionInfo(string? dataSource, string? d { SemanticConventions.AttributeDbSystem, MicrosoftSqlServerDatabaseSystemName }, }; - if (options.EnableConnectionLevelAttributes && dataSource != null) + if (dataSource != null) { var connectionDetails = SqlConnectionDetails.ParseFromDataSource(dataSource); diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index 6d2fa60f8e..96d36f896b 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -191,29 +191,6 @@ command names will ever be captured. When using the `Microsoft.Data.SqlClient` NuGet package (v1.1+) stored procedure command names, full query text, and other command text will be captured. -### EnableConnectionLevelAttributes - -> [!NOTE] -> EnableConnectionLevelAttributes is supported on all runtimes. - -By default, `EnabledConnectionLevelAttributes` is enabled. -When `EnabledConnectionLevelAttributes` is enabled, -the [`DataSource`](https://docs.microsoft.com/dotnet/api/system.data.common.dbconnection.datasource) -will be parsed and the server name or IP address will be sent as -the `server.address` attribute, the instance name will be sent as -the `db.mssql.instance_name` attribute, and the port will be sent as the -`server.port` attribute if it is not 1433 (the default port). - -The following example shows how to use `EnableConnectionLevelAttributes`. - -```csharp -using var tracerProvider = Sdk.CreateTracerProviderBuilder() - .AddSqlClientInstrumentation( - options => options.EnableConnectionLevelAttributes = true) - .AddConsoleExporter() - .Build(); -``` - ### Enrich > [!NOTE] diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs index 1aa0078e2f..06bee628eb 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientTraceInstrumentationOptions.cs @@ -63,26 +63,6 @@ internal SqlClientTraceInstrumentationOptions(IConfiguration configuration) /// public bool SetDbStatementForText { get; set; } - /// - /// Gets or sets a value indicating whether or not the should parse the DataSource on a - /// SqlConnection into server name, instance name, and/or port - /// connection-level attribute tags. Default value: . - /// - /// - /// - /// EnableConnectionLevelAttributes is supported on all runtimes. - /// - /// - /// If enabled, SqlConnection DataSource will be parsed and the server name will be sent as the - /// tag, - /// the instance name will be sent as the tag, - /// and the port will be sent as the tag if it is not 1433 (the default port). - /// - /// - public bool EnableConnectionLevelAttributes { get; set; } = true; - /// /// Gets or sets an action to enrich an with the /// raw SqlCommand object. diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index a253ef350d..c31cd18c40 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -185,27 +185,23 @@ public void SqlClientCallsAreCollectedSuccessfully( } [Theory] - [InlineData(true, "localhost", "localhost", null, null, null)] - [InlineData(true, "127.0.0.1,1433", null, "127.0.0.1", null, null)] - [InlineData(true, "127.0.0.1,1434", null, "127.0.0.1", null, 1434)] - [InlineData(true, "127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", 1818)] - [InlineData(false, "localhost", null, null, null, null)] + [InlineData("localhost", "localhost", null, null, null)] + [InlineData("127.0.0.1,1433", null, "127.0.0.1", null, null)] + [InlineData("127.0.0.1,1434", null, "127.0.0.1", null, 1434)] + [InlineData("127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", 1818)] // Test cases when EmitOldAttributes = false and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database) - [InlineData(true, "localhost", "localhost", null, null, null, false, true)] - [InlineData(true, "127.0.0.1,1433", null, "127.0.0.1", null, null, false, true)] - [InlineData(true, "127.0.0.1,1434", null, "127.0.0.1", null, 1434, false, true)] - [InlineData(true, "127.0.0.1\\instanceName, 1818", null, "127.0.0.1", null, 1818, false, true)] - [InlineData(false, "localhost", null, null, null, null, false, true)] + [InlineData("localhost", "localhost", null, null, null, false, true)] + [InlineData("127.0.0.1,1433", null, "127.0.0.1", null, null, false, true)] + [InlineData("127.0.0.1,1434", null, "127.0.0.1", null, 1434, false, true)] + [InlineData("127.0.0.1\\instanceName, 1818", null, "127.0.0.1", null, 1818, false, true)] // Test cases when EmitOldAttributes = true and EmitNewAttributes = true (i.e., OTEL_SEMCONV_STABILITY_OPT_IN=database/dup) - [InlineData(true, "localhost", "localhost", null, null, null, true, true)] - [InlineData(true, "127.0.0.1,1433", null, "127.0.0.1", null, null, true, true)] - [InlineData(true, "127.0.0.1,1434", null, "127.0.0.1", null, 1434, true, true)] - [InlineData(true, "127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", 1818, true, true)] - [InlineData(false, "localhost", null, null, null, null, true, true)] + [InlineData("localhost", "localhost", null, null, null, true, true)] + [InlineData("127.0.0.1,1433", null, "127.0.0.1", null, null, true, true)] + [InlineData("127.0.0.1,1434", null, "127.0.0.1", null, 1434, true, true)] + [InlineData("127.0.0.1\\instanceName, 1818", null, "127.0.0.1", "instanceName", 1818, true, true)] public void SqlClientAddsConnectionLevelAttributes( - bool enableConnectionLevelAttributes, string dataSource, string? expectedServerHostName, string? expectedServerIpAddress, @@ -216,7 +212,6 @@ public void SqlClientAddsConnectionLevelAttributes( { var options = new SqlClientTraceInstrumentationOptions() { - EnableConnectionLevelAttributes = enableConnectionLevelAttributes, EmitOldAttributes = emitOldAttributes, EmitNewAttributes = emitNewAttributes, }; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index 891395edd8..023b5bd67d 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -37,7 +37,6 @@ public static IEnumerable EventSourceFakeTestCases() from commandType in new[] { CommandType.StoredProcedure, CommandType.Text } from isFailure in bools from captureText in bools - from enableConnectionLevelAttributes in bools from emitOldAttributes in bools from emitNewAttributes in bools from tracingEnabled in bools @@ -56,7 +55,6 @@ where emitOldAttributes && emitNewAttributes captureText, isFailure, sqlExceptionNumber, - enableConnectionLevelAttributes, emitOldAttributes, emitNewAttributes, tracingEnabled, @@ -120,7 +118,6 @@ public void EventSourceFakeTests( bool captureText, bool isFailure = false, int sqlExceptionNumber = 0, - bool enableConnectionLevelAttributes = false, bool emitOldAttributes = true, bool emitNewAttributes = false, bool tracingEnabled = true, @@ -139,7 +136,6 @@ public void EventSourceFakeTests( .AddSqlClientInstrumentation(options => { options.SetDbStatementForText = captureText; - options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; options.EmitOldAttributes = emitOldAttributes; options.EmitNewAttributes = emitNewAttributes; }); @@ -187,7 +183,7 @@ public void EventSourceFakeTests( if (tracingEnabled) { activity = Assert.Single(activities); - VerifyActivityData(commandText, captureText, isFailure, dataSource, activity, enableConnectionLevelAttributes, emitOldAttributes, emitNewAttributes); + VerifyActivityData(commandText, captureText, isFailure, dataSource, activity, emitOldAttributes, emitNewAttributes); } var dbClientOperationDurationMetrics = metrics @@ -308,11 +304,10 @@ private static void VerifyActivityData( bool isFailure, string dataSource, Activity activity, - bool enableConnectionLevelAttributes = false, bool emitOldAttributes = true, bool emitNewAttributes = false) { - if (emitNewAttributes && enableConnectionLevelAttributes) + if (emitNewAttributes) { Assert.Equal("instanceName.master", activity.DisplayName); } @@ -324,32 +319,29 @@ private static void VerifyActivityData( Assert.Equal(ActivityKind.Client, activity.Kind); Assert.Equal(SqlActivitySourceHelper.MicrosoftSqlServerDatabaseSystemName, activity.GetTagValue(SemanticConventions.AttributeDbSystem)); - if (enableConnectionLevelAttributes) - { - var connectionDetails = SqlConnectionDetails.ParseFromDataSource(dataSource); + var connectionDetails = SqlConnectionDetails.ParseFromDataSource(dataSource); - if (!string.IsNullOrEmpty(connectionDetails.ServerHostName)) - { - Assert.Equal(connectionDetails.ServerHostName, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); - } - else - { - Assert.Equal(connectionDetails.ServerIpAddress, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); - } + if (!string.IsNullOrEmpty(connectionDetails.ServerHostName)) + { + Assert.Equal(connectionDetails.ServerHostName, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + } + else + { + Assert.Equal(connectionDetails.ServerIpAddress, activity.GetTagValue(SemanticConventions.AttributeServerAddress)); + } - if (emitOldAttributes && !string.IsNullOrEmpty(connectionDetails.InstanceName)) - { - Assert.Equal(connectionDetails.InstanceName, activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); - } - else - { - Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); - } + if (emitOldAttributes && !string.IsNullOrEmpty(connectionDetails.InstanceName)) + { + Assert.Equal(connectionDetails.InstanceName, activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); + } + else + { + Assert.Null(activity.GetTagValue(SemanticConventions.AttributeDbMsSqlInstanceName)); + } - if (connectionDetails.Port.HasValue) - { - Assert.Equal(connectionDetails.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort)); - } + if (connectionDetails.Port.HasValue) + { + Assert.Equal(connectionDetails.Port, activity.GetTagValue(SemanticConventions.AttributeServerPort)); } if (emitOldAttributes) @@ -359,7 +351,7 @@ private static void VerifyActivityData( if (emitNewAttributes) { - Assert.Equal(!enableConnectionLevelAttributes ? "master" : "instanceName.master", activity.GetTagValue(SemanticConventions.AttributeDbNamespace)); + Assert.Equal("instanceName.master", activity.GetTagValue(SemanticConventions.AttributeDbNamespace)); } if (captureText) From bbc53c56ce74d3a5a424d0a4417230a62a747eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Fri, 13 Dec 2024 19:00:26 +0100 Subject: [PATCH 1472/1499] [repo] Fix FindComponentOwners for latest project in component_owners (#2416) --- build/scripts/build.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/build.psm1 b/build/scripts/build.psm1 index 9b7d560b60..8ba3b4d055 100644 --- a/build/scripts/build.psm1 +++ b/build/scripts/build.psm1 @@ -125,7 +125,7 @@ function FindComponentOwners { { $projectName = [System.IO.Path]::GetFileName($projectDir) - $match = [regex]::Match($componentOwnersContent, "src\/$projectName\/:([\w\W\s]*?)src") + $match = [regex]::Match($componentOwnersContent, "src\/$projectName\/:([\w\W\s]*?)(src|test)") if ($match.Success -eq $true) { $matches = [regex]::Matches($match.Groups[1].Value, "-\s*(.*)") From c27013d128e1bdde7476f68d991d0f3257f999fa Mon Sep 17 00:00:00 2001 From: David Ashpole Date: Fri, 13 Dec 2024 18:37:07 -0500 Subject: [PATCH 1473/1499] [geneva] Update links to openmetrics to reference the v1.0.0 release in proto files (#2418) --- .../Proto/opentelemetry/proto/metrics/v1/metrics.proto | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/metrics/v1/metrics.proto b/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/metrics/v1/metrics.proto index da986dda18..b951b6d65b 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/metrics/v1/metrics.proto +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/Proto/opentelemetry/proto/metrics/v1/metrics.proto @@ -415,7 +415,7 @@ message HistogramDataPoint { // events, and is assumed to be monotonic over the values of these events. // Negative events *can* be recorded, but sum should not be filled out when // doing so. This is specifically to enforce compatibility w/ OpenMetrics, - // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram + // see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram optional double sum = 5; // bucket_counts is an optional field contains the count values of histogram @@ -494,7 +494,7 @@ message ExponentialHistogramDataPoint { // events, and is assumed to be monotonic over the values of these events. // Negative events *can* be recorded, but sum should not be filled out when // doing so. This is specifically to enforce compatibility w/ OpenMetrics, - // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#histogram + // see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#histogram optional double sum = 5; // scale describes the resolution of the histogram. Boundaries are @@ -607,7 +607,7 @@ message SummaryDataPoint { // events, and is assumed to be monotonic over the values of these events. // Negative events *can* be recorded, but sum should not be filled out when // doing so. This is specifically to enforce compatibility w/ OpenMetrics, - // see: https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#summary + // see: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#summary double sum = 5; // Represents the value at a given quantile of a distribution. From 34637cc9c3d5ac829a2efef19657500f3b563eed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:48:47 -0800 Subject: [PATCH 1474/1499] Bump DavidAnson/markdownlint-cli2-action from 16.0.0 to 18.0.0 (#2419) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .github/workflows/markdownlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 2ae611dae5..0f42b9c805 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -12,7 +12,7 @@ jobs: uses: actions/checkout@v4 - name: run markdownlint - uses: DavidAnson/markdownlint-cli2-action@v16.0.0 + uses: DavidAnson/markdownlint-cli2-action@v18.0.0 with: globs: | **/*.md From 1ca05685cbad63d3fa813b9cab49be341048e69e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:05:56 -0800 Subject: [PATCH 1475/1499] Bump codecov/codecov-action from 4 to 5 (#2420) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mikel Blanchard --- .github/workflows/Component.BuildTest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index dc571bb118..ee5132682a 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -127,7 +127,7 @@ jobs: - name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }} if: ${{ inputs.run-tests && hashFiles('./TestResults/Cobertura.xml') != '' }} - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 continue-on-error: true # Note: Don't fail for upload failures env: OS: ${{ matrix.os }} From 46e0c60035b239845f455697efd49720f70521f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Mon, 16 Dec 2024 21:47:10 +0100 Subject: [PATCH 1476/1499] [documentation] Fix links (#2423) --- CONTRIBUTING.md | 2 +- README.md | 2 +- src/OpenTelemetry.Exporter.InfluxDB/README.md | 2 +- src/OpenTelemetry.Extensions.AWS/CHANGELOG.md | 2 +- .../README.md | 14 +++----------- .../README.md | 14 +++++++------- .../README.md | 4 ++-- .../README.md | 13 ++++++------- .../README.md | 10 ++++------ .../README.md | 5 +++-- .../CHANGELOG.md | 2 +- .../README.md | 9 ++++----- .../CHANGELOG.md | 2 +- .../README.md | 18 +++++++++--------- .../README.md | 2 +- .../README.md | 10 +++++----- .../README.md | 4 ++-- .../README.md | 4 ++-- .../README.md | 2 +- .../README.md | 11 +++++------ .../README.md | 7 +++---- .../CHANGELOG.md | 2 +- 22 files changed, 64 insertions(+), 77 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 45df3c028c..de776feb7b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -168,7 +168,7 @@ A PR is considered to be **ready to merge** when: 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 +approvals and/or discussion, 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. diff --git a/README.md b/README.md index cab0fc0fdc..f553a9afb3 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ repository](https://github.com/open-telemetry/community/blob/main/guides/contrib * [Piotr Kiełkowicz](https://github.com/Kielek), Splunk *Find more about the maintainer role in [community -repository](h[ttps://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer)).* +repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).* ### Emeritus diff --git a/src/OpenTelemetry.Exporter.InfluxDB/README.md b/src/OpenTelemetry.Exporter.InfluxDB/README.md index 3dfbbb893f..590e11e4b9 100644 --- a/src/OpenTelemetry.Exporter.InfluxDB/README.md +++ b/src/OpenTelemetry.Exporter.InfluxDB/README.md @@ -26,7 +26,7 @@ dotnet add package --prerelease OpenTelemetry.Exporter.InfluxDB ### Step 2: Configure OpenTelemetry MeterProvider -* When using the [OpenTelemetry.Extensions.Hosting](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Extensions.Hosting/README.md) +* When using the [OpenTelemetry.Extensions.Hosting](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md) package on .NET 6.0+: ```csharp diff --git a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md index 057affda10..27d883bd1a 100644 --- a/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions.AWS/CHANGELOG.md @@ -103,4 +103,4 @@ SDK](https://www.nuget.org/packages/OpenTelemetry/). The AWSXRay extensions include plugin to generate X-Ray format trace-ids and a propagator to propagate the X-Ray trace header to downstream. For more details, please refer to the -[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Contrib.Extensions.AWSXRay/README.md) +[README](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Extensions.AWS/README.md) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/README.md b/src/OpenTelemetry.Instrumentation.AspNet/README.md index 4e9c7b5447..ce0fc4a879 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/README.md @@ -15,17 +15,9 @@ which instruments [ASP.NET](https://docs.microsoft.com/aspnet/overview) and collect metrics and traces about incoming web requests. > [!NOTE] -> This component is based on the OpenTelemetry semantic conventions for -[metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) -and -[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). -These conventions are -[Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), -and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). -Until a [stable -version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) -is released, there can be breaking changes. You can track the progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). +> This package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). +Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) +is released, there can be breaking changes. ## Steps to enable OpenTelemetry.Instrumentation.AspNet diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md index 12a76ed607..7ca1c3350e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/README.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/README.md @@ -41,7 +41,7 @@ ASP.NET Core instrumentation must be enabled at application startup. This is typically done in the `ConfigureServices` of your `Startup` class. Both examples below enables OpenTelemetry by calling `AddOpenTelemetry()` on `IServiceCollection`. This extension method requires adding the package -[`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md) +[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md) to the application. This ensures instrumentations are disposed when the host is shutdown. @@ -51,7 +51,7 @@ The following example demonstrates adding ASP.NET Core instrumentation with the extension method `WithTracing()` on `OpenTelemetryBuilder`. then extension method `AddAspNetCoreInstrumentation()` on `TracerProviderBuilder` to the application. This example also sets up the Console Exporter, -which requires adding the package [`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +which requires adding the package [`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) to the application. ```csharp @@ -97,7 +97,7 @@ The following example demonstrates adding ASP.NET Core instrumentation with the extension method `WithMetrics()` on `OpenTelemetryBuilder` then extension method `AddAspNetCoreInstrumentation()` on `MeterProviderBuilder` to the application. This example also sets up the Console Exporter, -which requires adding the package [`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +which requires adding the package [`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) to the application. ```csharp @@ -185,7 +185,7 @@ This instrumentation can be configured to change the default behavior by using // TODO: This section could be refined. When used with -[`OpenTelemetry.Extensions.Hosting`](../OpenTelemetry.Extensions.Hosting/README.md), +[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md), all configurations to `AspNetCoreTraceInstrumentationOptions` can be done in the `ConfigureServices` method of you applications `Startup` class as shown below. @@ -270,7 +270,7 @@ services.AddOpenTelemetry() })); ``` -[Processor](../../docs/trace/extending-the-sdk/README.md#processor), +[Processor](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#processor), is the general extensibility point to add additional properties to any activity. The `Enrich` option is specific to this instrumentation, and is provided to get access to `HttpRequest` and `HttpResponse`. @@ -365,8 +365,8 @@ This component uses an [EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) with the name "OpenTelemetry-Instrumentation-AspNetCore" for its internal logging. Please refer to [SDK -troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on -seeing these internal logs. +troubleshooting](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry/README.md#troubleshooting) +for instructions on seeing these internal logs. ## References diff --git a/src/OpenTelemetry.Instrumentation.Cassandra/README.md b/src/OpenTelemetry.Instrumentation.Cassandra/README.md index d9dcda3611..6909fbc03f 100644 --- a/src/OpenTelemetry.Instrumentation.Cassandra/README.md +++ b/src/OpenTelemetry.Instrumentation.Cassandra/README.md @@ -63,7 +63,7 @@ public class Program For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for -[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). @@ -101,6 +101,6 @@ var cluster = new Builder() * [OpenTelemetry Project](https://opentelemetry.io/) -* [OpenTelemetry semantic conventions for database calls](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md) +* [OpenTelemetry semantic conventions for Cassandra](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/cassandra.md) * [Cassandra C# Driver](https://github.com/datastax/csharp-driver) diff --git a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md index 690efee13a..1b16f1af16 100644 --- a/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md +++ b/src/OpenTelemetry.Instrumentation.ElasticsearchClient/README.md @@ -16,19 +16,18 @@ Library](https://github.com/open-telemetry/opentelemetry-specification/blob/main which instruments [NEST/Elasticsearch.Net](https://www.nuget.org/packages/NEST) and collects traces about outgoing requests. -**Note: This component is based on the OpenTelemetry semantic conventions for -[metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) +> [!NOTE] +> This component is based on the OpenTelemetry semantic conventions for +[metrics](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/elasticsearch.md) and -[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +[traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/elasticsearch.md). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) -is released, there can be [breaking changes](./CHANGELOG.md). You can track the -progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** +is released, there can be [breaking changes](./CHANGELOG.md). ## Steps to enable OpenTelemetry.Instrumentation.ElasticsearchClient @@ -70,7 +69,7 @@ public class Program For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for -[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to the documentation for diff --git a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md index 0a37df8cee..c545251eb9 100644 --- a/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md +++ b/src/OpenTelemetry.Instrumentation.EntityFrameworkCore/README.md @@ -16,18 +16,16 @@ which instruments and collects traces about outgoing requests. **Note: This component is based on the OpenTelemetry semantic conventions for -[metrics](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions) +[metrics](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-metrics.md) and -[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +[traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) -is released, there can be [breaking changes](./CHANGELOG.md). You can track the -progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23).** +is released, there can be [breaking changes](./CHANGELOG.md).** ## Steps to enable OpenTelemetry.Instrumentation.EntityFrameworkCore @@ -68,7 +66,7 @@ public class Program For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for -[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to the documentation for diff --git a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md index a4b2489ddd..b2d23b106d 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcCore/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcCore/README.md @@ -13,13 +13,14 @@ Adds OpenTelemetry instrumentation for gRPC Core-based client and server calls. gRPC Core is the predecessor to ASP.NET Core gRPC. See -For ASP.NET Core gRPC client instrumentation see +For ASP.NET Core gRPC client instrumentation see +[OpenTelemetry.Instrumentation.GrpcNetClient](../OpenTelemetry.Instrumentation.GrpcNetClient/README.md). For ASP.NET Core gRPC server instrumentation is bundled within the AspNetCore instrumentation. Each inbound or outbound gRPC call will generate a Span which follows the -semantic RPC specification +[semantic RPC specification](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md). ## Installation diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md index 50a8581489..6652dec550 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/CHANGELOG.md @@ -32,7 +32,7 @@ Released 2024-Feb-09 * **Breaking Change**: Please be advised that the - [SuppressDownstreamInstrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient#suppressdownstreaminstrumentation) + [SuppressDownstreamInstrumentation](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient#suppressdownstreaminstrumentation) option no longer works when used in conjunction with the `OpenTelemetry.Instrumentation.Http` package version `1.6.0` or greater. This is not a result of a change in the `OpenTelemetry.Instrumentation.GrpcNetClient` diff --git a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md index 1941ded778..f385395c68 100644 --- a/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md +++ b/src/OpenTelemetry.Instrumentation.GrpcNetClient/README.md @@ -18,11 +18,10 @@ and collects traces about outgoing gRPC requests. [traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/rpc/rpc-spans.md). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), -and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) -is released, there can be breaking changes. You can track the progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). +is released, there can be breaking changes. ## Supported .NET Versions @@ -50,7 +49,7 @@ The following example demonstrates adding Grpc.Net.Client instrumentation to a console application. This example also sets up the OpenTelemetry Console exporter and adds instrumentation for HttpClient, which requires adding the packages -[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) and [`OpenTelemetry.Instrumentation.Http`](../OpenTelemetry.Instrumentation.Http/README.md) to the application. As Grpc.Net.Client uses HttpClient underneath, it is @@ -135,7 +134,7 @@ services.AddOpenTelemetry() }); ``` -[Processor](../../docs/trace/extending-the-sdk/README.md#processor), +[Processor](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/trace/extending-the-sdk/README.md#processor), is the general extensibility point to add additional properties to any activity. The `Enrich` option is specific to this instrumentation, and is provided to get access to `HttpRequest` and `HttpResponse`. diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 3e90df8b9b..6b909b08ac 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -88,7 +88,7 @@ Released 2023-Dec-01 * Removed reference to `OpenTelemetry` package. This is a **breaking change** for users relying on - [SuppressDownstreamInstrumentation](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient#suppressdownstreaminstrumentation) + [SuppressDownstreamInstrumentation](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Instrumentation.GrpcNetClient#suppressdownstreaminstrumentation) option in `OpenTelemetry.Instrumentation.GrpcNetClient`. For details, check out this [issue](https://github.com/open-telemetry/opentelemetry-dotnet/issues/5092). diff --git a/src/OpenTelemetry.Instrumentation.Http/README.md b/src/OpenTelemetry.Instrumentation.Http/README.md index df39d39614..570f2dcf74 100644 --- a/src/OpenTelemetry.Instrumentation.Http/README.md +++ b/src/OpenTelemetry.Instrumentation.Http/README.md @@ -52,7 +52,7 @@ The following example demonstrates adding `HttpClient` instrumentation with the extension method `.AddHttpClientInstrumentation()` on `TracerProviderBuilder` to a console application. This example also sets up the OpenTelemetry Console Exporter, which requires adding the package -[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) to the application. ```csharp @@ -97,7 +97,7 @@ The following example demonstrates adding `HttpClient` instrumentation with the extension method `.AddHttpClientInstrumentation()` on `MeterProviderBuilder` to a console application. This example also sets up the OpenTelemetry Console Exporter, which requires adding the package -[`OpenTelemetry.Exporter.Console`](../OpenTelemetry.Exporter.Console/README.md) +[`OpenTelemetry.Exporter.Console`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Exporter.Console/README.md) to the application. ```csharp @@ -116,8 +116,8 @@ public class Program } ``` -Refer to this [example](../../examples/AspNetCore/Program.cs) to see how to -enable this instrumentation in an ASP.NET core application. +Refer to this [example](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/examples/AspNetCore/Program.cs) +to see how to enable this instrumentation in an ASP.NET Core application. Refer to this [example](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/main/src/OpenTelemetry.Instrumentation.AspNet/README.md) @@ -344,9 +344,9 @@ var tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the -general extensibility point to add additional properties to any activity. The -`Enrich` option is specific to this instrumentation, and is provided to get +[Processor](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/docs/trace/extending-the-sdk/README.md#processor), +is the general extensibility point to add additional properties to any activity. +The `Enrich` option is specific to this instrumentation, and is provided to get access to raw request, response, and exception objects. When overriding the default settings provided by instrumentation or adding @@ -406,8 +406,8 @@ This component uses an [EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) with the name "OpenTelemetry-Instrumentation-Http" for its internal logging. Please refer to [SDK -troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on -seeing these internal logs. +troubleshooting](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/README.md#troubleshooting) +for instructions on seeing these internal logs. ## References diff --git a/src/OpenTelemetry.Instrumentation.MassTransit/README.md b/src/OpenTelemetry.Instrumentation.MassTransit/README.md index 2183728485..dd5bcd13b7 100644 --- a/src/OpenTelemetry.Instrumentation.MassTransit/README.md +++ b/src/OpenTelemetry.Instrumentation.MassTransit/README.md @@ -75,7 +75,7 @@ x.AddMassTransitInstrumentation( })); ``` -For full operation list please see: [OperationName](OperationName.cs). +For full operation list please see: [OperationName](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.MassTransit-1.0.0-beta.3/src/OpenTelemetry.Instrumentation.MassTransit/OperationName.cs). All operations are enabled by default. diff --git a/src/OpenTelemetry.Instrumentation.MySqlData/README.md b/src/OpenTelemetry.Instrumentation.MySqlData/README.md index 6671c3ba39..6df201d3cf 100644 --- a/src/OpenTelemetry.Instrumentation.MySqlData/README.md +++ b/src/OpenTelemetry.Instrumentation.MySqlData/README.md @@ -60,7 +60,7 @@ public class Program For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for -[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). @@ -78,13 +78,13 @@ This instrumentation can be configured to change the default behavior by using ### Capturing 'db.statement' The `MySqlDataInstrumentationOptions` class exposes several properties that can be -used to configure how the [`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md#call-level-attributes) +used to configure how the [`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/mysql.md) attribute is captured upon execution of a query. #### SetDbStatement The `SetDbStatement` property can be used to control whether this instrumentation -should set the [`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md#call-level-attributes) +should set the [`db.statement`](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/mysql.md) attribute to the text of the `MySqlCommand` being executed. Since `CommandType.Text` might contain sensitive data, SQL capturing is @@ -124,7 +124,7 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() ### RecordException This option can be set to instruct the instrumentation to record Exceptions -as Activity [events](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/exceptions.md). +as Activity [events](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md). > Due to the limitation of this library's implementation, We cannot get the raw `MysqlException`, > only exception message is available. @@ -143,4 +143,4 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() * [OpenTelemetry Project](https://opentelemetry.io/) -* [OpenTelemetry semantic conventions for database calls](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md) +* [OpenTelemetry semantic conventions for MySQL](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/mysql.md) diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index f2553161b3..afdb703055 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -95,7 +95,7 @@ even if tracing is disabled. ``` The instrumentation is implemented based on [metrics semantic -conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/http-metrics.md#metric-httpserverduration). +conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-metrics.md#metric-httpserverrequestduration). Currently, the instrumentation supports the following metric. | Name | Instrument Type | Unit | Description | @@ -107,7 +107,7 @@ Currently, the instrumentation supports the following metric. The OpenTelemetry OWIN instrumentation will create spans with very generic names based on the http method of the request. For example: `HTTP GET` or `HTTP POST`. The reason for this is the [OpenTelemetry Specification http semantic -conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name) +conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#name) call specifically for low cardinality values and OWIN does not expose any kind of route template. diff --git a/src/OpenTelemetry.Instrumentation.Process/README.md b/src/OpenTelemetry.Instrumentation.Process/README.md index 4cebfd9a1e..46eb214cc5 100644 --- a/src/OpenTelemetry.Instrumentation.Process/README.md +++ b/src/OpenTelemetry.Instrumentation.Process/README.md @@ -16,7 +16,7 @@ telemetry about process behavior. The process metric instruments being implemented are following OpenTelemetry [metrics semantic -conventions](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md#metric-instruments). +conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/system/process-metrics.md). ## Steps to enable OpenTelemetry.Instrumentation.Process @@ -133,7 +133,7 @@ The API used to retrieve the value is > This metric is under > [discussion](https://github.com/open-telemetry/opentelemetry-specification/issues/3200) and not part of the [Process Metrics -Spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/process-metrics.md) +Spec](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/system/process-metrics.md) at this time. ### process.thread.count diff --git a/src/OpenTelemetry.Instrumentation.Quartz/README.md b/src/OpenTelemetry.Instrumentation.Quartz/README.md index 1ce4f8aac0..c98a9d35fd 100644 --- a/src/OpenTelemetry.Instrumentation.Quartz/README.md +++ b/src/OpenTelemetry.Instrumentation.Quartz/README.md @@ -17,7 +17,7 @@ Automatically instruments the Quartz jobs from QuartzNET Instrumentation is only supported when using .NET Framework >= `net472` and .NET Standard >= `netstandard2.0`. Quartz`net461` support for activity sources has been removed, more information can be found -[here](https://www.quartz-scheduler.net/2021/04/07/quartznet-3-3-released/). +[here](https://github.com/quartznet/quartznet/releases/tag/v3.3.0). ## Installation diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index 96d36f896b..d77db1ce59 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -27,11 +27,10 @@ and later. [traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/database-spans.md). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), -and hence, this package is a [pre-release](../../VERSIONING.md#pre-releases). +and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) -is released, there can be breaking changes. You can track the progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). +is released, there can be breaking changes. ## Steps to enable OpenTelemetry.Instrumentation.SqlClient @@ -223,9 +222,9 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -[Processor](../../docs/trace/extending-the-sdk/README.md#processor), is the -general extensibility point to add additional properties to any activity. The -`Enrich` option is specific to this instrumentation, and is provided to get +[Processor](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/trace/extending-the-sdk/README.md#processor), +is the general extensibility point to add additional properties to any activity. +The `Enrich` option is specific to this instrumentation, and is provided to get access to `SqlCommand` object. ### RecordException diff --git a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md index cf9efeae8f..bfcc48ca73 100644 --- a/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md +++ b/src/OpenTelemetry.Instrumentation.StackExchangeRedis/README.md @@ -17,14 +17,13 @@ and collects traces about outgoing calls to Redis. > [!NOTE] > This component is based on the OpenTelemetry semantic conventions for -[traces](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions). +[traces](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/database/redis.md). These conventions are [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/document-status.md), and hence, this package is a [pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases). Until a [stable version](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/telemetry-stability.md) -is released, there can be breaking changes. You can track the progress from -[milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestone/23). +is released, there can be breaking changes. ## Steps to enable OpenTelemetry.Instrumentation.StackExchangeRedis @@ -72,7 +71,7 @@ public class Program For an ASP.NET Core application, adding instrumentation is typically done in the `ConfigureServices` of your `Startup` class. Refer to documentation for -[OpenTelemetry.Instrumentation.AspNetCore](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Instrumentation.AspNetCore/README.md). +[OpenTelemetry.Instrumentation.AspNetCore](../OpenTelemetry.Instrumentation.AspNetCore/README.md). For an ASP.NET application, adding instrumentation is typically done in the `Global.asax.cs`. Refer to documentation for [OpenTelemetry.Instrumentation.AspNet](../OpenTelemetry.Instrumentation.AspNet/README.md). diff --git a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md index 89a5d7a7a7..59bfc34787 100644 --- a/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md +++ b/src/OpenTelemetry.PersistentStorage.FileSystem/CHANGELOG.md @@ -21,7 +21,7 @@ Released 2023-Apr-17 ([#1110](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1110)) * Going forward the NuGet package will be - [`OpenTelemetry.PersistentStorage.FileSystem`](https://www.nuget.org/packages/OpenTelemetry.Extensions.FileSystem). + [`OpenTelemetry.PersistentStorage.FileSystem`](https://www.nuget.org/packages/OpenTelemetry.PersistentStorage.FileSystem). Older versions will remain at [`OpenTelemetry.Extensions.PersistentStorage`](https://www.nuget.org/packages/OpenTelemetry.Extensions.PersistentStorage) [(#1079)](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1079) From 6bd743e7e34e364c73c4e6bd5099246f7ac08365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Dec 2024 19:41:12 +0100 Subject: [PATCH 1477/1499] [repo] Pin Ubuntu to 22.04 (#2425) --- .github/workflows/Component.BuildTest.yml | 4 ++-- .github/workflows/add-labels.yml | 4 ++-- .github/workflows/assign-reviewers.yml | 2 +- .github/workflows/automation.yml | 2 +- .../workflows/ci-Exporter.OneCollector-Integration.yml | 6 +++--- .github/workflows/ci.yml | 6 +++--- .github/workflows/core-version-update.yml | 2 +- .github/workflows/integration.yml | 4 ++-- .github/workflows/markdownlint.yml | 2 +- .github/workflows/post-release.yml | 2 +- .github/workflows/prepare-release.yml | 10 +++++----- .github/workflows/publish-packages.yml | 2 +- .github/workflows/sanitycheck.yml | 4 ++-- .github/workflows/stale.yml | 2 +- .github/workflows/verifyaotcompat.yml | 2 +- .github/workflows/yamllint.yml | 2 +- 16 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/Component.BuildTest.yml b/.github/workflows/Component.BuildTest.yml index ee5132682a..54dc22f530 100644 --- a/.github/workflows/Component.BuildTest.yml +++ b/.github/workflows/Component.BuildTest.yml @@ -18,7 +18,7 @@ on: required: false type: string os-list: - default: '[ "windows-latest", "ubuntu-latest" ]' + default: '[ "windows-latest", "ubuntu-22.04" ]' required: false type: string tfm-list: @@ -46,7 +46,7 @@ jobs: os: ${{ fromJSON(inputs.os-list) }} version: ${{ fromJSON(inputs.tfm-list) }} exclude: - - os: ubuntu-latest + - os: ubuntu-22.04 version: net462 - os: macos-latest version: net462 diff --git a/.github/workflows/add-labels.yml b/.github/workflows/add-labels.yml index 3ba9ad161c..03af20e08f 100644 --- a/.github/workflows/add-labels.yml +++ b/.github/workflows/add-labels.yml @@ -14,7 +14,7 @@ jobs: add-labels-on-issues: if: github.event_name == 'issues' && !github.event.issue.pull_request - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: check out code @@ -36,7 +36,7 @@ jobs: add-labels-on-pull-requests: if: github.event_name == 'pull_request_target' - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: check out code diff --git a/.github/workflows/assign-reviewers.yml b/.github/workflows/assign-reviewers.yml index 1cf146e060..7a0768d4bd 100644 --- a/.github/workflows/assign-reviewers.yml +++ b/.github/workflows/assign-reviewers.yml @@ -7,7 +7,7 @@ on: jobs: assign: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 name: Assign Reviewers steps: - uses: dyladan/component-owners@main diff --git a/.github/workflows/automation.yml b/.github/workflows/automation.yml index 1385474892..9ea74f7221 100644 --- a/.github/workflows/automation.yml +++ b/.github/workflows/automation.yml @@ -18,7 +18,7 @@ on: jobs: resolve-automation: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 outputs: enabled: ${{ steps.evaluate.outputs.enabled }} diff --git a/.github/workflows/ci-Exporter.OneCollector-Integration.yml b/.github/workflows/ci-Exporter.OneCollector-Integration.yml index bac716d202..c9f7f5c667 100644 --- a/.github/workflows/ci-Exporter.OneCollector-Integration.yml +++ b/.github/workflows/ci-Exporter.OneCollector-Integration.yml @@ -18,7 +18,7 @@ jobs: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && 'external' || 'internal' }} - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - run: echo ✓ @@ -28,10 +28,10 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - os: [ windows-latest, ubuntu-latest ] + os: [ windows-latest, ubuntu-22.04 ] version: [ net462, net8.0 ] exclude: - - os: ubuntu-latest + - os: ubuntu-22.04 version: net462 runs-on: ${{ matrix.os }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1557da70f4..a0cb55915b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -479,7 +479,7 @@ jobs: with: project-name: Component[OpenTelemetry.Resources.Host] code-cov-name: Resources.Host - os-list: '[ "windows-latest", "ubuntu-latest", "macos-latest" ]' + os-list: '[ "windows-latest", "ubuntu-22.04", "macos-latest" ]' build-test-resources-operatingsystem: needs: detect-changes @@ -491,7 +491,7 @@ jobs: with: project-name: Component[OpenTelemetry.Resources.OperatingSystem] code-cov-name: Resources.OperatingSystem - os-list: '[ "windows-latest", "ubuntu-latest", "macos-latest" ]' + os-list: '[ "windows-latest", "ubuntu-22.04", "macos-latest" ]' build-test-resources-process: needs: detect-changes @@ -628,7 +628,7 @@ jobs: verify-aot-compat ] if: always() && !cancelled() - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - run: | if ( ${{ contains(needs.*.result, 'failure') }} == true ); then echo 'build failed ✗'; exit 1; else echo 'build complete ✓'; fi diff --git a/.github/workflows/core-version-update.yml b/.github/workflows/core-version-update.yml index cf3d1019f3..38a74d5390 100644 --- a/.github/workflows/core-version-update.yml +++ b/.github/workflows/core-version-update.yml @@ -14,7 +14,7 @@ jobs: secrets: inherit core-version-update: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: automation diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 8acaf0ee2d..8b18a11193 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -10,7 +10,7 @@ on: jobs: redis-integration-test: if: inputs.job == 'all' || inputs.job == 'redis-integration-test' - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -23,7 +23,7 @@ jobs: kafka-integration-test: if: inputs.job == 'all' || inputs.job == 'kafka-integration-test' - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index 0f42b9c805..1843be2346 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -5,7 +5,7 @@ on: jobs: run-markdownlint: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: check out code diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml index a16d0e0b0a..f36228b5bb 100644 --- a/.github/workflows/post-release.yml +++ b/.github/workflows/post-release.yml @@ -16,7 +16,7 @@ jobs: secrets: inherit post-release: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: - automation diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 224c04ce69..bda2707485 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -79,7 +79,7 @@ jobs: secrets: inherit prepare-release-pr: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: automation @@ -110,7 +110,7 @@ jobs: -gitUserEmail '${{ needs.automation.outputs.email }}' lock-pr-and-post-notice-to-create-release-tag: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: automation @@ -142,7 +142,7 @@ jobs: -botUserName '${{ needs.automation.outputs.username }}' create-release-tag-unlock-pr-post-notice: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: automation @@ -181,7 +181,7 @@ jobs: -gitUserEmail '${{ needs.automation.outputs.email }}' update-changelog-release-dates-on-prepare-pr-post-notice: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: automation @@ -221,7 +221,7 @@ jobs: -gitUserEmail '${{ needs.automation.outputs.email }}' process-release-request-issue: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: automation diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index 6d13c4686a..3a43202540 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -104,7 +104,7 @@ jobs: nuget push src\**\*.nupkg -Source https://api.nuget.org/v3/index.json -ApiKey ${{ secrets.NUGET_TOKEN }} -SymbolApiKey ${{ secrets.NUGET_TOKEN }} post-build: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 needs: - automation diff --git a/.github/workflows/sanitycheck.yml b/.github/workflows/sanitycheck.yml index 8563d4b1cb..ee413dc1cd 100644 --- a/.github/workflows/sanitycheck.yml +++ b/.github/workflows/sanitycheck.yml @@ -5,7 +5,7 @@ on: jobs: run-misspell: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: check out code @@ -20,7 +20,7 @@ jobs: run: ./bin/misspell -error . run-sanitycheck: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: check out code diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 9111144a58..506faba0ad 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,7 +8,7 @@ on: jobs: stale: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/stale@v9 with: diff --git a/.github/workflows/verifyaotcompat.yml b/.github/workflows/verifyaotcompat.yml index 1aff3cac2a..961d070a7c 100644 --- a/.github/workflows/verifyaotcompat.yml +++ b/.github/workflows/verifyaotcompat.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false # ensures the entire test matrix is run, even if one permutation fails matrix: - os: [ ubuntu-latest, windows-latest ] + os: [ ubuntu-22.04, windows-latest ] version: [ net8.0, net9.0 ] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/yamllint.yml b/.github/workflows/yamllint.yml index d802191d66..c0312f672d 100644 --- a/.github/workflows/yamllint.yml +++ b/.github/workflows/yamllint.yml @@ -5,7 +5,7 @@ on: jobs: run-yamllint: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: check out code From 2be10607cb2add6d49f1a2f191472f3fcd70ddad Mon Sep 17 00:00:00 2001 From: Matt Hensley <130569+matt-hensley@users.noreply.github.com> Date: Tue, 17 Dec 2024 13:57:51 -0500 Subject: [PATCH 1478/1499] [Extensions] Adds `BaggageLogRecordProcessor` (#2354) Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Unshipped.txt | 4 + src/OpenTelemetry.Extensions/CHANGELOG.md | 3 + .../Internal/BaggageLogRecordProcessor.cs | 46 ++++++ .../OpenTelemetryExtensionsEventSource.cs | 8 +- .../Logs/OpenTelemetryLoggingExtensions.cs | 100 +++++++++++++ src/OpenTelemetry.Extensions/README.md | 22 +++ .../TracerProviderBuilderExtensions.cs | 2 +- ...erFactoryBaggageLogRecordProcessorTests.cs | 135 +++++++++++++++++ ...erBuilderBaggageLogRecordProcessorTests.cs | 140 ++++++++++++++++++ .../OpenTelemetry.Extensions.Tests.csproj | 5 + 10 files changed, 463 insertions(+), 2 deletions(-) create mode 100644 src/OpenTelemetry.Extensions/Internal/BaggageLogRecordProcessor.cs create mode 100644 test/OpenTelemetry.Extensions.Tests/Logs/LoggerFactoryBaggageLogRecordProcessorTests.cs create mode 100644 test/OpenTelemetry.Extensions.Tests/Logs/LoggerProviderBuilderBaggageLogRecordProcessorTests.cs diff --git a/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt index 1b59a80012..064129dc23 100644 --- a/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Extensions/.publicApi/PublicAPI.Unshipped.txt @@ -14,6 +14,10 @@ OpenTelemetry.Trace.BaggageActivityProcessor OpenTelemetry.Trace.TracerProviderBuilderExtensions override OpenTelemetry.RateLimitingSampler.ShouldSample(in OpenTelemetry.Trace.SamplingParameters samplingParameters) -> OpenTelemetry.Trace.SamplingResult override OpenTelemetry.Trace.BaggageActivityProcessor.OnStart(System.Diagnostics.Activity! data) -> void +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddBaggageProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddBaggageProcessor(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Predicate! baggageKeyPredicate) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddBaggageProcessor(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AddBaggageProcessor(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Predicate! baggageKeyPredicate) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static Microsoft.Extensions.Logging.OpenTelemetryLoggingExtensions.AttachLogsToActivityEvent(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! loggerOptions, System.Action? configure = null) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! static OpenTelemetry.Trace.BaggageActivityProcessor.AllowAllBaggageKeys.get -> System.Predicate! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddAutoFlushActivityProcessor(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Func! predicate, int timeoutMilliseconds = 10000) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index a0848e428f..23a55b79e5 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -19,6 +19,9 @@ rate per second. For details see * Updated OpenTelemetry core component version(s) to `1.10.0`. ([#2317](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2317)) +* Adds Baggage LogRecord Processor. + ([#2354](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2354)) + ## 1.0.0-beta.5 Released 2024-May-08 diff --git a/src/OpenTelemetry.Extensions/Internal/BaggageLogRecordProcessor.cs b/src/OpenTelemetry.Extensions/Internal/BaggageLogRecordProcessor.cs new file mode 100644 index 0000000000..9fd4811ebd --- /dev/null +++ b/src/OpenTelemetry.Extensions/Internal/BaggageLogRecordProcessor.cs @@ -0,0 +1,46 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Logs; + +namespace OpenTelemetry.Extensions.Internal; + +internal sealed class BaggageLogRecordProcessor : BaseProcessor +{ + private readonly Predicate baggageKeyPredicate; + + public BaggageLogRecordProcessor(Predicate baggageKeyPredicate) + { + this.baggageKeyPredicate = baggageKeyPredicate ?? throw new ArgumentNullException(nameof(baggageKeyPredicate)); + } + + public static Predicate AllowAllBaggageKeys => (_) => true; + + public override void OnEnd(LogRecord data) + { + var baggage = Baggage.Current; + + if (data != null && baggage.Count > 0) + { + var capacity = (data.Attributes?.Count ?? 0) + baggage.Count; + var attributes = new List>(capacity); + + foreach (var entry in baggage) + { + if (this.baggageKeyPredicate(entry.Key)) + { + attributes.Add(new(entry.Key, entry.Value)); + } + } + + if (data.Attributes != null) + { + attributes.AddRange(data.Attributes); + } + + data.Attributes = attributes; + } + + base.OnEnd(data!); + } +} diff --git a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs index 7cef228fb4..9963e43ee0 100644 --- a/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs +++ b/src/OpenTelemetry.Extensions/Internal/OpenTelemetryExtensionsEventSource.cs @@ -45,8 +45,14 @@ public void LogRecordFilterException(string? categoryName, string exception) } [Event(3, Message = "Baggage key predicate threw exeption when trying to add baggage entry with key '{0}'. Baggage entry will not be added to the activity. Exception: '{1}'", Level = EventLevel.Warning)] - public void BaggageKeyPredicateException(string baggageKey, string exception) + public void BaggageKeyActivityPredicateException(string baggageKey, string exception) { this.WriteEvent(3, baggageKey, exception); } + + [Event(4, Message = "Baggage key predicate threw exeption when trying to add baggage entry with key '{0}'. Baggage entry will not be added to the log record. Exception: '{1}'", Level = EventLevel.Warning)] + public void BaggageKeyLogRecordPredicateException(string baggageKey, string exception) + { + this.WriteEvent(4, baggageKey, exception); + } } diff --git a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs index ce4152036b..e349bb3742 100644 --- a/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs +++ b/src/OpenTelemetry.Extensions/Logs/OpenTelemetryLoggingExtensions.cs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; +using OpenTelemetry; +using OpenTelemetry.Extensions.Internal; using OpenTelemetry.Internal; using OpenTelemetry.Logs; @@ -34,4 +36,102 @@ public static OpenTelemetryLoggerOptions AttachLogsToActivityEvent( return loggerOptions.AddProcessor(new ActivityEventAttachingLogProcessor(options)); #pragma warning restore CA2000 // Dispose objects before losing scope } + + /// + /// Adds a processor to the OpenTelemetry which will copy all + /// baggage entries as log record attributes. + /// + /// to add the processor to. + /// The instance of to chain the calls. + /// is null. + /// + /// Copies all current baggage entries to log record attributes. + /// + public static OpenTelemetryLoggerOptions AddBaggageProcessor( + this OpenTelemetryLoggerOptions loggerOptions) + { + return loggerOptions.AddBaggageProcessor(BaggageLogRecordProcessor.AllowAllBaggageKeys); + } + + /// + /// Adds a processor to the OpenTelemetry which will conditionally copy + /// baggage entries as log record attributes. + /// + /// to add the processor to. + /// Predicate to determine which baggage keys should be added to the log record. + /// The instance of to chain the calls. + /// is null. + /// is null. + /// + /// Conditionally copies current baggage entries to log record attributes. + /// In case of an exception the predicate is treated as false, and the baggage entry will not be copied. + /// + public static OpenTelemetryLoggerOptions AddBaggageProcessor( + this OpenTelemetryLoggerOptions loggerOptions, + Predicate baggageKeyPredicate) + { + Guard.ThrowIfNull(loggerOptions); + Guard.ThrowIfNull(baggageKeyPredicate); + + return loggerOptions.AddProcessor(_ => SetupBaggageLogRecordProcessor(baggageKeyPredicate)); + } + + /// + /// Adds a processor to the OpenTelemetry which will copy all + /// baggage entries as log record attributes. + /// + /// to add the processor to. + /// The instance of to chain the calls. + /// is null. + /// + /// Copies all current baggage entries to log record attributes. + /// + public static LoggerProviderBuilder AddBaggageProcessor( + this LoggerProviderBuilder builder) + { + return builder.AddBaggageProcessor(BaggageLogRecordProcessor.AllowAllBaggageKeys); + } + + /// + /// Adds a processor to the OpenTelemetry which will copy all + /// baggage entries as log record attributes. + /// + /// to add the processor to. + /// Predicate to determine which baggage keys should be added to the log record. + /// The instance of to chain the calls. + /// is null. + /// is null. + /// + /// Conditionally copies current baggage entries to log record attributes. + /// In case of an exception the predicate is treated as false, and the baggage entry will not be copied. + /// + public static LoggerProviderBuilder AddBaggageProcessor( + this LoggerProviderBuilder builder, + Predicate baggageKeyPredicate) + { + Guard.ThrowIfNull(builder); + Guard.ThrowIfNull(baggageKeyPredicate); + + return builder.AddProcessor(_ => SetupBaggageLogRecordProcessor(baggageKeyPredicate)); + } + + private static BaggageLogRecordProcessor SetupBaggageLogRecordProcessor(Predicate baggageKeyPredicate) + { + return new BaggageLogRecordProcessor(baggageKey => + { + try + { + return baggageKeyPredicate(baggageKey); + } + catch (Exception exception) + { + OpenTelemetryExtensionsEventSource.Log.BaggageKeyLogRecordPredicateException(baggageKey, exception.Message); + return false; + } + }); + } } diff --git a/src/OpenTelemetry.Extensions/README.md b/src/OpenTelemetry.Extensions/README.md index 6ad53f5476..0fafdc3d4e 100644 --- a/src/OpenTelemetry.Extensions/README.md +++ b/src/OpenTelemetry.Extensions/README.md @@ -20,6 +20,28 @@ future. Adds a log processor which will convert log messages into events and attach them to the currently running `Activity`. +### AddBaggageProcessor + +Adds a log processor which will copy baggage entries to log records. +The method takes an optional predicate to filter the copied baggage entries +based on the entry key. If no predicate is provided, all entries are copied. + +Example of AddBaggageProcessor usage with a predicate: + +```csharp +var regex = new Regex("^allow", RegexOptions.Compiled); +using var loggerFactory = LoggerFactory.Create(builder => builder +.AddOpenTelemetry(options => +{ + options.AddBaggageProcessor(regex.IsMatch); + // other set up (exporters, processors) +}) +``` + +Warning: The baggage key predicate is executed for every baggage entry for each +log record. +Do not use slow or intensive operations. + ## Traces ### AutoFlushActivityProcessor diff --git a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs index 8ab9da3ac7..4cfddb9213 100644 --- a/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Extensions/TracerProviderBuilderExtensions.cs @@ -68,7 +68,7 @@ public static TracerProviderBuilder AddBaggageActivityProcessor( } catch (Exception exception) { - OpenTelemetryExtensionsEventSource.Log.BaggageKeyPredicateException(baggageKey, exception.Message); + OpenTelemetryExtensionsEventSource.Log.BaggageKeyActivityPredicateException(baggageKey, exception.Message); return false; } })); diff --git a/test/OpenTelemetry.Extensions.Tests/Logs/LoggerFactoryBaggageLogRecordProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Logs/LoggerFactoryBaggageLogRecordProcessorTests.cs new file mode 100644 index 0000000000..4c3d5e77b2 --- /dev/null +++ b/test/OpenTelemetry.Extensions.Tests/Logs/LoggerFactoryBaggageLogRecordProcessorTests.cs @@ -0,0 +1,135 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Tests.Logs; + +public class LoggerFactoryBaggageLogRecordProcessorTests +{ + [Fact] + public void BaggageLogRecordProcessor_CanAddAllowAllBaggageKeysPredicate() + { + var logRecordList = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddBaggageProcessor(); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + Baggage.SetBaggage("allow", "value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + } + + [Fact] + public void BaggageLogRecordProcessor_CanUseCustomPredicate() + { + var logRecordList = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddBaggageProcessor((baggageKey) => baggageKey.StartsWith("allow", StringComparison.Ordinal)); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + Baggage.SetBaggage("allow", "value"); + Baggage.SetBaggage("deny", "other_value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + Assert.DoesNotContain(logRecord.Attributes, kv => kv.Key == "deny"); + } + + [Fact] + public void BaggageLogRecordProcessor_CanUseRegex() + { + var regex = new Regex("^allow", RegexOptions.Compiled); + var logRecordList = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddBaggageProcessor(regex.IsMatch); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + Baggage.SetBaggage("allow", "value"); + Baggage.SetBaggage("deny", "other_value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + Assert.DoesNotContain(logRecord.Attributes, kv => kv.Key == "deny"); + } + + [Fact] + public void BaggageLogRecordProcessor_PredicateThrows_DoesNothing() + { + var logRecordList = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddBaggageProcessor(_ => throw new Exception("Predicate throws an exception.")); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + Baggage.SetBaggage("deny", "value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.DoesNotContain(logRecord?.Attributes ?? [], kv => kv.Key == "deny"); + } + + [Fact] + public void BaggageLogRecordProcessor_PredicateThrows_OnlyDropsEntriesThatThrow() + { + var logRecordList = new List(); + using var loggerFactory = LoggerFactory.Create(builder => builder + .AddOpenTelemetry(options => + { + options.AddBaggageProcessor(key => + { + return key != "allow" ? throw new Exception("Predicate throws an exception.") : true; + }); + options.AddInMemoryExporter(logRecordList); + }) + .AddFilter("*", LogLevel.Trace)); // Enable all LogLevels + Baggage.SetBaggage("allow", "value"); + Baggage.SetBaggage("deny", "value"); + Baggage.SetBaggage("deny_2", "value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + Assert.DoesNotContain(logRecord?.Attributes ?? [], kv => kv.Key == "deny"); + } + + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } +} diff --git a/test/OpenTelemetry.Extensions.Tests/Logs/LoggerProviderBuilderBaggageLogRecordProcessorTests.cs b/test/OpenTelemetry.Extensions.Tests/Logs/LoggerProviderBuilderBaggageLogRecordProcessorTests.cs new file mode 100644 index 0000000000..5a8c865c1e --- /dev/null +++ b/test/OpenTelemetry.Extensions.Tests/Logs/LoggerProviderBuilderBaggageLogRecordProcessorTests.cs @@ -0,0 +1,140 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; +using System.Text.RegularExpressions; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using OpenTelemetry.Trace; +using Xunit; + +namespace OpenTelemetry.Extensions.Tests.Logs; + +public class LoggerProviderBuilderBaggageLogRecordProcessorTests +{ + [Fact] + public void BaggageLogRecordProcessor_CanAddAllowAllBaggageKeysPredicate() + { + var logRecordList = new List(); + var sp = new ServiceCollection(); + sp.AddOpenTelemetry().WithLogging(builder => + { + builder.AddBaggageProcessor(); + builder.AddInMemoryExporter(logRecordList); + }); + var s = sp.BuildServiceProvider(); + var loggerFactory = s.GetRequiredService(); + Baggage.SetBaggage("allow", "value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + } + + [Fact] + public void BaggageLogRecordProcessor_CanUseCustomPredicate() + { + var logRecordList = new List(); + var sp = new ServiceCollection(); + sp.AddOpenTelemetry().WithLogging(builder => + { + builder.AddBaggageProcessor((baggageKey) => baggageKey.StartsWith("allow", StringComparison.Ordinal)); + builder.AddInMemoryExporter(logRecordList); + }); + var s = sp.BuildServiceProvider(); + var loggerFactory = s.GetRequiredService(); + Baggage.SetBaggage("allow", "value"); + Baggage.SetBaggage("deny", "other_value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + Assert.DoesNotContain(logRecord.Attributes, kv => kv.Key == "deny"); + } + + [Fact] + public void BaggageLogRecordProcessor_CanUseRegex() + { + var regex = new Regex("^allow", RegexOptions.Compiled); + var logRecordList = new List(); + var sp = new ServiceCollection(); + sp.AddOpenTelemetry().WithLogging(builder => + { + builder.AddBaggageProcessor(regex.IsMatch); + builder.AddInMemoryExporter(logRecordList); + }); + var s = sp.BuildServiceProvider(); + var loggerFactory = s.GetRequiredService(); + Baggage.SetBaggage("allow", "value"); + Baggage.SetBaggage("deny", "other_value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + Assert.DoesNotContain(logRecord.Attributes, kv => kv.Key == "deny"); + } + + [Fact] + public void BaggageLogRecordProcessor_PredicateThrows_DoesNothing() + { + var logRecordList = new List(); + var sp = new ServiceCollection(); + sp.AddOpenTelemetry().WithLogging(builder => + { + builder.AddBaggageProcessor(_ => throw new Exception("Predicate throws an exception.")); + builder.AddInMemoryExporter(logRecordList); + }); + var s = sp.BuildServiceProvider(); + var loggerFactory = s.GetRequiredService(); + Baggage.SetBaggage("deny", "value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.DoesNotContain(logRecord?.Attributes ?? [], kv => kv.Key == "deny"); + } + + [Fact] + public void BaggageLogRecordProcessor_PredicateThrows_OnlyDropsEntriesThatThrow() + { + var logRecordList = new List(); + var sp = new ServiceCollection(); + sp.AddOpenTelemetry().WithLogging(builder => + { + builder.AddBaggageProcessor(key => + { + return key != "allow" ? throw new Exception("Predicate throws an exception.") : true; + }); + builder.AddInMemoryExporter(logRecordList); + }); + var s = sp.BuildServiceProvider(); + var loggerFactory = s.GetRequiredService(); + Baggage.SetBaggage("allow", "value"); + Baggage.SetBaggage("deny", "value"); + Baggage.SetBaggage("deny_2", "value"); + + var logger = loggerFactory.CreateLogger(GetTestMethodName()); + logger.LogError("this does not matter"); + var logRecord = Assert.Single(logRecordList); + Assert.NotNull(logRecord); + Assert.NotNull(logRecord.Attributes); + Assert.Contains(logRecord.Attributes, kv => kv.Key == "allow"); + Assert.DoesNotContain(logRecord?.Attributes ?? [], kv => kv.Key == "deny"); + } + + private static string GetTestMethodName([CallerMemberName] string callingMethodName = "") + { + return callingMethodName; + } +} diff --git a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj index 1aa7195de6..4372bf3b0e 100644 --- a/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj +++ b/test/OpenTelemetry.Extensions.Tests/OpenTelemetry.Extensions.Tests.csproj @@ -15,4 +15,9 @@ + + + + + From aca23a2f2b968d61db75eb0504ae45118abe900c Mon Sep 17 00:00:00 2001 From: Mikel Blanchard Date: Tue, 17 Dec 2024 11:14:34 -0800 Subject: [PATCH 1479/1499] [repo] Allow dependabot to bump SDK patch version (#2417) --- .github/dependabot.yml | 12 ++++++++++++ opentelemetry-dotnet-contrib.sln | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2ac5ee6784..168e352f88 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,15 @@ updates: interval: "daily" labels: - "infra" + - package-ecosystem: "dotnet-sdk" + directory: "/" + schedule: + interval: "weekly" + day: "wednesday" + labels: + - "infra" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index 936e6672f8..a67e744eb3 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -261,7 +261,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{1FCC8E src\Shared\ServerCertificateValidationProvider.cs = src\Shared\ServerCertificateValidationProvider.cs src\Shared\SpanAttributeConstants.cs = src\Shared\SpanAttributeConstants.cs src\Shared\SpanHelper.cs = src\Shared\SpanHelper.cs - src\Shared\SqlProcessor.cs = src\Shared\SqlProcessor.cs + src\Shared\SqlProcessor.cs = src\Shared\SqlProcessor.cs src\Shared\UriHelper.cs = src\Shared\UriHelper.cs EndProjectSection EndProject From 8dc88653328716f20a4a87e1dfc70db18015b325 Mon Sep 17 00:00:00 2001 From: Santiago Blanco <56326361+sablancoleis@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:23:13 -0800 Subject: [PATCH 1480/1499] [Instrumentation.ServiceFabricRemoting] initial implementation (#2288) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Santiago Blanco <56326361+sablanc-msft@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + .github/ISSUE_TEMPLATE/release_request.yml | 1 + .github/codecov.yml | 5 + .github/component_owners.yml | 4 + .github/workflows/ci.yml | 14 ++ .github/workflows/prepare-release.yml | 1 + opentelemetry-dotnet-contrib.sln | 14 ++ .../.publicApi/PublicAPI.Shipped.txt | 1 + .../.publicApi/PublicAPI.Unshipped.txt | 37 ++++ ...tEnrichedActorRemotingProviderAttribute.cs | 123 +++++++++++ .../AssemblyInfo.cs | 11 + .../CHANGELOG.md | 5 + ...strumentation.ServiceFabricRemoting.csproj | 34 +++ .../README.md | 195 ++++++++++++++++++ .../ServiceFabricRemotingActivitySource.cs | 22 ++ ...iceFabricRemotingInstrumentationOptions.cs | 54 +++++ .../ServiceFabricRemotingUtils.cs | 32 +++ ...nrichedServiceRemotingProviderAttribute.cs | 114 ++++++++++ ...ServiceRemotingMessageDispatcherAdapter.cs | 115 +++++++++++ ...extEnrichedServiceRemotingClientAdapter.cs | 142 +++++++++++++ ...chedServiceRemotingClientFactoryAdapter.cs | 98 +++++++++ .../TracerProviderBuilderExtensions.cs | 51 +++++ .../IMyTestActor.cs | 11 + .../IMyTestActorService.cs | 11 + .../ITestMyStatefulService.cs | 11 + ...nsportServiceRemotingRequestContextMock.cs | 18 ++ .../Mocks/ServiceRemotingClientMock.cs | 54 +++++ ...ServiceRemotingRequestMessageHeaderMock.cs | 71 +++++++ .../ServiceRemotingRequestMessageMock.cs | 29 +++ ...erviceRemotingResponseMessageHeaderMock.cs | 49 +++++ .../MyTestActor.cs | 31 +++ .../MyTestActorService.cs | 62 ++++++ .../MyTestStatefulService.cs | 59 ++++++ ...ntation.ServiceFabricRemoting.Tests.csproj | 30 +++ .../ServiceFabricRemotingTests.cs | 174 ++++++++++++++++ .../ServiceFabricUtils.cs | 81 ++++++++ .../ServiceResponse.cs | 15 ++ 38 files changed, 1781 insertions(+) create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Shipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Unshipped.txt create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ActorRemoting/TraceContextEnrichedActorRemotingProviderAttribute.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/AssemblyInfo.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/CHANGELOG.md create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/OpenTelemetry.Instrumentation.ServiceFabricRemoting.csproj create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/README.md create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingActivitySource.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingInstrumentationOptions.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingUtils.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemoting/TraceContextEnrichedServiceRemotingProviderAttribute.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemotingMessageDispatcherAdapter.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientAdapter.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientFactoryAdapter.cs create mode 100644 src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TracerProviderBuilderExtensions.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActor.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActorService.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ITestMyStatefulService.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/FabricTransportServiceRemotingRequestContextMock.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingClientMock.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageHeaderMock.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageMock.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingResponseMessageHeaderMock.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActor.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActorService.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestStatefulService.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests.csproj create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricRemotingTests.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricUtils.cs create mode 100644 test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceResponse.cs diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9441d40269..f2e67d4e55 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -45,6 +45,7 @@ body: - OpenTelemetry.Instrumentation.Process - OpenTelemetry.Instrumentation.Quartz - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.ServiceFabricRemoting - OpenTelemetry.Instrumentation.SqlClient - OpenTelemetry.Instrumentation.StackExchangeRedis - OpenTelemetry.Instrumentation.Wcf diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 0443264723..5461bf353a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -45,6 +45,7 @@ body: - OpenTelemetry.Instrumentation.Process - OpenTelemetry.Instrumentation.Quartz - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.ServiceFabricRemoting - OpenTelemetry.Instrumentation.SqlClient - OpenTelemetry.Instrumentation.StackExchangeRedis - OpenTelemetry.Instrumentation.Wcf diff --git a/.github/ISSUE_TEMPLATE/release_request.yml b/.github/ISSUE_TEMPLATE/release_request.yml index d7bfea1b5c..b219f533ff 100644 --- a/.github/ISSUE_TEMPLATE/release_request.yml +++ b/.github/ISSUE_TEMPLATE/release_request.yml @@ -43,6 +43,7 @@ body: - OpenTelemetry.Instrumentation.Process - OpenTelemetry.Instrumentation.Quartz - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.ServiceFabricRemoting - OpenTelemetry.Instrumentation.SqlClient - OpenTelemetry.Instrumentation.StackExchangeRedis - OpenTelemetry.Instrumentation.Wcf diff --git a/.github/codecov.yml b/.github/codecov.yml index ae835620c7..b94a66eb52 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -150,6 +150,11 @@ flags: paths: - src/OpenTelemetry.Instrumentation.Runtime + unittests-Instrumentation.ServiceFabricRemoting: + carryforward: true + paths: + - src/OpenTelemetry.Instrumentation.ServiceFabricRemoting + unittests-Instrumentation.SqlClient: carryforward: true paths: diff --git a/.github/component_owners.yml b/.github/component_owners.yml index cbd6deb94c..b140db27bc 100644 --- a/.github/component_owners.yml +++ b/.github/component_owners.yml @@ -56,6 +56,8 @@ components: src/OpenTelemetry.Instrumentation.Runtime/: - twenzel - xiang17 + src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/: + - sablancoleis src/OpenTelemetry.Instrumentation.Wcf/: - codeblanch src/OpenTelemetry.PersistentStorage.Abstractions/: @@ -149,6 +151,8 @@ components: test/OpenTelemetry.Instrumentation.Runtime.Tests/: - twenzel - xiang17 + test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/: + - sablancoleis test/OpenTelemetry.Instrumentation.Wcf.Tests/: - codeblanch test/OpenTelemetry.PersistentStorage.FileSystem.Tests/: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0cb55915b..7f7318acb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ jobs: instrumentation-process: ['*/OpenTelemetry.Instrumentation.Process*/**', 'examples/process-instrumentation/**', '!**/*.md'] instrumentation-quartz: ['*/OpenTelemetry.Instrumentation.Quartz*/**', '!**/*.md'] instrumentation-runtime: ['*/OpenTelemetry.Instrumentation.Runtime*/**', 'examples/runtime-instrumentation/**', '!**/*.md'] + instrumentation-servicefabricremoting: ['*/OpenTelemetry.Instrumentation.ServiceFabricRemoting*/**', '!**/*.md'] instrumentation-sqlclient: ['*/OpenTelemetry.Instrumentation.SqlClient*/**', '!**/*.md'] instrumentation-stackexchangeredis: ['*/OpenTelemetry.Instrumentation.StackExchangeRedis*/**', 'examples/redis/**', '!**/*.md'] instrumentation-wcf: ['*/OpenTelemetry.Instrumentation.Wcf*/**', 'examples/wcf/**', '!**/*.md'] @@ -371,6 +372,17 @@ jobs: project-name: OpenTelemetry.Instrumentation.Runtime code-cov-name: Instrumentation.Runtime + build-test-instrumentation-servicefabricremoting: + needs: detect-changes + if: | + contains(needs.detect-changes.outputs.changes, 'instrumentation-servicefabricremoting') + || contains(needs.detect-changes.outputs.changes, 'build') + || contains(needs.detect-changes.outputs.changes, 'shared') + uses: ./.github/workflows/Component.BuildTest.yml + with: + project-name: Component[OpenTelemetry.Instrumentation.ServiceFabricRemoting] + code-cov-name: Instrumentation.ServiceFabricRemoting + build-test-instrumentation-sqlclient: needs: detect-changes if: | @@ -563,6 +575,7 @@ jobs: || contains(needs.detect-changes.outputs.changes, 'instrumentation-grpcnetclient') || contains(needs.detect-changes.outputs.changes, 'instrumentation-http') || contains(needs.detect-changes.outputs.changes, 'instrumentation-runtime') + || contains(needs.detect-changes.outputs.changes, 'instrumentation-servicefabricremoting') || contains(needs.detect-changes.outputs.changes, 'instrumentation-sqlclient') || contains(needs.detect-changes.outputs.changes, 'instrumentation-stackexchangeredis') || contains(needs.detect-changes.outputs.changes, 'resources-aws') @@ -610,6 +623,7 @@ jobs: build-test-instrumentation-process, build-test-instrumentation-quartz, build-test-instrumentation-runtime, + build-test-instrumentation-servicefabricremoting, build-test-instrumentation-sqlclient, build-test-instrumentation-stackexchangeredis, build-test-instrumentation-stackexchangeredis-integration, diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index bda2707485..dc84ca1068 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -34,6 +34,7 @@ on: - OpenTelemetry.Instrumentation.Process - OpenTelemetry.Instrumentation.Quartz - OpenTelemetry.Instrumentation.Runtime + - OpenTelemetry.Instrumentation.ServiceFabricRemoting - OpenTelemetry.Instrumentation.SqlClient - OpenTelemetry.Instrumentation.StackExchangeRedis - OpenTelemetry.Instrumentation.Wcf diff --git a/opentelemetry-dotnet-contrib.sln b/opentelemetry-dotnet-contrib.sln index a67e744eb3..abcb4727f6 100644 --- a/opentelemetry-dotnet-contrib.sln +++ b/opentelemetry-dotnet-contrib.sln @@ -400,6 +400,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kafka", "kafka", "{3A464E7A EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Examples.ConfluentKafka", "examples\kafka\Examples.ConfluentKafka.csproj", "{9B994669-E839-4C42-A0F1-DF9DD058C1DC}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ServiceFabricRemoting", "src\OpenTelemetry.Instrumentation.ServiceFabricRemoting\OpenTelemetry.Instrumentation.ServiceFabricRemoting.csproj", "{91BA4FF0-50BC-49D0-976B-CBC9E5FE8337}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests", "test\OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests\OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests.csproj", "{00C9F0B8-3D51-483C-821A-5889B38A144C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -822,6 +826,14 @@ Global {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {9B994669-E839-4C42-A0F1-DF9DD058C1DC}.Release|Any CPU.Build.0 = Release|Any CPU + {91BA4FF0-50BC-49D0-976B-CBC9E5FE8337}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91BA4FF0-50BC-49D0-976B-CBC9E5FE8337}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91BA4FF0-50BC-49D0-976B-CBC9E5FE8337}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91BA4FF0-50BC-49D0-976B-CBC9E5FE8337}.Release|Any CPU.Build.0 = Release|Any CPU + {00C9F0B8-3D51-483C-821A-5889B38A144C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00C9F0B8-3D51-483C-821A-5889B38A144C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00C9F0B8-3D51-483C-821A-5889B38A144C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00C9F0B8-3D51-483C-821A-5889B38A144C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -948,6 +960,8 @@ Global {BE40900A-2859-471D-8802-21DFD73DDAA7} = {2097345F-4DD3-477D-BC54-A922F9B2B402} {3A464E7A-42F3-44B0-B8D7-80521A7704A6} = {B75EE478-97F7-4E9F-9A5A-DB3D0988EDEA} {9B994669-E839-4C42-A0F1-DF9DD058C1DC} = {3A464E7A-42F3-44B0-B8D7-80521A7704A6} + {91BA4FF0-50BC-49D0-976B-CBC9E5FE8337} = {22DF5DC0-1290-4E83-A9D8-6BB7DE3B3E63} + {00C9F0B8-3D51-483C-821A-5889B38A144C} = {2097345F-4DD3-477D-BC54-A922F9B2B402} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B0816796-CDB3-47D7-8C3C-946434DE3B66} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..dae70bf6c4 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1,37 @@ +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.AddExceptionAtClient.get -> bool +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.AddExceptionAtClient.set -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.AddExceptionAtServer.get -> bool +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.AddExceptionAtServer.set -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.EnrichAtClientFromRequest.get -> System.Action? +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.EnrichAtClientFromRequest.set -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.EnrichAtClientFromResponse.get -> System.Action? +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.EnrichAtClientFromResponse.set -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.Filter.get -> System.Func? +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.Filter.set -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceFabricRemotingInstrumentationOptions.ServiceFabricRemotingInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceRemotingMessageDispatcherAdapter +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceRemotingMessageDispatcherAdapter.Dispose() -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceRemotingMessageDispatcherAdapter.GetRemotingMessageBodyFactory() -> Microsoft.ServiceFabric.Services.Remoting.V2.IServiceRemotingMessageBodyFactory! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceRemotingMessageDispatcherAdapter.HandleOneWayMessage(Microsoft.ServiceFabric.Services.Remoting.V2.IServiceRemotingRequestMessage! requestMessage) -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceRemotingMessageDispatcherAdapter.HandleRequestResponseAsync(Microsoft.ServiceFabric.Services.Remoting.V2.Runtime.IServiceRemotingRequestContext! requestContext, Microsoft.ServiceFabric.Services.Remoting.V2.IServiceRemotingRequestMessage! requestMessage) -> System.Threading.Tasks.Task! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.ServiceRemotingMessageDispatcherAdapter.ServiceRemotingMessageDispatcherAdapter(Microsoft.ServiceFabric.Services.Remoting.V2.Runtime.IServiceRemotingMessageHandler! dispatcher) -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedActorRemotingProviderAttribute +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedActorRemotingProviderAttribute.TraceContextEnrichedActorRemotingProviderAttribute() -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.ClientConnected -> System.EventHandler!>! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.ClientDisconnected -> System.EventHandler!>! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.GetClientAsync(System.Fabric.ResolvedServicePartition! previousRsp, Microsoft.ServiceFabric.Services.Communication.Client.TargetReplicaSelector targetReplicaSelector, string! listenerName, Microsoft.ServiceFabric.Services.Communication.Client.OperationRetrySettings! retrySettings, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.GetClientAsync(System.Uri! serviceUri, Microsoft.ServiceFabric.Services.Client.ServicePartitionKey! partitionKey, Microsoft.ServiceFabric.Services.Communication.Client.TargetReplicaSelector targetReplicaSelector, string! listenerName, Microsoft.ServiceFabric.Services.Communication.Client.OperationRetrySettings! retrySettings, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.GetRemotingMessageBodyFactory() -> Microsoft.ServiceFabric.Services.Remoting.V2.IServiceRemotingMessageBodyFactory! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.ReportOperationExceptionAsync(Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingClient! client, Microsoft.ServiceFabric.Services.Communication.Client.ExceptionInformation! exceptionInformation, Microsoft.ServiceFabric.Services.Communication.Client.OperationRetrySettings! retrySettings, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingClientFactoryAdapter.TraceContextEnrichedServiceRemotingClientFactoryAdapter(Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingClientFactory! serviceRemotingClientFactory) -> void +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingProviderAttribute +OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingProviderAttribute.TraceContextEnrichedServiceRemotingProviderAttribute() -> void +OpenTelemetry.Trace.TracerProviderBuilderExtensions +override OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedActorRemotingProviderAttribute.CreateServiceRemotingClientFactory(Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingCallbackMessageHandler? callbackMessageHandler) -> Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingClientFactory! +override OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedActorRemotingProviderAttribute.CreateServiceRemotingListeners() -> System.Collections.Generic.Dictionary!>! +override OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingProviderAttribute.CreateServiceRemotingClientFactoryV2(Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingCallbackMessageHandler? callbackMessageHandler) -> Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingClientFactory! +override OpenTelemetry.Instrumentation.ServiceFabricRemoting.TraceContextEnrichedServiceRemotingProviderAttribute.CreateServiceRemotingListeners() -> System.Collections.Generic.Dictionary!>! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddServiceFabricRemotingInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddServiceFabricRemotingInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! tracerProviderBuilder, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ActorRemoting/TraceContextEnrichedActorRemotingProviderAttribute.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ActorRemoting/TraceContextEnrichedActorRemotingProviderAttribute.cs new file mode 100644 index 0000000000..3eed71be42 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ActorRemoting/TraceContextEnrichedActorRemotingProviderAttribute.cs @@ -0,0 +1,123 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.ServiceFabric.Actors.Generator; +using Microsoft.ServiceFabric.Actors.Remoting.FabricTransport; +using Microsoft.ServiceFabric.Actors.Remoting.V2.FabricTransport.Client; +using Microsoft.ServiceFabric.Actors.Remoting.V2.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Actors.Remoting.V2.Runtime; +using Microsoft.ServiceFabric.Actors.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.FabricTransport; +using Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2.Client; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +/// +/// Sets fabric TCP transport as the default remoting provider for the actors. +/// +[AttributeUsage(AttributeTargets.Assembly)] +public sealed class TraceContextEnrichedActorRemotingProviderAttribute : FabricTransportActorRemotingProviderAttribute +{ + private const string DefaultV2listenerName = "V2Listener"; + + /// + /// Initializes a new instance of the class. + /// + public TraceContextEnrichedActorRemotingProviderAttribute() + { + this.RemotingClientVersion = Microsoft.ServiceFabric.Services.Remoting.RemotingClientVersion.V2; + this.RemotingListenerVersion = Microsoft.ServiceFabric.Services.Remoting.RemotingListenerVersion.V2; + } + + /// + /// Creates a service remoting listener for remoting the actor interfaces. + /// . + /// + /// A as for the specified actor service. + /// + public override Dictionary> CreateServiceRemotingListeners() + { + Dictionary> dictionary = new Dictionary>(); + + dictionary.Add(DefaultV2listenerName, (actorService) => + { + ActorServiceRemotingDispatcher actorServiceRemotingDispatcher = new ActorServiceRemotingDispatcher(actorService, serviceRemotingRequestMessageBodyFactory: null); + ServiceRemotingMessageDispatcherAdapter dispatcherAdapter = new ServiceRemotingMessageDispatcherAdapter(actorServiceRemotingDispatcher); + FabricTransportRemotingListenerSettings listenerSettings = this.InitializeListenerSettings(actorService); + + return new FabricTransportActorServiceRemotingListener(actorService, dispatcherAdapter, listenerSettings); + }); + + return dictionary; + } + + /// + /// Creates a service remoting client factory that can be used by the Microsoft.ServiceFabric.Services.Remoting.V2.Client.ServiceProxyFactory + /// to create a proxy for the remoted interface of the service. + /// + /// Client implementation where the callbacks should be dispatched. + /// An . + public override IServiceRemotingClientFactory CreateServiceRemotingClientFactory(IServiceRemotingCallbackMessageHandler? callbackMessageHandler) + { + FabricTransportRemotingSettings settings = new FabricTransportRemotingSettings(); + settings.MaxMessageSize = this.GetAndValidateMaxMessageSize(settings.MaxMessageSize); + settings.OperationTimeout = this.GetAndValidateOperationTimeout(settings.OperationTimeout); + settings.KeepAliveTimeout = this.GetAndValidateKeepAliveTimeout(settings.KeepAliveTimeout); + settings.ConnectTimeout = this.GetConnectTimeout(settings.ConnectTimeout); + + FabricTransportActorRemotingClientFactory fabricTransportActorRemotingClientFactory = new FabricTransportActorRemotingClientFactory( + settings, + callbackMessageHandler, + servicePartitionResolver: null, + exceptionHandlers: null, + traceId: null); + + return new TraceContextEnrichedServiceRemotingClientFactoryAdapter(fabricTransportActorRemotingClientFactory); + } + + private static FabricTransportRemotingListenerSettings GetActorListenerSettings(ActorService actorService) + { + string sectionName = ActorNameFormat.GetFabricServiceTransportSettingsSectionName(actorService.ActorTypeInformation.ImplementationType); + + bool isSucceded = FabricTransportRemotingListenerSettings.TryLoadFrom(sectionName, out FabricTransportRemotingListenerSettings listenerSettings); + if (!isSucceded) + { + listenerSettings = new FabricTransportRemotingListenerSettings(); + } + + return listenerSettings; + } + + private FabricTransportRemotingListenerSettings InitializeListenerSettings(ActorService actorService) + { + FabricTransportRemotingListenerSettings listenerSettings = GetActorListenerSettings(actorService); + + listenerSettings.MaxMessageSize = this.GetAndValidateMaxMessageSize(listenerSettings.MaxMessageSize); + listenerSettings.OperationTimeout = this.GetAndValidateOperationTimeout(listenerSettings.OperationTimeout); + listenerSettings.KeepAliveTimeout = this.GetAndValidateKeepAliveTimeout(listenerSettings.KeepAliveTimeout); + + return listenerSettings; + } + + private long GetAndValidateMaxMessageSize(long maxMessageSizeDefault) + { + return (this.MaxMessageSize > 0) ? this.MaxMessageSize : maxMessageSizeDefault; + } + + private TimeSpan GetAndValidateOperationTimeout(TimeSpan operationTimeoutDefault) + { + return (this.OperationTimeoutInSeconds > 0) ? TimeSpan.FromSeconds(this.OperationTimeoutInSeconds) : operationTimeoutDefault; + } + + private TimeSpan GetAndValidateKeepAliveTimeout(TimeSpan keepAliveTimeoutDefault) + { + return (this.KeepAliveTimeoutInSeconds > 0) ? TimeSpan.FromSeconds(this.KeepAliveTimeoutInSeconds) : keepAliveTimeoutDefault; + } + + private TimeSpan GetConnectTimeout(TimeSpan connectTimeoutDefault) + { + return (this.ConnectTimeoutInMilliseconds > 0) ? TimeSpan.FromMilliseconds(this.ConnectTimeoutInMilliseconds) : connectTimeoutDefault; + } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/AssemblyInfo.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/AssemblyInfo.cs new file mode 100644 index 0000000000..f35369a78b --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/AssemblyInfo.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Runtime.CompilerServices; + +[assembly: CLSCompliant(false)] +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests")] +#endif diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/CHANGELOG.md new file mode 100644 index 0000000000..5e61f8e249 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +* Initial release of `OpenTelemetry.Instrumentation.ServiceFabricRemoting` library. diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/OpenTelemetry.Instrumentation.ServiceFabricRemoting.csproj b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/OpenTelemetry.Instrumentation.ServiceFabricRemoting.csproj new file mode 100644 index 0000000000..32851ef8da --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/OpenTelemetry.Instrumentation.ServiceFabricRemoting.csproj @@ -0,0 +1,34 @@ + + + + + $(NetStandardMinimumSupportedVersion) + ServiceFabric Remoting instrumentation for OpenTelemetry .NET. + $(PackageTags);distributed-tracing + Instrumentation.ServiceFabricRemoting- + + + + + true + + + + + None + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/README.md b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/README.md new file mode 100644 index 0000000000..a44deb1753 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/README.md @@ -0,0 +1,195 @@ +# Service Fabric Remoting Instrumentation for OpenTelemetry .NET + +| Status | | +| ------------- |-----------| +| Stability | [Beta](../../README.md#beta) | +| Code Owners | [@sablancoleis](https://github.com/sablancoleis) | + +[![NuGet version badge](https://img.shields.io/nuget/v/OpenTelemetry.Instrumentation.ServiceFabricRemoting)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ServiceFabricRemoting) +[![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ServiceFabricRemoting)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ServiceFabricRemoting) +[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.ServiceFabricRemoting)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.ServiceFabricRemoting) + +This is an [Instrumentation Library](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/glossary.md#instrumentation-library), +which instruments [Service Fabric Remoting](https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting) +and collects telemetry about incoming requests. + +## Steps to enable OpenTelemetry.Instrumentation.ServiceFabricRemoting + +### Step 1: Install Package + +Add a reference to the +[`OpenTelemetry.Instrumentation.ServiceFabricRemoting`](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ServiceFabricRemoting) +package. Also, add any other instrumentations & exporters you will need. + +```shell +dotnet add package OpenTelemetry.Instrumentation.ServiceFabricRemoting +``` + +### Step 2: Configure SF Remoting with Distributed Tracing instrumentation + +These instructions are a moified vertion of the steps mentioned here: +[`Use an assembly attribute to use the V2 stack`](https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting#use-an-assembly-attribute-to-use-the-v2-stack) + +a) Change the endpoint resource from "ServiceEndpoint" to "ServiceEndpointV2" + in the service manifest. + +```xml + + + + + +``` + +b) Use the Microsoft.ServiceFabric.Services.Remoting.Runtime +.CreateServiceRemotingInstanceListeners +extension method to create remoting listeners. + +```csharp + protected override IEnumerable CreateServiceInstanceListeners() + { + return this.CreateServiceRemotingInstanceListeners(); + } +``` + +c) Mark the assembly that contains the remoting interfaces with a +**TraceContextEnrichedActorRemotingProvider** and/or a +**TraceContextEnrichedServiceRemotingProvider** attribute. +*Note that these attributes are not part of the Service Fabric SDK +and are provided by the OpenTelemetry.Instrumentation.ServiceFabricRemoting package.** + +```csharp + [assembly: TraceContextEnrichedActorRemotingProvider()] + [assembly: TraceContextEnrichedServiceRemotingProvider()] +``` + +### Step 3: Enable SF Remoting Instrumentation + +#### Configure OpenTelemetry TracerProvider in Program.cs + +Call the `AddServiceFabricRemotingInstrumentation` extension method on the +`TracerProviderBuilder` to register the OpenTelemetry instrumentation. + +```csharp + using TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ServiceFabricRemoting-Example")) + .AddServiceFabricRemotingInstrumentation() + .AddOtlpExporter() + .Build(); +``` + +This will register the `ServiceFabric.Remoting` ActivitySource and create +spans for incoming and outgoing remoting calls. + +It will also automatically inject the trace context and Baggage into the +remoting headers, and extract them on the receiving side. + +#### Configuration options + +The `AddServiceFabricRemotingInstrumentation` extension method takes an optional +`ServiceFabricRemotingInstrumentationOptions` parameter that offers the following +configurable settings: + +- **Filter** - A filter function that can be used to exclude certain remoting +calls from being instrumented. +The function takes a `ServiceRemotingRequest` and returns a boolean value. +If the function returns `true`, the remoting call will be instrumented. +If the function returns `false`, the remoting call will not be instrumented. +By default, all remoting calls are instrumented. + +```csharp + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ServiceFabricRemoting-Example")) + .AddServiceFabricRemotingInstrumentation(options => + { + options.Filter = requestMessage => + { + // Exclude remoting calls to a specific method + IServiceRemotingRequestMessageHeader requestMessageHeader = requestMessage?.GetHeader(); + if (requestMessageHeader?.MethodName == "SomeMethodToIgnore") + { + return false; + } + return true; + }; + }) + .AddOtlpExporter() + .Build(); +``` + +- **EnrichAtClientFromRequest** - A function that can be used to enrich the span +created for the client side of the remoting call. +The function takes a `Activity` and a `ServiceRemotingRequest` and returns the `Activity`. +By default, the client span is enriched with the service interface name +and method name. + +```csharp + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ServiceFabricRemoting-Example")) + .AddServiceFabricRemotingInstrumentation(options => + { + options.EnrichAtClientFromRequest = (activity, requestMessage) => + { + // Add custom attributes to the client span + activity.SetTag("CustomAttribute", "CustomValue"); + return activity; + }; + }) + .AddOtlpExporter() + .Build(); +``` + +- **EnrichAtServerFromRequest** - A function that can be used to enrich the span +created for the server side of the remoting call. +The function takes a `Activity` and a `ServiceRemotingRequest` and returns the `Activity`. +By default, the server span is enriched with the service interface +name and method name. + +```csharp + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ServiceFabricRemoting-Example")) + .AddServiceFabricRemotingInstrumentation(options => + { + options.EnrichAtServerFromRequest = (activity, requestMessage) => + { + // Add custom attributes to the server span + activity.SetTag("CustomAttribute", "CustomValue"); + return activity; + }; + }) + .AddOtlpExporter() + .Build(); +``` + +- **AddExceptionAtClient** - Gets or sets a value indicating whether +the exception will be recorded at the client as an `ActivityEvent` or not. + +```csharp + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ServiceFabricRemoting-Example")) + .AddServiceFabricRemotingInstrumentation(options => + { + options.AddExceptionAtClient = true; + }) + .AddOtlpExporter() + .Build(); +``` + +- **AddExceptionAtServer** - Gets or sets a value indicating whether +the exception will be recorded at the server as an `ActivityEvent` or not + +```csharp + TracerProvider tracerProvider = Sdk.CreateTracerProviderBuilder() + .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("ServiceFabricRemoting-Example")) + .AddServiceFabricRemotingInstrumentation(options => + { + options.AddExceptionAtServer = true; + }) + .AddOtlpExporter() + .Build(); +``` + +## References + +- [Azure Service Fabric documentation](https://learn.microsoft.com/en-us/azure/service-fabric/) +- [OpenTelemetry Project](https://opentelemetry.io/) diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingActivitySource.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingActivitySource.cs new file mode 100644 index 0000000000..eb69c138d5 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingActivitySource.cs @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Reflection; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +internal class ServiceFabricRemotingActivitySource +{ + internal static readonly Assembly Assembly = typeof(ServiceFabricRemotingActivitySource).Assembly; + internal static readonly AssemblyName AssemblyName = Assembly.GetName(); + internal static readonly string ActivitySourceName = AssemblyName.Name; + + internal static readonly string IncomingRequestActivityName = ActivitySourceName + ".IncomingRequest"; + internal static readonly string OutgoingRequestActivityName = ActivitySourceName + ".OutgoingRequest"; + + public static ActivitySource ActivitySource { get; } = new ActivitySource(ActivitySourceName, Assembly.GetPackageVersion()); + + public static ServiceFabricRemotingInstrumentationOptions? Options { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingInstrumentationOptions.cs new file mode 100644 index 0000000000..dd549be835 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingInstrumentationOptions.cs @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.ServiceFabric.Services.Remoting.V2; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +/// +/// Options for ServiceFabric Remoting instrumentation. +/// +public class ServiceFabricRemotingInstrumentationOptions +{ + /// + /// Initializes a new instance of the class. + /// + public ServiceFabricRemotingInstrumentationOptions() + { + } + + /// + /// Gets or sets a Filter function that determines whether or not to collect telemetry about requests on a per request basis. + /// The Filter gets the , and should return a boolean. + /// If Filter returns true, the request is collected. + /// If Filter returns false or throw exception, the request is filtered out. + /// + public Func? Filter { get; set; } + + /// + /// Gets or sets an action to enrich the created by the client instrumentation, from the request. + /// + public Action? EnrichAtClientFromRequest { get; set; } + + /// + /// Gets or sets an action to enrich the created by the client instrumentation, from the response. + /// + public Action? EnrichAtClientFromResponse { get; set; } + + /// + /// Gets or sets a value indicating whether the exception will be recorded at the client as or not. + /// + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/exceptions.md. + /// + public bool AddExceptionAtClient { get; set; } + + /// + /// Gets or sets a value indicating whether the exception will be recorded at the server as or not. + /// + /// + /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/exceptions.md. + /// + public bool AddExceptionAtServer { get; set; } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingUtils.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingUtils.cs new file mode 100644 index 0000000000..9e90cab099 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceFabricRemotingUtils.cs @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Text; +using Microsoft.ServiceFabric.Services.Remoting.V2; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +internal static class ServiceFabricRemotingUtils +{ + internal static void InjectTraceContextIntoServiceRemotingRequestMessageHeader(IServiceRemotingRequestMessageHeader requestMessageHeader, string key, string value) + { + if (!requestMessageHeader.TryGetHeaderValue(key, out byte[] _)) + { + byte[] valueAsBytes = Encoding.UTF8.GetBytes(value); + + requestMessageHeader.AddHeader(key, valueAsBytes); + } + } + + internal static IEnumerable ExtractTraceContextFromRequestMessageHeader(IServiceRemotingRequestMessageHeader requestMessageHeader, string headerKey) + { + if (requestMessageHeader.TryGetHeaderValue(headerKey, out byte[] headerValueAsBytes)) + { + string headerValue = Encoding.UTF8.GetString(headerValueAsBytes); + + return [headerValue]; + } + + return Enumerable.Empty(); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemoting/TraceContextEnrichedServiceRemotingProviderAttribute.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemoting/TraceContextEnrichedServiceRemotingProviderAttribute.cs new file mode 100644 index 0000000000..4fb29fe8d3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemoting/TraceContextEnrichedServiceRemotingProviderAttribute.cs @@ -0,0 +1,114 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Fabric; +using Microsoft.ServiceFabric.Services.Remoting; +using Microsoft.ServiceFabric.Services.Remoting.FabricTransport; +using Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2.Client; +using Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Client; +using Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2.Runtime; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +/// +/// This attributes allows to set Fabric TCP transport as the default service remoting transport provider in the assembly and customization of it. +/// +[AttributeUsage(AttributeTargets.Assembly)] +public sealed class TraceContextEnrichedServiceRemotingProviderAttribute : FabricTransportServiceRemotingProviderAttribute +{ + private const string DefaultV2listenerName = "V2Listener"; + + /// + /// Initializes a new instance of the class. + /// + public TraceContextEnrichedServiceRemotingProviderAttribute() + { + this.RemotingClientVersion = RemotingClientVersion.V2; + this.RemotingListenerVersion = RemotingListenerVersion.V2; + } + + /// + /// Creates a V2 service remoting listener for remoting the service interface. + /// + /// + /// A Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime.FabricTransportServiceRemotingListener + /// as Microsoft.ServiceFabric.Services.Remoting.Runtime.IServiceRemotingListener for the specified service implementation. + /// + public override Dictionary> CreateServiceRemotingListeners() + { + Dictionary> dictionary = new Dictionary>(); + + dictionary.Add(DefaultV2listenerName, (ServiceContext serviceContext, IService serviceImplementation) => + { + FabricTransportRemotingListenerSettings listenerSettings = this.GetListenerSettings(serviceContext); + ServiceRemotingMessageDispatcher serviceRemotingMessageDispatcher = new ServiceRemotingMessageDispatcher(serviceContext, serviceImplementation); + ServiceRemotingMessageDispatcherAdapter dispatcherAdapter = new ServiceRemotingMessageDispatcherAdapter(serviceRemotingMessageDispatcher); + + return new FabricTransportServiceRemotingListener(serviceContext, dispatcherAdapter, listenerSettings); + }); + + return dictionary; + } + + /// + /// Creates a V2 service remoting client factory for connecting to the service over remoted service interfaces. + /// + /// The client implementation where the callbacks should be dispatched. + /// + /// A Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Client.FabricTransportServiceRemotingClientFactory + /// as Microsoft.ServiceFabric.Services.Remoting.V2.Client.IServiceRemotingClientFactory + /// that can be used with Microsoft.ServiceFabric.Services.Remoting.Client.ServiceProxyFactory + /// to generate service proxy to talk to a stateless or stateful service over remoted actor interface. + /// + public override IServiceRemotingClientFactory CreateServiceRemotingClientFactoryV2(IServiceRemotingCallbackMessageHandler? callbackMessageHandler) + { + FabricTransportRemotingSettings fabricTransportRemotingSettings = new FabricTransportRemotingSettings(); + fabricTransportRemotingSettings.MaxMessageSize = this.GetAndValidateMaxMessageSize(fabricTransportRemotingSettings.MaxMessageSize); + fabricTransportRemotingSettings.OperationTimeout = this.GetAndValidateOperationTimeout(fabricTransportRemotingSettings.OperationTimeout); + fabricTransportRemotingSettings.KeepAliveTimeout = this.GetAndValidateKeepAliveTimeout(fabricTransportRemotingSettings.KeepAliveTimeout); + fabricTransportRemotingSettings.ConnectTimeout = this.GetConnectTimeout(fabricTransportRemotingSettings.ConnectTimeout); + + FabricTransportServiceRemotingClientFactory fabricTransportServiceRemotingClientFactory = new FabricTransportServiceRemotingClientFactory( + fabricTransportRemotingSettings, + callbackMessageHandler, + servicePartitionResolver: null, + exceptionHandlers: null, + traceId: null); + + return new TraceContextEnrichedServiceRemotingClientFactoryAdapter(fabricTransportServiceRemotingClientFactory); + } + + private FabricTransportRemotingListenerSettings GetListenerSettings(ServiceContext serviceContext) + { + FabricTransportRemotingListenerSettings listenerSettings = new FabricTransportRemotingListenerSettings(); + + listenerSettings.MaxMessageSize = this.GetAndValidateMaxMessageSize(listenerSettings.MaxMessageSize); + listenerSettings.OperationTimeout = this.GetAndValidateOperationTimeout(listenerSettings.OperationTimeout); + listenerSettings.KeepAliveTimeout = this.GetAndValidateKeepAliveTimeout(listenerSettings.KeepAliveTimeout); + + return listenerSettings; + } + + private long GetAndValidateMaxMessageSize(long maxMessageSizeDefault) + { + return (this.MaxMessageSize > 0) ? this.MaxMessageSize : maxMessageSizeDefault; + } + + private TimeSpan GetAndValidateOperationTimeout(TimeSpan operationTimeoutDefault) + { + return (this.OperationTimeoutInSeconds > 0) ? TimeSpan.FromSeconds(this.OperationTimeoutInSeconds) : operationTimeoutDefault; + } + + private TimeSpan GetAndValidateKeepAliveTimeout(TimeSpan keepAliveTimeoutDefault) + { + return (this.KeepAliveTimeoutInSeconds > 0) ? TimeSpan.FromSeconds(this.KeepAliveTimeoutInSeconds) : keepAliveTimeoutDefault; + } + + private TimeSpan GetConnectTimeout(TimeSpan connectTimeoutDefault) + { + return (this.ConnectTimeoutInMilliseconds > 0) ? TimeSpan.FromMilliseconds(this.ConnectTimeoutInMilliseconds) : connectTimeoutDefault; + } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemotingMessageDispatcherAdapter.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemotingMessageDispatcherAdapter.cs new file mode 100644 index 0000000000..3c3f489504 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/ServiceRemotingMessageDispatcherAdapter.cs @@ -0,0 +1,115 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.ServiceFabric.Services.Remoting.V2; +using Microsoft.ServiceFabric.Services.Remoting.V2.Runtime; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +/// +/// Provides an implementation of that can dispatch +/// messages to an actor service and to the actors hosted in the service. +/// +public sealed class ServiceRemotingMessageDispatcherAdapter : IServiceRemotingMessageHandler, IDisposable +{ + private static readonly TextMapPropagator Propagator = Propagators.DefaultTextMapPropagator; + + private readonly IServiceRemotingMessageHandler innerDispatcher; + + /// + /// Initializes a new instance of the class. + /// + /// The IServiceRemotingMessageHandler to wrap. + public ServiceRemotingMessageDispatcherAdapter(IServiceRemotingMessageHandler dispatcher) + { + Guard.ThrowIfNull(dispatcher); + + this.innerDispatcher = dispatcher; + } + + /// + /// Gets a factory for creating the remoting message bodies. + /// + /// A factory for creating the remoting message bodies. + public IServiceRemotingMessageBodyFactory GetRemotingMessageBodyFactory() + { + return this.innerDispatcher.GetRemotingMessageBodyFactory(); + } + + /// + /// Handles a one way message from the client. + /// + /// The request message. + public void HandleOneWayMessage(IServiceRemotingRequestMessage requestMessage) + { + this.innerDispatcher.HandleOneWayMessage(requestMessage); + } + + /// + /// Dispatches the messages received from the client to the actor service methods or the actor methods. + /// This can be used by user where they know interfaceId and MethodId for the method to dispatch to. + /// + /// Request context that allows getting the callback channel if required. + /// Remoting message. + /// The response for the received request. + public async Task HandleRequestResponseAsync(IServiceRemotingRequestContext requestContext, IServiceRemotingRequestMessage requestMessage) + { + Guard.ThrowIfNull(requestMessage); + + if (ServiceFabricRemotingActivitySource.Options?.Filter?.Invoke(requestMessage) == false) + { + // If we filter out the request we don't need to process anything related to the activity + return await this.innerDispatcher.HandleRequestResponseAsync(requestContext, requestMessage).ConfigureAwait(false); + } + else + { + IServiceRemotingRequestMessageHeader requestMessageHeader = requestMessage.GetHeader(); + Guard.ThrowIfNull(requestMessageHeader, "requestMessage.GetHeader()"); + + // Extract the PropagationContext of the upstream parent from the message headers. + PropagationContext parentContext = Propagator.Extract(default, requestMessageHeader, ServiceFabricRemotingUtils.ExtractTraceContextFromRequestMessageHeader); + Baggage.Current = parentContext.Baggage; + + string activityName = requestMessageHeader?.MethodName ?? ServiceFabricRemotingActivitySource.IncomingRequestActivityName; + + using (Activity? activity = ServiceFabricRemotingActivitySource.ActivitySource.StartActivity(activityName, ActivityKind.Server, parentContext.ActivityContext)) + { + try + { + IServiceRemotingResponseMessage responseMessage = await this.innerDispatcher.HandleRequestResponseAsync(requestContext, requestMessage).ConfigureAwait(false); + + return responseMessage; + } + catch (Exception ex) + { + if (activity != null) + { + activity.SetStatus(ActivityStatusCode.Error); + + if (ServiceFabricRemotingActivitySource.Options?.AddExceptionAtServer == true) + { + activity.RecordException(ex); + } + } + + throw; + } + } + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + if (this.innerDispatcher is IDisposable disposable) + { + disposable.Dispose(); + } + } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientAdapter.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientAdapter.cs new file mode 100644 index 0000000000..7c130d3373 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientAdapter.cs @@ -0,0 +1,142 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Fabric; +using Microsoft.ServiceFabric.Services.Remoting.V2; +using Microsoft.ServiceFabric.Services.Remoting.V2.Client; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Internal; +using OpenTelemetry.Trace; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +/// +/// An IServiceRemotingClient that enriches the outgoing request with the current Activity (if any). +/// +internal class TraceContextEnrichedServiceRemotingClientAdapter : IServiceRemotingClient +{ + private static readonly TextMapPropagator Propagator = Propagators.DefaultTextMapPropagator; + + private readonly IServiceRemotingClient innerClient; + + public TraceContextEnrichedServiceRemotingClientAdapter(IServiceRemotingClient remotingClient) + { + this.innerClient = remotingClient; + } + + public IServiceRemotingClient InnerClient + { + get { return this.innerClient; } + } + + public ResolvedServicePartition ResolvedServicePartition + { + get { return this.InnerClient.ResolvedServicePartition; } + set { this.InnerClient.ResolvedServicePartition = value; } + } + + public string ListenerName + { + get { return this.InnerClient.ListenerName; } + set { this.InnerClient.ListenerName = value; } + } + + public ResolvedServiceEndpoint Endpoint + { + get { return this.InnerClient.Endpoint; } + set { this.InnerClient.Endpoint = value; } + } + + public async Task RequestResponseAsync(IServiceRemotingRequestMessage requestMessage) + { + Guard.ThrowIfNull(requestMessage); + + if (ServiceFabricRemotingActivitySource.Options?.Filter?.Invoke(requestMessage) == false) + { + // If we filter out the request we don't need to process anything related to the activity + return await this.innerClient.RequestResponseAsync(requestMessage).ConfigureAwait(false); + } + else + { + IServiceRemotingRequestMessageHeader requestMessageHeader = requestMessage.GetHeader(); + Guard.ThrowIfNull(requestMessageHeader, "requestMessage.GetHeader()"); + + string activityName = requestMessageHeader.MethodName ?? ServiceFabricRemotingActivitySource.OutgoingRequestActivityName; + + using (Activity? activity = ServiceFabricRemotingActivitySource.ActivitySource.StartActivity(activityName, ActivityKind.Client)) + { + // Depending on Sampling (and whether a listener is registered or not), the activity above may not be created. + // If it is created, then propagate its context. + if (activity != null) + { + try + { + ServiceFabricRemotingActivitySource.Options?.EnrichAtClientFromRequest?.Invoke(activity, requestMessage); + } + catch (Exception) + { + // TODO: Log error + } + + try + { + // Inject the ActivityContext into the message headers to propagate trace context and Baggage to the receiving service. + Propagator.Inject(new PropagationContext(activity.Context, Baggage.Current), requestMessageHeader, ServiceFabricRemotingUtils.InjectTraceContextIntoServiceRemotingRequestMessageHeader); + } + catch (Exception ex) + { + activity.SetStatus(ActivityStatusCode.Error, $"Error trying to inject the context in the remoting request: '{ex.Message}'"); + } + } + + try + { + IServiceRemotingResponseMessage responseMessage = await this.innerClient.RequestResponseAsync(requestMessage).ConfigureAwait(false); + + if (activity != null) + { + try + { + ServiceFabricRemotingActivitySource.Options?.EnrichAtClientFromResponse?.Invoke(activity, responseMessage, /* exception */ null); + } + catch (Exception) + { + // TODO: Log error + } + } + + return responseMessage; + } + catch (Exception ex) + { + if (activity != null) + { + activity.SetStatus(ActivityStatusCode.Error); + + if (ServiceFabricRemotingActivitySource.Options?.AddExceptionAtClient == true) + { + activity.RecordException(ex); + } + + try + { + ServiceFabricRemotingActivitySource.Options?.EnrichAtClientFromResponse?.Invoke(activity, /* serviceRemotingResponseMessage */ null, ex); + } + catch (Exception) + { + // TODO: Log error + } + } + + throw; + } + } + } + } + + public void SendOneWay(IServiceRemotingRequestMessage requestMessage) + { + this.InnerClient.SendOneWay(requestMessage); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientFactoryAdapter.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientFactoryAdapter.cs new file mode 100644 index 0000000000..fbe02e4411 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TraceContextEnrichedServiceRemotingClientFactoryAdapter.cs @@ -0,0 +1,98 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Fabric; +using Microsoft.ServiceFabric.Services.Client; +using Microsoft.ServiceFabric.Services.Communication.Client; +using Microsoft.ServiceFabric.Services.Remoting.V2; +using Microsoft.ServiceFabric.Services.Remoting.V2.Client; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting; + +/// +/// An IServiceRemotingClientFactory that uses Fabric TCP transport to create IServiceRemotingClient +/// that communicate with stateless and stateful services over interfaces that are +/// remoted via Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime.FabricTransportServiceRemotingListener. +/// +/// Both the client and the listener are instrumented to propagate both the traceContext and Baggage objects from OpenTelemetry. +/// +public class TraceContextEnrichedServiceRemotingClientFactoryAdapter : IServiceRemotingClientFactory +{ + private readonly IServiceRemotingClientFactory innerFactory; + + /// + /// Initializes a new instance of the class. + /// + /// The communication client factory to wrap. + public TraceContextEnrichedServiceRemotingClientFactoryAdapter(IServiceRemotingClientFactory serviceRemotingClientFactory) + { + this.innerFactory = serviceRemotingClientFactory; + } + + /// + /// Event handler that is fired when a client is connected to the service endpoint. + /// + public event EventHandler> ClientConnected + { + add { this.innerFactory.ClientConnected += value; } + remove { this.innerFactory.ClientConnected -= value; } + } + + /// + /// Event handler that is fired when a client is disconnected from the service endpoint. + /// + public event EventHandler> ClientDisconnected + { + add { this.innerFactory.ClientDisconnected += value; } + remove { this.innerFactory.ClientDisconnected -= value; } + } + + /// + /// Gets a factory for creating the remoting message bodies. + /// + /// A factory for creating the remoting message bodies. + public IServiceRemotingMessageBodyFactory GetRemotingMessageBodyFactory() + { + return this.innerFactory.GetRemotingMessageBodyFactory(); + } + + /// + public async Task GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken) + { + IServiceRemotingClient serviceRemotingClient = await this.innerFactory.GetClientAsync( + serviceUri, + partitionKey, + targetReplicaSelector, + listenerName, + retrySettings, + cancellationToken).ConfigureAwait(false); + + return new TraceContextEnrichedServiceRemotingClientAdapter(serviceRemotingClient); + } + + /// + public async Task GetClientAsync(ResolvedServicePartition previousRsp, TargetReplicaSelector targetReplicaSelector, string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken) + { + IServiceRemotingClient serviceRemotingClient = await this.innerFactory.GetClientAsync( + previousRsp, + targetReplicaSelector, + listenerName, + retrySettings, + cancellationToken).ConfigureAwait(false); + + return new TraceContextEnrichedServiceRemotingClientAdapter(serviceRemotingClient); + } + + /// + public Task ReportOperationExceptionAsync(IServiceRemotingClient client, ExceptionInformation exceptionInformation, OperationRetrySettings retrySettings, CancellationToken cancellationToken) + { + IServiceRemotingClient innerClient = client; + TraceContextEnrichedServiceRemotingClientAdapter? clientAdapter = client as TraceContextEnrichedServiceRemotingClientAdapter; + if (clientAdapter != null) + { + innerClient = clientAdapter.InnerClient; + } + + return this.innerFactory.ReportOperationExceptionAsync(innerClient, exceptionInformation, retrySettings, cancellationToken); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TracerProviderBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TracerProviderBuilderExtensions.cs new file mode 100644 index 0000000000..f8d275576a --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ServiceFabricRemoting/TracerProviderBuilderExtensions.cs @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using OpenTelemetry.Instrumentation.ServiceFabricRemoting; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Trace; + +/// +/// Extension methods to simplify registering of ServiceFabric Remoting instrumentation. +/// +public static class TracerProviderBuilderExtensions +{ + /// + /// Enables the incoming requests automatic data collection for ServiceFabric Remoting. + /// + /// being configured. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddServiceFabricRemotingInstrumentation(this TracerProviderBuilder builder) + { + return AddServiceFabricRemotingInstrumentation(builder, configure: null); + } + + /// + /// Enables the incoming requests automatic data collection for ServiceFabric Remoting. + /// + /// being configured. + /// ServiceFabric Remoting configuration options. + /// The instance of to chain the calls. + public static TracerProviderBuilder AddServiceFabricRemotingInstrumentation(this TracerProviderBuilder tracerProviderBuilder, Action? configure) + { + Guard.ThrowIfNull(tracerProviderBuilder); + + return tracerProviderBuilder.ConfigureServices(services => + { + if (configure != null) + { + services.Configure(configure); + } + + services.ConfigureOpenTelemetryTracerProvider((serviceProvider, builder) => + { + ServiceFabricRemotingActivitySource.Options = serviceProvider.GetRequiredService>().Get(name: null); + + builder.AddSource(ServiceFabricRemotingActivitySource.ActivitySourceName); + }); + }); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActor.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActor.cs new file mode 100644 index 0000000000..a3c506201b --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActor.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.ServiceFabric.Actors; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public interface IMyTestActor : IActor +{ + Task TestContextPropagation(string valueToReturn); +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActorService.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActorService.cs new file mode 100644 index 0000000000..0a661ff269 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/IMyTestActorService.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.ServiceFabric.Actors; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public interface IMyTestActorService : IActorService +{ + Task TestContextPropagation(string valueToReturn); +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ITestMyStatefulService.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ITestMyStatefulService.cs new file mode 100644 index 0000000000..95f83922eb --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ITestMyStatefulService.cs @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.ServiceFabric.Services.Remoting; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public interface ITestMyStatefulService : IService +{ + Task TestContextPropagation(string valueToReturn); +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/FabricTransportServiceRemotingRequestContextMock.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/FabricTransportServiceRemotingRequestContextMock.cs new file mode 100644 index 0000000000..d7066092e2 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/FabricTransportServiceRemotingRequestContextMock.cs @@ -0,0 +1,18 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.ServiceFabric.Services.Remoting.V2.Runtime; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +internal class FabricTransportServiceRemotingRequestContextMock : IServiceRemotingRequestContext +{ + public FabricTransportServiceRemotingRequestContextMock() + { + } + + public IServiceRemotingCallbackClient? GetCallBackClient() + { + return null; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingClientMock.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingClientMock.cs new file mode 100644 index 0000000000..57ab9f5872 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingClientMock.cs @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Fabric; +using System.Text; +using Microsoft.ServiceFabric.Services.Remoting.V2; +using Microsoft.ServiceFabric.Services.Remoting.V2.Client; +using OpenTelemetry.Context.Propagation; +using ServiceFabric.Mocks.RemotingV2; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +internal class ServiceRemotingClientMock : IServiceRemotingClient +{ + public ServiceRemotingClientMock() + { + } + + public ResolvedServicePartition ResolvedServicePartition { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public string ListenerName { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public ResolvedServiceEndpoint Endpoint { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + /// + /// The RequestResponseAsync method reads the headers from the request and injects them into the response, using OpneTelemetry's TextMapPropagator. + /// + public Task RequestResponseAsync(IServiceRemotingRequestMessage requestMessage) + { + IServiceRemotingRequestMessageHeader requestMessageHeader = requestMessage.GetHeader(); + PropagationContext propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, requestMessageHeader, ServiceFabricRemotingUtils.ExtractTraceContextFromRequestMessageHeader); + + MockServiceRemotingResponseMessage responseMessage = new MockServiceRemotingResponseMessage() + { + Header = new ServiceRemotingResponseMessageHeaderMock(), + }; + + Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(propagationContext.ActivityContext, propagationContext.Baggage), responseMessage.Header, this.InjectTraceContextIntoServiceRemotingRequestMessageHeader); + + return Task.FromResult(responseMessage); + } + + public void SendOneWay(IServiceRemotingRequestMessage requestMessage) => throw new NotImplementedException(); + + private void InjectTraceContextIntoServiceRemotingRequestMessageHeader(IServiceRemotingResponseMessageHeader responseMessageHeaders, string key, string value) + { + if (!responseMessageHeaders.TryGetHeaderValue(key, out byte[] _)) + { + byte[] valueAsBytes = Encoding.UTF8.GetBytes(value); + + responseMessageHeaders.AddHeader(key, valueAsBytes); + } + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageHeaderMock.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageHeaderMock.cs new file mode 100644 index 0000000000..4aacb37b4e --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageHeaderMock.cs @@ -0,0 +1,71 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Fabric; +using System.Globalization; +using System.Runtime.Serialization; +using Microsoft.ServiceFabric.Services.Remoting.V2; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +internal class ServiceRemotingRequestMessageHeaderMock : IServiceRemotingRequestMessageHeader +{ + [DataMember(Name = "Headers", IsRequired = true, Order = 2)] + private readonly Dictionary headers = new Dictionary(); + + public ServiceRemotingRequestMessageHeaderMock() + { + this.InvocationId = null; + } + + /// + /// Gets or sets the methodId of the remote method. + /// + [DataMember(Name = "MethodId", IsRequired = true, Order = 0)] + public int MethodId { get; set; } + + /// + /// Gets or sets the interface id of the remote interface. + /// + [DataMember(Name = "InterfaceId", IsRequired = true, Order = 1)] + public int InterfaceId { get; set; } + + /// + /// Gets or sets identifier for the remote method invocation. + /// + [DataMember(Name = "InvocationId", IsRequired = false, Order = 3, EmitDefaultValue = false)] + public string? InvocationId { get; set; } + + /// + /// Gets or sets the method name of the remote method. + /// + [DataMember(Name = "MethodName", IsRequired = false, Order = 4)] + public string? MethodName { get; set; } + + /// + /// Gets or sets the request id. + /// + [DataMember(Name = "RequestId", IsRequired = false, Order = 5)] + public Guid RequestId { get; set; } + + public void AddHeader(string headerName, byte[] headerValue) + { + if (this.headers.ContainsKey(headerName)) + { + throw new FabricElementAlreadyExistsException(string.Format((IFormatProvider)(object)CultureInfo.CurrentCulture, "ErrorHeaderAlreadyExists")); + } + + this.headers[headerName] = headerValue; + } + + public bool TryGetHeaderValue(string headerName, out byte[]? headerValue) + { + headerValue = null; + if (this.headers == null) + { + return false; + } + + return this.headers.TryGetValue(headerName, out headerValue); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageMock.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageMock.cs new file mode 100644 index 0000000000..65a81fde09 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingRequestMessageMock.cs @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Microsoft.ServiceFabric.Services.Remoting.V2; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +internal class ServiceRemotingRequestMessageMock : IServiceRemotingRequestMessage +{ + private readonly IServiceRemotingRequestMessageHeader header; + + private readonly IServiceRemotingRequestMessageBody msgBody; + + public ServiceRemotingRequestMessageMock(IServiceRemotingRequestMessageHeader header, IServiceRemotingRequestMessageBody msgBody) + { + this.header = header; + this.msgBody = msgBody; + } + + public IServiceRemotingRequestMessageHeader GetHeader() + { + return this.header; + } + + public IServiceRemotingRequestMessageBody GetBody() + { + return this.msgBody; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingResponseMessageHeaderMock.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingResponseMessageHeaderMock.cs new file mode 100644 index 0000000000..ba8eef9619 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/Mocks/ServiceRemotingResponseMessageHeaderMock.cs @@ -0,0 +1,49 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Fabric; +using System.Globalization; +using Microsoft.ServiceFabric.Services.Remoting.V2; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +internal class ServiceRemotingResponseMessageHeaderMock : IServiceRemotingResponseMessageHeader +{ + private Dictionary headers; + + public ServiceRemotingResponseMessageHeaderMock() + { + this.headers = new Dictionary(); + } + + public void AddHeader(string headerName, byte[] headerValue) + { + if (this.headers.ContainsKey(headerName)) + { + throw new FabricElementAlreadyExistsException(string.Format((IFormatProvider)(object)CultureInfo.CurrentCulture, "ErrorHeaderAlreadyExists")); + } + + this.headers[headerName] = headerValue; + } + + public bool CheckIfItsEmpty() + { + if (this.headers == null || this.headers.Count == 0) + { + return true; + } + + return false; + } + + public bool TryGetHeaderValue(string headerName, out byte[]? headerValue) + { + headerValue = null; + if (this.headers == null) + { + return false; + } + + return this.headers.TryGetValue(headerName, out headerValue); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActor.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActor.cs new file mode 100644 index 0000000000..168cc0c08e --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActor.cs @@ -0,0 +1,31 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using Microsoft.ServiceFabric.Actors; +using Microsoft.ServiceFabric.Actors.Runtime; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public class MyTestActor : Actor, IMyTestActor +{ + public MyTestActor(ActorService actorService, ActorId actorId) + : base(actorService, actorId) + { + } + + public Task TestContextPropagation(string valueToReturn) + { + ActivityContext activityContext = Activity.Current!.Context; + Baggage baggage = Baggage.Current; + + ServiceResponse serviceResponse = new ServiceResponse + { + ParameterValue = valueToReturn, + ActivityContext = activityContext, + Baggage = baggage, + }; + + return Task.FromResult(serviceResponse); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActorService.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActorService.cs new file mode 100644 index 0000000000..330bd42159 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestActorService.cs @@ -0,0 +1,62 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Fabric; +using Microsoft.ServiceFabric.Actors; +using Microsoft.ServiceFabric.Actors.Remoting.V2.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Actors.Remoting.V2.Runtime; +using Microsoft.ServiceFabric.Actors.Runtime; +using Microsoft.ServiceFabric.Services.Communication.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2.Runtime; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public class MyTestActorService : ActorService, IMyTestActorService +{ + private static readonly Guid ActorId = Guid.Parse("{1F263E8C-78D4-4D91-AAE6-C4B9CE03D6EB}"); + + private readonly ServiceRemotingMessageDispatcherAdapter dispatcher; + private MyTestActor actor; + + public MyTestActorService(StatefulServiceContext context, ActorTypeInformation actorTypeInfo, Func? actorFactory = null, Func? stateManagerFactory = null, IActorStateProvider? stateProvider = null, ActorServiceSettings? settings = null) + : base(context, actorTypeInfo, actorFactory, stateManagerFactory, stateProvider, settings) + { + ActorServiceRemotingDispatcher actorServiceRemotingDispatcher = new ActorServiceRemotingDispatcher(this, serviceRemotingRequestMessageBodyFactory: null); + + this.dispatcher = new ServiceRemotingMessageDispatcherAdapter(actorServiceRemotingDispatcher); + + ActorId id = new ActorId(ActorId); + this.actor = new MyTestActor(this, id); + } + + public IServiceRemotingMessageHandler Dispatcher + { + get { return this.dispatcher; } + } + + public MyTestActor Actor + { + get { return this.actor; } + } + + public Task TestContextPropagation(string valueToReturn) + { + return this.actor.TestContextPropagation(valueToReturn); + } + + protected override IEnumerable CreateServiceReplicaListeners() + { + Func getListenerFunc = () => + { + FabricTransportRemotingListenerSettings listenerSettings = new FabricTransportRemotingListenerSettings(); + + return new FabricTransportActorServiceRemotingListener(this, this.dispatcher, listenerSettings); + }; + + ServiceReplicaListener serviceReplicaListener = new ServiceReplicaListener((StatefulServiceContext t) => getListenerFunc(), "V2Listener"); + + return [serviceReplicaListener]; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestStatefulService.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestStatefulService.cs new file mode 100644 index 0000000000..f3fbbd315f --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/MyTestStatefulService.cs @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Fabric; +using Microsoft.ServiceFabric.Data; +using Microsoft.ServiceFabric.Services.Communication.Runtime; +using Microsoft.ServiceFabric.Services.Remoting; +using Microsoft.ServiceFabric.Services.Remoting.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2.FabricTransport.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2.Runtime; +using Microsoft.ServiceFabric.Services.Runtime; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public class MyTestStatefulService : StatefulService, ITestMyStatefulService +{ + private IServiceRemotingMessageHandler? dispatcher; + + public MyTestStatefulService(StatefulServiceContext serviceContext, IReliableStateManagerReplica reliableStateManagerReplica) + : base(serviceContext, reliableStateManagerReplica) + { + } + + public Task TestContextPropagation(string valueToReturn) + { + ActivityContext activityContext = Activity.Current!.Context; + Baggage baggage = Baggage.Current; + + ServiceResponse serviceResponse = new ServiceResponse + { + ParameterValue = valueToReturn, + ActivityContext = activityContext, + Baggage = baggage, + }; + + return Task.FromResult(serviceResponse); + } + + internal void SetDispatcher(IServiceRemotingMessageHandler dispatcher) + { + this.dispatcher = dispatcher; + } + + protected override IEnumerable CreateServiceReplicaListeners() + { + Func getListenerFunc = (ServiceContext serviceContext, IService serviceImplementation) => + { + FabricTransportRemotingListenerSettings listenerSettings = new FabricTransportRemotingListenerSettings(); + + return new FabricTransportServiceRemotingListener(serviceContext, this.dispatcher, listenerSettings); + }; + + ServiceReplicaListener serviceReplicaListener = new ServiceReplicaListener((StatefulServiceContext t) => getListenerFunc(this.ServiceContext, this), "V2Listener"); + + return [serviceReplicaListener]; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests.csproj b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests.csproj new file mode 100644 index 0000000000..79b9bbf971 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests.csproj @@ -0,0 +1,30 @@ + + + + + $(SupportedNetTargets) + $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) + + + + + None + + + + + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricRemotingTests.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricRemotingTests.cs new file mode 100644 index 0000000000..e93e46ff40 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricRemotingTests.cs @@ -0,0 +1,174 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; +using System.Fabric; +using System.Reflection; +using System.Text; +using Microsoft.ServiceFabric.Actors; +using Microsoft.ServiceFabric.Actors.Runtime; +using Microsoft.ServiceFabric.Services.Remoting.V2; +using Microsoft.ServiceFabric.Services.Remoting.V2.Runtime; +using OpenTelemetry.Context.Propagation; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; +using ServiceFabric.Mocks; +using ServiceFabric.Mocks.RemotingV2; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public class ServiceFabricRemotingTests +{ + private const string ValueToSend = "SomeValue"; + private const string BaggageKey = "SomeBaggageKey"; + private const string BaggageValue = "SomeBaggageValue"; + private static readonly ActivitySource ActivitySource = new ActivitySource("ServiceFabricRemotingTests"); + + [Fact] + public async Task TestStatefulServiceContextPropagation_ShouldExtractActivityContextAndBaggage() + { + // Arrange + using TracerProvider provider = Sdk.CreateTracerProviderBuilder() + .AddServiceFabricRemotingInstrumentation() + .Build(); + + TextMapPropagator propagator = Propagators.DefaultTextMapPropagator; + + StatefulServiceContext serviceContext = MockStatefulServiceContextFactory.Default; + MockReliableStateManager reliableStateManager = new MockReliableStateManager(); + + // We need to create the service, then the dispatcher, and then set the dispatcher on the service, because the dispatcher needs the service as an argument, and the service needs the dispatcher. + MyTestStatefulService myStatefulService = new MyTestStatefulService(serviceContext, reliableStateManager); + ServiceRemotingMessageDispatcher serviceRemotingMessageDispatcher = new ServiceRemotingMessageDispatcher(serviceContext, myStatefulService); + ServiceRemotingMessageDispatcherAdapter dispatcherAdapter = new ServiceRemotingMessageDispatcherAdapter(serviceRemotingMessageDispatcher); + myStatefulService.SetDispatcher(dispatcherAdapter); + + // We create an ActivityContext and Baggage to inject into the request message, instead of starting a new Activity, because the dispatcher is in the same process as the test, and we don't want to set Activity.Current. + ActivityContext activityContext = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); + Baggage baggage = Baggage.Create(new Dictionary { { BaggageKey, BaggageValue } }); + + IServiceRemotingRequestMessageHeader remotingRequestMessageHeader = this.CreateServiceRemotingRequestMessageHeader(typeof(ITestMyStatefulService), nameof(ITestMyStatefulService.TestContextPropagation)); + + propagator.Inject(new PropagationContext(activityContext, baggage), remotingRequestMessageHeader, ServiceFabricRemotingUtils.InjectTraceContextIntoServiceRemotingRequestMessageHeader); + + MockServiceRemotingRequestMessageBody messageBody = new MockServiceRemotingRequestMessageBody(); + messageBody.SetParameter(0, "valueToReturn", ValueToSend); + + ServiceRemotingRequestMessageMock requestMessage = new(remotingRequestMessageHeader, messageBody); + FabricTransportServiceRemotingRequestContextMock remotingRequestContext = new FabricTransportServiceRemotingRequestContextMock(); + + // Act + IServiceRemotingResponseMessage response = await dispatcherAdapter.HandleRequestResponseAsync(remotingRequestContext, requestMessage); + + // Assert + ServiceResponse serviceResponse = (ServiceResponse)response.GetBody().Get(typeof(ServiceResponse)); + + Assert.Equal(ValueToSend, serviceResponse.ParameterValue); + Assert.Equal(activityContext.TraceId, serviceResponse.ActivityContext.TraceId); + Assert.Equal(BaggageValue, serviceResponse.Baggage.GetBaggage(BaggageKey)); + } + + [Fact] + public async Task TestActorContextPropagation_ShouldExtractActivityContextAndBaggage() + { + // Arrange + using TracerProvider provider = Sdk.CreateTracerProviderBuilder() + .AddServiceFabricRemotingInstrumentation() + .Build(); + + TextMapPropagator propagator = Propagators.DefaultTextMapPropagator; + + // We have to include the method 'TestContextPropagation' in the interface IMyTestActorService a redirected it to the actor because the normal flow in the base classes is not unit-testable. + // This still allows us to test what we want to test here, which is the method 'HandleRequestResponseAsync' in TraceContextEnrichedActorServiceV2RemotingDispatcher. + Func actorFactory = (service, actorId) => ((MyTestActorService)service).Actor; + MyTestActorService actorService = MockActorServiceFactory.CreateCustomActorServiceForActor(actorFactory); + + // We create an ActivityContext and Baggage to inject into the request message, instead of starting a new Activity, because the dispatcher is in the same process as the test, and we don't want to set Activity.Current. + ActivityContext activityContext = new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); + Baggage baggage = Baggage.Create(new Dictionary { { BaggageKey, BaggageValue } }); + + IServiceRemotingRequestMessageHeader actorRemotingMessageHeaders = this.CreateServiceRemotingRequestMessageHeader(typeof(IMyTestActorService), nameof(IMyTestActorService.TestContextPropagation)); + + propagator.Inject(new PropagationContext(activityContext, baggage), actorRemotingMessageHeaders, ServiceFabricRemotingUtils.InjectTraceContextIntoServiceRemotingRequestMessageHeader); + + MockServiceRemotingRequestMessageBody messageBody = new MockServiceRemotingRequestMessageBody(); + messageBody.SetParameter(0, "valueToReturn", ValueToSend); + + ServiceRemotingRequestMessageMock requestMessage = new(actorRemotingMessageHeaders, messageBody); + FabricTransportServiceRemotingRequestContextMock remotingRequestContext = new FabricTransportServiceRemotingRequestContextMock(); + + // Act + IServiceRemotingResponseMessage response = await actorService.Dispatcher.HandleRequestResponseAsync(remotingRequestContext, requestMessage); + + // Assert + ServiceResponse serviceResponse = (ServiceResponse)response.GetBody().Get(typeof(ServiceResponse)); + + Assert.Equal(ValueToSend, serviceResponse.ParameterValue); + Assert.Equal(activityContext.TraceId, serviceResponse.ActivityContext.TraceId); + Assert.Equal(BaggageValue, serviceResponse.Baggage.GetBaggage(BaggageKey)); + } + + [Fact] + public async Task TestServiceRemotingClientContextPropagation_ShouldInjectActivityContextAndBaggage() + { + // Arrange + using TracerProvider provider = Sdk.CreateTracerProviderBuilder() + .AddServiceFabricRemotingInstrumentation() + .AddSource(ActivitySource.Name) + .Build(); + + // The Baggage set here will be used automatically by TraceContextEnrichedServiceRemotingClientAdapter to inject the baggage into the request message. + Baggage.SetBaggage(BaggageKey, BaggageValue); + + // The activity is created here will be used automatically by TraceContextEnrichedServiceRemotingClientAdapter to inject the context into the request message. + using (Activity activity = ActivitySource.StartActivity("TestActivity")!) + { + ServiceRemotingRequestMessageHeaderMock header = new ServiceRemotingRequestMessageHeaderMock(); + MockServiceRemotingRequestMessageBody messageBody = new MockServiceRemotingRequestMessageBody(); + ServiceRemotingRequestMessageMock requestMessage = new(header, messageBody); + + // The ServiceRemotingClientMock reads the headers from the request and injects them into the response, using OpneTelemetry's TextMapPropagator. + ServiceRemotingClientMock innerClient = new ServiceRemotingClientMock(); + TraceContextEnrichedServiceRemotingClientAdapter serviceRemotingClientAdapter = new TraceContextEnrichedServiceRemotingClientAdapter(innerClient); + + // Act + IServiceRemotingResponseMessage response = await serviceRemotingClientAdapter.RequestResponseAsync(requestMessage); + + // Assert + IServiceRemotingResponseMessageHeader responseMessageHeaders = response.GetHeader(); + PropagationContext propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, responseMessageHeaders, this.ExtractTraceContextFromRequestMessageHeader); + + Assert.Equal(activity.TraceId, propagationContext.ActivityContext.TraceId); + Assert.Equal(BaggageValue, propagationContext.Baggage.GetBaggage(BaggageKey)); + } + } + + private ServiceRemotingRequestMessageHeaderMock CreateServiceRemotingRequestMessageHeader(Type interfaceType, string methodName) + { + int interfaceId = ServiceFabricUtils.GetInterfaceId(interfaceType); + + MethodInfo methodInfo = interfaceType.GetMethod(methodName)!; + int methodId = ServiceFabricUtils.GetMethodId(methodInfo); + + ServiceRemotingRequestMessageHeaderMock serviceRemotingRequestMessageHeader = new ServiceRemotingRequestMessageHeaderMock + { + InterfaceId = interfaceId, + MethodId = methodId, + }; + + return serviceRemotingRequestMessageHeader; + } + + private IEnumerable ExtractTraceContextFromRequestMessageHeader(IServiceRemotingResponseMessageHeader responseMessageHeaders, string headerKey) + { + if (responseMessageHeaders.TryGetHeaderValue(headerKey, out byte[] headerValueAsBytes)) + { + string headerValue = Encoding.UTF8.GetString(headerValueAsBytes); + + return [headerValue]; + } + + return Enumerable.Empty(); + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricUtils.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricUtils.cs new file mode 100644 index 0000000000..19a780ef1d --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceFabricUtils.cs @@ -0,0 +1,81 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Reflection; +using System.Text; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +internal static class ServiceFabricUtils +{ + private static readonly ulong[] Crc64Table = new ulong[256] + { + 0uL, 4823603603198064275uL, 9647207206396128550uL, 14344283933443513269uL, 5274672035359026399uL, 847670339082705484uL, 14759040976900489721uL, 10241823793177474922uL, 10549344070718052798uL, 15030250704074698541uL, + 1695340678165410968uL, 6158653484774949387uL, 15804726273676621153uL, 11071337880091427826uL, 6824194888265062471uL, 2036903512645398228uL, 7367177604490692079uL, 2651944067726553980uL, 16419204125234161865uL, 11613757334439845466uL, + 3390681356330821936uL, 7926053118503640995uL, 12317306969549898774uL, 16726154088988619397uL, 17607865585094646865uL, 13162708473643690690uL, 8194994013375312247uL, 3695931686473304036uL, 13648389776530124942uL, 18417527692557321757uL, + 4073807025290796456uL, 8825348881154370363uL, 14734355208981384158uL, 10271039580541631821uL, 5303888135453107960uL, 822984195088142443uL, 9604374506261047041uL, 14391664176758772114uL, 47380625301539367uL, 4780770595170139316uL, + 6781362712661643872uL, 2084283301222999283uL, 15852106237007281990uL, 11028505464239851989uL, 1670654249350217407uL, 6187869865390245932uL, 10578560694269006745uL, 15005564104267687178uL, 12269926345859042865uL, 16768987096479742114uL, + 3433514057002836759uL, 7878672873577829764uL, 16389988026750624494uL, 11638443477897467005uL, 7391863372946608072uL, 2622728278751721819uL, 4044590402276644751uL, 8850035479350698268uL, 13673076206955870889uL, 18388311311405091898uL, + 8147614050581592912uL, 3738764100714335683uL, 17650697762308740726uL, 13115328684529279205uL, 15709965168302367023uL, 11021966344253216700uL, 6909860770376862729uL, 2095335087373712026uL, 10607776270906215920uL, 15115916238825782115uL, + 1645968390176284886uL, 6063892853452478021uL, 5216239979862816913uL, 762004938812542466uL, 14808413130408695223uL, 10336584279807992612uL, 94761250603078734uL, 4872975272980325085uL, 9561541190340278632uL, 14285852213486374907uL, + 13562725425323287744uL, 18359094313119879763uL, 4168566602445998566uL, 8874722219015798645uL, 17657238303940757535uL, 13257468400305012364uL, 8136561383943382329uL, 3610266854770152362uL, 3341308498700434814uL, 7831293060043656173uL, + 12375739730780491864uL, 16811819059476047563uL, 7452841817450123681uL, 2710377314828461874uL, 16324444680414493831uL, 11564384134825822740uL, 1621282580641819377uL, 6093108618008534114uL, 10636992411005044695uL, 15091230119249932612uL, + 6867028114005673518uL, 2142715359940571325uL, 15757345747155659528uL, 10979133309658045851uL, 9518708972583580495uL, 14333231979791697372uL, 142141253402664553uL, 4830142882085382394uL, 14783726745893216144uL, 10365800689136969987uL, + 5245456557503443638uL, 737318311902463013uL, 8089180804553289502uL, 3653099890976004493uL, 17700070958701396536uL, 13210088128275084459uL, 4139350461810230209uL, 8899408340202190162uL, 13587411233247080167uL, 18329878549100632180uL, + 16295228101163185824uL, 11589070762272702515uL, 7477528201428671366uL, 2681160907110034709uL, 12328359726370364031uL, 16854651450907929836uL, 3384140715920324441uL, 7783913295349006794uL, 17796789492404876493uL, 12973186262895182430uL, + 8294265019745835499uL, 3597188614796881784uL, 13819721540753725458uL, 18246723593521770113uL, 4190670174747424052uL, 8707887697765516199uL, 7249714899603402099uL, 2768808468102880224uL, 16248400991498780757uL, 11785088403942012614uL, + 3291936780352569772uL, 8025325358597240639uL, 12127785706904956042uL, 16915077318774037017uL, 10432479959725633826uL, 15147713122803500977uL, 1524009877625084932uL, 6329456346323069591uL, 15705454305770282493uL, 11170082187107838830uL, + 6635271944638132443uL, 2226424485906433608uL, 189522501206157468uL, 4634679410803088911uL, 9745950545960650170uL, 14245012653811987241uL, 5445476407655580739uL, 676338306971005648uL, 14876502445374089573uL, 10124960353263198198uL, + 4215391513593610003uL, 8678706776937023872uL, 13790540925671641653uL, 18271444552530207910uL, 8337133204891997132uL, 3549843186494580063uL, 17749444438031597290uL, 13016054137459951737uL, 12170653315997410989uL, 16867732534171963454uL, + 3244592164593781643uL, 8068192726900473112uL, 16273122767886764658uL, 11755906975779290337uL, 7220533709540304724uL, 2793530071884239303uL, 6682616997400869628uL, 2183556611878603887uL, 15662586120087312346uL, 11217427617020813641uL, + 1553190491096487459uL, 6304735387851432112uL, 10407758620342516485uL, 15176894045242543510uL, 14905683634900247362uL, 10100238751092381137uL, 5420754629656923748uL, 705519735670536439uL, 9793295161182637981uL, 14202145287119436046uL, + 146654890503152315uL, 4682024195942093864uL, 3242565161283638754uL, 7930564333232481137uL, 12186217236017068228uL, 17000743249723264599uL, 7335380351123765565uL, 2827240748300537774uL, 16153640314560107547uL, 11735716164790313608uL, + 13734056228011347036uL, 18188291445129067215uL, 4285430719881142650uL, 8757259798139230185uL, 17846161249714921603uL, 13067947420601767440uL, 8235833358291897765uL, 3511522545606540086uL, 5387043107155988493uL, 590673871457609374uL, + 14925875833148783915uL, 10219719885873843128uL, 284282506805329106uL, 4684052045342640705uL, 9660285764170764788uL, 14186579979835500391uL, 15610694155489642931uL, 11120709418076880672uL, 6720936860919424149uL, 2284857304564388358uL, + 10490913115006887276uL, 15233377424362361855uL, 1474636623804926026uL, 6234696958930763481uL, 16178361609106579004uL, 11706535215248140463uL, 7306199781952008986uL, 2851961734412043657uL, 12229085463316509411uL, 16953397843693241456uL, + 3195220067441434565uL, 7973432182840617302uL, 8278700923620460418uL, 3464177731752866065uL, 17798816680404380324uL, 13110814815472245815uL, 4310152537884486493uL, 8728078392784608718uL, 13704874997943502459uL, 18213013024491712744uL, + 9707630858549910483uL, 14143712128616820032uL, 241414281116563189uL, 4731397450835853414uL, 14955056402857342732uL, 10194998898151653791uL, 5362321814220069418uL, 619854820462849209uL, 1503817855483314797uL, 6209975379031176446uL, + 10466191297540353867uL, 15262558828106308056uL, 6768281431840648882uL, 2241989909157107745uL, 15567826590698013588uL, 11168054230320002311uL, + }; + + internal static int GetInterfaceId(Type type) + { + string text = ((MemberInfo)type).Name; + if (type.Namespace != null) + { + text = string.Concat(type.Namespace, text); + } + + int interfaceId = (int)ToCRC64(Encoding.UTF8.GetBytes(text)); + return interfaceId; + } + + internal static int GetMethodId(MethodInfo methodInfo) + { + string text = methodInfo.Name; + if (methodInfo.DeclaringType != null) + { + if (methodInfo.DeclaringType.Namespace != null) + { + text = methodInfo.DeclaringType.Namespace + text; + } + + text = methodInfo.DeclaringType.Name + text; + } + + int methodId = (int)ToCRC64(Encoding.UTF8.GetBytes(text)); + return methodId; + } + + private static ulong ToCRC64(byte[] value) + { + ulong num = 18446744073709551615uL; + for (int i = 0; i < value.Length; i++) + { + uint num2 = (uint)((int)(num >> 56) ^ value[i]) & 0xFFu; + num = Crc64Table[num2] ^ (num << 8); + } + + return num ^ 0xFFFFFFFFFFFFFFFFuL; + } +} diff --git a/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceResponse.cs b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceResponse.cs new file mode 100644 index 0000000000..c2f8a37efd --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests/ServiceResponse.cs @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Diagnostics; + +namespace OpenTelemetry.Instrumentation.ServiceFabricRemoting.Tests; + +public class ServiceResponse +{ + public string? ParameterValue { get; set; } + + public ActivityContext ActivityContext { get; set; } + + public Baggage Baggage { get; set; } +} From ff566186bf8269c2d9ce8a2b47177a2f5705f840 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 21:30:10 +0100 Subject: [PATCH 1481/1499] Bump dotnet-sdk from 9.0.100 to 9.0.101 (#2427) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz --- .github/workflows/ci.yml | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f7318acb0..bf1bc6ba96 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: filters: | md: [ '**.md' ] yml: [ '**.yml', '**.yaml', '.yamllint' ] - build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*', '**/*.targets', '**/*.props'] + build: ['build/**', '.github/**/*.yml', '!.github/workflows/package-*', '**/*.targets', '**/*.props', 'global.json'] shared: ['src/Shared/**', 'test/Shared/**'] contrib-shared-tests: ['test/OpenTelemetry.Contrib.Shared.Tests/**'] code: ['**.cs', '**.csproj', '.editorconfig'] diff --git a/global.json b/global.json index 6a79b98070..df28660f8e 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestFeature", - "version": "9.0.100" + "version": "9.0.101" } } From f7987b5a976f7b363aaebc24e87d2fa4d63d5c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Tue, 17 Dec 2024 21:46:08 +0100 Subject: [PATCH 1482/1499] [SemanticConvention] Bump to v1.29.0 (#2428) --- .../.publicApi/PublicAPI.Unshipped.txt | 87 ++++++++ .../Attributes/AwsAttributes.cs | 3 - .../Attributes/CicdAttributes.cs | 4 +- .../Attributes/CloudAttributes.cs | 1 - .../Attributes/CloudfoundryAttributes.cs | 2 +- .../Attributes/DbAttributes.cs | 116 +++++++++- .../Attributes/DeploymentAttributes.cs | 1 - .../Attributes/ErrorAttributes.cs | 1 - .../Attributes/FaasAttributes.cs | 2 - .../Attributes/FeatureFlagAttributes.cs | 86 +++++++- .../Attributes/GenAiAttributes.cs | 37 +++- .../Attributes/GeoAttributes.cs | 92 ++++++++ .../Attributes/K8sAttributes.cs | 2 - .../Attributes/NetworkAttributes.cs | 15 +- .../Attributes/ProcessAttributes.cs | 14 ++ .../Attributes/ServiceAttributes.cs | 2 +- .../Attributes/TestAttributes.cs | 4 +- .../Attributes/UrlAttributes.cs | 41 +++- .../Attributes/UserAgentAttributes.cs | 24 +++ .../Attributes/VcsAttributes.cs | 200 +++++++++++++++++- .../CHANGELOG.md | 3 + .../scripts/generate.ps1 | 4 +- .../scripts/generate.sh | 4 +- 23 files changed, 689 insertions(+), 56 deletions(-) create mode 100644 src/OpenTelemetry.SemanticConventions/Attributes/GeoAttributes.cs diff --git a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt index 3e05247004..16c48b3ec7 100644 --- a/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.SemanticConventions/.publicApi/PublicAPI.Unshipped.txt @@ -193,8 +193,10 @@ const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCollectionName = const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbConnectionString = "db.connection_string" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbClientId = "db.cosmosdb.client_id" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbConsistencyLevel = "db.cosmosdb.consistency_level" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbContainer = "db.cosmosdb.container" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRegionsContacted = "db.cosmosdb.regions_contacted" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbCosmosdbStatusCode = "db.cosmosdb.status_code" -> string! @@ -211,9 +213,12 @@ const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbNamespace = "db. const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperation = "db.operation" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationBatchSize = "db.operation.batch.size" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationName = "db.operation.name" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbOperationParameterTemplate = "db.operation.parameter" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryParameterTemplate = "db.query.parameter" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQuerySummary = "db.query.summary" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbQueryText = "db.query.text" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbRedisDatabaseIndex = "db.redis.database_index" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbResponseReturnedRows = "db.response.returned_rows" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbResponseStatusCode = "db.response.status_code" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbSqlTable = "db.sql.table" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.AttributeDbStatement = "db.statement" -> string! @@ -236,6 +241,11 @@ const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValu const OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValues.Used = "used" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Direct = "direct" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues.Gateway = "gateway" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConsistencyLevelValues.BoundedStaleness = "BoundedStaleness" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConsistencyLevelValues.ConsistentPrefix = "ConsistentPrefix" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConsistencyLevelValues.Eventual = "Eventual" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConsistencyLevelValues.Session = "Session" -> string! +const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConsistencyLevelValues.Strong = "Strong" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Batch = "batch" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Create = "create" -> string! const OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues.Delete = "delete" -> string! @@ -367,9 +377,23 @@ const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Http = const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Other = "other" -> string! const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Pubsub = "pubsub" -> string! const OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues.Timer = "timer" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagContextId = "feature_flag.context.id" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagEvaluationErrorMessage = "feature_flag.evaluation.error.message" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagEvaluationReason = "feature_flag.evaluation.reason" -> string! const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagKey = "feature_flag.key" -> string! const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagProviderName = "feature_flag.provider_name" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagSetId = "feature_flag.set.id" -> string! const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagVariant = "feature_flag.variant" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.AttributeFeatureFlagVersion = "feature_flag.version" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Cached = "cached" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Default = "default" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Disabled = "disabled" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Error = "error" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Split = "split" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Stale = "stale" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Static = "static" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.TargetingMatch = "targeting_match" -> string! +const OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues.Unknown = "unknown" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileAccessed = "file.accessed" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileAttributes = "file.attributes" -> string! const OpenTelemetry.SemanticConventions.FileAttributes.AttributeFileChanged = "file.changed" -> string! @@ -398,8 +422,10 @@ const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiRequ const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiRequestSeed = "gen_ai.openai.request.seed" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiRequestServiceTier = "gen_ai.openai.request.service_tier" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiResponseServiceTier = "gen_ai.openai.response.service_tier" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOpenaiResponseSystemFingerprint = "gen_ai.openai.response.system_fingerprint" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiOperationName = "gen_ai.operation.name" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiPrompt = "gen_ai.prompt" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestEncodingFormats = "gen_ai.request.encoding_formats" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestFrequencyPenalty = "gen_ai.request.frequency_penalty" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestMaxTokens = "gen_ai.request.max_tokens" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.AttributeGenAiRequestModel = "gen_ai.request.model" -> string! @@ -423,13 +449,31 @@ const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestRespon const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestServiceTierValues.Auto = "auto" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestServiceTierValues.Default = "default" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.Chat = "chat" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.Embeddings = "embeddings" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues.TextCompletion = "text_completion" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Anthropic = "anthropic" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.AwsBedrock = "aws.bedrock" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.AzAiInference = "az.ai.inference" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Cohere = "cohere" -> string! +const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.IbmWatsonxAi = "ibm.watsonx.ai" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.Openai = "openai" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues.VertexAi = "vertex_ai" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues.Completion = "output" -> string! const OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues.Input = "input" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoContinentCode = "geo.continent.code" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoCountryIsoCode = "geo.country.iso_code" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoLocalityName = "geo.locality.name" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoLocationLat = "geo.location.lat" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoLocationLon = "geo.location.lon" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoPostalCode = "geo.postal_code" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.AttributeGeoRegionIsoCode = "geo.region.iso_code" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.Af = "AF" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.An = "AN" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.As = "AS" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.Eu = "EU" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.Na = "NA" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.Oc = "OC" -> string! +const OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues.Sa = "SA" -> string! const OpenTelemetry.SemanticConventions.GoAttributes.AttributeGoMemoryType = "go.memory.type" -> string! const OpenTelemetry.SemanticConventions.GoAttributes.GoMemoryTypeValues.Other = "other" -> string! const OpenTelemetry.SemanticConventions.GoAttributes.GoMemoryTypeValues.Stack = "stack" -> string! @@ -706,6 +750,7 @@ const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrie const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkCarrierName = "network.carrier.name" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionSubtype = "network.connection.subtype" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkConnectionType = "network.connection.type" -> string! +const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkInterfaceName = "network.interface.name" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkIoDirection = "network.io.direction" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalAddress = "network.local.address" -> string! const OpenTelemetry.SemanticConventions.NetworkAttributes.AttributeNetworkLocalPort = "network.local.port" -> string! @@ -793,6 +838,7 @@ const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCpuSta const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessCreationTime = "process.creation.time" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdGnu = "process.executable.build_id.gnu" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdGo = "process.executable.build_id.go" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdHtlhash = "process.executable.build_id.htlhash" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableBuildIdProfiling = "process.executable.build_id.profiling" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutableName = "process.executable.name" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExecutablePath = "process.executable.path" -> string! @@ -800,6 +846,7 @@ const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExitCo const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessExitTime = "process.exit.time" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessGroupLeaderPid = "process.group_leader.pid" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessInteractive = "process.interactive" -> string! +const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessLinuxCgroup = "process.linux.cgroup" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessOwner = "process.owner" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessPagingFaultType = "process.paging.fault_type" -> string! const OpenTelemetry.SemanticConventions.ProcessAttributes.AttributeProcessParentPid = "process.parent_pid" -> string! @@ -1047,7 +1094,10 @@ const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTemplate = "ur const OpenTelemetry.SemanticConventions.UrlAttributes.AttributeUrlTopLevelDomain = "url.top_level_domain" -> string! const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentName = "user_agent.name" -> string! const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentOriginal = "user_agent.original" -> string! +const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentSyntheticType = "user_agent.synthetic.type" -> string! const OpenTelemetry.SemanticConventions.UserAgentAttributes.AttributeUserAgentVersion = "user_agent.version" -> string! +const OpenTelemetry.SemanticConventions.UserAgentAttributes.UserAgentSyntheticTypeValues.Bot = "bot" -> string! +const OpenTelemetry.SemanticConventions.UserAgentAttributes.UserAgentSyntheticTypeValues.Test = "test" -> string! const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserEmail = "user.email" -> string! const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserFullName = "user.full_name" -> string! const OpenTelemetry.SemanticConventions.UserAttributes.AttributeUserHash = "user.hash" -> string! @@ -1065,14 +1115,40 @@ const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.L const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.MapSpace = "map_space" -> string! const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.NewSpace = "new_space" -> string! const OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues.OldSpace = "old_space" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsChangeId = "vcs.change.id" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsChangeState = "vcs.change.state" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsChangeTitle = "vcs.change.title" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsLineChangeType = "vcs.line_change.type" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefBaseName = "vcs.ref.base.name" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefBaseRevision = "vcs.ref.base.revision" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefBaseType = "vcs.ref.base.type" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefHeadName = "vcs.ref.head.name" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefHeadRevision = "vcs.ref.head.revision" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefHeadType = "vcs.ref.head.type" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRefType = "vcs.ref.type" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryChangeId = "vcs.repository.change.id" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryChangeTitle = "vcs.repository.change.title" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryRefName = "vcs.repository.ref.name" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryRefRevision = "vcs.repository.ref.revision" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryRefType = "vcs.repository.ref.type" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRepositoryUrlFull = "vcs.repository.url.full" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.AttributeVcsRevisionDeltaDirection = "vcs.revision_delta.direction" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsChangeStateValues.Closed = "closed" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsChangeStateValues.Merged = "merged" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsChangeStateValues.Open = "open" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsChangeStateValues.Wip = "wip" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsLineChangeTypeValues.Added = "added" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsLineChangeTypeValues.Removed = "removed" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefBaseTypeValues.Branch = "branch" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefBaseTypeValues.Tag = "tag" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefHeadTypeValues.Branch = "branch" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefHeadTypeValues.Tag = "tag" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefTypeValues.Branch = "branch" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefTypeValues.Tag = "tag" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues.Branch = "branch" -> string! const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues.Tag = "tag" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRevisionDeltaDirectionValues.Ahead = "ahead" -> string! +const OpenTelemetry.SemanticConventions.VcsAttributes.VcsRevisionDeltaDirectionValues.Behind = "behind" -> string! const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineDescription = "webengine.description" -> string! const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineName = "webengine.name" -> string! const OpenTelemetry.SemanticConventions.WebengineAttributes.AttributeWebengineVersion = "webengine.version" -> string! @@ -1105,6 +1181,7 @@ OpenTelemetry.SemanticConventions.DbAttributes.DbCassandraConsistencyLevelValues OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionsStateValues OpenTelemetry.SemanticConventions.DbAttributes.DbClientConnectionStateValues OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConnectionModeValues +OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbConsistencyLevelValues OpenTelemetry.SemanticConventions.DbAttributes.DbCosmosdbOperationTypeValues OpenTelemetry.SemanticConventions.DbAttributes.DbSystemValues OpenTelemetry.SemanticConventions.DeploymentAttributes @@ -1126,6 +1203,7 @@ OpenTelemetry.SemanticConventions.FaasAttributes.FaasDocumentOperationValues OpenTelemetry.SemanticConventions.FaasAttributes.FaasInvokedProviderValues OpenTelemetry.SemanticConventions.FaasAttributes.FaasTriggerValues OpenTelemetry.SemanticConventions.FeatureFlagAttributes +OpenTelemetry.SemanticConventions.FeatureFlagAttributes.FeatureFlagEvaluationReasonValues OpenTelemetry.SemanticConventions.FileAttributes OpenTelemetry.SemanticConventions.GcpAttributes OpenTelemetry.SemanticConventions.GenAiAttributes @@ -1134,6 +1212,8 @@ OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOpenaiRequestServiceTierV OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiOperationNameValues OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiSystemValues OpenTelemetry.SemanticConventions.GenAiAttributes.GenAiTokenTypeValues +OpenTelemetry.SemanticConventions.GeoAttributes +OpenTelemetry.SemanticConventions.GeoAttributes.GeoContinentCodeValues OpenTelemetry.SemanticConventions.GoAttributes OpenTelemetry.SemanticConventions.GoAttributes.GoMemoryTypeValues OpenTelemetry.SemanticConventions.GraphqlAttributes @@ -1228,10 +1308,17 @@ OpenTelemetry.SemanticConventions.TlsAttributes OpenTelemetry.SemanticConventions.TlsAttributes.TlsProtocolNameValues OpenTelemetry.SemanticConventions.UrlAttributes OpenTelemetry.SemanticConventions.UserAgentAttributes +OpenTelemetry.SemanticConventions.UserAgentAttributes.UserAgentSyntheticTypeValues OpenTelemetry.SemanticConventions.UserAttributes OpenTelemetry.SemanticConventions.V8jsAttributes OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsGcTypeValues OpenTelemetry.SemanticConventions.V8jsAttributes.V8jsHeapSpaceNameValues OpenTelemetry.SemanticConventions.VcsAttributes +OpenTelemetry.SemanticConventions.VcsAttributes.VcsChangeStateValues +OpenTelemetry.SemanticConventions.VcsAttributes.VcsLineChangeTypeValues +OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefBaseTypeValues +OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefHeadTypeValues +OpenTelemetry.SemanticConventions.VcsAttributes.VcsRefTypeValues OpenTelemetry.SemanticConventions.VcsAttributes.VcsRepositoryRefTypeValues +OpenTelemetry.SemanticConventions.VcsAttributes.VcsRevisionDeltaDirectionValues OpenTelemetry.SemanticConventions.WebengineAttributes \ No newline at end of file diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs index 9ba5b04bd4..0c858abe9f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/AwsAttributes.cs @@ -222,7 +222,6 @@ public static class AwsAttributes /// The copy_source attribute applies to S3 copy operations and corresponds to the --copy-source parameter /// of the copy-object operation within the S3 API. /// This applies in particular to the following operations: - ///

    ///

      ///
    • copy-object
    • ///
    • upload-part-copy.
    • @@ -246,7 +245,6 @@ public static class AwsAttributes /// /// The key attribute is applicable to all object-related S3 operations, i.e. that require the object key as a mandatory parameter. /// This applies in particular to the following operations: - ///

      ///

        ///
      • copy-object
      • ///
      • delete-object
      • @@ -283,7 +281,6 @@ public static class AwsAttributes /// The upload_id attribute applies to S3 multipart-upload operations and corresponds to the --upload-id parameter /// of the S3 API multipart operations. /// This applies in particular to the following operations: - ///

        ///

          ///
        • abort-multipart-upload
        • ///
        • complete-multipart-upload
        • diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs index 3af1aed457..ea3592c798 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CicdAttributes.cs @@ -25,7 +25,7 @@ public static class CicdAttributes public const string AttributeCicdPipelineRunId = "cicd.pipeline.run.id"; /// - /// The human readable name of a task within a pipeline. Task here most closely aligns with a computing process in a pipeline. Other terms for tasks include commands, steps, and procedures. + /// The human readable name of a task within a pipeline. Task here most closely aligns with a computing process in a pipeline. Other terms for tasks include commands, steps, and procedures. /// public const string AttributeCicdPipelineTaskName = "cicd.pipeline.task.name"; @@ -35,7 +35,7 @@ public static class CicdAttributes public const string AttributeCicdPipelineTaskRunId = "cicd.pipeline.task.run.id"; /// - /// The URL of the pipeline run providing the complete address in order to locate and identify the pipeline run. + /// The URL of the pipeline run providing the complete address in order to locate and identify the pipeline run. /// public const string AttributeCicdPipelineTaskRunUrlFull = "cicd.pipeline.task.run.url.full"; diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs index c3a23ce1ff..7e6107547f 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudAttributes.cs @@ -57,7 +57,6 @@ public static class CloudAttributes ///

          /// The exact value to use for cloud.resource_id depends on the cloud provider. /// The following well-known definitions MUST be used if you set this attribute and they apply: - ///

          ///

            ///
          • AWS Lambda: The function ARN. /// Take care not to use the "invoked ARN" directly but replace any diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs index 51c841d0c6..c85b90b08d 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/CloudfoundryAttributes.cs @@ -28,7 +28,7 @@ public static class CloudfoundryAttributes /// The index of the application instance. 0 when just one instance is active. ///
    /// - /// CloudFoundry defines the instance_id in the Loggegator v2 envelope. + /// CloudFoundry defines the instance_id in the Loggregator v2 envelope. /// It is used for logs and metrics emitted by CloudFoundry. It is /// supposed to contain the application instance index for applications /// deployed on the runtime. diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs index 3c8d6ca97c..8f00575763 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DbAttributes.cs @@ -77,8 +77,13 @@ public static class DbAttributes ///
    /// /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. - /// If the collection name is parsed from the query text, it SHOULD be the first collection name found in the query and it SHOULD match the value provided in the query text including any schema and database name prefix. - /// For batch operations, if the individual operations are known to have the same collection name then that collection name SHOULD be used, otherwise db.collection.name SHOULD NOT be captured. + ///

    + /// The collection name SHOULD NOT be extracted from db.query.text, + /// unless the query format is known to only ever have a single collection name present. + ///

    + /// For batch operations, if the individual operations are known to have the same collection name + /// then that collection name SHOULD be used. + ///

    /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbCollectionName = "db.collection.name"; @@ -99,6 +104,11 @@ public static class DbAttributes ///

    public const string AttributeDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode"; + /// + /// Account or request consistency level. + /// + public const string AttributeDbCosmosdbConsistencyLevel = "db.cosmosdb.consistency_level"; + /// /// Deprecated, use db.collection.name instead. /// @@ -106,12 +116,21 @@ public static class DbAttributes public const string AttributeDbCosmosdbContainer = "db.cosmosdb.container"; /// - /// Cosmos DB Operation Type. + /// Deprecated, no replacement at this time. /// + [Obsolete("No replacement at this time.")] public const string AttributeDbCosmosdbOperationType = "db.cosmosdb.operation_type"; /// - /// RU consumed for that operation. + /// List of regions contacted during operation in the order that they were contacted. If there is more than one region listed, it indicates that the operation was performed on multiple regions i.e. cross-regional call. + /// + /// + /// Region name matches the format of displayName in Azure Location API. + /// + public const string AttributeDbCosmosdbRegionsContacted = "db.cosmosdb.regions_contacted"; + + /// + /// Request units consumed for the operation. /// public const string AttributeDbCosmosdbRequestCharge = "db.cosmosdb.request_charge"; @@ -210,23 +229,47 @@ public static class DbAttributes /// The name of the operation or command being executed. ///
    /// - /// It is RECOMMENDED to capture the value as provided by the application without attempting to do any case normalization. - /// If the operation name is parsed from the query text, it SHOULD be the first operation name found in the query. - /// For batch operations, if the individual operations are known to have the same operation name then that operation name SHOULD be used prepended by BATCH , otherwise db.operation.name SHOULD be BATCH or some other database system specific term if more applicable. + /// It is RECOMMENDED to capture the value as provided by the application + /// without attempting to do any case normalization. + ///

    + /// The operation name SHOULD NOT be extracted from db.query.text, + /// unless the query format is known to only ever have a single operation name present. + ///

    + /// For batch operations, if the individual operations are known to have the same operation name + /// then that operation name SHOULD be used prepended by BATCH , + /// otherwise db.operation.name SHOULD be BATCH or some other database + /// system specific term if more applicable. + ///

    /// This attribute has stability level RELEASE CANDIDATE. /// public const string AttributeDbOperationName = "db.operation.name"; ///

    - /// A query parameter used in db.query.text, with being the parameter name, and the attribute value being a string representation of the parameter value. + /// A database operation parameter, with being the parameter name, and the attribute value being a string representation of the parameter value. /// /// - /// Query parameters should only be captured when db.query.text is parameterized with placeholders. /// If a parameter has no name and instead is referenced only by index, then SHOULD be the 0-based index. + /// If db.query.text is also captured, then db.operation.parameter. SHOULD match up with the parameterized placeholders present in db.query.text. /// This attribute has stability level RELEASE CANDIDATE. /// + public const string AttributeDbOperationParameterTemplate = "db.operation.parameter"; + + /// + /// A query parameter used in db.query.text, with being the parameter name, and the attribute value being a string representation of the parameter value. + /// + [Obsolete("Replaced by db.operation.parameter.")] public const string AttributeDbQueryParameterTemplate = "db.query.parameter"; + /// + /// Low cardinality representation of a database query text. + /// + /// + /// db.query.summary provides static summary of the query text. It describes a class of database queries and is useful as a grouping key, especially when analyzing telemetry for database calls involving complex queries. + /// Summary may be available to the instrumentation through instrumentation hooks or other means. If it is not available, instrumentations that support query parsing SHOULD generate a summary following Generating query summary section. + /// This attribute has stability level RELEASE CANDIDATE. + /// + public const string AttributeDbQuerySummary = "db.query.summary"; + /// /// The database query being executed. /// @@ -244,6 +287,11 @@ public static class DbAttributes [Obsolete("Replaced by db.namespace.")] public const string AttributeDbRedisDatabaseIndex = "db.redis.database_index"; + /// + /// Number of rows returned by the operation. + /// + public const string AttributeDbResponseReturnedRows = "db.response.returned_rows"; + /// /// Database response status code. /// @@ -382,7 +430,7 @@ public static class DbClientConnectionsStateValues public static class DbCosmosdbConnectionModeValues { /// - /// Gateway (HTTP) connections mode. + /// Gateway (HTTP) connection. /// public const string Gateway = "gateway"; @@ -393,83 +441,129 @@ public static class DbCosmosdbConnectionModeValues } /// - /// Cosmos DB Operation Type. + /// Account or request consistency level. + /// + public static class DbCosmosdbConsistencyLevelValues + { + /// + /// strong. + /// + public const string Strong = "Strong"; + + /// + /// bounded_staleness. + /// + public const string BoundedStaleness = "BoundedStaleness"; + + /// + /// session. + /// + public const string Session = "Session"; + + /// + /// eventual. + /// + public const string Eventual = "Eventual"; + + /// + /// consistent_prefix. + /// + public const string ConsistentPrefix = "ConsistentPrefix"; + } + + /// + /// Deprecated, no replacement at this time. /// public static class DbCosmosdbOperationTypeValues { /// /// batch. /// + [Obsolete("No replacement at this time.")] public const string Batch = "batch"; /// /// create. /// + [Obsolete("No replacement at this time.")] public const string Create = "create"; /// /// delete. /// + [Obsolete("No replacement at this time.")] public const string Delete = "delete"; /// /// execute. /// + [Obsolete("No replacement at this time.")] public const string Execute = "execute"; /// /// execute_javascript. /// + [Obsolete("No replacement at this time.")] public const string ExecuteJavascript = "execute_javascript"; /// /// invalid. /// + [Obsolete("No replacement at this time.")] public const string Invalid = "invalid"; /// /// head. /// + [Obsolete("No replacement at this time.")] public const string Head = "head"; /// /// head_feed. /// + [Obsolete("No replacement at this time.")] public const string HeadFeed = "head_feed"; /// /// patch. /// + [Obsolete("No replacement at this time.")] public const string Patch = "patch"; /// /// query. /// + [Obsolete("No replacement at this time.")] public const string Query = "query"; /// /// query_plan. /// + [Obsolete("No replacement at this time.")] public const string QueryPlan = "query_plan"; /// /// read. /// + [Obsolete("No replacement at this time.")] public const string Read = "read"; /// /// read_feed. /// + [Obsolete("No replacement at this time.")] public const string ReadFeed = "read_feed"; /// /// replace. /// + [Obsolete("No replacement at this time.")] public const string Replace = "replace"; /// /// upsert. /// + [Obsolete("No replacement at this time.")] public const string Upsert = "upsert"; } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs index 692bf8b875..111a741816 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/DeploymentAttributes.cs @@ -28,7 +28,6 @@ public static class DeploymentAttributes /// the service.namespace, service.name and service.instance.id resource attributes. /// This implies that resources carrying the following attribute combinations MUST be /// considered to be identifying the same service: - ///

    ///

      ///
    • service.name=frontend, deployment.environment.name=production
    • ///
    • service.name=frontend, deployment.environment.name=staging.
    • diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs index c3924017fc..195559a5b7 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ErrorAttributes.cs @@ -34,7 +34,6 @@ public static class ErrorAttributes ///

      /// If a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes), /// it's RECOMMENDED to: - ///

      ///

        ///
      • Use a domain-specific attribute
      • ///
      • Set error.type to capture all errors, regardless of whether they are defined within the domain-specific set or not.
      • diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs index 688c78976b..6784c99315 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FaasAttributes.cs @@ -104,7 +104,6 @@ public static class FaasAttributes /// For some cloud providers, the above definition is ambiguous. The following /// definition of function name MUST be used for this attribute /// (and consequently the span name) for the listed cloud providers/products: - ///

        ///

          ///
        • Azure: The full name /, i.e., function app name /// followed by a forward slash followed by the function name (this form @@ -131,7 +130,6 @@ public static class FaasAttributes /// /// /// Depending on the cloud provider and platform, use: - ///

          ///

            ///
          • AWS Lambda: The function version /// (an integer represented as a decimal string).
          • diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs index 9c56474985..62c4babcdb 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/FeatureFlagAttributes.cs @@ -15,27 +15,99 @@ namespace OpenTelemetry.SemanticConventions; public static class FeatureFlagAttributes { /// - /// The unique identifier of the feature flag. + /// The unique identifier for the flag evaluation context. For example, the targeting key. + /// + public const string AttributeFeatureFlagContextId = "feature_flag.context.id"; + + /// + /// A message explaining the nature of an error occurring during flag evaluation. + /// + public const string AttributeFeatureFlagEvaluationErrorMessage = "feature_flag.evaluation.error.message"; + + /// + /// The reason code which shows how a feature flag value was determined. + /// + public const string AttributeFeatureFlagEvaluationReason = "feature_flag.evaluation.reason"; + + /// + /// The lookup key of the feature flag. /// public const string AttributeFeatureFlagKey = "feature_flag.key"; /// - /// The name of the service provider that performs the flag evaluation. + /// Identifies the feature flag provider. /// public const string AttributeFeatureFlagProviderName = "feature_flag.provider_name"; /// - /// SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used. + /// The identifier of the flag set to which the feature flag belongs. + /// + public const string AttributeFeatureFlagSetId = "feature_flag.set.id"; + + /// + /// A semantic identifier for an evaluated flag value. /// /// /// A semantic identifier, commonly referred to as a variant, provides a means /// for referring to a value without including the value itself. This can /// provide additional context for understanding the meaning behind a value. /// For example, the variant red maybe be used for the value #c05543. - ///

            - /// A stringified version of the value can be used in situations where a - /// semantic identifier is unavailable. String representation of the value - /// should be determined by the implementer. /// public const string AttributeFeatureFlagVariant = "feature_flag.variant"; + + ///

            + /// The version of the ruleset used during the evaluation. This may be any stable value which uniquely identifies the ruleset. + /// + public const string AttributeFeatureFlagVersion = "feature_flag.version"; + + /// + /// The reason code which shows how a feature flag value was determined. + /// + public static class FeatureFlagEvaluationReasonValues + { + /// + /// The resolved value is static (no dynamic evaluation). + /// + public const string Static = "static"; + + /// + /// The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or dynamic evaluation yielded no result). + /// + public const string Default = "default"; + + /// + /// The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting. + /// + public const string TargetingMatch = "targeting_match"; + + /// + /// The resolved value was the result of pseudorandom assignment. + /// + public const string Split = "split"; + + /// + /// The resolved value was retrieved from cache. + /// + public const string Cached = "cached"; + + /// + /// The resolved value was the result of the flag being disabled in the management system. + /// + public const string Disabled = "disabled"; + + /// + /// The reason for the resolved value could not be determined. + /// + public const string Unknown = "unknown"; + + /// + /// The resolved value is non-authoritative or possibly out of date. + /// + public const string Stale = "stale"; + + /// + /// The resolved value was the result of an error. + /// + public const string Error = "error"; + } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs index 13b13ef464..9ef30f9c36 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GenAiAttributes.cs @@ -31,7 +31,7 @@ public static class GenAiAttributes public const string AttributeGenAiOpenaiRequestSeed = "gen_ai.openai.request.seed"; /// - /// The service tier requested. May be a specific tier, detault, or auto. + /// The service tier requested. May be a specific tier, default, or auto. /// public const string AttributeGenAiOpenaiRequestServiceTier = "gen_ai.openai.request.service_tier"; @@ -40,6 +40,11 @@ public static class GenAiAttributes /// public const string AttributeGenAiOpenaiResponseServiceTier = "gen_ai.openai.response.service_tier"; + /// + /// A fingerprint to track any eventual change in the Generative AI environment. + /// + public const string AttributeGenAiOpenaiResponseSystemFingerprint = "gen_ai.openai.response.system_fingerprint"; + /// /// The name of the operation being performed. /// @@ -54,6 +59,14 @@ public static class GenAiAttributes [Obsolete("Removed, no replacement at this time.")] public const string AttributeGenAiPrompt = "gen_ai.prompt"; + /// + /// The encoding formats requested in an embeddings operation, if specified. + /// + /// + /// In some GenAI systems the encoding formats are called embedding types. Also, some GenAI systems only accept a single format per request. + /// + public const string AttributeGenAiRequestEncodingFormats = "gen_ai.request.encoding_formats"; + /// /// The frequency penalty setting for the GenAI request. /// @@ -174,7 +187,7 @@ public static class GenAiOpenaiRequestResponseFormatValues } /// - /// The service tier requested. May be a specific tier, detault, or auto. + /// The service tier requested. May be a specific tier, default, or auto. /// public static class GenAiOpenaiRequestServiceTierValues { @@ -203,6 +216,11 @@ public static class GenAiOperationNameValues /// Text completions operation such as OpenAI Completions API (Legacy). /// public const string TextCompletion = "text_completion"; + + /// + /// Embeddings operation such as OpenAI Create embeddings API. + /// + public const string Embeddings = "embeddings"; } /// @@ -229,6 +247,21 @@ public static class GenAiSystemValues /// Cohere. /// public const string Cohere = "cohere"; + + /// + /// Azure AI Inference. + /// + public const string AzAiInference = "az.ai.inference"; + + /// + /// IBM Watsonx AI. + /// + public const string IbmWatsonxAi = "ibm.watsonx.ai"; + + /// + /// AWS Bedrock. + /// + public const string AwsBedrock = "aws.bedrock"; } /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/GeoAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/GeoAttributes.cs new file mode 100644 index 0000000000..a97a4200e3 --- /dev/null +++ b/src/OpenTelemetry.SemanticConventions/Attributes/GeoAttributes.cs @@ -0,0 +1,92 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file has been auto generated from 'src\OpenTelemetry.SemanticConventions\scripts\templates\registry\SemanticConventionsAttributes.cs.j2' + +#nullable enable + +#pragma warning disable CS1570 // XML comment has badly formed XML + +namespace OpenTelemetry.SemanticConventions; + +/// +/// Constants for semantic attribute names outlined by the OpenTelemetry specifications. +/// +public static class GeoAttributes +{ + /// + /// Two-letter code representing continent’s name. + /// + public const string AttributeGeoContinentCode = "geo.continent.code"; + + /// + /// Two-letter ISO Country Code (ISO 3166-1 alpha2). + /// + public const string AttributeGeoCountryIsoCode = "geo.country.iso_code"; + + /// + /// Locality name. Represents the name of a city, town, village, or similar populated place. + /// + public const string AttributeGeoLocalityName = "geo.locality.name"; + + /// + /// Latitude of the geo location in WGS84. + /// + public const string AttributeGeoLocationLat = "geo.location.lat"; + + /// + /// Longitude of the geo location in WGS84. + /// + public const string AttributeGeoLocationLon = "geo.location.lon"; + + /// + /// Postal code associated with the location. Values appropriate for this field may also be known as a postcode or ZIP code and will vary widely from country to country. + /// + public const string AttributeGeoPostalCode = "geo.postal_code"; + + /// + /// Region ISO code (ISO 3166-2). + /// + public const string AttributeGeoRegionIsoCode = "geo.region.iso_code"; + + /// + /// Two-letter code representing continent’s name. + /// + public static class GeoContinentCodeValues + { + /// + /// Africa. + /// + public const string Af = "AF"; + + /// + /// Antarctica. + /// + public const string An = "AN"; + + /// + /// Asia. + /// + public const string As = "AS"; + + /// + /// Europe. + /// + public const string Eu = "EU"; + + /// + /// North America. + /// + public const string Na = "NA"; + + /// + /// Oceania. + /// + public const string Oc = "OC"; + + /// + /// South America. + /// + public const string Sa = "SA"; + } +} diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs index 28eb510d0e..5bd69ad441 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/K8sAttributes.cs @@ -37,13 +37,11 @@ public static class K8sAttributes /// UUIDs as standardized by /// ISO/IEC 9834-8 and ITU-T X.667. /// Which states: - ///

            ///

            /// If generated according to one of the mechanisms defined in Rec. /// ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be /// different from all other UUIDs generated before 3603 A.D., or is /// extremely likely to be different (depending on the mechanism chosen).
            - /// ///

            /// Therefore, UIDs between clusters should be extremely unlikely to /// conflict. diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs index 301b5d9e70..9901f3a745 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/NetworkAttributes.cs @@ -44,6 +44,11 @@ public static class NetworkAttributes ///

            public const string AttributeNetworkConnectionType = "network.connection.type"; + /// + /// The network interface name. + /// + public const string AttributeNetworkInterfaceName = "network.interface.name"; + /// /// The network IO operation direction. /// @@ -70,7 +75,7 @@ public static class NetworkAttributes public const string AttributeNetworkPeerPort = "network.peer.port"; /// - /// OSI application layer or non-OSI equivalent. + /// OSI application layer or non-OSI equivalent. /// /// /// The value SHOULD be normalized to lowercase. @@ -86,7 +91,7 @@ public static class NetworkAttributes public const string AttributeNetworkProtocolVersion = "network.protocol.version"; /// - /// OSI transport layer or inter-process communication method. + /// OSI transport layer or inter-process communication method. /// /// /// The value SHOULD be normalized to lowercase. @@ -98,7 +103,7 @@ public static class NetworkAttributes public const string AttributeNetworkTransport = "network.transport"; /// - /// OSI network layer or non-OSI equivalent. + /// OSI network layer or non-OSI equivalent. /// /// /// The value SHOULD be normalized to lowercase. @@ -264,7 +269,7 @@ public static class NetworkIoDirectionValues } /// - /// OSI transport layer or inter-process communication method. + /// OSI transport layer or inter-process communication method. /// public static class NetworkTransportValues { @@ -295,7 +300,7 @@ public static class NetworkTransportValues } /// - /// OSI network layer or non-OSI equivalent. + /// OSI network layer or non-OSI equivalent. /// public static class NetworkTypeValues { diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs index 76395a4be3..5f5aa03ef1 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ProcessAttributes.cs @@ -66,6 +66,12 @@ public static class ProcessAttributes /// /// Profiling specific build ID for executables. See the OTel specification for Profiles for more information. /// + public const string AttributeProcessExecutableBuildIdHtlhash = "process.executable.build_id.htlhash"; + + /// + /// "Deprecated, use process.executable.build_id.htlhash instead.". + /// + [Obsolete("Replaced by process.executable.build_id.htlhash.")] public const string AttributeProcessExecutableBuildIdProfiling = "process.executable.build_id.profiling"; /// @@ -98,6 +104,14 @@ public static class ProcessAttributes /// public const string AttributeProcessInteractive = "process.interactive"; + /// + /// The control group associated with the process. + /// + /// + /// Control groups (cgroups) are a kernel feature used to organize and manage process resources. This attribute provides the path(s) to the cgroup(s) associated with the process, which should match the contents of the /proc//cgroup file. + /// + public const string AttributeProcessLinuxCgroup = "process.linux.cgroup"; + /// /// The username of the user that owns the process. /// diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs index 18d3b5f96b..51490a445d 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/ServiceAttributes.cs @@ -30,7 +30,7 @@ public static class ServiceAttributes ///

            /// UUIDs are typically recommended, as only an opaque value for the purposes of identifying a service instance is /// needed. Similar to what can be seen in the man page for the - /// /etc/machine-id file, the underlying + /// /etc/machine-id file, the underlying /// data, such as pod name and namespace should be treated as confidential, being the user's choice to expose it /// or not via another resource attribute. ///

            diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs index d3d1bf9705..12ddd062cd 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/TestAttributes.cs @@ -15,7 +15,7 @@ namespace OpenTelemetry.SemanticConventions; public static class TestAttributes { ///

            - /// The fully qualified human readable name of the test case. + /// The fully qualified human readable name of the test case. /// public const string AttributeTestCaseName = "test.case.name"; @@ -25,7 +25,7 @@ public static class TestAttributes public const string AttributeTestCaseResultStatus = "test.case.result.status"; /// - /// The human readable name of a test suite. + /// The human readable name of a test suite. /// public const string AttributeTestSuiteName = "test.suite.name"; diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs index c6277699c2..5f1242bb51 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UrlAttributes.cs @@ -39,9 +39,30 @@ public static class UrlAttributes /// Absolute URL describing a network resource according to RFC3986. /// /// - /// For network calls, URL usually has scheme://host[:port][path][?query][#fragment] format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. - /// url.full MUST NOT contain credentials passed via URL in form of https://username:password@www.example.com/. In such case username and password SHOULD be redacted and attribute's value SHOULD be https://REDACTED:REDACTED@www.example.com/. - /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it. + /// For network calls, URL usually has scheme://host[:port][path][?query][#fragment] format, where the fragment + /// is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. + ///

            + /// url.full MUST NOT contain credentials passed via URL in form of https://username:password@www.example.com/. + /// In such case username and password SHOULD be redacted and attribute's value SHOULD be https://REDACTED:REDACTED@www.example.com/. + ///

            + /// url.full SHOULD capture the absolute URL when it is available (or can be reconstructed). + ///

            + /// Sensitive content provided in url.full SHOULD be scrubbed when instrumentations can identify it. + ///

            + /// + /// Query string values for the following keys SHOULD be redacted by default and replaced by the + /// value REDACTED: + ///

            + ///

            + /// This list is subject to change over time. + ///

            + /// When a query string value is redacted, the query string key SHOULD still be preserved, e.g. + /// https://www.example.com/path?color=blue&sig=REDACTED. /// public const string AttributeUrlFull = "url.full"; @@ -72,6 +93,20 @@ public static class UrlAttributes /// /// /// Sensitive content provided in url.query SHOULD be scrubbed when instrumentations can identify it. + ///

            + /// + /// Query string values for the following keys SHOULD be redacted by default and replaced by the value REDACTED: + ///

            + ///

            + /// This list is subject to change over time. + ///

            + /// When a query string value is redacted, the query string key SHOULD still be preserved, e.g. + /// q=OpenTelemetry&sig=REDACTED. /// public const string AttributeUrlQuery = "url.query"; diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs index 7b728d07be..e6237f51cb 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/UserAgentAttributes.cs @@ -27,6 +27,14 @@ public static class UserAgentAttributes /// public const string AttributeUserAgentOriginal = "user_agent.original"; + ///

            + /// Specifies the category of synthetic traffic, such as tests or bots. + /// + /// + /// This attribute MAY be derived from the contents of the user_agent.original attribute. Components that populate the attribute are responsible for determining what they consider to be synthetic bot or test traffic. This attribute can either be set for self-identification purposes, or on telemetry detected to be generated as a result of a synthetic request. This attribute is useful for distinguishing between genuine client traffic and synthetic traffic generated by bots or tests. + /// + public const string AttributeUserAgentSyntheticType = "user_agent.synthetic.type"; + /// /// Version of the user-agent extracted from original. Usually refers to the browser's version. /// @@ -34,4 +42,20 @@ public static class UserAgentAttributes /// Example of extracting browser's version from original string. In the case of using a user-agent for non-browser products, such as microservices with multiple names/versions inside the user_agent.original, the most significant version SHOULD be selected. In such a scenario it should align with user_agent.name. ///
            public const string AttributeUserAgentVersion = "user_agent.version"; + + /// + /// Specifies the category of synthetic traffic, such as tests or bots. + /// + public static class UserAgentSyntheticTypeValues + { + /// + /// Bot source. + /// + public const string Bot = "bot"; + + /// + /// Synthetic test source. + /// + public const string Test = "test"; + } } diff --git a/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs b/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs index 5173e18ffd..703e1edb96 100644 --- a/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs +++ b/src/OpenTelemetry.SemanticConventions/Attributes/VcsAttributes.cs @@ -15,19 +15,29 @@ namespace OpenTelemetry.SemanticConventions; public static class VcsAttributes { /// - /// The ID of the change (pull request/merge request) if applicable. This is usually a unique (within repository) identifier generated by the VCS system. + /// The ID of the change (pull request/merge request/changelist) if applicable. This is usually a unique (within repository) identifier generated by the VCS system. /// - public const string AttributeVcsRepositoryChangeId = "vcs.repository.change.id"; + public const string AttributeVcsChangeId = "vcs.change.id"; /// - /// The human readable title of the change (pull request/merge request). This title is often a brief summary of the change and may get merged in to a ref as the commit summary. + /// The state of the change (pull request/merge request/changelist). /// - public const string AttributeVcsRepositoryChangeTitle = "vcs.repository.change.title"; + public const string AttributeVcsChangeState = "vcs.change.state"; + + /// + /// The human readable title of the change (pull request/merge request/changelist). This title is often a brief summary of the change and may get merged in to a ref as the commit summary. + /// + public const string AttributeVcsChangeTitle = "vcs.change.title"; + + /// + /// The type of line change being measured on a branch or change. + /// + public const string AttributeVcsLineChangeType = "vcs.line_change.type"; /// /// The name of the reference such as branch or tag in the repository. /// - public const string AttributeVcsRepositoryRefName = "vcs.repository.ref.name"; + public const string AttributeVcsRefBaseName = "vcs.ref.base.name"; /// /// The revision, literally revised version, The revision most often refers to a commit object in Git, or a revision number in SVN. @@ -39,35 +49,209 @@ public static class VcsAttributes /// not necessarily have to be a hash; it can simply define a /// revision number /// which is an integer that is monotonically increasing. In cases where - /// it is identical to the ref.name, it SHOULD still be included. It is + /// it is identical to the ref.base.name, it SHOULD still be included. It is /// up to the implementer to decide which value to set as the revision /// based on the VCS system and situational context. /// - public const string AttributeVcsRepositoryRefRevision = "vcs.repository.ref.revision"; + public const string AttributeVcsRefBaseRevision = "vcs.ref.base.revision"; /// /// The type of the reference in the repository. /// + public const string AttributeVcsRefBaseType = "vcs.ref.base.type"; + + /// + /// The name of the reference such as branch or tag in the repository. + /// + public const string AttributeVcsRefHeadName = "vcs.ref.head.name"; + + /// + /// The revision, literally revised version, The revision most often refers to a commit object in Git, or a revision number in SVN. + /// + /// + /// The revision can be a full hash value (see glossary), + /// of the recorded change to a ref within a repository pointing to a + /// commit commit object. It does + /// not necessarily have to be a hash; it can simply define a + /// revision number + /// which is an integer that is monotonically increasing. In cases where + /// it is identical to the ref.head.name, it SHOULD still be included. It is + /// up to the implementer to decide which value to set as the revision + /// based on the VCS system and situational context. + /// + public const string AttributeVcsRefHeadRevision = "vcs.ref.head.revision"; + + /// + /// The type of the reference in the repository. + /// + public const string AttributeVcsRefHeadType = "vcs.ref.head.type"; + + /// + /// The type of the reference in the repository. + /// + public const string AttributeVcsRefType = "vcs.ref.type"; + + /// + /// Deprecated, use vcs.change.id instead. + /// + [Obsolete("Deprecated, use vcs.change.id instead.")] + public const string AttributeVcsRepositoryChangeId = "vcs.repository.change.id"; + + /// + /// Deprecated, use vcs.change.title instead. + /// + [Obsolete("Deprecated, use vcs.change.title instead.")] + public const string AttributeVcsRepositoryChangeTitle = "vcs.repository.change.title"; + + /// + /// Deprecated, use vcs.ref.head.name instead. + /// + [Obsolete("Deprecated, use vcs.ref.head.name instead.")] + public const string AttributeVcsRepositoryRefName = "vcs.repository.ref.name"; + + /// + /// Deprecated, use vcs.ref.head.revision instead. + /// + [Obsolete("Deprecated, use vcs.ref.head.revision instead.")] + public const string AttributeVcsRepositoryRefRevision = "vcs.repository.ref.revision"; + + /// + /// Deprecated, use vcs.ref.head.type instead. + /// + [Obsolete("Deprecated, use vcs.ref.head.type instead.")] public const string AttributeVcsRepositoryRefType = "vcs.repository.ref.type"; /// - /// The URL of the repository providing the complete address in order to locate and identify the repository. + /// The URL of the repository providing the complete address in order to locate and identify the repository. /// public const string AttributeVcsRepositoryUrlFull = "vcs.repository.url.full"; + /// + /// The type of revision comparison. + /// + public const string AttributeVcsRevisionDeltaDirection = "vcs.revision_delta.direction"; + + /// + /// The state of the change (pull request/merge request/changelist). + /// + public static class VcsChangeStateValues + { + /// + /// Open means the change is currently active and under review. It hasn't been merged into the target branch yet, and it's still possible to make changes or add comments. + /// + public const string Open = "open"; + + /// + /// WIP (work-in-progress, draft) means the change is still in progress and not yet ready for a full review. It might still undergo significant changes. + /// + public const string Wip = "wip"; + + /// + /// Closed means the merge request has been closed without merging. This can happen for various reasons, such as the changes being deemed unnecessary, the issue being resolved in another way, or the author deciding to withdraw the request. + /// + public const string Closed = "closed"; + + /// + /// Merged indicates that the change has been successfully integrated into the target codebase. + /// + public const string Merged = "merged"; + } + + /// + /// The type of line change being measured on a branch or change. + /// + public static class VcsLineChangeTypeValues + { + /// + /// How many lines were added. + /// + public const string Added = "added"; + + /// + /// How many lines were removed. + /// + public const string Removed = "removed"; + } + /// /// The type of the reference in the repository. /// + public static class VcsRefBaseTypeValues + { + /// + /// branch. + /// + public const string Branch = "branch"; + + /// + /// tag. + /// + public const string Tag = "tag"; + } + + /// + /// The type of the reference in the repository. + /// + public static class VcsRefHeadTypeValues + { + /// + /// branch. + /// + public const string Branch = "branch"; + + /// + /// tag. + /// + public const string Tag = "tag"; + } + + /// + /// The type of the reference in the repository. + /// + public static class VcsRefTypeValues + { + /// + /// branch. + /// + public const string Branch = "branch"; + + /// + /// tag. + /// + public const string Tag = "tag"; + } + + /// + /// Deprecated, use vcs.ref.head.type instead. + /// public static class VcsRepositoryRefTypeValues { /// /// branch. /// + [Obsolete("Deprecated, use vcs.ref.head.type instead.")] public const string Branch = "branch"; /// /// tag. /// + [Obsolete("Deprecated, use vcs.ref.head.type instead.")] public const string Tag = "tag"; } + + /// + /// The type of revision comparison. + /// + public static class VcsRevisionDeltaDirectionValues + { + /// + /// How many revisions the change is behind the target ref. + /// + public const string Behind = "behind"; + + /// + /// How many revisions the change is ahead of the target ref. + /// + public const string Ahead = "ahead"; + } } diff --git a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md index 331dc114d9..5261535858 100644 --- a/src/OpenTelemetry.SemanticConventions/CHANGELOG.md +++ b/src/OpenTelemetry.SemanticConventions/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Updated to `v1.29.0` release of OpenTelemetry Semantic Conventions. + ([#2428](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2428)) + * Updated to `v1.28.0` release of OpenTelemetry Semantic Conventions. ([#2189](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2189)) diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 index 8f60be53b9..0b0edbeca8 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.ps1 @@ -2,8 +2,8 @@ $SCRIPT_DIR = $PSScriptRoot $ROOT_DIR = "${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -$SEMCONV_VERSION="1.28.0" -$GENERATOR_VERSION="v0.10.0" +$SEMCONV_VERSION="1.29.0" +$GENERATOR_VERSION="v0.12.0" Set-Location $SCRIPT_DIR diff --git a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh index ea34b10635..eaaa3d80b0 100644 --- a/src/OpenTelemetry.SemanticConventions/scripts/generate.sh +++ b/src/OpenTelemetry.SemanticConventions/scripts/generate.sh @@ -5,8 +5,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="${SCRIPT_DIR}/../" # freeze the spec version to make SemanticAttributes generation reproducible -SEMCONV_VERSION="1.28.0" -GENERATOR_VERSION="v0.10.0" +SEMCONV_VERSION="1.29.0" +GENERATOR_VERSION="v0.12.0" cd ${SCRIPT_DIR} From ab278bb929443133e8563f67161e3c0a68564449 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 18 Dec 2024 10:36:57 -0800 Subject: [PATCH 1483/1499] [GenevaExporter] Add ability to export Log Exception using StackTrace (#2422) Co-authored-by: Rajkumar Rangaraj Co-authored-by: Mikel Blanchard --- .../.publicApi/PublicAPI.Unshipped.txt | 1 + .../CHANGELOG.md | 6 +++++ .../ExceptionStackExportMode.cs | 23 +++++++++++++++--- .../Internal/MsgPack/MsgPackLogExporter.cs | 24 +++++++++++++------ .../Internal/Tld/TldLogExporter.cs | 9 +++++++ 5 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt index e69de29bb2..44dadc78df 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode.ExportAsStackTraceString = 2 -> OpenTelemetry.Exporter.Geneva.ExceptionStackExportMode \ No newline at end of file diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 5635ffc0c0..3fc87b0de5 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Added support for exporting exception stack traces using + `Exception.StackTrace`. This can be enabled via the + `ExceptionStackExportMode.ExportAsStackTraceString` enum. Applicable only to + the LogExporter. + ([#2422](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2422)) + ## 1.10.0 Released 2024-Nov-18 diff --git a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs index 9030a32b9c..87b2ec20ae 100644 --- a/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs +++ b/src/OpenTelemetry.Exporter.Geneva/ExceptionStackExportMode.cs @@ -4,19 +4,36 @@ namespace OpenTelemetry.Exporter.Geneva; /// -/// Contains the exception stack trace export mode defintions. +/// Defines modes for exporting exception stack traces. Currently applicable only to the Logs signal. /// public enum ExceptionStackExportMode { /// - /// Exception stack traces are dropped. + /// Exception stack traces are dropped and not exported. /// Drop, /// - /// Exception stack traces are exported as strings. + /// Exports exception stack traces as a string using the ToString() implementation of the exception. + /// The output is formatted in a culture-agnostic manner and is primarily designed for human readability. + /// See . /// + /// + /// Typically, ToString() includes information about inner exceptions and additional details, + /// such as the exception message. However, this behavior is not guaranteed, as custom exceptions + /// can override ToString() to return arbitrary content. + /// ExportAsString, + /// + /// Exports exception stack traces as a string using the StackTrace property of the exception. + /// See . + /// + /// + /// This represents the raw stack trace and does not include inner exception details. + /// Note that the StackTrace property can also be overridden in custom exception implementations. + /// + ExportAsStackTraceString, + // ExportAsArrayOfStacks - future if stacks can be exported in more structured way } diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs index de39f6e7fd..ba3c9969c1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/MsgPack/MsgPackLogExporter.cs @@ -419,20 +419,30 @@ internal ArraySegment SerializeLogRecord(LogRecord logRecord) cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, logRecord.Exception.Message); cntFields += 1; + // The current approach relies on the existing trim + // capabilities which trims string in excess of STRING_SIZE_LIMIT_CHAR_COUNT + // TODO: Revisit this: + // 1. Trim it off based on how much more bytes are available + // before running out of limit instead of STRING_SIZE_LIMIT_CHAR_COUNT. + // 2. Trim smarter, by trimming the middle of stack, an + // keep top and bottom. if (this.exportExceptionStack == ExceptionStackExportMode.ExportAsString) { - // The current approach relies on the existing trim - // capabilities which trims string in excess of STRING_SIZE_LIMIT_CHAR_COUNT - // TODO: Revisit this: - // 1. Trim it off based on how much more bytes are available - // before running out of limit instead of STRING_SIZE_LIMIT_CHAR_COUNT. - // 2. Trim smarter, by trimming the middle of stack, an - // keep top and bottom. var exceptionStack = logRecord.Exception.ToInvariantString(); cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_stack"); cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, exceptionStack); cntFields += 1; } + else if (this.exportExceptionStack == ExceptionStackExportMode.ExportAsStackTraceString) + { + var exceptionStack = logRecord.Exception.StackTrace; + if (exceptionStack != null) + { + cursor = MessagePackSerializer.SerializeAsciiString(buffer, cursor, "env_ex_stack"); + cursor = MessagePackSerializer.SerializeUnicodeString(buffer, cursor, exceptionStack); + cntFields += 1; + } + } } MessagePackSerializer.WriteUInt16(buffer, idxMapSizePatch, cntFields); diff --git a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs index 1e28710271..9f31da3f01 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Internal/Tld/TldLogExporter.cs @@ -260,6 +260,15 @@ internal EventBuilder SerializeLogRecord(LogRecord logRecord) eb.AddCountedAnsiString("ext_ex_stack", exceptionStack, Encoding.UTF8, 0, Math.Min(exceptionStack.Length, StringLengthLimit)); partAFieldsCount++; } + else if (this.exceptionStackExportMode == ExceptionStackExportMode.ExportAsStackTraceString) + { + var stackTrace = logRecord.Exception.StackTrace; + if (stackTrace != null) + { + eb.AddCountedAnsiString("ext_ex_stack", stackTrace, Encoding.UTF8, 0, Math.Min(stackTrace.Length, StringLengthLimit)); + partAFieldsCount++; + } + } } eb.SetStructFieldCount(partAFieldsCountPatch, partAFieldsCount); From 31cea68a81fbaeacbde1431898746ce4454b08d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Kie=C5=82kowicz?= Date: Thu, 19 Dec 2024 20:33:33 +0100 Subject: [PATCH 1484/1499] [repo] Metrics instrumentations - utilize advice API for histogram boundaries (#2430) Co-authored-by: Mikel Blanchard --- .../CHANGELOG.md | 5 ++++ .../Implementation/HttpInMetricsListener.cs | 5 ++-- .../CHANGELOG.md | 5 ++++ .../Implementation/HttpInMetricsListener.cs | 6 ++++- .../CHANGELOG.md | 6 +++++ .../ConfluentKafkaCommon.cs | 23 +++++++++++++++---- .../CHANGELOG.md | 5 ++++ .../HttpHandlerMetricsDiagnosticListener.cs | 6 ++++- .../HttpWebRequestActivitySource.netfx.cs | 6 ++++- .../CHANGELOG.md | 5 ++++ .../OwinInstrumentationMetrics.cs | 6 ++++- .../CHANGELOG.md | 5 ++++ .../Implementation/SqlActivitySourceHelper.cs | 7 +++--- 13 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md index 567a32e291..eea2ca09f3 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNet/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The `http.server.request.duration` histogram (measured in seconds) produced by + the metrics instrumentation in this package now uses the [Advice API](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.10.0/docs/metrics/customizing-the-sdk/README.md#explicit-bucket-histogram-aggregation) + to set default explicit buckets following the [OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/http/http-metrics.md). + ([#2430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2430)) + ## 1.10.0-beta.1 Released 2024-Dec-09 diff --git a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs index 0dac906cb0..cf17fc867e 100644 --- a/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNet/Implementation/HttpInMetricsListener.cs @@ -18,10 +18,11 @@ internal sealed class HttpInMetricsListener : IDisposable public HttpInMetricsListener(Meter meter, AspNetMetricsInstrumentationOptions options) { - this.httpServerDuration = meter.CreateHistogram( + this.httpServerDuration = meter.CreateHistogram( "http.server.request.duration", unit: "s", - description: "Duration of HTTP server requests."); + description: "Duration of HTTP server requests.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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] }); TelemetryHttpModule.Options.OnRequestStoppedCallback += this.OnStopActivity; this.options = options; } diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md index 2bb349e1fc..a4f0dc0941 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The `http.server.request.duration` histogram (measured in seconds) produced by + the metrics instrumentation in this package now uses the [Advice API](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.10.0/docs/metrics/customizing-the-sdk/README.md#explicit-bucket-histogram-aggregation) + to set default explicit buckets following the [OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/http/http-metrics.md). + ([#2430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2430)) + ## 1.10.1 Released 2024-Dec-10 diff --git a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs index c9040d0248..551421403a 100644 --- a/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs +++ b/src/OpenTelemetry.Instrumentation.AspNetCore/Implementation/HttpInMetricsListener.cs @@ -33,7 +33,11 @@ internal sealed class HttpInMetricsListener : ListenerHandler private static readonly PropertyFetcher HttpContextPropertyFetcher = new("HttpContext"); private static readonly object ErrorTypeHttpContextItemsKey = new(); - private static readonly Histogram HttpServerRequestDuration = Meter.CreateHistogram(HttpServerRequestDurationMetricName, "s", "Duration of HTTP server requests."); + private static readonly Histogram HttpServerRequestDuration = Meter.CreateHistogram( + HttpServerRequestDurationMetricName, + unit: "s", + description: " Duration of HTTP server requests.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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 HttpInMetricsListener(string name) : base(name) diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md index bd314a325b..75e3e56b90 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/CHANGELOG.md @@ -14,6 +14,12 @@ span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) +* The `messaging.receive.duration` and `messaging.publish.duration` histograms + (measured in seconds) produced by the metrics instrumentation in this package + now uses the [Advice API](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.10.0/docs/metrics/customizing-the-sdk/README.md#explicit-bucket-histogram-aggregation) + to set default explicit buckets following the [OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.24.0/docs/messaging/messaging-metrics.md). + ([#2430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2430)) + ## 0.1.0-alpha.2 Released 2024-Sep-18 diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs index b4c024db0e..e7572b0463 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaCommon.cs @@ -19,8 +19,23 @@ internal static class ConfluentKafkaCommon internal static readonly string InstrumentationVersion = typeof(ConfluentKafkaCommon).Assembly.GetPackageVersion(); internal static readonly ActivitySource ActivitySource = new(InstrumentationName, InstrumentationVersion); internal static readonly Meter Meter = new(InstrumentationName, InstrumentationVersion); - internal static readonly Counter ReceiveMessagesCounter = Meter.CreateCounter(SemanticConventions.MetricMessagingReceiveMessages); - internal static readonly Histogram ReceiveDurationHistogram = Meter.CreateHistogram(SemanticConventions.MetricMessagingReceiveDuration); - internal static readonly Counter PublishMessagesCounter = Meter.CreateCounter(SemanticConventions.MetricMessagingPublishMessages); - internal static readonly Histogram PublishDurationHistogram = Meter.CreateHistogram(SemanticConventions.MetricMessagingPublishDuration); + internal static readonly Counter ReceiveMessagesCounter = Meter.CreateCounter( + SemanticConventions.MetricMessagingReceiveMessages, + description: "Measures the number of received messages."); + + internal static readonly Histogram ReceiveDurationHistogram = Meter.CreateHistogram( + SemanticConventions.MetricMessagingReceiveDuration, + unit: "s", + description: "Measures the duration of receive operation.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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 Counter PublishMessagesCounter = Meter.CreateCounter( + SemanticConventions.MetricMessagingPublishMessages, + description: "Measures the number of published messages."); + + internal static readonly Histogram PublishDurationHistogram = Meter.CreateHistogram( + SemanticConventions.MetricMessagingPublishDuration, + unit: "s", + description: "Measures the duration of publish operation.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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] }); } diff --git a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md index 6b909b08ac..350df7e937 100644 --- a/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Http/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* The `http.client.request.duration` histogram (measured in seconds) produced by + the metrics instrumentation in this package now uses the [Advice API](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.10.0/docs/metrics/customizing-the-sdk/README.md#explicit-bucket-histogram-aggregation) + to set default explicit buckets following the [OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/http/http-metrics.md). + ([#2430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2430)) + ## 1.10.0 Released 2024-Nov-27 diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs index dd3dc6970c..b6f0fb48d7 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpHandlerMetricsDiagnosticListener.cs @@ -22,7 +22,11 @@ internal sealed class HttpHandlerMetricsDiagnosticListener : ListenerHandler internal static readonly string MeterVersion = AssemblyName.Version!.ToString(); internal static readonly Meter Meter = new(MeterName, MeterVersion); private const string OnUnhandledExceptionEvent = "System.Net.Http.Exception"; - private static readonly Histogram HttpClientRequestDuration = Meter.CreateHistogram("http.client.request.duration", "s", "Duration of HTTP client requests."); + private static readonly Histogram HttpClientRequestDuration = Meter.CreateHistogram( + "http.client.request.duration", + unit: "s", + description: "Duration of HTTP client requests.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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] }); private static readonly PropertyFetcher StopRequestFetcher = new("Request"); private static readonly PropertyFetcher StopResponseFetcher = new("Response"); diff --git a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs index c28670cbd7..e9b1c6f135 100644 --- a/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.Http/Implementation/HttpWebRequestActivitySource.netfx.cs @@ -38,7 +38,11 @@ internal static class HttpWebRequestActivitySource private static readonly string Version = AssemblyName.Version.ToString(); private static readonly ActivitySource WebRequestActivitySource = new(ActivitySourceName, Version); private static readonly Meter WebRequestMeter = new(MeterName, Version); - private static readonly Histogram HttpClientRequestDuration = WebRequestMeter.CreateHistogram("http.client.request.duration", "s", "Duration of HTTP client requests."); + private static readonly Histogram HttpClientRequestDuration = WebRequestMeter.CreateHistogram( + "http.client.request.duration", + unit: "s", + description: "Duration of HTTP client requests.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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] }); // Fields for reflection private static FieldInfo connectionGroupListField; diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 89a4131868..9bd787ae02 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -24,6 +24,11 @@ span status. For details see: [Setting Status](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Api/README.md#setting-status). ([#2358](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2358)) +* The `http.server.request.duration` histogram (measured in seconds) produced by + the metrics instrumentation in this package now uses the [Advice API](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.10.0/docs/metrics/customizing-the-sdk/README.md#explicit-bucket-histogram-aggregation) + to set default explicit buckets following the [OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/http/http-metrics.md). + ([#2430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2430)) + ## 1.0.0-rc.6 Released 2024-Apr-19 diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs index e5d2280194..735555239c 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/OwinInstrumentationMetrics.cs @@ -13,5 +13,9 @@ internal static class OwinInstrumentationMetrics internal static readonly AssemblyName AssemblyName = Assembly.GetName(); internal static readonly string MeterName = AssemblyName.Name; internal static readonly Meter Instance = new(MeterName, Assembly.GetPackageVersion()); - internal static readonly Histogram HttpServerDuration = Instance.CreateHistogram("http.server.request.duration", "s", "Duration of HTTP server requests."); + internal static readonly Histogram HttpServerDuration = Instance.CreateHistogram( + "http.server.request.duration", + unit: "s", + description: "Duration of HTTP server requests.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [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] }); } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index 16f15d141d..e1e5f5c1ee 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -5,6 +5,11 @@ * **Breaking change** The `EnableConnectionLevelAttributes` option has been removed. ([#2414](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2414)) +* The `db.client.operation.duration` histogram (measured in seconds) produced by + the metrics instrumentation in this package now uses the [Advice API](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.10.0/docs/metrics/customizing-the-sdk/README.md#explicit-bucket-histogram-aggregation) + to set default explicit buckets following the [OpenTelemetry Specification](https://github.com/open-telemetry/semantic-conventions/blob/v1.29.0/docs/database/database-metrics.md). + ([#2430](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2430)) + ## 1.10.0-beta.1 Released 2024-Dec-09 diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs index a332be18b7..b1ad4815ab 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlActivitySourceHelper.cs @@ -25,10 +25,11 @@ internal sealed class SqlActivitySourceHelper public static readonly string MeterName = AssemblyName.Name!; public static readonly Meter Meter = new(MeterName, Assembly.GetPackageVersion()); - public static readonly Histogram DbClientOperationDuration = Meter.CreateHistogram( + public static readonly Histogram DbClientOperationDuration = Meter.CreateHistogram( "db.client.operation.duration", - "s", - "Duration of database client operations."); + unit: "s", + description: "Duration of database client operations.", + advice: new InstrumentAdvice { HistogramBucketBoundaries = [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10] }); internal static readonly string[] SharedTagNames = [ From c455a85f52201400e6cdbde7c663097bc4834b9b Mon Sep 17 00:00:00 2001 From: Philip Pittle Date: Thu, 19 Dec 2024 16:05:01 -0800 Subject: [PATCH 1485/1499] Upgrade Semantic Convention handling in AWS libraries. (#2367) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Alan West <3676547+alanwest@users.noreply.github.com> Co-authored-by: Piotr Kiełkowicz --- .../.publicApi/PublicAPI.Unshipped.txt | 7 + .../AWSClientInstrumentationOptions.cs | 5 + .../CHANGELOG.md | 8 + .../Implementation/AWSSemanticConventions.cs | 35 - .../Implementation/AWSServiceHelper.cs | 39 +- .../AWSTracingPipelineCustomizer.cs | 4 +- .../AWSTracingPipelineHandler.cs | 34 +- .../OpenTelemetry.Instrumentation.AWS.csproj | 3 +- .../README.md | 45 ++ .../.publicApi/PublicAPI.Unshipped.txt | 7 + .../AWSLambdaInstrumentationOptions.cs | 5 + .../AWSLambdaWrapper.cs | 11 +- .../CHANGELOG.md | 5 + .../Implementation/AWSLambdaHttpUtils.cs | 74 +- .../AWSLambdaResourceDetector.cs | 35 +- .../AWSLambdaSemanticConventions.cs | 20 - .../Implementation/AWSLambdaUtils.cs | 77 +- .../Implementation/CommonExtensions.cs | 8 - ...Telemetry.Instrumentation.AWSLambda.csproj | 3 +- .../README.md | 39 + .../TracerProviderBuilderExtensions.cs | 6 +- .../.publicApi/PublicAPI.Unshipped.txt | 14 +- .../.publicApi/net8.0/PublicAPI.Unshipped.txt | 4 +- .../AWSEBSDetector.cs | 56 +- .../AWSEC2Detector.cs | 68 +- .../AWSECSDetector.cs | 129 +-- .../AWSEKSDetector.cs | 45 +- .../AWSResourceBuilderExtensions.cs | 45 +- .../AWSResourceBuilderOptions.cs | 15 + .../AWSSemanticConventions.cs | 52 -- src/OpenTelemetry.Resources.AWS/CHANGELOG.md | 5 + .../OpenTelemetry.Resources.AWS.csproj | 2 + src/OpenTelemetry.Resources.AWS/README.md | 43 + src/Shared/AWS/AWSSemanticConventions.Base.cs | 754 ++++++++++++++++++ .../AWS/AWSSemanticConventions.Legacy.cs | 109 +++ src/Shared/AWS/AWSSemanticConventions.cs | 507 ++++++++++++ .../AWS/AWSSemanticConventions.v1.28.0.cs | 55 ++ .../AWS/AWSSemanticConventions.v1.29.0.cs | 24 + src/Shared/AWS/SemanticConventionVersion.cs | 105 +++ .../AWSClientInstrumentationOptionsTests.cs | 92 +++ .../TestAWSClientInstrumentation.cs | 59 +- .../AWSLambdaWrapperTests.cs | 78 +- .../Implementation/AWSLambdaHttpUtilsTests.cs | 119 +-- .../Implementation/CommonExtensionsTests.cs | 33 - .../AWSEBSDetectorTests.cs | 22 +- .../AWSEC2DetectorTests.cs | 42 +- .../AWSECSDetectorTests.cs | 111 ++- .../AWSEKSDetectorTests.cs | 51 +- 48 files changed, 2526 insertions(+), 583 deletions(-) delete mode 100644 src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs delete mode 100644 src/OpenTelemetry.Instrumentation.AWSLambda/Implementation/AWSLambdaSemanticConventions.cs create mode 100644 src/OpenTelemetry.Resources.AWS/AWSResourceBuilderOptions.cs delete mode 100644 src/OpenTelemetry.Resources.AWS/AWSSemanticConventions.cs create mode 100644 src/Shared/AWS/AWSSemanticConventions.Base.cs create mode 100644 src/Shared/AWS/AWSSemanticConventions.Legacy.cs create mode 100644 src/Shared/AWS/AWSSemanticConventions.cs create mode 100644 src/Shared/AWS/AWSSemanticConventions.v1.28.0.cs create mode 100644 src/Shared/AWS/AWSSemanticConventions.v1.29.0.cs create mode 100644 src/Shared/AWS/SemanticConventionVersion.cs create mode 100644 test/OpenTelemetry.Instrumentation.AWS.Tests/AWSClientInstrumentationOptionsTests.cs delete mode 100644 test/OpenTelemetry.Instrumentation.AWSLambda.Tests/Implementation/CommonExtensionsTests.cs diff --git a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt index d8633d91a7..d9f3466a01 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.AWS/.publicApi/PublicAPI.Unshipped.txt @@ -1,6 +1,13 @@ #nullable enable +OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion +OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion.Legacy = -1 -> OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion +OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion.Latest = 0 -> OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion +OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion.V1_29_0 = 2 -> OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion +OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion.V1_28_0 = 1 -> OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.AWSClientInstrumentationOptions() -> void +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SemanticConventionVersion.get -> OpenTelemetry.Instrumentation.AWS.SemanticConventionVersion +OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SemanticConventionVersion.set -> void OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.get -> bool OpenTelemetry.Instrumentation.AWS.AWSClientInstrumentationOptions.SuppressDownstreamInstrumentation.set -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions diff --git a/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs index f476d1915d..193c65ebcf 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/AWSClientInstrumentationOptions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using OpenTelemetry.AWS; + namespace OpenTelemetry.Instrumentation.AWS; /// @@ -12,4 +14,7 @@ public class AWSClientInstrumentationOptions /// Gets or sets a value indicating whether downstream instrumentation is suppressed. /// public bool SuppressDownstreamInstrumentation { get; set; } + + /// + public SemanticConventionVersion SemanticConventionVersion { get; set; } = AWSSemanticConventions.DefaultSemanticConventionVersion; } diff --git a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md index b4affacd6c..25d1d4cf4b 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.AWS/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +* Introduce `AWSClientInstrumentationOptions.SemanticConventionVersion` which + provides a mechanism for developers to opt-in to newer versions of the + of the OpenTelemetry Semantic Conventions. Currently, you need to opt-in + to these new conventions. In the upcoming stable release of this library, + the new conventions will be enabled by default, and the conventions this library + currently emit will no longer be supported. + ([#2367](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2367)) + ## 1.10.0-beta.2 Released 2024-Dec-12 diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs deleted file mode 100644 index 61d72da34e..0000000000 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSSemanticConventions.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -namespace OpenTelemetry.Instrumentation.AWS.Implementation; - -internal static class AWSSemanticConventions -{ - public const string AttributeAWSServiceName = "aws.service"; - public const string AttributeAWSOperationName = "aws.operation"; - public const string AttributeAWSRegion = "aws.region"; - public const string AttributeAWSRequestId = "aws.requestId"; - - public const string AttributeAWSDynamoTableName = "aws.table_name"; - public const string AttributeAWSSQSQueueUrl = "aws.queue_url"; - - // AWS Bedrock service attributes not yet defined in semantic conventions - public const string AttributeAWSBedrockAgentId = "aws.bedrock.agent.id"; - public const string AttributeAWSBedrockDataSourceId = "aws.bedrock.data_source.id"; - public const string AttributeAWSBedrockGuardrailId = "aws.bedrock.guardrail.id"; - public const string AttributeAWSBedrockKnowledgeBaseId = "aws.bedrock.knowledge_base.id"; - public const string AttributeAWSBedrock = "aws_bedrock"; - - // should be global convention for Gen AI attributes - public const string AttributeGenAiModelId = "gen_ai.request.model"; - public const string AttributeGenAiSystem = "gen_ai.system"; - - public const string AttributeHttpStatusCode = "http.status_code"; - public const string AttributeHttpResponseContentLength = "http.response_content_length"; - - public const string AttributeValueDynamoDb = "dynamodb"; - - public const string AttributeValueRPCSystem = "rpc.system"; - public const string AttributeValueRPCService = "rpc.service"; - public const string AttributeValueRPCMethod = "rpc.method"; -} diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs index 7e87865b3c..67ea5d94df 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSServiceHelper.cs @@ -2,12 +2,28 @@ // SPDX-License-Identifier: Apache-2.0 using Amazon.Runtime; +using OpenTelemetry.AWS; namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal class AWSServiceHelper { - internal static IReadOnlyDictionary> ServiceRequestParameterMap = new Dictionary>() + public AWSServiceHelper(AWSSemanticConventions semanticConventions) + { + this.ParameterAttributeMap = + semanticConventions + .ParameterMappingBuilder + .AddAttributeAWSDynamoTableName("TableName") + .AddAttributeAWSSQSQueueUrl("QueueUrl") + .AddAttributeGenAiModelId("ModelId") + .AddAttributeAWSBedrockAgentId("AgentId") + .AddAttributeAWSBedrockDataSourceId("DataSourceId") + .AddAttributeAWSBedrockGuardrailId("GuardrailId") + .AddAttributeAWSBedrockKnowledgeBaseId("KnowledgeBaseId") + .Build(); + } + + internal static IReadOnlyDictionary> ServiceRequestParameterMap { get; } = new Dictionary>() { { AWSServiceType.DynamoDbService, ["TableName"] }, { AWSServiceType.SQSService, ["QueueUrl"] }, @@ -16,25 +32,14 @@ internal class AWSServiceHelper { AWSServiceType.BedrockRuntimeService, ["ModelId"] }, }; - internal static IReadOnlyDictionary> ServiceResponseParameterMap = new Dictionary>() + internal static IReadOnlyDictionary> ServiceResponseParameterMap { get; } = new Dictionary>() { { AWSServiceType.BedrockService, ["GuardrailId"] }, { AWSServiceType.BedrockAgentService, ["AgentId", "DataSourceId"] }, }; - internal static IReadOnlyDictionary ParameterAttributeMap = new Dictionary() - { - { "TableName", AWSSemanticConventions.AttributeAWSDynamoTableName }, - { "QueueUrl", AWSSemanticConventions.AttributeAWSSQSQueueUrl }, - { "ModelId", AWSSemanticConventions.AttributeGenAiModelId }, - { "AgentId", AWSSemanticConventions.AttributeAWSBedrockAgentId }, - { "DataSourceId", AWSSemanticConventions.AttributeAWSBedrockDataSourceId }, - { "GuardrailId", AWSSemanticConventions.AttributeAWSBedrockGuardrailId }, - { "KnowledgeBaseId", AWSSemanticConventions.AttributeAWSBedrockKnowledgeBaseId }, - }; - // for Bedrock Agent operations, we map each supported operation to one resource: Agent, DataSource, or KnowledgeBase - internal static List BedrockAgentAgentOps = + internal static List BedrockAgentAgentOps { get; } = [ "CreateAgentActionGroup", "CreateAgentAlias", @@ -56,7 +61,7 @@ internal class AWSServiceHelper "UpdateAgent" ]; - internal static List BedrockAgentKnowledgeBaseOps = + internal static List BedrockAgentKnowledgeBaseOps { get; } = [ "AssociateAgentKnowledgeBase", "CreateDataSource", @@ -68,13 +73,15 @@ internal class AWSServiceHelper "UpdateAgentKnowledgeBase" ]; - internal static List BedrockAgentDataSourceOps = + internal static List BedrockAgentDataSourceOps { get; } = [ "DeleteDataSource", "GetDataSource", "UpdateDataSource" ]; + internal IDictionary ParameterAttributeMap { get; } + internal static IReadOnlyDictionary OperationNameToResourceMap() { var operationClassMap = new Dictionary(); diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs index d9c1f550a5..6239999bb9 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineCustomizer.cs @@ -12,6 +12,8 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; /// internal class AWSTracingPipelineCustomizer : IRuntimePipelineCustomizer { + public const string UniqueName = "AWS Tracing Registration Customization"; + private readonly AWSClientInstrumentationOptions options; public AWSTracingPipelineCustomizer(AWSClientInstrumentationOptions options) @@ -19,7 +21,7 @@ public AWSTracingPipelineCustomizer(AWSClientInstrumentationOptions options) this.options = options; } - public string UniqueName => "AWS Tracing Registration Customization"; + string IRuntimePipelineCustomizer.UniqueName => UniqueName; public void Customize(Type serviceClientType, RuntimePipeline pipeline) { diff --git a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs index 2a13fed2ba..ef28d3cc5e 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs +++ b/src/OpenTelemetry.Instrumentation.AWS/Implementation/AWSTracingPipelineHandler.cs @@ -5,8 +5,8 @@ using Amazon.Runtime; using Amazon.Runtime.Internal; using Amazon.Runtime.Telemetry; +using OpenTelemetry.AWS; using OpenTelemetry.Context.Propagation; -using OpenTelemetry.Trace; namespace OpenTelemetry.Instrumentation.AWS.Implementation; @@ -19,17 +19,21 @@ namespace OpenTelemetry.Instrumentation.AWS.Implementation; internal sealed class AWSTracingPipelineHandler : PipelineHandler { private readonly AWSClientInstrumentationOptions options; + private readonly AWSSemanticConventions awsSemanticConventions; + private readonly AWSServiceHelper awsServiceHelper; public AWSTracingPipelineHandler(AWSClientInstrumentationOptions options) { this.options = options; + this.awsSemanticConventions = new AWSSemanticConventions(options.SemanticConventionVersion); + this.awsServiceHelper = new AWSServiceHelper(this.awsSemanticConventions); } public override void InvokeSync(IExecutionContext executionContext) { var activity = this.ProcessBeginRequest(executionContext); base.InvokeSync(executionContext); - ProcessEndRequest(activity, executionContext); + this.ProcessEndRequest(activity, executionContext); } public override async Task InvokeAsync(IExecutionContext executionContext) @@ -37,7 +41,7 @@ public override async Task InvokeAsync(IExecutionContext executionContext) var activity = this.ProcessBeginRequest(executionContext); var ret = await base.InvokeAsync(executionContext).ConfigureAwait(false); - ProcessEndRequest(activity, executionContext); + this.ProcessEndRequest(activity, executionContext); return ret; } @@ -48,7 +52,7 @@ public override async Task InvokeAsync(IExecutionContext executionContext) "IL2075", Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] #endif - private static void AddResponseSpecificInformation(Activity activity, IExecutionContext executionContext) + private void AddResponseSpecificInformation(Activity activity, IExecutionContext executionContext) { var service = executionContext.RequestContext.ServiceMetaData.ServiceId; var responseContext = executionContext.ResponseContext; @@ -67,14 +71,14 @@ private static void AddResponseSpecificInformation(Activity activity, IExecution var operationName = Utils.RemoveSuffix(response.GetType().Name, "Response"); if (AWSServiceHelper.OperationNameToResourceMap()[operationName] == parameter) { - AddBedrockAgentResponseAttribute(activity, response, parameter); + this.AddBedrockAgentResponseAttribute(activity, response, parameter); } } var property = response.GetType().GetProperty(parameter); if (property != null) { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + if (this.awsServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) { activity.SetTag(attribute, property.GetValue(response)); } @@ -95,7 +99,7 @@ private static void AddResponseSpecificInformation(Activity activity, IExecution "IL2075", Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] #endif - private static void AddBedrockAgentResponseAttribute(Activity activity, AmazonWebServiceResponse response, string parameter) + private void AddBedrockAgentResponseAttribute(Activity activity, AmazonWebServiceResponse response, string parameter) { var responseObject = response.GetType().GetProperty(Utils.RemoveSuffix(parameter, "Id")); if (responseObject != null) @@ -106,7 +110,7 @@ private static void AddBedrockAgentResponseAttribute(Activity activity, AmazonWe var property = attributeObject.GetType().GetProperty(parameter); if (property != null) { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + if (this.awsServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) { activity.SetTag(attribute, property.GetValue(attributeObject)); } @@ -121,7 +125,7 @@ private static void AddBedrockAgentResponseAttribute(Activity activity, AmazonWe "IL2075", Justification = "The reflected properties were already used by the AWS SDK's marshallers so the properties could not have been trimmed.")] #endif - private static void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext) + private void AddRequestSpecificInformation(Activity activity, IRequestContext requestContext) { var service = requestContext.ServiceMetaData.ServiceId; @@ -145,7 +149,7 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon var property = request.GetType().GetProperty(parameter); if (property != null) { - if (AWSServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) + if (this.awsServiceHelper.ParameterAttributeMap.TryGetValue(parameter, out var attribute)) { activity.SetTag(attribute, property.GetValue(request)); } @@ -161,7 +165,7 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon if (AWSServiceType.IsDynamoDbService(service)) { - activity.SetTag(SemanticConventions.AttributeDbSystem, AWSSemanticConventions.AttributeValueDynamoDb); + this.awsSemanticConventions.TagBuilder.SetTagAttributeDbSystemToDynamoDb(activity); } else if (AWSServiceType.IsSqsService(service)) { @@ -175,18 +179,18 @@ private static void AddRequestSpecificInformation(Activity activity, IRequestCon } else if (AWSServiceType.IsBedrockRuntimeService(service)) { - activity.SetTag(AWSSemanticConventions.AttributeGenAiSystem, AWSSemanticConventions.AttributeAWSBedrock); + this.awsSemanticConventions.TagBuilder.SetTagAttributeGenAiSystemToBedrock(activity); } } - private static void ProcessEndRequest(Activity? activity, IExecutionContext executionContext) + private void ProcessEndRequest(Activity? activity, IExecutionContext executionContext) { if (activity == null || !activity.IsAllDataRequested) { return; } - AddResponseSpecificInformation(activity, executionContext); + this.AddResponseSpecificInformation(activity, executionContext); } private Activity? ProcessBeginRequest(IExecutionContext executionContext) @@ -205,7 +209,7 @@ private static void ProcessEndRequest(Activity? activity, IExecutionContext exec return null; } - AddRequestSpecificInformation(currentActivity, executionContext.RequestContext); + this.AddRequestSpecificInformation(currentActivity, executionContext.RequestContext); return currentActivity; } } diff --git a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj index b4b422dd49..8f2906daad 100644 --- a/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj +++ b/src/OpenTelemetry.Instrumentation.AWS/OpenTelemetry.Instrumentation.AWS.csproj @@ -6,6 +6,7 @@ $(TargetFrameworks);$(NetFrameworkMinimumSupportedVersion) AWS client instrumentation for OpenTelemetry .NET. Instrumentation.AWS- + INSTRUMENTATION_AWS;$(DefineConstants)